2 * Copyright (c) 2014 MediaTek Inc.
3 * Author: Jie Qiu <jie.qiu@mediatek.com>
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.
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.
15 #include <drm/drm_crtc.h>
16 #include <drm/drm_crtc_helper.h>
17 #include <linux/kernel.h>
18 #include <linux/component.h>
19 #include <linux/platform_device.h>
21 #include <linux/of_graph.h>
22 #include <linux/interrupt.h>
23 #include <linux/types.h>
24 #include <linux/clk.h>
26 #include "mtk_dpi_regs.h"
27 #include "mtk_drm_ddp_comp.h"
29 enum mtk_dpi_out_bit_num
{
30 MTK_DPI_OUT_BIT_NUM_8BITS
,
31 MTK_DPI_OUT_BIT_NUM_10BITS
,
32 MTK_DPI_OUT_BIT_NUM_12BITS
,
33 MTK_DPI_OUT_BIT_NUM_16BITS
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
,
44 enum mtk_dpi_out_channel_swap
{
45 MTK_DPI_OUT_CHANNEL_SWAP_RGB
,
46 MTK_DPI_OUT_CHANNEL_SWAP_GBR
,
47 MTK_DPI_OUT_CHANNEL_SWAP_BRG
,
48 MTK_DPI_OUT_CHANNEL_SWAP_RBG
,
49 MTK_DPI_OUT_CHANNEL_SWAP_GRB
,
50 MTK_DPI_OUT_CHANNEL_SWAP_BGR
53 enum mtk_dpi_out_color_format
{
54 MTK_DPI_COLOR_FORMAT_RGB
,
55 MTK_DPI_COLOR_FORMAT_RGB_FULL
,
56 MTK_DPI_COLOR_FORMAT_YCBCR_444
,
57 MTK_DPI_COLOR_FORMAT_YCBCR_422
,
58 MTK_DPI_COLOR_FORMAT_XV_YCC
,
59 MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL
,
60 MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
64 struct mtk_ddp_comp ddp_comp
;
65 struct drm_encoder encoder
;
68 struct clk
*engine_clk
;
69 struct clk
*pixel_clk
;
72 struct drm_display_mode mode
;
73 enum mtk_dpi_out_color_format color_format
;
74 enum mtk_dpi_out_yc_map yc_map
;
75 enum mtk_dpi_out_bit_num bit_num
;
76 enum mtk_dpi_out_channel_swap channel_swap
;
81 static inline struct mtk_dpi
*mtk_dpi_from_encoder(struct drm_encoder
*e
)
83 return container_of(e
, struct mtk_dpi
, encoder
);
86 enum mtk_dpi_polarity
{
87 MTK_DPI_POLARITY_RISING
,
88 MTK_DPI_POLARITY_FALLING
,
91 enum mtk_dpi_power_ctl
{
92 DPI_POWER_START
= BIT(0),
93 DPI_POWER_ENABLE
= BIT(1),
96 struct mtk_dpi_polarities
{
97 enum mtk_dpi_polarity de_pol
;
98 enum mtk_dpi_polarity ck_pol
;
99 enum mtk_dpi_polarity hsync_pol
;
100 enum mtk_dpi_polarity vsync_pol
;
103 struct mtk_dpi_sync_param
{
107 bool shift_half_line
;
110 struct mtk_dpi_yc_limit
{
117 static void mtk_dpi_mask(struct mtk_dpi
*dpi
, u32 offset
, u32 val
, u32 mask
)
119 u32 tmp
= readl(dpi
->regs
+ offset
) & ~mask
;
122 writel(tmp
, dpi
->regs
+ offset
);
125 static void mtk_dpi_sw_reset(struct mtk_dpi
*dpi
, bool reset
)
127 mtk_dpi_mask(dpi
, DPI_RET
, reset
? RST
: 0, RST
);
130 static void mtk_dpi_enable(struct mtk_dpi
*dpi
)
132 mtk_dpi_mask(dpi
, DPI_EN
, EN
, EN
);
135 static void mtk_dpi_disable(struct mtk_dpi
*dpi
)
137 mtk_dpi_mask(dpi
, DPI_EN
, 0, EN
);
140 static void mtk_dpi_config_hsync(struct mtk_dpi
*dpi
,
141 struct mtk_dpi_sync_param
*sync
)
143 mtk_dpi_mask(dpi
, DPI_TGEN_HWIDTH
,
144 sync
->sync_width
<< HPW
, HPW_MASK
);
145 mtk_dpi_mask(dpi
, DPI_TGEN_HPORCH
,
146 sync
->back_porch
<< HBP
, HBP_MASK
);
147 mtk_dpi_mask(dpi
, DPI_TGEN_HPORCH
, sync
->front_porch
<< HFP
,
151 static void mtk_dpi_config_vsync(struct mtk_dpi
*dpi
,
152 struct mtk_dpi_sync_param
*sync
,
153 u32 width_addr
, u32 porch_addr
)
155 mtk_dpi_mask(dpi
, width_addr
,
156 sync
->sync_width
<< VSYNC_WIDTH_SHIFT
,
158 mtk_dpi_mask(dpi
, width_addr
,
159 sync
->shift_half_line
<< VSYNC_HALF_LINE_SHIFT
,
160 VSYNC_HALF_LINE_MASK
);
161 mtk_dpi_mask(dpi
, porch_addr
,
162 sync
->back_porch
<< VSYNC_BACK_PORCH_SHIFT
,
163 VSYNC_BACK_PORCH_MASK
);
164 mtk_dpi_mask(dpi
, porch_addr
,
165 sync
->front_porch
<< VSYNC_FRONT_PORCH_SHIFT
,
166 VSYNC_FRONT_PORCH_MASK
);
169 static void mtk_dpi_config_vsync_lodd(struct mtk_dpi
*dpi
,
170 struct mtk_dpi_sync_param
*sync
)
172 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH
, DPI_TGEN_VPORCH
);
175 static void mtk_dpi_config_vsync_leven(struct mtk_dpi
*dpi
,
176 struct mtk_dpi_sync_param
*sync
)
178 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH_LEVEN
,
179 DPI_TGEN_VPORCH_LEVEN
);
182 static void mtk_dpi_config_vsync_rodd(struct mtk_dpi
*dpi
,
183 struct mtk_dpi_sync_param
*sync
)
185 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH_RODD
,
186 DPI_TGEN_VPORCH_RODD
);
189 static void mtk_dpi_config_vsync_reven(struct mtk_dpi
*dpi
,
190 struct mtk_dpi_sync_param
*sync
)
192 mtk_dpi_config_vsync(dpi
, sync
, DPI_TGEN_VWIDTH_REVEN
,
193 DPI_TGEN_VPORCH_REVEN
);
196 static void mtk_dpi_config_pol(struct mtk_dpi
*dpi
,
197 struct mtk_dpi_polarities
*dpi_pol
)
201 pol
= (dpi_pol
->ck_pol
== MTK_DPI_POLARITY_RISING
? 0 : CK_POL
) |
202 (dpi_pol
->de_pol
== MTK_DPI_POLARITY_RISING
? 0 : DE_POL
) |
203 (dpi_pol
->hsync_pol
== MTK_DPI_POLARITY_RISING
? 0 : HSYNC_POL
) |
204 (dpi_pol
->vsync_pol
== MTK_DPI_POLARITY_RISING
? 0 : VSYNC_POL
);
205 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, pol
,
206 CK_POL
| DE_POL
| HSYNC_POL
| VSYNC_POL
);
209 static void mtk_dpi_config_3d(struct mtk_dpi
*dpi
, bool en_3d
)
211 mtk_dpi_mask(dpi
, DPI_CON
, en_3d
? TDFP_EN
: 0, TDFP_EN
);
214 static void mtk_dpi_config_interface(struct mtk_dpi
*dpi
, bool inter
)
216 mtk_dpi_mask(dpi
, DPI_CON
, inter
? INTL_EN
: 0, INTL_EN
);
219 static void mtk_dpi_config_fb_size(struct mtk_dpi
*dpi
, u32 width
, u32 height
)
221 mtk_dpi_mask(dpi
, DPI_SIZE
, width
<< HSIZE
, HSIZE_MASK
);
222 mtk_dpi_mask(dpi
, DPI_SIZE
, height
<< VSIZE
, VSIZE_MASK
);
225 static void mtk_dpi_config_channel_limit(struct mtk_dpi
*dpi
,
226 struct mtk_dpi_yc_limit
*limit
)
228 mtk_dpi_mask(dpi
, DPI_Y_LIMIT
, limit
->y_bottom
<< Y_LIMINT_BOT
,
230 mtk_dpi_mask(dpi
, DPI_Y_LIMIT
, limit
->y_top
<< Y_LIMINT_TOP
,
232 mtk_dpi_mask(dpi
, DPI_C_LIMIT
, limit
->c_bottom
<< C_LIMIT_BOT
,
234 mtk_dpi_mask(dpi
, DPI_C_LIMIT
, limit
->c_top
<< C_LIMIT_TOP
,
238 static void mtk_dpi_config_bit_num(struct mtk_dpi
*dpi
,
239 enum mtk_dpi_out_bit_num num
)
244 case MTK_DPI_OUT_BIT_NUM_8BITS
:
247 case MTK_DPI_OUT_BIT_NUM_10BITS
:
250 case MTK_DPI_OUT_BIT_NUM_12BITS
:
253 case MTK_DPI_OUT_BIT_NUM_16BITS
:
260 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, val
<< OUT_BIT
,
264 static void mtk_dpi_config_yc_map(struct mtk_dpi
*dpi
,
265 enum mtk_dpi_out_yc_map map
)
270 case MTK_DPI_OUT_YC_MAP_RGB
:
273 case MTK_DPI_OUT_YC_MAP_CYCY
:
276 case MTK_DPI_OUT_YC_MAP_YCYC
:
279 case MTK_DPI_OUT_YC_MAP_CY
:
282 case MTK_DPI_OUT_YC_MAP_YC
:
290 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, val
<< YC_MAP
, YC_MAP_MASK
);
293 static void mtk_dpi_config_channel_swap(struct mtk_dpi
*dpi
,
294 enum mtk_dpi_out_channel_swap swap
)
299 case MTK_DPI_OUT_CHANNEL_SWAP_RGB
:
302 case MTK_DPI_OUT_CHANNEL_SWAP_GBR
:
305 case MTK_DPI_OUT_CHANNEL_SWAP_BRG
:
308 case MTK_DPI_OUT_CHANNEL_SWAP_RBG
:
311 case MTK_DPI_OUT_CHANNEL_SWAP_GRB
:
314 case MTK_DPI_OUT_CHANNEL_SWAP_BGR
:
322 mtk_dpi_mask(dpi
, DPI_OUTPUT_SETTING
, val
<< CH_SWAP
, CH_SWAP_MASK
);
325 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi
*dpi
, bool enable
)
327 mtk_dpi_mask(dpi
, DPI_CON
, enable
? YUV422_EN
: 0, YUV422_EN
);
330 static void mtk_dpi_config_csc_enable(struct mtk_dpi
*dpi
, bool enable
)
332 mtk_dpi_mask(dpi
, DPI_CON
, enable
? CSC_ENABLE
: 0, CSC_ENABLE
);
335 static void mtk_dpi_config_swap_input(struct mtk_dpi
*dpi
, bool enable
)
337 mtk_dpi_mask(dpi
, DPI_CON
, enable
? IN_RB_SWAP
: 0, IN_RB_SWAP
);
340 static void mtk_dpi_config_2n_h_fre(struct mtk_dpi
*dpi
)
342 mtk_dpi_mask(dpi
, DPI_H_FRE_CON
, H_FRE_2N
, H_FRE_2N
);
345 static void mtk_dpi_config_color_format(struct mtk_dpi
*dpi
,
346 enum mtk_dpi_out_color_format format
)
348 if ((format
== MTK_DPI_COLOR_FORMAT_YCBCR_444
) ||
349 (format
== MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL
)) {
350 mtk_dpi_config_yuv422_enable(dpi
, false);
351 mtk_dpi_config_csc_enable(dpi
, true);
352 mtk_dpi_config_swap_input(dpi
, false);
353 mtk_dpi_config_channel_swap(dpi
, MTK_DPI_OUT_CHANNEL_SWAP_BGR
);
354 } else if ((format
== MTK_DPI_COLOR_FORMAT_YCBCR_422
) ||
355 (format
== MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
)) {
356 mtk_dpi_config_yuv422_enable(dpi
, true);
357 mtk_dpi_config_csc_enable(dpi
, true);
358 mtk_dpi_config_swap_input(dpi
, true);
359 mtk_dpi_config_channel_swap(dpi
, MTK_DPI_OUT_CHANNEL_SWAP_RGB
);
361 mtk_dpi_config_yuv422_enable(dpi
, false);
362 mtk_dpi_config_csc_enable(dpi
, false);
363 mtk_dpi_config_swap_input(dpi
, false);
364 mtk_dpi_config_channel_swap(dpi
, MTK_DPI_OUT_CHANNEL_SWAP_RGB
);
368 static void mtk_dpi_power_off(struct mtk_dpi
*dpi
, enum mtk_dpi_power_ctl pctl
)
370 dpi
->power_ctl
&= ~pctl
;
372 if ((dpi
->power_ctl
& DPI_POWER_START
) ||
373 (dpi
->power_ctl
& DPI_POWER_ENABLE
))
379 mtk_dpi_disable(dpi
);
380 clk_disable_unprepare(dpi
->pixel_clk
);
381 clk_disable_unprepare(dpi
->engine_clk
);
382 dpi
->power_sta
= false;
385 static int mtk_dpi_power_on(struct mtk_dpi
*dpi
, enum mtk_dpi_power_ctl pctl
)
389 dpi
->power_ctl
|= pctl
;
391 if (!(dpi
->power_ctl
& DPI_POWER_START
) &&
392 !(dpi
->power_ctl
& DPI_POWER_ENABLE
))
398 ret
= clk_prepare_enable(dpi
->engine_clk
);
400 dev_err(dpi
->dev
, "Failed to enable engine clock: %d\n", ret
);
404 ret
= clk_prepare_enable(dpi
->pixel_clk
);
406 dev_err(dpi
->dev
, "Failed to enable pixel clock: %d\n", ret
);
411 dpi
->power_sta
= true;
415 clk_disable_unprepare(dpi
->engine_clk
);
417 dpi
->power_ctl
&= ~pctl
;
421 static int mtk_dpi_set_display_mode(struct mtk_dpi
*dpi
,
422 struct drm_display_mode
*mode
)
424 struct mtk_dpi_yc_limit limit
;
425 struct mtk_dpi_polarities dpi_pol
;
426 struct mtk_dpi_sync_param hsync
;
427 struct mtk_dpi_sync_param vsync_lodd
= { 0 };
428 struct mtk_dpi_sync_param vsync_leven
= { 0 };
429 struct mtk_dpi_sync_param vsync_rodd
= { 0 };
430 struct mtk_dpi_sync_param vsync_reven
= { 0 };
431 unsigned long pix_rate
;
432 unsigned long pll_rate
;
435 /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
436 pix_rate
= 1000UL * mode
->clock
;
437 if (mode
->clock
<= 27000)
439 else if (mode
->clock
<= 84000)
441 else if (mode
->clock
<= 167000)
445 pll_rate
= pix_rate
* factor
;
447 dev_dbg(dpi
->dev
, "Want PLL %lu Hz, pixel clock %lu Hz\n",
450 clk_set_rate(dpi
->tvd_clk
, pll_rate
);
451 pll_rate
= clk_get_rate(dpi
->tvd_clk
);
453 pix_rate
= pll_rate
/ factor
;
454 clk_set_rate(dpi
->pixel_clk
, pix_rate
);
455 pix_rate
= clk_get_rate(dpi
->pixel_clk
);
457 dev_dbg(dpi
->dev
, "Got PLL %lu Hz, pixel clock %lu Hz\n",
460 limit
.c_bottom
= 0x0010;
461 limit
.c_top
= 0x0FE0;
462 limit
.y_bottom
= 0x0010;
463 limit
.y_top
= 0x0FE0;
465 dpi_pol
.ck_pol
= MTK_DPI_POLARITY_FALLING
;
466 dpi_pol
.de_pol
= MTK_DPI_POLARITY_RISING
;
467 dpi_pol
.hsync_pol
= mode
->flags
& DRM_MODE_FLAG_PHSYNC
?
468 MTK_DPI_POLARITY_FALLING
: MTK_DPI_POLARITY_RISING
;
469 dpi_pol
.vsync_pol
= mode
->flags
& DRM_MODE_FLAG_PVSYNC
?
470 MTK_DPI_POLARITY_FALLING
: MTK_DPI_POLARITY_RISING
;
472 hsync
.sync_width
= mode
->hsync_end
- mode
->hsync_start
;
473 hsync
.back_porch
= mode
->htotal
- mode
->hsync_end
;
474 hsync
.front_porch
= mode
->hsync_start
- mode
->hdisplay
;
475 hsync
.shift_half_line
= false;
477 vsync_lodd
.sync_width
= mode
->vsync_end
- mode
->vsync_start
;
478 vsync_lodd
.back_porch
= mode
->vtotal
- mode
->vsync_end
;
479 vsync_lodd
.front_porch
= mode
->vsync_start
- mode
->vdisplay
;
480 vsync_lodd
.shift_half_line
= false;
482 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
&&
483 mode
->flags
& DRM_MODE_FLAG_3D_MASK
) {
484 vsync_leven
= vsync_lodd
;
485 vsync_rodd
= vsync_lodd
;
486 vsync_reven
= vsync_lodd
;
487 vsync_leven
.shift_half_line
= true;
488 vsync_reven
.shift_half_line
= true;
489 } else if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
&&
490 !(mode
->flags
& DRM_MODE_FLAG_3D_MASK
)) {
491 vsync_leven
= vsync_lodd
;
492 vsync_leven
.shift_half_line
= true;
493 } else if (!(mode
->flags
& DRM_MODE_FLAG_INTERLACE
) &&
494 mode
->flags
& DRM_MODE_FLAG_3D_MASK
) {
495 vsync_rodd
= vsync_lodd
;
497 mtk_dpi_sw_reset(dpi
, true);
498 mtk_dpi_config_pol(dpi
, &dpi_pol
);
500 mtk_dpi_config_hsync(dpi
, &hsync
);
501 mtk_dpi_config_vsync_lodd(dpi
, &vsync_lodd
);
502 mtk_dpi_config_vsync_rodd(dpi
, &vsync_rodd
);
503 mtk_dpi_config_vsync_leven(dpi
, &vsync_leven
);
504 mtk_dpi_config_vsync_reven(dpi
, &vsync_reven
);
506 mtk_dpi_config_3d(dpi
, !!(mode
->flags
& DRM_MODE_FLAG_3D_MASK
));
507 mtk_dpi_config_interface(dpi
, !!(mode
->flags
&
508 DRM_MODE_FLAG_INTERLACE
));
509 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
510 mtk_dpi_config_fb_size(dpi
, mode
->hdisplay
, mode
->vdisplay
/ 2);
512 mtk_dpi_config_fb_size(dpi
, mode
->hdisplay
, mode
->vdisplay
);
514 mtk_dpi_config_channel_limit(dpi
, &limit
);
515 mtk_dpi_config_bit_num(dpi
, dpi
->bit_num
);
516 mtk_dpi_config_channel_swap(dpi
, dpi
->channel_swap
);
517 mtk_dpi_config_yc_map(dpi
, dpi
->yc_map
);
518 mtk_dpi_config_color_format(dpi
, dpi
->color_format
);
519 mtk_dpi_config_2n_h_fre(dpi
);
520 mtk_dpi_sw_reset(dpi
, false);
525 static void mtk_dpi_encoder_destroy(struct drm_encoder
*encoder
)
527 drm_encoder_cleanup(encoder
);
530 static const struct drm_encoder_funcs mtk_dpi_encoder_funcs
= {
531 .destroy
= mtk_dpi_encoder_destroy
,
534 static bool mtk_dpi_encoder_mode_fixup(struct drm_encoder
*encoder
,
535 const struct drm_display_mode
*mode
,
536 struct drm_display_mode
*adjusted_mode
)
541 static void mtk_dpi_encoder_mode_set(struct drm_encoder
*encoder
,
542 struct drm_display_mode
*mode
,
543 struct drm_display_mode
*adjusted_mode
)
545 struct mtk_dpi
*dpi
= mtk_dpi_from_encoder(encoder
);
547 drm_mode_copy(&dpi
->mode
, adjusted_mode
);
550 static void mtk_dpi_encoder_disable(struct drm_encoder
*encoder
)
552 struct mtk_dpi
*dpi
= mtk_dpi_from_encoder(encoder
);
554 mtk_dpi_power_off(dpi
, DPI_POWER_ENABLE
);
557 static void mtk_dpi_encoder_enable(struct drm_encoder
*encoder
)
559 struct mtk_dpi
*dpi
= mtk_dpi_from_encoder(encoder
);
561 mtk_dpi_power_on(dpi
, DPI_POWER_ENABLE
);
562 mtk_dpi_set_display_mode(dpi
, &dpi
->mode
);
565 static int mtk_dpi_atomic_check(struct drm_encoder
*encoder
,
566 struct drm_crtc_state
*crtc_state
,
567 struct drm_connector_state
*conn_state
)
572 static const struct drm_encoder_helper_funcs mtk_dpi_encoder_helper_funcs
= {
573 .mode_fixup
= mtk_dpi_encoder_mode_fixup
,
574 .mode_set
= mtk_dpi_encoder_mode_set
,
575 .disable
= mtk_dpi_encoder_disable
,
576 .enable
= mtk_dpi_encoder_enable
,
577 .atomic_check
= mtk_dpi_atomic_check
,
580 static void mtk_dpi_start(struct mtk_ddp_comp
*comp
)
582 struct mtk_dpi
*dpi
= container_of(comp
, struct mtk_dpi
, ddp_comp
);
584 mtk_dpi_power_on(dpi
, DPI_POWER_START
);
587 static void mtk_dpi_stop(struct mtk_ddp_comp
*comp
)
589 struct mtk_dpi
*dpi
= container_of(comp
, struct mtk_dpi
, ddp_comp
);
591 mtk_dpi_power_off(dpi
, DPI_POWER_START
);
594 static const struct mtk_ddp_comp_funcs mtk_dpi_funcs
= {
595 .start
= mtk_dpi_start
,
596 .stop
= mtk_dpi_stop
,
599 static int mtk_dpi_bind(struct device
*dev
, struct device
*master
, void *data
)
601 struct mtk_dpi
*dpi
= dev_get_drvdata(dev
);
602 struct drm_device
*drm_dev
= data
;
605 ret
= mtk_ddp_comp_register(drm_dev
, &dpi
->ddp_comp
);
607 dev_err(dev
, "Failed to register component %s: %d\n",
608 dev
->of_node
->full_name
, ret
);
612 ret
= drm_encoder_init(drm_dev
, &dpi
->encoder
, &mtk_dpi_encoder_funcs
,
613 DRM_MODE_ENCODER_TMDS
, NULL
);
615 dev_err(dev
, "Failed to initialize decoder: %d\n", ret
);
618 drm_encoder_helper_add(&dpi
->encoder
, &mtk_dpi_encoder_helper_funcs
);
620 /* Currently DPI0 is fixed to be driven by OVL1 */
621 dpi
->encoder
.possible_crtcs
= BIT(1);
623 dpi
->encoder
.bridge
->encoder
= &dpi
->encoder
;
624 ret
= drm_bridge_attach(dpi
->encoder
.dev
, dpi
->encoder
.bridge
);
626 dev_err(dev
, "Failed to attach bridge: %d\n", ret
);
630 dpi
->bit_num
= MTK_DPI_OUT_BIT_NUM_8BITS
;
631 dpi
->channel_swap
= MTK_DPI_OUT_CHANNEL_SWAP_RGB
;
632 dpi
->yc_map
= MTK_DPI_OUT_YC_MAP_RGB
;
633 dpi
->color_format
= MTK_DPI_COLOR_FORMAT_RGB
;
638 drm_encoder_cleanup(&dpi
->encoder
);
640 mtk_ddp_comp_unregister(drm_dev
, &dpi
->ddp_comp
);
644 static void mtk_dpi_unbind(struct device
*dev
, struct device
*master
,
647 struct mtk_dpi
*dpi
= dev_get_drvdata(dev
);
648 struct drm_device
*drm_dev
= data
;
650 drm_encoder_cleanup(&dpi
->encoder
);
651 mtk_ddp_comp_unregister(drm_dev
, &dpi
->ddp_comp
);
654 static const struct component_ops mtk_dpi_component_ops
= {
655 .bind
= mtk_dpi_bind
,
656 .unbind
= mtk_dpi_unbind
,
659 static int mtk_dpi_probe(struct platform_device
*pdev
)
661 struct device
*dev
= &pdev
->dev
;
663 struct resource
*mem
;
664 struct device_node
*ep
, *bridge_node
= NULL
;
668 dpi
= devm_kzalloc(dev
, sizeof(*dpi
), GFP_KERNEL
);
674 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
675 dpi
->regs
= devm_ioremap_resource(dev
, mem
);
676 if (IS_ERR(dpi
->regs
)) {
677 ret
= PTR_ERR(dpi
->regs
);
678 dev_err(dev
, "Failed to ioremap mem resource: %d\n", ret
);
682 dpi
->engine_clk
= devm_clk_get(dev
, "engine");
683 if (IS_ERR(dpi
->engine_clk
)) {
684 ret
= PTR_ERR(dpi
->engine_clk
);
685 dev_err(dev
, "Failed to get engine clock: %d\n", ret
);
689 dpi
->pixel_clk
= devm_clk_get(dev
, "pixel");
690 if (IS_ERR(dpi
->pixel_clk
)) {
691 ret
= PTR_ERR(dpi
->pixel_clk
);
692 dev_err(dev
, "Failed to get pixel clock: %d\n", ret
);
696 dpi
->tvd_clk
= devm_clk_get(dev
, "pll");
697 if (IS_ERR(dpi
->tvd_clk
)) {
698 ret
= PTR_ERR(dpi
->tvd_clk
);
699 dev_err(dev
, "Failed to get tvdpll clock: %d\n", ret
);
703 dpi
->irq
= platform_get_irq(pdev
, 0);
705 dev_err(dev
, "Failed to get irq: %d\n", dpi
->irq
);
709 ep
= of_graph_get_next_endpoint(dev
->of_node
, NULL
);
711 bridge_node
= of_graph_get_remote_port_parent(ep
);
715 dev_err(dev
, "Failed to find bridge node\n");
719 dev_info(dev
, "Found bridge node: %s\n", bridge_node
->full_name
);
721 dpi
->encoder
.bridge
= of_drm_find_bridge(bridge_node
);
722 of_node_put(bridge_node
);
723 if (!dpi
->encoder
.bridge
)
724 return -EPROBE_DEFER
;
726 comp_id
= mtk_ddp_comp_get_id(dev
->of_node
, MTK_DPI
);
728 dev_err(dev
, "Failed to identify by alias: %d\n", comp_id
);
732 ret
= mtk_ddp_comp_init(dev
, dev
->of_node
, &dpi
->ddp_comp
, comp_id
,
735 dev_err(dev
, "Failed to initialize component: %d\n", ret
);
739 platform_set_drvdata(pdev
, dpi
);
741 ret
= component_add(dev
, &mtk_dpi_component_ops
);
743 dev_err(dev
, "Failed to add component: %d\n", ret
);
750 static int mtk_dpi_remove(struct platform_device
*pdev
)
752 component_del(&pdev
->dev
, &mtk_dpi_component_ops
);
757 static const struct of_device_id mtk_dpi_of_ids
[] = {
758 { .compatible
= "mediatek,mt8173-dpi", },
762 struct platform_driver mtk_dpi_driver
= {
763 .probe
= mtk_dpi_probe
,
764 .remove
= mtk_dpi_remove
,
766 .name
= "mediatek-dpi",
767 .of_match_table
= mtk_dpi_of_ids
,