dmaengine: dw: revisit data_width property
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Wed, 27 Apr 2016 11:15:38 +0000 (14:15 +0300)
committerVinod Koul <vinod.koul@intel.com>
Mon, 2 May 2016 10:00:47 +0000 (15:30 +0530)
There several changes are done here:

- Convert the property to be in bytes

  Besides that this is a common practice for such property, the use of a value
  in bytes much more convenient than handling the encoded one.

- Rename data_width to data-width in the device tree bindings

  The change leaves the support for the old format as well just in case someone
  will use a newer kernel with an old device tree blob.

- While here, replace dwc_fast_ffs() by __ffs()

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Documentation/devicetree/bindings/dma/snps-dma.txt
arch/arc/boot/dts/abilis_tb10x.dtsi
arch/arm/boot/dts/spear13xx.dtsi
drivers/dma/dw/core.c
drivers/dma/dw/platform.c
include/linux/platform_data/dma-dw.h

index c99c1ffac199d3f0faad9ba97c7b24be4efb183f..0f5583293c9caba6b8758d28e68a26ecffec2fbd 100644 (file)
@@ -13,6 +13,11 @@ Required properties:
 - chan_priority: priority of channels. 0 (default): increase from chan 0->n, 1:
   increase from chan n->0
 - block_size: Maximum block size supported by the controller
+- data-width: Maximum data width supported by hardware per AHB master
+  (in bytes, power of 2)
+
+
+Deprecated properties:
 - data_width: Maximum data width supported by hardware per AHB master
   (0 - 8bits, 1 - 16bits, ..., 5 - 256bits)
 
@@ -38,7 +43,7 @@ Example:
                chan_allocation_order = <1>;
                chan_priority = <1>;
                block_size = <0xfff>;
-               data_width = <3 3>;
+               data-width = <8 8>;
        };
 
 DMA clients connected to the Designware DMA controller must use the format
index cfb5052239a1cffdcb3f8ac3dc07537441d55bef..2f53bedb0cdee4b2aae2b5e9cf2cf00027c7deef 100644 (file)
                        chan_allocation_order = <0>;
                        chan_priority = <1>;
                        block_size = <0x7ff>;
-                       data_width = <2>;
+                       data-width = <4>;
                        clocks = <&ahb_clk>;
                        clock-names = "hclk";
                };
index 14594ce8c18a5a889bbb0fb1fd0c02d7161638c3..449acf0d82721c057b9383b5996b56f17af96179 100644 (file)
                        chan_priority = <1>;
                        block_size = <0xfff>;
                        dma-masters = <2>;
