From: Torsten Duwe <[email protected]> A driver for Broadcom rescal reset controllers ported from linux/drivers/reset/reset-brcmstb-rescal.c to U-Boot.
Signed-off-by: Torsten Duwe <[email protected]> --- configs/rpi_arm64_defconfig | 1 + drivers/reset/Kconfig | 7 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-brcmstb-rescal.c | 103 +++++++++++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 drivers/reset/reset-brcmstb-rescal.c diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig index 153d7ed301e..38af5029403 100644 --- a/configs/rpi_arm64_defconfig +++ b/configs/rpi_arm64_defconfig @@ -45,6 +45,7 @@ CONFIG_PCI_BRCMSTB=y CONFIG_PINCTRL=y # CONFIG_PINCTRL_GENERIC is not set CONFIG_RESET_BRCMSTB=y +CONFIG_RESET_BRCMSTB_RESCAL=y CONFIG_DM_RNG=y CONFIG_RNG_IPROC200=y # CONFIG_REQUIRE_SERIAL_CONSOLE is not set diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 46ffc103320..b7d2d4b18d5 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -71,6 +71,13 @@ config RESET_BRCMSTB If you wish to use reset resources managed by the Broadcom Reset Controller, say Y here. Otherwise, say N. +config RESET_BRCMSTB_RESCAL + bool "Generic Rescal Reset controller driver for Broadcom" + help + Support rescal reset controller on Broadcom. + If you wish to use reset resources managed by the Broadcom + Reset Controller, say Y here. Otherwise, say N. + 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 ebf3d7425a4..c7a9da3268d 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -14,6 +14,7 @@ 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_BRCMSTB) += reset-brcmstb.o +obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.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-brcmstb-rescal.c b/drivers/reset/reset-brcmstb-rescal.c new file mode 100644 index 00000000000..fc8fcfa8b3f --- /dev/null +++ b/drivers/reset/reset-brcmstb-rescal.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Broadcom STB generic reset controller + * + * Copyright (C) 2024 EPAM Systems + * Moved from linux kernel: + * Copyright (C) 2018-2020 Broadcom + */ + +#include <asm/io.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <errno.h> +#include <linux/bitops.h> +#include <linux/delay.h> +#include <linux/iopoll.h> +#include <log.h> +#include <malloc.h> +#include <reset-uclass.h> + +#define BRCM_RESCAL_START 0x0 +#define BRCM_RESCAL_START_BIT BIT(0) +#define BRCM_RESCAL_CTRL 0x4 +#define BRCM_RESCAL_STATUS 0x8 +#define BRCM_RESCAL_STATUS_BIT BIT(0) + +struct brcm_rescal_reset { + void __iomem *base; +}; + +/* Also doubles a deassert */ +static int brcm_rescal_reset_set(struct reset_ctl *rst) +{ + struct brcm_rescal_reset *data = dev_get_priv(rst->dev); + void __iomem *base = data->base; + u32 reg; + int ret; + + reg = readl(base + BRCM_RESCAL_START); + writel(reg | BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START); + reg = readl(base + BRCM_RESCAL_START); + if (!(reg & BRCM_RESCAL_START_BIT)) { + dev_err(rst->dev, "failed to start SATA/PCIe rescal\n"); + return -EIO; + } + + ret = readl_poll_timeout(base + BRCM_RESCAL_STATUS, reg, + (reg & BRCM_RESCAL_STATUS_BIT), 100); + if (ret) { + dev_err(rst->dev, "time out on SATA/PCIe rescal\n"); + return ret; + } + + reg = readl(base + BRCM_RESCAL_START); + writel(reg & ~BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START); + + dev_dbg(rst->dev, "SATA/PCIe rescal success\n"); + return 0; +} + +/* A dummy function - deassert/reset does all the work */ +static int brcm_rescal_reset_assert(struct reset_ctl *rst) +{ + return 0; +} + +static int brcm_rescal_reset_xlate(struct reset_ctl *reset_ctl, + struct ofnode_phandle_args *args) +{ + /* This is needed if #reset-cells == 0. */ + return 0; +} + +static const struct reset_ops brcm_rescal_reset_ops = { + .rst_deassert = brcm_rescal_reset_set, + .rst_assert = brcm_rescal_reset_assert, + .of_xlate = brcm_rescal_reset_xlate, +}; + +static int brcm_rescal_reset_probe(struct udevice *dev) +{ + struct brcm_rescal_reset *data = dev_get_priv(dev); + + data->base = dev_remap_addr(dev); + if (!data->base) + return -EINVAL; + + return 0; +} + +static const struct udevice_id brcm_rescal_reset_of_match[] = { + {.compatible = "brcm,bcm7216-pcie-sata-rescal"}, + {}, +}; + +U_BOOT_DRIVER(brcmstb_reset_rescal) = { + .name = "brcmstb-reset-rescal", + .id = UCLASS_RESET, + .of_match = brcm_rescal_reset_of_match, + .ops = &brcm_rescal_reset_ops, + .probe = brcm_rescal_reset_probe, + .priv_auto = sizeof(struct brcm_rescal_reset), +}; -- 2.51.0

