mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 00/29] RISC-V: add BeagleV Beta board support
@ 2021-06-19  4:50 Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 01/29] clocksource: RISC-V: demote probe success messages to debug level Ahmad Fatoum
                   ` (29 more replies)
  0 siblings, 30 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox

The changes allow barebox to run second stage (after ddrinit and second
boot) on the BeagleV beta board. It does everything necessary to support
Ethernet, MMC, GPIO, pinmux, pinconf, clock, reset, watchdog, HWRNG and
DMA between CPU and the cache-incoherent DMA masters.

The current vendor kernel doesn't care much for low-level
initialization, depending on pinmux, pinconf, clock and reset to happen
completely in the bootloader. This makes an initial bootloader port
much more complex, because you need not only care about the peripherals
you use yourself, but those that Linux may want to access to.

For this reason, there is a starfive-pwrseq driver that binds against
some nodes like the neural network accelerator, which we will probably
never support, but at least tickles it resets and enables its clocks.

Some peripherals require writing magic values into registers, which
this series doesn't do. If your boot hangs, consider checking out:

https://github.com/a3f/barebox/tree/beaglev

instead, which imports some vendor boot code to support more
peripherals. This series is sufficient to have barebox boot kernels that
do their own initialization though. Problem is there are no such kernels
yet ^^.

Candidates for further steps:

 - Support more peripherals in starfive-pwrseq
 - Get Designware i2c controller working, so we can use PMIC for reset
 - Get Cadence QSPI working, so barebox can flash itself and use
   environment on flash
 - Figure out the ticket lottery stuff, so we can boot multi-core
 - Replace ddrinit and secondboot with PBL, load from there opensbi
   and then return to barebox proper
 - Complete missing clock tree info when Documentation is available

I can use a hand impementing these, so patches are most certainly
welcome (Antony, I am looking at you ;-).

v1 was here:
	https://lore.barebox.org/barebox/20210531073821.15257-1-a.fatoum@pengutronix.de/

v1 -> v2:
  - Dropped untested PMIC and flash chip commits. i2c and qspi controller
    drivers in tree don't yet work for BeagleV
  - remove clocksource clutter from console
  - import S-/M-Mode multi-image series, so we can build all images for
    the same ISA in one go
  - Drop barebox,provide-mac-address from OTP driver. This is now done
    via nvmem-cells reference
  - Replace coherent memory from SRAM allocator with non-1:1 mapping:
    Give devices the cached <= 32 bit address, as they are
    cache-incoherent anyway, and use the > 32 bit uncached address from
    CPU side. Works beautifully
  - Drop 64-bit-conversion for dw_mmc. Sascha did it for rk3568 and it
    works for BeagleV too
  - Check Designware ETH coherent memory allocation against mask
  - Rebase on newest clock changes
  - Disable clocks after resets (Sascha)
  - Move repsonsibility of keeping reset-synchronous clocks needed
    for normal operation enabled to drivers (Sascha, off-list)
  - Handle fence.i trap in exception handler to support SoCs without
    Zifencei ISA extension
  - Add some static clock initialization to starfive-pwrseq driver
  - Add pinctrl driver support
  - Add GPIO driver support
  - Add board support


Ahmad Fatoum (29):
  clocksource: RISC-V: demote probe success messages to debug level
  RISC-V: virt: select only one timer
  RISC-V: extend multi-image to support both S- and M-Mode
  RISC-V: cpuinfo: return some output for non-SBI systems as well
  RISC-V: S-Mode: propagate Hart ID
  RISC-V: erizo: make it easier to reuse ns16550 debug_ll
  RISC-V: socs: add Kconfig entry for StarFive JH7100
  nvmem: add StarFive OTP support
  RISC-V: dma: support multiple dma_alloc_coherent backends
  RISC-V: add exception support
  RISC-V: support incoherent I-Cache
  drivers: soc: sifive: add basic L2 cache controller driver
  soc: starfive: add support for JH7100 incoherent interconnect
  soc: sifive: l2_cache: enable maximum available cache ways
  net: designware: fix non-1:1 mapped 64-bit systems
  net: designware: add support for IP integrated into StarFive SoC
  mci: allocate DMA-able memory
  mci: allocate sector_buf on demand
  dma: allocate 32-byte aligned buffers by default
  mci: dw_mmc: add optional reset line
  mci: dw_mmc: match against StarFive MMC compatibles
  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
  reset: add device_reset_all helper
  gpio: add support for StarFive GPIO controller
  misc: add power sequencing driver for initializing StarFive
    peripherals
  RISC-V: StarFive: add board support for BeagleV Starlight

 Documentation/boards/riscv.rst                |  37 +
 arch/riscv/Kconfig                            |  19 +-
 arch/riscv/Kconfig.socs                       |  56 +-
 arch/riscv/boards/Makefile                    |   1 +
 arch/riscv/boards/beaglev/Makefile            |   5 +
 arch/riscv/boards/beaglev/board.c             |  30 +
 .../beaglev/defaultenv-beaglev/boot/buildroot |  13 +
 .../beaglev/defaultenv-beaglev/boot/fedora    |  16 +
 .../defaultenv-beaglev/nv/boot.default        |   1 +
 arch/riscv/boards/beaglev/lowlevel.c          |  18 +
 arch/riscv/boards/erizo/lowlevel.c            |   6 +-
 arch/riscv/boards/hifive/lowlevel.c           |  17 +-
 arch/riscv/boot/board-dt-2nd.c                |   4 +-
 arch/riscv/boot/entry.c                       |   5 +-
 arch/riscv/boot/entry.h                       |   6 +-
 arch/riscv/boot/start.c                       |  15 +-
 arch/riscv/boot/uncompress.c                  |  11 +-
 arch/riscv/configs/starfive_defconfig         | 131 +++
 arch/riscv/cpu/Makefile                       |   4 +
 arch/riscv/cpu/core.c                         |  40 +-
 arch/riscv/cpu/dma.c                          |  74 ++
 arch/riscv/cpu/interrupts.c                   | 139 +++
 arch/riscv/cpu/mtrap.S                        |  30 +
 arch/riscv/cpu/strap.S                        |  30 +
 arch/riscv/dts/Makefile                       |   1 +
 arch/riscv/dts/jh7100-beaglev-starlight.dts   |  54 ++
 arch/riscv/dts/jh7100-beaglev-starlight.dtsi  | 369 ++++++++
 arch/riscv/dts/jh7100.dtsi                    | 798 ++++++++++++++++++
 arch/riscv/include/asm/asm-offsets.h          |   1 +
 arch/riscv/include/asm/barebox-riscv.h        |  14 +-
 arch/riscv/include/asm/barrier.h              |  27 +
 arch/riscv/include/asm/cacheflush.h           |  16 +
 arch/riscv/include/asm/debug_ll.h             |  10 +-
 arch/riscv/include/asm/dma.h                  |  48 +-
 arch/riscv/include/asm/io.h                   |  10 +
 arch/riscv/include/asm/irq.h                  | 107 +++
 arch/riscv/include/asm/ptrace.h               | 143 ++++
 arch/riscv/include/asm/sbi.h                  |   8 +-
 arch/riscv/include/asm/system.h               |  61 ++
 arch/riscv/include/asm/unwind.h               |   9 +
 arch/riscv/lib/asm-offsets.c                  |  46 +
 arch/riscv/lib/bootm.c                        |   4 +-
 arch/riscv/lib/cpuinfo.c                      |  56 +-
 arch/riscv/lib/reloc.c                        |   8 +
 arch/riscv/lib/sbi.c                          |   4 +
 arch/riscv/lib/setupc.S                       |   2 +
 commands/Kconfig                              |   4 +-
 common/Kconfig                                |  11 +
 common/globalvar.c                            |  21 +
 common/oftree.c                               |  19 +-
 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/clocksource/timer-clint.c             |   7 +-
 drivers/clocksource/timer-riscv.c             |   5 +-
 drivers/gpio/Kconfig                          |   8 +
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-starfive-vic.c              | 177 ++++
 drivers/hw_random/Kconfig                     |   7 +
 drivers/hw_random/Makefile                    |   1 +
 drivers/hw_random/starfive-vic-rng.c          | 208 +++++
 drivers/mci/dw_mmc.c                          |  23 +-
 drivers/mci/mci-core.c                        |  15 +-
 drivers/misc/Kconfig                          |  10 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/starfive-pwrseq.c                |  92 ++
 drivers/net/Kconfig                           |   8 +
 drivers/net/Makefile                          |   1 +
 drivers/net/designware.c                      |  64 +-
 drivers/net/designware.h                      |  29 +-
 drivers/net/designware_starfive.c             | 110 +++
 drivers/nvmem/Kconfig                         |   8 +
 drivers/nvmem/Makefile                        |   2 +
 drivers/nvmem/starfive-otp.c                  | 201 +++++
 drivers/pinctrl/pinctrl-single.c              |   4 +-
 drivers/reset/Kconfig                         |   6 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/core.c                          |  78 +-
 drivers/reset/reset-starfive-vic.c            | 234 +++++
 drivers/soc/Makefile                          |   5 +
 drivers/soc/sifive/Makefile                   |   1 +
 drivers/soc/sifive/sifive_l2_cache.c          | 136 +++
 drivers/soc/starfive/Makefile                 |   1 +
 drivers/soc/starfive/jh7100_dma.c             |  55 ++
 drivers/watchdog/Kconfig                      |   7 +
 drivers/watchdog/Makefile                     |   1 +
 drivers/watchdog/starfive_wdt.c               | 106 +++
 images/Makefile.riscv                         |   4 +
 include/dma.h                                 |   7 +-
 include/dt-bindings/clock/starfive-jh7100.h   | 203 +++++
 .../reset-controller/starfive-jh7100.h        | 126 +++
 include/globalvar.h                           |   8 +
 include/linux/reset.h                         |   7 +
 include/pinctrl.h                             |   6 +
 include/soc/sifive/l2_cache.h                 |  10 +
 include/soc/starfive/rstgen.h                 |  41 +
 include/soc/starfive/sysmain.h                |  15 +
 99 files changed, 4878 insertions(+), 154 deletions(-)
 create mode 100644 arch/riscv/boards/beaglev/Makefile
 create mode 100644 arch/riscv/boards/beaglev/board.c
 create mode 100755 arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot
 create mode 100755 arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora
 create mode 100644 arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default
 create mode 100644 arch/riscv/boards/beaglev/lowlevel.c
 create mode 100644 arch/riscv/configs/starfive_defconfig
 create mode 100644 arch/riscv/cpu/dma.c
 create mode 100644 arch/riscv/cpu/interrupts.c
 create mode 100644 arch/riscv/cpu/mtrap.S
 create mode 100644 arch/riscv/cpu/strap.S
 create mode 100644 arch/riscv/dts/jh7100-beaglev-starlight.dts
 create mode 100644 arch/riscv/dts/jh7100-beaglev-starlight.dtsi
 create mode 100644 arch/riscv/dts/jh7100.dtsi
 create mode 100644 arch/riscv/include/asm/asm-offsets.h
 create mode 100644 arch/riscv/include/asm/barrier.h
 create mode 100644 arch/riscv/include/asm/cacheflush.h
 create mode 100644 arch/riscv/include/asm/irq.h
 create mode 100644 arch/riscv/include/asm/ptrace.h
 create mode 100644 arch/riscv/include/asm/system.h
 create mode 100644 arch/riscv/include/asm/unwind.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/gpio/gpio-starfive-vic.c
 create mode 100644 drivers/hw_random/starfive-vic-rng.c
 create mode 100644 drivers/misc/starfive-pwrseq.c
 create mode 100644 drivers/net/designware_starfive.c
 create mode 100644 drivers/nvmem/starfive-otp.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/soc/starfive/Makefile
 create mode 100644 drivers/soc/starfive/jh7100_dma.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/soc/sifive/l2_cache.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] 33+ messages in thread

* [PATCH v2 01/29] clocksource: RISC-V: demote probe success messages to debug level
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 02/29] RISC-V: virt: select only one timer Ahmad Fatoum
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

There's always some clocksource driver loaded, so reporting it probed
successfully doesn't add much value. timebase-frequency can be read
from the device tree if needed and which drivers were probed successfully
can be seen in drvinfo output, so demote both riscv and clint timer
messages to debug level.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/clocksource/timer-clint.c | 2 +-
 drivers/clocksource/timer-riscv.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c
index b7360010bdb6..4eeb9cf7ffc9 100644
--- a/drivers/clocksource/timer-clint.c
+++ b/drivers/clocksource/timer-clint.c
@@ -72,7 +72,7 @@ static int clint_timer_init_dt(struct device_d* dev)
 		return PTR_ERR(iores);
 	clint_timer_val = IOMEM(iores->start) + CLINT_TIMER_VAL_OFF;
 
-	dev_info(dev, "running at %lu Hz\n", riscv_timebase);
+	dev_dbg(dev, "running at %lu Hz\n", riscv_timebase);
 
 	clint_clocksource.mult = clocksource_hz2mult(riscv_timebase, clint_clocksource.shift);
 
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index ef67cff47555..c2d32b36bbc5 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -59,7 +59,7 @@ static struct clocksource riscv_clocksource = {
 
 static int riscv_timer_init(struct device_d* dev)
 {
-	dev_info(dev, "running at %lu Hz\n", riscv_timebase);
+	dev_dbg(dev, "running at %lu Hz\n", riscv_timebase);
 
 	riscv_clocksource.mult = clocksource_hz2mult(riscv_timebase, riscv_clocksource.shift);
 
-- 
2.29.2


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


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

* [PATCH v2 02/29] RISC-V: virt: select only one timer
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 01/29] clocksource: RISC-V: demote probe success messages to debug level Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 03/29] RISC-V: extend multi-image to support both S- and M-Mode Ahmad Fatoum
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

S-Mode should use the riscv timer, so no need to select CLINT timer for
virt.

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

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index c6875738d05c..fd36745755e0 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -16,7 +16,6 @@ config BOARD_ERIZO_GENERIC
 config SOC_VIRT
 	bool "QEMU Virt Machine"
 	select BOARD_RISCV_GENERIC_DT
-	select CLINT_TIMER
 	help
 	  Generates an image tht can be be booted by QEMU. The image is called
 	  barebox-dt-2nd.img
-- 
2.29.2


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


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

* [PATCH v2 03/29] RISC-V: extend multi-image to support both S- and M-Mode
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 01/29] clocksource: RISC-V: demote probe success messages to debug level Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 02/29] RISC-V: virt: select only one timer Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 04/29] RISC-V: cpuinfo: return some output for non-SBI systems as well Ahmad Fatoum
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

We can't currently mix S-Mode and M-Mode images in the same build
and there's no straight-forward way to determine which mode we are in.

Move the decision on which mode barebox is targeted at out of Kconfig
and into the PBL. PBL code can call either barebox_riscv_supervisor_entry
or barebox_riscv_machine_entry to signal to barebox proper which mode
it's running in. Currently the only user of this information is the
RISC-V timer clocksource driver.

Any new code that does IS_ENABLED(CONFIG_RISCV_SBI) or
IS_ENABLED(CONFIG_RISCV_M_MODE) should also be adapted to use riscv_mode().

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/Kconfig                     | 14 +++++----
 arch/riscv/Kconfig.socs                |  2 ++
 arch/riscv/boards/erizo/lowlevel.c     |  6 ++--
 arch/riscv/boards/hifive/lowlevel.c    | 17 ++++++-----
 arch/riscv/boot/board-dt-2nd.c         |  2 +-
 arch/riscv/boot/entry.c                |  5 ++--
 arch/riscv/boot/entry.h                |  6 ++--
 arch/riscv/boot/start.c                | 12 +++++---
 arch/riscv/boot/uncompress.c           |  6 ++--
 arch/riscv/include/asm/barebox-riscv.h | 10 ++++++-
 arch/riscv/include/asm/system.h        | 41 ++++++++++++++++++++++++++
 arch/riscv/lib/sbi.c                   |  4 +++
 drivers/clocksource/timer-clint.c      |  5 ++--
 drivers/clocksource/timer-riscv.c      |  3 +-
 14 files changed, 102 insertions(+), 31 deletions(-)
 create mode 100644 arch/riscv/include/asm/system.h

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index a4aa799acf01..bbafdea1b959 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -97,14 +97,18 @@ config NMON_HELP
 	  Say yes here to get the nmon commands message on
 	  every nmon start.
 
-# set if we run in machine mode, cleared if we run in supervisor mode
+# selected by boards where barebox runs in machine mode
 config RISCV_M_MODE
 	bool
 
-# set if we are running in S-mode and can use SBI calls
-config RISCV_SBI
+# selected by boards where barebox runs in supervisor mode
+config RISCV_S_MODE
 	bool
-	depends on !RISCV_M_MODE
-	default y
+
+config RISCV_MULTI_MODE
+	def_bool RISCV_S_MODE && RISCV_M_MODE
+
+config RISCV_SBI
+	def_bool RISCV_S_MODE
 
 endmenu
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index fd36745755e0..f1b431555fcd 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -15,6 +15,7 @@ config BOARD_ERIZO_GENERIC
 
 config SOC_VIRT
 	bool "QEMU Virt Machine"
+	select RISCV_S_MODE
 	select BOARD_RISCV_GENERIC_DT
 	help
 	  Generates an image tht can be be booted by QEMU. The image is called
@@ -22,6 +23,7 @@ config SOC_VIRT
 
 config SOC_SIFIVE
 	bool "SiFive SoCs"
+	select RISCV_S_MODE
 	select CLK_SIFIVE
 	select CLK_SIFIVE_PRCI
 	select RISCV_TIMER
diff --git a/arch/riscv/boards/erizo/lowlevel.c b/arch/riscv/boards/erizo/lowlevel.c
index 6acf15931cdf..fc262ed61b56 100644
--- a/arch/riscv/boards/erizo/lowlevel.c
+++ b/arch/riscv/boards/erizo/lowlevel.c
@@ -7,12 +7,14 @@
 ENTRY_FUNCTION(start_erizo_generic, a0, a1, a2)
 {
 	extern char __dtb_z_erizo_generic_start[];
+	void *fdt;
 
 	debug_ll_init();
 	putc_ll('>');
 
 	/* On POR, we are running from read-only memory here. */
 
-	barebox_riscv_entry(0x80000000, SZ_8M,
-			    __dtb_z_erizo_generic_start + get_runtime_offset());
+	fdt = __dtb_z_erizo_generic_start + get_runtime_offset();
+
+	barebox_riscv_machine_entry(0x80000000, SZ_8M, fdt);
 }
diff --git a/arch/riscv/boards/hifive/lowlevel.c b/arch/riscv/boards/hifive/lowlevel.c
index 1de13cac1688..8a20f3c51d40 100644
--- a/arch/riscv/boards/hifive/lowlevel.c
+++ b/arch/riscv/boards/hifive/lowlevel.c
@@ -4,22 +4,23 @@
 #include <asm/barebox-riscv.h>
 #include <debug_ll.h>
 
+static __always_inline void start_hifive(void *fdt)
+{
+	putc_ll('>');
+
+	barebox_riscv_supervisor_entry(0x80000000, SZ_128M, fdt);
+}
+
 ENTRY_FUNCTION(start_hifive_unmatched, a0, a1, a2)
 {
 	extern char __dtb_z_hifive_unmatched_a00_start[];
 
-	putc_ll('>');
-
-	barebox_riscv_entry(0x80000000, SZ_128M,
-			    __dtb_z_hifive_unmatched_a00_start + get_runtime_offset());
+	start_hifive(__dtb_z_hifive_unmatched_a00_start + get_runtime_offset());
 }
 
 ENTRY_FUNCTION(start_hifive_unleashed, a0, a1, a2)
 {
 	extern char __dtb_z_hifive_unleashed_a00_start[];
 
-	putc_ll('>');
-
-	barebox_riscv_entry(0x80000000, SZ_128M,
-			    __dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
+	start_hifive(__dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
 }
diff --git a/arch/riscv/boot/board-dt-2nd.c b/arch/riscv/boot/board-dt-2nd.c
index e9810f8add97..48cb23ae5e92 100644
--- a/arch/riscv/boot/board-dt-2nd.c
+++ b/arch/riscv/boot/board-dt-2nd.c
@@ -73,5 +73,5 @@ ENTRY_FUNCTION(start_dt_2nd, a0, _fdt, a2)
 	    _fdt < riscv_mem_stack_top(membase, endmem))
 		memsize = ALIGN_DOWN(_fdt - membase, SZ_1M);
 
-	barebox_riscv_entry(membase, memsize, fdt);
+	barebox_riscv_supervisor_entry(membase, memsize, fdt);
 }
diff --git a/arch/riscv/boot/entry.c b/arch/riscv/boot/entry.c
index eb286423d875..e4a5c2208df3 100644
--- a/arch/riscv/boot/entry.c
+++ b/arch/riscv/boot/entry.c
@@ -20,10 +20,11 @@
  */
 
 void __noreturn __naked barebox_riscv_entry(unsigned long membase,
-					    unsigned long memsize, void *boarddata)
+					    unsigned long memsize, void *boarddata,
+					    unsigned flags)
 {
 	unsigned long stack_top = riscv_mem_stack_top(membase, membase + memsize);
 	asm volatile ("move sp, %0" : : "r"(stack_top));
-	barebox_pbl_start(membase, memsize, boarddata);
+	barebox_pbl_start(membase, memsize, boarddata, flags);
 }
 
diff --git a/arch/riscv/boot/entry.h b/arch/riscv/boot/entry.h
index b3a24d2783f7..fb4af5eae558 100644
--- a/arch/riscv/boot/entry.h
+++ b/arch/riscv/boot/entry.h
@@ -6,10 +6,12 @@
 
 void __noreturn barebox_non_pbl_start(unsigned long membase,
 				      unsigned long memsize,
-				      void *boarddata);
+				      void *boarddata,
+				      unsigned flags);
 
 void __noreturn barebox_pbl_start(unsigned long membase,
 				  unsigned long memsize,
-				  void *boarddata);
+				  void *boarddata,
+				  unsigned flags);
 
 #endif
diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c
index 05f6c6231f7e..82bd02d0a0d0 100644
--- a/arch/riscv/boot/start.c
+++ b/arch/riscv/boot/start.c
@@ -26,6 +26,7 @@ static unsigned long riscv_barebox_size;
 static unsigned long riscv_endmem;
 static void *barebox_boarddata;
 static unsigned long barebox_boarddata_size;
+unsigned barebox_riscv_pbl_flags;
 
 void *barebox_riscv_boot_dtb(void)
 {
@@ -107,7 +108,8 @@ device_initcall(barebox_memory_areas_init);
  * the pbl. The stack already has been set up by the pbl.
  */
 __noreturn __no_sanitize_address __section(.text_entry)
-void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata)
+void barebox_non_pbl_start(unsigned long membase, unsigned long memsize,
+			   void *boarddata, unsigned flags)
 {
 	unsigned long endmem = membase + memsize;
 	unsigned long malloc_start, malloc_end;
@@ -168,18 +170,20 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *b
 
 	mem_malloc_init((void *)malloc_start, (void *)malloc_end - 1);
 
+	barebox_riscv_pbl_flags = flags;
+
 	pr_debug("starting barebox...\n");
 
 	start_barebox();
 }
 
-void start(unsigned long membase, unsigned long memsize, void *boarddata);
+void start(unsigned long membase, unsigned long memsize, void *boarddata, unsigned flags);
 /*
  * First function in the uncompressed image. We get here from
  * the pbl. The stack already has been set up by the pbl.
  */
 void __no_sanitize_address __section(.text_entry) start(unsigned long membase,
-		unsigned long memsize, void *boarddata)
+		unsigned long memsize, void *boarddata, unsigned flags)
 {
-	barebox_non_pbl_start(membase, memsize, boarddata);
+	barebox_non_pbl_start(membase, memsize, boarddata, flags);
 }
diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
index b4e010998a4a..35a91e8cb62a 100644
--- a/arch/riscv/boot/uncompress.c
+++ b/arch/riscv/boot/uncompress.c
@@ -23,10 +23,10 @@ unsigned long free_mem_ptr;
 unsigned long free_mem_end_ptr;
 
 void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
-				  void *fdt)
+				  void *fdt, unsigned flags)
 {
 	uint32_t pg_len, uncompressed_len;
-	void __noreturn (*barebox)(unsigned long, unsigned long, void *);
+	void __noreturn (*barebox)(unsigned long, unsigned long, void *, unsigned);
 	unsigned long endmem = membase + memsize;
 	unsigned long barebox_base;
 	void *pg_start, *pg_end;
@@ -67,5 +67,5 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
 
 	pr_debug("jumping to uncompressed image at 0x%p. dtb=0x%p\n", barebox, fdt);
 
-	barebox(membase, memsize, fdt);
+	barebox(membase, memsize, fdt, flags);
 }
diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
index bb1d15308b48..f4081a71f00e 100644
--- a/arch/riscv/include/asm/barebox-riscv.h
+++ b/arch/riscv/include/asm/barebox-riscv.h
@@ -19,14 +19,22 @@
 #include <linux/compiler.h>
 #include <asm/sections.h>
 #include <asm/barebox-riscv-head.h>
+#include <asm/system.h>
 
 unsigned long get_runtime_offset(void);
 
 void setup_c(void);
 void relocate_to_current_adr(void);
 void relocate_to_adr(unsigned long target);
+
 void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long memsize,
-					    void *boarddata);
+					    void *boarddata, unsigned int flags);
+
+#define barebox_riscv_machine_entry(membase, memsize, boarddata) \
+	barebox_riscv_entry(membase, memsize, boarddata, RISCV_M_MODE)
+
+#define barebox_riscv_supervisor_entry(membase, memsize, boarddata) \
+	barebox_riscv_entry(membase, memsize, boarddata, RISCV_S_MODE)
 
 unsigned long riscv_mem_ramoops_get(void);
 unsigned long riscv_mem_endmem_get(void);
diff --git a/arch/riscv/include/asm/system.h b/arch/riscv/include/asm/system.h
new file mode 100644
index 000000000000..3d57a7d191f6
--- /dev/null
+++ b/arch/riscv/include/asm/system.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_SYSTEM_H_
+#define __ASM_SYSTEM_H_
+
+#ifndef __ASSEMBLY__
+
+#define RISCV_MODE_MASK 0x3
+enum riscv_mode {
+    RISCV_U_MODE	= 0,
+    RISCV_S_MODE	= 1,
+    RISCV_HS_MODE	= 2,
+    RISCV_M_MODE	= 3,
+};
+
+static inline enum riscv_mode __riscv_mode(u32 flags)
+{
+	/* allow non-LTO builds to discard code for unused modes */
+	if (!IS_ENABLED(CONFIG_RISCV_MULTI_MODE)) {
+		if (IS_ENABLED(CONFIG_RISCV_M_MODE))
+			return RISCV_M_MODE;
+		if (IS_ENABLED(CONFIG_RISCV_S_MODE))
+			return RISCV_S_MODE;
+	}
+
+	return flags & RISCV_MODE_MASK;
+}
+
+#ifndef __PBL__
+extern unsigned barebox_riscv_pbl_flags;
+
+static inline enum riscv_mode riscv_mode(void)
+{
+	return __riscv_mode(barebox_riscv_pbl_flags);
+}
+
+#endif
+
+#endif
+
+#endif
diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c
index 973c9d9d0f1e..45a04fb821a9 100644
--- a/arch/riscv/lib/sbi.c
+++ b/arch/riscv/lib/sbi.c
@@ -6,6 +6,7 @@
  */
 
 #include <asm/sbi.h>
+#include <asm/system.h>
 #include <linux/export.h>
 #include <errno.h>
 #include <init.h>
@@ -53,6 +54,9 @@ static int sbi_init(void)
 {
 	int ret;
 
+	if (riscv_mode() != RISCV_S_MODE)
+		return 0;
+
 	ret = sbi_get_spec_version();
 	if (ret > 0)
 		sbi_spec_version = ret;
diff --git a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c
index 4eeb9cf7ffc9..412ce3e1e985 100644
--- a/drivers/clocksource/timer-clint.c
+++ b/drivers/clocksource/timer-clint.c
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 #include <io.h>
 #include <asm/timer.h>
+#include <asm/system.h>
 
 #define CLINT_TIMER_VAL_OFF	0xbff8
 
@@ -63,8 +64,8 @@ static int clint_timer_init_dt(struct device_d* dev)
 {
 	struct resource *iores;
 
-	/* one timer is enough */
-	if (clint_timer_val)
+	/* one timer is enough. Only M-Mode */
+	if (clint_timer_val || riscv_mode() != RISCV_M_MODE)
 		return 0;
 
 	iores = dev_request_mem_resource(dev, 0);
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index c2d32b36bbc5..5a517fe6b43d 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -12,6 +12,7 @@
 #include <clock.h>
 #include <asm/timer.h>
 #include <asm/csr.h>
+#include <asm/system.h>
 
 static u64 notrace riscv_timer_get_count_sbi(void)
 {
@@ -45,7 +46,7 @@ static u64 notrace riscv_timer_get_count_rdcycle(void)
 
 static u64 notrace riscv_timer_get_count(void)
 {
-	if (IS_ENABLED(CONFIG_RISCV_SBI))
+	if (riscv_mode() == RISCV_S_MODE)
 		return riscv_timer_get_count_sbi();
 	else
 		return riscv_timer_get_count_rdcycle();
-- 
2.29.2


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


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

* [PATCH v2 04/29] RISC-V: cpuinfo: return some output for non-SBI systems as well
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (2 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 03/29] RISC-V: extend multi-image to support both S- and M-Mode Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 05/29] RISC-V: S-Mode: propagate Hart ID Ahmad Fatoum
                   ` (25 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

If barebox managed to actually execute the cpuinfo command, it probably
means that it's assumption which instructon set is being used and
whether it runs in machine or supervisor mode is correct.

Add that output to cpuinfo, so it shows at least something for non-SBI
configurations.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/include/asm/sbi.h |  8 ++----
 arch/riscv/lib/cpuinfo.c     | 55 +++++++++++++++++++++++++-----------
 commands/Kconfig             |  4 +--
 3 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index ab1fc9a128e5..eb4018de382e 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -9,9 +9,7 @@
 
 #include <linux/types.h>
 
-#ifdef CONFIG_RISCV_SBI
 enum sbi_ext_id {
-#ifdef CONFIG_RISCV_SBI_V01
 	SBI_EXT_0_1_SET_TIMER = 0x0,
 	SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1,
 	SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2,
@@ -21,7 +19,7 @@ enum sbi_ext_id {
 	SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6,
 	SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7,
 	SBI_EXT_0_1_SHUTDOWN = 0x8,
-#endif
+
 	SBI_EXT_BASE = 0x10,
 	SBI_EXT_TIME = 0x54494D45,
 	SBI_EXT_IPI = 0x735049,
@@ -167,7 +165,5 @@ static inline unsigned long sbi_minor_version(void)
 }
 
 int sbi_err_map_linux_errno(int err);
-#else /* CONFIG_RISCV_SBI */
-static inline int sbi_remote_fence_i(const unsigned long *hart_mask) { return -1; }
-#endif /* CONFIG_RISCV_SBI */
+
 #endif /* _ASM_RISCV_SBI_H */
diff --git a/arch/riscv/lib/cpuinfo.c b/arch/riscv/lib/cpuinfo.c
index 21b99a990a1a..16305e6c4d96 100644
--- a/arch/riscv/lib/cpuinfo.c
+++ b/arch/riscv/lib/cpuinfo.c
@@ -2,6 +2,7 @@
 #include <common.h>
 #include <command.h>
 #include <asm/sbi.h>
+#include <asm/system.h>
 
 static const char *implementations[] = {
 	[0] = "\"Berkeley Boot Loader (BBL)\" ",
@@ -12,34 +13,56 @@ static const char *implementations[] = {
 	[5] = "\"Diosix\" ",
 };
 
+static const char *modes[] = {
+	[RISCV_U_MODE] = "U",
+	[RISCV_S_MODE] = "S",
+	[RISCV_HS_MODE] = "HS",
+	[RISCV_M_MODE] = "M",
+};
+
 static int do_cpuinfo(int argc, char *argv[])
 {
 	const char *implementation = "";
+	enum riscv_mode mode;
 	unsigned long impid;
 
-	printf("SBI specification v%lu.%lu detected\n",
-	       sbi_major_version(), sbi_minor_version());
+	mode = riscv_mode() & RISCV_MODE_MASK;
+
+	printf("%s barebox for %s-Mode\n",
+	       IS_ENABLED(CONFIG_ARCH_RV64I) ? "RV64I" : "RV32I",
+	       modes[mode]);
+
+	switch (mode) {
+	case RISCV_S_MODE:
+		if (!IS_ENABLED(CONFIG_RISCV_SBI))
+			break;
+		printf("SBI specification v%lu.%lu detected\n",
+		       sbi_major_version(), sbi_minor_version());
 
-	if (sbi_spec_is_0_1())
-		return 0;
+		if (sbi_spec_is_0_1())
+			return 0;
 
-	impid = __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID);
-	if (impid < ARRAY_SIZE(implementations))
-		implementation = implementations[impid];
+		impid = __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID);
+		if (impid < ARRAY_SIZE(implementations))
+			implementation = implementations[impid];
 
-	printf("SBI implementation ID=0x%lx %sVersion=0x%lx\n",
-	       impid, implementation, __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION));
+		printf("SBI implementation ID=0x%lx %sVersion=0x%lx\n",
+		       impid, implementation, __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION));
 
-	printf("SBI Machine VENDORID=0x%lx ARCHID=0x%lx MIMPID=0x%lx\n",
-	       __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID),
-	       __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID),
-	       __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID));
+		printf("SBI Machine VENDORID=0x%lx ARCHID=0x%lx MIMPID=0x%lx\n",
+		       __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID),
+		       __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID),
+		       __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID));
+		break;
+	default:
+		break;
+	}
 
 	return 0;
 }
 
 BAREBOX_CMD_START(cpuinfo)
 	.cmd            = do_cpuinfo,
