From patchwork Wed Dec 2 17:22:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlo Caione X-Patchwork-Id: 7749751 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CE50ABEEE1 for ; Wed, 2 Dec 2015 17:25:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C5E6B204AD for ; Wed, 2 Dec 2015 17:25:57 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [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 D1CD9204A2 for ; Wed, 2 Dec 2015 17:25:56 +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 1a4B8I-0004tc-Dy; Wed, 02 Dec 2015 17:23:58 +0000 Received: from mail-wm0-x236.google.com ([2a00:1450:400c:c09::236]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1a4B7Y-0004PL-Tv for linux-arm-kernel@lists.infradead.org; Wed, 02 Dec 2015 17:23:16 +0000 Received: by wmuu63 with SMTP id u63so224433413wmu.0 for ; Wed, 02 Dec 2015 09:22:51 -0800 (PST) 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=Ehvk0K2Tp6mmUdBWvG8NmVWiX6La/cPw43uZrGV6LDA=; b=Nkk4PSHjED4WGkn05qlaC0PEXRMC8XTNA4GgEDSM8k16leA9eanZAcOCJhKpMSBw/7 Y4J68AJTsWeXcRUZjfUeWrUB6yCJulEx2Vp3HyWGVdeXbsIn9sid2L+b7OX6M0Hszpl8 C2lshDxK7Jdd9fmwUYTx/WPPiYSYXq/7RmVINihybhApRMGSChuJbrL966O2I6qGTxW3 eJyehqFW7TtxIBQpRg2E8d7ng7Jk1Wdl2oKcaDpl7ZS1DKJK3P+yALFsVZVLYFsIHgM/ LsUpR/FvKP2EPUvSgMxW7RXraU8BLH6uZggCLH1ZOxZS0/dKmR3FWb5VsfuDxlT6TKpE MPKg== X-Received: by 10.194.24.97 with SMTP id t1mr6176011wjf.127.1449076971369; Wed, 02 Dec 2015 09:22:51 -0800 (PST) Received: from localhost.localdomain ([212.91.95.170]) by smtp.gmail.com with ESMTPSA id s189sm4111113wmf.16.2015.12.02.09.22.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 02 Dec 2015 09:22:50 -0800 (PST) From: Carlo Caione To: robh+dt@kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, mturquette@baylibre.com, linux-clk@vger.kernel.org, linux@arm.linux.org.uk, linux-meson@googlegroups.com, drake@endlessm.com, jerry.cao@amlogic.com, victor.wan@amlogic.com, pawel.moll@arm.com, arnd@arndb.de Subject: [PATCH v2 3/7] clk: Amlogic: Add reset controller for CPU cores for Meson8b Date: Wed, 2 Dec 2015 18:22:29 +0100 Message-Id: <1449076953-5058-4-git-send-email-carlo@caione.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1449076953-5058-1-git-send-email-carlo@caione.org> References: <1449076953-5058-1-git-send-email-carlo@caione.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151202_092313_309906_3524B2C8 X-CRM114-Status: GOOD ( 16.52 ) X-Spam-Score: -2.6 (--) 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: Carlo Caione 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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_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 From: Carlo Caione In the Amlogic Meson8b SoC we need to soft reset the CPU cores during the boot to enable the SMP support. With this patch we extend the clock controller adding a small reset controller in charge of resetting the cores. Signed-off-by: Carlo Caione --- drivers/clk/meson/clk-cpu.c | 60 +++++++++++++++++++++++++++++++- drivers/clk/meson/clkc.c | 5 +-- drivers/clk/meson/clkc.h | 6 ++-- drivers/clk/meson/meson8b-clkc.c | 4 +-- include/dt-bindings/clock/meson8b-clkc.h | 5 +++ 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c index f7c30ea..8836fa9 100644 --- a/drivers/clk/meson/clk-cpu.c +++ b/drivers/clk/meson/clk-cpu.c @@ -37,9 +37,14 @@ #include #include #include +#include +#include #define MESON_CPU_CLK_CNTL1 0x00 #define MESON_CPU_CLK_CNTL 0x40 +#define MESON_CPU_CLK_CNTL_CPU 0x19c + +#define MESON_MAX_CPU_RST 4 #define MESON_CPU_CLK_MUX1 BIT(7) #define MESON_CPU_CLK_MUX2 BIT(0) @@ -51,6 +56,11 @@ #include "clkc.h" +struct meson_reset_cpu { + void __iomem *reset_base; + struct reset_controller_dev rcdev; +}; + struct meson_clk_cpu { struct notifier_block clk_nb; const struct clk_div_table *div_table; @@ -182,13 +192,50 @@ static const struct clk_ops meson_clk_cpu_ops = { .set_rate = meson_clk_cpu_set_rate, }; -struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, +static int meson_reset_cpu_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 reg; + struct meson_reset_cpu *reset_cpu = container_of(rcdev, + struct meson_reset_cpu, + rcdev); + + reg = readl(reset_cpu->reset_base); + reg |= BIT(id + 24); + writel(reg, reset_cpu->reset_base); + + return 0; +} + +static int meson_reset_cpu_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 reg; + struct meson_reset_cpu *reset_cpu = container_of(rcdev, + struct meson_reset_cpu, + rcdev); + + reg = readl(reset_cpu->reset_base); + reg &= ~BIT(id + 24); + writel(reg, reset_cpu->reset_base); + + return 0; +} + +static struct reset_control_ops meson_cpu_reset_ops = { + .assert = meson_reset_cpu_assert, + .deassert = meson_reset_cpu_deassert, +}; + +struct clk *meson_clk_register_cpu(struct device_node *np, + const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock) { struct clk *clk; struct clk *pclk; struct meson_clk_cpu *clk_cpu; + struct meson_reset_cpu *reset_cpu; struct clk_init_data init; int ret; @@ -231,6 +278,17 @@ struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, goto unregister_clk_nb; } + reset_cpu = kzalloc(sizeof(*reset_cpu), GFP_KERNEL); + if (!reset_cpu) + goto out; + + reset_cpu->reset_base = reg_base + MESON_CPU_CLK_CNTL_CPU; + reset_cpu->rcdev.nr_resets = MESON_MAX_CPU_RST; + reset_cpu->rcdev.ops = &meson_cpu_reset_ops; + reset_cpu->rcdev.of_node = np; + reset_controller_register(&reset_cpu->rcdev); + +out: return clk; unregister_clk_nb: diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c index c83ae13..df71e82 100644 --- a/drivers/clk/meson/clkc.c +++ b/drivers/clk/meson/clkc.c @@ -197,7 +197,8 @@ meson_clk_register_fixed_rate(const struct clk_conf *clk_conf, return clk; } -void __init meson_clk_register_clks(const struct clk_conf *clk_confs, +void __init meson_clk_register_clks(struct device_node *np, + const struct clk_conf *clk_confs, size_t nr_confs, void __iomem *clk_base) { @@ -221,7 +222,7 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs, clk_base); break; case CLK_CPU: - clk = meson_clk_register_cpu(clk_conf, clk_base, + clk = meson_clk_register_cpu(np, clk_conf, clk_base, &clk_lock); break; case CLK_PLL: diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 609ae92..648d41d 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -177,9 +177,11 @@ struct clk_conf { } \ struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks); -void meson_clk_register_clks(const struct clk_conf *clk_confs, +void meson_clk_register_clks(struct device_node *np, + const struct clk_conf *clk_confs, unsigned int nr_confs, void __iomem *clk_base); -struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, +struct clk *meson_clk_register_cpu(struct device_node *np, + const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock); struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock); diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c index 61f6d55..98f1ebd 100644 --- a/drivers/clk/meson/meson8b-clkc.c +++ b/drivers/clk/meson/meson8b-clkc.c @@ -179,7 +179,7 @@ static void __init meson8b_clkc_init(struct device_node *np) return; } - meson_clk_register_clks(&meson8b_xtal_conf, 1, clk_base); + meson_clk_register_clks(np, &meson8b_xtal_conf, 1, clk_base); iounmap(clk_base); /* Generic clocks and PLLs */ @@ -189,7 +189,7 @@ static void __init meson8b_clkc_init(struct device_node *np) return; } - meson_clk_register_clks(meson8b_clk_confs, + meson_clk_register_clks(np, meson8b_clk_confs, ARRAY_SIZE(meson8b_clk_confs), clk_base); } diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h index bd2720d..bbdadca 100644 --- a/include/dt-bindings/clock/meson8b-clkc.h +++ b/include/dt-bindings/clock/meson8b-clkc.h @@ -5,6 +5,11 @@ #ifndef __MESON8B_CLKC_H #define __MESON8B_CLKC_H +#define RST_CORE0 0 +#define RST_CORE1 1 +#define RST_CORE2 2 +#define RST_CORE3 3 + #define CLKID_UNUSED 0 #define CLKID_XTAL 1 #define CLKID_PLL_FIXED 2