.. | .. |
---|
| 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"); |
---|