aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-09-09 19:06:13 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-12 13:36:09 +0100
commitb5c616a75428d85f92407e4509553f937b720630 (patch)
treeacd793c74e59365dd7f995df0fac2cd8530e2d5c /drivers/gpu/drm
parentec5da01e23eec303dd313aa62b8ed4712c488437 (diff)
drm/i915/sdvo: Poll command status 5 times without delay on read
The documentation says that an SDVO command takes a maximum of 15us to be processed by the device, and that it is sufficient to read the status byte 3 times (whilst the command is still in the PENDING state) for the driver to be confident that sufficient time has elapsed. We err on the safe side and try 5 times before giving up. The only question that remains: was the old behaviour derived by experiments with real hardware? A look into the murky history of UMS, implies that the behaviour was accidental and the current retry mechanism was solely designed to catch the status byte indicating PENDING with no reference to hardware behaviour. (commit ac9181c014638dbeb334b40b4029d0ccb2b7a0fc in xf86-video-intel) Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c71
1 files changed, 36 insertions, 35 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 96952d20cd2..a812d65fa31 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -462,54 +462,55 @@ static const char *cmd_status_names[] = {
"Scaling not supported"
};
-static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo,
- void *response, int response_len,
- u8 status)
+static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
+ void *response, int response_len)
{
+ u8 retry = 5;
+ u8 status;
int i;
+ /*
+ * The documentation states that all commands will be
+ * processed within 15µs, and that we need only poll
+ * the status byte a maximum of 3 times in order for the
+ * command to be complete.
+ *
+ * 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))
+ return false;
+ } while (status == SDVO_CMD_STATUS_PENDING && --retry);
+
DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo));
- for (i = 0; i < response_len; i++)
- DRM_LOG_KMS("%02X ", ((u8 *)response)[i]);
- for (; i < 8; i++)
- DRM_LOG_KMS(" ");
if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
DRM_LOG_KMS("(%s)", cmd_status_names[status]);
else
DRM_LOG_KMS("(??? %d)", status);
- DRM_LOG_KMS("\n");
-}
-static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
- void *response, int response_len)
-{
- int i;
- u8 status;
- u8 retry = 50;
-
- while (retry--) {
- /* Read the command response */
- for (i = 0; i < response_len; i++) {
- if (!intel_sdvo_read_byte(intel_sdvo,
- SDVO_I2C_RETURN_0 + i,
- &((u8 *)response)[i]))
- return false;
- }
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ goto log_fail;
- /* read the return status */
- if (!intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS,
- &status))
- return false;
+ /* Read the command response */
+ for (i = 0; i < response_len; i++) {
+ if (!intel_sdvo_read_byte(intel_sdvo,
+ SDVO_I2C_RETURN_0 + i,
+ &((u8 *)response)[i]))
+ goto log_fail;
+ DRM_LOG_KMS("%02X ", ((u8 *)response)[i]);
+ }
- intel_sdvo_debug_response(intel_sdvo, response, response_len,
- status);
- if (status != SDVO_CMD_STATUS_PENDING)
- break;
+ for (; i < 8; i++)
+ DRM_LOG_KMS(" ");
+ DRM_LOG_KMS("\n");
- mdelay(50);
- }
+ return true;
- return status == SDVO_CMD_STATUS_SUCCESS;
+log_fail:
+ DRM_LOG_KMS("\n");
+ return false;
}
static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)