1 /* SPDX-License-Identifier: GPL-2.0-only OR MIT */
3 #include <console/console.h>
4 #include <device/mmio.h>
6 #include <soc/addressmap.h>
12 static void disp_config_main_path_connection(void)
15 write32(&mmsys_cfg
->mmsys_ovl_mout_en
,
16 DISP_OVL0_TO_DISP_RDMA0
);
17 write32(&mmsys_cfg
->mmsys_sel_in
,
18 SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
|
19 SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
|
20 SEL_IN_DP_INTF0_FROM_VPP_MERGE
);
21 write32(&mmsys_cfg
->mmsys_sel_out
,
22 SEL_OUT_DISP_DITHER0_TO_DSC_WRAP0_IN
|
23 SEL_OUT_DSC_WRAP0_OUT_TO_VPP_MERGE
|
24 SEL_OUT_VPP_MERGE_TO_DP_INTF0
);
27 static void disp_config_main_path_mutex(void)
29 write32(&disp_mutex
->mutex
[0].mod
, MUTEX_MOD_MAIN_PATH
);
31 /* Clock source from DP_INTF0 */
32 write32(&disp_mutex
->mutex
[0].ctl
,
33 MUTEX_SOF_DP_INTF0
| (MUTEX_SOF_DP_INTF0
<< 7));
34 write32(&disp_mutex
->mutex
[0].en
, BIT(0));
37 static void ovl_bgclr_in_sel(u32 idx
)
39 setbits32(&disp_ovl
[idx
]->datapath_con
, BIT(2));
42 static void ovl_layer_smi_id_en(u32 idx
)
44 setbits32(&disp_ovl
[idx
]->datapath_con
, BIT(0));
47 static void ovl_layer_gclast_en(u32 idx
)
49 setbits32(&disp_ovl
[idx
]->datapath_con
, BIT(24));
50 setbits32(&disp_ovl
[idx
]->datapath_con
, BIT(25));
53 static void ovl_layer_output_clamp_en(u32 idx
)
55 setbits32(&disp_ovl
[idx
]->datapath_con
, BIT(26));
58 static void ccorr_config(u32 width
, u32 height
)
60 struct disp_ccorr_regs
*const regs
= disp_ccorr
;
62 write32(®s
->size
, width
<< 16 | height
);
63 clrsetbits32(®s
->cfg
, PQ_ENGINE_EN
, PQ_RELAY_MODE
);
64 write32(®s
->en
, PQ_EN
);
67 static void aal_config(u32 width
, u32 height
)
69 struct disp_aal_regs
*const regs
= disp_aal
;
71 write32(®s
->size
, width
<< 16 | height
);
72 write32(®s
->output_size
, width
<< 16 | height
);
73 clrsetbits32(®s
->cfg
, PQ_ENGINE_EN
, PQ_RELAY_MODE
);
74 write32(®s
->en
, PQ_EN
);
77 static void gamma_config(u32 width
, u32 height
)
79 struct disp_gamma_regs
*const regs
= disp_gamma
;
81 write32(®s
->size
, width
<< 16 | height
);
82 setbits32(®s
->cfg
, PQ_RELAY_MODE
);
83 write32(®s
->en
, PQ_EN
);
86 static void dither_config(u32 width
, u32 height
)
88 struct disp_dither_regs
*const regs
= disp_dither
;
89 write32(®s
->size
, width
<< 16 | height
);
90 setbits32(®s
->cfg
, PQ_RELAY_MODE
);
91 write32(®s
->en
, PQ_EN
);
94 static void dsc_config(void)
96 struct disp_dsc_regs
*const regs
= disp_dsc
;
98 /* Enable dsc bypass mode. */
99 write32(®s
->con
, DISP_DSC0_CON
);
102 static void merge_config(u32 width
, u32 height
)
104 struct disp_merge_regs
*const regs
= disp_merge
;
106 write32(®s
->cfg0
, height
<< 16 | width
);
107 write32(®s
->cfg4
, height
<< 16 | width
);
108 write32(®s
->cfg25
, height
<< 16 | width
);
109 setbits32(®s
->cfg10
, MERGE_SWAP
);
110 setbits32(®s
->cfg12
, MERGE_MODE
);
111 write32(®s
->en
, 0x1);
114 static void main_disp_path_setup(u32 width
, u32 height
, u32 vrefresh
)
117 u32 pixel_clk
= width
* height
* vrefresh
;
119 for (idx
= 0; idx
< MAIN_PATH_OVL_NR
; idx
++) {
120 ovl_set_roi(idx
, width
, height
, idx
? 0 : 0xff0000ff);
121 ovl_layer_smi_id_en(idx
);
122 ovl_layer_gclast_en(idx
);
123 ovl_layer_output_clamp_en(idx
);
126 rdma_config(width
, height
, pixel_clk
, 5 * KiB
);
127 color_start(width
, height
);
128 ccorr_config(width
, height
);
129 aal_config(width
, height
);
130 gamma_config(width
, height
);
131 dither_config(width
, height
);
133 merge_config(width
, height
);
134 disp_config_main_path_connection();
135 disp_config_main_path_mutex();
138 static void disp_clock_on(void)
140 clrbits32(&mmsys_cfg
->mmsys_cg_con0
, CG_CON0_DISP_ALL
);
141 clrbits32(&mmsys_cfg
->mmsys_cg_con1
, CG_CON1_DISP_ALL
);
142 clrbits32(&mmsys_cfg
->mmsys_cg_con2
, CG_CON2_DISP_ALL
);
145 void mtk_ddp_init(void)
149 /* Turn off M4U port. */
150 write32((void *)(SMI_LARB0
+ SMI_LARB_PORT_L0_OVL_RDMA0
), 0);
153 void mtk_ddp_mode_set(const struct edid
*edid
, enum disp_path_sel path
)
155 u32 fmt
= OVL_INFMT_RGBA8888
;
156 u32 bpp
= edid
->framebuffer_bits_per_pixel
/ 8;
157 u32 width
= edid
->mode
.ha
;
158 u32 height
= edid
->mode
.va
;
159 u32 vrefresh
= edid
->mode
.refresh
;
161 printk(BIOS_DEBUG
, "%s: display resolution: %dx%d@%d bpp %d\n",
162 __func__
, width
, height
, vrefresh
, bpp
);
165 if (!width
|| !height
)
168 vrefresh
= edid
->mode
.pixel_clock
* 1000 /
169 ((width
+ edid
->mode
.hbl
) *
170 (height
+ edid
->mode
.vbl
));
172 printk(BIOS_WARNING
, "%s: vrefresh is not provided; using %d\n",
176 main_disp_path_setup(width
, height
, vrefresh
);
178 ovl_layer_config(fmt
, bpp
, width
, height
);