mtk_dpi.c 20 KB

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