• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/mmio.h>
5 #include <edid.h>
6 #include <soc/addressmap.h>
7 #include <soc/ddp.h>
8 
disp_config_main_path_connection(void)9 static void disp_config_main_path_connection(void)
10 {
11 	/* ovl0->ovl0_2l */
12 	write32(&mmsys_cfg->mmsys_ovl_mout_en,
13 		(DISP_OVL0_GO_BG | DISP_OVL0_2L_GO_BLEND));
14 	write32(&mmsys_cfg->ovl0_2l_mout_en, OVL0_MOUT_EN_DISP_RDMA0);
15 	write32(&mmsys_cfg->rdma0_sel_in, RDMA0_SEL_IN_OVL0_2L);
16 	write32(&mmsys_cfg->rdma0_sout_sel, RDMA0_SOUT_COLOR0);
17 	write32(&mmsys_cfg->ccorr0_sout_sel, CCORR0_SOUT_AAL0);
18 	write32(&mmsys_cfg->aal0_sel_in, AAL0_SEL_IN_CCORR0);
19 	write32(&mmsys_cfg->dither0_mout_en, DITHER0_MOUT_DSI0);
20 	write32(&mmsys_cfg->dsi0_sel_in, DSI0_SEL_IN_DITHER0);
21 }
22 
disp_config_main_path_mutex(void)23 static void disp_config_main_path_mutex(void)
24 {
25 	write32(&disp_mutex->mutex[0].mod, MUTEX_MOD_MAIN_PATH);
26 
27 	/* Clock source from DSI0 */
28 	write32(&disp_mutex->mutex[0].ctl,
29 		MUTEX_SOF_DSI0 | (MUTEX_SOF_DSI0 << 6));
30 	write32(&disp_mutex->mutex[0].en, BIT(0));
31 }
32 
ovl_bgclr_in_sel(u32 idx)33 static void ovl_bgclr_in_sel(u32 idx)
34 {
35 	setbits32(&disp_ovl[idx]->datapath_con, BIT(2));
36 }
37 
ovl_layer_smi_id_en(u32 idx)38 static void ovl_layer_smi_id_en(u32 idx)
39 {
40 	printk(BIOS_INFO, "%s\n", __func__);
41 
42 	setbits32(&disp_ovl[idx]->datapath_con, BIT(0));
43 }
44 
ccorr_config(u32 width,u32 height)45 static void ccorr_config(u32 width, u32 height)
46 {
47 	struct disp_ccorr_regs *const regs = disp_ccorr;
48 	int enable_relay = 0;
49 
50 	printk(BIOS_INFO, "%s\n", __func__);
51 
52 	write32(&regs->size, width << 16 | height);
53 
54 	if (enable_relay) {
55 		setbits32(&regs->cfg, PQ_RELAY_MODE);
56 		clrbits32(&regs->cfg, PQ_ENGINE_EN);
57 	} else {
58 		clrbits32(&regs->cfg, PQ_RELAY_MODE);
59 		setbits32(&regs->cfg, PQ_ENGINE_EN);
60 	}
61 
62 	write32(&regs->en, PQ_EN);
63 }
64 
aal_config(u32 width,u32 height)65 static void aal_config(u32 width, u32 height)
66 {
67 	struct disp_aal_regs *const regs = disp_aal;
68 	int enable_relay = 1;
69 
70 	printk(BIOS_INFO, "%s\n", __func__);
71 
72 	write32(&regs->size, width << 16 | height);
73 	write32(&regs->output_size, width << 16 | height);
74 
75 	if (enable_relay) {
76 		setbits32(&regs->cfg, PQ_RELAY_MODE);
77 		clrbits32(&regs->cfg, PQ_ENGINE_EN);
78 	} else {
79 		clrbits32(&regs->cfg, PQ_RELAY_MODE);
80 		setbits32(&regs->cfg, PQ_ENGINE_EN);
81 	}
82 
83 	write32(&regs->en, PQ_EN);
84 }
85 
gamma_config(u32 width,u32 height)86 static void gamma_config(u32 width, u32 height)
87 {
88 	struct disp_gamma_regs *const regs = disp_gamma;
89 	int enable_relay = 0;
90 
91 	printk(BIOS_INFO, "%s\n", __func__);
92 
93 	write32(&regs->size, width << 16 | height);
94 
95 	if (enable_relay)
96 		setbits32(&regs->cfg, PQ_RELAY_MODE);
97 	else
98 		clrbits32(&regs->cfg, PQ_RELAY_MODE);
99 
100 	write32(&regs->en, PQ_EN);
101 }
102 
postmask_config(u32 width,u32 height)103 static void postmask_config(u32 width, u32 height)
104 {
105 	struct disp_postmask_regs *const regs = disp_postmask;
106 	int enable_relay = 1;
107 
108 	printk(BIOS_INFO, "%s\n", __func__);
109 
110 	write32(&regs->size, width << 16 | height);
111 
112 	if (enable_relay)
113 		setbits32(&regs->cfg, PQ_RELAY_MODE);
114 	else
115 		clrbits32(&regs->cfg, PQ_RELAY_MODE);
116 
117 	write32(&regs->en, PQ_EN);
118 }
119 
dither_config(u32 width,u32 height)120 static void dither_config(u32 width, u32 height)
121 {
122 	struct disp_dither_regs *const regs = disp_dither;
123 	int enable_relay = 1;
124 
125 	printk(BIOS_INFO, "%s\n", __func__);
126 
127 	write32(&regs->size, width << 16 | height);
128 
129 	if (enable_relay)
130 		setbits32(&regs->cfg, PQ_RELAY_MODE);
131 	else
132 		clrbits32(&regs->cfg, PQ_RELAY_MODE);
133 
134 	write32(&regs->en, PQ_EN);
135 }
136 
137 
main_disp_path_setup(u32 width,u32 height,u32 vrefresh)138 static void main_disp_path_setup(u32 width, u32 height, u32 vrefresh)
139 {
140 	u32 idx = 0;
141 	u32 pixel_clk = width * height * vrefresh;
142 
143 	printk(BIOS_INFO, "%s\n", __func__);
144 
145 	for (idx = 0; idx < MAIN_PATH_OVL_NR; idx++) {
146 		ovl_set_roi(idx, width, height, idx ? 0 : 0xff0000ff);
147 		ovl_layer_smi_id_en(idx);
148 	}
149 
150 	rdma_config(width, height, pixel_clk, 5 * KiB);
151 	color_start(width, height);
152 	ccorr_config(width, height);
153 	aal_config(width, height);
154 	gamma_config(width, height);
155 	postmask_config(width, height);
156 	dither_config(width, height);
157 	disp_config_main_path_connection();
158 	disp_config_main_path_mutex();
159 }
160 
disp_clock_on(void)161 static void disp_clock_on(void)
162 {
163 	clrbits32(&mmsys_cfg->mmsys_cg_con0, CG_CON0_DISP_ALL);
164 
165 	clrbits32(&mmsys_cfg->mmsys_cg_con1, CG_CON1_DISP_ALL);
166 
167 	clrbits32(&mmsys_cfg->mmsys_cg_con2, CG_CON2_DISP_ALL);
168 }
169 
mtk_ddp_init(void)170 void mtk_ddp_init(void)
171 {
172 	disp_clock_on();
173 	/* Turn off M4U port. */
174 	write32((void *)(SMI_LARB0 + SMI_LARB_PORT_L0_OVL_RDMA0), 0);
175 }
176 
mtk_ddp_mode_set(const struct edid * edid)177 void mtk_ddp_mode_set(const struct edid *edid)
178 {
179 	u32 fmt = OVL_INFMT_RGBA8888;
180 	u32 bpp = edid->framebuffer_bits_per_pixel / 8;
181 	u32 width = edid->mode.ha;
182 	u32 height = edid->mode.va;
183 	u32 vrefresh = edid->mode.refresh;
184 
185 	printk(BIOS_INFO, "%s display resolution: %dx%d@%d bpp %d\n",
186 		__func__, width, height, vrefresh, bpp);
187 
188 	if (!vrefresh) {
189 		vrefresh = 60;
190 		printk(BIOS_INFO, "%s invalid vrefresh %d\n",
191 		__func__, vrefresh);
192 	}
193 
194 	main_disp_path_setup(width, height, vrefresh);
195 	rdma_start();
196 	ovl_layer_config(fmt, bpp, width, height);
197 	ovl_bgclr_in_sel(1);
198 }
199