risc-v/starfive/starfive2/d1: all of RichNeese's Risc-V boards and families - squashed

- `risc-v`: rework RichNeese's boards, reduce families, move tweaks to boards
- `risc-v`/`starfive`: `CONFIG_MOTORCOMM_PHY=m` for the onboard Ethernet
- `risc-v`/`starfive`: use mainline kernel 6.1.y, with StarFive's rebased patches against `v6.1.5`
  - from https://github.com/starfive-tech/linux/commits/visionfive
  - contention point: `1022-soc-sifive-ccache-Add-StarFive-JH71x0-support.patch` which I merged half-assed, need review/fixes?
  - `risc-v`/`starfive`: update kernel config, sans changes
- `risc-v`/`starfive`: switch from `grub` to `extlinux`
- `risc-v`/`starfive`: new `starfive` family with their (vendor) kernel

Co-authored-by: Richard Neese <r.neese@gmail.com>
This commit is contained in:
Ricardo Pardini 2022-12-14 19:07:30 +01:00
parent 7f11a59c3a
commit 9e29827ad9
No known key found for this signature in database
GPG Key ID: 3D38CA12A66C5D02
63 changed files with 72122 additions and 0 deletions

47
config/boards/beaglev.wip Normal file
View File

@ -0,0 +1,47 @@
# RISC-V StarFive BeagleV
BOARD_NAME="BeagleV"
BOARDFAMILY="starfive"
KERNEL_TARGET="edge"
BOOT_FDT_FILE="starfive/jh7100-beaglev-starlight-a1.dtb"
SRC_EXTLINUX="yes"
SRC_CMDLINE="console=ttyS0,115200n8 console=tty0 earlycon=sbi rootflags=data=writeback stmmaceth=chain_mode:1 rw"
BOOTCONFIG=none
function post_family_tweaks__beaglev_uenv() {
# rpardini: uEnv.txt is needed to re-enable distroboot-like behaviour on the board's SPI u-boot
display_alert "$BOARD" "creating uEnv.txt" "info"
cat <<- UENV_SCRIPT_HEADER > "${SDCARD}/boot/uEnv.txt"
fdt_high=0xffffffffffffffff
initrd_high=0xffffffffffffffff
scriptaddr=0x88100000
script_offset_f=0x1fff000
script_size_f=0x1000
kernel_addr_r=0x84000000
kernel_comp_addr_r=0x90000000
kernel_comp_size=0x10000000
fdt_addr_r=0x88000000
ramdisk_addr_r=0x88300000
distro_bootpart=1
uenvcmd=run mmc_boot
UENV_SCRIPT_HEADER
display_alert "$BOARD" "creating 10-hdmi.conf" "info"
mkdir -p "${SDCARD}/etc/X11/xorg.conf.d"
cat <<- XORG_HDMI_CONF > "${SDCARD}/etc/X11/xorg.conf.d/10-hdmi.conf"
Section "Device"
Identifier "Default Device"
Driver "modesetting"
Option "AccelMethod" "none" ### "glamor" to enable 3D acceleration, "none" to disable.
EndSection
Section "ServerFlags"
Option "AutoAddGPU" "off"
Option "Debug" "dmabuf_capable"
EndSection
XORG_HDMI_CONF
return 0
}

View File

@ -0,0 +1,8 @@
# RISC-V Mangopi-MQ D1
BOARD_NAME="Mangopi-MQ"
BOARDFAMILY="d1"
KERNEL_TARGET="edge"
BOOT_FDT_FILE="allwinner/sun20i-d1-nezha.dtb"
SRC_EXTLINUX="yes"
SRC_CMDLINE="console=ttyS0,115200n8 console=tty0 earlycon=sbi cma=96M rootflags=data=writeback stmmaceth=chain_mode:1 rw"
BOOTCONFIG="nezha_defconfig"

8
config/boards/nezha.wip Normal file
View File

@ -0,0 +1,8 @@
# RISC-V Nezha D1
BOARD_NAME="Nezha"
BOARDFAMILY="d1"
KERNEL_TARGET="edge"
BOOT_FDT_FILE="all winner/sun20i-d1-nezha.dtb"
SRC_EXTLINUX="yes"
SRC_CMDLINE="console=ttyS0,115200n8 console=tty0 earlycon=sbi cma=96M rootflags=data=writeback stmmaceth=chain_mode:1 rw"
BOOTCONFIG="nezha_defconfig"

34
config/boards/star64.wip Normal file
View File

@ -0,0 +1,34 @@
# RISC-V Pine64 Star64
BOARD_NAME="Star64"
BOARDFAMILY="starfive2"
KERNEL_TARGET="edge"
BOOT_FDT_FILE="starfive/jh7110-star64-pine64.dtb"
SRC_EXTLINUX="yes"
SRC_CMDLINE="console=ttyS0,115200n8 console=tty0 earlycon=sbi rootflags=data=writeback stmmaceth=chain_mode:1 rw"
BOOTCONFIG=none
function post_family_tweaks__star64_uenv() {
# rpardini: uEnv.txt is needed to re-enable distroboot-like behaviour on the board's SPI u-boot
display_alert "$BOARD" "creating uEnv.txt" "info"
cat <<- UENV_SCRIPT_HEADER > "${SDCARD}/boot/uEnv.txt"
fdt_high=0xffffffffffffffff
initrd_high=0xffffffffffffffff
kernel_addr_r=0x44000000
kernel_comp_addr_r=0x90000000
kernel_comp_size=0x10000000
fdt_addr_r=0x48000000
ramdisk_addr_r=0x48100000
# Move distro to first boot to speed up booting
boot_targets=distro mmc1 dhcp
distro_bootpart=1
# Fix missing bootcmd
bootcmd=run bootcmd_distro
UENV_SCRIPT_HEADER
return 0
}

View File

@ -0,0 +1,8 @@
# RISC-V SiFive Unleashed
BOARD_NAME="Unleashed"
BOARDFAMILY="starfive"
KERNEL_TARGET="edge"
BOOT_FDT_FILE="sifive/hifive-unleashed-a00.dtb"
SRC_EXTLINUX="yes"
SRC_CMDLINE="console=ttyS0,115200n8 console=tty0 earlycon=sbi rootflags=data=writeback stmmaceth=chain_mode:1 rw"
BOOTCONFIG=none

View File

@ -0,0 +1,8 @@
# RISC-V SiFive Unmatched
BOARD_NAME="Unmatched"
BOARDFAMILY="starfive"
KERNEL_TARGET="edge"
BOOT_FDT_FILE="sifive/hifive-unmatched-a00.dtb"
SRC_EXTLINUX="yes"
SRC_CMDLINE="console=ttyS0,115200n8 console=tty0 earlycon=sbi rootflags=data=writeback stmmaceth=chain_mode:1 rw"
BOOTCONFIG=none

View File

@ -0,0 +1,47 @@
# RISC-V StarFive Visionfive V1
BOARD_NAME="VisionFive"
BOARDFAMILY="starfive"
KERNEL_TARGET="edge"
BOOT_FDT_FILE="starfive/jh7100-starfive-visionfive-v1.dtb"
SRC_EXTLINUX="yes"
SRC_CMDLINE="console=ttyS0,115200n8 console=tty0 earlycon=sbi rootflags=data=writeback stmmaceth=chain_mode:1 rw"
BOOTCONFIG=none
function post_family_tweaks__visionfive_uenv() {
# rpardini: uEnv.txt is needed to re-enable distroboot-like behaviour on the board's SPI u-boot
display_alert "$BOARD" "creating uEnv.txt" "info"
cat <<- UENV_SCRIPT_HEADER > "${SDCARD}/boot/uEnv.txt"
fdt_high=0xffffffffffffffff
initrd_high=0xffffffffffffffff
scriptaddr=0x88100000
script_offset_f=0x1fff000
script_size_f=0x1000
kernel_addr_r=0x84000000
kernel_comp_addr_r=0x90000000
kernel_comp_size=0x10000000
fdt_addr_r=0x88000000
ramdisk_addr_r=0x88300000
distro_bootpart=1
uenvcmd=run mmc_boot
UENV_SCRIPT_HEADER
display_alert "$BOARD" "creating 10-hdmi.conf" "info"
mkdir -p "${SDCARD}/etc/X11/xorg.conf.d"
cat <<- XORG_HDMI_CONF > "${SDCARD}/etc/X11/xorg.conf.d/10-hdmi.conf"
Section "Device"
Identifier "Default Device"
Driver "modesetting"
Option "AccelMethod" "none" ### "glamor" to enable 3D acceleration, "none" to disable.
EndSection
Section "ServerFlags"
Option "AutoAddGPU" "off"
Option "Debug" "dmabuf_capable"
EndSection
XORG_HDMI_CONF
return 0
}

View File

@ -0,0 +1,34 @@
# RISC-V StarFive Visionfive V2
BOARD_NAME="VisionFive2"
BOARDFAMILY="starfive2"
KERNEL_TARGET="edge"
BOOT_FDT_FILE="starfive/jh7110-visionfive-v2.dtb"
SRC_EXTLINUX="yes"
SRC_CMDLINE="console=ttyS0,115200n8 console=tty0 earlycon=sbi rootflags=data=writeback stmmaceth=chain_mode:1 rw"
BOOTCONFIG=none
function post_family_tweaks__visionfive2_uenv() {
# rpardini: uEnv.txt is needed to re-enable distroboot-like behaviour on the board's SPI u-boot
display_alert "$BOARD" "creating uEnv.txt" "info"
cat <<- UENV_SCRIPT_HEADER > "${SDCARD}/boot/uEnv.txt"
fdt_high=0xffffffffffffffff
initrd_high=0xffffffffffffffff
kernel_addr_r=0x44000000
kernel_comp_addr_r=0x90000000
kernel_comp_size=0x10000000
fdt_addr_r=0x48000000
ramdisk_addr_r=0x48100000
# Move distro to first boot to speed up booting
boot_targets=distro mmc1 dhcp
distro_bootpart=1
# Fix missing bootcmd
bootcmd=run bootcmd_distro
UENV_SCRIPT_HEADER
return 0
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
debian-ports-archive-keyring

View File

@ -0,0 +1,29 @@
ARCH="riscv64"
BOOTSOURCE='https://github.com/smaeul/u-boot'
BOOTBRANCH='branch:d1-wip'
BOOTPATCHDIR="u-boot-nezha"
UBOOT_TARGET_MAP=";;u-boot.img"
LINUXFAMILY="d1"
LINUXCONFIG="linux-d1-${BRANCH}"
case "${BRANCH}" in
edge)
declare -g KERNEL_MAJOR_MINOR="6.1" # Major and minor versions of this kernel. For mainline caching.
KERNELSOURCE='https://github.com/smaeul/linux'
KERNELBRANCH="branch:riscv/d1-wip"
KERNELPATCHDIR="d1-${BRANCH}"
LINUXCONFIG="linux-d1-${BRANCH}"
;;
esac
#KERNELPATCHDIR="archive/starfive-${KERNEL_MAJOR_MINOR}" # Don't use symlinks.
write_uboot_platform() {
dd if=$SRC/packages/blobs/riscv64/nezha/boot0_sdcard_sun20iw1p1.bin of=$2 bs=8192 seek=16 conv=notrunc
dd if=$SRC/packages/blobs/riscv64/nezha/u-boot.toc1 of=$2 bs=512 seek=32800 conv=notrunc
dd if=$SRC/packages/blobs/riscv64/nezha/u-boot.toc1 of=$2 bs=512 seek=24576 conv=notrunc
}

View File

@ -0,0 +1,16 @@
ARCH="riscv64"
LINUXCONFIG="linux-starfive-${BRANCH}"
LINUXFAMILY="starfive"
case "${BRANCH}" in
edge)
declare -g KERNEL_MAJOR_MINOR="6.1" # Major and minor versions of this kernel. For mainline caching.
KERNELBRANCH='branch:linux-6.1.y'
;;
esac
KERNELPATCHDIR="archive/starfive-${KERNEL_MAJOR_MINOR}" # Don't use symlinks.

View File

@ -0,0 +1,17 @@
ARCH="riscv64"
LINUXCONFIG="linux-starfive2-${BRANCH}"
LINUXFAMILY="starfive2"
case "${BRANCH}" in
edge)
declare -g KERNEL_MAJOR_MINOR="5.15" # Major and minor versions of this kernel. For mainline caching.
KERNELSOURCE='https://github.com/starfive-tech/linux'
KERNELBRANCH="branch:JH7110_VisionFive2_devel"
KERNELPATCHDIR="starfive2-${BRANCH}"
;;
esac
#KERNELPATCHDIR="archive/starfive2-${KERNEL_MAJOR_MINOR}" # Don't use symlinks.

View File

@ -0,0 +1,380 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matteo Croce <technoboy85@gmail.com>
Date: Wed, 29 Sep 2021 19:22:32 +0200
Subject: riscv: optimized memcpy
Write a C version of memcpy() which uses the biggest data size allowed,
without generating unaligned accesses.
The procedure is made of three steps:
First copy data one byte at time until the destination buffer is aligned
to a long boundary.
Then copy the data one long at time shifting the current and the next u8
to compose a long at every cycle.
Finally, copy the remainder one byte at time.
On a BeagleV, the TCP RX throughput increased by 45%:
before:
$ iperf3 -c beaglev
Connecting to host beaglev, port 5201
[ 5] local 192.168.85.6 port 44840 connected to 192.168.85.48 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 76.4 MBytes 641 Mbits/sec 27 624 KBytes
[ 5] 1.00-2.00 sec 72.5 MBytes 608 Mbits/sec 0 708 KBytes
[ 5] 2.00-3.00 sec 73.8 MBytes 619 Mbits/sec 10 451 KBytes
[ 5] 3.00-4.00 sec 72.5 MBytes 608 Mbits/sec 0 564 KBytes
[ 5] 4.00-5.00 sec 73.8 MBytes 619 Mbits/sec 0 658 KBytes
[ 5] 5.00-6.00 sec 73.8 MBytes 619 Mbits/sec 14 522 KBytes
[ 5] 6.00-7.00 sec 73.8 MBytes 619 Mbits/sec 0 621 KBytes
[ 5] 7.00-8.00 sec 72.5 MBytes 608 Mbits/sec 0 706 KBytes
[ 5] 8.00-9.00 sec 73.8 MBytes 619 Mbits/sec 20 580 KBytes
[ 5] 9.00-10.00 sec 73.8 MBytes 619 Mbits/sec 0 672 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 736 MBytes 618 Mbits/sec 71 sender
[ 5] 0.00-10.01 sec 733 MBytes 615 Mbits/sec receiver
after:
$ iperf3 -c beaglev
Connecting to host beaglev, port 5201
[ 5] local 192.168.85.6 port 44864 connected to 192.168.85.48 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 109 MBytes 912 Mbits/sec 48 559 KBytes
[ 5] 1.00-2.00 sec 108 MBytes 902 Mbits/sec 0 690 KBytes
[ 5] 2.00-3.00 sec 106 MBytes 891 Mbits/sec 36 396 KBytes
[ 5] 3.00-4.00 sec 108 MBytes 902 Mbits/sec 0 567 KBytes
[ 5] 4.00-5.00 sec 106 MBytes 891 Mbits/sec 0 699 KBytes
[ 5] 5.00-6.00 sec 106 MBytes 891 Mbits/sec 32 414 KBytes
[ 5] 6.00-7.00 sec 106 MBytes 891 Mbits/sec 0 583 KBytes
[ 5] 7.00-8.00 sec 106 MBytes 891 Mbits/sec 0 708 KBytes
[ 5] 8.00-9.00 sec 106 MBytes 891 Mbits/sec 28 433 KBytes
[ 5] 9.00-10.00 sec 108 MBytes 902 Mbits/sec 0 591 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 1.04 GBytes 897 Mbits/sec 144 sender
[ 5] 0.00-10.01 sec 1.04 GBytes 894 Mbits/sec receiver
And the decreased CPU time of the memcpy() is observable with perf top.
This is the `perf top -Ue task-clock` output when doing the test:
before:
Overhead Shared O Symbol
42.22% [kernel] [k] memcpy
35.00% [kernel] [k] __asm_copy_to_user
3.50% [kernel] [k] sifive_l2_flush64_range
2.30% [kernel] [k] stmmac_napi_poll_rx
1.11% [kernel] [k] memset
after:
Overhead Shared O Symbol
45.69% [kernel] [k] __asm_copy_to_user
29.06% [kernel] [k] memcpy
4.09% [kernel] [k] sifive_l2_flush64_range
2.77% [kernel] [k] stmmac_napi_poll_rx
1.24% [kernel] [k] memset
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/include/asm/string.h | 6 +-
arch/riscv/kernel/riscv_ksyms.c | 2 -
arch/riscv/lib/Makefile | 7 +-
arch/riscv/lib/memcpy.S | 108 ----------
arch/riscv/lib/string.c | 91 ++++++++
arch/riscv/purgatory/Makefile | 6 +-
6 files changed, 104 insertions(+), 116 deletions(-)
diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
index 909049366555..23fdcbffb6a1 100644
--- a/arch/riscv/include/asm/string.h
+++ b/arch/riscv/include/asm/string.h
@@ -12,9 +12,11 @@
#define __HAVE_ARCH_MEMSET
extern asmlinkage void *memset(void *, int, size_t);
extern asmlinkage void *__memset(void *, int, size_t);
+
#define __HAVE_ARCH_MEMCPY
-extern asmlinkage void *memcpy(void *, const void *, size_t);
-extern asmlinkage void *__memcpy(void *, const void *, size_t);
+extern void *memcpy(void *dest, const void *src, size_t count);
+extern void *__memcpy(void *dest, const void *src, size_t count);
+
#define __HAVE_ARCH_MEMMOVE
extern asmlinkage void *memmove(void *, const void *, size_t);
extern asmlinkage void *__memmove(void *, const void *, size_t);
diff --git a/arch/riscv/kernel/riscv_ksyms.c b/arch/riscv/kernel/riscv_ksyms.c
index 5ab1c7e1a6ed..3f6d512a5b97 100644
--- a/arch/riscv/kernel/riscv_ksyms.c
+++ b/arch/riscv/kernel/riscv_ksyms.c
@@ -10,8 +10,6 @@
* Assembly functions that may be used (directly or indirectly) by modules
*/
EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__memset);
-EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(__memmove);
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 25d5c9664e57..023d78f20960 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -1,9 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-only
lib-y += delay.o
-lib-y += memcpy.o
lib-y += memset.o
lib-y += memmove.o
lib-$(CONFIG_MMU) += uaccess.o
lib-$(CONFIG_64BIT) += tishift.o
+lib-y += string.o
+
+# string.o implements standard library functions like memset/memcpy etc.
+# Use -ffreestanding to ensure that the compiler does not try to "optimize"
+# them into calls to themselves.
+CFLAGS_string.o := -ffreestanding
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/riscv/lib/memcpy.S b/arch/riscv/lib/memcpy.S
deleted file mode 100644
index 51ab716253fa..000000000000
--- a/arch/riscv/lib/memcpy.S
+++ /dev/null
@@ -1,108 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2013 Regents of the University of California
- */
-
-#include <linux/linkage.h>
-#include <asm/asm.h>
-
-/* void *memcpy(void *, const void *, size_t) */
-ENTRY(__memcpy)
-WEAK(memcpy)
- move t6, a0 /* Preserve return value */
-
- /* Defer to byte-oriented copy for small sizes */
- sltiu a3, a2, 128
- bnez a3, 4f
- /* Use word-oriented copy only if low-order bits match */
- andi a3, t6, SZREG-1
- andi a4, a1, SZREG-1
- bne a3, a4, 4f
-
- beqz a3, 2f /* Skip if already aligned */
- /*
- * Round to nearest double word-aligned address
- * greater than or equal to start address
- */
- andi a3, a1, ~(SZREG-1)
- addi a3, a3, SZREG
- /* Handle initial misalignment */
- sub a4, a3, a1
-1:
- lb a5, 0(a1)
- addi a1, a1, 1
- sb a5, 0(t6)
- addi t6, t6, 1
- bltu a1, a3, 1b
- sub a2, a2, a4 /* Update count */
-
-2:
- andi a4, a2, ~((16*SZREG)-1)
- beqz a4, 4f
- add a3, a1, a4
-3:
- REG_L a4, 0(a1)
- REG_L a5, SZREG(a1)
- REG_L a6, 2*SZREG(a1)
- REG_L a7, 3*SZREG(a1)
- REG_L t0, 4*SZREG(a1)
- REG_L t1, 5*SZREG(a1)
- REG_L t2, 6*SZREG(a1)
- REG_L t3, 7*SZREG(a1)
- REG_L t4, 8*SZREG(a1)
- REG_L t5, 9*SZREG(a1)
- REG_S a4, 0(t6)
- REG_S a5, SZREG(t6)
- REG_S a6, 2*SZREG(t6)
- REG_S a7, 3*SZREG(t6)
- REG_S t0, 4*SZREG(t6)
- REG_S t1, 5*SZREG(t6)
- REG_S t2, 6*SZREG(t6)
- REG_S t3, 7*SZREG(t6)
- REG_S t4, 8*SZREG(t6)
- REG_S t5, 9*SZREG(t6)
- REG_L a4, 10*SZREG(a1)
- REG_L a5, 11*SZREG(a1)
- REG_L a6, 12*SZREG(a1)
- REG_L a7, 13*SZREG(a1)
- REG_L t0, 14*SZREG(a1)
- REG_L t1, 15*SZREG(a1)
- addi a1, a1, 16*SZREG
- REG_S a4, 10*SZREG(t6)
- REG_S a5, 11*SZREG(t6)
- REG_S a6, 12*SZREG(t6)
- REG_S a7, 13*SZREG(t6)
- REG_S t0, 14*SZREG(t6)
- REG_S t1, 15*SZREG(t6)
- addi t6, t6, 16*SZREG
- bltu a1, a3, 3b
- andi a2, a2, (16*SZREG)-1 /* Update count */
-
-4:
- /* Handle trailing misalignment */
- beqz a2, 6f
- add a3, a1, a2
-
- /* Use word-oriented copy if co-aligned to word boundary */
- or a5, a1, t6
- or a5, a5, a3
- andi a5, a5, 3
- bnez a5, 5f
-7:
- lw a4, 0(a1)
- addi a1, a1, 4
- sw a4, 0(t6)
- addi t6, t6, 4
- bltu a1, a3, 7b
-
- ret
-
-5:
- lb a4, 0(a1)
- addi a1, a1, 1
- sb a4, 0(t6)
- addi t6, t6, 1
- bltu a1, a3, 5b
-6:
- ret
-END(__memcpy)
diff --git a/arch/riscv/lib/string.c b/arch/riscv/lib/string.c
new file mode 100644
index 000000000000..32509ab0232e
--- /dev/null
+++ b/arch/riscv/lib/string.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * String functions optimized for hardware which doesn't
+ * handle unaligned memory accesses efficiently.
+ *
+ * Copyright (C) 2021 Matteo Croce
+ */
+
+#define __NO_FORTIFY
+#include <linux/types.h>
+#include <linux/module.h>
+
+/* Minimum size for a word copy to be convenient */
+#define BYTES_LONG sizeof(long)
+#define WORD_MASK (BYTES_LONG - 1)
+#define MIN_THRESHOLD (BYTES_LONG * 2)
+
+/* convenience union to avoid cast between different pointer types */
+union types {
+ u8 *as_u8;
+ unsigned long *as_ulong;
+ uintptr_t as_uptr;
+};
+
+union const_types {
+ const u8 *as_u8;
+ unsigned long *as_ulong;
+ uintptr_t as_uptr;
+};
+
+void *__memcpy(void *dest, const void *src, size_t count)
+{
+ union const_types s = { .as_u8 = src };
+ union types d = { .as_u8 = dest };
+ int distance = 0;
+
+ if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
+ if (count < MIN_THRESHOLD)
+ goto copy_remainder;
+
+ /* Copy a byte at time until destination is aligned. */
+ for (; d.as_uptr & WORD_MASK; count--)
+ *d.as_u8++ = *s.as_u8++;
+
+ distance = s.as_uptr & WORD_MASK;
+ }
+
+ if (distance) {
+ unsigned long last, next;
+
+ /*
+ * s is distance bytes ahead of d, and d just reached
+ * the alignment boundary. Move s backward to word align it
+ * and shift data to compensate for distance, in order to do
+ * word-by-word copy.
+ */
+ s.as_u8 -= distance;
+
+ next = s.as_ulong[0];
+ for (; count >= BYTES_LONG; count -= BYTES_LONG) {
+ last = next;
+ next = s.as_ulong[1];
+
+ d.as_ulong[0] = last >> (distance * 8) |
+ next << ((BYTES_LONG - distance) * 8);
+
+ d.as_ulong++;
+ s.as_ulong++;
+ }
+
+ /* Restore s with the original offset. */
+ s.as_u8 += distance;
+ } else {
+ /*
+ * If the source and dest lower bits are the same, do a simple
+ * 32/64 bit wide copy.
+ */
+ for (; count >= BYTES_LONG; count -= BYTES_LONG)
+ *d.as_ulong++ = *s.as_ulong++;
+ }
+
+copy_remainder:
+ while (count--)
+ *d.as_u8++ = *s.as_u8++;
+
+ return dest;
+}
+EXPORT_SYMBOL(__memcpy);
+
+void *memcpy(void *dest, const void *src, size_t count) __weak __alias(__memcpy);
+EXPORT_SYMBOL(memcpy);
diff --git a/arch/riscv/purgatory/Makefile b/arch/riscv/purgatory/Makefile
index dd58e1d99397..cdac455aa044 100644
--- a/arch/riscv/purgatory/Makefile
+++ b/arch/riscv/purgatory/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
OBJECT_FILES_NON_STANDARD := y
-purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o
+purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o rvstring.o memset.o
targets += $(purgatory-y)
PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
@@ -12,8 +12,8 @@ $(obj)/string.o: $(srctree)/lib/string.c FORCE
$(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE
$(call if_changed_rule,cc_o_c)
-$(obj)/memcpy.o: $(srctree)/arch/riscv/lib/memcpy.S FORCE
- $(call if_changed_rule,as_o_S)
+$(obj)/rvstring.o: $(srctree)/arch/riscv/lib/string.c FORCE
+ $(call if_changed_rule,cc_o_c)
$(obj)/memset.o: $(srctree)/arch/riscv/lib/memset.S FORCE
$(call if_changed_rule,as_o_S)
--
Armbian

View File

@ -0,0 +1,415 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matteo Croce <technoboy85@gmail.com>
Date: Wed, 29 Sep 2021 19:22:33 +0200
Subject: riscv: optimized memmove
When the destination buffer is before the source one, or when the
buffers doesn't overlap, it's safe to use memcpy() instead, which is
optimized to use a bigger data size possible.
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
---
arch/riscv/include/asm/string.h | 6 +-
arch/riscv/kernel/riscv_ksyms.c | 2 -
arch/riscv/lib/Makefile | 1 -
arch/riscv/lib/memmove.S | 316 ----------
arch/riscv/lib/string.c | 23 +
5 files changed, 26 insertions(+), 322 deletions(-)
diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
index 23fdcbffb6a1..02120466d5a1 100644
--- a/arch/riscv/include/asm/string.h
+++ b/arch/riscv/include/asm/string.h
@@ -16,10 +16,10 @@ extern asmlinkage void *__memset(void *, int, size_t);
#define __HAVE_ARCH_MEMCPY
extern void *memcpy(void *dest, const void *src, size_t count);
extern void *__memcpy(void *dest, const void *src, size_t count);
-
#define __HAVE_ARCH_MEMMOVE
-extern asmlinkage void *memmove(void *, const void *, size_t);
-extern asmlinkage void *__memmove(void *, const void *, size_t);
+extern void *memmove(void *dest, const void *src, size_t count);
+extern void *__memmove(void *dest, const void *src, size_t count);
+
/* For those files which don't want to check by kasan. */
#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
#define memcpy(dst, src, len) __memcpy(dst, src, len)
diff --git a/arch/riscv/kernel/riscv_ksyms.c b/arch/riscv/kernel/riscv_ksyms.c
index 3f6d512a5b97..361565c4db7e 100644
--- a/arch/riscv/kernel/riscv_ksyms.c
+++ b/arch/riscv/kernel/riscv_ksyms.c
@@ -10,6 +10,4 @@
* Assembly functions that may be used (directly or indirectly) by modules
*/
EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__memset);
-EXPORT_SYMBOL(__memmove);
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 023d78f20960..9166b61cc2dc 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
lib-y += delay.o
lib-y += memset.o
-lib-y += memmove.o
lib-$(CONFIG_MMU) += uaccess.o
lib-$(CONFIG_64BIT) += tishift.o
lib-y += string.o
diff --git a/arch/riscv/lib/memmove.S b/arch/riscv/lib/memmove.S
deleted file mode 100644
index e0609e1f0864..000000000000
--- a/arch/riscv/lib/memmove.S
+++ /dev/null
@@ -1,316 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2022 Michael T. Kloos <michael@michaelkloos.com>
- */
-
-#include <linux/linkage.h>
-#include <asm/asm.h>
-
-SYM_FUNC_START(__memmove)
-SYM_FUNC_START_WEAK(memmove)
- /*
- * Returns
- * a0 - dest
- *
- * Parameters
- * a0 - Inclusive first byte of dest
- * a1 - Inclusive first byte of src
- * a2 - Length of copy n
- *
- * Because the return matches the parameter register a0,
- * we will not clobber or modify that register.
- *
- * Note: This currently only works on little-endian.
- * To port to big-endian, reverse the direction of shifts
- * in the 2 misaligned fixup copy loops.
- */
-
- /* Return if nothing to do */
- beq a0, a1, return_from_memmove
- beqz a2, return_from_memmove
-
- /*
- * Register Uses
- * Forward Copy: a1 - Index counter of src
- * Reverse Copy: a4 - Index counter of src
- * Forward Copy: t3 - Index counter of dest
- * Reverse Copy: t4 - Index counter of dest
- * Both Copy Modes: t5 - Inclusive first multibyte/aligned of dest
- * Both Copy Modes: t6 - Non-Inclusive last multibyte/aligned of dest
- * Both Copy Modes: t0 - Link / Temporary for load-store
- * Both Copy Modes: t1 - Temporary for load-store
- * Both Copy Modes: t2 - Temporary for load-store
- * Both Copy Modes: a5 - dest to src alignment offset
- * Both Copy Modes: a6 - Shift ammount
- * Both Copy Modes: a7 - Inverse Shift ammount
- * Both Copy Modes: a2 - Alternate breakpoint for unrolled loops
- */
-
- /*
- * Solve for some register values now.
- * Byte copy does not need t5 or t6.
- */
- mv t3, a0
- add t4, a0, a2
- add a4, a1, a2
-
- /*
- * Byte copy if copying less than (2 * SZREG) bytes. This can
- * cause problems with the bulk copy implementation and is
- * small enough not to bother.
- */
- andi t0, a2, -(2 * SZREG)
- beqz t0, byte_copy
-
- /*
- * Now solve for t5 and t6.
- */
- andi t5, t3, -SZREG
- andi t6, t4, -SZREG
- /*
- * If dest(Register t3) rounded down to the nearest naturally
- * aligned SZREG address, does not equal dest, then add SZREG
- * to find the low-bound of SZREG alignment in the dest memory
- * region. Note that this could overshoot the dest memory
- * region if n is less than SZREG. This is one reason why
- * we always byte copy if n is less than SZREG.
- * Otherwise, dest is already naturally aligned to SZREG.
- */
- beq t5, t3, 1f
- addi t5, t5, SZREG
- 1:
-
- /*
- * If the dest and src are co-aligned to SZREG, then there is
- * no need for the full rigmarole of a full misaligned fixup copy.
- * Instead, do a simpler co-aligned copy.
- */
- xor t0, a0, a1
- andi t1, t0, (SZREG - 1)
- beqz t1, coaligned_copy
- /* Fall through to misaligned fixup copy */
-
-misaligned_fixup_copy:
- bltu a1, a0, misaligned_fixup_copy_reverse
-
-misaligned_fixup_copy_forward:
- jal t0, byte_copy_until_aligned_forward
-
- andi a5, a1, (SZREG - 1) /* Find the alignment offset of src (a1) */
- slli a6, a5, 3 /* Multiply by 8 to convert that to bits to shift */
- sub a5, a1, t3 /* Find the difference between src and dest */
- andi a1, a1, -SZREG /* Align the src pointer */
- addi a2, t6, SZREG /* The other breakpoint for the unrolled loop*/
-
- /*
- * Compute The Inverse Shift
- * a7 = XLEN - a6 = XLEN + -a6
- * 2s complement negation to find the negative: -a6 = ~a6 + 1
- * Add that to XLEN. XLEN = SZREG * 8.
- */
- not a7, a6
- addi a7, a7, (SZREG * 8 + 1)
-
- /*
- * Fix Misalignment Copy Loop - Forward
- * load_val0 = load_ptr[0];
- * do {
- * load_val1 = load_ptr[1];
- * store_ptr += 2;
- * store_ptr[0 - 2] = (load_val0 >> {a6}) | (load_val1 << {a7});
- *
- * if (store_ptr == {a2})
- * break;
- *
- * load_val0 = load_ptr[2];
- * load_ptr += 2;
- * store_ptr[1 - 2] = (load_val1 >> {a6}) | (load_val0 << {a7});
- *
- * } while (store_ptr != store_ptr_end);
- * store_ptr = store_ptr_end;
- */
-
- REG_L t0, (0 * SZREG)(a1)
- 1:
- REG_L t1, (1 * SZREG)(a1)
- addi t3, t3, (2 * SZREG)
- srl t0, t0, a6
- sll t2, t1, a7
- or t2, t0, t2
- REG_S t2, ((0 * SZREG) - (2 * SZREG))(t3)
-
- beq t3, a2, 2f
-
- REG_L t0, (2 * SZREG)(a1)
- addi a1, a1, (2 * SZREG)
- srl t1, t1, a6
- sll t2, t0, a7
- or t2, t1, t2
- REG_S t2, ((1 * SZREG) - (2 * SZREG))(t3)
-
- bne t3, t6, 1b
- 2:
- mv t3, t6 /* Fix the dest pointer in case the loop was broken */
-
- add a1, t3, a5 /* Restore the src pointer */
- j byte_copy_forward /* Copy any remaining bytes */
-
-misaligned_fixup_copy_reverse:
- jal t0, byte_copy_until_aligned_reverse
-
- andi a5, a4, (SZREG - 1) /* Find the alignment offset of src (a4) */
- slli a6, a5, 3 /* Multiply by 8 to convert that to bits to shift */
- sub a5, a4, t4 /* Find the difference between src and dest */
- andi a4, a4, -SZREG /* Align the src pointer */
- addi a2, t5, -SZREG /* The other breakpoint for the unrolled loop*/
-
- /*
- * Compute The Inverse Shift
- * a7 = XLEN - a6 = XLEN + -a6
- * 2s complement negation to find the negative: -a6 = ~a6 + 1
- * Add that to XLEN. XLEN = SZREG * 8.
- */
- not a7, a6
- addi a7, a7, (SZREG * 8 + 1)
-
- /*
- * Fix Misalignment Copy Loop - Reverse
- * load_val1 = load_ptr[0];
- * do {
- * load_val0 = load_ptr[-1];
- * store_ptr -= 2;
- * store_ptr[1] = (load_val0 >> {a6}) | (load_val1 << {a7});
- *
- * if (store_ptr == {a2})
- * break;
- *
- * load_val1 = load_ptr[-2];
- * load_ptr -= 2;
- * store_ptr[0] = (load_val1 >> {a6}) | (load_val0 << {a7});
- *
- * } while (store_ptr != store_ptr_end);
- * store_ptr = store_ptr_end;
- */
-
- REG_L t1, ( 0 * SZREG)(a4)
- 1:
- REG_L t0, (-1 * SZREG)(a4)
- addi t4, t4, (-2 * SZREG)
- sll t1, t1, a7
- srl t2, t0, a6
- or t2, t1, t2
- REG_S t2, ( 1 * SZREG)(t4)
-
- beq t4, a2, 2f
-
- REG_L t1, (-2 * SZREG)(a4)
- addi a4, a4, (-2 * SZREG)
- sll t0, t0, a7
- srl t2, t1, a6
- or t2, t0, t2
- REG_S t2, ( 0 * SZREG)(t4)
-
- bne t4, t5, 1b
- 2:
- mv t4, t5 /* Fix the dest pointer in case the loop was broken */
-
- add a4, t4, a5 /* Restore the src pointer */
- j byte_copy_reverse /* Copy any remaining bytes */
-
-/*
- * Simple copy loops for SZREG co-aligned memory locations.
- * These also make calls to do byte copies for any unaligned
- * data at their terminations.
- */
-coaligned_copy:
- bltu a1, a0, coaligned_copy_reverse
-
-coaligned_copy_forward:
- jal t0, byte_copy_until_aligned_forward
-
- 1:
- REG_L t1, ( 0 * SZREG)(a1)
- addi a1, a1, SZREG
- addi t3, t3, SZREG
- REG_S t1, (-1 * SZREG)(t3)
- bne t3, t6, 1b
-
- j byte_copy_forward /* Copy any remaining bytes */
-
-coaligned_copy_reverse:
- jal t0, byte_copy_until_aligned_reverse
-
- 1:
- REG_L t1, (-1 * SZREG)(a4)
- addi a4, a4, -SZREG
- addi t4, t4, -SZREG
- REG_S t1, ( 0 * SZREG)(t4)
- bne t4, t5, 1b
-
- j byte_copy_reverse /* Copy any remaining bytes */
-
-/*
- * These are basically sub-functions within the function. They
- * are used to byte copy until the dest pointer is in alignment.
- * At which point, a bulk copy method can be used by the
- * calling code. These work on the same registers as the bulk
- * copy loops. Therefore, the register values can be picked
- * up from where they were left and we avoid code duplication
- * without any overhead except the call in and return jumps.
- */
-byte_copy_until_aligned_forward:
- beq t3, t5, 2f
- 1:
- lb t1, 0(a1)
- addi a1, a1, 1
- addi t3, t3, 1
- sb t1, -1(t3)
- bne t3, t5, 1b
- 2:
- jalr zero, 0x0(t0) /* Return to multibyte copy loop */
-
-byte_copy_until_aligned_reverse:
- beq t4, t6, 2f
- 1:
- lb t1, -1(a4)
- addi a4, a4, -1
- addi t4, t4, -1
- sb t1, 0(t4)
- bne t4, t6, 1b
- 2:
- jalr zero, 0x0(t0) /* Return to multibyte copy loop */
-
-/*
- * Simple byte copy loops.
- * These will byte copy until they reach the end of data to copy.
- * At that point, they will call to return from memmove.
- */
-byte_copy:
- bltu a1, a0, byte_copy_reverse
-
-byte_copy_forward:
- beq t3, t4, 2f
- 1:
- lb t1, 0(a1)
- addi a1, a1, 1
- addi t3, t3, 1
- sb t1, -1(t3)
- bne t3, t4, 1b
- 2:
- ret
-
-byte_copy_reverse:
- beq t4, t3, 2f
- 1:
- lb t1, -1(a4)
- addi a4, a4, -1
- addi t4, t4, -1
- sb t1, 0(t4)
- bne t4, t3, 1b
- 2:
-
-return_from_memmove:
- ret
-
-SYM_FUNC_END(memmove)
-SYM_FUNC_END(__memmove)
diff --git a/arch/riscv/lib/string.c b/arch/riscv/lib/string.c
index 32509ab0232e..bd52581e2068 100644
--- a/arch/riscv/lib/string.c
+++ b/arch/riscv/lib/string.c
@@ -89,3 +89,26 @@ EXPORT_SYMBOL(__memcpy);
void *memcpy(void *dest, const void *src, size_t count) __weak __alias(__memcpy);
EXPORT_SYMBOL(memcpy);
+
+/*
+ * Simply check if the buffer overlaps an call memcpy() in case,
+ * otherwise do a simple one byte at time backward copy.
+ */
+void *__memmove(void *dest, const void *src, size_t count)
+{
+ if (dest < src || src + count <= dest)
+ return __memcpy(dest, src, count);
+
+ if (dest > src) {
+ const char *s = src + count;
+ char *tmp = dest + count;
+
+ while (count--)
+ *--tmp = *--s;
+ }
+ return dest;
+}
+EXPORT_SYMBOL(__memmove);
+
+void *memmove(void *dest, const void *src, size_t count) __weak __alias(__memmove);
+EXPORT_SYMBOL(memmove);
--
Armbian

