aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/clock.c')
-rw-r--r--arch/arm/mach-tegra/clock.c78
1 files changed, 60 insertions, 18 deletions
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 966009f375..575da2bdb5 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -128,14 +128,14 @@ unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
struct clk_pll_simple *simple_pll = NULL;
u32 misc_data, data;
- if (clkid < (enum clock_id)TEGRA_CLK_PLLS) {
+ if (clkid < (enum clock_id)TEGRA_CLK_PLLS)
pll = get_pll(clkid);
- } else {
+ else
simple_pll = clock_get_simple_pll(clkid);
- if (!simple_pll) {
- debug("%s: Uknown simple PLL %d\n", __func__, clkid);
- return 0;
- }
+
+ if (!simple_pll && !pll) {
+ log_err("Unknown PLL id %d\n", clkid);
+ return 0;
}
/*
@@ -542,7 +542,8 @@ unsigned int __weak clk_m_get_rate(unsigned int parent_rate)
unsigned clock_get_rate(enum clock_id clkid)
{
- struct clk_pll *pll;
+ struct clk_pll *pll = NULL;
+ struct clk_pll_simple *simple_pll = NULL;
u32 base, divm;
u64 parent_rate, rate;
struct clk_pll_info *pllinfo = &tegra_pll_info_table[clkid];
@@ -554,10 +555,20 @@ unsigned clock_get_rate(enum clock_id clkid)
if (clkid == CLOCK_ID_CLK_M)
return clk_m_get_rate(parent_rate);
- pll = get_pll(clkid);
- if (!pll)
+ if (clkid < (enum clock_id)TEGRA_CLK_PLLS)
+ pll = get_pll(clkid);
+ else
+ simple_pll = clock_get_simple_pll(clkid);
+
+ if (!simple_pll && !pll) {
+ log_err("Unknown PLL id %d\n", clkid);
return 0;
- base = readl(&pll->pll_base);
+ }
+
+ if (pll)
+ base = readl(&pll->pll_base);
+ else
+ base = readl(&simple_pll->pll_base);
rate = parent_rate * ((base >> pllinfo->n_shift) & pllinfo->n_mask);
divm = (base >> pllinfo->m_shift) & pllinfo->m_mask;
@@ -599,12 +610,24 @@ unsigned clock_get_rate(enum clock_id clkid)
int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
{
u32 base_reg, misc_reg;
- struct clk_pll *pll;
+ struct clk_pll *pll = NULL;
+ struct clk_pll_simple *simple_pll = NULL;
struct clk_pll_info *pllinfo = &tegra_pll_info_table[clkid];
- pll = get_pll(clkid);
+ if (clkid < (enum clock_id)TEGRA_CLK_PLLS)
+ pll = get_pll(clkid);
+ else
+ simple_pll = clock_get_simple_pll(clkid);
- base_reg = readl(&pll->pll_base);
+ if (!simple_pll && !pll) {
+ log_err("Unknown PLL id %d\n", clkid);
+ return 0;
+ }
+
+ if (pll)
+ base_reg = readl(&pll->pll_base);
+ else
+ base_reg = readl(&simple_pll->pll_base);
/* Set BYPASS, m, n and p to PLL_BASE */
base_reg &= ~(pllinfo->m_mask << pllinfo->m_shift);
@@ -631,21 +654,37 @@ int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
}
base_reg |= PLL_BYPASS_MASK;
- writel(base_reg, &pll->pll_base);
+ if (pll)
+ writel(base_reg, &pll->pll_base);
+ else
+ writel(base_reg, &simple_pll->pll_base);
/* Set cpcon (KCP) to PLL_MISC */
- misc_reg = readl(&pll->pll_misc);
+ if (pll)
+ misc_reg = readl(&pll->pll_misc);
+ else
+ misc_reg = readl(&simple_pll->pll_misc);
+
misc_reg &= ~(pllinfo->kcp_mask << pllinfo->kcp_shift);
misc_reg |= cpcon << pllinfo->kcp_shift;
- writel(misc_reg, &pll->pll_misc);
+ if (pll)
+ writel(misc_reg, &pll->pll_misc);
+ else
+ writel(misc_reg, &simple_pll->pll_misc);
/* Enable PLL */
base_reg |= PLL_ENABLE_MASK;
- writel(base_reg, &pll->pll_base);
+ if (pll)
+ writel(base_reg, &pll->pll_base);
+ else
+ writel(base_reg, &simple_pll->pll_base);
/* Disable BYPASS */
base_reg &= ~PLL_BYPASS_MASK;
- writel(base_reg, &pll->pll_base);
+ if (pll)
+ writel(base_reg, &pll->pll_base);
+ else
+ writel(base_reg, &simple_pll->pll_base);
return 0;
}
@@ -729,6 +768,9 @@ void clock_init(void)
pll_rate[CLOCK_ID_SFROM32KHZ] = 32768;
pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC);
pll_rate[CLOCK_ID_CLK_M] = clock_get_rate(CLOCK_ID_CLK_M);
+#ifndef CONFIG_TEGRA20
+ pll_rate[CLOCK_ID_DISPLAY2] = clock_get_rate(CLOCK_ID_DISPLAY2);
+#endif
debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]);
debug("CLKM = %d\n", pll_rate[CLOCK_ID_CLK_M]);