-                       data_width = <3 3>;
+                       data-width = <8 8>;
                };
 
                dma@eb000000 {
                        chan_allocation_order = <1>;
                        chan_priority = <1>;
                        block_size = <0xfff>;
-                       data_width = <3 3>;
+                       data-width = <8 8>;
                };
 
                fsmc: flash@b0000000 {
index 78522dcf3a7d730c98df73d148cd4b81adfd9405..992da255b8e657c0ad4238e0ec8d6d53ee6bfecc 100644 (file)
@@ -162,21 +162,6 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
 
 /*----------------------------------------------------------------------*/
 
-static inline unsigned int dwc_fast_ffs(unsigned long long v)
-{
-       /*
-        * We can be a lot more clever here, but this should take care
-        * of the most common optimization.
-        */
-       if (!(v & 7))
-               return 3;
-       else if (!(v & 3))
-               return 2;
-       else if (!(v & 1))
-               return 1;
-       return 0;
-}
-
 static inline void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
 {
        dev_err(chan2dev(&dwc->chan),
@@ -677,11 +662,12 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
        struct dw_desc          *prev;
        size_t                  xfer_count;
        size_t                  offset;
+       u8                      m_master = dwc->m_master;
        unsigned int            src_width;
        unsigned int            dst_width;
-       unsigned int            data_width;
+       unsigned int            data_width = dw->data_width[m_master];
        u32                     ctllo;
-       u8                      lms = DWC_LLP_LMS(dwc->m_master);
+       u8                      lms = DWC_LLP_LMS(m_master);
 
        dev_vdbg(chan2dev(chan),
                        "%s: d%pad s%pad l0x%zx f0x%lx\n", __func__,
@@ -694,10 +680,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 
        dwc->direction = DMA_MEM_TO_MEM;
 
-       data_width = dw->data_width[dwc->m_master];
-
-       src_width = dst_width = min_t(unsigned int, data_width,
-                                     dwc_fast_ffs(src | dest | len));
+       src_width = dst_width = __ffs(data_width | src | dest | len);
 
        ctllo = DWC_DEFAULT_CTLLO(chan)
                        | DWC_CTLL_DST_WIDTH(dst_width)
@@ -757,11 +740,12 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
        struct dw_desc          *prev;
        struct dw_desc          *first;
        u32                     ctllo;
-       u8                      lms = DWC_LLP_LMS(dwc->m_master);
+       u8                      m_master = dwc->m_master;
+       u8                      lms = DWC_LLP_LMS(m_master);
        dma_addr_t              reg;
        unsigned int            reg_width;
        unsigned int            mem_width;
-       unsigned int            data_width;
+       unsigned int            data_width = dw->data_width[m_master];
        unsigned int            i;
        struct scatterlist      *sg;
        size_t                  total_len = 0;
@@ -787,8 +771,6 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
                        DWC_CTLL_FC(DW_DMA_FC_D_M2P);
 
-               data_width = dw->data_width[dwc->m_master];
-
                for_each_sg(sgl, sg, sg_len, i) {
                        struct dw_desc  *desc;
                        u32             len, dlen, mem;
@@ -796,8 +778,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                        mem = sg_dma_address(sg);
                        len = sg_dma_len(sg);
 
-                       mem_width = min_t(unsigned int,
-                                         data_width, dwc_fast_ffs(mem | len));
+                       mem_width = __ffs(data_width | mem | len);
 
 slave_sg_todev_fill_desc:
                        desc = dwc_desc_get(dwc);
@@ -843,8 +824,6 @@ slave_sg_todev_fill_desc:
                ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
                        DWC_CTLL_FC(DW_DMA_FC_D_P2M);
 
-               data_width = dw->data_width[dwc->m_master];
-
                for_each_sg(sgl, sg, sg_len, i) {
                        struct dw_desc  *desc;
                        u32             len, dlen, mem;
@@ -852,8 +831,7 @@ slave_sg_todev_fill_desc:
                        mem = sg_dma_address(sg);
                        len = sg_dma_len(sg);
 
-                       mem_width = min_t(unsigned int,
-                                         data_width, dwc_fast_ffs(mem | len));
+                       mem_width = __ffs(data_width | mem | len);
 
 slave_sg_fromdev_fill_desc:
                        desc = dwc_desc_get(dwc);
@@ -1500,7 +1478,7 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
                pdata->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
                for (i = 0; i < pdata->nr_masters; i++) {
                        pdata->data_width[i] =
-                               (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
+                               4 << (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3);
                }
                max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
 
index e65ebe5ab88f557278a8fafcfb184495f3eb2b0f..2420fb7267bc1832e3cef04cfc333a3a269f4d16 100644 (file)
@@ -138,9 +138,12 @@ dw_dma_parse_dt(struct platform_device *pdev)
        if (!of_property_read_u32(np, "block_size", &tmp))
                pdata->block_size = tmp;
 
-       if (!of_property_read_u32_array(np, "data_width", arr, nr_masters)) {
+       if (!of_property_read_u32_array(np, "data-width", arr, nr_masters)) {
                for (tmp = 0; tmp < nr_masters; tmp++)
                        pdata->data_width[tmp] = arr[tmp];
+       } else if (!of_property_read_u32_array(np, "data_width", arr, nr_masters)) {
+               for (tmp = 0; tmp < nr_masters; tmp++)
+                       pdata->data_width[tmp] = BIT(arr[tmp] & 0x07);
        }
 
        return pdata;
index b881b978e4866ba86a79a44aeecac5b7d91f5f02..ad768111c350e2cec3d218ca2f46e85202e2afd7 100644 (file)
@@ -43,7 +43,7 @@ struct dw_dma_slave {
  * @block_size: Maximum block size supported by the controller
  * @nr_masters: Number of AHB masters supported by the controller
  * @data_width: Maximum data width supported by hardware per AHB master
- *             (0 - 8bits, 1 - 16bits, ..., 5 - 256bits)
+ *             (in bytes, power of 2)
  */
 struct dw_dma_platform_data {
        unsigned int    nr_channels;