Merge tag 'davinci-for-v3.16/edma' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorOlof Johansson <olof@lixom.net>
Mon, 26 May 2014 21:59:05 +0000 (14:59 -0700)
committerOlof Johansson <olof@lixom.net>
Mon, 26 May 2014 21:59:05 +0000 (14:59 -0700)
Merge "DaVinci EDMA clean-up for v3.16" from Sekhar Nori:

This series makes edma use configuration information available within
the IP instead of reading it from platform data or DT. Some other useful
clean-ups are included too.

* tag 'davinci-for-v3.16/edma' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci: (34 commits)
  ARM: edma: Remove redundant/unused parameters from edma_soc_info
  ARM: davinci: Remove redundant/unused parameters for edma
  ARM: dts: am4372: Remove obsolete properties from edma node
  ARM: dts: am33xx: Remove obsolete properties from edma node
  dt/bindings: ti,edma: Remove redundant properties from documentation
  ARM: edma: Get IP configuration from HW (number of channels, tc, etc)
  ARM: edma: Save number of regions from pdata to struct edma
  ARM: edma: Remove num_cc member from struct edma
  ARM: edma: Remove queue_tc_mapping data from edma_soc_info
  ARM: davinci: Remove eDMA3 queue_tc_mapping data from edma_soc_info
  ARM: edma: Do not change TC -> Queue mapping, leave it to default.
  ARM: edma: Take the number of tc from edma_soc_info (pdata)
  ARM: edma: No need to clean the pdata in edma_of_parse_dt()
  ARM: edma: Clean up and simplify the code around irq request
  dmaengine: edma: update DMA memcpy to use new param element
  dmaengine: edma: Document variables used for residue accounting
  dmaengine: edma: Provide granular accounting
  dmaengine: edma: Make reading the position of active channels work
  dmaengine: edma: Store transfer data in edma_desc and edma_pset
  dmaengine: edma: Create private pset struct
  ...

Signed-off-by: Olof Johansson <olof@lixom.net>
1  2 
Documentation/devicetree/bindings/dma/ti-edma.txt
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am4372.dtsi
arch/arm/common/edma.c

@@@ -26,9 -30,6 +30,6 @@@ edma: edma@49000000 
        compatible = "ti,edma3";
        ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
        #dma-cells = <1>;
-       dma-channels = <64>;
-       ti,edma-regions = <4>;
-       ti,edma-slots = <256>;
 -      ti,edma-xbar-event-map = <1 12
 -                                2 13>;
 +      ti,edma-xbar-event-map = /bits/ 16 <1 12
 +                                          2 13>;
  };
                        compatible = "ti,edma3";
                        ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
                        reg =   <0x49000000 0x10000>,
 -                              <0x44e10f90 0x10>;
 +                              <0x44e10f90 0x40>;
                        interrupts = <12 13 14>;
                        #dma-cells = <1>;
-                       dma-channels = <64>;
-                       ti,edma-regions = <4>;
-                       ti,edma-slots = <256>;
                };
  
                gpio0: gpio@44e07000 {
Simple merge
@@@ -1421,20 -1414,99 +1414,81 @@@ void edma_clear_event(unsigned channel
  }
  EXPORT_SYMBOL(edma_clear_event);
  
+ static int edma_setup_from_hw(struct device *dev, struct edma_soc_info *pdata,
+                             struct edma *edma_cc)
+ {
+       int i;
+       u32 value, cccfg;
+       s8 (*queue_priority_map)[2];
+       /* Decode the eDMA3 configuration from CCCFG register */
+       cccfg = edma_read(0, EDMA_CCCFG);
+       value = GET_NUM_REGN(cccfg);
+       edma_cc->num_region = BIT(value);
+       value = GET_NUM_DMACH(cccfg);
+       edma_cc->num_channels = BIT(value + 1);
+       value = GET_NUM_PAENTRY(cccfg);
+       edma_cc->num_slots = BIT(value + 4);
+       value = GET_NUM_EVQUE(cccfg);
+       edma_cc->num_tc = value + 1;
+       dev_dbg(dev, "eDMA3 HW configuration (cccfg: 0x%08x):\n", cccfg);
+       dev_dbg(dev, "num_region: %u\n", edma_cc->num_region);
+       dev_dbg(dev, "num_channel: %u\n", edma_cc->num_channels);
+       dev_dbg(dev, "num_slot: %u\n", edma_cc->num_slots);
+       dev_dbg(dev, "num_tc: %u\n", edma_cc->num_tc);
+       /* Nothing need to be done if queue priority is provided */
+       if (pdata->queue_priority_mapping)
+               return 0;
+       /*
+        * Configure TC/queue priority as follows:
+        * Q0 - priority 0
+        * Q1 - priority 1
+        * Q2 - priority 2
+        * ...
+        * The meaning of priority numbers: 0 highest priority, 7 lowest
+        * priority. So Q0 is the highest priority queue and the last queue has
+        * the lowest priority.
+        */
+       queue_priority_map = devm_kzalloc(dev,
+                                         (edma_cc->num_tc + 1) * sizeof(s8),
+                                         GFP_KERNEL);
+       if (!queue_priority_map)
+               return -ENOMEM;
+       for (i = 0; i < edma_cc->num_tc; i++) {
+               queue_priority_map[i][0] = i;
+               queue_priority_map[i][1] = i;
+       }
+       queue_priority_map[i][0] = -1;
+       queue_priority_map[i][1] = -1;
+       pdata->queue_priority_mapping = queue_priority_map;
+       pdata->default_queue = 0;
+       return 0;
+ }
  #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DMADEVICES)
  
 -static int edma_of_read_u32_to_s16_array(const struct device_node *np,
 -                                       const char *propname, s16 *out_values,
 -                                       size_t sz)
 +static int edma_xbar_event_map(struct device *dev, struct device_node *node,
 +                             struct edma_soc_info *pdata, size_t sz)
  {
 -      int ret;
 -
 -      ret = of_property_read_u16_array(np, propname, out_values, sz);
 -      if (ret)
 -              return ret;
 -
 -      /* Terminate it */
 -      *out_values++ = -1;
 -      *out_values++ = -1;
 -
 -      return 0;
 -}
 -
 -static int edma_xbar_event_map(struct device *dev,
 -                             struct device_node *node,
 -                             struct edma_soc_info *pdata, int len)
 -{
 -      int ret, i;
 +      const char pname[] = "ti,edma-xbar-event-map";
        struct resource res;
        void __iomem *xbar;
 -      const s16 (*xbar_chans)[2];
 +      s16 (*xbar_chans)[2];
 +      size_t nelm = sz / sizeof(s16);
        u32 shift, offset, mux;
 +      int ret, i;
  
 -      xbar_chans = devm_kzalloc(dev,
 -                                len/sizeof(s16) + 2*sizeof(s16),
 -                                GFP_KERNEL);
 +      xbar_chans = devm_kzalloc(dev, (nelm + 2) * sizeof(s16), GFP_KERNEL);
        if (!xbar_chans)
                return -ENOMEM;