From patchwork Tue Sep 2 09:13:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Hecht X-Patchwork-Id: 4823911 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 97962C0338 for ; Tue, 2 Sep 2014 09:13:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 887AE20154 for ; Tue, 2 Sep 2014 09:13:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 51208200ED for ; Tue, 2 Sep 2014 09:13:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753265AbaIBJN4 (ORCPT ); Tue, 2 Sep 2014 05:13:56 -0400 Received: from mail-we0-f173.google.com ([74.125.82.173]:34210 "EHLO mail-we0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753259AbaIBJNz (ORCPT ); Tue, 2 Sep 2014 05:13:55 -0400 Received: by mail-we0-f173.google.com with SMTP id t60so6612123wes.32 for ; Tue, 02 Sep 2014 02:13:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=c4voNJjT/lEaEYJWhIj5jpCiMadUxrE3b63zlHdyCX4=; b=n6afstFTym0CG1DXF+l5WiBMMICil1/pFpaBcirMexfmBpdTFoMmuwQlgVsb0zNTqX c6jsE4Jo9tUjg+QSem94lqKZiFiXCbECGsmLwKGday5X3ZtvV8qtjpQFTVCWbnOsQRkj kkgWXQL23l/H8mu81oJB/LvYq94JLI8KXwTbF8B5PE0lE2IsOINU8cAA52CdrDeRkLbH HcJUYwRNzuuRvDhYswxR4BiYuFNqhCccPBvHhCbNxLCh5DD+DfCKv5c3htXHbL+9BUHc blHKrD41KCe/9itAmiQo9KkMMKtmzY1pHrTM7dsWXoRZyHP1ZNcbFjw4ND9vxaAYh938 9WsQ== X-Received: by 10.194.171.37 with SMTP id ar5mr37168180wjc.69.1409649234016; Tue, 02 Sep 2014 02:13:54 -0700 (PDT) Received: from groucho.site ([91.108.183.74]) by mx.google.com with ESMTPSA id h6sm8087525wjb.33.2014.09.02.02.13.52 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Sep 2014 02:13:53 -0700 (PDT) From: Ulrich Hecht To: horms@verge.net.au Cc: linux-sh@vger.kernel.org, mturquette@linaro.org, magnus.damm@gmail.com, Laurent Pinchart , Geert Uytterhoeven , Ulrich Hecht , Ulrich Hecht Subject: [PATCH v2 09/10] clk: shmobile: div6: support selectable-input clocks Date: Tue, 2 Sep 2014 11:13:05 +0200 Message-Id: <1409649186-1046-10-git-send-email-ulrich.hecht+renesas@gmail.com> X-Mailer: git-send-email 1.8.4.5 In-Reply-To: <1409649186-1046-1-git-send-email-ulrich.hecht+renesas@gmail.com> References: <1409649186-1046-1-git-send-email-ulrich.hecht+renesas@gmail.com> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-8.4 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SBL, RP_MATCHES_RCVD, T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ulrich Hecht Support for setting the parent at initialization time based on the current hardware configuration in DIV6 clocks with selectable parents as found in the r8a73a4, r8a7740, sh73a0, and other SoCs. Signed-off-by: Ulrich Hecht Acked-by: Geert Uytterhoeven --- .../bindings/clock/renesas,cpg-div6-clocks.txt | 12 +++++++- drivers/clk/shmobile/clk-div6.c | 32 ++++++++++++++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt index 952e373..2633ea1 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt @@ -7,14 +7,24 @@ to 64. Required Properties: - compatible: Must be one of the following + - "renesas,r8a73a4-div6-clock" for R8A73A4 (R-Mobile APE6) DIV6 clocks + - "renesas,r8a7740-div6-clock" for R8A7740 (R-Mobile A1) DIV6 clocks - "renesas,r8a7790-div6-clock" for R8A7790 (R-Car H2) DIV6 clocks - "renesas,r8a7791-div6-clock" for R8A7791 (R-Car M2) DIV6 clocks + - "renesas,sh73a0-div6-clock" for SH73A0 (SH-MobileAG5) DIV6 clocks - "renesas,cpg-div6-clock" for generic DIV6 clocks - reg: Base address and length of the memory resource used by the DIV6 clock - - clocks: Reference to the parent clock + - clocks: Reference to the parent clock(s) - #clock-cells: Must be 0 - clock-output-names: The name of the clock as a free-form string +Optional Properties: + + - renesas,src-shift: Bit position of the input clock selector (default: + fixed input clock; requires renesas,src-width) + - renesas,src-width: Bit width of the input clock selector (default: fixed + input clock; requires renesas,src-shift) + Example ------- diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c index f065f69..f8b57bf 100644 --- a/drivers/clk/shmobile/clk-div6.c +++ b/drivers/clk/shmobile/clk-div6.c @@ -39,8 +39,11 @@ struct div6_clock { static int cpg_div6_clock_enable(struct clk_hw *hw) { struct div6_clock *clock = to_div6_clock(hw); + u32 val; - clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg); + val = (clk_readl(clock->reg) & ~(CPG_DIV6_DIV_MASK | CPG_DIV6_CKSTP)) + | CPG_DIV6_DIV(clock->div - 1); + clk_writel(val, clock->reg); return 0; } @@ -52,7 +55,7 @@ static void cpg_div6_clock_disable(struct clk_hw *hw) /* DIV6 clocks require the divisor field to be non-zero when stopping * the clock. */ - clk_writel(CPG_DIV6_CKSTP | CPG_DIV6_DIV(CPG_DIV6_DIV_MASK), + clk_writel(clk_readl(clock->reg) | CPG_DIV6_CKSTP | CPG_DIV6_DIV_MASK, clock->reg); } @@ -94,12 +97,14 @@ static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate, { struct div6_clock *clock = to_div6_clock(hw); unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate); + u32 val; clock->div = div; + val = clk_readl(clock->reg) & ~CPG_DIV6_DIV_MASK; /* Only program the new divisor if the clock isn't stopped. */ - if (!(clk_readl(clock->reg) & CPG_DIV6_CKSTP)) - clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg); + if (!(val & CPG_DIV6_CKSTP)) + clk_writel(val | CPG_DIV6_DIV(clock->div - 1), clock->reg); return 0; } @@ -120,6 +125,8 @@ static void __init cpg_div6_clock_init(struct device_node *np) const char *parent_name; const char *name; struct clk *clk; + u32 src_shift; + u32 src_width; int ret; clock = kzalloc(sizeof(*clock), GFP_KERNEL); @@ -150,7 +157,22 @@ static void __init cpg_div6_clock_init(struct device_node *np) goto error; } - parent_name = of_clk_get_parent_name(np, 0); + if (!of_property_read_u32(np, "renesas,src-shift", &src_shift)) { + if (!of_property_read_u32(np, "renesas,src-width", + &src_width)) { + unsigned int parent_idx = + (clk_readl(clock->reg) >> src_shift) & + (BIT(src_width) - 1); + parent_name = of_clk_get_parent_name(np, parent_idx); + } else { + pr_err("%s: renesas,src-shift without renesas,src-width in %s\n", + __func__, np->name); + goto error; + } + } else { + parent_name = of_clk_get_parent_name(np, 0); + } + if (parent_name == NULL) { pr_err("%s: failed to get %s DIV6 clock parent name\n", __func__, np->name);