prepare for SPI controller driver
authorFlorian Fainelli <florian@openwrt.org>
Fri, 6 Mar 2009 01:15:00 +0000 (01:15 +0000)
committerFlorian Fainelli <florian@openwrt.org>
Fri, 6 Mar 2009 01:15:00 +0000 (01:15 +0000)
SVN-Revision: 14755

target/linux/brcm63xx/files/arch/mips/bcm63xx/cpu.c
target/linux/brcm63xx/files/arch/mips/bcm63xx/dev-spi.c [new file with mode: 0644]
target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_cpu.h
target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_dev_spi.h [new file with mode: 0644]
target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_io.h

index c147e2831a5bbe28258ad440959a786872813c50..b69821cc61f3043c5deb9f752f13ee76e436ea9c 100644 (file)
@@ -4,6 +4,7 @@
  * for more details.
  *
  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *              2009 Florian Fainelli <florian@openwrt.org>
  */
 
 #include <linux/kernel.h>
@@ -20,6 +21,9 @@ EXPORT_SYMBOL(bcm63xx_regs_base);
 const int *bcm63xx_irqs;
 EXPORT_SYMBOL(bcm63xx_irqs);
 
+const unsigned long *bcm63xx_regs_spi;
+EXPORT_SYMBOL(bcm63xx_regs_spi);
+
 static u16 bcm63xx_cpu_id;
 static u16 bcm63xx_cpu_rev;
 static unsigned int bcm63xx_cpu_freq;
@@ -49,6 +53,21 @@ static const int bcm96338_irqs[] = {
        [IRQ_ENET0_TXDMA]       = BCM_6338_ENET0_TXDMA_IRQ,
 };
 
+static const unsigned long bcm96338_regs_spi[] = {
+       [SPI_CMD]               = SPI_BCM_6338_SPI_CMD,
+       [SPI_INT_STATUS]        = SPI_BCM_6338_SPI_INT_STATUS,
+       [SPI_INT_MASK_ST]       = SPI_BCM_6338_SPI_MASK_INT_ST,
+       [SPI_INT_MASK]          = SPI_BCM_6338_SPI_INT_MASK,
+       [SPI_ST]                = SPI_BCM_6338_SPI_ST,
+       [SPI_CLK_CFG]           = SPI_BCM_6338_SPI_CLK_CFG,
+       [SPI_FILL_BYTE]         = SPI_BCM_6338_SPI_FILL_BYTE,
+       [SPI_MSG_TAIL]          = SPI_BCM_6338_SPI_MSG_TAIL,
+       [SPI_RX_TAIL]           = SPI_BCM_6338_SPI_RX_TAIL,
+       [SPI_MSG_CTL]           = SPI_BCM_6338_SPI_MSG_CTL,
+       [SPI_MSG_DATA]          = SPI_BCM_6338_SPI_MSG_DATA,
+       [SPI_RX_DATA]           = SPI_BCM_6338_SPI_RX_DATA,
+};
+
 /*
  * 6348 register sets and irqs
  */
@@ -90,6 +109,21 @@ static const int bcm96348_irqs[] = {
        [IRQ_PCI]               = BCM_6348_PCI_IRQ,
 };
 
+static const unsigned long bcm96348_regs_spi[] = {
+       [SPI_CMD]               = SPI_BCM_6348_SPI_CMD,
+       [SPI_INT_STATUS]        = SPI_BCM_6348_SPI_INT_STATUS,
+       [SPI_INT_MASK_ST]       = SPI_BCM_6348_SPI_MASK_INT_ST,
+       [SPI_INT_MASK]          = SPI_BCM_6348_SPI_INT_MASK,
+       [SPI_ST]                = SPI_BCM_6348_SPI_ST,
+       [SPI_CLK_CFG]           = SPI_BCM_6348_SPI_CLK_CFG,
+       [SPI_FILL_BYTE]         = SPI_BCM_6348_SPI_FILL_BYTE,
+       [SPI_MSG_TAIL]          = SPI_BCM_6348_SPI_MSG_TAIL,
+       [SPI_RX_TAIL]           = SPI_BCM_6348_SPI_RX_TAIL,
+       [SPI_MSG_CTL]           = SPI_BCM_6348_SPI_MSG_CTL,
+       [SPI_MSG_DATA]          = SPI_BCM_6348_SPI_MSG_DATA,
+       [SPI_RX_DATA]           = SPI_BCM_6348_SPI_RX_DATA,
+};
+
 /*
  * 6358 register sets and irqs
  */
