From 361c81f996707e122bffe95c5a3e6c47611b8a29 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 15 Jun 2015 13:15:26 +0200 Subject: ARM: ep93xx: move timer to its own file This breaks the timer code out of the core file in preparation for refactoring. Tested-by: H Hartley Sweeten Reviewed-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/mach-ep93xx/Makefile | 2 +- arch/arm/mach-ep93xx/core.c | 109 ----------------------------------- arch/arm/mach-ep93xx/timer-ep93xx.c | 112 ++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 110 deletions(-) create mode 100644 arch/arm/mach-ep93xx/timer-ep93xx.c diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index 78d427b34b1f..b7ae4345ac08 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile @@ -1,7 +1,7 @@ # # Makefile for the linux kernel. # -obj-y := core.o clock.o +obj-y := core.o clock.o timer-ep93xx.o obj-$(CONFIG_EP93XX_DMA) += dma.o diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 0e571f1749d6..5e2151bcc0c5 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -47,7 +46,6 @@ #include #include -#include #include "soc.h" @@ -73,113 +71,6 @@ void __init ep93xx_map_io(void) iotable_init(ep93xx_io_desc, ARRAY_SIZE(ep93xx_io_desc)); } - -/************************************************************************* - * Timer handling for EP93xx - ************************************************************************* - * The ep93xx has four internal timers. Timers 1, 2 (both 16 bit) and - * 3 (32 bit) count down at 508 kHz, are self-reloading, and can generate - * an interrupt on underflow. Timer 4 (40 bit) counts down at 983.04 kHz, - * is free-running, and can't generate interrupts. - * - * The 508 kHz timers are ideal for use for the timer interrupt, as the - * most common values of HZ divide 508 kHz nicely. We pick one of the 16 - * bit timers (timer 1) since we don't need more than 16 bits of reload - * value as long as HZ >= 8. - * - * The higher clock rate of timer 4 makes it a better choice than the - * other timers for use in gettimeoffset(), while the fact that it can't - * generate interrupts means we don't have to worry about not being able - * to use this timer for something else. We also use timer 4 for keeping - * track of lost jiffies. - */ -#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x)) -#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00) -#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04) -#define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08) -#define EP93XX_TIMER123_CONTROL_ENABLE (1 << 7) -#define EP93XX_TIMER123_CONTROL_MODE (1 << 6) -#define EP93XX_TIMER123_CONTROL_CLKSEL (1 << 3) -#define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c) -#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20) -#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24) -#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28) -#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c) -#define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60) -#define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64) -#define EP93XX_TIMER4_VALUE_HIGH_ENABLE (1 << 8) -#define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80) -#define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84) -#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88) -#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c) - -#define EP93XX_TIMER123_CLOCK 508469 -#define EP93XX_TIMER4_CLOCK 983040 - -#define TIMER1_RELOAD ((EP93XX_TIMER123_CLOCK / HZ) - 1) -#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(EP93XX_TIMER4_CLOCK, HZ) - -static unsigned int last_jiffy_time; - -static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) -{ - /* Writing any value clears the timer interrupt */ - __raw_writel(1, EP93XX_TIMER1_CLEAR); - - /* Recover lost jiffies */ - while ((signed long) - (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) - >= TIMER4_TICKS_PER_JIFFY) { - last_jiffy_time += TIMER4_TICKS_PER_JIFFY; - timer_tick(); - } - - return IRQ_HANDLED; -} - -static struct irqaction ep93xx_timer_irq = { - .name = "ep93xx timer", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = ep93xx_timer_interrupt, -}; - -static u32 ep93xx_gettimeoffset(void) -{ - int offset; - - offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time; - - /* - * Timer 4 is based on a 983.04 kHz reference clock, - * so dividing by 983040 gives the fraction of a second, - * so dividing by 0.983040 converts to uS. - * Refactor the calculation to avoid overflow. - * Finally, multiply by 1000 to give nS. - */ - return (offset + (53 * offset / 3072)) * 1000; -} - -void __init ep93xx_timer_init(void) -{ - u32 tmode = EP93XX_TIMER123_CONTROL_MODE | - EP93XX_TIMER123_CONTROL_CLKSEL; - - arch_gettimeoffset = ep93xx_gettimeoffset; - - /* Enable periodic HZ timer. */ - __raw_writel(tmode, EP93XX_TIMER1_CONTROL); - __raw_writel(TIMER1_RELOAD, EP93XX_TIMER1_LOAD); - __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE, - EP93XX_TIMER1_CONTROL); - - /* Enable lost jiffy timer. */ - __raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE, - EP93XX_TIMER4_VALUE_HIGH); - - setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq); -} - - /************************************************************************* * EP93xx IRQ handling *************************************************************************/ diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c new file mode 100644 index 000000000000..978252c52661 --- /dev/null +++ b/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include +#include +#include "soc.h" + +/************************************************************************* + * Timer handling for EP93xx + ************************************************************************* + * The ep93xx has four internal timers. Timers 1, 2 (both 16 bit) and + * 3 (32 bit) count down at 508 kHz, are self-reloading, and can generate + * an interrupt on underflow. Timer 4 (40 bit) counts down at 983.04 kHz, + * is free-running, and can't generate interrupts. + * + * The 508 kHz timers are ideal for use for the timer interrupt, as the + * most common values of HZ divide 508 kHz nicely. We pick one of the 16 + * bit timers (timer 1) since we don't need more than 16 bits of reload + * value as long as HZ >= 8. + * + * The higher clock rate of timer 4 makes it a better choice than the + * other timers for use in gettimeoffset(), while the fact that it can't + * generate interrupts means we don't have to worry about not being able + * to use this timer for something else. We also use timer 4 for keeping + * track of lost jiffies. + */ +#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x)) +#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00) +#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04) +#define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08) +#define EP93XX_TIMER123_CONTROL_ENABLE (1 << 7) +#define EP93XX_TIMER123_CONTROL_MODE (1 << 6) +#define EP93XX_TIMER123_CONTROL_CLKSEL (1 << 3) +#define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c) +#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20) +#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24) +#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28) +#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c) +#define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60) +#define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64) +#define EP93XX_TIMER4_VALUE_HIGH_ENABLE (1 << 8) +#define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80) +#define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84) +#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88) +#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c) + +#define EP93XX_TIMER123_CLOCK 508469 +#define EP93XX_TIMER4_CLOCK 983040 + +#define TIMER1_RELOAD ((EP93XX_TIMER123_CLOCK / HZ) - 1) +#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(EP93XX_TIMER4_CLOCK, HZ) + +static unsigned int last_jiffy_time; + +static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) +{ + /* Writing any value clears the timer interrupt */ + __raw_writel(1, EP93XX_TIMER1_CLEAR); + + /* Recover lost jiffies */ + while ((signed long) + (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) + >= TIMER4_TICKS_PER_JIFFY) { + last_jiffy_time += TIMER4_TICKS_PER_JIFFY; + timer_tick(); + } + + return IRQ_HANDLED; +} + +static struct irqaction ep93xx_timer_irq = { + .name = "ep93xx timer", + .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = ep93xx_timer_interrupt, +}; + +static u32 ep93xx_gettimeoffset(void) +{ + int offset; + + offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time; + + /* + * Timer 4 is based on a 983.04 kHz reference clock, + * so dividing by 983040 gives the fraction of a second, + * so dividing by 0.983040 converts to uS. + * Refactor the calculation to avoid overflow. + * Finally, multiply by 1000 to give nS. + */ + return (offset + (53 * offset / 3072)) * 1000; +} + +void __init ep93xx_timer_init(void) +{ + u32 tmode = EP93XX_TIMER123_CONTROL_MODE | + EP93XX_TIMER123_CONTROL_CLKSEL; + + arch_gettimeoffset = ep93xx_gettimeoffset; + + /* Enable periodic HZ timer. */ + __raw_writel(tmode, EP93XX_TIMER1_CONTROL); + __raw_writel(TIMER1_RELOAD, EP93XX_TIMER1_LOAD); + __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE, + EP93XX_TIMER1_CONTROL); + + /* Enable lost jiffy timer. */ + __raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE, + EP93XX_TIMER4_VALUE_HIGH); + + setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq); +} -- cgit v1.2.3 From 000bc17817bfe9e7d1fd59cec9e95f6b3638872f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 15 Jun 2015 14:34:03 +0200 Subject: ARM: ep93xx: switch to GENERIC_CLOCKEVENTS This switches the EP93xx to use GENERIC_CLOCKEVENTS and CLKSRC_MMIO. Also implements a sched_clock() hook. Tested on the SIM.ONE. Use only oneshot events. Tested-by: H Hartley Sweeten Reviewed-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/Kconfig | 3 +- arch/arm/mach-ep93xx/timer-ep93xx.c | 110 +++++++++++++++++++++++------------- 2 files changed, 72 insertions(+), 41 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a750c1425c3a..00623a2c5d0c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -418,11 +418,12 @@ config ARCH_EP93XX bool "EP93xx-based" select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_REQUIRE_GPIOLIB - select ARCH_USES_GETTIMEOFFSET select ARM_AMBA select ARM_VIC select CLKDEV_LOOKUP + select CLKSRC_MMIO select CPU_ARM920T + select GENERIC_CLOCKEVENTS help This enables support for the Cirrus EP93xx series of CPUs. diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c index 978252c52661..932236b348bc 100644 --- a/arch/arm/mach-ep93xx/timer-ep93xx.c +++ b/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -1,5 +1,8 @@ #include #include +#include +#include +#include #include #include #include @@ -45,26 +48,68 @@ #define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88) #define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c) -#define EP93XX_TIMER123_CLOCK 508469 -#define EP93XX_TIMER4_CLOCK 983040 +#define EP93XX_TIMER123_RATE 508469 +#define EP93XX_TIMER4_RATE 983040 -#define TIMER1_RELOAD ((EP93XX_TIMER123_CLOCK / HZ) - 1) -#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(EP93XX_TIMER4_CLOCK, HZ) +static u64 notrace ep93xx_read_sched_clock(void) +{ + u64 ret; + + ret = __raw_readl(EP93XX_TIMER4_VALUE_LOW); + ret |= ((u64) (__raw_readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32); + return ret; +} + +cycle_t ep93xx_clocksource_read(struct clocksource *c) +{ + u64 ret; + + ret = __raw_readl(EP93XX_TIMER4_VALUE_LOW); + ret |= ((u64) (__raw_readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32); + return (cycle_t) ret; +} + +static int ep93xx_clkevt_set_next_event(unsigned long next, + struct clock_event_device *evt) +{ + /* Default mode: periodic, off, 508 kHz */ + u32 tmode = EP93XX_TIMER123_CONTROL_MODE | + EP93XX_TIMER123_CONTROL_CLKSEL; + + /* Clear timer */ + __raw_writel(tmode, EP93XX_TIMER1_CONTROL); + + /* Set next event */ + __raw_writel(next, EP93XX_TIMER1_LOAD); + __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE, + EP93XX_TIMER1_CONTROL); + return 0; +} -static unsigned int last_jiffy_time; + +static void ep93xx_clkevt_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + /* Disable timer */ + __raw_writel(0, EP93XX_TIMER1_CONTROL); +} + +static struct clock_event_device ep93xx_clockevent = { + .name = "timer1", + .features = CLOCK_EVT_FEAT_ONESHOT, + .set_mode = ep93xx_clkevt_set_mode, + .set_next_event = ep93xx_clkevt_set_next_event, + .rating = 300, +}; static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) { + struct clock_event_device *evt = dev_id; + /* Writing any value clears the timer interrupt */ __raw_writel(1, EP93XX_TIMER1_CLEAR); - /* Recover lost jiffies */ - while ((signed long) - (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) - >= TIMER4_TICKS_PER_JIFFY) { - last_jiffy_time += TIMER4_TICKS_PER_JIFFY; - timer_tick(); - } + evt->event_handler(evt); return IRQ_HANDLED; } @@ -73,40 +118,25 @@ static struct irqaction ep93xx_timer_irq = { .name = "ep93xx timer", .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = ep93xx_timer_interrupt, + .dev_id = &ep93xx_clockevent, }; -static u32 ep93xx_gettimeoffset(void) -{ - int offset; - - offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time; - - /* - * Timer 4 is based on a 983.04 kHz reference clock, - * so dividing by 983040 gives the fraction of a second, - * so dividing by 0.983040 converts to uS. - * Refactor the calculation to avoid overflow. - * Finally, multiply by 1000 to give nS. - */ - return (offset + (53 * offset / 3072)) * 1000; -} - void __init ep93xx_timer_init(void) { - u32 tmode = EP93XX_TIMER123_CONTROL_MODE | - EP93XX_TIMER123_CONTROL_CLKSEL; - - arch_gettimeoffset = ep93xx_gettimeoffset; - - /* Enable periodic HZ timer. */ - __raw_writel(tmode, EP93XX_TIMER1_CONTROL); - __raw_writel(TIMER1_RELOAD, EP93XX_TIMER1_LOAD); - __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE, - EP93XX_TIMER1_CONTROL); - - /* Enable lost jiffy timer. */ + /* Enable and register clocksource and sched_clock on timer 4 */ __raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE, EP93XX_TIMER4_VALUE_HIGH); + clocksource_mmio_init(NULL, "timer4", + EP93XX_TIMER4_RATE, 200, 40, + ep93xx_clocksource_read); + sched_clock_register(ep93xx_read_sched_clock, 40, + EP93XX_TIMER4_RATE); + /* Set up clockevent on timer 1 */ setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq); + // FIXME: timer one is 16 bits 1-ffff use timer 3 1-ffffffff */ + clockevents_config_and_register(&ep93xx_clockevent, + EP93XX_TIMER123_RATE, + 1, + 0xffffU); } -- cgit v1.2.3 From d118d977c19ef778c597473e1c4e53703681054a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 15 Jun 2015 14:38:16 +0200 Subject: ARM: ep93xx: use non-raw accessors for timer The timer has no business using __raw accessors, in this case the readl/writel makes perfect sense as the changes really need to hit these registers before we continue. Tested-by: H Hartley Sweeten Reviewed-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/mach-ep93xx/timer-ep93xx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c index 932236b348bc..95d54ec769f6 100644 --- a/arch/arm/mach-ep93xx/timer-ep93xx.c +++ b/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -55,8 +55,8 @@ static u64 notrace ep93xx_read_sched_clock(void) { u64 ret; - ret = __raw_readl(EP93XX_TIMER4_VALUE_LOW); - ret |= ((u64) (__raw_readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32); + ret = readl(EP93XX_TIMER4_VALUE_LOW); + ret |= ((u64) (readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32); return ret; } @@ -64,8 +64,8 @@ cycle_t ep93xx_clocksource_read(struct clocksource *c) { u64 ret; - ret = __raw_readl(EP93XX_TIMER4_VALUE_LOW); - ret |= ((u64) (__raw_readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32); + ret = readl(EP93XX_TIMER4_VALUE_LOW); + ret |= ((u64) (readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32); return (cycle_t) ret; } @@ -77,12 +77,12 @@ static int ep93xx_clkevt_set_next_event(unsigned long next, EP93XX_TIMER123_CONTROL_CLKSEL; /* Clear timer */ - __raw_writel(tmode, EP93XX_TIMER1_CONTROL); + writel(tmode, EP93XX_TIMER1_CONTROL); /* Set next event */ - __raw_writel(next, EP93XX_TIMER1_LOAD); - __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE, - EP93XX_TIMER1_CONTROL); + writel(next, EP93XX_TIMER1_LOAD); + writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE, + EP93XX_TIMER1_CONTROL); return 0; } @@ -91,7 +91,7 @@ static void ep93xx_clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { /* Disable timer */ - __raw_writel(0, EP93XX_TIMER1_CONTROL); + writel(0, EP93XX_TIMER1_CONTROL); } static struct clock_event_device ep93xx_clockevent = { @@ -107,7 +107,7 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) struct clock_event_device *evt = dev_id; /* Writing any value clears the timer interrupt */ - __raw_writel(1, EP93XX_TIMER1_CLEAR); + writel(1, EP93XX_TIMER1_CLEAR); evt->event_handler(evt); @@ -124,8 +124,8 @@ static struct irqaction ep93xx_timer_irq = { void __init ep93xx_timer_init(void) { /* Enable and register clocksource and sched_clock on timer 4 */ - __raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE, - EP93XX_TIMER4_VALUE_HIGH); + writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE, + EP93XX_TIMER4_VALUE_HIGH); clocksource_mmio_init(NULL, "timer4", EP93XX_TIMER4_RATE, 200, 40, ep93xx_clocksource_read); -- cgit v1.2.3 From d5878e6e2289418ba870db4afa9e1805e78eb8ee Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 15 Jun 2015 14:42:25 +0200 Subject: ARM: ep93xx: switch clockevent to timer 3 If we switch clock events to timer 3 we will have more bits to use and can sleep longer when using NO_HZ. Tested-by: H Hartley Sweeten Reviewed-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/mach-ep93xx/timer-ep93xx.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c index 95d54ec769f6..9edaa754b689 100644 --- a/arch/arm/mach-ep93xx/timer-ep93xx.c +++ b/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -77,12 +77,12 @@ static int ep93xx_clkevt_set_next_event(unsigned long next, EP93XX_TIMER123_CONTROL_CLKSEL; /* Clear timer */ - writel(tmode, EP93XX_TIMER1_CONTROL); + writel(tmode, EP93XX_TIMER3_CONTROL); /* Set next event */ - writel(next, EP93XX_TIMER1_LOAD); + writel(next, EP93XX_TIMER3_LOAD); writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE, - EP93XX_TIMER1_CONTROL); + EP93XX_TIMER3_CONTROL); return 0; } @@ -91,7 +91,7 @@ static void ep93xx_clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { /* Disable timer */ - writel(0, EP93XX_TIMER1_CONTROL); + writel(0, EP93XX_TIMER3_CONTROL); } static struct clock_event_device ep93xx_clockevent = { @@ -107,7 +107,7 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) struct clock_event_device *evt = dev_id; /* Writing any value clears the timer interrupt */ - writel(1, EP93XX_TIMER1_CLEAR); + writel(1, EP93XX_TIMER3_CLEAR); evt->event_handler(evt); @@ -132,11 +132,10 @@ void __init ep93xx_timer_init(void) sched_clock_register(ep93xx_read_sched_clock, 40, EP93XX_TIMER4_RATE); - /* Set up clockevent on timer 1 */ - setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq); - // FIXME: timer one is 16 bits 1-ffff use timer 3 1-ffffffff */ + /* Set up clockevent on timer 3 */ + setup_irq(IRQ_EP93XX_TIMER3, &ep93xx_timer_irq); clockevents_config_and_register(&ep93xx_clockevent, EP93XX_TIMER123_RATE, 1, - 0xffffU); + 0xffffffffU); } -- cgit v1.2.3 From 8ed3912e17973e48701f65efe4493811914fc5fe Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 16 Jun 2015 09:00:44 +0200 Subject: ARM: ep93xx: update comment on timer usage When refactoring the EP93xx timer some of the documentation git out of date. Update it. Reviewed-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/mach-ep93xx/timer-ep93xx.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c index 9edaa754b689..ac48ac1fd16d 100644 --- a/arch/arm/mach-ep93xx/timer-ep93xx.c +++ b/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -18,15 +18,14 @@ * is free-running, and can't generate interrupts. * * The 508 kHz timers are ideal for use for the timer interrupt, as the - * most common values of HZ divide 508 kHz nicely. We pick one of the 16 - * bit timers (timer 1) since we don't need more than 16 bits of reload - * value as long as HZ >= 8. + * most common values of HZ divide 508 kHz nicely. We pick the 32 bit + * timer (timer 3) to get as long sleep intervals as possible when using + * CONFIG_NO_HZ. * * The higher clock rate of timer 4 makes it a better choice than the - * other timers for use in gettimeoffset(), while the fact that it can't - * generate interrupts means we don't have to worry about not being able - * to use this timer for something else. We also use timer 4 for keeping - * track of lost jiffies. + * other timers for use as clock source and for sched_clock(), providing + * a stable 40 bit time base. + ************************************************************************* */ #define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x)) #define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00) -- cgit v1.2.3 From b8824c9a54bb380367541718b50f03cb08524c8d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Jun 2015 10:35:06 -0700 Subject: ARM: ep93xx: remove memory configuration options The ARM_PATCH_PHYS_VIRT option makes the ep93xx memory configuration options obsolete. This allows support for all the ep93xx variations to be built into a single kernel. Signed-off-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/Kconfig | 8 +++--- arch/arm/mach-ep93xx/Kconfig | 54 -------------------------------------- arch/arm/mach-ep93xx/Makefile.boot | 15 +---------- 3 files changed, 4 insertions(+), 73 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 00623a2c5d0c..d504acc0da52 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -268,7 +268,6 @@ config PHYS_OFFSET depends on !ARM_PATCH_PHYS_VIRT default DRAM_BASE if !MMU default 0x00000000 if ARCH_EBSA110 || \ - EP93XX_SDCE3_SYNC_PHYS_OFFSET || \ ARCH_FOOTBRIDGE || \ ARCH_INTEGRATOR || \ ARCH_IOP13XX || \ @@ -277,10 +276,7 @@ config PHYS_OFFSET default 0x10000000 if ARCH_OMAP1 || ARCH_RPC default 0x20000000 if ARCH_S5PV210 default 0x70000000 if REALVIEW_HIGH_PHYS_OFFSET - default 0xc0000000 if EP93XX_SDCE0_PHYS_OFFSET || ARCH_SA1100 - default 0xd0000000 if EP93XX_SDCE1_PHYS_OFFSET - default 0xe0000000 if EP93XX_SDCE2_PHYS_OFFSET - default 0xf0000000 if EP93XX_SDCE3_ASYNC_PHYS_OFFSET + default 0xc0000000 if ARCH_SA1100 help Please provide the physical address corresponding to the location of main memory in your system. @@ -419,7 +415,9 @@ config ARCH_EP93XX select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_REQUIRE_GPIOLIB select ARM_AMBA + select ARM_PATCH_PHYS_VIRT select ARM_VIC + select AUTO_ZRELADDR select CLKDEV_LOOKUP select CLKSRC_MMIO select CPU_ARM920T diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig index bec570ae6494..61a75ca3684e 100644 --- a/arch/arm/mach-ep93xx/Kconfig +++ b/arch/arm/mach-ep93xx/Kconfig @@ -15,45 +15,8 @@ config CRUNCH comment "EP93xx Platforms" -choice - prompt "EP93xx first SDRAM bank selection" - default EP93XX_SDCE3_SYNC_PHYS_OFFSET - -config EP93XX_SDCE3_SYNC_PHYS_OFFSET - bool "0x00000000 - SDCE3/SyncBoot" - help - Select this option if you want support for EP93xx boards with the - first SDRAM bank at 0x00000000. - -config EP93XX_SDCE0_PHYS_OFFSET - bool "0xc0000000 - SDCEO" - help - Select this option if you want support for EP93xx boards with the - first SDRAM bank at 0xc0000000. - -config EP93XX_SDCE1_PHYS_OFFSET - bool "0xd0000000 - SDCE1" - help - Select this option if you want support for EP93xx boards with the - first SDRAM bank at 0xd0000000. - -config EP93XX_SDCE2_PHYS_OFFSET - bool "0xe0000000 - SDCE2" - help - Select this option if you want support for EP93xx boards with the - first SDRAM bank at 0xe0000000. - -config EP93XX_SDCE3_ASYNC_PHYS_OFFSET - bool "0xf0000000 - SDCE3/AsyncBoot" - help - Select this option if you want support for EP93xx boards with the - first SDRAM bank at 0xf0000000. - -endchoice - config MACH_ADSSPHERE bool "Support ADS Sphere" - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET help Say 'Y' here if you want your kernel to support the ADS Sphere board. @@ -63,7 +26,6 @@ config MACH_EDB93XX config MACH_EDB9301 bool "Support Cirrus Logic EDB9301" - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET select MACH_EDB93XX help Say 'Y' here if you want your kernel to support the Cirrus @@ -71,7 +33,6 @@ config MACH_EDB9301 config MACH_EDB9302 bool "Support Cirrus Logic EDB9302" - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET select MACH_EDB93XX help Say 'Y' here if you want your kernel to support the Cirrus @@ -79,7 +40,6 @@ config MACH_EDB9302 config MACH_EDB9302A bool "Support Cirrus Logic EDB9302A" - depends on EP93XX_SDCE0_PHYS_OFFSET select MACH_EDB93XX help Say 'Y' here if you want your kernel to support the Cirrus @@ -87,7 +47,6 @@ config MACH_EDB9302A config MACH_EDB9307 bool "Support Cirrus Logic EDB9307" - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET select MACH_EDB93XX help Say 'Y' here if you want your kernel to support the Cirrus @@ -95,7 +54,6 @@ config MACH_EDB9307 config MACH_EDB9307A bool "Support Cirrus Logic EDB9307A" - depends on EP93XX_SDCE0_PHYS_OFFSET select MACH_EDB93XX help Say 'Y' here if you want your kernel to support the Cirrus @@ -103,7 +61,6 @@ config MACH_EDB9307A config MACH_EDB9312 bool "Support Cirrus Logic EDB9312" - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET select MACH_EDB93XX help Say 'Y' here if you want your kernel to support the Cirrus @@ -111,7 +68,6 @@ config MACH_EDB9312 config MACH_EDB9315 bool "Support Cirrus Logic EDB9315" - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET select MACH_EDB93XX help Say 'Y' here if you want your kernel to support the Cirrus @@ -119,14 +75,12 @@ config MACH_EDB9315 config MACH_EDB9315A bool "Support Cirrus Logic EDB9315A" - depends on EP93XX_SDCE0_PHYS_OFFSET select MACH_EDB93XX help Say 'Y' here if you want your kernel to support the Cirrus Logic EDB9315A Evaluation Board. config MACH_GESBC9312 - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET bool "Support Glomation GESBC-9312-sx" help Say 'Y' here if you want your kernel to support the Glomation @@ -137,7 +91,6 @@ config MACH_MICRO9 config MACH_MICRO9H bool "Support Contec Micro9-High" - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET select MACH_MICRO9 help Say 'Y' here if you want your kernel to support the @@ -145,7 +98,6 @@ config MACH_MICRO9H config MACH_MICRO9M bool "Support Contec Micro9-Mid" - depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET select MACH_MICRO9 help Say 'Y' here if you want your kernel to support the @@ -153,7 +105,6 @@ config MACH_MICRO9M config MACH_MICRO9L bool "Support Contec Micro9-Lite" - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET select MACH_MICRO9 help Say 'Y' here if you want your kernel to support the @@ -161,7 +112,6 @@ config MACH_MICRO9L config MACH_MICRO9S bool "Support Contec Micro9-Slim" - depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET select MACH_MICRO9 help Say 'Y' here if you want your kernel to support the @@ -169,28 +119,24 @@ config MACH_MICRO9S config MACH_SIM_ONE bool "Support Simplemachines Sim.One board" - depends on EP93XX_SDCE0_PHYS_OFFSET help Say 'Y' here if you want your kernel to support the Simplemachines Sim.One board. config MACH_SNAPPER_CL15 bool "Support Bluewater Systems Snapper CL15 Module" - depends on EP93XX_SDCE0_PHYS_OFFSET help Say 'Y' here if you want your kernel to support the Bluewater Systems Snapper CL15 Module. config MACH_TS72XX bool "Support Technologic Systems TS-72xx SBC" - depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET help Say 'Y' here if you want your kernel to support the Technologic Systems TS-72xx board. config MACH_VISION_EP9307 bool "Support Vision Engraving Systems EP9307 SoM" - depends on EP93XX_SDCE0_PHYS_OFFSET help Say 'Y' here if you want your kernel to support the Vision Engraving Systems EP9307 SoM. diff --git a/arch/arm/mach-ep93xx/Makefile.boot b/arch/arm/mach-ep93xx/Makefile.boot index d3113a71cb40..ed82ed7c949f 100644 --- a/arch/arm/mach-ep93xx/Makefile.boot +++ b/arch/arm/mach-ep93xx/Makefile.boot @@ -1,14 +1 @@ - zreladdr-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) += 0x00008000 -params_phys-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) := 0x00000100 - - zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) += 0xc0008000 -params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0000100 - - zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) += 0xd0008000 -params_phys-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0000100 - - zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) += 0xe0008000 -params_phys-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0000100 - - zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) += 0xf0008000 -params_phys-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0000100 +# Empty file waiting for deletion once Makefile.boot isn't needed any more. -- cgit v1.2.3 From e8a7d2bb93f8b713b0536ef6f86b745b288fa96f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 18 Jun 2015 16:46:34 +0200 Subject: ARM: ep93xx: toss the device ID into the entropy pool It doesn't hurt to add this random stuff into the entropy pool as is custom to do with device-unique numbers. Reviewed-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/mach-ep93xx/core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 5e2151bcc0c5..c393b1b0310d 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -862,6 +863,12 @@ static const char __init *ep93xx_get_soc_id(void) if (id != id2) return "invalid"; + /* Toss the unique ID into the entropy pool */ + add_device_randomness(&id2, 4); + add_device_randomness(&id3, 4); + add_device_randomness(&id4, 4); + add_device_randomness(&id5, 4); + snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id), "%08x%08x%08x%08x", id2, id3, id4, id5); -- cgit v1.2.3 From 25105231f071960c0f7109f0e01ba55c7b823701 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 16 Jun 2015 09:52:46 -0700 Subject: ARM: ep93xx: vision_ep9307: enable DMA for SPI Enable the 'use_dma' flag in the SPI platform data to improve the speed of the mmc_spi driver. Signed-off-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/mach-ep93xx/vision_ep9307.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index 6bc1c181581d..aa87dfa5e805 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c @@ -281,7 +281,8 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { }; static struct ep93xx_spi_info vision_spi_master __initdata = { - .num_chipselect = ARRAY_SIZE(vision_spi_board_info), + .num_chipselect = ARRAY_SIZE(vision_spi_board_info), + .use_dma = 1, }; /************************************************************************* -- cgit v1.2.3 From b07b4e2972372c1ca86dda78802aecc01cbc187a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 16 Jun 2015 09:52:47 -0700 Subject: ARM: ep93xx: vision_ep9307: add audio support Add I2S audio support to the vision_ep9307 system. Signed-off-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/mach-ep93xx/vision_ep9307.c | 58 ++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index aa87dfa5e805..ff22a6a6e2bf 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -168,6 +170,35 @@ static struct i2c_board_info vision_i2c_info[] __initdata = { }, }; +/************************************************************************* + * SPI CS4271 Audio Codec + *************************************************************************/ +static struct cs4271_platform_data vision_cs4271_data = { + .gpio_nreset = EP93XX_GPIO_LINE_H(2), +}; + +static int vision_cs4271_hw_setup(struct spi_device *spi) +{ + return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6, + GPIOF_OUT_INIT_HIGH, spi->modalias); +} + +static void vision_cs4271_hw_cleanup(struct spi_device *spi) +{ + gpio_free(EP93XX_GPIO_LINE_EGPIO6); +} + +static void vision_cs4271_hw_cs_control(struct spi_device *spi, int value) +{ + gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value); +} + +static struct ep93xx_spi_chip_ops vision_cs4271_hw = { + .setup = vision_cs4271_hw_setup, + .cleanup = vision_cs4271_hw_cleanup, + .cs_control = vision_cs4271_hw_cs_control, +}; + /************************************************************************* * SPI Flash *************************************************************************/ @@ -262,12 +293,20 @@ static struct ep93xx_spi_chip_ops vision_spi_mmc_hw = { *************************************************************************/ static struct spi_board_info vision_spi_board_info[] __initdata = { { + .modalias = "cs4271", + .platform_data = &vision_cs4271_data, + .controller_data = &vision_cs4271_hw, + .max_speed_hz = 6000000, + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_3, + }, { .modalias = "sst25l", .platform_data = &vision_spi_flash_data, .controller_data = &vision_spi_flash_hw, .max_speed_hz = 20000000, .bus_num = 0, - .chip_select = 0, + .chip_select = 1, .mode = SPI_MODE_3, }, { .modalias = "mmc_spi", @@ -275,7 +314,7 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { .controller_data = &vision_spi_mmc_hw, .max_speed_hz = 20000000, .bus_num = 0, - .chip_select = 1, + .chip_select = 2, .mode = SPI_MODE_3, }, }; @@ -285,6 +324,20 @@ static struct ep93xx_spi_info vision_spi_master __initdata = { .use_dma = 1, }; +/************************************************************************* + * I2S Audio + *************************************************************************/ +static struct platform_device vision_audio_device = { + .name = "edb93xx-audio", + .id = -1, +}; + +static void __init vision_register_i2s(void) +{ + ep93xx_register_i2s(); + platform_device_register(&vision_audio_device); +} + /************************************************************************* * Machine Initialization *************************************************************************/ @@ -310,6 +363,7 @@ static void __init vision_init_machine(void) ARRAY_SIZE(vision_i2c_info)); ep93xx_register_spi(&vision_spi_master, vision_spi_board_info, ARRAY_SIZE(vision_spi_board_info)); + vision_register_i2s(); } MACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307") -- cgit v1.2.3 From 109965a32b67cf45951f4fcb92c8d606c0474619 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Jul 2015 16:56:40 +0200 Subject: ARM: ep93xx: simone: enable DMA on the SPI host The SPI host on the SIM.ONE is used for the MMC/SD card and will badly need this turbo boost. Reviewed-by: H Hartley Sweeten Signed-off-by: Linus Walleij --- arch/arm/mach-ep93xx/simone.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index 3c950f5864f3..d0938a219443 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c @@ -169,6 +169,7 @@ static struct spi_board_info simone_spi_devices[] __initdata = { static struct ep93xx_spi_info simone_spi_info __initdata = { .num_chipselect = ARRAY_SIZE(simone_spi_devices), + .use_dma = 1, }; static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = { -- cgit v1.2.3