blob: 89c5a62830a7023196d97491047713b34ced152b [file] [log] [blame]
Tomasz Figa1db02872013-10-16 21:10:54 +02001/*
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
Arnd Bergmanna0e157a2015-02-27 20:31:51 +010017#include <plat/cpu.h>
Tomasz Figa1db02872013-10-16 21:10:54 +020018#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{
Arnd Bergmanna0e157a2015-02-27 20:31:51 +0100234 if (!soc_is_s3c64xx())
235 return 0;
236
Tomasz Figa1db02872013-10-16 21:10:54 +0200237 /* 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);