@@ -133,6 +167,21 @@ static const int bcm96358_irqs[] = {
        [IRQ_PCI]               = BCM_6358_PCI_IRQ,
 };
 
+static const unsigned long bcm96358_regs_spi[] = {
+       [SPI_CMD]               = SPI_BCM_6358_SPI_CMD,
+       [SPI_INT_STATUS]        = SPI_BCM_6358_SPI_INT_STATUS,
+       [SPI_INT_MASK_ST]       = SPI_BCM_6358_SPI_MASK_INT_ST,
+       [SPI_INT_MASK]          = SPI_BCM_6358_SPI_INT_MASK,
+       [SPI_ST]                = SPI_BCM_6358_SPI_STATUS,
+       [SPI_CLK_CFG]           = SPI_BCM_6358_SPI_CLK_CFG,
+       [SPI_FILL_BYTE]         = SPI_BCM_6358_SPI_FILL_BYTE,
+       [SPI_MSG_TAIL]          = SPI_BCM_6358_SPI_MSG_TAIL,
+       [SPI_RX_TAIL]           = SPI_BCM_6358_SPI_RX_TAIL,
+       [SPI_MSG_CTL]           = SPI_BCM_6358_MSG_CTL,
+       [SPI_MSG_DATA]          = SPI_BCM_6358_SPI_MSG_DATA,
+       [SPI_RX_DATA]           = SPI_BCM_6358_SPI_RX_FIFO,
+};
+
 u16 __bcm63xx_get_cpu_id(void)
 {
        return bcm63xx_cpu_id;
@@ -236,16 +285,19 @@ void __init bcm63xx_cpu_init(void)
                expected_cpu_id = BCM6338_CPU_ID;
                bcm63xx_regs_base = bcm96338_regs_base;
                bcm63xx_irqs = bcm96338_irqs;
+               bcm63xx_regs_spi = bcm96338_regs_spi;
                break;
        case CPU_BCM6348:
                expected_cpu_id = BCM6348_CPU_ID;
                bcm63xx_regs_base = bcm96348_regs_base;
                bcm63xx_irqs = bcm96348_irqs;
+               bcm63xx_regs_spi = bcm96348_regs_spi;
                break;
        case CPU_BCM6358:
                expected_cpu_id = BCM6358_CPU_ID;
                bcm63xx_regs_base = bcm96358_regs_base;
                bcm63xx_irqs = bcm96358_irqs;
+               bcm63xx_regs_spi = bcm96358_regs_spi;
                break;
        }
 
diff --git a/target/linux/brcm63xx/files/arch/mips/bcm63xx/dev-spi.c b/target/linux/brcm63xx/files/arch/mips/bcm63xx/dev-spi.c
new file mode 100644 (file)
index 0000000..4aea088
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org> 
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_spi.h>
+
+static struct resource spi_resources[] = {
+       {
+               .start          = -1, /* filled at runtime */
+               .end            = -1, /* filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = -1, /* filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct bcm63xx_spi_pdata spi_pdata = {
+       .bus_num                = 0,
+       .num_chipselect         = 4,
+       .speed_hz               = 50000000,     /* Fclk */
+};
+
+static struct platform_device bcm63xx_spi_device = {
+       .name           = "bcm63xx_spi",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(spi_resources),
+       .resource       = spi_resources,
+       .dev.pdata      = &spi_pdata;
+};
+
+int __init bcm63xx_spi_register(void)
+{
+       spi_resources[0].start = bcm63xx_regset_address(RSET_SPI);
+       spi_resources[0].end = spi_resources[0].start;
+       spi_resources[0].end += RSET_SPI_SIZE - 1;
+       spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI);
+
+       /* Fill in platform data */
+       if (CPU_IS_BCM6338() || CPU_IS_BCM6348()) {
+               spi_pdata.msg_fifo_size = SPI_BCM_6338_SPI_MSG_DATA_SIZE;
+               spi_pdata.rx_fifo_size = SPI_BCM_6338_SPI_RX_DATA_SIZE;
+       }
+
+       if (CPU_IS_BCM6358()) {
+               spi_pdata.msg_fifo_size = SPI_BCM_6358_SPI_MSG_DATA_SIZE;
+               spi_pdata.rx_fifo_size =  SPI_BCM_6358_SPI_RX_DATA_SIZE;
+       }
+       
+       return platform_device_register(&bcm63xx_spi_device);
+}
index 6fa8825b49853894d59fb8a831d412cf876ef2a3..be9da2eee72bcde6016d23b839c679e2e1eda40a 100644 (file)
@@ -289,6 +289,120 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
        return 0;
 }
 
