|
@@ -205,38 +205,124 @@ void dsi_phy_hw_v4_0_commit_phy_timing(struct dsi_phy_hw *phy,
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * enable() - Enable PHY hardware
|
|
|
+ * cphy_enable() - Enable CPHY hardware
|
|
|
* @phy: Pointer to DSI PHY hardware object.
|
|
|
* @cfg: Per lane configurations for timing, strength and lane
|
|
|
* configurations.
|
|
|
*/
|
|
|
-void dsi_phy_hw_v4_0_enable(struct dsi_phy_hw *phy,
|
|
|
+static void dsi_phy_hw_cphy_enable(struct dsi_phy_hw *phy,
|
|
|
struct dsi_phy_cfg *cfg)
|
|
|
{
|
|
|
- int rc = 0;
|
|
|
- u32 status;
|
|
|
- u32 const delay_us = 5;
|
|
|
- u32 const timeout_us = 1000;
|
|
|
struct dsi_phy_per_lane_cfgs *timing = &cfg->timing;
|
|
|
u32 data;
|
|
|
u32 minor_ver = 0;
|
|
|
- bool less_than_1500_mhz = false;
|
|
|
- u32 vreg_ctrl_0 = 0;
|
|
|
+ /* For C-PHY, no low power settings for lower clk rate */
|
|
|
+ u32 vreg_ctrl_0 = 0x51;
|
|
|
u32 glbl_str_swi_cal_sel_ctrl = 0;
|
|
|
u32 glbl_hstx_str_ctrl_0 = 0;
|
|
|
u32 glbl_rescode_top_ctrl = 0;
|
|
|
u32 glbl_rescode_bot_ctrl = 0;
|
|
|
|
|
|
- if (dsi_phy_hw_v4_0_is_pll_on(phy))
|
|
|
- DSI_PHY_WARN(phy, "PLL turned on before configuring PHY\n");
|
|
|
+ if (phy->version == DSI_PHY_VERSION_4_1) {
|
|
|
+ glbl_rescode_top_ctrl = 0x00;
|
|
|
+ glbl_rescode_bot_ctrl = 0x3C;
|
|
|
+ glbl_str_swi_cal_sel_ctrl = 0x00;
|
|
|
+ glbl_hstx_str_ctrl_0 = 0x88;
|
|
|
+ } else {
|
|
|
+ glbl_str_swi_cal_sel_ctrl = 0x03;
|
|
|
+ glbl_hstx_str_ctrl_0 = 0x66;
|
|
|
+ glbl_rescode_top_ctrl = 0x03;
|
|
|
+ glbl_rescode_bot_ctrl = 0x3c;
|
|
|
+ }
|
|
|
|
|
|
- /* wait for REFGEN READY */
|
|
|
- rc = readl_poll_timeout_atomic(phy->base + DSIPHY_CMN_PHY_STATUS,
|
|
|
- status, (status & BIT(0)), delay_us, timeout_us);
|
|
|
- if (rc) {
|
|
|
- DSI_PHY_ERR(phy, "Ref gen not ready. Aborting\n");
|
|
|
- return;
|
|
|
+ /* de-assert digital and pll power down */
|
|
|
+ data = BIT(6) | BIT(5);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_CTRL_0, data);
|
|
|
+
|
|
|
+ /* Assert PLL core reset */
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_PLL_CNTRL, 0x00);
|
|
|
+
|
|
|
+ /* turn off resync FIFO */
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_RBUF_CTRL, 0x00);
|
|
|
+
|
|
|
+ /* program CMN_CTRL_4 for minor_ver 2 chipsets*/
|
|
|
+ minor_ver = DSI_R32(phy, DSIPHY_CMN_REVISION_ID0);
|
|
|
+ minor_ver = minor_ver & (0xf0);
|
|
|
+ if (minor_ver == 0x20)
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_CTRL_4, 0x04);
|
|
|
+
|
|
|
+ /* Configure PHY lane swap */
|
|
|
+ dsi_phy_hw_v4_0_lane_swap_config(phy, &cfg->lane_map);
|
|
|
+
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_GLBL_CTRL, BIT(6));
|
|
|
+
|
|
|
+ /* Enable LDO */
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_0, vreg_ctrl_0);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_1, 0x55);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL,
|
|
|
+ glbl_str_swi_cal_sel_ctrl);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_GLBL_HSTX_STR_CTRL_0, glbl_hstx_str_ctrl_0);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_GLBL_PEMPH_CTRL_0, 0x11);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_GLBL_PEMPH_CTRL_1, 0x01);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL,
|
|
|
+ glbl_rescode_top_ctrl);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL,
|
|
|
+ glbl_rescode_bot_ctrl);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_GLBL_LPTX_STR_CTRL, 0x55);
|
|
|
+
|
|
|
+ /* Remove power down from all blocks */
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_CTRL_0, 0x7f);
|
|
|
+
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_LANE_CTRL0, 0x17);
|
|
|
+
|
|
|
+ switch (cfg->pll_source) {
|
|
|
+ case DSI_PLL_SOURCE_STANDALONE:
|
|
|
+ case DSI_PLL_SOURCE_NATIVE:
|
|
|
+ data = 0x0; /* internal PLL */
|
|
|
+ break;
|
|
|
+ case DSI_PLL_SOURCE_NON_NATIVE:
|
|
|
+ data = 0x1; /* external PLL */
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
}
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_CLK_CFG1, (data << 2)); /* set PLL src */
|
|
|
+
|
|
|
+ /* DSI PHY timings */
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_0, timing->lane_v4[0]);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_4, timing->lane_v4[4]);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_5, timing->lane_v4[5]);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_6, timing->lane_v4[6]);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_7, timing->lane_v4[7]);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_8, timing->lane_v4[8]);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_9, timing->lane_v4[9]);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_10, timing->lane_v4[10]);
|
|
|
+ DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_11, timing->lane_v4[11]);
|
|
|
+
|
|
|
+ /* DSI lane settings */
|
|
|
+ dsi_phy_hw_v4_0_lane_settings(phy, cfg);
|
|
|
+
|
|
|
+ DSI_PHY_DBG(phy, "C-Phy enabled\n");
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * dphy_enable() - Enable DPHY hardware
|
|
|
+ * @phy: Pointer to DSI PHY hardware object.
|
|
|
+ * @cfg: Per lane configurations for timing, strength and lane
|
|
|
+ * configurations.
|
|
|
+ */
|
|
|
+static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy,
|
|
|
+ struct dsi_phy_cfg *cfg)
|
|
|
+{
|
|
|
+ struct dsi_phy_per_lane_cfgs *timing = &cfg->timing;
|
|
|
+ u32 data;
|
|
|
+ u32 minor_ver = 0;
|
|
|
+ bool less_than_1500_mhz = false;
|
|
|
+ u32 vreg_ctrl_0 = 0;
|
|
|
+ u32 glbl_str_swi_cal_sel_ctrl = 0;
|
|
|
+ u32 glbl_hstx_str_ctrl_0 = 0;
|
|
|
+ u32 glbl_rescode_top_ctrl = 0;
|
|
|
+ u32 glbl_rescode_bot_ctrl = 0;
|
|
|
|
|
|
/* Alter PHY configurations if data rate less than 1.5GHZ*/
|
|
|
if (cfg->bit_clk_rate_hz <= 1500000000)
|
|
@@ -322,7 +408,39 @@ void dsi_phy_hw_v4_0_enable(struct dsi_phy_hw *phy,
|
|
|
/* DSI lane settings */
|
|
|
dsi_phy_hw_v4_0_lane_settings(phy, cfg);
|
|
|
|
|
|
- DSI_PHY_DBG(phy, "Phy enabled\n");
|
|
|
+ DSI_PHY_DBG(phy, "D-Phy enabled\n");
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * enable() - Enable PHY hardware
|
|
|
+ * @phy: Pointer to DSI PHY hardware object.
|
|
|
+ * @cfg: Per lane configurations for timing, strength and lane
|
|
|
+ * configurations.
|
|
|
+ */
|
|
|
+void dsi_phy_hw_v4_0_enable(struct dsi_phy_hw *phy,
|
|
|
+ struct dsi_phy_cfg *cfg)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+ u32 status;
|
|
|
+ u32 const delay_us = 5;
|
|
|
+ u32 const timeout_us = 1000;
|
|
|
+
|
|
|
+ if (dsi_phy_hw_v4_0_is_pll_on(phy))
|
|
|
+ pr_warn("PLL turned on before configuring PHY\n");
|
|
|
+
|
|
|
+ /* wait for REFGEN READY */
|
|
|
+ rc = readl_poll_timeout_atomic(phy->base + DSIPHY_CMN_PHY_STATUS,
|
|
|
+ status, (status & BIT(0)), delay_us, timeout_us);
|
|
|
+ if (rc) {
|
|
|
+ DSI_PHY_ERR(phy, "Ref gen not ready. Aborting\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cfg->phy_type == DSI_PHY_TYPE_CPHY)
|
|
|
+ dsi_phy_hw_cphy_enable(phy, cfg);
|
|
|
+ else /* Default PHY type is DPHY */
|
|
|
+ dsi_phy_hw_dphy_enable(phy, cfg);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|