diff mbox

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

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

Commit Message

Dave Airlie May 5, 2010, 1:03 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index 1d56983..c1c669a 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -1330,12 +1330,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;
@@ -1344,9 +1345,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 30293be..f2ea756 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1406,13 +1406,20 @@  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("DAC load detection isn't properly supported on this GPU\n");
+			return false;
+		}
+
 		args.sDacload.ucMisc = 0;
 
 		if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||
@@ -1452,8 +1459,8 @@  radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
 	uint32_t bios_0_scratch;
 
 	if (!atombios_dac_load_detect(encoder, connector)) {
-		DRM_DEBUG("detect returned false \n");
-		return connector_status_unknown;
+		DRM_DEBUG("dac detect returned false\n");
+		return connector_status_disconnected;
 	}
 
 	if (rdev->family >= CHIP_R600)