ARM: meson: add clock/reset controller
Subsystems (6)
cover ARM: meson: add clock/reset controller
This patchset introduces preliminary support for the clock/reset controller found on Amlogic MesonX SoCs and enables it for the Meson6.
The reset controller is in charge of shutting off the clock to disable modules and submodules within the chip. Unfortunately the documentation we have does not explicit which clock is gated but only which peripheral is reset so the clocks introduced are not gated but the peripherals are reset using the reset controller.
DTS patches will follow.
Carlo Caione (4):
ARM: meson: add basic infrastructure for clocks
ARM: meson: add reset controller
ARM: meson: enable reset controller in kconfig
ARM: meson: add documentation for reset/clock controller
.../bindings/clock/amlogic,meson6-clkc.txt | 45 ++++ arch/arm/mach-meson/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/meson/Makefile | 8 + drivers/clk/meson/clk-pll.c | 298 +++++++++++++++++++++ drivers/clk/meson/clkc.c | 151 +++++++++++ drivers/clk/meson/clkc.h | 174 ++++++++++++ drivers/clk/meson/meson6-clkc.c | 178 ++++++++++++ drivers/clk/meson/rstc.c | 152 +++++++++++ include/dt-bindings/clock/meson6-clkc.h | 18 ++ 10 files changed, 1027 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,meson6-clkc.txt create mode 100644 drivers/clk/meson/Makefile create mode 100644 drivers/clk/meson/clk-pll.c create mode 100644 drivers/clk/meson/clkc.c create mode 100644 drivers/clk/meson/clkc.h create mode 100644 drivers/clk/meson/meson6-clkc.c create mode 100644 drivers/clk/meson/rstc.c create mode 100644 include/dt-bindings/clock/meson6-clkc.h
Signature · 1 line
1.9.1
PATCH 1/4 ARM: meson: add basic infrastructure for clocks
This patchset adds the infrastructure for registering and managing the core clocks found on Amlogic MesonX SoCs and also adds the support for the basic Meson6 clocks.
--- drivers/clk/Makefile | 1 + drivers/clk/meson/Makefile | 7 + drivers/clk/meson/clk-pll.c | 298 ++++++++++++++++++++++++++++++++ drivers/clk/meson/clkc.c | 151 ++++++++++++++++ drivers/clk/meson/clkc.h | 159 +++++++++++++++++ drivers/clk/meson/meson6-clkc.c | 160 +++++++++++++++++ include/dt-bindings/clock/meson6-clkc.h | 18 ++ 7 files changed, 794 insertions(+) create mode 100644 drivers/clk/meson/Makefile create mode 100644 drivers/clk/meson/clk-pll.c create mode 100644 drivers/clk/meson/clkc.c create mode 100644 drivers/clk/meson/clkc.h create mode 100644 drivers/clk/meson/meson6-clkc.c create mode 100644 include/dt-bindings/clock/meson6-clkc.h
drivers/clk/Makefile +1 -0
@@ -51,6 +51,7 @@ ifeq ($(CONFIG_COMMON_CLK), y) obj-$(CONFIG_ARCH_MMP) += mmp/ endif obj-$(CONFIG_PLAT_ORION) += mvebu/ +obj-$(CONFIG_ARCH_MESON) += meson/ obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
drivers/clk/meson/Makefile new file +7 -0
@@ -0,0 +1,7 @@ +# +# Makefile for Meson specific clk +# + +obj-y += clkc.o +obj-y += meson6-clkc.o +obj-y += clk-pll.o
drivers/clk/meson/clk-pll.c new file +298 -0
298 lines not on this page · raw message
drivers/clk/meson/clkc.c new file +151 -0
151 lines not on this page · raw message
drivers/clk/meson/clkc.h new file +159 -0
159 lines not on this page · raw message
drivers/clk/meson/meson6-clkc.c new file +160 -0
160 lines not on this page · raw message
include/dt-bindings/clock/meson6-clkc.h new file +18 -0
@@ -0,0 +1,18 @@ +/* +* Meson6 clock tree IDs +*/ + +#define CLKID_XTAL 1 +#define CLKID_RTC_XTAL 2 +#define CLKID_DPLL_SYS 3 +#define CLKID_DPLL_DDR 4 +#define CLKID_DPLL_VID2 5 +#define CLKID_MPLL_FIXED 6 +#define CLKID_HPLL_HDMI 7 +#define CLKID_HPLL_LVDS 8 +#define CLKID_FCLK_DIV2 9 +#define CLKID_FCLK_DIV3 10 +#define CLKID_FCLK_DIV5 11 +#define CLKID_CLK81 12 + +#define CLK_NR_CLKS (CLKID_CLK81 + 1)
Signature · 1 line
1.9.1
PATCH 1/4 ARM: meson: add basic infrastructure for clocks
Quoting Carlo Caione (2014-11-19 02:32:20)
Quoted 3 lines
This patchset adds the infrastructure for registering and managing the core clocks found on Amlogic MesonX SoCs and also adds the support for the basic Meson6 clocks.
Minor nitpick: typically the $SUBJECT starts with "arm:" if the patch primarily deals with code under arch/arm. Since this code lives in drivers/clk it might be better to use something like:
clk: meson: add basic infrastructure for clocks
<snip>
Quoted 50 lines
drivers/clk/meson/clk-pll.c new file +50
-0+static void meson_clk_pll_get_parms (struct meson_clk_pll *pll, +unsigned long *rate,unsigned long p_rate, +u16 *best_n,u16 *best_m,u16 *best_od_fb) +{ +unsigned long rate_mhz, p_rate_mhz; +unsigned long pll_vco_min_mhz, pll_vco_max_mhz; +unsigned long cur_rate_mhz, best_rate_mhz; +u16 m, m_min, m_max, m_mask; +u16 n, n_min, n_max, n_mask, _n_min, _n_max; +u16 od_fb, od_fb_max; + + rate_mhz = *rate /1000000 ; + p_rate_mhz = p_rate /1000000 ; + pll_vco_min_mhz = pll->conf->vco_min_mhz; + pll_vco_max_mhz = pll->conf->vco_max_mhz; + best_rate_mhz =ULONG_MAX ; + *best_n =0 ; + *best_m =0 ; + *best_od_fb =1 ; + + m_mask =PMASK (pll->conf->m.width); + n_mask =PMASK (pll->conf->n.width); + +/* FREF = P_RATE / N */ + n_min =max_t (u16,DIV_ROUND_UP (p_rate_mhz,MESON_FREF_MAX_MHZ ),1 ); + n_max =min_t (u16, p_rate_mhz /MESON_FREF_MIN_MHZ , n_mask); + + od_fb_max =1 <<PMASK (pll->conf->od_fb.width); + +for (od_fb =1 ; od_fb <= od_fb_max; od_fb <<=1 ) { + +/* VCO = P_RATE * M * OD_FB / N */ + m_min =max_t (u16,DIV_ROUND_UP (pll_vco_min_mhz, + p_rate_mhz * od_fb) * n_min,1 ); + m_max =min_t (u16, (pll_vco_max_mhz * n_max) / + (p_rate_mhz * od_fb), m_mask); + + +for (m = m_min; m <= m_max; m++) { + _n_min =max_t (u16, n_min, +DIV_ROUND_UP (p_rate_mhz * m * od_fb, + pll_vco_max_mhz)); + _n_max =min_t (u16, n_max, + p_rate_mhz * m * od_fb / pll_vco_min_mhz); + +for (n = _n_min; n <= _n_max; n++) { + cur_rate_mhz = p_rate_mhz * m * od_fb / n; + +if (abs (cur_rate_mhz - rate_mhz) < +abs (best_rate_mhz - rate_mhz)) {
drivers/clk/meson/clk-pll.c line 126
Quoted 10 lines
drivers/clk/meson/clk-pll.c new file +10
-0+ best_rate_mhz = cur_rate_mhz; + *best_n = n; + *best_m = m; + *best_od_fb = od_fb; +if (best_rate_mhz == rate_mhz) + goto done; + } + } + } + }
Nothing strictly wrong with the above, but is is n^3 complexity. If your tables are large then you might be spending a non-trivial amount time calculating the pll parameters.
<snip>
Quoted 41 lines
drivers/clk/meson/clk-pll.c new file +41
-0+ +done: + *best_od_fb >>=1 ; + *rate = best_rate_mhz *1000000 ; +return ; + +} + +static unsigned long meson_clk_pll_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct meson_clk_pll *pll =to_meson_clk_pll (hw); +struct parm *p_n, *p_m, *p_od_fb; +unsigned long parent_rate_mhz = parent_rate /1000000 ; +unsigned long rate_mhz; +u16 n, m, od_fb =1 ; +u32 reg_n, reg_m, reg_od_fb; + + p_n = &pll->conf->n; + p_m = &pll->conf->m; + p_od_fb = &pll->conf->od_fb; + + reg_n =readl (pll->base + p_n->reg_off); + n =PARM_GET (p_n->width, p_n->shift, reg_n); + + reg_m =readl (pll->base + p_m->reg_off); + m =PARM_GET (p_m->width, p_m->shift, reg_m); + +if (p_od_fb->width !=MESON_PARM_NOT_APPLICABLE ) { + reg_od_fb =readl (pll->base + p_od_fb->reg_off); + od_fb =PARM_GET (p_od_fb->width, p_od_fb->shift, reg_od_fb); + od_fb =1 << od_fb; + } + + rate_mhz = parent_rate_mhz * m * od_fb / n; + +return rate_mhz *1000000 ; +} + +static long meson_clk_pll_round_rate (struct clk_hw *hw,unsigned long rate, +unsigned long *parent_rate)
drivers/clk/meson/clk-pll.c line 177
Quoted 10 lines
drivers/clk/meson/clk-pll.c new file +10
-0+{ +struct meson_clk_pll *pll =to_meson_clk_pll (hw); +u16 m, n, od_fb; + +meson_clk_pll_get_parms (pll, &rate, *parent_rate, &n, &m, &od_fb); +if (m ==0 || n ==0 ) +return -EINVAL ; + +return rate; +}
Can the clock signal input to your pll by multiplexed? Are there multiple possible parents to a pll? If so you might want to use .determine_rate over .round_rate.
<snip>
Quoted 24 lines
drivers/clk/meson/clkc.h new file +18
-0@@ -0,0 +1,159 @@ +/* +* Copyright (c) 2014 Carlo Caione <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __CLKC_H +#define __CLKC_H
<snip>
drivers/clk/meson/clkc.h line 159
Quoted 10 lines
drivers/clk/meson/clkc.h new file +10
-0+void meson_clk_init (struct device_node *np,unsigned long nr_clks); +void meson_clk_add_lookup (struct clk *clk,unsigned int id); +void meson_clk_register_pll_divs (struct pll_div_conf *pll_divs, +unsigned int nr_pll_divs, +void __iomem *reg_base); +void meson_clk_register_pll_div (struct pll_div_conf *pll_div_conf, +void __iomem *reg_base,spinlock_t *lock); +void meson_clk_register_clks (struct clk_conf *clk_confs, +unsigned int nr_confs, +void __iomem *clk_base);
Missing #endif here causes compile failure.
Regards,
Mike
PATCH 1/4 ARM: meson: add basic infrastructure for clocks
Quoted 10 lines · Mike Turquette
Quoting Carlo Caione (2014-11-19 02:32:20)
Quoted 3 lines
This patchset adds the infrastructure for registering and managing the core clocks found on Amlogic MesonX SoCs and also adds the support for the basic Meson6 clocks.
Minor nitpick: typically the $SUBJECT starts with "arm:" if the patch primarily deals with code under
arch/arm. Since this code lives indrivers/clkit might be better to use something like:clk: meson: add basic infrastructure for clocks
Good to know. Thanks.
Quoted 56 lines
Quoted 56 lines
drivers/clk/meson/clk-pll.c new file +56
-0+static void meson_clk_pll_get_parms (struct meson_clk_pll *pll, +unsigned long *rate,unsigned long p_rate, +u16 *best_n,u16 *best_m,u16 *best_od_fb) +{ +unsigned long rate_mhz, p_rate_mhz; +unsigned long pll_vco_min_mhz, pll_vco_max_mhz; +unsigned long cur_rate_mhz, best_rate_mhz; +u16 m, m_min, m_max, m_mask; +u16 n, n_min, n_max, n_mask, _n_min, _n_max; +u16 od_fb, od_fb_max; + + rate_mhz = *rate /1000000 ; + p_rate_mhz = p_rate /1000000 ; + pll_vco_min_mhz = pll->conf->vco_min_mhz; + pll_vco_max_mhz = pll->conf->vco_max_mhz; + best_rate_mhz =ULONG_MAX ; + *best_n =0 ; + *best_m =0 ; + *best_od_fb =1 ; + + m_mask =PMASK (pll->conf->m.width); + n_mask =PMASK (pll->conf->n.width); + +/* FREF = P_RATE / N */ + n_min =max_t (u16,DIV_ROUND_UP (p_rate_mhz,MESON_FREF_MAX_MHZ ),1 ); + n_max =min_t (u16, p_rate_mhz /MESON_FREF_MIN_MHZ , n_mask); + + od_fb_max =1 <<PMASK (pll->conf->od_fb.width); + +for (od_fb =1 ; od_fb <= od_fb_max; od_fb <<=1 ) { + +/* VCO = P_RATE * M * OD_FB / N */ + m_min =max_t (u16,DIV_ROUND_UP (pll_vco_min_mhz, + p_rate_mhz * od_fb) * n_min,1 ); + m_max =min_t (u16, (pll_vco_max_mhz * n_max) / + (p_rate_mhz * od_fb), m_mask); + + +for (m = m_min; m <= m_max; m++) { + _n_min =max_t (u16, n_min, +DIV_ROUND_UP (p_rate_mhz * m * od_fb, + pll_vco_max_mhz)); + _n_max =min_t (u16, n_max, + p_rate_mhz * m * od_fb / pll_vco_min_mhz); + +for (n = _n_min; n <= _n_max; n++) { + cur_rate_mhz = p_rate_mhz * m * od_fb / n; + +if (abs (cur_rate_mhz - rate_mhz) < +abs (best_rate_mhz - rate_mhz)) { + best_rate_mhz = cur_rate_mhz; + *best_n = n; + *best_m = m; + *best_od_fb = od_fb; +if (best_rate_mhz == rate_mhz) + goto done;
Quoted 8 lines
drivers/clk/meson/clk-pll.c line 126
Quoted 4 lines
drivers/clk/meson/clk-pll.c new file +4
-0+ } + } + } + }Nothing strictly wrong with the above, but is is n^3 complexity. If your tables are large then you might be spending a non-trivial amount time calculating the pll parameters.
Actually od_fb il always quite small (maximum /1, /2, /4, /8 maximum). But I see the problem.
I'll investigate a bit to check if there is a way to make it simpler (and shorter)
Quoted 47 lines
Quoted 47 lines
drivers/clk/meson/clk-pll.c new file +47
-0+ +done: + *best_od_fb >>=1 ; + *rate = best_rate_mhz *1000000 ; +return ; + +} + +static unsigned long meson_clk_pll_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct meson_clk_pll *pll =to_meson_clk_pll (hw); +struct parm *p_n, *p_m, *p_od_fb; +unsigned long parent_rate_mhz = parent_rate /1000000 ; +unsigned long rate_mhz; +u16 n, m, od_fb =1 ; +u32 reg_n, reg_m, reg_od_fb; + + p_n = &pll->conf->n; + p_m = &pll->conf->m; + p_od_fb = &pll->conf->od_fb; + + reg_n =readl (pll->base + p_n->reg_off); + n =PARM_GET (p_n->width, p_n->shift, reg_n); + + reg_m =readl (pll->base + p_m->reg_off); + m =PARM_GET (p_m->width, p_m->shift, reg_m); + +if (p_od_fb->width !=MESON_PARM_NOT_APPLICABLE ) { + reg_od_fb =readl (pll->base + p_od_fb->reg_off); + od_fb =PARM_GET (p_od_fb->width, p_od_fb->shift, reg_od_fb); + od_fb =1 << od_fb; + } + + rate_mhz = parent_rate_mhz * m * od_fb / n; + +return rate_mhz *1000000 ; +} + +static long meson_clk_pll_round_rate (struct clk_hw *hw,unsigned long rate, +unsigned long *parent_rate) +{ +struct meson_clk_pll *pll =to_meson_clk_pll (hw); +u16 m, n, od_fb; + +meson_clk_pll_get_parms (pll, &rate, *parent_rate, &n, &m, &od_fb); +if (m ==0 || n ==0 )
Quoted 8 lines
drivers/clk/meson/clk-pll.c line 177
Quoted 4 lines
drivers/clk/meson/clk-pll.c new file +4
-0+return -EINVAL ; + +return rate; +}Can the clock signal input to your pll by multiplexed? Are there multiple possible parents to a pll? If so you might want to use .determine_rate over .round_rate.
The input to the PLLs is always unique for both Meson6 and Meson8.
Quoted 29 lines
<snip>
Quoted 24 lines
drivers/clk/meson/clkc.h new file +18
-0@@ -0,0 +1,159 @@ +/* +* Copyright (c) 2014 Carlo Caione <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __CLKC_H +#define __CLKC_H<snip>
Quoted 12 lines
drivers/clk/meson/clkc.h line 159
Quoted 10 lines
drivers/clk/meson/clkc.h new file +10
-0+void meson_clk_init (struct device_node *np,unsigned long nr_clks); +void meson_clk_add_lookup (struct clk *clk,unsigned int id); +void meson_clk_register_pll_divs (struct pll_div_conf *pll_divs, +unsigned int nr_pll_divs, +void __iomem *reg_base); +void meson_clk_register_pll_div (struct pll_div_conf *pll_div_conf, +void __iomem *reg_base,spinlock_t *lock); +void meson_clk_register_clks (struct clk_conf *clk_confs, +unsigned int nr_confs, +void __iomem *clk_base);Missing #endif here causes compile failure.
Ah, then you will find a double #endif in the reset controller patch. I screwed up separating the patches.
Thank you for the review.
Signature · 1 line
Carlo Caione
PATCH 1/4 ARM: meson: add basic infrastructure for clocks
In reply to Carlo CaioneQuoting Carlo Caione (2014-11-19 02:32:20)
Quoted 16 lines
drivers/clk/meson/clk-pll.c new file +10
-0@@ -0,0 +1,298 @@ +/* +* Copyright (c) 2014 Carlo Caione <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
drivers/clk/meson/clk-pll.c line 20
Quoted 10 lines
drivers/clk/meson/clk-pll.c new file +10
-0+* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/delay.h> +#include <linux/err.h>
All of the headers below are unnecessary. Copy/paste? I didn't bother to check the ones above.
drivers/clk/meson/clk-pll.c line 25
Quoted 5 lines
drivers/clk/meson/clk-pll.c new file +5
-0+#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/slab.h> +#include <linux/string.h>
Regards,
Mike
PATCH 1/4 ARM: meson: add basic infrastructure for clocks
Quoted 22 lines · Mike Turquette
Quoting Carlo Caione (2014-11-19 02:32:20)
Quoted 21 lines
drivers/clk/meson/clk-pll.c new file +15
-0@@ -0,0 +1,298 @@ +/* +* Copyright (c) 2014 Carlo Caione <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/
Quoted 8 lines
drivers/clk/meson/clk-pll.c line 20
Quoted 5 lines
drivers/clk/meson/clk-pll.c new file +5
-0+ +#include <linux/clk-provider.h> +#include <linux/clkdev.h> +#include <linux/delay.h> +#include <linux/err.h> All of the headers below are unnecessary. Copy/paste? I didn't bother to check the ones above.
No prob. I'll fix them also.
Quoted 8 lines
drivers/clk/meson/clk-pll.c line 25
Quoted 5 lines
drivers/clk/meson/clk-pll.c new file +5
-0+#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/slab.h> +#include <linux/string.h> Regards,
Mike
Thanks,
Signature · 1 line
Carlo Caione
PATCH 2/4 ARM: meson: add reset controller
In reply to Carlo CaioneModules and submodules within Meson6 and Meson8 SoCs can be disabled by shutting off the clock. The control for these clocks comes from several registers that are mapped contiguously except a special register that controls peripherals in the AO (Always-On) power domain. The reset controller manages both the cases according to the reset ID.
--- drivers/clk/meson/Makefile | 1 + drivers/clk/meson/clkc.h | 15 ++++ drivers/clk/meson/meson6-clkc.c | 18 +++++ drivers/clk/meson/rstc.c | 152 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 186 insertions(+) create mode 100644 drivers/clk/meson/rstc.c
drivers/clk/meson/Makefile +1 -0
@@ -5,3 +5,4 @@ obj-y += clkc.o obj-y += meson6-clkc.o obj-y += clk-pll.o +obj-$(CONFIG_RESET_CONTROLLER) += rstc.o
drivers/clk/meson/clkc.h +15 -0
@@ -157,3 +157,18 @@ void meson_clk_register_pll_div(struct pll_div_conf *pll_div_conf,void meson_clk_register_clks (struct clk_conf *clk_confs,unsigned int nr_confs,void __iomem *clk_base); + +#ifdef CONFIG_RESET_CONTROLLER +void meson_register_rstc (struct device_node *np,unsigned int num_regs, +void __iomem *ao_base,void __iomem *ot_base, +unsigned int ao_off_id,u8 flags); +#else +static inline void meson_register_rstc (struct device_node *np, +unsigned int num_regs, +void __iomem *ao_base, +void __iomem *ot_base, +unsigned int ao_off_id,u8 flags) +{ +} +#endif +#endif /* __CLKC_H */
drivers/clk/meson/meson6-clkc.c +18 -0
@@ -30,9 +30,16 @@#define MESON6_REG_DPLL_VID2 0x011c#define MESON6_REG_HPLL 0x0270#define MESON6_REG_HHI_MPEG 0x0174 +#define MESON6_REG_RSTC 0x0140#define MESON6_XTAL "xtal" +/* +* Every reset ID >= 163 is mapped to the AO domain register +*/ +#define MESON6_RSTC_N_REGS 6 +#define MESON6_AO_OFF ((MESON6_RSTC_N_REGS - 1) * BITS_PER_LONG + 3) +static struct pll_conf dpll_conf =PLL_CONF2 (750 ,1512 ,PARM (0x00 ,0 ,9 ),PARM (0x00 ,9 ,5 ));
@@ -129,6 +136,7 @@ static struct clk_conf meson_clk_confs[] __initdata = {static void __init meson_clkc_init (struct device_node *np) {void __iomem *clk_base; +void __iomem *ao_base;u32 xtal_rate;/* XTAL */
@@ -156,5 +164,15 @@ static void __init meson_clkc_init(struct device_node *np) clk_base);meson_clk_register_pll_divs (meson_pll_divs,ARRAY_SIZE (meson_pll_divs), clk_base); + +/* Reset controller */ + ao_base =of_iomap (np,2 ); +if (!ao_base) { +pr_warn ("%s: Unable to map ao domain base for reset controller\n" , __func__); +return ; + } + +meson_register_rstc (np,MESON6_RSTC_N_REGS , ao_base, + clk_base +MESON6_REG_RSTC ,MESON6_AO_OFF ,0 ); }CLK_OF_DECLARE (meson6_clock,"amlogic,meson6-clkc" , meson_clkc_init);
drivers/clk/meson/rstc.c new file +152 -0
152 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH 3/4 ARM: meson: enable reset controller in kconfig
In reply to Carlo CaioneModify the arch Kconfig to enable the reset controller
--- arch/arm/mach-meson/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/mach-meson/Kconfig +2 -0
@@ -10,6 +10,8 @@ config MACH_MESON6 bool "Amlogic Meson6 (8726MX) SoCs support" default ARCH_MESON select MESON6_TIMER + select ARCH_HAS_RESET_CONTROLLER + select RESET_CONTROLLER config MACH_MESON8 bool "Amlogic Meson8 SoCs support"
Signature · 1 line
1.9.1
PATCH 4/4 ARM: meson: add documentation for reset/clock controller
In reply to Carlo CaioneAdd documentation for the reset and clock controller
--- .../bindings/clock/amlogic,meson6-clkc.txt | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/amlogic,meson6-clkc.txt
Documentation/devicetree/bindings/clock/amlogic,meson6-clkc.txt new file +45 -0
@@ -0,0 +1,45 @@ +* Amlogic Meson6 Clock and Reset Unit + +The Amlogic Meson6 clock controller generates and supplies clock to various +controllers within the SoC and also implements a reset controller for SoC +peripherals. + +Required Properties: + +- compatible: should be "amlogic,meson6-clkc" +- reg: it must be composed by three tuples: + 0) physical base address of the xtal register and length of memory + mapped region. + 1) physical base address of the clock controller and length of memory + mapped region. + 2) physical base address of the AO domain reset register and length + of memory mapped region. + +- #clock-cells: should be 1. +- #reset-cells: should be 1. + +Each clock is assigned an identifier and client nodes can use this identifier +to specify the clock which they consume. All available clocks are defined as +preprocessor macros in the dt-bindings/clock/meson6-clkc.h header and can be +used in device tree sources. + +Example: Clock controller node: + + clkc: clock-controller at c1104000 { + #clock-cells = <1>; + #reset-cells = <1>; + compatible = "amlogic,meson6-clkc"; + reg = <0xc1108000 0x4>, <0xc1104000 0x460>, <0xc8100040 0x4>; + }; + + +Example: UART controller node that consumes the clock generated by the clock + controller: + + uart_AO: serial at c81004c0 { + compatible = "amlogic,meson-uart"; + reg = <0xc81004c0 0x14>; + interrupts = <0 90 1>; + clocks = <&clkc CLKID_CLK81>; + status = "disabled"; + };
Signature · 1 line
1.9.1