diff options
author | Koen Vandeputte <koen.vandeputte@ncentric.com> | 2017-02-07 16:19:18 +0100 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2017-02-10 11:05:57 +0100 |
commit | 1db4135e32e03c0131301ed46d906a2bf8f08c9b (patch) | |
tree | f1da4a38a5ee6d7337843d9528f7e21fa61a006f /target/linux/cns3xxx/patches-4.9/090-timers.patch | |
parent | b96566aad4340c5b790bdaea0514885857ea84bf (diff) | |
download | mtk-20170518-1db4135e32e03c0131301ed46d906a2bf8f08c9b.zip mtk-20170518-1db4135e32e03c0131301ed46d906a2bf8f08c9b.tar.gz mtk-20170518-1db4135e32e03c0131301ed46d906a2bf8f08c9b.tar.bz2 |
cns3xxx: add preliminary 4.9 support
Adds preliminary kernel 4.9 support for this target.
- Refreshed/Updated all patches
Added 3 new patches:
- 093 --> Add virtual PCI MMIO mapping
- 230 --> Remove deprecated code
- 240 --> Rework AT24 eeprom code to use the new NVMEM API
Compiled & tested on cns3xxx (gw2388)
Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Diffstat (limited to 'target/linux/cns3xxx/patches-4.9/090-timers.patch')
-rw-r--r-- | target/linux/cns3xxx/patches-4.9/090-timers.patch | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/target/linux/cns3xxx/patches-4.9/090-timers.patch b/target/linux/cns3xxx/patches-4.9/090-timers.patch new file mode 100644 index 0000000..6f7713f --- /dev/null +++ b/target/linux/cns3xxx/patches-4.9/090-timers.patch @@ -0,0 +1,103 @@ +--- a/arch/arm/mach-cns3xxx/core.c ++++ b/arch/arm/mach-cns3xxx/core.c +@@ -138,6 +138,7 @@ static int cns3xxx_set_oneshot(struct cl + + /* period set, and timer enabled in 'next_event' hook */ + ctrl |= (1 << 2) | (1 << 9); ++ writel(0, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET); + writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + return 0; + } +@@ -148,7 +149,7 @@ static int cns3xxx_set_periodic(struct c + int pclk = cns3xxx_cpu_clock() / 8; + int reload; + +- reload = pclk * 20 / (3 * HZ) * 0x25000; ++ reload = pclk * 1000000 / HZ; + writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET); + ctrl |= (1 << 0) | (1 << 2) | (1 << 9); + writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); +@@ -175,7 +176,7 @@ static struct clock_event_device cns3xxx + .set_state_oneshot = cns3xxx_set_oneshot, + .tick_resume = cns3xxx_shutdown, + .set_next_event = cns3xxx_timer_set_next_event, +- .rating = 350, ++ .rating = 300, + .cpumask = cpu_all_mask, + }; + +@@ -220,6 +221,32 @@ static void __init cns3xxx_init_twd(void + twd_local_timer_register(&cns3xx_twd_local_timer); + } + ++static cycle_t cns3xxx_get_cycles(struct clocksource *cs) ++{ ++ u64 val; ++ ++ val = readl(cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET); ++ val &= 0xffff; ++ ++ return ((val << 32) | readl(cns3xxx_tmr1 + TIMER_FREERUN_OFFSET)); ++} ++ ++static struct clocksource clocksource_cns3xxx = { ++ .name = "freerun", ++ .rating = 200, ++ .read = cns3xxx_get_cycles, ++ .mask = CLOCKSOURCE_MASK(48), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++static void __init cns3xxx_clocksource_init(void) ++{ ++ /* Reset the FreeRunning counter */ ++ writel((1 << 16), cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET); ++ ++ clocksource_register_khz(&clocksource_cns3xxx, 100); ++} ++ + /* + * Set up the clock source and clock events devices + */ +@@ -237,13 +264,12 @@ static void __init __cns3xxx_timer_init( + /* stop free running timer3 */ + writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET); + +- /* timer1 */ +- writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET); +- writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET); +- + writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET); + writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET); + ++ val = (cns3xxx_cpu_clock() >> 3) * 1000000 / HZ; ++ writel(val, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET); ++ + /* mask irq, non-mask timer1 overflow */ + irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET); + irq_mask &= ~(1 << 2); +@@ -255,23 +281,9 @@ static void __init __cns3xxx_timer_init( + val |= (1 << 9); + writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); + +- /* timer2 */ +- writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET); +- writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET); +- +- /* mask irq */ +- irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET); +- irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5)); +- writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET); +- +- /* down counter */ +- val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); +- val |= (1 << 10); +- writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET); +- +- /* Make irqs happen for the system timer */ + setup_irq(timer_irq, &cns3xxx_timer_irq); + ++ cns3xxx_clocksource_init(); + cns3xxx_clockevents_init(timer_irq); + cns3xxx_init_twd(); + } |