Skip to content

Commit

Permalink
ARM: davinci: da850: use clk->set_parent for async3
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David Lechner authored and Sekhar Nori committed Apr 27, 2016
1 parent 6fc9ebb commit 3f2a09d
Showing 1 changed file with 33 additions and 48 deletions.
81 changes: 33 additions & 48 deletions arch/arm/mach-davinci/da850.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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[] = {
Expand All @@ -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),
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 3f2a09d

Please sign in to comment.