drm/i915: add DP test request handling
authorJesse Barnes <jbarnes@virtuousgeek.org>
Thu, 20 Oct 2011 22:09:17 +0000 (15:09 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 21 Oct 2011 06:22:01 +0000 (23:22 -0700)
DPCD 1.1+ adds some automated test infrastructure support.  Add support
for reading the IRQ source and jumping to a test handling routine if
needed.  Subsequent patches will handle particular tests; this patch
just ACKs any requested tests by default.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Keith Packard <keithp@keithp.com>
drivers/gpu/drm/i915/intel_dp.c
include/drm/drm_dp_helper.h

index e0ff908..58c827b 100644 (file)
@@ -1776,6 +1776,27 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
        return false;
 }
 
+static bool
+intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector)
+{
+       int ret;
+
+       ret = intel_dp_aux_native_read_retry(intel_dp,
+                                            DP_DEVICE_SERVICE_IRQ_VECTOR,
+                                            sink_irq_vector, 1);
+       if (!ret)
+               return false;
+
+       return true;
+}
+
+static void
+intel_dp_handle_test_request(struct intel_dp *intel_dp)
+{
+       /* NAK by default */
+       intel_dp_aux_native_write_1(intel_dp, DP_TEST_RESPONSE, DP_TEST_ACK);
+}
+
 /*
  * According to DP spec
  * 5.1.2:
@@ -1788,6 +1809,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
 static void
 intel_dp_check_link_status(struct intel_dp *intel_dp)
 {
+       u8 sink_irq_vector;
+
        if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON)
                return;
 
@@ -1806,6 +1829,20 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
                return;
        }
 
+       /* Try to read the source of the interrupt */
+       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+           intel_dp_get_sink_irq(intel_dp, &sink_irq_vector)) {
+               /* Clear interrupt source */
+               intel_dp_aux_native_write_1(intel_dp,
+                                           DP_DEVICE_SERVICE_IRQ_VECTOR,
+                                           sink_irq_vector);
+
+               if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST)
+                       intel_dp_handle_test_request(intel_dp);
+               if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ))
+                       DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
+       }
+
        if (!intel_channel_eq_ok(intel_dp)) {
                DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
                              drm_get_encoder_name(&intel_dp->base.base));
index 2b1a358..0d2f727 100644 (file)
 # define DP_PSR_CRC_VERIFICATION           (1 << 2)
 # define DP_PSR_FRAME_CAPTURE              (1 << 3)
 
+#define DP_DEVICE_SERVICE_IRQ_VECTOR       0x201
+# define DP_REMOTE_CONTROL_COMMAND_PENDING  (1 << 0)
+# define DP_AUTOMATED_TEST_REQUEST         (1 << 1)
+# define DP_CP_IRQ                         (1 << 2)
+# define DP_SINK_SPECIFIC_IRQ              (1 << 6)
+
 #define DP_LANE0_1_STATUS                  0x202
 #define DP_LANE2_3_STATUS                  0x203
 # define DP_LANE_CR_DONE                   (1 << 0)
 # define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK   0xc0
 # define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
 
+#define DP_TEST_REQUEST                            0x218
+# define DP_TEST_LINK_TRAINING             (1 << 0)
+# define DP_TEST_LINK_PATTERN              (1 << 1)
+# define DP_TEST_LINK_EDID_READ                    (1 << 2)
+# define DP_TEST_LINK_PHY_TEST_PATTERN     (1 << 3) /* DPCD >= 1.1 */
+
+#define DP_TEST_LINK_RATE                  0x219
+# define DP_LINK_RATE_162                  (0x6)
+# define DP_LINK_RATE_27                   (0xa)
+
+#define DP_TEST_LANE_COUNT                 0x220
+
+#define DP_TEST_PATTERN                            0x221
+
+#define DP_TEST_RESPONSE                   0x260
+# define DP_TEST_ACK                       (1 << 0)
+# define DP_TEST_NAK                       (1 << 1)
+# define DP_TEST_EDID_CHECKSUM_WRITE       (1 << 2)
+
 #define DP_SET_POWER                        0x600
 # define DP_SET_POWER_D0                    0x1
 # define DP_SET_POWER_D3                    0x2