git: f240b19abf0b - stable/13 - sifive_prci: Add reset support for the FU540 and FU740

Jessica Clarke jrtc27 at FreeBSD.org
Tue Sep 7 12:09:54 UTC 2021


The branch stable/13 has been updated by jrtc27:

URL: https://cgit.FreeBSD.org/src/commit/?id=f240b19abf0bceef6248e6426d0a2f20792fb64a

commit f240b19abf0bceef6248e6426d0a2f20792fb64a
Author:     Jessica Clarke <jrtc27 at FreeBSD.org>
AuthorDate: 2021-08-07 18:27:29 +0000
Commit:     Jessica Clarke <jrtc27 at FreeBSD.org>
CommitDate: 2021-09-07 12:06:50 +0000

    sifive_prci: Add reset support for the FU540 and FU740
    
    This is needed for FU740 PCIe support. Whilst we don't need the FU540's
    resets they are also defined for completeness.
    
    Reviewed by:    manu
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D31024
    
    (cherry picked from commit 8e7e0690ecd79e8adc9182d486c05748bd97d26d)
---
 sys/riscv/conf/GENERIC         |  1 +
 sys/riscv/sifive/sifive_prci.c | 57 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/sys/riscv/conf/GENERIC b/sys/riscv/conf/GENERIC
index 805ca47a637e..f2194cb5c8e8 100644
--- a/sys/riscv/conf/GENERIC
+++ b/sys/riscv/conf/GENERIC
@@ -82,6 +82,7 @@ device		rcons
 # EXT_RESOURCES pseudo devices
 options 	EXT_RESOURCES
 device		clk
+device		hwreset
 device		syscon
 device		syscon_power
 device		riscv_syscon
diff --git a/sys/riscv/sifive/sifive_prci.c b/sys/riscv/sifive/sifive_prci.c
index 36f2f6705f7e..fee67bb153ac 100644
--- a/sys/riscv/sifive/sifive_prci.c
+++ b/sys/riscv/sifive/sifive_prci.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/openfirm.h>
 
 #include "clkdev_if.h"
+#include "hwreset_if.h"
 
 static struct resource_spec prci_spec[] = {
 	{ SYS_RES_MEMORY, 0, RF_ACTIVE },
@@ -69,6 +70,8 @@ struct prci_softc {
 	struct resource		*res;
 	bus_space_tag_t		bst;
 	bus_space_handle_t	bsh;
+
+	int			nresets;
 };
 
 struct prci_clk_pll_sc {
@@ -94,6 +97,9 @@ struct prci_clk_div_sc {
 #define	PRCI_PLL_DIVQ_MASK		0x38000
 #define	PRCI_PLL_DIVQ_SHIFT		15
 
+/* Called devicesresetreg on the FU540 */
+#define	PRCI_DEVICES_RESET_N		0x28
+
 #define	PRCI_READ(_sc, _reg)		\
     bus_space_read_4((_sc)->bst, (_sc)->bsh, (_reg))
 #define	PRCI_WRITE(_sc, _reg, _val)	\
@@ -155,6 +161,7 @@ struct prci_config {
 	struct prci_div_def	*div_clks;
 	struct prci_gate_def	*gate_clks;
 	struct clk_fixed_def	*tlclk_def;
+	int			nresets;
 };
 
 /* FU540 clock numbers */
@@ -191,6 +198,7 @@ static struct clk_fixed_def fu540_tlclk_def = {
 struct prci_config fu540_prci_config = {
 	.pll_clks = fu540_pll_clks,
 	.tlclk_def = &fu540_tlclk_def,
+	.nresets = 6,
 };
 
 /* FU740 clock numbers */
@@ -254,6 +262,7 @@ struct prci_config fu740_prci_config = {
 	.div_clks = fu740_div_clks,
 	.gate_clks = fu740_gate_clks,
 	.tlclk_def = &fu740_tlclk_def,
+	.nresets = 7,
 };
 
 static struct ofw_compat_data compat_data[] = {
@@ -547,6 +556,8 @@ prci_attach(device_t dev)
 	if (error)
 		panic("Couldn't finalise clock domain");
 
+	sc->nresets = cfg->nresets;
+
 	return (0);
 
 fail1:
@@ -616,6 +627,48 @@ prci_device_unlock(device_t dev)
 	PRCI_UNLOCK(sc);
 }
 
+static int
+prci_reset_assert(device_t dev, intptr_t id, bool reset)
+{
+	struct prci_softc *sc;
+	uint32_t reg;
+
+	sc = device_get_softc(dev);
+
+	if (id >= sc->nresets)
+		return (ENXIO);
+
+	PRCI_LOCK(sc);
+	reg = PRCI_READ(sc, PRCI_DEVICES_RESET_N);
+	if (reset)
+		reg &= ~(1u << id);
+	else
+		reg |= (1u << id);
+	PRCI_WRITE(sc, PRCI_DEVICES_RESET_N, reg);
+	PRCI_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+prci_reset_is_asserted(device_t dev, intptr_t id, bool *reset)
+{
+	struct prci_softc *sc;
+	uint32_t reg;
+
+	sc = device_get_softc(dev);
+
+	if (id >= sc->nresets)
+		return (ENXIO);
+
+	PRCI_LOCK(sc);
+	reg = PRCI_READ(sc, PRCI_DEVICES_RESET_N);
+	*reset = (reg & (1u << id)) == 0;
+	PRCI_UNLOCK(sc);
+
+	return (0);
+}
+
 static device_method_t prci_methods[] = {
 	DEVMETHOD(device_probe,		prci_probe),
 	DEVMETHOD(device_attach,	prci_attach),
@@ -627,6 +680,10 @@ static device_method_t prci_methods[] = {
 	DEVMETHOD(clkdev_device_lock,	prci_device_lock),
 	DEVMETHOD(clkdev_device_unlock,	prci_device_unlock),
 
+	/* Reset interface */
+	DEVMETHOD(hwreset_assert,	prci_reset_assert),
+	DEVMETHOD(hwreset_is_asserted,	prci_reset_is_asserted),
+
 	DEVMETHOD_END
 };
 


More information about the dev-commits-src-all mailing list