From 4477ca45fb368880bf77b10ed3b24b03f0cc82da Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 21 Mar 2013 21:02:37 +0100 Subject: ARM: ARMv7-M: Allow the building of new kernel port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch modifies the required Kconfig and Makefile files to allow the building of kernel for Cortex-M3. Signed-off-by: Catalin Marinas Reviewed-by: Jonathan Austin Tested-by: Jonathan Austin Signed-off-by: Uwe Kleine-König --- arch/arm/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dedf02b6f322..7c8c6079f948 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -9,7 +9,7 @@ config ARM select BUILDTIME_EXTABLE_SORT if MMU select CPU_PM if (SUSPEND || CPU_IDLE) select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU - select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) + select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW @@ -1685,7 +1685,7 @@ config SCHED_HRTICK config THUMB2_KERNEL bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY - depends on CPU_V7 && !CPU_V6 && !CPU_V6K + depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K default y if CPU_THUMBONLY select AEABI select ARM_ASM_UNIFIED -- cgit v1.2.3 From 0e2ee0c0610ec211a9f0ebf3088cbf4da422ebf8 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 27 Jan 2013 11:07:23 +0100 Subject: arm: kirkwood: Instantiate cpufreq driver Register a platform driver structure for the cpufreq driver. Signed-off-by: Andrew Lunn Tested-by: Adam Baker Signed-off-by: Jason Cooper --- arch/arm/Kconfig | 1 + arch/arm/mach-kirkwood/board-dt.c | 2 ++ arch/arm/mach-kirkwood/common.c | 23 +++++++++++++++++++++++ arch/arm/mach-kirkwood/common.h | 2 ++ arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 2 ++ 5 files changed, 30 insertions(+) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d423d58f938d..76fa76687262 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -501,6 +501,7 @@ config ARCH_DOVE config ARCH_KIRKWOOD bool "Marvell Kirkwood" + select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB select CPU_FEROCEON select GENERIC_CLOCKEVENTS diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index a8dae114b537..4cc9edf39865 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -92,6 +92,8 @@ static void __init kirkwood_dt_init(void) kirkwood_l2_init(); + kirkwood_cpufreq_init(); + /* Setup root of clk tree */ kirkwood_of_clk_init(); diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c2cae69e6d2b..97882fcbf6ee 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -603,6 +603,29 @@ void __init kirkwood_audio_init(void) platform_device_register(&kirkwood_pcm_device); } +/***************************************************************************** + * CPU Frequency + ****************************************************************************/ +static struct resource kirkwood_cpufreq_resources[] = { + [0] = { + .start = CPU_CONTROL_PHYS, + .end = CPU_CONTROL_PHYS + 3, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device kirkwood_cpufreq_device = { + .name = "kirkwood-cpufreq", + .id = -1, + .num_resources = ARRAY_SIZE(kirkwood_cpufreq_resources), + .resource = kirkwood_cpufreq_resources, +}; + +void __init kirkwood_cpufreq_init(void) +{ + platform_device_register(&kirkwood_cpufreq_device); +} + /***************************************************************************** * General ****************************************************************************/ diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 21da3b1ebd7b..99e769893c35 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -51,6 +51,8 @@ void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *)); void kirkwood_audio_init(void); void kirkwood_cpuidle_init(void); +void kirkwood_cpufreq_init(void); + void kirkwood_restart(char, const char *); void kirkwood_clk_init(void); diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index 5c82b7dce4e2..d4cbe5e81bb4 100644 --- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -17,6 +17,7 @@ #define CPU_CONFIG_ERROR_PROP 0x00000004 #define CPU_CONTROL (BRIDGE_VIRT_BASE + 0x0104) +#define CPU_CONTROL_PHYS (BRIDGE_PHYS_BASE + 0x0104) #define CPU_RESET 0x00000002 #define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) @@ -69,6 +70,7 @@ #define CGC_RUNIT (1 << 7) #define CGC_XOR0 (1 << 8) #define CGC_AUDIO (1 << 9) +#define CGC_POWERSAVE (1 << 11) #define CGC_SATA0 (1 << 14) #define CGC_SATA1 (1 << 15) #define CGC_XOR1 (1 << 16) -- cgit v1.2.3 From 5a5056cccfb0479f52a0464a6b371b441c84aa0c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 8 Apr 2013 10:50:11 +0200 Subject: ARM: u300: device tree support for the timer This adds device tree support for the U300 timer, by making the memory base offset and IRQ dynamically assigned, then optionally looking them up from the device tree. Since the timer needs to be registered before any platform devices are created, we will go into the device tree and look up the "/timer@c0014000" node and read our base address and IRQ from there. Signed-off-by: Linus Walleij --- .../bindings/timer/stericsson-u300-apptimer.txt | 18 ++++ arch/arm/Kconfig | 1 + arch/arm/mach-u300/timer.c | 109 ++++++++++++++------- arch/arm/mach-u300/timer.h | 1 + 4 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt (limited to 'arch/arm/Kconfig') diff --git a/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt b/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt new file mode 100644 index 000000000000..9499bc8ee9e3 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt @@ -0,0 +1,18 @@ +ST-Ericsson U300 apptimer + +Required properties: + +- compatible : should be "stericsson,u300-apptimer" +- reg : Specifies base physical address and size of the registers. +- interrupts : A list of 4 interrupts; one for each subtimer. These + are, in order: OS (operating system), DD (device driver) both + adopted for EPOC/Symbian with two specific IRQs for these tasks, + then GP1 and GP2, which are general-purpose timers. + +Example: + +timer { + compatible = "stericsson,u300-apptimer"; + reg = <0xc0014000 0x1000>; + interrupts = <24 25 26 27>; +}; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d423d58f938d..fbad3337a838 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -821,6 +821,7 @@ config ARCH_U300 select ARM_VIC select CLKDEV_LOOKUP select CLKSRC_MMIO + select CLKSRC_OF select COMMON_CLK select CPU_ARM926T select GENERIC_CLOCKEVENTS diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c index c3d3802b46a0..df1e3b5427b6 100644 --- a/arch/arm/mach-u300/timer.c +++ b/arch/arm/mach-u300/timer.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -190,6 +192,8 @@ #define TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) #define US_PER_TICK ((1000000 + (HZ/2)) / HZ) +static void __iomem *u300_timer_base; + /* * The u300_set_mode() function is always called first, if we * have oneshot timer active, the oneshot scheduling function @@ -202,28 +206,28 @@ static void u300_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_PERIODIC: /* Disable interrupts on GPT1 */ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + u300_timer_base + U300_TIMER_APP_GPT1IE); /* Disable GP1 while we're reprogramming it. */ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); + u300_timer_base + U300_TIMER_APP_DGPT1); /* * Set the periodic mode to a certain number of ticks per * jiffy. */ writel(TICKS_PER_JIFFY, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC); + u300_timer_base + U300_TIMER_APP_GPT1TC); /* * Set continuous mode, so the timer keeps triggering * interrupts. */ writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS, - U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M); + u300_timer_base + U300_TIMER_APP_SGPT1M); /* Enable timer interrupts */ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + u300_timer_base + U300_TIMER_APP_GPT1IE); /* Then enable the OS timer again */ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1); + u300_timer_base + U300_TIMER_APP_EGPT1); break; case CLOCK_EVT_MODE_ONESHOT: /* Just break; here? */ @@ -234,33 +238,33 @@ static void u300_set_mode(enum clock_event_mode mode, */ /* Disable interrupts on GPT1 */ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + u300_timer_base + U300_TIMER_APP_GPT1IE); /* Disable GP1 while we're reprogramming it. */ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); + u300_timer_base + U300_TIMER_APP_DGPT1); /* * Expire far in the future, u300_set_next_event() will be * called soon... */ - writel(0xFFFFFFFF, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC); + writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC); /* We run one shot per tick here! */ writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, - U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M); + u300_timer_base + U300_TIMER_APP_SGPT1M); /* Enable interrupts for this timer */ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + u300_timer_base + U300_TIMER_APP_GPT1IE); /* Enable timer */ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1); + u300_timer_base + U300_TIMER_APP_EGPT1); break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: /* Disable interrupts on GP1 */ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + u300_timer_base + U300_TIMER_APP_GPT1IE); /* Disable GP1 */ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); + u300_timer_base + U300_TIMER_APP_DGPT1); break; case CLOCK_EVT_MODE_RESUME: /* Ignore this call */ @@ -282,27 +286,27 @@ static int u300_set_next_event(unsigned long cycles, { /* Disable interrupts on GPT1 */ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + u300_timer_base + U300_TIMER_APP_GPT1IE); /* Disable GP1 while we're reprogramming it. */ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); + u300_timer_base + U300_TIMER_APP_DGPT1); /* Reset the General Purpose timer 1. */ writel(U300_TIMER_APP_RGPT1_TIMER_RESET, - U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1); + u300_timer_base + U300_TIMER_APP_RGPT1); /* IRQ in n * cycles */ - writel(cycles, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC); + writel(cycles, u300_timer_base + U300_TIMER_APP_GPT1TC); /* * We run one shot per tick here! (This is necessary to reconfigure, * the timer will tilt if you don't!) */ writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, - U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M); + u300_timer_base + U300_TIMER_APP_SGPT1M); /* Enable timer interrupts */ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + u300_timer_base + U300_TIMER_APP_GPT1IE); /* Then enable the OS timer again */ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1); + u300_timer_base + U300_TIMER_APP_EGPT1); return 0; } @@ -321,8 +325,9 @@ static irqreturn_t u300_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = &clockevent_u300_1mhz; /* ACK/Clear timer IRQ for the APP GPT1 Timer */ + writel(U300_TIMER_APP_GPT1IA_IRQ_ACK, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IA); + u300_timer_base + U300_TIMER_APP_GPT1IA); evt->event_handler(evt); return IRQ_HANDLED; } @@ -343,12 +348,12 @@ static struct irqaction u300_timer_irq = { static u32 notrace u300_read_sched_clock(void) { - return readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); + return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); } static unsigned long u300_read_current_timer(void) { - return readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); + return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); } static struct delay_timer u300_delay_timer; @@ -356,11 +361,14 @@ static struct delay_timer u300_delay_timer; /* * This sets up the system timers, clock source and clock event. */ -void __init u300_timer_init(void) +static void __init u300_timer_setup(void __iomem *base, int irq) { struct clk *clk; unsigned long rate; + u300_timer_base = base; + pr_info("U300 GP1 timer @ base: %p, IRQ: %d\n", u300_timer_base, irq); + /* Clock the interrupt controller */ clk = clk_get_sys("apptimer", NULL); BUG_ON(IS_ERR(clk)); @@ -378,40 +386,40 @@ void __init u300_timer_init(void) * Example usage in cnh1601578 cpu subsystem pd_timer_app.c */ writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_CRC); + u300_timer_base + U300_TIMER_APP_CRC); writel(U300_TIMER_APP_ROST_TIMER_RESET, - U300_TIMER_APP_VBASE + U300_TIMER_APP_ROST); + u300_timer_base + U300_TIMER_APP_ROST); writel(U300_TIMER_APP_DOST_TIMER_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_DOST); + u300_timer_base + U300_TIMER_APP_DOST); writel(U300_TIMER_APP_RDDT_TIMER_RESET, - U300_TIMER_APP_VBASE + U300_TIMER_APP_RDDT); + u300_timer_base + U300_TIMER_APP_RDDT); writel(U300_TIMER_APP_DDDT_TIMER_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_DDDT); + u300_timer_base + U300_TIMER_APP_DDDT); /* Reset the General Purpose timer 1. */ writel(U300_TIMER_APP_RGPT1_TIMER_RESET, - U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1); + u300_timer_base + U300_TIMER_APP_RGPT1); /* Set up the IRQ handler */ - setup_irq(IRQ_U300_TIMER_APP_GP1, &u300_timer_irq); + setup_irq(irq, &u300_timer_irq); /* Reset the General Purpose timer 2 */ writel(U300_TIMER_APP_RGPT2_TIMER_RESET, - U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT2); + u300_timer_base + U300_TIMER_APP_RGPT2); /* Set this timer to run around forever */ - writel(0xFFFFFFFFU, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2TC); + writel(0xFFFFFFFFU, u300_timer_base + U300_TIMER_APP_GPT2TC); /* Set continuous mode so it wraps around */ writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS, - U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT2M); + u300_timer_base + U300_TIMER_APP_SGPT2M); /* Disable timer interrupts */ writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2IE); + u300_timer_base + U300_TIMER_APP_GPT2IE); /* Then enable the GP2 timer to use as a free running us counter */ writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, - U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); + u300_timer_base + U300_TIMER_APP_EGPT2); /* Use general purpose timer 2 as clock source */ - if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC, + if (clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC, "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) pr_err("timer: failed to initialize U300 clock source\n"); @@ -424,3 +432,28 @@ void __init u300_timer_init(void) * used by hrtimers! */ } + + +void __init u300_timer_init() +{ + u300_timer_setup(U300_TIMER_APP_VBASE, IRQ_U300_TIMER_APP_GP1); +} + +#ifdef CONFIG_OF + +static void __init u300_timer_init_of(struct device_node *np) +{ + void __iomem *base; + struct resource irq_res; + int irq; + + base = of_iomap(np, 0); + /* Get the IRQ for the GP1 timer */ + irq = of_irq_to_resource(np, 2, &irq_res); + u300_timer_setup(base, irq); +} + +CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer", + u300_timer_init_of); + +#endif diff --git a/arch/arm/mach-u300/timer.h b/arch/arm/mach-u300/timer.h index d34287bc34f5..7766dfa6979d 100644 --- a/arch/arm/mach-u300/timer.h +++ b/arch/arm/mach-u300/timer.h @@ -1 +1,2 @@ extern void u300_timer_init(void); + -- cgit v1.2.3 From 2cd3c92738722d4b510830e948ffad9c7f60adf8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 31 May 2013 05:00:27 +0200 Subject: Revert "ARM: shmobile: Disallow PINCTRL without GPIOLIB" GPIOLIB dependency handling was added to the PINCTRL core by commit 2afe8229687ec24cbc07e78449a588bb8b68f858 Author: Haojian Zhuang Date: Thu Mar 28 07:34:19 2013 +0800 pinctrl: core: add dependence of GPIOLIB There is not need to handle that dependency at the SH Mobile level anymore. Revert commit 6722f6cb763203cab775297b6e9d00834af0d6d7 Author: Magnus Damm Date: Mon Mar 18 22:58:18 2013 +0900 ARM: shmobile: Disallow PINCTRL without GPIOLIB Modify mach-shmobile to only select PINCTRL in case of ARCH_WANT_OPTIONAL_GPIOLIB is set. This fixes a build error triggered when adding a new SoC lacking GPIO software support (ARCH_WANT_OPTIONAL_GPIOLIB=n): Signed-off-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49d993cee512..dfb4fee1f552 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -645,7 +645,7 @@ config ARCH_SHMOBILE select MULTI_IRQ_HANDLER select NEED_MACH_MEMORY_H select NO_IOPORT - select PINCTRL if ARCH_WANT_OPTIONAL_GPIOLIB + select PINCTRL select PM_GENERIC_DOMAINS if PM select SPARSE_IRQ help -- cgit v1.2.3 From 5c15bd28ff194b2d738f0fa408696f2684470a26 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Mon, 13 May 2013 21:07:20 +0400 Subject: ARM: clps711x: Remove NEED_MACH_MEMORY_H dependency This patch removes dependency of NEED_MACH_MEMORY_H for CLPS711X-target. Since some board may have memory holes, define ARCH_HAS_HOLES_MEMORYMODEL for these boards. Signed-off-by: Alexander Shiyan Signed-off-by: Olof Johansson --- arch/arm/Kconfig | 1 - arch/arm/mach-clps711x/Kconfig | 3 +- arch/arm/mach-clps711x/include/mach/memory.h | 41 ---------------------------- 3 files changed, 1 insertion(+), 44 deletions(-) delete mode 100644 arch/arm/mach-clps711x/include/mach/memory.h (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49d993cee512..c7e2a88b2691 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -370,7 +370,6 @@ config ARCH_CLPS711X select CPU_ARM720T select GENERIC_CLOCKEVENTS select MULTI_IRQ_HANDLER - select NEED_MACH_MEMORY_H select SPARSE_IRQ help Support for Cirrus Logic 711x/721x/731x based boards. diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index 2d00165e85ec..01ad4d41e728 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig @@ -22,8 +22,7 @@ config ARCH_CLEP7312 config ARCH_EDB7211 bool "EDB7211" - select ARCH_SELECT_MEMORY_MODEL - select ARCH_SPARSEMEM_ENABLE + select ARCH_HAS_HOLES_MEMORYMODEL help Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 evaluation board. diff --git a/arch/arm/mach-clps711x/include/mach/memory.h b/arch/arm/mach-clps711x/include/mach/memory.h deleted file mode 100644 index fc0e028d9405..000000000000 --- a/arch/arm/mach-clps711x/include/mach/memory.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/memory.h - * - * Copyright (C) 1999 ARM Limited - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET UL(0xc0000000) - -/* - * The PS7211 allows up to 256MB max per DRAM bank, but the EDB7211 - * uses only one of the two banks (bank #1). However, even within - * bank #1, memory is discontiguous. - * - * The EDB7211 has two 8MB DRAM areas with 8MB of empty space between - * them, so we use 24 for the node max shift to get 16MB node sizes. - */ - -#define SECTION_SIZE_BITS 24 -#define MAX_PHYSMEM_BITS 32 - -#endif - -- cgit v1.2.3 From c99f72addbf5c0ad37d5a9b26f99208464d35f5c Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Mon, 13 May 2013 21:07:32 +0400 Subject: ARM: clps711x: Add clocksource framework Signed-off-by: Alexander Shiyan Signed-off-by: Olof Johansson --- arch/arm/Kconfig | 1 + arch/arm/mach-clps711x/common.c | 48 ++++++++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 8 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c7e2a88b2691..fc93deb1baaf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -366,6 +366,7 @@ config ARCH_CLPS711X select ARCH_REQUIRE_GPIOLIB select AUTO_ZRELADDR select CLKDEV_LOOKUP + select CLKSRC_MMIO select COMMON_CLK select CPU_ARM720T select GENERIC_CLOCKEVENTS diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c index 768d41c68cea..bd658398a819 100644 --- a/arch/arm/mach-clps711x/common.c +++ b/arch/arm/mach-clps711x/common.c @@ -27,12 +27,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -251,13 +253,32 @@ asmlinkage void __exception_irq_entry clps711x_handle_irq(struct pt_regs *regs) handle_IRQ(fls16(irqstat) + 16, regs); } +static u32 notrace clps711x_sched_clock_read(void) +{ + return ~readw_relaxed(CLPS711X_VIRT_BASE + TC1D); +} + static void clps711x_clockevent_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { + disable_irq(IRQ_TC2OI); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + enable_irq(IRQ_TC2OI); + break; + case CLOCK_EVT_MODE_ONESHOT: + /* Not supported */ + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + /* Left event sources disabled, no more interrupts appear */ + break; + } } static struct clock_event_device clockevent_clps711x = { - .name = "CLPS711x Clockevents", + .name = "clps711x-clockevent", .rating = 300, .features = CLOCK_EVT_FEAT_PERIODIC, .set_mode = clps711x_clockevent_set_mode, @@ -271,8 +292,8 @@ static irqreturn_t clps711x_timer_interrupt(int irq, void *dev_id) } static struct irqaction clps711x_timer_irq = { - .name = "CLPS711x Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .name = "clps711x-timer", + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = clps711x_timer_interrupt, }; @@ -320,9 +341,9 @@ void __init clps711x_timer_init(void) else timh = 541440; } else - timh = cpu / 144; + timh = DIV_ROUND_CLOSEST(cpu, 144); - timl = timh / 256; + timl = DIV_ROUND_CLOSEST(timh, 256); /* All clocks are fixed */ add_fixed_clk(clk_pll, "pll", pll); @@ -335,13 +356,24 @@ void __init clps711x_timer_init(void) pr_info("CPU frequency set at %i Hz.\n", cpu); + /* Start Timer1 in free running mode (Low frequency) */ + tmp = clps_readl(SYSCON1) & ~(SYSCON1_TC1S | SYSCON1_TC1M); + clps_writel(tmp, SYSCON1); + + setup_sched_clock(clps711x_sched_clock_read, 16, timl); + + clocksource_mmio_init(CLPS711X_VIRT_BASE + TC1D, + "clps711x_clocksource", timl, 300, 16, + clocksource_mmio_readw_down); + + /* Set Timer2 prescaler */ clps_writew(DIV_ROUND_CLOSEST(timh, HZ), TC2D); - tmp = clps_readl(SYSCON1); - tmp |= SYSCON1_TC2S | SYSCON1_TC2M; + /* Start Timer2 in prescale mode (High frequency)*/ + tmp = clps_readl(SYSCON1) | SYSCON1_TC2M | SYSCON1_TC2S; clps_writel(tmp, SYSCON1); - clockevents_config_and_register(&clockevent_clps711x, timh, 1, 0xffff); + clockevents_config_and_register(&clockevent_clps711x, timh, 0, 0); setup_irq(IRQ_TC2OI, &clps711x_timer_irq); } -- cgit v1.2.3 From 6597619f9c85a0782d427d6723c96cf768e99086 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Mon, 13 May 2013 21:07:36 +0400 Subject: ARM: clps711x: Add support for SYSCON driver This patch adds support for SYSCON driver for CLPS711X targets. At this time there are no users for this driver, but it is will be used as start point to use in CLPS711X drivers and remove dependencies. Signed-off-by: Alexander Shiyan Signed-off-by: Olof Johansson --- arch/arm/Kconfig | 1 + arch/arm/mach-clps711x/devices.c | 20 ++++++ arch/arm/mach-clps711x/include/mach/clps711x.h | 88 +----------------------- drivers/mfd/syscon.c | 3 + include/linux/mfd/syscon/clps711x.h | 94 ++++++++++++++++++++++++++ 5 files changed, 120 insertions(+), 86 deletions(-) create mode 100644 include/linux/mfd/syscon/clps711x.h (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fc93deb1baaf..4217db7fa883 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -370,6 +370,7 @@ config ARCH_CLPS711X select COMMON_CLK select CPU_ARM720T select GENERIC_CLOCKEVENTS + select MFD_SYSCON select MULTI_IRQ_HANDLER select SPARSE_IRQ help diff --git a/arch/arm/mach-clps711x/devices.c b/arch/arm/mach-clps711x/devices.c index 21161ed4c0c4..856b81cf2f8a 100644 --- a/arch/arm/mach-clps711x/devices.c +++ b/arch/arm/mach-clps711x/devices.c @@ -10,6 +10,7 @@ */ #include +#include #include @@ -42,7 +43,26 @@ static void __init clps711x_add_gpio(void) } } +const struct resource clps711x_syscon_res[] __initconst = { + /* SYSCON1, SYSFLG1 */ + DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON1, SZ_128), + /* SYSCON2, SYSFLG2 */ + DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON2, SZ_128), + /* SYSCON3 */ + DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON3, SZ_64), +}; + +static void __init clps711x_add_syscon(void) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(clps711x_syscon_res); i++) + platform_device_register_simple("clps711x-syscon", i + 1, + &clps711x_syscon_res[i], 1); +} + void __init clps711x_devices_init(void) { clps711x_add_gpio(); + clps711x_add_syscon(); } diff --git a/arch/arm/mach-clps711x/include/mach/clps711x.h b/arch/arm/mach-clps711x/include/mach/clps711x.h index 01d1b9559710..0286f4bf9945 100644 --- a/arch/arm/mach-clps711x/include/mach/clps711x.h +++ b/arch/arm/mach-clps711x/include/mach/clps711x.h @@ -21,6 +21,8 @@ #ifndef __MACH_CLPS711X_H #define __MACH_CLPS711X_H +#include + #define CLPS711X_PHYS_BASE (0x80000000) #define PADR (0x0000) @@ -96,83 +98,9 @@ #define RANDID2 (0x2708) #define RANDID3 (0x270c) -/* common bits: SYSCON1 / SYSCON2 */ -#define SYSCON_UARTEN (1 << 8) - -#define SYSCON1_KBDSCAN(x) ((x) & 15) -#define SYSCON1_KBDSCANMASK (15) -#define SYSCON1_TC1M (1 << 4) -#define SYSCON1_TC1S (1 << 5) -#define SYSCON1_TC2M (1 << 6) -#define SYSCON1_TC2S (1 << 7) -#define SYSCON1_UART1EN SYSCON_UARTEN -#define SYSCON1_BZTOG (1 << 9) -#define SYSCON1_BZMOD (1 << 10) -#define SYSCON1_DBGEN (1 << 11) -#define SYSCON1_LCDEN (1 << 12) -#define SYSCON1_CDENTX (1 << 13) -#define SYSCON1_CDENRX (1 << 14) -#define SYSCON1_SIREN (1 << 15) -#define SYSCON1_ADCKSEL(x) (((x) & 3) << 16) -#define SYSCON1_ADCKSEL_MASK (3 << 16) -#define SYSCON1_EXCKEN (1 << 18) -#define SYSCON1_WAKEDIS (1 << 19) -#define SYSCON1_IRTXM (1 << 20) - -/* common bits: SYSFLG1 / SYSFLG2 */ -#define SYSFLG_UBUSY (1 << 11) -#define SYSFLG_URXFE (1 << 22) -#define SYSFLG_UTXFF (1 << 23) - -#define SYSFLG1_MCDR (1 << 0) -#define SYSFLG1_DCDET (1 << 1) -#define SYSFLG1_WUDR (1 << 2) -#define SYSFLG1_WUON (1 << 3) -#define SYSFLG1_CTS (1 << 8) -#define SYSFLG1_DSR (1 << 9) -#define SYSFLG1_DCD (1 << 10) -#define SYSFLG1_UBUSY SYSFLG_UBUSY -#define SYSFLG1_NBFLG (1 << 12) -#define SYSFLG1_RSTFLG (1 << 13) -#define SYSFLG1_PFFLG (1 << 14) -#define SYSFLG1_CLDFLG (1 << 15) -#define SYSFLG1_URXFE SYSFLG_URXFE -#define SYSFLG1_UTXFF SYSFLG_UTXFF -#define SYSFLG1_CRXFE (1 << 24) -#define SYSFLG1_CTXFF (1 << 25) -#define SYSFLG1_SSIBUSY (1 << 26) -#define SYSFLG1_ID (1 << 29) -#define SYSFLG1_VERID(x) (((x) >> 30) & 3) -#define SYSFLG1_VERID_MASK (3 << 30) - -#define SYSFLG2_SSRXOF (1 << 0) -#define SYSFLG2_RESVAL (1 << 1) -#define SYSFLG2_RESFRM (1 << 2) -#define SYSFLG2_SS2RXFE (1 << 3) -#define SYSFLG2_SS2TXFF (1 << 4) -#define SYSFLG2_SS2TXUF (1 << 5) -#define SYSFLG2_CKMODE (1 << 6) -#define SYSFLG2_UBUSY SYSFLG_UBUSY -#define SYSFLG2_URXFE SYSFLG_URXFE -#define SYSFLG2_UTXFF SYSFLG_UTXFF - #define LCDCON_GSEN (1 << 30) #define LCDCON_GSMD (1 << 31) -#define SYSCON2_SERSEL (1 << 0) -#define SYSCON2_KBD6 (1 << 1) -#define SYSCON2_DRAMZ (1 << 2) -#define SYSCON2_KBWEN (1 << 3) -#define SYSCON2_SS2TXEN (1 << 4) -#define SYSCON2_PCCARD1 (1 << 5) -#define SYSCON2_PCCARD2 (1 << 6) -#define SYSCON2_SS2RXEN (1 << 7) -#define SYSCON2_UART2EN SYSCON_UARTEN -#define SYSCON2_SS2MAEN (1 << 9) -#define SYSCON2_OSTB (1 << 12) -#define SYSCON2_CLKENSL (1 << 13) -#define SYSCON2_BUZFREQ (1 << 14) - /* common bits: UARTDR1 / UARTDR2 */ #define UARTDR_FRMERR (1 << 8) #define UARTDR_PARERR (1 << 9) @@ -228,18 +156,6 @@ #define DAI64FS_MCLK256EN (1 << 3) #define DAI64FS_LOOPBACK (1 << 5) -#define SYSCON3_ADCCON (1 << 0) -#define SYSCON3_CLKCTL0 (1 << 1) -#define SYSCON3_CLKCTL1 (1 << 2) -#define SYSCON3_DAISEL (1 << 3) -#define SYSCON3_ADCCKNSEN (1 << 4) -#define SYSCON3_VERSN(x) (((x) >> 5) & 7) -#define SYSCON3_VERSN_MASK (7 << 5) -#define SYSCON3_FASTWAKE (1 << 8) -#define SYSCON3_DAIEN (1 << 9) -#define SYSCON3_128FS SYSCON3_DAIEN -#define SYSCON3_ENPD67 (1 << 10) - #define SDCONF_ACTIVE (1 << 10) #define SDCONF_CLKCTL (1 << 9) #define SDCONF_WIDTH_4 (0 << 7) diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 962a6e17a01a..1a31512369f9 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -159,6 +159,9 @@ static int syscon_probe(struct platform_device *pdev) static const struct platform_device_id syscon_ids[] = { { "syscon", }, +#ifdef CONFIG_ARCH_CLPS711X + { "clps711x-syscon", }, +#endif { } }; diff --git a/include/linux/mfd/syscon/clps711x.h b/include/linux/mfd/syscon/clps711x.h new file mode 100644 index 000000000000..26355abae515 --- /dev/null +++ b/include/linux/mfd/syscon/clps711x.h @@ -0,0 +1,94 @@ +/* + * CLPS711X system register bits definitions + * + * Copyright (C) 2013 Alexander Shiyan + * + * 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 _LINUX_MFD_SYSCON_CLPS711X_H_ +#define _LINUX_MFD_SYSCON_CLPS711X_H_ + +#define SYSCON_OFFSET (0x00) +#define SYSFLG_OFFSET (0x40) + +#define SYSCON1_KBDSCAN(x) ((x) & 15) +#define SYSCON1_KBDSCAN_MASK (15) +#define SYSCON1_TC1M (1 << 4) +#define SYSCON1_TC1S (1 << 5) +#define SYSCON1_TC2M (1 << 6) +#define SYSCON1_TC2S (1 << 7) +#define SYSCON1_BZTOG (1 << 9) +#define SYSCON1_BZMOD (1 << 10) +#define SYSCON1_DBGEN (1 << 11) +#define SYSCON1_LCDEN (1 << 12) +#define SYSCON1_CDENTX (1 << 13) +#define SYSCON1_CDENRX (1 << 14) +#define SYSCON1_SIREN (1 << 15) +#define SYSCON1_ADCKSEL(x) (((x) & 3) << 16) +#define SYSCON1_ADCKSEL_MASK (3 << 16) +#define SYSCON1_EXCKEN (1 << 18) +#define SYSCON1_WAKEDIS (1 << 19) +#define SYSCON1_IRTXM (1 << 20) + +#define SYSCON2_SERSEL (1 << 0) +#define SYSCON2_KBD6 (1 << 1) +#define SYSCON2_DRAMZ (1 << 2) +#define SYSCON2_KBWEN (1 << 3) +#define SYSCON2_SS2TXEN (1 << 4) +#define SYSCON2_PCCARD1 (1 << 5) +#define SYSCON2_PCCARD2 (1 << 6) +#define SYSCON2_SS2RXEN (1 << 7) +#define SYSCON2_SS2MAEN (1 << 9) +#define SYSCON2_OSTB (1 << 12) +#define SYSCON2_CLKENSL (1 << 13) +#define SYSCON2_BUZFREQ (1 << 14) + +#define SYSCON3_ADCCON (1 << 0) +#define SYSCON3_CLKCTL0 (1 << 1) +#define SYSCON3_CLKCTL1 (1 << 2) +#define SYSCON3_DAISEL (1 << 3) +#define SYSCON3_ADCCKNSEN (1 << 4) +#define SYSCON3_VERSN(x) (((x) >> 5) & 7) +#define SYSCON3_VERSN_MASK (7 << 5) +#define SYSCON3_FASTWAKE (1 << 8) +#define SYSCON3_DAIEN (1 << 9) +#define SYSCON3_128FS SYSCON3_DAIEN +#define SYSCON3_ENPD67 (1 << 10) + +#define SYSCON_UARTEN (1 << 8) + +#define SYSFLG1_MCDR (1 << 0) +#define SYSFLG1_DCDET (1 << 1) +#define SYSFLG1_WUDR (1 << 2) +#define SYSFLG1_WUON (1 << 3) +#define SYSFLG1_CTS (1 << 8) +#define SYSFLG1_DSR (1 << 9) +#define SYSFLG1_DCD (1 << 10) +#define SYSFLG1_NBFLG (1 << 12) +#define SYSFLG1_RSTFLG (1 << 13) +#define SYSFLG1_PFFLG (1 << 14) +#define SYSFLG1_CLDFLG (1 << 15) +#define SYSFLG1_CRXFE (1 << 24) +#define SYSFLG1_CTXFF (1 << 25) +#define SYSFLG1_SSIBUSY (1 << 26) +#define SYSFLG1_ID (1 << 29) +#define SYSFLG1_VERID(x) (((x) >> 30) & 3) +#define SYSFLG1_VERID_MASK (3 << 30) + +#define SYSFLG2_SSRXOF (1 << 0) +#define SYSFLG2_RESVAL (1 << 1) +#define SYSFLG2_RESFRM (1 << 2) +#define SYSFLG2_SS2RXFE (1 << 3) +#define SYSFLG2_SS2TXFF (1 << 4) +#define SYSFLG2_SS2TXUF (1 << 5) +#define SYSFLG2_CKMODE (1 << 6) + +#define SYSFLG_UBUSY (1 << 11) +#define SYSFLG_URXFE (1 << 22) +#define SYSFLG_UTXFF (1 << 23) + +#endif -- cgit v1.2.3 From f8b1ac01458a39454d04172df4c070134902f837 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Sat, 15 Jun 2013 09:01:11 +0900 Subject: ARM: EXYNOS: Make ARCH_EXYNOS select USE_OF Since EXYNOS is now DT-only, it always requires USE_OF option to be selected. This patch moves USE_OF selection from entries of DT board files to ARCH_EXYNOS. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Acked-by: Arnd Bergmann Signed-off-by: Kukjin Kim --- arch/arm/Kconfig | 1 + arch/arm/mach-exynos/Kconfig | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49d993cee512..fc20cfc471d0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -796,6 +796,7 @@ config ARCH_EXYNOS select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_GPIO_H select NEED_MACH_MEMORY_H + select USE_OF help Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 41fd73f4c29e..2bc2696153f9 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -98,7 +98,6 @@ config MACH_EXYNOS4_DT select PINCTRL select PINCTRL_EXYNOS select S5P_DEV_MFC - select USE_OF help Machine support for Samsung Exynos4 machine with device tree enabled. Select this if a fdt blob is available for the Exynos4 SoC based board. @@ -111,7 +110,6 @@ config MACH_EXYNOS5_DT depends on ARCH_EXYNOS5 select ARM_AMBA select CLKSRC_OF - select USE_OF help Machine support for Samsung EXYNOS5 machine with device tree enabled. Select this if a fdt blob is available for the EXYNOS5 SoC based board. -- cgit v1.2.3 From cd8dc7ae41f2b2e6392e32c8471589a8ca5fa705 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Sat, 15 Jun 2013 09:01:49 +0900 Subject: ARM: SAMSUNG: Introduce SAMSUNG_ATAGS Kconfig entry This patch adds a Kconfig entry that enables compilation of legacy support code required for Samsung platforms that require ATAGS based boot. This allows to bypass compilation of this code when platforms without ATAGS support are selected. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Acked-by: Arnd Bergmann Signed-off-by: Kukjin Kim --- arch/arm/Kconfig | 6 ++++++ arch/arm/plat-samsung/Kconfig | 26 +++++++++++++++++++++----- arch/arm/plat-samsung/Makefile | 6 +++--- 3 files changed, 30 insertions(+), 8 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fc20cfc471d0..aa8dcfc27903 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -702,6 +702,7 @@ config ARCH_S3C24XX select MULTI_IRQ_HANDLER select NEED_MACH_GPIO_H select NEED_MACH_IO_H + select SAMSUNG_ATAGS help Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443 and S3C2450 SoCs based systems, such as the Simtec Electronics BAST @@ -726,6 +727,7 @@ config ARCH_S3C64XX select PLAT_SAMSUNG select S3C_DEV_NAND select S3C_GPIO_TRACK + select SAMSUNG_ATAGS select SAMSUNG_CLKSRC select SAMSUNG_GPIOLIB_4BIT select SAMSUNG_IRQ_VIC_TIMER @@ -744,6 +746,7 @@ config ARCH_S5P64X0 select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_GPIO_H + select SAMSUNG_ATAGS help Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440, SMDK6450. @@ -760,6 +763,7 @@ config ARCH_S5PC100 select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_GPIO_H + select SAMSUNG_ATAGS help Samsung S5PC100 series based systems @@ -778,6 +782,7 @@ config ARCH_S5PV210 select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_GPIO_H select NEED_MACH_MEMORY_H + select SAMSUNG_ATAGS help Samsung S5PV210/S5PC110 series based systems @@ -796,6 +801,7 @@ config ARCH_EXYNOS select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_GPIO_H select NEED_MACH_MEMORY_H + select SAMSUNG_ATAGS select USE_OF help Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5) diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index f8ed2de0a678..c0f0542e6dfc 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -60,6 +60,20 @@ config S3C_LOWLEVEL_UART_PORT this configuration should be between zero and two. The port must have been initialised by the boot-loader before use. +config SAMSUNG_ATAGS + def_bool n + depends on !ARCH_MULTIPLATFORM + depends on ATAGS + help + This option enables ATAGS based boot support code for + Samsung platforms, including static platform devices, legacy + clock, timer and interrupt initialization, etc. + + Platforms that support only DT based boot need not to select + this option. + +if SAMSUNG_ATAGS + # timer options config SAMSUNG_HRT @@ -367,11 +381,6 @@ config S5P_DEV_JPEG help Compile in platform device definitions for JPEG codec -config S5P_DEV_MFC - bool - help - Compile in setup memory (init) code for MFC - config S5P_DEV_ONENAND bool help @@ -412,6 +421,8 @@ config S3C_DMA help Internal configuration for S3C DMA core +endif + config SAMSUNG_DMADEV bool select ARM_AMBA @@ -421,6 +432,11 @@ config SAMSUNG_DMADEV help Use DMA device engine for PL330 DMAC. +config S5P_DEV_MFC + bool + help + Compile in setup memory (init) code for MFC + comment "Power management" config SAMSUNG_PM_DEBUG diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index a23c460299a1..b549ea9cfe09 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -31,10 +31,10 @@ obj-$(CONFIG_S3C_ADC) += adc.o # devices -obj-y += platformdata.o +obj-$(CONFIG_SAMSUNG_ATAGS) += platformdata.o -obj-y += devs.o -obj-y += dev-uart.o +obj-$(CONFIG_SAMSUNG_ATAGS) += devs.o +obj-$(CONFIG_SAMSUNG_ATAGS) += dev-uart.o obj-$(CONFIG_S5P_DEV_MFC) += s5p-dev-mfc.o obj-$(CONFIG_S5P_DEV_UART) += s5p-dev-uart.o -- cgit v1.2.3 From 69469995980edab1a99f50a51e5e9525b4e11148 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 Jun 2013 18:46:47 +0900 Subject: ARM: shmobile: Enable ARM_PATCH_PHYS_VIRT Adjust mach-shmobile to add a select for CONFIG_ARM_PATCH_PHYS_VIRT and at the same time remove NEED_MACH_MEMORY_H. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dfb4fee1f552..f06e65bbef79 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -634,6 +634,7 @@ config ARCH_MSM config ARCH_SHMOBILE bool "Renesas SH-Mobile / R-Mobile" + select ARM_PATCH_PHYS_VIRT select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU if SMP @@ -643,7 +644,6 @@ config ARCH_SHMOBILE select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select MULTI_IRQ_HANDLER - select NEED_MACH_MEMORY_H select NO_IOPORT select PINCTRL select PM_GENERIC_DOMAINS if PM -- cgit v1.2.3 From 75a7f3f18e0deee2023351789cc3c393f07220c7 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 22 Apr 2013 11:29:30 +0200 Subject: ARM: u300: delete all static board data We have now transferred all the U300 peripherals to the device tree, so we just select USE_OF, and delete all static board data, then require that this platform shall be booted using the device tree and nothing else. This gets rid of the MMCI (PL180), PL022, and serial PL011 platform data entries and more. Signed-off-by: Linus Walleij --- arch/arm/Kconfig | 1 + arch/arm/mach-u300/Makefile | 2 - arch/arm/mach-u300/core.c | 548 +---------------------------------------- arch/arm/mach-u300/i2c.c | 285 --------------------- arch/arm/mach-u300/i2c.h | 23 -- arch/arm/mach-u300/regulator.c | 12 +- arch/arm/mach-u300/spi.c | 102 -------- arch/arm/mach-u300/spi.h | 26 -- arch/arm/mach-u300/timer.c | 38 +-- arch/arm/mach-u300/timer.h | 2 - arch/arm/mach-u300/u300-gpio.h | 70 ------ 11 files changed, 22 insertions(+), 1087 deletions(-) delete mode 100644 arch/arm/mach-u300/i2c.c delete mode 100644 arch/arm/mach-u300/i2c.h delete mode 100644 arch/arm/mach-u300/spi.c delete mode 100644 arch/arm/mach-u300/spi.h delete mode 100644 arch/arm/mach-u300/timer.h delete mode 100644 arch/arm/mach-u300/u300-gpio.h (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fbad3337a838..26896433ae78 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -827,6 +827,7 @@ config ARCH_U300 select GENERIC_CLOCKEVENTS select HAVE_TCM select SPARSE_IRQ + select USE_OF help Support for ST-Ericsson U300 series mobile platforms. diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index 5a86c58da396..0f362b64fb87 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile @@ -7,7 +7,5 @@ obj-m := obj-n := obj- := -obj-$(CONFIG_SPI_PL022) += spi.o obj-$(CONFIG_MACH_U300_SPIDUMMY) += dummyspichip.o -obj-$(CONFIG_I2C_STU300) += i2c.o obj-$(CONFIG_REGULATOR_AB3100) += regulator.o diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 8f9e77aea76a..13d48125b89b 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -9,50 +9,20 @@ * Author: Linus Walleij */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include #include #include -#include -#include #include #include #include +#include -#include -#include -#include #include -#include #include -#include +#include #include -#include - -#include "timer.h" -#include "spi.h" -#include "i2c.h" -#include "u300-gpio.h" /* * Static I/O mappings that are needed for booting the U300 platforms. The @@ -86,287 +56,6 @@ static void __init u300_map_io(void) iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc)); } -/* - * Declaration of devices found on the U300 board and - * their respective memory locations. - */ - -static struct amba_pl011_data uart0_plat_data = { -#ifdef CONFIG_COH901318 - .dma_filter = coh901318_filter_id, - .dma_rx_param = (void *) U300_DMA_UART0_RX, - .dma_tx_param = (void *) U300_DMA_UART0_TX, -#endif -}; - -/* Slow device at 0x3000 offset */ -static AMBA_APB_DEVICE(uart0, "uart0", 0, U300_UART0_BASE, - { IRQ_U300_UART0 }, &uart0_plat_data); - -/* The U335 have an additional UART1 on the APP CPU */ -static struct amba_pl011_data uart1_plat_data = { -#ifdef CONFIG_COH901318 - .dma_filter = coh901318_filter_id, - .dma_rx_param = (void *) U300_DMA_UART1_RX, - .dma_tx_param = (void *) U300_DMA_UART1_TX, -#endif -}; - -/* Fast device at 0x7000 offset */ -static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE, - { IRQ_U300_UART1 }, &uart1_plat_data); - -/* AHB device at 0x4000 offset */ -static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL); - -/* Fast device at 0x6000 offset */ -static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE, - { IRQ_U300_SPI }, NULL); - -/* Fast device at 0x1000 offset */ -#define U300_MMCSD_IRQS { IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 } - -static struct mmci_platform_data mmcsd_platform_data = { - /* - * Do not set ocr_mask or voltage translation function, - * we have a regulator we can control instead. - */ - .f_max = 24000000, - .gpio_wp = -1, - .gpio_cd = U300_GPIO_PIN_MMC_CD, - .cd_invert = true, - .capabilities = MMC_CAP_MMC_HIGHSPEED | - MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, -#ifdef CONFIG_COH901318 - .dma_filter = coh901318_filter_id, - .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX, - /* Don't specify a TX channel, this RX channel is bidirectional */ -#endif -}; - -static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE, - U300_MMCSD_IRQS, &mmcsd_platform_data); - -/* - * The order of device declaration may be important, since some devices - * have dependencies on other devices being initialized first. - */ -static struct amba_device *amba_devs[] __initdata = { - &uart0_device, - &uart1_device, - &pl022_device, - &pl172_device, - &mmcsd_device, -}; - -/* Here follows a list of all hw resources that the platform devices - * allocate. Note, clock dependencies are not included - */ - -static struct resource gpio_resources[] = { - { - .start = U300_GPIO_BASE, - .end = (U300_GPIO_BASE + SZ_4K - 1), - .flags = IORESOURCE_MEM, - }, - { - .name = "gpio0", - .start = IRQ_U300_GPIO_PORT0, - .end = IRQ_U300_GPIO_PORT0, - .flags = IORESOURCE_IRQ, - }, - { - .name = "gpio1", - .start = IRQ_U300_GPIO_PORT1, - .end = IRQ_U300_GPIO_PORT1, - .flags = IORESOURCE_IRQ, - }, - { - .name = "gpio2", - .start = IRQ_U300_GPIO_PORT2, - .end = IRQ_U300_GPIO_PORT2, - .flags = IORESOURCE_IRQ, - }, - { - .name = "gpio3", - .start = IRQ_U300_GPIO_PORT3, - .end = IRQ_U300_GPIO_PORT3, - .flags = IORESOURCE_IRQ, - }, - { - .name = "gpio4", - .start = IRQ_U300_GPIO_PORT4, - .end = IRQ_U300_GPIO_PORT4, - .flags = IORESOURCE_IRQ, - }, - { - .name = "gpio5", - .start = IRQ_U300_GPIO_PORT5, - .end = IRQ_U300_GPIO_PORT5, - .flags = IORESOURCE_IRQ, - }, - { - .name = "gpio6", - .start = IRQ_U300_GPIO_PORT6, - .end = IRQ_U300_GPIO_PORT6, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource keypad_resources[] = { - { - .start = U300_KEYPAD_BASE, - .end = U300_KEYPAD_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "coh901461-press", - .start = IRQ_U300_KEYPAD_KEYBF, - .end = IRQ_U300_KEYPAD_KEYBF, - .flags = IORESOURCE_IRQ, - }, - { - .name = "coh901461-release", - .start = IRQ_U300_KEYPAD_KEYBR, - .end = IRQ_U300_KEYPAD_KEYBR, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource rtc_resources[] = { - { - .start = U300_RTC_BASE, - .end = U300_RTC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_U300_RTC, - .end = IRQ_U300_RTC, - .flags = IORESOURCE_IRQ, - }, -}; - -/* - * Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2) - * but these are not yet used by the driver. - */ -static struct resource fsmc_resources[] = { - { - .name = "nand_addr", - .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE, - .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "nand_cmd", - .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE, - .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "nand_data", - .start = U300_NAND_CS0_PHYS_BASE, - .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "fsmc_regs", - .start = U300_NAND_IF_PHYS_BASE, - .end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource i2c0_resources[] = { - { - .start = U300_I2C0_BASE, - .end = U300_I2C0_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_U300_I2C0, - .end = IRQ_U300_I2C0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource i2c1_resources[] = { - { - .start = U300_I2C1_BASE, - .end = U300_I2C1_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_U300_I2C1, - .end = IRQ_U300_I2C1, - .flags = IORESOURCE_IRQ, - }, - -}; - -static struct resource wdog_resources[] = { - { - .start = U300_WDOG_BASE, - .end = U300_WDOG_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_U300_WDOG, - .end = IRQ_U300_WDOG, - .flags = IORESOURCE_IRQ, - } -}; - -static struct resource dma_resource[] = { - { - .start = U300_DMAC_BASE, - .end = U300_DMAC_BASE + PAGE_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_U300_DMA, - .end = IRQ_U300_DMA, - .flags = IORESOURCE_IRQ, - } -}; - - -static struct resource pinctrl_resources[] = { - { - .start = U300_SYSCON_BASE, - .end = U300_SYSCON_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device wdog_device = { - .name = "coh901327_wdog", - .id = -1, - .num_resources = ARRAY_SIZE(wdog_resources), - .resource = wdog_resources, -}; - -static struct platform_device i2c0_device = { - .name = "stu300", - .id = 0, - .num_resources = ARRAY_SIZE(i2c0_resources), - .resource = i2c0_resources, -}; - -static struct platform_device i2c1_device = { - .name = "stu300", - .id = 1, - .num_resources = ARRAY_SIZE(i2c1_resources), - .resource = i2c1_resources, -}; - -static struct platform_device pinctrl_device = { - .name = "pinctrl-u300", - .id = -1, - .num_resources = ARRAY_SIZE(pinctrl_resources), - .resource = pinctrl_resources, -}; - /* * The different variants have a few different versions of the * GPIO block, with different number of ports. @@ -376,75 +65,6 @@ static struct u300_gpio_platform u300_gpio_plat = { .gpio_base = 0, }; -static struct platform_device gpio_device = { - .name = "u300-gpio", - .id = -1, - .num_resources = ARRAY_SIZE(gpio_resources), - .resource = gpio_resources, - .dev = { - .platform_data = &u300_gpio_plat, - }, -}; - -static struct platform_device keypad_device = { - .name = "keypad", - .id = -1, - .num_resources = ARRAY_SIZE(keypad_resources), - .resource = keypad_resources, -}; - -static struct platform_device rtc_device = { - .name = "rtc-coh901331", - .id = -1, - .num_resources = ARRAY_SIZE(rtc_resources), - .resource = rtc_resources, -}; - -static struct mtd_partition u300_partitions[] = { - { - .name = "bootrecords", - .offset = 0, - .size = SZ_128K, - }, - { - .name = "free", - .offset = SZ_128K, - .size = 8064 * SZ_1K, - }, - { - .name = "platform", - .offset = 8192 * SZ_1K, - .size = 253952 * SZ_1K, - }, -}; - -static struct fsmc_nand_platform_data nand_platform_data = { - .partitions = u300_partitions, - .nr_partitions = ARRAY_SIZE(u300_partitions), - .options = NAND_SKIP_BBTSCAN, - .width = FSMC_NAND_BW8, -}; - -static struct platform_device nand_device = { - .name = "fsmc-nand", - .id = -1, - .resource = fsmc_resources, - .num_resources = ARRAY_SIZE(fsmc_resources), - .dev = { - .platform_data = &nand_platform_data, - }, -}; - -static struct platform_device dma_device = { - .name = "coh901318", - .id = -1, - .resource = dma_resource, - .num_resources = ARRAY_SIZE(dma_resource), - .dev = { - .coherent_dma_mask = ~0, - }, -}; - static unsigned long pin_pullup_conf[] = { PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1), }; @@ -471,61 +91,6 @@ static struct pinctrl_map __initdata u300_pinmux_map[] = { pin_highz_conf), }; -/* - * Notice that AMBA devices are initialized before platform devices. - * - */ -static struct platform_device *platform_devs[] __initdata = { - &dma_device, - &i2c0_device, - &i2c1_device, - &keypad_device, - &rtc_device, - &pinctrl_device, - &gpio_device, - &nand_device, - &wdog_device, -}; - -/* - * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected - * together so some interrupts are connected to the first one and some - * to the second one. - */ -static void __init u300_init_irq(void) -{ - u32 mask[2] = {0, 0}; - struct clk *clk; - int i; - - /* initialize clocking early, we want to clock the INTCON */ - u300_clk_init(U300_SYSCON_VBASE); - - /* Bootstrap EMIF and SEMI clocks */ - clk = clk_get_sys("pl172", NULL); - BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); - clk = clk_get_sys("semi", NULL); - BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); - - /* Clock the interrupt controller */ - clk = clk_get_sys("intcon", NULL); - BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); - - for (i = 0; i < U300_VIC_IRQS_END; i++) - set_bit(i, (unsigned long *) &mask[0]); - vic_init((void __iomem *) U300_INTCON0_VBASE, IRQ_U300_INTCON0_START, - mask[0], mask[0]); - vic_init((void __iomem *) U300_INTCON1_VBASE, IRQ_U300_INTCON1_START, - mask[1], mask[1]); -} - - -/* - * U300 platforms peripheral handling - */ struct db_chip { u16 chipid; const char *name; @@ -604,74 +169,6 @@ static void __init u300_init_check_chip(void) } } -/* - * Some devices and their resources require reserved physical memory from - * the end of the available RAM. This function traverses the list of devices - * and assigns actual addresses to these. - */ -static void __init u300_assign_physmem(void) -{ - unsigned long curr_start = __pa(high_memory); - int i, j; - - for (i = 0; i < ARRAY_SIZE(platform_devs); i++) { - for (j = 0; j < platform_devs[i]->num_resources; j++) { - struct resource *const res = - &platform_devs[i]->resource[j]; - - if (IORESOURCE_MEM == res->flags && - 0 == res->start) { - res->start = curr_start; - res->end += curr_start; - curr_start += resource_size(res); - - printk(KERN_INFO "core.c: Mapping RAM " \ - "%#x-%#x to device %s:%s\n", - res->start, res->end, - platform_devs[i]->name, res->name); - } - } - } -} - -static void __init u300_init_machine(void) -{ - int i; - u16 val; - - /* Check what platform we run and print some status information */ - u300_init_check_chip(); - - /* Initialize SPI device with some board specifics */ - u300_spi_init(&pl022_device); - - /* Register the AMBA devices in the AMBA bus abstraction layer */ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - } - - u300_assign_physmem(); - - /* Initialize pinmuxing */ - pinctrl_register_mappings(u300_pinmux_map, - ARRAY_SIZE(u300_pinmux_map)); - - /* Register subdevices on the I2C buses */ - u300_i2c_register_board_devices(); - - /* Register the platform devices */ - platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - - /* Register subdevices on the SPI bus */ - u300_spi_register_board_devices(); - - /* Enable SEMI self refresh */ - val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) | - U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE; - writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR); -} - /* Forward declare this function from the watchdog */ void coh901327_watchdog_reset(void); @@ -692,35 +189,6 @@ static void u300_restart(char mode, const char *cmd) while (1); } -MACHINE_START(U300, "Ericsson AB U335 S335/B335 Prototype Board") - /* Maintainer: Linus Walleij */ - .atag_offset = 0x100, - .map_io = u300_map_io, - .nr_irqs = 0, - .init_irq = u300_init_irq, - .init_time = u300_timer_init, - .init_machine = u300_init_machine, - .restart = u300_restart, -MACHINE_END - -#ifdef CONFIG_OF - -static struct pl022_ssp_controller spi_plat_data = { - /* If you have several SPI buses this varies, we have only bus 0 */ - .bus_id = 0, - /* - * On the APP CPU GPIO 4, 5 and 6 are connected as generic - * chip selects for SPI. (Same on U330, U335 and U365.) - * TODO: make sure the GPIO driver can select these properly - * and do padmuxing accordingly too. - */ - .num_chipselect = 3, - .enable_dma = 1, - .dma_filter = coh901318_filter_id, - .dma_rx_param = (void *) U300_DMA_SPI_RX, - .dma_tx_param = (void *) U300_DMA_SPI_TX, -}; - /* These are mostly to get the right device names for the clock lookups */ static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("stericsson,pinctrl-u300", U300_SYSCON_BASE, @@ -736,17 +204,17 @@ static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("stericsson,fsmc-nand", U300_NAND_IF_PHYS_BASE, "fsmc-nand", NULL), OF_DEV_AUXDATA("arm,primecell", U300_UART0_BASE, - "uart0", &uart0_plat_data), + "uart0", NULL), OF_DEV_AUXDATA("arm,primecell", U300_UART1_BASE, - "uart1", &uart1_plat_data), + "uart1", NULL), OF_DEV_AUXDATA("arm,primecell", U300_SPI_BASE, - "pl022", &spi_plat_data), + "pl022", NULL), OF_DEV_AUXDATA("st,ddci2c", U300_I2C0_BASE, "stu300.0", NULL), OF_DEV_AUXDATA("st,ddci2c", U300_I2C1_BASE, "stu300.1", NULL), OF_DEV_AUXDATA("arm,primecell", U300_MMCSD_BASE, - "mmci", &mmcsd_platform_data), + "mmci", NULL), { /* sentinel */ }, }; @@ -780,8 +248,6 @@ static void __init u300_init_machine_dt(void) /* Check what platform we run and print some status information */ u300_init_check_chip(); - u300_assign_physmem(); - /* Initialize pinmuxing */ pinctrl_register_mappings(u300_pinmux_map, ARRAY_SIZE(u300_pinmux_map)); @@ -808,5 +274,3 @@ DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)") .restart = u300_restart, .dt_compat = u300_board_compat, MACHINE_END - -#endif /* CONFIG_OF */ diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c deleted file mode 100644 index 96800aa1316d..000000000000 --- a/arch/arm/mach-u300/i2c.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * arch/arm/mach-u300/i2c.c - * - * Copyright (C) 2009-2012 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * - * Register board i2c devices - * Author: Linus Walleij - */ -#include -#include -#include -#include -#include -#include - -/* - * Initial settings of ab3100 registers. - * Common for below LDO regulator settings are that - * bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0). - * Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode. - */ - -/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */ -#define LDO_A_SETTING 0x16 -/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */ -#define LDO_C_SETTING 0x10 -/* LDO_D 0x10: 2.65V, ON, sleep mode not used */ -#define LDO_D_SETTING 0x10 -/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */ -#define LDO_E_SETTING 0x10 -/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */ -#define LDO_E_SLEEP_SETTING 0x00 -/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */ -#define LDO_F_SETTING 0xD0 -/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */ -#define LDO_G_SETTING 0x00 -/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */ -#define LDO_H_SETTING 0x18 -/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */ -#define LDO_K_SETTING 0x00 -/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */ -#define LDO_EXT_SETTING 0x00 -/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */ -#define BUCK_SETTING 0x7D -/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */ -#define BUCK_SLEEP_SETTING 0xAC - -#ifdef CONFIG_AB3100_CORE -static struct regulator_consumer_supply supply_ldo_c[] = { - { - .dev_name = "ab3100-codec", - .supply = "vaudio", /* Powers the codec */ - }, -}; - -/* - * This one needs to be a supply so we can turn it off - * in order to shut down the system. - */ -static struct regulator_consumer_supply supply_ldo_d[] = { - { - .supply = "vana15", /* Powers the SoC (CPU etc) */ - }, -}; - -static struct regulator_consumer_supply supply_ldo_g[] = { - { - .dev_name = "mmci", - .supply = "vmmc", /* Powers MMC/SD card */ - }, -}; - -static struct regulator_consumer_supply supply_ldo_h[] = { - { - .dev_name = "xgam_pdi", - .supply = "vdisp", /* Powers camera, display etc */ - }, -}; - -static struct regulator_consumer_supply supply_ldo_k[] = { - { - .dev_name = "irda", - .supply = "vir", /* Power IrDA */ - }, -}; - -/* - * This is a placeholder for whoever wish to use the - * external power. - */ -static struct regulator_consumer_supply supply_ldo_ext[] = { - { - .supply = "vext", /* External power */ - }, -}; - -/* Preset (hardware defined) voltages for these regulators */ -#define LDO_A_VOLTAGE 2750000 -#define LDO_C_VOLTAGE 2650000 -#define LDO_D_VOLTAGE 2650000 - -static struct ab3100_platform_data ab3100_plf_data = { - .reg_constraints = { - /* LDO A routing and constraints */ - { - .constraints = { - .name = "vrad", - .min_uV = LDO_A_VOLTAGE, - .max_uV = LDO_A_VOLTAGE, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .always_on = 1, - .boot_on = 1, - }, - }, - /* LDO C routing and constraints */ - { - .constraints = { - .min_uV = LDO_C_VOLTAGE, - .max_uV = LDO_C_VOLTAGE, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - }, - .num_consumer_supplies = ARRAY_SIZE(supply_ldo_c), - .consumer_supplies = supply_ldo_c, - }, - /* LDO D routing and constraints */ - { - .constraints = { - .min_uV = LDO_D_VOLTAGE, - .max_uV = LDO_D_VOLTAGE, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - /* - * Actually this is boot_on but we need - * to reference count it externally to - * be able to shut down the system. - */ - }, - .num_consumer_supplies = ARRAY_SIZE(supply_ldo_d), - .consumer_supplies = supply_ldo_d, - }, - /* LDO E routing and constraints */ - { - .constraints = { - .name = "vio", - .min_uV = 1800000, - .max_uV = 1800000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .always_on = 1, - .boot_on = 1, - }, - }, - /* LDO F routing and constraints */ - { - .constraints = { - .name = "vana25", - .min_uV = 2500000, - .max_uV = 2500000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .always_on = 1, - .boot_on = 1, - }, - }, - /* LDO G routing and constraints */ - { - .constraints = { - .min_uV = 1500000, - .max_uV = 2850000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .valid_ops_mask = - REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(supply_ldo_g), - .consumer_supplies = supply_ldo_g, - }, - /* LDO H routing and constraints */ - { - .constraints = { - .min_uV = 1200000, - .max_uV = 2750000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .valid_ops_mask = - REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(supply_ldo_h), - .consumer_supplies = supply_ldo_h, - }, - /* LDO K routing and constraints */ - { - .constraints = { - .min_uV = 1800000, - .max_uV = 2750000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .valid_ops_mask = - REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(supply_ldo_k), - .consumer_supplies = supply_ldo_k, - }, - /* External regulator interface. No fixed voltage specified. - * If we knew the voltage of the external regulator and it - * was connected on the board, we could add the (fixed) - * voltage for it here. - */ - { - .constraints = { - .min_uV = 0, - .max_uV = 0, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .valid_ops_mask = - REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(supply_ldo_ext), - .consumer_supplies = supply_ldo_ext, - }, - /* Buck converter routing and constraints */ - { - .constraints = { - .name = "vcore", - .min_uV = 1200000, - .max_uV = 1800000, - .valid_modes_mask = REGULATOR_MODE_NORMAL, - .valid_ops_mask = - REGULATOR_CHANGE_VOLTAGE, - .always_on = 1, - .boot_on = 1, - }, - }, - }, - .reg_initvals = { - LDO_A_SETTING, - LDO_C_SETTING, - LDO_E_SETTING, - LDO_E_SLEEP_SETTING, - LDO_F_SETTING, - LDO_G_SETTING, - LDO_H_SETTING, - LDO_K_SETTING, - LDO_EXT_SETTING, - BUCK_SETTING, - BUCK_SLEEP_SETTING, - LDO_D_SETTING, - }, -}; -#endif - -static struct i2c_board_info __initdata bus0_i2c_board_info[] = { -#ifdef CONFIG_AB3100_CORE - { - .type = "ab3100", - .addr = 0x48, - .irq = IRQ_U300_IRQ0_EXT, - .platform_data = &ab3100_plf_data, - }, -#else - { }, -#endif -}; - -static struct i2c_board_info __initdata bus1_i2c_board_info[] = { - { - .type = "fwcam", - .addr = 0x10, - }, - { - .type = "fwcam", - .addr = 0x5d, - }, -}; - -void __init u300_i2c_register_board_devices(void) -{ - i2c_register_board_info(0, bus0_i2c_board_info, - ARRAY_SIZE(bus0_i2c_board_info)); - /* - * This makes the core shut down all unused regulators - * after all the initcalls have completed. - */ - regulator_has_full_constraints(); - i2c_register_board_info(1, bus1_i2c_board_info, - ARRAY_SIZE(bus1_i2c_board_info)); -} diff --git a/arch/arm/mach-u300/i2c.h b/arch/arm/mach-u300/i2c.h deleted file mode 100644 index 485c02e5c06d..000000000000 --- a/arch/arm/mach-u300/i2c.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * arch/arm/mach-u300/i2c.h - * - * Copyright (C) 2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * - * Register board i2c devices - * Author: Linus Walleij - */ - -#ifndef MACH_U300_I2C_H -#define MACH_U300_I2C_H - -#ifdef CONFIG_I2C_STU300 -void __init u300_i2c_register_board_devices(void); -#else -/* Compile out this stuff if no I2C adapter is available */ -static inline void __init u300_i2c_register_board_devices(void) -{ -} -#endif - -#endif diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c index 8a67dc604576..bbda954e00fd 100644 --- a/arch/arm/mach-u300/regulator.c +++ b/arch/arm/mach-u300/regulator.c @@ -58,10 +58,7 @@ static int __init __u300_init_boardpower(struct platform_device *pdev) u32 val; pr_info("U300: setting up board power\n"); - if (pdev) - main_power_15 = regulator_get(&pdev->dev, "vana15"); - else - main_power_15 = regulator_get(NULL, "vana15"); + main_power_15 = regulator_get(&pdev->dev, "vana15"); if (IS_ERR(main_power_15)) { pr_err("could not get vana15"); @@ -114,11 +111,8 @@ static struct platform_driver s365_board_driver = { */ static int __init u300_init_boardpower(void) { - if (of_have_populated_dt()) - return platform_driver_probe(&s365_board_driver, - s365_board_probe); - /* Only call this on non-DT boots */ - return __u300_init_boardpower(NULL); + return platform_driver_probe(&s365_board_driver, + s365_board_probe); } device_initcall(u300_init_boardpower); diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c deleted file mode 100644 index 910698293d64..000000000000 --- a/arch/arm/mach-u300/spi.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * arch/arm/mach-u300/spi.c - * - * Copyright (C) 2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * - * Author: Linus Walleij - */ -#include -#include -#include -#include -#include -#include - -/* - * The following is for the actual devices on the SSP/SPI bus - */ -#ifdef CONFIG_MACH_U300_SPIDUMMY -static void select_dummy_chip(u32 chipselect) -{ - pr_debug("CORE: %s called with CS=0x%x (%s)\n", - __func__, - chipselect, - chipselect ? "unselect chip" : "select chip"); - /* - * Here you would write the chip select value to the GPIO pins if - * this was a real chip (but this is a loopback dummy). - */ -} - -struct pl022_config_chip dummy_chip_info = { - /* available POLLING_TRANSFER, INTERRUPT_TRANSFER, DMA_TRANSFER */ - .com_mode = DMA_TRANSFER, - .iface = SSP_INTERFACE_MOTOROLA_SPI, - /* We can only act as master but SSP_SLAVE is possible in theory */ - .hierarchy = SSP_MASTER, - /* 0 = drive TX even as slave, 1 = do not drive TX as slave */ - .slave_tx_disable = 0, - .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, - .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, - .ctrl_len = SSP_BITS_12, - .wait_state = SSP_MWIRE_WAIT_ZERO, - .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, - /* - * This is where you insert a call to a function to enable CS - * (usually GPIO) for a certain chip. - */ - .cs_control = select_dummy_chip, -}; -#endif - -static struct spi_board_info u300_spi_devices[] = { -#ifdef CONFIG_MACH_U300_SPIDUMMY - { - /* A dummy chip used for loopback tests */ - .modalias = "spi-dummy", - /* Really dummy, pass in additional chip config here */ - .platform_data = NULL, - /* This defines how the controller shall handle the device */ - .controller_data = &dummy_chip_info, - /* .irq - no external IRQ routed from this device */ - .max_speed_hz = 1000000, - .bus_num = 0, /* Only one bus on this chip */ - .chip_select = 0, - /* Means SPI_CS_HIGH, change if e.g low CS */ - .mode = SPI_MODE_1 | SPI_LOOP, - }, -#endif -}; - -static struct pl022_ssp_controller ssp_platform_data = { - /* If you have several SPI buses this varies, we have only bus 0 */ - .bus_id = 0, - /* - * On the APP CPU GPIO 4, 5 and 6 are connected as generic - * chip selects for SPI. (Same on U330, U335 and U365.) - * TODO: make sure the GPIO driver can select these properly - * and do padmuxing accordingly too. - */ - .num_chipselect = 3, -#ifdef CONFIG_COH901318 - .enable_dma = 1, - .dma_filter = coh901318_filter_id, - .dma_rx_param = (void *) U300_DMA_SPI_RX, - .dma_tx_param = (void *) U300_DMA_SPI_TX, -#else - .enable_dma = 0, -#endif -}; - - -void __init u300_spi_init(struct amba_device *adev) -{ - adev->dev.platform_data = &ssp_platform_data; -} - -void __init u300_spi_register_board_devices(void) -{ - /* Register any SPI devices */ - spi_register_board_info(u300_spi_devices, ARRAY_SIZE(u300_spi_devices)); -} diff --git a/arch/arm/mach-u300/spi.h b/arch/arm/mach-u300/spi.h deleted file mode 100644 index bd3d867e240f..000000000000 --- a/arch/arm/mach-u300/spi.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/mach-u300/spi.h - * - * Copyright (C) 2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * - * Author: Linus Walleij - */ -#ifndef SPI_H -#define SPI_H -#include - -#ifdef CONFIG_SPI_PL022 -void __init u300_spi_init(struct amba_device *adev); -void __init u300_spi_register_board_devices(void); -#else -/* Compile out SPI support if PL022 is not selected */ -static inline void __init u300_spi_init(struct amba_device *adev) -{ -} -static inline void __init u300_spi_register_board_devices(void) -{ -} -#endif - -#endif diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c index df1e3b5427b6..f3efef0c5dbc 100644 --- a/arch/arm/mach-u300/timer.c +++ b/arch/arm/mach-u300/timer.c @@ -30,8 +30,6 @@ #include #include -#include "timer.h" - /* * APP side special timer registers * This timer contains four timers which can fire an interrupt each. @@ -361,12 +359,22 @@ static struct delay_timer u300_delay_timer; /* * This sets up the system timers, clock source and clock event. */ -static void __init u300_timer_setup(void __iomem *base, int irq) +static void __init u300_timer_init_of(struct device_node *np) { + struct resource irq_res; + int irq; struct clk *clk; unsigned long rate; - u300_timer_base = base; + u300_timer_base = of_iomap(np, 0); + if (!u300_timer_base) + panic("could not ioremap system timer\n"); + + /* Get the IRQ for the GP1 timer */ + irq = of_irq_to_resource(np, 2, &irq_res); + if (irq <= 0) + panic("no IRQ for system timer\n"); + pr_info("U300 GP1 timer @ base: %p, IRQ: %d\n", u300_timer_base, irq); /* Clock the interrupt controller */ @@ -433,27 +441,5 @@ static void __init u300_timer_setup(void __iomem *base, int irq) */ } - -void __init u300_timer_init() -{ - u300_timer_setup(U300_TIMER_APP_VBASE, IRQ_U300_TIMER_APP_GP1); -} - -#ifdef CONFIG_OF - -static void __init u300_timer_init_of(struct device_node *np) -{ - void __iomem *base; - struct resource irq_res; - int irq; - - base = of_iomap(np, 0); - /* Get the IRQ for the GP1 timer */ - irq = of_irq_to_resource(np, 2, &irq_res); - u300_timer_setup(base, irq); -} - CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer", u300_timer_init_of); - -#endif diff --git a/arch/arm/mach-u300/timer.h b/arch/arm/mach-u300/timer.h deleted file mode 100644 index 7766dfa6979d..000000000000 --- a/arch/arm/mach-u300/timer.h +++ /dev/null @@ -1,2 +0,0 @@ -extern void u300_timer_init(void); - diff --git a/arch/arm/mach-u300/u300-gpio.h b/arch/arm/mach-u300/u300-gpio.h deleted file mode 100644 index 83f50772e169..000000000000 --- a/arch/arm/mach-u300/u300-gpio.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Individual pin assignments for the B335/S335. - * Notice that the actual usage of these pins depends on the - * PAD MUX settings, that is why the same number can potentially - * appear several times. In the reference design each pin is only - * used for one purpose. These were determined by inspecting the - * S365 schematic. - */ -#define U300_GPIO_PIN_UART_RX 0 -#define U300_GPIO_PIN_UART_TX 1 -#define U300_GPIO_PIN_UART_CTS 2 -#define U300_GPIO_PIN_UART_RTS 3 -#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */ -#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */ -#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */ -#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */ - -#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */ -#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */ -#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */ -#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */ -#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */ -#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */ -#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */ -#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */ - -#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */ -#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */ -#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */ -#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */ -#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */ -#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */ -#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */ -#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */ - -#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */ -#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */ -#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */ -#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */ -#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */ -#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */ -#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */ -#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */ - -#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */ -#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */ -#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */ -#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */ -#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */ -#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */ -#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */ -#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */ - -#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */ -#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */ -#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */ -#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */ -#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */ -#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */ -#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */ -#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */ - -#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */ -#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */ -#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */ -#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */ -#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */ -#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */ -#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */ -#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */ -- cgit v1.2.3 From e1b3144586876ac0318f344b4a525108f86c1abd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 2 May 2013 18:01:46 +0200 Subject: ARM: u300: convert to multiplatform Now that we removed our dependency on the U300 can be converted to mutliplatform. Remove the invalid restriction that U300 would not support AUTO_ZRELADDR (it does) and update the defconfig in the process. Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- arch/arm/Kconfig | 21 +-------------------- arch/arm/configs/u300_defconfig | 11 ++++------- arch/arm/mach-u300/Kconfig | 31 +++++++++++++++++++++++++------ 3 files changed, 30 insertions(+), 33 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 26896433ae78..b6f9ce6f4f5b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -812,25 +812,6 @@ config ARCH_SHARK Support for the StrongARM based Digital DNARD machine, also known as "Shark" (). -config ARCH_U300 - bool "ST-Ericsson U300 Series" - depends on MMU - select ARCH_REQUIRE_GPIOLIB - select ARM_AMBA - select ARM_PATCH_PHYS_VIRT - select ARM_VIC - select CLKDEV_LOOKUP - select CLKSRC_MMIO - select CLKSRC_OF - select COMMON_CLK - select CPU_ARM926T - select GENERIC_CLOCKEVENTS - select HAVE_TCM - select SPARSE_IRQ - select USE_OF - help - Support for ST-Ericsson U300 series mobile platforms. - config ARCH_DAVINCI bool "TI DaVinci" select ARCH_HAS_HOLES_MEMORYMODEL @@ -2041,7 +2022,7 @@ config CRASH_DUMP config AUTO_ZRELADDR bool "Auto calculation of the decompressed kernel image address" - depends on !ZBOOT_ROM && !ARCH_U300 + depends on !ZBOOT_ROM help ZRELADDR is the physical address where the decompressed kernel image will be placed. If AUTO_ZRELADDR is selected, the address diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index 374000ec4e4e..a5fa0d90185a 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig @@ -1,7 +1,8 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_EXPERT=y # CONFIG_AIO is not set @@ -11,12 +12,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_CFQ is not set +# CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_U300=y -CONFIG_MACH_U300=y -CONFIG_MACH_U300_BS335=y CONFIG_MACH_U300_SPIDUMMY=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT=y CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 @@ -44,11 +42,11 @@ CONFIG_I2C=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_FB=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_MMC=y CONFIG_MMC_CLKGATE=y @@ -70,4 +68,3 @@ CONFIG_DEBUG_FS=y CONFIG_TIMER_STATS=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_DEBUG_INFO=y -# CONFIG_CRC32 is not set diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig index 1f597647d431..e2f350f2c32b 100644 --- a/arch/arm/mach-u300/Kconfig +++ b/arch/arm/mach-u300/Kconfig @@ -1,24 +1,45 @@ -if ARCH_U300 - menu "ST-Ericsson AB U300/U335 Platform" comment "ST-Ericsson Mobile Platform Products" -config MACH_U300 - bool "U300" +config ARCH_U300 + bool "ST-Ericsson U300 Series" + depends on MMU + select ARCH_REQUIRE_GPIOLIB + select ARM_AMBA + select ARM_PATCH_PHYS_VIRT + select ARM_VIC + select CLKDEV_LOOKUP + select CLKSRC_MMIO + select CLKSRC_OF + select COMMON_CLK + select CPU_ARM926T + select GENERIC_CLOCKEVENTS + select HAVE_TCM select PINCTRL select PINCTRL_COH901 select PINCTRL_U300 + select SPARSE_IRQ + select USE_OF + help + Support for ST-Ericsson U300 series mobile platforms. comment "ST-Ericsson U300/U335 Feature Selections" +config MACH_U300 + depends on ARCH_U300 + bool "U300" + default y + config U300_DEBUG + depends on ARCH_U300 bool "Debug support for U300" depends on PM help Debug support for U300 in sysfs, procfs etc. config MACH_U300_SPIDUMMY + depends on ARCH_U300 bool "SSP/SPI dummy chip" select SPI select SPI_MASTER @@ -31,5 +52,3 @@ config MACH_U300_SPIDUMMY SPI framework and ARM PL022 support. endmenu - -endif -- cgit v1.2.3 From 828989ad87af15b555f783a70efa2cc526b35b3f Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 10 Jun 2013 11:27:13 -0400 Subject: ARM: keystone: Add minimal TI Keystone platform support Texas Instruments Keystone family of multi-core devices are based on ARM Cortex A15. Patch adds basic definitions for a new Keystone sub-architecture in ARM. The TCI66xxK2H Communications Infrastructure Keystone SoCs are member of the C66x family based on TI's new KeyStone 2 multi-core SoC Architecture designed specifically for high performance wireless and networking infrastructure applications. The SOCs contains many subsystems like Cortex A15 ARM CorePacs, C66XX DSP CorePacs, MSMC memory controller, Tera Net bus, IP Network, Navigator, Hyperlink, 1G/10G Ethernet, Radio layers and queue based communication systems. Cc: Arnd Bergmann Cc: arm@kernel.org Acked-by: Olof Johansson Signed-off-by: Santosh Shilimkar --- arch/arm/Kconfig | 3 + arch/arm/Kconfig.debug | 16 ++++ arch/arm/Makefile | 1 + arch/arm/configs/keystone_defconfig | 157 +++++++++++++++++++++++++++++++++++ arch/arm/include/debug/keystone.S | 43 ++++++++++ arch/arm/mach-keystone/Kconfig | 14 ++++ arch/arm/mach-keystone/Makefile | 1 + arch/arm/mach-keystone/Makefile.boot | 1 + arch/arm/mach-keystone/keystone.c | 71 ++++++++++++++++ 9 files changed, 307 insertions(+) create mode 100644 arch/arm/configs/keystone_defconfig create mode 100644 arch/arm/include/debug/keystone.S create mode 100644 arch/arm/mach-keystone/Kconfig create mode 100644 arch/arm/mach-keystone/Makefile create mode 100644 arch/arm/mach-keystone/Makefile.boot create mode 100644 arch/arm/mach-keystone/keystone.c (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49d993cee512..62cd2fac482e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -948,6 +948,8 @@ source "arch/arm/mach-iop13xx/Kconfig" source "arch/arm/mach-ixp4xx/Kconfig" +source "arch/arm/mach-keystone/Kconfig" + source "arch/arm/mach-kirkwood/Kconfig" source "arch/arm/mach-ks8695/Kconfig" @@ -1560,6 +1562,7 @@ config ARCH_NR_GPIO int default 1024 if ARCH_SHMOBILE || ARCH_TEGRA default 512 if SOC_OMAP5 + default 512 if ARCH_KEYSTONE default 392 if ARCH_U8500 default 352 if ARCH_VT8500 default 288 if ARCH_SUNXI diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 1d41908d5cda..62e7f95c6643 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -251,6 +251,20 @@ choice Say Y here if you want kernel low-level debugging support on i.MX6Q/DL. + config DEBUG_KEYSTONE_UART0 + bool "Kernel low-level debugging on KEYSTONE2 using UART0" + depends on ARCH_KEYSTONE + help + Say Y here if you want the debug print routines to direct + their output to UART0 serial port on KEYSTONE2 devices. + + config DEBUG_KEYSTONE_UART1 + bool "Kernel low-level debugging on KEYSTONE2 using UART1" + depends on ARCH_KEYSTONE + help + Say Y here if you want the debug print routines to direct + their output to UART1 serial port on KEYSTONE2 devices. + config DEBUG_MMP_UART2 bool "Kernel low-level debugging message via MMP UART2" depends on ARCH_MMP @@ -632,6 +646,8 @@ config DEBUG_LL_INCLUDE DEBUG_IMX51_UART || \ DEBUG_IMX53_UART ||\ DEBUG_IMX6Q_UART + default "debug/keystone.S" if DEBUG_KEYSTONE_UART0 || \ + DEBUG_KEYSTONE_UART1 default "debug/mvebu.S" if DEBUG_MVEBU_UART default "debug/mxs.S" if DEBUG_IMX23_UART || DEBUG_IMX28_UART default "debug/nomadik.S" if DEBUG_NOMADIK_UART diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1ba358ba16b8..a1c9a78d63d4 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -194,6 +194,7 @@ machine-$(CONFIG_PLAT_SPEAR) += spear machine-$(CONFIG_ARCH_VIRT) += virt machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_ARCH_SUNXI) += sunxi +machine-$(CONFIG_ARCH_KEYSTONE) += keystone # Platform directory name. This list is sorted alphanumerically # by CONFIG_* macro name. diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig new file mode 100644 index 000000000000..62e968cac9dc --- /dev/null +++ b/arch/arm/configs/keystone_defconfig @@ -0,0 +1,157 @@ +# CONFIG_SWAP is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_BLK_DEV_INITRD=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_ELF_CORE is not set +# CONFIG_BASE_FULL is not set +CONFIG_EMBEDDED=y +CONFIG_PROFILING=y +CONFIG_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_ARCH_KEYSTONE=y +CONFIG_ARM_LPAE=y +CONFIG_SMP=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_HIGHMEM=y +CONFIG_VFP=y +CONFIG_NEON=y +# CONFIG_SUSPEND is not set +CONFIG_PM_RUNTIME=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_STATISTICS=y +CONFIG_NET_KEY=y +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_NET_IPIP=y +CONFIG_NET_IPGRE_DEMUX=y +CONFIG_NET_IPGRE=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V2=y +CONFIG_INET_AH=y +CONFIG_INET_IPCOMP=y +CONFIG_IPV6=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETFILTER=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_CPU=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_ULOG=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_TARGET_CLUSTERIP=y +CONFIG_IP_NF_TARGET_ECN=y +CONFIG_IP_NF_TARGET_TTL=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP_SCTP=y +CONFIG_VLAN_8021Q=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_CMA=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_PLATRAM=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_NAND=y +CONFIG_MTD_UBI=y +CONFIG_PROC_DEVICETREE=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_EEPROM_AT24=y +CONFIG_NETDEVICES=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +CONFIG_SPI=y +CONFIG_SPI_SPIDEV=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_USB_SUPPORT is not set +CONFIG_DMADEVICES=y +CONFIG_COMMON_CLK_DEBUG=y +CONFIG_MEMORY=y +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_WBUF_VERIFY=y +CONFIG_UBIFS_FS=y +CONFIG_CRAMFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_USER=y +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_XCBC=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y diff --git a/arch/arm/include/debug/keystone.S b/arch/arm/include/debug/keystone.S new file mode 100644 index 000000000000..9aef9ba3f4f0 --- /dev/null +++ b/arch/arm/include/debug/keystone.S @@ -0,0 +1,43 @@ +/* + * Early serial debug output macro for Keystone SOCs + * + * Copyright 2013 Texas Instruments, Inc. + * Santosh Shilimkar + * + * Based on RMKs low level debug code. + * Copyright (C) 1994-1999 Russell King + * + * 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 + +#define UART_SHIFT 2 +#if defined(CONFIG_DEBUG_KEYSTONE_UART0) +#define UART_PHYS 0x02530c00 +#define UART_VIRT 0xfeb30c00 +#elif defined(CONFIG_DEBUG_KEYSTONE_UART1) +#define UART_PHYS 0x02531000 +#define UART_VIRT 0xfeb31000 +#endif + + .macro addruart, rp, rv, tmp + ldr \rv, =UART_VIRT @ physical base address + ldr \rp, =UART_PHYS @ virtual base address + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #UART_TX << UART_SHIFT] + .endm + + .macro busyuart,rd,rx +1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] + and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE + teq \rd, #UART_LSR_TEMT | UART_LSR_THRE + bne 1002b + .endm + + .macro waituart,rd,rx + .endm diff --git a/arch/arm/mach-keystone/Kconfig b/arch/arm/mach-keystone/Kconfig new file mode 100644 index 000000000000..aebe8cdd88fc --- /dev/null +++ b/arch/arm/mach-keystone/Kconfig @@ -0,0 +1,14 @@ +config ARCH_KEYSTONE + bool "Texas Instruments Keystone Devices" + depends on ARCH_MULTI_V7 + select CPU_V7 + select ARM_GIC + select HAVE_ARM_ARCH_TIMER + select CLKSRC_MMIO + select GENERIC_CLOCKEVENTS + select HAVE_SCHED_CLOCK + select ARCH_WANT_OPTIONAL_GPIOLIB + select ARM_ERRATA_798181 + help + Support for boards based on the Texas Instruments Keystone family of + SoCs. diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile new file mode 100644 index 000000000000..d4671d55215a --- /dev/null +++ b/arch/arm/mach-keystone/Makefile @@ -0,0 +1 @@ +obj-y := keystone.o diff --git a/arch/arm/mach-keystone/Makefile.boot b/arch/arm/mach-keystone/Makefile.boot new file mode 100644 index 000000000000..f3835c43af61 --- /dev/null +++ b/arch/arm/mach-keystone/Makefile.boot @@ -0,0 +1 @@ +zreladdr-y := 0x80008000 diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c new file mode 100644 index 000000000000..a67c19b8be20 --- /dev/null +++ b/arch/arm/mach-keystone/keystone.c @@ -0,0 +1,71 @@ +/* + * Keystone2 based boards and SOC related code. + * + * Copyright 2013 Texas Instruments, Inc. + * Cyril Chemparathy + * Santosh Shilimkar + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define PLL_RESET_WRITE_KEY_MASK 0xffff0000 +#define PLL_RESET_WRITE_KEY 0x5a69 +#define PLL_RESET BIT(16) + +static void __iomem *keystone_rstctrl; + +static void __init keystone_init(void) +{ + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "ti,keystone-reset"); + if (WARN_ON(!node)) + pr_warn("ti,keystone-reset node undefined\n"); + + keystone_rstctrl = of_iomap(node, 0); + if (WARN_ON(!keystone_rstctrl)) + pr_warn("ti,keystone-reset iomap error\n"); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char *keystone_match[] __initconst = { + "ti,keystone-evm", + NULL, +}; + +void keystone_restart(char mode, const char *cmd) +{ + u32 val; + + BUG_ON(!keystone_rstctrl); + + /* Enable write access to RSTCTRL */ + val = readl(keystone_rstctrl); + val &= PLL_RESET_WRITE_KEY_MASK; + val |= PLL_RESET_WRITE_KEY; + writel(val, keystone_rstctrl); + + /* Reset the SOC */ + val = readl(keystone_rstctrl); + val &= ~PLL_RESET; + writel(val, keystone_rstctrl); +} + +DT_MACHINE_START(KEYSTONE, "Keystone") + .init_machine = keystone_init, + .dt_compat = keystone_match, + .restart = keystone_restart, +MACHINE_END -- cgit v1.2.3 From 3ad7a42d5a9c3736cd6d2c6f7e6038d0ca8b316c Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Wed, 6 Mar 2013 11:15:31 -0500 Subject: ARM: davinci: move private EDMA API to arm/common Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. Signed-off-by: Matt Porter Acked-by: Chris Ball # davinci_mmc.c Acked-by: Mark Brown Acked-by: Olof Johansson [nsekhar@ti.com: dropped davinci sffsdr changes] Signed-off-by: Sekhar Nori --- arch/arm/Kconfig | 1 + arch/arm/common/Kconfig | 3 + arch/arm/common/Makefile | 1 + arch/arm/common/edma.c | 1591 +++++++++++++++++++++++++++ arch/arm/mach-davinci/Makefile | 2 +- arch/arm/mach-davinci/board-tnetv107x-evm.c | 2 +- arch/arm/mach-davinci/davinci.h | 2 +- arch/arm/mach-davinci/devices-tnetv107x.c | 2 +- arch/arm/mach-davinci/devices.c | 6 +- arch/arm/mach-davinci/dm355.c | 2 +- arch/arm/mach-davinci/dm365.c | 2 +- arch/arm/mach-davinci/dm644x.c | 2 +- arch/arm/mach-davinci/dm646x.c | 2 +- arch/arm/mach-davinci/dma.c | 1591 --------------------------- arch/arm/mach-davinci/include/mach/da8xx.h | 2 +- arch/arm/mach-davinci/include/mach/edma.h | 267 ----- drivers/dma/edma.c | 2 +- drivers/mmc/host/davinci_mmc.c | 1 + include/linux/mfd/davinci_voicecodec.h | 3 +- include/linux/platform_data/edma.h | 182 +++ include/linux/platform_data/spi-davinci.h | 2 +- sound/soc/davinci/davinci-evm.c | 1 + sound/soc/davinci/davinci-pcm.c | 1 + sound/soc/davinci/davinci-pcm.h | 2 +- 24 files changed, 1799 insertions(+), 1873 deletions(-) create mode 100644 arch/arm/common/edma.c delete mode 100644 arch/arm/mach-davinci/dma.c delete mode 100644 arch/arm/mach-davinci/include/mach/edma.h create mode 100644 include/linux/platform_data/edma.h (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49d993cee512..b1c66a48a454 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -840,6 +840,7 @@ config ARCH_DAVINCI select GENERIC_IRQ_CHIP select HAVE_IDE select NEED_MACH_GPIO_H + select TI_PRIV_EDMA select USE_OF select ZONE_DMA help diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 9353184d730d..c3a4e9ceba34 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -17,3 +17,6 @@ config SHARP_PARAM config SHARP_SCOOP bool + +config TI_PRIV_EDMA + bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 48434cbe3e89..8c60f473e976 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o AFLAGS_mcpm_head.o := -march=armv7-a AFLAGS_vlock.o := -march=armv7-a +obj-$(CONFIG_TI_PRIV_EDMA) += edma.o diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c new file mode 100644 index 000000000000..dcaeb8ec5d38 --- /dev/null +++ b/arch/arm/common/edma.c @@ -0,0 +1,1591 @@ +/* + * EDMA3 support for DaVinci + * + * Copyright (C) 2006-2009 Texas Instruments. + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +/* Offsets matching "struct edmacc_param" */ +#define PARM_OPT 0x00 +#define PARM_SRC 0x04 +#define PARM_A_B_CNT 0x08 +#define PARM_DST 0x0c +#define PARM_SRC_DST_BIDX 0x10 +#define PARM_LINK_BCNTRLD 0x14 +#define PARM_SRC_DST_CIDX 0x18 +#define PARM_CCNT 0x1c + +#define PARM_SIZE 0x20 + +/* Offsets for EDMA CC global channel registers and their shadows */ +#define SH_ER 0x00 /* 64 bits */ +#define SH_ECR 0x08 /* 64 bits */ +#define SH_ESR 0x10 /* 64 bits */ +#define SH_CER 0x18 /* 64 bits */ +#define SH_EER 0x20 /* 64 bits */ +#define SH_EECR 0x28 /* 64 bits */ +#define SH_EESR 0x30 /* 64 bits */ +#define SH_SER 0x38 /* 64 bits */ +#define SH_SECR 0x40 /* 64 bits */ +#define SH_IER 0x50 /* 64 bits */ +#define SH_IECR 0x58 /* 64 bits */ +#define SH_IESR 0x60 /* 64 bits */ +#define SH_IPR 0x68 /* 64 bits */ +#define SH_ICR 0x70 /* 64 bits */ +#define SH_IEVAL 0x78 +#define SH_QER 0x80 +#define SH_QEER 0x84 +#define SH_QEECR 0x88 +#define SH_QEESR 0x8c +#define SH_QSER 0x90 +#define SH_QSECR 0x94 +#define SH_SIZE 0x200 + +/* Offsets for EDMA CC global registers */ +#define EDMA_REV 0x0000 +#define EDMA_CCCFG 0x0004 +#define EDMA_QCHMAP 0x0200 /* 8 registers */ +#define EDMA_DMAQNUM 0x0240 /* 8 registers (4 on OMAP-L1xx) */ +#define EDMA_QDMAQNUM 0x0260 +#define EDMA_QUETCMAP 0x0280 +#define EDMA_QUEPRI 0x0284 +#define EDMA_EMR 0x0300 /* 64 bits */ +#define EDMA_EMCR 0x0308 /* 64 bits */ +#define EDMA_QEMR 0x0310 +#define EDMA_QEMCR 0x0314 +#define EDMA_CCERR 0x0318 +#define EDMA_CCERRCLR 0x031c +#define EDMA_EEVAL 0x0320 +#define EDMA_DRAE 0x0340 /* 4 x 64 bits*/ +#define EDMA_QRAE 0x0380 /* 4 registers */ +#define EDMA_QUEEVTENTRY 0x0400 /* 2 x 16 registers */ +#define EDMA_QSTAT 0x0600 /* 2 registers */ +#define EDMA_QWMTHRA 0x0620 +#define EDMA_QWMTHRB 0x0624 +#define EDMA_CCSTAT 0x0640 + +#define EDMA_M 0x1000 /* global channel registers */ +#define EDMA_ECR 0x1008 +#define EDMA_ECRH 0x100C +#define EDMA_SHADOW0 0x2000 /* 4 regions shadowing global channels */ +#define EDMA_PARM 0x4000 /* 128 param entries */ + +#define PARM_OFFSET(param_no) (EDMA_PARM + ((param_no) << 5)) + +#define EDMA_DCHMAP 0x0100 /* 64 registers */ +#define CHMAP_EXIST BIT(24) + +#define EDMA_MAX_DMACH 64 +#define EDMA_MAX_PARAMENTRY 512 + +/*****************************************************************************/ + +static void __iomem *edmacc_regs_base[EDMA_MAX_CC]; + +static inline unsigned int edma_read(unsigned ctlr, int offset) +{ + return (unsigned int)__raw_readl(edmacc_regs_base[ctlr] + offset); +} + +static inline void edma_write(unsigned ctlr, int offset, int val) +{ + __raw_writel(val, edmacc_regs_base[ctlr] + offset); +} +static inline void edma_modify(unsigned ctlr, int offset, unsigned and, + unsigned or) +{ + unsigned val = edma_read(ctlr, offset); + val &= and; + val |= or; + edma_write(ctlr, offset, val); +} +static inline void edma_and(unsigned ctlr, int offset, unsigned and) +{ + unsigned val = edma_read(ctlr, offset); + val &= and; + edma_write(ctlr, offset, val); +} +static inline void edma_or(unsigned ctlr, int offset, unsigned or) +{ + unsigned val = edma_read(ctlr, offset); + val |= or; + edma_write(ctlr, offset, val); +} +static inline unsigned int edma_read_array(unsigned ctlr, int offset, int i) +{ + return edma_read(ctlr, offset + (i << 2)); +} +static inline void edma_write_array(unsigned ctlr, int offset, int i, + unsigned val) +{ + edma_write(ctlr, offset + (i << 2), val); +} +static inline void edma_modify_array(unsigned ctlr, int offset, int i, + unsigned and, unsigned or) +{ + edma_modify(ctlr, offset + (i << 2), and, or); +} +static inline void edma_or_array(unsigned ctlr, int offset, int i, unsigned or) +{ + edma_or(ctlr, offset + (i << 2), or); +} +static inline void edma_or_array2(unsigned ctlr, int offset, int i, int j, + unsigned or) +{ + edma_or(ctlr, offset + ((i*2 + j) << 2), or); +} +static inline void edma_write_array2(unsigned ctlr, int offset, int i, int j, + unsigned val) +{ + edma_write(ctlr, offset + ((i*2 + j) << 2), val); +} +static inline unsigned int edma_shadow0_read(unsigned ctlr, int offset) +{ + return edma_read(ctlr, EDMA_SHADOW0 + offset); +} +static inline unsigned int edma_shadow0_read_array(unsigned ctlr, int offset, + int i) +{ + return edma_read(ctlr, EDMA_SHADOW0 + offset + (i << 2)); +} +static inline void edma_shadow0_write(unsigned ctlr, int offset, unsigned val) +{ + edma_write(ctlr, EDMA_SHADOW0 + offset, val); +} +static inline void edma_shadow0_write_array(unsigned ctlr, int offset, int i, + unsigned val) +{ + edma_write(ctlr, EDMA_SHADOW0 + offset + (i << 2), val); +} +static inline unsigned int edma_parm_read(unsigned ctlr, int offset, + int param_no) +{ + return edma_read(ctlr, EDMA_PARM + offset + (param_no << 5)); +} +static inline void edma_parm_write(unsigned ctlr, int offset, int param_no, + unsigned val) +{ + edma_write(ctlr, EDMA_PARM + offset + (param_no << 5), val); +} +static inline void edma_parm_modify(unsigned ctlr, int offset, int param_no, + unsigned and, unsigned or) +{ + edma_modify(ctlr, EDMA_PARM + offset + (param_no << 5), and, or); +} +static inline void edma_parm_and(unsigned ctlr, int offset, int param_no, + unsigned and) +{ + edma_and(ctlr, EDMA_PARM + offset + (param_no << 5), and); +} +static inline void edma_parm_or(unsigned ctlr, int offset, int param_no, + unsigned or) +{ + edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or); +} + +static inline void set_bits(int offset, int len, unsigned long *p) +{ + for (; len > 0; len--) + set_bit(offset + (len - 1), p); +} + +static inline void clear_bits(int offset, int len, unsigned long *p) +{ + for (; len > 0; len--) + clear_bit(offset + (len - 1), p); +} + +/*****************************************************************************/ + +/* actual number of DMA channels and slots on this silicon */ +struct edma { + /* how many dma resources of each type */ + unsigned num_channels; + unsigned num_region; + unsigned num_slots; + unsigned num_tc; + unsigned num_cc; + enum dma_event_q default_queue; + + /* list of channels with no even trigger; terminated by "-1" */ + const s8 *noevent; + + /* The edma_inuse bit for each PaRAM slot is clear unless the + * channel is in use ... by ARM or DSP, for QDMA, or whatever. + */ + DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY); + + /* The edma_unused bit for each channel is clear unless + * it is not being used on this platform. It uses a bit + * of SOC-specific initialization code. + */ + DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH); + + unsigned irq_res_start; + unsigned irq_res_end; + + struct dma_interrupt_data { + void (*callback)(unsigned channel, unsigned short ch_status, + void *data); + void *data; + } intr_data[EDMA_MAX_DMACH]; +}; + +static struct edma *edma_cc[EDMA_MAX_CC]; +static int arch_num_cc; + +/* dummy param set used to (re)initialize parameter RAM slots */ +static const struct edmacc_param dummy_paramset = { + .link_bcntrld = 0xffff, + .ccnt = 1, +}; + +/*****************************************************************************/ + +static void map_dmach_queue(unsigned ctlr, unsigned ch_no, + enum dma_event_q queue_no) +{ + int bit = (ch_no & 0x7) * 4; + + /* default to low priority queue */ + if (queue_no == EVENTQ_DEFAULT) + queue_no = edma_cc[ctlr]->default_queue; + + queue_no &= 7; + edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3), + ~(0x7 << bit), queue_no << bit); +} + +static void __init map_queue_tc(unsigned ctlr, int queue_no, int tc_no) +{ + int bit = queue_no * 4; + edma_modify(ctlr, EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit)); +} + +static void __init assign_priority_to_queue(unsigned ctlr, int queue_no, + int priority) +{ + int bit = queue_no * 4; + edma_modify(ctlr, EDMA_QUEPRI, ~(0x7 << bit), + ((priority & 0x7) << bit)); +} + +/** + * map_dmach_param - Maps channel number to param entry number + * + * This maps the dma channel number to param entry numberter. In + * other words using the DMA channel mapping registers a param entry + * can be mapped to any channel + * + * Callers are responsible for ensuring the channel mapping logic is + * included in that particular EDMA variant (Eg : dm646x) + * + */ +static void __init map_dmach_param(unsigned ctlr) +{ + int i; + for (i = 0; i < EDMA_MAX_DMACH; i++) + edma_write_array(ctlr, EDMA_DCHMAP , i , (i << 5)); +} + +static inline void +setup_dma_interrupt(unsigned lch, + void (*callback)(unsigned channel, u16 ch_status, void *data), + void *data) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(lch); + lch = EDMA_CHAN_SLOT(lch); + + if (!callback) + edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5, + BIT(lch & 0x1f)); + + edma_cc[ctlr]->intr_data[lch].callback = callback; + edma_cc[ctlr]->intr_data[lch].data = data; + + if (callback) { + edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5, + BIT(lch & 0x1f)); + edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5, + BIT(lch & 0x1f)); + } +} + +static int irq2ctlr(int irq) +{ + if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end) + return 0; + else if (irq >= edma_cc[1]->irq_res_start && + irq <= edma_cc[1]->irq_res_end) + return 1; + + return -1; +} + +/****************************************************************************** + * + * DMA interrupt handler + * + *****************************************************************************/ +static irqreturn_t dma_irq_handler(int irq, void *data) +{ + int ctlr; + u32 sh_ier; + u32 sh_ipr; + u32 bank; + + ctlr = irq2ctlr(irq); + if (ctlr < 0) + return IRQ_NONE; + + dev_dbg(data, "dma_irq_handler\n"); + + sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0); + if (!sh_ipr) { + sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 1); + if (!sh_ipr) + return IRQ_NONE; + sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 1); + bank = 1; + } else { + sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 0); + bank = 0; + } + + do { + u32 slot; + u32 channel; + + dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr); + + slot = __ffs(sh_ipr); + sh_ipr &= ~(BIT(slot)); + + if (sh_ier & BIT(slot)) { + channel = (bank << 5) | slot; + /* Clear the corresponding IPR bits */ + edma_shadow0_write_array(ctlr, SH_ICR, bank, + BIT(slot)); + if (edma_cc[ctlr]->intr_data[channel].callback) + edma_cc[ctlr]->intr_data[channel].callback( + channel, DMA_COMPLETE, + edma_cc[ctlr]->intr_data[channel].data); + } + } while (sh_ipr); + + edma_shadow0_write(ctlr, SH_IEVAL, 1); + return IRQ_HANDLED; +} + +/****************************************************************************** + * + * DMA error interrupt handler + * + *****************************************************************************/ +static irqreturn_t dma_ccerr_handler(int irq, void *data) +{ + int i; + int ctlr; + unsigned int cnt = 0; + + ctlr = irq2ctlr(irq); + if (ctlr < 0) + return IRQ_NONE; + + dev_dbg(data, "dma_ccerr_handler\n"); + + if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) && + (edma_read_array(ctlr, EDMA_EMR, 1) == 0) && + (edma_read(ctlr, EDMA_QEMR) == 0) && + (edma_read(ctlr, EDMA_CCERR) == 0)) + return IRQ_NONE; + + while (1) { + int j = -1; + if (edma_read_array(ctlr, EDMA_EMR, 0)) + j = 0; + else if (edma_read_array(ctlr, EDMA_EMR, 1)) + j = 1; + if (j >= 0) { + dev_dbg(data, "EMR%d %08x\n", j, + edma_read_array(ctlr, EDMA_EMR, j)); + for (i = 0; i < 32; i++) { + int k = (j << 5) + i; + if (edma_read_array(ctlr, EDMA_EMR, j) & + BIT(i)) { + /* Clear the corresponding EMR bits */ + edma_write_array(ctlr, EDMA_EMCR, j, + BIT(i)); + /* Clear any SER */ + edma_shadow0_write_array(ctlr, SH_SECR, + j, BIT(i)); + if (edma_cc[ctlr]->intr_data[k]. + callback) { + edma_cc[ctlr]->intr_data[k]. + callback(k, + DMA_CC_ERROR, + edma_cc[ctlr]->intr_data + [k].data); + } + } + } + } else if (edma_read(ctlr, EDMA_QEMR)) { + dev_dbg(data, "QEMR %02x\n", + edma_read(ctlr, EDMA_QEMR)); + for (i = 0; i < 8; i++) { + if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) { + /* Clear the corresponding IPR bits */ + edma_write(ctlr, EDMA_QEMCR, BIT(i)); + edma_shadow0_write(ctlr, SH_QSECR, + BIT(i)); + + /* NOTE: not reported!! */ + } + } + } else if (edma_read(ctlr, EDMA_CCERR)) { + dev_dbg(data, "CCERR %08x\n", + edma_read(ctlr, EDMA_CCERR)); + /* FIXME: CCERR.BIT(16) ignored! much better + * to just write CCERRCLR with CCERR value... + */ + for (i = 0; i < 8; i++) { + if (edma_read(ctlr, EDMA_CCERR) & BIT(i)) { + /* Clear the corresponding IPR bits */ + edma_write(ctlr, EDMA_CCERRCLR, BIT(i)); + + /* NOTE: not reported!! */ + } + } + } + if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) && + (edma_read_array(ctlr, EDMA_EMR, 1) == 0) && + (edma_read(ctlr, EDMA_QEMR) == 0) && + (edma_read(ctlr, EDMA_CCERR) == 0)) + break; + cnt++; + if (cnt > 10) + break; + } + edma_write(ctlr, EDMA_EEVAL, 1); + return IRQ_HANDLED; +} + +/****************************************************************************** + * + * Transfer controller error interrupt handlers + * + *****************************************************************************/ + +#define tc_errs_handled false /* disabled as long as they're NOPs */ + +static irqreturn_t dma_tc0err_handler(int irq, void *data) +{ + dev_dbg(data, "dma_tc0err_handler\n"); + return IRQ_HANDLED; +} + +static irqreturn_t dma_tc1err_handler(int irq, void *data) +{ + dev_dbg(data, "dma_tc1err_handler\n"); + return IRQ_HANDLED; +} + +static int reserve_contiguous_slots(int ctlr, unsigned int id, + unsigned int num_slots, + unsigned int start_slot) +{ + int i, j; + unsigned int count = num_slots; + int stop_slot = start_slot; + DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY); + + for (i = start_slot; i < edma_cc[ctlr]->num_slots; ++i) { + j = EDMA_CHAN_SLOT(i); + if (!test_and_set_bit(j, edma_cc[ctlr]->edma_inuse)) { + /* Record our current beginning slot */ + if (count == num_slots) + stop_slot = i; + + count--; + set_bit(j, tmp_inuse); + + if (count == 0) + break; + } else { + clear_bit(j, tmp_inuse); + + if (id == EDMA_CONT_PARAMS_FIXED_EXACT) { + stop_slot = i; + break; + } else { + count = num_slots; + } + } + } + + /* + * We have to clear any bits that we set + * if we run out parameter RAM slots, i.e we do find a set + * of contiguous parameter RAM slots but do not find the exact number + * requested as we may reach the total number of parameter RAM slots + */ + if (i == edma_cc[ctlr]->num_slots) + stop_slot = i; + + j = start_slot; + for_each_set_bit_from(j, tmp_inuse, stop_slot) + clear_bit(j, edma_cc[ctlr]->edma_inuse); + + if (count) + return -EBUSY; + + for (j = i - num_slots + 1; j <= i; ++j) + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j), + &dummy_paramset, PARM_SIZE); + + return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1); +} + +static int prepare_unused_channel_list(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + int i, ctlr; + + for (i = 0; i < pdev->num_resources; i++) { + if ((pdev->resource[i].flags & IORESOURCE_DMA) && + (int)pdev->resource[i].start >= 0) { + ctlr = EDMA_CTLR(pdev->resource[i].start); + clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start), + edma_cc[ctlr]->edma_unused); + } + } + + return 0; +} + +/*-----------------------------------------------------------------------*/ + +static bool unused_chan_list_done; + +/* Resource alloc/free: dma channels, parameter RAM slots */ + +/** + * edma_alloc_channel - allocate DMA channel and paired parameter RAM + * @channel: specific channel to allocate; negative for "any unmapped channel" + * @callback: optional; to be issued on DMA completion or errors + * @data: passed to callback + * @eventq_no: an EVENTQ_* constant, used to choose which Transfer + * Controller (TC) executes requests using this channel. Use + * EVENTQ_DEFAULT unless you really need a high priority queue. + * + * This allocates a DMA channel and its associated parameter RAM slot. + * The parameter RAM is initialized to hold a dummy transfer. + * + * Normal use is to pass a specific channel number as @channel, to make + * use of hardware events mapped to that channel. When the channel will + * be used only for software triggering or event chaining, channels not + * mapped to hardware events (or mapped to unused events) are preferable. + * + * DMA transfers start from a channel using edma_start(), or by + * chaining. When the transfer described in that channel's parameter RAM + * slot completes, that slot's data may be reloaded through a link. + * + * DMA errors are only reported to the @callback associated with the + * channel driving that transfer, but transfer completion callbacks can + * be sent to another channel under control of the TCC field in + * the option word of the transfer's parameter RAM set. Drivers must not + * use DMA transfer completion callbacks for channels they did not allocate. + * (The same applies to TCC codes used in transfer chaining.) + * + * Returns the number of the channel, else negative errno. + */ +int edma_alloc_channel(int channel, + void (*callback)(unsigned channel, u16 ch_status, void *data), + void *data, + enum dma_event_q eventq_no) +{ + unsigned i, done = 0, ctlr = 0; + int ret = 0; + + if (!unused_chan_list_done) { + /* + * Scan all the platform devices to find out the EDMA channels + * used and clear them in the unused list, making the rest + * available for ARM usage. + */ + ret = bus_for_each_dev(&platform_bus_type, NULL, NULL, + prepare_unused_channel_list); + if (ret < 0) + return ret; + + unused_chan_list_done = true; + } + + if (channel >= 0) { + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + } + + if (channel < 0) { + for (i = 0; i < arch_num_cc; i++) { + channel = 0; + for (;;) { + channel = find_next_bit(edma_cc[i]->edma_unused, + edma_cc[i]->num_channels, + channel); + if (channel == edma_cc[i]->num_channels) + break; + if (!test_and_set_bit(channel, + edma_cc[i]->edma_inuse)) { + done = 1; + ctlr = i; + break; + } + channel++; + } + if (done) + break; + } + if (!done) + return -ENOMEM; + } else if (channel >= edma_cc[ctlr]->num_channels) { + return -EINVAL; + } else if (test_and_set_bit(channel, edma_cc[ctlr]->edma_inuse)) { + return -EBUSY; + } + + /* ensure access through shadow region 0 */ + edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f)); + + /* ensure no events are pending */ + edma_stop(EDMA_CTLR_CHAN(ctlr, channel)); + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel), + &dummy_paramset, PARM_SIZE); + + if (callback) + setup_dma_interrupt(EDMA_CTLR_CHAN(ctlr, channel), + callback, data); + + map_dmach_queue(ctlr, channel, eventq_no); + + return EDMA_CTLR_CHAN(ctlr, channel); +} +EXPORT_SYMBOL(edma_alloc_channel); + + +/** + * edma_free_channel - deallocate DMA channel + * @channel: dma channel returned from edma_alloc_channel() + * + * This deallocates the DMA channel and associated parameter RAM slot + * allocated by edma_alloc_channel(). + * + * Callers are responsible for ensuring the channel is inactive, and + * will not be reactivated by linking, chaining, or software calls to + * edma_start(). + */ +void edma_free_channel(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel >= edma_cc[ctlr]->num_channels) + return; + + setup_dma_interrupt(channel, NULL, NULL); + /* REVISIT should probably take out of shadow region 0 */ + + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel), + &dummy_paramset, PARM_SIZE); + clear_bit(channel, edma_cc[ctlr]->edma_inuse); +} +EXPORT_SYMBOL(edma_free_channel); + +/** + * edma_alloc_slot - allocate DMA parameter RAM + * @slot: specific slot to allocate; negative for "any unused slot" + * + * This allocates a parameter RAM slot, initializing it to hold a + * dummy transfer. Slots allocated using this routine have not been + * mapped to a hardware DMA channel, and will normally be used by + * linking to them from a slot associated with a DMA channel. + * + * Normal use is to pass EDMA_SLOT_ANY as the @slot, but specific + * slots may be allocated on behalf of DSP firmware. + * + * Returns the number of the slot, else negative errno. + */ +int edma_alloc_slot(unsigned ctlr, int slot) +{ + if (!edma_cc[ctlr]) + return -EINVAL; + + if (slot >= 0) + slot = EDMA_CHAN_SLOT(slot); + + if (slot < 0) { + slot = edma_cc[ctlr]->num_channels; + for (;;) { + slot = find_next_zero_bit(edma_cc[ctlr]->edma_inuse, + edma_cc[ctlr]->num_slots, slot); + if (slot == edma_cc[ctlr]->num_slots) + return -ENOMEM; + if (!test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) + break; + } + } else if (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots) { + return -EINVAL; + } else if (test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) { + return -EBUSY; + } + + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), + &dummy_paramset, PARM_SIZE); + + return EDMA_CTLR_CHAN(ctlr, slot); +} +EXPORT_SYMBOL(edma_alloc_slot); + +/** + * edma_free_slot - deallocate DMA parameter RAM + * @slot: parameter RAM slot returned from edma_alloc_slot() + * + * This deallocates the parameter RAM slot allocated by edma_alloc_slot(). + * Callers are responsible for ensuring the slot is inactive, and will + * not be activated. + */ +void edma_free_slot(unsigned slot) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots) + return; + + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), + &dummy_paramset, PARM_SIZE); + clear_bit(slot, edma_cc[ctlr]->edma_inuse); +} +EXPORT_SYMBOL(edma_free_slot); + + +/** + * edma_alloc_cont_slots- alloc contiguous parameter RAM slots + * The API will return the starting point of a set of + * contiguous parameter RAM slots that have been requested + * + * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT + * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT + * @count: number of contiguous Paramter RAM slots + * @slot - the start value of Parameter RAM slot that should be passed if id + * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT + * + * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of + * contiguous Parameter RAM slots from parameter RAM 64 in the case of + * DaVinci SOCs and 32 in the case of DA8xx SOCs. + * + * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a + * set of contiguous parameter RAM slots from the "slot" that is passed as an + * argument to the API. + * + * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries + * starts looking for a set of contiguous parameter RAMs from the "slot" + * that is passed as an argument to the API. On failure the API will try to + * find a set of contiguous Parameter RAM slots from the remaining Parameter + * RAM slots + */ +int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) +{ + /* + * The start slot requested should be greater than + * the number of channels and lesser than the total number + * of slots + */ + if ((id != EDMA_CONT_PARAMS_ANY) && + (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots)) + return -EINVAL; + + /* + * The number of parameter RAM slots requested cannot be less than 1 + * and cannot be more than the number of slots minus the number of + * channels + */ + if (count < 1 || count > + (edma_cc[ctlr]->num_slots - edma_cc[ctlr]->num_channels)) + return -EINVAL; + + switch (id) { + case EDMA_CONT_PARAMS_ANY: + return reserve_contiguous_slots(ctlr, id, count, + edma_cc[ctlr]->num_channels); + case EDMA_CONT_PARAMS_FIXED_EXACT: + case EDMA_CONT_PARAMS_FIXED_NOT_EXACT: + return reserve_contiguous_slots(ctlr, id, count, slot); + default: + return -EINVAL; + } + +} +EXPORT_SYMBOL(edma_alloc_cont_slots); + +/** + * edma_free_cont_slots - deallocate DMA parameter RAM slots + * @slot: first parameter RAM of a set of parameter RAM slots to be freed + * @count: the number of contiguous parameter RAM slots to be freed + * + * This deallocates the parameter RAM slots allocated by + * edma_alloc_cont_slots. + * Callers/applications need to keep track of sets of contiguous + * parameter RAM slots that have been allocated using the edma_alloc_cont_slots + * API. + * Callers are responsible for ensuring the slots are inactive, and will + * not be activated. + */ +int edma_free_cont_slots(unsigned slot, int count) +{ + unsigned ctlr, slot_to_free; + int i; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_channels || + slot >= edma_cc[ctlr]->num_slots || + count < 1) + return -EINVAL; + + for (i = slot; i < slot + count; ++i) { + ctlr = EDMA_CTLR(i); + slot_to_free = EDMA_CHAN_SLOT(i); + + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free), + &dummy_paramset, PARM_SIZE); + clear_bit(slot_to_free, edma_cc[ctlr]->edma_inuse); + } + + return 0; +} +EXPORT_SYMBOL(edma_free_cont_slots); + +/*-----------------------------------------------------------------------*/ + +/* Parameter RAM operations (i) -- read/write partial slots */ + +/** + * edma_set_src - set initial DMA source address in parameter RAM slot + * @slot: parameter RAM slot being configured + * @src_port: physical address of source (memory, controller FIFO, etc) + * @addressMode: INCR, except in very rare cases + * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the + * width to use when addressing the fifo (e.g. W8BIT, W32BIT) + * + * Note that the source address is modified during the DMA transfer + * according to edma_set_src_index(). + */ +void edma_set_src(unsigned slot, dma_addr_t src_port, + enum address_mode mode, enum fifo_width width) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot); + + if (mode) { + /* set SAM and program FWID */ + i = (i & ~(EDMA_FWID)) | (SAM | ((width & 0x7) << 8)); + } else { + /* clear SAM */ + i &= ~SAM; + } + edma_parm_write(ctlr, PARM_OPT, slot, i); + + /* set the source port address + in source register of param structure */ + edma_parm_write(ctlr, PARM_SRC, slot, src_port); + } +} +EXPORT_SYMBOL(edma_set_src); + +/** + * edma_set_dest - set initial DMA destination address in parameter RAM slot + * @slot: parameter RAM slot being configured + * @dest_port: physical address of destination (memory, controller FIFO, etc) + * @addressMode: INCR, except in very rare cases + * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the + * width to use when addressing the fifo (e.g. W8BIT, W32BIT) + * + * Note that the destination address is modified during the DMA transfer + * according to edma_set_dest_index(). + */ +void edma_set_dest(unsigned slot, dma_addr_t dest_port, + enum address_mode mode, enum fifo_width width) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot); + + if (mode) { + /* set DAM and program FWID */ + i = (i & ~(EDMA_FWID)) | (DAM | ((width & 0x7) << 8)); + } else { + /* clear DAM */ + i &= ~DAM; + } + edma_parm_write(ctlr, PARM_OPT, slot, i); + /* set the destination port address + in dest register of param structure */ + edma_parm_write(ctlr, PARM_DST, slot, dest_port); + } +} +EXPORT_SYMBOL(edma_set_dest); + +/** + * edma_get_position - returns the current transfer points + * @slot: parameter RAM slot being examined + * @src: pointer to source port position + * @dst: pointer to destination port position + * + * Returns current source and destination addresses for a particular + * parameter RAM slot. Its channel should not be active when this is called. + */ +void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst) +{ + struct edmacc_param temp; + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + edma_read_slot(EDMA_CTLR_CHAN(ctlr, slot), &temp); + if (src != NULL) + *src = temp.src; + if (dst != NULL) + *dst = temp.dst; +} +EXPORT_SYMBOL(edma_get_position); + +/** + * edma_set_src_index - configure DMA source address indexing + * @slot: parameter RAM slot being configured + * @src_bidx: byte offset between source arrays in a frame + * @src_cidx: byte offset between source frames in a block + * + * Offsets are specified to support either contiguous or discontiguous + * memory transfers, or repeated access to a hardware register, as needed. + * When accessing hardware registers, both offsets are normally zero. + */ +void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot, + 0xffff0000, src_bidx); + edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot, + 0xffff0000, src_cidx); + } +} +EXPORT_SYMBOL(edma_set_src_index); + +/** + * edma_set_dest_index - configure DMA destination address indexing + * @slot: parameter RAM slot being configured + * @dest_bidx: byte offset between destination arrays in a frame + * @dest_cidx: byte offset between destination frames in a block + * + * Offsets are specified to support either contiguous or discontiguous + * memory transfers, or repeated access to a hardware register, as needed. + * When accessing hardware registers, both offsets are normally zero. + */ +void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot, + 0x0000ffff, dest_bidx << 16); + edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot, + 0x0000ffff, dest_cidx << 16); + } +} +EXPORT_SYMBOL(edma_set_dest_index); + +/** + * edma_set_transfer_params - configure DMA transfer parameters + * @slot: parameter RAM slot being configured + * @acnt: how many bytes per array (at least one) + * @bcnt: how many arrays per frame (at least one) + * @ccnt: how many frames per block (at least one) + * @bcnt_rld: used only for A-Synchronized transfers; this specifies + * the value to reload into bcnt when it decrements to zero + * @sync_mode: ASYNC or ABSYNC + * + * See the EDMA3 documentation to understand how to configure and link + * transfers using the fields in PaRAM slots. If you are not doing it + * all at once with edma_write_slot(), you will use this routine + * plus two calls each for source and destination, setting the initial + * address and saying how to index that address. + * + * An example of an A-Synchronized transfer is a serial link using a + * single word shift register. In that case, @acnt would be equal to + * that word size; the serial controller issues a DMA synchronization + * event to transfer each word, and memory access by the DMA transfer + * controller will be word-at-a-time. + * + * An example of an AB-Synchronized transfer is a device using a FIFO. + * In that case, @acnt equals the FIFO width and @bcnt equals its depth. + * The controller with the FIFO issues DMA synchronization events when + * the FIFO threshold is reached, and the DMA transfer controller will + * transfer one frame to (or from) the FIFO. It will probably use + * efficient burst modes to access memory. + */ +void edma_set_transfer_params(unsigned slot, + u16 acnt, u16 bcnt, u16 ccnt, + u16 bcnt_rld, enum sync_dimension sync_mode) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot < edma_cc[ctlr]->num_slots) { + edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot, + 0x0000ffff, bcnt_rld << 16); + if (sync_mode == ASYNC) + edma_parm_and(ctlr, PARM_OPT, slot, ~SYNCDIM); + else + edma_parm_or(ctlr, PARM_OPT, slot, SYNCDIM); + /* Set the acount, bcount, ccount registers */ + edma_parm_write(ctlr, PARM_A_B_CNT, slot, (bcnt << 16) | acnt); + edma_parm_write(ctlr, PARM_CCNT, slot, ccnt); + } +} +EXPORT_SYMBOL(edma_set_transfer_params); + +/** + * edma_link - link one parameter RAM slot to another + * @from: parameter RAM slot originating the link + * @to: parameter RAM slot which is the link target + * + * The originating slot should not be part of any active DMA transfer. + */ +void edma_link(unsigned from, unsigned to) +{ + unsigned ctlr_from, ctlr_to; + + ctlr_from = EDMA_CTLR(from); + from = EDMA_CHAN_SLOT(from); + ctlr_to = EDMA_CTLR(to); + to = EDMA_CHAN_SLOT(to); + + if (from >= edma_cc[ctlr_from]->num_slots) + return; + if (to >= edma_cc[ctlr_to]->num_slots) + return; + edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000, + PARM_OFFSET(to)); +} +EXPORT_SYMBOL(edma_link); + +/** + * edma_unlink - cut link from one parameter RAM slot + * @from: parameter RAM slot originating the link + * + * The originating slot should not be part of any active DMA transfer. + * Its link is set to 0xffff. + */ +void edma_unlink(unsigned from) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(from); + from = EDMA_CHAN_SLOT(from); + + if (from >= edma_cc[ctlr]->num_slots) + return; + edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff); +} +EXPORT_SYMBOL(edma_unlink); + +/*-----------------------------------------------------------------------*/ + +/* Parameter RAM operations (ii) -- read/write whole parameter sets */ + +/** + * edma_write_slot - write parameter RAM data for slot + * @slot: number of parameter RAM slot being modified + * @param: data to be written into parameter RAM slot + * + * Use this to assign all parameters of a transfer at once. This + * allows more efficient setup of transfers than issuing multiple + * calls to set up those parameters in small pieces, and provides + * complete control over all transfer options. + */ +void edma_write_slot(unsigned slot, const struct edmacc_param *param) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot >= edma_cc[ctlr]->num_slots) + return; + memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param, + PARM_SIZE); +} +EXPORT_SYMBOL(edma_write_slot); + +/** + * edma_read_slot - read parameter RAM data from slot + * @slot: number of parameter RAM slot being copied + * @param: where to store copy of parameter RAM data + * + * Use this to read data from a parameter RAM slot, perhaps to + * save them as a template for later reuse. + */ +void edma_read_slot(unsigned slot, struct edmacc_param *param) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(slot); + slot = EDMA_CHAN_SLOT(slot); + + if (slot >= edma_cc[ctlr]->num_slots) + return; + memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot), + PARM_SIZE); +} +EXPORT_SYMBOL(edma_read_slot); + +/*-----------------------------------------------------------------------*/ + +/* Various EDMA channel control operations */ + +/** + * edma_pause - pause dma on a channel + * @channel: on which edma_start() has been called + * + * This temporarily disables EDMA hardware events on the specified channel, + * preventing them from triggering new transfers on its behalf + */ +void edma_pause(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + unsigned int mask = BIT(channel & 0x1f); + + edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask); + } +} +EXPORT_SYMBOL(edma_pause); + +/** + * edma_resume - resumes dma on a paused channel + * @channel: on which edma_pause() has been called + * + * This re-enables EDMA hardware events on the specified channel. + */ +void edma_resume(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + unsigned int mask = BIT(channel & 0x1f); + + edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask); + } +} +EXPORT_SYMBOL(edma_resume); + +/** + * edma_start - start dma on a channel + * @channel: channel being activated + * + * Channels with event associations will be triggered by their hardware + * events, and channels without such associations will be triggered by + * software. (At this writing there is no interface for using software + * triggers except with channels that don't support hardware triggers.) + * + * Returns zero on success, else negative errno. + */ +int edma_start(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + int j = channel >> 5; + unsigned int mask = BIT(channel & 0x1f); + + /* EDMA channels without event association */ + if (test_bit(channel, edma_cc[ctlr]->edma_unused)) { + pr_debug("EDMA: ESR%d %08x\n", j, + edma_shadow0_read_array(ctlr, SH_ESR, j)); + edma_shadow0_write_array(ctlr, SH_ESR, j, mask); + return 0; + } + + /* EDMA channel with event association */ + pr_debug("EDMA: ER%d %08x\n", j, + edma_shadow0_read_array(ctlr, SH_ER, j)); + /* Clear any pending event or error */ + edma_write_array(ctlr, EDMA_ECR, j, mask); + edma_write_array(ctlr, EDMA_EMCR, j, mask); + /* Clear any SER */ + edma_shadow0_write_array(ctlr, SH_SECR, j, mask); + edma_shadow0_write_array(ctlr, SH_EESR, j, mask); + pr_debug("EDMA: EER%d %08x\n", j, + edma_shadow0_read_array(ctlr, SH_EER, j)); + return 0; + } + + return -EINVAL; +} +EXPORT_SYMBOL(edma_start); + +/** + * edma_stop - stops dma on the channel passed + * @channel: channel being deactivated + * + * When @lch is a channel, any active transfer is paused and + * all pending hardware events are cleared. The current transfer + * may not be resumed, and the channel's Parameter RAM should be + * reinitialized before being reused. + */ +void edma_stop(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + int j = channel >> 5; + unsigned int mask = BIT(channel & 0x1f); + + edma_shadow0_write_array(ctlr, SH_EECR, j, mask); + edma_shadow0_write_array(ctlr, SH_ECR, j, mask); + edma_shadow0_write_array(ctlr, SH_SECR, j, mask); + edma_write_array(ctlr, EDMA_EMCR, j, mask); + + pr_debug("EDMA: EER%d %08x\n", j, + edma_shadow0_read_array(ctlr, SH_EER, j)); + + /* REVISIT: consider guarding against inappropriate event + * chaining by overwriting with dummy_paramset. + */ + } +} +EXPORT_SYMBOL(edma_stop); + +/****************************************************************************** + * + * It cleans ParamEntry qand bring back EDMA to initial state if media has + * been removed before EDMA has finished.It is usedful for removable media. + * Arguments: + * ch_no - channel no + * + * Return: zero on success, or corresponding error no on failure + * + * FIXME this should not be needed ... edma_stop() should suffice. + * + *****************************************************************************/ + +void edma_clean_channel(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel < edma_cc[ctlr]->num_channels) { + int j = (channel >> 5); + unsigned int mask = BIT(channel & 0x1f); + + pr_debug("EDMA: EMR%d %08x\n", j, + edma_read_array(ctlr, EDMA_EMR, j)); + edma_shadow0_write_array(ctlr, SH_ECR, j, mask); + /* Clear the corresponding EMR bits */ + edma_write_array(ctlr, EDMA_EMCR, j, mask); + /* Clear any SER */ + edma_shadow0_write_array(ctlr, SH_SECR, j, mask); + edma_write(ctlr, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0)); + } +} +EXPORT_SYMBOL(edma_clean_channel); + +/* + * edma_clear_event - clear an outstanding event on the DMA channel + * Arguments: + * channel - channel number + */ +void edma_clear_event(unsigned channel) +{ + unsigned ctlr; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + + if (channel >= edma_cc[ctlr]->num_channels) + return; + if (channel < 32) + edma_write(ctlr, EDMA_ECR, BIT(channel)); + else + edma_write(ctlr, EDMA_ECRH, BIT(channel - 32)); +} +EXPORT_SYMBOL(edma_clear_event); + +/*-----------------------------------------------------------------------*/ + +static int __init edma_probe(struct platform_device *pdev) +{ + struct edma_soc_info **info = pdev->dev.platform_data; + const s8 (*queue_priority_mapping)[2]; + const s8 (*queue_tc_mapping)[2]; + int i, j, off, ln, found = 0; + int status = -1; + const s16 (*rsv_chans)[2]; + const s16 (*rsv_slots)[2]; + int irq[EDMA_MAX_CC] = {0, 0}; + int err_irq[EDMA_MAX_CC] = {0, 0}; + struct resource *r[EDMA_MAX_CC] = {NULL}; + resource_size_t len[EDMA_MAX_CC]; + char res_name[10]; + char irq_name[10]; + + if (!info) + return -ENODEV; + + for (j = 0; j < EDMA_MAX_CC; j++) { + sprintf(res_name, "edma_cc%d", j); + r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM, + res_name); + if (!r[j] || !info[j]) { + if (found) + break; + else + return -ENODEV; + } else { + found = 1; + } + + len[j] = resource_size(r[j]); + + r[j] = request_mem_region(r[j]->start, len[j], + dev_name(&pdev->dev)); + if (!r[j]) { + status = -EBUSY; + goto fail1; + } + + edmacc_regs_base[j] = ioremap(r[j]->start, len[j]); + if (!edmacc_regs_base[j]) { + status = -EBUSY; + goto fail1; + } + + edma_cc[j] = kzalloc(sizeof(struct edma), GFP_KERNEL); + if (!edma_cc[j]) { + status = -ENOMEM; + goto fail1; + } + + edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel, + EDMA_MAX_DMACH); + edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot, + EDMA_MAX_PARAMENTRY); + edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc, + EDMA_MAX_CC); + + edma_cc[j]->default_queue = info[j]->default_queue; + + dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", + edmacc_regs_base[j]); + + for (i = 0; i < edma_cc[j]->num_slots; i++) + memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i), + &dummy_paramset, PARM_SIZE); + + /* Mark all channels as unused */ + memset(edma_cc[j]->edma_unused, 0xff, + sizeof(edma_cc[j]->edma_unused)); + + if (info[j]->rsv) { + + /* Clear the reserved channels in unused list */ + rsv_chans = info[j]->rsv->rsv_chans; + if (rsv_chans) { + for (i = 0; rsv_chans[i][0] != -1; i++) { + off = rsv_chans[i][0]; + ln = rsv_chans[i][1]; + clear_bits(off, ln, + edma_cc[j]->edma_unused); + } + } + + /* Set the reserved slots in inuse list */ + rsv_slots = info[j]->rsv->rsv_slots; + if (rsv_slots) { + for (i = 0; rsv_slots[i][0] != -1; i++) { + off = rsv_slots[i][0]; + ln = rsv_slots[i][1]; + set_bits(off, ln, + edma_cc[j]->edma_inuse); + } + } + } + + sprintf(irq_name, "edma%d", j); + irq[j] = platform_get_irq_byname(pdev, irq_name); + edma_cc[j]->irq_res_start = irq[j]; + status = request_irq(irq[j], dma_irq_handler, 0, "edma", + &pdev->dev); + if (status < 0) { + dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", + irq[j], status); + goto fail; + } + + sprintf(irq_name, "edma%d_err", j); + err_irq[j] = platform_get_irq_byname(pdev, irq_name); + edma_cc[j]->irq_res_end = err_irq[j]; + status = request_irq(err_irq[j], dma_ccerr_handler, 0, + "edma_error", &pdev->dev); + if (status < 0) { + dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", + err_irq[j], status); + goto fail; + } + + for (i = 0; i < edma_cc[j]->num_channels; i++) + map_dmach_queue(j, i, info[j]->default_queue); + + queue_tc_mapping = info[j]->queue_tc_mapping; + queue_priority_mapping = info[j]->queue_priority_mapping; + + /* Event queue to TC mapping */ + for (i = 0; queue_tc_mapping[i][0] != -1; i++) + map_queue_tc(j, queue_tc_mapping[i][0], + queue_tc_mapping[i][1]); + + /* Event queue priority mapping */ + for (i = 0; queue_priority_mapping[i][0] != -1; i++) + assign_priority_to_queue(j, + queue_priority_mapping[i][0], + queue_priority_mapping[i][1]); + + /* Map the channel to param entry if channel mapping logic + * exist + */ + if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST) + map_dmach_param(j); + + for (i = 0; i < info[j]->n_region; i++) { + edma_write_array2(j, EDMA_DRAE, i, 0, 0x0); + edma_write_array2(j, EDMA_DRAE, i, 1, 0x0); + edma_write_array(j, EDMA_QRAE, i, 0x0); + } + arch_num_cc++; + } + + if (tc_errs_handled) { + status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0, + "edma_tc0", &pdev->dev); + if (status < 0) { + dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", + IRQ_TCERRINT0, status); + return status; + } + status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0, + "edma_tc1", &pdev->dev); + if (status < 0) { + dev_dbg(&pdev->dev, "request_irq %d --> %d\n", + IRQ_TCERRINT, status); + return status; + } + } + + return 0; + +fail: + for (i = 0; i < EDMA_MAX_CC; i++) { + if (err_irq[i]) + free_irq(err_irq[i], &pdev->dev); + if (irq[i]) + free_irq(irq[i], &pdev->dev); + } +fail1: + for (i = 0; i < EDMA_MAX_CC; i++) { + if (r[i]) + release_mem_region(r[i]->start, len[i]); + if (edmacc_regs_base[i]) + iounmap(edmacc_regs_base[i]); + kfree(edma_cc[i]); + } + return status; +} + + +static struct platform_driver edma_driver = { + .driver.name = "edma", +}; + +static int __init edma_init(void) +{ + return platform_driver_probe(&edma_driver, edma_probe); +} +arch_initcall(edma_init); + diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index dd1ffccc75e9..63997a1128e6 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -5,7 +5,7 @@ # Common objects obj-y := time.o clock.o serial.o psc.o \ - dma.o usb.o common.o sram.o aemif.o + usb.o common.o sram.o aemif.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index ba798370fc96..78ea395d2aca 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,12 +26,12 @@ #include #include #include +#include #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index b4b7451a8434..a883043d0820 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -23,9 +23,9 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index cfb194df18ed..612a0856e9c5 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -18,10 +18,10 @@ #include #include #include +#include #include #include -#include #include #include "clock.h" diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index a7068a3aa9d3..90b83d00fe2b 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -19,9 +19,10 @@ #include #include #include -#include #include #include +#include + #include "davinci.h" #include "clock.h" @@ -34,6 +35,9 @@ #define DM365_MMCSD0_BASE 0x01D11000 #define DM365_MMCSD1_BASE 0x01D00000 +#define DAVINCI_DMA_MMCRXEVT 26 +#define DAVINCI_DMA_MMCTXEVT 27 + void __iomem *davinci_sysmod_base; void davinci_map_sysmod(void) diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index a11034a358f1..526cf7d06d0e 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include "davinci.h" #include "clock.h" diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 40fa4fee9331..c4b741173c06 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -18,11 +18,11 @@ #include #include #include +#include #include #include -#include #include #include #include diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 4d37d3e2a193..dd156d58fe64 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -12,11 +12,11 @@ #include #include #include +#include #include #include -#include #include #include #include diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index ac7b431c4c8e..6d52a321a8cf 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -13,11 +13,11 @@ #include #include #include +#include #include #include -#include #include #include #include diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c deleted file mode 100644 index 45b7c71d9cc1..000000000000 --- a/arch/arm/mach-davinci/dma.c +++ /dev/null @@ -1,1591 +0,0 @@ -/* - * EDMA3 support for DaVinci - * - * Copyright (C) 2006-2009 Texas Instruments. - * - * 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 -#include -#include -#include -#include -#include -#include - -#include - -/* Offsets matching "struct edmacc_param" */ -#define PARM_OPT 0x00 -#define PARM_SRC 0x04 -#define PARM_A_B_CNT 0x08 -#define PARM_DST 0x0c -#define PARM_SRC_DST_BIDX 0x10 -#define PARM_LINK_BCNTRLD 0x14 -#define PARM_SRC_DST_CIDX 0x18 -#define PARM_CCNT 0x1c - -#define PARM_SIZE 0x20 - -/* Offsets for EDMA CC global channel registers and their shadows */ -#define SH_ER 0x00 /* 64 bits */ -#define SH_ECR 0x08 /* 64 bits */ -#define SH_ESR 0x10 /* 64 bits */ -#define SH_CER 0x18 /* 64 bits */ -#define SH_EER 0x20 /* 64 bits */ -#define SH_EECR 0x28 /* 64 bits */ -#define SH_EESR 0x30 /* 64 bits */ -#define SH_SER 0x38 /* 64 bits */ -#define SH_SECR 0x40 /* 64 bits */ -#define SH_IER 0x50 /* 64 bits */ -#define SH_IECR 0x58 /* 64 bits */ -#define SH_IESR 0x60 /* 64 bits */ -#define SH_IPR 0x68 /* 64 bits */ -#define SH_ICR 0x70 /* 64 bits */ -#define SH_IEVAL 0x78 -#define SH_QER 0x80 -#define SH_QEER 0x84 -#define SH_QEECR 0x88 -#define SH_QEESR 0x8c -#define SH_QSER 0x90 -#define SH_QSECR 0x94 -#define SH_SIZE 0x200 - -/* Offsets for EDMA CC global registers */ -#define EDMA_REV 0x0000 -#define EDMA_CCCFG 0x0004 -#define EDMA_QCHMAP 0x0200 /* 8 registers */ -#define EDMA_DMAQNUM 0x0240 /* 8 registers (4 on OMAP-L1xx) */ -#define EDMA_QDMAQNUM 0x0260 -#define EDMA_QUETCMAP 0x0280 -#define EDMA_QUEPRI 0x0284 -#define EDMA_EMR 0x0300 /* 64 bits */ -#define EDMA_EMCR 0x0308 /* 64 bits */ -#define EDMA_QEMR 0x0310 -#define EDMA_QEMCR 0x0314 -#define EDMA_CCERR 0x0318 -#define EDMA_CCERRCLR 0x031c -#define EDMA_EEVAL 0x0320 -#define EDMA_DRAE 0x0340 /* 4 x 64 bits*/ -#define EDMA_QRAE 0x0380 /* 4 registers */ -#define EDMA_QUEEVTENTRY 0x0400 /* 2 x 16 registers */ -#define EDMA_QSTAT 0x0600 /* 2 registers */ -#define EDMA_QWMTHRA 0x0620 -#define EDMA_QWMTHRB 0x0624 -#define EDMA_CCSTAT 0x0640 - -#define EDMA_M 0x1000 /* global channel registers */ -#define EDMA_ECR 0x1008 -#define EDMA_ECRH 0x100C -#define EDMA_SHADOW0 0x2000 /* 4 regions shadowing global channels */ -#define EDMA_PARM 0x4000 /* 128 param entries */ - -#define PARM_OFFSET(param_no) (EDMA_PARM + ((param_no) << 5)) - -#define EDMA_DCHMAP 0x0100 /* 64 registers */ -#define CHMAP_EXIST BIT(24) - -#define EDMA_MAX_DMACH 64 -#define EDMA_MAX_PARAMENTRY 512 - -/*****************************************************************************/ - -static void __iomem *edmacc_regs_base[EDMA_MAX_CC]; - -static inline unsigned int edma_read(unsigned ctlr, int offset) -{ - return (unsigned int)__raw_readl(edmacc_regs_base[ctlr] + offset); -} - -static inline void edma_write(unsigned ctlr, int offset, int val) -{ - __raw_writel(val, edmacc_regs_base[ctlr] + offset); -} -static inline void edma_modify(unsigned ctlr, int offset, unsigned and, - unsigned or) -{ - unsigned val = edma_read(ctlr, offset); - val &= and; - val |= or; - edma_write(ctlr, offset, val); -} -static inline void edma_and(unsigned ctlr, int offset, unsigned and) -{ - unsigned val = edma_read(ctlr, offset); - val &= and; - edma_write(ctlr, offset, val); -} -static inline void edma_or(unsigned ctlr, int offset, unsigned or) -{ - unsigned val = edma_read(ctlr, offset); - val |= or; - edma_write(ctlr, offset, val); -} -static inline unsigned int edma_read_array(unsigned ctlr, int offset, int i) -{ - return edma_read(ctlr, offset + (i << 2)); -} -static inline void edma_write_array(unsigned ctlr, int offset, int i, - unsigned val) -{ - edma_write(ctlr, offset + (i << 2), val); -} -static inline void edma_modify_array(unsigned ctlr, int offset, int i, - unsigned and, unsigned or) -{ - edma_modify(ctlr, offset + (i << 2), and, or); -} -static inline void edma_or_array(unsigned ctlr, int offset, int i, unsigned or) -{ - edma_or(ctlr, offset + (i << 2), or); -} -static inline void edma_or_array2(unsigned ctlr, int offset, int i, int j, - unsigned or) -{ - edma_or(ctlr, offset + ((i*2 + j) << 2), or); -} -static inline void edma_write_array2(unsigned ctlr, int offset, int i, int j, - unsigned val) -{ - edma_write(ctlr, offset + ((i*2 + j) << 2), val); -} -static inline unsigned int edma_shadow0_read(unsigned ctlr, int offset) -{ - return edma_read(ctlr, EDMA_SHADOW0 + offset); -} -static inline unsigned int edma_shadow0_read_array(unsigned ctlr, int offset, - int i) -{ - return edma_read(ctlr, EDMA_SHADOW0 + offset + (i << 2)); -} -static inline void edma_shadow0_write(unsigned ctlr, int offset, unsigned val) -{ - edma_write(ctlr, EDMA_SHADOW0 + offset, val); -} -static inline void edma_shadow0_write_array(unsigned ctlr, int offset, int i, - unsigned val) -{ - edma_write(ctlr, EDMA_SHADOW0 + offset + (i << 2), val); -} -static inline unsigned int edma_parm_read(unsigned ctlr, int offset, - int param_no) -{ - return edma_read(ctlr, EDMA_PARM + offset + (param_no << 5)); -} -static inline void edma_parm_write(unsigned ctlr, int offset, int param_no, - unsigned val) -{ - edma_write(ctlr, EDMA_PARM + offset + (param_no << 5), val); -} -static inline void edma_parm_modify(unsigned ctlr, int offset, int param_no, - unsigned and, unsigned or) -{ - edma_modify(ctlr, EDMA_PARM + offset + (param_no << 5), and, or); -} -static inline void edma_parm_and(unsigned ctlr, int offset, int param_no, - unsigned and) -{ - edma_and(ctlr, EDMA_PARM + offset + (param_no << 5), and); -} -static inline void edma_parm_or(unsigned ctlr, int offset, int param_no, - unsigned or) -{ - edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or); -} - -static inline void set_bits(int offset, int len, unsigned long *p) -{ - for (; len > 0; len--) - set_bit(offset + (len - 1), p); -} - -static inline void clear_bits(int offset, int len, unsigned long *p) -{ - for (; len > 0; len--) - clear_bit(offset + (len - 1), p); -} - -/*****************************************************************************/ - -/* actual number of DMA channels and slots on this silicon */ -struct edma { - /* how many dma resources of each type */ - unsigned num_channels; - unsigned num_region; - unsigned num_slots; - unsigned num_tc; - unsigned num_cc; - enum dma_event_q default_queue; - - /* list of channels with no even trigger; terminated by "-1" */ - const s8 *noevent; - - /* The edma_inuse bit for each PaRAM slot is clear unless the - * channel is in use ... by ARM or DSP, for QDMA, or whatever. - */ - DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY); - - /* The edma_unused bit for each channel is clear unless - * it is not being used on this platform. It uses a bit - * of SOC-specific initialization code. - */ - DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH); - - unsigned irq_res_start; - unsigned irq_res_end; - - struct dma_interrupt_data { - void (*callback)(unsigned channel, unsigned short ch_status, - void *data); - void *data; - } intr_data[EDMA_MAX_DMACH]; -}; - -static struct edma *edma_cc[EDMA_MAX_CC]; -static int arch_num_cc; - -/* dummy param set used to (re)initialize parameter RAM slots */ -static const struct edmacc_param dummy_paramset = { - .link_bcntrld = 0xffff, - .ccnt = 1, -}; - -/*****************************************************************************/ - -static void map_dmach_queue(unsigned ctlr, unsigned ch_no, - enum dma_event_q queue_no) -{ - int bit = (ch_no & 0x7) * 4; - - /* default to low priority queue */ - if (queue_no == EVENTQ_DEFAULT) - queue_no = edma_cc[ctlr]->default_queue; - - queue_no &= 7; - edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3), - ~(0x7 << bit), queue_no << bit); -} - -static void __init map_queue_tc(unsigned ctlr, int queue_no, int tc_no) -{ - int bit = queue_no * 4; - edma_modify(ctlr, EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit)); -} - -static void __init assign_priority_to_queue(unsigned ctlr, int queue_no, - int priority) -{ - int bit = queue_no * 4; - edma_modify(ctlr, EDMA_QUEPRI, ~(0x7 << bit), - ((priority & 0x7) << bit)); -} - -/** - * map_dmach_param - Maps channel number to param entry number - * - * This maps the dma channel number to param entry numberter. In - * other words using the DMA channel mapping registers a param entry - * can be mapped to any channel - * - * Callers are responsible for ensuring the channel mapping logic is - * included in that particular EDMA variant (Eg : dm646x) - * - */ -static void __init map_dmach_param(unsigned ctlr) -{ - int i; - for (i = 0; i < EDMA_MAX_DMACH; i++) - edma_write_array(ctlr, EDMA_DCHMAP , i , (i << 5)); -} - -static inline void -setup_dma_interrupt(unsigned lch, - void (*callback)(unsigned channel, u16 ch_status, void *data), - void *data) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(lch); - lch = EDMA_CHAN_SLOT(lch); - - if (!callback) - edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5, - BIT(lch & 0x1f)); - - edma_cc[ctlr]->intr_data[lch].callback = callback; - edma_cc[ctlr]->intr_data[lch].data = data; - - if (callback) { - edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5, - BIT(lch & 0x1f)); - edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5, - BIT(lch & 0x1f)); - } -} - -static int irq2ctlr(int irq) -{ - if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end) - return 0; - else if (irq >= edma_cc[1]->irq_res_start && - irq <= edma_cc[1]->irq_res_end) - return 1; - - return -1; -} - -/****************************************************************************** - * - * DMA interrupt handler - * - *****************************************************************************/ -static irqreturn_t dma_irq_handler(int irq, void *data) -{ - int ctlr; - u32 sh_ier; - u32 sh_ipr; - u32 bank; - - ctlr = irq2ctlr(irq); - if (ctlr < 0) - return IRQ_NONE; - - dev_dbg(data, "dma_irq_handler\n"); - - sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0); - if (!sh_ipr) { - sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 1); - if (!sh_ipr) - return IRQ_NONE; - sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 1); - bank = 1; - } else { - sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 0); - bank = 0; - } - - do { - u32 slot; - u32 channel; - - dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr); - - slot = __ffs(sh_ipr); - sh_ipr &= ~(BIT(slot)); - - if (sh_ier & BIT(slot)) { - channel = (bank << 5) | slot; - /* Clear the corresponding IPR bits */ - edma_shadow0_write_array(ctlr, SH_ICR, bank, - BIT(slot)); - if (edma_cc[ctlr]->intr_data[channel].callback) - edma_cc[ctlr]->intr_data[channel].callback( - channel, DMA_COMPLETE, - edma_cc[ctlr]->intr_data[channel].data); - } - } while (sh_ipr); - - edma_shadow0_write(ctlr, SH_IEVAL, 1); - return IRQ_HANDLED; -} - -/****************************************************************************** - * - * DMA error interrupt handler - * - *****************************************************************************/ -static irqreturn_t dma_ccerr_handler(int irq, void *data) -{ - int i; - int ctlr; - unsigned int cnt = 0; - - ctlr = irq2ctlr(irq); - if (ctlr < 0) - return IRQ_NONE; - - dev_dbg(data, "dma_ccerr_handler\n"); - - if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) && - (edma_read_array(ctlr, EDMA_EMR, 1) == 0) && - (edma_read(ctlr, EDMA_QEMR) == 0) && - (edma_read(ctlr, EDMA_CCERR) == 0)) - return IRQ_NONE; - - while (1) { - int j = -1; - if (edma_read_array(ctlr, EDMA_EMR, 0)) - j = 0; - else if (edma_read_array(ctlr, EDMA_EMR, 1)) - j = 1; - if (j >= 0) { - dev_dbg(data, "EMR%d %08x\n", j, - edma_read_array(ctlr, EDMA_EMR, j)); - for (i = 0; i < 32; i++) { - int k = (j << 5) + i; - if (edma_read_array(ctlr, EDMA_EMR, j) & - BIT(i)) { - /* Clear the corresponding EMR bits */ - edma_write_array(ctlr, EDMA_EMCR, j, - BIT(i)); - /* Clear any SER */ - edma_shadow0_write_array(ctlr, SH_SECR, - j, BIT(i)); - if (edma_cc[ctlr]->intr_data[k]. - callback) { - edma_cc[ctlr]->intr_data[k]. - callback(k, - DMA_CC_ERROR, - edma_cc[ctlr]->intr_data - [k].data); - } - } - } - } else if (edma_read(ctlr, EDMA_QEMR)) { - dev_dbg(data, "QEMR %02x\n", - edma_read(ctlr, EDMA_QEMR)); - for (i = 0; i < 8; i++) { - if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) { - /* Clear the corresponding IPR bits */ - edma_write(ctlr, EDMA_QEMCR, BIT(i)); - edma_shadow0_write(ctlr, SH_QSECR, - BIT(i)); - - /* NOTE: not reported!! */ - } - } - } else if (edma_read(ctlr, EDMA_CCERR)) { - dev_dbg(data, "CCERR %08x\n", - edma_read(ctlr, EDMA_CCERR)); - /* FIXME: CCERR.BIT(16) ignored! much better - * to just write CCERRCLR with CCERR value... - */ - for (i = 0; i < 8; i++) { - if (edma_read(ctlr, EDMA_CCERR) & BIT(i)) { - /* Clear the corresponding IPR bits */ - edma_write(ctlr, EDMA_CCERRCLR, BIT(i)); - - /* NOTE: not reported!! */ - } - } - } - if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) && - (edma_read_array(ctlr, EDMA_EMR, 1) == 0) && - (edma_read(ctlr, EDMA_QEMR) == 0) && - (edma_read(ctlr, EDMA_CCERR) == 0)) - break; - cnt++; - if (cnt > 10) - break; - } - edma_write(ctlr, EDMA_EEVAL, 1); - return IRQ_HANDLED; -} - -/****************************************************************************** - * - * Transfer controller error interrupt handlers - * - *****************************************************************************/ - -#define tc_errs_handled false /* disabled as long as they're NOPs */ - -static irqreturn_t dma_tc0err_handler(int irq, void *data) -{ - dev_dbg(data, "dma_tc0err_handler\n"); - return IRQ_HANDLED; -} - -static irqreturn_t dma_tc1err_handler(int irq, void *data) -{ - dev_dbg(data, "dma_tc1err_handler\n"); - return IRQ_HANDLED; -} - -static int reserve_contiguous_slots(int ctlr, unsigned int id, - unsigned int num_slots, - unsigned int start_slot) -{ - int i, j; - unsigned int count = num_slots; - int stop_slot = start_slot; - DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY); - - for (i = start_slot; i < edma_cc[ctlr]->num_slots; ++i) { - j = EDMA_CHAN_SLOT(i); - if (!test_and_set_bit(j, edma_cc[ctlr]->edma_inuse)) { - /* Record our current beginning slot */ - if (count == num_slots) - stop_slot = i; - - count--; - set_bit(j, tmp_inuse); - - if (count == 0) - break; - } else { - clear_bit(j, tmp_inuse); - - if (id == EDMA_CONT_PARAMS_FIXED_EXACT) { - stop_slot = i; - break; - } else { - count = num_slots; - } - } - } - - /* - * We have to clear any bits that we set - * if we run out parameter RAM slots, i.e we do find a set - * of contiguous parameter RAM slots but do not find the exact number - * requested as we may reach the total number of parameter RAM slots - */ - if (i == edma_cc[ctlr]->num_slots) - stop_slot = i; - - j = start_slot; - for_each_set_bit_from(j, tmp_inuse, stop_slot) - clear_bit(j, edma_cc[ctlr]->edma_inuse); - - if (count) - return -EBUSY; - - for (j = i - num_slots + 1; j <= i; ++j) - memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j), - &dummy_paramset, PARM_SIZE); - - return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1); -} - -static int prepare_unused_channel_list(struct device *dev, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - int i, ctlr; - - for (i = 0; i < pdev->num_resources; i++) { - if ((pdev->resource[i].flags & IORESOURCE_DMA) && - (int)pdev->resource[i].start >= 0) { - ctlr = EDMA_CTLR(pdev->resource[i].start); - clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start), - edma_cc[ctlr]->edma_unused); - } - } - - return 0; -} - -/*-----------------------------------------------------------------------*/ - -static bool unused_chan_list_done; - -/* Resource alloc/free: dma channels, parameter RAM slots */ - -/** - * edma_alloc_channel - allocate DMA channel and paired parameter RAM - * @channel: specific channel to allocate; negative for "any unmapped channel" - * @callback: optional; to be issued on DMA completion or errors - * @data: passed to callback - * @eventq_no: an EVENTQ_* constant, used to choose which Transfer - * Controller (TC) executes requests using this channel. Use - * EVENTQ_DEFAULT unless you really need a high priority queue. - * - * This allocates a DMA channel and its associated parameter RAM slot. - * The parameter RAM is initialized to hold a dummy transfer. - * - * Normal use is to pass a specific channel number as @channel, to make - * use of hardware events mapped to that channel. When the channel will - * be used only for software triggering or event chaining, channels not - * mapped to hardware events (or mapped to unused events) are preferable. - * - * DMA transfers start from a channel using edma_start(), or by - * chaining. When the transfer described in that channel's parameter RAM - * slot completes, that slot's data may be reloaded through a link. - * - * DMA errors are only reported to the @callback associated with the - * channel driving that transfer, but transfer completion callbacks can - * be sent to another channel under control of the TCC field in - * the option word of the transfer's parameter RAM set. Drivers must not - * use DMA transfer completion callbacks for channels they did not allocate. - * (The same applies to TCC codes used in transfer chaining.) - * - * Returns the number of the channel, else negative errno. - */ -int edma_alloc_channel(int channel, - void (*callback)(unsigned channel, u16 ch_status, void *data), - void *data, - enum dma_event_q eventq_no) -{ - unsigned i, done = 0, ctlr = 0; - int ret = 0; - - if (!unused_chan_list_done) { - /* - * Scan all the platform devices to find out the EDMA channels - * used and clear them in the unused list, making the rest - * available for ARM usage. - */ - ret = bus_for_each_dev(&platform_bus_type, NULL, NULL, - prepare_unused_channel_list); - if (ret < 0) - return ret; - - unused_chan_list_done = true; - } - - if (channel >= 0) { - ctlr = EDMA_CTLR(channel); - channel = EDMA_CHAN_SLOT(channel); - } - - if (channel < 0) { - for (i = 0; i < arch_num_cc; i++) { - channel = 0; - for (;;) { - channel = find_next_bit(edma_cc[i]->edma_unused, - edma_cc[i]->num_channels, - channel); - if (channel == edma_cc[i]->num_channels) - break; - if (!test_and_set_bit(channel, - edma_cc[i]->edma_inuse)) { - done = 1; - ctlr = i; - break; - } - channel++; - } - if (done) - break; - } - if (!done) - return -ENOMEM; - } else if (channel >= edma_cc[ctlr]->num_channels) { - return -EINVAL; - } else if (test_and_set_bit(channel, edma_cc[ctlr]->edma_inuse)) { - return -EBUSY; - } - - /* ensure access through shadow region 0 */ - edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f)); - - /* ensure no events are pending */ - edma_stop(EDMA_CTLR_CHAN(ctlr, channel)); - memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel), - &dummy_paramset, PARM_SIZE); - - if (callback) - setup_dma_interrupt(EDMA_CTLR_CHAN(ctlr, channel), - callback, data); - - map_dmach_queue(ctlr, channel, eventq_no); - - return EDMA_CTLR_CHAN(ctlr, channel); -} -EXPORT_SYMBOL(edma_alloc_channel); - - -/** - * edma_free_channel - deallocate DMA channel - * @channel: dma channel returned from edma_alloc_channel() - * - * This deallocates the DMA channel and associated parameter RAM slot - * allocated by edma_alloc_channel(). - * - * Callers are responsible for ensuring the channel is inactive, and - * will not be reactivated by linking, chaining, or software calls to - * edma_start(). - */ -void edma_free_channel(unsigned channel) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(channel); - channel = EDMA_CHAN_SLOT(channel); - - if (channel >= edma_cc[ctlr]->num_channels) - return; - - setup_dma_interrupt(channel, NULL, NULL); - /* REVISIT should probably take out of shadow region 0 */ - - memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel), - &dummy_paramset, PARM_SIZE); - clear_bit(channel, edma_cc[ctlr]->edma_inuse); -} -EXPORT_SYMBOL(edma_free_channel); - -/** - * edma_alloc_slot - allocate DMA parameter RAM - * @slot: specific slot to allocate; negative for "any unused slot" - * - * This allocates a parameter RAM slot, initializing it to hold a - * dummy transfer. Slots allocated using this routine have not been - * mapped to a hardware DMA channel, and will normally be used by - * linking to them from a slot associated with a DMA channel. - * - * Normal use is to pass EDMA_SLOT_ANY as the @slot, but specific - * slots may be allocated on behalf of DSP firmware. - * - * Returns the number of the slot, else negative errno. - */ -int edma_alloc_slot(unsigned ctlr, int slot) -{ - if (!edma_cc[ctlr]) - return -EINVAL; - - if (slot >= 0) - slot = EDMA_CHAN_SLOT(slot); - - if (slot < 0) { - slot = edma_cc[ctlr]->num_channels; - for (;;) { - slot = find_next_zero_bit(edma_cc[ctlr]->edma_inuse, - edma_cc[ctlr]->num_slots, slot); - if (slot == edma_cc[ctlr]->num_slots) - return -ENOMEM; - if (!test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) - break; - } - } else if (slot < edma_cc[ctlr]->num_channels || - slot >= edma_cc[ctlr]->num_slots) { - return -EINVAL; - } else if (test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) { - return -EBUSY; - } - - memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), - &dummy_paramset, PARM_SIZE); - - return EDMA_CTLR_CHAN(ctlr, slot); -} -EXPORT_SYMBOL(edma_alloc_slot); - -/** - * edma_free_slot - deallocate DMA parameter RAM - * @slot: parameter RAM slot returned from edma_alloc_slot() - * - * This deallocates the parameter RAM slot allocated by edma_alloc_slot(). - * Callers are responsible for ensuring the slot is inactive, and will - * not be activated. - */ -void edma_free_slot(unsigned slot) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - if (slot < edma_cc[ctlr]->num_channels || - slot >= edma_cc[ctlr]->num_slots) - return; - - memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), - &dummy_paramset, PARM_SIZE); - clear_bit(slot, edma_cc[ctlr]->edma_inuse); -} -EXPORT_SYMBOL(edma_free_slot); - - -/** - * edma_alloc_cont_slots- alloc contiguous parameter RAM slots - * The API will return the starting point of a set of - * contiguous parameter RAM slots that have been requested - * - * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT - * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT - * @count: number of contiguous Paramter RAM slots - * @slot - the start value of Parameter RAM slot that should be passed if id - * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT - * - * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of - * contiguous Parameter RAM slots from parameter RAM 64 in the case of - * DaVinci SOCs and 32 in the case of DA8xx SOCs. - * - * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a - * set of contiguous parameter RAM slots from the "slot" that is passed as an - * argument to the API. - * - * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries - * starts looking for a set of contiguous parameter RAMs from the "slot" - * that is passed as an argument to the API. On failure the API will try to - * find a set of contiguous Parameter RAM slots from the remaining Parameter - * RAM slots - */ -int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) -{ - /* - * The start slot requested should be greater than - * the number of channels and lesser than the total number - * of slots - */ - if ((id != EDMA_CONT_PARAMS_ANY) && - (slot < edma_cc[ctlr]->num_channels || - slot >= edma_cc[ctlr]->num_slots)) - return -EINVAL; - - /* - * The number of parameter RAM slots requested cannot be less than 1 - * and cannot be more than the number of slots minus the number of - * channels - */ - if (count < 1 || count > - (edma_cc[ctlr]->num_slots - edma_cc[ctlr]->num_channels)) - return -EINVAL; - - switch (id) { - case EDMA_CONT_PARAMS_ANY: - return reserve_contiguous_slots(ctlr, id, count, - edma_cc[ctlr]->num_channels); - case EDMA_CONT_PARAMS_FIXED_EXACT: - case EDMA_CONT_PARAMS_FIXED_NOT_EXACT: - return reserve_contiguous_slots(ctlr, id, count, slot); - default: - return -EINVAL; - } - -} -EXPORT_SYMBOL(edma_alloc_cont_slots); - -/** - * edma_free_cont_slots - deallocate DMA parameter RAM slots - * @slot: first parameter RAM of a set of parameter RAM slots to be freed - * @count: the number of contiguous parameter RAM slots to be freed - * - * This deallocates the parameter RAM slots allocated by - * edma_alloc_cont_slots. - * Callers/applications need to keep track of sets of contiguous - * parameter RAM slots that have been allocated using the edma_alloc_cont_slots - * API. - * Callers are responsible for ensuring the slots are inactive, and will - * not be activated. - */ -int edma_free_cont_slots(unsigned slot, int count) -{ - unsigned ctlr, slot_to_free; - int i; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - if (slot < edma_cc[ctlr]->num_channels || - slot >= edma_cc[ctlr]->num_slots || - count < 1) - return -EINVAL; - - for (i = slot; i < slot + count; ++i) { - ctlr = EDMA_CTLR(i); - slot_to_free = EDMA_CHAN_SLOT(i); - - memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free), - &dummy_paramset, PARM_SIZE); - clear_bit(slot_to_free, edma_cc[ctlr]->edma_inuse); - } - - return 0; -} -EXPORT_SYMBOL(edma_free_cont_slots); - -/*-----------------------------------------------------------------------*/ - -/* Parameter RAM operations (i) -- read/write partial slots */ - -/** - * edma_set_src - set initial DMA source address in parameter RAM slot - * @slot: parameter RAM slot being configured - * @src_port: physical address of source (memory, controller FIFO, etc) - * @addressMode: INCR, except in very rare cases - * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the - * width to use when addressing the fifo (e.g. W8BIT, W32BIT) - * - * Note that the source address is modified during the DMA transfer - * according to edma_set_src_index(). - */ -void edma_set_src(unsigned slot, dma_addr_t src_port, - enum address_mode mode, enum fifo_width width) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - if (slot < edma_cc[ctlr]->num_slots) { - unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot); - - if (mode) { - /* set SAM and program FWID */ - i = (i & ~(EDMA_FWID)) | (SAM | ((width & 0x7) << 8)); - } else { - /* clear SAM */ - i &= ~SAM; - } - edma_parm_write(ctlr, PARM_OPT, slot, i); - - /* set the source port address - in source register of param structure */ - edma_parm_write(ctlr, PARM_SRC, slot, src_port); - } -} -EXPORT_SYMBOL(edma_set_src); - -/** - * edma_set_dest - set initial DMA destination address in parameter RAM slot - * @slot: parameter RAM slot being configured - * @dest_port: physical address of destination (memory, controller FIFO, etc) - * @addressMode: INCR, except in very rare cases - * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the - * width to use when addressing the fifo (e.g. W8BIT, W32BIT) - * - * Note that the destination address is modified during the DMA transfer - * according to edma_set_dest_index(). - */ -void edma_set_dest(unsigned slot, dma_addr_t dest_port, - enum address_mode mode, enum fifo_width width) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - if (slot < edma_cc[ctlr]->num_slots) { - unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot); - - if (mode) { - /* set DAM and program FWID */ - i = (i & ~(EDMA_FWID)) | (DAM | ((width & 0x7) << 8)); - } else { - /* clear DAM */ - i &= ~DAM; - } - edma_parm_write(ctlr, PARM_OPT, slot, i); - /* set the destination port address - in dest register of param structure */ - edma_parm_write(ctlr, PARM_DST, slot, dest_port); - } -} -EXPORT_SYMBOL(edma_set_dest); - -/** - * edma_get_position - returns the current transfer points - * @slot: parameter RAM slot being examined - * @src: pointer to source port position - * @dst: pointer to destination port position - * - * Returns current source and destination addresses for a particular - * parameter RAM slot. Its channel should not be active when this is called. - */ -void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst) -{ - struct edmacc_param temp; - unsigned ctlr; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - edma_read_slot(EDMA_CTLR_CHAN(ctlr, slot), &temp); - if (src != NULL) - *src = temp.src; - if (dst != NULL) - *dst = temp.dst; -} -EXPORT_SYMBOL(edma_get_position); - -/** - * edma_set_src_index - configure DMA source address indexing - * @slot: parameter RAM slot being configured - * @src_bidx: byte offset between source arrays in a frame - * @src_cidx: byte offset between source frames in a block - * - * Offsets are specified to support either contiguous or discontiguous - * memory transfers, or repeated access to a hardware register, as needed. - * When accessing hardware registers, both offsets are normally zero. - */ -void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - if (slot < edma_cc[ctlr]->num_slots) { - edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot, - 0xffff0000, src_bidx); - edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot, - 0xffff0000, src_cidx); - } -} -EXPORT_SYMBOL(edma_set_src_index); - -/** - * edma_set_dest_index - configure DMA destination address indexing - * @slot: parameter RAM slot being configured - * @dest_bidx: byte offset between destination arrays in a frame - * @dest_cidx: byte offset between destination frames in a block - * - * Offsets are specified to support either contiguous or discontiguous - * memory transfers, or repeated access to a hardware register, as needed. - * When accessing hardware registers, both offsets are normally zero. - */ -void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - if (slot < edma_cc[ctlr]->num_slots) { - edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot, - 0x0000ffff, dest_bidx << 16); - edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot, - 0x0000ffff, dest_cidx << 16); - } -} -EXPORT_SYMBOL(edma_set_dest_index); - -/** - * edma_set_transfer_params - configure DMA transfer parameters - * @slot: parameter RAM slot being configured - * @acnt: how many bytes per array (at least one) - * @bcnt: how many arrays per frame (at least one) - * @ccnt: how many frames per block (at least one) - * @bcnt_rld: used only for A-Synchronized transfers; this specifies - * the value to reload into bcnt when it decrements to zero - * @sync_mode: ASYNC or ABSYNC - * - * See the EDMA3 documentation to understand how to configure and link - * transfers using the fields in PaRAM slots. If you are not doing it - * all at once with edma_write_slot(), you will use this routine - * plus two calls each for source and destination, setting the initial - * address and saying how to index that address. - * - * An example of an A-Synchronized transfer is a serial link using a - * single word shift register. In that case, @acnt would be equal to - * that word size; the serial controller issues a DMA synchronization - * event to transfer each word, and memory access by the DMA transfer - * controller will be word-at-a-time. - * - * An example of an AB-Synchronized transfer is a device using a FIFO. - * In that case, @acnt equals the FIFO width and @bcnt equals its depth. - * The controller with the FIFO issues DMA synchronization events when - * the FIFO threshold is reached, and the DMA transfer controller will - * transfer one frame to (or from) the FIFO. It will probably use - * efficient burst modes to access memory. - */ -void edma_set_transfer_params(unsigned slot, - u16 acnt, u16 bcnt, u16 ccnt, - u16 bcnt_rld, enum sync_dimension sync_mode) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - if (slot < edma_cc[ctlr]->num_slots) { - edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot, - 0x0000ffff, bcnt_rld << 16); - if (sync_mode == ASYNC) - edma_parm_and(ctlr, PARM_OPT, slot, ~SYNCDIM); - else - edma_parm_or(ctlr, PARM_OPT, slot, SYNCDIM); - /* Set the acount, bcount, ccount registers */ - edma_parm_write(ctlr, PARM_A_B_CNT, slot, (bcnt << 16) | acnt); - edma_parm_write(ctlr, PARM_CCNT, slot, ccnt); - } -} -EXPORT_SYMBOL(edma_set_transfer_params); - -/** - * edma_link - link one parameter RAM slot to another - * @from: parameter RAM slot originating the link - * @to: parameter RAM slot which is the link target - * - * The originating slot should not be part of any active DMA transfer. - */ -void edma_link(unsigned from, unsigned to) -{ - unsigned ctlr_from, ctlr_to; - - ctlr_from = EDMA_CTLR(from); - from = EDMA_CHAN_SLOT(from); - ctlr_to = EDMA_CTLR(to); - to = EDMA_CHAN_SLOT(to); - - if (from >= edma_cc[ctlr_from]->num_slots) - return; - if (to >= edma_cc[ctlr_to]->num_slots) - return; - edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000, - PARM_OFFSET(to)); -} -EXPORT_SYMBOL(edma_link); - -/** - * edma_unlink - cut link from one parameter RAM slot - * @from: parameter RAM slot originating the link - * - * The originating slot should not be part of any active DMA transfer. - * Its link is set to 0xffff. - */ -void edma_unlink(unsigned from) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(from); - from = EDMA_CHAN_SLOT(from); - - if (from >= edma_cc[ctlr]->num_slots) - return; - edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff); -} -EXPORT_SYMBOL(edma_unlink); - -/*-----------------------------------------------------------------------*/ - -/* Parameter RAM operations (ii) -- read/write whole parameter sets */ - -/** - * edma_write_slot - write parameter RAM data for slot - * @slot: number of parameter RAM slot being modified - * @param: data to be written into parameter RAM slot - * - * Use this to assign all parameters of a transfer at once. This - * allows more efficient setup of transfers than issuing multiple - * calls to set up those parameters in small pieces, and provides - * complete control over all transfer options. - */ -void edma_write_slot(unsigned slot, const struct edmacc_param *param) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - if (slot >= edma_cc[ctlr]->num_slots) - return; - memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param, - PARM_SIZE); -} -EXPORT_SYMBOL(edma_write_slot); - -/** - * edma_read_slot - read parameter RAM data from slot - * @slot: number of parameter RAM slot being copied - * @param: where to store copy of parameter RAM data - * - * Use this to read data from a parameter RAM slot, perhaps to - * save them as a template for later reuse. - */ -void edma_read_slot(unsigned slot, struct edmacc_param *param) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(slot); - slot = EDMA_CHAN_SLOT(slot); - - if (slot >= edma_cc[ctlr]->num_slots) - return; - memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot), - PARM_SIZE); -} -EXPORT_SYMBOL(edma_read_slot); - -/*-----------------------------------------------------------------------*/ - -/* Various EDMA channel control operations */ - -/** - * edma_pause - pause dma on a channel - * @channel: on which edma_start() has been called - * - * This temporarily disables EDMA hardware events on the specified channel, - * preventing them from triggering new transfers on its behalf - */ -void edma_pause(unsigned channel) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(channel); - channel = EDMA_CHAN_SLOT(channel); - - if (channel < edma_cc[ctlr]->num_channels) { - unsigned int mask = BIT(channel & 0x1f); - - edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask); - } -} -EXPORT_SYMBOL(edma_pause); - -/** - * edma_resume - resumes dma on a paused channel - * @channel: on which edma_pause() has been called - * - * This re-enables EDMA hardware events on the specified channel. - */ -void edma_resume(unsigned channel) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(channel); - channel = EDMA_CHAN_SLOT(channel); - - if (channel < edma_cc[ctlr]->num_channels) { - unsigned int mask = BIT(channel & 0x1f); - - edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask); - } -} -EXPORT_SYMBOL(edma_resume); - -/** - * edma_start - start dma on a channel - * @channel: channel being activated - * - * Channels with event associations will be triggered by their hardware - * events, and channels without such associations will be triggered by - * software. (At this writing there is no interface for using software - * triggers except with channels that don't support hardware triggers.) - * - * Returns zero on success, else negative errno. - */ -int edma_start(unsigned channel) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(channel); - channel = EDMA_CHAN_SLOT(channel); - - if (channel < edma_cc[ctlr]->num_channels) { - int j = channel >> 5; - unsigned int mask = BIT(channel & 0x1f); - - /* EDMA channels without event association */ - if (test_bit(channel, edma_cc[ctlr]->edma_unused)) { - pr_debug("EDMA: ESR%d %08x\n", j, - edma_shadow0_read_array(ctlr, SH_ESR, j)); - edma_shadow0_write_array(ctlr, SH_ESR, j, mask); - return 0; - } - - /* EDMA channel with event association */ - pr_debug("EDMA: ER%d %08x\n", j, - edma_shadow0_read_array(ctlr, SH_ER, j)); - /* Clear any pending event or error */ - edma_write_array(ctlr, EDMA_ECR, j, mask); - edma_write_array(ctlr, EDMA_EMCR, j, mask); - /* Clear any SER */ - edma_shadow0_write_array(ctlr, SH_SECR, j, mask); - edma_shadow0_write_array(ctlr, SH_EESR, j, mask); - pr_debug("EDMA: EER%d %08x\n", j, - edma_shadow0_read_array(ctlr, SH_EER, j)); - return 0; - } - - return -EINVAL; -} -EXPORT_SYMBOL(edma_start); - -/** - * edma_stop - stops dma on the channel passed - * @channel: channel being deactivated - * - * When @lch is a channel, any active transfer is paused and - * all pending hardware events are cleared. The current transfer - * may not be resumed, and the channel's Parameter RAM should be - * reinitialized before being reused. - */ -void edma_stop(unsigned channel) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(channel); - channel = EDMA_CHAN_SLOT(channel); - - if (channel < edma_cc[ctlr]->num_channels) { - int j = channel >> 5; - unsigned int mask = BIT(channel & 0x1f); - - edma_shadow0_write_array(ctlr, SH_EECR, j, mask); - edma_shadow0_write_array(ctlr, SH_ECR, j, mask); - edma_shadow0_write_array(ctlr, SH_SECR, j, mask); - edma_write_array(ctlr, EDMA_EMCR, j, mask); - - pr_debug("EDMA: EER%d %08x\n", j, - edma_shadow0_read_array(ctlr, SH_EER, j)); - - /* REVISIT: consider guarding against inappropriate event - * chaining by overwriting with dummy_paramset. - */ - } -} -EXPORT_SYMBOL(edma_stop); - -/****************************************************************************** - * - * It cleans ParamEntry qand bring back EDMA to initial state if media has - * been removed before EDMA has finished.It is usedful for removable media. - * Arguments: - * ch_no - channel no - * - * Return: zero on success, or corresponding error no on failure - * - * FIXME this should not be needed ... edma_stop() should suffice. - * - *****************************************************************************/ - -void edma_clean_channel(unsigned channel) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(channel); - channel = EDMA_CHAN_SLOT(channel); - - if (channel < edma_cc[ctlr]->num_channels) { - int j = (channel >> 5); - unsigned int mask = BIT(channel & 0x1f); - - pr_debug("EDMA: EMR%d %08x\n", j, - edma_read_array(ctlr, EDMA_EMR, j)); - edma_shadow0_write_array(ctlr, SH_ECR, j, mask); - /* Clear the corresponding EMR bits */ - edma_write_array(ctlr, EDMA_EMCR, j, mask); - /* Clear any SER */ - edma_shadow0_write_array(ctlr, SH_SECR, j, mask); - edma_write(ctlr, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0)); - } -} -EXPORT_SYMBOL(edma_clean_channel); - -/* - * edma_clear_event - clear an outstanding event on the DMA channel - * Arguments: - * channel - channel number - */ -void edma_clear_event(unsigned channel) -{ - unsigned ctlr; - - ctlr = EDMA_CTLR(channel); - channel = EDMA_CHAN_SLOT(channel); - - if (channel >= edma_cc[ctlr]->num_channels) - return; - if (channel < 32) - edma_write(ctlr, EDMA_ECR, BIT(channel)); - else - edma_write(ctlr, EDMA_ECRH, BIT(channel - 32)); -} -EXPORT_SYMBOL(edma_clear_event); - -/*-----------------------------------------------------------------------*/ - -static int __init edma_probe(struct platform_device *pdev) -{ - struct edma_soc_info **info = pdev->dev.platform_data; - const s8 (*queue_priority_mapping)[2]; - const s8 (*queue_tc_mapping)[2]; - int i, j, off, ln, found = 0; - int status = -1; - const s16 (*rsv_chans)[2]; - const s16 (*rsv_slots)[2]; - int irq[EDMA_MAX_CC] = {0, 0}; - int err_irq[EDMA_MAX_CC] = {0, 0}; - struct resource *r[EDMA_MAX_CC] = {NULL}; - resource_size_t len[EDMA_MAX_CC]; - char res_name[10]; - char irq_name[10]; - - if (!info) - return -ENODEV; - - for (j = 0; j < EDMA_MAX_CC; j++) { - sprintf(res_name, "edma_cc%d", j); - r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM, - res_name); - if (!r[j] || !info[j]) { - if (found) - break; - else - return -ENODEV; - } else { - found = 1; - } - - len[j] = resource_size(r[j]); - - r[j] = request_mem_region(r[j]->start, len[j], - dev_name(&pdev->dev)); - if (!r[j]) { - status = -EBUSY; - goto fail1; - } - - edmacc_regs_base[j] = ioremap(r[j]->start, len[j]); - if (!edmacc_regs_base[j]) { - status = -EBUSY; - goto fail1; - } - - edma_cc[j] = kzalloc(sizeof(struct edma), GFP_KERNEL); - if (!edma_cc[j]) { - status = -ENOMEM; - goto fail1; - } - - edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel, - EDMA_MAX_DMACH); - edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot, - EDMA_MAX_PARAMENTRY); - edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc, - EDMA_MAX_CC); - - edma_cc[j]->default_queue = info[j]->default_queue; - - dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", - edmacc_regs_base[j]); - - for (i = 0; i < edma_cc[j]->num_slots; i++) - memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i), - &dummy_paramset, PARM_SIZE); - - /* Mark all channels as unused */ - memset(edma_cc[j]->edma_unused, 0xff, - sizeof(edma_cc[j]->edma_unused)); - - if (info[j]->rsv) { - - /* Clear the reserved channels in unused list */ - rsv_chans = info[j]->rsv->rsv_chans; - if (rsv_chans) { - for (i = 0; rsv_chans[i][0] != -1; i++) { - off = rsv_chans[i][0]; - ln = rsv_chans[i][1]; - clear_bits(off, ln, - edma_cc[j]->edma_unused); - } - } - - /* Set the reserved slots in inuse list */ - rsv_slots = info[j]->rsv->rsv_slots; - if (rsv_slots) { - for (i = 0; rsv_slots[i][0] != -1; i++) { - off = rsv_slots[i][0]; - ln = rsv_slots[i][1]; - set_bits(off, ln, - edma_cc[j]->edma_inuse); - } - } - } - - sprintf(irq_name, "edma%d", j); - irq[j] = platform_get_irq_byname(pdev, irq_name); - edma_cc[j]->irq_res_start = irq[j]; - status = request_irq(irq[j], dma_irq_handler, 0, "edma", - &pdev->dev); - if (status < 0) { - dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", - irq[j], status); - goto fail; - } - - sprintf(irq_name, "edma%d_err", j); - err_irq[j] = platform_get_irq_byname(pdev, irq_name); - edma_cc[j]->irq_res_end = err_irq[j]; - status = request_irq(err_irq[j], dma_ccerr_handler, 0, - "edma_error", &pdev->dev); - if (status < 0) { - dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", - err_irq[j], status); - goto fail; - } - - for (i = 0; i < edma_cc[j]->num_channels; i++) - map_dmach_queue(j, i, info[j]->default_queue); - - queue_tc_mapping = info[j]->queue_tc_mapping; - queue_priority_mapping = info[j]->queue_priority_mapping; - - /* Event queue to TC mapping */ - for (i = 0; queue_tc_mapping[i][0] != -1; i++) - map_queue_tc(j, queue_tc_mapping[i][0], - queue_tc_mapping[i][1]); - - /* Event queue priority mapping */ - for (i = 0; queue_priority_mapping[i][0] != -1; i++) - assign_priority_to_queue(j, - queue_priority_mapping[i][0], - queue_priority_mapping[i][1]); - - /* Map the channel to param entry if channel mapping logic - * exist - */ - if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST) - map_dmach_param(j); - - for (i = 0; i < info[j]->n_region; i++) { - edma_write_array2(j, EDMA_DRAE, i, 0, 0x0); - edma_write_array2(j, EDMA_DRAE, i, 1, 0x0); - edma_write_array(j, EDMA_QRAE, i, 0x0); - } - arch_num_cc++; - } - - if (tc_errs_handled) { - status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0, - "edma_tc0", &pdev->dev); - if (status < 0) { - dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", - IRQ_TCERRINT0, status); - return status; - } - status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0, - "edma_tc1", &pdev->dev); - if (status < 0) { - dev_dbg(&pdev->dev, "request_irq %d --> %d\n", - IRQ_TCERRINT, status); - return status; - } - } - - return 0; - -fail: - for (i = 0; i < EDMA_MAX_CC; i++) { - if (err_irq[i]) - free_irq(err_irq[i], &pdev->dev); - if (irq[i]) - free_irq(irq[i], &pdev->dev); - } -fail1: - for (i = 0; i < EDMA_MAX_CC; i++) { - if (r[i]) - release_mem_region(r[i]->start, len[i]); - if (edmacc_regs_base[i]) - iounmap(edmacc_regs_base[i]); - kfree(edma_cc[i]); - } - return status; -} - - -static struct platform_driver edma_driver = { - .driver.name = "edma", -}; - -static int __init edma_init(void) -{ - return platform_driver_probe(&edma_driver, edma_probe); -} -arch_initcall(edma_init); - diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index faec783b0dc8..3c797e2272f8 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -20,8 +20,8 @@ #include #include -#include #include +#include #include #include #include diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h deleted file mode 100644 index 7e84c906ceff..000000000000 --- a/arch/arm/mach-davinci/include/mach/edma.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * TI DAVINCI dma definitions - * - * Copyright (C) 2006-2009 Texas Instruments. - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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. - * - */ - -/* - * This EDMA3 programming framework exposes two basic kinds of resource: - * - * Channel Triggers transfers, usually from a hardware event but - * also manually or by "chaining" from DMA completions. - * Each channel is coupled to a Parameter RAM (PaRAM) slot. - * - * Slot Each PaRAM slot holds a DMA transfer descriptor (PaRAM - * "set"), source and destination addresses, a link to a - * next PaRAM slot (if any), options for the transfer, and - * instructions for updating those addresses. There are - * more than twice as many slots as event channels. - * - * Each PaRAM set describes a sequence of transfers, either for one large - * buffer or for several discontiguous smaller buffers. An EDMA transfer - * is driven only from a channel, which performs the transfers specified - * in its PaRAM slot until there are no more transfers. When that last - * transfer completes, the "link" field may be used to reload the channel's - * PaRAM slot with a new transfer descriptor. - * - * The EDMA Channel Controller (CC) maps requests from channels into physical - * Transfer Controller (TC) requests when the channel triggers (by hardware - * or software events, or by chaining). The two physical DMA channels provided - * by the TCs are thus shared by many logical channels. - * - * DaVinci hardware also has a "QDMA" mechanism which is not currently - * supported through this interface. (DSP firmware uses it though.) - */ - -#ifndef EDMA_H_ -#define EDMA_H_ - -/* PaRAM slots are laid out like this */ -struct edmacc_param { - unsigned int opt; - unsigned int src; - unsigned int a_b_cnt; - unsigned int dst; - unsigned int src_dst_bidx; - unsigned int link_bcntrld; - unsigned int src_dst_cidx; - unsigned int ccnt; -}; - -#define CCINT0_INTERRUPT 16 -#define CCERRINT_INTERRUPT 17 -#define TCERRINT0_INTERRUPT 18 -#define TCERRINT1_INTERRUPT 19 - -/* fields in edmacc_param.opt */ -#define SAM BIT(0) -#define DAM BIT(1) -#define SYNCDIM BIT(2) -#define STATIC BIT(3) -#define EDMA_FWID (0x07 << 8) -#define TCCMODE BIT(11) -#define EDMA_TCC(t) ((t) << 12) -#define TCINTEN BIT(20) -#define ITCINTEN BIT(21) -#define TCCHEN BIT(22) -#define ITCCHEN BIT(23) - -#define TRWORD (0x7<<2) -#define PAENTRY (0x1ff<<5) - -/* Drivers should avoid using these symbolic names for dm644x - * channels, and use platform_device IORESOURCE_DMA resources - * instead. (Other DaVinci chips have different peripherals - * and thus have different DMA channel mappings.) - */ -#define DAVINCI_DMA_MCBSP_TX 2 -#define DAVINCI_DMA_MCBSP_RX 3 -#define DAVINCI_DMA_VPSS_HIST 4 -#define DAVINCI_DMA_VPSS_H3A 5 -#define DAVINCI_DMA_VPSS_PRVU 6 -#define DAVINCI_DMA_VPSS_RSZ 7 -#define DAVINCI_DMA_IMCOP_IMXINT 8 -#define DAVINCI_DMA_IMCOP_VLCDINT 9 -#define DAVINCI_DMA_IMCO_PASQINT 10 -#define DAVINCI_DMA_IMCOP_DSQINT 11 -#define DAVINCI_DMA_SPI_SPIX 16 -#define DAVINCI_DMA_SPI_SPIR 17 -#define DAVINCI_DMA_UART0_URXEVT0 18 -#define DAVINCI_DMA_UART0_UTXEVT0 19 -#define DAVINCI_DMA_UART1_URXEVT1 20 -#define DAVINCI_DMA_UART1_UTXEVT1 21 -#define DAVINCI_DMA_UART2_URXEVT2 22 -#define DAVINCI_DMA_UART2_UTXEVT2 23 -#define DAVINCI_DMA_MEMSTK_MSEVT 24 -#define DAVINCI_DMA_MMCRXEVT 26 -#define DAVINCI_DMA_MMCTXEVT 27 -#define DAVINCI_DMA_I2C_ICREVT 28 -#define DAVINCI_DMA_I2C_ICXEVT 29 -#define DAVINCI_DMA_GPIO_GPINT0 32 -#define DAVINCI_DMA_GPIO_GPINT1 33 -#define DAVINCI_DMA_GPIO_GPINT2 34 -#define DAVINCI_DMA_GPIO_GPINT3 35 -#define DAVINCI_DMA_GPIO_GPINT4 36 -#define DAVINCI_DMA_GPIO_GPINT5 37 -#define DAVINCI_DMA_GPIO_GPINT6 38 -#define DAVINCI_DMA_GPIO_GPINT7 39 -#define DAVINCI_DMA_GPIO_GPBNKINT0 40 -#define DAVINCI_DMA_GPIO_GPBNKINT1 41 -#define DAVINCI_DMA_GPIO_GPBNKINT2 42 -#define DAVINCI_DMA_GPIO_GPBNKINT3 43 -#define DAVINCI_DMA_GPIO_GPBNKINT4 44 -#define DAVINCI_DMA_TIMER0_TINT0 48 -#define DAVINCI_DMA_TIMER1_TINT1 49 -#define DAVINCI_DMA_TIMER2_TINT2 50 -#define DAVINCI_DMA_TIMER3_TINT3 51 -#define DAVINCI_DMA_PWM0 52 -#define DAVINCI_DMA_PWM1 53 -#define DAVINCI_DMA_PWM2 54 - -/* DA830 specific EDMA3 information */ -#define EDMA_DA830_NUM_DMACH 32 -#define EDMA_DA830_NUM_TCC 32 -#define EDMA_DA830_NUM_PARAMENTRY 128 -#define EDMA_DA830_NUM_EVQUE 2 -#define EDMA_DA830_NUM_TC 2 -#define EDMA_DA830_CHMAP_EXIST 0 -#define EDMA_DA830_NUM_REGIONS 4 -#define DA830_DMACH2EVENT_MAP0 0x000FC03Fu -#define DA830_DMACH2EVENT_MAP1 0x00000000u -#define DA830_EDMA_ARM_OWN 0x30FFCCFFu - -/*ch_status paramater of callback function possible values*/ -#define DMA_COMPLETE 1 -#define DMA_CC_ERROR 2 -#define DMA_TC1_ERROR 3 -#define DMA_TC2_ERROR 4 - -enum address_mode { - INCR = 0, - FIFO = 1 -}; - -enum fifo_width { - W8BIT = 0, - W16BIT = 1, - W32BIT = 2, - W64BIT = 3, - W128BIT = 4, - W256BIT = 5 -}; - -enum dma_event_q { - EVENTQ_0 = 0, - EVENTQ_1 = 1, - EVENTQ_2 = 2, - EVENTQ_3 = 3, - EVENTQ_DEFAULT = -1 -}; - -enum sync_dimension { - ASYNC = 0, - ABSYNC = 1 -}; - -#define EDMA_CTLR_CHAN(ctlr, chan) (((ctlr) << 16) | (chan)) -#define EDMA_CTLR(i) ((i) >> 16) -#define EDMA_CHAN_SLOT(i) ((i) & 0xffff) - -#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */ -#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */ -#define EDMA_CONT_PARAMS_ANY 1001 -#define EDMA_CONT_PARAMS_FIXED_EXACT 1002 -#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003 - -#define EDMA_MAX_CC 2 - -/* alloc/free DMA channels and their dedicated parameter RAM slots */ -int edma_alloc_channel(int channel, - void (*callback)(unsigned channel, u16 ch_status, void *data), - void *data, enum dma_event_q); -void edma_free_channel(unsigned channel); - -/* alloc/free parameter RAM slots */ -int edma_alloc_slot(unsigned ctlr, int slot); -void edma_free_slot(unsigned slot); - -/* alloc/free a set of contiguous parameter RAM slots */ -int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count); -int edma_free_cont_slots(unsigned slot, int count); - -/* calls that operate on part of a parameter RAM slot */ -void edma_set_src(unsigned slot, dma_addr_t src_port, - enum address_mode mode, enum fifo_width); -void edma_set_dest(unsigned slot, dma_addr_t dest_port, - enum address_mode mode, enum fifo_width); -void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst); -void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx); -void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx); -void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt, - u16 bcnt_rld, enum sync_dimension sync_mode); -void edma_link(unsigned from, unsigned to); -void edma_unlink(unsigned from); - -/* calls that operate on an entire parameter RAM slot */ -void edma_write_slot(unsigned slot, const struct edmacc_param *params); -void edma_read_slot(unsigned slot, struct edmacc_param *params); - -/* channel control operations */ -int edma_start(unsigned channel); -void edma_stop(unsigned channel); -void edma_clean_channel(unsigned channel); -void edma_clear_event(unsigned channel); -void edma_pause(unsigned channel); -void edma_resume(unsigned channel); - -struct edma_rsv_info { - - const s16 (*rsv_chans)[2]; - const s16 (*rsv_slots)[2]; -}; - -/* platform_data for EDMA driver */ -struct edma_soc_info { - - /* how many dma resources of each type */ - unsigned n_channel; - unsigned n_region; - unsigned n_slot; - unsigned n_tc; - unsigned n_cc; - /* - * Default queue is expected to be a low-priority queue. - * This way, long transfers on the default queue started - * by the codec engine will not cause audio defects. - */ - enum dma_event_q default_queue; - - /* Resource reservation for other cores */ - struct edma_rsv_info *rsv; - - const s8 (*queue_tc_mapping)[2]; - const s8 (*queue_priority_mapping)[2]; -}; - -#endif diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index cd7e3280fadd..5f3e532436ee 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include "dmaengine.h" #include "virt-dma.h" diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 3946a0eb3a03..5dfb70c669dc 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -37,6 +37,7 @@ #include #include +#include #include /* diff --git a/include/linux/mfd/davinci_voicecodec.h b/include/linux/mfd/davinci_voicecodec.h index 0ab61320ffa8..7dd6524d2aac 100644 --- a/include/linux/mfd/davinci_voicecodec.h +++ b/include/linux/mfd/davinci_voicecodec.h @@ -26,8 +26,7 @@ #include #include #include - -#include +#include /* * Register values. diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h new file mode 100644 index 000000000000..2344ea2675ad --- /dev/null +++ b/include/linux/platform_data/edma.h @@ -0,0 +1,182 @@ +/* + * TI EDMA definitions + * + * Copyright (C) 2006-2013 Texas Instruments. + * + * 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 EDMA3 programming framework exposes two basic kinds of resource: + * + * Channel Triggers transfers, usually from a hardware event but + * also manually or by "chaining" from DMA completions. + * Each channel is coupled to a Parameter RAM (PaRAM) slot. + * + * Slot Each PaRAM slot holds a DMA transfer descriptor (PaRAM + * "set"), source and destination addresses, a link to a + * next PaRAM slot (if any), options for the transfer, and + * instructions for updating those addresses. There are + * more than twice as many slots as event channels. + * + * Each PaRAM set describes a sequence of transfers, either for one large + * buffer or for several discontiguous smaller buffers. An EDMA transfer + * is driven only from a channel, which performs the transfers specified + * in its PaRAM slot until there are no more transfers. When that last + * transfer completes, the "link" field may be used to reload the channel's + * PaRAM slot with a new transfer descriptor. + * + * The EDMA Channel Controller (CC) maps requests from channels into physical + * Transfer Controller (TC) requests when the channel triggers (by hardware + * or software events, or by chaining). The two physical DMA channels provided + * by the TCs are thus shared by many logical channels. + * + * DaVinci hardware also has a "QDMA" mechanism which is not currently + * supported through this interface. (DSP firmware uses it though.) + */ + +#ifndef EDMA_H_ +#define EDMA_H_ + +/* PaRAM slots are laid out like this */ +struct edmacc_param { + unsigned int opt; + unsigned int src; + unsigned int a_b_cnt; + unsigned int dst; + unsigned int src_dst_bidx; + unsigned int link_bcntrld; + unsigned int src_dst_cidx; + unsigned int ccnt; +}; + +/* fields in edmacc_param.opt */ +#define SAM BIT(0) +#define DAM BIT(1) +#define SYNCDIM BIT(2) +#define STATIC BIT(3) +#define EDMA_FWID (0x07 << 8) +#define TCCMODE BIT(11) +#define EDMA_TCC(t) ((t) << 12) +#define TCINTEN BIT(20) +#define ITCINTEN BIT(21) +#define TCCHEN BIT(22) +#define ITCCHEN BIT(23) + +/*ch_status paramater of callback function possible values*/ +#define DMA_COMPLETE 1 +#define DMA_CC_ERROR 2 +#define DMA_TC1_ERROR 3 +#define DMA_TC2_ERROR 4 + +enum address_mode { + INCR = 0, + FIFO = 1 +}; + +enum fifo_width { + W8BIT = 0, + W16BIT = 1, + W32BIT = 2, + W64BIT = 3, + W128BIT = 4, + W256BIT = 5 +}; + +enum dma_event_q { + EVENTQ_0 = 0, + EVENTQ_1 = 1, + EVENTQ_2 = 2, + EVENTQ_3 = 3, + EVENTQ_DEFAULT = -1 +}; + +enum sync_dimension { + ASYNC = 0, + ABSYNC = 1 +}; + +#define EDMA_CTLR_CHAN(ctlr, chan) (((ctlr) << 16) | (chan)) +#define EDMA_CTLR(i) ((i) >> 16) +#define EDMA_CHAN_SLOT(i) ((i) & 0xffff) + +#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */ +#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */ +#define EDMA_CONT_PARAMS_ANY 1001 +#define EDMA_CONT_PARAMS_FIXED_EXACT 1002 +#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003 + +#define EDMA_MAX_CC 2 + +/* alloc/free DMA channels and their dedicated parameter RAM slots */ +int edma_alloc_channel(int channel, + void (*callback)(unsigned channel, u16 ch_status, void *data), + void *data, enum dma_event_q); +void edma_free_channel(unsigned channel); + +/* alloc/free parameter RAM slots */ +int edma_alloc_slot(unsigned ctlr, int slot); +void edma_free_slot(unsigned slot); + +/* alloc/free a set of contiguous parameter RAM slots */ +int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count); +int edma_free_cont_slots(unsigned slot, int count); + +/* calls that operate on part of a parameter RAM slot */ +void edma_set_src(unsigned slot, dma_addr_t src_port, + enum address_mode mode, enum fifo_width); +void edma_set_dest(unsigned slot, dma_addr_t dest_port, + enum address_mode mode, enum fifo_width); +void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst); +void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx); +void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx); +void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt, + u16 bcnt_rld, enum sync_dimension sync_mode); +void edma_link(unsigned from, unsigned to); +void edma_unlink(unsigned from); + +/* calls that operate on an entire parameter RAM slot */ +void edma_write_slot(unsigned slot, const struct edmacc_param *params); +void edma_read_slot(unsigned slot, struct edmacc_param *params); + +/* channel control operations */ +int edma_start(unsigned channel); +void edma_stop(unsigned channel); +void edma_clean_channel(unsigned channel); +void edma_clear_event(unsigned channel); +void edma_pause(unsigned channel); +void edma_resume(unsigned channel); + +struct edma_rsv_info { + + const s16 (*rsv_chans)[2]; + const s16 (*rsv_slots)[2]; +}; + +/* platform_data for EDMA driver */ +struct edma_soc_info { + + /* how many dma resources of each type */ + unsigned n_channel; + unsigned n_region; + unsigned n_slot; + unsigned n_tc; + unsigned n_cc; + /* + * Default queue is expected to be a low-priority queue. + * This way, long transfers on the default queue started + * by the codec engine will not cause audio defects. + */ + enum dma_event_q default_queue; + + /* Resource reservation for other cores */ + struct edma_rsv_info *rsv; + + const s8 (*queue_tc_mapping)[2]; + const s8 (*queue_priority_mapping)[2]; +}; + +#endif diff --git a/include/linux/platform_data/spi-davinci.h b/include/linux/platform_data/spi-davinci.h index 7af305b37868..8dc2fa47a2aa 100644 --- a/include/linux/platform_data/spi-davinci.h +++ b/include/linux/platform_data/spi-davinci.h @@ -19,7 +19,7 @@ #ifndef __ARCH_ARM_DAVINCI_SPI_H #define __ARCH_ARM_DAVINCI_SPI_H -#include +#include #define SPI_INTERN_CS 0xFF diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 484b22c5df5d..fd7c45b9ed5a 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index b2f27c2e5fdc..8460edce1c3b 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index b6ef7039dd09..fbb710c76c08 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h @@ -14,7 +14,7 @@ #include #include -#include +#include struct davinci_pcm_dma_params { int channel; /* sync dma channel ID */ -- cgit v1.2.3 From 880cf0717f70678b2ecd6bb762e469c64c3b0d83 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 19 Jun 2013 01:22:20 +0900 Subject: ARM: SAMSUNG: Introduce GPIO_SAMSUNG Kconfig entry This patch adds Kconfig entry that selects whether legacy Samsung GPIO driver should be built or not. For platforms that support only DT based boot, the new pinctrl driver is used and so the old one is not needed. Cc: Grant Likely Cc: Linus Walleij Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/Kconfig | 6 ++++++ arch/arm/plat-samsung/include/plat/pm.h | 5 +++++ drivers/gpio/Kconfig | 7 +++++++ drivers/gpio/Makefile | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index aa8dcfc27903..15e599437e96 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -695,6 +695,7 @@ config ARCH_S3C24XX select CLKDEV_LOOKUP select CLKSRC_MMIO select GENERIC_CLOCKEVENTS + select GPIO_SAMSUNG select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -718,6 +719,7 @@ config ARCH_S3C64XX select CLKSRC_MMIO select CPU_V6 select GENERIC_CLOCKEVENTS + select GPIO_SAMSUNG select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -741,6 +743,7 @@ config ARCH_S5P64X0 select CLKSRC_MMIO select CPU_V6 select GENERIC_CLOCKEVENTS + select GPIO_SAMSUNG select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -758,6 +761,7 @@ config ARCH_S5PC100 select CLKSRC_MMIO select CPU_V7 select GENERIC_CLOCKEVENTS + select GPIO_SAMSUNG select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -776,6 +780,7 @@ config ARCH_S5PV210 select CLKSRC_MMIO select CPU_V7 select GENERIC_CLOCKEVENTS + select GPIO_SAMSUNG select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -795,6 +800,7 @@ config ARCH_EXYNOS select COMMON_CLK select CPU_V7 select GENERIC_CLOCKEVENTS + select GPIO_SAMSUNG select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index f6fcadeee969..5d47ca35cabd 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h @@ -166,6 +166,7 @@ extern void s3c_pm_check_store(void); */ extern void s3c_pm_configure_extint(void); +#ifdef CONFIG_GPIO_SAMSUNG /** * samsung_pm_restore_gpios() - restore the state of the gpios after sleep. * @@ -181,6 +182,10 @@ extern void samsung_pm_restore_gpios(void); * Save the GPIO states for resotration on resume. See samsung_pm_restore_gpios(). */ extern void samsung_pm_save_gpios(void); +#else +static inline void samsung_pm_restore_gpios(void) {} +static inline void samsung_pm_save_gpios(void) {} +#endif extern void s3c_pm_save_core(void); extern void s3c_pm_restore_core(void); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 573c449c49b9..9c993ed491f1 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -209,6 +209,13 @@ config GPIO_RCAR help Say yes here to support GPIO on Renesas R-Car SoCs. +config GPIO_SAMSUNG + bool + depends on PLAT_SAMSUNG + help + Legacy GPIO support. Use only for platforms without support for + pinctrl. + config GPIO_SPEAR_SPICS bool "ST SPEAr13xx SPI Chip Select as GPIO support" depends on PLAT_SPEAR diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 0cb2d656ad16..ef3e983a2f1e 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -59,7 +59,7 @@ obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o -obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o +obj-$(CONFIG_GPIO_SAMSUNG) += gpio-samsung.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o -- cgit v1.2.3 From e245f9699e941fcc01af200806e8307e4ab7198d Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 19 Jun 2013 01:26:42 +0900 Subject: ARM: EXYNOS: Decouple ARCH_EXYNOS from PLAT_S5P After removing support for ATAGS based boot on Exynos, there is not much that can be shared between Exynos and other S5P platforms. This patch makes Exynos a standalone Samsung platform, not using PLAT_S5P. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/Kconfig | 3 +++ arch/arm/Makefile | 1 + arch/arm/mach-exynos/Kconfig | 1 + arch/arm/plat-samsung/Kconfig | 8 +++----- arch/arm/plat-samsung/pm-gpio.c | 5 +++-- 5 files changed, 11 insertions(+), 7 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 15e599437e96..a4e32fd9bb4a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -795,7 +795,9 @@ config ARCH_EXYNOS bool "Samsung EXYNOS" select ARCH_HAS_CPUFREQ select ARCH_HAS_HOLES_MEMORYMODEL + select ARCH_REQUIRE_GPIOLIB select ARCH_SPARSEMEM_ENABLE + select ARM_GIC select CLKDEV_LOOKUP select COMMON_CLK select CPU_V7 @@ -807,6 +809,7 @@ config ARCH_EXYNOS select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_GPIO_H select NEED_MACH_MEMORY_H + select S5P_GPIO_DRVSTR select SAMSUNG_ATAGS select USE_OF help diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1ba358ba16b8..60133fb4d6c3 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -197,6 +197,7 @@ machine-$(CONFIG_ARCH_SUNXI) += sunxi # Platform directory name. This list is sorted alphanumerically # by CONFIG_* macro name. +plat-$(CONFIG_ARCH_EXYNOS) += samsung plat-$(CONFIG_ARCH_OMAP) += omap plat-$(CONFIG_ARCH_S3C64XX) += samsung plat-$(CONFIG_PLAT_IOP) += iop diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 2bc2696153f9..1f356790a4f4 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -14,6 +14,7 @@ menu "SAMSUNG EXYNOS SoCs Support" config ARCH_EXYNOS4 bool "SAMSUNG EXYNOS4" default y + select GIC_NON_BANKED select HAVE_ARM_SCU if SMP select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 7b08b2678b1a..ca27cc9ac4bf 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -6,7 +6,7 @@ config PLAT_SAMSUNG bool - depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P + depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P || ARCH_EXYNOS default y select GENERIC_IRQ_CHIP select NO_IOPORT @@ -15,12 +15,10 @@ config PLAT_SAMSUNG config PLAT_S5P bool - depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) + depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) default y select ARCH_REQUIRE_GPIOLIB - select ARM_GIC if ARCH_EXYNOS - select ARM_VIC if !ARCH_EXYNOS - select GIC_NON_BANKED if ARCH_EXYNOS4 + select ARM_VIC select NO_IOPORT select PLAT_SAMSUNG select S3C_GPIO_TRACK diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c index c2ff92c30bdf..a8de3cfe2ee1 100644 --- a/arch/arm/plat-samsung/pm-gpio.c +++ b/arch/arm/plat-samsung/pm-gpio.c @@ -192,7 +192,8 @@ struct samsung_gpio_pm samsung_gpio_pm_2bit = { .resume = samsung_gpio_pm_2bit_resume, }; -#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P) +#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P) \ + || defined(CONFIG_ARCH_EXYNOS) static void samsung_gpio_pm_4bit_save(struct samsung_gpio_chip *chip) { chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON); @@ -302,7 +303,7 @@ struct samsung_gpio_pm samsung_gpio_pm_4bit = { .save = samsung_gpio_pm_4bit_save, .resume = samsung_gpio_pm_4bit_resume, }; -#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */ +#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P || CONFIG_ARCH_EXYNOS */ /** * samsung_pm_save_gpio() - save gpio chip data for suspend -- cgit v1.2.3 From 17859bec3557beb7f5b268e4fa35457e75071469 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 19 Jun 2013 01:27:37 +0900 Subject: ARM: EXYNOS: Do not select legacy Kconfig symbols any more This patch removes selection of several legacy Kconfig symbols from ARCH_EXYNOS to bypass compilation of code used only for ATAGS based boot. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/Kconfig | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a4e32fd9bb4a..17a2d6a65728 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -802,15 +802,11 @@ config ARCH_EXYNOS select COMMON_CLK select CPU_V7 select GENERIC_CLOCKEVENTS - select GPIO_SAMSUNG select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS - select NEED_MACH_GPIO_H select NEED_MACH_MEMORY_H - select S5P_GPIO_DRVSTR - select SAMSUNG_ATAGS select USE_OF help Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5) -- cgit v1.2.3 From 6e726ea4f50e7fea5844a2a0fee29d6d3d2e8bdf Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Sat, 15 Jun 2013 09:28:55 +0900 Subject: ARM: EXYNOS: Select SPARSE_IRQ for Exynos This patch adds selection of CONFIG_SPARSE_IRQ for ARCH_EXYNOS, since it is required by multiplatform and allows to remove the legacy mach/irqs.h header. To make this possible, a dummy IRQ_EINT_BIT macro is added to pm-core.h header to allow plat-samsung/pm.c compile. This macro is irrelevant for Exynos and will be removed after reworking Samsung pm code for multiplatform compatibility. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Acked-by: Arnd Bergmann Signed-off-by: Kukjin Kim --- arch/arm/Kconfig | 1 + arch/arm/mach-exynos/include/mach/pm-core.h | 1 + 2 files changed, 2 insertions(+) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 17a2d6a65728..14f6e1138e88 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -807,6 +807,7 @@ config ARCH_EXYNOS select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_MEMORY_H + select SPARSE_IRQ select USE_OF help Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5) diff --git a/arch/arm/mach-exynos/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h index dd62559a2ed4..71e6b89719ab 100644 --- a/arch/arm/mach-exynos/include/mach/pm-core.h +++ b/arch/arm/mach-exynos/include/mach/pm-core.h @@ -70,6 +70,7 @@ static inline void samsung_pm_saved_gpios(void) } /* Compatibility definitions to make plat-samsung/pm.c compile */ +#define IRQ_EINT_BIT(x) 1 #define s3c_irqwake_intallow 0 #define s3c_irqwake_eintallow 0 -- cgit v1.2.3 From d63dc0514d56e108cc96e334ca26b538263e52a2 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sun, 2 Jun 2013 23:09:41 +0200 Subject: arm: add basic support for Rockchip RK3066a boards This adds a generic devicetree board file and a dtsi for boards based on the RK3066a SoCs from Rockchip. Apart from the generic parts (gic, clocks, pinctrl) the only components currently supported are the timers, uarts and mmc ports (all DesignWare- based). Signed-off-by: Heiko Stuebner Acked-by: Olof Johansson --- arch/arm/Kconfig | 2 + arch/arm/Makefile | 1 + arch/arm/boot/dts/rk3066a.dtsi | 390 ++++++++++++++++++++++++++++++++++++++ arch/arm/mach-rockchip/Kconfig | 16 ++ arch/arm/mach-rockchip/Makefile | 1 + arch/arm/mach-rockchip/rockchip.c | 52 +++++ 6 files changed, 462 insertions(+) create mode 100644 arch/arm/boot/dts/rk3066a.dtsi create mode 100644 arch/arm/mach-rockchip/Kconfig create mode 100644 arch/arm/mach-rockchip/Makefile create mode 100644 arch/arm/mach-rockchip/rockchip.c (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49d993cee512..94d3491ae40a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -981,6 +981,8 @@ source "arch/arm/mach-mmp/Kconfig" source "arch/arm/mach-realview/Kconfig" +source "arch/arm/mach-rockchip/Kconfig" + source "arch/arm/mach-sa1100/Kconfig" source "arch/arm/plat-samsung/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1ba358ba16b8..126313fcc594 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -171,6 +171,7 @@ machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell machine-$(CONFIG_ARCH_PRIMA2) += prima2 machine-$(CONFIG_ARCH_PXA) += pxa machine-$(CONFIG_ARCH_REALVIEW) += realview +machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip machine-$(CONFIG_ARCH_RPC) += rpc machine-$(CONFIG_ARCH_S3C24XX) += s3c24xx machine-$(CONFIG_ARCH_S3C64XX) += s3c64xx diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi new file mode 100644 index 000000000000..56bfac93d3f6 --- /dev/null +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner + * + * 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. + */ + +#include +#include +#include +#include +#include "skeleton.dtsi" +#include "rk3066a-clocks.dtsi" + +/ { + compatible = "rockchip,rk3066a"; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + next-level-cache = <&L2>; + reg = <0x0>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + next-level-cache = <&L2>; + reg = <0x1>; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + gic: interrupt-controller@1013d000 { + compatible = "arm,cortex-a9-gic"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x1013d000 0x1000>, + <0x1013c100 0x0100>; + }; + + L2: l2-cache-controller@10138000 { + compatible = "arm,pl310-cache"; + reg = <0x10138000 0x1000>; + cache-unified; + cache-level = <2>; + }; + + local-timer@1013c600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x1013c600 0x20>; + interrupts = ; + clocks = <&dummy150m>; + }; + + timer@20038000 { + compatible = "snps,dw-apb-timer-osc"; + reg = <0x20038000 0x100>; + interrupts = ; + clocks = <&clk_gates1 0>, <&clk_gates7 7>; + clock-names = "timer", "pclk"; + }; + + timer@2003a000 { + compatible = "snps,dw-apb-timer-osc"; + reg = <0x2003a000 0x100>; + interrupts = ; + clocks = <&clk_gates1 1>, <&clk_gates7 8>; + clock-names = "timer", "pclk"; + }; + + timer@2000e000 { + compatible = "snps,dw-apb-timer-osc"; + reg = <0x2000e000 0x100>; + interrupts = ; + clocks = <&clk_gates1 2>, <&clk_gates7 9>; + clock-names = "timer", "pclk"; + }; + + pinctrl@20008000 { + compatible = "rockchip,rk3066a-pinctrl"; + reg = <0x20008000 0x150>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio0: gpio0@20034000 { + compatible = "rockchip,gpio-bank"; + reg = <0x20034000 0x100>; + interrupts = ; + clocks = <&clk_gates8 9>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio1@2003c000 { + compatible = "rockchip,gpio-bank"; + reg = <0x2003c000 0x100>; + interrupts = ; + clocks = <&clk_gates8 10>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio2@2003e000 { + compatible = "rockchip,gpio-bank"; + reg = <0x2003e000 0x100>; + interrupts = ; + clocks = <&clk_gates8 11>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio3@20080000 { + compatible = "rockchip,gpio-bank"; + reg = <0x20080000 0x100>; + interrupts = ; + clocks = <&clk_gates8 12>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio4: gpio4@20084000 { + compatible = "rockchip,gpio-bank"; + reg = <0x20084000 0x100>; + interrupts = ; + clocks = <&clk_gates8 13>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio6: gpio6@2000a000 { + compatible = "rockchip,gpio-bank"; + reg = <0x2000a000 0x100>; + interrupts = ; + clocks = <&clk_gates8 15>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + pcfg_pull_default: pcfg_pull_default { + bias-pull-pin-default; + }; + + pcfg_pull_none: pcfg_pull_none { + bias-disable; + }; + + uart0 { + uart0_xfer: uart0-xfer { + rockchip,pins = , + ; + rockchip,config = <&pcfg_pull_default>; + }; + + uart0_cts: uart0-cts { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + uart0_rts: uart0-rts { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + }; + + uart1 { + uart1_xfer: uart1-xfer { + rockchip,pins = , + ; + rockchip,config = <&pcfg_pull_default>; + }; + + uart1_cts: uart1-cts { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + uart1_rts: uart1-rts { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + }; + + uart2 { + uart2_xfer: uart2-xfer { + rockchip,pins = , + ; + rockchip,config = <&pcfg_pull_default>; + }; + /* no rts / cts for uart2 */ + }; + + uart3 { + uart3_xfer: uart3-xfer { + rockchip,pins = , + ; + rockchip,config = <&pcfg_pull_default>; + }; + + uart3_cts: uart3-cts { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + uart3_rts: uart3-rts { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + }; + + sd0 { + sd0_clk: sd0-clk { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd0_cmd: sd0-cmd { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd0_cd: sd0-cd { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd0_wp: sd0-wp { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd0_bus1: sd0-bus-width1 { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd0_bus4: sd0-bus-width4 { + rockchip,pins = , + , + , + ; + rockchip,config = <&pcfg_pull_default>; + }; + }; + + sd1 { + sd1_clk: sd1-clk { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd1_cmd: sd1-cmd { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd1_cd: sd1-cd { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd1_wp: sd1-wp { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd1_bus1: sd1-bus-width1 { + rockchip,pins = ; + rockchip,config = <&pcfg_pull_default>; + }; + + sd1_bus4: sd1-bus-width4 { + rockchip,pins = , + , + , + ; + rockchip,config = <&pcfg_pull_default>; + }; + }; + }; + + uart0: serial@10124000 { + compatible = "snps,dw-apb-uart"; + reg = <0x10124000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&clk_gates1 8>; + status = "disabled"; + }; + + uart1: serial@10126000 { + compatible = "snps,dw-apb-uart"; + reg = <0x10126000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&clk_gates1 10>; + status = "disabled"; + }; + + uart2: serial@20064000 { + compatible = "snps,dw-apb-uart"; + reg = <0x20064000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&clk_gates1 12>; + status = "disabled"; + }; + + uart3: serial@20068000 { + compatible = "snps,dw-apb-uart"; + reg = <0x20068000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&clk_gates1 14>; + status = "disabled"; + }; + + dwmmc@10214000 { + compatible = "rockchip,rk2928-dw-mshc"; + reg = <0x10214000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + + clocks = <&clk_gates5 10>, <&clk_gates2 11>; + clock-names = "biu", "ciu"; + + status = "disabled"; + }; + + dwmmc@10218000 { + compatible = "rockchip,rk2928-dw-mshc"; + reg = <0x10218000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + + clocks = <&clk_gates5 11>, <&clk_gates2 13>; + clock-names = "biu", "ciu"; + + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig new file mode 100644 index 000000000000..25ee12b21f01 --- /dev/null +++ b/arch/arm/mach-rockchip/Kconfig @@ -0,0 +1,16 @@ +config ARCH_ROCKCHIP + bool "Rockchip RK2928 and RK3xxx SOCs" if ARCH_MULTI_V7 + select PINCTRL + select PINCTRL_ROCKCHIP + select ARCH_REQUIRE_GPIOLIB + select ARM_GIC + select CACHE_L2X0 + select HAVE_ARM_TWD if LOCAL_TIMERS + select HAVE_SMP + select LOCAL_TIMERS if SMP + select COMMON_CLK + select GENERIC_CLOCKEVENTS + select DW_APB_TIMER_OF + help + Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs + containing the RK2928, RK30xx and RK31xx series. diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile new file mode 100644 index 000000000000..1547d4fc920a --- /dev/null +++ b/arch/arm/mach-rockchip/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c new file mode 100644 index 000000000000..724d2d81f976 --- /dev/null +++ b/arch/arm/mach-rockchip/rockchip.c @@ -0,0 +1,52 @@ +/* + * Device Tree support for Rockchip SoCs + * + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void __init rockchip_timer_init(void) +{ + of_clk_init(NULL); + clocksource_of_init(); +} + +static void __init rockchip_dt_init(void) +{ + l2x0_of_init(0, ~0UL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char * const rockchip_board_dt_compat[] = { + "rockchip,rk2928", + "rockchip,rk3066a", + "rockchip,rk3066b", + "rockchip,rk3188", + NULL, +}; + +DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)") + .init_machine = rockchip_dt_init, + .init_time = rockchip_timer_init, + .dt_compat = rockchip_board_dt_compat, +MACHINE_END -- cgit v1.2.3 From 24e860fbfdb1c3f97d17d3578a146f3b42b9ad83 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 3 Jun 2013 15:38:58 +0200 Subject: ARM: multiplatform: always pick one CPU type With the new default platform code, we can always boot using DT without requiring a board file, but we cannot build a kernel unless we select at least one CPU core, which breaks some "randconfig" builds. This adapts the ARCH_MULTI_V4T and ARCH_MULTI_V5 options so we always default to a common CPU core if no platform was enabled that picks something else. The default we pick for ARMv4T is ARM920T, while for ARMv5 we pick ARM926T. Signed-off-by: Arnd Bergmann --- arch/arm/Kconfig | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index db5aa5f2d1de..ffbaaa5405c5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -870,20 +870,21 @@ menu "Multiple platform selection" comment "CPU Core family selection" -config ARCH_MULTI_V4 - bool "ARMv4 based platforms (FA526, StrongARM)" - depends on !ARCH_MULTI_V6_V7 - select ARCH_MULTI_V4_V5 - config ARCH_MULTI_V4T bool "ARMv4T based platforms (ARM720T, ARM920T, ...)" depends on !ARCH_MULTI_V6_V7 select ARCH_MULTI_V4_V5 + select CPU_ARM920T if !(CPU_ARM7TDMI || CPU_ARM720T || \ + CPU_ARM740T || CPU_ARM9TDMI || CPU_ARM922T || \ + CPU_ARM925T || CPU_ARM940T) config ARCH_MULTI_V5 bool "ARMv5 based platforms (ARM926T, XSCALE, PJ1, ...)" depends on !ARCH_MULTI_V6_V7 select ARCH_MULTI_V4_V5 + select CPU_ARM926T if (!CPU_ARM946E || CPU_ARM1020 || \ + CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \ + CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_FEROCEON) config ARCH_MULTI_V4_V5 bool -- cgit v1.2.3 From 3f06d15782fc8ec9af9be71c87fd1afa6ffae9f7 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 21 Jun 2013 16:25:29 +0900 Subject: ARM: EXYNOS: Enable PCIe support for Exynos5440 Enable PCIe support for Exynos5440 which has two PCIe controllers. Signed-off-by: Jingoo Han Acked-by: Kukjin Kim Signed-off-by: Arnd Bergmann --- arch/arm/Kconfig | 1 + arch/arm/mach-exynos/Kconfig | 2 ++ 2 files changed, 3 insertions(+) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ffbaaa5405c5..d70260dd7428 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1397,6 +1397,7 @@ config PCI_HOST_ITE8152 select DMABOUNCE source "drivers/pci/Kconfig" +source "drivers/pci/pcie/Kconfig" source "drivers/pcmcia/Kconfig" diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 1e0e3999c17a..0ecd5af20545 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -85,6 +85,8 @@ config SOC_EXYNOS5440 select ARCH_HAS_OPP select ARM_ARCH_TIMER select AUTO_ZRELADDR + select MIGHT_HAVE_PCI + select PCI_DOMAINS if PCI select PINCTRL_EXYNOS5440 select PM_OPP help -- cgit v1.2.3