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:
parent
7f11a59c3a
commit
9e29827ad9
47
config/boards/beaglev.wip
Normal file
47
config/boards/beaglev.wip
Normal 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
|
||||
}
|
||||
8
config/boards/mangopi-mq.wip
Normal file
8
config/boards/mangopi-mq.wip
Normal 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
8
config/boards/nezha.wip
Normal 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
34
config/boards/star64.wip
Normal 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
|
||||
}
|
||||
8
config/boards/unleashed.wip
Normal file
8
config/boards/unleashed.wip
Normal 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
|
||||
8
config/boards/unmatched.wip
Normal file
8
config/boards/unmatched.wip
Normal 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
|
||||
47
config/boards/visionfive.wip
Normal file
47
config/boards/visionfive.wip
Normal 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
|
||||
}
|
||||
34
config/boards/visionfive2.wip
Normal file
34
config/boards/visionfive2.wip
Normal 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
|
||||
}
|
||||
6872
config/kernel/linux-d1-edge.config
Normal file
6872
config/kernel/linux-d1-edge.config
Normal file
File diff suppressed because it is too large
Load Diff
9404
config/kernel/linux-starfive-edge.config
Normal file
9404
config/kernel/linux-starfive-edge.config
Normal file
File diff suppressed because it is too large
Load Diff
5474
config/kernel/linux-starfive2-edge.config
Normal file
5474
config/kernel/linux-starfive2-edge.config
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@
|
||||
debian-ports-archive-keyring
|
||||
29
config/sources/families/d1.conf
Normal file
29
config/sources/families/d1.conf
Normal 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
|
||||
}
|
||||
16
config/sources/families/starfive.conf
Normal file
16
config/sources/families/starfive.conf
Normal 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.
|
||||
|
||||
17
config/sources/families/starfive2.conf
Normal file
17
config/sources/families/starfive2.conf
Normal 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.
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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", >xclk_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
|
||||
|
||||
@ -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
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
32860
patch/kernel/archive/starfive-6.1/1046-nvdla-add-NVDLA-driver.patch
Normal file
32860
patch/kernel/archive/starfive-6.1/1046-nvdla-add-NVDLA-driver.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user