-BAREBOX_CMD_DESC("show CPU information")
-BAREBOX_CMD_GROUP(CMD_GRP_INFO)
-	BAREBOX_CMD_END
+	BAREBOX_CMD_DESC("show CPU information")
+	BAREBOX_CMD_GROUP(CMD_GRP_INFO)
+BAREBOX_CMD_END
diff --git a/commands/Kconfig b/commands/Kconfig
index 7bb36d6e417e..22375360885b 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -47,9 +47,9 @@ config CMD_ARM_CPUINFO
 config CMD_RISCV_CPUINFO
 	bool "cpuinfo command"
 	default y
-	depends on RISCV_SBI
+	depends on RISCV
 	help
-	  Show SBI info about RISC-V CPU
+	  Show info about RISC-V CPU
 
 config CMD_DEVINFO
 	tristate
-- 
2.29.2


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


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

* [PATCH v2 05/29] RISC-V: S-Mode: propagate Hart ID
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (3 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 04/29] RISC-V: cpuinfo: return some output for non-SBI systems as well Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 06/29] RISC-V: erizo: make it easier to reuse ns16550 debug_ll Ahmad Fatoum
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Unlike other architectures we support, Linux must apparently be
booted on all cores by the bootloader. To achieve this, the bootloaders
running on the multiple cores synchronize via IPIs.

We will get there eventually, but for now, let's restrict barebox
to boot Linux on a single core. S-Mode firmware is passed hart (core) id
in a0. This is propagated via the thread pointer register, which is
unused by GCC and made available as:

 - cpuinfo output when running in S-Mode
 - $global.hartid
 - a0 when booting via bootm
 - /chosen/boot-hartid fixup: will come in handy when we gain EFI
   loading support
 - single /cpus/*/reg: All other CPU nodes are deleted via fixup

For M-Mode, we can query hart id via CSR. It's unknown whether erizo
supports it and we don't yet have exception support to handle it not
being available, so changes are only done for S-Mode for now.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/boards/hifive/lowlevel.c    |  8 +++----
 arch/riscv/boot/board-dt-2nd.c         |  4 ++--
 arch/riscv/cpu/core.c                  | 33 +++++++++++++++++++++++++-
 arch/riscv/include/asm/barebox-riscv.h |  6 +++--
 arch/riscv/include/asm/system.h        | 20 ++++++++++++++++
 arch/riscv/lib/bootm.c                 |  4 +++-
 arch/riscv/lib/cpuinfo.c               |  1 +
 common/globalvar.c                     | 21 ++++++++++++++++
 common/oftree.c                        | 19 ++++++++++++++-
 include/globalvar.h                    |  8 +++++++
 10 files changed, 113 insertions(+), 11 deletions(-)

diff --git a/arch/riscv/boards/hifive/lowlevel.c b/arch/riscv/boards/hifive/lowlevel.c
index 8a20f3c51d40..5e8969bef1da 100644
--- a/arch/riscv/boards/hifive/lowlevel.c
+++ b/arch/riscv/boards/hifive/lowlevel.c
@@ -4,23 +4,23 @@
 #include <asm/barebox-riscv.h>
 #include <debug_ll.h>
 
-static __always_inline void start_hifive(void *fdt)
+static __always_inline void start_hifive(unsigned long hartid, void *fdt)
 {
 	putc_ll('>');
 
-	barebox_riscv_supervisor_entry(0x80000000, SZ_128M, fdt);
+	barebox_riscv_supervisor_entry(0x80000000, SZ_128M, hartid, fdt);
 }
 
 ENTRY_FUNCTION(start_hifive_unmatched, a0, a1, a2)
 {
 	extern char __dtb_z_hifive_unmatched_a00_start[];
 
-	start_hifive(__dtb_z_hifive_unmatched_a00_start + get_runtime_offset());
+	start_hifive(a0, __dtb_z_hifive_unmatched_a00_start + get_runtime_offset());
 }
 
 ENTRY_FUNCTION(start_hifive_unleashed, a0, a1, a2)
 {
 	extern char __dtb_z_hifive_unleashed_a00_start[];
 
-	start_hifive(__dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
+	start_hifive(a0, __dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
 }
diff --git a/arch/riscv/boot/board-dt-2nd.c b/arch/riscv/boot/board-dt-2nd.c
index 48cb23ae5e92..f31c48a906c2 100644
--- a/arch/riscv/boot/board-dt-2nd.c
+++ b/arch/riscv/boot/board-dt-2nd.c
@@ -40,7 +40,7 @@ static const struct fdt_device_id console_ids[] = {
 	{ /* sentinel */ }
 };
 
-ENTRY_FUNCTION(start_dt_2nd, a0, _fdt, a2)
+ENTRY_FUNCTION(start_dt_2nd, hartid, _fdt, a2)
 {
 	unsigned long membase, memsize, endmem, endfdt, uncompressed_len;
 	struct fdt_header *fdt = (void *)_fdt;
@@ -73,5 +73,5 @@ ENTRY_FUNCTION(start_dt_2nd, a0, _fdt, a2)
 	    _fdt < riscv_mem_stack_top(membase, endmem))
 		memsize = ALIGN_DOWN(_fdt - membase, SZ_1M);
 
-	barebox_riscv_supervisor_entry(membase, memsize, fdt);
+	barebox_riscv_supervisor_entry(membase, memsize, hartid, fdt);
 }
diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c
index 982d378eddec..62eb0ca87164 100644
--- a/arch/riscv/cpu/core.c
+++ b/arch/riscv/cpu/core.c
@@ -19,6 +19,8 @@
 #include <linux/err.h>
 #include <memory.h>
 #include <asm-generic/memory_layout.h>
+#include <globalvar.h>
+#include <magicvar.h>
 #include <io.h>
 
 static int riscv_request_stack(void)
@@ -30,6 +32,31 @@ coredevice_initcall(riscv_request_stack);
 
 static struct device_d timer_dev;
 
+static s64 hartid;
+
+BAREBOX_MAGICVAR(global.hartid, "RISC-V hartid");
+
+static int riscv_fixup_cpus(struct device_node *root, void *context)
+{
+	struct device_node *cpus_node, *np, *tmp;
+
+	cpus_node = of_find_node_by_name(root, "cpus");
+	if (!cpus_node)
+		return 0;
+
+	for_each_child_of_node_safe(cpus_node, tmp, np) {
+		u32 cpu_index;
+
+		if (of_property_read_u32(np, "reg", &cpu_index))
+			continue;
+
+		if (cpu_index != hartid)
+			of_delete_node(np);
+	}
+
+	return 0;
+}
+
 static int riscv_probe(struct device_d *parent)
 {
 	int ret;
@@ -46,7 +73,11 @@ static int riscv_probe(struct device_d *parent)
 			return ret;
 	}
 
-	return 0;
+	hartid = riscv_hartid();
+	if (hartid >= 0)
+		globalvar_add_simple_uint64("hartid", &hartid, "%llu");
+
+	return of_register_fixup(riscv_fixup_cpus, NULL);
 }
 
 static struct of_device_id riscv_dt_ids[] = {
diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
index f4081a71f00e..bbe6cd040642 100644
--- a/arch/riscv/include/asm/barebox-riscv.h
+++ b/arch/riscv/include/asm/barebox-riscv.h
@@ -33,8 +33,10 @@ void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long
 #define barebox_riscv_machine_entry(membase, memsize, boarddata) \
 	barebox_riscv_entry(membase, memsize, boarddata, RISCV_M_MODE)
 
-#define barebox_riscv_supervisor_entry(membase, memsize, boarddata) \
-	barebox_riscv_entry(membase, memsize, boarddata, RISCV_S_MODE)
+#define barebox_riscv_supervisor_entry(membase, memsize, hartid, boarddata) do { \
+	__asm__ volatile("mv tp, %0\n" : : "r"(hartid)); \
+	barebox_riscv_entry(membase, memsize, boarddata, RISCV_S_MODE); \
+} while (0)
 
 unsigned long riscv_mem_ramoops_get(void);
 unsigned long riscv_mem_endmem_get(void);
diff --git a/arch/riscv/include/asm/system.h b/arch/riscv/include/asm/system.h
index 3d57a7d191f6..adf856f9e99b 100644
--- a/arch/riscv/include/asm/system.h
+++ b/arch/riscv/include/asm/system.h
@@ -26,6 +26,22 @@ static inline enum riscv_mode __riscv_mode(u32 flags)
 	return flags & RISCV_MODE_MASK;
 }
 
+static inline long __riscv_hartid(u32 flags)
+{
+	long hartid = -1;
+
+	switch (__riscv_mode(flags)) {
+	case RISCV_S_MODE:
+		__asm__ volatile("mv %0, tp\n" : "=r"(hartid) :);
+		break;
+	default:
+		/* unimplemented */
+		break;
+	}
+
+	return hartid;
+}
+
 #ifndef __PBL__
 extern unsigned barebox_riscv_pbl_flags;
 
@@ -34,6 +50,10 @@ static inline enum riscv_mode riscv_mode(void)
 	return __riscv_mode(barebox_riscv_pbl_flags);
 }
 
+static inline long riscv_hartid(void)
+{
+	return __riscv_hartid(barebox_riscv_pbl_flags);
+}
 #endif
 
 #endif
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index b3e41de4a890..835ff345e347 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -3,11 +3,13 @@
 
 #include <common.h>
 #include <bootm.h>
+#include <asm/system.h>
 
 static int do_bootm_linux(struct image_data *data)
 {
 	void (*fn)(unsigned long a0, unsigned long dtb, unsigned long a2);
 	phys_addr_t devicetree;
+	long hartid = riscv_hartid();
 
 	fn = booti_load_image(data, &devicetree);
 	if (IS_ERR(fn))
@@ -15,7 +17,7 @@ static int do_bootm_linux(struct image_data *data)
 
 	shutdown_barebox();
 
-	fn(0, devicetree, 0);
+	fn(hartid >= 0 ? hartid : 0, devicetree, 0);
 
 	return -EINVAL;
 }
diff --git a/arch/riscv/lib/cpuinfo.c b/arch/riscv/lib/cpuinfo.c
index 16305e6c4d96..2d9cee2a6270 100644
--- a/arch/riscv/lib/cpuinfo.c
+++ b/arch/riscv/lib/cpuinfo.c
@@ -34,6 +34,7 @@ static int do_cpuinfo(int argc, char *argv[])
 
 	switch (mode) {
 	case RISCV_S_MODE:
+		printf("Hart ID=%lu\n", riscv_hartid());
 		if (!IS_ENABLED(CONFIG_RISCV_SBI))
 			break;
 		printf("SBI specification v%lu.%lu detected\n",
diff --git a/common/globalvar.c b/common/globalvar.c
index 8bb5015ce4e8..9e5a99f79353 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -565,6 +565,27 @@ int globalvar_add_simple_int(const char *name, int *value,
 	return 0;
 }
 
+int globalvar_add_simple_uint64(const char *name, u64 *value,
+				const char *format)
+{
+	struct param_d *p;
+	int ret;
+
+	ret = globalvar_remove_unqualified(name);
+	if (ret)
+		return ret;
+
+	p = dev_add_param_uint64(&global_device, name, NULL, NULL,
+		value, format, NULL);
+
+	if (IS_ERR(p))
+		return PTR_ERR(p);
+
+	globalvar_nv_sync(name);
+
+	return 0;
+}
+
 int globalvar_add_bool(const char *name,
 		       int (*set)(struct param_d *, void *),
 		       int *value, void *priv)
diff --git a/common/oftree.c b/common/oftree.c
index 5eaa63ad7ebc..1fcc5277c58d 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -232,7 +232,24 @@ static int of_fixup_bootargs(struct device_node *root, void *unused)
 			return err;
 	}
 
-	return of_fixup_bootargs_bootsource(root, node);
+	err = of_fixup_bootargs_bootsource(root, node);
+	if (err)
+		return err;
+
+	if (IS_ENABLED(CONFIG_RISCV)) {
+		const char *hartid;
+
+		hartid = getenv("global.hartid");
+		if (hartid) {
+			unsigned long id;
+
+			err = kstrtoul(hartid, 10, &id);
+			if (!err)
+				err = of_property_write_u32(node, "boot-hartid", id);
+		}
+	}
+
+	return err;
 }
 
 static int of_register_bootargs_fixup(void)
diff --git a/include/globalvar.h b/include/globalvar.h
index 84bee9102cf3..476bb920f3e1 100644
--- a/include/globalvar.h
+++ b/include/globalvar.h
@@ -20,6 +20,8 @@ void globalvar_set(const char *name, const char *val);
 int globalvar_add_simple_string(const char *name, char **value);
 int globalvar_add_simple_int(const char *name, int *value,
 			     const char *format);
+int globalvar_add_simple_uint64(const char *name, u64 *value,
+				const char *format);
 int globalvar_add_bool(const char *name,
 		       int (*set)(struct param_d *, void *),
 		       int *value, void *priv);
@@ -55,6 +57,12 @@ static inline int globalvar_add_simple_int(const char *name,
 	return 0;
 }
 
+static inline int globalvar_add_simple_uint64(const char *name,
+		u64 *value, const char *format)
+{
+	return 0;
+}
+
 static inline int globalvar_add_bool(const char *name,
 		int (*set)(struct param_d *, void *),
 		int *value, void *priv)
-- 
2.29.2


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


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

* [PATCH v2 06/29] RISC-V: erizo: make it easier to reuse ns16550 debug_ll
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (4 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 05/29] RISC-V: S-Mode: propagate Hart ID Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 07/29] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Incoming StarFive support also uses ns16550 compatibles as UART IP.
Make reuse easier by making the two most likely parameters to change
SoC-specific (base address and baud clock frequency) and move the rest
behind the new CONFIG_DEBUG_LL_NS16550.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/include/asm/debug_ll.h | 7 +++++--
 common/Kconfig                    | 6 ++++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/debug_ll.h b/arch/riscv/include/asm/debug_ll.h
index 6904460af98f..13609d25c559 100644
--- a/arch/riscv/include/asm/debug_ll.h
+++ b/arch/riscv/include/asm/debug_ll.h
@@ -12,13 +12,16 @@
 
 #include <linux/kconfig.h>
 
-#ifdef CONFIG_DEBUG_ERIZO
+#ifdef CONFIG_DEBUG_LL_NS16550
 
+#if defined CONFIG_DEBUG_ERIZO
 #define DEBUG_LL_UART_ADDR	0x90000000
+#define DEBUG_LL_UART_CLK       (24000000 / 16)
+#endif
+
 #define DEBUG_LL_UART_SHIFT	2
 #define DEBUG_LL_UART_IOSIZE32
 
-#define DEBUG_LL_UART_CLK       (24000000 / 16)
 #define DEBUG_LL_UART_BPS       CONFIG_BAUDRATE
 #define DEBUG_LL_UART_DIVISOR   (DEBUG_LL_UART_CLK / DEBUG_LL_UART_BPS)
 
diff --git a/common/Kconfig b/common/Kconfig
index 8b8f80bbb3ba..98be9b58abce 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1376,6 +1376,7 @@ config DEBUG_RPI3_MINI_UART
 config DEBUG_ERIZO
 	bool "Erizo ns16550 port"
 	depends on SOC_ERIZO
+	select DEBUG_LL_NS16550
 
 config DEBUG_SIFIVE
 	bool "SiFive serial0 port"
@@ -1383,6 +1384,11 @@ config DEBUG_SIFIVE
 
 endchoice
 
+config DEBUG_LL_NS16550
+	bool
+	help
+	  Selected by RISC-V platforms that use ns16550 for debug_ll
+
 config DEBUG_IMX_UART_PORT
 	int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \
 						DEBUG_IMX21_UART || \
