Re: [1/2] RTC: Add core rtc support for Gemini Soc devices

From: Roman Yeryomin
Date: Wed Jul 08 2015 - 18:37:32 EST


On 2015-05-08 19:08, Arnd Bergmann wrote:
On Thursday 07 May 2015 12:03:25 Roman Yeryomin wrote:
On 2015-05-06 22:22, Arnd Bergmann wrote:
> On Wednesday 06 May 2015 19:21:21 Roman Yeryomin wrote:
>>
>> > Thanks to point that, I'll merge that one which seems clean enough:
>> > http://git.openwrt.org/?p=openwrt.git;a=blob;f=target/linux/gemini/files/drivers/rtc/rtc-gemini.c;h=587d8122b2fbb1230437eadcce4789a53aa60ee5;hb=4c637410a2a1ab45988e8ca6202554a502102039
>>
>> For 3.18 (and up) to work on gemini 160-gemini-timers.patch is vital.
>> Without that timers are broken and cpu is super slow.
>
> Do you know what part of the patch is the actual bug fix? We should
> probably
> merge that separately and mark it for stable backports, while the bulk
> of that
> patch seems to just rearrange code.
>
> Arnd

Sorry, didn't try to extract the exact lines it but I guess it's that
part which touches the scheduler clock code.
Because without that patch sched clock runs at 100Hz instead of 25MHz.
I can dive into this deeper if you want, I just didn't see the need.

I think that would be helpful, yes.


OK, here are the minimal changes required (see attachment). Tested on 4.1.1
Let me know if you want me to submit it in some other way.

Regards,
Roman--- a/arch/arm/mach-gemini/time.c
+++ b/arch/arm/mach-gemini/time.c
@@ -15,6 +15,7 @@
#include <asm/mach/time.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
+#include <linux/sched_clock.h>

/*
* Register definitions for the timers
@@ -34,9 +35,17 @@
#define TIMER_3_CR_ENABLE (1 << 6)
#define TIMER_3_CR_CLOCK (1 << 7)
#define TIMER_3_CR_INT (1 << 8)
+#define TIMER_1_CR_UPDOWN (1 << 9)
+#define TIMER_2_CR_UPDOWN (1 << 10)
+#define TIMER_3_CR_UPDOWN (1 << 11)

static unsigned int tick_rate;

+static u64 notrace gemini_read_sched_clock(void)
+{
+ return readl(TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER3_BASE)));
+}
+
static int gemini_timer_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
@@ -155,14 +164,18 @@ void __init gemini_timer_init(void)
*/
setup_irq(IRQ_TIMER2, &gemini_timer_irq);

- /* Enable and use TIMER1 as clock source */
- writel(0xffffffff, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE)));
- writel(0xffffffff, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER1_BASE)));
- writel(TIMER_1_CR_ENABLE, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
- if (clocksource_mmio_init(TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER1_BASE)),
- "TIMER1", tick_rate, 300, 32,
+ /* Enable and use TIMER3 as clock source */
+ writel(0, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER3_BASE)));
+ writel(0, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER3_BASE)));
+ writel(0, TIMER_MATCH1(IO_ADDRESS(GEMINI_TIMER3_BASE)));
+ writel(0, TIMER_MATCH2(IO_ADDRESS(GEMINI_TIMER3_BASE)));
+ writel(TIMER_3_CR_ENABLE | TIMER_3_CR_UPDOWN,
+ TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+ if (clocksource_mmio_init(TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER3_BASE)),
+ "TIMER3", tick_rate, 300, 32,
clocksource_mmio_readl_up))
pr_err("timer: failed to initialize gemini clock source\n");
+ sched_clock_register(gemini_read_sched_clock, 32, tick_rate);

/* Configure and register the clockevent */
clockevents_config_and_register(&gemini_clockevent, tick_rate,