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 = {
140 .memcpy_burst_size = PL08X_BURST_SZ_4,
141 .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
142 .memcpy_prot_buff = true,
143 .memcpy_prot_cache = true,
144 .lli_buses = PL08X_AHB1,
145 .mem_buses = PL08X_AHB1,
146 .get_xfer_signal = pl08x_get_xfer_signal,
147 .put_xfer_signal = pl08x_put_xfer_signal,
148 .slave_channels = s3c64xx_dma0_info,
149 .num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
150 .slave_map = s3c64xx_dma0_slave_map,
151 .slave_map_len = ARRAY_SIZE(s3c64xx_dma0_slave_map),
154 static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
155 0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);
161 static struct pl08x_channel_data s3c64xx_dma1_info[] = {
166 .periph_buses = PL08X_AHB2,
171 .periph_buses = PL08X_AHB2,
176 .periph_buses = PL08X_AHB2,
181 .periph_buses = PL08X_AHB2,
186 .periph_buses = PL08X_AHB2,
191 .periph_buses = PL08X_AHB2,
193 .bus_id = "ac97_out",
196 .periph_buses = PL08X_AHB2,
201 .periph_buses = PL08X_AHB2,
203 .bus_id = "ac97_mic",
206 .periph_buses = PL08X_AHB2,
211 .periph_buses = PL08X_AHB2,
216 .periph_buses = PL08X_AHB2,
218 .bus_id = "external",
221 .periph_buses = PL08X_AHB2,
225 static const struct dma_slave_map s3c64xx_dma1_slave_map[] = {
226 { "samsung-pcm.1", "tx", &s3c64xx_dma1_info[0] },
227 { "samsung-pcm.1", "rx", &s3c64xx_dma1_info[1] },
228 { "samsung-i2s.1", "tx", &s3c64xx_dma1_info[2] },
229 { "samsung-i2s.1", "rx", &s3c64xx_dma1_info[3] },
230 { "s3c6410-spi.1", "tx", &s3c64xx_dma1_info[4] },
231 { "s3c6410-spi.1", "rx", &s3c64xx_dma1_info[5] },
234 struct pl08x_platform_data s3c64xx_dma1_plat_data = {
235 .memcpy_burst_size = PL08X_BURST_SZ_4,
236 .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
237 .memcpy_prot_buff = true,
238 .memcpy_prot_cache = true,
239 .lli_buses = PL08X_AHB1,
240 .mem_buses = PL08X_AHB1,
241 .get_xfer_signal = pl08x_get_xfer_signal,
242 .put_xfer_signal = pl08x_put_xfer_signal,
243 .slave_channels = s3c64xx_dma1_info,
244 .num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
245 .slave_map = s3c64xx_dma1_slave_map,
246 .slave_map_len = ARRAY_SIZE(s3c64xx_dma1_slave_map),
249 static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
250 0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);
252 static int __init s3c64xx_pl080_init(void)
254 if (!soc_is_s3c64xx())
257 /* Set all DMA configuration to be DMA, not SDMA */
258 writel(0xffffff, S3C64XX_SDMA_SEL);
260 if (of_have_populated_dt())
263 amba_device_register(&s3c64xx_dma0_device, &iomem_resource);
264 amba_device_register(&s3c64xx_dma1_device, &iomem_resource);
268 arch_initcall(s3c64xx_pl080_init);