1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Cadence MHDP8546 DP bridge driver.
4  *
5  * Copyright (C) 2020 Cadence Design Systems, Inc.
6  *
7  */
8 
9 #include <linux/io.h>
10 #include <linux/iopoll.h>
11 
12 #include <asm/unaligned.h>
13 
14 #include <drm/display/drm_hdcp_helper.h>
15 
16 #include "cdns-mhdp8546-hdcp.h"
17 
cdns_mhdp_secure_mailbox_read(struct cdns_mhdp_device * mhdp)18 static int cdns_mhdp_secure_mailbox_read(struct cdns_mhdp_device *mhdp)
19 {
20 	int ret, empty;
21 
22 	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
23 
24 	ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_EMPTY,
25 				 empty, !empty, MAILBOX_RETRY_US,
26 				 MAILBOX_TIMEOUT_US);
27 	if (ret < 0)
28 		return ret;
29 
30 	return readl(mhdp->sapb_regs + CDNS_MAILBOX_RX_DATA) & 0xff;
31 }
32 
cdns_mhdp_secure_mailbox_write(struct cdns_mhdp_device * mhdp,u8 val)33 static int cdns_mhdp_secure_mailbox_write(struct cdns_mhdp_device *mhdp,
34 					  u8 val)
35 {
36 	int ret, full;
37 
38 	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
39 
40 	ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_FULL,
41 				 full, !full, MAILBOX_RETRY_US,
42 				 MAILBOX_TIMEOUT_US);
43 	if (ret < 0)
44 		return ret;
45 
46 	writel(val, mhdp->sapb_regs + CDNS_MAILBOX_TX_DATA);
47 
48 	return 0;
49 }
50 
cdns_mhdp_secure_mailbox_recv_header(struct cdns_mhdp_device * mhdp,u8 module_id,u8 opcode,u16 req_size)51 static int cdns_mhdp_secure_mailbox_recv_header(struct cdns_mhdp_device *mhdp,
52 						u8 module_id,
53 						u8 opcode,
54 						u16 req_size)
55 {
56 	u32 mbox_size, i;
57 	u8 header[4];
58 	int ret;
59 
60 	/* read the header of the message */
61 	for (i = 0; i < sizeof(header); i++) {
62 		ret = cdns_mhdp_secure_mailbox_read(mhdp);
63 		if (ret < 0)
64 			return ret;
65 
66 		header[i] = ret;
67 	}
68 
69 	mbox_size = get_unaligned_be16(header + 2);
70 
71 	if (opcode != header[0] || module_id != header[1] ||
72 	    (opcode != HDCP_TRAN_IS_REC_ID_VALID && req_size != mbox_size)) {
73 		for (i = 0; i < mbox_size; i++)
74 			if (cdns_mhdp_secure_mailbox_read(mhdp) < 0)
75 				break;
76 		return -EINVAL;
77 	}
78 
79 	return 0;
80 }
81 
cdns_mhdp_secure_mailbox_recv_data(struct cdns_mhdp_device * mhdp,u8 * buff,u16 buff_size)82 static int cdns_mhdp_secure_mailbox_recv_data(struct cdns_mhdp_device *mhdp,
83 					      u8 *buff, u16 buff_size)
84 {
85 	int ret;
86 	u32 i;
87 
88 	for (i = 0; i < buff_size; i++) {
89 		ret = cdns_mhdp_secure_mailbox_read(mhdp);
90 		if (ret < 0)
91 			return ret;
92 
93 		buff[i] = ret;
94 	}
95 
96 	return 0;
97 }
98 
cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_device * mhdp,u8 module_id,u8 opcode,u16 size,u8 * message)99 static int cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_device *mhdp,
100 					 u8 module_id,
101 					 u8 opcode,
102 					 u16 size,
103 					 u8 *message)
104 {
105 	u8 header[4];
106 	int ret;
107 	u32 i;
108 
109 	header[0] = opcode;
110 	header[1] = module_id;
111 	put_unaligned_be16(size, header + 2);
112 
113 	for (i = 0; i < sizeof(header); i++) {
114 		ret = cdns_mhdp_secure_mailbox_write(mhdp, header[i]);
115 		if (ret)
116 			return ret;
117 	}
118 
119 	for (i = 0; i < size; i++) {
120 		ret = cdns_mhdp_secure_mailbox_write(mhdp, message[i]);
121 		if (ret)
122 			return ret;
123 	}
124 
125 	return 0;
126 }
127 
cdns_mhdp_hdcp_get_status(struct cdns_mhdp_device * mhdp,u16 * hdcp_port_status)128 static int cdns_mhdp_hdcp_get_status(struct cdns_mhdp_device *mhdp,
129 				     u16 *hdcp_port_status)
130 {
131 	u8 hdcp_status[HDCP_STATUS_SIZE];
132 	int ret;
133 
134 	mutex_lock(&mhdp->mbox_mutex);
135 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
136 					    HDCP_TRAN_STATUS_CHANGE, 0, NULL);
137 	if (ret)
138 		goto err_get_hdcp_status;
139 
140 	ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
141 						   HDCP_TRAN_STATUS_CHANGE,
142 						   sizeof(hdcp_status));
143 	if (ret)
144 		goto err_get_hdcp_status;
145 
146 	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_status,
147 						 sizeof(hdcp_status));
148 	if (ret)
149 		goto err_get_hdcp_status;
150 
151 	*hdcp_port_status = ((u16)(hdcp_status[0] << 8) | hdcp_status[1]);
152 
153 err_get_hdcp_status:
154 	mutex_unlock(&mhdp->mbox_mutex);
155 
156 	return ret;
157 }
158 
cdns_mhdp_hdcp_handle_status(struct cdns_mhdp_device * mhdp,u16 status)159 static u8 cdns_mhdp_hdcp_handle_status(struct cdns_mhdp_device *mhdp,
160 				       u16 status)
161 {
162 	u8 err = GET_HDCP_PORT_STS_LAST_ERR(status);
163 
164 	if (err)
165 		dev_dbg(mhdp->dev, "HDCP Error = %d", err);
166 
167 	return err;
168 }
169 
cdns_mhdp_hdcp_rx_id_valid_response(struct cdns_mhdp_device * mhdp,u8 valid)170 static int cdns_mhdp_hdcp_rx_id_valid_response(struct cdns_mhdp_device *mhdp,
171 					       u8 valid)
172 {
173 	int ret;
174 
175 	mutex_lock(&mhdp->mbox_mutex);
176 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
177 					    HDCP_TRAN_RESPOND_RECEIVER_ID_VALID,
178 					    1, &valid);
179 	mutex_unlock(&mhdp->mbox_mutex);
180 
181 	return ret;
182 }
183 
cdns_mhdp_hdcp_rx_id_valid(struct cdns_mhdp_device * mhdp,u8 * recv_num,u8 * hdcp_rx_id)184 static int cdns_mhdp_hdcp_rx_id_valid(struct cdns_mhdp_device *mhdp,
185 				      u8 *recv_num, u8 *hdcp_rx_id)
186 {
187 	u8 rec_id_hdr[2];
188 	u8 status;
189 	int ret;
190 
191 	mutex_lock(&mhdp->mbox_mutex);
192 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
193 					    HDCP_TRAN_IS_REC_ID_VALID, 0, NULL);
194 	if (ret)
195 		goto err_rx_id_valid;
196 
197 	ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
198 						   HDCP_TRAN_IS_REC_ID_VALID,
199 						   sizeof(status));
200 	if (ret)
201 		goto err_rx_id_valid;
202 
203 	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, rec_id_hdr, 2);
204 	if (ret)
205 		goto err_rx_id_valid;
206 
207 	*recv_num = rec_id_hdr[0];
208 
209 	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_rx_id, 5 * *recv_num);
210 
211 err_rx_id_valid:
212 	mutex_unlock(&mhdp->mbox_mutex);
213 
214 	return ret;
215 }
216 
cdns_mhdp_hdcp_km_stored_resp(struct cdns_mhdp_device * mhdp,u32 size,u8 * km)217 static int cdns_mhdp_hdcp_km_stored_resp(struct cdns_mhdp_device *mhdp,
218 					 u32 size, u8 *km)
219 {
220 	int ret;
221 
222 	mutex_lock(&mhdp->mbox_mutex);
223 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
224 					    HDCP2X_TX_RESPOND_KM, size, km);
225 	mutex_unlock(&mhdp->mbox_mutex);
226 
227 	return ret;
228 }
229 
cdns_mhdp_hdcp_tx_is_km_stored(struct cdns_mhdp_device * mhdp,u8 * resp,u32 size)230 static int cdns_mhdp_hdcp_tx_is_km_stored(struct cdns_mhdp_device *mhdp,
231 					  u8 *resp, u32 size)
232 {
233 	int ret;
234 
235 	mutex_lock(&mhdp->mbox_mutex);
236 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
237 					    HDCP2X_TX_IS_KM_STORED, 0, NULL);
238 	if (ret)
239 		goto err_is_km_stored;
240 
241 	ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
242 						   HDCP2X_TX_IS_KM_STORED,
243 						   size);
244 	if (ret)
245 		goto err_is_km_stored;
246 
247 	ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, resp, size);
248 err_is_km_stored:
249 	mutex_unlock(&mhdp->mbox_mutex);
250 
251 	return ret;
252 }
253 
cdns_mhdp_hdcp_tx_config(struct cdns_mhdp_device * mhdp,u8 hdcp_cfg)254 static int cdns_mhdp_hdcp_tx_config(struct cdns_mhdp_device *mhdp,
255 				    u8 hdcp_cfg)
256 {
257 	int ret;
258 
259 	mutex_lock(&mhdp->mbox_mutex);
260 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
261 					    HDCP_TRAN_CONFIGURATION, 1, &hdcp_cfg);
262 	mutex_unlock(&mhdp->mbox_mutex);
263 
264 	return ret;
265 }
266 
cdns_mhdp_hdcp_set_config(struct cdns_mhdp_device * mhdp,u8 hdcp_config,bool enable)267 static int cdns_mhdp_hdcp_set_config(struct cdns_mhdp_device *mhdp,
268 				     u8 hdcp_config, bool enable)
269 {
270 	u16 hdcp_port_status;
271 	u32 ret_event;
272 	u8 hdcp_cfg;
273 	int ret;
274 
275 	hdcp_cfg = hdcp_config | (enable ? 0x04 : 0) |
276 		   (HDCP_CONTENT_TYPE_0 << 3);
277 	cdns_mhdp_hdcp_tx_config(mhdp, hdcp_cfg);
278 	ret_event = cdns_mhdp_wait_for_sw_event(mhdp, CDNS_HDCP_TX_STATUS);
279 	if (!ret_event)
280 		return -1;
281 
282 	ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
283 	if (ret || cdns_mhdp_hdcp_handle_status(mhdp, hdcp_port_status))
284 		return -1;
285 
286 	return 0;
287 }
288 
cdns_mhdp_hdcp_auth_check(struct cdns_mhdp_device * mhdp)289 static int cdns_mhdp_hdcp_auth_check(struct cdns_mhdp_device *mhdp)
290 {
291 	u16 hdcp_port_status;
292 	u32 ret_event;
293 	int ret;
294 
295 	ret_event = cdns_mhdp_wait_for_sw_event(mhdp, CDNS_HDCP_TX_STATUS);
296 	if (!ret_event)
297 		return -1;
298 
299 	ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
300 	if (ret || cdns_mhdp_hdcp_handle_status(mhdp, hdcp_port_status))
301 		return -1;
302 
303 	if (hdcp_port_status & 1) {
304 		dev_dbg(mhdp->dev, "Authentication completed successfully!\n");
305 		return 0;
306 	}
307 
308 	dev_dbg(mhdp->dev, "Authentication failed\n");
309 
310 	return -1;
311 }
312 
cdns_mhdp_hdcp_check_receviers(struct cdns_mhdp_device * mhdp)313 static int cdns_mhdp_hdcp_check_receviers(struct cdns_mhdp_device *mhdp)
314 {
315 	u8 hdcp_rec_id[HDCP_MAX_RECEIVERS][HDCP_RECEIVER_ID_SIZE_BYTES];
316 	u8 hdcp_num_rec;
317 	u32 ret_event;
318 
319 	ret_event = cdns_mhdp_wait_for_sw_event(mhdp,
320 						CDNS_HDCP_TX_IS_RCVR_ID_VALID);
321 	if (!ret_event)
322 		return -1;
323 
324 	hdcp_num_rec = 0;
325 	memset(&hdcp_rec_id, 0, sizeof(hdcp_rec_id));
326 	cdns_mhdp_hdcp_rx_id_valid(mhdp, &hdcp_num_rec, (u8 *)hdcp_rec_id);
327 	cdns_mhdp_hdcp_rx_id_valid_response(mhdp, 1);
328 
329 	return 0;
330 }
331 
cdns_mhdp_hdcp_auth_22(struct cdns_mhdp_device * mhdp)332 static int cdns_mhdp_hdcp_auth_22(struct cdns_mhdp_device *mhdp)
333 {
334 	u8 resp[HDCP_STATUS_SIZE];
335 	u16 hdcp_port_status;
336 	u32 ret_event;
337 	int ret;
338 
339 	dev_dbg(mhdp->dev, "HDCP: Start 2.2 Authentication\n");
340 	ret_event = cdns_mhdp_wait_for_sw_event(mhdp,
341 						CDNS_HDCP2_TX_IS_KM_STORED);
342 	if (!ret_event)
343 		return -1;
344 
345 	if (ret_event & CDNS_HDCP_TX_STATUS) {
346 		mhdp->sw_events &= ~CDNS_HDCP_TX_STATUS;
347 		ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
348 		if (ret || cdns_mhdp_hdcp_handle_status(mhdp, hdcp_port_status))
349 			return -1;
350 	}
351 
352 	cdns_mhdp_hdcp_tx_is_km_stored(mhdp, resp, sizeof(resp));
353 	cdns_mhdp_hdcp_km_stored_resp(mhdp, 0, NULL);
354 
355 	if (cdns_mhdp_hdcp_check_receviers(mhdp))
356 		return -1;
357 
358 	return 0;
359 }
360 
cdns_mhdp_hdcp_auth_14(struct cdns_mhdp_device * mhdp)361 static inline int cdns_mhdp_hdcp_auth_14(struct cdns_mhdp_device *mhdp)
362 {
363 	dev_dbg(mhdp->dev, "HDCP: Starting 1.4 Authentication\n");
364 	return cdns_mhdp_hdcp_check_receviers(mhdp);
365 }
366 
cdns_mhdp_hdcp_auth(struct cdns_mhdp_device * mhdp,u8 hdcp_config)367 static int cdns_mhdp_hdcp_auth(struct cdns_mhdp_device *mhdp,
368 			       u8 hdcp_config)
369 {
370 	int ret;
371 
372 	ret = cdns_mhdp_hdcp_set_config(mhdp, hdcp_config, true);
373 	if (ret)
374 		goto auth_failed;
375 
376 	if (hdcp_config == HDCP_TX_1)
377 		ret = cdns_mhdp_hdcp_auth_14(mhdp);
378 	else
379 		ret = cdns_mhdp_hdcp_auth_22(mhdp);
380 
381 	if (ret)
382 		goto auth_failed;
383 
384 	ret = cdns_mhdp_hdcp_auth_check(mhdp);
385 	if (ret)
386 		ret = cdns_mhdp_hdcp_auth_check(mhdp);
387 
388 auth_failed:
389 	return ret;
390 }
391 
_cdns_mhdp_hdcp_disable(struct cdns_mhdp_device * mhdp)392 static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp)
393 {
394 	int ret;
395 
396 	dev_dbg(mhdp->dev, "[%s:%d] HDCP is being disabled...\n",
397 		mhdp->connector.name, mhdp->connector.base.id);
398 
399 	ret = cdns_mhdp_hdcp_set_config(mhdp, 0, false);
400 
401 	return ret;
402 }
403 
_cdns_mhdp_hdcp_enable(struct cdns_mhdp_device * mhdp,u8 content_type)404 static int _cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type)
405 {
406 	int ret = -EINVAL;
407 	int tries = 3;
408 	u32 i;
409 
410 	for (i = 0; i < tries; i++) {
411 		if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0 ||
412 		    content_type == DRM_MODE_HDCP_CONTENT_TYPE1) {
413 			ret = cdns_mhdp_hdcp_auth(mhdp, HDCP_TX_2);
414 			if (!ret)
415 				return 0;
416 			_cdns_mhdp_hdcp_disable(mhdp);
417 		}
418 
419 		if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0) {
420 			ret = cdns_mhdp_hdcp_auth(mhdp, HDCP_TX_1);
421 			if (!ret)
422 				return 0;
423 			_cdns_mhdp_hdcp_disable(mhdp);
424 		}
425 	}
426 
427 	dev_err(mhdp->dev, "HDCP authentication failed (%d tries/%d)\n",
428 		tries, ret);
429 
430 	return ret;
431 }
432 
cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device * mhdp)433 static int cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device *mhdp)
434 {
435 	u16 hdcp_port_status;
436 	int ret = 0;
437 
438 	mutex_lock(&mhdp->hdcp.mutex);
439 	if (mhdp->hdcp.value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
440 		goto out;
441 
442 	ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
443 	if (!ret && hdcp_port_status & HDCP_PORT_STS_AUTH)
444 		goto out;
445 
446 	dev_err(mhdp->dev,
447 		"[%s:%d] HDCP link failed, retrying authentication\n",
448 		mhdp->connector.name, mhdp->connector.base.id);
449 
450 	ret = _cdns_mhdp_hdcp_disable(mhdp);
451 	if (ret) {
452 		mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
453 		schedule_work(&mhdp->hdcp.prop_work);
454 		goto out;
455 	}
456 
457 	ret = _cdns_mhdp_hdcp_enable(mhdp, mhdp->hdcp.hdcp_content_type);
458 	if (ret) {
459 		mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
460 		schedule_work(&mhdp->hdcp.prop_work);
461 	}
462 out:
463 	mutex_unlock(&mhdp->hdcp.mutex);
464 	return ret;
465 }
466 
cdns_mhdp_hdcp_check_work(struct work_struct * work)467 static void cdns_mhdp_hdcp_check_work(struct work_struct *work)
468 {
469 	struct delayed_work *d_work = to_delayed_work(work);
470 	struct cdns_mhdp_hdcp *hdcp = container_of(d_work,
471 						   struct cdns_mhdp_hdcp,
472 						   check_work);
473 	struct cdns_mhdp_device *mhdp = container_of(hdcp,
474 						     struct cdns_mhdp_device,
475 						     hdcp);
476 
477 	if (!cdns_mhdp_hdcp_check_link(mhdp))
478 		schedule_delayed_work(&hdcp->check_work,
479 				      DRM_HDCP_CHECK_PERIOD_MS);
480 }
481 
cdns_mhdp_hdcp_prop_work(struct work_struct * work)482 static void cdns_mhdp_hdcp_prop_work(struct work_struct *work)
483 {
484 	struct cdns_mhdp_hdcp *hdcp = container_of(work,
485 						   struct cdns_mhdp_hdcp,
486 						   prop_work);
487 	struct cdns_mhdp_device *mhdp = container_of(hdcp,
488 						     struct cdns_mhdp_device,
489 						     hdcp);
490 	struct drm_device *dev = mhdp->connector.dev;
491 	struct drm_connector_state *state;
492 
493 	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
494 	mutex_lock(&mhdp->hdcp.mutex);
495 	if (mhdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
496 		state = mhdp->connector.state;
497 		state->content_protection = mhdp->hdcp.value;
498 	}
499 	mutex_unlock(&mhdp->hdcp.mutex);
500 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
501 }
502 
cdns_mhdp_hdcp_set_lc(struct cdns_mhdp_device * mhdp,u8 * val)503 int cdns_mhdp_hdcp_set_lc(struct cdns_mhdp_device *mhdp, u8 *val)
504 {
505 	int ret;
506 
507 	mutex_lock(&mhdp->mbox_mutex);
508 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_GENERAL,
509 					    HDCP_GENERAL_SET_LC_128,
510 					    16, val);
511 	mutex_unlock(&mhdp->mbox_mutex);
512 
513 	return ret;
514 }
515 
516 int
cdns_mhdp_hdcp_set_public_key_param(struct cdns_mhdp_device * mhdp,struct cdns_hdcp_tx_public_key_param * val)517 cdns_mhdp_hdcp_set_public_key_param(struct cdns_mhdp_device *mhdp,
518 				    struct cdns_hdcp_tx_public_key_param *val)
519 {
520 	int ret;
521 
522 	mutex_lock(&mhdp->mbox_mutex);
523 	ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
524 					    HDCP2X_TX_SET_PUBLIC_KEY_PARAMS,
525 					    sizeof(*val), (u8 *)val);
526 	mutex_unlock(&mhdp->mbox_mutex);
527 
528 	return ret;
529 }
530 
cdns_mhdp_hdcp_enable(struct cdns_mhdp_device * mhdp,u8 content_type)531 int cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type)
532 {
533 	int ret;
534 
535 	mutex_lock(&mhdp->hdcp.mutex);
536 	ret = _cdns_mhdp_hdcp_enable(mhdp, content_type);
537 	if (ret)
538 		goto out;
539 
540 	mhdp->hdcp.hdcp_content_type = content_type;
541 	mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
542 	schedule_work(&mhdp->hdcp.prop_work);
543 	schedule_delayed_work(&mhdp->hdcp.check_work,
544 			      DRM_HDCP_CHECK_PERIOD_MS);
545 out:
546 	mutex_unlock(&mhdp->hdcp.mutex);
547 	return ret;
548 }
549 
cdns_mhdp_hdcp_disable(struct cdns_mhdp_device * mhdp)550 int cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp)
551 {
552 	int ret = 0;
553 
554 	mutex_lock(&mhdp->hdcp.mutex);
555 	if (mhdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
556 		mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
557 		schedule_work(&mhdp->hdcp.prop_work);
558 		ret = _cdns_mhdp_hdcp_disable(mhdp);
559 	}
560 	mutex_unlock(&mhdp->hdcp.mutex);
561 	cancel_delayed_work_sync(&mhdp->hdcp.check_work);
562 
563 	return ret;
564 }
565 
cdns_mhdp_hdcp_init(struct cdns_mhdp_device * mhdp)566 void cdns_mhdp_hdcp_init(struct cdns_mhdp_device *mhdp)
567 {
568 	INIT_DELAYED_WORK(&mhdp->hdcp.check_work, cdns_mhdp_hdcp_check_work);
569 	INIT_WORK(&mhdp->hdcp.prop_work, cdns_mhdp_hdcp_prop_work);
570 	mutex_init(&mhdp->hdcp.mutex);
571 }
572