-- 
2.29.2


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


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

* [PATCH v2 07/29] RISC-V: socs: add Kconfig entry for StarFive JH7100
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (5 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 06/29] RISC-V: erizo: make it easier to reuse ns16550 debug_ll Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 08/29] nvmem: add StarFive OTP support Ahmad Fatoum
                   ` (22 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The JH7100 is the StarFive SoC with SiFive CPUs in the pre-production
BeagleV. Th JH7110 in later boards will be cache-coherent, but the
JH7100 will need some workarounds.

Add Kconfig symbols, so newly introduced symbols can depend on them.

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

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index f1b431555fcd..8f955cd4d220 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -21,8 +21,12 @@ config SOC_VIRT
 	  Generates an image tht can be be booted by QEMU. The image is called
 	  barebox-dt-2nd.img
 
+config CPU_SIFIVE
+	bool
+
 config SOC_SIFIVE
 	bool "SiFive SoCs"
+	select CPU_SIFIVE
 	select RISCV_S_MODE
 	select CLK_SIFIVE
 	select CLK_SIFIVE_PRCI
@@ -41,4 +45,22 @@ config BOARD_HIFIVE
 
 endif
 
+config SOC_STARFIVE
+	bool "StarFive SoCs"
+	help
+	  This enables support for SiFive SoC platform hardware.
+
+if SOC_STARFIVE
+
+config SOC_STARFIVE_JH71XX
+	bool
+	select CPU_SIFIVE
+
+config SOC_STARFIVE_JH7100
+	bool
+	select SOC_STARFIVE_JH71XX
+
+endif
+
+
 endmenu
-- 
2.29.2


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


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

* [PATCH v2 08/29] nvmem: add StarFive OTP support
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (6 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 07/29] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 09/29] RISC-V: dma: support multiple dma_alloc_coherent backends Ahmad Fatoum
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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 | 201 +++++++++++++++++++++++++++++++++++
 3 files changed, 211 insertions(+)
 create mode 100644 drivers/nvmem/starfive-otp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 0d7c0b7b9e3d..3781f7a839fc 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -65,4 +65,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 53c02dc7850c..55507f544126 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -22,3 +22,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..f9bf05ca87ec
--- /dev/null
+++ b/drivers/nvmem/starfive-otp.c
@@ -0,0 +1,201 @@
+// 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/clk.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_probe(struct device_d *dev)
+{
+	struct starfive_otp *priv;
+	struct regmap_config config = {};
+	struct resource *iores;
+	struct regmap *map;
+	struct clk *clk;
+	u32 total_fuses;
+	int ret;
+
+	clk = clk_get(dev, NULL);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	clk_enable(clk);
+
+	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);
+
+	return PTR_ERR_OR_ZERO(nvmem_regmap_register(map, "starfive-otp"));
+}
+
+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] 33+ messages in thread

* [PATCH v2 09/29] RISC-V: dma: support multiple dma_alloc_coherent backends
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (7 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 08/29] nvmem: add StarFive OTP support Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 10/29] RISC-V: add exception support Ahmad Fatoum
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

StarFive JH7100 is incoherent between CPU and dma masters like GMAC.
It has an uncached alias though similar to what we have on MIPS.

StarFive JH7110 will fix this and be cache coherent like other SiFive
SoCs. Support both by allowing driver to define their own
dma_alloc_coherent implementations.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/cpu/Makefile      |  1 +
 arch/riscv/cpu/dma.c         | 74 ++++++++++++++++++++++++++++++++++++
 arch/riscv/include/asm/dma.h | 48 +++++++----------------
 3 files changed, 88 insertions(+), 35 deletions(-)
 create mode 100644 arch/riscv/cpu/dma.c

diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile
index f1312be699a1..9ce77ad869cd 100644
--- a/arch/riscv/cpu/Makefile
+++ b/arch/riscv/cpu/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-y += core.o time.o
+obj-$(CONFIG_HAS_DMA) += dma.o
diff --git a/arch/riscv/cpu/dma.c b/arch/riscv/cpu/dma.c
new file mode 100644
index 000000000000..5a4d714e5e71
--- /dev/null
+++ b/arch/riscv/cpu/dma.c
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <common.h>
+#include <xfuncs.h>
+#include <asm/dma.h>
+#include <malloc.h>
+
+static void __dma_flush_range(dma_addr_t start, dma_addr_t end)
+{
+}
+
+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_ops coherent_dma_ops = {
+	.alloc_coherent = __dma_alloc_coherent,
+	.free_coherent = __dma_free_coherent,
+	.flush_range = __dma_flush_range,
+	.inv_range = __dma_flush_range,
+};
+
+static const struct dma_ops *dma_ops = &coherent_dma_ops;
+
+void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+	return dma_ops->alloc_coherent(size, dma_handle);
+}
+
+void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
+{
+	dma_ops->free_coherent(vaddr, dma_handle, size);
+}
+
+void dma_set_ops(const struct dma_ops *ops)
+{
+	dma_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_ops->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_ops->inv_range(address, address + size);
+        else
+                dma_ops->flush_range(address, address + size);
+}
diff --git a/arch/riscv/include/asm/dma.h b/arch/riscv/include/asm/dma.h
index 4204653984a3..56bcf06cc4af 100644
--- a/arch/riscv/include/asm/dma.h
+++ b/arch/riscv/include/asm/dma.h
@@ -1,44 +1,22 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_DMA_MAPPING_H
-#define _ASM_DMA_MAPPING_H
+#ifndef _RISCV_ASM_DMA_H
+#define _RISCV_ASM_DMA_H
 
-#include <common.h>
-#include <xfuncs.h>
-#include <linux/build_bug.h>
-#include <malloc.h>
+#include <linux/types.h>
 
-#ifdef CONFIG_MMU
-#error DMA stubs need be replaced when using MMU and caches
-#endif
+struct dma_ops {
+	void *(*alloc_coherent)(size_t size, dma_addr_t *dma_handle);
+	void (*free_coherent)(void *vaddr, dma_addr_t dma_handle, size_t size);
 
-static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
-{
-	void *ret;
+	void (*flush_range)(dma_addr_t start, dma_addr_t end);
+	void (*inv_range)(dma_addr_t start, dma_addr_t end);
+};
 
-	ret = xmemalign(PAGE_SIZE, size);
+/* Override for SoCs with cache-incoherent DMA masters */
+void dma_set_ops(const struct dma_ops *ops);
 
-	memset(ret, 0, size);
+#define DMA_ALIGNMENT 64
 
-	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] 33+ messages in thread

* [PATCH v2 10/29] RISC-V: add exception support
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (8 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 09/29] RISC-V: dma: support multiple dma_alloc_coherent backends Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 11/29] RISC-V: support incoherent I-Cache Ahmad Fatoum
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Add S- and M-Mode support for dumping registers when catching unexpected
CPU exceptions. Load access faults when data_abort_mask is active will
be skipped over. This allows outputting xxx when doing md /dev/mem for
non-accessible space.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 arch/riscv/Kconfig                   |   5 +
 arch/riscv/boot/start.c              |   3 +
 arch/riscv/boot/uncompress.c         |   3 +
 arch/riscv/cpu/Makefile              |   3 +
 arch/riscv/cpu/interrupts.c          | 130 ++++++++++++++++++++++++
 arch/riscv/cpu/mtrap.S               |  30 ++++++
 arch/riscv/cpu/strap.S               |  30 ++++++
 arch/riscv/include/asm/asm-offsets.h |   1 +
 arch/riscv/include/asm/irq.h         | 107 ++++++++++++++++++++
 arch/riscv/include/asm/ptrace.h      | 143 +++++++++++++++++++++++++++
 arch/riscv/include/asm/unwind.h      |   9 ++
 arch/riscv/lib/asm-offsets.c         |  46 +++++++++
 12 files changed, 510 insertions(+)
 create mode 100644 arch/riscv/cpu/interrupts.c
 create mode 100644 arch/riscv/cpu/mtrap.S
 create mode 100644 arch/riscv/cpu/strap.S
 create mode 100644 arch/riscv/include/asm/asm-offsets.h
 create mode 100644 arch/riscv/include/asm/irq.h
 create mode 100644 arch/riscv/include/asm/ptrace.h
 create mode 100644 arch/riscv/include/asm/unwind.h

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index bbafdea1b959..a814a1a45b1c 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -77,6 +77,11 @@ config RISCV_OPTIMZED_STRING_FUNCTIONS
 	  These functions work faster than the normal versions but increase
 	  your binary size.
 
+config RISCV_EXCEPTIONS
+	bool "enable exception handling support"
+	default y
+	select ARCH_HAS_DATA_ABORT_MASK
+
 config HAS_NMON
 	bool
 
diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c
index 82bd02d0a0d0..72ab93cb7691 100644
--- a/arch/riscv/boot/start.c
+++ b/arch/riscv/boot/start.c
@@ -16,6 +16,7 @@
 #include <uncompress.h>
 #include <malloc.h>
 #include <compressed-dtb.h>
+#include <asm/irq.h>
 
 #include <debug_ll.h>
 
@@ -122,6 +123,8 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize,
 
 	barrier();
 
+	irq_init_vector(__riscv_mode(flags));
+
 	pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
 
 	riscv_endmem = endmem;
diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
index 35a91e8cb62a..c6c20b38e390 100644
--- a/arch/riscv/boot/uncompress.c
+++ b/arch/riscv/boot/uncompress.c
@@ -14,6 +14,7 @@
 #include <asm-generic/memory_layout.h>
 #include <asm/sections.h>
 #include <asm/unaligned.h>
+#include <asm/irq.h>
 
 #include <debug_ll.h>
 
@@ -32,6 +33,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
 	void *pg_start, *pg_end;
 	unsigned long pc = get_pc();
 
+	irq_init_vector(__riscv_mode(flags));
+
 	/* piggy data is not relocated, so determine the bounds now */
 	pg_start = input_data + get_runtime_offset();
 	pg_end = input_data_end + get_runtime_offset();
diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile
index 9ce77ad869cd..717baaaaa727 100644
--- a/arch/riscv/cpu/Makefile
+++ b/arch/riscv/cpu/Makefile
@@ -2,3 +2,6 @@
 
 obj-y += core.o time.o
 obj-$(CONFIG_HAS_DMA) += dma.o
+obj-pbl-$(CONFIG_RISCV_M_MODE) += mtrap.o
+obj-pbl-$(CONFIG_RISCV_S_MODE) += strap.o
+obj-pbl-y += interrupts.o
diff --git a/arch/riscv/cpu/interrupts.c b/arch/riscv/cpu/interrupts.c
new file mode 100644
index 000000000000..df6d3e6e010b
--- /dev/null
+++ b/arch/riscv/cpu/interrupts.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2016-17 Microsemi Corporation.
+ * Padmarao Begari, Microsemi Corporation <padmarao.begari@microsemi.com>
+ *
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ *
+ * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/irq.h>
+#include <asm/csr.h>
+#include <abort.h>
+#include <pbl.h>
+
+#define MCAUSE32_INT	0x80000000
+#define MCAUSE64_INT	0x8000000000000000
+
+#ifdef CONFIG_64BIT
+# define MCAUSE_INT MCAUSE64_INT
+#else
+# define MCAUSE_INT MCAUSE32_INT
+#endif
+
+static void show_regs(const struct pt_regs *regs)
+{
+	printf("\nsp:  " REG_FMT " gp:  " REG_FMT " tp:  " REG_FMT "\n",
+	       regs->sp, regs->gp, regs->tp);
+	printf("t0:  " REG_FMT " t1:  " REG_FMT " t2:  " REG_FMT "\n",
+	       regs->t0, regs->t1, regs->t2);
+	printf("s0:  " REG_FMT " s1:  " REG_FMT " a0:  " REG_FMT "\n",
+	       regs->s0, regs->s1, regs->a0);
+	printf("a1:  " REG_FMT " a2:  " REG_FMT " a3:  " REG_FMT "\n",
+	       regs->a1, regs->a2, regs->a3);
+	printf("a4:  " REG_FMT " a5:  " REG_FMT " a6:  " REG_FMT "\n",
+	       regs->a4, regs->a5, regs->a6);
+	printf("a7:  " REG_FMT " s2:  " REG_FMT " s3:  " REG_FMT "\n",
+	       regs->a7, regs->s2, regs->s3);
+	printf("s4:  " REG_FMT " s5:  " REG_FMT " s6:  " REG_FMT "\n",
+	       regs->s4, regs->s5, regs->s6);
+	printf("s7:  " REG_FMT " s8:  " REG_FMT " s9:  " REG_FMT "\n",
+	       regs->s7, regs->s8, regs->s9);
+	printf("s10: " REG_FMT " s11: " REG_FMT " t3:  " REG_FMT "\n",
+	       regs->s10, regs->s11, regs->t3);
+	printf("t4:  " REG_FMT " t5:  " REG_FMT " t6:  " REG_FMT "\n",
+	       regs->t4, regs->t5, regs->t6);
+}
+
+static void report_trap(const struct pt_regs *regs)
+{
+	static const char * const exception_code[] = {
+		[0]  = "Instruction address misaligned",
+		[1]  = "Instruction access fault",
+		[2]  = "Illegal instruction",
+		[3]  = "Breakpoint",
+		[4]  = "Load address misaligned",
+		[5]  = "Load access fault",
+		[6]  = "Store/AMO address misaligned",
+		[7]  = "Store/AMO access fault",
+		[8]  = "Environment call from U-mode",
+		[9]  = "Environment call from S-mode",
+		[10] = "Reserved",
+		[11] = "Environment call from M-mode",
+		[12] = "Instruction page fault",
+		[13] = "Load page fault",
+		[14] = "Reserved",
+		[15] = "Store/AMO page fault",
+
+	};
+
+	printf("Unhandled exception: %ld", regs->cause);
+
+	if (regs->cause < ARRAY_SIZE(exception_code))
+		printf(" \"%s\"\n", exception_code[regs->cause]);
+
+	printf("E [<" REG_FMT ">] ra: [<" REG_FMT ">] tval: " REG_FMT "\n",
+	       regs->epc, regs->ra, regs->badaddr);
+
+	show_regs(regs);
+}
+
+
+
+#ifdef __PBL__
+
+static inline bool skip_data_abort(struct pt_regs *regs)
+{
+	return false;
+}
+
+#else
+
+static volatile bool riscv_data_abort_occurred;
+static volatile bool riscv_ignore_data_abort;
+
+void data_abort_mask(void)
+{
+	riscv_data_abort_occurred = false;
+	riscv_ignore_data_abort = true;
+}
+
+int data_abort_unmask(void)
+{
+	riscv_ignore_data_abort = false;
+	return riscv_data_abort_occurred;
+}
+
+static inline bool skip_data_abort(struct pt_regs *regs)
+{
+	return regs->cause == EXC_LOAD_ACCESS && riscv_ignore_data_abort;
+}
+
+#endif
+
+unsigned long handle_trap(struct pt_regs *regs)
+{
+	if (skip_data_abort(regs))
+		goto skip;
+
+	report_trap(regs);
+	hang();
+
+skip:
+	return regs->epc + 4;
+}
+
diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S
new file mode 100644
index 000000000000..e4aba7d69415
--- /dev/null
+++ b/arch/riscv/cpu/mtrap.S
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 FORTH-ICS/CARV
+ *  Nick Kossifidis <mick@ics.forth.gr>
+ */
+
+#include <asm/asm.h>
+#include <asm/irq.h>
+#include <linux/linkage.h>
+
+.section .text.mtrap_entry
+ENTRY(mtrap_entry)
+	addi sp, sp, -PT_SIZE_ON_STACK
+        pt_regs_push sp
+	csrr t1, mstatus
+	csrr t2, mepc
+	csrr t3, mtval
+	csrr t4, mcause
+
+	REG_S t1, PT_STATUS(sp)
+	REG_S t2, PT_EPC(sp)
+	REG_S t3, PT_BADADDR(sp)
+	REG_S t4, PT_CAUSE(sp)
+	mv a0, sp
+	jal handle_trap
+	csrw mepc, a0
+        pt_regs_pop sp
+	addi sp, sp, PT_SIZE_ON_STACK
+	mret
+ENDPROC(mtrap_entry)
diff --git a/arch/riscv/cpu/strap.S b/arch/riscv/cpu/strap.S
new file mode 100644
index 000000000000..c1d684c19425
--- /dev/null
+++ b/arch/riscv/cpu/strap.S
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 FORTH-ICS/CARV
+ *  Nick Kossifidis <mick@ics.forth.gr>
+ */
+
+#include <asm/asm.h>
+#include <asm/irq.h>
+#include <linux/linkage.h>
+
+.section .text.strap_entry
+ENTRY(strap_entry)
+	addi sp, sp, -PT_SIZE_ON_STACK
+        pt_regs_push sp
+	csrr t1, sstatus
+	csrr t2, sepc
+	csrr t3, stval
+	csrr t4, scause
+
+	REG_S t1, PT_STATUS(sp)
+	REG_S t2, PT_EPC(sp)
+	REG_S t3, PT_BADADDR(sp)
+	REG_S t4, PT_CAUSE(sp)
+	mv a0, sp
+	jal handle_trap
+	csrw sepc, a0
+        pt_regs_pop sp
+	addi sp, sp, PT_SIZE_ON_STACK
+	sret
+ENDPROC(strap_entry)
diff --git a/arch/riscv/include/asm/asm-offsets.h b/arch/riscv/include/asm/asm-offsets.h
new file mode 100644
index 000000000000..d370ee36a182
--- /dev/null
+++ b/arch/riscv/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/riscv/include/asm/irq.h b/arch/riscv/include/asm/irq.h
new file mode 100644
index 000000000000..fde7589baa80
--- /dev/null
+++ b/arch/riscv/include/asm/irq.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef RISCV_ASM_IRQ_H__
+#define RISCV_ASM_IRQ_H__
+
+#include <asm/csr.h>
+#include <asm/system.h>
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
+
+#ifndef __ASSEMBLY__
+#include <asm/barebox-riscv.h>
+void strap_entry(void);
+void mtrap_entry(void);
+unsigned long handle_trap(struct pt_regs *regs);
+
+static inline void irq_init_vector(enum riscv_mode mode)
+{
+	switch (mode) {
+#ifdef CONFIG_RISCV_EXCEPTIONS
+	case RISCV_S_MODE:
+		asm volatile ("csrw stvec, %0; csrw sie, zero" : :
+			      "r"(strap_entry + get_runtime_offset()));
+		break;
+	case RISCV_M_MODE:
+		asm volatile ("csrw mtvec, %0; csrw mie, zero" : :
+			      "r"(mtrap_entry + get_runtime_offset()));
+		break;
+#endif
+	default:
+		break;
+	}
+}
+
+#else
+
+.macro	pt_regs_push ptr
+	REG_S ra,  PT_RA(\ptr)	/* x1 */
+	REG_S sp,  PT_SP(\ptr)	/* x2 */
+	REG_S gp,  PT_GP(\ptr)	/* x3 */
+	REG_S tp,  PT_TP(\ptr)	/* x4 */
+	REG_S t0,  PT_T0(\ptr)	/* x5 */
+	REG_S t1,  PT_T1(\ptr)	/* x6 */
+	REG_S t2,  PT_T2(\ptr)	/* x7 */
+	REG_S s0,  PT_S0(\ptr)	/* x8/fp */
+	REG_S s1,  PT_S1(\ptr)	/* x9 */
+	REG_S a0,  PT_A0(\ptr)	/* x10 */
+	REG_S a1,  PT_A1(\ptr)	/* x11 */
+	REG_S a2,  PT_A2(\ptr)	/* x12 */
+	REG_S a3,  PT_A3(\ptr)	/* x13 */
+	REG_S a4,  PT_A4(\ptr)	/* x14 */
+	REG_S a5,  PT_A5(\ptr)	/* x15 */
+	REG_S a6,  PT_A6(\ptr)	/* x16 */
+	REG_S a7,  PT_A7(\ptr)	/* x17 */
+	REG_S s2,  PT_S2(\ptr)	/* x18 */
+	REG_S s3,  PT_S3(\ptr)	/* x19 */
+	REG_S s4,  PT_S4(\ptr)	/* x20 */
+	REG_S s5,  PT_S5(\ptr)	/* x21 */
+	REG_S s6,  PT_S6(\ptr)	/* x22 */
+	REG_S s7,  PT_S7(\ptr)	/* x23 */
+	REG_S s8,  PT_S8(\ptr)	/* x24 */
+	REG_S s9,  PT_S9(\ptr)	/* x25 */
+	REG_S s10, PT_S10(\ptr)	/* x26 */
+	REG_S s11, PT_S11(\ptr)	/* x27 */
+	REG_S t3,  PT_T3(\ptr)	/* x28 */
+	REG_S t4,  PT_T4(\ptr)	/* x29 */
+	REG_S t5,  PT_T5(\ptr)	/* x30 */
+	REG_S t6,  PT_T6(\ptr)	/* x31 */
+.endm
+
+.macro	pt_regs_pop ptr
+	REG_L ra,  PT_RA(\ptr)	/* x1 */
+	REG_L sp,  PT_SP(\ptr)	/* x2 */
+	REG_L gp,  PT_GP(\ptr)	/* x3 */
+	REG_L tp,  PT_TP(\ptr)	/* x4 */
+	REG_L t0,  PT_T0(\ptr)	/* x5 */
+	REG_L t1,  PT_T1(\ptr)	/* x6 */
+	REG_L t2,  PT_T2(\ptr)	/* x7 */
+	REG_L s0,  PT_S0(\ptr)	/* x8/fp */
+	REG_L s1,  PT_S1(\ptr)	/* x9 */
+	REG_L a0,  PT_A0(\ptr)	/* x10 */
+	REG_L a1,  PT_A1(\ptr)	/* x11 */
+	REG_L a2,  PT_A2(\ptr)	/* x12 */
+	REG_L a3,  PT_A3(\ptr)	/* x13 */
+	REG_L a4,  PT_A4(\ptr)	/* x14 */
+	REG_L a5,  PT_A5(\ptr)	/* x15 */
+	REG_L a6,  PT_A6(\ptr)	/* x16 */
+	REG_L a7,  PT_A7(\ptr)	/* x17 */
+	REG_L s2,  PT_S2(\ptr)	/* x18 */
+	REG_L s3,  PT_S3(\ptr)	/* x19 */
+	REG_L s4,  PT_S4(\ptr)	/* x20 */
+	REG_L s5,  PT_S5(\ptr)	/* x21 */
+	REG_L s6,  PT_S6(\ptr)	/* x22 */
+	REG_L s7,  PT_S7(\ptr)	/* x23 */
+	REG_L s8,  PT_S8(\ptr)	/* x24 */
+	REG_L s9,  PT_S9(\ptr)	/* x25 */
+	REG_L s10, PT_S10(\ptr)	/* x26 */
+	REG_L s11, PT_S11(\ptr)	/* x27 */
+	REG_L t3,  PT_T3(\ptr)	/* x28 */
+	REG_L t4,  PT_T4(\ptr)	/* x29 */
+	REG_L t5,  PT_T5(\ptr)	/* x30 */
+	REG_L t6,  PT_T6(\ptr)	/* x31 */
+.endm
+
+#endif
+
+#endif
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
new file mode 100644
index 000000000000..b5e792f6669b
--- /dev/null
+++ b/arch/riscv/include/asm/ptrace.h
@@ -0,0 +1,143 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2012 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_PTRACE_H
+#define _ASM_RISCV_PTRACE_H
+
+#include <asm/csr.h>
+#include <linux/compiler.h>
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+	unsigned long epc;
+	unsigned long ra;
+	unsigned long sp;
+	unsigned long gp;
+	unsigned long tp;
+	unsigned long t0;
+	unsigned long t1;
+	unsigned long t2;
+	unsigned long s0;
+	unsigned long s1;
+	unsigned long a0;
+	unsigned long a1;
+	unsigned long a2;
+	unsigned long a3;
+	unsigned long a4;
+	unsigned long a5;
+	unsigned long a6;
+	unsigned long a7;
+	unsigned long s2;
+	unsigned long s3;
+	unsigned long s4;
+	unsigned long s5;
+	unsigned long s6;
+	unsigned long s7;
+	unsigned long s8;
+	unsigned long s9;
+	unsigned long s10;
+	unsigned long s11;
+	unsigned long t3;
+	unsigned long t4;
+	unsigned long t5;
+	unsigned long t6;
+	/* Supervisor/Machine CSRs */
+	unsigned long status;
+	unsigned long badaddr;
+	unsigned long cause;
+};
+
+#ifdef CONFIG_64BIT
+#define REG_FMT "%016lx"
+#else
+#define REG_FMT "%08lx"
+#endif
+
+#define user_mode(regs) (((regs)->status & SR_PP) == 0)
+
+#define MAX_REG_OFFSET offsetof(struct pt_regs, cause)
+
+/* Helpers for working with the instruction pointer */
+static inline unsigned long instruction_pointer(struct pt_regs *regs)
+{
+	return regs->epc;
+}
+static inline void instruction_pointer_set(struct pt_regs *regs,
+					   unsigned long val)
+{
+	regs->epc = val;
+}
+
+#define profile_pc(regs) instruction_pointer(regs)
+
+/* Helpers for working with the user stack pointer */
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
+{
+	return regs->sp;
+}
+static inline void user_stack_pointer_set(struct pt_regs *regs,
+					  unsigned long val)
+{
+	regs->sp =  val;
+}
+
+/* Valid only for Kernel mode traps. */
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+	return regs->sp;
+}
+
+/* Helpers for working with the frame pointer */
+static inline unsigned long frame_pointer(struct pt_regs *regs)
+{
+	return regs->s0;
+}
+static inline void frame_pointer_set(struct pt_regs *regs,
+				     unsigned long val)
+{
+	regs->s0 = val;
+}
+
+static inline unsigned long regs_return_value(struct pt_regs *regs)
+{
+	return regs->a0;
+}
+
+static inline void regs_set_return_value(struct pt_regs *regs,
+					 unsigned long val)
+{
+	regs->a0 = val;
+}
+
+extern int regs_query_register_offset(const char *name);
+extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+					       unsigned int n);
+
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+			   unsigned long frame_pointer);
+int do_syscall_trace_enter(struct pt_regs *regs);
+void do_syscall_trace_exit(struct pt_regs *regs);
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs:	pt_regs from which register value is gotten
+ * @offset:	offset of the register.
+ *
+ * regs_get_register returns the value of a register whose offset from @regs.
+ * The @offset is the offset of the register in struct pt_regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+					      unsigned int offset)
+{
+	if (unlikely(offset > MAX_REG_OFFSET))
+		return 0;
+
+	return *(unsigned long *)((unsigned long)regs + offset);
+}
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_PTRACE_H */
diff --git a/arch/riscv/include/asm/unwind.h b/arch/riscv/include/asm/unwind.h
new file mode 100644
index 000000000000..9e5c8b542094
--- /dev/null
+++ b/arch/riscv/include/asm/unwind.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef RISCV_ASM_UNWIND_H__
+#define RISCV_ASM_UNWIND_H__
+
+struct pt_regs;
+
+void unwind_backtrace(struct pt_regs *regs);
+
+#endif
diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c
index 22f382b71e7b..4b869690f198 100644
--- a/arch/riscv/lib/asm-offsets.c
+++ b/arch/riscv/lib/asm-offsets.c
@@ -5,8 +5,54 @@
  */
 
 #include <linux/kbuild.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+
+#define STACK_ALIGN		16
 
 int main(void)
 {
+	DEFINE(PT_SIZE, sizeof(struct pt_regs));
+	OFFSET(PT_EPC, pt_regs, epc);
+	OFFSET(PT_RA, pt_regs, ra);
+	OFFSET(PT_FP, pt_regs, s0);
+	OFFSET(PT_S0, pt_regs, s0);
+	OFFSET(PT_S1, pt_regs, s1);
+	OFFSET(PT_S2, pt_regs, s2);
+	OFFSET(PT_S3, pt_regs, s3);
+	OFFSET(PT_S4, pt_regs, s4);
+	OFFSET(PT_S5, pt_regs, s5);
+	OFFSET(PT_S6, pt_regs, s6);
+	OFFSET(PT_S7, pt_regs, s7);
+	OFFSET(PT_S8, pt_regs, s8);
+	OFFSET(PT_S9, pt_regs, s9);
+	OFFSET(PT_S10, pt_regs, s10);
+	OFFSET(PT_S11, pt_regs, s11);
+	OFFSET(PT_SP, pt_regs, sp);
+	OFFSET(PT_TP, pt_regs, tp);
+	OFFSET(PT_A0, pt_regs, a0);
+	OFFSET(PT_A1, pt_regs, a1);
+	OFFSET(PT_A2, pt_regs, a2);
+	OFFSET(PT_A3, pt_regs, a3);
+	OFFSET(PT_A4, pt_regs, a4);
+	OFFSET(PT_A5, pt_regs, a5);
+	OFFSET(PT_A6, pt_regs, a6);
+	OFFSET(PT_A7, pt_regs, a7);
+	OFFSET(PT_T0, pt_regs, t0);
+	OFFSET(PT_T1, pt_regs, t1);
+	OFFSET(PT_T2, pt_regs, t2);
+	OFFSET(PT_T3, pt_regs, t3);
+	OFFSET(PT_T4, pt_regs, t4);
+	OFFSET(PT_T5, pt_regs, t5);
+	OFFSET(PT_T6, pt_regs, t6);
+	OFFSET(PT_GP, pt_regs, gp);
+	OFFSET(PT_STATUS, pt_regs, status);
+	OFFSET(PT_BADADDR, pt_regs, badaddr);
+	OFFSET(PT_CAUSE, pt_regs, cause);
+
+	/*
+	 * We allocate a pt_regs on the stack. This ensures the alignment is sane.
+	 */
+	DEFINE(PT_SIZE_ON_STACK, ALIGN(sizeof(struct pt_regs), STACK_ALIGN));
 	return 0;
 }
-- 
2.29.2


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


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

* [PATCH v2 11/29] RISC-V: support incoherent I-Cache
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (9 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 10/29] RISC-V: add exception support Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 12/29] drivers: soc: sifive: add basic L2 cache controller driver Ahmad Fatoum
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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.

The underlying fence.i primitive is part of the Zifencei
(load/store fence) ISA extension. As we can't be sure it's always
available, the exception handler will skip over the instruction
if the CPU trips over it. Alternatively, if CONFIG_HAS_CACHE=n,
the instruction won't be emitted at all.

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/cpu/interrupts.c            |  9 +++++++++
 arch/riscv/include/asm/barebox-riscv.h |  2 ++
 arch/riscv/include/asm/cacheflush.h    | 16 ++++++++++++++++
 arch/riscv/lib/reloc.c                 |  8 ++++++++
 arch/riscv/lib/setupc.S                |  2 ++
 8 files changed, 48 insertions(+)
 create mode 100644 arch/riscv/include/asm/cacheflush.h

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 8f955cd4d220..6ec2315d4e70 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -17,12 +17,14 @@ config SOC_VIRT
 	bool "QEMU Virt Machine"
 	select RISCV_S_MODE
 	select BOARD_RISCV_GENERIC_DT
+	select HAS_CACHE
 	help
 	  Generates an image tht can be be booted by QEMU. The image is called
 	  barebox-dt-2nd.img
 
 config CPU_SIFIVE
 	bool
+	select HAS_CACHE
 
 config SOC_SIFIVE
 	bool "SiFive SoCs"
diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
index c6c20b38e390..4ed9b4d37192 100644
--- a/arch/riscv/boot/uncompress.c
+++ b/arch/riscv/boot/uncompress.c
@@ -66,6 +66,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/cpu/interrupts.c b/arch/riscv/cpu/interrupts.c
index df6d3e6e010b..0e8951b61968 100644
--- a/arch/riscv/cpu/interrupts.c
+++ b/arch/riscv/cpu/interrupts.c
@@ -121,6 +121,15 @@ unsigned long handle_trap(struct pt_regs *regs)
 	if (skip_data_abort(regs))
 		goto skip;
 
+	if (regs->cause == 2) { /* illegal instruction */
+		switch(*(unsigned long *)regs->epc) {
+		case 0x0000100f: /* fence.i */
+			goto skip;
+		default:
+			break;
+		}
+	}
+
 	report_trap(regs);
 	hang();
 
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/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
new file mode 100644
index 000000000000..9ff25740c66b
--- /dev/null
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_CACHEFLUSH_H
+#define _ASM_RISCV_CACHEFLUSH_H
+
+static inline void local_flush_icache_all(void)
+{
+#ifdef HAS_CACHE
+	asm volatile ("fence.i" ::: "memory");
+#endif
+}
+
+#endif /* _ASM_RISCV_CACHEFLUSH_H */
diff --git a/arch/riscv/lib/reloc.c b/arch/riscv/lib/reloc.c
index 2fc8818cd698..479d586afdee 100644
--- a/arch/riscv/lib/reloc.c
+++ b/arch/riscv/lib/reloc.c
@@ -5,6 +5,7 @@
 #include <linux/linkage.h>
 #include <asm/sections.h>
 #include <asm/barebox-riscv.h>
+#include <asm/cacheflush.h>
 #include <debug_ll.h>
 #include <asm-generic/module.h>
 
@@ -24,6 +25,11 @@
 
 #define RISC_R_TYPE(x)	((x) & 0xFF)
 
+void sync_caches_for_execution(void)
+{
+	local_flush_icache_all();
+}
+
 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] 33+ messages in thread

* [PATCH v2 12/29] drivers: soc: sifive: add basic L2 cache controller driver
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (10 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 11/29] RISC-V: support incoherent I-Cache Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 13/29] soc: starfive: add support for JH7100 incoherent interconnect Ahmad Fatoum
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

SiFive SoCs are cache coherent with respect to other DMA masters,
so there is no need to explicitly flush cache lines.
Incoming StarFive SoC uses SiFive CPU and L2 cache controller,
but is cache-incoherent and thus needs the maintenance for DMA.

Add a basic driver that exports the cache flush function for
SoC-specific drivers to use.

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 | 116 +++++++++++++++++++++++++++
 include/soc/sifive/l2_cache.h        |  10 +++
 7 files changed, 164 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
 create mode 100644 include/soc/sifive/l2_cache.h

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 6ec2315d4e70..b4fdfd9741cd 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -64,5 +64,10 @@ config SOC_STARFIVE_JH7100
 
 endif
 
+comment "CPU features"
+
+config SIFIVE_L2
+	bool "SiFive L2 cache controller"
+	depends on CPU_SIFIVE
 
 endmenu
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..b787379586ae
--- /dev/null
+++ b/drivers/soc/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y	+= imx/
+obj-$(CONFIG_CPU_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..96d6d4ec4773
--- /dev/null
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -0,0 +1,116 @@
+// 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 <soc/sifive/l2_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);
+}
+
+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 (WARN_ON(!l2_base))
+		return;
+
+	if (start == end)
+		return;
+
+	mb();
+	for (line = start; line < end; line += SIFIVE_L2_FLUSH64_LINE_LEN) {
+		writeq(line, l2_base + SIFIVE_L2_FLUSH64);
+		mb();
+	}
+}
+
+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;
+
+	return 0;
+}
+
+static const struct of_device_id sifive_l2_ids[] = {
+	{ .compatible = "sifive,fu540-c000-ccache" },
+	{ .compatible = "sifive,fu740-c000-ccache" },
+	{ /* 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);
diff --git a/include/soc/sifive/l2_cache.h b/include/soc/sifive/l2_cache.h
new file mode 100644
index 000000000000..0da655cd4e30
--- /dev/null
+++ b/include/soc/sifive/l2_cache.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __SOC_SIFIVE_L2_CACHE_H_
+#define __SOC_SIFIVE_L2_CACHE_H_
+
+#include <linux/types.h>
+
+void sifive_l2_flush64_range(dma_addr_t start, dma_addr_t end);
+
+#endif
-- 
2.29.2


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


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

* [PATCH v2 13/29] soc: starfive: add support for JH7100 incoherent interconnect
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (11 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 12/29] drivers: soc: sifive: add basic L2 cache controller driver Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 14/29] soc: sifive: l2_cache: enable maximum available cache ways Ahmad Fatoum
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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 +++
 drivers/soc/Makefile                 |  1 +
 drivers/soc/sifive/sifive_l2_cache.c |  1 +
 drivers/soc/starfive/Makefile        |  1 +
 drivers/soc/starfive/jh7100_dma.c    | 55 ++++++++++++++++++++++++++++
 5 files changed, 63 insertions(+)
 create mode 100644 drivers/soc/starfive/Makefile
 create mode 100644 drivers/soc/starfive/jh7100_dma.c

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index b4fdfd9741cd..c112fcc82e1a 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -61,6 +61,11 @@ config SOC_STARFIVE_JH71XX
 config SOC_STARFIVE_JH7100
 	bool
 	select SOC_STARFIVE_JH71XX
+	select SIFIVE_L2
+	help
+	  Unlike JH7110 and later, CPU on the JH7100 are not cache-coherent
+	  with respect to DMA masters like GMAC and DW MMC controller.
+	  Select this if barebox needs to do DMA on this SoC.
 
 endif
 
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index b787379586ae..c3499c0c7f30 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,3 +2,4 @@
 
 obj-y	+= imx/
 obj-$(CONFIG_CPU_SIFIVE)	+= sifive/
+obj-$(CONFIG_SOC_STARFIVE)	+= starfive/
diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
index 96d6d4ec4773..9e54474f7ae8 100644
--- a/drivers/soc/sifive/sifive_l2_cache.c
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -105,6 +105,7 @@ static int sifive_l2_probe(struct device_d *dev)
 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 */ },
 };
 
diff --git a/drivers/soc/starfive/Makefile b/drivers/soc/starfive/Makefile
new file mode 100644
index 000000000000..72504b3bef26
--- /dev/null
+++ b/drivers/soc/starfive/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SOC_STARFIVE_JH7100) += jh7100_dma.o
diff --git a/drivers/soc/starfive/jh7100_dma.c b/drivers/soc/starfive/jh7100_dma.c
new file mode 100644
index 000000000000..a1dc48e73f6e
--- /dev/null
+++ b/drivers/soc/starfive/jh7100_dma.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <asm/dma.h>
+#include <soc/sifive/l2_cache.h>
+
+#define SDRAM_CACHED_BASE	0x80000000
+#define SDRAM_UNCACHED_BASE	0x1000000000
+
+static inline void *jh7100_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+	dma_addr_t cpu_base;
+	void *ret;
+
+	ret = xmemalign(PAGE_SIZE, size);
+
+	memset(ret, 0, size);
+
+	cpu_base = (dma_addr_t)ret;
+
+	if (dma_handle)
+		*dma_handle = cpu_base;
+
+	sifive_l2_flush64_range(cpu_base, cpu_base + size);
+
+	return ret - SDRAM_CACHED_BASE + SDRAM_UNCACHED_BASE;
+
+}
+
+static inline void jh7100_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
+{
+	free((void *)dma_handle);
+}
+
+static const struct dma_ops jh7100_dma_ops = {
+	.alloc_coherent = jh7100_alloc_coherent,
+	.free_coherent = jh7100_free_coherent,
+	.flush_range = sifive_l2_flush64_range,
+	.inv_range = sifive_l2_flush64_range,
+};
+
+static int jh7100_dma_init(void)
+{
+	/* board drivers can claim the machine compatible, so no driver here */
+	if (!of_machine_is_compatible("starfive,jh7100"))
+		return 0;
+
+	dma_set_ops(&jh7100_dma_ops);
+
+	return 0;
+}
+mmu_initcall(jh7100_dma_init);
-- 
2.29.2


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


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

* [PATCH v2 14/29] soc: sifive: l2_cache: enable maximum available cache ways
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (12 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 13/29] soc: starfive: add support for JH7100 incoherent interconnect Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems Ahmad Fatoum
                   ` (15 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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 | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
index 9e54474f7ae8..a1e9a1062204 100644
--- a/drivers/soc/sifive/sifive_l2_cache.c
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -15,6 +15,7 @@
 #include <init.h>
 #include <soc/sifive/l2_cache.h>
 #include <asm/barrier.h>
+#include <linux/bitops.h>
 
 #define SIFIVE_L2_DIRECCFIX_LOW 0x100
 #define SIFIVE_L2_DIRECCFIX_HIGH 0x104
@@ -40,6 +41,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;
@@ -84,6 +88,19 @@ void sifive_l2_flush64_range(dma_addr_t start, dma_addr_t end)
 	}
 }
 
