[ARM] 4432/5: davinci: pin mux support
Vladimir Barinov [Tue, 10 Jul 2007 12:10:04 +0000 (13:10 +0100)]
Support pin multiplexing configurations driver for TI DaVinci SoC

Signed-off-by: Vladimir Barinov <vbarinov@ru.mvista.com>
Acked-by: Kevin Hilman <khilman@mvista.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/mux.c [new file with mode: 0644]
arch/arm/mach-davinci/psc.c
include/asm-arm/arch-davinci/mux.h [new file with mode: 0644]

index 731c0a6..99ac2e5 100644 (file)
@@ -5,7 +5,7 @@
 
 # Common objects
 obj-y                  := time.o irq.o clock.o serial.o io.o id.o psc.o \
-                          gpio.o
+                          gpio.o mux.o
 
 # Board specific
 obj-$(CONFIG_MACH_DAVINCI_EVM)  += board-evm.o
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
new file mode 100644 (file)
index 0000000..92d26bd
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * DaVinci pin multiplexing configurations
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+
+#include <asm/arch/mux.h>
+
+/* System control register offsets */
+#define PINMUX0         0x00
+#define PINMUX1         0x04
+
+static DEFINE_SPINLOCK(mux_lock);
+
+void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
+{
+       u32 pinmux, muxreg = PINMUX0;
+
+       if (mux >= DAVINCI_MUX_LEVEL2) {
+               muxreg = PINMUX1;
+               mux -= DAVINCI_MUX_LEVEL2;
+       }
+
+       spin_lock(&mux_lock);
+       pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg);
+       if (enable)
+               pinmux |= (1 << mux);
+       else
+               pinmux &= ~(1 << mux);
+       davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg);
+       spin_unlock(&mux_lock);
+}
index e1b0050..1334416 100644 (file)
 #include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/arch/psc.h>
+#include <asm/arch/mux.h>
 
-#define PTCMD       __REG(0x01C41120)
-#define PDSTAT      __REG(0x01C41200)
-#define PDCTL1      __REG(0x01C41304)
-#define EPCPR       __REG(0x01C41070)
-#define PTSTAT      __REG(0x01C41128)
+/* PSC register offsets */
+#define EPCPR          0x070
+#define PTCMD          0x120
+#define PTSTAT         0x128
+#define PDSTAT         0x200
+#define PDCTL1         0x304
+#define MDSTAT         0x800
+#define MDCTL          0xA00
 
-#define MDSTAT      IO_ADDRESS(0x01C41800)
-#define MDCTL       IO_ADDRESS(0x01C41A00)
-
-#define PINMUX0             __REG(0x01c40000)
-#define PINMUX1             __REG(0x01c40004)
-#define VDD3P3V_PWDN __REG(0x01C40048)
+/* System control register offsets */
+#define VDD3P3V_PWDN   0x48
 
 static void davinci_psc_mux(unsigned int id)
 {
        switch (id) {
        case DAVINCI_LPSC_ATA:
-               PINMUX0 |= (1 << 17) | (1 << 16);
+               davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1);
+               davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1);
                break;
        case DAVINCI_LPSC_MMC_SD:
                /* VDD power manupulations are done in U-Boot for CPMAC
                 * so applies to MMC as well
                 */
                /*Set up the pull regiter for MMC */
-               VDD3P3V_PWDN = 0x0;
-               PINMUX1 &= (~(1 << 9));
+               davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN);
+               davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0);
                break;
        case DAVINCI_LPSC_I2C:
-               PINMUX1 |= (1 << 7);
+               davinci_mux_peripheral(DAVINCI_MUX_I2C, 1);
                break;
        case DAVINCI_LPSC_McBSP:
-               PINMUX1 |= (1 << 10);
+               davinci_mux_peripheral(DAVINCI_MUX_ASP, 1);
                break;
        default:
                break;
@@ -67,33 +68,59 @@ static void davinci_psc_mux(unsigned int id)
 /* Enable or disable a PSC domain */
 void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
 {
-       volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id);
-       volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id);
+       u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
 
        if (id < 0)
                return;
 
+       mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
        if (enable)
-               *mdctl |= 0x00000003;   /* Enable Module */
+               mdctl |= 0x00000003;    /* Enable Module */
        else
