From patchwork Mon Jan 8 13:28:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 123715 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2727659qgn; Mon, 8 Jan 2018 05:30:25 -0800 (PST) X-Google-Smtp-Source: ACJfBotno/jykRexNrvzKKKPLxPLfLFybrk9aymacAqXqiXxvhwgBqoJqZEHNFWwutFE2xqDxJpg X-Received: by 10.99.97.209 with SMTP id v200mr1748232pgb.126.1515418225644; Mon, 08 Jan 2018 05:30:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515418225; cv=none; d=google.com; s=arc-20160816; b=QVnhF05o7DQsVZKZENgyNFE2caoL9aCuzAvCejLSkiCGsg6AbVbX/DT+4rYoYeUndV aXr9nWYOwGfcFUWE3J+ZgyabOlfzPAWccjGC71iWJQSt6muvMKp8a4a/AClqZYZ2nYlp LDRKUdd00LkJ5oNQzWYU+Yw8U12qjvDF+oWfyFf//IGmac8Qjjlg+BM9hG1dcdQWJAnf 00KN3sD08VmeugVdLUoeQKYIupyYJm0BJAn3XTvSUJ54x1+ECP29KkHt/iayriLLE96y op3LL+nIJdvTMEgLqK5+jiCzURkFwnaN6SuXZMrGeHLkC/Cwt5s3chTIYRERuKHn/AG0 KbBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=WxW0wTXrQlL11cQloR5uFczaFJHJAFTucfu/a7Auct0=; b=jrY/ridEwqg8/w7syHU5LRXotR2y3R8PowvSIDDHSdjvO2ggwbhhJOesp8PA0dVa2h 09C6m7NoV5iGwJnxWcXOKA/cUIB0MF819lNILSmLCVot/t67BAdMErrDlK9/rZleT2r8 XO8k1ttyx84mwleYNkGF6DMiQ6WqTTzh4oSzVeZHpKGIE3aB+SPidvUTD8o225UMmGZ9 3GaqxQkqCYOZ8m914WvKmZZ1WJaGe1xzaY2BPtDyOG5oiy9DdqVbbWvvGS6tukDzBb+T acvrN0rxFC3O28ym79+JGWjPUQyHRdhN7/vNrFikO/cyRCNhsKTaf7rJki8AlFi5Zicg Rbmg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UQ536CFx; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w63si8403963pfd.289.2018.01.08.05.30.25; Mon, 08 Jan 2018 05:30:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UQ536CFx; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933424AbeAHN36 (ORCPT + 28 others); Mon, 8 Jan 2018 08:29:58 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:38146 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933389AbeAHN3x (ORCPT ); Mon, 8 Jan 2018 08:29:53 -0500 Received: by mail-wm0-f67.google.com with SMTP id 64so14209652wme.3 for ; Mon, 08 Jan 2018 05:29:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WxW0wTXrQlL11cQloR5uFczaFJHJAFTucfu/a7Auct0=; b=UQ536CFx1KSNZwIcLAGAaAF8vgWhwaFTO7Zi/cFZoycBXhcJkugIZDnjAfh3byi9hP 75zsmzOrPInpXbWgHexOkgE02lRWFRBbbBOD9PhljG4D/vpQWwp4Nt2hyG1ZZY0tMYAu W9cPJN4jQLLgLb/QJ2rd/8CrccjvUoFsnVByM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WxW0wTXrQlL11cQloR5uFczaFJHJAFTucfu/a7Auct0=; b=bTtGL68QuGZwDfpyzfTzFR0pepNULVTEDysJ/eqi5p488K5qGkU5qyfrJ9BYKp6JrE ymnxxKjUwkintKjsJmoM/PsKI4AiDnnHyIALaW4l5ZsqRxYBjfeTbmIfEeMSa4XyGG7z wHK8fChHwyO249zY3EDOiHGyeohQRHvMJbJKVO7ZHk3+g3NOJW6JHt5B5r1+6E5kZy2c 1krj9CCODWWjSUcNAFhS04bztHFLyad9gBZj1Lj1AHCK34T5ZWp2srM7Y7JUajs7s1jA ZH7YdKCQHg6KkPQKJuYEvZKxE9sC4ZqaAhwORN6SpXu1l6vyWbvb2DFPTVzs45B/CUps m6oA== X-Gm-Message-State: AKGB3mLO98PeAOPkbS5iQpYw3SX3FUEppQyJW9Gle3WaxiS6bvmOUQU8 4tIby65PQgg+u8GCTy45mCBoAQ== X-Received: by 10.28.228.132 with SMTP id b126mr8402889wmh.18.1515418191532; Mon, 08 Jan 2018 05:29:51 -0800 (PST) Received: from mai.lan ([2001:41d0:fe90:b800:312a:53a5:1bef:6622]) by smtp.gmail.com with ESMTPSA id q196sm14354222wmb.22.2018.01.08.05.29.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 08 Jan 2018 05:29:50 -0800 (PST) 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 16/20] clocksource/drivers/stm32: Add the oneshot mode Date: Mon, 8 Jan 2018 14:28:55 +0100 Message-Id: <1515418139-23276-16-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 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Benjamin Gaignard The stm32 timer block is able to have a counter and a comparator. Instead of using the auto-reload register for periodic event, we switch to the oneshot mode by using the comparator register. The timer is able to generate an interrupt when the counter overflows but we don't want that as this counter will be use as a clocksource in the next patches. So it is disabled by the UDIS bit of the control register. Signed-off-by: Benjamin Gaignard Signed-off-by: Daniel Lezcano Tested-by: Benjamin Gaignard Acked-by: Benjamin Gaignard --- drivers/clocksource/timer-stm32.c | 56 ++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 12 deletions(-) -- 2.7.4 diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c index ac55896..baca42c 100644 --- a/drivers/clocksource/timer-stm32.c +++ b/drivers/clocksource/timer-stm32.c @@ -24,14 +24,18 @@ #define TIM_DIER 0x0c #define TIM_SR 0x10 #define TIM_EGR 0x14 +#define TIM_CNT 0x24 #define TIM_PSC 0x28 #define TIM_ARR 0x2c +#define TIM_CCR1 0x34 #define TIM_CR1_CEN BIT(0) +#define TIM_CR1_UDIS BIT(1) #define TIM_CR1_OPM BIT(3) #define TIM_CR1_ARPE BIT(7) #define TIM_DIER_UIE BIT(0) +#define TIM_DIER_CC1IE BIT(1) #define TIM_SR_UIF BIT(0) @@ -40,33 +44,57 @@ #define TIM_PSC_MAX USHRT_MAX #define TIM_PSC_CLKRATE 10000 +static void stm32_clock_event_disable(struct timer_of *to) +{ + writel_relaxed(0, timer_of_base(to) + TIM_DIER); +} + +static void stm32_clock_event_enable(struct timer_of *to) +{ + writel_relaxed(TIM_CR1_UDIS | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1); +} + static int stm32_clock_event_shutdown(struct clock_event_device *clkevt) { struct timer_of *to = to_timer_of(clkevt); - writel_relaxed(0, timer_of_base(to) + TIM_CR1); + stm32_clock_event_disable(to); return 0; } -static int stm32_clock_event_set_periodic(struct clock_event_device *clkevt) +static int stm32_clock_event_set_next_event(unsigned long evt, + struct clock_event_device *clkevt) { struct timer_of *to = to_timer_of(clkevt); + unsigned long now, next; + + next = readl_relaxed(timer_of_base(to) + TIM_CNT) + evt; + writel_relaxed(next, timer_of_base(to) + TIM_CCR1); + now = readl_relaxed(timer_of_base(to) + TIM_CNT); + + if ((next - now) > evt) + return -ETIME; - writel_relaxed(timer_of_period(to), timer_of_base(to) + TIM_ARR); - writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1); + writel_relaxed(TIM_DIER_CC1IE, timer_of_base(to) + TIM_DIER); return 0; } -static int stm32_clock_event_set_next_event(unsigned long evt, - struct clock_event_device *clkevt) +static int stm32_clock_event_set_periodic(struct clock_event_device *clkevt) +{ + struct timer_of *to = to_timer_of(clkevt); + + stm32_clock_event_enable(to); + + return stm32_clock_event_set_next_event(timer_of_period(to), clkevt); +} + +static int stm32_clock_event_set_oneshot(struct clock_event_device *clkevt) { struct timer_of *to = to_timer_of(clkevt); - writel_relaxed(evt, timer_of_base(to) + TIM_ARR); - writel_relaxed(TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_CEN, - timer_of_base(to) + TIM_CR1); + stm32_clock_event_enable(to); return 0; } @@ -78,6 +106,11 @@ static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id) writel_relaxed(0, timer_of_base(to) + TIM_SR); + if (clockevent_state_periodic(clkevt)) + stm32_clock_event_set_periodic(clkevt); + else + stm32_clock_event_shutdown(clkevt); + clkevt->event_handler(clkevt); return IRQ_HANDLED; @@ -108,9 +141,10 @@ static void __init stm32_clockevent_init(struct timer_of *to) to->clkevt.name = to->np->full_name; to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC; + to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; to->clkevt.set_state_shutdown = stm32_clock_event_shutdown; to->clkevt.set_state_periodic = stm32_clock_event_set_periodic; - to->clkevt.set_state_oneshot = stm32_clock_event_shutdown; + to->clkevt.set_state_oneshot = stm32_clock_event_set_oneshot; to->clkevt.tick_resume = stm32_clock_event_shutdown; to->clkevt.set_next_event = stm32_clock_event_set_next_event; @@ -129,12 +163,10 @@ static void __init stm32_clockevent_init(struct timer_of *to) prescaler = prescaler < TIM_PSC_MAX ? prescaler : TIM_PSC_MAX; to->clkevt.rating = 100; } - writel_relaxed(0, timer_of_base(to) + TIM_ARR); writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC); writel_relaxed(TIM_EGR_UG, timer_of_base(to) + TIM_EGR); writel_relaxed(0, timer_of_base(to) + TIM_SR); - writel_relaxed(TIM_DIER_UIE, timer_of_base(to) + TIM_DIER); /* Adjust rate and period given the prescaler value */ to->of_clk.rate = DIV_ROUND_CLOSEST(to->of_clk.rate, prescaler);