+/*
+ * SPI register layout is not compatible
+ * accross CPU versions but it is software
+ * compatible
+ */
+
+enum bcm63xx_regs_spi {
+       SPI_CMD,
+       SPI_INT_STATUS,
+       SPI_INT_MASK_ST,
+       SPI_INT_MASK,
+       SPI_ST,
+       SPI_CLK_CFG,
+       SPI_FILL_BYTE,
+       SPI_MSG_TAIL,
+       SPI_RX_TAIL,
+       SPI_MSG_CTL,
+       SPI_MSG_DATA,
+       SPI_RX_DATA,
+};
+
+extern const unsigned long *bcm63xx_regs_spi;
+
+static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg)
+{
+#ifdef BCMCPU_RUNTIME_DETECT
+        return bcm63xx_regs_spi[reg];
+#else
+#ifdef CONFIG_BCM63XX_CPU_6338
+switch (reg) {
+       case SPI_CMD:
+               return SPI_BCM_6338_SPI_CMD;
+       case SPI_INT_STATUS:
+               return SPI_BCM_6338_SPI_INT_STATUS;
+       case SPI_INT_MASK_ST:
+               return SPI_BCM_6338_SPI_MASK_INT_ST;
+       case SPI_INT_MASK:
+               return SPI_BCM_6338_SPI_INT_MASK;
+       case SPI_ST:
+               return SPI_BCM_6338_SPI_ST;
+       case SPI_CLK_CFG:
+               return SPI_BCM_6338_SPI_CLK_CFG;
+       case SPI_FILL_BYTE:
+               return SPI_BCM_6338_SPI_FILL_BYTE;
+       case SPI_MSG_TAIL:
+               return SPI_BCM_6338_SPI_MSG_TAIL;
+       case SPI_RX_TAIL:
+               return SPI_BCM_6338_SPI_RX_TAIL;
+       case SPI_MSG_CTL:
+               return SPI_BCM_6338_SPI_MSG_CTL;
+       case SPI_MSG_DATA:
+               return SPI_BCM_6338_SPI_MSG_DATA;
+       case SPI_RX_DATA:
+               return SPI_BCM_6338_SPI_RX_DATA;
+}
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+switch (reg) {
+       case SPI_CMD:
+               return SPI_BCM_6348_SPI_CMD;
+       case SPI_INT_MASK_ST:
+               return SPI_BCM_6348_SPI_MASK_INT_ST;
+       case SPI_INT_STATUS:
+               return SPI_BCM_6348_SPI_INT_STATUS;
+       case SPI_ST:
+               return SPI_BCM_6348_SPI_ST;
+       case SPI_CLK_CFG:
+               return SPI_BCM_6348_SPI_CLK_CFG;
+       case SPI_FILL_BYTE:
+               return SPI_BCM_6348_SPI_FILL_BYTE;
+       case SPI_MSG_TAIL:
+               return SPI_BCM_6348_SPI_MSG_TAIL;
+       case SPI_RX_TAIL:
+               return SPI_BCM_6348_SPI_RX_TAIL;
+       case SPI_MSG_CTL:
+               return SPI_BCM_6348_SPI_MSG_CTL;
+       case SPI_MSG_DATA:
+               return SPI_BCM_6348_SPI_MSG_DATA;
+       case SPI_BCM_6348_SPI_RX_DATA:
+               return SPI_BCM_6348_SPI_RX_DATA;
+}
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6358
+switch (reg) {
+       case SPI_CMD:
+               return SPI_BCM_6358_SPI_CMD;
+       case SPI_INT_STATUS:
+               return SPI_BCM_6358_SPI_INT_STATUS;
+       case SPI_INT_MASK_ST:
+               return SPI_BCM_6358_SPI_MASK_INT_ST;
+       case SPI_INT_MASK:
+               return SPI_BCM_6358_SPI_INT_MASK;
+       case SPI_ST:
+               return SPI_BCM_6358_SPI_STATUS;
+       case SPI_CLK_CFG:
+               return SPI_BCM_6358_SPI_CLK_CFG;
+       case SPI_FILL_BYTE:
+               return SPI_BCM_6358_SPI_FILL_BYTE;
+       case SPI_MSG_TAIL:
+               return SPI_BCM_6358_SPI_MSG_TAIL;
+       case SPI_RX_TAIL:
+               return SPI_BCM_6358_SPI_RX_TAIL;
+       case SPI_MSG_CTL:
+               return SPI_BCM_6358_MSG_CTL;
+       case SPI_MSG_DATA:
+               return SPI_BCM_6358_SPI_MSG_DATA;
+       case SPI_RX_DATA:
+               return SPI_BCM_6358_SPI_RX_FIFO;
+}
+#endif
+#endif
+       return 0;
+}
+
 /*
  * IRQ number changes across CPU too
  */
