aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2018-01-08 14:55:43 -0500
committerSean Paul <seanpaul@chromium.org>2018-01-08 14:58:44 -0500
commit20f24d776d1be6ecf353f21a158e7b716143e523 (patch)
treefcfb6175a596528b10f721d7085d42cf5d43141e
parent2320175feb74a11d3b287eead09bb5c0953cf27f (diff)
drm/i915: Implement HDCP for DisplayPort
This patch adds HDCP support for DisplayPort connectors by implementing the intel_hdcp_shim. Most of this is straightforward read/write from/to DPCD registers. One thing worth pointing out is the Aksv output bit. It wasn't easily separable like it's HDMI counterpart, so it's crammed in with the rest of it. Changes in v2: - Moved intel_hdcp_check_link out of intel_dp_check_link and only call it on short pulse. Since intel_hdcp_check_link does its own locking, this ensures we don't deadlock when intel_dp_check_link is called holding connection_mutex. - Rebased on drm-intel-next Changes in v3: - Initialize new worker Changes in v4: - Use intel_hdcp_init (Daniel) - Check for reauth requests in check_link (Ram) Changes in v5: - None Changes in v6: - Fix build warnings when printing ssize_t Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Ramalingam C <ramalingam.c@intel.com> Signed-off-by: Sean Paul <seanpaul@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20180108195545.218615-10-seanpaul@chromium.org
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c244
1 files changed, 237 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 35c5299feab6..68229f53d5b8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -36,7 +36,9 @@
36#include <drm/drm_atomic_helper.h> 36#include <drm/drm_atomic_helper.h>
37#include <drm/drm_crtc.h> 37#include <drm/drm_crtc.h>
38#include <drm/drm_crtc_helper.h> 38#include <drm/drm_crtc_helper.h>
39#include <drm/drm_dp_helper.h>
39#include <drm/drm_edid.h> 40#include <drm/drm_edid.h>
41#include <drm/drm_hdcp.h>
40#include "intel_drv.h" 42#include "intel_drv.h"
41#include <drm/i915_drm.h> 43#include <drm/i915_drm.h>
42#include "i915_drv.h" 44#include "i915_drv.h"
@@ -1025,10 +1027,29 @@ static uint32_t skl_get_aux_send_ctl(struct intel_dp *intel_dp,
1025 DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); 1027 DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
1026} 1028}
1027 1029
1030static uint32_t intel_dp_get_aux_send_ctl(struct intel_dp *intel_dp,
1031 bool has_aux_irq,
1032 int send_bytes,
1033 uint32_t aux_clock_divider,
1034 bool aksv_write)
1035{
1036 uint32_t val = 0;
1037
1038 if (aksv_write) {
1039 send_bytes += 5;
1040 val |= DP_AUX_CH_CTL_AUX_AKSV_SELECT;
1041 }
1042
1043 return val | intel_dp->get_aux_send_ctl(intel_dp,
1044 has_aux_irq,
1045 send_bytes,
1046 aux_clock_divider);
1047}
1048
1028static int 1049static int
1029intel_dp_aux_ch(struct intel_dp *intel_dp, 1050intel_dp_aux_ch(struct intel_dp *intel_dp,
1030 const uint8_t *send, int send_bytes, 1051 const uint8_t *send, int send_bytes,
1031 uint8_t *recv, int recv_size) 1052 uint8_t *recv, int recv_size, bool aksv_write)
1032{ 1053{
1033 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 1054 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
1034 struct drm_i915_private *dev_priv = 1055 struct drm_i915_private *dev_priv =
@@ -1088,10 +1109,11 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
1088 } 1109 }
1089 1110
1090 while ((aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, clock++))) { 1111 while ((aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, clock++))) {
1091 u32 send_ctl = intel_dp->get_aux_send_ctl(intel_dp, 1112 u32 send_ctl = intel_dp_get_aux_send_ctl(intel_dp,
1092 has_aux_irq, 1113 has_aux_irq,
1093 send_bytes, 1114 send_bytes,
1094 aux_clock_divider); 1115 aux_clock_divider,
1116 aksv_write);
1095 1117
1096 /* Must try at least 3 times according to DP spec */ 1118 /* Must try at least 3 times according to DP spec */
1097 for (try = 0; try < 5; try++) { 1119 for (try = 0; try < 5; try++) {
@@ -1228,7 +1250,8 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
1228 if (msg->buffer) 1250 if (msg->buffer)
1229 memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size); 1251 memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size);
1230 1252
1231 ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize); 1253 ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize,
1254 false);
1232 if (ret > 0) { 1255 if (ret > 0) {
1233 msg->reply = rxbuf[0] >> 4; 1256 msg->reply = rxbuf[0] >> 4;
1234 1257
@@ -1250,7 +1273,8 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
1250 if (WARN_ON(rxsize > 20)) 1273 if (WARN_ON(rxsize > 20))
1251 return -E2BIG; 1274 return -E2BIG;
1252 1275
1253 ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize); 1276 ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize,
1277 false);
1254 if (ret > 0) { 1278 if (ret > 0) {
1255 msg->reply = rxbuf[0] >> 4; 1279 msg->reply = rxbuf[0] >> 4;
1256 /* 1280 /*
@@ -4985,6 +5009,203 @@ void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
4985 pps_unlock(intel_dp); 5009 pps_unlock(intel_dp);
4986} 5010}
4987 5011
5012static
5013int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
5014 u8 *an)
5015{
5016 struct intel_dp *intel_dp = enc_to_intel_dp(&intel_dig_port->base.base);
5017 uint8_t txbuf[4], rxbuf[2], reply = 0;
5018 ssize_t dpcd_ret;
5019 int ret;
5020
5021 /* Output An first, that's easy */
5022 dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN,
5023 an, DRM_HDCP_AN_LEN);
5024 if (dpcd_ret != DRM_HDCP_AN_LEN) {
5025 DRM_ERROR("Failed to write An over DP/AUX (%zd)\n", dpcd_ret);
5026 return dpcd_ret >= 0 ? -EIO : dpcd_ret;
5027 }
5028
5029 /*
5030 * Since Aksv is Oh-So-Secret, we can't access it in software. So in
5031 * order to get it on the wire, we need to create the AUX header as if
5032 * we were writing the data, and then tickle the hardware to output the
5033 * data once the header is sent out.
5034 */
5035 txbuf[0] = (DP_AUX_NATIVE_WRITE << 4) |
5036 ((DP_AUX_HDCP_AKSV >> 16) & 0xf);
5037 txbuf[1] = (DP_AUX_HDCP_AKSV >> 8) & 0xff;
5038 txbuf[2] = DP_AUX_HDCP_AKSV & 0xff;
5039 txbuf[3] = DRM_HDCP_KSV_LEN - 1;
5040
5041 ret = intel_dp_aux_ch(intel_dp, txbuf, sizeof(txbuf), rxbuf,
5042 sizeof(rxbuf), true);
5043 if (ret < 0) {
5044 DRM_ERROR("Write Aksv over DP/AUX failed (%d)\n", ret);
5045 return ret;
5046 } else if (ret == 0) {
5047 DRM_ERROR("Aksv write over DP/AUX was empty\n");
5048 return -EIO;
5049 }
5050
5051 reply = (rxbuf[0] >> 4) & DP_AUX_NATIVE_REPLY_MASK;
5052 return reply == DP_AUX_NATIVE_REPLY_ACK ? 0 : -EIO;
5053}
5054
5055static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
5056 u8 *bksv)
5057{
5058 ssize_t ret;
5059 ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
5060 DRM_HDCP_KSV_LEN);
5061 if (ret != DRM_HDCP_KSV_LEN) {
5062 DRM_ERROR("Read Bksv from DP/AUX failed (%zd)\n", ret);
5063 return ret >= 0 ? -EIO : ret;
5064 }
5065 return 0;
5066}
5067
5068static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
5069 u8 *bstatus)
5070{
5071 ssize_t ret;
5072 /*
5073 * For some reason the HDMI and DP HDCP specs call this register
5074 * definition by different names. In the HDMI spec, it's called BSTATUS,
5075 * but in DP it's called BINFO.
5076 */
5077 ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO,
5078 bstatus, DRM_HDCP_BSTATUS_LEN);
5079 if (ret != DRM_HDCP_BSTATUS_LEN) {
5080 DRM_ERROR("Read bstatus from DP/AUX failed (%zd)\n", ret);
5081 return ret >= 0 ? -EIO : ret;
5082 }
5083 return 0;
5084}
5085
5086static
5087int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
5088 bool *repeater_present)
5089{
5090 ssize_t ret;
5091 u8 bcaps;
5092 ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS,
5093 &bcaps, 1);
5094 if (ret != 1) {
5095 DRM_ERROR("Read bcaps from DP/AUX failed (%zd)\n", ret);
5096 return ret >= 0 ? -EIO : ret;
5097 }
5098 *repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
5099 return 0;
5100}
5101
5102static
5103int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
5104 u8 *ri_prime)
5105{
5106 ssize_t ret;
5107 ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
5108 ri_prime, DRM_HDCP_RI_LEN);
5109 if (ret != DRM_HDCP_RI_LEN) {
5110 DRM_ERROR("Read Ri' from DP/AUX failed (%zd)\n", ret);
5111 return ret >= 0 ? -EIO : ret;
5112 }
5113 return 0;
5114}
5115
5116static
5117int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
5118 bool *ksv_ready)
5119{
5120 ssize_t ret;
5121 u8 bstatus;
5122 ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
5123 &bstatus, 1);
5124 if (ret != 1) {
5125 DRM_ERROR("Read bstatus from DP/AUX failed (%zd)\n", ret);
5126 return ret >= 0 ? -EIO : ret;
5127 }
5128 *ksv_ready = bstatus & DP_BSTATUS_READY;
5129 return 0;
5130}
5131
5132static
5133int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
5134 int num_downstream, u8 *ksv_fifo)
5135{
5136 ssize_t ret;
5137 int i;
5138
5139 /* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
5140 for (i = 0; i < num_downstream; i += 3) {
5141 size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
5142 ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
5143 DP_AUX_HDCP_KSV_FIFO,
5144 ksv_fifo + i * DRM_HDCP_KSV_LEN,
5145 len);
5146 if (ret != len) {
5147 DRM_ERROR("Read ksv[%d] from DP/AUX failed (%zd)\n", i,
5148 ret);
5149 return ret >= 0 ? -EIO : ret;
5150 }
5151 }
5152 return 0;
5153}
5154
5155static
5156int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
5157 int i, u32 *part)
5158{
5159 ssize_t ret;
5160
5161 if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
5162 return -EINVAL;
5163
5164 ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
5165 DP_AUX_HDCP_V_PRIME(i), part,
5166 DRM_HDCP_V_PRIME_PART_LEN);
5167 if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
5168 DRM_ERROR("Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
5169 return ret >= 0 ? -EIO : ret;
5170 }
5171 return 0;
5172}
5173
5174static
5175int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
5176 bool enable)
5177{
5178 /* Not used for single stream DisplayPort setups */
5179 return 0;
5180}
5181
5182static
5183bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
5184{
5185 ssize_t ret;
5186 u8 bstatus;
5187 ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
5188 &bstatus, 1);
5189 if (ret != 1) {
5190 DRM_ERROR("Read bstatus from DP/AUX failed (%zd)\n", ret);
5191 return ret >= 0 ? -EIO : ret;
5192 }
5193 return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ));
5194}
5195
5196static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
5197 .write_an_aksv = intel_dp_hdcp_write_an_aksv,
5198 .read_bksv = intel_dp_hdcp_read_bksv,
5199 .read_bstatus = intel_dp_hdcp_read_bstatus,
5200 .repeater_present = intel_dp_hdcp_repeater_present,
5201 .read_ri_prime = intel_dp_hdcp_read_ri_prime,
5202 .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
5203 .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
5204 .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
5205 .toggle_signalling = intel_dp_hdcp_toggle_signalling,
5206 .check_link = intel_dp_hdcp_check_link,
5207};
5208
4988static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) 5209static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
4989{ 5210{
4990 struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); 5211 struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
@@ -5150,6 +5371,9 @@ err:
5150 drm_modeset_acquire_fini(&ctx); 5371 drm_modeset_acquire_fini(&ctx);
5151 WARN(iret, "Acquiring modeset locks failed with %i\n", iret); 5372 WARN(iret, "Acquiring modeset locks failed with %i\n", iret);
5152 5373
5374 /* Short pulse can signify loss of hdcp authentication */
5375 intel_hdcp_check_link(intel_dp->attached_connector);
5376
5153 if (!handled) { 5377 if (!handled) {
5154 intel_dp->detect_done = false; 5378 intel_dp->detect_done = false;
5155 goto put_power; 5379 goto put_power;
@@ -6128,6 +6352,12 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
6128 6352
6129 intel_dp_add_properties(intel_dp, connector); 6353 intel_dp_add_properties(intel_dp, connector);
6130 6354
6355 if (INTEL_GEN(dev_priv) >= 9 && !intel_dp_is_edp(intel_dp)) {
6356 int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
6357 if (ret)
6358 DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
6359 }
6360
6131 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written 6361 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
6132 * 0xd. Failure to do so will result in spurious interrupts being 6362 * 0xd. Failure to do so will result in spurious interrupts being
6133 * generated on the port when a cable is not attached. 6363 * generated on the port when a cable is not attached.