Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933508AbeAHNbd (ORCPT + 1 other); Mon, 8 Jan 2018 08:31:33 -0500 Received: from mail-wm0-f68.google.com ([74.125.82.68]:44441 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932821AbeAHN3u (ORCPT ); Mon, 8 Jan 2018 08:29:50 -0500 X-Google-Smtp-Source: ACJfBouAf+LIIXbD2hH+Ma2qvWMwWsMLDhFeCU/fxe7J2s/sWXgRY6B6ffwrvLg89Ver/XUBxrFM1g== From: Daniel Lezcano To: tglx@linutronix.de Cc: linux-kernel@vger.kernel.org, Benjamin Gaignard , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org (moderated list:ARM/STM32 ARCHITECTURE) Subject: [PATCH 15/20] clocksource/drivers/stm32: Compute a prescaler value with a targeted rate Date: Mon, 8 Jan 2018 14:28:54 +0100 Message-Id: <1515418139-23276-15-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515418139-23276-1-git-send-email-daniel.lezcano@linaro.org> References: <1bbaef2e-4080-3f54-7db3-a8989acfd691@free.fr> <1515418139-23276-1-git-send-email-daniel.lezcano@linaro.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: From: Benjamin Gaignard The prescaler value is arbitrarily set to 1024 without any regard to the timer frequency. For 32bits 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 16bits timers a prescaler value is needed if we don't want to wrap too often per second which is unefficient and adds more and more error margin. With a targeted clock of 10MHz, the 16bits are precise enough whatever the timer frequency is as we will compute the prescaler. Signed-off-by: Benjamin Gaignard Signed-off-by: Daniel Lezcano Tested-by: Benjamin Gaignard Acked-by: Benjamin Gaignard --- 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 862134e..ac55896 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); -- 2.7.4