From: David Brownell <[email protected]>

Use memcpy_{from,to}io() to read and write entire parameter RAM
slots, saving a surprising 268 bytes over the existing code.
Renames those parameters to be more sensible than "temp".

Fix a minor glitch and ensure all DMA channels are initialized with
a dummy transfer with all options zeroed, so it's not possible to
accidentally start getting intermediate completion callbacks or
event chaining by accident.  Save eight bytes while doing that.

Shrink davinci_stop_dma() by not testing if the bits are already
cleared; if they were, clearing again is harmless.  And shrink
map_dmach_queue() by avoiding a superfluous test.

EDMA runtime code footprint is now under 2700 bytes, and there
are still further cleanups that could be done...

Signed-off-by: David Brownell <[email protected]>
---
 arch/arm/mach-davinci/dma.c |   87 +++++++++++++-----------------------------
 1 file changed, 27 insertions(+), 60 deletions(-)

--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -102,7 +102,7 @@
 
 #define PARM_OFFSET(param_no)  (EDMA_PARM + ((param_no) << 5))
 
-static const void __iomem *edmacc_regs_base = 
IO_ADDRESS(DAVINCI_DMA_3PCC_BASE);
+#define edmacc_regs_base       IO_ADDRESS(DAVINCI_DMA_3PCC_BASE)
 
 /*****************************************************************************/
 
