diff options
Diffstat (limited to 'arch/arm/mach-tegra/tegra2_clocks.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra2_clocks.c | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index 7c42e7b1481a..b1f1dd3f63c6 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -779,8 +779,9 @@ static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate) if (sel->input_rate == 0) { unsigned long cfreq; - BUG_ON(c->flags & PLLU); struct clk_pll_freq_table cfg; + + BUG_ON(c->flags & PLLU); sel = &cfg; switch (input_rate) { @@ -2486,10 +2487,12 @@ struct clk tegra_list_periph_clks[] = { PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 0x31E, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 0x31E, 600000000, mux_pllp_plld_pllc_clkm, MUX), /* scales with voltage and process_id */ PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 0x31E, 600000000, mux_pllp_plld_pllc_clkm, MUX), /* scales with voltage and process_id */ - PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */ + PERIPH_CLK("usbd", "tegra-udc.0", NULL, 22, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */ PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */ PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 0x31E, 480000000, mux_clk_m, 0), /* requires min voltage */ PERIPH_CLK("dsia", "tegradc.0", "dsia", 48, 0, 0x31E, 500000000, mux_plld_out0, 0), /* scales with voltage */ + PERIPH_CLK("dsi1-fixed", "tegradc.0", "dsi-fixed", 0, 0, 0x31E, 108000000, mux_pllp_out3, PERIPH_NO_ENB), + PERIPH_CLK("dsi2-fixed", "tegradc.1", "dsi-fixed", 0, 0, 0x31E, 108000000, mux_pllp_out3, PERIPH_NO_ENB), PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 0x31E, 72000000, mux_pllp_out3, 0), PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 0x31E, 150000000, mux_clk_m, 0), /* same frequency as VI */ PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 0x31E, 150000000, mux_clk_m, PERIPH_NO_RESET), @@ -2503,7 +2506,7 @@ struct clk tegra_list_shared_clks[] = { SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_virtual_sclk), SHARED_CLK("mon.sclk", "tegra-stat-mon", "sclk", &tegra_clk_virtual_sclk), SHARED_CLK("bsea.sclk", "tegra-aes", "sclk", &tegra_clk_virtual_sclk), - SHARED_CLK("usbd.sclk", "fsl-tegra-udc", "sclk", &tegra_clk_virtual_sclk), + SHARED_CLK("usbd.sclk", "tegra-udc.0", "sclk", &tegra_clk_virtual_sclk), SHARED_CLK("usb1.sclk", "tegra-ehci.0", "sclk", &tegra_clk_virtual_sclk), SHARED_CLK("usb2.sclk", "tegra-ehci.1", "sclk", &tegra_clk_virtual_sclk), SHARED_CLK("usb3.sclk", "tegra-ehci.2", "sclk", &tegra_clk_virtual_sclk), @@ -2519,7 +2522,7 @@ struct clk tegra_list_shared_clks[] = { SHARED_CLK("3d.emc", "tegra_gr3d", "emc", &tegra_clk_emc), SHARED_CLK("2d.emc", "tegra_gr2d", "emc", &tegra_clk_emc), SHARED_CLK("mpe.emc", "tegra_mpe", "emc", &tegra_clk_emc), - SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc), + SHARED_CLK("usbd.emc", "tegra-udc.0", "emc", &tegra_clk_emc), SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc), SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc), SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc), @@ -2770,7 +2773,7 @@ unsigned long tegra_emc_to_cpu_ratio(unsigned long cpu_rate) #ifdef CONFIG_PM_SLEEP static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM + - PERIPH_CLK_SOURCE_NUM + 22]; + PERIPH_CLK_SOURCE_NUM + 24]; static int tegra_clk_suspend(void) { @@ -2778,6 +2781,8 @@ static int tegra_clk_suspend(void) u32 *ctx = clk_rst_suspend; *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK; + *ctx++ = clk_readl(tegra_pll_p_out1.reg); + *ctx++ = clk_readl(tegra_pll_p_out3.reg); *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE); *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c)); *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE); @@ -2830,11 +2835,26 @@ static void tegra_clk_resume(void) unsigned long off, i; const u32 *ctx = clk_rst_suspend; u32 val; + u32 pll_p_out12, pll_p_out34; + u32 pll_m_out1, pll_a_out0, pll_c_out1; val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK; val |= *ctx++; clk_writel(val, OSC_CTRL); + /* Since we are going to reset devices and switch clock sources in this + * function, plls and secondary dividers is required to be enabled. The + * actual value will be restored back later. Note that boot plls: pllm, + * pllp, and pllu are already configured and enabled. + */ + + val = PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE; + val |= val << 16; + pll_p_out12 = *ctx++; + clk_writel(pll_p_out12 | val, tegra_pll_p_out1.reg); + pll_p_out34 = *ctx++; + clk_writel(pll_p_out34 | val, tegra_pll_p_out3.reg); + clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE); clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c)); clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE); @@ -2847,9 +2867,13 @@ static void tegra_clk_resume(void) clk_writel(*ctx++, tegra_pll_u.reg + PLL_MISC(&tegra_pll_u)); udelay(1000); - clk_writel(*ctx++, tegra_pll_m_out1.reg); - clk_writel(*ctx++, tegra_pll_a_out0.reg); - clk_writel(*ctx++, tegra_pll_c_out1.reg); + val = PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE; + pll_m_out1 = *ctx++; + clk_writel(pll_m_out1 | val, tegra_pll_m_out1.reg); + pll_a_out0 = *ctx++; + clk_writel(pll_a_out0 | val, tegra_pll_a_out0.reg); + pll_c_out1 = *ctx++; + clk_writel(pll_c_out1 | val, tegra_pll_c_out1.reg); clk_writel(*ctx++, tegra_clk_cclk.reg); clk_writel(*ctx++, tegra_clk_cclk.reg + SUPER_CLK_DIVIDER); @@ -2886,6 +2910,13 @@ static void tegra_clk_resume(void) clk_writel(*ctx++, MISC_CLK_ENB); clk_writel(*ctx++, CLK_MASK_ARM); + + /* Restore back the actual pll and secondary divider values */ + clk_writel(pll_p_out12, tegra_pll_p_out1.reg); + clk_writel(pll_p_out34, tegra_pll_p_out3.reg); + clk_writel(pll_m_out1, tegra_pll_m_out1.reg); + clk_writel(pll_a_out0, tegra_pll_a_out0.reg); + clk_writel(pll_c_out1, tegra_pll_c_out1.reg); } #else |