msm: clock-8960: Support v2 clocks
Some new clocks (and a PLL) have been added in v2. Support the
usb_hsic clocks and csi2 clocks.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index efab3b8..8ad143b 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -27,6 +27,7 @@
#include <mach/clk.h>
#include <mach/rpm-regulator.h>
#include <mach/msm_xo.h>
+#include <mach/socinfo.h>
#include "clock-local.h"
#include "clock-rpm.h"
@@ -69,6 +70,9 @@
#define BB_PLL8_STATUS_REG REG(0x3158)
#define BB_PLL8_CONFIG_REG REG(0x3154)
#define BB_PLL8_TEST_CTL_REG REG(0x3150)
+#define BB_MMCC_PLL2_MODE_REG REG(0x3160)
+#define BB_MMCC_PLL2_TEST_CTL_REG REG(0x3170)
+#define BB_PLL14_STATUS_REG REG(0x31D8)
#define PLLTEST_PAD_CFG_REG REG(0x2FA4)
#define PMEM_ACLK_CTL_REG REG(0x25A0)
#define RINGOSC_NS_REG REG(0x2DC0)
@@ -93,6 +97,14 @@
#define USB_HS1_RESET_REG REG(0x2910)
#define USB_HS1_XCVR_FS_CLK_MD_REG REG(0x2908)
#define USB_HS1_XCVR_FS_CLK_NS_REG REG(0x290C)
+#define USB_HSIC_HCLK_CTL_REG REG(0x2920)
+#define USB_HSIC_HSIC_CLK_CTL_REG REG(0x2B44)
+#define USB_HSIC_HSIC_CLK_SRC_CTL_REG REG(0x2B40)
+#define USB_HSIC_HSIO_CAL_CLK_CTL_REG REG(0x2B48)
+#define USB_HSIC_RESET_REG REG(0x2934)
+#define USB_HSIC_SYSTEM_CLK_CTL_REG REG(0x292C)
+#define USB_HSIC_XCVR_FS_CLK_MD_REG REG(0x2924)
+#define USB_HSIC_XCVR_FS_CLK_NS_REG REG(0x2928)
#define USB_PHY0_RESET_REG REG(0x2E20)
/* Multimedia clock registers. */
@@ -100,15 +112,24 @@
#define AHB_EN2_REG REG_MM(0x0038)
#define AHB_NS_REG REG_MM(0x0004)
#define AXI_NS_REG REG_MM(0x0014)
-#define CAMCLKn_NS_REG(n) REG_MM(0x0148+(0x14*(n)))
-#define CAMCLKn_CC_REG(n) REG_MM(0x0140+(0x14*(n)))
-#define CAMCLKn_MD_REG(n) REG_MM(0x0144+(0x14*(n)))
+#define CAMCLK0_NS_REG REG_MM(0x0148)
+#define CAMCLK0_CC_REG REG_MM(0x0140)
+#define CAMCLK0_MD_REG REG_MM(0x0144)
+#define CAMCLK1_NS_REG REG_MM(0x015C)
+#define CAMCLK1_CC_REG REG_MM(0x0154)
+#define CAMCLK1_MD_REG REG_MM(0x0158)
+#define CAMCLK2_NS_REG REG_MM(0x0228)
+#define CAMCLK2_CC_REG REG_MM(0x0220)
+#define CAMCLK2_MD_REG REG_MM(0x0224)
#define CSI0_NS_REG REG_MM(0x0048)
#define CSI0_CC_REG REG_MM(0x0040)
#define CSI0_MD_REG REG_MM(0x0044)
#define CSI1_NS_REG REG_MM(0x0010)
#define CSI1_CC_REG REG_MM(0x0024)
#define CSI1_MD_REG REG_MM(0x0028)
+#define CSI2_NS_REG REG_MM(0x0234)
+#define CSI2_CC_REG REG_MM(0x022C)
+#define CSI2_MD_REG REG_MM(0x0230)
#define CSIPHYTIMER_CC_REG REG_MM(0x0160)
#define CSIPHYTIMER_MD_REG REG_MM(0x0164)
#define CSIPHYTIMER_NS_REG REG_MM(0x0168)
@@ -161,6 +182,7 @@
#define MDP_NS_REG REG_MM(0x00D0)
#define MISC_CC_REG REG_MM(0x0058)
#define MISC_CC2_REG REG_MM(0x005C)
+#define MISC_CC3_REG REG_MM(0x0238)
#define MM_PLL1_MODE_REG REG_MM(0x031C)
#define ROT_CC_REG REG_MM(0x00E0)
#define ROT_NS_REG REG_MM(0x00E8)
@@ -170,6 +192,7 @@
#define SW_RESET_ALL_REG REG_MM(0x0204)
#define SW_RESET_AXI_REG REG_MM(0x0208)
#define SW_RESET_CORE_REG REG_MM(0x0210)
+#define SW_RESET_CORE2_REG REG_MM(0x0214)
#define TV_CC_REG REG_MM(0x00EC)
#define TV_CC2_REG REG_MM(0x0124)
#define TV_MD_REG REG_MM(0x00F0)
@@ -181,6 +204,7 @@
#define VFE_CC_REG REG_MM(0x0104)
#define VFE_MD_REG REG_MM(0x0108)
#define VFE_NS_REG REG_MM(0x010C)
+#define VFE_CC2_REG REG_MM(0x023C)
#define VPE_CC_REG REG_MM(0x0110)
#define VPE_NS_REG REG_MM(0x0118)
@@ -219,12 +243,14 @@
#define pll8_to_bb_mux 3
#define pll6_to_bb_mux 4
#define gnd_to_bb_mux 5
+#define pll3_to_bb_mux 6
#define pxo_to_mm_mux 0
#define pll1_to_mm_mux 1
#define pll2_to_mm_mux 1
#define pll8_to_mm_mux 2
#define pll0_to_mm_mux 3
#define gnd_to_mm_mux 4
+#define pll3_to_mm_mux 5
#define hdmi_pll_to_mm_mux 3
#define cxo_to_xo_mux 0
#define pxo_to_xo_mux 1
@@ -383,6 +409,17 @@
},
};
+static struct pll_clk pll3_clk = {
+ .rate = 1200000000,
+ .mode_reg = BB_MMCC_PLL2_MODE_REG,
+ .parent = &pxo_clk.c,
+ .c = {
+ .dbg_name = "pll3_clk",
+ .ops = &clk_ops_pll,
+ CLK_INIT(pll3_clk.c),
+ },
+};
+
static struct pll_vote_clk pll4_clk = {
.rate = 393216000,
.en_reg = BB_PLL_ENA_SC0_REG,
@@ -409,6 +446,19 @@
},
};
+static struct pll_vote_clk pll14_clk = {
+ .rate = 480000000,
+ .en_reg = BB_PLL_ENA_SC0_REG,
+ .en_mask = BIT(14),
+ .status_reg = BB_PLL14_STATUS_REG,
+ .parent = &pxo_clk.c,
+ .c = {
+ .dbg_name = "pll14_clk",
+ .ops = &clk_ops_pll_vote,
+ CLK_INIT(pll14_clk.c),
+ },
+};
+
/*
* SoC-specific functions required by clock-local driver
*/
@@ -1359,6 +1409,120 @@
},
};
+static struct clk_freq_tbl clk_tbl_usb_hsic[] = {
+ F_USB( 0, gnd, 1, 0, 0, NONE),
+ F_USB(60000000, pll8, 1, 5, 32, LOW),
+ F_END
+};
+
+static struct rcg_clk usb_hsic_xcvr_fs_clk = {
+ .b = {
+ .ctl_reg = USB_HSIC_XCVR_FS_CLK_NS_REG,
+ .en_mask = BIT(9),
+ .halt_reg = CLK_HALT_CFPB_STATEA_REG,
+ .halt_bit = 26,
+ },
+ .ns_reg = USB_HSIC_XCVR_FS_CLK_NS_REG,
+ .md_reg = USB_HSIC_XCVR_FS_CLK_MD_REG,
+ .root_en_mask = BIT(11),
+ .ns_mask = (BM(23, 16) | BM(6, 0)),
+ .set_rate = set_rate_mnd,
+ .freq_tbl = clk_tbl_usb_hsic,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "usb_hsic_xcvr_fs_clk",
+ .ops = &clk_ops_rcg_8960,
+ CLK_INIT(usb_hsic_xcvr_fs_clk.c),
+ },
+};
+
+static struct branch_clk usb_hsic_system_clk = {
+ .b = {
+ .ctl_reg = USB_HSIC_SYSTEM_CLK_CTL_REG,
+ .en_mask = BIT(4),
+ .reset_reg = USB_HSIC_RESET_REG,
+ .reset_mask = BIT(0),
+ .halt_reg = CLK_HALT_CFPB_STATEA_REG,
+ .halt_bit = 24,
+ },
+ .parent = &usb_hsic_xcvr_fs_clk.c,
+ .c = {
+ .dbg_name = "usb_hsic_system_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(usb_hsic_system_clk.c),
+ },
+};
+
+#define F_USB_HSIC(f, s, v) \
+ { \
+ .freq_hz = f, \
+ .src_clk = &s##_clk.c, \
+ .sys_vdd = v, \
+ }
+static struct clk_freq_tbl clk_tbl_usb2_hsic[] = {
+ F_USB_HSIC(480000000, pll14, LOW),
+ F_END
+};
+
+static struct rcg_clk usb_hsic_hsic_src_clk = {
+ .b = {
+ .ctl_reg = USB_HSIC_HSIC_CLK_SRC_CTL_REG,
+ .halt_check = NOCHECK,
+ },
+ .root_en_mask = BIT(0),
+ .set_rate = set_rate_nop,
+ .freq_tbl = clk_tbl_usb2_hsic,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "usb_hsic_hsic_src_clk",
+ .ops = &clk_ops_rcg_8960,
+ CLK_INIT(usb_hsic_hsic_src_clk.c),
+ },
+};
+
+static struct branch_clk usb_hsic_hsic_clk = {
+ .b = {
+ .ctl_reg = USB_HSIC_HSIC_CLK_CTL_REG,
+ .en_mask = BIT(0),
+ .halt_reg = CLK_HALT_CFPB_STATEA_REG,
+ .halt_bit = 19,
+ },
+ .parent = &usb_hsic_hsic_src_clk.c,
+ .c = {
+ .dbg_name = "usb_hsic_hsic_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(usb_hsic_hsic_clk.c),
+ },
+};
+
+#define F_USB_HSIO_CAL(f, s, v) \
+ { \
+ .freq_hz = f, \
+ .src_clk = &s##_clk.c, \
+ .sys_vdd = v, \
+ }
+static struct clk_freq_tbl clk_tbl_usb_hsio_cal[] = {
+ F_USB_HSIO_CAL(9000000, pxo, LOW),
+ F_END
+};
+
+static struct rcg_clk usb_hsic_hsio_cal_clk = {
+ .b = {
+ .ctl_reg = USB_HSIC_HSIO_CAL_CLK_CTL_REG,
+ .en_mask = BIT(0),
+ .halt_reg = CLK_HALT_CFPB_STATEA_REG,
+ .halt_bit = 23,
+ },
+ .set_rate = set_rate_nop,
+ .freq_tbl = clk_tbl_usb_hsio_cal,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "usb_hsic_hsio_cal_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(usb_hsic_hsio_cal_clk.c),
+ },
+};
+
static struct branch_clk usb_phy0_clk = {
.b = {
.reset_reg = USB_PHY0_RESET_REG,
@@ -1727,6 +1891,20 @@
},
};
+static struct branch_clk usb_hsic_p_clk = {
+ .b = {
+ .ctl_reg = USB_HSIC_HCLK_CTL_REG,
+ .en_mask = BIT(4),
+ .halt_reg = CLK_HALT_CFPB_STATEA_REG,
+ .halt_bit = 28,
+ },
+ .c = {
+ .dbg_name = "usb_hsic_p_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(usb_hsic_p_clk.c),
+ },
+};
+
static struct branch_clk sdc1_p_clk = {
.b = {
.ctl_reg = SDCn_HCLK_CTL_REG(1),
@@ -1904,26 +2082,26 @@
},
};
-#define CLK_CAM(i, n, hb) \
- struct rcg_clk i##_clk = { \
+#define CLK_CAM(name, n, hb) \
+ struct rcg_clk name = { \
.b = { \
- .ctl_reg = CAMCLKn_CC_REG(n), \
+ .ctl_reg = CAMCLK##n##_CC_REG, \
.en_mask = BIT(0), \
.halt_reg = DBG_BUS_VEC_I_REG, \
.halt_bit = hb, \
}, \
- .ns_reg = CAMCLKn_NS_REG(n), \
- .md_reg = CAMCLKn_MD_REG(n), \
+ .ns_reg = CAMCLK##n##_NS_REG, \
+ .md_reg = CAMCLK##n##_MD_REG, \
.root_en_mask = BIT(2), \
- .ns_mask = (BM(31, 24) | BM(15, 14) | BM(2, 0)), \
+ .ns_mask = BM(31, 24) | BM(15, 14) | BM(2, 0), \
.ctl_mask = BM(7, 6), \
.set_rate = set_rate_mnd_8, \
.freq_tbl = clk_tbl_cam, \
.current_freq = &rcg_dummy_freq, \
.c = { \
- .dbg_name = #i "_clk", \
+ .dbg_name = #name, \
.ops = &clk_ops_rcg_8960, \
- CLK_INIT(i##_clk.c), \
+ CLK_INIT(name.c), \
}, \
}
#define F_CAM(f, s, d, m, n, v) \
@@ -1952,8 +2130,9 @@
F_END
};
-static CLK_CAM(cam0, 0, 15);
-static CLK_CAM(cam1, 1, 16);
+static CLK_CAM(cam0_clk, 0, 15);
+static CLK_CAM(cam1_clk, 1, 16);
+static CLK_CAM(cam2_clk, 2, 31);
#define F_CSI(f, s, d, m, n, v) \
{ \
@@ -1980,7 +2159,7 @@
},
.md_reg = CSI0_MD_REG,
.root_en_mask = BIT(2),
- .ns_mask = BM(31, 24) | BM(15, 12) | BM(2, 0),
+ .ns_mask = BM(31, 24) | BM(15, 14) | BM(2, 0),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_csi,
@@ -2034,7 +2213,7 @@
},
.md_reg = CSI1_MD_REG,
.root_en_mask = BIT(2),
- .ns_mask = BM(31, 24) | BM(15, 12) | BM(2, 0),
+ .ns_mask = BM(31, 24) | BM(15, 14) | BM(2, 0),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_csi,
@@ -2080,27 +2259,87 @@
},
};
+static struct rcg_clk csi2_src_clk = {
+ .ns_reg = CSI2_NS_REG,
+ .b = {
+ .ctl_reg = CSI2_CC_REG,
+ .halt_check = NOCHECK,
+ },
+ .md_reg = CSI2_MD_REG,
+ .root_en_mask = BIT(2),
+ .ns_mask = BM(31, 24) | BM(15, 14) | BM(2, 0),
+ .ctl_mask = BM(7, 6),
+ .set_rate = set_rate_mnd,
+ .freq_tbl = clk_tbl_csi,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "csi2_src_clk",
+ .ops = &clk_ops_rcg_8960,
+ CLK_INIT(csi2_src_clk.c),
+ },
+};
+
+static struct branch_clk csi2_clk = {
+ .b = {
+ .ctl_reg = CSI2_CC_REG,
+ .en_mask = BIT(0),
+ .reset_reg = SW_RESET_CORE2_REG,
+ .reset_mask = BIT(2),
+ .halt_reg = DBG_BUS_VEC_B_REG,
+ .halt_bit = 29,
+ },
+ .parent = &csi2_src_clk.c,
+ .c = {
+ .dbg_name = "csi2_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi2_clk.c),
+ },
+};
+
+static struct branch_clk csi2_phy_clk = {
+ .b = {
+ .ctl_reg = CSI2_CC_REG,
+ .en_mask = BIT(8),
+ .reset_reg = SW_RESET_CORE_REG,
+ .reset_mask = BIT(31),
+ .halt_reg = DBG_BUS_VEC_I_REG,
+ .halt_bit = 29,
+ },
+ .parent = &csi2_src_clk.c,
+ .c = {
+ .dbg_name = "csi2_phy_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi2_phy_clk.c),
+ },
+};
+
+/*
+ * The csi pix and csi rdi clocks have two bits in two registers to control a
+ * three input mux. So we have the generic rcg_clk_enable() path handle the
+ * first bit, and this function handle the second bit.
+ */
+static void set_rate_pix_rdi(struct rcg_clk *clk, struct clk_freq_tbl *nf)
+{
+ u32 reg = readl_relaxed(MISC_CC3_REG);
+ u32 bit = (u32)nf->extra_freq_data;
+ if (nf->freq_hz == 2)
+ reg |= bit;
+ else
+ reg &= ~bit;
+ writel_relaxed(reg, MISC_CC3_REG);
+}
+
#define F_CSI_PIX(s) \
{ \
.src_clk = &csi##s##_clk.c, \
.freq_hz = s, \
.ns_val = BVAL(25, 25, s), \
+ .extra_freq_data = (void *)BIT(13), \
}
static struct clk_freq_tbl clk_tbl_csi_pix[] = {
F_CSI_PIX(0), /* CSI0 source */
F_CSI_PIX(1), /* CSI1 source */
- F_END
-};
-
-#define F_CSI_RDI(s) \
- { \
- .src_clk = &csi##s##_clk.c, \
- .freq_hz = s, \
- .ns_val = BVAL(12, 12, s), \
- }
-static struct clk_freq_tbl clk_tbl_csi_rdi[] = {
- F_CSI_RDI(0), /* CSI0 source */
- F_CSI_RDI(1), /* CSI1 source */
+ F_CSI_PIX(2), /* CSI2 source */
F_END
};
@@ -2114,7 +2353,7 @@
},
.ns_reg = MISC_CC_REG,
.ns_mask = BIT(25),
- .set_rate = set_rate_nop,
+ .set_rate = set_rate_pix_rdi,
.freq_tbl = clk_tbl_csi_pix,
.current_freq = &rcg_dummy_freq,
.c = {
@@ -2124,6 +2363,53 @@
},
};
+#define F_CSI_PIX1(s) \
+ { \
+ .src_clk = &csi##s##_clk.c, \
+ .freq_hz = s, \
+ .ns_val = BVAL(9, 8, s), \
+ }
+static struct clk_freq_tbl clk_tbl_csi_pix1[] = {
+ F_CSI_PIX1(0), /* CSI0 source */
+ F_CSI_PIX1(1), /* CSI1 source */
+ F_CSI_PIX1(2), /* CSI2 source */
+ F_END
+};
+
+static struct rcg_clk csi_pix1_clk = {
+ .b = {
+ .ctl_reg = MISC_CC3_REG,
+ .en_mask = BIT(10),
+ .halt_check = DELAY,
+ .reset_reg = SW_RESET_CORE_REG,
+ .reset_mask = BIT(30),
+ },
+ .ns_reg = MISC_CC3_REG,
+ .ns_mask = BM(9, 8),
+ .set_rate = set_rate_nop,
+ .freq_tbl = clk_tbl_csi_pix1,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "csi_pix1_clk",
+ .ops = &clk_ops_rcg_8960,
+ CLK_INIT(csi_pix1_clk.c),
+ },
+};
+
+#define F_CSI_RDI(s) \
+ { \
+ .src_clk = &csi##s##_clk.c, \
+ .freq_hz = s, \
+ .ns_val = BVAL(12, 12, s), \
+ .extra_freq_data = (void *)BIT(12), \
+ }
+static struct clk_freq_tbl clk_tbl_csi_rdi[] = {
+ F_CSI_RDI(0), /* CSI0 source */
+ F_CSI_RDI(1), /* CSI1 source */
+ F_CSI_RDI(2), /* CSI2 source */
+ F_END
+};
+
static struct rcg_clk csi_rdi_clk = {
.b = {
.ctl_reg = MISC_CC_REG,
@@ -2134,7 +2420,7 @@
},
.ns_reg = MISC_CC_REG,
.ns_mask = BIT(12),
- .set_rate = set_rate_nop,
+ .set_rate = set_rate_pix_rdi,
.freq_tbl = clk_tbl_csi_rdi,
.current_freq = &rcg_dummy_freq,
.c = {
@@ -2144,6 +2430,72 @@
},
};
+#define F_CSI_RDI1(s) \
+ { \
+ .src_clk = &csi##s##_clk.c, \
+ .freq_hz = s, \
+ .ns_val = BVAL(1, 0, s), \
+ }
+static struct clk_freq_tbl clk_tbl_csi_rdi1[] = {
+ F_CSI_RDI1(0), /* CSI0 source */
+ F_CSI_RDI1(1), /* CSI1 source */
+ F_CSI_RDI1(2), /* CSI2 source */
+ F_END
+};
+
+static struct rcg_clk csi_rdi1_clk = {
+ .b = {
+ .ctl_reg = MISC_CC3_REG,
+ .en_mask = BIT(2),
+ .halt_check = DELAY,
+ .reset_reg = SW_RESET_CORE2_REG,
+ .reset_mask = BIT(1),
+ },
+ .ns_reg = MISC_CC3_REG,
+ .ns_mask = BM(1, 0),
+ .set_rate = set_rate_nop,
+ .freq_tbl = clk_tbl_csi_rdi1,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "csi_rdi1_clk",
+ .ops = &clk_ops_rcg_8960,
+ CLK_INIT(csi_rdi1_clk.c),
+ },
+};
+
+#define F_CSI_RDI2(s) \
+ { \
+ .src_clk = &csi##s##_clk.c, \
+ .freq_hz = s, \
+ .ns_val = BVAL(5, 4, s), \
+ }
+static struct clk_freq_tbl clk_tbl_csi_rdi2[] = {
+ F_CSI_RDI2(0), /* CSI0 source */
+ F_CSI_RDI2(1), /* CSI1 source */
+ F_CSI_RDI2(2), /* CSI2 source */
+ F_END
+};
+
+static struct rcg_clk csi_rdi2_clk = {
+ .b = {
+ .ctl_reg = MISC_CC3_REG,
+ .en_mask = BIT(6),
+ .halt_check = DELAY,
+ .reset_reg = SW_RESET_CORE2_REG,
+ .reset_mask = BIT(0),
+ },
+ .ns_reg = MISC_CC3_REG,
+ .ns_mask = BM(5, 4),
+ .set_rate = set_rate_nop,
+ .freq_tbl = clk_tbl_csi_rdi2,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "csi_rdi2_clk",
+ .ops = &clk_ops_rcg_8960,
+ CLK_INIT(csi_rdi2_clk.c),
+ },
+};
+
#define F_CSI_PHYTIMER(f, s, d, m, n, v) \
{ \
.freq_hz = f, \
@@ -2211,6 +2563,21 @@
},
};
+static struct branch_clk csi2phy_timer_clk = {
+ .b = {
+ .ctl_reg = CSIPHYTIMER_CC_REG,
+ .en_mask = BIT(11),
+ .halt_reg = DBG_BUS_VEC_I_REG,
+ .halt_bit = 30,
+ },
+ .parent = &csiphy_timer_src_clk.c,
+ .c = {
+ .dbg_name = "csi2phy_timer_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi2phy_timer_clk.c),
+ },
+};
+
#define F_DSI(d) \
{ \
.freq_hz = d, \
@@ -2450,6 +2817,27 @@
F_END
};
+static struct clk_freq_tbl clk_tbl_gfx3d_v2[] = {
+ F_GFX3D( 0, gnd, 0, 0, NONE),
+ F_GFX3D( 27000000, pxo, 0, 0, LOW),
+ F_GFX3D( 48000000, pll8, 1, 8, LOW),
+ F_GFX3D( 54857000, pll8, 1, 7, LOW),
+ F_GFX3D( 64000000, pll8, 1, 6, LOW),
+ F_GFX3D( 76800000, pll8, 1, 5, LOW),
+ F_GFX3D( 96000000, pll8, 1, 4, LOW),
+ F_GFX3D(128000000, pll8, 1, 3, LOW),
+ F_GFX3D(145455000, pll2, 2, 11, NOMINAL),
+ F_GFX3D(160000000, pll2, 1, 5, NOMINAL),
+ F_GFX3D(177778000, pll2, 2, 9, NOMINAL),
+ F_GFX3D(200000000, pll2, 1, 4, NOMINAL),
+ F_GFX3D(228571000, pll2, 2, 7, NOMINAL),
+ F_GFX3D(266667000, pll2, 1, 3, NOMINAL),
+ F_GFX3D(300000000, pll3, 1, 4, NOMINAL),
+ F_GFX3D(320000000, pll2, 2, 5, HIGH),
+ F_GFX3D(400000000, pll2, 1, 2, HIGH),
+ F_END
+};
+
static struct bank_masks bmnd_info_gfx3d = {
.bank_sel_mask = BIT(11),
.bank0_mask = {
@@ -2512,6 +2900,7 @@
F_IJPEG(153600000, pll8, 1, 2, 5, NOMINAL),
F_IJPEG(200000000, pll2, 4, 0, 0, NOMINAL),
F_IJPEG(228571000, pll2, 1, 2, 7, NOMINAL),
+ F_IJPEG(320000000, pll2, 1, 2, 5, HIGH),
F_END
};
@@ -3073,6 +3462,7 @@
F_VFE(200000000, pll2, 2, 1, 2, NOMINAL),
F_VFE(228570000, pll2, 1, 2, 7, NOMINAL),
F_VFE(266667000, pll2, 1, 1, 3, NOMINAL),
+ F_VFE(320000000, pll2, 1, 2, 5, HIGH),
F_END
};
@@ -3492,6 +3882,9 @@
{ TEST_PER_LS(0x80), &adm0_p_clk.c },
{ TEST_PER_LS(0x84), &usb_hs1_p_clk.c },
{ TEST_PER_LS(0x85), &usb_hs1_xcvr_clk.c },
+ { TEST_PER_LS(0x86), &usb_hsic_p_clk.c },
+ { TEST_PER_LS(0x87), &usb_hsic_system_clk.c },
+ { TEST_PER_LS(0x88), &usb_hsic_xcvr_fs_clk.c },
{ TEST_PER_LS(0x89), &usb_fs1_p_clk.c },
{ TEST_PER_LS(0x8A), &usb_fs1_sys_clk.c },
{ TEST_PER_LS(0x8B), &usb_fs1_xcvr_clk.c },
@@ -3502,6 +3895,7 @@
{ TEST_PER_LS(0x91), &tsif_ref_clk.c },
{ TEST_PER_LS(0x92), &ce1_p_clk.c },
{ TEST_PER_LS(0x94), &tssc_clk.c },
+ { TEST_PER_LS(0x9D), &usb_hsic_hsio_cal_clk.c },
{ TEST_PER_LS(0xA4), &ce1_core_clk.c },
{ TEST_PER_HS(0x07), &afab_clk.c },
@@ -3511,6 +3905,7 @@
{ TEST_PER_HS(0x2A), &adm0_clk.c },
{ TEST_PER_HS(0x34), &ebi1_clk.c },
{ TEST_PER_HS(0x34), &ebi1_a_clk.c },
+ { TEST_PER_HS(0x50), &usb_hsic_hsic_clk.c },
{ TEST_MM_LS(0x00), &dsi1_byte_clk.c },
{ TEST_MM_LS(0x01), &dsi2_byte_clk.c },
@@ -3545,6 +3940,7 @@
{ TEST_MM_LS(0x25), &mmfpb_clk.c },
{ TEST_MM_LS(0x25), &mmfpb_a_clk.c },
{ TEST_MM_LS(0x26), &dsi2_m_p_clk.c },
+ { TEST_MM_LS(0x27), &cam2_clk.c },
{ TEST_MM_HS(0x00), &csi0_clk.c },
{ TEST_MM_HS(0x01), &csi1_clk.c },
@@ -3581,6 +3977,12 @@
{ TEST_MM_HS(0x2A), &vcodec_axi_b_clk.c },
{ TEST_MM_HS(0x2B), &csi1phy_timer_clk.c },
{ TEST_MM_HS(0x2C), &csi0phy_timer_clk.c },
+ { TEST_MM_HS(0x2D), &csi2_clk.c },
+ { TEST_MM_HS(0x2E), &csi2_phy_clk.c },
+ { TEST_MM_HS(0x2F), &csi2phy_timer_clk.c },
+ { TEST_MM_HS(0x30), &csi_pix1_clk.c },
+ { TEST_MM_HS(0x31), &csi_rdi1_clk.c },
+ { TEST_MM_HS(0x32), &csi_rdi2_clk.c },
{ TEST_LPA(0x0F), &mi2s_bit_clk.c },
{ TEST_LPA(0x10), &codec_i2s_mic_bit_clk.c },
@@ -3766,7 +4168,7 @@
.multiplier = 1,
};
-static struct clk_lookup msm_clocks_8960[] = {
+static struct clk_lookup msm_clocks_8960_v1[] __initdata = {
CLK_LOOKUP("cxo", cxo_clk.c, NULL),
CLK_LOOKUP("pll2", pll2_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
@@ -3984,6 +4386,26 @@
CLK_LOOKUP("krait1_mclk", krait1_m_clk, NULL),
};
+static struct clk_lookup msm_clocks_8960_v2[] __initdata = {
+ CLK_LOOKUP("cam_clk", cam2_clk.c, NULL),
+ CLK_LOOKUP("csi_src_clk", csi2_src_clk.c, NULL),
+ CLK_LOOKUP("csi_clk", csi2_clk.c, NULL),
+ CLK_LOOKUP("csi_pix1_clk", csi_pix1_clk.c, NULL),
+ CLK_LOOKUP("csi_rdi1_clk", csi_rdi1_clk.c, NULL),
+ CLK_LOOKUP("csi_rdi2_clk", csi_rdi2_clk.c, NULL),
+ CLK_LOOKUP("csi_phy_clk", csi2_phy_clk.c, NULL),
+ CLK_LOOKUP("csi2phy_timer_clk", csi2phy_timer_clk.c, NULL),
+ CLK_LOOKUP("usb_hsic_xcvr_fs_clk", usb_hsic_xcvr_fs_clk.c, NULL),
+ CLK_LOOKUP("usb_hsic_hsic_clk", usb_hsic_hsic_clk.c, NULL),
+ CLK_LOOKUP("usb_hsic_hsio_cal_clk", usb_hsic_hsio_cal_clk.c, NULL),
+ CLK_LOOKUP("usb_hsic_system_clk", usb_hsic_system_clk.c, NULL),
+ CLK_LOOKUP("usb_hsic_p_clk", usb_hsic_p_clk.c, NULL),
+};
+
+/* Add v2 clocks dynamically at runtime */
+static struct clk_lookup msm_clocks_8960[ARRAY_SIZE(msm_clocks_8960_v1) +
+ ARRAY_SIZE(msm_clocks_8960_v2)];
+
/*
* Miscellaneous clock register initializations
*/
@@ -4043,6 +4465,7 @@
rmwreg(0x000004FF, TV_CC2_REG, 0x000007FF);
rmwreg(0xC0FF0000, VCODEC_CC_REG, 0xE0FF0010);
rmwreg(0x80FF0000, VFE_CC_REG, 0xE0FF4010);
+ rmwreg(0x800000FF, VFE_CC2_REG, 0xE00000FF);
rmwreg(0x80FF0000, VPE_CC_REG, 0xE0FF0010);
/* De-assert MM AXI resets to all hardware blocks. */
@@ -4110,9 +4533,12 @@
return 0;
}
+struct clock_init_data msm8960_clock_init_data __initdata;
+
/* Local clock driver initialization. */
static void __init msm8960_clock_init(void)
{
+ size_t num_lookups = ARRAY_SIZE(msm_clocks_8960_v1);
xo_pxo = msm_xo_get(MSM_XO_PXO, "clock-8960");
if (IS_ERR(xo_pxo)) {
pr_err("%s: msm_xo_get(PXO) failed.\n", __func__);
@@ -4124,6 +4550,17 @@
BUG();
}
+ memcpy(msm_clocks_8960, msm_clocks_8960_v1, sizeof(msm_clocks_8960_v1));
+ if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2) {
+ struct clk_freq_tbl **ptr =
+ (struct clk_freq_tbl **)&gfx3d_clk.freq_tbl;
+ *ptr = clk_tbl_gfx3d_v2;
+ memcpy(msm_clocks_8960 + ARRAY_SIZE(msm_clocks_8960_v1),
+ msm_clocks_8960_v2, sizeof(msm_clocks_8960_v2));
+ num_lookups = ARRAY_SIZE(msm_clocks_8960);
+ }
+ msm8960_clock_init_data.size = num_lookups;
+
soc_update_sys_vdd = msm8960_update_sys_vdd;
local_vote_sys_vdd(HIGH);
@@ -4141,6 +4578,9 @@
clk_set_rate(&usb_hs1_xcvr_clk.c, 60000000);
clk_set_rate(&usb_fs1_src_clk.c, 60000000);
clk_set_rate(&usb_fs2_src_clk.c, 60000000);
+ clk_set_rate(&usb_hsic_xcvr_fs_clk.c, 60000000);
+ clk_set_rate(&usb_hsic_hsic_src_clk.c, 480000000);
+ clk_set_rate(&usb_hsic_hsio_cal_clk.c, 9000000);
/*
* The halt status bits for PDM and TSSC may be incorrect at boot.
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index fa84906..e6cc233 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -185,13 +185,16 @@
void __init msm_clock_init(struct clock_init_data *data)
{
unsigned n;
- struct clk_lookup *clock_tbl = data->table;
- size_t num_clocks = data->size;
+ struct clk_lookup *clock_tbl;
+ size_t num_clocks;
clk_init_data = data;
if (clk_init_data->init)
clk_init_data->init();
+ clock_tbl = data->table;
+ num_clocks = data->size;
+
for (n = 0; n < num_clocks; n++) {
struct clk *clk = clock_tbl[n].clk;
struct clk *parent = clk_get_parent(clk);