Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'dmaengine-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine

Pull dmaengine updates from Vinod Koul:
"New support:
- TI J721S2 CSI BCDMA support

Updates:
- Native HDMI support for dw edma driver
- ste dma40 updates for supporting proper SRAM handle in DT
- removal of dma device chancnt setting in drivers"

* tag 'dmaengine-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (28 commits)
dmaengine: sprd: Don't set chancnt
dmaengine: hidma: Don't set chancnt
dmaengine: plx_dma: Don't set chancnt
dmaengine: axi-dmac: Don't set chancnt
dmaengine: dw-axi-dmac: Don't set chancnt
dmaengine: qcom: bam_dma: allow omitting num-{channels,ees}
dmaengine: dw-edma: Add HDMA DebugFS support
dmaengine: dw-edma: Add support for native HDMA
dmaengine: dw-edma: Create a new dw_edma_core_ops structure to abstract controller operation
dmaengine: dw-edma: Rename dw_edma_core_ops structure to dw_edma_plat_ops
dmaengine: ste_dma40: use proper format string for resource_size_t
dmaengine: make QCOM_HIDMA depend on HAS_IOMEM
dmaengine: ste_dma40: fix typo in enum documentation
dmaengine: ste_dma40: use correct print specfier for resource_size_t
MAINTAINERS: Add myself as the DW eDMA driver reviewer
MAINTAINERS: Add Manivannan to DW eDMA driver maintainers list
MAINTAINERS: Demote Gustavo Pimentel to DW EDMA driver reviewer
dmaengine: ti: k3-udma: Add support for J721S2 CSI BCDMA instance
dt-bindings: dma: ti: Add J721S2 BCDMA
dmaengine: ti: k3-psil-j721s2: Add PSI-L thread map for main CPSW2G
...

