Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Samsung's S3C64XX generic DMA support using amba-pl08x driver.
0004 //
0005 // Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
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  * DMA0
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  * DMA1
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     /* Set all DMA configuration to be DMA, not SDMA */
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);