From patchwork Thu Jan 4 12:50:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 10144677 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A0F6B6034B for ; Thu, 4 Jan 2018 12:53:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8BFCC28634 for ; Thu, 4 Jan 2018 12:53:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7EC1A28639; Thu, 4 Jan 2018 12:53:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C6BF428634 for ; Thu, 4 Jan 2018 12:53:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=8bnvIeOEMo+w/HPJp/BaixTtWwngcXEDrHBjagB+nJc=; b=GTEMpHfiIkI6vzhluaJmitJfls Rmq6G/ewBDijNnLNuTBivxp6X+Vz7E8ENJqvEDuGHKmaZcXrWaDSursAjHw3GpYa05ExeZVOhiuS/ Q6XNyld33pqDUFvzKpKLJjKg00FXOlt8HRpFdD+3l4wDvTRw9NwGEQZE6x20pYXubSzzJsMM3F2Ta 0rZzdO+4qFiG2HfeBC/hXNIYzPY0EWeQLiwiHbnl/1QO4m6uNQ4J1EgHMkWp7Vr2q/fb/3LODfkB3 hj/vijOuMIDdm4B8P9DAcJC/YPN7+Oa8i+vZSSDVtCFtNutxeiRyWG6V4jhsnIH+y9YB5VdlnH68F EyGTMqtw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eX51e-0007J3-7h; Thu, 04 Jan 2018 12:53:38 +0000 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eX4ze-0005t8-3a for linux-arm-kernel@lists.infradead.org; Thu, 04 Jan 2018 12:51:48 +0000 Received: by mail-wm0-x243.google.com with SMTP id y82so2046121wmg.1 for ; Thu, 04 Jan 2018 04:51:29 -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=migRDHJdxnkLgsjmJtEkASHxaZfMp7VL85o/Dq6lDaI=; b=YDuZ4TaHsZ61jI6/gwSwo4Eerw76/jbeNLZdbY8mKPoj+3We/bxFnClqe68fhzAEUW qzoVHfWnt2ZfGsE/egM5v5KX8Bwe88MHb7hb3UXtlSlp1hDQqFqJX7SIumI56AR2Dzrj PosuQacCqLUsWFz42zdCbnisWYxF9p+VCTqr4= 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=migRDHJdxnkLgsjmJtEkASHxaZfMp7VL85o/Dq6lDaI=; b=BD3zwkWXl1vrpj9URMxNfx8U3i1eNWr2A8tJg0D/hv5N5PU0XDiKWx2Px29bmVQnvu ug6ejJUmM/OInXgp1bwdUhdUvdWc4VNpzqq9a/bEsc9w1932h1H7/RpLQLgDKherFwLF W9VZtg3steQUJI+dTs51gNXRQT4n/k89ZDJhx2XIPqHReA1b5ccIyHa0tbHXr1ZsQ2OL pND+SxkjfMFsIyGbIm75uAos5zLwkvJx2QD/EjG3xss+3r6vOp9GbMvBvIoSPlN+z8G0 /F5P+QemhQ8Ny0IQzxSNaXKu8+po49+jv2SodTbZiwuEcndU2u5yqqqT1RV8m2lsBZku ZG4g== X-Gm-Message-State: AKGB3mL7/NpdxQUZMpVKBKHU3I7aLrJ1lLfDGCyovY9g2e3Hcnv7CRQo X+sKkT/JltRXKKWSNE1QNcvaUQkcykQ= X-Google-Smtp-Source: ACJfBovQ2YGUPVJWCJ4sJ14YAFAkKhrsAOMkj3w6qiGtI/Hd78Tk1YsmyarlLntAplCdqm8D4fQIjg== X-Received: by 10.28.213.2 with SMTP id m2mr3684087wmg.141.1515070288282; Thu, 04 Jan 2018 04:51:28 -0800 (PST) Received: from mai.lan ([2001:41d0:fe90:b800:c10d:405d:d60:60bb]) by smtp.gmail.com with ESMTPSA id d71sm3668348wma.7.2018.01.04.04.51.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 04 Jan 2018 04:51:27 -0800 (PST) From: Daniel Lezcano To: daniel.lezcano@linaro.org, tglx@linutronix.de Subject: [PATCH 08/12] clocksource/drivers/stm32: Add the oneshot mode Date: Thu, 4 Jan 2018 13:50:24 +0100 Message-Id: <1515070228-10481-9-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515070228-10481-1-git-send-email-daniel.lezcano@linaro.org> References: <1515070228-10481-1-git-send-email-daniel.lezcano@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180104_045134_562343_41240A96 X-CRM114-Status: GOOD ( 16.25 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: benjamin.gaignard@linaro.org, Alexandre Torgue , linux-kernel@vger.kernel.org, Maxime Coquelin , "moderated list:ARM/STM32 ARCHITECTURE" , Benjamin Gaignard MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP 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. [Daniel Lezcano]: Modified the changelog and splitted the oneshot mode from the original patch in order to provide one feature at a time. Signed-off-by: Benjamin Gaignard Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-stm32.c | 56 ++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 12 deletions(-) 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);