if (clk->parent)
__clk_enable(clk->parent);
if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
- davinci_psc_config(psc_domain(clk), clk->lpsc, 1);
+ davinci_psc_config(psc_domain(clk), clk->psc_ctlr,
+ clk->lpsc, 1);
}
static void __clk_disable(struct clk *clk)
if (WARN_ON(clk->usecount == 0))
return;
if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
- davinci_psc_config(psc_domain(clk), clk->lpsc, 0);
+ davinci_psc_config(psc_domain(clk), clk->psc_ctlr,
+ clk->lpsc, 0);
if (clk->parent)
__clk_disable(clk->parent);
}
continue;
/* ignore if in Disabled or SwRstDisable states */
- if (!davinci_psc_is_clk_active(ck->lpsc))
+ if (!davinci_psc_is_clk_active(ck->psc_ctlr, ck->lpsc))
continue;
pr_info("Clocks: disable unused %s\n", ck->name);
- davinci_psc_config(psc_domain(ck), ck->lpsc, 0);
+ davinci_psc_config(psc_domain(ck), ck->psc_ctlr, ck->lpsc, 0);
}
spin_unlock_irq(&clockfw_lock);
u8 usecount;
u8 flags;
u8 lpsc;
+ u8 psc_ctlr;
struct clk *parent;
struct pll_data *pll_data;
u32 div_reg;
},
};
+static void __iomem *dm355_psc_bases[] = {
+ IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
+};
+
static struct davinci_soc_info davinci_soc_info_dm355 = {
.io_desc = dm355_io_desc,
.io_desc_num = ARRAY_SIZE(dm355_io_desc),
.ids = dm355_ids,
.ids_num = ARRAY_SIZE(dm355_ids),
.cpu_clks = dm355_clks,
+ .psc_bases = dm355_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm355_psc_bases),
};
void __init dm355_init(void)
},
};
+static void __iomem *dm644x_psc_bases[] = {
+ IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
+};
+
static struct davinci_soc_info davinci_soc_info_dm644x = {
.io_desc = dm644x_io_desc,
.io_desc_num = ARRAY_SIZE(dm644x_io_desc),
.ids = dm644x_ids,
.ids_num = ARRAY_SIZE(dm644x_ids),
.cpu_clks = dm644x_clks,
+ .psc_bases = dm644x_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
};
void __init dm644x_init(void)
},
};
+static void __iomem *dm646x_psc_bases[] = {
+ IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
+};
+
static struct davinci_soc_info davinci_soc_info_dm646x = {
.io_desc = dm646x_io_desc,
.io_desc_num = ARRAY_SIZE(dm646x_io_desc),
.ids = dm646x_ids,
.ids_num = ARRAY_SIZE(dm646x_ids),
.cpu_clks = dm646x_clks,
+ .psc_bases = dm646x_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases),
};
void __init dm646x_init(void)
struct davinci_id *ids;
unsigned long ids_num;
struct davinci_clk *cpu_clks;
+ void __iomem **psc_bases;
+ unsigned long psc_bases_num;
};
extern struct davinci_soc_info davinci_soc_info;
#ifndef __ASM_ARCH_PSC_H
#define __ASM_ARCH_PSC_H
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
+
/* Power and Sleep Controller (PSC) Domains */
#define DAVINCI_GPSC_ARMDOMAIN 0
#define DAVINCI_GPSC_DSPDOMAIN 1
#define DM646X_LPSC_TIMER1 35
#define DM646X_LPSC_ARM_INTC 45
-extern int davinci_psc_is_clk_active(unsigned int id);
-extern void davinci_psc_config(unsigned int domain, unsigned int id,
- char enable);
+extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
+extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+ unsigned int id, char enable);
#endif /* __ASM_ARCH_PSC_H */
#include <mach/psc.h>
#include <mach/mux.h>
-#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
-
/* PSC register offsets */
#define EPCPR 0x070
#define PTCMD 0x120
#define MDSTAT_STATE_MASK 0x1f
/* Return nonzero iff the domain's clock is active */
-int __init davinci_psc_is_clk_active(unsigned int id)
+int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
{
- void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE);
- u32 mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
+ void __iomem *psc_base;
+ u32 mdstat;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
+ pr_warning("PSC: Bad psc data: 0x%x[%d]\n",
+ (int)soc_info->psc_bases, ctlr);
+ return 0;
+ }
+
+ psc_base = soc_info->psc_bases[ctlr];
+ mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
/* if clocked, state can be "Enable" or "SyncReset" */
return mdstat & BIT(12);
}
/* Enable or disable a PSC domain */
-void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
+void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+ unsigned int id, char enable)
{
u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl;
- void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE);
+ void __iomem *psc_base;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
u32 next_state = enable ? 0x3 : 0x2; /* 0x3 enables, 0x2 disables */
+ if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
+ pr_warning("PSC: Bad psc data: 0x%x[%d]\n",
+ (int)soc_info->psc_bases, ctlr);
+ return;
+ }
+
+ psc_base = soc_info->psc_bases[ctlr];
+
mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
mdctl &= ~MDSTAT_STATE_MASK;
mdctl |= next_state;