diff options
Diffstat (limited to 'arch/arm/mach-imx/clk-imx6q.c')
-rw-r--r-- | arch/arm/mach-imx/clk-imx6q.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index c0c4e723b7f5..2f9ff93a4e61 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c | |||
@@ -54,9 +54,18 @@ | |||
54 | #define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) | 54 | #define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) |
55 | #define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) | 55 | #define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) |
56 | 56 | ||
57 | #define CGPR 0x64 | ||
58 | #define BM_CGPR_CHICKEN_BIT (0x1 << 17) | ||
59 | |||
57 | static void __iomem *ccm_base; | 60 | static void __iomem *ccm_base; |
58 | 61 | ||
59 | void __init imx6q_clock_map_io(void) { } | 62 | void imx6q_set_chicken_bit(void) |
63 | { | ||
64 | u32 val = readl_relaxed(ccm_base + CGPR); | ||
65 | |||
66 | val |= BM_CGPR_CHICKEN_BIT; | ||
67 | writel_relaxed(val, ccm_base + CGPR); | ||
68 | } | ||
60 | 69 | ||
61 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | 70 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) |
62 | { | 71 | { |
@@ -68,6 +77,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | |||
68 | break; | 77 | break; |
69 | case WAIT_UNCLOCKED: | 78 | case WAIT_UNCLOCKED: |
70 | val |= 0x1 << BP_CLPCR_LPM; | 79 | val |= 0x1 << BP_CLPCR_LPM; |
80 | val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM; | ||
71 | break; | 81 | break; |
72 | case STOP_POWER_ON: | 82 | case STOP_POWER_ON: |
73 | val |= 0x2 << BP_CLPCR_LPM; | 83 | val |= 0x2 << BP_CLPCR_LPM; |
@@ -154,15 +164,15 @@ enum mx6q_clks { | |||
154 | usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg, | 164 | usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg, |
155 | pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg, | 165 | pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg, |
156 | ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, | 166 | ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, |
157 | sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, | 167 | sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate, |
158 | clk_max | 168 | usbphy2_gate, clk_max |
159 | }; | 169 | }; |
160 | 170 | ||
161 | static struct clk *clk[clk_max]; | 171 | static struct clk *clk[clk_max]; |
162 | static struct clk_onecell_data clk_data; | 172 | static struct clk_onecell_data clk_data; |
163 | 173 | ||
164 | static enum mx6q_clks const clks_init_on[] __initconst = { | 174 | static enum mx6q_clks const clks_init_on[] __initconst = { |
165 | mmdc_ch0_axi, rom, | 175 | mmdc_ch0_axi, rom, pll1_sys, |
166 | }; | 176 | }; |
167 | 177 | ||
168 | static struct clk_div_table clk_enet_ref_table[] = { | 178 | static struct clk_div_table clk_enet_ref_table[] = { |
@@ -208,8 +218,21 @@ int __init mx6q_clocks_init(void) | |||
208 | clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3); | 218 | clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3); |
209 | clk[pll8_mlb] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll8_mlb", "osc", base + 0xd0, 0x0); | 219 | clk[pll8_mlb] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll8_mlb", "osc", base + 0xd0, 0x0); |
210 | 220 | ||
211 | clk[usbphy1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6); | 221 | /* |
212 | clk[usbphy2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6); | 222 | * Bit 20 is the reserved and read-only bit, we do this only for: |
223 | * - Do nothing for usbphy clk_enable/disable | ||
224 | * - Keep refcount when do usbphy clk_enable/disable, in that case, | ||
225 | * the clk framework may need to enable/disable usbphy's parent | ||
226 | */ | ||
227 | clk[usbphy1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); | ||
228 | clk[usbphy2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); | ||
229 | |||
230 | /* | ||
231 | * usbphy*_gate needs to be on after system boots up, and software | ||
232 | * never needs to control it anymore. | ||
233 | */ | ||
234 | clk[usbphy1_gate] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6); | ||
235 | clk[usbphy2_gate] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6); | ||
213 | 236 | ||
214 | clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5); | 237 | clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5); |
215 | clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4); | 238 | clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4); |
@@ -436,6 +459,11 @@ int __init mx6q_clocks_init(void) | |||
436 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) | 459 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) |
437 | clk_prepare_enable(clk[clks_init_on[i]]); | 460 | clk_prepare_enable(clk[clks_init_on[i]]); |
438 | 461 | ||
462 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | ||
463 | clk_prepare_enable(clk[usbphy1_gate]); | ||
464 | clk_prepare_enable(clk[usbphy2_gate]); | ||
465 | } | ||
466 | |||
439 | /* Set initial power mode */ | 467 | /* Set initial power mode */ |
440 | imx6q_set_lpm(WAIT_CLOCKED); | 468 | imx6q_set_lpm(WAIT_CLOCKED); |
441 | 469 | ||