From 5a909f4d4d10f3a7a59b3b75eee502937e166891 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Mon, 2 May 2022 22:00:05 -0500 Subject: [PATCH 13/90] clk: sunxi: Add a driver for the legacy A31/A23/A33 PRCM Signed-off-by: Samuel Holland --- drivers/clk/sunxi/Kconfig | 13 ++++- drivers/clk/sunxi/Makefile | 1 + drivers/clk/sunxi/clk_a31_apb0.c | 97 ++++++++++++++++++++++++++++++++ include/clk/sunxi.h | 1 + 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 drivers/clk/sunxi/clk_a31_apb0.c --- a/drivers/clk/sunxi/Kconfig +++ b/drivers/clk/sunxi/Kconfig @@ -38,12 +38,21 @@ config CLK_SUN6I_A31 This enables common clock driver support for platforms based on Allwinner A31/A31s SoC. +config CLK_SUN6I_A31_APB0 + bool "Clock driver for Allwinner A31 generation PRCM (legacy)" + default MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 + help + This enables common clock driver support for the PRCM + in Allwinner A31/A31s/A23/A33 SoCs using the legacy PRCM + MFD binding. + config CLK_SUN6I_A31_R - bool "Clock driver for Allwinner A31 generation PRCM" + bool "Clock driver for Allwinner A31 generation PRCM (CCU)" default SUNXI_GEN_SUN6I help This enables common clock driver support for the PRCM - in Allwinner A31/A31s/A23/A33/A83T/H3/A64/H5 SoCs. + in Allwinner A31/A31s/A23/A33/A83T/H3/A64/H5 SoCs using + the new CCU binding. config CLK_SUN8I_A23 bool "Clock driver for Allwinner A23/A33" --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_CLK_SUNIV_F1C100S) += clk_f obj-$(CONFIG_CLK_SUN4I_A10) += clk_a10.o obj-$(CONFIG_CLK_SUN5I_A10S) += clk_a10s.o obj-$(CONFIG_CLK_SUN6I_A31) += clk_a31.o +obj-$(CONFIG_CLK_SUN6I_A31_APB0) += clk_a31_apb0.o obj-$(CONFIG_CLK_SUN6I_A31_R) += clk_a31_r.o obj-$(CONFIG_CLK_SUN8I_A23) += clk_a23.o obj-$(CONFIG_CLK_SUN8I_A83T) += clk_a83t.o --- /dev/null +++ b/drivers/clk/sunxi/clk_a31_apb0.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) Samuel Holland + */ + +#include +#include +#include +#include + +static struct ccu_clk_gate sun6i_apb0_gates[] = { + [0] = GATE(0x028, BIT(0)), + [1] = GATE(0x028, BIT(1)), + [2] = GATE(0x028, BIT(2)), + [3] = GATE(0x028, BIT(3)), + [4] = GATE(0x028, BIT(4)), + [5] = GATE(0x028, BIT(5)), + [6] = GATE(0x028, BIT(6)), + [7] = GATE(0x028, BIT(7)), +}; + +static struct ccu_reset sun6i_apb0_resets[] = { + [0] = RESET(0x0b0, BIT(0)), + [1] = RESET(0x0b0, BIT(1)), + [2] = RESET(0x0b0, BIT(2)), + [3] = RESET(0x0b0, BIT(3)), + [4] = RESET(0x0b0, BIT(4)), + [5] = RESET(0x0b0, BIT(5)), + [6] = RESET(0x0b0, BIT(6)), + [7] = RESET(0x0b0, BIT(7)), +}; + +const struct ccu_desc sun6i_apb0_clk_desc = { + .gates = sun6i_apb0_gates, + .resets = sun6i_apb0_resets, + .num_gates = ARRAY_SIZE(sun6i_apb0_gates), + .num_resets = ARRAY_SIZE(sun6i_apb0_resets), +}; + +static int sun6i_apb0_of_to_plat(struct udevice *dev) +{ + struct ccu_plat *plat = dev_get_plat(dev); + + plat->base = dev_read_addr_ptr(dev->parent); + if (!plat->base) + return -ENOMEM; + + plat->desc = (const struct ccu_desc *)dev_get_driver_data(dev); + if (!plat->desc) + return -EINVAL; + + return 0; +} + +static const struct udevice_id sun6i_apb0_clk_ids[] = { + { .compatible = "allwinner,sun6i-a31-apb0-gates-clk", + .data = (ulong)&sun6i_apb0_clk_desc }, + { .compatible = "allwinner,sun8i-a23-apb0-gates-clk", + .data = (ulong)&sun6i_apb0_clk_desc }, + { } +}; + +U_BOOT_DRIVER(sun6i_apb0_clk) = { + .name = "sun6i_apb0_clk", + .id = UCLASS_CLK, + .of_match = sun6i_apb0_clk_ids, + .of_to_plat = sun6i_apb0_of_to_plat, + .plat_auto = sizeof(struct ccu_plat), + .ops = &sunxi_clk_ops, +}; + +static const struct udevice_id sun6i_apb0_reset_ids[] = { + { .compatible = "allwinner,sun6i-a31-clock-reset", + .data = (ulong)&sun6i_apb0_clk_desc }, + { } +}; + +U_BOOT_DRIVER(sun6i_apb0_reset) = { + .name = "sun6i_apb0_reset", + .id = UCLASS_RESET, + .of_match = sun6i_apb0_reset_ids, + .of_to_plat = sun6i_apb0_of_to_plat, + .plat_auto = sizeof(struct ccu_plat), + .ops = &sunxi_reset_ops, +}; + +static const struct udevice_id sun6i_prcm_mfd_ids[] = { + { .compatible = "allwinner,sun6i-a31-prcm" }, + { .compatible = "allwinner,sun8i-a23-prcm" }, + { } +}; + +U_BOOT_DRIVER(sun6i_prcm_mfd) = { + .name = "sun6i_prcm_mfd", + .id = UCLASS_SIMPLE_BUS, + .of_match = sun6i_prcm_mfd_ids, +}; --- a/include/clk/sunxi.h +++ b/include/clk/sunxi.h @@ -86,5 +86,6 @@ struct ccu_plat { }; extern struct clk_ops sunxi_clk_ops; +extern struct reset_ops sunxi_reset_ops; #endif /* _CLK_SUNXI_H */