0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/io.h>
0010 #include <linux/iopoll.h>
0011
0012 #include <asm/unaligned.h>
0013
0014 #include <drm/display/drm_hdcp_helper.h>
0015
0016 #include "cdns-mhdp8546-hdcp.h"
0017
0018 static int cdns_mhdp_secure_mailbox_read(struct cdns_mhdp_device *mhdp)
0019 {
0020 int ret, empty;
0021
0022 WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
0023
0024 ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_EMPTY,
0025 empty, !empty, MAILBOX_RETRY_US,
0026 MAILBOX_TIMEOUT_US);
0027 if (ret < 0)
0028 return ret;
0029
0030 return readl(mhdp->sapb_regs + CDNS_MAILBOX_RX_DATA) & 0xff;
0031 }
0032
0033 static int cdns_mhdp_secure_mailbox_write(struct cdns_mhdp_device *mhdp,
0034 u8 val)
0035 {
0036 int ret, full;
0037
0038 WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
0039
0040 ret = readx_poll_timeout(readl, mhdp->sapb_regs + CDNS_MAILBOX_FULL,
0041 full, !full, MAILBOX_RETRY_US,
0042 MAILBOX_TIMEOUT_US);
0043 if (ret < 0)
0044 return ret;
0045
0046 writel(val, mhdp->sapb_regs + CDNS_MAILBOX_TX_DATA);
0047
0048 return 0;
0049 }
0050
0051 static int cdns_mhdp_secure_mailbox_recv_header(struct cdns_mhdp_device *mhdp,
0052 u8 module_id,
0053 u8 opcode,
0054 u16 req_size)
0055 {
0056 u32 mbox_size, i;
0057 u8 header[4];
0058 int ret;
0059
0060
0061 for (i = 0; i < sizeof(header); i++) {
0062 ret = cdns_mhdp_secure_mailbox_read(mhdp);
0063 if (ret < 0)
0064 return ret;
0065
0066 header[i] = ret;
0067 }
0068
0069 mbox_size = get_unaligned_be16(header + 2);
0070
0071 if (opcode != header[0] || module_id != header[1] ||
0072 (opcode != HDCP_TRAN_IS_REC_ID_VALID && req_size != mbox_size)) {
0073 for (i = 0; i < mbox_size; i++)
0074 if (cdns_mhdp_secure_mailbox_read(mhdp) < 0)
0075 break;
0076 return -EINVAL;
0077 }
0078
0079 return 0;
0080 }
0081
0082 static int cdns_mhdp_secure_mailbox_recv_data(struct cdns_mhdp_device *mhdp,
0083 u8 *buff, u16 buff_size)
0084 {
0085 int ret;
0086 u32 i;
0087
0088 for (i = 0; i < buff_size; i++) {
0089 ret = cdns_mhdp_secure_mailbox_read(mhdp);
0090 if (ret < 0)
0091 return ret;
0092
0093 buff[i] = ret;
0094 }
0095
0096 return 0;
0097 }
0098
0099 static int cdns_mhdp_secure_mailbox_send(struct cdns_mhdp_device *mhdp,
0100 u8 module_id,
0101 u8 opcode,
0102 u16 size,
0103 u8 *message)
0104 {
0105 u8 header[4];
0106 int ret;
0107 u32 i;
0108
0109 header[0] = opcode;
0110 header[1] = module_id;
0111 put_unaligned_be16(size, header + 2);
0112
0113 for (i = 0; i < sizeof(header); i++) {
0114 ret = cdns_mhdp_secure_mailbox_write(mhdp, header[i]);
0115 if (ret)
0116 return ret;
0117 }
0118
0119 for (i = 0; i < size; i++) {
0120 ret = cdns_mhdp_secure_mailbox_write(mhdp, message[i]);
0121 if (ret)
0122 return ret;
0123 }
0124
0125 return 0;
0126 }
0127
0128 static int cdns_mhdp_hdcp_get_status(struct cdns_mhdp_device *mhdp,
0129 u16 *hdcp_port_status)
0130 {
0131 u8 hdcp_status[HDCP_STATUS_SIZE];
0132 int ret;
0133
0134 mutex_lock(&mhdp->mbox_mutex);
0135 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
0136 HDCP_TRAN_STATUS_CHANGE, 0, NULL);
0137 if (ret)
0138 goto err_get_hdcp_status;
0139
0140 ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
0141 HDCP_TRAN_STATUS_CHANGE,
0142 sizeof(hdcp_status));
0143 if (ret)
0144 goto err_get_hdcp_status;
0145
0146 ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_status,
0147 sizeof(hdcp_status));
0148 if (ret)
0149 goto err_get_hdcp_status;
0150
0151 *hdcp_port_status = ((u16)(hdcp_status[0] << 8) | hdcp_status[1]);
0152
0153 err_get_hdcp_status:
0154 mutex_unlock(&mhdp->mbox_mutex);
0155
0156 return ret;
0157 }
0158
0159 static u8 cdns_mhdp_hdcp_handle_status(struct cdns_mhdp_device *mhdp,
0160 u16 status)
0161 {
0162 u8 err = GET_HDCP_PORT_STS_LAST_ERR(status);
0163
0164 if (err)
0165 dev_dbg(mhdp->dev, "HDCP Error = %d", err);
0166
0167 return err;
0168 }
0169
0170 static int cdns_mhdp_hdcp_rx_id_valid_response(struct cdns_mhdp_device *mhdp,
0171 u8 valid)
0172 {
0173 int ret;
0174
0175 mutex_lock(&mhdp->mbox_mutex);
0176 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
0177 HDCP_TRAN_RESPOND_RECEIVER_ID_VALID,
0178 1, &valid);
0179 mutex_unlock(&mhdp->mbox_mutex);
0180
0181 return ret;
0182 }
0183
0184 static int cdns_mhdp_hdcp_rx_id_valid(struct cdns_mhdp_device *mhdp,
0185 u8 *recv_num, u8 *hdcp_rx_id)
0186 {
0187 u8 rec_id_hdr[2];
0188 u8 status;
0189 int ret;
0190
0191 mutex_lock(&mhdp->mbox_mutex);
0192 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
0193 HDCP_TRAN_IS_REC_ID_VALID, 0, NULL);
0194 if (ret)
0195 goto err_rx_id_valid;
0196
0197 ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
0198 HDCP_TRAN_IS_REC_ID_VALID,
0199 sizeof(status));
0200 if (ret)
0201 goto err_rx_id_valid;
0202
0203 ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, rec_id_hdr, 2);
0204 if (ret)
0205 goto err_rx_id_valid;
0206
0207 *recv_num = rec_id_hdr[0];
0208
0209 ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, hdcp_rx_id, 5 * *recv_num);
0210
0211 err_rx_id_valid:
0212 mutex_unlock(&mhdp->mbox_mutex);
0213
0214 return ret;
0215 }
0216
0217 static int cdns_mhdp_hdcp_km_stored_resp(struct cdns_mhdp_device *mhdp,
0218 u32 size, u8 *km)
0219 {
0220 int ret;
0221
0222 mutex_lock(&mhdp->mbox_mutex);
0223 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
0224 HDCP2X_TX_RESPOND_KM, size, km);
0225 mutex_unlock(&mhdp->mbox_mutex);
0226
0227 return ret;
0228 }
0229
0230 static int cdns_mhdp_hdcp_tx_is_km_stored(struct cdns_mhdp_device *mhdp,
0231 u8 *resp, u32 size)
0232 {
0233 int ret;
0234
0235 mutex_lock(&mhdp->mbox_mutex);
0236 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
0237 HDCP2X_TX_IS_KM_STORED, 0, NULL);
0238 if (ret)
0239 goto err_is_km_stored;
0240
0241 ret = cdns_mhdp_secure_mailbox_recv_header(mhdp, MB_MODULE_ID_HDCP_TX,
0242 HDCP2X_TX_IS_KM_STORED,
0243 size);
0244 if (ret)
0245 goto err_is_km_stored;
0246
0247 ret = cdns_mhdp_secure_mailbox_recv_data(mhdp, resp, size);
0248 err_is_km_stored:
0249 mutex_unlock(&mhdp->mbox_mutex);
0250
0251 return ret;
0252 }
0253
0254 static int cdns_mhdp_hdcp_tx_config(struct cdns_mhdp_device *mhdp,
0255 u8 hdcp_cfg)
0256 {
0257 int ret;
0258
0259 mutex_lock(&mhdp->mbox_mutex);
0260 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
0261 HDCP_TRAN_CONFIGURATION, 1, &hdcp_cfg);
0262 mutex_unlock(&mhdp->mbox_mutex);
0263
0264 return ret;
0265 }
0266
0267 static int cdns_mhdp_hdcp_set_config(struct cdns_mhdp_device *mhdp,
0268 u8 hdcp_config, bool enable)
0269 {
0270 u16 hdcp_port_status;
0271 u32 ret_event;
0272 u8 hdcp_cfg;
0273 int ret;
0274
0275 hdcp_cfg = hdcp_config | (enable ? 0x04 : 0) |
0276 (HDCP_CONTENT_TYPE_0 << 3);
0277 cdns_mhdp_hdcp_tx_config(mhdp, hdcp_cfg);
0278 ret_event = cdns_mhdp_wait_for_sw_event(mhdp, CDNS_HDCP_TX_STATUS);
0279 if (!ret_event)
0280 return -1;
0281
0282 ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
0283 if (ret || cdns_mhdp_hdcp_handle_status(mhdp, hdcp_port_status))
0284 return -1;
0285
0286 return 0;
0287 }
0288
0289 static int cdns_mhdp_hdcp_auth_check(struct cdns_mhdp_device *mhdp)
0290 {
0291 u16 hdcp_port_status;
0292 u32 ret_event;
0293 int ret;
0294
0295 ret_event = cdns_mhdp_wait_for_sw_event(mhdp, CDNS_HDCP_TX_STATUS);
0296 if (!ret_event)
0297 return -1;
0298
0299 ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
0300 if (ret || cdns_mhdp_hdcp_handle_status(mhdp, hdcp_port_status))
0301 return -1;
0302
0303 if (hdcp_port_status & 1) {
0304 dev_dbg(mhdp->dev, "Authentication completed successfully!\n");
0305 return 0;
0306 }
0307
0308 dev_dbg(mhdp->dev, "Authentication failed\n");
0309
0310 return -1;
0311 }
0312
0313 static int cdns_mhdp_hdcp_check_receviers(struct cdns_mhdp_device *mhdp)
0314 {
0315 u8 hdcp_rec_id[HDCP_MAX_RECEIVERS][HDCP_RECEIVER_ID_SIZE_BYTES];
0316 u8 hdcp_num_rec;
0317 u32 ret_event;
0318
0319 ret_event = cdns_mhdp_wait_for_sw_event(mhdp,
0320 CDNS_HDCP_TX_IS_RCVR_ID_VALID);
0321 if (!ret_event)
0322 return -1;
0323
0324 hdcp_num_rec = 0;
0325 memset(&hdcp_rec_id, 0, sizeof(hdcp_rec_id));
0326 cdns_mhdp_hdcp_rx_id_valid(mhdp, &hdcp_num_rec, (u8 *)hdcp_rec_id);
0327 cdns_mhdp_hdcp_rx_id_valid_response(mhdp, 1);
0328
0329 return 0;
0330 }
0331
0332 static int cdns_mhdp_hdcp_auth_22(struct cdns_mhdp_device *mhdp)
0333 {
0334 u8 resp[HDCP_STATUS_SIZE];
0335 u16 hdcp_port_status;
0336 u32 ret_event;
0337 int ret;
0338
0339 dev_dbg(mhdp->dev, "HDCP: Start 2.2 Authentication\n");
0340 ret_event = cdns_mhdp_wait_for_sw_event(mhdp,
0341 CDNS_HDCP2_TX_IS_KM_STORED);
0342 if (!ret_event)
0343 return -1;
0344
0345 if (ret_event & CDNS_HDCP_TX_STATUS) {
0346 mhdp->sw_events &= ~CDNS_HDCP_TX_STATUS;
0347 ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
0348 if (ret || cdns_mhdp_hdcp_handle_status(mhdp, hdcp_port_status))
0349 return -1;
0350 }
0351
0352 cdns_mhdp_hdcp_tx_is_km_stored(mhdp, resp, sizeof(resp));
0353 cdns_mhdp_hdcp_km_stored_resp(mhdp, 0, NULL);
0354
0355 if (cdns_mhdp_hdcp_check_receviers(mhdp))
0356 return -1;
0357
0358 return 0;
0359 }
0360
0361 static inline int cdns_mhdp_hdcp_auth_14(struct cdns_mhdp_device *mhdp)
0362 {
0363 dev_dbg(mhdp->dev, "HDCP: Starting 1.4 Authentication\n");
0364 return cdns_mhdp_hdcp_check_receviers(mhdp);
0365 }
0366
0367 static int cdns_mhdp_hdcp_auth(struct cdns_mhdp_device *mhdp,
0368 u8 hdcp_config)
0369 {
0370 int ret;
0371
0372 ret = cdns_mhdp_hdcp_set_config(mhdp, hdcp_config, true);
0373 if (ret)
0374 goto auth_failed;
0375
0376 if (hdcp_config == HDCP_TX_1)
0377 ret = cdns_mhdp_hdcp_auth_14(mhdp);
0378 else
0379 ret = cdns_mhdp_hdcp_auth_22(mhdp);
0380
0381 if (ret)
0382 goto auth_failed;
0383
0384 ret = cdns_mhdp_hdcp_auth_check(mhdp);
0385 if (ret)
0386 ret = cdns_mhdp_hdcp_auth_check(mhdp);
0387
0388 auth_failed:
0389 return ret;
0390 }
0391
0392 static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp)
0393 {
0394 int ret;
0395
0396 dev_dbg(mhdp->dev, "[%s:%d] HDCP is being disabled...\n",
0397 mhdp->connector.name, mhdp->connector.base.id);
0398
0399 ret = cdns_mhdp_hdcp_set_config(mhdp, 0, false);
0400
0401 return ret;
0402 }
0403
0404 static int _cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type)
0405 {
0406 int ret, tries = 3;
0407 u32 i;
0408
0409 for (i = 0; i < tries; i++) {
0410 if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0 ||
0411 content_type == DRM_MODE_HDCP_CONTENT_TYPE1) {
0412 ret = cdns_mhdp_hdcp_auth(mhdp, HDCP_TX_2);
0413 if (!ret)
0414 return 0;
0415 _cdns_mhdp_hdcp_disable(mhdp);
0416 }
0417
0418 if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0) {
0419 ret = cdns_mhdp_hdcp_auth(mhdp, HDCP_TX_1);
0420 if (!ret)
0421 return 0;
0422 _cdns_mhdp_hdcp_disable(mhdp);
0423 }
0424 }
0425
0426 dev_err(mhdp->dev, "HDCP authentication failed (%d tries/%d)\n",
0427 tries, ret);
0428
0429 return ret;
0430 }
0431
0432 static int cdns_mhdp_hdcp_check_link(struct cdns_mhdp_device *mhdp)
0433 {
0434 u16 hdcp_port_status;
0435 int ret = 0;
0436
0437 mutex_lock(&mhdp->hdcp.mutex);
0438 if (mhdp->hdcp.value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
0439 goto out;
0440
0441 ret = cdns_mhdp_hdcp_get_status(mhdp, &hdcp_port_status);
0442 if (!ret && hdcp_port_status & HDCP_PORT_STS_AUTH)
0443 goto out;
0444
0445 dev_err(mhdp->dev,
0446 "[%s:%d] HDCP link failed, retrying authentication\n",
0447 mhdp->connector.name, mhdp->connector.base.id);
0448
0449 ret = _cdns_mhdp_hdcp_disable(mhdp);
0450 if (ret) {
0451 mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
0452 schedule_work(&mhdp->hdcp.prop_work);
0453 goto out;
0454 }
0455
0456 ret = _cdns_mhdp_hdcp_enable(mhdp, mhdp->hdcp.hdcp_content_type);
0457 if (ret) {
0458 mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
0459 schedule_work(&mhdp->hdcp.prop_work);
0460 }
0461 out:
0462 mutex_unlock(&mhdp->hdcp.mutex);
0463 return ret;
0464 }
0465
0466 static void cdns_mhdp_hdcp_check_work(struct work_struct *work)
0467 {
0468 struct delayed_work *d_work = to_delayed_work(work);
0469 struct cdns_mhdp_hdcp *hdcp = container_of(d_work,
0470 struct cdns_mhdp_hdcp,
0471 check_work);
0472 struct cdns_mhdp_device *mhdp = container_of(hdcp,
0473 struct cdns_mhdp_device,
0474 hdcp);
0475
0476 if (!cdns_mhdp_hdcp_check_link(mhdp))
0477 schedule_delayed_work(&hdcp->check_work,
0478 DRM_HDCP_CHECK_PERIOD_MS);
0479 }
0480
0481 static void cdns_mhdp_hdcp_prop_work(struct work_struct *work)
0482 {
0483 struct cdns_mhdp_hdcp *hdcp = container_of(work,
0484 struct cdns_mhdp_hdcp,
0485 prop_work);
0486 struct cdns_mhdp_device *mhdp = container_of(hdcp,
0487 struct cdns_mhdp_device,
0488 hdcp);
0489 struct drm_device *dev = mhdp->connector.dev;
0490 struct drm_connector_state *state;
0491
0492 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
0493 mutex_lock(&mhdp->hdcp.mutex);
0494 if (mhdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
0495 state = mhdp->connector.state;
0496 state->content_protection = mhdp->hdcp.value;
0497 }
0498 mutex_unlock(&mhdp->hdcp.mutex);
0499 drm_modeset_unlock(&dev->mode_config.connection_mutex);
0500 }
0501
0502 int cdns_mhdp_hdcp_set_lc(struct cdns_mhdp_device *mhdp, u8 *val)
0503 {
0504 int ret;
0505
0506 mutex_lock(&mhdp->mbox_mutex);
0507 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_GENERAL,
0508 HDCP_GENERAL_SET_LC_128,
0509 16, val);
0510 mutex_unlock(&mhdp->mbox_mutex);
0511
0512 return ret;
0513 }
0514
0515 int
0516 cdns_mhdp_hdcp_set_public_key_param(struct cdns_mhdp_device *mhdp,
0517 struct cdns_hdcp_tx_public_key_param *val)
0518 {
0519 int ret;
0520
0521 mutex_lock(&mhdp->mbox_mutex);
0522 ret = cdns_mhdp_secure_mailbox_send(mhdp, MB_MODULE_ID_HDCP_TX,
0523 HDCP2X_TX_SET_PUBLIC_KEY_PARAMS,
0524 sizeof(*val), (u8 *)val);
0525 mutex_unlock(&mhdp->mbox_mutex);
0526
0527 return ret;
0528 }
0529
0530 int cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type)
0531 {
0532 int ret;
0533
0534 mutex_lock(&mhdp->hdcp.mutex);
0535 ret = _cdns_mhdp_hdcp_enable(mhdp, content_type);
0536 if (ret)
0537 goto out;
0538
0539 mhdp->hdcp.hdcp_content_type = content_type;
0540 mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
0541 schedule_work(&mhdp->hdcp.prop_work);
0542 schedule_delayed_work(&mhdp->hdcp.check_work,
0543 DRM_HDCP_CHECK_PERIOD_MS);
0544 out:
0545 mutex_unlock(&mhdp->hdcp.mutex);
0546 return ret;
0547 }
0548
0549 int cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp)
0550 {
0551 int ret = 0;
0552
0553 mutex_lock(&mhdp->hdcp.mutex);
0554 if (mhdp->hdcp.value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
0555 mhdp->hdcp.value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
0556 schedule_work(&mhdp->hdcp.prop_work);
0557 ret = _cdns_mhdp_hdcp_disable(mhdp);
0558 }
0559 mutex_unlock(&mhdp->hdcp.mutex);
0560 cancel_delayed_work_sync(&mhdp->hdcp.check_work);
0561
0562 return ret;
0563 }
0564
0565 void cdns_mhdp_hdcp_init(struct cdns_mhdp_device *mhdp)
0566 {
0567 INIT_DELAYED_WORK(&mhdp->hdcp.check_work, cdns_mhdp_hdcp_check_work);
0568 INIT_WORK(&mhdp->hdcp.prop_work, cdns_mhdp_hdcp_prop_work);
0569 mutex_init(&mhdp->hdcp.mutex);
0570 }