mtk_dpi.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. /*
  2. * Copyright (c) 2014 MediaTek Inc.
  3. * Author: Jie Qiu <jie.qiu@mediatek.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  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 <drm/drmP.h>
  15. #include <drm/drm_crtc.h>
  16. #include <drm/drm_crtc_helper.h>
  17. #include <linux/kernel.h>
  18. #include <linux/component.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/of.h>
  21. #include <linux/of_graph.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/types.h>
  24. #include <linux/clk.h>
  25. #include <video/videomode.h>
  26. #include "mtk_dpi_regs.h"
  27. #include "mtk_drm_ddp_comp.h"
  28. enum mtk_dpi_out_bit_num {
  29. MTK_DPI_OUT_BIT_NUM_8BITS,
  30. MTK_DPI_OUT_BIT_NUM_10BITS,
  31. MTK_DPI_OUT_BIT_NUM_12BITS,
  32. MTK_DPI_OUT_BIT_NUM_16BITS
  33. };
  34. enum mtk_dpi_out_yc_map {
  35. MTK_DPI_OUT_YC_MAP_RGB,
  36. MTK_DPI_OUT_YC_MAP_CYCY,
  37. MTK_DPI_OUT_YC_MAP_YCYC,
  38. MTK_DPI_OUT_YC_MAP_CY,
  39. MTK_DPI_OUT_YC_MAP_YC
  40. };
  41. enum mtk_dpi_out_channel_swap {
  42. MTK_DPI_OUT_CHANNEL_SWAP_RGB,
  43. MTK_DPI_OUT_CHANNEL_SWAP_GBR,
  44. MTK_DPI_OUT_CHANNEL_SWAP_BRG,
  45. MTK_DPI_OUT_CHANNEL_SWAP_RBG,
  46. MTK_DPI_OUT_CHANNEL_SWAP_GRB,
  47. MTK_DPI_OUT_CHANNEL_SWAP_BGR
  48. };
  49. enum mtk_dpi_out_color_format {
  50. MTK_DPI_COLOR_FORMAT_RGB,
  51. MTK_DPI_COLOR_FORMAT_RGB_FULL,
  52. MTK_DPI_COLOR_FORMAT_YCBCR_444,
  53. MTK_DPI_COLOR_FORMAT_YCBCR_422,
  54. MTK_DPI_COLOR_FORMAT_XV_YCC,
  55. MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL,
  56. MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
  57. };
  58. struct mtk_dpi {
  59. struct mtk_ddp_comp ddp_comp;
  60. struct drm_encoder encoder;
  61. struct drm_bridge *bridge;
  62. void __iomem *regs;
  63. struct device *dev;
  64. struct clk *engine_clk;
  65. struct clk *pixel_clk;
  66. struct clk *tvd_clk;
  67. int irq;
  68. struct drm_display_mode mode;
  69. enum mtk_dpi_out_color_format color_format;
  70. enum mtk_dpi_out_yc_map yc_map;
  71. enum mtk_dpi_out_bit_num bit_num;
  72. enum mtk_dpi_out_channel_swap channel_swap;
  73. bool power_sta;
  74. u8 power_ctl;
  75. };
  76. static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e)
  77. {
  78. return container_of(e, struct mtk_dpi, encoder);
  79. }
  80. enum mtk_dpi_polarity {
  81. MTK_DPI_POLARITY_RISING,
  82. MTK_DPI_POLARITY_FALLING,
  83. };
  84. enum mtk_dpi_power_ctl {
  85. DPI_POWER_START = BIT(0),
  86. DPI_POWER_ENABLE = BIT(1),
  87. };
  88. struct mtk_dpi_polarities {
  89. enum mtk_dpi_polarity de_pol;
  90. enum mtk_dpi_polarity ck_pol;
  91. enum mtk_dpi_polarity hsync_pol;
  92. enum mtk_dpi_polarity vsync_pol;
  93. };
  94. struct mtk_dpi_sync_param {
  95. u32 sync_width;
  96. u32 front_porch;
  97. u32 back_porch;
  98. bool shift_half_line;
  99. };
  100. struct mtk_dpi_yc_limit {
  101. u16 y_top;
  102. u16 y_bottom;
  103. u16 c_top;
  104. u16 c_bottom;
  105. };
  106. static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
  107. {
  108. u32 tmp = readl(dpi->regs + offset) & ~mask;
  109. tmp |= (val & mask);
  110. writel(tmp, dpi->regs + offset);
  111. }
  112. static void mtk_dpi_sw_reset(struct mtk_dpi *dpi, bool reset)
  113. {
  114. mtk_dpi_mask(dpi, DPI_RET, reset ? RST : 0, RST);
  115. }
  116. static void mtk_dpi_enable(struct mtk_dpi *dpi)
  117. {
  118. mtk_dpi_mask(dpi, DPI_EN, EN, EN);
  119. }
  120. static void mtk_dpi_disable(struct mtk_dpi *dpi)
  121. {
  122. mtk_dpi_mask(dpi, DPI_EN, 0, EN);
  123. }
  124. static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
  125. struct mtk_dpi_sync_param *sync)
  126. {
  127. mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
  128. sync->sync_width << HPW, HPW_MASK);
  129. mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
  130. sync->back_porch << HBP, HBP_MASK);
  131. mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
  132. HFP_MASK);
  133. }
  134. static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
  135. struct mtk_dpi_sync_param *sync,
  136. u32 width_addr, u32 porch_addr)
  137. {
  138. mtk_dpi_mask(dpi, width_addr,
  139. sync->sync_width << VSYNC_WIDTH_SHIFT,
  140. VSYNC_WIDTH_MASK);
  141. mtk_dpi_mask(dpi, width_addr,
  142. sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
  143. VSYNC_HALF_LINE_MASK);
  144. mtk_dpi_mask(dpi, porch_addr,
  145. sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
  146. VSYNC_BACK_PORCH_MASK);
  147. mtk_dpi_mask(dpi, porch_addr,
  148. sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
  149. VSYNC_FRONT_PORCH_MASK);
  150. }
  151. static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi,
  152. struct mtk_dpi_sync_param *sync)
  153. {
  154. mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH, DPI_TGEN_VPORCH);
  155. }
  156. static void mtk_dpi_config_vsync_leven(struct mtk_dpi *dpi,
  157. struct mtk_dpi_sync_param *sync)
  158. {
  159. mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_LEVEN,
  160. DPI_TGEN_VPORCH_LEVEN);
  161. }
  162. static void mtk_dpi_config_vsync_rodd(struct mtk_dpi *dpi,
  163. struct mtk_dpi_sync_param *sync)
  164. {
  165. mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_RODD,
  166. DPI_TGEN_VPORCH_RODD);
  167. }
  168. static void mtk_dpi_config_vsync_reven(struct mtk_dpi *dpi,
  169. struct mtk_dpi_sync_param *sync)
  170. {
  171. mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_REVEN,
  172. DPI_TGEN_VPORCH_REVEN);
  173. }
  174. static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
  175. struct mtk_dpi_polarities *dpi_pol)
  176. {
  177. unsigned int pol;
  178. pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
  179. (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
  180. (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
  181. (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
  182. mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
  183. CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
  184. }
  185. static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
  186. {
  187. mtk_dpi_mask(dpi, DPI_CON, en_3d ? TDFP_EN : 0, TDFP_EN);
  188. }
  189. static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
  190. {
  191. mtk_dpi_mask(dpi, DPI_CON, inter ? INTL_EN : 0, INTL_EN);
  192. }
  193. static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
  194. {
  195. mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK);
  196. mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK);
  197. }
  198. static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi,
  199. struct mtk_dpi_yc_limit *limit)
  200. {
  201. mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_bottom << Y_LIMINT_BOT,
  202. Y_LIMINT_BOT_MASK);
  203. mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_top << Y_LIMINT_TOP,
  204. Y_LIMINT_TOP_MASK);
  205. mtk_dpi_mask(dpi, DPI_C_LIMIT, limit->c_bottom << C_LIMIT_BOT,
  206. C_LIMIT_BOT_MASK);
  207. mtk_dpi_mask(dpi, DPI_C_LIMIT, limit->c_top << C_LIMIT_TOP,
  208. C_LIMIT_TOP_MASK);
  209. }
  210. static void mtk_dpi_config_bit_num(struct mtk_dpi *dpi,
  211. enum mtk_dpi_out_bit_num num)
  212. {
  213. u32 val;
  214. switch (num) {
  215. case MTK_DPI_OUT_BIT_NUM_8BITS:
  216. val = OUT_BIT_8;
  217. break;
  218. case MTK_DPI_OUT_BIT_NUM_10BITS:
  219. val = OUT_BIT_10;
  220. break;
  221. case MTK_DPI_OUT_BIT_NUM_12BITS:
  222. val = OUT_BIT_12;
  223. break;
  224. case MTK_DPI_OUT_BIT_NUM_16BITS:
  225. val = OUT_BIT_16;
  226. break;
  227. default:
  228. val = OUT_BIT_8;
  229. break;
  230. }
  231. mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << OUT_BIT,
  232. OUT_BIT_MASK);
  233. }
  234. static void mtk_dpi_config_yc_map(struct mtk_dpi *dpi,
  235. enum mtk_dpi_out_yc_map map)
  236. {
  237. u32 val;
  238. switch (map) {
  239. case MTK_DPI_OUT_YC_MAP_RGB:
  240. val = YC_MAP_RGB;
  241. break;
  242. case MTK_DPI_OUT_YC_MAP_CYCY:
  243. val = YC_MAP_CYCY;
  244. break;
  245. case MTK_DPI_OUT_YC_MAP_YCYC:
  246. val = YC_MAP_YCYC;
  247. break;
  248. case MTK_DPI_OUT_YC_MAP_CY:
  249. val = YC_MAP_CY;
  250. break;
  251. case MTK_DPI_OUT_YC_MAP_YC:
  252. val = YC_MAP_YC;
  253. break;
  254. default:
  255. val = YC_MAP_RGB;
  256. break;
  257. }
  258. mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << YC_MAP, YC_MAP_MASK);
  259. }
  260. static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
  261. enum mtk_dpi_out_channel_swap swap)
  262. {
  263. u32 val;
  264. switch (swap) {
  265. case MTK_DPI_OUT_CHANNEL_SWAP_RGB:
  266. val = SWAP_RGB;
  267. break;
  268. case MTK_DPI_OUT_CHANNEL_SWAP_GBR:
  269. val = SWAP_GBR;
  270. break;
  271. case MTK_DPI_OUT_CHANNEL_SWAP_BRG:
  272. val = SWAP_BRG;
  273. break;
  274. case MTK_DPI_OUT_CHANNEL_SWAP_RBG:
  275. val = SWAP_RBG;
  276. break;
  277. case MTK_DPI_OUT_CHANNEL_SWAP_GRB:
  278. val = SWAP_GRB;
  279. break;
  280. case MTK_DPI_OUT_CHANNEL_SWAP_BGR:
  281. val = SWAP_BGR;
  282. break;
  283. default:
  284. val = SWAP_RGB;
  285. break;
  286. }
  287. mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
  288. }
  289. static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
  290. {
  291. mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
  292. }
  293. static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
  294. {
  295. mtk_dpi_mask(dpi, DPI_CON, enable ? CSC_ENABLE : 0, CSC_ENABLE);
  296. }
  297. static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
  298. {
  299. mtk_dpi_mask(dpi, DPI_CON, enable ? IN_RB_SWAP : 0, IN_RB_SWAP);
  300. }
  301. static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi)
  302. {
  303. mtk_dpi_mask(dpi, DPI_H_FRE_CON, H_FRE_2N, H_FRE_2N);
  304. }
  305. static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
  306. enum mtk_dpi_out_color_format format)
  307. {
  308. if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) ||
  309. (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
  310. mtk_dpi_config_yuv422_enable(dpi, false);
  311. mtk_dpi_config_csc_enable(dpi, true);
  312. mtk_dpi_config_swap_input(dpi, false);
  313. mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
  314. } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
  315. (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
  316. mtk_dpi_config_yuv422_enable(dpi, true);
  317. mtk_dpi_config_csc_enable(dpi, true);
  318. mtk_dpi_config_swap_input(dpi, true);
  319. mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
  320. } else {
  321. mtk_dpi_config_yuv422_enable(dpi, false);
  322. mtk_dpi_config_csc_enable(dpi, false);
  323. mtk_dpi_config_swap_input(dpi, false);
  324. mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
  325. }
  326. }
  327. static void mtk_dpi_power_off(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl)
  328. {
  329. dpi->power_ctl &= ~pctl;
  330. if ((dpi->power_ctl & DPI_POWER_START) ||
  331. (dpi->power_ctl & DPI_POWER_ENABLE))
  332. return;
  333. if (!dpi->power_sta)
  334. return;
  335. mtk_dpi_disable(dpi);
  336. clk_disable_unprepare(dpi->pixel_clk);
  337. clk_disable_unprepare(dpi->engine_clk);
  338. dpi->power_sta = false;
  339. }
  340. static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl)
  341. {
  342. int ret;
  343. dpi->power_ctl |= pctl;
  344. if (!(dpi->power_ctl & DPI_POWER_START) &&
  345. !(dpi->power_ctl & DPI_POWER_ENABLE))
  346. return 0;
  347. if (dpi->power_sta)
  348. return 0;
  349. ret = clk_prepare_enable(dpi->engine_clk);
  350. if (ret) {
  351. dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
  352. goto err_eng;
  353. }
  354. ret = clk_prepare_enable(dpi->pixel_clk);
  355. if (ret) {
  356. dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
  357. goto err_pixel;
  358. }
  359. mtk_dpi_enable(dpi);
  360. dpi->power_sta = true;
  361. return 0;
  362. err_pixel:
  363. clk_disable_unprepare(dpi->engine_clk);
  364. err_eng:
  365. dpi->power_ctl &= ~pctl;
  366. return ret;
  367. }
  368. static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
  369. struct drm_display_mode *mode)
  370. {
  371. struct mtk_dpi_yc_limit limit;
  372. struct mtk_dpi_polarities dpi_pol;
  373. struct mtk_dpi_sync_param hsync;
  374. struct mtk_dpi_sync_param vsync_lodd = { 0 };
  375. struct mtk_dpi_sync_param vsync_leven = { 0 };
  376. struct mtk_dpi_sync_param vsync_rodd = { 0 };
  377. struct mtk_dpi_sync_param vsync_reven = { 0 };
  378. struct videomode vm = { 0 };
  379. unsigned long pll_rate;
  380. unsigned int factor;
  381. /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
  382. if (mode->clock <= 27000)
  383. factor = 3 << 4;
  384. else if (mode->clock <= 84000)
  385. factor = 3 << 3;
  386. else if (mode->clock <= 167000)
  387. factor = 3 << 2;
  388. else
  389. factor = 3 << 1;
  390. drm_display_mode_to_videomode(mode, &vm);
  391. pll_rate = vm.pixelclock * factor;
  392. dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
  393. pll_rate, vm.pixelclock);
  394. clk_set_rate(dpi->tvd_clk, pll_rate);
  395. pll_rate = clk_get_rate(dpi->tvd_clk);
  396. vm.pixelclock = pll_rate / factor;
  397. clk_set_rate(dpi->pixel_clk, vm.pixelclock);
  398. vm.pixelclock = clk_get_rate(dpi->pixel_clk);
  399. dev_dbg(dpi->dev, "Got PLL %lu Hz, pixel clock %lu Hz\n",
  400. pll_rate, vm.pixelclock);
  401. limit.c_bottom = 0x0010;
  402. limit.c_top = 0x0FE0;
  403. limit.y_bottom = 0x0010;
  404. limit.y_top = 0x0FE0;
  405. dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
  406. dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
  407. dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
  408. MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
  409. dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
  410. MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
  411. hsync.sync_width = vm.hsync_len;
  412. hsync.back_porch = vm.hback_porch;
  413. hsync.front_porch = vm.hfront_porch;
  414. hsync.shift_half_line = false;
  415. vsync_lodd.sync_width = vm.vsync_len;
  416. vsync_lodd.back_porch = vm.vback_porch;
  417. vsync_lodd.front_porch = vm.vfront_porch;
  418. vsync_lodd.shift_half_line = false;
  419. if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
  420. mode->flags & DRM_MODE_FLAG_3D_MASK) {
  421. vsync_leven = vsync_lodd;
  422. vsync_rodd = vsync_lodd;
  423. vsync_reven = vsync_lodd;
  424. vsync_leven.shift_half_line = true;
  425. vsync_reven.shift_half_line = true;
  426. } else if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
  427. !(mode->flags & DRM_MODE_FLAG_3D_MASK)) {
  428. vsync_leven = vsync_lodd;
  429. vsync_leven.shift_half_line = true;
  430. } else if (!(vm.flags & DISPLAY_FLAGS_INTERLACED) &&
  431. mode->flags & DRM_MODE_FLAG_3D_MASK) {
  432. vsync_rodd = vsync_lodd;
  433. }
  434. mtk_dpi_sw_reset(dpi, true);
  435. mtk_dpi_config_pol(dpi, &dpi_pol);
  436. mtk_dpi_config_hsync(dpi, &hsync);
  437. mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd);
  438. mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd);
  439. mtk_dpi_config_vsync_leven(dpi, &vsync_leven);
  440. mtk_dpi_config_vsync_reven(dpi, &vsync_reven);
  441. mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK));
  442. mtk_dpi_config_interface(dpi, !!(vm.flags &
  443. DISPLAY_FLAGS_INTERLACED));
  444. if (vm.flags & DISPLAY_FLAGS_INTERLACED)
  445. mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive >> 1);
  446. else
  447. mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
  448. mtk_dpi_config_channel_limit(dpi, &limit);
  449. mtk_dpi_config_bit_num(dpi, dpi->bit_num);
  450. mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
  451. mtk_dpi_config_yc_map(dpi, dpi->yc_map);
  452. mtk_dpi_config_color_format(dpi, dpi->color_format);
  453. mtk_dpi_config_2n_h_fre(dpi);
  454. mtk_dpi_sw_reset(dpi, false);
  455. return 0;
  456. }
  457. static void mtk_dpi_encoder_destroy(struct drm_encoder *encoder)
  458. {
  459. drm_encoder_cleanup(encoder);
  460. }
  461. static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = {
  462. .destroy = mtk_dpi_encoder_destroy,
  463. };
  464. static bool mtk_dpi_encoder_mode_fixup(struct drm_encoder *encoder,
  465. const struct drm_display_mode *mode,
  466. struct drm_display_mode *adjusted_mode)
  467. {
  468. return true;
  469. }
  470. static void mtk_dpi_encoder_mode_set(struct drm_encoder *encoder,
  471. struct drm_display_mode *mode,
  472. struct drm_display_mode *adjusted_mode)
  473. {
  474. struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder);
  475. drm_mode_copy(&dpi->mode, adjusted_mode);
  476. }
  477. static void mtk_dpi_encoder_disable(struct drm_encoder *encoder)
  478. {
  479. struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder);
  480. mtk_dpi_power_off(dpi, DPI_POWER_ENABLE);
  481. }
  482. static void mtk_dpi_encoder_enable(struct drm_encoder *encoder)
  483. {
  484. struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder);
  485. mtk_dpi_power_on(dpi, DPI_POWER_ENABLE);
  486. mtk_dpi_set_display_mode(dpi, &dpi->mode);
  487. }
  488. static int mtk_dpi_atomic_check(struct drm_encoder *encoder,
  489. struct drm_crtc_state *crtc_state,
  490. struct drm_connector_state *conn_state)
  491. {
  492. return 0;
  493. }
  494. static const struct drm_encoder_helper_funcs mtk_dpi_encoder_helper_funcs = {
  495. .mode_fixup = mtk_dpi_encoder_mode_fixup,
  496. .mode_set = mtk_dpi_encoder_mode_set,
  497. .disable = mtk_dpi_encoder_disable,
  498. .enable = mtk_dpi_encoder_enable,
  499. .atomic_check = mtk_dpi_atomic_check,
  500. };
  501. static void mtk_dpi_start(struct mtk_ddp_comp *comp)
  502. {
  503. struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp);
  504. mtk_dpi_power_on(dpi, DPI_POWER_START);
  505. }
  506. static void mtk_dpi_stop(struct mtk_ddp_comp *comp)
  507. {
  508. struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp);
  509. mtk_dpi_power_off(dpi, DPI_POWER_START);
  510. }
  511. static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = {
  512. .start = mtk_dpi_start,
  513. .stop = mtk_dpi_stop,
  514. };
  515. static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
  516. {
  517. struct mtk_dpi *dpi = dev_get_drvdata(dev);
  518. struct drm_device *drm_dev = data;
  519. int ret;
  520. ret = mtk_ddp_comp_register(drm_dev, &dpi->ddp_comp);
  521. if (ret < 0) {
  522. dev_err(dev, "Failed to register component %pOF: %d\n",
  523. dev->of_node, ret);
  524. return ret;
  525. }
  526. ret = drm_encoder_init(drm_dev, &dpi->encoder, &mtk_dpi_encoder_funcs,
  527. DRM_MODE_ENCODER_TMDS, NULL);
  528. if (ret) {
  529. dev_err(dev, "Failed to initialize decoder: %d\n", ret);
  530. goto err_unregister;
  531. }
  532. drm_encoder_helper_add(&dpi->encoder, &mtk_dpi_encoder_helper_funcs);
  533. /* Currently DPI0 is fixed to be driven by OVL1 */
  534. dpi->encoder.possible_crtcs = BIT(1);
  535. ret = drm_bridge_attach(&dpi->encoder, dpi->bridge, NULL);
  536. if (ret) {
  537. dev_err(dev, "Failed to attach bridge: %d\n", ret);
  538. goto err_cleanup;
  539. }
  540. dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
  541. dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
  542. dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
  543. dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
  544. return 0;
  545. err_cleanup:
  546. drm_encoder_cleanup(&dpi->encoder);
  547. err_unregister:
  548. mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp);
  549. return ret;
  550. }
  551. static void mtk_dpi_unbind(struct device *dev, struct device *master,
  552. void *data)
  553. {
  554. struct mtk_dpi *dpi = dev_get_drvdata(dev);
  555. struct drm_device *drm_dev = data;
  556. drm_encoder_cleanup(&dpi->encoder);
  557. mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp);
  558. }
  559. static const struct component_ops mtk_dpi_component_ops = {
  560. .bind = mtk_dpi_bind,
  561. .unbind = mtk_dpi_unbind,
  562. };
  563. static int mtk_dpi_probe(struct platform_device *pdev)
  564. {
  565. struct device *dev = &pdev->dev;
  566. struct mtk_dpi *dpi;
  567. struct resource *mem;
  568. struct device_node *bridge_node;
  569. int comp_id;
  570. int ret;
  571. dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
  572. if (!dpi)
  573. return -ENOMEM;
  574. dpi->dev = dev;
  575. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  576. dpi->regs = devm_ioremap_resource(dev, mem);
  577. if (IS_ERR(dpi->regs)) {
  578. ret = PTR_ERR(dpi->regs);
  579. dev_err(dev, "Failed to ioremap mem resource: %d\n", ret);
  580. return ret;
  581. }
  582. dpi->engine_clk = devm_clk_get(dev, "engine");
  583. if (IS_ERR(dpi->engine_clk)) {
  584. ret = PTR_ERR(dpi->engine_clk);
  585. dev_err(dev, "Failed to get engine clock: %d\n", ret);
  586. return ret;
  587. }
  588. dpi->pixel_clk = devm_clk_get(dev, "pixel");
  589. if (IS_ERR(dpi->pixel_clk)) {
  590. ret = PTR_ERR(dpi->pixel_clk);
  591. dev_err(dev, "Failed to get pixel clock: %d\n", ret);
  592. return ret;
  593. }
  594. dpi->tvd_clk = devm_clk_get(dev, "pll");
  595. if (IS_ERR(dpi->tvd_clk)) {
  596. ret = PTR_ERR(dpi->tvd_clk);
  597. dev_err(dev, "Failed to get tvdpll clock: %d\n", ret);
  598. return ret;
  599. }
  600. dpi->irq = platform_get_irq(pdev, 0);
  601. if (dpi->irq <= 0) {
  602. dev_err(dev, "Failed to get irq: %d\n", dpi->irq);
  603. return -EINVAL;
  604. }
  605. bridge_node = of_graph_get_remote_node(dev->of_node, 0, 0);
  606. if (!bridge_node)
  607. return -ENODEV;
  608. dev_info(dev, "Found bridge node: %pOF\n", bridge_node);
  609. dpi->bridge = of_drm_find_bridge(bridge_node);
  610. of_node_put(bridge_node);
  611. if (!dpi->bridge)
  612. return -EPROBE_DEFER;
  613. comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI);
  614. if (comp_id < 0) {
  615. dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
  616. return comp_id;
  617. }
  618. ret = mtk_ddp_comp_init(dev, dev->of_node, &dpi->ddp_comp, comp_id,
  619. &mtk_dpi_funcs);
  620. if (ret) {
  621. dev_err(dev, "Failed to initialize component: %d\n", ret);
  622. return ret;
  623. }
  624. platform_set_drvdata(pdev, dpi);
  625. ret = component_add(dev, &mtk_dpi_component_ops);
  626. if (ret) {
  627. dev_err(dev, "Failed to add component: %d\n", ret);
  628. return ret;
  629. }
  630. return 0;
  631. }
  632. static int mtk_dpi_remove(struct platform_device *pdev)
  633. {
  634. component_del(&pdev->dev, &mtk_dpi_component_ops);
  635. return 0;
  636. }
  637. static const struct of_device_id mtk_dpi_of_ids[] = {
  638. { .compatible = "mediatek,mt8173-dpi", },
  639. {}
  640. };
  641. struct platform_driver mtk_dpi_driver = {
  642. .probe = mtk_dpi_probe,
  643. .remove = mtk_dpi_remove,
  644. .driver = {
  645. .name = "mediatek-dpi",
  646. .of_match_table = mtk_dpi_of_ids,
  647. },
  648. };