platform: apq8084: Support display clocks for APQ8084
Add dsi clock, mdp clock, bus clock and gdsc clock
enable/disable API for APQ8084 target. It also updates
the APQ8084 display IO mapping.
Change-Id: Ifa746110fb1dcfb8dbad958a8370a54be2293f91
diff --git a/platform/apq8084/acpuclock.c b/platform/apq8084/acpuclock.c
index b785aa1..bfae903 100644
--- a/platform/apq8084/acpuclock.c
+++ b/platform/apq8084/acpuclock.c
@@ -239,3 +239,183 @@
ASSERT(0);
}
}
+
+void mdp_gdsc_ctrl(uint8_t enable)
+{
+ uint32_t reg = 0;
+ reg = readl(MDP_GDSCR);
+ if (enable) {
+ if (!(reg & GDSC_POWER_ON_BIT)) {
+ reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
+ reg |= GDSC_EN_FEW_WAIT_256_MASK;
+ writel(reg, MDP_GDSCR);
+ while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)));
+ } else {
+ dprintf(INFO, "MDP GDSC already enabled\n");
+ }
+ } else {
+ reg |= BIT(0);
+ writel(reg, MDP_GDSCR);
+ while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT));
+ }
+}
+
+/* Configure MDP clock */
+void mdp_clock_enable(void)
+{
+ int ret;
+
+ /* Set MDP clock to 240MHz */
+ ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ ret = clk_get_set_enable("mdss_mdp_clk_src", 240000000, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ ret = clk_get_set_enable("mdss_mdp_clk", 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ ret = clk_get_set_enable("mdss_mdp_lut_clk", 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set lut_mdp clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+}
+
+void mdp_clock_disable()
+{
+ clk_disable(clk_get("mdss_vsync_clk"));
+ clk_disable(clk_get("mdss_mdp_clk"));
+ clk_disable(clk_get("mdss_mdp_lut_clk"));
+ clk_disable(clk_get("mdss_mdp_clk_src"));
+ clk_disable(clk_get("mdp_ahb_clk"));
+
+}
+
+void mmss_bus_clock_enable(void)
+{
+ int ret;
+ /* Configure MMSSNOC AXI clock */
+ ret = clk_get_set_enable("mmss_mmssnoc_axi_clk", 100000000, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set mmssnoc_axi_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ /* Configure S0 AXI clock */
+ ret = clk_get_set_enable("mmss_s0_axi_clk", 100000000, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set mmss_s0_axi_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ /* Configure AXI clock */
+ ret = clk_get_set_enable("mdss_axi_clk", 100000000, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+}
+
+void mmss_bus_clock_disable(void)
+{
+ /* Disable MDSS AXI clock */
+ clk_disable(clk_get("mdss_axi_clk"));
+
+ /* Disable MMSSNOC S0AXI clock */
+ clk_disable(clk_get("mmss_s0_axi_clk"));
+
+ /* Disable MMSSNOC AXI clock */
+ clk_disable(clk_get("mmss_mmssnoc_axi_clk"));
+}
+
+void mmss_dsi_clock_enable(uint32_t dsi_pixel0_cfg_rcgr, uint32_t dual_dsi,
+ uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
+{
+ int ret;
+
+ /* Configure Byte clock -autopll- This will not change because
+ byte clock does not need any divider*/
+ writel(0x100, DSI_BYTE0_CFG_RCGR);
+ writel(0x1, DSI_BYTE0_CMD_RCGR);
+ writel(0x1, DSI_BYTE0_CBCR);
+
+ /* Configure Pixel clock */
+ writel(dsi_pixel0_cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
+ writel(0x1, DSI_PIXEL0_CMD_RCGR);
+ writel(0x1, DSI_PIXEL0_CBCR);
+
+ writel(pclk0_m, DSI_PIXEL0_M);
+ writel(pclk0_n, DSI_PIXEL0_N);
+ writel(pclk0_d, DSI_PIXEL0_D);
+
+ /* Configure ESC clock */
+ ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ if (dual_dsi) {
+ /* Configure Byte 1 clock */
+ writel(0x100, DSI_BYTE1_CFG_RCGR);
+ writel(0x1, DSI_BYTE1_CMD_RCGR);
+ writel(0x1, DSI_BYTE1_CBCR);
+
+ /* Configure Pixel clock */
+ writel(dsi_pixel0_cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
+ writel(0x1, DSI_PIXEL1_CMD_RCGR);
+ writel(0x1, DSI_PIXEL1_CBCR);
+
+ writel(pclk0_m, DSI_PIXEL0_M);
+ writel(pclk0_n, DSI_PIXEL0_N);
+ writel(pclk0_d, DSI_PIXEL0_D);
+
+ /* Configure ESC clock */
+ ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set esc1_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+ }
+}
+
+void mmss_dsi_clock_disable(uint32_t dual_dsi)
+{
+ /* Disable ESC clock */
+ clk_disable(clk_get("mdss_esc0_clk"));
+ writel(0x0, DSI_BYTE0_CBCR);
+ writel(0x0, DSI_PIXEL0_CBCR);
+
+ if (dual_dsi) {
+ /* Disable ESC clock */
+ clk_disable(clk_get("mdss_esc1_clk"));
+ writel(0x0, DSI_BYTE1_CBCR);
+ writel(0x0, DSI_PIXEL1_CBCR);
+ }
+}
diff --git a/platform/apq8084/apq8084-clock.c b/platform/apq8084/apq8084-clock.c
index a353a15..37e6323 100644
--- a/platform/apq8084/apq8084-clock.c
+++ b/platform/apq8084/apq8084-clock.c
@@ -329,6 +329,194 @@
},
};
+/* Display clocks */
+static struct clk_freq_tbl ftbl_mdss_esc0_1_clk[] = {
+ F_MM(19200000, cxo, 1, 0, 0),
+ F_END
+};
+
+static struct clk_freq_tbl ftbl_mdss_esc1_1_clk[] = {
+ F_MM(19200000, cxo, 1, 0, 0),
+ F_END
+};
+
+static struct clk_freq_tbl ftbl_mmss_axi_clk[] = {
+ F_MM(19200000, cxo, 1, 0, 0),
+ F_MM(100000000, gpll0, 6, 0, 0),
+ F_END
+};
+
+static struct clk_freq_tbl ftbl_mdp_clk[] = {
+ F_MM( 75000000, gpll0, 8, 0, 0),
+ F_MM( 240000000, gpll0, 2.5, 0, 0),
+ F_END
+};
+
+static struct rcg_clk dsi_esc0_clk_src = {
+ .cmd_reg = (uint32_t *) DSI_ESC0_CMD_RCGR,
+ .cfg_reg = (uint32_t *) DSI_ESC0_CFG_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_mdss_esc0_1_clk,
+
+ .c = {
+ .dbg_name = "dsi_esc0_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct rcg_clk dsi_esc1_clk_src = {
+ .cmd_reg = (uint32_t *) DSI_ESC1_CMD_RCGR,
+ .cfg_reg = (uint32_t *) DSI_ESC1_CFG_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_mdss_esc1_1_clk,
+
+ .c = {
+ .dbg_name = "dsi_esc1_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct clk_freq_tbl ftbl_mdss_vsync_clk[] = {
+ F_MM(19200000, cxo, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk vsync_clk_src = {
+ .cmd_reg = (uint32_t *) VSYNC_CMD_RCGR,
+ .cfg_reg = (uint32_t *) VSYNC_CFG_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_mdss_vsync_clk,
+
+ .c = {
+ .dbg_name = "vsync_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct rcg_clk mdp_axi_clk_src = {
+ .cmd_reg = (uint32_t *) MDP_AXI_CMD_RCGR,
+ .cfg_reg = (uint32_t *) MDP_AXI_CFG_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_mmss_axi_clk,
+
+ .c = {
+ .dbg_name = "mdp_axi_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct branch_clk mdss_esc0_clk = {
+ .cbcr_reg = (uint32_t *) DSI_ESC0_CBCR,
+ .parent = &dsi_esc0_clk_src.c,
+ .has_sibling = 0,
+
+ .c = {
+ .dbg_name = "mdss_esc0_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk mdss_esc1_clk = {
+ .cbcr_reg = (uint32_t *) DSI_ESC1_CBCR,
+ .parent = &dsi_esc1_clk_src.c,
+ .has_sibling = 0,
+
+ .c = {
+ .dbg_name = "mdss_esc1_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk mdss_axi_clk = {
+ .cbcr_reg = (uint32_t *) MDP_AXI_CBCR,
+ .parent = &mdp_axi_clk_src.c,
+ .has_sibling = 0,
+
+ .c = {
+ .dbg_name = "mdss_axi_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk mmss_mmssnoc_axi_clk = {
+ .cbcr_reg = (uint32_t *) MMSS_MMSSNOC_AXI_CBCR,
+ .parent = &mdp_axi_clk_src.c,
+ .has_sibling = 0,
+
+ .c = {
+ .dbg_name = "mmss_mmssnoc_axi_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk mmss_s0_axi_clk = {
+ .cbcr_reg = (uint32_t *) MMSS_S0_AXI_CBCR,
+ .parent = &mdp_axi_clk_src.c,
+ .has_sibling = 0,
+
+ .c = {
+ .dbg_name = "mmss_s0_axi_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk mdp_ahb_clk = {
+ .cbcr_reg = (uint32_t *) MDP_AHB_CBCR,
+ .has_sibling = 1,
+
+ .c = {
+ .dbg_name = "mdp_ahb_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct rcg_clk mdss_mdp_clk_src = {
+ .cmd_reg = (uint32_t *) MDP_CMD_RCGR,
+ .cfg_reg = (uint32_t *) MDP_CFG_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_mdp_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "mdss_mdp_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct branch_clk mdss_mdp_clk = {
+ .cbcr_reg = (uint32_t *) MDP_CBCR,
+ .parent = &mdss_mdp_clk_src.c,
+ .has_sibling = 1,
+
+ .c = {
+ .dbg_name = "mdss_mdp_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk mdss_mdp_lut_clk = {
+ .cbcr_reg = MDP_LUT_CBCR,
+ .parent = &mdss_mdp_clk_src.c,
+ .has_sibling = 1,
+
+ .c = {
+ .dbg_name = "mdss_mdp_lut_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk mdss_vsync_clk = {
+ .cbcr_reg = MDSS_VSYNC_CBCR,
+ .parent = &vsync_clk_src.c,
+ .has_sibling = 0,
+
+ .c = {
+ .dbg_name = "mdss_vsync_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+
/* Clock lookup table */
static struct clk_lookup msm_clocks_8084[] =
{
@@ -344,6 +532,18 @@
/* USB 3.0 */
CLK_LOOKUP("usb30_iface_clk", gcc_sys_noc_usb30_axi_clk.c),
CLK_LOOKUP("usb30_master_clk", gcc_usb30_master_clk.c),
+
+ /* mdss clocks */
+ CLK_LOOKUP("mdp_ahb_clk", mdp_ahb_clk.c),
+ CLK_LOOKUP("mdss_esc0_clk", mdss_esc0_clk.c),
+ CLK_LOOKUP("mdss_esc1_clk", mdss_esc1_clk.c),
+ CLK_LOOKUP("mdss_axi_clk", mdss_axi_clk.c),
+ CLK_LOOKUP("mmss_mmssnoc_axi_clk", mmss_mmssnoc_axi_clk.c),
+ CLK_LOOKUP("mmss_s0_axi_clk", mmss_s0_axi_clk.c),
+ CLK_LOOKUP("mdss_vsync_clk", mdss_vsync_clk.c),
+ CLK_LOOKUP("mdss_mdp_clk_src", mdss_mdp_clk_src.c),
+ CLK_LOOKUP("mdss_mdp_clk", mdss_mdp_clk.c),
+ CLK_LOOKUP("mdss_mdp_lut_clk", mdss_mdp_lut_clk.c),
};
void platform_clock_init(void)
diff --git a/platform/apq8084/include/platform/clock.h b/platform/apq8084/include/platform/clock.h
index b620dd0..943b9e5 100644
--- a/platform/apq8084/include/platform/clock.h
+++ b/platform/apq8084/include/platform/clock.h
@@ -34,6 +34,58 @@
#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
+#define REG_MM(off) (MSM_MMSS_CLK_CTL_BASE + (off))
+
+#define MDP_GDSCR REG_MM(0x2304)
+#define GDSC_POWER_ON_BIT BIT(31)
+#define GDSC_POWER_ON_STATUS_BIT BIT(29)
+#define GDSC_EN_FEW_WAIT_MASK (0x0F << 16)
+#define GDSC_EN_FEW_WAIT_256_MASK BIT(19)
+
+#define VSYNC_CMD_RCGR REG_MM(0x2080)
+#define VSYNC_CFG_RCGR REG_MM(0x2084)
+#define MDSS_VSYNC_CBCR REG_MM(0x2328)
+#define MDP_CMD_RCGR REG_MM(0x2040)
+#define MDP_CFG_RCGR REG_MM(0x2044)
+#define MDP_CBCR REG_MM(0x231C)
+#define MDP_LUT_CBCR REG_MM(0x2320)
+#define MDP_AHB_CBCR REG_MM(0x2308)
+
+#define MDP_AXI_CMD_RCGR REG_MM(0x5040)
+#define MDP_AXI_CFG_RCGR REG_MM(0x5044)
+
+#define MDP_AXI_CBCR REG_MM(0x2310)
+#define MMSS_S0_AXI_CBCR REG_MM(0x5064)
+#define MMSS_MMSSNOC_AXI_CBCR REG_MM(0x506C)
+
+#define DSI_BYTE0_CMD_RCGR REG_MM(0x2120)
+#define DSI_BYTE0_CFG_RCGR REG_MM(0x2124)
+#define DSI_BYTE0_CBCR REG_MM(0x233C)
+#define DSI_ESC0_CMD_RCGR REG_MM(0x2160)
+#define DSI_ESC0_CFG_RCGR REG_MM(0x2164)
+#define DSI_ESC0_CBCR REG_MM(0x2344)
+#define DSI_PIXEL0_CMD_RCGR REG_MM(0x2000)
+#define DSI_PIXEL0_CFG_RCGR REG_MM(0x2004)
+#define DSI_PIXEL0_CBCR REG_MM(0x2314)
+#define DSI_PIXEL0_M REG_MM(0x2008)
+#define DSI_PIXEL0_N REG_MM(0x200C)
+#define DSI_PIXEL0_D REG_MM(0x2010)
+
+#define DSI0_PHY_PLL_OUT BIT(8)
+#define PIXEL_SRC_DIV_1_5 BIT(1)
+
+#define DSI_BYTE1_CMD_RCGR REG_MM(0x2140)
+#define DSI_BYTE1_CFG_RCGR REG_MM(0x2144)
+#define DSI_BYTE1_CBCR REG_MM(0x2340)
+#define DSI_ESC1_CMD_RCGR REG_MM(0x2180)
+#define DSI_ESC1_CFG_RCGR REG_MM(0x2184)
+#define DSI_ESC1_CBCR REG_MM(0x2348)
+#define DSI_PIXEL1_CMD_RCGR REG_MM(0x2020)
+#define DSI_PIXEL1_CFG_RCGR REG_MM(0x2024)
+#define DSI_PIXEL1_CBCR REG_MM(0x2318)
+#define DSI_PIXEL1_M REG_MM(0x2028)
+#define DSI_PIXEL1_N REG_MM(0x202C)
+#define DSI_PIXEL1_D REG_MM(0x2030)
void platform_clock_init(void);
diff --git a/platform/apq8084/include/platform/iomap.h b/platform/apq8084/include/platform/iomap.h
index 7f47659..38ffe6c 100644
--- a/platform/apq8084/include/platform/iomap.h
+++ b/platform/apq8084/include/platform/iomap.h
@@ -176,4 +176,43 @@
#define BOOT_CONFIG_OFFSET 0x00006034
#define BOOT_CONFIG_REG (SEC_CTRL_CORE_BASE+BOOT_CONFIG_OFFSET)
+/* mdss */
+#define MSM_MMSS_CLK_CTL_BASE 0xFD8C0000
+
+#define MIPI_DSI_BASE (0xFD922800)
+#define MIPI_DSI0_BASE (MIPI_DSI_BASE)
+#define MIPI_DSI1_BASE (0xFD922E00)
+#define REG_DSI(off) (MIPI_DSI_BASE + 0x04 + (off))
+
+#define MDP_BASE (0xfd900000)
+#define REG_MDP(off) (MDP_BASE + (off))
+
+#define SOFT_RESET 0x118
+#define CLK_CTRL 0x11C
+#define TRIG_CTRL 0x084
+#define CTRL 0x004
+#define COMMAND_MODE_DMA_CTRL 0x03C
+#define ERR_INT_MASK0 0x10C
+
+#define LANE_SWAP_CTL 0x0B0
+#define TIMING_CTL 0x0C4
+
+#define VIDEO_MODE_ACTIVE_H 0x024
+#define VIDEO_MODE_ACTIVE_V 0x028
+#define VIDEO_MODE_TOTAL 0x02C
+#define VIDEO_MODE_HSYNC 0x030
+#define VIDEO_MODE_VSYNC 0x034
+#define VIDEO_MODE_VSYNC_VPOS 0x038
+
+#define DMA_CMD_OFFSET 0x048
+#define DMA_CMD_LENGTH 0x04C
+
+#define INT_CTRL 0x110
+#define CMD_MODE_DMA_SW_TRIGGER 0x090
+
+#define EOT_PACKET_CTRL 0x0C8
+#define MISR_VIDEO_CTRL 0x0A4
+#define VIDEO_MODE_CTRL 0x010
+#define HS_TIMER_CTRL 0x0BC
+
#endif