On Mon, May 31, 2021 at 09:38:19AM +0200, Ahmad Fatoum wrote: > The StarFive SoC has a single reset controller, which seems to control > reset of all clocks and peripherals. It differs from the ones supported > by the Linux reset-simple driver in that it has a dedicated status > registers that needs to be polled to verify the reset has completed. > > Also special is that most resets (> 70) are synchronous. As the reset > status poll would just time out without the clock, have the reset > controller enable the clock as part of the reset. OS can decide later, > which clocks to disable again. > > Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> > --- > arch/riscv/Kconfig.socs | 1 + > drivers/reset/Kconfig | 6 + > drivers/reset/Makefile | 1 + > drivers/reset/reset-starfive-vic.c | 204 ++++++++++++++++++ > .../reset-controller/starfive-jh7100.h | 126 +++++++++++ > include/soc/starfive/rstgen.h | 41 ++++ > 6 files changed, 379 insertions(+) > create mode 100644 drivers/reset/reset-starfive-vic.c > create mode 100644 include/dt-bindings/reset-controller/starfive-jh7100.h > create mode 100644 include/soc/starfive/rstgen.h > > diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs > index 3e4cd3cdad59..d2b4a955d1c4 100644 > --- a/arch/riscv/Kconfig.socs > +++ b/arch/riscv/Kconfig.socs > @@ -52,6 +52,7 @@ endif > config SOC_STARFIVE > bool "StarFive SoCs" > select CLINT_TIMER > + select ARCH_HAS_RESET_CONTROLLER > help > This enables support for SiFive SoC platform hardware. > > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig > index 316ece9e7176..9429f107bb67 100644 > --- a/drivers/reset/Kconfig > +++ b/drivers/reset/Kconfig > @@ -27,4 +27,10 @@ config RESET_STM32 > help > This enables the reset controller driver for STM32MP and STM32 MCUs. > > +config RESET_STARFIVE > + bool "StarFive Controller Driver" if COMPILE_TEST > + default SOC_STARFIVE > + help > + This enables the reset controller driver for the StarFive JH7100. > + > endif > diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile > index 8460c4b154f5..ce494baae58e 100644 > --- a/drivers/reset/Makefile > +++ b/drivers/reset/Makefile > @@ -2,3 +2,4 @@ obj-$(CONFIG_RESET_CONTROLLER) += core.o > obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o > obj-$(CONFIG_RESET_IMX7) += reset-imx7.o > obj-$(CONFIG_RESET_STM32) += reset-stm32.o > +obj-$(CONFIG_RESET_STARFIVE) += reset-starfive-vic.o > diff --git a/drivers/reset/reset-starfive-vic.c b/drivers/reset/reset-starfive-vic.c > new file mode 100644 > index 000000000000..d6a8d0138ab2 > --- /dev/null > +++ b/drivers/reset/reset-starfive-vic.c > @@ -0,0 +1,204 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (c) 2021 Ahmad Fatoum, Pengutronix > + * > + * StarFive Reset Controller driver > + */ > +#define pr_fmt(fmt) "reset-starfive: " fmt > + > +#include <common.h> > +#include <init.h> > +#include <linux/clk.h> > +#include <linux/err.h> > +#include <linux/reset-controller.h> > +#include <soc/starfive/rstgen.h> > +#include <dt-bindings/reset-controller/starfive-jh7100.h> > +#include <dt-bindings/clock/starfive-jh7100.h> > + > +struct starfive_rstgen { > + void __iomem *base; > + struct reset_controller_dev rcdev; > + const struct starfive_rstgen_ops *ops; > + struct device_node *clknp; > + const int *sync_resets; > +}; > + > +static struct starfive_rstgen *to_starfive_rstgen(struct reset_controller_dev *rcdev) > +{ > + return container_of(rcdev, struct starfive_rstgen, rcdev); > +} > + > +static const int jh7110_rstgen_sync_resets[RSTN_END] = { > + [RSTN_SGDMA2P_AHB] = CLK_SGDMA2P_AHB, > + [RSTN_SGDMA2P_AXI] = CLK_SGDMA2P_AXI, > + [RSTN_DMA2PNOC_AXI] = CLK_DMA2PNOC_AXI, > + [RSTN_DLA_AXI] = CLK_DLA_AXI, > + [RSTN_DLANOC_AXI] = CLK_DLANOC_AXI, > + [RSTN_DLA_APB] = CLK_DLA_APB, > + [RSTN_VDECBRG_MAIN] = CLK_VDECBRG_MAIN, > + [RSTN_VDEC_AXI] = CLK_VDEC_AXI, > + [RSTN_VDEC_BCLK] = CLK_VDEC_BCLK, > + [RSTN_VDEC_CCLK] = CLK_VDEC_CCLK, > + [RSTN_VDEC_APB] = CLK_VDEC_APB, > + [RSTN_JPEG_AXI] = CLK_JPEG_AXI, > + [RSTN_JPEG_CCLK] = CLK_JPEG_CCLK, > + [RSTN_JPEG_APB] = CLK_JPEG_APB, > + [RSTN_JPCGC300_MAIN] = CLK_JPCGC300_MAIN, > + [RSTN_GC300_2X] = CLK_GC300_2X, > + [RSTN_GC300_AXI] = CLK_GC300_AXI, > + [RSTN_GC300_AHB] = CLK_GC300_AHB, > + [RSTN_VENC_AXI] = CLK_VENC_AXI, > + [RSTN_VENCBRG_MAIN] = CLK_VENCBRG_MAIN, > + [RSTN_VENC_BCLK] = CLK_VENC_BCLK, > + [RSTN_VENC_CCLK] = CLK_VENC_CCLK, > + [RSTN_VENC_APB] = CLK_VENC_APB, > + [RSTN_DDRPHY_APB] = CLK_DDRPHY_APB, > + [RSTN_USB_AXI] = CLK_USB_AXI, > + [RSTN_SGDMA1P_AXI] = CLK_SGDMA1P_AXI, > + [RSTN_DMA1P_AXI] = CLK_DMA1P_AXI, > + [RSTN_NNE_AHB] = CLK_NNE_AHB, > + [RSTN_NNE_AXI] = CLK_NNE_AXI, > + [RSTN_NNENOC_AXI] = CLK_NNENOC_AXI, > + [RSTN_DLASLV_AXI] = CLK_DLASLV_AXI, > + [RSTN_VOUT_SRC] = CLK_VOUT_SRC, > + [RSTN_DISP_AXI] = CLK_DISP_AXI, > + [RSTN_DISPNOC_AXI] = CLK_DISPNOC_AXI, > + [RSTN_SDIO0_AHB] = CLK_SDIO0_AHB, > + [RSTN_SDIO1_AHB] = CLK_SDIO1_AHB, > + [RSTN_GMAC_AHB] = CLK_GMAC_AHB, > + [RSTN_SPI2AHB_AHB] = CLK_SPI2AHB_AHB, > + [RSTN_SPI2AHB_CORE] = CLK_SPI2AHB_CORE, > + [RSTN_EZMASTER_AHB] = CLK_EZMASTER_AHB, > + [RSTN_SEC_AHB] = CLK_SEC_AHB, > + [RSTN_AES] = CLK_AES, > + [RSTN_PKA] = CLK_PKA, > + [RSTN_SHA] = CLK_SHA, > + [RSTN_TRNG_APB] = CLK_TRNG_APB, > + [RSTN_OTP_APB] = CLK_OTP_APB, > + [RSTN_UART0_APB] = CLK_UART0_APB, > + [RSTN_UART0_CORE] = CLK_UART0_CORE, > + [RSTN_UART1_APB] = CLK_UART1_APB, > + [RSTN_UART1_CORE] = CLK_UART1_CORE, > + [RSTN_SPI0_APB] = CLK_SPI0_APB, > + [RSTN_SPI0_CORE] = CLK_SPI0_CORE, > + [RSTN_SPI1_APB] = CLK_SPI1_APB, > + [RSTN_SPI1_CORE] = CLK_SPI1_CORE, > + [RSTN_I2C0_APB] = CLK_I2C0_APB, > + [RSTN_I2C0_CORE] = CLK_I2C0_CORE, > + [RSTN_I2C1_APB] = CLK_I2C1_APB, > + [RSTN_I2C1_CORE] = CLK_I2C1_CORE, > + [RSTN_GPIO_APB] = CLK_GPIO_APB, > + [RSTN_UART2_APB] = CLK_UART2_APB, > + [RSTN_UART2_CORE] = CLK_UART2_CORE, > + [RSTN_UART3_APB] = CLK_UART3_APB, > + [RSTN_UART3_CORE] = CLK_UART3_CORE, > + [RSTN_SPI2_APB] = CLK_SPI2_APB, > + [RSTN_SPI2_CORE] = CLK_SPI2_CORE, > + [RSTN_SPI3_APB] = CLK_SPI3_APB, > + [RSTN_SPI3_CORE] = CLK_SPI3_CORE, > + [RSTN_I2C2_APB] = CLK_I2C2_APB, > + [RSTN_I2C2_CORE] = CLK_I2C2_CORE, > + [RSTN_I2C3_APB] = CLK_I2C3_APB, > + [RSTN_I2C3_CORE] = CLK_I2C3_CORE, > + [RSTN_WDTIMER_APB] = CLK_WDTIMER_APB, > + [RSTN_WDT] = CLK_WDT_CORE, > + [RSTN_VP6INTC_APB] = CLK_VP6INTC_APB, > + [RSTN_TEMP_APB] = CLK_TEMP_APB, > + [RSTN_TEMP_SENSE] = CLK_TEMP_SENSE, > +}; > + > +static int starfive_reset_clk_enable(struct starfive_rstgen *priv, unsigned id) > +{ > + struct of_phandle_args clkspec = { > + .np = priv->clknp, > + .args_count = 1, > + }; > + > + if (!priv->sync_resets || !priv->sync_resets[id]) > + return 0; > + > + clkspec.args[0] = priv->sync_resets[id]; > + > + pr_debug("synchronous reset=%u clk=%u\n", id, priv->sync_resets[id]); > + > + return clk_enable(of_clk_get_from_provider(&clkspec)); This clock is enabled twice per reset cycle and never disabled. It should be balanced or enabled only once. Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox