0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/amba/bus.h>
0009 #include <linux/amba/pl080.h>
0010 #include <linux/amba/pl08x.h>
0011 #include <linux/of.h>
0012
0013 #include "cpu.h"
0014 #include "irqs.h"
0015 #include "map.h"
0016
0017 #include "regs-sys-s3c64xx.h"
0018
0019 static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd)
0020 {
0021 return cd->min_signal;
0022 }
0023
0024 static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch)
0025 {
0026 }
0027
0028
0029
0030
0031
0032 static struct pl08x_channel_data s3c64xx_dma0_info[] = {
0033 {
0034 .bus_id = "uart0_tx",
0035 .min_signal = 0,
0036 .max_signal = 0,
0037 .periph_buses = PL08X_AHB2,
0038 }, {
0039 .bus_id = "uart0_rx",
0040 .min_signal = 1,
0041 .max_signal = 1,
0042 .periph_buses = PL08X_AHB2,
0043 }, {
0044 .bus_id = "uart1_tx",
0045 .min_signal = 2,
0046 .max_signal = 2,
0047 .periph_buses = PL08X_AHB2,
0048 }, {
0049 .bus_id = "uart1_rx",
0050 .min_signal = 3,
0051 .max_signal = 3,
0052 .periph_buses = PL08X_AHB2,
0053 }, {
0054 .bus_id = "uart2_tx",
0055 .min_signal = 4,
0056 .max_signal = 4,
0057 .periph_buses = PL08X_AHB2,
0058 }, {
0059 .bus_id = "uart2_rx",
0060 .min_signal = 5,
0061 .max_signal = 5,
0062 .periph_buses = PL08X_AHB2,
0063 }, {
0064 .bus_id = "uart3_tx",
0065 .min_signal = 6,
0066 .max_signal = 6,
0067 .periph_buses = PL08X_AHB2,
0068 }, {
0069 .bus_id = "uart3_rx",
0070 .min_signal = 7,
0071 .max_signal = 7,
0072 .periph_buses = PL08X_AHB2,
0073 }, {
0074 .bus_id = "pcm0_tx",
0075 .min_signal = 8,
0076 .max_signal = 8,
0077 .periph_buses = PL08X_AHB2,
0078 }, {
0079 .bus_id = "pcm0_rx",
0080 .min_signal = 9,
0081 .max_signal = 9,
0082 .periph_buses = PL08X_AHB2,
0083 }, {
0084 .bus_id = "i2s0_tx",
0085 .min_signal = 10,
0086 .max_signal = 10,
0087 .periph_buses = PL08X_AHB2,
0088 }, {
0089 .bus_id = "i2s0_rx",
0090 .min_signal = 11,
0091 .max_signal = 11,
0092 .periph_buses = PL08X_AHB2,
0093 }, {
0094 .bus_id = "spi0_tx",
0095 .min_signal = 12,
0096 .max_signal = 12,
0097 .periph_buses = PL08X_AHB2,
0098 }, {
0099 .bus_id = "spi0_rx",
0100 .min_signal = 13,
0101 .max_signal = 13,
0102 .periph_buses = PL08X_AHB2,
0103 }, {
0104 .bus_id = "i2s2_tx",
0105 .min_signal = 14,
0106 .max_signal = 14,
0107 .periph_buses = PL08X_AHB2,
0108 }, {
0109 .bus_id = "i2s2_rx",
0110 .min_signal = 15,
0111 .max_signal = 15,
0112 .periph_buses = PL08X_AHB2,
0113 }
0114 };
0115
0116 static const struct dma_slave_map s3c64xx_dma0_slave_map[] = {
0117 { "s3c6400-uart.0", "tx", &s3c64xx_dma0_info[0] },
0118 { "s3c6400-uart.0", "rx", &s3c64xx_dma0_info[1] },
0119 { "s3c6400-uart.1", "tx", &s3c64xx_dma0_info[2] },
0120 { "s3c6400-uart.1", "rx", &s3c64xx_dma0_info[3] },
0121 { "s3c6400-uart.2", "tx", &s3c64xx_dma0_info[4] },
0122 { "s3c6400-uart.2", "rx", &s3c64xx_dma0_info[5] },
0123 { "s3c6400-uart.3", "tx", &s3c64xx_dma0_info[6] },
0124 { "s3c6400-uart.3", "rx", &s3c64xx_dma0_info[7] },
0125 { "samsung-pcm.0", "tx", &s3c64xx_dma0_info[8] },
0126 { "samsung-pcm.0", "rx", &s3c64xx_dma0_info[9] },
0127 { "samsung-i2s.0", "tx", &s3c64xx_dma0_info[10] },
0128 { "samsung-i2s.0", "rx", &s3c64xx_dma0_info[11] },
0129 { "s3c6410-spi.0", "tx", &s3c64xx_dma0_info[12] },
0130 { "s3c6410-spi.0", "rx", &s3c64xx_dma0_info[13] },
0131 { "samsung-i2s.2", "tx", &s3c64xx_dma0_info[14] },
0132 { "samsung-i2s.2", "rx", &s3c64xx_dma0_info[15] },
0133 };
0134
0135 struct pl08x_platform_data s3c64xx_dma0_plat_data = {
0136 .memcpy_burst_size = PL08X_BURST_SZ_4,
0137 .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
0138 .memcpy_prot_buff = true,
0139 .memcpy_prot_cache = true,
0140 .lli_buses = PL08X_AHB1,
0141 .mem_buses = PL08X_AHB1,
0142 .get_xfer_signal = pl08x_get_xfer_signal,
0143 .put_xfer_signal = pl08x_put_xfer_signal,
0144 .slave_channels = s3c64xx_dma0_info,
0145 .num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
0146 .slave_map = s3c64xx_dma0_slave_map,
0147 .slave_map_len = ARRAY_SIZE(s3c64xx_dma0_slave_map),
0148 };
0149
0150 static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
0151 0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);
0152
0153
0154
0155
0156
0157 static struct pl08x_channel_data s3c64xx_dma1_info[] = {
0158 {
0159 .bus_id = "pcm1_tx",
0160 .min_signal = 0,
0161 .max_signal = 0,
0162 .periph_buses = PL08X_AHB2,
0163 }, {
0164 .bus_id = "pcm1_rx",
0165 .min_signal = 1,
0166 .max_signal = 1,
0167 .periph_buses = PL08X_AHB2,
0168 }, {
0169 .bus_id = "i2s1_tx",
0170 .min_signal = 2,
0171 .max_signal = 2,
0172 .periph_buses = PL08X_AHB2,
0173 }, {
0174 .bus_id = "i2s1_rx",
0175 .min_signal = 3,
0176 .max_signal = 3,
0177 .periph_buses = PL08X_AHB2,
0178 }, {
0179 .bus_id = "spi1_tx",
0180 .min_signal = 4,
0181 .max_signal = 4,
0182 .periph_buses = PL08X_AHB2,
0183 }, {
0184 .bus_id = "spi1_rx",
0185 .min_signal = 5,
0186 .max_signal = 5,
0187 .periph_buses = PL08X_AHB2,
0188 }, {
0189 .bus_id = "ac97_out",
0190 .min_signal = 6,
0191 .max_signal = 6,
0192 .periph_buses = PL08X_AHB2,
0193 }, {
0194 .bus_id = "ac97_in",
0195 .min_signal = 7,
0196 .max_signal = 7,
0197 .periph_buses = PL08X_AHB2,
0198 }, {
0199 .bus_id = "ac97_mic",
0200 .min_signal = 8,
0201 .max_signal = 8,
0202 .periph_buses = PL08X_AHB2,
0203 }, {
0204 .bus_id = "pwm",
0205 .min_signal = 9,
0206 .max_signal = 9,
0207 .periph_buses = PL08X_AHB2,
0208 }, {
0209 .bus_id = "irda",
0210 .min_signal = 10,
0211 .max_signal = 10,
0212 .periph_buses = PL08X_AHB2,
0213 }, {
0214 .bus_id = "external",
0215 .min_signal = 11,
0216 .max_signal = 11,
0217 .periph_buses = PL08X_AHB2,
0218 },
0219 };
0220
0221 static const struct dma_slave_map s3c64xx_dma1_slave_map[] = {
0222 { "samsung-pcm.1", "tx", &s3c64xx_dma1_info[0] },
0223 { "samsung-pcm.1", "rx", &s3c64xx_dma1_info[1] },
0224 { "samsung-i2s.1", "tx", &s3c64xx_dma1_info[2] },
0225 { "samsung-i2s.1", "rx", &s3c64xx_dma1_info[3] },
0226 { "s3c6410-spi.1", "tx", &s3c64xx_dma1_info[4] },
0227 { "s3c6410-spi.1", "rx", &s3c64xx_dma1_info[5] },
0228 };
0229
0230 struct pl08x_platform_data s3c64xx_dma1_plat_data = {
0231 .memcpy_burst_size = PL08X_BURST_SZ_4,
0232 .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
0233 .memcpy_prot_buff = true,
0234 .memcpy_prot_cache = true,
0235 .lli_buses = PL08X_AHB1,
0236 .mem_buses = PL08X_AHB1,
0237 .get_xfer_signal = pl08x_get_xfer_signal,
0238 .put_xfer_signal = pl08x_put_xfer_signal,
0239 .slave_channels = s3c64xx_dma1_info,
0240 .num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
0241 .slave_map = s3c64xx_dma1_slave_map,
0242 .slave_map_len = ARRAY_SIZE(s3c64xx_dma1_slave_map),
0243 };
0244
0245 static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
0246 0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);
0247
0248 static int __init s3c64xx_pl080_init(void)
0249 {
0250 if (!soc_is_s3c64xx())
0251 return 0;
0252
0253
0254 writel(0xffffff, S3C64XX_SDMA_SEL);
0255
0256 if (of_have_populated_dt())
0257 return 0;
0258
0259 amba_device_register(&s3c64xx_dma0_device, &iomem_resource);
0260 amba_device_register(&s3c64xx_dma1_device, &iomem_resource);
0261
0262 return 0;
0263 }
0264 arch_initcall(s3c64xx_pl080_init);