| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2013-2014 Allwinner Tech Co., Ltd |
|---|
| 3 | 4 | * Author: Sugar <shuge@allwinnertech.com> |
|---|
| 4 | 5 | * |
|---|
| 5 | 6 | * Copyright (C) 2014 Maxime Ripard |
|---|
| 6 | 7 | * Maxime Ripard <maxime.ripard@free-electrons.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | 8 | */ |
|---|
| 13 | 9 | |
|---|
| 14 | 10 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 68 | 64 | #define DMA_CHAN_LLI_ADDR 0x08 |
|---|
| 69 | 65 | |
|---|
| 70 | 66 | #define DMA_CHAN_CUR_CFG 0x0c |
|---|
| 71 | | -#define DMA_CHAN_MAX_DRQ 0x1f |
|---|
| 72 | | -#define DMA_CHAN_CFG_SRC_DRQ(x) ((x) & DMA_CHAN_MAX_DRQ) |
|---|
| 73 | | -#define DMA_CHAN_CFG_SRC_IO_MODE BIT(5) |
|---|
| 74 | | -#define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5) |
|---|
| 67 | +#define DMA_CHAN_MAX_DRQ_A31 0x1f |
|---|
| 68 | +#define DMA_CHAN_MAX_DRQ_H6 0x3f |
|---|
| 69 | +#define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) |
|---|
| 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) |
|---|
| 75 | 73 | #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) |
|---|
| 76 | 74 | #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) |
|---|
| 77 | 75 | #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) |
|---|
| 78 | 76 | |
|---|
| 79 | | -#define DMA_CHAN_CFG_DST_DRQ(x) (DMA_CHAN_CFG_SRC_DRQ(x) << 16) |
|---|
| 80 | | -#define DMA_CHAN_CFG_DST_IO_MODE (DMA_CHAN_CFG_SRC_IO_MODE << 16) |
|---|
| 81 | | -#define DMA_CHAN_CFG_DST_LINEAR_MODE (DMA_CHAN_CFG_SRC_LINEAR_MODE << 16) |
|---|
| 77 | +#define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) |
|---|
| 78 | +#define DMA_CHAN_CFG_DST_DRQ_H6(x) (DMA_CHAN_CFG_SRC_DRQ_H6(x) << 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) |
|---|
| 82 | 81 | #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) |
|---|
| 83 | 82 | #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16) |
|---|
| 84 | 83 | #define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16) |
|---|
| .. | .. |
|---|
| 98 | 97 | #define LLI_LAST_ITEM 0xfffff800 |
|---|
| 99 | 98 | #define NORMAL_WAIT 8 |
|---|
| 100 | 99 | #define DRQ_SDRAM 1 |
|---|
| 100 | +#define LINEAR_MODE 0 |
|---|
| 101 | +#define IO_MODE 1 |
|---|
| 101 | 102 | |
|---|
| 102 | 103 | /* forward declaration */ |
|---|
| 103 | 104 | struct sun6i_dma_dev; |
|---|
| .. | .. |
|---|
| 125 | 126 | */ |
|---|
| 126 | 127 | void (*clock_autogate_enable)(struct sun6i_dma_dev *); |
|---|
| 127 | 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); |
|---|
| 128 | 131 | u32 src_burst_lengths; |
|---|
| 129 | 132 | u32 dst_burst_lengths; |
|---|
| 130 | 133 | u32 src_addr_widths; |
|---|
| 131 | 134 | u32 dst_addr_widths; |
|---|
| 135 | + bool has_mbus_clk; |
|---|
| 132 | 136 | }; |
|---|
| 133 | 137 | |
|---|
| 134 | 138 | /* |
|---|
| .. | .. |
|---|
| 182 | 186 | struct dma_device slave; |
|---|
| 183 | 187 | void __iomem *base; |
|---|
| 184 | 188 | struct clk *clk; |
|---|
| 189 | + struct clk *clk_mbus; |
|---|
| 185 | 190 | int irq; |
|---|
| 186 | 191 | spinlock_t lock; |
|---|
| 187 | 192 | struct reset_control *rstc; |
|---|
| .. | .. |
|---|
| 307 | 312 | { |
|---|
| 308 | 313 | *p_cfg |= DMA_CHAN_CFG_SRC_BURST_H3(src_burst) | |
|---|
| 309 | 314 | DMA_CHAN_CFG_DST_BURST_H3(dst_burst); |
|---|
| 315 | +} |
|---|
| 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); |
|---|
| 310 | 339 | } |
|---|
| 311 | 340 | |
|---|
| 312 | 341 | static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) |
|---|
| .. | .. |
|---|
| 438 | 467 | return 0; |
|---|
| 439 | 468 | } |
|---|
| 440 | 469 | |
|---|
| 441 | | -static void sun6i_dma_tasklet(unsigned long data) |
|---|
| 470 | +static void sun6i_dma_tasklet(struct tasklet_struct *t) |
|---|
| 442 | 471 | { |
|---|
| 443 | | - struct sun6i_dma_dev *sdev = (struct sun6i_dma_dev *)data; |
|---|
| 472 | + struct sun6i_dma_dev *sdev = from_tasklet(sdev, t, task); |
|---|
| 444 | 473 | struct sun6i_vchan *vchan; |
|---|
| 445 | 474 | struct sun6i_pchan *pchan; |
|---|
| 446 | 475 | unsigned int pchan_alloc = 0; |
|---|
| .. | .. |
|---|
| 632 | 661 | |
|---|
| 633 | 662 | burst = convert_burst(8); |
|---|
| 634 | 663 | width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); |
|---|
| 635 | | - v_lli->cfg = DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | |
|---|
| 636 | | - DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | |
|---|
| 637 | | - DMA_CHAN_CFG_DST_LINEAR_MODE | |
|---|
| 638 | | - DMA_CHAN_CFG_SRC_LINEAR_MODE | |
|---|
| 639 | | - DMA_CHAN_CFG_SRC_WIDTH(width) | |
|---|
| 664 | + v_lli->cfg = DMA_CHAN_CFG_SRC_WIDTH(width) | |
|---|
| 640 | 665 | DMA_CHAN_CFG_DST_WIDTH(width); |
|---|
| 641 | 666 | |
|---|
| 642 | 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); |
|---|
| 643 | 670 | |
|---|
| 644 | 671 | sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); |
|---|
| 645 | 672 | |
|---|
| .. | .. |
|---|
| 691 | 718 | if (dir == DMA_MEM_TO_DEV) { |
|---|
| 692 | 719 | v_lli->src = sg_dma_address(sg); |
|---|
| 693 | 720 | v_lli->dst = sconfig->dst_addr; |
|---|
| 694 | | - v_lli->cfg = lli_cfg | |
|---|
| 695 | | - DMA_CHAN_CFG_DST_IO_MODE | |
|---|
| 696 | | - DMA_CHAN_CFG_SRC_LINEAR_MODE | |
|---|
| 697 | | - DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | |
|---|
| 698 | | - DMA_CHAN_CFG_DST_DRQ(vchan->port); |
|---|
| 721 | + v_lli->cfg = lli_cfg; |
|---|
| 722 | + sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); |
|---|
| 723 | + sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); |
|---|
| 699 | 724 | |
|---|
| 700 | 725 | dev_dbg(chan2dev(chan), |
|---|
| 701 | 726 | "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", |
|---|
| .. | .. |
|---|
| 706 | 731 | } else { |
|---|
| 707 | 732 | v_lli->src = sconfig->src_addr; |
|---|
| 708 | 733 | v_lli->dst = sg_dma_address(sg); |
|---|
| 709 | | - v_lli->cfg = lli_cfg | |
|---|
| 710 | | - DMA_CHAN_CFG_DST_LINEAR_MODE | |
|---|
| 711 | | - DMA_CHAN_CFG_SRC_IO_MODE | |
|---|
| 712 | | - DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | |
|---|
| 713 | | - DMA_CHAN_CFG_SRC_DRQ(vchan->port); |
|---|
| 734 | + v_lli->cfg = lli_cfg; |
|---|
| 735 | + sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); |
|---|
| 736 | + sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); |
|---|
| 714 | 737 | |
|---|
| 715 | 738 | dev_dbg(chan2dev(chan), |
|---|
| 716 | 739 | "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", |
|---|
| .. | .. |
|---|
| 776 | 799 | if (dir == DMA_MEM_TO_DEV) { |
|---|
| 777 | 800 | v_lli->src = buf_addr + period_len * i; |
|---|
| 778 | 801 | v_lli->dst = sconfig->dst_addr; |
|---|
| 779 | | - v_lli->cfg = lli_cfg | |
|---|
| 780 | | - DMA_CHAN_CFG_DST_IO_MODE | |
|---|
| 781 | | - DMA_CHAN_CFG_SRC_LINEAR_MODE | |
|---|
| 782 | | - DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | |
|---|
| 783 | | - DMA_CHAN_CFG_DST_DRQ(vchan->port); |
|---|
| 802 | + v_lli->cfg = lli_cfg; |
|---|
| 803 | + sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); |
|---|
| 804 | + sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); |
|---|
| 784 | 805 | } else { |
|---|
| 785 | 806 | v_lli->src = sconfig->src_addr; |
|---|
| 786 | 807 | v_lli->dst = buf_addr + period_len * i; |
|---|
| 787 | | - v_lli->cfg = lli_cfg | |
|---|
| 788 | | - DMA_CHAN_CFG_DST_LINEAR_MODE | |
|---|
| 789 | | - DMA_CHAN_CFG_SRC_IO_MODE | |
|---|
| 790 | | - DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | |
|---|
| 791 | | - DMA_CHAN_CFG_SRC_DRQ(vchan->port); |
|---|
| 808 | + v_lli->cfg = lli_cfg; |
|---|
| 809 | + sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); |
|---|
| 810 | + sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); |
|---|
| 792 | 811 | } |
|---|
| 793 | 812 | |
|---|
| 794 | 813 | prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); |
|---|
| .. | .. |
|---|
| 1053 | 1072 | .nr_max_requests = 30, |
|---|
| 1054 | 1073 | .nr_max_vchans = 53, |
|---|
| 1055 | 1074 | .set_burst_length = sun6i_set_burst_length_a31, |
|---|
| 1075 | + .set_drq = sun6i_set_drq_a31, |
|---|
| 1076 | + .set_mode = sun6i_set_mode_a31, |
|---|
| 1056 | 1077 | .src_burst_lengths = BIT(1) | BIT(8), |
|---|
| 1057 | 1078 | .dst_burst_lengths = BIT(1) | BIT(8), |
|---|
| 1058 | 1079 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
|---|
| .. | .. |
|---|
| 1074 | 1095 | .nr_max_vchans = 37, |
|---|
| 1075 | 1096 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, |
|---|
| 1076 | 1097 | .set_burst_length = sun6i_set_burst_length_a31, |
|---|
| 1098 | + .set_drq = sun6i_set_drq_a31, |
|---|
| 1099 | + .set_mode = sun6i_set_mode_a31, |
|---|
| 1077 | 1100 | .src_burst_lengths = BIT(1) | BIT(8), |
|---|
| 1078 | 1101 | .dst_burst_lengths = BIT(1) | BIT(8), |
|---|
| 1079 | 1102 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
|---|
| .. | .. |
|---|
| 1090 | 1113 | .nr_max_vchans = 39, |
|---|
| 1091 | 1114 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, |
|---|
| 1092 | 1115 | .set_burst_length = sun6i_set_burst_length_a31, |
|---|
| 1116 | + .set_drq = sun6i_set_drq_a31, |
|---|
| 1117 | + .set_mode = sun6i_set_mode_a31, |
|---|
| 1093 | 1118 | .src_burst_lengths = BIT(1) | BIT(8), |
|---|
| 1094 | 1119 | .dst_burst_lengths = BIT(1) | BIT(8), |
|---|
| 1095 | 1120 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
|---|
| .. | .. |
|---|
| 1113 | 1138 | .nr_max_vchans = 34, |
|---|
| 1114 | 1139 | .clock_autogate_enable = sun6i_enable_clock_autogate_h3, |
|---|
| 1115 | 1140 | .set_burst_length = sun6i_set_burst_length_h3, |
|---|
| 1141 | + .set_drq = sun6i_set_drq_a31, |
|---|
| 1142 | + .set_mode = sun6i_set_mode_a31, |
|---|
| 1116 | 1143 | .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
|---|
| 1117 | 1144 | .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
|---|
| 1118 | 1145 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
|---|
| .. | .. |
|---|
| 1132 | 1159 | static struct sun6i_dma_config sun50i_a64_dma_cfg = { |
|---|
| 1133 | 1160 | .clock_autogate_enable = sun6i_enable_clock_autogate_h3, |
|---|
| 1134 | 1161 | .set_burst_length = sun6i_set_burst_length_h3, |
|---|
| 1162 | + .set_drq = sun6i_set_drq_a31, |
|---|
| 1163 | + .set_mode = sun6i_set_mode_a31, |
|---|
| 1135 | 1164 | .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
|---|
| 1136 | 1165 | .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
|---|
| 1137 | 1166 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
|---|
| .. | .. |
|---|
| 1145 | 1174 | }; |
|---|
| 1146 | 1175 | |
|---|
| 1147 | 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 | +/* |
|---|
| 1148 | 1199 | * The V3s have only 8 physical channels, a maximum DRQ port id of 23, |
|---|
| 1149 | 1200 | * and a total of 24 usable source and destination endpoints. |
|---|
| 1150 | 1201 | */ |
|---|
| .. | .. |
|---|
| 1155 | 1206 | .nr_max_vchans = 24, |
|---|
| 1156 | 1207 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, |
|---|
| 1157 | 1208 | .set_burst_length = sun6i_set_burst_length_a31, |
|---|
| 1209 | + .set_drq = sun6i_set_drq_a31, |
|---|
| 1210 | + .set_mode = sun6i_set_mode_a31, |
|---|
| 1158 | 1211 | .src_burst_lengths = BIT(1) | BIT(8), |
|---|
| 1159 | 1212 | .dst_burst_lengths = BIT(1) | BIT(8), |
|---|
| 1160 | 1213 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
|---|
| .. | .. |
|---|
| 1172 | 1225 | { .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg }, |
|---|
| 1173 | 1226 | { .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg }, |
|---|
| 1174 | 1227 | { .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg }, |
|---|
| 1228 | + { .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg }, |
|---|
| 1175 | 1229 | { /* sentinel */ } |
|---|
| 1176 | 1230 | }; |
|---|
| 1177 | 1231 | MODULE_DEVICE_TABLE(of, sun6i_dma_match); |
|---|
| .. | .. |
|---|
| 1197 | 1251 | return PTR_ERR(sdc->base); |
|---|
| 1198 | 1252 | |
|---|
| 1199 | 1253 | sdc->irq = platform_get_irq(pdev, 0); |
|---|
| 1200 | | - if (sdc->irq < 0) { |
|---|
| 1201 | | - dev_err(&pdev->dev, "Cannot claim IRQ\n"); |
|---|
| 1254 | + if (sdc->irq < 0) |
|---|
| 1202 | 1255 | return sdc->irq; |
|---|
| 1203 | | - } |
|---|
| 1204 | 1256 | |
|---|
| 1205 | 1257 | sdc->clk = devm_clk_get(&pdev->dev, NULL); |
|---|
| 1206 | 1258 | if (IS_ERR(sdc->clk)) { |
|---|
| 1207 | 1259 | dev_err(&pdev->dev, "No clock specified\n"); |
|---|
| 1208 | 1260 | return PTR_ERR(sdc->clk); |
|---|
| 1261 | + } |
|---|
| 1262 | + |
|---|
| 1263 | + if (sdc->cfg->has_mbus_clk) { |
|---|
| 1264 | + sdc->clk_mbus = devm_clk_get(&pdev->dev, "mbus"); |
|---|
| 1265 | + if (IS_ERR(sdc->clk_mbus)) { |
|---|
| 1266 | + dev_err(&pdev->dev, "No mbus clock specified\n"); |
|---|
| 1267 | + return PTR_ERR(sdc->clk_mbus); |
|---|
| 1268 | + } |
|---|
| 1209 | 1269 | } |
|---|
| 1210 | 1270 | |
|---|
| 1211 | 1271 | sdc->rstc = devm_reset_control_get(&pdev->dev, NULL); |
|---|
| .. | .. |
|---|
| 1262 | 1322 | ret = of_property_read_u32(np, "dma-requests", &sdc->max_request); |
|---|
| 1263 | 1323 | if (ret && !sdc->max_request) { |
|---|
| 1264 | 1324 | dev_info(&pdev->dev, "Missing dma-requests, using %u.\n", |
|---|
| 1265 | | - DMA_CHAN_MAX_DRQ); |
|---|
| 1266 | | - sdc->max_request = DMA_CHAN_MAX_DRQ; |
|---|
| 1325 | + DMA_CHAN_MAX_DRQ_A31); |
|---|
| 1326 | + sdc->max_request = DMA_CHAN_MAX_DRQ_A31; |
|---|
| 1267 | 1327 | } |
|---|
| 1268 | 1328 | |
|---|
| 1269 | 1329 | /* |
|---|
| .. | .. |
|---|
| 1283 | 1343 | if (!sdc->vchans) |
|---|
| 1284 | 1344 | return -ENOMEM; |
|---|
| 1285 | 1345 | |
|---|
| 1286 | | - tasklet_init(&sdc->task, sun6i_dma_tasklet, (unsigned long)sdc); |
|---|
| 1346 | + tasklet_setup(&sdc->task, sun6i_dma_tasklet); |
|---|
| 1287 | 1347 | |
|---|
| 1288 | 1348 | for (i = 0; i < sdc->num_pchans; i++) { |
|---|
| 1289 | 1349 | struct sun6i_pchan *pchan = &sdc->pchans[i]; |
|---|
| .. | .. |
|---|
| 1312 | 1372 | goto err_reset_assert; |
|---|
| 1313 | 1373 | } |
|---|
| 1314 | 1374 | |
|---|
| 1375 | + if (sdc->cfg->has_mbus_clk) { |
|---|
| 1376 | + ret = clk_prepare_enable(sdc->clk_mbus); |
|---|
| 1377 | + if (ret) { |
|---|
| 1378 | + dev_err(&pdev->dev, "Couldn't enable mbus clock\n"); |
|---|
| 1379 | + goto err_clk_disable; |
|---|
| 1380 | + } |
|---|
| 1381 | + } |
|---|
| 1382 | + |
|---|
| 1315 | 1383 | ret = devm_request_irq(&pdev->dev, sdc->irq, sun6i_dma_interrupt, 0, |
|---|
| 1316 | 1384 | dev_name(&pdev->dev), sdc); |
|---|
| 1317 | 1385 | if (ret) { |
|---|
| 1318 | 1386 | dev_err(&pdev->dev, "Cannot request IRQ\n"); |
|---|
| 1319 | | - goto err_clk_disable; |
|---|
| 1387 | + goto err_mbus_clk_disable; |
|---|
| 1320 | 1388 | } |
|---|
| 1321 | 1389 | |
|---|
| 1322 | 1390 | ret = dma_async_device_register(&sdc->slave); |
|---|
| .. | .. |
|---|
| 1341 | 1409 | dma_async_device_unregister(&sdc->slave); |
|---|
| 1342 | 1410 | err_irq_disable: |
|---|
| 1343 | 1411 | sun6i_kill_tasklet(sdc); |
|---|
| 1412 | +err_mbus_clk_disable: |
|---|
| 1413 | + clk_disable_unprepare(sdc->clk_mbus); |
|---|
| 1344 | 1414 | err_clk_disable: |
|---|
| 1345 | 1415 | clk_disable_unprepare(sdc->clk); |
|---|
| 1346 | 1416 | err_reset_assert: |
|---|
| .. | .. |
|---|
| 1359 | 1429 | |
|---|
| 1360 | 1430 | sun6i_kill_tasklet(sdc); |
|---|
| 1361 | 1431 | |
|---|
| 1432 | + clk_disable_unprepare(sdc->clk_mbus); |
|---|
| 1362 | 1433 | clk_disable_unprepare(sdc->clk); |
|---|
| 1363 | 1434 | reset_control_assert(sdc->rstc); |
|---|
| 1364 | 1435 | |
|---|