mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support
@ 2021-05-31  7:38 Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 01/20] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
                   ` (19 more replies)
  0 siblings, 20 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox

This series doesn't yet add BeagleV support, but it lays the groundwork:
  - Some drivers are adapted for 64-bit operation
  - The incoherent interconnect on the JH7100 is handled
    (Will be coherent for JH7110 in normal BeagleV)
  - Some basic drivers are added

Notably missing are GPIO, pinctrl and board support. I still need to
clean those up, so they will follow later.

Ahmad Fatoum (20):
  RISC-V: socs: add Kconfig entry for StarFive JH7100
  net: designware: add support for IP integrated into StarFive SoC
  mfd: add TI TPS65086 PMIC restart driver
  mtd: spi-nor: cadence: fix 64-bit issues
  nvmem: add StarFive OTP support
  RISC-V: dma: support multiple dma_alloc_coherent backends
  RISC-V: support incoherent I-Cache
  soc: add support for StarFive JH7100 incoherent interconnect
  soc: sifive: l2_cache: enable maximum available cache ways
  net: designware: fix 64-bit incompatibilities
  dma: support marking SRAM for coherent DMA use
  mci: allocate DMA-able memory
  mci: allocate sector_buf on demand
  dma: allocate 32-byte aligned buffers by default
  mci: dw_mmc: enable use on 64-bit CPUs
  mci: dw_mmc: match against generic "snps,dw-mshc" compatible
  clk: add initial StarFive clock support
  reset: add StarFive reset controller driver
  watchdog: add StarFive watchdog driver
  hw_random: add driver for RNG on StarFive SoC

 arch/riscv/Kconfig.socs                       |  23 ++
 arch/riscv/boot/uncompress.c                  |   2 +
 arch/riscv/cpu/Makefile                       |   2 +
 arch/riscv/cpu/cache.c                        |  22 ++
 arch/riscv/cpu/core.c                         |   7 +
 arch/riscv/cpu/dma.c                          |  69 ++++
 arch/riscv/include/asm/barebox-riscv.h        |   2 +
 arch/riscv/include/asm/barrier.h              |  27 ++
 arch/riscv/include/asm/cache.h                |  17 +
 arch/riscv/include/asm/dma.h                  |  42 +-
 arch/riscv/include/asm/io.h                   |  10 +
 arch/riscv/lib/reloc.c                        |   8 +
 arch/riscv/lib/setupc.S                       |   2 +
 common/Kconfig                                |   4 +
 common/Makefile                               |   3 +-
 drivers/Makefile                              |   2 +-
 drivers/clk/Makefile                          |   1 +
 drivers/clk/starfive/Makefile                 |   3 +
 drivers/clk/starfive/clk.h                    |  64 +++
 drivers/clk/starfive/jh7100-clkgen.c          | 363 ++++++++++++++++++
 drivers/dma/Kconfig                           |   6 +
 drivers/dma/Makefile                          |   1 +
 drivers/dma/coherent-pool.c                   | 120 ++++++
 drivers/hw_random/Kconfig                     |   7 +
 drivers/hw_random/Makefile                    |   1 +
 drivers/hw_random/starfive-vic-rng.c          | 200 ++++++++++
 drivers/mci/dw_mmc.c                          |  28 +-
 drivers/mci/mci-core.c                        |  15 +-
 drivers/mfd/Kconfig                           |  10 +
 drivers/mfd/Makefile                          |   2 +
 drivers/mfd/core.c                            |  25 ++
 drivers/mfd/tps65086.c                        |  76 ++++
 drivers/mtd/spi-nor/cadence-quadspi.c         |  10 +-
 drivers/net/Kconfig                           |   8 +
 drivers/net/Makefile                          |   1 +
 drivers/net/designware.c                      |  35 +-
 drivers/net/designware.h                      |   7 +-
 drivers/net/designware_starfive.c             | 109 ++++++
 drivers/nvmem/Kconfig                         |   8 +
 drivers/nvmem/Makefile                        |   2 +
 drivers/nvmem/starfive-otp.c                  | 227 +++++++++++
 drivers/power/reset/Kconfig                   |   6 +
 drivers/power/reset/Makefile                  |   1 +
 drivers/power/reset/tps65086-restart.c        |  55 +++
 drivers/reset/Kconfig                         |   6 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-starfive-vic.c            | 204 ++++++++++
 drivers/soc/Makefile                          |   4 +
 drivers/soc/sifive/Makefile                   |   1 +
 drivers/soc/sifive/sifive_l2_cache.c          | 158 ++++++++
 drivers/watchdog/Kconfig                      |   7 +
 drivers/watchdog/Makefile                     |   1 +
 drivers/watchdog/starfive_wdt.c               |  97 +++++
 include/dma.h                                 |   7 +-
 include/dt-bindings/clock/starfive-jh7100.h   | 203 ++++++++++
 .../reset-controller/starfive-jh7100.h        | 126 ++++++
 include/linux/mfd/core.h                      |  26 ++
 include/linux/mfd/tps65086.h                  |  98 +++++
 include/soc/starfive/rstgen.h                 |  41 ++
 include/soc/starfive/sysmain.h                |  15 +
 60 files changed, 2551 insertions(+), 77 deletions(-)
 create mode 100644 arch/riscv/cpu/cache.c
 create mode 100644 arch/riscv/cpu/dma.c
 create mode 100644 arch/riscv/include/asm/barrier.h
 create mode 100644 arch/riscv/include/asm/cache.h
 create mode 100644 drivers/clk/starfive/Makefile
 create mode 100644 drivers/clk/starfive/clk.h
 create mode 100644 drivers/clk/starfive/jh7100-clkgen.c
 create mode 100644 drivers/dma/coherent-pool.c
 create mode 100644 drivers/hw_random/starfive-vic-rng.c
 create mode 100644 drivers/mfd/core.c
 create mode 100644 drivers/mfd/tps65086.c
 create mode 100644 drivers/net/designware_starfive.c
 create mode 100644 drivers/nvmem/starfive-otp.c
 create mode 100644 drivers/power/reset/tps65086-restart.c
 create mode 100644 drivers/reset/reset-starfive-vic.c
 create mode 100644 drivers/soc/Makefile
 create mode 100644 drivers/soc/sifive/Makefile
 create mode 100644 drivers/soc/sifive/sifive_l2_cache.c
 create mode 100644 drivers/watchdog/starfive_wdt.c
 create mode 100644 include/dt-bindings/clock/starfive-jh7100.h
 create mode 100644 include/dt-bindings/reset-controller/starfive-jh7100.h
 create mode 100644 include/linux/mfd/core.h
 create mode 100644 include/linux/mfd/tps65086.h
 create mode 100644 include/soc/starfive/rstgen.h
 create mode 100644 include/soc/starfive/sysmain.h

-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 01/20] RISC-V: socs: add Kconfig entry for StarFive JH7100
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 02/20] net: designware: add support for IP integrated into StarFive SoC Ahmad Fatoum
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The JH7100 is the SoC in the pre-production BeagleV. The normal one
will have a JH7110. Add Kconfig symbols, so newly introduced symbols
can depend on them.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/Kconfig.socs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 67d19caeb3b0..9c82a36fe4bd 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -42,4 +42,19 @@ config BOARD_HIFIVE
 
 endif
 
+config SOC_STARFIVE
+	bool "StarFive SoCs"
+	select CLINT_TIMER
+	help
+	  This enables support for SiFive SoC platform hardware.
+
+if SOC_STARFIVE
+
+config SOC_STARFIVE_JH7100
+	bool
+	select SOC_SIFIVE
+
+endif
+
+
 endmenu
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 02/20] net: designware: add support for IP integrated into StarFive SoC
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 01/20] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 03/20] mfd: add TI TPS65086 PMIC restart driver Ahmad Fatoum
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The Designware MAC on the StarFive jh7100 needs some special speed
configuration. Match against a new starfive,stmmac compatible that
describes that.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/net/Kconfig               |   8 +++
 drivers/net/Makefile              |   1 +
 drivers/net/designware.c          |   7 +-
 drivers/net/designware.h          |   1 +
 drivers/net/designware_starfive.c | 109 ++++++++++++++++++++++++++++++
 include/soc/starfive/sysmain.h    |  15 ++++
 6 files changed, 138 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/designware_starfive.c
 create mode 100644 include/soc/starfive/sysmain.h

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 0d55ea7a3b60..ed018dbf9a67 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -82,6 +82,14 @@ config DRIVER_NET_DESIGNWARE_SOCFPGA
 	  This option enables support for the Synopsys
 	  Designware Core Univesal MAC 10M/100M/1G ethernet IP on SoCFPGA.
 
+config DRIVER_NET_DESIGNWARE_STARFIVE
+	bool "Designware Universal MAC ethernet driver for StarFive platforms"
+	depends on SOC_STARFIVE || COMPILE_TEST
+	select MFD_SYSCON
+	help
+	  This option enables support for the Synopsys
+	  Designware Core Univesal MAC 10M/100M/1G ethernet IP on StarFive.
+
 endif
 
 config DRIVER_NET_DESIGNWARE_EQOS
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 656d45a868a5..0ce310de05c2 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_DRIVER_NET_DAVINCI_EMAC)	+= davinci_emac.o
 obj-$(CONFIG_DRIVER_NET_DESIGNWARE)	+= designware.o
 obj-$(CONFIG_DRIVER_NET_DESIGNWARE_GENERIC) += designware_generic.o
 obj-$(CONFIG_DRIVER_NET_DESIGNWARE_SOCFPGA) += designware_socfpga.o
+obj-$(CONFIG_DRIVER_NET_DESIGNWARE_STARFIVE) += designware_starfive.o
 obj-$(CONFIG_DRIVER_NET_DESIGNWARE_EQOS) += designware_eqos.o
 obj-$(CONFIG_DRIVER_NET_DESIGNWARE_STM32) += designware_stm32.o
 obj-$(CONFIG_DRIVER_NET_DESIGNWARE_TEGRA186) += designware_tegra186.o
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 0ee6d3d78ac7..e815d74ce9b8 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -457,11 +457,12 @@ struct dw_eth_dev *dwc_drv_probe(struct device_d *dev)
 	if (ret)
 		return ERR_PTR(ret);
 
-	if (drvdata && drvdata->enh_desc)
+	if (drvdata) {
 		priv->enh_desc = drvdata->enh_desc;
-	else
+		priv->fix_mac_speed = drvdata->fix_mac_speed;
+	} else {
 		dev_warn(dev, "No drvdata specified\n");
-
+	}
 
 	if (pdata) {
 		priv->phy_addr = pdata->phy_addr;
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index 0a6a6bf1a497..ef3705b1e387 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -35,6 +35,7 @@ struct dw_eth_dev {
 
 struct dw_eth_drvdata {
 	bool enh_desc;
+	void (*fix_mac_speed)(int speed);
 	void *priv;
 };
 
diff --git a/drivers/net/designware_starfive.c b/drivers/net/designware_starfive.c
new file mode 100644
index 000000000000..e7e3fe5fb364
--- /dev/null
+++ b/drivers/net/designware_starfive.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <init.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+#include <mfd/syscon.h>
+#include <soc/starfive/sysmain.h>
+#include "designware.h"
+
+/*
+ * GMAC_GTXCLK
+ * bit         name                 access  default         description
+ * [31]        _gmac_gtxclk enable  RW      0x0             "1:enable; 0:disable"
+ * [30]        reserved             -       0x0             reserved
+ * [29:8]      reserved             -       0x0             reserved
+ * [7:0]       gmac_gtxclk ratio    RW      0x4             divider value
+ *
+ * 1000M: gtxclk@125M => 500/125 = 0x4
+ * 100M:  gtxclk@25M  => 500/25  = 0x14
+ * 10M:   gtxclk@2.5M => 500/2.5 = 0xc8
+ */
+
+#define CLKGEN_BASE                    0x11800000
+#define CLKGEN_GMAC_GTXCLK_OFFSET      0x1EC
+#define CLKGEN_GMAC_GTXCLK_ADDR        (CLKGEN_BASE + CLKGEN_GMAC_GTXCLK_OFFSET)
+
+
+#define CLKGEN_125M_DIV                0x4
+#define CLKGEN_25M_DIV                 0x14
+#define CLKGEN_2_5M_DIV                0xc8
+
+static void dwmac_fixed_speed(int speed)
+{
+	/* TODO: move this into clk driver */
+	void __iomem *addr = IOMEM(CLKGEN_GMAC_GTXCLK_ADDR);
+	u32 value;
+
+	value = readl(addr) & (~0x000000FF);
+
+	switch (speed) {
+	case SPEED_1000: value |= CLKGEN_125M_DIV; break;
+	case SPEED_100:  value |= CLKGEN_25M_DIV;  break;
+	case SPEED_10:   value |= CLKGEN_2_5M_DIV; break;
+	default: return;
+	}
+
+	writel(value, addr);
+}
+
+static struct dw_eth_drvdata starfive_drvdata = {
+	.enh_desc = 1,
+	.fix_mac_speed = dwmac_fixed_speed,
+};
+
+static int starfive_dwc_ether_probe(struct device_d *dev)
+{
+	struct dw_eth_dev *dwc;
+	struct regmap *regmap;
+	int ret;
+	struct clk_bulk_data clks[] = {
+		{ .id = "ptp_ref" },
+		{ .id = "tx" },
+	};
+
+	regmap = syscon_regmap_lookup_by_phandle(dev->device_node, "starfive,sysmain");
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "Could not get starfive,sysmain node\n");
+		return PTR_ERR(regmap);
+	}
+
+	ret = clk_bulk_get(dev, ARRAY_SIZE(clks), clks);
+	if (ret)
+		return ret;
+
+	ret = clk_bulk_enable(ARRAY_SIZE(clks), clks);
+	if (ret < 0)
+		return ret;
+
+	ret = device_reset(dev);
+	if (ret)
+		return ret;
+
+	dwc = dwc_drv_probe(dev);
+	if (IS_ERR(dwc))
+		return PTR_ERR(dwc);
+
+	if (phy_interface_mode_is_rgmii(dwc->interface)) {
+		regmap_update_bits(regmap, SYSMAIN_GMAC_PHY_INTF_SEL, 0x7, 0x1);
+		regmap_write(regmap, SYSMAIN_GMAC_GTXCLK_DLYCHAIN_SEL, 0x4);
+	}
+
+	return 0;
+}
+
+static struct of_device_id starfive_dwc_ether_compatible[] = {
+	{ .compatible = "starfive,stmmac", .data = &starfive_drvdata },
+	{ /* sentinel */ }
+};
+
+static struct driver_d starfive_dwc_ether_driver = {
+	.name = "starfive-designware_eth",
+	.probe = starfive_dwc_ether_probe,
+	.of_compatible = starfive_dwc_ether_compatible,
+};
+device_platform_driver(starfive_dwc_ether_driver);
diff --git a/include/soc/starfive/sysmain.h b/include/soc/starfive/sysmain.h
new file mode 100644
index 000000000000..b58f8d9825fd
--- /dev/null
+++ b/include/soc/starfive/sysmain.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _STARFIVE_SYSMAIN_H_
+#define _STARFIVE_SYSMAIN_H_
+
+#define SYSMAIN_PLL0_REG			0x00
+#define SYSMAIN_PLL1_REG			0x04
+#define SYSMAIN_PLL2_REG			0x08
+#define SYSMAIN_PLLS_STAT			0x0c
+
+#define SYSMAIN_GMAC_PHY_INTF_SEL		0x70
+#define SYSMAIN_GMAC_GTXCLK_DLYCHAIN_SEL	0xC8
+
+
+#endif //_SYSCON_SYSMAIN_CTRL_MACRO_H_
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 03/20] mfd: add TI TPS65086 PMIC restart driver
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 01/20] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 02/20] net: designware: add support for IP integrated into StarFive SoC Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-06-07  6:44   ` Sascha Hauer
  2021-05-31  7:38 ` [PATCH 04/20] mtd: spi-nor: cadence: fix 64-bit issues Ahmad Fatoum
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The PMIC offers regulators, GPIOs and system restart. Add restart only
for now.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/mfd/Kconfig                    | 10 +++
 drivers/mfd/Makefile                   |  2 +
 drivers/mfd/core.c                     | 25 +++++++
 drivers/mfd/tps65086.c                 | 76 ++++++++++++++++++++
 drivers/power/reset/Kconfig            |  6 ++
 drivers/power/reset/Makefile           |  1 +
 drivers/power/reset/tps65086-restart.c | 55 +++++++++++++++
 include/linux/mfd/core.h               | 26 +++++++
 include/linux/mfd/tps65086.h           | 98 ++++++++++++++++++++++++++
 9 files changed, 299 insertions(+)
 create mode 100644 drivers/mfd/core.c
 create mode 100644 drivers/mfd/tps65086.c
 create mode 100644 drivers/power/reset/tps65086-restart.c
 create mode 100644 include/linux/mfd/core.h
 create mode 100644 include/linux/mfd/tps65086.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d7a8949bafc8..6c76c86fa0cc 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -40,6 +40,16 @@ config MFD_SYSCON
 	help
 	  Select this option to enable accessing system control registers
 
+config MFD_TPS65086
+	bool "TI TPS65086 Power Management Integrated Chips (PMICs)"
+	depends on I2C
+	help
+	  If you say yes here you get support for the TPS65086 series of
+	  Power Management chips.
+	  This driver provides common support for accessing the device,
+	  additional drivers must be enabled in order to use the
+	  functionality of the device.
+
 config MFD_TWLCORE
 	bool
 
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 690e53693ebc..45037e06d62b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MFD_MC34704)	+= mc34704.o
 obj-$(CONFIG_MFD_MC9SDZ60)	+= mc9sdz60.o
 obj-$(CONFIG_MFD_STMPE)		+= stmpe-i2c.o
 obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
+obj-$(CONFIG_MFD_TPS65086)	+= tps65086.o
 obj-$(CONFIG_MFD_TWLCORE)	+= twl-core.o
 obj-$(CONFIG_MFD_TWL4030)	+= twl4030.o
 obj-$(CONFIG_MFD_TWL6030)	+= twl6030.o
@@ -17,3 +18,4 @@ obj-$(CONFIG_FINTEK_SUPERIO)	+= fintek-superio.o
 obj-$(CONFIG_SMSC_SUPERIO)	+= smsc-superio.o
 obj-$(CONFIG_MFD_STM32_TIMERS)	+= stm32-timers.o
 obj-$(CONFIG_MFD_ATMEL_FLEXCOM)	+= atmel-flexcom.o
+obj-y				+= core.o
diff --git a/drivers/mfd/core.c b/drivers/mfd/core.c
new file mode 100644
index 000000000000..ee600d4baafd
--- /dev/null
+++ b/drivers/mfd/core.c
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/mfd/core.h>
+#include <driver.h>
+
+int mfd_add_devices(struct device_d *parent, const struct mfd_cell *cells, int n_devs)
+{
+	struct device_d *dev;
+	int ret, i;
+
+	for (i = 0; i < n_devs; i++) {
+		dev = device_alloc(cells[i].name, DEVICE_ID_DYNAMIC);
+		dev->parent = parent;
+
+		ret = platform_device_register(dev);
+		if (ret)
+			return ret;
+
+		ret = device_add_data(dev, (void *)&cells[i], sizeof(cells[i]));
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
new file mode 100644
index 000000000000..12127922ad2b
--- /dev/null
+++ b/drivers/mfd/tps65086.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
+ *	Andrew F. Davis <afd@ti.com>
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <errno.h>
+#include <i2c/i2c.h>
+#include <linux/mfd/core.h>
+#include <init.h>
+#include <malloc.h>
+#include <of.h>
+#include <regmap.h>
+#include <xfuncs.h>
+
+#include <linux/mfd/tps65086.h>
+
+static const struct mfd_cell tps65086_cells[] = {
+	{ .name = "tps65086-regulator", },
+	{ .name = "tps65086-gpio", },
+};
+
+static const struct regmap_config tps65086_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0xB6,
+};
+
+static const struct of_device_id tps65086_of_match_table[] = {
+	{ .compatible = "ti,tps65086", },
+	{ /* sentinel */ }
+};
+
+static int tps65086_probe(struct device_d *dev)
+{
+	struct tps65086 *tps;
+	unsigned int version;
+	int ret;
+
+	tps = xzalloc(sizeof(*tps));
+	tps->dev = dev;
+
+	tps->regmap = regmap_init_i2c(to_i2c_client(dev), &tps65086_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		dev_err(tps->dev, "Failed to initialize register map\n");
+		return PTR_ERR(tps->regmap);
+	}
+
+	ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
+	if (ret) {
+		dev_err(tps->dev, "Failed to read revision register\n");
+		return ret;
+	}
+
+	dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
+		 (version & TPS65086_DEVICEID_PART_MASK),
+		 (char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
+		 (version & TPS65086_DEVICEID_REV_MASK) >> 6);
+
+	dev->priv = tps;
+
+	return mfd_add_devices(tps->dev, tps65086_cells, ARRAY_SIZE(tps65086_cells));
+}
+
+static struct driver_d tps65086_driver = {
+	.name	= "tps65086",
+	.of_compatible = tps65086_of_match_table,
+	.probe		= tps65086_probe,
+};
+device_i2c_driver(tps65086_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TPS65086 PMIC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index dec1482ccd0c..09d6ba0d9031 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -44,3 +44,9 @@ config POWER_RESET_GPIO_RESTART
 	  This driver supports restarting your board via a GPIO line.
 	  If your board needs a GPIO high/low to restart, say Y and
 	  create a binding in your devicetree.
+
+config POWER_RESET_TPS65086
+	bool "TPS65086 restart driver"
+	depends on MFD_TPS65086
+	help
+	  Reset TPS65086 PMIC on restart.
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 33d29d2d9546..b362400ba5ef 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o
 obj-$(CONFIG_POWER_RESET_SYSCON_POWEROFF) += syscon-poweroff.o
 obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
 obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
+obj-$(CONFIG_POWER_RESET_TPS65086) += tps65086-restart.o
diff --git a/drivers/power/reset/tps65086-restart.c b/drivers/power/reset/tps65086-restart.c
new file mode 100644
index 000000000000..686f215a7781
--- /dev/null
+++ b/drivers/power/reset/tps65086-restart.c
@@ -0,0 +1,55 @@
+
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Emil Renner Berthing
+ */
+
+#include <common.h>
+#include <init.h>
+#include <regmap.h>
+#include <restart.h>
+
+#include <linux/mfd/tps65086.h>
+
+struct tps65086_restart {
+	struct restart_handler handler;
+	struct tps65086 *tps;
+};
+
+static void __noreturn tps65086_restart_handle(struct restart_handler *this)
+{
+	struct tps65086_restart *tps65086_restart =
+		container_of(this, struct tps65086_restart, handler);
+	int ret;
+
+	ret = regmap_write(tps65086_restart->tps->regmap, TPS65086_FORCESHUTDN, 1);
+	WARN_ON(ret);
+
+	/* give it a little time */
+	mdelay(200);
+
+	panic("Unable to restart system\n");
+}
+
+static int tps65086_restart_probe(struct device_d *dev)
+{
+	struct tps65086_restart *tps65086_restart;
+
+	tps65086_restart = xzalloc(sizeof(*tps65086_restart));
+	tps65086_restart->tps = dev->parent->priv;
+
+	tps65086_restart->handler.name = "tps65086-restart";
+	tps65086_restart->handler.restart = tps65086_restart_handle;
+	tps65086_restart->handler.priority = 192;
+
+	return restart_handler_register(&tps65086_restart->handler);
+}
+
+static struct driver_d tps65086_restart_driver = {
+	.name = "tps65086-restart",
+	.probe = tps65086_restart_probe,
+};
+device_platform_driver(tps65086_restart_driver);
+
+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
+MODULE_DESCRIPTION("TPS65086 restart driver");
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
new file mode 100644
index 000000000000..b67ed25b1de8
--- /dev/null
+++ b/include/linux/mfd/core.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * drivers/mfd/mfd-core.h
+ *
+ * core MFD support
+ * Copyright (c) 2006 Ian Molton
+ * Copyright (c) 2007 Dmitry Baryshkov
+ */
+
+#ifndef MFD_CORE_H
+#define MFD_CORE_H
+
+#include <driver.h>
+
+/*
+ * This struct describes the MFD part ("cell").
+ * After registration the copy of this structure will become the platform data
+ * of the resulting device_d
+ */
+struct mfd_cell {
+	const char		*name;
+};
+
+int mfd_add_devices(struct device_d *parent, const struct mfd_cell *cells, int n_devs);
+
+#endif
diff --git a/include/linux/mfd/tps65086.h b/include/linux/mfd/tps65086.h
new file mode 100644
index 000000000000..70ecde153ff2
--- /dev/null
+++ b/include/linux/mfd/tps65086.h
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
+ *	Andrew F. Davis <afd@ti.com>
+ *
+ * Based on the TPS65912 driver
+ */
+
+#ifndef __LINUX_MFD_TPS65086_H
+#define __LINUX_MFD_TPS65086_H
+
+#include <driver.h>
+#include <regmap.h>
+
+/* List of registers for TPS65086 */
+#define TPS65086_DEVICEID		0x01
+#define TPS65086_IRQ			0x02
+#define TPS65086_IRQ_MASK		0x03
+#define TPS65086_PMICSTAT		0x04
+#define TPS65086_SHUTDNSRC		0x05
+#define TPS65086_BUCK1CTRL		0x20
+#define TPS65086_BUCK2CTRL		0x21
+#define TPS65086_BUCK3DECAY		0x22
+#define TPS65086_BUCK3VID		0x23
+#define TPS65086_BUCK3SLPCTRL		0x24
+#define TPS65086_BUCK4CTRL		0x25
+#define TPS65086_BUCK5CTRL		0x26
+#define TPS65086_BUCK6CTRL		0x27
+#define TPS65086_LDOA2CTRL		0x28
+#define TPS65086_LDOA3CTRL		0x29
+#define TPS65086_DISCHCTRL1		0x40
+#define TPS65086_DISCHCTRL2		0x41
+#define TPS65086_DISCHCTRL3		0x42
+#define TPS65086_PG_DELAY1		0x43
+#define TPS65086_FORCESHUTDN		0x91
+#define TPS65086_BUCK1SLPCTRL		0x92
+#define TPS65086_BUCK2SLPCTRL		0x93
+#define TPS65086_BUCK4VID		0x94
+#define TPS65086_BUCK4SLPVID		0x95
+#define TPS65086_BUCK5VID		0x96
+#define TPS65086_BUCK5SLPVID		0x97
+#define TPS65086_BUCK6VID		0x98
+#define TPS65086_BUCK6SLPVID		0x99
+#define TPS65086_LDOA2VID		0x9A
+#define TPS65086_LDOA3VID		0x9B
+#define TPS65086_BUCK123CTRL		0x9C
+#define TPS65086_PG_DELAY2		0x9D
+#define TPS65086_PIN_EN_MASK1		0x9E
+#define TPS65086_PIN_EN_MASK2		0x9F
+#define TPS65086_SWVTT_EN		0x9F
+#define TPS65086_PIN_EN_OVR1		0xA0
+#define TPS65086_PIN_EN_OVR2		0xA1
+#define TPS65086_GPOCTRL		0xA1
+#define TPS65086_PWR_FAULT_MASK1	0xA2
+#define TPS65086_PWR_FAULT_MASK2	0xA3
+#define TPS65086_GPO1PG_CTRL1		0xA4
+#define TPS65086_GPO1PG_CTRL2		0xA5
+#define TPS65086_GPO4PG_CTRL1		0xA6
+#define TPS65086_GPO4PG_CTRL2		0xA7
+#define TPS65086_GPO2PG_CTRL1		0xA8
+#define TPS65086_GPO2PG_CTRL2		0xA9
+#define TPS65086_GPO3PG_CTRL1		0xAA
+#define TPS65086_GPO3PG_CTRL2		0xAB
+#define TPS65086_LDOA1CTRL		0xAE
+#define TPS65086_PG_STATUS1		0xB0
+#define TPS65086_PG_STATUS2		0xB1
+#define TPS65086_PWR_FAULT_STATUS1	0xB2
+#define TPS65086_PWR_FAULT_STATUS2	0xB3
+#define TPS65086_TEMPCRIT		0xB4
+#define TPS65086_TEMPHOT		0xB5
+#define TPS65086_OC_STATUS		0xB6
+
+/* IRQ Register field definitions */
+#define TPS65086_IRQ_DIETEMP_MASK	BIT(0)
+#define TPS65086_IRQ_SHUTDN_MASK	BIT(3)
+#define TPS65086_IRQ_FAULT_MASK		BIT(7)
+
+/* DEVICEID Register field definitions */
+#define TPS65086_DEVICEID_PART_MASK	GENMASK(3, 0)
+#define TPS65086_DEVICEID_OTP_MASK	GENMASK(5, 4)
+#define TPS65086_DEVICEID_REV_MASK	GENMASK(7, 6)
+
+/* VID Masks */
+#define BUCK_VID_MASK			GENMASK(7, 1)
+#define VDOA1_VID_MASK			GENMASK(4, 1)
+#define VDOA23_VID_MASK			GENMASK(3, 0)
+
+/**
+ * struct tps65086 - state holder for the tps65086 driver
+ *
+ * Device data may be used to access the TPS65086 chip
+ */
+struct tps65086 {
+	struct device_d *dev;
+	struct regmap *regmap;
+};
+
+#endif /* __LINUX_MFD_TPS65086_H */
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 04/20] mtd: spi-nor: cadence: fix 64-bit issues
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (2 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 03/20] mfd: add TI TPS65086 PMIC restart driver Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-06-07  6:51   ` Sascha Hauer
  2021-05-31  7:38 ` [PATCH 05/20] nvmem: add StarFive OTP support Ahmad Fatoum
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Pointers are being cast to unsigned int, which will truncate the address
on 64-bit systems. Fix this.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/mtd/spi-nor/cadence-quadspi.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
index ea53d2cd847a..09015aad43f1 100644
--- a/drivers/mtd/spi-nor/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/cadence-quadspi.c
@@ -347,8 +347,8 @@ static int cqspi_command_read(struct spi_nor *nor,
 
 	if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || rxbuf == NULL) {
 		dev_err(nor->dev,
-			"Invalid input argument, len %d rxbuf 0x%08x\n", n_rx,
-			(unsigned int)rxbuf);
+			"Invalid input argument, len %d rxbuf %p\n", n_rx,
+			rxbuf);
 		return -EINVAL;
 	}
 
@@ -393,8 +393,8 @@ static __maybe_unused int cqspi_command_write(struct spi_nor *nor,
 
 	if (n_tx > 4 || (n_tx && txbuf == NULL)) {
 		dev_err(nor->dev,
-			"Invalid input argument, cmdlen %d txbuf 0x%08x\n",
-			n_tx, (unsigned int)txbuf);
+			"Invalid input argument, cmdlen %d txbuf %p\n",
+			n_tx, txbuf);
 		return -EINVAL;
 	}
 
@@ -433,7 +433,7 @@ static int cqspi_indirect_read_setup(struct spi_nor *nor,
 {
 	struct cqspi_flash_pdata *f_pdata;
 	struct cqspi_st *cqspi = nor->priv;
-	unsigned int ahb_base = (unsigned int) cqspi->ahb_base;
+	unsigned long ahb_base = (unsigned long) cqspi->ahb_base;
 	void __iomem *reg_base = cqspi->iobase;
 	unsigned int dummy_clk = 0;
 	unsigned int dummy_bytes;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 05/20] nvmem: add StarFive OTP support
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (3 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 04/20] mtd: spi-nor: cadence: fix 64-bit issues Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 06/20] RISC-V: dma: support multiple dma_alloc_coherent backends Ahmad Fatoum
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The OTP holds the ethernet MAC address. Add a driver, so barebox can
read it out.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/nvmem/Kconfig        |   8 ++
 drivers/nvmem/Makefile       |   2 +
 drivers/nvmem/starfive-otp.c | 227 +++++++++++++++++++++++++++++++++++
 3 files changed, 237 insertions(+)
 create mode 100644 drivers/nvmem/starfive-otp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index e4a72b1431a9..377d6c8b15cc 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -59,4 +59,12 @@ config STM32_BSEC
 	  This adds support for the STM32 OTP controller. Reads and writes
 	  to will go to the shadow RAM, not the OTP fuses themselvers.
 
+config STARFIVE_OTP
+	tristate "Starfive OTP Supprot"
+	depends on SOC_STARFIVE
+	depends on OFDEVICE
+	help
+	  This adds support for the StarFive OTP controller. Only reading
+	  is currently supported.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 617e3725a726..83ff3d23cb44 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -20,3 +20,5 @@ nvmem_eeprom_93xx46-y		:= eeprom_93xx46.o
 
 obj-$(CONFIG_STM32_BSEC)	+= nvmem_bsec.o
 nvmem_bsec-y			:= bsec.o
+
+obj-$(CONFIG_STARFIVE_OTP)	+= starfive-otp.o
diff --git a/drivers/nvmem/starfive-otp.c b/drivers/nvmem/starfive-otp.c
new file mode 100644
index 000000000000..5d1a94364d81
--- /dev/null
+++ b/drivers/nvmem/starfive-otp.c
@@ -0,0 +1,227 @@
+// SPDX_License-Identifier: GPL-2.0
+/*
+ *   Copyright 2021 StarFive, Inc
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <malloc.h>
+#include <xfuncs.h>
+#include <errno.h>
+#include <gpiod.h>
+#include <init.h>
+#include <net.h>
+#include <io.h>
+#include <of.h>
+#include <regmap.h>
+#include <machine_id.h>
+#include <linux/reset.h>
+#include <linux/nvmem-provider.h>
+
+// otp reg offset
+#define OTP_CFGR        0x00
+#define OTPC_IER        0x04
+#define OTPC_SRR        0x08
+#define OTP_OPRR        0x0c
+#define OTPC_CTLR       0x10
+#define OTPC_ADDRR      0x14
+#define OTPC_DINR       0x18
+#define OTPC_DOUTR      0x1c
+
+#define OTP_EMPTY_CELL_VALUE  0xffffffffUL
+
+// cfgr (offset 0x00)
+#define OTP_CFGR_PRG_CNT_MASK   0xff
+#define OTP_CFGR_PRG_CNT_SHIFT  0
+#define OTP_CFGR_DIV_1US_MASK   0xff
+#define OTP_CFGR_DIV_1US_SHIFT  8
+#define OTP_CFGR_RD_CYC_MASK    0x0f
+#define OTP_CFGR_RD_CYC_SHIFT   16
+
+// ier (offset 0x04)
+#define OTPC_IER_DONE_IE        BIT(0)
+#define OTPC_IER_BUSY_OPR_IE    BIT(1)
+
+// srr (offset 0x08)
+#define OTPC_SRR_DONE           BIT(0)
+#define OTPC_SRR_BUSY_OPR       BIT(1)
+#define OTPC_SRR_INFO_RD_LOCK   BIT(29)
+#define OTPC_SRR_INFO_WR_LOCK   BIT(30)
+#define OTPC_SRR_BUSY           BIT(31)
+
+// oprr (offset 0x0c)
+#define OTP_OPRR_OPR_MASK           0x00000007
+#define OTP_OPRR_OPR_SHIFT          0
+
+#define OTP_OPR_STANDBY             0x0 // user mode
+#define OTP_OPR_READ                0x1 // user mode
+#define OTP_OPR_MARGIN_READ_PROG    0x2 // testing mode
+#define OTP_OPR_MARGIN_READ_INIT    0x3 // testing mode
+#define OTP_OPR_PROGRAM             0x4 // user mode
+#define OTP_OPR_DEEP_STANDBY        0x5 // user mode
+#define OTP_OPR_DEBUG               0x6 // user mode
+
+// ctlr (offset 0x10, see EG512X32TH028CW01_v1.0.pdf "Pin Description")
+#define OTPC_CTLR_PCE               BIT(0)
+#define OTPC_CTLR_PTM_MASK          0x0000000e
+#define OTPC_CTLR_PTM_SHIFT         1
+#define OTPC_CTLR_PDSTB             BIT(4)
+#define OTPC_CTLR_PTR               BIT(5)
+#define OTPC_CTLR_PPROG             BIT(6)
+#define OTPC_CTLR_PWE               BIT(7)
+#define OTPC_CTLR_PCLK              BIT(8)
+
+// addrr (offset 0x14)
+#define OTPC_ADDRR_PA_MASK          0x000001ff
+#define OTPC_ADDRR_PA_SHIFT         0
+
+/*
+ * data format:
+ * struct starfive_otp_data{
+ * 	char vendor[32];
+ * 	uint64_t sn;
+ * 	uint8_t mac_addr[6];
+ * 	uint8_t padding_0[2];
+ * }
+ */
+
+struct starfive_otp {
+	int power_gpio;
+	struct starfive_otp_regs __iomem *regs;
+};
+
+struct starfive_otp_regs {
+	/* TODO: add otp ememory_eg512x32 registers define */
+	u32 otp_cfg;		/* timing Register */
+	u32 otpc_ie;		/* interrupt Enable */
+	u32 otpc_sr;		/* status Register */
+	u32 otp_opr;		/* operation mode select Register */
+	u32 otpc_ctl;		/* otp control port */
+	u32 otpc_addr;		/* otp pa port */
+	u32 otpc_din;		/* otp pdin port */
+	u32 otpc_dout;		/* otp pdout */
+	u32 reserved[504];
+	u32 mem[512];
+};
+
+/*
+ * offset and size are assumed aligned to the size of the fuses (32-bit).
+ */
+static int starfive_otp_read(void *ctx, unsigned offset, unsigned *val)
+{
+	struct starfive_otp *priv = ctx;
+
+	gpio_set_active(priv->power_gpio, true);
+	mdelay(10);
+
+	//otp set to read mode
+	writel(OTP_OPR_READ, &priv->regs->otp_opr);
+	mdelay(5);
+
+	/* read all requested fuses */
+	*val = readl(&priv->regs->mem[offset / 4]);
+
+	gpio_set_active(priv->power_gpio, false);
+	mdelay(5);
+
+	return 0;
+}
+
+static int starfive_otp_write(void *ctx, unsigned offset, unsigned val)
+{
+	return -EOPNOTSUPP;
+}
+
+static struct regmap_bus starfive_otp_regmap_bus = {
+	.reg_read = starfive_otp_read,
+	.reg_write = starfive_otp_write,
+};
+
+static int starfive_otp_set_mac(struct device_node *rnode, struct regmap *map, unsigned offset)
+{
+	u8 mac[8];
+	int ret;
+
+	ret = regmap_bulk_read(map, offset, mac, 8);
+	if (ret)
+		return ret;
+
+	of_eth_register_ethaddr(rnode, mac);
+	return 0;
+}
+
+static int starfive_otp_probe(struct device_d *dev)
+{
+	struct starfive_otp *priv;
+	struct regmap_config config = {};
+	struct nvmem_device *nvmem;
+	struct resource *iores;
+	const __be32 *prop;
+	struct regmap *map;
+	u32 total_fuses;
+	int len, ret;
+
+	ret = device_reset(dev);
+	if (ret)
+		return ret;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+
+	ret = of_property_read_u32(dev->device_node, "fuse-count", &total_fuses);
+	if (ret < 0) {
+		dev_err(dev, "missing required fuse-count property\n");
+		return ret;
+	}
+
+	config.name = "starfive-otp";
+	config.reg_bits = 32;
+	config.val_bits = 32;
+	config.reg_stride = 4;
+	config.max_register = total_fuses;
+
+	priv = xzalloc(sizeof(*priv));
+
+	priv->regs = IOMEM(iores->start);
+	priv->power_gpio = gpiod_get(dev, "power", GPIOD_OUT_LOW);
+	if (priv->power_gpio < 0)
+		return priv->power_gpio;
+
+	map = regmap_init(dev, &starfive_otp_regmap_bus, priv, &config);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+
+	nvmem = nvmem_regmap_register(map, "starfive-otp");
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	prop = of_get_property(dev->device_node, "barebox,provide-mac-address", &len);
+	if (prop && len == 2 * sizeof(__be32)) {
+		struct device_node *rnode;
+		u32 phandle, offset;
+
+		phandle = be32_to_cpup(prop++);
+
+		rnode = of_find_node_by_phandle(phandle);
+		offset = be32_to_cpup(prop++);
+
+		ret = starfive_otp_set_mac(rnode, map, offset);
+		if (ret)
+			dev_warn(dev, "error setting MAC address: %pe\n", ERR_PTR(ret));
+	}
+
+	return 0;
+}
+
+static struct of_device_id starfive_otp_dt_ids[] = {
+	{ .compatible = "starfive,fu740-otp" },
+	{ /* sentinel */ }
+};
+
+static struct driver_d starfive_otp_driver = {
+	.name	= "starfive_otp",
+	.probe	= starfive_otp_probe,
+	.of_compatible = starfive_otp_dt_ids,
+};
+device_platform_driver(starfive_otp_driver);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 06/20] RISC-V: dma: support multiple dma_alloc_coherent backends
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (4 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 05/20] nvmem: add StarFive OTP support Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 07/20] RISC-V: support incoherent I-Cache Ahmad Fatoum
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

StarFive JH7100 has uncached DDR region at 64G, but Designware MAC v3.70
has 32-bit DMA mask. There's internal RAM in first 4G that's uncached,
which we could use as backing store for dma_alloc_coherent.

Rework code, so SoC specific code can define own implementation.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/cpu/Makefile        |  2 +
 arch/riscv/cpu/cache.c         | 22 +++++++++++
 arch/riscv/cpu/dma.c           | 69 ++++++++++++++++++++++++++++++++++
 arch/riscv/include/asm/cache.h | 17 +++++++++
 arch/riscv/include/asm/dma.h   | 42 +++++----------------
 5 files changed, 119 insertions(+), 33 deletions(-)
 create mode 100644 arch/riscv/cpu/cache.c
 create mode 100644 arch/riscv/cpu/dma.c
 create mode 100644 arch/riscv/include/asm/cache.h

diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile
index f1312be699a1..e521ca4bfd47 100644
--- a/arch/riscv/cpu/Makefile
+++ b/arch/riscv/cpu/Makefile
@@ -1,3 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-y += core.o time.o
+obj-$(CONFIG_HAS_CACHE) += cache.o
+obj-$(CONFIG_HAS_DMA) += dma.o
diff --git a/arch/riscv/cpu/cache.c b/arch/riscv/cpu/cache.c
new file mode 100644
index 000000000000..d5aad7e4038b
--- /dev/null
+++ b/arch/riscv/cpu/cache.c
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <asm/cache.h>
+
+static struct cache_ops *cache_ops;
+
+void __dma_flush_range(dma_addr_t start, dma_addr_t end)
+{
+	if (cache_ops)
+		cache_ops->dma_flush_range(start, end);
+}
+
+void __dma_inv_range(dma_addr_t start, dma_addr_t end)
+{
+	if (cache_ops)
+		cache_ops->dma_inv_range(start, end);
+}
+
+void riscv_cache_set_ops(struct cache_ops *ops)
+{
+	cache_ops = ops;
+}
diff --git a/arch/riscv/cpu/dma.c b/arch/riscv/cpu/dma.c
new file mode 100644
index 000000000000..d7dc642f5830
--- /dev/null
+++ b/arch/riscv/cpu/dma.c
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <common.h>
+#include <xfuncs.h>
+#include <asm/dma.h>
+#include <asm/cache.h>
+#include <malloc.h>
+
+static void *__dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+	void *ret;
+
+	ret = xmemalign(PAGE_SIZE, size);
+
+	memset(ret, 0, size);
+
+	if (dma_handle)
+		*dma_handle = (dma_addr_t)ret;
+
+	return ret;
+}
+
+static void __dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
+{
+	free(vaddr);
+}
+
+static const struct dma_coherent_ops nommu_ops = {
+	.alloc = __dma_alloc_coherent,
+	.free = __dma_free_coherent,
+};
+
+static const struct dma_coherent_ops *dma_coherent_ops = &nommu_ops;
+
+void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+	return dma_coherent_ops->alloc(size, dma_handle);
+}
+
+void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
+{
+	dma_coherent_ops->free(vaddr, dma_handle, size);
+}
+
+void dma_set_coherent_ops(const struct dma_coherent_ops *ops)
+{
+	dma_coherent_ops = ops;
+}
+
+void dma_sync_single_for_cpu(dma_addr_t address, size_t size, enum dma_data_direction dir)
+{
+        /*
+         * FIXME: This function needs a device argument to support non 1:1 mappings
+         */
+        if (dir != DMA_TO_DEVICE)
+                __dma_inv_range(address, address + size);
+}
+
+void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir)
+{
+        /*
+         * FIXME: This function needs a device argument to support non 1:1 mappings
+         */
+
+        if (dir == DMA_FROM_DEVICE)
+                __dma_inv_range(address, address + size);
+        else
+                __dma_flush_range(address, address + size);
+}
diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h
new file mode 100644
index 000000000000..a1cdd6b13b62
--- /dev/null
+++ b/arch/riscv/include/asm/cache.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_CACHE_H
+#define __ASM_CACHE_H
+
+#include <linux/types.h>
+
+struct cache_ops {
+	void (*dma_flush_range)(dma_addr_t start, dma_addr_t end);
+	void (*dma_inv_range)(dma_addr_t start, dma_addr_t end);
+};
+
+void __dma_flush_range(dma_addr_t start, dma_addr_t end);
+void __dma_inv_range(dma_addr_t start, dma_addr_t end);
+
+void riscv_cache_set_ops(struct cache_ops *ops);
+
+#endif
diff --git a/arch/riscv/include/asm/dma.h b/arch/riscv/include/asm/dma.h
index 4204653984a3..b880e49732e0 100644
--- a/arch/riscv/include/asm/dma.h
+++ b/arch/riscv/include/asm/dma.h
@@ -2,43 +2,19 @@
 #ifndef _ASM_DMA_MAPPING_H
 #define _ASM_DMA_MAPPING_H
 
-#include <common.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
 #include <xfuncs.h>
-#include <linux/build_bug.h>
-#include <malloc.h>
 
-#ifdef CONFIG_MMU
-#error DMA stubs need be replaced when using MMU and caches
-#endif
+struct dma_coherent_ops {
+	void *(*alloc)(size_t size, dma_addr_t *dma_handle);
 
-static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
-{
-	void *ret;
+	void (*free)(void *vaddr, dma_addr_t dma_handle, size_t size);
+};
 
-	ret = xmemalign(PAGE_SIZE, size);
+void dma_set_coherent_ops(const struct dma_coherent_ops *ops);
+#define DMA_ALIGNMENT 64
 
-	memset(ret, 0, size);
-
-	if (dma_handle)
-		*dma_handle = (dma_addr_t)ret;
-
-	return ret;
-}
-
-static inline void dma_free_coherent(void *vaddr, dma_addr_t dma_handle,
-				     size_t size)
-{
-	free(vaddr);
-}
-
-static inline void dma_sync_single_for_cpu(dma_addr_t address, size_t size,
-					   enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_single_for_device(dma_addr_t address, size_t size,
-					      enum dma_data_direction dir)
-{
-}
+#include <dma.h>
 
 #endif /* _ASM_DMA_MAPPING_H */
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 07/20] RISC-V: support incoherent I-Cache
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (5 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 06/20] RISC-V: dma: support multiple dma_alloc_coherent backends Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:40   ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 08/20] soc: add support for StarFive JH7100 incoherent interconnect Ahmad Fatoum
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

SiFive SoCs have separate I-Caches that require self-modifying code
like barebox' relocation and PBL extraction code to do cache
maintenance. Implement sync_caches_for_execution and use it where
appropriate.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/Kconfig.socs                | 2 ++
 arch/riscv/boot/uncompress.c           | 2 ++
 arch/riscv/cpu/core.c                  | 7 +++++++
 arch/riscv/include/asm/barebox-riscv.h | 2 ++
 arch/riscv/lib/reloc.c                 | 8 ++++++++
 arch/riscv/lib/setupc.S                | 2 ++
 6 files changed, 23 insertions(+)

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 9c82a36fe4bd..d2970ba1d67f 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -18,6 +18,7 @@ config SOC_VIRT
 	select RISCV_S_MODE
 	select BOARD_RISCV_GENERIC_DT
 	select CLINT_TIMER
+	select HAS_CACHE
 	help
 	  Generates an image tht can be be booted by QEMU. The image is called
 	  barebox-dt-2nd.img
@@ -30,6 +31,7 @@ config SOC_SIFIVE
 	select RISCV_TIMER
 	select HAS_MACB
 	select HAS_ASM_DEBUG_LL
+	select HAS_CACHE
 	help
 	  This enables support for SiFive SoC platform hardware.
 
diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
index 35a91e8cb62a..9f1d25efb59b 100644
--- a/arch/riscv/boot/uncompress.c
+++ b/arch/riscv/boot/uncompress.c
@@ -63,6 +63,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
 
 	pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len);
 
+	sync_caches_for_execution();
+
 	barebox = (void *)barebox_base;
 
 	pr_debug("jumping to uncompressed image at 0x%p. dtb=0x%p\n", barebox, fdt);
diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c
index 62eb0ca87164..b4727fe7449b 100644
--- a/arch/riscv/cpu/core.c
+++ b/arch/riscv/cpu/core.c
@@ -18,6 +18,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <memory.h>
+#include <asm/barebox-riscv.h>
 #include <asm-generic/memory_layout.h>
 #include <globalvar.h>
 #include <magicvar.h>
@@ -91,3 +92,9 @@ static struct driver_d riscv_driver = {
 	.of_compatible = riscv_dt_ids,
 };
 postcore_platform_driver(riscv_driver);
+
+static void arch_shutdown(void)
+{
+	sync_caches_for_execution();
+}
+archshutdown_exitcall(arch_shutdown);
diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
index bbe6cd040642..abb320242769 100644
--- a/arch/riscv/include/asm/barebox-riscv.h
+++ b/arch/riscv/include/asm/barebox-riscv.h
@@ -27,6 +27,8 @@ void setup_c(void);
 void relocate_to_current_adr(void);
 void relocate_to_adr(unsigned long target);
 
+void sync_caches_for_execution(void);
+
 void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long memsize,
 					    void *boarddata, unsigned int flags);
 
diff --git a/arch/riscv/lib/reloc.c b/arch/riscv/lib/reloc.c
index 2fc8818cd698..165190775361 100644
--- a/arch/riscv/lib/reloc.c
+++ b/arch/riscv/lib/reloc.c
@@ -24,6 +24,12 @@
 
 #define RISC_R_TYPE(x)	((x) & 0xFF)
 
+void sync_caches_for_execution(void)
+{
+	if (IS_ENABLED(CONFIG_HAS_CACHE))
+		asm volatile ("fence.i" ::: "memory");
+}
+
 void relocate_to_current_adr(void)
 {
 	unsigned long offset;
@@ -63,4 +69,6 @@ void relocate_to_current_adr(void)
 			panic("");
 		}
 	}
+
+	sync_caches_for_execution();
 }
diff --git a/arch/riscv/lib/setupc.S b/arch/riscv/lib/setupc.S
index 5fdd81c2c3ec..d225186c79fd 100644
--- a/arch/riscv/lib/setupc.S
+++ b/arch/riscv/lib/setupc.S
@@ -46,6 +46,8 @@ ENTRY(relocate_to_adr)
 
 	jal	__memcpy
 
+	jal	sync_caches_for_execution
+
 	REG_L	a0, (SZREG * 1)(sp)
 	jr	a0 			/* jump to relocated address */
 copied:
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 08/20] soc: add support for StarFive JH7100 incoherent interconnect
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (6 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 07/20] RISC-V: support incoherent I-Cache Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 09/20] soc: sifive: l2_cache: enable maximum available cache ways Ahmad Fatoum
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The preproduction JH7100 used in the BeagleV beta does not ensure cache
coherence between CPU and some DMA masters like the Ethernet MAC.

Fix this for streaming DMA mappings by implementing cache cleaning and
discarding.  The Flush64 primitive can be used for both as it will
invalidate after flushing and not write-back clean lines.

Coherent DMA mapping will be implemented using allocation from uncached
SRAM in a follow-up commit.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/Kconfig.socs              |   5 +
 arch/riscv/include/asm/barrier.h     |  27 ++++++
 drivers/Makefile                     |   2 +-
 drivers/soc/Makefile                 |   4 +
 drivers/soc/sifive/Makefile          |   1 +
 drivers/soc/sifive/sifive_l2_cache.c | 137 +++++++++++++++++++++++++++
 6 files changed, 175 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/include/asm/barrier.h
 create mode 100644 drivers/soc/Makefile
 create mode 100644 drivers/soc/sifive/Makefile
 create mode 100644 drivers/soc/sifive/sifive_l2_cache.c

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index d2970ba1d67f..3e4cd3cdad59 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -37,6 +37,11 @@ config SOC_SIFIVE
 
 if SOC_SIFIVE
 
+config SIFIVE_L2
+	bool
+	help
+	  Selected by SoCs with cache incoherent interconnects
+
 config BOARD_HIFIVE
 	bool "HiFive"
 	depends on ARCH_RV64I
diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h
new file mode 100644
index 000000000000..eff529307a15
--- /dev/null
+++ b/arch/riscv/include/asm/barrier.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Based on arch/arm/include/asm/barrier.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2013 Regents of the University of California
+ * Copyright (C) 2017 SiFive
+ */
+
+#ifndef _ASM_RISCV_BARRIER_H
+#define _ASM_RISCV_BARRIER_H
+
+#ifndef __ASSEMBLY__
+
+#define nop()		__asm__ __volatile__ ("nop")
+
+#define RISCV_FENCE(p, s) \
+	__asm__ __volatile__ ("fence " #p "," #s : : : "memory")
+
+/* These barriers need to enforce ordering on both devices or memory. */
+#define mb()		RISCV_FENCE(iorw,iorw)
+#define rmb()		RISCV_FENCE(ir,ir)
+#define wmb()		RISCV_FENCE(ow,ow)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_BARRIER_H */
diff --git a/drivers/Makefile b/drivers/Makefile
index be5b0b3b04c9..aeb097e1f5ff 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -39,7 +39,7 @@ obj-$(CONFIG_HAB) += hab/
 obj-$(CONFIG_CRYPTO_HW) += crypto/
 obj-$(CONFIG_AIODEV) += aiodev/
 obj-y	+= memory/
-obj-y	+= soc/imx/
+obj-y	+= soc/
 obj-y	+= nvme/
 obj-y	+= ddr/
 obj-y	+= power/
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
new file mode 100644
index 000000000000..06b8c2a504af
--- /dev/null
+++ b/drivers/soc/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y	+= imx/
+obj-$(CONFIG_SOC_SIFIVE)	+= sifive/
diff --git a/drivers/soc/sifive/Makefile b/drivers/soc/sifive/Makefile
new file mode 100644
index 000000000000..e8113c66f576
--- /dev/null
+++ b/drivers/soc/sifive/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SIFIVE_L2) += sifive_l2_cache.o
diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
new file mode 100644
index 000000000000..1ac39c743681
--- /dev/null
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SiFive L2 cache controller Driver
+ *
+ * Copyright (C) 2018-2019 SiFive, Inc.
+ *
+ */
+
+#define pr_fmt(fmt) "sifive-l2: " fmt
+
+#include <io.h>
+#include <printk.h>
+#include <stdio.h>
+#include <driver.h>
+#include <init.h>
+#include <of.h>
+#include <asm/cache.h>
+#include <asm/barrier.h>
+
+#define SIFIVE_L2_DIRECCFIX_LOW 0x100
+#define SIFIVE_L2_DIRECCFIX_HIGH 0x104
+#define SIFIVE_L2_DIRECCFIX_COUNT 0x108
+
+#define SIFIVE_L2_DIRECCFAIL_LOW 0x120
+#define SIFIVE_L2_DIRECCFAIL_HIGH 0x124
+#define SIFIVE_L2_DIRECCFAIL_COUNT 0x128
+
+#define SIFIVE_L2_DATECCFIX_LOW 0x140
+#define SIFIVE_L2_DATECCFIX_HIGH 0x144
+#define SIFIVE_L2_DATECCFIX_COUNT 0x148
+
+#define SIFIVE_L2_DATECCFAIL_LOW 0x160
+#define SIFIVE_L2_DATECCFAIL_HIGH 0x164
+#define SIFIVE_L2_DATECCFAIL_COUNT 0x168
+
+#define SIFIVE_L2_FLUSH64 0x200
+
+#define SIFIVE_L2_CONFIG 0x00
+#define SIFIVE_L2_WAYENABLE 0x08
+#define SIFIVE_L2_ECCINJECTERR 0x40
+
+#define SIFIVE_L2_MAX_ECCINTR 4
+
+#define SIFIVE_L2_FLUSH64_LINE_LEN 64
+
+static void __iomem *l2_base = NULL;
+
+static void sifive_l2_config_read(struct device_d *dev)
+{
+	u32 regval, val;
+
+	printf("Cache configuration:\n");
+
+	regval = readl(l2_base + SIFIVE_L2_CONFIG);
+	val = regval & 0xFF;
+	printf("  #Banks: %d\n", val);
+	val = (regval & 0xFF00) >> 8;
+	printf("  #Ways per bank: %d\n", val);
+	val = (regval & 0xFF0000) >> 16;
+	printf("  #Sets per bank: %llu\n", 1llu << val);
+	val = (regval & 0xFF000000) >> 24;
+	printf("  #Bytes per cache block: %llu\n", 1llu << val);
+
+	regval = readl(l2_base + SIFIVE_L2_WAYENABLE);
+	printf("  #Index of the largest way enabled: %d\n", regval);
+}
+
+static void sifive_l2_flush64_range(dma_addr_t start, dma_addr_t end)
+{
+	unsigned long line;
+
+	start = ALIGN_DOWN(start, 64);
+	end = ALIGN(end, 64);
+
+	if (start == end)
+		return;
+
+	mb();
+	for (line = start; line < end; line += SIFIVE_L2_FLUSH64_LINE_LEN) {
+		writeq(line, l2_base + SIFIVE_L2_FLUSH64);
+		mb();
+	}
+}
+
+struct cache_ops sifive_l2_ops = {
+	.dma_flush_range = sifive_l2_flush64_range,
+	.dma_inv_range = sifive_l2_flush64_range,
+};
+
+/* Normally, L2 should be kept coherent between SiFive CPUs and other
+ * DMA masters on the SoC. If that's not the case, add it to the table
+ * here, so barebox dma_map_single and co. flush and invalidate as
+ * necessary.
+ * Note: If barebox is allocating from cacheable memory, you will
+ * need a driver to set dma_coherent_ops as well.
+ */
+static const struct of_device_id incoherent_soc_dt_ids[] = {
+	{ "starfive,jh7100" },
+	{ /* sentinel */ },
+};
+
+static int sifive_l2_probe(struct device_d *dev)
+{
+	struct resource *iores;
+
+	if (l2_base)
+		return -EBUSY;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+
+	l2_base = IOMEM(iores->start);
+
+	dev->info = sifive_l2_config_read;
+
+	if (of_match_node(incoherent_soc_dt_ids, of_get_root_node())) {
+		riscv_cache_set_ops(&sifive_l2_ops);
+		pr_info("enabling L2 cache ops\n");
+	}
+
+	return 0;
+}
+
+static const struct of_device_id sifive_l2_ids[] = {
+	{ .compatible = "sifive,fu540-c000-ccache" },
+	{ .compatible = "sifive,fu740-c000-ccache" },
+	{ .compatible = "starfive,ccache0" },
+	{ /* end of table */ },
+};
+
+static struct driver_d sifive_l2_driver = {
+	.name = "sfive-l2cache",
+	.probe = sifive_l2_probe,
+	.of_compatible = sifive_l2_ids,
+};
+postcore_platform_driver(sifive_l2_driver);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 09/20] soc: sifive: l2_cache: enable maximum available cache ways
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (7 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 08/20] soc: add support for StarFive JH7100 incoherent interconnect Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 10/20] net: designware: fix 64-bit incompatibilities Ahmad Fatoum
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Previous boot stages may not enable all cache ways, e.g. because they
are running from L2 cache. By the time barebox proper is running,
execution should be from main SDRAM, so it's ok now to enable the
maximum available count of cache ways.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/soc/sifive/sifive_l2_cache.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
index 1ac39c743681..f2cef133de63 100644
--- a/drivers/soc/sifive/sifive_l2_cache.c
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -16,6 +16,7 @@
 #include <of.h>
 #include <asm/cache.h>
 #include <asm/barrier.h>
+#include <linux/bitops.h>
 
 #define SIFIVE_L2_DIRECCFIX_LOW 0x100
 #define SIFIVE_L2_DIRECCFIX_HIGH 0x104
@@ -41,6 +42,9 @@
 
 #define SIFIVE_L2_MAX_ECCINTR 4
 
+#define MASK_NUM_WAYS   GENMASK(15, 8)
+#define NUM_WAYS_SHIFT  8
+
 #define SIFIVE_L2_FLUSH64_LINE_LEN 64
 
 static void __iomem *l2_base = NULL;
@@ -87,6 +91,21 @@ struct cache_ops sifive_l2_ops = {
 	.dma_inv_range = sifive_l2_flush64_range,
 };
 
+static int sifive_l2_enable_ways(void)
+{
+	u32 config;
+	u32 ways;
+
+	config = readl(l2_base + SIFIVE_L2_CONFIG);
+	ways = (config & MASK_NUM_WAYS) >> NUM_WAYS_SHIFT;
+
+	mb();
+	writel(ways - 1, l2_base + SIFIVE_L2_WAYENABLE);
+	mb();
+
+	return 0;
+}
+
 /* Normally, L2 should be kept coherent between SiFive CPUs and other
  * DMA masters on the SoC. If that's not the case, add it to the table
  * here, so barebox dma_map_single and co. flush and invalidate as
@@ -112,6 +131,8 @@ static int sifive_l2_probe(struct device_d *dev)
 
 	l2_base = IOMEM(iores->start);
 
+	sifive_l2_enable_ways();
+
 	dev->info = sifive_l2_config_read;
 
 	if (of_match_node(incoherent_soc_dt_ids, of_get_root_node())) {
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 10/20] net: designware: fix 64-bit incompatibilities
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (8 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 09/20] soc: sifive: l2_cache: enable maximum available cache ways Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 11/20] dma: support marking SRAM for coherent DMA use Ahmad Fatoum
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

drivers/net/designware.c handles the older Designware < 4.x MAC IPs,
which do not support DMA beyond 32-bit. They are still being integrated
into SoCs with 64-bit CPUs like the StarFive JH7100.

Fix the driver to support such usage. The driver still has the assumption
that barebox core will only pass it 32-bit pointers. This is now made
explicit by returning error codes when the DMA mask is violated.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/include/asm/io.h | 10 ++++++++++
 drivers/net/designware.c    | 28 +++++++++++++++-------------
 drivers/net/designware.h    |  6 ++++--
 3 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index 3cdea7fcace1..795e670e3b9b 100644
--- a/arch/riscv/include/asm/io.h
+++ b/arch/riscv/include/asm/io.h
@@ -5,4 +5,14 @@
 
 #include <asm-generic/io.h>
 
+static inline void *phys_to_virt(unsigned long phys)
+{
+	return (void *)phys;
+}
+
+static inline unsigned long virt_to_phys(volatile void *mem)
+{
+	return (unsigned long)mem;
+}
+
 #endif /* __ASM_RISCV_IO_H */
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index e815d74ce9b8..71c62d7ddc94 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -111,8 +111,8 @@ static void tx_descs_init(struct eth_device *dev)
 
 	for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
 		desc_p = &desc_table_p[idx];
-		desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE];
-		desc_p->dmamac_next = &desc_table_p[idx + 1];
+		desc_p->dmamac_addr = virt_to_phys(&txbuffs[idx * CONFIG_ETH_BUFSIZE]);
+		desc_p->dmamac_next = virt_to_phys(&desc_table_p[idx + 1]);
 
 		if (priv->enh_desc) {
 			desc_p->txrx_status &= ~(DESC_ENH_TXSTS_TXINT | DESC_ENH_TXSTS_TXLAST |
@@ -130,7 +130,7 @@ static void tx_descs_init(struct eth_device *dev)
 	}
 
 	/* Correcting the last pointer of the chain */
-	desc_p->dmamac_next = &desc_table_p[0];
+	desc_p->dmamac_next = virt_to_phys(&desc_table_p[0]);
 
 	writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
 	priv->tx_currdescnum = 0;
@@ -147,8 +147,8 @@ static void rx_descs_init(struct eth_device *dev)
 
 	for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
 		desc_p = &desc_table_p[idx];
-		desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
-		desc_p->dmamac_next = &desc_table_p[idx + 1];
+		desc_p->dmamac_addr = virt_to_phys(&rxbuffs[idx * CONFIG_ETH_BUFSIZE]);
+		desc_p->dmamac_next = virt_to_phys(&desc_table_p[idx + 1]);
 
 		desc_p->dmamac_cntl = MAC_MAX_FRAME_SZ;
 		if (priv->enh_desc)
@@ -156,13 +156,13 @@ static void rx_descs_init(struct eth_device *dev)
 		else
 			desc_p->dmamac_cntl |= DESC_RXCTRL_RXCHAIN;
 
-		dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr,
+		dma_sync_single_for_cpu(desc_p->dmamac_addr,
 					CONFIG_ETH_BUFSIZE, DMA_FROM_DEVICE);
 		desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
 	}
 
 	/* Correcting the last pointer of the chain */
-	desc_p->dmamac_next = &desc_table_p[0];
+	desc_p->dmamac_next = virt_to_phys(&desc_table_p[0]);
 
 	writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
 	priv->rx_currdescnum = 0;
@@ -285,8 +285,8 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
 		return -1;
 	}
 
-	memcpy((void *)desc_p->dmamac_addr, packet, length);
-	dma_sync_single_for_device((unsigned long)desc_p->dmamac_addr, length,
+	memcpy(dmamac_addr(desc_p), packet, length);
+	dma_sync_single_for_device(desc_p->dmamac_addr, length,
 				   DMA_TO_DEVICE);
 
 	if (priv->enh_desc) {
@@ -314,7 +314,7 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
 
 	/* Start the transmission */
 	writel(POLL_DATA, &dma_p->txpolldemand);
-	dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr, length,
+	dma_sync_single_for_cpu(desc_p->dmamac_addr, length,
 				DMA_TO_DEVICE);
 
 	return 0;
@@ -358,10 +358,10 @@ static int dwc_ether_rx(struct eth_device *dev)
 		length = (status & DESC_RXSTS_FRMLENMSK) >>
 			 DESC_RXSTS_FRMLENSHFT;
 
-		dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr,
+		dma_sync_single_for_cpu(desc_p->dmamac_addr,
 					length, DMA_FROM_DEVICE);
-		net_receive(dev, desc_p->dmamac_addr, length);
-		dma_sync_single_for_device((unsigned long)desc_p->dmamac_addr,
+		net_receive(dev, dmamac_addr(desc_p), length);
+		dma_sync_single_for_device(desc_p->dmamac_addr,
 					   length, DMA_FROM_DEVICE);
 		ret = length;
 	}
@@ -451,6 +451,8 @@ struct dw_eth_dev *dwc_drv_probe(struct device_d *dev)
 	int ret;
 	struct dw_eth_drvdata *drvdata;
 
+	dma_set_mask(dev, DMA_BIT_MASK(32));
+
 	priv = xzalloc(sizeof(struct dw_eth_dev));
 
 	ret = dev_get_drvdata(dev, (const void **)&drvdata);
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index ef3705b1e387..a085a6f16ad1 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -139,10 +139,12 @@ struct eth_dma_regs {
 struct dmamacdescr {
 	u32 txrx_status;
 	u32 dmamac_cntl;
-	void *dmamac_addr;
-	struct dmamacdescr *dmamac_next;
+	u32 dmamac_addr;
+	u32 dmamac_next;
 };
 
+#define dmamac_addr(descr) (phys_to_virt((descr)->dmamac_addr))
+
 /*
  * txrx_status definitions
  */
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 11/20] dma: support marking SRAM for coherent DMA use
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (9 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 10/20] net: designware: fix 64-bit incompatibilities Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-06-07  7:34   ` Sascha Hauer
  2021-06-07  7:39   ` Sascha Hauer
  2021-05-31  7:38 ` [PATCH 12/20] mci: allocate DMA-able memory Ahmad Fatoum
                   ` (8 subsequent siblings)
  19 siblings, 2 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The RISC-V architecture allows overriding the dma_alloc_coherent and
dma_free_coherent. Allow this to be controlled by device tree.

Cache-coherent SoCs won't need this, but incoherent ones that have
uncached regions can register them here.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 common/Kconfig              |   4 ++
 common/Makefile             |   3 +-
 drivers/dma/Kconfig         |   6 ++
 drivers/dma/Makefile        |   1 +
 drivers/dma/coherent-pool.c | 120 ++++++++++++++++++++++++++++++++++++
 5 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 drivers/dma/coherent-pool.c

diff --git a/common/Kconfig b/common/Kconfig
index ce349d4ebbf6..dbbcbb946fff 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -303,6 +303,9 @@ config EXPERIMENTAL
 	bool
 	prompt "Prompt for experimental code"
 
+config TLSF
+	bool
+
 choice
 	prompt "malloc implementation"
 
@@ -311,6 +314,7 @@ config MALLOC_DLMALLOC
 
 config MALLOC_TLSF
 	bool "tlsf"
+	select TLSF
 
 config MALLOC_DUMMY
 	bool "dummy malloc"
diff --git a/common/Makefile b/common/Makefile
index 382a4f661f67..0777d2030c99 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -40,7 +40,8 @@ obj-$(CONFIG_GLOBALVAR)		+= globalvar.o
 obj-$(CONFIG_GREGORIAN_CALENDER) += date.o
 obj-$(CONFIG_KALLSYMS)		+= kallsyms.o
 obj-$(CONFIG_MALLOC_DLMALLOC)	+= dlmalloc.o
-obj-$(CONFIG_MALLOC_TLSF)	+= tlsf_malloc.o tlsf.o calloc.o
+obj-$(CONFIG_TLSF)		+= tlsf.o
+obj-$(CONFIG_MALLOC_TLSF)	+= tlsf_malloc.o calloc.o
 KASAN_SANITIZE_tlsf.o := n
 obj-$(CONFIG_MALLOC_DUMMY)	+= dummy_malloc.o calloc.o
 obj-$(CONFIG_MEMINFO)		+= meminfo.o
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index c75fc8b9811f..6bc915585fbe 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -1,5 +1,11 @@
 menu "DMA support"
 
+config DMA_COHERENT_POOLS
+	bool
+	depends on RISCV
+	select TLSF
+	imply SRAM
+
 config MXS_APBH_DMA
 	tristate "MXS APBH DMA ENGINE"
 	depends on ARCH_IMX23 || ARCH_IMX28 || ARCH_IMX6
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 49d6d6573f4f..5503a4af0049 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_MXS_APBH_DMA)	+= apbh_dma.o
 obj-$(CONFIG_HAS_DMA)		+= map.o
+obj-$(CONFIG_DMA_COHERENT_POOLS)	+= coherent-pool.o
diff --git a/drivers/dma/coherent-pool.c b/drivers/dma/coherent-pool.c
new file mode 100644
index 000000000000..524283be711f
--- /dev/null
+++ b/drivers/dma/coherent-pool.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#define pr_fmt(fmt) "dma-coherent-pool: " fmt
+
+#include <common.h>
+#include <asm/dma.h>
+#include <linux/list.h>
+#include <errno.h>
+#include <tlsf.h>
+
+struct dma_coherent_pool {
+	tlsf_t handle;
+	const struct resource *resource;
+	struct list_head list;
+};
+
+static LIST_HEAD(pools);
+
+static void *pool_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+	struct dma_coherent_pool *pool;
+	void *ret = NULL;
+
+	list_for_each_entry(pool, &pools, list) {
+		ret = tlsf_memalign(pool->handle, DMA_ALIGNMENT, size);
+		if (!ret)
+			continue;
+	}
+
+	BUG_ON(!ret);
+
+	memset(ret, 0, size);
+
+	if (dma_handle)
+		*dma_handle = (dma_addr_t)ret;
+
+	pr_debug("alloc(%zu) == %p\n", size, ret);
+
+	return ret;
+}
+
+static void pool_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
+{
+	resource_size_t addr = (resource_size_t)vaddr;
+	struct dma_coherent_pool *pool;
+
+	list_for_each_entry(pool, &pools, list) {
+		if (pool->resource->start <= addr && addr <= pool->resource->end) {
+			tlsf_free(pool->handle, vaddr);
+			return;
+		}
+	}
+
+	pr_warn("freeing invalid region: %p\n", vaddr);
+}
+
+static const struct dma_coherent_ops pool_ops = {
+	.alloc = pool_alloc_coherent,
+	.free = pool_free_coherent,
+};
+
+static int compare_pool_sizes(struct list_head *_a, struct list_head *_b)
+{
+	struct dma_coherent_pool *a = list_entry(_a, struct dma_coherent_pool, list);
+	struct dma_coherent_pool *b = list_entry(_b, struct dma_coherent_pool, list);
+
+	if (resource_size(a->resource) > resource_size(b->resource))
+		return 1;
+	if (resource_size(a->resource) < resource_size(b->resource))
+		return -1;
+	return 0;
+}
+
+static int dma_declare_coherent_pool(const struct resource *res)
+{
+	struct dma_coherent_pool *pool;
+	tlsf_t handle;
+
+	handle = tlsf_create_with_pool((void *)res->start, resource_size(res));
+	if (!handle)
+		return -EINVAL;
+
+	pool = xmalloc(sizeof(*pool));
+	pool->handle = handle;
+	pool->resource = res;
+
+	list_add_sort(&pool->list, &pools, compare_pool_sizes);
+
+	dma_set_coherent_ops(&pool_ops);
+
+	pr_debug("registered pool @(%llx-%llx)\n", (u64)res->start, (u64)res->end);
+
+	return 0;
+}
+
+static int coherent_dma_pool_probe(struct device_d *dev)
+{
+	struct resource *res;
+
+	res = dev_get_resource(dev, IORESOURCE_MEM, 0);
+	if (IS_ERR(res))
+		return PTR_ERR(res);
+
+	return dma_declare_coherent_pool(res);
+}
+
+static struct of_device_id coherent_dma_pool_dt_ids[] = {
+	{ .compatible = "barebox,coherent-dma-pool", },
+	{ /* sentinel */ }
+};
+
+static struct driver_d coherent_dma_pool_driver = {
+	.name = "coherent-dma-pool",
+	.probe = coherent_dma_pool_probe,
+	.of_compatible = coherent_dma_pool_dt_ids,
+};
+coredevice_platform_driver(coherent_dma_pool_driver);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 12/20] mci: allocate DMA-able memory
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (10 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 11/20] dma: support marking SRAM for coherent DMA use Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 13/20] mci: allocate sector_buf on demand Ahmad Fatoum
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Doesn't yet make a difference, but in a future commit, RISC-V will use a
64-bit alignment for the sector buffers by defining a custom dma_alloc.

Prepare for this.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/mci/mci-core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index a160b9889459..70a8b971ca6d 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -21,6 +21,7 @@
 #include <of.h>
 #include <linux/err.h>
 #include <linux/sizes.h>
+#include <dma.h>
 
 #define MAX_BUFFER_NUMBER 0xffffffff
 
@@ -1851,7 +1852,7 @@ static int mci_set_probe(struct param_d *param, void *priv)
 
 static int mci_init(void)
 {
-	sector_buf = xmemalign(32, SECTOR_SIZE);
+	sector_buf = dma_alloc(SECTOR_SIZE);
 
 	return 0;
 }
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 13/20] mci: allocate sector_buf on demand
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (11 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 12/20] mci: allocate DMA-able memory Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 14/20] dma: allocate 32-byte aligned buffers by default Ahmad Fatoum
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The MCI core uses a common bounce buffer for unaligned block
reads/writes as well as sd_change_freq. This buffer is allocated at
device initcall level, same as the MMC drivers themselves.

For CONFIG_MCI_STARTUP=y configurations this seems to imply that
sd_change_freq could attempt writing the NULL page. Avoid this
by just allocating the buffer when the first MMC device is registered.

This doesn't solve all issues; so add a comment noting that.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/mci/mci-core.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 70a8b971ca6d..196fecdbd090 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1789,6 +1789,11 @@ static int mci_card_probe(struct mci *mci)
 		mci->cdevname = basprintf("disk%d", disknum);
 	}
 
+	if (!sector_buf)
+		sector_buf = dma_alloc(SECTOR_SIZE);
+
+	/* FIXME we don't check sector_buf against the device dma mask here */
+
 	rc = mci_startup(mci);
 	if (rc) {
 		dev_warn(&mci->dev, "Card's startup fails with %d\n", rc);
@@ -1850,15 +1855,6 @@ static int mci_set_probe(struct param_d *param, void *priv)
 	return 0;
 }
 
-static int mci_init(void)
-{
-	sector_buf = dma_alloc(SECTOR_SIZE);
-
-	return 0;
-}
-
-device_initcall(mci_init);
-
 int mci_detect_card(struct mci_host *host)
 {
 	int rc;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 14/20] dma: allocate 32-byte aligned buffers by default
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (12 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 13/20] mci: allocate sector_buf on demand Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 15/20] mci: dw_mmc: enable use on 64-bit CPUs Ahmad Fatoum
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

If dma_alloc() is really used for streaming-dma between cache-incoherent
masters, it should return cache-line aligned buffers, so we don't risk
invalidating shared cache lines. Bump up the default alignment to 32-bytes.

This doesn't affect ARM, as it defines its own implementation with
64-byte buffers.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 include/dma.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/dma.h b/include/dma.h
index 1b1cb3a40796..90f9254ea80f 100644
--- a/include/dma.h
+++ b/include/dma.h
@@ -8,6 +8,7 @@
 
 #include <malloc.h>
 #include <xfuncs.h>
+#include <linux/kernel.h>
 
 #include <dma-dir.h>
 #include <asm/dma.h>
@@ -15,10 +16,14 @@
 
 #define DMA_ADDRESS_BROKEN	NULL
 
+#ifndef DMA_ALIGNMENT
+#define DMA_ALIGNMENT	32
+#endif
+
 #ifndef dma_alloc
 static inline void *dma_alloc(size_t size)
 {
-	return xmalloc(size);
+	return xmemalign(DMA_ALIGNMENT, ALIGN(size, DMA_ALIGNMENT));
 }
 #endif
 
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 15/20] mci: dw_mmc: enable use on 64-bit CPUs
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (13 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 14/20] dma: allocate 32-byte aligned buffers by default Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 16/20] mci: dw_mmc: match against generic "snps, dw-mshc" compatible Ahmad Fatoum
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Provided that all DMA addresses can be safely truncated to 32-bit, the
driver is already usable on 64-bit CPUs. Silence the warnings and add
a check to ensure that coherent DMA addresses are indeed 32-bit.

arch code will need to make sure that dma_alloc() returns DMA memory
suitable for all DMA masters.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/mci/dw_mmc.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c
index 7979568841fc..db8aa9473458 100644
--- a/drivers/mci/dw_mmc.c
+++ b/drivers/mci/dw_mmc.c
@@ -124,12 +124,12 @@ static int dwmci_prepare_data_dma(struct dwmci_host *host,
 
 	dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
 
-	dwmci_writel(host, DWMCI_DBADDR, (uint32_t)desc);
+	dwmci_writel(host, DWMCI_DBADDR, virt_to_phys(desc));
 
 	if (data->flags & MMC_DATA_READ)
-		start_addr = (uint32_t)data->dest;
+		start_addr = virt_to_phys(data->dest);
 	else
-		start_addr = (uint32_t)data->src;
+		start_addr = virt_to_phys((void *)data->src);
 
 	do {
 		flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH;
@@ -145,7 +145,7 @@ static int dwmci_prepare_data_dma(struct dwmci_host *host,
 		desc->flags = flags;
 		desc->cnt = cnt;
 		desc->addr = start_addr + (i * PAGE_SIZE);
-		desc->next_addr = (uint32_t)(desc + 1);
+		desc->next_addr = virt_to_phys(desc + 1);
 
 		dev_dbg(host->mci.hw_dev, "desc@ 0x%p 0x%08x 0x%08x 0x%08x 0x%08x\n",
 				desc, flags, cnt, desc->addr, desc->next_addr);
@@ -290,10 +290,10 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
 		num_bytes = data->blocks * data->blocksize;
 
 		if (data->flags & MMC_DATA_WRITE)
-			dma_sync_single_for_device((unsigned long)data->src,
+			dma_sync_single_for_device(virt_to_phys((void *)data->src),
 						   num_bytes, DMA_TO_DEVICE);
 		else
-			dma_sync_single_for_device((unsigned long)data->dest,
+			dma_sync_single_for_device(virt_to_phys(data->dest),
 						   num_bytes, DMA_FROM_DEVICE);
 
 		ret = dwmci_prepare_data(host, data);
@@ -400,10 +400,10 @@ dwmci_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
 			dwmci_writel(host, DWMCI_CTRL, ctrl);
 
 			if (data->flags & MMC_DATA_WRITE)
-				dma_sync_single_for_cpu((unsigned long)data->src,
+				dma_sync_single_for_cpu(virt_to_phys((void *)data->src),
 							num_bytes, DMA_TO_DEVICE);
 			else
-				dma_sync_single_for_cpu((unsigned long)data->dest,
+				dma_sync_single_for_cpu(virt_to_phys(data->dest),
 							num_bytes, DMA_FROM_DEVICE);
 		}
 	}
@@ -547,6 +547,9 @@ static int dw_mmc_probe(struct device_d *dev)
 	struct resource *iores;
 	struct dwmci_host *host;
 	struct dw_mmc_platform_data *pdata = dev->platform_data;
+	dma_addr_t idmac;
+
+	dma_set_mask(dev, DMA_BIT_MASK(32));
 
 	host = xzalloc(sizeof(*host));
 
@@ -567,7 +570,12 @@ static int dw_mmc_probe(struct device_d *dev)
 	host->ioaddr = IOMEM(iores->start);
 
 	host->idmac = dma_alloc_coherent(sizeof(*host->idmac) * DW_MMC_NUM_IDMACS,
-					 DMA_ADDRESS_BROKEN);
+					 &idmac); /* still DMA_ADDRESS_BROKEN */
+
+	if (dma_mapping_error(dev, idmac)) {
+		dev_err(dev, "allocated buffer violates DMA mask\n");
+		return -ENOMEM;
+	}
 
 	host->mci.send_cmd = dwmci_cmd;
 	host->mci.set_ios = dwmci_set_ios;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 16/20] mci: dw_mmc: match against generic "snps, dw-mshc" compatible
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (14 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 15/20] mci: dw_mmc: enable use on 64-bit CPUs Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 17/20] clk: add initial StarFive clock support Ahmad Fatoum
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

So far, we only matched against instances of the DesignWare MMC
controller on Rockchip and Altera SoCs. Match against the generic
snps,dw-mshc compatible as well.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/mci/dw_mmc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c
index db8aa9473458..55f2d84a883d 100644
--- a/drivers/mci/dw_mmc.c
+++ b/drivers/mci/dw_mmc.c
@@ -623,6 +623,8 @@ static __maybe_unused struct of_device_id dw_mmc_compatible[] = {
 		.compatible = "rockchip,rk2928-dw-mshc",
 	}, {
 		.compatible = "rockchip,rk3288-dw-mshc",
+	}, {
+		.compatible = "snps,dw-mshc",
 	}, {
 		/* sentinel */
 	}
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 17/20] clk: add initial StarFive clock support
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (15 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 16/20] mci: dw_mmc: match against generic "snps, dw-mshc" compatible Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  8:41   ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 18/20] reset: add StarFive reset controller driver Ahmad Fatoum
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

All clocks seem to share a common format:

 struct starfive_clk {
	u32 divisor : 24;
	u32 mux : 6;
	u32 invert : 1;
	u32 enable : 1;
 };

There is no documentation, what the acceptable divisor values are, but
we could already register gates and muxes, do so for now until
documentation is available.

The bulk of this code has been machine-generated by parsing the macros
in the vendor U-Boot <asm/arch-vic7100/clkgen_ctrl_macro.h>.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/clk/Makefile                        |   1 +
 drivers/clk/starfive/Makefile               |   3 +
 drivers/clk/starfive/clk.h                  |  64 ++++
 drivers/clk/starfive/jh7100-clkgen.c        | 363 ++++++++++++++++++++
 include/dt-bindings/clock/starfive-jh7100.h | 203 +++++++++++
 5 files changed, 634 insertions(+)
 create mode 100644 drivers/clk/starfive/Makefile
 create mode 100644 drivers/clk/starfive/clk.h
 create mode 100644 drivers/clk/starfive/jh7100-clkgen.c
 create mode 100644 include/dt-bindings/clock/starfive-jh7100.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index b0be8d1bd89a..499df2fe392b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_MACH_MIPS_LOONGSON)+= loongson/
 obj-$(CONFIG_ARCH_LAYERSCAPE)	+= clk-qoric.o
 obj-y				+= analogbits/
 obj-$(CONFIG_CLK_SIFIVE)	+= sifive/
+obj-$(CONFIG_SOC_STARFIVE)	+= starfive/
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
new file mode 100644
index 000000000000..7e4104993580
--- /dev/null
+++ b/drivers/clk/starfive/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SOC_STARFIVE_JH7100) += jh7100-clkgen.o
diff --git a/drivers/clk/starfive/clk.h b/drivers/clk/starfive/clk.h
new file mode 100644
index 000000000000..cfbf116dcb78
--- /dev/null
+++ b/drivers/clk/starfive/clk.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef STARFIVE_CLK_H_
+#define STARFIVE_CLK_H_
+
+#include <linux/clk.h>
+
+#define STARFIVE_CLK_ENABLE_SHIFT	31
+#define STARFIVE_CLK_INVERT_SHIFT	30
+#define STARFIVE_CLK_MUX_SHIFT		24
+
+static inline struct clk *starfive_clk_underspecifid(const char *name, const char *parent)
+{
+	/*
+	 * TODO With documentation available, all users of this functions can be
+	 * migrated to one of the above or to a clk_fixed_factor with
+	 * appropriate factor
+	 */
+	return clk_fixed_factor(name, parent, 1, 1, 0);
+}
+
+static inline struct clk *starfive_clk_divider(const char *name, const char *parent,
+		void __iomem *reg, u8 width)
+{
+	return starfive_clk_underspecifid(name, parent);
+}
+
+static inline struct clk *starfive_clk_gate(const char *name, const char *parent,
+		void __iomem *reg)
+{
+	return clk_gate(name, parent, reg, STARFIVE_CLK_ENABLE_SHIFT, CLK_SET_RATE_PARENT, 0);
+}
+
+static inline struct clk *starfive_clk_divider_table(const char *name,
+		const char *parent, void __iomem *reg, u8 width,
+		const struct clk_div_table *table)
+{
+	return clk_divider_table(name, parent, CLK_SET_RATE_PARENT, reg, 0,
+				 width, table, 0);
+}
+
+static inline struct clk *starfive_clk_gated_divider(const char *name,
+		const char *parent, void __iomem *reg, u8 width)
+{
+	/* TODO divider part */
+	return clk_gate(name, parent, reg, STARFIVE_CLK_ENABLE_SHIFT, CLK_SET_RATE_PARENT, 0);
+}
+
+static inline struct clk *starfive_clk_gate_dis(const char *name, const char *parent,
+		void __iomem *reg)
+{
+	return clk_gate_inverted(name, parent, reg, STARFIVE_CLK_INVERT_SHIFT, CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *starfive_clk_mux(const char *name, void __iomem *reg,
+		u8 width, const char * const *parents, u8 num_parents)
+{
+	return clk_mux(name, 0, reg, STARFIVE_CLK_MUX_SHIFT, width, parents, num_parents, 0);
+}
+
+#endif
diff --git a/drivers/clk/starfive/jh7100-clkgen.c b/drivers/clk/starfive/jh7100-clkgen.c
new file mode 100644
index 000000000000..df5353e8e624
--- /dev/null
+++ b/drivers/clk/starfive/jh7100-clkgen.c
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <dt-bindings/clock/starfive-jh7100.h>
+
+#include "clk.h"
+
+
+static const char *cpundbus_root_sels[4] = {
+	[0] = "osc_sys",
+	[1] = "pll0_out",
+	[2] = "pll1_out",
+	[3] = "pll2_out",
+};
+
+static const char *dla_root_sels[4] = {
+	[0] = "osc_sys",
+	[1] = "pll1_out",
+	[2] = "pll2_out",
+	[3] = "dummy",
+};
+
+static const char *dsp_root_sels[4] = {
+	[0] = "osc_sys",
+	[1] = "pll0_out",
+	[2] = "pll1_out",
+	[3] = "pll2_out",
+};
+
+static const char *gmacusb_root_sels[4] = {
+	[0] = "osc_sys",
+	[1] = "pll0_out",
+	[2] = "pll2_out",
+	[3] = "dummy",
+};
+
+static const char *perh0_root_sels[2] = {
+	[0] = "osc_sys",
+	[1] = "pll0_out",
+};
+
+static const char *perh1_root_sels[2] = {
+	[0] = "osc_sys",
+	[1] = "pll2_out",
+};
+
+static const char *vin_root_sels[4] = {
+	[0] = "osc_sys",
+	[1] = "pll1_out",
+	[2] = "pll2_out",
+	[3] = "dummy",
+};
+
+static const char *vout_root_sels[4] = {
+	[0] = "osc_aud",
+	[1] = "pll0_out",
+	[2] = "pll2_out",
+	[3] = "dummy",
+};
+
+static const char *cdechifi4_root_sels[4] = {
+	[0] = "osc_sys",
+	[1] = "pll1_out",
+	[2] = "pll2_out",
+	[3] = "dummy",
+};
+
+static const char *cdec_root_sels[4] = {
+	[0] = "osc_sys",
+	[1] = "pll0_out",
+	[2] = "pll1_out",
+	[3] = "dummy",
+};
+
+static const char *voutbus_root_sels[4] = {
+	[0] = "osc_aud",
+	[1] = "pll0_out",
+	[2] = "pll2_out",
+	[3] = "dummy",
+};
+
+static const char *pll2_refclk_sels[2] = {
+	[0] = "osc_sys",
+	[1] = "osc_aud",
+};
+
+static const char *ddrc0_sels[4] = {
+	[0] = "ddrosc_div2",
+	[1] = "ddrpll_div2",
+	[2] = "ddrpll_div4",
+	[3] = "ddrpll_div8",
+};
+
+static const char *ddrc1_sels[4] = {
+	[0] = "ddrosc_div2",
+	[1] = "ddrpll_div2",
+	[2] = "ddrpll_div4",
+	[3] = "ddrpll_div8",
+};
+
+static const char *nne_bus_sels[2] = {
+	[0] = "cpu_axi",
+	[1] = "nnebus_src1",
+};
+
+static const char *usbphy_25m_sels[2] = {
+	[0] = "osc_sys",
+	[1] = "usbphy_plldiv25m",
+};
+
+static const char *gmac_tx_sels[4] = {
+	[0] = "gmac_gtxclk",
+	[1] = "gmac_mii_txclk",
+	[2] = "gmac_rmii_txclk",
+	[3] = "dummy",
+};
+
+static const char *gmac_rx_pre_sels[2] = {
+	[0] = "gmac_gr_mii_rxclk",
+	[1] = "gmac_rmii_rxclk",
+};
+
+static struct clk *clks[CLK_END];
+
+/* assume osc_sys as direct parent for clocks of yet unknown lineage */
+#define UNKNOWN "osc_sys"
+
+static void starfive_clkgen_init(struct device_node *np, void __iomem *base)
+{
+	clks[CLK_OSC_SYS]		= of_clk_get_by_name(np, "osc_sys");
+	clks[CLK_OSC_AUD]		= of_clk_get_by_name(np, "osc_aud");
+	clks[CLK_PLL0_OUT]		= starfive_clk_underspecifid("pll0_out", "osc_sys");
+	clks[CLK_PLL1_OUT]		= starfive_clk_underspecifid("pll1_out", "osc_sys");
+	clks[CLK_PLL2_OUT]		= starfive_clk_underspecifid("pll2_out", "pll2_refclk");
+	clks[CLK_CPUNDBUS_ROOT]		= starfive_clk_mux("cpundbus_root", base + 0x0, 2, cpundbus_root_sels, ARRAY_SIZE(cpundbus_root_sels));
+	clks[CLK_DLA_ROOT]		= starfive_clk_mux("dla_root",	base + 0x4, 2, dla_root_sels, ARRAY_SIZE(dla_root_sels));
+	clks[CLK_DSP_ROOT]		= starfive_clk_mux("dsp_root",	base + 0x8, 2, dsp_root_sels, ARRAY_SIZE(dsp_root_sels));
+	clks[CLK_GMACUSB_ROOT]		= starfive_clk_mux("gmacusb_root",	base + 0xC, 2, gmacusb_root_sels, ARRAY_SIZE(gmacusb_root_sels));
+	clks[CLK_PERH0_ROOT]		= starfive_clk_mux("perh0_root",	base + 0x10, 1, perh0_root_sels, ARRAY_SIZE(perh0_root_sels));
+	clks[CLK_PERH1_ROOT]		= starfive_clk_mux("perh1_root",	base + 0x14, 1, perh1_root_sels, ARRAY_SIZE(perh1_root_sels));
+	clks[CLK_VIN_ROOT]		= starfive_clk_mux("vin_root",	base + 0x18, 2, vin_root_sels, ARRAY_SIZE(vin_root_sels));
+	clks[CLK_VOUT_ROOT]		= starfive_clk_mux("vout_root",	base + 0x1C, 2, vout_root_sels, ARRAY_SIZE(vout_root_sels));
+	clks[CLK_AUDIO_ROOT]		= starfive_clk_gated_divider("audio_root",		UNKNOWN,	base + 0x20, 4);
+	clks[CLK_CDECHIFI4_ROOT]	= starfive_clk_mux("cdechifi4_root",	base + 0x24, 2, cdechifi4_root_sels, ARRAY_SIZE(cdechifi4_root_sels));
+	clks[CLK_CDEC_ROOT]		= starfive_clk_mux("cdec_root",	base + 0x28, 2, cdec_root_sels, ARRAY_SIZE(cdec_root_sels));
+	clks[CLK_VOUTBUS_ROOT]		= starfive_clk_mux("voutbus_root",	base + 0x2C, 2, voutbus_root_sels, ARRAY_SIZE(voutbus_root_sels));
+	clks[CLK_CPUNBUS_ROOT_DIV]	= starfive_clk_divider("cpunbus_root_div",		"cpunbus_root",	base + 0x30, 2);
+	clks[CLK_DSP_ROOT_DIV]		= starfive_clk_divider("dsp_root_div",		"dsp_root",	base + 0x34, 3);
+	clks[CLK_PERH0_SRC]		= starfive_clk_divider("perh0_src",		"perh0_root",	base + 0x38, 3);
+	clks[CLK_PERH1_SRC]		= starfive_clk_divider("perh1_src",		"perh1_root",	base + 0x3C, 3);
+	clks[CLK_PLL0_TESTOUT]		= starfive_clk_gated_divider("pll0_testout",		"pll0_out",	base + 0x40, 5);
+	clks[CLK_PLL1_TESTOUT]		= starfive_clk_gated_divider("pll1_testout",		"pll1_out",	base + 0x44, 5);
+	clks[CLK_PLL2_TESTOUT]		= starfive_clk_gated_divider("pll2_testout",		"pll2_out",	base + 0x48, 5);
+	clks[CLK_PLL2_REF]		= starfive_clk_mux("pll2_refclk",	base + 0x4C, 1, pll2_refclk_sels, ARRAY_SIZE(pll2_refclk_sels));
+	clks[CLK_CPU_CORE]		= starfive_clk_divider("cpu_core",		UNKNOWN,	base + 0x50, 4);
+	clks[CLK_CPU_AXI]		= starfive_clk_divider("cpu_axi",		UNKNOWN,	base + 0x54, 4);
+	clks[CLK_AHB_BUS]		= starfive_clk_divider("ahb_bus",		UNKNOWN,	base + 0x58, 4);
+	clks[CLK_APB1_BUS]		= starfive_clk_divider("apb1_bus",		UNKNOWN,	base + 0x5C, 4);
+	clks[CLK_APB2_BUS]		= starfive_clk_divider("apb2_bus",		UNKNOWN,	base + 0x60, 4);
+	clks[CLK_DOM3AHB_BUS]		= starfive_clk_gate("dom3ahb_bus",		UNKNOWN,	base + 0x64);
+	clks[CLK_DOM7AHB_BUS]		= starfive_clk_gate("dom7ahb_bus",		UNKNOWN,	base + 0x68);
+	clks[CLK_U74_CORE0]		= starfive_clk_gate("u74_core0",		UNKNOWN,	base + 0x6C);
+	clks[CLK_U74_CORE1]		= starfive_clk_gated_divider("u74_core1",		"",	base + 0x70, 4);
+	clks[CLK_U74_AXI]		= starfive_clk_gate("u74_axi",		UNKNOWN,	base + 0x74);
+	clks[CLK_U74RTC_TOGGLE]		= starfive_clk_gate("u74rtc_toggle",		UNKNOWN,	base + 0x78);
+	clks[CLK_SGDMA2P_AXI]		= starfive_clk_gate("sgdma2p_axi",		UNKNOWN,	base + 0x7C);
+	clks[CLK_DMA2PNOC_AXI]		= starfive_clk_gate("dma2pnoc_axi",		UNKNOWN,	base + 0x80);
+	clks[CLK_SGDMA2P_AHB]		= starfive_clk_gate("sgdma2p_ahb",		UNKNOWN,	base + 0x84);
+	clks[CLK_DLA_BUS]		= starfive_clk_divider("dla_bus",		UNKNOWN,	base + 0x88, 3);
+	clks[CLK_DLA_AXI]		= starfive_clk_gate("dla_axi",		UNKNOWN,	base + 0x8C);
+	clks[CLK_DLANOC_AXI]		= starfive_clk_gate("dlanoc_axi",		UNKNOWN,	base + 0x90);
+	clks[CLK_DLA_APB]		= starfive_clk_gate("dla_apb",		UNKNOWN,	base + 0x94);
+	clks[CLK_VP6_CORE]		= starfive_clk_gated_divider("vp6_core",		UNKNOWN,	base + 0x98, 3);
+	clks[CLK_VP6BUS_SRC]		= starfive_clk_divider("vp6bus_src",		UNKNOWN,	base + 0x9C, 3);
+	clks[CLK_VP6_AXI]		= starfive_clk_gated_divider("vp6_axi",		UNKNOWN,	base + 0xA0, 3);
+	clks[CLK_VCDECBUS_SRC]		= starfive_clk_divider("vcdecbus_src",		UNKNOWN,	base + 0xA4, 3);
+	clks[CLK_VDEC_BUS]		= starfive_clk_divider("vdec_bus",		UNKNOWN,	base + 0xA8, 4);
+	clks[CLK_VDEC_AXI]		= starfive_clk_gate("vdec_axi",		UNKNOWN,	base + 0xAC);
+	clks[CLK_VDECBRG_MAIN]		= starfive_clk_gate("vdecbrg_mainclk",		UNKNOWN,	base + 0xB0);
+	clks[CLK_VDEC_BCLK]		= starfive_clk_gated_divider("vdec_bclk",		UNKNOWN,	base + 0xB4, 4);
+	clks[CLK_VDEC_CCLK]		= starfive_clk_gated_divider("vdec_cclk",		UNKNOWN,	base + 0xB8, 4);
+	clks[CLK_VDEC_APB]		= starfive_clk_gate("vdec_apb",		UNKNOWN,	base + 0xBC);
+	clks[CLK_JPEG_AXI]		= starfive_clk_gated_divider("jpeg_axi",		UNKNOWN,	base + 0xC0, 4);
+	clks[CLK_JPEG_CCLK]		= starfive_clk_gated_divider("jpeg_cclk",		UNKNOWN,	base + 0xC4, 4);
+	clks[CLK_JPEG_APB]		= starfive_clk_gate("jpeg_apb",		UNKNOWN,	base + 0xC8);
+	clks[CLK_GC300_2X]		= starfive_clk_gated_divider("gc300_2x",		UNKNOWN,	base + 0xCC, 4);
+	clks[CLK_GC300_AHB]		= starfive_clk_gate("gc300_ahb",		UNKNOWN,	base + 0xD0);
+	clks[CLK_JPCGC300_AXIBUS]	= starfive_clk_divider("jpcgc300_axibus",		UNKNOWN,	base + 0xD4, 4);
+	clks[CLK_GC300_AXI]		= starfive_clk_gate("gc300_axi",		UNKNOWN,	base + 0xD8);
+	clks[CLK_JPCGC300_MAIN]		= starfive_clk_gate("jpcgc300_mainclk",		UNKNOWN,	base + 0xDC);
+	clks[CLK_VENC_BUS]		= starfive_clk_divider("venc_bus",		UNKNOWN,	base + 0xE0, 4);
+	clks[CLK_VENC_AXI]		= starfive_clk_gate("venc_axi",		UNKNOWN,	base + 0xE4);
+	clks[CLK_VENCBRG_MAIN]		= starfive_clk_gate("vencbrg_mainclk",		UNKNOWN,	base + 0xE8);
+	clks[CLK_VENC_BCLK]		= starfive_clk_gated_divider("venc_bclk",		UNKNOWN,	base + 0xEC, 4);
+	clks[CLK_VENC_CCLK]		= starfive_clk_gated_divider("venc_cclk",		UNKNOWN,	base + 0xF0, 4);
+	clks[CLK_VENC_APB]		= starfive_clk_gate("venc_apb",		UNKNOWN,	base + 0xF4);
+	clks[CLK_DDRPLL_DIV2]		= starfive_clk_gated_divider("ddrpll_div2",		UNKNOWN,	base + 0xF8, 2);
+	clks[CLK_DDRPLL_DIV4]		= starfive_clk_gated_divider("ddrpll_div4",		UNKNOWN,	base + 0xFC, 2);
+	clks[CLK_DDRPLL_DIV8]		= starfive_clk_gated_divider("ddrpll_div8",		UNKNOWN,	base + 0x100, 2);
+	clks[CLK_DDROSC_DIV2]		= starfive_clk_gated_divider("ddrosc_div2",		UNKNOWN,	base + 0x104, 2);
+	clks[CLK_DDRC0]			= starfive_clk_mux("ddrc0",	base + 0x108, 2, ddrc0_sels, ARRAY_SIZE(ddrc0_sels));
+	clks[CLK_DDRC1]			= starfive_clk_mux("ddrc1",	base + 0x10C, 2, ddrc1_sels, ARRAY_SIZE(ddrc1_sels));
+	clks[CLK_DDRPHY_APB]		= starfive_clk_gate("ddrphy_apb",		UNKNOWN,	base + 0x110);
+	clks[CLK_NOC_ROB]		= starfive_clk_divider("noc_rob",		UNKNOWN,	base + 0x114, 4);
+	clks[CLK_NOC_COG]		= starfive_clk_divider("noc_cog",		UNKNOWN,	base + 0x118, 4);
+	clks[CLK_NNE_AHB]		= starfive_clk_gate("nne_ahb",		UNKNOWN,	base + 0x11C);
+	clks[CLK_NNEBUS_SRC1]		= starfive_clk_divider("nnebus_src1",		UNKNOWN,	base + 0x120, 3);
+	clks[CLK_NNE_BUS]		= starfive_clk_mux("nne_bus",	base + 0x124, 2, nne_bus_sels, ARRAY_SIZE(nne_bus_sels));
+	clks[CLK_NNE_AXI]		= starfive_clk_gate("nne_axi",	UNKNOWN, base + 0x128);
+	clks[CLK_NNENOC_AXI]		= starfive_clk_gate("nnenoc_axi",		UNKNOWN,	base + 0x12C);
+	clks[CLK_DLASLV_AXI]		= starfive_clk_gate("dlaslv_axi",		UNKNOWN,	base + 0x130);
+	clks[CLK_DSPX2C_AXI]		= starfive_clk_gate("dspx2c_axi",		UNKNOWN,	base + 0x134);
+	clks[CLK_HIFI4_SRC]		= starfive_clk_divider("hifi4_src",		UNKNOWN,	base + 0x138, 3);
+	clks[CLK_HIFI4_COREFREE]	= starfive_clk_divider("hifi4_corefree",		UNKNOWN,	base + 0x13C, 4);
+	clks[CLK_HIFI4_CORE]		= starfive_clk_gate("hifi4_core",		UNKNOWN,	base + 0x140);
+	clks[CLK_HIFI4_BUS]		= starfive_clk_divider("hifi4_bus",		UNKNOWN,	base + 0x144, 4);
+	clks[CLK_HIFI4_AXI]		= starfive_clk_gate("hifi4_axi",		UNKNOWN,	base + 0x148);
+	clks[CLK_HIFI4NOC_AXI]		= starfive_clk_gate("hifi4noc_axi",		UNKNOWN,	base + 0x14C);
+	clks[CLK_SGDMA1P_BUS]		= starfive_clk_divider("sgdma1p_bus",		UNKNOWN,	base + 0x150, 4);
+	clks[CLK_SGDMA1P_AXI]		= starfive_clk_gate("sgdma1p_axi",		UNKNOWN,	base + 0x154);
+	clks[CLK_DMA1P_AXI]		= starfive_clk_gate("dma1p_axi",		UNKNOWN,	base + 0x158);
+	clks[CLK_X2C_AXI]		= starfive_clk_gated_divider("x2c_axi",		UNKNOWN,	base + 0x15C, 4);
+	clks[CLK_USB_BUS]		= starfive_clk_divider("usb_bus",		UNKNOWN,	base + 0x160, 4);
+	clks[CLK_USB_AXI]		= starfive_clk_gate("usb_axi",		UNKNOWN,	base + 0x164);
+	clks[CLK_USBNOC_AXI]		= starfive_clk_gate("usbnoc_axi",		UNKNOWN,	base + 0x168);
+	clks[CLK_USBPHY_ROOTDIV]	= starfive_clk_divider("usbphy_rootdiv",		UNKNOWN,	base + 0x16C, 3);
+	clks[CLK_USBPHY_125M]		= starfive_clk_gated_divider("usbphy_125m",		UNKNOWN,	base + 0x170, 4);
+	clks[CLK_USBPHY_PLLDIV25M]	= starfive_clk_gated_divider("usbphy_plldiv25m",		UNKNOWN,	base + 0x174, 6);
+	clks[CLK_USBPHY_25M]		= starfive_clk_mux("usbphy_25m",	base + 0x178, 1, usbphy_25m_sels, ARRAY_SIZE(usbphy_25m_sels));
+	clks[CLK_AUDIO_DIV]		= starfive_clk_divider("audio_div",		UNKNOWN,	base + 0x17C, 18);
+	clks[CLK_AUDIO_SRC]		= starfive_clk_gate("audio_src",		UNKNOWN,	base + 0x180);
+	clks[CLK_AUDIO_12288]		= starfive_clk_gate("audio_12288",		UNKNOWN,	base + 0x184);
+	clks[CLK_VIN_SRC]		= starfive_clk_gated_divider("vin_src",		UNKNOWN,	base + 0x188, 3);
+	clks[CLK_ISP0_BUS]		= starfive_clk_divider("isp0_bus",		UNKNOWN,	base + 0x18C, 4);
+	clks[CLK_ISP0_AXI]		= starfive_clk_gate("isp0_axi",		UNKNOWN,	base + 0x190);
+	clks[CLK_ISP0NOC_AXI]		= starfive_clk_gate("isp0noc_axi",		UNKNOWN,	base + 0x194);
+	clks[CLK_ISPSLV_AXI]		= starfive_clk_gate("ispslv_axi",		UNKNOWN,	base + 0x198);
+	clks[CLK_ISP1_BUS]		= starfive_clk_divider("isp1_bus",		UNKNOWN,	base + 0x19C, 4);
+	clks[CLK_ISP1_AXI]		= starfive_clk_gate("isp1_axi",		UNKNOWN,	base + 0x1A0);
+	clks[CLK_ISP1NOC_AXI]		= starfive_clk_gate("isp1noc_axi",		UNKNOWN,	base + 0x1A4);
+	clks[CLK_VIN_BUS]		= starfive_clk_divider("vin_bus",		UNKNOWN,	base + 0x1A8, 4);
+	clks[CLK_VIN_AXI]		= starfive_clk_gate("vin_axi",		UNKNOWN,	base + 0x1AC);
+	clks[CLK_VINNOC_AXI]		= starfive_clk_gate("vinnoc_axi",		UNKNOWN,	base + 0x1B0);
+	clks[CLK_VOUT_SRC]		= starfive_clk_gated_divider("vout_src",		UNKNOWN,	base + 0x1B4, 3);
+	clks[CLK_DISPBUS_SRC]		= starfive_clk_divider("dispbus_src",		UNKNOWN,	base + 0x1B8, 3);
+	clks[CLK_DISP_BUS]		= starfive_clk_divider("disp_bus",		UNKNOWN,	base + 0x1BC, 3);
+	clks[CLK_DISP_AXI]		= starfive_clk_gate("disp_axi",		UNKNOWN,	base + 0x1C0);
+	clks[CLK_DISPNOC_AXI]		= starfive_clk_gate("dispnoc_axi",		UNKNOWN,	base + 0x1C4);
+	clks[CLK_SDIO0_AHB]		= starfive_clk_gate("sdio0_ahb",		UNKNOWN,	base + 0x1C8);
+	clks[CLK_SDIO0_CCLKINT]		= starfive_clk_gated_divider("sdio0_cclkint",		UNKNOWN,	base + 0x1CC, 5);
+	clks[CLK_SDIO0_CCLKINT_INV]	= starfive_clk_gate_dis("sdio0_cclkint_inv",		UNKNOWN,	base + 0x1D0);
+	clks[CLK_SDIO1_AHB]		= starfive_clk_gate("sdio1_ahb",		UNKNOWN,	base + 0x1D4);
+	clks[CLK_SDIO1_CCLKINT]		= starfive_clk_gated_divider("sdio1_cclkint",		UNKNOWN,	base + 0x1D8, 5);
+	clks[CLK_SDIO1_CCLKINT_INV]	= starfive_clk_gate_dis("sdio1_cclkint_inv",		UNKNOWN,	base + 0x1DC);
+	clks[CLK_GMAC_AHB]		= starfive_clk_gate("gmac_ahb",		UNKNOWN,	base + 0x1E0);
+	clks[CLK_GMAC_ROOT_DIV]		= starfive_clk_divider("gmac_root_div",		UNKNOWN,	base + 0x1E4, 4);
+	clks[CLK_GMAC_PTP_REF]		= starfive_clk_gated_divider("gmac_ptp_refclk",		UNKNOWN,	base + 0x1E8, 5);
+	clks[CLK_GMAC_GTX]		= starfive_clk_gated_divider("gmac_gtxclk",		UNKNOWN,	base + 0x1EC, 8);
+	clks[CLK_GMAC_RMII_TX]		= starfive_clk_gated_divider("gmac_rmii_txclk",		UNKNOWN,	base + 0x1F0, 4);
+	clks[CLK_GMAC_RMII_RX]		= starfive_clk_gated_divider("gmac_rmii_rxclk",		UNKNOWN,	base + 0x1F4, 4);
+	clks[CLK_GMAC_TX]		= starfive_clk_mux("gmac_tx",	base + 0x1F8, 2, gmac_tx_sels, ARRAY_SIZE(gmac_tx_sels));
+	clks[CLK_GMAC_TX_INV]		= starfive_clk_gate_dis("gmac_tx_inv",		UNKNOWN,	base + 0x1FC);
+	clks[CLK_GMAC_RX_PRE]		= starfive_clk_mux("gmac_rx_pre",	base + 0x200, 1, gmac_rx_pre_sels, ARRAY_SIZE(gmac_rx_pre_sels));
+	clks[CLK_GMAC_RX_INV]		= starfive_clk_gate_dis("gmac_rx_inv",		UNKNOWN,	base + 0x204);
+	clks[CLK_GMAC_RMII]		= starfive_clk_gate("gmac_rmii",		UNKNOWN,	base + 0x208);
+	clks[CLK_GMAC_TOPHYREF]		= starfive_clk_gated_divider("gmac_tophyref",		UNKNOWN,	base + 0x20C, 7);
+	clks[CLK_SPI2AHB_AHB]		= starfive_clk_gate("spi2ahb_ahb",		UNKNOWN,	base + 0x210);
+	clks[CLK_SPI2AHB_CORE]		= starfive_clk_gated_divider("spi2ahb_core",		UNKNOWN,	base + 0x214, 5);
+	clks[CLK_EZMASTER_AHB]		= starfive_clk_gate("ezmaster_ahb",		UNKNOWN,	base + 0x218);
+	clks[CLK_E24_AHB]		= starfive_clk_gate("e24_ahb",		UNKNOWN,	base + 0x21C);
+	clks[CLK_E24RTC_TOGGLE]		= starfive_clk_gate("e24rtc_toggle",		UNKNOWN,	base + 0x220);
+	clks[CLK_QSPI_AHB]		= starfive_clk_gate("qspi_ahb",		UNKNOWN,	base + 0x224);
+	clks[CLK_QSPI_APB]		= starfive_clk_gate("qspi_apb",		UNKNOWN,	base + 0x228);
+	clks[CLK_QSPI_REF]		= starfive_clk_gated_divider("qspi_refclk",		UNKNOWN,	base + 0x22C, 5);
+	clks[CLK_SEC_AHB]		= starfive_clk_gate("sec_ahb",		UNKNOWN,	base + 0x230);
+	clks[CLK_AES]			= starfive_clk_gate("aes_clk",		UNKNOWN,	base + 0x234);
+	clks[CLK_SHA]			= starfive_clk_gate("sha_clk",		UNKNOWN,	base + 0x238);
+	clks[CLK_PKA]			= starfive_clk_gate("pka_clk",		UNKNOWN,	base + 0x23C);
+	clks[CLK_TRNG_APB]		= starfive_clk_gate("trng_apb",		UNKNOWN,	base + 0x240);
+	clks[CLK_OTP_APB]		= starfive_clk_gate("otp_apb",		UNKNOWN,	base + 0x244);
+	clks[CLK_UART0_APB]		= starfive_clk_gate("uart0_apb",		UNKNOWN,	base + 0x248);
+	clks[CLK_UART0_CORE]		= starfive_clk_gated_divider("uart0_core",		UNKNOWN,	base + 0x24C, 6);
+	clks[CLK_UART1_APB]		= starfive_clk_gate("uart1_apb",		UNKNOWN,	base + 0x250);
+	clks[CLK_UART1_CORE]		= starfive_clk_gated_divider("uart1_core",		UNKNOWN,	base + 0x254, 6);
+	clks[CLK_SPI0_APB]		= starfive_clk_gate("spi0_apb",		UNKNOWN,	base + 0x258);
+	clks[CLK_SPI0_CORE]		= starfive_clk_gated_divider("spi0_core",		UNKNOWN,	base + 0x25C, 6);
+	clks[CLK_SPI1_APB]		= starfive_clk_gate("spi1_apb",		UNKNOWN,	base + 0x260);
+	clks[CLK_SPI1_CORE]		= starfive_clk_gated_divider("spi1_core",		UNKNOWN,	base + 0x264, 6);
+	clks[CLK_I2C0_APB]		= starfive_clk_gate("i2c0_apb",		UNKNOWN,	base + 0x268);
+	clks[CLK_I2C0_CORE]		= starfive_clk_gated_divider("i2c0_core",		UNKNOWN,	base + 0x26C, 6);
+	clks[CLK_I2C1_APB]		= starfive_clk_gate("i2c1_apb",		UNKNOWN,	base + 0x270);
+	clks[CLK_I2C1_CORE]		= starfive_clk_gated_divider("i2c1_core",		UNKNOWN,	base + 0x274, 6);
+	clks[CLK_GPIO_APB]		= starfive_clk_gate("gpio_apb",		UNKNOWN,	base + 0x278);
+	clks[CLK_UART2_APB]		= starfive_clk_gate("uart2_apb",		UNKNOWN,	base + 0x27C);
+	clks[CLK_UART2_CORE]		= starfive_clk_gated_divider("uart2_core",		UNKNOWN,	base + 0x280, 6);
+	clks[CLK_UART3_APB]		= starfive_clk_gate("uart3_apb",		UNKNOWN,	base + 0x284);
+	clks[CLK_UART3_CORE]		= starfive_clk_gated_divider("uart3_core",		UNKNOWN,	base + 0x288, 6);
+	clks[CLK_SPI2_APB]		= starfive_clk_gate("spi2_apb",		UNKNOWN,	base + 0x28C);
+	clks[CLK_SPI2_CORE]		= starfive_clk_gated_divider("spi2_core",		UNKNOWN,	base + 0x290, 6);
+	clks[CLK_SPI3_APB]		= starfive_clk_gate("spi3_apb",		UNKNOWN,	base + 0x294);
+	clks[CLK_SPI3_CORE]		= starfive_clk_gated_divider("spi3_core",		UNKNOWN,	base + 0x298, 6);
+	clks[CLK_I2C2_APB]		= starfive_clk_gate("i2c2_apb",		UNKNOWN,	base + 0x29C);
+	clks[CLK_I2C2_CORE]		= starfive_clk_gated_divider("i2c2_core",		UNKNOWN,	base + 0x2A0, 6);
+	clks[CLK_I2C3_APB]		= starfive_clk_gate("i2c3_apb",		UNKNOWN,	base + 0x2A4);
+	clks[CLK_I2C3_CORE]		= starfive_clk_gated_divider("i2c3_core",		UNKNOWN,	base + 0x2A8, 6);
+	clks[CLK_WDTIMER_APB]		= starfive_clk_gate("wdtimer_apb",		UNKNOWN,	base + 0x2AC);
+	clks[CLK_WDT_CORE]		= starfive_clk_gated_divider("wdt_coreclk",		UNKNOWN,	base + 0x2B0, 6);
+	clks[CLK_TIMER0_CORE]		= starfive_clk_gated_divider("timer0_coreclk",		UNKNOWN,	base + 0x2B4, 6);
+	clks[CLK_TIMER1_CORE]		= starfive_clk_gated_divider("timer1_coreclk",		UNKNOWN,	base + 0x2B8, 6);
+	clks[CLK_TIMER2_CORE]		= starfive_clk_gated_divider("timer2_coreclk",		UNKNOWN,	base + 0x2BC, 6);
+	clks[CLK_TIMER3_CORE]		= starfive_clk_gated_divider("timer3_coreclk",		UNKNOWN,	base + 0x2C0, 6);
+	clks[CLK_TIMER4_CORE]		= starfive_clk_gated_divider("timer4_coreclk",		UNKNOWN,	base + 0x2C4, 6);
+	clks[CLK_TIMER5_CORE]		= starfive_clk_gated_divider("timer5_coreclk",		UNKNOWN,	base + 0x2C8, 6);
+	clks[CLK_TIMER6_CORE]		= starfive_clk_gated_divider("timer6_coreclk",		UNKNOWN,	base + 0x2CC, 6);
+	clks[CLK_VP6INTC_APB]		= starfive_clk_gate("vp6intc_apb",		UNKNOWN,	base + 0x2D0);
+	clks[CLK_PWM_APB]		= starfive_clk_gate("pwm_apb",		UNKNOWN,	base + 0x2D4);
+	clks[CLK_MSI_APB]		= starfive_clk_gate("msi_apb",		UNKNOWN,	base + 0x2D8);
+	clks[CLK_TEMP_APB]		= starfive_clk_gate("temp_apb",		UNKNOWN,	base + 0x2DC);
+	clks[CLK_TEMP_SENSE]		= starfive_clk_gated_divider("temp_sense",		UNKNOWN,	base + 0x2E0, 5);
+	clks[CLK_SYSERR_APB]		= starfive_clk_gate("syserr_apb",		UNKNOWN,	base + 0x2E4);
+}
+
+static struct clk_onecell_data clk_data;
+
+static int starfive_clkgen_clk_probe(struct device_d *dev)
+{
+	struct resource *iores;
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+
+	starfive_clkgen_init(dev->device_node, IOMEM(iores->start));
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(dev->device_node, of_clk_src_onecell_get,
+			    &clk_data);
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id starfive_clkgen_clk_dt_ids[] = {
+	{ .compatible = "starfive,jh7100-clkgen" },
+	{ /* sentinel */ }
+};
+
+static struct driver_d starfive_clkgen_clk_driver = {
+	.probe	= starfive_clkgen_clk_probe,
+	.name	= "starfive-clkgen",
+	.of_compatible = starfive_clkgen_clk_dt_ids,
+};
+core_platform_driver(starfive_clkgen_clk_driver);
diff --git a/include/dt-bindings/clock/starfive-jh7100.h b/include/dt-bindings/clock/starfive-jh7100.h
new file mode 100644
index 000000000000..9ad5e7f9bfd5
--- /dev/null
+++ b/include/dt-bindings/clock/starfive-jh7100.h
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: GPL-2.0 OR X11 */
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H
+
+#define	CLK_OSC_SYS		0
+#define	CLK_OSC_AUD		1
+#define	CLK_PLL0_OUT		2
+#define	CLK_PLL1_OUT		3
+#define	CLK_PLL2_OUT		4
+#define CLK_CPUNDBUS_ROOT	5
+#define CLK_DLA_ROOT		6
+#define CLK_DSP_ROOT		7
+#define CLK_GMACUSB_ROOT	8
+#define CLK_PERH0_ROOT		9
+#define CLK_PERH1_ROOT		10
+#define CLK_VIN_ROOT		11
+#define CLK_VOUT_ROOT		12
+#define CLK_AUDIO_ROOT		13
+#define CLK_CDECHIFI4_ROOT	14
+#define CLK_CDEC_ROOT		15
+#define CLK_VOUTBUS_ROOT	16
+#define CLK_CPUNBUS_ROOT_DIV	17
+#define CLK_DSP_ROOT_DIV	18
+#define CLK_PERH0_SRC		19
+#define CLK_PERH1_SRC		20
+#define CLK_PLL0_TESTOUT	21
+#define CLK_PLL1_TESTOUT	22
+#define CLK_PLL2_TESTOUT	23
+#define CLK_PLL2_REF		24
+#define CLK_CPU_CORE		25
+#define CLK_CPU_AXI		26
+#define CLK_AHB_BUS		27
+#define CLK_APB1_BUS		28
+#define CLK_APB2_BUS		29
+#define CLK_DOM3AHB_BUS		30
+#define CLK_DOM7AHB_BUS		31
+#define CLK_U74_CORE0		32
+#define CLK_U74_CORE1		33
+#define CLK_U74_AXI		34
+#define CLK_U74RTC_TOGGLE	35
+#define CLK_SGDMA2P_AXI		35
+#define CLK_DMA2PNOC_AXI	37
+#define CLK_SGDMA2P_AHB		37
+#define CLK_DLA_BUS		39
+#define CLK_DLA_AXI		40
+#define CLK_DLANOC_AXI		41
+#define CLK_DLA_APB		42
+#define CLK_VP6_CORE		43
+#define CLK_VP6BUS_SRC		44
+#define CLK_VP6_AXI		45
+#define CLK_VCDECBUS_SRC	46
+#define CLK_VDEC_BUS		47
+#define CLK_VDEC_AXI		48
+#define CLK_VDECBRG_MAIN	49
+#define CLK_VDEC_BCLK		50
+#define CLK_VDEC_CCLK		51
+#define CLK_VDEC_APB		52
+#define CLK_JPEG_AXI		53
+#define CLK_JPEG_CCLK		54
+#define CLK_JPEG_APB		55
+#define CLK_GC300_2X		56
+#define CLK_GC300_AHB		57
+#define CLK_JPCGC300_AXIBUS	58
+#define CLK_GC300_AXI		59
+#define CLK_JPCGC300_MAIN	60
+#define CLK_VENC_BUS		61
+#define CLK_VENC_AXI		62
+#define CLK_VENCBRG_MAIN	63
+#define CLK_VENC_BCLK		64
+#define CLK_VENC_CCLK		65
+#define CLK_VENC_APB		66
+#define CLK_DDRPLL_DIV2		67
+#define CLK_DDRPLL_DIV4		68
+#define CLK_DDRPLL_DIV8		69
+#define CLK_DDROSC_DIV2		70
+#define CLK_DDRC0		71
+#define CLK_DDRC1		72
+#define CLK_DDRPHY_APB		73
+#define CLK_NOC_ROB		74
+#define CLK_NOC_COG		75
+#define CLK_NNE_AHB		76
+#define CLK_NNEBUS_SRC1		77
+#define CLK_NNE_BUS		78
+#define CLK_NNE_AXI		79
+#define CLK_NNENOC_AXI		80
+#define CLK_DLASLV_AXI		81
+#define CLK_DSPX2C_AXI		82
+#define CLK_HIFI4_SRC		83
+#define CLK_HIFI4_COREFREE	84
+#define CLK_HIFI4_CORE		85
+#define CLK_HIFI4_BUS		86
+#define CLK_HIFI4_AXI		87
+#define CLK_HIFI4NOC_AXI	88
+#define CLK_SGDMA1P_BUS		89
+#define CLK_SGDMA1P_AXI		90
+#define CLK_DMA1P_AXI		91
+#define CLK_X2C_AXI		92
+#define CLK_USB_BUS		93
+#define CLK_USB_AXI		94
+#define CLK_USBNOC_AXI		95
+#define CLK_USBPHY_ROOTDIV	96
+#define CLK_USBPHY_125M		97
+#define CLK_USBPHY_PLLDIV25M	98
+#define CLK_USBPHY_25M		99
+#define CLK_AUDIO_DIV		100
+#define CLK_AUDIO_SRC		101
+#define CLK_AUDIO_12288		102
+#define CLK_VIN_SRC		103
+#define CLK_ISP0_BUS		104
+#define CLK_ISP0_AXI		105
+#define CLK_ISP0NOC_AXI		106
+#define CLK_ISPSLV_AXI		107
+#define CLK_ISP1_BUS		108
+#define CLK_ISP1_AXI		109
+#define CLK_ISP1NOC_AXI		110
+#define CLK_VIN_BUS		111
+#define CLK_VIN_AXI		112
+#define CLK_VINNOC_AXI		113
+#define CLK_VOUT_SRC		114
+#define CLK_DISPBUS_SRC		115
+#define CLK_DISP_BUS		116
+#define CLK_DISP_AXI		117
+#define CLK_DISPNOC_AXI		118
+#define CLK_SDIO0_AHB		119
+#define CLK_SDIO0_CCLKINT	120
+#define CLK_SDIO0_CCLKINT_INV	121
+#define CLK_SDIO1_AHB		122
+#define CLK_SDIO1_CCLKINT	123
+#define CLK_SDIO1_CCLKINT_INV	124
+#define CLK_GMAC_AHB		125
+#define CLK_GMAC_ROOT_DIV	126
+#define CLK_GMAC_PTP_REF	127
+#define CLK_GMAC_GTX		128
+#define CLK_GMAC_RMII_TX	129
+#define CLK_GMAC_RMII_RX	130
+#define CLK_GMAC_TX		131
+#define CLK_GMAC_TX_INV		132
+#define CLK_GMAC_RX_PRE		133
+#define CLK_GMAC_RX_INV		134
+#define CLK_GMAC_RMII		135
+#define CLK_GMAC_TOPHYREF	136
+#define CLK_SPI2AHB_AHB		137
+#define CLK_SPI2AHB_CORE	138
+#define CLK_EZMASTER_AHB	139
+#define CLK_E24_AHB		140
+#define CLK_E24RTC_TOGGLE	141
+#define CLK_QSPI_AHB		142
+#define CLK_QSPI_APB		143
+#define CLK_QSPI_REF		144
+#define CLK_SEC_AHB		145
+#define CLK_AES			146
+#define CLK_SHA			147
+#define CLK_PKA			148
+#define CLK_TRNG_APB		149
+#define CLK_OTP_APB		150
+#define CLK_UART0_APB		151
+#define CLK_UART0_CORE		152
+#define CLK_UART1_APB		153
+#define CLK_UART1_CORE		154
+#define CLK_SPI0_APB		155
+#define CLK_SPI0_CORE		156
+#define CLK_SPI1_APB		157
+#define CLK_SPI1_CORE		158
+#define CLK_I2C0_APB		159
+#define CLK_I2C0_CORE		160
+#define CLK_I2C1_APB		161
+#define CLK_I2C1_CORE		162
+#define CLK_GPIO_APB		163
+#define CLK_UART2_APB		164
+#define CLK_UART2_CORE		165
+#define CLK_UART3_APB		166
+#define CLK_UART3_CORE		167
+#define CLK_SPI2_APB		168
+#define CLK_SPI2_CORE		169
+#define CLK_SPI3_APB		170
+#define CLK_SPI3_CORE		171
+#define CLK_I2C2_APB		172
+#define CLK_I2C2_CORE		173
+#define CLK_I2C3_APB		174
+#define CLK_I2C3_CORE		175
+#define CLK_WDTIMER_APB		176
+#define CLK_WDT_CORE		177
+#define CLK_TIMER0_CORE		178
+#define CLK_TIMER1_CORE		179
+#define CLK_TIMER2_CORE		180
+#define CLK_TIMER3_CORE		181
+#define CLK_TIMER4_CORE		182
+#define CLK_TIMER5_CORE		183
+#define CLK_TIMER6_CORE		184
+#define CLK_VP6INTC_APB		185
+#define CLK_PWM_APB		186
+#define CLK_MSI_APB		187
+#define CLK_TEMP_APB		188
+#define CLK_TEMP_SENSE		189
+#define CLK_SYSERR_APB		190
+
+#define CLK_END			191
+
+#endif
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 18/20] reset: add StarFive reset controller driver
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (16 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 17/20] clk: add initial StarFive clock support Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-06-07  8:00   ` Sascha Hauer
  2021-05-31  7:38 ` [PATCH 19/20] watchdog: add StarFive watchdog driver Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 20/20] hw_random: add driver for RNG on StarFive SoC Ahmad Fatoum
  19 siblings, 1 reply; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

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@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));
+}
+
+static int starfive_rstgen(struct reset_controller_dev *rcdev, unsigned id, bool assert)
+{
+	struct starfive_rstgen *priv = to_starfive_rstgen(rcdev);
+	void __iomem *base = priv->base;
+
+	starfive_reset_clk_enable(priv, id);
+
+	__starfive_rstgen(base, id, assert);
+	return wait_on_timeout(NSEC_PER_MSEC, __starfive_rstgen_asserted(base, id) == assert);
+}
+
+static int starfive_rstgen_assert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	return starfive_rstgen(rcdev, id, true);
+}
+
+static int starfive_rstgen_deassert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	return starfive_rstgen(rcdev, id, false);
+}
+
+static int starfive_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	int ret;
+
+	ret = starfive_rstgen_assert(rcdev, id);
+	if (ret)
+		return ret;
+
+	udelay(2);
+
+	return starfive_rstgen_deassert(rcdev, id);
+}
+
+static const struct reset_control_ops starfive_rstgen_ops = {
+	.assert		= starfive_rstgen_assert,
+	.deassert	= starfive_rstgen_deassert,
+	.reset		= starfive_reset,
+};
+
+static int starfive_rstgen_probe(struct device_d *dev)
+{
+	struct starfive_rstgen *priv;
+	struct resource *iores;
+
+	priv = xzalloc(sizeof(*priv));
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+
+	if ((priv->sync_resets = device_get_match_data(dev))) {
+		priv->clknp = of_find_compatible_node(NULL, NULL, "starfive,jh7100-clkgen");
+		if (!priv->clknp)
+			return -ENODEV;
+	}
+
+	priv->base = IOMEM(iores->start);
+	priv->rcdev.nr_resets = RSTN_END;
+	priv->rcdev.ops = &starfive_rstgen_ops;
+	priv->rcdev.of_node = dev->device_node;
+
+	return reset_controller_register(&priv->rcdev);
+}
+
+static const struct of_device_id starfive_rstgen_reset_dt_ids[] = {
+	{ .compatible = "starfive,jh7100-rstgen", .data = jh7110_rstgen_sync_resets },
+	{ /* sentinel */ },
+};
+
+static struct driver_d starfive_rstgen_reset_driver = {
+	.name = "starfive_rstgen",
+	.probe = starfive_rstgen_probe,
+	.of_compatible = starfive_rstgen_reset_dt_ids,
+};
+core_platform_driver(starfive_rstgen_reset_driver);
diff --git a/include/dt-bindings/reset-controller/starfive-jh7100.h b/include/dt-bindings/reset-controller/starfive-jh7100.h
new file mode 100644
index 000000000000..390a528576b9
--- /dev/null
+++ b/include/dt-bindings/reset-controller/starfive-jh7100.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0 OR X11 */
+/*
+ * Copyright (c) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_STARFIVE_JH7100
+#define _DT_BINDINGS_RESET_CONTROLLER_STARFIVE_JH7100
+
+#define RSTN_DOM3AHB_BUS	0
+#define RSTN_DOM7AHB_BUS	1
+#define RST_U74			2
+#define RSTN_U74_AXI		3
+#define RSTN_SGDMA2P_AHB	4
+#define RSTN_SGDMA2P_AXI	5
+#define RSTN_DMA2PNOC_AXI	6
+#define RSTN_DLA_AXI		7
+#define RSTN_DLANOC_AXI		8
+#define RSTN_DLA_APB		9
+#define RST_VP6_DRESET		10
+#define RST_VP6_BRESET		11
+#define RSTN_VP6_AXI		12
+#define RSTN_VDECBRG_MAIN	13
+#define RSTN_VDEC_AXI		14
+#define RSTN_VDEC_BCLK		15
+#define RSTN_VDEC_CCLK		16
+#define RSTN_VDEC_APB		17
+#define RSTN_JPEG_AXI		18
+#define RSTN_JPEG_CCLK		19
+#define RSTN_JPEG_APB		20
+#define RSTN_JPCGC300_MAIN	21
+#define RSTN_GC300_2X		22
+#define RSTN_GC300_AXI		23
+#define RSTN_GC300_AHB		24
+#define RSTN_VENC_AXI		25
+#define RSTN_VENCBRG_MAIN	26
+#define RSTN_VENC_BCLK		27
+#define RSTN_VENC_CCLK		28
+#define RSTN_VENC_APB		29
+#define RSTN_DDRPHY_APB		30
+#define RSTN_NOC_ROB		31
+#define RSTN_NOC_COG		32
+#define RSTN_HIFI4_AXI		33
+#define RSTN_HIFI4NOC_AXI	34
+#define RST_HIFI4_drESET	35
+#define RST_HIFI4_bRESET	36
+#define RSTN_USB_AXI		37
+#define RSTN_USBNOC_AXI		38
+#define RSTN_SGDMA1P_AXI	39
+#define RSTN_DMA1P_AXI		40
+#define RSTN_X2C_AXI		41
+#define RSTN_NNE_AHB		42
+#define RSTN_NNE_AXI		43
+#define RSTN_NNENOC_AXI		44
+#define RSTN_DLASLV_AXI		45
+#define RSTN_DSPX2C_AXI		46
+#define RSTN_VIN_SRC		47
+#define RSTN_ISPSLV_AXI		48
+#define RSTN_VIN_AXI		49
+#define RSTN_VINNOC_AXI		50
+#define RSTN_ISP0_AXI		51
+#define RSTN_ISP0NOC_AXI	52
+#define RSTN_ISP1_AXI		53
+#define RSTN_ISP1NOC_AXI	54
+#define RSTN_VOUT_SRC		55
+#define RSTN_DISP_AXI		56
+#define RSTN_DISPNOC_AXI	57
+#define RSTN_SDIO0_AHB		58
+#define RSTN_SDIO1_AHB		59
+#define RSTN_GMAC_AHB		60
+#define RSTN_SPI2AHB_AHB	61
+#define RSTN_SPI2AHB_CORE	62
+#define RSTN_EZMASTER_AHB	63
+#define RST_E24			64
+#define RSTN_QSPI_AHB		65
+#define RSTN_QSPI_CORE		66
+#define RSTN_QSPI_APB		67
+#define RSTN_SEC_AHB		68
+#define RSTN_AES		69
+#define RSTN_PKA		70
+#define RSTN_SHA		71
+#define RSTN_TRNG_APB		72
+#define RSTN_OTP_APB		73
+#define RSTN_UART0_APB		74
+#define RSTN_UART0_CORE		75
+#define RSTN_UART1_APB		76
+#define RSTN_UART1_CORE		77
+#define RSTN_SPI0_APB		78
+#define RSTN_SPI0_CORE		79
+#define RSTN_SPI1_APB		80
+#define RSTN_SPI1_CORE		81
+#define RSTN_I2C0_APB		82
+#define RSTN_I2C0_CORE		83
+#define RSTN_I2C1_APB		84
+#define RSTN_I2C1_CORE		85
+#define RSTN_GPIO_APB		86
+#define RSTN_UART2_APB		87
+#define RSTN_UART2_CORE		88
+#define RSTN_UART3_APB		89
+#define RSTN_UART3_CORE		90
+#define RSTN_SPI2_APB		91
+#define RSTN_SPI2_CORE		92
+#define RSTN_SPI3_APB		93
+#define RSTN_SPI3_CORE		94
+#define RSTN_I2C2_APB		95
+#define RSTN_I2C2_CORE		96
+#define RSTN_I2C3_APB		97
+#define RSTN_I2C3_CORE		98
+#define RSTN_WDTIMER_APB	99
+#define RSTN_WDT		100
+#define RSTN_TIMER0		101
+#define RSTN_TIMER1		102
+#define RSTN_TIMER2		103
+#define RSTN_TIMER3		104
+#define RSTN_TIMER4		105
+#define RSTN_TIMER5		106
+#define RSTN_TIMER6		107
+#define RSTN_VP6INTC_APB	108
+#define RSTN_PWM_APB		109
+#define RSTN_MSI_APB		110
+#define RSTN_TEMP_APB		111
+#define RSTN_TEMP_SENSE		112
+#define RSTN_SYSERR_APB		113
+
+#define RSTN_END		114
+
+#endif
diff --git a/include/soc/starfive/rstgen.h b/include/soc/starfive/rstgen.h
new file mode 100644
index 000000000000..7a674aabe9f2
--- /dev/null
+++ b/include/soc/starfive/rstgen.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __SOC_STARFIVE_RSTGEN_H_
+#define __SOC_STARFIVE_RSTGEN_H_
+
+#include <dt-bindings/reset-controller/starfive-jh7100.h>
+#include <linux/bitops.h>
+#include <linux/types.h>
+
+#define STARFIVE_RSTGEN_STATUS	0x10
+
+static inline void __iomem *starfive_rstgen_bank(void __iomem *base, unsigned long *id)
+{
+	void __iomem *bank = base + *id / (4 * BITS_PER_BYTE) * 4;
+	*id %= 4 * BITS_PER_BYTE;
+	return bank;
+}
+
+static inline void __starfive_rstgen(void __iomem *base, unsigned long id, bool assert)
+{
+	void __iomem *bank = starfive_rstgen_bank(base, &id);
+	u32 val;
+
+	val = readl(bank);
+
+	if (assert)
+		val |= BIT(id);
+	else
+		val &= ~BIT(id);
+
+	writel(val, bank);
+}
+
+static bool __starfive_rstgen_asserted(void __iomem *base, unsigned long id)
+{
+	void __iomem *bank = starfive_rstgen_bank(base, &id);
+
+	return !(readl(bank + STARFIVE_RSTGEN_STATUS) & BIT(id));
+}
+
+#endif
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 19/20] watchdog: add StarFive watchdog driver
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (17 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 18/20] reset: add StarFive reset controller driver Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  2021-05-31  7:38 ` [PATCH 20/20] hw_random: add driver for RNG on StarFive SoC Ahmad Fatoum
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/watchdog/Kconfig        |  7 +++
 drivers/watchdog/Makefile       |  1 +
 drivers/watchdog/starfive_wdt.c | 97 +++++++++++++++++++++++++++++++++
 3 files changed, 105 insertions(+)
 create mode 100644 drivers/watchdog/starfive_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 542659825045..8aeca0bd6f5f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -148,4 +148,11 @@ config ITCO_WDT
 	  NO_REBOOT flag which prevents the watchdog from rebooting the
 	  machine.
 
