From patchwork Fri Apr 17 10:50:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Griffin X-Patchwork-Id: 47278 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f70.google.com (mail-la0-f70.google.com [209.85.215.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id DC32E20553 for ; Fri, 17 Apr 2015 10:50:57 +0000 (UTC) Received: by lamp14 with SMTP id p14sf24142323lam.3 for ; Fri, 17 Apr 2015 03:50:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=T4oP4XkRsmrweBoVNeJ7lgKQV0ReZ6mamvKkDoQpIyA=; b=MWeHjhQRmxvJjnpPXmfhIlKxf7mbOmLvmHuiH0ynEHJDCVv1Pf2Ap0H27FuCmTEaCZ U6W5HwmLNbpKdG7ScoX92lKDAHdYHCyibG61dWsRsDpan9NVxSeq+gz3fSR/0FysYNeI ZaH04PcwDYlrTQ+UJqPiu0mRJJBs9lRRG/2XbSSfpdutX117d39VNbUU425koINz2STG rvEazz9ZT+pxANnzw7hs6aLBxwreommOgHLOV76ffv7IO6guhdUTefmlWHsP3TPNt5rg 94cyOYyqTMmJyQe1gMtP7bWsEJhC8asm5Tx3y8iz4w8ykvTRIE9iX2uRV8wqN21JVXc8 jFyw== X-Gm-Message-State: ALoCoQnsZLZbSpo/s6BvIoHTntVbQaHMGZIlOrSeqDeHmM1VipxDPd3iMJ4XaUxuKfkMaOBZ7RZz X-Received: by 10.112.203.168 with SMTP id kr8mr1120070lbc.10.1429267856549; Fri, 17 Apr 2015 03:50:56 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.42.137 with SMTP id o9ls432022lal.16.gmail; Fri, 17 Apr 2015 03:50:56 -0700 (PDT) X-Received: by 10.152.2.38 with SMTP id 6mr2408772lar.80.1429267856378; Fri, 17 Apr 2015 03:50:56 -0700 (PDT) Received: from mail-lb0-f170.google.com (mail-lb0-f170.google.com. [209.85.217.170]) by mx.google.com with ESMTPS id au9si8473257lbc.168.2015.04.17.03.50.56 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Apr 2015 03:50:56 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.170 as permitted sender) client-ip=209.85.217.170; Received: by lbbuc2 with SMTP id uc2so79643145lbb.2 for ; Fri, 17 Apr 2015 03:50:56 -0700 (PDT) X-Received: by 10.112.160.227 with SMTP id xn3mr2335745lbb.112.1429267856262; Fri, 17 Apr 2015 03:50:56 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.67.65 with SMTP id l1csp3654575lbt; Fri, 17 Apr 2015 03:50:54 -0700 (PDT) X-Received: by 10.70.63.1 with SMTP id c1mr4462483pds.90.1429267853133; Fri, 17 Apr 2015 03:50:53 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id fa8si16250399pdb.16.2015.04.17.03.50.51; Fri, 17 Apr 2015 03:50:53 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753747AbbDQKuk (ORCPT + 27 others); Fri, 17 Apr 2015 06:50:40 -0400 Received: from mail-wi0-f171.google.com ([209.85.212.171]:35647 "EHLO mail-wi0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751812AbbDQKug (ORCPT ); Fri, 17 Apr 2015 06:50:36 -0400 Received: by widdi4 with SMTP id di4so17095726wid.0 for ; Fri, 17 Apr 2015 03:50:35 -0700 (PDT) X-Received: by 10.194.142.168 with SMTP id rx8mr4655729wjb.43.1429267834917; Fri, 17 Apr 2015 03:50:34 -0700 (PDT) Received: from localhost.localdomain ([213.205.252.24]) by mx.google.com with ESMTPSA id mv11sm2092668wic.23.2015.04.17.03.50.32 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 17 Apr 2015 03:50:34 -0700 (PDT) From: Peter Griffin To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, srinivas.kandagatla@gmail.com, maxime.coquelin@st.com, patrice.chotard@st.com, daniel.lezcano@linaro.org, tglx@linutronix.de Cc: peter.griffin@linaro.org, lee.jones@linaro.org, devicetree@vger.kernel.org, Ajit Pal Singh Subject: [PATCH 1/5] clocksource: st_lpc: Add LPC timer as a clocksource. Date: Fri, 17 Apr 2015 11:50:19 +0100 Message-Id: <1429267823-8879-2-git-send-email-peter.griffin@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1429267823-8879-1-git-send-email-peter.griffin@linaro.org> References: <1429267823-8879-1-git-send-email-peter.griffin@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.griffin@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.170 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch adds support for the LPC timer as a clocksource which is found on stih407 family SoCs. We wish to use the LPC timer as a clocksource instead of arm_global_timer, as the latter is tied to CPU frequency, and that driver currently makes no account for frequency scaling. Once this driver is merged cpufreq can be enabled for stih407 family SoCs without also effecting sched_clock. Signed-off-by: Ajit Pal Singh Signed-off-by: Peter Griffin --- drivers/clocksource/Kconfig | 16 +++++ drivers/clocksource/Makefile | 1 + drivers/clocksource/st_lpc.c | 154 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 drivers/clocksource/st_lpc.c diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index a0b036c..29cd67d 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -253,4 +253,20 @@ config CLKSRC_PXA help This enables OST0 support available on PXA and SA-11x0 platforms. + +config CLKSRC_ST_LPC_CLOCK + bool + depends on ARCH_STI + select CLKSRC_OF if OF + help + Enable this option to use the Low Power controller timer + as clock source. + +config CLKSRC_ST_LPC_TIMER_SCHED_CLOCK + bool + depends on ST_LPC_CLOCK + default y + help + Use Low Power controller timer clock source as sched_clock + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 752d5c7..356d331 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o +obj-$(CONFIG_CLKSRC_ST_LPC_CLOCK) += st_lpc.o diff --git a/drivers/clocksource/st_lpc.c b/drivers/clocksource/st_lpc.c new file mode 100644 index 0000000..f9abded --- /dev/null +++ b/drivers/clocksource/st_lpc.c @@ -0,0 +1,154 @@ +/* + * This driver implements a Clocksource using the Low Power Timer in + * the Low Power Controller (LPC) in some STMicroelectronics + * STi series SoCs + * + * Copyright (C) 2015 STMicroelectronics Limited + * Author: Francesco Virlinzi + * Author: Ajit Pal Singh + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + */ + +#include +#include +#include +#include +#include +#include + +/* Low Power Timer */ +#define LPC_LPT_LSB_OFF 0x400 +#define LPC_LPT_MSB_OFF 0x404 +#define LPC_LPT_START_OFF 0x408 + +struct st_lpc { + struct clk *clk; + void __iomem *iomem_cs; +}; + +static struct st_lpc *st_lpc; + +static u64 notrace st_lpc_counter_read(void) +{ + u64 counter; + u32 lower; + u32 upper, old_upper; + + upper = readl_relaxed(st_lpc->iomem_cs + LPC_LPT_MSB_OFF); + do { + old_upper = upper; + lower = readl_relaxed(st_lpc->iomem_cs + LPC_LPT_LSB_OFF); + upper = readl_relaxed(st_lpc->iomem_cs + LPC_LPT_MSB_OFF); + } while (upper != old_upper); + + counter = upper; + counter <<= 32; + counter |= lower; + return counter; +} + +static cycle_t st_lpc_clocksource_read(struct clocksource *cs) +{ + return st_lpc_counter_read(); +} + +static void st_lpc_clocksource_reset(struct clocksource *cs) +{ + writel_relaxed(0, st_lpc->iomem_cs + LPC_LPT_START_OFF); + writel_relaxed(0, st_lpc->iomem_cs + LPC_LPT_MSB_OFF); + writel_relaxed(0, st_lpc->iomem_cs + LPC_LPT_LSB_OFF); + writel_relaxed(1, st_lpc->iomem_cs + LPC_LPT_START_OFF); +} + +static struct clocksource st_lpc_clocksource = { + .name = "st-lpc clocksource", + .rating = 301, + .read = st_lpc_clocksource_read, + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +#ifdef CONFIG_CLKSRC_LPC_TIMER_SCHED_CLOCK +static u64 notrace st_lpc_sched_clock_read(void) +{ + return st_lpc_counter_read(); +} +#endif + +static void __init st_lpc_clocksource_init(void) +{ + unsigned long rate; + + st_lpc_clocksource_reset(&st_lpc_clocksource); + + rate = clk_get_rate(st_lpc->clk); +#ifdef CONFIG_CLKSRC_LPC_TIMER_SCHED_CLOCK + sched_clock_register(st_lpc_sched_clock_read, 64, rate); +#endif + clocksource_register_hz(&st_lpc_clocksource, rate); + +} + +static int st_lpc_setup_clk(struct device_node *np) +{ + char *clk_name = "lpc_clk"; + struct clk *clk; + int ret; + + clk = of_clk_get_by_name(np, clk_name); + if (IS_ERR(clk)) { + pr_err("st-lpc: unable to get lpc clock\n"); + ret = PTR_ERR(clk); + return ret; + } + + if (clk_prepare_enable(clk)) { + pr_err("st-lpc: %s could not be enabled\n", clk_name); + return -EINVAL; + } + + if (!clk_get_rate(clk)) { + pr_err("st-lpc: Unable to get clock rate\n"); + clk_disable_unprepare(clk); + return -EINVAL; + } + + pr_info("st-lpc: %s running @ %lu Hz\n", + clk_name, clk_get_rate(clk)); + + st_lpc->clk = clk; + + return 0; +} + +static void __init st_lpc_of_register(struct device_node *np) +{ + st_lpc = kzalloc(sizeof(*st_lpc), GFP_KERNEL); + if (!st_lpc) { + pr_err("st-lpc: No memory available\n"); + return; + } + + st_lpc->iomem_cs = of_iomap(np, 0); + if (!st_lpc->iomem_cs) { + pr_err("st-lpc: Unable to map iomem\n"); + goto err_kfree; + } + + if (st_lpc_setup_clk(np)) + goto err_iounmap; + + st_lpc_clocksource_init(); + + pr_info("st-lpc: clocksource initialised: iomem: %p\n", + st_lpc->iomem_cs); + return; +err_iounmap: + iounmap(st_lpc->iomem_cs); +err_kfree: + kfree(st_lpc); +} + +CLOCKSOURCE_OF_DECLARE(st_lpc, "st,st_lpc_timer", st_lpc_of_register);