Commit | Line | Data |
---|---|---|
28a196fe KK |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // | |
3 | // Samsung's S3C64XX generic DMA support using amba-pl08x driver. | |
4 | // | |
5 | // Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com> | |
1db0287a TF |
6 | |
7 | #include <linux/kernel.h> | |
8 | #include <linux/amba/bus.h> | |
9 | #include <linux/amba/pl080.h> | |
10 | #include <linux/amba/pl08x.h> | |
11 | #include <linux/of.h> | |
12 | ||
c6ff132d | 13 | #include "cpu.h" |
c78a41fc | 14 | #include "irqs.h" |
c6ff132d | 15 | #include "map.h" |
1db0287a | 16 | |
71b9114d | 17 | #include "regs-sys-s3c64xx.h" |
1db0287a TF |
18 | |
19 | static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd) | |
20 | { | |
21 | return cd->min_signal; | |
22 | } | |
23 | ||
24 | static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch) | |
25 | { | |
26 | } | |
27 | ||
28 | /* | |
29 | * DMA0 | |
30 | */ | |
31 | ||
32 | static struct pl08x_channel_data s3c64xx_dma0_info[] = { | |
33 | { | |
34 | .bus_id = "uart0_tx", | |
35 | .min_signal = 0, | |
36 | .max_signal = 0, | |
37 | .periph_buses = PL08X_AHB2, | |
38 | }, { | |
39 | .bus_id = "uart0_rx", | |
40 | .min_signal = 1, | |
41 | .max_signal = 1, | |
42 | .periph_buses = PL08X_AHB2, | |
43 | }, { | |
44 | .bus_id = "uart1_tx", | |
45 | .min_signal = 2, | |
46 | .max_signal = 2, | |
47 | .periph_buses = PL08X_AHB2, | |
48 | }, { | |
49 | .bus_id = "uart1_rx", | |
50 | .min_signal = 3, | |
51 | .max_signal = 3, | |
52 | .periph_buses = PL08X_AHB2, | |
53 | }, { | |
54 | .bus_id = "uart2_tx", | |
55 | .min_signal = 4, | |
56 | .max_signal = 4, | |
57 | .periph_buses = PL08X_AHB2, | |
58 | }, { | |
59 | .bus_id = "uart2_rx", | |
60 | .min_signal = 5, | |
61 | .max_signal = 5, | |
62 | .periph_buses = PL08X_AHB2, | |
63 | }, { | |
64 | .bus_id = "uart3_tx", | |
65 | .min_signal = 6, | |
66 | .max_signal = 6, | |
67 | .periph_buses = PL08X_AHB2, | |
68 | }, { | |
69 | .bus_id = "uart3_rx", | |
70 | .min_signal = 7, | |
71 | .max_signal = 7, | |
72 | .periph_buses = PL08X_AHB2, | |
73 | }, { | |
74 | .bus_id = "pcm0_tx", | |
75 | .min_signal = 8, | |
76 | .max_signal = 8, | |
77 | .periph_buses = PL08X_AHB2, | |
78 | }, { | |
79 | .bus_id = "pcm0_rx", | |
80 | .min_signal = 9, | |
81 | .max_signal = 9, | |
82 | .periph_buses = PL08X_AHB2, | |
83 | }, { | |
84 | .bus_id = "i2s0_tx", | |
85 | .min_signal = 10, | |
86 | .max_signal = 10, | |
87 | .periph_buses = PL08X_AHB2, | |
88 | }, { | |
89 | .bus_id = "i2s0_rx", | |
90 | .min_signal = 11, | |
91 | .max_signal = 11, | |
92 | .periph_buses = PL08X_AHB2, | |
93 | }, { | |
94 | .bus_id = "spi0_tx", | |
95 | .min_signal = 12, | |
96 | .max_signal = 12, | |
97 | .periph_buses = PL08X_AHB2, | |
98 | }, { | |
99 | .bus_id = "spi0_rx", | |
100 | .min_signal = 13, | |
101 | .max_signal = 13, | |
102 | .periph_buses = PL08X_AHB2, | |
103 | }, { | |
104 | .bus_id = "i2s2_tx", | |
105 | .min_signal = 14, | |
106 | .max_signal = 14, | |
107 | .periph_buses = PL08X_AHB2, | |
108 | }, { | |
109 | .bus_id = "i2s2_rx", | |
110 | .min_signal = 15, | |
111 | .max_signal = 15, | |
112 | .periph_buses = PL08X_AHB2, | |
113 | } | |
114 | }; | |
115 | ||
5d13982a SN |
116 | static const struct dma_slave_map s3c64xx_dma0_slave_map[] = { |
117 | { "s3c6400-uart.0", "tx", &s3c64xx_dma0_info[0] }, | |
118 | { "s3c6400-uart.0", "rx", &s3c64xx_dma0_info[1] }, | |
119 | { "s3c6400-uart.1", "tx", &s3c64xx_dma0_info[2] }, | |
120 | { "s3c6400-uart.1", "rx", &s3c64xx_dma0_info[3] }, | |
121 | { "s3c6400-uart.2", "tx", &s3c64xx_dma0_info[4] }, | |
122 | { "s3c6400-uart.2", "rx", &s3c64xx_dma0_info[5] }, | |
123 | { "s3c6400-uart.3", "tx", &s3c64xx_dma0_info[6] }, | |
124 | { "s3c6400-uart.3", "rx", &s3c64xx_dma0_info[7] }, | |
125 | { "samsung-pcm.0", "tx", &s3c64xx_dma0_info[8] }, | |
126 | { "samsung-pcm.0", "rx", &s3c64xx_dma0_info[9] }, | |
127 | { "samsung-i2s.0", "tx", &s3c64xx_dma0_info[10] }, | |
128 | { "samsung-i2s.0", "rx", &s3c64xx_dma0_info[11] }, | |
129 | { "s3c6410-spi.0", "tx", &s3c64xx_dma0_info[12] }, | |
130 | { "s3c6410-spi.0", "rx", &s3c64xx_dma0_info[13] }, | |
131 | { "samsung-i2s.2", "tx", &s3c64xx_dma0_info[14] }, | |
132 | { "samsung-i2s.2", "rx", &s3c64xx_dma0_info[15] }, | |
133 | }; | |
134 | ||
1db0287a | 135 | struct pl08x_platform_data s3c64xx_dma0_plat_data = { |
4166a56a LW |
136 | .memcpy_burst_size = PL08X_BURST_SZ_4, |
137 | .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS, | |
138 | .memcpy_prot_buff = true, | |
139 | .memcpy_prot_cache = true, | |
1db0287a TF |
140 | .lli_buses = PL08X_AHB1, |
141 | .mem_buses = PL08X_AHB1, | |
142 | .get_xfer_signal = pl08x_get_xfer_signal, | |
143 | .put_xfer_signal = pl08x_put_xfer_signal, | |
144 | .slave_channels = s3c64xx_dma0_info, | |
145 | .num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info), | |
5d13982a SN |
146 | .slave_map = s3c64xx_dma0_slave_map, |
147 | .slave_map_len = ARRAY_SIZE(s3c64xx_dma0_slave_map), | |
1db0287a TF |
148 | }; |
149 | ||
150 | static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0, | |
151 | 0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data); | |
152 | ||
153 | /* | |
154 | * DMA1 | |
155 | */ | |
156 | ||
157 | static struct pl08x_channel_data s3c64xx_dma1_info[] = { | |
158 | { | |
159 | .bus_id = "pcm1_tx", | |
160 | .min_signal = 0, | |
161 | .max_signal = 0, | |
162 | .periph_buses = PL08X_AHB2, | |
163 | }, { | |
164 | .bus_id = "pcm1_rx", | |
165 | .min_signal = 1, | |
166 | .max_signal = 1, | |
167 | .periph_buses = PL08X_AHB2, | |
168 | }, { | |
169 | .bus_id = "i2s1_tx", | |
170 | .min_signal = 2, | |
171 | .max_signal = 2, | |
172 | .periph_buses = PL08X_AHB2, | |
173 | }, { | |
174 | .bus_id = "i2s1_rx", | |
175 | .min_signal = 3, | |
176 | .max_signal = 3, | |
177 | .periph_buses = PL08X_AHB2, | |
178 | }, { | |
179 | .bus_id = "spi1_tx", | |
180 | .min_signal = 4, | |
181 | .max_signal = 4, | |
182 | .periph_buses = PL08X_AHB2, | |
183 | }, { | |
184 | .bus_id = "spi1_rx", | |
185 | .min_signal = 5, | |
186 | .max_signal = 5, | |
187 | .periph_buses = PL08X_AHB2, | |
188 | }, { | |
189 | .bus_id = "ac97_out", | |
190 | .min_signal = 6, | |
191 | .max_signal = 6, | |
192 | .periph_buses = PL08X_AHB2, | |
193 | }, { | |
194 | .bus_id = "ac97_in", | |
195 | .min_signal = 7, | |
196 | .max_signal = 7, | |
197 | .periph_buses = PL08X_AHB2, | |
198 | }, { | |
199 | .bus_id = "ac97_mic", | |
200 | .min_signal = 8, | |
201 | .max_signal = 8, | |
202 | .periph_buses = PL08X_AHB2, | |
203 | }, { | |
204 | .bus_id = "pwm", | |
205 | .min_signal = 9, | |
206 | .max_signal = 9, | |
207 | .periph_buses = PL08X_AHB2, | |
208 | }, { | |
209 | .bus_id = "irda", | |
210 | .min_signal = 10, | |
211 | .max_signal = 10, | |
212 | .periph_buses = PL08X_AHB2, | |
213 | }, { | |
214 | .bus_id = "external", | |
215 | .min_signal = 11, | |
216 | .max_signal = 11, | |
217 | .periph_buses = PL08X_AHB2, | |
218 | }, | |
219 | }; | |
220 | ||
5d13982a SN |
221 | static const struct dma_slave_map s3c64xx_dma1_slave_map[] = { |
222 | { "samsung-pcm.1", "tx", &s3c64xx_dma1_info[0] }, | |
223 | { "samsung-pcm.1", "rx", &s3c64xx_dma1_info[1] }, | |
224 | { "samsung-i2s.1", "tx", &s3c64xx_dma1_info[2] }, | |
225 | { "samsung-i2s.1", "rx", &s3c64xx_dma1_info[3] }, | |
226 | { "s3c6410-spi.1", "tx", &s3c64xx_dma1_info[4] }, | |
227 | { "s3c6410-spi.1", "rx", &s3c64xx_dma1_info[5] }, | |
228 | }; | |
229 | ||
1db0287a | 230 | struct pl08x_platform_data s3c64xx_dma1_plat_data = { |
4166a56a LW |
231 | .memcpy_burst_size = PL08X_BURST_SZ_4, |
232 | .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS, | |
233 | .memcpy_prot_buff = true, | |
234 | .memcpy_prot_cache = true, | |
1db0287a TF |
235 | .lli_buses = PL08X_AHB1, |
236 | .mem_buses = PL08X_AHB1, | |
237 | .get_xfer_signal = pl08x_get_xfer_signal, | |
238 | .put_xfer_signal = pl08x_put_xfer_signal, | |
239 | .slave_channels = s3c64xx_dma1_info, | |
240 | .num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info), | |
5d13982a SN |
241 | .slave_map = s3c64xx_dma1_slave_map, |
242 | .slave_map_len = ARRAY_SIZE(s3c64xx_dma1_slave_map), | |
1db0287a TF |
243 | }; |
244 | ||
245 | static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0, | |
246 | 0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data); | |
247 | ||
248 | static int __init s3c64xx_pl080_init(void) | |
249 | { | |
a0e157af AB |
250 | if (!soc_is_s3c64xx()) |
251 | return 0; | |
252 | ||
1db0287a TF |
253 | /* Set all DMA configuration to be DMA, not SDMA */ |
254 | writel(0xffffff, S3C64XX_SDMA_SEL); | |
255 | ||
256 | if (of_have_populated_dt()) | |
257 | return 0; | |
258 | ||
259 | amba_device_register(&s3c64xx_dma0_device, &iomem_resource); | |
260 | amba_device_register(&s3c64xx_dma1_device, &iomem_resource); | |
261 | ||
262 | return 0; | |
263 | } | |
264 | arch_initcall(s3c64xx_pl080_init); |