+config STARFIVE_WDT
+	tristate "StarFive Watchdog Timer"
+	depends on SOC_STARFIVE && OFDEVICE
+	help
+	  If you say yes here you get support for the watchdog device
+	  on StarFive SoCs.
+
 endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 0b598af40218..4e784b5aaa30 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_STPMIC1_WATCHDOG) += stpmic1_wdt.o
 obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
 obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o
 obj-$(CONFIG_ITCO_WDT) += itco_wdt.o
+obj-$(CONFIG_STARFIVE_WDT) += starfive_wdt.o
diff --git a/drivers/watchdog/starfive_wdt.c b/drivers/watchdog/starfive_wdt.c
new file mode 100644
index 000000000000..abe20f7a1a82
--- /dev/null
+++ b/drivers/watchdog/starfive_wdt.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2018 Kalray Inc.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <of.h>
+#include <watchdog.h>
+#include <linux/reset.h>
+
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#define WDT_REG_RESET_EN	0x104
+#define WDT_REG_TIMEOUT		0x108
+#define WDT_REG_CONTROL		0x110
+#define WDT_REG_UNLOCK		0x13c
+
+#define WDT_UNLOCK_KEY	0x378f0765
+
+struct starfive_wdt {
+	uint32_t clk_rate;
+	struct watchdog wdd;
+	void __iomem *base;
+	bool setup;
+};
+
+static int starfive_wdt_set_timeout(struct watchdog *wdd, unsigned int timeout)
+{
+	struct starfive_wdt *wd = container_of(wdd, struct starfive_wdt, wdd);
+
+	writel(0, wd->base + WDT_REG_CONTROL);
+
+	if (timeout > 0) {
+		timeout *= wd->clk_rate;
+		writel(timeout, wd->base + WDT_REG_TIMEOUT);
+		writel(1, wd->base + WDT_REG_CONTROL);
+	}
+
+	return 0;
+}
+
+static int starfive_wdt_drv_probe(struct device_d *dev)
+{
+	struct starfive_wdt *wd;
+	struct resource *iores;
+	struct watchdog *wdd;
+	struct clk *clk;
+	int ret;
+
+	clk = clk_get(dev, NULL);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+
+	wd = xzalloc(sizeof(*wd));
+	wd->base = IOMEM(iores->start);
+
+	wd->clk_rate = clk_get_rate(clk);
+
+	ret = device_reset_all(dev);
+	if (ret)
+		return ret;
+
+	writel(WDT_UNLOCK_KEY, wd->base + WDT_REG_UNLOCK);
+	wd->base = IOMEM(iores->start);
+	/* reset, not interrupt, on timer expiry */
+	writel(1, wd->base + WDT_REG_RESET_EN);
+
+	wdd = &wd->wdd;
+	wdd->name = "starfive_wdt";
+	wdd->hwdev = dev;
+	wdd->set_timeout = starfive_wdt_set_timeout;
+	wdd->timeout_max = U32_MAX / wd->clk_rate;
+
+	wdd->running = readl(wd->base + WDT_REG_CONTROL) & 1 ?
+		WDOG_HW_RUNNING : WDOG_HW_NOT_RUNNING;
+
+	return watchdog_register(wdd);
+}
+
+static struct of_device_id starfive_wdt_of_match[] = {
+	{ .compatible = "starfive,wdt", },
+	{ /* sentinel */ }
+};
+
+static struct driver_d starfive_wdt_driver = {
+	.name		= "starfive-wdt",
+	.probe		= starfive_wdt_drv_probe,
+	.of_compatible	= starfive_wdt_of_match,
+};
+device_platform_driver(starfive_wdt_driver);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 20/20] hw_random: add driver for RNG on StarFive SoC
  2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
                   ` (18 preceding siblings ...)
  2021-05-31  7:38 ` [PATCH 19/20] watchdog: add StarFive watchdog driver Ahmad Fatoum
