From: Thomas Koeller <[email protected]> Change the SPI setup code to allow use of all SPI units. Also, move some resource assignments (DMA channels, interrupts) to the board code, where they belong. These really should not be hard-coded in dm365.c.
Signed-off-by: Thomas Koeller <[email protected]> --- arch/arm/mach-davinci/board-dm365-evm.c | 37 +++- arch/arm/mach-davinci/board_dm365_evm_resources.h | 17 ++ arch/arm/mach-davinci/dm365.c | 278 +++++++++++++++++---- arch/arm/mach-davinci/include/mach/dm365.h | 16 +- 4 files changed, 293 insertions(+), 55 deletions(-) create mode 100644 arch/arm/mach-davinci/board_dm365_evm_resources.h diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index ab3b0e2..6797d3e 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -49,6 +49,8 @@ #include <media/tvp7002.h> #include <media/davinci/videohd.h> +#include "board_dm365_evm_resources.h" + /* have_imager() - Check if we have support for imager interface */ @@ -832,16 +834,39 @@ static struct spi_eeprom at25640 = { .flags = EE_ADDR2, }; -static struct spi_board_info dm365_evm_spi_info[] __initconst = { - { +static const struct spi_board_info + dm365_evm_spi_info_at25 __initconst = { .modalias = "at25", .platform_data = &at25640, .max_speed_hz = 20 * 1000 * 1000, /* at 3v3 */ .bus_num = 0, .chip_select = 0, .mode = SPI_MODE_0, - }, -}; + }; + +static struct dm365_spi_unit_desc + dm365_evm_spi_udesc_at25 = { + .spi_hwunit = 0, + .chipsel = BIT(0), + .irq = IRQ_SPI0, + .dma_tx_chan = DMA_CHAN_SPI0_TX, + .dma_rx_chan = DMA_CHAN_SPI0_RX, + .dma_evtq = DMA_EVQ_SPI0, + .pdata = { + .version = SPI_VERSION_1, + .num_chipselect = 2, + .clk_internal = 1, + .cs_hold = 1, + .intr_level = 0, + .poll_mode = 1, /* 0 -> interrupt mode 1-> polling mode */ + .use_dma = 1, /* when 1, value in poll_mode is ignored */ + .c2tdelay = 0, + .t2cdelay = 0 + } + }; + + + static __init void dm365_evm_init(void) { @@ -861,8 +886,8 @@ static __init void dm365_evm_init(void) dm365_init_rtc(); dm365_init_ks(&dm365evm_ks_data); - dm365_init_spi0(BIT(0), dm365_evm_spi_info, - ARRAY_SIZE(dm365_evm_spi_info)); + dm365_init_spi(&dm365_evm_spi_udesc_at25, 1, &dm365_evm_spi_info_at25); + return; } static __init void dm365_evm_irq_init(void) diff --git a/arch/arm/mach-davinci/board_dm365_evm_resources.h b/arch/arm/mach-davinci/board_dm365_evm_resources.h new file mode 100644 index 0000000..d9cfc6b --- /dev/null +++ b/arch/arm/mach-davinci/board_dm365_evm_resources.h @@ -0,0 +1,17 @@ +#ifndef _DAVINCI_EVM_RESOURCES_H +#define _DAVINCI_EVM_RESOURCES_H + +#include <mach/irqs.h> +#include <mach/edma.h> + +/* IRQs */ +#define IRQ_SPI0 IRQ_DM365_SPIINT0_0 + +/* DMA channels */ +#define DMA_CHAN_SPI0_TX 16 +#define DMA_CHAN_SPI0_RX 17 + +/* DMA event queues */ +#define DMA_EVQ_SPI0 EVENTQ_3 + +#endif /* _DAVINCI_EVM_RESOURCES_H */ diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index ed6c9c7..023d708 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -616,72 +616,256 @@ EVT_CFG(DM365, EVT3_ASP_RX, 1, 1, 0, false) #endif }; -static u64 dm365_spi0_dma_mask = DMA_BIT_MASK(32); +static u64 dm365_spi_dma_mask = DMA_BIT_MASK(32); -static struct davinci_spi_platform_data dm365_spi0_pdata = { - .version = SPI_VERSION_1, - .num_chipselect = 2, - .clk_internal = 1, - .cs_hold = 1, - .intr_level = 0, - .poll_mode = 1, /* 0 -> interrupt mode 1-> polling mode */ - .use_dma = 1, /* when 1, value in poll_mode is ignored */ - .c2tdelay = 0, - .t2cdelay = 0, +enum dm365_spi_resource_index { + spirsrc_iomem, + spirsrc_irq, + spirsrc_rxdma, + spirsrc_txdma, + spirsrc_evqdma }; -static struct resource dm365_spi0_resources[] = { + +static struct resource dm365_spi_resources[spirsrc_evqdma + 1][5] = { { - .start = 0x01c66000, - .end = 0x01c667ff, - .flags = IORESOURCE_MEM, + [spirsrc_iomem] = { + .start = 0x01c66000, + .end = 0x01c667ff, + .flags = IORESOURCE_MEM, + }, + [spirsrc_irq] = { + .flags = IORESOURCE_IRQ, + }, + [spirsrc_rxdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_RX_CHAN, + }, + [spirsrc_txdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_TX_CHAN, + }, + [spirsrc_evqdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_EVENT_Q, + } }, { - .start = IRQ_DM365_SPIINT0_0, - .flags = IORESOURCE_IRQ, + [spirsrc_iomem] = { + .start = 0x01c66800, + .end = 0x01c66fff, + .flags = IORESOURCE_MEM, + }, + [spirsrc_irq] = { + .flags = IORESOURCE_IRQ, + }, + [spirsrc_rxdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_RX_CHAN, + }, + [spirsrc_txdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_TX_CHAN, + }, + [spirsrc_evqdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_EVENT_Q, + } }, { - .start = 17, - .flags = IORESOURCE_DMA | IORESOURCE_DMA_RX_CHAN, + [spirsrc_iomem] = { + .start = 0x01c67800, + .end = 0x01c67fff, + .flags = IORESOURCE_MEM, + }, + [spirsrc_irq] = { + .flags = IORESOURCE_IRQ, + }, + [spirsrc_rxdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_RX_CHAN, + }, + [spirsrc_txdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_TX_CHAN, + }, + [spirsrc_evqdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_EVENT_Q, + } }, { - .start = 16, - .flags = IORESOURCE_DMA | IORESOURCE_DMA_TX_CHAN, + [spirsrc_iomem] = { + .start = 0x01c68000, + .end = 0x01c687ff, + .flags = IORESOURCE_MEM, + }, + [spirsrc_irq] = { + .flags = IORESOURCE_IRQ, + }, + [spirsrc_rxdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_RX_CHAN, + }, + [spirsrc_txdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_TX_CHAN, + }, + [spirsrc_evqdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_EVENT_Q, + } }, { - .start = EVENTQ_3, - .flags = IORESOURCE_DMA | IORESOURCE_DMA_EVENT_Q, + [spirsrc_iomem] = { + .start = 0x01c23000, + .end = 0x01c237ff, + .flags = IORESOURCE_MEM, + }, + [spirsrc_irq] = { + .flags = IORESOURCE_IRQ, + }, + [spirsrc_rxdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_RX_CHAN, + }, + [spirsrc_txdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_TX_CHAN, + }, + [spirsrc_evqdma] = { + .flags = IORESOURCE_DMA | IORESOURCE_DMA_EVENT_Q, + } + } +}; + +static struct platform_device dm365_spi_device[] = { + { + .name = "spi_davinci", + .id = 0, + .dev = { + .dma_mask = &dm365_spi_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(dm365_spi_resources[0]), + .resource = dm365_spi_resources[0] }, -}; - -static struct platform_device dm365_spi0_device = { - .name = "spi_davinci", - .id = 0, - .dev = { - .dma_mask = &dm365_spi0_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &dm365_spi0_pdata, + { + .name = "spi_davinci", + .id = 1, + .dev = { + .dma_mask = &dm365_spi_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(dm365_spi_resources[1]), + .resource = dm365_spi_resources[1] + }, + { + .name = "spi_davinci", + .id = 2, + .dev = { + .dma_mask = &dm365_spi_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(dm365_spi_resources[2]), + .resource = dm365_spi_resources[2] + }, + { + .name = "spi_davinci", + .id = 3, + .dev = { + .dma_mask = &dm365_spi_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(dm365_spi_resources[3]), + .resource = dm365_spi_resources[3] }, - .num_resources = ARRAY_SIZE(dm365_spi0_resources), - .resource = dm365_spi0_resources, + { + .name = "spi_davinci", + .id = 4, + .dev = { + .dma_mask = &dm365_spi_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(dm365_spi_resources[4]), + .resource = dm365_spi_resources[4] + } +}; + +struct dm365_spi_pins { + int sclk; + int sdi; + int sdo; + int sdena0; + int sdena1; +}; + +static const struct dm365_spi_pins dm365_spi_pinmap[] __initconst = { + { + .sclk = DM365_SPI0_SCLK, + .sdi = DM365_SPI0_SDI, + .sdo = DM365_SPI0_SDO, + .sdena0 = DM365_SPI0_SDENA0, + .sdena1 = DM365_SPI0_SDENA1 + }, + { + .sclk = DM365_SPI1_SCLK, + .sdi = DM365_SPI1_SDI, + .sdo = DM365_SPI1_SDO, + .sdena0 = DM365_SPI1_SDENA0, + .sdena1 = DM365_SPI1_SDENA1 + }, + { + .sclk = DM365_SPI2_SCLK, + .sdi = DM365_SPI2_SDI, + .sdo = DM365_SPI2_SDO, + .sdena0 = DM365_SPI2_SDENA0, + .sdena1 = DM365_SPI2_SDENA1 + }, + { + .sclk = DM365_SPI3_SCLK, + .sdi = DM365_SPI3_SDI, + .sdo = DM365_SPI3_SDO, + .sdena0 = DM365_SPI3_SDENA0, + .sdena1 = DM365_SPI3_SDENA1 + }, + { + .sclk = DM365_SPI4_SCLK, + .sdi = DM365_SPI4_SDI, + .sdo = DM365_SPI4_SDO, + .sdena0 = DM365_SPI4_SDENA0, + .sdena1 = DM365_SPI4_SDENA1 + } }; -void __init dm365_init_spi0(unsigned chipselect_mask, - struct spi_board_info *info, unsigned len) +void __init dm365_init_spi(struct dm365_spi_unit_desc *unit, + unsigned int ninfo, + const struct spi_board_info *info) { - davinci_cfg_reg(DM365_SPI0_SCLK); - davinci_cfg_reg(DM365_SPI0_SDI); - davinci_cfg_reg(DM365_SPI0_SDO); + int err; + const unsigned int hwunit = unit->spi_hwunit; + const struct dm365_spi_pins * const pins = &dm365_spi_pinmap[hwunit]; + struct platform_device * const pdev = &dm365_spi_device[hwunit]; + struct davinci_spi_platform_data * const pdata = &unit->pdata; - /* not all slaves will be wired up */ - if (chipselect_mask & BIT(0)) - davinci_cfg_reg(DM365_SPI0_SDENA0); - if (chipselect_mask & BIT(1)) - davinci_cfg_reg(DM365_SPI0_SDENA1); - - spi_register_board_info(info, len); + davinci_cfg_reg(pins->sclk); + davinci_cfg_reg(pins->sdi); + davinci_cfg_reg(pins->sdo); - platform_device_register(&dm365_spi0_device); + /* not all slaves will be wired up */ + if (unit->chipsel & BIT(0)) + davinci_cfg_reg(pins->sdena0); + if (unit->chipsel & BIT(1)) + davinci_cfg_reg(pins->sdena1); + + pdev->dev.platform_data = pdata; + + pdev->resource[spirsrc_irq].start = + pdev->resource[spirsrc_irq].end = unit->irq; + pdev->resource[spirsrc_rxdma].start = + pdev->resource[spirsrc_rxdma].end = unit->dma_rx_chan; + pdev->resource[spirsrc_txdma].start = + pdev->resource[spirsrc_txdma].end = unit->dma_tx_chan; + pdev->resource[spirsrc_evqdma].start = + pdev->resource[spirsrc_evqdma].end = unit->dma_evtq; + + pr_debug("Creating SPI%u: irq = %u, dma_rx = %u, dma_tx = %u, " + "dma_evq = %u", + hwunit, unit->irq, unit->dma_rx_chan, unit->dma_tx_chan, + unit->dma_evtq); + + err = platform_device_register(pdev); + if (unlikely(err)) + pr_err("Failed to create platform device for SPI%u - error %d", + hwunit, err); + + spi_register_board_info(info, ninfo); } diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h index 44b0cc6..3d2a823 100644 --- a/arch/arm/mach-davinci/include/mach/dm365.h +++ b/arch/arm/mach-davinci/include/mach/dm365.h @@ -19,6 +19,7 @@ #include <mach/emac.h> #include <mach/asp.h> #include <mach/keyscan.h> +#include <mach/spi.h> #define DM365_EMAC_BASE (0x01D07000) #define DM365_EMAC_CNTRL_OFFSET (0x0000) @@ -38,8 +39,19 @@ void __init dm365_init_rtc(void); void __init dm365_init_ks(struct davinci_ks_platform_data *pdata); void dm365_set_vpfe_config(struct vpfe_config *cfg); +struct dm365_spi_unit_desc { + unsigned int spi_hwunit; + unsigned int chipsel; + unsigned int irq; + unsigned int dma_tx_chan; + unsigned int dma_rx_chan; + unsigned int dma_evtq; + struct davinci_spi_platform_data pdata; +}; + struct spi_board_info; -void dm365_init_spi0(unsigned chipselect_mask, - struct spi_board_info *info, unsigned len); +void dm365_init_spi(struct dm365_spi_unit_desc *unit, + unsigned int ninfo, + const struct spi_board_info *info); #endif /* __ASM_ARCH_DM365_H */ -- 1.7.0.3 _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
