Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753787AbeAHRgj (ORCPT + 1 other); Mon, 8 Jan 2018 12:36:39 -0500 Received: from terminus.zytor.com ([65.50.211.136]:39071 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751159AbeAHRgh (ORCPT ); Mon, 8 Jan 2018 12:36:37 -0500 Date: Mon, 8 Jan 2018 09:32:14 -0800 From: tip-bot for Benjamin Gaignard Message-ID: Cc: mingo@kernel.org, mcoquelin.stm32@gmail.com, alexandre.torgue@st.com, torvalds@linux-foundation.org, hpa@zytor.com, linux-kernel@vger.kernel.org, peterz@infradead.org, tglx@linutronix.de, benjamin.gaignard@st.com, daniel.lezcano@linaro.org Reply-To: daniel.lezcano@linaro.org, tglx@linutronix.de, benjamin.gaignard@st.com, linux-kernel@vger.kernel.org, peterz@infradead.org, hpa@zytor.com, torvalds@linux-foundation.org, alexandre.torgue@st.com, mingo@kernel.org, mcoquelin.stm32@gmail.com In-Reply-To: <1515418139-23276-15-git-send-email-daniel.lezcano@linaro.org> References: <1515418139-23276-15-git-send-email-daniel.lezcano@linaro.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:timers/core] clocksource/drivers/stm32: Compute a prescaler value with a targeted rate Git-Commit-ID: 4744daa10dcd3a1470fbeba4945fbf44dcb1b0d1 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: Commit-ID: 4744daa10dcd3a1470fbeba4945fbf44dcb1b0d1 Gitweb: https://git.kernel.org/tip/4744daa10dcd3a1470fbeba4945fbf44dcb1b0d1 Author: Benjamin Gaignard AuthorDate: Mon, 8 Jan 2018 14:28:54 +0100 Committer: Ingo Molnar CommitDate: Mon, 8 Jan 2018 17:57:25 +0100 clocksource/drivers/stm32: Compute a prescaler value with a targeted rate The prescaler value is arbitrarily set to 1024 without any regard to the timer frequency. For 32-bit timers, there is no need to set a prescaler value as they wrap in an acceptable interval and give the opportunity to have precise timers on this platform. However, for 16-bit timers a prescaler value is needed if we don't want to wrap too often per second which is inefficient and adds more and more error margin. With a targeted clock of 10MHz, the 16 bits are precise enough whatever the timer frequency is as we will compute the prescaler. Tested-by: Benjamin Gaignard Signed-off-by: Benjamin Gaignard Signed-off-by: Daniel Lezcano Acked-by: Benjamin Gaignard Cc: Alexandre Torgue Cc: Linus Torvalds Cc: Maxime Coquelin Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1515418139-23276-15-git-send-email-daniel.lezcano@linaro.org Signed-off-by: Ingo Molnar --- drivers/clocksource/timer-stm32.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c index 33c7c90..928ac28 100644 --- a/drivers/clocksource/timer-stm32.c +++ b/drivers/clocksource/timer-stm32.c @@ -37,6 +37,9 @@ #define TIM_EGR_UG BIT(0) +#define TIM_PSC_MAX USHRT_MAX +#define TIM_PSC_CLKRATE 10000 + static int stm32_clock_event_shutdown(struct clock_event_device *clkevt) { struct timer_of *to = to_timer_of(clkevt); @@ -116,7 +119,14 @@ static void __init stm32_clockevent_init(struct timer_of *to) prescaler = 1; to->clkevt.rating = 250; } else { - prescaler = 1024; + prescaler = DIV_ROUND_CLOSEST(timer_of_rate(to), + TIM_PSC_CLKRATE); + /* + * The prescaler register is an u16, the variable + * can't be greater than TIM_PSC_MAX, let's cap it in + * this case. + */ + prescaler = prescaler < TIM_PSC_MAX ? prescaler : TIM_PSC_MAX; to->clkevt.rating = 100; } writel_relaxed(0, timer_of_base(to) + TIM_ARR);