diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-17 12:55:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-17 12:55:43 -0400 |
commit | 47ebe00b684c2bc183a766bc33c8b5943bc0df85 (patch) | |
tree | c0f155acc5623f6990d20b7a623f48f5e7aa0f61 /drivers/dma/sun6i-dma.c | |
parent | fa121bb3fed6313b1f0af23952301e06cf6d32ed (diff) | |
parent | 5c274ca4cfb22a455e880f61536b1894fa29fd17 (diff) |
Merge tag 'dmaengine-5.3-rc1' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine updates from Vinod Koul:
- Add support in dmaengine core to do device node checks for DT devices
and update bunch of drivers to use that and remove open coding from
drivers
- New driver/driver support for new hardware, namely:
- MediaTek UART APDMA
- Freescale i.mx7ulp edma2
- Synopsys eDMA IP core version 0
- Allwinner H6 DMA
- Updates to axi-dma and support for interleaved cyclic transfers
- Greg's debugfs return value check removals on drivers
- Updates to stm32-dma, hsu, dw, pl330, tegra drivers
* tag 'dmaengine-5.3-rc1' of git://git.infradead.org/users/vkoul/slave-dma: (68 commits)
dmaengine: Revert "dmaengine: fsl-edma: add i.mx7ulp edma2 version support"
dmaengine: at_xdmac: check for non-empty xfers_list before invoking callback
Documentation: dmaengine: clean up description of dmatest usage
dmaengine: tegra210-adma: remove PM_CLK dependency
dmaengine: fsl-edma: add i.mx7ulp edma2 version support
dt-bindings: dma: fsl-edma: add new i.mx7ulp-edma
dmaengine: fsl-edma-common: version check for v2 instead
dmaengine: fsl-edma-common: move dmamux register to another single function
dmaengine: fsl-edma: add drvdata for fsl-edma
dmaengine: Revert "dmaengine: fsl-edma: support little endian for edma driver"
dmaengine: rcar-dmac: Reject zero-length slave DMA requests
dmaengine: dw: Enable iDMA 32-bit on Intel Elkhart Lake
dmaengine: dw-edma: fix semicolon.cocci warnings
dmaengine: sh: usb-dmac: Use [] to denote a flexible array member
dmaengine: dmatest: timeout value of -1 should specify infinite wait
dmaengine: dw: Distinguish ->remove() between DW and iDMA 32-bit
dmaengine: fsl-edma: support little endian for edma driver
dmaengine: hsu: Revert "set HSU_CH_MTSR to memory width"
dmagengine: pl330: add code to get reset property
dt-bindings: pl330: document the optional resets property
...
Diffstat (limited to 'drivers/dma/sun6i-dma.c')
-rw-r--r-- | drivers/dma/sun6i-dma.c | 147 |
1 files changed, 112 insertions, 35 deletions
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index e8fcc69b1de9..ed5b68dcfe50 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c | |||
@@ -64,17 +64,20 @@ | |||
64 | #define DMA_CHAN_LLI_ADDR 0x08 | 64 | #define DMA_CHAN_LLI_ADDR 0x08 |
65 | 65 | ||
66 | #define DMA_CHAN_CUR_CFG 0x0c | 66 | #define DMA_CHAN_CUR_CFG 0x0c |
67 | #define DMA_CHAN_MAX_DRQ 0x1f | 67 | #define DMA_CHAN_MAX_DRQ_A31 0x1f |
68 | #define DMA_CHAN_CFG_SRC_DRQ(x) ((x) & DMA_CHAN_MAX_DRQ) | 68 | #define DMA_CHAN_MAX_DRQ_H6 0x3f |
69 | #define DMA_CHAN_CFG_SRC_IO_MODE BIT(5) | 69 | #define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) |
70 | #define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5) | 70 | #define DMA_CHAN_CFG_SRC_DRQ_H6(x) ((x) & DMA_CHAN_MAX_DRQ_H6) |
71 | #define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5) | ||
72 | #define DMA_CHAN_CFG_SRC_MODE_H6(x) (((x) & 0x1) << 8) | ||
71 | #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) | 73 | #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) |
72 | #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) | 74 | #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) |
73 | #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) | 75 | #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) |
74 | 76 | ||
75 | #define DMA_CHAN_CFG_DST_DRQ(x) (DMA_CHAN_CFG_SRC_DRQ(x) << 16) | 77 | #define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) |
76 | #define DMA_CHAN_CFG_DST_IO_MODE (DMA_CHAN_CFG_SRC_IO_MODE << 16) | 78 | #define DMA_CHAN_CFG_DST_DRQ_H6(x) (DMA_CHAN_CFG_SRC_DRQ_H6(x) << 16) |
77 | #define DMA_CHAN_CFG_DST_LINEAR_MODE (DMA_CHAN_CFG_SRC_LINEAR_MODE << 16) | 79 | #define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16) |
80 | #define DMA_CHAN_CFG_DST_MODE_H6(x) (DMA_CHAN_CFG_SRC_MODE_H6(x) << 16) | ||
78 | #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) | 81 | #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) |
79 | #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16) | 82 | #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16) |
80 | #define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16) | 83 | #define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16) |
@@ -94,6 +97,8 @@ | |||
94 | #define LLI_LAST_ITEM 0xfffff800 | 97 | #define LLI_LAST_ITEM 0xfffff800 |
95 | #define NORMAL_WAIT 8 | 98 | #define NORMAL_WAIT 8 |
96 | #define DRQ_SDRAM 1 | 99 | #define DRQ_SDRAM 1 |
100 | #define LINEAR_MODE 0 | ||
101 | #define IO_MODE 1 | ||
97 | 102 | ||
98 | /* forward declaration */ | 103 | /* forward declaration */ |
99 | struct sun6i_dma_dev; | 104 | struct sun6i_dma_dev; |
@@ -121,10 +126,13 @@ struct sun6i_dma_config { | |||
121 | */ | 126 | */ |
122 | void (*clock_autogate_enable)(struct sun6i_dma_dev *); | 127 | void (*clock_autogate_enable)(struct sun6i_dma_dev *); |
123 | void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst); | 128 | void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst); |
129 | void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq); | ||
130 | void (*set_mode)(u32 *p_cfg, s8 src_mode, s8 dst_mode); | ||
124 | u32 src_burst_lengths; | 131 | u32 src_burst_lengths; |
125 | u32 dst_burst_lengths; | 132 | u32 dst_burst_lengths; |
126 | u32 src_addr_widths; | 133 | u32 src_addr_widths; |
127 | u32 dst_addr_widths; | 134 | u32 dst_addr_widths; |
135 | bool has_mbus_clk; | ||
128 | }; | 136 | }; |
129 | 137 | ||
130 | /* | 138 | /* |
@@ -178,6 +186,7 @@ struct sun6i_dma_dev { | |||
178 | struct dma_device slave; | 186 | struct dma_device slave; |
179 | void __iomem *base; | 187 | void __iomem *base; |
180 | struct clk *clk; | 188 | struct clk *clk; |
189 | struct clk *clk_mbus; | ||
181 | int irq; | 190 | int irq; |
182 | spinlock_t lock; | 191 | spinlock_t lock; |
183 | struct reset_control *rstc; | 192 | struct reset_control *rstc; |
@@ -305,6 +314,30 @@ static void sun6i_set_burst_length_h3(u32 *p_cfg, s8 src_burst, s8 dst_burst) | |||
305 | DMA_CHAN_CFG_DST_BURST_H3(dst_burst); | 314 | DMA_CHAN_CFG_DST_BURST_H3(dst_burst); |
306 | } | 315 | } |
307 | 316 | ||
317 | static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq) | ||
318 | { | ||
319 | *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_A31(src_drq) | | ||
320 | DMA_CHAN_CFG_DST_DRQ_A31(dst_drq); | ||
321 | } | ||
322 | |||
323 | static void sun6i_set_drq_h6(u32 *p_cfg, s8 src_drq, s8 dst_drq) | ||
324 | { | ||
325 | *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_H6(src_drq) | | ||
326 | DMA_CHAN_CFG_DST_DRQ_H6(dst_drq); | ||
327 | } | ||
328 | |||
329 | static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode) | ||
330 | { | ||
331 | *p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) | | ||
332 | DMA_CHAN_CFG_DST_MODE_A31(dst_mode); | ||
333 | } | ||
334 | |||
335 | static void sun6i_set_mode_h6(u32 *p_cfg, s8 src_mode, s8 dst_mode) | ||
336 | { | ||
337 | *p_cfg |= DMA_CHAN_CFG_SRC_MODE_H6(src_mode) | | ||
338 | DMA_CHAN_CFG_DST_MODE_H6(dst_mode); | ||
339 | } | ||
340 | |||
308 | static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) | 341 | static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) |
309 | { | 342 | { |
310 | struct sun6i_desc *txd = pchan->desc; | 343 | struct sun6i_desc *txd = pchan->desc; |
@@ -628,14 +661,12 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( | |||
628 | 661 | ||
629 | burst = convert_burst(8); | 662 | burst = convert_burst(8); |
630 | width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); | 663 | width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); |
631 | v_lli->cfg = DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | | 664 | v_lli->cfg = DMA_CHAN_CFG_SRC_WIDTH(width) | |
632 | DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | | ||
633 | DMA_CHAN_CFG_DST_LINEAR_MODE | | ||
634 | DMA_CHAN_CFG_SRC_LINEAR_MODE | | ||
635 | DMA_CHAN_CFG_SRC_WIDTH(width) | | ||
636 | DMA_CHAN_CFG_DST_WIDTH(width); | 665 | DMA_CHAN_CFG_DST_WIDTH(width); |
637 | 666 | ||
638 | sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst); | 667 | sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst); |
668 | sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM); | ||
669 | sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, LINEAR_MODE); | ||
639 | 670 | ||
640 | sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); | 671 | sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); |
641 | 672 | ||
@@ -687,11 +718,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( | |||
687 | if (dir == DMA_MEM_TO_DEV) { | 718 | if (dir == DMA_MEM_TO_DEV) { |
688 | v_lli->src = sg_dma_address(sg); | 719 | v_lli->src = sg_dma_address(sg); |
689 | v_lli->dst = sconfig->dst_addr; | 720 | v_lli->dst = sconfig->dst_addr; |
690 | v_lli->cfg = lli_cfg | | 721 | v_lli->cfg = lli_cfg; |
691 | DMA_CHAN_CFG_DST_IO_MODE | | 722 | sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); |
692 | DMA_CHAN_CFG_SRC_LINEAR_MODE | | 723 | sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); |
693 | DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | | ||
694 | DMA_CHAN_CFG_DST_DRQ(vchan->port); | ||
695 | 724 | ||
696 | dev_dbg(chan2dev(chan), | 725 | dev_dbg(chan2dev(chan), |
697 | "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", | 726 | "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", |
@@ -702,11 +731,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( | |||
702 | } else { | 731 | } else { |
703 | v_lli->src = sconfig->src_addr; | 732 | v_lli->src = sconfig->src_addr; |
704 | v_lli->dst = sg_dma_address(sg); | 733 | v_lli->dst = sg_dma_address(sg); |
705 | v_lli->cfg = lli_cfg | | 734 | v_lli->cfg = lli_cfg; |
706 | DMA_CHAN_CFG_DST_LINEAR_MODE | | 735 | sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); |
707 | DMA_CHAN_CFG_SRC_IO_MODE | | 736 | sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); |
708 | DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | | ||
709 | DMA_CHAN_CFG_SRC_DRQ(vchan->port); | ||
710 | 737 | ||
711 | dev_dbg(chan2dev(chan), | 738 | dev_dbg(chan2dev(chan), |
712 | "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", | 739 | "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", |
@@ -772,19 +799,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( | |||
772 | if (dir == DMA_MEM_TO_DEV) { | 799 | if (dir == DMA_MEM_TO_DEV) { |
773 | v_lli->src = buf_addr + period_len * i; | 800 | v_lli->src = buf_addr + period_len * i; |
774 | v_lli->dst = sconfig->dst_addr; | 801 | v_lli->dst = sconfig->dst_addr; |
775 | v_lli->cfg = lli_cfg | | 802 | v_lli->cfg = lli_cfg; |
776 | DMA_CHAN_CFG_DST_IO_MODE | | 803 | sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); |
777 | DMA_CHAN_CFG_SRC_LINEAR_MODE | | 804 | sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); |
778 | DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | | ||
779 | DMA_CHAN_CFG_DST_DRQ(vchan->port); | ||
780 | } else { | 805 | } else { |
781 | v_lli->src = sconfig->src_addr; | 806 | v_lli->src = sconfig->src_addr; |
782 | v_lli->dst = buf_addr + period_len * i; | 807 | v_lli->dst = buf_addr + period_len * i; |
783 | v_lli->cfg = lli_cfg | | 808 | v_lli->cfg = lli_cfg; |
784 | DMA_CHAN_CFG_DST_LINEAR_MODE | | 809 | sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); |
785 | DMA_CHAN_CFG_SRC_IO_MODE | | 810 | sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); |
786 | DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | | ||
787 | DMA_CHAN_CFG_SRC_DRQ(vchan->port); | ||
788 | } | 811 | } |
789 | 812 | ||
790 | prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); | 813 | prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); |
@@ -1049,6 +1072,8 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = { | |||
1049 | .nr_max_requests = 30, | 1072 | .nr_max_requests = 30, |
1050 | .nr_max_vchans = 53, | 1073 | .nr_max_vchans = 53, |
1051 | .set_burst_length = sun6i_set_burst_length_a31, | 1074 | .set_burst_length = sun6i_set_burst_length_a31, |
1075 | .set_drq = sun6i_set_drq_a31, | ||
1076 | .set_mode = sun6i_set_mode_a31, | ||
1052 | .src_burst_lengths = BIT(1) | BIT(8), | 1077 | .src_burst_lengths = BIT(1) | BIT(8), |
1053 | .dst_burst_lengths = BIT(1) | BIT(8), | 1078 | .dst_burst_lengths = BIT(1) | BIT(8), |
1054 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | | 1079 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
@@ -1070,6 +1095,8 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = { | |||
1070 | .nr_max_vchans = 37, | 1095 | .nr_max_vchans = 37, |
1071 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, | 1096 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, |
1072 | .set_burst_length = sun6i_set_burst_length_a31, | 1097 | .set_burst_length = sun6i_set_burst_length_a31, |
1098 | .set_drq = sun6i_set_drq_a31, | ||
1099 | .set_mode = sun6i_set_mode_a31, | ||
1073 | .src_burst_lengths = BIT(1) | BIT(8), | 1100 | .src_burst_lengths = BIT(1) | BIT(8), |
1074 | .dst_burst_lengths = BIT(1) | BIT(8), | 1101 | .dst_burst_lengths = BIT(1) | BIT(8), |
1075 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | | 1102 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
@@ -1086,6 +1113,8 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = { | |||
1086 | .nr_max_vchans = 39, | 1113 | .nr_max_vchans = 39, |
1087 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, | 1114 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, |
1088 | .set_burst_length = sun6i_set_burst_length_a31, | 1115 | .set_burst_length = sun6i_set_burst_length_a31, |
1116 | .set_drq = sun6i_set_drq_a31, | ||
1117 | .set_mode = sun6i_set_mode_a31, | ||
1089 | .src_burst_lengths = BIT(1) | BIT(8), | 1118 | .src_burst_lengths = BIT(1) | BIT(8), |
1090 | .dst_burst_lengths = BIT(1) | BIT(8), | 1119 | .dst_burst_lengths = BIT(1) | BIT(8), |
1091 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | | 1120 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
@@ -1109,6 +1138,8 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = { | |||
1109 | .nr_max_vchans = 34, | 1138 | .nr_max_vchans = 34, |
1110 | .clock_autogate_enable = sun6i_enable_clock_autogate_h3, | 1139 | .clock_autogate_enable = sun6i_enable_clock_autogate_h3, |
1111 | .set_burst_length = sun6i_set_burst_length_h3, | 1140 | .set_burst_length = sun6i_set_burst_length_h3, |
1141 | .set_drq = sun6i_set_drq_a31, | ||
1142 | .set_mode = sun6i_set_mode_a31, | ||
1112 | .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), | 1143 | .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
1113 | .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), | 1144 | .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
1114 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | | 1145 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
@@ -1128,6 +1159,8 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = { | |||
1128 | static struct sun6i_dma_config sun50i_a64_dma_cfg = { | 1159 | static struct sun6i_dma_config sun50i_a64_dma_cfg = { |
1129 | .clock_autogate_enable = sun6i_enable_clock_autogate_h3, | 1160 | .clock_autogate_enable = sun6i_enable_clock_autogate_h3, |
1130 | .set_burst_length = sun6i_set_burst_length_h3, | 1161 | .set_burst_length = sun6i_set_burst_length_h3, |
1162 | .set_drq = sun6i_set_drq_a31, | ||
1163 | .set_mode = sun6i_set_mode_a31, | ||
1131 | .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), | 1164 | .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
1132 | .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), | 1165 | .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
1133 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | | 1166 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
@@ -1141,6 +1174,28 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = { | |||
1141 | }; | 1174 | }; |
1142 | 1175 | ||
1143 | /* | 1176 | /* |
1177 | * The H6 binding uses the number of dma channels from the | ||
1178 | * device tree node. | ||
1179 | */ | ||
1180 | static struct sun6i_dma_config sun50i_h6_dma_cfg = { | ||
1181 | .clock_autogate_enable = sun6i_enable_clock_autogate_h3, | ||
1182 | .set_burst_length = sun6i_set_burst_length_h3, | ||
1183 | .set_drq = sun6i_set_drq_h6, | ||
1184 | .set_mode = sun6i_set_mode_h6, | ||
1185 | .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), | ||
1186 | .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), | ||
1187 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | | ||
1188 | BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | | ||
1189 | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | | ||
1190 | BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), | ||
1191 | .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | | ||
1192 | BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | | ||
1193 | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | | ||
1194 | BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), | ||
1195 | .has_mbus_clk = true, | ||
1196 | }; | ||
1197 | |||
1198 | /* | ||
1144 | * The V3s have only 8 physical channels, a maximum DRQ port id of 23, | 1199 | * The V3s have only 8 physical channels, a maximum DRQ port id of 23, |
1145 | * and a total of 24 usable source and destination endpoints. | 1200 | * and a total of 24 usable source and destination endpoints. |
1146 | */ | 1201 | */ |
@@ -1151,6 +1206,8 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = { | |||
1151 | .nr_max_vchans = 24, | 1206 | .nr_max_vchans = 24, |
1152 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, | 1207 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, |
1153 | .set_burst_length = sun6i_set_burst_length_a31, | 1208 | .set_burst_length = sun6i_set_burst_length_a31, |
1209 | .set_drq = sun6i_set_drq_a31, | ||
1210 | .set_mode = sun6i_set_mode_a31, | ||
1154 | .src_burst_lengths = BIT(1) | BIT(8), | 1211 | .src_burst_lengths = BIT(1) | BIT(8), |
1155 | .dst_burst_lengths = BIT(1) | BIT(8), | 1212 | .dst_burst_lengths = BIT(1) | BIT(8), |
1156 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | | 1213 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
@@ -1168,6 +1225,7 @@ static const struct of_device_id sun6i_dma_match[] = { | |||
1168 | { .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg }, | 1225 | { .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg }, |
1169 | { .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg }, | 1226 | { .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg }, |
1170 | { .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg }, | 1227 | { .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg }, |
1228 | { .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg }, | ||
1171 | { /* sentinel */ } | 1229 | { /* sentinel */ } |
1172 | }; | 1230 | }; |
1173 | MODULE_DEVICE_TABLE(of, sun6i_dma_match); | 1231 | MODULE_DEVICE_TABLE(of, sun6i_dma_match); |
@@ -1204,6 +1262,14 @@ static int sun6i_dma_probe(struct platform_device *pdev) | |||
1204 | return PTR_ERR(sdc->clk); | 1262 | return PTR_ERR(sdc->clk); |
1205 | } | 1263 | } |
1206 | 1264 | ||
1265 | if (sdc->cfg->has_mbus_clk) { | ||
1266 | sdc->clk_mbus = devm_clk_get(&pdev->dev, "mbus"); | ||
1267 | if (IS_ERR(sdc->clk_mbus)) { | ||
1268 | dev_err(&pdev->dev, "No mbus clock specified\n"); | ||
1269 | return PTR_ERR(sdc->clk_mbus); | ||
1270 | } | ||
1271 | } | ||
1272 | |||
1207 | sdc->rstc = devm_reset_control_get(&pdev->dev, NULL); | 1273 | sdc->rstc = devm_reset_control_get(&pdev->dev, NULL); |
1208 | if (IS_ERR(sdc->rstc)) { | 1274 | if (IS_ERR(sdc->rstc)) { |
1209 | dev_err(&pdev->dev, "No reset controller specified\n"); | 1275 | dev_err(&pdev->dev, "No reset controller specified\n"); |
@@ -1258,8 +1324,8 @@ static int sun6i_dma_probe(struct platform_device *pdev) | |||
1258 | ret = of_property_read_u32(np, "dma-requests", &sdc->max_request); | 1324 | ret = of_property_read_u32(np, "dma-requests", &sdc->max_request); |
1259 | if (ret && !sdc->max_request) { | 1325 | if (ret && !sdc->max_request) { |
1260 | dev_info(&pdev->dev, "Missing dma-requests, using %u.\n", | 1326 | dev_info(&pdev->dev, "Missing dma-requests, using %u.\n", |
1261 | DMA_CHAN_MAX_DRQ); | 1327 | DMA_CHAN_MAX_DRQ_A31); |
1262 | sdc->max_request = DMA_CHAN_MAX_DRQ; | 1328 | sdc->max_request = DMA_CHAN_MAX_DRQ_A31; |
1263 | } | 1329 | } |
1264 | 1330 | ||
1265 | /* | 1331 | /* |
@@ -1308,11 +1374,19 @@ static int sun6i_dma_probe(struct platform_device *pdev) | |||
1308 | goto err_reset_assert; | 1374 | goto err_reset_assert; |
1309 | } | 1375 | } |
1310 | 1376 | ||
1377 | if (sdc->cfg->has_mbus_clk) { | ||
1378 | ret = clk_prepare_enable(sdc->clk_mbus); | ||
1379 | if (ret) { | ||
1380 | dev_err(&pdev->dev, "Couldn't enable mbus clock\n"); | ||
1381 | goto err_clk_disable; | ||
1382 | } | ||
1383 | } | ||
1384 | |||
1311 | ret = devm_request_irq(&pdev->dev, sdc->irq, sun6i_dma_interrupt, 0, | 1385 | ret = devm_request_irq(&pdev->dev, sdc->irq, sun6i_dma_interrupt, 0, |
1312 | dev_name(&pdev->dev), sdc); | 1386 | dev_name(&pdev->dev), sdc); |
1313 | if (ret) { | 1387 | if (ret) { |
1314 | dev_err(&pdev->dev, "Cannot request IRQ\n"); | 1388 | dev_err(&pdev->dev, "Cannot request IRQ\n"); |
1315 | goto err_clk_disable; | 1389 | goto err_mbus_clk_disable; |
1316 | } | 1390 | } |
1317 | 1391 | ||
1318 | ret = dma_async_device_register(&sdc->slave); | 1392 | ret = dma_async_device_register(&sdc->slave); |
@@ -1337,6 +1411,8 @@ err_dma_unregister: | |||
1337 | dma_async_device_unregister(&sdc->slave); | 1411 | dma_async_device_unregister(&sdc->slave); |
1338 | err_irq_disable: | 1412 | err_irq_disable: |
1339 | sun6i_kill_tasklet(sdc); | 1413 | sun6i_kill_tasklet(sdc); |
1414 | err_mbus_clk_disable: | ||
1415 | clk_disable_unprepare(sdc->clk_mbus); | ||
1340 | err_clk_disable: | 1416 | err_clk_disable: |
1341 | clk_disable_unprepare(sdc->clk); | 1417 | clk_disable_unprepare(sdc->clk); |
1342 | err_reset_assert: | 1418 | err_reset_assert: |
@@ -1355,6 +1431,7 @@ static int sun6i_dma_remove(struct platform_device *pdev) | |||
1355 | 1431 | ||
1356 | sun6i_kill_tasklet(sdc); | 1432 | sun6i_kill_tasklet(sdc); |
1357 | 1433 | ||
1434 | clk_disable_unprepare(sdc->clk_mbus); | ||
1358 | clk_disable_unprepare(sdc->clk); | 1435 | clk_disable_unprepare(sdc->clk); |
1359 | reset_control_assert(sdc->rstc); | 1436 | reset_control_assert(sdc->rstc); |
1360 | 1437 | ||