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

Merge tag 'dmaengine-4.13-rc1' of git://git.infradead.org/users/vkoul/slave-dma

Pull dmaengine updates from Vinod Koul:

- removal of AVR32 support in dw driver as AVR32 is gone

- new driver for Broadcom stream buffer accelerator (SBA) RAID driver

- add support for Faraday Technology FTDMAC020 in amba-pl08x driver

- IOMMU support in pl330 driver

- updates to bunch of drivers

* tag 'dmaengine-4.13-rc1' of git://git.infradead.org/users/vkoul/slave-dma: (36 commits)
dmaengine: qcom_hidma: correct API violation for submit
dmaengine: zynqmp_dma: Remove max len check in zynqmp_dma_prep_memcpy
dmaengine: tegra-apb: Really fix runtime-pm usage
dmaengine: fsl_raid: make of_device_ids const.
dmaengine: qcom_hidma: allow ACPI/DT parameters to be overridden
dmaengine: fsldma: set BWC, DAHTS and SAHTS values correctly
dmaengine: Kconfig: Simplify the help text for MXS_DMA
dmaengine: pl330: Delete unused functions
dmaengine: Replace WARN_TAINT_ONCE() with pr_warn_once()
dmaengine: Kconfig: Extend the dependency for MXS_DMA
dmaengine: mxs: Use %zu for printing a size_t variable
dmaengine: ste_dma40: Cleanup scatterlist layering violations
dmaengine: imx-dma: cleanup scatterlist layering violations
dmaengine: use proper name for the R-Car SoC
dmaengine: imx-sdma: Fix compilation warning.
dmaengine: imx-sdma: Handle return value of clk_prepare_enable
dmaengine: pl330: Add IOMMU support to slave tranfers
dmaengine: DW DMAC: Handle return value of clk_prepare_enable
dmaengine: pl08x: use GENMASK() to create bitmasks
dmaengine: pl08x: Add support for Faraday Technology FTDMAC020
...

