aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c2412/dma.c39
-rw-r--r--arch/arm/plat-s3c24xx/dma.c16
-rw-r--r--include/asm-arm/plat-s3c24xx/dma.h5
3 files changed, 54 insertions, 6 deletions
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index c9cd51439126..1dd864993566 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -40,106 +40,141 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
40 [DMACH_XD0] = { 40 [DMACH_XD0] = {
41 .name = "xdreq0", 41 .name = "xdreq0",
42 .channels = MAP(S3C2412_DMAREQSEL_XDREQ0), 42 .channels = MAP(S3C2412_DMAREQSEL_XDREQ0),
43 .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ0),
43 }, 44 },
44 [DMACH_XD1] = { 45 [DMACH_XD1] = {
45 .name = "xdreq1", 46 .name = "xdreq1",
46 .channels = MAP(S3C2412_DMAREQSEL_XDREQ1), 47 .channels = MAP(S3C2412_DMAREQSEL_XDREQ1),
48 .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ1),
47 }, 49 },
48 [DMACH_SDI] = { 50 [DMACH_SDI] = {
49 .name = "sdi", 51 .name = "sdi",
50 .channels = MAP(S3C2412_DMAREQSEL_SDI), 52 .channels = MAP(S3C2412_DMAREQSEL_SDI),
53 .channels_rx = MAP(S3C2412_DMAREQSEL_SDI),
51 .hw_addr.to = S3C2410_PA_SDI + S3C2410_SDIDATA, 54 .hw_addr.to = S3C2410_PA_SDI + S3C2410_SDIDATA,
52 .hw_addr.from = S3C2410_PA_SDI + S3C2410_SDIDATA, 55 .hw_addr.from = S3C2410_PA_SDI + S3C2410_SDIDATA,
53 }, 56 },
54 [DMACH_SPI0] = { 57 [DMACH_SPI0] = {
55 .name = "spi0", 58 .name = "spi0",
56 .channels = MAP(S3C2412_DMAREQSEL_SPI0TX), 59 .channels = MAP(S3C2412_DMAREQSEL_SPI0TX),
60 .channels_rx = MAP(S3C2412_DMAREQSEL_SPI0RX),
57 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, 61 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
58 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, 62 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
59 }, 63 },
60 [DMACH_SPI1] = { 64 [DMACH_SPI1] = {
61 .name = "spi1", 65 .name = "spi1",
62 .channels = MAP(S3C2412_DMAREQSEL_SPI1TX), 66 .channels = MAP(S3C2412_DMAREQSEL_SPI1TX),
67 .channels_rx = MAP(S3C2412_DMAREQSEL_SPI1RX),
63 .hw_addr.to = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT, 68 .hw_addr.to = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT,
64 .hw_addr.from = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPRDAT, 69 .hw_addr.from = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPRDAT,
65 }, 70 },
66 [DMACH_UART0] = { 71 [DMACH_UART0] = {
67 .name = "uart0", 72 .name = "uart0",
68 .channels = MAP(S3C2412_DMAREQSEL_UART0_0), 73 .channels = MAP(S3C2412_DMAREQSEL_UART0_0),
74 .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_0),
69 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, 75 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
70 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, 76 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
71 }, 77 },
72 [DMACH_UART1] = { 78 [DMACH_UART1] = {
73 .name = "uart1", 79 .name = "uart1",
74 .channels = MAP(S3C2412_DMAREQSEL_UART1_0), 80 .channels = MAP(S3C2412_DMAREQSEL_UART1_0),
81 .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_0),
75 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, 82 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
76 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, 83 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
77 }, 84 },
78 [DMACH_UART2] = { 85 [DMACH_UART2] = {
79 .name = "uart2", 86 .name = "uart2",
80 .channels = MAP(S3C2412_DMAREQSEL_UART2_0), 87 .channels = MAP(S3C2412_DMAREQSEL_UART2_0),
88 .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_0),
81 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, 89 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
82 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, 90 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
83 }, 91 },
84 [DMACH_UART0_SRC2] = { 92 [DMACH_UART0_SRC2] = {
85 .name = "uart0", 93 .name = "uart0",
86 .channels = MAP(S3C2412_DMAREQSEL_UART0_1), 94 .channels = MAP(S3C2412_DMAREQSEL_UART0_1),
95 .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_1),
87 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, 96 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
88 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, 97 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
89 }, 98 },
90 [DMACH_UART1_SRC2] = { 99 [DMACH_UART1_SRC2] = {
91 .name = "uart1", 100 .name = "uart1",
92 .channels = MAP(S3C2412_DMAREQSEL_UART1_1), 101 .channels = MAP(S3C2412_DMAREQSEL_UART1_1),
102 .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_1),
93 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, 103 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
94 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, 104 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
95 }, 105 },
96 [DMACH_UART2_SRC2] = { 106 [DMACH_UART2_SRC2] = {
97 .name = "uart2", 107 .name = "uart2",
98 .channels = MAP(S3C2412_DMAREQSEL_UART2_1), 108 .channels = MAP(S3C2412_DMAREQSEL_UART2_1),
109 .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_1),
99 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, 110 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
100 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, 111 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
101 }, 112 },
102 [DMACH_TIMER] = { 113 [DMACH_TIMER] = {
103 .name = "timer", 114 .name = "timer",
104 .channels = MAP(S3C2412_DMAREQSEL_TIMER), 115 .channels = MAP(S3C2412_DMAREQSEL_TIMER),
116 .channels_rx = MAP(S3C2412_DMAREQSEL_TIMER),
105 }, 117 },
106 [DMACH_I2S_IN] = { 118 [DMACH_I2S_IN] = {
107 .name = "i2s-sdi", 119 .name = "i2s-sdi",
108 .channels = MAP(S3C2412_DMAREQSEL_I2SRX), 120 .channels = MAP(S3C2412_DMAREQSEL_I2SRX),
121 .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX),
109 .hw_addr.from = S3C2410_PA_IIS + S3C2412_IISRXD, 122 .hw_addr.from = S3C2410_PA_IIS + S3C2412_IISRXD,
110 }, 123 },
111 [DMACH_I2S_OUT] = { 124 [DMACH_I2S_OUT] = {
112 .name = "i2s-sdo", 125 .name = "i2s-sdo",
113 .channels = MAP(S3C2412_DMAREQSEL_I2STX), 126 .channels = MAP(S3C2412_DMAREQSEL_I2STX),
127 .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX),
114 .hw_addr.to = S3C2410_PA_IIS + S3C2412_IISTXD, 128 .hw_addr.to = S3C2410_PA_IIS + S3C2412_IISTXD,
115 }, 129 },
116 [DMACH_USB_EP1] = { 130 [DMACH_USB_EP1] = {
117 .name = "usb-ep1", 131 .name = "usb-ep1",
118 .channels = MAP(S3C2412_DMAREQSEL_USBEP1), 132 .channels = MAP(S3C2412_DMAREQSEL_USBEP1),
133 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP1),
119 }, 134 },
120 [DMACH_USB_EP2] = { 135 [DMACH_USB_EP2] = {
121 .name = "usb-ep2", 136 .name = "usb-ep2",
122 .channels = MAP(S3C2412_DMAREQSEL_USBEP2), 137 .channels = MAP(S3C2412_DMAREQSEL_USBEP2),
138 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP2),
123 }, 139 },
124 [DMACH_USB_EP3] = { 140 [DMACH_USB_EP3] = {
125 .name = "usb-ep3", 141 .name = "usb-ep3",
126 .channels = MAP(S3C2412_DMAREQSEL_USBEP3), 142 .channels = MAP(S3C2412_DMAREQSEL_USBEP3),
143 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP3),
127 }, 144 },
128 [DMACH_USB_EP4] = { 145 [DMACH_USB_EP4] = {
129 .name = "usb-ep4", 146 .name = "usb-ep4",
130 .channels = MAP(S3C2412_DMAREQSEL_USBEP4), 147 .channels = MAP(S3C2412_DMAREQSEL_USBEP4),
148 .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP4),
131 }, 149 },
132}; 150};
133 151
152static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
153 struct s3c24xx_dma_map *map,
154 enum s3c2410_dmasrc dir)
155{
156 unsigned long chsel;
157
158 if (dir == S3C2410_DMASRC_HW)
159 chsel = map->channels_rx[0];
160 else
161 chsel = map->channels[0];
162
163 chsel &= ~DMA_CH_VALID;
164 chsel |= S3C2412_DMAREQSEL_HW;
165
166 writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL);
167}
168
134static void s3c2412_dma_select(struct s3c2410_dma_chan *chan, 169static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
135 struct s3c24xx_dma_map *map) 170 struct s3c24xx_dma_map *map)
136{ 171{
137 writel(map->channels[0] | S3C2412_DMAREQSEL_HW, 172 s3c2412_dma_direction(chan, map, chan->source);
138 chan->regs + S3C2412_DMA_DMAREQSEL);
139} 173}
140 174
141static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { 175static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
142 .select = s3c2412_dma_select, 176 .select = s3c2412_dma_select,
177 .direction = s3c2412_dma_direction,
143 .dcon_mask = 0, 178 .dcon_mask = 0,
144 .map = s3c2412_dma_mappings, 179 .map = s3c2412_dma_mappings,
145 .map_size = ARRAY_SIZE(s3c2412_dma_mappings), 180 .map_size = ARRAY_SIZE(s3c2412_dma_mappings),
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index aae1b9cbaf44..10ef3995b114 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -1184,7 +1184,7 @@ int s3c2410_dma_devconfig(int channel,
1184 dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0)); 1184 dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
1185 1185
1186 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST); 1186 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
1187 return 0; 1187 break;
1188 1188
1189 case S3C2410_DMASRC_MEM: 1189 case S3C2410_DMASRC_MEM:
1190 /* source is memory */ 1190 /* source is memory */
@@ -1195,11 +1195,19 @@ int s3c2410_dma_devconfig(int channel,
1195 dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3); 1195 dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
1196 1196
1197 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC); 1197 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
1198 return 0; 1198 break;
1199
1200 default:
1201 printk(KERN_ERR "dma%d: invalid source type (%d)\n",
1202 channel, source);
1203
1204 return -EINVAL;
1199 } 1205 }
1200 1206
1201 printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source); 1207 if (dma_sel.direction != NULL)
1202 return -EINVAL; 1208 (dma_sel.direction)(chan, chan->map, source);
1209
1210 return 0;
1203} 1211}
1204 1212
1205EXPORT_SYMBOL(s3c2410_dma_devconfig); 1213EXPORT_SYMBOL(s3c2410_dma_devconfig);
diff --git a/include/asm-arm/plat-s3c24xx/dma.h b/include/asm-arm/plat-s3c24xx/dma.h
index 2c59406435e5..c78efe316fc8 100644
--- a/include/asm-arm/plat-s3c24xx/dma.h
+++ b/include/asm-arm/plat-s3c24xx/dma.h
@@ -32,6 +32,7 @@ struct s3c24xx_dma_map {
32 struct s3c24xx_dma_addr hw_addr; 32 struct s3c24xx_dma_addr hw_addr;
33 33
34 unsigned long channels[S3C2410_DMA_CHANNELS]; 34 unsigned long channels[S3C2410_DMA_CHANNELS];
35 unsigned long channels_rx[S3C2410_DMA_CHANNELS];
35}; 36};
36 37
37struct s3c24xx_dma_selection { 38struct s3c24xx_dma_selection {
@@ -41,6 +42,10 @@ struct s3c24xx_dma_selection {
41 42
42 void (*select)(struct s3c2410_dma_chan *chan, 43 void (*select)(struct s3c2410_dma_chan *chan,
43 struct s3c24xx_dma_map *map); 44 struct s3c24xx_dma_map *map);
45
46 void (*direction)(struct s3c2410_dma_chan *chan,
47 struct s3c24xx_dma_map *map,
48 enum s3c2410_dmasrc dir);
44}; 49};
45 50
46extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); 51extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);