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