| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Core driver for the Synopsys DesignWare DMA Controller |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2007-2008 Atmel Corporation |
|---|
| 5 | 6 | * Copyright (C) 2010-2011 ST Microelectronics |
|---|
| 6 | 7 | * Copyright (C) 2013 Intel Corporation |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 10 | | - * published by the Free Software Foundation. |
|---|
| 11 | 8 | */ |
|---|
| 12 | 9 | |
|---|
| 13 | 10 | #include <linux/bitops.h> |
|---|
| .. | .. |
|---|
| 36 | 33 | * The driver has been tested with the Atmel AT32AP7000, which does not |
|---|
| 37 | 34 | * support descriptor writeback. |
|---|
| 38 | 35 | */ |
|---|
| 39 | | - |
|---|
| 40 | | -#define DWC_DEFAULT_CTLLO(_chan) ({ \ |
|---|
| 41 | | - struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \ |
|---|
| 42 | | - struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \ |
|---|
| 43 | | - bool _is_slave = is_slave_direction(_dwc->direction); \ |
|---|
| 44 | | - u8 _smsize = _is_slave ? _sconfig->src_maxburst : \ |
|---|
| 45 | | - DW_DMA_MSIZE_16; \ |
|---|
| 46 | | - u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \ |
|---|
| 47 | | - DW_DMA_MSIZE_16; \ |
|---|
| 48 | | - u8 _dms = (_dwc->direction == DMA_MEM_TO_DEV) ? \ |
|---|
| 49 | | - _dwc->dws.p_master : _dwc->dws.m_master; \ |
|---|
| 50 | | - u8 _sms = (_dwc->direction == DMA_DEV_TO_MEM) ? \ |
|---|
| 51 | | - _dwc->dws.p_master : _dwc->dws.m_master; \ |
|---|
| 52 | | - \ |
|---|
| 53 | | - (DWC_CTLL_DST_MSIZE(_dmsize) \ |
|---|
| 54 | | - | DWC_CTLL_SRC_MSIZE(_smsize) \ |
|---|
| 55 | | - | DWC_CTLL_LLP_D_EN \ |
|---|
| 56 | | - | DWC_CTLL_LLP_S_EN \ |
|---|
| 57 | | - | DWC_CTLL_DMS(_dms) \ |
|---|
| 58 | | - | DWC_CTLL_SMS(_sms)); \ |
|---|
| 59 | | - }) |
|---|
| 60 | 36 | |
|---|
| 61 | 37 | /* The set of bus widths supported by the DMA controller */ |
|---|
| 62 | 38 | #define DW_DMA_BUSWIDTHS \ |
|---|
| .. | .. |
|---|
| 138 | 114 | dwc->descs_allocated--; |
|---|
| 139 | 115 | } |
|---|
| 140 | 116 | |
|---|
| 141 | | -static void dwc_initialize_chan_idma32(struct dw_dma_chan *dwc) |
|---|
| 142 | | -{ |
|---|
| 143 | | - u32 cfghi = 0; |
|---|
| 144 | | - u32 cfglo = 0; |
|---|
| 145 | | - |
|---|
| 146 | | - /* Set default burst alignment */ |
|---|
| 147 | | - cfglo |= IDMA32C_CFGL_DST_BURST_ALIGN | IDMA32C_CFGL_SRC_BURST_ALIGN; |
|---|
| 148 | | - |
|---|
| 149 | | - /* Low 4 bits of the request lines */ |
|---|
| 150 | | - cfghi |= IDMA32C_CFGH_DST_PER(dwc->dws.dst_id & 0xf); |
|---|
| 151 | | - cfghi |= IDMA32C_CFGH_SRC_PER(dwc->dws.src_id & 0xf); |
|---|
| 152 | | - |
|---|
| 153 | | - /* Request line extension (2 bits) */ |
|---|
| 154 | | - cfghi |= IDMA32C_CFGH_DST_PER_EXT(dwc->dws.dst_id >> 4 & 0x3); |
|---|
| 155 | | - cfghi |= IDMA32C_CFGH_SRC_PER_EXT(dwc->dws.src_id >> 4 & 0x3); |
|---|
| 156 | | - |
|---|
| 157 | | - channel_writel(dwc, CFG_LO, cfglo); |
|---|
| 158 | | - channel_writel(dwc, CFG_HI, cfghi); |
|---|
| 159 | | -} |
|---|
| 160 | | - |
|---|
| 161 | | -static void dwc_initialize_chan_dw(struct dw_dma_chan *dwc) |
|---|
| 162 | | -{ |
|---|
| 163 | | - struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
|---|
| 164 | | - u32 cfghi = DWC_CFGH_FIFO_MODE; |
|---|
| 165 | | - u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority); |
|---|
| 166 | | - bool hs_polarity = dwc->dws.hs_polarity; |
|---|
| 167 | | - |
|---|
| 168 | | - cfghi |= DWC_CFGH_DST_PER(dwc->dws.dst_id); |
|---|
| 169 | | - cfghi |= DWC_CFGH_SRC_PER(dwc->dws.src_id); |
|---|
| 170 | | - cfghi |= DWC_CFGH_PROTCTL(dw->pdata->protctl); |
|---|
| 171 | | - |
|---|
| 172 | | - /* Set polarity of handshake interface */ |
|---|
| 173 | | - cfglo |= hs_polarity ? DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL : 0; |
|---|
| 174 | | - |
|---|
| 175 | | - channel_writel(dwc, CFG_LO, cfglo); |
|---|
| 176 | | - channel_writel(dwc, CFG_HI, cfghi); |
|---|
| 177 | | -} |
|---|
| 178 | | - |
|---|
| 179 | 117 | static void dwc_initialize(struct dw_dma_chan *dwc) |
|---|
| 180 | 118 | { |
|---|
| 181 | 119 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
|---|
| 182 | 120 | |
|---|
| 183 | | - if (test_bit(DW_DMA_IS_INITIALIZED, &dwc->flags)) |
|---|
| 184 | | - return; |
|---|
| 185 | | - |
|---|
| 186 | | - if (dw->pdata->is_idma32) |
|---|
| 187 | | - dwc_initialize_chan_idma32(dwc); |
|---|
| 188 | | - else |
|---|
| 189 | | - dwc_initialize_chan_dw(dwc); |
|---|
| 121 | + dw->initialize_chan(dwc); |
|---|
| 190 | 122 | |
|---|
| 191 | 123 | /* Enable interrupts */ |
|---|
| 192 | 124 | channel_set_bit(dw, MASK.XFER, dwc->mask); |
|---|
| 193 | 125 | channel_set_bit(dw, MASK.ERROR, dwc->mask); |
|---|
| 194 | | - |
|---|
| 195 | | - set_bit(DW_DMA_IS_INITIALIZED, &dwc->flags); |
|---|
| 196 | 126 | } |
|---|
| 197 | 127 | |
|---|
| 198 | 128 | /*----------------------------------------------------------------------*/ |
|---|
| .. | .. |
|---|
| 213 | 143 | channel_clear_bit(dw, CH_EN, dwc->mask); |
|---|
| 214 | 144 | while (dma_readl(dw, CH_EN) & dwc->mask) |
|---|
| 215 | 145 | cpu_relax(); |
|---|
| 216 | | -} |
|---|
| 217 | | - |
|---|
| 218 | | -static u32 bytes2block(struct dw_dma_chan *dwc, size_t bytes, |
|---|
| 219 | | - unsigned int width, size_t *len) |
|---|
| 220 | | -{ |
|---|
| 221 | | - struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
|---|
| 222 | | - u32 block; |
|---|
| 223 | | - |
|---|
| 224 | | - /* Always in bytes for iDMA 32-bit */ |
|---|
| 225 | | - if (dw->pdata->is_idma32) |
|---|
| 226 | | - width = 0; |
|---|
| 227 | | - |
|---|
| 228 | | - if ((bytes >> width) > dwc->block_size) { |
|---|
| 229 | | - block = dwc->block_size; |
|---|
| 230 | | - *len = block << width; |
|---|
| 231 | | - } else { |
|---|
| 232 | | - block = bytes >> width; |
|---|
| 233 | | - *len = bytes; |
|---|
| 234 | | - } |
|---|
| 235 | | - |
|---|
| 236 | | - return block; |
|---|
| 237 | | -} |
|---|
| 238 | | - |
|---|
| 239 | | -static size_t block2bytes(struct dw_dma_chan *dwc, u32 block, u32 width) |
|---|
| 240 | | -{ |
|---|
| 241 | | - struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
|---|
| 242 | | - |
|---|
| 243 | | - if (dw->pdata->is_idma32) |
|---|
| 244 | | - return IDMA32C_CTLH_BLOCK_TS(block); |
|---|
| 245 | | - |
|---|
| 246 | | - return DWC_CTLH_BLOCK_TS(block) << width; |
|---|
| 247 | 146 | } |
|---|
| 248 | 147 | |
|---|
| 249 | 148 | /*----------------------------------------------------------------------*/ |
|---|
| .. | .. |
|---|
| 391 | 290 | /* Returns how many bytes were already received from source */ |
|---|
| 392 | 291 | static inline u32 dwc_get_sent(struct dw_dma_chan *dwc) |
|---|
| 393 | 292 | { |
|---|
| 293 | + struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
|---|
| 394 | 294 | u32 ctlhi = channel_readl(dwc, CTL_HI); |
|---|
| 395 | 295 | u32 ctllo = channel_readl(dwc, CTL_LO); |
|---|
| 396 | 296 | |
|---|
| 397 | | - return block2bytes(dwc, ctlhi, ctllo >> 4 & 7); |
|---|
| 297 | + return dw->block2bytes(dwc, ctlhi, ctllo >> 4 & 7); |
|---|
| 398 | 298 | } |
|---|
| 399 | 299 | |
|---|
| 400 | 300 | static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) |
|---|
| .. | .. |
|---|
| 563 | 463 | dwc_descriptor_complete(dwc, bad_desc, true); |
|---|
| 564 | 464 | } |
|---|
| 565 | 465 | |
|---|
| 566 | | -static void dw_dma_tasklet(unsigned long data) |
|---|
| 466 | +static void dw_dma_tasklet(struct tasklet_struct *t) |
|---|
| 567 | 467 | { |
|---|
| 568 | | - struct dw_dma *dw = (struct dw_dma *)data; |
|---|
| 468 | + struct dw_dma *dw = from_tasklet(dw, t, tasklet); |
|---|
| 569 | 469 | struct dw_dma_chan *dwc; |
|---|
| 570 | 470 | u32 status_xfer; |
|---|
| 571 | 471 | u32 status_err; |
|---|
| .. | .. |
|---|
| 651 | 551 | unsigned int src_width; |
|---|
| 652 | 552 | unsigned int dst_width; |
|---|
| 653 | 553 | unsigned int data_width = dw->pdata->data_width[m_master]; |
|---|
| 654 | | - u32 ctllo; |
|---|
| 554 | + u32 ctllo, ctlhi; |
|---|
| 655 | 555 | u8 lms = DWC_LLP_LMS(m_master); |
|---|
| 656 | 556 | |
|---|
| 657 | 557 | dev_vdbg(chan2dev(chan), |
|---|
| .. | .. |
|---|
| 667 | 567 | |
|---|
| 668 | 568 | src_width = dst_width = __ffs(data_width | src | dest | len); |
|---|
| 669 | 569 | |
|---|
| 670 | | - ctllo = DWC_DEFAULT_CTLLO(chan) |
|---|
| 570 | + ctllo = dw->prepare_ctllo(dwc) |
|---|
| 671 | 571 | | DWC_CTLL_DST_WIDTH(dst_width) |
|---|
| 672 | 572 | | DWC_CTLL_SRC_WIDTH(src_width) |
|---|
| 673 | 573 | | DWC_CTLL_DST_INC |
|---|
| .. | .. |
|---|
| 680 | 580 | if (!desc) |
|---|
| 681 | 581 | goto err_desc_get; |
|---|
| 682 | 582 | |
|---|
| 583 | + ctlhi = dw->bytes2block(dwc, len - offset, src_width, &xfer_count); |
|---|
| 584 | + |
|---|
| 683 | 585 | lli_write(desc, sar, src + offset); |
|---|
| 684 | 586 | lli_write(desc, dar, dest + offset); |
|---|
| 685 | 587 | lli_write(desc, ctllo, ctllo); |
|---|
| 686 | | - lli_write(desc, ctlhi, bytes2block(dwc, len - offset, src_width, &xfer_count)); |
|---|
| 588 | + lli_write(desc, ctlhi, ctlhi); |
|---|
| 687 | 589 | desc->len = xfer_count; |
|---|
| 688 | 590 | |
|---|
| 689 | 591 | if (!first) { |
|---|
| .. | .. |
|---|
| 721 | 623 | struct dma_slave_config *sconfig = &dwc->dma_sconfig; |
|---|
| 722 | 624 | struct dw_desc *prev; |
|---|
| 723 | 625 | struct dw_desc *first; |
|---|
| 724 | | - u32 ctllo; |
|---|
| 626 | + u32 ctllo, ctlhi; |
|---|
| 725 | 627 | u8 m_master = dwc->dws.m_master; |
|---|
| 726 | 628 | u8 lms = DWC_LLP_LMS(m_master); |
|---|
| 727 | 629 | dma_addr_t reg; |
|---|
| .. | .. |
|---|
| 745 | 647 | case DMA_MEM_TO_DEV: |
|---|
| 746 | 648 | reg_width = __ffs(sconfig->dst_addr_width); |
|---|
| 747 | 649 | reg = sconfig->dst_addr; |
|---|
| 748 | | - ctllo = (DWC_DEFAULT_CTLLO(chan) |
|---|
| 650 | + ctllo = dw->prepare_ctllo(dwc) |
|---|
| 749 | 651 | | DWC_CTLL_DST_WIDTH(reg_width) |
|---|
| 750 | 652 | | DWC_CTLL_DST_FIX |
|---|
| 751 | | - | DWC_CTLL_SRC_INC); |
|---|
| 653 | + | DWC_CTLL_SRC_INC; |
|---|
| 752 | 654 | |
|---|
| 753 | 655 | ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) : |
|---|
| 754 | 656 | DWC_CTLL_FC(DW_DMA_FC_D_M2P); |
|---|
| .. | .. |
|---|
| 768 | 670 | if (!desc) |
|---|
| 769 | 671 | goto err_desc_get; |
|---|
| 770 | 672 | |
|---|
| 673 | + ctlhi = dw->bytes2block(dwc, len, mem_width, &dlen); |
|---|
| 674 | + |
|---|
| 771 | 675 | lli_write(desc, sar, mem); |
|---|
| 772 | 676 | lli_write(desc, dar, reg); |
|---|
| 773 | | - lli_write(desc, ctlhi, bytes2block(dwc, len, mem_width, &dlen)); |
|---|
| 677 | + lli_write(desc, ctlhi, ctlhi); |
|---|
| 774 | 678 | lli_write(desc, ctllo, ctllo | DWC_CTLL_SRC_WIDTH(mem_width)); |
|---|
| 775 | 679 | desc->len = dlen; |
|---|
| 776 | 680 | |
|---|
| .. | .. |
|---|
| 793 | 697 | case DMA_DEV_TO_MEM: |
|---|
| 794 | 698 | reg_width = __ffs(sconfig->src_addr_width); |
|---|
| 795 | 699 | reg = sconfig->src_addr; |
|---|
| 796 | | - ctllo = (DWC_DEFAULT_CTLLO(chan) |
|---|
| 700 | + ctllo = dw->prepare_ctllo(dwc) |
|---|
| 797 | 701 | | DWC_CTLL_SRC_WIDTH(reg_width) |
|---|
| 798 | 702 | | DWC_CTLL_DST_INC |
|---|
| 799 | | - | DWC_CTLL_SRC_FIX); |
|---|
| 703 | + | DWC_CTLL_SRC_FIX; |
|---|
| 800 | 704 | |
|---|
| 801 | 705 | ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) : |
|---|
| 802 | 706 | DWC_CTLL_FC(DW_DMA_FC_D_P2M); |
|---|
| .. | .. |
|---|
| 814 | 718 | if (!desc) |
|---|
| 815 | 719 | goto err_desc_get; |
|---|
| 816 | 720 | |
|---|
| 721 | + ctlhi = dw->bytes2block(dwc, len, reg_width, &dlen); |
|---|
| 722 | + |
|---|
| 817 | 723 | lli_write(desc, sar, reg); |
|---|
| 818 | 724 | lli_write(desc, dar, mem); |
|---|
| 819 | | - lli_write(desc, ctlhi, bytes2block(dwc, len, reg_width, &dlen)); |
|---|
| 820 | | - mem_width = __ffs(data_width | mem | dlen); |
|---|
| 725 | + lli_write(desc, ctlhi, ctlhi); |
|---|
| 726 | + mem_width = __ffs(data_width | mem); |
|---|
| 821 | 727 | lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width)); |
|---|
| 822 | 728 | desc->len = dlen; |
|---|
| 823 | 729 | |
|---|
| .. | .. |
|---|
| 866 | 772 | if (dws->dma_dev != chan->device->dev) |
|---|
| 867 | 773 | return false; |
|---|
| 868 | 774 | |
|---|
| 775 | + /* permit channels in accordance with the channels mask */ |
|---|
| 776 | + if (dws->channels && !(dws->channels & dwc->mask)) |
|---|
| 777 | + return false; |
|---|
| 778 | + |
|---|
| 869 | 779 | /* We have to copy data since dws can be temporary storage */ |
|---|
| 870 | 780 | memcpy(&dwc->dws, dws, sizeof(struct dw_dma_slave)); |
|---|
| 871 | 781 | |
|---|
| .. | .. |
|---|
| 876 | 786 | static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig) |
|---|
| 877 | 787 | { |
|---|
| 878 | 788 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
|---|
| 879 | | - struct dma_slave_config *sc = &dwc->dma_sconfig; |
|---|
| 880 | 789 | struct dw_dma *dw = to_dw_dma(chan->device); |
|---|
| 881 | | - /* |
|---|
| 882 | | - * Fix sconfig's burst size according to dw_dmac. We need to convert |
|---|
| 883 | | - * them as: |
|---|
| 884 | | - * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3. |
|---|
| 885 | | - * |
|---|
| 886 | | - * NOTE: burst size 2 is not supported by DesignWare controller. |
|---|
| 887 | | - * iDMA 32-bit supports it. |
|---|
| 888 | | - */ |
|---|
| 889 | | - u32 s = dw->pdata->is_idma32 ? 1 : 2; |
|---|
| 890 | | - |
|---|
| 891 | | - /* Check if chan will be configured for slave transfers */ |
|---|
| 892 | | - if (!is_slave_direction(sconfig->direction)) |
|---|
| 893 | | - return -EINVAL; |
|---|
| 894 | 790 | |
|---|
| 895 | 791 | memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); |
|---|
| 896 | | - dwc->direction = sconfig->direction; |
|---|
| 897 | 792 | |
|---|
| 898 | | - sc->src_maxburst = sc->src_maxburst > 1 ? fls(sc->src_maxburst) - s : 0; |
|---|
| 899 | | - sc->dst_maxburst = sc->dst_maxburst > 1 ? fls(sc->dst_maxburst) - s : 0; |
|---|
| 793 | + dwc->dma_sconfig.src_maxburst = |
|---|
| 794 | + clamp(dwc->dma_sconfig.src_maxburst, 0U, dwc->max_burst); |
|---|
| 795 | + dwc->dma_sconfig.dst_maxburst = |
|---|
| 796 | + clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst); |
|---|
| 797 | + |
|---|
| 798 | + dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst); |
|---|
| 799 | + dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst); |
|---|
| 900 | 800 | |
|---|
| 901 | 801 | return 0; |
|---|
| 902 | 802 | } |
|---|
| .. | .. |
|---|
| 905 | 805 | { |
|---|
| 906 | 806 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
|---|
| 907 | 807 | unsigned int count = 20; /* timeout iterations */ |
|---|
| 908 | | - u32 cfglo; |
|---|
| 909 | 808 | |
|---|
| 910 | | - cfglo = channel_readl(dwc, CFG_LO); |
|---|
| 911 | | - if (dw->pdata->is_idma32) { |
|---|
| 912 | | - if (drain) |
|---|
| 913 | | - cfglo |= IDMA32C_CFGL_CH_DRAIN; |
|---|
| 914 | | - else |
|---|
| 915 | | - cfglo &= ~IDMA32C_CFGL_CH_DRAIN; |
|---|
| 916 | | - } |
|---|
| 917 | | - channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP); |
|---|
| 809 | + dw->suspend_chan(dwc, drain); |
|---|
| 810 | + |
|---|
| 918 | 811 | while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY) && count--) |
|---|
| 919 | 812 | udelay(2); |
|---|
| 920 | 813 | |
|---|
| .. | .. |
|---|
| 933 | 826 | return 0; |
|---|
| 934 | 827 | } |
|---|
| 935 | 828 | |
|---|
| 936 | | -static inline void dwc_chan_resume(struct dw_dma_chan *dwc) |
|---|
| 829 | +static inline void dwc_chan_resume(struct dw_dma_chan *dwc, bool drain) |
|---|
| 937 | 830 | { |
|---|
| 938 | | - u32 cfglo = channel_readl(dwc, CFG_LO); |
|---|
| 831 | + struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
|---|
| 939 | 832 | |
|---|
| 940 | | - channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP); |
|---|
| 833 | + dw->resume_chan(dwc, drain); |
|---|
| 941 | 834 | |
|---|
| 942 | 835 | clear_bit(DW_DMA_IS_PAUSED, &dwc->flags); |
|---|
| 943 | 836 | } |
|---|
| .. | .. |
|---|
| 950 | 843 | spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 951 | 844 | |
|---|
| 952 | 845 | if (test_bit(DW_DMA_IS_PAUSED, &dwc->flags)) |
|---|
| 953 | | - dwc_chan_resume(dwc); |
|---|
| 846 | + dwc_chan_resume(dwc, false); |
|---|
| 954 | 847 | |
|---|
| 955 | 848 | spin_unlock_irqrestore(&dwc->lock, flags); |
|---|
| 956 | 849 | |
|---|
| .. | .. |
|---|
| 973 | 866 | |
|---|
| 974 | 867 | dwc_chan_disable(dw, dwc); |
|---|
| 975 | 868 | |
|---|
| 976 | | - dwc_chan_resume(dwc); |
|---|
| 869 | + dwc_chan_resume(dwc, true); |
|---|
| 977 | 870 | |
|---|
| 978 | 871 | /* active_list entries will end up before queued entries */ |
|---|
| 979 | 872 | list_splice_init(&dwc->queue, &list); |
|---|
| .. | .. |
|---|
| 1063 | 956 | |
|---|
| 1064 | 957 | /*----------------------------------------------------------------------*/ |
|---|
| 1065 | 958 | |
|---|
| 1066 | | -/* |
|---|
| 1067 | | - * Program FIFO size of channels. |
|---|
| 1068 | | - * |
|---|
| 1069 | | - * By default full FIFO (512 bytes) is assigned to channel 0. Here we |
|---|
| 1070 | | - * slice FIFO on equal parts between channels. |
|---|
| 1071 | | - */ |
|---|
| 1072 | | -static void idma32_fifo_partition(struct dw_dma *dw) |
|---|
| 959 | +void do_dw_dma_off(struct dw_dma *dw) |
|---|
| 1073 | 960 | { |
|---|
| 1074 | | - u64 value = IDMA32C_FP_PSIZE_CH0(64) | IDMA32C_FP_PSIZE_CH1(64) | |
|---|
| 1075 | | - IDMA32C_FP_UPDATE; |
|---|
| 1076 | | - u64 fifo_partition = 0; |
|---|
| 1077 | | - |
|---|
| 1078 | | - if (!dw->pdata->is_idma32) |
|---|
| 1079 | | - return; |
|---|
| 1080 | | - |
|---|
| 1081 | | - /* Fill FIFO_PARTITION low bits (Channels 0..1, 4..5) */ |
|---|
| 1082 | | - fifo_partition |= value << 0; |
|---|
| 1083 | | - |
|---|
| 1084 | | - /* Fill FIFO_PARTITION high bits (Channels 2..3, 6..7) */ |
|---|
| 1085 | | - fifo_partition |= value << 32; |
|---|
| 1086 | | - |
|---|
| 1087 | | - /* Program FIFO Partition registers - 64 bytes per channel */ |
|---|
| 1088 | | - idma32_writeq(dw, FIFO_PARTITION1, fifo_partition); |
|---|
| 1089 | | - idma32_writeq(dw, FIFO_PARTITION0, fifo_partition); |
|---|
| 1090 | | -} |
|---|
| 1091 | | - |
|---|
| 1092 | | -static void dw_dma_off(struct dw_dma *dw) |
|---|
| 1093 | | -{ |
|---|
| 1094 | | - unsigned int i; |
|---|
| 1095 | | - |
|---|
| 1096 | 961 | dma_writel(dw, CFG, 0); |
|---|
| 1097 | 962 | |
|---|
| 1098 | 963 | channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask); |
|---|
| .. | .. |
|---|
| 1103 | 968 | |
|---|
| 1104 | 969 | while (dma_readl(dw, CFG) & DW_CFG_DMA_EN) |
|---|
| 1105 | 970 | cpu_relax(); |
|---|
| 1106 | | - |
|---|
| 1107 | | - for (i = 0; i < dw->dma.chancnt; i++) |
|---|
| 1108 | | - clear_bit(DW_DMA_IS_INITIALIZED, &dw->chan[i].flags); |
|---|
| 1109 | 971 | } |
|---|
| 1110 | 972 | |
|---|
| 1111 | | -static void dw_dma_on(struct dw_dma *dw) |
|---|
| 973 | +void do_dw_dma_on(struct dw_dma *dw) |
|---|
| 1112 | 974 | { |
|---|
| 1113 | 975 | dma_writel(dw, CFG, DW_CFG_DMA_EN); |
|---|
| 1114 | 976 | } |
|---|
| .. | .. |
|---|
| 1144 | 1006 | |
|---|
| 1145 | 1007 | /* Enable controller here if needed */ |
|---|
| 1146 | 1008 | if (!dw->in_use) |
|---|
| 1147 | | - dw_dma_on(dw); |
|---|
| 1009 | + do_dw_dma_on(dw); |
|---|
| 1148 | 1010 | dw->in_use |= dwc->mask; |
|---|
| 1149 | 1011 | |
|---|
| 1150 | 1012 | return 0; |
|---|
| .. | .. |
|---|
| 1155 | 1017 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
|---|
| 1156 | 1018 | struct dw_dma *dw = to_dw_dma(chan->device); |
|---|
| 1157 | 1019 | unsigned long flags; |
|---|
| 1158 | | - LIST_HEAD(list); |
|---|
| 1159 | 1020 | |
|---|
| 1160 | 1021 | dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__, |
|---|
| 1161 | 1022 | dwc->descs_allocated); |
|---|
| .. | .. |
|---|
| 1170 | 1031 | /* Clear custom channel configuration */ |
|---|
| 1171 | 1032 | memset(&dwc->dws, 0, sizeof(struct dw_dma_slave)); |
|---|
| 1172 | 1033 | |
|---|
| 1173 | | - clear_bit(DW_DMA_IS_INITIALIZED, &dwc->flags); |
|---|
| 1174 | | - |
|---|
| 1175 | 1034 | /* Disable interrupts */ |
|---|
| 1176 | 1035 | channel_clear_bit(dw, MASK.XFER, dwc->mask); |
|---|
| 1177 | 1036 | channel_clear_bit(dw, MASK.BLOCK, dwc->mask); |
|---|
| .. | .. |
|---|
| 1182 | 1041 | /* Disable controller in case it was a last user */ |
|---|
| 1183 | 1042 | dw->in_use &= ~dwc->mask; |
|---|
| 1184 | 1043 | if (!dw->in_use) |
|---|
| 1185 | | - dw_dma_off(dw); |
|---|
| 1044 | + do_dw_dma_off(dw); |
|---|
| 1186 | 1045 | |
|---|
| 1187 | 1046 | dev_vdbg(chan2dev(chan), "%s: done\n", __func__); |
|---|
| 1188 | 1047 | } |
|---|
| 1189 | 1048 | |
|---|
| 1190 | | -int dw_dma_probe(struct dw_dma_chip *chip) |
|---|
| 1049 | +static void dwc_caps(struct dma_chan *chan, struct dma_slave_caps *caps) |
|---|
| 1191 | 1050 | { |
|---|
| 1051 | + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
|---|
| 1052 | + |
|---|
| 1053 | + caps->max_burst = dwc->max_burst; |
|---|
| 1054 | + |
|---|
| 1055 | + /* |
|---|
| 1056 | + * It might be crucial for some devices to have the hardware |
|---|
| 1057 | + * accelerated multi-block transfers supported, aka LLPs in DW DMAC |
|---|
| 1058 | + * notation. So if LLPs are supported then max_sg_burst is set to |
|---|
| 1059 | + * zero which means unlimited number of SG entries can be handled in a |
|---|
| 1060 | + * single DMA transaction, otherwise it's just one SG entry. |
|---|
| 1061 | + */ |
|---|
| 1062 | + if (dwc->nollp) |
|---|
| 1063 | + caps->max_sg_burst = 1; |
|---|
| 1064 | + else |
|---|
| 1065 | + caps->max_sg_burst = 0; |
|---|
| 1066 | +} |
|---|
| 1067 | + |
|---|
| 1068 | +int do_dma_probe(struct dw_dma_chip *chip) |
|---|
| 1069 | +{ |
|---|
| 1070 | + struct dw_dma *dw = chip->dw; |
|---|
| 1192 | 1071 | struct dw_dma_platform_data *pdata; |
|---|
| 1193 | | - struct dw_dma *dw; |
|---|
| 1194 | 1072 | bool autocfg = false; |
|---|
| 1195 | 1073 | unsigned int dw_params; |
|---|
| 1196 | 1074 | unsigned int i; |
|---|
| 1197 | 1075 | int err; |
|---|
| 1198 | | - |
|---|
| 1199 | | - dw = devm_kzalloc(chip->dev, sizeof(*dw), GFP_KERNEL); |
|---|
| 1200 | | - if (!dw) |
|---|
| 1201 | | - return -ENOMEM; |
|---|
| 1202 | 1076 | |
|---|
| 1203 | 1077 | dw->pdata = devm_kzalloc(chip->dev, sizeof(*dw->pdata), GFP_KERNEL); |
|---|
| 1204 | 1078 | if (!dw->pdata) |
|---|
| 1205 | 1079 | return -ENOMEM; |
|---|
| 1206 | 1080 | |
|---|
| 1207 | 1081 | dw->regs = chip->regs; |
|---|
| 1208 | | - chip->dw = dw; |
|---|
| 1209 | 1082 | |
|---|
| 1210 | 1083 | pm_runtime_get_sync(chip->dev); |
|---|
| 1211 | 1084 | |
|---|
| .. | .. |
|---|
| 1232 | 1105 | pdata->block_size = dma_readl(dw, MAX_BLK_SIZE); |
|---|
| 1233 | 1106 | |
|---|
| 1234 | 1107 | /* Fill platform data with the default values */ |
|---|
| 1235 | | - pdata->is_private = true; |
|---|
| 1236 | | - pdata->is_memcpy = true; |
|---|
| 1237 | 1108 | pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING; |
|---|
| 1238 | 1109 | pdata->chan_priority = CHAN_PRIORITY_ASCENDING; |
|---|
| 1239 | 1110 | } else if (chip->pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS) { |
|---|
| .. | .. |
|---|
| 1257 | 1128 | dw->all_chan_mask = (1 << pdata->nr_channels) - 1; |
|---|
| 1258 | 1129 | |
|---|
| 1259 | 1130 | /* Force dma off, just in case */ |
|---|
| 1260 | | - dw_dma_off(dw); |
|---|
| 1261 | | - |
|---|
| 1262 | | - idma32_fifo_partition(dw); |
|---|
| 1131 | + dw->disable(dw); |
|---|
| 1263 | 1132 | |
|---|
| 1264 | 1133 | /* Device and instance ID for IRQ and DMA pool */ |
|---|
| 1265 | | - if (pdata->is_idma32) |
|---|
| 1266 | | - snprintf(dw->name, sizeof(dw->name), "idma32:dmac%d", chip->id); |
|---|
| 1267 | | - else |
|---|
| 1268 | | - snprintf(dw->name, sizeof(dw->name), "dw:dmac%d", chip->id); |
|---|
| 1134 | + dw->set_device_name(dw, chip->id); |
|---|
| 1269 | 1135 | |
|---|
| 1270 | 1136 | /* Create a pool of consistent memory blocks for hardware descriptors */ |
|---|
| 1271 | 1137 | dw->desc_pool = dmam_pool_create(dw->name, chip->dev, |
|---|
| .. | .. |
|---|
| 1276 | 1142 | goto err_pdata; |
|---|
| 1277 | 1143 | } |
|---|
| 1278 | 1144 | |
|---|
| 1279 | | - tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw); |
|---|
| 1145 | + tasklet_setup(&dw->tasklet, dw_dma_tasklet); |
|---|
| 1280 | 1146 | |
|---|
| 1281 | 1147 | err = request_irq(chip->irq, dw_dma_interrupt, IRQF_SHARED, |
|---|
| 1282 | 1148 | dw->name, dw); |
|---|
| .. | .. |
|---|
| 1328 | 1194 | */ |
|---|
| 1329 | 1195 | dwc->block_size = |
|---|
| 1330 | 1196 | (4 << ((pdata->block_size >> 4 * i) & 0xf)) - 1; |
|---|
| 1197 | + |
|---|
| 1198 | + /* |
|---|
| 1199 | + * According to the DW DMA databook the true scatter- |
|---|
| 1200 | + * gether LLPs aren't available if either multi-block |
|---|
| 1201 | + * config is disabled (CHx_MULTI_BLK_EN == 0) or the |
|---|
| 1202 | + * LLP register is hard-coded to zeros |
|---|
| 1203 | + * (CHx_HC_LLP == 1). |
|---|
| 1204 | + */ |
|---|
| 1331 | 1205 | dwc->nollp = |
|---|
| 1332 | | - (dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0; |
|---|
| 1206 | + (dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0 || |
|---|
| 1207 | + (dwc_params >> DWC_PARAMS_HC_LLP & 0x1) == 1; |
|---|
| 1208 | + dwc->max_burst = |
|---|
| 1209 | + (0x4 << (dwc_params >> DWC_PARAMS_MSIZE & 0x7)); |
|---|
| 1333 | 1210 | } else { |
|---|
| 1334 | 1211 | dwc->block_size = pdata->block_size; |
|---|
| 1335 | 1212 | dwc->nollp = !pdata->multi_block[i]; |
|---|
| 1213 | + dwc->max_burst = pdata->max_burst[i] ?: DW_DMA_MAX_BURST; |
|---|
| 1336 | 1214 | } |
|---|
| 1337 | 1215 | } |
|---|
| 1338 | 1216 | |
|---|
| .. | .. |
|---|
| 1345 | 1223 | |
|---|
| 1346 | 1224 | /* Set capabilities */ |
|---|
| 1347 | 1225 | dma_cap_set(DMA_SLAVE, dw->dma.cap_mask); |
|---|
| 1348 | | - if (pdata->is_private) |
|---|
| 1349 | | - dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask); |
|---|
| 1350 | | - if (pdata->is_memcpy) |
|---|
| 1351 | | - dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask); |
|---|
| 1226 | + dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask); |
|---|
| 1227 | + dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask); |
|---|
| 1352 | 1228 | |
|---|
| 1353 | 1229 | dw->dma.dev = chip->dev; |
|---|
| 1354 | 1230 | dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources; |
|---|
| .. | .. |
|---|
| 1357 | 1233 | dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy; |
|---|
| 1358 | 1234 | dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; |
|---|
| 1359 | 1235 | |
|---|
| 1236 | + dw->dma.device_caps = dwc_caps; |
|---|
| 1360 | 1237 | dw->dma.device_config = dwc_config; |
|---|
| 1361 | 1238 | dw->dma.device_pause = dwc_pause; |
|---|
| 1362 | 1239 | dw->dma.device_resume = dwc_resume; |
|---|
| .. | .. |
|---|
| 1366 | 1243 | dw->dma.device_issue_pending = dwc_issue_pending; |
|---|
| 1367 | 1244 | |
|---|
| 1368 | 1245 | /* DMA capabilities */ |
|---|
| 1246 | + dw->dma.min_burst = DW_DMA_MIN_BURST; |
|---|
| 1247 | + dw->dma.max_burst = DW_DMA_MAX_BURST; |
|---|
| 1369 | 1248 | dw->dma.src_addr_widths = DW_DMA_BUSWIDTHS; |
|---|
| 1370 | 1249 | dw->dma.dst_addr_widths = DW_DMA_BUSWIDTHS; |
|---|
| 1371 | 1250 | dw->dma.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) | |
|---|
| 1372 | 1251 | BIT(DMA_MEM_TO_MEM); |
|---|
| 1373 | 1252 | dw->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; |
|---|
| 1253 | + |
|---|
| 1254 | + /* |
|---|
| 1255 | + * For now there is no hardware with non uniform maximum block size |
|---|
| 1256 | + * across all of the device channels, so we set the maximum segment |
|---|
| 1257 | + * size as the block size found for the very first channel. |
|---|
| 1258 | + */ |
|---|
| 1259 | + dma_set_max_seg_size(dw->dma.dev, dw->chan[0].block_size); |
|---|
| 1374 | 1260 | |
|---|
| 1375 | 1261 | err = dma_async_device_register(&dw->dma); |
|---|
| 1376 | 1262 | if (err) |
|---|
| .. | .. |
|---|
| 1389 | 1275 | pm_runtime_put_sync_suspend(chip->dev); |
|---|
| 1390 | 1276 | return err; |
|---|
| 1391 | 1277 | } |
|---|
| 1392 | | -EXPORT_SYMBOL_GPL(dw_dma_probe); |
|---|
| 1393 | 1278 | |
|---|
| 1394 | | -int dw_dma_remove(struct dw_dma_chip *chip) |
|---|
| 1279 | +int do_dma_remove(struct dw_dma_chip *chip) |
|---|
| 1395 | 1280 | { |
|---|
| 1396 | 1281 | struct dw_dma *dw = chip->dw; |
|---|
| 1397 | 1282 | struct dw_dma_chan *dwc, *_dwc; |
|---|
| 1398 | 1283 | |
|---|
| 1399 | 1284 | pm_runtime_get_sync(chip->dev); |
|---|
| 1400 | 1285 | |
|---|
| 1401 | | - dw_dma_off(dw); |
|---|
| 1286 | + do_dw_dma_off(dw); |
|---|
| 1402 | 1287 | dma_async_device_unregister(&dw->dma); |
|---|
| 1403 | 1288 | |
|---|
| 1404 | 1289 | free_irq(chip->irq, dw); |
|---|
| .. | .. |
|---|
| 1413 | 1298 | pm_runtime_put_sync_suspend(chip->dev); |
|---|
| 1414 | 1299 | return 0; |
|---|
| 1415 | 1300 | } |
|---|
| 1416 | | -EXPORT_SYMBOL_GPL(dw_dma_remove); |
|---|
| 1417 | 1301 | |
|---|
| 1418 | | -int dw_dma_disable(struct dw_dma_chip *chip) |
|---|
| 1302 | +int do_dw_dma_disable(struct dw_dma_chip *chip) |
|---|
| 1419 | 1303 | { |
|---|
| 1420 | 1304 | struct dw_dma *dw = chip->dw; |
|---|
| 1421 | 1305 | |
|---|
| 1422 | | - dw_dma_off(dw); |
|---|
| 1306 | + dw->disable(dw); |
|---|
| 1423 | 1307 | return 0; |
|---|
| 1424 | 1308 | } |
|---|
| 1425 | | -EXPORT_SYMBOL_GPL(dw_dma_disable); |
|---|
| 1309 | +EXPORT_SYMBOL_GPL(do_dw_dma_disable); |
|---|
| 1426 | 1310 | |
|---|
| 1427 | | -int dw_dma_enable(struct dw_dma_chip *chip) |
|---|
| 1311 | +int do_dw_dma_enable(struct dw_dma_chip *chip) |
|---|
| 1428 | 1312 | { |
|---|
| 1429 | 1313 | struct dw_dma *dw = chip->dw; |
|---|
| 1430 | 1314 | |
|---|
| 1431 | | - idma32_fifo_partition(dw); |
|---|
| 1432 | | - |
|---|
| 1433 | | - dw_dma_on(dw); |
|---|
| 1315 | + dw->enable(dw); |
|---|
| 1434 | 1316 | return 0; |
|---|
| 1435 | 1317 | } |
|---|
| 1436 | | -EXPORT_SYMBOL_GPL(dw_dma_enable); |
|---|
| 1318 | +EXPORT_SYMBOL_GPL(do_dw_dma_enable); |
|---|
| 1437 | 1319 | |
|---|
| 1438 | 1320 | MODULE_LICENSE("GPL v2"); |
|---|
| 1439 | 1321 | MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller core driver"); |
|---|