xref: /aosp_15_r20/external/coreboot/src/soc/mediatek/common/dsi.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <assert.h>
4 #include <console/console.h>
5 #include <mipi/panel.h>
6 #include <device/mmio.h>
7 #include <delay.h>
8 #include <edid.h>
9 #include <soc/dsi.h>
10 #include <string.h>
11 #include <timer.h>
12 
13 #define MIN_HFP_BYTE	2
14 #define MIN_HBP_BYTE	2
15 
mtk_dsi_get_bits_per_pixel(u32 format)16 static unsigned int mtk_dsi_get_bits_per_pixel(u32 format)
17 {
18 	switch (format) {
19 	case MIPI_DSI_FMT_RGB565:
20 		return 16;
21 	case MIPI_DSI_FMT_RGB666_PACKED:
22 		return 18;
23 	case MIPI_DSI_FMT_RGB666:
24 	case MIPI_DSI_FMT_RGB888:
25 		return 24;
26 	}
27 	printk(BIOS_WARNING, "%s: WARN: Unknown format %d, assuming 24 bpp\n",
28 	       __func__, format);
29 	return 24;
30 }
31 
mtk_dsi_get_data_rate(u32 bits_per_pixel,u32 lanes,const struct edid * edid)32 static u32 mtk_dsi_get_data_rate(u32 bits_per_pixel, u32 lanes,
33 				 const struct edid *edid)
34 {
35 	/* data_rate = pixel_clock * bits_per_pixel * mipi_ratio / lanes
36 	 * Note pixel_clock comes in kHz and returned data_rate is in bps.
37 	 * mipi_ratio is the clk coefficient to balance the pixel clk in MIPI
38 	 * for older platforms which do not have complete implementation in HFP.
39 	 * Newer platforms should just set that to 1.0 (100 / 100).
40 	 */
41 	u32 data_rate = DIV_ROUND_UP((u64)edid->mode.pixel_clock *
42 				     bits_per_pixel * 1000 *
43 				     MTK_DSI_MIPI_RATIO_NUMERATOR,
44 				     (u64)lanes *
45 				     MTK_DSI_MIPI_RATIO_DENOMINATOR);
46 	printk(BIOS_INFO, "DSI data_rate: %u bps\n", data_rate);
47 
48 	if (data_rate < MTK_DSI_DATA_RATE_MIN_MHZ * MHz) {
49 		printk(BIOS_ERR, "data rate (%ubps) must be >= %ubps. "
50 		       "Please check the pixel clock (%u), "
51 		       "bits per pixel (%u), "
52 		       "mipi_ratio (%d%%) and number of lanes (%d)\n",
53 		       data_rate, MTK_DSI_DATA_RATE_MIN_MHZ * MHz,
54 		       edid->mode.pixel_clock, bits_per_pixel,
55 		       (100 * MTK_DSI_MIPI_RATIO_NUMERATOR /
56 			MTK_DSI_MIPI_RATIO_DENOMINATOR), lanes);
57 		return 0;
58 	}
59 	return data_rate;
60 }
61 
mtk_dsi_override_phy_timing(struct mtk_phy_timing * timing)62 __weak void mtk_dsi_override_phy_timing(struct mtk_phy_timing *timing)
63 {
64 	/* Do nothing. */
65 }
66 
mtk_dsi_phy_timing(u32 data_rate,struct mtk_phy_timing * timing)67 static void mtk_dsi_phy_timing(u32 data_rate, struct mtk_phy_timing *timing)
68 {
69 	u32 timcon0, timcon1, timcon2, timcon3;
70 	u32 data_rate_mhz = DIV_ROUND_UP(data_rate, MHz);
71 
72 	memset(timing, 0, sizeof(*timing));
73 
74 	timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1;
75 	timing->da_hs_prepare = (80 * data_rate_mhz + 4 * 1000) / 8000;
76 	timing->da_hs_zero = (170 * data_rate_mhz + 10 * 1000) / 8000 + 1 -
77 			     timing->da_hs_prepare;
78 	timing->da_hs_trail = timing->da_hs_prepare + 1;
79 
80 	timing->ta_go = 4 * timing->lpx - 2;
81 	timing->ta_sure = timing->lpx + 2;
82 	timing->ta_get = 4 * timing->lpx;
83 	timing->da_hs_exit = 2 * timing->lpx + 1;
84 
85 	timing->da_hs_sync = 1;
86 
87 	timing->clk_hs_prepare = 70 * data_rate_mhz / (8 * 1000);
88 	timing->clk_hs_post = timing->clk_hs_prepare + 8;
89 	timing->clk_hs_trail = timing->clk_hs_prepare;
90 	timing->clk_hs_zero = timing->clk_hs_trail * 4;
91 	timing->clk_hs_exit = 2 * timing->clk_hs_trail;
92 
93 	/* Allow board-specific tuning. */
94 	mtk_dsi_override_phy_timing(timing);
95 
96 	timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
97 		  timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
98 	timcon1 = timing->ta_go | timing->ta_sure << 8 |
99 		  timing->ta_get << 16 | timing->da_hs_exit << 24;
100 	timcon2 = timing->da_hs_sync << 8 | timing->clk_hs_zero << 16 |
101 		  timing->clk_hs_trail << 24;
102 	timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
103 		  timing->clk_hs_exit << 16;
104 
105 	write32(&dsi0->dsi_phy_timecon0, timcon0);
106 	write32(&dsi0->dsi_phy_timecon1, timcon1);
107 	write32(&dsi0->dsi_phy_timecon2, timcon2);
108 	write32(&dsi0->dsi_phy_timecon3, timcon3);
109 }
110 
mtk_dsi_clk_hs_mode_enable(void)111 static void mtk_dsi_clk_hs_mode_enable(void)
112 {
113 	setbits32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
114 }
115 
mtk_dsi_clk_hs_mode_disable(void)116 static void mtk_dsi_clk_hs_mode_disable(void)
117 {
118 	clrbits32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
119 }
120 
mtk_dsi_set_mode(u32 mode_flags)121 static void mtk_dsi_set_mode(u32 mode_flags)
122 {
123 	u32 tmp_reg1 = 0;
124 
125 	if (mode_flags & MIPI_DSI_MODE_VIDEO) {
126 		tmp_reg1 = SYNC_PULSE_MODE;
127 
128 		if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
129 			tmp_reg1 = BURST_MODE;
130 
131 		if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
132 			tmp_reg1 = SYNC_PULSE_MODE;
133 	}
134 
135 	write32(&dsi0->dsi_mode_ctrl, tmp_reg1);
136 }
137 
mtk_dsi_rxtx_control(u32 mode_flags,u32 lanes)138 static void mtk_dsi_rxtx_control(u32 mode_flags, u32 lanes)
139 {
140 	u32 tmp_reg = 0;
141 
142 	switch (lanes) {
143 	case 1:
144 		tmp_reg = 1 << 2;
145 		break;
146 	case 2:
147 		tmp_reg = 3 << 2;
148 		break;
149 	case 3:
150 		tmp_reg = 7 << 2;
151 		break;
152 	case 4:
153 	default:
154 		tmp_reg = 0xf << 2;
155 		break;
156 	}
157 
158 	if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
159 		tmp_reg |= NON_CONTINUOUS_CLK;
160 
161 	if (!(mode_flags & MIPI_DSI_MODE_EOT_PACKET))
162 		tmp_reg |= EOTP_DISABLE;
163 
164 	write32(&dsi0->dsi_txrx_ctrl, tmp_reg);
165 }
166 
mtk_dsi_config_vdo_timing(u32 mode_flags,u32 format,u32 lanes,const struct edid * edid,const struct mtk_phy_timing * phy_timing)167 static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes,
168 				      const struct edid *edid,
169 				      const struct mtk_phy_timing *phy_timing)
170 {
171 	u32 hsync_active_byte;
172 	u32 hbp;
173 	u32 hfp;
174 	s32 hbp_byte;
175 	s32 hfp_byte;
176 	u32 vbp_byte;
177 	u32 vfp_byte;
178 	u32 bytes_per_pixel;
179 	u32 packet_fmt;
180 	u32 hactive;
181 	u32 data_phy_cycles;
182 
183 	bytes_per_pixel = DIV_ROUND_UP(mtk_dsi_get_bits_per_pixel(format), 8);
184 	vbp_byte = edid->mode.vbl - edid->mode.vso - edid->mode.vspw -
185 		   edid->mode.vborder;
186 	vfp_byte = edid->mode.vso - edid->mode.vborder;
187 
188 	write32(&dsi0->dsi_vsa_nl, edid->mode.vspw);
189 	write32(&dsi0->dsi_vbp_nl, vbp_byte);
190 	write32(&dsi0->dsi_vfp_nl, vfp_byte);
191 	write32(&dsi0->dsi_vact_nl, edid->mode.va);
192 
193 	hsync_active_byte = edid->mode.hspw * bytes_per_pixel - 10;
194 
195 	hbp = edid->mode.hbl - edid->mode.hso - edid->mode.hspw -
196 	      edid->mode.hborder;
197 	hfp = edid->mode.hso - edid->mode.hborder;
198 
199 	if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
200 		hbp_byte = hbp * bytes_per_pixel - 10;
201 	else
202 		hbp_byte = (hbp + edid->mode.hspw) * bytes_per_pixel - 10;
203 	hfp_byte = hfp * bytes_per_pixel;
204 
205 	data_phy_cycles = phy_timing->lpx + phy_timing->da_hs_prepare +
206 			  phy_timing->da_hs_zero + phy_timing->da_hs_exit + 3;
207 
208 	u32 delta = 10;
209 
210 	if (mode_flags & MIPI_DSI_MODE_EOT_PACKET)
211 		delta += 2;
212 
213 	if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
214 		delta += 6;
215 
216 	u32 d_phy = phy_timing->d_phy;
217 	if (d_phy == 0)
218 		d_phy = data_phy_cycles * lanes + delta;
219 
220 	if ((hfp + hbp) * bytes_per_pixel > d_phy) {
221 		hfp_byte -= d_phy * hfp / (hfp + hbp);
222 		hbp_byte -= d_phy * hbp / (hfp + hbp);
223 	} else {
224 		printk(BIOS_ERR, "HFP %u plus HBP %u is not greater than d_phy %u, "
225 		       "the panel may not work properly.\n", hfp * bytes_per_pixel,
226 		       hbp * bytes_per_pixel, d_phy);
227 	}
228 
229 	if (mode_flags & MIPI_DSI_MODE_LINE_END) {
230 		hsync_active_byte = DIV_ROUND_UP(hsync_active_byte, lanes) * lanes - 2;
231 		hbp_byte = DIV_ROUND_UP(hbp_byte, lanes) * lanes - 2;
232 		hfp_byte = DIV_ROUND_UP(hfp_byte, lanes) * lanes - 2;
233 		hbp_byte -= (edid->mode.ha * bytes_per_pixel + 2) % lanes;
234 	}
235 
236 	if (hfp_byte + hbp_byte < MIN_HFP_BYTE + MIN_HBP_BYTE) {
237 		printk(BIOS_ERR, "Calculated hfp_byte %d and hbp_byte %d are too small, "
238 		       "the panel may not work properly.\n", hfp_byte, hbp_byte);
239 	} else if (hfp_byte < MIN_HFP_BYTE) {
240 		printk(BIOS_NOTICE, "Calculated hfp_byte %d is too small, "
241 		       "adjust it to the minimum value %d.\n", hfp_byte, MIN_HFP_BYTE);
242 		hbp_byte -= MIN_HFP_BYTE - hfp_byte;
243 		hfp_byte = MIN_HFP_BYTE;
244 	} else if (hbp_byte < MIN_HBP_BYTE) {
245 		printk(BIOS_NOTICE, "Calculated hbp_byte %d is too small, "
246 		       "adjust it to the minimum value %d.\n", hbp_byte, MIN_HBP_BYTE);
247 		hfp_byte -= MIN_HBP_BYTE - hbp_byte;
248 		hbp_byte = MIN_HBP_BYTE;
249 	}
250 
251 	write32(&dsi0->dsi_hsa_wc, hsync_active_byte);
252 	write32(&dsi0->dsi_hbp_wc, hbp_byte);
253 	write32(&dsi0->dsi_hfp_wc, hfp_byte);
254 
255 	switch (format) {
256 	case MIPI_DSI_FMT_RGB888:
257 		packet_fmt = PACKED_PS_24BIT_RGB888;
258 		break;
259 	case MIPI_DSI_FMT_RGB666:
260 		packet_fmt = LOOSELY_PS_18BIT_RGB666;
261 		break;
262 	case MIPI_DSI_FMT_RGB666_PACKED:
263 		packet_fmt = PACKED_PS_18BIT_RGB666;
264 		break;
265 	case MIPI_DSI_FMT_RGB565:
266 		packet_fmt = PACKED_PS_16BIT_RGB565;
267 		break;
268 	default:
269 		packet_fmt = PACKED_PS_24BIT_RGB888;
270 		break;
271 	}
272 
273 	hactive = edid->mode.ha;
274 	packet_fmt |= (hactive * bytes_per_pixel) & DSI_PS_WC;
275 
276 	write32(&dsi0->dsi_psctrl,
277 		PIXEL_STREAM_CUSTOM_HEADER << DSI_PSCON_CUSTOM_HEADER_SHIFT |
278 		packet_fmt);
279 
280 	/* Older systems like MT8173 do not support size_con. */
281 	if (MTK_DSI_HAVE_SIZE_CON)
282 		write32(&dsi0->dsi_size_con,
283 			edid->mode.va << DSI_SIZE_CON_HEIGHT_SHIFT |
284 			hactive << DSI_SIZE_CON_WIDTH_SHIFT);
285 }
286 
mtk_dsi_start(void)287 static void mtk_dsi_start(void)
288 {
289 	write32(&dsi0->dsi_start, 0);
290 	/* Only start master DSI */
291 	write32(&dsi0->dsi_start, 1);
292 }
293 
mtk_dsi_is_read_command(enum mipi_dsi_transaction type)294 static bool mtk_dsi_is_read_command(enum mipi_dsi_transaction type)
295 {
296 	switch (type) {
297 	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
298 	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
299 	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
300 	case MIPI_DSI_DCS_READ:
301 		return true;
302 	default:
303 		return false;
304 	}
305 }
306 
mtk_dsi_cmdq(enum mipi_dsi_transaction type,const u8 * data,u8 len)307 static enum cb_err mtk_dsi_cmdq(enum mipi_dsi_transaction type, const u8 *data, u8 len)
308 {
309 	const u8 *tx_buf = data;
310 	u32 config;
311 	int i, j;
312 
313 	if (!wait_ms(20, !(read32(&dsi0->dsi_intsta) & DSI_BUSY))) {
314 		printk(BIOS_ERR, "%s: cannot get DSI ready for sending commands"
315 		       " after 20ms and the panel may not work properly.\n",
316 		       __func__);
317 		return CB_ERR;
318 	}
319 	write32(&dsi0->dsi_intsta, 0);
320 
321 	if (mtk_dsi_is_read_command(type))
322 		config = BTA;
323 	else
324 		config = (len > 2) ? LONG_PACKET : SHORT_PACKET;
325 
326 	if (len <= 2) {
327 		uint32_t val = (type << 8) | config;
328 		for (i = 0; i < len; i++)
329 			val |= tx_buf[i] << (i + 2) * 8;
330 		write32(&dsi0->dsi_cmdq[0], val);
331 		write32(&dsi0->dsi_cmdq_size, 1);
332 	} else {
333 		/* TODO(hungte) Replace by buffer_to_fifo32_prefix */
334 		write32(&dsi0->dsi_cmdq[0], (len << 16) | (type << 8) | config);
335 		for (i = 0; i < len; i += 4) {
336 			uint32_t val = 0;
337 			for (j = 0; j < MIN(len - i, 4); j++)
338 				val |= tx_buf[i + j] << j * 8;
339 			write32(&dsi0->dsi_cmdq[i / 4 + 1], val);
340 		}
341 		write32(&dsi0->dsi_cmdq_size, 1 + DIV_ROUND_UP(len, 4));
342 	}
343 
344 	mtk_dsi_start();
345 
346 	if (!wait_us(400, read32(&dsi0->dsi_intsta) & CMD_DONE_INT_FLAG)) {
347 		printk(BIOS_ERR, "%s: failed sending DSI command, "
348 		       "panel may not work.\n", __func__);
349 		return CB_ERR;
350 	}
351 
352 	return CB_SUCCESS;
353 }
354 
mtk_dsi_reset_dphy(void)355 static void mtk_dsi_reset_dphy(void)
356 {
357 	setbits32(&dsi0->dsi_con_ctrl, DPHY_RESET);
358 	clrbits32(&dsi0->dsi_con_ctrl, DPHY_RESET);
359 }
360 
mtk_dsi_init(u32 mode_flags,u32 format,u32 lanes,const struct edid * edid,const u8 * init_commands)361 int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid,
362 		 const u8 *init_commands)
363 {
364 	u32 data_rate;
365 	u32 bits_per_pixel = mtk_dsi_get_bits_per_pixel(format);
366 
367 	data_rate = mtk_dsi_get_data_rate(bits_per_pixel, lanes, edid);
368 	if (!data_rate)
369 		return -1;
370 
371 	mtk_dsi_configure_mipi_tx(data_rate, lanes);
372 	mtk_dsi_reset();
373 	struct mtk_phy_timing phy_timing;
374 	mtk_dsi_phy_timing(data_rate, &phy_timing);
375 	mtk_dsi_rxtx_control(mode_flags, lanes);
376 	mdelay(1);
377 	mtk_dsi_reset_dphy();
378 	mtk_dsi_clk_hs_mode_disable();
379 	mtk_dsi_config_vdo_timing(mode_flags, format, lanes, edid, &phy_timing);
380 	mtk_dsi_clk_hs_mode_enable();
381 	if (init_commands)
382 		mipi_panel_parse_init_commands(init_commands, mtk_dsi_cmdq);
383 	mtk_dsi_set_mode(mode_flags);
384 	mtk_dsi_start();
385 
386 	return 0;
387 }
388