From 1b49f10c69b45a8b169c69eaa127e7f91a32f7c7 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 16 Oct 2013 21:10:52 +0200 Subject: [PATCH 01/10] spi: s3c64xx: Do not require legacy DMA API in case of S3C64XX With support for amba-pl08x driver, on S3C64xx the generic DMA engine API can be used instead of the private s3c-dma interface. Signed-off-by: Tomasz Figa Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index eb1f1ef5fa2e..760d7b6b8591 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -395,7 +395,7 @@ config SPI_S3C24XX_FIQ config SPI_S3C64XX tristate "Samsung S3C64XX series type SPI" depends on PLAT_SAMSUNG - select S3C64XX_DMA if ARCH_S3C64XX + select S3C64XX_DMA if ARCH_S3C64XX && !S3C64XX_PL080 help SPI driver for Samsung S3C64XX and newer SoCs. From 1db0287ab186637488e51ae43109692624f2d5a3 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 16 Oct 2013 21:10:54 +0200 Subject: [PATCH 02/10] ARM: s3c64xx: Add support for DMA using generic amba-pl08x driver This patch adds all required platform-specific data and initialization code to support the generic amba-pl08x driver on S3C64xx SoCs. Also some compatibility definitions are added to make the transition from legacy API to DMA engine easier. The biggest hack here is passing const char * pointers through DMA resource, casted to unsigned long, but this is how Samsung DMA wrappers (used to support both s3c-dma and DMA engine in drivers) are designed. Signed-off-by: Tomasz Figa Signed-off-by: Mark Brown --- arch/arm/Kconfig | 1 + arch/arm/mach-s3c64xx/Kconfig | 8 +- arch/arm/mach-s3c64xx/Makefile | 1 + arch/arm/mach-s3c64xx/common.h | 5 + arch/arm/mach-s3c64xx/include/mach/dma.h | 63 ++++++ arch/arm/mach-s3c64xx/pl080.c | 244 +++++++++++++++++++++++ arch/arm/plat-samsung/devs.c | 10 +- arch/arm/plat-samsung/dma-ops.c | 8 +- 8 files changed, 336 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-s3c64xx/pl080.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c1f1a7eee953..ba0e23234ecf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -723,6 +723,7 @@ config ARCH_S3C64XX bool "Samsung S3C64XX" select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB + select ARM_AMBA select ARM_VIC select CLKDEV_LOOKUP select CLKSRC_SAMSUNG_PWM diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 2cb8dc55b50e..d8e0288bf2bf 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -17,9 +17,15 @@ config CPU_S3C6410 help Enable S3C6410 CPU support +config S3C64XX_PL080 + bool "S3C64XX DMA using generic PL08x driver" + select AMBA_PL08X + select SAMSUNG_DMADEV + config S3C64XX_DMA - bool "S3C64XX DMA" + bool "S3C64XX DMA using legacy S3C DMA API" select S3C_DMA + depends on !S3C64XX_PL080 config S3C64XX_SETUP_SDHCI bool diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 6faedcffce04..e8e9a468cbc9 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o # DMA support obj-$(CONFIG_S3C64XX_DMA) += dma.o +obj-$(CONFIG_S3C64XX_PL080) += pl080.o # Device support diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h index bd3bd562011e..7043e7a3a67e 100644 --- a/arch/arm/mach-s3c64xx/common.h +++ b/arch/arm/mach-s3c64xx/common.h @@ -58,4 +58,9 @@ int __init s3c64xx_pm_late_initcall(void); static inline int s3c64xx_pm_late_initcall(void) { return 0; } #endif +#ifdef CONFIG_S3C64XX_PL080 +extern struct pl08x_platform_data s3c64xx_dma0_plat_data; +extern struct pl08x_platform_data s3c64xx_dma1_plat_data; +#endif + #endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */ diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index fe1a98cf0e4c..26a6bc300589 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -11,6 +11,8 @@ #ifndef __ASM_ARCH_DMA_H #define __ASM_ARCH_DMA_H __FILE__ +#ifdef CONFIG_S3C64XX_DMA + #define S3C_DMA_CHANNELS (16) /* see mach-s3c2410/dma.h for notes on dma channel numbers */ @@ -128,4 +130,65 @@ struct s3c2410_dma_chan { #include +#else + +#define S3C64XX_DMA_CHAN(name) ((unsigned long)(name)) + +/* DMA0/SDMA0 */ +#define DMACH_UART0 S3C64XX_DMA_CHAN("uart0_tx") +#define DMACH_UART0_SRC2 S3C64XX_DMA_CHAN("uart0_rx") +#define DMACH_UART1 S3C64XX_DMA_CHAN("uart1_tx") +#define DMACH_UART1_SRC2 S3C64XX_DMA_CHAN("uart1_rx") +#define DMACH_UART2 S3C64XX_DMA_CHAN("uart2_tx") +#define DMACH_UART2_SRC2 S3C64XX_DMA_CHAN("uart2_rx") +#define DMACH_UART3 S3C64XX_DMA_CHAN("uart3_tx") +#define DMACH_UART3_SRC2 S3C64XX_DMA_CHAN("uart3_rx") +#define DMACH_PCM0_TX S3C64XX_DMA_CHAN("pcm0_tx") +#define DMACH_PCM0_RX S3C64XX_DMA_CHAN("pcm0_rx") +#define DMACH_I2S0_OUT S3C64XX_DMA_CHAN("i2s0_tx") +#define DMACH_I2S0_IN S3C64XX_DMA_CHAN("i2s0_rx") +#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx") +#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx") +#define DMACH_HSI_I2SV40_TX S3C64XX_DMA_CHAN("i2s2_tx") +#define DMACH_HSI_I2SV40_RX S3C64XX_DMA_CHAN("i2s2_rx") + +/* DMA1/SDMA1 */ +#define DMACH_PCM1_TX S3C64XX_DMA_CHAN("pcm1_tx") +#define DMACH_PCM1_RX S3C64XX_DMA_CHAN("pcm1_rx") +#define DMACH_I2S1_OUT S3C64XX_DMA_CHAN("i2s1_tx") +#define DMACH_I2S1_IN S3C64XX_DMA_CHAN("i2s1_rx") +#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx") +#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx") +#define DMACH_AC97_PCMOUT S3C64XX_DMA_CHAN("ac97_out") +#define DMACH_AC97_PCMIN S3C64XX_DMA_CHAN("ac97_in") +#define DMACH_AC97_MICIN S3C64XX_DMA_CHAN("ac97_mic") +#define DMACH_PWM S3C64XX_DMA_CHAN("pwm") +#define DMACH_IRDA S3C64XX_DMA_CHAN("irda") +#define DMACH_EXTERNAL S3C64XX_DMA_CHAN("external") +#define DMACH_SECURITY_RX S3C64XX_DMA_CHAN("sec_rx") +#define DMACH_SECURITY_TX S3C64XX_DMA_CHAN("sec_tx") + +enum dma_ch { + DMACH_MAX = 32 +}; + +struct s3c2410_dma_client { + char *name; +}; + +static inline bool samsung_dma_has_circular(void) +{ + return true; +} + +static inline bool samsung_dma_is_dmadev(void) +{ + return true; +} + +#include +#include + +#endif + #endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s3c64xx/pl080.c b/arch/arm/mach-s3c64xx/pl080.c new file mode 100644 index 000000000000..901a984bddc2 --- /dev/null +++ b/arch/arm/mach-s3c64xx/pl080.c @@ -0,0 +1,244 @@ +/* + * Samsung's S3C64XX generic DMA support using amba-pl08x driver. + * + * Copyright (c) 2013 Tomasz Figa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "regs-sys.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, + } +}; + +struct pl08x_platform_data s3c64xx_dma0_plat_data = { + .memcpy_channel = { + .bus_id = "memcpy", + .cctl_memcpy = + (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | + PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT | + PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | + PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | + PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | + PL080_CONTROL_PROT_SYS), + }, + .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), +}; + +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, + }, +}; + +struct pl08x_platform_data s3c64xx_dma1_plat_data = { + .memcpy_channel = { + .bus_id = "memcpy", + .cctl_memcpy = + (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT | + PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT | + PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | + PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | + PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE | + PL080_CONTROL_PROT_SYS), + }, + .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), +}; + +static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0, + 0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data); + +static int __init s3c64xx_pl080_init(void) +{ + /* 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); diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 99a3590f0349..ac07e871f6a7 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -1468,6 +1468,8 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; #if defined(CONFIG_PL330_DMA) pd.filter = pl330_filter; +#elif defined(CONFIG_S3C64XX_PL080) + pd.filter = pl08x_filter_id; #elif defined(CONFIG_S3C24XX_DMAC) pd.filter = s3c24xx_dma_filter; #endif @@ -1509,8 +1511,10 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio; -#ifdef CONFIG_PL330_DMA +#if defined(CONFIG_PL330_DMA) pd.filter = pl330_filter; +#elif defined(CONFIG_S3C64XX_PL080) + pd.filter = pl08x_filter_id; #endif s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1); @@ -1550,8 +1554,10 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, pd.num_cs = num_cs; pd.src_clk_nr = src_clk_nr; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio; -#ifdef CONFIG_PL330_DMA +#if defined(CONFIG_PL330_DMA) pd.filter = pl330_filter; +#elif defined(CONFIG_S3C64XX_PL080) + pd.filter = pl08x_filter_id; #endif s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2); diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index ec0d731b0e7b..886326ee6f6c 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -18,6 +18,12 @@ #include +#if defined(CONFIG_PL330_DMA) +#define dma_filter pl330_filter +#elif defined(CONFIG_S3C64XX_PL080) +#define dma_filter pl08x_filter_id +#endif + static unsigned samsung_dmadev_request(enum dma_ch dma_ch, struct samsung_dma_req *param, struct device *dev, char *ch_name) @@ -30,7 +36,7 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch, if (dev->of_node) return (unsigned)dma_request_slave_channel(dev, ch_name); else - return (unsigned)dma_request_channel(mask, pl330_filter, + return (unsigned)dma_request_channel(mask, dma_filter, (void *)dma_ch); } From d37f7617bd677c46c49daa3c023920cb91fe14db Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 16 Oct 2013 21:10:55 +0200 Subject: [PATCH 03/10] clk: samsung: s3c64xx: Add aliases for DMA clocks This patch adds clkdev aliases for clocks used by PL08x DMA driver. Signed-off-by: Tomasz Figa Signed-off-by: Mark Brown --- drivers/clk/samsung/clk-s3c64xx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index 7d2c84265947..06cf10592f52 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -332,7 +332,9 @@ static struct samsung_clock_alias s3c64xx_clock_aliases[] = { ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"), ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"), ALIAS(HCLK_DMA1, NULL, "dma1"), + ALIAS(HCLK_DMA1, "dma-pl080s.1", "apb_pclk"), ALIAS(HCLK_DMA0, NULL, "dma0"), + ALIAS(HCLK_DMA0, "dma-pl080s.0", "apb_pclk"), ALIAS(HCLK_CAMIF, "s3c-camif", "camif"), ALIAS(HCLK_LCD, "s3c-fb", "lcd"), ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"), From 15469ed37f8a9c004ac537495f9f7c51790a80c0 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 16 Oct 2013 21:10:56 +0200 Subject: [PATCH 04/10] ARM: s3c64xx: Remove legacy DMA driver Since support for generic PL08x DMA engine driver has been added, there is no need to keep the old legacy driver, so this patch removes it. Signed-off-by: Tomasz Figa Signed-off-by: Mark Brown --- arch/arm/mach-s3c64xx/Kconfig | 5 - arch/arm/mach-s3c64xx/Makefile | 1 - arch/arm/mach-s3c64xx/dma.c | 762 ----------------------- arch/arm/mach-s3c64xx/include/mach/dma.h | 123 ---- 4 files changed, 891 deletions(-) delete mode 100644 arch/arm/mach-s3c64xx/dma.c diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index d8e0288bf2bf..7094bccbae91 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -22,11 +22,6 @@ config S3C64XX_PL080 select AMBA_PL08X select SAMSUNG_DMADEV -config S3C64XX_DMA - bool "S3C64XX DMA using legacy S3C DMA API" - select S3C_DMA - depends on !S3C64XX_PL080 - config S3C64XX_SETUP_SDHCI bool select S3C64XX_SETUP_SDHCI_GPIO diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index e8e9a468cbc9..58069a702a43 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o # DMA support -obj-$(CONFIG_S3C64XX_DMA) += dma.o obj-$(CONFIG_S3C64XX_PL080) += pl080.o # Device support diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c deleted file mode 100644 index 7e22c2113816..000000000000 --- a/arch/arm/mach-s3c64xx/dma.c +++ /dev/null @@ -1,762 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/dma.c - * - * Copyright 2009 Openmoko, Inc. - * Copyright 2009 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * S3C64XX DMA core - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -/* - * NOTE: Code in this file is not used when booting with Device Tree support. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "regs-sys.h" - -/* dma channel state information */ - -struct s3c64xx_dmac { - struct device dev; - struct clk *clk; - void __iomem *regs; - struct s3c2410_dma_chan *channels; - enum dma_ch chanbase; -}; - -/* pool to provide LLI buffers */ -static struct dma_pool *dma_pool; - -/* Debug configuration and code */ - -static unsigned char debug_show_buffs = 0; - -static void dbg_showchan(struct s3c2410_dma_chan *chan) -{ - pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n", - chan->number, - readl(chan->regs + PL080_CH_SRC_ADDR), - readl(chan->regs + PL080_CH_DST_ADDR), - readl(chan->regs + PL080_CH_LLI), - readl(chan->regs + PL080_CH_CONTROL), - readl(chan->regs + PL080S_CH_CONTROL2), - readl(chan->regs + PL080S_CH_CONFIG)); -} - -static void show_lli(struct pl080s_lli *lli) -{ - pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n", - lli, lli->src_addr, lli->dst_addr, lli->next_lli, - lli->control0, lli->control1); -} - -static void dbg_showbuffs(struct s3c2410_dma_chan *chan) -{ - struct s3c64xx_dma_buff *ptr; - struct s3c64xx_dma_buff *end; - - pr_debug("DMA%d: buffs next %p, curr %p, end %p\n", - chan->number, chan->next, chan->curr, chan->end); - - ptr = chan->next; - end = chan->end; - - if (debug_show_buffs) { - for (; ptr != NULL; ptr = ptr->next) { - pr_debug("DMA%d: %08x ", - chan->number, ptr->lli_dma); - show_lli(ptr->lli); - } - } -} - -/* End of Debug */ - -static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel) -{ - struct s3c2410_dma_chan *chan; - unsigned int start, offs; - - start = 0; - - if (channel >= DMACH_PCM1_TX) - start = 8; - - for (offs = 0; offs < 8; offs++) { - chan = &s3c2410_chans[start + offs]; - if (!chan->in_use) - goto found; - } - - return NULL; - -found: - s3c_dma_chan_map[channel] = chan; - return chan; -} - -int s3c2410_dma_config(enum dma_ch channel, int xferunit) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - - if (chan == NULL) - return -EINVAL; - - switch (xferunit) { - case 1: - chan->hw_width = 0; - break; - case 2: - chan->hw_width = 1; - break; - case 4: - chan->hw_width = 2; - break; - default: - printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit); - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL(s3c2410_dma_config); - -static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan, - struct pl080s_lli *lli, - dma_addr_t data, int size) -{ - dma_addr_t src, dst; - u32 control0, control1; - - switch (chan->source) { - case DMA_FROM_DEVICE: - src = chan->dev_addr; - dst = data; - control0 = PL080_CONTROL_SRC_AHB2; - control0 |= PL080_CONTROL_DST_INCR; - break; - - case DMA_TO_DEVICE: - src = data; - dst = chan->dev_addr; - control0 = PL080_CONTROL_DST_AHB2; - control0 |= PL080_CONTROL_SRC_INCR; - break; - default: - BUG(); - } - - /* note, we do not currently setup any of the burst controls */ - - control1 = size >> chan->hw_width; /* size in no of xfers */ - control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */ - control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */ - control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT; - control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT; - - lli->src_addr = src; - lli->dst_addr = dst; - lli->next_lli = 0; - lli->control0 = control0; - lli->control1 = control1; -} - -static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan, - struct pl080s_lli *lli) -{ - void __iomem *regs = chan->regs; - - pr_debug("%s: LLI %p => regs\n", __func__, lli); - show_lli(lli); - - writel(lli->src_addr, regs + PL080_CH_SRC_ADDR); - writel(lli->dst_addr, regs + PL080_CH_DST_ADDR); - writel(lli->next_lli, regs + PL080_CH_LLI); - writel(lli->control0, regs + PL080_CH_CONTROL); - writel(lli->control1, regs + PL080S_CH_CONTROL2); -} - -static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan) -{ - struct s3c64xx_dmac *dmac = chan->dmac; - u32 config; - u32 bit = chan->bit; - - dbg_showchan(chan); - - pr_debug("%s: clearing interrupts\n", __func__); - - /* clear interrupts */ - writel(bit, dmac->regs + PL080_TC_CLEAR); - writel(bit, dmac->regs + PL080_ERR_CLEAR); - - pr_debug("%s: starting channel\n", __func__); - - config = readl(chan->regs + PL080S_CH_CONFIG); - config |= PL080_CONFIG_ENABLE; - config &= ~PL080_CONFIG_HALT; - - pr_debug("%s: writing config %08x\n", __func__, config); - writel(config, chan->regs + PL080S_CH_CONFIG); - - return 0; -} - -static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan) -{ - u32 config; - int timeout; - - pr_debug("%s: stopping channel\n", __func__); - - dbg_showchan(chan); - - config = readl(chan->regs + PL080S_CH_CONFIG); - config |= PL080_CONFIG_HALT; - writel(config, chan->regs + PL080S_CH_CONFIG); - - timeout = 1000; - do { - config = readl(chan->regs + PL080S_CH_CONFIG); - pr_debug("%s: %d - config %08x\n", __func__, timeout, config); - if (config & PL080_CONFIG_ACTIVE) - udelay(10); - else - break; - } while (--timeout > 0); - - if (config & PL080_CONFIG_ACTIVE) { - printk(KERN_ERR "%s: channel still active\n", __func__); - return -EFAULT; - } - - config = readl(chan->regs + PL080S_CH_CONFIG); - config &= ~PL080_CONFIG_ENABLE; - writel(config, chan->regs + PL080S_CH_CONFIG); - - return 0; -} - -static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan, - struct s3c64xx_dma_buff *buf, - enum s3c2410_dma_buffresult result) -{ - if (chan->callback_fn != NULL) - (chan->callback_fn)(chan, buf->pw, 0, result); -} - -static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff) -{ - dma_pool_free(dma_pool, buff->lli, buff->lli_dma); - kfree(buff); -} - -static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan) -{ - struct s3c64xx_dma_buff *buff, *next; - u32 config; - - dbg_showchan(chan); - - pr_debug("%s: flushing channel\n", __func__); - - config = readl(chan->regs + PL080S_CH_CONFIG); - config &= ~PL080_CONFIG_ENABLE; - writel(config, chan->regs + PL080S_CH_CONFIG); - - /* dump all the buffers associated with this channel */ - - for (buff = chan->curr; buff != NULL; buff = next) { - next = buff->next; - pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next); - - s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT); - s3c64xx_dma_freebuff(buff); - } - - chan->curr = chan->next = chan->end = NULL; - - return 0; -} - -int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - - WARN_ON(!chan); - if (!chan) - return -EINVAL; - - switch (op) { - case S3C2410_DMAOP_START: - return s3c64xx_dma_start(chan); - - case S3C2410_DMAOP_STOP: - return s3c64xx_dma_stop(chan); - - case S3C2410_DMAOP_FLUSH: - return s3c64xx_dma_flush(chan); - - /* believe PAUSE/RESUME are no-ops */ - case S3C2410_DMAOP_PAUSE: - case S3C2410_DMAOP_RESUME: - case S3C2410_DMAOP_STARTED: - case S3C2410_DMAOP_TIMEOUT: - return 0; - } - - return -ENOENT; -} -EXPORT_SYMBOL(s3c2410_dma_ctrl); - -/* s3c2410_dma_enque - * - */ - -int s3c2410_dma_enqueue(enum dma_ch channel, void *id, - dma_addr_t data, int size) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - struct s3c64xx_dma_buff *next; - struct s3c64xx_dma_buff *buff; - struct pl080s_lli *lli; - unsigned long flags; - int ret; - - WARN_ON(!chan); - if (!chan) - return -EINVAL; - - buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC); - if (!buff) { - printk(KERN_ERR "%s: no memory for buffer\n", __func__); - return -ENOMEM; - } - - lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma); - if (!lli) { - printk(KERN_ERR "%s: no memory for lli\n", __func__); - ret = -ENOMEM; - goto err_buff; - } - - pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n", - __func__, buff, data, lli, (u32)buff->lli_dma, size); - - buff->lli = lli; - buff->pw = id; - - s3c64xx_dma_fill_lli(chan, lli, data, size); - - local_irq_save(flags); - - if ((next = chan->next) != NULL) { - struct s3c64xx_dma_buff *end = chan->end; - struct pl080s_lli *endlli = end->lli; - - pr_debug("enquing onto channel\n"); - - end->next = buff; - endlli->next_lli = buff->lli_dma; - - if (chan->flags & S3C2410_DMAF_CIRCULAR) { - struct s3c64xx_dma_buff *curr = chan->curr; - lli->next_lli = curr->lli_dma; - } - - if (next == chan->curr) { - writel(buff->lli_dma, chan->regs + PL080_CH_LLI); - chan->next = buff; - } - - show_lli(endlli); - chan->end = buff; - } else { - pr_debug("enquing onto empty channel\n"); - - chan->curr = buff; - chan->next = buff; - chan->end = buff; - - s3c64xx_lli_to_regs(chan, lli); - } - - local_irq_restore(flags); - - show_lli(lli); - - dbg_showchan(chan); - dbg_showbuffs(chan); - return 0; - -err_buff: - kfree(buff); - return ret; -} - -EXPORT_SYMBOL(s3c2410_dma_enqueue); - - -int s3c2410_dma_devconfig(enum dma_ch channel, - enum dma_data_direction source, - unsigned long devaddr) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - u32 peripheral; - u32 config = 0; - - pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n", - __func__, channel, source, devaddr, chan); - - WARN_ON(!chan); - if (!chan) - return -EINVAL; - - peripheral = (chan->peripheral & 0xf); - chan->source = source; - chan->dev_addr = devaddr; - - pr_debug("%s: peripheral %d\n", __func__, peripheral); - - switch (source) { - case DMA_FROM_DEVICE: - config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT; - config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT; - break; - case DMA_TO_DEVICE: - config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT; - config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT; - break; - default: - printk(KERN_ERR "%s: bad source\n", __func__); - return -EINVAL; - } - - /* allow TC and ERR interrupts */ - config |= PL080_CONFIG_TC_IRQ_MASK; - config |= PL080_CONFIG_ERR_IRQ_MASK; - - pr_debug("%s: config %08x\n", __func__, config); - - writel(config, chan->regs + PL080S_CH_CONFIG); - - return 0; -} -EXPORT_SYMBOL(s3c2410_dma_devconfig); - - -int s3c2410_dma_getposition(enum dma_ch channel, - dma_addr_t *src, dma_addr_t *dst) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - - WARN_ON(!chan); - if (!chan) - return -EINVAL; - - if (src != NULL) - *src = readl(chan->regs + PL080_CH_SRC_ADDR); - - if (dst != NULL) - *dst = readl(chan->regs + PL080_CH_DST_ADDR); - - return 0; -} -EXPORT_SYMBOL(s3c2410_dma_getposition); - -/* s3c2410_request_dma - * - * get control of an dma channel -*/ - -int s3c2410_dma_request(enum dma_ch channel, - struct s3c2410_dma_client *client, - void *dev) -{ - struct s3c2410_dma_chan *chan; - unsigned long flags; - - pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n", - channel, client->name, dev); - - local_irq_save(flags); - - chan = s3c64xx_dma_map_channel(channel); - if (chan == NULL) { - local_irq_restore(flags); - return -EBUSY; - } - - dbg_showchan(chan); - - chan->client = client; - chan->in_use = 1; - chan->peripheral = channel; - chan->flags = 0; - - local_irq_restore(flags); - - /* need to setup */ - - pr_debug("%s: channel initialised, %p\n", __func__, chan); - - return chan->number | DMACH_LOW_LEVEL; -} - -EXPORT_SYMBOL(s3c2410_dma_request); - -/* s3c2410_dma_free - * - * release the given channel back to the system, will stop and flush - * any outstanding transfers, and ensure the channel is ready for the - * next claimant. - * - * Note, although a warning is currently printed if the freeing client - * info is not the same as the registrant's client info, the free is still - * allowed to go through. -*/ - -int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client) -{ - struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); - unsigned long flags; - - if (chan == NULL) - return -EINVAL; - - local_irq_save(flags); - - if (chan->client != client) { - printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n", - channel, chan->client, client); - } - - /* sort out stopping and freeing the channel */ - - - chan->client = NULL; - chan->in_use = 0; - - if (!(channel & DMACH_LOW_LEVEL)) - s3c_dma_chan_map[channel] = NULL; - - local_irq_restore(flags); - - return 0; -} - -EXPORT_SYMBOL(s3c2410_dma_free); - -static irqreturn_t s3c64xx_dma_irq(int irq, void *pw) -{ - struct s3c64xx_dmac *dmac = pw; - struct s3c2410_dma_chan *chan; - enum s3c2410_dma_buffresult res; - u32 tcstat, errstat; - u32 bit; - int offs; - - tcstat = readl(dmac->regs + PL080_TC_STATUS); - errstat = readl(dmac->regs + PL080_ERR_STATUS); - - for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) { - struct s3c64xx_dma_buff *buff; - - if (!(errstat & bit) && !(tcstat & bit)) - continue; - - chan = dmac->channels + offs; - res = S3C2410_RES_ERR; - - if (tcstat & bit) { - writel(bit, dmac->regs + PL080_TC_CLEAR); - res = S3C2410_RES_OK; - } - - if (errstat & bit) - writel(bit, dmac->regs + PL080_ERR_CLEAR); - - /* 'next' points to the buffer that is next to the - * currently active buffer. - * For CIRCULAR queues, 'next' will be same as 'curr' - * when 'end' is the active buffer. - */ - buff = chan->curr; - while (buff && buff != chan->next - && buff->next != chan->next) - buff = buff->next; - - if (!buff) - BUG(); - - if (buff == chan->next) - buff = chan->end; - - s3c64xx_dma_bufffdone(chan, buff, res); - - /* Free the node and update curr, if non-circular queue */ - if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) { - chan->curr = buff->next; - s3c64xx_dma_freebuff(buff); - } - - /* Update 'next' */ - buff = chan->next; - if (chan->next == chan->end) { - chan->next = chan->curr; - if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) - chan->end = NULL; - } else { - chan->next = buff->next; - } - } - - return IRQ_HANDLED; -} - -static struct bus_type dma_subsys = { - .name = "s3c64xx-dma", - .dev_name = "s3c64xx-dma", -}; - -static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, - int irq, unsigned int base) -{ - struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno]; - struct s3c64xx_dmac *dmac; - char clkname[16]; - void __iomem *regs; - void __iomem *regptr; - int err, ch; - - dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL); - if (!dmac) { - printk(KERN_ERR "%s: failed to alloc mem\n", __func__); - return -ENOMEM; - } - - dmac->dev.id = chno / 8; - dmac->dev.bus = &dma_subsys; - - err = device_register(&dmac->dev); - if (err) { - printk(KERN_ERR "%s: failed to register device\n", __func__); - goto err_alloc; - } - - regs = ioremap(base, 0x200); - if (!regs) { - printk(KERN_ERR "%s: failed to ioremap()\n", __func__); - err = -ENXIO; - goto err_dev; - } - - snprintf(clkname, sizeof(clkname), "dma%d", dmac->dev.id); - - dmac->clk = clk_get(NULL, clkname); - if (IS_ERR(dmac->clk)) { - printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname); - err = PTR_ERR(dmac->clk); - goto err_map; - } - - clk_prepare_enable(dmac->clk); - - dmac->regs = regs; - dmac->chanbase = chbase; - dmac->channels = chptr; - - err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac); - if (err < 0) { - printk(KERN_ERR "%s: failed to get irq\n", __func__); - goto err_clk; - } - - regptr = regs + PL080_Cx_BASE(0); - - for (ch = 0; ch < 8; ch++, chptr++) { - pr_debug("%s: registering DMA %d (%p)\n", - __func__, chno + ch, regptr); - - chptr->bit = 1 << ch; - chptr->number = chno + ch; - chptr->dmac = dmac; - chptr->regs = regptr; - regptr += PL080_Cx_STRIDE; - } - - /* for the moment, permanently enable the controller */ - writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG); - - printk(KERN_INFO "PL080: IRQ %d, at %p, channels %d..%d\n", - irq, regs, chno, chno+8); - - return 0; - -err_clk: - clk_disable_unprepare(dmac->clk); - clk_put(dmac->clk); -err_map: - iounmap(regs); -err_dev: - device_unregister(&dmac->dev); -err_alloc: - kfree(dmac); - return err; -} - -static int __init s3c64xx_dma_init(void) -{ - int ret; - - /* This driver is not supported when booting with device tree. */ - if (of_have_populated_dt()) - return -ENODEV; - - printk(KERN_INFO "%s: Registering DMA channels\n", __func__); - - dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0); - if (!dma_pool) { - printk(KERN_ERR "%s: failed to create pool\n", __func__); - return -ENOMEM; - } - - ret = subsys_system_register(&dma_subsys, NULL); - if (ret) { - printk(KERN_ERR "%s: failed to create subsys\n", __func__); - return -ENOMEM; - } - - /* Set all DMA configuration to be DMA, not SDMA */ - writel(0xffffff, S3C64XX_SDMA_SEL); - - /* Register standard DMA controllers */ - s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); - s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000); - - return 0; -} - -arch_initcall(s3c64xx_dma_init); diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 26a6bc300589..059b1fc85037 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -11,127 +11,6 @@ #ifndef __ASM_ARCH_DMA_H #define __ASM_ARCH_DMA_H __FILE__ -#ifdef CONFIG_S3C64XX_DMA - -#define S3C_DMA_CHANNELS (16) - -/* see mach-s3c2410/dma.h for notes on dma channel numbers */ - -/* Note, for the S3C64XX architecture we keep the DMACH_ - * defines in the order they are allocated to [S]DMA0/[S]DMA1 - * so that is easy to do DHACH_ -> DMA controller conversion - */ -enum dma_ch { - /* DMA0/SDMA0 */ - DMACH_UART0 = 0, - DMACH_UART0_SRC2, - DMACH_UART1, - DMACH_UART1_SRC2, - DMACH_UART2, - DMACH_UART2_SRC2, - DMACH_UART3, - DMACH_UART3_SRC2, - DMACH_PCM0_TX, - DMACH_PCM0_RX, - DMACH_I2S0_OUT, - DMACH_I2S0_IN, - DMACH_SPI0_TX, - DMACH_SPI0_RX, - DMACH_HSI_I2SV40_TX, - DMACH_HSI_I2SV40_RX, - - /* DMA1/SDMA1 */ - DMACH_PCM1_TX = 16, - DMACH_PCM1_RX, - DMACH_I2S1_OUT, - DMACH_I2S1_IN, - DMACH_SPI1_TX, - DMACH_SPI1_RX, - DMACH_AC97_PCMOUT, - DMACH_AC97_PCMIN, - DMACH_AC97_MICIN, - DMACH_PWM, - DMACH_IRDA, - DMACH_EXTERNAL, - DMACH_RES1, - DMACH_RES2, - DMACH_SECURITY_RX, /* SDMA1 only */ - DMACH_SECURITY_TX, /* SDMA1 only */ - DMACH_MAX /* the end */ -}; - -static inline bool samsung_dma_has_circular(void) -{ - return true; -} - -static inline bool samsung_dma_is_dmadev(void) -{ - return false; -} -#define S3C2410_DMAF_CIRCULAR (1 << 0) - -#include - -#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ - -struct s3c64xx_dma_buff; - -/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor - * @next: Pointer to next buffer in queue or ring. - * @pw: Client provided identifier - * @lli: Pointer to hardware descriptor this buffer is associated with. - * @lli_dma: Hardare address of the descriptor. - */ -struct s3c64xx_dma_buff { - struct s3c64xx_dma_buff *next; - - void *pw; - struct pl080s_lli *lli; - dma_addr_t lli_dma; -}; - -struct s3c64xx_dmac; - -struct s3c2410_dma_chan { - unsigned char number; /* number of this dma channel */ - unsigned char in_use; /* channel allocated */ - unsigned char bit; /* bit for enable/disable/etc */ - unsigned char hw_width; - unsigned char peripheral; - - unsigned int flags; - enum dma_data_direction source; - - - dma_addr_t dev_addr; - - struct s3c2410_dma_client *client; - struct s3c64xx_dmac *dmac; /* pointer to controller */ - - void __iomem *regs; - - /* cdriver callbacks */ - s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */ - s3c2410_dma_opfn_t op_fn; /* channel op callback */ - - /* buffer list and information */ - struct s3c64xx_dma_buff *curr; /* current dma buffer */ - struct s3c64xx_dma_buff *next; /* next buffer to load */ - struct s3c64xx_dma_buff *end; /* end of queue */ - - /* note, when channel is running in circular mode, curr is the - * first buffer enqueued, end is the last and curr is where the - * last buffer-done event is set-at. The buffers are not freed - * and the last buffer hardware descriptor points back to the - * first. - */ -}; - -#include - -#else - #define S3C64XX_DMA_CHAN(name) ((unsigned long)(name)) /* DMA0/SDMA0 */ @@ -189,6 +68,4 @@ static inline bool samsung_dma_is_dmadev(void) #include #include -#endif - #endif /* __ASM_ARCH_IRQ_H */ From a7a996d19219424c8ca8f16474138b4ee170727f Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 16 Oct 2013 21:10:57 +0200 Subject: [PATCH 05/10] clk: samsung: s3c64xx: Remove clock aliases of old DMA driver Since the old DMA driver got removed, these aliases are no longer necessary. Signed-off-by: Tomasz Figa Signed-off-by: Mark Brown --- drivers/clk/samsung/clk-s3c64xx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index 06cf10592f52..8e27aee6887e 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -331,9 +331,7 @@ static struct samsung_clock_alias s3c64xx_clock_aliases[] = { ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"), ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"), ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"), - ALIAS(HCLK_DMA1, NULL, "dma1"), ALIAS(HCLK_DMA1, "dma-pl080s.1", "apb_pclk"), - ALIAS(HCLK_DMA0, NULL, "dma0"), ALIAS(HCLK_DMA0, "dma-pl080s.0", "apb_pclk"), ALIAS(HCLK_CAMIF, "s3c-camif", "camif"), ALIAS(HCLK_LCD, "s3c-fb", "lcd"), From 3faecea70b0d6d050e0ae911032ec340341dc389 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 16 Oct 2013 21:10:58 +0200 Subject: [PATCH 06/10] spi: s3c64xx: Always select S3C64XX_PL080 when ARCH_S3C64XX is enabled The legacy S3C64xx DMA driver has been removed, DMA support on S3C64xx is provided only by the generic PL08x driver. This patch modifies the Kconfig entry of spi-s3c64xx driver, which relies on availability of DMA, to always select the S3C64XX_PL080 symbol. Signed-off-by: Tomasz Figa Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 760d7b6b8591..e2dd2fbec5ee 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -395,7 +395,7 @@ config SPI_S3C24XX_FIQ config SPI_S3C64XX tristate "Samsung S3C64XX series type SPI" depends on PLAT_SAMSUNG - select S3C64XX_DMA if ARCH_S3C64XX && !S3C64XX_PL080 + select S3C64XX_PL080 if ARCH_S3C64XX help SPI driver for Samsung S3C64XX and newer SoCs. From 3688569e8173e84cd95d98f158245e17bca4f593 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 19 Oct 2013 15:23:15 +0100 Subject: [PATCH 07/10] ASoC: samsung: Provide helper for DMA init In preparation for using the dmaengine helpers in ASoC rather than the dmaengine wrappers for the Samsung API wrap the configuration of dma_data. The dmaengine code expects different data to that used by the legacy API. Signed-off-by: Mark Brown --- sound/soc/samsung/ac97.c | 51 +++++++++++++--------------------------- sound/soc/samsung/dma.c | 8 +++++++ sound/soc/samsung/dma.h | 3 +++ sound/soc/samsung/i2s.c | 7 ++++-- sound/soc/samsung/pcm.c | 18 +++++++------- 5 files changed, 42 insertions(+), 45 deletions(-) diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 350ba23a9893..4a88e36c82ec 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -221,24 +221,6 @@ static struct snd_ac97_bus_ops s3c_ac97_ops = { .reset = s3c_ac97_cold_reset, }; -static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct s3c_dma_params *dma_data; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = &s3c_ac97_pcm_out; - else - dma_data = &s3c_ac97_pcm_in; - - snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); - - return 0; -} - static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -279,21 +261,6 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - else - snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in); - - return 0; -} - static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -329,15 +296,27 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops s3c_ac97_dai_ops = { - .hw_params = s3c_ac97_hw_params, .trigger = s3c_ac97_trigger, }; static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { - .hw_params = s3c_ac97_hw_mic_params, .trigger = s3c_ac97_mic_trigger, }; +static int s3c_ac97_dai_probe(struct snd_soc_dai *dai) +{ + samsung_asoc_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in); + + return 0; +} + +static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai) +{ + samsung_asoc_init_dma_data(dai, NULL, &s3c_ac97_mic_in); + + return 0; +} + static struct snd_soc_dai_driver s3c_ac97_dai[] = { [S3C_AC97_DAI_PCM] = { .name = "samsung-ac97", @@ -354,6 +333,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .probe = s3c_ac97_dai_probe, .ops = &s3c_ac97_dai_ops, }, [S3C_AC97_DAI_MIC] = { @@ -365,6 +345,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { .channels_max = 1, .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .probe = s3c_ac97_mic_dai_probe, .ops = &s3c_ac97_mic_dai_ops, }, }; diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index fe2748b494d4..ee23194f7ab8 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -441,6 +441,14 @@ static struct snd_soc_platform_driver samsung_asoc_platform = { .pcm_free = dma_free_dma_buffers, }; +void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, + struct s3c_dma_params *playback, + struct s3c_dma_params *capture) +{ + snd_soc_dai_init_dma_data(dai, playback, capture); +} +EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); + int samsung_asoc_dma_platform_register(struct device *dev) { return snd_soc_register_platform(dev, &samsung_asoc_platform); diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index 0e86315a3eaf..fb09a1c5f75b 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h @@ -22,6 +22,9 @@ struct s3c_dma_params { char *ch_name; }; +void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, + struct s3c_dma_params *playback, + struct s3c_dma_params *capture); int samsung_asoc_dma_platform_register(struct device *dev); void samsung_asoc_dma_platform_unregister(struct device *dev); diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index a5cbdb4f1655..eab0050d4579 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -946,8 +946,11 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - if (other && other->clk) /* If this is probe on secondary */ + if (other && other->clk) { /* If this is probe on secondary */ + samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, + NULL); goto probe_exit; + } i2s->addr = ioremap(i2s->base, 0x100); if (i2s->addr == NULL) { @@ -963,7 +966,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) } clk_prepare_enable(i2s->clk); - snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); + samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); if (other) { other->addr = i2s->addr; diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index e54256fc4b2c..6a5e4bf6ac96 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -275,7 +275,6 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); - struct s3c_dma_params *dma_data; void __iomem *regs = pcm->regs; struct clk *clk; int sclk_div, sync_div; @@ -284,13 +283,6 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, dev_dbg(pcm->dev, "Entered %s\n", __func__); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = pcm->dma_playback; - else - dma_data = pcm->dma_capture; - - snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); - /* Strictly check for sample size */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -461,10 +453,20 @@ static const struct snd_soc_dai_ops s3c_pcm_dai_ops = { .set_fmt = s3c_pcm_set_fmt, }; +static int s3c_pcm_dai_probe(struct snd_soc_dai *dai) +{ + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, pcm->dma_playback, pcm->dma_capture); + + return 0; +} + #define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 #define S3C_PCM_DAI_DECLARE \ .symmetric_rates = 1, \ + .probe = s3c_pcm_dai_probe, \ .ops = &s3c_pcm_dai_ops, \ .playback = { \ .channels_min = 2, \ From d37bdf736d9b7a198d35aaaf611e96ddc2e00ddf Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 5 Dec 2013 14:14:52 +0000 Subject: [PATCH 08/10] ASoC: samsung: Use ASoC dmaengine code where possible Since all Exynos platforms have been converted to dmaengine and many of the older platforms are in the process of conversion they do not need to use the legacy s3c-dma APIs for DMA but can instead use the standard ASoC dmaengine helpers. This both allows them to benefit from improvements implemented in the generic code and supports multiplatform. This patch includes some fixes from Padma for Exynos SoCs, her testing was on a slightly earlier version of the patch due to unrelated breakage preventing testing. Signed-off-by: Mark Brown Tested By: Padmavathi Venna --- sound/soc/samsung/Kconfig | 13 +++++- sound/soc/samsung/Makefile | 6 ++- sound/soc/samsung/dma.h | 3 ++ sound/soc/samsung/dmaengine.c | 84 +++++++++++++++++++++++++++++++++++ sound/soc/samsung/i2s.c | 2 + 5 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 sound/soc/samsung/dmaengine.c diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 37459dfd168d..27930fc432dc 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -1,13 +1,22 @@ config SND_SOC_SAMSUNG tristate "ASoC support for Samsung" depends on PLAT_SAMSUNG - select S3C64XX_DMA if ARCH_S3C64XX - select S3C24XX_DMA if ARCH_S3C24XX + select S3C2410_DMA if ARCH_S3C24XX + select S3C64XX_PL080 if ARCH_S3C64XX + select SND_S3C_DMA if !ARCH_S3C24XX + select SND_S3C_DMA_LEGACY if ARCH_S3C24XX + select SND_SOC_GENERIC_DMAENGINE_PCM if !ARCH_S3C24XX help Say Y or M if you want to add support for codecs attached to the Samsung SoCs' Audio interfaces. You will also need to select the audio interfaces to support below. +config SND_S3C_DMA + tristate + +config SND_S3C_DMA_LEGACY + tristate + config SND_S3C24XX_I2S tristate select S3C2410_DMA diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 709f6059ad67..86715d8efee6 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -1,5 +1,6 @@ # S3c24XX Platform Support -snd-soc-s3c24xx-objs := dma.o +snd-soc-s3c-dma-objs := dmaengine.o +snd-soc-s3c-dma-legacy-objs := dma.o snd-soc-idma-objs := idma.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o @@ -9,7 +10,8 @@ snd-soc-samsung-spdif-objs := spdif.o snd-soc-pcm-objs := pcm.o snd-soc-i2s-objs := i2s.o -obj-$(CONFIG_SND_SOC_SAMSUNG) += snd-soc-s3c24xx.o +obj-$(CONFIG_SND_S3C_DMA) += snd-soc-s3c-dma.o +obj-$(CONFIG_SND_S3C_DMA_LEGACY) += snd-soc-s3c-dma-legacy.o obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index fb09a1c5f75b..225e5378014e 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h @@ -12,6 +12,8 @@ #ifndef _S3C_AUDIO_H #define _S3C_AUDIO_H +#include + struct s3c_dma_params { struct s3c2410_dma_client *client; /* stream identifier */ int channel; /* Channel ID */ @@ -20,6 +22,7 @@ struct s3c_dma_params { unsigned ch; struct samsung_dma_ops *ops; char *ch_name; + struct snd_dmaengine_dai_dma_data dma_data; }; void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c new file mode 100644 index 000000000000..3be479d51b9b --- /dev/null +++ b/sound/soc/samsung/dmaengine.c @@ -0,0 +1,84 @@ +/* + * dmaengine.c - Samsung dmaengine wrapper + * + * Author: Mark Brown + * Copyright 2013 Linaro + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "dma.h" + +#ifdef CONFIG_ARCH_S3C64XX +#define filter_fn pl08x_filter_id +#else +#define filter_fn NULL +#endif + +static const struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = { + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, + .compat_filter_fn = filter_fn, +}; + +void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, + struct s3c_dma_params *playback, + struct s3c_dma_params *capture) +{ + struct snd_dmaengine_dai_dma_data *playback_data = NULL; + struct snd_dmaengine_dai_dma_data *capture_data = NULL; + + if (playback) { + playback_data = &playback->dma_data; + playback_data->filter_data = (void *)playback->channel; + playback_data->chan_name = playback->ch_name; + playback_data->addr = playback->dma_addr; + playback_data->addr_width = playback->dma_size; + } + if (capture) { + capture_data = &capture->dma_data; + capture_data->filter_data = (void *)capture->channel; + capture_data->chan_name = capture->ch_name; + capture_data->addr = capture->dma_addr; + capture_data->addr_width = capture->dma_size; + } + + snd_soc_dai_init_dma_data(dai, playback_data, capture_data); +} +EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); + +int samsung_asoc_dma_platform_register(struct device *dev) +{ + return snd_dmaengine_pcm_register(dev, &samsung_dmaengine_pcm_config, + SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + SND_DMAENGINE_PCM_FLAG_COMPAT); +} +EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); + +void samsung_asoc_dma_platform_unregister(struct device *dev) +{ + return snd_dmaengine_pcm_unregister(dev); +} +EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_unregister); + +MODULE_AUTHOR("Mark Brown "); +MODULE_DESCRIPTION("Samsung dmaengine ASoC driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index eab0050d4579..92f64363427d 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -702,6 +702,8 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, } writel(mod, i2s->addr + I2SMOD); + samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); + i2s->frmclk = params_rate(params); return 0; From 61c66c60c75bd7f9650e27fb0a017bc39f2629a2 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 26 Dec 2013 11:41:29 +0530 Subject: [PATCH 09/10] ASoC: samsung: Trivial cleanups in header files commit 5d229ce569be ("ASoC: samsung: move plat/ headers to local directory") moved the header files but forgot to clean the pointers to their old locaton. Remove them now. Signed-off-by: Sachin Kamat Reviewed-by: Jingoo Han Signed-off-by: Mark Brown --- sound/soc/samsung/regs-ac97.h | 9 ++++----- sound/soc/samsung/regs-iis.h | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/sound/soc/samsung/regs-ac97.h b/sound/soc/samsung/regs-ac97.h index c3878f7acb83..a71be45bbffc 100644 --- a/sound/soc/samsung/regs-ac97.h +++ b/sound/soc/samsung/regs-ac97.h @@ -1,5 +1,4 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-ac97.h - * +/* * Copyright (c) 2006 Simtec Electronics * http://www.simtec.co.uk/products/SWLINUX/ * @@ -10,8 +9,8 @@ * S3C2440 AC97 Controller */ -#ifndef __ASM_ARCH_REGS_AC97_H -#define __ASM_ARCH_REGS_AC97_H __FILE__ +#ifndef __SAMSUNG_REGS_AC97_H__ +#define __SAMSUNG_REGS_AC97_H__ #define S3C_AC97_GLBCTRL (0x00) @@ -64,4 +63,4 @@ #define S3C_AC97_PCM_DATA (0x18) #define S3C_AC97_MIC_DATA (0x1C) -#endif /* __ASM_ARCH_REGS_AC97_H */ +#endif /* __SAMSUNG_REGS_AC97_H__ */ diff --git a/sound/soc/samsung/regs-iis.h b/sound/soc/samsung/regs-iis.h index a18d35e7a735..dc6cbbe9c4f0 100644 --- a/sound/soc/samsung/regs-iis.h +++ b/sound/soc/samsung/regs-iis.h @@ -1,5 +1,4 @@ -/* arch/arm/plat-samsung/include/plat/regs-iis.h - * +/* * Copyright (c) 2003 Simtec Electronics * http://www.simtec.co.uk/products/SWLINUX/ * @@ -10,8 +9,8 @@ * S3C2410 IIS register definition */ -#ifndef __ASM_ARCH_REGS_IIS_H -#define __ASM_ARCH_REGS_IIS_H +#ifndef __SAMSUNG_REGS_IIS_H__ +#define __SAMSUNG_REGS_IIS_H__ #define S3C2410_IISCON (0x00) @@ -67,4 +66,4 @@ #define S3C2410_IISFIFO (0x10) -#endif /* __ASM_ARCH_REGS_IIS_H */ +#endif /* __SAMSUNG_REGS_IIS_H__ */ From 328089a47112a4fc06071e2003ecd75cc6d31029 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 20 Dec 2013 14:20:20 +0100 Subject: [PATCH 10/10] ASoC: samsung: Don't set unused struct snd_pcm_hardware fields The ASoC core assumes that the PCM component of the ASoC card transparently moves data around and does not impose any restrictions on the memory layout or the transfer speed. It ignores all fields from the snd_pcm_hardware struct for the PCM driver that are related to this. Setting these fields in the PCM driver might suggest otherwise though, so rather not set them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/dma.c | 6 ------ sound/soc/samsung/idma.c | 8 -------- 2 files changed, 14 deletions(-) diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index ee23194f7ab8..dc09b71b7d9f 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -35,12 +35,6 @@ static const struct snd_pcm_hardware dma_hardware = { SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S8, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = 128*1024, .period_bytes_min = PAGE_SIZE, .period_bytes_max = PAGE_SIZE*2, diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index e4f318fc2f82..3d5cf1530b6f 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -35,14 +35,6 @@ static const struct snd_pcm_hardware idma_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_U24_LE | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S8, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = MAX_IDMA_BUFFER, .period_bytes_min = 128, .period_bytes_max = MAX_IDMA_PERIOD,