rockchip/rk3399: mipi: correct phy parameter setting
[coreboot.git] / src / soc / rockchip / rk3399 / mipi.c
blobf44c7993cacf9356b25f66b73b7b1a78ed8cdef0
1 /*
2 * This file is part of the coreboot project.
4 * Copyright 2017 Rockchip Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <arch/io.h>
17 #include <assert.h>
18 #include <console/console.h>
19 #include <delay.h>
20 #include <device/device.h>
21 #include <edid.h>
22 #include <gpio.h>
23 #include <stdlib.h>
24 #include <stdint.h>
25 #include <string.h>
26 #include <soc/addressmap.h>
27 #include <soc/clock.h>
28 #include <soc/display.h>
29 #include <soc/mipi.h>
30 #include <soc/soc.h>
31 #include <timer.h>
33 static struct rk_mipi_dsi rk_mipi;
34 static struct rk_mipi_regs *mipi_regs = (void *)MIPI_BASE;
37 * The controller should generate 2 frames before
38 * preparing the peripheral.
40 static void rk_mipi_dsi_wait_for_two_frames(struct rk_mipi_dsi *dsi,
41 const struct edid *edid)
43 int two_frames;
44 unsigned int refresh = edid->mode.refresh;
46 two_frames = div_round_up(MSECS_PER_SEC * 2, refresh);
47 mdelay(two_frames);
50 static const struct dphy_pll_parameter_map dppa_map[] = {
51 { 89, 0x00, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM},
52 { 99, 0x10, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM},
53 { 109, 0x20, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM},
54 { 129, 0x01, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
55 { 139, 0x11, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
56 { 149, 0x21, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
57 { 169, 0x02, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
58 { 179, 0x12, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
59 { 199, 0x22, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
60 { 219, 0x03, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
61 { 239, 0x13, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
62 { 249, 0x23, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
63 { 269, 0x04, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM},
64 { 299, 0x14, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM},
65 { 329, 0x05, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
66 { 359, 0x15, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
67 { 399, 0x25, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
68 { 449, 0x06, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
69 { 499, 0x16, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
70 { 549, 0x07, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM},
71 { 599, 0x17, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM},
72 { 649, 0x08, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
73 { 699, 0x18, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
74 { 749, 0x09, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
75 { 799, 0x19, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
76 { 849, 0x29, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
77 { 899, 0x39, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
78 { 949, 0x0a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
79 { 999, 0x1a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
80 {1049, 0x2a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
81 {1099, 0x3a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
82 {1149, 0x0b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
83 {1199, 0x1b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
84 {1249, 0x2b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
85 {1299, 0x3b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
86 {1349, 0x0c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
87 {1399, 0x1c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
88 {1449, 0x2c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
89 {1500, 0x3c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM}
92 static int max_mbps_to_parameter(unsigned int max_mbps)
94 int i;
96 for (i = 0; i < ARRAY_SIZE(dppa_map); i++) {
97 if (dppa_map[i].max_mbps >= max_mbps)
98 return i;
101 return -1;
104 static void rk_mipi_dsi_phy_write(struct rk_mipi_dsi *dsi,
105 u8 test_code,
106 u8 test_data)
109 * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
110 * is latched internally as the current test code. Test data is
111 * programmed internally by rising edge on TESTCLK.
113 write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_TESTCLK | PHY_UNTESTCLR);
115 write32(&mipi_regs->dsi_phy_tst_ctrl1, PHY_TESTEN | PHY_TESTDOUT(0) |
116 PHY_TESTDIN(test_code));
118 write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLK | PHY_UNTESTCLR);
120 write32(&mipi_regs->dsi_phy_tst_ctrl1, PHY_UNTESTEN | PHY_TESTDOUT(0) |
121 PHY_TESTDIN(test_data));
123 write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_TESTCLK | PHY_UNTESTCLR);
126 static int rk_mipi_dsi_phy_init(struct rk_mipi_dsi *dsi)
128 int i, vco;
129 int lane_mbps = div_round_up(dsi->lane_bps, USECS_PER_SEC);
131 vco = (lane_mbps < 200) ? 0 : (lane_mbps + 100) / 200;
133 i = max_mbps_to_parameter(lane_mbps);
134 if (i < 0) {
135 printk(BIOS_DEBUG,
136 "failed to get parameter for %dmbps clock\n", lane_mbps);
137 return i;
140 /* Start by clearing PHY state */
141 write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLR);
142 write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_TESTCLR);
143 write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLR);
145 rk_mipi_dsi_phy_write(dsi, PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL,
146 BYPASS_VCO_RANGE |
147 VCO_RANGE_CON_SEL(vco) |
148 VCO_IN_CAP_CON_LOW |
149 REF_BIAS_CUR_SEL);
151 rk_mipi_dsi_phy_write(dsi, PLL_CP_CONTROL_PLL_LOCK_BYPASS,
152 CP_CURRENT_SEL(dppa_map[i].icpctrl));
153 rk_mipi_dsi_phy_write(dsi, PLL_LPF_AND_CP_CONTROL,
154 CP_PROGRAM_EN |
155 LPF_PROGRAM_EN |
156 LPF_RESISTORS_SEL(dppa_map[i].lpfctrl));
157 rk_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_0,
158 HSFREQRANGE_SEL(dppa_map[i].hsfreqrange));
160 rk_mipi_dsi_phy_write(dsi, PLL_INPUT_DIVIDER_RATIO,
161 INPUT_DIVIDER(dsi->input_div));
162 rk_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
163 LOOP_DIV_LOW_SEL(dsi->feedback_div) |
164 LOW_PROGRAM_EN);
165 rk_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
166 LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
167 HIGH_PROGRAM_EN);
168 rk_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
169 PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
170 rk_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY,
171 LOW_PROGRAM_EN |
172 BIASEXTR_SEL(BIASEXTR_127_7));
173 rk_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY,
174 HIGH_PROGRAM_EN |
175 BANDGAP_SEL(BANDGAP_96_10));
176 rk_mipi_dsi_phy_write(dsi, BANDGAP_AND_BIAS_CONTROL,
177 POWER_CONTROL | INTERNAL_REG_CURRENT |
178 BIAS_BLOCK_ON | BANDGAP_ON);
179 rk_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL,
180 TER_RESISTOR_LOW | TER_CAL_DONE |
181 SETRD_MAX | TER_RESISTORS_ON);
182 rk_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL,
183 TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON |
184 SETRD_MAX | POWER_MANAGE |
185 TER_RESISTORS_ON);
187 write32(&mipi_regs->dsi_phy_rstz, PHY_ENFORCEPLL | PHY_ENABLECLK |
188 PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
189 return 0;
192 static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)
194 switch (fmt) {
195 case MIPI_DSI_FMT_RGB888:
196 case MIPI_DSI_FMT_RGB666:
197 return 24;
199 case MIPI_DSI_FMT_RGB666_PACKED:
200 return 18;
202 case MIPI_DSI_FMT_RGB565:
203 return 16;
206 return -1;
209 static int rk_mipi_dsi_get_lane_bps(struct rk_mipi_dsi *dsi,
210 const struct edid *edid)
212 u32 i, pre;
213 u64 pclk, pllref, tmp, target_bps;
214 u32 m = 1, n = 1;
215 u32 max_bps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps * MHz;
216 int bpp;
218 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
219 if (bpp < 0) {
220 printk(BIOS_DEBUG, "failed to get bpp for pixel format %d\n",
221 dsi->format);
222 return bpp;
224 pclk = edid->mode.pixel_clock * MSECS_PER_SEC;
225 /* take 1 / 0.8, since mbps must bigger than bandwidth of RGB */
226 target_bps = pclk / dsi->lanes * bpp / 8 * 10;
227 if (target_bps >= max_bps) {
228 printk(BIOS_DEBUG, "DPHY clock frequency is out of range\n");
229 return -1;
231 pllref = OSC_HZ;
232 tmp = pllref;
234 * The limits on the PLL divisor are:
236 * 5MHz <= (pllref / n) <= 40MHz
238 for (i = pllref / (5 * MHz); i > div_round_up(pllref, 40 * MHz); i--) {
239 pre = pllref / i;
240 if ((tmp > (target_bps % pre)) && (target_bps / pre < 512)) {
241 tmp = target_bps % pre;
242 n = i;
243 m = target_bps / pre;
245 if (tmp == 0)
246 break;
248 dsi->lane_bps = pllref / n * m;
249 dsi->input_div = n;
250 dsi->feedback_div = m;
252 return 0;
255 static void rk_mipi_dsi_dpi_config(struct rk_mipi_dsi *dsi)
257 u32 color = 0;
259 switch (dsi->format) {
260 case MIPI_DSI_FMT_RGB888:
261 color = DPI_COLOR_CODING_24BIT;
262 break;
263 case MIPI_DSI_FMT_RGB666:
264 color = DPI_COLOR_CODING_18BIT_2 | EN18_LOOSELY;
265 break;
266 case MIPI_DSI_FMT_RGB666_PACKED:
267 color = DPI_COLOR_CODING_18BIT_1;
268 break;
269 case MIPI_DSI_FMT_RGB565:
270 color = DPI_COLOR_CODING_16BIT_1;
271 break;
274 write32(&mipi_regs->dsi_dpi_vcid, 0);
275 write32(&mipi_regs->dsi_dpi_color_coding, color);
277 write32(&mipi_regs->dsi_dpi_cfg_pol, 0);
279 write32(&mipi_regs->dsi_dpi_lp_cmd_tim, OUTVACT_LPCMD_TIME(4) |
280 INVACT_LPCMD_TIME(4));
283 static void rk_mipi_dsi_packet_handler_config(struct rk_mipi_dsi *dsi)
285 write32(&mipi_regs->dsi_pckhdl_cfg, EN_CRC_RX | EN_ECC_RX | EN_BTA);
288 static void rk_mipi_dsi_video_mode_config(struct rk_mipi_dsi *dsi)
290 write32(&mipi_regs->dsi_vid_mode_cfg,
291 VID_MODE_TYPE_BURST_SYNC_PULSES | ENABLE_LOW_POWER);
294 static void rk_mipi_dsi_video_packet_config(struct rk_mipi_dsi *dsi)
296 write32(&mipi_regs->dsi_vid_pkt_size, VID_PKT_SIZE(0x300));
299 static void rk_mipi_dsi_command_mode_config(struct rk_mipi_dsi *dsi)
301 write32(&mipi_regs->dsi_to_cnt_cfg,
302 HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
303 write32(&mipi_regs->dsi_bta_to_cnt, 0xd00);
304 write32(&mipi_regs->dsi_cmd_mode_cfg, CMD_MODE_ALL_LP);
305 write32(&mipi_regs->dsi_mode_cfg, ENABLE_CMD_MODE);
308 /* Get lane byte clock cycles. */
309 static u32 rk_mipi_dsi_get_hcomponent_lbcc(struct rk_mipi_dsi *dsi,
310 u32 hcomponent,
311 const struct edid *edid)
313 u32 lbcc;
314 u64 lbcc_tmp;
316 lbcc_tmp = hcomponent * dsi->lane_bps / (8 * MSECS_PER_SEC);
317 lbcc = div_round_up(lbcc_tmp, edid->mode.pixel_clock);
319 return lbcc;
322 static void rk_mipi_dsi_line_timer_config(struct rk_mipi_dsi *dsi,
323 const struct edid *edid)
325 u32 htotal, hsa, hbp, lbcc;
327 htotal = edid->mode.ha + edid->mode.hbl;
328 hsa = edid->mode.hspw;
329 hbp = edid->mode.hbl - edid->mode.hso - edid->mode.hspw;
331 lbcc = rk_mipi_dsi_get_hcomponent_lbcc(dsi, htotal, edid);
332 write32(&mipi_regs->dsi_vid_hline_time, lbcc);
334 lbcc = rk_mipi_dsi_get_hcomponent_lbcc(dsi, hsa, edid);
335 write32(&mipi_regs->dsi_vid_hsa_time, lbcc);
336 lbcc = rk_mipi_dsi_get_hcomponent_lbcc(dsi, hbp, edid);
337 write32(&mipi_regs->dsi_vid_hbp_time, lbcc);
340 static void rk_mipi_dsi_vertical_timing_config(struct rk_mipi_dsi *dsi,
341 const struct edid *edid)
343 u32 vactive, vsa, vfp, vbp;
345 vactive = edid->mode.va;
346 vsa = edid->mode.vspw;
347 vfp = edid->mode.vso;
348 vbp = edid->mode.vbl - edid->mode.vso - edid->mode.vspw;
350 write32(&mipi_regs->dsi_vid_vactive_lines, vactive);
351 write32(&mipi_regs->dsi_vid_vsa_lines, vsa);
352 write32(&mipi_regs->dsi_vid_vfp_lines, vfp);
353 write32(&mipi_regs->dsi_vid_vbp_lines, vbp);
356 static void rk_mipi_dsi_dphy_timing_config(struct rk_mipi_dsi *dsi)
359 * HS-PREPARE: 40ns + 4 * UI ~ 85ns + 6 * UI
360 * HS-EXIT: 100ns
362 write32(&mipi_regs->dsi_phy_tmr_cfg, PHY_HS2LP_TIME(0x40) |
363 PHY_LP2HS_TIME(0x40) |
364 MAX_RD_TIME(10000));
366 write32(&mipi_regs->dsi_phy_tmr_lpclk_cfg, PHY_CLKHS2LP_TIME(0x40) |
367 PHY_CLKLP2HS_TIME(0x40));
370 static void rk_mipi_dsi_clear_err(struct rk_mipi_dsi *dsi)
372 read32(&mipi_regs->dsi_int_st0);
373 read32(&mipi_regs->dsi_int_st1);
374 write32(&mipi_regs->dsi_int_msk0, 0);
375 write32(&mipi_regs->dsi_int_msk1, 0);
378 static void rk_mipi_dsi_dphy_interface_config(struct rk_mipi_dsi *dsi)
380 write32(&mipi_regs->dsi_phy_if_cfg, PHY_STOP_WAIT_TIME(0x20) |
381 N_LANES(dsi->lanes));
384 static void rk_mipi_dsi_set_mode(struct rk_mipi_dsi *dsi,
385 enum rk_mipi_dsi_mode mode)
387 write32(&mipi_regs->dsi_pwr_up, RESET);
388 if (mode == MIPI_DSI_CMD_MODE) {
389 write32(&mipi_regs->dsi_mode_cfg, ENABLE_CMD_MODE);
390 } else {
391 write32(&mipi_regs->dsi_mode_cfg, ENABLE_VIDEO_MODE);
392 rk_mipi_dsi_video_mode_config(dsi);
393 write32(&mipi_regs->dsi_lpclk_ctrl, PHY_TXREQUESTCLKHS);
395 write32(&mipi_regs->dsi_pwr_up, POWERUP);
398 static void rk_mipi_dsi_init(struct rk_mipi_dsi *dsi)
401 * The maximum permitted escape clock is 20MHz and it is derived from
402 * lanebyteclk, which is running at "lane_mbps / 8". Thus we want:
404 * (lane_mbps >> 3) / esc_clk_division < 20
405 * which is:
406 * (lane_mbps >> 3) / 20 > esc_clk_division
408 u32 esc_clk_division = div_round_up(dsi->lane_bps, 8 * 20 * USECS_PER_SEC);
410 write32(&mipi_regs->dsi_pwr_up, RESET);
411 write32(&mipi_regs->dsi_phy_rstz, PHY_DISFORCEPLL | PHY_DISABLECLK |
412 PHY_RSTZ | PHY_SHUTDOWNZ);
413 write32(&mipi_regs->dsi_clk_cfg,
414 TO_CLK_DIVIDSION(10) |
415 TX_ESC_CLK_DIVIDSION(esc_clk_division));
418 static int rk_mipi_dsi_dcs_transfer(struct rk_mipi_dsi *dsi, u32 hdr_val)
420 int ret;
422 hdr_val = GEN_HDATA(hdr_val) | GEN_HTYPE(0x05);
423 ret = read32(&mipi_regs->dsi_cmd_pkt_status);
424 if (ret < 0) {
425 printk(BIOS_DEBUG, "failed to get available command FIFO\n");
426 return ret;
429 write32(&mipi_regs->dsi_lpclk_ctrl, 0);
430 write32(&mipi_regs->dsi_cmd_mode_cfg, CMD_MODE_ALL_LP);
431 write32(&mipi_regs->dsi_gen_hdr, hdr_val);
433 return 0;
436 void rk_mipi_prepare(const struct edid *edid, u32 display_on_mdelay, u32 video_mode_mdelay)
438 rk_mipi.lanes = 4;
439 rk_mipi.format = MIPI_DSI_FMT_RGB888;
440 if (rk_mipi_dsi_get_lane_bps(&rk_mipi, edid) < 0)
441 return;
443 rk_mipi_dsi_init(&rk_mipi);
444 rk_mipi_dsi_dpi_config(&rk_mipi);
445 rk_mipi_dsi_packet_handler_config(&rk_mipi);
446 rk_mipi_dsi_video_mode_config(&rk_mipi);
447 rk_mipi_dsi_video_packet_config(&rk_mipi);
448 rk_mipi_dsi_command_mode_config(&rk_mipi);
449 rk_mipi_dsi_line_timer_config(&rk_mipi, edid);
450 rk_mipi_dsi_vertical_timing_config(&rk_mipi, edid);
451 rk_mipi_dsi_dphy_timing_config(&rk_mipi);
452 rk_mipi_dsi_dphy_interface_config(&rk_mipi);
453 rk_mipi_dsi_clear_err(&rk_mipi);
454 if (rk_mipi_dsi_phy_init(&rk_mipi) < 0)
455 return;
456 rk_mipi_dsi_wait_for_two_frames(&rk_mipi, edid);
458 rk_mipi_dsi_set_mode(&rk_mipi, MIPI_DSI_CMD_MODE);
459 if (rk_mipi_dsi_dcs_transfer(&rk_mipi, MIPI_DCS_EXIT_SLEEP_MODE) < 0)
460 return;
461 mdelay(display_on_mdelay);
462 if (rk_mipi_dsi_dcs_transfer(&rk_mipi, MIPI_DCS_SET_DISPLAY_ON) < 0)
463 return;
464 mdelay(video_mode_mdelay);
466 rk_mipi_dsi_set_mode(&rk_mipi, MIPI_DSI_VID_MODE);