From 16ca1d09e62d7d3d71f48313428cf7cf026fa177 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 17 Aug 2015 13:29:51 +0530 Subject: ARM: OMAP5: Add support for disabling clocks in uboot Add do_disable_clocks() to disable clock domains and module clocks. These clocks are enabled using do_enable_clocks(). Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Vignesh R Reviewed-by: Jagan Teki --- arch/arm/cpu/armv7/omap-common/clocks-common.c | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'arch/arm/cpu/armv7') diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c index c94a807819..e28b79568d 100644 --- a/arch/arm/cpu/armv7/omap-common/clocks-common.c +++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c @@ -648,6 +648,14 @@ static inline void enable_clock_domain(u32 const clkctrl_reg, u32 enable_mode) debug("Enable clock domain - %x\n", clkctrl_reg); } +static inline void disable_clock_domain(u32 const clkctrl_reg) +{ + clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK, + CD_CLKCTRL_CLKTRCTRL_SW_SLEEP << + CD_CLKCTRL_CLKTRCTRL_SHIFT); + debug("Disable clock domain - %x\n", clkctrl_reg); +} + static inline void wait_for_clk_enable(u32 clkctrl_addr) { u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED; @@ -677,6 +685,34 @@ static inline void enable_clock_module(u32 const clkctrl_addr, u32 enable_mode, wait_for_clk_enable(clkctrl_addr); } +static inline void wait_for_clk_disable(u32 clkctrl_addr) +{ + u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_FULLY_FUNCTIONAL; + u32 bound = LDELAY; + + while ((idlest != MODULE_CLKCTRL_IDLEST_DISABLED)) { + clkctrl = readl(clkctrl_addr); + idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >> + MODULE_CLKCTRL_IDLEST_SHIFT; + if (--bound == 0) { + printf("Clock disable failed for 0x%x idlest 0x%x\n", + clkctrl_addr, clkctrl); + return; + } + } +} + +static inline void disable_clock_module(u32 const clkctrl_addr, + u32 wait_for_disable) +{ + clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_DISABLE << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + debug("Disable clock module - %x\n", clkctrl_addr); + if (wait_for_disable) + wait_for_clk_disable(clkctrl_addr); +} + void freq_update_core(void) { u32 freq_config1 = 0; @@ -800,6 +836,23 @@ void do_enable_clocks(u32 const *clk_domains, } } +void do_disable_clocks(u32 const *clk_domains, + u32 const *clk_modules_disable, + u8 wait_for_disable) +{ + u32 i, max = 100; + + + /* Clock modules that need to be put in SW_DISABLE */ + for (i = 0; (i < max) && clk_modules_disable[i]; i++) + disable_clock_module(clk_modules_disable[i], + wait_for_disable); + + /* Put the clock domains in SW_SLEEP mode */ + for (i = 0; (i < max) && clk_domains[i]; i++) + disable_clock_domain(clk_domains[i]); +} + void prcm_init(void) { switch (omap_hw_init_context()) { -- cgit