+static void 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();
+}
+
 static int sifive_l2_probe(struct device_d *dev)
 {
 	struct resource *iores;
@@ -97,6 +114,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;
 
 	return 0;
-- 
2.29.2


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


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

* [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (13 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 14/29] soc: sifive: l2_cache: enable maximum available cache ways Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-21  7:25   ` Sascha Hauer
  2021-06-19  4:50 ` [PATCH v2 16/29] net: designware: add support for IP integrated into StarFive SoC Ahmad Fatoum
                   ` (14 subsequent siblings)
  29 siblings, 1 reply; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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, which additionally
needs a non 1:1 mapping for coherent DMA.

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    | 57 ++++++++++++++++++++++---------------
 drivers/net/designware.h    | 28 +++++++++++++++---
 3 files changed, 68 insertions(+), 27 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 0ee6d3d78ac7..559e202c29ce 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -104,15 +104,15 @@ static void tx_descs_init(struct eth_device *dev)
 {
 	struct dw_eth_dev *priv = dev->priv;
 	struct eth_dma_regs *dma_p = priv->dma_regs_p;
-	struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
+	struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable_cpu[0];
 	char *txbuffs = &priv->txbuffs[0];
 	struct dmamacdescr *desc_p;
 	u32 idx;
 
 	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 = tx_dma_addr(priv, &desc_table_p[idx + 1]);
 
 		if (priv->enh_desc) {
 			desc_p->txrx_status &= ~(DESC_ENH_TXSTS_TXINT | DESC_ENH_TXSTS_TXLAST |
@@ -130,9 +130,9 @@ 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 = tx_dma_addr(priv, &desc_table_p[0]);
 
-	writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
+	writel(desc_p->dmamac_next, &dma_p->txdesclistaddr);
 	priv->tx_currdescnum = 0;
 }
 
@@ -140,15 +140,15 @@ static void rx_descs_init(struct eth_device *dev)
 {
 	struct dw_eth_dev *priv = dev->priv;
 	struct eth_dma_regs *dma_p = priv->dma_regs_p;
-	struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
+	struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable_cpu[0];
 	char *rxbuffs = &priv->rxbuffs[0];
 	struct dmamacdescr *desc_p;
 	u32 idx;
 
 	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 = rx_dma_addr(priv, &desc_table_p[idx + 1]);
 
 		desc_p->dmamac_cntl = MAC_MAX_FRAME_SZ;
 		if (priv->enh_desc)
@@ -156,15 +156,15 @@ 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 = rx_dma_addr(priv, &desc_table_p[0]);
 
-	writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
+	writel(desc_p->dmamac_next, &dma_p->rxdesclistaddr);
 	priv->rx_currdescnum = 0;
 }
 
@@ -276,7 +276,7 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
 	struct dw_eth_dev *priv = dev->priv;
 	struct eth_dma_regs *dma_p = priv->dma_regs_p;
 	u32 owndma, desc_num = priv->tx_currdescnum;
-	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
+	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable_cpu[desc_num];
 
 	owndma = priv->enh_desc ? DESC_ENH_TXSTS_OWNBYDMA : DESC_TXSTS_OWNBYDMA;
 	/* Check if the descriptor is owned by CPU */
@@ -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;
@@ -324,7 +324,7 @@ static int dwc_ether_rx(struct eth_device *dev)
 {
 	struct dw_eth_dev *priv = dev->priv;
 	u32 desc_num = priv->rx_currdescnum;
-	struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
+	struct dmamacdescr *desc_p = &priv->rx_mac_descrtable_cpu[desc_num];
 
 	u32 status = desc_p->txrx_status;
 	int length = 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);
@@ -481,12 +483,21 @@ struct dw_eth_dev *dwc_drv_probe(struct device_d *dev)
 	priv->mac_regs_p = base;
 	dwc_version(dev, readl(&priv->mac_regs_p->version));
 	priv->dma_regs_p = base + DW_DMA_BASE_OFFSET;
-	priv->tx_mac_descrtable = dma_alloc_coherent(
+
+	priv->tx_mac_descrtable_cpu = dma_alloc_coherent(
 		CONFIG_TX_DESCR_NUM * sizeof(struct dmamacdescr),
-		DMA_ADDRESS_BROKEN);
-	priv->rx_mac_descrtable = dma_alloc_coherent(
+		&priv->tx_mac_descrtable_dev);
+
+	if (dma_mapping_error(dev, priv->tx_mac_descrtable_dev))
+		return ERR_PTR(-EFAULT);
+
+	priv->rx_mac_descrtable_cpu = dma_alloc_coherent(
 		CONFIG_RX_DESCR_NUM * sizeof(struct dmamacdescr),
-		DMA_ADDRESS_BROKEN);
+		&priv->rx_mac_descrtable_dev);
+
+	if (dma_mapping_error(dev, priv->rx_mac_descrtable_dev))
+		return ERR_PTR(-EFAULT);
+
 	priv->txbuffs = dma_alloc(TX_TOTAL_BUFSIZE);
 	priv->rxbuffs = dma_alloc(RX_TOTAL_BUFSIZE);
 
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index 0a6a6bf1a497..5851187c0cf0 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -8,6 +8,7 @@
 #define __DESIGNWARE_ETH_H
 
 #include <net.h>
+#include <linux/types.h>
 
 struct dw_eth_dev {
 	struct eth_device netdev;
@@ -18,8 +19,11 @@ struct dw_eth_dev {
 	u32 tx_currdescnum;
 	u32 rx_currdescnum;
 
-	struct dmamacdescr *tx_mac_descrtable;
-	struct dmamacdescr *rx_mac_descrtable;
+	struct dmamacdescr *tx_mac_descrtable_cpu;
+	struct dmamacdescr *rx_mac_descrtable_cpu;
+
+	dma_addr_t tx_mac_descrtable_dev;
+	dma_addr_t rx_mac_descrtable_dev;
 
 	u8 *txbuffs;
 	u8 *rxbuffs;
@@ -38,6 +42,20 @@ struct dw_eth_drvdata {
 	void *priv;
 };
 
+static inline dma_addr_t tx_dma_addr(struct dw_eth_dev *priv,
+				     struct dmamacdescr *desc)
+{
+	return priv->tx_mac_descrtable_dev
+		+ ((u8 *)desc - (u8 *)priv->tx_mac_descrtable_cpu);
+}
+
+static inline dma_addr_t rx_dma_addr(struct dw_eth_dev *priv,
+				     struct dmamacdescr *desc)
+{
+	return priv->rx_mac_descrtable_dev
+		+ ((u8 *)desc - (u8 *)priv->rx_mac_descrtable_cpu);
+}
+
 struct dw_eth_dev *dwc_drv_probe(struct device_d *dev);
 void dwc_drv_remove(struct device_d *dev);
 
@@ -138,10 +156,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] 33+ messages in thread

* [PATCH v2 16/29] net: designware: add support for IP integrated into StarFive SoC
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (14 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 17/29] mci: allocate DMA-able memory Ahmad Fatoum
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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 | 110 ++++++++++++++++++++++++++++++
 include/soc/starfive/sysmain.h    |  15 ++++
 6 files changed, 139 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 18931211b54f..802169a86e8c 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 1674d53dffe8..fb3e3bdee46a 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 559e202c29ce..afc275e81ecb 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -459,11 +459,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 5851187c0cf0..8f6234aec5d1 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -39,6 +39,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..3dc9d14e11c1
--- /dev/null
+++ b/drivers/net/designware_starfive.c
@@ -0,0 +1,110 @@
+// 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 = "stmmaceth" },
+		{ .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] 33+ messages in thread

* [PATCH v2 17/29] mci: allocate DMA-able memory
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (15 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 16/29] net: designware: add support for IP integrated into StarFive SoC Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 18/29] mci: allocate sector_buf on demand Ahmad Fatoum
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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 a094f3cbf522..b174067a7fbc 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
 
@@ -1852,7 +1853,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] 33+ messages in thread

* [PATCH v2 18/29] mci: allocate sector_buf on demand
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (16 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 17/29] mci: allocate DMA-able memory Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 19/29] dma: allocate 32-byte aligned buffers by default Ahmad Fatoum
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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 b174067a7fbc..92a73c8f1dfe 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1790,6 +1790,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);
@@ -1851,15 +1856,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] 33+ messages in thread

* [PATCH v2 19/29] dma: allocate 32-byte aligned buffers by default
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (17 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 18/29] mci: allocate sector_buf on demand Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 20/29] mci: dw_mmc: add optional reset line Ahmad Fatoum
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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] 33+ messages in thread

* [PATCH v2 20/29] mci: dw_mmc: add optional reset line
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (18 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 19/29] dma: allocate 32-byte aligned buffers by default Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 21/29] mci: dw_mmc: match against StarFive MMC compatibles Ahmad Fatoum
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Steffen Trumtrar, Ahmad Fatoum

The bindings describe a reset line for the MMC controller and we have
boards with device tree that contain a reset line that barebox has so
far never acted upon. For the StarFive, we need the reset, so have the
driver toggle it optionally if specified. This change wasn't tested
on existing users of the driver, like the SoCFPGA or the Rockchip
rk2928 and rk3288.

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

diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c
index 930b538adc15..ad1d2a06b914 100644
--- a/drivers/mci/dw_mmc.c
+++ b/drivers/mci/dw_mmc.c
@@ -17,6 +17,7 @@
 #include <io.h>
 #include <platform_data/dw_mmc.h>
 #include <linux/bitops.h>
+#include <linux/reset.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <errno.h>
@@ -548,6 +549,7 @@ static int dwmci_init(struct mci_host *mci, struct device_d *dev)
 
 static int dw_mmc_probe(struct device_d *dev)
 {
+	struct reset_control	*rst;
 	struct resource *iores;
 	struct dwmci_host *host;
 	struct dw_mmc_platform_data *pdata = dev->platform_data;
@@ -568,6 +570,15 @@ static int dw_mmc_probe(struct device_d *dev)
 	clk_enable(host->clk_biu);
 	clk_enable(host->clk_ciu);
 
+	rst = reset_control_get(dev, "reset");
+	if (IS_ERR(rst)) {
+		dev_warn(dev, "error claiming reset: %pe\n", rst);
+	} else if (rst) {
+		reset_control_assert(rst);
+		udelay(10);
+		reset_control_deassert(rst);
+	}
+
 	iores = dev_request_mem_resource(dev, 0);
 	if (IS_ERR(iores))
 		return PTR_ERR(iores);
-- 
2.29.2


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


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

* [PATCH v2 21/29] mci: dw_mmc: match against StarFive MMC compatibles
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (19 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 20/29] mci: dw_mmc: add optional reset line Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 22/29] clk: add initial StarFive clock support Ahmad Fatoum
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The Linux driver in v5.13 doesn't determine min and max frequency from
clk_ciu, instead it consults the clock-frequency property in the device
tree. We will want to follow the Linux way for the StarFive, especially
because clk_get_rate returns bogus results for the JH7100, because the
clock tree doesn't yet describe enough information to calculate rates.

Add a compatible that does the necessary things as well as a generic
snps,dw-mshc compatible, like what the vendor device tree uses. The hope
is, that with complete clock tree described, we can drop the
starfive,jh7100-dw-mshc compatible check in future and use the generic
compatible instead.

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

diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c
index ad1d2a06b914..b402090ab3cb 100644
--- a/drivers/mci/dw_mmc.c
+++ b/drivers/mci/dw_mmc.c
@@ -32,7 +32,7 @@ struct dwmci_host {
 	unsigned int fifo_size_bytes;
 
 	struct dwmci_idmac *idmac;
-	unsigned long clkrate;
+	u32 clkrate;
 	int ciu_div;
 	u32 fifoth_val;
 	u32 pwren_value;
@@ -572,7 +572,7 @@ static int dw_mmc_probe(struct device_d *dev)
 
 	rst = reset_control_get(dev, "reset");
 	if (IS_ERR(rst)) {
-		dev_warn(dev, "error claiming reset: %pe\n", rst);
+		return PTR_ERR(rst);
 	} else if (rst) {
 		reset_control_assert(rst);
 		udelay(10);
@@ -617,7 +617,11 @@ static int dw_mmc_probe(struct device_d *dev)
 	else
 		host->pwren_value = 1;
 
-	host->clkrate = clk_get_rate(host->clk_ciu);
+	if (of_device_is_compatible(dev->device_node, "starfive,jh7100-dw-mshc"))
+		of_property_read_u32(dev->device_node, "clock-frequency", &host->clkrate);
+	if (!host->clkrate)
+		host->clkrate = clk_get_rate(host->clk_ciu);
+
 	host->mci.f_min = host->clkrate / 510 / host->ciu_div;
 	if (host->mci.f_min < 200000)
 		host->mci.f_min = 200000;
@@ -635,6 +639,10 @@ static __maybe_unused struct of_device_id dw_mmc_compatible[] = {
 		.compatible = "rockchip,rk2928-dw-mshc",
 	}, {
 		.compatible = "rockchip,rk3288-dw-mshc",
+	}, {
+		.compatible = "snps,dw-mshc",
+	}, {
+		.compatible = "starfive,jh7100-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] 33+ messages in thread

* [PATCH v2 22/29] clk: add initial StarFive clock support
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (20 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 21/29] mci: dw_mmc: match against StarFive MMC compatibles Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 23/29] reset: add StarFive reset controller driver Ahmad Fatoum
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

All clocks seem to share a common format:

 struct starfive_clk {
	u32 divisor : 24;	/* LSB */
	u32 mux : 6;
	u32 invert : 1;
	u32 enable : 1;		/* MSB */
 };

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..4e9bf7f2ba83
--- /dev/null
+++ b/drivers/clk/starfive/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SOC_STARFIVE_JH71XX) += 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] 33+ messages in thread

* [PATCH v2 23/29] reset: add StarFive reset controller driver
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (21 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 22/29] clk: add initial StarFive clock support Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 24/29] watchdog: add StarFive watchdog driver Ahmad Fatoum
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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            | 234 ++++++++++++++++++
 .../reset-controller/starfive-jh7100.h        | 126 ++++++++++
 include/soc/starfive/rstgen.h                 |  41 +++
 6 files changed, 409 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 c112fcc82e1a..e5603b001c74 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -49,6 +49,7 @@ endif
 
 config SOC_STARFIVE
 	bool "StarFive SoCs"
+	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..bcf615da0a13
--- /dev/null
+++ b/drivers/reset/reset-starfive-vic.c
@@ -0,0 +1,234 @@
+// 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 struct clk *starfive_reset_clk_get(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 of_clk_get_from_provider(&clkspec);
+}
+
+static int starfive_reset_clk_enable(struct starfive_rstgen *priv, unsigned id)
+{
+	return clk_enable(starfive_reset_clk_get(priv, id));
+}
+
+static void starfive_reset_clk_disable(struct starfive_rstgen *priv, unsigned id)
+{
+	clk_disable(starfive_reset_clk_get(priv, id));
+}
+
+static int starfive_rstgen(struct starfive_rstgen *priv, unsigned id, bool assert)
+{
+	void __iomem *base = priv->base;
+
+	__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)
+{
+	struct starfive_rstgen *priv = to_starfive_rstgen(rcdev);
+	int ret;
+
+	starfive_reset_clk_enable(priv, id);
+	ret = starfive_rstgen(priv, id, true);
+	starfive_reset_clk_disable(priv, id);
+
+	return ret;
+}
+
+static int starfive_rstgen_deassert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	struct starfive_rstgen *priv = to_starfive_rstgen(rcdev);
+	int ret;
+
+	starfive_reset_clk_enable(priv, id);
+	ret = starfive_rstgen(priv, id, false);
+	starfive_reset_clk_disable(priv, id);
+
+	return ret;
+}
+
+static int starfive_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	struct starfive_rstgen *priv = to_starfive_rstgen(rcdev);
+	int ret;
+
+	starfive_reset_clk_enable(priv, id);
+
+	ret = starfive_rstgen(priv, id, true);
+	if (ret)
+		goto out;
+
+	udelay(2);
+
+	ret = starfive_rstgen(priv, id, false);
+
+out:
+	starfive_reset_clk_disable(priv, id);
+
+	return ret;
+}
+
+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] 33+ messages in thread

* [PATCH v2 24/29] watchdog: add StarFive watchdog driver
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (22 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 23/29] reset: add StarFive reset controller driver Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 25/29] hw_random: add driver for RNG on StarFive SoC Ahmad Fatoum
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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 | 106 ++++++++++++++++++++++++++++++++
 3 files changed, 114 insertions(+)
 create mode 100644 drivers/watchdog/starfive_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b785181c59db..080bc91ff7f5 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -141,4 +141,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..6779566fd6c1
--- /dev/null
+++ b/drivers/watchdog/starfive_wdt.c
@@ -0,0 +1,106 @@
+// 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
+
+#define WDT_TICKS_PER_SEC	50000000
+
+struct starfive_wdt {
+	u32 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_bulk_data clks[] = {
+		{ .id = "bus" },
+		{ .id = "core" },
+	};
+	int ret;
+
+	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_all(dev);
+	if (ret)
+		return ret;
+
+	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 = WDT_TICKS_PER_SEC;
+
+	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] 33+ messages in thread

* [PATCH v2 25/29] hw_random: add driver for RNG on StarFive SoC
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (23 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 24/29] watchdog: add StarFive watchdog driver Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 26/29] reset: add device_reset_all helper Ahmad Fatoum
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 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 | 208 +++++++++++++++++++++++++++
 3 files changed, 216 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..f7b7585884ac
--- /dev/null
+++ b/drivers/hw_random/starfive-vic-rng.c
@@ -0,0 +1,208 @@
+// 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>
+#include <linux/clk.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);
+	struct clk *clk;
+	int ret;
+
+	clk = clk_get(rng->dev, NULL);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	clk_enable(clk);
+
+	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] 33+ messages in thread

* [PATCH v2 26/29] reset: add device_reset_all helper
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (24 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 25/29] hw_random: add driver for RNG on StarFive SoC Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 27/29] gpio: add support for StarFive GPIO controller Ahmad Fatoum
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Some StarFive peripherals have 5 resets that need to be triggered in
order. Add a helper to simplify this. The Linux way of doing this would
be to import the reset_control_array API, but device_reset_all as
implemented here saves us from this boilerplate.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/reset/core.c  | 78 +++++++++++++++++++++++++++++++++++++------
 include/linux/reset.h |  7 ++++
 2 files changed, 75 insertions(+), 10 deletions(-)

diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 26a54f21dff0..940b46d4b4bd 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -139,30 +139,35 @@ int reset_control_deassert(struct reset_control *rstc)
 EXPORT_SYMBOL_GPL(reset_control_deassert);
 
 /**
- * of_reset_control_get - Lookup and obtain a reference to a reset controller.
+ * of_reset_control_count - Count reset lines
+ * @node: device node
+ *
+ * Returns number of resets, 0 if none specified
+ */
+static int of_reset_control_count(struct device_node *node)
+{
+	return of_count_phandle_with_args(node, "resets", "#reset-cells");
+}
+
+/**
+ * of_reset_control_get_by_index - Lookup and obtain a reference to a reset controller.
  * @node: device to be reset by the controller
- * @id: reset line name
+ * @index: reset line index
  *
  * Returns a struct reset_control or IS_ERR() condition containing errno.
- *
- * Use of id names is optional.
  */
-static struct reset_control *of_reset_control_get(struct device_node *node,
-						  const char *id)
+static struct reset_control *of_reset_control_get_by_index(struct device_node *node,
+							   int index)
 {
 	struct reset_control *rstc;
 	struct reset_controller_dev *r, *rcdev;
 	struct of_phandle_args args;
-	int index = 0;
 	int rstc_id;
 	int ret;
 
 	if (!of_get_property(node, "resets", NULL))
 		return NULL;
 
-	if (id)
-		index = of_property_match_string(node,
-						 "reset-names", id);
 	ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
 					 index, &args);
 	if (ret)
@@ -195,6 +200,26 @@ static struct reset_control *of_reset_control_get(struct device_node *node,
 	return rstc;
 }
 
+/**
+ * of_reset_control_get - Lookup and obtain a reference to a reset controller.
+ * @node: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Returns a struct reset_control or IS_ERR() condition containing errno.
+ *
+ * Use of id names is optional.
+ */
+static struct reset_control *of_reset_control_get(struct device_node *node,
+						  const char *id)
+{
+	int index = 0;
+
+	if (id)
+		index = of_property_match_string(node, "reset-names", id);
+
+	return of_reset_control_get_by_index(node, index);
+}
+
 static struct reset_control *
 gpio_reset_control_get(struct device_d *dev, const char *id)
 {
@@ -302,6 +327,39 @@ int device_reset(struct device_d *dev)
 }
 EXPORT_SYMBOL_GPL(device_reset);
 
+int device_reset_all(struct device_d *dev)
+{
+	struct reset_control *rstc;
+	int ret, i;
+
+	for (i = 0; i < of_reset_control_count(dev->device_node); i++) {
+		int ret;
+
+		rstc = of_reset_control_get_by_index(dev->device_node, i);
+		if (IS_ERR(rstc))
+			return PTR_ERR(rstc);
+
+		ret = reset_control_reset(rstc);
+		if (ret)
+			return ret;
+
+		reset_control_put(rstc);
+	}
+
+	if (i == 0) {
+		rstc = gpio_reset_control_get(dev, NULL);
+
+		ret = reset_control_reset(rstc);
+		if (ret)
+			return ret;
+
+		reset_control_put(rstc);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(device_reset_all);
+
 int device_reset_us(struct device_d *dev, int us)
 {
 	struct reset_control *rstc;
diff --git a/include/linux/reset.h b/include/linux/reset.h
index a166fe1cfe04..0a98ea6bacdf 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -17,6 +17,8 @@ int __must_check device_reset(struct device_d *dev);
 
 int __must_check device_reset_us(struct device_d *dev, int us);
 
+int __must_check device_reset_all(struct device_d *dev);
+
 #else
 
 static inline int reset_control_reset(struct reset_control *rstc)
@@ -54,6 +56,11 @@ static inline int device_reset(struct device_d *dev)
 	return 0;
 }
 
+static inline int device_reset_all(struct device_d *dev)
+{
+	return 0;
+}
+
 #endif /* CONFIG_RESET_CONTROLLER */
 
 #endif
-- 
2.29.2


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


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

* [PATCH v2 27/29] gpio: add support for StarFive GPIO controller
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (25 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 26/29] reset: add device_reset_all helper Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 28/29] misc: add power sequencing driver for initializing StarFive peripherals Ahmad Fatoum
                   ` (2 subsequent siblings)
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

This imports support for the StarFive GPIO controller from the vendor's
kernel tree.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/gpio/Kconfig             |   8 ++
 drivers/gpio/Makefile            |   1 +
 drivers/gpio/gpio-starfive-vic.c | 177 +++++++++++++++++++++++++++++++
 drivers/pinctrl/pinctrl-single.c |   4 +-
 include/pinctrl.h                |   6 ++
 5 files changed, 194 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpio/gpio-starfive-vic.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a8ee9e58b84e..98a44fbbb578 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -171,6 +171,14 @@ config GPIO_SIFIVE
 	help
 	  Say yes here to support the GPIO device on SiFive SoCs.
 
+config GPIO_STARFIVE
+	bool "StarFive GPIO support"
+	depends on SOC_STARFIVE || CROSS_COMPILE
+	depends on OF_GPIO
+	select GPIO_GENERIC
+	help
+	  Say yes here to support the GPIO device on StarFive SoCs.
+
 config GPIO_LIBFTDI1
 	bool "libftdi1 driver"
 	depends on SANDBOX
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 25e12105d83d..638cbb19a328 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_GPIO_SX150X)	+= gpio-sx150x.o
 obj-$(CONFIG_GPIO_VF610)	+= gpio-vf610.o
 obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
 obj-$(CONFIG_GPIO_SIFIVE)	+= gpio-sifive.o
+obj-$(CONFIG_GPIO_STARFIVE)	+= gpio-starfive-vic.o
diff --git a/drivers/gpio/gpio-starfive-vic.c b/drivers/gpio/gpio-starfive-vic.c
new file mode 100644
index 000000000000..baa4f584d5e8
--- /dev/null
+++ b/drivers/gpio/gpio-starfive-vic.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
+ */
+
+#include <linux/basic_mmio_gpio.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+#include <printk.h>
+#include <driver.h>
+#include <errno.h>
+#include <pinctrl.h>
+
+#define GPIO_EN		0x0
+#define GPIO_IS_LOW	0x10
+#define GPIO_IS_HIGH	0x14
+#define GPIO_IBE_LOW	0x18
+#define GPIO_IBE_HIGH	0x1c
+#define GPIO_IEV_LOW	0x20
+#define GPIO_IEV_HIGH	0x24
+#define GPIO_IE_LOW	0x28
+#define GPIO_IE_HIGH	0x2c
+#define GPIO_IC_LOW	0x30
+#define GPIO_IC_HIGH	0x34
+//read only
+#define GPIO_RIS_LOW	0x38
+#define GPIO_RIS_HIGH	0x3c
+#define GPIO_MIS_LOW	0x40
+#define GPIO_MIS_HIGH	0x44
+#define GPIO_DIN_LOW	0x48
+#define GPIO_DIN_HIGH	0x4c
+
+#define GPIO_DOUT_X_REG	0x50
+#define GPIO_DOEN_X_REG	0x54
+
+#define MAX_GPIO	 64
+
+struct starfive_gpio {
+	void __iomem		*base;
+	struct gpio_chip	gc;
+};
+
+#define to_starfive_gpio(gc) container_of(gc, struct starfive_gpio, gc)
+
+static int starfive_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct starfive_gpio *chip = to_starfive_gpio(gc);
+
+	if (offset >= gc->ngpio)
+		return -EINVAL;
+
+	writel(0x1, chip->base + GPIO_DOEN_X_REG + offset * 8);
+
+	return 0;
+}
+
+static int starfive_direction_output(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct starfive_gpio *chip = to_starfive_gpio(gc);
+
+	if (offset >= gc->ngpio)
+		return -EINVAL;
+	writel(0x0, chip->base + GPIO_DOEN_X_REG + offset * 8);
+	writel(value, chip->base + GPIO_DOUT_X_REG + offset * 8);
+
+	return 0;
+}
+
+static int starfive_get_direction(struct gpio_chip *gc, unsigned offset)
+{
+	struct starfive_gpio *chip = to_starfive_gpio(gc);
+
+	if (offset >= gc->ngpio)
+		return -EINVAL;
+
+	return readl(chip->base + GPIO_DOEN_X_REG + offset * 8) & 0x1;
+}
+
+static int starfive_get_value(struct gpio_chip *gc, unsigned offset)
+{
+	struct starfive_gpio *chip = to_starfive_gpio(gc);
+	int value;
+
+	if (offset >= gc->ngpio)
+		return -EINVAL;
+
+	if(offset < 32){
+		value = readl(chip->base + GPIO_DIN_LOW);
+		return (value >> offset) & 0x1;
+	} else {
+		value = readl(chip->base + GPIO_DIN_HIGH);
+		return (value >> (offset - 32)) & 0x1;
+	}
+}
+
+static void starfive_set_value(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct starfive_gpio *chip = to_starfive_gpio(gc);
+
+	if (offset >= gc->ngpio)
+		return;
+
+	writel(value, chip->base + GPIO_DOUT_X_REG + offset * 8);
+}
+
+static struct gpio_ops starfive_gpio_ops = {
+	.direction_input = starfive_direction_input,
+	.direction_output = starfive_direction_output,
+	.get_direction = starfive_get_direction,
+	.get = starfive_get_value,
+	.set = starfive_set_value,
+};
+
+static int starfive_gpio_probe(struct device_d *dev)
+{
+	struct starfive_gpio *chip;
+	struct resource *res;
+	struct clk *clk;
+	int ret;
+
+	clk = clk_get(dev, NULL);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	clk_enable(clk);
+
+	ret = device_reset(dev);
+	if (ret)
+		return ret;
+
+	ret = pinctrl_single_probe(dev);
+	if (ret)
+		return ret;
+
+	res = dev_get_resource(dev, IORESOURCE_MEM, 0);
+	if (IS_ERR(res))
+		return PTR_ERR(res);
+
+	chip = xzalloc(sizeof(*chip));
+	chip->base = IOMEM(res->start);
+
+	chip->gc.base = -1;
+	chip->gc.ngpio = MAX_GPIO;
+	chip->gc.dev = dev;
+	chip->gc.ops = &starfive_gpio_ops;
+
+	/* Disable all GPIO interrupts */
+	iowrite32(0, chip->base + GPIO_IE_HIGH);
+	iowrite32(0, chip->base + GPIO_IE_LOW);
+
+	ret = gpiochip_add(&chip->gc);
+	if (ret) {
+		dev_err(dev, "could not add gpiochip\n");
+		gpiochip_remove(&chip->gc);
+		return ret;
+	}
+
+	writel(1, chip->base + GPIO_EN);
+
+	return 0;
+}
+
+static const struct of_device_id starfive_gpio_match[] = {
+	{ .compatible = "starfive,gpio0", },
+	{ },
+};
+
+static struct driver_d starfive_gpio_driver = {
+	.probe	= starfive_gpio_probe,
+	.name		= "starfive_gpio",
+	.of_compatible	= starfive_gpio_match,
+};
+postcore_platform_driver(starfive_gpio_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
+MODULE_DESCRIPTION("Starfive VIC GPIO generator driver");
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index c77466023216..cf2f724d187d 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -128,7 +128,7 @@ static struct pinctrl_ops pcs_ops = {
 	.set_state = pcs_set_state,
 };
 
-static int pcs_probe(struct device_d *dev)
+int pinctrl_single_probe(struct device_d *dev)
 {
 	struct resource *iores;
 	struct pinctrl_single *pcs;
@@ -215,7 +215,7 @@ static __maybe_unused struct of_device_id pcs_dt_ids[] = {
 
 static struct driver_d pcs_driver = {
 	.name		= "pinctrl-single",
-	.probe		= pcs_probe,
+	.probe		= pinctrl_single_probe,
 	.of_compatible	= DRV_OF_COMPAT(pcs_dt_ids),
 };
 
diff --git a/include/pinctrl.h b/include/pinctrl.h
index 0fd7f491189c..a628c3aac95b 100644
--- a/include/pinctrl.h
+++ b/include/pinctrl.h
@@ -29,6 +29,7 @@ int of_pinctrl_select_state_default(struct device_node *np);
 int pinctrl_gpio_direction_input(unsigned pin);
 int pinctrl_gpio_direction_output(unsigned int pin);
 int pinctrl_gpio_get_direction(unsigned pin);
+int pinctrl_single_probe(struct device_d *dev);
 #else
 static inline int pinctrl_select_state(struct device_d *dev, const char *state)
 {
@@ -64,6 +65,11 @@ static inline int pinctrl_gpio_get_direction(unsigned pin)
 {
 	return -ENOTSUPP;
 }
+
+static inline int pinctrl_single_probe(struct device_d *dev)
+{
+	return -ENOSYS;
+}
 #endif
 
 #endif /* PINCTRL_H */
-- 
2.29.2


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


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

* [PATCH v2 28/29] misc: add power sequencing driver for initializing StarFive peripherals
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (26 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 27/29] gpio: add support for StarFive GPIO controller Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-19  4:50 ` [PATCH v2 29/29] RISC-V: StarFive: add board support for BeagleV Starlight Ahmad Fatoum
  2021-06-21  9:11 ` [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Sascha Hauer
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

There will likely not be a use case for having neural network
accelerator driver support within barebox. Still the driver requires a
reset sequence, which is not yet supported by vendor kernel's or known
forks. Until Linux can take care of this itself, add a simple driver
that gets some of the peripherals out of reset.

There also enables unconditionally some of the clocks that the vendor
kernel may depend on. Hopefully, in future, the whole driver can be
dropped when the kernel starts to do clock and reset control itself.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 drivers/misc/Kconfig           | 10 ++++
 drivers/misc/Makefile          |  1 +
 drivers/misc/starfive-pwrseq.c | 92 ++++++++++++++++++++++++++++++++++
 3 files changed, 103 insertions(+)
 create mode 100644 drivers/misc/starfive-pwrseq.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 87674a2a29f9..7426dfc46398 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -42,4 +42,14 @@ config ACPI_TEST
 	help
 	  This is a simple Test driver to test the ACPI bus.
 
+config STARFIVE_PWRSEQ
+	bool "StarFive power sequencing driver"
+	depends on SOC_STARFIVE
+	help
+	  This driver sets up a number of StarFive peripherals not matched
+	  by more specific barebox drivers by deasserting reset lines, muxing
+	  pins and/or enabling clocks. Peripherals set up by this can then
+	  be accessed over /dev/mem or used from kernels which still depend
+	  on bootloader for initialization.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 4d92465a1e5e..36743e6ae6a3 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_STATE_DRV)		+= state.o
 obj-$(CONFIG_DEV_MEM)		+= mem.o
 obj-$(CONFIG_UBOOTVAR)		+= ubootvar.o
 obj-$(CONFIG_ACPI_TEST)		+= acpi-test.o
+obj-$(CONFIG_STARFIVE_PWRSEQ)	+= starfive-pwrseq.o
diff --git a/drivers/misc/starfive-pwrseq.c b/drivers/misc/starfive-pwrseq.c
new file mode 100644
index 000000000000..6236547bc568
--- /dev/null
+++ b/drivers/misc/starfive-pwrseq.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <driver.h>
+#include <init.h>
+#include <linux/reset.h>
+#include <dt-bindings/clock/starfive-jh7100.h>
+#include <linux/clk.h>
+
+struct starfive_pwrseq {
+	const char **names;
+};
+
+static int starfive_pwrseq_probe(struct device_d *dev)
+{
+	int ret;
+
+	ret = device_reset_all(dev);
+	if (ret)
+		return ret;
+
+	return of_platform_populate(dev->device_node, NULL, dev);
+}
+
+static struct of_device_id starfive_pwrseq_dt_ids[] = {
+	{ .compatible = "starfive,axi-dma" },
+	{ .compatible = "cm,cm521-vpu" },
+	{ .compatible = "starfive,vic-sec" },
+	{ .compatible = "sfc,tempsensor" },
+	{ .compatible = "cm,codaj12-jpu-1" },
+	{ .compatible = "cdns,xrp" },
+	{ .compatible = "starfive,nne50" },
+	{ .compatible = "nvidia,nvdla_os_initial" },
+	{ .compatible = "starfive,spi2ahb" },
+	{ /* sentinel */ }
+};
+
+static struct driver_d starfive_pwrseq_driver = {
+	.name	= "starfive_pwrseq",
+	.probe	= starfive_pwrseq_probe,
+	.of_compatible = starfive_pwrseq_dt_ids,
+};
+
+static const int clks[] = {
+	CLK_VDEC_AXI, CLK_VDECBRG_MAIN, CLK_VDEC_BCLK, CLK_VDEC_CCLK, CLK_VDEC_APB,
+	CLK_JPEG_AXI, CLK_JPEG_CCLK, CLK_JPEG_APB,
+	CLK_DLA_AXI, CLK_DLANOC_AXI, CLK_DLA_APB, CLK_NNENOC_AXI, CLK_DLASLV_AXI,
+	CLK_VENC_AXI, CLK_VENCBRG_MAIN, CLK_VENC_BCLK, CLK_VENC_CCLK, CLK_VENC_APB,
+	CLK_SGDMA1P_AXI,
+	CLK_DMA2PNOC_AXI, CLK_SGDMA2P_AXI, CLK_SGDMA2P_AHB,
+	CLK_SDIO0_AHB,
+	CLK_SDIO1_AHB,
+	CLK_SPI2AHB_AHB, CLK_SPI2AHB_CORE,
+	CLK_EZMASTER_AHB,
+	CLK_SEC_AHB, CLK_AES, CLK_SHA, CLK_PKA,
+	CLK_UART0_APB, CLK_UART0_CORE,
+	CLK_UART1_APB, CLK_UART1_CORE,
+	CLK_UART2_APB, CLK_UART2_CORE,
+	CLK_UART3_APB, CLK_UART3_CORE,
+	CLK_SPI0_APB, CLK_SPI0_CORE,
+	CLK_SPI1_APB, CLK_SPI1_CORE,
+	CLK_SPI2_APB, CLK_SPI2_CORE,
+	CLK_SPI3_APB, CLK_SPI3_CORE,
+	CLK_I2C0_APB, CLK_I2C0_CORE,
+	CLK_I2C1_APB, CLK_I2C1_CORE,
+	CLK_I2C2_APB, CLK_I2C2_CORE,
+	CLK_I2C3_APB, CLK_I2C3_CORE,
+	CLK_VP6INTC_APB,
+	CLK_TEMP_APB, CLK_TEMP_SENSE,
+
+	CLK_END
+};
+
+static int __init starfive_pwrseq_driver_register(void)
+{
+	struct of_phandle_args clkspec;
+	int i;
+
+	clkspec.args_count = 1;
+	clkspec.np = of_find_compatible_node(NULL, NULL, "starfive,jh7100-clkgen");
+	if (clkspec.np) {
+		for (i = 0; clks[i] != CLK_END; i++) {
+			clkspec.args[0] = clks[i];
+			clk_enable(of_clk_get_from_provider(&clkspec));
+		}
+	}
+
+	return platform_driver_register(&starfive_pwrseq_driver);
+}
+device_initcall(starfive_pwrseq_driver_register);
-- 
2.29.2


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


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

* [PATCH v2 29/29] RISC-V: StarFive: add board support for BeagleV Starlight
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (27 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 28/29] misc: add power sequencing driver for initializing StarFive peripherals Ahmad Fatoum
@ 2021-06-19  4:50 ` Ahmad Fatoum
  2021-06-21  9:11 ` [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Sascha Hauer
  29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19  4:50 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

With the different drivers now in place, we have everything to start a
barebox image.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
 Documentation/boards/riscv.rst                |  37 +
 arch/riscv/Kconfig.socs                       |  18 +
 arch/riscv/boards/Makefile                    |   1 +
 arch/riscv/boards/beaglev/Makefile            |   5 +
 arch/riscv/boards/beaglev/board.c             |  30 +
 .../beaglev/defaultenv-beaglev/boot/buildroot |  13 +
 .../beaglev/defaultenv-beaglev/boot/fedora    |  16 +
 .../defaultenv-beaglev/nv/boot.default        |   1 +
 arch/riscv/boards/beaglev/lowlevel.c          |  18 +
 arch/riscv/configs/starfive_defconfig         | 131 +++
 arch/riscv/dts/Makefile                       |   1 +
 arch/riscv/dts/jh7100-beaglev-starlight.dts   |  54 ++
 arch/riscv/dts/jh7100-beaglev-starlight.dtsi  | 369 ++++++++
 arch/riscv/dts/jh7100.dtsi                    | 798 ++++++++++++++++++
 arch/riscv/include/asm/debug_ll.h             |   3 +
 common/Kconfig                                |   5 +
 images/Makefile.riscv                         |   4 +
 17 files changed, 1504 insertions(+)
 create mode 100644 arch/riscv/boards/beaglev/Makefile
 create mode 100644 arch/riscv/boards/beaglev/board.c
 create mode 100755 arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot
 create mode 100755 arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora
 create mode 100644 arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default
 create mode 100644 arch/riscv/boards/beaglev/lowlevel.c
 create mode 100644 arch/riscv/configs/starfive_defconfig
 create mode 100644 arch/riscv/dts/jh7100-beaglev-starlight.dts
 create mode 100644 arch/riscv/dts/jh7100-beaglev-starlight.dtsi
 create mode 100644 arch/riscv/dts/jh7100.dtsi

diff --git a/Documentation/boards/riscv.rst b/Documentation/boards/riscv.rst
index 53d13550f369..97f4d1deb7ba 100644
--- a/Documentation/boards/riscv.rst
+++ b/Documentation/boards/riscv.rst
@@ -60,6 +60,43 @@ into the config file.
 
 See https://barebox.org/jsbarebox/?graphic=1 for a live example.
 
+BeagleV
+-------
+
+barebox has second-stage support for the BeagleV Starlight::
+
+  make ARCH=riscv starfive_defconfig
+  make
+
+Thie resulting ``./images/barebox-beaglev-starlight.img`` can be used as payload
+to opensbi::
+
+  git clone https://github.com/starfive-tech/opensbi
+  cd opensbi
+  export ARCH=riscv
+  export PLATFORM=starfive/vic7100
+  export FW_PAYLOAD_PATH=$BAREBOX/build/images/barebox-beaglev-starlight.img
+
+  make ARCH=riscv
+  ./fsz.sh ./build/platform/starfive/vic7100/firmware/fw_payload.bin fw_payload.bin.out
+  ls -l $OPENSBI/build/platform/starfive/vic7100/firmware/fw_payload.bin.out
+
+The resulting ``./platform/starfive/vic7100/firmware/fw_payload.bin.out`` can then
+be flashed via Xmodem to the board::
+
+  picocom -b 115200 /dev/ttyUSB0 --send-cmd "sx -vv" --receive-cmd "rx -vv"
+  0:update uboot
+  select the function: 0␤
+  send file by xmodem
+  ^A^S./platform/starfive/vic7100/firmware/fw_payload.bin.out␤
+
+After reset, barebox should then boot to shell and attempt booting kernel ``Image``
+and device tree ``jh7100-starlight.dtb`` from the first root partition with the same
+partition as rootfs. Note that while barebox does take over some initialization,
+because of lack of Linux drivers, it doesn't yet do everything. If you experience
+boot hangs, you may need to disable devices (or extend the starfive-pwrseq driver
+to initialize it for you).
+
 Erizo
 -----
 
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index e5603b001c74..de74f216a215 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -50,6 +50,8 @@ endif
 config SOC_STARFIVE
 	bool "StarFive SoCs"
 	select ARCH_HAS_RESET_CONTROLLER
+	select RISCV_S_MODE
+	select HAS_ASM_DEBUG_LL
 	help
 	  This enables support for SiFive SoC platform hardware.
 
@@ -68,6 +70,22 @@ config SOC_STARFIVE_JH7100
 	  with respect to DMA masters like GMAC and DW MMC controller.
 	  Select this if barebox needs to do DMA on this SoC.
 
+config BOARD_BEAGLEV
+	bool "BeagleV"
+	depends on ARCH_RV64I
+	select SOC_STARFIVE_JH71XX
+	select USE_COMPRESSED_DTB
+
+config BOARD_BEAGLEV_BETA
+	bool "BeagleV Beta (with JH7100)"
+	depends on BOARD_BEAGLEV
+	select SOC_STARFIVE_JH7100
+	help
+	  Select this for hardware using the earlier JH7100 SoC. The JH7110
+	  used with later production runs is cache-coherent and thus can do
+	  without the special DMA handling enabled by this option. It's safe
+	  to enable this option for other SoCs.
+
 endif
 
 comment "CPU features"
diff --git a/arch/riscv/boards/Makefile b/arch/riscv/boards/Makefile
index 99f22f32b470..cb28a25d8bc8 100644
--- a/arch/riscv/boards/Makefile
+++ b/arch/riscv/boards/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_BOARD_ERIZO_GENERIC)	+= erizo/
 obj-$(CONFIG_BOARD_HIFIVE)		+= hifive/
+obj-$(CONFIG_BOARD_BEAGLEV)		+= beaglev/
diff --git a/arch/riscv/boards/beaglev/Makefile b/arch/riscv/boards/beaglev/Makefile
new file mode 100644
index 000000000000..23efc273ee0a
--- /dev/null
+++ b/arch/riscv/boards/beaglev/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+pbl-y += lowlevel.o
+obj-y += board.o
+bbenv-y += defaultenv-beaglev
diff --git a/arch/riscv/boards/beaglev/board.c b/arch/riscv/boards/beaglev/board.c
new file mode 100644
index 000000000000..110754ea95fb
--- /dev/null
+++ b/arch/riscv/boards/beaglev/board.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <bbu.h>
+#include <envfs.h>
+
+static int beaglev_probe(struct device_d *dev)
+{
+	barebox_set_hostname("beaglev-starlight");
+
+	defaultenv_append_directory(defaultenv_beaglev);
+
+	return 0;
+}
+
+static const struct of_device_id beaglev_of_match[] = {
+	{ .compatible = "beagle,beaglev-starlight-jh7100" },
+	{ /* sentinel */ },
+};
+
+static struct driver_d beaglev_board_driver = {
+	.name = "board-beaglev",
+	.probe = beaglev_probe,
+	.of_compatible = beaglev_of_match,
+};
+device_platform_driver(beaglev_board_driver);
diff --git a/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot
new file mode 100755
index 000000000000..157223bbee45
--- /dev/null
+++ b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+BOOT=/mnt/mmc0.0/boot
+
+detect mmc0
+
+global.linux.bootargs.base="rhgb stmmaceth=chain_mode:1"
+
+global.bootm.oftree=$BOOT/jh7100-starlight.dtb
+global.bootm.image=$BOOT/Image
+global linux.bootargs.root=rootwait
+global linux.bootargs.earlycon=earlycon
+global.bootm.appendroot=1
diff --git a/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora
new file mode 100755
index 000000000000..4f9ab16f8233
--- /dev/null
+++ b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+BOOT=/mnt/mmc0.0
+VERSION=5.10.6-210.0.riscv64.fc33.riscv64
+
+detect mmc0
+
+global.linux.bootargs.base="root=UUID=ae1e722a-d01b-4cdc-ab56-7b68abcdd0fe rhgb stmmaceth=chain_mode:1 selinux=0 LANG=en_US.UTF-8"
+
+global.bootm.oftree=${BOOT}/starfive_vic7100_beagle_v.dtb
+global.bootm.initrd=${BOOT}/initramfs-${VERSION}.img
+global.bootm.image=${BOOT}/vmlinuz-${VERSION}
+global linux.bootargs.root=rootwait
+global linux.bootargs.earlycon=earlycon
+#global.bootm.root_dev=mmc0.1
+#global.bootm.appendroot=1
diff --git a/arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default b/arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default
new file mode 100644
index 000000000000..880a6b1d8cf2
--- /dev/null
+++ b/arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default
@@ -0,0 +1 @@
+buildroot net
diff --git a/arch/riscv/boards/beaglev/lowlevel.c b/arch/riscv/boards/beaglev/lowlevel.c
new file mode 100644
index 000000000000..cccb928bc8e9
--- /dev/null
+++ b/arch/riscv/boards/beaglev/lowlevel.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <debug_ll.h>
+#include <asm/barebox-riscv.h>
+
+ENTRY_FUNCTION(start_beaglev_starlight, a0, a1, a2)
+{
+	extern char __dtb_z_jh7100_beaglev_starlight_start[];
+	void *fdt;
+
+	debug_ll_init();
+	putc_ll('>');
+
+	fdt = __dtb_z_jh7100_beaglev_starlight_start + get_runtime_offset();
+
+	barebox_riscv_supervisor_entry(0x84000000, SZ_512M, a0, fdt);
+}
diff --git a/arch/riscv/configs/starfive_defconfig b/arch/riscv/configs/starfive_defconfig
new file mode 100644
index 000000000000..c4df2256f589
--- /dev/null
+++ b/arch/riscv/configs/starfive_defconfig
@@ -0,0 +1,131 @@
+CONFIG_ARCH_RV64I=y
+CONFIG_SOC_STARFIVE=y
+CONFIG_BOARD_BEAGLEV=y
+CONFIG_BOARD_BEAGLEV_BETA=y
+CONFIG_BOARD_RISCV_GENERIC_DT=y
+CONFIG_RISCV_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_STACK_SIZE=0x20000
+CONFIG_MALLOC_SIZE=0x0
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
+CONFIG_RELOCATABLE=y
+CONFIG_PANIC_HANG=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_BOOTM_INITRD=y
+CONFIG_SYSTEM_PARTITIONS=y
+CONFIG_IMD_TARGET=y
+CONFIG_CONSOLE_ALLOW_COLOR=y
+CONFIG_PBL_CONSOLE=y
+CONFIG_PARTITION_DISK_EFI=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_BAREBOXENV_TARGET=y
+CONFIG_BAREBOXCRC32_TARGET=y
+CONFIG_STATE=y
+CONFIG_STATE_CRYPTO=y
+CONFIG_BOOTCHOOSER=y
+CONFIG_RESET_SOURCE=y
+CONFIG_MACHINE_ID=y
+CONFIG_CMD_DMESG=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_IMD=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_POLLER=y
+CONFIG_CMD_SLICE=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_BOOTCHOOSER=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_CMP=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_MSLEEP=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DETECT=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_POWEROFF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_WD=y
+CONFIG_CMD_2048=y
+CONFIG_CMD_BAREBOX_UPDATE=y
+CONFIG_CMD_OF_DIFF=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_DISPLAY_TIMINGS=y
+CONFIG_CMD_OF_FIXUP_STATUS=y
+CONFIG_CMD_OF_OVERLAY=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_NET=y
+CONFIG_NET_NFS=y
+CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_DRIVER_NET_DESIGNWARE=y
+CONFIG_DRIVER_NET_DESIGNWARE_GENERIC=y
+CONFIG_DRIVER_NET_DESIGNWARE_STARFIVE=y
+CONFIG_MICREL_PHY=y
+CONFIG_SPI_MEM=y
+CONFIG_DRIVER_SPI_GPIO=y
+CONFIG_MCI=y
+CONFIG_MCI_DW=y
+CONFIG_CLOCKSOURCE_DUMMY_RATE=60000
+CONFIG_SRAM=y
+CONFIG_STARFIVE_PWRSEQ=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_LED_GPIO_OF=y
+CONFIG_LED_TRIGGERS=y
+CONFIG_WATCHDOG=y
+CONFIG_STARFIVE_WDT=y
+CONFIG_HWRNG=y
+CONFIG_HW_RANDOM_STARFIVE=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_STARFIVE=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_RMEM=y
+CONFIG_STARFIVE_OTP=y
+CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_NVMEM_REBOOT_MODE=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+# CONFIG_VIRTIO_MENU is not set
+CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
+CONFIG_FS_UIMAGEFS=y
+CONFIG_FS_PSTORE=y
+CONFIG_FS_SQUASHFS=y
+CONFIG_ZLIB=y
+CONFIG_BZLIB=y
+CONFIG_LZ4_DECOMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
+CONFIG_XZ_DECOMPRESS=y
+CONFIG_BASE64=y
+CONFIG_DIGEST_CRC32_GENERIC=y
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index 17fdc9445bd0..4a15423b7fc7 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -7,5 +7,6 @@ obj- += dummy.o
 pbl-$(CONFIG_BOARD_ERIZO_GENERIC) += erizo-generic.dtb.o
 pbl-$(CONFIG_BOARD_HIFIVE) += hifive-unmatched-a00.dtb.o \
                               hifive-unleashed-a00.dtb.o
+pbl-$(CONFIG_BOARD_BEAGLEV) += jh7100-beaglev-starlight.dtb.o
 
 clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts
diff --git a/arch/riscv/dts/jh7100-beaglev-starlight.dts b/arch/riscv/dts/jh7100-beaglev-starlight.dts
new file mode 100644
index 000000000000..8b4c1ac0eaa4
--- /dev/null
+++ b/arch/riscv/dts/jh7100-beaglev-starlight.dts
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/dts-v1/;
+
+#include "jh7100-beaglev-starlight.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	compatible = "beagle,beaglev-starlight-jh7100", "starfive,jh7100";
+	model = "BeagleV Starlight Beta";
+
+	aliases {
+		serial0 = &uart3;
+		serial1 = &uart0;
+	};
+
+	chosen {
+		environment {
+			compatible = "barebox,environment";
+			device-path = &qpsi_env;
+			status = "disabled"; /* QSPI writes don't work yet */
+		};
+	};
+};
+
+&nor_flash {
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "secondboot";
+			reg = <0x0 0x10000>;
+		};
+
+		partition@10000 {
+			label = "ddrinit";
+			reg = <0x10000 0x10000>;
+		};
+
+		partition@20000 {
+			label = "sbi";
+			reg = <0x20000 0x1e0000>;
+		};
+
+		qpsi_env: partition@200000 {
+			label = "environment";
+			reg = <0x200000 0x1e00000>;
+		};
+	};
+};
diff --git a/arch/riscv/dts/jh7100-beaglev-starlight.dtsi b/arch/riscv/dts/jh7100-beaglev-starlight.dtsi
new file mode 100644
index 000000000000..13238f087f16
--- /dev/null
+++ b/arch/riscv/dts/jh7100-beaglev-starlight.dtsi
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "jh7100.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	compatible = "beagle,beaglev-starlight-jh7100", "starfive,jh7100";
+	model = "BeagleV Starlight Beta";
+
+	aliases {
+		serial0 = &uart3;
+		serial1 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200";
+	};
+
+	cpus {
+		timebase-frequency = <6250000>;
+	};
+
+	gpiopof: gpio-poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			label = "beaglev:green:ack";
+			gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x2 0x0>;
+	};
+
+	memory@3000000000 {
+		device_type = "memory";
+		reg = <0x30 0x0 0x0 0x0>;
+	};
+};
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rgmii>;
+	phy-mode = "rgmii-txid";
+	nvmem-cell-names = "mac-address";
+	nvmem-cells = <&ethaddr>;
+};
+
+&gpio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpio>;
+};
+
+&sdio0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdio0>;
+	bus-width = <4>;
+	cap-sd-highspeed;
+	broken-cd;
+	no-sdio;
+	status = "okay";
+};
+
+&sdio1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdio1>;
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart0>;
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&usb3 {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c0>;
+	status = "okay";
+
+	imx219@10 {
+		compatible = "imx219";
+		reg = <0x10>;
+		reset-gpio = <&gpio 58 0>;
+	};
+
+	tps65086@5e {
+		compatible = "ti,tps65086";
+		reg = <0x5e>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	tda998x@70 {
+		compatible = "nxp,tda998x";
+		reg = <0x70>;
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	status = "okay";
+
+	seeed_plane_i2c@45 {
+		compatible = "seeed_panel";
+		reg = <0x45>;
+	};
+};
+
+&qspi {
+	nor_flash: nor-flash@0 {
+		compatible = "spi-flash";
+		reg = <0>;
+		spi-max-frequency = <31250000>;
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		cdns,read-delay = <4>;
+		cdns,tshsl-ns = <1>;
+		cdns,tsd2d-ns = <1>;
+		cdns,tchsh-ns = <1>;
+		cdns,tslch-ns = <1>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <1>;
+	};
+};
+
+&spi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi2>;
+	status = "okay";
+
+	spi_dev0: spi@0 {
+		compatible = "rohm,dh2228fv";
+		spi-max-frequency = <10000000>;
+		reg = <0>;
+		status = "okay";
+	};
+};
+
+&qspi {
+	status = "okay";
+};
+
+&spi2 {
+	status = "okay";
+};
+
+&otp {
+	power-gpios = <&gpio 56 GPIO_ACTIVE_HIGH>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	ethaddr: ethaddr@28 {
+		reg = <0x28 6>;
+		label = "mac-address";
+	};
+};
+
+&gpio {
+	pinctrl_uart0: uart0_pins {
+		pinctrl-single,pins = <
+			0x358 0x2a	/* GPIO40: uart0_pad_sin */
+			0x194 0x1	/* GPIO40: doen_HIGH */
+			0x198 0x7f	/* GPIO41: dout_uart0_pad_sout */
+			0x19c 0x0	/* GPIO41: doen_LOW */
+			0x1a0 0x7e	/* GPIO42: dout_uart0_pad_rtsn */
+			0x1a4 0x0	/* GPIO42: doen_LOW */
+			0x348 0x29	/* GPIO39: uart0_pad_ctsn */
+			0x18c 0x1	/* GPIO39: doen_HIGH */
+			0x16c 0x0	/* GPIO35: doen_LOW */
+			0x168 0x1	/* GPIO35: dout_HIGH */
+		>;
+	};
+
+	pinctrl_i2c0: i2c0_pins {
+		pinctrl-single,pins = <
+			0x240 0x0		/* GPIO62: dout_LOW */
+			0x238 0x0		/* GPIO61: dout_LOW */
+			0x244 0x80000008	/* GPIO62: doen_i2c0_pad_sck_oe
+							   doen_reverse_(1) */
+			0x23c 0x80000009	/* GPIO61: doen_i2c0_pad_sda_oe
+							   doen_reverse_(1) */
+			0x278 0x40		/* GPIO62: i2c0_pad_sck_in */
+			0x27c 0x3f		/* GPIO61: i2c0_pad_sda_in */
+		>;
+	};
+
+	pinctrl_i2c1: i2c1_pins {
+		pinctrl-single,pins = <
+			0x1c8 0x0		/* GPIO47: dout_LOW */
+			0x1d0 0x0		/* GPIO48: dout_LOW */
+			0x1cc 0x8000000a	/* GPIO47: doen_i2c1_pad_sck_oe
+							   doen_reverse_(1) */
+			0x1d4 0x8000000b	/* GPIO48: doen_i2c1_pad_sda_oe
+							   doen_reverse_(1) */
+			0x280 0x31		/* GPIO47: i2c1_pad_sck_in */
+			0x284 0x32		/* GPIO48: i2c1_pad_sda_in */
+		>;
+	};
+
+	pinctrl_i2c2: i2c2_pins {
+		pinctrl-single,pins = <
+			0x230 0x0		/* GPIO60: dout_LOW */
+			0x228 0x0		/* GPIO59: dout_LOW */
+			0x234 0x8000000c	/* GPIO60: doen_i2c2_pad_sck_oe
+							   doen_reverse_(1) */
+			0x22c 0x8000000d	/* GPIO59: doen_i2c2_pad_sda_oe
+							   doen_reverse_(1) */
+			0x288 0x3e		/* GPIO60: i2c2_pad_sck_in */
+			0x28c 0x3d		/* GPIO59: i2c2_pad_sda_in */
+		>;
+	};
+
+	pinctrl_spi2: spi2_pins {
+		pinctrl-single,pins = <
+			/* MISO */
+			0xa8  0x6f	/* GPIO11: dout_spi2_pad_txd */
+			0xac  0x0	/* GPIO11: doen_LOW */
+			/* MOSI */
+			0x320 0xe	/* GPIO12: spi2_pad_rxd */
+			0xb4  0x1	/* GPIO12: doen_HIGH */
+			/* SCLK */
+			0xe0  0x6c	/* GPIO18: dout_spi2_pad_sck_out */
+			0xe4  0x0	/* GPIO18: doen_LOW */
+			/* CS */
+			0xe8  0x6d	/* GPIO19: dout_spi2_pad_ss_0_n */
+			0xec  0x0	/* GPIO19: doen_LOW */
+		>;
+
+	};
+
+	pinctrl_sdio0: sdio0_pins {
+		pinctrl-single,pins = <
+			0x2b4 0x39		/* GPIO55: sdio0_pad_card_detect_n */
+			0x20c 0x1		/* GPIO55: doen_HIGH */
+			0x200 0x36		/* GPIO54: dout_sdio0_pad_cclk_out */
+			0x204 0x0		/* GPIO54: doen_LOW */
+			0x1fc 0x80000037	/* GPIO53: doen_sdio0_pad_ccmd_oe
+							   doen_reverse_(1) */
+			0x1f8 0x38		/* GPIO53: dout_sdio0_pad_ccmd_out */
+			0x2bc 0x37		/* GPIO53: _sdio0_pad_ccmd_in */
+			0x1dc 0x80000039	/* GPIO49: doen_sdio0_pad_cdata_oe_bit0
+							   doen_reverse_(1) */
+			0x1d8 0x41		/* GPIO49: dout_sdio0_pad_cdata_out_bit0 */
+			0x2c0 0x33		/* GPIO49: sdio0_pad_cdata_in_bit0 */
+			0x1e4 0x8000003a	/* GPIO50: doen_sdio0_pad_cdata_oe_bit1
+							   doen_reverse_(1) */
+			0x1e0 0x42		/* GPIO50: dout_sdio0_pad_cdata_out_bit1 */
+			0x2c4 0x34		/* GPIO50: sdio0_pad_cdata_in_bit1 */
+			0x1ec 0x8000003b	/* GPIO51: doen_sdio0_pad_cdata_oe_bit2
+							   doen_reverse_(1) */
+			0x1e8 0x43		/* GPIO51: dout_sdio0_pad_cdata_out_bit2 */
+			0x2c8 0x35		/* GPIO51: sdio0_pad_cdata_in_bit2 */
+			0x1f4 0x8000003c	/* GPIO52: doen_sdio0_pad_cdata_oe_bit3
+							   doen_reverse_(1) */
+			0x1f0 0x44		/* GPIO52: dout_sdio0_pad_cdata_out_bit3 */
+			0x2cc 0x36		/* GPIO52: sdio0_pad_cdata_in_bit3(52) */
+		>;
+	};
+
+	pinctrl_sdio1: sdio1_pins {
+		pinctrl-single,pins = <
+			0x158 0x4b		/* GPIO33: dout_sdio1_pad_cclk_out */
+			0x15c 0x0		/* GPIO33: doen_LOW */
+			0x13c 0x8000004c	/* GPIO29: doen_sdio1_pad_ccmd_oe
+							   doen_reverse_(1) */
+			0x138 0x4d		/* GPIO29: dout_sdio1_pad_ccmd_out */
+			0x2e8 0x1f		/* GPIO29: sdio1_pad_ccmd_in */
+			0x174 0x8000004e	/* GPIO36: doen_sdio1_pad_cdata_oe_bit0
+							   doen_reverse_(1) */
+			0x170 0x56		/* GPIO36: dout_sdio1_pad_cdata_out_bit0 */
+			0x2ec 0x26		/* GPIO36: sdio1_pad_cdata_in_bit0 */
+			0x144 0x8000004f	/* GPIO30: doen_sdio1_pad_cdata_oe_bit1
+							   doen_reverse_(1) */
+			0x140 0x57		/* GPIO30: dout_sdio1_pad_cdata_out_bit1 */
+			0x2f0 0x20		/* GPIO30: sdio1_pad_cdata_in_bit1 */
+			0x164 0x80000050	/* GPIO34: doen_sdio1_pad_cdata_oe_bit2
+							   doen_reverse_(1) */
+			0x160 0x58		/* GPIO34: dout_sdio1_pad_cdata_out_bit2 */
+			0x2f4 0x24		/* GPIO34: sdio1_pad_cdata_in_bit2 */
+			0x14c 0x80000051	/* GPIO31: doen_sdio1_pad_cdata_oe_bit3
+							   doen_reverse_(1) */
+			0x148 0x59		/* GPIO31: dout_sdio1_pad_cdata_out_bit3 */
+			0x2f8 0x21		/* GPIO31: sdio1_pad_cdata_in_bit3 */
+		>;
+	};
+};
+
+&pinconf {
+	pinctrl_rgmii: rgmii_pins {
+		pinctrl-single,pins = <
+			0x164	0xC30080
+			0x168	0x30080
+
+			0x16c	0x30003
+			0x170	0x30003
+			0x174	0x30003
+			0x178	0x30003
+
+			0x17c	0xC800003
+
+			0x180	0x8000C0
+			0x184	0xC000C0
+			0x188	0xC000C0
+			0x18c	0xC000C0
+			0x190	0xC000C0
+			0x194	0xC000C0
+			0x198	0xC000C0
+		>;
+	};
+
+	/* Force most pins to input. Taken from vendor's sys_funcshare_io_input_en */
+	pinctrl_gpio: gpio_pins {
+		pinctrl-single,pins = <
+			0x80 0xc000c0 /* gpio0     */
+			0x90 0xc000c0 /* gpio8-9   */
+			0x94 0xc000c0 /* gpio10-11 */
+			0x98 0xc000c0 /* gpio12    */
+			0xa0 0xc000c0 /* gpio16-17 */
+			0xa4 0xc000c0 /* gpio18-19 */
+			0xa8 0xc000c0 /* gpio20-21 */
+			0xac 0xc000c0 /* gpio22-23 */
+			0xb0 0xc000c0 /* gpio24-25 */
+			0xb4 0xc000c0 /* gpio26-27 */
+			0xb8 0xc000c0 /* gpio28-29 */
+			0xbc 0xc000c0 /* gpio30-31 */
+			0xc0 0xc000c0 /* gpio32-33 */
+			0xc4 0xc000c0 /* gpio34-35 */
+			0xcc 0xc000c0 /* gpio38-39 */
+			0xd0 0xc000c0 /* gpio40-41 */
+			0xd4 0xc000c0 /* gpio42-43 */
+			0xd8 0xc000c0 /* gpio44-45 */
+			0xdc 0xc000c0 /* gpio46-47 */
+			0xe0 0xc000c0 /* gpio48-49 */
+			0xe4 0xc000c0 /* gpio50-51 */
+			0xe8 0xc000c0 /* gpio52-53 */
+			0xec 0xc000c0 /* gpio54-55 */
+			0xf0 0xc000c0 /* gpio56-57 */
+			0xf4 0xc000c0 /* gpio58-59 */
+			0xf8 0xc000c0 /* gpio60-61 */
+			0xfc 0xc000c0 /* gpio62-63 */
+		>;
+	};
+};
diff --git a/arch/riscv/dts/jh7100.dtsi b/arch/riscv/dts/jh7100.dtsi
new file mode 100644
index 000000000000..e3990582af97
--- /dev/null
+++ b/arch/riscv/dts/jh7100.dtsi
@@ -0,0 +1,798 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dt-bindings/reset-controller/starfive-jh7100.h>
+#include <dt-bindings/clock/starfive-jh7100.h>
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	compatible = "starfive,jh7100";
+
+	aliases {
+		spi0 = &qspi;
+		mmc0 = &sdio0;
+		mmc1 = &sdio1;
+		usb0 = &usb3;
+	};
+
+	chosen {
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu@0 {
+			compatible = "sifive,u74-mc", "riscv";
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <32>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <32>;
+			mmu-type = "riscv,sv39";
+			next-level-cache = <&ccache>;
+			reg = <0>;
+			riscv,isa = "rv64imafdc";
+			starfive,itim = <&itim0>;
+			status = "okay";
+			tlb-split;
+			cpu0_intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+
+		cpu@1 {
+			compatible = "sifive,u74-mc", "riscv";
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <32768>;
+			d-tlb-sets = <1>;
+			d-tlb-size = <32>;
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <32768>;
+			i-tlb-sets = <1>;
+			i-tlb-size = <32>;
+			mmu-type = "riscv,sv39";
+			next-level-cache = <&ccache>;
+			reg = <1>;
+			riscv,isa = "rv64imafdc";
+			starfive,itim = <&itim1>;
+			status = "okay";
+			tlb-split;
+			cpu1_intc: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+	};
+
+	osc_sys: clock-osc-sys {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+		clock-output-names = "osc_sys";
+	};
+
+	osc_aud: clock-osc-audio {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <27000000>;
+		clock-output-names = "osc_aud";
+	};
+
+	i2c0clk: i2c0clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <49500000>;
+		clock-output-names = "i2c0clk";
+	};
+
+	i2c2clk: i2c2clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <49500000>;
+		clock-output-names = "i2c2clk";
+	};
+
+	axiclk: axiclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <500000000>;
+		clock-output-names = "axiclk";
+	};
+
+	ahb0clk: ahb0clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <250000000>;
+	};
+
+	apb1clk: apb1clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+	};
+
+	apb2clk: apb2clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+	};
+
+	jpuclk: jpuclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <333333333>;
+	};
+
+	vpuclk: vpuclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <400000000>;
+	};
+
+	qspi_clk: qspi-clk@0 {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <50000000>;
+	};
+
+	uartclk: uartclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <100000000>;
+	};
+
+	hs_uartclk: hs_uartclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <74250000>;
+	};
+
+	spiclk: spiclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <50000000>;
+	};
+
+	pwmclk: pwmclk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x0 0x28000000>;
+			alignment = <0x0 0x1000>;
+			alloc-ranges = <0x0 0xa0000000 0x0 0x28000000>;
+			linux,cma-default;
+		};
+
+		jpu_reserved: framebuffer@c9000000 {
+			reg = <0x0 0xc9000000 0x0 0x4000000>;
+		};
+
+		nvdla_reserved:framebuffer@d0000000 {
+			reg = <0x0 0xd0000000 0x0 0x28000000>;
+		};
+
+		vin_reserved: framebuffer@f9000000 {
+			compatible = "shared-dma-pool";
+			no-map;
+			reg = <0x0 0xf9000000 0x0 0x1000000>;
+		};
+
+		sffb_reserved: framebuffer@fb000000 {
+			compatible = "shared-dma-pool";
+			no-map;
+			reg = <0x0 0xfb000000 0x0 0x2000000>;
+		};
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		#clock-cells = <1>;
+		compatible = "simple-bus";
+		ranges;
+
+		intram0: sram@18000000 {
+			compatible = "mmio-sram";
+			reg = <0x0 0x18000000 0x0 0x20000>;
+		};
+
+		intram1: sram@18080000 {
+			compatible = "mmio-sram";
+			reg = <0x0 0x18080000 0x0 0x8000>;
+		};
+
+		ccache: cache-controller@2010000 {
+			cache-block-size = <64>;
+			cache-level = <2>;
+			cache-sets = <2048>;
+			cache-size = <2097152>;
+			cache-unified;
+			compatible = "sifive,fu540-c000-ccache", "starfive,ccache0", "cache";
+			interrupt-parent = <&plic>;
+			interrupts = <128 131 129 130>;
+			/*next-level-cache = <&L40 &L36>;*/
+			reg = <0x0 0x2010000 0x0 0x1000 0x0 0x8000000 0x0 0x2000000>;
+			reg-names = "control", "sideband";
+		};
+
+		dtim: dtim@1000000 {
+			compatible = "starfive,dtim0";
+			reg = <0x0 0x1000000 0x0 0x2000>;
+			reg-names = "mem";
+		};
+
+		itim0: itim@1808000 {
+			compatible = "starfive,itim0";
+			reg = <0x0 0x1808000 0x0 0x8000>;
+			reg-names = "mem";
+		};
+
+		itim1: itim@1820000 {
+			compatible = "starfive,itim0";
+			reg = <0x0 0x1820000 0x0 0x8000>;
+			reg-names = "mem";
+		};
+
+		clint: clint@2000000 {
+			#interrupt-cells = <1>;
+			compatible = "riscv,clint0";
+			interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 &cpu1_intc 3 &cpu1_intc 7>;
+			reg = <0x0 0x2000000 0x0 0x10000>;
+			reg-names = "control";
+		};
+
+		plic: plic@c000000 {
+			#interrupt-cells = <1>;
+			compatible = "riscv,plic0";
+			interrupt-controller;
+			interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9 &cpu1_intc 11 &cpu1_intc 9>;
+			reg = <0x0 0xc000000 0x0 0x4000000>;
+			reg-names = "control";
+			riscv,max-priority = <7>;
+			riscv,ndev = <127>;
+		};
+
+		sysmain: syscon@11850000 {
+			compatible = "syscon";
+			reg = <0x0 0x11850000 0x0 0x4000>;
+		};
+
+		pinconf: pinctrl@11858000 {
+			compatible = "pinctrl-single";
+			reg = <0x0 0x11858000 0x0 0x4000>;
+			#pinctrl-cells = <1>;
+			pinctrl-single,register-width = <32>;
+			pinctrl-single,function-mask = <0xffffffff>;
+		};
+
+		uart0: hs_serial@11870000 {
+			compatible = "snps,dw-apb-uart";
+			interrupt-parent = <&plic>;
+			interrupts = <92>;
+			reg = <0x0 0x11870000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&hs_uartclk>, <&apb1clk>;
+			clock-names = "baudclk", "apb_pclk";
+			current-clock = <74250000>;
+			current-speed = <115200>;
+			status = "disabled";
+		};
+
+		uart1: hs_serial@11880000 {
+			compatible = "snps,dw-apb-uart";
+			interrupt-parent = <&plic>;
+			interrupts = <93>;
+			reg = <0x0 0x11880000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&hs_uartclk>, <&apb1clk>;
+			clock-names = "baudclk", "apb_pclk";
+			current-clock = <74250000>;
+			current-speed = <115200>;
+			status = "disabled";
+		};
+
+		uart2: serial@12430000 {
+			compatible = "snps,dw-apb-uart";
+			interrupt-parent = <&plic>;
+			interrupts = <72>;
+			reg = <0x0 0x12430000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&uartclk>, <&apb2clk>;
+			clock-names = "baudclk", "apb_pclk";
+			current-clock = <100000000>;
+			current-speed = <115200>;
+			status = "disabled";
+		};
+
+		uart3: serial@12440000 {
+			compatible = "snps,dw-apb-uart", "starfive,uart0";
+			interrupt-parent = <&plic>;
+			interrupts = <73>;
+			reg = <0x0 0x12440000 0x0 0x10000>;
+			reg-io-width = <4>;
+			reg-shift = <2>;
+			clocks = <&uartclk>, <&apb2clk>;
+			clock-names = "baudclk", "apb_pclk";
+			current-clock = <100000000>;
+			current-speed = <115200>;
+			status = "disabled";
+		};
+
+		nne50: nne@10800000 {
+			compatible = "starfive,nne50";
+			reg = <0x0 0x10800000 0x0 0x10000>;
+			resets = <&rstgen RSTN_DLA_AXI>,
+				<&rstgen RSTN_DLANOC_AXI>,
+				<&rstgen RSTN_DLA_APB>,
+				<&rstgen RSTN_NNENOC_AXI>,
+				<&rstgen RSTN_DLASLV_AXI>;
+
+			assigned-clocks = <&clkgen CLK_NNE_BUS>;
+			assigned-clocks-parents = <&clkgen CLK_CPU_AXI>;
+			status = "okay";
+		};
+
+		dma2p: sgdma2p@100b0000 {
+			compatible = "starfive,axi-dma", "snps,axi-dma-1.01a";
+			reg = <0x0 0x100b0000 0x0 0x10000>;
+			clocks = <&axiclk>, <&ahb0clk>;
+			clock-names = "core-clk", "cfgr-clk";
+			resets = <&rstgen RSTN_DMA2PNOC_AXI>, <&rstgen RSTN_SGDMA2P_AXI>, <&rstgen RSTN_SGDMA2P_AHB>;
+			reset-names = "noc", "axi", "ahb";
+			interrupt-parent = <&plic>;
+			interrupts = <2>;
+			dma-channels = <4>;
+			snps,dma-masters = <1>;
+			snps,data-width = <4>;
+			snps,block-size = <4096 4096 4096 4096>;
+			snps,priority = <0 1 2 3>;
+			snps,axi-max-burst-len = <128>;
+			status = "okay";
+		};
+
+		dma1p: sgdma1p@10500000 {
+			compatible = "starfive,axi-dma", "snps,axi-dma-1.01a";
+			reg = <0x0 0x10500000 0x0 0x10000>;
+			clocks = <&axiclk>, <&ahb0clk>;
+			clock-names = "core-clk", "cfgr-clk";
+			resets = <&rstgen RSTN_SGDMA1P_AXI>;
+			interrupt-parent = <&plic>;
+			interrupts = <1>;
+			dma-channels = <16>;
+			snps,dma-masters = <1>;
+			snps,data-width = <3>;
+			snps,block-size = <4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096>;
+			snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
+			snps,axi-max-burst-len = <64>;
+			status = "okay";
+		};
+
+		usb3: usb@104c0000 {
+			compatible = "cdns,usb3";
+			reg = <0x0 0x104c0000 0x0 0x10000>,	// memory area for HOST registers
+			      <0x0 0x104d0000 0x0 0x10000>,	// memory area for DEVICE registers
+			      <0x0 0x104e0000 0x0 0x10000>;	// memory area for OTG/DRD registers
+			reg-names = "otg", "xhci", "dev";
+			interrupt-parent = <&plic>;
+			interrupts = <43>, <44>, <52>;
+			interrupt-names = "otg",
+					"host",
+					"peripheral";
+			phy-names = "cdns3,usb3-phy", "cdns3,usb2-phy";
+			maximum-speed = "super-speed";
+			status = "disabled";
+		};
+
+		gpio: gpio@11910000 {
+			compatible = "starfive,gpio0";
+			interrupt-parent = <&plic>;
+			interrupts = <32>;
+			resets = <&rstgen RSTN_GPIO_APB>;
+			clocks = <&clkgen CLK_GPIO_APB>;
+			reg = <0x0 0x11910000 0x0 0x10000>;
+			reg-names = "control";
+			interrupt-controller;
+			#gpio-cells = <2>;
+			#pinctrl-cells = <1>;
+			pinctrl-single,register-width = <32>;
+			pinctrl-single,function-mask = <0xffffffff>;
+		};
+
+		i2c0: i2c@118b0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			#clock-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0x0 0x118b0000 0x0 0x10000>;
+			interrupt-parent = <&plic>;
+			interrupts = <96>;
+			clocks = <&i2c0clk>;
+			clock-frequency = <100000>;
+			i2c-sda-hold-time-ns = <300>;
+			i2c-sda-falling-time-ns = <500>;
+			i2c-scl-falling-time-ns = <500>;
+			scl-gpio = <&gpio 62 0>;
+			sda-gpio = <&gpio 61 0>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@118c0000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			#clock-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0x0 0x118c0000 0x0 0x10000>;
+			interrupt-parent = <&plic>;
+			interrupts = <97>;
+			clocks = <&i2c0clk>;
+			clock-frequency = <400000>;
+			i2c-sda-hold-time-ns = <300>;
+			i2c-sda-falling-time-ns = <100>;
+			i2c-scl-falling-time-ns = <100>;
+			scl-gpio = <&gpio 47 0>;
+			sda-gpio = <&gpio 48 0>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@12450000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			#clock-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0x0 0x12450000 0x0 0x10000>;
+			interrupt-parent = <&plic>;
+			interrupts = <74>;
+			clocks = <&i2c2clk>;
+			clock-frequency = <100000>;
+			i2c-sda-hold-time-ns = <300>;
+			i2c-sda-falling-time-ns = <500>;
+			i2c-scl-falling-time-ns = <500>;
+			scl-gpio = <&gpio 60 0>;
+			sda-gpio = <&gpio 59 0>;
+			status = "disabled";
+		};
+
+		trng: trng@118d0000 {
+			compatible = "starfive,vic-rng";
+			reg = <0x0 0x118d0000 0x0 0x10000>;
+			interrupt-parent = <&plic>;
+			interrupts = <98>;
+			clocks = <&clkgen CLK_TRNG_APB>;
+			resets = <&rstgen RSTN_TRNG_APB>;
+		};
+
+		crypto: crypto@100d0000 {
+			compatible = "starfive,vic-sec";
+			reg = <0x0 0x100d0000 0x0 0x20000>,
+			      <0x0 0x11800234 0x0 0xc>;
+			reg-names = "secmem", "secclk";
+			resets = <&rstgen RSTN_SEC_AHB>, <&rstgen RSTN_AES>,
+			    <&rstgen RSTN_PKA>, <&rstgen RSTN_SHA>;
+			interrupt-parent = <&plic>;
+			interrupts = <31>;
+			clocks = <&osc_sys>;
+		};
+
+		/* gmac device configuration */
+		stmmac_axi_setup: stmmac-axi-config {
+			snps,wr_osr_lmt = <0xf>;
+			snps,rd_osr_lmt = <0xf>;
+			snps,blen = <256 128 64 32 0 0 0>;
+		};
+
+		gmac: gmac@10020000 {
+			compatible = "starfive,stmmac";
+			reg = <0x0 0x10020000 0x0 0x10000>;
+			interrupt-parent = <&plic>;
+			interrupts = <6 7>;
+			interrupt-names = "macirq", "eth_wake_irq";
+			resets = <&rstgen RSTN_GMAC_AHB>;
+			reset-names = "stmmaceth";
+			clocks = <&clkgen CLK_GMAC_AHB>, <&clkgen CLK_GMAC_PTP_REF>,
+				 <&clkgen CLK_GMAC_GTX>;
+			clock-names = "stmmaceth", "ptp_ref", "tx";
+			max-frame-size = <9000>;
+			snps,multicast-filter-bins = <256>;
+			snps,perfect-filter-entries = <128>;
+			rx-fifo-depth = <32768>;
+			tx-fifo-depth = <16384>;
+			snps,fixed-burst = <1>;
+			snps,no-pbl-x8 = <1>;
+			/*snps,force_sf_dma_mode;*/
+			snps,force_thresh_dma_mode;
+			snps,axi-config = <&stmmac_axi_setup>;
+			starfive,sysmain = <&sysmain>;
+		};
+
+		nbdla: nvdla@11940000 {
+			compatible = "nvidia,nvdla_os_initial";
+			interrupt-parent = <&plic>;
+			resets = <&rstgen RSTN_DLA_AXI>,
+				<&rstgen RSTN_DLANOC_AXI>,
+				<&rstgen RSTN_DLA_APB>,
+				<&rstgen RSTN_NNENOC_AXI>,
+				<&rstgen RSTN_DLASLV_AXI>;
+			interrupts = <22>;
+			memory-region = <&nvdla_reserved>;
+			reg = <0x0 0x11940000 0x0 0x40000>;
+			status = "okay";
+		};
+
+		jpu: coadj12@11900000 {
+			compatible = "cm,codaj12-jpu-1";
+			reg = <0x0 0x11900000 0x0 0x300>;
+			memory-region = <&jpu_reserved>;
+			interrupt-parent = <&plic>;
+			interrupts = <24>;
+			clocks = <&jpuclk>;
+			clock-names = "jpege";
+			reg-names = "control";
+			resets = <&rstgen RSTN_JPEG_AXI>, <&rstgen RSTN_JPEG_CCLK>,
+			       <&rstgen RSTN_JPEG_APB>;
+			status = "okay";
+		};
+
+		clkgen: clock-controller@11800000 {
+			compatible = "starfive,jh7100-clkgen";
+			reg = <0x0 0x11800000 0x0 0x10000>;
+			clocks = <&osc_sys>, <&osc_aud>;
+			clock-names = "osc_sys", "osc_aud";
+			#clock-cells = <1>;
+		};
+
+		vpu_dec: vpu_dec@118f0000 {
+			compatible = "cm,cm511-vpu";
+			reg = <0 0x118f0000 0 0x10000>;
+			//memory-region = <&vpu_reserved>;
+			interrupt-parent = <&plic>;
+			interrupts = <23>;
+			clocks = <&vpuclk>;
+			clock-names = "vcodec";
+			resets = <&rstgen RSTN_VDEC_AXI>, <&rstgen RSTN_VDECBRG_MAIN>,
+			    <&rstgen RSTN_VDEC_BCLK>, <&rstgen RSTN_VDEC_CCLK>,
+			    <&rstgen RSTN_VDEC_APB>;
+			status = "okay";
+		};
+
+		vpu_enc: vpu_enc@118e0000 {
+			compatible = "cm,cm521-vpu";
+			reg = <0x0 0x118e0000 0x0 0x4000>;
+			interrupt-parent = <&plic>;
+			interrupts = <26>;
+			clocks = <&vpuclk>;
+			clock-names = "vcodec";
+			resets = <&rstgen RSTN_VENC_AXI>, <&rstgen RSTN_VENCBRG_MAIN>,
+			    <&rstgen RSTN_VENC_BCLK>, <&rstgen RSTN_VENC_CCLK>,
+			    <&rstgen RSTN_VENC_APB>;
+			reg-names = "control";
+		};
+
+		wdt: watchdogm@12480000 {
+			compatible = "starfive,wdt";
+			reg = <0x0 0x12480000 0x0 0x10000>;
+			clocks = <&clkgen CLK_WDTIMER_APB>,<&clkgen CLK_WDT_CORE>;
+			clock-names = "bus", "core";
+			resets = <&rstgen RSTN_WDTIMER_APB>, <&rstgen RSTN_WDT>;
+			reset-names = "bus", "core";
+		};
+
+		ptc: pwm@12490000 {
+			compatible = "starfive,pwm0";
+			reg = <0x0 0x12490000 0x0 0x10000>;
+			reg-names = "control";
+			sifive,approx-period = <100000000>;
+			clocks = <&pwmclk>;
+			#pwm-cells = <3>;
+			sifive,npwm = <8>;
+
+		};
+
+		rstgen: reset-controller@11840000 {
+			compatible = "starfive,jh7100-rstgen";
+			reg = <0x0 0x11840000 0x0 0x10000>;
+			#reset-cells = <1>;
+		};
+
+		spi2ahb {
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			compatible = "starfive,spi2ahb";
+			resets = <&rstgen RSTN_SPI2AHB_AHB>, <&rstgen RSTN_SPI2AHB_CORE>;
+
+			qspi: spi@11860000 {
+				compatible = "cadence,qspi", "cdns,qspi-nor";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x0 0x11860000 0x0 0x10000 0x0 0x20000000 0x0 0x20000000>;
+				interrupts = <3>;
+				interrupt-parent = <&plic>;
+				clocks = <&qspi_clk>;
+				cdns,fifo-depth = <256>;
+				cdns,fifo-width = <4>;
+				cdns,trigger-address = <0x00000000>;
+				status = "disabled";
+				spi-max-frequency = <250000000>;
+			};
+
+			spi2: spi@12410000 {
+				compatible = "snps,dw-apb-ssi";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupt-parent = <&plic>;
+				interrupts = <70>;
+				reg = <0x0 0x12410000 0x0 0x10000>;
+				clocks = <&spiclk>;
+				status = "disabled";
+				/*
+				num-cs = <1>;
+				cs-gpios = <&gpio 0 0>;
+				*/
+			};
+		};
+
+		xrp@f0000000 {
+			compatible = "cdns,xrp";
+			reg = <0x0  0xf0000000 0x0 0x01ffffff
+			       0x10 0x72000000 0x0 0x00001000
+			       0x10 0x72001000 0x0 0x00fff000
+			       0x0  0x124b0000 0x0 0x00010000>;
+			clocks = <&osc_sys>;
+			interrupt-parent = <&plic>;
+			firmware-name = "vp6_elf";
+			resets = <&rstgen RSTN_VP6INTC_APB>;
+			dsp-irq = <19 20>;
+			dsp-irq-src = <0x20 0x21>;
+			intc-irq-mode = <1>;
+			intc-irq = <0 1>;
+			interrupts = <27 28>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x40000000 0x0  0x40000000 0x01000000
+			          0xb0000000 0x10 0x70000000 0x3000000>;
+			dsp@0 {
+			};
+		};
+
+		sdio0: sdio0@10000000 {
+			compatible = "starfive,jh7100-dw-mshc", "snps,dw-mshc";
+			reg = <0x0 0x10000000 0x0 0x10000>;
+			interrupts = <4>;
+			interrupt-parent = <&plic>;
+			clocks = <&clkgen CLK_SDIO0_AHB>, <&clkgen CLK_SDIO0_CCLKINT>;
+			clock-names = "biu", "ciu";
+			resets = <&rstgen RSTN_SDIO0_AHB>;
+			reset-names = "reset";
+			clock-frequency = <100000000>;
+			max-frequency = <10000000>;
+			fifo-depth = <32>;
+			card-detect-delay = <300>;
+			fifo-watermark-aligned;
+			data-addr = <0>;
+			post-power-on-delay-ms = <200>;
+			status = "disabled";
+		};
+
+		sdio1: sdio1@10010000 {
+			compatible = "starfive,jh7100-dw-mshc", "snps,dw-mshc";
+			reg = <0x0 0x10010000 0x0 0x10000>;
+			interrupts = <5>;
+			interrupt-parent = <&plic>;
+			clocks = <&clkgen CLK_SDIO1_AHB>, <&clkgen CLK_SDIO1_CCLKINT>;
+			clock-names = "biu", "ciu";
+			resets = <&rstgen RSTN_SDIO1_AHB>;
+			reset-names = "reset";
+			clock-frequency = <100000000>;
+			max-frequency = <10000000>;
+			fifo-depth = <32>;
+			card-detect-delay = <300>;
+			fifo-watermark-aligned;
+			data-addr = <0>;
+			bus-width = <4>;
+			cap-sd-highspeed;
+			cap-sdio-irq;
+			cap-mmc-hw-reset;
+			enable-sdio-wakeup;
+			keep-power-in-suspend;
+			cap-mmc-highspeed;
+			post-power-on-delay-ms = <200>;
+			status = "disabled";
+		};
+
+		sfivefb: sfivefb@12000000 {
+			compatible = "starfive,vpp-lcdc";
+			interrupt-parent = <&plic>;
+			interrupts = <101>, <103>;
+			interrupt-names = "lcdc_irq", "vpp1_irq";
+			reg = <0x0 0x12000000 0x0 0x10000>,
+				<0x0 0x12100000 0x0 0x10000>,
+				<0x0 0x12040000 0x0 0x10000>,
+				<0x0 0x12080000 0x0 0x10000>,
+				<0x0 0x120c0000 0x0 0x10000>,
+				<0x0 0x12240000 0x0 0x10000>,
+				<0x0 0x12250000 0x0 0x10000>,
+				<0x0 0x12260000 0x0 0x10000>;
+			reg-names = "lcdc", "dsitx", "vpp0", "vpp1", "vpp2", "clk", "rst", "sys";
+			memory-region = <&sffb_reserved>;
+			clocks = <&uartclk>, <&apb2clk>;
+			clock-names = "baudclk", "apb_pclk";
+			status = "okay";
+			ddr-format = <4>;/* LCDC win_format WIN_FMT_RGB565 */
+		};
+
+		vin_sysctl: vin_sysctl@19800000 {
+			compatible = "starfive,stf-vin";
+			reg = <0x0 0x19800000 0x0 0x10000>,
+			      <0x0 0x19810000 0x0 0x10000>,
+			      <0x0 0x19820000 0x0 0x10000>,
+			      <0x0 0x19830000 0x0 0x10000>,
+			      <0x0 0x19840000 0x0 0x10000>,
+			      <0x0 0x19870000 0x0 0x30000>,
+			      <0x0 0x198a0000 0x0 0x30000>,
+			      <0x0 0x11800000 0x0 0x10000>,
+			      <0x0 0x11840000 0x0 0x10000>,
+			      <0x0 0x11858000 0x0 0x10000>;
+			reg-names = "mipi0", "vclk", "vrst", "mipi1", "sctrl",
+			            "isp0", "isp1", "tclk", "trst", "iopad";
+			interrupt-parent = <&plic>;
+			interrupts = <119 109>;
+			memory-region = <&vin_reserved>;
+			/*defaule config for imx219 vin&isp*/
+			format = <3>; /* SRC_CSI2RX_VIN_ISP */
+			frame-width = <800>;
+			frame-height =<480>;
+			isp0_enable;
+			csi-lane = <2>;
+			csi-dlane-swaps = /bits/ 8 <1>,/bits/ 8 <2>,/bits/ 8 <3>,/bits/ 8 <4>;
+			csi-dlane-pn-swaps = /bits/ 8 <0>,/bits/ 8 <0>,/bits/ 8 <0>,/bits/ 8 <0>;
+			csi-clane-swap = /bits/ 8 <0>;
+			csi-clane-pn-swap = /bits/ 8 <0>;
+			csi-mipiID = <0>;
+			csi-width = <1920>;
+			csi-height = <1080>;
+			csi-dt = <0x2b>;
+		};
+
+		sfc_tmp: tmpsensor@124a0000 {
+			compatible = "sfc,tempsensor";
+			reg = <0x0 0x124a0000 0x0 0x1000>;
+			interrupt-parent = <&plic>;
+			interrupts = <122>;
+			resets = <&rstgen RSTN_TEMP_APB>, <&rstgen RSTN_TEMP_SENSE>;
+			status = "okay";
+		};
+
+		otp: otp@11810000 {
+			compatible = "starfive,fu740-otp";
+			reg = <0x0 0x11810000 0x0 0x10000>;
+			fuse-count = <0x200>;
+			resets = <&rstgen RSTN_OTP_APB>;
+			clocks = <&clkgen CLK_OTP_APB>;
+		};
+	};
+};
diff --git a/arch/riscv/include/asm/debug_ll.h b/arch/riscv/include/asm/debug_ll.h
index 13609d25c559..b4caa0597a2d 100644
--- a/arch/riscv/include/asm/debug_ll.h
+++ b/arch/riscv/include/asm/debug_ll.h
@@ -17,6 +17,9 @@
 #if defined CONFIG_DEBUG_ERIZO
 #define DEBUG_LL_UART_ADDR	0x90000000
 #define DEBUG_LL_UART_CLK       (24000000 / 16)
