From patchwork Mon Feb 15 07:34:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Petazzoni X-Patchwork-Id: 8310861 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 368809F2F0 for ; Mon, 15 Feb 2016 07:47:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 364AE204AF for ; Mon, 15 Feb 2016 07:47:38 +0000 (UTC) Received: from bombadil.infradead.org (unknown [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 19831203C2 for ; Mon, 15 Feb 2016 07:47:37 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aVDjH-0006fp-7q; Mon, 15 Feb 2016 07:37:55 +0000 Received: from down.free-electrons.com ([37.187.137.238] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aVDhF-0004vD-9J for linux-arm-kernel@lists.infradead.org; Mon, 15 Feb 2016 07:35:57 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id A97972B2; Mon, 15 Feb 2016 08:35:21 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RDNS_NONE,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost (AToulouse-657-1-45-133.w92-156.abo.wanadoo.fr [92.156.219.133]) by mail.free-electrons.com (Postfix) with ESMTPSA id 68EB3222; Mon, 15 Feb 2016 08:35:21 +0100 (CET) From: Thomas Petazzoni To: Michael Turquette , Stephen Boyd , linux-clk@vger.kernel.org, devicetree@vger.kernel.org, Rob Herring , Ian Campbell , Pawel Moll , Mark Rutland , Kumar Gala Subject: [PATCH 2/3] clk: mvebu: add AP806 core clock driver Date: Mon, 15 Feb 2016 08:34:57 +0100 Message-Id: <1455521698-7905-3-git-send-email-thomas.petazzoni@free-electrons.com> X-Mailer: git-send-email 2.6.4 In-Reply-To: <1455521698-7905-1-git-send-email-thomas.petazzoni@free-electrons.com> References: <1455521698-7905-1-git-send-email-thomas.petazzoni@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160214_233550_083223_D81A7718 X-CRM114-Status: GOOD ( 22.18 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lior Amsalem , Andrew Lunn , Jason Cooper , Nadav Haklai , Gregory Clement , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org, Sebastian Hesselbarth MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This commit adds a new driver to handle the core clocks found in the AP806 HW block, which is the core block of all Armada 7K and 8K Marvell 64-bits processors. This core clock driver reads the Sample-At-Reset register to determine the frequencies of several core clocks: DDR, Ring and CPU clocks. Signed-off-by: Thomas Petazzoni --- .../clock/mvebu-armada-ap806-core-clock.txt | 33 ++++++ drivers/clk/mvebu/Kconfig | 3 + drivers/clk/mvebu/Makefile | 2 +- drivers/clk/mvebu/ap806-core.c | 112 +++++++++++++++++++++ 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/mvebu-armada-ap806-core-clock.txt create mode 100644 drivers/clk/mvebu/ap806-core.c diff --git a/Documentation/devicetree/bindings/clock/mvebu-armada-ap806-core-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-armada-ap806-core-clock.txt new file mode 100644 index 0000000..b2131bb --- /dev/null +++ b/Documentation/devicetree/bindings/clock/mvebu-armada-ap806-core-clock.txt @@ -0,0 +1,33 @@ +* Clock bindings for Marvell MVEBU AP806 Core clocks + +The Marvell MVEBU Armada 7K/8K SoCs contain a block called AP806, +hosting the CPU and other core components of the CPU. This Device Tree +binding allows to describe the core clocks of the AP806, whose +frequencies are determined by reading the Sample-At-Reset (SAR) +register. + +Clock consumers must specify the desired clock by having the clock ID +in its "clocks" phandle cell. + +The following is a list of provided IDs and clock names for the core +Armada AP806 clocks: + + 0 = DDR + 1 = Ring + 2 = CPU + +Required properties: +- compatible: must be be one of the following: + "marvell,armada-ap806-core-clock" +- reg: must be the register address of the Sample-At-Reset (SAR) register +- #clock-cells: from common clock binding; shall be set to 1 +- clock-output-names: name of the output clocks + +Example: + + coreclk: clk@0x6F8204 { + compatible = "marvell,armada-ap806-core-clock"; + reg = <0x6F8204 0x04>; + #clock-cells = <1>; + clock-output-names = "ddr", "ring", "cpu"; + }; diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index 2769625..fd84172 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -42,3 +42,6 @@ config KIRKWOOD_CLK config ORION_CLK bool select MVEBU_CLK_COMMON + +config ARMADA_AP806_CORE_CLK + bool diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index 8866115..db5c28c 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile @@ -1,11 +1,11 @@ obj-$(CONFIG_MVEBU_CLK_COMMON) += common.o obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o obj-$(CONFIG_MVEBU_CLK_COREDIV) += clk-corediv.o - obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o +obj-$(CONFIG_ARMADA_AP806_CORE_CLK) += ap806-core.o obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o diff --git a/drivers/clk/mvebu/ap806-core.c b/drivers/clk/mvebu/ap806-core.c new file mode 100644 index 0000000..56c81cd --- /dev/null +++ b/drivers/clk/mvebu/ap806-core.c @@ -0,0 +1,112 @@ +/* + * Marvell Armada AP806 core clocks + * + * Copyright (C) 2016 Marvell + * + * Thomas Petazzoni + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include + +/* + * AP806 PLLs: + * 0 - DDR + * 1 - Ring + * 2 - CPU + */ + +#define AP806_PLL_NUM 3 +#define AP806_PLL_FREQ 7 + +/* SAR parameters to get the PLL data */ +struct apclk_sar { + int mask; + int offset; + const char *name; +}; + +static const struct apclk_sar +ap806_core_clk_sar[AP806_PLL_NUM] __initconst = { + { .mask = 0x7, .offset = 21 }, + { .mask = 0x7, .offset = 18 }, + { .mask = 0x7, .offset = 15 }, +}; + +static struct clk *ap806_core_clks[AP806_PLL_NUM]; + +static struct clk_onecell_data ap806_core_clk_data = { + .clks = ap806_core_clks, + .clk_num = AP806_PLL_NUM, +}; + +/* mapping between SAR value to frequency */ +static const u32 +ap806_core_clk_freq[AP806_PLL_NUM][AP806_PLL_FREQ] __initconst = { + { 2400000000, 2100000000, 1800000000, + 1600000000, 1300000000, 1300000000, + 1300000000 }, + { 2000000000, 1800000000, 1600000000, + 1400000000, 1200000000, 1200000000, + 1200000000 }, + { 2500000000, 2200000000, 2000000000, + 1700000000, 1600000000, 1200000000, + 1200000000 }, +}; + +static unsigned long __init ap806_core_clk_get_freq(u32 reg, int clk_idx) +{ + int freq_idx; + const struct apclk_sar *clk_info; + + clk_info = &ap806_core_clk_sar[clk_idx]; + + freq_idx = (reg >> clk_info->offset) & clk_info->mask; + if (WARN_ON(freq_idx > AP806_PLL_FREQ)) + return 0; + else + return ap806_core_clk_freq[clk_idx][freq_idx]; +} + +static void __init ap806_core_clk_init(struct device_node *np) +{ + void __iomem *base; + u32 reg; + int i; + + base = of_iomap(np, 0); + if (WARN_ON(!base)) + return; + + reg = readl(base); + + iounmap(base); + + for (i = 0; i < AP806_PLL_NUM; i++) { + unsigned long freq; + const char *name; + + freq = ap806_core_clk_get_freq(reg, i); + + of_property_read_string_index(np, "clock-output-names", + i, &name); + + ap806_core_clks[i] = + clk_register_fixed_rate(NULL, name, NULL, + CLK_IS_ROOT, freq); + } + + of_clk_add_provider(np, of_clk_src_onecell_get, + &ap806_core_clk_data); +} + +CLK_OF_DECLARE(ap806_core_clk, "marvell,armada-ap806-core-clock", + ap806_core_clk_init);