+3027 -444
+7 -2
Documentation/devicetree/bindings/dma/arm-pl08x.txt
··· 3 3 Required properties: 4 4 - compatible: "arm,pl080", "arm,primecell"; 5 5 "arm,pl081", "arm,primecell"; 6 + "faraday,ftdmac020", "arm,primecell" 7 + - arm,primecell-periphid: on the FTDMAC020 the primecell ID is not hard-coded 8 + in the hardware and must be specified here as <0x0003b080>. This number 9 + follows the PrimeCell standard numbering using the JEP106 vendor code 0x38 10 + for Faraday Technology. 6 11 - reg: Address range of the PL08x registers 7 12 - interrupt: The PL08x interrupt number 8 13 - clocks: The clock running the IP core clock ··· 25 20 - dma-requests: contains the total number of DMA requests supported by the DMAC 26 21 - memcpy-burst-size: the size of the bursts for memcpy: 1, 4, 8, 16, 32 27 22 64, 128 or 256 bytes are legal values 28 - - memcpy-bus-width: the bus width used for memcpy: 8, 16 or 32 are legal 29 - values 23 + - memcpy-bus-width: the bus width used for memcpy in bits: 8, 16 or 32 are legal 24 + values, the Faraday FTDMAC020 can also accept 64 bits 30 25 31 26 Clients 32 27 Required properties:
+29
Documentation/devicetree/bindings/dma/brcm,iproc-sba.txt
··· 1 + * Broadcom SBA RAID engine 2 + 3 + Required properties: 4 + - compatible: Should be one of the following 5 + "brcm,iproc-sba" 6 + "brcm,iproc-sba-v2" 7 + The "brcm,iproc-sba" has support for only 6 PQ coefficients 8 + The "brcm,iproc-sba-v2" has support for only 30 PQ coefficients 9 + - mboxes: List of phandle and mailbox channel specifiers 10 + 11 + Example: 12 + 13 + raid_mbox: mbox@67400000 { 14 + ... 15 + #mbox-cells = <3>; 16 + ... 17 + }; 18 + 19 + raid0 { 20 + compatible = "brcm,iproc-sba-v2"; 21 + mboxes = <&raid_mbox 0 0x1 0xffff>, 22 + <&raid_mbox 1 0x1 0xffff>, 23 + <&raid_mbox 2 0x1 0xffff>, 24 + <&raid_mbox 3 0x1 0xffff>, 25 + <&raid_mbox 4 0x1 0xffff>, 26 + <&raid_mbox 5 0x1 0xffff>, 27 + <&raid_mbox 6 0x1 0xffff>, 28 + <&raid_mbox 7 0x1 0xffff>; 29 + };
+3 -2
Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
··· 30 30 31 31 - interrupts: interrupt specifiers for the DMAC, one for each entry in 32 32 interrupt-names. 33 - - interrupt-names: one entry per channel, named "ch%u", where %u is the 34 - channel number ranging from zero to the number of channels minus one. 33 + - interrupt-names: one entry for the error interrupt, named "error", plus one 34 + entry per channel, named "ch%u", where %u is the channel number ranging from 35 + zero to the number of channels minus one. 35 36 36 37 - clock-names: "fck" for the functional clock 37 38 - clocks: a list of phandle + clock-specifier pairs, one for each entry
+1 -1
Documentation/devicetree/bindings/dma/shdma.txt
··· 1 1 * SHDMA Device Tree bindings 2 2 3 - Sh-/r-mobile and r-car systems often have multiple identical DMA controller 3 + Sh-/r-mobile and R-Car systems often have multiple identical DMA controller 4 4 instances, capable of serving any of a common set of DMA slave devices, using 5 5 the same configuration. To describe this topology we require all compatible 6 6 SHDMA DT nodes to be placed under a DMA multiplexer node. All such compatible
+3
arch/arm/mach-lpc32xx/phy3250.c
··· 137 137 } 138 138 139 139 static struct pl08x_platform_data pl08x_pd = { 140 + /* Some reasonable memcpy defaults */ 141 + .memcpy_burst_size = PL08X_BURST_SZ_256, 142 + .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS, 140 143 .slave_channels = &pl08x_slave_channels[0], 141 144 .num_slave_channels = ARRAY_SIZE(pl08x_slave_channels), 142 145 .get_xfer_signal = pl08x_get_signal,
+8 -20
arch/arm/mach-s3c64xx/pl080.c
··· 137 137 }; 138 138 139 139 struct pl08x_platform_data s3c64xx_dma0_plat_data = { 140 - .memcpy_channel = { 141 - .bus_id = "memcpy", 142 - .cctl_memcpy = 143 - (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | 144 - PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT | 145 - PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | 146 - PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | 147 - PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | 148 - PL080_CONTROL_PROT_SYS), 149 - }, 140 + .memcpy_burst_size = PL08X_BURST_SZ_4, 141 + .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS, 142 + .memcpy_prot_buff = true, 143 + .memcpy_prot_cache = true, 150 144 .lli_buses = PL08X_AHB1, 151 145 .mem_buses = PL08X_AHB1, 152 146 .get_xfer_signal = pl08x_get_xfer_signal, ··· 232 238 }; 233 239 234 240 struct pl08x_platform_data s3c64xx_dma1_plat_data = { 235 - .memcpy_channel = { 236 - .bus_id = "memcpy", 237 - .cctl_memcpy = 238 - (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | 239 - PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT | 240 - PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | 241 - PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | 242 - PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | 243 - PL080_CONTROL_PROT_SYS), 244 - }, 241 + .memcpy_burst_size = PL08X_BURST_SZ_4, 242 + .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS, 243 + .memcpy_prot_buff = true, 244 + .memcpy_prot_cache = true, 245 245 .lli_buses = PL08X_AHB1, 246 246 .mem_buses = PL08X_AHB1, 247 247 .get_xfer_signal = pl08x_get_xfer_signal,
+4 -10
arch/arm/mach-spear/spear3xx.c
··· 44 44 45 45 /* dmac device registration */ 46 46 struct pl08x_platform_data pl080_plat_data = { 47 - .memcpy_channel = { 48 - .bus_id = "memcpy", 49 - .cctl_memcpy = 50 - (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ 51 - PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ 52 - PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ 53 - PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ 54 - PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \ 55 - PL080_CONTROL_PROT_SYS), 56 - }, 47 + .memcpy_burst_size = PL08X_BURST_SZ_16, 48 + .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS, 49 + .memcpy_prot_buff = true, 50 + .memcpy_prot_cache = true, 57 51 .lli_buses = PL08X_AHB1, 58 52 .mem_buses = PL08X_AHB1, 59 53 .get_xfer_signal = pl080_get_signal,
+4 -10
arch/arm/mach-spear/spear6xx.c
··· 322 322 }; 323 323 324 324 static struct pl08x_platform_data spear6xx_pl080_plat_data = { 325 - .memcpy_channel = { 326 - .bus_id = "memcpy", 327 - .cctl_memcpy = 328 - (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ 329 - PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ 330 - PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ 331 - PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ 332 - PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | \ 333 - PL080_CONTROL_PROT_SYS), 334 - }, 325 + .memcpy_burst_size = PL08X_BURST_SZ_16, 326 + .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS, 327 + .memcpy_prot_buff = true, 328 + .memcpy_prot_cache = true, 335 329 .lli_buses = PL08X_AHB1, 336 330 .mem_buses = PL08X_AHB1, 337 331 .get_xfer_signal = pl080_get_signal,
+2 -3
crypto/async_tx/async_pq.c
··· 62 62 dma_addr_t dma_dest[2]; 63 63 int src_off = 0; 64 64 65 - if (submit->flags & ASYNC_TX_FENCE) 66 - dma_flags |= DMA_PREP_FENCE; 67 - 68 65 while (src_cnt > 0) { 69 66 submit->flags = flags_orig; 70 67 pq_src_cnt = min(src_cnt, dma_maxpq(dma, dma_flags)); ··· 80 83 if (cb_fn_orig) 81 84 dma_flags |= DMA_PREP_INTERRUPT; 82 85 } 86 + if (submit->flags & ASYNC_TX_FENCE) 87 + dma_flags |= DMA_PREP_FENCE; 83 88 84 89 /* Drivers force forward progress in case they can not provide 85 90 * a descriptor
+21 -5
drivers/dma/Kconfig
··· 62 62 select DMA_ENGINE 63 63 select DMA_VIRTUAL_CHANNELS 64 64 help 65 - Platform has a PL08x DMAC device 66 - which can provide DMA engine support 65 + Say yes if your platform has a PL08x DMAC device which can 66 + provide DMA engine support. This includes the original ARM 67 + PL080 and PL081, Samsungs PL080 derivative and Faraday 68 + Technology's FTDMAC020 PL080 derivative. 67 69 68 70 config AMCC_PPC440SPE_ADMA 69 71 tristate "AMCC PPC440SPe ADMA support" ··· 100 98 Enable support for the Analog Devices AXI-DMAC peripheral. This DMA 101 99 controller is often used in Analog Device's reference designs for FPGA 102 100 platforms. 101 + 102 + config BCM_SBA_RAID 103 + tristate "Broadcom SBA RAID engine support" 104 + depends on ARM64 || COMPILE_TEST 105 + depends on MAILBOX && RAID6_PQ 106 + select DMA_ENGINE 107 + select DMA_ENGINE_RAID 108 + select ASYNC_TX_DISABLE_XOR_VAL_DMA 109 + select ASYNC_TX_DISABLE_PQ_VAL_DMA 110 + default ARCH_BCM_IPROC 111 + help 112 + Enable support for Broadcom SBA RAID Engine. The SBA RAID 113 + engine is available on most of the Broadcom iProc SoCs. It 114 + has the capability to offload memcpy, xor and pq computation 115 + for raid5/6. 103 116 104 117 config COH901318 105 118 bool "ST-Ericsson COH901318 DMA support" ··· 371 354 372 355 config MXS_DMA 373 356 bool "MXS DMA support" 374 - depends on SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q || SOC_IMX6UL 357 + depends on ARCH_MXS || ARCH_MXC || COMPILE_TEST 375 358 select STMP_DEVICE 376 359 select DMA_ENGINE 377 360 help 378 361 Support the MXS DMA engine. This engine including APBH-DMA 379 - and APBX-DMA is integrated into Freescale 380 - i.MX23/28/MX6Q/MX6DL/MX6UL chips. 362 + and APBX-DMA is integrated into some Freescale chips. 381 363 382 364 config MX3_IPU 383 365 bool "MX3x Image Processing Unit support"
+1
drivers/dma/Makefile
··· 17 17 obj-$(CONFIG_AT_HDMAC) += at_hdmac.o 18 18 obj-$(CONFIG_AT_XDMAC) += at_xdmac.o 19 19 obj-$(CONFIG_AXI_DMAC) += dma-axi-dmac.o 20 + obj-$(CONFIG_BCM_SBA_RAID) += bcm-sba-raid.o 20 21 obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o 21 22 obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o 22 23 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
+757 -217
drivers/dma/amba-pl08x.c
··· 1 1 /* 2 2 * Copyright (c) 2006 ARM Ltd. 3 3 * Copyright (c) 2010 ST-Ericsson SA 4 + * Copyirght (c) 2017 Linaro Ltd. 4 5 * 5 6 * Author: Peter Pearse <peter.pearse@arm.com> 6 - * Author: Linus Walleij <linus.walleij@stericsson.com> 7 + * Author: Linus Walleij <linus.walleij@linaro.org> 7 8 * 8 9 * This program is free software; you can redistribute it and/or modify it 9 10 * under the terms of the GNU General Public License as published by the Free ··· 111 110 * @channels: the number of channels available in this variant 112 111 * @signals: the number of request signals available from the hardware 113 112 * @dualmaster: whether this version supports dual AHB masters or not. 114 - * @nomadik: whether the channels have Nomadik security extension bits 115 - * that need to be checked for permission before use and some registers are 116 - * missing 117 - * @pl080s: whether this version is a PL080S, which has separate register and 118 - * LLI word for transfer size. 113 + * @nomadik: whether this variant is a ST Microelectronics Nomadik, where the 114 + * channels have Nomadik security extension bits that need to be checked 115 + * for permission before use and some registers are missing 116 + * @pl080s: whether this variant is a Samsung PL080S, which has separate 117 + * register and LLI word for transfer size. 118 + * @ftdmac020: whether this variant is a Faraday Technology FTDMAC020 119 119 * @max_transfer_size: the maximum single element transfer size for this 120 120 * PL08x variant. 121 121 */ ··· 127 125 bool dualmaster; 128 126 bool nomadik; 129 127 bool pl080s; 128 + bool ftdmac020; 130 129 u32 max_transfer_size; 131 130 }; 132 131 ··· 151 148 * @id: physical index to this channel 152 149 * @base: memory base address for this physical channel 153 150 * @reg_config: configuration address for this physical channel 151 + * @reg_control: control address for this physical channel 152 + * @reg_src: transfer source address register 153 + * @reg_dst: transfer destination address register 154 + * @reg_lli: transfer LLI address register 155 + * @reg_busy: if the variant has a special per-channel busy register, 156 + * this contains a pointer to it 154 157 * @lock: a lock to use when altering an instance of this struct 155 158 * @serving: the virtual channel currently being served by this physical 156 159 * channel 157 160 * @locked: channel unavailable for the system, e.g. dedicated to secure 158 161 * world 162 + * @ftdmac020: channel is on a FTDMAC020 163 + * @pl080s: channel is on a PL08s 159 164 */ 160 165 struct pl08x_phy_chan { 161 166 unsigned int id; 162 167 void __iomem *base; 163 168 void __iomem *reg_config; 169 + void __iomem *reg_control; 170 + void __iomem *reg_src; 171 + void __iomem *reg_dst; 172 + void __iomem *reg_lli; 173 + void __iomem *reg_busy; 164 174 spinlock_t lock; 165 175 struct pl08x_dma_chan *serving; 166 176 bool locked; 177 + bool ftdmac020; 178 + bool pl080s; 167 179 }; 168 180 169 181 /** ··· 271 253 272 254 /** 273 255 * struct pl08x_driver_data - the local state holder for the PL08x 274 - * @slave: slave engine for this instance 256 + * @slave: optional slave engine for this instance 275 257 * @memcpy: memcpy engine for this instance 258 + * @has_slave: the PL08x has a slave engine (routed signals) 276 259 * @base: virtual memory base (remapped) for the PL08x 277 260 * @adev: the corresponding AMBA (PrimeCell) bus entry 278 261 * @vd: vendor data for this PL08x variant ··· 288 269 struct pl08x_driver_data { 289 270 struct dma_device slave; 290 271 struct dma_device memcpy; 272 + bool has_slave; 291 273 void __iomem *base; 292 274 struct amba_device *adev; 293 275 const struct vendor_data *vd; ··· 380 360 { 381 361 unsigned int val; 382 362 363 + /* If we have a special busy register, take a shortcut */ 364 + if (ch->reg_busy) { 365 + val = readl(ch->reg_busy); 366 + return !!(val & BIT(ch->id)); 367 + } 383 368 val = readl(ch->reg_config); 384 369 return val & PL080_CONFIG_ACTIVE; 385 370 } 386 371 372 + /* 373 + * pl08x_write_lli() - Write an LLI into the DMA controller. 374 + * 375 + * The PL08x derivatives support linked lists, but the first item of the 376 + * list containing the source, destination, control word and next LLI is 377 + * ignored. Instead the driver has to write those values directly into the 378 + * SRC, DST, LLI and control registers. On FTDMAC020 also the SIZE 379 + * register need to be set up for the first transfer. 380 + */ 387 381 static void pl08x_write_lli(struct pl08x_driver_data *pl08x, 388 382 struct pl08x_phy_chan *phychan, const u32 *lli, u32 ccfg) 389 383 { ··· 415 381 phychan->id, lli[PL080_LLI_SRC], lli[PL080_LLI_DST], 416 382 lli[PL080_LLI_LLI], lli[PL080_LLI_CCTL], ccfg); 417 383 418 - writel_relaxed(lli[PL080_LLI_SRC], phychan->base + PL080_CH_SRC_ADDR); 419 - writel_relaxed(lli[PL080_LLI_DST], phychan->base + PL080_CH_DST_ADDR); 420 - writel_relaxed(lli[PL080_LLI_LLI], phychan->base + PL080_CH_LLI); 421 - writel_relaxed(lli[PL080_LLI_CCTL], phychan->base + PL080_CH_CONTROL); 384 + writel_relaxed(lli[PL080_LLI_SRC], phychan->reg_src); 385 + writel_relaxed(lli[PL080_LLI_DST], phychan->reg_dst); 386 + writel_relaxed(lli[PL080_LLI_LLI], phychan->reg_lli); 422 387 388 + /* 389 + * The FTMAC020 has a different layout in the CCTL word of the LLI 390 + * and the CCTL register which is split in CSR and SIZE registers. 391 + * Convert the LLI item CCTL into the proper values to write into 392 + * the CSR and SIZE registers. 393 + */ 394 + if (phychan->ftdmac020) { 395 + u32 llictl = lli[PL080_LLI_CCTL]; 396 + u32 val = 0; 397 + 398 + /* Write the transfer size (12 bits) to the size register */ 399 + writel_relaxed(llictl & FTDMAC020_LLI_TRANSFER_SIZE_MASK, 400 + phychan->base + FTDMAC020_CH_SIZE); 401 + /* 402 + * Then write the control bits 28..16 to the control register 403 + * by shuffleing the bits around to where they are in the 404 + * main register. The mapping is as follows: 405 + * Bit 28: TC_MSK - mask on all except last LLI 406 + * Bit 27..25: SRC_WIDTH 407 + * Bit 24..22: DST_WIDTH 408 + * Bit 21..20: SRCAD_CTRL 409 + * Bit 19..17: DSTAD_CTRL 410 + * Bit 17: SRC_SEL 411 + * Bit 16: DST_SEL 412 + */ 413 + if (llictl & FTDMAC020_LLI_TC_MSK) 414 + val |= FTDMAC020_CH_CSR_TC_MSK; 415 + val |= ((llictl & FTDMAC020_LLI_SRC_WIDTH_MSK) >> 416 + (FTDMAC020_LLI_SRC_WIDTH_SHIFT - 417 + FTDMAC020_CH_CSR_SRC_WIDTH_SHIFT)); 418 + val |= ((llictl & FTDMAC020_LLI_DST_WIDTH_MSK) >> 419 + (FTDMAC020_LLI_DST_WIDTH_SHIFT - 420 + FTDMAC020_CH_CSR_DST_WIDTH_SHIFT)); 421 + val |= ((llictl & FTDMAC020_LLI_SRCAD_CTL_MSK) >> 422 + (FTDMAC020_LLI_SRCAD_CTL_SHIFT - 423 + FTDMAC020_CH_CSR_SRCAD_CTL_SHIFT)); 424 + val |= ((llictl & FTDMAC020_LLI_DSTAD_CTL_MSK) >> 425 + (FTDMAC020_LLI_DSTAD_CTL_SHIFT - 426 + FTDMAC020_CH_CSR_DSTAD_CTL_SHIFT)); 427 + if (llictl & FTDMAC020_LLI_SRC_SEL) 428 + val |= FTDMAC020_CH_CSR_SRC_SEL; 429 + if (llictl & FTDMAC020_LLI_DST_SEL) 430 + val |= FTDMAC020_CH_CSR_DST_SEL; 431 + 432 + /* 433 + * Set up the bits that exist in the CSR but are not 434 + * part the LLI, i.e. only gets written to the control 435 + * register right here. 436 + * 437 + * FIXME: do not just handle memcpy, also handle slave DMA. 438 + */ 439 + switch (pl08x->pd->memcpy_burst_size) { 440 + default: 441 + case PL08X_BURST_SZ_1: 442 + val |= PL080_BSIZE_1 << 443 + FTDMAC020_CH_CSR_SRC_SIZE_SHIFT; 444 + break; 445 + case PL08X_BURST_SZ_4: 446 + val |= PL080_BSIZE_4 << 447 + FTDMAC020_CH_CSR_SRC_SIZE_SHIFT; 448 + break; 449 + case PL08X_BURST_SZ_8: 450 + val |= PL080_BSIZE_8 << 451 + FTDMAC020_CH_CSR_SRC_SIZE_SHIFT; 452 + break; 453 + case PL08X_BURST_SZ_16: 454 + val |= PL080_BSIZE_16 << 455 + FTDMAC020_CH_CSR_SRC_SIZE_SHIFT; 456 + break; 457 + case PL08X_BURST_SZ_32: 458 + val |= PL080_BSIZE_32 << 459 + FTDMAC020_CH_CSR_SRC_SIZE_SHIFT; 460 + break; 461 + case PL08X_BURST_SZ_64: 462 + val |= PL080_BSIZE_64 << 463 + FTDMAC020_CH_CSR_SRC_SIZE_SHIFT; 464 + break; 465 + case PL08X_BURST_SZ_128: 466 + val |= PL080_BSIZE_128 << 467 + FTDMAC020_CH_CSR_SRC_SIZE_SHIFT; 468 + break; 469 + case PL08X_BURST_SZ_256: 470 + val |= PL080_BSIZE_256 << 471 + FTDMAC020_CH_CSR_SRC_SIZE_SHIFT; 472 + break; 473 + } 474 + 475 + /* Protection flags */ 476 + if (pl08x->pd->memcpy_prot_buff) 477 + val |= FTDMAC020_CH_CSR_PROT2; 478 + if (pl08x->pd->memcpy_prot_cache) 479 + val |= FTDMAC020_CH_CSR_PROT3; 480 + /* We are the kernel, so we are in privileged mode */ 481 + val |= FTDMAC020_CH_CSR_PROT1; 482 + 483 + writel_relaxed(val, phychan->reg_control); 484 + } else { 485 + /* Bits are just identical */ 486 + writel_relaxed(lli[PL080_LLI_CCTL], phychan->reg_control); 487 + } 488 + 489 + /* Second control word on the PL080s */ 423 490 if (pl08x->vd->pl080s) 424 491 writel_relaxed(lli[PL080S_LLI_CCTL2], 425 492 phychan->base + PL080S_CH_CONTROL2); ··· 558 423 cpu_relax(); 559 424 560 425 /* Do not access config register until channel shows as inactive */ 561 - val = readl(phychan->reg_config); 562 - while ((val & PL080_CONFIG_ACTIVE) || (val & PL080_CONFIG_ENABLE)) 426 + if (phychan->ftdmac020) { 563 427 val = readl(phychan->reg_config); 428 + while (val & FTDMAC020_CH_CFG_BUSY) 429 + val = readl(phychan->reg_config); 564 430 565 - writel(val | PL080_CONFIG_ENABLE, phychan->reg_config); 431 + val = readl(phychan->reg_control); 432 + while (val & FTDMAC020_CH_CSR_EN) 433 + val = readl(phychan->reg_control); 434 + 435 + writel(val | FTDMAC020_CH_CSR_EN, 436 + phychan->reg_control); 437 + } else { 438 + val = readl(phychan->reg_config); 439 + while ((val & PL080_CONFIG_ACTIVE) || 440 + (val & PL080_CONFIG_ENABLE)) 441 + val = readl(phychan->reg_config); 442 + 443 + writel(val | PL080_CONFIG_ENABLE, phychan->reg_config); 444 + } 566 445 } 567 446 568 447 /* ··· 593 444 { 594 445 u32 val; 595 446 int timeout; 447 + 448 + if (ch->ftdmac020) { 449 + /* Use the enable bit on the FTDMAC020 */ 450 + val = readl(ch->reg_control); 451 + val &= ~FTDMAC020_CH_CSR_EN; 452 + writel(val, ch->reg_control); 453 + return; 454 + } 596 455 597 456 /* Set the HALT bit and wait for the FIFO to drain */ 598 457 val = readl(ch->reg_config); ··· 621 464 { 622 465 u32 val; 623 466 467 + /* Use the enable bit on the FTDMAC020 */ 468 + if (ch->ftdmac020) { 469 + val = readl(ch->reg_control); 470 + val |= FTDMAC020_CH_CSR_EN; 471 + writel(val, ch->reg_control); 472 + return; 473 + } 474 + 624 475 /* Clear the HALT bit */ 625 476 val = readl(ch->reg_config); 626 477 val &= ~PL080_CONFIG_HALT; ··· 644 479 static void pl08x_terminate_phy_chan(struct pl08x_driver_data *pl08x, 645 480 struct pl08x_phy_chan *ch) 646 481 { 647 - u32 val = readl(ch->reg_config); 482 + u32 val; 648 483 484 + /* The layout for the FTDMAC020 is different */ 485 + if (ch->ftdmac020) { 486 + /* Disable all interrupts */ 487 + val = readl(ch->reg_config); 488 + val |= (FTDMAC020_CH_CFG_INT_ABT_MASK | 489 + FTDMAC020_CH_CFG_INT_ERR_MASK | 490 + FTDMAC020_CH_CFG_INT_TC_MASK); 491 + writel(val, ch->reg_config); 492 + 493 + /* Abort and disable channel */ 494 + val = readl(ch->reg_control); 495 + val &= ~FTDMAC020_CH_CSR_EN; 496 + val |= FTDMAC020_CH_CSR_ABT; 497 + writel(val, ch->reg_control); 498 + 499 + /* Clear ABT and ERR interrupt flags */ 500 + writel(BIT(ch->id) | BIT(ch->id + 16), 501 + pl08x->base + PL080_ERR_CLEAR); 502 + writel(BIT(ch->id), pl08x->base + PL080_TC_CLEAR); 503 + 504 + return; 505 + } 506 + 507 + val = readl(ch->reg_config); 649 508 val &= ~(PL080_CONFIG_ENABLE | PL080_CONFIG_ERR_IRQ_MASK | 650 509 PL080_CONFIG_TC_IRQ_MASK); 651 - 652 510 writel(val, ch->reg_config); 653 511 654 512 writel(BIT(ch->id), pl08x->base + PL080_ERR_CLEAR); 655 513 writel(BIT(ch->id), pl08x->base + PL080_TC_CLEAR); 656 514 } 657 515 658 - static inline u32 get_bytes_in_cctl(u32 cctl) 516 + static u32 get_bytes_in_phy_channel(struct pl08x_phy_chan *ch) 659 517 { 660 - /* The source width defines the number of bytes */ 661 - u32 bytes = cctl & PL080_CONTROL_TRANSFER_SIZE_MASK; 518 + u32 val; 519 + u32 bytes; 662 520 663 - cctl &= PL080_CONTROL_SWIDTH_MASK; 521 + if (ch->ftdmac020) { 522 + bytes = readl(ch->base + FTDMAC020_CH_SIZE); 664 523 665 - switch (cctl >> PL080_CONTROL_SWIDTH_SHIFT) { 524 + val = readl(ch->reg_control); 525 + val &= FTDMAC020_CH_CSR_SRC_WIDTH_MSK; 526 + val >>= FTDMAC020_CH_CSR_SRC_WIDTH_SHIFT; 527 + } else if (ch->pl080s) { 528 + val = readl(ch->base + PL080S_CH_CONTROL2); 529 + bytes = val & PL080S_CONTROL_TRANSFER_SIZE_MASK; 530 + 531 + val = readl(ch->reg_control); 532 + val &= PL080_CONTROL_SWIDTH_MASK; 533 + val >>= PL080_CONTROL_SWIDTH_SHIFT; 534 + } else { 535 + /* Plain PL08x */ 536 + val = readl(ch->reg_control); 537 + bytes = val & PL080_CONTROL_TRANSFER_SIZE_MASK; 538 + 539 + val &= PL080_CONTROL_SWIDTH_MASK; 540 + val >>= PL080_CONTROL_SWIDTH_SHIFT; 541 + } 542 + 543 + switch (val) { 666 544 case PL080_WIDTH_8BIT: 667 545 break; 668 546 case PL080_WIDTH_16BIT: ··· 718 510 return bytes; 719 511 } 720 512 721 - static inline u32 get_bytes_in_cctl_pl080s(u32 cctl, u32 cctl1) 513 + static u32 get_bytes_in_lli(struct pl08x_phy_chan *ch, const u32 *llis_va) 722 514 { 723 - /* The source width defines the number of bytes */ 724 - u32 bytes = cctl1 & PL080S_CONTROL_TRANSFER_SIZE_MASK; 515 + u32 val; 516 + u32 bytes; 725 517 726 - cctl &= PL080_CONTROL_SWIDTH_MASK; 518 + if (ch->ftdmac020) { 519 + val = llis_va[PL080_LLI_CCTL]; 520 + bytes = val & FTDMAC020_LLI_TRANSFER_SIZE_MASK; 727 521 728 - switch (cctl >> PL080_CONTROL_SWIDTH_SHIFT) { 522 + val = llis_va[PL080_LLI_CCTL]; 523 + val &= FTDMAC020_LLI_SRC_WIDTH_MSK; 524 + val >>= FTDMAC020_LLI_SRC_WIDTH_SHIFT; 525 + } else if (ch->pl080s) { 526 + val = llis_va[PL080S_LLI_CCTL2]; 527 + bytes = val & PL080S_CONTROL_TRANSFER_SIZE_MASK; 528 + 529 + val = llis_va[PL080_LLI_CCTL]; 530 + val &= PL080_CONTROL_SWIDTH_MASK; 531 + val >>= PL080_CONTROL_SWIDTH_SHIFT; 532 + } else { 533 + /* Plain PL08x */ 534 + val = llis_va[PL080_LLI_CCTL]; 535 + bytes = val & PL080_CONTROL_TRANSFER_SIZE_MASK; 536 + 537 + val &= PL080_CONTROL_SWIDTH_MASK; 538 + val >>= PL080_CONTROL_SWIDTH_SHIFT; 539 + } 540 + 541 + switch (val) { 729 542 case PL080_WIDTH_8BIT: 730 543 break; 731 544 case PL080_WIDTH_16BIT: ··· 781 552 * Follow the LLIs to get the number of remaining 782 553 * bytes in the currently active transaction. 783 554 */ 784 - clli = readl(ch->base + PL080_CH_LLI) & ~PL080_LLI_LM_AHB2; 555 + clli = readl(ch->reg_lli) & ~PL080_LLI_LM_AHB2; 785 556 786 557 /* First get the remaining bytes in the active transfer */ 787 - if (pl08x->vd->pl080s) 788 - bytes = get_bytes_in_cctl_pl080s( 789 - readl(ch->base + PL080_CH_CONTROL), 790 - readl(ch->base + PL080S_CH_CONTROL2)); 791 - else 792 - bytes = get_bytes_in_cctl(readl(ch->base + PL080_CH_CONTROL)); 558 + bytes = get_bytes_in_phy_channel(ch); 793 559 794 560 if (!clli) 795 561 return bytes; ··· 805 581 llis_va_limit = llis_va + llis_max_words; 806 582 807 583 for (; llis_va < llis_va_limit; llis_va += pl08x->lli_words) { 808 - if (pl08x->vd->pl080s) 809 - bytes += get_bytes_in_cctl_pl080s( 810 - llis_va[PL080_LLI_CCTL], 811 - llis_va[PL080S_LLI_CCTL2]); 812 - else 813 - bytes += get_bytes_in_cctl(llis_va[PL080_LLI_CCTL]); 584 + bytes += get_bytes_in_lli(ch, llis_va); 814 585 815 586 /* 816 587 * A LLI pointer going backward terminates the LLI list ··· 924 705 break; 925 706 } 926 707 927 - if (!next) { 708 + if (!next && pl08x->has_slave) { 928 709 list_for_each_entry(p, &pl08x->slave.channels, vc.chan.device_node) 929 710 if (p->state == PL08X_CHAN_WAITING) { 930 711 next = p; ··· 965 746 * LLI handling 966 747 */ 967 748 968 - static inline unsigned int pl08x_get_bytes_for_cctl(unsigned int coded) 749 + static inline unsigned int 750 + pl08x_get_bytes_for_lli(struct pl08x_driver_data *pl08x, 751 + u32 cctl, 752 + bool source) 969 753 { 970 - switch (coded) { 754 + u32 val; 755 + 756 + if (pl08x->vd->ftdmac020) { 757 + if (source) 758 + val = (cctl & FTDMAC020_LLI_SRC_WIDTH_MSK) >> 759 + FTDMAC020_LLI_SRC_WIDTH_SHIFT; 760 + else 761 + val = (cctl & FTDMAC020_LLI_DST_WIDTH_MSK) >> 762 + FTDMAC020_LLI_DST_WIDTH_SHIFT; 763 + } else { 764 + if (source) 765 + val = (cctl & PL080_CONTROL_SWIDTH_MASK) >> 766 + PL080_CONTROL_SWIDTH_SHIFT; 767 + else 768 + val = (cctl & PL080_CONTROL_DWIDTH_MASK) >> 769 + PL080_CONTROL_DWIDTH_SHIFT; 770 + } 771 + 772 + switch (val) { 971 773 case PL080_WIDTH_8BIT: 972 774 return 1; 973 775 case PL080_WIDTH_16BIT: ··· 1002 762 return 0; 1003 763 } 1004 764 1005 - static inline u32 pl08x_cctl_bits(u32 cctl, u8 srcwidth, u8 dstwidth, 1006 - size_t tsize) 765 + static inline u32 pl08x_lli_control_bits(struct pl08x_driver_data *pl08x, 766 + u32 cctl, 767 + u8 srcwidth, u8 dstwidth, 768 + size_t tsize) 1007 769 { 1008 770 u32 retbits = cctl; 1009 771 1010 - /* Remove all src, dst and transfer size bits */ 1011 - retbits &= ~PL080_CONTROL_DWIDTH_MASK; 1012 - retbits &= ~PL080_CONTROL_SWIDTH_MASK; 1013 - retbits &= ~PL080_CONTROL_TRANSFER_SIZE_MASK; 772 + /* 773 + * Remove all src, dst and transfer size bits, then set the 774 + * width and size according to the parameters. The bit offsets 775 + * are different in the FTDMAC020 so we need to accound for this. 776 + */ 777 + if (pl08x->vd->ftdmac020) { 778 + retbits &= ~FTDMAC020_LLI_DST_WIDTH_MSK; 779 + retbits &= ~FTDMAC020_LLI_SRC_WIDTH_MSK; 780 + retbits &= ~FTDMAC020_LLI_TRANSFER_SIZE_MASK; 1014 781 1015 - /* Then set the bits according to the parameters */ 1016 - switch (srcwidth) { 1017 - case 1: 1018 - retbits |= PL080_WIDTH_8BIT << PL080_CONTROL_SWIDTH_SHIFT; 1019 - break; 1020 - case 2: 1021 - retbits |= PL080_WIDTH_16BIT << PL080_CONTROL_SWIDTH_SHIFT; 1022 - break; 1023 - case 4: 1024 - retbits |= PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT; 1025 - break; 1026 - default: 1027 - BUG(); 1028 - break; 782 + switch (srcwidth) { 783 + case 1: 784 + retbits |= PL080_WIDTH_8BIT << 785 + FTDMAC020_LLI_SRC_WIDTH_SHIFT; 786 + break; 787 + case 2: 788 + retbits |= PL080_WIDTH_16BIT << 789 + FTDMAC020_LLI_SRC_WIDTH_SHIFT; 790 + break; 791 + case 4: 792 + retbits |= PL080_WIDTH_32BIT << 793 + FTDMAC020_LLI_SRC_WIDTH_SHIFT; 794 + break; 795 + default: 796 + BUG(); 797 + break; 798 + } 799 + 800 + switch (dstwidth) { 801 + case 1: 802 + retbits |= PL080_WIDTH_8BIT << 803 + FTDMAC020_LLI_DST_WIDTH_SHIFT; 804 + break; 805 + case 2: 806 + retbits |= PL080_WIDTH_16BIT << 807 + FTDMAC020_LLI_DST_WIDTH_SHIFT; 808 + break; 809 + case 4: 810 + retbits |= PL080_WIDTH_32BIT << 811 + FTDMAC020_LLI_DST_WIDTH_SHIFT; 812 + break; 813 + default: 814 + BUG(); 815 + break; 816 + } 817 + 818 + tsize &= FTDMAC020_LLI_TRANSFER_SIZE_MASK; 819 + retbits |= tsize << FTDMAC020_LLI_TRANSFER_SIZE_SHIFT; 820 + } else { 821 + retbits &= ~PL080_CONTROL_DWIDTH_MASK; 822 + retbits &= ~PL080_CONTROL_SWIDTH_MASK; 823 + retbits &= ~PL080_CONTROL_TRANSFER_SIZE_MASK; 824 + 825 + switch (srcwidth) { 826 + case 1: 827 + retbits |= PL080_WIDTH_8BIT << 828 + PL080_CONTROL_SWIDTH_SHIFT; 829 + break; 830 + case 2: 831 + retbits |= PL080_WIDTH_16BIT << 832 + PL080_CONTROL_SWIDTH_SHIFT; 833 + break; 834 + case 4: 835 + retbits |= PL080_WIDTH_32BIT << 836 + PL080_CONTROL_SWIDTH_SHIFT; 837 + break; 838 + default: 839 + BUG(); 840 + break; 841 + } 842 + 843 + switch (dstwidth) { 844 + case 1: 845 + retbits |= PL080_WIDTH_8BIT << 846 + PL080_CONTROL_DWIDTH_SHIFT; 847 + break; 848 + case 2: 849 + retbits |= PL080_WIDTH_16BIT << 850 + PL080_CONTROL_DWIDTH_SHIFT; 851 + break; 852 + case 4: 853 + retbits |= PL080_WIDTH_32BIT << 854 + PL080_CONTROL_DWIDTH_SHIFT; 855 + break; 856 + default: 857 + BUG(); 858 + break; 859 + } 860 + 861 + tsize &= PL080_CONTROL_TRANSFER_SIZE_MASK; 862 + retbits |= tsize << PL080_CONTROL_TRANSFER_SIZE_SHIFT; 1029 863 } 1030 864 1031 - switch (dstwidth) { 1032 - case 1: 1033 - retbits |= PL080_WIDTH_8BIT << PL080_CONTROL_DWIDTH_SHIFT; 1034 - break; 1035 - case 2: 1036 - retbits |= PL080_WIDTH_16BIT << PL080_CONTROL_DWIDTH_SHIFT; 1037 - break; 1038 - case 4: 1039 - retbits |= PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT; 1040 - break; 1041 - default: 1042 - BUG(); 1043 - break; 1044 - } 1045 - 1046 - tsize &= PL080_CONTROL_TRANSFER_SIZE_MASK; 1047 - retbits |= tsize << PL080_CONTROL_TRANSFER_SIZE_SHIFT; 1048 865 return retbits; 1049 866 } 1050 867 ··· 1122 825 * - prefers the destination bus if both available 1123 826 * - prefers bus with fixed address (i.e. peripheral) 1124 827 */ 1125 - static void pl08x_choose_master_bus(struct pl08x_lli_build_data *bd, 1126 - struct pl08x_bus_data **mbus, struct pl08x_bus_data **sbus, u32 cctl) 828 + static void pl08x_choose_master_bus(struct pl08x_driver_data *pl08x, 829 + struct pl08x_lli_build_data *bd, 830 + struct pl08x_bus_data **mbus, 831 + struct pl08x_bus_data **sbus, 832 + u32 cctl) 1127 833 { 1128 - if (!(cctl & PL080_CONTROL_DST_INCR)) { 834 + bool dst_incr; 835 + bool src_incr; 836 + 837 + /* 838 + * The FTDMAC020 only supports memory-to-memory transfer, so 839 + * source and destination always increase. 840 + */ 841 + if (pl08x->vd->ftdmac020) { 842 + dst_incr = true; 843 + src_incr = true; 844 + } else { 845 + dst_incr = !!(cctl & PL080_CONTROL_DST_INCR); 846 + src_incr = !!(cctl & PL080_CONTROL_SRC_INCR); 847 + } 848 + 849 + /* 850 + * If either bus is not advancing, i.e. it is a peripheral, that 851 + * one becomes master 852 + */ 853 + if (!dst_incr) { 1129 854 *mbus = &bd->dstbus; 1130 855 *sbus = &bd->srcbus; 1131 - } else if (!(cctl & PL080_CONTROL_SRC_INCR)) { 856 + } else if (!src_incr) { 1132 857 *mbus = &bd->srcbus; 1133 858 *sbus = &bd->dstbus; 1134 859 } else { ··· 1188 869 if (pl08x->vd->pl080s) 1189 870 llis_va[PL080S_LLI_CCTL2] = cctl2; 1190 871 1191 - if (cctl & PL080_CONTROL_SRC_INCR) 872 + if (pl08x->vd->ftdmac020) { 873 + /* FIXME: only memcpy so far so both increase */ 1192 874 bd->srcbus.addr += len; 1193 - if (cctl & PL080_CONTROL_DST_INCR) 1194 875 bd->dstbus.addr += len; 876 + } else { 877 + if (cctl & PL080_CONTROL_SRC_INCR) 878 + bd->srcbus.addr += len; 879 + if (cctl & PL080_CONTROL_DST_INCR) 880 + bd->dstbus.addr += len; 881 + } 1195 882 1196 883 BUG_ON(bd->remainder < len); 1197 884 ··· 1208 883 struct pl08x_lli_build_data *bd, u32 *cctl, u32 len, 1209 884 int num_llis, size_t *total_bytes) 1210 885 { 1211 - *cctl = pl08x_cctl_bits(*cctl, 1, 1, len); 886 + *cctl = pl08x_lli_control_bits(pl08x, *cctl, 1, 1, len); 1212 887 pl08x_fill_lli_for_desc(pl08x, bd, num_llis, len, *cctl, len); 1213 888 (*total_bytes) += len; 1214 889 } 1215 890 1216 - #ifdef VERBOSE_DEBUG 891 + #if 1 1217 892 static void pl08x_dump_lli(struct pl08x_driver_data *pl08x, 1218 893 const u32 *llis_va, int num_llis) 1219 894 { ··· 1278 953 cctl = txd->cctl; 1279 954 1280 955 /* Find maximum width of the source bus */ 1281 - bd.srcbus.maxwidth = 1282 - pl08x_get_bytes_for_cctl((cctl & PL080_CONTROL_SWIDTH_MASK) >> 1283 - PL080_CONTROL_SWIDTH_SHIFT); 956 + bd.srcbus.maxwidth = pl08x_get_bytes_for_lli(pl08x, cctl, true); 1284 957 1285 958 /* Find maximum width of the destination bus */ 1286 - bd.dstbus.maxwidth = 1287 - pl08x_get_bytes_for_cctl((cctl & PL080_CONTROL_DWIDTH_MASK) >> 1288 - PL080_CONTROL_DWIDTH_SHIFT); 959 + bd.dstbus.maxwidth = pl08x_get_bytes_for_lli(pl08x, cctl, false); 1289 960 1290 961 list_for_each_entry(dsg, &txd->dsg_list, node) { 1291 962 total_bytes = 0; ··· 1293 972 bd.srcbus.buswidth = bd.srcbus.maxwidth; 1294 973 bd.dstbus.buswidth = bd.dstbus.maxwidth; 1295 974 1296 - pl08x_choose_master_bus(&bd, &mbus, &sbus, cctl); 975 + pl08x_choose_master_bus(pl08x, &bd, &mbus, &sbus, cctl); 1297 976 1298 977 dev_vdbg(&pl08x->adev->dev, 1299 978 "src=0x%08llx%s/%u dst=0x%08llx%s/%u len=%zu\n", ··· 1330 1009 * supported. Thus, we can't have scattered addresses. 1331 1010 */ 1332 1011 if (!bd.remainder) { 1333 - u32 fc = (txd->ccfg & PL080_CONFIG_FLOW_CONTROL_MASK) >> 1334 - PL080_CONFIG_FLOW_CONTROL_SHIFT; 1012 + u32 fc; 1013 + 1014 + /* FTDMAC020 only does memory-to-memory */ 1015 + if (pl08x->vd->ftdmac020) 1016 + fc = PL080_FLOW_MEM2MEM; 1017 + else 1018 + fc = (txd->ccfg & PL080_CONFIG_FLOW_CONTROL_MASK) >> 1019 + PL080_CONFIG_FLOW_CONTROL_SHIFT; 1335 1020 if (!((fc >= PL080_FLOW_SRC2DST_DST) && 1336 1021 (fc <= PL080_FLOW_SRC2DST_SRC))) { 1337 1022 dev_err(&pl08x->adev->dev, "%s sg len can't be zero", ··· 1354 1027 return 0; 1355 1028 } 1356 1029 1357 - cctl = pl08x_cctl_bits(cctl, bd.srcbus.buswidth, 1358 - bd.dstbus.buswidth, 0); 1030 + cctl = pl08x_lli_control_bits(pl08x, cctl, 1031 + bd.srcbus.buswidth, bd.dstbus.buswidth, 1032 + 0); 1359 1033 pl08x_fill_lli_for_desc(pl08x, &bd, num_llis++, 1360 1034 0, cctl, 0); 1361 1035 break; ··· 1435 1107 "size 0x%08zx (remainder 0x%08zx)\n", 1436 1108 __func__, lli_len, bd.remainder); 1437 1109 1438 - cctl = pl08x_cctl_bits(cctl, bd.srcbus.buswidth, 1439 - bd.dstbus.buswidth, tsize); 1110 + cctl = pl08x_lli_control_bits(pl08x, cctl, 1111 + bd.srcbus.buswidth, bd.dstbus.buswidth, 1112 + tsize); 1440 1113 pl08x_fill_lli_for_desc(pl08x, &bd, num_llis++, 1441 1114 lli_len, cctl, tsize); 1442 1115 total_bytes += lli_len; ··· 1480 1151 /* The final LLI terminates the LLI. */ 1481 1152 last_lli[PL080_LLI_LLI] = 0; 1482 1153 /* The final LLI element shall also fire an interrupt. */ 1483 - last_lli[PL080_LLI_CCTL] |= PL080_CONTROL_TC_IRQ_EN; 1154 + if (pl08x->vd->ftdmac020) 1155 + last_lli[PL080_LLI_CCTL] &= ~FTDMAC020_LLI_TC_MSK; 1156 + else 1157 + last_lli[PL080_LLI_CCTL] |= PL080_CONTROL_TC_IRQ_EN; 1484 1158 } 1485 1159 1486 1160 pl08x_dump_lli(pl08x, llis_va, num_llis); ··· 1649 1317 * will be routed to each port. We try to have source and destination 1650 1318 * on separate ports, but always respect the allowable settings. 1651 1319 */ 1652 - static u32 pl08x_select_bus(u8 src, u8 dst) 1320 + static u32 pl08x_select_bus(bool ftdmac020, u8 src, u8 dst) 1653 1321 { 1654 1322 u32 cctl = 0; 1323 + u32 dst_ahb2; 1324 + u32 src_ahb2; 1325 + 1326 + /* The FTDMAC020 use different bits to indicate src/dst bus */ 1327 + if (ftdmac020) { 1328 + dst_ahb2 = FTDMAC020_LLI_DST_SEL; 1329 + src_ahb2 = FTDMAC020_LLI_SRC_SEL; 1330 + } else { 1331 + dst_ahb2 = PL080_CONTROL_DST_AHB2; 1332 + src_ahb2 = PL080_CONTROL_SRC_AHB2; 1333 + } 1655 1334 1656 1335 if (!(dst & PL08X_AHB1) || ((dst & PL08X_AHB2) && (src & PL08X_AHB1))) 1657 - cctl |= PL080_CONTROL_DST_AHB2; 1336 + cctl |= dst_ahb2; 1658 1337 if (!(src & PL08X_AHB1) || ((src & PL08X_AHB2) && !(dst & PL08X_AHB2))) 1659 - cctl |= PL080_CONTROL_SRC_AHB2; 1338 + cctl |= src_ahb2; 1660 1339 1661 1340 return cctl; 1662 1341 } ··· 1755 1412 { 1756 1413 struct pl08x_txd *txd = kzalloc(sizeof(*txd), GFP_NOWAIT); 1757 1414 1758 - if (txd) { 1415 + if (txd) 1759 1416 INIT_LIST_HEAD(&txd->dsg_list); 1760 - 1761 - /* Always enable error and terminal interrupts */ 1762 - txd->ccfg = PL080_CONFIG_ERR_IRQ_MASK | 1763 - PL080_CONFIG_TC_IRQ_MASK; 1764 - } 1765 1417 return txd; 1418 + } 1419 + 1420 + static u32 pl08x_memcpy_cctl(struct pl08x_driver_data *pl08x) 1421 + { 1422 + u32 cctl = 0; 1423 + 1424 + /* Conjure cctl */ 1425 + switch (pl08x->pd->memcpy_burst_size) { 1426 + default: 1427 + dev_err(&pl08x->adev->dev, 1428 + "illegal burst size for memcpy, set to 1\n"); 1429 + /* Fall through */ 1430 + case PL08X_BURST_SZ_1: 1431 + cctl |= PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT | 1432 + PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT; 1433 + break; 1434 + case PL08X_BURST_SZ_4: 1435 + cctl |= PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | 1436 + PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT; 1437 + break; 1438 + case PL08X_BURST_SZ_8: 1439 + cctl |= PL080_BSIZE_8 << PL080_CONTROL_SB_SIZE_SHIFT | 1440 + PL080_BSIZE_8 << PL080_CONTROL_DB_SIZE_SHIFT; 1441 + break; 1442 + case PL08X_BURST_SZ_16: 1443 + cctl |= PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | 1444 + PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT; 1445 + break; 1446 + case PL08X_BURST_SZ_32: 1447 + cctl |= PL080_BSIZE_32 << PL080_CONTROL_SB_SIZE_SHIFT | 1448 + PL080_BSIZE_32 << PL080_CONTROL_DB_SIZE_SHIFT; 1449 + break; 1450 + case PL08X_BURST_SZ_64: 1451 + cctl |= PL080_BSIZE_64 << PL080_CONTROL_SB_SIZE_SHIFT | 1452 + PL080_BSIZE_64 << PL080_CONTROL_DB_SIZE_SHIFT; 1453 + break; 1454 + case PL08X_BURST_SZ_128: 1455 + cctl |= PL080_BSIZE_128 << PL080_CONTROL_SB_SIZE_SHIFT | 1456 + PL080_BSIZE_128 << PL080_CONTROL_DB_SIZE_SHIFT; 1457 + break; 1458 + case PL08X_BURST_SZ_256: 1459 + cctl |= PL080_BSIZE_256 << PL080_CONTROL_SB_SIZE_SHIFT | 1460 + PL080_BSIZE_256 << PL080_CONTROL_DB_SIZE_SHIFT; 1461 + break; 1462 + } 1463 + 1464 + switch (pl08x->pd->memcpy_bus_width) { 1465 + default: 1466 + dev_err(&pl08x->adev->dev, 1467 + "illegal bus width for memcpy, set to 8 bits\n"); 1468 + /* Fall through */ 1469 + case PL08X_BUS_WIDTH_8_BITS: 1470 + cctl |= PL080_WIDTH_8BIT << PL080_CONTROL_SWIDTH_SHIFT | 1471 + PL080_WIDTH_8BIT << PL080_CONTROL_DWIDTH_SHIFT; 1472 + break; 1473 + case PL08X_BUS_WIDTH_16_BITS: 1474 + cctl |= PL080_WIDTH_16BIT << PL080_CONTROL_SWIDTH_SHIFT | 1475 + PL080_WIDTH_16BIT << PL080_CONTROL_DWIDTH_SHIFT; 1476 + break; 1477 + case PL08X_BUS_WIDTH_32_BITS: 1478 + cctl |= PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | 1479 + PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT; 1480 + break; 1481 + } 1482 + 1483 + /* Protection flags */ 1484 + if (pl08x->pd->memcpy_prot_buff) 1485 + cctl |= PL080_CONTROL_PROT_BUFF; 1486 + if (pl08x->pd->memcpy_prot_cache) 1487 + cctl |= PL080_CONTROL_PROT_CACHE; 1488 + 1489 + /* We are the kernel, so we are in privileged mode */ 1490 + cctl |= PL080_CONTROL_PROT_SYS; 1491 + 1492 + /* Both to be incremented or the code will break */ 1493 + cctl |= PL080_CONTROL_SRC_INCR | PL080_CONTROL_DST_INCR; 1494 + 1495 + if (pl08x->vd->dualmaster) 1496 + cctl |= pl08x_select_bus(false, 1497 + pl08x->mem_buses, 1498 + pl08x->mem_buses); 1499 + 1500 + return cctl; 1501 + } 1502 + 1503 + static u32 pl08x_ftdmac020_memcpy_cctl(struct pl08x_driver_data *pl08x) 1504 + { 1505 + u32 cctl = 0; 1506 + 1507 + /* Conjure cctl */ 1508 + switch (pl08x->pd->memcpy_bus_width) { 1509 + default: 1510 + dev_err(&pl08x->adev->dev, 1511 + "illegal bus width for memcpy, set to 8 bits\n"); 1512 + /* Fall through */ 1513 + case PL08X_BUS_WIDTH_8_BITS: 1514 + cctl |= PL080_WIDTH_8BIT << FTDMAC020_LLI_SRC_WIDTH_SHIFT | 1515 + PL080_WIDTH_8BIT << FTDMAC020_LLI_DST_WIDTH_SHIFT; 1516 + break; 1517 + case PL08X_BUS_WIDTH_16_BITS: 1518 + cctl |= PL080_WIDTH_16BIT << FTDMAC020_LLI_SRC_WIDTH_SHIFT | 1519 + PL080_WIDTH_16BIT << FTDMAC020_LLI_DST_WIDTH_SHIFT; 1520 + break; 1521 + case PL08X_BUS_WIDTH_32_BITS: 1522 + cctl |= PL080_WIDTH_32BIT << FTDMAC020_LLI_SRC_WIDTH_SHIFT | 1523 + PL080_WIDTH_32BIT << FTDMAC020_LLI_DST_WIDTH_SHIFT; 1524 + break; 1525 + } 1526 + 1527 + /* 1528 + * By default mask the TC IRQ on all LLIs, it will be unmasked on 1529 + * the last LLI item by other code. 1530 + */ 1531 + cctl |= FTDMAC020_LLI_TC_MSK; 1532 + 1533 + /* 1534 + * Both to be incremented so leave bits FTDMAC020_LLI_SRCAD_CTL 1535 + * and FTDMAC020_LLI_DSTAD_CTL as zero 1536 + */ 1537 + if (pl08x->vd->dualmaster) 1538 + cctl |= pl08x_select_bus(true, 1539 + pl08x->mem_buses, 1540 + pl08x->mem_buses); 1541 + 1542 + return cctl; 1766 1543 } 1767 1544 1768 1545 /* ··· 1915 1452 dsg->src_addr = src; 1916 1453 dsg->dst_addr = dest; 1917 1454 dsg->len = len; 1918 - 1919 - /* Set platform data for m2m */ 1920 - txd->ccfg |= PL080_FLOW_MEM2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1921 - txd->cctl = pl08x->pd->memcpy_channel.cctl_memcpy & 1922 - ~(PL080_CONTROL_DST_AHB2 | PL080_CONTROL_SRC_AHB2); 1923 - 1924 - /* Both to be incremented or the code will break */ 1925 - txd->cctl |= PL080_CONTROL_SRC_INCR | PL080_CONTROL_DST_INCR; 1926 - 1927 - if (pl08x->vd->dualmaster) 1928 - txd->cctl |= pl08x_select_bus(pl08x->mem_buses, 1929 - pl08x->mem_buses); 1455 + if (pl08x->vd->ftdmac020) { 1456 + /* Writing CCFG zero ENABLES all interrupts */ 1457 + txd->ccfg = 0; 1458 + txd->cctl = pl08x_ftdmac020_memcpy_cctl(pl08x); 1459 + } else { 1460 + txd->ccfg = PL080_CONFIG_ERR_IRQ_MASK | 1461 + PL080_CONFIG_TC_IRQ_MASK | 1462 + PL080_FLOW_MEM2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1463 + txd->cctl = pl08x_memcpy_cctl(pl08x); 1464 + } 1930 1465 1931 1466 ret = pl08x_fill_llis_for_desc(plchan->host, txd); 1932 1467 if (!ret) { ··· 1988 1527 return NULL; 1989 1528 } 1990 1529 1991 - txd->cctl = cctl | pl08x_select_bus(src_buses, dst_buses); 1530 + txd->cctl = cctl | pl08x_select_bus(false, src_buses, dst_buses); 1992 1531 1993 1532 if (plchan->cfg.device_fc) 1994 1533 tmp = (direction == DMA_MEM_TO_DEV) ? PL080_FLOW_MEM2PER_PER : ··· 1997 1536 tmp = (direction == DMA_MEM_TO_DEV) ? PL080_FLOW_MEM2PER : 1998 1537 PL080_FLOW_PER2MEM; 1999 1538 2000 - txd->ccfg |= tmp << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1539 + txd->ccfg = PL080_CONFIG_ERR_IRQ_MASK | 1540 + PL080_CONFIG_TC_IRQ_MASK | 1541 + tmp << PL080_CONFIG_FLOW_CONTROL_SHIFT; 2001 1542 2002 1543 ret = pl08x_request_mux(plchan); 2003 1544 if (ret < 0) { ··· 2276 1813 /* The Nomadik variant does not have the config register */ 2277 1814 if (pl08x->vd->nomadik) 2278 1815 return; 1816 + /* The FTDMAC020 variant does this in another register */ 1817 + if (pl08x->vd->ftdmac020) { 1818 + writel(PL080_CONFIG_ENABLE, pl08x->base + FTDMAC020_CSR); 1819 + return; 1820 + } 2279 1821 writel(PL080_CONFIG_ENABLE, pl08x->base + PL080_CONFIG); 2280 1822 } 2281 1823 ··· 2393 1925 chan->signal = i; 2394 1926 pl08x_dma_slave_init(chan); 2395 1927 } else { 2396 - chan->cd = &pl08x->pd->memcpy_channel; 1928 + chan->cd = kzalloc(sizeof(*chan->cd), GFP_KERNEL); 1929 + if (!chan->cd) { 1930 + kfree(chan); 1931 + return -ENOMEM; 1932 + } 1933 + chan->cd->bus_id = "memcpy"; 1934 + chan->cd->periph_buses = pl08x->pd->mem_buses; 2397 1935 chan->name = kasprintf(GFP_KERNEL, "memcpy%d", i); 2398 1936 if (!chan->name) { 1937 + kfree(chan->cd); 2399 1938 kfree(chan); 2400 1939 return -ENOMEM; 2401 1940 } ··· 2484 2009 pl08x_state_str(chan->state)); 2485 2010 } 2486 2011 2487 - seq_printf(s, "\nPL08x virtual slave channels:\n"); 2488 - seq_printf(s, "CHANNEL:\tSTATE:\n"); 2489 - seq_printf(s, "--------\t------\n"); 2490 - list_for_each_entry(chan, &pl08x->slave.channels, vc.chan.device_node) { 2491 - seq_printf(s, "%s\t\t%s\n", chan->name, 2492 - pl08x_state_str(chan->state)); 2012 + if (pl08x->has_slave) { 2013 + seq_printf(s, "\nPL08x virtual slave channels:\n"); 2014 + seq_printf(s, "CHANNEL:\tSTATE:\n"); 2015 + seq_printf(s, "--------\t------\n"); 2016 + list_for_each_entry(chan, &pl08x->slave.channels, 2017 + vc.chan.device_node) { 2018 + seq_printf(s, "%s\t\t%s\n", chan->name, 2019 + pl08x_state_str(chan->state)); 2020 + } 2493 2021 } 2494 2022 2495 2023 return 0; ··· 2529 2051 u32 id) 2530 2052 { 2531 2053 struct pl08x_dma_chan *chan; 2054 + 2055 + /* Trying to get a slave channel from something with no slave support */ 2056 + if (!pl08x->has_slave) 2057 + return NULL; 2532 2058 2533 2059 list_for_each_entry(chan, &pl08x->slave.channels, vc.chan.device_node) { 2534 2060 if (chan->signal == id) ··· 2581 2099 { 2582 2100 struct pl08x_platform_data *pd; 2583 2101 struct pl08x_channel_data *chanp = NULL; 2584 - u32 cctl_memcpy = 0; 2585 2102 u32 val; 2586 2103 int ret; 2587 2104 int i; ··· 2620 2139 dev_err(&adev->dev, "illegal burst size for memcpy, set to 1\n"); 2621 2140 /* Fall through */ 2622 2141 case 1: 2623 - cctl_memcpy |= PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT | 2624 - PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT; 2142 + pd->memcpy_burst_size = PL08X_BURST_SZ_1; 2625 2143 break; 2626 2144 case 4: 2627 - cctl_memcpy |= PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | 2628 - PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT; 2145 + pd->memcpy_burst_size = PL08X_BURST_SZ_4; 2629 2146 break; 2630 2147 case 8: 2631 - cctl_memcpy |= PL080_BSIZE_8 << PL080_CONTROL_SB_SIZE_SHIFT | 2632 - PL080_BSIZE_8 << PL080_CONTROL_DB_SIZE_SHIFT; 2148 + pd->memcpy_burst_size = PL08X_BURST_SZ_8; 2633 2149 break; 2634 2150 case 16: 2635 - cctl_memcpy |= PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | 2636 - PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT; 2151 + pd->memcpy_burst_size = PL08X_BURST_SZ_16; 2637 2152 break; 2638 2153 case 32: 2639 - cctl_memcpy |= PL080_BSIZE_32 << PL080_CONTROL_SB_SIZE_SHIFT | 2640 - PL080_BSIZE_32 << PL080_CONTROL_DB_SIZE_SHIFT; 2154 + pd->memcpy_burst_size = PL08X_BURST_SZ_32; 2641 2155 break; 2642 2156 case 64: 2643 - cctl_memcpy |= PL080_BSIZE_64 << PL080_CONTROL_SB_SIZE_SHIFT | 2644 - PL080_BSIZE_64 << PL080_CONTROL_DB_SIZE_SHIFT; 2157 + pd->memcpy_burst_size = PL08X_BURST_SZ_64; 2645 2158 break; 2646 2159 case 128: 2647 - cctl_memcpy |= PL080_BSIZE_128 << PL080_CONTROL_SB_SIZE_SHIFT | 2648 - PL080_BSIZE_128 << PL080_CONTROL_DB_SIZE_SHIFT; 2160 + pd->memcpy_burst_size = PL08X_BURST_SZ_128; 2649 2161 break; 2650 2162 case 256: 2651 - cctl_memcpy |= PL080_BSIZE_256 << PL080_CONTROL_SB_SIZE_SHIFT | 2652 - PL080_BSIZE_256 << PL080_CONTROL_DB_SIZE_SHIFT; 2163 + pd->memcpy_burst_size = PL08X_BURST_SZ_256; 2653 2164 break; 2654 2165 } 2655 2166 ··· 2655 2182 dev_err(&adev->dev, "illegal bus width for memcpy, set to 8 bits\n"); 2656 2183 /* Fall through */ 2657 2184 case 8: 2658 - cctl_memcpy |= PL080_WIDTH_8BIT << PL080_CONTROL_SWIDTH_SHIFT | 2659 - PL080_WIDTH_8BIT << PL080_CONTROL_DWIDTH_SHIFT; 2185 + pd->memcpy_bus_width = PL08X_BUS_WIDTH_8_BITS; 2660 2186 break; 2661 2187 case 16: 2662 - cctl_memcpy |= PL080_WIDTH_16BIT << PL080_CONTROL_SWIDTH_SHIFT | 2663 - PL080_WIDTH_16BIT << PL080_CONTROL_DWIDTH_SHIFT; 2188 + pd->memcpy_bus_width = PL08X_BUS_WIDTH_16_BITS; 2664 2189 break; 2665 2190 case 32: 2666 - cctl_memcpy |= PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | 2667 - PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT; 2191 + pd->memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS; 2668 2192 break; 2669 2193 } 2670 - 2671 - /* This is currently the only thing making sense */ 2672 - cctl_memcpy |= PL080_CONTROL_PROT_SYS; 2673 - 2674 - /* Set up memcpy channel */ 2675 - pd->memcpy_channel.bus_id = "memcpy"; 2676 - pd->memcpy_channel.cctl_memcpy = cctl_memcpy; 2677 - /* Use the buses that can access memory, obviously */ 2678 - pd->memcpy_channel.periph_buses = pd->mem_buses; 2679 2194 2680 2195 /* 2681 2196 * Allocate channel data for all possible slave channels (one ··· 2671 2210 * for a device and have it's AHB interfaces set up at 2672 2211 * translation time. 2673 2212 */ 2674 - chanp = devm_kcalloc(&adev->dev, 2675 - pl08x->vd->signals, 2676 - sizeof(struct pl08x_channel_data), 2677 - GFP_KERNEL); 2678 - if (!chanp) 2679 - return -ENOMEM; 2213 + if (pl08x->vd->signals) { 2214 + chanp = devm_kcalloc(&adev->dev, 2215 + pl08x->vd->signals, 2216 + sizeof(struct pl08x_channel_data), 2217 + GFP_KERNEL); 2218 + if (!chanp) 2219 + return -ENOMEM; 2680 2220 2681 - pd->slave_channels = chanp; 2682 - for (i = 0; i < pl08x->vd->signals; i++) { 2683 - /* chanp->periph_buses will be assigned at translation */ 2684 - chanp->bus_id = kasprintf(GFP_KERNEL, "slave%d", i); 2685 - chanp++; 2221 + pd->slave_channels = chanp; 2222 + for (i = 0; i < pl08x->vd->signals; i++) { 2223 + /* 2224 + * chanp->periph_buses will be assigned at translation 2225 + */ 2226 + chanp->bus_id = kasprintf(GFP_KERNEL, "slave%d", i); 2227 + chanp++; 2228 + } 2229 + pd->num_slave_channels = pl08x->vd->signals; 2686 2230 } 2687 - pd->num_slave_channels = pl08x->vd->signals; 2688 2231 2689 2232 pl08x->pd = pd; 2690 2233 ··· 2707 2242 static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) 2708 2243 { 2709 2244 struct pl08x_driver_data *pl08x; 2710 - const struct vendor_data *vd = id->data; 2245 + struct vendor_data *vd = id->data; 2711 2246 struct device_node *np = adev->dev.of_node; 2712 2247 u32 tsfr_size; 2713 2248 int ret = 0; ··· 2733 2268 pl08x->adev = adev; 2734 2269 pl08x->vd = vd; 2735 2270 2271 + pl08x->base = ioremap(adev->res.start, resource_size(&adev->res)); 2272 + if (!pl08x->base) { 2273 + ret = -ENOMEM; 2274 + goto out_no_ioremap; 2275 + } 2276 + 2277 + if (vd->ftdmac020) { 2278 + u32 val; 2279 + 2280 + val = readl(pl08x->base + FTDMAC020_REVISION); 2281 + dev_info(&pl08x->adev->dev, "FTDMAC020 %d.%d rel %d\n", 2282 + (val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff); 2283 + val = readl(pl08x->base + FTDMAC020_FEATURE); 2284 + dev_info(&pl08x->adev->dev, "FTDMAC020 %d channels, " 2285 + "%s built-in bridge, %s, %s linked lists\n", 2286 + (val >> 12) & 0x0f, 2287 + (val & BIT(10)) ? "no" : "has", 2288 + (val & BIT(9)) ? "AHB0 and AHB1" : "AHB0", 2289 + (val & BIT(8)) ? "supports" : "does not support"); 2290 + 2291 + /* Vendor data from feature register */ 2292 + if (!(val & BIT(8))) 2293 + dev_warn(&pl08x->adev->dev, 2294 + "linked lists not supported, required\n"); 2295 + vd->channels = (val >> 12) & 0x0f; 2296 + vd->dualmaster = !!(val & BIT(9)); 2297 + } 2298 + 2736 2299 /* Initialize memcpy engine */ 2737 2300 dma_cap_set(DMA_MEMCPY, pl08x->memcpy.cap_mask); 2738 2301 pl08x->memcpy.dev = &adev->dev; ··· 2777 2284 pl08x->memcpy.dst_addr_widths = PL80X_DMA_BUSWIDTHS; 2778 2285 pl08x->memcpy.directions = BIT(DMA_MEM_TO_MEM); 2779 2286 pl08x->memcpy.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; 2287 + if (vd->ftdmac020) 2288 + pl08x->memcpy.copy_align = DMAENGINE_ALIGN_4_BYTES; 2780 2289 2781 - /* Initialize slave engine */ 2782 - dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask); 2783 - dma_cap_set(DMA_CYCLIC, pl08x->slave.cap_mask); 2784 - pl08x->slave.dev = &adev->dev; 2785 - pl08x->slave.device_free_chan_resources = pl08x_free_chan_resources; 2786 - pl08x->slave.device_prep_dma_interrupt = pl08x_prep_dma_interrupt; 2787 - pl08x->slave.device_tx_status = pl08x_dma_tx_status; 2788 - pl08x->slave.device_issue_pending = pl08x_issue_pending; 2789 - pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg; 2790 - pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic; 2791 - pl08x->slave.device_config = pl08x_config; 2792 - pl08x->slave.device_pause = pl08x_pause; 2793 - pl08x->slave.device_resume = pl08x_resume; 2794 - pl08x->slave.device_terminate_all = pl08x_terminate_all; 2795 - pl08x->slave.src_addr_widths = PL80X_DMA_BUSWIDTHS; 2796 - pl08x->slave.dst_addr_widths = PL80X_DMA_BUSWIDTHS; 2797 - pl08x->slave.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); 2798 - pl08x->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; 2290 + 2291 + /* 2292 + * Initialize slave engine, if the block has no signals, that means 2293 + * we have no slave support. 2294 + */ 2295 + if (vd->signals) { 2296 + pl08x->has_slave = true; 2297 + dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask); 2298 + dma_cap_set(DMA_CYCLIC, pl08x->slave.cap_mask); 2299 + pl08x->slave.dev = &adev->dev; 2300 + pl08x->slave.device_free_chan_resources = 2301 + pl08x_free_chan_resources; 2302 + pl08x->slave.device_prep_dma_interrupt = 2303 + pl08x_prep_dma_interrupt; 2304 + pl08x->slave.device_tx_status = pl08x_dma_tx_status; 2305 + pl08x->slave.device_issue_pending = pl08x_issue_pending; 2306 + pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg; 2307 + pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic; 2308 + pl08x->slave.device_config = pl08x_config; 2309 + pl08x->slave.device_pause = pl08x_pause; 2310 + pl08x->slave.device_resume = pl08x_resume; 2311 + pl08x->slave.device_terminate_all = pl08x_terminate_all; 2312 + pl08x->slave.src_addr_widths = PL80X_DMA_BUSWIDTHS; 2313 + pl08x->slave.dst_addr_widths = PL80X_DMA_BUSWIDTHS; 2314 + pl08x->slave.directions = 2315 + BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); 2316 + pl08x->slave.residue_granularity = 2317 + DMA_RESIDUE_GRANULARITY_SEGMENT; 2318 + } 2799 2319 2800 2320 /* Get the platform data */ 2801 2321 pl08x->pd = dev_get_platdata(&adev->dev); ··· 2850 2344 goto out_no_lli_pool; 2851 2345 } 2852 2346 2853 - pl08x->base = ioremap(adev->res.start, resource_size(&adev->res)); 2854 - if (!pl08x->base) { 2855 - ret = -ENOMEM; 2856 - goto out_no_ioremap; 2857 - } 2858 - 2859 2347 /* Turn on the PL08x */ 2860 2348 pl08x_ensure_on(pl08x); 2861 2349 2862 - /* Attach the interrupt handler */ 2863 - writel(0x000000FF, pl08x->base + PL080_ERR_CLEAR); 2350 + /* Clear any pending interrupts */ 2351 + if (vd->ftdmac020) 2352 + /* This variant has error IRQs in bits 16-19 */ 2353 + writel(0x0000FFFF, pl08x->base + PL080_ERR_CLEAR); 2354 + else 2355 + writel(0x000000FF, pl08x->base + PL080_ERR_CLEAR); 2864 2356 writel(0x000000FF, pl08x->base + PL080_TC_CLEAR); 2865 2357 2358 + /* Attach the interrupt handler */ 2866 2359 ret = request_irq(adev->irq[0], pl08x_irq, 0, DRIVER_NAME, pl08x); 2867 2360 if (ret) { 2868 2361 dev_err(&adev->dev, "%s failed to request interrupt %d\n", ··· 2882 2377 2883 2378 ch->id = i; 2884 2379 ch->base = pl08x->base + PL080_Cx_BASE(i); 2885 - ch->reg_config = ch->base + vd->config_offset; 2380 + if (vd->ftdmac020) { 2381 + /* FTDMA020 has a special channel busy register */ 2382 + ch->reg_busy = ch->base + FTDMAC020_CH_BUSY; 2383 + ch->reg_config = ch->base + FTDMAC020_CH_CFG; 2384 + ch->reg_control = ch->base + FTDMAC020_CH_CSR; 2385 + ch->reg_src = ch->base + FTDMAC020_CH_SRC_ADDR; 2386 + ch->reg_dst = ch->base + FTDMAC020_CH_DST_ADDR; 2387 + ch->reg_lli = ch->base + FTDMAC020_CH_LLP; 2388 + ch->ftdmac020 = true; 2389 + } else { 2390 + ch->reg_config = ch->base + vd->config_offset; 2391 + ch->reg_control = ch->base + PL080_CH_CONTROL; 2392 + ch->reg_src = ch->base + PL080_CH_SRC_ADDR; 2393 + ch->reg_dst = ch->base + PL080_CH_DST_ADDR; 2394 + ch->reg_lli = ch->base + PL080_CH_LLI; 2395 + } 2396 + if (vd->pl080s) 2397 + ch->pl080s = true; 2398 + 2886 2399 spin_lock_init(&ch->lock); 2887 2400 2888 2401 /* ··· 2933 2410 } 2934 2411 2935 2412 /* Register slave channels */ 2936 - ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->slave, 2937 - pl08x->pd->num_slave_channels, true); 2938 - if (ret < 0) { 2939 - dev_warn(&pl08x->adev->dev, 2940 - "%s failed to enumerate slave channels - %d\n", 2941 - __func__, ret); 2942 - goto out_no_slave; 2413 + if (pl08x->has_slave) { 2414 + ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->slave, 2415 + pl08x->pd->num_slave_channels, true); 2416 + if (ret < 0) { 2417 + dev_warn(&pl08x->adev->dev, 2418 + "%s failed to enumerate slave channels - %d\n", 2419 + __func__, ret); 2420 + goto out_no_slave; 2421 + } 2943 2422 } 2944 2423 2945 2424 ret = dma_async_device_register(&pl08x->memcpy); ··· 2952 2427 goto out_no_memcpy_reg; 2953 2428 } 2954 2429 2955 - ret = dma_async_device_register(&pl08x->slave); 2956 - if (ret) { 2957 - dev_warn(&pl08x->adev->dev, 2430 + if (pl08x->has_slave) { 2431 + ret = dma_async_device_register(&pl08x->slave); 2432 + if (ret) { 2433 + dev_warn(&pl08x->adev->dev, 2958 2434 "%s failed to register slave as an async device - %d\n", 2959 2435 __func__, ret); 2960 - goto out_no_slave_reg; 2436 + goto out_no_slave_reg; 2437 + } 2961 2438 } 2962 2439 2963 2440 amba_set_drvdata(adev, pl08x); ··· 2973 2446 out_no_slave_reg: 2974 2447 dma_async_device_unregister(&pl08x->memcpy); 2975 2448 out_no_memcpy_reg: 2976 - pl08x_free_virtual_channels(&pl08x->slave); 2449 + if (pl08x->has_slave) 2450 + pl08x_free_virtual_channels(&pl08x->slave); 2977 2451 out_no_slave: 2978 2452 pl08x_free_virtual_channels(&pl08x->memcpy); 2979 2453 out_no_memcpy: ··· 2982 2454 out_no_phychans: 2983 2455 free_irq(adev->irq[0], pl08x); 2984 2456 out_no_irq: 2985 - iounmap(pl08x->base); 2986 - out_no_ioremap: 2987 2457 dma_pool_destroy(pl08x->pool); 2988 2458 out_no_lli_pool: 2989 2459 out_no_platdata: 2460 + iounmap(pl08x->base); 2461 + out_no_ioremap: 2990 2462 kfree(pl08x); 2991 2463 out_no_pl08x: 2992 2464 amba_release_regions(adev); ··· 3027 2499 .max_transfer_size = PL080_CONTROL_TRANSFER_SIZE_MASK, 3028 2500 }; 3029 2501 2502 + static struct vendor_data vendor_ftdmac020 = { 2503 + .config_offset = PL080_CH_CONFIG, 2504 + .ftdmac020 = true, 2505 + .max_transfer_size = PL080_CONTROL_TRANSFER_SIZE_MASK, 2506 + }; 2507 + 3030 2508 static struct amba_id pl08x_ids[] = { 3031 2509 /* Samsung PL080S variant */ 3032 2510 { ··· 3057 2523 .id = 0x00280080, 3058 2524 .mask = 0x00ffffff, 3059 2525 .data = &vendor_nomadik, 2526 + }, 2527 + /* Faraday Technology FTDMAC020 */ 2528 + { 2529 + .id = 0x0003b080, 2530 + .mask = 0x000fffff, 2531 + .data = &vendor_ftdmac020, 3060 2532 }, 3061 2533 { 0, 0 }, 3062 2534 };
+1785
drivers/dma/bcm-sba-raid.c
··· 1 + /* 2 + * Copyright (C) 2017 Broadcom 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + /* 10 + * Broadcom SBA RAID Driver 11 + * 12 + * The Broadcom stream buffer accelerator (SBA) provides offloading 13 + * capabilities for RAID operations. The SBA offload engine is accessible 14 + * via Broadcom SoC specific ring manager. Two or more offload engines 15 + * can share same Broadcom SoC specific ring manager due to this Broadcom 16 + * SoC specific ring manager driver is implemented as a mailbox controller 17 + * driver and offload engine drivers are implemented as mallbox clients. 18 + * 19 + * Typically, Broadcom SoC specific ring manager will implement larger 20 + * number of hardware rings over one or more SBA hardware devices. By 21 + * design, the internal buffer size of SBA hardware device is limited 22 + * but all offload operations supported by SBA can be broken down into 23 + * multiple small size requests and executed parallely on multiple SBA 24 + * hardware devices for achieving high through-put. 25 + * 26 + * The Broadcom SBA RAID driver does not require any register programming 27 + * except submitting request to SBA hardware device via mailbox channels. 28 + * This driver implements a DMA device with one DMA channel using a set 29 + * of mailbox channels provided by Broadcom SoC specific ring manager 30 + * driver. To exploit parallelism (as described above), all DMA request 31 + * coming to SBA RAID DMA channel are broken down to smaller requests 32 + * and submitted to multiple mailbox channels in round-robin fashion. 33 + * For having more SBA DMA channels, we can create more SBA device nodes 34 + * in Broadcom SoC specific DTS based on number of hardware rings supported 35 + * by Broadcom SoC ring manager. 36 + */ 37 + 38 + #include <linux/bitops.h> 39 + #include <linux/dma-mapping.h> 40 + #include <linux/dmaengine.h> 41 + #include <linux/list.h> 42 + #include <linux/mailbox_client.h> 43 + #include <linux/mailbox/brcm-message.h> 44 + #include <linux/module.h> 45 + #include <linux/of_device.h> 46 + #include <linux/slab.h> 47 + #include <linux/raid/pq.h> 48 + 49 + #include "dmaengine.h" 50 + 51 + /* SBA command related defines */ 52 + #define SBA_TYPE_SHIFT 48 53 + #define SBA_TYPE_MASK GENMASK(1, 0) 54 + #define SBA_TYPE_A 0x0 55 + #define SBA_TYPE_B 0x2 56 + #define SBA_TYPE_C 0x3 57 + #define SBA_USER_DEF_SHIFT 32 58 + #define SBA_USER_DEF_MASK GENMASK(15, 0) 59 + #define SBA_R_MDATA_SHIFT 24 60 + #define SBA_R_MDATA_MASK GENMASK(7, 0) 61 + #define SBA_C_MDATA_MS_SHIFT 18 62 + #define SBA_C_MDATA_MS_MASK GENMASK(1, 0) 63 + #define SBA_INT_SHIFT 17 64 + #define SBA_INT_MASK BIT(0) 65 + #define SBA_RESP_SHIFT 16 66 + #define SBA_RESP_MASK BIT(0) 67 + #define SBA_C_MDATA_SHIFT 8 68 + #define SBA_C_MDATA_MASK GENMASK(7, 0) 69 + #define SBA_C_MDATA_BNUMx_SHIFT(__bnum) (2 * (__bnum)) 70 + #define SBA_C_MDATA_BNUMx_MASK GENMASK(1, 0) 71 + #define SBA_C_MDATA_DNUM_SHIFT 5 72 + #define SBA_C_MDATA_DNUM_MASK GENMASK(4, 0) 73 + #define SBA_C_MDATA_LS(__v) ((__v) & 0xff) 74 + #define SBA_C_MDATA_MS(__v) (((__v) >> 8) & 0x3) 75 + #define SBA_CMD_SHIFT 0 76 + #define SBA_CMD_MASK GENMASK(3, 0) 77 + #define SBA_CMD_ZERO_BUFFER 0x4 78 + #define SBA_CMD_ZERO_ALL_BUFFERS 0x8 79 + #define SBA_CMD_LOAD_BUFFER 0x9 80 + #define SBA_CMD_XOR 0xa 81 + #define SBA_CMD_GALOIS_XOR 0xb 82 + #define SBA_CMD_WRITE_BUFFER 0xc 83 + #define SBA_CMD_GALOIS 0xe 84 + 85 + /* Driver helper macros */ 86 + #define to_sba_request(tx) \ 87 + container_of(tx, struct sba_request, tx) 88 + #define to_sba_device(dchan) \ 89 + container_of(dchan, struct sba_device, dma_chan) 90 + 91 + enum sba_request_state { 92 + SBA_REQUEST_STATE_FREE = 1, 93 + SBA_REQUEST_STATE_ALLOCED = 2, 94 + SBA_REQUEST_STATE_PENDING = 3, 95 + SBA_REQUEST_STATE_ACTIVE = 4, 96 + SBA_REQUEST_STATE_RECEIVED = 5, 97 + SBA_REQUEST_STATE_COMPLETED = 6, 98 + SBA_REQUEST_STATE_ABORTED = 7, 99 + }; 100 + 101 + struct sba_request { 102 + /* Global state */ 103 + struct list_head node; 104 + struct sba_device *sba; 105 + enum sba_request_state state; 106 + bool fence; 107 + /* Chained requests management */ 108 + struct sba_request *first; 109 + struct list_head next; 110 + unsigned int next_count; 111 + atomic_t next_pending_count; 112 + /* BRCM message data */ 113 + void *resp; 114 + dma_addr_t resp_dma; 115 + struct brcm_sba_command *cmds; 116 + struct brcm_message msg; 117 + struct dma_async_tx_descriptor tx; 118 + }; 119 + 120 + enum sba_version { 121 + SBA_VER_1 = 0, 122 + SBA_VER_2 123 + }; 124 + 125 + struct sba_device { 126 + /* Underlying device */ 127 + struct device *dev; 128 + /* DT configuration parameters */ 129 + enum sba_version ver; 130 + /* Derived configuration parameters */ 131 + u32 max_req; 132 + u32 hw_buf_size; 133 + u32 hw_resp_size; 134 + u32 max_pq_coefs; 135 + u32 max_pq_srcs; 136 + u32 max_cmd_per_req; 137 + u32 max_xor_srcs; 138 + u32 max_resp_pool_size; 139 + u32 max_cmds_pool_size; 140 + /* Maibox client and Mailbox channels */ 141 + struct mbox_client client; 142 + int mchans_count; 143 + atomic_t mchans_current; 144 + struct mbox_chan **mchans; 145 + struct device *mbox_dev; 146 + /* DMA device and DMA channel */ 147 + struct dma_device dma_dev; 148 + struct dma_chan dma_chan; 149 + /* DMA channel resources */ 150 + void *resp_base; 151 + dma_addr_t resp_dma_base; 152 + void *cmds_base; 153 + dma_addr_t cmds_dma_base; 154 + spinlock_t reqs_lock; 155 + struct sba_request *reqs; 156 + bool reqs_fence; 157 + struct list_head reqs_alloc_list; 158 + struct list_head reqs_pending_list; 159 + struct list_head reqs_active_list; 160 + struct list_head reqs_received_list; 161 + struct list_head reqs_completed_list; 162 + struct list_head reqs_aborted_list; 163 + struct list_head reqs_free_list; 164 + int reqs_free_count; 165 + }; 166 + 167 + /* ====== SBA command helper routines ===== */ 168 + 169 + static inline u64 __pure sba_cmd_enc(u64 cmd, u32 val, u32 shift, u32 mask) 170 + { 171 + cmd &= ~((u64)mask << shift); 172 + cmd |= ((u64)(val & mask) << shift); 173 + return cmd; 174 + } 175 + 176 + static inline u32 __pure sba_cmd_load_c_mdata(u32 b0) 177 + { 178 + return b0 & SBA_C_MDATA_BNUMx_MASK; 179 + } 180 + 181 + static inline u32 __pure sba_cmd_write_c_mdata(u32 b0) 182 + { 183 + return b0 & SBA_C_MDATA_BNUMx_MASK; 184 + } 185 + 186 + static inline u32 __pure sba_cmd_xor_c_mdata(u32 b1, u32 b0) 187 + { 188 + return (b0 & SBA_C_MDATA_BNUMx_MASK) | 189 + ((b1 & SBA_C_MDATA_BNUMx_MASK) << SBA_C_MDATA_BNUMx_SHIFT(1)); 190 + } 191 + 192 + static inline u32 __pure sba_cmd_pq_c_mdata(u32 d, u32 b1, u32 b0) 193 + { 194 + return (b0 & SBA_C_MDATA_BNUMx_MASK) | 195 + ((b1 & SBA_C_MDATA_BNUMx_MASK) << SBA_C_MDATA_BNUMx_SHIFT(1)) | 196 + ((d & SBA_C_MDATA_DNUM_MASK) << SBA_C_MDATA_DNUM_SHIFT); 197 + } 198 + 199 + /* ====== Channel resource management routines ===== */ 200 + 201 + static struct sba_request *sba_alloc_request(struct sba_device *sba) 202 + { 203 + unsigned long flags; 204 + struct sba_request *req = NULL; 205 + 206 + spin_lock_irqsave(&sba->reqs_lock, flags); 207 + 208 + req = list_first_entry_or_null(&sba->reqs_free_list, 209 + struct sba_request, node); 210 + if (req) { 211 + list_move_tail(&req->node, &sba->reqs_alloc_list); 212 + req->state = SBA_REQUEST_STATE_ALLOCED; 213 + req->fence = false; 214 + req->first = req; 215 + INIT_LIST_HEAD(&req->next); 216 + req->next_count = 1; 217 + atomic_set(&req->next_pending_count, 1); 218 + 219 + sba->reqs_free_count--; 220 + 221 + dma_async_tx_descriptor_init(&req->tx, &sba->dma_chan); 222 + } 223 + 224 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 225 + 226 + return req; 227 + } 228 + 229 + /* Note: Must be called with sba->reqs_lock held */ 230 + static void _sba_pending_request(struct sba_device *sba, 231 + struct sba_request *req) 232 + { 233 + lockdep_assert_held(&sba->reqs_lock); 234 + req->state = SBA_REQUEST_STATE_PENDING; 235 + list_move_tail(&req->node, &sba->reqs_pending_list); 236 + if (list_empty(&sba->reqs_active_list)) 237 + sba->reqs_fence = false; 238 + } 239 + 240 + /* Note: Must be called with sba->reqs_lock held */ 241 + static bool _sba_active_request(struct sba_device *sba, 242 + struct sba_request *req) 243 + { 244 + lockdep_assert_held(&sba->reqs_lock); 245 + if (list_empty(&sba->reqs_active_list)) 246 + sba->reqs_fence = false; 247 + if (sba->reqs_fence) 248 + return false; 249 + req->state = SBA_REQUEST_STATE_ACTIVE; 250 + list_move_tail(&req->node, &sba->reqs_active_list); 251 + if (req->fence) 252 + sba->reqs_fence = true; 253 + return true; 254 + } 255 + 256 + /* Note: Must be called with sba->reqs_lock held */ 257 + static void _sba_abort_request(struct sba_device *sba, 258 + struct sba_request *req) 259 + { 260 + lockdep_assert_held(&sba->reqs_lock); 261 + req->state = SBA_REQUEST_STATE_ABORTED; 262 + list_move_tail(&req->node, &sba->reqs_aborted_list); 263 + if (list_empty(&sba->reqs_active_list)) 264 + sba->reqs_fence = false; 265 + } 266 + 267 + /* Note: Must be called with sba->reqs_lock held */ 268 + static void _sba_free_request(struct sba_device *sba, 269 + struct sba_request *req) 270 + { 271 + lockdep_assert_held(&sba->reqs_lock); 272 + req->state = SBA_REQUEST_STATE_FREE; 273 + list_move_tail(&req->node, &sba->reqs_free_list); 274 + if (list_empty(&sba->reqs_active_list)) 275 + sba->reqs_fence = false; 276 + sba->reqs_free_count++; 277 + } 278 + 279 + static void sba_received_request(struct sba_request *req) 280 + { 281 + unsigned long flags; 282 + struct sba_device *sba = req->sba; 283 + 284 + spin_lock_irqsave(&sba->reqs_lock, flags); 285 + req->state = SBA_REQUEST_STATE_RECEIVED; 286 + list_move_tail(&req->node, &sba->reqs_received_list); 287 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 288 + } 289 + 290 + static void sba_complete_chained_requests(struct sba_request *req) 291 + { 292 + unsigned long flags; 293 + struct sba_request *nreq; 294 + struct sba_device *sba = req->sba; 295 + 296 + spin_lock_irqsave(&sba->reqs_lock, flags); 297 + 298 + req->state = SBA_REQUEST_STATE_COMPLETED; 299 + list_move_tail(&req->node, &sba->reqs_completed_list); 300 + list_for_each_entry(nreq, &req->next, next) { 301 + nreq->state = SBA_REQUEST_STATE_COMPLETED; 302 + list_move_tail(&nreq->node, &sba->reqs_completed_list); 303 + } 304 + if (list_empty(&sba->reqs_active_list)) 305 + sba->reqs_fence = false; 306 + 307 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 308 + } 309 + 310 + static void sba_free_chained_requests(struct sba_request *req) 311 + { 312 + unsigned long flags; 313 + struct sba_request *nreq; 314 + struct sba_device *sba = req->sba; 315 + 316 + spin_lock_irqsave(&sba->reqs_lock, flags); 317 + 318 + _sba_free_request(sba, req); 319 + list_for_each_entry(nreq, &req->next, next) 320 + _sba_free_request(sba, nreq); 321 + 322 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 323 + } 324 + 325 + static void sba_chain_request(struct sba_request *first, 326 + struct sba_request *req) 327 + { 328 + unsigned long flags; 329 + struct sba_device *sba = req->sba; 330 + 331 + spin_lock_irqsave(&sba->reqs_lock, flags); 332 + 333 + list_add_tail(&req->next, &first->next); 334 + req->first = first; 335 + first->next_count++; 336 + atomic_set(&first->next_pending_count, first->next_count); 337 + 338 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 339 + } 340 + 341 + static void sba_cleanup_nonpending_requests(struct sba_device *sba) 342 + { 343 + unsigned long flags; 344 + struct sba_request *req, *req1; 345 + 346 + spin_lock_irqsave(&sba->reqs_lock, flags); 347 + 348 + /* Freeup all alloced request */ 349 + list_for_each_entry_safe(req, req1, &sba->reqs_alloc_list, node) 350 + _sba_free_request(sba, req); 351 + 352 + /* Freeup all received request */ 353 + list_for_each_entry_safe(req, req1, &sba->reqs_received_list, node) 354 + _sba_free_request(sba, req); 355 + 356 + /* Freeup all completed request */ 357 + list_for_each_entry_safe(req, req1, &sba->reqs_completed_list, node) 358 + _sba_free_request(sba, req); 359 + 360 + /* Set all active requests as aborted */ 361 + list_for_each_entry_safe(req, req1, &sba->reqs_active_list, node) 362 + _sba_abort_request(sba, req); 363 + 364 + /* 365 + * Note: We expect that aborted request will be eventually 366 + * freed by sba_receive_message() 367 + */ 368 + 369 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 370 + } 371 + 372 + static void sba_cleanup_pending_requests(struct sba_device *sba) 373 + { 374 + unsigned long flags; 375 + struct sba_request *req, *req1; 376 + 377 + spin_lock_irqsave(&sba->reqs_lock, flags); 378 + 379 + /* Freeup all pending request */ 380 + list_for_each_entry_safe(req, req1, &sba->reqs_pending_list, node) 381 + _sba_free_request(sba, req); 382 + 383 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 384 + } 385 + 386 + /* ====== DMAENGINE callbacks ===== */ 387 + 388 + static void sba_free_chan_resources(struct dma_chan *dchan) 389 + { 390 + /* 391 + * Channel resources are pre-alloced so we just free-up 392 + * whatever we can so that we can re-use pre-alloced 393 + * channel resources next time. 394 + */ 395 + sba_cleanup_nonpending_requests(to_sba_device(dchan)); 396 + } 397 + 398 + static int sba_device_terminate_all(struct dma_chan *dchan) 399 + { 400 + /* Cleanup all pending requests */ 401 + sba_cleanup_pending_requests(to_sba_device(dchan)); 402 + 403 + return 0; 404 + } 405 + 406 + static int sba_send_mbox_request(struct sba_device *sba, 407 + struct sba_request *req) 408 + { 409 + int mchans_idx, ret = 0; 410 + 411 + /* Select mailbox channel in round-robin fashion */ 412 + mchans_idx = atomic_inc_return(&sba->mchans_current); 413 + mchans_idx = mchans_idx % sba->mchans_count; 414 + 415 + /* Send message for the request */ 416 + req->msg.error = 0; 417 + ret = mbox_send_message(sba->mchans[mchans_idx], &req->msg); 418 + if (ret < 0) { 419 + dev_err(sba->dev, "send message failed with error %d", ret); 420 + return ret; 421 + } 422 + ret = req->msg.error; 423 + if (ret < 0) { 424 + dev_err(sba->dev, "message error %d", ret); 425 + return ret; 426 + } 427 + 428 + return 0; 429 + } 430 + 431 + static void sba_issue_pending(struct dma_chan *dchan) 432 + { 433 + int ret; 434 + unsigned long flags; 435 + struct sba_request *req, *req1; 436 + struct sba_device *sba = to_sba_device(dchan); 437 + 438 + spin_lock_irqsave(&sba->reqs_lock, flags); 439 + 440 + /* Process all pending request */ 441 + list_for_each_entry_safe(req, req1, &sba->reqs_pending_list, node) { 442 + /* Try to make request active */ 443 + if (!_sba_active_request(sba, req)) 444 + break; 445 + 446 + /* Send request to mailbox channel */ 447 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 448 + ret = sba_send_mbox_request(sba, req); 449 + spin_lock_irqsave(&sba->reqs_lock, flags); 450 + 451 + /* If something went wrong then keep request pending */ 452 + if (ret < 0) { 453 + _sba_pending_request(sba, req); 454 + break; 455 + } 456 + } 457 + 458 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 459 + } 460 + 461 + static dma_cookie_t sba_tx_submit(struct dma_async_tx_descriptor *tx) 462 + { 463 + unsigned long flags; 464 + dma_cookie_t cookie; 465 + struct sba_device *sba; 466 + struct sba_request *req, *nreq; 467 + 468 + if (unlikely(!tx)) 469 + return -EINVAL; 470 + 471 + sba = to_sba_device(tx->chan); 472 + req = to_sba_request(tx); 473 + 474 + /* Assign cookie and mark all chained requests pending */ 475 + spin_lock_irqsave(&sba->reqs_lock, flags); 476 + cookie = dma_cookie_assign(tx); 477 + _sba_pending_request(sba, req); 478 + list_for_each_entry(nreq, &req->next, next) 479 + _sba_pending_request(sba, nreq); 480 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 481 + 482 + return cookie; 483 + } 484 + 485 + static enum dma_status sba_tx_status(struct dma_chan *dchan, 486 + dma_cookie_t cookie, 487 + struct dma_tx_state *txstate) 488 + { 489 + int mchan_idx; 490 + enum dma_status ret; 491 + struct sba_device *sba = to_sba_device(dchan); 492 + 493 + for (mchan_idx = 0; mchan_idx < sba->mchans_count; mchan_idx++) 494 + mbox_client_peek_data(sba->mchans[mchan_idx]); 495 + 496 + ret = dma_cookie_status(dchan, cookie, txstate); 497 + if (ret == DMA_COMPLETE) 498 + return ret; 499 + 500 + return dma_cookie_status(dchan, cookie, txstate); 501 + } 502 + 503 + static void sba_fillup_interrupt_msg(struct sba_request *req, 504 + struct brcm_sba_command *cmds, 505 + struct brcm_message *msg) 506 + { 507 + u64 cmd; 508 + u32 c_mdata; 509 + struct brcm_sba_command *cmdsp = cmds; 510 + 511 + /* Type-B command to load dummy data into buf0 */ 512 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 513 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 514 + cmd = sba_cmd_enc(cmd, req->sba->hw_resp_size, 515 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 516 + c_mdata = sba_cmd_load_c_mdata(0); 517 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 518 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 519 + cmd = sba_cmd_enc(cmd, SBA_CMD_LOAD_BUFFER, 520 + SBA_CMD_SHIFT, SBA_CMD_MASK); 521 + cmdsp->cmd = cmd; 522 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 523 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 524 + cmdsp->data = req->resp_dma; 525 + cmdsp->data_len = req->sba->hw_resp_size; 526 + cmdsp++; 527 + 528 + /* Type-A command to write buf0 to dummy location */ 529 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 530 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 531 + cmd = sba_cmd_enc(cmd, req->sba->hw_resp_size, 532 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 533 + cmd = sba_cmd_enc(cmd, 0x1, 534 + SBA_RESP_SHIFT, SBA_RESP_MASK); 535 + c_mdata = sba_cmd_write_c_mdata(0); 536 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 537 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 538 + cmd = sba_cmd_enc(cmd, SBA_CMD_WRITE_BUFFER, 539 + SBA_CMD_SHIFT, SBA_CMD_MASK); 540 + cmdsp->cmd = cmd; 541 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 542 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 543 + if (req->sba->hw_resp_size) { 544 + cmdsp->flags |= BRCM_SBA_CMD_HAS_RESP; 545 + cmdsp->resp = req->resp_dma; 546 + cmdsp->resp_len = req->sba->hw_resp_size; 547 + } 548 + cmdsp->flags |= BRCM_SBA_CMD_HAS_OUTPUT; 549 + cmdsp->data = req->resp_dma; 550 + cmdsp->data_len = req->sba->hw_resp_size; 551 + cmdsp++; 552 + 553 + /* Fillup brcm_message */ 554 + msg->type = BRCM_MESSAGE_SBA; 555 + msg->sba.cmds = cmds; 556 + msg->sba.cmds_count = cmdsp - cmds; 557 + msg->ctx = req; 558 + msg->error = 0; 559 + } 560 + 561 + static struct dma_async_tx_descriptor * 562 + sba_prep_dma_interrupt(struct dma_chan *dchan, unsigned long flags) 563 + { 564 + struct sba_request *req = NULL; 565 + struct sba_device *sba = to_sba_device(dchan); 566 + 567 + /* Alloc new request */ 568 + req = sba_alloc_request(sba); 569 + if (!req) 570 + return NULL; 571 + 572 + /* 573 + * Force fence so that no requests are submitted 574 + * until DMA callback for this request is invoked. 575 + */ 576 + req->fence = true; 577 + 578 + /* Fillup request message */ 579 + sba_fillup_interrupt_msg(req, req->cmds, &req->msg); 580 + 581 + /* Init async_tx descriptor */ 582 + req->tx.flags = flags; 583 + req->tx.cookie = -EBUSY; 584 + 585 + return &req->tx; 586 + } 587 + 588 + static void sba_fillup_memcpy_msg(struct sba_request *req, 589 + struct brcm_sba_command *cmds, 590 + struct brcm_message *msg, 591 + dma_addr_t msg_offset, size_t msg_len, 592 + dma_addr_t dst, dma_addr_t src) 593 + { 594 + u64 cmd; 595 + u32 c_mdata; 596 + struct brcm_sba_command *cmdsp = cmds; 597 + 598 + /* Type-B command to load data into buf0 */ 599 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 600 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 601 + cmd = sba_cmd_enc(cmd, msg_len, 602 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 603 + c_mdata = sba_cmd_load_c_mdata(0); 604 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 605 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 606 + cmd = sba_cmd_enc(cmd, SBA_CMD_LOAD_BUFFER, 607 + SBA_CMD_SHIFT, SBA_CMD_MASK); 608 + cmdsp->cmd = cmd; 609 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 610 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 611 + cmdsp->data = src + msg_offset; 612 + cmdsp->data_len = msg_len; 613 + cmdsp++; 614 + 615 + /* Type-A command to write buf0 */ 616 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 617 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 618 + cmd = sba_cmd_enc(cmd, msg_len, 619 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 620 + cmd = sba_cmd_enc(cmd, 0x1, 621 + SBA_RESP_SHIFT, SBA_RESP_MASK); 622 + c_mdata = sba_cmd_write_c_mdata(0); 623 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 624 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 625 + cmd = sba_cmd_enc(cmd, SBA_CMD_WRITE_BUFFER, 626 + SBA_CMD_SHIFT, SBA_CMD_MASK); 627 + cmdsp->cmd = cmd; 628 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 629 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 630 + if (req->sba->hw_resp_size) { 631 + cmdsp->flags |= BRCM_SBA_CMD_HAS_RESP; 632 + cmdsp->resp = req->resp_dma; 633 + cmdsp->resp_len = req->sba->hw_resp_size; 634 + } 635 + cmdsp->flags |= BRCM_SBA_CMD_HAS_OUTPUT; 636 + cmdsp->data = dst + msg_offset; 637 + cmdsp->data_len = msg_len; 638 + cmdsp++; 639 + 640 + /* Fillup brcm_message */ 641 + msg->type = BRCM_MESSAGE_SBA; 642 + msg->sba.cmds = cmds; 643 + msg->sba.cmds_count = cmdsp - cmds; 644 + msg->ctx = req; 645 + msg->error = 0; 646 + } 647 + 648 + static struct sba_request * 649 + sba_prep_dma_memcpy_req(struct sba_device *sba, 650 + dma_addr_t off, dma_addr_t dst, dma_addr_t src, 651 + size_t len, unsigned long flags) 652 + { 653 + struct sba_request *req = NULL; 654 + 655 + /* Alloc new request */ 656 + req = sba_alloc_request(sba); 657 + if (!req) 658 + return NULL; 659 + req->fence = (flags & DMA_PREP_FENCE) ? true : false; 660 + 661 + /* Fillup request message */ 662 + sba_fillup_memcpy_msg(req, req->cmds, &req->msg, 663 + off, len, dst, src); 664 + 665 + /* Init async_tx descriptor */ 666 + req->tx.flags = flags; 667 + req->tx.cookie = -EBUSY; 668 + 669 + return req; 670 + } 671 + 672 + static struct dma_async_tx_descriptor * 673 + sba_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst, dma_addr_t src, 674 + size_t len, unsigned long flags) 675 + { 676 + size_t req_len; 677 + dma_addr_t off = 0; 678 + struct sba_device *sba = to_sba_device(dchan); 679 + struct sba_request *first = NULL, *req; 680 + 681 + /* Create chained requests where each request is upto hw_buf_size */ 682 + while (len) { 683 + req_len = (len < sba->hw_buf_size) ? len : sba->hw_buf_size; 684 + 685 + req = sba_prep_dma_memcpy_req(sba, off, dst, src, 686 + req_len, flags); 687 + if (!req) { 688 + if (first) 689 + sba_free_chained_requests(first); 690 + return NULL; 691 + } 692 + 693 + if (first) 694 + sba_chain_request(first, req); 695 + else 696 + first = req; 697 + 698 + off += req_len; 699 + len -= req_len; 700 + } 701 + 702 + return (first) ? &first->tx : NULL; 703 + } 704 + 705 + static void sba_fillup_xor_msg(struct sba_request *req, 706 + struct brcm_sba_command *cmds, 707 + struct brcm_message *msg, 708 + dma_addr_t msg_offset, size_t msg_len, 709 + dma_addr_t dst, dma_addr_t *src, u32 src_cnt) 710 + { 711 + u64 cmd; 712 + u32 c_mdata; 713 + unsigned int i; 714 + struct brcm_sba_command *cmdsp = cmds; 715 + 716 + /* Type-B command to load data into buf0 */ 717 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 718 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 719 + cmd = sba_cmd_enc(cmd, msg_len, 720 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 721 + c_mdata = sba_cmd_load_c_mdata(0); 722 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 723 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 724 + cmd = sba_cmd_enc(cmd, SBA_CMD_LOAD_BUFFER, 725 + SBA_CMD_SHIFT, SBA_CMD_MASK); 726 + cmdsp->cmd = cmd; 727 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 728 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 729 + cmdsp->data = src[0] + msg_offset; 730 + cmdsp->data_len = msg_len; 731 + cmdsp++; 732 + 733 + /* Type-B commands to xor data with buf0 and put it back in buf0 */ 734 + for (i = 1; i < src_cnt; i++) { 735 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 736 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 737 + cmd = sba_cmd_enc(cmd, msg_len, 738 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 739 + c_mdata = sba_cmd_xor_c_mdata(0, 0); 740 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 741 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 742 + cmd = sba_cmd_enc(cmd, SBA_CMD_XOR, 743 + SBA_CMD_SHIFT, SBA_CMD_MASK); 744 + cmdsp->cmd = cmd; 745 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 746 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 747 + cmdsp->data = src[i] + msg_offset; 748 + cmdsp->data_len = msg_len; 749 + cmdsp++; 750 + } 751 + 752 + /* Type-A command to write buf0 */ 753 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 754 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 755 + cmd = sba_cmd_enc(cmd, msg_len, 756 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 757 + cmd = sba_cmd_enc(cmd, 0x1, 758 + SBA_RESP_SHIFT, SBA_RESP_MASK); 759 + c_mdata = sba_cmd_write_c_mdata(0); 760 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 761 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 762 + cmd = sba_cmd_enc(cmd, SBA_CMD_WRITE_BUFFER, 763 + SBA_CMD_SHIFT, SBA_CMD_MASK); 764 + cmdsp->cmd = cmd; 765 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 766 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 767 + if (req->sba->hw_resp_size) { 768 + cmdsp->flags |= BRCM_SBA_CMD_HAS_RESP; 769 + cmdsp->resp = req->resp_dma; 770 + cmdsp->resp_len = req->sba->hw_resp_size; 771 + } 772 + cmdsp->flags |= BRCM_SBA_CMD_HAS_OUTPUT; 773 + cmdsp->data = dst + msg_offset; 774 + cmdsp->data_len = msg_len; 775 + cmdsp++; 776 + 777 + /* Fillup brcm_message */ 778 + msg->type = BRCM_MESSAGE_SBA; 779 + msg->sba.cmds = cmds; 780 + msg->sba.cmds_count = cmdsp - cmds; 781 + msg->ctx = req; 782 + msg->error = 0; 783 + } 784 + 785 + struct sba_request * 786 + sba_prep_dma_xor_req(struct sba_device *sba, 787 + dma_addr_t off, dma_addr_t dst, dma_addr_t *src, 788 + u32 src_cnt, size_t len, unsigned long flags) 789 + { 790 + struct sba_request *req = NULL; 791 + 792 + /* Alloc new request */ 793 + req = sba_alloc_request(sba); 794 + if (!req) 795 + return NULL; 796 + req->fence = (flags & DMA_PREP_FENCE) ? true : false; 797 + 798 + /* Fillup request message */ 799 + sba_fillup_xor_msg(req, req->cmds, &req->msg, 800 + off, len, dst, src, src_cnt); 801 + 802 + /* Init async_tx descriptor */ 803 + req->tx.flags = flags; 804 + req->tx.cookie = -EBUSY; 805 + 806 + return req; 807 + } 808 + 809 + static struct dma_async_tx_descriptor * 810 + sba_prep_dma_xor(struct dma_chan *dchan, dma_addr_t dst, dma_addr_t *src, 811 + u32 src_cnt, size_t len, unsigned long flags) 812 + { 813 + size_t req_len; 814 + dma_addr_t off = 0; 815 + struct sba_device *sba = to_sba_device(dchan); 816 + struct sba_request *first = NULL, *req; 817 + 818 + /* Sanity checks */ 819 + if (unlikely(src_cnt > sba->max_xor_srcs)) 820 + return NULL; 821 + 822 + /* Create chained requests where each request is upto hw_buf_size */ 823 + while (len) { 824 + req_len = (len < sba->hw_buf_size) ? len : sba->hw_buf_size; 825 + 826 + req = sba_prep_dma_xor_req(sba, off, dst, src, src_cnt, 827 + req_len, flags); 828 + if (!req) { 829 + if (first) 830 + sba_free_chained_requests(first); 831 + return NULL; 832 + } 833 + 834 + if (first) 835 + sba_chain_request(first, req); 836 + else 837 + first = req; 838 + 839 + off += req_len; 840 + len -= req_len; 841 + } 842 + 843 + return (first) ? &first->tx : NULL; 844 + } 845 + 846 + static void sba_fillup_pq_msg(struct sba_request *req, 847 + bool pq_continue, 848 + struct brcm_sba_command *cmds, 849 + struct brcm_message *msg, 850 + dma_addr_t msg_offset, size_t msg_len, 851 + dma_addr_t *dst_p, dma_addr_t *dst_q, 852 + const u8 *scf, dma_addr_t *src, u32 src_cnt) 853 + { 854 + u64 cmd; 855 + u32 c_mdata; 856 + unsigned int i; 857 + struct brcm_sba_command *cmdsp = cmds; 858 + 859 + if (pq_continue) { 860 + /* Type-B command to load old P into buf0 */ 861 + if (dst_p) { 862 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 863 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 864 + cmd = sba_cmd_enc(cmd, msg_len, 865 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 866 + c_mdata = sba_cmd_load_c_mdata(0); 867 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 868 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 869 + cmd = sba_cmd_enc(cmd, SBA_CMD_LOAD_BUFFER, 870 + SBA_CMD_SHIFT, SBA_CMD_MASK); 871 + cmdsp->cmd = cmd; 872 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 873 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 874 + cmdsp->data = *dst_p + msg_offset; 875 + cmdsp->data_len = msg_len; 876 + cmdsp++; 877 + } 878 + 879 + /* Type-B command to load old Q into buf1 */ 880 + if (dst_q) { 881 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 882 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 883 + cmd = sba_cmd_enc(cmd, msg_len, 884 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 885 + c_mdata = sba_cmd_load_c_mdata(1); 886 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 887 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 888 + cmd = sba_cmd_enc(cmd, SBA_CMD_LOAD_BUFFER, 889 + SBA_CMD_SHIFT, SBA_CMD_MASK); 890 + cmdsp->cmd = cmd; 891 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 892 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 893 + cmdsp->data = *dst_q + msg_offset; 894 + cmdsp->data_len = msg_len; 895 + cmdsp++; 896 + } 897 + } else { 898 + /* Type-A command to zero all buffers */ 899 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 900 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 901 + cmd = sba_cmd_enc(cmd, msg_len, 902 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 903 + cmd = sba_cmd_enc(cmd, SBA_CMD_ZERO_ALL_BUFFERS, 904 + SBA_CMD_SHIFT, SBA_CMD_MASK); 905 + cmdsp->cmd = cmd; 906 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 907 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 908 + cmdsp++; 909 + } 910 + 911 + /* Type-B commands for generate P onto buf0 and Q onto buf1 */ 912 + for (i = 0; i < src_cnt; i++) { 913 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 914 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 915 + cmd = sba_cmd_enc(cmd, msg_len, 916 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 917 + c_mdata = sba_cmd_pq_c_mdata(raid6_gflog[scf[i]], 1, 0); 918 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 919 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 920 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_MS(c_mdata), 921 + SBA_C_MDATA_MS_SHIFT, SBA_C_MDATA_MS_MASK); 922 + cmd = sba_cmd_enc(cmd, SBA_CMD_GALOIS_XOR, 923 + SBA_CMD_SHIFT, SBA_CMD_MASK); 924 + cmdsp->cmd = cmd; 925 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 926 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 927 + cmdsp->data = src[i] + msg_offset; 928 + cmdsp->data_len = msg_len; 929 + cmdsp++; 930 + } 931 + 932 + /* Type-A command to write buf0 */ 933 + if (dst_p) { 934 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 935 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 936 + cmd = sba_cmd_enc(cmd, msg_len, 937 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 938 + cmd = sba_cmd_enc(cmd, 0x1, 939 + SBA_RESP_SHIFT, SBA_RESP_MASK); 940 + c_mdata = sba_cmd_write_c_mdata(0); 941 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 942 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 943 + cmd = sba_cmd_enc(cmd, SBA_CMD_WRITE_BUFFER, 944 + SBA_CMD_SHIFT, SBA_CMD_MASK); 945 + cmdsp->cmd = cmd; 946 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 947 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 948 + if (req->sba->hw_resp_size) { 949 + cmdsp->flags |= BRCM_SBA_CMD_HAS_RESP; 950 + cmdsp->resp = req->resp_dma; 951 + cmdsp->resp_len = req->sba->hw_resp_size; 952 + } 953 + cmdsp->flags |= BRCM_SBA_CMD_HAS_OUTPUT; 954 + cmdsp->data = *dst_p + msg_offset; 955 + cmdsp->data_len = msg_len; 956 + cmdsp++; 957 + } 958 + 959 + /* Type-A command to write buf1 */ 960 + if (dst_q) { 961 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 962 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 963 + cmd = sba_cmd_enc(cmd, msg_len, 964 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 965 + cmd = sba_cmd_enc(cmd, 0x1, 966 + SBA_RESP_SHIFT, SBA_RESP_MASK); 967 + c_mdata = sba_cmd_write_c_mdata(1); 968 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 969 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 970 + cmd = sba_cmd_enc(cmd, SBA_CMD_WRITE_BUFFER, 971 + SBA_CMD_SHIFT, SBA_CMD_MASK); 972 + cmdsp->cmd = cmd; 973 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 974 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 975 + if (req->sba->hw_resp_size) { 976 + cmdsp->flags |= BRCM_SBA_CMD_HAS_RESP; 977 + cmdsp->resp = req->resp_dma; 978 + cmdsp->resp_len = req->sba->hw_resp_size; 979 + } 980 + cmdsp->flags |= BRCM_SBA_CMD_HAS_OUTPUT; 981 + cmdsp->data = *dst_q + msg_offset; 982 + cmdsp->data_len = msg_len; 983 + cmdsp++; 984 + } 985 + 986 + /* Fillup brcm_message */ 987 + msg->type = BRCM_MESSAGE_SBA; 988 + msg->sba.cmds = cmds; 989 + msg->sba.cmds_count = cmdsp - cmds; 990 + msg->ctx = req; 991 + msg->error = 0; 992 + } 993 + 994 + struct sba_request * 995 + sba_prep_dma_pq_req(struct sba_device *sba, dma_addr_t off, 996 + dma_addr_t *dst_p, dma_addr_t *dst_q, dma_addr_t *src, 997 + u32 src_cnt, const u8 *scf, size_t len, unsigned long flags) 998 + { 999 + struct sba_request *req = NULL; 1000 + 1001 + /* Alloc new request */ 1002 + req = sba_alloc_request(sba); 1003 + if (!req) 1004 + return NULL; 1005 + req->fence = (flags & DMA_PREP_FENCE) ? true : false; 1006 + 1007 + /* Fillup request messages */ 1008 + sba_fillup_pq_msg(req, dmaf_continue(flags), 1009 + req->cmds, &req->msg, 1010 + off, len, dst_p, dst_q, scf, src, src_cnt); 1011 + 1012 + /* Init async_tx descriptor */ 1013 + req->tx.flags = flags; 1014 + req->tx.cookie = -EBUSY; 1015 + 1016 + return req; 1017 + } 1018 + 1019 + static void sba_fillup_pq_single_msg(struct sba_request *req, 1020 + bool pq_continue, 1021 + struct brcm_sba_command *cmds, 1022 + struct brcm_message *msg, 1023 + dma_addr_t msg_offset, size_t msg_len, 1024 + dma_addr_t *dst_p, dma_addr_t *dst_q, 1025 + dma_addr_t src, u8 scf) 1026 + { 1027 + u64 cmd; 1028 + u32 c_mdata; 1029 + u8 pos, dpos = raid6_gflog[scf]; 1030 + struct brcm_sba_command *cmdsp = cmds; 1031 + 1032 + if (!dst_p) 1033 + goto skip_p; 1034 + 1035 + if (pq_continue) { 1036 + /* Type-B command to load old P into buf0 */ 1037 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 1038 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 1039 + cmd = sba_cmd_enc(cmd, msg_len, 1040 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 1041 + c_mdata = sba_cmd_load_c_mdata(0); 1042 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 1043 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 1044 + cmd = sba_cmd_enc(cmd, SBA_CMD_LOAD_BUFFER, 1045 + SBA_CMD_SHIFT, SBA_CMD_MASK); 1046 + cmdsp->cmd = cmd; 1047 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 1048 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 1049 + cmdsp->data = *dst_p + msg_offset; 1050 + cmdsp->data_len = msg_len; 1051 + cmdsp++; 1052 + 1053 + /* 1054 + * Type-B commands to xor data with buf0 and put it 1055 + * back in buf0 1056 + */ 1057 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 1058 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 1059 + cmd = sba_cmd_enc(cmd, msg_len, 1060 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 1061 + c_mdata = sba_cmd_xor_c_mdata(0, 0); 1062 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 1063 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 1064 + cmd = sba_cmd_enc(cmd, SBA_CMD_XOR, 1065 + SBA_CMD_SHIFT, SBA_CMD_MASK); 1066 + cmdsp->cmd = cmd; 1067 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 1068 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 1069 + cmdsp->data = src + msg_offset; 1070 + cmdsp->data_len = msg_len; 1071 + cmdsp++; 1072 + } else { 1073 + /* Type-B command to load old P into buf0 */ 1074 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 1075 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 1076 + cmd = sba_cmd_enc(cmd, msg_len, 1077 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 1078 + c_mdata = sba_cmd_load_c_mdata(0); 1079 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 1080 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 1081 + cmd = sba_cmd_enc(cmd, SBA_CMD_LOAD_BUFFER, 1082 + SBA_CMD_SHIFT, SBA_CMD_MASK); 1083 + cmdsp->cmd = cmd; 1084 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 1085 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 1086 + cmdsp->data = src + msg_offset; 1087 + cmdsp->data_len = msg_len; 1088 + cmdsp++; 1089 + } 1090 + 1091 + /* Type-A command to write buf0 */ 1092 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 1093 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 1094 + cmd = sba_cmd_enc(cmd, msg_len, 1095 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 1096 + cmd = sba_cmd_enc(cmd, 0x1, 1097 + SBA_RESP_SHIFT, SBA_RESP_MASK); 1098 + c_mdata = sba_cmd_write_c_mdata(0); 1099 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 1100 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 1101 + cmd = sba_cmd_enc(cmd, SBA_CMD_WRITE_BUFFER, 1102 + SBA_CMD_SHIFT, SBA_CMD_MASK); 1103 + cmdsp->cmd = cmd; 1104 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 1105 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 1106 + if (req->sba->hw_resp_size) { 1107 + cmdsp->flags |= BRCM_SBA_CMD_HAS_RESP; 1108 + cmdsp->resp = req->resp_dma; 1109 + cmdsp->resp_len = req->sba->hw_resp_size; 1110 + } 1111 + cmdsp->flags |= BRCM_SBA_CMD_HAS_OUTPUT; 1112 + cmdsp->data = *dst_p + msg_offset; 1113 + cmdsp->data_len = msg_len; 1114 + cmdsp++; 1115 + 1116 + skip_p: 1117 + if (!dst_q) 1118 + goto skip_q; 1119 + 1120 + /* Type-A command to zero all buffers */ 1121 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 1122 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 1123 + cmd = sba_cmd_enc(cmd, msg_len, 1124 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 1125 + cmd = sba_cmd_enc(cmd, SBA_CMD_ZERO_ALL_BUFFERS, 1126 + SBA_CMD_SHIFT, SBA_CMD_MASK); 1127 + cmdsp->cmd = cmd; 1128 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 1129 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 1130 + cmdsp++; 1131 + 1132 + if (dpos == 255) 1133 + goto skip_q_computation; 1134 + pos = (dpos < req->sba->max_pq_coefs) ? 1135 + dpos : (req->sba->max_pq_coefs - 1); 1136 + 1137 + /* 1138 + * Type-B command to generate initial Q from data 1139 + * and store output into buf0 1140 + */ 1141 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 1142 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 1143 + cmd = sba_cmd_enc(cmd, msg_len, 1144 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 1145 + c_mdata = sba_cmd_pq_c_mdata(pos, 0, 0); 1146 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 1147 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 1148 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_MS(c_mdata), 1149 + SBA_C_MDATA_MS_SHIFT, SBA_C_MDATA_MS_MASK); 1150 + cmd = sba_cmd_enc(cmd, SBA_CMD_GALOIS, 1151 + SBA_CMD_SHIFT, SBA_CMD_MASK); 1152 + cmdsp->cmd = cmd; 1153 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 1154 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 1155 + cmdsp->data = src + msg_offset; 1156 + cmdsp->data_len = msg_len; 1157 + cmdsp++; 1158 + 1159 + dpos -= pos; 1160 + 1161 + /* Multiple Type-A command to generate final Q */ 1162 + while (dpos) { 1163 + pos = (dpos < req->sba->max_pq_coefs) ? 1164 + dpos : (req->sba->max_pq_coefs - 1); 1165 + 1166 + /* 1167 + * Type-A command to generate Q with buf0 and 1168 + * buf1 store result in buf0 1169 + */ 1170 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 1171 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 1172 + cmd = sba_cmd_enc(cmd, msg_len, 1173 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 1174 + c_mdata = sba_cmd_pq_c_mdata(pos, 0, 1); 1175 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 1176 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 1177 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_MS(c_mdata), 1178 + SBA_C_MDATA_MS_SHIFT, SBA_C_MDATA_MS_MASK); 1179 + cmd = sba_cmd_enc(cmd, SBA_CMD_GALOIS, 1180 + SBA_CMD_SHIFT, SBA_CMD_MASK); 1181 + cmdsp->cmd = cmd; 1182 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 1183 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 1184 + cmdsp++; 1185 + 1186 + dpos -= pos; 1187 + } 1188 + 1189 + skip_q_computation: 1190 + if (pq_continue) { 1191 + /* 1192 + * Type-B command to XOR previous output with 1193 + * buf0 and write it into buf0 1194 + */ 1195 + cmd = sba_cmd_enc(0x0, SBA_TYPE_B, 1196 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 1197 + cmd = sba_cmd_enc(cmd, msg_len, 1198 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 1199 + c_mdata = sba_cmd_xor_c_mdata(0, 0); 1200 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 1201 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 1202 + cmd = sba_cmd_enc(cmd, SBA_CMD_XOR, 1203 + SBA_CMD_SHIFT, SBA_CMD_MASK); 1204 + cmdsp->cmd = cmd; 1205 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 1206 + cmdsp->flags = BRCM_SBA_CMD_TYPE_B; 1207 + cmdsp->data = *dst_q + msg_offset; 1208 + cmdsp->data_len = msg_len; 1209 + cmdsp++; 1210 + } 1211 + 1212 + /* Type-A command to write buf0 */ 1213 + cmd = sba_cmd_enc(0x0, SBA_TYPE_A, 1214 + SBA_TYPE_SHIFT, SBA_TYPE_MASK); 1215 + cmd = sba_cmd_enc(cmd, msg_len, 1216 + SBA_USER_DEF_SHIFT, SBA_USER_DEF_MASK); 1217 + cmd = sba_cmd_enc(cmd, 0x1, 1218 + SBA_RESP_SHIFT, SBA_RESP_MASK); 1219 + c_mdata = sba_cmd_write_c_mdata(0); 1220 + cmd = sba_cmd_enc(cmd, SBA_C_MDATA_LS(c_mdata), 1221 + SBA_C_MDATA_SHIFT, SBA_C_MDATA_MASK); 1222 + cmd = sba_cmd_enc(cmd, SBA_CMD_WRITE_BUFFER, 1223 + SBA_CMD_SHIFT, SBA_CMD_MASK); 1224 + cmdsp->cmd = cmd; 1225 + *cmdsp->cmd_dma = cpu_to_le64(cmd); 1226 + cmdsp->flags = BRCM_SBA_CMD_TYPE_A; 1227 + if (req->sba->hw_resp_size) { 1228 + cmdsp->flags |= BRCM_SBA_CMD_HAS_RESP; 1229 + cmdsp->resp = req->resp_dma; 1230 + cmdsp->resp_len = req->sba->hw_resp_size; 1231 + } 1232 + cmdsp->flags |= BRCM_SBA_CMD_HAS_OUTPUT; 1233 + cmdsp->data = *dst_q + msg_offset; 1234 + cmdsp->data_len = msg_len; 1235 + cmdsp++; 1236 + 1237 + skip_q: 1238 + /* Fillup brcm_message */ 1239 + msg->type = BRCM_MESSAGE_SBA; 1240 + msg->sba.cmds = cmds; 1241 + msg->sba.cmds_count = cmdsp - cmds; 1242 + msg->ctx = req; 1243 + msg->error = 0; 1244 + } 1245 + 1246 + struct sba_request * 1247 + sba_prep_dma_pq_single_req(struct sba_device *sba, dma_addr_t off, 1248 + dma_addr_t *dst_p, dma_addr_t *dst_q, 1249 + dma_addr_t src, u8 scf, size_t len, 1250 + unsigned long flags) 1251 + { 1252 + struct sba_request *req = NULL; 1253 + 1254 + /* Alloc new request */ 1255 + req = sba_alloc_request(sba); 1256 + if (!req) 1257 + return NULL; 1258 + req->fence = (flags & DMA_PREP_FENCE) ? true : false; 1259 + 1260 + /* Fillup request messages */ 1261 + sba_fillup_pq_single_msg(req, dmaf_continue(flags), 1262 + req->cmds, &req->msg, off, len, 1263 + dst_p, dst_q, src, scf); 1264 + 1265 + /* Init async_tx descriptor */ 1266 + req->tx.flags = flags; 1267 + req->tx.cookie = -EBUSY; 1268 + 1269 + return req; 1270 + } 1271 + 1272 + static struct dma_async_tx_descriptor * 1273 + sba_prep_dma_pq(struct dma_chan *dchan, dma_addr_t *dst, dma_addr_t *src, 1274 + u32 src_cnt, const u8 *scf, size_t len, unsigned long flags) 1275 + { 1276 + u32 i, dst_q_index; 1277 + size_t req_len; 1278 + bool slow = false; 1279 + dma_addr_t off = 0; 1280 + dma_addr_t *dst_p = NULL, *dst_q = NULL; 1281 + struct sba_device *sba = to_sba_device(dchan); 1282 + struct sba_request *first = NULL, *req; 1283 + 1284 + /* Sanity checks */ 1285 + if (unlikely(src_cnt > sba->max_pq_srcs)) 1286 + return NULL; 1287 + for (i = 0; i < src_cnt; i++) 1288 + if (sba->max_pq_coefs <= raid6_gflog[scf[i]]) 1289 + slow = true; 1290 + 1291 + /* Figure-out P and Q destination addresses */ 1292 + if (!(flags & DMA_PREP_PQ_DISABLE_P)) 1293 + dst_p = &dst[0]; 1294 + if (!(flags & DMA_PREP_PQ_DISABLE_Q)) 1295 + dst_q = &dst[1]; 1296 + 1297 + /* Create chained requests where each request is upto hw_buf_size */ 1298 + while (len) { 1299 + req_len = (len < sba->hw_buf_size) ? len : sba->hw_buf_size; 1300 + 1301 + if (slow) { 1302 + dst_q_index = src_cnt; 1303 + 1304 + if (dst_q) { 1305 + for (i = 0; i < src_cnt; i++) { 1306 + if (*dst_q == src[i]) { 1307 + dst_q_index = i; 1308 + break; 1309 + } 1310 + } 1311 + } 1312 + 1313 + if (dst_q_index < src_cnt) { 1314 + i = dst_q_index; 1315 + req = sba_prep_dma_pq_single_req(sba, 1316 + off, dst_p, dst_q, src[i], scf[i], 1317 + req_len, flags | DMA_PREP_FENCE); 1318 + if (!req) 1319 + goto fail; 1320 + 1321 + if (first) 1322 + sba_chain_request(first, req); 1323 + else 1324 + first = req; 1325 + 1326 + flags |= DMA_PREP_CONTINUE; 1327 + } 1328 + 1329 + for (i = 0; i < src_cnt; i++) { 1330 + if (dst_q_index == i) 1331 + continue; 1332 + 1333 + req = sba_prep_dma_pq_single_req(sba, 1334 + off, dst_p, dst_q, src[i], scf[i], 1335 + req_len, flags | DMA_PREP_FENCE); 1336 + if (!req) 1337 + goto fail; 1338 + 1339 + if (first) 1340 + sba_chain_request(first, req); 1341 + else 1342 + first = req; 1343 + 1344 + flags |= DMA_PREP_CONTINUE; 1345 + } 1346 + } else { 1347 + req = sba_prep_dma_pq_req(sba, off, 1348 + dst_p, dst_q, src, src_cnt, 1349 + scf, req_len, flags); 1350 + if (!req) 1351 + goto fail; 1352 + 1353 + if (first) 1354 + sba_chain_request(first, req); 1355 + else 1356 + first = req; 1357 + } 1358 + 1359 + off += req_len; 1360 + len -= req_len; 1361 + } 1362 + 1363 + return (first) ? &first->tx : NULL; 1364 + 1365 + fail: 1366 + if (first) 1367 + sba_free_chained_requests(first); 1368 + return NULL; 1369 + } 1370 + 1371 + /* ====== Mailbox callbacks ===== */ 1372 + 1373 + static void sba_dma_tx_actions(struct sba_request *req) 1374 + { 1375 + struct dma_async_tx_descriptor *tx = &req->tx; 1376 + 1377 + WARN_ON(tx->cookie < 0); 1378 + 1379 + if (tx->cookie > 0) { 1380 + dma_cookie_complete(tx); 1381 + 1382 + /* 1383 + * Call the callback (must not sleep or submit new 1384 + * operations to this channel) 1385 + */ 1386 + if (tx->callback) 1387 + tx->callback(tx->callback_param); 1388 + 1389 + dma_descriptor_unmap(tx); 1390 + } 1391 + 1392 + /* Run dependent operations */ 1393 + dma_run_dependencies(tx); 1394 + 1395 + /* If waiting for 'ack' then move to completed list */ 1396 + if (!async_tx_test_ack(&req->tx)) 1397 + sba_complete_chained_requests(req); 1398 + else 1399 + sba_free_chained_requests(req); 1400 + } 1401 + 1402 + static void sba_receive_message(struct mbox_client *cl, void *msg) 1403 + { 1404 + unsigned long flags; 1405 + struct brcm_message *m = msg; 1406 + struct sba_request *req = m->ctx, *req1; 1407 + struct sba_device *sba = req->sba; 1408 + 1409 + /* Error count if message has error */ 1410 + if (m->error < 0) 1411 + dev_err(sba->dev, "%s got message with error %d", 1412 + dma_chan_name(&sba->dma_chan), m->error); 1413 + 1414 + /* Mark request as received */ 1415 + sba_received_request(req); 1416 + 1417 + /* Wait for all chained requests to be completed */ 1418 + if (atomic_dec_return(&req->first->next_pending_count)) 1419 + goto done; 1420 + 1421 + /* Point to first request */ 1422 + req = req->first; 1423 + 1424 + /* Update request */ 1425 + if (req->state == SBA_REQUEST_STATE_RECEIVED) 1426 + sba_dma_tx_actions(req); 1427 + else 1428 + sba_free_chained_requests(req); 1429 + 1430 + spin_lock_irqsave(&sba->reqs_lock, flags); 1431 + 1432 + /* Re-check all completed request waiting for 'ack' */ 1433 + list_for_each_entry_safe(req, req1, &sba->reqs_completed_list, node) { 1434 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 1435 + sba_dma_tx_actions(req); 1436 + spin_lock_irqsave(&sba->reqs_lock, flags); 1437 + } 1438 + 1439 + spin_unlock_irqrestore(&sba->reqs_lock, flags); 1440 + 1441 + done: 1442 + /* Try to submit pending request */ 1443 + sba_issue_pending(&sba->dma_chan); 1444 + } 1445 + 1446 + /* ====== Platform driver routines ===== */ 1447 + 1448 + static int sba_prealloc_channel_resources(struct sba_device *sba) 1449 + { 1450 + int i, j, p, ret = 0; 1451 + struct sba_request *req = NULL; 1452 + 1453 + sba->resp_base = dma_alloc_coherent(sba->dma_dev.dev, 1454 + sba->max_resp_pool_size, 1455 + &sba->resp_dma_base, GFP_KERNEL); 1456 + if (!sba->resp_base) 1457 + return -ENOMEM; 1458 + 1459 + sba->cmds_base = dma_alloc_coherent(sba->dma_dev.dev, 1460 + sba->max_cmds_pool_size, 1461 + &sba->cmds_dma_base, GFP_KERNEL); 1462 + if (!sba->cmds_base) { 1463 + ret = -ENOMEM; 1464 + goto fail_free_resp_pool; 1465 + } 1466 + 1467 + spin_lock_init(&sba->reqs_lock); 1468 + sba->reqs_fence = false; 1469 + INIT_LIST_HEAD(&sba->reqs_alloc_list); 1470 + INIT_LIST_HEAD(&sba->reqs_pending_list); 1471 + INIT_LIST_HEAD(&sba->reqs_active_list); 1472 + INIT_LIST_HEAD(&sba->reqs_received_list); 1473 + INIT_LIST_HEAD(&sba->reqs_completed_list); 1474 + INIT_LIST_HEAD(&sba->reqs_aborted_list); 1475 + INIT_LIST_HEAD(&sba->reqs_free_list); 1476 + 1477 + sba->reqs = devm_kcalloc(sba->dev, sba->max_req, 1478 + sizeof(*req), GFP_KERNEL); 1479 + if (!sba->reqs) { 1480 + ret = -ENOMEM; 1481 + goto fail_free_cmds_pool; 1482 + } 1483 + 1484 + for (i = 0, p = 0; i < sba->max_req; i++) { 1485 + req = &sba->reqs[i]; 1486 + INIT_LIST_HEAD(&req->node); 1487 + req->sba = sba; 1488 + req->state = SBA_REQUEST_STATE_FREE; 1489 + INIT_LIST_HEAD(&req->next); 1490 + req->next_count = 1; 1491 + atomic_set(&req->next_pending_count, 0); 1492 + req->fence = false; 1493 + req->resp = sba->resp_base + p; 1494 + req->resp_dma = sba->resp_dma_base + p; 1495 + p += sba->hw_resp_size; 1496 + req->cmds = devm_kcalloc(sba->dev, sba->max_cmd_per_req, 1497 + sizeof(*req->cmds), GFP_KERNEL); 1498 + if (!req->cmds) { 1499 + ret = -ENOMEM; 1500 + goto fail_free_cmds_pool; 1501 + } 1502 + for (j = 0; j < sba->max_cmd_per_req; j++) { 1503 + req->cmds[j].cmd = 0; 1504 + req->cmds[j].cmd_dma = sba->cmds_base + 1505 + (i * sba->max_cmd_per_req + j) * sizeof(u64); 1506 + req->cmds[j].cmd_dma_addr = sba->cmds_dma_base + 1507 + (i * sba->max_cmd_per_req + j) * sizeof(u64); 1508 + req->cmds[j].flags = 0; 1509 + } 1510 + memset(&req->msg, 0, sizeof(req->msg)); 1511 + dma_async_tx_descriptor_init(&req->tx, &sba->dma_chan); 1512 + req->tx.tx_submit = sba_tx_submit; 1513 + req->tx.phys = req->resp_dma; 1514 + list_add_tail(&req->node, &sba->reqs_free_list); 1515 + } 1516 + 1517 + sba->reqs_free_count = sba->max_req; 1518 + 1519 + return 0; 1520 + 1521 + fail_free_cmds_pool: 1522 + dma_free_coherent(sba->dma_dev.dev, 1523 + sba->max_cmds_pool_size, 1524 + sba->cmds_base, sba->cmds_dma_base); 1525 + fail_free_resp_pool: 1526 + dma_free_coherent(sba->dma_dev.dev, 1527 + sba->max_resp_pool_size, 1528 + sba->resp_base, sba->resp_dma_base); 1529 + return ret; 1530 + } 1531 + 1532 + static void sba_freeup_channel_resources(struct sba_device *sba) 1533 + { 1534 + dmaengine_terminate_all(&sba->dma_chan); 1535 + dma_free_coherent(sba->dma_dev.dev, sba->max_cmds_pool_size, 1536 + sba->cmds_base, sba->cmds_dma_base); 1537 + dma_free_coherent(sba->dma_dev.dev, sba->max_resp_pool_size, 1538 + sba->resp_base, sba->resp_dma_base); 1539 + sba->resp_base = NULL; 1540 + sba->resp_dma_base = 0; 1541 + } 1542 + 1543 + static int sba_async_register(struct sba_device *sba) 1544 + { 1545 + int ret; 1546 + struct dma_device *dma_dev = &sba->dma_dev; 1547 + 1548 + /* Initialize DMA channel cookie */ 1549 + sba->dma_chan.device = dma_dev; 1550 + dma_cookie_init(&sba->dma_chan); 1551 + 1552 + /* Initialize DMA device capability mask */ 1553 + dma_cap_zero(dma_dev->cap_mask); 1554 + dma_cap_set(DMA_INTERRUPT, dma_dev->cap_mask); 1555 + dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); 1556 + dma_cap_set(DMA_XOR, dma_dev->cap_mask); 1557 + dma_cap_set(DMA_PQ, dma_dev->cap_mask); 1558 + 1559 + /* 1560 + * Set mailbox channel device as the base device of 1561 + * our dma_device because the actual memory accesses 1562 + * will be done by mailbox controller 1563 + */ 1564 + dma_dev->dev = sba->mbox_dev; 1565 + 1566 + /* Set base prep routines */ 1567 + dma_dev->device_free_chan_resources = sba_free_chan_resources; 1568 + dma_dev->device_terminate_all = sba_device_terminate_all; 1569 + dma_dev->device_issue_pending = sba_issue_pending; 1570 + dma_dev->device_tx_status = sba_tx_status; 1571 + 1572 + /* Set interrupt routine */ 1573 + if (dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask)) 1574 + dma_dev->device_prep_dma_interrupt = sba_prep_dma_interrupt; 1575 + 1576 + /* Set memcpy routine */ 1577 + if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) 1578 + dma_dev->device_prep_dma_memcpy = sba_prep_dma_memcpy; 1579 + 1580 + /* Set xor routine and capability */ 1581 + if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) { 1582 + dma_dev->device_prep_dma_xor = sba_prep_dma_xor; 1583 + dma_dev->max_xor = sba->max_xor_srcs; 1584 + } 1585 + 1586 + /* Set pq routine and capability */ 1587 + if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) { 1588 + dma_dev->device_prep_dma_pq = sba_prep_dma_pq; 1589 + dma_set_maxpq(dma_dev, sba->max_pq_srcs, 0); 1590 + } 1591 + 1592 + /* Initialize DMA device channel list */ 1593 + INIT_LIST_HEAD(&dma_dev->channels); 1594 + list_add_tail(&sba->dma_chan.device_node, &dma_dev->channels); 1595 + 1596 + /* Register with Linux async DMA framework*/ 1597 + ret = dma_async_device_register(dma_dev); 1598 + if (ret) { 1599 + dev_err(sba->dev, "async device register error %d", ret); 1600 + return ret; 1601 + } 1602 + 1603 + dev_info(sba->dev, "%s capabilities: %s%s%s%s\n", 1604 + dma_chan_name(&sba->dma_chan), 1605 + dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "interrupt " : "", 1606 + dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "memcpy " : "", 1607 + dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "", 1608 + dma_has_cap(DMA_PQ, dma_dev->cap_mask) ? "pq " : ""); 1609 + 1610 + return 0; 1611 + } 1612 + 1613 + static int sba_probe(struct platform_device *pdev) 1614 + { 1615 + int i, ret = 0, mchans_count; 1616 + struct sba_device *sba; 1617 + struct platform_device *mbox_pdev; 1618 + struct of_phandle_args args; 1619 + 1620 + /* Allocate main SBA struct */ 1621 + sba = devm_kzalloc(&pdev->dev, sizeof(*sba), GFP_KERNEL); 1622 + if (!sba) 1623 + return -ENOMEM; 1624 + 1625 + sba->dev = &pdev->dev; 1626 + platform_set_drvdata(pdev, sba); 1627 + 1628 + /* Determine SBA version from DT compatible string */ 1629 + if (of_device_is_compatible(sba->dev->of_node, "brcm,iproc-sba")) 1630 + sba->ver = SBA_VER_1; 1631 + else if (of_device_is_compatible(sba->dev->of_node, 1632 + "brcm,iproc-sba-v2")) 1633 + sba->ver = SBA_VER_2; 1634 + else 1635 + return -ENODEV; 1636 + 1637 + /* Derived Configuration parameters */ 1638 + switch (sba->ver) { 1639 + case SBA_VER_1: 1640 + sba->max_req = 1024; 1641 + sba->hw_buf_size = 4096; 1642 + sba->hw_resp_size = 8; 1643 + sba->max_pq_coefs = 6; 1644 + sba->max_pq_srcs = 6; 1645 + break; 1646 + case SBA_VER_2: 1647 + sba->max_req = 1024; 1648 + sba->hw_buf_size = 4096; 1649 + sba->hw_resp_size = 8; 1650 + sba->max_pq_coefs = 30; 1651 + /* 1652 + * We can support max_pq_srcs == max_pq_coefs because 1653 + * we are limited by number of SBA commands that we can 1654 + * fit in one message for underlying ring manager HW. 1655 + */ 1656 + sba->max_pq_srcs = 12; 1657 + break; 1658 + default: 1659 + return -EINVAL; 1660 + } 1661 + sba->max_cmd_per_req = sba->max_pq_srcs + 3; 1662 + sba->max_xor_srcs = sba->max_cmd_per_req - 1; 1663 + sba->max_resp_pool_size = sba->max_req * sba->hw_resp_size; 1664 + sba->max_cmds_pool_size = sba->max_req * 1665 + sba->max_cmd_per_req * sizeof(u64); 1666 + 1667 + /* Setup mailbox client */ 1668 + sba->client.dev = &pdev->dev; 1669 + sba->client.rx_callback = sba_receive_message; 1670 + sba->client.tx_block = false; 1671 + sba->client.knows_txdone = false; 1672 + sba->client.tx_tout = 0; 1673 + 1674 + /* Number of channels equals number of mailbox channels */ 1675 + ret = of_count_phandle_with_args(pdev->dev.of_node, 1676 + "mboxes", "#mbox-cells"); 1677 + if (ret <= 0) 1678 + return -ENODEV; 1679 + mchans_count = ret; 1680 + sba->mchans_count = 0; 1681 + atomic_set(&sba->mchans_current, 0); 1682 + 1683 + /* Allocate mailbox channel array */ 1684 + sba->mchans = devm_kcalloc(&pdev->dev, sba->mchans_count, 1685 + sizeof(*sba->mchans), GFP_KERNEL); 1686 + if (!sba->mchans) 1687 + return -ENOMEM; 1688 + 1689 + /* Request mailbox channels */ 1690 + for (i = 0; i < mchans_count; i++) { 1691 + sba->mchans[i] = mbox_request_channel(&sba->client, i); 1692 + if (IS_ERR(sba->mchans[i])) { 1693 + ret = PTR_ERR(sba->mchans[i]); 1694 + goto fail_free_mchans; 1695 + } 1696 + sba->mchans_count++; 1697 + } 1698 + 1699 + /* Find-out underlying mailbox device */ 1700 + ret = of_parse_phandle_with_args(pdev->dev.of_node, 1701 + "mboxes", "#mbox-cells", 0, &args); 1702 + if (ret) 1703 + goto fail_free_mchans; 1704 + mbox_pdev = of_find_device_by_node(args.np); 1705 + of_node_put(args.np); 1706 + if (!mbox_pdev) { 1707 + ret = -ENODEV; 1708 + goto fail_free_mchans; 1709 + } 1710 + sba->mbox_dev = &mbox_pdev->dev; 1711 + 1712 + /* All mailbox channels should be of same ring manager device */ 1713 + for (i = 1; i < mchans_count; i++) { 1714 + ret = of_parse_phandle_with_args(pdev->dev.of_node, 1715 + "mboxes", "#mbox-cells", i, &args); 1716 + if (ret) 1717 + goto fail_free_mchans; 1718 + mbox_pdev = of_find_device_by_node(args.np); 1719 + of_node_put(args.np); 1720 + if (sba->mbox_dev != &mbox_pdev->dev) { 1721 + ret = -EINVAL; 1722 + goto fail_free_mchans; 1723 + } 1724 + } 1725 + 1726 + /* Register DMA device with linux async framework */ 1727 + ret = sba_async_register(sba); 1728 + if (ret) 1729 + goto fail_free_mchans; 1730 + 1731 + /* Prealloc channel resource */ 1732 + ret = sba_prealloc_channel_resources(sba); 1733 + if (ret) 1734 + goto fail_async_dev_unreg; 1735 + 1736 + /* Print device info */ 1737 + dev_info(sba->dev, "%s using SBAv%d and %d mailbox channels", 1738 + dma_chan_name(&sba->dma_chan), sba->ver+1, 1739 + sba->mchans_count); 1740 + 1741 + return 0; 1742 + 1743 + fail_async_dev_unreg: 1744 + dma_async_device_unregister(&sba->dma_dev); 1745 + fail_free_mchans: 1746 + for (i = 0; i < sba->mchans_count; i++) 1747 + mbox_free_channel(sba->mchans[i]); 1748 + return ret; 1749 + } 1750 + 1751 + static int sba_remove(struct platform_device *pdev) 1752 + { 1753 + int i; 1754 + struct sba_device *sba = platform_get_drvdata(pdev); 1755 + 1756 + sba_freeup_channel_resources(sba); 1757 + 1758 + dma_async_device_unregister(&sba->dma_dev); 1759 + 1760 + for (i = 0; i < sba->mchans_count; i++) 1761 + mbox_free_channel(sba->mchans[i]); 1762 + 1763 + return 0; 1764 + } 1765 + 1766 + static const struct of_device_id sba_of_match[] = { 1767 + { .compatible = "brcm,iproc-sba", }, 1768 + { .compatible = "brcm,iproc-sba-v2", }, 1769 + {}, 1770 + }; 1771 + MODULE_DEVICE_TABLE(of, sba_of_match); 1772 + 1773 + static struct platform_driver sba_driver = { 1774 + .probe = sba_probe, 1775 + .remove = sba_remove, 1776 + .driver = { 1777 + .name = "bcm-sba-raid", 1778 + .of_match_table = sba_of_match, 1779 + }, 1780 + }; 1781 + module_platform_driver(sba_driver); 1782 + 1783 + MODULE_DESCRIPTION("Broadcom SBA RAID driver"); 1784 + MODULE_AUTHOR("Anup Patel <anup.patel@broadcom.com>"); 1785 + MODULE_LICENSE("GPL v2");
+5 -1
drivers/dma/dw/platform.c
··· 306 306 { 307 307 struct platform_device *pdev = to_platform_device(dev); 308 308 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 309 + int ret; 309 310 310 - clk_prepare_enable(chip->clk); 311 + ret = clk_prepare_enable(chip->clk); 312 + if (ret) 313 + return ret; 314 + 311 315 return dw_dma_enable(chip); 312 316 } 313 317
+1 -1
drivers/dma/fsl_raid.c
··· 877 877 return 0; 878 878 } 879 879 880 - static struct of_device_id fsl_re_ids[] = { 880 + static const struct of_device_id fsl_re_ids[] = { 881 881 { .compatible = "fsl,raideng-v1.0", }, 882 882 {} 883 883 };
+4 -1
drivers/dma/fsldma.c
··· 269 269 case 2: 270 270 case 4: 271 271 case 8: 272 + mode &= ~FSL_DMA_MR_SAHTS_MASK; 272 273 mode |= FSL_DMA_MR_SAHE | (__ilog2(size) << 14); 273 274 break; 274 275 } ··· 302 301 case 2: 303 302 case 4: 304 303 case 8: 304 + mode &= ~FSL_DMA_MR_DAHTS_MASK; 305 305 mode |= FSL_DMA_MR_DAHE | (__ilog2(size) << 16); 306 306 break; 307 307 } ··· 329 327 BUG_ON(size > 1024); 330 328 331 329 mode = get_mr(chan); 332 - mode |= (__ilog2(size) << 24) & 0x0f000000; 330 + mode &= ~FSL_DMA_MR_BWC_MASK; 331 + mode |= (__ilog2(size) << 24) & FSL_DMA_MR_BWC_MASK; 333 332 334 333 set_mr(chan, mode); 335 334 }
+4
drivers/dma/fsldma.h
··· 36 36 #define FSL_DMA_MR_DAHE 0x00002000 37 37 #define FSL_DMA_MR_SAHE 0x00001000 38 38 39 + #define FSL_DMA_MR_SAHTS_MASK 0x0000C000 40 + #define FSL_DMA_MR_DAHTS_MASK 0x00030000 41 + #define FSL_DMA_MR_BWC_MASK 0x0f000000 42 + 39 43 /* 40 44 * Bandwidth/pause control determines how many bytes a given 41 45 * channel is allowed to transfer before the DMA engine pauses
+2 -5
drivers/dma/imx-dma.c
··· 888 888 sg_init_table(imxdmac->sg_list, periods); 889 889 890 890 for (i = 0; i < periods; i++) { 891 - imxdmac->sg_list[i].page_link = 0; 891 + sg_assign_page(&imxdmac->sg_list[i], NULL); 892 892 imxdmac->sg_list[i].offset = 0; 893 893 imxdmac->sg_list[i].dma_address = dma_addr; 894 894 sg_dma_len(&imxdmac->sg_list[i]) = period_len; ··· 896 896 } 897 897 898 898 /* close the loop */ 899 - imxdmac->sg_list[periods].offset = 0; 900 - sg_dma_len(&imxdmac->sg_list[periods]) = 0; 901 - imxdmac->sg_list[periods].page_link = 902 - ((unsigned long)imxdmac->sg_list | 0x01) & ~0x02; 899 + sg_chain(imxdmac->sg_list, periods + 1, imxdmac->sg_list); 903 900 904 901 desc->type = IMXDMA_DESC_CYCLIC; 905 902 desc->sg = imxdmac->sg_list;
+20 -7
drivers/dma/imx-sdma.c
··· 1323 1323 } 1324 1324 1325 1325 if (period_len > 0xffff) { 1326 - dev_err(sdma->dev, "SDMA channel %d: maximum period size exceeded: %d > %d\n", 1326 + dev_err(sdma->dev, "SDMA channel %d: maximum period size exceeded: %zu > %d\n", 1327 1327 channel, period_len, 0xffff); 1328 1328 goto err_out; 1329 1329 } ··· 1347 1347 if (i + 1 == num_periods) 1348 1348 param |= BD_WRAP; 1349 1349 1350 - dev_dbg(sdma->dev, "entry %d: count: %d dma: %#llx %s%s\n", 1350 + dev_dbg(sdma->dev, "entry %d: count: %zu dma: %#llx %s%s\n", 1351 1351 i, period_len, (u64)dma_addr, 1352 1352 param & BD_WRAP ? "wrap" : "", 1353 1353 param & BD_INTR ? " intr" : ""); ··· 1755 1755 if (IS_ERR(sdma->clk_ahb)) 1756 1756 return PTR_ERR(sdma->clk_ahb); 1757 1757 1758 - clk_prepare(sdma->clk_ipg); 1759 - clk_prepare(sdma->clk_ahb); 1758 + ret = clk_prepare(sdma->clk_ipg); 1759 + if (ret) 1760 + return ret; 1761 + 1762 + ret = clk_prepare(sdma->clk_ahb); 1763 + if (ret) 1764 + goto err_clk; 1760 1765 1761 1766 ret = devm_request_irq(&pdev->dev, irq, sdma_int_handler, 0, "sdma", 1762 1767 sdma); 1763 1768 if (ret) 1764 - return ret; 1769 + goto err_irq; 1765 1770 1766 1771 sdma->irq = irq; 1767 1772 1768 1773 sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL); 1769 - if (!sdma->script_addrs) 1770 - return -ENOMEM; 1774 + if (!sdma->script_addrs) { 1775 + ret = -ENOMEM; 1776 + goto err_irq; 1777 + } 1771 1778 1772 1779 /* initially no scripts available */ 1773 1780 saddr_arr = (s32 *)sdma->script_addrs; ··· 1889 1882 dma_async_device_unregister(&sdma->dma_device); 1890 1883 err_init: 1891 1884 kfree(sdma->script_addrs); 1885 + err_irq: 1886 + clk_unprepare(sdma->clk_ahb); 1887 + err_clk: 1888 + clk_unprepare(sdma->clk_ipg); 1892 1889 return ret; 1893 1890 } 1894 1891 ··· 1904 1893 devm_free_irq(&pdev->dev, sdma->irq, sdma); 1905 1894 dma_async_device_unregister(&sdma->dma_device); 1906 1895 kfree(sdma->script_addrs); 1896 + clk_unprepare(sdma->clk_ahb); 1897 + clk_unprepare(sdma->clk_ipg); 1907 1898 /* Kill the tasklet */ 1908 1899 for (i = 0; i < MAX_DMA_CHANNELS; i++) { 1909 1900 struct sdma_channel *sdmac = &sdma->channel[i];
+4 -4
drivers/dma/ioat/dca.c
··· 336 336 } 337 337 338 338 if (dca3_tag_map_invalid(ioatdca->tag_map)) { 339 - WARN_TAINT_ONCE(1, TAINT_FIRMWARE_WORKAROUND, 340 - "%s %s: APICID_TAG_MAP set incorrectly by BIOS, disabling DCA\n", 341 - dev_driver_string(&pdev->dev), 342 - dev_name(&pdev->dev)); 339 + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); 340 + pr_warn_once("%s %s: APICID_TAG_MAP set incorrectly by BIOS, disabling DCA\n", 341 + dev_driver_string(&pdev->dev), 342 + dev_name(&pdev->dev)); 343 343 free_dca_provider(dca); 344 344 return NULL; 345 345 }
+59 -3
drivers/dma/mv_xor_v2.c
··· 42 42 #define MV_XOR_V2_DMA_IMSG_THRD_OFF 0x018 43 43 #define MV_XOR_V2_DMA_IMSG_THRD_MASK 0x7FFF 44 44 #define MV_XOR_V2_DMA_IMSG_THRD_SHIFT 0x0 45 + #define MV_XOR_V2_DMA_IMSG_TIMER_EN BIT(18) 45 46 #define MV_XOR_V2_DMA_DESQ_AWATTR_OFF 0x01C 46 47 /* Same flags as MV_XOR_V2_DMA_DESQ_ARATTR_OFF */ 47 48 #define MV_XOR_V2_DMA_DESQ_ALLOC_OFF 0x04C ··· 56 55 #define MV_XOR_V2_DMA_DESQ_STOP_OFF 0x800 57 56 #define MV_XOR_V2_DMA_DESQ_DEALLOC_OFF 0x804 58 57 #define MV_XOR_V2_DMA_DESQ_ADD_OFF 0x808 58 + #define MV_XOR_V2_DMA_IMSG_TMOT 0x810 59 + #define MV_XOR_V2_DMA_IMSG_TIMER_THRD_MASK 0x1FFF 60 + #define MV_XOR_V2_DMA_IMSG_TIMER_THRD_SHIFT 0 59 61 60 62 /* XOR Global registers */ 61 63 #define MV_XOR_V2_GLOB_BW_CTRL 0x4 ··· 93 89 * sufficient to reach a good level of performance. 94 90 */ 95 91 #define MV_XOR_V2_DESC_NUM 1024 92 + 93 + /* 94 + * Threshold values for descriptors and timeout, determined by 95 + * experimentation as giving a good level of performance. 96 + */ 97 + #define MV_XOR_V2_DONE_IMSG_THRD 0x14 98 + #define MV_XOR_V2_TIMER_THRD 0xB0 96 99 97 100 /** 98 101 * struct mv_xor_v2_descriptor - DMA HW descriptor ··· 255 244 xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_CTRL_OFF); 256 245 257 246 return MV_XOR_V2_EXT_DESC_SIZE; 247 + } 248 + 249 + /* 250 + * Set the IMSG threshold 251 + */ 252 + static inline 253 + void mv_xor_v2_enable_imsg_thrd(struct mv_xor_v2_device *xor_dev) 254 + { 255 + u32 reg; 256 + 257 + /* Configure threshold of number of descriptors, and enable timer */ 258 + reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF); 259 + reg &= (~MV_XOR_V2_DMA_IMSG_THRD_MASK << MV_XOR_V2_DMA_IMSG_THRD_SHIFT); 260 + reg |= (MV_XOR_V2_DONE_IMSG_THRD << MV_XOR_V2_DMA_IMSG_THRD_SHIFT); 261 + reg |= MV_XOR_V2_DMA_IMSG_TIMER_EN; 262 + writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF); 263 + 264 + /* Configure Timer Threshold */ 265 + reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_TMOT); 266 + reg &= (~MV_XOR_V2_DMA_IMSG_TIMER_THRD_MASK << 267 + MV_XOR_V2_DMA_IMSG_TIMER_THRD_SHIFT); 268 + reg |= (MV_XOR_V2_TIMER_THRD << MV_XOR_V2_DMA_IMSG_TIMER_THRD_SHIFT); 269 + writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_TMOT); 258 270 } 259 271 260 272 static irqreturn_t mv_xor_v2_interrupt_handler(int irq, void *data) ··· 535 501 mv_xor_v2_add_desc_to_desq(xor_dev, xor_dev->npendings); 536 502 xor_dev->npendings = 0; 537 503 538 - /* Activate the channel */ 539 - writel(0, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_STOP_OFF); 540 - 541 504 spin_unlock_bh(&xor_dev->lock); 542 505 } 543 506 ··· 696 665 return 0; 697 666 } 698 667 668 + static int mv_xor_v2_suspend(struct platform_device *dev, pm_message_t state) 669 + { 670 + struct mv_xor_v2_device *xor_dev = platform_get_drvdata(dev); 671 + 672 + /* Set this bit to disable to stop the XOR unit. */ 673 + writel(0x1, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_STOP_OFF); 674 + 675 + return 0; 676 + } 677 + 678 + static int mv_xor_v2_resume(struct platform_device *dev) 679 + { 680 + struct mv_xor_v2_device *xor_dev = platform_get_drvdata(dev); 681 + 682 + mv_xor_v2_set_desc_size(xor_dev); 683 + mv_xor_v2_enable_imsg_thrd(xor_dev); 684 + mv_xor_v2_descq_init(xor_dev); 685 + 686 + return 0; 687 + } 688 + 699 689 static int mv_xor_v2_probe(struct platform_device *pdev) 700 690 { 701 691 struct mv_xor_v2_device *xor_dev; ··· 847 795 list_add_tail(&xor_dev->dmachan.device_node, 848 796 &dma_dev->channels); 849 797 798 + mv_xor_v2_enable_imsg_thrd(xor_dev); 799 + 850 800 mv_xor_v2_descq_init(xor_dev); 851 801 852 802 ret = dma_async_device_register(dma_dev); ··· 898 844 899 845 static struct platform_driver mv_xor_v2_driver = { 900 846 .probe = mv_xor_v2_probe, 847 + .suspend = mv_xor_v2_suspend, 848 + .resume = mv_xor_v2_resume, 901 849 .remove = mv_xor_v2_remove, 902 850 .driver = { 903 851 .name = "mv_xor_v2",
+1 -1
drivers/dma/mxs-dma.c
··· 617 617 618 618 if (period_len > MAX_XFER_BYTES) { 619 619 dev_err(mxs_dma->dma_device.dev, 620 - "maximum period size exceeded: %d > %d\n", 620 + "maximum period size exceeded: %zu > %d\n", 621 621 period_len, MAX_XFER_BYTES); 622 622 goto err_out; 623 623 }
+66 -76
drivers/dma/pl330.c
··· 443 443 /* For D-to-M and M-to-D channels */ 444 444 int burst_sz; /* the peripheral fifo width */ 445 445 int burst_len; /* the number of burst */ 446 - dma_addr_t fifo_addr; 446 + phys_addr_t fifo_addr; 447 + /* DMA-mapped view of the FIFO; may differ if an IOMMU is present */ 448 + dma_addr_t fifo_dma; 449 + enum dma_data_direction dir; 447 450 448 451 /* for cyclic capability */ 449 452 bool cyclic; ··· 541 538 struct dma_pl330_desc *desc; 542 539 }; 543 540 544 - static inline bool _queue_empty(struct pl330_thread *thrd) 545 - { 546 - return thrd->req[0].desc == NULL && thrd->req[1].desc == NULL; 547 - } 548 - 549 541 static inline bool _queue_full(struct pl330_thread *thrd) 550 542 { 551 543 return thrd->req[0].desc != NULL && thrd->req[1].desc != NULL; ··· 560 562 static inline u32 get_revision(u32 periph_id) 561 563 { 562 564 return (periph_id >> PERIPH_REV_SHIFT) & PERIPH_REV_MASK; 563 - } 564 - 565 - static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[], 566 - enum pl330_dst da, u16 val) 567 - { 568 - if (dry_run) 569 - return SZ_DMAADDH; 570 - 571 - buf[0] = CMD_DMAADDH; 572 - buf[0] |= (da << 1); 573 - buf[1] = val; 574 - buf[2] = val >> 8; 575 - 576 - PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n", 577 - da == 1 ? "DA" : "SA", val); 578 - 579 - return SZ_DMAADDH; 580 565 } 581 566 582 567 static inline u32 _emit_END(unsigned dry_run, u8 buf[]) ··· 719 738 return SZ_DMAMOV; 720 739 } 721 740 722 - static inline u32 _emit_NOP(unsigned dry_run, u8 buf[]) 723 - { 724 - if (dry_run) 725 - return SZ_DMANOP; 726 - 727 - buf[0] = CMD_DMANOP; 728 - 729 - PL330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n"); 730 - 731 - return SZ_DMANOP; 732 - } 733 - 734 741 static inline u32 _emit_RMB(unsigned dry_run, u8 buf[]) 735 742 { 736 743 if (dry_run) ··· 784 815 cond == SINGLE ? 'S' : 'B', peri >> 3); 785 816 786 817 return SZ_DMASTP; 787 - } 788 - 789 - static inline u32 _emit_STZ(unsigned dry_run, u8 buf[]) 790 - { 791 - if (dry_run) 792 - return SZ_DMASTZ; 793 - 794 - buf[0] = CMD_DMASTZ; 795 - 796 - PL330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n"); 797 - 798 - return SZ_DMASTZ; 799 - } 800 - 801 - static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev, 802 - unsigned invalidate) 803 - { 804 - if (dry_run) 805 - return SZ_DMAWFE; 806 - 807 - buf[0] = CMD_DMAWFE; 808 - 809 - ev &= 0x1f; 810 - ev <<= 3; 811 - buf[1] = ev; 812 - 813 - if (invalidate) 814 - buf[1] |= (1 << 1); 815 - 816 - PL330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n", 817 - ev >> 3, invalidate ? ", I" : ""); 818 - 819 - return SZ_DMAWFE; 820 818 } 821 819 822 820 static inline u32 _emit_WFP(unsigned dry_run, u8 buf[], ··· 2056 2120 return 1; 2057 2121 } 2058 2122 2123 + /* 2124 + * We need the data direction between the DMAC (the dma-mapping "device") and 2125 + * the FIFO (the dmaengine "dev"), from the FIFO's point of view. Confusing! 2126 + */ 2127 + static enum dma_data_direction 2128 + pl330_dma_slave_map_dir(enum dma_transfer_direction dir) 2129 + { 2130 + switch (dir) { 2131 + case DMA_MEM_TO_DEV: 2132 + return DMA_FROM_DEVICE; 2133 + case DMA_DEV_TO_MEM: 2134 + return DMA_TO_DEVICE; 2135 + case DMA_DEV_TO_DEV: 2136 + return DMA_BIDIRECTIONAL; 2137 + default: 2138 + return DMA_NONE; 2139 + } 2140 + } 2141 + 2142 + static void pl330_unprep_slave_fifo(struct dma_pl330_chan *pch) 2143 + { 2144 + if (pch->dir != DMA_NONE) 2145 + dma_unmap_resource(pch->chan.device->dev, pch->fifo_dma, 2146 + 1 << pch->burst_sz, pch->dir, 0); 2147 + pch->dir = DMA_NONE; 2148 + } 2149 + 2150 + 2151 + static bool pl330_prep_slave_fifo(struct dma_pl330_chan *pch, 2152 + enum dma_transfer_direction dir) 2153 + { 2154 + struct device *dev = pch->chan.device->dev; 2155 + enum dma_data_direction dma_dir = pl330_dma_slave_map_dir(dir); 2156 + 2157 + /* Already mapped for this config? */ 2158 + if (pch->dir == dma_dir) 2159 + return true; 2160 + 2161 + pl330_unprep_slave_fifo(pch); 2162 + pch->fifo_dma = dma_map_resource(dev, pch->fifo_addr, 2163 + 1 << pch->burst_sz, dma_dir, 0); 2164 + if (dma_mapping_error(dev, pch->fifo_dma)) 2165 + return false; 2166 + 2167 + pch->dir = dma_dir; 2168 + return true; 2169 + } 2170 + 2059 2171 static int pl330_config(struct dma_chan *chan, 2060 2172 struct dma_slave_config *slave_config) 2061 2173 { 2062 2174 struct dma_pl330_chan *pch = to_pchan(chan); 2063 2175 2176 + pl330_unprep_slave_fifo(pch); 2064 2177 if (slave_config->direction == DMA_MEM_TO_DEV) { 2065 2178 if (slave_config->dst_addr) 2066 2179 pch->fifo_addr = slave_config->dst_addr; ··· 2220 2235 spin_unlock_irqrestore(&pl330->lock, flags); 2221 2236 pm_runtime_mark_last_busy(pch->dmac->ddma.dev); 2222 2237 pm_runtime_put_autosuspend(pch->dmac->ddma.dev); 2238 + pl330_unprep_slave_fifo(pch); 2223 2239 } 2224 2240 2225 2241 static int pl330_get_current_xferred_count(struct dma_pl330_chan *pch, ··· 2550 2564 return NULL; 2551 2565 } 2552 2566 2567 + if (!pl330_prep_slave_fifo(pch, direction)) 2568 + return NULL; 2569 + 2553 2570 for (i = 0; i < len / period_len; i++) { 2554 2571 desc = pl330_get_desc(pch); 2555 2572 if (!desc) { ··· 2582 2593 desc->rqcfg.src_inc = 1; 2583 2594 desc->rqcfg.dst_inc = 0; 2584 2595 src = dma_addr; 2585 - dst = pch->fifo_addr; 2596 + dst = pch->fifo_dma; 2586 2597 break; 2587 2598 case DMA_DEV_TO_MEM: 2588 2599 desc->rqcfg.src_inc = 0; 2589 2600 desc->rqcfg.dst_inc = 1; 2590 - src = pch->fifo_addr; 2601 + src = pch->fifo_dma; 2591 2602 dst = dma_addr; 2592 2603 break; 2593 2604 default: ··· 2700 2711 struct dma_pl330_chan *pch = to_pchan(chan); 2701 2712 struct scatterlist *sg; 2702 2713 int i; 2703 - dma_addr_t addr; 2704 2714 2705 2715 if (unlikely(!pch || !sgl || !sg_len)) 2706 2716 return NULL; 2707 2717 2708 - addr = pch->fifo_addr; 2718 + if (!pl330_prep_slave_fifo(pch, direction)) 2719 + return NULL; 2709 2720 2710 2721 first = NULL; 2711 2722 ··· 2731 2742 if (direction == DMA_MEM_TO_DEV) { 2732 2743 desc->rqcfg.src_inc = 1; 2733 2744 desc->rqcfg.dst_inc = 0; 2734 - fill_px(&desc->px, 2735 - addr, sg_dma_address(sg), sg_dma_len(sg)); 2745 + fill_px(&desc->px, pch->fifo_dma, sg_dma_address(sg), 2746 + sg_dma_len(sg)); 2736 2747 } else { 2737 2748 desc->rqcfg.src_inc = 0; 2738 2749 desc->rqcfg.dst_inc = 1; 2739 - fill_px(&desc->px, 2740 - sg_dma_address(sg), addr, sg_dma_len(sg)); 2750 + fill_px(&desc->px, sg_dma_address(sg), pch->fifo_dma, 2751 + sg_dma_len(sg)); 2741 2752 } 2742 2753 2743 2754 desc->rqcfg.brst_size = pch->burst_sz; ··· 2895 2906 pch->thread = NULL; 2896 2907 pch->chan.device = pd; 2897 2908 pch->dmac = pl330; 2909 + pch->dir = DMA_NONE; 2898 2910 2899 2911 /* Add the channel to the DMAC list */ 2900 2912 list_add_tail(&pch->chan.device_node, &pd->channels);
+17 -5
drivers/dma/qcom/hidma.c
··· 1 1 /* 2 2 * Qualcomm Technologies HIDMA DMA engine interface 3 3 * 4 - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify 7 7 * it under the terms of the GNU General Public License version 2 and ··· 210 210 INIT_LIST_HEAD(&mchan->prepared); 211 211 INIT_LIST_HEAD(&mchan->active); 212 212 INIT_LIST_HEAD(&mchan->completed); 213 + INIT_LIST_HEAD(&mchan->queued); 213 214 214 215 spin_lock_init(&mchan->lock); 215 216 list_add_tail(&mchan->chan.device_node, &ddev->channels); ··· 231 230 struct hidma_chan *mchan = to_hidma_chan(dmach); 232 231 struct hidma_dev *dmadev = mchan->dmadev; 233 232 unsigned long flags; 233 + struct hidma_desc *qdesc, *next; 234 234 int status; 235 235 236 236 spin_lock_irqsave(&mchan->lock, flags); 237 + list_for_each_entry_safe(qdesc, next, &mchan->queued, node) { 238 + hidma_ll_queue_request(dmadev->lldev, qdesc->tre_ch); 239 + list_move_tail(&qdesc->node, &mchan->active); 240 + } 241 + 237 242 if (!mchan->running) { 238 243 struct hidma_desc *desc = list_first_entry(&mchan->active, 239 244 struct hidma_desc, ··· 322 315 pm_runtime_put_autosuspend(dmadev->ddev.dev); 323 316 return -ENODEV; 324 317 } 318 + pm_runtime_mark_last_busy(dmadev->ddev.dev); 319 + pm_runtime_put_autosuspend(dmadev->ddev.dev); 325 320 326 321 mdesc = container_of(txd, struct hidma_desc, desc); 327 322 spin_lock_irqsave(&mchan->lock, irqflags); 328 323 329 - /* Move descriptor to active */ 330 - list_move_tail(&mdesc->node, &mchan->active); 324 + /* Move descriptor to queued */ 325 + list_move_tail(&mdesc->node, &mchan->queued); 331 326 332 327 /* Update cookie */ 333 328 cookie = dma_cookie_assign(txd); 334 329 335 - hidma_ll_queue_request(dmadev->lldev, mdesc->tre_ch); 336 330 spin_unlock_irqrestore(&mchan->lock, irqflags); 337 331 338 332 return cookie; ··· 439 431 list_splice_init(&mchan->active, &list); 440 432 list_splice_init(&mchan->prepared, &list); 441 433 list_splice_init(&mchan->completed, &list); 434 + list_splice_init(&mchan->queued, &list); 442 435 spin_unlock_irqrestore(&mchan->lock, irqflags); 443 436 444 437 /* this suspends the existing transfer */ ··· 804 795 device_property_read_u32(&pdev->dev, "desc-count", 805 796 &dmadev->nr_descriptors); 806 797 807 - if (!dmadev->nr_descriptors && nr_desc_prm) 798 + if (nr_desc_prm) { 799 + dev_info(&pdev->dev, "overriding number of descriptors as %d\n", 800 + nr_desc_prm); 808 801 dmadev->nr_descriptors = nr_desc_prm; 802 + } 809 803 810 804 if (!dmadev->nr_descriptors) 811 805 dmadev->nr_descriptors = HIDMA_NR_DEFAULT_DESC;
+1
drivers/dma/qcom/hidma.h
··· 104 104 struct dma_chan chan; 105 105 struct list_head free; 106 106 struct list_head prepared; 107 + struct list_head queued; 107 108 struct list_head active; 108 109 struct list_head completed; 109 110
+46 -1
drivers/dma/qcom/hidma_mgmt.c
··· 1 1 /* 2 2 * Qualcomm Technologies HIDMA DMA engine Management interface 3 3 * 4 - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify 7 7 * it under the terms of the GNU General Public License version 2 and ··· 48 48 49 49 #define HIDMA_AUTOSUSPEND_TIMEOUT 2000 50 50 #define HIDMA_MAX_CHANNEL_WEIGHT 15 51 + 52 + static unsigned int max_write_request; 53 + module_param(max_write_request, uint, 0644); 54 + MODULE_PARM_DESC(max_write_request, 55 + "maximum write burst (default: ACPI/DT value)"); 56 + 57 + static unsigned int max_read_request; 58 + module_param(max_read_request, uint, 0644); 59 + MODULE_PARM_DESC(max_read_request, 60 + "maximum read burst (default: ACPI/DT value)"); 61 + 62 + static unsigned int max_wr_xactions; 63 + module_param(max_wr_xactions, uint, 0644); 64 + MODULE_PARM_DESC(max_wr_xactions, 65 + "maximum number of write transactions (default: ACPI/DT value)"); 66 + 67 + static unsigned int max_rd_xactions; 68 + module_param(max_rd_xactions, uint, 0644); 69 + MODULE_PARM_DESC(max_rd_xactions, 70 + "maximum number of read transactions (default: ACPI/DT value)"); 51 71 52 72 int hidma_mgmt_setup(struct hidma_mgmt_dev *mgmtdev) 53 73 { ··· 227 207 goto out; 228 208 } 229 209 210 + if (max_write_request) { 211 + dev_info(&pdev->dev, "overriding max-write-burst-bytes: %d\n", 212 + max_write_request); 213 + mgmtdev->max_write_request = max_write_request; 214 + } else 215 + max_write_request = mgmtdev->max_write_request; 216 + 230 217 rc = device_property_read_u32(&pdev->dev, "max-read-burst-bytes", 231 218 &mgmtdev->max_read_request); 232 219 if (rc) { 233 220 dev_err(&pdev->dev, "max-read-burst-bytes missing\n"); 234 221 goto out; 235 222 } 223 + if (max_read_request) { 224 + dev_info(&pdev->dev, "overriding max-read-burst-bytes: %d\n", 225 + max_read_request); 226 + mgmtdev->max_read_request = max_read_request; 227 + } else 228 + max_read_request = mgmtdev->max_read_request; 236 229 237 230 rc = device_property_read_u32(&pdev->dev, "max-write-transactions", 238 231 &mgmtdev->max_wr_xactions); ··· 253 220 dev_err(&pdev->dev, "max-write-transactions missing\n"); 254 221 goto out; 255 222 } 223 + if (max_wr_xactions) { 224 + dev_info(&pdev->dev, "overriding max-write-transactions: %d\n", 225 + max_wr_xactions); 226 + mgmtdev->max_wr_xactions = max_wr_xactions; 227 + } else 228 + max_wr_xactions = mgmtdev->max_wr_xactions; 256 229 257 230 rc = device_property_read_u32(&pdev->dev, "max-read-transactions", 258 231 &mgmtdev->max_rd_xactions); ··· 266 227 dev_err(&pdev->dev, "max-read-transactions missing\n"); 267 228 goto out; 268 229 } 230 + if (max_rd_xactions) { 231 + dev_info(&pdev->dev, "overriding max-read-transactions: %d\n", 232 + max_rd_xactions); 233 + mgmtdev->max_rd_xactions = max_rd_xactions; 234 + } else 235 + max_rd_xactions = mgmtdev->max_rd_xactions; 269 236 270 237 mgmtdev->priority = devm_kcalloc(&pdev->dev, 271 238 mgmtdev->dma_channels,
+21 -6
drivers/dma/sh/rcar-dmac.c
··· 144 144 * @chan: base DMA channel object 145 145 * @iomem: channel I/O memory base 146 146 * @index: index of this channel in the controller 147 + * @irq: channel IRQ 147 148 * @src: slave memory address and size on the source side 148 149 * @dst: slave memory address and size on the destination side 149 150 * @mid_rid: hardware MID/RID for the DMA client using this channel ··· 162 161 struct dma_chan chan; 163 162 void __iomem *iomem; 164 163 unsigned int index; 164 + int irq; 165 165 166 166 struct rcar_dmac_chan_slave src; 167 167 struct rcar_dmac_chan_slave dst; ··· 1010 1008 rcar_dmac_chan_halt(rchan); 1011 1009 spin_unlock_irq(&rchan->lock); 1012 1010 1013 - /* Now no new interrupts will occur */ 1011 + /* 1012 + * Now no new interrupts will occur, but one might already be 1013 + * running. Wait for it to finish before freeing resources. 1014 + */ 1015 + synchronize_irq(rchan->irq); 1014 1016 1015 1017 if (rchan->mid_rid >= 0) { 1016 1018 /* The caller is holding dma_list_mutex */ ··· 1372 1366 spin_unlock_irqrestore(&rchan->lock, flags); 1373 1367 } 1374 1368 1369 + static void rcar_dmac_device_synchronize(struct dma_chan *chan) 1370 + { 1371 + struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan); 1372 + 1373 + synchronize_irq(rchan->irq); 1374 + } 1375 + 1375 1376 /* ----------------------------------------------------------------------------- 1376 1377 * IRQ handling 1377 1378 */ ··· 1663 1650 struct dma_chan *chan = &rchan->chan; 1664 1651 char pdev_irqname[5]; 1665 1652 char *irqname; 1666 - int irq; 1667 1653 int ret; 1668 1654 1669 1655 rchan->index = index; ··· 1679 1667 1680 1668 /* Request the channel interrupt. */ 1681 1669 sprintf(pdev_irqname, "ch%u", index); 1682 - irq = platform_get_irq_byname(pdev, pdev_irqname); 1683 - if (irq < 0) { 1670 + rchan->irq = platform_get_irq_byname(pdev, pdev_irqname); 1671 + if (rchan->irq < 0) { 1684 1672 dev_err(dmac->dev, "no IRQ specified for channel %u\n", index); 1685 1673 return -ENODEV; 1686 1674 } ··· 1690 1678 if (!irqname) 1691 1679 return -ENOMEM; 1692 1680 1693 - ret = devm_request_threaded_irq(dmac->dev, irq, rcar_dmac_isr_channel, 1681 + ret = devm_request_threaded_irq(dmac->dev, rchan->irq, 1682 + rcar_dmac_isr_channel, 1694 1683 rcar_dmac_isr_channel_thread, 0, 1695 1684 irqname, rchan); 1696 1685 if (ret) { 1697 - dev_err(dmac->dev, "failed to request IRQ %u (%d)\n", irq, ret); 1686 + dev_err(dmac->dev, "failed to request IRQ %u (%d)\n", 1687 + rchan->irq, ret); 1698 1688 return ret; 1699 1689 } 1700 1690 ··· 1860 1846 engine->device_terminate_all = rcar_dmac_chan_terminate_all; 1861 1847 engine->device_tx_status = rcar_dmac_tx_status; 1862 1848 engine->device_issue_pending = rcar_dmac_issue_pending; 1849 + engine->device_synchronize = rcar_dmac_device_synchronize; 1863 1850 1864 1851 ret = dma_async_device_register(engine); 1865 1852 if (ret < 0)
+1 -4
drivers/dma/ste_dma40.c
··· 2528 2528 dma_addr += period_len; 2529 2529 } 2530 2530 2531 - sg[periods].offset = 0; 2532 - sg_dma_len(&sg[periods]) = 0; 2533 - sg[periods].page_link = 2534 - ((unsigned long)sg | 0x01) & ~0x02; 2531 + sg_chain(sg, periods + 1, sg); 2535 2532 2536 2533 txd = d40_prep_sg(chan, sg, sg, periods, direction, 2537 2534 DMA_PREP_INTERRUPT);
+10 -40
drivers/dma/tegra20-apb-dma.c
··· 1494 1494 static int tegra_dma_runtime_suspend(struct device *dev) 1495 1495 { 1496 1496 struct tegra_dma *tdma = dev_get_drvdata(dev); 1497 - 1498 - clk_disable_unprepare(tdma->dma_clk); 1499 - return 0; 1500 - } 1501 - 1502 - static int tegra_dma_runtime_resume(struct device *dev) 1503 - { 1504 - struct tegra_dma *tdma = dev_get_drvdata(dev); 1505 - int ret; 1506 - 1507 - ret = clk_prepare_enable(tdma->dma_clk); 1508 - if (ret < 0) { 1509 - dev_err(dev, "clk_enable failed: %d\n", ret); 1510 - return ret; 1511 - } 1512 - return 0; 1513 - } 1514 - 1515 - #ifdef CONFIG_PM_SLEEP 1516 - static int tegra_dma_pm_suspend(struct device *dev) 1517 - { 1518 - struct tegra_dma *tdma = dev_get_drvdata(dev); 1519 1497 int i; 1520 - int ret; 1521 - 1522 - /* Enable clock before accessing register */ 1523 - ret = pm_runtime_get_sync(dev); 1524 - if (ret < 0) 1525 - return ret; 1526 1498 1527 1499 tdma->reg_gen = tdma_read(tdma, TEGRA_APBDMA_GENERAL); 1528 1500 for (i = 0; i < tdma->chip_data->nr_channels; i++) { ··· 1515 1543 TEGRA_APBDMA_CHAN_WCOUNT); 1516 1544 } 1517 1545 1518 - /* Disable clock */ 1519 - pm_runtime_put(dev); 1546 + clk_disable_unprepare(tdma->dma_clk); 1547 + 1520 1548 return 0; 1521 1549 } 1522 1550 1523 - static int tegra_dma_pm_resume(struct device *dev) 1551 + static int tegra_dma_runtime_resume(struct device *dev) 1524 1552 { 1525 1553 struct tegra_dma *tdma = dev_get_drvdata(dev); 1526 - int i; 1527 - int ret; 1554 + int i, ret; 1528 1555 1529 - /* Enable clock before accessing register */ 1530 - ret = pm_runtime_get_sync(dev); 1531 - if (ret < 0) 1556 + ret = clk_prepare_enable(tdma->dma_clk); 1557 + if (ret < 0) { 1558 + dev_err(dev, "clk_enable failed: %d\n", ret); 1532 1559 return ret; 1560 + } 1533 1561 1534 1562 tdma_write(tdma, TEGRA_APBDMA_GENERAL, tdma->reg_gen); 1535 1563 tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); ··· 1554 1582 (ch_reg->csr & ~TEGRA_APBDMA_CSR_ENB)); 1555 1583 } 1556 1584 1557 - /* Disable clock */ 1558 - pm_runtime_put(dev); 1559 1585 return 0; 1560 1586 } 1561 - #endif 1562 1587 1563 1588 static const struct dev_pm_ops tegra_dma_dev_pm_ops = { 1564 1589 SET_RUNTIME_PM_OPS(tegra_dma_runtime_suspend, tegra_dma_runtime_resume, 1565 1590 NULL) 1566 - SET_SYSTEM_SLEEP_PM_OPS(tegra_dma_pm_suspend, tegra_dma_pm_resume) 1591 + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1592 + pm_runtime_force_resume) 1567 1593 }; 1568 1594 1569 1595 static const struct of_device_id tegra_dma_of_match[] = {
-3
drivers/dma/xilinx/zynqmp_dma.c
··· 794 794 795 795 chan = to_chan(dchan); 796 796 797 - if (len > ZYNQMP_DMA_MAX_TRANS_LEN) 798 - return NULL; 799 - 800 797 desc_cnt = DIV_ROUND_UP(len, ZYNQMP_DMA_MAX_TRANS_LEN); 801 798 802 799 spin_lock_bh(&chan->lock);
+93 -12
include/linux/amba/pl080.h
··· 44 44 45 45 #define PL080_SYNC (0x34) 46 46 47 - /* Per channel configuration registers */ 47 + /* The Faraday Technology FTDMAC020 variant registers */ 48 + #define FTDMAC020_CH_BUSY (0x20) 49 + /* Identical to PL080_CONFIG */ 50 + #define FTDMAC020_CSR (0x24) 51 + /* Identical to PL080_SYNC */ 52 + #define FTDMAC020_SYNC (0x2C) 53 + #define FTDMAC020_REVISION (0x30) 54 + #define FTDMAC020_FEATURE (0x34) 48 55 49 56 /* Per channel configuration registers */ 50 57 #define PL080_Cx_BASE(x) ((0x100 + (x * 0x20))) ··· 62 55 #define PL080_CH_CONFIG (0x10) 63 56 #define PL080S_CH_CONTROL2 (0x10) 64 57 #define PL080S_CH_CONFIG (0x14) 58 + /* The Faraday FTDMAC020 derivative shuffles the registers around */ 59 + #define FTDMAC020_CH_CSR (0x00) 60 + #define FTDMAC020_CH_CFG (0x04) 61 + #define FTDMAC020_CH_SRC_ADDR (0x08) 62 + #define FTDMAC020_CH_DST_ADDR (0x0C) 63 + #define FTDMAC020_CH_LLP (0x10) 64 + #define FTDMAC020_CH_SIZE (0x14) 65 65 66 - #define PL080_LLI_ADDR_MASK (0x3fffffff << 2) 66 + #define PL080_LLI_ADDR_MASK GENMASK(31, 2) 67 67 #define PL080_LLI_ADDR_SHIFT (2) 68 68 #define PL080_LLI_LM_AHB2 BIT(0) 69 69 70 70 #define PL080_CONTROL_TC_IRQ_EN BIT(31) 71 - #define PL080_CONTROL_PROT_MASK (0x7 << 28) 71 + #define PL080_CONTROL_PROT_MASK GENMASK(30, 28) 72 72 #define PL080_CONTROL_PROT_SHIFT (28) 73 73 #define PL080_CONTROL_PROT_CACHE BIT(30) 74 74 #define PL080_CONTROL_PROT_BUFF BIT(29) ··· 84 70 #define PL080_CONTROL_SRC_INCR BIT(26) 85 71 #define PL080_CONTROL_DST_AHB2 BIT(25) 86 72 #define PL080_CONTROL_SRC_AHB2 BIT(24) 87 - #define PL080_CONTROL_DWIDTH_MASK (0x7 << 21) 73 + #define PL080_CONTROL_DWIDTH_MASK GENMASK(23, 21) 88 74 #define PL080_CONTROL_DWIDTH_SHIFT (21) 89 - #define PL080_CONTROL_SWIDTH_MASK (0x7 << 18) 75 + #define PL080_CONTROL_SWIDTH_MASK GENMASK(20, 18) 90 76 #define PL080_CONTROL_SWIDTH_SHIFT (18) 91 - #define PL080_CONTROL_DB_SIZE_MASK (0x7 << 15) 77 + #define PL080_CONTROL_DB_SIZE_MASK GENMASK(17, 15) 92 78 #define PL080_CONTROL_DB_SIZE_SHIFT (15) 93 - #define PL080_CONTROL_SB_SIZE_MASK (0x7 << 12) 79 + #define PL080_CONTROL_SB_SIZE_MASK GENMASK(14, 12) 94 80 #define PL080_CONTROL_SB_SIZE_SHIFT (12) 95 - #define PL080_CONTROL_TRANSFER_SIZE_MASK (0xfff << 0) 96 - #define PL080S_CONTROL_TRANSFER_SIZE_MASK (0x1ffffff << 0) 81 + #define PL080_CONTROL_TRANSFER_SIZE_MASK GENMASK(11, 0) 82 + #define PL080S_CONTROL_TRANSFER_SIZE_MASK GENMASK(24, 0) 97 83 #define PL080_CONTROL_TRANSFER_SIZE_SHIFT (0) 98 84 99 85 #define PL080_BSIZE_1 (0x0) ··· 116 102 #define PL080_CONFIG_LOCK BIT(16) 117 103 #define PL080_CONFIG_TC_IRQ_MASK BIT(15) 118 104 #define PL080_CONFIG_ERR_IRQ_MASK BIT(14) 119 - #define PL080_CONFIG_FLOW_CONTROL_MASK (0x7 << 11) 105 + #define PL080_CONFIG_FLOW_CONTROL_MASK GENMASK(13, 11) 120 106 #define PL080_CONFIG_FLOW_CONTROL_SHIFT (11) 121 - #define PL080_CONFIG_DST_SEL_MASK (0xf << 6) 107 + #define PL080_CONFIG_DST_SEL_MASK GENMASK(9, 6) 122 108 #define PL080_CONFIG_DST_SEL_SHIFT (6) 123 - #define PL080_CONFIG_SRC_SEL_MASK (0xf << 1) 109 + #define PL080_CONFIG_SRC_SEL_MASK GENMASK(4, 1) 124 110 #define PL080_CONFIG_SRC_SEL_SHIFT (1) 125 111 #define PL080_CONFIG_ENABLE BIT(0) 126 112 ··· 132 118 #define PL080_FLOW_MEM2PER_PER (0x5) 133 119 #define PL080_FLOW_PER2MEM_PER (0x6) 134 120 #define PL080_FLOW_SRC2DST_SRC (0x7) 121 + 122 + #define FTDMAC020_CH_CSR_TC_MSK BIT(31) 123 + /* Later versions have a threshold in bits 24..26, */ 124 + #define FTDMAC020_CH_CSR_FIFOTH_MSK GENMASK(26, 24) 125 + #define FTDMAC020_CH_CSR_FIFOTH_SHIFT (24) 126 + #define FTDMAC020_CH_CSR_CHPR1_MSK GENMASK(23, 22) 127 + #define FTDMAC020_CH_CSR_PROT3 BIT(21) 128 + #define FTDMAC020_CH_CSR_PROT2 BIT(20) 129 + #define FTDMAC020_CH_CSR_PROT1 BIT(19) 130 + #define FTDMAC020_CH_CSR_SRC_SIZE_MSK GENMASK(18, 16) 131 + #define FTDMAC020_CH_CSR_SRC_SIZE_SHIFT (16) 132 + #define FTDMAC020_CH_CSR_ABT BIT(15) 133 + #define FTDMAC020_CH_CSR_SRC_WIDTH_MSK GENMASK(13, 11) 134 + #define FTDMAC020_CH_CSR_SRC_WIDTH_SHIFT (11) 135 + #define FTDMAC020_CH_CSR_DST_WIDTH_MSK GENMASK(10, 8) 136 + #define FTDMAC020_CH_CSR_DST_WIDTH_SHIFT (8) 137 + #define FTDMAC020_CH_CSR_MODE BIT(7) 138 + /* 00 = increase, 01 = decrease, 10 = fix */ 139 + #define FTDMAC020_CH_CSR_SRCAD_CTL_MSK GENMASK(6, 5) 140 + #define FTDMAC020_CH_CSR_SRCAD_CTL_SHIFT (5) 141 + #define FTDMAC020_CH_CSR_DSTAD_CTL_MSK GENMASK(4, 3) 142 + #define FTDMAC020_CH_CSR_DSTAD_CTL_SHIFT (3) 143 + #define FTDMAC020_CH_CSR_SRC_SEL BIT(2) 144 + #define FTDMAC020_CH_CSR_DST_SEL BIT(1) 145 + #define FTDMAC020_CH_CSR_EN BIT(0) 146 + 147 + /* FIFO threshold setting */ 148 + #define FTDMAC020_CH_CSR_FIFOTH_1 (0x0) 149 + #define FTDMAC020_CH_CSR_FIFOTH_2 (0x1) 150 + #define FTDMAC020_CH_CSR_FIFOTH_4 (0x2) 151 + #define FTDMAC020_CH_CSR_FIFOTH_8 (0x3) 152 + #define FTDMAC020_CH_CSR_FIFOTH_16 (0x4) 153 + /* The FTDMAC020 supports 64bit wide transfers */ 154 + #define FTDMAC020_WIDTH_64BIT (0x3) 155 + /* Address can be increased, decreased or fixed */ 156 + #define FTDMAC020_CH_CSR_SRCAD_CTL_INC (0x0) 157 + #define FTDMAC020_CH_CSR_SRCAD_CTL_DEC (0x1) 158 + #define FTDMAC020_CH_CSR_SRCAD_CTL_FIXED (0x2) 159 + 160 + #define FTDMAC020_CH_CFG_LLP_CNT_MASK GENMASK(19, 16) 161 + #define FTDMAC020_CH_CFG_LLP_CNT_SHIFT (16) 162 + #define FTDMAC020_CH_CFG_BUSY BIT(8) 163 + #define FTDMAC020_CH_CFG_INT_ABT_MASK BIT(2) 164 + #define FTDMAC020_CH_CFG_INT_ERR_MASK BIT(1) 165 + #define FTDMAC020_CH_CFG_INT_TC_MASK BIT(0) 166 + 167 + /* Inside the LLIs, the applicable CSR fields are mapped differently */ 168 + #define FTDMAC020_LLI_TC_MSK BIT(28) 169 + #define FTDMAC020_LLI_SRC_WIDTH_MSK GENMASK(27, 25) 170 + #define FTDMAC020_LLI_SRC_WIDTH_SHIFT (25) 171 + #define FTDMAC020_LLI_DST_WIDTH_MSK GENMASK(24, 22) 172 + #define FTDMAC020_LLI_DST_WIDTH_SHIFT (22) 173 + #define FTDMAC020_LLI_SRCAD_CTL_MSK GENMASK(21, 20) 174 + #define FTDMAC020_LLI_SRCAD_CTL_SHIFT (20) 175 + #define FTDMAC020_LLI_DSTAD_CTL_MSK GENMASK(19, 18) 176 + #define FTDMAC020_LLI_DSTAD_CTL_SHIFT (18) 177 + #define FTDMAC020_LLI_SRC_SEL BIT(17) 178 + #define FTDMAC020_LLI_DST_SEL BIT(16) 179 + #define FTDMAC020_LLI_TRANSFER_SIZE_MASK GENMASK(11, 0) 180 + #define FTDMAC020_LLI_TRANSFER_SIZE_SHIFT (0) 181 + 182 + #define FTDMAC020_CFG_LLP_CNT_MASK GENMASK(19, 16) 183 + #define FTDMAC020_CFG_LLP_CNT_SHIFT (16) 184 + #define FTDMAC020_CFG_BUSY BIT(8) 185 + #define FTDMAC020_CFG_INT_ABT_MSK BIT(2) 186 + #define FTDMAC020_CFG_INT_ERR_MSK BIT(1) 187 + #define FTDMAC020_CFG_INT_TC_MSK BIT(0) 135 188 136 189 /* DMA linked list chain structure */ 137 190
+26 -4
include/linux/amba/pl08x.h
··· 47 47 * devices with static assignments 48 48 * @muxval: a number usually used to poke into some mux regiser to 49 49 * mux in the signal to this channel 50 - * @cctl_memcpy: options for the channel control register for memcpy 51 - * *** not used for slave channels *** 52 50 * @addr: source/target address in physical memory for this DMA channel, 53 51 * can be the address of a FIFO register for burst requests for example. 54 52 * This can be left undefined if the PrimeCell API is used for configuring ··· 61 63 int min_signal; 62 64 int max_signal; 63 65 u32 muxval; 64 - u32 cctl_memcpy; 65 66 dma_addr_t addr; 66 67 bool single; 67 68 u8 periph_buses; 69 + }; 70 + 71 + enum pl08x_burst_size { 72 + PL08X_BURST_SZ_1, 73 + PL08X_BURST_SZ_4, 74 + PL08X_BURST_SZ_8, 75 + PL08X_BURST_SZ_16, 76 + PL08X_BURST_SZ_32, 77 + PL08X_BURST_SZ_64, 78 + PL08X_BURST_SZ_128, 79 + PL08X_BURST_SZ_256, 80 + }; 81 + 82 + enum pl08x_bus_width { 83 + PL08X_BUS_WIDTH_8_BITS, 84 + PL08X_BUS_WIDTH_16_BITS, 85 + PL08X_BUS_WIDTH_32_BITS, 68 86 }; 69 87 70 88 /** ··· 90 76 * platform, all inclusive, including multiplexed channels. The available 91 77 * physical channels will be multiplexed around these signals as they are 92 78 * requested, just enumerate all possible channels. 79 + * @num_slave_channels: number of elements in the slave channel array 80 + * @memcpy_burst_size: the appropriate burst size for memcpy operations 81 + * @memcpy_bus_width: memory bus width 82 + * @memcpy_prot_buff: whether memcpy DMA is bufferable 83 + * @memcpy_prot_cache: whether memcpy DMA is cacheable 93 84 * @get_xfer_signal: request a physical signal to be used for a DMA transfer 94 85 * immediately: if there is some multiplexing or similar blocking the use 95 86 * of the channel the transfer can be denied by returning less than zero, ··· 109 90 struct pl08x_platform_data { 110 91 struct pl08x_channel_data *slave_channels; 111 92 unsigned int num_slave_channels; 112 - struct pl08x_channel_data memcpy_channel; 93 + enum pl08x_burst_size memcpy_burst_size; 94 + enum pl08x_bus_width memcpy_bus_width; 95 + bool memcpy_prot_buff; 96 + bool memcpy_prot_cache; 113 97 int (*get_xfer_signal)(const struct pl08x_channel_data *); 114 98 void (*put_xfer_signal)(const struct pl08x_channel_data *, int); 115 99 u8 lli_buses;
+1
include/linux/raid/pq.h
··· 142 142 extern const u8 raid6_gfmul[256][256] __attribute__((aligned(256))); 143 143 extern const u8 raid6_vgfmul[256][32] __attribute__((aligned(256))); 144 144 extern const u8 raid6_gfexp[256] __attribute__((aligned(256))); 145 + extern const u8 raid6_gflog[256] __attribute__((aligned(256))); 145 146 extern const u8 raid6_gfinv[256] __attribute__((aligned(256))); 146 147 extern const u8 raid6_gfexi[256] __attribute__((aligned(256))); 147 148
+20
lib/raid6/mktables.c
··· 125 125 printf("EXPORT_SYMBOL(raid6_gfexp);\n"); 126 126 printf("#endif\n"); 127 127 128 + /* Compute log-of-2 table */ 129 + printf("\nconst u8 __attribute__((aligned(256)))\n" 130 + "raid6_gflog[256] =\n" "{\n"); 131 + for (i = 0; i < 256; i += 8) { 132 + printf("\t"); 133 + for (j = 0; j < 8; j++) { 134 + v = 255; 135 + for (k = 0; k < 256; k++) 136 + if (exptbl[k] == (i + j)) { 137 + v = k; 138 + break; 139 + } 140 + printf("0x%02x,%c", v, (j == 7) ? '\n' : ' '); 141 + } 142 + } 143 + printf("};\n"); 144 + printf("#ifdef __KERNEL__\n"); 145 + printf("EXPORT_SYMBOL(raid6_gflog);\n"); 146 + printf("#endif\n"); 147 + 128 148 /* Compute inverse table x^-1 == x^254 */ 129 149 printf("\nconst u8 __attribute__((aligned(256)))\n" 130 150 "raid6_gfinv[256] =\n" "{\n");