+int enable_pcie_clock(void)
+{
+ struct anatop_regs *anatop_regs =
+ (struct anatop_regs *)ANATOP_BASE_ADDR;
+ struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+ u32 lvds1_clk_sel;
+
+ /*
+ * Here be dragons!
+ *
+ * The register ANATOP_MISC1 is not documented in the Freescale
+ * MX6RM. The register that is mapped in the ANATOP space and
+ * marked as ANATOP_MISC1 is actually documented in the PMU section
+ * of the datasheet as PMU_MISC1.
+ *
+ * Switch LVDS clock source to SATA (0xb) on mx6q/dl or PCI (0xa) on
+ * mx6sx, disable clock INPUT and enable clock OUTPUT. This is important
+ * for PCI express link that is clocked from the i.MX6.
+ */
+#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN (1 << 12)
+#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN (1 << 10)
+#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK 0x0000001F
+#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF 0xa
+#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF 0xb
+
+ if (is_cpu_type(MXC_CPU_MX6SX))
+ lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF;
+ else
+ lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF;
+
+ clrsetbits_le32(&anatop_regs->ana_misc1,
+ ANADIG_ANA_MISC1_LVDSCLK1_IBEN |
+ ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK,
+ ANADIG_ANA_MISC1_LVDSCLK1_OBEN | lvds1_clk_sel);
+
+ /* PCIe reference clock sourced from AXI. */
+ clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL);
+
+ /* Party time! Ungate the clock to the PCIe. */
+#ifndef CONFIG_MX6SX
+ ungate_sata_clock();
+#endif
+ ungate_pcie_clock();
+
+ return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA |
+ BM_ANADIG_PLL_ENET_ENABLE_PCIE);
+}
+
+#ifdef CONFIG_SECURE_BOOT
+void hab_caam_clock_enable(unsigned char enable)
+{
+ u32 reg;
+
+ /* CG4 ~ CG6, CAAM clocks */
+ reg = __raw_readl(&imx_ccm->CCGR0);
+ if (enable)
+ reg |= (MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
+ MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
+ MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
+ else
+ reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
+ MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
+ MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
+ __raw_writel(reg, &imx_ccm->CCGR0);
+
+ /* EMI slow clk */
+ reg = __raw_readl(&imx_ccm->CCGR6);
+ if (enable)
+ reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
+ else
+ reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK;
+ __raw_writel(reg, &imx_ccm->CCGR6);
+}
+#endif
+
+static void enable_pll3(void)
+{
+ struct anatop_regs __iomem *anatop =
+ (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
+
+ /* make sure pll3 is enabled */
+ if ((readl(&anatop->usb1_pll_480_ctrl) &
+ BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) {
+ /* enable pll's power */
+ writel(BM_ANADIG_USB1_PLL_480_CTRL_POWER,
+ &anatop->usb1_pll_480_ctrl_set);
+ writel(0x80, &anatop->ana_misc2_clr);
+ /* wait for pll lock */
+ while ((readl(&anatop->usb1_pll_480_ctrl) &
+ BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0)
+ ;
+ /* disable bypass */
+ writel(BM_ANADIG_USB1_PLL_480_CTRL_BYPASS,
+ &anatop->usb1_pll_480_ctrl_clr);
+ /* enable pll output */
+ writel(BM_ANADIG_USB1_PLL_480_CTRL_ENABLE,
+ &anatop->usb1_pll_480_ctrl_set);
+ }
+}
+
+void enable_thermal_clk(void)
+{
+ enable_pll3();