David Brownell <[email protected]> writes:

> From: David Brownell <[email protected]>
>
> Move EDMA platform device creation into SoC-specific init code,
> and provide it with platform_data to parameterize some of the
> key differences.
>
> Handle some key dm646x differences.  Ones that can change the
> behavior including supporting all the DMA slots (512 vs just 128)
> and a different set of no-events channels.
>
> This doesn't yet ioremap(), or support using more than the first
> two TCs on platforms like dm646x or dm365.
>
> Signed-off-by: David Brownell <[email protected]>

Thanks, pushing today.

Kevin

> ---
> Sanity tested on dm6446 and dm355 EVM boards.
>
>  arch/arm/mach-davinci/dm355.c             |   69 +++++
>  arch/arm/mach-davinci/dm644x.c            |   72 +++++
>  arch/arm/mach-davinci/dm646x.c            |   84 ++++++
>  arch/arm/mach-davinci/dma.c               |  342 ++++++++++++----------------
>  arch/arm/mach-davinci/include/mach/edma.h |   24 +
>  5 files changed, 396 insertions(+), 195 deletions(-)
>
> --- a/arch/arm/mach-davinci/dm355.c
> +++ b/arch/arm/mach-davinci/dm355.c
> @@ -18,6 +18,8 @@
>  
>  #include <mach/dm355.h>
>  #include <mach/clock.h>
> +#include <mach/cpu.h>
> +#include <mach/edma.h>
>  #include <mach/psc.h>
>  #include <mach/mux.h>
>  #include <mach/irqs.h>
> @@ -463,8 +465,75 @@ EVT_CFG(DM355,  EVT9_ASP1_RX,          1,  
>  EVT_CFG(DM355,  EVT26_MMC0_RX,             2,    1,    0,     false)
>  };
>  
> +/*----------------------------------------------------------------------*/
> +
> +static const s8 dma_chan_dm355_no_event[] = {
> +     12, 13, 24, 56, 57,
> +     58, 59, 60, 61, 62,
> +     63,
> +     -1
> +};
> +
> +static struct edma_soc_info dm355_edma_info = {
> +     .n_channel      = 64,
> +     .n_region       = 4,
> +     .n_slot         = 128,
> +     .n_tc           = 2,
> +     .noevent        = dma_chan_dm355_no_event,
> +};
> +
> +static struct resource edma_resources[] = {
> +     {
> +             .start  = 0x01c00000,
> +             .end    = 0x01c00000 + SZ_64K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .name   = "edma_tc0",
> +             .start  = 0x01c10000,
> +             .end    = 0x01c10000 + SZ_1K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .name   = "edma_tc1",
> +             .start  = 0x01c10400,
> +             .end    = 0x01c10400 + SZ_1K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .start  = IRQ_CCINT0,
> +             .flags  = IORESOURCE_IRQ,
> +     },
> +     {
> +             .start  = IRQ_CCERRINT,
> +             .flags  = IORESOURCE_IRQ,
> +     },
> +     /* not using (or muxing) TC*_ERR */
> +};
> +
> +static struct platform_device dm355_edma_device = {
> +     .name                   = "edma",
> +     .id                     = -1,
> +     .dev.platform_data      = &dm355_edma_info,
> +     .num_resources          = ARRAY_SIZE(edma_resources),
> +     .resource               = edma_resources,
> +};
> +
> +/*----------------------------------------------------------------------*/
> +
>  void __init dm355_init(void)
>  {
>       davinci_clk_init(dm355_clks);
>       davinci_mux_register(dm355_pins, ARRAY_SIZE(dm355_pins));;
>  }
> +
> +static int __init dm355_init_devices(void)
> +{
> +     if (!cpu_is_davinci_dm355())
> +             return 0;
> +
> +     davinci_cfg_reg(DM355_INT_EDMA_CC);
> +     platform_device_register(&dm355_edma_device);
> +     return 0;
> +}
> +postcore_initcall(dm355_init_devices);
> --- a/arch/arm/mach-davinci/dm644x.c
> +++ b/arch/arm/mach-davinci/dm644x.c
> @@ -11,9 +11,13 @@
>  #include <linux/kernel.h>
>  #include <linux/init.h>
>  #include <linux/clk.h>
> +#include <linux/platform_device.h>
>  
>  #include <mach/dm644x.h>
>  #include <mach/clock.h>
> +#include <mach/cpu.h>
> +#include <mach/edma.h>
> +#include <mach/irqs.h>
>  #include <mach/psc.h>
>  #include <mach/mux.h>
>  
> @@ -358,8 +362,76 @@ MUX_CFG(DM644X, LFLDEN,          0,   25,    1,  
>  };
>  
>  
> +/*----------------------------------------------------------------------*/
> +
> +static const s8 dma_chan_dm644x_no_event[] = {
> +      0,  1, 12, 13, 14,
> +     15, 25, 30, 31, 45,
> +     46, 47, 55, 56, 57,
> +     58, 59, 60, 61, 62,
> +     63,
> +     -1
> +};
> +
> +static struct edma_soc_info dm644x_edma_info = {
> +     .n_channel      = 64,
> +     .n_region       = 4,
> +     .n_slot         = 128,
> +     .n_tc           = 2,
> +     .noevent        = dma_chan_dm644x_no_event,
> +};
> +
> +static struct resource edma_resources[] = {
> +     {
> +             .start  = 0x01c00000,
> +             .end    = 0x01c00000 + SZ_64K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .name   = "edma_tc0",
> +             .start  = 0x01c10000,
> +             .end    = 0x01c10000 + SZ_1K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .name   = "edma_tc1",
> +             .start  = 0x01c10400,
> +             .end    = 0x01c10400 + SZ_1K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .start  = IRQ_CCINT0,
> +             .flags  = IORESOURCE_IRQ,
> +     },
> +     {
> +             .start  = IRQ_CCERRINT,
> +             .flags  = IORESOURCE_IRQ,
> +     },
> +     /* not using TC*_ERR */
> +};
> +
> +static struct platform_device dm644x_edma_device = {
> +     .name                   = "edma",
> +     .id                     = -1,
> +     .dev.platform_data      = &dm644x_edma_info,
> +     .num_resources          = ARRAY_SIZE(edma_resources),
> +     .resource               = edma_resources,
> +};
> +
> +/*----------------------------------------------------------------------*/
> +
>  void __init dm644x_init(void)
>  {
>       davinci_clk_init(dm644x_clks);
>       davinci_mux_register(dm644x_pins, ARRAY_SIZE(dm644x_pins));
>  }
> +
> +static int __init dm644x_init_devices(void)
> +{
> +     if (!cpu_is_davinci_dm644x())
> +             return 0;
> +
> +     platform_device_register(&dm644x_edma_device);
> +     return 0;
> +}
> +postcore_initcall(dm644x_init_devices);
> --- a/arch/arm/mach-davinci/dm646x.c
> +++ b/arch/arm/mach-davinci/dm646x.c
> @@ -11,9 +11,13 @@
>  #include <linux/kernel.h>
>  #include <linux/init.h>
>  #include <linux/clk.h>
> +#include <linux/platform_device.h>
>  
>  #include <mach/dm646x.h>
>  #include <mach/clock.h>
> +#include <mach/cpu.h>
> +#include <mach/edma.h>
> +#include <mach/irqs.h>
>  #include <mach/psc.h>
>  #include <mach/mux.h>
>  
> @@ -273,8 +277,88 @@ MUX_CFG(DM646X, AUDCK1,          0,   29,    1,  
>  MUX_CFG(DM646X, AUDCK0,              0,   28,    1,    0,     false)
>  };
>  
> +/*----------------------------------------------------------------------*/
> +
> +static const s8 dma_chan_dm646x_no_event[] = {
> +      0,  1,  2,  3, 13,
> +     14, 15, 24, 25, 26,
> +     27, 30, 31, 54, 55,
> +     56,
> +     -1
> +};
> +
> +static struct edma_soc_info dm646x_edma_info = {
> +     .n_channel      = 64,
> +     .n_region       = 6,    /* 0-1, 4-7 */
> +     .n_slot         = 512,
> +     .n_tc           = 4,
> +     .noevent        = dma_chan_dm646x_no_event,
> +};
> +
> +static struct resource edma_resources[] = {
> +     {
> +             .start  = 0x01c00000,
> +             .end    = 0x01c00000 + SZ_64K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .name   = "edma_tc0",
> +             .start  = 0x01c10000,
> +             .end    = 0x01c10000 + SZ_1K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .name   = "edma_tc1",
> +             .start  = 0x01c10400,
> +             .end    = 0x01c10400 + SZ_1K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .name   = "edma_tc2",
> +             .start  = 0x01c10800,
> +             .end    = 0x01c10800 + SZ_1K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .name   = "edma_tc3",
> +             .start  = 0x01c10c00,
> +             .end    = 0x01c10c00 + SZ_1K - 1,
> +             .flags  = IORESOURCE_MEM,
> +     },
> +     {
> +             .start  = IRQ_CCINT0,
> +             .flags  = IORESOURCE_IRQ,
> +     },
> +     {
> +             .start  = IRQ_CCERRINT,
> +             .flags  = IORESOURCE_IRQ,
> +     },
> +     /* not using TC*_ERR */
> +};
> +
> +static struct platform_device dm646x_edma_device = {
> +     .name                   = "edma",
> +     .id                     = -1,
> +     .dev.platform_data      = &dm646x_edma_info,
> +     .num_resources          = ARRAY_SIZE(edma_resources),
> +     .resource               = edma_resources,
> +};
> +
> +/*----------------------------------------------------------------------*/
> +
> +
>  void __init dm646x_init(void)
>  {
>       davinci_clk_init(dm646x_clks);
>       davinci_mux_register(dm646x_pins, ARRAY_SIZE(dm646x_pins));
>  }
> +
> +static int __init dm646x_init_devices(void)
> +{
> +     if (!cpu_is_davinci_dm646x())
> +             return 0;
> +
> +     platform_device_register(&dm646x_edma_device);
> +     return 0;
> +}
> +postcore_initcall(dm646x_init_devices);
> --- a/arch/arm/mach-davinci/dma.c
> +++ b/arch/arm/mach-davinci/dma.c
> @@ -104,6 +104,12 @@
>  
>  #define edmacc_regs_base     IO_ADDRESS(DAVINCI_DMA_3PCC_BASE)
>  
> +
> +#define EDMA_MAX_DMACH           64
> +#define EDMA_MAX_PARAMENTRY     512
> +#define EDMA_MAX_EVQUE            2  /* FIXME too small */
> +
> +
>  
> /*****************************************************************************/
>  
>  static inline unsigned int edma_read(int offset)
> @@ -199,55 +205,25 @@ static inline void edma_parm_or(int offs
>  
>  
> /*****************************************************************************/
>  
> -static struct platform_driver edma_driver = {
> -     .driver.name    = "edma",
> -};
> -
> -static struct resource edma_resources[] = {
> -     {
> -             .start  = DAVINCI_DMA_3PCC_BASE,
> -             .end    = DAVINCI_DMA_3PCC_BASE + SZ_64K - 1,
> -             .flags  = IORESOURCE_MEM,
> -     },
> -     {
> -             .name   = "edma_tc0",
> -             .start  = 0x01c10000,
> -             .end    = 0x01c10000 + SZ_1K - 1,
> -             .flags  = IORESOURCE_MEM,
> -     },
> -     {
> -             .name   = "edma_tc1",
> -             .start  = 0x01c10400,
> -             .end    = 0x01c10400 + SZ_1K - 1,
> -             .flags  = IORESOURCE_MEM,
> -     },
> -};
> -
> -static struct platform_device edma_dev = {
> -     .name           = "edma",
> -     .id             = -1,
> -     .dev.driver     = &edma_driver.driver,
> -     .num_resources  = ARRAY_SIZE(edma_resources),
> -     .resource       = edma_resources,
> -};
> -
> -/*****************************************************************************/
> +/* actual number of DMA channels and slots on this silicon */
> +static unsigned num_channels;
> +static unsigned num_slots;
>  
>  static struct dma_interrupt_data {
>       void (*callback)(unsigned channel, unsigned short ch_status, void 
> *data);
>       void *data;
> -} intr_data[DAVINCI_EDMA_NUM_DMACH];
> +} intr_data[EDMA_MAX_DMACH];
>  
>  /* The edma_inuse bit for each PaRAM slot is clear unless the
>   * channel is in use ... by ARM or DSP, for QDMA, or whatever.
>   */
> -static DECLARE_BITMAP(edma_inuse, DAVINCI_EDMA_NUM_PARAMENTRY);
> +static DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
>  
>  /* The edma_noevent bit for each channel is clear unless
>   * it doesn't trigger DMA events on this platform.  It uses a
>   * bit of SOC-specific initialization code.
>   */
> -static DECLARE_BITMAP(edma_noevent, DAVINCI_EDMA_NUM_DMACH);
> +static DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH);
>  
>  /* dummy param set used to (re)initialize parameter RAM slots */
>  static const struct edmacc_param dummy_paramset = {
> @@ -255,16 +231,8 @@ static const struct edmacc_param dummy_p
>       .ccnt = 1,
>  };
>  
> -static const s8 __initconst dma_chan_dm644x_no_event[] = {
> -     0, 1, 12, 13, 14, 15, 25, 30, 31, 45, 46, 47, 55, 56, 57, 58, 59, 60,
> -     61, 62, 63, -1
> -};
> -static const s8 __initconst dma_chan_dm355_no_event[] = {
> -     12, 13, 24, 56, 57, 58, 59, 60, 61, 62, 63, -1
> -};
> -
>  static const int __initconst
> -queue_tc_mapping[DAVINCI_EDMA_NUM_EVQUE + 1][2] = {
> +queue_tc_mapping[EDMA_MAX_EVQUE + 1][2] = {
>  /* {event queue no, TC no} */
>       {0, 0},
>       {1, 1},
> @@ -272,7 +240,7 @@ queue_tc_mapping[DAVINCI_EDMA_NUM_EVQUE 
>  };
>  
>  static const int __initconst
> -queue_priority_mapping[DAVINCI_EDMA_NUM_EVQUE + 1][2] = {
> +queue_priority_mapping[EDMA_MAX_EVQUE + 1][2] = {
>       /* {event queue no, Priority} */
>       {0, 3},
>       {1, 7},
> @@ -337,7 +305,7 @@ static irqreturn_t dma_irq_handler(int i
>       int i;
>       unsigned int cnt = 0;
>  
> -     dev_dbg(&edma_dev.dev, "dma_irq_handler\n");
> +     dev_dbg(data, "dma_irq_handler\n");
>  
>       if ((edma_shadow0_read_array(SH_IPR, 0) == 0)
>           && (edma_shadow0_read_array(SH_IPR, 1) == 0))
> @@ -351,7 +319,7 @@ static irqreturn_t dma_irq_handler(int i
>                       j = 1;
>               else
>                       break;
> -             dev_dbg(&edma_dev.dev, "IPR%d %08x\n", j,
> +             dev_dbg(data, "IPR%d %08x\n", j,
>                               edma_shadow0_read_array(SH_IPR, j));
>               for (i = 0; i < 32; i++) {
>                       int k = (j << 5) + i;
> @@ -382,7 +350,7 @@ static irqreturn_t dma_ccerr_handler(int
>       int i;
>       unsigned int cnt = 0;
>  
> -     dev_dbg(&edma_dev.dev, "dma_ccerr_handler\n");
> +     dev_dbg(data, "dma_ccerr_handler\n");
>  
>       if ((edma_read_array(EDMA_EMR, 0) == 0) &&
>           (edma_read_array(EDMA_EMR, 1) == 0) &&
> @@ -396,7 +364,7 @@ static irqreturn_t dma_ccerr_handler(int
>               else if (edma_read_array(EDMA_EMR, 1))
>                       j = 1;
>               if (j >= 0) {
> -                     dev_dbg(&edma_dev.dev, "EMR%d %08x\n", j,
> +                     dev_dbg(data, "EMR%d %08x\n", j,
>                                       edma_read_array(EDMA_EMR, j));
>                       for (i = 0; i < 32; i++) {
>                               int k = (j << 5) + i;
> @@ -415,7 +383,7 @@ static irqreturn_t dma_ccerr_handler(int
>                               }
>                       }
>               } else if (edma_read(EDMA_QEMR)) {
> -                     dev_dbg(&edma_dev.dev, "QEMR %02x\n",
> +                     dev_dbg(data, "QEMR %02x\n",
>                               edma_read(EDMA_QEMR));
>                       for (i = 0; i < 8; i++) {
>                               if (edma_read(EDMA_QEMR) & (1 << i)) {
> @@ -427,7 +395,7 @@ static irqreturn_t dma_ccerr_handler(int
>                               }
>                       }
>               } else if (edma_read(EDMA_CCERR)) {
> -                     dev_dbg(&edma_dev.dev, "CCERR %08x\n",
> +                     dev_dbg(data, "CCERR %08x\n",
>                               edma_read(EDMA_CCERR));
>                       /* FIXME:  CCERR.BIT(16) ignored!  much better
>                        * to just write CCERRCLR with CCERR value...
> @@ -465,116 +433,16 @@ static irqreturn_t dma_ccerr_handler(int
>  
>  static irqreturn_t dma_tc0err_handler(int irq, void *data)
>  {
> -     dev_dbg(&edma_dev.dev, "dma_tc0err_handler\n");
> +     dev_dbg(data, "dma_tc0err_handler\n");
>       return IRQ_HANDLED;
>  }
>  
>  static irqreturn_t dma_tc1err_handler(int irq, void *data)
>  {
> -     dev_dbg(&edma_dev.dev, "dma_tc1err_handler\n");
> +     dev_dbg(data, "dma_tc1err_handler\n");
>       return IRQ_HANDLED;
>  }
>  
> -/******************************************************************************
> - *
> - * DMA initialisation on davinci
> - *
> - 
> *****************************************************************************/
> -static int __init davinci_dma_init(void)
> -{
> -     int i;
> -     int status;
> -     const s8 *noevent;
> -
> -     platform_driver_register(&edma_driver);
> -     platform_device_register(&edma_dev);
> -
> -     dev_dbg(&edma_dev.dev, "DMA REG BASE ADDR=%p\n", edmacc_regs_base);
> -
> -     for (i = 0; i < DAVINCI_EDMA_NUM_PARAMENTRY; i++)
> -             memcpy_toio(edmacc_regs_base + PARM_OFFSET(i),
> -                             &dummy_paramset, PARM_SIZE);
> -
> -     if (cpu_is_davinci_dm355()) {
> -             /* NOTE conflicts with SPI1_INT{0,1} and SPI2_INT0 */
> -             davinci_cfg_reg(DM355_INT_EDMA_CC);
> -             if (tc_errs_handled) {
> -                     davinci_cfg_reg(DM355_INT_EDMA_TC0_ERR);
> -                     davinci_cfg_reg(DM355_INT_EDMA_TC1_ERR);
> -             }
> -             noevent = dma_chan_dm355_no_event;
> -     } else if (cpu_is_davinci_dm644x()) {
> -             noevent = dma_chan_dm644x_no_event;
> -     } else {
> -             /* alloc_channel(EDMA_CHANNEL_ANY) fails */
> -             noevent = NULL;
> -     }
> -
> -     if (noevent) {
> -             while (*noevent != -1)
> -                     set_bit(*noevent++, edma_noevent);
> -     }
> -
> -     status = request_irq(IRQ_CCINT0, dma_irq_handler, 0, "edma", NULL);
> -     if (status < 0) {
> -             dev_dbg(&edma_dev.dev, "request_irq %d failed --> %d\n",
> -                     IRQ_CCINT0, status);
> -             return status;
> -     }
> -     status = request_irq(IRQ_CCERRINT, dma_ccerr_handler, 0,
> -                             "edma_error", NULL);
> -     if (status < 0) {
> -             dev_dbg(&edma_dev.dev, "request_irq %d failed --> %d\n",
> -                     IRQ_CCERRINT, status);
> -             return status;
> -     }
> -
> -     if (tc_errs_handled) {
> -             status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0,
> -                                     "edma_tc0", NULL);
> -             if (status < 0) {
> -                     dev_dbg(&edma_dev.dev, "request_irq %d failed --> %d\n",
> -                             IRQ_TCERRINT0, status);
> -                     return status;
> -             }
> -             status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0,
> -                                     "edma_tc1", NULL);
> -             if (status < 0) {
> -                     dev_dbg(&edma_dev.dev, "request_irq %d --> %d\n",
> -                             IRQ_TCERRINT, status);
> -                     return status;
> -             }
> -     }
> -
> -     /* Everything lives on transfer controller 1 until otherwise specified.
> -      * This way, long transfers on the low priority queue
> -      * started by the codec engine will not cause audio defects.
> -      */
> -     for (i = 0; i < DAVINCI_EDMA_NUM_DMACH; i++)
> -             map_dmach_queue(i, EVENTQ_1);
> -
> -     i = 0;
> -     /* Event queue to TC mapping */
> -     while (queue_tc_mapping[i][0] != -1) {
> -             map_queue_tc(queue_tc_mapping[i][0], queue_tc_mapping[i][1]);
> -             i++;
> -     }
> -     i = 0;
> -     /* Event queue priority mapping */
> -     while (queue_priority_mapping[i][0] != -1) {
> -             assign_priority_to_queue(queue_priority_mapping[i][0],
> -                                      queue_priority_mapping[i][1]);
> -             i++;
> -     }
> -     for (i = 0; i < DAVINCI_EDMA_NUM_REGIONS; i++) {
> -             edma_write_array2(EDMA_DRAE, i, 0, 0x0);
> -             edma_write_array2(EDMA_DRAE, i, 1, 0x0);
> -             edma_write_array(EDMA_QRAE, i, 0x0);
> -     }
> -     return 0;
> -}
> -arch_initcall(davinci_dma_init);
> -
>  /*-----------------------------------------------------------------------*/
>  
>  /* Resource alloc/free:  dma channels, parameter RAM slots */
> @@ -618,13 +486,13 @@ int edma_alloc_channel(int channel,
>               channel = 0;
>               for (;;) {
>                       channel = find_next_zero_bit(edma_inuse,
> -                                     DAVINCI_EDMA_NUM_DMACH, channel);
> -                     if (channel == DAVINCI_EDMA_NUM_DMACH)
> +                                     num_channels, channel);
> +                     if (channel == num_channels)
>                               return -ENOMEM;
>                       if (!test_and_set_bit(channel, edma_inuse))
>                               break;
>               }
> -     } else if (channel >= DAVINCI_EDMA_NUM_DMACH) {
> +     } else if (channel >= num_channels) {
>               return -EINVAL;
>       } else if (test_and_set_bit(channel, edma_inuse)) {
>               return -EBUSY;
> @@ -661,7 +529,7 @@ EXPORT_SYMBOL(edma_alloc_channel);
>   */
>  void edma_free_channel(unsigned channel)
>  {
> -     if (channel >= DAVINCI_EDMA_NUM_DMACH)
> +     if (channel >= num_channels)
>               return;
>  
>       setup_dma_interrupt(channel, NULL, NULL);
> @@ -690,17 +558,16 @@ EXPORT_SYMBOL(edma_free_channel);
>  int edma_alloc_slot(int slot)
>  {
>       if (slot < 0) {
> -             slot = DAVINCI_EDMA_NUM_DMACH;
> +             slot = num_channels;
>               for (;;) {
>                       slot = find_next_zero_bit(edma_inuse,
> -                                     DAVINCI_EDMA_NUM_PARAMENTRY, slot);
> -                     if (slot == DAVINCI_EDMA_NUM_PARAMENTRY)
> +                                     num_slots, slot);
> +                     if (slot == num_slots)
>                               return -ENOMEM;
>                       if (!test_and_set_bit(slot, edma_inuse))
>                               break;
>               }
> -     } else if (slot < DAVINCI_EDMA_NUM_DMACH
> -                     || slot >= DAVINCI_EDMA_NUM_PARAMENTRY) {
> +     } else if (slot < num_channels || slot >= num_slots) {
>               return -EINVAL;
>       } else if (test_and_set_bit(slot, edma_inuse)) {
>               return -EBUSY;
> @@ -723,8 +590,7 @@ EXPORT_SYMBOL(edma_alloc_slot);
>   */
>  void edma_free_slot(unsigned slot)
>  {
> -     if (slot < DAVINCI_EDMA_NUM_DMACH
> -                     || slot >= DAVINCI_EDMA_NUM_PARAMENTRY)
> +     if (slot < num_channels || slot >= num_slots)
>               return;
>  
>       memcpy_toio(edmacc_regs_base + PARM_OFFSET(slot),
> @@ -751,7 +617,7 @@ EXPORT_SYMBOL(edma_free_slot);
>  void edma_set_src(unsigned slot, dma_addr_t src_port,
>                               enum address_mode mode, enum fifo_width width)
>  {
> -     if (slot < DAVINCI_EDMA_NUM_PARAMENTRY) {
> +     if (slot < num_slots) {
>               unsigned int i = edma_parm_read(PARM_OPT, slot);
>  
>               if (mode) {
> @@ -784,7 +650,7 @@ EXPORT_SYMBOL(edma_set_src);
>  void edma_set_dest(unsigned slot, dma_addr_t dest_port,
>                                enum address_mode mode, enum fifo_width width)
>  {
> -     if (slot < DAVINCI_EDMA_NUM_PARAMENTRY) {
> +     if (slot < num_slots) {
>               unsigned int i = edma_parm_read(PARM_OPT, slot);
>  
>               if (mode) {
> @@ -835,7 +701,7 @@ EXPORT_SYMBOL(edma_get_position);
>   */
>  void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx)
>  {
> -     if (slot < DAVINCI_EDMA_NUM_PARAMENTRY) {
> +     if (slot < num_slots) {
>               edma_parm_modify(PARM_SRC_DST_BIDX, slot,
>                               0xffff0000, src_bidx);
>               edma_parm_modify(PARM_SRC_DST_CIDX, slot,
> @@ -856,7 +722,7 @@ EXPORT_SYMBOL(edma_set_src_index);
>   */
>  void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx)
>  {
> -     if (slot < DAVINCI_EDMA_NUM_PARAMENTRY) {
> +     if (slot < num_slots) {
>               edma_parm_modify(PARM_SRC_DST_BIDX, slot,
>                               0x0000ffff, dest_bidx << 16);
>               edma_parm_modify(PARM_SRC_DST_CIDX, slot,
> @@ -898,7 +764,7 @@ void edma_set_transfer_params(unsigned s
>               u16 acnt, u16 bcnt, u16 ccnt,
>               u16 bcnt_rld, enum sync_dimension sync_mode)
>  {
> -     if (slot < DAVINCI_EDMA_NUM_PARAMENTRY) {
> +     if (slot < num_slots) {
>               edma_parm_modify(PARM_LINK_BCNTRLD, slot,
>                               0x0000ffff, bcnt_rld << 16);
>               if (sync_mode == ASYNC)
> @@ -921,9 +787,9 @@ EXPORT_SYMBOL(edma_set_transfer_params);
>   */
>  void edma_link(unsigned from, unsigned to)
>  {
> -     if (from >= DAVINCI_EDMA_NUM_PARAMENTRY)
> +     if (from >= num_slots)
>               return;
> -     if (to >= DAVINCI_EDMA_NUM_PARAMENTRY)
> +     if (to >= num_slots)
>               return;
>       edma_parm_modify(PARM_LINK_BCNTRLD, from, 0xffff0000, PARM_OFFSET(to));
>  }
> @@ -938,7 +804,7 @@ EXPORT_SYMBOL(edma_link);
>   */
>  void edma_unlink(unsigned from)
>  {
> -     if (from >= DAVINCI_EDMA_NUM_PARAMENTRY)
> +     if (from >= num_slots)
>               return;
>       edma_parm_or(PARM_LINK_BCNTRLD, from, 0xffff);
>  }
> @@ -960,7 +826,7 @@ EXPORT_SYMBOL(edma_unlink);
>   */
>  void edma_write_slot(unsigned slot, const struct edmacc_param *param)
>  {
> -     if (slot >= DAVINCI_EDMA_NUM_PARAMENTRY)
> +     if (slot >= num_slots)
>               return;
>       memcpy_toio(edmacc_regs_base + PARM_OFFSET(slot), param, PARM_SIZE);
>  }
> @@ -976,7 +842,7 @@ EXPORT_SYMBOL(edma_write_slot);
>   */
>  void edma_read_slot(unsigned slot, struct edmacc_param *param)
>  {
> -     if (slot >= DAVINCI_EDMA_NUM_PARAMENTRY)
> +     if (slot >= num_slots)
>               return;
>       memcpy_fromio(param, edmacc_regs_base + PARM_OFFSET(slot), PARM_SIZE);
>  }
> @@ -995,7 +861,7 @@ EXPORT_SYMBOL(edma_read_slot);
>   */
>  void edma_pause(unsigned channel)
>  {
> -     if (channel < DAVINCI_EDMA_NUM_DMACH) {
> +     if (channel < num_channels) {
>               unsigned int mask = (1 << (channel & 0x1f));
>  
>               edma_shadow0_write_array(SH_EECR, channel >> 5, mask);
> @@ -1011,7 +877,7 @@ EXPORT_SYMBOL(edma_pause);
>   */
>  void edma_resume(unsigned channel)
>  {
> -     if (channel < DAVINCI_EDMA_NUM_DMACH) {
> +     if (channel < num_channels) {
>               unsigned int mask = (1 << (channel & 0x1f));
>  
>               edma_shadow0_write_array(SH_EESR, channel >> 5, mask);
> @@ -1032,27 +898,27 @@ EXPORT_SYMBOL(edma_resume);
>   */
>  int edma_start(unsigned channel)
>  {
> -     if (channel < DAVINCI_EDMA_NUM_DMACH) {
> +     if (channel < num_channels) {
>               int j = channel >> 5;
>               unsigned int mask = (1 << (channel & 0x1f));
>  
>               /* EDMA channels without event association */
>               if (test_bit(channel, edma_noevent)) {
> -                     dev_dbg(&edma_dev.dev, "ESR%d %08x\n", j,
> +                     pr_debug("EDMA: ESR%d %08x\n", j,
>                               edma_shadow0_read_array(SH_ESR, j));
>                       edma_shadow0_write_array(SH_ESR, j, mask);
>                       return 0;
>               }
>  
>               /* EDMA channel with event association */
> -             dev_dbg(&edma_dev.dev, "ER%d %08x\n", j,
> +             pr_debug("EDMA: ER%d %08x\n", j,
>                       edma_shadow0_read_array(SH_ER, j));
>               /* Clear any pending error */
>               edma_write_array(EDMA_EMCR, j, mask);
>               /* Clear any SER */
>               edma_shadow0_write_array(SH_SECR, j, mask);
>               edma_shadow0_write_array(SH_EESR, j, mask);
> -             dev_dbg(&edma_dev.dev, "EER%d %08x\n", j,
> +             pr_debug("EDMA: EER%d %08x\n", j,
>                       edma_shadow0_read_array(SH_EER, j));
>               return 0;
>       }
> @@ -1072,7 +938,7 @@ EXPORT_SYMBOL(edma_start);
>   */
>  void edma_stop(unsigned channel)
>  {
> -     if (channel < DAVINCI_EDMA_NUM_DMACH) {
> +     if (channel < num_channels) {
>               int j = channel >> 5;
>               unsigned int mask = (1 << (channel & 0x1f));
>  
> @@ -1081,7 +947,7 @@ void edma_stop(unsigned channel)
>               edma_shadow0_write_array(SH_SECR, j, mask);
>               edma_write_array(EDMA_EMCR, j, mask);
>  
> -             dev_dbg(&edma_dev.dev, "EER%d %08x\n", j,
> +             pr_debug("EDMA: EER%d %08x\n", j,
>                               edma_shadow0_read_array(SH_EER, j));
>  
>               /* REVISIT:  consider guarding against inappropriate event
> @@ -1106,11 +972,11 @@ EXPORT_SYMBOL(edma_stop);
>  
>  void edma_clean_channel(unsigned channel)
>  {
> -     if (channel < DAVINCI_EDMA_NUM_DMACH) {
> +     if (channel < num_channels) {
>               int j = (channel >> 5);
>               unsigned int mask = 1 << (channel & 0x1f);
>  
> -             dev_dbg(&edma_dev.dev, "EMR%d %08x\n", j,
> +             pr_debug("EDMA: EMR%d %08x\n", j,
>                               edma_read_array(EDMA_EMR, j));
>               edma_shadow0_write_array(SH_ECR, j, mask);
>               /* Clear the corresponding EMR bits */
> @@ -1121,3 +987,109 @@ void edma_clean_channel(unsigned channel
>       }
>  }
>  EXPORT_SYMBOL(edma_clean_channel);
> +
> +/*-----------------------------------------------------------------------*/
> +
> +static int __init edma_probe(struct platform_device *pdev)
> +{
> +     struct edma_soc_info    *info = pdev->dev.platform_data;
> +     int                     i;
> +     int                     status;
> +     const s8                *noevent;
> +     int                     irq = 0, err_irq = 0;
> +
> +     if (!info)
> +             return -ENODEV;
> +
> +     num_channels = min_t(unsigned, info->n_channel, EDMA_MAX_DMACH);
> +     num_slots = min_t(unsigned, info->n_slot, EDMA_MAX_PARAMENTRY);
> +
> +     dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", edmacc_regs_base);
> +
> +     for (i = 0; i < num_slots; i++)
> +             memcpy_toio(edmacc_regs_base + PARM_OFFSET(i),
> +                             &dummy_paramset, PARM_SIZE);
> +
> +     noevent = info->noevent;
> +     if (noevent) {
> +             while (*noevent != -1)
> +                     set_bit(*noevent++, edma_noevent);
> +     }
> +
> +     irq = platform_get_irq(pdev, 0);
> +     status = request_irq(irq, dma_irq_handler, 0, "edma", &pdev->dev);
> +     if (status < 0) {
> +             dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
> +                     irq, status);
> +             goto fail;
> +     }
> +
> +     err_irq = platform_get_irq(pdev, 1);
> +     status = request_irq(err_irq, dma_ccerr_handler, 0,
> +                             "edma_error", &pdev->dev);
> +     if (status < 0) {
> +             dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
> +                     err_irq, status);
> +             goto fail;
> +     }
> +
> +     if (tc_errs_handled) {
> +             status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0,
> +                                     "edma_tc0", &pdev->dev);
> +             if (status < 0) {
> +                     dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
> +                             IRQ_TCERRINT0, status);
> +                     return status;
> +             }
> +             status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0,
> +                                     "edma_tc1", &pdev->dev);
> +             if (status < 0) {
> +                     dev_dbg(&pdev->dev, "request_irq %d --> %d\n",
> +                             IRQ_TCERRINT, status);
> +                     return status;
> +             }
> +     }
> +
> +     /* Everything lives on transfer controller 1 until otherwise specified.
> +      * This way, long transfers on the low priority queue
> +      * started by the codec engine will not cause audio defects.
> +      */
> +     for (i = 0; i < num_channels; i++)
> +             map_dmach_queue(i, EVENTQ_1);
> +
> +     /* Event queue to TC mapping */
> +     for (i = 0; queue_tc_mapping[i][0] != -1; i++)
> +             map_queue_tc(queue_tc_mapping[i][0], queue_tc_mapping[i][1]);
> +
> +     /* Event queue priority mapping */
> +     for (i = 0; queue_priority_mapping[i][0] != -1; i++)
> +             assign_priority_to_queue(queue_priority_mapping[i][0],
> +                                      queue_priority_mapping[i][1]);
> +
> +     for (i = 0; i < info->n_region; i++) {
> +             edma_write_array2(EDMA_DRAE, i, 0, 0x0);
> +             edma_write_array2(EDMA_DRAE, i, 1, 0x0);
> +             edma_write_array(EDMA_QRAE, i, 0x0);
> +     }
> +
> +     return 0;
> +
> +fail:
> +     if (err_irq)
> +             free_irq(err_irq, NULL);
> +     if (irq)
> +             free_irq(irq, NULL);
> +     return status;
> +}
> +
> +
> +static struct platform_driver edma_driver = {
> +     .driver.name    = "edma",
> +};
> +
> +static int __init edma_init(void)
> +{
> +     return platform_driver_probe(&edma_driver, edma_probe);
> +}
> +arch_initcall(edma_init);
> +
> --- a/arch/arm/mach-davinci/include/mach/edma.h
> +++ b/arch/arm/mach-davinci/include/mach/edma.h
> @@ -91,16 +91,6 @@ struct edmacc_param {
>  #define TRWORD (0x7<<2)
>  #define PAENTRY (0x1ff<<5)
>  
> -
> -#define DAVINCI_EDMA_NUM_DMACH           64
> -
> -#define DAVINCI_EDMA_NUM_PARAMENTRY     128
> -#define DAVINCI_EDMA_NUM_EVQUE            2
> -#define DAVINCI_EDMA_CHMAPEXIST           0
> -#define DAVINCI_EDMA_NUM_REGIONS          4
> -#define DAVINCI_EDMA_MEMPROTECT           0
> -
> -
>  /* Drivers should avoid using these symbolic names for dm644x
>   * channels, and use platform_device IORESOURCE_DMA resources
>   * instead.  (Other DaVinci chips have different peripherals
> @@ -221,4 +211,18 @@ void edma_resume(unsigned channel);
>  /* UNRELATED TO DMA */
>  int davinci_alloc_iram(unsigned size);
>  void davinci_free_iram(unsigned addr, unsigned size);
> +
> +/* platform_data for EDMA driver */
> +struct edma_soc_info {
> +
> +     /* how many dma resources of each type */
> +     unsigned        n_channel;
> +     unsigned        n_region;
> +     unsigned        n_slot;
> +     unsigned        n_tc;
> +
> +     /* list of channels with no even trigger; terminated by "-1" */
> +     const s8        *noevent;
> +};
> +
>  #endif

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to