omap2 clock: add support for inverted enable bits
authorPaul Walmsley <paul@pwsan.com>
Thu, 27 Sep 2007 06:11:22 +0000 (00:11 -0600)
committerTony Lindgren <tony@atomide.com>
Fri, 28 Sep 2007 22:55:18 +0000 (15:55 -0700)
On 3430ES2 (and presumably beyond), some clock tree branches from
DPLL3 & 4 can be powered down by setting 'PWRDN' bits in CM_CLKEN_PLL.
It appears that an easy way to power these branches down in our
existing clock framework is to use the PWRDN bits as clock enable bits
for the specific DPLL branches they affect.  The problem with this is
that the meaning of a set PWRDN bit is 'disable,' not 'enable.'  So,
introduce a new clock flag, INVERT_ENABLE, that clears the bit on
'clock enable,' and sets the bit on 'clock disable.'  This flag is used
on all PWRDN clock branches in the 3430 clock framework.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/clock.c
include/asm-arm/arch-omap/clock.h

index 0fba409..1696c46 100644 (file)
@@ -170,6 +170,11 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name)
 };
 
 
+/*
+ * Note: We don't need special code here for INVERT_ENABLE
+ * for the time being since INVERT_ENABLE only applies to clocks enabled by
+ * CM_CLKEN_PLL
+ */
 static void omap2_clk_wait_ready(struct clk *clk)
 {
        void __iomem *reg, *other_reg, *st_reg;
@@ -224,7 +229,10 @@ int _omap2_clk_enable(struct clk *clk)
        }
 
        regval32 = cm_read_reg(clk->enable_reg);
-       regval32 |= (1 << clk->enable_bit);
+       if (clk->flags & INVERT_ENABLE)
+               regval32 &= ~(1 << clk->enable_bit);
+       else
+               regval32 |= (1 << clk->enable_bit);
        cm_write_reg(regval32, clk->enable_reg);
        wmb();
 
@@ -257,7 +265,10 @@ void _omap2_clk_disable(struct clk *clk)
        }
 
        regval32 = cm_read_reg(clk->enable_reg);
-       regval32 &= ~(1 << clk->enable_bit);
+       if (clk->flags & INVERT_ENABLE)
+               regval32 |= (1 << clk->enable_bit);
+       else
+               regval32 &= ~(1 << clk->enable_bit);
        cm_write_reg(regval32, clk->enable_reg);
        wmb();
 }
@@ -709,10 +720,12 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
 #ifdef CONFIG_OMAP_RESET_CLOCKS
 void __init omap2_clk_disable_unused(struct clk *clk)
 {
-       u32 regval32;
+       u32 regval32, v;
+
+       v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0;
 
        regval32 = cm_read_reg(clk->enable_reg);
-       if ((regval32 & (1 << clk->enable_bit)) == 0)
+       if ((regval32 & (1 << clk->enable_bit)) == v)
                return;
 
        printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name);
index 2e471c5..8986955 100644 (file)
@@ -104,7 +104,8 @@ extern void clk_enable_init_clocks(void);
 #define DELAYED_APP            (1 << 9)        /* Delay application of clock */
 #define CONFIG_PARTICIPANT     (1 << 10)       /* Fundamental clock */
 #define ENABLE_ON_INIT         (1 << 11)       /* Enable upon framework init */
-/* bits 12-20 are currently free */
+#define INVERT_ENABLE           (1 << 12)       /* 0 enables, 1 disables */
+/* bits 13-20 are currently free */
 #define CLOCK_IN_OMAP310       (1 << 21)
 #define CLOCK_IN_OMAP730       (1 << 22)
 #define CLOCK_IN_OMAP1510      (1 << 23)