diff --git a/drivers/clk/clk_bl808.c b/drivers/clk/clk_bl808.c index 149cb638195..ad507d48dc9 100644 --- a/drivers/clk/clk_bl808.c +++ b/drivers/clk/clk_bl808.c @@ -14,6 +14,7 @@ #include #include #include +#include #define PRNTS(...) (const u8[]) { __VA_ARGS__ } @@ -388,9 +389,16 @@ static const struct bl808_clk_data bl808_mm_glb_clks[] = { }, }; +static const struct bl808_reset_data bl808_mm_glb_resets[] = { + [RST_MM_CPU] = { MM_GLB_MM_SW_SYS_RESET_OFFSET, + MM_GLB_REG_CTRL_MMCPU0_RESET_POS }, +}; + static const struct bl808_clk_desc bl808_mm_glb_clk_desc = { .clks = bl808_mm_glb_clks, + .resets = bl808_mm_glb_resets, .num_clks = ARRAY_SIZE(bl808_mm_glb_clks), + .num_resets = ARRAY_SIZE(bl808_mm_glb_resets), }; static const struct bl808_clk_data bl808_pds_clks[] = { @@ -738,6 +746,18 @@ struct clk_ops bl808_clk_ops = { .dump = bl808_clk_dump, }; +extern U_BOOT_DRIVER(bl808_reset); + +static int bl808_clk_bind(struct udevice *dev) +{ + if (IS_ENABLED(CONFIG_RESET_BL808)) { + device_bind(dev, DM_DRIVER_REF(bl808_reset), "reset", + dev_get_plat(dev), dev_ofnode(dev), NULL); + } + + return 0; +} + static int bl808_clk_probe(struct udevice *dev) { const struct bl808_clk_plat *plat = dev_get_plat(dev); @@ -771,6 +791,7 @@ U_BOOT_DRIVER(bl808_clk) = { .name = "bl808_clk", .id = UCLASS_CLK, .of_match = bl808_clk_ids, + .bind = bl808_clk_bind, .probe = bl808_clk_probe, .of_to_plat = bl808_clk_of_to_plat, .plat_auto = sizeof(struct bl808_clk_plat), diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index e4039d74744..c17af75e5b0 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -63,6 +63,12 @@ config RESET_BCM6345 help Support reset controller on BCM6345. +config RESET_BL808 + bool "Reset controller driver for BL808" + depends on DM_RESET && TARGET_BOUFFALO_BL808 + help + This enables reset controller support for the Bouffalo Lab BL808 SoC. + config RESET_UNIPHIER bool "Reset controller driver for UniPhier SoCs" depends on ARCH_UNIPHIER diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 6c8b45ecbab..44d8e092e54 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o +obj-$(CONFIG_RESET_BL808) += reset-bl808.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o diff --git a/drivers/reset/reset-bl808.c b/drivers/reset/reset-bl808.c new file mode 100644 index 00000000000..e638cb81abd --- /dev/null +++ b/drivers/reset/reset-bl808.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct bl808_reset_data * +bl808_reset_get_data(const struct bl808_clk_plat *plat, + const struct reset_ctl *reset_ctl) +{ + const struct bl808_clk_desc *desc = plat->desc; + + if (reset_ctl->id >= desc->num_resets) + return NULL; + + return &desc->resets[reset_ctl->id]; +} + +static int bl808_reset_request(struct reset_ctl *reset_ctl) +{ + const struct bl808_clk_plat *plat = dev_get_plat(reset_ctl->dev); + + return bl808_reset_get_data(plat, reset_ctl) ? 0 : -EINVAL; +} + +static int bl808_reset_set(struct reset_ctl *reset_ctl, bool assert) +{ + const struct bl808_clk_plat *plat = dev_get_plat(reset_ctl->dev); + const struct bl808_reset_data *data = bl808_reset_get_data(plat, reset_ctl); + u32 mask = BIT(data->bit); + + clrsetbits_le32(plat->base + data->reg, mask, assert ? mask : 0); + + return 0; +} + +static int bl808_reset_assert(struct reset_ctl *reset_ctl) +{ + return bl808_reset_set(reset_ctl, true); +} + +static int bl808_reset_deassert(struct reset_ctl *reset_ctl) +{ + return bl808_reset_set(reset_ctl, false); +} + +static int bl808_reset_status(struct reset_ctl *reset_ctl) +{ + const struct bl808_clk_plat *plat = dev_get_plat(reset_ctl->dev); + const struct bl808_reset_data *data = bl808_reset_get_data(plat, reset_ctl); + u32 mask = BIT(data->bit); + + return !!(readl(plat->base + data->reg) & mask); +} + +static const struct reset_ops bl808_reset_ops = { + .request = bl808_reset_request, + .rst_assert = bl808_reset_assert, + .rst_deassert = bl808_reset_deassert, + .rst_status = bl808_reset_status, +}; + +U_BOOT_DRIVER(bl808_reset) = { + .name = "bl808_reset", + .id = UCLASS_RESET, + .ops = &bl808_reset_ops, +}; diff --git a/include/clk/bl808.h b/include/clk/bl808.h index 49c9b11fac5..348ae8a3ba0 100644 --- a/include/clk/bl808.h +++ b/include/clk/bl808.h @@ -16,9 +16,16 @@ struct bl808_clk_data { u16 fixed_div; }; +struct bl808_reset_data { + u16 reg; + u8 bit; +}; + struct bl808_clk_desc { const struct bl808_clk_data *clks; + const struct bl808_reset_data *resets; u8 num_clks; + u8 num_resets; }; struct bl808_clk_plat { diff --git a/include/dt-bindings/reset/bl808-glb.h b/include/dt-bindings/reset/bl808-glb.h new file mode 100644 index 00000000000..815d044e73a --- /dev/null +++ b/include/dt-bindings/reset/bl808-glb.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */ + +#ifndef _DT_BINDINGS_RESET_BL808_GLB_H_ +#define _DT_BINDINGS_RESET_BL808_GLB_H_ + +#define RST_USB 0 + +#endif /* _DT_BINDINGS_RESET_BL808_GLB_H_ */ diff --git a/include/dt-bindings/reset/bl808-mm-glb.h b/include/dt-bindings/reset/bl808-mm-glb.h new file mode 100644 index 00000000000..9bdc77d5657 --- /dev/null +++ b/include/dt-bindings/reset/bl808-mm-glb.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */ + +#ifndef _DT_BINDINGS_RESET_BL808_MM_GLB_H_ +#define _DT_BINDINGS_RESET_BL808_MM_GLB_H_ + +#define RST_MM_CPU 0 + +#endif /* _DT_BINDINGS_RESET_BL808_MM_GLB_H_ */