cdns-mhdp8546-hdcp.c 13 KB

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