<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>