| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Ingenic JZ4780 DMA controller |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2015 Imagination Technologies |
|---|
| 5 | 6 | * Author: Alex Smith <alex@alex-smith.me.uk> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 8 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 9 | | - * Free Software Foundation; either version 2 of the License, or (at your |
|---|
| 10 | | - * option) any later version. |
|---|
| 11 | 7 | */ |
|---|
| 12 | 8 | |
|---|
| 13 | 9 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 16 | 12 | #include <linux/interrupt.h> |
|---|
| 17 | 13 | #include <linux/module.h> |
|---|
| 18 | 14 | #include <linux/of.h> |
|---|
| 15 | +#include <linux/of_device.h> |
|---|
| 19 | 16 | #include <linux/of_dma.h> |
|---|
| 20 | 17 | #include <linux/platform_device.h> |
|---|
| 21 | 18 | #include <linux/slab.h> |
|---|
| .. | .. |
|---|
| 23 | 20 | #include "dmaengine.h" |
|---|
| 24 | 21 | #include "virt-dma.h" |
|---|
| 25 | 22 | |
|---|
| 26 | | -#define JZ_DMA_NR_CHANNELS 32 |
|---|
| 27 | | - |
|---|
| 28 | 23 | /* Global registers. */ |
|---|
| 29 | | -#define JZ_DMA_REG_DMAC 0x1000 |
|---|
| 30 | | -#define JZ_DMA_REG_DIRQP 0x1004 |
|---|
| 31 | | -#define JZ_DMA_REG_DDR 0x1008 |
|---|
| 32 | | -#define JZ_DMA_REG_DDRS 0x100c |
|---|
| 33 | | -#define JZ_DMA_REG_DMACP 0x101c |
|---|
| 34 | | -#define JZ_DMA_REG_DSIRQP 0x1020 |
|---|
| 35 | | -#define JZ_DMA_REG_DSIRQM 0x1024 |
|---|
| 36 | | -#define JZ_DMA_REG_DCIRQP 0x1028 |
|---|
| 37 | | -#define JZ_DMA_REG_DCIRQM 0x102c |
|---|
| 24 | +#define JZ_DMA_REG_DMAC 0x00 |
|---|
| 25 | +#define JZ_DMA_REG_DIRQP 0x04 |
|---|
| 26 | +#define JZ_DMA_REG_DDR 0x08 |
|---|
| 27 | +#define JZ_DMA_REG_DDRS 0x0c |
|---|
| 28 | +#define JZ_DMA_REG_DCKE 0x10 |
|---|
| 29 | +#define JZ_DMA_REG_DCKES 0x14 |
|---|
| 30 | +#define JZ_DMA_REG_DCKEC 0x18 |
|---|
| 31 | +#define JZ_DMA_REG_DMACP 0x1c |
|---|
| 32 | +#define JZ_DMA_REG_DSIRQP 0x20 |
|---|
| 33 | +#define JZ_DMA_REG_DSIRQM 0x24 |
|---|
| 34 | +#define JZ_DMA_REG_DCIRQP 0x28 |
|---|
| 35 | +#define JZ_DMA_REG_DCIRQM 0x2c |
|---|
| 38 | 36 | |
|---|
| 39 | 37 | /* Per-channel registers. */ |
|---|
| 40 | 38 | #define JZ_DMA_REG_CHAN(n) (n * 0x20) |
|---|
| 41 | | -#define JZ_DMA_REG_DSA(n) (0x00 + JZ_DMA_REG_CHAN(n)) |
|---|
| 42 | | -#define JZ_DMA_REG_DTA(n) (0x04 + JZ_DMA_REG_CHAN(n)) |
|---|
| 43 | | -#define JZ_DMA_REG_DTC(n) (0x08 + JZ_DMA_REG_CHAN(n)) |
|---|
| 44 | | -#define JZ_DMA_REG_DRT(n) (0x0c + JZ_DMA_REG_CHAN(n)) |
|---|
| 45 | | -#define JZ_DMA_REG_DCS(n) (0x10 + JZ_DMA_REG_CHAN(n)) |
|---|
| 46 | | -#define JZ_DMA_REG_DCM(n) (0x14 + JZ_DMA_REG_CHAN(n)) |
|---|
| 47 | | -#define JZ_DMA_REG_DDA(n) (0x18 + JZ_DMA_REG_CHAN(n)) |
|---|
| 48 | | -#define JZ_DMA_REG_DSD(n) (0x1c + JZ_DMA_REG_CHAN(n)) |
|---|
| 39 | +#define JZ_DMA_REG_DSA 0x00 |
|---|
| 40 | +#define JZ_DMA_REG_DTA 0x04 |
|---|
| 41 | +#define JZ_DMA_REG_DTC 0x08 |
|---|
| 42 | +#define JZ_DMA_REG_DRT 0x0c |
|---|
| 43 | +#define JZ_DMA_REG_DCS 0x10 |
|---|
| 44 | +#define JZ_DMA_REG_DCM 0x14 |
|---|
| 45 | +#define JZ_DMA_REG_DDA 0x18 |
|---|
| 46 | +#define JZ_DMA_REG_DSD 0x1c |
|---|
| 49 | 47 | |
|---|
| 50 | 48 | #define JZ_DMA_DMAC_DMAE BIT(0) |
|---|
| 51 | 49 | #define JZ_DMA_DMAC_AR BIT(2) |
|---|
| 52 | 50 | #define JZ_DMA_DMAC_HLT BIT(3) |
|---|
| 51 | +#define JZ_DMA_DMAC_FAIC BIT(27) |
|---|
| 53 | 52 | #define JZ_DMA_DMAC_FMSC BIT(31) |
|---|
| 54 | 53 | |
|---|
| 55 | 54 | #define JZ_DMA_DRT_AUTO 0x8 |
|---|
| .. | .. |
|---|
| 86 | 85 | BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ |
|---|
| 87 | 86 | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)) |
|---|
| 88 | 87 | |
|---|
| 88 | +#define JZ4780_DMA_CTRL_OFFSET 0x1000 |
|---|
| 89 | + |
|---|
| 90 | +/* macros for use with jz4780_dma_soc_data.flags */ |
|---|
| 91 | +#define JZ_SOC_DATA_ALLOW_LEGACY_DT BIT(0) |
|---|
| 92 | +#define JZ_SOC_DATA_PROGRAMMABLE_DMA BIT(1) |
|---|
| 93 | +#define JZ_SOC_DATA_PER_CHAN_PM BIT(2) |
|---|
| 94 | +#define JZ_SOC_DATA_NO_DCKES_DCKEC BIT(3) |
|---|
| 95 | +#define JZ_SOC_DATA_BREAK_LINKS BIT(4) |
|---|
| 96 | + |
|---|
| 89 | 97 | /** |
|---|
| 90 | 98 | * struct jz4780_dma_hwdesc - descriptor structure read by the DMA controller. |
|---|
| 91 | 99 | * @dcm: value for the DCM (channel command) register |
|---|
| .. | .. |
|---|
| 94 | 102 | * @dtc: transfer count (number of blocks of the transfer size specified in DCM |
|---|
| 95 | 103 | * to transfer) in the low 24 bits, offset of the next descriptor from the |
|---|
| 96 | 104 | * descriptor base address in the upper 8 bits. |
|---|
| 97 | | - * @sd: target/source stride difference (in stride transfer mode). |
|---|
| 98 | | - * @drt: request type |
|---|
| 99 | 105 | */ |
|---|
| 100 | 106 | struct jz4780_dma_hwdesc { |
|---|
| 101 | 107 | uint32_t dcm; |
|---|
| 102 | 108 | uint32_t dsa; |
|---|
| 103 | 109 | uint32_t dta; |
|---|
| 104 | 110 | uint32_t dtc; |
|---|
| 105 | | - uint32_t sd; |
|---|
| 106 | | - uint32_t drt; |
|---|
| 107 | | - uint32_t reserved[2]; |
|---|
| 108 | 111 | }; |
|---|
| 109 | 112 | |
|---|
| 110 | 113 | /* Size of allocations for hardware descriptor blocks. */ |
|---|
| .. | .. |
|---|
| 135 | 138 | unsigned int curr_hwdesc; |
|---|
| 136 | 139 | }; |
|---|
| 137 | 140 | |
|---|
| 141 | +struct jz4780_dma_soc_data { |
|---|
| 142 | + unsigned int nb_channels; |
|---|
| 143 | + unsigned int transfer_ord_max; |
|---|
| 144 | + unsigned long flags; |
|---|
| 145 | +}; |
|---|
| 146 | + |
|---|
| 138 | 147 | struct jz4780_dma_dev { |
|---|
| 139 | 148 | struct dma_device dma_device; |
|---|
| 140 | | - void __iomem *base; |
|---|
| 149 | + void __iomem *chn_base; |
|---|
| 150 | + void __iomem *ctrl_base; |
|---|
| 141 | 151 | struct clk *clk; |
|---|
| 142 | 152 | unsigned int irq; |
|---|
| 153 | + const struct jz4780_dma_soc_data *soc_data; |
|---|
| 143 | 154 | |
|---|
| 144 | 155 | uint32_t chan_reserved; |
|---|
| 145 | | - struct jz4780_dma_chan chan[JZ_DMA_NR_CHANNELS]; |
|---|
| 156 | + struct jz4780_dma_chan chan[]; |
|---|
| 146 | 157 | }; |
|---|
| 147 | 158 | |
|---|
| 148 | 159 | struct jz4780_dma_filter_data { |
|---|
| 149 | | - struct device_node *of_node; |
|---|
| 150 | 160 | uint32_t transfer_type; |
|---|
| 151 | 161 | int channel; |
|---|
| 152 | 162 | }; |
|---|
| .. | .. |
|---|
| 169 | 179 | dma_device); |
|---|
| 170 | 180 | } |
|---|
| 171 | 181 | |
|---|
| 172 | | -static inline uint32_t jz4780_dma_readl(struct jz4780_dma_dev *jzdma, |
|---|
| 173 | | - unsigned int reg) |
|---|
| 182 | +static inline uint32_t jz4780_dma_chn_readl(struct jz4780_dma_dev *jzdma, |
|---|
| 183 | + unsigned int chn, unsigned int reg) |
|---|
| 174 | 184 | { |
|---|
| 175 | | - return readl(jzdma->base + reg); |
|---|
| 185 | + return readl(jzdma->chn_base + reg + JZ_DMA_REG_CHAN(chn)); |
|---|
| 176 | 186 | } |
|---|
| 177 | 187 | |
|---|
| 178 | | -static inline void jz4780_dma_writel(struct jz4780_dma_dev *jzdma, |
|---|
| 188 | +static inline void jz4780_dma_chn_writel(struct jz4780_dma_dev *jzdma, |
|---|
| 189 | + unsigned int chn, unsigned int reg, uint32_t val) |
|---|
| 190 | +{ |
|---|
| 191 | + writel(val, jzdma->chn_base + reg + JZ_DMA_REG_CHAN(chn)); |
|---|
| 192 | +} |
|---|
| 193 | + |
|---|
| 194 | +static inline uint32_t jz4780_dma_ctrl_readl(struct jz4780_dma_dev *jzdma, |
|---|
| 195 | + unsigned int reg) |
|---|
| 196 | +{ |
|---|
| 197 | + return readl(jzdma->ctrl_base + reg); |
|---|
| 198 | +} |
|---|
| 199 | + |
|---|
| 200 | +static inline void jz4780_dma_ctrl_writel(struct jz4780_dma_dev *jzdma, |
|---|
| 179 | 201 | unsigned int reg, uint32_t val) |
|---|
| 180 | 202 | { |
|---|
| 181 | | - writel(val, jzdma->base + reg); |
|---|
| 203 | + writel(val, jzdma->ctrl_base + reg); |
|---|
| 204 | +} |
|---|
| 205 | + |
|---|
| 206 | +static inline void jz4780_dma_chan_enable(struct jz4780_dma_dev *jzdma, |
|---|
| 207 | + unsigned int chn) |
|---|
| 208 | +{ |
|---|
| 209 | + if (jzdma->soc_data->flags & JZ_SOC_DATA_PER_CHAN_PM) { |
|---|
| 210 | + unsigned int reg; |
|---|
| 211 | + |
|---|
| 212 | + if (jzdma->soc_data->flags & JZ_SOC_DATA_NO_DCKES_DCKEC) |
|---|
| 213 | + reg = JZ_DMA_REG_DCKE; |
|---|
| 214 | + else |
|---|
| 215 | + reg = JZ_DMA_REG_DCKES; |
|---|
| 216 | + |
|---|
| 217 | + jz4780_dma_ctrl_writel(jzdma, reg, BIT(chn)); |
|---|
| 218 | + } |
|---|
| 219 | +} |
|---|
| 220 | + |
|---|
| 221 | +static inline void jz4780_dma_chan_disable(struct jz4780_dma_dev *jzdma, |
|---|
| 222 | + unsigned int chn) |
|---|
| 223 | +{ |
|---|
| 224 | + if ((jzdma->soc_data->flags & JZ_SOC_DATA_PER_CHAN_PM) && |
|---|
| 225 | + !(jzdma->soc_data->flags & JZ_SOC_DATA_NO_DCKES_DCKEC)) |
|---|
| 226 | + jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DCKEC, BIT(chn)); |
|---|
| 182 | 227 | } |
|---|
| 183 | 228 | |
|---|
| 184 | 229 | static struct jz4780_dma_desc *jz4780_dma_desc_alloc( |
|---|
| .. | .. |
|---|
| 215 | 260 | kfree(desc); |
|---|
| 216 | 261 | } |
|---|
| 217 | 262 | |
|---|
| 218 | | -static uint32_t jz4780_dma_transfer_size(unsigned long val, uint32_t *shift) |
|---|
| 263 | +static uint32_t jz4780_dma_transfer_size(struct jz4780_dma_chan *jzchan, |
|---|
| 264 | + unsigned long val, uint32_t *shift) |
|---|
| 219 | 265 | { |
|---|
| 266 | + struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan); |
|---|
| 220 | 267 | int ord = ffs(val) - 1; |
|---|
| 221 | 268 | |
|---|
| 222 | 269 | /* |
|---|
| .. | .. |
|---|
| 228 | 275 | */ |
|---|
| 229 | 276 | if (ord == 3) |
|---|
| 230 | 277 | ord = 2; |
|---|
| 231 | | - else if (ord > 7) |
|---|
| 232 | | - ord = 7; |
|---|
| 278 | + else if (ord > jzdma->soc_data->transfer_ord_max) |
|---|
| 279 | + ord = jzdma->soc_data->transfer_ord_max; |
|---|
| 233 | 280 | |
|---|
| 234 | 281 | *shift = ord; |
|---|
| 235 | 282 | |
|---|
| .. | .. |
|---|
| 262 | 309 | desc->dcm = JZ_DMA_DCM_SAI; |
|---|
| 263 | 310 | desc->dsa = addr; |
|---|
| 264 | 311 | desc->dta = config->dst_addr; |
|---|
| 265 | | - desc->drt = jzchan->transfer_type; |
|---|
| 266 | 312 | |
|---|
| 267 | 313 | width = config->dst_addr_width; |
|---|
| 268 | 314 | maxburst = config->dst_maxburst; |
|---|
| .. | .. |
|---|
| 270 | 316 | desc->dcm = JZ_DMA_DCM_DAI; |
|---|
| 271 | 317 | desc->dsa = config->src_addr; |
|---|
| 272 | 318 | desc->dta = addr; |
|---|
| 273 | | - desc->drt = jzchan->transfer_type; |
|---|
| 274 | 319 | |
|---|
| 275 | 320 | width = config->src_addr_width; |
|---|
| 276 | 321 | maxburst = config->src_maxburst; |
|---|
| .. | .. |
|---|
| 283 | 328 | * divisible by the transfer size, and we must not use more than the |
|---|
| 284 | 329 | * maximum burst specified by the user. |
|---|
| 285 | 330 | */ |
|---|
| 286 | | - tsz = jz4780_dma_transfer_size(addr | len | (width * maxburst), |
|---|
| 331 | + tsz = jz4780_dma_transfer_size(jzchan, addr | len | (width * maxburst), |
|---|
| 287 | 332 | &jzchan->transfer_shift); |
|---|
| 288 | 333 | |
|---|
| 289 | 334 | switch (width) { |
|---|
| .. | .. |
|---|
| 311 | 356 | void *context) |
|---|
| 312 | 357 | { |
|---|
| 313 | 358 | struct jz4780_dma_chan *jzchan = to_jz4780_dma_chan(chan); |
|---|
| 359 | + struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan); |
|---|
| 314 | 360 | struct jz4780_dma_desc *desc; |
|---|
| 315 | 361 | unsigned int i; |
|---|
| 316 | 362 | int err; |
|---|
| .. | .. |
|---|
| 331 | 377 | |
|---|
| 332 | 378 | desc->desc[i].dcm |= JZ_DMA_DCM_TIE; |
|---|
| 333 | 379 | |
|---|
| 334 | | - if (i != (sg_len - 1)) { |
|---|
| 380 | + if (i != (sg_len - 1) && |
|---|
| 381 | + !(jzdma->soc_data->flags & JZ_SOC_DATA_BREAK_LINKS)) { |
|---|
| 335 | 382 | /* Automatically proceeed to the next descriptor. */ |
|---|
| 336 | 383 | desc->desc[i].dcm |= JZ_DMA_DCM_LINK; |
|---|
| 337 | 384 | |
|---|
| .. | .. |
|---|
| 412 | 459 | if (!desc) |
|---|
| 413 | 460 | return NULL; |
|---|
| 414 | 461 | |
|---|
| 415 | | - tsz = jz4780_dma_transfer_size(dest | src | len, |
|---|
| 462 | + tsz = jz4780_dma_transfer_size(jzchan, dest | src | len, |
|---|
| 416 | 463 | &jzchan->transfer_shift); |
|---|
| 464 | + |
|---|
| 465 | + jzchan->transfer_type = JZ_DMA_DRT_AUTO; |
|---|
| 417 | 466 | |
|---|
| 418 | 467 | desc->desc[0].dsa = src; |
|---|
| 419 | 468 | desc->desc[0].dta = dest; |
|---|
| 420 | | - desc->desc[0].drt = JZ_DMA_DRT_AUTO; |
|---|
| 421 | 469 | desc->desc[0].dcm = JZ_DMA_DCM_TIE | JZ_DMA_DCM_SAI | JZ_DMA_DCM_DAI | |
|---|
| 422 | 470 | tsz << JZ_DMA_DCM_TSZ_SHIFT | |
|---|
| 423 | 471 | JZ_DMA_WIDTH_32_BIT << JZ_DMA_DCM_SP_SHIFT | |
|---|
| .. | .. |
|---|
| 472 | 520 | (jzchan->curr_hwdesc + 1) % jzchan->desc->count; |
|---|
| 473 | 521 | } |
|---|
| 474 | 522 | |
|---|
| 475 | | - /* Use 8-word descriptors. */ |
|---|
| 476 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DCS(jzchan->id), JZ_DMA_DCS_DES8); |
|---|
| 523 | + /* Enable the channel's clock. */ |
|---|
| 524 | + jz4780_dma_chan_enable(jzdma, jzchan->id); |
|---|
| 525 | + |
|---|
| 526 | + /* Use 4-word descriptors. */ |
|---|
| 527 | + jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, 0); |
|---|
| 528 | + |
|---|
| 529 | + /* Set transfer type. */ |
|---|
| 530 | + jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DRT, |
|---|
| 531 | + jzchan->transfer_type); |
|---|
| 532 | + |
|---|
| 533 | + /* |
|---|
| 534 | + * Set the transfer count. This is redundant for a descriptor-driven |
|---|
| 535 | + * transfer. However, there can be a delay between the transfer start |
|---|
| 536 | + * time and when DTCn reg contains the new transfer count. Setting |
|---|
| 537 | + * it explicitly ensures residue is computed correctly at all times. |
|---|
| 538 | + */ |
|---|
| 539 | + jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DTC, |
|---|
| 540 | + jzchan->desc->desc[jzchan->curr_hwdesc].dtc); |
|---|
| 477 | 541 | |
|---|
| 478 | 542 | /* Write descriptor address and initiate descriptor fetch. */ |
|---|
| 479 | 543 | desc_phys = jzchan->desc->desc_phys + |
|---|
| 480 | 544 | (jzchan->curr_hwdesc * sizeof(*jzchan->desc->desc)); |
|---|
| 481 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DDA(jzchan->id), desc_phys); |
|---|
| 482 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DDRS, BIT(jzchan->id)); |
|---|
| 545 | + jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DDA, desc_phys); |
|---|
| 546 | + jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DDRS, BIT(jzchan->id)); |
|---|
| 483 | 547 | |
|---|
| 484 | 548 | /* Enable the channel. */ |
|---|
| 485 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DCS(jzchan->id), |
|---|
| 486 | | - JZ_DMA_DCS_DES8 | JZ_DMA_DCS_CTE); |
|---|
| 549 | + jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, |
|---|
| 550 | + JZ_DMA_DCS_CTE); |
|---|
| 487 | 551 | } |
|---|
| 488 | 552 | |
|---|
| 489 | 553 | static void jz4780_dma_issue_pending(struct dma_chan *chan) |
|---|
| .. | .. |
|---|
| 509 | 573 | spin_lock_irqsave(&jzchan->vchan.lock, flags); |
|---|
| 510 | 574 | |
|---|
| 511 | 575 | /* Clear the DMA status and stop the transfer. */ |
|---|
| 512 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DCS(jzchan->id), 0); |
|---|
| 576 | + jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, 0); |
|---|
| 513 | 577 | if (jzchan->desc) { |
|---|
| 514 | 578 | vchan_terminate_vdesc(&jzchan->desc->vdesc); |
|---|
| 515 | 579 | jzchan->desc = NULL; |
|---|
| 516 | 580 | } |
|---|
| 581 | + |
|---|
| 582 | + jz4780_dma_chan_disable(jzdma, jzchan->id); |
|---|
| 517 | 583 | |
|---|
| 518 | 584 | vchan_get_all_descriptors(&jzchan->vchan, &head); |
|---|
| 519 | 585 | |
|---|
| .. | .. |
|---|
| 526 | 592 | static void jz4780_dma_synchronize(struct dma_chan *chan) |
|---|
| 527 | 593 | { |
|---|
| 528 | 594 | struct jz4780_dma_chan *jzchan = to_jz4780_dma_chan(chan); |
|---|
| 595 | + struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan); |
|---|
| 529 | 596 | |
|---|
| 530 | 597 | vchan_synchronize(&jzchan->vchan); |
|---|
| 598 | + jz4780_dma_chan_disable(jzdma, jzchan->id); |
|---|
| 531 | 599 | } |
|---|
| 532 | 600 | |
|---|
| 533 | 601 | static int jz4780_dma_config(struct dma_chan *chan, |
|---|
| .. | .. |
|---|
| 549 | 617 | struct jz4780_dma_desc *desc, unsigned int next_sg) |
|---|
| 550 | 618 | { |
|---|
| 551 | 619 | struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan); |
|---|
| 552 | | - unsigned int residue, count; |
|---|
| 620 | + unsigned int count = 0; |
|---|
| 553 | 621 | unsigned int i; |
|---|
| 554 | 622 | |
|---|
| 555 | | - residue = 0; |
|---|
| 556 | | - |
|---|
| 557 | 623 | for (i = next_sg; i < desc->count; i++) |
|---|
| 558 | | - residue += desc->desc[i].dtc << jzchan->transfer_shift; |
|---|
| 624 | + count += desc->desc[i].dtc & GENMASK(23, 0); |
|---|
| 559 | 625 | |
|---|
| 560 | | - if (next_sg != 0) { |
|---|
| 561 | | - count = jz4780_dma_readl(jzdma, |
|---|
| 562 | | - JZ_DMA_REG_DTC(jzchan->id)); |
|---|
| 563 | | - residue += count << jzchan->transfer_shift; |
|---|
| 564 | | - } |
|---|
| 626 | + if (next_sg != 0) |
|---|
| 627 | + count += jz4780_dma_chn_readl(jzdma, jzchan->id, |
|---|
| 628 | + JZ_DMA_REG_DTC); |
|---|
| 565 | 629 | |
|---|
| 566 | | - return residue; |
|---|
| 630 | + return count << jzchan->transfer_shift; |
|---|
| 567 | 631 | } |
|---|
| 568 | 632 | |
|---|
| 569 | 633 | static enum dma_status jz4780_dma_tx_status(struct dma_chan *chan, |
|---|
| .. | .. |
|---|
| 573 | 637 | struct virt_dma_desc *vdesc; |
|---|
| 574 | 638 | enum dma_status status; |
|---|
| 575 | 639 | unsigned long flags; |
|---|
| 640 | + unsigned long residue = 0; |
|---|
| 576 | 641 | |
|---|
| 577 | 642 | spin_lock_irqsave(&jzchan->vchan.lock, flags); |
|---|
| 578 | 643 | |
|---|
| .. | .. |
|---|
| 583 | 648 | vdesc = vchan_find_desc(&jzchan->vchan, cookie); |
|---|
| 584 | 649 | if (vdesc) { |
|---|
| 585 | 650 | /* On the issued list, so hasn't been processed yet */ |
|---|
| 586 | | - txstate->residue = jz4780_dma_desc_residue(jzchan, |
|---|
| 651 | + residue = jz4780_dma_desc_residue(jzchan, |
|---|
| 587 | 652 | to_jz4780_dma_desc(vdesc), 0); |
|---|
| 588 | 653 | } else if (cookie == jzchan->desc->vdesc.tx.cookie) { |
|---|
| 589 | | - txstate->residue = jz4780_dma_desc_residue(jzchan, jzchan->desc, |
|---|
| 654 | + residue = jz4780_dma_desc_residue(jzchan, jzchan->desc, |
|---|
| 590 | 655 | jzchan->curr_hwdesc + 1); |
|---|
| 591 | | - } else |
|---|
| 592 | | - txstate->residue = 0; |
|---|
| 656 | + } |
|---|
| 657 | + dma_set_residue(txstate, residue); |
|---|
| 593 | 658 | |
|---|
| 594 | 659 | if (vdesc && jzchan->desc && vdesc == &jzchan->desc->vdesc |
|---|
| 595 | 660 | && jzchan->desc->status & (JZ_DMA_DCS_AR | JZ_DMA_DCS_HLT)) |
|---|
| .. | .. |
|---|
| 600 | 665 | return status; |
|---|
| 601 | 666 | } |
|---|
| 602 | 667 | |
|---|
| 603 | | -static void jz4780_dma_chan_irq(struct jz4780_dma_dev *jzdma, |
|---|
| 604 | | - struct jz4780_dma_chan *jzchan) |
|---|
| 668 | +static bool jz4780_dma_chan_irq(struct jz4780_dma_dev *jzdma, |
|---|
| 669 | + struct jz4780_dma_chan *jzchan) |
|---|
| 605 | 670 | { |
|---|
| 671 | + const unsigned int soc_flags = jzdma->soc_data->flags; |
|---|
| 672 | + struct jz4780_dma_desc *desc = jzchan->desc; |
|---|
| 606 | 673 | uint32_t dcs; |
|---|
| 674 | + bool ack = true; |
|---|
| 607 | 675 | |
|---|
| 608 | 676 | spin_lock(&jzchan->vchan.lock); |
|---|
| 609 | 677 | |
|---|
| 610 | | - dcs = jz4780_dma_readl(jzdma, JZ_DMA_REG_DCS(jzchan->id)); |
|---|
| 611 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DCS(jzchan->id), 0); |
|---|
| 678 | + dcs = jz4780_dma_chn_readl(jzdma, jzchan->id, JZ_DMA_REG_DCS); |
|---|
| 679 | + jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, 0); |
|---|
| 612 | 680 | |
|---|
| 613 | 681 | if (dcs & JZ_DMA_DCS_AR) { |
|---|
| 614 | 682 | dev_warn(&jzchan->vchan.chan.dev->device, |
|---|
| .. | .. |
|---|
| 626 | 694 | if ((dcs & (JZ_DMA_DCS_AR | JZ_DMA_DCS_HLT)) == 0) { |
|---|
| 627 | 695 | if (jzchan->desc->type == DMA_CYCLIC) { |
|---|
| 628 | 696 | vchan_cyclic_callback(&jzchan->desc->vdesc); |
|---|
| 629 | | - } else { |
|---|
| 630 | | - vchan_cookie_complete(&jzchan->desc->vdesc); |
|---|
| 631 | | - jzchan->desc = NULL; |
|---|
| 632 | | - } |
|---|
| 633 | 697 | |
|---|
| 634 | | - jz4780_dma_begin(jzchan); |
|---|
| 698 | + jz4780_dma_begin(jzchan); |
|---|
| 699 | + } else if (dcs & JZ_DMA_DCS_TT) { |
|---|
| 700 | + if (!(soc_flags & JZ_SOC_DATA_BREAK_LINKS) || |
|---|
| 701 | + (jzchan->curr_hwdesc + 1 == desc->count)) { |
|---|
| 702 | + vchan_cookie_complete(&desc->vdesc); |
|---|
| 703 | + jzchan->desc = NULL; |
|---|
| 704 | + } |
|---|
| 705 | + |
|---|
| 706 | + jz4780_dma_begin(jzchan); |
|---|
| 707 | + } else { |
|---|
| 708 | + /* False positive - continue the transfer */ |
|---|
| 709 | + ack = false; |
|---|
| 710 | + jz4780_dma_chn_writel(jzdma, jzchan->id, |
|---|
| 711 | + JZ_DMA_REG_DCS, |
|---|
| 712 | + JZ_DMA_DCS_CTE); |
|---|
| 713 | + } |
|---|
| 635 | 714 | } |
|---|
| 636 | 715 | } else { |
|---|
| 637 | 716 | dev_err(&jzchan->vchan.chan.dev->device, |
|---|
| .. | .. |
|---|
| 639 | 718 | } |
|---|
| 640 | 719 | |
|---|
| 641 | 720 | spin_unlock(&jzchan->vchan.lock); |
|---|
| 721 | + |
|---|
| 722 | + return ack; |
|---|
| 642 | 723 | } |
|---|
| 643 | 724 | |
|---|
| 644 | 725 | static irqreturn_t jz4780_dma_irq_handler(int irq, void *data) |
|---|
| 645 | 726 | { |
|---|
| 646 | 727 | struct jz4780_dma_dev *jzdma = data; |
|---|
| 647 | | - uint32_t pending, dmac; |
|---|
| 728 | + unsigned int nb_channels = jzdma->soc_data->nb_channels; |
|---|
| 729 | + unsigned long pending; |
|---|
| 730 | + uint32_t dmac; |
|---|
| 648 | 731 | int i; |
|---|
| 649 | 732 | |
|---|
| 650 | | - pending = jz4780_dma_readl(jzdma, JZ_DMA_REG_DIRQP); |
|---|
| 733 | + pending = jz4780_dma_ctrl_readl(jzdma, JZ_DMA_REG_DIRQP); |
|---|
| 651 | 734 | |
|---|
| 652 | | - for (i = 0; i < JZ_DMA_NR_CHANNELS; i++) { |
|---|
| 653 | | - if (!(pending & (1<<i))) |
|---|
| 654 | | - continue; |
|---|
| 655 | | - |
|---|
| 656 | | - jz4780_dma_chan_irq(jzdma, &jzdma->chan[i]); |
|---|
| 735 | + for_each_set_bit(i, &pending, nb_channels) { |
|---|
| 736 | + if (jz4780_dma_chan_irq(jzdma, &jzdma->chan[i])) |
|---|
| 737 | + pending &= ~BIT(i); |
|---|
| 657 | 738 | } |
|---|
| 658 | 739 | |
|---|
| 659 | 740 | /* Clear halt and address error status of all channels. */ |
|---|
| 660 | | - dmac = jz4780_dma_readl(jzdma, JZ_DMA_REG_DMAC); |
|---|
| 741 | + dmac = jz4780_dma_ctrl_readl(jzdma, JZ_DMA_REG_DMAC); |
|---|
| 661 | 742 | dmac &= ~(JZ_DMA_DMAC_HLT | JZ_DMA_DMAC_AR); |
|---|
| 662 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DMAC, dmac); |
|---|
| 743 | + jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMAC, dmac); |
|---|
| 663 | 744 | |
|---|
| 664 | 745 | /* Clear interrupt pending status. */ |
|---|
| 665 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DIRQP, 0); |
|---|
| 746 | + jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DIRQP, pending); |
|---|
| 666 | 747 | |
|---|
| 667 | 748 | return IRQ_HANDLED; |
|---|
| 668 | 749 | } |
|---|
| .. | .. |
|---|
| 699 | 780 | struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan); |
|---|
| 700 | 781 | struct jz4780_dma_filter_data *data = param; |
|---|
| 701 | 782 | |
|---|
| 702 | | - if (jzdma->dma_device.dev->of_node != data->of_node) |
|---|
| 703 | | - return false; |
|---|
| 704 | 783 | |
|---|
| 705 | 784 | if (data->channel > -1) { |
|---|
| 706 | 785 | if (data->channel != jzchan->id) |
|---|
| .. | .. |
|---|
| 724 | 803 | if (dma_spec->args_count != 2) |
|---|
| 725 | 804 | return NULL; |
|---|
| 726 | 805 | |
|---|
| 727 | | - data.of_node = ofdma->of_node; |
|---|
| 728 | 806 | data.transfer_type = dma_spec->args[0]; |
|---|
| 729 | 807 | data.channel = dma_spec->args[1]; |
|---|
| 730 | 808 | |
|---|
| 731 | 809 | if (data.channel > -1) { |
|---|
| 732 | | - if (data.channel >= JZ_DMA_NR_CHANNELS) { |
|---|
| 810 | + if (data.channel >= jzdma->soc_data->nb_channels) { |
|---|
| 733 | 811 | dev_err(jzdma->dma_device.dev, |
|---|
| 734 | 812 | "device requested non-existent channel %u\n", |
|---|
| 735 | 813 | data.channel); |
|---|
| .. | .. |
|---|
| 749 | 827 | return dma_get_slave_channel( |
|---|
| 750 | 828 | &jzdma->chan[data.channel].vchan.chan); |
|---|
| 751 | 829 | } else { |
|---|
| 752 | | - return dma_request_channel(mask, jz4780_dma_filter_fn, &data); |
|---|
| 830 | + return __dma_request_channel(&mask, jz4780_dma_filter_fn, &data, |
|---|
| 831 | + ofdma->of_node); |
|---|
| 753 | 832 | } |
|---|
| 754 | 833 | } |
|---|
| 755 | 834 | |
|---|
| 756 | 835 | static int jz4780_dma_probe(struct platform_device *pdev) |
|---|
| 757 | 836 | { |
|---|
| 758 | 837 | struct device *dev = &pdev->dev; |
|---|
| 838 | + const struct jz4780_dma_soc_data *soc_data; |
|---|
| 759 | 839 | struct jz4780_dma_dev *jzdma; |
|---|
| 760 | 840 | struct jz4780_dma_chan *jzchan; |
|---|
| 761 | 841 | struct dma_device *dd; |
|---|
| .. | .. |
|---|
| 767 | 847 | return -EINVAL; |
|---|
| 768 | 848 | } |
|---|
| 769 | 849 | |
|---|
| 770 | | - jzdma = devm_kzalloc(dev, sizeof(*jzdma), GFP_KERNEL); |
|---|
| 850 | + soc_data = device_get_match_data(dev); |
|---|
| 851 | + if (!soc_data) |
|---|
| 852 | + return -EINVAL; |
|---|
| 853 | + |
|---|
| 854 | + jzdma = devm_kzalloc(dev, struct_size(jzdma, chan, |
|---|
| 855 | + soc_data->nb_channels), GFP_KERNEL); |
|---|
| 771 | 856 | if (!jzdma) |
|---|
| 772 | 857 | return -ENOMEM; |
|---|
| 773 | 858 | |
|---|
| 859 | + jzdma->soc_data = soc_data; |
|---|
| 774 | 860 | platform_set_drvdata(pdev, jzdma); |
|---|
| 775 | 861 | |
|---|
| 776 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 777 | | - if (!res) { |
|---|
| 862 | + jzdma->chn_base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 863 | + if (IS_ERR(jzdma->chn_base)) |
|---|
| 864 | + return PTR_ERR(jzdma->chn_base); |
|---|
| 865 | + |
|---|
| 866 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
|---|
| 867 | + if (res) { |
|---|
| 868 | + jzdma->ctrl_base = devm_ioremap_resource(dev, res); |
|---|
| 869 | + if (IS_ERR(jzdma->ctrl_base)) |
|---|
| 870 | + return PTR_ERR(jzdma->ctrl_base); |
|---|
| 871 | + } else if (soc_data->flags & JZ_SOC_DATA_ALLOW_LEGACY_DT) { |
|---|
| 872 | + /* |
|---|
| 873 | + * On JZ4780, if the second memory resource was not supplied, |
|---|
| 874 | + * assume we're using an old devicetree, and calculate the |
|---|
| 875 | + * offset to the control registers. |
|---|
| 876 | + */ |
|---|
| 877 | + jzdma->ctrl_base = jzdma->chn_base + JZ4780_DMA_CTRL_OFFSET; |
|---|
| 878 | + } else { |
|---|
| 778 | 879 | dev_err(dev, "failed to get I/O memory\n"); |
|---|
| 779 | 880 | return -EINVAL; |
|---|
| 780 | | - } |
|---|
| 781 | | - |
|---|
| 782 | | - jzdma->base = devm_ioremap_resource(dev, res); |
|---|
| 783 | | - if (IS_ERR(jzdma->base)) |
|---|
| 784 | | - return PTR_ERR(jzdma->base); |
|---|
| 785 | | - |
|---|
| 786 | | - ret = platform_get_irq(pdev, 0); |
|---|
| 787 | | - if (ret < 0) { |
|---|
| 788 | | - dev_err(dev, "failed to get IRQ: %d\n", ret); |
|---|
| 789 | | - return ret; |
|---|
| 790 | | - } |
|---|
| 791 | | - |
|---|
| 792 | | - jzdma->irq = ret; |
|---|
| 793 | | - |
|---|
| 794 | | - ret = request_irq(jzdma->irq, jz4780_dma_irq_handler, 0, dev_name(dev), |
|---|
| 795 | | - jzdma); |
|---|
| 796 | | - if (ret) { |
|---|
| 797 | | - dev_err(dev, "failed to request IRQ %u!\n", jzdma->irq); |
|---|
| 798 | | - return ret; |
|---|
| 799 | 881 | } |
|---|
| 800 | 882 | |
|---|
| 801 | 883 | jzdma->clk = devm_clk_get(dev, NULL); |
|---|
| 802 | 884 | if (IS_ERR(jzdma->clk)) { |
|---|
| 803 | 885 | dev_err(dev, "failed to get clock\n"); |
|---|
| 804 | 886 | ret = PTR_ERR(jzdma->clk); |
|---|
| 805 | | - goto err_free_irq; |
|---|
| 887 | + return ret; |
|---|
| 806 | 888 | } |
|---|
| 807 | 889 | |
|---|
| 808 | 890 | clk_prepare_enable(jzdma->clk); |
|---|
| .. | .. |
|---|
| 839 | 921 | * Also set the FMSC bit - it increases MSC performance, so it makes |
|---|
| 840 | 922 | * little sense not to enable it. |
|---|
| 841 | 923 | */ |
|---|
| 842 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DMAC, |
|---|
| 843 | | - JZ_DMA_DMAC_DMAE | JZ_DMA_DMAC_FMSC); |
|---|
| 844 | | - jz4780_dma_writel(jzdma, JZ_DMA_REG_DMACP, 0); |
|---|
| 924 | + jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMAC, JZ_DMA_DMAC_DMAE | |
|---|
| 925 | + JZ_DMA_DMAC_FAIC | JZ_DMA_DMAC_FMSC); |
|---|
| 926 | + |
|---|
| 927 | + if (soc_data->flags & JZ_SOC_DATA_PROGRAMMABLE_DMA) |
|---|
| 928 | + jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMACP, 0); |
|---|
| 845 | 929 | |
|---|
| 846 | 930 | INIT_LIST_HEAD(&dd->channels); |
|---|
| 847 | 931 | |
|---|
| 848 | | - for (i = 0; i < JZ_DMA_NR_CHANNELS; i++) { |
|---|
| 932 | + for (i = 0; i < soc_data->nb_channels; i++) { |
|---|
| 849 | 933 | jzchan = &jzdma->chan[i]; |
|---|
| 850 | 934 | jzchan->id = i; |
|---|
| 851 | 935 | |
|---|
| .. | .. |
|---|
| 853 | 937 | jzchan->vchan.desc_free = jz4780_dma_desc_free; |
|---|
| 854 | 938 | } |
|---|
| 855 | 939 | |
|---|
| 856 | | - ret = dma_async_device_register(dd); |
|---|
| 940 | + ret = platform_get_irq(pdev, 0); |
|---|
| 941 | + if (ret < 0) |
|---|
| 942 | + goto err_disable_clk; |
|---|
| 943 | + |
|---|
| 944 | + jzdma->irq = ret; |
|---|
| 945 | + |
|---|
| 946 | + ret = request_irq(jzdma->irq, jz4780_dma_irq_handler, 0, dev_name(dev), |
|---|
| 947 | + jzdma); |
|---|
| 948 | + if (ret) { |
|---|
| 949 | + dev_err(dev, "failed to request IRQ %u!\n", jzdma->irq); |
|---|
| 950 | + goto err_disable_clk; |
|---|
| 951 | + } |
|---|
| 952 | + |
|---|
| 953 | + ret = dmaenginem_async_device_register(dd); |
|---|
| 857 | 954 | if (ret) { |
|---|
| 858 | 955 | dev_err(dev, "failed to register device\n"); |
|---|
| 859 | | - goto err_disable_clk; |
|---|
| 956 | + goto err_free_irq; |
|---|
| 860 | 957 | } |
|---|
| 861 | 958 | |
|---|
| 862 | 959 | /* Register with OF DMA helpers. */ |
|---|
| .. | .. |
|---|
| 864 | 961 | jzdma); |
|---|
| 865 | 962 | if (ret) { |
|---|
| 866 | 963 | dev_err(dev, "failed to register OF DMA controller\n"); |
|---|
| 867 | | - goto err_unregister_dev; |
|---|
| 964 | + goto err_free_irq; |
|---|
| 868 | 965 | } |
|---|
| 869 | 966 | |
|---|
| 870 | 967 | dev_info(dev, "JZ4780 DMA controller initialised\n"); |
|---|
| 871 | 968 | return 0; |
|---|
| 872 | 969 | |
|---|
| 873 | | -err_unregister_dev: |
|---|
| 874 | | - dma_async_device_unregister(dd); |
|---|
| 970 | +err_free_irq: |
|---|
| 971 | + free_irq(jzdma->irq, jzdma); |
|---|
| 875 | 972 | |
|---|
| 876 | 973 | err_disable_clk: |
|---|
| 877 | 974 | clk_disable_unprepare(jzdma->clk); |
|---|
| 878 | | - |
|---|
| 879 | | -err_free_irq: |
|---|
| 880 | | - free_irq(jzdma->irq, jzdma); |
|---|
| 881 | 975 | return ret; |
|---|
| 882 | 976 | } |
|---|
| 883 | 977 | |
|---|
| .. | .. |
|---|
| 888 | 982 | |
|---|
| 889 | 983 | of_dma_controller_free(pdev->dev.of_node); |
|---|
| 890 | 984 | |
|---|
| 985 | + clk_disable_unprepare(jzdma->clk); |
|---|
| 891 | 986 | free_irq(jzdma->irq, jzdma); |
|---|
| 892 | 987 | |
|---|
| 893 | | - for (i = 0; i < JZ_DMA_NR_CHANNELS; i++) |
|---|
| 988 | + for (i = 0; i < jzdma->soc_data->nb_channels; i++) |
|---|
| 894 | 989 | tasklet_kill(&jzdma->chan[i].vchan.task); |
|---|
| 895 | 990 | |
|---|
| 896 | | - dma_async_device_unregister(&jzdma->dma_device); |
|---|
| 897 | 991 | return 0; |
|---|
| 898 | 992 | } |
|---|
| 899 | 993 | |
|---|
| 994 | +static const struct jz4780_dma_soc_data jz4740_dma_soc_data = { |
|---|
| 995 | + .nb_channels = 6, |
|---|
| 996 | + .transfer_ord_max = 5, |
|---|
| 997 | + .flags = JZ_SOC_DATA_BREAK_LINKS, |
|---|
| 998 | +}; |
|---|
| 999 | + |
|---|
| 1000 | +static const struct jz4780_dma_soc_data jz4725b_dma_soc_data = { |
|---|
| 1001 | + .nb_channels = 6, |
|---|
| 1002 | + .transfer_ord_max = 5, |
|---|
| 1003 | + .flags = JZ_SOC_DATA_PER_CHAN_PM | JZ_SOC_DATA_NO_DCKES_DCKEC | |
|---|
| 1004 | + JZ_SOC_DATA_BREAK_LINKS, |
|---|
| 1005 | +}; |
|---|
| 1006 | + |
|---|
| 1007 | +static const struct jz4780_dma_soc_data jz4770_dma_soc_data = { |
|---|
| 1008 | + .nb_channels = 6, |
|---|
| 1009 | + .transfer_ord_max = 6, |
|---|
| 1010 | + .flags = JZ_SOC_DATA_PER_CHAN_PM, |
|---|
| 1011 | +}; |
|---|
| 1012 | + |
|---|
| 1013 | +static const struct jz4780_dma_soc_data jz4780_dma_soc_data = { |
|---|
| 1014 | + .nb_channels = 32, |
|---|
| 1015 | + .transfer_ord_max = 7, |
|---|
| 1016 | + .flags = JZ_SOC_DATA_ALLOW_LEGACY_DT | JZ_SOC_DATA_PROGRAMMABLE_DMA, |
|---|
| 1017 | +}; |
|---|
| 1018 | + |
|---|
| 1019 | +static const struct jz4780_dma_soc_data x1000_dma_soc_data = { |
|---|
| 1020 | + .nb_channels = 8, |
|---|
| 1021 | + .transfer_ord_max = 7, |
|---|
| 1022 | + .flags = JZ_SOC_DATA_PROGRAMMABLE_DMA, |
|---|
| 1023 | +}; |
|---|
| 1024 | + |
|---|
| 1025 | +static const struct jz4780_dma_soc_data x1830_dma_soc_data = { |
|---|
| 1026 | + .nb_channels = 32, |
|---|
| 1027 | + .transfer_ord_max = 7, |
|---|
| 1028 | + .flags = JZ_SOC_DATA_PROGRAMMABLE_DMA, |
|---|
| 1029 | +}; |
|---|
| 1030 | + |
|---|
| 900 | 1031 | static const struct of_device_id jz4780_dma_dt_match[] = { |
|---|
| 901 | | - { .compatible = "ingenic,jz4780-dma", .data = NULL }, |
|---|
| 1032 | + { .compatible = "ingenic,jz4740-dma", .data = &jz4740_dma_soc_data }, |
|---|
| 1033 | + { .compatible = "ingenic,jz4725b-dma", .data = &jz4725b_dma_soc_data }, |
|---|
| 1034 | + { .compatible = "ingenic,jz4770-dma", .data = &jz4770_dma_soc_data }, |
|---|
| 1035 | + { .compatible = "ingenic,jz4780-dma", .data = &jz4780_dma_soc_data }, |
|---|
| 1036 | + { .compatible = "ingenic,x1000-dma", .data = &x1000_dma_soc_data }, |
|---|
| 1037 | + { .compatible = "ingenic,x1830-dma", .data = &x1830_dma_soc_data }, |
|---|
| 902 | 1038 | {}, |
|---|
| 903 | 1039 | }; |
|---|
| 904 | 1040 | MODULE_DEVICE_TABLE(of, jz4780_dma_dt_match); |
|---|