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>
11 #include <linux/media-bus-format.h>
13 #include <linux/of_graph.h>
14 #include <linux/pinctrl/consumer.h>
15 #include <linux/platform_device.h>
16 #include <linux/soc/mediatek/mtk-mmsys.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_bridge_connector.h>
24 #include <drm/drm_crtc.h>
25 #include <drm/drm_edid.h>
26 #include <drm/drm_of.h>
27 #include <drm/drm_simple_kms_helper.h>
29 #include "mtk_ddp_comp.h"
30 #include "mtk_disp_drv.h"
31 #include "mtk_dpi_regs.h"
32 #include "mtk_drm_drv.h"
34 enum mtk_dpi_out_bit_num
{
35 MTK_DPI_OUT_BIT_NUM_8BITS
,
36 MTK_DPI_OUT_BIT_NUM_10BITS
,
37 MTK_DPI_OUT_BIT_NUM_12BITS
,
38 MTK_DPI_OUT_BIT_NUM_16BITS
41 enum mtk_dpi_out_yc_map
{
42 MTK_DPI_OUT_YC_MAP_RGB
,
43 MTK_DPI_OUT_YC_MAP_CYCY
,
44 MTK_DPI_OUT_YC_MAP_YCYC
,
45 MTK_DPI_OUT_YC_MAP_CY
,
49 enum mtk_dpi_out_channel_swap
{
50 MTK_DPI_OUT_CHANNEL_SWAP_RGB
,
51 MTK_DPI_OUT_CHANNEL_SWAP_GBR
,
52 MTK_DPI_OUT_CHANNEL_SWAP_BRG
,
53 MTK_DPI_OUT_CHANNEL_SWAP_RBG
,
54 MTK_DPI_OUT_CHANNEL_SWAP_GRB
,
55 MTK_DPI_OUT_CHANNEL_SWAP_BGR
58 enum mtk_dpi_out_color_format
{
59 MTK_DPI_COLOR_FORMAT_RGB
,
60 MTK_DPI_COLOR_FORMAT_YCBCR_422
64 struct drm_encoder encoder
;
65 struct drm_bridge bridge
;
66 struct drm_bridge
*next_bridge
;
67 struct drm_connector
*connector
;
70 struct device
*mmsys_dev
;
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
;
88 static inline struct mtk_dpi
*bridge_to_dpi(struct drm_bridge
*b
)
90 return container_of(b
, struct mtk_dpi
, bridge
);
93 enum mtk_dpi_polarity
{
94 MTK_DPI_POLARITY_RISING
,
95 MTK_DPI_POLARITY_FALLING
,
98 struct mtk_dpi_polarities
{
99 enum mtk_dpi_polarity de_pol
;
100 enum mtk_dpi_polarity ck_pol
;
101 enum mtk_dpi_polarity hsync_pol
;
102 enum mtk_dpi_polarity vsync_pol
;
105 struct mtk_dpi_sync_param
{
109 bool shift_half_line
;
112 struct mtk_dpi_yc_limit
{
120 * struct mtk_dpi_conf - Configuration of mediatek dpi.
121 * @cal_factor: Callback function to calculate factor value.
122 * @reg_h_fre_con: Register address of frequency control.
123 * @max_clock_khz: Max clock frequency supported for this SoCs in khz units.
124 * @edge_sel_en: Enable of edge selection.
125 * @output_fmts: Array of supported output formats.
126 * @num_output_fmts: Quantity of supported output formats.
127 * @is_ck_de_pol: Support CK/DE polarity.
128 * @swap_input_support: Support input swap function.
129 * @support_direct_pin: IP supports direct connection to dpi panels.
130 * @input_2pixel: Input pixel of dp_intf is 2 pixel per round, so enable this
131 * config to enable this feature.
132 * @dimension_mask: Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
134 * @hvsize_mask: Mask of HSIZE and VSIZE mask (no shift).
135 * @channel_swap_shift: Shift value of channel swap.
136 * @yuv422_en_bit: Enable bit of yuv422.
137 * @csc_enable_bit: Enable bit of CSC.
138 * @pixels_per_iter: Quantity of transferred pixels per iteration.
139 * @edge_cfg_in_mmsys: If the edge configuration for DPI's output needs to be set in MMSYS.
141 struct mtk_dpi_conf
{
142 unsigned int (*cal_factor
)(int clock
);
146 const u32
*output_fmts
;
149 bool swap_input_support
;
150 bool support_direct_pin
;
154 u32 channel_swap_shift
;
158 bool edge_cfg_in_mmsys
;
161 static void mtk_dpi_mask(struct mtk_dpi
*dpi
, u32 offset
, u32 val
, u32 mask
)
163 u32 tmp
= readl(dpi
->regs
+ offset
) & ~mask
;
166 writel(tmp
, dpi
->regs
+ offset
);
169 static void mtk_dpi_sw_reset(struct mtk_dpi
*dpi
, bool reset
)
171 mtk_dpi_mask(dpi
, DPI_RET
, reset
? RST
: 0, RST
);
174 static void mtk_dpi_enable(struct mtk_dpi
*dpi
)
176 mtk_dpi_mask(dpi
, DPI_EN
, EN
, EN
);
179 static void mtk_dpi_disable(struct mtk_dpi
*dpi
)
181 mtk_dpi_mask(dpi
, DPI_EN
, 0, EN
);
184 static void mtk_dpi_config_hsync(struct mtk_dpi
*dpi
,
185 struct mtk_dpi_sync_param
*sync
)
187 mtk_dpi_mask(dpi
, DPI_TGEN_HWIDTH
, sync
->sync_width
<< HPW
,
188 dpi
->conf
->dimension_mask
<< HPW
);
189 mtk_dpi_mask(dpi
, DPI_TGEN_HPORCH
, sync
->back_porch
<< HBP
,
190 dpi
->conf
->dimension_mask
<< HBP
);
191 mtk_dpi_mask(dpi
, DPI_TGEN_HPORCH
, sync
->front_porch
<< HFP
,
192 dpi
->conf
->dimension_mask
<< HFP
);
195 static void mtk_dpi_config_vsync(struct mtk_dpi
*dpi
,
196 struct mtk_dpi_sync_param
*sync
,
197 u32 width_addr
, u32 porch_addr
)
199 mtk_dpi_mask(dpi
, width_addr
,
200 sync
->shift_half_line
<< VSYNC_HALF_LINE_SHIFT
,
201 VSYNC_HALF_LINE_MASK
);
202 mtk_dpi_mask(dpi
, width_addr
,
203 sync
->sync_width
<< VSYNC_WIDTH_SHIFT
,
204 dpi
->conf
->dimension_mask
<< VSYNC_WIDTH_SHIFT
);
205 mtk_dpi_mask(dpi
, porch_addr
,
206 sync
->back_porch
<< VSYNC_BACK_PORCH_SHIFT
,
207 dpi
->conf
->dimension_mask
<< VSYNC_BACK_PORCH_SHIFT
);
208 mtk_dpi_mask(dpi
, porch_addr
,
209 sync
->front_porch
<< VSYNC_FRONT_PORCH_SHIFT
,
210 dpi
->conf
->dimension_mask
<< VSYNC_FRONT_PORCH_SHIFT
);
213 static void mtk_dpi_config_vsync_lodd(struct mtk_dpi
*dpi
,
214 struct mtk_dpi_sync_param
*sync
)
216 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH
, DPI_TGEN_VPORCH
);
219 static void mtk_dpi_config_vsync_leven(struct mtk_dpi
*dpi
,
220 struct mtk_dpi_sync_param
*sync
)
222 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH_LEVEN
,
223 DPI_TGEN_VPORCH_LEVEN
);
226 static void mtk_dpi_config_vsync_rodd(struct mtk_dpi
*dpi
,
227 struct mtk_dpi_sync_param
*sync
)
229 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH_RODD
,
230 DPI_TGEN_VPORCH_RODD
);
233 static void mtk_dpi_config_vsync_reven(struct mtk_dpi
*dpi
,
234 struct mtk_dpi_sync_param
*sync
)
236 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH_REVEN
,
237 DPI_TGEN_VPORCH_REVEN
);
240 static void mtk_dpi_config_pol(struct mtk_dpi
*dpi
,
241 struct mtk_dpi_polarities
*dpi_pol
)
246 mask
= HSYNC_POL
| VSYNC_POL
;
247 pol
= (dpi_pol
->hsync_pol
== MTK_DPI_POLARITY_RISING
? 0 : HSYNC_POL
) |
248 (dpi_pol
->vsync_pol
== MTK_DPI_POLARITY_RISING
? 0 : VSYNC_POL
);
249 if (dpi
->conf
->is_ck_de_pol
) {
250 mask
|= CK_POL
| DE_POL
;
251 pol
|= (dpi_pol
->ck_pol
== MTK_DPI_POLARITY_RISING
?
253 (dpi_pol
->de_pol
== MTK_DPI_POLARITY_RISING
?
257 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, pol
, mask
);
260 static void mtk_dpi_config_3d(struct mtk_dpi
*dpi
, bool en_3d
)
262 mtk_dpi_mask(dpi
, DPI_CON
, en_3d
? TDFP_EN
: 0, TDFP_EN
);
265 static void mtk_dpi_config_interface(struct mtk_dpi
*dpi
, bool inter
)
267 mtk_dpi_mask(dpi
, DPI_CON
, inter
? INTL_EN
: 0, INTL_EN
);
270 static void mtk_dpi_config_fb_size(struct mtk_dpi
*dpi
, u32 width
, u32 height
)
272 mtk_dpi_mask(dpi
, DPI_SIZE
, width
<< HSIZE
,
273 dpi
->conf
->hvsize_mask
<< HSIZE
);
274 mtk_dpi_mask(dpi
, DPI_SIZE
, height
<< VSIZE
,
275 dpi
->conf
->hvsize_mask
<< VSIZE
);
278 static void mtk_dpi_config_channel_limit(struct mtk_dpi
*dpi
)
280 struct mtk_dpi_yc_limit limit
;
282 if (drm_default_rgb_quant_range(&dpi
->mode
) ==
283 HDMI_QUANTIZATION_RANGE_LIMITED
) {
284 limit
.y_bottom
= 0x10;
286 limit
.c_bottom
= 0x10;
295 mtk_dpi_mask(dpi
, DPI_Y_LIMIT
, limit
.y_bottom
<< Y_LIMINT_BOT
,
297 mtk_dpi_mask(dpi
, DPI_Y_LIMIT
, limit
.y_top
<< Y_LIMINT_TOP
,
299 mtk_dpi_mask(dpi
, DPI_C_LIMIT
, limit
.c_bottom
<< C_LIMIT_BOT
,
301 mtk_dpi_mask(dpi
, DPI_C_LIMIT
, limit
.c_top
<< C_LIMIT_TOP
,
305 static void mtk_dpi_config_bit_num(struct mtk_dpi
*dpi
,
306 enum mtk_dpi_out_bit_num num
)
311 case MTK_DPI_OUT_BIT_NUM_8BITS
:
314 case MTK_DPI_OUT_BIT_NUM_10BITS
:
317 case MTK_DPI_OUT_BIT_NUM_12BITS
:
320 case MTK_DPI_OUT_BIT_NUM_16BITS
:
327 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, val
<< OUT_BIT
,
331 static void mtk_dpi_config_yc_map(struct mtk_dpi
*dpi
,
332 enum mtk_dpi_out_yc_map map
)
337 case MTK_DPI_OUT_YC_MAP_RGB
:
340 case MTK_DPI_OUT_YC_MAP_CYCY
:
343 case MTK_DPI_OUT_YC_MAP_YCYC
:
346 case MTK_DPI_OUT_YC_MAP_CY
:
349 case MTK_DPI_OUT_YC_MAP_YC
:
357 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, val
<< YC_MAP
, YC_MAP_MASK
);
360 static void mtk_dpi_config_channel_swap(struct mtk_dpi
*dpi
,
361 enum mtk_dpi_out_channel_swap swap
)
366 case MTK_DPI_OUT_CHANNEL_SWAP_RGB
:
369 case MTK_DPI_OUT_CHANNEL_SWAP_GBR
:
372 case MTK_DPI_OUT_CHANNEL_SWAP_BRG
:
375 case MTK_DPI_OUT_CHANNEL_SWAP_RBG
:
378 case MTK_DPI_OUT_CHANNEL_SWAP_GRB
:
381 case MTK_DPI_OUT_CHANNEL_SWAP_BGR
:
389 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
,
390 val
<< dpi
->conf
->channel_swap_shift
,
391 CH_SWAP_MASK
<< dpi
->conf
->channel_swap_shift
);
394 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi
*dpi
, bool enable
)
396 mtk_dpi_mask(dpi
, DPI_CON
, enable
? dpi
->conf
->yuv422_en_bit
: 0,
397 dpi
->conf
->yuv422_en_bit
);
400 static void mtk_dpi_config_csc_enable(struct mtk_dpi
*dpi
, bool enable
)
402 mtk_dpi_mask(dpi
, DPI_CON
, enable
? dpi
->conf
->csc_enable_bit
: 0,
403 dpi
->conf
->csc_enable_bit
);
406 static void mtk_dpi_config_swap_input(struct mtk_dpi
*dpi
, bool enable
)
408 mtk_dpi_mask(dpi
, DPI_CON
, enable
? IN_RB_SWAP
: 0, IN_RB_SWAP
);
411 static void mtk_dpi_config_2n_h_fre(struct mtk_dpi
*dpi
)
413 mtk_dpi_mask(dpi
, dpi
->conf
->reg_h_fre_con
, H_FRE_2N
, H_FRE_2N
);
416 static void mtk_dpi_config_disable_edge(struct mtk_dpi
*dpi
)
418 if (dpi
->conf
->edge_sel_en
)
419 mtk_dpi_mask(dpi
, dpi
->conf
->reg_h_fre_con
, 0, EDGE_SEL_EN
);
422 static void mtk_dpi_config_color_format(struct mtk_dpi
*dpi
,
423 enum mtk_dpi_out_color_format format
)
425 mtk_dpi_config_channel_swap(dpi
, MTK_DPI_OUT_CHANNEL_SWAP_RGB
);
427 if (format
== MTK_DPI_COLOR_FORMAT_YCBCR_422
) {
428 mtk_dpi_config_yuv422_enable(dpi
, true);
429 mtk_dpi_config_csc_enable(dpi
, true);
432 * If height is smaller than 720, we need to use RGB_TO_BT601
433 * to transfer to yuv422. Otherwise, we use RGB_TO_JPEG.
435 mtk_dpi_mask(dpi
, DPI_MATRIX_SET
, dpi
->mode
.hdisplay
<= 720 ?
436 MATRIX_SEL_RGB_TO_BT601
: MATRIX_SEL_RGB_TO_JPEG
,
437 INT_MATRIX_SEL_MASK
);
439 mtk_dpi_config_yuv422_enable(dpi
, false);
440 mtk_dpi_config_csc_enable(dpi
, false);
441 if (dpi
->conf
->swap_input_support
)
442 mtk_dpi_config_swap_input(dpi
, false);
446 static void mtk_dpi_dual_edge(struct mtk_dpi
*dpi
)
448 if ((dpi
->output_fmt
== MEDIA_BUS_FMT_RGB888_2X12_LE
) ||
449 (dpi
->output_fmt
== MEDIA_BUS_FMT_RGB888_2X12_BE
)) {
450 mtk_dpi_mask(dpi
, DPI_DDR_SETTING
, DDR_EN
| DDR_4PHASE
,
451 DDR_EN
| DDR_4PHASE
);
452 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
,
453 dpi
->output_fmt
== MEDIA_BUS_FMT_RGB888_2X12_LE
?
454 EDGE_SEL
: 0, EDGE_SEL
);
455 if (dpi
->conf
->edge_cfg_in_mmsys
)
456 mtk_mmsys_ddp_dpi_fmt_config(dpi
->mmsys_dev
, MTK_DPI_RGB888_DDR_CON
);
458 mtk_dpi_mask(dpi
, DPI_DDR_SETTING
, DDR_EN
| DDR_4PHASE
, 0);
459 if (dpi
->conf
->edge_cfg_in_mmsys
)
460 mtk_mmsys_ddp_dpi_fmt_config(dpi
->mmsys_dev
, MTK_DPI_RGB888_SDR_CON
);
464 static void mtk_dpi_power_off(struct mtk_dpi
*dpi
)
466 if (WARN_ON(dpi
->refcount
== 0))
469 if (--dpi
->refcount
!= 0)
472 mtk_dpi_disable(dpi
);
473 clk_disable_unprepare(dpi
->pixel_clk
);
474 clk_disable_unprepare(dpi
->engine_clk
);
477 static int mtk_dpi_power_on(struct mtk_dpi
*dpi
)
481 if (++dpi
->refcount
!= 1)
484 ret
= clk_prepare_enable(dpi
->engine_clk
);
486 dev_err(dpi
->dev
, "Failed to enable engine clock: %d\n", ret
);
490 ret
= clk_prepare_enable(dpi
->pixel_clk
);
492 dev_err(dpi
->dev
, "Failed to enable pixel clock: %d\n", ret
);
499 clk_disable_unprepare(dpi
->engine_clk
);
505 static int mtk_dpi_set_display_mode(struct mtk_dpi
*dpi
,
506 struct drm_display_mode
*mode
)
508 struct mtk_dpi_polarities dpi_pol
;
509 struct mtk_dpi_sync_param hsync
;
510 struct mtk_dpi_sync_param vsync_lodd
= { 0 };
511 struct mtk_dpi_sync_param vsync_leven
= { 0 };
512 struct mtk_dpi_sync_param vsync_rodd
= { 0 };
513 struct mtk_dpi_sync_param vsync_reven
= { 0 };
514 struct videomode vm
= { 0 };
515 unsigned long pll_rate
;
518 /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
519 factor
= dpi
->conf
->cal_factor(mode
->clock
);
520 drm_display_mode_to_videomode(mode
, &vm
);
521 pll_rate
= vm
.pixelclock
* factor
;
523 dev_dbg(dpi
->dev
, "Want PLL %lu Hz, pixel clock %lu Hz\n",
524 pll_rate
, vm
.pixelclock
);
526 clk_set_rate(dpi
->tvd_clk
, pll_rate
);
527 pll_rate
= clk_get_rate(dpi
->tvd_clk
);
530 * Depending on the IP version, we may output a different amount of
531 * pixels for each iteration: divide the clock by this number and
532 * adjust the display porches accordingly.
534 vm
.pixelclock
= pll_rate
/ factor
;
535 vm
.pixelclock
/= dpi
->conf
->pixels_per_iter
;
537 if ((dpi
->output_fmt
== MEDIA_BUS_FMT_RGB888_2X12_LE
) ||
538 (dpi
->output_fmt
== MEDIA_BUS_FMT_RGB888_2X12_BE
))
539 clk_set_rate(dpi
->pixel_clk
, vm
.pixelclock
* 2);
541 clk_set_rate(dpi
->pixel_clk
, vm
.pixelclock
);
544 vm
.pixelclock
= clk_get_rate(dpi
->pixel_clk
);
546 dev_dbg(dpi
->dev
, "Got PLL %lu Hz, pixel clock %lu Hz\n",
547 pll_rate
, vm
.pixelclock
);
549 dpi_pol
.ck_pol
= MTK_DPI_POLARITY_FALLING
;
550 dpi_pol
.de_pol
= MTK_DPI_POLARITY_RISING
;
551 dpi_pol
.hsync_pol
= vm
.flags
& DISPLAY_FLAGS_HSYNC_HIGH
?
552 MTK_DPI_POLARITY_FALLING
: MTK_DPI_POLARITY_RISING
;
553 dpi_pol
.vsync_pol
= vm
.flags
& DISPLAY_FLAGS_VSYNC_HIGH
?
554 MTK_DPI_POLARITY_FALLING
: MTK_DPI_POLARITY_RISING
;
557 * Depending on the IP version, we may output a different amount of
558 * pixels for each iteration: divide the clock by this number and
559 * adjust the display porches accordingly.
561 hsync
.sync_width
= vm
.hsync_len
/ dpi
->conf
->pixels_per_iter
;
562 hsync
.back_porch
= vm
.hback_porch
/ dpi
->conf
->pixels_per_iter
;
563 hsync
.front_porch
= vm
.hfront_porch
/ dpi
->conf
->pixels_per_iter
;
565 hsync
.shift_half_line
= false;
566 vsync_lodd
.sync_width
= vm
.vsync_len
;
567 vsync_lodd
.back_porch
= vm
.vback_porch
;
568 vsync_lodd
.front_porch
= vm
.vfront_porch
;
569 vsync_lodd
.shift_half_line
= false;
571 if (vm
.flags
& DISPLAY_FLAGS_INTERLACED
&&
572 mode
->flags
& DRM_MODE_FLAG_3D_MASK
) {
573 vsync_leven
= vsync_lodd
;
574 vsync_rodd
= vsync_lodd
;
575 vsync_reven
= vsync_lodd
;
576 vsync_leven
.shift_half_line
= true;
577 vsync_reven
.shift_half_line
= true;
578 } else if (vm
.flags
& DISPLAY_FLAGS_INTERLACED
&&
579 !(mode
->flags
& DRM_MODE_FLAG_3D_MASK
)) {
580 vsync_leven
= vsync_lodd
;
581 vsync_leven
.shift_half_line
= true;
582 } else if (!(vm
.flags
& DISPLAY_FLAGS_INTERLACED
) &&
583 mode
->flags
& DRM_MODE_FLAG_3D_MASK
) {
584 vsync_rodd
= vsync_lodd
;
586 mtk_dpi_sw_reset(dpi
, true);
587 mtk_dpi_config_pol(dpi
, &dpi_pol
);
589 mtk_dpi_config_hsync(dpi
, &hsync
);
590 mtk_dpi_config_vsync_lodd(dpi
, &vsync_lodd
);
591 mtk_dpi_config_vsync_rodd(dpi
, &vsync_rodd
);
592 mtk_dpi_config_vsync_leven(dpi
, &vsync_leven
);
593 mtk_dpi_config_vsync_reven(dpi
, &vsync_reven
);
595 mtk_dpi_config_3d(dpi
, !!(mode
->flags
& DRM_MODE_FLAG_3D_MASK
));
596 mtk_dpi_config_interface(dpi
, !!(vm
.flags
&
597 DISPLAY_FLAGS_INTERLACED
));
598 if (vm
.flags
& DISPLAY_FLAGS_INTERLACED
)
599 mtk_dpi_config_fb_size(dpi
, vm
.hactive
, vm
.vactive
>> 1);
601 mtk_dpi_config_fb_size(dpi
, vm
.hactive
, vm
.vactive
);
603 mtk_dpi_config_channel_limit(dpi
);
604 mtk_dpi_config_bit_num(dpi
, dpi
->bit_num
);
605 mtk_dpi_config_channel_swap(dpi
, dpi
->channel_swap
);
606 mtk_dpi_config_color_format(dpi
, dpi
->color_format
);
607 if (dpi
->conf
->support_direct_pin
) {
608 mtk_dpi_config_yc_map(dpi
, dpi
->yc_map
);
609 mtk_dpi_config_2n_h_fre(dpi
);
610 mtk_dpi_dual_edge(dpi
);
611 mtk_dpi_config_disable_edge(dpi
);
613 if (dpi
->conf
->input_2pixel
) {
614 mtk_dpi_mask(dpi
, DPI_CON
, DPINTF_INPUT_2P_EN
,
617 mtk_dpi_sw_reset(dpi
, false);
622 static u32
*mtk_dpi_bridge_atomic_get_output_bus_fmts(struct drm_bridge
*bridge
,
623 struct drm_bridge_state
*bridge_state
,
624 struct drm_crtc_state
*crtc_state
,
625 struct drm_connector_state
*conn_state
,
626 unsigned int *num_output_fmts
)
628 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
631 *num_output_fmts
= 0;
633 if (!dpi
->conf
->output_fmts
) {
634 dev_err(dpi
->dev
, "output_fmts should not be null\n");
638 output_fmts
= kcalloc(dpi
->conf
->num_output_fmts
, sizeof(*output_fmts
),
643 *num_output_fmts
= dpi
->conf
->num_output_fmts
;
645 memcpy(output_fmts
, dpi
->conf
->output_fmts
,
646 sizeof(*output_fmts
) * dpi
->conf
->num_output_fmts
);
651 static u32
*mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge
*bridge
,
652 struct drm_bridge_state
*bridge_state
,
653 struct drm_crtc_state
*crtc_state
,
654 struct drm_connector_state
*conn_state
,
656 unsigned int *num_input_fmts
)
662 input_fmts
= kcalloc(1, sizeof(*input_fmts
),
668 input_fmts
[0] = MEDIA_BUS_FMT_RGB888_1X24
;
673 static int mtk_dpi_bridge_atomic_check(struct drm_bridge
*bridge
,
674 struct drm_bridge_state
*bridge_state
,
675 struct drm_crtc_state
*crtc_state
,
676 struct drm_connector_state
*conn_state
)
678 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
679 unsigned int out_bus_format
;
681 out_bus_format
= bridge_state
->output_bus_cfg
.format
;
683 if (out_bus_format
== MEDIA_BUS_FMT_FIXED
)
684 if (dpi
->conf
->num_output_fmts
)
685 out_bus_format
= dpi
->conf
->output_fmts
[0];
687 dev_dbg(dpi
->dev
, "input format 0x%04x, output format 0x%04x\n",
688 bridge_state
->input_bus_cfg
.format
,
689 bridge_state
->output_bus_cfg
.format
);
691 dpi
->output_fmt
= out_bus_format
;
692 dpi
->bit_num
= MTK_DPI_OUT_BIT_NUM_8BITS
;
693 dpi
->channel_swap
= MTK_DPI_OUT_CHANNEL_SWAP_RGB
;
694 dpi
->yc_map
= MTK_DPI_OUT_YC_MAP_RGB
;
695 if (out_bus_format
== MEDIA_BUS_FMT_YUYV8_1X16
)
696 dpi
->color_format
= MTK_DPI_COLOR_FORMAT_YCBCR_422
;
698 dpi
->color_format
= MTK_DPI_COLOR_FORMAT_RGB
;
703 static int mtk_dpi_bridge_attach(struct drm_bridge
*bridge
,
704 enum drm_bridge_attach_flags flags
)
706 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
709 dpi
->next_bridge
= devm_drm_of_get_bridge(dpi
->dev
, dpi
->dev
->of_node
, 1, -1);
710 if (IS_ERR(dpi
->next_bridge
)) {
711 ret
= PTR_ERR(dpi
->next_bridge
);
712 if (ret
== -EPROBE_DEFER
)
715 /* Old devicetree has only one endpoint */
716 dpi
->next_bridge
= devm_drm_of_get_bridge(dpi
->dev
, dpi
->dev
->of_node
, 0, 0);
717 if (IS_ERR(dpi
->next_bridge
))
718 return dev_err_probe(dpi
->dev
, PTR_ERR(dpi
->next_bridge
),
719 "Failed to get bridge\n");
722 return drm_bridge_attach(bridge
->encoder
, dpi
->next_bridge
,
723 &dpi
->bridge
, flags
);
726 static void mtk_dpi_bridge_mode_set(struct drm_bridge
*bridge
,
727 const struct drm_display_mode
*mode
,
728 const struct drm_display_mode
*adjusted_mode
)
730 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
732 drm_mode_copy(&dpi
->mode
, adjusted_mode
);
735 static void mtk_dpi_bridge_disable(struct drm_bridge
*bridge
)
737 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
739 mtk_dpi_power_off(dpi
);
741 if (dpi
->pinctrl
&& dpi
->pins_gpio
)
742 pinctrl_select_state(dpi
->pinctrl
, dpi
->pins_gpio
);
745 static void mtk_dpi_bridge_enable(struct drm_bridge
*bridge
)
747 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
749 if (dpi
->pinctrl
&& dpi
->pins_dpi
)
750 pinctrl_select_state(dpi
->pinctrl
, dpi
->pins_dpi
);
752 mtk_dpi_power_on(dpi
);
753 mtk_dpi_set_display_mode(dpi
, &dpi
->mode
);
757 static enum drm_mode_status
758 mtk_dpi_bridge_mode_valid(struct drm_bridge
*bridge
,
759 const struct drm_display_info
*info
,
760 const struct drm_display_mode
*mode
)
762 struct mtk_dpi
*dpi
= bridge_to_dpi(bridge
);
764 if (mode
->clock
> dpi
->conf
->max_clock_khz
)
765 return MODE_CLOCK_HIGH
;
770 static const struct drm_bridge_funcs mtk_dpi_bridge_funcs
= {
771 .attach
= mtk_dpi_bridge_attach
,
772 .mode_set
= mtk_dpi_bridge_mode_set
,
773 .mode_valid
= mtk_dpi_bridge_mode_valid
,
774 .disable
= mtk_dpi_bridge_disable
,
775 .enable
= mtk_dpi_bridge_enable
,
776 .atomic_check
= mtk_dpi_bridge_atomic_check
,
777 .atomic_get_output_bus_fmts
= mtk_dpi_bridge_atomic_get_output_bus_fmts
,
778 .atomic_get_input_bus_fmts
= mtk_dpi_bridge_atomic_get_input_bus_fmts
,
779 .atomic_duplicate_state
= drm_atomic_helper_bridge_duplicate_state
,
780 .atomic_destroy_state
= drm_atomic_helper_bridge_destroy_state
,
781 .atomic_reset
= drm_atomic_helper_bridge_reset
,
784 void mtk_dpi_start(struct device
*dev
)
786 struct mtk_dpi
*dpi
= dev_get_drvdata(dev
);
788 mtk_dpi_power_on(dpi
);
791 void mtk_dpi_stop(struct device
*dev
)
793 struct mtk_dpi
*dpi
= dev_get_drvdata(dev
);
795 mtk_dpi_power_off(dpi
);
798 unsigned int mtk_dpi_encoder_index(struct device
*dev
)
800 struct mtk_dpi
*dpi
= dev_get_drvdata(dev
);
801 unsigned int encoder_index
= drm_encoder_index(&dpi
->encoder
);
803 dev_dbg(dev
, "encoder index:%d\n", encoder_index
);
804 return encoder_index
;
807 static int mtk_dpi_bind(struct device
*dev
, struct device
*master
, void *data
)
809 struct mtk_dpi
*dpi
= dev_get_drvdata(dev
);
810 struct drm_device
*drm_dev
= data
;
811 struct mtk_drm_private
*priv
= drm_dev
->dev_private
;
814 dpi
->mmsys_dev
= priv
->mmsys_dev
;
815 ret
= drm_simple_encoder_init(drm_dev
, &dpi
->encoder
,
816 DRM_MODE_ENCODER_TMDS
);
818 dev_err(dev
, "Failed to initialize decoder: %d\n", ret
);
822 ret
= mtk_find_possible_crtcs(drm_dev
, dpi
->dev
);
825 dpi
->encoder
.possible_crtcs
= ret
;
827 ret
= drm_bridge_attach(&dpi
->encoder
, &dpi
->bridge
, NULL
,
828 DRM_BRIDGE_ATTACH_NO_CONNECTOR
);
832 dpi
->connector
= drm_bridge_connector_init(drm_dev
, &dpi
->encoder
);
833 if (IS_ERR(dpi
->connector
)) {
834 dev_err(dev
, "Unable to create bridge connector\n");
835 ret
= PTR_ERR(dpi
->connector
);
838 drm_connector_attach_encoder(dpi
->connector
, &dpi
->encoder
);
843 drm_encoder_cleanup(&dpi
->encoder
);
847 static void mtk_dpi_unbind(struct device
*dev
, struct device
*master
,
850 struct mtk_dpi
*dpi
= dev_get_drvdata(dev
);
852 drm_encoder_cleanup(&dpi
->encoder
);
855 static const struct component_ops mtk_dpi_component_ops
= {
856 .bind
= mtk_dpi_bind
,
857 .unbind
= mtk_dpi_unbind
,
860 static unsigned int mt8173_calculate_factor(int clock
)
864 else if (clock
<= 84000)
866 else if (clock
<= 167000)
872 static unsigned int mt2701_calculate_factor(int clock
)
876 else if (clock
<= 128000)
882 static unsigned int mt8183_calculate_factor(int clock
)
886 else if (clock
<= 167000)
892 static unsigned int mt8195_dpintf_calculate_factor(int clock
)
896 else if (clock
< 200000)
902 static const u32 mt8173_output_fmts
[] = {
903 MEDIA_BUS_FMT_RGB888_1X24
,
906 static const u32 mt8183_output_fmts
[] = {
907 MEDIA_BUS_FMT_RGB888_2X12_LE
,
908 MEDIA_BUS_FMT_RGB888_2X12_BE
,
911 static const u32 mt8195_output_fmts
[] = {
912 MEDIA_BUS_FMT_RGB888_1X24
,
913 MEDIA_BUS_FMT_YUYV8_1X16
,
916 static const struct mtk_dpi_conf mt8173_conf
= {
917 .cal_factor
= mt8173_calculate_factor
,
918 .reg_h_fre_con
= 0xe0,
919 .max_clock_khz
= 300000,
920 .output_fmts
= mt8173_output_fmts
,
921 .num_output_fmts
= ARRAY_SIZE(mt8173_output_fmts
),
922 .pixels_per_iter
= 1,
923 .is_ck_de_pol
= true,
924 .swap_input_support
= true,
925 .support_direct_pin
= true,
926 .dimension_mask
= HPW_MASK
,
927 .hvsize_mask
= HSIZE_MASK
,
928 .channel_swap_shift
= CH_SWAP
,
929 .yuv422_en_bit
= YUV422_EN
,
930 .csc_enable_bit
= CSC_ENABLE
,
933 static const struct mtk_dpi_conf mt2701_conf
= {
934 .cal_factor
= mt2701_calculate_factor
,
935 .reg_h_fre_con
= 0xb0,
937 .max_clock_khz
= 150000,
938 .output_fmts
= mt8173_output_fmts
,
939 .num_output_fmts
= ARRAY_SIZE(mt8173_output_fmts
),
940 .pixels_per_iter
= 1,
941 .is_ck_de_pol
= true,
942 .swap_input_support
= true,
943 .support_direct_pin
= true,
944 .dimension_mask
= HPW_MASK
,
945 .hvsize_mask
= HSIZE_MASK
,
946 .channel_swap_shift
= CH_SWAP
,
947 .yuv422_en_bit
= YUV422_EN
,
948 .csc_enable_bit
= CSC_ENABLE
,
951 static const struct mtk_dpi_conf mt8183_conf
= {
952 .cal_factor
= mt8183_calculate_factor
,
953 .reg_h_fre_con
= 0xe0,
954 .max_clock_khz
= 100000,
955 .output_fmts
= mt8183_output_fmts
,
956 .num_output_fmts
= ARRAY_SIZE(mt8183_output_fmts
),
957 .pixels_per_iter
= 1,
958 .is_ck_de_pol
= true,
959 .swap_input_support
= true,
960 .support_direct_pin
= true,
961 .dimension_mask
= HPW_MASK
,
962 .hvsize_mask
= HSIZE_MASK
,
963 .channel_swap_shift
= CH_SWAP
,
964 .yuv422_en_bit
= YUV422_EN
,
965 .csc_enable_bit
= CSC_ENABLE
,
968 static const struct mtk_dpi_conf mt8186_conf
= {
969 .cal_factor
= mt8183_calculate_factor
,
970 .reg_h_fre_con
= 0xe0,
971 .max_clock_khz
= 150000,
972 .output_fmts
= mt8183_output_fmts
,
973 .num_output_fmts
= ARRAY_SIZE(mt8183_output_fmts
),
974 .edge_cfg_in_mmsys
= true,
975 .pixels_per_iter
= 1,
976 .is_ck_de_pol
= true,
977 .swap_input_support
= true,
978 .support_direct_pin
= true,
979 .dimension_mask
= HPW_MASK
,
980 .hvsize_mask
= HSIZE_MASK
,
981 .channel_swap_shift
= CH_SWAP
,
982 .yuv422_en_bit
= YUV422_EN
,
983 .csc_enable_bit
= CSC_ENABLE
,
986 static const struct mtk_dpi_conf mt8192_conf
= {
987 .cal_factor
= mt8183_calculate_factor
,
988 .reg_h_fre_con
= 0xe0,
989 .max_clock_khz
= 150000,
990 .output_fmts
= mt8183_output_fmts
,
991 .num_output_fmts
= ARRAY_SIZE(mt8183_output_fmts
),
992 .pixels_per_iter
= 1,
993 .is_ck_de_pol
= true,
994 .swap_input_support
= true,
995 .support_direct_pin
= true,
996 .dimension_mask
= HPW_MASK
,
997 .hvsize_mask
= HSIZE_MASK
,
998 .channel_swap_shift
= CH_SWAP
,
999 .yuv422_en_bit
= YUV422_EN
,
1000 .csc_enable_bit
= CSC_ENABLE
,
1003 static const struct mtk_dpi_conf mt8195_dpintf_conf
= {
1004 .cal_factor
= mt8195_dpintf_calculate_factor
,
1005 .max_clock_khz
= 600000,
1006 .output_fmts
= mt8195_output_fmts
,
1007 .num_output_fmts
= ARRAY_SIZE(mt8195_output_fmts
),
1008 .pixels_per_iter
= 4,
1009 .input_2pixel
= true,
1010 .dimension_mask
= DPINTF_HPW_MASK
,
1011 .hvsize_mask
= DPINTF_HSIZE_MASK
,
1012 .channel_swap_shift
= DPINTF_CH_SWAP
,
1013 .yuv422_en_bit
= DPINTF_YUV422_EN
,
1014 .csc_enable_bit
= DPINTF_CSC_ENABLE
,
1017 static int mtk_dpi_probe(struct platform_device
*pdev
)
1019 struct device
*dev
= &pdev
->dev
;
1020 struct mtk_dpi
*dpi
;
1023 dpi
= devm_kzalloc(dev
, sizeof(*dpi
), GFP_KERNEL
);
1028 dpi
->conf
= (struct mtk_dpi_conf
*)of_device_get_match_data(dev
);
1029 dpi
->output_fmt
= MEDIA_BUS_FMT_RGB888_1X24
;
1031 dpi
->pinctrl
= devm_pinctrl_get(&pdev
->dev
);
1032 if (IS_ERR(dpi
->pinctrl
)) {
1033 dpi
->pinctrl
= NULL
;
1034 dev_dbg(&pdev
->dev
, "Cannot find pinctrl!\n");
1037 dpi
->pins_gpio
= pinctrl_lookup_state(dpi
->pinctrl
, "sleep");
1038 if (IS_ERR(dpi
->pins_gpio
)) {
1039 dpi
->pins_gpio
= NULL
;
1040 dev_dbg(&pdev
->dev
, "Cannot find pinctrl idle!\n");
1043 pinctrl_select_state(dpi
->pinctrl
, dpi
->pins_gpio
);
1045 dpi
->pins_dpi
= pinctrl_lookup_state(dpi
->pinctrl
, "default");
1046 if (IS_ERR(dpi
->pins_dpi
)) {
1047 dpi
->pins_dpi
= NULL
;
1048 dev_dbg(&pdev
->dev
, "Cannot find pinctrl active!\n");
1051 dpi
->regs
= devm_platform_ioremap_resource(pdev
, 0);
1052 if (IS_ERR(dpi
->regs
))
1053 return dev_err_probe(dev
, PTR_ERR(dpi
->regs
),
1054 "Failed to ioremap mem resource\n");
1056 dpi
->engine_clk
= devm_clk_get(dev
, "engine");
1057 if (IS_ERR(dpi
->engine_clk
))
1058 return dev_err_probe(dev
, PTR_ERR(dpi
->engine_clk
),
1059 "Failed to get engine clock\n");
1061 dpi
->pixel_clk
= devm_clk_get(dev
, "pixel");
1062 if (IS_ERR(dpi
->pixel_clk
))
1063 return dev_err_probe(dev
, PTR_ERR(dpi
->pixel_clk
),
1064 "Failed to get pixel clock\n");
1066 dpi
->tvd_clk
= devm_clk_get(dev
, "pll");
1067 if (IS_ERR(dpi
->tvd_clk
))
1068 return dev_err_probe(dev
, PTR_ERR(dpi
->tvd_clk
),
1069 "Failed to get tvdpll clock\n");
1071 dpi
->irq
= platform_get_irq(pdev
, 0);
1075 platform_set_drvdata(pdev
, dpi
);
1077 dpi
->bridge
.funcs
= &mtk_dpi_bridge_funcs
;
1078 dpi
->bridge
.of_node
= dev
->of_node
;
1079 dpi
->bridge
.type
= DRM_MODE_CONNECTOR_DPI
;
1081 ret
= devm_drm_bridge_add(dev
, &dpi
->bridge
);
1085 ret
= component_add(dev
, &mtk_dpi_component_ops
);
1087 return dev_err_probe(dev
, ret
, "Failed to add component.\n");
1092 static void mtk_dpi_remove(struct platform_device
*pdev
)
1094 component_del(&pdev
->dev
, &mtk_dpi_component_ops
);
1097 static const struct of_device_id mtk_dpi_of_ids
[] = {
1098 { .compatible
= "mediatek,mt2701-dpi", .data
= &mt2701_conf
},
1099 { .compatible
= "mediatek,mt8173-dpi", .data
= &mt8173_conf
},
1100 { .compatible
= "mediatek,mt8183-dpi", .data
= &mt8183_conf
},
1101 { .compatible
= "mediatek,mt8186-dpi", .data
= &mt8186_conf
},
1102 { .compatible
= "mediatek,mt8188-dp-intf", .data
= &mt8195_dpintf_conf
},
1103 { .compatible
= "mediatek,mt8192-dpi", .data
= &mt8192_conf
},
1104 { .compatible
= "mediatek,mt8195-dp-intf", .data
= &mt8195_dpintf_conf
},
1107 MODULE_DEVICE_TABLE(of
, mtk_dpi_of_ids
);
1109 struct platform_driver mtk_dpi_driver
= {
1110 .probe
= mtk_dpi_probe
,
1111 .remove
= mtk_dpi_remove
,
1113 .name
= "mediatek-dpi",
1114 .of_match_table
= mtk_dpi_of_ids
,