aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/clk-imx6q.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/clk-imx6q.c')
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c43
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
57static void __iomem *ccm_base; 60static void __iomem *ccm_base;
58 61
59void __init imx6q_clock_map_io(void) { } 62void 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
61int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) 70int 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"
105static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; 115static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
106static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; 116static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
107static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; 117static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
108static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", }; 118static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
109static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; 119static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
110static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 120static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
111static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; 121static 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
161static struct clk *clk[clk_max]; 171static struct clk *clk[clk_max];
162static struct clk_onecell_data clk_data; 172static struct clk_onecell_data clk_data;
163 173
164static enum mx6q_clks const clks_init_on[] __initconst = { 174static enum mx6q_clks const clks_init_on[] __initconst = {
165 mmdc_ch0_axi, rom, 175 mmdc_ch0_axi, rom, pll1_sys,
166}; 176};
167 177
168static struct clk_div_table clk_enet_ref_table[] = { 178static 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