+1074 -401
+28 -8
Documentation/devicetree/bindings/dma/stericsson,dma40.yaml
··· 112 112 - const: stericsson,dma40 113 113 114 114 reg: 115 - items: 116 - - description: DMA40 memory base 117 - - description: LCPA memory base 115 + oneOf: 116 + - items: 117 + - description: DMA40 memory base 118 + - items: 119 + - description: DMA40 memory base 120 + - description: LCPA memory base, deprecated, use eSRAM pool instead 121 + deprecated: true 122 + 118 123 119 124 reg-names: 120 - items: 121 - - const: base 122 - - const: lcpa 125 + oneOf: 126 + - items: 127 + - const: base 128 + - items: 129 + - const: base 130 + - const: lcpa 131 + deprecated: true 123 132 124 133 interrupts: 125 134 maxItems: 1 126 135 127 136 clocks: 128 137 maxItems: 1 138 + 139 + sram: 140 + $ref: /schemas/types.yaml#/definitions/phandle-array 141 + description: A phandle array with inner size 1 (no arg cells). 142 + First phandle is the LCPA (Logical Channel Parameter Address) memory. 143 + Second phandle is the LCLA (Logical Channel Link base Address) memory. 144 + maxItems: 2 145 + items: 146 + maxItems: 1 129 147 130 148 memcpy-channels: 131 149 $ref: /schemas/types.yaml#/definitions/uint32-array ··· 156 138 - reg 157 139 - interrupts 158 140 - clocks 141 + - sram 159 142 - memcpy-channels 160 143 161 144 additionalProperties: false ··· 168 149 #include <dt-bindings/mfd/dbx500-prcmu.h> 169 150 dma-controller@801c0000 { 170 151 compatible = "stericsson,db8500-dma40", "stericsson,dma40"; 171 - reg = <0x801c0000 0x1000>, <0x40010000 0x800>; 172 - reg-names = "base", "lcpa"; 152 + reg = <0x801c0000 0x1000>; 153 + reg-names = "base"; 154 + sram = <&lcpa>, <&lcla>; 173 155 interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; 174 156 #dma-cells = <3>; 175 157 memcpy-channels = <56 57 58 59 60>;
+29 -1
Documentation/devicetree/bindings/dma/ti/k3-bcdma.yaml
··· 33 33 enum: 34 34 - ti,am62a-dmss-bcdma-csirx 35 35 - ti,am64-dmss-bcdma 36 + - ti,j721s2-dmss-bcdma-csi 36 37 37 38 reg: 38 39 minItems: 3 ··· 152 151 required: 153 152 - power-domains 154 153 155 - else: 154 + - if: 155 + properties: 156 + compatible: 157 + contains: 158 + const: ti,am64-dmss-bcdma 159 + then: 156 160 properties: 157 161 reg: 158 162 minItems: 5 ··· 172 166 173 167 required: 174 168 - ti,sci-rm-range-bchan 169 + - ti,sci-rm-range-tchan 170 + 171 + - if: 172 + properties: 173 + compatible: 174 + contains: 175 + const: ti,j721s2-dmss-bcdma-csi 176 + then: 177 + properties: 178 + ti,sci-rm-range-bchan: false 179 + 180 + reg: 181 + maxItems: 4 182 + 183 + reg-names: 184 + items: 185 + - const: gcfg 186 + - const: rchanrt 187 + - const: tchanrt 188 + - const: ringrt 189 + 190 + required: 175 191 - ti,sci-rm-range-tchan 176 192 177 193 unevaluatedProperties: false
+6
Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dpdma.yaml
··· 41 41 clock-names: 42 42 const: axi_clk 43 43 44 + power-domains: 45 + maxItems: 1 46 + 44 47 required: 45 48 - "#dma-cells" 46 49 - compatible ··· 51 48 - interrupts 52 49 - clocks 53 50 - clock-names 51 + - power-domains 54 52 55 53 additionalProperties: false 56 54 57 55 examples: 58 56 - | 59 57 #include <dt-bindings/interrupt-controller/arm-gic.h> 58 + #include <dt-bindings/power/xlnx-zynqmp-power.h> 60 59 61 60 dma: dma-controller@fd4c0000 { 62 61 compatible = "xlnx,zynqmp-dpdma"; ··· 68 63 clocks = <&dpdma_clk>; 69 64 clock-names = "axi_clk"; 70 65 #dma-cells = <1>; 66 + power-domains = <&zynqmp_firmware PD_DP>; 71 67 }; 72 68 73 69 ...
+3 -1
MAINTAINERS
··· 5932 5932 F: drivers/mtd/nand/raw/denali* 5933 5933 5934 5934 DESIGNWARE EDMA CORE IP DRIVER 5935 - M: Gustavo Pimentel <gustavo.pimentel@synopsys.com> 5935 + M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 5936 + R: Gustavo Pimentel <gustavo.pimentel@synopsys.com> 5937 + R: Serge Semin <fancer.lancer@gmail.com> 5936 5938 L: dmaengine@vger.kernel.org 5937 5939 S: Maintained 5938 5940 F: drivers/dma/dw-edma/
+1
drivers/dma/Kconfig
··· 553 553 bool "ST-Ericsson DMA40 support" 554 554 depends on ARCH_U8500 555 555 select DMA_ENGINE 556 + select SRAM 556 557 help 557 558 Support for ST-Ericsson DMA40 controller 558 559
-1
drivers/dma/dma-axi-dmac.c
··· 963 963 dma_dev->device_terminate_all = axi_dmac_terminate_all; 964 964 dma_dev->device_synchronize = axi_dmac_synchronize; 965 965 dma_dev->dev = &pdev->dev; 966 - dma_dev->chancnt = 1; 967 966 dma_dev->src_addr_widths = BIT(dmac->chan.src_width); 968 967 dma_dev->dst_addr_widths = BIT(dmac->chan.dest_width); 969 968 dma_dev->directions = BIT(dmac->chan.direction);
-1
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
··· 1466 1466 dma_cap_set(DMA_CYCLIC, dw->dma.cap_mask); 1467 1467 1468 1468 /* DMA capabilities */ 1469 - dw->dma.chancnt = hdata->nr_channels; 1470 1469 dw->dma.max_burst = hdata->axi_rw_burst_len; 1471 1470 dw->dma.src_addr_widths = AXI_DMA_BUSWIDTHS; 1472 1471 dw->dma.dst_addr_widths = AXI_DMA_BUSWIDTHS;
+5 -3
drivers/dma/dw-edma/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 3 3 obj-$(CONFIG_DW_EDMA) += dw-edma.o 4 - dw-edma-$(CONFIG_DEBUG_FS) := dw-edma-v0-debugfs.o 5 - dw-edma-objs := dw-edma-core.o \ 6 - dw-edma-v0-core.o $(dw-edma-y) 4 + dw-edma-$(CONFIG_DEBUG_FS) := dw-edma-v0-debugfs.o \ 5 + dw-hdma-v0-debugfs.o 6 + dw-edma-objs := dw-edma-core.o \ 7 + dw-edma-v0-core.o \ 8 + dw-hdma-v0-core.o $(dw-edma-y) 7 9 obj-$(CONFIG_DW_EDMA_PCIE) += dw-edma-pcie.o
+30 -58
drivers/dma/dw-edma/dw-edma-core.c
··· 18 18 19 19 #include "dw-edma-core.h" 20 20 #include "dw-edma-v0-core.h" 21 + #include "dw-hdma-v0-core.h" 21 22 #include "../dmaengine.h" 22 23 #include "../virt-dma.h" 23 24 ··· 184 183 185 184 static int dw_edma_start_transfer(struct dw_edma_chan *chan) 186 185 { 186 + struct dw_edma *dw = chan->dw; 187 187 struct dw_edma_chunk *child; 188 188 struct dw_edma_desc *desc; 189 189 struct virt_dma_desc *vd; ··· 202 200 if (!child) 203 201 return 0; 204 202 205 - dw_edma_v0_core_start(child, !desc->xfer_sz); 203 + dw_edma_core_start(dw, child, !desc->xfer_sz); 206 204 desc->xfer_sz += child->ll_region.sz; 207 205 dw_edma_free_burst(child); 208 206 list_del(&child->list); ··· 289 287 chan->configured = false; 290 288 } else if (chan->status == EDMA_ST_IDLE) { 291 289 chan->configured = false; 292 - } else if (dw_edma_v0_core_ch_status(chan) == DMA_COMPLETE) { 290 + } else if (dw_edma_core_ch_status(chan) == DMA_COMPLETE) { 293 291 /* 294 292 * The channel is in a false BUSY state, probably didn't 295 293 * receive or lost an interrupt ··· 601 599 struct virt_dma_desc *vd; 602 600 unsigned long flags; 603 601 604 - dw_edma_v0_core_clear_done_int(chan); 605 - 606 602 spin_lock_irqsave(&chan->vc.lock, flags); 607 603 vd = vchan_next_desc(&chan->vc); 608 604 if (vd) { ··· 641 641 struct virt_dma_desc *vd; 642 642 unsigned long flags; 643 643 644 - dw_edma_v0_core_clear_abort_int(chan); 645 - 646 644 spin_lock_irqsave(&chan->vc.lock, flags); 647 645 vd = vchan_next_desc(&chan->vc); 648 646 if (vd) { ··· 652 654 chan->status = EDMA_ST_IDLE; 653 655 } 654 656 655 - static irqreturn_t dw_edma_interrupt(int irq, void *data, bool write) 656 - { 657 - struct dw_edma_irq *dw_irq = data; 658 - struct dw_edma *dw = dw_irq->dw; 659 - unsigned long total, pos, val; 660 - unsigned long off; 661 - u32 mask; 662 - 663 - if (write) { 664 - total = dw->wr_ch_cnt; 665 - off = 0; 666 - mask = dw_irq->wr_mask; 667 - } else { 668 - total = dw->rd_ch_cnt; 669 - off = dw->wr_ch_cnt; 670 - mask = dw_irq->rd_mask; 671 - } 672 - 673 - val = dw_edma_v0_core_status_done_int(dw, write ? 674 - EDMA_DIR_WRITE : 675 - EDMA_DIR_READ); 676 - val &= mask; 677 - for_each_set_bit(pos, &val, total) { 678 - struct dw_edma_chan *chan = &dw->chan[pos + off]; 679 - 680 - dw_edma_done_interrupt(chan); 681 - } 682 - 683 - val = dw_edma_v0_core_status_abort_int(dw, write ? 684 - EDMA_DIR_WRITE : 685 - EDMA_DIR_READ); 686 - val &= mask; 687 - for_each_set_bit(pos, &val, total) { 688 - struct dw_edma_chan *chan = &dw->chan[pos + off]; 689 - 690 - dw_edma_abort_interrupt(chan); 691 - } 692 - 693 - return IRQ_HANDLED; 694 - } 695 - 696 657 static inline irqreturn_t dw_edma_interrupt_write(int irq, void *data) 697 658 { 698 - return dw_edma_interrupt(irq, data, true); 659 + struct dw_edma_irq *dw_irq = data; 660 + 661 + return dw_edma_core_handle_int(dw_irq, EDMA_DIR_WRITE, 662 + dw_edma_done_interrupt, 663 + dw_edma_abort_interrupt); 699 664 } 700 665 701 666 static inline irqreturn_t dw_edma_interrupt_read(int irq, void *data) 702 667 { 703 - return dw_edma_interrupt(irq, data, false); 668 + struct dw_edma_irq *dw_irq = data; 669 + 670 + return dw_edma_core_handle_int(dw_irq, EDMA_DIR_READ, 671 + dw_edma_done_interrupt, 672 + dw_edma_abort_interrupt); 704 673 } 705 674 706 675 static irqreturn_t dw_edma_interrupt_common(int irq, void *data) 707 676 { 708 - dw_edma_interrupt(irq, data, true); 709 - dw_edma_interrupt(irq, data, false); 677 + irqreturn_t ret = IRQ_NONE; 710 678 711 - return IRQ_HANDLED; 679 + ret |= dw_edma_interrupt_write(irq, data); 680 + ret |= dw_edma_interrupt_read(irq, data); 681 + 682 + return ret; 712 683 } 713 684 714 685 static int dw_edma_alloc_chan_resources(struct dma_chan *dchan) ··· 778 811 779 812 vchan_init(&chan->vc, dma); 780 813 781 - dw_edma_v0_core_device_config(chan); 814 + dw_edma_core_ch_config(chan); 782 815 } 783 816 784 817 /* Set DMA channel capabilities */ ··· 923 956 924 957 dw->chip = chip; 925 958 959 + if (dw->chip->mf == EDMA_MF_HDMA_NATIVE) 960 + dw_hdma_v0_core_register(dw); 961 + else 962 + dw_edma_v0_core_register(dw); 963 + 926 964 raw_spin_lock_init(&dw->lock); 927 965 928 966 dw->wr_ch_cnt = min_t(u16, chip->ll_wr_cnt, 929 - dw_edma_v0_core_ch_count(dw, EDMA_DIR_WRITE)); 967 + dw_edma_core_ch_count(dw, EDMA_DIR_WRITE)); 930 968 dw->wr_ch_cnt = min_t(u16, dw->wr_ch_cnt, EDMA_MAX_WR_CH); 931 969 932 970 dw->rd_ch_cnt = min_t(u16, chip->ll_rd_cnt, 933 - dw_edma_v0_core_ch_count(dw, EDMA_DIR_READ)); 971 + dw_edma_core_ch_count(dw, EDMA_DIR_READ)); 934 972 dw->rd_ch_cnt = min_t(u16, dw->rd_ch_cnt, EDMA_MAX_RD_CH); 935 973 936 974 if (!dw->wr_ch_cnt && !dw->rd_ch_cnt) ··· 954 982 dev_name(chip->dev)); 955 983 956 984 /* Disable eDMA, only to establish the ideal initial conditions */ 957 - dw_edma_v0_core_off(dw); 985 + dw_edma_core_off(dw); 958 986 959 987 /* Request IRQs */ 960 988 err = dw_edma_irq_request(dw, &wr_alloc, &rd_alloc); ··· 967 995 goto err_irq_free; 968 996 969 997 /* Turn debugfs on */ 970 - dw_edma_v0_core_debugfs_on(dw); 998 + dw_edma_core_debugfs_on(dw); 971 999 972 1000 chip->dw = dw; 973 1001 ··· 993 1021 return -ENODEV; 994 1022 995 1023 /* Disable eDMA */ 996 - dw_edma_v0_core_off(dw); 1024 + dw_edma_core_off(dw); 997 1025 998 1026 /* Free irqs */ 999 1027 for (i = (dw->nr_irqs - 1); i >= 0; i--)
+58
drivers/dma/dw-edma/dw-edma-core.h
··· 111 111 raw_spinlock_t lock; /* Only for legacy */ 112 112 113 113 struct dw_edma_chip *chip; 114 + 115 + const struct dw_edma_core_ops *core; 116 + }; 117 + 118 + typedef void (*dw_edma_handler_t)(struct dw_edma_chan *); 119 + 120 + struct dw_edma_core_ops { 121 + void (*off)(struct dw_edma *dw); 122 + u16 (*ch_count)(struct dw_edma *dw, enum dw_edma_dir dir); 123 + enum dma_status (*ch_status)(struct dw_edma_chan *chan); 124 + irqreturn_t (*handle_int)(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, 125 + dw_edma_handler_t done, dw_edma_handler_t abort); 126 + void (*start)(struct dw_edma_chunk *chunk, bool first); 127 + void (*ch_config)(struct dw_edma_chan *chan); 128 + void (*debugfs_on)(struct dw_edma *dw); 114 129 }; 115 130 116 131 struct dw_edma_sg { ··· 161 146 struct dw_edma_chan *dchan2dw_edma_chan(struct dma_chan *dchan) 162 147 { 163 148 return vc2dw_edma_chan(to_virt_chan(dchan)); 149 + } 150 + 151 + static inline 152 + void dw_edma_core_off(struct dw_edma *dw) 153 + { 154 + dw->core->off(dw); 155 + } 156 + 157 + static inline 158 + u16 dw_edma_core_ch_count(struct dw_edma *dw, enum dw_edma_dir dir) 159 + { 160 + return dw->core->ch_count(dw, dir); 161 + } 162 + 163 + static inline 164 + enum dma_status dw_edma_core_ch_status(struct dw_edma_chan *chan) 165 + { 166 + return chan->dw->core->ch_status(chan); 167 + } 168 + 169 + static inline irqreturn_t 170 + dw_edma_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, 171 + dw_edma_handler_t done, dw_edma_handler_t abort) 172 + { 173 + return dw_irq->dw->core->handle_int(dw_irq, dir, done, abort); 174 + } 175 + 176 + static inline 177 + void dw_edma_core_start(struct dw_edma *dw, struct dw_edma_chunk *chunk, bool first) 178 + { 179 + dw->core->start(chunk, first); 180 + } 181 + 182 + static inline 183 + void dw_edma_core_ch_config(struct dw_edma_chan *chan) 184 + { 185 + chan->dw->core->ch_config(chan); 186 + } 187 + 188 + static inline 189 + void dw_edma_core_debugfs_on(struct dw_edma *dw) 190 + { 191 + dw->core->debugfs_on(dw); 164 192 } 165 193 166 194 #endif /* _DW_EDMA_CORE_H */
+2 -2
drivers/dma/dw-edma/dw-edma-pcie.c
··· 109 109 return region.start; 110 110 } 111 111 112 - static const struct dw_edma_core_ops dw_edma_pcie_core_ops = { 112 + static const struct dw_edma_plat_ops dw_edma_pcie_plat_ops = { 113 113 .irq_vector = dw_edma_pcie_irq_vector, 114 114 .pci_address = dw_edma_pcie_address, 115 115 }; ··· 225 225 226 226 chip->mf = vsec_data.mf; 227 227 chip->nr_irqs = nr_irqs; 228 - chip->ops = &dw_edma_pcie_core_ops; 228 + chip->ops = &dw_edma_pcie_plat_ops; 229 229 230 230 chip->ll_wr_cnt = vsec_data.wr_ch_cnt; 231 231 chip->ll_rd_cnt = vsec_data.rd_ch_cnt;
+72 -13
drivers/dma/dw-edma/dw-edma-v0-core.c
··· 7 7 */ 8 8 9 9 #include <linux/bitfield.h> 10 - 10 + #include <linux/irqreturn.h> 11 11 #include <linux/io-64-nonatomic-lo-hi.h> 12 12 13 13 #include "dw-edma-core.h" ··· 160 160 readl_ch(dw, dir, ch, &(__dw_ch_regs(dw, dir, ch)->name)) 161 161 162 162 /* eDMA management callbacks */ 163 - void dw_edma_v0_core_off(struct dw_edma *dw) 163 + static void dw_edma_v0_core_off(struct dw_edma *dw) 164 164 { 165 165 SET_BOTH_32(dw, int_mask, 166 166 EDMA_V0_DONE_INT_MASK | EDMA_V0_ABORT_INT_MASK); ··· 169 169 SET_BOTH_32(dw, engine_en, 0); 170 170 } 171 171 172 - u16 dw_edma_v0_core_ch_count(struct dw_edma *dw, enum dw_edma_dir dir) 172 + static u16 dw_edma_v0_core_ch_count(struct dw_edma *dw, enum dw_edma_dir dir) 173 173 { 174 174 u32 num_ch; 175 175 ··· 186 186 return (u16)num_ch; 187 187 } 188 188 189 - enum dma_status dw_edma_v0_core_ch_status(struct dw_edma_chan *chan) 189 + static enum dma_status dw_edma_v0_core_ch_status(struct dw_edma_chan *chan) 190 190 { 191 191 struct dw_edma *dw = chan->dw; 192 192 u32 tmp; ··· 202 202 return DMA_ERROR; 203 203 } 204 204 205 - void dw_edma_v0_core_clear_done_int(struct dw_edma_chan *chan) 205 + static void dw_edma_v0_core_clear_done_int(struct dw_edma_chan *chan) 206 206 { 207 207 struct dw_edma *dw = chan->dw; 208 208 ··· 210 210 FIELD_PREP(EDMA_V0_DONE_INT_MASK, BIT(chan->id))); 211 211 } 212 212 213 - void dw_edma_v0_core_clear_abort_int(struct dw_edma_chan *chan) 213 + static void dw_edma_v0_core_clear_abort_int(struct dw_edma_chan *chan) 214 214 { 215 215 struct dw_edma *dw = chan->dw; 216 216 ··· 218 218 FIELD_PREP(EDMA_V0_ABORT_INT_MASK, BIT(chan->id))); 219 219 } 220 220 221 - u32 dw_edma_v0_core_status_done_int(struct dw_edma *dw, enum dw_edma_dir dir) 221 + static u32 dw_edma_v0_core_status_done_int(struct dw_edma *dw, enum dw_edma_dir dir) 222 222 { 223 223 return FIELD_GET(EDMA_V0_DONE_INT_MASK, 224 224 GET_RW_32(dw, dir, int_status)); 225 225 } 226 226 227 - u32 dw_edma_v0_core_status_abort_int(struct dw_edma *dw, enum dw_edma_dir dir) 227 + static u32 dw_edma_v0_core_status_abort_int(struct dw_edma *dw, enum dw_edma_dir dir) 228 228 { 229 229 return FIELD_GET(EDMA_V0_ABORT_INT_MASK, 230 230 GET_RW_32(dw, dir, int_status)); 231 + } 232 + 233 + static irqreturn_t 234 + dw_edma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, 235 + dw_edma_handler_t done, dw_edma_handler_t abort) 236 + { 237 + struct dw_edma *dw = dw_irq->dw; 238 + unsigned long total, pos, val; 239 + irqreturn_t ret = IRQ_NONE; 240 + struct dw_edma_chan *chan; 241 + unsigned long off; 242 + u32 mask; 243 + 244 + if (dir == EDMA_DIR_WRITE) { 245 + total = dw->wr_ch_cnt; 246 + off = 0; 247 + mask = dw_irq->wr_mask; 248 + } else { 249 + total = dw->rd_ch_cnt; 250 + off = dw->wr_ch_cnt; 251 + mask = dw_irq->rd_mask; 252 + } 253 + 254 + val = dw_edma_v0_core_status_done_int(dw, dir); 255 + val &= mask; 256 + for_each_set_bit(pos, &val, total) { 257 + chan = &dw->chan[pos + off]; 258 + 259 + dw_edma_v0_core_clear_done_int(chan); 260 + done(chan); 261 + 262 + ret = IRQ_HANDLED; 263 + } 264 + 265 + val = dw_edma_v0_core_status_abort_int(dw, dir); 266 + val &= mask; 267 + for_each_set_bit(pos, &val, total) { 268 + chan = &dw->chan[pos + off]; 269 + 270 + dw_edma_v0_core_clear_abort_int(chan); 271 + abort(chan); 272 + 273 + ret = IRQ_HANDLED; 274 + } 275 + 276 + return ret; 231 277 } 232 278 233 279 static void dw_edma_v0_write_ll_data(struct dw_edma_chunk *chunk, int i, ··· 346 300 dw_edma_v0_write_ll_link(chunk, i, control, chunk->ll_region.paddr); 347 301 } 348 302 349 - void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first) 303 + static void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first) 350 304 { 351 305 struct dw_edma_chan *chan = chunk->chan; 352 306 struct dw_edma *dw = chan->dw; ··· 417 371 FIELD_PREP(EDMA_V0_DOORBELL_CH_MASK, chan->id)); 418 372 } 419 373 420 - int dw_edma_v0_core_device_config(struct dw_edma_chan *chan) 374 + static void dw_edma_v0_core_ch_config(struct dw_edma_chan *chan) 421 375 { 422 376 struct dw_edma *dw = chan->dw; 423 377 u32 tmp = 0; ··· 484 438 SET_RW_32(dw, chan->dir, ch67_imwr_data, tmp); 485 439 break; 486 440 } 487 - 488 - return 0; 489 441 } 490 442 491 443 /* eDMA debugfs callbacks */ 492 - void dw_edma_v0_core_debugfs_on(struct dw_edma *dw) 444 + static void dw_edma_v0_core_debugfs_on(struct dw_edma *dw) 493 445 { 494 446 dw_edma_v0_debugfs_on(dw); 447 + } 448 + 449 + static const struct dw_edma_core_ops dw_edma_v0_core = { 450 + .off = dw_edma_v0_core_off, 451 + .ch_count = dw_edma_v0_core_ch_count, 452 + .ch_status = dw_edma_v0_core_ch_status, 453 + .handle_int = dw_edma_v0_core_handle_int, 454 + .start = dw_edma_v0_core_start, 455 + .ch_config = dw_edma_v0_core_ch_config, 456 + .debugfs_on = dw_edma_v0_core_debugfs_on, 457 + }; 458 + 459 + void dw_edma_v0_core_register(struct dw_edma *dw) 460 + { 461 + dw->core = &dw_edma_v0_core; 495 462 }
+2 -12
drivers/dma/dw-edma/dw-edma-v0-core.h
··· 11 11 12 12 #include <linux/dma/edma.h> 13 13 14 - /* eDMA management callbacks */ 15 - void dw_edma_v0_core_off(struct dw_edma *chan); 16 - u16 dw_edma_v0_core_ch_count(struct dw_edma *chan, enum dw_edma_dir dir); 17 - enum dma_status dw_edma_v0_core_ch_status(struct dw_edma_chan *chan); 18 - void dw_edma_v0_core_clear_done_int(struct dw_edma_chan *chan); 19 - void dw_edma_v0_core_clear_abort_int(struct dw_edma_chan *chan); 20 - u32 dw_edma_v0_core_status_done_int(struct dw_edma *chan, enum dw_edma_dir dir); 21 - u32 dw_edma_v0_core_status_abort_int(struct dw_edma *chan, enum dw_edma_dir dir); 22 - void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first); 23 - int dw_edma_v0_core_device_config(struct dw_edma_chan *chan); 24 - /* eDMA debug fs callbacks */ 25 - void dw_edma_v0_core_debugfs_on(struct dw_edma *dw); 14 + /* eDMA core register */ 15 + void dw_edma_v0_core_register(struct dw_edma *dw); 26 16 27 17 #endif /* _DW_EDMA_V0_CORE_H */
+296
drivers/dma/dw-edma/dw-hdma-v0-core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2023 Cai Huoqing 4 + * Synopsys DesignWare HDMA v0 core 5 + */ 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/irqreturn.h> 9 + #include <linux/io-64-nonatomic-lo-hi.h> 10 + 11 + #include "dw-edma-core.h" 12 + #include "dw-hdma-v0-core.h" 13 + #include "dw-hdma-v0-regs.h" 14 + #include "dw-hdma-v0-debugfs.h" 15 + 16 + enum dw_hdma_control { 17 + DW_HDMA_V0_CB = BIT(0), 18 + DW_HDMA_V0_TCB = BIT(1), 19 + DW_HDMA_V0_LLP = BIT(2), 20 + DW_HDMA_V0_LIE = BIT(3), 21 + DW_HDMA_V0_RIE = BIT(4), 22 + DW_HDMA_V0_CCS = BIT(8), 23 + DW_HDMA_V0_LLE = BIT(9), 24 + }; 25 + 26 + static inline struct dw_hdma_v0_regs __iomem *__dw_regs(struct dw_edma *dw) 27 + { 28 + return dw->chip->reg_base; 29 + } 30 + 31 + static inline struct dw_hdma_v0_ch_regs __iomem * 32 + __dw_ch_regs(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch) 33 + { 34 + if (dir == EDMA_DIR_WRITE) 35 + return &(__dw_regs(dw)->ch[ch].wr); 36 + else 37 + return &(__dw_regs(dw)->ch[ch].rd); 38 + } 39 + 40 + #define SET_CH_32(dw, dir, ch, name, value) \ 41 + writel(value, &(__dw_ch_regs(dw, dir, ch)->name)) 42 + 43 + #define GET_CH_32(dw, dir, ch, name) \ 44 + readl(&(__dw_ch_regs(dw, dir, ch)->name)) 45 + 46 + #define SET_BOTH_CH_32(dw, ch, name, value) \ 47 + do { \ 48 + writel(value, &(__dw_ch_regs(dw, EDMA_DIR_WRITE, ch)->name)); \ 49 + writel(value, &(__dw_ch_regs(dw, EDMA_DIR_READ, ch)->name)); \ 50 + } while (0) 51 + 52 + /* HDMA management callbacks */ 53 + static void dw_hdma_v0_core_off(struct dw_edma *dw) 54 + { 55 + int id; 56 + 57 + for (id = 0; id < HDMA_V0_MAX_NR_CH; id++) { 58 + SET_BOTH_CH_32(dw, id, int_setup, 59 + HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK); 60 + SET_BOTH_CH_32(dw, id, int_clear, 61 + HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK); 62 + SET_BOTH_CH_32(dw, id, ch_en, 0); 63 + } 64 + } 65 + 66 + static u16 dw_hdma_v0_core_ch_count(struct dw_edma *dw, enum dw_edma_dir dir) 67 + { 68 + u32 num_ch = 0; 69 + int id; 70 + 71 + for (id = 0; id < HDMA_V0_MAX_NR_CH; id++) { 72 + if (GET_CH_32(dw, id, dir, ch_en) & BIT(0)) 73 + num_ch++; 74 + } 75 + 76 + if (num_ch > HDMA_V0_MAX_NR_CH) 77 + num_ch = HDMA_V0_MAX_NR_CH; 78 + 79 + return (u16)num_ch; 80 + } 81 + 82 + static enum dma_status dw_hdma_v0_core_ch_status(struct dw_edma_chan *chan) 83 + { 84 + struct dw_edma *dw = chan->dw; 85 + u32 tmp; 86 + 87 + tmp = FIELD_GET(HDMA_V0_CH_STATUS_MASK, 88 + GET_CH_32(dw, chan->id, chan->dir, ch_stat)); 89 + 90 + if (tmp == 1) 91 + return DMA_IN_PROGRESS; 92 + else if (tmp == 3) 93 + return DMA_COMPLETE; 94 + else 95 + return DMA_ERROR; 96 + } 97 + 98 + static void dw_hdma_v0_core_clear_done_int(struct dw_edma_chan *chan) 99 + { 100 + struct dw_edma *dw = chan->dw; 101 + 102 + SET_CH_32(dw, chan->dir, chan->id, int_clear, HDMA_V0_STOP_INT_MASK); 103 + } 104 + 105 + static void dw_hdma_v0_core_clear_abort_int(struct dw_edma_chan *chan) 106 + { 107 + struct dw_edma *dw = chan->dw; 108 + 109 + SET_CH_32(dw, chan->dir, chan->id, int_clear, HDMA_V0_ABORT_INT_MASK); 110 + } 111 + 112 + static u32 dw_hdma_v0_core_status_int(struct dw_edma_chan *chan) 113 + { 114 + struct dw_edma *dw = chan->dw; 115 + 116 + return GET_CH_32(dw, chan->dir, chan->id, int_stat); 117 + } 118 + 119 + static irqreturn_t 120 + dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, 121 + dw_edma_handler_t done, dw_edma_handler_t abort) 122 + { 123 + struct dw_edma *dw = dw_irq->dw; 124 + unsigned long total, pos, val; 125 + irqreturn_t ret = IRQ_NONE; 126 + struct dw_edma_chan *chan; 127 + unsigned long off, mask; 128 + 129 + if (dir == EDMA_DIR_WRITE) { 130 + total = dw->wr_ch_cnt; 131 + off = 0; 132 + mask = dw_irq->wr_mask; 133 + } else { 134 + total = dw->rd_ch_cnt; 135 + off = dw->wr_ch_cnt; 136 + mask = dw_irq->rd_mask; 137 + } 138 + 139 + for_each_set_bit(pos, &mask, total) { 140 + chan = &dw->chan[pos + off]; 141 + 142 + val = dw_hdma_v0_core_status_int(chan); 143 + if (FIELD_GET(HDMA_V0_STOP_INT_MASK, val)) { 144 + dw_hdma_v0_core_clear_done_int(chan); 145 + done(chan); 146 + 147 + ret = IRQ_HANDLED; 148 + } 149 + 150 + if (FIELD_GET(HDMA_V0_ABORT_INT_MASK, val)) { 151 + dw_hdma_v0_core_clear_abort_int(chan); 152 + abort(chan); 153 + 154 + ret = IRQ_HANDLED; 155 + } 156 + } 157 + 158 + return ret; 159 + } 160 + 161 + static void dw_hdma_v0_write_ll_data(struct dw_edma_chunk *chunk, int i, 162 + u32 control, u32 size, u64 sar, u64 dar) 163 + { 164 + ptrdiff_t ofs = i * sizeof(struct dw_hdma_v0_lli); 165 + 166 + if (chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) { 167 + struct dw_hdma_v0_lli *lli = chunk->ll_region.vaddr.mem + ofs; 168 + 169 + lli->control = control; 170 + lli->transfer_size = size; 171 + lli->sar.reg = sar; 172 + lli->dar.reg = dar; 173 + } else { 174 + struct dw_hdma_v0_lli __iomem *lli = chunk->ll_region.vaddr.io + ofs; 175 + 176 + writel(control, &lli->control); 177 + writel(size, &lli->transfer_size); 178 + writeq(sar, &lli->sar.reg); 179 + writeq(dar, &lli->dar.reg); 180 + } 181 + } 182 + 183 + static void dw_hdma_v0_write_ll_link(struct dw_edma_chunk *chunk, 184 + int i, u32 control, u64 pointer) 185 + { 186 + ptrdiff_t ofs = i * sizeof(struct dw_hdma_v0_lli); 187 + 188 + if (chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) { 189 + struct dw_hdma_v0_llp *llp = chunk->ll_region.vaddr.mem + ofs; 190 + 191 + llp->control = control; 192 + llp->llp.reg = pointer; 193 + } else { 194 + struct dw_hdma_v0_llp __iomem *llp = chunk->ll_region.vaddr.io + ofs; 195 + 196 + writel(control, &llp->control); 197 + writeq(pointer, &llp->llp.reg); 198 + } 199 + } 200 + 201 + static void dw_hdma_v0_core_write_chunk(struct dw_edma_chunk *chunk) 202 + { 203 + struct dw_edma_burst *child; 204 + struct dw_edma_chan *chan = chunk->chan; 205 + u32 control = 0, i = 0; 206 + int j; 207 + 208 + if (chunk->cb) 209 + control = DW_HDMA_V0_CB; 210 + 211 + j = chunk->bursts_alloc; 212 + list_for_each_entry(child, &chunk->burst->list, list) { 213 + j--; 214 + if (!j) { 215 + control |= DW_HDMA_V0_LIE; 216 + if (!(chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL)) 217 + control |= DW_HDMA_V0_RIE; 218 + } 219 + 220 + dw_hdma_v0_write_ll_data(chunk, i++, control, child->sz, 221 + child->sar, child->dar); 222 + } 223 + 224 + control = DW_HDMA_V0_LLP | DW_HDMA_V0_TCB; 225 + if (!chunk->cb) 226 + control |= DW_HDMA_V0_CB; 227 + 228 + dw_hdma_v0_write_ll_link(chunk, i, control, chunk->ll_region.paddr); 229 + } 230 + 231 + static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first) 232 + { 233 + struct dw_edma_chan *chan = chunk->chan; 234 + struct dw_edma *dw = chan->dw; 235 + u32 tmp; 236 + 237 + dw_hdma_v0_core_write_chunk(chunk); 238 + 239 + if (first) { 240 + /* Enable engine */ 241 + SET_CH_32(dw, chan->dir, chan->id, ch_en, BIT(0)); 242 + /* Interrupt enable&unmask - done, abort */ 243 + tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup) | 244 + HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK | 245 + HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_STOP_INT_EN; 246 + SET_CH_32(dw, chan->dir, chan->id, int_setup, tmp); 247 + /* Channel control */ 248 + SET_CH_32(dw, chan->dir, chan->id, control1, HDMA_V0_LINKLIST_EN); 249 + /* Linked list */ 250 + /* llp is not aligned on 64bit -> keep 32bit accesses */ 251 + SET_CH_32(dw, chan->dir, chan->id, llp.lsb, 252 + lower_32_bits(chunk->ll_region.paddr)); 253 + SET_CH_32(dw, chan->dir, chan->id, llp.msb, 254 + upper_32_bits(chunk->ll_region.paddr)); 255 + } 256 + /* Set consumer cycle */ 257 + SET_CH_32(dw, chan->dir, chan->id, cycle_sync, 258 + HDMA_V0_CONSUMER_CYCLE_STAT | HDMA_V0_CONSUMER_CYCLE_BIT); 259 + /* Doorbell */ 260 + SET_CH_32(dw, chan->dir, chan->id, doorbell, HDMA_V0_DOORBELL_START); 261 + } 262 + 263 + static void dw_hdma_v0_core_ch_config(struct dw_edma_chan *chan) 264 + { 265 + struct dw_edma *dw = chan->dw; 266 + 267 + /* MSI done addr - low, high */ 268 + SET_CH_32(dw, chan->dir, chan->id, msi_stop.lsb, chan->msi.address_lo); 269 + SET_CH_32(dw, chan->dir, chan->id, msi_stop.msb, chan->msi.address_hi); 270 + /* MSI abort addr - low, high */ 271 + SET_CH_32(dw, chan->dir, chan->id, msi_abort.lsb, chan->msi.address_lo); 272 + SET_CH_32(dw, chan->dir, chan->id, msi_abort.msb, chan->msi.address_hi); 273 + /* config MSI data */ 274 + SET_CH_32(dw, chan->dir, chan->id, msi_msgdata, chan->msi.data); 275 + } 276 + 277 + /* HDMA debugfs callbacks */ 278 + static void dw_hdma_v0_core_debugfs_on(struct dw_edma *dw) 279 + { 280 + dw_hdma_v0_debugfs_on(dw); 281 + } 282 + 283 + static const struct dw_edma_core_ops dw_hdma_v0_core = { 284 + .off = dw_hdma_v0_core_off, 285 + .ch_count = dw_hdma_v0_core_ch_count, 286 + .ch_status = dw_hdma_v0_core_ch_status, 287 + .handle_int = dw_hdma_v0_core_handle_int, 288 + .start = dw_hdma_v0_core_start, 289 + .ch_config = dw_hdma_v0_core_ch_config, 290 + .debugfs_on = dw_hdma_v0_core_debugfs_on, 291 + }; 292 + 293 + void dw_hdma_v0_core_register(struct dw_edma *dw) 294 + { 295 + dw->core = &dw_hdma_v0_core; 296 + }
+17
drivers/dma/dw-edma/dw-hdma-v0-core.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2023 Cai Huoqing 4 + * Synopsys DesignWare HDMA v0 core 5 + * 6 + * Author: Cai Huoqing <cai.huoqing@linux.dev> 7 + */ 8 + 9 + #ifndef _DW_HDMA_V0_CORE_H 10 + #define _DW_HDMA_V0_CORE_H 11 + 12 + #include <linux/dma/edma.h> 13 + 14 + /* HDMA core register */ 15 + void dw_hdma_v0_core_register(struct dw_edma *dw); 16 + 17 + #endif /* _DW_HDMA_V0_CORE_H */
+170
drivers/dma/dw-edma/dw-hdma-v0-debugfs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2023 Cai Huoqing 4 + * Synopsys DesignWare HDMA v0 debugfs 5 + * 6 + * Author: Cai Huoqing <cai.huoqing@linux.dev> 7 + */ 8 + 9 + #include <linux/debugfs.h> 10 + #include <linux/bitfield.h> 11 + 12 + #include "dw-hdma-v0-debugfs.h" 13 + #include "dw-hdma-v0-regs.h" 14 + #include "dw-edma-core.h" 15 + 16 + #define REGS_ADDR(dw, name) \ 17 + ({ \ 18 + struct dw_hdma_v0_regs __iomem *__regs = (dw)->chip->reg_base; \ 19 + \ 20 + (void __iomem *)&__regs->name; \ 21 + }) 22 + 23 + #define REGS_CH_ADDR(dw, name, _dir, _ch) \ 24 + ({ \ 25 + struct dw_hdma_v0_ch_regs __iomem *__ch_regs; \ 26 + \ 27 + if (_dir == EDMA_DIR_READ) \ 28 + __ch_regs = REGS_ADDR(dw, ch[_ch].rd); \ 29 + else \ 30 + __ch_regs = REGS_ADDR(dw, ch[_ch].wr); \ 31 + \ 32 + (void __iomem *)&__ch_regs->name; \ 33 + }) 34 + 35 + #define CTX_REGISTER(dw, name, dir, ch) \ 36 + {#name, REGS_CH_ADDR(dw, name, dir, ch)} 37 + 38 + #define WRITE_STR "write" 39 + #define READ_STR "read" 40 + #define CHANNEL_STR "channel" 41 + #define REGISTERS_STR "registers" 42 + 43 + struct dw_hdma_debugfs_entry { 44 + const char *name; 45 + void __iomem *reg; 46 + }; 47 + 48 + static int dw_hdma_debugfs_u32_get(void *data, u64 *val) 49 + { 50 + struct dw_hdma_debugfs_entry *entry = data; 51 + void __iomem *reg = entry->reg; 52 + 53 + *val = readl(reg); 54 + 55 + return 0; 56 + } 57 + DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_hdma_debugfs_u32_get, NULL, "0x%08llx\n"); 58 + 59 + static void dw_hdma_debugfs_create_x32(struct dw_edma *dw, 60 + const struct dw_hdma_debugfs_entry ini[], 61 + int nr_entries, struct dentry *dent) 62 + { 63 + struct dw_hdma_debugfs_entry *entries; 64 + int i; 65 + 66 + entries = devm_kcalloc(dw->chip->dev, nr_entries, sizeof(*entries), 67 + GFP_KERNEL); 68 + if (!entries) 69 + return; 70 + 71 + for (i = 0; i < nr_entries; i++) { 72 + entries[i] = ini[i]; 73 + 74 + debugfs_create_file_unsafe(entries[i].name, 0444, dent, 75 + &entries[i], &fops_x32); 76 + } 77 + } 78 + 79 + static void dw_hdma_debugfs_regs_ch(struct dw_edma *dw, enum dw_edma_dir dir, 80 + u16 ch, struct dentry *dent) 81 + { 82 + const struct dw_hdma_debugfs_entry debugfs_regs[] = { 83 + CTX_REGISTER(dw, ch_en, dir, ch), 84 + CTX_REGISTER(dw, doorbell, dir, ch), 85 + CTX_REGISTER(dw, prefetch, dir, ch), 86 + CTX_REGISTER(dw, handshake, dir, ch), 87 + CTX_REGISTER(dw, llp.lsb, dir, ch), 88 + CTX_REGISTER(dw, llp.msb, dir, ch), 89 + CTX_REGISTER(dw, cycle_sync, dir, ch), 90 + CTX_REGISTER(dw, transfer_size, dir, ch), 91 + CTX_REGISTER(dw, sar.lsb, dir, ch), 92 + CTX_REGISTER(dw, sar.msb, dir, ch), 93 + CTX_REGISTER(dw, dar.lsb, dir, ch), 94 + CTX_REGISTER(dw, dar.msb, dir, ch), 95 + CTX_REGISTER(dw, watermark_en, dir, ch), 96 + CTX_REGISTER(dw, control1, dir, ch), 97 + CTX_REGISTER(dw, func_num, dir, ch), 98 + CTX_REGISTER(dw, qos, dir, ch), 99 + CTX_REGISTER(dw, ch_stat, dir, ch), 100 + CTX_REGISTER(dw, int_stat, dir, ch), 101 + CTX_REGISTER(dw, int_setup, dir, ch), 102 + CTX_REGISTER(dw, int_clear, dir, ch), 103 + CTX_REGISTER(dw, msi_stop.lsb, dir, ch), 104 + CTX_REGISTER(dw, msi_stop.msb, dir, ch), 105 + CTX_REGISTER(dw, msi_watermark.lsb, dir, ch), 106 + CTX_REGISTER(dw, msi_watermark.msb, dir, ch), 107 + CTX_REGISTER(dw, msi_abort.lsb, dir, ch), 108 + CTX_REGISTER(dw, msi_abort.msb, dir, ch), 109 + CTX_REGISTER(dw, msi_msgdata, dir, ch), 110 + }; 111 + int nr_entries = ARRAY_SIZE(debugfs_regs); 112 + 113 + dw_hdma_debugfs_create_x32(dw, debugfs_regs, nr_entries, dent); 114 + } 115 + 116 + static void dw_hdma_debugfs_regs_wr(struct dw_edma *dw, struct dentry *dent) 117 + { 118 + struct dentry *regs_dent, *ch_dent; 119 + char name[16]; 120 + int i; 121 + 122 + regs_dent = debugfs_create_dir(WRITE_STR, dent); 123 + 124 + for (i = 0; i < dw->wr_ch_cnt; i++) { 125 + snprintf(name, sizeof(name), "%s:%d", CHANNEL_STR, i); 126 + 127 + ch_dent = debugfs_create_dir(name, regs_dent); 128 + 129 + dw_hdma_debugfs_regs_ch(dw, EDMA_DIR_WRITE, i, ch_dent); 130 + } 131 + } 132 + 133 + static void dw_hdma_debugfs_regs_rd(struct dw_edma *dw, struct dentry *dent) 134 + { 135 + struct dentry *regs_dent, *ch_dent; 136 + char name[16]; 137 + int i; 138 + 139 + regs_dent = debugfs_create_dir(READ_STR, dent); 140 + 141 + for (i = 0; i < dw->rd_ch_cnt; i++) { 142 + snprintf(name, sizeof(name), "%s:%d", CHANNEL_STR, i); 143 + 144 + ch_dent = debugfs_create_dir(name, regs_dent); 145 + 146 + dw_hdma_debugfs_regs_ch(dw, EDMA_DIR_READ, i, ch_dent); 147 + } 148 + } 149 + 150 + static void dw_hdma_debugfs_regs(struct dw_edma *dw) 151 + { 152 + struct dentry *regs_dent; 153 + 154 + regs_dent = debugfs_create_dir(REGISTERS_STR, dw->dma.dbg_dev_root); 155 + 156 + dw_hdma_debugfs_regs_wr(dw, regs_dent); 157 + dw_hdma_debugfs_regs_rd(dw, regs_dent); 158 + } 159 + 160 + void dw_hdma_v0_debugfs_on(struct dw_edma *dw) 161 + { 162 + if (!debugfs_initialized()) 163 + return; 164 + 165 + debugfs_create_u32("mf", 0444, dw->dma.dbg_dev_root, &dw->chip->mf); 166 + debugfs_create_u16("wr_ch_cnt", 0444, dw->dma.dbg_dev_root, &dw->wr_ch_cnt); 167 + debugfs_create_u16("rd_ch_cnt", 0444, dw->dma.dbg_dev_root, &dw->rd_ch_cnt); 168 + 169 + dw_hdma_debugfs_regs(dw); 170 + }
+22
drivers/dma/dw-edma/dw-hdma-v0-debugfs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2023 Cai Huoqing 4 + * Synopsys DesignWare HDMA v0 debugfs 5 + * 6 + * Author: Cai Huoqing <cai.huoqing@linux.dev> 7 + */ 8 + 9 + #ifndef _DW_HDMA_V0_DEBUG_FS_H 10 + #define _DW_HDMA_V0_DEBUG_FS_H 11 + 12 + #include <linux/dma/edma.h> 13 + 14 + #ifdef CONFIG_DEBUG_FS 15 + void dw_hdma_v0_debugfs_on(struct dw_edma *dw); 16 + #else 17 + static inline void dw_hdma_v0_debugfs_on(struct dw_edma *dw) 18 + { 19 + } 20 + #endif /* CONFIG_DEBUG_FS */ 21 + 22 + #endif /* _DW_HDMA_V0_DEBUG_FS_H */
+129
drivers/dma/dw-edma/dw-hdma-v0-regs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2023 Cai Huoqing 4 + * Synopsys DesignWare HDMA v0 reg 5 + * 6 + * Author: Cai Huoqing <cai.huoqing@linux.dev> 7 + */ 8 + 9 + #ifndef _DW_HDMA_V0_REGS_H 10 + #define _DW_HDMA_V0_REGS_H 11 + 12 + #include <linux/dmaengine.h> 13 + 14 + #define HDMA_V0_MAX_NR_CH 8 15 + #define HDMA_V0_LOCAL_ABORT_INT_EN BIT(6) 16 + #define HDMA_V0_REMOTE_ABORT_INT_EN BIT(5) 17 + #define HDMA_V0_LOCAL_STOP_INT_EN BIT(4) 18 + #define HDMA_V0_REMOTEL_STOP_INT_EN BIT(3) 19 + #define HDMA_V0_ABORT_INT_MASK BIT(2) 20 + #define HDMA_V0_STOP_INT_MASK BIT(0) 21 + #define HDMA_V0_LINKLIST_EN BIT(0) 22 + #define HDMA_V0_CONSUMER_CYCLE_STAT BIT(1) 23 + #define HDMA_V0_CONSUMER_CYCLE_BIT BIT(0) 24 + #define HDMA_V0_DOORBELL_START BIT(0) 25 + #define HDMA_V0_CH_STATUS_MASK GENMASK(1, 0) 26 + 27 + struct dw_hdma_v0_ch_regs { 28 + u32 ch_en; /* 0x0000 */ 29 + u32 doorbell; /* 0x0004 */ 30 + u32 prefetch; /* 0x0008 */ 31 + u32 handshake; /* 0x000c */ 32 + union { 33 + u64 reg; /* 0x0010..0x0014 */ 34 + struct { 35 + u32 lsb; /* 0x0010 */ 36 + u32 msb; /* 0x0014 */ 37 + }; 38 + } llp; 39 + u32 cycle_sync; /* 0x0018 */ 40 + u32 transfer_size; /* 0x001c */ 41 + union { 42 + u64 reg; /* 0x0020..0x0024 */ 43 + struct { 44 + u32 lsb; /* 0x0020 */ 45 + u32 msb; /* 0x0024 */ 46 + }; 47 + } sar; 48 + union { 49 + u64 reg; /* 0x0028..0x002c */ 50 + struct { 51 + u32 lsb; /* 0x0028 */ 52 + u32 msb; /* 0x002c */ 53 + }; 54 + } dar; 55 + u32 watermark_en; /* 0x0030 */ 56 + u32 control1; /* 0x0034 */ 57 + u32 func_num; /* 0x0038 */ 58 + u32 qos; /* 0x003c */ 59 + u32 padding_1[16]; /* 0x0040..0x007c */ 60 + u32 ch_stat; /* 0x0080 */ 61 + u32 int_stat; /* 0x0084 */ 62 + u32 int_setup; /* 0x0088 */ 63 + u32 int_clear; /* 0x008c */ 64 + union { 65 + u64 reg; /* 0x0090..0x0094 */ 66 + struct { 67 + u32 lsb; /* 0x0090 */ 68 + u32 msb; /* 0x0094 */ 69 + }; 70 + } msi_stop; 71 + union { 72 + u64 reg; /* 0x0098..0x009c */ 73 + struct { 74 + u32 lsb; /* 0x0098 */ 75 + u32 msb; /* 0x009c */ 76 + }; 77 + } msi_watermark; 78 + union { 79 + u64 reg; /* 0x00a0..0x00a4 */ 80 + struct { 81 + u32 lsb; /* 0x00a0 */ 82 + u32 msb; /* 0x00a4 */ 83 + }; 84 + } msi_abort; 85 + u32 msi_msgdata; /* 0x00a8 */ 86 + u32 padding_2[21]; /* 0x00ac..0x00fc */ 87 + } __packed; 88 + 89 + struct dw_hdma_v0_ch { 90 + struct dw_hdma_v0_ch_regs wr; /* 0x0000 */ 91 + struct dw_hdma_v0_ch_regs rd; /* 0x0100 */ 92 + } __packed; 93 + 94 + struct dw_hdma_v0_regs { 95 + struct dw_hdma_v0_ch ch[HDMA_V0_MAX_NR_CH]; /* 0x0000..0x0fa8 */ 96 + } __packed; 97 + 98 + struct dw_hdma_v0_lli { 99 + u32 control; 100 + u32 transfer_size; 101 + union { 102 + u64 reg; 103 + struct { 104 + u32 lsb; 105 + u32 msb; 106 + }; 107 + } sar; 108 + union { 109 + u64 reg; 110 + struct { 111 + u32 lsb; 112 + u32 msb; 113 + }; 114 + } dar; 115 + } __packed; 116 + 117 + struct dw_hdma_v0_llp { 118 + u32 control; 119 + u32 reserved; 120 + union { 121 + u64 reg; 122 + struct { 123 + u32 lsb; 124 + u32 msb; 125 + }; 126 + } llp; 127 + } __packed; 128 + 129 + #endif /* _DW_HDMA_V0_REGS_H */
-1
drivers/dma/plx_dma.c
··· 517 517 plxdev->bar = pcim_iomap_table(pdev)[0]; 518 518 519 519 dma = &plxdev->dma_dev; 520 - dma->chancnt = 1; 521 520 INIT_LIST_HEAD(&dma->channels); 522 521 dma_cap_set(DMA_MEMCPY, dma->cap_mask); 523 522 dma->copy_align = DMAENGINE_ALIGN_1_BYTE;
+1
drivers/dma/qcom/Kconfig
··· 45 45 46 46 config QCOM_HIDMA 47 47 tristate "Qualcomm Technologies HIDMA Channel support" 48 + depends on HAS_IOMEM 48 49 select DMA_ENGINE 49 50 help 50 51 Enable support for the Qualcomm Technologies HIDMA controller.
+9 -9
drivers/dma/qcom/bam_dma.c
··· 1272 1272 bdev->powered_remotely = of_property_read_bool(pdev->dev.of_node, 1273 1273 "qcom,powered-remotely"); 1274 1274 1275 - if (bdev->controlled_remotely || bdev->powered_remotely) { 1275 + if (bdev->controlled_remotely || bdev->powered_remotely) 1276 + bdev->bamclk = devm_clk_get_optional(bdev->dev, "bam_clk"); 1277 + else 1278 + bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk"); 1279 + 1280 + if (IS_ERR(bdev->bamclk)) 1281 + return PTR_ERR(bdev->bamclk); 1282 + 1283 + if (!bdev->bamclk) { 1276 1284 ret = of_property_read_u32(pdev->dev.of_node, "num-channels", 1277 1285 &bdev->num_channels); 1278 1286 if (ret) ··· 1291 1283 if (ret) 1292 1284 dev_err(bdev->dev, "num-ees unspecified in dt\n"); 1293 1285 } 1294 - 1295 - if (bdev->controlled_remotely || bdev->powered_remotely) 1296 - bdev->bamclk = devm_clk_get_optional(bdev->dev, "bam_clk"); 1297 - else 1298 - bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk"); 1299 - 1300 - if (IS_ERR(bdev->bamclk)) 1301 - return PTR_ERR(bdev->bamclk); 1302 1286 1303 1287 ret = clk_prepare_enable(bdev->bamclk); 1304 1288 if (ret) {
-1
drivers/dma/qcom/hidma.c
··· 214 214 215 215 spin_lock_init(&mchan->lock); 216 216 list_add_tail(&mchan->chan.device_node, &ddev->channels); 217 - dmadev->ddev.chancnt++; 218 217 return 0; 219 218 } 220 219
-1
drivers/dma/sprd-dma.c
··· 1169 1169 1170 1170 dma_cap_set(DMA_MEMCPY, sdev->dma_dev.cap_mask); 1171 1171 sdev->total_chns = chn_count; 1172 - sdev->dma_dev.chancnt = chn_count; 1173 1172 INIT_LIST_HEAD(&sdev->dma_dev.channels); 1174 1173 INIT_LIST_HEAD(&sdev->dma_dev.global_node); 1175 1174 sdev->dma_dev.dev = &pdev->dev;
+150 -184
drivers/dma/ste_dma40.c
··· 19 19 #include <linux/pm_runtime.h> 20 20 #include <linux/err.h> 21 21 #include <linux/of.h> 22 + #include <linux/of_address.h> 22 23 #include <linux/of_dma.h> 23 24 #include <linux/amba/bus.h> 24 25 #include <linux/regulator/consumer.h> 25 - #include <linux/platform_data/dma-ste-dma40.h> 26 26 27 27 #include "dmaengine.h" 28 + #include "ste_dma40.h" 28 29 #include "ste_dma40_ll.h" 30 + 31 + /** 32 + * struct stedma40_platform_data - Configuration struct for the dma device. 33 + * 34 + * @dev_tx: mapping between destination event line and io address 35 + * @dev_rx: mapping between source event line and io address 36 + * @disabled_channels: A vector, ending with -1, that marks physical channels 37 + * that are for different reasons not available for the driver. 38 + * @soft_lli_chans: A vector, that marks physical channels will use LLI by SW 39 + * which avoids HW bug that exists in some versions of the controller. 40 + * SoftLLI introduces relink overhead that could impact performace for 41 + * certain use cases. 42 + * @num_of_soft_lli_chans: The number of channels that needs to be configured 43 + * to use SoftLLI. 44 + * @use_esram_lcla: flag for mapping the lcla into esram region 45 + * @num_of_memcpy_chans: The number of channels reserved for memcpy. 46 + * @num_of_phy_chans: The number of physical channels implemented in HW. 47 + * 0 means reading the number of channels from DMA HW but this is only valid 48 + * for 'multiple of 4' channels, like 8. 49 + */ 50 + struct stedma40_platform_data { 51 + int disabled_channels[STEDMA40_MAX_PHYS]; 52 + int *soft_lli_chans; 53 + int num_of_soft_lli_chans; 54 + bool use_esram_lcla; 55 + int num_of_memcpy_chans; 56 + int num_of_phy_chans; 57 + }; 29 58 30 59 #define D40_NAME "dma40" 31 60 ··· 136 107 }; 137 108 138 109 /** 139 - * enum 40_command - The different commands and/or statuses. 110 + * enum d40_command - The different commands and/or statuses. 140 111 * 141 112 * @D40_DMA_STOP: DMA channel command STOP or status STOPPED, 142 113 * @D40_DMA_RUN: The DMA channel is RUNNING of the command RUN. ··· 554 525 * @virtbase: The virtual base address of the DMA's register. 555 526 * @rev: silicon revision detected. 556 527 * @clk: Pointer to the DMA clock structure. 557 - * @phy_start: Physical memory start of the DMA registers. 558 - * @phy_size: Size of the DMA register map. 559 528 * @irq: The IRQ number. 560 529 * @num_memcpy_chans: The number of channels used for memcpy (mem-to-mem 561 530 * transfers). ··· 597 570 void __iomem *virtbase; 598 571 u8 rev:4; 599 572 struct clk *clk; 600 - phys_addr_t phy_start; 601 - resource_size_t phy_size; 602 573 int irq; 603 574 int num_memcpy_chans; 604 575 int num_phy_chans; ··· 2293 2268 return NULL; 2294 2269 } 2295 2270 2296 - bool stedma40_filter(struct dma_chan *chan, void *data) 2271 + static bool stedma40_filter(struct dma_chan *chan, void *data) 2297 2272 { 2298 2273 struct stedma40_chan_cfg *info = data; 2299 2274 struct d40_chan *d40c = ··· 2312 2287 2313 2288 return err == 0; 2314 2289 } 2315 - EXPORT_SYMBOL(stedma40_filter); 2316 2290 2317 2291 static void __d40_set_prio_rt(struct d40_chan *d40c, int dev_type, bool src) 2318 2292 { ··· 3124 3100 return num_phy_chans_avail; 3125 3101 } 3126 3102 3127 - static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) 3103 + /* Called from the registered devm action */ 3104 + static void d40_drop_kmem_cache_action(void *d) 3105 + { 3106 + struct kmem_cache *desc_slab = d; 3107 + 3108 + kmem_cache_destroy(desc_slab); 3109 + } 3110 + 3111 + static int __init d40_hw_detect_init(struct platform_device *pdev, 3112 + struct d40_base **retbase) 3128 3113 { 3129 3114 struct stedma40_platform_data *plat_data = dev_get_platdata(&pdev->dev); 3115 + struct device *dev = &pdev->dev; 3130 3116 struct clk *clk; 3131 3117 void __iomem *virtbase; 3132 - struct resource *res; 3133 3118 struct d40_base *base; 3134 3119 int num_log_chans; 3135 3120 int num_phy_chans; 3136 3121 int num_memcpy_chans; 3137 - int clk_ret = -EINVAL; 3138 3122 int i; 3139 3123 u32 pid; 3140 3124 u32 cid; 3141 3125 u8 rev; 3126 + int ret; 3142 3127 3143 - clk = clk_get(&pdev->dev, NULL); 3144 - if (IS_ERR(clk)) { 3145 - d40_err(&pdev->dev, "No matching clock found\n"); 3146 - goto check_prepare_enabled; 3147 - } 3148 - 3149 - clk_ret = clk_prepare_enable(clk); 3150 - if (clk_ret) { 3151 - d40_err(&pdev->dev, "Failed to prepare/enable clock\n"); 3152 - goto disable_unprepare; 3153 - } 3128 + clk = devm_clk_get_enabled(dev, NULL); 3129 + if (IS_ERR(clk)) 3130 + return PTR_ERR(clk); 3154 3131 3155 3132 /* Get IO for DMAC base address */ 3156 - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base"); 3157 - if (!res) 3158 - goto disable_unprepare; 3159 - 3160 - if (request_mem_region(res->start, resource_size(res), 3161 - D40_NAME " I/O base") == NULL) 3162 - goto release_region; 3163 - 3164 - virtbase = ioremap(res->start, resource_size(res)); 3165 - if (!virtbase) 3166 - goto release_region; 3133 + virtbase = devm_platform_ioremap_resource_byname(pdev, "base"); 3134 + if (IS_ERR(virtbase)) 3135 + return PTR_ERR(virtbase); 3167 3136 3168 3137 /* This is just a regular AMBA PrimeCell ID actually */ 3169 3138 for (pid = 0, i = 0; i < 4; i++) 3170 - pid |= (readl(virtbase + resource_size(res) - 0x20 + 4 * i) 3139 + pid |= (readl(virtbase + SZ_4K - 0x20 + 4 * i) 3171 3140 & 255) << (i * 8); 3172 3141 for (cid = 0, i = 0; i < 4; i++) 3173 - cid |= (readl(virtbase + resource_size(res) - 0x10 + 4 * i) 3142 + cid |= (readl(virtbase + SZ_4K - 0x10 + 4 * i) 3174 3143 & 255) << (i * 8); 3175 3144 3176 3145 if (cid != AMBA_CID) { 3177 - d40_err(&pdev->dev, "Unknown hardware! No PrimeCell ID\n"); 3178 - goto unmap_io; 3146 + d40_err(dev, "Unknown hardware! No PrimeCell ID\n"); 3147 + return -EINVAL; 3179 3148 } 3180 3149 if (AMBA_MANF_BITS(pid) != AMBA_VENDOR_ST) { 3181 - d40_err(&pdev->dev, "Unknown designer! Got %x wanted %x\n", 3150 + d40_err(dev, "Unknown designer! Got %x wanted %x\n", 3182 3151 AMBA_MANF_BITS(pid), 3183 3152 AMBA_VENDOR_ST); 3184 - goto unmap_io; 3153 + return -EINVAL; 3185 3154 } 3186 3155 /* 3187 3156 * HW revision: ··· 3187 3170 */ 3188 3171 rev = AMBA_REV_BITS(pid); 3189 3172 if (rev < 2) { 3190 - d40_err(&pdev->dev, "hardware revision: %d is not supported", rev); 3191 - goto unmap_io; 3173 + d40_err(dev, "hardware revision: %d is not supported", rev); 3174 + return -EINVAL; 3192 3175 } 3193 3176 3194 3177 /* The number of physical channels on this HW */ ··· 3205 3188 3206 3189 num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; 3207 3190 3208 - dev_info(&pdev->dev, 3209 - "hardware rev: %d @ %pa with %d physical and %d logical channels\n", 3210 - rev, &res->start, num_phy_chans, num_log_chans); 3191 + dev_info(dev, 3192 + "hardware rev: %d with %d physical and %d logical channels\n", 3193 + rev, num_phy_chans, num_log_chans); 3211 3194 3212 - base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + 3213 - (num_phy_chans + num_log_chans + num_memcpy_chans) * 3214 - sizeof(struct d40_chan), GFP_KERNEL); 3195 + base = devm_kzalloc(dev, 3196 + ALIGN(sizeof(struct d40_base), 4) + 3197 + (num_phy_chans + num_log_chans + num_memcpy_chans) * 3198 + sizeof(struct d40_chan), GFP_KERNEL); 3215 3199 3216 - if (base == NULL) 3217 - goto unmap_io; 3200 + if (!base) 3201 + return -ENOMEM; 3218 3202 3219 3203 base->rev = rev; 3220 3204 base->clk = clk; 3221 3205 base->num_memcpy_chans = num_memcpy_chans; 3222 3206 base->num_phy_chans = num_phy_chans; 3223 3207 base->num_log_chans = num_log_chans; 3224 - base->phy_start = res->start; 3225 - base->phy_size = resource_size(res); 3226 3208 base->virtbase = virtbase; 3227 3209 base->plat_data = plat_data; 3228 - base->dev = &pdev->dev; 3210 + base->dev = dev; 3229 3211 base->phy_chans = ((void *)base) + ALIGN(sizeof(struct d40_base), 4); 3230 3212 base->log_chans = &base->phy_chans[num_phy_chans]; 3231 3213 ··· 3258 3242 base->gen_dmac.init_reg_size = ARRAY_SIZE(dma_init_reg_v4a); 3259 3243 } 3260 3244 3261 - base->phy_res = kcalloc(num_phy_chans, 3262 - sizeof(*base->phy_res), 3263 - GFP_KERNEL); 3245 + base->phy_res = devm_kcalloc(dev, num_phy_chans, 3246 + sizeof(*base->phy_res), 3247 + GFP_KERNEL); 3264 3248 if (!base->phy_res) 3265 - goto free_base; 3249 + return -ENOMEM; 3266 3250 3267 - base->lookup_phy_chans = kcalloc(num_phy_chans, 3268 - sizeof(*base->lookup_phy_chans), 3269 - GFP_KERNEL); 3251 + base->lookup_phy_chans = devm_kcalloc(dev, num_phy_chans, 3252 + sizeof(*base->lookup_phy_chans), 3253 + GFP_KERNEL); 3270 3254 if (!base->lookup_phy_chans) 3271 - goto free_phy_res; 3255 + return -ENOMEM; 3272 3256 3273 - base->lookup_log_chans = kcalloc(num_log_chans, 3274 - sizeof(*base->lookup_log_chans), 3275 - GFP_KERNEL); 3257 + base->lookup_log_chans = devm_kcalloc(dev, num_log_chans, 3258 + sizeof(*base->lookup_log_chans), 3259 + GFP_KERNEL); 3276 3260 if (!base->lookup_log_chans) 3277 - goto free_phy_chans; 3261 + return -ENOMEM; 3278 3262 3279 - base->reg_val_backup_chan = kmalloc_array(base->num_phy_chans, 3263 + base->reg_val_backup_chan = devm_kmalloc_array(dev, base->num_phy_chans, 3280 3264 sizeof(d40_backup_regs_chan), 3281 3265 GFP_KERNEL); 3282 3266 if (!base->reg_val_backup_chan) 3283 - goto free_log_chans; 3267 + return -ENOMEM; 3284 3268 3285 - base->lcla_pool.alloc_map = kcalloc(num_phy_chans 3269 + base->lcla_pool.alloc_map = devm_kcalloc(dev, num_phy_chans 3286 3270 * D40_LCLA_LINK_PER_EVENT_GRP, 3287 3271 sizeof(*base->lcla_pool.alloc_map), 3288 3272 GFP_KERNEL); 3289 3273 if (!base->lcla_pool.alloc_map) 3290 - goto free_backup_chan; 3274 + return -ENOMEM; 3291 3275 3292 - base->regs_interrupt = kmalloc_array(base->gen_dmac.il_size, 3276 + base->regs_interrupt = devm_kmalloc_array(dev, base->gen_dmac.il_size, 3293 3277 sizeof(*base->regs_interrupt), 3294 3278 GFP_KERNEL); 3295 3279 if (!base->regs_interrupt) 3296 - goto free_map; 3280 + return -ENOMEM; 3297 3281 3298 3282 base->desc_slab = kmem_cache_create(D40_NAME, sizeof(struct d40_desc), 3299 3283 0, SLAB_HWCACHE_ALIGN, 3300 3284 NULL); 3301 - if (base->desc_slab == NULL) 3302 - goto free_regs; 3285 + if (!base->desc_slab) 3286 + return -ENOMEM; 3303 3287 3288 + ret = devm_add_action_or_reset(dev, d40_drop_kmem_cache_action, 3289 + base->desc_slab); 3290 + if (ret) 3291 + return ret; 3304 3292 3305 - return base; 3306 - free_regs: 3307 - kfree(base->regs_interrupt); 3308 - free_map: 3309 - kfree(base->lcla_pool.alloc_map); 3310 - free_backup_chan: 3311 - kfree(base->reg_val_backup_chan); 3312 - free_log_chans: 3313 - kfree(base->lookup_log_chans); 3314 - free_phy_chans: 3315 - kfree(base->lookup_phy_chans); 3316 - free_phy_res: 3317 - kfree(base->phy_res); 3318 - free_base: 3319 - kfree(base); 3320 - unmap_io: 3321 - iounmap(virtbase); 3322 - release_region: 3323 - release_mem_region(res->start, resource_size(res)); 3324 - check_prepare_enabled: 3325 - if (!clk_ret) 3326 - disable_unprepare: 3327 - clk_disable_unprepare(clk); 3328 - if (!IS_ERR(clk)) 3329 - clk_put(clk); 3330 - return NULL; 3293 + *retbase = base; 3294 + 3295 + return 0; 3331 3296 } 3332 3297 3333 3298 static void __init d40_hw_init(struct d40_base *base) ··· 3448 3451 return ret; 3449 3452 } 3450 3453 3451 - static int __init d40_of_probe(struct platform_device *pdev, 3454 + static int __init d40_of_probe(struct device *dev, 3452 3455 struct device_node *np) 3453 3456 { 3454 3457 struct stedma40_platform_data *pdata; 3455 3458 int num_phy = 0, num_memcpy = 0, num_disabled = 0; 3456 3459 const __be32 *list; 3457 3460 3458 - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 3461 + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 3459 3462 if (!pdata) 3460 3463 return -ENOMEM; 3461 3464 ··· 3468 3471 num_memcpy /= sizeof(*list); 3469 3472 3470 3473 if (num_memcpy > D40_MEMCPY_MAX_CHANS || num_memcpy <= 0) { 3471 - d40_err(&pdev->dev, 3474 + d40_err(dev, 3472 3475 "Invalid number of memcpy channels specified (%d)\n", 3473 3476 num_memcpy); 3474 3477 return -EINVAL; ··· 3483 3486 num_disabled /= sizeof(*list); 3484 3487 3485 3488 if (num_disabled >= STEDMA40_MAX_PHYS || num_disabled < 0) { 3486 - d40_err(&pdev->dev, 3489 + d40_err(dev, 3487 3490 "Invalid number of disabled channels specified (%d)\n", 3488 3491 num_disabled); 3489 3492 return -EINVAL; ··· 3494 3497 num_disabled); 3495 3498 pdata->disabled_channels[num_disabled] = -1; 3496 3499 3497 - pdev->dev.platform_data = pdata; 3500 + dev->platform_data = pdata; 3498 3501 3499 3502 return 0; 3500 3503 } 3501 3504 3502 3505 static int __init d40_probe(struct platform_device *pdev) 3503 3506 { 3504 - struct stedma40_platform_data *plat_data = dev_get_platdata(&pdev->dev); 3507 + struct device *dev = &pdev->dev; 3505 3508 struct device_node *np = pdev->dev.of_node; 3506 - int ret = -ENOENT; 3509 + struct device_node *np_lcpa; 3507 3510 struct d40_base *base; 3508 3511 struct resource *res; 3512 + struct resource res_lcpa; 3509 3513 int num_reserved_chans; 3510 3514 u32 val; 3515 + int ret; 3511 3516 3512 - if (!plat_data) { 3513 - if (np) { 3514 - if (d40_of_probe(pdev, np)) { 3515 - ret = -ENOMEM; 3516 - goto report_failure; 3517 - } 3518 - } else { 3519 - d40_err(&pdev->dev, "No pdata or Device Tree provided\n"); 3520 - goto report_failure; 3521 - } 3517 + if (d40_of_probe(dev, np)) { 3518 + ret = -ENOMEM; 3519 + goto report_failure; 3522 3520 } 3523 3521 3524 - base = d40_hw_detect_init(pdev); 3525 - if (!base) 3522 + ret = d40_hw_detect_init(pdev, &base); 3523 + if (ret) 3526 3524 goto report_failure; 3527 3525 3528 3526 num_reserved_chans = d40_phy_res_init(base); ··· 3527 3535 spin_lock_init(&base->interrupt_lock); 3528 3536 spin_lock_init(&base->execmd_lock); 3529 3537 3530 - /* Get IO for logical channel parameter address */ 3531 - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lcpa"); 3532 - if (!res) { 3533 - ret = -ENOENT; 3534 - d40_err(&pdev->dev, "No \"lcpa\" memory resource\n"); 3535 - goto destroy_cache; 3538 + /* Get IO for logical channel parameter address (LCPA) */ 3539 + np_lcpa = of_parse_phandle(np, "sram", 0); 3540 + if (!np_lcpa) { 3541 + dev_err(dev, "no LCPA SRAM node\n"); 3542 + ret = -EINVAL; 3543 + goto report_failure; 3536 3544 } 3537 - base->lcpa_size = resource_size(res); 3538 - base->phy_lcpa = res->start; 3539 - 3540 - if (request_mem_region(res->start, resource_size(res), 3541 - D40_NAME " I/O lcpa") == NULL) { 3542 - ret = -EBUSY; 3543 - d40_err(&pdev->dev, "Failed to request LCPA region %pR\n", res); 3544 - goto destroy_cache; 3545 + /* This is no device so read the address directly from the node */ 3546 + ret = of_address_to_resource(np_lcpa, 0, &res_lcpa); 3547 + if (ret) { 3548 + dev_err(dev, "no LCPA SRAM resource\n"); 3549 + goto report_failure; 3545 3550 } 3551 + base->lcpa_size = resource_size(&res_lcpa); 3552 + base->phy_lcpa = res_lcpa.start; 3553 + dev_info(dev, "found LCPA SRAM at %pad, size %pa\n", 3554 + &base->phy_lcpa, &base->lcpa_size); 3546 3555 3547 3556 /* We make use of ESRAM memory for this. */ 3548 3557 val = readl(base->virtbase + D40_DREG_LCPA); 3549 - if (res->start != val && val != 0) { 3550 - dev_warn(&pdev->dev, 3551 - "[%s] Mismatch LCPA dma 0x%x, def %pa\n", 3552 - __func__, val, &res->start); 3558 + if (base->phy_lcpa != val && val != 0) { 3559 + dev_warn(dev, 3560 + "[%s] Mismatch LCPA dma 0x%x, def %08x\n", 3561 + __func__, val, (u32)base->phy_lcpa); 3553 3562 } else 3554 - writel(res->start, base->virtbase + D40_DREG_LCPA); 3563 + writel(base->phy_lcpa, base->virtbase + D40_DREG_LCPA); 3555 3564 3556 - base->lcpa_base = ioremap(res->start, resource_size(res)); 3565 + base->lcpa_base = devm_ioremap(dev, base->phy_lcpa, base->lcpa_size); 3557 3566 if (!base->lcpa_base) { 3558 3567 ret = -ENOMEM; 3559 - d40_err(&pdev->dev, "Failed to ioremap LCPA region\n"); 3560 - goto destroy_cache; 3568 + d40_err(dev, "Failed to ioremap LCPA region\n"); 3569 + goto report_failure; 3561 3570 } 3562 3571 /* If lcla has to be located in ESRAM we don't need to allocate */ 3563 3572 if (base->plat_data->use_esram_lcla) { ··· 3566 3573 "lcla_esram"); 3567 3574 if (!res) { 3568 3575 ret = -ENOENT; 3569 - d40_err(&pdev->dev, 3576 + d40_err(dev, 3570 3577 "No \"lcla_esram\" memory resource\n"); 3571 - goto destroy_cache; 3578 + goto report_failure; 3572 3579 } 3573 - base->lcla_pool.base = ioremap(res->start, 3574 - resource_size(res)); 3580 + base->lcla_pool.base = devm_ioremap(dev, res->start, 3581 + resource_size(res)); 3575 3582 if (!base->lcla_pool.base) { 3576 3583 ret = -ENOMEM; 3577 - d40_err(&pdev->dev, "Failed to ioremap LCLA region\n"); 3578 - goto destroy_cache; 3584 + d40_err(dev, "Failed to ioremap LCLA region\n"); 3585 + goto report_failure; 3579 3586 } 3580 3587 writel(res->start, base->virtbase + D40_DREG_LCLA); 3581 3588 3582 3589 } else { 3583 3590 ret = d40_lcla_allocate(base); 3584 3591 if (ret) { 3585 - d40_err(&pdev->dev, "Failed to allocate LCLA area\n"); 3592 + d40_err(dev, "Failed to allocate LCLA area\n"); 3586 3593 goto destroy_cache; 3587 3594 } 3588 3595 } ··· 3593 3600 3594 3601 ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base); 3595 3602 if (ret) { 3596 - d40_err(&pdev->dev, "No IRQ defined\n"); 3603 + d40_err(dev, "No IRQ defined\n"); 3597 3604 goto destroy_cache; 3598 3605 } 3599 3606 ··· 3601 3608 3602 3609 base->lcpa_regulator = regulator_get(base->dev, "lcla_esram"); 3603 3610 if (IS_ERR(base->lcpa_regulator)) { 3604 - d40_err(&pdev->dev, "Failed to get lcpa_regulator\n"); 3611 + d40_err(dev, "Failed to get lcpa_regulator\n"); 3605 3612 ret = PTR_ERR(base->lcpa_regulator); 3606 3613 base->lcpa_regulator = NULL; 3607 3614 goto destroy_cache; ··· 3609 3616 3610 3617 ret = regulator_enable(base->lcpa_regulator); 3611 3618 if (ret) { 3612 - d40_err(&pdev->dev, 3619 + d40_err(dev, 3613 3620 "Failed to enable lcpa_regulator\n"); 3614 3621 regulator_put(base->lcpa_regulator); 3615 3622 base->lcpa_regulator = NULL; ··· 3632 3639 3633 3640 ret = dma_set_max_seg_size(base->dev, STEDMA40_MAX_SEG_SIZE); 3634 3641 if (ret) { 3635 - d40_err(&pdev->dev, "Failed to set dma max seg size\n"); 3642 + d40_err(dev, "Failed to set dma max seg size\n"); 3636 3643 goto destroy_cache; 3637 3644 } 3638 3645 3639 3646 d40_hw_init(base); 3640 3647 3641 - if (np) { 3642 - ret = of_dma_controller_register(np, d40_xlate, NULL); 3643 - if (ret) 3644 - dev_err(&pdev->dev, 3645 - "could not register of_dma_controller\n"); 3648 + ret = of_dma_controller_register(np, d40_xlate, NULL); 3649 + if (ret) { 3650 + dev_err(dev, 3651 + "could not register of_dma_controller\n"); 3652 + goto destroy_cache; 3646 3653 } 3647 3654 3648 3655 dev_info(base->dev, "initialized\n"); 3649 3656 return 0; 3657 + 3650 3658 destroy_cache: 3651 - kmem_cache_destroy(base->desc_slab); 3652 - if (base->virtbase) 3653 - iounmap(base->virtbase); 3654 - 3655 - if (base->lcla_pool.base && base->plat_data->use_esram_lcla) { 3656 - iounmap(base->lcla_pool.base); 3657 - base->lcla_pool.base = NULL; 3658 - } 3659 - 3660 3659 if (base->lcla_pool.dma_addr) 3661 3660 dma_unmap_single(base->dev, base->lcla_pool.dma_addr, 3662 3661 SZ_1K * base->num_phy_chans, ··· 3660 3675 3661 3676 kfree(base->lcla_pool.base_unaligned); 3662 3677 3663 - if (base->lcpa_base) 3664 - iounmap(base->lcpa_base); 3665 - 3666 - if (base->phy_lcpa) 3667 - release_mem_region(base->phy_lcpa, 3668 - base->lcpa_size); 3669 - if (base->phy_start) 3670 - release_mem_region(base->phy_start, 3671 - base->phy_size); 3672 - if (base->clk) { 3673 - clk_disable_unprepare(base->clk); 3674 - clk_put(base->clk); 3675 - } 3676 - 3677 3678 if (base->lcpa_regulator) { 3678 3679 regulator_disable(base->lcpa_regulator); 3679 3680 regulator_put(base->lcpa_regulator); 3680 3681 } 3681 3682 3682 - kfree(base->lcla_pool.alloc_map); 3683 - kfree(base->lookup_log_chans); 3684 - kfree(base->lookup_phy_chans); 3685 - kfree(base->phy_res); 3686 - kfree(base); 3687 3683 report_failure: 3688 - d40_err(&pdev->dev, "probe failed\n"); 3684 + d40_err(dev, "probe failed\n"); 3689 3685 return ret; 3690 3686 } 3691 3687
+2 -1
drivers/dma/ste_dma40_ll.c
··· 6 6 */ 7 7 8 8 #include <linux/kernel.h> 9 - #include <linux/platform_data/dma-ste-dma40.h> 9 + #include <linux/dmaengine.h> 10 10 11 + #include "ste_dma40.h" 11 12 #include "ste_dma40_ll.h" 12 13 13 14 static u8 d40_width_to_bits(enum dma_slave_buswidth width)
+11
drivers/dma/ti/k3-psil-j721s2.c
··· 99 99 PSIL_PDMA_XY_PKT(0x461d), 100 100 PSIL_PDMA_XY_PKT(0x461e), 101 101 PSIL_PDMA_XY_PKT(0x461f), 102 + /* MAIN_CPSW2G */ 103 + PSIL_ETHERNET(0x4640), 102 104 /* PDMA_USART_G0 - UART0-1 */ 103 105 PSIL_PDMA_XY_PKT(0x4700), 104 106 PSIL_PDMA_XY_PKT(0x4701), ··· 163 161 PSIL_ETHERNET(0xf005), 164 162 PSIL_ETHERNET(0xf006), 165 163 PSIL_ETHERNET(0xf007), 164 + /* MAIN_CPSW2G */ 165 + PSIL_ETHERNET(0xc640), 166 + PSIL_ETHERNET(0xc641), 167 + PSIL_ETHERNET(0xc642), 168 + PSIL_ETHERNET(0xc643), 169 + PSIL_ETHERNET(0xc644), 170 + PSIL_ETHERNET(0xc645), 171 + PSIL_ETHERNET(0xc646), 172 + PSIL_ETHERNET(0xc647), 166 173 /* SA2UL */ 167 174 PSIL_SA2UL(0xf500, 1), 168 175 PSIL_SA2UL(0xf501, 1),
+25
drivers/dma/ti/k3-udma.c
··· 4308 4308 }, 4309 4309 }; 4310 4310 4311 + static struct udma_soc_data j721s2_bcdma_csi_soc_data = { 4312 + .oes = { 4313 + .bcdma_tchan_data = 0x800, 4314 + .bcdma_tchan_ring = 0xa00, 4315 + .bcdma_rchan_data = 0xe00, 4316 + .bcdma_rchan_ring = 0x1000, 4317 + }, 4318 + }; 4319 + 4311 4320 static struct udma_match_data am62a_bcdma_csirx_data = { 4312 4321 .type = DMA_TYPE_BCDMA, 4313 4322 .psil_base = 0x3100, ··· 4355 4346 }, 4356 4347 }; 4357 4348 4349 + static struct udma_match_data j721s2_bcdma_csi_data = { 4350 + .type = DMA_TYPE_BCDMA, 4351 + .psil_base = 0x2000, 4352 + .enable_memcpy_support = false, 4353 + .burst_size = { 4354 + TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */ 4355 + 0, /* No H Channels */ 4356 + 0, /* No UH Channels */ 4357 + }, 4358 + .soc_data = &j721s2_bcdma_csi_soc_data, 4359 + }; 4360 + 4358 4361 static const struct of_device_id udma_of_match[] = { 4359 4362 { 4360 4363 .compatible = "ti,am654-navss-main-udmap", ··· 4393 4372 { 4394 4373 .compatible = "ti,am62a-dmss-bcdma-csirx", 4395 4374 .data = &am62a_bcdma_csirx_data, 4375 + }, 4376 + { 4377 + .compatible = "ti,j721s2-dmss-bcdma-csi", 4378 + .data = &j721s2_bcdma_csi_data, 4396 4379 }, 4397 4380 { /* Sentinel */ }, 4398 4381 };
+1 -1
drivers/pci/controller/dwc/pcie-designware.c
··· 834 834 return platform_get_irq_byname_optional(pdev, name); 835 835 } 836 836 837 - static struct dw_edma_core_ops dw_pcie_edma_ops = { 837 + static struct dw_edma_plat_ops dw_pcie_edma_ops = { 838 838 .irq_vector = dw_pcie_edma_irq_vector, 839 839 }; 840 840
+4 -3
include/linux/dma/edma.h
··· 40 40 * iATU windows. That will be done by the controller 41 41 * automatically. 42 42 */ 43 - struct dw_edma_core_ops { 43 + struct dw_edma_plat_ops { 44 44 int (*irq_vector)(struct device *dev, unsigned int nr); 45 45 u64 (*pci_address)(struct device *dev, phys_addr_t cpu_addr); 46 46 }; ··· 48 48 enum dw_edma_map_format { 49 49 EDMA_MF_EDMA_LEGACY = 0x0, 50 50 EDMA_MF_EDMA_UNROLL = 0x1, 51 - EDMA_MF_HDMA_COMPAT = 0x5 51 + EDMA_MF_HDMA_COMPAT = 0x5, 52 + EDMA_MF_HDMA_NATIVE = 0x7, 52 53 }; 53 54 54 55 /** ··· 81 80 struct dw_edma_chip { 82 81 struct device *dev; 83 82 int nr_irqs; 84 - const struct dw_edma_core_ops *ops; 83 + const struct dw_edma_plat_ops *ops; 85 84 u32 flags; 86 85 87 86 void __iomem *reg_base;
+1 -100
include/linux/platform_data/dma-ste-dma40.h drivers/dma/ste_dma40.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson SA 2007-2010 4 - * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson 5 - * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson 6 - */ 7 - 8 2 9 3 #ifndef STE_DMA40_H 10 4 #define STE_DMA40_H 11 - 12 - #include <linux/dmaengine.h> 13 - #include <linux/scatterlist.h> 14 - #include <linux/workqueue.h> 15 - #include <linux/interrupt.h> 16 5 17 6 /* 18 7 * Maxium size for a single dma descriptor ··· 107 118 int phy_channel; 108 119 }; 109 120 110 - /** 111 - * struct stedma40_platform_data - Configuration struct for the dma device. 112 - * 113 - * @dev_tx: mapping between destination event line and io address 114 - * @dev_rx: mapping between source event line and io address 115 - * @disabled_channels: A vector, ending with -1, that marks physical channels 116 - * that are for different reasons not available for the driver. 117 - * @soft_lli_chans: A vector, that marks physical channels will use LLI by SW 118 - * which avoids HW bug that exists in some versions of the controller. 119 - * SoftLLI introduces relink overhead that could impact performace for 120 - * certain use cases. 121 - * @num_of_soft_lli_chans: The number of channels that needs to be configured 122 - * to use SoftLLI. 123 - * @use_esram_lcla: flag for mapping the lcla into esram region 124 - * @num_of_memcpy_chans: The number of channels reserved for memcpy. 125 - * @num_of_phy_chans: The number of physical channels implemented in HW. 126 - * 0 means reading the number of channels from DMA HW but this is only valid 127 - * for 'multiple of 4' channels, like 8. 128 - */ 129 - struct stedma40_platform_data { 130 - int disabled_channels[STEDMA40_MAX_PHYS]; 131 - int *soft_lli_chans; 132 - int num_of_soft_lli_chans; 133 - bool use_esram_lcla; 134 - int num_of_memcpy_chans; 135 - int num_of_phy_chans; 136 - }; 137 - 138 - #ifdef CONFIG_STE_DMA40 139 - 140 - /** 141 - * stedma40_filter() - Provides stedma40_chan_cfg to the 142 - * ste_dma40 dma driver via the dmaengine framework. 143 - * does some checking of what's provided. 144 - * 145 - * Never directly called by client. It used by dmaengine. 146 - * @chan: dmaengine handle. 147 - * @data: Must be of type: struct stedma40_chan_cfg and is 148 - * the configuration of the framework. 149 - * 150 - * 151 - */ 152 - 153 - bool stedma40_filter(struct dma_chan *chan, void *data); 154 - 155 - /** 156 - * stedma40_slave_mem() - Transfers a raw data buffer to or from a slave 157 - * (=device) 158 - * 159 - * @chan: dmaengine handle 160 - * @addr: source or destination physicall address. 161 - * @size: bytes to transfer 162 - * @direction: direction of transfer 163 - * @flags: is actually enum dma_ctrl_flags. See dmaengine.h 164 - */ 165 - 166 - static inline struct 167 - dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, 168 - dma_addr_t addr, 169 - unsigned int size, 170 - enum dma_transfer_direction direction, 171 - unsigned long flags) 172 - { 173 - struct scatterlist sg; 174 - sg_init_table(&sg, 1); 175 - sg.dma_address = addr; 176 - sg.length = size; 177 - 178 - return dmaengine_prep_slave_sg(chan, &sg, 1, direction, flags); 179 - } 180 - 181 - #else 182 - static inline bool stedma40_filter(struct dma_chan *chan, void *data) 183 - { 184 - return false; 185 - } 186 - 187 - static inline struct 188 - dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, 189 - dma_addr_t addr, 190 - unsigned int size, 191 - enum dma_transfer_direction direction, 192 - unsigned long flags) 193 - { 194 - return NULL; 195 - } 196 - #endif 197 - 198 - #endif 121 + #endif /* STE_DMA40_H */