1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2014 MediaTek Inc.
4 * Author: Jie Qiu <jie.qiu@mediatek.com>
8 #include <linux/component.h>
9 #include <linux/interrupt.h>
10 #include <linux/kernel.h>
12 #include <linux/of_device.h>
13 #include <linux/of_gpio.h>
14 #include <linux/of_graph.h>
15 #include <linux/pinctrl/consumer.h>
16 #include <linux/platform_device.h>
17 #include <linux/types.h>
19 #include <video/videomode.h>
21 #include <drm/drm_atomic_helper.h>
22 #include <drm/drm_bridge.h>
23 #include <drm/drm_crtc.h>
24 #include <drm/drm_of.h>
25 #include <drm/drm_simple_kms_helper.h>
27 #include "mtk_dpi_regs.h"
28 #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
37 enum mtk_dpi_out_yc_map
{
38 MTK_DPI_OUT_YC_MAP_RGB
,
39 MTK_DPI_OUT_YC_MAP_CYCY
,
40 MTK_DPI_OUT_YC_MAP_YCYC
,
41 MTK_DPI_OUT_YC_MAP_CY
,
45 enum mtk_dpi_out_channel_swap
{
46 MTK_DPI_OUT_CHANNEL_SWAP_RGB
,
47 MTK_DPI_OUT_CHANNEL_SWAP_GBR
,
48 MTK_DPI_OUT_CHANNEL_SWAP_BRG
,
49 MTK_DPI_OUT_CHANNEL_SWAP_RBG
,
50 MTK_DPI_OUT_CHANNEL_SWAP_GRB
,
51 MTK_DPI_OUT_CHANNEL_SWAP_BGR
54 enum mtk_dpi_out_color_format
{
55 MTK_DPI_COLOR_FORMAT_RGB
,
56 MTK_DPI_COLOR_FORMAT_RGB_FULL
,
57 MTK_DPI_COLOR_FORMAT_YCBCR_444
,
58 MTK_DPI_COLOR_FORMAT_YCBCR_422
,
59 MTK_DPI_COLOR_FORMAT_XV_YCC
,
60 MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL
,
61 MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
65 struct mtk_ddp_comp ddp_comp
;
66 struct drm_encoder encoder
;
67 struct drm_bridge bridge
;
68 struct drm_bridge
*next_bridge
;
71 struct clk
*engine_clk
;
72 struct clk
*pixel_clk
;
75 struct drm_display_mode mode
;
76 const struct mtk_dpi_conf
*conf
;
77 enum mtk_dpi_out_color_format color_format
;
78 enum mtk_dpi_out_yc_map yc_map
;
79 enum mtk_dpi_out_bit_num bit_num
;
80 enum mtk_dpi_out_channel_swap channel_swap
;
81 struct pinctrl
*pinctrl
;
82 struct pinctrl_state
*pins_gpio
;
83 struct pinctrl_state
*pins_dpi
;
87 static inline struct mtk_dpi
*bridge_to_dpi(struct drm_bridge
*b
)
89 return container_of(b
, struct mtk_dpi
, bridge
);
92 enum mtk_dpi_polarity
{
93 MTK_DPI_POLARITY_RISING
,
94 MTK_DPI_POLARITY_FALLING
,
97 struct mtk_dpi_polarities
{
98 enum mtk_dpi_polarity de_pol
;
99 enum mtk_dpi_polarity ck_pol
;
100 enum mtk_dpi_polarity hsync_pol
;
101 enum mtk_dpi_polarity vsync_pol
;
104 struct mtk_dpi_sync_param
{
108 bool shift_half_line
;
111 struct mtk_dpi_yc_limit
{
118 struct mtk_dpi_conf
{
119 unsigned int (*cal_factor
)(int clock
);
124 static void mtk_dpi_mask(struct mtk_dpi
*dpi
, u32 offset
, u32 val
, u32 mask
)
126 u32 tmp
= readl(dpi
->regs
+ offset
) & ~mask
;
129 writel(tmp
, dpi
->regs
+ offset
);
132 static void mtk_dpi_sw_reset(struct mtk_dpi
*dpi
, bool reset
)
134 mtk_dpi_mask(dpi
, DPI_RET
, reset
? RST
: 0, RST
);
137 static void mtk_dpi_enable(struct mtk_dpi
*dpi
)
139 mtk_dpi_mask(dpi
, DPI_EN
, EN
, EN
);
142 static void mtk_dpi_disable(struct mtk_dpi
*dpi
)
144 mtk_dpi_mask(dpi
, DPI_EN
, 0, EN
);
147 static void mtk_dpi_config_hsync(struct mtk_dpi
*dpi
,
148 struct mtk_dpi_sync_param
*sync
)
150 mtk_dpi_mask(dpi
, DPI_TGEN_HWIDTH
,
151 sync
->sync_width
<< HPW
, HPW_MASK
);
152 mtk_dpi_mask(dpi
, DPI_TGEN_HPORCH
,
153 sync
->back_porch
<< HBP
, HBP_MASK
);
154 mtk_dpi_mask(dpi
, DPI_TGEN_HPORCH
, sync
->front_porch
<< HFP
,
158 static void mtk_dpi_config_vsync(struct mtk_dpi
*dpi
,
159 struct mtk_dpi_sync_param
*sync
,
160 u32 width_addr
, u32 porch_addr
)
162 mtk_dpi_mask(dpi
, width_addr
,
163 sync
->sync_width
<< VSYNC_WIDTH_SHIFT
,
165 mtk_dpi_mask(dpi
, width_addr
,
166 sync
->shift_half_line
<< VSYNC_HALF_LINE_SHIFT
,
167 VSYNC_HALF_LINE_MASK
);
168 mtk_dpi_mask(dpi
, porch_addr
,
169 sync
->back_porch
<< VSYNC_BACK_PORCH_SHIFT
,
170 VSYNC_BACK_PORCH_MASK
);
171 mtk_dpi_mask(dpi
, porch_addr
,
172 sync
->front_porch
<< VSYNC_FRONT_PORCH_SHIFT
,
173 VSYNC_FRONT_PORCH_MASK
);
176 static void mtk_dpi_config_vsync_lodd(struct mtk_dpi
*dpi
,
177 struct mtk_dpi_sync_param
*sync
)
179 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH
, DPI_TGEN_VPORCH
);
182 static void mtk_dpi_config_vsync_leven(struct mtk_dpi
*dpi
,
183 struct mtk_dpi_sync_param
*sync
)
185 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH_LEVEN
,
186 DPI_TGEN_VPORCH_LEVEN
);
189 static void mtk_dpi_config_vsync_rodd(struct mtk_dpi
*dpi
,
190 struct mtk_dpi_sync_param
*sync
)
192 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH_RODD
,
193 DPI_TGEN_VPORCH_RODD
);
196 static void mtk_dpi_config_vsync_reven(struct mtk_dpi
*dpi
,
197 struct mtk_dpi_sync_param
*sync
)
199 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH_REVEN
,
200 DPI_TGEN_VPORCH_REVEN
);
203 static void mtk_dpi_config_pol(struct mtk_dpi
*dpi
,
204 struct mtk_dpi_polarities
*dpi_pol
)
208 pol
= (dpi_pol
->ck_pol
== MTK_DPI_POLARITY_RISING
? 0 : CK_POL
) |
209 (dpi_pol
->de_pol
== MTK_DPI_POLARITY_RISING
? 0 : DE_POL
) |
210 (dpi_pol
->hsync_pol
== MTK_DPI_POLARITY_RISING
? 0 : HSYNC_POL
) |
211 (dpi_pol
->vsync_pol
== MTK_DPI_POLARITY_RISING
? 0 : VSYNC_POL
);
212 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, pol
,
213 CK_POL
| DE_POL
| HSYNC_POL
| VSYNC_POL
);
216 static void mtk_dpi_config_3d(struct mtk_dpi
*dpi
, bool en_3d
)
218 mtk_dpi_mask(dpi
, DPI_CON
, en_3d
? TDFP_EN
: 0, TDFP_EN
);
221 static void mtk_dpi_config_interface(struct mtk_dpi
*dpi
, bool inter
)
223 mtk_dpi_mask(dpi
, DPI_CON
, inter
? INTL_EN
: 0, INTL_EN
);
226 static void mtk_dpi_config_fb_size(struct mtk_dpi
*dpi
, u32 width
, u32 height
)
228 mtk_dpi_mask(dpi
, DPI_SIZE
, width
<< HSIZE
, HSIZE_MASK
);
229 mtk_dpi_mask(dpi
, DPI_SIZE
, height
<< VSIZE
, VSIZE_MASK
);
232 static void mtk_dpi_config_channel_limit(struct mtk_dpi
*dpi
,
233 struct mtk_dpi_yc_limit
*limit
)
235 mtk_dpi_mask(dpi
, DPI_Y_LIMIT
, limit
->y_bottom
<< Y_LIMINT_BOT
,
237 mtk_dpi_mask(dpi
, DPI_Y_LIMIT
, limit
->y_top
<< Y_LIMINT_TOP
,
239 mtk_dpi_mask(dpi
, DPI_C_LIMIT
, limit
->c_bottom
<< C_LIMIT_BOT
,
241 mtk_dpi_mask(dpi
, DPI_C_LIMIT
, limit
->c_top
<< C_LIMIT_TOP
,
245 static void mtk_dpi_config_bit_num(struct mtk_dpi
*dpi
,
246 enum mtk_dpi_out_bit_num num
)
251 case MTK_DPI_OUT_BIT_NUM_8BITS
:
254 case MTK_DPI_OUT_BIT_NUM_10BITS
:
257 case MTK_DPI_OUT_BIT_NUM_12BITS
:
260 case MTK_DPI_OUT_BIT_NUM_16BITS
:
267 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, val
<< OUT_BIT
,
271 static void mtk_dpi_config_yc_map(struct mtk_dpi
*dpi
,
272 enum mtk_dpi_out_yc_map map
)
277 case MTK_DPI_OUT_YC_MAP_RGB
:
280 case MTK_DPI_OUT_YC_MAP_CYCY
:
283 case MTK_DPI_OUT_YC_MAP_YCYC
:
286 case MTK_DPI_OUT_YC_MAP_CY
:
289 case MTK_DPI_OUT_YC_MAP_YC
:
297 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, val
<< YC_MAP
, YC_MAP_MASK
);
300 static void mtk_dpi_config_channel_swap(struct mtk_dpi
*dpi
,
301 enum mtk_dpi_out_channel_swap swap
)
306 case MTK_DPI_OUT_CHANNEL_SWAP_RGB
:
309 case MTK_DPI_OUT_CHANNEL_SWAP_GBR
:
312 case MTK_DPI_OUT_CHANNEL_SWAP_BRG
:
315 case MTK_DPI_OUT_CHANNEL_SWAP_RBG
:
318 case MTK_DPI_OUT_CHANNEL_SWAP_GRB
:
321 case MTK_DPI_OUT_CHANNEL_SWAP_BGR
:
329 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, val
<< CH_SWAP
, CH_SWAP_MASK
);
332 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi
*dpi
, bool enable
)
334 mtk_dpi_mask(dpi
, DPI_CON
, enable
? YUV422_EN
: 0, YUV422_EN
);
337 static void mtk_dpi_config_csc_enable(struct mtk_dpi
*dpi
, bool enable
)
339 mtk_dpi_mask(dpi
, DPI_CON
, enable
? CSC_ENABLE
: 0, CSC_ENABLE
);
342 static void mtk_dpi_config_swap_input(struct mtk_dpi
*dpi
, bool enable
)
344 mtk_dpi_mask(dpi
, DPI_CON
, enable
? IN_RB_SWAP
: 0, IN_RB_SWAP
);
347 static void mtk_dpi_config_2n_h_fre(struct mtk_dpi
*dpi
)
349 mtk_dpi_mask(dpi
, dpi
->conf
->reg_h_fre_con
, H_FRE_2N
, H_FRE_2N
);
352 static void mtk_dpi_config_disable_edge(struct mtk_dpi
*dpi
)
354 if (dpi
->conf
->edge_sel_en
)
355 mtk_dpi_mask(dpi
, dpi
->conf
->reg_h_fre_con
, 0, EDGE_SEL_EN
);
358 static void mtk_dpi_config_color_format(struct mtk_dpi
*dpi
,
359 enum mtk_dpi_out_color_format format
)
361 if ((format
== MTK_DPI_COLOR_FORMAT_YCBCR_444
) ||
362 (format
== MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL
)) {
363 mtk_dpi_config_yuv422_enable(dpi
, false);
364 mtk_dpi_config_csc_enable(dpi
, true);
365 mtk_dpi_config_swap_input(dpi
, false);
366 mtk_dpi_config_channel_swap(dpi
, MTK_DPI_OUT_CHANNEL_SWAP_BGR
);
367 } else if ((format
== MTK_DPI_COLOR_FORMAT_YCBCR_422
) ||
368 (format
== MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
)) {
369 mtk_dpi_config_yuv422_enable(dpi
, true);
370 mtk_dpi_config_csc_enable(dpi
, true);
371 mtk_dpi_config_swap_input(dpi
, true);
372 mtk_dpi_config_channel_swap(dpi
, MTK_DPI_OUT_CHANNEL_SWAP_RGB
);
374 mtk_dpi_config_yuv422_enable(dpi
, false);
375 mtk_dpi_config_csc_enable(dpi
, false);
376 mtk_dpi_config_swap_input(dpi
, false);
377 mtk_dpi_config_channel_swap(dpi
, MTK_DPI_OUT_CHANNEL_SWAP_RGB
);
381 static void mtk_dpi_power_off(struct mtk_dpi
*dpi
)
383 if (WARN_ON(dpi
->refcount
== 0))
386 if (--dpi
->refcount
!= 0)
389 if (dpi
->pinctrl
&& dpi
->pins_gpio
)
390 pinctrl_select_state(dpi
->pinctrl
, dpi
->pins_gpio
);
392 mtk_dpi_disable(dpi
);
393 clk_disable_unprepare(dpi
->pixel_clk
);
394 clk_disable_unprepare(dpi
->engine_clk
);
397 static int mtk_dpi_power_on(struct mtk_dpi
*dpi
)
401 if (++dpi
->refcount
!= 1)
404 ret
= clk_prepare_enable(dpi
->engine_clk
);
406 dev_err(dpi
->dev
, "Failed to enable engine clock: %d\n", ret
);
410 ret
= clk_prepare_enable(dpi
->pixel_clk
);
412 dev_err(dpi
->dev
, "Failed to enable pixel clock: %d\n", ret
);
416 if (dpi
->pinctrl
&& dpi
->pins_dpi
)
417 pinctrl_select_state(dpi
->pinctrl
, dpi
->pins_dpi
);
423 clk_disable_unprepare(dpi
->engine_clk
);
429 static int mtk_dpi_set_display_mode(struct mtk_dpi
*dpi
,
430 struct drm_display_mode
*mode
)
432 struct mtk_dpi_yc_limit limit
;
433 struct mtk_dpi_polarities dpi_pol
;
434 struct mtk_dpi_sync_param hsync
;
435 struct mtk_dpi_sync_param vsync_lodd
= { 0 };
436 struct mtk_dpi_sync_param vsync_leven
= { 0 };
437 struct mtk_dpi_sync_param vsync_rodd
= { 0 };
438 struct mtk_dpi_sync_param vsync_reven
= { 0 };
439 struct videomode vm
= { 0 };
440 unsigned long pll_rate
;
443 /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
444 factor
= dpi
->conf
->cal_factor(mode
->clock
);
445 drm_display_mode_to_videomode(mode
, &vm
);
446 pll_rate
= vm
.pixelclock
* factor
;
448 dev_dbg(dpi
->dev
, "Want PLL %lu Hz, pixel clock %lu Hz\n",
449 pll_rate
, vm
.pixelclock
);
451 clk_set_rate(dpi
->tvd_clk
, pll_rate
);
452 pll_rate
= clk_get_rate(dpi
->tvd_clk
);
454 vm
.pixelclock
= pll_rate
/ factor
;
455 clk_set_rate(dpi
->pixel_clk
, vm
.pixelclock
);
456 vm
.pixelclock
= clk_get_rate(dpi
->pixel_clk
);
458 dev_dbg(dpi
->dev
, "Got PLL %lu Hz, pixel clock %lu Hz\n",
459 pll_rate
, vm
.pixelclock
);
461 limit
.c_bottom
= 0x0010;
462 limit
.c_top
= 0x0FE0;
463 limit
.y_bottom
= 0x0010;
464 limit
.y_top
= 0x0FE0;
466 dpi_pol
.ck_pol
= MTK_DPI_POLARITY_FALLING
;
467 dpi_pol
.de_pol
= MTK_DPI_POLARITY_RISING
;
468 dpi_pol
.hsync_pol
= vm
.flags
& DISPLAY_FLAGS_HSYNC_HIGH
?
469 MTK_DPI_POLARITY_FALLING
: MTK_DPI_POLARITY_RISING
;
470 dpi_pol
.vsync_pol
= vm
.flags
& DISPLAY_FLAGS_VSYNC_HIGH
?
471 MTK_DPI_POLARITY_FALLING
: MTK_DPI_POLARITY_RISING
;
472 hsync
.sync_width
= vm
.hsync_len
;
473 hsync
.back_porch
= vm
.hback_porch
;
474 hsync
.front_porch
= vm
.hfront_porch
;
475 hsync
.shift_half_line
= false;
476 vsync_lodd
.sync_width
= vm
.vsync_len
;
477 vsync_lodd
.back_porch
= vm
.vback_porch
;
478 vsync_lodd
.front_porch
= vm
.vfront_porch
;
479 vsync_lodd
.shift_half_line
= false;
481 if (vm
.flags
& DISPLAY_FLAGS_INTERLACED
&&
482 mode
->flags
& DRM_MODE_FLAG_3D_MASK
) {
483 vsync_leven
= vsync_lodd
;
484 vsync_rodd
= vsync_lodd
;
485 vsync_reven
= vsync_lodd
;
486 vsync_leven
.shift_half_line
= true;
487 vsync_reven
.shift_half_line
= true;
488 } else if (vm
.flags
& DISPLAY_FLAGS_INTERLACED
&&
489 !(mode
->flags
& DRM_MODE_FLAG_3D_MASK
)) {
490 vsync_leven
= vsync_lodd
;
491 vsync_leven
.shift_half_line
= true;
492 } else if (!(vm
.flags
& DISPLAY_FLAGS_INTERLACED
) &&
493 mode
->flags
& DRM_MODE_FLAG_3D_MASK
) {
494 vsync_rodd
= vsync_lodd
;
496 mtk_dpi_sw_reset(dpi
, true);
497 mtk_dpi_config_pol(dpi
, &dpi_pol
);
499 mtk_dpi_config_hsync(dpi
, &hsync
);
500 mtk_dpi_config_vsync_lodd(dpi
, &vsync_lodd
);
501 mtk_dpi_config_vsync_rodd(dpi
, &vsync_rodd
);
502 mtk_dpi_config_vsync_leven(dpi
, &vsync_leven
);
503 mtk_dpi_config_vsync_reven(dpi
, &vsync_reven
);
505 mtk_dpi_config_3d(dpi
, !!(mode
->flags
& DRM_MODE_FLAG_3D_MASK
));
506 mtk_dpi_config_interface(dpi
, !!(vm
.flags
&
507 DISPLAY_FLAGS_INTERLACED
));
508 if (vm
.flags
& DISPLAY_FLAGS_INTERLACED
)
509 mtk_dpi_config_fb_size(dpi
, vm
.hactive
, vm
.vactive
>> 1);
511 mtk_dpi_config_fb_size(dpi
, vm
.hactive
, vm
.vactive
);
513 mtk_dpi_config_channel_limit(dpi
, &limit
);
514 mtk_dpi_config_bit_num(dpi
, dpi
->bit_num
);
515 mtk_dpi_config_channel_swap(dpi
, dpi
->channel_swap
);
516 mtk_dpi_config_yc_map(dpi
, dpi
->yc_map
);
517 mtk_dpi_config_color_format(dpi
, dpi
->color_format
);
518 mtk_dpi_config_2n_h_fre(dpi
);
519 mtk_dpi_config_disable_edge(dpi
);
520 mtk_dpi_sw_reset(dpi
, false);
525 static int mtk_dpi_bridge_attach(struct drm_bridge
*bridge
,
526 enum drm_bridge_attach_flags flags
)
528 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
530 return drm_bridge_attach(bridge
->encoder
, dpi
->next_bridge
,
531 &dpi
->bridge
, flags
);
534 static void mtk_dpi_bridge_mode_set(struct drm_bridge
*bridge
,
535 const struct drm_display_mode
*mode
,
536 const struct drm_display_mode
*adjusted_mode
)
538 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
540 drm_mode_copy(&dpi
->mode
, adjusted_mode
);
543 static void mtk_dpi_bridge_disable(struct drm_bridge
*bridge
)
545 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
547 mtk_dpi_power_off(dpi
);
550 static void mtk_dpi_bridge_enable(struct drm_bridge
*bridge
)
552 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
554 mtk_dpi_power_on(dpi
);
555 mtk_dpi_set_display_mode(dpi
, &dpi
->mode
);
558 static const struct drm_bridge_funcs mtk_dpi_bridge_funcs
= {
559 .attach
= mtk_dpi_bridge_attach
,
560 .mode_set
= mtk_dpi_bridge_mode_set
,
561 .disable
= mtk_dpi_bridge_disable
,
562 .enable
= mtk_dpi_bridge_enable
,
565 static void mtk_dpi_start(struct mtk_ddp_comp
*comp
)
567 struct mtk_dpi
*dpi
= container_of(comp
, struct mtk_dpi
, ddp_comp
);
569 mtk_dpi_power_on(dpi
);
572 static void mtk_dpi_stop(struct mtk_ddp_comp
*comp
)
574 struct mtk_dpi
*dpi
= container_of(comp
, struct mtk_dpi
, ddp_comp
);
576 mtk_dpi_power_off(dpi
);
579 static const struct mtk_ddp_comp_funcs mtk_dpi_funcs
= {
580 .start
= mtk_dpi_start
,
581 .stop
= mtk_dpi_stop
,
584 static int mtk_dpi_bind(struct device
*dev
, struct device
*master
, void *data
)
586 struct mtk_dpi
*dpi
= dev_get_drvdata(dev
);
587 struct drm_device
*drm_dev
= data
;
590 ret
= mtk_ddp_comp_register(drm_dev
, &dpi
->ddp_comp
);
592 dev_err(dev
, "Failed to register component %pOF: %d\n",
597 ret
= drm_simple_encoder_init(drm_dev
, &dpi
->encoder
,
598 DRM_MODE_ENCODER_TMDS
);
600 dev_err(dev
, "Failed to initialize decoder: %d\n", ret
);
604 dpi
->encoder
.possible_crtcs
= mtk_drm_find_possible_crtc_by_comp(drm_dev
, dpi
->ddp_comp
);
606 ret
= drm_bridge_attach(&dpi
->encoder
, &dpi
->bridge
, NULL
, 0);
608 dev_err(dev
, "Failed to attach bridge: %d\n", ret
);
612 dpi
->bit_num
= MTK_DPI_OUT_BIT_NUM_8BITS
;
613 dpi
->channel_swap
= MTK_DPI_OUT_CHANNEL_SWAP_RGB
;
614 dpi
->yc_map
= MTK_DPI_OUT_YC_MAP_RGB
;
615 dpi
->color_format
= MTK_DPI_COLOR_FORMAT_RGB
;
620 drm_encoder_cleanup(&dpi
->encoder
);
622 mtk_ddp_comp_unregister(drm_dev
, &dpi
->ddp_comp
);
626 static void mtk_dpi_unbind(struct device
*dev
, struct device
*master
,
629 struct mtk_dpi
*dpi
= dev_get_drvdata(dev
);
630 struct drm_device
*drm_dev
= data
;
632 drm_encoder_cleanup(&dpi
->encoder
);
633 mtk_ddp_comp_unregister(drm_dev
, &dpi
->ddp_comp
);
636 static const struct component_ops mtk_dpi_component_ops
= {
637 .bind
= mtk_dpi_bind
,
638 .unbind
= mtk_dpi_unbind
,
641 static unsigned int mt8173_calculate_factor(int clock
)
645 else if (clock
<= 84000)
647 else if (clock
<= 167000)
653 static unsigned int mt2701_calculate_factor(int clock
)
657 else if (clock
<= 128000)
663 static unsigned int mt8183_calculate_factor(int clock
)
667 else if (clock
<= 167000)
673 static const struct mtk_dpi_conf mt8173_conf
= {
674 .cal_factor
= mt8173_calculate_factor
,
675 .reg_h_fre_con
= 0xe0,
678 static const struct mtk_dpi_conf mt2701_conf
= {
679 .cal_factor
= mt2701_calculate_factor
,
680 .reg_h_fre_con
= 0xb0,
684 static const struct mtk_dpi_conf mt8183_conf
= {
685 .cal_factor
= mt8183_calculate_factor
,
686 .reg_h_fre_con
= 0xe0,
689 static int mtk_dpi_probe(struct platform_device
*pdev
)
691 struct device
*dev
= &pdev
->dev
;
693 struct resource
*mem
;
697 dpi
= devm_kzalloc(dev
, sizeof(*dpi
), GFP_KERNEL
);
702 dpi
->conf
= (struct mtk_dpi_conf
*)of_device_get_match_data(dev
);
704 dpi
->pinctrl
= devm_pinctrl_get(&pdev
->dev
);
705 if (IS_ERR(dpi
->pinctrl
)) {
707 dev_dbg(&pdev
->dev
, "Cannot find pinctrl!\n");
710 dpi
->pins_gpio
= pinctrl_lookup_state(dpi
->pinctrl
, "sleep");
711 if (IS_ERR(dpi
->pins_gpio
)) {
712 dpi
->pins_gpio
= NULL
;
713 dev_dbg(&pdev
->dev
, "Cannot find pinctrl idle!\n");
716 pinctrl_select_state(dpi
->pinctrl
, dpi
->pins_gpio
);
718 dpi
->pins_dpi
= pinctrl_lookup_state(dpi
->pinctrl
, "default");
719 if (IS_ERR(dpi
->pins_dpi
)) {
720 dpi
->pins_dpi
= NULL
;
721 dev_dbg(&pdev
->dev
, "Cannot find pinctrl active!\n");
724 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
725 dpi
->regs
= devm_ioremap_resource(dev
, mem
);
726 if (IS_ERR(dpi
->regs
)) {
727 ret
= PTR_ERR(dpi
->regs
);
728 dev_err(dev
, "Failed to ioremap mem resource: %d\n", ret
);
732 dpi
->engine_clk
= devm_clk_get(dev
, "engine");
733 if (IS_ERR(dpi
->engine_clk
)) {
734 ret
= PTR_ERR(dpi
->engine_clk
);
735 if (ret
!= -EPROBE_DEFER
)
736 dev_err(dev
, "Failed to get engine clock: %d\n", ret
);
741 dpi
->pixel_clk
= devm_clk_get(dev
, "pixel");
742 if (IS_ERR(dpi
->pixel_clk
)) {
743 ret
= PTR_ERR(dpi
->pixel_clk
);
744 if (ret
!= -EPROBE_DEFER
)
745 dev_err(dev
, "Failed to get pixel clock: %d\n", ret
);
750 dpi
->tvd_clk
= devm_clk_get(dev
, "pll");
751 if (IS_ERR(dpi
->tvd_clk
)) {
752 ret
= PTR_ERR(dpi
->tvd_clk
);
753 if (ret
!= -EPROBE_DEFER
)
754 dev_err(dev
, "Failed to get tvdpll clock: %d\n", ret
);
759 dpi
->irq
= platform_get_irq(pdev
, 0);
761 dev_err(dev
, "Failed to get irq: %d\n", dpi
->irq
);
765 ret
= drm_of_find_panel_or_bridge(dev
->of_node
, 0, 0,
766 NULL
, &dpi
->next_bridge
);
770 dev_info(dev
, "Found bridge node: %pOF\n", dpi
->next_bridge
->of_node
);
772 comp_id
= mtk_ddp_comp_get_id(dev
->of_node
, MTK_DPI
);
774 dev_err(dev
, "Failed to identify by alias: %d\n", comp_id
);
778 ret
= mtk_ddp_comp_init(dev
, dev
->of_node
, &dpi
->ddp_comp
, comp_id
,
781 dev_err(dev
, "Failed to initialize component: %d\n", ret
);
785 platform_set_drvdata(pdev
, dpi
);
787 dpi
->bridge
.funcs
= &mtk_dpi_bridge_funcs
;
788 dpi
->bridge
.of_node
= dev
->of_node
;
789 dpi
->bridge
.type
= DRM_MODE_CONNECTOR_DPI
;
791 drm_bridge_add(&dpi
->bridge
);
793 ret
= component_add(dev
, &mtk_dpi_component_ops
);
795 drm_bridge_remove(&dpi
->bridge
);
796 dev_err(dev
, "Failed to add component: %d\n", ret
);
803 static int mtk_dpi_remove(struct platform_device
*pdev
)
805 struct mtk_dpi
*dpi
= platform_get_drvdata(pdev
);
807 component_del(&pdev
->dev
, &mtk_dpi_component_ops
);
808 drm_bridge_remove(&dpi
->bridge
);
813 static const struct of_device_id mtk_dpi_of_ids
[] = {
814 { .compatible
= "mediatek,mt2701-dpi",
815 .data
= &mt2701_conf
,
817 { .compatible
= "mediatek,mt8173-dpi",
818 .data
= &mt8173_conf
,
820 { .compatible
= "mediatek,mt8183-dpi",
821 .data
= &mt8183_conf
,
826 struct platform_driver mtk_dpi_driver
= {
827 .probe
= mtk_dpi_probe
,
828 .remove
= mtk_dpi_remove
,
830 .name
= "mediatek-dpi",
831 .of_match_table
= mtk_dpi_of_ids
,