@ 2021-05-31  7:38 ` Ahmad Fatoum
  19 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:38 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Straight port from the vendor kernel with the difference that we
take the device out of reset. This allows to load older kernels that
don't yet do reset and clock handling.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/hw_random/Kconfig            |   7 +
 drivers/hw_random/Makefile           |   1 +
 drivers/hw_random/starfive-vic-rng.c | 200 +++++++++++++++++++++++++++
 3 files changed, 208 insertions(+)
 create mode 100644 drivers/hw_random/starfive-vic-rng.c

diff --git a/drivers/hw_random/Kconfig b/drivers/hw_random/Kconfig
index a84c03efef90..764911f4d35e 100644
--- a/drivers/hw_random/Kconfig
+++ b/drivers/hw_random/Kconfig
@@ -36,4 +36,11 @@ config HW_RANDOM_VIRTIO
 	  This driver provides guest-side support for the virtual Random Number
 	  Generator hardware.
 
+config HW_RANDOM_STARFIVE
+	tristate "StarFive Random Number Generator"
+	depends on SOC_STARFIVE || COMPILE_TEST
+	help
+	  This driver provides barebox support for the Random Number
+	  Generator hardware found on the StarFive family of SoCs.
+
 endif
diff --git a/drivers/hw_random/Makefile b/drivers/hw_random/Makefile
index 4bab3967fc4d..4cf33d2d93e6 100644
--- a/drivers/hw_random/Makefile
+++ b/drivers/hw_random/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_HWRNG_MXC_RNGC) += mxc-rngc.o
 obj-$(CONFIG_HWRNG_STM32) += stm32-rng.o
 obj-$(CONFIG_HWRNG_DEV_RANDOM) += dev-random.o
 obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
+obj-$(CONFIG_HW_RANDOM_STARFIVE) += starfive-vic-rng.o
diff --git a/drivers/hw_random/starfive-vic-rng.c b/drivers/hw_random/starfive-vic-rng.c
new file mode 100644
index 000000000000..45badd5200b6
--- /dev/null
+++ b/drivers/hw_random/starfive-vic-rng.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
+ */
+#include <common.h>
+#include <linux/err.h>
+#include <io.h>
+#include <of.h>
+#include <driver.h>
+#include <linux/hw_random.h>
+#include <linux/reset.h>
+
+#define VIC_RAND_LEN 4
+
+#define VIC_CTRL		0x00
+#define VIC_MODE		0x04
+#define VIC_SMODE		0x08
+#define VIC_STAT		0x0C
+#define VIC_IE			0x10
+#define VIC_ISTAT		0x14
+#define VIC_ALARM		0x18
+#define VIC_BUILD_ID		0x1C
+#define VIC_FEATURES		0x20
+#define VIC_RAND0		0x24
+#define VIC_NPA_DATA0		0x34
+#define VIC_SEED0		0x74
+#define VIC_IA_RDATA		0xA4
+#define VIC_IA_WDATA		0xA8
+#define VIC_IA_ADDR		0xAC
+#define VIC_IA_CMD		0xB0
+
+/* CTRL */
+#define VIC_CTRL_CMD_NOP		0
+#define VIC_CTRL_CMD_GEN_NOISE		1
+#define VIC_CTRL_CMD_GEN_NONCE		2
+#define VIC_CTRL_CMD_CREATE_STATE	3
+#define VIC_CTRL_CMD_RENEW_STATE	4
+#define VIC_CTRL_CMD_REFRESH_ADDIN	5
+#define VIC_CTRL_CMD_GEN_RANDOM		6
+#define VIC_CTRL_CMD_ADVANCE_STATE	7
+#define VIC_CTRL_CMD_KAT		8
+#define VIC_CTRL_CMD_ZEROIZE		15
+
+/* SMODE */
+#define _VIC_SMODE_SECURE_EN	1
+
+#define VIC_SMODE_SECURE_EN(x)		((x) << _VIC_SMODE_SECURE_EN)
+
+/* STAT */
+#define _VIC_STAT_BUSY		31
+
+#define VIC_STAT_BUSY		(1UL << _VIC_STAT_BUSY)
+
+/* IE */
+#define _VIC_IE_GLBL		31
+#define _VIC_IE_DONE		4
+#define _VIC_IE_ALARMS		3
+#define _VIC_IE_NOISE_RDY	2
+#define _VIC_IE_KAT_COMPLETE	1
+#define _VIC_IE_ZEROIZE		0
+
+#define VIC_IE_GLBL		(1UL << _VIC_IE_GLBL)
+#define VIC_IE_DONE		(1UL << _VIC_IE_DONE)
+#define VIC_IE_ALARMS		(1UL << _VIC_IE_ALARMS)
+#define VIC_IE_NOISE_RDY	(1UL << _VIC_IE_NOISE_RDY)
+#define VIC_IE_KAT_COMPLETE	(1UL << _VIC_IE_KAT_COMPLETE)
+#define VIC_IE_ZEROIZE		(1UL << _VIC_IE_ZEROIZE)
+#define VIC_IE_ALL		(VIC_IE_GLBL | VIC_IE_DONE | VIC_IE_ALARMS | \
+				 VIC_IE_NOISE_RDY | VIC_IE_KAT_COMPLETE | VIC_IE_ZEROIZE)
+
+#define to_vic_rng(p)	container_of(p, struct vic_rng, rng)
+
+struct vic_rng {
+	struct device_d	*dev;
+	void __iomem	*base;
+	struct hwrng	rng;
+};
+
+static inline void vic_wait_till_idle(struct vic_rng *hrng)
+{
+	while(readl(hrng->base + VIC_STAT) & VIC_STAT_BUSY)
+		;
+}
+
+static inline void vic_rng_irq_mask_clear(struct vic_rng *hrng)
+{
+	u32 data = readl(hrng->base + VIC_ISTAT);
+	writel(data, hrng->base + VIC_ISTAT);
+	writel(0, hrng->base + VIC_ALARM);
+}
+
+static int vic_trng_cmd(struct vic_rng *hrng, u32 cmd)
+{
+	vic_wait_till_idle(hrng);
+
+	switch (cmd) {
+	case VIC_CTRL_CMD_NOP:
+	case VIC_CTRL_CMD_GEN_NOISE:
+	case VIC_CTRL_CMD_GEN_NONCE:
+	case VIC_CTRL_CMD_CREATE_STATE:
+	case VIC_CTRL_CMD_RENEW_STATE:
+	case VIC_CTRL_CMD_REFRESH_ADDIN:
+	case VIC_CTRL_CMD_GEN_RANDOM:
+	case VIC_CTRL_CMD_ADVANCE_STATE:
+	case VIC_CTRL_CMD_KAT:
+	case VIC_CTRL_CMD_ZEROIZE:
+		writel(cmd, hrng->base + VIC_CTRL);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int vic_rng_init(struct hwrng *rng)
+{
+	struct vic_rng *hrng = to_vic_rng(rng);
+	int ret;
+
+	ret = device_reset(rng->dev);
+	if (ret)
+		return ret;
+
+	// clear register: ISTAT
+	vic_rng_irq_mask_clear(hrng);
+
+	// set mission mode
+	writel(VIC_SMODE_SECURE_EN(1), hrng->base + VIC_SMODE);
+
+	vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
+	vic_wait_till_idle(hrng);
+
+	// set interrupt
+	writel(VIC_IE_ALL, hrng->base + VIC_IE);
+
+	// zeroize
+	vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
+
+	vic_wait_till_idle(hrng);
+
+	return 0;
+}
+
+static int vic_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+	struct vic_rng *hrng = to_vic_rng(rng);
+
+	vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
+	vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
+	vic_trng_cmd(hrng, VIC_CTRL_CMD_CREATE_STATE);
+
+	vic_wait_till_idle(hrng);
+	max = min_t(size_t, max, VIC_RAND_LEN * 4);
+
+	writel(0x0, hrng->base + VIC_MODE);
+	vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_RANDOM);
+
+	vic_wait_till_idle(hrng);
+	memcpy_fromio(buf, hrng->base + VIC_RAND0, max);
+	vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
+
+	vic_wait_till_idle(hrng);
+	return max;
+}
+
+static int vic_rng_probe(struct device_d *dev)
+{
+	struct vic_rng *hrng;
+	struct resource *res;
+
+	hrng = xzalloc(sizeof(*hrng));
+
+	res = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(res))
+		return PTR_ERR(res);
+
+	hrng->base = IOMEM(res->start);
+	hrng->dev = dev;
+
+	hrng->rng.name = dev_name(dev);
+	hrng->rng.init = vic_rng_init;
+	hrng->rng.read = vic_rng_read;
+
+	return hwrng_register(dev, &hrng->rng);
+}
+
+static const struct of_device_id vic_rng_dt_ids[] = {
+	{ .compatible = "starfive,vic-rng" },
+	{ /* sentinel */ }
+};
+
+static struct driver_d vic_rng_driver = {
+	.name		= "vic-rng",
+	.probe		= vic_rng_probe,
+	.of_compatible	= vic_rng_dt_ids,
+};
+device_platform_driver(vic_rng_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
+MODULE_DESCRIPTION("Starfive VIC random number generator driver");
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/20] RISC-V: support incoherent I-Cache
  2021-05-31  7:38 ` [PATCH 07/20] RISC-V: support incoherent I-Cache Ahmad Fatoum
