xref: /linux/arch/arm/mach-s3c/pl080.c (revision c78a41fc)
171b9114dSArnd Bergmann // SPDX-License-Identifier: GPL-2.0
271b9114dSArnd Bergmann //
371b9114dSArnd Bergmann // Samsung's S3C64XX generic DMA support using amba-pl08x driver.
471b9114dSArnd Bergmann //
571b9114dSArnd Bergmann // Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
671b9114dSArnd Bergmann 
771b9114dSArnd Bergmann #include <linux/kernel.h>
871b9114dSArnd Bergmann #include <linux/amba/bus.h>
971b9114dSArnd Bergmann #include <linux/amba/pl080.h>
1071b9114dSArnd Bergmann #include <linux/amba/pl08x.h>
1171b9114dSArnd Bergmann #include <linux/of.h>
1271b9114dSArnd Bergmann 
13c6ff132dSArnd Bergmann #include "cpu.h"
14c78a41fcSArnd Bergmann #include "irqs.h"
15c6ff132dSArnd Bergmann #include "map.h"
1671b9114dSArnd Bergmann 
1771b9114dSArnd Bergmann #include "regs-sys-s3c64xx.h"
1871b9114dSArnd Bergmann 
pl08x_get_xfer_signal(const struct pl08x_channel_data * cd)1971b9114dSArnd Bergmann static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd)
2071b9114dSArnd Bergmann {
2171b9114dSArnd Bergmann 	return cd->min_signal;
2271b9114dSArnd Bergmann }
2371b9114dSArnd Bergmann 
pl08x_put_xfer_signal(const struct pl08x_channel_data * cd,int ch)2471b9114dSArnd Bergmann static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch)
2571b9114dSArnd Bergmann {
2671b9114dSArnd Bergmann }
2771b9114dSArnd Bergmann 
2871b9114dSArnd Bergmann /*
2971b9114dSArnd Bergmann  * DMA0
3071b9114dSArnd Bergmann  */
3171b9114dSArnd Bergmann 
3271b9114dSArnd Bergmann static struct pl08x_channel_data s3c64xx_dma0_info[] = {
3371b9114dSArnd Bergmann 	{
3471b9114dSArnd Bergmann 		.bus_id = "uart0_tx",
3571b9114dSArnd Bergmann 		.min_signal = 0,
3671b9114dSArnd Bergmann 		.max_signal = 0,
3771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
3871b9114dSArnd Bergmann 	}, {
3971b9114dSArnd Bergmann 		.bus_id = "uart0_rx",
4071b9114dSArnd Bergmann 		.min_signal = 1,
4171b9114dSArnd Bergmann 		.max_signal = 1,
4271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
4371b9114dSArnd Bergmann 	}, {
4471b9114dSArnd Bergmann 		.bus_id = "uart1_tx",
4571b9114dSArnd Bergmann 		.min_signal = 2,
4671b9114dSArnd Bergmann 		.max_signal = 2,
4771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
4871b9114dSArnd Bergmann 	}, {
4971b9114dSArnd Bergmann 		.bus_id = "uart1_rx",
5071b9114dSArnd Bergmann 		.min_signal = 3,
5171b9114dSArnd Bergmann 		.max_signal = 3,
5271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
5371b9114dSArnd Bergmann 	}, {
5471b9114dSArnd Bergmann 		.bus_id = "uart2_tx",
5571b9114dSArnd Bergmann 		.min_signal = 4,
5671b9114dSArnd Bergmann 		.max_signal = 4,
5771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
5871b9114dSArnd Bergmann 	}, {
5971b9114dSArnd Bergmann 		.bus_id = "uart2_rx",
6071b9114dSArnd Bergmann 		.min_signal = 5,
6171b9114dSArnd Bergmann 		.max_signal = 5,
6271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
6371b9114dSArnd Bergmann 	}, {
6471b9114dSArnd Bergmann 		.bus_id = "uart3_tx",
6571b9114dSArnd Bergmann 		.min_signal = 6,
6671b9114dSArnd Bergmann 		.max_signal = 6,
6771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
6871b9114dSArnd Bergmann 	}, {
6971b9114dSArnd Bergmann 		.bus_id = "uart3_rx",
7071b9114dSArnd Bergmann 		.min_signal = 7,
7171b9114dSArnd Bergmann 		.max_signal = 7,
7271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
7371b9114dSArnd Bergmann 	}, {
7471b9114dSArnd Bergmann 		.bus_id = "pcm0_tx",
7571b9114dSArnd Bergmann 		.min_signal = 8,
7671b9114dSArnd Bergmann 		.max_signal = 8,
7771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
7871b9114dSArnd Bergmann 	}, {
7971b9114dSArnd Bergmann 		.bus_id = "pcm0_rx",
8071b9114dSArnd Bergmann 		.min_signal = 9,
8171b9114dSArnd Bergmann 		.max_signal = 9,
8271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
8371b9114dSArnd Bergmann 	}, {
8471b9114dSArnd Bergmann 		.bus_id = "i2s0_tx",
8571b9114dSArnd Bergmann 		.min_signal = 10,
8671b9114dSArnd Bergmann 		.max_signal = 10,
8771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
8871b9114dSArnd Bergmann 	}, {
8971b9114dSArnd Bergmann 		.bus_id = "i2s0_rx",
9071b9114dSArnd Bergmann 		.min_signal = 11,
9171b9114dSArnd Bergmann 		.max_signal = 11,
9271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
9371b9114dSArnd Bergmann 	}, {
9471b9114dSArnd Bergmann 		.bus_id = "spi0_tx",
9571b9114dSArnd Bergmann 		.min_signal = 12,
9671b9114dSArnd Bergmann 		.max_signal = 12,
9771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
9871b9114dSArnd Bergmann 	}, {
9971b9114dSArnd Bergmann 		.bus_id = "spi0_rx",
10071b9114dSArnd Bergmann 		.min_signal = 13,
10171b9114dSArnd Bergmann 		.max_signal = 13,
10271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
10371b9114dSArnd Bergmann 	}, {
10471b9114dSArnd Bergmann 		.bus_id = "i2s2_tx",
10571b9114dSArnd Bergmann 		.min_signal = 14,
10671b9114dSArnd Bergmann 		.max_signal = 14,
10771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
10871b9114dSArnd Bergmann 	}, {
10971b9114dSArnd Bergmann 		.bus_id = "i2s2_rx",
11071b9114dSArnd Bergmann 		.min_signal = 15,
11171b9114dSArnd Bergmann 		.max_signal = 15,
11271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
11371b9114dSArnd Bergmann 	}
11471b9114dSArnd Bergmann };
11571b9114dSArnd Bergmann 
11671b9114dSArnd Bergmann static const struct dma_slave_map s3c64xx_dma0_slave_map[] = {
11771b9114dSArnd Bergmann 	{ "s3c6400-uart.0", "tx", &s3c64xx_dma0_info[0] },
11871b9114dSArnd Bergmann 	{ "s3c6400-uart.0", "rx", &s3c64xx_dma0_info[1] },
11971b9114dSArnd Bergmann 	{ "s3c6400-uart.1", "tx", &s3c64xx_dma0_info[2] },
12071b9114dSArnd Bergmann 	{ "s3c6400-uart.1", "rx", &s3c64xx_dma0_info[3] },
12171b9114dSArnd Bergmann 	{ "s3c6400-uart.2", "tx", &s3c64xx_dma0_info[4] },
12271b9114dSArnd Bergmann 	{ "s3c6400-uart.2", "rx", &s3c64xx_dma0_info[5] },
12371b9114dSArnd Bergmann 	{ "s3c6400-uart.3", "tx", &s3c64xx_dma0_info[6] },
12471b9114dSArnd Bergmann 	{ "s3c6400-uart.3", "rx", &s3c64xx_dma0_info[7] },
12571b9114dSArnd Bergmann 	{ "samsung-pcm.0", "tx", &s3c64xx_dma0_info[8] },
12671b9114dSArnd Bergmann 	{ "samsung-pcm.0", "rx", &s3c64xx_dma0_info[9] },
12771b9114dSArnd Bergmann 	{ "samsung-i2s.0", "tx", &s3c64xx_dma0_info[10] },
12871b9114dSArnd Bergmann 	{ "samsung-i2s.0", "rx", &s3c64xx_dma0_info[11] },
12971b9114dSArnd Bergmann 	{ "s3c6410-spi.0", "tx", &s3c64xx_dma0_info[12] },
13071b9114dSArnd Bergmann 	{ "s3c6410-spi.0", "rx", &s3c64xx_dma0_info[13] },
13171b9114dSArnd Bergmann 	{ "samsung-i2s.2", "tx", &s3c64xx_dma0_info[14] },
13271b9114dSArnd Bergmann 	{ "samsung-i2s.2", "rx", &s3c64xx_dma0_info[15] },
13371b9114dSArnd Bergmann };
13471b9114dSArnd Bergmann 
13571b9114dSArnd Bergmann struct pl08x_platform_data s3c64xx_dma0_plat_data = {
13671b9114dSArnd Bergmann 	.memcpy_burst_size = PL08X_BURST_SZ_4,
13771b9114dSArnd Bergmann 	.memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
13871b9114dSArnd Bergmann 	.memcpy_prot_buff = true,
13971b9114dSArnd Bergmann 	.memcpy_prot_cache = true,
14071b9114dSArnd Bergmann 	.lli_buses = PL08X_AHB1,
14171b9114dSArnd Bergmann 	.mem_buses = PL08X_AHB1,
14271b9114dSArnd Bergmann 	.get_xfer_signal = pl08x_get_xfer_signal,
14371b9114dSArnd Bergmann 	.put_xfer_signal = pl08x_put_xfer_signal,
14471b9114dSArnd Bergmann 	.slave_channels = s3c64xx_dma0_info,
14571b9114dSArnd Bergmann 	.num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
14671b9114dSArnd Bergmann 	.slave_map = s3c64xx_dma0_slave_map,
14771b9114dSArnd Bergmann 	.slave_map_len = ARRAY_SIZE(s3c64xx_dma0_slave_map),
14871b9114dSArnd Bergmann };
14971b9114dSArnd Bergmann 
15071b9114dSArnd Bergmann static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
15171b9114dSArnd Bergmann 			0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);
15271b9114dSArnd Bergmann 
15371b9114dSArnd Bergmann /*
15471b9114dSArnd Bergmann  * DMA1
15571b9114dSArnd Bergmann  */
15671b9114dSArnd Bergmann 
15771b9114dSArnd Bergmann static struct pl08x_channel_data s3c64xx_dma1_info[] = {
15871b9114dSArnd Bergmann 	{
15971b9114dSArnd Bergmann 		.bus_id = "pcm1_tx",
16071b9114dSArnd Bergmann 		.min_signal = 0,
16171b9114dSArnd Bergmann 		.max_signal = 0,
16271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
16371b9114dSArnd Bergmann 	}, {
16471b9114dSArnd Bergmann 		.bus_id = "pcm1_rx",
16571b9114dSArnd Bergmann 		.min_signal = 1,
16671b9114dSArnd Bergmann 		.max_signal = 1,
16771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
16871b9114dSArnd Bergmann 	}, {
16971b9114dSArnd Bergmann 		.bus_id = "i2s1_tx",
17071b9114dSArnd Bergmann 		.min_signal = 2,
17171b9114dSArnd Bergmann 		.max_signal = 2,
17271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
17371b9114dSArnd Bergmann 	}, {
17471b9114dSArnd Bergmann 		.bus_id = "i2s1_rx",
17571b9114dSArnd Bergmann 		.min_signal = 3,
17671b9114dSArnd Bergmann 		.max_signal = 3,
17771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
17871b9114dSArnd Bergmann 	}, {
17971b9114dSArnd Bergmann 		.bus_id = "spi1_tx",
18071b9114dSArnd Bergmann 		.min_signal = 4,
18171b9114dSArnd Bergmann 		.max_signal = 4,
18271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
18371b9114dSArnd Bergmann 	}, {
18471b9114dSArnd Bergmann 		.bus_id = "spi1_rx",
18571b9114dSArnd Bergmann 		.min_signal = 5,
18671b9114dSArnd Bergmann 		.max_signal = 5,
18771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
18871b9114dSArnd Bergmann 	}, {
18971b9114dSArnd Bergmann 		.bus_id = "ac97_out",
19071b9114dSArnd Bergmann 		.min_signal = 6,
19171b9114dSArnd Bergmann 		.max_signal = 6,
19271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
19371b9114dSArnd Bergmann 	}, {
19471b9114dSArnd Bergmann 		.bus_id = "ac97_in",
19571b9114dSArnd Bergmann 		.min_signal = 7,
19671b9114dSArnd Bergmann 		.max_signal = 7,
19771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
19871b9114dSArnd Bergmann 	}, {
19971b9114dSArnd Bergmann 		.bus_id = "ac97_mic",
20071b9114dSArnd Bergmann 		.min_signal = 8,
20171b9114dSArnd Bergmann 		.max_signal = 8,
20271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
20371b9114dSArnd Bergmann 	}, {
20471b9114dSArnd Bergmann 		.bus_id = "pwm",
20571b9114dSArnd Bergmann 		.min_signal = 9,
20671b9114dSArnd Bergmann 		.max_signal = 9,
20771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
20871b9114dSArnd Bergmann 	}, {
20971b9114dSArnd Bergmann 		.bus_id = "irda",
21071b9114dSArnd Bergmann 		.min_signal = 10,
21171b9114dSArnd Bergmann 		.max_signal = 10,
21271b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
21371b9114dSArnd Bergmann 	}, {
21471b9114dSArnd Bergmann 		.bus_id = "external",
21571b9114dSArnd Bergmann 		.min_signal = 11,
21671b9114dSArnd Bergmann 		.max_signal = 11,
21771b9114dSArnd Bergmann 		.periph_buses = PL08X_AHB2,
21871b9114dSArnd Bergmann 	},
21971b9114dSArnd Bergmann };
22071b9114dSArnd Bergmann 
22171b9114dSArnd Bergmann static const struct dma_slave_map s3c64xx_dma1_slave_map[] = {
22271b9114dSArnd Bergmann 	{ "samsung-pcm.1", "tx", &s3c64xx_dma1_info[0] },
22371b9114dSArnd Bergmann 	{ "samsung-pcm.1", "rx", &s3c64xx_dma1_info[1] },
22471b9114dSArnd Bergmann 	{ "samsung-i2s.1", "tx", &s3c64xx_dma1_info[2] },
22571b9114dSArnd Bergmann 	{ "samsung-i2s.1", "rx", &s3c64xx_dma1_info[3] },
22671b9114dSArnd Bergmann 	{ "s3c6410-spi.1", "tx", &s3c64xx_dma1_info[4] },
22771b9114dSArnd Bergmann 	{ "s3c6410-spi.1", "rx", &s3c64xx_dma1_info[5] },
22871b9114dSArnd Bergmann };
22971b9114dSArnd Bergmann 
23071b9114dSArnd Bergmann struct pl08x_platform_data s3c64xx_dma1_plat_data = {
23171b9114dSArnd Bergmann 	.memcpy_burst_size = PL08X_BURST_SZ_4,
23271b9114dSArnd Bergmann 	.memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
23371b9114dSArnd Bergmann 	.memcpy_prot_buff = true,
23471b9114dSArnd Bergmann 	.memcpy_prot_cache = true,
23571b9114dSArnd Bergmann 	.lli_buses = PL08X_AHB1,
23671b9114dSArnd Bergmann 	.mem_buses = PL08X_AHB1,
23771b9114dSArnd Bergmann 	.get_xfer_signal = pl08x_get_xfer_signal,
23871b9114dSArnd Bergmann 	.put_xfer_signal = pl08x_put_xfer_signal,
23971b9114dSArnd Bergmann 	.slave_channels = s3c64xx_dma1_info,
24071b9114dSArnd Bergmann 	.num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
24171b9114dSArnd Bergmann 	.slave_map = s3c64xx_dma1_slave_map,
24271b9114dSArnd Bergmann 	.slave_map_len = ARRAY_SIZE(s3c64xx_dma1_slave_map),
24371b9114dSArnd Bergmann };
24471b9114dSArnd Bergmann 
24571b9114dSArnd Bergmann static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
24671b9114dSArnd Bergmann 			0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);
24771b9114dSArnd Bergmann 
s3c64xx_pl080_init(void)24871b9114dSArnd Bergmann static int __init s3c64xx_pl080_init(void)
24971b9114dSArnd Bergmann {
25071b9114dSArnd Bergmann 	if (!soc_is_s3c64xx())
25171b9114dSArnd Bergmann 		return 0;
25271b9114dSArnd Bergmann 
25371b9114dSArnd Bergmann 	/* Set all DMA configuration to be DMA, not SDMA */
25471b9114dSArnd Bergmann 	writel(0xffffff, S3C64XX_SDMA_SEL);
25571b9114dSArnd Bergmann 
25671b9114dSArnd Bergmann 	if (of_have_populated_dt())
25771b9114dSArnd Bergmann 		return 0;
25871b9114dSArnd Bergmann 
25971b9114dSArnd Bergmann 	amba_device_register(&s3c64xx_dma0_device, &iomem_resource);
26071b9114dSArnd Bergmann 	amba_device_register(&s3c64xx_dma1_device, &iomem_resource);
26171b9114dSArnd Bergmann 
26271b9114dSArnd Bergmann 	return 0;
26371b9114dSArnd Bergmann }
26471b9114dSArnd Bergmann arch_initcall(s3c64xx_pl080_init);
265