[PATCH] ARM: 2804/1: OMAP update 9/11: Update OMAP arch files
authorTony Lindgren <tony@atomide.com>
Sun, 10 Jul 2005 18:58:18 +0000 (19:58 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 10 Jul 2005 18:58:18 +0000 (19:58 +0100)
Patch from Tony Lindgren

This patch by various OMAP developers syncs the OMAP
specific arch files with the linux-omap tree.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-omap1/io.c
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/clock.c
arch/arm/plat-omap/clock.h
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/mcbsp.c
arch/arm/plat-omap/mux.c
arch/arm/plat-omap/usb.c
include/asm-arm/arch-omap/dma.h
include/asm-arm/arch-omap/mux.h

index f1258c1..207df0f 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/io.h>
 #include <asm/arch/tc.h>
 
+extern int clk_init(void);
 extern void omap_check_revision(void);
 
 /*
index a72fe55..3453658 100644 (file)
@@ -19,6 +19,19 @@ endchoice
 
 comment "OMAP Feature Selections"
 
+config OMAP_RESET_CLOCKS
+       bool "Reset unused clocks during boot"
+       depends on ARCH_OMAP
+       default n
+       help
+         Say Y if you want to reset unused clocks during boot.
+         This option saves power, but assumes all drivers are
+         using the clock framework. Broken drivers that do not
+         yet use clock framework may not work with this option.
+         If you are booting from another operating system, you
+         probably do not want this option enabled until your
+         device drivers work properly.
+
 config OMAP_MUX
        bool "OMAP multiplexing support"
         depends on ARCH_OMAP
index 155157f..59d91b3 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 
+#include <asm/io.h>
 #include <asm/semaphore.h>
 #include <asm/hardware/clock.h>
 #include <asm/arch/board.h>
@@ -25,6 +26,8 @@ static LIST_HEAD(clocks);
 static DECLARE_MUTEX(clocks_sem);
 static DEFINE_SPINLOCK(clockfw_lock);
 static void propagate_rate(struct clk *  clk);
+/* UART clock function */
+static int set_uart_rate(struct clk * clk, unsigned long rate);
 /* External clock (MCLK & BCLK) functions */
 static int set_ext_clk_rate(struct clk *  clk, unsigned long rate);
 static long round_ext_clk_rate(struct clk *  clk, unsigned long rate);
@@ -34,7 +37,7 @@ static int select_table_rate(struct clk *  clk, unsigned long rate);
 static long round_to_table_rate(struct clk *  clk, unsigned long rate);
 void clk_setdpll(__u16, __u16);
 
-struct mpu_rate rate_table[] = {
+static struct mpu_rate rate_table[] = {
        /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
         * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
         */
@@ -48,7 +51,7 @@ struct mpu_rate rate_table[] = {
        { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
        { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
        {  96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
-       {  48000000, 12000000, 192000000, 0x0ccf, 0x2810 }, /* 4/4/4/4/8/8 */
+       {  48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/8/4/4/8/8 */
        {  24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
 #endif
 #if defined(CONFIG_OMAP_ARM_182MHZ)
@@ -58,7 +61,7 @@ struct mpu_rate rate_table[] = {
        { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
 #endif
 #if defined(CONFIG_OMAP_ARM_150MHZ)
-       { 150000000, 12000000, 150000000, 0x150a, 0x2cb0 }, /* 0/0/1/1/2/2 */
+       { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
 #endif
 #if defined(CONFIG_OMAP_ARM_120MHZ)
        { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
@@ -76,19 +79,11 @@ struct mpu_rate rate_table[] = {
 };
 
 
-static void ckctl_recalc(struct clk *  clk)
-{
-       int dsor;
-
-       /* Calculate divisor encoded as 2-bit exponent */
-       dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
-       if (unlikely(clk->rate == clk->parent->rate / dsor))
-               return; /* No change, quick exit */
-       clk->rate = clk->parent->rate / dsor;
-
-       if (unlikely(clk->flags & RATE_PROPAGATES))
-               propagate_rate(clk);
-}
+static void ckctl_recalc(struct clk *  clk);
+int __clk_enable(struct clk *clk);
+void __clk_disable(struct clk *clk);
+void __clk_unuse(struct clk *clk);
+int __clk_use(struct clk *clk);
 
 
 static void followparent_recalc(struct clk *  clk)
@@ -102,6 +97,14 @@ static void watchdog_recalc(struct clk *  clk)
        clk->rate = clk->parent->rate / 14;
 }
 
+static void uart_recalc(struct clk * clk)
+{
+       unsigned int val = omap_readl(clk->enable_reg);
+       if (val & clk->enable_bit)
+               clk->rate = 48000000;
+       else
+               clk->rate = 12000000;
+}
 
 static struct clk ck_ref = {
        .name           = "ck_ref",
@@ -138,7 +141,7 @@ static struct clk arm_ck = {
 static struct clk armper_ck = {
        .name           = "armper_ck",
        .parent         = &ck_dpll1,
-       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+       .flags          = CLOCK_IN_OMAP730 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
                          RATE_CKCTL,
        .enable_reg     = ARM_IDLECT2,
        .enable_bit     = EN_PERCK,
@@ -185,7 +188,7 @@ static struct clk armwdt_ck = {
 static struct clk arminth_ck16xx = {
        .name           = "arminth_ck",
        .parent         = &arm_ck,
-       .flags          = CLOCK_IN_OMAP16XX,
+       .flags          = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
        .recalc         = &followparent_recalc,
        /* Note: On 16xx the frequency can be divided by 2 by programming
         * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
@@ -214,6 +217,38 @@ static struct clk dspmmu_ck = {
        .recalc         = &ckctl_recalc,
 };
 
+static struct clk dspper_ck = {
+       .name           = "dspper_ck",
+       .parent         = &ck_dpll1,
+       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+                         RATE_CKCTL | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
+       .enable_reg     = DSP_IDLECT2,
+       .enable_bit     = EN_PERCK,
+       .rate_offset    = CKCTL_PERDIV_OFFSET,
+       .recalc         = &followparent_recalc,
+       //.recalc               = &ckctl_recalc,
+};
+
+static struct clk dspxor_ck = {
+       .name           = "dspxor_ck",
+       .parent         = &ck_ref,
+       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+                         DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
+       .enable_reg     = DSP_IDLECT2,
+       .enable_bit     = EN_XORPCK,
+       .recalc         = &followparent_recalc,
+};
+
+static struct clk dsptim_ck = {
+       .name           = "dsptim_ck",
+       .parent         = &ck_ref,
+       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+                         DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
+       .enable_reg     = DSP_IDLECT2,
+       .enable_bit     = EN_DSPTIMCK,
+       .recalc         = &followparent_recalc,
+};
+
 static struct clk tc_ck = {
        .name           = "tc_ck",
        .parent         = &ck_dpll1,
@@ -226,7 +261,7 @@ static struct clk tc_ck = {
 static struct clk arminth_ck1510 = {
        .name           = "arminth_ck",
        .parent         = &tc_ck,
-       .flags          = CLOCK_IN_OMAP1510,
+       .flags          = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
        .recalc         = &followparent_recalc,
        /* Note: On 1510 the frequency follows TC_CK
         *
@@ -237,7 +272,7 @@ static struct clk arminth_ck1510 = {
 static struct clk tipb_ck = {
        .name           = "tibp_ck",
        .parent         = &tc_ck,
-       .flags          = CLOCK_IN_OMAP1510,
+       .flags          = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
        .recalc         = &followparent_recalc,
 };
 
@@ -271,14 +306,15 @@ static struct clk tc2_ck = {
 static struct clk dma_ck = {
        .name           = "dma_ck",
        .parent         = &tc_ck,
-       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
+       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+                         ALWAYS_ENABLED,
        .recalc         = &followparent_recalc,
 };
 
 static struct clk dma_lcdfree_ck = {
        .name           = "dma_lcdfree_ck",
        .parent         = &tc_ck,
-       .flags          = CLOCK_IN_OMAP16XX,
+       .flags          = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
        .recalc         = &followparent_recalc,
 };
 
@@ -303,14 +339,14 @@ static struct clk lb_ck = {
 static struct clk rhea1_ck = {
        .name           = "rhea1_ck",
        .parent         = &tc_ck,
-       .flags          = CLOCK_IN_OMAP16XX,
+       .flags          = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
        .recalc         = &followparent_recalc,
 };
 
 static struct clk rhea2_ck = {
        .name           = "rhea2_ck",
        .parent         = &tc_ck,
-       .flags          = CLOCK_IN_OMAP16XX,
+       .flags          = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
        .recalc         = &followparent_recalc,
 };
 
@@ -325,43 +361,55 @@ static struct clk lcd_ck = {
        .recalc         = &ckctl_recalc,
 };
 
-static struct clk uart1_ck = {
+static struct clk uart1_1510 = {
+       .name           = "uart1_ck",
+       /* Direct from ULPD, no parent */
+       .rate           = 12000000,
+       .flags          = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
+       .enable_reg     = MOD_CONF_CTRL_0,
+       .enable_bit     = 29,   /* Chooses between 12MHz and 48MHz */
+       .set_rate       = &set_uart_rate,
+       .recalc         = &uart_recalc,
+};
+
+static struct clk uart1_16xx = {
        .name           = "uart1_ck",
        /* Direct from ULPD, no parent */
        .rate           = 48000000,
-       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-                         RATE_FIXED | ENABLE_REG_32BIT,
+       .flags          = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
        .enable_reg     = MOD_CONF_CTRL_0,
        .enable_bit     = 29,
-       /* (Only on 1510)
-        * The "enable bit" actually chooses between 48MHz and 12MHz.
-        */
 };
 
 static struct clk uart2_ck = {
        .name           = "uart2_ck",
        /* Direct from ULPD, no parent */
-       .rate           = 48000000,
-       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-                         RATE_FIXED | ENABLE_REG_32BIT,
+       .rate           = 12000000,
+       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT,
        .enable_reg     = MOD_CONF_CTRL_0,
-       .enable_bit     = 30,
-       /* (for both 1510 and 16xx)
-        * The "enable bit" actually chooses between 48MHz and 12MHz/32kHz.
-        */
+       .enable_bit     = 30,   /* Chooses between 12MHz and 48MHz */
+       .set_rate       = &set_uart_rate,
+       .recalc         = &uart_recalc,
 };
 
-static struct clk uart3_ck = {
+static struct clk uart3_1510 = {
+       .name           = "uart3_ck",
+       /* Direct from ULPD, no parent */
+       .rate           = 12000000,
+       .flags          = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
+       .enable_reg     = MOD_CONF_CTRL_0,
+       .enable_bit     = 31,   /* Chooses between 12MHz and 48MHz */
+       .set_rate       = &set_uart_rate,
+       .recalc         = &uart_recalc,
+};
+
+static struct clk uart3_16xx = {
        .name           = "uart3_ck",
        /* Direct from ULPD, no parent */
        .rate           = 48000000,
-       .flags          = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-                         RATE_FIXED | ENABLE_REG_32BIT,
+       .flags          = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
        .enable_reg     = MOD_CONF_CTRL_0,
        .enable_bit     = 31,
-       /* (Only on 1510)
-        * The "enable bit" actually chooses between 48MHz and 12MHz.
-        */
 };
 
 static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
@@ -480,6 +528,9 @@ static struct clk *  onchip_clks[] = {
        /* CK_GEN2 clocks */
        &dsp_ck,
        &dspmmu_ck,
+       &dspper_ck,
+       &dspxor_ck,
+       &dsptim_ck,
        /* CK_GEN3 clocks */
        &tc_ck,
        &tipb_ck,
@@ -494,9 +545,11 @@ static struct clk *  onchip_clks[] = {
        &rhea2_ck,
        &lcd_ck,
        /* ULPD clocks */
-       &uart1_ck,
+       &uart1_1510,
+       &uart1_16xx,
        &uart2_ck,
-       &uart3_ck,
+       &uart3_1510,
+       &uart3_16xx,
        &usb_clko,
        &usb_hhc_ck1510, &usb_hhc_ck16xx,
        &mclk_1510,  &mclk_16xx,
@@ -547,14 +600,34 @@ int __clk_enable(struct clk *clk)
                return 0;
        }
 
+       if (clk->flags & DSP_DOMAIN_CLOCK) {
+               __clk_use(&api_ck);
+       }
+
        if (clk->flags & ENABLE_REG_32BIT) {
-               regval32 = omap_readl(clk->enable_reg);
-               regval32 |= (1 << clk->enable_bit);
-               omap_writel(regval32, clk->enable_reg);
+               if (clk->flags & VIRTUAL_IO_ADDRESS) {
+                       regval32 = __raw_readl(clk->enable_reg);
+                       regval32 |= (1 << clk->enable_bit);
+                       __raw_writel(regval32, clk->enable_reg);
+               } else {
+                       regval32 = omap_readl(clk->enable_reg);
+                       regval32 |= (1 << clk->enable_bit);
+                       omap_writel(regval32, clk->enable_reg);
+               }
        } else {
-               regval16 = omap_readw(clk->enable_reg);
-               regval16 |= (1 << clk->enable_bit);
-               omap_writew(regval16, clk->enable_reg);
+               if (clk->flags & VIRTUAL_IO_ADDRESS) {
+                       regval16 = __raw_readw(clk->enable_reg);
+                       regval16 |= (1 << clk->enable_bit);
+                       __raw_writew(regval16, clk->enable_reg);
+               } else {
+                       regval16 = omap_readw(clk->enable_reg);
+                       regval16 |= (1 << clk->enable_bit);
+                       omap_writew(regval16, clk->enable_reg);
+               }
+       }
+
+       if (clk->flags & DSP_DOMAIN_CLOCK) {
+               __clk_unuse(&api_ck);
        }
 
        return 0;
@@ -569,14 +642,34 @@ void __clk_disable(struct clk *clk)
        if (clk->enable_reg == 0)
                return;
 
+       if (clk->flags & DSP_DOMAIN_CLOCK) {
+               __clk_use(&api_ck);
+       }
+
        if (clk->flags & ENABLE_REG_32BIT) {
-               regval32 = omap_readl(clk->enable_reg);
-               regval32 &= ~(1 << clk->enable_bit);
-               omap_writel(regval32, clk->enable_reg);
+               if (clk->flags & VIRTUAL_IO_ADDRESS) {
+                       regval32 = __raw_readl(clk->enable_reg);
+                       regval32 &= ~(1 << clk->enable_bit);
+                       __raw_writel(regval32, clk->enable_reg);
+               } else {
+                       regval32 = omap_readl(clk->enable_reg);
+                       regval32 &= ~(1 << clk->enable_bit);
+                       omap_writel(regval32, clk->enable_reg);
+               }
        } else {
-               regval16 = omap_readw(clk->enable_reg);
-               regval16 &= ~(1 << clk->enable_bit);
-               omap_writew(regval16, clk->enable_reg);
+               if (clk->flags & VIRTUAL_IO_ADDRESS) {
+                       regval16 = __raw_readw(clk->enable_reg);
+                       regval16 &= ~(1 << clk->enable_bit);
+                       __raw_writew(regval16, clk->enable_reg);
+               } else {
+                       regval16 = omap_readw(clk->enable_reg);
+                       regval16 &= ~(1 << clk->enable_bit);
+                       omap_writew(regval16, clk->enable_reg);
+               }
+       }
+
+       if (clk->flags & DSP_DOMAIN_CLOCK) {
+               __clk_unuse(&api_ck);
        }
 }
 
@@ -766,6 +859,33 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
        return dsor_exp;
 }
 
+
+static void ckctl_recalc(struct clk *  clk)
+{
+       int dsor;
+
+       /* Calculate divisor encoded as 2-bit exponent */
+       if (clk->flags & DSP_DOMAIN_CLOCK) {
+               /* The clock control bits are in DSP domain,
+                * so api_ck is needed for access.
+                * Note that DSP_CKCTL virt addr = phys addr, so
+                * we must use __raw_readw() instead of omap_readw().
+                */
+               __clk_use(&api_ck);
+               dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
+               __clk_unuse(&api_ck);
+       } else {
+               dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
+       }
+       if (unlikely(clk->rate == clk->parent->rate / dsor))
+               return; /* No change, quick exit */
+       clk->rate = clk->parent->rate / dsor;
+
+       if (unlikely(clk->flags & RATE_PROPAGATES))
+               propagate_rate(clk);
+}
+
+
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
        int dsor_exp;
@@ -826,6 +946,9 @@ static int select_table_rate(struct clk *  clk, unsigned long rate)
        if (!ptr->rate)
                return -EINVAL;
 
+       if (!ptr->rate)
+               return -EINVAL;
+
        if (unlikely(ck_dpll1.rate == 0)) {
                omap_writew(ptr->dpllctl_val, DPLL_CTL);
                ck_dpll1.rate = ptr->pll_rate;
@@ -921,6 +1044,23 @@ static unsigned calc_ext_dsor(unsigned long rate)
        return dsor;
 }
 
+/* Only needed on 1510 */
+static int set_uart_rate(struct clk * clk, unsigned long rate)
+{
+       unsigned int val;
+
+       val = omap_readl(clk->enable_reg);
+       if (rate == 12000000)
+               val &= ~(1 << clk->enable_bit);
+       else if (rate == 48000000)
+               val |= (1 << clk->enable_bit);
+       else
+               return -EINVAL;
+       omap_writel(val, clk->enable_reg);
+       clk->rate = rate;
+
+       return 0;
+}
 
 static int set_ext_clk_rate(struct clk *  clk, unsigned long rate)
 {
@@ -985,7 +1125,18 @@ void clk_unregister(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_unregister);
 
-
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+/*
+ * Resets some clocks that may be left on from bootloader,
+ * but leaves serial clocks on. See also omap_late_clk_reset().
+ */
+static inline void omap_early_clk_reset(void)
+{
+       //omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
+}
+#else
+#define omap_early_clk_reset() {}
+#endif
 
 int __init clk_init(void)
 {
@@ -993,6 +1144,8 @@ int __init clk_init(void)
        const struct omap_clock_config *info;
        int crystal_type = 0; /* Default 12 MHz */
 
+       omap_early_clk_reset();
+
        for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
                if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
                        clk_register(*clkp);
@@ -1023,9 +1176,42 @@ int __init clk_init(void)
                ck_ref.rate = 19200000;
 #endif
 
+       printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
+              omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
+              omap_readw(ARM_CKCTL));
+
        /* We want to be in syncronous scalable mode */
        omap_writew(0x1000, ARM_SYSST);
 
+#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
+       /* Use values set by bootloader. Determine PLL rate and recalculate
+        * dependent clocks as if kernel had changed PLL or divisors.
+        */
+       {
+               unsigned pll_ctl_val = omap_readw(DPLL_CTL);
+
+               ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
+               if (pll_ctl_val & 0x10) {
+                       /* PLL enabled, apply multiplier and divisor */
+                       if (pll_ctl_val & 0xf80)
+                               ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
+                       ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
+               } else {
+                       /* PLL disabled, apply bypass divisor */
+                       switch (pll_ctl_val & 0xc) {
+                       case 0:
+                               break;
+                       case 0x4:
+                               ck_dpll1.rate /= 2;
+                               break;
+                       default:
+                               ck_dpll1.rate /= 4;
+                               break;
+                       }
+               }
+       }
+       propagate_rate(&ck_dpll1);
+#else
        /* Find the highest supported frequency and enable it */
        if (select_table_rate(&virtual_ck_mpu, ~0)) {
                printk(KERN_ERR "System frequencies not set. Check your config.\n");
@@ -1034,12 +1220,13 @@ int __init clk_init(void)
                omap_writew(0x1005, ARM_CKCTL);
                ck_dpll1.rate = 60000000;
                propagate_rate(&ck_dpll1);
-               printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld/%ld/%ld\n",
-                      ck_ref.rate, ck_dpll1.rate, arm_ck.rate);
        }
-
+#endif
        /* Cache rates for clocks connected to ck_ref (not dpll1) */
        propagate_rate(&ck_ref);
+       printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld.%01ld/%ld/%ld MHz\n",
+              ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
+              ck_dpll1.rate, arm_ck.rate);
 
 #ifdef CONFIG_MACH_OMAP_PERSEUS2
        /* Select slicer output as OMAP input clock */
@@ -1074,3 +1261,63 @@ int __init clk_init(void)
 
        return 0;
 }
+
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+
+static int __init omap_late_clk_reset(void)
+{
+       /* Turn off all unused clocks */
+       struct clk *p;
+       __u32 regval32;
+
+       omap_writew(0, SOFT_REQ_REG);
+       omap_writew(0, SOFT_REQ_REG2);
+
+       list_for_each_entry(p, &clocks, node) {
+               if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
+                       p->enable_reg == 0)
+                       continue;
+
+               /* Assume no DSP clocks have been activated by bootloader */
+               if (p->flags & DSP_DOMAIN_CLOCK)
+                       continue;
+
+               /* Is the clock already disabled? */
+               if (p->flags & ENABLE_REG_32BIT) {
+                       if (p->flags & VIRTUAL_IO_ADDRESS)
+                               regval32 = __raw_readl(p->enable_reg);
+                       else
+                               regval32 = omap_readl(p->enable_reg);
+               } else {
+                       if (p->flags & VIRTUAL_IO_ADDRESS)
+                               regval32 = __raw_readw(p->enable_reg);
+                       else
+                               regval32 = omap_readw(p->enable_reg);
+               }
+
+               if ((regval32 & (1 << p->enable_bit)) == 0)
+                       continue;
+
+               /* FIXME: This clock seems to be necessary but no-one
+                * has asked for its activation. */
+               if (p == &tc2_ck         // FIX: pm.c (SRAM), CCP, Camera
+                   || p == &ck_dpll1out // FIX: SoSSI, SSR
+                   || p == &arm_gpio_ck // FIX: GPIO code for 1510
+                   ) {
+                       printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
+                              p->name);
+                       continue;
+               }
+
+               printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
+               __clk_disable(p);
+               printk(" done\n");
+       }
+
+       return 0;
+}
+
+late_initcall(omap_late_clk_reset);
+
+#endif
index 08b504d..a89e1e8 100644 (file)
@@ -52,6 +52,8 @@ struct mpu_rate {
 #define CLOCK_IN_OMAP16XX      64
 #define CLOCK_IN_OMAP1510      128
 #define CLOCK_IN_OMAP730       256
+#define DSP_DOMAIN_CLOCK       512
+#define VIRTUAL_IO_ADDRESS     1024
 
 /* ARM_CKCTL bit shifts */
 #define CKCTL_PERDIV_OFFSET    0
@@ -63,6 +65,8 @@ struct mpu_rate {
 /*#define ARM_TIMXO            12*/
 #define EN_DSPCK               13
 /*#define ARM_INTHCK_SEL       14*/ /* Divide-by-2 for mpu inth_ck */
+/* DSP_CKCTL bit shifts */
+#define CKCTL_DSPPERDIV_OFFSET 0
 
 /* ARM_IDLECT1 bit shifts */
 /*#define IDLWDT_ARM   0*/
@@ -96,6 +100,9 @@ struct mpu_rate {
 #define EN_TC1_CK      2
 #define EN_TC2_CK      4
 
+/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
+#define EN_DSPTIMCK    5
+
 /* Various register defines for clock controls scattered around OMAP chip */
 #define USB_MCLK_EN_BIT                4       /* In ULPD_CLKC_CTRL */
 #define USB_HOST_HHC_UHOST_EN  9       /* In MOD_CONF_CTRL_0 */
@@ -103,7 +110,8 @@ struct mpu_rate {
 #define COM_ULPD_PLL_CLK_REQ   1       /* In COM_CLK_DIV_CTRL_SEL */
 #define SWD_CLK_DIV_CTRL_SEL   0xfffe0874
 #define COM_CLK_DIV_CTRL_SEL   0xfffe0878
-
+#define SOFT_REQ_REG           0xfffe0834
+#define SOFT_REQ_REG2          0xfffe0880
 
 int clk_register(struct clk *clk);
 void clk_unregister(struct clk *clk);
index 015bd2c..c0a5c2f 100644 (file)
@@ -794,10 +794,6 @@ static void set_b1_regs(void)
        w = omap_readw(OMAP1610_DMA_LCD_CTRL);
        /* Always set the source port as SDRAM for now*/
        w &= ~(0x03 << 6);
-       if (lcd_dma.ext_ctrl)
-               w |= 1 << 8;
-       else
-               w &= ~(1 << 8);
        if (lcd_dma.callback != NULL)
                w |= 1 << 1;            /* Block interrupt enable */
        else
@@ -889,9 +885,15 @@ void omap_enable_lcd_dma(void)
         */
        if (enable_1510_mode || !lcd_dma.ext_ctrl)
                return;
+
+       w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+       w |= 1 << 8;
+       omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
        w = omap_readw(OMAP1610_DMA_LCD_CCR);
        w |= 1 << 7;
        omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
        lcd_dma.active = 1;
 }
 
@@ -922,10 +924,19 @@ void omap_setup_lcd_dma(void)
 
 void omap_stop_lcd_dma(void)
 {
+       u16 w;
+
        lcd_dma.active = 0;
-       if (!enable_1510_mode && lcd_dma.ext_ctrl)
-               omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~(1 << 7),
-                           OMAP1610_DMA_LCD_CCR);
+       if (enable_1510_mode || !lcd_dma.ext_ctrl)
+               return;
+
+       w = omap_readw(OMAP1610_DMA_LCD_CCR);
+       w &= ~(1 << 7);
+       omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+       w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+       w &= ~(1 << 8);
+       omap_writew(w, OMAP1610_DMA_LCD_CTRL);
 }
 
 /*
@@ -972,6 +983,25 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
                             (OMAP_DMA_CDSA_U(lch) << 16));
 }
 
+int omap_dma_running(void)
+{
+       int lch;
+
+       /* Check if LCD DMA is running */
+       if (cpu_is_omap16xx())
+               if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
+                       return 1;
+
+       for (lch = 0; lch < dma_chan_count; lch++) {
+               u16 w;
+
+               w = omap_readw(OMAP_DMA_CCR(lch));
+               if (w & OMAP_DMA_CCR_EN)
+                       return 1;
+       }
+       return 0;
+}
+
 static int __init omap_init_dma(void)
 {
        int ch, r;
index 10c3f22..43567d5 100644 (file)
@@ -66,6 +66,7 @@ struct omap_mcbsp {
 static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
 static struct clk *mcbsp_dsp_ck = 0;
 static struct clk *mcbsp_api_ck = 0;
+static struct clk *mcbsp_dspxor_ck = 0;
 
 
 static void omap_mcbsp_dump_reg(u8 id)
@@ -175,7 +176,7 @@ static int omap_mcbsp_check(unsigned int id)
                return 0;
        }
 
-       if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
+       if (cpu_is_omap1510() || cpu_is_omap16xx()) {
                if (id > OMAP_MAX_MCBSP_COUNT) {
                        printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
                        return -1;
@@ -191,15 +192,12 @@ static int omap_mcbsp_check(unsigned int id)
 
 static void omap_mcbsp_dsp_request(void)
 {
-       if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
-               omap_writew((omap_readw(ARM_RSTCT1) | (1 << 1) | (1 << 2)),
-                           ARM_RSTCT1);
-               clk_enable(mcbsp_dsp_ck);
-               clk_enable(mcbsp_api_ck);
+       if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+               clk_use(mcbsp_dsp_ck);
+               clk_use(mcbsp_api_ck);
 
                /* enable 12MHz clock to mcbsp 1 & 3 */
-               __raw_writew(__raw_readw(DSP_IDLECT2) | (1 << EN_XORPCK),
-                            DSP_IDLECT2);
+               clk_use(mcbsp_dspxor_ck);
                __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
                             DSP_RSTCT2);
        }
@@ -207,10 +205,13 @@ static void omap_mcbsp_dsp_request(void)
 
 static void omap_mcbsp_dsp_free(void)
 {
-       /* Useless for now */
+       if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+               clk_unuse(mcbsp_dspxor_ck);
+               clk_unuse(mcbsp_dsp_ck);
+               clk_unuse(mcbsp_api_ck);
+       }
 }
 
-
 int omap_mcbsp_request(unsigned int id)
 {
        int err;
@@ -350,6 +351,73 @@ void omap_mcbsp_stop(unsigned int id)
 }
 
 
+/* polled mcbsp i/o operations */
+int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
+{
+       u32 base = mcbsp[id].io_base;
+       writew(buf, base + OMAP_MCBSP_REG_DXR1);
+       /* if frame sync error - clear the error */
+       if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
+               /* clear error */
+               writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
+                      base + OMAP_MCBSP_REG_SPCR2);
+               /* resend */
+               return -1;
+       } else {
+               /* wait for transmit confirmation */
+               int attemps = 0;
+               while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
+                       if (attemps++ > 1000) {
+                               writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
+                                      (~XRST),
+                                      base + OMAP_MCBSP_REG_SPCR2);
+                               udelay(10);
+                               writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
+                                      (XRST),
+                                      base + OMAP_MCBSP_REG_SPCR2);
+                               udelay(10);
+                               printk(KERN_ERR
+                                      " Could not write to McBSP Register\n");
+                               return -2;
+                       }
+               }
+       }
+       return 0;
+}
+
+int omap_mcbsp_pollread(unsigned int id, u16 * buf)
+{
+       u32 base = mcbsp[id].io_base;
+       /* if frame sync error - clear the error */
+       if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
+               /* clear error */
+               writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
+                      base + OMAP_MCBSP_REG_SPCR1);
+               /* resend */
+               return -1;
+       } else {
+               /* wait for recieve confirmation */
+               int attemps = 0;
+               while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
+                       if (attemps++ > 1000) {
+                               writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
+                                      (~RRST),
+                                      base + OMAP_MCBSP_REG_SPCR1);
+                               udelay(10);
+                               writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
+                                      (RRST),
+                                      base + OMAP_MCBSP_REG_SPCR1);
+                               udelay(10);
+                               printk(KERN_ERR
+                                      " Could not read from McBSP Register\n");
+                               return -2;
+                       }
+               }
+       }
+       *buf = readw(base + OMAP_MCBSP_REG_DRR1);
+       return 0;
+}
+
 /*
  * IRQ based word transmission.
  */
@@ -625,10 +693,15 @@ static int __init omap_mcbsp_init(void)
                return PTR_ERR(mcbsp_dsp_ck);
        }
        mcbsp_api_ck = clk_get(0, "api_ck");
-       if (IS_ERR(mcbsp_dsp_ck)) {
+       if (IS_ERR(mcbsp_api_ck)) {
                printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
                return PTR_ERR(mcbsp_api_ck);
        }
+       mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
+       if (IS_ERR(mcbsp_dspxor_ck)) {
+               printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
+               return PTR_ERR(mcbsp_dspxor_ck);
+       }
 
 #ifdef CONFIG_ARCH_OMAP730
        if (cpu_is_omap730()) {
@@ -643,7 +716,7 @@ static int __init omap_mcbsp_init(void)
        }
 #endif
 #if defined(CONFIG_ARCH_OMAP16XX)
-       if (cpu_is_omap1610() || cpu_is_omap1710()) {
+       if (cpu_is_omap16xx()) {
                mcbsp_info = mcbsp_1610;
                mcbsp_count = ARRAY_SIZE(mcbsp_1610);
        }
index cbecd10..ea7b955 100644 (file)
@@ -53,19 +53,13 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
                return -EINVAL;
        }
 
-       cfg = &reg_cfg_table[reg_cfg];
-
-       /*
-        * We do a pretty long section here with lock on, but pin muxing
-        * should only happen on driver init for each driver, so it's not time
-        * critical.
-        */
-       spin_lock_irqsave(&mux_spin_lock, flags);
+       cfg = (reg_cfg_set *)&reg_cfg_table[reg_cfg];
 
        /* Check the mux register in question */
        if (cfg->mux_reg) {
                unsigned        tmp1, tmp2;
 
+               spin_lock_irqsave(&mux_spin_lock, flags);
                reg_orig = omap_readl(cfg->mux_reg);
 
                /* The mux registers always seem to be 3 bits long */
@@ -80,11 +74,13 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
                        warn = 1;
 
                omap_writel(reg, cfg->mux_reg);
+               spin_unlock_irqrestore(&mux_spin_lock, flags);
        }
 
        /* Check for pull up or pull down selection on 1610 */
        if (!cpu_is_omap1510()) {
                if (cfg->pu_pd_reg && cfg->pull_val) {
+                       spin_lock_irqsave(&mux_spin_lock, flags);
                        pu_pd_orig = omap_readl(cfg->pu_pd_reg);
                        mask = 1 << cfg->pull_bit;
 
@@ -100,11 +96,13 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
                                pu_pd = pu_pd_orig & ~mask;
                        }
                        omap_writel(pu_pd, cfg->pu_pd_reg);
+                       spin_unlock_irqrestore(&mux_spin_lock, flags);
                }
        }
 
        /* Check for an associated pull down register */
        if (cfg->pull_reg) {
+               spin_lock_irqsave(&mux_spin_lock, flags);
                pull_orig = omap_readl(cfg->pull_reg);
                mask = 1 << cfg->pull_bit;
 
@@ -121,6 +119,7 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
                }
 
                omap_writel(pull, cfg->pull_reg);
+               spin_unlock_irqrestore(&mux_spin_lock, flags);
        }
 
        if (warn) {
@@ -149,8 +148,6 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
        }
 #endif
 
-       spin_unlock_irqrestore(&mux_spin_lock, flags);
-
 #ifdef CONFIG_OMAP_MUX_ERRORS
        return warn ? -ETXTBSY : 0;
 #else
index ab38e4e..25bc4a8 100644 (file)
@@ -326,7 +326,7 @@ static u64 ohci_dmamask = ~(u32)0;
 static struct resource ohci_resources[] = {
        {
                .start  = OMAP_OHCI_BASE,
-               .end    = OMAP_OHCI_BASE + 4096,
+               .end    = OMAP_OHCI_BASE + 4096 - 1,
                .flags  = IORESOURCE_MEM,
        },
        {
index d785248..ce114ce 100644 (file)
@@ -241,6 +241,7 @@ extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
 extern dma_addr_t omap_get_dma_src_pos(int lch);
 extern dma_addr_t omap_get_dma_dst_pos(int lch);
 extern void omap_clear_dma(int lch);
+extern int omap_dma_running(void);
 
 /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
 extern int omap_dma_in_1510_mode(void);
index 39f99de..5bd3f00 100644 (file)
@@ -231,7 +231,7 @@ typedef enum {
        J19_1610_ETM_D6,
        J18_1610_ETM_D7,
 
-       /* OMAP-1610 GPIO */
+       /* OMAP16XX GPIO */
        P20_1610_GPIO4,
        V9_1610_GPIO7,
        W8_1610_GPIO9,
@@ -241,6 +241,9 @@ typedef enum {
        AA20_1610_GPIO_41,
        W19_1610_GPIO48,
        M7_1610_GPIO62,
+       V14_16XX_GPIO37,
+       R9_16XX_GPIO18,
+       L14_16XX_GPIO49,
 
        /* OMAP-1610 uWire */
        V19_1610_UWIRE_SCLK,
@@ -285,12 +288,13 @@ typedef enum {
        V6_USB2_TXD,
        W5_USB2_SE0,
 
-       /* UART1 1610 */
-
+       /* 16XX UART */
        R13_1610_UART1_TX,
-       V14_1610_UART1_RX,
+       V14_16XX_UART1_RX,
        R14_1610_UART1_CTS,
        AA15_1610_UART1_RTS,
+       R9_16XX_UART2_RX,
+       L14_16XX_UART3_RX,
 
        /* I2C OMAP-1610 */
        I2C_SCL,
@@ -332,7 +336,7 @@ typedef enum {
  * Table of various FUNC_MUX and PULL_DWN combinations for each device.
  * See also reg_cfg_t above for the lookup table.
  */
-static reg_cfg_set __initdata_or_module
+static const reg_cfg_set __initdata_or_module
 reg_cfg_table[] = {
 /*
  *      description            mux  mode   mux  pull pull  pull  pu_pd  pu  dbg
@@ -455,7 +459,7 @@ MUX_CFG("L19_1610_ETM_D0",   5,   18,    1,   0,  26,   0,    0,     0,  1)
 MUX_CFG("J19_1610_ETM_D6",      5,    0,    1,   0,  20,   0,    0,     0,  1)
 MUX_CFG("J18_1610_ETM_D7",      5,   27,    1,   0,  19,   0,    0,     0,  1)
 
-/* OMAP-1610 GPIO */
+/* OMAP16XX GPIO */
 MUX_CFG("P20_1610_GPIO4",       6,   27,    0,   1,   7,   0,    1,     1,  1)
 MUX_CFG("V9_1610_GPIO7",        B,   12,    1,   2,  20,   0,    2,     1,  1)
 MUX_CFG("W8_1610_GPIO9",        B,   21,    0,   2,  23,   0,    2,     1,  1)
@@ -465,6 +469,9 @@ MUX_CFG("V5_1610_GPIO24",    B,   15,    7,   2,  21,   0,    2,     1,  1)
 MUX_CFG("AA20_1610_GPIO_41",    9,    9,    7,   1,  31,   0,    1,     1,  1)
 MUX_CFG("W19_1610_GPIO48",      8,   15,    7,   1,  23,   1,    1,     0,  1)
 MUX_CFG("M7_1610_GPIO62",      10,    0,    0,   4,  24,   0,    4,     0,  1)
+MUX_CFG("V14_16XX_GPIO37",      9,   18,    7,   2,   2,   0,    2,     2,  0)
+MUX_CFG("R9_16XX_GPIO18",       C,   18,    7,   3,   0,   0,    3,     0,  0)
+MUX_CFG("L14_16XX_GPIO49",      6,    3,    7,   0,  31,   0,    0,    31,  0)
 
 /* OMAP-1610 uWire */
 MUX_CFG("V19_1610_UWIRE_SCLK",  8,    6,    0,   1,  20,   0,    1,     1,  1)
@@ -503,16 +510,17 @@ MUX_CFG("Y10_USB0_SUSP",   B,   3,     5,   2,  17,   0,    2,     0,  1)
 MUX_CFG("W9_USB2_TXEN",                 B,   9,     1,  NA,   0,   0,   NA,     0,  1)
 MUX_CFG("AA9_USB2_VP",          B,   6,     1,  NA,   0,   0,   NA,     0,  1)
 MUX_CFG("Y5_USB2_RCV",          C,  21,     1,  NA,   0,   0,   NA,     0,  1)
-MUX_CFG("R8_USB2_VM",           C,  18,     1,  NA,   0,   0,   NA,     0,  1)
+MUX_CFG("R9_USB2_VM",           C,  18,     1,  NA,   0,   0,   NA,     0,  1)
 MUX_CFG("V6_USB2_TXD",          C,  27,     2,  NA,   0,   0,   NA,     0,  1)
 MUX_CFG("W5_USB2_SE0",          C,  24,     2,  NA,   0,   0,   NA,     0,  1)
 
-
-/* UART1 */
+/* 16XX UART */
 MUX_CFG("R13_1610_UART1_TX",    A,  12,     6,   2,  10,   0,    2,    10,  1)
-MUX_CFG("V14_1610_UART1_RX",    9,  18,     0,   2,   2,   0,    2,     2,  1)
+MUX_CFG("V14_16XX_UART1_RX",    9,  18,     0,   2,   2,   0,    2,     2,  1)
 MUX_CFG("R14_1610_UART1_CTS",   9,  15,     0,   2,   1,   0,    2,     1,  1)
 MUX_CFG("AA15_1610_UART1_RTS",  9,  12,     1,   2,   0,   0,    2,     0,  1)
+MUX_CFG("R9_16XX_UART2_RX",     C,  18,     0,   3,   0,   0,    3,     0,  1)
+MUX_CFG("L14_16XX_UART3_RX",    6,   3,     0,   0,  31,   0,    0,    31,  1)
 
 /* I2C interface */
 MUX_CFG("I2C_SCL",              7,  24,     0,  NA,   0,   0,   NA,     0,  0)