From: narmstrong@baylibre.com (Neil Armstrong)
To: linus-amlogic@lists.infradead.org
Subject: [PATCH v2 2/3] clk: meson: meson8b: register the built-in reset controller
Date: Tue, 25 Jul 2017 09:58:30 +0200 [thread overview]
Message-ID: <5976FA26.1050907@baylibre.com> (raw)
In-Reply-To: <20170722185807.10504-3-martin.blumenstingl@googlemail.com>
Le 22/07/2017 20:58, Martin Blumenstingl a ?crit :
> The clock controller also includes some reset lines. This patch
> implements a reset controller to assert and de-assert these resets.
> The reset controller itself is registered early (through
> CLK_OF_DECLARE_DRIVER) because it is needed very early in the boot
> process (to start the secondary CPU cores).
>
> According to the public S805 datasheet there are two more reset bits
> in the HHI_SYS_CPU_CLK_CNTL0 register, which are not implemented by
> this patch (as these seem to be unused in Amlogic's vendor Linux kernel
> sources and their u-boot tree):
> - bit 15: GEN_DIV_SOFT_RESET
> - bit 14: SOFT_RESET
>
> All information was taken from the public S805 Datasheet and Amlogic's
> vendor GPL kernel sources. This patch is based on an earlier version
> submitted by Carlo Caione.
>
> Suggested-by: Carlo Caione <carlo@endlessm.com>
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
> ---
> drivers/clk/meson/Kconfig | 1 +
> drivers/clk/meson/meson8b.c | 159 ++++++++++++++++++++++++++++++++++++++++----
> drivers/clk/meson/meson8b.h | 25 ++++++-
> 3 files changed, 172 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 5588f75a8414..d2d0174a6eca 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -6,6 +6,7 @@ config COMMON_CLK_AMLOGIC
> config COMMON_CLK_MESON8B
> bool
> depends on COMMON_CLK_AMLOGIC
> + select RESET_CONTROLLER
> help
> Support for the clock controller on AmLogic S802 (Meson8),
> S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
> diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
> index bb3f1de876b1..0f853057885c 100644
> --- a/drivers/clk/meson/meson8b.c
> +++ b/drivers/clk/meson/meson8b.c
> @@ -25,6 +25,8 @@
> #include <linux/clk-provider.h>
> #include <linux/of_address.h>
> #include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +#include <linux/slab.h>
> #include <linux/init.h>
>
> #include "clkc.h"
> @@ -32,6 +34,13 @@
>
> static DEFINE_SPINLOCK(clk_lock);
>
> +static void __iomem *clk_base;
> +
> +struct meson8b_clk_reset {
> + struct reset_controller_dev reset;
> + void __iomem *base;
> +};
> +
> static const struct pll_rate_table sys_pll_rate_table[] = {
> PLL_RATE(312000000, 52, 1, 2),
> PLL_RATE(336000000, 56, 1, 2),
> @@ -690,20 +699,114 @@ static struct clk_divider *const meson8b_clk_dividers[] = {
> &meson8b_mpeg_clk_div,
> };
>
> +static const struct meson8b_clk_reset_line {
> + u32 reg;
> + u8 bit_idx;
> +} meson8b_clk_reset_bits[] = {
> + [RESETID_L2_CACHE_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
> + },
> + [RESETID_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
> + },
> + [RESETID_SCU_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
> + },
> + [RESETID_CPU3_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
> + },
> + [RESETID_CPU2_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
> + },
> + [RESETID_CPU1_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
> + },
> + [RESETID_CPU0_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
> + },
> + [RESETID_A5_GLOBAL_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
> + },
> + [RESETID_A5_AXI_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
> + },
> + [RESETID_A5_ABP_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
> + },
> + [RESETID_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
> + },
> + [RESETID_VID_CLK_CNTL_SOFT_RESET] = {
> + .reg = HHI_VID_CLK_CNTL, .bit_idx = 15
> + },
> + [RESETID_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
> + },
> + [RESETID_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
> + },
> + [RESETID_VID_DIVIDER_CNTL_RESET_N_POST] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
> + },
> + [RESETID_VID_DIVIDER_CNTL_RESET_N_PRE] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
> + },
> +};
> +
> +static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
> + unsigned long id, bool assert)
> +{
> + struct meson8b_clk_reset *meson8b_clk_reset =
> + container_of(rcdev, struct meson8b_clk_reset, reset);
> + unsigned long flags;
> + const struct meson8b_clk_reset_line *reset;
> + u32 val;
> +
> + if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
> + return -EINVAL;
> +
> + reset = &meson8b_clk_reset_bits[id];
> +
> + spin_lock_irqsave(&clk_lock, flags);
> +
> + val = readl(meson8b_clk_reset->base + reset->reg);
> + if (assert)
> + val |= BIT(reset->bit_idx);
> + else
> + val &= ~BIT(reset->bit_idx);
> + writel(val, meson8b_clk_reset->base + reset->reg);
> +
> + spin_unlock_irqrestore(&clk_lock, flags);
> +
> + return 0;
> +}
> +
> +static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + return meson8b_clk_reset_update(rcdev, id, true);
> +}
> +
> +static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + return meson8b_clk_reset_update(rcdev, id, false);
> +}
> +
> +static const struct reset_control_ops meson8b_clk_reset_ops = {
> + .assert = meson8b_clk_reset_assert,
> + .deassert = meson8b_clk_reset_deassert,
> +};
> +
> static int meson8b_clkc_probe(struct platform_device *pdev)
> {
> - void __iomem *clk_base;
> int ret, clkid, i;
> struct clk_hw *parent_hw;
> struct clk *parent_clk;
> struct device *dev = &pdev->dev;
>
> - /* Generic clocks and PLLs */
> - clk_base = of_iomap(dev->of_node, 1);
> - if (!clk_base) {
> - pr_err("%s: Unable to map clk base\n", __func__);
> + if (!clk_base)
> return -ENXIO;
> - }
>
> /* Populate base address for PLLs */
> for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
> @@ -743,7 +846,7 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
> /* FIXME convert to devm_clk_register */
> ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
> if (ret)
> - goto iounmap;
> + return ret;
> }
>
> /*
> @@ -766,15 +869,11 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
> if (ret) {
> pr_err("%s: failed to register clock notifier for cpu_clk\n",
> __func__);
> - goto iounmap;
> + return ret;
> }
>
> return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
> &meson8b_hw_onecell_data);
> -
> -iounmap:
> - iounmap(clk_base);
> - return ret;
> }
>
> static const struct of_device_id meson8b_clkc_match_table[] = {
> @@ -793,3 +892,39 @@ static struct platform_driver meson8b_driver = {
> };
>
> builtin_platform_driver(meson8b_driver);
> +
> +static void __init meson8b_clkc_reset_init(struct device_node *np)
> +{
> + struct meson8b_clk_reset *rstc;
> + int ret;
> +
> + /* Generic clocks, PLLs and some of the reset-bits */
> + clk_base = of_iomap(np, 1);
> + if (!clk_base) {
> + pr_err("%s: Unable to map clk base\n", __func__);
> + return;
> + }
> +
> + rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
> + if (!rstc)
> + return;
> +
> + /* Reset Controller */
> + rstc->base = clk_base;
> + rstc->reset.ops = &meson8b_clk_reset_ops;
> + rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
> + rstc->reset.of_node = np;
> + ret = reset_controller_register(&rstc->reset);
> + if (ret) {
> + pr_err("%s: Failed to register clkc reset controller: %d\n",
> + __func__, ret);
> + return;
> + }
> +}
> +
> +CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
> + meson8b_clkc_reset_init);
> +CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
> + meson8b_clkc_reset_init);
> +CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
> + meson8b_clkc_reset_init);
> diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
> index a687e02547dc..5f4d8e49dd4d 100644
> --- a/drivers/clk/meson/meson8b.h
> +++ b/drivers/clk/meson/meson8b.h
> @@ -37,6 +37,9 @@
> #define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */
> #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */
> #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */
> +#define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */
> +#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */
> +#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */
> #define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
> #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
> #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
> @@ -163,7 +166,27 @@
>
> #define CLK_NR_CLKS 96
>
> -/* include the CLKIDs that have been made part of the stable DT binding */
> +#define RESETID_L2_CACHE_SOFT_RESET 0
> +#define RESETID_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET 1
> +#define RESETID_SCU_SOFT_RESET 2
> +#define RESETID_CPU0_SOFT_RESET 3
> +#define RESETID_CPU1_SOFT_RESET 4
> +#define RESETID_CPU2_SOFT_RESET 5
> +#define RESETID_CPU3_SOFT_RESET 6
> +#define RESETID_A5_GLOBAL_RESET 7
> +#define RESETID_A5_AXI_SOFT_RESET 8
> +#define RESETID_A5_ABP_SOFT_RESET 9
> +#define RESETID_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET 10
> +#define RESETID_VID_CLK_CNTL_SOFT_RESET 11
> +#define RESETID_VID_DIVIDER_CNTL_SOFT_RESET_POST 12
> +#define RESETID_VID_DIVIDER_CNTL_SOFT_RESET_PRE 13
> +#define RESETID_VID_DIVIDER_CNTL_RESET_N_POST 14
> +#define RESETID_VID_DIVIDER_CNTL_RESET_N_PRE 15
I think you should directly expose them in a dt-bindings/reset/meson8b-clkc-reset.h file and include it here.
> +
> +/*
> + * include the CLKID and RESETID that have
> + * been made part of the stable DT binding
> + */
> #include <dt-bindings/clock/meson8b-clkc.h>
>
> #endif /* __MESON8B_H */
>
Apart from that :
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
WARNING: multiple messages have this Message-ID (diff)
From: Neil Armstrong <narmstrong@baylibre.com>
To: Martin Blumenstingl <martin.blumenstingl@googlemail.com>,
linux-amlogic@lists.infradead.org, khilman@baylibre.com,
carlo@caione.org, jbrunet@baylibre.com,
linux-clk@vger.kernel.org, robh+dt@kernel.org
Cc: devicetree@vger.kernel.org, linux@armlinux.org.uk,
mark.rutland@arm.com, mturquette@baylibre.com,
sboyd@codeaurora.org
Subject: Re: [PATCH v2 2/3] clk: meson: meson8b: register the built-in reset controller
Date: Tue, 25 Jul 2017 09:58:30 +0200 [thread overview]
Message-ID: <5976FA26.1050907@baylibre.com> (raw)
In-Reply-To: <20170722185807.10504-3-martin.blumenstingl@googlemail.com>
Le 22/07/2017 20:58, Martin Blumenstingl a écrit :
> The clock controller also includes some reset lines. This patch
> implements a reset controller to assert and de-assert these resets.
> The reset controller itself is registered early (through
> CLK_OF_DECLARE_DRIVER) because it is needed very early in the boot
> process (to start the secondary CPU cores).
>
> According to the public S805 datasheet there are two more reset bits
> in the HHI_SYS_CPU_CLK_CNTL0 register, which are not implemented by
> this patch (as these seem to be unused in Amlogic's vendor Linux kernel
> sources and their u-boot tree):
> - bit 15: GEN_DIV_SOFT_RESET
> - bit 14: SOFT_RESET
>
> All information was taken from the public S805 Datasheet and Amlogic's
> vendor GPL kernel sources. This patch is based on an earlier version
> submitted by Carlo Caione.
>
> Suggested-by: Carlo Caione <carlo@endlessm.com>
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
> ---
> drivers/clk/meson/Kconfig | 1 +
> drivers/clk/meson/meson8b.c | 159 ++++++++++++++++++++++++++++++++++++++++----
> drivers/clk/meson/meson8b.h | 25 ++++++-
> 3 files changed, 172 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 5588f75a8414..d2d0174a6eca 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -6,6 +6,7 @@ config COMMON_CLK_AMLOGIC
> config COMMON_CLK_MESON8B
> bool
> depends on COMMON_CLK_AMLOGIC
> + select RESET_CONTROLLER
> help
> Support for the clock controller on AmLogic S802 (Meson8),
> S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
> diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
> index bb3f1de876b1..0f853057885c 100644
> --- a/drivers/clk/meson/meson8b.c
> +++ b/drivers/clk/meson/meson8b.c
> @@ -25,6 +25,8 @@
> #include <linux/clk-provider.h>
> #include <linux/of_address.h>
> #include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +#include <linux/slab.h>
> #include <linux/init.h>
>
> #include "clkc.h"
> @@ -32,6 +34,13 @@
>
> static DEFINE_SPINLOCK(clk_lock);
>
> +static void __iomem *clk_base;
> +
> +struct meson8b_clk_reset {
> + struct reset_controller_dev reset;
> + void __iomem *base;
> +};
> +
> static const struct pll_rate_table sys_pll_rate_table[] = {
> PLL_RATE(312000000, 52, 1, 2),
> PLL_RATE(336000000, 56, 1, 2),
> @@ -690,20 +699,114 @@ static struct clk_divider *const meson8b_clk_dividers[] = {
> &meson8b_mpeg_clk_div,
> };
>
> +static const struct meson8b_clk_reset_line {
> + u32 reg;
> + u8 bit_idx;
> +} meson8b_clk_reset_bits[] = {
> + [RESETID_L2_CACHE_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
> + },
> + [RESETID_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
> + },
> + [RESETID_SCU_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
> + },
> + [RESETID_CPU3_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
> + },
> + [RESETID_CPU2_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
> + },
> + [RESETID_CPU1_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
> + },
> + [RESETID_CPU0_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
> + },
> + [RESETID_A5_GLOBAL_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
> + },
> + [RESETID_A5_AXI_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
> + },
> + [RESETID_A5_ABP_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
> + },
> + [RESETID_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
> + },
> + [RESETID_VID_CLK_CNTL_SOFT_RESET] = {
> + .reg = HHI_VID_CLK_CNTL, .bit_idx = 15
> + },
> + [RESETID_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
> + },
> + [RESETID_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
> + },
> + [RESETID_VID_DIVIDER_CNTL_RESET_N_POST] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
> + },
> + [RESETID_VID_DIVIDER_CNTL_RESET_N_PRE] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
> + },
> +};
> +
> +static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
> + unsigned long id, bool assert)
> +{
> + struct meson8b_clk_reset *meson8b_clk_reset =
> + container_of(rcdev, struct meson8b_clk_reset, reset);
> + unsigned long flags;
> + const struct meson8b_clk_reset_line *reset;
> + u32 val;
> +
> + if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
> + return -EINVAL;
> +
> + reset = &meson8b_clk_reset_bits[id];
> +
> + spin_lock_irqsave(&clk_lock, flags);
> +
> + val = readl(meson8b_clk_reset->base + reset->reg);
> + if (assert)
> + val |= BIT(reset->bit_idx);
> + else
> + val &= ~BIT(reset->bit_idx);
> + writel(val, meson8b_clk_reset->base + reset->reg);
> +
> + spin_unlock_irqrestore(&clk_lock, flags);
> +
> + return 0;
> +}
> +
> +static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + return meson8b_clk_reset_update(rcdev, id, true);
> +}
> +
> +static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + return meson8b_clk_reset_update(rcdev, id, false);
> +}
> +
> +static const struct reset_control_ops meson8b_clk_reset_ops = {
> + .assert = meson8b_clk_reset_assert,
> + .deassert = meson8b_clk_reset_deassert,
> +};
> +
> static int meson8b_clkc_probe(struct platform_device *pdev)
> {
> - void __iomem *clk_base;
> int ret, clkid, i;
> struct clk_hw *parent_hw;
> struct clk *parent_clk;
> struct device *dev = &pdev->dev;
>
> - /* Generic clocks and PLLs */
> - clk_base = of_iomap(dev->of_node, 1);
> - if (!clk_base) {
> - pr_err("%s: Unable to map clk base\n", __func__);
> + if (!clk_base)
> return -ENXIO;
> - }
>
> /* Populate base address for PLLs */
> for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
> @@ -743,7 +846,7 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
> /* FIXME convert to devm_clk_register */
> ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
> if (ret)
> - goto iounmap;
> + return ret;
> }
>
> /*
> @@ -766,15 +869,11 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
> if (ret) {
> pr_err("%s: failed to register clock notifier for cpu_clk\n",
> __func__);
> - goto iounmap;
> + return ret;
> }
>
> return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
> &meson8b_hw_onecell_data);
> -
> -iounmap:
> - iounmap(clk_base);
> - return ret;
> }
>
> static const struct of_device_id meson8b_clkc_match_table[] = {
> @@ -793,3 +892,39 @@ static struct platform_driver meson8b_driver = {
> };
>
> builtin_platform_driver(meson8b_driver);
> +
> +static void __init meson8b_clkc_reset_init(struct device_node *np)
> +{
> + struct meson8b_clk_reset *rstc;
> + int ret;
> +
> + /* Generic clocks, PLLs and some of the reset-bits */
> + clk_base = of_iomap(np, 1);
> + if (!clk_base) {
> + pr_err("%s: Unable to map clk base\n", __func__);
> + return;
> + }
> +
> + rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
> + if (!rstc)
> + return;
> +
> + /* Reset Controller */
> + rstc->base = clk_base;
> + rstc->reset.ops = &meson8b_clk_reset_ops;
> + rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
> + rstc->reset.of_node = np;
> + ret = reset_controller_register(&rstc->reset);
> + if (ret) {
> + pr_err("%s: Failed to register clkc reset controller: %d\n",
> + __func__, ret);
> + return;
> + }
> +}
> +
> +CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
> + meson8b_clkc_reset_init);
> +CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
> + meson8b_clkc_reset_init);
> +CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
> + meson8b_clkc_reset_init);
> diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
> index a687e02547dc..5f4d8e49dd4d 100644
> --- a/drivers/clk/meson/meson8b.h
> +++ b/drivers/clk/meson/meson8b.h
> @@ -37,6 +37,9 @@
> #define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */
> #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */
> #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */
> +#define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */
> +#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */
> +#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */
> #define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
> #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
> #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
> @@ -163,7 +166,27 @@
>
> #define CLK_NR_CLKS 96
>
> -/* include the CLKIDs that have been made part of the stable DT binding */
> +#define RESETID_L2_CACHE_SOFT_RESET 0
> +#define RESETID_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET 1
> +#define RESETID_SCU_SOFT_RESET 2
> +#define RESETID_CPU0_SOFT_RESET 3
> +#define RESETID_CPU1_SOFT_RESET 4
> +#define RESETID_CPU2_SOFT_RESET 5
> +#define RESETID_CPU3_SOFT_RESET 6
> +#define RESETID_A5_GLOBAL_RESET 7
> +#define RESETID_A5_AXI_SOFT_RESET 8
> +#define RESETID_A5_ABP_SOFT_RESET 9
> +#define RESETID_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET 10
> +#define RESETID_VID_CLK_CNTL_SOFT_RESET 11
> +#define RESETID_VID_DIVIDER_CNTL_SOFT_RESET_POST 12
> +#define RESETID_VID_DIVIDER_CNTL_SOFT_RESET_PRE 13
> +#define RESETID_VID_DIVIDER_CNTL_RESET_N_POST 14
> +#define RESETID_VID_DIVIDER_CNTL_RESET_N_PRE 15
I think you should directly expose them in a dt-bindings/reset/meson8b-clkc-reset.h file and include it here.
> +
> +/*
> + * include the CLKID and RESETID that have
> + * been made part of the stable DT binding
> + */
> #include <dt-bindings/clock/meson8b-clkc.h>
>
> #endif /* __MESON8B_H */
>
Apart from that :
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
WARNING: multiple messages have this Message-ID (diff)
From: Neil Armstrong <narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
To: Martin Blumenstingl
<martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
khilman-rdvid1DuHRBWk0Htik3J/w@public.gmane.org,
carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org,
jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org,
linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org,
mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org,
sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org
Subject: Re: [PATCH v2 2/3] clk: meson: meson8b: register the built-in reset controller
Date: Tue, 25 Jul 2017 09:58:30 +0200 [thread overview]
Message-ID: <5976FA26.1050907@baylibre.com> (raw)
In-Reply-To: <20170722185807.10504-3-martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
Le 22/07/2017 20:58, Martin Blumenstingl a écrit :
> The clock controller also includes some reset lines. This patch
> implements a reset controller to assert and de-assert these resets.
> The reset controller itself is registered early (through
> CLK_OF_DECLARE_DRIVER) because it is needed very early in the boot
> process (to start the secondary CPU cores).
>
> According to the public S805 datasheet there are two more reset bits
> in the HHI_SYS_CPU_CLK_CNTL0 register, which are not implemented by
> this patch (as these seem to be unused in Amlogic's vendor Linux kernel
> sources and their u-boot tree):
> - bit 15: GEN_DIV_SOFT_RESET
> - bit 14: SOFT_RESET
>
> All information was taken from the public S805 Datasheet and Amlogic's
> vendor GPL kernel sources. This patch is based on an earlier version
> submitted by Carlo Caione.
>
> Suggested-by: Carlo Caione <carlo-6IF/jdPJHihWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
> ---
> drivers/clk/meson/Kconfig | 1 +
> drivers/clk/meson/meson8b.c | 159 ++++++++++++++++++++++++++++++++++++++++----
> drivers/clk/meson/meson8b.h | 25 ++++++-
> 3 files changed, 172 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 5588f75a8414..d2d0174a6eca 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -6,6 +6,7 @@ config COMMON_CLK_AMLOGIC
> config COMMON_CLK_MESON8B
> bool
> depends on COMMON_CLK_AMLOGIC
> + select RESET_CONTROLLER
> help
> Support for the clock controller on AmLogic S802 (Meson8),
> S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
> diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
> index bb3f1de876b1..0f853057885c 100644
> --- a/drivers/clk/meson/meson8b.c
> +++ b/drivers/clk/meson/meson8b.c
> @@ -25,6 +25,8 @@
> #include <linux/clk-provider.h>
> #include <linux/of_address.h>
> #include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
> +#include <linux/slab.h>
> #include <linux/init.h>
>
> #include "clkc.h"
> @@ -32,6 +34,13 @@
>
> static DEFINE_SPINLOCK(clk_lock);
>
> +static void __iomem *clk_base;
> +
> +struct meson8b_clk_reset {
> + struct reset_controller_dev reset;
> + void __iomem *base;
> +};
> +
> static const struct pll_rate_table sys_pll_rate_table[] = {
> PLL_RATE(312000000, 52, 1, 2),
> PLL_RATE(336000000, 56, 1, 2),
> @@ -690,20 +699,114 @@ static struct clk_divider *const meson8b_clk_dividers[] = {
> &meson8b_mpeg_clk_div,
> };
>
> +static const struct meson8b_clk_reset_line {
> + u32 reg;
> + u8 bit_idx;
> +} meson8b_clk_reset_bits[] = {
> + [RESETID_L2_CACHE_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
> + },
> + [RESETID_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
> + },
> + [RESETID_SCU_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
> + },
> + [RESETID_CPU3_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
> + },
> + [RESETID_CPU2_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
> + },
> + [RESETID_CPU1_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
> + },
> + [RESETID_CPU0_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
> + },
> + [RESETID_A5_GLOBAL_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
> + },
> + [RESETID_A5_AXI_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
> + },
> + [RESETID_A5_ABP_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
> + },
> + [RESETID_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
> + .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
> + },
> + [RESETID_VID_CLK_CNTL_SOFT_RESET] = {
> + .reg = HHI_VID_CLK_CNTL, .bit_idx = 15
> + },
> + [RESETID_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
> + },
> + [RESETID_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
> + },
> + [RESETID_VID_DIVIDER_CNTL_RESET_N_POST] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
> + },
> + [RESETID_VID_DIVIDER_CNTL_RESET_N_PRE] = {
> + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
> + },
> +};
> +
> +static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
> + unsigned long id, bool assert)
> +{
> + struct meson8b_clk_reset *meson8b_clk_reset =
> + container_of(rcdev, struct meson8b_clk_reset, reset);
> + unsigned long flags;
> + const struct meson8b_clk_reset_line *reset;
> + u32 val;
> +
> + if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
> + return -EINVAL;
> +
> + reset = &meson8b_clk_reset_bits[id];
> +
> + spin_lock_irqsave(&clk_lock, flags);
> +
> + val = readl(meson8b_clk_reset->base + reset->reg);
> + if (assert)
> + val |= BIT(reset->bit_idx);
> + else
> + val &= ~BIT(reset->bit_idx);
> + writel(val, meson8b_clk_reset->base + reset->reg);
> +
> + spin_unlock_irqrestore(&clk_lock, flags);
> +
> + return 0;
> +}
> +
> +static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + return meson8b_clk_reset_update(rcdev, id, true);
> +}
> +
> +static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + return meson8b_clk_reset_update(rcdev, id, false);
> +}
> +
> +static const struct reset_control_ops meson8b_clk_reset_ops = {
> + .assert = meson8b_clk_reset_assert,
> + .deassert = meson8b_clk_reset_deassert,
> +};
> +
> static int meson8b_clkc_probe(struct platform_device *pdev)
> {
> - void __iomem *clk_base;
> int ret, clkid, i;
> struct clk_hw *parent_hw;
> struct clk *parent_clk;
> struct device *dev = &pdev->dev;
>
> - /* Generic clocks and PLLs */
> - clk_base = of_iomap(dev->of_node, 1);
> - if (!clk_base) {
> - pr_err("%s: Unable to map clk base\n", __func__);
> + if (!clk_base)
> return -ENXIO;
> - }
>
> /* Populate base address for PLLs */
> for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
> @@ -743,7 +846,7 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
> /* FIXME convert to devm_clk_register */
> ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
> if (ret)
> - goto iounmap;
> + return ret;
> }
>
> /*
> @@ -766,15 +869,11 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
> if (ret) {
> pr_err("%s: failed to register clock notifier for cpu_clk\n",
> __func__);
> - goto iounmap;
> + return ret;
> }
>
> return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
> &meson8b_hw_onecell_data);
> -
> -iounmap:
> - iounmap(clk_base);
> - return ret;
> }
>
> static const struct of_device_id meson8b_clkc_match_table[] = {
> @@ -793,3 +892,39 @@ static struct platform_driver meson8b_driver = {
> };
>
> builtin_platform_driver(meson8b_driver);
> +
> +static void __init meson8b_clkc_reset_init(struct device_node *np)
> +{
> + struct meson8b_clk_reset *rstc;
> + int ret;
> +
> + /* Generic clocks, PLLs and some of the reset-bits */
> + clk_base = of_iomap(np, 1);
> + if (!clk_base) {
> + pr_err("%s: Unable to map clk base\n", __func__);
> + return;
> + }
> +
> + rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
> + if (!rstc)
> + return;
> +
> + /* Reset Controller */
> + rstc->base = clk_base;
> + rstc->reset.ops = &meson8b_clk_reset_ops;
> + rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
> + rstc->reset.of_node = np;
> + ret = reset_controller_register(&rstc->reset);
> + if (ret) {
> + pr_err("%s: Failed to register clkc reset controller: %d\n",
> + __func__, ret);
> + return;
> + }
> +}
> +
> +CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
> + meson8b_clkc_reset_init);
> +CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
> + meson8b_clkc_reset_init);
> +CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
> + meson8b_clkc_reset_init);
> diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
> index a687e02547dc..5f4d8e49dd4d 100644
> --- a/drivers/clk/meson/meson8b.h
> +++ b/drivers/clk/meson/meson8b.h
> @@ -37,6 +37,9 @@
> #define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */
> #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */
> #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */
> +#define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */
> +#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */
> +#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */
> #define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
> #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
> #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
> @@ -163,7 +166,27 @@
>
> #define CLK_NR_CLKS 96
>
> -/* include the CLKIDs that have been made part of the stable DT binding */
> +#define RESETID_L2_CACHE_SOFT_RESET 0
> +#define RESETID_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET 1
> +#define RESETID_SCU_SOFT_RESET 2
> +#define RESETID_CPU0_SOFT_RESET 3
> +#define RESETID_CPU1_SOFT_RESET 4
> +#define RESETID_CPU2_SOFT_RESET 5
> +#define RESETID_CPU3_SOFT_RESET 6
> +#define RESETID_A5_GLOBAL_RESET 7
> +#define RESETID_A5_AXI_SOFT_RESET 8
> +#define RESETID_A5_ABP_SOFT_RESET 9
> +#define RESETID_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET 10
> +#define RESETID_VID_CLK_CNTL_SOFT_RESET 11
> +#define RESETID_VID_DIVIDER_CNTL_SOFT_RESET_POST 12
> +#define RESETID_VID_DIVIDER_CNTL_SOFT_RESET_PRE 13
> +#define RESETID_VID_DIVIDER_CNTL_RESET_N_POST 14
> +#define RESETID_VID_DIVIDER_CNTL_RESET_N_PRE 15
I think you should directly expose them in a dt-bindings/reset/meson8b-clkc-reset.h file and include it here.
> +
> +/*
> + * include the CLKID and RESETID that have
> + * been made part of the stable DT binding
> + */
> #include <dt-bindings/clock/meson8b-clkc.h>
>
> #endif /* __MESON8B_H */
>
Apart from that :
Reviewed-by: Neil Armstrong <narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2017-07-25 7:58 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-22 18:58 [PATCH v2 0/3] add the reset controller to the Meson8b clkc Martin Blumenstingl
2017-07-22 18:58 ` Martin Blumenstingl
2017-07-22 18:58 ` [PATCH v2 1/3] dt-bindings: clock: meson8b: describe the embedded reset controller Martin Blumenstingl
2017-07-22 18:58 ` Martin Blumenstingl
2017-07-25 7:55 ` Neil Armstrong
2017-07-25 7:55 ` Neil Armstrong
2017-07-22 18:58 ` [PATCH v2 2/3] clk: meson: meson8b: register the built-in " Martin Blumenstingl
2017-07-22 18:58 ` Martin Blumenstingl
2017-07-22 18:58 ` Martin Blumenstingl
2017-07-25 7:58 ` Neil Armstrong [this message]
2017-07-25 7:58 ` Neil Armstrong
2017-07-25 7:58 ` Neil Armstrong
2017-07-25 19:17 ` Martin Blumenstingl
2017-07-25 19:17 ` Martin Blumenstingl
2017-07-25 19:17 ` Martin Blumenstingl
2017-07-22 18:58 ` [PATCH v2 3/3] ARM: dts: meson: mark the clock controller also as " Martin Blumenstingl
2017-07-22 18:58 ` Martin Blumenstingl
2017-07-25 7:58 ` Neil Armstrong
2017-07-25 7:58 ` Neil Armstrong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5976FA26.1050907@baylibre.com \
--to=narmstrong@baylibre.com \
--cc=linus-amlogic@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.