@ 2021-05-31  7:40   ` Ahmad Fatoum
  2021-06-07  7:33     ` Ahmad Fatoum
  0 siblings, 1 reply; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  7:40 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox

Hello Antony,

On 31.05.21 09:38, Ahmad Fatoum wrote:
> SiFive SoCs have separate I-Caches that require self-modifying code
> like barebox' relocation and PBL extraction code to do cache
> maintenance. Implement sync_caches_for_execution and use it where
> appropriate.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
>  arch/riscv/Kconfig.socs                | 2 ++
>  arch/riscv/boot/uncompress.c           | 2 ++
>  arch/riscv/cpu/core.c                  | 7 +++++++
>  arch/riscv/include/asm/barebox-riscv.h | 2 ++
>  arch/riscv/lib/reloc.c                 | 8 ++++++++
>  arch/riscv/lib/setupc.S                | 2 ++
>  6 files changed, 23 insertions(+)
> 
> diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
> index 9c82a36fe4bd..d2970ba1d67f 100644
> --- a/arch/riscv/Kconfig.socs
> +++ b/arch/riscv/Kconfig.socs
> @@ -18,6 +18,7 @@ config SOC_VIRT
>  	select RISCV_S_MODE
>  	select BOARD_RISCV_GENERIC_DT
>  	select CLINT_TIMER
> +	select HAS_CACHE
>  	help
>  	  Generates an image tht can be be booted by QEMU. The image is called
>  	  barebox-dt-2nd.img
> @@ -30,6 +31,7 @@ config SOC_SIFIVE
>  	select RISCV_TIMER
>  	select HAS_MACB
>  	select HAS_ASM_DEBUG_LL
> +	select HAS_CACHE
>  	help
>  	  This enables support for SiFive SoC platform hardware.
>  
> diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
> index 35a91e8cb62a..9f1d25efb59b 100644
> --- a/arch/riscv/boot/uncompress.c
> +++ b/arch/riscv/boot/uncompress.c
> @@ -63,6 +63,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
>  
>  	pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len);
>  
> +	sync_caches_for_execution();
> +
>  	barebox = (void *)barebox_base;
>  
>  	pr_debug("jumping to uncompressed image at 0x%p. dtb=0x%p\n", barebox, fdt);
> diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c
> index 62eb0ca87164..b4727fe7449b 100644
> --- a/arch/riscv/cpu/core.c
> +++ b/arch/riscv/cpu/core.c
> @@ -18,6 +18,7 @@
>  #include <linux/clk.h>
>  #include <linux/err.h>
>  #include <memory.h>
> +#include <asm/barebox-riscv.h>
>  #include <asm-generic/memory_layout.h>
>  #include <globalvar.h>
>  #include <magicvar.h>
> @@ -91,3 +92,9 @@ static struct driver_d riscv_driver = {
>  	.of_compatible = riscv_dt_ids,
>  };
>  postcore_platform_driver(riscv_driver);
> +
> +static void arch_shutdown(void)
> +{
> +	sync_caches_for_execution();
> +}
> +archshutdown_exitcall(arch_shutdown);
> diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
> index bbe6cd040642..abb320242769 100644
> --- a/arch/riscv/include/asm/barebox-riscv.h
> +++ b/arch/riscv/include/asm/barebox-riscv.h
> @@ -27,6 +27,8 @@ void setup_c(void);
>  void relocate_to_current_adr(void);
>  void relocate_to_adr(unsigned long target);
>  
> +void sync_caches_for_execution(void);
> +
>  void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long memsize,
>  					    void *boarddata, unsigned int flags);
>  
> diff --git a/arch/riscv/lib/reloc.c b/arch/riscv/lib/reloc.c
> index 2fc8818cd698..165190775361 100644
> --- a/arch/riscv/lib/reloc.c
> +++ b/arch/riscv/lib/reloc.c
> @@ -24,6 +24,12 @@
>  
>  #define RISC_R_TYPE(x)	((x) & 0xFF)
>  
> +void sync_caches_for_execution(void)
> +{
> +	if (IS_ENABLED(CONFIG_HAS_CACHE))
> +		asm volatile ("fence.i" ::: "memory");

If Erizo on FPGA chokes on this, we can have it pass
along a feature flag from PBL that says it doesn't
need cache maintenance. Please advise.

> +}
> +
>  void relocate_to_current_adr(void)
>  {
>  	unsigned long offset;
> @@ -63,4 +69,6 @@ void relocate_to_current_adr(void)
>  			panic("");
>  		}
>  	}
> +
> +	sync_caches_for_execution();
>  }
> diff --git a/arch/riscv/lib/setupc.S b/arch/riscv/lib/setupc.S
> index 5fdd81c2c3ec..d225186c79fd 100644
> --- a/arch/riscv/lib/setupc.S
> +++ b/arch/riscv/lib/setupc.S
> @@ -46,6 +46,8 @@ ENTRY(relocate_to_adr)
>  
>  	jal	__memcpy
>  
> +	jal	sync_caches_for_execution
> +
>  	REG_L	a0, (SZREG * 1)(sp)
>  	jr	a0 			/* jump to relocated address */
>  copied:
> 

