drm/i915/sdvo: Poll command status 5 times without delay on read
[pandora-kernel.git] / drivers / gpu / drm / i915 / intel_sdvo.c
index 96952d2..a812d65 100644 (file)
@@ -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)