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