-- 
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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 17/20] clk: add initial StarFive clock support
  2021-05-31  7:38 ` [PATCH 17/20] clk: add initial StarFive clock support Ahmad Fatoum
@ 2021-05-31  8:41   ` Ahmad Fatoum
  0 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-05-31  8:41 UTC (permalink / raw)
  To: barebox

On 31.05.21 09:38, Ahmad Fatoum wrote:
> All clocks seem to share a common format:
> 
>  struct starfive_clk {
> 	u32 divisor : 24;
> 	u32 mux : 6;
> 	u32 invert : 1;
> 	u32 enable : 1;
>  };
> 
> There is no documentation, what the acceptable divisor values are, but
> we could already register gates and muxes, do so for now until
> documentation is available.
> 
> The bulk of this code has been machine-generated by parsing the macros
> in the vendor U-Boot <asm/arch-vic7100/clkgen_ctrl_macro.h>.

If someone's curious:
https://gist.github.com/a3f/085ea5d58e3bf3e5536e441b1a45f0ce

Advising to rinse your eyes afterwards.

> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
>  drivers/clk/Makefile                        |   1 +
>  drivers/clk/starfive/Makefile               |   3 +
>  drivers/clk/starfive/clk.h                  |  64 ++++
>  drivers/clk/starfive/jh7100-clkgen.c        | 363 ++++++++++++++++++++
>  include/dt-bindings/clock/starfive-jh7100.h | 203 +++++++++++
>  5 files changed, 634 insertions(+)
>  create mode 100644 drivers/clk/starfive/Makefile
>  create mode 100644 drivers/clk/starfive/clk.h
>  create mode 100644 drivers/clk/starfive/jh7100-clkgen.c
>  create mode 100644 include/dt-bindings/clock/starfive-jh7100.h
> 
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index b0be8d1bd89a..499df2fe392b 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -23,3 +23,4 @@ obj-$(CONFIG_MACH_MIPS_LOONGSON)+= loongson/
>  obj-$(CONFIG_ARCH_LAYERSCAPE)	+= clk-qoric.o
>  obj-y				+= analogbits/
>  obj-$(CONFIG_CLK_SIFIVE)	+= sifive/
> +obj-$(CONFIG_SOC_STARFIVE)	+= starfive/
> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
> new file mode 100644
> index 000000000000..7e4104993580
> --- /dev/null
> +++ b/drivers/clk/starfive/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_SOC_STARFIVE_JH7100) += jh7100-clkgen.o
> diff --git a/drivers/clk/starfive/clk.h b/drivers/clk/starfive/clk.h
> new file mode 100644
> index 000000000000..cfbf116dcb78
> --- /dev/null
> +++ b/drivers/clk/starfive/clk.h
> @@ -0,0 +1,64 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright 2021 Ahmad Fatoum, Pengutronix
> + */
> +
> +#ifndef STARFIVE_CLK_H_
> +#define STARFIVE_CLK_H_
> +
> +#include <linux/clk.h>
> +
> +#define STARFIVE_CLK_ENABLE_SHIFT	31
> +#define STARFIVE_CLK_INVERT_SHIFT	30
> +#define STARFIVE_CLK_MUX_SHIFT		24
> +
> +static inline struct clk *starfive_clk_underspecifid(const char *name, const char *parent)
> +{
> +	/*
> +	 * TODO With documentation available, all users of this functions can be
> +	 * migrated to one of the above or to a clk_fixed_factor with
> +	 * appropriate factor
> +	 */
> +	return clk_fixed_factor(name, parent, 1, 1, 0);
> +}
> +
> +static inline struct clk *starfive_clk_divider(const char *name, const char *parent,
> +		void __iomem *reg, u8 width)
> +{
> +	return starfive_clk_underspecifid(name, parent);
> +}
> +
> +static inline struct clk *starfive_clk_gate(const char *name, const char *parent,
> +		void __iomem *reg)
> +{
> +	return clk_gate(name, parent, reg, STARFIVE_CLK_ENABLE_SHIFT, CLK_SET_RATE_PARENT, 0);
> +}
> +
> +static inline struct clk *starfive_clk_divider_table(const char *name,
> +		const char *parent, void __iomem *reg, u8 width,
> +		const struct clk_div_table *table)
> +{
> +	return clk_divider_table(name, parent, CLK_SET_RATE_PARENT, reg, 0,
> +				 width, table, 0);
> +}
> +
> +static inline struct clk *starfive_clk_gated_divider(const char *name,
> +		const char *parent, void __iomem *reg, u8 width)
> +{
> +	/* TODO divider part */
> +	return clk_gate(name, parent, reg, STARFIVE_CLK_ENABLE_SHIFT, CLK_SET_RATE_PARENT, 0);
> +}
> +
> +static inline struct clk *starfive_clk_gate_dis(const char *name, const char *parent,
> +		void __iomem *reg)
> +{
> +	return clk_gate_inverted(name, parent, reg, STARFIVE_CLK_INVERT_SHIFT, CLK_SET_RATE_PARENT);
> +}
> +
> +static inline struct clk *starfive_clk_mux(const char *name, void __iomem *reg,
> +		u8 width, const char * const *parents, u8 num_parents)
> +{
> +	return clk_mux(name, 0, reg, STARFIVE_CLK_MUX_SHIFT, width, parents, num_parents, 0);
> +}
> +
> +#endif
> diff --git a/drivers/clk/starfive/jh7100-clkgen.c b/drivers/clk/starfive/jh7100-clkgen.c
> new file mode 100644
> index 000000000000..df5353e8e624
> --- /dev/null
> +++ b/drivers/clk/starfive/jh7100-clkgen.c
> @@ -0,0 +1,363 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2021 Ahmad Fatoum, Pengutronix
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <driver.h>
> +#include <linux/clk.h>
> +#include <io.h>
> +#include <of.h>
> +#include <linux/clkdev.h>
> +#include <linux/err.h>
> +#include <dt-bindings/clock/starfive-jh7100.h>
> +
> +#include "clk.h"
> +
> +
> +static const char *cpundbus_root_sels[4] = {
> +	[0] = "osc_sys",
> +	[1] = "pll0_out",
> +	[2] = "pll1_out",
> +	[3] = "pll2_out",
> +};
> +
> +static const char *dla_root_sels[4] = {
> +	[0] = "osc_sys",
> +	[1] = "pll1_out",
> +	[2] = "pll2_out",
> +	[3] = "dummy",
> +};
> +
> +static const char *dsp_root_sels[4] = {
> +	[0] = "osc_sys",
> +	[1] = "pll0_out",
> +	[2] = "pll1_out",
> +	[3] = "pll2_out",
> +};
> +
> +static const char *gmacusb_root_sels[4] = {
> +	[0] = "osc_sys",
> +	[1] = "pll0_out",
> +	[2] = "pll2_out",
> +	[3] = "dummy",
> +};
> +
> +static const char *perh0_root_sels[2] = {
> +	[0] = "osc_sys",
> +	[1] = "pll0_out",
> +};
> +
> +static const char *perh1_root_sels[2] = {
> +	[0] = "osc_sys",
> +	[1] = "pll2_out",
> +};
> +
> +static const char *vin_root_sels[4] = {
> +	[0] = "osc_sys",
> +	[1] = "pll1_out",
> +	[2] = "pll2_out",
> +	[3] = "dummy",
> +};
> +
> +static const char *vout_root_sels[4] = {
> +	[0] = "osc_aud",
> +	[1] = "pll0_out",
> +	[2] = "pll2_out",
> +	[3] = "dummy",
> +};
> +
> +static const char *cdechifi4_root_sels[4] = {
> +	[0] = "osc_sys",
> +	[1] = "pll1_out",
> +	[2] = "pll2_out",
> +	[3] = "dummy",
> +};
> +
> +static const char *cdec_root_sels[4] = {
> +	[0] = "osc_sys",
> +	[1] = "pll0_out",
> +	[2] = "pll1_out",
> +	[3] = "dummy",
> +};
> +
> +static const char *voutbus_root_sels[4] = {
> +	[0] = "osc_aud",
> +	[1] = "pll0_out",
> +	[2] = "pll2_out",
> +	[3] = "dummy",
> +};
> +
> +static const char *pll2_refclk_sels[2] = {
> +	[0] = "osc_sys",
> +	[1] = "osc_aud",
> +};
> +
> +static const char *ddrc0_sels[4] = {
> +	[0] = "ddrosc_div2",
> +	[1] = "ddrpll_div2",
> +	[2] = "ddrpll_div4",
> +	[3] = "ddrpll_div8",
> +};
> +
> +static const char *ddrc1_sels[4] = {
> +	[0] = "ddrosc_div2",
> +	[1] = "ddrpll_div2",
> +	[2] = "ddrpll_div4",
> +	[3] = "ddrpll_div8",
> +};
> +
> +static const char *nne_bus_sels[2] = {
> +	[0] = "cpu_axi",
> +	[1] = "nnebus_src1",
> +};
> +
> +static const char *usbphy_25m_sels[2] = {
> +	[0] = "osc_sys",
> +	[1] = "usbphy_plldiv25m",
> +};
> +
> +static const char *gmac_tx_sels[4] = {
> +	[0] = "gmac_gtxclk",
> +	[1] = "gmac_mii_txclk",
> +	[2] = "gmac_rmii_txclk",
> +	[3] = "dummy",
> +};
> +
> +static const char *gmac_rx_pre_sels[2] = {
> +	[0] = "gmac_gr_mii_rxclk",
> +	[1] = "gmac_rmii_rxclk",
> +};
> +
> +static struct clk *clks[CLK_END];
> +
> +/* assume osc_sys as direct parent for clocks of yet unknown lineage */
> +#define UNKNOWN "osc_sys"
> +
> +static void starfive_clkgen_init(struct device_node *np, void __iomem *base)
> +{
> +	clks[CLK_OSC_SYS]		= of_clk_get_by_name(np, "osc_sys");
> +	clks[CLK_OSC_AUD]		= of_clk_get_by_name(np, "osc_aud");
> +	clks[CLK_PLL0_OUT]		= starfive_clk_underspecifid("pll0_out", "osc_sys");
> +	clks[CLK_PLL1_OUT]		= starfive_clk_underspecifid("pll1_out", "osc_sys");
> +	clks[CLK_PLL2_OUT]		= starfive_clk_underspecifid("pll2_out", "pll2_refclk");
> +	clks[CLK_CPUNDBUS_ROOT]		= starfive_clk_mux("cpundbus_root", base + 0x0, 2, cpundbus_root_sels, ARRAY_SIZE(cpundbus_root_sels));
> +	clks[CLK_DLA_ROOT]		= starfive_clk_mux("dla_root",	base + 0x4, 2, dla_root_sels, ARRAY_SIZE(dla_root_sels));
> +	clks[CLK_DSP_ROOT]		= starfive_clk_mux("dsp_root",	base + 0x8, 2, dsp_root_sels, ARRAY_SIZE(dsp_root_sels));
> +	clks[CLK_GMACUSB_ROOT]		= starfive_clk_mux("gmacusb_root",	base + 0xC, 2, gmacusb_root_sels, ARRAY_SIZE(gmacusb_root_sels));
> +	clks[CLK_PERH0_ROOT]		= starfive_clk_mux("perh0_root",	base + 0x10, 1, perh0_root_sels, ARRAY_SIZE(perh0_root_sels));
> +	clks[CLK_PERH1_ROOT]		= starfive_clk_mux("perh1_root",	base + 0x14, 1, perh1_root_sels, ARRAY_SIZE(perh1_root_sels));
> +	clks[CLK_VIN_ROOT]		= starfive_clk_mux("vin_root",	base + 0x18, 2, vin_root_sels, ARRAY_SIZE(vin_root_sels));
> +	clks[CLK_VOUT_ROOT]		= starfive_clk_mux("vout_root",	base + 0x1C, 2, vout_root_sels, ARRAY_SIZE(vout_root_sels));
> +	clks[CLK_AUDIO_ROOT]		= starfive_clk_gated_divider("audio_root",		UNKNOWN,	base + 0x20, 4);
> +	clks[CLK_CDECHIFI4_ROOT]	= starfive_clk_mux("cdechifi4_root",	base + 0x24, 2, cdechifi4_root_sels, ARRAY_SIZE(cdechifi4_root_sels));
> +	clks[CLK_CDEC_ROOT]		= starfive_clk_mux("cdec_root",	base + 0x28, 2, cdec_root_sels, ARRAY_SIZE(cdec_root_sels));
> +	clks[CLK_VOUTBUS_ROOT]		= starfive_clk_mux("voutbus_root",	base + 0x2C, 2, voutbus_root_sels, ARRAY_SIZE(voutbus_root_sels));
> +	clks[CLK_CPUNBUS_ROOT_DIV]	= starfive_clk_divider("cpunbus_root_div",		"cpunbus_root",	base + 0x30, 2);
> +	clks[CLK_DSP_ROOT_DIV]		= starfive_clk_divider("dsp_root_div",		"dsp_root",	base + 0x34, 3);
> +	clks[CLK_PERH0_SRC]		= starfive_clk_divider("perh0_src",		"perh0_root",	base + 0x38, 3);
> +	clks[CLK_PERH1_SRC]		= starfive_clk_divider("perh1_src",		"perh1_root",	base + 0x3C, 3);
> +	clks[CLK_PLL0_TESTOUT]		= starfive_clk_gated_divider("pll0_testout",		"pll0_out",	base + 0x40, 5);
> +	clks[CLK_PLL1_TESTOUT]		= starfive_clk_gated_divider("pll1_testout",		"pll1_out",	base + 0x44, 5);
> +	clks[CLK_PLL2_TESTOUT]		= starfive_clk_gated_divider("pll2_testout",		"pll2_out",	base + 0x48, 5);
> +	clks[CLK_PLL2_REF]		= starfive_clk_mux("pll2_refclk",	base + 0x4C, 1, pll2_refclk_sels, ARRAY_SIZE(pll2_refclk_sels));
> +	clks[CLK_CPU_CORE]		= starfive_clk_divider("cpu_core",		UNKNOWN,	base + 0x50, 4);
> +	clks[CLK_CPU_AXI]		= starfive_clk_divider("cpu_axi",		UNKNOWN,	base + 0x54, 4);
> +	clks[CLK_AHB_BUS]		= starfive_clk_divider("ahb_bus",		UNKNOWN,	base + 0x58, 4);
> +	clks[CLK_APB1_BUS]		= starfive_clk_divider("apb1_bus",		UNKNOWN,	base + 0x5C, 4);
> +	clks[CLK_APB2_BUS]		= starfive_clk_divider("apb2_bus",		UNKNOWN,	base + 0x60, 4);
> +	clks[CLK_DOM3AHB_BUS]		= starfive_clk_gate("dom3ahb_bus",		UNKNOWN,	base + 0x64);
> +	clks[CLK_DOM7AHB_BUS]		= starfive_clk_gate("dom7ahb_bus",		UNKNOWN,	base + 0x68);
> +	clks[CLK_U74_CORE0]		= starfive_clk_gate("u74_core0",		UNKNOWN,	base + 0x6C);
> +	clks[CLK_U74_CORE1]		= starfive_clk_gated_divider("u74_core1",		"",	base + 0x70, 4);
> +	clks[CLK_U74_AXI]		= starfive_clk_gate("u74_axi",		UNKNOWN,	base + 0x74);
> +	clks[CLK_U74RTC_TOGGLE]		= starfive_clk_gate("u74rtc_toggle",		UNKNOWN,	base + 0x78);
> +	clks[CLK_SGDMA2P_AXI]		= starfive_clk_gate("sgdma2p_axi",		UNKNOWN,	base + 0x7C);
> +	clks[CLK_DMA2PNOC_AXI]		= starfive_clk_gate("dma2pnoc_axi",		UNKNOWN,	base + 0x80);
> +	clks[CLK_SGDMA2P_AHB]		= starfive_clk_gate("sgdma2p_ahb",		UNKNOWN,	base + 0x84);
> +	clks[CLK_DLA_BUS]		= starfive_clk_divider("dla_bus",		UNKNOWN,	base + 0x88, 3);
> +	clks[CLK_DLA_AXI]		= starfive_clk_gate("dla_axi",		UNKNOWN,	base + 0x8C);
> +	clks[CLK_DLANOC_AXI]		= starfive_clk_gate("dlanoc_axi",		UNKNOWN,	base + 0x90);
> +	clks[CLK_DLA_APB]		= starfive_clk_gate("dla_apb",		UNKNOWN,	base + 0x94);
> +	clks[CLK_VP6_CORE]		= starfive_clk_gated_divider("vp6_core",		UNKNOWN,	base + 0x98, 3);
> +	clks[CLK_VP6BUS_SRC]		= starfive_clk_divider("vp6bus_src",		UNKNOWN,	base + 0x9C, 3);
> +	clks[CLK_VP6_AXI]		= starfive_clk_gated_divider("vp6_axi",		UNKNOWN,	base + 0xA0, 3);
> +	clks[CLK_VCDECBUS_SRC]		= starfive_clk_divider("vcdecbus_src",		UNKNOWN,	base + 0xA4, 3);
> +	clks[CLK_VDEC_BUS]		= starfive_clk_divider("vdec_bus",		UNKNOWN,	base + 0xA8, 4);
> +	clks[CLK_VDEC_AXI]		= starfive_clk_gate("vdec_axi",		UNKNOWN,	base + 0xAC);
> +	clks[CLK_VDECBRG_MAIN]		= starfive_clk_gate("vdecbrg_mainclk",		UNKNOWN,	base + 0xB0);
> +	clks[CLK_VDEC_BCLK]		= starfive_clk_gated_divider("vdec_bclk",		UNKNOWN,	base + 0xB4, 4);
> +	clks[CLK_VDEC_CCLK]		= starfive_clk_gated_divider("vdec_cclk",		UNKNOWN,	base + 0xB8, 4);
> +	clks[CLK_VDEC_APB]		= starfive_clk_gate("vdec_apb",		UNKNOWN,	base + 0xBC);
> +	clks[CLK_JPEG_AXI]		= starfive_clk_gated_divider("jpeg_axi",		UNKNOWN,	base + 0xC0, 4);
> +	clks[CLK_JPEG_CCLK]		= starfive_clk_gated_divider("jpeg_cclk",		UNKNOWN,	base + 0xC4, 4);
> +	clks[CLK_JPEG_APB]		= starfive_clk_gate("jpeg_apb",		UNKNOWN,	base + 0xC8);
> +	clks[CLK_GC300_2X]		= starfive_clk_gated_divider("gc300_2x",		UNKNOWN,	base + 0xCC, 4);
> +	clks[CLK_GC300_AHB]		= starfive_clk_gate("gc300_ahb",		UNKNOWN,	base + 0xD0);
> +	clks[CLK_JPCGC300_AXIBUS]	= starfive_clk_divider("jpcgc300_axibus",		UNKNOWN,	base + 0xD4, 4);
> +	clks[CLK_GC300_AXI]		= starfive_clk_gate("gc300_axi",		UNKNOWN,	base + 0xD8);
> +	clks[CLK_JPCGC300_MAIN]		= starfive_clk_gate("jpcgc300_mainclk",		UNKNOWN,	base + 0xDC);
> +	clks[CLK_VENC_BUS]		= starfive_clk_divider("venc_bus",		UNKNOWN,	base + 0xE0, 4);
> +	clks[CLK_VENC_AXI]		= starfive_clk_gate("venc_axi",		UNKNOWN,	base + 0xE4);
> +	clks[CLK_VENCBRG_MAIN]		= starfive_clk_gate("vencbrg_mainclk",		UNKNOWN,	base + 0xE8);
> +	clks[CLK_VENC_BCLK]		= starfive_clk_gated_divider("venc_bclk",		UNKNOWN,	base + 0xEC, 4);
> +	clks[CLK_VENC_CCLK]		= starfive_clk_gated_divider("venc_cclk",		UNKNOWN,	base + 0xF0, 4);
> +	clks[CLK_VENC_APB]		= starfive_clk_gate("venc_apb",		UNKNOWN,	base + 0xF4);
> +	clks[CLK_DDRPLL_DIV2]		= starfive_clk_gated_divider("ddrpll_div2",		UNKNOWN,	base + 0xF8, 2);
> +	clks[CLK_DDRPLL_DIV4]		= starfive_clk_gated_divider("ddrpll_div4",		UNKNOWN,	base + 0xFC, 2);
> +	clks[CLK_DDRPLL_DIV8]		= starfive_clk_gated_divider("ddrpll_div8",		UNKNOWN,	base + 0x100, 2);
> +	clks[CLK_DDROSC_DIV2]		= starfive_clk_gated_divider("ddrosc_div2",		UNKNOWN,	base + 0x104, 2);
> +	clks[CLK_DDRC0]			= starfive_clk_mux("ddrc0",	base + 0x108, 2, ddrc0_sels, ARRAY_SIZE(ddrc0_sels));
> +	clks[CLK_DDRC1]			= starfive_clk_mux("ddrc1",	base + 0x10C, 2, ddrc1_sels, ARRAY_SIZE(ddrc1_sels));
> +	clks[CLK_DDRPHY_APB]		= starfive_clk_gate("ddrphy_apb",		UNKNOWN,	base + 0x110);
> +	clks[CLK_NOC_ROB]		= starfive_clk_divider("noc_rob",		UNKNOWN,	base + 0x114, 4);
> +	clks[CLK_NOC_COG]		= starfive_clk_divider("noc_cog",		UNKNOWN,	base + 0x118, 4);
> +	clks[CLK_NNE_AHB]		= starfive_clk_gate("nne_ahb",		UNKNOWN,	base + 0x11C);
> +	clks[CLK_NNEBUS_SRC1]		= starfive_clk_divider("nnebus_src1",		UNKNOWN,	base + 0x120, 3);
> +	clks[CLK_NNE_BUS]		= starfive_clk_mux("nne_bus",	base + 0x124, 2, nne_bus_sels, ARRAY_SIZE(nne_bus_sels));
> +	clks[CLK_NNE_AXI]		= starfive_clk_gate("nne_axi",	UNKNOWN, base + 0x128);
> +	clks[CLK_NNENOC_AXI]		= starfive_clk_gate("nnenoc_axi",		UNKNOWN,	base + 0x12C);
> +	clks[CLK_DLASLV_AXI]		= starfive_clk_gate("dlaslv_axi",		UNKNOWN,	base + 0x130);
> +	clks[CLK_DSPX2C_AXI]		= starfive_clk_gate("dspx2c_axi",		UNKNOWN,	base + 0x134);
> +	clks[CLK_HIFI4_SRC]		= starfive_clk_divider("hifi4_src",		UNKNOWN,	base + 0x138, 3);
> +	clks[CLK_HIFI4_COREFREE]	= starfive_clk_divider("hifi4_corefree",		UNKNOWN,	base + 0x13C, 4);
> +	clks[CLK_HIFI4_CORE]		= starfive_clk_gate("hifi4_core",		UNKNOWN,	base + 0x140);
> +	clks[CLK_HIFI4_BUS]		= starfive_clk_divider("hifi4_bus",		UNKNOWN,	base + 0x144, 4);
> +	clks[CLK_HIFI4_AXI]		= starfive_clk_gate("hifi4_axi",		UNKNOWN,	base + 0x148);
> +	clks[CLK_HIFI4NOC_AXI]		= starfive_clk_gate("hifi4noc_axi",		UNKNOWN,	base + 0x14C);
> +	clks[CLK_SGDMA1P_BUS]		= starfive_clk_divider("sgdma1p_bus",		UNKNOWN,	base + 0x150, 4);
> +	clks[CLK_SGDMA1P_AXI]		= starfive_clk_gate("sgdma1p_axi",		UNKNOWN,	base + 0x154);
> +	clks[CLK_DMA1P_AXI]		= starfive_clk_gate("dma1p_axi",		UNKNOWN,	base + 0x158);
> +	clks[CLK_X2C_AXI]		= starfive_clk_gated_divider("x2c_axi",		UNKNOWN,	base + 0x15C, 4);
> +	clks[CLK_USB_BUS]		= starfive_clk_divider("usb_bus",		UNKNOWN,	base + 0x160, 4);
> +	clks[CLK_USB_AXI]		= starfive_clk_gate("usb_axi",		UNKNOWN,	base + 0x164);
> +	clks[CLK_USBNOC_AXI]		= starfive_clk_gate("usbnoc_axi",		UNKNOWN,	base + 0x168);
> +	clks[CLK_USBPHY_ROOTDIV]	= starfive_clk_divider("usbphy_rootdiv",		UNKNOWN,	base + 0x16C, 3);
> +	clks[CLK_USBPHY_125M]		= starfive_clk_gated_divider("usbphy_125m",		UNKNOWN,	base + 0x170, 4);
> +	clks[CLK_USBPHY_PLLDIV25M]	= starfive_clk_gated_divider("usbphy_plldiv25m",		UNKNOWN,	base + 0x174, 6);
> +	clks[CLK_USBPHY_25M]		= starfive_clk_mux("usbphy_25m",	base + 0x178, 1, usbphy_25m_sels, ARRAY_SIZE(usbphy_25m_sels));
> +	clks[CLK_AUDIO_DIV]		= starfive_clk_divider("audio_div",		UNKNOWN,	base + 0x17C, 18);
> +	clks[CLK_AUDIO_SRC]		= starfive_clk_gate("audio_src",		UNKNOWN,	base + 0x180);
> +	clks[CLK_AUDIO_12288]		= starfive_clk_gate("audio_12288",		UNKNOWN,	base + 0x184);
> +	clks[CLK_VIN_SRC]		= starfive_clk_gated_divider("vin_src",		UNKNOWN,	base + 0x188, 3);
> +	clks[CLK_ISP0_BUS]		= starfive_clk_divider("isp0_bus",		UNKNOWN,	base + 0x18C, 4);
> +	clks[CLK_ISP0_AXI]		= starfive_clk_gate("isp0_axi",		UNKNOWN,	base + 0x190);
> +	clks[CLK_ISP0NOC_AXI]		= starfive_clk_gate("isp0noc_axi",		UNKNOWN,	base + 0x194);
> +	clks[CLK_ISPSLV_AXI]		= starfive_clk_gate("ispslv_axi",		UNKNOWN,	base + 0x198);
> +	clks[CLK_ISP1_BUS]		= starfive_clk_divider("isp1_bus",		UNKNOWN,	base + 0x19C, 4);
> +	clks[CLK_ISP1_AXI]		= starfive_clk_gate("isp1_axi",		UNKNOWN,	base + 0x1A0);
> +	clks[CLK_ISP1NOC_AXI]		= starfive_clk_gate("isp1noc_axi",		UNKNOWN,	base + 0x1A4);
> +	clks[CLK_VIN_BUS]		= starfive_clk_divider("vin_bus",		UNKNOWN,	base + 0x1A8, 4);
> +	clks[CLK_VIN_AXI]		= starfive_clk_gate("vin_axi",		UNKNOWN,	base + 0x1AC);
> +	clks[CLK_VINNOC_AXI]		= starfive_clk_gate("vinnoc_axi",		UNKNOWN,	base + 0x1B0);
> +	clks[CLK_VOUT_SRC]		= starfive_clk_gated_divider("vout_src",		UNKNOWN,	base + 0x1B4, 3);
> +	clks[CLK_DISPBUS_SRC]		= starfive_clk_divider("dispbus_src",		UNKNOWN,	base + 0x1B8, 3);
> +	clks[CLK_DISP_BUS]		= starfive_clk_divider("disp_bus",		UNKNOWN,	base + 0x1BC, 3);
> +	clks[CLK_DISP_AXI]		= starfive_clk_gate("disp_axi",		UNKNOWN,	base + 0x1C0);
> +	clks[CLK_DISPNOC_AXI]		= starfive_clk_gate("dispnoc_axi",		UNKNOWN,	base + 0x1C4);
> +	clks[CLK_SDIO0_AHB]		= starfive_clk_gate("sdio0_ahb",		UNKNOWN,	base + 0x1C8);
> +	clks[CLK_SDIO0_CCLKINT]		= starfive_clk_gated_divider("sdio0_cclkint",		UNKNOWN,	base + 0x1CC, 5);
> +	clks[CLK_SDIO0_CCLKINT_INV]	= starfive_clk_gate_dis("sdio0_cclkint_inv",		UNKNOWN,	base + 0x1D0);
> +	clks[CLK_SDIO1_AHB]		= starfive_clk_gate("sdio1_ahb",		UNKNOWN,	base + 0x1D4);
> +	clks[CLK_SDIO1_CCLKINT]		= starfive_clk_gated_divider("sdio1_cclkint",		UNKNOWN,	base + 0x1D8, 5);
> +	clks[CLK_SDIO1_CCLKINT_INV]	= starfive_clk_gate_dis("sdio1_cclkint_inv",		UNKNOWN,	base + 0x1DC);
> +	clks[CLK_GMAC_AHB]		= starfive_clk_gate("gmac_ahb",		UNKNOWN,	base + 0x1E0);
> +	clks[CLK_GMAC_ROOT_DIV]		= starfive_clk_divider("gmac_root_div",		UNKNOWN,	base + 0x1E4, 4);
> +	clks[CLK_GMAC_PTP_REF]		= starfive_clk_gated_divider("gmac_ptp_refclk",		UNKNOWN,	base + 0x1E8, 5);
> +	clks[CLK_GMAC_GTX]		= starfive_clk_gated_divider("gmac_gtxclk",		UNKNOWN,	base + 0x1EC, 8);
> +	clks[CLK_GMAC_RMII_TX]		= starfive_clk_gated_divider("gmac_rmii_txclk",		UNKNOWN,	base + 0x1F0, 4);
> +	clks[CLK_GMAC_RMII_RX]		= starfive_clk_gated_divider("gmac_rmii_rxclk",		UNKNOWN,	base + 0x1F4, 4);
> +	clks[CLK_GMAC_TX]		= starfive_clk_mux("gmac_tx",	base + 0x1F8, 2, gmac_tx_sels, ARRAY_SIZE(gmac_tx_sels));
> +	clks[CLK_GMAC_TX_INV]		= starfive_clk_gate_dis("gmac_tx_inv",		UNKNOWN,	base + 0x1FC);
> +	clks[CLK_GMAC_RX_PRE]		= starfive_clk_mux("gmac_rx_pre",	base + 0x200, 1, gmac_rx_pre_sels, ARRAY_SIZE(gmac_rx_pre_sels));
> +	clks[CLK_GMAC_RX_INV]		= starfive_clk_gate_dis("gmac_rx_inv",		UNKNOWN,	base + 0x204);
> +	clks[CLK_GMAC_RMII]		= starfive_clk_gate("gmac_rmii",		UNKNOWN,	base + 0x208);
> +	clks[CLK_GMAC_TOPHYREF]		= starfive_clk_gated_divider("gmac_tophyref",		UNKNOWN,	base + 0x20C, 7);
> +	clks[CLK_SPI2AHB_AHB]		= starfive_clk_gate("spi2ahb_ahb",		UNKNOWN,	base + 0x210);
> +	clks[CLK_SPI2AHB_CORE]		= starfive_clk_gated_divider("spi2ahb_core",		UNKNOWN,	base + 0x214, 5);
> +	clks[CLK_EZMASTER_AHB]		= starfive_clk_gate("ezmaster_ahb",		UNKNOWN,	base + 0x218);
> +	clks[CLK_E24_AHB]		= starfive_clk_gate("e24_ahb",		UNKNOWN,	base + 0x21C);
> +	clks[CLK_E24RTC_TOGGLE]		= starfive_clk_gate("e24rtc_toggle",		UNKNOWN,	base + 0x220);
> +	clks[CLK_QSPI_AHB]		= starfive_clk_gate("qspi_ahb",		UNKNOWN,	base + 0x224);
> +	clks[CLK_QSPI_APB]		= starfive_clk_gate("qspi_apb",		UNKNOWN,	base + 0x228);
> +	clks[CLK_QSPI_REF]		= starfive_clk_gated_divider("qspi_refclk",		UNKNOWN,	base + 0x22C, 5);
> +	clks[CLK_SEC_AHB]		= starfive_clk_gate("sec_ahb",		UNKNOWN,	base + 0x230);
> +	clks[CLK_AES]			= starfive_clk_gate("aes_clk",		UNKNOWN,	base + 0x234);
> +	clks[CLK_SHA]			= starfive_clk_gate("sha_clk",		UNKNOWN,	base + 0x238);
> +	clks[CLK_PKA]			= starfive_clk_gate("pka_clk",		UNKNOWN,	base + 0x23C);
> +	clks[CLK_TRNG_APB]		= starfive_clk_gate("trng_apb",		UNKNOWN,	base + 0x240);
> +	clks[CLK_OTP_APB]		= starfive_clk_gate("otp_apb",		UNKNOWN,	base + 0x244);
> +	clks[CLK_UART0_APB]		= starfive_clk_gate("uart0_apb",		UNKNOWN,	base + 0x248);
> +	clks[CLK_UART0_CORE]		= starfive_clk_gated_divider("uart0_core",		UNKNOWN,	base + 0x24C, 6);
> +	clks[CLK_UART1_APB]		= starfive_clk_gate("uart1_apb",		UNKNOWN,	base + 0x250);
> +	clks[CLK_UART1_CORE]		= starfive_clk_gated_divider("uart1_core",		UNKNOWN,	base + 0x254, 6);
> +	clks[CLK_SPI0_APB]		= starfive_clk_gate("spi0_apb",		UNKNOWN,	base + 0x258);
> +	clks[CLK_SPI0_CORE]		= starfive_clk_gated_divider("spi0_core",		UNKNOWN,	base + 0x25C, 6);
> +	clks[CLK_SPI1_APB]		= starfive_clk_gate("spi1_apb",		UNKNOWN,	base + 0x260);
> +	clks[CLK_SPI1_CORE]		= starfive_clk_gated_divider("spi1_core",		UNKNOWN,	base + 0x264, 6);
> +	clks[CLK_I2C0_APB]		= starfive_clk_gate("i2c0_apb",		UNKNOWN,	base + 0x268);
> +	clks[CLK_I2C0_CORE]		= starfive_clk_gated_divider("i2c0_core",		UNKNOWN,	base + 0x26C, 6);
> +	clks[CLK_I2C1_APB]		= starfive_clk_gate("i2c1_apb",		UNKNOWN,	base + 0x270);
> +	clks[CLK_I2C1_CORE]		= starfive_clk_gated_divider("i2c1_core",		UNKNOWN,	base + 0x274, 6);
> +	clks[CLK_GPIO_APB]		= starfive_clk_gate("gpio_apb",		UNKNOWN,	base + 0x278);
> +	clks[CLK_UART2_APB]		= starfive_clk_gate("uart2_apb",		UNKNOWN,	base + 0x27C);
> +	clks[CLK_UART2_CORE]		= starfive_clk_gated_divider("uart2_core",		UNKNOWN,	base + 0x280, 6);
> +	clks[CLK_UART3_APB]		= starfive_clk_gate("uart3_apb",		UNKNOWN,	base + 0x284);
> +	clks[CLK_UART3_CORE]		= starfive_clk_gated_divider("uart3_core",		UNKNOWN,	base + 0x288, 6);
> +	clks[CLK_SPI2_APB]		= starfive_clk_gate("spi2_apb",		UNKNOWN,	base + 0x28C);
> +	clks[CLK_SPI2_CORE]		= starfive_clk_gated_divider("spi2_core",		UNKNOWN,	base + 0x290, 6);
> +	clks[CLK_SPI3_APB]		= starfive_clk_gate("spi3_apb",		UNKNOWN,	base + 0x294);
> +	clks[CLK_SPI3_CORE]		= starfive_clk_gated_divider("spi3_core",		UNKNOWN,	base + 0x298, 6);
> +	clks[CLK_I2C2_APB]		= starfive_clk_gate("i2c2_apb",		UNKNOWN,	base + 0x29C);
> +	clks[CLK_I2C2_CORE]		= starfive_clk_gated_divider("i2c2_core",		UNKNOWN,	base + 0x2A0, 6);
> +	clks[CLK_I2C3_APB]		= starfive_clk_gate("i2c3_apb",		UNKNOWN,	base + 0x2A4);
> +	clks[CLK_I2C3_CORE]		= starfive_clk_gated_divider("i2c3_core",		UNKNOWN,	base + 0x2A8, 6);
> +	clks[CLK_WDTIMER_APB]		= starfive_clk_gate("wdtimer_apb",		UNKNOWN,	base + 0x2AC);
> +	clks[CLK_WDT_CORE]		= starfive_clk_gated_divider("wdt_coreclk",		UNKNOWN,	base + 0x2B0, 6);
> +	clks[CLK_TIMER0_CORE]		= starfive_clk_gated_divider("timer0_coreclk",		UNKNOWN,	base + 0x2B4, 6);
> +	clks[CLK_TIMER1_CORE]		= starfive_clk_gated_divider("timer1_coreclk",		UNKNOWN,	base + 0x2B8, 6);
> +	clks[CLK_TIMER2_CORE]		= starfive_clk_gated_divider("timer2_coreclk",		UNKNOWN,	base + 0x2BC, 6);
> +	clks[CLK_TIMER3_CORE]		= starfive_clk_gated_divider("timer3_coreclk",		UNKNOWN,	base + 0x2C0, 6);
> +	clks[CLK_TIMER4_CORE]		= starfive_clk_gated_divider("timer4_coreclk",		UNKNOWN,	base + 0x2C4, 6);
> +	clks[CLK_TIMER5_CORE]		= starfive_clk_gated_divider("timer5_coreclk",		UNKNOWN,	base + 0x2C8, 6);
> +	clks[CLK_TIMER6_CORE]		= starfive_clk_gated_divider("timer6_coreclk",		UNKNOWN,	base + 0x2CC, 6);
> +	clks[CLK_VP6INTC_APB]		= starfive_clk_gate("vp6intc_apb",		UNKNOWN,	base + 0x2D0);
> +	clks[CLK_PWM_APB]		= starfive_clk_gate("pwm_apb",		UNKNOWN,	base + 0x2D4);
> +	clks[CLK_MSI_APB]		= starfive_clk_gate("msi_apb",		UNKNOWN,	base + 0x2D8);
> +	clks[CLK_TEMP_APB]		= starfive_clk_gate("temp_apb",		UNKNOWN,	base + 0x2DC);
> +	clks[CLK_TEMP_SENSE]		= starfive_clk_gated_divider("temp_sense",		UNKNOWN,	base + 0x2E0, 5);
> +	clks[CLK_SYSERR_APB]		= starfive_clk_gate("syserr_apb",		UNKNOWN,	base + 0x2E4);
> +}
> +
> +static struct clk_onecell_data clk_data;
> +
> +static int starfive_clkgen_clk_probe(struct device_d *dev)
> +{
> +	struct resource *iores;
> +
> +	iores = dev_request_mem_resource(dev, 0);
> +	if (IS_ERR(iores))
> +		return PTR_ERR(iores);
> +
> +	starfive_clkgen_init(dev->device_node, IOMEM(iores->start));
> +
> +	clk_data.clks = clks;
> +	clk_data.clk_num = ARRAY_SIZE(clks);
> +	of_clk_add_provider(dev->device_node, of_clk_src_onecell_get,
> +			    &clk_data);
> +
> +	return 0;
> +}
> +
> +static __maybe_unused struct of_device_id starfive_clkgen_clk_dt_ids[] = {
> +	{ .compatible = "starfive,jh7100-clkgen" },
> +	{ /* sentinel */ }
> +};
> +
> +static struct driver_d starfive_clkgen_clk_driver = {
> +	.probe	= starfive_clkgen_clk_probe,
> +	.name	= "starfive-clkgen",
> +	.of_compatible = starfive_clkgen_clk_dt_ids,
> +};
> +core_platform_driver(starfive_clkgen_clk_driver);
> diff --git a/include/dt-bindings/clock/starfive-jh7100.h b/include/dt-bindings/clock/starfive-jh7100.h
> new file mode 100644
> index 000000000000..9ad5e7f9bfd5
> --- /dev/null
> +++ b/include/dt-bindings/clock/starfive-jh7100.h
> @@ -0,0 +1,203 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR X11 */
> +/*
> + * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
> + */
> +
> +#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H
> +#define __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H
> +
> +#define	CLK_OSC_SYS		0
> +#define	CLK_OSC_AUD		1
> +#define	CLK_PLL0_OUT		2
> +#define	CLK_PLL1_OUT		3
> +#define	CLK_PLL2_OUT		4
> +#define CLK_CPUNDBUS_ROOT	5
> +#define CLK_DLA_ROOT		6
> +#define CLK_DSP_ROOT		7
> +#define CLK_GMACUSB_ROOT	8
> +#define CLK_PERH0_ROOT		9
> +#define CLK_PERH1_ROOT		10
> +#define CLK_VIN_ROOT		11
> +#define CLK_VOUT_ROOT		12
> +#define CLK_AUDIO_ROOT		13
> +#define CLK_CDECHIFI4_ROOT	14
> +#define CLK_CDEC_ROOT		15
> +#define CLK_VOUTBUS_ROOT	16
> +#define CLK_CPUNBUS_ROOT_DIV	17
> +#define CLK_DSP_ROOT_DIV	18
> +#define CLK_PERH0_SRC		19
> +#define CLK_PERH1_SRC		20
> +#define CLK_PLL0_TESTOUT	21
> +#define CLK_PLL1_TESTOUT	22
> +#define CLK_PLL2_TESTOUT	23
> +#define CLK_PLL2_REF		24
> +#define CLK_CPU_CORE		25
> +#define CLK_CPU_AXI		26
> +#define CLK_AHB_BUS		27
> +#define CLK_APB1_BUS		28
> +#define CLK_APB2_BUS		29
> +#define CLK_DOM3AHB_BUS		30
> +#define CLK_DOM7AHB_BUS		31
> +#define CLK_U74_CORE0		32
> +#define CLK_U74_CORE1		33
> +#define CLK_U74_AXI		34
> +#define CLK_U74RTC_TOGGLE	35
> +#define CLK_SGDMA2P_AXI		35
> +#define CLK_DMA2PNOC_AXI	37
> +#define CLK_SGDMA2P_AHB		37
> +#define CLK_DLA_BUS		39
> +#define CLK_DLA_AXI		40
> +#define CLK_DLANOC_AXI		41
> +#define CLK_DLA_APB		42
> +#define CLK_VP6_CORE		43
> +#define CLK_VP6BUS_SRC		44
> +#define CLK_VP6_AXI		45
> +#define CLK_VCDECBUS_SRC	46
> +#define CLK_VDEC_BUS		47
> +#define CLK_VDEC_AXI		48
> +#define CLK_VDECBRG_MAIN	49
> +#define CLK_VDEC_BCLK		50
> +#define CLK_VDEC_CCLK		51
> +#define CLK_VDEC_APB		52
> +#define CLK_JPEG_AXI		53
> +#define CLK_JPEG_CCLK		54
> +#define CLK_JPEG_APB		55
> +#define CLK_GC300_2X		56
> +#define CLK_GC300_AHB		57
> +#define CLK_JPCGC300_AXIBUS	58
> +#define CLK_GC300_AXI		59
> +#define CLK_JPCGC300_MAIN	60
> +#define CLK_VENC_BUS		61
> +#define CLK_VENC_AXI		62
> +#define CLK_VENCBRG_MAIN	63
> +#define CLK_VENC_BCLK		64
> +#define CLK_VENC_CCLK		65
> +#define CLK_VENC_APB		66
> +#define CLK_DDRPLL_DIV2		67
> +#define CLK_DDRPLL_DIV4		68
> +#define CLK_DDRPLL_DIV8		69
> +#define CLK_DDROSC_DIV2		70
> +#define CLK_DDRC0		71
> +#define CLK_DDRC1		72
> +#define CLK_DDRPHY_APB		73
> +#define CLK_NOC_ROB		74
> +#define CLK_NOC_COG		75
> +#define CLK_NNE_AHB		76
> +#define CLK_NNEBUS_SRC1		77
> +#define CLK_NNE_BUS		78
> +#define CLK_NNE_AXI		79
> +#define CLK_NNENOC_AXI		80
> +#define CLK_DLASLV_AXI		81
> +#define CLK_DSPX2C_AXI		82
> +#define CLK_HIFI4_SRC		83
> +#define CLK_HIFI4_COREFREE	84
> +#define CLK_HIFI4_CORE		85
> +#define CLK_HIFI4_BUS		86
> +#define CLK_HIFI4_AXI		87
> +#define CLK_HIFI4NOC_AXI	88
> +#define CLK_SGDMA1P_BUS		89
> +#define CLK_SGDMA1P_AXI		90
> +#define CLK_DMA1P_AXI		91
> +#define CLK_X2C_AXI		92
> +#define CLK_USB_BUS		93
> +#define CLK_USB_AXI		94
> +#define CLK_USBNOC_AXI		95
> +#define CLK_USBPHY_ROOTDIV	96
> +#define CLK_USBPHY_125M		97
> +#define CLK_USBPHY_PLLDIV25M	98
> +#define CLK_USBPHY_25M		99
> +#define CLK_AUDIO_DIV		100
> +#define CLK_AUDIO_SRC		101
> +#define CLK_AUDIO_12288		102
> +#define CLK_VIN_SRC		103
> +#define CLK_ISP0_BUS		104
> +#define CLK_ISP0_AXI		105
> +#define CLK_ISP0NOC_AXI		106
> +#define CLK_ISPSLV_AXI		107
> +#define CLK_ISP1_BUS		108
> +#define CLK_ISP1_AXI		109
> +#define CLK_ISP1NOC_AXI		110
> +#define CLK_VIN_BUS		111
> +#define CLK_VIN_AXI		112
> +#define CLK_VINNOC_AXI		113
> +#define CLK_VOUT_SRC		114
> +#define CLK_DISPBUS_SRC		115
> +#define CLK_DISP_BUS		116
> +#define CLK_DISP_AXI		117
> +#define CLK_DISPNOC_AXI		118
> +#define CLK_SDIO0_AHB		119
> +#define CLK_SDIO0_CCLKINT	120
> +#define CLK_SDIO0_CCLKINT_INV	121
> +#define CLK_SDIO1_AHB		122
> +#define CLK_SDIO1_CCLKINT	123
> +#define CLK_SDIO1_CCLKINT_INV	124
> +#define CLK_GMAC_AHB		125
> +#define CLK_GMAC_ROOT_DIV	126
> +#define CLK_GMAC_PTP_REF	127
> +#define CLK_GMAC_GTX		128
> +#define CLK_GMAC_RMII_TX	129
> +#define CLK_GMAC_RMII_RX	130
> +#define CLK_GMAC_TX		131
> +#define CLK_GMAC_TX_INV		132
> +#define CLK_GMAC_RX_PRE		133
> +#define CLK_GMAC_RX_INV		134
> +#define CLK_GMAC_RMII		135
> +#define CLK_GMAC_TOPHYREF	136
> +#define CLK_SPI2AHB_AHB		137
> +#define CLK_SPI2AHB_CORE	138
> +#define CLK_EZMASTER_AHB	139
> +#define CLK_E24_AHB		140
> +#define CLK_E24RTC_TOGGLE	141
> +#define CLK_QSPI_AHB		142
> +#define CLK_QSPI_APB		143
> +#define CLK_QSPI_REF		144
> +#define CLK_SEC_AHB		145
> +#define CLK_AES			146
> +#define CLK_SHA			147
> +#define CLK_PKA			148
> +#define CLK_TRNG_APB		149
> +#define CLK_OTP_APB		150
> +#define CLK_UART0_APB		151
> +#define CLK_UART0_CORE		152
> +#define CLK_UART1_APB		153
> +#define CLK_UART1_CORE		154
> +#define CLK_SPI0_APB		155
> +#define CLK_SPI0_CORE		156
> +#define CLK_SPI1_APB		157
> +#define CLK_SPI1_CORE		158
> +#define CLK_I2C0_APB		159
> +#define CLK_I2C0_CORE		160
> +#define CLK_I2C1_APB		161
> +#define CLK_I2C1_CORE		162
> +#define CLK_GPIO_APB		163
> +#define CLK_UART2_APB		164
> +#define CLK_UART2_CORE		165
> +#define CLK_UART3_APB		166
> +#define CLK_UART3_CORE		167
> +#define CLK_SPI2_APB		168
> +#define CLK_SPI2_CORE		169
> +#define CLK_SPI3_APB		170
> +#define CLK_SPI3_CORE		171
> +#define CLK_I2C2_APB		172
> +#define CLK_I2C2_CORE		173
> +#define CLK_I2C3_APB		174
> +#define CLK_I2C3_CORE		175
> +#define CLK_WDTIMER_APB		176
> +#define CLK_WDT_CORE		177
> +#define CLK_TIMER0_CORE		178
> +#define CLK_TIMER1_CORE		179
> +#define CLK_TIMER2_CORE		180
> +#define CLK_TIMER3_CORE		181
> +#define CLK_TIMER4_CORE		182
> +#define CLK_TIMER5_CORE		183
> +#define CLK_TIMER6_CORE		184
> +#define CLK_VP6INTC_APB		185
> +#define CLK_PWM_APB		186
> +#define CLK_MSI_APB		187
> +#define CLK_TEMP_APB		188
> +#define CLK_TEMP_SENSE		189
> +#define CLK_SYSERR_APB		190
> +
> +#define CLK_END			191
> +
> +#endif
> 

