1d079b7e4SSean Paul /* SPDX-License-Identifier: MIT */
2d079b7e4SSean Paul /*
3d079b7e4SSean Paul * Copyright (C) 2020 Google, Inc.
4d079b7e4SSean Paul *
5d079b7e4SSean Paul * Authors:
6d079b7e4SSean Paul * Sean Paul <seanpaul@chromium.org>
7d079b7e4SSean Paul */
8d079b7e4SSean Paul
9da68386dSThomas Zimmermann #include <drm/display/drm_dp_helper.h>
10da68386dSThomas Zimmermann #include <drm/display/drm_dp_mst_helper.h>
116a99099fSThomas Zimmermann #include <drm/display/drm_hdcp_helper.h>
12d079b7e4SSean Paul #include <drm/drm_print.h>
13d079b7e4SSean Paul
14*801543b2SJani Nikula #include "i915_reg.h"
151fa01409SSean Paul #include "intel_ddi.h"
167785ae0bSVille Syrjälä #include "intel_de.h"
17b23109c5SJani Nikula #include "intel_display_types.h"
18d079b7e4SSean Paul #include "intel_dp.h"
19b23109c5SJani Nikula #include "intel_dp_hdcp.h"
20d079b7e4SSean Paul #include "intel_hdcp.h"
219e6a82b9SJani Nikula #include "intel_hdcp_regs.h"
22d079b7e4SSean Paul
transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)236a08cbdaSVille Syrjälä static u32 transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
241a67a168SAnshuman Gupta {
251a67a168SAnshuman Gupta switch (cpu_transcoder) {
261a67a168SAnshuman Gupta case TRANSCODER_A:
276a08cbdaSVille Syrjälä return HDCP_STATUS_STREAM_A_ENC;
281a67a168SAnshuman Gupta case TRANSCODER_B:
296a08cbdaSVille Syrjälä return HDCP_STATUS_STREAM_B_ENC;
301a67a168SAnshuman Gupta case TRANSCODER_C:
316a08cbdaSVille Syrjälä return HDCP_STATUS_STREAM_C_ENC;
321a67a168SAnshuman Gupta case TRANSCODER_D:
336a08cbdaSVille Syrjälä return HDCP_STATUS_STREAM_D_ENC;
341a67a168SAnshuman Gupta default:
356a08cbdaSVille Syrjälä return 0;
361a67a168SAnshuman Gupta }
371a67a168SAnshuman Gupta }
381a67a168SAnshuman Gupta
intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp * hdcp,int timeout)39d079b7e4SSean Paul static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
40d079b7e4SSean Paul {
41d079b7e4SSean Paul long ret;
42d079b7e4SSean Paul
43d079b7e4SSean Paul #define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
44d079b7e4SSean Paul ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
45d079b7e4SSean Paul msecs_to_jiffies(timeout));
46d079b7e4SSean Paul
47d079b7e4SSean Paul if (!ret)
48d079b7e4SSean Paul DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n");
49d079b7e4SSean Paul }
50d079b7e4SSean Paul
51d079b7e4SSean Paul static
intel_dp_hdcp_write_an_aksv(struct intel_digital_port * dig_port,u8 * an)52d079b7e4SSean Paul int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
53d079b7e4SSean Paul u8 *an)
54d079b7e4SSean Paul {
55d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
56d079b7e4SSean Paul u8 aksv[DRM_HDCP_KSV_LEN] = {};
57d079b7e4SSean Paul ssize_t dpcd_ret;
58d079b7e4SSean Paul
59d079b7e4SSean Paul /* Output An first, that's easy */
60d079b7e4SSean Paul dpcd_ret = drm_dp_dpcd_write(&dig_port->dp.aux, DP_AUX_HDCP_AN,
61d079b7e4SSean Paul an, DRM_HDCP_AN_LEN);
62d079b7e4SSean Paul if (dpcd_ret != DRM_HDCP_AN_LEN) {
63d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
64d079b7e4SSean Paul "Failed to write An over DP/AUX (%zd)\n",
65d079b7e4SSean Paul dpcd_ret);
66d079b7e4SSean Paul return dpcd_ret >= 0 ? -EIO : dpcd_ret;
67d079b7e4SSean Paul }
68d079b7e4SSean Paul
69d079b7e4SSean Paul /*
70d079b7e4SSean Paul * Since Aksv is Oh-So-Secret, we can't access it in software. So we
71d079b7e4SSean Paul * send an empty buffer of the correct length through the DP helpers. On
72d079b7e4SSean Paul * the other side, in the transfer hook, we'll generate a flag based on
73d079b7e4SSean Paul * the destination address which will tickle the hardware to output the
74d079b7e4SSean Paul * Aksv on our behalf after the header is sent.
75d079b7e4SSean Paul */
76d079b7e4SSean Paul dpcd_ret = drm_dp_dpcd_write(&dig_port->dp.aux, DP_AUX_HDCP_AKSV,
77d079b7e4SSean Paul aksv, DRM_HDCP_KSV_LEN);
78d079b7e4SSean Paul if (dpcd_ret != DRM_HDCP_KSV_LEN) {
79d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
80d079b7e4SSean Paul "Failed to write Aksv over DP/AUX (%zd)\n",
81d079b7e4SSean Paul dpcd_ret);
82d079b7e4SSean Paul return dpcd_ret >= 0 ? -EIO : dpcd_ret;
83d079b7e4SSean Paul }
84d079b7e4SSean Paul return 0;
85d079b7e4SSean Paul }
86d079b7e4SSean Paul
intel_dp_hdcp_read_bksv(struct intel_digital_port * dig_port,u8 * bksv)87d079b7e4SSean Paul static int intel_dp_hdcp_read_bksv(struct intel_digital_port *dig_port,
88d079b7e4SSean Paul u8 *bksv)
89d079b7e4SSean Paul {
90d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
91d079b7e4SSean Paul ssize_t ret;
92d079b7e4SSean Paul
93d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
94d079b7e4SSean Paul DRM_HDCP_KSV_LEN);
95d079b7e4SSean Paul if (ret != DRM_HDCP_KSV_LEN) {
96d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
97d079b7e4SSean Paul "Read Bksv from DP/AUX failed (%zd)\n", ret);
98d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
99d079b7e4SSean Paul }
100d079b7e4SSean Paul return 0;
101d079b7e4SSean Paul }
102d079b7e4SSean Paul
intel_dp_hdcp_read_bstatus(struct intel_digital_port * dig_port,u8 * bstatus)103d079b7e4SSean Paul static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *dig_port,
104d079b7e4SSean Paul u8 *bstatus)
105d079b7e4SSean Paul {
106d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
107d079b7e4SSean Paul ssize_t ret;
108d079b7e4SSean Paul
109d079b7e4SSean Paul /*
110d079b7e4SSean Paul * For some reason the HDMI and DP HDCP specs call this register
111d079b7e4SSean Paul * definition by different names. In the HDMI spec, it's called BSTATUS,
112d079b7e4SSean Paul * but in DP it's called BINFO.
113d079b7e4SSean Paul */
114d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BINFO,
115d079b7e4SSean Paul bstatus, DRM_HDCP_BSTATUS_LEN);
116d079b7e4SSean Paul if (ret != DRM_HDCP_BSTATUS_LEN) {
117d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
118d079b7e4SSean Paul "Read bstatus from DP/AUX failed (%zd)\n", ret);
119d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
120d079b7e4SSean Paul }
121d079b7e4SSean Paul return 0;
122d079b7e4SSean Paul }
123d079b7e4SSean Paul
124d079b7e4SSean Paul static
intel_dp_hdcp_read_bcaps(struct intel_digital_port * dig_port,u8 * bcaps)125d079b7e4SSean Paul int intel_dp_hdcp_read_bcaps(struct intel_digital_port *dig_port,
126d079b7e4SSean Paul u8 *bcaps)
127d079b7e4SSean Paul {
128d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
129d079b7e4SSean Paul ssize_t ret;
130d079b7e4SSean Paul
131d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BCAPS,
132d079b7e4SSean Paul bcaps, 1);
133d079b7e4SSean Paul if (ret != 1) {
134d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
135d079b7e4SSean Paul "Read bcaps from DP/AUX failed (%zd)\n", ret);
136d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
137d079b7e4SSean Paul }
138d079b7e4SSean Paul
139d079b7e4SSean Paul return 0;
140d079b7e4SSean Paul }
141d079b7e4SSean Paul
142d079b7e4SSean Paul static
intel_dp_hdcp_repeater_present(struct intel_digital_port * dig_port,bool * repeater_present)143d079b7e4SSean Paul int intel_dp_hdcp_repeater_present(struct intel_digital_port *dig_port,
144d079b7e4SSean Paul bool *repeater_present)
145d079b7e4SSean Paul {
146d079b7e4SSean Paul ssize_t ret;
147d079b7e4SSean Paul u8 bcaps;
148d079b7e4SSean Paul
149d079b7e4SSean Paul ret = intel_dp_hdcp_read_bcaps(dig_port, &bcaps);
150d079b7e4SSean Paul if (ret)
151d079b7e4SSean Paul return ret;
152d079b7e4SSean Paul
153d079b7e4SSean Paul *repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
154d079b7e4SSean Paul return 0;
155d079b7e4SSean Paul }
156d079b7e4SSean Paul
157d079b7e4SSean Paul static
intel_dp_hdcp_read_ri_prime(struct intel_digital_port * dig_port,u8 * ri_prime)158d079b7e4SSean Paul int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *dig_port,
159d079b7e4SSean Paul u8 *ri_prime)
160d079b7e4SSean Paul {
161d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
162d079b7e4SSean Paul ssize_t ret;
163d079b7e4SSean Paul
164d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
165d079b7e4SSean Paul ri_prime, DRM_HDCP_RI_LEN);
166d079b7e4SSean Paul if (ret != DRM_HDCP_RI_LEN) {
167d079b7e4SSean Paul drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed (%zd)\n",
168d079b7e4SSean Paul ret);
169d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
170d079b7e4SSean Paul }
171d079b7e4SSean Paul return 0;
172d079b7e4SSean Paul }
173d079b7e4SSean Paul
174d079b7e4SSean Paul static
intel_dp_hdcp_read_ksv_ready(struct intel_digital_port * dig_port,bool * ksv_ready)175d079b7e4SSean Paul int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *dig_port,
176d079b7e4SSean Paul bool *ksv_ready)
177d079b7e4SSean Paul {
178d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
179d079b7e4SSean Paul ssize_t ret;
180d079b7e4SSean Paul u8 bstatus;
181d079b7e4SSean Paul
182d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
183d079b7e4SSean Paul &bstatus, 1);
184d079b7e4SSean Paul if (ret != 1) {
185d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
186d079b7e4SSean Paul "Read bstatus from DP/AUX failed (%zd)\n", ret);
187d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
188d079b7e4SSean Paul }
189d079b7e4SSean Paul *ksv_ready = bstatus & DP_BSTATUS_READY;
190d079b7e4SSean Paul return 0;
191d079b7e4SSean Paul }
192d079b7e4SSean Paul
193d079b7e4SSean Paul static
intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port * dig_port,int num_downstream,u8 * ksv_fifo)194d079b7e4SSean Paul int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port,
195d079b7e4SSean Paul int num_downstream, u8 *ksv_fifo)
196d079b7e4SSean Paul {
197d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
198d079b7e4SSean Paul ssize_t ret;
199d079b7e4SSean Paul int i;
200d079b7e4SSean Paul
201d079b7e4SSean Paul /* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
202d079b7e4SSean Paul for (i = 0; i < num_downstream; i += 3) {
203d079b7e4SSean Paul size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
204d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux,
205d079b7e4SSean Paul DP_AUX_HDCP_KSV_FIFO,
206d079b7e4SSean Paul ksv_fifo + i * DRM_HDCP_KSV_LEN,
207d079b7e4SSean Paul len);
208d079b7e4SSean Paul if (ret != len) {
209d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
210d079b7e4SSean Paul "Read ksv[%d] from DP/AUX failed (%zd)\n",
211d079b7e4SSean Paul i, ret);
212d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
213d079b7e4SSean Paul }
214d079b7e4SSean Paul }
215d079b7e4SSean Paul return 0;
216d079b7e4SSean Paul }
217d079b7e4SSean Paul
218d079b7e4SSean Paul static
intel_dp_hdcp_read_v_prime_part(struct intel_digital_port * dig_port,int i,u32 * part)219d079b7e4SSean Paul int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *dig_port,
220d079b7e4SSean Paul int i, u32 *part)
221d079b7e4SSean Paul {
222d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
223d079b7e4SSean Paul ssize_t ret;
224d079b7e4SSean Paul
225d079b7e4SSean Paul if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
226d079b7e4SSean Paul return -EINVAL;
227d079b7e4SSean Paul
228d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux,
229d079b7e4SSean Paul DP_AUX_HDCP_V_PRIME(i), part,
230d079b7e4SSean Paul DRM_HDCP_V_PRIME_PART_LEN);
231d079b7e4SSean Paul if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
232d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
233d079b7e4SSean Paul "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
234d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
235d079b7e4SSean Paul }
236d079b7e4SSean Paul return 0;
237d079b7e4SSean Paul }
238d079b7e4SSean Paul
239d079b7e4SSean Paul static
intel_dp_hdcp_toggle_signalling(struct intel_digital_port * dig_port,enum transcoder cpu_transcoder,bool enable)240d079b7e4SSean Paul int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *dig_port,
241d079b7e4SSean Paul enum transcoder cpu_transcoder,
242d079b7e4SSean Paul bool enable)
243d079b7e4SSean Paul {
244d079b7e4SSean Paul /* Not used for single stream DisplayPort setups */
245d079b7e4SSean Paul return 0;
246d079b7e4SSean Paul }
247d079b7e4SSean Paul
248d079b7e4SSean Paul static
intel_dp_hdcp_check_link(struct intel_digital_port * dig_port,struct intel_connector * connector)249038bac89SSean Paul bool intel_dp_hdcp_check_link(struct intel_digital_port *dig_port,
250038bac89SSean Paul struct intel_connector *connector)
251d079b7e4SSean Paul {
252d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
253d079b7e4SSean Paul ssize_t ret;
254d079b7e4SSean Paul u8 bstatus;
255d079b7e4SSean Paul
256d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
257d079b7e4SSean Paul &bstatus, 1);
258d079b7e4SSean Paul if (ret != 1) {
259d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
260d079b7e4SSean Paul "Read bstatus from DP/AUX failed (%zd)\n", ret);
261d079b7e4SSean Paul return false;
262d079b7e4SSean Paul }
263d079b7e4SSean Paul
264d079b7e4SSean Paul return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ));
265d079b7e4SSean Paul }
266d079b7e4SSean Paul
267d079b7e4SSean Paul static
intel_dp_hdcp_capable(struct intel_digital_port * dig_port,bool * hdcp_capable)268d079b7e4SSean Paul int intel_dp_hdcp_capable(struct intel_digital_port *dig_port,
269d079b7e4SSean Paul bool *hdcp_capable)
270d079b7e4SSean Paul {
271d079b7e4SSean Paul ssize_t ret;
272d079b7e4SSean Paul u8 bcaps;
273d079b7e4SSean Paul
274d079b7e4SSean Paul ret = intel_dp_hdcp_read_bcaps(dig_port, &bcaps);
275d079b7e4SSean Paul if (ret)
276d079b7e4SSean Paul return ret;
277d079b7e4SSean Paul
278d079b7e4SSean Paul *hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
279d079b7e4SSean Paul return 0;
280d079b7e4SSean Paul }
281d079b7e4SSean Paul
282d079b7e4SSean Paul struct hdcp2_dp_errata_stream_type {
283d079b7e4SSean Paul u8 msg_id;
284d079b7e4SSean Paul u8 stream_type;
285d079b7e4SSean Paul } __packed;
286d079b7e4SSean Paul
287d079b7e4SSean Paul struct hdcp2_dp_msg_data {
288d079b7e4SSean Paul u8 msg_id;
289d079b7e4SSean Paul u32 offset;
290d079b7e4SSean Paul bool msg_detectable;
291d079b7e4SSean Paul u32 timeout;
292d079b7e4SSean Paul u32 timeout2; /* Added for non_paired situation */
293989cf9a9SAnshuman Gupta /* Timeout to read entire msg */
294989cf9a9SAnshuman Gupta u32 msg_read_timeout;
295d079b7e4SSean Paul };
296d079b7e4SSean Paul
297d079b7e4SSean Paul static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = {
298989cf9a9SAnshuman Gupta { HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0, 0},
299d079b7e4SSean Paul { HDCP_2_2_AKE_SEND_CERT, DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
300989cf9a9SAnshuman Gupta false, HDCP_2_2_CERT_TIMEOUT_MS, 0, HDCP_2_2_DP_CERT_READ_TIMEOUT_MS},
301d079b7e4SSean Paul { HDCP_2_2_AKE_NO_STORED_KM, DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
302989cf9a9SAnshuman Gupta false, 0, 0, 0 },
303d079b7e4SSean Paul { HDCP_2_2_AKE_STORED_KM, DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
304989cf9a9SAnshuman Gupta false, 0, 0, 0 },
305d079b7e4SSean Paul { HDCP_2_2_AKE_SEND_HPRIME, DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
306d079b7e4SSean Paul true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
307989cf9a9SAnshuman Gupta HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS, HDCP_2_2_DP_HPRIME_READ_TIMEOUT_MS},
308d079b7e4SSean Paul { HDCP_2_2_AKE_SEND_PAIRING_INFO,
309d079b7e4SSean Paul DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
310989cf9a9SAnshuman Gupta HDCP_2_2_PAIRING_TIMEOUT_MS, 0, HDCP_2_2_DP_PAIRING_READ_TIMEOUT_MS },
311989cf9a9SAnshuman Gupta { HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0, 0 },
312d079b7e4SSean Paul { HDCP_2_2_LC_SEND_LPRIME, DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
313989cf9a9SAnshuman Gupta false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0, 0 },
314d079b7e4SSean Paul { HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET, false,
315989cf9a9SAnshuman Gupta 0, 0, 0 },
316d079b7e4SSean Paul { HDCP_2_2_REP_SEND_RECVID_LIST,
317d079b7e4SSean Paul DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
318989cf9a9SAnshuman Gupta HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0, 0 },
319d079b7e4SSean Paul { HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET, false,
320989cf9a9SAnshuman Gupta 0, 0, 0 },
321d079b7e4SSean Paul { HDCP_2_2_REP_STREAM_MANAGE,
322d079b7e4SSean Paul DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
323989cf9a9SAnshuman Gupta 0, 0, 0},
324d079b7e4SSean Paul { HDCP_2_2_REP_STREAM_READY, DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
325989cf9a9SAnshuman Gupta false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0, 0 },
326d079b7e4SSean Paul /* local define to shovel this through the write_2_2 interface */
327d079b7e4SSean Paul #define HDCP_2_2_ERRATA_DP_STREAM_TYPE 50
328d079b7e4SSean Paul { HDCP_2_2_ERRATA_DP_STREAM_TYPE,
329d079b7e4SSean Paul DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
330d079b7e4SSean Paul 0, 0 },
331d079b7e4SSean Paul };
332d079b7e4SSean Paul
333d079b7e4SSean Paul static int
intel_dp_hdcp2_read_rx_status(struct intel_digital_port * dig_port,u8 * rx_status)334d079b7e4SSean Paul intel_dp_hdcp2_read_rx_status(struct intel_digital_port *dig_port,
335d079b7e4SSean Paul u8 *rx_status)
336d079b7e4SSean Paul {
337d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
338d079b7e4SSean Paul ssize_t ret;
339d079b7e4SSean Paul
340d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux,
341d079b7e4SSean Paul DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
342d079b7e4SSean Paul HDCP_2_2_DP_RXSTATUS_LEN);
343d079b7e4SSean Paul if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
344d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
345d079b7e4SSean Paul "Read bstatus from DP/AUX failed (%zd)\n", ret);
346d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
347d079b7e4SSean Paul }
348d079b7e4SSean Paul
349d079b7e4SSean Paul return 0;
350d079b7e4SSean Paul }
351d079b7e4SSean Paul
352d079b7e4SSean Paul static
hdcp2_detect_msg_availability(struct intel_digital_port * dig_port,u8 msg_id,bool * msg_ready)353d079b7e4SSean Paul int hdcp2_detect_msg_availability(struct intel_digital_port *dig_port,
354d079b7e4SSean Paul u8 msg_id, bool *msg_ready)
355d079b7e4SSean Paul {
356d079b7e4SSean Paul u8 rx_status;
357d079b7e4SSean Paul int ret;
358d079b7e4SSean Paul
359d079b7e4SSean Paul *msg_ready = false;
360d079b7e4SSean Paul ret = intel_dp_hdcp2_read_rx_status(dig_port, &rx_status);
361d079b7e4SSean Paul if (ret < 0)
362d079b7e4SSean Paul return ret;
363d079b7e4SSean Paul
364d079b7e4SSean Paul switch (msg_id) {
365d079b7e4SSean Paul case HDCP_2_2_AKE_SEND_HPRIME:
366d079b7e4SSean Paul if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
367d079b7e4SSean Paul *msg_ready = true;
368d079b7e4SSean Paul break;
369d079b7e4SSean Paul case HDCP_2_2_AKE_SEND_PAIRING_INFO:
370d079b7e4SSean Paul if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
371d079b7e4SSean Paul *msg_ready = true;
372d079b7e4SSean Paul break;
373d079b7e4SSean Paul case HDCP_2_2_REP_SEND_RECVID_LIST:
374d079b7e4SSean Paul if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
375d079b7e4SSean Paul *msg_ready = true;
376d079b7e4SSean Paul break;
377d079b7e4SSean Paul default:
378d079b7e4SSean Paul DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
379d079b7e4SSean Paul return -EINVAL;
380d079b7e4SSean Paul }
381d079b7e4SSean Paul
382d079b7e4SSean Paul return 0;
383d079b7e4SSean Paul }
384d079b7e4SSean Paul
385d079b7e4SSean Paul static ssize_t
intel_dp_hdcp2_wait_for_msg(struct intel_digital_port * dig_port,const struct hdcp2_dp_msg_data * hdcp2_msg_data)386d079b7e4SSean Paul intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *dig_port,
387d079b7e4SSean Paul const struct hdcp2_dp_msg_data *hdcp2_msg_data)
388d079b7e4SSean Paul {
389d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
390d079b7e4SSean Paul struct intel_dp *dp = &dig_port->dp;
391d079b7e4SSean Paul struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
392d079b7e4SSean Paul u8 msg_id = hdcp2_msg_data->msg_id;
393d079b7e4SSean Paul int ret, timeout;
394d079b7e4SSean Paul bool msg_ready = false;
395d079b7e4SSean Paul
396d079b7e4SSean Paul if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
397d079b7e4SSean Paul timeout = hdcp2_msg_data->timeout2;
398d079b7e4SSean Paul else
399d079b7e4SSean Paul timeout = hdcp2_msg_data->timeout;
400d079b7e4SSean Paul
401d079b7e4SSean Paul /*
402d079b7e4SSean Paul * There is no way to detect the CERT, LPRIME and STREAM_READY
403d079b7e4SSean Paul * availability. So Wait for timeout and read the msg.
404d079b7e4SSean Paul */
405d079b7e4SSean Paul if (!hdcp2_msg_data->msg_detectable) {
406d079b7e4SSean Paul mdelay(timeout);
407d079b7e4SSean Paul ret = 0;
408d079b7e4SSean Paul } else {
409d079b7e4SSean Paul /*
410d079b7e4SSean Paul * As we want to check the msg availability at timeout, Ignoring
411d079b7e4SSean Paul * the timeout at wait for CP_IRQ.
412d079b7e4SSean Paul */
413d079b7e4SSean Paul intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
414d079b7e4SSean Paul ret = hdcp2_detect_msg_availability(dig_port,
415d079b7e4SSean Paul msg_id, &msg_ready);
416d079b7e4SSean Paul if (!msg_ready)
417d079b7e4SSean Paul ret = -ETIMEDOUT;
418d079b7e4SSean Paul }
419d079b7e4SSean Paul
420d079b7e4SSean Paul if (ret)
421d079b7e4SSean Paul drm_dbg_kms(&i915->drm,
422d079b7e4SSean Paul "msg_id %d, ret %d, timeout(mSec): %d\n",
423d079b7e4SSean Paul hdcp2_msg_data->msg_id, ret, timeout);
424d079b7e4SSean Paul
425d079b7e4SSean Paul return ret;
426d079b7e4SSean Paul }
427d079b7e4SSean Paul
get_hdcp2_dp_msg_data(u8 msg_id)428d079b7e4SSean Paul static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
429d079b7e4SSean Paul {
430d079b7e4SSean Paul int i;
431d079b7e4SSean Paul
432d079b7e4SSean Paul for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++)
433d079b7e4SSean Paul if (hdcp2_dp_msg_data[i].msg_id == msg_id)
434d079b7e4SSean Paul return &hdcp2_dp_msg_data[i];
435d079b7e4SSean Paul
436d079b7e4SSean Paul return NULL;
437d079b7e4SSean Paul }
438d079b7e4SSean Paul
439d079b7e4SSean Paul static
intel_dp_hdcp2_write_msg(struct intel_digital_port * dig_port,void * buf,size_t size)440d079b7e4SSean Paul int intel_dp_hdcp2_write_msg(struct intel_digital_port *dig_port,
441d079b7e4SSean Paul void *buf, size_t size)
442d079b7e4SSean Paul {
443d079b7e4SSean Paul unsigned int offset;
444d079b7e4SSean Paul u8 *byte = buf;
445d079b7e4SSean Paul ssize_t ret, bytes_to_write, len;
446d079b7e4SSean Paul const struct hdcp2_dp_msg_data *hdcp2_msg_data;
447d079b7e4SSean Paul
448d079b7e4SSean Paul hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
449d079b7e4SSean Paul if (!hdcp2_msg_data)
450d079b7e4SSean Paul return -EINVAL;
451d079b7e4SSean Paul
452d079b7e4SSean Paul offset = hdcp2_msg_data->offset;
453d079b7e4SSean Paul
454d079b7e4SSean Paul /* No msg_id in DP HDCP2.2 msgs */
455d079b7e4SSean Paul bytes_to_write = size - 1;
456d079b7e4SSean Paul byte++;
457d079b7e4SSean Paul
458d079b7e4SSean Paul while (bytes_to_write) {
459d079b7e4SSean Paul len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
460d079b7e4SSean Paul DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
461d079b7e4SSean Paul
462d079b7e4SSean Paul ret = drm_dp_dpcd_write(&dig_port->dp.aux,
463d079b7e4SSean Paul offset, (void *)byte, len);
464d079b7e4SSean Paul if (ret < 0)
465d079b7e4SSean Paul return ret;
466d079b7e4SSean Paul
467d079b7e4SSean Paul bytes_to_write -= ret;
468d079b7e4SSean Paul byte += ret;
469d079b7e4SSean Paul offset += ret;
470d079b7e4SSean Paul }
471d079b7e4SSean Paul
472d079b7e4SSean Paul return size;
473d079b7e4SSean Paul }
474d079b7e4SSean Paul
475d079b7e4SSean Paul static
get_receiver_id_list_rx_info(struct intel_digital_port * dig_port,u32 * dev_cnt,u8 * byte)4760f317ebbSJuston Li ssize_t get_receiver_id_list_rx_info(struct intel_digital_port *dig_port, u32 *dev_cnt, u8 *byte)
477d079b7e4SSean Paul {
478d079b7e4SSean Paul ssize_t ret;
4790f317ebbSJuston Li u8 *rx_info = byte;
480d079b7e4SSean Paul
481d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux,
482d079b7e4SSean Paul DP_HDCP_2_2_REG_RXINFO_OFFSET,
483d079b7e4SSean Paul (void *)rx_info, HDCP_2_2_RXINFO_LEN);
484d079b7e4SSean Paul if (ret != HDCP_2_2_RXINFO_LEN)
485d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
486d079b7e4SSean Paul
4870f317ebbSJuston Li *dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
488d079b7e4SSean Paul HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
489d079b7e4SSean Paul
4900f317ebbSJuston Li if (*dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
4910f317ebbSJuston Li *dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
492d079b7e4SSean Paul
493d079b7e4SSean Paul return ret;
494d079b7e4SSean Paul }
495d079b7e4SSean Paul
496d079b7e4SSean Paul static
intel_dp_hdcp2_read_msg(struct intel_digital_port * dig_port,u8 msg_id,void * buf,size_t size)497d079b7e4SSean Paul int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port,
498d079b7e4SSean Paul u8 msg_id, void *buf, size_t size)
499d079b7e4SSean Paul {
500d079b7e4SSean Paul struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
50158cfa329SJuston Li struct intel_dp *dp = &dig_port->dp;
50258cfa329SJuston Li struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
503d079b7e4SSean Paul unsigned int offset;
504d079b7e4SSean Paul u8 *byte = buf;
505d079b7e4SSean Paul ssize_t ret, bytes_to_recv, len;
506d079b7e4SSean Paul const struct hdcp2_dp_msg_data *hdcp2_msg_data;
50728972f82SAnshuman Gupta ktime_t msg_end = ktime_set(0, 0);
508989cf9a9SAnshuman Gupta bool msg_expired;
5090f317ebbSJuston Li u32 dev_cnt;
510d079b7e4SSean Paul
511d079b7e4SSean Paul hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
512d079b7e4SSean Paul if (!hdcp2_msg_data)
513d079b7e4SSean Paul return -EINVAL;
514d079b7e4SSean Paul offset = hdcp2_msg_data->offset;
515d079b7e4SSean Paul
516d079b7e4SSean Paul ret = intel_dp_hdcp2_wait_for_msg(dig_port, hdcp2_msg_data);
517d079b7e4SSean Paul if (ret < 0)
518d079b7e4SSean Paul return ret;
519d079b7e4SSean Paul
52058cfa329SJuston Li hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
52158cfa329SJuston Li
5220f317ebbSJuston Li /* DP adaptation msgs has no msg_id */
5230f317ebbSJuston Li byte++;
5240f317ebbSJuston Li
525d079b7e4SSean Paul if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
5260f317ebbSJuston Li ret = get_receiver_id_list_rx_info(dig_port, &dev_cnt, byte);
527d079b7e4SSean Paul if (ret < 0)
528d079b7e4SSean Paul return ret;
529d079b7e4SSean Paul
5300f317ebbSJuston Li byte += ret;
5310f317ebbSJuston Li size = sizeof(struct hdcp2_rep_send_receiverid_list) -
5320f317ebbSJuston Li HDCP_2_2_RXINFO_LEN - HDCP_2_2_RECEIVER_IDS_MAX_LEN +
5330f317ebbSJuston Li (dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
5340f317ebbSJuston Li offset += HDCP_2_2_RXINFO_LEN;
535d079b7e4SSean Paul }
536d079b7e4SSean Paul
5370f317ebbSJuston Li bytes_to_recv = size - 1;
538d079b7e4SSean Paul
539d079b7e4SSean Paul while (bytes_to_recv) {
540d079b7e4SSean Paul len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
541d079b7e4SSean Paul DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
542d079b7e4SSean Paul
543989cf9a9SAnshuman Gupta /* Entire msg read timeout since initiate of msg read */
544989cf9a9SAnshuman Gupta if (bytes_to_recv == size - 1 && hdcp2_msg_data->msg_read_timeout > 0)
545989cf9a9SAnshuman Gupta msg_end = ktime_add_ms(ktime_get_raw(),
546989cf9a9SAnshuman Gupta hdcp2_msg_data->msg_read_timeout);
547989cf9a9SAnshuman Gupta
548d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux, offset,
549d079b7e4SSean Paul (void *)byte, len);
550d079b7e4SSean Paul if (ret < 0) {
551d079b7e4SSean Paul drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
552d079b7e4SSean Paul msg_id, ret);
553d079b7e4SSean Paul return ret;
554d079b7e4SSean Paul }
555d079b7e4SSean Paul
556d079b7e4SSean Paul bytes_to_recv -= ret;
557d079b7e4SSean Paul byte += ret;
558d079b7e4SSean Paul offset += ret;
559d079b7e4SSean Paul }
560989cf9a9SAnshuman Gupta
561989cf9a9SAnshuman Gupta if (hdcp2_msg_data->msg_read_timeout > 0) {
562989cf9a9SAnshuman Gupta msg_expired = ktime_after(ktime_get_raw(), msg_end);
563989cf9a9SAnshuman Gupta if (msg_expired) {
564989cf9a9SAnshuman Gupta drm_dbg_kms(&i915->drm, "msg_id %d, entire msg read timeout(mSec): %d\n",
565989cf9a9SAnshuman Gupta msg_id, hdcp2_msg_data->msg_read_timeout);
566989cf9a9SAnshuman Gupta return -ETIMEDOUT;
567989cf9a9SAnshuman Gupta }
568989cf9a9SAnshuman Gupta }
569989cf9a9SAnshuman Gupta
570d079b7e4SSean Paul byte = buf;
571d079b7e4SSean Paul *byte = msg_id;
572d079b7e4SSean Paul
573d079b7e4SSean Paul return size;
574d079b7e4SSean Paul }
575d079b7e4SSean Paul
576d079b7e4SSean Paul static
intel_dp_hdcp2_config_stream_type(struct intel_digital_port * dig_port,bool is_repeater,u8 content_type)577d079b7e4SSean Paul int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *dig_port,
578d079b7e4SSean Paul bool is_repeater, u8 content_type)
579d079b7e4SSean Paul {
580d079b7e4SSean Paul int ret;
581d079b7e4SSean Paul struct hdcp2_dp_errata_stream_type stream_type_msg;
582d079b7e4SSean Paul
583d079b7e4SSean Paul if (is_repeater)
584d079b7e4SSean Paul return 0;
585d079b7e4SSean Paul
586d079b7e4SSean Paul /*
587d079b7e4SSean Paul * Errata for DP: As Stream type is used for encryption, Receiver
588d079b7e4SSean Paul * should be communicated with stream type for the decryption of the
589d079b7e4SSean Paul * content.
590d079b7e4SSean Paul * Repeater will be communicated with stream type as a part of it's
591d079b7e4SSean Paul * auth later in time.
592d079b7e4SSean Paul */
593d079b7e4SSean Paul stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
594d079b7e4SSean Paul stream_type_msg.stream_type = content_type;
595d079b7e4SSean Paul
596d079b7e4SSean Paul ret = intel_dp_hdcp2_write_msg(dig_port, &stream_type_msg,
597d079b7e4SSean Paul sizeof(stream_type_msg));
598d079b7e4SSean Paul
599d079b7e4SSean Paul return ret < 0 ? ret : 0;
600d079b7e4SSean Paul
601d079b7e4SSean Paul }
602d079b7e4SSean Paul
603d079b7e4SSean Paul static
intel_dp_hdcp2_check_link(struct intel_digital_port * dig_port,struct intel_connector * connector)6045bd29e32SAnshuman Gupta int intel_dp_hdcp2_check_link(struct intel_digital_port *dig_port,
6055bd29e32SAnshuman Gupta struct intel_connector *connector)
606d079b7e4SSean Paul {
607d079b7e4SSean Paul u8 rx_status;
608d079b7e4SSean Paul int ret;
609d079b7e4SSean Paul
610d079b7e4SSean Paul ret = intel_dp_hdcp2_read_rx_status(dig_port, &rx_status);
611d079b7e4SSean Paul if (ret)
612d079b7e4SSean Paul return ret;
613d079b7e4SSean Paul
614d079b7e4SSean Paul if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
615d079b7e4SSean Paul ret = HDCP_REAUTH_REQUEST;
616d079b7e4SSean Paul else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
617d079b7e4SSean Paul ret = HDCP_LINK_INTEGRITY_FAILURE;
618d079b7e4SSean Paul else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
619d079b7e4SSean Paul ret = HDCP_TOPOLOGY_CHANGE;
620d079b7e4SSean Paul
621d079b7e4SSean Paul return ret;
622d079b7e4SSean Paul }
623d079b7e4SSean Paul
624d079b7e4SSean Paul static
intel_dp_hdcp2_capable(struct intel_digital_port * dig_port,bool * capable)625d079b7e4SSean Paul int intel_dp_hdcp2_capable(struct intel_digital_port *dig_port,
626d079b7e4SSean Paul bool *capable)
627d079b7e4SSean Paul {
628d079b7e4SSean Paul u8 rx_caps[3];
629d079b7e4SSean Paul int ret;
630d079b7e4SSean Paul
631d079b7e4SSean Paul *capable = false;
632d079b7e4SSean Paul ret = drm_dp_dpcd_read(&dig_port->dp.aux,
633d079b7e4SSean Paul DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
634d079b7e4SSean Paul rx_caps, HDCP_2_2_RXCAPS_LEN);
635d079b7e4SSean Paul if (ret != HDCP_2_2_RXCAPS_LEN)
636d079b7e4SSean Paul return ret >= 0 ? -EIO : ret;
637d079b7e4SSean Paul
638d079b7e4SSean Paul if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
639d079b7e4SSean Paul HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
640d079b7e4SSean Paul *capable = true;
641d079b7e4SSean Paul
642d079b7e4SSean Paul return 0;
643d079b7e4SSean Paul }
644d079b7e4SSean Paul
645d079b7e4SSean Paul static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
646d079b7e4SSean Paul .write_an_aksv = intel_dp_hdcp_write_an_aksv,
647d079b7e4SSean Paul .read_bksv = intel_dp_hdcp_read_bksv,
648d079b7e4SSean Paul .read_bstatus = intel_dp_hdcp_read_bstatus,
649d079b7e4SSean Paul .repeater_present = intel_dp_hdcp_repeater_present,
650d079b7e4SSean Paul .read_ri_prime = intel_dp_hdcp_read_ri_prime,
651d079b7e4SSean Paul .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
652d079b7e4SSean Paul .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
653d079b7e4SSean Paul .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
654d079b7e4SSean Paul .toggle_signalling = intel_dp_hdcp_toggle_signalling,
655d079b7e4SSean Paul .check_link = intel_dp_hdcp_check_link,
656d079b7e4SSean Paul .hdcp_capable = intel_dp_hdcp_capable,
657d079b7e4SSean Paul .write_2_2_msg = intel_dp_hdcp2_write_msg,
658d079b7e4SSean Paul .read_2_2_msg = intel_dp_hdcp2_read_msg,
659d079b7e4SSean Paul .config_stream_type = intel_dp_hdcp2_config_stream_type,
660d079b7e4SSean Paul .check_2_2_link = intel_dp_hdcp2_check_link,
661d079b7e4SSean Paul .hdcp_2_2_capable = intel_dp_hdcp2_capable,
662d079b7e4SSean Paul .protocol = HDCP_PROTOCOL_DP,
663d079b7e4SSean Paul };
664d079b7e4SSean Paul
6651fa01409SSean Paul static int
intel_dp_mst_toggle_hdcp_stream_select(struct intel_connector * connector,bool enable)6661a67a168SAnshuman Gupta intel_dp_mst_toggle_hdcp_stream_select(struct intel_connector *connector,
6671fa01409SSean Paul bool enable)
6681fa01409SSean Paul {
6691a67a168SAnshuman Gupta struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
6701a67a168SAnshuman Gupta struct drm_i915_private *i915 = to_i915(connector->base.dev);
6711a67a168SAnshuman Gupta struct intel_hdcp *hdcp = &connector->hdcp;
6721fa01409SSean Paul int ret;
6731fa01409SSean Paul
6741a67a168SAnshuman Gupta ret = intel_ddi_toggle_hdcp_bits(&dig_port->base,
6751a67a168SAnshuman Gupta hdcp->stream_transcoder, enable,
6761a67a168SAnshuman Gupta TRANS_DDI_HDCP_SELECT);
6771fa01409SSean Paul if (ret)
6781a67a168SAnshuman Gupta drm_err(&i915->drm, "%s HDCP stream select failed (%d)\n",
6791fa01409SSean Paul enable ? "Enable" : "Disable", ret);
6801fa01409SSean Paul return ret;
6811fa01409SSean Paul }
6821fa01409SSean Paul
6831a67a168SAnshuman Gupta static int
intel_dp_mst_hdcp_stream_encryption(struct intel_connector * connector,bool enable)6841a67a168SAnshuman Gupta intel_dp_mst_hdcp_stream_encryption(struct intel_connector *connector,
6851a67a168SAnshuman Gupta bool enable)
6861a67a168SAnshuman Gupta {
6871a67a168SAnshuman Gupta struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
6881a67a168SAnshuman Gupta struct drm_i915_private *i915 = to_i915(connector->base.dev);
6891a67a168SAnshuman Gupta struct intel_hdcp *hdcp = &connector->hdcp;
6901a67a168SAnshuman Gupta enum port port = dig_port->base.port;
6911a67a168SAnshuman Gupta enum transcoder cpu_transcoder = hdcp->stream_transcoder;
6921a67a168SAnshuman Gupta u32 stream_enc_status;
6931a67a168SAnshuman Gupta int ret;
6941a67a168SAnshuman Gupta
6951a67a168SAnshuman Gupta ret = intel_dp_mst_toggle_hdcp_stream_select(connector, enable);
6961a67a168SAnshuman Gupta if (ret)
6971a67a168SAnshuman Gupta return ret;
6981a67a168SAnshuman Gupta
6991a67a168SAnshuman Gupta stream_enc_status = transcoder_to_stream_enc_status(cpu_transcoder);
7001a67a168SAnshuman Gupta if (!stream_enc_status)
7011a67a168SAnshuman Gupta return -EINVAL;
7021a67a168SAnshuman Gupta
7031a67a168SAnshuman Gupta /* Wait for encryption confirmation */
7041a67a168SAnshuman Gupta if (intel_de_wait_for_register(i915,
7051a67a168SAnshuman Gupta HDCP_STATUS(i915, cpu_transcoder, port),
7061a67a168SAnshuman Gupta stream_enc_status,
7071a67a168SAnshuman Gupta enable ? stream_enc_status : 0,
7081a67a168SAnshuman Gupta HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
7091a67a168SAnshuman Gupta drm_err(&i915->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
7101a67a168SAnshuman Gupta transcoder_name(cpu_transcoder), enable ? "enabled" : "disabled");
7111a67a168SAnshuman Gupta return -ETIMEDOUT;
7121a67a168SAnshuman Gupta }
7131a67a168SAnshuman Gupta
7141a67a168SAnshuman Gupta return 0;
7151a67a168SAnshuman Gupta }
7161a67a168SAnshuman Gupta
717e9fd05c3SAnshuman Gupta static int
intel_dp_mst_hdcp2_stream_encryption(struct intel_connector * connector,bool enable)718e9fd05c3SAnshuman Gupta intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector,
719e9fd05c3SAnshuman Gupta bool enable)
720e9fd05c3SAnshuman Gupta {
721e9fd05c3SAnshuman Gupta struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
722e9fd05c3SAnshuman Gupta struct drm_i915_private *i915 = to_i915(connector->base.dev);
723e9fd05c3SAnshuman Gupta struct hdcp_port_data *data = &dig_port->hdcp_port_data;
724e9fd05c3SAnshuman Gupta struct intel_hdcp *hdcp = &connector->hdcp;
725e9fd05c3SAnshuman Gupta enum transcoder cpu_transcoder = hdcp->stream_transcoder;
726e9fd05c3SAnshuman Gupta enum pipe pipe = (enum pipe)cpu_transcoder;
727e9fd05c3SAnshuman Gupta enum port port = dig_port->base.port;
728e9fd05c3SAnshuman Gupta int ret;
729e9fd05c3SAnshuman Gupta
730e9fd05c3SAnshuman Gupta drm_WARN_ON(&i915->drm, enable &&
731e9fd05c3SAnshuman Gupta !!(intel_de_read(i915, HDCP2_AUTH_STREAM(i915, cpu_transcoder, port))
732e9fd05c3SAnshuman Gupta & AUTH_STREAM_TYPE) != data->streams[0].stream_type);
733e9fd05c3SAnshuman Gupta
734e9fd05c3SAnshuman Gupta ret = intel_dp_mst_toggle_hdcp_stream_select(connector, enable);
735e9fd05c3SAnshuman Gupta if (ret)
736e9fd05c3SAnshuman Gupta return ret;
737e9fd05c3SAnshuman Gupta
738e9fd05c3SAnshuman Gupta /* Wait for encryption confirmation */
739e9fd05c3SAnshuman Gupta if (intel_de_wait_for_register(i915,
740e9fd05c3SAnshuman Gupta HDCP2_STREAM_STATUS(i915, cpu_transcoder, pipe),
741e9fd05c3SAnshuman Gupta STREAM_ENCRYPTION_STATUS,
742e9fd05c3SAnshuman Gupta enable ? STREAM_ENCRYPTION_STATUS : 0,
743e9fd05c3SAnshuman Gupta HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
744e9fd05c3SAnshuman Gupta drm_err(&i915->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
745e9fd05c3SAnshuman Gupta transcoder_name(cpu_transcoder), enable ? "enabled" : "disabled");
746e9fd05c3SAnshuman Gupta return -ETIMEDOUT;
747e9fd05c3SAnshuman Gupta }
748e9fd05c3SAnshuman Gupta
749e9fd05c3SAnshuman Gupta return 0;
750e9fd05c3SAnshuman Gupta }
751e9fd05c3SAnshuman Gupta
752e9fd05c3SAnshuman Gupta static
intel_dp_mst_hdcp2_check_link(struct intel_digital_port * dig_port,struct intel_connector * connector)753e9fd05c3SAnshuman Gupta int intel_dp_mst_hdcp2_check_link(struct intel_digital_port *dig_port,
754e9fd05c3SAnshuman Gupta struct intel_connector *connector)
755e9fd05c3SAnshuman Gupta {
756e9fd05c3SAnshuman Gupta struct intel_hdcp *hdcp = &connector->hdcp;
757e9fd05c3SAnshuman Gupta int ret;
758e9fd05c3SAnshuman Gupta
759e9fd05c3SAnshuman Gupta /*
760e9fd05c3SAnshuman Gupta * We do need to do the Link Check only for the connector involved with
761e9fd05c3SAnshuman Gupta * HDCP port authentication and encryption.
762e9fd05c3SAnshuman Gupta * We can re-use the hdcp->is_repeater flag to know that the connector
763e9fd05c3SAnshuman Gupta * involved with HDCP port authentication and encryption.
764e9fd05c3SAnshuman Gupta */
765e9fd05c3SAnshuman Gupta if (hdcp->is_repeater) {
766e9fd05c3SAnshuman Gupta ret = intel_dp_hdcp2_check_link(dig_port, connector);
767e9fd05c3SAnshuman Gupta if (ret)
768e9fd05c3SAnshuman Gupta return ret;
769e9fd05c3SAnshuman Gupta }
770e9fd05c3SAnshuman Gupta
771ee0735ffSJuston Li return 0;
772e9fd05c3SAnshuman Gupta }
773e9fd05c3SAnshuman Gupta
7741fa01409SSean Paul static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
7751fa01409SSean Paul .write_an_aksv = intel_dp_hdcp_write_an_aksv,
7761fa01409SSean Paul .read_bksv = intel_dp_hdcp_read_bksv,
7771fa01409SSean Paul .read_bstatus = intel_dp_hdcp_read_bstatus,
7781fa01409SSean Paul .repeater_present = intel_dp_hdcp_repeater_present,
7791fa01409SSean Paul .read_ri_prime = intel_dp_hdcp_read_ri_prime,
7801fa01409SSean Paul .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
7811fa01409SSean Paul .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
7821fa01409SSean Paul .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
7831a67a168SAnshuman Gupta .toggle_signalling = intel_dp_hdcp_toggle_signalling,
7841a67a168SAnshuman Gupta .stream_encryption = intel_dp_mst_hdcp_stream_encryption,
78503b3a759SSean Paul .check_link = intel_dp_hdcp_check_link,
7861fa01409SSean Paul .hdcp_capable = intel_dp_hdcp_capable,
787e9fd05c3SAnshuman Gupta .write_2_2_msg = intel_dp_hdcp2_write_msg,
788e9fd05c3SAnshuman Gupta .read_2_2_msg = intel_dp_hdcp2_read_msg,
789e9fd05c3SAnshuman Gupta .config_stream_type = intel_dp_hdcp2_config_stream_type,
790e9fd05c3SAnshuman Gupta .stream_2_2_encryption = intel_dp_mst_hdcp2_stream_encryption,
791e9fd05c3SAnshuman Gupta .check_2_2_link = intel_dp_mst_hdcp2_check_link,
792e9fd05c3SAnshuman Gupta .hdcp_2_2_capable = intel_dp_hdcp2_capable,
7931fa01409SSean Paul .protocol = HDCP_PROTOCOL_DP,
7941fa01409SSean Paul };
7951fa01409SSean Paul
intel_dp_hdcp_init(struct intel_digital_port * dig_port,struct intel_connector * intel_connector)796b23109c5SJani Nikula int intel_dp_hdcp_init(struct intel_digital_port *dig_port,
797d079b7e4SSean Paul struct intel_connector *intel_connector)
798d079b7e4SSean Paul {
799d079b7e4SSean Paul struct drm_device *dev = intel_connector->base.dev;
800d079b7e4SSean Paul struct drm_i915_private *dev_priv = to_i915(dev);
801d079b7e4SSean Paul struct intel_encoder *intel_encoder = &dig_port->base;
802d079b7e4SSean Paul enum port port = intel_encoder->port;
803d079b7e4SSean Paul struct intel_dp *intel_dp = &dig_port->dp;
804d079b7e4SSean Paul
805d079b7e4SSean Paul if (!is_hdcp_supported(dev_priv, port))
806d079b7e4SSean Paul return 0;
807d079b7e4SSean Paul
8081fa01409SSean Paul if (intel_connector->mst_port)
80929b283a4SAnshuman Gupta return intel_hdcp_init(intel_connector, dig_port,
8101fa01409SSean Paul &intel_dp_mst_hdcp_shim);
8111fa01409SSean Paul else if (!intel_dp_is_edp(intel_dp))
81229b283a4SAnshuman Gupta return intel_hdcp_init(intel_connector, dig_port,
813bf3657daSSean Paul &intel_dp_hdcp_shim);
814d079b7e4SSean Paul
815d079b7e4SSean Paul return 0;
816d079b7e4SSean Paul }
817