aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vkoul@kernel.org>2018-10-24 04:16:04 -0400
committerVinod Koul <vkoul@kernel.org>2018-10-24 04:16:04 -0400
commit81c3ee027e5d79eb184d2b225a67b06e9e5b9271 (patch)
tree93099f59b6ce49265b2ebd943fc6f42d05644e7f
parentb29cf44398a93ae6ea9122f9b722faad0d280981 (diff)
parentd426c517a7425dbd8e362051017b8acab20e8818 (diff)
Merge branch 'topic/jz' into for-linus
-rw-r--r--Documentation/devicetree/bindings/dma/jz4780-dma.txt14
-rw-r--r--arch/mips/boot/dts/ingenic/jz4740.dtsi15
-rw-r--r--arch/mips/boot/dts/ingenic/jz4770.dtsi30
-rw-r--r--arch/mips/boot/dts/ingenic/jz4780.dtsi3
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/dma-jz4780.c281
6 files changed, 261 insertions, 84 deletions
diff --git a/Documentation/devicetree/bindings/dma/jz4780-dma.txt b/Documentation/devicetree/bindings/dma/jz4780-dma.txt
index 03e9cf7b42e0..636fcb26b164 100644
--- a/Documentation/devicetree/bindings/dma/jz4780-dma.txt
+++ b/Documentation/devicetree/bindings/dma/jz4780-dma.txt
@@ -2,8 +2,13 @@
2 2
3Required properties: 3Required properties:
4 4
5- compatible: Should be "ingenic,jz4780-dma" 5- compatible: Should be one of:
6- reg: Should contain the DMA controller registers location and length. 6 * ingenic,jz4740-dma
7 * ingenic,jz4725b-dma
8 * ingenic,jz4770-dma
9 * ingenic,jz4780-dma
10- reg: Should contain the DMA channel registers location and length, followed
11 by the DMA controller registers location and length.
7- interrupts: Should contain the interrupt specifier of the DMA controller. 12- interrupts: Should contain the interrupt specifier of the DMA controller.
8- clocks: Should contain a clock specifier for the JZ4780 PDMA clock. 13- clocks: Should contain a clock specifier for the JZ4780 PDMA clock.
9- #dma-cells: Must be <2>. Number of integer cells in the dmas property of 14- #dma-cells: Must be <2>. Number of integer cells in the dmas property of
@@ -19,9 +24,10 @@ Optional properties:
19 24
20Example: 25Example:
21 26
22dma: dma@13420000 { 27dma: dma-controller@13420000 {
23 compatible = "ingenic,jz4780-dma"; 28 compatible = "ingenic,jz4780-dma";
24 reg = <0x13420000 0x10000>; 29 reg = <0x13420000 0x400
30 0x13421000 0x40>;
25 31
26 interrupt-parent = <&intc>; 32 interrupt-parent = <&intc>;
27 interrupts = <10>; 33 interrupts = <10>;
diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi
index 26c6b561d6f7..6fb16fd24035 100644
--- a/arch/mips/boot/dts/ingenic/jz4740.dtsi
+++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi
@@ -154,6 +154,21 @@
154 clock-names = "baud", "module"; 154 clock-names = "baud", "module";
155 }; 155 };
156 156
157 dmac: dma-controller@13020000 {
158 compatible = "ingenic,jz4740-dma";
159 reg = <0x13020000 0xbc
160 0x13020300 0x14>;
161 #dma-cells = <2>;
162
163 interrupt-parent = <&intc>;
164 interrupts = <29>;
165
166 clocks = <&cgu JZ4740_CLK_DMA>;
167
168 /* Disable dmac until we have something that uses it */
169 status = "disabled";
170 };
171
157 uhc: uhc@13030000 { 172 uhc: uhc@13030000 {
158 compatible = "ingenic,jz4740-ohci", "generic-ohci"; 173 compatible = "ingenic,jz4740-ohci", "generic-ohci";
159 reg = <0x13030000 0x1000>; 174 reg = <0x13030000 0x1000>;
diff --git a/arch/mips/boot/dts/ingenic/jz4770.dtsi b/arch/mips/boot/dts/ingenic/jz4770.dtsi
index 7c2804f3f5f1..49ede6c14ff3 100644
--- a/arch/mips/boot/dts/ingenic/jz4770.dtsi
+++ b/arch/mips/boot/dts/ingenic/jz4770.dtsi
@@ -196,6 +196,36 @@
196 status = "disabled"; 196 status = "disabled";
197 }; 197 };
198 198
199 dmac0: dma-controller@13420000 {
200 compatible = "ingenic,jz4770-dma";
201 reg = <0x13420000 0xC0
202 0x13420300 0x20>;
203
204 #dma-cells = <1>;
205
206 clocks = <&cgu JZ4770_CLK_DMA>;
207 interrupt-parent = <&intc>;
208 interrupts = <24>;
209
210 /* Disable dmac0 until we have something that uses it */
211 status = "disabled";
212 };
213
214 dmac1: dma-controller@13420100 {
215 compatible = "ingenic,jz4770-dma";
216 reg = <0x13420100 0xC0
217 0x13420400 0x20>;
218
219 #dma-cells = <1>;
220
221 clocks = <&cgu JZ4770_CLK_DMA>;
222 interrupt-parent = <&intc>;
223 interrupts = <23>;
224
225 /* Disable dmac1 until we have something that uses it */
226 status = "disabled";
227 };
228
199 uhc: uhc@13430000 { 229 uhc: uhc@13430000 {
200 compatible = "generic-ohci"; 230 compatible = "generic-ohci";
201 reg = <0x13430000 0x1000>; 231 reg = <0x13430000 0x1000>;
diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi
index ce93d57f1b4d..b03cdec56de9 100644
--- a/arch/mips/boot/dts/ingenic/jz4780.dtsi
+++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi
@@ -266,7 +266,8 @@
266 266
267 dma: dma@13420000 { 267 dma: dma@13420000 {
268 compatible = "ingenic,jz4780-dma"; 268 compatible = "ingenic,jz4780-dma";
269 reg = <0x13420000 0x10000>; 269 reg = <0x13420000 0x400
270 0x13421000 0x40>;
270 #dma-cells = <2>; 271 #dma-cells = <2>;
271 272
272 interrupt-parent = <&intc>; 273 interrupt-parent = <&intc>;
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 05104325d685..de511db021cc 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -143,7 +143,7 @@ config DMA_JZ4740
143 143
144config DMA_JZ4780 144config DMA_JZ4780
145 tristate "JZ4780 DMA support" 145 tristate "JZ4780 DMA support"
146 depends on MACH_JZ4780 || COMPILE_TEST 146 depends on MIPS || COMPILE_TEST
147 select DMA_ENGINE 147 select DMA_ENGINE
148 select DMA_VIRTUAL_CHANNELS 148 select DMA_VIRTUAL_CHANNELS
149 help 149 help
diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c
index b2a244902bc5..a8b6225faa12 100644
--- a/drivers/dma/dma-jz4780.c
+++ b/drivers/dma/dma-jz4780.c
@@ -16,6 +16,7 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/of.h> 18#include <linux/of.h>
19#include <linux/of_device.h>
19#include <linux/of_dma.h> 20#include <linux/of_dma.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
@@ -23,33 +24,35 @@
23#include "dmaengine.h" 24#include "dmaengine.h"
24#include "virt-dma.h" 25#include "virt-dma.h"
25 26
26#define JZ_DMA_NR_CHANNELS 32
27
28/* Global registers. */ 27/* Global registers. */
29#define JZ_DMA_REG_DMAC 0x1000 28#define JZ_DMA_REG_DMAC 0x00
30#define JZ_DMA_REG_DIRQP 0x1004 29#define JZ_DMA_REG_DIRQP 0x04
31#define JZ_DMA_REG_DDR 0x1008 30#define JZ_DMA_REG_DDR 0x08
32#define JZ_DMA_REG_DDRS 0x100c 31#define JZ_DMA_REG_DDRS 0x0c
33#define JZ_DMA_REG_DMACP 0x101c 32#define JZ_DMA_REG_DCKE 0x10
34#define JZ_DMA_REG_DSIRQP 0x1020 33#define JZ_DMA_REG_DCKES 0x14
35#define JZ_DMA_REG_DSIRQM 0x1024 34#define JZ_DMA_REG_DCKEC 0x18
36#define JZ_DMA_REG_DCIRQP 0x1028 35#define JZ_DMA_REG_DMACP 0x1c
37#define JZ_DMA_REG_DCIRQM 0x102c 36#define JZ_DMA_REG_DSIRQP 0x20
37#define JZ_DMA_REG_DSIRQM 0x24
38#define JZ_DMA_REG_DCIRQP 0x28
39#define JZ_DMA_REG_DCIRQM 0x2c
38 40
39/* Per-channel registers. */ 41/* Per-channel registers. */
40#define JZ_DMA_REG_CHAN(n) (n * 0x20) 42#define JZ_DMA_REG_CHAN(n) (n * 0x20)
41#define JZ_DMA_REG_DSA(n) (0x00 + JZ_DMA_REG_CHAN(n)) 43#define JZ_DMA_REG_DSA 0x00
42#define JZ_DMA_REG_DTA(n) (0x04 + JZ_DMA_REG_CHAN(n)) 44#define JZ_DMA_REG_DTA 0x04
43#define JZ_DMA_REG_DTC(n) (0x08 + JZ_DMA_REG_CHAN(n)) 45#define JZ_DMA_REG_DTC 0x08
44#define JZ_DMA_REG_DRT(n) (0x0c + JZ_DMA_REG_CHAN(n)) 46#define JZ_DMA_REG_DRT 0x0c
45#define JZ_DMA_REG_DCS(n) (0x10 + JZ_DMA_REG_CHAN(n)) 47#define JZ_DMA_REG_DCS 0x10
46#define JZ_DMA_REG_DCM(n) (0x14 + JZ_DMA_REG_CHAN(n)) 48#define JZ_DMA_REG_DCM 0x14
47#define JZ_DMA_REG_DDA(n) (0x18 + JZ_DMA_REG_CHAN(n)) 49#define JZ_DMA_REG_DDA 0x18
48#define JZ_DMA_REG_DSD(n) (0x1c + JZ_DMA_REG_CHAN(n)) 50#define JZ_DMA_REG_DSD 0x1c
49 51
50#define JZ_DMA_DMAC_DMAE BIT(0) 52#define JZ_DMA_DMAC_DMAE BIT(0)
51#define JZ_DMA_DMAC_AR BIT(2) 53#define JZ_DMA_DMAC_AR BIT(2)
52#define JZ_DMA_DMAC_HLT BIT(3) 54#define JZ_DMA_DMAC_HLT BIT(3)
55#define JZ_DMA_DMAC_FAIC BIT(27)
53#define JZ_DMA_DMAC_FMSC BIT(31) 56#define JZ_DMA_DMAC_FMSC BIT(31)
54 57
55#define JZ_DMA_DRT_AUTO 0x8 58#define JZ_DMA_DRT_AUTO 0x8
@@ -86,6 +89,14 @@
86 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ 89 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
87 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)) 90 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
88 91
92#define JZ4780_DMA_CTRL_OFFSET 0x1000
93
94/* macros for use with jz4780_dma_soc_data.flags */
95#define JZ_SOC_DATA_ALLOW_LEGACY_DT BIT(0)
96#define JZ_SOC_DATA_PROGRAMMABLE_DMA BIT(1)
97#define JZ_SOC_DATA_PER_CHAN_PM BIT(2)
98#define JZ_SOC_DATA_NO_DCKES_DCKEC BIT(3)
99
89/** 100/**
90 * struct jz4780_dma_hwdesc - descriptor structure read by the DMA controller. 101 * struct jz4780_dma_hwdesc - descriptor structure read by the DMA controller.
91 * @dcm: value for the DCM (channel command) register 102 * @dcm: value for the DCM (channel command) register
@@ -94,17 +105,12 @@
94 * @dtc: transfer count (number of blocks of the transfer size specified in DCM 105 * @dtc: transfer count (number of blocks of the transfer size specified in DCM
95 * to transfer) in the low 24 bits, offset of the next descriptor from the 106 * to transfer) in the low 24 bits, offset of the next descriptor from the
96 * descriptor base address in the upper 8 bits. 107 * descriptor base address in the upper 8 bits.
97 * @sd: target/source stride difference (in stride transfer mode).
98 * @drt: request type
99 */ 108 */
100struct jz4780_dma_hwdesc { 109struct jz4780_dma_hwdesc {
101 uint32_t dcm; 110 uint32_t dcm;
102 uint32_t dsa; 111 uint32_t dsa;
103 uint32_t dta; 112 uint32_t dta;
104 uint32_t dtc; 113 uint32_t dtc;
105 uint32_t sd;
106 uint32_t drt;
107 uint32_t reserved[2];
108}; 114};
109 115
110/* Size of allocations for hardware descriptor blocks. */ 116/* Size of allocations for hardware descriptor blocks. */
@@ -135,14 +141,22 @@ struct jz4780_dma_chan {
135 unsigned int curr_hwdesc; 141 unsigned int curr_hwdesc;
136}; 142};
137 143
144struct jz4780_dma_soc_data {
145 unsigned int nb_channels;
146 unsigned int transfer_ord_max;
147 unsigned long flags;
148};
149
138struct jz4780_dma_dev { 150struct jz4780_dma_dev {
139 struct dma_device dma_device; 151 struct dma_device dma_device;
140 void __iomem *base; 152 void __iomem *chn_base;
153 void __iomem *ctrl_base;
141 struct clk *clk; 154 struct clk *clk;
142 unsigned int irq; 155 unsigned int irq;
156 const struct jz4780_dma_soc_data *soc_data;
143 157
144 uint32_t chan_reserved; 158 uint32_t chan_reserved;
145 struct jz4780_dma_chan chan[JZ_DMA_NR_CHANNELS]; 159 struct jz4780_dma_chan chan[];
146}; 160};
147 161
148struct jz4780_dma_filter_data { 162struct jz4780_dma_filter_data {
@@ -169,16 +183,51 @@ static inline struct jz4780_dma_dev *jz4780_dma_chan_parent(
169 dma_device); 183 dma_device);
170} 184}
171 185
172static inline uint32_t jz4780_dma_readl(struct jz4780_dma_dev *jzdma, 186static inline uint32_t jz4780_dma_chn_readl(struct jz4780_dma_dev *jzdma,
187 unsigned int chn, unsigned int reg)
188{
189 return readl(jzdma->chn_base + reg + JZ_DMA_REG_CHAN(chn));
190}
191
192static inline void jz4780_dma_chn_writel(struct jz4780_dma_dev *jzdma,
193 unsigned int chn, unsigned int reg, uint32_t val)
194{
195 writel(val, jzdma->chn_base + reg + JZ_DMA_REG_CHAN(chn));
196}
197
198static inline uint32_t jz4780_dma_ctrl_readl(struct jz4780_dma_dev *jzdma,
173 unsigned int reg) 199 unsigned int reg)
174{ 200{
175 return readl(jzdma->base + reg); 201 return readl(jzdma->ctrl_base + reg);
176} 202}
177 203
178static inline void jz4780_dma_writel(struct jz4780_dma_dev *jzdma, 204static inline void jz4780_dma_ctrl_writel(struct jz4780_dma_dev *jzdma,
179 unsigned int reg, uint32_t val) 205 unsigned int reg, uint32_t val)
180{ 206{
181 writel(val, jzdma->base + reg); 207 writel(val, jzdma->ctrl_base + reg);
208}
209
210static inline void jz4780_dma_chan_enable(struct jz4780_dma_dev *jzdma,
211 unsigned int chn)
212{
213 if (jzdma->soc_data->flags & JZ_SOC_DATA_PER_CHAN_PM) {
214 unsigned int reg;
215
216 if (jzdma->soc_data->flags & JZ_SOC_DATA_NO_DCKES_DCKEC)
217 reg = JZ_DMA_REG_DCKE;
218 else
219 reg = JZ_DMA_REG_DCKES;
220
221 jz4780_dma_ctrl_writel(jzdma, reg, BIT(chn));
222 }
223}
224
225static inline void jz4780_dma_chan_disable(struct jz4780_dma_dev *jzdma,
226 unsigned int chn)
227{
228 if ((jzdma->soc_data->flags & JZ_SOC_DATA_PER_CHAN_PM) &&
229 !(jzdma->soc_data->flags & JZ_SOC_DATA_NO_DCKES_DCKEC))
230 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DCKEC, BIT(chn));
182} 231}
183 232
184static struct jz4780_dma_desc *jz4780_dma_desc_alloc( 233static struct jz4780_dma_desc *jz4780_dma_desc_alloc(
@@ -215,8 +264,10 @@ static void jz4780_dma_desc_free(struct virt_dma_desc *vdesc)
215 kfree(desc); 264 kfree(desc);
216} 265}
217 266
218static uint32_t jz4780_dma_transfer_size(unsigned long val, uint32_t *shift) 267static uint32_t jz4780_dma_transfer_size(struct jz4780_dma_chan *jzchan,
268 unsigned long val, uint32_t *shift)
219{ 269{
270 struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan);
220 int ord = ffs(val) - 1; 271 int ord = ffs(val) - 1;
221 272
222 /* 273 /*
@@ -228,8 +279,8 @@ static uint32_t jz4780_dma_transfer_size(unsigned long val, uint32_t *shift)
228 */ 279 */
229 if (ord == 3) 280 if (ord == 3)
230 ord = 2; 281 ord = 2;
231 else if (ord > 7) 282 else if (ord > jzdma->soc_data->transfer_ord_max)
232 ord = 7; 283 ord = jzdma->soc_data->transfer_ord_max;
233 284
234 *shift = ord; 285 *shift = ord;
235 286
@@ -262,7 +313,6 @@ static int jz4780_dma_setup_hwdesc(struct jz4780_dma_chan *jzchan,
262 desc->dcm = JZ_DMA_DCM_SAI; 313 desc->dcm = JZ_DMA_DCM_SAI;
263 desc->dsa = addr; 314 desc->dsa = addr;
264 desc->dta = config->dst_addr; 315 desc->dta = config->dst_addr;
265 desc->drt = jzchan->transfer_type;
266 316
267 width = config->dst_addr_width; 317 width = config->dst_addr_width;
268 maxburst = config->dst_maxburst; 318 maxburst = config->dst_maxburst;
@@ -270,7 +320,6 @@ static int jz4780_dma_setup_hwdesc(struct jz4780_dma_chan *jzchan,
270 desc->dcm = JZ_DMA_DCM_DAI; 320 desc->dcm = JZ_DMA_DCM_DAI;
271 desc->dsa = config->src_addr; 321 desc->dsa = config->src_addr;
272 desc->dta = addr; 322 desc->dta = addr;
273 desc->drt = jzchan->transfer_type;
274 323
275 width = config->src_addr_width; 324 width = config->src_addr_width;
276 maxburst = config->src_maxburst; 325 maxburst = config->src_maxburst;
@@ -283,7 +332,7 @@ static int jz4780_dma_setup_hwdesc(struct jz4780_dma_chan *jzchan,
283 * divisible by the transfer size, and we must not use more than the 332 * divisible by the transfer size, and we must not use more than the
284 * maximum burst specified by the user. 333 * maximum burst specified by the user.
285 */ 334 */
286 tsz = jz4780_dma_transfer_size(addr | len | (width * maxburst), 335 tsz = jz4780_dma_transfer_size(jzchan, addr | len | (width * maxburst),
287 &jzchan->transfer_shift); 336 &jzchan->transfer_shift);
288 337
289 switch (width) { 338 switch (width) {
@@ -412,12 +461,13 @@ static struct dma_async_tx_descriptor *jz4780_dma_prep_dma_memcpy(
412 if (!desc) 461 if (!desc)
413 return NULL; 462 return NULL;
414 463
415 tsz = jz4780_dma_transfer_size(dest | src | len, 464 tsz = jz4780_dma_transfer_size(jzchan, dest | src | len,
416 &jzchan->transfer_shift); 465 &jzchan->transfer_shift);
417 466
467 jzchan->transfer_type = JZ_DMA_DRT_AUTO;
468
418 desc->desc[0].dsa = src; 469 desc->desc[0].dsa = src;
419 desc->desc[0].dta = dest; 470 desc->desc[0].dta = dest;
420 desc->desc[0].drt = JZ_DMA_DRT_AUTO;
421 desc->desc[0].dcm = JZ_DMA_DCM_TIE | JZ_DMA_DCM_SAI | JZ_DMA_DCM_DAI | 471 desc->desc[0].dcm = JZ_DMA_DCM_TIE | JZ_DMA_DCM_SAI | JZ_DMA_DCM_DAI |
422 tsz << JZ_DMA_DCM_TSZ_SHIFT | 472 tsz << JZ_DMA_DCM_TSZ_SHIFT |
423 JZ_DMA_WIDTH_32_BIT << JZ_DMA_DCM_SP_SHIFT | 473 JZ_DMA_WIDTH_32_BIT << JZ_DMA_DCM_SP_SHIFT |
@@ -472,18 +522,34 @@ static void jz4780_dma_begin(struct jz4780_dma_chan *jzchan)
472 (jzchan->curr_hwdesc + 1) % jzchan->desc->count; 522 (jzchan->curr_hwdesc + 1) % jzchan->desc->count;
473 } 523 }
474 524
475 /* Use 8-word descriptors. */ 525 /* Enable the channel's clock. */
476 jz4780_dma_writel(jzdma, JZ_DMA_REG_DCS(jzchan->id), JZ_DMA_DCS_DES8); 526 jz4780_dma_chan_enable(jzdma, jzchan->id);
527
528 /* Use 4-word descriptors. */
529 jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, 0);
530
531 /* Set transfer type. */
532 jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DRT,
533 jzchan->transfer_type);
534
535 /*
536 * Set the transfer count. This is redundant for a descriptor-driven
537 * transfer. However, there can be a delay between the transfer start
538 * time and when DTCn reg contains the new transfer count. Setting
539 * it explicitly ensures residue is computed correctly at all times.
540 */
541 jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DTC,
542 jzchan->desc->desc[jzchan->curr_hwdesc].dtc);
477 543
478 /* Write descriptor address and initiate descriptor fetch. */ 544 /* Write descriptor address and initiate descriptor fetch. */
479 desc_phys = jzchan->desc->desc_phys + 545 desc_phys = jzchan->desc->desc_phys +
480 (jzchan->curr_hwdesc * sizeof(*jzchan->desc->desc)); 546 (jzchan->curr_hwdesc * sizeof(*jzchan->desc->desc));
481 jz4780_dma_writel(jzdma, JZ_DMA_REG_DDA(jzchan->id), desc_phys); 547 jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DDA, desc_phys);
482 jz4780_dma_writel(jzdma, JZ_DMA_REG_DDRS, BIT(jzchan->id)); 548 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DDRS, BIT(jzchan->id));
483 549
484 /* Enable the channel. */ 550 /* Enable the channel. */
485 jz4780_dma_writel(jzdma, JZ_DMA_REG_DCS(jzchan->id), 551 jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS,
486 JZ_DMA_DCS_DES8 | JZ_DMA_DCS_CTE); 552 JZ_DMA_DCS_CTE);
487} 553}
488 554
489static void jz4780_dma_issue_pending(struct dma_chan *chan) 555static void jz4780_dma_issue_pending(struct dma_chan *chan)
@@ -509,12 +575,14 @@ static int jz4780_dma_terminate_all(struct dma_chan *chan)
509 spin_lock_irqsave(&jzchan->vchan.lock, flags); 575 spin_lock_irqsave(&jzchan->vchan.lock, flags);
510 576
511 /* Clear the DMA status and stop the transfer. */ 577 /* Clear the DMA status and stop the transfer. */
512 jz4780_dma_writel(jzdma, JZ_DMA_REG_DCS(jzchan->id), 0); 578 jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, 0);
513 if (jzchan->desc) { 579 if (jzchan->desc) {
514 vchan_terminate_vdesc(&jzchan->desc->vdesc); 580 vchan_terminate_vdesc(&jzchan->desc->vdesc);
515 jzchan->desc = NULL; 581 jzchan->desc = NULL;
516 } 582 }
517 583
584 jz4780_dma_chan_disable(jzdma, jzchan->id);
585
518 vchan_get_all_descriptors(&jzchan->vchan, &head); 586 vchan_get_all_descriptors(&jzchan->vchan, &head);
519 587
520 spin_unlock_irqrestore(&jzchan->vchan.lock, flags); 588 spin_unlock_irqrestore(&jzchan->vchan.lock, flags);
@@ -526,8 +594,10 @@ static int jz4780_dma_terminate_all(struct dma_chan *chan)
526static void jz4780_dma_synchronize(struct dma_chan *chan) 594static void jz4780_dma_synchronize(struct dma_chan *chan)
527{ 595{
528 struct jz4780_dma_chan *jzchan = to_jz4780_dma_chan(chan); 596 struct jz4780_dma_chan *jzchan = to_jz4780_dma_chan(chan);
597 struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan);
529 598
530 vchan_synchronize(&jzchan->vchan); 599 vchan_synchronize(&jzchan->vchan);
600 jz4780_dma_chan_disable(jzdma, jzchan->id);
531} 601}
532 602
533static int jz4780_dma_config(struct dma_chan *chan, 603static int jz4780_dma_config(struct dma_chan *chan,
@@ -549,21 +619,17 @@ static size_t jz4780_dma_desc_residue(struct jz4780_dma_chan *jzchan,
549 struct jz4780_dma_desc *desc, unsigned int next_sg) 619 struct jz4780_dma_desc *desc, unsigned int next_sg)
550{ 620{
551 struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan); 621 struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan);
552 unsigned int residue, count; 622 unsigned int count = 0;
553 unsigned int i; 623 unsigned int i;
554 624
555 residue = 0;
556
557 for (i = next_sg; i < desc->count; i++) 625 for (i = next_sg; i < desc->count; i++)
558 residue += desc->desc[i].dtc << jzchan->transfer_shift; 626 count += desc->desc[i].dtc & GENMASK(23, 0);
559 627
560 if (next_sg != 0) { 628 if (next_sg != 0)
561 count = jz4780_dma_readl(jzdma, 629 count += jz4780_dma_chn_readl(jzdma, jzchan->id,
562 JZ_DMA_REG_DTC(jzchan->id)); 630 JZ_DMA_REG_DTC);
563 residue += count << jzchan->transfer_shift;
564 }
565 631
566 return residue; 632 return count << jzchan->transfer_shift;
567} 633}
568 634
569static enum dma_status jz4780_dma_tx_status(struct dma_chan *chan, 635static enum dma_status jz4780_dma_tx_status(struct dma_chan *chan,
@@ -573,6 +639,7 @@ static enum dma_status jz4780_dma_tx_status(struct dma_chan *chan,
573 struct virt_dma_desc *vdesc; 639 struct virt_dma_desc *vdesc;
574 enum dma_status status; 640 enum dma_status status;
575 unsigned long flags; 641 unsigned long flags;
642 unsigned long residue = 0;
576 643
577 status = dma_cookie_status(chan, cookie, txstate); 644 status = dma_cookie_status(chan, cookie, txstate);
578 if ((status == DMA_COMPLETE) || (txstate == NULL)) 645 if ((status == DMA_COMPLETE) || (txstate == NULL))
@@ -583,13 +650,13 @@ static enum dma_status jz4780_dma_tx_status(struct dma_chan *chan,
583 vdesc = vchan_find_desc(&jzchan->vchan, cookie); 650 vdesc = vchan_find_desc(&jzchan->vchan, cookie);
584 if (vdesc) { 651 if (vdesc) {
585 /* On the issued list, so hasn't been processed yet */ 652 /* On the issued list, so hasn't been processed yet */
586 txstate->residue = jz4780_dma_desc_residue(jzchan, 653 residue = jz4780_dma_desc_residue(jzchan,
587 to_jz4780_dma_desc(vdesc), 0); 654 to_jz4780_dma_desc(vdesc), 0);
588 } else if (cookie == jzchan->desc->vdesc.tx.cookie) { 655 } else if (cookie == jzchan->desc->vdesc.tx.cookie) {
589 txstate->residue = jz4780_dma_desc_residue(jzchan, jzchan->desc, 656 residue = jz4780_dma_desc_residue(jzchan, jzchan->desc,
590 (jzchan->curr_hwdesc + 1) % jzchan->desc->count); 657 jzchan->curr_hwdesc + 1);
591 } else 658 }
592 txstate->residue = 0; 659 dma_set_residue(txstate, residue);
593 660
594 if (vdesc && jzchan->desc && vdesc == &jzchan->desc->vdesc 661 if (vdesc && jzchan->desc && vdesc == &jzchan->desc->vdesc
595 && jzchan->desc->status & (JZ_DMA_DCS_AR | JZ_DMA_DCS_HLT)) 662 && jzchan->desc->status & (JZ_DMA_DCS_AR | JZ_DMA_DCS_HLT))
@@ -606,8 +673,8 @@ static void jz4780_dma_chan_irq(struct jz4780_dma_dev *jzdma,
606 673
607 spin_lock(&jzchan->vchan.lock); 674 spin_lock(&jzchan->vchan.lock);
608 675
609 dcs = jz4780_dma_readl(jzdma, JZ_DMA_REG_DCS(jzchan->id)); 676 dcs = jz4780_dma_chn_readl(jzdma, jzchan->id, JZ_DMA_REG_DCS);
610 jz4780_dma_writel(jzdma, JZ_DMA_REG_DCS(jzchan->id), 0); 677 jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, 0);
611 678
612 if (dcs & JZ_DMA_DCS_AR) { 679 if (dcs & JZ_DMA_DCS_AR) {
613 dev_warn(&jzchan->vchan.chan.dev->device, 680 dev_warn(&jzchan->vchan.chan.dev->device,
@@ -646,9 +713,9 @@ static irqreturn_t jz4780_dma_irq_handler(int irq, void *data)
646 uint32_t pending, dmac; 713 uint32_t pending, dmac;
647 int i; 714 int i;
648 715
649 pending = jz4780_dma_readl(jzdma, JZ_DMA_REG_DIRQP); 716 pending = jz4780_dma_ctrl_readl(jzdma, JZ_DMA_REG_DIRQP);
650 717
651 for (i = 0; i < JZ_DMA_NR_CHANNELS; i++) { 718 for (i = 0; i < jzdma->soc_data->nb_channels; i++) {
652 if (!(pending & (1<<i))) 719 if (!(pending & (1<<i)))
653 continue; 720 continue;
654 721
@@ -656,12 +723,12 @@ static irqreturn_t jz4780_dma_irq_handler(int irq, void *data)
656 } 723 }
657 724
658 /* Clear halt and address error status of all channels. */ 725 /* Clear halt and address error status of all channels. */
659 dmac = jz4780_dma_readl(jzdma, JZ_DMA_REG_DMAC); 726 dmac = jz4780_dma_ctrl_readl(jzdma, JZ_DMA_REG_DMAC);
660 dmac &= ~(JZ_DMA_DMAC_HLT | JZ_DMA_DMAC_AR); 727 dmac &= ~(JZ_DMA_DMAC_HLT | JZ_DMA_DMAC_AR);
661 jz4780_dma_writel(jzdma, JZ_DMA_REG_DMAC, dmac); 728 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMAC, dmac);
662 729
663 /* Clear interrupt pending status. */ 730 /* Clear interrupt pending status. */
664 jz4780_dma_writel(jzdma, JZ_DMA_REG_DIRQP, 0); 731 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DIRQP, 0);
665 732
666 return IRQ_HANDLED; 733 return IRQ_HANDLED;
667} 734}
@@ -728,7 +795,7 @@ static struct dma_chan *jz4780_of_dma_xlate(struct of_phandle_args *dma_spec,
728 data.channel = dma_spec->args[1]; 795 data.channel = dma_spec->args[1];
729 796
730 if (data.channel > -1) { 797 if (data.channel > -1) {
731 if (data.channel >= JZ_DMA_NR_CHANNELS) { 798 if (data.channel >= jzdma->soc_data->nb_channels) {
732 dev_err(jzdma->dma_device.dev, 799 dev_err(jzdma->dma_device.dev,
733 "device requested non-existent channel %u\n", 800 "device requested non-existent channel %u\n",
734 data.channel); 801 data.channel);
@@ -755,16 +822,29 @@ static struct dma_chan *jz4780_of_dma_xlate(struct of_phandle_args *dma_spec,
755static int jz4780_dma_probe(struct platform_device *pdev) 822static int jz4780_dma_probe(struct platform_device *pdev)
756{ 823{
757 struct device *dev = &pdev->dev; 824 struct device *dev = &pdev->dev;
825 const struct jz4780_dma_soc_data *soc_data;
758 struct jz4780_dma_dev *jzdma; 826 struct jz4780_dma_dev *jzdma;
759 struct jz4780_dma_chan *jzchan; 827 struct jz4780_dma_chan *jzchan;
760 struct dma_device *dd; 828 struct dma_device *dd;
761 struct resource *res; 829 struct resource *res;
762 int i, ret; 830 int i, ret;
763 831
764 jzdma = devm_kzalloc(dev, sizeof(*jzdma), GFP_KERNEL); 832 if (!dev->of_node) {
833 dev_err(dev, "This driver must be probed from devicetree\n");
834 return -EINVAL;
835 }
836
837 soc_data = device_get_match_data(dev);
838 if (!soc_data)
839 return -EINVAL;
840
841 jzdma = devm_kzalloc(dev, sizeof(*jzdma)
842 + sizeof(*jzdma->chan) * soc_data->nb_channels,
843 GFP_KERNEL);
765 if (!jzdma) 844 if (!jzdma)
766 return -ENOMEM; 845 return -ENOMEM;
767 846
847 jzdma->soc_data = soc_data;
768 platform_set_drvdata(pdev, jzdma); 848 platform_set_drvdata(pdev, jzdma);
769 849
770 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 850 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -773,9 +853,26 @@ static int jz4780_dma_probe(struct platform_device *pdev)
773 return -EINVAL; 853 return -EINVAL;
774 } 854 }
775 855
776 jzdma->base = devm_ioremap_resource(dev, res); 856 jzdma->chn_base = devm_ioremap_resource(dev, res);
777 if (IS_ERR(jzdma->base)) 857 if (IS_ERR(jzdma->chn_base))
778 return PTR_ERR(jzdma->base); 858 return PTR_ERR(jzdma->chn_base);
859
860 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
861 if (res) {
862 jzdma->ctrl_base = devm_ioremap_resource(dev, res);
863 if (IS_ERR(jzdma->ctrl_base))
864 return PTR_ERR(jzdma->ctrl_base);
865 } else if (soc_data->flags & JZ_SOC_DATA_ALLOW_LEGACY_DT) {
866 /*
867 * On JZ4780, if the second memory resource was not supplied,
868 * assume we're using an old devicetree, and calculate the
869 * offset to the control registers.
870 */
871 jzdma->ctrl_base = jzdma->chn_base + JZ4780_DMA_CTRL_OFFSET;
872 } else {
873 dev_err(dev, "failed to get I/O memory\n");
874 return -EINVAL;
875 }
779 876
780 ret = platform_get_irq(pdev, 0); 877 ret = platform_get_irq(pdev, 0);
781 if (ret < 0) { 878 if (ret < 0) {
@@ -833,13 +930,15 @@ static int jz4780_dma_probe(struct platform_device *pdev)
833 * Also set the FMSC bit - it increases MSC performance, so it makes 930 * Also set the FMSC bit - it increases MSC performance, so it makes
834 * little sense not to enable it. 931 * little sense not to enable it.
835 */ 932 */
836 jz4780_dma_writel(jzdma, JZ_DMA_REG_DMAC, 933 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMAC, JZ_DMA_DMAC_DMAE |
837 JZ_DMA_DMAC_DMAE | JZ_DMA_DMAC_FMSC); 934 JZ_DMA_DMAC_FAIC | JZ_DMA_DMAC_FMSC);
838 jz4780_dma_writel(jzdma, JZ_DMA_REG_DMACP, 0); 935
936 if (soc_data->flags & JZ_SOC_DATA_PROGRAMMABLE_DMA)
937 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMACP, 0);
839 938
840 INIT_LIST_HEAD(&dd->channels); 939 INIT_LIST_HEAD(&dd->channels);
841 940
842 for (i = 0; i < JZ_DMA_NR_CHANNELS; i++) { 941 for (i = 0; i < soc_data->nb_channels; i++) {
843 jzchan = &jzdma->chan[i]; 942 jzchan = &jzdma->chan[i];
844 jzchan->id = i; 943 jzchan->id = i;
845 944
@@ -881,14 +980,40 @@ static int jz4780_dma_remove(struct platform_device *pdev)
881 980
882 free_irq(jzdma->irq, jzdma); 981 free_irq(jzdma->irq, jzdma);
883 982
884 for (i = 0; i < JZ_DMA_NR_CHANNELS; i++) 983 for (i = 0; i < jzdma->soc_data->nb_channels; i++)
885 tasklet_kill(&jzdma->chan[i].vchan.task); 984 tasklet_kill(&jzdma->chan[i].vchan.task);
886 985
887 return 0; 986 return 0;
888} 987}
889 988
989static const struct jz4780_dma_soc_data jz4740_dma_soc_data = {
990 .nb_channels = 6,
991 .transfer_ord_max = 5,
992};
993
994static const struct jz4780_dma_soc_data jz4725b_dma_soc_data = {
995 .nb_channels = 6,
996 .transfer_ord_max = 5,
997 .flags = JZ_SOC_DATA_PER_CHAN_PM | JZ_SOC_DATA_NO_DCKES_DCKEC,
998};
999
1000static const struct jz4780_dma_soc_data jz4770_dma_soc_data = {
1001 .nb_channels = 6,
1002 .transfer_ord_max = 6,
1003 .flags = JZ_SOC_DATA_PER_CHAN_PM,
1004};
1005
1006static const struct jz4780_dma_soc_data jz4780_dma_soc_data = {
1007 .nb_channels = 32,
1008 .transfer_ord_max = 7,
1009 .flags = JZ_SOC_DATA_ALLOW_LEGACY_DT | JZ_SOC_DATA_PROGRAMMABLE_DMA,
1010};
1011
890static const struct of_device_id jz4780_dma_dt_match[] = { 1012static const struct of_device_id jz4780_dma_dt_match[] = {
891 { .compatible = "ingenic,jz4780-dma", .data = NULL }, 1013 { .compatible = "ingenic,jz4740-dma", .data = &jz4740_dma_soc_data },
1014 { .compatible = "ingenic,jz4725b-dma", .data = &jz4725b_dma_soc_data },
1015 { .compatible = "ingenic,jz4770-dma", .data = &jz4770_dma_soc_data },
1016 { .compatible = "ingenic,jz4780-dma", .data = &jz4780_dma_soc_data },
892 {}, 1017 {},
893}; 1018};
894MODULE_DEVICE_TABLE(of, jz4780_dma_dt_match); 1019MODULE_DEVICE_TABLE(of, jz4780_dma_dt_match);