From patchwork Tue Nov 17 14:56:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlo Caione X-Patchwork-Id: 7637821 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 8913A9F392 for ; Tue, 17 Nov 2015 15:00:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6E17820108 for ; Tue, 17 Nov 2015 15:00:58 +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 4CFEE20148 for ; Tue, 17 Nov 2015 15:00:50 +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 1Zyhia-0003Yn-KC; Tue, 17 Nov 2015 14:58:48 +0000 Received: from mail-wm0-x234.google.com ([2a00:1450:400c:c09::234]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZyhhC-0002ld-QZ for linux-arm-kernel@lists.infradead.org; Tue, 17 Nov 2015 14:57:26 +0000 Received: by wmec201 with SMTP id c201so231834792wme.0 for ; Tue, 17 Nov 2015 06:57:01 -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=vP49mxhc47EeZkgUd1IUQ7qz4FfIvys8hYP2guMO0n3uj0OlRFeTFqg6YgMcGnVLAX spFwIl/0tO1lhEmr3029ebdpZv/4mgvz+xFbbX9dAli+02ZoekOrR1IOvDdVkurUPbEB jqW6x81FeCxxnJbUzzUdWQQIQsA5xunMO6hVT/PPMRT1J/so3KQjZHceXvRiVBdaJ+ri pgA7VM6a2x0cbGYKzlYNgcs57eAciKnztnyXXRoknTzSwZBLYdl1ifd8NHETThfK12du vqYbH7/9zA/mqkWZsQKem74sra/VbOmA9ueAL7N/nd0wUyBiXqypbfddWUl6Cr34W135 lFhQ== X-Received: by 10.194.201.202 with SMTP id kc10mr51641453wjc.84.1447772221244; Tue, 17 Nov 2015 06:57:01 -0800 (PST) Received: from localhost.localdomain ([212.91.95.170]) by smtp.gmail.com with ESMTPSA id b84sm22578986wmh.15.2015.11.17.06.57.00 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 17 Nov 2015 06:57:00 -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 3/7] clk: meson8b: Add reset controller for CPU cores Date: Tue, 17 Nov 2015 15:56:38 +0100 Message-Id: <1447772202-12418-4-git-send-email-carlo@caione.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1447772202-12418-1-git-send-email-carlo@caione.org> References: <1447772202-12418-1-git-send-email-carlo@caione.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151117_065723_156094_16F941A3 X-CRM114-Status: GOOD ( 17.46 ) X-Spam-Score: -2.4 (--) 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.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,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