/*
- * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#define CCDR 0x04
#define CCDR_CH0_HS_BYP 17
#define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
+#define BM_CCSR_STEP_CLK_SEL (1 << 8)
#define CACRR 0x10
#define CDHIPR 0x48
#define BM_CDHIPR_ARM_PODF_BUSY (1 << 16)
static unsigned int share_count_ssi1;
static unsigned int share_count_ssi2;
static unsigned int share_count_ssi3;
+static unsigned int share_count_spdif;
static struct clk *clks[IMX6SL_CLK_END];
static struct clk_onecell_data clk_data;
IMX6SL_CLK_IPG, IMX6SL_CLK_ARM, IMX6SL_CLK_MMDC_ROOT,
};
+extern int low_bus_freq_mode;
/*
* ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken
* during WAIT mode entry process could cause cache memory
}
}
-static void imx6sl_enable_pll_arm(bool enable)
-{
- static u32 saved_pll_arm;
- u32 val;
-
- if (enable) {
- saved_pll_arm = val = readl_relaxed(anatop_base + PLL_ARM);
- val |= BM_PLL_ARM_ENABLE;
- val &= ~BM_PLL_ARM_POWERDOWN;
- writel_relaxed(val, anatop_base + PLL_ARM);
- while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
- ;
- } else {
- writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
- }
-}
-
void imx6sl_set_wait_clk(bool enter)
{
static unsigned long saved_arm_div;
+ u32 val;
int arm_div_for_wait = imx6sl_get_arm_divider_for_wait();
- /*
- * According to hardware design, arm podf change need
- * PLL1 clock enabled.
- */
- if (arm_div_for_wait == ARM_WAIT_DIV_396M)
- imx6sl_enable_pll_arm(true);
-
if (enter) {
- saved_arm_div = readl_relaxed(ccm_base + CACRR);
- writel_relaxed(arm_div_for_wait, ccm_base + CACRR);
+ /*
+ * If in this mode, the IPG clock is at 12MHz, we can
+ * only run ARM at a max 28.8MHz, so we need to run
+ * from the 24MHz OSC, as there is no way to get
+ * 28.8MHz, when ARM is sourced from PLl1.
+ */
+ if (low_bus_freq_mode) {
+ val = readl_relaxed(ccm_base + CCSR);
+ val |= BM_CCSR_PLL1_SW_CLK_SEL;
+ writel_relaxed(val, ccm_base + CCSR);
+ } else {
+ saved_arm_div = readl_relaxed(ccm_base + CACRR);
+ writel_relaxed(arm_div_for_wait, ccm_base + CACRR);
+ }
} else {
- writel_relaxed(saved_arm_div, ccm_base + CACRR);
+ if (low_bus_freq_mode) {
+ val = readl_relaxed(ccm_base + CCSR);
+ val &= ~BM_CCSR_PLL1_SW_CLK_SEL;
+ writel_relaxed(val, ccm_base + CCSR);
+ } else {
+ writel_relaxed(saved_arm_div, ccm_base + CACRR);
+ }
}
while (__raw_readl(ccm_base + CDHIPR) & BM_CDHIPR_ARM_PODF_BUSY)
;
-
- if (arm_div_for_wait == ARM_WAIT_DIV_396M)
- imx6sl_enable_pll_arm(false);
}
static int __init setup_uart_clk(char *uart_rate)
imx_clk_set_parent(clks[IMX6SL_PLL6_BYPASS], clks[IMX6SL_CLK_PLL6]);
imx_clk_set_parent(clks[IMX6SL_PLL7_BYPASS], clks[IMX6SL_CLK_PLL7]);
- clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
+ clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1);
clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6);
clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
- clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14);
+ clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif0_podf", base + 0x7c, 14, &share_count_spdif);
+ clks[IMX6SL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif);
clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);