-- 
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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 03/20] mfd: add TI TPS65086 PMIC restart driver
  2021-05-31  7:38 ` [PATCH 03/20] mfd: add TI TPS65086 PMIC restart driver Ahmad Fatoum
@ 2021-06-07  6:44   ` Sascha Hauer
  0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2021-06-07  6:44 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

Hi Ahmad,

On Mon, May 31, 2021 at 09:38:04AM +0200, Ahmad Fatoum wrote:
> +#include <common.h>
> +#include <driver.h>
> +#include <errno.h>
> +#include <i2c/i2c.h>
> +#include <linux/mfd/core.h>
> +#include <init.h>
> +#include <malloc.h>
> +#include <of.h>
> +#include <regmap.h>
> +#include <xfuncs.h>
> +
> +#include <linux/mfd/tps65086.h>
> +
> +static const struct mfd_cell tps65086_cells[] = {
> +	{ .name = "tps65086-regulator", },
> +	{ .name = "tps65086-gpio", },
> +};

Ok to have cells here which do not have a driver yet,

> +static struct driver_d tps65086_restart_driver = {
> +	.name = "tps65086-restart",
> +	.probe = tps65086_restart_probe,
> +};

but you should register the cells for the existing driver.

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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 04/20] mtd: spi-nor: cadence: fix 64-bit issues
  2021-05-31  7:38 ` [PATCH 04/20] mtd: spi-nor: cadence: fix 64-bit issues Ahmad Fatoum
@ 2021-06-07  6:51   ` Sascha Hauer
  0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2021-06-07  6:51 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Mon, May 31, 2021 at 09:38:05AM +0200, Ahmad Fatoum wrote:
