Linux Audio

Check our new training course

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