<p>Lin Huang has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/22471">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">rockchip/rk3399: support dual mipi dsi<br><br>Refactor the mipi driver, so we can support dual mipi panel.<br>And pass the panel data through devicetree.cb, that we can<br>support different panel with different board.<br><br>Change-Id: Id1286c0ccbe50c89514c8daee66439116d3f1ca4<br>Signed-off-by: Lin Huang <hl@rock-chips.com><br>---<br>M src/soc/rockchip/common/include/soc/vop.h<br>M src/soc/rockchip/common/vop.c<br>M src/soc/rockchip/rk3399/chip.h<br>M src/soc/rockchip/rk3399/display.c<br>M src/soc/rockchip/rk3399/include/soc/addressmap.h<br>M src/soc/rockchip/rk3399/include/soc/mipi.h<br>M src/soc/rockchip/rk3399/mipi.c<br>7 files changed, 210 insertions(+), 102 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/71/22471/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/rockchip/common/include/soc/vop.h b/src/soc/rockchip/common/include/soc/vop.h<br>index c5c5425..9119cd3 100644<br>--- a/src/soc/rockchip/common/include/soc/vop.h<br>+++ b/src/soc/rockchip/common/include/soc/vop.h<br>@@ -120,6 +120,7 @@<br> VOP_MODE_EDP = 0,<br> VOP_MODE_HDMI,<br> VOP_MODE_MIPI,<br>+ VOP_MODE_DUAL_MIPI,<br> VOP_MODE_NONE,<br> VOP_MODE_AUTO_DETECT,<br> VOP_MODE_UNKNOWN,<br>@@ -154,6 +155,7 @@<br> #define V_MMU_EN(x) (((x) & 1) << 20)<br> #define V_DMA_BURST_LENGTH(x) (((x) & 3) << 18)<br> #define V_MIPI_OUT_EN(x) (((x) & 1) << 15)<br>+#define V_DUAL_MIPI_EN(x) (((x) & 1) << 3)<br> #define V_EDP_OUT_EN(x) (((x) & 1) << 14)<br> #define V_HDMI_OUT_EN(x) (((x) & 1) << 13)<br> #define V_RGB_OUT_EN(x) (((x) & 1) << 12)<br>diff --git a/src/soc/rockchip/common/vop.c b/src/soc/rockchip/common/vop.c<br>index 70d59bd..4631591 100644<br>--- a/src/soc/rockchip/common/vop.c<br>+++ b/src/soc/rockchip/common/vop.c<br>@@ -119,8 +119,13 @@<br> dsp_out_mode = 15;<br> break;<br> case VOP_MODE_MIPI:<br>- clrsetbits_le32(&preg->sys_ctrl,<br>- M_ALL_OUT_EN, V_MIPI_OUT_EN(1));<br>+ clrsetbits_le32(&preg->sys_ctrl, M_ALL_OUT_EN,<br>+ V_MIPI_OUT_EN(1));<br>+ dsp_out_mode = 0;<br>+ break;<br>+ case VOP_MODE_DUAL_MIPI:<br>+ clrsetbits_le32(&preg->sys_ctrl, M_ALL_OUT_EN,<br>+ V_MIPI_OUT_EN(1) | V_DUAL_MIPI_EN(1));<br> dsp_out_mode = 0;<br> break;<br> case VOP_MODE_EDP:<br>diff --git a/src/soc/rockchip/rk3399/chip.h b/src/soc/rockchip/rk3399/chip.h<br>index 4b2ccc5..71b54af 100644<br>--- a/src/soc/rockchip/rk3399/chip.h<br>+++ b/src/soc/rockchip/rk3399/chip.h<br>@@ -25,6 +25,9 @@<br> u32 bl_power_on_udelay;<br> u32 bl_pwm_to_enable_udelay;<br> u32 framebuffer_bits_per_pixel;<br>+ u32 panel_dual_mipi;<br>+ u32 panel_format;<br>+ u32 panel_lanes;<br> u32 vop_mode;<br> u32 panel_pixel_clock; /* below only be considered for MIPI displays */<br> u32 panel_refresh;<br>@@ -38,6 +41,8 @@<br> u32 panel_vspw;<br> u32 panel_display_on_mdelay;<br> u32 panel_video_mode_mdelay;<br>+ u32 panel_need_init;<br>+ char panel_init_data[250];<br> };<br> <br> #endif /* __SOC_ROCKCHIP_RK3399_CHIP_H__ */<br>diff --git a/src/soc/rockchip/rk3399/display.c b/src/soc/rockchip/rk3399/display.c<br>index 379e1bf..e532837 100644<br>--- a/src/soc/rockchip/rk3399/display.c<br>+++ b/src/soc/rockchip/rk3399/display.c<br>@@ -48,9 +48,11 @@<br> printk(BIOS_WARNING, "Retrying epd initialization.\n");<br> }<br> <br>-static void rk_get_mipi_mode(struct edid *edid, device_t dev)<br>+static void rk_get_mipi_mode(device_t dev, struct edid *edid,<br>+ struct mipi_panel_data *panel_data)<br> {<br> struct soc_rockchip_rk3399_config *conf = dev->chip_info;<br>+ int init_data_size = 0;<br> <br> edid->mode.pixel_clock = conf->panel_pixel_clock;<br> edid->mode.refresh = conf->panel_refresh;<br>@@ -62,13 +64,27 @@<br> edid->mode.vbl = conf->panel_vbl;<br> edid->mode.vso = conf->panel_vso;<br> edid->mode.vspw = conf->panel_vspw;<br>+ panel_data->dual_mipi_enable = conf->panel_dual_mipi;<br>+ panel_data->format = conf->panel_format;<br>+ panel_data->lanes = conf->panel_lanes;<br>+ panel_data->display_on_mdelay = conf->panel_display_on_mdelay;<br>+ panel_data->video_mode_mdelay = conf->panel_video_mode_mdelay;<br>+ if (conf->panel_need_init) {<br>+ init_data_size = sizeof(conf->panel_init_data);<br>+ panel_data->init_data_size = init_data_size;<br>+ panel_data->init_data = malloc(init_data_size);<br>+ memcpy(panel_data->init_data, conf->panel_init_data,<br>+ init_data_size);<br>+ }<br> }<br>+<br> void rk_display_init(device_t dev)<br> {<br> struct edid edid;<br> struct soc_rockchip_rk3399_config *conf = dev->chip_info;<br> enum vop_modes detected_mode = VOP_MODE_UNKNOWN;<br> int retry_count = 0;<br>+ struct mipi_panel_data panel_data;<br> <br> /* let's use vop0 in rk3399 */<br> uint32_t vop_id = 0;<br>@@ -113,11 +129,19 @@<br> <br> /* disable turnrequest turndisable forcetxstop forcerxmode */<br> write32(&rk3399_grf->soc_con22, RK_CLRBITS(0xffff));<br>- /* select mipi-dsi0 signal from vop0 */<br>- write32(&rk3399_grf->soc_con20, RK_CLRBITS(1 << 0));<br>+ write32(&rk3399_grf->soc_con23, RK_CLRBITS(0xffff));<br>+ write32(&rk3399_grf->soc_con24, 0xe00080);<br>+ write32(&rk3399_grf->soc_con23, 0xf000f);<br> <br>- rk_get_mipi_mode(&edid, dev);<br>- detected_mode = VOP_MODE_MIPI;<br>+ /* select mipi-dsi0 and mipi-dsi1 signal from vop0 */<br>+ write32(&rk3399_grf->soc_con20,<br>+ RK_CLRBITS((1 << 0) | (1 << 4)));<br>+<br>+ rk_get_mipi_mode(dev, &edid, &panel_data);<br>+ if (panel_data.dual_mipi_enable)<br>+ detected_mode = VOP_MODE_DUAL_MIPI;<br>+ else<br>+ detected_mode = VOP_MODE_MIPI;<br> break;<br> default:<br> printk(BIOS_WARNING, "Unsupported vop_mode, aborting.\n");<br>@@ -138,7 +162,8 @@<br> <br> switch (detected_mode) {<br> case VOP_MODE_MIPI:<br>- rk_mipi_prepare(&edid, conf->panel_display_on_mdelay, conf->panel_video_mode_mdelay);<br>+ case VOP_MODE_DUAL_MIPI:<br>+ rk_mipi_prepare(&edid, &panel_data);<br> break;<br> case VOP_MODE_EDP:<br> /* will enable edp in depthcharge */<br>diff --git a/src/soc/rockchip/rk3399/include/soc/addressmap.h b/src/soc/rockchip/rk3399/include/soc/addressmap.h<br>index 7a365ad..5dca6bb 100644<br>--- a/src/soc/rockchip/rk3399/include/soc/addressmap.h<br>+++ b/src/soc/rockchip/rk3399/include/soc/addressmap.h<br>@@ -59,7 +59,8 @@<br> #define SARADC_BASE 0xff100000<br> #define RK_PWM_BASE 0xff420000<br> #define EDP_BASE 0xff970000<br>-#define MIPI_BASE 0xff960000<br>+#define MIPI0_BASE 0xff960000<br>+#define MIPI1_BASE 0xff968000<br> <br> #define VOP_BIG_BASE 0xff900000 /* corresponds to vop_id 0 */<br> #define VOP_LIT_BASE 0xff8f0000 /* corresponds to vop_id 1 */<br>diff --git a/src/soc/rockchip/rk3399/include/soc/mipi.h b/src/soc/rockchip/rk3399/include/soc/mipi.h<br>index f427376..0b0c382 100644<br>--- a/src/soc/rockchip/rk3399/include/soc/mipi.h<br>+++ b/src/soc/rockchip/rk3399/include/soc/mipi.h<br>@@ -262,8 +262,9 @@<br> #define GEN_PLD_R_FULL BIT(5)<br> #define GEN_RD_CMD_BUSY BIT(6)<br> <br>-#define MIPI_DSI_DCS_SHORT_WRITE 0x05<br>-#define MIPI_DSI_DCS_LONG_WRITE 0x39<br>+#define MIPI_DSI_DCS_SHORT_WRITE 0x05<br>+#define MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM 0x23<br>+#define MIPI_DSI_DCS_LONG_WRITE 0x39<br> <br> enum mipi_dsi_pixel_format {<br> MIPI_DSI_FMT_RGB888,<br>@@ -313,6 +314,7 @@<br> };<br> <br> struct rk_mipi_dsi {<br>+ struct rk_mipi_regs *mipi_regs;<br> u64 lane_bps; /* per lane */<br> u32 lanes;<br> u32 format;<br>@@ -320,5 +322,16 @@<br> u16 feedback_div;<br> };<br> <br>-void rk_mipi_prepare(const struct edid *edid, u32 display_on_mdelay, u32 video_mode_mdelay);<br>+struct mipi_panel_data {<br>+ u32 dual_mipi_enable;<br>+ u32 format;<br>+ u32 lanes;<br>+ u32 display_on_mdelay;<br>+ u32 video_mode_mdelay;<br>+ u32 init_data_size;<br>+ char *init_data;<br>+};<br>+<br>+void rk_mipi_prepare(const struct edid *edid,<br>+ struct mipi_panel_data *panel_data);<br> #endif<br>diff --git a/src/soc/rockchip/rk3399/mipi.c b/src/soc/rockchip/rk3399/mipi.c<br>index f0a20c4..39e93c7 100644<br>--- a/src/soc/rockchip/rk3399/mipi.c<br>+++ b/src/soc/rockchip/rk3399/mipi.c<br>@@ -30,8 +30,8 @@<br> #include <soc/soc.h><br> #include <timer.h><br> <br>-static struct rk_mipi_dsi rk_mipi;<br>-static struct rk_mipi_regs *mipi_regs = (void *)MIPI_BASE;<br>+static struct rk_mipi_dsi rk_mipi0;<br>+static struct rk_mipi_dsi rk_mipi1;<br> <br> /*<br> * The controller should generate 2 frames before<br>@@ -110,17 +110,20 @@<br> * is latched internally as the current test code. Test data is<br> * programmed internally by rising edge on TESTCLK.<br> */<br>- write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_TESTCLK | PHY_UNTESTCLR);<br>+ write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0,<br>+ PHY_TESTCLK | PHY_UNTESTCLR);<br> <br>- write32(&mipi_regs->dsi_phy_tst_ctrl1, PHY_TESTEN | PHY_TESTDOUT(0) |<br>- PHY_TESTDIN(test_code));<br>+ write32(&dsi->mipi_regs->dsi_phy_tst_ctrl1,<br>+ PHY_TESTEN | PHY_TESTDOUT(0) | PHY_TESTDIN(test_code));<br> <br>- write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLK | PHY_UNTESTCLR);<br>+ write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0,<br>+ PHY_UNTESTCLK | PHY_UNTESTCLR);<br> <br>- write32(&mipi_regs->dsi_phy_tst_ctrl1, PHY_UNTESTEN | PHY_TESTDOUT(0) |<br>- PHY_TESTDIN(test_data));<br>+ write32(&dsi->mipi_regs->dsi_phy_tst_ctrl1,<br>+ PHY_UNTESTEN | PHY_TESTDOUT(0) | PHY_TESTDIN(test_data));<br> <br>- write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_TESTCLK | PHY_UNTESTCLR);<br>+ write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0,<br>+ PHY_TESTCLK | PHY_UNTESTCLR);<br> }<br> <br> /* bytes_per_ns - Nanoseconds to byte clock cycles */<br>@@ -142,7 +145,7 @@<br> <br> stopwatch_init_msecs_expire(&sw, 20);<br> do {<br>- val = read32(&mipi_regs->dsi_phy_status);<br>+ val = read32(&dsi->mipi_regs->dsi_phy_status);<br> if (val & LOCK)<br> return 0;<br> } while (!stopwatch_expired(&sw));<br>@@ -166,9 +169,9 @@<br> }<br> <br> /* Start by clearing PHY state */<br>- write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLR);<br>- write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_TESTCLR);<br>- write32(&mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLR);<br>+ write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLR);<br>+ write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0, PHY_TESTCLR);<br>+ write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLR);<br> <br> rk_mipi_dsi_phy_write(dsi, PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL,<br> BYPASS_VCO_RANGE |<br>@@ -244,8 +247,9 @@<br> rk_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL,<br> BIT(5) | bytes_per_ns(dsi, 100));<br> <br>- write32(&mipi_regs->dsi_phy_rstz, PHY_ENFORCEPLL | PHY_ENABLECLK |<br>- PHY_UNRSTZ | PHY_UNSHUTDOWNZ);<br>+ write32(&dsi->mipi_regs->dsi_phy_rstz,<br>+ PHY_ENFORCEPLL | PHY_ENABLECLK |<br>+ PHY_UNRSTZ | PHY_UNSHUTDOWNZ);<br> <br> if (rk_mipi_dsi_wait_phy_lock(dsi)) {<br> printk(BIOS_ERR, "failed to wait for phy lock state\n");<br>@@ -254,7 +258,7 @@<br> <br> stopwatch_init_msecs_expire(&sw, 20);<br> do {<br>- val = read32(&mipi_regs->dsi_phy_status);<br>+ val = read32(&dsi->mipi_regs->dsi_phy_status);<br> if (val & STOP_STATE_CLK_LANE)<br> return 0;<br> } while (!stopwatch_expired(&sw));<br>@@ -281,11 +285,13 @@<br> }<br> <br> static int rk_mipi_dsi_get_lane_bps(struct rk_mipi_dsi *dsi,<br>- const struct edid *edid)<br>+ const struct edid *edid,<br>+ const struct mipi_panel_data *panel_data)<br> {<br> u64 pclk, target_bps;<br> u32 max_bps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps * MHz;<br> int bpp;<br>+ u32 lanes = dsi->lanes;<br> u64 best_freq = 0;<br> u64 fvco_min, fvco_max, fref;<br> u32 min_prediv, max_prediv;<br>@@ -301,8 +307,11 @@<br> }<br> pclk = edid->mode.pixel_clock * MSECS_PER_SEC;<br> <br>+ if (panel_data->dual_mipi_enable)<br>+ lanes = dsi->lanes * 2;<br>+<br> /* take 1 / 0.8, since mbps must bigger than bandwidth of RGB */<br>- target_bps = pclk / dsi->lanes * bpp / 8 * 10;<br>+ target_bps = pclk / lanes * bpp / 8 * 10;<br> if (target_bps >= max_bps) {<br> printk(BIOS_DEBUG, "DPHY clock frequency is out of range\n");<br> return -1;<br>@@ -381,38 +390,48 @@<br> break;<br> }<br> <br>- write32(&mipi_regs->dsi_dpi_vcid, 0);<br>- write32(&mipi_regs->dsi_dpi_color_coding, color);<br>+ write32(&dsi->mipi_regs->dsi_dpi_vcid, 0);<br>+ write32(&dsi->mipi_regs->dsi_dpi_color_coding, color);<br> <br>- write32(&mipi_regs->dsi_dpi_cfg_pol, 0);<br>+ write32(&dsi->mipi_regs->dsi_dpi_cfg_pol, 0);<br> <br>- write32(&mipi_regs->dsi_dpi_lp_cmd_tim, OUTVACT_LPCMD_TIME(4) |<br>- INVACT_LPCMD_TIME(4));<br>+ write32(&dsi->mipi_regs->dsi_dpi_lp_cmd_tim,<br>+ OUTVACT_LPCMD_TIME(4) | INVACT_LPCMD_TIME(4));<br> }<br> <br> static void rk_mipi_dsi_packet_handler_config(struct rk_mipi_dsi *dsi)<br> {<br>- write32(&mipi_regs->dsi_pckhdl_cfg, EN_CRC_RX | EN_ECC_RX | EN_BTA);<br>+ write32(&dsi->mipi_regs->dsi_pckhdl_cfg,<br>+ EN_CRC_RX | EN_ECC_RX | EN_BTA);<br> }<br> <br> static void rk_mipi_dsi_video_mode_config(struct rk_mipi_dsi *dsi)<br> {<br>- write32(&mipi_regs->dsi_vid_mode_cfg,<br>+ write32(&dsi->mipi_regs->dsi_vid_mode_cfg,<br> VID_MODE_TYPE_BURST_SYNC_PULSES | ENABLE_LOW_POWER);<br> }<br> <br>-static void rk_mipi_dsi_video_packet_config(struct rk_mipi_dsi *dsi)<br>+static void rk_mipi_dsi_video_packet_config(struct rk_mipi_dsi *dsi,<br>+ const struct edid *edid,<br>+ struct mipi_panel_data *panel_data)<br> {<br>- write32(&mipi_regs->dsi_vid_pkt_size, VID_PKT_SIZE(0x300));<br>+ int pkt_size;<br>+<br>+ if (panel_data->dual_mipi_enable)<br>+ pkt_size = VID_PKT_SIZE(edid->mode.ha / 2 + 4);<br>+ else<br>+ pkt_size = VID_PKT_SIZE(edid->mode.ha);<br>+<br>+ write32(&dsi->mipi_regs->dsi_vid_pkt_size, pkt_size);<br> }<br> <br> static void rk_mipi_dsi_command_mode_config(struct rk_mipi_dsi *dsi)<br> {<br>- write32(&mipi_regs->dsi_to_cnt_cfg,<br>+ write32(&dsi->mipi_regs->dsi_to_cnt_cfg,<br> HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));<br>- write32(&mipi_regs->dsi_bta_to_cnt, 0xd00);<br>- write32(&mipi_regs->dsi_cmd_mode_cfg, CMD_MODE_ALL_LP);<br>- write32(&mipi_regs->dsi_mode_cfg, ENABLE_CMD_MODE);<br>+ write32(&dsi->mipi_regs->dsi_bta_to_cnt, 0xd00);<br>+ write32(&dsi->mipi_regs->dsi_cmd_mode_cfg, CMD_MODE_ALL_LP);<br>+ write32(&dsi->mipi_regs->dsi_mode_cfg, ENABLE_CMD_MODE);<br> }<br> <br> /* Get lane byte clock cycles. */<br>@@ -439,12 +458,12 @@<br> hbp = edid->mode.hbl - edid->mode.hso - edid->mode.hspw;<br> <br> lbcc = rk_mipi_dsi_get_hcomponent_lbcc(dsi, htotal, edid);<br>- write32(&mipi_regs->dsi_vid_hline_time, lbcc);<br>+ write32(&dsi->mipi_regs->dsi_vid_hline_time, lbcc);<br> <br> lbcc = rk_mipi_dsi_get_hcomponent_lbcc(dsi, hsa, edid);<br>- write32(&mipi_regs->dsi_vid_hsa_time, lbcc);<br>+ write32(&dsi->mipi_regs->dsi_vid_hsa_time, lbcc);<br> lbcc = rk_mipi_dsi_get_hcomponent_lbcc(dsi, hbp, edid);<br>- write32(&mipi_regs->dsi_vid_hbp_time, lbcc);<br>+ write32(&dsi->mipi_regs->dsi_vid_hbp_time, lbcc);<br> }<br> <br> static void rk_mipi_dsi_vertical_timing_config(struct rk_mipi_dsi *dsi,<br>@@ -457,10 +476,10 @@<br> vfp = edid->mode.vso;<br> vbp = edid->mode.vbl - edid->mode.vso - edid->mode.vspw;<br> <br>- write32(&mipi_regs->dsi_vid_vactive_lines, vactive);<br>- write32(&mipi_regs->dsi_vid_vsa_lines, vsa);<br>- write32(&mipi_regs->dsi_vid_vfp_lines, vfp);<br>- write32(&mipi_regs->dsi_vid_vbp_lines, vbp);<br>+ write32(&dsi->mipi_regs->dsi_vid_vactive_lines, vactive);<br>+ write32(&dsi->mipi_regs->dsi_vid_vsa_lines, vsa);<br>+ write32(&dsi->mipi_regs->dsi_vid_vfp_lines, vfp);<br>+ write32(&dsi->mipi_regs->dsi_vid_vbp_lines, vbp);<br> }<br> <br> static void rk_mipi_dsi_dphy_timing_config(struct rk_mipi_dsi *dsi)<br>@@ -469,40 +488,40 @@<br> * HS-PREPARE: 40ns + 4 * UI ~ 85ns + 6 * UI<br> * HS-EXIT: 100ns<br> */<br>- write32(&mipi_regs->dsi_phy_tmr_cfg, PHY_HS2LP_TIME(0x40) |<br>+ write32(&dsi->mipi_regs->dsi_phy_tmr_cfg, PHY_HS2LP_TIME(0x40) |<br> PHY_LP2HS_TIME(0x40) |<br> MAX_RD_TIME(10000));<br> <br>- write32(&mipi_regs->dsi_phy_tmr_lpclk_cfg, PHY_CLKHS2LP_TIME(0x40) |<br>- PHY_CLKLP2HS_TIME(0x40));<br>+ write32(&dsi->mipi_regs->dsi_phy_tmr_lpclk_cfg,<br>+ PHY_CLKHS2LP_TIME(0x40) | PHY_CLKLP2HS_TIME(0x40));<br> }<br> <br> static void rk_mipi_dsi_clear_err(struct rk_mipi_dsi *dsi)<br> {<br>- read32(&mipi_regs->dsi_int_st0);<br>- read32(&mipi_regs->dsi_int_st1);<br>- write32(&mipi_regs->dsi_int_msk0, 0);<br>- write32(&mipi_regs->dsi_int_msk1, 0);<br>+ read32(&dsi->mipi_regs->dsi_int_st0);<br>+ read32(&dsi->mipi_regs->dsi_int_st1);<br>+ write32(&dsi->mipi_regs->dsi_int_msk0, 0);<br>+ write32(&dsi->mipi_regs->dsi_int_msk1, 0);<br> }<br> <br> static void rk_mipi_dsi_dphy_interface_config(struct rk_mipi_dsi *dsi)<br> {<br>- write32(&mipi_regs->dsi_phy_if_cfg, PHY_STOP_WAIT_TIME(0x20) |<br>+ write32(&dsi->mipi_regs->dsi_phy_if_cfg, PHY_STOP_WAIT_TIME(0x20) |<br> N_LANES(dsi->lanes));<br> }<br> <br> static void rk_mipi_dsi_set_mode(struct rk_mipi_dsi *dsi,<br> enum rk_mipi_dsi_mode mode)<br> {<br>- write32(&mipi_regs->dsi_pwr_up, RESET);<br>+ write32(&dsi->mipi_regs->dsi_pwr_up, RESET);<br> if (mode == MIPI_DSI_CMD_MODE) {<br>- write32(&mipi_regs->dsi_mode_cfg, ENABLE_CMD_MODE);<br>+ write32(&dsi->mipi_regs->dsi_mode_cfg, ENABLE_CMD_MODE);<br> } else {<br>- write32(&mipi_regs->dsi_mode_cfg, ENABLE_VIDEO_MODE);<br>+ write32(&dsi->mipi_regs->dsi_mode_cfg, ENABLE_VIDEO_MODE);<br> rk_mipi_dsi_video_mode_config(dsi);<br>- write32(&mipi_regs->dsi_lpclk_ctrl, PHY_TXREQUESTCLKHS);<br>+ write32(&dsi->mipi_regs->dsi_lpclk_ctrl, PHY_TXREQUESTCLKHS);<br> }<br>- write32(&mipi_regs->dsi_pwr_up, POWERUP);<br>+ write32(&dsi->mipi_regs->dsi_pwr_up, POWERUP);<br> }<br> <br> static void rk_mipi_dsi_init(struct rk_mipi_dsi *dsi)<br>@@ -515,20 +534,21 @@<br> * which is:<br> * (lane_mbps >> 3) / 20 > esc_clk_division<br> */<br>- u32 esc_clk_division = div_round_up(dsi->lane_bps, 8 * 20 * USECS_PER_SEC);<br>+ u32 esc_clk_division = div_round_up(dsi->lane_bps,<br>+ 8 * 20 * USECS_PER_SEC);<br> <br>- write32(&mipi_regs->dsi_pwr_up, RESET);<br>- write32(&mipi_regs->dsi_phy_rstz, PHY_DISFORCEPLL | PHY_DISABLECLK |<br>- PHY_RSTZ | PHY_SHUTDOWNZ);<br>- write32(&mipi_regs->dsi_clk_cfg,<br>+ write32(&dsi->mipi_regs->dsi_pwr_up, RESET);<br>+ write32(&dsi->mipi_regs->dsi_phy_rstz,<br>+ PHY_DISFORCEPLL | PHY_DISABLECLK | PHY_RSTZ | PHY_SHUTDOWNZ);<br>+ write32(&dsi->mipi_regs->dsi_clk_cfg,<br> TO_CLK_DIVIDSION(10) |<br> TX_ESC_CLK_DIVIDSION(esc_clk_division));<br> }<br> <br> static void rk_mipi_message_config(struct rk_mipi_dsi *dsi)<br> {<br>- write32(&mipi_regs->dsi_lpclk_ctrl, 0);<br>- write32(&mipi_regs->dsi_cmd_mode_cfg, CMD_MODE_ALL_LP);<br>+ write32(&dsi->mipi_regs->dsi_lpclk_ctrl, 0);<br>+ write32(&dsi->mipi_regs->dsi_cmd_mode_cfg, CMD_MODE_ALL_LP);<br> }<br> <br> static int rk_mipi_dsi_check_cmd_fifo(struct rk_mipi_dsi *dsi)<br>@@ -538,7 +558,7 @@<br> <br> stopwatch_init_msecs_expire(&sw, 20);<br> do {<br>- val = read32(&mipi_regs->dsi_cmd_pkt_status);<br>+ val = read32(&dsi->mipi_regs->dsi_cmd_pkt_status);<br> if (!(val & GEN_CMD_FULL))<br> return 0 ;<br> } while (!stopwatch_expired(&sw));<br>@@ -557,12 +577,12 @@<br> return 1;<br> }<br> <br>- write32(&mipi_regs->dsi_gen_hdr, hdr_val);<br>+ write32(&dsi->mipi_regs->dsi_gen_hdr, hdr_val);<br> <br> mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;<br> stopwatch_init_msecs_expire(&sw, 20);<br> do {<br>- val = read32(&mipi_regs->dsi_cmd_pkt_status);<br>+ val = read32(&dsi->mipi_regs->dsi_cmd_pkt_status);<br> if ((val & mask) == mask)<br> return 0 ;<br> } while (!stopwatch_expired(&sw));<br>@@ -583,43 +603,80 @@<br> return rk_mipi_dsi_gen_pkt_hdr_write(dsi, val);<br> }<br> <br>-void rk_mipi_prepare(const struct edid *edid, u32 display_on_mdelay, u32 video_mode_mdelay)<br>+static void rk_mipi_enable(struct rk_mipi_dsi *dsi,<br>+ const struct edid *edid,<br>+ struct mipi_panel_data *panel_data)<br>+{<br>+ if (rk_mipi_dsi_get_lane_bps(dsi, edid, panel_data) < 0)<br>+ return;<br>+<br>+ rk_mipi_dsi_init(dsi);<br>+ rk_mipi_dsi_dpi_config(dsi);<br>+ rk_mipi_dsi_packet_handler_config(dsi);<br>+ rk_mipi_dsi_video_mode_config(dsi);<br>+ rk_mipi_dsi_video_packet_config(dsi, edid, panel_data);<br>+ rk_mipi_dsi_command_mode_config(dsi);<br>+ rk_mipi_dsi_line_timer_config(dsi, edid);<br>+ rk_mipi_dsi_vertical_timing_config(dsi, edid);<br>+ rk_mipi_dsi_dphy_timing_config(dsi);<br>+ rk_mipi_dsi_dphy_interface_config(dsi);<br>+ rk_mipi_dsi_clear_err(dsi);<br>+ if (rk_mipi_dsi_phy_init(dsi) < 0)<br>+ return;<br>+ rk_mipi_dsi_wait_for_two_frames(dsi, edid);<br>+<br>+ rk_mipi_dsi_set_mode(dsi, MIPI_DSI_CMD_MODE);<br>+}<br>+<br>+void rk_mipi_prepare(const struct edid *edid,<br>+ struct mipi_panel_data *panel_data)<br> {<br> u16 value;<br>+ u16 *init_data = (u16 *)panel_data->init_data;<br>+ int i;<br> <br>- rk_mipi.lanes = 4;<br>- rk_mipi.format = MIPI_DSI_FMT_RGB888;<br>- if (rk_mipi_dsi_get_lane_bps(&rk_mipi, edid) < 0)<br>- return;<br>+ rk_mipi0.mipi_regs = (void *)MIPI0_BASE;<br>+ rk_mipi0.lanes = panel_data->lanes;<br>+ rk_mipi0.format = panel_data->format;<br>+ if (panel_data->dual_mipi_enable) {<br>+ rk_mipi1.mipi_regs = (void *)MIPI1_BASE;<br>+ rk_mipi0.lanes = panel_data->lanes / 2;<br>+ rk_mipi1.lanes = panel_data->lanes / 2;<br>+ rk_mipi1.format = panel_data->format;<br>+ }<br> <br>- rk_mipi_dsi_init(&rk_mipi);<br>- rk_mipi_dsi_dpi_config(&rk_mipi);<br>- rk_mipi_dsi_packet_handler_config(&rk_mipi);<br>- rk_mipi_dsi_video_mode_config(&rk_mipi);<br>- rk_mipi_dsi_video_packet_config(&rk_mipi);<br>- rk_mipi_dsi_command_mode_config(&rk_mipi);<br>- rk_mipi_dsi_line_timer_config(&rk_mipi, edid);<br>- rk_mipi_dsi_vertical_timing_config(&rk_mipi, edid);<br>- rk_mipi_dsi_dphy_timing_config(&rk_mipi);<br>- rk_mipi_dsi_dphy_interface_config(&rk_mipi);<br>- rk_mipi_dsi_clear_err(&rk_mipi);<br>- if (rk_mipi_dsi_phy_init(&rk_mipi) < 0)<br>- return;<br>- rk_mipi_dsi_wait_for_two_frames(&rk_mipi, edid);<br>+ rk_mipi_enable(&rk_mipi0, edid, panel_data);<br>+ if (panel_data->dual_mipi_enable)<br>+ rk_mipi_enable(&rk_mipi1, edid, panel_data);<br> <br>- rk_mipi_dsi_set_mode(&rk_mipi, MIPI_DSI_CMD_MODE);<br>+ for (i = 0; i < panel_data->init_data_size / sizeof(*init_data); i++) {<br>+ value = init_data[i];<br>+ rk_mipi_dsi_dcs_short_write(&rk_mipi0, value,<br>+ MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM);<br>+ if (panel_data->dual_mipi_enable)<br>+ rk_mipi_dsi_dcs_short_write(&rk_mipi1, value,<br>+ MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM);<br>+ }<br> <br> value = MIPI_DCS_EXIT_SLEEP_MODE;<br>- if (rk_mipi_dsi_dcs_short_write(&rk_mipi,<br>- value, MIPI_DSI_DCS_SHORT_WRITE) < 0)<br>+ if (rk_mipi_dsi_dcs_short_write(&rk_mipi0, value,<br>+ MIPI_DSI_DCS_SHORT_WRITE) < 0)<br> return;<br>- mdelay(display_on_mdelay);<br>-<br>+ if (panel_data->dual_mipi_enable)<br>+ if (rk_mipi_dsi_dcs_short_write(&rk_mipi1, value,<br>+ MIPI_DSI_DCS_SHORT_WRITE) < 0)<br>+ return;<br>+ mdelay(panel_data->display_on_mdelay);<br> value = MIPI_DCS_SET_DISPLAY_ON;<br>- if (rk_mipi_dsi_dcs_short_write(&rk_mipi,<br>- value, MIPI_DSI_DCS_SHORT_WRITE) < 0)<br>+ if (rk_mipi_dsi_dcs_short_write(&rk_mipi0, value,<br>+ MIPI_DSI_DCS_SHORT_WRITE) < 0)<br> return;<br>- mdelay(video_mode_mdelay);<br>-<br>- rk_mipi_dsi_set_mode(&rk_mipi, MIPI_DSI_VID_MODE);<br>+ if (panel_data->dual_mipi_enable)<br>+ if (rk_mipi_dsi_dcs_short_write(&rk_mipi1, value,<br>+ MIPI_DSI_DCS_SHORT_WRITE) < 0)<br>+ return;<br>+ mdelay(panel_data->video_mode_mdelay);<br>+ rk_mipi_dsi_set_mode(&rk_mipi0, MIPI_DSI_VID_MODE);<br>+ if (panel_data->dual_mipi_enable)<br>+ rk_mipi_dsi_set_mode(&rk_mipi1, MIPI_DSI_VID_MODE);<br> }<br></pre><p>To view, visit <a href="https://review.coreboot.org/22471">change 22471</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/22471"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Id1286c0ccbe50c89514c8daee66439116d3f1ca4 </div>
<div style="display:none"> Gerrit-Change-Number: 22471 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Lin Huang <hl@rock-chips.com> </div>