View File

@ -0,0 +1,280 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matteo Croce <technoboy85@gmail.com>
Date: Wed, 29 Sep 2021 19:22:34 +0200
Subject: riscv: optimized memset
The generic memset is defined as a byte at time write. This is always
safe, but it's slower than a 4 byte or even 8 byte write.
Write a generic memset which fills the data one byte at time until the
destination is aligned, then fills using the largest size allowed,
and finally fills the remaining data one byte at time.
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/include/asm/string.h | 8 +-
arch/riscv/kernel/Makefile | 1 -
arch/riscv/kernel/riscv_ksyms.c | 13 --
arch/riscv/lib/Makefile | 1 -
arch/riscv/lib/memset.S | 113 ----------
arch/riscv/lib/string.c | 41 ++++
arch/riscv/purgatory/Makefile | 5 +-
7 files changed, 44 insertions(+), 138 deletions(-)
diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
index 02120466d5a1..3b79b14a2bf1 100644
--- a/arch/riscv/include/asm/string.h
+++ b/arch/riscv/include/asm/string.h
@@ -6,13 +6,9 @@
#ifndef _ASM_RISCV_STRING_H
#define _ASM_RISCV_STRING_H
-#include <linux/types.h>
-#include <linux/linkage.h>
-
#define __HAVE_ARCH_MEMSET
-extern asmlinkage void *memset(void *, int, size_t);
-extern asmlinkage void *__memset(void *, int, size_t);
-
+extern void *memset(void *s, int c, size_t count);
+extern void *__memset(void *s, int c, size_t count);
#define __HAVE_ARCH_MEMCPY
extern void *memcpy(void *dest, const void *src, size_t count);
extern void *__memcpy(void *dest, const void *src, size_t count);
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index db6e4b1294ba..eea7ce0e7d30 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -46,7 +46,6 @@ obj-y += syscall_table.o
obj-y += sys_riscv.o
obj-y += time.o
obj-y += traps.o
-obj-y += riscv_ksyms.o
obj-y += stacktrace.o
obj-y += cacheinfo.o
obj-y += patch.o
diff --git a/arch/riscv/kernel/riscv_ksyms.c b/arch/riscv/kernel/riscv_ksyms.c
deleted file mode 100644
index 361565c4db7e..000000000000
--- a/arch/riscv/kernel/riscv_ksyms.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2017 Zihao Yu
- */
-
-#include <linux/export.h>
-#include <linux/uaccess.h>
-
-/*
- * Assembly functions that may be used (directly or indirectly) by modules
- */
-EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(__memset);
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 9166b61cc2dc..482e28132d77 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
lib-y += delay.o
-lib-y += memset.o
lib-$(CONFIG_MMU) += uaccess.o
lib-$(CONFIG_64BIT) += tishift.o
lib-y += string.o
diff --git a/arch/riscv/lib/memset.S b/arch/riscv/lib/memset.S
deleted file mode 100644
index 34c5360c6705..000000000000
--- a/arch/riscv/lib/memset.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2013 Regents of the University of California
- */
-
-
-#include <linux/linkage.h>
-#include <asm/asm.h>
-
-/* void *memset(void *, int, size_t) */
-ENTRY(__memset)
-WEAK(memset)
- move t0, a0 /* Preserve return value */
-
- /* Defer to byte-oriented fill for small sizes */
- sltiu a3, a2, 16
- bnez a3, 4f
-
- /*
- * Round to nearest XLEN-aligned address
- * greater than or equal to start address
- */
- addi a3, t0, SZREG-1
- andi a3, a3, ~(SZREG-1)
- beq a3, t0, 2f /* Skip if already aligned */
- /* Handle initial misalignment */
- sub a4, a3, t0
-1:
- sb a1, 0(t0)
- addi t0, t0, 1
- bltu t0, a3, 1b
- sub a2, a2, a4 /* Update count */
-
-2: /* Duff's device with 32 XLEN stores per iteration */
- /* Broadcast value into all bytes */
- andi a1, a1, 0xff
- slli a3, a1, 8
- or a1, a3, a1
- slli a3, a1, 16
- or a1, a3, a1
-#ifdef CONFIG_64BIT
- slli a3, a1, 32
- or a1, a3, a1
-#endif
-
- /* Calculate end address */
- andi a4, a2, ~(SZREG-1)
- add a3, t0, a4
-
- andi a4, a4, 31*SZREG /* Calculate remainder */
- beqz a4, 3f /* Shortcut if no remainder */
- neg a4, a4
- addi a4, a4, 32*SZREG /* Calculate initial offset */
-
- /* Adjust start address with offset */
- sub t0, t0, a4
-
- /* Jump into loop body */
- /* Assumes 32-bit instruction lengths */
- la a5, 3f
-#ifdef CONFIG_64BIT
- srli a4, a4, 1
-#endif
- add a5, a5, a4
- jr a5
-3:
- REG_S a1, 0(t0)
- REG_S a1, SZREG(t0)
- REG_S a1, 2*SZREG(t0)
- REG_S a1, 3*SZREG(t0)
- REG_S a1, 4*SZREG(t0)
- REG_S a1, 5*SZREG(t0)
- REG_S a1, 6*SZREG(t0)
- REG_S a1, 7*SZREG(t0)
- REG_S a1, 8*SZREG(t0)
- REG_S a1, 9*SZREG(t0)
- REG_S a1, 10*SZREG(t0)
- REG_S a1, 11*SZREG(t0)
- REG_S a1, 12*SZREG(t0)
- REG_S a1, 13*SZREG(t0)
- REG_S a1, 14*SZREG(t0)
- REG_S a1, 15*SZREG(t0)
- REG_S a1, 16*SZREG(t0)
- REG_S a1, 17*SZREG(t0)
- REG_S a1, 18*SZREG(t0)
- REG_S a1, 19*SZREG(t0)
- REG_S a1, 20*SZREG(t0)
- REG_S a1, 21*SZREG(t0)
- REG_S a1, 22*SZREG(t0)
- REG_S a1, 23*SZREG(t0)
- REG_S a1, 24*SZREG(t0)
- REG_S a1, 25*SZREG(t0)
- REG_S a1, 26*SZREG(t0)
- REG_S a1, 27*SZREG(t0)
- REG_S a1, 28*SZREG(t0)
- REG_S a1, 29*SZREG(t0)
- REG_S a1, 30*SZREG(t0)
- REG_S a1, 31*SZREG(t0)
- addi t0, t0, 32*SZREG
- bltu t0, a3, 3b
- andi a2, a2, SZREG-1 /* Update count */
-
-4:
- /* Handle trailing misalignment */
- beqz a2, 6f
- add a3, t0, a2
-5:
- sb a1, 0(t0)
- addi t0, t0, 1
- bltu t0, a3, 5b
-6:
- ret
-END(__memset)
diff --git a/arch/riscv/lib/string.c b/arch/riscv/lib/string.c
index bd52581e2068..7fc9ec5c26a7 100644
--- a/arch/riscv/lib/string.c
+++ b/arch/riscv/lib/string.c
@@ -112,3 +112,44 @@ EXPORT_SYMBOL(__memmove);
void *memmove(void *dest, const void *src, size_t count) __weak __alias(__memmove);
EXPORT_SYMBOL(memmove);
+
+void *__memset(void *s, int c, size_t count)
+{
+ union types dest = { .as_u8 = s };
+
+ if (count >= MIN_THRESHOLD) {
+ unsigned long cu = (unsigned long)c;
+
+ /* Compose an ulong with 'c' repeated 4/8 times */
+#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
+ cu *= 0x0101010101010101UL;
+#else
+ cu |= cu << 8;
+ cu |= cu << 16;
+ /* Suppress warning on 32 bit machines */
+ cu |= (cu << 16) << 16;
+#endif
+ if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
+ /*
+ * Fill the buffer one byte at time until
+ * the destination is word aligned.
+ */
+ for (; count && dest.as_uptr & WORD_MASK; count--)
+ *dest.as_u8++ = c;
+ }
+
+ /* Copy using the largest size allowed */
+ for (; count >= BYTES_LONG; count -= BYTES_LONG)
+ *dest.as_ulong++ = cu;
+ }
+
+ /* copy the remainder */
+ while (count--)
+ *dest.as_u8++ = c;
+
+ return s;
+}
+EXPORT_SYMBOL(__memset);
+
+void *memset(void *s, int c, size_t count) __weak __alias(__memset);
+EXPORT_SYMBOL(memset);
diff --git a/arch/riscv/purgatory/Makefile b/arch/riscv/purgatory/Makefile
index cdac455aa044..59991f835924 100644
--- a/arch/riscv/purgatory/Makefile
+++ b/arch/riscv/purgatory/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
OBJECT_FILES_NON_STANDARD := y
-purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o rvstring.o memset.o
+purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o rvstring.o
targets += $(purgatory-y)
PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
@@ -15,9 +15,6 @@ $(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE
$(obj)/rvstring.o: $(srctree)/arch/riscv/lib/string.c FORCE
$(call if_changed_rule,cc_o_c)
-$(obj)/memset.o: $(srctree)/arch/riscv/lib/memset.S FORCE
- $(call if_changed_rule,as_o_S)
-
$(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
$(call if_changed_rule,cc_o_c)
--
Armbian

View File

@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Thu, 25 Nov 2021 14:21:18 +0100
Subject: riscv: dts: starfive: Group tuples in interrupt properties
To improve human readability and enable automatic validation, the tuples
in the various properties containing interrupt specifiers should be
grouped.
Fix this by grouping the tuples of "interrupts-extended" properties
using angle brackets.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
arch/riscv/boot/dts/starfive/jh7100.dtsi | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
index 000447482aca..08eca47b5f29 100644
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -118,15 +118,15 @@ soc {
clint: clint@2000000 {
compatible = "starfive,jh7100-clint", "sifive,clint0";
reg = <0x0 0x2000000 0x0 0x10000>;
- interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7
- &cpu1_intc 3 &cpu1_intc 7>;
+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
+ <&cpu1_intc 3>, <&cpu1_intc 7>;
};
plic: interrupt-controller@c000000 {
compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0";
reg = <0x0 0xc000000 0x0 0x4000000>;
- interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9
- &cpu1_intc 11 &cpu1_intc 9>;
+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
+ <&cpu1_intc 11>, <&cpu1_intc 9>;
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
--
Armbian

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 20 Nov 2021 17:13:22 +0100
Subject: RISC-V: Add StarFive JH7100 audio clock node
Add device tree node for the audio clocks on the StarFive JH7100 RISC-V
SoC.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
index 08eca47b5f29..571667b984c9 100644
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -133,6 +133,16 @@ plic: interrupt-controller@c000000 {
riscv,ndev = <133>;
};
+ audclk: clock-controller@10480000 {
+ compatible = "starfive,jh7100-audclk";
+ reg = <0x0 0x10480000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_AUDIO_SRC>,
+ <&clkgen JH7100_CLK_AUDIO_12288>,
+ <&clkgen JH7100_CLK_DOM7AHB_BUS>;
+ clock-names = "audio_src", "audio_12288", "dom7ahb_bus";
+ #clock-cells = <1>;
+ };
+
clkgen: clock-controller@11800000 {
compatible = "starfive,jh7100-clkgen";
reg = <0x0 0x11800000 0x0 0x10000>;
--
Armbian

View File

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Wed, 31 Aug 2022 22:54:07 +0200
Subject: RISC-V: Mark StarFive JH7100 as having non-coherent DMAs
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/boot/dts/starfive/jh7100.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
index 571667b984c9..0b948f61e253 100644
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -111,6 +111,7 @@ gmac_gr_mii_rxclk: gmac_gr_mii_rxclk {
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
+ dma-noncoherent;
#address-cells = <2>;
#size-cells = <2>;
ranges;
--
Armbian

View File

@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 20 Nov 2021 19:29:25 +0100
Subject: dt-bindings: reset: Add StarFive JH7100 audio reset definitions
Add all resets for the StarFive JH7100 audio reset controller.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
include/dt-bindings/reset/starfive-jh7100-audio.h | 31 ++++++++++
1 file changed, 31 insertions(+)
diff --git a/include/dt-bindings/reset/starfive-jh7100-audio.h b/include/dt-bindings/reset/starfive-jh7100-audio.h
new file mode 100644
index 000000000000..30e3d4cf067a
--- /dev/null
+++ b/include/dt-bindings/reset/starfive-jh7100-audio.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2021 Emil Renner Berthing
+ */
+
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
+#define __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
+
+#define JH7100_AUDRSTN_APB_BUS 0
+#define JH7100_AUDRSTN_I2SADC_APB 1
+#define JH7100_AUDRSTN_I2SADC_SRST 2
+#define JH7100_AUDRSTN_PDM_APB 3
+#define JH7100_AUDRSTN_I2SVAD_APB 4
+#define JH7100_AUDRSTN_I2SVAD_SRST 5
+#define JH7100_AUDRSTN_SPDIF_APB 6
+#define JH7100_AUDRSTN_PWMDAC_APB 7
+#define JH7100_AUDRSTN_I2SDAC_APB 8
+#define JH7100_AUDRSTN_I2SDAC_SRST 9
+#define JH7100_AUDRSTN_I2S1_APB 10
+#define JH7100_AUDRSTN_I2S1_SRST 11
+#define JH7100_AUDRSTN_I2SDAC16K_APB 12
+#define JH7100_AUDRSTN_I2SDAC16K_SRST 13
+#define JH7100_AUDRSTN_DMA1P_AHB 14
+#define JH7100_AUDRSTN_USB_APB 15
+#define JH7100_AUDRST_USB_AXI 16
+#define JH7100_AUDRST_USB_PWRUP_RST_N 17
+#define JH7100_AUDRST_USB_PONRST 18
+
+#define JH7100_AUDRSTN_END 19
+
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__ */
--
Armbian

View File

@ -0,0 +1,60 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Tue, 7 Dec 2021 21:48:51 +0100
Subject: dt-bindings: reset: Add starfive,jh7100-audrst bindings
Add bindings for the audio reset controller on the StarFive JH7100
RISC-V SoC.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml | 38 ++++++++++
1 file changed, 38 insertions(+)
diff --git a/Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml b/Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
new file mode 100644
index 000000000000..6ed85cc84c95
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reset/starfive,jh7100-audrst.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7100 SoC Audio Reset Controller Device Tree Bindings
+
+maintainers:
+ - Emil Renner Berthing <kernel@esmil.dk>
+
+properties:
+ compatible:
+ enum:
+ - starfive,jh7100-audrst
+
+ reg:
+ maxItems: 1
+
+ "#reset-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ reset-controller@10490000 {
+ compatible = "starfive,jh7100-audrst";
+ reg = <0x10490000 0x10000>;
+ #reset-cells = <1>;
+ };
+
+...
--
Armbian

View File

@ -0,0 +1,106 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 20 Nov 2021 18:30:33 +0100
Subject: reset: Create subdirectory for StarFive drivers
This moves the StarFive JH7100 reset driver to a new subdirectory in
preparation for adding more StarFive reset drivers.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
MAINTAINERS | 2 +-
drivers/reset/Kconfig | 8 +-------
drivers/reset/Makefile | 2 +-
drivers/reset/starfive/Kconfig | 8 ++++++++
drivers/reset/starfive/Makefile | 2 ++
drivers/reset/{ => starfive}/reset-starfive-jh7100.c | 0
6 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index ee4ef9a73e7d..7a472ac625e1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19652,7 +19652,7 @@ STARFIVE JH7100 RESET CONTROLLER DRIVER
M: Emil Renner Berthing <kernel@esmil.dk>
S: Maintained
F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
-F: drivers/reset/reset-starfive-jh7100.c
+F: drivers/reset/starfive/reset-starfive-jh7100.c
F: include/dt-bindings/reset/starfive-jh7100.h
STATIC BRANCH/CALL
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index de176c2fbad9..1e8e1c4954cd 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -232,13 +232,6 @@ config RESET_SOCFPGA
This enables the reset driver for the SoCFPGA ARMv7 platforms. This
driver gets initialized early during platform init calls.
-config RESET_STARFIVE_JH7100
- bool "StarFive JH7100 Reset Driver"
- depends on SOC_STARFIVE || COMPILE_TEST
- default SOC_STARFIVE
- help
- This enables the reset controller driver for the StarFive JH7100 SoC.
-
config RESET_SUNPLUS
bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
default ARCH_SUNPLUS
@@ -320,6 +313,7 @@ config RESET_ZYNQ
help
This enables the reset controller driver for Xilinx Zynq SoCs.
+source "drivers/reset/starfive/Kconfig"
source "drivers/reset/sti/Kconfig"
source "drivers/reset/hisilicon/Kconfig"
source "drivers/reset/tegra/Kconfig"
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 3e7e5fd633a8..7fec5af6c964 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += core.o
obj-y += hisilicon/
+obj-y += starfive/
obj-$(CONFIG_ARCH_STI) += sti/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
@@ -30,7 +31,6 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
-obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
diff --git a/drivers/reset/starfive/Kconfig b/drivers/reset/starfive/Kconfig
new file mode 100644
index 000000000000..cddebdba7177
--- /dev/null
+++ b/drivers/reset/starfive/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config RESET_STARFIVE_JH7100
+ bool "StarFive JH7100 Reset Driver"
+ depends on SOC_STARFIVE || COMPILE_TEST
+ default SOC_STARFIVE
+ help
+ This enables the reset controller driver for the StarFive JH7100 SoC.
diff --git a/drivers/reset/starfive/Makefile b/drivers/reset/starfive/Makefile
new file mode 100644
index 000000000000..670d049423f5
--- /dev/null
+++ b/drivers/reset/starfive/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
diff --git a/drivers/reset/reset-starfive-jh7100.c b/drivers/reset/starfive/reset-starfive-jh7100.c
similarity index 100%
rename from drivers/reset/reset-starfive-jh7100.c
rename to drivers/reset/starfive/reset-starfive-jh7100.c
--
Armbian

View File

@ -0,0 +1,104 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Wed, 24 Nov 2021 01:30:54 +0100
Subject: reset: starfive: Use 32bit I/O on 32bit registers
The driver currently uses 64bit I/O on the 32bit registers. This works
because there are 4 assert registers and 4 status register, so they're
only ever accessed on 64bit boundaries.
There are however other reset controllers for audio and video on the SoC
with only one status register that isn't 64bit aligned so 64bit I/O
would result in an unaligned access exception.
Switch to 32bit I/O in preparation for supporting these resets too.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/reset/starfive/reset-starfive-jh7100.c | 40 +++++-----
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/reset/starfive/reset-starfive-jh7100.c b/drivers/reset/starfive/reset-starfive-jh7100.c
index fc44b2fb3e03..7563d317f5c8 100644
--- a/drivers/reset/starfive/reset-starfive-jh7100.c
+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
@@ -34,16 +34,16 @@
* lines don't though, so store the expected value of the status registers when
* all lines are asserted.
*/
-static const u64 jh7100_reset_asserted[2] = {
+static const u32 jh7100_reset_asserted[4] = {
/* STATUS0 */
- BIT_ULL_MASK(JH7100_RST_U74) |
- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
+ BIT(JH7100_RST_U74 % 32) |
+ BIT(JH7100_RST_VP6_DRESET % 32) |
+ BIT(JH7100_RST_VP6_BRESET % 32),
/* STATUS1 */
- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
+ BIT(JH7100_RST_HIFI4_DRESET % 32) |
+ BIT(JH7100_RST_HIFI4_BRESET % 32),
/* STATUS2 */
- BIT_ULL_MASK(JH7100_RST_E24) |
+ BIT(JH7100_RST_E24 % 32),
/* STATUS3 */
0,
};
@@ -65,12 +65,12 @@ static int jh7100_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct jh7100_reset *data = jh7100_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
- u64 done = jh7100_reset_asserted[offset] & mask;
- u64 value;
+ unsigned long offset = id / 32;
+ u32 mask = BIT(id % 32);
+ void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u32);
+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u32);
+ u32 done = jh7100_reset_asserted[offset] & mask;
+ u32 value;
unsigned long flags;
int ret;
@@ -79,15 +79,15 @@ static int jh7100_reset_update(struct reset_controller_dev *rcdev,
spin_lock_irqsave(&data->lock, flags);
- value = readq(reg_assert);
+ value = readl(reg_assert);
if (assert)
value |= mask;
else
value &= ~mask;
- writeq(value, reg_assert);
+ writel(value, reg_assert);
/* if the associated clock is gated, deasserting might otherwise hang forever */
- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
+ ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
spin_unlock_irqrestore(&data->lock, flags);
return ret;
@@ -121,10 +121,10 @@ static int jh7100_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct jh7100_reset *data = jh7100_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
- u64 value = readq(reg_status);
+ unsigned long offset = id / 32;
+ u32 mask = BIT(id % 32);
+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u32);
+ u32 value = readl(reg_status);
return !((value ^ jh7100_reset_asserted[offset]) & mask);
}
--
Armbian

View File

@ -0,0 +1,246 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 20 Nov 2021 19:30:49 +0100
Subject: reset: starfive: Add JH7100 audio reset driver
The audio resets are almost identical to the system resets, there are
just fewer of them. So factor out and export a generic probe function,
so most of the reset controller implementation can be shared.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
MAINTAINERS | 8 +-
drivers/reset/starfive/Kconfig | 7 ++
drivers/reset/starfive/Makefile | 1 +
drivers/reset/starfive/reset-starfive-jh7100-audio.c | 58 ++++++++++
drivers/reset/starfive/reset-starfive-jh7100.c | 37 ++++--
drivers/reset/starfive/reset-starfive-jh7100.h | 16 +++
6 files changed, 112 insertions(+), 15 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 7a472ac625e1..d54528018850 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19648,12 +19648,12 @@ F: Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
F: drivers/pinctrl/starfive/
F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
-STARFIVE JH7100 RESET CONTROLLER DRIVER
+STARFIVE JH7100 RESET CONTROLLER DRIVERS
M: Emil Renner Berthing <kernel@esmil.dk>
S: Maintained
-F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
-F: drivers/reset/starfive/reset-starfive-jh7100.c
-F: include/dt-bindings/reset/starfive-jh7100.h
+F: Documentation/devicetree/bindings/reset/starfive,jh7100-*.yaml
+F: drivers/reset/starfive/reset-starfive-jh7100*
+F: include/dt-bindings/reset/starfive-jh7100*.h
STATIC BRANCH/CALL
M: Peter Zijlstra <peterz@infradead.org>
diff --git a/drivers/reset/starfive/Kconfig b/drivers/reset/starfive/Kconfig
index cddebdba7177..5f88d3792d96 100644
--- a/drivers/reset/starfive/Kconfig
+++ b/drivers/reset/starfive/Kconfig
@@ -6,3 +6,10 @@ config RESET_STARFIVE_JH7100
default SOC_STARFIVE
help
This enables the reset controller driver for the StarFive JH7100 SoC.
+
+config RESET_STARFIVE_JH7100_AUDIO
+ tristate "StarFive JH7100 Audio Reset Driver"
+ depends on RESET_STARFIVE_JH7100
+ default m if SOC_STARFIVE
+ help
+ This enables the audio reset driver for the StarFive JH7100 SoC.
diff --git a/drivers/reset/starfive/Makefile b/drivers/reset/starfive/Makefile
index 670d049423f5..d3a55a75dd0f 100644
--- a/drivers/reset/starfive/Makefile
+++ b/drivers/reset/starfive/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
+obj-$(CONFIG_RESET_STARFIVE_JH7100_AUDIO) += reset-starfive-jh7100-audio.o
diff --git a/drivers/reset/starfive/reset-starfive-jh7100-audio.c b/drivers/reset/starfive/reset-starfive-jh7100-audio.c
new file mode 100644
index 000000000000..bae8f8c90d28
--- /dev/null
+++ b/drivers/reset/starfive/reset-starfive-jh7100-audio.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Audio reset driver for the StarFive JH7100 SoC
+ *
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/reset/starfive-jh7100-audio.h>
+
+#include "reset-starfive-jh7100.h"
+
+/* register offsets */
+#define JH7100_AUDRST_ASSERT0 0x00
+#define JH7100_AUDRST_STATUS0 0x04
+
+/*
+ * Writing a 1 to the n'th bit of the ASSERT register asserts
+ * line n, and writing a 0 deasserts the same line.
+ * Most reset lines have their status inverted so a 0 bit in the STATUS
+ * register means the line is asserted and a 1 means it's deasserted. A few
+ * lines don't though, so store the expected value of the status registers when
+ * all lines are asserted.
+ */
+static const u32 jh7100_audrst_asserted[1] = {
+ BIT(JH7100_AUDRST_USB_AXI) |
+ BIT(JH7100_AUDRST_USB_PWRUP_RST_N) |
+ BIT(JH7100_AUDRST_USB_PONRST)
+};
+
+static int jh7100_audrst_probe(struct platform_device *pdev)
+{
+ return reset_starfive_jh7100_generic_probe(pdev, jh7100_audrst_asserted,
+ JH7100_AUDRST_STATUS0, JH7100_AUDRSTN_END);
+}
+
+static const struct of_device_id jh7100_audrst_dt_ids[] = {
+ { .compatible = "starfive,jh7100-audrst" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh7100_audrst_dt_ids);
+
+static struct platform_driver jh7100_audrst_driver = {
+ .probe = jh7100_audrst_probe,
+ .driver = {
+ .name = "jh7100-reset-audio",
+ .of_match_table = jh7100_audrst_dt_ids,
+ },
+};
+module_platform_driver(jh7100_audrst_driver);
+
+MODULE_AUTHOR("Emil Renner Berthing");
+MODULE_DESCRIPTION("StarFive JH7100 audio reset driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/reset/starfive/reset-starfive-jh7100.c b/drivers/reset/starfive/reset-starfive-jh7100.c
index 7563d317f5c8..8e8733908c70 100644
--- a/drivers/reset/starfive/reset-starfive-jh7100.c
+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
@@ -16,6 +16,8 @@
#include <dt-bindings/reset/starfive-jh7100.h>
+#include "reset-starfive-jh7100.h"
+
/* register offsets */
#define JH7100_RESET_ASSERT0 0x00
#define JH7100_RESET_ASSERT1 0x04
@@ -52,7 +54,9 @@ struct jh7100_reset {
struct reset_controller_dev rcdev;
/* protect registers against concurrent read-modify-write */
spinlock_t lock;
- void __iomem *base;
+ void __iomem *assert;
+ void __iomem *status;
+ const u32 *asserted;
};
static inline struct jh7100_reset *
@@ -67,9 +71,9 @@ static int jh7100_reset_update(struct reset_controller_dev *rcdev,
struct jh7100_reset *data = jh7100_reset_from(rcdev);
unsigned long offset = id / 32;
u32 mask = BIT(id % 32);
- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u32);
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u32);
- u32 done = jh7100_reset_asserted[offset] & mask;
+ void __iomem *reg_assert = data->assert + offset * sizeof(u32);
+ void __iomem *reg_status = data->status + offset * sizeof(u32);
+ u32 done = data->asserted[offset] & mask;
u32 value;
unsigned long flags;
int ret;
@@ -123,10 +127,10 @@ static int jh7100_reset_status(struct reset_controller_dev *rcdev,
struct jh7100_reset *data = jh7100_reset_from(rcdev);
unsigned long offset = id / 32;
u32 mask = BIT(id % 32);
- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u32);
+ void __iomem *reg_status = data->status + offset * sizeof(u32);
u32 value = readl(reg_status);
- return !((value ^ jh7100_reset_asserted[offset]) & mask);
+ return !((value ^ data->asserted[offset]) & mask);
}
static const struct reset_control_ops jh7100_reset_ops = {
@@ -136,7 +140,8 @@ static const struct reset_control_ops jh7100_reset_ops = {
.status = jh7100_reset_status,
};
-static int __init jh7100_reset_probe(struct platform_device *pdev)
+int reset_starfive_jh7100_generic_probe(struct platform_device *pdev, const u32 *asserted,
+ unsigned int status_offset, unsigned int nr_resets)
{
struct jh7100_reset *data;
@@ -144,19 +149,29 @@ static int __init jh7100_reset_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
- data->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(data->base))
- return PTR_ERR(data->base);
+ data->assert = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(data->assert))
+ return PTR_ERR(data->assert);
data->rcdev.ops = &jh7100_reset_ops;
data->rcdev.owner = THIS_MODULE;
- data->rcdev.nr_resets = JH7100_RSTN_END;
+ data->rcdev.nr_resets = nr_resets;
data->rcdev.dev = &pdev->dev;
data->rcdev.of_node = pdev->dev.of_node;
+
spin_lock_init(&data->lock);
+ data->status = data->assert + status_offset;
+ data->asserted = asserted;
return devm_reset_controller_register(&pdev->dev, &data->rcdev);
}
+EXPORT_SYMBOL_GPL(reset_starfive_jh7100_generic_probe);
+
+static int __init jh7100_reset_probe(struct platform_device *pdev)
+{
+ return reset_starfive_jh7100_generic_probe(pdev, jh7100_reset_asserted,
+ JH7100_RESET_STATUS0, JH7100_RSTN_END);
+}
static const struct of_device_id jh7100_reset_dt_ids[] = {
{ .compatible = "starfive,jh7100-reset" },
diff --git a/drivers/reset/starfive/reset-starfive-jh7100.h b/drivers/reset/starfive/reset-starfive-jh7100.h
new file mode 100644
index 000000000000..ee8f3e3b1644
--- /dev/null
+++ b/drivers/reset/starfive/reset-starfive-jh7100.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#ifndef _RESET_STARFIVE_JH7100_H_
+#define _RESET_STARFIVE_JH7100_H_
+
+#include <linux/platform_device.h>
+
+int reset_starfive_jh7100_generic_probe(struct platform_device *pdev,
+ const u32 *asserted,
+ unsigned int status_offset,
+ unsigned int nr_resets);
+
+#endif
--
Armbian

View File

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 20 Nov 2021 21:33:08 +0100
Subject: RISC-V: Add StarFive JH7100 audio reset node
Add device tree node for the audio resets on the StarFive JH7100 RISC-V
SoC.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/boot/dts/starfive/jh7100.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
index 0b948f61e253..9f387fdf4afc 100644
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -144,6 +144,12 @@ audclk: clock-controller@10480000 {
#clock-cells = <1>;
};
+ audrst: reset-controller@10490000 {
+ compatible = "starfive,jh7100-audrst";
+ reg = <0x0 0x10490000 0x0 0x10000>;
+ #reset-cells = <1>;
+ };
+
clkgen: clock-controller@11800000 {
compatible = "starfive,jh7100-clkgen";
reg = <0x0 0x11800000 0x0 0x10000>;
--
Armbian

View File

@ -0,0 +1,98 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Thu, 14 Oct 2021 20:35:43 +0200
Subject: clk: starfive: jh7100: Keep more clocks alive
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/clk/starfive/clk-starfive-jh7100.c | 36 +++++-----
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/clk/starfive/clk-starfive-jh7100.c b/drivers/clk/starfive/clk-starfive-jh7100.c
index 691aeebc7092..86d9d52ca114 100644
--- a/drivers/clk/starfive/clk-starfive-jh7100.c
+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
@@ -99,9 +99,9 @@ static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
JH7100_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
JH7100_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
JH7100__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
- JH7100_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
- JH7100_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
- JH7100_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
+ JH7100_GATE(JH7100_CLK_DLA_AXI, "dla_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
+ JH7100_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
+ JH7100_GATE(JH7100_CLK_DLA_APB, "dla_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
JH7100_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
JH7100__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
JH7100_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
@@ -163,11 +163,11 @@ static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
JH7100_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
JH7100_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
JH7100__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
- JH7100_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
- JH7100_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
+ JH7100_GATE(JH7100_CLK_USB_AXI, "usb_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
+ JH7100_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
JH7100__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
- JH7100_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
- JH7100_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32, JH7100_CLK_USBPHY_ROOTDIV),
+ JH7100_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", CLK_IGNORE_UNUSED, 8, JH7100_CLK_USBPHY_ROOTDIV),
+ JH7100_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", CLK_IGNORE_UNUSED, 32, JH7100_CLK_USBPHY_ROOTDIV),
JH7100__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
JH7100_CLK_OSC_SYS,
JH7100_CLK_USBPHY_PLLDIV25M),
@@ -185,23 +185,23 @@ static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
JH7100__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
JH7100_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
JH7100_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
- JH7100_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
+ JH7100_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", CLK_IGNORE_UNUSED, 4, JH7100_CLK_VOUT_ROOT),
JH7100__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
JH7100__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
- JH7100_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
- JH7100_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
+ JH7100_GATE(JH7100_CLK_DISP_AXI, "disp_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
+ JH7100_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
JH7100_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
JH7100_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
JH7100__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
JH7100_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
JH7100_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
JH7100__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
- JH7100_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH7100_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", CLK_IGNORE_UNUSED, JH7100_CLK_AHB_BUS),
JH7100__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
- JH7100_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
- JH7100_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
- JH7100_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
- JH7100_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH7100_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", CLK_IGNORE_UNUSED, 31, JH7100_CLK_GMAC_ROOT_DIV),
+ JH7100_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", CLK_IGNORE_UNUSED, 255, JH7100_CLK_GMAC_ROOT_DIV),
+ JH7100_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH7100_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
JH7100__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
JH7100_CLK_GMAC_GTX,
JH7100_CLK_GMAC_TX_INV,
@@ -211,8 +211,8 @@ static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
JH7100_CLK_GMAC_GR_MII_RX,
JH7100_CLK_GMAC_RMII_RX),
JH7100__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
- JH7100_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
- JH7100_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
+ JH7100_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", CLK_IGNORE_UNUSED, JH7100_CLK_GMAC_RMII_REF),
+ JH7100_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", CLK_IGNORE_UNUSED, 127, JH7100_CLK_GMAC_ROOT_DIV),
JH7100_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
JH7100_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
JH7100_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
@@ -225,7 +225,7 @@ static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
JH7100_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
JH7100_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
JH7100_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
- JH7100_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
+ JH7100_GATE(JH7100_CLK_TRNG_APB, "trng_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
JH7100_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
JH7100_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
JH7100_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
--
Armbian

View File

@ -0,0 +1,134 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 17 Jul 2021 21:50:38 +0200
Subject: pinctrl: starfive: Reset pinmux settings
Current u-boot doesn't seem to take into account that some GPIOs are
configured as inputs/outputs of certain peripherals on power-up. This
means it ends up configuring some GPIOs as inputs to more than one
peripheral which the documentation explicitly says is illegal. Similarly
it also ends up configuring more than one GPIO as output of the same
peripheral. While not explicitly mentioned by the documentation this
also seems like a bad idea.
The easiest way to remedy this mess is to just disconnect all GPIOs from
peripherals and have our pinmux configuration set everything up
properly. This, however, means that we'd disconnect the serial console
from its pins for a while, so add a device tree property to keep
certain GPIOs from being reset.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml | 4 +
drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c | 66 ++++++++++
2 files changed, 70 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
index 69c0dd9998ea..ba3a664cf2ae 100644
--- a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
@@ -88,6 +88,10 @@ properties:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3, 4, 5, 6]
+ starfive,keep-gpiomux:
+ description: Keep pinmux for these GPIOs from being reset at boot.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
required:
- compatible
- reg
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
index 5b544fb7f3d8..4230633dce26 100644
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
@@ -200,6 +200,10 @@ static u16 starfive_drive_strength_from_max_mA(u32 i)
return (clamp(i, 14U, 63U) - 14) / 7;
}
+static bool keepmux;
+module_param(keepmux, bool, 0644);
+MODULE_PARM_DESC(keepmux, "Keep pinmux settings from previous boot stage");
+
struct starfive_pinctrl {
struct gpio_chip gc;
struct pinctrl_gpio_range gpios;
@@ -1222,6 +1226,65 @@ static void starfive_disable_clock(void *data)
clk_disable_unprepare(data);
}
+#define GPI_END (GPI_USB_OVER_CURRENT + 1)
+static void starfive_pinmux_reset(struct starfive_pinctrl *sfp)
+{
+ static const DECLARE_BITMAP(defaults, GPI_END) = {
+ BIT_MASK(GPI_I2C0_PAD_SCK_IN) |
+ BIT_MASK(GPI_I2C0_PAD_SDA_IN) |
+ BIT_MASK(GPI_I2C1_PAD_SCK_IN) |
+ BIT_MASK(GPI_I2C1_PAD_SDA_IN) |
+ BIT_MASK(GPI_I2C2_PAD_SCK_IN) |
+ BIT_MASK(GPI_I2C2_PAD_SDA_IN) |
+ BIT_MASK(GPI_I2C3_PAD_SCK_IN) |
+ BIT_MASK(GPI_I2C3_PAD_SDA_IN) |
+ BIT_MASK(GPI_SDIO0_PAD_CARD_DETECT_N) |
+
+ BIT_MASK(GPI_SDIO1_PAD_CARD_DETECT_N) |
+ BIT_MASK(GPI_SPI0_PAD_SS_IN_N) |
+ BIT_MASK(GPI_SPI1_PAD_SS_IN_N) |
+ BIT_MASK(GPI_SPI2_PAD_SS_IN_N) |
+ BIT_MASK(GPI_SPI2AHB_PAD_SS_N) |
+ BIT_MASK(GPI_SPI3_PAD_SS_IN_N),
+
+ BIT_MASK(GPI_UART0_PAD_SIN) |
+ BIT_MASK(GPI_UART1_PAD_SIN) |
+ BIT_MASK(GPI_UART2_PAD_SIN) |
+ BIT_MASK(GPI_UART3_PAD_SIN) |
+ BIT_MASK(GPI_USB_OVER_CURRENT)
+ };
+ DECLARE_BITMAP(keep, NR_GPIOS) = {};
+ struct device_node *np = sfp->gc.parent->of_node;
+ int len = of_property_count_u32_elems(np, "starfive,keep-gpiomux");
+ int i;
+
+ for (i = 0; i < len; i++) {
+ u32 gpio;
+
+ of_property_read_u32_index(np, "starfive,keep-gpiomux", i, &gpio);
+ if (gpio < NR_GPIOS)
+ set_bit(gpio, keep);
+ }
+
+ for (i = 0; i < NR_GPIOS; i++) {
+ if (test_bit(i, keep))
+ continue;
+
+ writel_relaxed(GPO_DISABLE, sfp->base + GPON_DOEN_CFG + 8 * i);
+ writel_relaxed(GPO_LOW, sfp->base + GPON_DOUT_CFG + 8 * i);
+ }
+
+ for (i = 0; i < GPI_END; i++) {
+ void __iomem *reg = sfp->base + GPI_CFG_OFFSET + 4 * i;
+ u32 din = readl_relaxed(reg);
+
+ if (din >= 2 && din < (NR_GPIOS + 2) && test_bit(din - 2, keep))
+ continue;
+
+ writel_relaxed(test_bit(i, defaults), reg);
+ }
+}
+
static int starfive_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1283,6 +1346,9 @@ static int starfive_probe(struct platform_device *pdev)
writel(value, sfp->padctl + IO_PADSHARE_SEL);
}
+ if (!keepmux)
+ starfive_pinmux_reset(sfp);
+
value = readl(sfp->padctl + IO_PADSHARE_SEL);
switch (value) {
case 0:
--
Armbian

View File

@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Thu, 14 Oct 2021 20:56:54 +0200
Subject: serial: 8250_dw: Add starfive,jh7100-hsuart compatible
This adds a compatible for the high speed UARTs on the StarFive JH7100
RISC-V SoC. Just like the regular uarts we also need to keep the input
clocks at their default rate and rely only on the divisor in the UART.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/tty/serial/8250/8250_dw.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 7db51781289e..b749f2805df7 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -777,6 +777,7 @@ static const struct of_device_id dw8250_of_match[] = {
{ .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
{ .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
{ .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
+ { .compatible = "starfive,jh7100-hsuart", .data = &dw8250_starfive_jh7100_data },
{ .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data },
{ /* Sentinel */ }
};
--
Armbian

View File

@ -0,0 +1,97 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sun, 6 Jun 2021 22:15:22 +0200
Subject: dt-bindings: hwmon: add starfive,jh71x0-temp bindings
Add bindings for the temperature sensor on the StarFive JH7100 and
JH7110 SoCs.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml | 75 ++++++++++
1 file changed, 75 insertions(+)
diff --git a/Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml b/Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
new file mode 100644
index 000000000000..232ef8797b29
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/starfive,jh71x0-temp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH71x0 Temperature Sensor
+
+maintainers:
+ - Emil Renner Berthing <kernel@esmil.dk>
+
+description: |
+ StarFive Technology Co. JH71x0 embedded temperature sensor
+
+properties:
+ compatible:
+ enum:
+ - starfive,jh7100-temp
+ - starfive,jh7110-temp
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 2
+ maxItems: 2
+
+ clock-names:
+ items:
+ - const: "sense"
+ - const: "bus"
+
+ '#thermal-sensor-cells':
+ const: 0
+
+ interrupts:
+ maxItems: 1
+
+ resets:
+ minItems: 2
+ maxItems: 2
+
+ reset-names:
+ items:
+ - const: "sense"
+ - const: "bus"
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - interrupts
+ - resets
+ - reset-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/starfive-jh7100.h>
+ #include <dt-bindings/reset/starfive-jh7100.h>
+
+ tmon: tmon@124a0000 {
+ compatible = "starfive,jh7100-temp";
+ reg = <0x124a0000 0x10000>;
+ clocks = <&clkgen JH7100_CLK_TEMP_SENSE>,
+ <&clkgen JH7100_CLK_TEMP_APB>;
+ clock-names = "sense", "bus";
+ #thermal-sensor-cells = <0>;
+ interrupts = <122>;
+ resets = <&rstgen JH7100_RSTN_TEMP_SENSE>,
+ <&rstgen JH7100_RSTN_TEMP_APB>;
+ reset-names = "sense", "bus";
+ };
--
Armbian

View File

@ -0,0 +1,481 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sun, 6 Jun 2021 22:31:18 +0200
Subject: hwmon: (sfctemp) Add StarFive JH71x0 temperature sensor
Register definitions and conversion constants based on sfctemp driver by
Samin in the StarFive 5.10 kernel.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
---
Documentation/hwmon/index.rst | 1 +
Documentation/hwmon/sfctemp.rst | 33 +
MAINTAINERS | 8 +
drivers/hwmon/Kconfig | 10 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/sfctemp.c | 350 ++++++++++
6 files changed, 403 insertions(+)
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index c1d11cf13eef..f7ede608b6e3 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -179,6 +179,7 @@ Hardware Monitoring Kernel Drivers
sch5627
sch5636
scpi-hwmon
+ sfctemp
sht15
sht21
sht3x
diff --git a/Documentation/hwmon/sfctemp.rst b/Documentation/hwmon/sfctemp.rst
new file mode 100644
index 000000000000..9fbd5bb1f356
--- /dev/null
+++ b/Documentation/hwmon/sfctemp.rst
@@ -0,0 +1,33 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver sfctemp
+=====================
+
+Supported chips:
+ - StarFive JH7100
+ - StarFive JH7110
+
+Authors:
+ - Emil Renner Berthing <kernel@esmil.dk>
+
+Description
+-----------
+
+This driver adds support for reading the built-in temperature sensor on the
+JH7100 and JH7110 RISC-V SoCs by StarFive Technology Co. Ltd.
+
+``sysfs`` interface
+-------------------
+
+The temperature sensor can be enabled, disabled and queried via the standard
+hwmon interface in sysfs under ``/sys/class/hwmon/hwmonX`` for some value of
+``X``:
+
+================ ==== =============================================
+Name Perm Description
+================ ==== =============================================
+temp1_enable RW Enable or disable temperature sensor.
+ Automatically enabled by the driver,
+ but may be disabled to save power.
+temp1_input RO Temperature reading in milli-degrees Celsius.
+================ ==== =============================================
diff --git a/MAINTAINERS b/MAINTAINERS
index d54528018850..c783fa9c9d85 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18662,6 +18662,14 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/sfc/
+SFCTEMP HWMON DRIVER
+M: Emil Renner Berthing <kernel@esmil.dk>
+L: linux-hwmon@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
+F: Documentation/hwmon/sfctemp.rst
+F: drivers/hwmon/sfctemp.c
+
SFF/SFP/SFP+ MODULE SUPPORT
M: Russell King <linux@armlinux.org.uk>
L: netdev@vger.kernel.org
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index d3bccc8176c5..bd3fa315f62a 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1911,6 +1911,16 @@ config SENSORS_STTS751
This driver can also be built as a module. If so, the module
will be called stts751.
+config SENSORS_SFCTEMP
+ tristate "Starfive JH71x0 temperature sensor"
+ depends on SOC_STARFIVE || COMPILE_TEST
+ help
+ If you say yes here you get support for temperature sensor
+ on the Starfive JH71x0 SoCs.
+
+ This driver can also be built as a module. If so, the module
+ will be called sfctemp.
+
config SENSORS_SMM665
tristate "Summit Microelectronics SMM665"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 11d076cad8a2..5a4a02c5535c 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -179,6 +179,7 @@ obj-$(CONFIG_SENSORS_SBRMI) += sbrmi.o
obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o
+obj-$(CONFIG_SENSORS_SFCTEMP) += sfctemp.o
obj-$(CONFIG_SENSORS_SL28CPLD) += sl28cpld-hwmon.o
obj-$(CONFIG_SENSORS_SHT15) += sht15.o
obj-$(CONFIG_SENSORS_SHT21) += sht21.o
diff --git a/drivers/hwmon/sfctemp.c b/drivers/hwmon/sfctemp.c
new file mode 100644
index 000000000000..e56716ad9587
--- /dev/null
+++ b/drivers/hwmon/sfctemp.c
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ * Copyright (C) 2021 Samin Guo <samin.guo@starfivetech.com>
+ */
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/hwmon.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+/*
+ * TempSensor reset. The RSTN can be de-asserted once the analog core has
+ * powered up. Trst(min 100ns)
+ * 0:reset 1:de-assert
+ */
+#define SFCTEMP_RSTN BIT(0)
+
+/*
+ * TempSensor analog core power down. The analog core will be powered up
+ * Tpu(min 50us) after PD is de-asserted. RSTN should be held low until the
+ * analog core is powered up.
+ * 0:power up 1:power down
+ */
+#define SFCTEMP_PD BIT(1)
+
+/*
+ * TempSensor start conversion enable.
+ * 0:disable 1:enable
+ */
+#define SFCTEMP_RUN BIT(2)
+
+/*
+ * TempSensor conversion value output.
+ * Temp(C)=DOUT*Y/4094 - K
+ */
+#define SFCTEMP_DOUT_POS 16
+#define SFCTEMP_DOUT_MSK GENMASK(27, 16)
+
+/* DOUT to Celcius conversion constants */
+#define SFCTEMP_Y1000 237500L
+#define SFCTEMP_Z 4094L
+#define SFCTEMP_K1000 81100L
+
+struct sfctemp {
+ /* serialize access to hardware register and enabled below */
+ struct mutex lock;
+ struct completion conversion_done;
+ void __iomem *regs;
+ struct clk *clk_sense;
+ struct clk *clk_bus;
+ struct reset_control *rst_sense;
+ struct reset_control *rst_bus;
+ bool enabled;
+};
+
+static irqreturn_t sfctemp_isr(int irq, void *data)
+{
+ struct sfctemp *sfctemp = data;
+
+ complete(&sfctemp->conversion_done);
+ return IRQ_HANDLED;
+}
+
+static void sfctemp_power_up(struct sfctemp *sfctemp)
+{
+ /* make sure we're powered down first */
+ writel(SFCTEMP_PD, sfctemp->regs);
+ udelay(1);
+
+ writel(0, sfctemp->regs);
+ /* wait t_pu(50us) + t_rst(100ns) */
+ usleep_range(60, 200);
+
+ /* de-assert reset */
+ writel(SFCTEMP_RSTN, sfctemp->regs);
+ udelay(1); /* wait t_su(500ps) */
+}
+
+static void sfctemp_power_down(struct sfctemp *sfctemp)
+{
+ writel(SFCTEMP_PD, sfctemp->regs);
+}
+
+static void sfctemp_run_single(struct sfctemp *sfctemp)
+{
+ writel(SFCTEMP_RSTN | SFCTEMP_RUN, sfctemp->regs);
+ udelay(1);
+ writel(SFCTEMP_RSTN, sfctemp->regs);
+}
+
+static int sfctemp_enable(struct sfctemp *sfctemp)
+{
+ int ret = 0;
+
+ mutex_lock(&sfctemp->lock);
+ if (sfctemp->enabled)
+ goto done;
+
+ ret = clk_prepare_enable(sfctemp->clk_bus);
+ if (ret)
+ goto err;
+ ret = reset_control_deassert(sfctemp->rst_bus);
+ if (ret)
+ goto err_disable_bus;
+
+ ret = clk_prepare_enable(sfctemp->clk_sense);
+ if (ret)
+ goto err_assert_bus;
+ ret = reset_control_deassert(sfctemp->rst_sense);
+ if (ret)
+ goto err_disable_sense;
+
+ sfctemp_power_up(sfctemp);
+ sfctemp->enabled = true;
+done:
+ mutex_unlock(&sfctemp->lock);
+ return ret;
+
+err_disable_sense:
+ clk_disable_unprepare(sfctemp->clk_sense);
+err_assert_bus:
+ reset_control_assert(sfctemp->rst_bus);
+err_disable_bus:
+ clk_disable_unprepare(sfctemp->clk_bus);
+err:
+ mutex_unlock(&sfctemp->lock);
+ return ret;
+}
+
+static int sfctemp_disable(struct sfctemp *sfctemp)
+{
+ mutex_lock(&sfctemp->lock);
+ if (!sfctemp->enabled)
+ goto done;
+
+ sfctemp_power_down(sfctemp);
+ reset_control_assert(sfctemp->rst_sense);
+ clk_disable_unprepare(sfctemp->clk_sense);
+ reset_control_assert(sfctemp->rst_bus);
+ clk_disable_unprepare(sfctemp->clk_bus);
+ sfctemp->enabled = false;
+done:
+ mutex_unlock(&sfctemp->lock);
+ return 0;
+}
+
+static void sfctemp_disable_action(void *data)
+{
+ sfctemp_disable(data);
+}
+
+static int sfctemp_convert(struct sfctemp *sfctemp, long *val)
+{
+ int ret;
+
+ mutex_lock(&sfctemp->lock);
+ if (!sfctemp->enabled) {
+ ret = -ENODATA;
+ goto out;
+ }
+
+ sfctemp_run_single(sfctemp);
+
+ ret = wait_for_completion_interruptible_timeout(&sfctemp->conversion_done,
+ msecs_to_jiffies(10));
+ if (ret <= 0) {
+ if (ret == 0)
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+
+ /* calculate temperature in milli Celcius */
+ *val = (long)((readl(sfctemp->regs) & SFCTEMP_DOUT_MSK) >> SFCTEMP_DOUT_POS)
+ * SFCTEMP_Y1000 / SFCTEMP_Z - SFCTEMP_K1000;
+
+ ret = 0;
+out:
+ mutex_unlock(&sfctemp->lock);
+ return ret;
+}
+
+static umode_t sfctemp_is_visible(const void *data, enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ switch (type) {
+ case hwmon_temp:
+ switch (attr) {
+ case hwmon_temp_enable:
+ return 0644;
+ case hwmon_temp_input:
+ return 0444;
+ }
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+static int sfctemp_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+{
+ struct sfctemp *sfctemp = dev_get_drvdata(dev);
+
+ switch (type) {
+ case hwmon_temp:
+ switch (attr) {
+ case hwmon_temp_enable:
+ *val = sfctemp->enabled;
+ return 0;
+ case hwmon_temp_input:
+ return sfctemp_convert(sfctemp, val);
+ }
+ return -EINVAL;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int sfctemp_write(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long val)
+{
+ struct sfctemp *sfctemp = dev_get_drvdata(dev);
+
+ switch (type) {
+ case hwmon_temp:
+ switch (attr) {
+ case hwmon_temp_enable:
+ if (val == 0)
+ return sfctemp_disable(sfctemp);
+ if (val == 1)
+ return sfctemp_enable(sfctemp);
+ break;
+ }
+ return -EINVAL;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct hwmon_channel_info *sfctemp_info[] = {
+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
+ HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT),
+ NULL
+};
+
+static const struct hwmon_ops sfctemp_hwmon_ops = {
+ .is_visible = sfctemp_is_visible,
+ .read = sfctemp_read,
+ .write = sfctemp_write,
+};
+
+static const struct hwmon_chip_info sfctemp_chip_info = {
+ .ops = &sfctemp_hwmon_ops,
+ .info = sfctemp_info,
+};
+
+static int sfctemp_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device *hwmon_dev;
+ struct sfctemp *sfctemp;
+ int ret;
+
+ sfctemp = devm_kzalloc(dev, sizeof(*sfctemp), GFP_KERNEL);
+ if (!sfctemp)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, sfctemp);
+ mutex_init(&sfctemp->lock);
+ init_completion(&sfctemp->conversion_done);
+
+ sfctemp->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(sfctemp->regs))
+ return PTR_ERR(sfctemp->regs);
+
+ sfctemp->clk_sense = devm_clk_get(dev, "sense");
+ if (IS_ERR(sfctemp->clk_sense))
+ return dev_err_probe(dev, PTR_ERR(sfctemp->clk_sense),
+ "error getting sense clock\n");
+
+ sfctemp->clk_bus = devm_clk_get(dev, "bus");
+ if (IS_ERR(sfctemp->clk_bus))
+ return dev_err_probe(dev, PTR_ERR(sfctemp->clk_bus),
+ "error getting bus clock\n");
+
+ sfctemp->rst_sense = devm_reset_control_get_exclusive(dev, "sense");
+ if (IS_ERR(sfctemp->rst_sense))
+ return dev_err_probe(dev, PTR_ERR(sfctemp->rst_sense),
+ "error getting sense reset\n");
+
+ sfctemp->rst_bus = devm_reset_control_get_exclusive(dev, "bus");
+ if (IS_ERR(sfctemp->rst_bus))
+ return dev_err_probe(dev, PTR_ERR(sfctemp->rst_bus),
+ "error getting busreset\n");
+
+ ret = reset_control_assert(sfctemp->rst_sense);
+ if (ret)
+ return dev_err_probe(dev, ret, "error asserting sense reset\n");
+
+ ret = reset_control_assert(sfctemp->rst_bus);
+ if (ret)
+ return dev_err_probe(dev, ret, "error asserting bus reset\n");
+
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = devm_request_irq(dev, ret, sfctemp_isr, 0, pdev->name, sfctemp);
+ if (ret)
+ return dev_err_probe(dev, ret, "error requesting irq\n");
+
+ ret = devm_add_action(dev, sfctemp_disable_action, sfctemp);
+ if (ret)
+ return ret;
+
+ ret = sfctemp_enable(sfctemp);
+ if (ret)
+ return dev_err_probe(dev, ret, "error enabling temperature sensor: %d\n", ret);
+
+ hwmon_dev = devm_hwmon_device_register_with_info(dev, pdev->name, sfctemp,
+ &sfctemp_chip_info, NULL);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct of_device_id sfctemp_of_match[] = {
+ { .compatible = "starfive,jh7100-temp" },
+ { .compatible = "starfive,jh7110-temp" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sfctemp_of_match);
+
+static struct platform_driver sfctemp_driver = {
+ .probe = sfctemp_probe,
+ .driver = {
+ .name = "sfctemp",
+ .of_match_table = sfctemp_of_match,
+ },
+};
+module_platform_driver(sfctemp_driver);
+
+MODULE_AUTHOR("Emil Renner Berthing");
+MODULE_DESCRIPTION("StarFive JH71x0 temperature sensor driver");
+MODULE_LICENSE("GPL");
--
Armbian

View File

@ -0,0 +1,818 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samin Guo <samin.guo@starfivetech.com>
Date: Wed, 17 Nov 2021 11:06:25 +0800
Subject: watchdog: Add StarFive SI5 watchdog driver
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/watchdog/Kconfig | 9 +
drivers/watchdog/Makefile | 3 +
drivers/watchdog/starfive-wdt.c | 761 ++++++++++
3 files changed, 773 insertions(+)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b64bc49c7f30..0d0f31d753f3 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -2082,6 +2082,15 @@ config UML_WATCHDOG
tristate "UML watchdog"
depends on UML || COMPILE_TEST
+# RISCV Architecture
+
+config STARFIVE_WATCHDOG
+ tristate "StarFive Watchdog support"
+ depends on RISCV
+ select WATCHDOG_CORE
+ help
+ Say Y here to support the starfive Si5 watchdog.
+
#
# ISA-based Watchdog Cards
#
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index d41e5f830ae7..9c22f1a43d5c 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -210,6 +210,9 @@ obj-$(CONFIG_WATCHDOG_SUN4V) += sun4v_wdt.o
# Xen
obj-$(CONFIG_XEN_WDT) += xen_wdt.o
+# RISCV Architecture
+obj-$(CONFIG_STARFIVE_WATCHDOG) += starfive-wdt.o
+
# Architecture Independent
obj-$(CONFIG_BD957XMUF_WATCHDOG) += bd9576_wdt.o
obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c
new file mode 100644
index 000000000000..5870a782994c
--- /dev/null
+++ b/drivers/watchdog/starfive-wdt.c
@@ -0,0 +1,761 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Watchdog driver for the StarFive JH7100 SoC
+ *
+ * Copyright (C) 2021 Samin Guo <samin.guo@starfivetech.com>
+ * Copyright (C) 2021 Walker Chen <walker.chen@starfivetech.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mfd/syscon.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+
+/* JH7100 WatchDog register define */
+#define JH7100_WDGINTSTAUS 0x000
+#define JH7100_WDOGCONTROL 0x104 /* Watchdog Control Register R/W */
+#define JH7100_WDOGLOAD 0x108 /* The initial value to be loaded */
+ /* into the counter and is also used */
+ /* as the reload value. R/W */
+#define JH7100_WDOGEN 0x110 /* Watchdog enable Register */
+#define JH7100_WDOGRELOAD 0x114 /* Write this register to reload preset */
+ /* value to counter. (Write 0 or 1 are both ok) */
+#define JH7100_WDOGVALUE 0x118 /* Watchdog Value Register RO */
+#define JH7100_WDOGINTCLR 0x120 /* Watchdog Clear Interrupt Register WO */
+#define JH7100_WDOGINTMSK 0x124 /* Watchdog Interrupt Mask Register */
+#define JH7100_WDOGLOCK 0x13c /* Watchdog Lock Register R/W */
+
+#define JH7100_UNLOCK_KEY 0x378f0765
+#define JH7100_RESEN_SHIFT 0
+#define JH7100_EN_SHIFT 0
+#define JH7100_INTCLR_AVA_SHIFT 1 /* Watchdog can clear interrupt when this bit is 0 */
+
+/* WDOGCONTROL */
+#define WDOG_INT_EN 0x0
+#define WDOG_RESET_EN 0x1
+
+/* WDOGLOCK */
+#define WDOG_LOCKED BIT(0)
+
+#define SI5_WATCHDOG_INTCLR 0x1
+#define SI5_WATCHDOG_ENABLE 0x1
+#define SI5_WATCHDOG_ATBOOT 0x0
+#define SI5_WATCHDOG_MAXCNT 0xffffffff
+
+#define SI5_WATCHDOG_DEFAULT_TIME (15)
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+static int tmr_margin;
+static int tmr_atboot = SI5_WATCHDOG_ATBOOT;
+static int soft_noboot;
+
+module_param(tmr_margin, int, 0);
+module_param(tmr_atboot, int, 0);
+module_param(nowayout, bool, 0);
+module_param(soft_noboot, int, 0);
+
+MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. (default="
+ __MODULE_STRING(SI5_WATCHDOG_DEFAULT_TIME) ")");
+MODULE_PARM_DESC(tmr_atboot,
+ "Watchdog is started at boot time if set to 1, default="
+ __MODULE_STRING(SI5_WATCHDOG_ATBOOT));
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default 0)");
+
+struct si5_wdt_variant_t {
+ u32 unlock_key;
+ u8 enrst_shift;
+ u8 en_shift;
+ u8 intclr_check;
+ u8 intclr_ava_shift;
+};
+
+struct si5_wdt_variant {
+ u32 control;
+ u32 load;
+ u32 enable;
+ u32 reload;
+ u32 value;
+ u32 int_clr;
+ u32 int_mask;
+ u32 unlock;
+ struct si5_wdt_variant_t *variant;
+};
+
+struct stf_si5_wdt {
+ u64 freq;
+ struct device *dev;
+ struct watchdog_device wdt_device;
+ struct clk *core_clk;
+ struct clk *apb_clk;
+ struct reset_control *rst_wdtimer_apb;
+ struct reset_control *rst_wdt;
+
+ const struct si5_wdt_variant *drv_data;
+ u32 count; /*count of timeout*/
+ u32 reload; /*restore the count*/
+ void __iomem *base;
+ spinlock_t lock;
+};
+
+#ifdef CONFIG_OF
+static struct si5_wdt_variant_t jh7100_variant = {
+ .unlock_key = JH7100_UNLOCK_KEY,
+ .enrst_shift = JH7100_RESEN_SHIFT,
+ .en_shift = JH7100_EN_SHIFT,
+ .intclr_check = 1,
+ .intclr_ava_shift = JH7100_INTCLR_AVA_SHIFT,
+};
+
+static const struct si5_wdt_variant drv_data_jh7100 = {
+ .control = JH7100_WDOGCONTROL,
+ .load = JH7100_WDOGLOAD,
+ .enable = JH7100_WDOGEN,
+ .reload = JH7100_WDOGRELOAD,
+ .value = JH7100_WDOGVALUE,
+ .int_clr = JH7100_WDOGINTCLR,
+ .int_mask = JH7100_WDOGINTMSK,
+ .unlock = JH7100_WDOGLOCK,
+ .variant = &jh7100_variant,
+};
+
+static const struct of_device_id starfive_wdt_match[] = {
+ { .compatible = "starfive,si5-wdt", .data = &drv_data_jh7100 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, starfive_wdt_match);
+#endif
+
+static const struct platform_device_id si5wdt_ids[] = {
+ {
+ .name = "starfive-si5-wdt",
+ .driver_data = (unsigned long)&drv_data_jh7100,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, si5wdt_ids);
+
+static int si5wdt_get_clock_rate(struct stf_si5_wdt *wdt)
+{
+ int ret;
+ u32 freq;
+
+ if (!IS_ERR(wdt->core_clk)) {
+ wdt->freq = clk_get_rate(wdt->core_clk);
+ return 0;
+ }
+
+ /* Next we try to get clock-frequency from dts.*/
+ ret = of_property_read_u32(wdt->dev->of_node, "clock-frequency", &freq);
+ if (!ret) {
+ wdt->freq = (u64)freq;
+ return 0;
+ }
+ else
+ dev_err(wdt->dev, "get rate failed, need clock-frequency define in dts.\n");
+
+ return -ENOENT;
+}
+
+static int si5wdt_enable_clock(struct stf_si5_wdt *wdt)
+{
+ int ret;
+
+ wdt->rst_wdtimer_apb = devm_reset_control_get_exclusive(wdt->dev, "wdtimer_apb");
+ if (IS_ERR(wdt->rst_wdtimer_apb))
+ return dev_err_probe(wdt->dev, PTR_ERR(wdt->rst_wdtimer_apb),
+ "failed to get apb reset\n");
+
+ wdt->rst_wdt = devm_reset_control_get_exclusive(wdt->dev, "wdt");
+ if (IS_ERR(wdt->rst_wdt))
+ return dev_err_probe(wdt->dev, PTR_ERR(wdt->rst_wdt),
+ "failed to get core reset\n");
+
+ wdt->apb_clk = devm_clk_get(wdt->dev, "wdtimer_apb");
+ if (IS_ERR(wdt->apb_clk))
+ return dev_err_probe(wdt->dev, PTR_ERR(wdt->apb_clk),
+ "failed to get apb clock\n");
+
+ wdt->core_clk = devm_clk_get(wdt->dev, "wdt_coreclk");
+ if (IS_ERR(wdt->core_clk))
+ return dev_err_probe(wdt->dev, PTR_ERR(wdt->core_clk),
+ "failed to get core clock\n");
+
+ ret = clk_prepare_enable(wdt->apb_clk);
+ if (ret)
+ return dev_err_probe(wdt->dev, ret, "failed to enable apb clock\n");
+
+ ret = clk_prepare_enable(wdt->core_clk);
+ if (ret)
+ return dev_err_probe(wdt->dev, ret, "failed to enable core clock\n");
+
+ ret = reset_control_assert(wdt->rst_wdtimer_apb);
+ if (ret)
+ return dev_err_probe(wdt->dev, ret, "failed to assert apb reset\n");
+
+ ret = reset_control_assert(wdt->rst_wdt);
+ if (ret)
+ return dev_err_probe(wdt->dev, ret, "failed to assert core reset\n");
+
+ ret = reset_control_deassert(wdt->rst_wdtimer_apb);
+ if (ret)
+ return dev_err_probe(wdt->dev, ret, "failed to deassert apb reset\n");
+
+ ret = reset_control_deassert(wdt->rst_wdt);
+ if (ret)
+ return dev_err_probe(wdt->dev, ret, "failed to deassert core reset\n");
+
+ return 0;
+}
+
+static __maybe_unused
+u32 si5wdt_sec_to_ticks(struct stf_si5_wdt *wdt, u32 sec)
+{
+ return sec * wdt->freq;
+}
+
+static __maybe_unused
+u32 si5wdt_ticks_to_sec(struct stf_si5_wdt *wdt, u32 ticks)
+{
+ return DIV_ROUND_CLOSEST(ticks, wdt->freq);
+}
+
+/*
+ * Write unlock-key to unlock. Write other value to lock. When lock bit is 1,
+ * external accesses to other watchdog registers are ignored.
+ */
+static int si5wdt_is_locked(struct stf_si5_wdt *wdt)
+{
+ u32 val;
+
+ val = readl(wdt->base + wdt->drv_data->unlock);
+ return !!(val & WDOG_LOCKED);
+}
+
+static void si5wdt_unlock(struct stf_si5_wdt *wdt)
+{
+ if (si5wdt_is_locked(wdt))
+ writel(wdt->drv_data->variant->unlock_key,
+ wdt->base + wdt->drv_data->unlock);
+}
+
+static void si5wdt_lock(struct stf_si5_wdt *wdt)
+{
+ if (!si5wdt_is_locked(wdt))
+ writel(~wdt->drv_data->variant->unlock_key,
+ wdt->base + wdt->drv_data->unlock);
+}
+
+static int __maybe_unused si5wdt_is_running(struct stf_si5_wdt *wdt)
+{
+ u32 val;
+
+ si5wdt_unlock(wdt);
+ val = readl(wdt->base + wdt->drv_data->enable);
+ si5wdt_lock(wdt);
+
+ return !!(val & SI5_WATCHDOG_ENABLE <<
+ wdt->drv_data->variant->en_shift);
+}
+
+static inline void si5wdt_int_enable(struct stf_si5_wdt *wdt)
+{
+ u32 val;
+
+ if (wdt->drv_data->int_mask) {
+ val = readl(wdt->base + wdt->drv_data->int_mask);
+ val &= ~(1<<0);
+ writel(val, wdt->base + wdt->drv_data->int_mask);
+ }
+}
+
+static inline void si5wdt_int_disable(struct stf_si5_wdt *wdt)
+{
+ u32 val;
+
+ if (wdt->drv_data->int_mask) {
+ val = readl(wdt->base + wdt->drv_data->int_mask);
+ val |= (1<<0);
+ writel(val, wdt->base + wdt->drv_data->int_mask);
+ }
+}
+
+static void si5wdt_enable_reset(struct stf_si5_wdt *wdt)
+{
+ u32 val;
+
+ val = readl(wdt->base + wdt->drv_data->control);
+ val |= WDOG_RESET_EN << wdt->drv_data->variant->enrst_shift;
+ /* enable wdog interrupt to reset */
+ writel(val, wdt->base + wdt->drv_data->control);
+}
+
+static void si5wdt_disable_reset(struct stf_si5_wdt *wdt)
+{
+ u32 val;
+
+ val = readl(wdt->base + wdt->drv_data->control);
+ val &= ~(WDOG_RESET_EN << wdt->drv_data->variant->enrst_shift);
+ /*disable wdog interrupt to reset*/
+ writel(val, wdt->base + wdt->drv_data->control);
+}
+
+static void si5wdt_int_clr(struct stf_si5_wdt *wdt)
+{
+ void __iomem *addr;
+ u8 clr_check;
+ u8 clr_ava_shift;
+
+ addr = wdt->base + wdt->drv_data->int_clr;
+ clr_ava_shift = wdt->drv_data->variant->intclr_ava_shift;
+ clr_check = wdt->drv_data->variant->intclr_check;
+ if (clr_check) {
+ /* waiting interrupt can be to clearing */
+ do {
+
+ } while (readl(addr) & BIT(clr_ava_shift));
+ }
+
+ writel(SI5_WATCHDOG_INTCLR, addr);
+}
+
+static inline void si5wdt_set_count(struct stf_si5_wdt *wdt, u32 val)
+{
+ writel(val, wdt->base + wdt->drv_data->load);
+}
+
+static inline u32 si5wdt_get_count(struct stf_si5_wdt *wdt)
+{
+ return readl(wdt->base + wdt->drv_data->value);
+}
+
+static inline void si5wdt_enable(struct stf_si5_wdt *wdt)
+{
+ u32 val;
+
+ val = readl(wdt->base + wdt->drv_data->enable);
+ val |= SI5_WATCHDOG_ENABLE << wdt->drv_data->variant->en_shift;
+ writel(val, wdt->base + wdt->drv_data->enable);
+}
+
+static inline void si5wdt_disable(struct stf_si5_wdt *wdt)
+{
+ u32 val;
+
+ val = readl(wdt->base + wdt->drv_data->enable);
+ val &= ~(SI5_WATCHDOG_ENABLE << wdt->drv_data->variant->en_shift);
+ writel(val, wdt->base + wdt->drv_data->enable);
+}
+
+static inline void
+si5wdt_set_relod_count(struct stf_si5_wdt *wdt, u32 count)
+{
+ writel(count, wdt->base + wdt->drv_data->load);
+ if (wdt->drv_data->reload)
+ writel(0x1, wdt->base + wdt->drv_data->reload);
+
+}
+
+static int si5wdt_mask_and_disable_reset(struct stf_si5_wdt *wdt, bool mask)
+{
+ si5wdt_unlock(wdt);
+
+ if (mask)
+ si5wdt_disable_reset(wdt);
+ else
+ si5wdt_enable_reset(wdt);
+
+ si5wdt_lock(wdt);
+
+ return 0;
+}
+
+static unsigned int si5wdt_max_timeout(struct stf_si5_wdt *wdt)
+{
+ return DIV_ROUND_UP(SI5_WATCHDOG_MAXCNT, wdt->freq) - 1;
+}
+
+static unsigned int si5wdt_get_timeleft(struct watchdog_device *wdd)
+{
+ struct stf_si5_wdt *wdt = watchdog_get_drvdata(wdd);
+ u32 count;
+
+ si5wdt_unlock(wdt);
+ count = si5wdt_get_count(wdt);
+ si5wdt_lock(wdt);
+
+ return si5wdt_ticks_to_sec(wdt, count);
+}
+
+static int si5wdt_keepalive(struct watchdog_device *wdd)
+{
+ struct stf_si5_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ spin_lock(&wdt->lock);
+
+ si5wdt_unlock(wdt);
+ si5wdt_set_relod_count(wdt, wdt->count);
+ si5wdt_lock(wdt);
+
+ spin_unlock(&wdt->lock);
+
+ return 0;
+}
+
+static irqreturn_t si5wdt_interrupt_handler(int irq, void *data)
+{
+ /*
+ * We don't clear the IRQ status. It's supposed to be done by the
+ * following ping operations.
+ */
+
+ return IRQ_HANDLED;
+}
+
+static int si5wdt_stop(struct watchdog_device *wdd)
+{
+ struct stf_si5_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ spin_lock(&wdt->lock);
+
+ si5wdt_unlock(wdt);
+ si5wdt_int_disable(wdt);
+ si5wdt_int_clr(wdt);
+ si5wdt_disable(wdt);
+ si5wdt_lock(wdt);
+
+ spin_unlock(&wdt->lock);
+
+ return 0;
+}
+
+static int si5wdt_start(struct watchdog_device *wdd)
+{
+ struct stf_si5_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ spin_lock(&wdt->lock);
+
+ si5wdt_unlock(wdt);
+
+ if (soft_noboot)
+ si5wdt_disable_reset(wdt);
+ else
+ si5wdt_enable_reset(wdt);
+
+ si5wdt_set_count(wdt, wdt->count);
+ si5wdt_int_enable(wdt);
+ si5wdt_enable(wdt);
+
+ si5wdt_lock(wdt);
+
+ spin_unlock(&wdt->lock);
+
+ return 0;
+}
+
+static int si5wdt_restart(struct watchdog_device *wdd, unsigned long action,
+ void *data)
+{
+ struct stf_si5_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ si5wdt_unlock(wdt);
+ /* disable watchdog, to be safe */
+ si5wdt_disable(wdt);
+
+ if (soft_noboot)
+ si5wdt_disable_reset(wdt);
+ else
+ si5wdt_enable_reset(wdt);
+
+ /* put initial values into count and data */
+ si5wdt_set_count(wdt, wdt->count);
+
+ /* set the watchdog to go and reset... */
+ si5wdt_int_clr(wdt);
+ si5wdt_int_enable(wdt);
+ si5wdt_enable(wdt);
+
+ /* wait for reset to assert... */
+ mdelay(500);
+
+ si5wdt_lock(wdt);
+
+ return 0;
+}
+
+static int si5wdt_set_timeout(struct watchdog_device *wdd,
+ unsigned int timeout)
+{
+ struct stf_si5_wdt *wdt = watchdog_get_drvdata(wdd);
+
+ unsigned long freq = wdt->freq;
+ unsigned int count;
+
+ if (timeout < 1)
+ return -EINVAL;
+
+ count = timeout * freq;
+
+ if (count > SI5_WATCHDOG_MAXCNT) {
+ dev_warn(wdt->dev, "timeout %d too big,use the MAX-timeout set.\n",
+ timeout);
+ timeout = si5wdt_max_timeout(wdt);
+ count = timeout * freq;
+ }
+
+ dev_info(wdt->dev, "Heartbeat: timeout=%d, count=%d (%08x)\n",
+ timeout, count, count);
+
+ si5wdt_unlock(wdt);
+ si5wdt_disable(wdt);
+ si5wdt_set_relod_count(wdt, count);
+ si5wdt_enable(wdt);
+ si5wdt_lock(wdt);
+
+ wdt->count = count;
+ wdd->timeout = timeout;
+
+ return 0;
+}
+
+#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
+
+static const struct watchdog_info si5_wdt_ident = {
+ .options = OPTIONS,
+ .firmware_version = 0,
+ .identity = "StarFive SI5 Watchdog",
+};
+
+static const struct watchdog_ops si5wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = si5wdt_start,
+ .stop = si5wdt_stop,
+ .ping = si5wdt_keepalive,
+ .set_timeout = si5wdt_set_timeout,
+ .restart = si5wdt_restart,
+ .get_timeleft = si5wdt_get_timeleft,
+};
+
+static const struct watchdog_device starfive_si5_wdd = {
+ .info = &si5_wdt_ident,
+ .ops = &si5wdt_ops,
+ .timeout = SI5_WATCHDOG_DEFAULT_TIME,
+};
+
+static inline const struct si5_wdt_variant *
+si5_get_wdt_drv_data(struct platform_device *pdev)
+{
+ const struct si5_wdt_variant *variant;
+
+ variant = of_device_get_match_data(&pdev->dev);
+ if (!variant) {
+ /* Device matched by platform_device_id */
+ variant = (struct si5_wdt_variant *)
+ platform_get_device_id(pdev)->driver_data;
+ }
+
+ return variant;
+}
+
+static int si5wdt_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct stf_si5_wdt *wdt;
+ int wdt_irq;
+ int ret;
+
+ wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
+ if (!wdt)
+ return -ENOMEM;
+
+ wdt->dev = dev;
+ spin_lock_init(&wdt->lock);
+ wdt->wdt_device = starfive_si5_wdd;
+
+ wdt->drv_data = si5_get_wdt_drv_data(pdev);
+
+ wdt_irq = platform_get_irq(pdev, 0);
+ if (wdt_irq < 0)
+ return wdt_irq;
+
+ /* get the memory region for the watchdog timer */
+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(wdt->base))
+ return PTR_ERR(wdt->base);
+
+ ret = si5wdt_enable_clock(wdt);
+ if (ret)
+ return ret;
+
+ si5wdt_get_clock_rate(wdt);
+
+ wdt->wdt_device.min_timeout = 1;
+ wdt->wdt_device.max_timeout = si5wdt_max_timeout(wdt);
+
+ watchdog_set_drvdata(&wdt->wdt_device, wdt);
+
+ /*
+ * see if we can actually set the requested timer margin,
+ * and if not, try the default value.
+ */
+ watchdog_init_timeout(&wdt->wdt_device, tmr_margin, dev);
+
+ ret = si5wdt_set_timeout(&wdt->wdt_device,
+ wdt->wdt_device.timeout);
+ if (ret) {
+ dev_info(dev, "tmr_margin value out of range, default %d used\n",
+ SI5_WATCHDOG_DEFAULT_TIME);
+ si5wdt_set_timeout(&wdt->wdt_device,
+ SI5_WATCHDOG_DEFAULT_TIME);
+ }
+
+ ret = devm_request_irq(dev, wdt_irq, si5wdt_interrupt_handler, 0,
+ pdev->name, pdev);
+ if (ret != 0) {
+ dev_err(dev, "failed to install irq (%d)\n", ret);
+ goto err;
+ }
+
+ watchdog_set_nowayout(&wdt->wdt_device, nowayout);
+ watchdog_set_restart_priority(&wdt->wdt_device, 128);
+
+ wdt->wdt_device.parent = dev;
+
+ ret = watchdog_register_device(&wdt->wdt_device);
+ if (ret)
+ goto err;
+
+ ret = si5wdt_mask_and_disable_reset(wdt, false);
+ if (ret < 0)
+ goto err_unregister;
+
+ if (tmr_atboot) {
+ dev_info(dev, "starting watchdog timer\n");
+ si5wdt_start(&wdt->wdt_device);
+ } else {
+
+ /*
+ * if we're not enabling the watchdog, then ensure it is
+ * disabled if it has been left running from the bootloader
+ * or other source.
+ */
+ si5wdt_stop(&wdt->wdt_device);
+ }
+
+ platform_set_drvdata(pdev, wdt);
+
+ return 0;
+
+ err_unregister:
+ watchdog_unregister_device(&wdt->wdt_device);
+
+ err:
+ return ret;
+}
+
+static int si5wdt_remove(struct platform_device *dev)
+{
+ int ret;
+ struct stf_si5_wdt *wdt = platform_get_drvdata(dev);
+
+ ret = si5wdt_mask_and_disable_reset(wdt, true);
+ if (ret < 0)
+ return ret;
+
+ watchdog_unregister_device(&wdt->wdt_device);
+
+ clk_disable_unprepare(wdt->core_clk);
+
+ return 0;
+}
+
+static void si5wdt_shutdown(struct platform_device *dev)
+{
+ struct stf_si5_wdt *wdt = platform_get_drvdata(dev);
+
+ si5wdt_mask_and_disable_reset(wdt, true);
+
+ si5wdt_stop(&wdt->wdt_device);
+
+}
+
+#ifdef CONFIG_PM_SLEEP
+
+static int si5wdt_suspend(struct device *dev)
+{
+ int ret;
+ struct stf_si5_wdt *wdt = dev_get_drvdata(dev);
+
+ si5wdt_unlock(wdt);
+
+ /* Save watchdog state, and turn it off. */
+ wdt->reload = si5wdt_get_count(wdt);
+
+ ret = si5wdt_mask_and_disable_reset(wdt, true);
+ if (ret < 0)
+ return ret;
+
+ /* Note that WTCNT doesn't need to be saved. */
+ si5wdt_stop(&wdt->wdt_device);
+
+ si5wdt_lock(wdt);
+
+ return 0;
+}
+
+static int si5wdt_resume(struct device *dev)
+{
+ int ret;
+ struct stf_si5_wdt *wdt = dev_get_drvdata(dev);
+
+ si5wdt_unlock(wdt);
+
+ /* Restore watchdog state. */
+ si5wdt_set_relod_count(wdt, wdt->reload);
+
+ ret = si5wdt_mask_and_disable_reset(wdt, false);
+ if (ret < 0)
+ return ret;
+
+ si5wdt_lock(wdt);
+
+ dev_info(dev, "watchdog resume\n")
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(si5wdt_pm_ops, si5wdt_suspend, si5wdt_resume);
+
+static struct platform_driver starfive_si5wdt_driver = {
+ .probe = si5wdt_probe,
+ .remove = si5wdt_remove,
+ .shutdown = si5wdt_shutdown,
+ .id_table = si5wdt_ids,
+ .driver = {
+ .name = "starfive-si5-wdt",
+ .pm = &si5wdt_pm_ops,
+ .of_match_table = of_match_ptr(starfive_wdt_match),
+ },
+};
+
+module_platform_driver(starfive_si5wdt_driver);
+
+MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
+MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
+MODULE_DESCRIPTION("StarFive SI5 Watchdog Device Driver");
+MODULE_LICENSE("GPL v2");
--
Armbian

View File

@ -0,0 +1,487 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Huan Feng <huan.feng@starfivetech.com>
Date: Fri, 8 Jan 2021 03:35:42 +0800
Subject: hwrng: Add StarFive JH7100 Random Number Generator driver
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/char/hw_random/Kconfig | 13 +
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/starfive-vic-rng.c | 256 ++++++++++
drivers/char/hw_random/starfive-vic-rng.h | 167 ++++++
4 files changed, 437 insertions(+)
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 3da8e85f8aae..f7f38b442c06 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -322,6 +322,19 @@ config HW_RANDOM_POWERNV
If unsure, say Y.
+config HW_RANDOM_STARFIVE_VIC
+ tristate "Starfive VIC Random Number Generator support"
+ depends on HW_RANDOM && (SOC_STARFIVE || COMPILE_TEST)
+ default SOC_STARFIVE
+ help
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on Starfive VIC SoC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called starfive-vic-rng.
+
+ If unsure, say Y.
+
config HW_RANDOM_HISI
tristate "Hisilicon Random Number Generator support"
depends on HW_RANDOM && ARCH_HISI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 3e948cf04476..157ea23aa46d 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
+obj-$(CONFIG_HW_RANDOM_STARFIVE_VIC) += starfive-vic-rng.o
obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
diff --git a/drivers/char/hw_random/starfive-vic-rng.c b/drivers/char/hw_random/starfive-vic-rng.c
new file mode 100644
index 000000000000..1e003b755a52
--- /dev/null
+++ b/drivers/char/hw_random/starfive-vic-rng.c
@@ -0,0 +1,256 @@
+/*
+ ******************************************************************************
+ * @file starfive-vic-rng.c
+ * @author StarFive Technology
+ * @version V1.0
+ * @date 08/13/2020
+ * @brief
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
+ */
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/random.h>
+
+#include "starfive-vic-rng.h"
+
+#define to_vic_rng(p) container_of(p, struct vic_rng, rng)
+
+struct vic_rng {
+ struct device *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)
+{
+ // clear register: ISTAT
+ 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) {
+ int res = 0;
+ // wait till idle
+ 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);
+ break;
+ default:
+ res = -1;
+ break;
+ }
+
+ return res;
+}
+
+static int vic_rng_init(struct hwrng *rng)
+{
+ struct vic_rng *hrng = to_vic_rng(rng);
+
+ // wait till idle
+
+ // 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 irqreturn_t vic_rng_irq(int irq, void *priv)
+{
+ u32 status, val;
+ struct vic_rng *hrng = (struct vic_rng *)priv;
+
+ /*
+ * clearing the interrupt will also clear the error register
+ * read error and status before clearing
+ */
+ status = readl(hrng->base + VIC_ISTAT);
+
+ if (status & VIC_ISTAT_ALARMS) {
+ writel(VIC_ISTAT_ALARMS, hrng->base + VIC_ISTAT);
+ val = readl(hrng->base + VIC_ALARM);
+ if (val & VIC_ALARM_ILLEGAL_CMD_SEQ) {
+ writel(VIC_ALARM_ILLEGAL_CMD_SEQ, hrng->base + VIC_ALARM);
+ //dev_info(hrng->dev, "ILLEGAL CMD SEQ: LAST_CMD=0x%x\r\n",
+ //VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)));
+ } else {
+ dev_info(hrng->dev, "Failed test: %x\r\n", val);
+ }
+ }
+
+ if (status & VIC_ISTAT_ZEROIZE) {
+ writel(VIC_ISTAT_ZEROIZE, hrng->base + VIC_ISTAT);
+ //dev_info(hrng->dev, "zeroized\r\n");
+ }
+
+ if (status & VIC_ISTAT_KAT_COMPLETE) {
+ writel(VIC_ISTAT_KAT_COMPLETE, hrng->base + VIC_ISTAT);
+ //dev_info(hrng->dev, "kat_completed\r\n");
+ }
+
+ if (status & VIC_ISTAT_NOISE_RDY) {
+ writel(VIC_ISTAT_NOISE_RDY, hrng->base + VIC_ISTAT);
+ //dev_info(hrng->dev, "noise_rdy\r\n");
+ }
+
+ if (status & VIC_ISTAT_DONE) {
+ writel(VIC_ISTAT_DONE, hrng->base + VIC_ISTAT);
+ //dev_info(hrng->dev, "done\r\n");
+ /*
+ if (VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)) ==
+ VIC_CTRL_CMD_GEN_RANDOM) {
+ dev_info(hrng->dev, "Need Update Buffer\r\n");
+ }
+ */
+ }
+ vic_rng_irq_mask_clear(hrng);
+
+ return IRQ_HANDLED;
+}
+
+static void vic_rng_cleanup(struct hwrng *rng)
+{
+ struct vic_rng *hrng = to_vic_rng(rng);
+
+ writel(0, hrng->base + VIC_CTRL);
+}
+
+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 platform_device *pdev)
+{
+ int ret;
+ int irq;
+ struct vic_rng *rng;
+ struct resource *res;
+
+ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+ if (!rng){
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, rng);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ rng->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(rng->base)){
+ return PTR_ERR(rng->base);
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(&pdev->dev, "Couldn't get irq %d\n", irq);
+ return irq;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq, vic_rng_irq, 0, pdev->name,
+ (void *)rng);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't get interrupt working.\n");
+ return ret;
+ }
+
+ rng->rng.name = pdev->name;
+ rng->rng.init = vic_rng_init;
+ rng->rng.cleanup = vic_rng_cleanup;
+ rng->rng.read = vic_rng_read;
+
+ rng->dev = &pdev->dev;
+
+ ret = devm_hwrng_register(&pdev->dev, &rng->rng);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register hwrng\n");
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "Initialized\n");
+
+ return 0;
+}
+
+static const struct of_device_id vic_rng_dt_ids[] = {
+ { .compatible = "starfive,vic-rng" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, vic_rng_dt_ids);
+
+static struct platform_driver vic_rng_driver = {
+ .probe = vic_rng_probe,
+ .driver = {
+ .name = "vic-rng",
+ .of_match_table = vic_rng_dt_ids,
+ },
+};
+
+module_platform_driver(vic_rng_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
+MODULE_DESCRIPTION("Starfive VIC random number generator driver");
diff --git a/drivers/char/hw_random/starfive-vic-rng.h b/drivers/char/hw_random/starfive-vic-rng.h
new file mode 100644
index 000000000000..b3bbabde0cfb
--- /dev/null
+++ b/drivers/char/hw_random/starfive-vic-rng.h
@@ -0,0 +1,167 @@
+/*
+ ******************************************************************************
+ * @file starfive-vic-rng.h
+ * @author StarFive Technology
+ * @version V1.0
+ * @date 08/13/2020
+ * @brief
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
+ */
+
+#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
+
+/* MODE */
+#define _VIC_MODE_ADDIN_PRESENT 4
+#define _VIC_MODE_PRED_RESIST 3
+#define _VIC_MODE_KAT_SEL 2
+#define _VIC_MODE_KAT_VEC 1
+#define _VIC_MODE_SEC_ALG 0
+
+#define VIC_MODE_ADDIN_PRESENT (1UL << _VIC_MODE_ADDIN_PRESENT)
+#define VIC_MODE_PRED_RESIST (1UL << _VIC_MODE_PRED_RESIST)
+#define VIC_MODE_KAT_SEL (1UL << _VIC_MODE_KAT_SEL)
+#define VIC_MODE_KAT_VEC (1UL << _VIC_MODE_KAT_VEC)
+#define VIC_MODE_SEC_ALG (1UL << _VIC_MODE_SEC_ALG)
+
+/* SMODE */
+#define _VIC_SMODE_MAX_REJECTS 2
+#define _VIC_SMODE_SECURE_EN 1
+#define _VIC_SMODE_NONCE 0
+
+#define VIC_SMODE_MAX_REJECTS(x) ((x) << _VIC_SMODE_MAX_REJECTS)
+#define VIC_SMODE_SECURE_EN(x) ((x) << _VIC_SMODE_SECURE_EN)
+#define VIC_SMODE_NONCE (1UL << _VIC_SMODE_NONCE)
+
+/* STAT */
+#define _VIC_STAT_BUSY 31
+#define _VIC_STAT_DRBG_STATE 7
+#define _VIC_STAT_SECURE 6
+#define _VIC_STAT_NONCE_MODE 5
+#define _VIC_STAT_SEC_ALG 4
+#define _VIC_STAT_LAST_CMD 0
+
+#define VIC_STAT_BUSY (1UL << _VIC_STAT_BUSY)
+#define VIC_STAT_DRBG_STATE (1UL << _VIC_STAT_DRBG_STATE)
+#define VIC_STAT_SECURE (1UL << _VIC_STAT_SECURE)
+#define VIC_STAT_NONCE_MODE (1UL << _VIC_STAT_NONCE_MODE)
+#define VIC_STAT_SEC_ALG (1UL << _VIC_STAT_SEC_ALG)
+#define VIC_STAT_LAST_CMD(x) (((x) >> _VIC_STAT_LAST_CMD) & 0xF)
+
+/* 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)
+
+/* ISTAT */
+#define _VIC_ISTAT_DONE 4
+#define _VIC_ISTAT_ALARMS 3
+#define _VIC_ISTAT_NOISE_RDY 2
+#define _VIC_ISTAT_KAT_COMPLETE 1
+#define _VIC_ISTAT_ZEROIZE 0
+
+#define VIC_ISTAT_DONE (1UL << _VIC_ISTAT_DONE)
+#define VIC_ISTAT_ALARMS (1UL << _VIC_ISTAT_ALARMS)
+#define VIC_ISTAT_NOISE_RDY (1UL << _VIC_ISTAT_NOISE_RDY)
+#define VIC_ISTAT_KAT_COMPLETE (1UL << _VIC_ISTAT_KAT_COMPLETE)
+#define VIC_ISTAT_ZEROIZE (1UL << _VIC_ISTAT_ZEROIZE)
+
+/* ALARMS */
+#define VIC_ALARM_ILLEGAL_CMD_SEQ (1UL << 4)
+#define VIC_ALARM_FAILED_TEST_ID_OK 0
+#define VIC_ALARM_FAILED_TEST_ID_KAT_STAT 1
+#define VIC_ALARM_FAILED_TEST_ID_KAT 2
+#define VIC_ALARM_FAILED_TEST_ID_MONOBIT 3
+#define VIC_ALARM_FAILED_TEST_ID_RUN 4
+#define VIC_ALARM_FAILED_TEST_ID_LONGRUN 5
+#define VIC_ALARM_FAILED_TEST_ID_AUTOCORRELATION 6
+#define VIC_ALARM_FAILED_TEST_ID_POKER 7
+#define VIC_ALARM_FAILED_TEST_ID_REPETITION_COUNT 8
+#define VIC_ALARM_FAILED_TEST_ID_ADAPATIVE_PROPORTION 9
+
+/* BUILD_ID */
+#define VIC_BUILD_ID_STEPPING(x) (((x) >> 28) & 0xF)
+#define VIC_BUILD_ID_EPN(x) ((x) & 0xFFFF)
+
+/* FEATURES */
+#define VIC_FEATURES_AES_256(x) (((x) >> 9) & 1)
+#define VIC_FEATURES_EXTRA_PS_PRESENT(x) (((x) >> 8) & 1)
+#define VIC_FEATURES_DIAG_LEVEL_NS(x) (((x) >> 7) & 1)
+#define VIC_FEATURES_DIAG_LEVEL_CLP800(x) (((x) >> 4) & 7)
+#define VIC_FEATURES_DIAG_LEVEL_ST_HLT(x) (((x) >> 1) & 7)
+#define VIC_FEATURES_SECURE_RST_STATE(x) ((x) & 1)
+
+/* IA_CMD */
+#define VIC_IA_CMD_GO (1UL << 31)
+#define VIC_IA_CMD_WR (1)
+
+#define _VIC_SMODE_MAX_REJECTS_MASK 255UL
+#define _VIC_SMODE_SECURE_EN_MASK 1UL
+#define _VIC_SMODE_NONCE_MASK 1UL
+#define _VIC_MODE_SEC_ALG_MASK 1UL
+#define _VIC_MODE_ADDIN_PRESENT_MASK 1UL
+#define _VIC_MODE_PRED_RESIST_MASK 1UL
+
+#define VIC_SMODE_SET_MAX_REJECTS(y, x) (((y) & ~(_VIC_SMODE_MAX_REJECTS_MASK << _VIC_SMODE_MAX_REJECTS)) | ((x) << _VIC_SMODE_MAX_REJECTS))
+#define VIC_SMODE_SET_SECURE_EN(y, x) (((y) & ~(_VIC_SMODE_SECURE_EN_MASK << _VIC_SMODE_SECURE_EN)) | ((x) << _VIC_SMODE_SECURE_EN))
+#define VIC_SMODE_SET_NONCE(y, x) (((y) & ~(_VIC_SMODE_NONCE_MASK << _VIC_SMODE_NONCE)) | ((x) << _VIC_SMODE_NONCE))
+#define VIC_SMODE_GET_MAX_REJECTS(x) (((x) >> _VIC_SMODE_MAX_REJECTS) & _VIC_SMODE_MAX_REJECTS_MASK)
+#define VIC_SMODE_GET_SECURE_EN(x) (((x) >> _VIC_SMODE_SECURE_EN) & _VIC_SMODE_SECURE_EN_MASK)
+#define VIC_SMODE_GET_NONCE(x) (((x) >> _VIC_SMODE_NONCE) & _VIC_SMODE_NONCE_MASK)
+
+#define VIC_MODE_SET_SEC_ALG(y, x) (((y) & ~(_VIC_MODE_SEC_ALG_MASK << _VIC_MODE_SEC_ALG)) | ((x) << _VIC_MODE_SEC_ALG))
+#define VIC_MODE_SET_PRED_RESIST(y, x) (((y) & ~(_VIC_MODE_PRED_RESIST_MASK << _VIC_MODE_PRED_RESIST)) | ((x) << _VIC_MODE_PRED_RESIST))
+#define VIC_MODE_SET_ADDIN_PRESENT(y, x) (((y) & ~(_VIC_MODE_ADDIN_PRESENT_MASK << _VIC_MODE_ADDIN_PRESENT)) | ((x) << _VIC_MODE_ADDIN_PRESENT))
+#define VIC_MODE_GET_SEC_ALG(x) (((x) >> _VIC_MODE_SEC_ALG) & _VIC_MODE_SEC_ALG_MASK)
+#define VIC_MODE_GET_PRED_RESIST(x) (((x) >> _VIC_MODE_PRED_RESIST) & _VIC_MODE_PRED_RESIST_MASK)
+#define VIC_MODE_GET_ADDIN_PRESENT(x) (((x) >> _VIC_MODE_ADDIN_PRESENT) & _VIC_MODE_ADDIN_PRESENT_MASK)
+
+#define VIC_RAND_LEN 4
--
Armbian

View File

@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Wed, 6 Apr 2022 01:04:45 +0200
Subject: dt-bindings: riscv: sifive-ccache: Support StarFive JH71x0 SoCs
This cache controller is also used on the StarFive JH7100 and JH7110
SoCs.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml b/Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml
index bf3f07421f7e..41eb60da04a4 100644
--- a/Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml
+++ b/Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml
@@ -25,6 +25,8 @@ select:
- sifive,ccache0
- sifive,fu540-c000-ccache
- sifive,fu740-c000-ccache
+ - starfive,jh7100-ccache
+ - starfive,jh7110-ccache
required:
- compatible
@@ -37,6 +39,8 @@ properties:
- sifive,ccache0
- sifive,fu540-c000-ccache
- sifive,fu740-c000-ccache
+ - starfive,jh7100-ccache
+ - starfive,jh7110-ccache
- const: cache
- items:
- const: microchip,mpfs-ccache
--
Armbian

View File

@ -0,0 +1,101 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Wed, 6 Apr 2022 00:38:05 +0200
Subject: soc: sifive: ccache: Add StarFive JH71x0 support
This adds support for the StarFive JH7100 and JH7110 SoCs which also
feature this SiFive cache controller.
Unfortunately the interrupt for uncorrected data is broken on the JH7100
and fires continuously, so add a quirk to not register a handler for it.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
Hacked-by: Ricardo Pardini <ricardo@pardini.net> for 6.1.y
---
arch/riscv/Kconfig.socs | 1 +
drivers/soc/Makefile | 2 +-
drivers/soc/sifive/Kconfig | 2 +-
drivers/soc/sifive/sifive_ccache.c | 12 +++++++++-
4 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 69774bb362d6..5a40e05f8cab 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -22,6 +22,7 @@ config SOC_STARFIVE
bool "StarFive SoCs"
select PINCTRL
select RESET_CONTROLLER
+ select SIFIVE_CCACHE
select SIFIVE_PLIC
help
This enables support for StarFive SoC platform hardware.
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 69ba6508cf2c..534669840858 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -26,7 +26,7 @@ obj-y += qcom/
obj-y += renesas/
obj-y += rockchip/
obj-$(CONFIG_SOC_SAMSUNG) += samsung/
-obj-$(CONFIG_SOC_SIFIVE) += sifive/
+obj-y += sifive/
obj-y += sunxi/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-y += ti/
diff --git a/drivers/soc/sifive/Kconfig b/drivers/soc/sifive/Kconfig
index ed4c571f8771..e86870be34c9 100644
--- a/drivers/soc/sifive/Kconfig
+++ b/drivers/soc/sifive/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-if SOC_SIFIVE
+if SOC_SIFIVE || SOC_STARFIVE
config SIFIVE_CCACHE
bool "Sifive Composable Cache controller"
diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
index 3684f5b40a80..fd5f0c7b060f 100644
--- a/drivers/soc/sifive/sifive_ccache.c
+++ b/drivers/soc/sifive/sifive_ccache.c
@@ -106,6 +106,8 @@ static void ccache_config_read(void)
static const struct of_device_id sifive_ccache_ids[] = {
{ .compatible = "sifive,fu540-c000-ccache" },
{ .compatible = "sifive,fu740-c000-ccache" },
+ { .compatible = "starfive,jh7100-ccache", .data = (void *)BIT(DATA_UNCORR) },
+ { .compatible = "starfive,jh7110-ccache" },
{ .compatible = "sifive,ccache0" },
{ /* end of table */ }
};
@@ -210,11 +212,15 @@ static int __init sifive_ccache_init(void)
struct device_node *np;
struct resource res;
int i, rc, intr_num;
+ const struct of_device_id *match;
+ unsigned long broken_irqs;
- np = of_find_matching_node(NULL, sifive_ccache_ids);
+ np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
if (!np)
return -ENODEV;
+ broken_irqs = (uintptr_t)match->data;
+
if (of_address_to_resource(np, 0, &res)) {
rc = -ENODEV;
goto err_node_put;
@@ -240,6 +246,10 @@ static int __init sifive_ccache_init(void)
for (i = 0; i < intr_num; i++) {
g_irq[i] = irq_of_parse_and_map(np, i);
+
+ if (broken_irqs & BIT(i))
+ continue;
+
rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc",
NULL);
if (rc) {
--
Armbian

View File

@ -0,0 +1,166 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 12 Jun 2021 16:48:31 -0700
Subject: soc: sifive: ccache: Add non-coherent DMA handling
Add functions to flush the caches and handle non-coherent DMA.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/soc/sifive/sifive_ccache.c | 60 +++++++++-
include/soc/sifive/sifive_ccache.h | 21 ++++
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c
index fd5f0c7b060f..4352c203f84d 100644
--- a/drivers/soc/sifive/sifive_ccache.c
+++ b/drivers/soc/sifive/sifive_ccache.c
@@ -8,13 +8,16 @@
#define pr_fmt(fmt) "CCACHE: " fmt
+#include <linux/align.h>
#include <linux/debugfs.h>
#include <linux/interrupt.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/device.h>
#include <linux/bitfield.h>
+#include <asm/cacheflush.h>
#include <asm/cacheinfo.h>
+#include <asm/page.h>
#include <soc/sifive/sifive_ccache.h>
#define SIFIVE_CCACHE_DIRECCFIX_LOW 0x100
@@ -39,10 +42,14 @@
#define SIFIVE_CCACHE_CONFIG_SETS_MASK GENMASK_ULL(23, 16)
#define SIFIVE_CCACHE_CONFIG_BLKS_MASK GENMASK_ULL(31, 24)
+#define SIFIVE_CCACHE_FLUSH64 0x200
+#define SIFIVE_CCACHE_FLUSH32 0x240
+
#define SIFIVE_CCACHE_WAYENABLE 0x08
#define SIFIVE_CCACHE_ECCINJECTERR 0x40
#define SIFIVE_CCACHE_MAX_ECCINTR 4
+#define SIFIVE_CCACHE_LINE_SIZE 64
static void __iomem *ccache_base;
static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR];
@@ -126,6 +133,47 @@ int unregister_sifive_ccache_error_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier);
+#ifdef CONFIG_RISCV_DMA_NONCOHERENT
+static phys_addr_t uncached_offset;
+DEFINE_STATIC_KEY_FALSE(sifive_ccache_handle_noncoherent_key);
+
+void sifive_ccache_flush_range(phys_addr_t start, size_t len)
+{
+ phys_addr_t end = start + len;
+ phys_addr_t line;
+
+ if (!len)
+ return;
+
+ mb();
+ for (line = ALIGN_DOWN(start, SIFIVE_CCACHE_LINE_SIZE); line < end;
+ line += SIFIVE_CCACHE_LINE_SIZE) {
+#ifdef CONFIG_32BIT
+ writel(line >> 4, ccache_base + SIFIVE_CCACHE_FLUSH32);
+#else
+ writeq(line, ccache_base + SIFIVE_CCACHE_FLUSH64);
+#endif
+ mb();
+ }
+}
+EXPORT_SYMBOL_GPL(sifive_ccache_flush_range);
+
+void *sifive_ccache_set_uncached(void *addr, size_t size)
+{
+ phys_addr_t phys_addr = __pa(addr) + uncached_offset;
+ void *mem_base;
+
+ mem_base = memremap(phys_addr, size, MEMREMAP_WT);
+ if (!mem_base) {
+ pr_err("%s memremap failed for addr %p\n", __func__, addr);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return mem_base;
+}
+EXPORT_SYMBOL_GPL(sifive_ccache_set_uncached);
+#endif /* CONFIG_RISCV_DMA_NONCOHERENT */
+
static int ccache_largest_wayenabled(void)
{
return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF;
@@ -214,6 +262,7 @@ static int __init sifive_ccache_init(void)
int i, rc, intr_num;
const struct of_device_id *match;
unsigned long broken_irqs;
+ u64 __maybe_unused offset;
np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
if (!np)
@@ -259,6 +308,15 @@ static int __init sifive_ccache_init(void)
}
of_node_put(np);
+#ifdef CONFIG_RISCV_DMA_NONCOHERENT
+ if (!of_property_read_u64(np, "uncached-offset", &offset)) {
+ uncached_offset = offset;
+ static_branch_enable(&sifive_ccache_handle_noncoherent_key);
+ riscv_cbom_block_size = SIFIVE_CCACHE_LINE_SIZE;
+ riscv_noncoherent_supported();
+ }
+#endif
+
ccache_config_read();
ccache_cache_ops.get_priv_group = ccache_get_priv_group;
@@ -279,4 +337,4 @@ static int __init sifive_ccache_init(void)
return rc;
}
-device_initcall(sifive_ccache_init);
+arch_initcall(sifive_ccache_init);
diff --git a/include/soc/sifive/sifive_ccache.h b/include/soc/sifive/sifive_ccache.h
index 4d4ed49388a0..d349ccb3969b 100644
--- a/include/soc/sifive/sifive_ccache.h
+++ b/include/soc/sifive/sifive_ccache.h
@@ -7,10 +7,31 @@
#ifndef __SOC_SIFIVE_CCACHE_H
#define __SOC_SIFIVE_CCACHE_H
+#include <linux/io.h>
+#include <linux/jump_label.h>
+
extern int register_sifive_ccache_error_notifier(struct notifier_block *nb);
extern int unregister_sifive_ccache_error_notifier(struct notifier_block *nb);
#define SIFIVE_CCACHE_ERR_TYPE_CE 0
#define SIFIVE_CCACHE_ERR_TYPE_UE 1
+DECLARE_STATIC_KEY_FALSE(sifive_ccache_handle_noncoherent_key);
+
+static inline bool sifive_ccache_handle_noncoherent(void)
+{
+#ifdef CONFIG_SIFIVE_CCACHE
+ return static_branch_unlikely(&sifive_ccache_handle_noncoherent_key);
+#else
+ return false;
+#endif
+}
+
+void sifive_ccache_flush_range(phys_addr_t start, size_t len);
+void *sifive_ccache_set_uncached(void *addr, size_t size);
+static inline void sifive_ccache_clear_uncached(void *addr, size_t size)
+{
+ memunmap(addr);
+}
+
#endif /* __SOC_SIFIVE_CCACHE_H */
--
Armbian

View File

@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 12 Jun 2021 16:48:31 -0700
Subject: riscv: Implement non-coherent DMA support via SiFive cache flushing
This variant is used on the StarFive JH7100 SoC.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
arch/riscv/Kconfig | 6 +-
arch/riscv/mm/dma-noncoherent.c | 37 +++++++++-
2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 8e5fd5682018..63234a5e84ac 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -223,12 +223,14 @@ config LOCKDEP_SUPPORT
def_bool y
config RISCV_DMA_NONCOHERENT
- bool
+ bool "Support non-coherent DMA"
+ default SOC_STARFIVE
select ARCH_HAS_DMA_PREP_COHERENT
+ select ARCH_HAS_DMA_SET_UNCACHED
+ select ARCH_HAS_DMA_CLEAR_UNCACHED
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SETUP_DMA_OPS
- select DMA_DIRECT_REMAP
config AS_HAS_INSN
def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
index d919efab6eba..e07e53aea537 100644
--- a/arch/riscv/mm/dma-noncoherent.c
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -9,14 +9,21 @@
#include <linux/dma-map-ops.h>
#include <linux/mm.h>
#include <asm/cacheflush.h>
+#include <soc/sifive/sifive_ccache.h>
static bool noncoherent_supported;
void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
enum dma_data_direction dir)
{
- void *vaddr = phys_to_virt(paddr);
+ void *vaddr;
+ if (sifive_ccache_handle_noncoherent()) {
+ sifive_ccache_flush_range(paddr, size);
+ return;
+ }
+
+ vaddr = phys_to_virt(paddr);
switch (dir) {
case DMA_TO_DEVICE:
ALT_CMO_OP(clean, vaddr, size, riscv_cbom_block_size);
@@ -35,8 +42,14 @@ void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
enum dma_data_direction dir)
{
- void *vaddr = phys_to_virt(paddr);
+ void *vaddr;
+
+ if (sifive_ccache_handle_noncoherent()) {
+ sifive_ccache_flush_range(paddr, size);
+ return;
+ }
+ vaddr = phys_to_virt(paddr);
switch (dir) {
case DMA_TO_DEVICE:
break;
@@ -49,10 +62,30 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
}
}
+void *arch_dma_set_uncached(void *addr, size_t size)
+{
+ if (sifive_ccache_handle_noncoherent())
+ return sifive_ccache_set_uncached(addr, size);
+
+ return addr;
+}
+
+void arch_dma_clear_uncached(void *addr, size_t size)
+{
+ if (sifive_ccache_handle_noncoherent())
+ sifive_ccache_clear_uncached(addr, size);
+}
+
void arch_dma_prep_coherent(struct page *page, size_t size)
{
void *flush_addr = page_address(page);
+ if (sifive_ccache_handle_noncoherent()) {
+ memset(flush_addr, 0, size);
+ sifive_ccache_flush_range(__pa(flush_addr), size);
+ return;
+ }
+
ALT_CMO_OP(flush, flush_addr, size, riscv_cbom_block_size);
}
--
Armbian

View File

@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sun, 3 Jul 2022 21:01:11 +0200
Subject: power: reset: tps65086: Allow building as a module
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/power/reset/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index a8c46ba5878f..c3a842f185e3 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -205,7 +205,7 @@ config POWER_RESET_ST
Reset support for STMicroelectronics boards.
config POWER_RESET_TPS65086
- bool "TPS65086 restart driver"
+ tristate "TPS65086 restart driver"
depends on MFD_TPS65086
help
This driver adds support for resetting the TPS65086 PMIC on restart.
--
Armbian

View File

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samin Guo <samin.guo@starfivetech.com>
Date: Fri, 8 Jan 2021 03:11:04 +0800
Subject: drivers/tty/serial/8250: update driver for JH7100
---
drivers/tty/serial/8250/8250_port.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 388172289627..e5044aa01298 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -71,8 +71,16 @@ static const struct serial8250_config uart_config[] = {
},
[PORT_16550] = {
.name = "16550",
+#ifdef CONFIG_SOC_STARFIVE
+ .fifo_size = 16,
+ .tx_loadsz = 16,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
+ .rxtrig_bytes = {1, 4, 8, 14},
+ .flags = UART_CAP_FIFO,
+#else
.fifo_size = 1,
.tx_loadsz = 1,
+#endif
},
[PORT_16550A] = {
.name = "16550A",
--
Armbian

View File

@ -0,0 +1,316 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chenjieqin <Jessica.Chen@starfivetech.com>
Date: Fri, 8 Jan 2021 03:56:54 +0800
Subject: pwm: sifive-ptc: Add SiFive PWM PTC driver
yiming.li: clear CNTR of PWM after setting period & duty_cycle
Emil: cleanups, clock, reset and div_u64
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/pwm/Kconfig | 11 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-sifive-ptc.c | 258 ++++++++++
3 files changed, 270 insertions(+)
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 60d13a949bc5..89cd8a6406e3 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -504,6 +504,17 @@ config PWM_SIFIVE
To compile this driver as a module, choose M here: the module
will be called pwm-sifive.
+config PWM_SIFIVE_PTC
+ tristate "SiFive PWM PTC support"
+ depends on SOC_SIFIVE || SOC_STARFIVE || COMPILE_TEST
+ depends on OF
+ depends on COMMON_CLK
+ help
+ Generic PWM framework driver for SiFive SoCs.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-sifive-ptc.
+
config PWM_SL28CPLD
tristate "Kontron sl28cpld PWM support"
depends on MFD_SL28CPLD || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 7bf1a29f02b8..fbaa279cf540 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o
obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
+obj-$(CONFIG_PWM_SIFIVE_PTC) += pwm-sifive-ptc.o
obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
obj-$(CONFIG_PWM_SPRD) += pwm-sprd.o
diff --git a/drivers/pwm/pwm-sifive-ptc.c b/drivers/pwm/pwm-sifive-ptc.c
new file mode 100644
index 000000000000..d0e592f48e69
--- /dev/null
+++ b/drivers/pwm/pwm-sifive-ptc.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2018 SiFive, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2, as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/reset.h>
+
+#include <dt-bindings/pwm/pwm.h>
+
+/* max channel of pwm */
+#define MAX_PWM 8
+
+/* PTC Register offsets */
+#define REG_RPTC_CNTR 0x0
+#define REG_RPTC_HRC 0x4
+#define REG_RPTC_LRC 0x8
+#define REG_RPTC_CTRL 0xC
+
+/* Bit for PWM clock */
+#define BIT_PWM_CLOCK_EN 31
+
+/* Bit for clock gen soft reset */
+#define BIT_CLK_GEN_SOFT_RESET 13
+
+#define NS_1 1000000000U
+
+/* Access PTC register (cntr hrc lrc and ctrl), need to replace PWM_BASE_ADDR */
+#define REG_PTC_BASE_ADDR_SUB(base, N) \
+ ((base) + (((N) > 3) ? (((N) - 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
+#define REG_PTC_RPTC_CNTR(base, N) (REG_PTC_BASE_ADDR_SUB(base, N))
+#define REG_PTC_RPTC_HRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
+#define REG_PTC_RPTC_LRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
+#define REG_PTC_RPTC_CTRL(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
+
+/* pwm ptc device */
+struct sifive_pwm_ptc_device {
+ struct pwm_chip chip;
+ struct clk *clk;
+ void __iomem *regs;
+};
+
+static inline struct sifive_pwm_ptc_device *chip_to_sifive_ptc(struct pwm_chip *c)
+{
+ return container_of(c, struct sifive_pwm_ptc_device, chip);
+}
+
+static void sifive_pwm_ptc_get_state(struct pwm_chip *chip, struct pwm_device *dev,
+ struct pwm_state *state)
+{
+ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
+ u32 data_lrc;
+ u32 data_hrc;
+ u32 pwm_clk_ns = 0;
+
+ /* get lrc and hrc data from registe */
+ data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
+ data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
+
+ /* how many ns does apb clock elapse */
+ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
+
+ /* pwm period(ns) */
+ state->period = data_lrc * pwm_clk_ns;
+
+ /* duty cycle(ns) means high level eclapse ns if it is normal polarity */
+ state->duty_cycle = data_hrc * pwm_clk_ns;
+
+ /* polarity, we don't use it now because it is not in dts */
+ state->polarity = PWM_POLARITY_NORMAL;
+
+ /* enabled or not */
+ state->enabled = 1;
+
+ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
+ dev_dbg(pwm->chip.dev, "data_hrc:0x%x 0x%x\n", data_hrc, data_lrc);
+ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
+ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
+ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
+ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
+}
+
+static int sifive_pwm_ptc_apply(struct pwm_chip *chip, struct pwm_device *dev,
+ const struct pwm_state *state)
+{
+ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
+ void __iomem *reg_addr;
+ u32 pwm_clk_ns = 0;
+ u32 data_hrc = 0;
+ u32 data_lrc = 0;
+ u32 period_data = 0;
+ u32 duty_data = 0;
+
+ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
+ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
+ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
+ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
+ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
+
+ /* duty_cycle should be less or equal than period */
+ if (state->duty_cycle > state->period)
+ return -EINVAL;
+
+ /* calculate pwm real period (ns) */
+ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
+
+ dev_dbg(pwm->chip.dev, "pwm_clk_ns:%u\n", pwm_clk_ns);
+
+ /* calculate period count */
+ period_data = div_u64(state->period, pwm_clk_ns);
+
+ if (!state->enabled)
+ /* if disabled, just set duty_data to 0, which means low level always */
+ duty_data = 0;
+ else
+ /* calculate duty count */
+ duty_data = div_u64(state->duty_cycle, pwm_clk_ns);
+
+ dev_dbg(pwm->chip.dev, "period_data:%u, duty_data:%u\n",
+ period_data, duty_data);
+
+ if (state->polarity == PWM_POLARITY_NORMAL)
+ /* calculate data_hrc */
+ data_hrc = period_data - duty_data;
+ else
+ /* calculate data_hrc */
+ data_hrc = duty_data;
+
+ data_lrc = period_data;
+
+ /* set hrc */
+ reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
+ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
+ __func__, reg_addr, data_hrc);
+
+ iowrite32(data_hrc, reg_addr);
+
+ dev_dbg(pwm->chip.dev, "%s: hrc ok\n", __func__);
+
+ /* set lrc */
+ reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
+ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
+ __func__, reg_addr, data_lrc);
+
+ iowrite32(data_lrc, reg_addr);
+ dev_dbg(pwm->chip.dev, "%s: lrc ok\n", __func__);
+
+ /* Clear REG_RPTC_CNTR after setting period & duty_cycle */
+ reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
+ iowrite32(0, reg_addr);
+ return 0;
+}
+
+static const struct pwm_ops sifive_pwm_ptc_ops = {
+ .get_state = sifive_pwm_ptc_get_state,
+ .apply = sifive_pwm_ptc_apply,
+ .owner = THIS_MODULE,
+};
+
+static void sifive_pwm_ptc_disable_action(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
+static int sifive_pwm_ptc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = pdev->dev.of_node;
+ struct sifive_pwm_ptc_device *pwm;
+ struct pwm_chip *chip;
+ struct reset_control *rst;
+ int ret;
+
+ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
+ if (!pwm)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, pwm);
+
+ chip = &pwm->chip;
+ chip->dev = dev;
+ chip->ops = &sifive_pwm_ptc_ops;
+
+ /* how many parameters can be transferred to ptc, need to fix */
+ chip->of_pwm_n_cells = 3;
+ chip->base = -1;
+
+ /* get pwm channels count, max value is 8 */
+ ret = of_property_read_u32(node, "starfive,npwm", &chip->npwm);
+ if (ret < 0 || chip->npwm > MAX_PWM)
+ chip->npwm = MAX_PWM;
+
+ dev_dbg(dev, "%s: npwm:0x%x\n", __func__, chip->npwm);
+
+ /* get IO base address */
+ pwm->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(pwm->regs))
+ return dev_err_probe(dev, PTR_ERR(pwm->regs),
+ "Unable to map IO resources\n");
+
+ pwm->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(pwm->clk))
+ return dev_err_probe(dev, PTR_ERR(pwm->clk),
+ "Unable to get controller clock\n");
+
+ ret = clk_prepare_enable(pwm->clk);
+ if (ret)
+ return dev_err_probe(dev, ret, "Unable to enable clock\n");
+
+ ret = devm_add_action_or_reset(dev, sifive_pwm_ptc_disable_action, pwm->clk);
+ if (ret)
+ return ret;
+
+ rst = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR(rst))
+ return dev_err_probe(dev, PTR_ERR(rst), "Unable to get reset\n");
+
+ ret = reset_control_deassert(rst);
+ if (ret)
+ return dev_err_probe(dev, ret, "Unable to deassert reset\n");
+
+ /*
+ * after pwmchip_add it will show up as /sys/class/pwm/pwmchip0,
+ * 0 is chip->base, pwm0 can be seen after running echo 0 > export
+ */
+ ret = devm_pwmchip_add(dev, chip);
+ if (ret)
+ return dev_err_probe(dev, ret, "cannot register PTC: %d\n", ret);
+
+ dev_dbg(dev, "SiFive PWM PTC chip registered %d PWMs\n", chip->npwm);
+ return 0;
+}
+
+static const struct of_device_id sifive_pwm_ptc_of_match[] = {
+ { .compatible = "starfive,pwm0" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sifive_pwm_ptc_of_match);
+
+static struct platform_driver sifive_pwm_ptc_driver = {
+ .probe = sifive_pwm_ptc_probe,
+ .driver = {
+ .name = "pwm-sifive-ptc",
+ .of_match_table = sifive_pwm_ptc_of_match,
+ },
+};
+module_platform_driver(sifive_pwm_ptc_driver);
+
+MODULE_DESCRIPTION("SiFive PWM PTC driver");
+MODULE_LICENSE("GPL v2");
--
Armbian

View File

@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Thu, 27 May 2021 20:13:43 +0200
Subject: [WIP] dt-bindings: dma: dw-axi-dmac: Increase DMA channel limit to 16
The first DMAC instance in the StarFive JH7100 SoC supports 16 DMA
channels.
FIXME Given there are more changes to the driver than just increasing
DMAC_MAX_CHANNELS, we probably need a new compatible value, too.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
index 67aa7bb6d36a..26c7d74bfe6d 100644
--- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
+++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
@@ -56,7 +56,7 @@ properties:
dma-channels:
minimum: 1
- maximum: 8
+ maximum: 16
resets:
maxItems: 1
@@ -79,14 +79,14 @@ properties:
Channel priority specifier associated with the DMA channels.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
- maxItems: 8
+ maxItems: 16
snps,block-size:
description: |
Channel block size specifier associated with the DMA channels.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
- maxItems: 8
+ maxItems: 16
snps,axi-max-burst-len:
description: |
--
Armbian

View File

@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samin Guo <samin.guo@starfivetech.com>
Date: Wed, 17 Nov 2021 14:50:45 +0800
Subject: dmaengine: dw-axi-dmac: Handle xfer start while non-idle
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
Signed-off-by: Curry Zhang <curry.zhang@starfivetech.com>
---
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 13 +++++++++-
drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index a183d93bd7e2..280b9d2bb1d0 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -377,11 +377,13 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
u32 irq_mask;
u8 lms = 0; /* Select AXI0 master for LLI fetching */
+ chan->is_err = false;
if (unlikely(axi_chan_is_hw_enable(chan))) {
dev_err(chan2dev(chan), "%s is non-idle!\n",
axi_chan_name(chan));
- return;
+ axi_chan_disable(chan);
+ chan->is_err = true;
}
axi_dma_enable(chan->chip);
@@ -1018,6 +1020,14 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
/* The bad descriptor currently is in the head of vc list */
vd = vchan_next_desc(&chan->vc);
+ if (chan->is_err) {
+ struct axi_dma_desc *desc = vd_to_axi_desc(vd);
+
+ axi_chan_block_xfer_start(chan, desc);
+ chan->is_err = false;
+ goto out;
+ }
+
/* Remove the completed descriptor from issued list */
list_del(&vd->node);
@@ -1032,6 +1042,7 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
/* Try to restart the controller */
axi_chan_start_first_queued(chan);
+out:
spin_unlock_irqrestore(&chan->vc.lock, flags);
}
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index e9d5eb0fd594..4019a9a42d7e 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -49,6 +49,7 @@ struct axi_dma_chan {
struct dma_slave_config config;
enum dma_transfer_direction direction;
bool cyclic;
+ bool is_err;
/* these other elements are all protected by vc.lock */
bool is_paused;
};
--
Armbian

View File

@ -0,0 +1,70 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samin Guo <samin.guo@starfivetech.com>
Date: Wed, 17 Nov 2021 14:50:45 +0800
Subject: dmaengine: dw-axi-dmac: Add StarFive JH7100 support
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 11 +++++++++-
drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 4 ++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 280b9d2bb1d0..2d151ba2ee5d 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -86,7 +86,7 @@ static inline void axi_chan_config_write(struct axi_dma_chan *chan,
cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
- if (chan->chip->dw->hdata->reg_map_8_channels) {
+ if (!IS_ENABLED(CONFIG_SOC_STARFIVE) && chan->chip->dw->hdata->reg_map_8_channels) {
cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
@@ -672,8 +672,13 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
+#ifdef CONFIG_SOC_STARFIVE
+ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_DST_MSIZE_POS |
+ DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_SRC_MSIZE_POS;
+#else
ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
+#endif
hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
set_desc_src_master(hw_desc);
@@ -1484,7 +1489,11 @@ static int dw_probe(struct platform_device *pdev)
* Therefore, set constraint to 1024 * 4.
*/
dw->dma.dev->dma_parms = &dw->dma_parms;
+#ifdef CONFIG_SOC_STARFIVE
+ dma_set_max_seg_size(&pdev->dev, DMAC_MAX_BLK_SIZE);
+#else
dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
+#endif
platform_set_drvdata(pdev, chip);
pm_runtime_enable(chip->dev);
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index 4019a9a42d7e..d6ec88c45f48 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -282,7 +282,11 @@ enum {
#define CH_CTL_L_SRC_MAST BIT(0)
/* CH_CFG_H */
+#ifdef CONFIG_SOC_STARFIVE
+#define CH_CFG_H_PRIORITY_POS 15
+#else
#define CH_CFG_H_PRIORITY_POS 17
+#endif
#define CH_CFG_H_DST_PER_POS 12
#define CH_CFG_H_SRC_PER_POS 7
#define CH_CFG_H_HS_SEL_DST_POS 4
--
Armbian

View File

@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
Date: Mon, 7 Nov 2022 21:05:18 +0100
Subject: net: phy: motorcomm: Disable rgmii rx delay
Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
---
drivers/net/phy/motorcomm.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index c7593f224177..35a4f2a76996 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -160,6 +160,7 @@
#define YT8521_CHIP_CONFIG_REG 0xA001
#define YT8521_CCR_SW_RST BIT(15)
+#define YT8521_CCR_RXC_DLY_EN BIT(8)
#define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0))
#define YT8521_CCR_MODE_UTP_TO_RGMII 0
@@ -1150,6 +1151,12 @@ static int yt8521_config_init(struct phy_device *phydev)
val);
if (ret < 0)
goto err_restore_page;
+
+ /* disable rx delay */
+ ret = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG,
+ YT8521_CCR_RXC_DLY_EN, 0);
+ if (ret < 0)
+ goto err_restore_page;
}
/* disable auto sleep */
--
Armbian

View File

@ -0,0 +1,236 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 9 Jul 2022 23:55:01 +0200
Subject: dt-bindings: clock: Add StarFive JH7110 system clock definitions
Add all clock outputs for the StarFive JH7110 system clock generator.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
include/dt-bindings/clock/starfive-jh7110-sys.h | 215 ++++++++++
1 file changed, 215 insertions(+)
diff --git a/include/dt-bindings/clock/starfive-jh7110-sys.h b/include/dt-bindings/clock/starfive-jh7110-sys.h
new file mode 100755
index 000000000000..5ef643895a7a
--- /dev/null
+++ b/include/dt-bindings/clock/starfive-jh7110-sys.h
@@ -0,0 +1,215 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_SYS_H__
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_SYS_H__
+
+#define JH7110_SYSCLK_CPU_ROOT 0 /* clk_cpu_root */
+#define JH7110_SYSCLK_CPU_CORE 1 /* clk_cpu_core */
+#define JH7110_SYSCLK_CPU_BUS 2 /* clk_cpu_bus */
+#define JH7110_SYSCLK_GPU_ROOT 3 /* clk_gpu_root */
+#define JH7110_SYSCLK_PERH_ROOT 4 /* clk_perh_root */
+#define JH7110_SYSCLK_BUS_ROOT 5 /* clk_bus_root */
+#define JH7110_SYSCLK_NOCSTG_BUS 6 /* clk_nocstg_bus */
+#define JH7110_SYSCLK_AXI_CFG0 7 /* clk_axi_cfg0 */
+#define JH7110_SYSCLK_STG_AXIAHB 8 /* clk_stg_axiahb */
+#define JH7110_SYSCLK_AHB0 9 /* clk_ahb0 */
+#define JH7110_SYSCLK_AHB1 10 /* clk_ahb1 */
+#define JH7110_SYSCLK_APB_BUS_FUNC 11 /* clk_apb_bus_func */
+#define JH7110_SYSCLK_APB0 12 /* clk_apb0 */
+#define JH7110_SYSCLK_PLL0_DIV2 13 /* clk_pll0_div2 */
+#define JH7110_SYSCLK_PLL1_DIV2 14 /* clk_pll1_div2 */
+#define JH7110_SYSCLK_PLL2_DIV2 15 /* clk_pll2_div2 */
+#define JH7110_SYSCLK_AUDIO_ROOT 16 /* clk_audio_root */
+#define JH7110_SYSCLK_MCLK_INNER 17 /* clk_mclk_inner */
+#define JH7110_SYSCLK_MCLK 18 /* clk_mclk */
+#define JH7110_SYSCLK_MCLK_OUT 19 /* clk_mclk_out */
+#define JH7110_SYSCLK_ISP_2X 20 /* clk_isp_2x */
+#define JH7110_SYSCLK_ISP_AXI 21 /* clk_isp_axi */
+#define JH7110_SYSCLK_GCLK0 22 /* clk_gclk0 */
+#define JH7110_SYSCLK_GCLK1 23 /* clk_gclk1 */
+#define JH7110_SYSCLK_GCLK2 24 /* clk_gclk2 */
+#define JH7110_SYSCLK_CORE 25 /* clk_u0_u7mc_sft7110_core_clk */
+#define JH7110_SYSCLK_CORE1 26 /* clk_u0_u7mc_sft7110_core_clk1 */
+#define JH7110_SYSCLK_CORE2 27 /* clk_u0_u7mc_sft7110_core_clk2 */
+#define JH7110_SYSCLK_CORE3 28 /* clk_u0_u7mc_sft7110_core_clk3 */
+#define JH7110_SYSCLK_CORE4 29 /* clk_u0_u7mc_sft7110_core_clk4 */
+#define JH7110_SYSCLK_DEBUG 30 /* clk_u0_u7mc_sft7110_debug_clk */
+#define JH7110_SYSCLK_RTC_TOGGLE 31 /* clk_u0_u7mc_sft7110_rtc_toggle */
+#define JH7110_SYSCLK_TRACE0 32 /* clk_u0_u7mc_sft7110_trace_clk0 */
+#define JH7110_SYSCLK_TRACE1 33 /* clk_u0_u7mc_sft7110_trace_clk1 */
+#define JH7110_SYSCLK_TRACE2 34 /* clk_u0_u7mc_sft7110_trace_clk2 */
+#define JH7110_SYSCLK_TRACE3 35 /* clk_u0_u7mc_sft7110_trace_clk3 */
+#define JH7110_SYSCLK_TRACE4 36 /* clk_u0_u7mc_sft7110_trace_clk4 */
+#define JH7110_SYSCLK_TRACE_COM 37 /* clk_u0_u7mc_sft7110_trace_com_clk */
+#define JH7110_SYSCLK_NOC_BUS_CPU_AXI 38 /* clk_u0_u7mc_sft7110_noc_bus_clk_cpu_axi */
+#define JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI 39 /* clk_u0_u7mc_sft7110_noc_bus_clk_axicfg0_axi */
+#define JH7110_SYSCLK_OSC_DIV2 40 /* clk_osc_div2 */
+#define JH7110_SYSCLK_PLL1_DIV4 41 /* clk_pll1_div4 */
+#define JH7110_SYSCLK_PLL1_DIV8 42 /* clk_pll1_div8 */
+#define JH7110_SYSCLK_DDR_BUS 43 /* clk_ddr_bus */
+#define JH7110_SYSCLK_DDR_AXI 44 /* clk_u0_ddr_sft7110_clk_axi */
+#define JH7110_SYSCLK_GPU_CORE 45 /* clk_gpu_core */
+#define JH7110_SYSCLK_GPU_CORE_CLK 46 /* clk_u0_img_gpu_core_clk */
+#define JH7110_SYSCLK_GPU_SYS_CLK 47 /* clk_u0_img_gpu_sys_clk */
+#define JH7110_SYSCLK_GPU_APB 48 /* clk_u0_img_gpu_clk_apb */
+#define JH7110_SYSCLK_GPU_RTC_TOGGLE 49 /* clk_u0_img_gpu_rtc_toggle */
+#define JH7110_SYSCLK_NOC_BUS_GPU_AXI 50 /* clk_u0_sft7110_noc_bus_clk_gpu_axi */
+#define JH7110_SYSCLK_ISP_TOP_CLK_ISPCORE_2X 51 /* clk_u0_dom_isp_top_clk_ispcore_2x */
+#define JH7110_SYSCLK_ISP_TOP_CLK_ISP_AXI 52 /* clk_u0_dom_isp_top_clk_isp_axi */
+#define JH7110_SYSCLK_NOC_BUS_ISP_AXI 53 /* clk_u0_sft7110_noc_bus_clk_isp_axi */
+#define JH7110_SYSCLK_HIFI4_CORE 54 /* clk_hifi4_core */
+#define JH7110_SYSCLK_HIFI4_AXI 55 /* clk_hifi4_axi */
+#define JH7110_SYSCLK_AXI_CFG1_DEC_MAIN 56 /* clk_u0_axi_cfg1_dec_clk_main */
+#define JH7110_SYSCLK_AXI_CFG1_DEC_AHB 57 /* clk_u0_axi_cfg1_dec_clk_ahb */
+#define JH7110_SYSCLK_VOUT_SRC 58 /* clk_u0_dom_vout_top_vout_src */
+#define JH7110_SYSCLK_VOUT_AXI 59 /* clk_vout_axi */
+#define JH7110_SYSCLK_NOC_BUS_DISP_AXI 60 /* clk_u0_sft7110_noc_bus_clk_disp_axi */
+#define JH7110_SYSCLK_VOUT_TOP_CLK_VOUT_AHB 61 /* clk_u0_dom_vout_top_clk_vout_ahb */
+#define JH7110_SYSCLK_VOUT_TOP_CLK_VOUT_AXI 62 /* clk_u0_dom_vout_top_clk_vout_axi */
+#define JH7110_SYSCLK_VOUT_TOP_CLK_HDMITX0_MCLK 63 /* clk_u0_dom_vout_top_clk_hdmitx0_mclk */
+#define JH7110_SYSCLK_VOUT_TOP_CLK_MIPIPHY_REF 64 /* clk_u0_dom_vout_top_clk_mipiphy_ref */
+#define JH7110_SYSCLK_JPEGC_AXI 65 /* clk_jpegc_axi */
+#define JH7110_SYSCLK_CODAJ12_AXI 66 /* clk_CODAJ12_clk_axi */
+#define JH7110_SYSCLK_CODAJ12_CORE 67 /* clk_CODAJ12_clk_core */
+#define JH7110_SYSCLK_CODAJ12_APB 68 /* clk_CODAJ12_clk_apb */
+#define JH7110_SYSCLK_VDEC_AXI 69 /* clk_vdec_axi */
+#define JH7110_SYSCLK_WAVE511_AXI 70 /* clk_u0_WAVE511_clk_axi */
+#define JH7110_SYSCLK_WAVE511_BPU 71 /* clk_u0_WAVE511_clk_bpu */
+#define JH7110_SYSCLK_WAVE511_VCE 72 /* clk_u0_WAVE511_clk_vce */
+#define JH7110_SYSCLK_WAVE511_APB 73 /* clk_u0_WAVE511_clk_apb */
+#define JH7110_SYSCLK_VDEC_JPG_ARB_JPG 74 /* clk_u0_vdec_jpg_arb_jpgclk */
+#define JH7110_SYSCLK_VDEC_JPG_ARB_MAIN 75 /* clk_u0_vdec_jpg_arb_mainclk */
+#define JH7110_SYSCLK_NOC_BUS_VDEC_AXI 76 /* clk_u0_sft7110_noc_bus_clk_vdec_axi */
+#define JH7110_SYSCLK_VENC_AXI 77 /* clk_vec_axi */
+#define JH7110_SYSCLK_WAVE420L_AXI 78 /* clk_u0_wave420l_clk_axi */
+#define JH7110_SYSCLK_WAVE420L_BPU 79 /* clk_u0_wave420l_clk_bpu */
+#define JH7110_SYSCLK_WAVE420L_VCE 80 /* clk_u0_wave420l_clk_vce */
+#define JH7110_SYSCLK_WAVE420L_APB 81 /* clk_u0_wave420l_clk_apb */
+#define JH7110_SYSCLK_NOC_BUS_VENC_AXI 82 /* clk_u0_sft7110_noc_bus_clk_venc_axi */
+#define JH7110_SYSCLK_AXI_CFG0_DEC_MAIN_DIV 83 /* clk_u0_axi_cfg0_dec_clk_main_div */
+#define JH7110_SYSCLK_AXI_CFG0_DEC_MAIN 84 /* clk_u0_axi_cfg0_dec_clk_main */
+#define JH7110_SYSCLK_AXI_CFG0_DEC_HIFI4 85 /* clk_u0_axi_cfg0_dec_clk_hifi4 */
+#define JH7110_SYSCLK_AXIMEM2_AXI 86 /* clk_u2_aximem_128b_clk_axi */
+#define JH7110_SYSCLK_QSPI_AHB 87 /* clk_u0_cdns_qspi_clk_ahb */
+#define JH7110_SYSCLK_QSPI_APB 88 /* clk_u0_cdns_qspi_clk_apb */
+#define JH7110_SYSCLK_QSPI_REF_SRC 89 /* clk_u0_cdns_qspi_ref_src */
+#define JH7110_SYSCLK_QSPI_REF 90 /* clk_u0_cdns_qspi_clk_ref */
+#define JH7110_SYSCLK_SDIO0_AHB 91 /* clk_u0_dw_sdio_clk_ahb */
+#define JH7110_SYSCLK_SDIO1_AHB 92 /* clk_u1_dw_sdio_clk_ahb */
+#define JH7110_SYSCLK_SDIO0_SDCARD 93 /* clk_u0_dw_sdio_clk_sdcard */
+#define JH7110_SYSCLK_SDIO1_SDCARD 94 /* clk_u1_dw_sdio_clk_sdcard */
+#define JH7110_SYSCLK_USB_125M 95 /* clk_usb_125m */
+#define JH7110_SYSCLK_NOC_BUS_STG_AXI 96 /* clk_u0_sft7110_noc_bus_clk_stg_axi */
+#define JH7110_SYSCLK_GMAC1_AHB 97 /* clk_u1_dw_gmac5_axi64_clk_ahb */
+#define JH7110_SYSCLK_GMAC1_AXI 98 /* clk_u1_dw_gmac5_axi64_clk_axi */
+#define JH7110_SYSCLK_GMAC_SRC 99 /* clk_gmac_src */
+#define JH7110_SYSCLK_GMAC1_GTXCLK 100 /* clk_gmac1_gtxclk */
+#define JH7110_SYSCLK_GMAC1_RMII_RTX 101 /* clk_gmac1_rmii_rtx */
+#define JH7110_SYSCLK_GMAC1_PTP 102 /* clk_u1_dw_gmac5_axi64_clk_ptp */
+#define JH7110_SYSCLK_GMAC1_RX 103 /* clk_u1_dw_gmac5_axi64_clk_rx */
+#define JH7110_SYSCLK_GMAC1_RX_INV 104 /* clk_u1_dw_gmac5_axi64_clk_rx_inv */
+#define JH7110_SYSCLK_GMAC1_TX 105 /* clk_u1_dw_gmac5_axi64_clk_tx */
+#define JH7110_SYSCLK_GMAC1_TX_INV 106 /* clk_u1_dw_gmac5_axi64_clk_tx_inv */
+#define JH7110_SYSCLK_GMAC1_GTXC 107 /* clk_gmac1_gtxc */
+#define JH7110_SYSCLK_GMAC0_GTXCLK 108 /* clk_gmac0_gtxclk */
+#define JH7110_SYSCLK_GMAC0_PTP 109 /* clk_gmac0_ptp */
+#define JH7110_SYSCLK_GMAC_PHY 110 /* clk_gmac_phy */
+#define JH7110_SYSCLK_GMAC0_GTXC 111 /* clk_gmac0_gtxc */
+#define JH7110_SYSCLK_IOMUX 112 /* clk_u0_sys_iomux_pclk */
+#define JH7110_SYSCLK_MAILBOX 113 /* clk_u0_mailbox_clk_apb */
+#define JH7110_SYSCLK_INT_CTRL_APB 114 /* clk_int_ctrl_clk_apb */
+#define JH7110_SYSCLK_CAN0_APB 115 /* clk_u0_can_ctrl_clk_apb */
+#define JH7110_SYSCLK_CAN0_TIMER 116 /* clk_u0_can_ctrl_clk_timer */
+#define JH7110_SYSCLK_CAN0_CAN 117 /* clk_u0_can_ctrl_clk_can */
+#define JH7110_SYSCLK_CAN1_APB 118 /* clk_u1_can_ctrl_clk_apb */
+#define JH7110_SYSCLK_CAN1_TIMER 119 /* clk_u1_can_ctrl_clk_timer */
+#define JH7110_SYSCLK_CAN1_CAN 120 /* clk_u1_can_ctrl_clk_can */
+#define JH7110_SYSCLK_PWM_APB 121 /* clk_u0_pwm_8ch_clk_apb */
+#define JH7110_SYSCLK_WDT_APB 122 /* clk_u0_dskit_wdt_clk_apb */
+#define JH7110_SYSCLK_WDT_CORE 123 /* clk_u0_dskit_wdt_clk_wdt */
+#define JH7110_SYSCLK_TIMER_APB 124 /* clk_u0_si5_timer_clk_apb */
+#define JH7110_SYSCLK_TIMER0 125 /* clk_u0_si5_timer_clk_timer0 */
+#define JH7110_SYSCLK_TIMER1 126 /* clk_u0_si5_timer_clk_timer1 */
+#define JH7110_SYSCLK_TIMER2 127 /* clk_u0_si5_timer_clk_timer2 */
+#define JH7110_SYSCLK_TIMER3 128 /* clk_u0_si5_timer_clk_timer3 */
+#define JH7110_SYSCLK_TEMP_APB 129 /* clk_u0_temp_sensor_clk_apb */
+#define JH7110_SYSCLK_TEMP_CORE 130 /* clk_u0_temp_sensor_clk_temp */
+#define JH7110_SYSCLK_SPI0_APB 131 /* clk_u0_ssp_spi_clk_apb */
+#define JH7110_SYSCLK_SPI1_APB 132 /* clk_u1_ssp_spi_clk_apb */
+#define JH7110_SYSCLK_SPI2_APB 133 /* clk_u2_ssp_spi_clk_apb */
+#define JH7110_SYSCLK_SPI3_APB 134 /* clk_u3_ssp_spi_clk_apb */
+#define JH7110_SYSCLK_SPI4_APB 135 /* clk_u4_ssp_spi_clk_apb */
+#define JH7110_SYSCLK_SPI5_APB 136 /* clk_u5_ssp_spi_clk_apb */
+#define JH7110_SYSCLK_SPI6_APB 137 /* clk_u6_ssp_spi_clk_apb */
+#define JH7110_SYSCLK_I2C0_APB 138 /* clk_u0_dw_i2c_clk_apb */
+#define JH7110_SYSCLK_I2C1_APB 139 /* clk_u1_dw_i2c_clk_apb */
+#define JH7110_SYSCLK_I2C2_APB 140 /* clk_u2_dw_i2c_clk_apb */
+#define JH7110_SYSCLK_I2C3_APB 141 /* clk_u3_dw_i2c_clk_apb */
+#define JH7110_SYSCLK_I2C4_APB 142 /* clk_u4_dw_i2c_clk_apb */
+#define JH7110_SYSCLK_I2C5_APB 143 /* clk_u5_dw_i2c_clk_apb */
+#define JH7110_SYSCLK_I2C6_APB 144 /* clk_u6_dw_i2c_clk_apb */
+#define JH7110_SYSCLK_UART0_APB 145 /* clk_u0_dw_uart_clk_apb */
+#define JH7110_SYSCLK_UART0_CORE 146 /* clk_u0_dw_uart_clk_core */
+#define JH7110_SYSCLK_UART1_APB 147 /* clk_u1_dw_uart_clk_apb */
+#define JH7110_SYSCLK_UART1_CORE 148 /* clk_u1_dw_uart_clk_core */
+#define JH7110_SYSCLK_UART2_APB 149 /* clk_u2_dw_uart_clk_apb */
+#define JH7110_SYSCLK_UART2_CORE 150 /* clk_u2_dw_uart_clk_core */
+#define JH7110_SYSCLK_UART3_APB 151 /* clk_u3_dw_uart_clk_apb */
+#define JH7110_SYSCLK_UART3_CORE 152 /* clk_u3_dw_uart_clk_core */
+#define JH7110_SYSCLK_UART4_APB 153 /* clk_u4_dw_uart_clk_apb */
+#define JH7110_SYSCLK_UART4_CORE 154 /* clk_u4_dw_uart_clk_core */
+#define JH7110_SYSCLK_UART5_APB 155 /* clk_u5_dw_uart_clk_apb */
+#define JH7110_SYSCLK_UART5_CORE 156 /* clk_u5_dw_uart_clk_core */
+#define JH7110_SYSCLK_PWMDAC_APB 157 /* clk_u0_pwmdac_clk_apb */
+#define JH7110_SYSCLK_PWMDAC_CORE 158 /* clk_u0_pwmdac_clk_core */
+#define JH7110_SYSCLK_SPDIF_APB 159 /* clk_u0_cdns_spdif_clk_apb */
+#define JH7110_SYSCLK_SPDIF_CORE 160 /* clk_u0_cdns_spdif_clk_core */
+#define JH7110_SYSCLK_I2STX0_APB 161 /* clk_u0_i2stx_4ch_clk_apb */
+#define JH7110_SYSCLK_I2STX0_BCLK_MST 162 /* clk_i2stx_4ch0_bclk_mst */
+#define JH7110_SYSCLK_I2STX0_BCLK_MST_INV 163 /* clk_i2stx_4ch0_bclk_mst_inv */
+#define JH7110_SYSCLK_I2STX0_LRCK_MST 164 /* clk_i2stx_4ch0_lrck_mst */
+#define JH7110_SYSCLK_I2STX0_BCLK 165 /* clk_u0_i2stx_4ch_bclk */
+#define JH7110_SYSCLK_I2STX0_BCLK_INV 166 /* clk_u0_i2stx_4ch_bclk_n */
+#define JH7110_SYSCLK_I2STX0_LRCK 167 /* clk_u0_i2stx_4ch_lrck */
+#define JH7110_SYSCLK_I2STX1_APB 168 /* clk_u1_i2stx_4ch_clk_apb */
+#define JH7110_SYSCLK_I2STX1_BCLK_MST 169 /* clk_i2stx_4ch1_bclk_mst */
+#define JH7110_SYSCLK_I2STX1_BCLK_MST_INV 170 /* clk_i2stx_4ch1_bclk_mst_inv */
+#define JH7110_SYSCLK_I2STX1_LRCK_MST 171 /* clk_i2stx_4ch1_lrck_mst */
+#define JH7110_SYSCLK_I2STX1_BCLK 172 /* clk_u1_i2stx_4ch_bclk */
+#define JH7110_SYSCLK_I2STX1_BCLK_INV 173 /* clk_u1_i2stx_4ch_bclk_n */
+#define JH7110_SYSCLK_I2STX1_LRCK 174 /* clk_u1_i2stx_4ch_lrck */
+#define JH7110_SYSCLK_I2SRX_APB 175 /* clk_u0_i2srx_3ch_clk_apb */
+#define JH7110_SYSCLK_I2SRX_BCLK_MST 176 /* clk_i2srx_3ch_bclk_mst */
+#define JH7110_SYSCLK_I2SRX_BCLK_MST_INV 177 /* clk_i2srx_3ch_bclk_mst_inv */
+#define JH7110_SYSCLK_I2SRX_LRCK_MST 178 /* clk_i2srx_3ch_lrck_mst */
+#define JH7110_SYSCLK_I2SRX_BCLK 179 /* clk_u0_i2srx_3ch_bclk */
+#define JH7110_SYSCLK_I2SRX_BCLK_INV 180 /* clk_u0_i2srx_3ch_bclk_n */
+#define JH7110_SYSCLK_I2SRX_LRCK 181 /* clk_u0_i2srx_3ch_lrck */
+#define JH7110_SYSCLK_PDM_DMIC 182 /* clk_u0_pdm_4mic_clk_dmic */
+#define JH7110_SYSCLK_PDM_APB 183 /* clk_u0_pdm_4mic_clk_apb */
+#define JH7110_SYSCLK_TDM_AHB 184 /* clk_u0_tdm16slot_clk_ahb */
+#define JH7110_SYSCLK_TDM_APB 185 /* clk_u0_tdm16slot_clk_apb */
+#define JH7110_SYSCLK_TDM_INTERNAL 186 /* clk_tdm_internal */
+#define JH7110_SYSCLK_TDM_CLK_TDM 187 /* clk_u0_tdm16slot_clk_tdm */
+#define JH7110_SYSCLK_TDM_CLK_TDM_N 188 /* clk_u0_tdm16slot_clk_tdm_n */
+#define JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG 189 /* clk_u0_jtag_certification_trng_clk */
+
+#define JH7110_SYSCLK_PLL0_OUT 190
+#define JH7110_SYSCLK_PLL1_OUT 191
+#define JH7110_SYSCLK_PLL2_OUT 192
+#define JH7110_SYSCLK_PCLK2_MUX_FUNC_PCLK 193
+#define JH7110_SYSCLK_U2_PCLK_MUX_PCLK 194
+#define JH7110_SYSCLK_APB_BUS 195
+#define JH7110_SYSCLK_AXI_CFG1 196
+#define JH7110_SYSCLK_APB12 197
+#define JH7110_SYSCLK_VOUT_ROOT 198
+#define JH7110_SYSCLK_VENC_ROOT 199
+#define JH7110_SYSCLK_VDEC_ROOT 200
+#define JH7110_SYSCLK_GMACUSB_ROOT 201
+
+#define JH7110_SYSCLK_END 202
+
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_SYS_H__ */
--
Armbian

View File

@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sun, 24 Jul 2022 20:35:41 +0200
Subject: dt-bindings: clock: Add StarFive JH7110 always-on definitions
Add all clock outputs for the StarFive JH7110 always-on clock generator.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
include/dt-bindings/clock/starfive-jh7110-aon.h | 44 ++++++++++
1 file changed, 44 insertions(+)
diff --git a/include/dt-bindings/clock/starfive-jh7110-aon.h b/include/dt-bindings/clock/starfive-jh7110-aon.h
new file mode 100755
index 000000000000..ab5003d006c8
--- /dev/null
+++ b/include/dt-bindings/clock/starfive-jh7110-aon.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_AON_H__
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_AON_H__
+
+#define JH7110_AONCLK_OSC_DIV4 0 /* clk_osc_div4 */
+#define JH7110_AONCLK_APB_FUNC 1 /* clk_aon_apb_func */
+#define JH7110_AONCLK_GMAC0_AHB 2 /* clk_u0_dw_gmac5_axi64_clk_ahb */
+#define JH7110_AONCLK_GMAC0_AXI 3 /* clk_u0_dw_gmac5_axi64_clk_axi */
+#define JH7110_AONCLK_GMAC0_RMII_RTX 4 /* clk_gmac0_rmii_rtx */
+#define JH7110_AONCLK_GMAC0_TX 5 /* clk_u0_dw_gmac5_axi64_clk_tx */
+#define JH7110_AONCLK_GMAC0_TX_INV 6 /* clk_u0_dw_gmac5_axi64_clk_tx_inv */
+#define JH7110_AONCLK_GMAC0_RX 7 /* clk_u0_dw_gmac5_axi64_clk_rx */
+#define JH7110_AONCLK_GMAC0_RX_INV 8 /* clk_u0_dw_gmac5_axi64_clk_rx_inv */
+#define JH7110_AONCLK_OTPC_APB 9 /* clk_u0_otpc_clk_apb */
+#define JH7110_AONCLK_RTC_APB 10 /* clk_u0_rtc_hms_clk_apb */
+#define JH7110_AONCLK_RTC_INTERNAL 11 /* clk_rtc_internal */
+#define JH7110_AONCLK_RTC_32K 12 /* clk_u0_rtc_hms_clk_osc32k */
+#define JH7110_AONCLK_RTC_CAL 13 /* clk_u0_rtc_hms_clk_cal */
+
+#define JH7110_AONCLK_END 14
+
+#if 0
+/* aon other */
+#define JH7110_U0_GMAC5_CLK_PTP 15
+#define JH7110_U0_GMAC5_CLK_RMII 16
+#define JH7110_AON_SYSCON_PCLK 17
+#define JH7110_AON_IOMUX_PCLK 18
+#define JH7110_AON_CRG_PCLK 19
+#define JH7110_PMU_CLK_APB 20
+#define JH7110_PMU_CLK_WKUP 21
+#define JH7110_RTC_HMS_CLK_OSC32K_G 22
+#define JH7110_32K_OUT 23
+#define JH7110_RESET0_CTRL_CLK_SRC 24
+/* aon other and source */
+#define JH7110_PCLK_MUX_FUNC_PCLK 25
+#define JH7110_PCLK_MUX_BIST_PCLK 26
+
+#endif
+
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_H__ */
--
Armbian

View File

@ -0,0 +1,162 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sat, 9 Jul 2022 23:16:55 +0200
Subject: dt-bindings: reset: Add StarFive JH7110 system reset definitions
Add resets for the StarFive JH7110 system reset controller.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
include/dt-bindings/reset/starfive-jh7110-sys.h | 141 ++++++++++
1 file changed, 141 insertions(+)
diff --git a/include/dt-bindings/reset/starfive-jh7110-sys.h b/include/dt-bindings/reset/starfive-jh7110-sys.h
new file mode 100644
index 000000000000..eb56b563d7d8
--- /dev/null
+++ b/include/dt-bindings/reset/starfive-jh7110-sys.h
@@ -0,0 +1,141 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_SYS_H__
+#define __DT_BINDINGS_RESET_STARFIVE_JH7110_SYS_H__
+
+#define JH7110_SYSRST_JTAG2APB 0 /* rstn_u0_jtag2apb_presetn */
+#define JH7110_SYSRST_SYSCON 1 /* rstn_u0_sys_syscon_presetn */
+#define JH7110_SYSRST_IOMUX 2 /* rstn_u0_sys_iomux_presetn */
+#define JH7110_SYSRST_BUS 3 /* rst_u0_u7mc_sft7110_rst_bus */
+#define JH7110_SYSRST_DEBUG 4 /* rst_u0_u7mc_sft7110_debug_reset */
+#define JH7110_SYSRST_CORE0 5 /* rst_u0_u7mc_sft7110_rst_core0 */
+#define JH7110_SYSRST_CORE1 6 /* rst_u0_u7mc_sft7110_rst_core1 */
+#define JH7110_SYSRST_CORE2 7 /* rst_u0_u7mc_sft7110_rst_core2 */
+#define JH7110_SYSRST_CORE3 8 /* rst_u0_u7mc_sft7110_rst_core3 */
+#define JH7110_SYSRST_CORE4 9 /* rst_u0_u7mc_sft7110_rst_core4 */
+#define JH7110_SYSRST_CORE0_ST 10 /* rst_u0_u7mc_sft7110_rst_core0_st */
+#define JH7110_SYSRST_CORE1_ST 11 /* rst_u0_u7mc_sft7110_rst_core1_st */
+#define JH7110_SYSRST_CORE2_ST 12 /* rst_u0_u7mc_sft7110_rst_core2_st */
+#define JH7110_SYSRST_CORE3_ST 13 /* rst_u0_u7mc_sft7110_rst_core3_st */
+#define JH7110_SYSRST_CORE4_ST 14 /* rst_u0_u7mc_sft7110_rst_core4_st */
+#define JH7110_SYSRST_TRACE0 15 /* rst_u0_u7mc_sft7110_trace_rst0 */
+#define JH7110_SYSRST_TRACE1 16 /* rst_u0_u7mc_sft7110_trace_rst1 */
+#define JH7110_SYSRST_TRACE2 17 /* rst_u0_u7mc_sft7110_trace_rst2 */
+#define JH7110_SYSRST_TRACE3 18 /* rst_u0_u7mc_sft7110_trace_rst3 */
+#define JH7110_SYSRST_TRACE4 19 /* rst_u0_u7mc_sft7110_trace_rst4 */
+#define JH7110_SYSRST_TRACE_COM 20 /* rst_u0_u7mc_sft7110_trace_com_rst */
+#define JH7110_SYSRST_GPU_APB 21 /* rstn_u0_img_gpu_rstn_apb */
+#define JH7110_SYSRST_GPU_DOMA 22 /* rstn_u0_img_gpu_rstn_doma */
+#define JH7110_SYSRST_NOC_BUS_APB_BUS 23 /* rstn_u0_sft7110_noc_bus_reset_apb_bus_n */
+#define JH7110_SYSRST_NOC_BUS_AXICFG0_AXI 24 /* rstn_u0_sft7110_noc_bus_reset_axicfg0_axi_n */
+#define JH7110_SYSRST_NOC_BUS_CPU_AXI 25 /* rstn_u0_sft7110_noc_bus_reset_cpu_axi_n */
+#define JH7110_SYSRST_NOC_BUS_DISP_AXI 26 /* rstn_u0_sft7110_noc_bus_reset_disp_axi_n */
+#define JH7110_SYSRST_NOC_BUS_GPU_AXI 27 /* rstn_u0_sft7110_noc_bus_reset_gpu_axi_n */
+#define JH7110_SYSRST_NOC_BUS_ISP_AXI 28 /* rstn_u0_sft7110_noc_bus_reset_isp_axi_n */
+#define JH7110_SYSRST_NOC_BUS_DDRC 29 /* rstn_u0_sft7110_noc_bus_reset_ddrc_n */
+#define JH7110_SYSRST_NOC_BUS_STG_AXI 30 /* rstn_u0_sft7110_noc_bus_reset_stg_axi_n */
+#define JH7110_SYSRST_NOC_BUS_VDEC_AXI 31 /* rstn_u0_sft7110_noc_bus_reset_vdec_axi_n */
+
+#define JH7110_SYSRST_NOC_BUS_VENC_AXI 32 /* rstn_u0_sft7110_noc_bus_reset_venc_axi_n */
+#define JH7110_SYSRST_AXI_CFG1_DEC_AHB 33 /* rstn_u0_axi_cfg1_dec_rstn_ahb */
+#define JH7110_SYSRST_AXI_CFG1_DEC_MAIN 34 /* rstn_u0_axi_cfg1_dec_rstn_main */
+#define JH7110_SYSRST_AXI_CFG0_DEC_MAIN 35 /* rstn_u0_axi_cfg0_dec_rstn_main */
+#define JH7110_SYSRST_AXI_CFG0_DEC_MAIN_DIV 36 /* rstn_u0_axi_cfg0_dec_rstn_main_div */
+#define JH7110_SYSRST_AXI_CFG0_DEC_HIFI4 37 /* rstn_u0_axi_cfg0_dec_rstn_hifi4 */
+#define JH7110_SYSRST_DDR_AXI 38 /* rstn_u0_ddr_sft7110_rst_axi */
+#define JH7110_SYSRST_DDR_OSC 39 /* rstn_u0_ddr_sft7110_rst_osc */
+#define JH7110_SYSRST_DDR_APB 40 /* rstn_u0_ddr_sft7110_rst_apb */
+#define JH7110_SYSRST_DOM_ISP_TOP_N 41 /* rstn_u0_dom_isp_top_rstn_ip_top_reset_n */
+#define JH7110_SYSRST_DOM_ISP_TOP_AXI 42 /* rstn_u0_dom_isp_top_rstn_isp_axi */
+#define JH7110_SYSRST_DOM_VOUT_TOP_SRC 43 /* rstn_u0_dom_vout_top_rstn_vout_src */
+#define JH7110_SYSRST_CODAJ12_AXI 44 /* rstn_u0_CODAJ12_rstn_axi */
+#define JH7110_SYSRST_CODAJ12_CORE 45 /* rstn_u0_CODAJ12_rstn_core */
+#define JH7110_SYSRST_CODAJ12_APB 46 /* rstn_u0_CODAJ12_rstn_apb */
+#define JH7110_SYSRST_WAVE511_AXI 47 /* rstn_u0_WAVE511_rstn_axi */
+#define JH7110_SYSRST_WAVE511_BPU 48 /* rstn_u0_WAVE511_rstn_bpu */
+#define JH7110_SYSRST_WAVE511_VCE 49 /* rstn_u0_WAVE511_rstn_vce */
+#define JH7110_SYSRST_WAVE511_APB 50 /* rstn_u0_WAVE511_rstn_apb */
+#define JH7110_SYSRST_VDEC_JPG_ARB_JPG 51 /* rstn_u0_vdec_jpg_arb_jpgresetn */
+#define JH7110_SYSRST_VDEC_JPG_ARB_MAIN 52 /* rstn_u0_vdec_jpg_arb_mainresetn */
+#define JH7110_SYSRST_AXIMEM0_AXI 53 /* rstn_u0_aximem_128b_rstn_axi */
+#define JH7110_SYSRST_WAVE420L_AXI 54 /* rstn_u0_wave420l_rstn_axi */
+#define JH7110_SYSRST_WAVE420L_BPU 55 /* rstn_u0_wave420l_rstn_bpu */
+#define JH7110_SYSRST_WAVE420L_VCE 56 /* rstn_u0_wave420l_rstn_vce */
+#define JH7110_SYSRST_WAVE420L_APB 57 /* rstn_u0_wave420l_rstn_apb */
+#define JH7110_SYSRST_AXIMEM1_AXI 58 /* rstn_u1_aximem_128b_rstn_axi */
+#define JH7110_SYSRST_AXIMEM2_AXI 59 /* rstn_u2_aximem_128b_rstn_axi */
+#define JH7110_SYSRST_INTMEM 60 /* rstn_u0_intmem_rom_sram_rstn_rom */
+#define JH7110_SYSRST_QSPI_AHB 61 /* rstn_u0_cdns_qspi_rstn_ahb */
+#define JH7110_SYSRST_QSPI_APB 62 /* rstn_u0_cdns_qspi_rstn_abb */
+#define JH7110_SYSRST_QSPI_REF 63 /* rstn_u0_cdns_qspi_rstn_ref */
+
+#define JH7110_SYSRST_SDIO0_AHB 64 /* rstn_u0_dw_sdio_rstn_ahb */
+#define JH7110_SYSRST_SDIO1_AHB 65 /* rstn_u1_dw_sdio_rstn_ahb */
+#define JH7110_SYSRST_GMAC1_AXI 66 /* rstn_u1_dw_gmac5_axi64_aresetn_i */
+#define JH7110_SYSRST_GMAC1_AHB 67 /* rstn_u1_dw_gmac5_axi64_hreset_n */
+#define JH7110_SYSRST_MAILBOX 68 /* rstn_u0_mailbox_presetn */
+#define JH7110_SYSRST_SPI0_APB 69 /* rstn_u0_ssp_spi_rstn_apb */
+#define JH7110_SYSRST_SPI1_APB 70 /* rstn_u1_ssp_spi_rstn_apb */
+#define JH7110_SYSRST_SPI2_APB 71 /* rstn_u2_ssp_spi_rstn_apb */
+#define JH7110_SYSRST_SPI3_APB 72 /* rstn_u3_ssp_spi_rstn_apb */
+#define JH7110_SYSRST_SPI4_APB 73 /* rstn_u4_ssp_spi_rstn_apb */
+#define JH7110_SYSRST_SPI5_APB 74 /* rstn_u5_ssp_spi_rstn_apb */
+#define JH7110_SYSRST_SPI6_APB 75 /* rstn_u6_ssp_spi_rstn_apb */
+#define JH7110_SYSRST_I2C0_APB 76 /* rstn_u0_dw_i2c_rstn_apb */
+#define JH7110_SYSRST_I2C1_APB 77 /* rstn_u1_dw_i2c_rstn_apb */
+#define JH7110_SYSRST_I2C2_APB 78 /* rstn_u2_dw_i2c_rstn_apb */
+#define JH7110_SYSRST_I2C3_APB 79 /* rstn_u3_dw_i2c_rstn_apb */
+#define JH7110_SYSRST_I2C4_APB 80 /* rstn_u4_dw_i2c_rstn_apb */
+#define JH7110_SYSRST_I2C5_APB 81 /* rstn_u5_dw_i2c_rstn_apb */
+#define JH7110_SYSRST_I2C6_APB 82 /* rstn_u6_dw_i2c_rstn_apb */
+#define JH7110_SYSRST_UART0_APB 83 /* rstn_u0_dw_uart_rstn_apb */
+#define JH7110_SYSRST_UART0_CORE 84 /* rstn_u0_dw_uart_rstn_core */
+#define JH7110_SYSRST_UART1_APB 85 /* rstn_u1_dw_uart_rstn_apb */
+#define JH7110_SYSRST_UART1_CORE 86 /* rstn_u1_dw_uart_rstn_core */
+#define JH7110_SYSRST_UART2_APB 87 /* rstn_u2_dw_uart_rstn_apb */
+#define JH7110_SYSRST_UART2_CORE 88 /* rstn_u2_dw_uart_rstn_core */
+#define JH7110_SYSRST_UART3_APB 89 /* rstn_u3_dw_uart_rstn_apb */
+#define JH7110_SYSRST_UART3_CORE 90 /* rstn_u3_dw_uart_rstn_core */
+#define JH7110_SYSRST_UART4_APB 91 /* rstn_u4_dw_uart_rstn_apb */
+#define JH7110_SYSRST_UART4_CORE 92 /* rstn_u4_dw_uart_rstn_core */
+#define JH7110_SYSRST_UART5_APB 93 /* rstn_u5_dw_uart_rstn_apb */
+#define JH7110_SYSRST_UART5_CORE 94 /* rstn_u5_dw_uart_rstn_core */
+#define JH7110_SYSRST_SPDIF_APB 95 /* rstn_u0_cdns_spdif_rstn_apb */
+
+#define JH7110_SYSRST_PWMDAC_APB 96 /* rstn_u0_pwmdac_rstn_apb */
+#define JH7110_SYSRST_PDM_DMIC 97 /* rstn_u0_pdm_4mic_rstn_dmic */
+#define JH7110_SYSRST_PDM_APB 98 /* rstn_u0_pdm_4mic_rstn_apb */
+#define JH7110_SYSRST_I2SRX_APB 99 /* rstn_u0_i2srx_3ch_rstn_apb */
+#define JH7110_SYSRST_I2SRX_BCLK 100 /* rstn_u0_i2srx_3ch_rstn_bclk */
+#define JH7110_SYSRST_I2STX0_APB 101 /* rstn_u0_i2stx_4ch_rstn_apb */
+#define JH7110_SYSRST_I2STX0_BCLK 102 /* rstn_u0_i2stx_4ch_rstn_bclk */
+#define JH7110_SYSRST_I2STX1_APB 103 /* rstn_u0_i2stx_4ch_rstn_apb */
+#define JH7110_SYSRST_I2STX1_BCLK 104 /* rstn_u0_i2stx_4ch_rstn_bclk */
+#define JH7110_SYSRST_TDM_AHB 105 /* rstn_u0_tdm16slot_rstn_ahb */
+#define JH7110_SYSRST_TDM_CORE 106 /* rstn_u0_tdm16slot_rstn_tdm */
+#define JH7110_SYSRST_TDM_APB 107 /* rstn_u0_tdm16slot_rstn_apb */
+#define JH7110_SYSRST_PWM_APB 108 /* rstn_u0_pwm_8ch_rstn_apb */
+#define JH7110_SYSRST_WDT_APB 109 /* rstn_u0_dskit_wdt_rstn_apb */
+#define JH7110_SYSRST_WDT_CORE 110 /* rstn_u0_dskit_wdt_rstn_wdt */
+#define JH7110_SYSRST_CAN0_APB 111 /* rstn_u0_can_ctrl_rstn_apb */
+#define JH7110_SYSRST_CAN0_CORE 112 /* rstn_u0_can_ctrl_rstn_can */
+#define JH7110_SYSRST_CAN0_TIMER 113 /* rstn_u0_can_ctrl_rstn_timer */
+#define JH7110_SYSRST_CAN1_APB 114 /* rstn_u1_can_ctrl_rstn_apb */
+#define JH7110_SYSRST_CAN1_CORE 115 /* rstn_u1_can_ctrl_rstn_can */
+#define JH7110_SYSRST_CAN1_TIMER 116 /* rstn_u1_can_ctrl_rstn_timer */
+#define JH7110_SYSRST_TIMER_APB 117 /* rstn_u0_si5_timer_rstn_apb */
+#define JH7110_SYSRST_TIMER0 118 /* rstn_u0_si5_timer_rstn_timer0 */
+#define JH7110_SYSRST_TIMER1 119 /* rstn_u0_si5_timer_rstn_timer1 */
+#define JH7110_SYSRST_TIMER2 120 /* rstn_u0_si5_timer_rstn_timer2 */
+#define JH7110_SYSRST_TIMER3 121 /* rstn_u0_si5_timer_rstn_timer3 */
+#define JH7110_SYSRST_INT_CTRL_APB 122 /* rstn_u0_int_ctrl_rstn_apb */
+#define JH7110_SYSRST_TEMP_APB 123 /* rstn_u0_temp_sensor_rstn_apb */
+#define JH7110_SYSRST_TEMP_CORE 124 /* rstn_u0_temp_sensor_rstn_temp */
+#define JH7110_SYSRST_JTAG_CERTIFICATION 125 /* rstn_u0_jtag_certification_rst_n */
+
+#define JH7110_SYSRST_END 126
+
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_SYS_H__ */
--
Armbian

View File

@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sun, 24 Jul 2022 19:39:05 +0200
Subject: dt-bindings: reset: Add StarFive JH7110 always-on definitions
Add resets for the StarFive JH7110 always-on reset controller.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
include/dt-bindings/reset/starfive-jh7110-aon.h | 20 ++++++++++
1 file changed, 20 insertions(+)
diff --git a/include/dt-bindings/reset/starfive-jh7110-aon.h b/include/dt-bindings/reset/starfive-jh7110-aon.h
new file mode 100644
index 000000000000..fec4bb7c6f3b
--- /dev/null
+++ b/include/dt-bindings/reset/starfive-jh7110-aon.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_AON_H__
+#define __DT_BINDINGS_RESET_STARFIVE_JH7110_AON_H__
+
+#define JH7110_AONRST_GMAC0_AXI 0 /* rstn_u0_u0_dw_gmac5_axi64_rstn_axi */
+#define JH7110_AONRST_GMAC0_AHB 1 /* rstn_u0_u0_dw_gmac5_axi64_rstn_ahb */
+#define JH7110_AONRST_AON_IOMUX 2 /* rstn_u0_aon_iomux_presetn */
+#define JH7110_AONRST_PMU_APB 3 /* rstn_u0_pmu_rstn_apb */
+#define JH7110_AONRST_PMU_WKUP 4 /* rstn_u0_pmu_rstn_wkup */
+#define JH7110_AONRST_RTC_APB 5 /* rstn_u0_rtc_hms_rstn_apb */
+#define JH7110_AONRST_RTC_CAL 6 /* rstn_u0_rtc_hms_rstn_cal */
+#define JH7110_AONRST_RTC_32K 7 /* rstn_u0_u7mc_sft7110_rst_core2 */
+
+#define JH7110_AONRST_END 8
+
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_SYS_H__ */
--
Armbian

View File

@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Wed, 6 Oct 2021 20:42:34 +0200
Subject: dt-bindings: mfd: syscon: Add StarFive JH7100 sysmain compatible
Document StarFive JH7100 SoC compatible for sysmain registers.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 4e4baf53796d..45c3c1d4841d 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -69,6 +69,7 @@ properties:
- samsung,exynos5433-sysreg
- samsung,exynos850-sysreg
- samsung,exynosautov9-sysreg
+ - starfive,jh7100-sysmain
- const: syscon
--
Armbian

View File

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Mon, 8 Aug 2022 17:13:34 +0200
Subject: dt-bindings: net: snps,dwmac: Add dwmac-5.20 version
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
Documentation/devicetree/bindings/net/snps,dwmac.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index 13b984076af5..d8779d3de3d6 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -30,6 +30,7 @@ select:
- snps,dwmac-4.10a
- snps,dwmac-4.20a
- snps,dwmac-5.10a
+ - snps,dwmac-5.20
- snps,dwxgmac
- snps,dwxgmac-2.10
--
Armbian

View File

@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Sun, 7 Aug 2022 22:26:00 +0200
Subject: net: stmmac: platform: Add snps,dwmac-5.20 IP compatible string
Add "snps,dwmac-5.20" compatible string for 5.20 version that can avoid
to define some platform data in the glue layer.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index eb6d9cd8e93f..971a58ab1c24 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -519,7 +519,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
of_device_is_compatible(np, "snps,dwmac-4.10a") ||
of_device_is_compatible(np, "snps,dwmac-4.20a") ||
- of_device_is_compatible(np, "snps,dwmac-5.10a")) {
+ of_device_is_compatible(np, "snps,dwmac-5.10a") ||
+ of_device_is_compatible(np, "snps,dwmac-5.20")) {
plat->has_gmac4 = 1;
plat->has_gmac = 0;
plat->pmt = 1;
--
Armbian

View File

@ -0,0 +1,154 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Mon, 8 Aug 2022 17:15:17 +0200
Subject: dt-bindings: net: Add dwmac-starfive bindings
Add bindings for the DWMAC glue layer for the StarFive JH71x0 SoCs.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
Documentation/devicetree/bindings/net/dwmac-starfive.yaml | 119 ++++++++++
Documentation/devicetree/bindings/net/snps,dwmac.yaml | 2 +
2 files changed, 121 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/dwmac-starfive.yaml b/Documentation/devicetree/bindings/net/dwmac-starfive.yaml
new file mode 100644
index 000000000000..4826895bda6f
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dwmac-starfive.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2022 Emil Renner Berthing
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/net/dwmac-starfive.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: StarFive JH71x0 DWMAC glue layer
+
+maintainers:
+ - Emil Renner Berthing <kernel@esmil.dk>
+
+description:
+ This file documents the platform glue layer for using the stmmac driver on
+ the StarFive JH71x0 RISC-V SoCs.
+
+select:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - starfive,jh7100-gmac
+ - starfive,jh7110-gmac
+ required:
+ - compatible
+
+allOf:
+ - $ref: "snps,dwmac.yaml#"
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: starfive,jh7100-gmac
+ - const: snps,dwmac
+ - items:
+ - const: starfive,jh7110-gmac
+ - const: snps,dwmac-5.20
+
+ reg: true
+
+ clocks:
+ minItems: 4
+ items:
+ - description: GMAC main clock
+ - description: GMAC AHB clock
+ - description: PTP clock
+ - description: GTX clock
+ - description: TX clock
+
+ clock-names:
+ minItems: 4
+ maxItems: 5
+ contains:
+ enum:
+ - stmmaceth
+ - pclk
+ - ptp_ref
+ - gtxc
+ - tx
+
+ starfive,syscon:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+ description: phandle to the syscon node
+
+ starfive,gtxclk-dlychain:
+ $ref: '/schemas/types.yaml#/definitions/uint32'
+ description: GTX clock delay chain setting
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/starfive-jh7110-sys.h>
+ #include <dt-bindings/clock/starfive-jh7110-aon.h>
+ #include <dt-bindings/reset/starfive-jh7110-sys.h>
+ #include <dt-bindings/reset/starfive-jh7110-aon.h>
+
+ gmac0: ethernet@16030000 {
+ compatible = "starfive,jh7110-gmac", "snps,dwmac-5.20";
+ reg = <0x16030000 0x10000>;
+ clocks = <&aoncrg JH7110_AONCLK_GMAC0_AXI>,
+ <&aoncrg JH7110_AONCLK_GMAC0_AHB>,
+ <&syscrg JH7110_SYSCLK_GMAC0_PTP>,
+ <&syscrg JH7110_SYSCLK_GMAC0_GTXC>,
+ <&aoncrg JH7110_AONCLK_GMAC0_TX_INV>;
+ clock-names = "stmmaceth", "pclk", "ptp_ref",
+ "gtxc", "tx";
+ resets = <&aoncrg JH7110_AONRST_GMAC0_AXI>;
+ reset-names = "stmmaceth";
+ interrupts = <7>, <6>, <5>;
+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+ max-frame-size = <9000>;
+ phy-mode = "rgmii-id";
+ snps,multicast-filter-bins = <64>;
+ snps,perfect-filter-entries = <128>;
+ rx-fifo-depth = <2048>;
+ tx-fifo-depth = <2048>;
+ snps,fixed-burst;
+ snps,no-pbl-x8;
+ snps,force_thresh_dma_mode;
+ snps,axi-config = <&stmmac_axi_setup>;
+ snps,tso;
+ snps,en-tx-lpi-clockgating;
+ snps,en-lpi;
+ snps,write-requests = <4>;
+ snps,read-requests = <4>;
+ snps,burst-map = <0x7>;
+ snps,txpbl = <16>;
+ snps,rxpbl = <16>;
+ };
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index d8779d3de3d6..ee32081e6213 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -90,6 +90,8 @@ properties:
- snps,dwmac-5.10a
- snps,dwxgmac
- snps,dwxgmac-2.10
+ - starfive,jh7100-gmac
+ - starfive,jh7110-gmac
reg:
minItems: 1
--
Armbian

View File

@ -0,0 +1,235 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Wed, 29 Sep 2021 20:50:22 +0200
Subject: net: stmmac: Add glue layer for StarFive JH71x0 SoCs
This adds a glue layer for the Synopsys DesignWare MAC IP core on the
StarFive JH71x0 SoCs.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
MAINTAINERS | 6 +
drivers/net/ethernet/stmicro/stmmac/Kconfig | 12 +
drivers/net/ethernet/stmicro/stmmac/Makefile | 1 +
drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c | 158 ++++++++++
4 files changed, 177 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index c783fa9c9d85..0b5252d2d62a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19641,6 +19641,12 @@ M: Emil Renner Berthing <kernel@esmil.dk>
S: Maintained
F: arch/riscv/boot/dts/starfive/
+STARFIVE DWMAC GLUE LAYER
+M: Emil Renner Berthing <kernel@esmil.dk>
+S: Maintained
+F: Documentation/devicetree/bindings/net/dwmac-starfive.yaml
+F: drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+
STARFIVE JH7100 CLOCK DRIVERS
M: Emil Renner Berthing <kernel@esmil.dk>
S: Maintained
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 31ff35174034..afe5bb88962b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -165,6 +165,18 @@ config DWMAC_SOCFPGA
for the stmmac device driver. This driver is used for
arria5 and cyclone5 FPGA SoCs.
+config DWMAC_STARFIVE
+ tristate "StarFive DWMAC support"
+ default m if SOC_STARFIVE
+ depends on SOC_STARFIVE || COMPILE_TEST
+ select MFD_SYSCON
+ help
+ Support for ethernet controller on StarFive SOCs.
+
+ This selects StarFive SoC glue layer support for the stmmac device
+ driver. This driver is used for the JH71x0 series GMAC ethernet
+ controller.
+
config DWMAC_STI
tristate "STi GMAC support"
default ARCH_STI
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index d4e12e9ace4f..09e3c141c2a1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o
obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
+obj-$(CONFIG_DWMAC_STARFIVE) += dwmac-starfive.o
obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
new file mode 100644
index 000000000000..4e1a33940e02
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dwmac-starfive.c - DWMAC glue layer for StarFive SoCs
+ *
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ */
+
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "stmmac.h"
+#include "stmmac_platform.h"
+
+#define JH7100_SYSMAIN_REGISTER28 0x70
+/* The value below is not a typo, just really bad naming by StarFive ¯\_(ツ)_/¯ */
+#define JH7100_SYSMAIN_REGISTER49 0xc8
+
+struct dwmac_starfive {
+ struct device *dev;
+ struct clk *gtxc;
+};
+
+static int dwmac_starfive_jh7100_syscon_init(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct regmap *sysmain;
+ u32 gtxclk_dlychain;
+ int ret;
+
+ sysmain = syscon_regmap_lookup_by_phandle(np, "starfive,syscon");
+ if (IS_ERR(sysmain))
+ return dev_err_probe(dev, PTR_ERR(sysmain),
+ "error getting sysmain registers\n");
+
+ /* Choose RGMII interface to the phy.
+ * TODO: support other interfaces once we know the meaning of other
+ * values in the register
+ */
+ ret = regmap_update_bits(sysmain, JH7100_SYSMAIN_REGISTER28, 0x7, 1);
+ if (ret)
+ return dev_err_probe(dev, ret, "error selecting gmac interface\n");
+
+ if (!of_property_read_u32(np, "starfive,gtxclk-dlychain", &gtxclk_dlychain)) {
+ ret = regmap_write(sysmain, JH7100_SYSMAIN_REGISTER49, gtxclk_dlychain);
+ if (ret)
+ return dev_err_probe(dev, ret, "error selecting gtxclk delay chain\n");
+ }
+
+ return 0;
+}
+
+static void dwmac_starfive_fix_mac_speed(void *data, unsigned int speed)
+{
+ struct dwmac_starfive *dwmac = data;
+ unsigned long rate;
+ int ret;
+
+ switch (speed) {
+ case SPEED_1000:
+ rate = 125000000;
+ break;
+ case SPEED_100:
+ rate = 25000000;
+ break;
+ case SPEED_10:
+ rate = 2500000;
+ break;
+ default:
+ dev_warn(dwmac->dev, "unsupported link speed %u\n", speed);
+ return;
+ }
+
+ ret = clk_set_rate(dwmac->gtxc, rate);
+ if (ret)
+ dev_err(dwmac->dev, "error setting gtx clock rate: %d\n", ret);
+}
+
+static int dwmac_starfive_probe(struct platform_device *pdev)
+{
+ struct stmmac_resources stmmac_res;
+ struct plat_stmmacenet_data *plat;
+ struct dwmac_starfive *dwmac;
+ struct clk *txclk;
+ int (*syscon_init)(struct device *dev);
+ int ret;
+
+ dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
+ if (!dwmac)
+ return -ENOMEM;
+
+ ret = stmmac_get_platform_resources(pdev, &stmmac_res);
+ if (ret)
+ return ret;
+
+ syscon_init = of_device_get_match_data(&pdev->dev);
+ if (syscon_init) {
+ ret = syscon_init(&pdev->dev);
+ if (ret)
+ return ret;
+ }
+
+ dwmac->gtxc = devm_clk_get_enabled(&pdev->dev, "gtxc");
+ if (IS_ERR(dwmac->gtxc))
+ return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->gtxc),
+ "error getting/enabling gtxc clock\n");
+
+ txclk = devm_clk_get_enabled(&pdev->dev, "tx");
+ if (IS_ERR(txclk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(txclk),
+ "error getting/enabling tx clock\n");
+
+ plat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+ if (IS_ERR(plat))
+ return dev_err_probe(&pdev->dev, PTR_ERR(plat),
+ "dt configuration failed\n");
+
+ dwmac->dev = &pdev->dev;
+ plat->bsp_priv = dwmac;
+ plat->fix_mac_speed = dwmac_starfive_fix_mac_speed;
+
+ ret = stmmac_dvr_probe(&pdev->dev, plat, &stmmac_res);
+ if (ret) {
+ stmmac_remove_config_dt(pdev, plat);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id dwmac_starfive_match[] = {
+ {
+ .compatible = "starfive,jh7100-gmac",
+ .data = dwmac_starfive_jh7100_syscon_init,
+ },
+ {
+ .compatible = "starfive,jh7110-gmac",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dwmac_starfive_match);
+
+static struct platform_driver dwmac_starfive_driver = {
+ .probe = dwmac_starfive_probe,
+ .remove = stmmac_pltfr_remove,
+ .driver = {
+ .name = "dwmac-starfive",
+ .pm = &stmmac_pltfr_pm_ops,
+ .of_match_table = dwmac_starfive_match,
+ },
+};
+module_platform_driver(dwmac_starfive_driver);
+
+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
+MODULE_DESCRIPTION("StarFive DWMAC Glue Layer");
+MODULE_LICENSE("GPL");
--
Armbian

View File

@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matteo Croce <technoboy85@gmail.com>
Date: Fri, 21 May 2021 03:26:38 +0200
Subject: net: stmmac: use GFP_DMA32
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index feb209d4b991..c7b9655d8677 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1420,7 +1420,7 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv,
{
struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
+ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
if (priv->dma_cap.addr64 <= 32)
gfp |= GFP_DMA32;
@@ -4576,7 +4576,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
int dirty = stmmac_rx_dirty(priv, queue);
unsigned int entry = rx_q->dirty_rx;
- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
+ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
if (priv->dma_cap.addr64 <= 32)
gfp |= GFP_DMA32;
--
Armbian

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Wed, 22 Sep 2021 16:35:15 +0200
Subject: [WIP] drm/starfive: Support DRM_FORMAT_XRGB8888
When creating dumb buffers with 32bpp and 24bit colour depth this is
default mode return by drm_mode_legacy_fb_format. So we need to support
this for common dumb buffers to just work.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/gpu/drm/starfive/starfive_drm_crtc.c | 1 +
drivers/gpu/drm/starfive/starfive_drm_plane.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/starfive/starfive_drm_crtc.c b/drivers/gpu/drm/starfive/starfive_drm_crtc.c
index 5ba973377059..e31ace35b382 100644
--- a/drivers/gpu/drm/starfive/starfive_drm_crtc.c
+++ b/drivers/gpu/drm/starfive/starfive_drm_crtc.c
@@ -64,6 +64,7 @@ static int ddrfmt_to_ppfmt(struct starfive_crtc *sf_crtc)
case DRM_FORMAT_NV12:
sf_crtc->vpp_format = COLOR_YUV420_NV12;
break;
+ case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
sf_crtc->vpp_format = COLOR_RGB888_ARGB;
break;
diff --git a/drivers/gpu/drm/starfive/starfive_drm_plane.c b/drivers/gpu/drm/starfive/starfive_drm_plane.c
index 119a9fe32769..7ee1d3576211 100644
--- a/drivers/gpu/drm/starfive/starfive_drm_plane.c
+++ b/drivers/gpu/drm/starfive/starfive_drm_plane.c
@@ -28,6 +28,7 @@ static const u32 formats[] = {
DRM_FORMAT_NV21,
DRM_FORMAT_NV12,
+ DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_ABGR8888,
};
--
Armbian

View File

@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "sw.multimedia" <sw.multimedia@starfivetech.com>
Date: Tue, 31 Aug 2021 16:48:57 +0800
Subject: drm/i2c/tda998x: Hardcode register values for Starlight
A proper solution to this hack should be found.
Signed-off-by: jack.zhu <jack.zhu@starfivetech.com>
Signed-off-by: keith.zhao <keith.zhao@starfivetech.com>
---
drivers/gpu/drm/i2c/tda998x_drv.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index d444e7fffb54..bf40966518fd 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1604,7 +1604,9 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
reg |= VIP_CNTRL_3_H_TGL;
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
reg |= VIP_CNTRL_3_V_TGL;
- reg_write(priv, REG_VIP_CNTRL_3, reg);
+ //reg_write(priv, REG_VIP_CNTRL_3, reg);
+ reg_write(priv, REG_VIP_CNTRL_3, 0x26);
+ reg_write(priv, REG_VIDFORMAT, 0x06);
reg_write(priv, REG_VIDFORMAT, 0x00);
reg_write16(priv, REG_REFPIX_MSB, ref_pix);
@@ -1642,7 +1644,8 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
reg |= TBG_CNTRL_1_H_TGL;
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
reg |= TBG_CNTRL_1_V_TGL;
- reg_write(priv, REG_TBG_CNTRL_1, reg);
+ //reg_write(priv, REG_TBG_CNTRL_1, reg);
+ reg_write(priv, REG_TBG_CNTRL_1, 0x46);
/* must be last register set: */
reg_write(priv, REG_TBG_CNTRL_0, 0);
--
Armbian

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Emil Renner Berthing <kernel@esmil.dk>
Date: Tue, 27 Apr 2021 17:05:57 +0200
Subject: spi: cadence-quadspi: Allow compilation on RISC-V
This IP is also used on the StarFive JH7100 riscv64 SoC and presumably
also the upcoming JH7110 SoC.
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
---
drivers/spi/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index d1bb62f7368b..02d35670598e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -230,7 +230,7 @@ config SPI_CADENCE
config SPI_CADENCE_QUADSPI
tristate "Cadence Quad SPI controller"
- depends on OF && (ARM || ARM64 || X86 || COMPILE_TEST)
+ depends on OF && (ARM || ARM64 || RISCV || X86 || COMPILE_TEST)
help
Enable support for the Cadence Quad SPI Flash controller.
--
Armbian