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: 123418 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp11390744qgn; Thu, 4 Jan 2018 04:52:39 -0800 (PST) X-Google-Smtp-Source: ACJfBovf+qgjlpXZHEk2UXnXQ6Ofla7vrZemIfu9W8Kb+rDtMdnhsNQLZRGiAX8cw8ZMk3vWv8pV X-Received: by 10.159.198.1 with SMTP id f1mr4542376plo.450.1515070359604; Thu, 04 Jan 2018 04:52:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515070359; cv=none; d=google.com; s=arc-20160816; b=F0EavMlOQNTJ8e9mDiHHiRuFcj+R8f2af8eWqZyjkxhwRkxyPrt7rO9XVxDIBSC5UF w/beQ3sfdSznl6pnlqHPPQ/AfMb02gc+Wd/PUUVweyLVg1fRWR9HXBNHD6i7f/Ijjtto /WYRL3WvHyFZjO6PgTnssjz5BM37xzKa6yuJMN56Y2U1TG9i1YID40GyDx5PkziHvaii K9xYEi4pjbTD8YeqEPbA/d3V6PjLNNSTTGnNKIbPM3jmDnlMBRP8NY7DhmlnKLsgvlt8 Q4uleyvkNlKdmQxr46iy2W9RSEG/sAVvesSqnv3UKNIoFTb1tTv81ab84KQnDcTSv0Np YOsA== 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=migRDHJdxnkLgsjmJtEkASHxaZfMp7VL85o/Dq6lDaI=; b=PLDkCSsDLHjmFrjK01oaWQO1tztSdCQ9X8Kt3XMUU9vLXevDM7zVl2iI2jIZNJECEk szAxW6/jlvBLrGPcBZ8ZQGyDCp2cVCauTcAWvSdufgZZPK8+AmxqBSV7CMsS+1yz511I IQgjS/iS1PnPyKdgRMRhIHqiHAPSjeS15ebrXhZDErynL+/8u4FTqm0NnCtIKFZGXgyM Xc8Zn8V1RBGLt7BY2AkdlcviVea1gilizXTLjsV02BnO8usF3NBA4q/N4kcYxcTAYUN1 pNzjpGLzbjbW0qNxCSbbDQZOvli2JzRxj3+avg05asC+x7mJRtRhOr+E7MUKzsv/eA0x Nzlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YDuZ4TaH; 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 b3si1999070pgr.829.2018.01.04.04.52.39; Thu, 04 Jan 2018 04:52:39 -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=YDuZ4TaH; 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 S1753145AbeADMwf (ORCPT + 27 others); Thu, 4 Jan 2018 07:52:35 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:32794 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752837AbeADMva (ORCPT ); Thu, 4 Jan 2018 07:51:30 -0500 Received: by mail-wm0-f66.google.com with SMTP id g130so2063042wme.0 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=igIfeN2aFZ7XEFJD7xAYeCwgNXjsQI4Ffq1pIwIJDGl8nQ+M4jFIo4u0KrchZ2691A AYXmQcaqYyvFqi6SPQIBPGn2Rin+DsgAuBRNFv8qp4nyB5OLm0q2HBdJMBcNFtv0SjKu KJepzEjrBh2MWr19Cgv2eYlWkKVJomWsmXFBOZjXvPCdhyMowKFf94aOypCDmRKzZWNT +z53KTO32iiTZ1EeDfn8YVy3xDX0Hrs8s1iwjPMt0oymwlIORKKama6Pa37V2Qx+npZ6 7ewGtS4644XNLOdVmy42cQ/sNK3N7gRL/d6BBlvnis9Abtw8b2b+9N1Ofdw0PD4rjc6s dmOA== X-Gm-Message-State: AKGB3mKB3A9Gv4jCBdRL+dghm2fv9XSD5u26SvZE88KtFZ45GFe9MyJi K9l0qA6aaJedEicD8swNDkGiAQ== 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 Cc: linux-kernel@vger.kernel.org, benjamin.gaignard@linaro.org, Benjamin Gaignard , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org (moderated list:ARM/STM32 ARCHITECTURE) 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> 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. [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(-) -- 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);