David Brownell <[email protected]> writes:

> On Wednesday 07 January 2009, Kevin Hilman wrote:
>> David Brownell <[email protected]> writes:
>> 
>> > Result:  object code down by over 55%; source by over 30%.
>> > (Compared to what's in current GIT.)
>> >
>> >  - Remove QDMA; it's got a poor and unused interface
>> >  - Remove duplicative IRQ bitmap, and related cleanup
>> >  - ...
>> >
>> > I'm thinking this gets it a lot closer to something that
>> > could go to mainline...
>> >
>> >
>> > These go on top of the DM355 MMC and DMA patches I sent
>> > before the holidays.  It's been sanity tested with MMC and
>> > audio, the only two drivers in the GIT tree that use DMA.
>> 
>> Dave,
>> 
>> I must be missing something since these don't apply for me on top of
>> your other series.  I've created a 'staging/daveb' branch in davinci
>> git where I've where I've applied all the stuff from you I haven't yet
>> pushed.  This series doesn't apply there.  The first patch gets 6/27
>> hunks failed.  Any idea what I'm missing?
>
> I think you applied the wrong version of the "fix valid channels
> for dm355" patch.  The first one I sent was pretty ugly.  Here's
> the version I prefer.

Doh, I'm saw the updated version but still managed to apply the first
version.  Sorry.  Now the EDMA series is applying for me.  After a
quick glance,  I like what I see.  Will review/merge tomorrow.

Kevin

>
> ======== CUT HERE
> From: David Brownell <[email protected]>
>
> Learn that the dm355 and dm644x chips have different sets of
> valid DMA event channels.  Those channels are now represented
> using a bitmap, which is small and much quicker to test than
> the previous array.
>
> MMC1 DMA now works on dm355; it uses channels that dm6446 doesn't.  
>
> Minor cleanups of the DaVinci DMA code:  spelling/grammar, and
> marking const data arrays as such.  Shrink some data.
>
> Signed-off-by: David Brownell <[email protected]>
> ---
> CHANGE since first version:  represent valid DMA event channels
> using a bitmap.  It's much cleaner, and faster too.
>
>  arch/arm/mach-davinci/dma.c |  146 +++++++++++++++++++++---------------------
>  1 file changed, 75 insertions(+), 71 deletions(-)
>
> --- a/arch/arm/mach-davinci/dma.c
> +++ b/arch/arm/mach-davinci/dma.c
> @@ -29,6 +29,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/platform_device.h>
>  #include <linux/spinlock.h>
> +#include <linux/compiler.h>
>  #include <linux/io.h>
>  
>  #include <mach/cpu.h>
> @@ -259,27 +260,27 @@ static struct dma_interrupt_data {
>  } intr_data[64];
>  
>  /*
> -  Each bit field of the elements bellow indicate the corresponding EDMA 
> channel
> +  Each bit field of the elements below indicates corresponding EDMA channel
>    availability  on arm side events
>  */
> -static unsigned long edma_channels_arm[] = {
> +static const unsigned long edma_channels_arm[] = {
>       0xffffffff,
>       0xffffffff
>  };
>  
>  /*
> -  Each bit field of the elements bellow indicate the corresponding QDMA 
> channel
> +  Each bit field of the elements below indicates corresponding QDMA channel
>    availability  on arm side events
>  */
> -static unsigned char qdma_channels_arm[] = {
> +static const unsigned char qdma_channels_arm[] = {
>       0x00
>  };
>  
>  /*
> -   Each bit field of the elements bellow indicate corresponding PARAM entry
> -   availibility on arm side events
> +   Each bit field of the elements below indicates corresponding PARAM entry
> +   availability on arm side events
>  */
> -static unsigned long param_entry_arm[] = {
> +static const unsigned long param_entry_arm[] = {
>       0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff,
>       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
>       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
> @@ -287,7 +288,7 @@ static unsigned long param_entry_arm[] =
>  };
>  
>  /*
> -   Each bit field of the elements bellow indicate whether a PARAM entry
> +   Each bit field of the elements below indicates whether a PARAM entry
>     is free or in use
>     1 - free
>     0 - in use
> @@ -300,7 +301,7 @@ static unsigned long param_entry_use_sta
>  };
>  
>  /*
> -   Each bit field of the elements bellow indicate whether a intrerrupt
> +   Each bit field of the elements below indicates whether an interrupt
>     is free or in use
>     1 - free
>     0 - in use
> @@ -310,23 +311,28 @@ static unsigned long dma_intr_use_status
>       0xffffffff
>  };
>  
> -/*
> -    This lists the DMA channel numbers which does not have any events
> -    associated with it
> -*/
> -static int dma_chan_no_event[] = {
> +/* The edma_noevent bit for each master 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 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 int queue_tc_mapping[DAVINCI_EDMA_NUM_EVQUE + 1][2] = {
> +static const int queue_tc_mapping[DAVINCI_EDMA_NUM_EVQUE + 1][2] = {
>  /* {event queue no, TC no} */
>       {0, 0},
>       {1, 1},
>       {-1, -1}
>  };
>  
> -static int queue_priority_mapping[DAVINCI_EDMA_NUM_EVQUE + 1][2] = {
> +static const int queue_priority_mapping[DAVINCI_EDMA_NUM_EVQUE + 1][2] = {
>       /* {event queue no, Priority} */
>       {0, 3},
>       {1, 7},
> @@ -335,7 +341,6 @@ static int queue_priority_mapping[DAVINC
>  
>  static int qdam_to_param_mapping[8] = { 0 };
>  
> -
>  
> /*****************************************************************************/
>  
>  static void map_dmach_queue(int ch_no, int queue_no)
> @@ -386,7 +391,8 @@ static void __init assign_priority_to_qu
>   
> *****************************************************************************/
>  static int request_param(int lch, int dev_id)
>  {
> -     int i = 0, j = 0, is_break = 0;
> +     int i = 0;
> +
>       if (lch >= 0 && lch < DAVINCI_EDMA_NUM_DMACH) {
>               /*
>                  In davinci there is 1:1 mapping between edma channels
> @@ -416,17 +422,16 @@ static int request_param(int lch, int de
>  
>               LOCK;
>               while (i < DAVINCI_EDMA_NUM_PARAMENTRY) {
> -                     j = 0, is_break = 1;
>                       if ((param_entry_arm[i / 32] & (1 << (i % 32))) &&
>                           (param_entry_use_status[i / 32] &
>                                               (1 << (i % 32)))) {
> +                             /* if (dev_id == DAVINCI_DMA_CHANNEL_ANY
> +                              *    || DAVINCI_EDMA_IS_Q(dev_id)) ...
> +                              */
>                               if (dev_id != DAVINCI_EDMA_PARAM_ANY) {
> -                                     while (dma_chan_no_event[j] != -1) {
> -                                             if (dma_chan_no_event[j] == i)
> -                                                     is_break = 0;
> -                                             j++;
> -                                     }
> -                                     if (!is_break)
> +                                     if (i >= DAVINCI_EDMA_NUM_DMACH)
> +                                             continue;
> +                                     if (test_bit(i, edma_noevent))
>                                               break;
>                               } else {
>                                       break;
> @@ -491,7 +496,8 @@ static int request_dma_interrupt(int lch
>                                void *data, int param_no, int requested_tcc)
>  {
>       signed int free_intr_no = -1;
> -     int i = 0, j = 0, is_break = 0;
> +     int i = 0;
> +
>       /* edma channels */
>       if (lch >= 0 && lch < DAVINCI_EDMA_NUM_DMACH) {
>               /* Bitmap dma_intr_use_status is used to identify availabe tcc
> @@ -524,17 +530,9 @@ static int request_dma_interrupt(int lch
>                       LOCK;
>                       if (dma_intr_use_status[requested_tcc / 32] &
>                           (1 << (requested_tcc % 32))) {
> -                             j = 0;
> -                             is_break = 1;
> -                             while (dma_chan_no_event[j] != -1) {
> -                                     if (dma_chan_no_event[j] ==
> -                                         requested_tcc) {
> -                                             is_break = 0;
> -                                             break;
> -                                     }
> -                                     j++;
> -                             }
> -                             if (!is_break) {
> +                             if (requested_tcc < DAVINCI_EDMA_NUM_DMACH
> +                                             && test_bit(requested_tcc,
> +                                                             edma_noevent)) {
>                                       dma_intr_use_status[requested_tcc / 32]
>                                           &= (~(1 << (requested_tcc % 32)));
>                                       free_intr_no = requested_tcc;
> @@ -558,18 +556,9 @@ static int request_dma_interrupt(int lch
>                       i = 0;
>                       LOCK;
>                       while (i < DAVINCI_EDMA_NUM_DMACH) {
> -                             j = 0;
> -                             is_break = 1;
>                               if (dma_intr_use_status[i / 32] &
>                                   (1 << (i % 32))) {
> -                                     while (dma_chan_no_event[j] != -1) {
> -                                             if (dma_chan_no_event[j] == i) {
> -                                                     is_break = 0;
> -                                                     break;
> -                                             }
> -                                             j++;
> -                                     }
> -                                     if (!is_break) {
> +                                     if (test_bit(i, edma_noevent)) {
>                                               dma_intr_use_status[i / 32] &=
>                                                   (~(1 << (i % 32)));
>                                               free_intr_no = i;
> @@ -586,12 +575,10 @@ static int request_dma_interrupt(int lch
>                       }
>                       UNLOCK;
>               }
> -     } else {
> -             dev_dbg(&edma_dev.dev, "ERROR lch = %d\r\n", lch);
>       }
> -     if (is_break) {
> -             dev_dbg(&edma_dev.dev,
> -                             "While allocating EDMA channel for QDMA");
> +     if (free_intr_no < 0) {
> +             dev_dbg(&edma_dev.dev, "no IRQ for channel %d\n", lch);
> +             return -EIO;
>       }
>       if (DAVINCI_EDMA_IS_Q(lch)) {
>               edma_or_array2(EDMA_DRAE, 0, free_intr_no >> 5,
> @@ -801,6 +788,7 @@ static int __init davinci_dma_init(void)
>  {
>       int i;
>       int status;
> +     const s8 *noevent;
>  
>       platform_driver_register(&edma_driver);
>       platform_device_register(&edma_dev);
> @@ -817,6 +805,17 @@ static int __init davinci_dma_init(void)
>                       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 {
> +             /* request_dma(DAVINCI_DMA_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);
> @@ -1013,17 +1012,24 @@ int davinci_request_dma(int dev_id, cons
>                       map_dmach_queue(dev_id, eventq_no);
>                       ret_val = 0;
>               }
> +
> +     /* return some master channel with no event association */
>       } else if (dev_id == DAVINCI_DMA_CHANNEL_ANY) {
>               i = 0;
>               ret_val = 0;
> -             while (dma_chan_no_event[i] != -1) {
> -                     if (!dma_chan[dma_chan_no_event[i]].in_use) {
> +             for (;;) {
> +                     i = find_next_bit(edma_noevent, i,
> +                                     DAVINCI_EDMA_NUM_DMACH);
> +                     if (i == DAVINCI_EDMA_NUM_DMACH)
> +                             break;
> +                     if (!dma_chan[i].in_use) {
>                               int j;
> -                             *lch = dma_chan_no_event[i];
> -                             j = dma_chan[*lch].param_no =
> -                                             request_param(*lch, dev_id);
> +
> +                             *lch = i;
> +                             j = request_param(*lch, dev_id);
>                               if (j == -1)
>                                       return -EINVAL;
> +                             dma_chan[*lch].param_no = j;
>                               dev_dbg(&edma_dev.dev, "param_no=%d\r\n", j);
>                               if (DAVINCI_EDMA_IS_Q(j)) {
>                                       edma_or_array(EDMA_QRAE, 0, 1 << (j -
> @@ -1047,8 +1053,9 @@ int davinci_request_dma(int dev_id, cons
>                               ret_val = 0;
>                               break;
>                       }
> -                     i++;
>               }
> +
> +     /* return some slave channel */
>       } else if (dev_id == DAVINCI_EDMA_PARAM_ANY) {
>               ret_val = 0;
>               for (i = DAVINCI_EDMA_QEND;
> @@ -1080,7 +1087,7 @@ int davinci_request_dma(int dev_id, cons
>       }
>       if (!ret_val) {
>               if (DAVINCI_EDMA_IS_Q(dev_id)) {
> -                     /* Master Channel */
> +                     /* Channel used for QDMA */
>                       unsigned int opt;
>                       int temp_ch = dma_chan[*lch].param_no;
>                       qdam_to_param_mapping[dev_id - DAVINCI_EDMA_QSTART] =
> @@ -1106,7 +1113,7 @@ int davinci_request_dma(int dev_id, cons
>                       edma_parm_or(PARM_LINK_BCNTRLD, temp_ch, 0xffff);
>               } else {
>                       int j;
> -                     /* Slave Channel */
> +                     /* Normal master or slave Channel */
>                       LOCK;
>                       /* Global structure to identify whether resoures is
>                          available or not */
> @@ -1377,20 +1384,17 @@ int davinci_start_dma(int lch)
>  {
>       int ret_val = 0;
>       if ((lch >= 0) && (lch < DAVINCI_EDMA_NUM_DMACH)) {
> -             int i = 0;
>               int j = lch >> 5;
>               unsigned int mask = (1 << (lch & 0x1f));
> -             /* If the dma start request is for the unused events */
> -             while (dma_chan_no_event[i] != -1) {
> -                     if (dma_chan_no_event[i] == lch) {
> -                             /* EDMA channels without event association */
> -                             dev_dbg(&edma_dev.dev, "ESR%d=%x\r\n", j,
> -                                     edma_shadow0_read_array(SH_ESR, j));
> -                             edma_shadow0_write_array(SH_ESR, j, mask);
> -                             return ret_val;
> -                     }
> -                     i++;
> +
> +             /* EDMA channels without event association */
> +             if (test_bit(lch, edma_noevent)) {
> +                     dev_dbg(&edma_dev.dev, "ESR%d %08x\n", j,
> +                             edma_shadow0_read_array(SH_ESR, j));
> +                     edma_shadow0_write_array(SH_ESR, j, mask);
> +                     return ret_val;
>               }
> +
>               /* EDMA channel with event association */
>               dev_dbg(&edma_dev.dev, "ER%d=%x\r\n", j,
>                       edma_shadow0_read_array(SH_ER, j));

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

Reply via email to