Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  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>
  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
 13#include <plat/cpu.h>
 14#include <mach/irqs.h>
 15#include <mach/map.h>
 16
 17#include "regs-sys.h"
 18
 19static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd)
 20{
 21	return cd->min_signal;
 22}
 23
 24static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch)
 25{
 26}
 27
 28/*
 29 * DMA0
 30 */
 31
 32static 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
116static 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
135struct pl08x_platform_data s3c64xx_dma0_plat_data = {
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,
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),
146	.slave_map = s3c64xx_dma0_slave_map,
147	.slave_map_len = ARRAY_SIZE(s3c64xx_dma0_slave_map),
148};
149
150static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
151			0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);
152
153/*
154 * DMA1
155 */
156
157static 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
221static 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
230struct pl08x_platform_data s3c64xx_dma1_plat_data = {
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,
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),
241	.slave_map = s3c64xx_dma1_slave_map,
242	.slave_map_len = ARRAY_SIZE(s3c64xx_dma1_slave_map),
243};
244
245static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
246			0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);
247
248static int __init s3c64xx_pl080_init(void)
249{
250	if (!soc_is_s3c64xx())
251		return 0;
252
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}
264arch_initcall(s3c64xx_pl080_init);