diff options
Diffstat (limited to 'target/linux')
5 files changed, 252 insertions, 0 deletions
diff --git a/target/linux/brcm63xx/files/arch/mips/bcm63xx/cpu.c b/target/linux/brcm63xx/files/arch/mips/bcm63xx/cpu.c index c147e2831a..b69821cc61 100644 --- a/target/linux/brcm63xx/files/arch/mips/bcm63xx/cpu.c +++ b/target/linux/brcm63xx/files/arch/mips/bcm63xx/cpu.c @@ -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 index 0000000000..4aea088d2d --- /dev/null +++ b/target/linux/brcm63xx/files/arch/mips/bcm63xx/dev-spi.c @@ -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); +} diff --git a/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_cpu.h b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_cpu.h index 6fa8825b49..be9da2eee7 100644 --- a/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_cpu.h +++ b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_cpu.h @@ -290,6 +290,120 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) } /* + * 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 */ enum bcm63xx_irq { 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 index 0000000000..bd47676a48 --- /dev/null +++ b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_dev_spi.h @@ -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 */ diff --git a/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_io.h b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_io.h index 1aef06f1f9..af98611152 100644 --- a/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_io.h +++ b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm63xx_io.h @@ -65,6 +65,12 @@ 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_ */ |