diff --git a/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_dev_spi.h b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_dev_spi.h
new file mode 100644 (file)
index 0000000..bd47676
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef BCM63XX_DEV_SPI_H
+#define BCM63XX_DEV_SPI_H
+
+#include <linux/types.h>
+
+int bcm63xx_spi_register(void);
+
+struct bcm63xx_spi_pdata {
+       unsigned int    msg_fifo_size;
+       unsigned int    rx_fifo_size;
+       int             bus_num;
+       int             num_chipselect;
+       u32             speed_hz;
+};
+
+#endif /* BCM63XX_DEV_SPI_H */
index 1aef06f1f981ba56c1fe1f136e30edcb0fb7731d..af98611152da6bae546dc411e3f8966a9878a502 100644 (file)
                                        bcm63xx_regset_address(s) + (o))
 #define bcm_rset_writel(s,v,o) bcm_writel((v), \
                                        bcm63xx_regset_address(s) + (o))
+#define bcm_reg_spi_readb(s,o) bcm_readb(bcm63xx_spireg(s) + (o))
+#define bcm_reg_spi_readw(s,o) bcm_readw(bcm63xx_spireg(s) + (o))
+#define bcm_reg_spi_writeb(s,v,o)      bcm_writeb((v), \
+                                       bcm63xx_spireg(s) + (o))
+#define bcm_reg_spi_writew(s,v,o)      bcm_writew((v), \
+                                       bcm63xx_spireg(s) + (o))
 
 /*
  * helpers for frequently used register sets
@@ -89,5 +95,9 @@
 #define bcm_memc_writel(v,o)   bcm_rset_writel(RSET_MEMC, (v), (o))
 #define bcm_ddr_readl(o)       bcm_rset_readl(RSET_DDR, (o))
 #define bcm_ddr_writel(v,o)    bcm_rset_writel(RSET_DDR, (v), (o))
+#define bcm_spi_readb(o)       bcm_reg_spi_readb(RSET_SPI, (o))
+#define bcm_spi_readw(o)       bcm_reg_spi_readw(RSET_SPI, (o))
+#define bcm_spi_writeb(v,o)    bcm_reg_spi_writeb(RSET_SPI, (v), (o))
+#define bcm_spi_writew(v,o)    bcm_reg_spi_writew(RSET_SPI, (v), (o))
 
 #endif /* ! BCM63XX_IO_H_ */