+#elif defined CONFIG_DEBUG_STARFIVE
+#define DEBUG_LL_UART_ADDR	0x12440000
+#define DEBUG_LL_UART_CLK       (100000000 / 16)
 #endif
 
 #define DEBUG_LL_UART_SHIFT	2
diff --git a/common/Kconfig b/common/Kconfig
index 98be9b58abce..d4e518bf8ade 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1378,6 +1378,11 @@ config DEBUG_ERIZO
 	depends on SOC_ERIZO
 	select DEBUG_LL_NS16550
 
+config DEBUG_STARFIVE
+	bool "Starfive ns16550 serial0 port"
+	depends on SOC_STARFIVE
+	select DEBUG_LL_NS16550
+
 config DEBUG_SIFIVE
 	bool "SiFive serial0 port"
 	depends on SOC_SIFIVE
diff --git a/images/Makefile.riscv b/images/Makefile.riscv
index c44c683431f7..4410765cf664 100644
--- a/images/Makefile.riscv
+++ b/images/Makefile.riscv
@@ -15,3 +15,7 @@ pblb-$(CONFIG_BOARD_HIFIVE) += start_hifive_unmatched start_hifive_unleashed
 FILE_barebox-hifive-unmatched.img = start_hifive_unmatched.pblb
 FILE_barebox-hifive-unleashed.img = start_hifive_unleashed.pblb
 image-$(CONFIG_BOARD_HIFIVE) += barebox-hifive-unmatched.img barebox-hifive-unleashed.img
