diff options
author | Ben Dooks <ben-linux@fluff.org> | 2010-05-19 18:05:15 +0900 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2010-05-19 18:05:15 +0900 |
commit | 1e8ff636beb6ee5c87868a6081cc4f95b1ccd713 (patch) | |
tree | 5a6be34a53bf640c035d642b4d19388d6a7fd6cc /arch | |
parent | 32457942b90aabb9242b450f02d18d9c8d982916 (diff) | |
parent | 7d1a2077a7e519fc0c68617526abea3f72632e60 (diff) |
ARM: Merge for-2635/s5p-dma
Merge branch 'for-2635/s5p-dma' into for-linus/samsung2
Conflicts:
arch/arm/mach-s5pv210/Makefile
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-s5p6440/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-s5p6440/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-s5p6440/dma.c | 105 | ||||
-rw-r--r-- | arch/arm/mach-s5p6440/include/mach/dma.h | 26 | ||||
-rw-r--r-- | arch/arm/mach-s5p6440/include/mach/map.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-s5p6442/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-s5p6442/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-s5p6442/dma.c | 105 | ||||
-rw-r--r-- | arch/arm/mach-s5p6442/include/mach/dma.h | 26 | ||||
-rw-r--r-- | arch/arm/mach-s5p6442/include/mach/map.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/dma.c | 168 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/include/mach/dma.h | 26 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/include/mach/map.h | 4 | ||||
-rw-r--r-- | arch/arm/plat-samsung/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/plat-samsung/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h | 78 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h | 32 | ||||
-rw-r--r-- | arch/arm/plat-samsung/s3c-pl330.c | 1224 |
20 files changed, 1813 insertions, 3 deletions
diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig index 4c29ff8b07de..77aeffd17330 100644 --- a/arch/arm/mach-s5p6440/Kconfig +++ b/arch/arm/mach-s5p6440/Kconfig @@ -9,6 +9,7 @@ if ARCH_S5P6440 config CPU_S5P6440 bool + select S3C_PL330_DMA help Enable S5P6440 CPU support diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile index 1ad894b1d3ab..3f243dd1ad14 100644 --- a/arch/arm/mach-s5p6440/Makefile +++ b/arch/arm/mach-s5p6440/Makefile @@ -12,7 +12,7 @@ obj- := # Core support for S5P6440 system -obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o +obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o dma.o # machine support diff --git a/arch/arm/mach-s5p6440/dma.c b/arch/arm/mach-s5p6440/dma.c new file mode 100644 index 000000000000..07606ad57519 --- /dev/null +++ b/arch/arm/mach-s5p6440/dma.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> + +#include <plat/devs.h> +#include <plat/irqs.h> + +#include <mach/map.h> +#include <mach/irqs.h> + +#include <plat/s3c-pl330-pdata.h> + +static u64 dma_dmamask = DMA_BIT_MASK(32); + +static struct resource s5p6440_pdma_resource[] = { + [0] = { + .start = S5P6440_PA_PDMA, + .end = S5P6440_PA_PDMA + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DMA0, + .end = IRQ_DMA0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5p6440_pdma_pdata = { + .peri = { + [0] = DMACH_UART0_RX, + [1] = DMACH_UART0_TX, + [2] = DMACH_UART1_RX, + [3] = DMACH_UART1_TX, + [4] = DMACH_UART2_RX, + [5] = DMACH_UART2_TX, + [6] = DMACH_UART3_RX, + [7] = DMACH_UART3_TX, + [8] = DMACH_MAX, + [9] = DMACH_MAX, + [10] = DMACH_PCM0_TX, + [11] = DMACH_PCM0_RX, + [12] = DMACH_I2S0_TX, + [13] = DMACH_I2S0_RX, + [14] = DMACH_SPI0_TX, + [15] = DMACH_SPI0_RX, + [16] = DMACH_MAX, + [17] = DMACH_MAX, + [18] = DMACH_MAX, + [19] = DMACH_MAX, + [20] = DMACH_SPI1_TX, + [21] = DMACH_SPI1_RX, + [22] = DMACH_MAX, + [23] = DMACH_MAX, + [24] = DMACH_MAX, + [25] = DMACH_MAX, + [26] = DMACH_MAX, + [27] = DMACH_MAX, + [28] = DMACH_MAX, + [29] = DMACH_PWM, + [30] = DMACH_MAX, + [31] = DMACH_MAX, + }, +}; + +static struct platform_device s5p6440_device_pdma = { + .name = "s3c-pl330", + .id = 1, + .num_resources = ARRAY_SIZE(s5p6440_pdma_resource), + .resource = s5p6440_pdma_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5p6440_pdma_pdata, + }, +}; + +static struct platform_device *s5p6440_dmacs[] __initdata = { + &s5p6440_device_pdma, +}; + +static int __init s5p6440_dma_init(void) +{ + platform_add_devices(s5p6440_dmacs, ARRAY_SIZE(s5p6440_dmacs)); + + return 0; +} +arch_initcall(s5p6440_dma_init); diff --git a/arch/arm/mach-s5p6440/include/mach/dma.h b/arch/arm/mach-s5p6440/include/mach/dma.h new file mode 100644 index 000000000000..81209eb1409b --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/dma.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MACH_DMA_H +#define __MACH_DMA_H + +/* This platform uses the common S3C DMA API driver for PL330 */ +#include <plat/s3c-dma-pl330.h> + +#endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h index 8924e5a4d6a6..0275784eb22f 100644 --- a/arch/arm/mach-s5p6440/include/mach/map.h +++ b/arch/arm/mach-s5p6440/include/mach/map.h @@ -29,6 +29,8 @@ #define S5P6440_PA_VIC0 (0xE4000000) #define S5P_PA_VIC0 S5P6440_PA_VIC0 +#define S5P6440_PA_PDMA 0xE9000000 + #define S5P6440_PA_VIC1 (0xE4100000) #define S5P_PA_VIC1 S5P6440_PA_VIC1 diff --git a/arch/arm/mach-s5p6442/Kconfig b/arch/arm/mach-s5p6442/Kconfig index 4f3f6de6a013..0fd41b447915 100644 --- a/arch/arm/mach-s5p6442/Kconfig +++ b/arch/arm/mach-s5p6442/Kconfig @@ -12,6 +12,7 @@ if ARCH_S5P6442 config CPU_S5P6442 bool select PLAT_S5P + select S3C_PL330_DMA help Enable S5P6442 CPU support diff --git a/arch/arm/mach-s5p6442/Makefile b/arch/arm/mach-s5p6442/Makefile index dde39a6ce6bc..17bd22ee107d 100644 --- a/arch/arm/mach-s5p6442/Makefile +++ b/arch/arm/mach-s5p6442/Makefile @@ -12,7 +12,7 @@ obj- := # Core support for S5P6442 system -obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o +obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o dma.o # machine support diff --git a/arch/arm/mach-s5p6442/dma.c b/arch/arm/mach-s5p6442/dma.c new file mode 100644 index 000000000000..ad4f8704b93d --- /dev/null +++ b/arch/arm/mach-s5p6442/dma.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> + +#include <plat/devs.h> +#include <plat/irqs.h> + +#include <mach/map.h> +#include <mach/irqs.h> + +#include <plat/s3c-pl330-pdata.h> + +static u64 dma_dmamask = DMA_BIT_MASK(32); + +static struct resource s5p6442_pdma_resource[] = { + [0] = { + .start = S5P6442_PA_PDMA, + .end = S5P6442_PA_PDMA + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PDMA, + .end = IRQ_PDMA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5p6442_pdma_pdata = { + .peri = { + [0] = DMACH_UART0_RX, + [1] = DMACH_UART0_TX, + [2] = DMACH_UART1_RX, + [3] = DMACH_UART1_TX, + [4] = DMACH_UART2_RX, + [5] = DMACH_UART2_TX, + [6] = DMACH_MAX, + [7] = DMACH_MAX, + [8] = DMACH_MAX, + [9] = DMACH_I2S0_RX, + [10] = DMACH_I2S0_TX, + [11] = DMACH_I2S0S_TX, + [12] = DMACH_I2S1_RX, + [13] = DMACH_I2S1_TX, + [14] = DMACH_MAX, + [15] = DMACH_MAX, + [16] = DMACH_SPI0_RX, + [17] = DMACH_SPI0_TX, + [18] = DMACH_MAX, + [19] = DMACH_MAX, + [20] = DMACH_PCM0_RX, + [21] = DMACH_PCM0_TX, + [22] = DMACH_PCM1_RX, + [23] = DMACH_PCM1_TX, + [24] = DMACH_MAX, + [25] = DMACH_MAX, + [26] = DMACH_MAX, + [27] = DMACH_MSM_REQ0, + [28] = DMACH_MSM_REQ1, + [29] = DMACH_MSM_REQ2, + [30] = DMACH_MSM_REQ3, + [31] = DMACH_MAX, + }, +}; + +static struct platform_device s5p6442_device_pdma = { + .name = "s3c-pl330", + .id = 1, + .num_resources = ARRAY_SIZE(s5p6442_pdma_resource), + .resource = s5p6442_pdma_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5p6442_pdma_pdata, + }, +}; + +static struct platform_device *s5p6442_dmacs[] __initdata = { + &s5p6442_device_pdma, +}; + +static int __init s5p6442_dma_init(void) +{ + platform_add_devices(s5p6442_dmacs, ARRAY_SIZE(s5p6442_dmacs)); + + return 0; +} +arch_initcall(s5p6442_dma_init); diff --git a/arch/arm/mach-s5p6442/include/mach/dma.h b/arch/arm/mach-s5p6442/include/mach/dma.h new file mode 100644 index 000000000000..81209eb1409b --- /dev/null +++ b/arch/arm/mach-s5p6442/include/mach/dma.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MACH_DMA_H +#define __MACH_DMA_H + +/* This platform uses the common S3C DMA API driver for PL330 */ +#include <plat/s3c-dma-pl330.h> + +#endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h index 685277d792fb..a263d77f6968 100644 --- a/arch/arm/mach-s5p6442/include/mach/map.h +++ b/arch/arm/mach-s5p6442/include/mach/map.h @@ -34,6 +34,9 @@ #define S5P6442_PA_VIC2 (0xE4200000) #define S5P_PA_VIC2 S5P6442_PA_VIC2 +#define S5P6442_PA_MDMA 0xE8000000 +#define S5P6442_PA_PDMA 0xE9000000 + #define S5P6442_PA_TIMER (0xEA000000) #define S5P_PA_TIMER S5P6442_PA_TIMER diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index af33a1a89b72..7601c28e240b 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -12,6 +12,7 @@ if ARCH_S5PV210 config CPU_S5PV210 bool select PLAT_S5P + select S3C_PL330_DMA help Enable S5PV210 CPU support diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 0acbdb34b560..192deac8aaab 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -12,7 +12,7 @@ obj- := # Core support for S5PV210 system -obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o gpiolib.o +obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o # machine support diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c new file mode 100644 index 000000000000..778ad5fe231a --- /dev/null +++ b/arch/arm/mach-s5pv210/dma.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> + +#include <plat/devs.h> +#include <plat/irqs.h> + +#include <mach/map.h> +#include <mach/irqs.h> + +#include <plat/s3c-pl330-pdata.h> + +static u64 dma_dmamask = DMA_BIT_MASK(32); + +static struct resource s5pv210_pdma0_resource[] = { + [0] = { + .start = S5PV210_PA_PDMA0, + .end = S5PV210_PA_PDMA0 + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PDMA0, + .end = IRQ_PDMA0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5pv210_pdma0_pdata = { + .peri = { + [0] = DMACH_UART0_RX, + [1] = DMACH_UART0_TX, + [2] = DMACH_UART1_RX, + [3] = DMACH_UART1_TX, + [4] = DMACH_UART2_RX, + [5] = DMACH_UART2_TX, + [6] = DMACH_UART3_RX, + [7] = DMACH_UART3_TX, + [8] = DMACH_MAX, + [9] = DMACH_I2S0_RX, + [10] = DMACH_I2S0_TX, + [11] = DMACH_I2S0S_TX, + [12] = DMACH_I2S1_RX, + [13] = DMACH_I2S1_TX, + [14] = DMACH_MAX, + [15] = DMACH_MAX, + [16] = DMACH_SPI0_RX, + [17] = DMACH_SPI0_TX, + [18] = DMACH_SPI1_RX, + [19] = DMACH_SPI1_TX, + [20] = DMACH_MAX, + [21] = DMACH_MAX, + [22] = DMACH_AC97_MICIN, + [23] = DMACH_AC97_PCMIN, + [24] = DMACH_AC97_PCMOUT, + [25] = DMACH_MAX, + [26] = DMACH_PWM, + [27] = DMACH_SPDIF, + [28] = DMACH_MAX, + [29] = DMACH_MAX, + [30] = DMACH_MAX, + [31] = DMACH_MAX, + }, +}; + +static struct platform_device s5pv210_device_pdma0 = { + .name = "s3c-pl330", + .id = 1, + .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource), + .resource = s5pv210_pdma0_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5pv210_pdma0_pdata, + }, +}; + +static struct resource s5pv210_pdma1_resource[] = { + [0] = { + .start = S5PV210_PA_PDMA1, + .end = S5PV210_PA_PDMA1 + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PDMA1, + .end = IRQ_PDMA1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5pv210_pdma1_pdata = { + .peri = { + [0] = DMACH_UART0_RX, + [1] = DMACH_UART0_TX, + [2] = DMACH_UART1_RX, + [3] = DMACH_UART1_TX, + [4] = DMACH_UART2_RX, + [5] = DMACH_UART2_TX, + [6] = DMACH_UART3_RX, + [7] = DMACH_UART3_TX, + [8] = DMACH_MAX, + [9] = DMACH_I2S0_RX, + [10] = DMACH_I2S0_TX, + [11] = DMACH_I2S0S_TX, + [12] = DMACH_I2S1_RX, + [13] = DMACH_I2S1_TX, + [14] = DMACH_I2S2_RX, + [15] = DMACH_I2S2_TX, + [16] = DMACH_SPI0_RX, + [17] = DMACH_SPI0_TX, + [18] = DMACH_SPI1_RX, + [19] = DMACH_SPI1_TX, + [20] = DMACH_MAX, + [21] = DMACH_MAX, + [22] = DMACH_PCM0_RX, + [23] = DMACH_PCM0_TX, + [24] = DMACH_PCM1_RX, + [25] = DMACH_PCM1_TX, + [26] = DMACH_MSM_REQ0, + [27] = DMACH_MSM_REQ1, + [28] = DMACH_MSM_REQ2, + [29] = DMACH_MSM_REQ3, + [30] = DMACH_PCM2_RX, + [31] = DMACH_PCM2_TX, + }, +}; + +static struct platform_device s5pv210_device_pdma1 = { + .name = "s3c-pl330", + .id = 2, + .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource), + .resource = s5pv210_pdma1_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5pv210_pdma1_pdata, + }, +}; + +static struct platform_device *s5pv210_dmacs[] __initdata = { + &s5pv210_device_pdma0, + &s5pv210_device_pdma1, +}; + +static int __init s5pv210_dma_init(void) +{ + platform_add_devices(s5pv210_dmacs, ARRAY_SIZE(s5pv210_dmacs)); + + return 0; +} +arch_initcall(s5pv210_dma_init); diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h new file mode 100644 index 000000000000..81209eb1409b --- /dev/null +++ b/arch/arm/mach-s5pv210/include/mach/dma.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MACH_DMA_H +#define __MACH_DMA_H + +/* This platform uses the common S3C DMA API driver for PL330 */ +#include <plat/s3c-dma-pl330.h> + +#endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index c22694c8231f..c038585080c0 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -43,6 +43,10 @@ #define S5PV210_PA_SROMC (0xE8000000) +#define S5PV210_PA_MDMA 0xFA200000 +#define S5PV210_PA_PDMA0 0xE0900000 +#define S5PV210_PA_PDMA1 0xE0A00000 + #define S5PV210_PA_VIC0 (0xF2000000) #define S5P_PA_VIC0 S5PV210_PA_VIC0 diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 7a36cf85e138..5349d2181bd2 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -203,6 +203,12 @@ config S3C_DMA help Internal configuration for S3C DMA core +config S3C_PL330_DMA + bool + select PL330 + help + S3C DMA API Driver for PL330 DMAC. + comment "Power management" config SAMSUNG_PM_DEBUG diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 0ad820acc385..ca6036745edc 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -46,6 +46,8 @@ obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o obj-$(CONFIG_S3C_DMA) += dma.o +obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o + # PM support obj-$(CONFIG_PM) += pm.o diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h new file mode 100644 index 000000000000..5fe6721b57f7 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __S3C_DMA_PL330_H_ +#define __S3C_DMA_PL330_H_ + +#define S3C2410_DMAF_AUTOSTART (1 << 0) +#define S3C2410_DMAF_CIRCULAR (1 << 1) + +/* + * PL330 can assign any channel to communicate with + * any of the peripherals attched to the DMAC. + * For the sake of consistency across client drivers, + * We keep the channel names unchanged and only add + * missing peripherals are added. + * Order is not important since S3C PL330 API driver + * use these just as IDs. + */ +enum dma_ch { + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_IRDA, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S0S_TX, + DMACH_I2S1_RX, + DMACH_I2S1_TX, + DMACH_I2S2_RX, + DMACH_I2S2_TX, + DMACH_SPI0_RX, + DMACH_SPI0_TX, + DMACH_SPI1_RX, + DMACH_SPI1_TX, + DMACH_SPI2_RX, + DMACH_SPI2_TX, + DMACH_AC97_MICIN, + DMACH_AC97_PCMIN, + DMACH_AC97_PCMOUT, + DMACH_EXTERNAL, + DMACH_PWM, + DMACH_SPDIF, + DMACH_HSI_RX, + DMACH_HSI_TX, + DMACH_PCM0_TX, + DMACH_PCM0_RX, + DMACH_PCM1_TX, + DMACH_PCM1_RX, + DMACH_PCM2_TX, + DMACH_PCM2_RX, + DMACH_MSM_REQ3, + DMACH_MSM_REQ2, + DMACH_MSM_REQ1, + DMACH_MSM_REQ0, + /* END Marker, also used to denote a reserved channel */ + DMACH_MAX, +}; + +static inline bool s3c_dma_has_circular(void) +{ + return true; +} + +#include <plat/dma.h> + +#endif /* __S3C_DMA_PL330_H_ */ diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h new file mode 100644 index 000000000000..bf5e2a9d408d --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h @@ -0,0 +1,32 @@ +/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __S3C_PL330_PDATA_H +#define __S3C_PL330_PDATA_H + +#include <plat/s3c-dma-pl330.h> + +/* + * Every PL330 DMAC has max 32 peripheral interfaces, + * of which some may be not be really used in your + * DMAC's configuration. + * Populate this array of 32 peri i/fs with relevant + * channel IDs for used peri i/f and DMACH_MAX for + * those unused. + * + * The platforms just need to provide this info + * to the S3C DMA API driver for PL330. + */ +struct s3c_pl330_platdata { + enum dma_ch peri[32]; +}; + +#endif /* __S3C_PL330_PDATA_H */ diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c new file mode 100644 index 000000000000..a91305a60aed --- /dev/null +++ b/arch/arm/plat-samsung/s3c-pl330.c @@ -0,0 +1,1224 @@ +/* linux/arch/arm/plat-samsung/s3c-pl330.c + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/platform_device.h> + +#include <asm/hardware/pl330.h> + +#include <plat/s3c-pl330-pdata.h> + +/** + * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC. + * @busy_chan: Number of channels currently busy. + * @peri: List of IDs of peripherals this DMAC can work with. + * @node: To attach to the global list of DMACs. + * @pi: PL330 configuration info for the DMAC. + * @kmcache: Pool to quickly allocate xfers for all channels in the dmac. + */ +struct s3c_pl330_dmac { + unsigned busy_chan; + enum dma_ch *peri; + struct list_head node; + struct pl330_info *pi; + struct kmem_cache *kmcache; +}; + +/** + * struct s3c_pl330_xfer - A request submitted by S3C DMA clients. + * @token: Xfer ID provided by the client. + * @node: To attach to the list of xfers on a channel. + * @px: Xfer for PL330 core. + * @chan: Owner channel of this xfer. + */ +struct s3c_pl330_xfer { + void *token; + struct list_head node; + struct pl330_xfer px; + struct s3c_pl330_chan *chan; +}; + +/** + * struct s3c_pl330_chan - Logical channel to communicate with + * a Physical peripheral. + * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC. + * NULL if the channel is available to be acquired. + * @id: ID of the peripheral that this channel can communicate with. + * @options: Options specified by the client. + * @sdaddr: Address provided via s3c2410_dma_devconfig. + * @node: To attach to the global list of channels. + * @lrq: Pointer to the last submitted pl330_req to PL330 core. + * @xfer_list: To manage list of xfers enqueued. + * @req: Two requests to communicate with the PL330 engine. + * @callback_fn: Callback function to the client. + * @rqcfg: Channel configuration for the xfers. + * @xfer_head: Pointer to the xfer to be next excecuted. + * @dmac: Pointer to the DMAC that manages this channel, NULL if the + * channel is available to be acquired. + * @client: Client of this channel. NULL if the + * channel is available to be acquired. + */ +struct s3c_pl330_chan { + void *pl330_chan_id; + enum dma_ch id; + unsigned int options; + unsigned long sdaddr; + struct list_head node; + struct pl330_req *lrq; + struct list_head xfer_list; + struct pl330_req req[2]; + s3c2410_dma_cbfn_t callback_fn; + struct pl330_reqcfg rqcfg; + struct s3c_pl330_xfer *xfer_head; + struct s3c_pl330_dmac *dmac; + struct s3c2410_dma_client *client; +}; + +/* All DMACs in the platform */ +static LIST_HEAD(dmac_list); + +/* All channels to peripherals in the platform */ +static LIST_HEAD(chan_list); + +/* + * Since we add resources(DMACs and Channels) to the global pool, + * we need to guard access to the resources using a global lock + */ +static DEFINE_SPINLOCK(res_lock); + +/* Returns the channel with ID 'id' in the chan_list */ +static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id) +{ + struct s3c_pl330_chan *ch; + + list_for_each_entry(ch, &chan_list, node) + if (ch->id == id) + return ch; + + return NULL; +} + +/* Allocate a new channel with ID 'id' and add to chan_list */ +static void chan_add(const enum dma_ch id) +{ + struct s3c_pl330_chan *ch = id_to_chan(id); + + /* Return if the channel already exists */ + if (ch) + return; + + ch = kmalloc(sizeof(*ch), GFP_KERNEL); + /* Return silently to work with other channels */ + if (!ch) + return; + + ch->id = id; + ch->dmac = NULL; + + list_add_tail(&ch->node, &chan_list); +} + +/* If the channel is not yet acquired by any client */ +static bool chan_free(struct s3c_pl330_chan *ch) +{ + if (!ch) + return false; + + /* Channel points to some DMAC only when it's acquired */ + return ch->dmac ? false : true; +} + +/* + * Returns 0 is peripheral i/f is invalid or not present on the dmac. + * Index + 1, otherwise. + */ +static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id) +{ + enum dma_ch *id = dmac->peri; + int i; + + /* Discount invalid markers */ + if (ch_id == DMACH_MAX) + return 0; + + for (i = 0; i < PL330_MAX_PERI; i++) + if (id[i] == ch_id) + return i + 1; + + return 0; +} + +/* If all channel threads of the DMAC are busy */ +static inline bool dmac_busy(struct s3c_pl330_dmac *dmac) +{ + struct pl330_info *pi = dmac->pi; + + return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true; +} + +/* + * Returns the number of free channels that + * can be handled by this dmac only. + */ +static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac) +{ + enum dma_ch *id = dmac->peri; + struct s3c_pl330_dmac *d; + struct s3c_pl330_chan *ch; + unsigned found, count = 0; + enum dma_ch p; + int i; + + for (i = 0; i < PL330_MAX_PERI; i++) { + p = id[i]; + ch = id_to_chan(p); + + if (p == DMACH_MAX || !chan_free(ch)) + continue; + + found = 0; + list_for_each_entry(d, &dmac_list, node) { + if (d != dmac && iface_of_dmac(d, ch->id)) { + found = 1; + break; + } + } + if (!found) + count++; + }< |