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.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine

Pull dmaengine updates from Vinod Koul:
"Unusually, more new driver and device support than updates. Couple of
new device support, AMD, Rcar, Intel and New drivers in Freescale,
Loonsoon, AMD and LPC32XX with DT conversion and mode updates etc.

New support:
- Support for AMD Versal Gen 2 DMA IP
- Rcar RZ/G3S SoC dma controller
- Support for Intel Diamond Rapids and Granite Rapids-D dma controllers
- Support for Freescale ls1021a-qdma controller
- New driver for Loongson-1 APB DMA
- New driver for AMD QDMA
- Pl08x in LPC32XX router dma driver

Updates:
- Support for dpdma cyclic dma mode
- XML conversion for marvell xor dma bindings
- Dma clocks documentation for imx dma"

* tag 'dmaengine-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (24 commits)
dmaengine: loongson1-apb-dma: Fix the build warning caused by the size of pdev_irqname
dmaengine: Fix spelling mistakes
dmaengine: Add dma router for pl08x in LPC32XX SoC
dmaengine: fsl-edma: add edma src ID check at request channel
dmaengine: fsl-edma: change to guard(mutex) within fsl_edma3_xlate()
dmaengine: avoid non-constant format string
dmaengine: imx-dma: Remove i.MX21 support
dt-bindings: dma: fsl,imx-dma: Document the DMA clocks
dmaengine: Loongson1: Add Loongson-1 APB DMA driver
dt-bindings: dma: Add Loongson-1 APB DMA
dmaengine: zynqmp_dma: Add support for AMD Versal Gen 2 DMA IP
dt-bindings: dmaengine: zynqmp_dma: Add a new compatible string
dmaengine: idxd: Add new DSA and IAA device IDs for Diamond Rapids platform
dmaengine: idxd: Add a new DSA device ID for Granite Rapids-D platform
dmaengine: ti: k3-udma: Remove unused declarations
dmaengine: amd: qdma: Add AMD QDMA driver
dmaengine: xilinx: dpdma: Add support for cyclic dma mode
dma: ipu: Remove include/linux/dma/ipu-dma.h
dt-bindings: dma: fsl-mxs-dma: Add compatible string "fsl,imx8qxp-dma-apbh"
dt-bindings: fsl-qdma: allow compatible string fallback to fsl,ls1021a-qdma
...

