mtk_dpi.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2014 MediaTek Inc.
  4. * Author: Jie Qiu <[email protected]>
  5. */
  6. #include <linux/clk.h>
  7. #include <linux/component.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/kernel.h>
  10. #include <linux/media-bus-format.h>
  11. #include <linux/of.h>
  12. #include <linux/of_device.h>
  13. #include <linux/of_graph.h>
  14. #include <linux/pinctrl/consumer.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/types.h>
  17. #include <video/videomode.h>
  18. #include <drm/drm_atomic_helper.h>
  19. #include <drm/drm_bridge.h>
  20. #include <drm/drm_bridge_connector.h>
  21. #include <drm/drm_crtc.h>
  22. #include <drm/drm_edid.h>
  23. #include <drm/drm_of.h>
  24. #include <drm/drm_simple_kms_helper.h>
  25. #include "mtk_disp_drv.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_YCBCR_422
  52. };
  53. struct mtk_dpi {
  54. struct drm_encoder encoder;
  55. struct drm_bridge bridge;
  56. struct drm_bridge *next_bridge;
  57. struct drm_connector *connector;
  58. void __iomem *regs;
  59. struct device *dev;
  60. struct clk *engine_clk;
  61. struct clk *pixel_clk;
  62. struct clk *tvd_clk;
  63. int irq;
  64. struct drm_display_mode mode;
  65. const struct mtk_dpi_conf *conf;
  66. enum mtk_dpi_out_color_format color_format;
  67. enum mtk_dpi_out_yc_map yc_map;
  68. enum mtk_dpi_out_bit_num bit_num;
  69. enum mtk_dpi_out_channel_swap channel_swap;
  70. struct pinctrl *pinctrl;
  71. struct pinctrl_state *pins_gpio;
  72. struct pinctrl_state *pins_dpi;
  73. u32 output_fmt;
  74. int refcount;
  75. };
  76. static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b)
  77. {
  78. return container_of(b, struct mtk_dpi, bridge);
  79. }
  80. enum mtk_dpi_polarity {
  81. MTK_DPI_POLARITY_RISING,
  82. MTK_DPI_POLARITY_FALLING,
  83. };
  84. struct mtk_dpi_polarities {
  85. enum mtk_dpi_polarity de_pol;
  86. enum mtk_dpi_polarity ck_pol;
  87. enum mtk_dpi_polarity hsync_pol;
  88. enum mtk_dpi_polarity vsync_pol;
  89. };
  90. struct mtk_dpi_sync_param {
  91. u32 sync_width;
  92. u32 front_porch;
  93. u32 back_porch;
  94. bool shift_half_line;
  95. };
  96. struct mtk_dpi_yc_limit {
  97. u16 y_top;
  98. u16 y_bottom;
  99. u16 c_top;
  100. u16 c_bottom;
  101. };
  102. /**
  103. * struct mtk_dpi_conf - Configuration of mediatek dpi.
  104. * @cal_factor: Callback function to calculate factor value.
  105. * @reg_h_fre_con: Register address of frequency control.
  106. * @max_clock_khz: Max clock frequency supported for this SoCs in khz units.
  107. * @edge_sel_en: Enable of edge selection.
  108. * @output_fmts: Array of supported output formats.
  109. * @num_output_fmts: Quantity of supported output formats.
  110. * @is_ck_de_pol: Support CK/DE polarity.
  111. * @swap_input_support: Support input swap function.
  112. * @support_direct_pin: IP supports direct connection to dpi panels.
  113. * @input_2pixel: Input pixel of dp_intf is 2 pixel per round, so enable this
  114. * config to enable this feature.
  115. * @dimension_mask: Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
  116. * (no shift).
  117. * @hvsize_mask: Mask of HSIZE and VSIZE mask (no shift).
  118. * @channel_swap_shift: Shift value of channel swap.
  119. * @yuv422_en_bit: Enable bit of yuv422.
  120. * @csc_enable_bit: Enable bit of CSC.
  121. * @pixels_per_iter: Quantity of transferred pixels per iteration.
  122. */
  123. struct mtk_dpi_conf {
  124. unsigned int (*cal_factor)(int clock);
  125. u32 reg_h_fre_con;
  126. u32 max_clock_khz;
  127. bool edge_sel_en;
  128. const u32 *output_fmts;
  129. u32 num_output_fmts;
  130. bool is_ck_de_pol;
  131. bool swap_input_support;
  132. bool support_direct_pin;
  133. bool input_2pixel;
  134. u32 dimension_mask;
  135. u32 hvsize_mask;
  136. u32 channel_swap_shift;
  137. u32 yuv422_en_bit;
  138. u32 csc_enable_bit;
  139. u32 pixels_per_iter;
  140. };
  141. static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
  142. {
  143. u32 tmp = readl(dpi->regs + offset) & ~mask;
  144. tmp |= (val & mask);
  145. writel(tmp, dpi->regs + offset);
  146. }
  147. static void mtk_dpi_sw_reset(struct mtk_dpi *dpi, bool reset)
  148. {
  149. mtk_dpi_mask(dpi, DPI_RET, reset ? RST : 0, RST);
  150. }
  151. static void mtk_dpi_enable(struct mtk_dpi *dpi)
  152. {
  153. mtk_dpi_mask(dpi, DPI_EN, EN, EN);
  154. }
  155. static void mtk_dpi_disable(struct mtk_dpi *dpi)
  156. {
  157. mtk_dpi_mask(dpi, DPI_EN, 0, EN);
  158. }
  159. static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
  160. struct mtk_dpi_sync_param *sync)
  161. {
  162. mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH, sync->sync_width << HPW,
  163. dpi->conf->dimension_mask << HPW);
  164. mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->back_porch << HBP,
  165. dpi->conf->dimension_mask << HBP);
  166. mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
  167. dpi->conf->dimension_mask << HFP);
  168. }
  169. static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
  170. struct mtk_dpi_sync_param *sync,
  171. u32 width_addr, u32 porch_addr)
  172. {
  173. mtk_dpi_mask(dpi, width_addr,
  174. sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
  175. VSYNC_HALF_LINE_MASK);
  176. mtk_dpi_mask(dpi, width_addr,
  177. sync->sync_width << VSYNC_WIDTH_SHIFT,
  178. dpi->conf->dimension_mask << VSYNC_WIDTH_SHIFT);
  179. mtk_dpi_mask(dpi, porch_addr,
  180. sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
  181. dpi->conf->dimension_mask << VSYNC_BACK_PORCH_SHIFT);
  182. mtk_dpi_mask(dpi, porch_addr,
  183. sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
  184. dpi->conf->dimension_mask << VSYNC_FRONT_PORCH_SHIFT);
  185. }
  186. static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi,
  187. struct mtk_dpi_sync_param *sync)
  188. {
  189. mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH, DPI_TGEN_VPORCH);
  190. }
  191. static void mtk_dpi_config_vsync_leven(struct mtk_dpi *dpi,
  192. struct mtk_dpi_sync_param *sync)
  193. {
  194. mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_LEVEN,
  195. DPI_TGEN_VPORCH_LEVEN);
  196. }
  197. static void mtk_dpi_config_vsync_rodd(struct mtk_dpi *dpi,
  198. struct mtk_dpi_sync_param *sync)
  199. {
  200. mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_RODD,
  201. DPI_TGEN_VPORCH_RODD);
  202. }
  203. static void mtk_dpi_config_vsync_reven(struct mtk_dpi *dpi,
  204. struct mtk_dpi_sync_param *sync)
  205. {
  206. mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_REVEN,
  207. DPI_TGEN_VPORCH_REVEN);
  208. }
  209. static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
  210. struct mtk_dpi_polarities *dpi_pol)
  211. {
  212. unsigned int pol;
  213. unsigned int mask;
  214. mask = HSYNC_POL | VSYNC_POL;
  215. pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
  216. (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
  217. if (dpi->conf->is_ck_de_pol) {
  218. mask |= CK_POL | DE_POL;
  219. pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
  220. 0 : CK_POL) |
  221. (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
  222. 0 : DE_POL);
  223. }
  224. mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
  225. }
  226. static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
  227. {
  228. mtk_dpi_mask(dpi, DPI_CON, en_3d ? TDFP_EN : 0, TDFP_EN);
  229. }
  230. static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
  231. {
  232. mtk_dpi_mask(dpi, DPI_CON, inter ? INTL_EN : 0, INTL_EN);
  233. }
  234. static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
  235. {
  236. mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
  237. dpi->conf->hvsize_mask << HSIZE);
  238. mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
  239. dpi->conf->hvsize_mask << VSIZE);
  240. }
  241. static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
  242. {
  243. struct mtk_dpi_yc_limit limit;
  244. if (drm_default_rgb_quant_range(&dpi->mode) ==
  245. HDMI_QUANTIZATION_RANGE_LIMITED) {
  246. limit.y_bottom = 0x10;
  247. limit.y_top = 0xfe0;
  248. limit.c_bottom = 0x10;
  249. limit.c_top = 0xfe0;
  250. } else {
  251. limit.y_bottom = 0;
  252. limit.y_top = 0xfff;
  253. limit.c_bottom = 0;
  254. limit.c_top = 0xfff;
  255. }
  256. mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit.y_bottom << Y_LIMINT_BOT,
  257. Y_LIMINT_BOT_MASK);
  258. mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit.y_top << Y_LIMINT_TOP,
  259. Y_LIMINT_TOP_MASK);
  260. mtk_dpi_mask(dpi, DPI_C_LIMIT, limit.c_bottom << C_LIMIT_BOT,
  261. C_LIMIT_BOT_MASK);
  262. mtk_dpi_mask(dpi, DPI_C_LIMIT, limit.c_top << C_LIMIT_TOP,
  263. C_LIMIT_TOP_MASK);
  264. }
  265. static void mtk_dpi_config_bit_num(struct mtk_dpi *dpi,
  266. enum mtk_dpi_out_bit_num num)
  267. {
  268. u32 val;
  269. switch (num) {
  270. case MTK_DPI_OUT_BIT_NUM_8BITS:
  271. val = OUT_BIT_8;
  272. break;
  273. case MTK_DPI_OUT_BIT_NUM_10BITS:
  274. val = OUT_BIT_10;
  275. break;
  276. case MTK_DPI_OUT_BIT_NUM_12BITS:
  277. val = OUT_BIT_12;
  278. break;
  279. case MTK_DPI_OUT_BIT_NUM_16BITS:
  280. val = OUT_BIT_16;
  281. break;
  282. default:
  283. val = OUT_BIT_8;
  284. break;
  285. }
  286. mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << OUT_BIT,
  287. OUT_BIT_MASK);
  288. }
  289. static void mtk_dpi_config_yc_map(struct mtk_dpi *dpi,
  290. enum mtk_dpi_out_yc_map map)
  291. {
  292. u32 val;
  293. switch (map) {
  294. case MTK_DPI_OUT_YC_MAP_RGB:
  295. val = YC_MAP_RGB;
  296. break;
  297. case MTK_DPI_OUT_YC_MAP_CYCY:
  298. val = YC_MAP_CYCY;
  299. break;
  300. case MTK_DPI_OUT_YC_MAP_YCYC:
  301. val = YC_MAP_YCYC;
  302. break;
  303. case MTK_DPI_OUT_YC_MAP_CY:
  304. val = YC_MAP_CY;
  305. break;
  306. case MTK_DPI_OUT_YC_MAP_YC:
  307. val = YC_MAP_YC;
  308. break;
  309. default:
  310. val = YC_MAP_RGB;
  311. break;
  312. }
  313. mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << YC_MAP, YC_MAP_MASK);
  314. }
  315. static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
  316. enum mtk_dpi_out_channel_swap swap)
  317. {
  318. u32 val;
  319. switch (swap) {
  320. case MTK_DPI_OUT_CHANNEL_SWAP_RGB:
  321. val = SWAP_RGB;
  322. break;
  323. case MTK_DPI_OUT_CHANNEL_SWAP_GBR:
  324. val = SWAP_GBR;
  325. break;
  326. case MTK_DPI_OUT_CHANNEL_SWAP_BRG:
  327. val = SWAP_BRG;
  328. break;
  329. case MTK_DPI_OUT_CHANNEL_SWAP_RBG:
  330. val = SWAP_RBG;
  331. break;
  332. case MTK_DPI_OUT_CHANNEL_SWAP_GRB:
  333. val = SWAP_GRB;
  334. break;
  335. case MTK_DPI_OUT_CHANNEL_SWAP_BGR:
  336. val = SWAP_BGR;
  337. break;
  338. default:
  339. val = SWAP_RGB;
  340. break;
  341. }
  342. mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
  343. val << dpi->conf->channel_swap_shift,
  344. CH_SWAP_MASK << dpi->conf->channel_swap_shift);
  345. }
  346. static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
  347. {
  348. mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit : 0,
  349. dpi->conf->yuv422_en_bit);
  350. }
  351. static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
  352. {
  353. mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->csc_enable_bit : 0,
  354. dpi->conf->csc_enable_bit);
  355. }
  356. static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
  357. {
  358. mtk_dpi_mask(dpi, DPI_CON, enable ? IN_RB_SWAP : 0, IN_RB_SWAP);
  359. }
  360. static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi)
  361. {
  362. mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N);
  363. }
  364. static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
  365. {
  366. if (dpi->conf->edge_sel_en)
  367. mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
  368. }
  369. static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
  370. enum mtk_dpi_out_color_format format)
  371. {
  372. mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
  373. if (format == MTK_DPI_COLOR_FORMAT_YCBCR_422) {
  374. mtk_dpi_config_yuv422_enable(dpi, true);
  375. mtk_dpi_config_csc_enable(dpi, true);
  376. /*
  377. * If height is smaller than 720, we need to use RGB_TO_BT601
  378. * to transfer to yuv422. Otherwise, we use RGB_TO_JPEG.
  379. */
  380. mtk_dpi_mask(dpi, DPI_MATRIX_SET, dpi->mode.hdisplay <= 720 ?
  381. MATRIX_SEL_RGB_TO_BT601 : MATRIX_SEL_RGB_TO_JPEG,
  382. INT_MATRIX_SEL_MASK);
  383. } else {
  384. mtk_dpi_config_yuv422_enable(dpi, false);
  385. mtk_dpi_config_csc_enable(dpi, false);
  386. if (dpi->conf->swap_input_support)
  387. mtk_dpi_config_swap_input(dpi, false);
  388. }
  389. }
  390. static void mtk_dpi_dual_edge(struct mtk_dpi *dpi)
  391. {
  392. if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
  393. (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
  394. mtk_dpi_mask(dpi, DPI_DDR_SETTING, DDR_EN | DDR_4PHASE,
  395. DDR_EN | DDR_4PHASE);
  396. mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
  397. dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE ?
  398. EDGE_SEL : 0, EDGE_SEL);
  399. } else {
  400. mtk_dpi_mask(dpi, DPI_DDR_SETTING, DDR_EN | DDR_4PHASE, 0);
  401. }
  402. }
  403. static void mtk_dpi_power_off(struct mtk_dpi *dpi)
  404. {
  405. if (WARN_ON(dpi->refcount == 0))
  406. return;
  407. if (--dpi->refcount != 0)
  408. return;
  409. mtk_dpi_disable(dpi);
  410. clk_disable_unprepare(dpi->pixel_clk);
  411. clk_disable_unprepare(dpi->engine_clk);
  412. }
  413. static int mtk_dpi_power_on(struct mtk_dpi *dpi)
  414. {
  415. int ret;
  416. if (++dpi->refcount != 1)
  417. return 0;
  418. ret = clk_prepare_enable(dpi->engine_clk);
  419. if (ret) {
  420. dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
  421. goto err_refcount;
  422. }
  423. ret = clk_prepare_enable(dpi->pixel_clk);
  424. if (ret) {
  425. dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
  426. goto err_pixel;
  427. }
  428. return 0;
  429. err_pixel:
  430. clk_disable_unprepare(dpi->engine_clk);
  431. err_refcount:
  432. dpi->refcount--;
  433. return ret;
  434. }
  435. static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
  436. struct drm_display_mode *mode)
  437. {
  438. struct mtk_dpi_polarities dpi_pol;
  439. struct mtk_dpi_sync_param hsync;
  440. struct mtk_dpi_sync_param vsync_lodd = { 0 };
  441. struct mtk_dpi_sync_param vsync_leven = { 0 };
  442. struct mtk_dpi_sync_param vsync_rodd = { 0 };
  443. struct mtk_dpi_sync_param vsync_reven = { 0 };
  444. struct videomode vm = { 0 };
  445. unsigned long pll_rate;
  446. unsigned int factor;
  447. /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
  448. factor = dpi->conf->cal_factor(mode->clock);
  449. drm_display_mode_to_videomode(mode, &vm);
  450. pll_rate = vm.pixelclock * factor;
  451. dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
  452. pll_rate, vm.pixelclock);
  453. clk_set_rate(dpi->tvd_clk, pll_rate);
  454. pll_rate = clk_get_rate(dpi->tvd_clk);
  455. /*
  456. * Depending on the IP version, we may output a different amount of
  457. * pixels for each iteration: divide the clock by this number and
  458. * adjust the display porches accordingly.
  459. */
  460. vm.pixelclock = pll_rate / factor;
  461. vm.pixelclock /= dpi->conf->pixels_per_iter;
  462. if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
  463. (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
  464. clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
  465. else
  466. clk_set_rate(dpi->pixel_clk, vm.pixelclock);
  467. vm.pixelclock = clk_get_rate(dpi->pixel_clk);
  468. dev_dbg(dpi->dev, "Got PLL %lu Hz, pixel clock %lu Hz\n",
  469. pll_rate, vm.pixelclock);
  470. dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
  471. dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
  472. dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
  473. MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
  474. dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
  475. MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
  476. /*
  477. * Depending on the IP version, we may output a different amount of
  478. * pixels for each iteration: divide the clock by this number and
  479. * adjust the display porches accordingly.
  480. */
  481. hsync.sync_width = vm.hsync_len / dpi->conf->pixels_per_iter;
  482. hsync.back_porch = vm.hback_porch / dpi->conf->pixels_per_iter;
  483. hsync.front_porch = vm.hfront_porch / dpi->conf->pixels_per_iter;
  484. hsync.shift_half_line = false;
  485. vsync_lodd.sync_width = vm.vsync_len;
  486. vsync_lodd.back_porch = vm.vback_porch;
  487. vsync_lodd.front_porch = vm.vfront_porch;
  488. vsync_lodd.shift_half_line = false;
  489. if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
  490. mode->flags & DRM_MODE_FLAG_3D_MASK) {
  491. vsync_leven = vsync_lodd;
  492. vsync_rodd = vsync_lodd;
  493. vsync_reven = vsync_lodd;
  494. vsync_leven.shift_half_line = true;
  495. vsync_reven.shift_half_line = true;
  496. } else if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
  497. !(mode->flags & DRM_MODE_FLAG_3D_MASK)) {
  498. vsync_leven = vsync_lodd;
  499. vsync_leven.shift_half_line = true;
  500. } else if (!(vm.flags & DISPLAY_FLAGS_INTERLACED) &&
  501. mode->flags & DRM_MODE_FLAG_3D_MASK) {
  502. vsync_rodd = vsync_lodd;
  503. }
  504. mtk_dpi_sw_reset(dpi, true);
  505. mtk_dpi_config_pol(dpi, &dpi_pol);
  506. mtk_dpi_config_hsync(dpi, &hsync);
  507. mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd);
  508. mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd);
  509. mtk_dpi_config_vsync_leven(dpi, &vsync_leven);
  510. mtk_dpi_config_vsync_reven(dpi, &vsync_reven);
  511. mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK));
  512. mtk_dpi_config_interface(dpi, !!(vm.flags &
  513. DISPLAY_FLAGS_INTERLACED));
  514. if (vm.flags & DISPLAY_FLAGS_INTERLACED)
  515. mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive >> 1);
  516. else
  517. mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
  518. mtk_dpi_config_channel_limit(dpi);
  519. mtk_dpi_config_bit_num(dpi, dpi->bit_num);
  520. mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
  521. mtk_dpi_config_color_format(dpi, dpi->color_format);
  522. if (dpi->conf->support_direct_pin) {
  523. mtk_dpi_config_yc_map(dpi, dpi->yc_map);
  524. mtk_dpi_config_2n_h_fre(dpi);
  525. mtk_dpi_dual_edge(dpi);
  526. mtk_dpi_config_disable_edge(dpi);
  527. }
  528. if (dpi->conf->input_2pixel) {
  529. mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
  530. DPINTF_INPUT_2P_EN);
  531. }
  532. mtk_dpi_sw_reset(dpi, false);
  533. return 0;
  534. }
  535. static u32 *mtk_dpi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
  536. struct drm_bridge_state *bridge_state,
  537. struct drm_crtc_state *crtc_state,
  538. struct drm_connector_state *conn_state,
  539. unsigned int *num_output_fmts)
  540. {
  541. struct mtk_dpi *dpi = bridge_to_dpi(bridge);
  542. u32 *output_fmts;
  543. *num_output_fmts = 0;
  544. if (!dpi->conf->output_fmts) {
  545. dev_err(dpi->dev, "output_fmts should not be null\n");
  546. return NULL;
  547. }
  548. output_fmts = kcalloc(dpi->conf->num_output_fmts, sizeof(*output_fmts),
  549. GFP_KERNEL);
  550. if (!output_fmts)
  551. return NULL;
  552. *num_output_fmts = dpi->conf->num_output_fmts;
  553. memcpy(output_fmts, dpi->conf->output_fmts,
  554. sizeof(*output_fmts) * dpi->conf->num_output_fmts);
  555. return output_fmts;
  556. }
  557. static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
  558. struct drm_bridge_state *bridge_state,
  559. struct drm_crtc_state *crtc_state,
  560. struct drm_connector_state *conn_state,
  561. u32 output_fmt,
  562. unsigned int *num_input_fmts)
  563. {
  564. u32 *input_fmts;
  565. *num_input_fmts = 0;
  566. input_fmts = kcalloc(1, sizeof(*input_fmts),
  567. GFP_KERNEL);
  568. if (!input_fmts)
  569. return NULL;
  570. *num_input_fmts = 1;
  571. input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
  572. return input_fmts;
  573. }
  574. static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
  575. struct drm_bridge_state *bridge_state,
  576. struct drm_crtc_state *crtc_state,
  577. struct drm_connector_state *conn_state)
  578. {
  579. struct mtk_dpi *dpi = bridge_to_dpi(bridge);
  580. unsigned int out_bus_format;
  581. out_bus_format = bridge_state->output_bus_cfg.format;
  582. if (out_bus_format == MEDIA_BUS_FMT_FIXED)
  583. if (dpi->conf->num_output_fmts)
  584. out_bus_format = dpi->conf->output_fmts[0];
  585. dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
  586. bridge_state->input_bus_cfg.format,
  587. bridge_state->output_bus_cfg.format);
  588. dpi->output_fmt = out_bus_format;
  589. dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
  590. dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
  591. dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
  592. if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
  593. dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422;
  594. else
  595. dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
  596. return 0;
  597. }
  598. static int mtk_dpi_bridge_attach(struct drm_bridge *bridge,
  599. enum drm_bridge_attach_flags flags)
  600. {
  601. struct mtk_dpi *dpi = bridge_to_dpi(bridge);
  602. return drm_bridge_attach(bridge->encoder, dpi->next_bridge,
  603. &dpi->bridge, flags);
  604. }
  605. static void mtk_dpi_bridge_mode_set(struct drm_bridge *bridge,
  606. const struct drm_display_mode *mode,
  607. const struct drm_display_mode *adjusted_mode)
  608. {
  609. struct mtk_dpi *dpi = bridge_to_dpi(bridge);
  610. drm_mode_copy(&dpi->mode, adjusted_mode);
  611. }
  612. static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
  613. {
  614. struct mtk_dpi *dpi = bridge_to_dpi(bridge);
  615. mtk_dpi_power_off(dpi);
  616. if (dpi->pinctrl && dpi->pins_gpio)
  617. pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
  618. }
  619. static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
  620. {
  621. struct mtk_dpi *dpi = bridge_to_dpi(bridge);
  622. if (dpi->pinctrl && dpi->pins_dpi)
  623. pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
  624. mtk_dpi_power_on(dpi);
  625. mtk_dpi_set_display_mode(dpi, &dpi->mode);
  626. mtk_dpi_enable(dpi);
  627. }
  628. static enum drm_mode_status
  629. mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
  630. const struct drm_display_info *info,
  631. const struct drm_display_mode *mode)
  632. {
  633. struct mtk_dpi *dpi = bridge_to_dpi(bridge);
  634. if (mode->clock > dpi->conf->max_clock_khz)
  635. return MODE_CLOCK_HIGH;
  636. return MODE_OK;
  637. }
  638. static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
  639. .attach = mtk_dpi_bridge_attach,
  640. .mode_set = mtk_dpi_bridge_mode_set,
  641. .mode_valid = mtk_dpi_bridge_mode_valid,
  642. .disable = mtk_dpi_bridge_disable,
  643. .enable = mtk_dpi_bridge_enable,
  644. .atomic_check = mtk_dpi_bridge_atomic_check,
  645. .atomic_get_output_bus_fmts = mtk_dpi_bridge_atomic_get_output_bus_fmts,
  646. .atomic_get_input_bus_fmts = mtk_dpi_bridge_atomic_get_input_bus_fmts,
  647. .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
  648. .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
  649. .atomic_reset = drm_atomic_helper_bridge_reset,
  650. };
  651. void mtk_dpi_start(struct device *dev)
  652. {
  653. struct mtk_dpi *dpi = dev_get_drvdata(dev);
  654. mtk_dpi_power_on(dpi);
  655. }
  656. void mtk_dpi_stop(struct device *dev)
  657. {
  658. struct mtk_dpi *dpi = dev_get_drvdata(dev);
  659. mtk_dpi_power_off(dpi);
  660. }
  661. static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
  662. {
  663. struct mtk_dpi *dpi = dev_get_drvdata(dev);
  664. struct drm_device *drm_dev = data;
  665. int ret;
  666. ret = drm_simple_encoder_init(drm_dev, &dpi->encoder,
  667. DRM_MODE_ENCODER_TMDS);
  668. if (ret) {
  669. dev_err(dev, "Failed to initialize decoder: %d\n", ret);
  670. return ret;
  671. }
  672. dpi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->dev);
  673. ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL,
  674. DRM_BRIDGE_ATTACH_NO_CONNECTOR);
  675. if (ret)
  676. goto err_cleanup;
  677. dpi->connector = drm_bridge_connector_init(drm_dev, &dpi->encoder);
  678. if (IS_ERR(dpi->connector)) {
  679. dev_err(dev, "Unable to create bridge connector\n");
  680. ret = PTR_ERR(dpi->connector);
  681. goto err_cleanup;
  682. }
  683. drm_connector_attach_encoder(dpi->connector, &dpi->encoder);
  684. return 0;
  685. err_cleanup:
  686. drm_encoder_cleanup(&dpi->encoder);
  687. return ret;
  688. }
  689. static void mtk_dpi_unbind(struct device *dev, struct device *master,
  690. void *data)
  691. {
  692. struct mtk_dpi *dpi = dev_get_drvdata(dev);
  693. drm_encoder_cleanup(&dpi->encoder);
  694. }
  695. static const struct component_ops mtk_dpi_component_ops = {
  696. .bind = mtk_dpi_bind,
  697. .unbind = mtk_dpi_unbind,
  698. };
  699. static unsigned int mt8173_calculate_factor(int clock)
  700. {
  701. if (clock <= 27000)
  702. return 3 << 4;
  703. else if (clock <= 84000)
  704. return 3 << 3;
  705. else if (clock <= 167000)
  706. return 3 << 2;
  707. else
  708. return 3 << 1;
  709. }
  710. static unsigned int mt2701_calculate_factor(int clock)
  711. {
  712. if (clock <= 64000)
  713. return 4;
  714. else if (clock <= 128000)
  715. return 2;
  716. else
  717. return 1;
  718. }
  719. static unsigned int mt8183_calculate_factor(int clock)
  720. {
  721. if (clock <= 27000)
  722. return 8;
  723. else if (clock <= 167000)
  724. return 4;
  725. else
  726. return 2;
  727. }
  728. static unsigned int mt8195_dpintf_calculate_factor(int clock)
  729. {
  730. if (clock < 70000)
  731. return 4;
  732. else if (clock < 200000)
  733. return 2;
  734. else
  735. return 1;
  736. }
  737. static const u32 mt8173_output_fmts[] = {
  738. MEDIA_BUS_FMT_RGB888_1X24,
  739. };
  740. static const u32 mt8183_output_fmts[] = {
  741. MEDIA_BUS_FMT_RGB888_2X12_LE,
  742. MEDIA_BUS_FMT_RGB888_2X12_BE,
  743. };
  744. static const u32 mt8195_output_fmts[] = {
  745. MEDIA_BUS_FMT_RGB888_1X24,
  746. MEDIA_BUS_FMT_YUYV8_1X16,
  747. };
  748. static const struct mtk_dpi_conf mt8173_conf = {
  749. .cal_factor = mt8173_calculate_factor,
  750. .reg_h_fre_con = 0xe0,
  751. .max_clock_khz = 300000,
  752. .output_fmts = mt8173_output_fmts,
  753. .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
  754. .pixels_per_iter = 1,
  755. .is_ck_de_pol = true,
  756. .swap_input_support = true,
  757. .support_direct_pin = true,
  758. .dimension_mask = HPW_MASK,
  759. .hvsize_mask = HSIZE_MASK,
  760. .channel_swap_shift = CH_SWAP,
  761. .yuv422_en_bit = YUV422_EN,
  762. .csc_enable_bit = CSC_ENABLE,
  763. };
  764. static const struct mtk_dpi_conf mt2701_conf = {
  765. .cal_factor = mt2701_calculate_factor,
  766. .reg_h_fre_con = 0xb0,
  767. .edge_sel_en = true,
  768. .max_clock_khz = 150000,
  769. .output_fmts = mt8173_output_fmts,
  770. .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
  771. .pixels_per_iter = 1,
  772. .is_ck_de_pol = true,
  773. .swap_input_support = true,
  774. .support_direct_pin = true,
  775. .dimension_mask = HPW_MASK,
  776. .hvsize_mask = HSIZE_MASK,
  777. .channel_swap_shift = CH_SWAP,
  778. .yuv422_en_bit = YUV422_EN,
  779. .csc_enable_bit = CSC_ENABLE,
  780. };
  781. static const struct mtk_dpi_conf mt8183_conf = {
  782. .cal_factor = mt8183_calculate_factor,
  783. .reg_h_fre_con = 0xe0,
  784. .max_clock_khz = 100000,
  785. .output_fmts = mt8183_output_fmts,
  786. .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
  787. .pixels_per_iter = 1,
  788. .is_ck_de_pol = true,
  789. .swap_input_support = true,
  790. .support_direct_pin = true,
  791. .dimension_mask = HPW_MASK,
  792. .hvsize_mask = HSIZE_MASK,
  793. .channel_swap_shift = CH_SWAP,
  794. .yuv422_en_bit = YUV422_EN,
  795. .csc_enable_bit = CSC_ENABLE,
  796. };
  797. static const struct mtk_dpi_conf mt8192_conf = {
  798. .cal_factor = mt8183_calculate_factor,
  799. .reg_h_fre_con = 0xe0,
  800. .max_clock_khz = 150000,
  801. .output_fmts = mt8183_output_fmts,
  802. .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
  803. .pixels_per_iter = 1,
  804. .is_ck_de_pol = true,
  805. .swap_input_support = true,
  806. .support_direct_pin = true,
  807. .dimension_mask = HPW_MASK,
  808. .hvsize_mask = HSIZE_MASK,
  809. .channel_swap_shift = CH_SWAP,
  810. .yuv422_en_bit = YUV422_EN,
  811. .csc_enable_bit = CSC_ENABLE,
  812. };
  813. static const struct mtk_dpi_conf mt8195_dpintf_conf = {
  814. .cal_factor = mt8195_dpintf_calculate_factor,
  815. .max_clock_khz = 600000,
  816. .output_fmts = mt8195_output_fmts,
  817. .num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
  818. .pixels_per_iter = 4,
  819. .input_2pixel = true,
  820. .dimension_mask = DPINTF_HPW_MASK,
  821. .hvsize_mask = DPINTF_HSIZE_MASK,
  822. .channel_swap_shift = DPINTF_CH_SWAP,
  823. .yuv422_en_bit = DPINTF_YUV422_EN,
  824. .csc_enable_bit = DPINTF_CSC_ENABLE,
  825. };
  826. static int mtk_dpi_probe(struct platform_device *pdev)
  827. {
  828. struct device *dev = &pdev->dev;
  829. struct mtk_dpi *dpi;
  830. struct resource *mem;
  831. int ret;
  832. dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
  833. if (!dpi)
  834. return -ENOMEM;
  835. dpi->dev = dev;
  836. dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev);
  837. dpi->output_fmt = MEDIA_BUS_FMT_RGB888_1X24;
  838. dpi->pinctrl = devm_pinctrl_get(&pdev->dev);
  839. if (IS_ERR(dpi->pinctrl)) {
  840. dpi->pinctrl = NULL;
  841. dev_dbg(&pdev->dev, "Cannot find pinctrl!\n");
  842. }
  843. if (dpi->pinctrl) {
  844. dpi->pins_gpio = pinctrl_lookup_state(dpi->pinctrl, "sleep");
  845. if (IS_ERR(dpi->pins_gpio)) {
  846. dpi->pins_gpio = NULL;
  847. dev_dbg(&pdev->dev, "Cannot find pinctrl idle!\n");
  848. }
  849. if (dpi->pins_gpio)
  850. pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
  851. dpi->pins_dpi = pinctrl_lookup_state(dpi->pinctrl, "default");
  852. if (IS_ERR(dpi->pins_dpi)) {
  853. dpi->pins_dpi = NULL;
  854. dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n");
  855. }
  856. }
  857. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  858. dpi->regs = devm_ioremap_resource(dev, mem);
  859. if (IS_ERR(dpi->regs)) {
  860. ret = PTR_ERR(dpi->regs);
  861. dev_err(dev, "Failed to ioremap mem resource: %d\n", ret);
  862. return ret;
  863. }
  864. dpi->engine_clk = devm_clk_get(dev, "engine");
  865. if (IS_ERR(dpi->engine_clk)) {
  866. ret = PTR_ERR(dpi->engine_clk);
  867. if (ret != -EPROBE_DEFER)
  868. dev_err(dev, "Failed to get engine clock: %d\n", ret);
  869. return ret;
  870. }
  871. dpi->pixel_clk = devm_clk_get(dev, "pixel");
  872. if (IS_ERR(dpi->pixel_clk)) {
  873. ret = PTR_ERR(dpi->pixel_clk);
  874. if (ret != -EPROBE_DEFER)
  875. dev_err(dev, "Failed to get pixel clock: %d\n", ret);
  876. return ret;
  877. }
  878. dpi->tvd_clk = devm_clk_get(dev, "pll");
  879. if (IS_ERR(dpi->tvd_clk)) {
  880. ret = PTR_ERR(dpi->tvd_clk);
  881. if (ret != -EPROBE_DEFER)
  882. dev_err(dev, "Failed to get tvdpll clock: %d\n", ret);
  883. return ret;
  884. }
  885. dpi->irq = platform_get_irq(pdev, 0);
  886. if (dpi->irq <= 0)
  887. return -EINVAL;
  888. ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
  889. NULL, &dpi->next_bridge);
  890. if (ret)
  891. return ret;
  892. dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node);
  893. platform_set_drvdata(pdev, dpi);
  894. dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
  895. dpi->bridge.of_node = dev->of_node;
  896. dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
  897. drm_bridge_add(&dpi->bridge);
  898. ret = component_add(dev, &mtk_dpi_component_ops);
  899. if (ret) {
  900. drm_bridge_remove(&dpi->bridge);
  901. dev_err(dev, "Failed to add component: %d\n", ret);
  902. return ret;
  903. }
  904. return 0;
  905. }
  906. static int mtk_dpi_remove(struct platform_device *pdev)
  907. {
  908. struct mtk_dpi *dpi = platform_get_drvdata(pdev);
  909. component_del(&pdev->dev, &mtk_dpi_component_ops);
  910. drm_bridge_remove(&dpi->bridge);
  911. return 0;
  912. }
  913. static const struct of_device_id mtk_dpi_of_ids[] = {
  914. { .compatible = "mediatek,mt2701-dpi",
  915. .data = &mt2701_conf,
  916. },
  917. { .compatible = "mediatek,mt8173-dpi",
  918. .data = &mt8173_conf,
  919. },
  920. { .compatible = "mediatek,mt8183-dpi",
  921. .data = &mt8183_conf,
  922. },
  923. { .compatible = "mediatek,mt8192-dpi",
  924. .data = &mt8192_conf,
  925. },
  926. { .compatible = "mediatek,mt8195-dp-intf",
  927. .data = &mt8195_dpintf_conf,
  928. },
  929. { },
  930. };
  931. MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
  932. struct platform_driver mtk_dpi_driver = {
  933. .probe = mtk_dpi_probe,
  934. .remove = mtk_dpi_remove,
  935. .driver = {
  936. .name = "mediatek-dpi",
  937. .of_match_table = mtk_dpi_of_ids,
  938. },
  939. };