diff options
Diffstat (limited to 'arch/arm/mach-imx/clk-imx6q.c')
-rw-r--r-- | arch/arm/mach-imx/clk-imx6q.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index c0c4e723b7f5..d38e54f5b6d7 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; |
@@ -105,7 +115,7 @@ static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m" | |||
105 | static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; | 115 | static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; |
106 | static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; | 116 | static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; |
107 | static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; | 117 | static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; |
108 | static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", }; | 118 | static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; |
109 | static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; | 119 | static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; |
110 | static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; | 120 | static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; |
111 | static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; | 121 | static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; |
@@ -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); |
@@ -420,7 +443,6 @@ int __init mx6q_clocks_init(void) | |||
420 | 443 | ||
421 | clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); | 444 | clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); |
422 | clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); | 445 | clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); |
423 | clk_register_clkdev(clk[twd], NULL, "smp_twd"); | ||
424 | clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); | 446 | clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); |
425 | clk_register_clkdev(clk[ahb], "ahb", NULL); | 447 | clk_register_clkdev(clk[ahb], "ahb", NULL); |
426 | clk_register_clkdev(clk[cko1], "cko1", NULL); | 448 | clk_register_clkdev(clk[cko1], "cko1", NULL); |
@@ -436,6 +458,11 @@ int __init mx6q_clocks_init(void) | |||
436 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) | 458 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) |
437 | clk_prepare_enable(clk[clks_init_on[i]]); | 459 | clk_prepare_enable(clk[clks_init_on[i]]); |
438 | 460 | ||
461 | if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { | ||
462 | clk_prepare_enable(clk[usbphy1_gate]); | ||
463 | clk_prepare_enable(clk[usbphy2_gate]); | ||
464 | } | ||
465 | |||
439 | /* Set initial power mode */ | 466 | /* Set initial power mode */ |
440 | imx6q_set_lpm(WAIT_CLOCKED); | 467 | imx6q_set_lpm(WAIT_CLOCKED); |
441 | 468 | ||