mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
264 lines
6.2 KiB
264 lines
6.2 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
// |
|
// Samsung's S3C64XX generic DMA support using amba-pl08x driver. |
|
// |
|
// Copyright (c) 2013 Tomasz Figa <[email protected]> |
|
|
|
#include <linux/kernel.h> |
|
#include <linux/amba/bus.h> |
|
#include <linux/amba/pl080.h> |
|
#include <linux/amba/pl08x.h> |
|
#include <linux/of.h> |
|
|
|
#include "cpu.h" |
|
#include <mach/irqs.h> |
|
#include "map.h" |
|
|
|
#include "regs-sys-s3c64xx.h" |
|
|
|
static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd) |
|
{ |
|
return cd->min_signal; |
|
} |
|
|
|
static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch) |
|
{ |
|
} |
|
|
|
/* |
|
* DMA0 |
|
*/ |
|
|
|
static struct pl08x_channel_data s3c64xx_dma0_info[] = { |
|
{ |
|
.bus_id = "uart0_tx", |
|
.min_signal = 0, |
|
.max_signal = 0, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "uart0_rx", |
|
.min_signal = 1, |
|
.max_signal = 1, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "uart1_tx", |
|
.min_signal = 2, |
|
.max_signal = 2, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "uart1_rx", |
|
.min_signal = 3, |
|
.max_signal = 3, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "uart2_tx", |
|
.min_signal = 4, |
|
.max_signal = 4, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "uart2_rx", |
|
.min_signal = 5, |
|
.max_signal = 5, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "uart3_tx", |
|
.min_signal = 6, |
|
.max_signal = 6, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "uart3_rx", |
|
.min_signal = 7, |
|
.max_signal = 7, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "pcm0_tx", |
|
.min_signal = 8, |
|
.max_signal = 8, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "pcm0_rx", |
|
.min_signal = 9, |
|
.max_signal = 9, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "i2s0_tx", |
|
.min_signal = 10, |
|
.max_signal = 10, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "i2s0_rx", |
|
.min_signal = 11, |
|
.max_signal = 11, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "spi0_tx", |
|
.min_signal = 12, |
|
.max_signal = 12, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "spi0_rx", |
|
.min_signal = 13, |
|
.max_signal = 13, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "i2s2_tx", |
|
.min_signal = 14, |
|
.max_signal = 14, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "i2s2_rx", |
|
.min_signal = 15, |
|
.max_signal = 15, |
|
.periph_buses = PL08X_AHB2, |
|
} |
|
}; |
|
|
|
static const struct dma_slave_map s3c64xx_dma0_slave_map[] = { |
|
{ "s3c6400-uart.0", "tx", &s3c64xx_dma0_info[0] }, |
|
{ "s3c6400-uart.0", "rx", &s3c64xx_dma0_info[1] }, |
|
{ "s3c6400-uart.1", "tx", &s3c64xx_dma0_info[2] }, |
|
{ "s3c6400-uart.1", "rx", &s3c64xx_dma0_info[3] }, |
|
{ "s3c6400-uart.2", "tx", &s3c64xx_dma0_info[4] }, |
|
{ "s3c6400-uart.2", "rx", &s3c64xx_dma0_info[5] }, |
|
{ "s3c6400-uart.3", "tx", &s3c64xx_dma0_info[6] }, |
|
{ "s3c6400-uart.3", "rx", &s3c64xx_dma0_info[7] }, |
|
{ "samsung-pcm.0", "tx", &s3c64xx_dma0_info[8] }, |
|
{ "samsung-pcm.0", "rx", &s3c64xx_dma0_info[9] }, |
|
{ "samsung-i2s.0", "tx", &s3c64xx_dma0_info[10] }, |
|
{ "samsung-i2s.0", "rx", &s3c64xx_dma0_info[11] }, |
|
{ "s3c6410-spi.0", "tx", &s3c64xx_dma0_info[12] }, |
|
{ "s3c6410-spi.0", "rx", &s3c64xx_dma0_info[13] }, |
|
{ "samsung-i2s.2", "tx", &s3c64xx_dma0_info[14] }, |
|
{ "samsung-i2s.2", "rx", &s3c64xx_dma0_info[15] }, |
|
}; |
|
|
|
struct pl08x_platform_data s3c64xx_dma0_plat_data = { |
|
.memcpy_burst_size = PL08X_BURST_SZ_4, |
|
.memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS, |
|
.memcpy_prot_buff = true, |
|
.memcpy_prot_cache = true, |
|
.lli_buses = PL08X_AHB1, |
|
.mem_buses = PL08X_AHB1, |
|
.get_xfer_signal = pl08x_get_xfer_signal, |
|
.put_xfer_signal = pl08x_put_xfer_signal, |
|
.slave_channels = s3c64xx_dma0_info, |
|
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info), |
|
.slave_map = s3c64xx_dma0_slave_map, |
|
.slave_map_len = ARRAY_SIZE(s3c64xx_dma0_slave_map), |
|
}; |
|
|
|
static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0, |
|
0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data); |
|
|
|
/* |
|
* DMA1 |
|
*/ |
|
|
|
static struct pl08x_channel_data s3c64xx_dma1_info[] = { |
|
{ |
|
.bus_id = "pcm1_tx", |
|
.min_signal = 0, |
|
.max_signal = 0, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "pcm1_rx", |
|
.min_signal = 1, |
|
.max_signal = 1, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "i2s1_tx", |
|
.min_signal = 2, |
|
.max_signal = 2, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "i2s1_rx", |
|
.min_signal = 3, |
|
.max_signal = 3, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "spi1_tx", |
|
.min_signal = 4, |
|
.max_signal = 4, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "spi1_rx", |
|
.min_signal = 5, |
|
.max_signal = 5, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "ac97_out", |
|
.min_signal = 6, |
|
.max_signal = 6, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "ac97_in", |
|
.min_signal = 7, |
|
.max_signal = 7, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "ac97_mic", |
|
.min_signal = 8, |
|
.max_signal = 8, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "pwm", |
|
.min_signal = 9, |
|
.max_signal = 9, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "irda", |
|
.min_signal = 10, |
|
.max_signal = 10, |
|
.periph_buses = PL08X_AHB2, |
|
}, { |
|
.bus_id = "external", |
|
.min_signal = 11, |
|
.max_signal = 11, |
|
.periph_buses = PL08X_AHB2, |
|
}, |
|
}; |
|
|
|
static const struct dma_slave_map s3c64xx_dma1_slave_map[] = { |
|
{ "samsung-pcm.1", "tx", &s3c64xx_dma1_info[0] }, |
|
{ "samsung-pcm.1", "rx", &s3c64xx_dma1_info[1] }, |
|
{ "samsung-i2s.1", "tx", &s3c64xx_dma1_info[2] }, |
|
{ "samsung-i2s.1", "rx", &s3c64xx_dma1_info[3] }, |
|
{ "s3c6410-spi.1", "tx", &s3c64xx_dma1_info[4] }, |
|
{ "s3c6410-spi.1", "rx", &s3c64xx_dma1_info[5] }, |
|
}; |
|
|
|
struct pl08x_platform_data s3c64xx_dma1_plat_data = { |
|
.memcpy_burst_size = PL08X_BURST_SZ_4, |
|
.memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS, |
|
.memcpy_prot_buff = true, |
|
.memcpy_prot_cache = true, |
|
.lli_buses = PL08X_AHB1, |
|
.mem_buses = PL08X_AHB1, |
|
.get_xfer_signal = pl08x_get_xfer_signal, |
|
.put_xfer_signal = pl08x_put_xfer_signal, |
|
.slave_channels = s3c64xx_dma1_info, |
|
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info), |
|
.slave_map = s3c64xx_dma1_slave_map, |
|
.slave_map_len = ARRAY_SIZE(s3c64xx_dma1_slave_map), |
|
}; |
|
|
|
static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0, |
|
0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data); |
|
|
|
static int __init s3c64xx_pl080_init(void) |
|
{ |
|
if (!soc_is_s3c64xx()) |
|
return 0; |
|
|
|
/* Set all DMA configuration to be DMA, not SDMA */ |
|
writel(0xffffff, S3C64XX_SDMA_SEL); |
|
|
|
if (of_have_populated_dt()) |
|
return 0; |
|
|
|
amba_device_register(&s3c64xx_dma0_device, &iomem_resource); |
|
amba_device_register(&s3c64xx_dma1_device, &iomem_resource); |
|
|
|
return 0; |
|
} |
|
arch_initcall(s3c64xx_pl080_init);
|
|
|