[PATCH 18/20] reset: add StarFive reset controller driver

Sascha Hauer sha at pengutronix.de
Mon Jun 7 01:00:47 PDT 2021


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 at pengutronix.de>
> ---
>  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 |



More information about the barebox mailing list