[coreboot-gerrit] Change in coreboot[master]: rockchip/rk3399: support dual mipi dsi

Lin Huang (Code Review) gerrit at coreboot.org
Wed Nov 15 04:28:17 CET 2017


Lin Huang has uploaded this change for review. ( https://review.coreboot.org/22471


Change subject: rockchip/rk3399: support dual mipi dsi
......................................................................

rockchip/rk3399: support dual mipi dsi

Refactor the mipi driver, so we can support dual mipi panel.
And pass the panel data through devicetree.cb, that we can
support different panel with different board.

Change-Id: Id1286c0ccbe50c89514c8daee66439116d3f1ca4
Signed-off-by: Lin Huang <hl at rock-chips.com>
---
M src/soc/rockchip/common/include/soc/vop.h
M src/soc/rockchip/common/vop.c
M src/soc/rockchip/rk3399/chip.h
M src/soc/rockchip/rk3399/display.c
M src/soc/rockchip/rk3399/include/soc/addressmap.h
M src/soc/rockchip/rk3399/include/soc/mipi.h
M src/soc/rockchip/rk3399/mipi.c
7 files changed, 210 insertions(+), 102 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/71/22471/1

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

-- 
To view, visit https://review.coreboot.org/22471
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Id1286c0ccbe50c89514c8daee66439116d3f1ca4
Gerrit-Change-Number: 22471
Gerrit-PatchSet: 1
Gerrit-Owner: Lin Huang <hl at rock-chips.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171115/5775c542/attachment-0001.html>


More information about the coreboot-gerrit mailing list