blob: 9e3478506c6f67ef1dd307971b2d7786b32f1104 [file] [log] [blame]
Ben Dooksa21765a2007-02-11 18:31:01 +01001/* linux/arch/arm/mach-s3c2412/dma.c
Ben Dooks34348012006-09-18 23:52:03 +01002 *
Ben Dooksc16f7bd2006-12-17 20:05:21 +01003 * Copyright (c) 2006 Simtec Electronics
Ben Dooks34348012006-09-18 23:52:03 +01004 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2412 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/sysdev.h>
Ben Dooksb6d1f542006-12-17 23:22:26 +010018#include <linux/serial_core.h>
Russell Kingfced80c2008-09-06 12:10:45 +010019#include <linux/io.h>
Ben Dooks34348012006-09-18 23:52:03 +010020
Russell Kinga09e64f2008-08-05 16:14:15 +010021#include <mach/dma.h>
Ben Dooks34348012006-09-18 23:52:03 +010022
Ben Dooksd5120ae2008-10-07 23:09:51 +010023#include <plat/dma.h>
Ben Dooksa2b7ba92008-10-07 22:26:09 +010024#include <plat/cpu.h>
Ben Dooks34348012006-09-18 23:52:03 +010025
Ben Dooksa2b7ba92008-10-07 22:26:09 +010026#include <plat/regs-serial.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010027#include <mach/regs-gpio.h>
Ben Dooksf74c95c2008-10-30 10:14:36 +000028#include <plat/regs-ac97.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010029#include <mach/regs-mem.h>
30#include <mach/regs-lcd.h>
31#include <mach/regs-sdi.h>
Ben Dooks8150bc82009-03-04 00:49:26 +000032#include <plat/regs-s3c2412-iis.h>
33#include <plat/regs-iis.h>
Ben Dooks13622702008-10-30 10:14:38 +000034#include <plat/regs-spi.h>
Ben Dooks34348012006-09-18 23:52:03 +010035
36#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
37
38static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
39 [DMACH_XD0] = {
40 .name = "xdreq0",
41 .channels = MAP(S3C2412_DMAREQSEL_XDREQ0),
Ben Dooksc6709e82008-01-28 13:01:20 +010042 .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ0),
Ben Dooks34348012006-09-18 23:52:03 +010043 },
44 [DMACH_XD1] = {
45 .name = "xdreq1",
46 .channels = MAP(S3C2412_DMAREQSEL_XDREQ1),
Ben Dooksc6709e82008-01-28 13:01:20 +010047 .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ1),
Ben Dooks34348012006-09-18 23:52:03 +010048 },
49 [DMACH_SDI] = {
50 .name = "sdi",
51 .channels = MAP(S3C2412_DMAREQSEL_SDI),
Ben Dooksc6709e82008-01-28 13:01:20 +010052 .channels_rx = MAP(S3C2412_DMAREQSEL_SDI),
Ben Dooksd45c30c2007-12-23 03:09:40 +010053 .hw_addr.to = S3C2410_PA_SDI + S3C2410_SDIDATA,
54 .hw_addr.from = S3C2410_PA_SDI + S3C2410_SDIDATA,
Ben Dooks34348012006-09-18 23:52:03 +010055 },
56 [DMACH_SPI0] = {
57 .name = "spi0",
58 .channels = MAP(S3C2412_DMAREQSEL_SPI0TX),
Ben Dooksc6709e82008-01-28 13:01:20 +010059 .channels_rx = MAP(S3C2412_DMAREQSEL_SPI0RX),
Ben Dooks34348012006-09-18 23:52:03 +010060 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
61 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
62 },
63 [DMACH_SPI1] = {
64 .name = "spi1",
65 .channels = MAP(S3C2412_DMAREQSEL_SPI1TX),
Ben Dooksc6709e82008-01-28 13:01:20 +010066 .channels_rx = MAP(S3C2412_DMAREQSEL_SPI1RX),
Sandeep Sanjay Patile9033822007-05-16 10:51:45 +010067 .hw_addr.to = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT,
68 .hw_addr.from = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPRDAT,
Ben Dooks34348012006-09-18 23:52:03 +010069 },
70 [DMACH_UART0] = {
71 .name = "uart0",
72 .channels = MAP(S3C2412_DMAREQSEL_UART0_0),
Ben Dooksc6709e82008-01-28 13:01:20 +010073 .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_0),
Ben Dooks34348012006-09-18 23:52:03 +010074 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
75 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
76 },
77 [DMACH_UART1] = {
78 .name = "uart1",
79 .channels = MAP(S3C2412_DMAREQSEL_UART1_0),
Ben Dooksc6709e82008-01-28 13:01:20 +010080 .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_0),
Ben Dooks34348012006-09-18 23:52:03 +010081 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
82 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
83 },
84 [DMACH_UART2] = {
85 .name = "uart2",
86 .channels = MAP(S3C2412_DMAREQSEL_UART2_0),
Ben Dooksc6709e82008-01-28 13:01:20 +010087 .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_0),
Ben Dooks34348012006-09-18 23:52:03 +010088 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
89 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
90 },
91 [DMACH_UART0_SRC2] = {
92 .name = "uart0",
93 .channels = MAP(S3C2412_DMAREQSEL_UART0_1),
Ben Dooksc6709e82008-01-28 13:01:20 +010094 .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_1),
Ben Dooks34348012006-09-18 23:52:03 +010095 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
96 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
97 },
98 [DMACH_UART1_SRC2] = {
99 .name = "uart1",
100 .channels = MAP(S3C2412_DMAREQSEL_UART1_1),
Ben Dooksc6709e82008-01-28 13:01:20 +0100101 .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_1),
Ben Dooks34348012006-09-18 23:52:03 +0100102 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
103 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
104 },
105 [DMACH_UART2_SRC2] = {
106 .name = "uart2",
107 .channels = MAP(S3C2412_DMAREQSEL_UART2_1),
Ben Dooksc6709e82008-01-28 13:01:20 +0100108 .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_1),
Ben Dooks34348012006-09-18 23:52:03 +0100109 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
110 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
111 },
112 [DMACH_TIMER] = {
113 .name = "timer",
114 .channels = MAP(S3C2412_DMAREQSEL_TIMER),
Ben Dooksc6709e82008-01-28 13:01:20 +0100115 .channels_rx = MAP(S3C2412_DMAREQSEL_TIMER),
Ben Dooks34348012006-09-18 23:52:03 +0100116 },
117 [DMACH_I2S_IN] = {
118 .name = "i2s-sdi",
119 .channels = MAP(S3C2412_DMAREQSEL_I2SRX),
Ben Dooksc6709e82008-01-28 13:01:20 +0100120 .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX),
Ben Dooksd45c30c2007-12-23 03:09:40 +0100121 .hw_addr.from = S3C2410_PA_IIS + S3C2412_IISRXD,
Ben Dooks34348012006-09-18 23:52:03 +0100122 },
123 [DMACH_I2S_OUT] = {
124 .name = "i2s-sdo",
125 .channels = MAP(S3C2412_DMAREQSEL_I2STX),
Ben Dooksc6709e82008-01-28 13:01:20 +0100126 .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX),
Ben Dooksd45c30c2007-12-23 03:09:40 +0100127 .hw_addr.to = S3C2410_PA_IIS + S3C2412_IISTXD,
Ben Dooks34348012006-09-18 23:52:03 +0100128 },
129 [DMACH_USB_EP1] = {
130 .name = "usb-ep1",
131 .channels = MAP(S3C2412_DMAREQSEL_USBEP1),
Ben Dooksc6709e82008-01-28 13:01:20 +0100132 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP1),
Ben Dooks34348012006-09-18 23:52:03 +0100133 },
134 [DMACH_USB_EP2] = {
135 .name = "usb-ep2",
136 .channels = MAP(S3C2412_DMAREQSEL_USBEP2),
Ben Dooksc6709e82008-01-28 13:01:20 +0100137 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP2),
Ben Dooks34348012006-09-18 23:52:03 +0100138 },
139 [DMACH_USB_EP3] = {
140 .name = "usb-ep3",
141 .channels = MAP(S3C2412_DMAREQSEL_USBEP3),
Ben Dooksc6709e82008-01-28 13:01:20 +0100142 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP3),
Ben Dooks34348012006-09-18 23:52:03 +0100143 },
144 [DMACH_USB_EP4] = {
145 .name = "usb-ep4",
146 .channels = MAP(S3C2412_DMAREQSEL_USBEP4),
Ben Dooksc6709e82008-01-28 13:01:20 +0100147 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP4),
Ben Dooks34348012006-09-18 23:52:03 +0100148 },
149};
150
Ben Dooksc6709e82008-01-28 13:01:20 +0100151static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
152 struct s3c24xx_dma_map *map,
153 enum s3c2410_dmasrc dir)
154{
155 unsigned long chsel;
156
157 if (dir == S3C2410_DMASRC_HW)
158 chsel = map->channels_rx[0];
159 else
160 chsel = map->channels[0];
161
162 chsel &= ~DMA_CH_VALID;
163 chsel |= S3C2412_DMAREQSEL_HW;
164
165 writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL);
166}
167
Ben Dooks34348012006-09-18 23:52:03 +0100168static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
169 struct s3c24xx_dma_map *map)
170{
Ben Dooksc6709e82008-01-28 13:01:20 +0100171 s3c2412_dma_direction(chan, map, chan->source);
Ben Dooks34348012006-09-18 23:52:03 +0100172}
173
174static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
175 .select = s3c2412_dma_select,
Ben Dooksc6709e82008-01-28 13:01:20 +0100176 .direction = s3c2412_dma_direction,
Ben Dooks34348012006-09-18 23:52:03 +0100177 .dcon_mask = 0,
178 .map = s3c2412_dma_mappings,
179 .map_size = ARRAY_SIZE(s3c2412_dma_mappings),
180};
181
Krzysztof Heltf2c10d62007-09-04 17:19:33 +0100182static int __init s3c2412_dma_add(struct sys_device *sysdev)
Ben Dooks34348012006-09-18 23:52:03 +0100183{
Ben Dooks48adbcf2007-02-17 15:37:14 +0100184 s3c2410_dma_init();
Ben Dooks34348012006-09-18 23:52:03 +0100185 return s3c24xx_dma_init_map(&s3c2412_dma_sel);
186}
187
188static struct sysdev_driver s3c2412_dma_driver = {
189 .add = s3c2412_dma_add,
190};
191
192static int __init s3c2412_dma_init(void)
193{
194 return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver);
195}
196
197arch_initcall(s3c2412_dma_init);