-               *mdctl &= 0xFFFFFFF2;   /* Disable Module */
+               mdctl &= 0xFFFFFFF2;    /* Disable Module */
+       davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
+
+       pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT);
+       if ((pdstat & 0x00000001) == 0) {
+               pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+               pdctl1 |= 0x1;
+               davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+
+               ptcmd = 1 << domain;
+               davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
 
-       if ((PDSTAT & 0x00000001) == 0) {
-               PDCTL1 |= 0x1;
-               PTCMD = (1 << domain);
-               while ((((EPCPR >> domain) & 1) == 0));
+               do {
+                       epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+                                             EPCPR);
+               } while ((((epcpr >> domain) & 1) == 0));
 
-               PDCTL1 |= 0x100;
-               while (!(((PTSTAT >> domain) & 1) == 0));
+               pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+               pdctl1 |= 0x100;
+               davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
+
+               do {
+                       ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+                                              PTSTAT);
+               } while (!(((ptstat >> domain) & 1) == 0));
        } else {
-               PTCMD = (1 << domain);
-               while (!(((PTSTAT >> domain) & 1) == 0));
+               ptcmd = 1 << domain;
+               davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
+
+               do {
+                       ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+                                              PTSTAT);
+               } while (!(((ptstat >> domain) & 1) == 0));
        }
 
        if (enable)
-               while (!((*mdstat & 0x0000001F) == 0x3));
+               mdstat_mask = 0x3;
        else
-               while (!((*mdstat & 0x0000001F) == 0x2));
+               mdstat_mask = 0x2;
+
+       do {
+               mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
+                                      MDSTAT + 4 * id);
+       } while (!((mdstat & 0x0000001F) == mdstat_mask));
 
        if (enable)
                davinci_psc_mux(id);
diff --git a/include/asm-arm/arch-davinci/mux.h b/include/asm-arm/arch-davinci/mux.h
new file mode 100644 (file)
index 0000000..c24b678
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * DaVinci pin multiplexing defines
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_MUX_H
+#define __ASM_ARCH_MUX_H
+
+#define DAVINCI_MUX_AEAW0      0
+#define DAVINCI_MUX_AEAW1      1
+#define DAVINCI_MUX_AEAW2      2
+#define DAVINCI_MUX_AEAW3      3
+#define DAVINCI_MUX_AEAW4      4
+#define DAVINCI_MUX_AECS4      10
+#define DAVINCI_MUX_AECS5      11
+#define DAVINCI_MUX_VLYNQWD0   12
+#define DAVINCI_MUX_VLYNQWD1   13
+#define DAVINCI_MUX_VLSCREN    14
+#define DAVINCI_MUX_VLYNQEN    15
+#define DAVINCI_MUX_HDIREN     16
+#define DAVINCI_MUX_ATAEN      17
+#define DAVINCI_MUX_RGB666     22
+#define DAVINCI_MUX_RGB888     23
+#define DAVINCI_MUX_LOEEN      24
+#define DAVINCI_MUX_LFLDEN     25
+#define DAVINCI_MUX_CWEN       26
+#define DAVINCI_MUX_CFLDEN     27
+#define DAVINCI_MUX_HPIEN      29
+#define DAVINCI_MUX_1394EN     30
+#define DAVINCI_MUX_EMACEN     31
+
+#define DAVINCI_MUX_LEVEL2     32
+#define DAVINCI_MUX_UART0      (DAVINCI_MUX_LEVEL2 + 0)
+#define DAVINCI_MUX_UART1      (DAVINCI_MUX_LEVEL2 + 1)
+#define DAVINCI_MUX_UART2      (DAVINCI_MUX_LEVEL2 + 2)
+#define DAVINCI_MUX_U2FLO      (DAVINCI_MUX_LEVEL2 + 3)
+#define DAVINCI_MUX_PWM0       (DAVINCI_MUX_LEVEL2 + 4)
+#define DAVINCI_MUX_PWM1       (DAVINCI_MUX_LEVEL2 + 5)
+#define DAVINCI_MUX_PWM2       (DAVINCI_MUX_LEVEL2 + 6)
+#define DAVINCI_MUX_I2C                (DAVINCI_MUX_LEVEL2 + 7)
+#define DAVINCI_MUX_SPI                (DAVINCI_MUX_LEVEL2 + 8)
+#define DAVINCI_MUX_MSTK       (DAVINCI_MUX_LEVEL2 + 9)
+#define DAVINCI_MUX_ASP                (DAVINCI_MUX_LEVEL2 + 10)
+#define DAVINCI_MUX_CLK0       (DAVINCI_MUX_LEVEL2 + 16)
+#define DAVINCI_MUX_CLK1       (DAVINCI_MUX_LEVEL2 + 17)
+#define DAVINCI_MUX_TIMIN      (DAVINCI_MUX_LEVEL2 + 18)
+
+extern void davinci_mux_peripheral(unsigned int mux, unsigned int enable);
+
+#endif /* __ASM_ARCH_MUX_H */