1 // SPDX-License-Identifier: GPL-2.0
3 * Cadence MHDP8546 DP bridge driver.
5 * Copyright (C) 2020 Cadence Design Systems, Inc.
10 #include <linux/iopoll.h>
12 #include <asm/unaligned.h>
14 #include <drm/drm_hdcp.h>
16 #include "cdns-mhdp8546-hdcp.h"
18 static int cdns_mhdp_secure_mailbox_read(struct cdns_mhdp_device *mhdp)
22 WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
24 ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_EMPTY,
25 empty, !empty, MAILBOX_RETRY_US,
30 return readl(mhdp->sapb_regs + CDNS_MAILBOX_RX_DATA) & 0xff;
33 static int cdns_mhdp_secure_mailbox_write(struct cdns_mhdp_device *mhdp,
38 WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
40 ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_FULL,
41 full, !full, MAILBOX_RETRY_US,
46 writel(val, mhdp->sapb_regs + CDNS_MAILBOX_TX_DATA);
51 static int cdns_mhdp_secure_mailbox_recv_header(struct cdns_mhdp_device *mhdp,
60 /* read the header of the message */
61 for (i = 0; i < sizeof(header); i++) {
62 ret = cdns_mhdp_secure_mailbox_read(mhdp);
69 mbox_size = get_unaligned_be16(header + 2);
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)
82 static int cdns_mhdp_secure_mailbox_recv_data(struct cdns_mhdp_device *mhdp,
83 u8 *buff, u16 buff_size)
88 for (i = 0; i < buff_size; i++) {
89 ret = cdns_mhdp_secure_mailbox_read(mhdp);
99 static int cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_device *mhdp,
110 header[1] = module_id;
111 put_unaligned_be16(size, header + 2);
113 for (i = 0; i < sizeof(header); i++) {
114 ret = cdns_mhdp_secure_mailbox_write(mhdp, header[i]);
119 for (i = 0; i < size; i++) {
120 ret = cdns_mhdp_secure_mailbox_write(mhdp, message[i]);
128 static int cdns_mhdp_hdcp_get_status(struct cdns_mhdp_device *mhdp,
129 u16 *hdcp_port_status)
131 u8 hdcp_status[HDCP_STATUS_SIZE];
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);
138 goto err_get_hdcp_status;
140 ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
141 HDCP_TRAN_STATUS_CHANGE,
142 sizeof(hdcp_status));
144 goto err_get_hdcp_status;
146 ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_status,
147 sizeof(hdcp_status));
149 goto err_get_hdcp_status;
151 *hdcp_port_status = ((u16)(hdcp_status[0] << 8) | hdcp_status[1]);
154 mutex_unlock(&mhdp->mbox_mutex);
159 static u8 cdns_mhdp_hdcp_handle_status(struct cdns_mhdp_device *mhdp,
162 u8 err = GET_HDCP_PORT_STS_LAST_ERR(status);
165 dev_dbg(mhdp->dev, "HDCP Error = %d", err);
170 static int cdns_mhdp_hdcp_rx_id_valid_response(struct cdns_mhdp_device *mhdp,
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,
179 mutex_unlock(&mhdp->mbox_mutex);
184 static int cdns_mhdp_hdcp_rx_id_valid(struct cdns_mhdp_device *mhdp,
185 u8 *recv_num, u8 *hdcp_rx_id)
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);
195 goto err_rx_id_valid;
197 ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
198 HDCP_TRAN_IS_REC_ID_VALID,
201 goto err_rx_id_valid;
203 ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, rec_id_hdr, 2);
205 goto err_rx_id_valid;
207 *recv_num = rec_id_hdr[0];
209 ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_rx_id, 5 * *recv_num);
212 mutex_unlock(&mhdp->mbox_mutex);
217 static int cdns_mhdp_hdcp_km_stored_resp(struct cdns_mhdp_device *mhdp,
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);
230 static int cdns_mhdp_hdcp_tx_is_km_stored(struct cdns_mhdp_device *mhdp,
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);
239 goto err_is_km_stored;
241 ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
242 HDCP2X_TX_IS_KM_STORED,
245 goto err_is_km_stored;
247 ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, resp, size);
249 mutex_unlock(&mhdp->mbox_mutex);
254 static int cdns_mhdp_hdcp_tx_config(struct cdns_mhdp_device *mhdp,
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);
267 static int cdns_mhdp_hdcp_set_config(struct cdns_mhdp_device *mhdp,
268 u8 hdcp_config, bool enable)
270 u16 hdcp_port_status;
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);
282 ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
283 if (ret || cdns_mhdp_hdcp_handle_status(mhdp, hdcp_port_status))
289 static int cdns_mhdp_hdcp_auth_check(struct cdns_mhdp_device *mhdp)
291 u16 hdcp_port_status;
295 ret_event = cdns_mhdp_wait_for_sw_event(mhdp, CDNS_HDCP_TX_STATUS);
299 ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
300 if (ret || cdns_mhdp_hdcp_handle_status(mhdp, hdcp_port_status))
303 if (hdcp_port_status & 1) {
304 dev_dbg(mhdp->dev, "Authentication completed successfully!\n");
308 dev_dbg(mhdp->dev, "Authentication failed\n");
313 static int cdns_mhdp_hdcp_check_receviers(struct cdns_mhdp_device *mhdp)
315 u8 hdcp_rec_id[HDCP_MAX_RECEIVERS][HDCP_RECEIVER_ID_SIZE_BYTES];
319 ret_event = cdns_mhdp_wait_for_sw_event(mhdp,
320 CDNS_HDCP_TX_IS_RCVR_ID_VALID);
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);
332 static int cdns_mhdp_hdcp_auth_22(struct cdns_mhdp_device *mhdp)
334 u8 resp[HDCP_STATUS_SIZE];
335 u16 hdcp_port_status;
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);
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))
352 cdns_mhdp_hdcp_tx_is_km_stored(mhdp, resp, sizeof(resp));
353 cdns_mhdp_hdcp_km_stored_resp(mhdp, 0, NULL);
355 if (cdns_mhdp_hdcp_check_receviers(mhdp))
361 static inline int cdns_mhdp_hdcp_auth_14(struct cdns_mhdp_device *mhdp)
363 dev_dbg(mhdp->dev, "HDCP: Starting 1.4 Authentication\n");
364 return cdns_mhdp_hdcp_check_receviers(mhdp);
367 static int cdns_mhdp_hdcp_auth(struct cdns_mhdp_device *mhdp,
372 ret = cdns_mhdp_hdcp_set_config(mhdp, hdcp_config, true);
376 if (hdcp_config == HDCP_TX_1)
377 ret = cdns_mhdp_hdcp_auth_14(mhdp);
379 ret = cdns_mhdp_hdcp_auth_22(mhdp);
384 ret = cdns_mhdp_hdcp_auth_check(mhdp);
386 ret = cdns_mhdp_hdcp_auth_check(mhdp);
392 static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp)
396 dev_dbg(mhdp->dev, "[%s:%d] HDCP is being disabled...\n",
397 mhdp->connector.name, mhdp->connector.base.id);
399 ret = cdns_mhdp_hdcp_set_config(mhdp, 0, false);
404 static int _cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type)
409 for (i = 0; i < tries; i++) {
410 if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0 ||
411 content_type == DRM_MODE_HDCP_CONTENT_TYPE1) {
412 ret = cdns_mhdp_hdcp_auth(mhdp, HDCP_TX_2);
415 _cdns_mhdp_hdcp_disable(mhdp);
418 if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0) {
419 ret = cdns_mhdp_hdcp_auth(mhdp, HDCP_TX_1);
422 _cdns_mhdp_hdcp_disable(mhdp);
426 dev_err(mhdp->dev, "HDCP authentication failed (%d tries/%d)\n",
432 static int cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device *mhdp)
434 u16 hdcp_port_status;
437 mutex_lock(&mhdp->hdcp.mutex);
438 if (mhdp->hdcp.value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
441 ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
442 if (!ret && hdcp_port_status & HDCP_PORT_STS_AUTH)
446 "[%s:%d] HDCP link failed, retrying authentication\n",
447 mhdp->connector.name, mhdp->connector.base.id);
449 ret = _cdns_mhdp_hdcp_disable(mhdp);
451 mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
452 schedule_work(&mhdp->hdcp.prop_work);
456 ret = _cdns_mhdp_hdcp_enable(mhdp, mhdp->hdcp.hdcp_content_type);
458 mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
459 schedule_work(&mhdp->hdcp.prop_work);
462 mutex_unlock(&mhdp->hdcp.mutex);
466 static void cdns_mhdp_hdcp_check_work(struct work_struct *work)
468 struct delayed_work *d_work = to_delayed_work(work);
469 struct cdns_mhdp_hdcp *hdcp = container_of(d_work,
470 struct cdns_mhdp_hdcp,
472 struct cdns_mhdp_device *mhdp = container_of(hdcp,
473 struct cdns_mhdp_device,
476 if (!cdns_mhdp_hdcp_check_link(mhdp))
477 schedule_delayed_work(&hdcp->check_work,
478 DRM_HDCP_CHECK_PERIOD_MS);
481 static void cdns_mhdp_hdcp_prop_work(struct work_struct *work)
483 struct cdns_mhdp_hdcp *hdcp = container_of(work,
484 struct cdns_mhdp_hdcp,
486 struct cdns_mhdp_device *mhdp = container_of(hdcp,
487 struct cdns_mhdp_device,
489 struct drm_device *dev = mhdp->connector.dev;
490 struct drm_connector_state *state;
492 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
493 mutex_lock(&mhdp->hdcp.mutex);
494 if (mhdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
495 state = mhdp->connector.state;
496 state->content_protection = mhdp->hdcp.value;
498 mutex_unlock(&mhdp->hdcp.mutex);
499 drm_modeset_unlock(&dev->mode_config.connection_mutex);
502 int cdns_mhdp_hdcp_set_lc(struct cdns_mhdp_device *mhdp, u8 *val)
506 mutex_lock(&mhdp->mbox_mutex);
507 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_GENERAL,
508 HDCP_GENERAL_SET_LC_128,
510 mutex_unlock(&mhdp->mbox_mutex);
516 cdns_mhdp_hdcp_set_public_key_param(struct cdns_mhdp_device *mhdp,
517 struct cdns_hdcp_tx_public_key_param *val)
521 mutex_lock(&mhdp->mbox_mutex);
522 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
523 HDCP2X_TX_SET_PUBLIC_KEY_PARAMS,
524 sizeof(*val), (u8 *)val);
525 mutex_unlock(&mhdp->mbox_mutex);
530 int cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type)
534 mutex_lock(&mhdp->hdcp.mutex);
535 ret = _cdns_mhdp_hdcp_enable(mhdp, content_type);
539 mhdp->hdcp.hdcp_content_type = content_type;
540 mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
541 schedule_work(&mhdp->hdcp.prop_work);
542 schedule_delayed_work(&mhdp->hdcp.check_work,
543 DRM_HDCP_CHECK_PERIOD_MS);
545 mutex_unlock(&mhdp->hdcp.mutex);
549 int cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp)
553 mutex_lock(&mhdp->hdcp.mutex);
554 if (mhdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
555 mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
556 schedule_work(&mhdp->hdcp.prop_work);
557 ret = _cdns_mhdp_hdcp_disable(mhdp);
559 mutex_unlock(&mhdp->hdcp.mutex);
560 cancel_delayed_work_sync(&mhdp->hdcp.check_work);
565 void cdns_mhdp_hdcp_init(struct cdns_mhdp_device *mhdp)
567 INIT_DELAYED_WORK(&mhdp->hdcp.check_work, cdns_mhdp_hdcp_check_work);
568 INIT_WORK(&mhdp->hdcp.prop_work, cdns_mhdp_hdcp_prop_work);
569 mutex_init(&mhdp->hdcp.mutex);