@@ -277,12 +277,11 @@ queue_priority_mapping[DAVINCI_EDMA_NUM_
 
 static void map_dmach_queue(int ch_no, int queue_no)
 {
+       int bit = (ch_no & 0x7) * 4;
+
        queue_no &= 7;
-       if (ch_no < DAVINCI_EDMA_NUM_DMACH) {
-               int bit = (ch_no & 0x7) * 4;
-               edma_modify_array(EDMA_DMAQNUM, (ch_no >> 3),
-                               ~(0x7 << bit), queue_no << bit);
-       }
+       edma_modify_array(EDMA_DMAQNUM, (ch_no >> 3),
+                       ~(0x7 << bit), queue_no << bit);
 }
 
 static void __init map_queue_tc(int queue_no, int tc_no)
@@ -632,6 +631,7 @@ int davinci_request_dma(int dev_id, cons
                        int *tcc, enum dma_event_q eventq_no)
 {
        int tcc_val = tcc ? *tcc : TCC_ANY;
+       struct edmacc_param param = { .opt = 0, };
 
        /* REVISIT:  tcc would be better as a non-pointer parameter */
        switch (tcc_val) {
@@ -703,20 +703,16 @@ alloc_master:
                return -EINVAL;
        }
 
-       /* Optionally fire Transfer Complete interrupts.
-        *
-        * REVISIT: probably worth zeroing the whole PaRAM
-        * structure, so other flag values (like ITCINTEN
-        * and chaining options) are defined...
-        */
+       /* Optionally fire Transfer Complete interrupts */
        if (tcc_val != TCC_ANY)
-               edma_parm_modify(PARM_OPT, dev_id, ~TCC,
-                       ((0x3f & tcc_val) << 12) | TCINTEN);
-       else
-               edma_parm_and(PARM_OPT, dev_id, ~TCINTEN);
+               param.opt = ((0x3f & tcc_val) << 12) | TCINTEN;
 
        /* init the link field to no link. i.e 0xffff */
-       edma_parm_or(PARM_LINK_BCNTRLD, dev_id, 0xffff);
+       param.link_bcntrld = 0xffff;
+
+       /* init channel with a dummy PaRAM set */
+       param.ccnt = 1;
+       memcpy_toio(edmacc_regs_base + PARM_OFFSET(dev_id), &param, PARM_SIZE);
 
        /* non-status return values */
        *lch = dev_id;
@@ -912,52 +908,34 @@ EXPORT_SYMBOL(davinci_set_dma_transfer_p
 /**
  * davinci_set_dma_params - write PaRAM data for channel
  * @lch: logical channel being configured
- * @temp: channel configuration to be used
+ * @param: channel configuration to be used
  *
  * Use this to assign all parameters of a transfer at once.  This
  * allows more efficient setup of transfers than issuing multiple
  * calls to set up those parameters in small pieces, and provides
  * complete control over all transfer options.
  */
-void davinci_set_dma_params(int lch, struct edmacc_param *temp)
+void davinci_set_dma_params(int lch, struct edmacc_param *param)
 {
-       if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
-               int j = lch;
-
-               edma_parm_write(PARM_OPT, j, temp->opt);
-               edma_parm_write(PARM_SRC, j, temp->src);
-               edma_parm_write(PARM_A_B_CNT, j, temp->a_b_cnt);
-               edma_parm_write(PARM_DST, j, temp->dst);
-               edma_parm_write(PARM_SRC_DST_BIDX, j, temp->src_dst_bidx);
-               edma_parm_write(PARM_LINK_BCNTRLD, j, temp->link_bcntrld);
-               edma_parm_write(PARM_SRC_DST_CIDX, j, temp->src_dst_cidx);
-               edma_parm_write(PARM_CCNT, j, temp->ccnt);
-       }
+       if (lch < 0 || lch >= DAVINCI_EDMA_NUM_PARAMENTRY)
+               return;
+       memcpy_toio(edmacc_regs_base + PARM_OFFSET(lch), param, PARM_SIZE);
 }
 EXPORT_SYMBOL(davinci_set_dma_params);
 
 /**
  * davinci_get_dma_params - read PaRAM data for channel
  * @lch: logical channel being queried
- * @temp: where to store current channel configuration
+ * @param: where to store current channel configuration
  *
  * Use this to read the Parameter RAM for a channel, perhaps to
  * save them as a template for later reuse.
  */
-void davinci_get_dma_params(int lch, struct edmacc_param *temp)
+void davinci_get_dma_params(int lch, struct edmacc_param *param)
 {
-       if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
-               int j = lch;
-
-               temp->opt = edma_parm_read(PARM_OPT, j);
-               temp->src = edma_parm_read(PARM_SRC, j);
-               temp->a_b_cnt = edma_parm_read(PARM_A_B_CNT, j);
-               temp->dst = edma_parm_read(PARM_DST, j);
-               temp->src_dst_bidx = edma_parm_read(PARM_SRC_DST_BIDX, j);
-               temp->link_bcntrld = edma_parm_read(PARM_LINK_BCNTRLD, j);
-               temp->src_dst_cidx = edma_parm_read(PARM_SRC_DST_CIDX, j);
-               temp->ccnt = edma_parm_read(PARM_CCNT, j);
-       }
+       if (lch < 0 || lch >= DAVINCI_EDMA_NUM_PARAMENTRY)
+               return;
+       memcpy_fromio(param, edmacc_regs_base + PARM_OFFSET(lch), PARM_SIZE);
 }
 EXPORT_SYMBOL(davinci_get_dma_params);
 
@@ -1024,21 +1002,10 @@ void davinci_stop_dma(int lch)
                unsigned int mask = (1 << (lch & 0x1f));
 
                edma_shadow0_write_array(SH_EECR, j, mask);
-               if (edma_shadow0_read_array(SH_ER, j) & mask) {
-                       dev_dbg(&edma_dev.dev, "ER%d %08x\n", j,
-                               edma_shadow0_read_array(SH_ER, j));
-                       edma_shadow0_write_array(SH_ECR, j, mask);
-               }
-               if (edma_shadow0_read_array(SH_SER, j) & mask) {
-                       dev_dbg(&edma_dev.dev, "SER%d %08x\n", j,
-                               edma_shadow0_read_array(SH_SER, j));
-                       edma_shadow0_write_array(SH_SECR, j, mask);
-               }
-               if (edma_read_array(EDMA_EMR, j) & mask) {
-                       dev_dbg(&edma_dev.dev, "EMR%d %08x\n", j,
-                               edma_read_array(EDMA_EMR, j));
-                       edma_write_array(EDMA_EMCR, j, mask);
-               }
+               edma_shadow0_write_array(SH_ECR, j, mask);
+               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,
                                edma_shadow0_read_array(SH_EER, j));
                /*

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

Reply via email to