From patchwork Mon Dec 30 03:25:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 3417491 Return-Path: X-Original-To: patchwork-linux-arm@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 D9825C02DC for ; Mon, 30 Dec 2013 03:31:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id ED4D1200FE for ; Mon, 30 Dec 2013 03:31:18 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CBAF6200F3 for ; Mon, 30 Dec 2013 03:31:17 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VxTXx-0002c7-Dt; Mon, 30 Dec 2013 03:29:42 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VxTXb-00088m-VI; Mon, 30 Dec 2013 03:29:19 +0000 Received: from smtp.csie.ntu.edu.tw ([140.112.30.61]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VxTWx-00084w-V9 for linux-arm-kernel@lists.infradead.org; Mon, 30 Dec 2013 03:28:43 +0000 Received: from mirror2.csie.ntu.edu.tw (mirror2.csie.ntu.edu.tw [140.112.30.76]) by smtp.csie.ntu.edu.tw (Postfix) with ESMTPSA id CC125203C1; Mon, 30 Dec 2013 11:28:06 +0800 (CST) Received: from wens by mirror2.csie.ntu.edu.tw with local (Exim 4.82) (envelope-from ) id 1VxTWQ-0007QS-Oo; Mon, 30 Dec 2013 11:28:06 +0800 From: Chen-Yu Tsai To: Maxime Ripard Subject: [PATCH v2 1/4] clk: sunxi: Allwinner A20 output clock support Date: Mon, 30 Dec 2013 11:25:46 +0800 Message-Id: <1388373949-28506-2-git-send-email-wens@csie.org> X-Mailer: git-send-email 1.8.5.2 In-Reply-To: <1388373949-28506-1-git-send-email-wens@csie.org> References: <1388373949-28506-1-git-send-email-wens@csie.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131229_222840_422494_76B5E9ED X-CRM114-Status: GOOD ( 15.15 ) X-Spam-Score: -2.3 (--) Cc: emilio@elopez.com.ar, linux-sunxi@googlegroups.com, Mike Turquette , Chen-Yu Tsai , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 This patch adds support for the external clock outputs on the Allwinner A20 SoC. The clock outputs are similar to "module 0" type clocks, with different offsets and widths for clock factors. Signed-off-by: Chen-Yu Tsai --- Documentation/devicetree/bindings/clock/sunxi.txt | 1 + drivers/clk/sunxi/clk-sunxi.c | 57 +++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 46d8433..c2cb762 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -36,6 +36,7 @@ Required properties: "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31 "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks + "allwinner,sun7i-a20-out-clk" - for the external output clocks Required properties for all clocks: - reg : shall be the control register address for the clock. diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 25d99b6..19d9e9e 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -330,6 +330,47 @@ static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate, /** + * sun7i_a20_get_out_factors() - calculates m, p factors for CLK_OUT_A/B + * CLK_OUT rate is calculated as follows + * rate = (parent_rate >> p) / (m + 1); + */ + +static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, + u8 *n, u8 *k, u8 *m, u8 *p) +{ + u8 div, calcm, calcp; + + /* These clocks can only divide, so we will never be able to achieve + * frequencies higher than the parent frequency */ + if (*freq > parent_rate) + *freq = parent_rate; + + div = parent_rate / *freq; + + if (div < 32) + calcp = 0; + else if (div / 2 < 32) + calcp = 1; + else if (div / 4 < 32) + calcp = 2; + else + calcp = 3; + + calcm = DIV_ROUND_UP(div, 1 << calcp); + + *freq = (parent_rate >> calcp) / calcm; + + /* we were called to round the frequency, we can now return */ + if (n == NULL) + return; + + *m = calcm - 1; + *p = calcp; +} + + + +/** * sunxi_factors_clk_setup() - Setup function for factor clocks */ @@ -384,6 +425,14 @@ static struct clk_factors_config sun4i_mod0_config = { .pwidth = 2, }; +/* user manual says "n" but it's really "p" */ +static struct clk_factors_config sun7i_a20_out_config = { + .mshift = 8, + .mwidth = 5, + .pshift = 20, + .pwidth = 2, +}; + static const struct factors_data sun4i_pll1_data __initconst = { .enable = 31, .table = &sun4i_pll1_config, @@ -414,6 +463,13 @@ static const struct factors_data sun4i_mod0_data __initconst = { .getter = sun4i_get_mod0_factors, }; +static const struct factors_data sun7i_a20_out_data __initconst = { + .enable = 31, + .mux = 24, + .table = &sun7i_a20_out_config, + .getter = sun7i_a20_get_out_factors, +}; + static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, const struct factors_data *data) { @@ -912,6 +968,7 @@ static const struct of_device_id clk_factors_match[] __initconst = { {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,}, {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,}, + {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, {} };