+
+pblb-$(CONFIG_BOARD_BEAGLEV) += start_beaglev_starlight
+FILE_barebox-beaglev-starlight.img = start_beaglev_starlight.pblb
+image-$(CONFIG_BOARD_BEAGLEV) += barebox-beaglev-starlight.img
-- 
2.29.2


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

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

* Re: [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems
  2021-06-19  4:50 ` [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems Ahmad Fatoum
@ 2021-06-21  7:25   ` Sascha Hauer
  2021-06-21  7:33     ` Ahmad Fatoum
  0 siblings, 1 reply; 33+ messages in thread
From: Sascha Hauer @ 2021-06-21  7:25 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Sat, Jun 19, 2021 at 06:50:41AM +0200, Ahmad Fatoum wrote:
> 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, which additionally
> needs a non 1:1 mapping for coherent DMA.
> 
> 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    | 57 ++++++++++++++++++++++---------------
>  drivers/net/designware.h    | 28 +++++++++++++++---
>  3 files changed, 68 insertions(+), 27 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 0ee6d3d78ac7..559e202c29ce 100644
> --- a/drivers/net/designware.c
> +++ b/drivers/net/designware.c
> @@ -104,15 +104,15 @@ static void tx_descs_init(struct eth_device *dev)
>  {
>  	struct dw_eth_dev *priv = dev->priv;
>  	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> -	struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
> +	struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable_cpu[0];
>  	char *txbuffs = &priv->txbuffs[0];
>  	struct dmamacdescr *desc_p;
>  	u32 idx;
>  
>  	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 = tx_dma_addr(priv, &desc_table_p[idx + 1]);
>  
>  		if (priv->enh_desc) {
>  			desc_p->txrx_status &= ~(DESC_ENH_TXSTS_TXINT | DESC_ENH_TXSTS_TXLAST |
> @@ -130,9 +130,9 @@ 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 = tx_dma_addr(priv, &desc_table_p[0]);
>  
> -	writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
> +	writel(desc_p->dmamac_next, &dma_p->txdesclistaddr);
>  	priv->tx_currdescnum = 0;
>  }
>  
> @@ -140,15 +140,15 @@ static void rx_descs_init(struct eth_device *dev)
>  {
>  	struct dw_eth_dev *priv = dev->priv;
>  	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> -	struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
> +	struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable_cpu[0];
>  	char *rxbuffs = &priv->rxbuffs[0];
>  	struct dmamacdescr *desc_p;
>  	u32 idx;
>  
>  	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]);

You have both the DMA and virtual addresses available when allocating
the memory. I think you should use this information rather than
introducing the need for a virt_to_phys() phys_to_virt() pair.

> @@ -276,7 +276,7 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
>  	struct dw_eth_dev *priv = dev->priv;
>  	struct eth_dma_regs *dma_p = priv->dma_regs_p;
>  	u32 owndma, desc_num = priv->tx_currdescnum;
> -	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
> +	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable_cpu[desc_num];
>  
>  	owndma = priv->enh_desc ? DESC_ENH_TXSTS_OWNBYDMA : DESC_TXSTS_OWNBYDMA;
>  	/* Check if the descriptor is owned by CPU */
> @@ -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);

Rather use dma_map_single() here?

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] 33+ messages in thread

* Re: [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems
  2021-06-21  7:25   ` Sascha Hauer
@ 2021-06-21  7:33     ` Ahmad Fatoum
  0 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-21  7:33 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

Hi,

On 21.06.21 09:25, Sascha Hauer wrote:
> On Sat, Jun 19, 2021 at 06:50:41AM +0200, Ahmad Fatoum wrote:
>> 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, which additionally
>> needs a non 1:1 mapping for coherent DMA.
>>
>> 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    | 57 ++++++++++++++++++++++---------------
>>  drivers/net/designware.h    | 28 +++++++++++++++---
>>  3 files changed, 68 insertions(+), 27 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 0ee6d3d78ac7..559e202c29ce 100644
>> --- a/drivers/net/designware.c
>> +++ b/drivers/net/designware.c
>> @@ -104,15 +104,15 @@ static void tx_descs_init(struct eth_device *dev)
>>  {
>>  	struct dw_eth_dev *priv = dev->priv;
>>  	struct eth_dma_regs *dma_p = priv->dma_regs_p;
>> -	struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
>> +	struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable_cpu[0];
>>  	char *txbuffs = &priv->txbuffs[0];
>>  	struct dmamacdescr *desc_p;
>>  	u32 idx;
>>  
>>  	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 = tx_dma_addr(priv, &desc_table_p[idx + 1]);
>>  
>>  		if (priv->enh_desc) {
>>  			desc_p->txrx_status &= ~(DESC_ENH_TXSTS_TXINT | DESC_ENH_TXSTS_TXLAST |
>> @@ -130,9 +130,9 @@ 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 = tx_dma_addr(priv, &desc_table_p[0]);
>>  
>> -	writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
>> +	writel(desc_p->dmamac_next, &dma_p->txdesclistaddr);
>>  	priv->tx_currdescnum = 0;
>>  }
>>  
>> @@ -140,15 +140,15 @@ static void rx_descs_init(struct eth_device *dev)
>>  {
>>  	struct dw_eth_dev *priv = dev->priv;
>>  	struct eth_dma_regs *dma_p = priv->dma_regs_p;
>> -	struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
>> +	struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable_cpu[0];
>>  	char *rxbuffs = &priv->rxbuffs[0];
>>  	struct dmamacdescr *desc_p;
>>  	u32 idx;
>>  
>>  	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]);
> 
> You have both the DMA and virtual addresses available when allocating
> the memory. I think you should use this information rather than
> introducing the need for a virt_to_phys() phys_to_virt() pair.

desc_p points at DMA coherent memory. desc_p->dmamac_addr is supposed to contain
the physical address of memory used for streaming DMA. I think virt_to_phys
is appropriate here.

> 
>> @@ -276,7 +276,7 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
>>  	struct dw_eth_dev *priv = dev->priv;
>>  	struct eth_dma_regs *dma_p = priv->dma_regs_p;
>>  	u32 owndma, desc_num = priv->tx_currdescnum;
>> -	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
>> +	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable_cpu[desc_num];
>>  
>>  	owndma = priv->enh_desc ? DESC_ENH_TXSTS_OWNBYDMA : DESC_TXSTS_OWNBYDMA;
>>  	/* Check if the descriptor is owned by CPU */
>> @@ -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);
> 
> Rather use dma_map_single() here?

There's is an unbalanced dma_sync_single_for_cpu in rx_descs_init().
I wasn't sure how to deal with it, had I wanted to move everything to dma_map_single.

I can supply a patch later for dma_map_single(), once I am told how, if that's
ok with you.

> 
> 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] 33+ messages in thread

* Re: [PATCH v2 00/29] RISC-V: add BeagleV Beta board support
  2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
                   ` (28 preceding siblings ...)
  2021-06-19  4:50 ` [PATCH v2 29/29] RISC-V: StarFive: add board support for BeagleV Starlight Ahmad Fatoum
@ 2021-06-21  9:11 ` Sascha Hauer
  29 siblings, 0 replies; 33+ messages in thread
From: Sascha Hauer @ 2021-06-21  9:11 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Sat, Jun 19, 2021 at 06:50:26AM +0200, Ahmad Fatoum wrote:
> The changes allow barebox to run second stage (after ddrinit and second
> boot) on the BeagleV beta board. It does everything necessary to support
> Ethernet, MMC, GPIO, pinmux, pinconf, clock, reset, watchdog, HWRNG and
> DMA between CPU and the cache-incoherent DMA masters.
> 
> The current vendor kernel doesn't care much for low-level
> initialization, depending on pinmux, pinconf, clock and reset to happen
> completely in the bootloader. This makes an initial bootloader port
> much more complex, because you need not only care about the peripherals
> you use yourself, but those that Linux may want to access to.
> 
> For this reason, there is a starfive-pwrseq driver that binds against
> some nodes like the neural network accelerator, which we will probably
> never support, but at least tickles it resets and enables its clocks.
> 
> Some peripherals require writing magic values into registers, which
> this series doesn't do. If your boot hangs, consider checking out:
> 
> https://github.com/a3f/barebox/tree/beaglev
> 
> instead, which imports some vendor boot code to support more
> peripherals. This series is sufficient to have barebox boot kernels that
> do their own initialization though. Problem is there are no such kernels
> yet ^^.
> 
> Candidates for further steps:
> 
>  - Support more peripherals in starfive-pwrseq
>  - Get Designware i2c controller working, so we can use PMIC for reset
>  - Get Cadence QSPI working, so barebox can flash itself and use
>    environment on flash
>  - Figure out the ticket lottery stuff, so we can boot multi-core
>  - Replace ddrinit and secondboot with PBL, load from there opensbi
>    and then return to barebox proper
>  - Complete missing clock tree info when Documentation is available
> 
> I can use a hand impementing these, so patches are most certainly
> welcome (Antony, I am looking at you ;-).
> 
> v1 was here:
> 	https://lore.barebox.org/barebox/20210531073821.15257-1-a.fatoum@pengutronix.de/
> 
> v1 -> v2:
>   - Dropped untested PMIC and flash chip commits. i2c and qspi controller
>     drivers in tree don't yet work for BeagleV
>   - remove clocksource clutter from console
>   - import S-/M-Mode multi-image series, so we can build all images for
>     the same ISA in one go
>   - Drop barebox,provide-mac-address from OTP driver. This is now done
>     via nvmem-cells reference
>   - Replace coherent memory from SRAM allocator with non-1:1 mapping:
>     Give devices the cached <= 32 bit address, as they are
>     cache-incoherent anyway, and use the > 32 bit uncached address from
>     CPU side. Works beautifully
>   - Drop 64-bit-conversion for dw_mmc. Sascha did it for rk3568 and it
>     works for BeagleV too
>   - Check Designware ETH coherent memory allocation against mask
>   - Rebase on newest clock changes
>   - Disable clocks after resets (Sascha)
>   - Move repsonsibility of keeping reset-synchronous clocks needed
>     for normal operation enabled to drivers (Sascha, off-list)
>   - Handle fence.i trap in exception handler to support SoCs without
>     Zifencei ISA extension
>   - Add some static clock initialization to starfive-pwrseq driver
>   - Add pinctrl driver support
>   - Add GPIO driver support
>   - Add board support
> 
> 
> Ahmad Fatoum (29):
>   clocksource: RISC-V: demote probe success messages to debug level
>   RISC-V: virt: select only one timer
>   RISC-V: extend multi-image to support both S- and M-Mode
>   RISC-V: cpuinfo: return some output for non-SBI systems as well
>   RISC-V: S-Mode: propagate Hart ID
>   RISC-V: erizo: make it easier to reuse ns16550 debug_ll
>   RISC-V: socs: add Kconfig entry for StarFive JH7100
>   nvmem: add StarFive OTP support
>   RISC-V: dma: support multiple dma_alloc_coherent backends
>   RISC-V: add exception support
>   RISC-V: support incoherent I-Cache
>   drivers: soc: sifive: add basic L2 cache controller driver
>   soc: starfive: add support for JH7100 incoherent interconnect
>   soc: sifive: l2_cache: enable maximum available cache ways
>   net: designware: fix non-1:1 mapped 64-bit systems
>   net: designware: add support for IP integrated into StarFive SoC
>   mci: allocate DMA-able memory
>   mci: allocate sector_buf on demand
>   dma: allocate 32-byte aligned buffers by default
>   mci: dw_mmc: add optional reset line
>   mci: dw_mmc: match against StarFive MMC compatibles
>   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
>   reset: add device_reset_all helper
>   gpio: add support for StarFive GPIO controller
>   misc: add power sequencing driver for initializing StarFive
>     peripherals
>   RISC-V: StarFive: add board support for BeagleV Starlight

Applied, thanks

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] 33+ messages in thread

