From patchwork Fri Mar 22 13:24:25 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 2319861 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id E5088400E6 for ; Fri, 22 Mar 2013 13:24:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751894Ab3CVNYc (ORCPT ); Fri, 22 Mar 2013 09:24:32 -0400 Received: from moutng.kundenserver.de ([212.227.17.10]:62805 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751698Ab3CVNYb (ORCPT ); Fri, 22 Mar 2013 09:24:31 -0400 Received: from axis700.grange (dslb-094-221-106-148.pools.arcor-ip.net [94.221.106.148]) by mrelayeu.kundenserver.de (node=mreu4) with ESMTP (Nemesis) id 0MTJZq-1U9eJw12pC-00SJOz; Fri, 22 Mar 2013 14:24:26 +0100 Received: by axis700.grange (Postfix, from userid 1000) id EA6B240BB4; Fri, 22 Mar 2013 14:24:25 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by axis700.grange (Postfix) with ESMTP id E6F7140BB3; Fri, 22 Mar 2013 14:24:25 +0100 (CET) Date: Fri, 22 Mar 2013 14:24:25 +0100 (CET) From: Guennadi Liakhovetski X-X-Sender: lyakh@axis700.grange To: linux-sh@vger.kernel.org cc: Magnus Damm , Simon Horman Subject: [PATCH/RFC 1/2] ARM: shmobile: wait for MSTP clock status to toggle, when enabling it In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Provags-ID: V02:K0:LTdjPW8Yd4/sDoCaNOpXHzvEPZ2hW5gP3nhuF5OMyRC PRZ9hYiJdUocn1bh66v5qzZtmjHOOq5Z0wl0vG/eFYWaqJEHXK jqcpes1EFdgFIdfPERu6CZsqbhrNxBJ7iMa38Br2PCscj9ctcD uVtEscLzs9ussTuVofQ6uBFCBPytFIhTD3lNYtmrXqXp578qpO x/nhrgRxdjHn2kxANAp4Ff0D1ycCsTEfbDDsQX9ZErnywPZG5Z YcQ8/kSOyc64uUehPGYDvcgpcdpRL9f0sp9ohww5Nq6ZjF2y2C Om5KIkvs368k18j4CgSGe3fv1My+4LGX4h2BDOiaFYI7o1pmkT 6V8MSaiw757r8Lek+q1SpFgdnT6jGnoCIRwl9wAXu2H26UjGys 89J9cJgY8os3g== Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org On r-/sh-mobile SoCs MSTP clocks are used by the runtime PM to dynamically enable and disable peripheral clocks. To make sure the clock has really started we have to read back its status register until it confirms success. Signed-off-by: Guennadi Liakhovetski --- drivers/sh/clk/cpg.c | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/sh_clk.h | 29 +++++++++++++++++------------ 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 1ebe67c..7442bc1 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -36,9 +36,47 @@ static void sh_clk_write(int value, struct clk *clk) iowrite32(value, clk->mapped_reg); } +static unsigned int r8(const void __iomem *addr) +{ + return ioread8(addr); +} + +static unsigned int r16(const void __iomem *addr) +{ + return ioread16(addr); +} + +static unsigned int r32(const void __iomem *addr) +{ + return ioread32(addr); +} + static int sh_clk_mstp_enable(struct clk *clk) { sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk); + if (clk->status_reg) { + unsigned int (*read)(const void __iomem *addr); + int i; + void __iomem *mapped_status = (phys_addr_t)clk->status_reg - + (phys_addr_t)clk->enable_reg + clk->mapped_reg; + + if (clk->flags & CLK_ENABLE_REG_8BIT) + read = r8; + else if (clk->flags & CLK_ENABLE_REG_16BIT) + read = r16; + else + read = r32; + + for (i = 1000; + (read(mapped_status) & (1 << clk->enable_bit)) && i; + i--) + cpu_relax(); + if (!i) { + pr_err("cpg: failed to enable %p[%d]\n", + clk->enable_reg, clk->enable_bit); + return -ETIMEDOUT; + } + } return 0; } diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 60c7239..e85bf79 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -52,6 +52,7 @@ struct clk { unsigned long flags; void __iomem *enable_reg; + void __iomem *status_reg; unsigned int enable_bit; void __iomem *mapped_reg; @@ -116,22 +117,26 @@ long clk_round_parent(struct clk *clk, unsigned long target, unsigned long *best_freq, unsigned long *parent_freq, unsigned int div_min, unsigned int div_max); -#define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _flags) \ -{ \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_enable_reg, \ - .enable_bit = _enable_bit, \ - .flags = _flags, \ +#define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _status_reg, _flags) \ +{ \ + .parent = _parent, \ + .enable_reg = (void __iomem *)_enable_reg, \ + .enable_bit = _enable_bit, \ + .status_reg = _status_reg, \ + .flags = _flags, \ } -#define SH_CLK_MSTP32(_p, _r, _b, _f) \ - SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_32BIT) +#define SH_CLK_MSTP32(_p, _r, _b, _f) \ + SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_32BIT) -#define SH_CLK_MSTP16(_p, _r, _b, _f) \ - SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_16BIT) +#define SH_CLK_MSTP32_STS(_p, _r, _b, _s, _f) \ + SH_CLK_MSTP(_p, _r, _b, _s, _f | CLK_ENABLE_REG_32BIT) -#define SH_CLK_MSTP8(_p, _r, _b, _f) \ - SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_8BIT) +#define SH_CLK_MSTP16(_p, _r, _b, _f) \ + SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_16BIT) + +#define SH_CLK_MSTP8(_p, _r, _b, _f) \ + SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_8BIT) int sh_clk_mstp_register(struct clk *clks, int nr);