Re: [linux-sunxi] [PATCH v4 7/9] clk: sunxi-ng: add support for the Allwinner H6 CCU

2018-03-16 Thread Jernej Škrabec
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

2018-03-16 Thread Icenowy Zheng
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",
+