diff options
Diffstat (limited to 'debian/patches-rt/0030-clocksource-TCLIB-Allow-higher-clock-rates-for-clock.patch')
-rw-r--r-- | debian/patches-rt/0030-clocksource-TCLIB-Allow-higher-clock-rates-for-clock.patch | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/debian/patches-rt/0030-clocksource-TCLIB-Allow-higher-clock-rates-for-clock.patch b/debian/patches-rt/0030-clocksource-TCLIB-Allow-higher-clock-rates-for-clock.patch new file mode 100644 index 000000000..92ac4b1e3 --- /dev/null +++ b/debian/patches-rt/0030-clocksource-TCLIB-Allow-higher-clock-rates-for-clock.patch @@ -0,0 +1,170 @@ +From 785e3ab127a7476bb4da35910092b0d2fd767a47 Mon Sep 17 00:00:00 2001 +From: Benedikt Spranger <b.spranger@linutronix.de> +Date: Mon, 8 Mar 2010 18:57:04 +0100 +Subject: [PATCH 030/347] clocksource: TCLIB: Allow higher clock rates for + clock events +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.246-rt110.tar.xz + +As default the TCLIB uses the 32KiHz base clock rate for clock events. +Add a compile time selection to allow higher clock resulution. + +(fixed up by Sami Pietikäinen <Sami.Pietikainen@wapice.com>) + +Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +--- + drivers/clocksource/tcb_clksrc.c | 36 +++++++++++++++++++------------- + drivers/misc/Kconfig | 12 +++++++++-- + 2 files changed, 31 insertions(+), 17 deletions(-) + +diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c +index de6baf564dfe..ba15242a6066 100644 +--- a/drivers/clocksource/tcb_clksrc.c ++++ b/drivers/clocksource/tcb_clksrc.c +@@ -25,8 +25,7 @@ + * this 32 bit free-running counter. the second channel is not used. + * + * - The third channel may be used to provide a 16-bit clockevent +- * source, used in either periodic or oneshot mode. This runs +- * at 32 KiHZ, and can handle delays of up to two seconds. ++ * source, used in either periodic or oneshot mode. + * + * A boot clocksource and clockevent source are also currently needed, + * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so +@@ -127,6 +126,7 @@ struct tc_clkevt_device { + struct clock_event_device clkevt; + struct clk *clk; + bool clk_enabled; ++ u32 freq; + void __iomem *regs; + }; + +@@ -135,13 +135,6 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt) + return container_of(clkevt, struct tc_clkevt_device, clkevt); + } + +-/* For now, we always use the 32K clock ... this optimizes for NO_HZ, +- * because using one of the divided clocks would usually mean the +- * tick rate can never be less than several dozen Hz (vs 0.5 Hz). +- * +- * A divided clock could be good for high resolution timers, since +- * 30.5 usec resolution can seem "low". +- */ + static u32 timer_clock; + + static void tc_clk_disable(struct clock_event_device *d) +@@ -191,7 +184,7 @@ static int tc_set_oneshot(struct clock_event_device *d) + + tc_clk_enable(d); + +- /* slow clock, count up to RC, then irq and stop */ ++ /* count up to RC, then irq and stop */ + writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | + ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR)); + writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); +@@ -213,10 +206,10 @@ static int tc_set_periodic(struct clock_event_device *d) + */ + tc_clk_enable(d); + +- /* slow clock, count up to RC, then irq and restart */ ++ /* count up to RC, then irq and restart */ + writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, + regs + ATMEL_TC_REG(2, CMR)); +- writel((32768 + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); ++ writel((tcd->freq + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); + + /* Enable clock and interrupts on RC compare */ + writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); +@@ -243,7 +236,11 @@ static struct tc_clkevt_device clkevt = { + .features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT, + /* Should be lower than at91rm9200's system timer */ ++#ifdef CONFIG_ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK + .rating = 125, ++#else ++ .rating = 200, ++#endif + .set_next_event = tc_next_event, + .set_state_shutdown = tc_shutdown_clk_off, + .set_state_periodic = tc_set_periodic, +@@ -265,8 +262,9 @@ static irqreturn_t ch2_irq(int irq, void *handle) + return IRQ_NONE; + } + +-static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) ++static int __init setup_clkevents(struct atmel_tc *tc, int divisor_idx) + { ++ unsigned divisor = atmel_tc_divisors[divisor_idx]; + int ret; + struct clk *t2_clk = tc->clk[2]; + int irq = tc->irq[2]; +@@ -287,7 +285,11 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) + clkevt.regs = tc->regs; + clkevt.clk = t2_clk; + +- timer_clock = clk32k_divisor_idx; ++ timer_clock = divisor_idx; ++ if (!divisor) ++ clkevt.freq = 32768; ++ else ++ clkevt.freq = clk_get_rate(t2_clk) / divisor; + + clkevt.clkevt.cpumask = cpumask_of(0); + +@@ -298,7 +300,7 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) + return ret; + } + +- clockevents_config_and_register(&clkevt.clkevt, 32768, 1, 0xffff); ++ clockevents_config_and_register(&clkevt.clkevt, clkevt.freq, 1, 0xffff); + + return ret; + } +@@ -435,7 +437,11 @@ static int __init tcb_clksrc_init(void) + goto err_disable_t1; + + /* channel 2: periodic and oneshot timer support */ ++#ifdef CONFIG_ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK + ret = setup_clkevents(tc, clk32k_divisor_idx); ++#else ++ ret = setup_clkevents(tc, best_divisor_idx); ++#endif + if (ret) + goto err_unregister_clksrc; + +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 3726eacdf65d..0900dec7ec04 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -69,8 +69,7 @@ config ATMEL_TCB_CLKSRC + are combined to make a single 32-bit timer. + + When GENERIC_CLOCKEVENTS is defined, the third timer channel +- may be used as a clock event device supporting oneshot mode +- (delays of up to two seconds) based on the 32 KiHz clock. ++ may be used as a clock event device supporting oneshot mode. + + config ATMEL_TCB_CLKSRC_BLOCK + int +@@ -83,6 +82,15 @@ config ATMEL_TCB_CLKSRC_BLOCK + TC can be used for other purposes, such as PWM generation and + interval timing. + ++config ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK ++ bool "TC Block use 32 KiHz clock" ++ depends on ATMEL_TCB_CLKSRC ++ default y ++ help ++ Select this to use 32 KiHz base clock rate as TC block clock ++ source for clock events. ++ ++ + config DUMMY_IRQ + tristate "Dummy IRQ handler" + default n +-- +2.36.1 + |