dma-s3c2410.c revision 24fae0fe2cf02eef941fd17a1e44b747483f4bef
1/* linux/arch/arm/mach-s3c2410/dma.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 *	Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 DMA selection
7 *
8 * http://armlinux.simtec.co.uk/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/serial_core.h>
19
20#include <mach/map.h>
21#include <mach/dma.h>
22
23#include <plat/cpu.h>
24#include <plat/dma-s3c24xx.h>
25
26#include <plat/regs-serial.h>
27#include <mach/regs-gpio.h>
28#include <plat/regs-ac97.h>
29#include <plat/regs-dma.h>
30#include <mach/regs-lcd.h>
31#include <plat/regs-iis.h>
32#include <plat/regs-spi.h>
33
34static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
35	[DMACH_XD0] = {
36		.name		= "xdreq0",
37		.channels[0]	= S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
38	},
39	[DMACH_XD1] = {
40		.name		= "xdreq1",
41		.channels[1]	= S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
42	},
43	[DMACH_SDI] = {
44		.name		= "sdi",
45		.channels[0]	= S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
46		.channels[2]	= S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
47		.channels[3]	= S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
48	},
49	[DMACH_SPI0] = {
50		.name		= "spi0",
51		.channels[1]	= S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
52	},
53	[DMACH_SPI1] = {
54		.name		= "spi1",
55		.channels[3]	= S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
56	},
57	[DMACH_UART0] = {
58		.name		= "uart0",
59		.channels[0]	= S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
60	},
61	[DMACH_UART1] = {
62		.name		= "uart1",
63		.channels[1]	= S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
64	},
65      	[DMACH_UART2] = {
66		.name		= "uart2",
67		.channels[3]	= S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
68	},
69	[DMACH_TIMER] = {
70		.name		= "timer",
71		.channels[0]	= S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
72		.channels[2]	= S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
73		.channels[3]	= S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
74	},
75	[DMACH_I2S_IN] = {
76		.name		= "i2s-sdi",
77		.channels[1]	= S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
78		.channels[2]	= S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
79	},
80	[DMACH_I2S_OUT] = {
81		.name		= "i2s-sdo",
82		.channels[2]	= S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
83	},
84	[DMACH_USB_EP1] = {
85		.name		= "usb-ep1",
86		.channels[0]	= S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
87	},
88	[DMACH_USB_EP2] = {
89		.name		= "usb-ep2",
90		.channels[1]	= S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
91	},
92	[DMACH_USB_EP3] = {
93		.name		= "usb-ep3",
94		.channels[2]	= S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
95	},
96	[DMACH_USB_EP4] = {
97		.name		= "usb-ep4",
98		.channels[3]	=S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
99	},
100};
101
102static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
103			       struct s3c24xx_dma_map *map)
104{
105	chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
106}
107
108static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
109	.select		= s3c2410_dma_select,
110	.dcon_mask	= 7 << 24,
111	.map		= s3c2410_dma_mappings,
112	.map_size	= ARRAY_SIZE(s3c2410_dma_mappings),
113};
114
115static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
116	.channels	= {
117		[DMACH_SDI]	= {
118			.list	= {
119				[0]	= 3 | DMA_CH_VALID,
120				[1]	= 2 | DMA_CH_VALID,
121				[2]	= 0 | DMA_CH_VALID,
122			},
123		},
124		[DMACH_I2S_IN]	= {
125			.list	= {
126				[0]	= 1 | DMA_CH_VALID,
127				[1]	= 2 | DMA_CH_VALID,
128			},
129		},
130	},
131};
132
133static int __init s3c2410_dma_add(struct device *dev,
134				  struct subsys_interface *sif)
135{
136	s3c2410_dma_init();
137	s3c24xx_dma_order_set(&s3c2410_dma_order);
138	return s3c24xx_dma_init_map(&s3c2410_dma_sel);
139}
140
141#if defined(CONFIG_CPU_S3C2410)
142static struct subsys_interface s3c2410_dma_interface = {
143	.name		= "s3c2410_dma",
144	.subsys		= &s3c2410_subsys,
145	.add_dev	= s3c2410_dma_add,
146};
147
148static int __init s3c2410_dma_drvinit(void)
149{
150	return subsys_interface_register(&s3c2410_dma_interface);
151}
152
153arch_initcall(s3c2410_dma_drvinit);
154
155static struct subsys_interface s3c2410a_dma_interface = {
156	.name		= "s3c2410a_dma",
157	.subsys		= &s3c2410a_subsys,
158	.add_dev	= s3c2410_dma_add,
159};
160
161static int __init s3c2410a_dma_drvinit(void)
162{
163	return subsys_interface_register(&s3c2410a_dma_interface);
164}
165
166arch_initcall(s3c2410a_dma_drvinit);
167#endif
168
169#if defined(CONFIG_CPU_S3C2442)
170/* S3C2442 DMA contains the same selection table as the S3C2410 */
171static struct subsys_interface s3c2442_dma_interface = {
172	.name		= "s3c2442_dma",
173	.subsys		= &s3c2442_subsys,
174	.add_dev	= s3c2410_dma_add,
175};
176
177static int __init s3c2442_dma_drvinit(void)
178{
179	return subsys_interface_register(&s3c2442_dma_interface);
180}
181
182arch_initcall(s3c2442_dma_drvinit);
183#endif
184
185