Skip to contentSkip to conversation

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

PATCH New Dave Airlie 1 participant 1 message Apr 27, 2010

Subsystems (2)
lore
Share & tools
lore

Dave Airlie

author maintainer
#0 lore raw

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

From: Dave Airlie <[email protected]>

The DAC Load detection table is meant to take a parameter selecting the DAC to do load detection on. However on certain BIOS revisions it accept no parameters and load detects both DACs, with the result that load detecting on the second DAC causes flicker on the first, which isn't really acceptable.

We should code up a workaround function for these chips to workaround this case.

---
 drivers/gpu/drm/radeon/atom.c            |   15 +++++++++++++--
 drivers/gpu/drm/radeon/atom.h            |    2 ++
 drivers/gpu/drm/radeon/radeon_encoders.c |   11 +++++++++--
 3 files changed, 24 insertions(+), 4 deletions(-)
drivers/gpu/drm/radeon/atom.c +13 -2
index bcec2d7..6477ac5 100644
@@ -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);
drivers/gpu/drm/radeon/atom.h +2 -0
index cd1b64a..ca21357 100644
@@ -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"
drivers/gpu/drm/radeon/radeon_encoders.c +9 -2
index c52fc30..36bcabd 100644
@@ -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;
 
Signature · 5 lines
1.7.0.1


------------------------------------------------------------------------------
--