blob: f72173e4ad71b8dd1235952507fec2e98b8097ff [file] [log] [blame]
Angel Ponse67ab182020-04-04 18:51:11 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Hung-Te Linc59fbf22019-08-07 08:00:58 +08002
Hung-Te Lin75e43142019-08-07 10:31:27 +08003#include <assert.h>
Hung-Te Linc59fbf22019-08-07 08:00:58 +08004#include <console/console.h>
Julius Werner5ff18082021-08-24 16:03:57 -07005#include <mipi/panel.h>
Hung-Te Linc59fbf22019-08-07 08:00:58 +08006#include <device/mmio.h>
7#include <delay.h>
8#include <edid.h>
9#include <soc/dsi.h>
Hung-Te Linff0945e2019-08-07 09:59:16 +080010#include <string.h>
Hung-Te Linc59fbf22019-08-07 08:00:58 +080011#include <timer.h>
12
Paul Mad0ded162020-05-08 14:28:25 +080013#define MIN_HFP_BYTE 2
14#define MIN_HBP_BYTE 2
15
Hung-Te Lin61e34662019-08-07 08:44:30 +080016static unsigned int mtk_dsi_get_bits_per_pixel(u32 format)
17{
18 switch (format) {
19 case MIPI_DSI_FMT_RGB565:
20 return 16;
Hung-Te Lin61e34662019-08-07 08:44:30 +080021 case MIPI_DSI_FMT_RGB666_PACKED:
22 return 18;
Yu-Ping Wub4a29382020-02-12 11:51:49 +080023 case MIPI_DSI_FMT_RGB666:
Hung-Te Lin61e34662019-08-07 08:44:30 +080024 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
Yu-Ping Wu443fbd72020-02-11 18:33:57 +080032static u32 mtk_dsi_get_data_rate(u32 bits_per_pixel, u32 lanes,
Hung-Te Lin302dddf2019-08-08 06:28:43 +080033 const struct edid *edid)
34{
35 /* data_rate = pixel_clock * bits_per_pixel * mipi_ratio / lanes
Yu-Ping Wu443fbd72020-02-11 18:33:57 +080036 * Note pixel_clock comes in kHz and returned data_rate is in bps.
Hung-Te Lin302dddf2019-08-08 06:28:43 +080037 * 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 */
Yu-Ping Wu443fbd72020-02-11 18:33:57 +080041 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);
Hung-Te Lin302dddf2019-08-08 06:28:43 +080047
Yu-Ping Wu443fbd72020-02-11 18:33:57 +080048 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), "
Hung-Te Lin302dddf2019-08-08 06:28:43 +080052 "mipi_ratio (%d%%) and number of lanes (%d)\n",
Yu-Ping Wu443fbd72020-02-11 18:33:57 +080053 data_rate, MTK_DSI_DATA_RATE_MIN_MHZ * MHz,
Hung-Te Lin302dddf2019-08-08 06:28:43 +080054 edid->mode.pixel_clock, bits_per_pixel,
55 (100 * MTK_DSI_MIPI_RATIO_NUMERATOR /
56 MTK_DSI_MIPI_RATIO_DENOMINATOR), lanes);
Yu-Ping Wu443fbd72020-02-11 18:33:57 +080057 return 0;
Hung-Te Lin302dddf2019-08-08 06:28:43 +080058 }
59 return data_rate;
60}
61
Hung-Te Linff0945e2019-08-07 09:59:16 +080062__weak void mtk_dsi_override_phy_timing(struct mtk_phy_timing *timing)
Hung-Te Linc59fbf22019-08-07 08:00:58 +080063{
Hung-Te Linff0945e2019-08-07 09:59:16 +080064 /* Do nothing. */
65}
66
Jitao Shif68cc812020-01-14 21:23:44 +080067static void mtk_dsi_phy_timing(u32 data_rate, struct mtk_phy_timing *timing)
Hung-Te Linff0945e2019-08-07 09:59:16 +080068{
Jitao Shif68cc812020-01-14 21:23:44 +080069 u32 timcon0, timcon1, timcon2, timcon3;
Yu-Ping Wu443fbd72020-02-11 18:33:57 +080070 u32 data_rate_mhz = DIV_ROUND_UP(data_rate, MHz);
Hung-Te Linc59fbf22019-08-07 08:00:58 +080071
Jitao Shif68cc812020-01-14 21:23:44 +080072 memset(timing, 0, sizeof(*timing));
Hung-Te Linc59fbf22019-08-07 08:00:58 +080073
Jitao Shif68cc812020-01-14 21:23:44 +080074 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;
Hung-Te Linff0945e2019-08-07 09:59:16 +080079
Jitao Shif68cc812020-01-14 21:23:44 +080080 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;
Hung-Te Linff0945e2019-08-07 09:59:16 +080084
Jitao Shif68cc812020-01-14 21:23:44 +080085 timing->da_hs_sync = 1;
Hung-Te Linff0945e2019-08-07 09:59:16 +080086
Jitao Shif68cc812020-01-14 21:23:44 +080087 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;
Hung-Te Linff0945e2019-08-07 09:59:16 +080092
93 /* Allow board-specific tuning. */
Jitao Shif68cc812020-01-14 21:23:44 +080094 mtk_dsi_override_phy_timing(timing);
Hung-Te Linff0945e2019-08-07 09:59:16 +080095
Jitao Shif68cc812020-01-14 21:23:44 +080096 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;
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800104
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
111static void mtk_dsi_clk_hs_mode_enable(void)
112{
Julius Werner55009af2019-12-02 22:03:27 -0800113 setbits32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800114}
115
116static void mtk_dsi_clk_hs_mode_disable(void)
117{
Julius Werner55009af2019-12-02 22:03:27 -0800118 clrbits32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800119}
120
121static 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
138static 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
Shaoming Chen9e38efc2020-12-23 11:45:59 +0800158 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;
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800163
164 write32(&dsi0->dsi_txrx_ctrl, tmp_reg);
165}
166
Hung-Te Lin3b217d52019-08-07 10:15:48 +0800167static 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)
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800170{
171 u32 hsync_active_byte;
Jitao Shif68cc812020-01-14 21:23:44 +0800172 u32 hbp;
173 u32 hfp;
Paul Mad0ded162020-05-08 14:28:25 +0800174 s32 hbp_byte;
175 s32 hfp_byte;
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800176 u32 vbp_byte;
177 u32 vfp_byte;
Hung-Te Lin61e34662019-08-07 08:44:30 +0800178 u32 bytes_per_pixel;
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800179 u32 packet_fmt;
180 u32 hactive;
Hung-Te Lin3b217d52019-08-07 10:15:48 +0800181 u32 data_phy_cycles;
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800182
Hung-Te Lin61e34662019-08-07 08:44:30 +0800183 bytes_per_pixel = DIV_ROUND_UP(mtk_dsi_get_bits_per_pixel(format), 8);
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800184 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
Hung-Te Lin61e34662019-08-07 08:44:30 +0800193 hsync_active_byte = edid->mode.hspw * bytes_per_pixel - 10;
Jitao Shif68cc812020-01-14 21:23:44 +0800194
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;
Hung-Te Lin3b217d52019-08-07 10:15:48 +0800204
205 data_phy_cycles = phy_timing->lpx + phy_timing->da_hs_prepare +
Jitao Shif68cc812020-01-14 21:23:44 +0800206 phy_timing->da_hs_zero + phy_timing->da_hs_exit + 3;
Hung-Te Lin3b217d52019-08-07 10:15:48 +0800207
Jitao Shi104b7a92021-03-12 17:35:18 +0800208 u32 delta = 10;
Shaoming Chen9e38efc2020-12-23 11:45:59 +0800209
210 if (mode_flags & MIPI_DSI_MODE_EOT_PACKET)
211 delta += 2;
212
Hung-Te Lin3b217d52019-08-07 10:15:48 +0800213 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;
Jitao Shif68cc812020-01-14 21:23:44 +0800219
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 {
Ruihai Zhou7a667152023-07-13 09:24:17 +0800224 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);
Jitao Shif68cc812020-01-14 21:23:44 +0800227 }
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800228
Jitao Shi927fa6d2021-02-01 13:21:45 +0800229 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
Paul Mad0ded162020-05-08 14:28:25 +0800236 if (hfp_byte + hbp_byte < MIN_HFP_BYTE + MIN_HBP_BYTE) {
Ruihai Zhou7a667152023-07-13 09:24:17 +0800237 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);
Paul Mad0ded162020-05-08 14:28:25 +0800239 } else if (hfp_byte < MIN_HFP_BYTE) {
Ruihai Zhou7a667152023-07-13 09:24:17 +0800240 printk(BIOS_NOTICE, "Calculated hfp_byte %d is too small, "
241 "adjust it to the minimum value %d.\n", hfp_byte, MIN_HFP_BYTE);
Paul Mad0ded162020-05-08 14:28:25 +0800242 hbp_byte -= MIN_HFP_BYTE - hfp_byte;
243 hfp_byte = MIN_HFP_BYTE;
244 } else if (hbp_byte < MIN_HBP_BYTE) {
Ruihai Zhou7a667152023-07-13 09:24:17 +0800245 printk(BIOS_NOTICE, "Calculated hbp_byte %d is too small, "
246 "adjust it to the minimum value %d.\n", hbp_byte, MIN_HBP_BYTE);
Paul Mad0ded162020-05-08 14:28:25 +0800247 hfp_byte -= MIN_HBP_BYTE - hbp_byte;
248 hbp_byte = MIN_HBP_BYTE;
249 }
250
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800251 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;
Hung-Te Lin61e34662019-08-07 08:44:30 +0800274 packet_fmt |= (hactive * bytes_per_pixel) & DSI_PS_WC;
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800275
Hung-Te Lin3b217d52019-08-07 10:15:48 +0800276 write32(&dsi0->dsi_psctrl,
277 PIXEL_STREAM_CUSTOM_HEADER << DSI_PSCON_CUSTOM_HEADER_SHIFT |
278 packet_fmt);
Hung-Te Lin32ddc0d2019-08-07 10:58:36 +0800279
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);
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800285}
286
287static 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
Julius Werner4757a7e2021-09-08 17:58:34 -0700294static bool mtk_dsi_is_read_command(enum mipi_dsi_transaction type)
Hung-Te Lin75e43142019-08-07 10:31:27 +0800295{
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;
Julius Werner4757a7e2021-09-08 17:58:34 -0700302 default:
303 return false;
Hung-Te Lin75e43142019-08-07 10:31:27 +0800304 }
Hung-Te Lin75e43142019-08-07 10:31:27 +0800305}
306
Julius Werner69cc5572022-03-04 17:49:56 -0800307static enum cb_err mtk_dsi_cmdq(enum mipi_dsi_transaction type, const u8 *data, u8 len)
Hung-Te Lin75e43142019-08-07 10:31:27 +0800308{
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__);
Julius Werner4757a7e2021-09-08 17:58:34 -0700317 return CB_ERR;
Hung-Te Lin75e43142019-08-07 10:31:27 +0800318 }
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__);
Julius Wernerb2a14802021-08-12 16:48:12 -0700349 return CB_ERR;
Hung-Te Lin75e43142019-08-07 10:31:27 +0800350 }
Julius Wernerb2a14802021-08-12 16:48:12 -0700351
Julius Wernerb2a14802021-08-12 16:48:12 -0700352 return CB_SUCCESS;
Hung-Te Lin75e43142019-08-07 10:31:27 +0800353}
354
Jitao Shib6ca9382019-10-22 10:15:34 +0800355static void mtk_dsi_reset_dphy(void)
356{
Julius Werner55009af2019-12-02 22:03:27 -0800357 setbits32(&dsi0->dsi_con_ctrl, DPHY_RESET);
358 clrbits32(&dsi0->dsi_con_ctrl, DPHY_RESET);
Jitao Shib6ca9382019-10-22 10:15:34 +0800359}
360
Hung-Te Lin75e43142019-08-07 10:31:27 +0800361int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid,
Hung-Te Line366ba12019-08-07 16:28:08 +0800362 const u8 *init_commands)
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800363{
Yu-Ping Wu443fbd72020-02-11 18:33:57 +0800364 u32 data_rate;
Hung-Te Lin61e34662019-08-07 08:44:30 +0800365 u32 bits_per_pixel = mtk_dsi_get_bits_per_pixel(format);
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800366
Hung-Te Lin302dddf2019-08-08 06:28:43 +0800367 data_rate = mtk_dsi_get_data_rate(bits_per_pixel, lanes, edid);
Yu-Ping Wu443fbd72020-02-11 18:33:57 +0800368 if (!data_rate)
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800369 return -1;
370
Hung-Te Lin302dddf2019-08-08 06:28:43 +0800371 mtk_dsi_configure_mipi_tx(data_rate, lanes);
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800372 mtk_dsi_reset();
Hung-Te Linff0945e2019-08-07 09:59:16 +0800373 struct mtk_phy_timing phy_timing;
374 mtk_dsi_phy_timing(data_rate, &phy_timing);
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800375 mtk_dsi_rxtx_control(mode_flags, lanes);
Jitao Shib6ca9382019-10-22 10:15:34 +0800376 mdelay(1);
377 mtk_dsi_reset_dphy();
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800378 mtk_dsi_clk_hs_mode_disable();
Hung-Te Lin3b217d52019-08-07 10:15:48 +0800379 mtk_dsi_config_vdo_timing(mode_flags, format, lanes, edid, &phy_timing);
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800380 mtk_dsi_clk_hs_mode_enable();
Yu-Ping Wuf8f50622021-12-27 13:46:35 +0800381 if (init_commands)
382 mipi_panel_parse_init_commands(init_commands, mtk_dsi_cmdq);
Hung-Te Lin75e43142019-08-07 10:31:27 +0800383 mtk_dsi_set_mode(mode_flags);
Hung-Te Linc59fbf22019-08-07 08:00:58 +0800384 mtk_dsi_start();
385
386 return 0;
387}