Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dma-s3c2440.c
Go to the documentation of this file.
1 /* linux/arch/arm/mach-s3c2440/dma.c
2  *
3  * Copyright (c) 2006 Simtec Electronics
4  * Ben Dooks <[email protected]>
5  *
6  * S3C2440 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/dma-s3c24xx.h>
24 #include <plat/cpu.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-mem.h>
31 #include <mach/regs-lcd.h>
32 #include <mach/regs-sdi.h>
33 #include <plat/regs-iis.h>
34 #include <plat/regs-spi.h>
35 
36 static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
37  [DMACH_XD0] = {
38  .name = "xdreq0",
39  .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
40  },
41  [DMACH_XD1] = {
42  .name = "xdreq1",
43  .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
44  },
45  [DMACH_SDI] = {
46  .name = "sdi",
47  .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
48  .channels[1] = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
49  .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
50  .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
51  },
52  [DMACH_SPI0] = {
53  .name = "spi0",
54  .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
55  },
56  [DMACH_SPI1] = {
57  .name = "spi1",
58  .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
59  },
60  [DMACH_UART0] = {
61  .name = "uart0",
62  .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
63  },
64  [DMACH_UART1] = {
65  .name = "uart1",
66  .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
67  },
68  [DMACH_UART2] = {
69  .name = "uart2",
70  .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
71  },
72  [DMACH_TIMER] = {
73  .name = "timer",
74  .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
75  .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
76  .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
77  },
78  [DMACH_I2S_IN] = {
79  .name = "i2s-sdi",
80  .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
81  .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
82  },
83  [DMACH_I2S_OUT] = {
84  .name = "i2s-sdo",
85  .channels[0] = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
86  .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
87  },
88  [DMACH_PCM_IN] = {
89  .name = "pcm-in",
90  .channels[0] = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
91  .channels[2] = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
92  },
93  [DMACH_PCM_OUT] = {
94  .name = "pcm-out",
95  .channels[1] = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
96  .channels[3] = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
97  },
98  [DMACH_MIC_IN] = {
99  .name = "mic-in",
100  .channels[2] = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
101  .channels[3] = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
102  },
103  [DMACH_USB_EP1] = {
104  .name = "usb-ep1",
105  .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
106  },
107  [DMACH_USB_EP2] = {
108  .name = "usb-ep2",
109  .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
110  },
111  [DMACH_USB_EP3] = {
112  .name = "usb-ep3",
113  .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
114  },
115  [DMACH_USB_EP4] = {
116  .name = "usb-ep4",
117  .channels[3] = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
118  },
119 };
120 
121 static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
122  struct s3c24xx_dma_map *map)
123 {
124  chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
125 }
126 
127 static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
128  .select = s3c2440_dma_select,
129  .dcon_mask = 7 << 24,
130  .map = s3c2440_dma_mappings,
131  .map_size = ARRAY_SIZE(s3c2440_dma_mappings),
132 };
133 
134 static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
135  .channels = {
136  [DMACH_SDI] = {
137  .list = {
138  [0] = 3 | DMA_CH_VALID,
139  [1] = 2 | DMA_CH_VALID,
140  [2] = 1 | DMA_CH_VALID,
141  [3] = 0 | DMA_CH_VALID,
142  },
143  },
144  [DMACH_I2S_IN] = {
145  .list = {
146  [0] = 1 | DMA_CH_VALID,
147  [1] = 2 | DMA_CH_VALID,
148  },
149  },
150  [DMACH_I2S_OUT] = {
151  .list = {
152  [0] = 2 | DMA_CH_VALID,
153  [1] = 1 | DMA_CH_VALID,
154  },
155  },
156  [DMACH_PCM_IN] = {
157  .list = {
158  [0] = 2 | DMA_CH_VALID,
159  [1] = 1 | DMA_CH_VALID,
160  },
161  },
162  [DMACH_PCM_OUT] = {
163  .list = {
164  [0] = 1 | DMA_CH_VALID,
165  [1] = 3 | DMA_CH_VALID,
166  },
167  },
168  [DMACH_MIC_IN] = {
169  .list = {
170  [0] = 3 | DMA_CH_VALID,
171  [1] = 2 | DMA_CH_VALID,
172  },
173  },
174  },
175 };
176 
177 static int __init s3c2440_dma_add(struct device *dev,
178  struct subsys_interface *sif)
179 {
181  s3c24xx_dma_order_set(&s3c2440_dma_order);
182  return s3c24xx_dma_init_map(&s3c2440_dma_sel);
183 }
184 
185 static struct subsys_interface s3c2440_dma_interface = {
186  .name = "s3c2440_dma",
187  .subsys = &s3c2440_subsys,
188  .add_dev = s3c2440_dma_add,
189 };
190 
191 static int __init s3c2440_dma_init(void)
192 {
193  return subsys_interface_register(&s3c2440_dma_interface);
194 }
195 
196 arch_initcall(s3c2440_dma_init);
197