> Pointers are being cast to unsigned int, which will truncate the address
> on 64-bit systems. Fix this.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
>  drivers/mtd/spi-nor/cadence-quadspi.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
> index ea53d2cd847a..09015aad43f1 100644
> --- a/drivers/mtd/spi-nor/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/cadence-quadspi.c
> @@ -347,8 +347,8 @@ static int cqspi_command_read(struct spi_nor *nor,
>  
>  	if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || rxbuf == NULL) {
>  		dev_err(nor->dev,
> -			"Invalid input argument, len %d rxbuf 0x%08x\n", n_rx,
> -			(unsigned int)rxbuf);
> +			"Invalid input argument, len %d rxbuf %p\n", n_rx,
> +			rxbuf);
>  		return -EINVAL;
>  	}
>  
> @@ -393,8 +393,8 @@ static __maybe_unused int cqspi_command_write(struct spi_nor *nor,
>  
>  	if (n_tx > 4 || (n_tx && txbuf == NULL)) {
>  		dev_err(nor->dev,
> -			"Invalid input argument, cmdlen %d txbuf 0x%08x\n",
> -			n_tx, (unsigned int)txbuf);
> +			"Invalid input argument, cmdlen %d txbuf %p\n",
> +			n_tx, txbuf);
>  		return -EINVAL;
>  	}
>  
> @@ -433,7 +433,7 @@ static int cqspi_indirect_read_setup(struct spi_nor *nor,
>  {
>  	struct cqspi_flash_pdata *f_pdata;
>  	struct cqspi_st *cqspi = nor->priv;
> -	unsigned int ahb_base = (unsigned int) cqspi->ahb_base;
> +	unsigned long ahb_base = (unsigned long) cqspi->ahb_base;

This makes the warning disappear, but not the underlying problem. The
ahb_base is written to a 32bit register later, so this won't work on
machines which have memory outside the 32bit range.
We had this problem earlier. What did we do there? I think we should
warn when this happens.

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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/20] RISC-V: support incoherent I-Cache
  2021-05-31  7:40   ` Ahmad Fatoum
@ 2021-06-07  7:33     ` Ahmad Fatoum
  0 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-06-07  7:33 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox

On 31.05.21 09:40, Ahmad Fatoum wrote:
> Hello Antony,
> 
> On 31.05.21 09:38, Ahmad Fatoum wrote:
>> SiFive SoCs have separate I-Caches that require self-modifying code
>> like barebox' relocation and PBL extraction code to do cache
>> maintenance. Implement sync_caches_for_execution and use it where
>> appropriate.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---

>> +void sync_caches_for_execution(void)
>> +{
>> +	if (IS_ENABLED(CONFIG_HAS_CACHE))
>> +		asm volatile ("fence.i" ::: "memory");
> 
> If Erizo on FPGA chokes on this, we can have it pass
> along a feature flag from PBL that says it doesn't
> need cache maintenance. Please advise.

I now skip over fence.i in the exception handler, so it should be ok
to call this, even on systems that lack Zifencei ISA extension.

I'll send out a v2 soon.

-- 
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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 11/20] dma: support marking SRAM for coherent DMA use
  2021-05-31  7:38 ` [PATCH 11/20] dma: support marking SRAM for coherent DMA use Ahmad Fatoum
@ 2021-06-07  7:34   ` Sascha Hauer
  2021-06-07  7:40     ` Ahmad Fatoum
  2021-06-07  7:39   ` Sascha Hauer
  1 sibling, 1 reply; 30+ messages in thread
From: Sascha Hauer @ 2021-06-07  7:34 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Mon, May 31, 2021 at 09:38:12AM +0200, Ahmad Fatoum wrote:
> The RISC-V architecture allows overriding the dma_alloc_coherent and
> dma_free_coherent. Allow this to be controlled by device tree.
> 
> Cache-coherent SoCs won't need this, but incoherent ones that have
> uncached regions can register them here.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> +static void *pool_alloc_coherent(size_t size, dma_addr_t *dma_handle)
> +{
> +	struct dma_coherent_pool *pool;
> +	void *ret = NULL;
> +
> +	list_for_each_entry(pool, &pools, list) {
> +		ret = tlsf_memalign(pool->handle, DMA_ALIGNMENT, size);
> +		if (!ret)
> +			continue;
> +	}
> +
> +	BUG_ON(!ret);

Being out of memory is no bug, no?

> +
> +	memset(ret, 0, size);
> +
> +	if (dma_handle)
> +		*dma_handle = (dma_addr_t)ret;
> +
> +	pr_debug("alloc(%zu) == %p\n", size, ret);
> +
> +	return ret;
> +}
> +
> +static void pool_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
> +{
> +	resource_size_t addr = (resource_size_t)vaddr;
> +	struct dma_coherent_pool *pool;
> +
> +	list_for_each_entry(pool, &pools, list) {
> +		if (pool->resource->start <= addr && addr <= pool->resource->end) {

Nice :)
I would have written if (addr >= start && addr <= end), but the way you
have written it makes it visually clear from the first sight that addr
should be in that specific range.

> +			tlsf_free(pool->handle, vaddr);
> +			return;
> +		}
> +	}
> +
> +	pr_warn("freeing invalid region: %p\n", vaddr);
> +}
> +
> +static const struct dma_coherent_ops pool_ops = {
> +	.alloc = pool_alloc_coherent,
> +	.free = pool_free_coherent,
> +};
> +
> +static int compare_pool_sizes(struct list_head *_a, struct list_head *_b)
> +{
> +	struct dma_coherent_pool *a = list_entry(_a, struct dma_coherent_pool, list);
> +	struct dma_coherent_pool *b = list_entry(_b, struct dma_coherent_pool, list);
> +
> +	if (resource_size(a->resource) > resource_size(b->resource))
> +		return 1;
> +	if (resource_size(a->resource) < resource_size(b->resource))
> +		return -1;
> +	return 0;
> +}
> +
> +static int dma_declare_coherent_pool(const struct resource *res)
> +{
> +	struct dma_coherent_pool *pool;
> +	tlsf_t handle;
> +
> +	handle = tlsf_create_with_pool((void *)res->start, resource_size(res));
> +	if (!handle)
> +		return -EINVAL;
> +
> +	pool = xmalloc(sizeof(*pool));

Better xzalloc()? It's too easy to add some element to a structure and
assume that it's initialized.

> +	pool->handle = handle;
> +	pool->resource = res;
> +
> +	list_add_sort(&pool->list, &pools, compare_pool_sizes);

The pools are sorted by their size, but is this a good criterion for the
pools priority?

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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 11/20] dma: support marking SRAM for coherent DMA use
  2021-05-31  7:38 ` [PATCH 11/20] dma: support marking SRAM for coherent DMA use Ahmad Fatoum
  2021-06-07  7:34   ` Sascha Hauer
