ARM: davinci: da850: use clk->set_parent for async3
The da850 family of processors has an async3 clock domain that can be muxed to either pll0_sysclk2 or pll1_sysclk2. Now that the davinci clocks have a set_parent callback, we can use this to control the async3 mux instead of a stand-alone function. This adds a new async3_clk and sets the appropriate child clocks. The default is use to pll1_sysclk2 since it is not affected by processor frequency scaling. Signed-off-by: David Lechner <david@lechnology.com> [nsekhar@ti.com: drop unnecessary comment] Signed-off-by: Sekhar Nori <nsekhar@ti.com>
This commit is contained in:
parent
6fc9ebbdeb
commit
3f2a09d57b
1 changed files with 33 additions and 48 deletions
|
@ -34,9 +34,6 @@
|
|||
#include "clock.h"
|
||||
#include "mux.h"
|
||||
|
||||
/* SoC specific clock flags */
|
||||
#define DA850_CLK_ASYNC3 BIT(16)
|
||||
|
||||
#define DA850_PLL1_BASE 0x01e1a000
|
||||
#define DA850_TIMER64P2_BASE 0x01f0c000
|
||||
#define DA850_TIMER64P3_BASE 0x01f0d000
|
||||
|
@ -161,6 +158,32 @@ static struct clk pll1_sysclk3 = {
|
|||
.div_reg = PLLDIV3,
|
||||
};
|
||||
|
||||
static int da850_async3_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
|
||||
if (parent == &pll0_sysclk2) {
|
||||
val &= ~CFGCHIP3_ASYNC3_CLKSRC;
|
||||
} else if (parent == &pll1_sysclk2) {
|
||||
val |= CFGCHIP3_ASYNC3_CLKSRC;
|
||||
} else {
|
||||
pr_err("Bad parent on async3 clock mux\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk async3_clk = {
|
||||
.name = "async3",
|
||||
.parent = &pll1_sysclk2,
|
||||
.set_parent = da850_async3_set_parent,
|
||||
};
|
||||
|
||||
static struct clk i2c0_clk = {
|
||||
.name = "i2c0",
|
||||
.parent = &pll0_aux_clk,
|
||||
|
@ -234,18 +257,16 @@ static struct clk uart0_clk = {
|
|||
|
||||
static struct clk uart1_clk = {
|
||||
.name = "uart1",
|
||||
.parent = &pll0_sysclk2,
|
||||
.parent = &async3_clk,
|
||||
.lpsc = DA8XX_LPSC1_UART1,
|
||||
.gpsc = 1,
|
||||
.flags = DA850_CLK_ASYNC3,
|
||||
};
|
||||
|
||||
static struct clk uart2_clk = {
|
||||
.name = "uart2",
|
||||
.parent = &pll0_sysclk2,
|
||||
.parent = &async3_clk,
|
||||
.lpsc = DA8XX_LPSC1_UART2,
|
||||
.gpsc = 1,
|
||||
.flags = DA850_CLK_ASYNC3,
|
||||
};
|
||||
|
||||
static struct clk aintc_clk = {
|
||||
|
@ -300,10 +321,9 @@ static struct clk emac_clk = {
|
|||
|
||||
static struct clk mcasp_clk = {
|
||||
.name = "mcasp",
|
||||
.parent = &pll0_sysclk2,
|
||||
.parent = &async3_clk,
|
||||
.lpsc = DA8XX_LPSC1_McASP0,
|
||||
.gpsc = 1,
|
||||
.flags = DA850_CLK_ASYNC3,
|
||||
};
|
||||
|
||||
static struct clk lcdc_clk = {
|
||||
|
@ -355,10 +375,9 @@ static struct clk spi0_clk = {
|
|||
|
||||
static struct clk spi1_clk = {
|
||||
.name = "spi1",
|
||||
.parent = &pll0_sysclk2,
|
||||
.parent = &async3_clk,
|
||||
.lpsc = DA8XX_LPSC1_SPI1,
|
||||
.gpsc = 1,
|
||||
.flags = DA850_CLK_ASYNC3,
|
||||
};
|
||||
|
||||
static struct clk vpif_clk = {
|
||||
|
@ -386,10 +405,9 @@ static struct clk dsp_clk = {
|
|||
|
||||
static struct clk ehrpwm_clk = {
|
||||
.name = "ehrpwm",
|
||||
.parent = &pll0_sysclk2,
|
||||
.parent = &async3_clk,
|
||||
.lpsc = DA8XX_LPSC1_PWM,
|
||||
.gpsc = 1,
|
||||
.flags = DA850_CLK_ASYNC3,
|
||||
};
|
||||
|
||||
#define DA8XX_EHRPWM_TBCLKSYNC BIT(12)
|
||||
|
@ -421,10 +439,9 @@ static struct clk ehrpwm_tbclk = {
|
|||
|
||||
static struct clk ecap_clk = {
|
||||
.name = "ecap",
|
||||
.parent = &pll0_sysclk2,
|
||||
.parent = &async3_clk,
|
||||
.lpsc = DA8XX_LPSC1_ECAP,
|
||||
.gpsc = 1,
|
||||
.flags = DA850_CLK_ASYNC3,
|
||||
};
|
||||
|
||||
static struct clk_lookup da850_clks[] = {
|
||||
|
@ -442,6 +459,7 @@ static struct clk_lookup da850_clks[] = {
|
|||
CLK(NULL, "pll1_aux", &pll1_aux_clk),
|
||||
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
|
||||
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
|
||||
CLK(NULL, "async3", &async3_clk),
|
||||
CLK("i2c_davinci.1", NULL, &i2c0_clk),
|
||||
CLK(NULL, "timer0", &timerp64_0_clk),
|
||||
CLK("davinci-wdt", NULL, &timerp64_1_clk),
|
||||
|
@ -909,30 +927,6 @@ static struct davinci_timer_info da850_timer_info = {
|
|||
.clocksource_id = T0_TOP,
|
||||
};
|
||||
|
||||
static void da850_set_async3_src(int pllnum)
|
||||
{
|
||||
struct clk *clk, *newparent = pllnum ? &pll1_sysclk2 : &pll0_sysclk2;
|
||||
struct clk_lookup *c;
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
for (c = da850_clks; c->clk; c++) {
|
||||
clk = c->clk;
|
||||
if (clk->flags & DA850_CLK_ASYNC3) {
|
||||
ret = clk_set_parent(clk, newparent);
|
||||
WARN(ret, "DA850: unable to re-parent clock %s",
|
||||
clk->name);
|
||||
}
|
||||
}
|
||||
|
||||
v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
if (pllnum)
|
||||
v |= CFGCHIP3_ASYNC3_CLKSRC;
|
||||
else
|
||||
v &= ~CFGCHIP3_ASYNC3_CLKSRC;
|
||||
__raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
/*
|
||||
* Notes:
|
||||
|
@ -1328,15 +1322,6 @@ void __init da850_init(void)
|
|||
if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Move the clock source of Async3 domain to PLL1 SYSCLK2.
|
||||
* This helps keeping the peripherals on this domain insulated
|
||||
* from CPU frequency changes caused by DVFS. The firmware sets
|
||||
* both PLL0 and PLL1 to the same frequency so, there should not
|
||||
* be any noticeable change even in non-DVFS use cases.
|
||||
*/
|
||||
da850_set_async3_src(1);
|
||||
|
||||
/* Unlock writing to PLL0 registers */
|
||||
v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
|
||||
v &= ~CFGCHIP0_PLL_MASTER_LOCK;
|
||||
|
|
Loading…
Reference in a new issue