Commit a09820043c9e11149145a1ec221eed4a7b42dcce

Authored by Andy Shevchenko
Committed by Vinod Koul
1 parent 4a63a8b3e8

dw_dmac: autoconfigure data_width or get it via platform data

Not all of the controllers support the 64 bit data width. Make it configurable
via platform data. The driver will try to get a value from the component
parameters, otherwise it will use the platform data.

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@linux.intel.com>

Showing 5 changed files with 56 additions and 6 deletions Side-by-side Diff

arch/arm/mach-spear13xx/spear13xx.c
... ... @@ -79,6 +79,8 @@
79 79 .chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
80 80 .chan_priority = CHAN_PRIORITY_DESCENDING,
81 81 .block_size = 4095U,
  82 + .nr_masters = 2,
  83 + .data_width = { 3, 3, 0, 0 },
82 84 };
83 85  
84 86 void __init spear13xx_l2x0_init(void)
arch/avr32/mach-at32ap/at32ap700x.c
... ... @@ -606,6 +606,8 @@
606 606 static struct dw_dma_platform_data dw_dmac0_data = {
607 607 .nr_channels = 3,
608 608 .block_size = 4095U,
  609 + .nr_masters = 2,
  610 + .data_width = { 2, 2, 0, 0 },
609 611 };
610 612  
611 613 static struct resource dw_dmac0_resource[] = {
drivers/dma/dw_dmac.c
... ... @@ -36,12 +36,22 @@
36 36 * which does not support descriptor writeback.
37 37 */
38 38  
  39 +static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
  40 +{
  41 + return slave ? slave->dst_master : 0;
  42 +}
  43 +
  44 +static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
  45 +{
  46 + return slave ? slave->src_master : 1;
  47 +}
  48 +
39 49 #define DWC_DEFAULT_CTLLO(_chan) ({ \
40 50 struct dw_dma_slave *__slave = (_chan->private); \
41 51 struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \
42 52 struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \
43   - int _dms = __slave ? __slave->dst_master : 0; \
44   - int _sms = __slave ? __slave->src_master : 1; \
  53 + int _dms = dwc_get_dms(__slave); \
  54 + int _sms = dwc_get_sms(__slave); \
45 55 u8 _smsize = __slave ? _sconfig->src_maxburst : \
46 56 DW_DMA_MSIZE_16; \
47 57 u8 _dmsize = __slave ? _sconfig->dst_maxburst : \
... ... @@ -631,6 +641,7 @@
631 641 size_t len, unsigned long flags)
632 642 {
633 643 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
  644 + struct dw_dma_slave *dws = chan->private;
634 645 struct dw_desc *desc;
635 646 struct dw_desc *first;
636 647 struct dw_desc *prev;
637 648  
... ... @@ -650,8 +661,12 @@
650 661 return NULL;
651 662 }
652 663  
653   - src_width = dst_width = dwc_fast_fls(src | dest | len);
  664 + src_width = min_t(unsigned int, dwc->dw->data_width[dwc_get_sms(dws)],
  665 + dwc_fast_fls(src | len));
654 666  
  667 + dst_width = min_t(unsigned int, dwc->dw->data_width[dwc_get_dms(dws)],
  668 + dwc_fast_fls(dest | len));
  669 +
655 670 ctllo = DWC_DEFAULT_CTLLO(chan)
656 671 | DWC_CTLL_DST_WIDTH(dst_width)
657 672 | DWC_CTLL_SRC_WIDTH(src_width)
... ... @@ -720,6 +735,7 @@
720 735 dma_addr_t reg;
721 736 unsigned int reg_width;
722 737 unsigned int mem_width;
  738 + unsigned int data_width;
723 739 unsigned int i;
724 740 struct scatterlist *sg;
725 741 size_t total_len = 0;
... ... @@ -743,6 +759,8 @@
743 759 ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
744 760 DWC_CTLL_FC(DW_DMA_FC_D_M2P);
745 761  
  762 + data_width = dwc->dw->data_width[dwc_get_sms(dws)];
  763 +
