cdn-dp-reg.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. /*
  2. * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
  3. * Author: Chris Zhong <zyw@rock-chips.com>
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/clk.h>
  15. #include <linux/device.h>
  16. #include <linux/delay.h>
  17. #include <linux/io.h>
  18. #include <linux/iopoll.h>
  19. #include <linux/reset.h>
  20. #include "cdn-dp-core.h"
  21. #include "cdn-dp-reg.h"
  22. #define CDN_DP_SPDIF_CLK 200000000
  23. #define FW_ALIVE_TIMEOUT_US 1000000
  24. #define MAILBOX_RETRY_US 1000
  25. #define MAILBOX_TIMEOUT_US 5000000
  26. #define LINK_TRAINING_RETRY_MS 20
  27. #define LINK_TRAINING_TIMEOUT_MS 500
  28. void cdn_dp_set_fw_clk(struct cdn_dp_device *dp, unsigned long clk)
  29. {
  30. writel(clk / 1000000, dp->regs + SW_CLK_H);
  31. }
  32. void cdn_dp_clock_reset(struct cdn_dp_device *dp)
  33. {
  34. u32 val;
  35. val = DPTX_FRMR_DATA_CLK_RSTN_EN |
  36. DPTX_FRMR_DATA_CLK_EN |
  37. DPTX_PHY_DATA_RSTN_EN |
  38. DPTX_PHY_DATA_CLK_EN |
  39. DPTX_PHY_CHAR_RSTN_EN |
  40. DPTX_PHY_CHAR_CLK_EN |
  41. SOURCE_AUX_SYS_CLK_RSTN_EN |
  42. SOURCE_AUX_SYS_CLK_EN |
  43. DPTX_SYS_CLK_RSTN_EN |
  44. DPTX_SYS_CLK_EN |
  45. CFG_DPTX_VIF_CLK_RSTN_EN |
  46. CFG_DPTX_VIF_CLK_EN;
  47. writel(val, dp->regs + SOURCE_DPTX_CAR);
  48. val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN;
  49. writel(val, dp->regs + SOURCE_PHY_CAR);
  50. val = SOURCE_PKT_SYS_RSTN_EN |
  51. SOURCE_PKT_SYS_CLK_EN |
  52. SOURCE_PKT_DATA_RSTN_EN |
  53. SOURCE_PKT_DATA_CLK_EN;
  54. writel(val, dp->regs + SOURCE_PKT_CAR);
  55. val = SPDIF_CDR_CLK_RSTN_EN |
  56. SPDIF_CDR_CLK_EN |
  57. SOURCE_AIF_SYS_RSTN_EN |
  58. SOURCE_AIF_SYS_CLK_EN |
  59. SOURCE_AIF_CLK_RSTN_EN |
  60. SOURCE_AIF_CLK_EN;
  61. writel(val, dp->regs + SOURCE_AIF_CAR);
  62. val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN |
  63. SOURCE_CIPHER_SYS_CLK_EN |
  64. SOURCE_CIPHER_CHAR_CLK_RSTN_EN |
  65. SOURCE_CIPHER_CHAR_CLK_EN;
  66. writel(val, dp->regs + SOURCE_CIPHER_CAR);
  67. val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN |
  68. SOURCE_CRYPTO_SYS_CLK_EN;
  69. writel(val, dp->regs + SOURCE_CRYPTO_CAR);
  70. /* enable Mailbox and PIF interrupt */
  71. writel(0, dp->regs + APB_INT_MASK);
  72. }
  73. static int cdn_dp_mailbox_read(struct cdn_dp_device *dp)
  74. {
  75. int val, ret;
  76. ret = readx_poll_timeout(readl, dp->regs + MAILBOX_EMPTY_ADDR,
  77. val, !val, MAILBOX_RETRY_US,
  78. MAILBOX_TIMEOUT_US);
  79. if (ret < 0)
  80. return ret;
  81. return readl(dp->regs + MAILBOX0_RD_DATA) & 0xff;
  82. }
  83. static int cdp_dp_mailbox_write(struct cdn_dp_device *dp, u8 val)
  84. {
  85. int ret, full;
  86. ret = readx_poll_timeout(readl, dp->regs + MAILBOX_FULL_ADDR,
  87. full, !full, MAILBOX_RETRY_US,
  88. MAILBOX_TIMEOUT_US);
  89. if (ret < 0)
  90. return ret;
  91. writel(val, dp->regs + MAILBOX0_WR_DATA);
  92. return 0;
  93. }
  94. static int cdn_dp_mailbox_validate_receive(struct cdn_dp_device *dp,
  95. u8 module_id, u8 opcode,
  96. u8 req_size)
  97. {
  98. u32 mbox_size, i;
  99. u8 header[4];
  100. int ret;
  101. /* read the header of the message */
  102. for (i = 0; i < 4; i++) {
  103. ret = cdn_dp_mailbox_read(dp);
  104. if (ret < 0)
  105. return ret;
  106. header[i] = ret;
  107. }
  108. mbox_size = (header[2] << 8) | header[3];
  109. if (opcode != header[0] || module_id != header[1] ||
  110. req_size != mbox_size) {
  111. /*
  112. * If the message in mailbox is not what we want, we need to
  113. * clear the mailbox by reading its contents.
  114. */
  115. for (i = 0; i < mbox_size; i++)
  116. if (cdn_dp_mailbox_read(dp) < 0)
  117. break;
  118. return -EINVAL;
  119. }
  120. return 0;
  121. }
  122. static int cdn_dp_mailbox_read_receive(struct cdn_dp_device *dp,
  123. u8 *buff, u8 buff_size)
  124. {
  125. u32 i;
  126. int ret;
  127. for (i = 0; i < buff_size; i++) {
  128. ret = cdn_dp_mailbox_read(dp);
  129. if (ret < 0)
  130. return ret;
  131. buff[i] = ret;
  132. }
  133. return 0;
  134. }
  135. static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, u8 module_id,
  136. u8 opcode, u16 size, u8 *message)
  137. {
  138. u8 header[4];
  139. int ret, i;
  140. header[0] = opcode;
  141. header[1] = module_id;
  142. header[2] = (size >> 8) & 0xff;
  143. header[3] = size & 0xff;
  144. for (i = 0; i < 4; i++) {
  145. ret = cdp_dp_mailbox_write(dp, header[i]);
  146. if (ret)
  147. return ret;
  148. }
  149. for (i = 0; i < size; i++) {
  150. ret = cdp_dp_mailbox_write(dp, message[i]);
  151. if (ret)
  152. return ret;
  153. }
  154. return 0;
  155. }
  156. static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
  157. {
  158. u8 msg[6];
  159. msg[0] = (addr >> 8) & 0xff;
  160. msg[1] = addr & 0xff;
  161. msg[2] = (val >> 24) & 0xff;
  162. msg[3] = (val >> 16) & 0xff;
  163. msg[4] = (val >> 8) & 0xff;
  164. msg[5] = val & 0xff;
  165. return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_REGISTER,
  166. sizeof(msg), msg);
  167. }
  168. static int cdn_dp_reg_write_bit(struct cdn_dp_device *dp, u16 addr,
  169. u8 start_bit, u8 bits_no, u32 val)
  170. {
  171. u8 field[8];
  172. field[0] = (addr >> 8) & 0xff;
  173. field[1] = addr & 0xff;
  174. field[2] = start_bit;
  175. field[3] = bits_no;
  176. field[4] = (val >> 24) & 0xff;
  177. field[5] = (val >> 16) & 0xff;
  178. field[6] = (val >> 8) & 0xff;
  179. field[7] = val & 0xff;
  180. return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_FIELD,
  181. sizeof(field), field);
  182. }
  183. int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
  184. {
  185. u8 msg[5], reg[5];
  186. int ret;
  187. msg[0] = (len >> 8) & 0xff;
  188. msg[1] = len & 0xff;
  189. msg[2] = (addr >> 16) & 0xff;
  190. msg[3] = (addr >> 8) & 0xff;
  191. msg[4] = addr & 0xff;
  192. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_DPCD,
  193. sizeof(msg), msg);
  194. if (ret)
  195. goto err_dpcd_read;
  196. ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
  197. DPTX_READ_DPCD,
  198. sizeof(reg) + len);
  199. if (ret)
  200. goto err_dpcd_read;
  201. ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
  202. if (ret)
  203. goto err_dpcd_read;
  204. ret = cdn_dp_mailbox_read_receive(dp, data, len);
  205. err_dpcd_read:
  206. return ret;
  207. }
  208. int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
  209. {
  210. u8 msg[6], reg[5];
  211. int ret;
  212. msg[0] = 0;
  213. msg[1] = 1;
  214. msg[2] = (addr >> 16) & 0xff;
  215. msg[3] = (addr >> 8) & 0xff;
  216. msg[4] = addr & 0xff;
  217. msg[5] = value;
  218. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_DPCD,
  219. sizeof(msg), msg);
  220. if (ret)
  221. goto err_dpcd_write;
  222. ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
  223. DPTX_WRITE_DPCD, sizeof(reg));
  224. if (ret)
  225. goto err_dpcd_write;
  226. ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
  227. if (ret)
  228. goto err_dpcd_write;
  229. if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))
  230. ret = -EINVAL;
  231. err_dpcd_write:
  232. if (ret)
  233. DRM_DEV_ERROR(dp->dev, "dpcd write failed: %d\n", ret);
  234. return ret;
  235. }
  236. int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem,
  237. u32 i_size, const u32 *d_mem, u32 d_size)
  238. {
  239. u32 reg;
  240. int i, ret;
  241. /* reset ucpu before load firmware*/
  242. writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET,
  243. dp->regs + APB_CTRL);
  244. for (i = 0; i < i_size; i += 4)
  245. writel(*i_mem++, dp->regs + ADDR_IMEM + i);
  246. for (i = 0; i < d_size; i += 4)
  247. writel(*d_mem++, dp->regs + ADDR_DMEM + i);
  248. /* un-reset ucpu */
  249. writel(0, dp->regs + APB_CTRL);
  250. /* check the keep alive register to make sure fw working */
  251. ret = readx_poll_timeout(readl, dp->regs + KEEP_ALIVE,
  252. reg, reg, 2000, FW_ALIVE_TIMEOUT_US);
  253. if (ret < 0) {
  254. DRM_DEV_ERROR(dp->dev, "failed to loaded the FW reg = %x\n",
  255. reg);
  256. return -EINVAL;
  257. }
  258. reg = readl(dp->regs + VER_L) & 0xff;
  259. dp->fw_version = reg;
  260. reg = readl(dp->regs + VER_H) & 0xff;
  261. dp->fw_version |= reg << 8;
  262. reg = readl(dp->regs + VER_LIB_L_ADDR) & 0xff;
  263. dp->fw_version |= reg << 16;
  264. reg = readl(dp->regs + VER_LIB_H_ADDR) & 0xff;
  265. dp->fw_version |= reg << 24;
  266. DRM_DEV_DEBUG(dp->dev, "firmware version: %x\n", dp->fw_version);
  267. return 0;
  268. }
  269. int cdn_dp_set_firmware_active(struct cdn_dp_device *dp, bool enable)
  270. {
  271. u8 msg[5];
  272. int ret, i;
  273. msg[0] = GENERAL_MAIN_CONTROL;
  274. msg[1] = MB_MODULE_ID_GENERAL;
  275. msg[2] = 0;
  276. msg[3] = 1;
  277. msg[4] = enable ? FW_ACTIVE : FW_STANDBY;
  278. for (i = 0; i < sizeof(msg); i++) {
  279. ret = cdp_dp_mailbox_write(dp, msg[i]);
  280. if (ret)
  281. goto err_set_firmware_active;
  282. }
  283. /* read the firmware state */
  284. for (i = 0; i < sizeof(msg); i++) {
  285. ret = cdn_dp_mailbox_read(dp);
  286. if (ret < 0)
  287. goto err_set_firmware_active;
  288. msg[i] = ret;
  289. }
  290. ret = 0;
  291. err_set_firmware_active:
  292. if (ret < 0)
  293. DRM_DEV_ERROR(dp->dev, "set firmware active failed\n");
  294. return ret;
  295. }
  296. int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip)
  297. {
  298. u8 msg[8];
  299. int ret;
  300. msg[0] = CDN_DP_MAX_LINK_RATE;
  301. msg[1] = lanes | SCRAMBLER_EN;
  302. msg[2] = VOLTAGE_LEVEL_2;
  303. msg[3] = PRE_EMPHASIS_LEVEL_3;
  304. msg[4] = PTS1 | PTS2 | PTS3 | PTS4;
  305. msg[5] = FAST_LT_NOT_SUPPORT;
  306. msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL;
  307. msg[7] = ENHANCED;
  308. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
  309. DPTX_SET_HOST_CAPABILITIES,
  310. sizeof(msg), msg);
  311. if (ret)
  312. goto err_set_host_cap;
  313. ret = cdn_dp_reg_write(dp, DP_AUX_SWAP_INVERSION_CONTROL,
  314. AUX_HOST_INVERT);
  315. err_set_host_cap:
  316. if (ret)
  317. DRM_DEV_ERROR(dp->dev, "set host cap failed: %d\n", ret);
  318. return ret;
  319. }
  320. int cdn_dp_event_config(struct cdn_dp_device *dp)
  321. {
  322. u8 msg[5];
  323. int ret;
  324. memset(msg, 0, sizeof(msg));
  325. msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING;
  326. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_ENABLE_EVENT,
  327. sizeof(msg), msg);
  328. if (ret)
  329. DRM_DEV_ERROR(dp->dev, "set event config failed: %d\n", ret);
  330. return ret;
  331. }
  332. u32 cdn_dp_get_event(struct cdn_dp_device *dp)
  333. {
  334. return readl(dp->regs + SW_EVENTS0);
  335. }
  336. int cdn_dp_get_hpd_status(struct cdn_dp_device *dp)
  337. {
  338. u8 status;
  339. int ret;
  340. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_HPD_STATE,
  341. 0, NULL);
  342. if (ret)
  343. goto err_get_hpd;
  344. ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
  345. DPTX_HPD_STATE, sizeof(status));
  346. if (ret)
  347. goto err_get_hpd;
  348. ret = cdn_dp_mailbox_read_receive(dp, &status, sizeof(status));
  349. if (ret)
  350. goto err_get_hpd;
  351. return status;
  352. err_get_hpd:
  353. DRM_DEV_ERROR(dp->dev, "get hpd status failed: %d\n", ret);
  354. return ret;
  355. }
  356. int cdn_dp_get_edid_block(void *data, u8 *edid,
  357. unsigned int block, size_t length)
  358. {
  359. struct cdn_dp_device *dp = data;
  360. u8 msg[2], reg[2], i;
  361. int ret;
  362. for (i = 0; i < 4; i++) {
  363. msg[0] = block / 2;
  364. msg[1] = block % 2;
  365. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_GET_EDID,
  366. sizeof(msg), msg);
  367. if (ret)
  368. continue;
  369. ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
  370. DPTX_GET_EDID,
  371. sizeof(reg) + length);
  372. if (ret)
  373. continue;
  374. ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg));
  375. if (ret)
  376. continue;
  377. ret = cdn_dp_mailbox_read_receive(dp, edid, length);
  378. if (ret)
  379. continue;
  380. if (reg[0] == length && reg[1] == block / 2)
  381. break;
  382. }
  383. if (ret)
  384. DRM_DEV_ERROR(dp->dev, "get block[%d] edid failed: %d\n", block,
  385. ret);
  386. return ret;
  387. }
  388. static int cdn_dp_training_start(struct cdn_dp_device *dp)
  389. {
  390. unsigned long timeout;
  391. u8 msg, event[2];
  392. int ret;
  393. msg = LINK_TRAINING_RUN;
  394. /* start training */
  395. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_TRAINING_CONTROL,
  396. sizeof(msg), &msg);
  397. if (ret)
  398. goto err_training_start;
  399. timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS);
  400. while (time_before(jiffies, timeout)) {
  401. msleep(LINK_TRAINING_RETRY_MS);
  402. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
  403. DPTX_READ_EVENT, 0, NULL);
  404. if (ret)
  405. goto err_training_start;
  406. ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
  407. DPTX_READ_EVENT,
  408. sizeof(event));
  409. if (ret)
  410. goto err_training_start;
  411. ret = cdn_dp_mailbox_read_receive(dp, event, sizeof(event));
  412. if (ret)
  413. goto err_training_start;
  414. if (event[1] & EQ_PHASE_FINISHED)
  415. return 0;
  416. }
  417. ret = -ETIMEDOUT;
  418. err_training_start:
  419. DRM_DEV_ERROR(dp->dev, "training failed: %d\n", ret);
  420. return ret;
  421. }
  422. static int cdn_dp_get_training_status(struct cdn_dp_device *dp)
  423. {
  424. u8 status[10];
  425. int ret;
  426. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_LINK_STAT,
  427. 0, NULL);
  428. if (ret)
  429. goto err_get_training_status;
  430. ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
  431. DPTX_READ_LINK_STAT,
  432. sizeof(status));
  433. if (ret)
  434. goto err_get_training_status;
  435. ret = cdn_dp_mailbox_read_receive(dp, status, sizeof(status));
  436. if (ret)
  437. goto err_get_training_status;
  438. dp->link.rate = status[0];
  439. dp->link.num_lanes = status[1];
  440. err_get_training_status:
  441. if (ret)
  442. DRM_DEV_ERROR(dp->dev, "get training status failed: %d\n", ret);
  443. return ret;
  444. }
  445. int cdn_dp_train_link(struct cdn_dp_device *dp)
  446. {
  447. int ret;
  448. ret = cdn_dp_training_start(dp);
  449. if (ret) {
  450. DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
  451. return ret;
  452. }
  453. ret = cdn_dp_get_training_status(dp);
  454. if (ret) {
  455. DRM_DEV_ERROR(dp->dev, "Failed to get training stat %d\n", ret);
  456. return ret;
  457. }
  458. DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
  459. dp->link.num_lanes);
  460. return ret;
  461. }
  462. int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
  463. {
  464. u8 msg;
  465. int ret;
  466. msg = !!active;
  467. ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO,
  468. sizeof(msg), &msg);
  469. if (ret)
  470. DRM_DEV_ERROR(dp->dev, "set video status failed: %d\n", ret);
  471. return ret;
  472. }
  473. static int cdn_dp_get_msa_misc(struct video_info *video,
  474. struct drm_display_mode *mode)
  475. {
  476. u32 msa_misc;
  477. u8 val[2] = {0};
  478. switch (video->color_fmt) {
  479. case PXL_RGB:
  480. case Y_ONLY:
  481. val[0] = 0;
  482. break;
  483. /* set YUV default color space conversion to BT601 */
  484. case YCBCR_4_4_4:
  485. val[0] = 6 + BT_601 * 8;
  486. break;
  487. case YCBCR_4_2_2:
  488. val[0] = 5 + BT_601 * 8;
  489. break;
  490. case YCBCR_4_2_0:
  491. val[0] = 5;
  492. break;
  493. };
  494. switch (video->color_depth) {
  495. case 6:
  496. val[1] = 0;
  497. break;
  498. case 8:
  499. val[1] = 1;
  500. break;
  501. case 10:
  502. val[1] = 2;
  503. break;
  504. case 12:
  505. val[1] = 3;
  506. break;
  507. case 16:
  508. val[1] = 4;
  509. break;
  510. };
  511. msa_misc = 2 * val[0] + 32 * val[1] +
  512. ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0);
  513. return msa_misc;
  514. }
  515. int cdn_dp_config_video(struct cdn_dp_device *dp)
  516. {
  517. struct video_info *video = &dp->video_info;
  518. struct drm_display_mode *mode = &dp->mode;
  519. u64 symbol;
  520. u32 val, link_rate, rem;
  521. u8 bit_per_pix, tu_size_reg = TU_SIZE;
  522. int ret;
  523. bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ?
  524. (video->color_depth * 2) : (video->color_depth * 3);
  525. link_rate = drm_dp_bw_code_to_link_rate(dp->link.rate) / 1000;
  526. ret = cdn_dp_reg_write(dp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
  527. if (ret)
  528. goto err_config_video;
  529. ret = cdn_dp_reg_write(dp, HSYNC2VSYNC_POL_CTRL, 0);
  530. if (ret)
  531. goto err_config_video;
  532. /*
  533. * get a best tu_size and valid symbol:
  534. * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32
  535. * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes)
  536. * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set
  537. * TU += 2 and repeat 2nd step.
  538. */
  539. do {
  540. tu_size_reg += 2;
  541. symbol = tu_size_reg * mode->clock * bit_per_pix;
  542. do_div(symbol, dp->link.num_lanes * link_rate * 8);
  543. rem = do_div(symbol, 1000);
  544. if (tu_size_reg > 64) {
  545. ret = -EINVAL;
  546. DRM_DEV_ERROR(dp->dev,
  547. "tu error, clk:%d, lanes:%d, rate:%d\n",
  548. mode->clock, dp->link.num_lanes,
  549. link_rate);
  550. goto err_config_video;
  551. }
  552. } while ((symbol <= 1) || (tu_size_reg - symbol < 4) ||
  553. (rem > 850) || (rem < 100));
  554. val = symbol + (tu_size_reg << 8);
  555. val |= TU_CNT_RST_EN;
  556. ret = cdn_dp_reg_write(dp, DP_FRAMER_TU, val);
  557. if (ret)
  558. goto err_config_video;
  559. /* set the FIFO Buffer size */
  560. val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate;
  561. val /= (dp->link.num_lanes * link_rate);
  562. val = div_u64(8 * (symbol + 1), bit_per_pix) - val;
  563. val += 2;
  564. ret = cdn_dp_reg_write(dp, DP_VC_TABLE(15), val);
  565. switch (video->color_depth) {
  566. case 6:
  567. val = BCS_6;
  568. break;
  569. case 8:
  570. val = BCS_8;
  571. break;
  572. case 10:
  573. val = BCS_10;
  574. break;
  575. case 12:
  576. val = BCS_12;
  577. break;
  578. case 16:
  579. val = BCS_16;
  580. break;
  581. };
  582. val += video->color_fmt << 8;
  583. ret = cdn_dp_reg_write(dp, DP_FRAMER_PXL_REPR, val);
  584. if (ret)
  585. goto err_config_video;
  586. val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0;
  587. val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0;
  588. ret = cdn_dp_reg_write(dp, DP_FRAMER_SP, val);
  589. if (ret)
  590. goto err_config_video;
  591. val = (mode->hsync_start - mode->hdisplay) << 16;
  592. val |= mode->htotal - mode->hsync_end;
  593. ret = cdn_dp_reg_write(dp, DP_FRONT_BACK_PORCH, val);
  594. if (ret)
  595. goto err_config_video;
  596. val = mode->hdisplay * bit_per_pix / 8;
  597. ret = cdn_dp_reg_write(dp, DP_BYTE_COUNT, val);
  598. if (ret)
  599. goto err_config_video;
  600. val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16);
  601. ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_0, val);
  602. if (ret)
  603. goto err_config_video;
  604. val = mode->hsync_end - mode->hsync_start;
  605. val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15);
  606. ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_1, val);
  607. if (ret)
  608. goto err_config_video;
  609. val = mode->vtotal;
  610. val |= (mode->vtotal - mode->vsync_start) << 16;
  611. ret = cdn_dp_reg_write(dp, MSA_VERTICAL_0, val);
  612. if (ret)
  613. goto err_config_video;
  614. val = mode->vsync_end - mode->vsync_start;
  615. val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15);
  616. ret = cdn_dp_reg_write(dp, MSA_VERTICAL_1, val);
  617. if (ret)
  618. goto err_config_video;
  619. val = cdn_dp_get_msa_misc(video, mode);
  620. ret = cdn_dp_reg_write(dp, MSA_MISC, val);
  621. if (ret)
  622. goto err_config_video;
  623. ret = cdn_dp_reg_write(dp, STREAM_CONFIG, 1);
  624. if (ret)
  625. goto err_config_video;
  626. val = mode->hsync_end - mode->hsync_start;
  627. val |= mode->hdisplay << 16;
  628. ret = cdn_dp_reg_write(dp, DP_HORIZONTAL, val);
  629. if (ret)
  630. goto err_config_video;
  631. val = mode->vdisplay;
  632. val |= (mode->vtotal - mode->vsync_start) << 16;
  633. ret = cdn_dp_reg_write(dp, DP_VERTICAL_0, val);
  634. if (ret)
  635. goto err_config_video;
  636. val = mode->vtotal;
  637. ret = cdn_dp_reg_write(dp, DP_VERTICAL_1, val);
  638. if (ret)
  639. goto err_config_video;
  640. ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 2, 1, 0);
  641. err_config_video:
  642. if (ret)
  643. DRM_DEV_ERROR(dp->dev, "config video failed: %d\n", ret);
  644. return ret;
  645. }
  646. int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio)
  647. {
  648. u32 val;
  649. int ret;
  650. ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, 0);
  651. if (ret) {
  652. DRM_DEV_ERROR(dp->dev, "audio stop failed: %d\n", ret);
  653. return ret;
  654. }
  655. val = SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
  656. val |= SPDIF_FIFO_MID_RANGE(0xe0);
  657. val |= SPDIF_JITTER_THRSH(0xe0);
  658. val |= SPDIF_JITTER_AVG_WIN(7);
  659. writel(val, dp->regs + SPDIF_CTRL_ADDR);
  660. /* clearn the audio config and reset */
  661. writel(0, dp->regs + AUDIO_SRC_CNTL);
  662. writel(0, dp->regs + AUDIO_SRC_CNFG);
  663. writel(AUDIO_SW_RST, dp->regs + AUDIO_SRC_CNTL);
  664. writel(0, dp->regs + AUDIO_SRC_CNTL);
  665. /* reset smpl2pckt component */
  666. writel(0, dp->regs + SMPL2PKT_CNTL);
  667. writel(AUDIO_SW_RST, dp->regs + SMPL2PKT_CNTL);
  668. writel(0, dp->regs + SMPL2PKT_CNTL);
  669. /* reset FIFO */
  670. writel(AUDIO_SW_RST, dp->regs + FIFO_CNTL);
  671. writel(0, dp->regs + FIFO_CNTL);
  672. if (audio->format == AFMT_SPDIF)
  673. clk_disable_unprepare(dp->spdif_clk);
  674. return 0;
  675. }
  676. int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable)
  677. {
  678. int ret;
  679. ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 4, 1, enable);
  680. if (ret)
  681. DRM_DEV_ERROR(dp->dev, "audio mute failed: %d\n", ret);
  682. return ret;
  683. }
  684. static void cdn_dp_audio_config_i2s(struct cdn_dp_device *dp,
  685. struct audio_info *audio)
  686. {
  687. int sub_pckt_num = 1, i2s_port_en_val = 0xf, i;
  688. u32 val;
  689. if (audio->channels == 2) {
  690. if (dp->link.num_lanes == 1)
  691. sub_pckt_num = 2;
  692. else
  693. sub_pckt_num = 4;
  694. i2s_port_en_val = 1;
  695. } else if (audio->channels == 4) {
  696. i2s_port_en_val = 3;
  697. }
  698. writel(0x0, dp->regs + SPDIF_CTRL_ADDR);
  699. writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
  700. val = MAX_NUM_CH(audio->channels);
  701. val |= NUM_OF_I2S_PORTS(audio->channels);
  702. val |= AUDIO_TYPE_LPCM;
  703. val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
  704. writel(val, dp->regs + SMPL2PKT_CNFG);
  705. if (audio->sample_width == 16)
  706. val = 0;
  707. else if (audio->sample_width == 24)
  708. val = 1 << 9;
  709. else
  710. val = 2 << 9;
  711. val |= AUDIO_CH_NUM(audio->channels);
  712. val |= I2S_DEC_PORT_EN(i2s_port_en_val);
  713. val |= TRANS_SMPL_WIDTH_32;
  714. writel(val, dp->regs + AUDIO_SRC_CNFG);
  715. for (i = 0; i < (audio->channels + 1) / 2; i++) {
  716. if (audio->sample_width == 16)
  717. val = (0x02 << 8) | (0x02 << 20);
  718. else if (audio->sample_width == 24)
  719. val = (0x0b << 8) | (0x0b << 20);
  720. val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
  721. writel(val, dp->regs + STTS_BIT_CH(i));
  722. }
  723. switch (audio->sample_rate) {
  724. case 32000:
  725. val = SAMPLING_FREQ(3) |
  726. ORIGINAL_SAMP_FREQ(0xc);
  727. break;
  728. case 44100:
  729. val = SAMPLING_FREQ(0) |
  730. ORIGINAL_SAMP_FREQ(0xf);
  731. break;
  732. case 48000:
  733. val = SAMPLING_FREQ(2) |
  734. ORIGINAL_SAMP_FREQ(0xd);
  735. break;
  736. case 88200:
  737. val = SAMPLING_FREQ(8) |
  738. ORIGINAL_SAMP_FREQ(0x7);
  739. break;
  740. case 96000:
  741. val = SAMPLING_FREQ(0xa) |
  742. ORIGINAL_SAMP_FREQ(5);
  743. break;
  744. case 176400:
  745. val = SAMPLING_FREQ(0xc) |
  746. ORIGINAL_SAMP_FREQ(3);
  747. break;
  748. case 192000:
  749. val = SAMPLING_FREQ(0xe) |
  750. ORIGINAL_SAMP_FREQ(1);
  751. break;
  752. }
  753. val |= 4;
  754. writel(val, dp->regs + COM_CH_STTS_BITS);
  755. writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
  756. writel(I2S_DEC_START, dp->regs + AUDIO_SRC_CNTL);
  757. }
  758. static void cdn_dp_audio_config_spdif(struct cdn_dp_device *dp)
  759. {
  760. u32 val;
  761. val = SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
  762. val |= SPDIF_FIFO_MID_RANGE(0xe0);
  763. val |= SPDIF_JITTER_THRSH(0xe0);
  764. val |= SPDIF_JITTER_AVG_WIN(7);
  765. writel(val, dp->regs + SPDIF_CTRL_ADDR);
  766. writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL);
  767. val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4);
  768. writel(val, dp->regs + SMPL2PKT_CNFG);
  769. writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL);
  770. val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
  771. val |= SPDIF_FIFO_MID_RANGE(0xe0);
  772. val |= SPDIF_JITTER_THRSH(0xe0);
  773. val |= SPDIF_JITTER_AVG_WIN(7);
  774. writel(val, dp->regs + SPDIF_CTRL_ADDR);
  775. clk_prepare_enable(dp->spdif_clk);
  776. clk_set_rate(dp->spdif_clk, CDN_DP_SPDIF_CLK);
  777. }
  778. int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio)
  779. {
  780. int ret;
  781. /* reset the spdif clk before config */
  782. if (audio->format == AFMT_SPDIF) {
  783. reset_control_assert(dp->spdif_rst);
  784. reset_control_deassert(dp->spdif_rst);
  785. }
  786. ret = cdn_dp_reg_write(dp, CM_LANE_CTRL, LANE_REF_CYC);
  787. if (ret)
  788. goto err_audio_config;
  789. ret = cdn_dp_reg_write(dp, CM_CTRL, 0);
  790. if (ret)
  791. goto err_audio_config;
  792. if (audio->format == AFMT_I2S)
  793. cdn_dp_audio_config_i2s(dp, audio);
  794. else if (audio->format == AFMT_SPDIF)
  795. cdn_dp_audio_config_spdif(dp);
  796. ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN);
  797. err_audio_config:
  798. if (ret)
  799. DRM_DEV_ERROR(dp->dev, "audio config failed: %d\n", ret);
  800. return ret;
  801. }