+2791 -275
+14
Documentation/devicetree/bindings/dma/fsl,imx-dma.yaml
··· 28 28 - description: DMA Error interrupt 29 29 minItems: 1 30 30 31 + clocks: 32 + maxItems: 2 33 + 34 + clock-names: 35 + items: 36 + - const: ipg 37 + - const: ahb 38 + 31 39 "#dma-cells": 32 40 const: 1 33 41 ··· 50 42 - reg 51 43 - interrupts 52 44 - "#dma-cells" 45 + - clocks 46 + - clock-names 53 47 54 48 additionalProperties: false 55 49 56 50 examples: 57 51 - | 52 + #include <dt-bindings/clock/imx27-clock.h> 53 + 58 54 dma-controller@10001000 { 59 55 compatible = "fsl,imx27-dma"; 60 56 reg = <0x10001000 0x1000>; 61 57 interrupts = <32 33>; 62 58 #dma-cells = <1>; 63 59 dma-channels = <16>; 60 + clocks = <&clks IMX27_CLK_DMA_IPG_GATE>, <&clks IMX27_CLK_DMA_AHB_GATE>; 61 + clock-names = "ipg", "ahb"; 64 62 };
+15
Documentation/devicetree/bindings/dma/fsl,mxs-dma.yaml
··· 11 11 12 12 allOf: 13 13 - $ref: dma-controller.yaml# 14 + - if: 15 + properties: 16 + compatible: 17 + contains: 18 + const: fsl,imx8qxp-dma-apbh 19 + then: 20 + required: 21 + - power-domains 22 + else: 23 + properties: 24 + power-domains: false 14 25 15 26 properties: 16 27 compatible: ··· 31 20 - fsl,imx6q-dma-apbh 32 21 - fsl,imx6sx-dma-apbh 33 22 - fsl,imx7d-dma-apbh 23 + - fsl,imx8qxp-dma-apbh 34 24 - const: fsl,imx28-dma-apbh 35 25 - enum: 36 26 - fsl,imx23-dma-apbh ··· 53 41 54 42 dma-channels: 55 43 enum: [4, 8, 16] 44 + 45 + power-domains: 46 + maxItems: 1 56 47 57 48 required: 58 49 - compatible
+8 -5
Documentation/devicetree/bindings/dma/fsl-qdma.yaml
··· 11 11 12 12 properties: 13 13 compatible: 14 - enum: 15 - - fsl,ls1021a-qdma 16 - - fsl,ls1028a-qdma 17 - - fsl,ls1043a-qdma 18 - - fsl,ls1046a-qdma 14 + oneOf: 15 + - const: fsl,ls1021a-qdma 16 + - items: 17 + - enum: 18 + - fsl,ls1028a-qdma 19 + - fsl,ls1043a-qdma 20 + - fsl,ls1046a-qdma 21 + - const: fsl,ls1021a-qdma 19 22 20 23 reg: 21 24 items:
+65
Documentation/devicetree/bindings/dma/loongson,ls1b-apbdma.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/dma/loongson,ls1b-apbdma.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Loongson-1 APB DMA Controller 8 + 9 + maintainers: 10 + - Keguang Zhang <keguang.zhang@gmail.com> 11 + 12 + description: 13 + Loongson-1 APB DMA controller provides 3 independent channels for 14 + peripherals such as NAND, audio playback and capture. 15 + 16 + properties: 17 + compatible: 18 + oneOf: 19 + - const: loongson,ls1b-apbdma 20 + - items: 21 + - enum: 22 + - loongson,ls1a-apbdma 23 + - loongson,ls1c-apbdma 24 + - const: loongson,ls1b-apbdma 25 + 26 + reg: 27 + maxItems: 1 28 + 29 + interrupts: 30 + items: 31 + - description: NAND interrupt 32 + - description: Audio playback interrupt 33 + - description: Audio capture interrupt 34 + 35 + interrupt-names: 36 + items: 37 + - const: ch0 38 + - const: ch1 39 + - const: ch2 40 + 41 + '#dma-cells': 42 + const: 1 43 + 44 + required: 45 + - compatible 46 + - reg 47 + - interrupts 48 + - interrupt-names 49 + - '#dma-cells' 50 + 51 + additionalProperties: false 52 + 53 + examples: 54 + - | 55 + #include <dt-bindings/interrupt-controller/irq.h> 56 + dma-controller@1fd01160 { 57 + compatible = "loongson,ls1b-apbdma"; 58 + reg = <0x1fd01160 0x4>; 59 + interrupt-parent = <&intc0>; 60 + interrupts = <13 IRQ_TYPE_EDGE_RISING>, 61 + <14 IRQ_TYPE_EDGE_RISING>, 62 + <15 IRQ_TYPE_EDGE_RISING>; 63 + interrupt-names = "ch0", "ch1", "ch2"; 64 + #dma-cells = <1>; 65 + };
+61
Documentation/devicetree/bindings/dma/marvell,xor-v2.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/dma/marvell,xor-v2.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Marvell XOR v2 engines 8 + 9 + maintainers: 10 + - Andrew Lunn <andrew@lunn.ch> 11 + 12 + properties: 13 + compatible: 14 + oneOf: 15 + - const: marvell,xor-v2 16 + - items: 17 + - enum: 18 + - marvell,armada-7k-xor 19 + - const: marvell,xor-v2 20 + 21 + reg: 22 + items: 23 + - description: DMA registers 24 + - description: global registers 25 + 26 + clocks: 27 + minItems: 1 28 + maxItems: 2 29 + 30 + clock-names: 31 + minItems: 1 32 + items: 33 + - const: core 34 + - const: reg 35 + 36 + msi-parent: 37 + description: 38 + Phandle to the MSI-capable interrupt controller used for 39 + interrupts. 40 + maxItems: 1 41 + 42 + dma-coherent: true 43 + 44 + required: 45 + - compatible 46 + - reg 47 + - msi-parent 48 + - dma-coherent 49 + 50 + additionalProperties: false 51 + 52 + examples: 53 + - | 54 + xor0@6a0000 { 55 + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; 56 + reg = <0x6a0000 0x1000>, <0x6b0000 0x1000>; 57 + clocks = <&ap_clk 0>, <&ap_clk 1>; 58 + clock-names = "core", "reg"; 59 + msi-parent = <&gic_v2m0>; 60 + dma-coherent; 61 + };
-28
Documentation/devicetree/bindings/dma/mv-xor-v2.txt
··· 1 - * Marvell XOR v2 engines 2 - 3 - Required properties: 4 - - compatible: one of the following values: 5 - "marvell,armada-7k-xor" 6 - "marvell,xor-v2" 7 - - reg: Should contain registers location and length (two sets) 8 - the first set is the DMA registers 9 - the second set is the global registers 10 - - msi-parent: Phandle to the MSI-capable interrupt controller used for 11 - interrupts. 12 - 13 - Optional properties: 14 - - clocks: Optional reference to the clocks used by the XOR engine. 15 - - clock-names: mandatory if there is a second clock, in this case the 16 - name must be "core" for the first clock and "reg" for the second 17 - one 18 - 19 - 20 - Example: 21 - 22 - xor0@400000 { 23 - compatible = "marvell,xor-v2"; 24 - reg = <0x400000 0x1000>, 25 - <0x410000 0x1000>; 26 - msi-parent = <&gic_v2m0>; 27 - dma-coherent; 28 - };
+1
Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
··· 19 19 - renesas,r9a07g043-dmac # RZ/G2UL and RZ/Five 20 20 - renesas,r9a07g044-dmac # RZ/G2{L,LC} 21 21 - renesas,r9a07g054-dmac # RZ/V2L 22 + - renesas,r9a08g045-dmac # RZ/G3S 22 23 - const: renesas,rz-dmac 23 24 24 25 reg:
+3 -1
Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml
··· 24 24 const: 1 25 25 26 26 compatible: 27 - const: xlnx,zynqmp-dma-1.0 27 + enum: 28 + - amd,versal2-dma-1.0 29 + - xlnx,zynqmp-dma-1.0 28 30 29 31 reg: 30 32 description: memory map for gdma/adma module access
+9
MAINTAINERS
··· 1147 1147 S: Maintained 1148 1148 F: drivers/dma/ptdma/ 1149 1149 1150 + AMD QDMA DRIVER 1151 + M: Nishad Saraf <nishads@amd.com> 1152 + M: Lizhi Hou <lizhi.hou@amd.com> 1153 + L: dmaengine@vger.kernel.org 1154 + S: Supported 1155 + F: drivers/dma/amd/qdma/ 1156 + F: include/linux/platform_data/amd_qdma.h 1157 + 1150 1158 AMD SEATTLE DEVICE TREE SUPPORT 1151 1159 M: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> 1152 1160 M: Tom Lendacky <thomas.lendacky@amd.com> ··· 2500 2492 F: Documentation/devicetree/bindings/i2c/nxp,pnx-i2c.yaml 2501 2493 F: arch/arm/boot/dts/nxp/lpc/lpc32* 2502 2494 F: arch/arm/mach-lpc32xx/ 2495 + F: drivers/dma/lpc32xx-dmamux.c 2503 2496 F: drivers/i2c/busses/i2c-pnx.c 2504 2497 F: drivers/net/ethernet/nxp/lpc_eth.c 2505 2498 F: drivers/usb/host/ohci-nxp.c
+1
arch/arm/mach-lpc32xx/Kconfig
··· 8 8 select CLKSRC_LPC32XX 9 9 select CPU_ARM926T 10 10 select GPIOLIB 11 + select LPC32XX_DMAMUX if AMBA_PL08X 11 12 help 12 13 Support for the NXP LPC32XX family of processors
+20
drivers/dma/Kconfig
··· 369 369 Support the DMA engine for Hisilicon K3 platform 370 370 devices. 371 371 372 + config LOONGSON1_APB_DMA 373 + tristate "Loongson1 APB DMA support" 374 + depends on MACH_LOONGSON32 || COMPILE_TEST 375 + select DMA_ENGINE 376 + select DMA_VIRTUAL_CHANNELS 377 + help 378 + This selects support for the APB DMA controller in Loongson1 SoCs, 379 + which is required by Loongson1 NAND and audio support. 380 + 372 381 config LPC18XX_DMAMUX 373 382 bool "NXP LPC18xx/43xx DMA MUX for PL080" 374 383 depends on ARCH_LPC18XX || COMPILE_TEST ··· 386 377 help 387 378 Enable support for DMA on NXP LPC18xx/43xx platforms 388 379 with PL080 and multiplexed DMA request lines. 380 + 381 + config LPC32XX_DMAMUX 382 + bool "NXP LPC32xx DMA MUX for PL080" 383 + depends on ARCH_LPC32XX || COMPILE_TEST 384 + depends on OF && AMBA_PL08X 385 + select MFD_SYSCON 386 + help 387 + Support for PL080 multiplexed DMA request lines on 388 + LPC32XX platrofm. 389 389 390 390 config LS2X_APB_DMA 391 391 tristate "Loongson LS2X APB DMA support" ··· 734 716 display driver. 735 717 736 718 # driver files 719 + source "drivers/dma/amd/Kconfig" 720 + 737 721 source "drivers/dma/bestcomm/Kconfig" 738 722 739 723 source "drivers/dma/mediatek/Kconfig"
+3
drivers/dma/Makefile
··· 49 49 obj-$(CONFIG_INTEL_IOATDMA) += ioat/ 50 50 obj-y += idxd/ 51 51 obj-$(CONFIG_K3_DMA) += k3dma.o 52 + obj-$(CONFIG_LOONGSON1_APB_DMA) += loongson1-apb-dma.o 52 53 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o 54 + obj-$(CONFIG_LPC32XX_DMAMUX) += lpc32xx-dmamux.o 53 55 obj-$(CONFIG_LS2X_APB_DMA) += ls2x-apb-dma.o 54 56 obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o 55 57 obj-$(CONFIG_MILBEAUT_XDMAC) += milbeaut-xdmac.o ··· 85 83 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/ 86 84 obj-$(CONFIG_INTEL_LDMA) += lgm/ 87 85 86 + obj-y += amd/ 88 87 obj-y += mediatek/ 89 88 obj-y += qcom/ 90 89 obj-y += stm32/
+2 -2
drivers/dma/acpi-dma.c
··· 112 112 } 113 113 114 114 /** 115 - * acpi_dma_parse_csrt - parse CSRT to exctract additional DMA resources 115 + * acpi_dma_parse_csrt - parse CSRT to extract additional DMA resources 116 116 * @adev: ACPI device to match with 117 117 * @adma: struct acpi_dma of the given DMA controller 118 118 * ··· 305 305 * found. 306 306 * 307 307 * Return: 308 - * 0, if no information is avaiable, -1 on mismatch, and 1 otherwise. 308 + * 0, if no information is available, -1 on mismatch, and 1 otherwise. 309 309 */ 310 310 static int acpi_dma_update_dma_spec(struct acpi_dma *adma, 311 311 struct acpi_dma_spec *dma_spec)
+2 -2
drivers/dma/altera-msgdma.c
··· 153 153 /** 154 154 * struct msgdma_sw_desc - implements a sw descriptor 155 155 * @async_tx: support for the async_tx api 156 - * @hw_desc: assosiated HW descriptor 156 + * @hw_desc: associated HW descriptor 157 157 * @node: node to move from the free list to the tx list 158 158 * @tx_list: transmit list node 159 159 */ ··· 511 511 * of the DMA controller. The descriptor will get flushed to the 512 512 * FIFO, once the last word (control word) is written. Since we 513 513 * are not 100% sure that memcpy() writes all word in the "correct" 514 - * oder (address from low to high) on all architectures, we make 514 + * order (address from low to high) on all architectures, we make 515 515 * sure this control word is written last by single coding it and 516 516 * adding some write-barriers here. 517 517 */
+1 -1
drivers/dma/amba-pl08x.c
··· 2 2 /* 3 3 * Copyright (c) 2006 ARM Ltd. 4 4 * Copyright (c) 2010 ST-Ericsson SA 5 - * Copyirght (c) 2017 Linaro Ltd. 5 + * Copyright (c) 2017 Linaro Ltd. 6 6 * 7 7 * Author: Peter Pearse <peter.pearse@arm.com> 8 8 * Author: Linus Walleij <linus.walleij@linaro.org>
+14
drivers/dma/amd/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + 3 + config AMD_QDMA 4 + tristate "AMD Queue-based DMA" 5 + depends on HAS_IOMEM 6 + select DMA_ENGINE 7 + select DMA_VIRTUAL_CHANNELS 8 + select REGMAP_MMIO 9 + help 10 + Enable support for the AMD Queue-based DMA subsystem. The primary 11 + mechanism to transfer data using the QDMA is for the QDMA engine to 12 + operate on instructions (descriptors) provided by the host operating 13 + system. Using the descriptors, the QDMA can move data in either the 14 + Host to Card (H2C) direction or the Card to Host (C2H) direction.
+3
drivers/dma/amd/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + obj-$(CONFIG_AMD_QDMA) += qdma/
+5
drivers/dma/amd/qdma/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + obj-$(CONFIG_AMD_QDMA) += amd-qdma.o 4 + 5 + amd-qdma-$(CONFIG_AMD_QDMA) := qdma.o qdma-comm-regs.o
+64
drivers/dma/amd/qdma/qdma-comm-regs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (C) 2023-2024, Advanced Micro Devices, Inc. 4 + */ 5 + 6 + #ifndef __QDMA_REGS_DEF_H 7 + #define __QDMA_REGS_DEF_H 8 + 9 + #include "qdma.h" 10 + 11 + const struct qdma_reg qdma_regos_default[QDMA_REGO_MAX] = { 12 + [QDMA_REGO_CTXT_DATA] = QDMA_REGO(0x804, 8), 13 + [QDMA_REGO_CTXT_CMD] = QDMA_REGO(0x844, 1), 14 + [QDMA_REGO_CTXT_MASK] = QDMA_REGO(0x824, 8), 15 + [QDMA_REGO_MM_H2C_CTRL] = QDMA_REGO(0x1004, 1), 16 + [QDMA_REGO_MM_C2H_CTRL] = QDMA_REGO(0x1204, 1), 17 + [QDMA_REGO_QUEUE_COUNT] = QDMA_REGO(0x120, 1), 18 + [QDMA_REGO_RING_SIZE] = QDMA_REGO(0x204, 1), 19 + [QDMA_REGO_H2C_PIDX] = QDMA_REGO(0x18004, 1), 20 + [QDMA_REGO_C2H_PIDX] = QDMA_REGO(0x18008, 1), 21 + [QDMA_REGO_INTR_CIDX] = QDMA_REGO(0x18000, 1), 22 + [QDMA_REGO_FUNC_ID] = QDMA_REGO(0x12c, 1), 23 + [QDMA_REGO_ERR_INT] = QDMA_REGO(0xb04, 1), 24 + [QDMA_REGO_ERR_STAT] = QDMA_REGO(0x248, 1), 25 + }; 26 + 27 + const struct qdma_reg_field qdma_regfs_default[QDMA_REGF_MAX] = { 28 + /* QDMA_REGO_CTXT_DATA fields */ 29 + [QDMA_REGF_IRQ_ENABLE] = QDMA_REGF(53, 53), 30 + [QDMA_REGF_WBK_ENABLE] = QDMA_REGF(52, 52), 31 + [QDMA_REGF_WBI_CHECK] = QDMA_REGF(34, 34), 32 + [QDMA_REGF_IRQ_ARM] = QDMA_REGF(16, 16), 33 + [QDMA_REGF_IRQ_VEC] = QDMA_REGF(138, 128), 34 + [QDMA_REGF_IRQ_AGG] = QDMA_REGF(139, 139), 35 + [QDMA_REGF_WBI_INTVL_ENABLE] = QDMA_REGF(35, 35), 36 + [QDMA_REGF_MRKR_DISABLE] = QDMA_REGF(62, 62), 37 + [QDMA_REGF_QUEUE_ENABLE] = QDMA_REGF(32, 32), 38 + [QDMA_REGF_QUEUE_MODE] = QDMA_REGF(63, 63), 39 + [QDMA_REGF_DESC_BASE] = QDMA_REGF(127, 64), 40 + [QDMA_REGF_DESC_SIZE] = QDMA_REGF(49, 48), 41 + [QDMA_REGF_RING_ID] = QDMA_REGF(47, 44), 42 + [QDMA_REGF_QUEUE_BASE] = QDMA_REGF(11, 0), 43 + [QDMA_REGF_QUEUE_MAX] = QDMA_REGF(44, 32), 44 + [QDMA_REGF_FUNCTION_ID] = QDMA_REGF(24, 17), 45 + [QDMA_REGF_INTR_AGG_BASE] = QDMA_REGF(66, 15), 46 + [QDMA_REGF_INTR_VECTOR] = QDMA_REGF(11, 1), 47 + [QDMA_REGF_INTR_SIZE] = QDMA_REGF(69, 67), 48 + [QDMA_REGF_INTR_VALID] = QDMA_REGF(0, 0), 49 + [QDMA_REGF_INTR_COLOR] = QDMA_REGF(14, 14), 50 + [QDMA_REGF_INTR_FUNCTION_ID] = QDMA_REGF(125, 114), 51 + /* QDMA_REGO_CTXT_CMD fields */ 52 + [QDMA_REGF_CMD_INDX] = QDMA_REGF(19, 7), 53 + [QDMA_REGF_CMD_CMD] = QDMA_REGF(6, 5), 54 + [QDMA_REGF_CMD_TYPE] = QDMA_REGF(4, 1), 55 + [QDMA_REGF_CMD_BUSY] = QDMA_REGF(0, 0), 56 + /* QDMA_REGO_QUEUE_COUNT fields */ 57 + [QDMA_REGF_QUEUE_COUNT] = QDMA_REGF(11, 0), 58 + /* QDMA_REGO_ERR_INT fields */ 59 + [QDMA_REGF_ERR_INT_FUNC] = QDMA_REGF(11, 0), 60 + [QDMA_REGF_ERR_INT_VEC] = QDMA_REGF(22, 12), 61 + [QDMA_REGF_ERR_INT_ARM] = QDMA_REGF(24, 24), 62 + }; 63 + 64 + #endif /* __QDMA_REGS_DEF_H */
+1143
drivers/dma/amd/qdma/qdma.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * DMA driver for AMD Queue-based DMA Subsystem 4 + * 5 + * Copyright (C) 2023-2024, Advanced Micro Devices, Inc. 6 + */ 7 + #include <linux/bitfield.h> 8 + #include <linux/bitops.h> 9 + #include <linux/dmaengine.h> 10 + #include <linux/module.h> 11 + #include <linux/mod_devicetable.h> 12 + #include <linux/dma-map-ops.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/platform_data/amd_qdma.h> 15 + #include <linux/regmap.h> 16 + 17 + #include "qdma.h" 18 + 19 + #define CHAN_STR(q) (((q)->dir == DMA_MEM_TO_DEV) ? "H2C" : "C2H") 20 + #define QDMA_REG_OFF(d, r) ((d)->roffs[r].off) 21 + 22 + /* MMIO regmap config for all QDMA registers */ 23 + static const struct regmap_config qdma_regmap_config = { 24 + .reg_bits = 32, 25 + .val_bits = 32, 26 + .reg_stride = 4, 27 + }; 28 + 29 + static inline struct qdma_queue *to_qdma_queue(struct dma_chan *chan) 30 + { 31 + return container_of(chan, struct qdma_queue, vchan.chan); 32 + } 33 + 34 + static inline struct qdma_mm_vdesc *to_qdma_vdesc(struct virt_dma_desc *vdesc) 35 + { 36 + return container_of(vdesc, struct qdma_mm_vdesc, vdesc); 37 + } 38 + 39 + static inline u32 qdma_get_intr_ring_idx(struct qdma_device *qdev) 40 + { 41 + u32 idx; 42 + 43 + idx = qdev->qintr_rings[qdev->qintr_ring_idx++].ridx; 44 + qdev->qintr_ring_idx %= qdev->qintr_ring_num; 45 + 46 + return idx; 47 + } 48 + 49 + static u64 qdma_get_field(const struct qdma_device *qdev, const u32 *data, 50 + enum qdma_reg_fields field) 51 + { 52 + const struct qdma_reg_field *f = &qdev->rfields[field]; 53 + u16 low_pos, hi_pos, low_bit, hi_bit; 54 + u64 value = 0, mask; 55 + 56 + low_pos = f->lsb / BITS_PER_TYPE(*data); 57 + hi_pos = f->msb / BITS_PER_TYPE(*data); 58 + 59 + if (low_pos == hi_pos) { 60 + low_bit = f->lsb % BITS_PER_TYPE(*data); 61 + hi_bit = f->msb % BITS_PER_TYPE(*data); 62 + mask = GENMASK(hi_bit, low_bit); 63 + value = (data[low_pos] & mask) >> low_bit; 64 + } else if (hi_pos == low_pos + 1) { 65 + low_bit = f->lsb % BITS_PER_TYPE(*data); 66 + hi_bit = low_bit + (f->msb - f->lsb); 67 + value = ((u64)data[hi_pos] << BITS_PER_TYPE(*data)) | 68 + data[low_pos]; 69 + mask = GENMASK_ULL(hi_bit, low_bit); 70 + value = (value & mask) >> low_bit; 71 + } else { 72 + hi_bit = f->msb % BITS_PER_TYPE(*data); 73 + mask = GENMASK(hi_bit, 0); 74 + value = data[hi_pos] & mask; 75 + low_bit = f->msb - f->lsb - hi_bit; 76 + value <<= low_bit; 77 + low_bit -= 32; 78 + value |= (u64)data[hi_pos - 1] << low_bit; 79 + mask = GENMASK(31, 32 - low_bit); 80 + value |= (data[hi_pos - 2] & mask) >> low_bit; 81 + } 82 + 83 + return value; 84 + } 85 + 86 + static void qdma_set_field(const struct qdma_device *qdev, u32 *data, 87 + enum qdma_reg_fields field, u64 value) 88 + { 89 + const struct qdma_reg_field *f = &qdev->rfields[field]; 90 + u16 low_pos, hi_pos, low_bit; 91 + 92 + low_pos = f->lsb / BITS_PER_TYPE(*data); 93 + hi_pos = f->msb / BITS_PER_TYPE(*data); 94 + low_bit = f->lsb % BITS_PER_TYPE(*data); 95 + 96 + data[low_pos++] |= value << low_bit; 97 + if (low_pos <= hi_pos) 98 + data[low_pos++] |= (u32)(value >> (32 - low_bit)); 99 + if (low_pos <= hi_pos) 100 + data[low_pos] |= (u32)(value >> (64 - low_bit)); 101 + } 102 + 103 + static inline int qdma_reg_write(const struct qdma_device *qdev, 104 + const u32 *data, enum qdma_regs reg) 105 + { 106 + const struct qdma_reg *r = &qdev->roffs[reg]; 107 + int ret; 108 + 109 + if (r->count > 1) 110 + ret = regmap_bulk_write(qdev->regmap, r->off, data, r->count); 111 + else 112 + ret = regmap_write(qdev->regmap, r->off, *data); 113 + 114 + return ret; 115 + } 116 + 117 + static inline int qdma_reg_read(const struct qdma_device *qdev, u32 *data, 118 + enum qdma_regs reg) 119 + { 120 + const struct qdma_reg *r = &qdev->roffs[reg]; 121 + int ret; 122 + 123 + if (r->count > 1) 124 + ret = regmap_bulk_read(qdev->regmap, r->off, data, r->count); 125 + else 126 + ret = regmap_read(qdev->regmap, r->off, data); 127 + 128 + return ret; 129 + } 130 + 131 + static int qdma_context_cmd_execute(const struct qdma_device *qdev, 132 + enum qdma_ctxt_type type, 133 + enum qdma_ctxt_cmd cmd, u16 index) 134 + { 135 + u32 value = 0; 136 + int ret; 137 + 138 + qdma_set_field(qdev, &value, QDMA_REGF_CMD_INDX, index); 139 + qdma_set_field(qdev, &value, QDMA_REGF_CMD_CMD, cmd); 140 + qdma_set_field(qdev, &value, QDMA_REGF_CMD_TYPE, type); 141 + 142 + ret = qdma_reg_write(qdev, &value, QDMA_REGO_CTXT_CMD); 143 + if (ret) 144 + return ret; 145 + 146 + ret = regmap_read_poll_timeout(qdev->regmap, 147 + QDMA_REG_OFF(qdev, QDMA_REGO_CTXT_CMD), 148 + value, 149 + !qdma_get_field(qdev, &value, 150 + QDMA_REGF_CMD_BUSY), 151 + QDMA_POLL_INTRVL_US, 152 + QDMA_POLL_TIMEOUT_US); 153 + if (ret) { 154 + qdma_err(qdev, "Context command execution timed out"); 155 + return ret; 156 + } 157 + 158 + return 0; 159 + } 160 + 161 + static int qdma_context_write_data(const struct qdma_device *qdev, 162 + const u32 *data) 163 + { 164 + u32 mask[QDMA_CTXT_REGMAP_LEN]; 165 + int ret; 166 + 167 + memset(mask, ~0, sizeof(mask)); 168 + 169 + ret = qdma_reg_write(qdev, mask, QDMA_REGO_CTXT_MASK); 170 + if (ret) 171 + return ret; 172 + 173 + ret = qdma_reg_write(qdev, data, QDMA_REGO_CTXT_DATA); 174 + if (ret) 175 + return ret; 176 + 177 + return 0; 178 + } 179 + 180 + static void qdma_prep_sw_desc_context(const struct qdma_device *qdev, 181 + const struct qdma_ctxt_sw_desc *ctxt, 182 + u32 *data) 183 + { 184 + memset(data, 0, QDMA_CTXT_REGMAP_LEN * sizeof(*data)); 185 + qdma_set_field(qdev, data, QDMA_REGF_DESC_BASE, ctxt->desc_base); 186 + qdma_set_field(qdev, data, QDMA_REGF_IRQ_VEC, ctxt->vec); 187 + qdma_set_field(qdev, data, QDMA_REGF_FUNCTION_ID, qdev->fid); 188 + 189 + qdma_set_field(qdev, data, QDMA_REGF_DESC_SIZE, QDMA_DESC_SIZE_32B); 190 + qdma_set_field(qdev, data, QDMA_REGF_RING_ID, QDMA_DEFAULT_RING_ID); 191 + qdma_set_field(qdev, data, QDMA_REGF_QUEUE_MODE, QDMA_QUEUE_OP_MM); 192 + qdma_set_field(qdev, data, QDMA_REGF_IRQ_ENABLE, 1); 193 + qdma_set_field(qdev, data, QDMA_REGF_WBK_ENABLE, 1); 194 + qdma_set_field(qdev, data, QDMA_REGF_WBI_CHECK, 1); 195 + qdma_set_field(qdev, data, QDMA_REGF_IRQ_ARM, 1); 196 + qdma_set_field(qdev, data, QDMA_REGF_IRQ_AGG, 1); 197 + qdma_set_field(qdev, data, QDMA_REGF_WBI_INTVL_ENABLE, 1); 198 + qdma_set_field(qdev, data, QDMA_REGF_QUEUE_ENABLE, 1); 199 + qdma_set_field(qdev, data, QDMA_REGF_MRKR_DISABLE, 1); 200 + } 201 + 202 + static void qdma_prep_intr_context(const struct qdma_device *qdev, 203 + const struct qdma_ctxt_intr *ctxt, 204 + u32 *data) 205 + { 206 + memset(data, 0, QDMA_CTXT_REGMAP_LEN * sizeof(*data)); 207 + qdma_set_field(qdev, data, QDMA_REGF_INTR_AGG_BASE, ctxt->agg_base); 208 + qdma_set_field(qdev, data, QDMA_REGF_INTR_VECTOR, ctxt->vec); 209 + qdma_set_field(qdev, data, QDMA_REGF_INTR_SIZE, ctxt->size); 210 + qdma_set_field(qdev, data, QDMA_REGF_INTR_VALID, ctxt->valid); 211 + qdma_set_field(qdev, data, QDMA_REGF_INTR_COLOR, ctxt->color); 212 + qdma_set_field(qdev, data, QDMA_REGF_INTR_FUNCTION_ID, qdev->fid); 213 + } 214 + 215 + static void qdma_prep_fmap_context(const struct qdma_device *qdev, 216 + const struct qdma_ctxt_fmap *ctxt, 217 + u32 *data) 218 + { 219 + memset(data, 0, QDMA_CTXT_REGMAP_LEN * sizeof(*data)); 220 + qdma_set_field(qdev, data, QDMA_REGF_QUEUE_BASE, ctxt->qbase); 221 + qdma_set_field(qdev, data, QDMA_REGF_QUEUE_MAX, ctxt->qmax); 222 + } 223 + 224 + /* 225 + * Program the indirect context register space 226 + * 227 + * Once the queue is enabled, context is dynamically updated by hardware. Any 228 + * modification of the context through this API when the queue is enabled can 229 + * result in unexpected behavior. Reading the context when the queue is enabled 230 + * is not recommended as it can result in reduced performance. 231 + */ 232 + static int qdma_prog_context(struct qdma_device *qdev, enum qdma_ctxt_type type, 233 + enum qdma_ctxt_cmd cmd, u16 index, u32 *ctxt) 234 + { 235 + int ret; 236 + 237 + mutex_lock(&qdev->ctxt_lock); 238 + if (cmd == QDMA_CTXT_WRITE) { 239 + ret = qdma_context_write_data(qdev, ctxt); 240 + if (ret) 241 + goto failed; 242 + } 243 + 244 + ret = qdma_context_cmd_execute(qdev, type, cmd, index); 245 + if (ret) 246 + goto failed; 247 + 248 + if (cmd == QDMA_CTXT_READ) { 249 + ret = qdma_reg_read(qdev, ctxt, QDMA_REGO_CTXT_DATA); 250 + if (ret) 251 + goto failed; 252 + } 253 + 254 + failed: 255 + mutex_unlock(&qdev->ctxt_lock); 256 + 257 + return ret; 258 + } 259 + 260 + static int qdma_check_queue_status(struct qdma_device *qdev, 261 + enum dma_transfer_direction dir, u16 qid) 262 + { 263 + u32 status, data[QDMA_CTXT_REGMAP_LEN] = {0}; 264 + enum qdma_ctxt_type type; 265 + int ret; 266 + 267 + if (dir == DMA_MEM_TO_DEV) 268 + type = QDMA_CTXT_DESC_SW_H2C; 269 + else 270 + type = QDMA_CTXT_DESC_SW_C2H; 271 + ret = qdma_prog_context(qdev, type, QDMA_CTXT_READ, qid, data); 272 + if (ret) 273 + return ret; 274 + 275 + status = qdma_get_field(qdev, data, QDMA_REGF_QUEUE_ENABLE); 276 + if (status) { 277 + qdma_err(qdev, "queue %d already in use", qid); 278 + return -EBUSY; 279 + } 280 + 281 + return 0; 282 + } 283 + 284 + static int qdma_clear_queue_context(const struct qdma_queue *queue) 285 + { 286 + enum qdma_ctxt_type h2c_types[] = { QDMA_CTXT_DESC_SW_H2C, 287 + QDMA_CTXT_DESC_HW_H2C, 288 + QDMA_CTXT_DESC_CR_H2C, 289 + QDMA_CTXT_PFTCH, }; 290 + enum qdma_ctxt_type c2h_types[] = { QDMA_CTXT_DESC_SW_C2H, 291 + QDMA_CTXT_DESC_HW_C2H, 292 + QDMA_CTXT_DESC_CR_C2H, 293 + QDMA_CTXT_PFTCH, }; 294 + struct qdma_device *qdev = queue->qdev; 295 + enum qdma_ctxt_type *type; 296 + int ret, num, i; 297 + 298 + if (queue->dir == DMA_MEM_TO_DEV) { 299 + type = h2c_types; 300 + num = ARRAY_SIZE(h2c_types); 301 + } else { 302 + type = c2h_types; 303 + num = ARRAY_SIZE(c2h_types); 304 + } 305 + for (i = 0; i < num; i++) { 306 + ret = qdma_prog_context(qdev, type[i], QDMA_CTXT_CLEAR, 307 + queue->qid, NULL); 308 + if (ret) { 309 + qdma_err(qdev, "Failed to clear ctxt %d", type[i]); 310 + return ret; 311 + } 312 + } 313 + 314 + return 0; 315 + } 316 + 317 + static int qdma_setup_fmap_context(struct qdma_device *qdev) 318 + { 319 + u32 ctxt[QDMA_CTXT_REGMAP_LEN]; 320 + struct qdma_ctxt_fmap fmap; 321 + int ret; 322 + 323 + ret = qdma_prog_context(qdev, QDMA_CTXT_FMAP, QDMA_CTXT_CLEAR, 324 + qdev->fid, NULL); 325 + if (ret) { 326 + qdma_err(qdev, "Failed clearing context"); 327 + return ret; 328 + } 329 + 330 + fmap.qbase = 0; 331 + fmap.qmax = qdev->chan_num * 2; 332 + qdma_prep_fmap_context(qdev, &fmap, ctxt); 333 + ret = qdma_prog_context(qdev, QDMA_CTXT_FMAP, QDMA_CTXT_WRITE, 334 + qdev->fid, ctxt); 335 + if (ret) 336 + qdma_err(qdev, "Failed setup fmap, ret %d", ret); 337 + 338 + return ret; 339 + } 340 + 341 + static int qdma_setup_queue_context(struct qdma_device *qdev, 342 + const struct qdma_ctxt_sw_desc *sw_desc, 343 + enum dma_transfer_direction dir, u16 qid) 344 + { 345 + u32 ctxt[QDMA_CTXT_REGMAP_LEN]; 346 + enum qdma_ctxt_type type; 347 + int ret; 348 + 349 + if (dir == DMA_MEM_TO_DEV) 350 + type = QDMA_CTXT_DESC_SW_H2C; 351 + else 352 + type = QDMA_CTXT_DESC_SW_C2H; 353 + 354 + qdma_prep_sw_desc_context(qdev, sw_desc, ctxt); 355 + /* Setup SW descriptor context */ 356 + ret = qdma_prog_context(qdev, type, QDMA_CTXT_WRITE, qid, ctxt); 357 + if (ret) 358 + qdma_err(qdev, "Failed setup SW desc ctxt for queue: %d", qid); 359 + 360 + return ret; 361 + } 362 + 363 + /* 364 + * Enable or disable memory-mapped DMA engines 365 + * 1: enable, 0: disable 366 + */ 367 + static int qdma_sgdma_control(struct qdma_device *qdev, u32 ctrl) 368 + { 369 + int ret; 370 + 371 + ret = qdma_reg_write(qdev, &ctrl, QDMA_REGO_MM_H2C_CTRL); 372 + ret |= qdma_reg_write(qdev, &ctrl, QDMA_REGO_MM_C2H_CTRL); 373 + 374 + return ret; 375 + } 376 + 377 + static int qdma_get_hw_info(struct qdma_device *qdev) 378 + { 379 + struct qdma_platdata *pdata = dev_get_platdata(&qdev->pdev->dev); 380 + u32 value = 0; 381 + int ret; 382 + 383 + ret = qdma_reg_read(qdev, &value, QDMA_REGO_QUEUE_COUNT); 384 + if (ret) 385 + return ret; 386 + 387 + value = qdma_get_field(qdev, &value, QDMA_REGF_QUEUE_COUNT) + 1; 388 + if (pdata->max_mm_channels * 2 > value) { 389 + qdma_err(qdev, "not enough hw queues %d", value); 390 + return -EINVAL; 391 + } 392 + qdev->chan_num = pdata->max_mm_channels; 393 + 394 + ret = qdma_reg_read(qdev, &qdev->fid, QDMA_REGO_FUNC_ID); 395 + if (ret) 396 + return ret; 397 + 398 + qdma_info(qdev, "max channel %d, function id %d", 399 + qdev->chan_num, qdev->fid); 400 + 401 + return 0; 402 + } 403 + 404 + static inline int qdma_update_pidx(const struct qdma_queue *queue, u16 pidx) 405 + { 406 + struct qdma_device *qdev = queue->qdev; 407 + 408 + return regmap_write(qdev->regmap, queue->pidx_reg, 409 + pidx | QDMA_QUEUE_ARM_BIT); 410 + } 411 + 412 + static inline int qdma_update_cidx(const struct qdma_queue *queue, 413 + u16 ridx, u16 cidx) 414 + { 415 + struct qdma_device *qdev = queue->qdev; 416 + 417 + return regmap_write(qdev->regmap, queue->cidx_reg, 418 + ((u32)ridx << 16) | cidx); 419 + } 420 + 421 + /** 422 + * qdma_free_vdesc - Free descriptor 423 + * @vdesc: Virtual DMA descriptor 424 + */ 425 + static void qdma_free_vdesc(struct virt_dma_desc *vdesc) 426 + { 427 + struct qdma_mm_vdesc *vd = to_qdma_vdesc(vdesc); 428 + 429 + kfree(vd); 430 + } 431 + 432 + static int qdma_alloc_queues(struct qdma_device *qdev, 433 + enum dma_transfer_direction dir) 434 + { 435 + struct qdma_queue *q, **queues; 436 + u32 i, pidx_base; 437 + int ret; 438 + 439 + if (dir == DMA_MEM_TO_DEV) { 440 + queues = &qdev->h2c_queues; 441 + pidx_base = QDMA_REG_OFF(qdev, QDMA_REGO_H2C_PIDX); 442 + } else { 443 + queues = &qdev->c2h_queues; 444 + pidx_base = QDMA_REG_OFF(qdev, QDMA_REGO_C2H_PIDX); 445 + } 446 + 447 + *queues = devm_kcalloc(&qdev->pdev->dev, qdev->chan_num, sizeof(*q), 448 + GFP_KERNEL); 449 + if (!*queues) 450 + return -ENOMEM; 451 + 452 + for (i = 0; i < qdev->chan_num; i++) { 453 + ret = qdma_check_queue_status(qdev, dir, i); 454 + if (ret) 455 + return ret; 456 + 457 + q = &(*queues)[i]; 458 + q->ring_size = QDMA_DEFAULT_RING_SIZE; 459 + q->idx_mask = q->ring_size - 2; 460 + q->qdev = qdev; 461 + q->dir = dir; 462 + q->qid = i; 463 + q->pidx_reg = pidx_base + i * QDMA_DMAP_REG_STRIDE; 464 + q->cidx_reg = QDMA_REG_OFF(qdev, QDMA_REGO_INTR_CIDX) + 465 + i * QDMA_DMAP_REG_STRIDE; 466 + q->vchan.desc_free = qdma_free_vdesc; 467 + vchan_init(&q->vchan, &qdev->dma_dev); 468 + } 469 + 470 + return 0; 471 + } 472 + 473 + static int qdma_device_verify(struct qdma_device *qdev) 474 + { 475 + u32 value; 476 + int ret; 477 + 478 + ret = regmap_read(qdev->regmap, QDMA_IDENTIFIER_REGOFF, &value); 479 + if (ret) 480 + return ret; 481 + 482 + value = FIELD_GET(QDMA_IDENTIFIER_MASK, value); 483 + if (value != QDMA_IDENTIFIER) { 484 + qdma_err(qdev, "Invalid identifier"); 485 + return -ENODEV; 486 + } 487 + qdev->rfields = qdma_regfs_default; 488 + qdev->roffs = qdma_regos_default; 489 + 490 + return 0; 491 + } 492 + 493 + static int qdma_device_setup(struct qdma_device *qdev) 494 + { 495 + struct device *dev = &qdev->pdev->dev; 496 + u32 ring_sz = QDMA_DEFAULT_RING_SIZE; 497 + int ret = 0; 498 + 499 + while (dev && get_dma_ops(dev)) 500 + dev = dev->parent; 501 + if (!dev) { 502 + qdma_err(qdev, "dma device not found"); 503 + return -EINVAL; 504 + } 505 + set_dma_ops(&qdev->pdev->dev, get_dma_ops(dev)); 506 + 507 + ret = qdma_setup_fmap_context(qdev); 508 + if (ret) { 509 + qdma_err(qdev, "Failed setup fmap context"); 510 + return ret; 511 + } 512 + 513 + /* Setup global ring buffer size at QDMA_DEFAULT_RING_ID index */ 514 + ret = qdma_reg_write(qdev, &ring_sz, QDMA_REGO_RING_SIZE); 515 + if (ret) { 516 + qdma_err(qdev, "Failed to setup ring %d of size %ld", 517 + QDMA_DEFAULT_RING_ID, QDMA_DEFAULT_RING_SIZE); 518 + return ret; 519 + } 520 + 521 + /* Enable memory-mapped DMA engine in both directions */ 522 + ret = qdma_sgdma_control(qdev, 1); 523 + if (ret) { 524 + qdma_err(qdev, "Failed to SGDMA with error %d", ret); 525 + return ret; 526 + } 527 + 528 + ret = qdma_alloc_queues(qdev, DMA_MEM_TO_DEV); 529 + if (ret) { 530 + qdma_err(qdev, "Failed to alloc H2C queues, ret %d", ret); 531 + return ret; 532 + } 533 + 534 + ret = qdma_alloc_queues(qdev, DMA_DEV_TO_MEM); 535 + if (ret) { 536 + qdma_err(qdev, "Failed to alloc C2H queues, ret %d", ret); 537 + return ret; 538 + } 539 + 540 + return 0; 541 + } 542 + 543 + /** 544 + * qdma_free_queue_resources() - Free queue resources 545 + * @chan: DMA channel 546 + */ 547 + static void qdma_free_queue_resources(struct dma_chan *chan) 548 + { 549 + struct qdma_queue *queue = to_qdma_queue(chan); 550 + struct qdma_device *qdev = queue->qdev; 551 + struct device *dev = qdev->dma_dev.dev; 552 + 553 + qdma_clear_queue_context(queue); 554 + vchan_free_chan_resources(&queue->vchan); 555 + dma_free_coherent(dev, queue->ring_size * QDMA_MM_DESC_SIZE, 556 + queue->desc_base, queue->dma_desc_base); 557 + } 558 + 559 + /** 560 + * qdma_alloc_queue_resources() - Allocate queue resources 561 + * @chan: DMA channel 562 + */ 563 + static int qdma_alloc_queue_resources(struct dma_chan *chan) 564 + { 565 + struct qdma_queue *queue = to_qdma_queue(chan); 566 + struct qdma_device *qdev = queue->qdev; 567 + struct qdma_ctxt_sw_desc desc; 568 + size_t size; 569 + int ret; 570 + 571 + ret = qdma_clear_queue_context(queue); 572 + if (ret) 573 + return ret; 574 + 575 + size = queue->ring_size * QDMA_MM_DESC_SIZE; 576 + queue->desc_base = dma_alloc_coherent(qdev->dma_dev.dev, size, 577 + &queue->dma_desc_base, 578 + GFP_KERNEL); 579 + if (!queue->desc_base) { 580 + qdma_err(qdev, "Failed to allocate descriptor ring"); 581 + return -ENOMEM; 582 + } 583 + 584 + /* Setup SW descriptor queue context for DMA memory map */ 585 + desc.vec = qdma_get_intr_ring_idx(qdev); 586 + desc.desc_base = queue->dma_desc_base; 587 + ret = qdma_setup_queue_context(qdev, &desc, queue->dir, queue->qid); 588 + if (ret) { 589 + qdma_err(qdev, "Failed to setup SW desc ctxt for %s", 590 + chan->name); 591 + dma_free_coherent(qdev->dma_dev.dev, size, queue->desc_base, 592 + queue->dma_desc_base); 593 + return ret; 594 + } 595 + 596 + queue->pidx = 0; 597 + queue->cidx = 0; 598 + 599 + return 0; 600 + } 601 + 602 + static bool qdma_filter_fn(struct dma_chan *chan, void *param) 603 + { 604 + struct qdma_queue *queue = to_qdma_queue(chan); 605 + struct qdma_queue_info *info = param; 606 + 607 + return info->dir == queue->dir; 608 + } 609 + 610 + static int qdma_xfer_start(struct qdma_queue *queue) 611 + { 612 + struct qdma_device *qdev = queue->qdev; 613 + int ret; 614 + 615 + if (!vchan_next_desc(&queue->vchan)) 616 + return 0; 617 + 618 + qdma_dbg(qdev, "Tnx kickoff with P: %d for %s%d", 619 + queue->issued_vdesc->pidx, CHAN_STR(queue), queue->qid); 620 + 621 + ret = qdma_update_pidx(queue, queue->issued_vdesc->pidx); 622 + if (ret) { 623 + qdma_err(qdev, "Failed to update PIDX to %d for %s queue: %d", 624 + queue->pidx, CHAN_STR(queue), queue->qid); 625 + } 626 + 627 + return ret; 628 + } 629 + 630 + static void qdma_issue_pending(struct dma_chan *chan) 631 + { 632 + struct qdma_queue *queue = to_qdma_queue(chan); 633 + unsigned long flags; 634 + 635 + spin_lock_irqsave(&queue->vchan.lock, flags); 636 + if (vchan_issue_pending(&queue->vchan)) { 637 + if (queue->submitted_vdesc) { 638 + queue->issued_vdesc = queue->submitted_vdesc; 639 + queue->submitted_vdesc = NULL; 640 + } 641 + qdma_xfer_start(queue); 642 + } 643 + 644 + spin_unlock_irqrestore(&queue->vchan.lock, flags); 645 + } 646 + 647 + static struct qdma_mm_desc *qdma_get_desc(struct qdma_queue *q) 648 + { 649 + struct qdma_mm_desc *desc; 650 + 651 + if (((q->pidx + 1) & q->idx_mask) == q->cidx) 652 + return NULL; 653 + 654 + desc = q->desc_base + q->pidx; 655 + q->pidx = (q->pidx + 1) & q->idx_mask; 656 + 657 + return desc; 658 + } 659 + 660 + static int qdma_hw_enqueue(struct qdma_queue *q, struct qdma_mm_vdesc *vdesc) 661 + { 662 + struct qdma_mm_desc *desc; 663 + struct scatterlist *sg; 664 + u64 addr, *src, *dst; 665 + u32 rest, len; 666 + int ret = 0; 667 + u32 i; 668 + 669 + if (!vdesc->sg_len) 670 + return 0; 671 + 672 + if (q->dir == DMA_MEM_TO_DEV) { 673 + dst = &vdesc->dev_addr; 674 + src = &addr; 675 + } else { 676 + dst = &addr; 677 + src = &vdesc->dev_addr; 678 + } 679 + 680 + for_each_sg(vdesc->sgl, sg, vdesc->sg_len, i) { 681 + addr = sg_dma_address(sg) + vdesc->sg_off; 682 + rest = sg_dma_len(sg) - vdesc->sg_off; 683 + while (rest) { 684 + len = min_t(u32, rest, QDMA_MM_DESC_MAX_LEN); 685 + desc = qdma_get_desc(q); 686 + if (!desc) { 687 + ret = -EBUSY; 688 + goto out; 689 + } 690 + 691 + desc->src_addr = cpu_to_le64(*src); 692 + desc->dst_addr = cpu_to_le64(*dst); 693 + desc->len = cpu_to_le32(len); 694 + 695 + vdesc->dev_addr += len; 696 + vdesc->sg_off += len; 697 + vdesc->pending_descs++; 698 + addr += len; 699 + rest -= len; 700 + } 701 + vdesc->sg_off = 0; 702 + } 703 + out: 704 + vdesc->sg_len -= i; 705 + vdesc->pidx = q->pidx; 706 + return ret; 707 + } 708 + 709 + static void qdma_fill_pending_vdesc(struct qdma_queue *q) 710 + { 711 + struct virt_dma_chan *vc = &q->vchan; 712 + struct qdma_mm_vdesc *vdesc = NULL; 713 + struct virt_dma_desc *vd; 714 + int ret; 715 + 716 + if (!list_empty(&vc->desc_issued)) { 717 + vd = &q->issued_vdesc->vdesc; 718 + list_for_each_entry_from(vd, &vc->desc_issued, node) { 719 + vdesc = to_qdma_vdesc(vd); 720 + ret = qdma_hw_enqueue(q, vdesc); 721 + if (ret) { 722 + q->issued_vdesc = vdesc; 723 + return; 724 + } 725 + } 726 + q->issued_vdesc = vdesc; 727 + } 728 + 729 + if (list_empty(&vc->desc_submitted)) 730 + return; 731 + 732 + if (q->submitted_vdesc) 733 + vd = &q->submitted_vdesc->vdesc; 734 + else 735 + vd = list_first_entry(&vc->desc_submitted, typeof(*vd), node); 736 + 737 + list_for_each_entry_from(vd, &vc->desc_submitted, node) { 738 + vdesc = to_qdma_vdesc(vd); 739 + ret = qdma_hw_enqueue(q, vdesc); 740 + if (ret) 741 + break; 742 + } 743 + q->submitted_vdesc = vdesc; 744 + } 745 + 746 + static dma_cookie_t qdma_tx_submit(struct dma_async_tx_descriptor *tx) 747 + { 748 + struct virt_dma_chan *vc = to_virt_chan(tx->chan); 749 + struct qdma_queue *q = to_qdma_queue(&vc->chan); 750 + struct virt_dma_desc *vd; 751 + unsigned long flags; 752 + dma_cookie_t cookie; 753 + 754 + vd = container_of(tx, struct virt_dma_desc, tx); 755 + spin_lock_irqsave(&vc->lock, flags); 756 + cookie = dma_cookie_assign(tx); 757 + 758 + list_move_tail(&vd->node, &vc->desc_submitted); 759 + qdma_fill_pending_vdesc(q); 760 + spin_unlock_irqrestore(&vc->lock, flags); 761 + 762 + return cookie; 763 + } 764 + 765 + static struct dma_async_tx_descriptor * 766 + qdma_prep_device_sg(struct dma_chan *chan, struct scatterlist *sgl, 767 + unsigned int sg_len, enum dma_transfer_direction dir, 768 + unsigned long flags, void *context) 769 + { 770 + struct qdma_queue *q = to_qdma_queue(chan); 771 + struct dma_async_tx_descriptor *tx; 772 + struct qdma_mm_vdesc *vdesc; 773 + 774 + vdesc = kzalloc(sizeof(*vdesc), GFP_NOWAIT); 775 + if (!vdesc) 776 + return NULL; 777 + vdesc->sgl = sgl; 778 + vdesc->sg_len = sg_len; 779 + if (dir == DMA_MEM_TO_DEV) 780 + vdesc->dev_addr = q->cfg.dst_addr; 781 + else 782 + vdesc->dev_addr = q->cfg.src_addr; 783 + 784 + tx = vchan_tx_prep(&q->vchan, &vdesc->vdesc, flags); 785 + tx->tx_submit = qdma_tx_submit; 786 + 787 + return tx; 788 + } 789 + 790 + static int qdma_device_config(struct dma_chan *chan, 791 + struct dma_slave_config *cfg) 792 + { 793 + struct qdma_queue *q = to_qdma_queue(chan); 794 + 795 + memcpy(&q->cfg, cfg, sizeof(*cfg)); 796 + 797 + return 0; 798 + } 799 + 800 + static int qdma_arm_err_intr(const struct qdma_device *qdev) 801 + { 802 + u32 value = 0; 803 + 804 + qdma_set_field(qdev, &value, QDMA_REGF_ERR_INT_FUNC, qdev->fid); 805 + qdma_set_field(qdev, &value, QDMA_REGF_ERR_INT_VEC, qdev->err_irq_idx); 806 + qdma_set_field(qdev, &value, QDMA_REGF_ERR_INT_ARM, 1); 807 + 808 + return qdma_reg_write(qdev, &value, QDMA_REGO_ERR_INT); 809 + } 810 + 811 + static irqreturn_t qdma_error_isr(int irq, void *data) 812 + { 813 + struct qdma_device *qdev = data; 814 + u32 err_stat = 0; 815 + int ret; 816 + 817 + ret = qdma_reg_read(qdev, &err_stat, QDMA_REGO_ERR_STAT); 818 + if (ret) { 819 + qdma_err(qdev, "read error state failed, ret %d", ret); 820 + goto out; 821 + } 822 + 823 + qdma_err(qdev, "global error %d", err_stat); 824 + ret = qdma_reg_write(qdev, &err_stat, QDMA_REGO_ERR_STAT); 825 + if (ret) 826 + qdma_err(qdev, "clear error state failed, ret %d", ret); 827 + 828 + out: 829 + qdma_arm_err_intr(qdev); 830 + return IRQ_HANDLED; 831 + } 832 + 833 + static irqreturn_t qdma_queue_isr(int irq, void *data) 834 + { 835 + struct qdma_intr_ring *intr = data; 836 + struct qdma_queue *q = NULL; 837 + struct qdma_device *qdev; 838 + u32 index, comp_desc; 839 + u64 intr_ent; 840 + u8 color; 841 + int ret; 842 + u16 qid; 843 + 844 + qdev = intr->qdev; 845 + index = intr->cidx; 846 + while (1) { 847 + struct virt_dma_desc *vd; 848 + struct qdma_mm_vdesc *vdesc; 849 + unsigned long flags; 850 + u32 cidx; 851 + 852 + intr_ent = le64_to_cpu(intr->base[index]); 853 + color = FIELD_GET(QDMA_INTR_MASK_COLOR, intr_ent); 854 + if (color != intr->color) 855 + break; 856 + 857 + qid = FIELD_GET(QDMA_INTR_MASK_QID, intr_ent); 858 + if (FIELD_GET(QDMA_INTR_MASK_TYPE, intr_ent)) 859 + q = qdev->c2h_queues; 860 + else 861 + q = qdev->h2c_queues; 862 + q += qid; 863 + 864 + cidx = FIELD_GET(QDMA_INTR_MASK_CIDX, intr_ent); 865 + 866 + spin_lock_irqsave(&q->vchan.lock, flags); 867 + comp_desc = (cidx - q->cidx) & q->idx_mask; 868 + 869 + vd = vchan_next_desc(&q->vchan); 870 + if (!vd) 871 + goto skip; 872 + 873 + vdesc = to_qdma_vdesc(vd); 874 + while (comp_desc > vdesc->pending_descs) { 875 + list_del(&vd->node); 876 + vchan_cookie_complete(vd); 877 + comp_desc -= vdesc->pending_descs; 878 + vd = vchan_next_desc(&q->vchan); 879 + vdesc = to_qdma_vdesc(vd); 880 + } 881 + vdesc->pending_descs -= comp_desc; 882 + if (!vdesc->pending_descs && QDMA_VDESC_QUEUED(vdesc)) { 883 + list_del(&vd->node); 884 + vchan_cookie_complete(vd); 885 + } 886 + q->cidx = cidx; 887 + 888 + qdma_fill_pending_vdesc(q); 889 + qdma_xfer_start(q); 890 + 891 + skip: 892 + spin_unlock_irqrestore(&q->vchan.lock, flags); 893 + 894 + /* 895 + * Wrap the index value and flip the expected color value if 896 + * interrupt aggregation PIDX has wrapped around. 897 + */ 898 + index++; 899 + index &= QDMA_INTR_RING_IDX_MASK; 900 + if (!index) 901 + intr->color = !intr->color; 902 + } 903 + 904 + /* 905 + * Update the software interrupt aggregation ring CIDX if a valid entry 906 + * was found. 907 + */ 908 + if (q) { 909 + qdma_dbg(qdev, "update intr ring%d %d", intr->ridx, index); 910 + 911 + /* 912 + * Record the last read index of status descriptor from the 913 + * interrupt aggregation ring. 914 + */ 915 + intr->cidx = index; 916 + 917 + ret = qdma_update_cidx(q, intr->ridx, index); 918 + if (ret) { 919 + qdma_err(qdev, "Failed to update IRQ CIDX"); 920 + return IRQ_NONE; 921 + } 922 + } 923 + 924 + return IRQ_HANDLED; 925 + } 926 + 927 + static int qdma_init_error_irq(struct qdma_device *qdev) 928 + { 929 + struct device *dev = &qdev->pdev->dev; 930 + int ret; 931 + u32 vec; 932 + 933 + vec = qdev->queue_irq_start - 1; 934 + 935 + ret = devm_request_threaded_irq(dev, vec, NULL, qdma_error_isr, 936 + IRQF_ONESHOT, "amd-qdma-error", qdev); 937 + if (ret) { 938 + qdma_err(qdev, "Failed to request error IRQ vector: %d", vec); 939 + return ret; 940 + } 941 + 942 + ret = qdma_arm_err_intr(qdev); 943 + if (ret) 944 + qdma_err(qdev, "Failed to arm err interrupt, ret %d", ret); 945 + 946 + return ret; 947 + } 948 + 949 + static int qdmam_alloc_qintr_rings(struct qdma_device *qdev) 950 + { 951 + u32 ctxt[QDMA_CTXT_REGMAP_LEN]; 952 + struct device *dev = &qdev->pdev->dev; 953 + struct qdma_intr_ring *ring; 954 + struct qdma_ctxt_intr intr_ctxt; 955 + u32 vector; 956 + int ret, i; 957 + 958 + qdev->qintr_ring_num = qdev->queue_irq_num; 959 + qdev->qintr_rings = devm_kcalloc(dev, qdev->qintr_ring_num, 960 + sizeof(*qdev->qintr_rings), 961 + GFP_KERNEL); 962 + if (!qdev->qintr_rings) 963 + return -ENOMEM; 964 + 965 + vector = qdev->queue_irq_start; 966 + for (i = 0; i < qdev->qintr_ring_num; i++, vector++) { 967 + ring = &qdev->qintr_rings[i]; 968 + ring->qdev = qdev; 969 + ring->msix_id = qdev->err_irq_idx + i + 1; 970 + ring->ridx = i; 971 + ring->color = 1; 972 + ring->base = dmam_alloc_coherent(dev, QDMA_INTR_RING_SIZE, 973 + &ring->dev_base, GFP_KERNEL); 974 + if (!ring->base) { 975 + qdma_err(qdev, "Failed to alloc intr ring %d", i); 976 + return -ENOMEM; 977 + } 978 + intr_ctxt.agg_base = QDMA_INTR_RING_BASE(ring->dev_base); 979 + intr_ctxt.size = (QDMA_INTR_RING_SIZE - 1) / 4096; 980 + intr_ctxt.vec = ring->msix_id; 981 + intr_ctxt.valid = true; 982 + intr_ctxt.color = true; 983 + ret = qdma_prog_context(qdev, QDMA_CTXT_INTR_COAL, 984 + QDMA_CTXT_CLEAR, ring->ridx, NULL); 985 + if (ret) { 986 + qdma_err(qdev, "Failed clear intr ctx, ret %d", ret); 987 + return ret; 988 + } 989 + 990 + qdma_prep_intr_context(qdev, &intr_ctxt, ctxt); 991 + ret = qdma_prog_context(qdev, QDMA_CTXT_INTR_COAL, 992 + QDMA_CTXT_WRITE, ring->ridx, ctxt); 993 + if (ret) { 994 + qdma_err(qdev, "Failed setup intr ctx, ret %d", ret); 995 + return ret; 996 + } 997 + 998 + ret = devm_request_threaded_irq(dev, vector, NULL, 999 + qdma_queue_isr, IRQF_ONESHOT, 1000 + "amd-qdma-queue", ring); 1001 + if (ret) { 1002 + qdma_err(qdev, "Failed to request irq %d", vector); 1003 + return ret; 1004 + } 1005 + } 1006 + 1007 + return 0; 1008 + } 1009 + 1010 + static int qdma_intr_init(struct qdma_device *qdev) 1011 + { 1012 + int ret; 1013 + 1014 + ret = qdma_init_error_irq(qdev); 1015 + if (ret) { 1016 + qdma_err(qdev, "Failed to init error IRQs, ret %d", ret); 1017 + return ret; 1018 + } 1019 + 1020 + ret = qdmam_alloc_qintr_rings(qdev); 1021 + if (ret) { 1022 + qdma_err(qdev, "Failed to init queue IRQs, ret %d", ret); 1023 + return ret; 1024 + } 1025 + 1026 + return 0; 1027 + } 1028 + 1029 + static void amd_qdma_remove(struct platform_device *pdev) 1030 + { 1031 + struct qdma_device *qdev = platform_get_drvdata(pdev); 1032 + 1033 + qdma_sgdma_control(qdev, 0); 1034 + dma_async_device_unregister(&qdev->dma_dev); 1035 + 1036 + mutex_destroy(&qdev->ctxt_lock); 1037 + } 1038 + 1039 + static int amd_qdma_probe(struct platform_device *pdev) 1040 + { 1041 + struct qdma_platdata *pdata = dev_get_platdata(&pdev->dev); 1042 + struct qdma_device *qdev; 1043 + struct resource *res; 1044 + void __iomem *regs; 1045 + int ret; 1046 + 1047 + qdev = devm_kzalloc(&pdev->dev, sizeof(*qdev), GFP_KERNEL); 1048 + if (!qdev) 1049 + return -ENOMEM; 1050 + 1051 + platform_set_drvdata(pdev, qdev); 1052 + qdev->pdev = pdev; 1053 + mutex_init(&qdev->ctxt_lock); 1054 + 1055 + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1056 + if (!res) { 1057 + qdma_err(qdev, "Failed to get IRQ resource"); 1058 + ret = -ENODEV; 1059 + goto failed; 1060 + } 1061 + qdev->err_irq_idx = pdata->irq_index; 1062 + qdev->queue_irq_start = res->start + 1; 1063 + qdev->queue_irq_num = resource_size(res) - 1; 1064 + 1065 + regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); 1066 + if (IS_ERR(regs)) { 1067 + ret = PTR_ERR(regs); 1068 + qdma_err(qdev, "Failed to map IO resource, err %d", ret); 1069 + goto failed; 1070 + } 1071 + 1072 + qdev->regmap = devm_regmap_init_mmio(&pdev->dev, regs, 1073 + &qdma_regmap_config); 1074 + if (IS_ERR(qdev->regmap)) { 1075 + ret = PTR_ERR(qdev->regmap); 1076 + qdma_err(qdev, "Regmap init failed, err %d", ret); 1077 + goto failed; 1078 + } 1079 + 1080 + ret = qdma_device_verify(qdev); 1081 + if (ret) 1082 + goto failed; 1083 + 1084 + ret = qdma_get_hw_info(qdev); 1085 + if (ret) 1086 + goto failed; 1087 + 1088 + INIT_LIST_HEAD(&qdev->dma_dev.channels); 1089 + 1090 + ret = qdma_device_setup(qdev); 1091 + if (ret) 1092 + goto failed; 1093 + 1094 + ret = qdma_intr_init(qdev); 1095 + if (ret) { 1096 + qdma_err(qdev, "Failed to initialize IRQs %d", ret); 1097 + goto failed_disable_engine; 1098 + } 1099 + 1100 + dma_cap_set(DMA_SLAVE, qdev->dma_dev.cap_mask); 1101 + dma_cap_set(DMA_PRIVATE, qdev->dma_dev.cap_mask); 1102 + 1103 + qdev->dma_dev.dev = &pdev->dev; 1104 + qdev->dma_dev.filter.map = pdata->device_map; 1105 + qdev->dma_dev.filter.mapcnt = qdev->chan_num * 2; 1106 + qdev->dma_dev.filter.fn = qdma_filter_fn; 1107 + qdev->dma_dev.device_alloc_chan_resources = qdma_alloc_queue_resources; 1108 + qdev->dma_dev.device_free_chan_resources = qdma_free_queue_resources; 1109 + qdev->dma_dev.device_prep_slave_sg = qdma_prep_device_sg; 1110 + qdev->dma_dev.device_config = qdma_device_config; 1111 + qdev->dma_dev.device_issue_pending = qdma_issue_pending; 1112 + qdev->dma_dev.device_tx_status = dma_cookie_status; 1113 + qdev->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); 1114 + 1115 + ret = dma_async_device_register(&qdev->dma_dev); 1116 + if (ret) { 1117 + qdma_err(qdev, "Failed to register AMD QDMA: %d", ret); 1118 + goto failed_disable_engine; 1119 + } 1120 + 1121 + return 0; 1122 + 1123 + failed_disable_engine: 1124 + qdma_sgdma_control(qdev, 0); 1125 + failed: 1126 + mutex_destroy(&qdev->ctxt_lock); 1127 + qdma_err(qdev, "Failed to probe AMD QDMA driver"); 1128 + return ret; 1129 + } 1130 + 1131 + static struct platform_driver amd_qdma_driver = { 1132 + .driver = { 1133 + .name = "amd-qdma", 1134 + }, 1135 + .probe = amd_qdma_probe, 1136 + .remove_new = amd_qdma_remove, 1137 + }; 1138 + 1139 + module_platform_driver(amd_qdma_driver); 1140 + 1141 + MODULE_DESCRIPTION("AMD QDMA driver"); 1142 + MODULE_AUTHOR("XRT Team <runtimeca39d@amd.com>"); 1143 + MODULE_LICENSE("GPL");
+266
drivers/dma/amd/qdma/qdma.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * DMA header for AMD Queue-based DMA Subsystem 4 + * 5 + * Copyright (C) 2023-2024, Advanced Micro Devices, Inc. 6 + */ 7 + 8 + #ifndef __QDMA_H 9 + #define __QDMA_H 10 + 11 + #include <linux/bitfield.h> 12 + #include <linux/dmaengine.h> 13 + #include <linux/kernel.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/regmap.h> 16 + 17 + #include "../../virt-dma.h" 18 + 19 + #define DISABLE 0 20 + #define ENABLE 1 21 + 22 + #define QDMA_MIN_IRQ 3 23 + #define QDMA_INTR_NAME_MAX_LEN 30 24 + #define QDMA_INTR_PREFIX "amd-qdma" 25 + 26 + #define QDMA_IDENTIFIER 0x1FD3 27 + #define QDMA_DEFAULT_RING_SIZE (BIT(10) + 1) 28 + #define QDMA_DEFAULT_RING_ID 0 29 + #define QDMA_POLL_INTRVL_US 10 /* 10us */ 30 + #define QDMA_POLL_TIMEOUT_US (500 * 1000) /* 500ms */ 31 + #define QDMA_DMAP_REG_STRIDE 16 32 + #define QDMA_CTXT_REGMAP_LEN 8 /* 8 regs */ 33 + #define QDMA_MM_DESC_SIZE 32 /* Bytes */ 34 + #define QDMA_MM_DESC_LEN_BITS 28 35 + #define QDMA_MM_DESC_MAX_LEN (BIT(QDMA_MM_DESC_LEN_BITS) - 1) 36 + #define QDMA_MIN_DMA_ALLOC_SIZE 4096 37 + #define QDMA_INTR_RING_SIZE BIT(13) 38 + #define QDMA_INTR_RING_IDX_MASK GENMASK(9, 0) 39 + #define QDMA_INTR_RING_BASE(_addr) ((_addr) >> 12) 40 + 41 + #define QDMA_IDENTIFIER_REGOFF 0x0 42 + #define QDMA_IDENTIFIER_MASK GENMASK(31, 16) 43 + #define QDMA_QUEUE_ARM_BIT BIT(16) 44 + 45 + #define qdma_err(qdev, fmt, args...) \ 46 + dev_err(&(qdev)->pdev->dev, fmt, ##args) 47 + 48 + #define qdma_dbg(qdev, fmt, args...) \ 49 + dev_dbg(&(qdev)->pdev->dev, fmt, ##args) 50 + 51 + #define qdma_info(qdev, fmt, args...) \ 52 + dev_info(&(qdev)->pdev->dev, fmt, ##args) 53 + 54 + enum qdma_reg_fields { 55 + QDMA_REGF_IRQ_ENABLE, 56 + QDMA_REGF_WBK_ENABLE, 57 + QDMA_REGF_WBI_CHECK, 58 + QDMA_REGF_IRQ_ARM, 59 + QDMA_REGF_IRQ_VEC, 60 + QDMA_REGF_IRQ_AGG, 61 + QDMA_REGF_WBI_INTVL_ENABLE, 62 + QDMA_REGF_MRKR_DISABLE, 63 + QDMA_REGF_QUEUE_ENABLE, 64 + QDMA_REGF_QUEUE_MODE, 65 + QDMA_REGF_DESC_BASE, 66 + QDMA_REGF_DESC_SIZE, 67 + QDMA_REGF_RING_ID, 68 + QDMA_REGF_CMD_INDX, 69 + QDMA_REGF_CMD_CMD, 70 + QDMA_REGF_CMD_TYPE, 71 + QDMA_REGF_CMD_BUSY, 72 + QDMA_REGF_QUEUE_COUNT, 73 + QDMA_REGF_QUEUE_MAX, 74 + QDMA_REGF_QUEUE_BASE, 75 + QDMA_REGF_FUNCTION_ID, 76 + QDMA_REGF_INTR_AGG_BASE, 77 + QDMA_REGF_INTR_VECTOR, 78 + QDMA_REGF_INTR_SIZE, 79 + QDMA_REGF_INTR_VALID, 80 + QDMA_REGF_INTR_COLOR, 81 + QDMA_REGF_INTR_FUNCTION_ID, 82 + QDMA_REGF_ERR_INT_FUNC, 83 + QDMA_REGF_ERR_INT_VEC, 84 + QDMA_REGF_ERR_INT_ARM, 85 + QDMA_REGF_MAX 86 + }; 87 + 88 + enum qdma_regs { 89 + QDMA_REGO_CTXT_DATA, 90 + QDMA_REGO_CTXT_CMD, 91 + QDMA_REGO_CTXT_MASK, 92 + QDMA_REGO_MM_H2C_CTRL, 93 + QDMA_REGO_MM_C2H_CTRL, 94 + QDMA_REGO_QUEUE_COUNT, 95 + QDMA_REGO_RING_SIZE, 96 + QDMA_REGO_H2C_PIDX, 97 + QDMA_REGO_C2H_PIDX, 98 + QDMA_REGO_INTR_CIDX, 99 + QDMA_REGO_FUNC_ID, 100 + QDMA_REGO_ERR_INT, 101 + QDMA_REGO_ERR_STAT, 102 + QDMA_REGO_MAX 103 + }; 104 + 105 + struct qdma_reg_field { 106 + u16 lsb; /* Least significant bit of field */ 107 + u16 msb; /* Most significant bit of field */ 108 + }; 109 + 110 + struct qdma_reg { 111 + u32 off; 112 + u32 count; 113 + }; 114 + 115 + #define QDMA_REGF(_msb, _lsb) { \ 116 + .lsb = (_lsb), \ 117 + .msb = (_msb), \ 118 + } 119 + 120 + #define QDMA_REGO(_off, _count) { \ 121 + .off = (_off), \ 122 + .count = (_count), \ 123 + } 124 + 125 + enum qdma_desc_size { 126 + QDMA_DESC_SIZE_8B, 127 + QDMA_DESC_SIZE_16B, 128 + QDMA_DESC_SIZE_32B, 129 + QDMA_DESC_SIZE_64B, 130 + }; 131 + 132 + enum qdma_queue_op_mode { 133 + QDMA_QUEUE_OP_STREAM, 134 + QDMA_QUEUE_OP_MM, 135 + }; 136 + 137 + enum qdma_ctxt_type { 138 + QDMA_CTXT_DESC_SW_C2H, 139 + QDMA_CTXT_DESC_SW_H2C, 140 + QDMA_CTXT_DESC_HW_C2H, 141 + QDMA_CTXT_DESC_HW_H2C, 142 + QDMA_CTXT_DESC_CR_C2H, 143 + QDMA_CTXT_DESC_CR_H2C, 144 + QDMA_CTXT_WRB, 145 + QDMA_CTXT_PFTCH, 146 + QDMA_CTXT_INTR_COAL, 147 + QDMA_CTXT_RSVD, 148 + QDMA_CTXT_HOST_PROFILE, 149 + QDMA_CTXT_TIMER, 150 + QDMA_CTXT_FMAP, 151 + QDMA_CTXT_FNC_STS, 152 + }; 153 + 154 + enum qdma_ctxt_cmd { 155 + QDMA_CTXT_CLEAR, 156 + QDMA_CTXT_WRITE, 157 + QDMA_CTXT_READ, 158 + QDMA_CTXT_INVALIDATE, 159 + QDMA_CTXT_MAX 160 + }; 161 + 162 + struct qdma_ctxt_sw_desc { 163 + u64 desc_base; 164 + u16 vec; 165 + }; 166 + 167 + struct qdma_ctxt_intr { 168 + u64 agg_base; 169 + u16 vec; 170 + u32 size; 171 + bool valid; 172 + bool color; 173 + }; 174 + 175 + struct qdma_ctxt_fmap { 176 + u16 qbase; 177 + u16 qmax; 178 + }; 179 + 180 + struct qdma_device; 181 + 182 + struct qdma_mm_desc { 183 + __le64 src_addr; 184 + __le32 len; 185 + __le32 reserved1; 186 + __le64 dst_addr; 187 + __le64 reserved2; 188 + } __packed; 189 + 190 + struct qdma_mm_vdesc { 191 + struct virt_dma_desc vdesc; 192 + struct qdma_queue *queue; 193 + struct scatterlist *sgl; 194 + u64 sg_off; 195 + u32 sg_len; 196 + u64 dev_addr; 197 + u32 pidx; 198 + u32 pending_descs; 199 + struct dma_slave_config cfg; 200 + }; 201 + 202 + #define QDMA_VDESC_QUEUED(vdesc) (!(vdesc)->sg_len) 203 + 204 + struct qdma_queue { 205 + struct qdma_device *qdev; 206 + struct virt_dma_chan vchan; 207 + enum dma_transfer_direction dir; 208 + struct dma_slave_config cfg; 209 + struct qdma_mm_desc *desc_base; 210 + struct qdma_mm_vdesc *submitted_vdesc; 211 + struct qdma_mm_vdesc *issued_vdesc; 212 + dma_addr_t dma_desc_base; 213 + u32 pidx_reg; 214 + u32 cidx_reg; 215 + u32 ring_size; 216 + u32 idx_mask; 217 + u16 qid; 218 + u32 pidx; 219 + u32 cidx; 220 + }; 221 + 222 + struct qdma_intr_ring { 223 + struct qdma_device *qdev; 224 + __le64 *base; 225 + dma_addr_t dev_base; 226 + char msix_name[QDMA_INTR_NAME_MAX_LEN]; 227 + u32 msix_vector; 228 + u16 msix_id; 229 + u32 ring_size; 230 + u16 ridx; 231 + u16 cidx; 232 + u8 color; 233 + }; 234 + 235 + #define QDMA_INTR_MASK_PIDX GENMASK_ULL(15, 0) 236 + #define QDMA_INTR_MASK_CIDX GENMASK_ULL(31, 16) 237 + #define QDMA_INTR_MASK_DESC_COLOR GENMASK_ULL(32, 32) 238 + #define QDMA_INTR_MASK_STATE GENMASK_ULL(34, 33) 239 + #define QDMA_INTR_MASK_ERROR GENMASK_ULL(36, 35) 240 + #define QDMA_INTR_MASK_TYPE GENMASK_ULL(38, 38) 241 + #define QDMA_INTR_MASK_QID GENMASK_ULL(62, 39) 242 + #define QDMA_INTR_MASK_COLOR GENMASK_ULL(63, 63) 243 + 244 + struct qdma_device { 245 + struct platform_device *pdev; 246 + struct dma_device dma_dev; 247 + struct regmap *regmap; 248 + struct mutex ctxt_lock; /* protect ctxt registers */ 249 + const struct qdma_reg_field *rfields; 250 + const struct qdma_reg *roffs; 251 + struct qdma_queue *h2c_queues; 252 + struct qdma_queue *c2h_queues; 253 + struct qdma_intr_ring *qintr_rings; 254 + u32 qintr_ring_num; 255 + u32 qintr_ring_idx; 256 + u32 chan_num; 257 + u32 queue_irq_start; 258 + u32 queue_irq_num; 259 + u32 err_irq_idx; 260 + u32 fid; 261 + }; 262 + 263 + extern const struct qdma_reg qdma_regos_default[QDMA_REGO_MAX]; 264 + extern const struct qdma_reg_field qdma_regfs_default[QDMA_REGF_MAX]; 265 + 266 + #endif /* __QDMA_H */
+3 -3
drivers/dma/at_hdmac.c
··· 339 339 * @regs: memory mapped register base 340 340 * @clk: dma controller clock 341 341 * @save_imr: interrupt mask register that is saved on suspend/resume cycle 342 - * @all_chan_mask: all channels availlable in a mask 342 + * @all_chan_mask: all channels available in a mask 343 343 * @lli_pool: hw lli table 344 344 * @memset_pool: hw memset pool 345 345 * @chan: channels table to store at_dma_chan structures ··· 668 668 * CTRLA is read in turn, next the DSCR is read a second time. If the two 669 669 * consecutive read values of the DSCR are the same then we assume both refers 670 670 * to the very same LLI as well as the CTRLA value read inbetween does. For 671 - * cyclic tranfers, the assumption is that a full loop is "not so fast". If the 671 + * cyclic transfers, the assumption is that a full loop is "not so fast". If the 672 672 * two DSCR values are different, we read again the CTRLA then the DSCR till two 673 673 * consecutive read values from DSCR are equal or till the maximum trials is 674 674 * reach. This algorithm is very unlikely not to find a stable value for DSCR. ··· 700 700 break; 701 701 702 702 /* 703 - * DSCR has changed inside the DMA controller, so the previouly 703 + * DSCR has changed inside the DMA controller, so the previously 704 704 * read value of CTRLA may refer to an already processed 705 705 * descriptor hence could be outdated. We need to update ctrla 706 706 * to match the current descriptor.
+2 -2
drivers/dma/bcm-sba-raid.c
··· 15 15 * number of hardware rings over one or more SBA hardware devices. By 16 16 * design, the internal buffer size of SBA hardware device is limited 17 17 * but all offload operations supported by SBA can be broken down into 18 - * multiple small size requests and executed parallely on multiple SBA 18 + * multiple small size requests and executed parallelly on multiple SBA 19 19 * hardware devices for achieving high through-put. 20 20 * 21 21 * The Broadcom SBA RAID driver does not require any register programming ··· 135 135 u32 max_xor_srcs; 136 136 u32 max_resp_pool_size; 137 137 u32 max_cmds_pool_size; 138 - /* Maibox client and Mailbox channels */ 138 + /* Mailbox client and Mailbox channels */ 139 139 struct mbox_client client; 140 140 struct mbox_chan *mchan; 141 141 struct device *mbox_dev;
+1 -1
drivers/dma/bcm2835-dma.c
··· 369 369 /* the last frame requires extra flags */ 370 370 d->cb_list[d->frames - 1].cb->info |= finalextrainfo; 371 371 372 - /* detect a size missmatch */ 372 + /* detect a size mismatch */ 373 373 if (buf_len && (d->size != buf_len)) 374 374 goto error_cb; 375 375
+1 -1
drivers/dma/dmaengine.c
··· 1070 1070 if (!name) 1071 1071 dev_set_name(&chan->dev->device, "dma%dchan%d", device->dev_id, chan->chan_id); 1072 1072 else 1073 - dev_set_name(&chan->dev->device, name); 1073 + dev_set_name(&chan->dev->device, "%s", name); 1074 1074 rc = device_register(&chan->dev->device); 1075 1075 if (rc) 1076 1076 goto err_out_ida;
+1 -1
drivers/dma/dmatest.c
··· 500 500 501 501 per_sec *= val; 502 502 per_sec = INT_TO_FIXPT(per_sec); 503 - do_div(per_sec, runtime); 503 + do_div(per_sec, (u32)runtime); 504 504 505 505 return per_sec; 506 506 }
+2 -2
drivers/dma/ep93xx_dma.c
··· 841 841 desc = container_of(tx, struct ep93xx_dma_desc, txd); 842 842 843 843 /* 844 - * If nothing is currently prosessed, we push this descriptor 844 + * If nothing is currently processed, we push this descriptor 845 845 * directly to the hardware. Otherwise we put the descriptor 846 846 * to the pending queue. 847 847 */ ··· 1025 1025 * @chan: channel 1026 1026 * @sgl: list of buffers to transfer 1027 1027 * @sg_len: number of entries in @sgl 1028 - * @dir: direction of tha DMA transfer 1028 + * @dir: direction of the DMA transfer 1029 1029 * @flags: flags for the descriptor 1030 1030 * @context: operation context (ignored) 1031 1031 *
+3 -3
drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.h
··· 12 12 u32 rsv:32; 13 13 union { 14 14 struct { 15 - u32 ssd:12; /* souce stride distance */ 16 - u32 sss:12; /* souce stride size */ 15 + u32 ssd:12; /* source stride distance */ 16 + u32 sss:12; /* source stride size */ 17 17 u32 rsv1:8; 18 18 } sdf; 19 19 struct { ··· 48 48 #define QDMA_SER_DISABLE (8) /* no notification */ 49 49 #define QDMA_SER_CTX BIT(8) /* notification by FQD_CTX[fqid] */ 50 50 #define QDMA_SER_DEST (2 << 8) /* notification by destination desc */ 51 - #define QDMA_SER_BOTH (3 << 8) /* soruce and dest notification */ 51 + #define QDMA_SER_BOTH (3 << 8) /* source and dest notification */ 52 52 #define QDMA_FD_SPF_ENALBE BIT(30) /* source prefetch enable */ 53 53 54 54 #define QMAN_FD_VA_ENABLE BIT(14) /* Address used is virtual address */
+23 -4
drivers/dma/fsl-edma-main.c
··· 100 100 return fsl_edma_err_handler(irq, dev_id); 101 101 } 102 102 103 + static bool fsl_edma_srcid_in_use(struct fsl_edma_engine *fsl_edma, u32 srcid) 104 + { 105 + struct fsl_edma_chan *fsl_chan; 106 + int i; 107 + 108 + for (i = 0; i < fsl_edma->n_chans; i++) { 109 + fsl_chan = &fsl_edma->chans[i]; 110 + 111 + if (fsl_chan->srcid && srcid == fsl_chan->srcid) { 112 + dev_err(&fsl_chan->pdev->dev, "The srcid is in use, can't use!"); 113 + return true; 114 + } 115 + } 116 + return false; 117 + } 118 + 103 119 static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec, 104 120 struct of_dma *ofdma) 105 121 { ··· 133 117 list_for_each_entry_safe(chan, _chan, &fsl_edma->dma_dev.channels, device_node) { 134 118 if (chan->client_count) 135 119 continue; 120 + 121 + if (fsl_edma_srcid_in_use(fsl_edma, dma_spec->args[1])) 122 + return NULL; 123 + 136 124 if ((chan->chan_id / chans_per_mux) == dma_spec->args[0]) { 137 125 chan = dma_get_slave_channel(chan); 138 126 if (chan) { ··· 173 153 174 154 b_chmux = !!(fsl_edma->drvdata->flags & FSL_EDMA_DRV_HAS_CHMUX); 175 155 176 - mutex_lock(&fsl_edma->fsl_edma_mutex); 156 + guard(mutex)(&fsl_edma->fsl_edma_mutex); 177 157 list_for_each_entry_safe(chan, _chan, &fsl_edma->dma_dev.channels, 178 158 device_node) { 179 159 ··· 181 161 continue; 182 162 183 163 fsl_chan = to_fsl_edma_chan(chan); 164 + if (fsl_edma_srcid_in_use(fsl_edma, dma_spec->args[0])) 165 + return NULL; 184 166 i = fsl_chan - fsl_edma->chans; 185 167 186 168 fsl_chan->priority = dma_spec->args[1]; ··· 199 177 if (!b_chmux && i == dma_spec->args[0]) { 200 178 chan = dma_get_slave_channel(chan); 201 179 chan->device->privatecnt++; 202 - mutex_unlock(&fsl_edma->fsl_edma_mutex); 203 180 return chan; 204 181 } else if (b_chmux && !fsl_chan->srcid) { 205 182 /* if controller support channel mux, choose a free channel */ 206 183 chan = dma_get_slave_channel(chan); 207 184 chan->device->privatecnt++; 208 185 fsl_chan->srcid = dma_spec->args[0]; 209 - mutex_unlock(&fsl_edma->fsl_edma_mutex); 210 186 return chan; 211 187 } 212 188 } 213 - mutex_unlock(&fsl_edma->fsl_edma_mutex); 214 189 return NULL; 215 190 } 216 191
+1 -1
drivers/dma/hisi_dma.c
··· 677 677 writel_relaxed(tmp, addr); 678 678 679 679 /* 680 - * 0 - dma should process FLR whith CPU. 680 + * 0 - dma should process FLR with CPU. 681 681 * 1 - dma not process FLR, only cpu process FLR. 682 682 */ 683 683 addr = q_base + HISI_DMA_HIP09_DMA_FLR_DISABLE +
+2 -2
drivers/dma/idma64.c
··· 290 290 desc->length += hw->len; 291 291 } while (i); 292 292 293 - /* Trigger an interrupt after the last block is transfered */ 293 + /* Trigger an interrupt after the last block is transferred */ 294 294 lli->ctllo |= IDMA64C_CTLL_INT_EN; 295 295 296 296 /* Disable LLP transfer in the last block */ ··· 364 364 if (!i) 365 365 return bytes; 366 366 367 - /* The current chunk is not fully transfered yet */ 367 + /* The current chunk is not fully transferred yet */ 368 368 bytes += desc->hw[--i].len; 369 369 370 370 return bytes - IDMA64C_CTLH_BLOCK_TS(ctlhi);
+6
drivers/dma/idxd/init.c
··· 69 69 static struct pci_device_id idxd_pci_tbl[] = { 70 70 /* DSA ver 1.0 platforms */ 71 71 { PCI_DEVICE_DATA(INTEL, DSA_SPR0, &idxd_driver_data[IDXD_TYPE_DSA]) }, 72 + /* DSA on GNR-D platforms */ 73 + { PCI_DEVICE_DATA(INTEL, DSA_GNRD, &idxd_driver_data[IDXD_TYPE_DSA]) }, 74 + /* DSA on DMR platforms */ 75 + { PCI_DEVICE_DATA(INTEL, DSA_DMR, &idxd_driver_data[IDXD_TYPE_DSA]) }, 72 76 73 77 /* IAX ver 1.0 platforms */ 74 78 { PCI_DEVICE_DATA(INTEL, IAX_SPR0, &idxd_driver_data[IDXD_TYPE_IAX]) }, 79 + /* IAA on DMR platforms */ 80 + { PCI_DEVICE_DATA(INTEL, IAA_DMR, &idxd_driver_data[IDXD_TYPE_IAX]) }, 75 81 { 0, } 76 82 }; 77 83 MODULE_DEVICE_TABLE(pci, idxd_pci_tbl);
+2 -2
drivers/dma/idxd/perfmon.c
··· 449 449 idxd_pmu->pmu.attr_groups = perfmon_attr_groups; 450 450 idxd_pmu->pmu.task_ctx_nr = perf_invalid_context; 451 451 idxd_pmu->pmu.event_init = perfmon_pmu_event_init; 452 - idxd_pmu->pmu.pmu_enable = perfmon_pmu_enable, 453 - idxd_pmu->pmu.pmu_disable = perfmon_pmu_disable, 452 + idxd_pmu->pmu.pmu_enable = perfmon_pmu_enable; 453 + idxd_pmu->pmu.pmu_disable = perfmon_pmu_disable; 454 454 idxd_pmu->pmu.add = perfmon_pmu_event_add; 455 455 idxd_pmu->pmu.del = perfmon_pmu_event_del; 456 456 idxd_pmu->pmu.start = perfmon_pmu_event_start;
+1 -1
drivers/dma/idxd/submit.c
··· 134 134 * completing the descriptor will return desc to allocator and 135 135 * the desc can be acquired by a different process and the 136 136 * desc->list can be modified. Delete desc from list so the 137 - * list trasversing does not get corrupted by the other process. 137 + * list traversing does not get corrupted by the other process. 138 138 */ 139 139 list_for_each_entry_safe(d, t, &flist, list) { 140 140 list_del_init(&d->list);
-3
drivers/dma/imx-dma.c
··· 167 167 168 168 enum imx_dma_type { 169 169 IMX1_DMA, 170 - IMX21_DMA, 171 170 IMX27_DMA, 172 171 }; 173 172 ··· 193 194 static const struct of_device_id imx_dma_of_dev_id[] = { 194 195 { 195 196 .compatible = "fsl,imx1-dma", .data = (const void *)IMX1_DMA, 196 - }, { 197 - .compatible = "fsl,imx21-dma", .data = (const void *)IMX21_DMA, 198 197 }, { 199 198 .compatible = "fsl,imx27-dma", .data = (const void *)IMX27_DMA, 200 199 }, {
+1 -1
drivers/dma/ioat/init.c
··· 905 905 906 906 op = IOAT_OP_XOR_VAL; 907 907 908 - /* validate the sources with the destintation page */ 908 + /* validate the sources with the destination page */ 909 909 for (i = 0; i < IOAT_NUM_SRC_TEST; i++) 910 910 xor_val_srcs[i] = xor_srcs[i]; 911 911 xor_val_srcs[i] = dest;
+1 -1
drivers/dma/lgm/lgm-dma.c
··· 107 107 * If header mode is set in DMA descriptor, 108 108 * If bit 30 is disabled, HDR_LEN must be configured according to channel 109 109 * requirement. 110 - * If bit 30 is enabled(checksum with heade mode), HDR_LEN has no need to 110 + * If bit 30 is enabled(checksum with header mode), HDR_LEN has no need to 111 111 * be configured. It will enable check sum for switch 112 112 * If header mode is not set in DMA descriptor, 113 113 * This register setting doesn't matter
+660
drivers/dma/loongson1-apb-dma.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Driver for Loongson-1 APB DMA Controller 4 + * 5 + * Copyright (C) 2015-2024 Keguang Zhang <keguang.zhang@gmail.com> 6 + */ 7 + 8 + #include <linux/dmapool.h> 9 + #include <linux/dma-mapping.h> 10 + #include <linux/init.h> 11 + #include <linux/interrupt.h> 12 + #include <linux/iopoll.h> 13 + #include <linux/module.h> 14 + #include <linux/of.h> 15 + #include <linux/of_dma.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/slab.h> 18 + 19 + #include "dmaengine.h" 20 + #include "virt-dma.h" 21 + 22 + /* Loongson-1 DMA Control Register */ 23 + #define LS1X_DMA_CTRL 0x0 24 + 25 + /* DMA Control Register Bits */ 26 + #define LS1X_DMA_STOP BIT(4) 27 + #define LS1X_DMA_START BIT(3) 28 + #define LS1X_DMA_ASK_VALID BIT(2) 29 + 30 + /* DMA Next Field Bits */ 31 + #define LS1X_DMA_NEXT_VALID BIT(0) 32 + 33 + /* DMA Command Field Bits */ 34 + #define LS1X_DMA_RAM2DEV BIT(12) 35 + #define LS1X_DMA_INT BIT(1) 36 + #define LS1X_DMA_INT_MASK BIT(0) 37 + 38 + #define LS1X_DMA_LLI_ALIGNMENT 64 39 + #define LS1X_DMA_LLI_ADDR_MASK GENMASK(31, __ffs(LS1X_DMA_LLI_ALIGNMENT)) 40 + #define LS1X_DMA_MAX_CHANNELS 3 41 + 42 + enum ls1x_dmadesc_offsets { 43 + LS1X_DMADESC_NEXT = 0, 44 + LS1X_DMADESC_SADDR, 45 + LS1X_DMADESC_DADDR, 46 + LS1X_DMADESC_LENGTH, 47 + LS1X_DMADESC_STRIDE, 48 + LS1X_DMADESC_CYCLES, 49 + LS1X_DMADESC_CMD, 50 + LS1X_DMADESC_SIZE 51 + }; 52 + 53 + struct ls1x_dma_lli { 54 + unsigned int hw[LS1X_DMADESC_SIZE]; 55 + dma_addr_t phys; 56 + struct list_head node; 57 + } __aligned(LS1X_DMA_LLI_ALIGNMENT); 58 + 59 + struct ls1x_dma_desc { 60 + struct virt_dma_desc vd; 61 + struct list_head lli_list; 62 + }; 63 + 64 + struct ls1x_dma_chan { 65 + struct virt_dma_chan vc; 66 + struct dma_pool *lli_pool; 67 + phys_addr_t src_addr; 68 + phys_addr_t dst_addr; 69 + enum dma_slave_buswidth src_addr_width; 70 + enum dma_slave_buswidth dst_addr_width; 71 + unsigned int bus_width; 72 + void __iomem *reg_base; 73 + int irq; 74 + bool is_cyclic; 75 + struct ls1x_dma_lli *curr_lli; 76 + }; 77 + 78 + struct ls1x_dma { 79 + struct dma_device ddev; 80 + unsigned int nr_chans; 81 + struct ls1x_dma_chan chan[]; 82 + }; 83 + 84 + static irqreturn_t ls1x_dma_irq_handler(int irq, void *data); 85 + 86 + #define to_ls1x_dma_chan(dchan) \ 87 + container_of(dchan, struct ls1x_dma_chan, vc.chan) 88 + 89 + #define to_ls1x_dma_desc(d) \ 90 + container_of(d, struct ls1x_dma_desc, vd) 91 + 92 + static inline struct device *chan2dev(struct dma_chan *chan) 93 + { 94 + return &chan->dev->device; 95 + } 96 + 97 + static inline int ls1x_dma_query(struct ls1x_dma_chan *chan, 98 + dma_addr_t *lli_phys) 99 + { 100 + struct dma_chan *dchan = &chan->vc.chan; 101 + int val, ret; 102 + 103 + val = *lli_phys & LS1X_DMA_LLI_ADDR_MASK; 104 + val |= LS1X_DMA_ASK_VALID; 105 + val |= dchan->chan_id; 106 + writel(val, chan->reg_base + LS1X_DMA_CTRL); 107 + ret = readl_poll_timeout_atomic(chan->reg_base + LS1X_DMA_CTRL, val, 108 + !(val & LS1X_DMA_ASK_VALID), 0, 3000); 109 + if (ret) 110 + dev_err(chan2dev(dchan), "failed to query DMA\n"); 111 + 112 + return ret; 113 + } 114 + 115 + static inline int ls1x_dma_start(struct ls1x_dma_chan *chan, 116 + dma_addr_t *lli_phys) 117 + { 118 + struct dma_chan *dchan = &chan->vc.chan; 119 + struct device *dev = chan2dev(dchan); 120 + int val, ret; 121 + 122 + val = *lli_phys & LS1X_DMA_LLI_ADDR_MASK; 123 + val |= LS1X_DMA_START; 124 + val |= dchan->chan_id; 125 + writel(val, chan->reg_base + LS1X_DMA_CTRL); 126 + ret = readl_poll_timeout(chan->reg_base + LS1X_DMA_CTRL, val, 127 + !(val & LS1X_DMA_START), 0, 1000); 128 + if (!ret) 129 + dev_dbg(dev, "start DMA with lli_phys=%pad\n", lli_phys); 130 + else 131 + dev_err(dev, "failed to start DMA\n"); 132 + 133 + return ret; 134 + } 135 + 136 + static inline void ls1x_dma_stop(struct ls1x_dma_chan *chan) 137 + { 138 + int val = readl(chan->reg_base + LS1X_DMA_CTRL); 139 + 140 + writel(val | LS1X_DMA_STOP, chan->reg_base + LS1X_DMA_CTRL); 141 + } 142 + 143 + static void ls1x_dma_free_chan_resources(struct dma_chan *dchan) 144 + { 145 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); 146 + struct device *dev = chan2dev(dchan); 147 + 148 + dma_free_coherent(dev, sizeof(struct ls1x_dma_lli), 149 + chan->curr_lli, chan->curr_lli->phys); 150 + dma_pool_destroy(chan->lli_pool); 151 + chan->lli_pool = NULL; 152 + devm_free_irq(dev, chan->irq, chan); 153 + vchan_free_chan_resources(&chan->vc); 154 + } 155 + 156 + static int ls1x_dma_alloc_chan_resources(struct dma_chan *dchan) 157 + { 158 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); 159 + struct device *dev = chan2dev(dchan); 160 + dma_addr_t phys; 161 + int ret; 162 + 163 + ret = devm_request_irq(dev, chan->irq, ls1x_dma_irq_handler, 164 + IRQF_SHARED, dma_chan_name(dchan), chan); 165 + if (ret) { 166 + dev_err(dev, "failed to request IRQ %d\n", chan->irq); 167 + return ret; 168 + } 169 + 170 + chan->lli_pool = dma_pool_create(dma_chan_name(dchan), dev, 171 + sizeof(struct ls1x_dma_lli), 172 + __alignof__(struct ls1x_dma_lli), 0); 173 + if (!chan->lli_pool) 174 + return -ENOMEM; 175 + 176 + /* allocate memory for querying the current lli */ 177 + dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); 178 + chan->curr_lli = dma_alloc_coherent(dev, sizeof(struct ls1x_dma_lli), 179 + &phys, GFP_KERNEL); 180 + if (!chan->curr_lli) { 181 + dma_pool_destroy(chan->lli_pool); 182 + return -ENOMEM; 183 + } 184 + chan->curr_lli->phys = phys; 185 + 186 + return 0; 187 + } 188 + 189 + static void ls1x_dma_free_desc(struct virt_dma_desc *vd) 190 + { 191 + struct ls1x_dma_desc *desc = to_ls1x_dma_desc(vd); 192 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(vd->tx.chan); 193 + struct ls1x_dma_lli *lli, *_lli; 194 + 195 + list_for_each_entry_safe(lli, _lli, &desc->lli_list, node) { 196 + list_del(&lli->node); 197 + dma_pool_free(chan->lli_pool, lli, lli->phys); 198 + } 199 + 200 + kfree(desc); 201 + } 202 + 203 + static struct ls1x_dma_desc *ls1x_dma_alloc_desc(void) 204 + { 205 + struct ls1x_dma_desc *desc; 206 + 207 + desc = kzalloc(sizeof(*desc), GFP_NOWAIT); 208 + if (!desc) 209 + return NULL; 210 + 211 + INIT_LIST_HEAD(&desc->lli_list); 212 + 213 + return desc; 214 + } 215 + 216 + static int ls1x_dma_prep_lli(struct dma_chan *dchan, struct ls1x_dma_desc *desc, 217 + struct scatterlist *sgl, unsigned int sg_len, 218 + enum dma_transfer_direction dir, bool is_cyclic) 219 + { 220 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); 221 + struct ls1x_dma_lli *lli, *prev = NULL, *first = NULL; 222 + struct device *dev = chan2dev(dchan); 223 + struct list_head *pos = NULL; 224 + struct scatterlist *sg; 225 + unsigned int dev_addr, cmd, i; 226 + 227 + switch (dir) { 228 + case DMA_MEM_TO_DEV: 229 + dev_addr = chan->dst_addr; 230 + chan->bus_width = chan->dst_addr_width; 231 + cmd = LS1X_DMA_RAM2DEV | LS1X_DMA_INT; 232 + break; 233 + case DMA_DEV_TO_MEM: 234 + dev_addr = chan->src_addr; 235 + chan->bus_width = chan->src_addr_width; 236 + cmd = LS1X_DMA_INT; 237 + break; 238 + default: 239 + dev_err(dev, "unsupported DMA direction: %s\n", 240 + dmaengine_get_direction_text(dir)); 241 + return -EINVAL; 242 + } 243 + 244 + for_each_sg(sgl, sg, sg_len, i) { 245 + dma_addr_t buf_addr = sg_dma_address(sg); 246 + size_t buf_len = sg_dma_len(sg); 247 + dma_addr_t phys; 248 + 249 + if (!is_dma_copy_aligned(dchan->device, buf_addr, 0, buf_len)) { 250 + dev_err(dev, "buffer is not aligned\n"); 251 + return -EINVAL; 252 + } 253 + 254 + /* allocate HW descriptors */ 255 + lli = dma_pool_zalloc(chan->lli_pool, GFP_NOWAIT, &phys); 256 + if (!lli) { 257 + dev_err(dev, "failed to alloc lli %u\n", i); 258 + return -ENOMEM; 259 + } 260 + 261 + /* setup HW descriptors */ 262 + lli->phys = phys; 263 + lli->hw[LS1X_DMADESC_SADDR] = buf_addr; 264 + lli->hw[LS1X_DMADESC_DADDR] = dev_addr; 265 + lli->hw[LS1X_DMADESC_LENGTH] = buf_len / chan->bus_width; 266 + lli->hw[LS1X_DMADESC_STRIDE] = 0; 267 + lli->hw[LS1X_DMADESC_CYCLES] = 1; 268 + lli->hw[LS1X_DMADESC_CMD] = cmd; 269 + 270 + if (prev) 271 + prev->hw[LS1X_DMADESC_NEXT] = 272 + lli->phys | LS1X_DMA_NEXT_VALID; 273 + prev = lli; 274 + 275 + if (!first) 276 + first = lli; 277 + 278 + list_add_tail(&lli->node, &desc->lli_list); 279 + } 280 + 281 + if (is_cyclic) { 282 + lli->hw[LS1X_DMADESC_NEXT] = first->phys | LS1X_DMA_NEXT_VALID; 283 + chan->is_cyclic = is_cyclic; 284 + } 285 + 286 + list_for_each(pos, &desc->lli_list) { 287 + lli = list_entry(pos, struct ls1x_dma_lli, node); 288 + print_hex_dump_debug("LLI: ", DUMP_PREFIX_OFFSET, 16, 4, 289 + lli, sizeof(*lli), false); 290 + } 291 + 292 + return 0; 293 + } 294 + 295 + static struct dma_async_tx_descriptor * 296 + ls1x_dma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, 297 + unsigned int sg_len, enum dma_transfer_direction dir, 298 + unsigned long flags, void *context) 299 + { 300 + struct ls1x_dma_desc *desc; 301 + 302 + dev_dbg(chan2dev(dchan), "sg_len=%u flags=0x%lx dir=%s\n", 303 + sg_len, flags, dmaengine_get_direction_text(dir)); 304 + 305 + desc = ls1x_dma_alloc_desc(); 306 + if (!desc) 307 + return NULL; 308 + 309 + if (ls1x_dma_prep_lli(dchan, desc, sgl, sg_len, dir, false)) { 310 + ls1x_dma_free_desc(&desc->vd); 311 + return NULL; 312 + } 313 + 314 + return vchan_tx_prep(to_virt_chan(dchan), &desc->vd, flags); 315 + } 316 + 317 + static struct dma_async_tx_descriptor * 318 + ls1x_dma_prep_dma_cyclic(struct dma_chan *dchan, dma_addr_t buf_addr, 319 + size_t buf_len, size_t period_len, 320 + enum dma_transfer_direction dir, unsigned long flags) 321 + { 322 + struct ls1x_dma_desc *desc; 323 + struct scatterlist *sgl; 324 + unsigned int sg_len; 325 + unsigned int i; 326 + int ret; 327 + 328 + dev_dbg(chan2dev(dchan), 329 + "buf_len=%zu period_len=%zu flags=0x%lx dir=%s\n", 330 + buf_len, period_len, flags, dmaengine_get_direction_text(dir)); 331 + 332 + desc = ls1x_dma_alloc_desc(); 333 + if (!desc) 334 + return NULL; 335 + 336 + /* allocate the scatterlist */ 337 + sg_len = buf_len / period_len; 338 + sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_NOWAIT); 339 + if (!sgl) 340 + return NULL; 341 + 342 + sg_init_table(sgl, sg_len); 343 + for (i = 0; i < sg_len; ++i) { 344 + sg_set_page(&sgl[i], pfn_to_page(PFN_DOWN(buf_addr)), 345 + period_len, offset_in_page(buf_addr)); 346 + sg_dma_address(&sgl[i]) = buf_addr; 347 + sg_dma_len(&sgl[i]) = period_len; 348 + buf_addr += period_len; 349 + } 350 + 351 + ret = ls1x_dma_prep_lli(dchan, desc, sgl, sg_len, dir, true); 352 + kfree(sgl); 353 + if (ret) { 354 + ls1x_dma_free_desc(&desc->vd); 355 + return NULL; 356 + } 357 + 358 + return vchan_tx_prep(to_virt_chan(dchan), &desc->vd, flags); 359 + } 360 + 361 + static int ls1x_dma_slave_config(struct dma_chan *dchan, 362 + struct dma_slave_config *config) 363 + { 364 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); 365 + 366 + chan->src_addr = config->src_addr; 367 + chan->src_addr_width = config->src_addr_width; 368 + chan->dst_addr = config->dst_addr; 369 + chan->dst_addr_width = config->dst_addr_width; 370 + 371 + return 0; 372 + } 373 + 374 + static int ls1x_dma_pause(struct dma_chan *dchan) 375 + { 376 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); 377 + int ret; 378 + 379 + guard(spinlock_irqsave)(&chan->vc.lock); 380 + /* save the current lli */ 381 + ret = ls1x_dma_query(chan, &chan->curr_lli->phys); 382 + if (!ret) 383 + ls1x_dma_stop(chan); 384 + 385 + return ret; 386 + } 387 + 388 + static int ls1x_dma_resume(struct dma_chan *dchan) 389 + { 390 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); 391 + 392 + guard(spinlock_irqsave)(&chan->vc.lock); 393 + 394 + return ls1x_dma_start(chan, &chan->curr_lli->phys); 395 + } 396 + 397 + static int ls1x_dma_terminate_all(struct dma_chan *dchan) 398 + { 399 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); 400 + struct virt_dma_desc *vd; 401 + LIST_HEAD(head); 402 + 403 + ls1x_dma_stop(chan); 404 + 405 + scoped_guard(spinlock_irqsave, &chan->vc.lock) { 406 + vd = vchan_next_desc(&chan->vc); 407 + if (vd) 408 + vchan_terminate_vdesc(vd); 409 + 410 + vchan_get_all_descriptors(&chan->vc, &head); 411 + } 412 + 413 + vchan_dma_desc_free_list(&chan->vc, &head); 414 + 415 + return 0; 416 + } 417 + 418 + static void ls1x_dma_synchronize(struct dma_chan *dchan) 419 + { 420 + vchan_synchronize(to_virt_chan(dchan)); 421 + } 422 + 423 + static enum dma_status ls1x_dma_tx_status(struct dma_chan *dchan, 424 + dma_cookie_t cookie, 425 + struct dma_tx_state *state) 426 + { 427 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); 428 + struct virt_dma_desc *vd; 429 + enum dma_status status; 430 + size_t bytes = 0; 431 + 432 + status = dma_cookie_status(dchan, cookie, state); 433 + if (status == DMA_COMPLETE) 434 + return status; 435 + 436 + scoped_guard(spinlock_irqsave, &chan->vc.lock) { 437 + vd = vchan_find_desc(&chan->vc, cookie); 438 + if (vd) { 439 + struct ls1x_dma_desc *desc = to_ls1x_dma_desc(vd); 440 + struct ls1x_dma_lli *lli; 441 + dma_addr_t next_phys; 442 + 443 + /* get the current lli */ 444 + if (ls1x_dma_query(chan, &chan->curr_lli->phys)) 445 + return status; 446 + 447 + /* locate the current lli */ 448 + next_phys = chan->curr_lli->hw[LS1X_DMADESC_NEXT]; 449 + list_for_each_entry(lli, &desc->lli_list, node) 450 + if (lli->hw[LS1X_DMADESC_NEXT] == next_phys) 451 + break; 452 + 453 + dev_dbg(chan2dev(dchan), "current lli_phys=%pad", 454 + &lli->phys); 455 + 456 + /* count the residues */ 457 + list_for_each_entry_from(lli, &desc->lli_list, node) 458 + bytes += lli->hw[LS1X_DMADESC_LENGTH] * 459 + chan->bus_width; 460 + } 461 + } 462 + 463 + dma_set_residue(state, bytes); 464 + 465 + return status; 466 + } 467 + 468 + static void ls1x_dma_issue_pending(struct dma_chan *dchan) 469 + { 470 + struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); 471 + 472 + guard(spinlock_irqsave)(&chan->vc.lock); 473 + 474 + if (vchan_issue_pending(&chan->vc)) { 475 + struct virt_dma_desc *vd = vchan_next_desc(&chan->vc); 476 + 477 + if (vd) { 478 + struct ls1x_dma_desc *desc = to_ls1x_dma_desc(vd); 479 + struct ls1x_dma_lli *lli; 480 + 481 + lli = list_first_entry(&desc->lli_list, 482 + struct ls1x_dma_lli, node); 483 + ls1x_dma_start(chan, &lli->phys); 484 + } 485 + } 486 + } 487 + 488 + static irqreturn_t ls1x_dma_irq_handler(int irq, void *data) 489 + { 490 + struct ls1x_dma_chan *chan = data; 491 + struct dma_chan *dchan = &chan->vc.chan; 492 + struct device *dev = chan2dev(dchan); 493 + struct virt_dma_desc *vd; 494 + 495 + scoped_guard(spinlock, &chan->vc.lock) { 496 + vd = vchan_next_desc(&chan->vc); 497 + if (!vd) { 498 + dev_warn(dev, 499 + "IRQ %d with no active desc on channel %d\n", 500 + irq, dchan->chan_id); 501 + return IRQ_NONE; 502 + } 503 + 504 + if (chan->is_cyclic) { 505 + vchan_cyclic_callback(vd); 506 + } else { 507 + list_del(&vd->node); 508 + vchan_cookie_complete(vd); 509 + } 510 + } 511 + 512 + dev_dbg(dev, "DMA IRQ %d on channel %d\n", irq, dchan->chan_id); 513 + 514 + return IRQ_HANDLED; 515 + } 516 + 517 + static int ls1x_dma_chan_probe(struct platform_device *pdev, 518 + struct ls1x_dma *dma) 519 + { 520 + void __iomem *reg_base; 521 + int id; 522 + 523 + reg_base = devm_platform_ioremap_resource(pdev, 0); 524 + if (IS_ERR(reg_base)) 525 + return PTR_ERR(reg_base); 526 + 527 + for (id = 0; id < dma->nr_chans; id++) { 528 + struct ls1x_dma_chan *chan = &dma->chan[id]; 529 + char pdev_irqname[16]; 530 + 531 + snprintf(pdev_irqname, sizeof(pdev_irqname), "ch%d", id); 532 + chan->irq = platform_get_irq_byname(pdev, pdev_irqname); 533 + if (chan->irq < 0) 534 + return dev_err_probe(&pdev->dev, chan->irq, 535 + "failed to get IRQ for ch%d\n", 536 + id); 537 + 538 + chan->reg_base = reg_base; 539 + chan->vc.desc_free = ls1x_dma_free_desc; 540 + vchan_init(&chan->vc, &dma->ddev); 541 + } 542 + 543 + return 0; 544 + } 545 + 546 + static void ls1x_dma_chan_remove(struct ls1x_dma *dma) 547 + { 548 + int id; 549 + 550 + for (id = 0; id < dma->nr_chans; id++) { 551 + struct ls1x_dma_chan *chan = &dma->chan[id]; 552 + 553 + if (chan->vc.chan.device == &dma->ddev) { 554 + list_del(&chan->vc.chan.device_node); 555 + tasklet_kill(&chan->vc.task); 556 + } 557 + } 558 + } 559 + 560 + static int ls1x_dma_probe(struct platform_device *pdev) 561 + { 562 + struct device *dev = &pdev->dev; 563 + struct dma_device *ddev; 564 + struct ls1x_dma *dma; 565 + int ret; 566 + 567 + ret = platform_irq_count(pdev); 568 + if (ret <= 0 || ret > LS1X_DMA_MAX_CHANNELS) 569 + return dev_err_probe(dev, -EINVAL, 570 + "Invalid number of IRQ channels: %d\n", 571 + ret); 572 + 573 + dma = devm_kzalloc(dev, struct_size(dma, chan, ret), GFP_KERNEL); 574 + if (!dma) 575 + return -ENOMEM; 576 + dma->nr_chans = ret; 577 + 578 + /* initialize DMA device */ 579 + ddev = &dma->ddev; 580 + ddev->dev = dev; 581 + ddev->copy_align = DMAENGINE_ALIGN_4_BYTES; 582 + ddev->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | 583 + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | 584 + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); 585 + ddev->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | 586 + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | 587 + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); 588 + ddev->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); 589 + ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; 590 + ddev->device_alloc_chan_resources = ls1x_dma_alloc_chan_resources; 591 + ddev->device_free_chan_resources = ls1x_dma_free_chan_resources; 592 + ddev->device_prep_slave_sg = ls1x_dma_prep_slave_sg; 593 + ddev->device_prep_dma_cyclic = ls1x_dma_prep_dma_cyclic; 594 + ddev->device_config = ls1x_dma_slave_config; 595 + ddev->device_pause = ls1x_dma_pause; 596 + ddev->device_resume = ls1x_dma_resume; 597 + ddev->device_terminate_all = ls1x_dma_terminate_all; 598 + ddev->device_synchronize = ls1x_dma_synchronize; 599 + ddev->device_tx_status = ls1x_dma_tx_status; 600 + ddev->device_issue_pending = ls1x_dma_issue_pending; 601 + dma_cap_set(DMA_SLAVE, ddev->cap_mask); 602 + INIT_LIST_HEAD(&ddev->channels); 603 + 604 + /* initialize DMA channels */ 605 + ret = ls1x_dma_chan_probe(pdev, dma); 606 + if (ret) 607 + goto err; 608 + 609 + ret = dmaenginem_async_device_register(ddev); 610 + if (ret) { 611 + dev_err(dev, "failed to register DMA device\n"); 612 + goto err; 613 + } 614 + 615 + ret = of_dma_controller_register(dev->of_node, of_dma_xlate_by_chan_id, 616 + ddev); 617 + if (ret) { 618 + dev_err(dev, "failed to register DMA controller\n"); 619 + goto err; 620 + } 621 + 622 + platform_set_drvdata(pdev, dma); 623 + dev_info(dev, "Loongson1 DMA driver registered\n"); 624 + 625 + return 0; 626 + 627 + err: 628 + ls1x_dma_chan_remove(dma); 629 + 630 + return ret; 631 + } 632 + 633 + static void ls1x_dma_remove(struct platform_device *pdev) 634 + { 635 + struct ls1x_dma *dma = platform_get_drvdata(pdev); 636 + 637 + of_dma_controller_free(pdev->dev.of_node); 638 + ls1x_dma_chan_remove(dma); 639 + } 640 + 641 + static const struct of_device_id ls1x_dma_match[] = { 642 + { .compatible = "loongson,ls1b-apbdma" }, 643 + { /* sentinel */ } 644 + }; 645 + MODULE_DEVICE_TABLE(of, ls1x_dma_match); 646 + 647 + static struct platform_driver ls1x_dma_driver = { 648 + .probe = ls1x_dma_probe, 649 + .remove = ls1x_dma_remove, 650 + .driver = { 651 + .name = KBUILD_MODNAME, 652 + .of_match_table = ls1x_dma_match, 653 + }, 654 + }; 655 + 656 + module_platform_driver(ls1x_dma_driver); 657 + 658 + MODULE_AUTHOR("Keguang Zhang <keguang.zhang@gmail.com>"); 659 + MODULE_DESCRIPTION("Loongson-1 APB DMA Controller driver"); 660 + MODULE_LICENSE("GPL");
+195
drivers/dma/lpc32xx-dmamux.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // Copyright 2024 Timesys Corporation <piotr.wojtaszczyk@timesys.com> 4 + // 5 + // Based on TI DMA Crossbar driver by: 6 + // Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com 7 + // Author: Peter Ujfalusi <peter.ujfalusi@ti.com> 8 + 9 + #include <linux/err.h> 10 + #include <linux/init.h> 11 + #include <linux/mfd/syscon.h> 12 + #include <linux/of.h> 13 + #include <linux/of_dma.h> 14 + #include <linux/of_platform.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/regmap.h> 17 + #include <linux/spinlock.h> 18 + 19 + #define LPC32XX_SSP_CLK_CTRL 0x78 20 + #define LPC32XX_I2S_CLK_CTRL 0x7c 21 + 22 + struct lpc32xx_dmamux { 23 + int signal; 24 + char *name_sel0; 25 + char *name_sel1; 26 + int muxval; 27 + int muxreg; 28 + int bit; 29 + bool busy; 30 + }; 31 + 32 + struct lpc32xx_dmamux_data { 33 + struct dma_router dmarouter; 34 + struct regmap *reg; 35 + spinlock_t lock; /* protects busy status flag */ 36 + }; 37 + 38 + /* From LPC32x0 User manual "3.2.1 DMA request signals" */ 39 + static struct lpc32xx_dmamux lpc32xx_muxes[] = { 40 + { 41 + .signal = 3, 42 + .name_sel0 = "spi2-rx-tx", 43 + .name_sel1 = "ssp1-rx", 44 + .muxreg = LPC32XX_SSP_CLK_CTRL, 45 + .bit = 5, 46 + }, 47 + { 48 + .signal = 10, 49 + .name_sel0 = "uart7-rx", 50 + .name_sel1 = "i2s1-dma1", 51 + .muxreg = LPC32XX_I2S_CLK_CTRL, 52 + .bit = 4, 53 + }, 54 + { 55 + .signal = 11, 56 + .name_sel0 = "spi1-rx-tx", 57 + .name_sel1 = "ssp1-tx", 58 + .muxreg = LPC32XX_SSP_CLK_CTRL, 59 + .bit = 4, 60 + }, 61 + { 62 + .signal = 14, 63 + .name_sel0 = "none", 64 + .name_sel1 = "ssp0-rx", 65 + .muxreg = LPC32XX_SSP_CLK_CTRL, 66 + .bit = 3, 67 + }, 68 + { 69 + .signal = 15, 70 + .name_sel0 = "none", 71 + .name_sel1 = "ssp0-tx", 72 + .muxreg = LPC32XX_SSP_CLK_CTRL, 73 + .bit = 2, 74 + }, 75 + }; 76 + 77 + static void lpc32xx_dmamux_release(struct device *dev, void *route_data) 78 + { 79 + struct lpc32xx_dmamux_data *dmamux = dev_get_drvdata(dev); 80 + struct lpc32xx_dmamux *mux = route_data; 81 + 82 + dev_dbg(dev, "releasing dma request signal %d routed to %s\n", 83 + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1); 84 + 85 + guard(spinlock)(&dmamux->lock); 86 + 87 + mux->busy = false; 88 + } 89 + 90 + static void *lpc32xx_dmamux_reserve(struct of_phandle_args *dma_spec, 91 + struct of_dma *ofdma) 92 + { 93 + struct platform_device *pdev = of_find_device_by_node(ofdma->of_node); 94 + struct device *dev = &pdev->dev; 95 + struct lpc32xx_dmamux_data *dmamux = platform_get_drvdata(pdev); 96 + unsigned long flags; 97 + struct lpc32xx_dmamux *mux = NULL; 98 + int i; 99 + 100 + if (dma_spec->args_count != 3) { 101 + dev_err(&pdev->dev, "invalid number of dma mux args\n"); 102 + return ERR_PTR(-EINVAL); 103 + } 104 + 105 + for (i = 0; i < ARRAY_SIZE(lpc32xx_muxes); i++) { 106 + if (lpc32xx_muxes[i].signal == dma_spec->args[0]) { 107 + mux = &lpc32xx_muxes[i]; 108 + break; 109 + } 110 + } 111 + if (!mux) { 112 + dev_err(&pdev->dev, "invalid mux request number: %d\n", 113 + dma_spec->args[0]); 114 + return ERR_PTR(-EINVAL); 115 + } 116 + 117 + if (dma_spec->args[2] > 1) { 118 + dev_err(&pdev->dev, "invalid dma mux value: %d\n", 119 + dma_spec->args[1]); 120 + return ERR_PTR(-EINVAL); 121 + } 122 + 123 + /* The of_node_put() will be done in the core for the node */ 124 + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0); 125 + if (!dma_spec->np) { 126 + dev_err(&pdev->dev, "can't get dma master\n"); 127 + return ERR_PTR(-EINVAL); 128 + } 129 + 130 + spin_lock_irqsave(&dmamux->lock, flags); 131 + if (mux->busy) { 132 + spin_unlock_irqrestore(&dmamux->lock, flags); 133 + dev_err(dev, "dma request signal %d busy, routed to %s\n", 134 + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1); 135 + of_node_put(dma_spec->np); 136 + return ERR_PTR(-EBUSY); 137 + } 138 + 139 + mux->busy = true; 140 + mux->muxval = dma_spec->args[2] ? BIT(mux->bit) : 0; 141 + 142 + regmap_update_bits(dmamux->reg, mux->muxreg, BIT(mux->bit), mux->muxval); 143 + spin_unlock_irqrestore(&dmamux->lock, flags); 144 + 145 + dma_spec->args[2] = 0; 146 + dma_spec->args_count = 2; 147 + 148 + dev_dbg(dev, "dma request signal %d routed to %s\n", 149 + mux->signal, mux->muxval ? mux->name_sel1 : mux->name_sel1); 150 + 151 + return mux; 152 + } 153 + 154 + static int lpc32xx_dmamux_probe(struct platform_device *pdev) 155 + { 156 + struct device_node *np = pdev->dev.of_node; 157 + struct lpc32xx_dmamux_data *dmamux; 158 + 159 + dmamux = devm_kzalloc(&pdev->dev, sizeof(*dmamux), GFP_KERNEL); 160 + if (!dmamux) 161 + return -ENOMEM; 162 + 163 + dmamux->reg = syscon_node_to_regmap(np->parent); 164 + if (IS_ERR(dmamux->reg)) { 165 + dev_err(&pdev->dev, "syscon lookup failed\n"); 166 + return PTR_ERR(dmamux->reg); 167 + } 168 + 169 + spin_lock_init(&dmamux->lock); 170 + platform_set_drvdata(pdev, dmamux); 171 + dmamux->dmarouter.dev = &pdev->dev; 172 + dmamux->dmarouter.route_free = lpc32xx_dmamux_release; 173 + 174 + return of_dma_router_register(np, lpc32xx_dmamux_reserve, 175 + &dmamux->dmarouter); 176 + } 177 + 178 + static const struct of_device_id lpc32xx_dmamux_match[] = { 179 + { .compatible = "nxp,lpc3220-dmamux" }, 180 + {}, 181 + }; 182 + 183 + static struct platform_driver lpc32xx_dmamux_driver = { 184 + .probe = lpc32xx_dmamux_probe, 185 + .driver = { 186 + .name = "lpc32xx-dmamux", 187 + .of_match_table = lpc32xx_dmamux_match, 188 + }, 189 + }; 190 + 191 + static int __init lpc32xx_dmamux_init(void) 192 + { 193 + return platform_driver_register(&lpc32xx_dmamux_driver); 194 + } 195 + arch_initcall(lpc32xx_dmamux_init);
+2 -2
drivers/dma/ls2x-apb-dma.c
··· 33 33 #define LDMA_STOP BIT(4) /* DMA stop operation */ 34 34 #define LDMA_CONFIG_MASK GENMASK(4, 0) /* DMA controller config bits mask */ 35 35 36 - /* Bitfields in ndesc_addr field of HW decriptor */ 36 + /* Bitfields in ndesc_addr field of HW descriptor */ 37 37 #define LDMA_DESC_EN BIT(0) /*1: The next descriptor is valid */ 38 38 #define LDMA_DESC_ADDR_LOW GENMASK(31, 1) 39 39 40 - /* Bitfields in cmd field of HW decriptor */ 40 + /* Bitfields in cmd field of HW descriptor */ 41 41 #define LDMA_INT BIT(1) /* Enable DMA interrupts */ 42 42 #define LDMA_DATA_DIRECTION BIT(12) /* 1: write to device, 0: read from device */ 43 43
+2 -2
drivers/dma/mediatek/mtk-cqdma.c
··· 518 518 /* setup dma channel */ 519 519 cvd[i]->ch = c; 520 520 521 - /* setup sourece, destination, and length */ 521 + /* setup source, destination, and length */ 522 522 tlen = (len > MTK_CQDMA_MAX_LEN) ? MTK_CQDMA_MAX_LEN : len; 523 523 cvd[i]->len = tlen; 524 524 cvd[i]->src = src; ··· 617 617 u32 i, min_refcnt = U32_MAX, refcnt; 618 618 unsigned long flags; 619 619 620 - /* allocate PC with the minimun refcount */ 620 + /* allocate PC with the minimum refcount */ 621 621 for (i = 0; i < cqdma->dma_channels; ++i) { 622 622 refcnt = refcount_read(&cqdma->pc[i]->refcnt); 623 623 if (refcnt < min_refcnt) {
+1 -1
drivers/dma/mediatek/mtk-hsdma.c
··· 226 226 * @pc_refcnt: Track how many VCs are using the PC 227 227 * @lock: Lock protect agaisting multiple VCs access PC 228 228 * @soc: The pointer to area holding differences among 229 - * vaious platform 229 + * various platform 230 230 */ 231 231 struct mtk_hsdma_device { 232 232 struct dma_device ddev;
+2 -2
drivers/dma/mv_xor.c
··· 414 414 if (!mv_chan_is_busy(mv_chan)) { 415 415 u32 current_desc = mv_chan_get_current_desc(mv_chan); 416 416 /* 417 - * and the curren desc is the end of the chain before 417 + * and the current desc is the end of the chain before 418 418 * the append, then we need to start the channel 419 419 */ 420 420 if (current_desc == old_chain_tail->async_tx.phys) ··· 1074 1074 if (!mv_chan->dma_desc_pool_virt) 1075 1075 return ERR_PTR(-ENOMEM); 1076 1076 1077 - /* discover transaction capabilites from the platform data */ 1077 + /* discover transaction capabilities from the platform data */ 1078 1078 dma_dev->cap_mask = cap_mask; 1079 1079 1080 1080 INIT_LIST_HEAD(&dma_dev->channels);
+1 -1
drivers/dma/mv_xor.h
··· 99 99 * @common: common dmaengine channel object members 100 100 * @slots_allocated: records the actual size of the descriptor slot pool 101 101 * @irq_tasklet: bottom half where mv_xor_slot_cleanup runs 102 - * @op_in_desc: new mode of driver, each op is writen to descriptor. 102 + * @op_in_desc: new mode of driver, each op is written to descriptor. 103 103 */ 104 104 struct mv_xor_chan { 105 105 int pending;
+1 -1
drivers/dma/mv_xor_v2.c
··· 175 175 * struct mv_xor_v2_sw_desc - implements a xor SW descriptor 176 176 * @idx: descriptor index 177 177 * @async_tx: support for the async_tx api 178 - * @hw_desc: assosiated HW descriptor 178 + * @hw_desc: associated HW descriptor 179 179 * @free_list: node of the free SW descriprots list 180 180 */ 181 181 struct mv_xor_v2_sw_desc {
+1 -1
drivers/dma/nbpfaxi.c
··· 897 897 /* 898 898 * We could check config->slave_id to match chan->terminal here, 899 899 * but with DT they would be coming from the same source, so 900 - * such a check would be superflous 900 + * such a check would be superfluous 901 901 */ 902 902 903 903 chan->slave_dst_addr = config->dst_addr;
+2 -2
drivers/dma/of-dma.c
··· 26 26 * 27 27 * Finds a DMA controller with matching device node and number for dma cells 28 28 * in a list of registered DMA controllers. If a match is found a valid pointer 29 - * to the DMA data stored is retuned. A NULL pointer is returned if no match is 29 + * to the DMA data stored is returned. A NULL pointer is returned if no match is 30 30 * found. 31 31 */ 32 32 static struct of_dma *of_dma_find_controller(const struct of_phandle_args *dma_spec) ··· 342 342 * 343 343 * This function can be used as the of xlate callback for DMA driver which wants 344 344 * to match the channel based on the channel id. When using this xlate function 345 - * the #dma-cells propety of the DMA controller dt node needs to be set to 1. 345 + * the #dma-cells property of the DMA controller dt node needs to be set to 1. 346 346 * The data parameter of of_dma_controller_register must be a pointer to the 347 347 * dma_device struct the function should match upon. 348 348 *
+1 -1
drivers/dma/owl-dma.c
··· 1156 1156 } 1157 1157 1158 1158 /* 1159 - * Eventhough the DMA controller is capable of generating 4 1159 + * Even though the DMA controller is capable of generating 4 1160 1160 * IRQ's for DMA priority feature, we only use 1 IRQ for 1161 1161 * simplification. 1162 1162 */
+1 -1
drivers/dma/ppc4xx/adma.c
··· 9 9 */ 10 10 11 11 /* 12 - * This driver supports the asynchrounous DMA copy and RAID engines available 12 + * This driver supports the asynchronous DMA copy and RAID engines available 13 13 * on the AMCC PPC440SPe Processors. 14 14 * Based on the Intel Xscale(R) family of I/O Processors (IOP 32x, 33x, 134x) 15 15 * ADMA driver written by D.Williams.
+1 -1
drivers/dma/ppc4xx/dma.h
··· 14 14 15 15 /* Number of elements in the array with statical CDBs */ 16 16 #define MAX_STAT_DMA_CDBS 16 17 - /* Number of DMA engines available on the contoller */ 17 + /* Number of DMA engines available on the controller */ 18 18 #define DMA_ENGINES_NUM 2 19 19 20 20 /* Maximum h/w supported number of destinations */
+1 -1
drivers/dma/ptdma/ptdma.h
··· 192 192 /* Queue dma pool */ 193 193 struct dma_pool *dma_pool; 194 194 195 - /* Queue base address (not neccessarily aligned)*/ 195 + /* Queue base address (not necessarily aligned)*/ 196 196 struct ptdma_desc *qbase; 197 197 198 198 /* Aligned queue start address (per requirement) */
+2 -2
drivers/dma/qcom/bam_dma.c
··· 440 440 val |= BAM_EN; 441 441 writel_relaxed(val, bam_addr(bdev, 0, BAM_CTRL)); 442 442 443 - /* set descriptor threshhold, start with 4 bytes */ 443 + /* set descriptor threshold, start with 4 bytes */ 444 444 writel_relaxed(DEFAULT_CNT_THRSHLD, 445 445 bam_addr(bdev, 0, BAM_DESC_CNT_TRSHLD)); 446 446 ··· 667 667 for_each_sg(sgl, sg, sg_len, i) 668 668 num_alloc += DIV_ROUND_UP(sg_dma_len(sg), BAM_FIFO_SIZE); 669 669 670 - /* allocate enough room to accomodate the number of entries */ 670 + /* allocate enough room to accommodate the number of entries */ 671 671 async_desc = kzalloc(struct_size(async_desc, desc, num_alloc), 672 672 GFP_NOWAIT); 673 673
+1 -1
drivers/dma/qcom/gpi.c
··· 1856 1856 1857 1857 read_lock_irqsave(&gpii->pm_lock, pm_lock_flags); 1858 1858 1859 - /* move all submitted discriptors to issued list */ 1859 + /* move all submitted descriptors to issued list */ 1860 1860 spin_lock_irqsave(&gchan->vc.lock, flags); 1861 1861 if (vchan_issue_pending(&gchan->vc)) 1862 1862 vd = list_last_entry(&gchan->vc.desc_issued,
+1 -1
drivers/dma/qcom/qcom_adm.c
··· 650 650 /* 651 651 * residue is either the full length if it is in the issued list, or 0 652 652 * if it is in progress. We have no reliable way of determining 653 - * anything inbetween 653 + * anything in between 654 654 */ 655 655 dma_set_residue(txstate, residue); 656 656
+1 -1
drivers/dma/sh/shdmac.c
··· 318 318 } 319 319 320 320 /* 321 - * Find a slave channel configuration from the contoller list by either a slave 321 + * Find a slave channel configuration from the controller list by either a slave 322 322 * ID in the non-DT case, or by a MID/RID value in the DT case 323 323 */ 324 324 static const struct sh_dmae_slave_config *dmae_find_slave(
+1 -1
drivers/dma/ste_dma40.h
··· 4 4 #define STE_DMA40_H 5 5 6 6 /* 7 - * Maxium size for a single dma descriptor 7 + * Maximum size for a single dma descriptor 8 8 * Size is limited to 16 bits. 9 9 * Size is in the units of addr-widths (1,2,4,8 bytes) 10 10 * Larger transfers will be split up to multiple linked desc
+1 -1
drivers/dma/ste_dma40_ll.h
··· 369 369 * @lcsp02: Either maps to register lcsp0 if src or lcsp2 if dst. 370 370 * @lcsp13: Either maps to register lcsp1 if src or lcsp3 if dst. 371 371 * 372 - * This struct must be 8 bytes aligned since it will be accessed directy by 372 + * This struct must be 8 bytes aligned since it will be accessed directly by 373 373 * the DMA. Never add any none hw mapped registers to this struct. 374 374 */ 375 375
+1 -1
drivers/dma/tegra20-apb-dma.c
··· 463 463 464 464 /* 465 465 * If interrupt is pending then do nothing as the ISR will handle 466 - * the programing for new request. 466 + * the programming for new request. 467 467 */ 468 468 if (status & TEGRA_APBDMA_STATUS_ISE_EOC) { 469 469 dev_err(tdc2dev(tdc),
-1
drivers/dma/ti/k3-udma.h
··· 131 131 struct udma_dev *of_xudma_dev_get(struct device_node *np, const char *property); 132 132 struct device *xudma_get_device(struct udma_dev *ud); 133 133 struct k3_ringacc *xudma_get_ringacc(struct udma_dev *ud); 134 - void xudma_dev_put(struct udma_dev *ud); 135 134 u32 xudma_dev_get_psil_base(struct udma_dev *ud); 136 135 struct udma_tisci_rm *xudma_dev_get_tisci_rm(struct udma_dev *ud); 137 136
+1 -1
drivers/dma/xgene-dma.c
··· 1742 1742 /* Initialize DMA channels software state */ 1743 1743 xgene_dma_init_channels(pdma); 1744 1744 1745 - /* Configue DMA rings */ 1745 + /* Configure DMA rings */ 1746 1746 ret = xgene_dma_init_rings(pdma); 1747 1747 if (ret) 1748 1748 goto err_clk_enable;
+99 -2
drivers/dma/xilinx/xilinx_dpdma.c
··· 149 149 * @addr_ext: upper 16 bit of 48 bit address (next_desc and src_addr) 150 150 * @next_desc: next descriptor 32 bit address 151 151 * @src_addr: payload source address (1st page, 32 LSB) 152 - * @addr_ext_23: payload source address (3nd and 3rd pages, 16 LSBs) 152 + * @addr_ext_23: payload source address (2nd and 3rd pages, 16 LSBs) 153 153 * @addr_ext_45: payload source address (4th and 5th pages, 16 LSBs) 154 154 * @src_addr2: payload source address (2nd page, 32 LSB) 155 155 * @src_addr3: payload source address (3rd page, 32 LSB) ··· 210 210 * @vchan: virtual DMA channel 211 211 * @reg: register base address 212 212 * @id: channel ID 213 - * @wait_to_stop: queue to wait for outstanding transacitons before stopping 213 + * @wait_to_stop: queue to wait for outstanding transactions before stopping 214 214 * @running: true if the channel is running 215 215 * @first_frame: flag for the first frame of stream 216 216 * @video_group: flag if multi-channel operation is needed for video channels ··· 668 668 } 669 669 670 670 kfree(desc); 671 + } 672 + 673 + /** 674 + * xilinx_dpdma_chan_prep_cyclic - Prepare a cyclic dma descriptor 675 + * @chan: DPDMA channel 676 + * @buf_addr: buffer address 677 + * @buf_len: buffer length 678 + * @period_len: number of periods 679 + * @flags: tx flags argument passed in to prepare function 680 + * 681 + * Prepare a tx descriptor incudling internal software/hardware descriptors 682 + * for the given cyclic transaction. 683 + * 684 + * Return: A dma async tx descriptor on success, or NULL. 685 + */ 686 + static struct dma_async_tx_descriptor * 687 + xilinx_dpdma_chan_prep_cyclic(struct xilinx_dpdma_chan *chan, 688 + dma_addr_t buf_addr, size_t buf_len, 689 + size_t period_len, unsigned long flags) 690 + { 691 + struct xilinx_dpdma_tx_desc *tx_desc; 692 + struct xilinx_dpdma_sw_desc *sw_desc, *last = NULL; 693 + unsigned int periods = buf_len / period_len; 694 + unsigned int i; 695 + 696 + tx_desc = xilinx_dpdma_chan_alloc_tx_desc(chan); 697 + if (!tx_desc) 698 + return NULL; 699 + 700 + for (i = 0; i < periods; i++) { 701 + struct xilinx_dpdma_hw_desc *hw_desc; 702 + 703 + if (!IS_ALIGNED(buf_addr, XILINX_DPDMA_ALIGN_BYTES)) { 704 + dev_err(chan->xdev->dev, 705 + "buffer should be aligned at %d B\n", 706 + XILINX_DPDMA_ALIGN_BYTES); 707 + goto error; 708 + } 709 + 710 + sw_desc = xilinx_dpdma_chan_alloc_sw_desc(chan); 711 + if (!sw_desc) 712 + goto error; 713 + 714 + xilinx_dpdma_sw_desc_set_dma_addrs(chan->xdev, sw_desc, last, 715 + &buf_addr, 1); 716 + hw_desc = &sw_desc->hw; 717 + hw_desc->xfer_size = period_len; 718 + hw_desc->hsize_stride = 719 + FIELD_PREP(XILINX_DPDMA_DESC_HSIZE_STRIDE_HSIZE_MASK, 720 + period_len) | 721 + FIELD_PREP(XILINX_DPDMA_DESC_HSIZE_STRIDE_STRIDE_MASK, 722 + period_len); 723 + hw_desc->control = XILINX_DPDMA_DESC_CONTROL_PREEMBLE | 724 + XILINX_DPDMA_DESC_CONTROL_IGNORE_DONE | 725 + XILINX_DPDMA_DESC_CONTROL_COMPLETE_INTR; 726 + 727 + list_add_tail(&sw_desc->node, &tx_desc->descriptors); 728 + 729 + buf_addr += period_len; 730 + last = sw_desc; 731 + } 732 + 733 + sw_desc = list_first_entry(&tx_desc->descriptors, 734 + struct xilinx_dpdma_sw_desc, node); 735 + last->hw.next_desc = lower_32_bits(sw_desc->dma_addr); 736 + if (chan->xdev->ext_addr) 737 + last->hw.addr_ext |= 738 + FIELD_PREP(XILINX_DPDMA_DESC_ADDR_EXT_NEXT_ADDR_MASK, 739 + upper_32_bits(sw_desc->dma_addr)); 740 + 741 + last->hw.control |= XILINX_DPDMA_DESC_CONTROL_LAST_OF_FRAME; 742 + 743 + return vchan_tx_prep(&chan->vchan, &tx_desc->vdesc, flags); 744 + 745 + error: 746 + xilinx_dpdma_chan_free_tx_desc(&tx_desc->vdesc); 747 + 748 + return NULL; 671 749 } 672 750 673 751 /** ··· 1267 1189 /* ----------------------------------------------------------------------------- 1268 1190 * DMA Engine Operations 1269 1191 */ 1192 + static struct dma_async_tx_descriptor * 1193 + xilinx_dpdma_prep_dma_cyclic(struct dma_chan *dchan, dma_addr_t buf_addr, 1194 + size_t buf_len, size_t period_len, 1195 + enum dma_transfer_direction direction, 1196 + unsigned long flags) 1197 + { 1198 + struct xilinx_dpdma_chan *chan = to_xilinx_chan(dchan); 1199 + 1200 + if (direction != DMA_MEM_TO_DEV) 1201 + return NULL; 1202 + 1203 + if (buf_len % period_len) 1204 + return NULL; 1205 + 1206 + return xilinx_dpdma_chan_prep_cyclic(chan, buf_addr, buf_len, 1207 + period_len, flags); 1208 + } 1270 1209 1271 1210 static struct dma_async_tx_descriptor * 1272 1211 xilinx_dpdma_prep_interleaved_dma(struct dma_chan *dchan, ··· 1767 1672 1768 1673 dma_cap_set(DMA_SLAVE, ddev->cap_mask); 1769 1674 dma_cap_set(DMA_PRIVATE, ddev->cap_mask); 1675 + dma_cap_set(DMA_CYCLIC, ddev->cap_mask); 1770 1676 dma_cap_set(DMA_INTERLEAVE, ddev->cap_mask); 1771 1677 dma_cap_set(DMA_REPEAT, ddev->cap_mask); 1772 1678 dma_cap_set(DMA_LOAD_EOT, ddev->cap_mask); ··· 1775 1679 1776 1680 ddev->device_alloc_chan_resources = xilinx_dpdma_alloc_chan_resources; 1777 1681 ddev->device_free_chan_resources = xilinx_dpdma_free_chan_resources; 1682 + ddev->device_prep_dma_cyclic = xilinx_dpdma_prep_dma_cyclic; 1778 1683 ddev->device_prep_interleaved_dma = xilinx_dpdma_prep_interleaved_dma; 1779 1684 /* TODO: Can we achieve better granularity ? */ 1780 1685 ddev->device_tx_status = dma_cookie_status;
+23 -4
drivers/dma/xilinx/zynqmp_dma.c
··· 22 22 #include "../dmaengine.h" 23 23 24 24 /* Register Offsets */ 25 - #define ZYNQMP_DMA_ISR 0x100 26 - #define ZYNQMP_DMA_IMR 0x104 27 - #define ZYNQMP_DMA_IER 0x108 28 - #define ZYNQMP_DMA_IDS 0x10C 25 + #define ZYNQMP_DMA_ISR (chan->irq_offset + 0x100) 26 + #define ZYNQMP_DMA_IMR (chan->irq_offset + 0x104) 27 + #define ZYNQMP_DMA_IER (chan->irq_offset + 0x108) 28 + #define ZYNQMP_DMA_IDS (chan->irq_offset + 0x10c) 29 29 #define ZYNQMP_DMA_CTRL0 0x110 30 30 #define ZYNQMP_DMA_CTRL1 0x114 31 31 #define ZYNQMP_DMA_DATA_ATTR 0x120 ··· 145 145 #define tx_to_desc(tx) container_of(tx, struct zynqmp_dma_desc_sw, \ 146 146 async_tx) 147 147 148 + /* IRQ Register offset for Versal Gen 2 */ 149 + #define IRQ_REG_OFFSET 0x308 150 + 148 151 /** 149 152 * struct zynqmp_dma_desc_ll - Hw linked list descriptor 150 153 * @addr: Buffer address ··· 214 211 * @bus_width: Bus width 215 212 * @src_burst_len: Source burst length 216 213 * @dst_burst_len: Dest burst length 214 + * @irq_offset: Irq register offset 217 215 */ 218 216 struct zynqmp_dma_chan { 219 217 struct zynqmp_dma_device *zdev; ··· 239 235 u32 bus_width; 240 236 u32 src_burst_len; 241 237 u32 dst_burst_len; 238 + u32 irq_offset; 242 239 }; 243 240 244 241 /** ··· 256 251 struct zynqmp_dma_chan *chan; 257 252 struct clk *clk_main; 258 253 struct clk *clk_apb; 254 + }; 255 + 256 + struct zynqmp_dma_config { 257 + u32 offset; 258 + }; 259 + 260 + static const struct zynqmp_dma_config versal2_dma_config = { 261 + .offset = IRQ_REG_OFFSET, 259 262 }; 260 263 261 264 static inline void zynqmp_dma_writeq(struct zynqmp_dma_chan *chan, u32 reg, ··· 905 892 { 906 893 struct zynqmp_dma_chan *chan; 907 894 struct device_node *node = pdev->dev.of_node; 895 + const struct zynqmp_dma_config *match_data; 908 896 int err; 909 897 910 898 chan = devm_kzalloc(zdev->dev, sizeof(*chan), GFP_KERNEL); ··· 932 918 dev_err(zdev->dev, "invalid bus-width value"); 933 919 return -EINVAL; 934 920 } 921 + 922 + match_data = of_device_get_match_data(&pdev->dev); 923 + if (match_data) 924 + chan->irq_offset = match_data->offset; 935 925 936 926 chan->is_dmacoherent = of_property_read_bool(node, "dma-coherent"); 937 927 zdev->chan = chan; ··· 1179 1161 } 1180 1162 1181 1163 static const struct of_device_id zynqmp_dma_of_match[] = { 1164 + { .compatible = "amd,versal2-dma-1.0", .data = &versal2_dma_config }, 1182 1165 { .compatible = "xlnx,zynqmp-dma-1.0", }, 1183 1166 {} 1184 1167 };
-174
include/linux/dma/ipu-dma.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) 2008 4 - * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> 5 - * 6 - * Copyright (C) 2005-2007 Freescale Semiconductor, Inc. 7 - */ 8 - 9 - #ifndef __LINUX_DMA_IPU_DMA_H 10 - #define __LINUX_DMA_IPU_DMA_H 11 - 12 - #include <linux/types.h> 13 - #include <linux/dmaengine.h> 14 - 15 - /* IPU DMA Controller channel definitions. */ 16 - enum ipu_channel { 17 - IDMAC_IC_0 = 0, /* IC (encoding task) to memory */ 18 - IDMAC_IC_1 = 1, /* IC (viewfinder task) to memory */ 19 - IDMAC_ADC_0 = 1, 20 - IDMAC_IC_2 = 2, 21 - IDMAC_ADC_1 = 2, 22 - IDMAC_IC_3 = 3, 23 - IDMAC_IC_4 = 4, 24 - IDMAC_IC_5 = 5, 25 - IDMAC_IC_6 = 6, 26 - IDMAC_IC_7 = 7, /* IC (sensor data) to memory */ 27 - IDMAC_IC_8 = 8, 28 - IDMAC_IC_9 = 9, 29 - IDMAC_IC_10 = 10, 30 - IDMAC_IC_11 = 11, 31 - IDMAC_IC_12 = 12, 32 - IDMAC_IC_13 = 13, 33 - IDMAC_SDC_0 = 14, /* Background synchronous display data */ 34 - IDMAC_SDC_1 = 15, /* Foreground data (overlay) */ 35 - IDMAC_SDC_2 = 16, 36 - IDMAC_SDC_3 = 17, 37 - IDMAC_ADC_2 = 18, 38 - IDMAC_ADC_3 = 19, 39 - IDMAC_ADC_4 = 20, 40 - IDMAC_ADC_5 = 21, 41 - IDMAC_ADC_6 = 22, 42 - IDMAC_ADC_7 = 23, 43 - IDMAC_PF_0 = 24, 44 - IDMAC_PF_1 = 25, 45 - IDMAC_PF_2 = 26, 46 - IDMAC_PF_3 = 27, 47 - IDMAC_PF_4 = 28, 48 - IDMAC_PF_5 = 29, 49 - IDMAC_PF_6 = 30, 50 - IDMAC_PF_7 = 31, 51 - }; 52 - 53 - /* Order significant! */ 54 - enum ipu_channel_status { 55 - IPU_CHANNEL_FREE, 56 - IPU_CHANNEL_INITIALIZED, 57 - IPU_CHANNEL_READY, 58 - IPU_CHANNEL_ENABLED, 59 - }; 60 - 61 - #define IPU_CHANNELS_NUM 32 62 - 63 - enum pixel_fmt { 64 - /* 1 byte */ 65 - IPU_PIX_FMT_GENERIC, 66 - IPU_PIX_FMT_RGB332, 67 - IPU_PIX_FMT_YUV420P, 68 - IPU_PIX_FMT_YUV422P, 69 - IPU_PIX_FMT_YUV420P2, 70 - IPU_PIX_FMT_YVU422P, 71 - /* 2 bytes */ 72 - IPU_PIX_FMT_RGB565, 73 - IPU_PIX_FMT_RGB666, 74 - IPU_PIX_FMT_BGR666, 75 - IPU_PIX_FMT_YUYV, 76 - IPU_PIX_FMT_UYVY, 77 - /* 3 bytes */ 78 - IPU_PIX_FMT_RGB24, 79 - IPU_PIX_FMT_BGR24, 80 - /* 4 bytes */ 81 - IPU_PIX_FMT_GENERIC_32, 82 - IPU_PIX_FMT_RGB32, 83 - IPU_PIX_FMT_BGR32, 84 - IPU_PIX_FMT_ABGR32, 85 - IPU_PIX_FMT_BGRA32, 86 - IPU_PIX_FMT_RGBA32, 87 - }; 88 - 89 - enum ipu_color_space { 90 - IPU_COLORSPACE_RGB, 91 - IPU_COLORSPACE_YCBCR, 92 - IPU_COLORSPACE_YUV 93 - }; 94 - 95 - /* 96 - * Enumeration of IPU rotation modes 97 - */ 98 - enum ipu_rotate_mode { 99 - /* Note the enum values correspond to BAM value */ 100 - IPU_ROTATE_NONE = 0, 101 - IPU_ROTATE_VERT_FLIP = 1, 102 - IPU_ROTATE_HORIZ_FLIP = 2, 103 - IPU_ROTATE_180 = 3, 104 - IPU_ROTATE_90_RIGHT = 4, 105 - IPU_ROTATE_90_RIGHT_VFLIP = 5, 106 - IPU_ROTATE_90_RIGHT_HFLIP = 6, 107 - IPU_ROTATE_90_LEFT = 7, 108 - }; 109 - 110 - /* 111 - * Enumeration of DI ports for ADC. 112 - */ 113 - enum display_port { 114 - DISP0, 115 - DISP1, 116 - DISP2, 117 - DISP3 118 - }; 119 - 120 - struct idmac_video_param { 121 - unsigned short in_width; 122 - unsigned short in_height; 123 - uint32_t in_pixel_fmt; 124 - unsigned short out_width; 125 - unsigned short out_height; 126 - uint32_t out_pixel_fmt; 127 - unsigned short out_stride; 128 - bool graphics_combine_en; 129 - bool global_alpha_en; 130 - bool key_color_en; 131 - enum display_port disp; 132 - unsigned short out_left; 133 - unsigned short out_top; 134 - }; 135 - 136 - /* 137 - * Union of initialization parameters for a logical channel. So far only video 138 - * parameters are used. 139 - */ 140 - union ipu_channel_param { 141 - struct idmac_video_param video; 142 - }; 143 - 144 - struct idmac_tx_desc { 145 - struct dma_async_tx_descriptor txd; 146 - struct scatterlist *sg; /* scatterlist for this */ 147 - unsigned int sg_len; /* tx-descriptor. */ 148 - struct list_head list; 149 - }; 150 - 151 - struct idmac_channel { 152 - struct dma_chan dma_chan; 153 - dma_cookie_t completed; /* last completed cookie */ 154 - union ipu_channel_param params; 155 - enum ipu_channel link; /* input channel, linked to the output */ 156 - enum ipu_channel_status status; 157 - void *client; /* Only one client per channel */ 158 - unsigned int n_tx_desc; 159 - struct idmac_tx_desc *desc; /* allocated tx-descriptors */ 160 - struct scatterlist *sg[2]; /* scatterlist elements in buffer-0 and -1 */ 161 - struct list_head free_list; /* free tx-descriptors */ 162 - struct list_head queue; /* queued tx-descriptors */ 163 - spinlock_t lock; /* protects sg[0,1], queue */ 164 - struct mutex chan_mutex; /* protects status, cookie, free_list */ 165 - bool sec_chan_en; 166 - int active_buffer; 167 - unsigned int eof_irq; 168 - char eof_name[16]; /* EOF IRQ name for request_irq() */ 169 - }; 170 - 171 - #define to_tx_desc(tx) container_of(tx, struct idmac_tx_desc, txd) 172 - #define to_idmac_chan(c) container_of(c, struct idmac_channel, dma_chan) 173 - 174 - #endif /* __LINUX_DMA_IPU_DMA_H */
-2
include/linux/dma/k3-udma-glue.h
··· 136 136 u32 k3_udma_glue_rx_get_flow_id_base(struct k3_udma_glue_rx_channel *rx_chn); 137 137 int k3_udma_glue_rx_get_irq(struct k3_udma_glue_rx_channel *rx_chn, 138 138 u32 flow_num); 139 - void k3_udma_glue_rx_put_irq(struct k3_udma_glue_rx_channel *rx_chn, 140 - u32 flow_num); 141 139 void k3_udma_glue_reset_rx_chn(struct k3_udma_glue_rx_channel *rx_chn, 142 140 u32 flow_num, void *data, 143 141 void (*cleanup)(void *data, dma_addr_t desc_dma),
+3
include/linux/pci_ids.h
··· 2709 2709 #define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 2710 2710 #define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 2711 2711 #define PCI_DEVICE_ID_INTEL_SST_TNG 0x119a 2712 + #define PCI_DEVICE_ID_INTEL_DSA_GNRD 0x11fb 2713 + #define PCI_DEVICE_ID_INTEL_DSA_DMR 0x1212 2714 + #define PCI_DEVICE_ID_INTEL_IAA_DMR 0x1216 2712 2715 #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 2713 2716 #define PCI_DEVICE_ID_INTEL_82437 0x122d 2714 2717 #define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e
+36
include/linux/platform_data/amd_qdma.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * Copyright (C) 2023-2024, Advanced Micro Devices, Inc. 4 + */ 5 + 6 + #ifndef _PLATDATA_AMD_QDMA_H 7 + #define _PLATDATA_AMD_QDMA_H 8 + 9 + #include <linux/dmaengine.h> 10 + 11 + /** 12 + * struct qdma_queue_info - DMA queue information. This information is used to 13 + * match queue when DMA channel is requested 14 + * @dir: Channel transfer direction 15 + */ 16 + struct qdma_queue_info { 17 + enum dma_transfer_direction dir; 18 + }; 19 + 20 + #define QDMA_FILTER_PARAM(qinfo) ((void *)(qinfo)) 21 + 22 + struct dma_slave_map; 23 + 24 + /** 25 + * struct qdma_platdata - Platform specific data for QDMA engine 26 + * @max_mm_channels: Maximum number of MM DMA channels in each direction 27 + * @device_map: DMA slave map 28 + * @irq_index: The index of first IRQ 29 + */ 30 + struct qdma_platdata { 31 + u32 max_mm_channels; 32 + u32 irq_index; 33 + struct dma_slave_map *device_map; 34 + }; 35 + 36 + #endif /* _PLATDATA_AMD_QDMA_H */