@ 2021-06-07  7:39   ` Sascha Hauer
  1 sibling, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2021-06-07  7:39 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Mon, May 31, 2021 at 09:38:12AM +0200, Ahmad Fatoum wrote:
> The RISC-V architecture allows overriding the dma_alloc_coherent and
> dma_free_coherent. Allow this to be controlled by device tree.
> 
> Cache-coherent SoCs won't need this, but incoherent ones that have
> uncached regions can register them here.
> 
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
>  common/Kconfig              |   4 ++
>  common/Makefile             |   3 +-
>  drivers/dma/Kconfig         |   6 ++
>  drivers/dma/Makefile        |   1 +
>  drivers/dma/coherent-pool.c | 120 ++++++++++++++++++++++++++++++++++++
>  5 files changed, 133 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/dma/coherent-pool.c
> 
> diff --git a/common/Kconfig b/common/Kconfig
> index ce349d4ebbf6..dbbcbb946fff 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -303,6 +303,9 @@ config EXPERIMENTAL
>  	bool
>  	prompt "Prompt for experimental code"
>  
> +config TLSF
> +	bool
> +
>  choice
>  	prompt "malloc implementation"
>  
> @@ -311,6 +314,7 @@ config MALLOC_DLMALLOC
>  
>  config MALLOC_TLSF
>  	bool "tlsf"
> +	select TLSF
>  
>  config MALLOC_DUMMY
>  	bool "dummy malloc"
> diff --git a/common/Makefile b/common/Makefile
> index 382a4f661f67..0777d2030c99 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -40,7 +40,8 @@ obj-$(CONFIG_GLOBALVAR)		+= globalvar.o
>  obj-$(CONFIG_GREGORIAN_CALENDER) += date.o
>  obj-$(CONFIG_KALLSYMS)		+= kallsyms.o
>  obj-$(CONFIG_MALLOC_DLMALLOC)	+= dlmalloc.o
> -obj-$(CONFIG_MALLOC_TLSF)	+= tlsf_malloc.o tlsf.o calloc.o
> +obj-$(CONFIG_TLSF)		+= tlsf.o
> +obj-$(CONFIG_MALLOC_TLSF)	+= tlsf_malloc.o calloc.o
>  KASAN_SANITIZE_tlsf.o := n
>  obj-$(CONFIG_MALLOC_DUMMY)	+= dummy_malloc.o calloc.o
>  obj-$(CONFIG_MEMINFO)		+= meminfo.o
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index c75fc8b9811f..6bc915585fbe 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -1,5 +1,11 @@
>  menu "DMA support"
>  
> +config DMA_COHERENT_POOLS
> +	bool
> +	depends on RISCV
> +	select TLSF
> +	imply SRAM

This symbol is invisible and selected when needed. We shouldn't need
this "depends on RISCV"

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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 11/20] dma: support marking SRAM for coherent DMA use
  2021-06-07  7:34   ` Sascha Hauer
@ 2021-06-07  7:40     ` Ahmad Fatoum
  0 siblings, 0 replies; 30+ messages in thread
From: Ahmad Fatoum @ 2021-06-07  7:40 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

Hi,

On 07.06.21 09:34, Sascha Hauer wrote:
> On Mon, May 31, 2021 at 09:38:12AM +0200, Ahmad Fatoum wrote:
>> The RISC-V architecture allows overriding the dma_alloc_coherent and
>> dma_free_coherent. Allow this to be controlled by device tree.
>>
>> Cache-coherent SoCs won't need this, but incoherent ones that have
>> uncached regions can register them here.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>> +static void *pool_alloc_coherent(size_t size, dma_addr_t *dma_handle)
>> +{
>> +	struct dma_coherent_pool *pool;
>> +	void *ret = NULL;
>> +
>> +	list_for_each_entry(pool, &pools, list) {
>> +		ret = tlsf_memalign(pool->handle, DMA_ALIGNMENT, size);
>> +		if (!ret)
>> +			continue;
>> +	}
>> +
>> +	BUG_ON(!ret);
> 
> Being out of memory is no bug, no?

It's for dma_alloc_coherent. Other archs use xmemalign and have no handling for
error cases.

> 
>> +
>> +	memset(ret, 0, size);
>> +
>> +	if (dma_handle)
>> +		*dma_handle = (dma_addr_t)ret;
>> +
>> +	pr_debug("alloc(%zu) == %p\n", size, ret);
>> +
>> +	return ret;
>> +}
>> +
>> +static void pool_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
>> +{
>> +	resource_size_t addr = (resource_size_t)vaddr;
>> +	struct dma_coherent_pool *pool;
>> +
>> +	list_for_each_entry(pool, &pools, list) {
>> +		if (pool->resource->start <= addr && addr <= pool->resource->end) {
> 
> Nice :)
> I would have written if (addr >= start && addr <= end), but the way you
> have written it makes it visually clear from the first sight that addr
> should be in that specific range.

Since I posted this series, someone nudged me into a better direction:
Set dma_addr to the cached alias address, which is < 32-bit and return
from alloc_coherent a > 32-bit address within the uncached alias.

As the devices aren't cache coherent, it doesn't matter that the alias they
get is the uncached one.

> 
>> +			tlsf_free(pool->handle, vaddr);
>> +			return;
>> +		}
>> +	}
>> +
>> +	pr_warn("freeing invalid region: %p\n", vaddr);
>> +}
>> +
>> +static const struct dma_coherent_ops pool_ops = {
>> +	.alloc = pool_alloc_coherent,
>> +	.free = pool_free_coherent,
>> +};
>> +
>> +static int compare_pool_sizes(struct list_head *_a, struct list_head *_b)
>> +{
>> +	struct dma_coherent_pool *a = list_entry(_a, struct dma_coherent_pool, list);
>> +	struct dma_coherent_pool *b = list_entry(_b, struct dma_coherent_pool, list);
>> +
>> +	if (resource_size(a->resource) > resource_size(b->resource))
>> +		return 1;
>> +	if (resource_size(a->resource) < resource_size(b->resource))
>> +		return -1;
>> +	return 0;
>> +}
>> +
>> +static int dma_declare_coherent_pool(const struct resource *res)
>> +{
>> +	struct dma_coherent_pool *pool;
>> +	tlsf_t handle;
>> +
>> +	handle = tlsf_create_with_pool((void *)res->start, resource_size(res));
>> +	if (!handle)
>> +		return -EINVAL;
>> +
>> +	pool = xmalloc(sizeof(*pool));
> 
> Better xzalloc()? It's too easy to add some element to a structure and
> assume that it's initialized.
> 
>> +	pool->handle = handle;
>> +	pool->resource = res;
>> +
>> +	list_add_sort(&pool->list, &pools, compare_pool_sizes);
> 
> The pools are sorted by their size, but is this a good criterion for the
> pools priority?

The idea was to have some fixed order, so issues are easier to debug.
With the changes described above, this commit can be replaced.
(The dma_set_ops one before will remain).

Cheers,
Ahmad

> 
> 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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 18/20] reset: add StarFive reset controller driver
  2021-05-31  7:38 ` [PATCH 18/20] reset: add StarFive reset controller driver Ahmad Fatoum
@ 2021-06-07  8:00   ` Sascha Hauer
  0 siblings, 0 replies; 30+ messages in thread
From: Sascha Hauer @ 2021-06-07  8:00 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

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@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 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2021-06-07  8:02 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-31  7:38 [PATCH 00/20] RISC-V: prepare for BeagleV pre-production board support Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 01/20] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 02/20] net: designware: add support for IP integrated into StarFive SoC Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 03/20] mfd: add TI TPS65086 PMIC restart driver Ahmad Fatoum
2021-06-07  6:44   ` Sascha Hauer
2021-05-31  7:38 ` [PATCH 04/20] mtd: spi-nor: cadence: fix 64-bit issues Ahmad Fatoum
2021-06-07  6:51   ` Sascha Hauer
2021-05-31  7:38 ` [PATCH 05/20] nvmem: add StarFive OTP support Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 06/20] RISC-V: dma: support multiple dma_alloc_coherent backends Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 07/20] RISC-V: support incoherent I-Cache Ahmad Fatoum
2021-05-31  7:40   ` Ahmad Fatoum
2021-06-07  7:33     ` Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 08/20] soc: add support for StarFive JH7100 incoherent interconnect Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 09/20] soc: sifive: l2_cache: enable maximum available cache ways Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 10/20] net: designware: fix 64-bit incompatibilities Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 11/20] dma: support marking SRAM for coherent DMA use Ahmad Fatoum
2021-06-07  7:34   ` Sascha Hauer
2021-06-07  7:40     ` Ahmad Fatoum
2021-06-07  7:39   ` Sascha Hauer
2021-05-31  7:38 ` [PATCH 12/20] mci: allocate DMA-able memory Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 13/20] mci: allocate sector_buf on demand Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 14/20] dma: allocate 32-byte aligned buffers by default Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 15/20] mci: dw_mmc: enable use on 64-bit CPUs Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 16/20] mci: dw_mmc: match against generic "snps, dw-mshc" compatible Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 17/20] clk: add initial StarFive clock support Ahmad Fatoum
2021-05-31  8:41   ` Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 18/20] reset: add StarFive reset controller driver Ahmad Fatoum
2021-06-07  8:00   ` Sascha Hauer
2021-05-31  7:38 ` [PATCH 19/20] watchdog: add StarFive watchdog driver Ahmad Fatoum
2021-05-31  7:38 ` [PATCH 20/20] hw_random: add driver for RNG on StarFive SoC Ahmad Fatoum

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox