diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-10-20 15:09:17 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-10-20 23:22:01 -0700 |
commit | a60f0e38d72a5e24085d6e7e27a4cadc20ae268a (patch) | |
tree | 65dfb758c4b13423203aeb8535f547b5718cd256 | |
parent | a2006cf5a7ad3463e7c1e9da2c4bc90499427558 (diff) |
drm/i915: add DP test request handling
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>
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 37 | ||||
-rw-r--r-- | include/drm/drm_dp_helper.h | 25 |
2 files changed, 62 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e0ff9085fd8..58c827b52a2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -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)); diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 2b1a3585f8d..0d2f727e96b 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -153,6 +153,12 @@ # 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) @@ -185,6 +191,25 @@ # 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 |