Re: [linux-sunxi] [PATCH v4 7/9] clk: sunxi-ng: add support for the Allwinner H6 CCU
Hi, Dne petek, 16. marec 2018 ob 15:02:13 CET je Icenowy Zheng napisal(a): > The Allwinner H6 SoC has a CCU which has been largely rearranged. > > Add support for it in the sunxi-ng CCU framework. > > Signed-off-by: Icenowy Zheng > Acked-by: Maxime Ripard > --- > Changes in v4: > - Extract the device tree binding document to another patch. > > Changes in v3: > - SPDX license idetifier fix. > - Add some comments at initialization. > > Changes in v2: > - Exported APB1 bus clock for PIO. > - Switch to SPDX license identifier. > > drivers/clk/sunxi-ng/Kconfig |5 + > drivers/clk/sunxi-ng/Makefile |1 + > drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 1207 > + drivers/clk/sunxi-ng/ccu-sun50i-h6.h | > 56 ++ > include/dt-bindings/clock/sun50i-h6-ccu.h | 124 +++ > include/dt-bindings/reset/sun50i-h6-ccu.h | 73 ++ > 6 files changed, 1466 insertions(+) > create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-h6.c > create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-h6.h > create mode 100644 include/dt-bindings/clock/sun50i-h6-ccu.h > create mode 100644 include/dt-bindings/reset/sun50i-h6-ccu.h > > diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig > index 33168f94ee39..79dfd296c3d1 100644 > --- a/drivers/clk/sunxi-ng/Kconfig > +++ b/drivers/clk/sunxi-ng/Kconfig > @@ -11,6 +11,11 @@ config SUN50I_A64_CCU > default ARM64 && ARCH_SUNXI > depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST > > +config SUN50I_H6_CCU > + bool "Support for the Allwinner H6 CCU" > + default ARM64 && ARCH_SUNXI > + depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST > + > config SUN4I_A10_CCU > bool "Support for the Allwinner A10/A20 CCU" > default MACH_SUN4I > diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile > index 4141c3fe08ae..128a40ee5c5e 100644 > --- a/drivers/clk/sunxi-ng/Makefile > +++ b/drivers/clk/sunxi-ng/Makefile > @@ -22,6 +22,7 @@ lib-$(CONFIG_SUNXI_CCU) += ccu_mp.o > > # SoC support > obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o > +obj-$(CONFIG_SUN50I_H6_CCU) += ccu-sun50i-h6.o > obj-$(CONFIG_SUN4I_A10_CCU) += ccu-sun4i-a10.o > obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o > obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c > b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c new file mode 100644 > index ..d5eab49e6350 > --- /dev/null > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c > @@ -0,0 +1,1207 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (c) 2017 Icenowy Zheng > + */ > + > +#include > +#include > +#include > + > +#include "ccu_common.h" > +#include "ccu_reset.h" > + > +#include "ccu_div.h" > +#include "ccu_gate.h" > +#include "ccu_mp.h" > +#include "ccu_mult.h" > +#include "ccu_nk.h" > +#include "ccu_nkm.h" > +#include "ccu_nkmp.h" > +#include "ccu_nm.h" > + > +#include "ccu-sun50i-h6.h" > + > +/* > + * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However > + * P should only be used for output frequencies lower than 288 MHz. > + * > + * For now we can just model it as a multiplier clock, and force P to /1. > + * > + * The M factor is present in the register's description, but not in the > + * frequency formula, and it's documented as "M is only used for backdoor > + * testing", so it's not modelled and then force to 0. > + */ > +#define SUN50I_H6_PLL_CPUX_REG 0x000 > +static struct ccu_mult pll_cpux_clk = { > + .enable = BIT(31), > + .lock = BIT(28), > + .mult = _SUNXI_CCU_MULT_MIN(8, 8, 12), > + .common = { > + .reg= 0x000, > + .hw.init= CLK_HW_INIT("pll-cpux", "osc24M", > + &ccu_mult_ops, > + CLK_SET_RATE_UNGATE), > + }, > +}; > + > +/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */ > +#define SUN50I_H6_PLL_DDR0_REG 0x010 > +static struct ccu_nkmp pll_ddr0_clk = { > + .enable = BIT(31), > + .lock = BIT(28), > + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), > + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ > + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ > + .common = { > + .reg= 0x010, > + .hw.init= CLK_HW_INIT("pll-ddr0", "osc24M", > + &ccu_nkmp_ops, > + CLK_SET_RATE_UNGATE), > + }, > +}; > + > +#define SUN50I_H6_PLL_PERIPH0_REG0x020 > +static struct ccu_nkmp pll_periph0_clk = { > + .enable = BIT(31), > + .lock = BIT(28), > + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), > + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ > + .p = _SUNXI_
[linux-sunxi] [PATCH v4 7/9] clk: sunxi-ng: add support for the Allwinner H6 CCU
The Allwinner H6 SoC has a CCU which has been largely rearranged. Add support for it in the sunxi-ng CCU framework. Signed-off-by: Icenowy Zheng Acked-by: Maxime Ripard --- Changes in v4: - Extract the device tree binding document to another patch. Changes in v3: - SPDX license idetifier fix. - Add some comments at initialization. Changes in v2: - Exported APB1 bus clock for PIO. - Switch to SPDX license identifier. drivers/clk/sunxi-ng/Kconfig |5 + drivers/clk/sunxi-ng/Makefile |1 + drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 1207 + drivers/clk/sunxi-ng/ccu-sun50i-h6.h | 56 ++ include/dt-bindings/clock/sun50i-h6-ccu.h | 124 +++ include/dt-bindings/reset/sun50i-h6-ccu.h | 73 ++ 6 files changed, 1466 insertions(+) create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-h6.c create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-h6.h create mode 100644 include/dt-bindings/clock/sun50i-h6-ccu.h create mode 100644 include/dt-bindings/reset/sun50i-h6-ccu.h diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 33168f94ee39..79dfd296c3d1 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -11,6 +11,11 @@ config SUN50I_A64_CCU default ARM64 && ARCH_SUNXI depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST +config SUN50I_H6_CCU + bool "Support for the Allwinner H6 CCU" + default ARM64 && ARCH_SUNXI + depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST + config SUN4I_A10_CCU bool "Support for the Allwinner A10/A20 CCU" default MACH_SUN4I diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 4141c3fe08ae..128a40ee5c5e 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile @@ -22,6 +22,7 @@ lib-$(CONFIG_SUNXI_CCU) += ccu_mp.o # SoC support obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o +obj-$(CONFIG_SUN50I_H6_CCU)+= ccu-sun50i-h6.o obj-$(CONFIG_SUN4I_A10_CCU)+= ccu-sun4i-a10.o obj-$(CONFIG_SUN5I_CCU)+= ccu-sun5i.o obj-$(CONFIG_SUN6I_A31_CCU)+= ccu-sun6i-a31.o diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c new file mode 100644 index ..d5eab49e6350 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -0,0 +1,1207 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017 Icenowy Zheng + */ + +#include +#include +#include + +#include "ccu_common.h" +#include "ccu_reset.h" + +#include "ccu_div.h" +#include "ccu_gate.h" +#include "ccu_mp.h" +#include "ccu_mult.h" +#include "ccu_nk.h" +#include "ccu_nkm.h" +#include "ccu_nkmp.h" +#include "ccu_nm.h" + +#include "ccu-sun50i-h6.h" + +/* + * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However + * P should only be used for output frequencies lower than 288 MHz. + * + * For now we can just model it as a multiplier clock, and force P to /1. + * + * The M factor is present in the register's description, but not in the + * frequency formula, and it's documented as "M is only used for backdoor + * testing", so it's not modelled and then force to 0. + */ +#define SUN50I_H6_PLL_CPUX_REG 0x000 +static struct ccu_mult pll_cpux_clk = { + .enable = BIT(31), + .lock = BIT(28), + .mult = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .common = { + .reg= 0x000, + .hw.init= CLK_HW_INIT("pll-cpux", "osc24M", + &ccu_mult_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */ +#define SUN50I_H6_PLL_DDR0_REG 0x010 +static struct ccu_nkmp pll_ddr0_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .common = { + .reg= 0x010, + .hw.init= CLK_HW_INIT("pll-ddr0", "osc24M", + &ccu_nkmp_ops, + CLK_SET_RATE_UNGATE), + }, +}; + +#define SUN50I_H6_PLL_PERIPH0_REG 0x020 +static struct ccu_nkmp pll_periph0_clk = { + .enable = BIT(31), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .fixed_post_div = 4, + .common = { + .reg= 0x020, + .features = CCU_FEATURE_FIXED_POSTDIV, + .hw.init= CLK_HW_INIT("pll-periph0", "osc24M", +