746 764 for_each_sg(sgl, sg, sg_len, i) {
747 765 struct dw_desc *desc;
748 766 u32 len, dlen, mem;
... ... @@ -750,7 +768,8 @@
750 768 mem = sg_dma_address(sg);
751 769 len = sg_dma_len(sg);
752 770  
753   - mem_width = dwc_fast_fls(mem | len);
  771 + mem_width = min_t(unsigned int,
  772 + data_width, dwc_fast_fls(mem | len));
754 773  
755 774 slave_sg_todev_fill_desc:
756 775 desc = dwc_desc_get(dwc);
... ... @@ -803,6 +822,8 @@
803 822 ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
804 823 DWC_CTLL_FC(DW_DMA_FC_D_P2M);
805 824  
  825 + data_width = dwc->dw->data_width[dwc_get_dms(dws)];
  826 +
806 827 for_each_sg(sgl, sg, sg_len, i) {
807 828 struct dw_desc *desc;
808 829 u32 len, dlen, mem;
... ... @@ -810,7 +831,8 @@
810 831 mem = sg_dma_address(sg);
811 832 len = sg_dma_len(sg);
812 833  
813   - mem_width = dwc_fast_fls(mem | len);
  834 + mem_width = min_t(unsigned int,
  835 + data_width, dwc_fast_fls(mem | len));
814 836  
815 837 slave_sg_fromdev_fill_desc:
816 838 desc = dwc_desc_get(dwc);
817 839  
... ... @@ -1415,9 +1437,19 @@
1415 1437 dw->regs = regs;
1416 1438  
1417 1439 /* get hardware configuration parameters */
1418   - if (autocfg)
  1440 + if (autocfg) {
1419 1441 max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
1420 1442  
  1443 + dw->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
  1444 + for (i = 0; i < dw->nr_masters; i++) {
  1445 + dw->data_width[i] =
  1446 + (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
  1447 + }
  1448 + } else {
  1449 + dw->nr_masters = pdata->nr_masters;
  1450 + memcpy(dw->data_width, pdata->data_width, 4);
  1451 + }
  1452 +
1421 1453 /* Calculate all channel mask before DMA setup */
1422 1454 dw->all_chan_mask = (1 << nr_channels) - 1;
1423 1455  
... ... @@ -1463,6 +1495,8 @@
1463 1495 INIT_LIST_HEAD(&dwc->free_list);
1464 1496  
1465 1497 channel_clear_bit(dw, CH_EN, dwc->mask);
  1498 +
  1499 + dwc->dw = dw;
1466 1500  
1467 1501 /* hardware configuration */
1468 1502 if (autocfg)
drivers/dma/dw_dmac_regs.h
... ... @@ -198,6 +198,9 @@
198 198  
199 199 /* configuration passed via DMA_SLAVE_CONFIG */
200 200 struct dma_slave_config dma_sconfig;
  201 +
  202 + /* backlink to dw_dma */
  203 + struct dw_dma *dw;
201 204 };
202 205  
203 206 static inline struct dw_dma_chan_regs __iomem *
... ... @@ -223,6 +226,10 @@
223 226 struct clk *clk;
224 227  
225 228 u8 all_chan_mask;
  229 +
  230 + /* hardware configuration */
  231 + unsigned char nr_masters;
  232 + unsigned char data_width[4];
226 233  
227 234 struct dw_dma_chan chan[0];
228 235 };
include/linux/dw_dmac.h
... ... @@ -20,6 +20,9 @@
20 20 * @is_private: The device channels should be marked as private and not for
21 21 * by the general purpose DMA channel allocator.
22 22 * @block_size: Maximum block size supported by the controller
  23 + * @nr_masters: Number of AHB masters supported by the controller
  24 + * @data_width: Maximum data width supported by hardware per AHB master
  25 + * (0 - 8bits, 1 - 16bits, ..., 5 - 256bits)
23 26 */
24 27 struct dw_dma_platform_data {
25 28 unsigned int nr_channels;
... ... @@ -31,6 +34,8 @@
31 34 #define CHAN_PRIORITY_DESCENDING 1 /* chan7 highest */
32 35 unsigned char chan_priority;
33 36 unsigned short block_size;
  37 + unsigned char nr_masters;
  38 + unsigned char data_width[4];
34 39 };
35 40  
36 41 /* bursts size */