end of thread, other threads:[~2021-06-21  9:13 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-19  4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 01/29] clocksource: RISC-V: demote probe success messages to debug level Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 02/29] RISC-V: virt: select only one timer Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 03/29] RISC-V: extend multi-image to support both S- and M-Mode Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 04/29] RISC-V: cpuinfo: return some output for non-SBI systems as well Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 05/29] RISC-V: S-Mode: propagate Hart ID Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 06/29] RISC-V: erizo: make it easier to reuse ns16550 debug_ll Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 07/29] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 08/29] nvmem: add StarFive OTP support Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 09/29] RISC-V: dma: support multiple dma_alloc_coherent backends Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 10/29] RISC-V: add exception support Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 11/29] RISC-V: support incoherent I-Cache Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 12/29] drivers: soc: sifive: add basic L2 cache controller driver Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 13/29] soc: starfive: add support for JH7100 incoherent interconnect Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 14/29] soc: sifive: l2_cache: enable maximum available cache ways Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems Ahmad Fatoum
2021-06-21  7:25   ` Sascha Hauer
2021-06-21  7:33     ` Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 16/29] net: designware: add support for IP integrated into StarFive SoC Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 17/29] mci: allocate DMA-able memory Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 18/29] mci: allocate sector_buf on demand Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 19/29] dma: allocate 32-byte aligned buffers by default Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 20/29] mci: dw_mmc: add optional reset line Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 21/29] mci: dw_mmc: match against StarFive MMC compatibles Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 22/29] clk: add initial StarFive clock support Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 23/29] reset: add StarFive reset controller driver Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 24/29] watchdog: add StarFive watchdog driver Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 25/29] hw_random: add driver for RNG on StarFive SoC Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 26/29] reset: add device_reset_all helper Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 27/29] gpio: add support for StarFive GPIO controller Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 28/29] misc: add power sequencing driver for initializing StarFive peripherals Ahmad Fatoum
2021-06-19  4:50 ` [PATCH v2 29/29] RISC-V: StarFive: add board support for BeagleV Starlight Ahmad Fatoum
2021-06-21  9:11 ` [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Sascha Hauer

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