diff mbox

drm/radeon/kms: avoid executing dac detection table on r4xx + rv515.

Message ID 1272344965-10923-1-git-send-email-airlied@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dave Airlie April 27, 2010, 5:09 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index bcec2d7..6477ac5 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -1320,12 +1320,13 @@  bool atom_parse_data_header(struct atom_context *ctx, int index,
 	return true;
 }
 
-bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
-			   uint8_t * crev)
+bool atom_parse_cmd_header_stack(struct atom_context *ctx, int index, uint8_t *frev,
+				 uint8_t *crev, uint8_t *ps_size, uint8_t *ws_size)
 {
 	int offset = index * 2 + 4;
 	int idx = CU16(ctx->cmd_table + offset);
 	u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4);
+	u16 table_attrib = CU16(idx + 4);
 
 	if (!mct[index])
 		return false;
@@ -1334,9 +1335,19 @@  bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
 		*frev = CU8(idx + 2);
 	if (crev)
 		*crev = CU8(idx + 3);
+	if (ps_size)
+		*ps_size = (table_attrib & 0xe00) >> 8;
+	if (ws_size)
+		*ws_size = (table_attrib & 0xff);
 	return true;
 }
 
+bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *rev,
+			   uint8_t *crev)
+{
+	return atom_parse_cmd_header_stack(ctx, index, rev, crev, NULL, NULL);
+}
+
 int atom_allocate_fb_scratch(struct atom_context *ctx)
 {
 	int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index cd1b64a..ca21357 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -147,6 +147,8 @@  bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
 			    uint8_t *frev, uint8_t *crev, uint16_t *data_start);
 bool atom_parse_cmd_header(struct atom_context *ctx, int index,
 			   uint8_t *frev, uint8_t *crev);
+bool atom_parse_cmd_header_stack(struct atom_context *ctx, int index, uint8_t *rev,
+				 uint8_t *crev, uint8_t *ps_size, uint8_t *ws_size);
 int atom_allocate_fb_scratch(struct atom_context *ctx);
 #include "atom-types.h"
 #include "atombios.h"
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index c52fc30..36bcabd 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1398,12 +1398,19 @@  atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *conn
 				       ATOM_DEVICE_CRT_SUPPORT)) {
 		DAC_LOAD_DETECTION_PS_ALLOCATION args;
 		int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
-		uint8_t frev, crev;
+		uint8_t frev, crev, ps_size;
 
 		memset(&args, 0, sizeof(args));
 
-		if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+		if (!atom_parse_cmd_header_stack(rdev->mode_info.atom_context, index, &frev, &crev, &ps_size, NULL))
 			return false;
+					       
+		/* r4xx and some early rv5xx probe all DACs, this can cause distrubances in the force,
+		   also on other DACs.  - we can detect these tables as they have a 0 sized param stack */
+		if (ps_size == 0) {
+			DRM_DEBUG("not executing dac load detection table due to buggy atom table\n");
+			return false;
+		}
 
 		args.sDacload.ucMisc = 0;