2 * Samsung's S3C64XX generic DMA support using amba-pl08x driver.
4 * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/kernel.h>
12 #include <linux/amba/bus.h>
13 #include <linux/amba/pl080.h>
14 #include <linux/amba/pl08x.h>
18 #include <mach/irqs.h>
23 static int pl08x_get_xfer_signal(const struct pl08x_channel_data
*cd
)
25 return cd
->min_signal
;
28 static void pl08x_put_xfer_signal(const struct pl08x_channel_data
*cd
, int ch
)
36 static struct pl08x_channel_data s3c64xx_dma0_info
[] = {
41 .periph_buses
= PL08X_AHB2
,
46 .periph_buses
= PL08X_AHB2
,
51 .periph_buses
= PL08X_AHB2
,
56 .periph_buses
= PL08X_AHB2
,
61 .periph_buses
= PL08X_AHB2
,
66 .periph_buses
= PL08X_AHB2
,
71 .periph_buses
= PL08X_AHB2
,
76 .periph_buses
= PL08X_AHB2
,
81 .periph_buses
= PL08X_AHB2
,
86 .periph_buses
= PL08X_AHB2
,
91 .periph_buses
= PL08X_AHB2
,
96 .periph_buses
= PL08X_AHB2
,
101 .periph_buses
= PL08X_AHB2
,
106 .periph_buses
= PL08X_AHB2
,
111 .periph_buses
= PL08X_AHB2
,
116 .periph_buses
= PL08X_AHB2
,
120 static const struct dma_slave_map s3c64xx_dma0_slave_map
[] = {
121 { "s3c6400-uart.0", "tx", &s3c64xx_dma0_info
[0] },
122 { "s3c6400-uart.0", "rx", &s3c64xx_dma0_info
[1] },
123 { "s3c6400-uart.1", "tx", &s3c64xx_dma0_info
[2] },
124 { "s3c6400-uart.1", "rx", &s3c64xx_dma0_info
[3] },
125 { "s3c6400-uart.2", "tx", &s3c64xx_dma0_info
[4] },
126 { "s3c6400-uart.2", "rx", &s3c64xx_dma0_info
[5] },
127 { "s3c6400-uart.3", "tx", &s3c64xx_dma0_info
[6] },
128 { "s3c6400-uart.3", "rx", &s3c64xx_dma0_info
[7] },
129 { "samsung-pcm.0", "tx", &s3c64xx_dma0_info
[8] },
130 { "samsung-pcm.0", "rx", &s3c64xx_dma0_info
[9] },
131 { "samsung-i2s.0", "tx", &s3c64xx_dma0_info
[10] },
132 { "samsung-i2s.0", "rx", &s3c64xx_dma0_info
[11] },
133 { "s3c6410-spi.0", "tx", &s3c64xx_dma0_info
[12] },
134 { "s3c6410-spi.0", "rx", &s3c64xx_dma0_info
[13] },
135 { "samsung-i2s.2", "tx", &s3c64xx_dma0_info
[14] },
136 { "samsung-i2s.2", "rx", &s3c64xx_dma0_info
[15] },
139 struct pl08x_platform_data s3c64xx_dma0_plat_data
= {
143 (PL080_BSIZE_4
<< PL080_CONTROL_SB_SIZE_SHIFT
|
144 PL080_BSIZE_4
<< PL080_CONTROL_DB_SIZE_SHIFT
|
145 PL080_WIDTH_32BIT
<< PL080_CONTROL_SWIDTH_SHIFT
|
146 PL080_WIDTH_32BIT
<< PL080_CONTROL_DWIDTH_SHIFT
|
147 PL080_CONTROL_PROT_BUFF
| PL080_CONTROL_PROT_CACHE
|
148 PL080_CONTROL_PROT_SYS
),
150 .lli_buses
= PL08X_AHB1
,
151 .mem_buses
= PL08X_AHB1
,
152 .get_xfer_signal
= pl08x_get_xfer_signal
,
153 .put_xfer_signal
= pl08x_put_xfer_signal
,
154 .slave_channels
= s3c64xx_dma0_info
,
155 .num_slave_channels
= ARRAY_SIZE(s3c64xx_dma0_info
),
156 .slave_map
= s3c64xx_dma0_slave_map
,
157 .slave_map_len
= ARRAY_SIZE(s3c64xx_dma0_slave_map
),
160 static AMBA_AHB_DEVICE(s3c64xx_dma0
, "dma-pl080s.0", 0,
161 0x75000000, {IRQ_DMA0
}, &s3c64xx_dma0_plat_data
);
167 static struct pl08x_channel_data s3c64xx_dma1_info
[] = {
172 .periph_buses
= PL08X_AHB2
,
177 .periph_buses
= PL08X_AHB2
,
182 .periph_buses
= PL08X_AHB2
,
187 .periph_buses
= PL08X_AHB2
,
192 .periph_buses
= PL08X_AHB2
,
197 .periph_buses
= PL08X_AHB2
,
199 .bus_id
= "ac97_out",
202 .periph_buses
= PL08X_AHB2
,
207 .periph_buses
= PL08X_AHB2
,
209 .bus_id
= "ac97_mic",
212 .periph_buses
= PL08X_AHB2
,
217 .periph_buses
= PL08X_AHB2
,
222 .periph_buses
= PL08X_AHB2
,
224 .bus_id
= "external",
227 .periph_buses
= PL08X_AHB2
,
231 static const struct dma_slave_map s3c64xx_dma1_slave_map
[] = {
232 { "samsung-pcm.1", "tx", &s3c64xx_dma1_info
[0] },
233 { "samsung-pcm.1", "rx", &s3c64xx_dma1_info
[1] },
234 { "samsung-i2s.1", "tx", &s3c64xx_dma1_info
[2] },
235 { "samsung-i2s.1", "rx", &s3c64xx_dma1_info
[3] },
236 { "s3c6410-spi.1", "tx", &s3c64xx_dma1_info
[4] },
237 { "s3c6410-spi.1", "rx", &s3c64xx_dma1_info
[5] },
240 struct pl08x_platform_data s3c64xx_dma1_plat_data
= {
244 (PL080_BSIZE_4
<< PL080_CONTROL_SB_SIZE_SHIFT
|
245 PL080_BSIZE_4
<< PL080_CONTROL_DB_SIZE_SHIFT
|
246 PL080_WIDTH_32BIT
<< PL080_CONTROL_SWIDTH_SHIFT
|
247 PL080_WIDTH_32BIT
<< PL080_CONTROL_DWIDTH_SHIFT
|
248 PL080_CONTROL_PROT_BUFF
| PL080_CONTROL_PROT_CACHE
|
249 PL080_CONTROL_PROT_SYS
),
251 .lli_buses
= PL08X_AHB1
,
252 .mem_buses
= PL08X_AHB1
,
253 .get_xfer_signal
= pl08x_get_xfer_signal
,
254 .put_xfer_signal
= pl08x_put_xfer_signal
,
255 .slave_channels
= s3c64xx_dma1_info
,
256 .num_slave_channels
= ARRAY_SIZE(s3c64xx_dma1_info
),
257 .slave_map
= s3c64xx_dma1_slave_map
,
258 .slave_map_len
= ARRAY_SIZE(s3c64xx_dma1_slave_map
),
261 static AMBA_AHB_DEVICE(s3c64xx_dma1
, "dma-pl080s.1", 0,
262 0x75100000, {IRQ_DMA1
}, &s3c64xx_dma1_plat_data
);
264 static int __init
s3c64xx_pl080_init(void)
266 if (!soc_is_s3c64xx())
269 /* Set all DMA configuration to be DMA, not SDMA */
270 writel(0xffffff, S3C64XX_SDMA_SEL
);
272 if (of_have_populated_dt())
275 amba_device_register(&s3c64xx_dma0_device
, &iomem_resource
);
276 amba_device_register(&s3c64xx_dma1_device
, &iomem_resource
);
280 arch_initcall(s3c64xx_pl080_init
);