Skip to content

Commit

Permalink
drm/i915/sdvo: If at first we don't succeed in reading the response, …
Browse files Browse the repository at this point in the history
…wait

We were not pausing after detecting the response was pending and so did
not allow the hardware sufficient time to complete before aborting. This
lead to transient failures whilst probing SDVO devices.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=30235
Reported-by: Knut Petersen <Knut_Petersen@t-online.de>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
  • Loading branch information
Chris Wilson committed Jan 25, 2011
1 parent 8e934db commit d121a5d
Showing 1 changed file with 23 additions and 23 deletions.
46 changes: 23 additions & 23 deletions drivers/gpu/drm/i915/intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,20 +473,6 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
return false;
}

i = 3;
while (status == SDVO_CMD_STATUS_PENDING && i--) {
if (!intel_sdvo_read_byte(intel_sdvo,
SDVO_I2C_CMD_STATUS,
&status))
return false;
}
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG_KMS("command returns response %s [%d]\n",
status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP ? cmd_status_names[status] : "???",
status);
return false;
}

return true;
}

Expand All @@ -497,6 +483,8 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
u8 status;
int i;

DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo));

/*
* The documentation states that all commands will be
* processed within 15µs, and that we need only poll
Expand All @@ -505,14 +493,19 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
*
* Check 5 times in case the hardware failed to read the docs.
*/
do {
if (!intel_sdvo_read_byte(intel_sdvo,
SDVO_I2C_CMD_STATUS,
&status))
goto log_fail;

while (status == SDVO_CMD_STATUS_PENDING && retry--) {
udelay(15);
if (!intel_sdvo_read_byte(intel_sdvo,
SDVO_I2C_CMD_STATUS,
&status))
return false;
} while (status == SDVO_CMD_STATUS_PENDING && --retry);
goto log_fail;
}

DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo));
if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
DRM_LOG_KMS("(%s)", cmd_status_names[status]);
else
Expand All @@ -533,7 +526,7 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
return true;

log_fail:
DRM_LOG_KMS("\n");
DRM_LOG_KMS("... failed\n");
return false;
}

Expand All @@ -550,14 +543,18 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
u8 ddc_bus)
{
/* This must be the immediately preceding write before the i2c xfer */
return intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_SET_CONTROL_BUS_SWITCH,
&ddc_bus, 1);
}

static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len)
{
return intel_sdvo_write_cmd(intel_sdvo, cmd, data, len);
if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len))
return false;

return intel_sdvo_read_response(intel_sdvo, NULL, 0);
}

static bool
Expand Down Expand Up @@ -859,18 +856,21 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)

intel_dip_infoframe_csum(&avi_if);

if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX,
if (!intel_sdvo_set_value(intel_sdvo,
SDVO_CMD_SET_HBUF_INDEX,
set_buf_index, 2))
return false;

for (i = 0; i < sizeof(avi_if); i += 8) {
if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA,
if (!intel_sdvo_set_value(intel_sdvo,
SDVO_CMD_SET_HBUF_DATA,
data, 8))
return false;
data++;
}

return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE,
return intel_sdvo_set_value(intel_sdvo,
SDVO_CMD_SET_HBUF_TXRATE,
&tx_rate, 1);
}

Expand Down

0 comments on commit d121a5d

Please sign in to comment.