Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
0b9180b7cb
@ -110,10 +110,10 @@ define Build/U-Boot/Target
|
||||
endef
|
||||
|
||||
define Build/Configure/U-Boot
|
||||
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(UBOOT_CONFIGURE_VARS) $(UBOOT_CONFIG)_config
|
||||
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) CROSS_COMPILE=$(TARGET_CROSS) $(UBOOT_CONFIGURE_VARS) $(UBOOT_CONFIG)_config
|
||||
$(if $(strip $(UBOOT_CUSTOMIZE_CONFIG)),
|
||||
$(PKG_BUILD_DIR)/scripts/config --file $(PKG_BUILD_DIR)/.config $(UBOOT_CUSTOMIZE_CONFIG)
|
||||
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(UBOOT_CONFIGURE_VARS) oldconfig)
|
||||
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) CROSS_COMPILE=$(TARGET_CROSS) $(UBOOT_CONFIGURE_VARS) oldconfig)
|
||||
endef
|
||||
|
||||
ifndef UBOOT_USE_INTREE_DTC
|
||||
|
@ -686,7 +686,7 @@ define U-Boot/mt7988_rfb-spim-nand
|
||||
BL2_BOOTDEV:=spim-nand
|
||||
BL2_SOC:=mt7988
|
||||
BL2_DDRTYPE:=comb
|
||||
DEPENDS:=+trusted-firmware-a-mt7988-spim-nand-comb
|
||||
DEPENDS:=+trusted-firmware-a-mt7988-spim-nand-comb +trusted-firmware-a-mt7988-spim-nand-ubi-comb
|
||||
endef
|
||||
|
||||
define U-Boot/mt7988_rfb-snand
|
||||
|
@ -87,7 +87,7 @@
|
||||
CONFIG_CLK=y
|
||||
--- a/configs/mt7981_rfb_defconfig
|
||||
+++ b/configs/mt7981_rfb_defconfig
|
||||
@@ -11,7 +11,23 @@ CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
@@ -11,7 +11,22 @@ CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
CONFIG_DEBUG_UART_CLOCK=40000000
|
||||
CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
CONFIG_DEBUG_UART=y
|
||||
@ -106,13 +106,12 @@
|
||||
+CONFIG_LED_BLINK=y
|
||||
+CONFIG_LED_GPIO=y
|
||||
+CONFIG_SPI_BOOT=y
|
||||
+CONFIG_NAND_BOOT=y
|
||||
+CONFIG_BOOTSTD_DEFAULTS=y
|
||||
+CONFIG_BOOTSTD_FULL=y
|
||||
CONFIG_DEFAULT_FDT_FILE="mt7981-rfb"
|
||||
CONFIG_SYS_CBSIZE=512
|
||||
CONFIG_SYS_PBSIZE=1049
|
||||
@@ -22,23 +38,74 @@ CONFIG_SYS_PROMPT="MT7981> "
|
||||
@@ -22,23 +37,74 @@ CONFIG_SYS_PROMPT="MT7981> "
|
||||
# CONFIG_BOOTM_PLAN9 is not set
|
||||
# CONFIG_BOOTM_RTEMS is not set
|
||||
# CONFIG_BOOTM_VXWORKS is not set
|
||||
@ -278,7 +277,7 @@
|
||||
CONFIG_CLK=y
|
||||
--- a/configs/mt7981_snfi_nand_rfb_defconfig
|
||||
+++ b/configs/mt7981_snfi_nand_rfb_defconfig
|
||||
@@ -12,7 +12,23 @@ CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
@@ -12,7 +12,22 @@ CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
CONFIG_DEBUG_UART_CLOCK=40000000
|
||||
CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
CONFIG_DEBUG_UART=y
|
||||
@ -297,13 +296,12 @@
|
||||
+CONFIG_LED_BLINK=y
|
||||
+CONFIG_LED_GPIO=y
|
||||
+CONFIG_SPI_BOOT=y
|
||||
+CONFIG_NAND_BOOT=y
|
||||
+CONFIG_BOOTSTD_DEFAULTS=y
|
||||
+CONFIG_BOOTSTD_FULL=y
|
||||
CONFIG_DEFAULT_FDT_FILE="mt7981-snfi-nand-rfb"
|
||||
CONFIG_LOGLEVEL=7
|
||||
CONFIG_LOG=y
|
||||
@@ -22,22 +38,73 @@ CONFIG_SYS_PBSIZE=1049
|
||||
@@ -22,22 +37,73 @@ CONFIG_SYS_PBSIZE=1049
|
||||
# CONFIG_BOOTM_PLAN9 is not set
|
||||
# CONFIG_BOOTM_RTEMS is not set
|
||||
# CONFIG_BOOTM_VXWORKS is not set
|
||||
|
@ -81,7 +81,7 @@
|
||||
+CONFIG_OF_SYSTEM_SETUP=y
|
||||
--- a/configs/mt7981_rfb_defconfig
|
||||
+++ b/configs/mt7981_rfb_defconfig
|
||||
@@ -135,3 +135,4 @@ CONFIG_DM_SPI=y
|
||||
@@ -134,3 +134,4 @@ CONFIG_DM_SPI=y
|
||||
CONFIG_MTK_SPIM=y
|
||||
CONFIG_HEXDUMP=y
|
||||
CONFIG_LMB_MAX_REGIONS=64
|
||||
@ -95,7 +95,7 @@
|
||||
+CONFIG_OF_SYSTEM_SETUP=y
|
||||
--- a/configs/mt7981_snfi_nand_rfb_defconfig
|
||||
+++ b/configs/mt7981_snfi_nand_rfb_defconfig
|
||||
@@ -120,3 +120,4 @@ CONFIG_DM_SERIAL=y
|
||||
@@ -119,3 +119,4 @@ CONFIG_DM_SERIAL=y
|
||||
CONFIG_MTK_SERIAL=y
|
||||
CONFIG_HEXDUMP=y
|
||||
CONFIG_LMB_MAX_REGIONS=64
|
||||
|
@ -1,3 +1,4 @@
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7986_xiaomi_redmi-ax6000_defconfig
|
||||
@@ -0,0 +1,104 @@
|
||||
+CONFIG_ARM=y
|
||||
|
@ -206,7 +206,7 @@
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7981_openwrt-one-nor_defconfig
|
||||
@@ -0,0 +1,129 @@
|
||||
@@ -0,0 +1,128 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
@ -224,7 +224,6 @@
|
||||
+CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
+CONFIG_DEBUG_UART=y
|
||||
+CONFIG_FIT=y
|
||||
+CONFIG_NAND_BOOT=y
|
||||
+CONFIG_SPI_BOOT=y
|
||||
+CONFIG_AUTOBOOT_MENU_SHOW=y
|
||||
+CONFIG_USE_PREBOOT=y
|
||||
@ -338,7 +337,7 @@
|
||||
+CONFIG_LMB_MAX_REGIONS=64
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7981_openwrt-one-spi-nand_defconfig
|
||||
@@ -0,0 +1,130 @@
|
||||
@@ -0,0 +1,129 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
@ -355,7 +354,6 @@
|
||||
+CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
+CONFIG_DEBUG_UART=y
|
||||
+CONFIG_FIT=y
|
||||
+CONFIG_NAND_BOOT=y
|
||||
+CONFIG_SPI_BOOT=y
|
||||
+CONFIG_AUTOBOOT_MENU_SHOW=y
|
||||
+CONFIG_USE_PREBOOT=y
|
||||
|
@ -90,7 +90,7 @@ mediatek_setup_interfaces()
|
||||
ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3" eth1
|
||||
;;
|
||||
mediatek,mt7988a-rfb)
|
||||
ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3 eth1" eth2
|
||||
ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3 eth2" eth1
|
||||
;;
|
||||
mercusys,mr90x-v1)
|
||||
ucidef_set_interfaces_lan_wan "lan0 lan1 lan2" eth1
|
||||
|
@ -4,28 +4,46 @@ move_config() {
|
||||
. /lib/upgrade/common.sh
|
||||
|
||||
local device="$1"
|
||||
local fstype="$2"
|
||||
[ -n "$device" ] && [ -b "$device" ] && {
|
||||
mount -t vfat "$device" /mnt
|
||||
mount -t "${fstype}" "$device" /mnt
|
||||
[ -f "/mnt/$BACKUP_FILE" ] && mv -f "/mnt/$BACKUP_FILE" /
|
||||
umount /mnt
|
||||
}
|
||||
}
|
||||
|
||||
octeon_get_n821_disk() {
|
||||
local partnum=$1
|
||||
local MAJOR MINOR DEVNAME DEVTYPE
|
||||
while read line; do
|
||||
export -n "${line}"
|
||||
done < $(find /sys/bus/platform/devices/16f0000000000.ehci/ -path \*block/sd[a-z]/uevent)
|
||||
echo "/dev/${DEVNAME}${partnum}"
|
||||
}
|
||||
|
||||
octeon_move_config() {
|
||||
. /lib/functions.sh
|
||||
|
||||
case "$(board_name)" in
|
||||
erlite|\
|
||||
ubnt,usg)
|
||||
move_config "/dev/sda1"
|
||||
move_config "/dev/sda1" "vfat"
|
||||
;;
|
||||
itus,shield-router)
|
||||
move_config "/dev/mmcblk1p1"
|
||||
move_config "/dev/mmcblk1p1" "vfat"
|
||||
;;
|
||||
ubnt,edgerouter-4 | \
|
||||
er|\
|
||||
ubnt,edgerouter-4|\
|
||||
ubnt,edgerouter-6p)
|
||||
move_config "/dev/mmcblk0p1"
|
||||
move_config "/dev/mmcblk0p1" "vfat"
|
||||
;;
|
||||
cisco,vedge1000)
|
||||
# Copy from the internal USB disk's first partition.
|
||||
# It is resolved from the device path to not be dependent on which
|
||||
# /dev/sd? path it is at, nor which UUID it happens to have.
|
||||
move_config "$(octeon_get_n821_disk 1)" "ext2"
|
||||
;;
|
||||
|
||||
esac
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,21 @@
|
||||
# Copyright (C) 2021 OpenWrt.org
|
||||
#
|
||||
|
||||
if [ -x /usr/sbin/blkid ]; then
|
||||
RAMFS_COPY_BIN="/usr/sbin/blkid"
|
||||
fi
|
||||
|
||||
platform_get_rootfs() {
|
||||
local rootfsdev
|
||||
local rootpartuuid
|
||||
|
||||
if read cmdline < /proc/cmdline; then
|
||||
case "$cmdline" in
|
||||
*root=PARTUUID=*)
|
||||
rootpartuuid="${cmdline##*root=PARTUUID=}"
|
||||
rootpartuuid="${rootpartuuid%% *}"
|
||||
rootfsdev="$(blkid -o device -t PARTUUID="${rootpartuuid}")"
|
||||
;;
|
||||
*root=*)
|
||||
rootfsdev="${cmdline##*root=}"
|
||||
rootfsdev="${rootfsdev%% *}"
|
||||
@ -17,10 +27,20 @@ platform_get_rootfs() {
|
||||
fi
|
||||
}
|
||||
|
||||
platform_get_n821_disk() {
|
||||
local partnum=$1
|
||||
local DEVNAME
|
||||
while read line; do
|
||||
export -n "${line}"
|
||||
done < $(find /sys/bus/platform/devices/16f0000000000.ehci/ -path \*block/sd[a-z]/uevent)
|
||||
echo "/dev/${DEVNAME}${partnum}"
|
||||
}
|
||||
|
||||
platform_copy_config_helper() {
|
||||
local device=$1
|
||||
local fstype=$2
|
||||
|
||||
mount -t vfat "$device" /mnt
|
||||
mount -t "${fstype}" "$device" /mnt
|
||||
cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
|
||||
umount /mnt
|
||||
}
|
||||
@ -29,14 +49,18 @@ platform_copy_config() {
|
||||
case "$(board_name)" in
|
||||
erlite|\
|
||||
ubnt,usg)
|
||||
platform_copy_config_helper /dev/sda1
|
||||
platform_copy_config_helper /dev/sda1 vfat
|
||||
;;
|
||||
itus,shield-router)
|
||||
platform_copy_config_helper /dev/mmcblk1p1
|
||||
platform_copy_config_helper /dev/mmcblk1p1 vfat
|
||||
;;
|
||||
er|\
|
||||
ubnt,edgerouter-4|\
|
||||
ubnt,edgerouter-6p)
|
||||
platform_copy_config_helper /dev/mmcblk0p1
|
||||
platform_copy_config_helper /dev/mmcblk0p1 vfat
|
||||
;;
|
||||
cisco,vedge1000)
|
||||
platform_copy_config_helper "$(platform_get_n821_disk 1)" ext2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@ -60,14 +84,26 @@ platform_do_flash() {
|
||||
echo "flashing Itus Kernel to /boot/$kernel (/dev/mmblk1p1)"
|
||||
tar -Oxf $tar_file "$board_dir/kernel" > /boot/$kernel
|
||||
else
|
||||
mount -t vfat /dev/$kernel /boot
|
||||
if [ "${board}" = "cisco,vedge1000" ]; then
|
||||
local rootpartuuid
|
||||
rootpartuuid="$(/usr/sbin/blkid -o value -s PARTUUID "${rootfs}")"
|
||||
if [ -n "${rootpartuuid}" ]; then
|
||||
echo "setting root partition to PARTUUID=${rootpartuuid}"
|
||||
fw_setenv bootcmd 'usb start; ext2load usb 0:1 $loadaddr vmlinux.64; bootoctlinux $loadaddr coremask=f endbootargs rootfstype=squashfs rootwait root=PARTUUID='"${rootpartuuid}"
|
||||
else
|
||||
echo "WARNING: unable to figure out root partition UUID, leaving bootcmd unchanged"
|
||||
fi
|
||||
mount -t ext2 "${kernel}" /boot
|
||||
else
|
||||
mount -t vfat "${kernel}" /boot
|
||||
fi
|
||||
|
||||
[ -f /boot/vmlinux.64 -a ! -L /boot/vmlinux.64 ] && {
|
||||
mv /boot/vmlinux.64 /boot/vmlinux.64.previous
|
||||
mv /boot/vmlinux.64.md5 /boot/vmlinux.64.md5.previous
|
||||
}
|
||||
|
||||
echo "flashing kernel to /dev/$kernel"
|
||||
echo "flashing kernel to $(awk '/\/boot/ {print $1}' /proc/mounts)"
|
||||
tar xf $tar_file $board_dir/kernel -O > /boot/vmlinux.64
|
||||
md5sum /boot/vmlinux.64 | cut -f1 -d " " > /boot/vmlinux.64.md5
|
||||
fi
|
||||
@ -85,20 +121,27 @@ platform_do_upgrade() {
|
||||
local rootfs="$(platform_get_rootfs)"
|
||||
local kernel=
|
||||
|
||||
if [ ! -b "${rootfs}" ] && [ "${board}" = "cisco,vedge1000" ]; then
|
||||
# Default to the built-in USB disk for N821
|
||||
rootfs="$(platform_get_n821_disk 2)"
|
||||
fi
|
||||
[ -b "${rootfs}" ] || return 1
|
||||
case "$board" in
|
||||
er | \
|
||||
ubnt,edgerouter-4 | \
|
||||
ubnt,edgerouter-6p)
|
||||
kernel=mmcblk0p1
|
||||
kernel=/dev/mmcblk0p1
|
||||
;;
|
||||
erlite|\
|
||||
ubnt,usg)
|
||||
kernel=sda1
|
||||
kernel=/dev/sda1
|
||||
;;
|
||||
itus,shield-router)
|
||||
kernel=ItusrouterImage
|
||||
;;
|
||||
cisco,vedge1000)
|
||||
kernel="$(platform_get_n821_disk 1)"
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
esac
|
||||
@ -122,7 +165,8 @@ platform_check_image() {
|
||||
itus,shield-router | \
|
||||
ubnt,edgerouter-4 | \
|
||||
ubnt,edgerouter-6p | \
|
||||
ubnt,usg)
|
||||
ubnt,usg | \
|
||||
cisco,vedge1000)
|
||||
local kernel_length=$(tar xf $tar_file $board_dir/kernel -O | wc -c 2> /dev/null)
|
||||
local rootfs_length=$(tar xf $tar_file $board_dir/root -O | wc -c 2> /dev/null)
|
||||
[ "$kernel_length" = 0 -o "$rootfs_length" = 0 ] && {
|
||||
|
@ -100,13 +100,16 @@ define Device/cisco_vedge1000
|
||||
DEVICE_MODEL := vEdge 1000
|
||||
BOARD_NAME := cisco,vedge1000
|
||||
DEVICE_PACKAGES += \
|
||||
blkid \
|
||||
kmod-hwmon-jc42 \
|
||||
kmod-hwmon-max6697 \
|
||||
kmod-of-mdio \
|
||||
kmod-rtc-ds1307 \
|
||||
kmod-usb-dwc3 \
|
||||
kmod-usb-storage-uas \
|
||||
kmod-usb3
|
||||
kmod-usb3 \
|
||||
sfdisk \
|
||||
uboot-envtools
|
||||
KERNEL := kernel-bin | append-dtb-elf
|
||||
KERNEL_DEPENDS := $$(wildcard $(DTS_DIR)/$(DEVICE_DTS).dts)
|
||||
DEVICE_DTS := cn6130_cisco_vedge1000
|
||||
|
164
target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts
Normal file
164
target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts
Normal file
@ -0,0 +1,164 @@
|
||||
#include "mt7628an.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
compatible = "yuncore,cpe200", "mediatek,mt7628an-soc";
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,57600";
|
||||
};
|
||||
|
||||
aliases {
|
||||
label-mac = ðernet;
|
||||
led-boot = &led_power;
|
||||
led-failsafe = &led_power;
|
||||
led-running = &led_power;
|
||||
led-upgrade = &led_power;
|
||||
};
|
||||
|
||||
keys {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
|
||||
mode {
|
||||
label = "mode";
|
||||
linux,input-type = <EV_SW>;
|
||||
linux,code = <BTN_0>;
|
||||
gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_power: power {
|
||||
function = LED_FUNCTION_POWER;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
lan {
|
||||
function = LED_FUNCTION_LAN;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan {
|
||||
function = LED_FUNCTION_WAN;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
watchdog {
|
||||
compatible = "linux,wdt-gpio";
|
||||
gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
|
||||
hw_algo = "toggle";
|
||||
hw_margin_ms = <20000>;
|
||||
always-running;
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@40000 {
|
||||
label = "factory";
|
||||
reg = <0x40000 0x10000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
macaddr_factory_4: macaddr@4 {
|
||||
reg = <0x4 0x6>;
|
||||
};
|
||||
|
||||
eeprom_factory_8000: eeprom@8000 {
|
||||
reg = <0x8000 0x600>;
|
||||
};
|
||||
|
||||
macaddr_factory_8004: macaddr@8004 {
|
||||
reg = <0x8004 0x6>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
partition@50000 {
|
||||
compatible = "denx,uimage";
|
||||
label = "firmware";
|
||||
reg = <0x50000 0x7b0000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ðernet {
|
||||
nvmem-cells = <&macaddr_factory_4>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
|
||||
&esw {
|
||||
mediatek,portmap = <0x2f>;
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie0 {
|
||||
mt76@0,0 {
|
||||
reg = <0x0000 0 0 0 0>;
|
||||
ieee80211-freq-limit = <5000000 6000000>;
|
||||
nvmem-cells = <&eeprom_factory_8000>, <&macaddr_factory_8004>;
|
||||
nvmem-cell-names = "eeprom", "mac-address";
|
||||
|
||||
led {
|
||||
led-sources = <0>;
|
||||
led-active-low;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&state_default {
|
||||
gpio {
|
||||
groups = "pwm0", "i2c", "refclk", "wdt", "i2s", "spi cs1",
|
||||
"spis", "gpio", "p0led_an", "p1led_an", "p2led_an",
|
||||
"p3led_an", "p4led_an", "wled_kn", "p0led_kn",
|
||||
"p1led_kn", "p2led_kn", "p3led_kn", "p4led_kn", "wled_an";
|
||||
function = "gpio";
|
||||
};
|
||||
};
|
@ -1141,6 +1141,14 @@ define Device/xiaomi_mi-ra75
|
||||
endef
|
||||
TARGET_DEVICES += xiaomi_mi-ra75
|
||||
|
||||
define Device/yuncore_cpe200
|
||||
IMAGE_SIZE := 7872k
|
||||
DEVICE_VENDOR := Yuncore
|
||||
DEVICE_MODEL := CPE200
|
||||
DEVICE_PACKAGES := -kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap kmod-mt7663-firmware-sta
|
||||
endef
|
||||
TARGET_DEVICES += yuncore_cpe200
|
||||
|
||||
define Device/yuncore_m300
|
||||
IMAGE_SIZE := 7872k
|
||||
DEVICE_VENDOR := Yuncore
|
||||
|
@ -19,6 +19,7 @@ asus,rt-n12-vp-b1|\
|
||||
netgear,r6020|\
|
||||
netgear,r6080|\
|
||||
netgear,r6120|\
|
||||
yuncore,cpe200|\
|
||||
yuncore,m300)
|
||||
ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0xf"
|
||||
ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
|
||||
|
@ -204,6 +204,10 @@ ramips_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"0:lan:2" "2:lan:1" "4:wan" "6@eth0"
|
||||
;;
|
||||
yuncore,cpe200)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0:lan" "4:wan" "6@eth0"
|
||||
;;
|
||||
zbtlink,zbt-we1226)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0:lan:2" "1:lan:1" "4:wan" "6@eth0"
|
||||
|
@ -11,6 +11,7 @@ FEATURES:=ext4
|
||||
KERNELNAME:=Image dtbs
|
||||
|
||||
KERNEL_PATCHVER:=6.1
|
||||
KERNEL_TESTING_PATCHVER:=6.6
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
|
||||
|
582
target/linux/starfive/config-6.6
Normal file
582
target/linux/starfive/config-6.6
Normal file
@ -0,0 +1,582 @@
|
||||
CONFIG_64BIT=y
|
||||
# CONFIG_ACPI is not set
|
||||
CONFIG_AMBA_PL08X=y
|
||||
CONFIG_ARCH_CLOCKSOURCE_INIT=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=18
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
|
||||
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
|
||||
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
|
||||
# CONFIG_ARCH_RV32I is not set
|
||||
CONFIG_ARCH_RV64I=y
|
||||
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_ARCH_SIFIVE=y
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
CONFIG_ARCH_STACKWALK=y
|
||||
CONFIG_ARCH_STARFIVE=y
|
||||
# CONFIG_ARCH_THEAD is not set
|
||||
CONFIG_ARCH_WANTS_THP_SWAP=y
|
||||
CONFIG_ARM_AMBA=y
|
||||
# CONFIG_ARM_MHU_V2 is not set
|
||||
CONFIG_ASN1=y
|
||||
CONFIG_ASSOCIATIVE_ARRAY=y
|
||||
CONFIG_AUXILIARY_BUS=y
|
||||
# CONFIG_AX45MP_L2_CACHE is not set
|
||||
# CONFIG_BT_AICUSB is not set
|
||||
CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
|
||||
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
|
||||
CONFIG_CC_NO_ARRAY_BOUNDS=y
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_CLKSRC_MMIO=y
|
||||
CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
|
||||
CONFIG_CLK_SIFIVE=y
|
||||
CONFIG_CLK_SIFIVE_PRCI=y
|
||||
CONFIG_CLK_STARFIVE_JH7100=y
|
||||
CONFIG_CLK_STARFIVE_JH7100_AUDIO=y
|
||||
CONFIG_CLK_STARFIVE_JH7110_AON=y
|
||||
CONFIG_CLK_STARFIVE_JH7110_ISP=y
|
||||
CONFIG_CLK_STARFIVE_JH7110_PLL=y
|
||||
CONFIG_CLK_STARFIVE_JH7110_STG=y
|
||||
CONFIG_CLK_STARFIVE_JH7110_SYS=y
|
||||
CONFIG_CLK_STARFIVE_JH7110_VOUT=y
|
||||
CONFIG_CLK_STARFIVE_JH71X0=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CLZ_TAB=y
|
||||
CONFIG_CMODEL_MEDANY=y
|
||||
# CONFIG_CMODEL_MEDLOW is not set
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
|
||||
# CONFIG_COMPAT_32BIT_TIME is not set
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
CONFIG_CONTEXT_TRACKING=y
|
||||
CONFIG_CONTEXT_TRACKING_IDLE=y
|
||||
CONFIG_CONTIG_ALLOC=y
|
||||
CONFIG_CPUFREQ_DT=y
|
||||
CONFIG_CPUFREQ_DT_PLATDEV=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
|
||||
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
|
||||
CONFIG_CPU_FREQ_GOV_COMMON=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_CPU_IDLE_GOV_MENU=y
|
||||
CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
|
||||
CONFIG_CPU_PM=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CRASH_CORE=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRC7=y
|
||||
CONFIG_CRC_ITU_T=y
|
||||
CONFIG_CRYPTO_BLAKE2B=y
|
||||
CONFIG_CRYPTO_CMAC=y
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
CONFIG_CRYPTO_DEV_JH7110=y
|
||||
CONFIG_CRYPTO_DRBG=y
|
||||
CONFIG_CRYPTO_DRBG_HMAC=y
|
||||
CONFIG_CRYPTO_DRBG_MENU=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_ECC=y
|
||||
CONFIG_CRYPTO_ECDH=y
|
||||
CONFIG_CRYPTO_ENGINE=y
|
||||
CONFIG_CRYPTO_HASH_INFO=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
|
||||
CONFIG_CRYPTO_LIB_SHA1=y
|
||||
CONFIG_CRYPTO_LIB_SHA256=y
|
||||
CONFIG_CRYPTO_LIB_UTILS=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_RNG_DEFAULT=y
|
||||
CONFIG_CRYPTO_RSA=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_CRYPTO_SHA512=y
|
||||
CONFIG_CRYPTO_SM3=y
|
||||
CONFIG_CRYPTO_SM3_GENERIC=y
|
||||
CONFIG_CRYPTO_USER=y
|
||||
CONFIG_CRYPTO_USER_API=y
|
||||
CONFIG_CRYPTO_USER_API_AEAD=y
|
||||
CONFIG_CRYPTO_USER_API_HASH=y
|
||||
CONFIG_CRYPTO_USER_API_RNG=y
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=y
|
||||
CONFIG_CRYPTO_XXHASH=y
|
||||
CONFIG_CRYPTO_ZSTD=y
|
||||
CONFIG_DEBUG_ATOMIC_SLEEP=y
|
||||
CONFIG_DEBUG_GPIO=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_PINCTRL=y
|
||||
CONFIG_DEBUG_RODATA_TEST=y
|
||||
CONFIG_DEBUG_RT_MUTEXES=y
|
||||
CONFIG_DEBUG_RWSEMS=y
|
||||
CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||
CONFIG_DEBUG_SG=y
|
||||
CONFIG_DEBUG_SPINLOCK=y
|
||||
CONFIG_DEBUG_TIMEKEEPING=y
|
||||
CONFIG_DEBUG_WX=y
|
||||
CONFIG_DECOMPRESS_GZIP=y
|
||||
# CONFIG_DEVFREQ_GOV_PASSIVE is not set
|
||||
# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
|
||||
# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
|
||||
# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
|
||||
# CONFIG_DEVFREQ_GOV_USERSPACE is not set
|
||||
# CONFIG_DEVFREQ_THERMAL is not set
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_DEVTMPFS_SAFE is not set
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMADEVICES_DEBUG=y
|
||||
CONFIG_DMADEVICES_VDEBUG=y
|
||||
CONFIG_DMA_ENGINE=y
|
||||
CONFIG_DMA_OF=y
|
||||
CONFIG_DMA_SHARED_BUFFER=y
|
||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
||||
# CONFIG_DPM_WATCHDOG is not set
|
||||
CONFIG_DTC=y
|
||||
CONFIG_DT_IDLE_GENPD=y
|
||||
CONFIG_DT_IDLE_STATES=y
|
||||
CONFIG_DWMAC_DWC_QOS_ETH=y
|
||||
# CONFIG_DWMAC_GENERIC is not set
|
||||
CONFIG_DWMAC_STARFIVE=y
|
||||
CONFIG_DW_AXI_DMAC=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
CONFIG_EEPROM_AT24=y
|
||||
CONFIG_EFI=y
|
||||
CONFIG_EFIVAR_FS=y
|
||||
# CONFIG_EFI_BOOTLOADER_CONTROL is not set
|
||||
# CONFIG_EFI_CAPSULE_LOADER is not set
|
||||
# CONFIG_EFI_COCO_SECRET is not set
|
||||
# CONFIG_EFI_DISABLE_PCI_DMA is not set
|
||||
CONFIG_EFI_DISABLE_RUNTIME=y
|
||||
CONFIG_EFI_EARLYCON=y
|
||||
CONFIG_EFI_ESRT=y
|
||||
CONFIG_EFI_GENERIC_STUB=y
|
||||
CONFIG_EFI_PARAMS_FROM_FDT=y
|
||||
CONFIG_EFI_RUNTIME_WRAPPERS=y
|
||||
CONFIG_EFI_STUB=y
|
||||
# CONFIG_EFI_TEST is not set
|
||||
# CONFIG_EFI_ZBOOT is not set
|
||||
# CONFIG_ERRATA_ANDES is not set
|
||||
CONFIG_ERRATA_STARFIVE_JH7100=y
|
||||
CONFIG_ERRATA_SIFIVE=y
|
||||
CONFIG_ERRATA_SIFIVE_CIP_1200=y
|
||||
CONFIG_ERRATA_SIFIVE_CIP_453=y
|
||||
# CONFIG_ERRATA_THEAD is not set
|
||||
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_FAILOVER=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
|
||||
CONFIG_FAT_DEFAULT_UTF8=y
|
||||
CONFIG_FAT_FS=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FIX_EARLYCON_MEM=y
|
||||
CONFIG_FONT_8x16=y
|
||||
CONFIG_FONT_AUTOSELECT=y
|
||||
CONFIG_FONT_SUPPORT=y
|
||||
CONFIG_FPU=y
|
||||
CONFIG_FS_IOMAP=y
|
||||
CONFIG_FS_MBCACHE=y
|
||||
CONFIG_FS_POSIX_ACL=y
|
||||
CONFIG_FWNODE_MDIO=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_FW_LOADER_SYSFS=y
|
||||
CONFIG_GCC11_NO_ARRAY_BOUNDS=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_ARCH_TOPOLOGY=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_CSUM=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IOREMAP=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_IRQ_MIGRATION=y
|
||||
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_PHY_MIPI_DPHY=y
|
||||
CONFIG_GENERIC_PINCONF=y
|
||||
CONFIG_GENERIC_PINCTRL_GROUPS=y
|
||||
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GLOB=y
|
||||
CONFIG_GPIOLIB_FASTPATH_LIMIT=128
|
||||
CONFIG_GPIOLIB_IRQCHIP=y
|
||||
CONFIG_GPIO_CDEV=y
|
||||
CONFIG_GPIO_TPS65086=y
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_HUGETLB_PAGE=y
|
||||
CONFIG_HVC_DRIVER=y
|
||||
CONFIG_HVC_RISCV_SBI=y
|
||||
CONFIG_HWMON=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_JH7110=y
|
||||
CONFIG_HW_RANDOM_STARFIVE_VIC=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_ALGOBIT=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_DESIGNWARE_CORE=y
|
||||
CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
# CONFIG_IPMS_CAN is not set
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_STACKS=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_JBD2=y
|
||||
CONFIG_JH71XX_PMU=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
CONFIG_LSM=""
|
||||
CONFIG_MARVELL_PHY=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
CONFIG_MEMORY_ISOLATION=y
|
||||
CONFIG_MEMTEST=y
|
||||
CONFIG_MFD_AXP20X=y
|
||||
CONFIG_MFD_AXP20X_I2C=y
|
||||
CONFIG_MFD_CORE=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MFD_TPS65086=y
|
||||
CONFIG_MICREL_PHY=y
|
||||
CONFIG_MICROCHIP_PHY=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK=y
|
||||
CONFIG_MMC_DEBUG=y
|
||||
CONFIG_MMC_DW=y
|
||||
# CONFIG_MMC_DW_BLUEFIELD is not set
|
||||
# CONFIG_MMC_DW_EXYNOS is not set
|
||||
# CONFIG_MMC_DW_HI3798CV200 is not set
|
||||
# CONFIG_MMC_DW_K3 is not set
|
||||
# CONFIG_MMC_DW_PCI is not set
|
||||
CONFIG_MMC_DW_PLTFM=y
|
||||
CONFIG_MMC_DW_STARFIVE=y
|
||||
CONFIG_MMIOWB=y
|
||||
CONFIG_MODULES_TREE_LOOKUP=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_MODULE_SECTIONS=y
|
||||
CONFIG_MOTORCOMM_PHY=y
|
||||
CONFIG_MPILIB=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NET_FAILOVER=y
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_NS=y
|
||||
CONFIG_NET_SELFTESTS=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_DEFAULT="iso8859-15"
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_NLS_ISO8859_15=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NONPORTABLE=y
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_NVMEM_SYSFS=y
|
||||
CONFIG_NVME_CORE=y
|
||||
CONFIG_NVME_HWMON=y
|
||||
# CONFIG_NVME_MULTIPATH is not set
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
# CONFIG_OF_CONFIGFS is not set
|
||||
CONFIG_OF_DMA_DEFAULT_COHERENT=y
|
||||
CONFIG_OF_DYNAMIC=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_OVERLAY=y
|
||||
CONFIG_OF_RESOLVE=y
|
||||
CONFIG_OID_REGISTRY=y
|
||||
CONFIG_OVERLAY_FS_INDEX=y
|
||||
CONFIG_OVERLAY_FS_METACOPY=y
|
||||
CONFIG_OVERLAY_FS_REDIRECT_DIR=y
|
||||
CONFIG_PADATA=y
|
||||
CONFIG_PAGE_EXTENSION=y
|
||||
CONFIG_PAGE_OFFSET=0xff60000000000000
|
||||
CONFIG_PAGE_POOL=y
|
||||
CONFIG_PAGE_REPORTING=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIE_CADENCE=y
|
||||
CONFIG_PCIE_CADENCE_HOST=y
|
||||
CONFIG_PCIE_CADENCE_PLAT=y
|
||||
CONFIG_PCIE_CADENCE_PLAT_HOST=y
|
||||
# CONFIG_PCIE_FU740 is not set
|
||||
CONFIG_PCIE_STARFIVE_HOST=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DOMAINS_GENERIC=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PCI_MSI_IRQ_DOMAIN=y
|
||||
CONFIG_PCS_XPCS=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
CONFIG_PGTABLE_LEVELS=5
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYLINK=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
# CONFIG_PHYS_RAM_BASE_FIXED is not set
|
||||
CONFIG_PHY_STARFIVE_DPHY_RX=y
|
||||
CONFIG_PHY_STARFIVE_JH7110_DPHY_RX=y
|
||||
CONFIG_PHY_STARFIVE_JH7110_PCIE=y
|
||||
CONFIG_PHY_STARFIVE_JH7110_USB=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_STARFIVE_JH7100=y
|
||||
CONFIG_PINCTRL_STARFIVE_JH7110=y
|
||||
CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
|
||||
CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_ADVANCED_DEBUG=y
|
||||
CONFIG_PM_CLK=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_PM_DEVFREQ=y
|
||||
# CONFIG_PM_DEVFREQ_EVENT is not set
|
||||
CONFIG_PM_GENERIC_DOMAINS=y
|
||||
CONFIG_PM_GENERIC_DOMAINS_OF=y
|
||||
CONFIG_PM_OPP=y
|
||||
CONFIG_PORTABLE=y
|
||||
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_RESET_GPIO_RESTART=y
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
|
||||
# CONFIG_POWER_RESET_TPS65086 is not set
|
||||
CONFIG_PPS=y
|
||||
CONFIG_PREEMPT_COUNT=y
|
||||
CONFIG_PREEMPT_NONE_BUILD=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_PROC_CHILDREN=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_PTDUMP_CORE=y
|
||||
CONFIG_PTP_1588_CLOCK=y
|
||||
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_OCORES=y
|
||||
# CONFIG_PWM_SIFIVE is not set
|
||||
CONFIG_PWM_SIFIVE_PTC=y
|
||||
CONFIG_PWM_STARFIVE_PTC=y
|
||||
CONFIG_PWM_SYSFS=y
|
||||
CONFIG_QUEUED_RWLOCKS=y
|
||||
CONFIG_RANDSTRUCT_NONE=y
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_RCU_EQS_DEBUG=y
|
||||
CONFIG_RD_GZIP=y
|
||||
CONFIG_REALTEK_PHY=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_I2C=y
|
||||
CONFIG_REGMAP_IRQ=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_AXP20X=y
|
||||
CONFIG_REGULATOR_STARFIVE_JH7110=y
|
||||
CONFIG_REGULATOR_TPS65086=y
|
||||
# CONFIG_RESET_ATTACK_MITIGATION is not set
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_RESET_SIMPLE=y
|
||||
CONFIG_RESET_STARFIVE_JH7100=y
|
||||
CONFIG_RESET_STARFIVE_JH7100_AUDIO=y
|
||||
CONFIG_RESET_STARFIVE_JH7110=y
|
||||
CONFIG_RESET_STARFIVE_JH71X0=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RISCV=y
|
||||
CONFIG_RISCV_ALTERNATIVE=y
|
||||
CONFIG_RISCV_BOOT_SPINWAIT=y
|
||||
CONFIG_RISCV_DMA_NONCOHERENT=y
|
||||
CONFIG_RISCV_INTC=y
|
||||
CONFIG_RISCV_ISA_C=y
|
||||
CONFIG_RISCV_ISA_FALLBACK=y
|
||||
CONFIG_RISCV_ISA_SVNAPOT=y
|
||||
# CONFIG_RISCV_ISA_SVPBMT is not set
|
||||
CONFIG_RISCV_ISA_V=y
|
||||
CONFIG_RISCV_ISA_V_DEFAULT_ENABLE=y
|
||||
CONFIG_RISCV_ISA_ZBB=y
|
||||
# CONFIG_RISCV_ISA_ZICBOM is not set
|
||||
CONFIG_RISCV_ISA_ZICBOZ=y
|
||||
CONFIG_RISCV_PMU=y
|
||||
CONFIG_RISCV_PMU_LEGACY=y
|
||||
CONFIG_RISCV_PMU_SBI=y
|
||||
CONFIG_RISCV_SBI=y
|
||||
CONFIG_RISCV_SBI_CPUIDLE=y
|
||||
CONFIG_RISCV_SBI_V01=y
|
||||
CONFIG_RISCV_TIMER=y
|
||||
CONFIG_RPMSG=y
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
# CONFIG_RPMSG_CTRL is not set
|
||||
CONFIG_RPMSG_NS=y
|
||||
# CONFIG_RPMSG_TTY is not set
|
||||
CONFIG_RPMSG_VIRTIO=y
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
# CONFIG_RTC_DRV_EFI is not set
|
||||
CONFIG_RTC_DRV_GOLDFISH=y
|
||||
CONFIG_RTC_DRV_HYM8563=y
|
||||
CONFIG_RTC_DRV_STARFIVE=y
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_SCSI_COMMON=y
|
||||
CONFIG_SCSI_VIRTIO=y
|
||||
CONFIG_SENSORS_SFCTEMP=y
|
||||
# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_8250_DWLIB=y
|
||||
CONFIG_SERIAL_8250_EXTENDED=y
|
||||
CONFIG_SERIAL_8250_MANY_PORTS=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=6
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=6
|
||||
# CONFIG_SERIAL_8250_SHARE_IRQ is not set
|
||||
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
|
||||
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SERIAL_SIFIVE=y
|
||||
CONFIG_SERIAL_SIFIVE_CONSOLE=y
|
||||
CONFIG_SGL_ALLOC=y
|
||||
CONFIG_SG_POOL=y
|
||||
CONFIG_SIFIVE_CCACHE=y
|
||||
CONFIG_SIFIVE_PLIC=y
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_SND_SOC_AC108 is not set
|
||||
# CONFIG_SND_SOC_STARFIVE is not set
|
||||
CONFIG_SOCK_DIAG=y
|
||||
CONFIG_SOCK_RX_QUEUE_MAPPING=y
|
||||
# CONFIG_SOC_MICROCHIP_POLARFIRE is not set
|
||||
CONFIG_SOC_SIFIVE=y
|
||||
CONFIG_SOC_STARFIVE=y
|
||||
# CONFIG_SOC_VIRT is not set
|
||||
CONFIG_SOFTLOCKUP_DETECTOR=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_CADENCE_QUADSPI=y
|
||||
CONFIG_SPI_DYNAMIC=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPI_MEM=y
|
||||
CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_STARFIVE_TIMER=y
|
||||
CONFIG_STARFIVE_JH7110_TIMER=y
|
||||
CONFIG_STARFIVE_WATCHDOG=y
|
||||
CONFIG_STMMAC_ETH=y
|
||||
CONFIG_STMMAC_PLATFORM=y
|
||||
CONFIG_STMMAC_SELFTESTS=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYNC_FILE=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
# CONFIG_SYSFB_SIMPLEFB is not set
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
|
||||
CONFIG_THERMAL_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_OF=y
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_THREAD_SIZE_ORDER=2
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TIMER_OF=y
|
||||
CONFIG_TIMER_PROBE=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_TOOLCHAIN_HAS_ZICBOM=y
|
||||
CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE=y
|
||||
CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y
|
||||
# CONFIG_TOUCHSCREEN_TINKER_FT5406 is not set
|
||||
CONFIG_TREE_RCU=y
|
||||
CONFIG_TREE_SRCU=y
|
||||
CONFIG_TTY_PRINTK=y
|
||||
CONFIG_TTY_PRINTK_LEVEL=6
|
||||
CONFIG_TUNE_GENERIC=y
|
||||
CONFIG_UCS2_STRING=y
|
||||
CONFIG_UNINLINE_SPIN_UNLOCK=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_COMMON=y
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
# CONFIG_USB_CONFIGFS_ACM is not set
|
||||
# CONFIG_USB_CONFIGFS_ECM is not set
|
||||
# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
|
||||
# CONFIG_USB_CONFIGFS_EEM is not set
|
||||
CONFIG_USB_CONFIGFS_F_FS=y
|
||||
# CONFIG_USB_CONFIGFS_F_HID is not set
|
||||
# CONFIG_USB_CONFIGFS_F_LB_SS is not set
|
||||
# CONFIG_USB_CONFIGFS_F_MIDI is not set
|
||||
# CONFIG_USB_CONFIGFS_F_MIDI2 is not set
|
||||
# CONFIG_USB_CONFIGFS_F_PRINTER is not set
|
||||
# CONFIG_USB_CONFIGFS_F_UAC1 is not set
|
||||
# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
|
||||
# CONFIG_USB_CONFIGFS_F_UAC2 is not set
|
||||
# CONFIG_USB_CONFIGFS_F_UVC is not set
|
||||
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
|
||||
# CONFIG_USB_CONFIGFS_NCM is not set
|
||||
# CONFIG_USB_CONFIGFS_OBEX is not set
|
||||
# CONFIG_USB_CONFIGFS_RNDIS is not set
|
||||
# CONFIG_USB_CONFIGFS_SERIAL is not set
|
||||
CONFIG_USB_F_FS=y
|
||||
CONFIG_USB_F_MASS_STORAGE=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_LIBCOMPOSITE=y
|
||||
CONFIG_USB_PCI=y
|
||||
CONFIG_USB_PHY=y
|
||||
CONFIG_USB_ROLE_SWITCH=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
# CONFIG_USB_UHCI_HCD is not set
|
||||
CONFIG_USELIB=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
# CONFIG_VIDEO_STF_VIN is not set
|
||||
# CONFIG_VIRTIO_BLK is not set
|
||||
# CONFIG_VIRTIO_NET is not set
|
||||
CONFIG_VMAP_STACK=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_WATCHDOG_SYSFS=y
|
||||
CONFIG_WERROR=y
|
||||
CONFIG_WQ_WATCHDOG=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_XXHASH=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
CONFIG_ZONE_DMA32=y
|
@ -0,0 +1,76 @@
|
||||
From 69275b667bd930cf5d5f577ba0ab1987c9d13987 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Mon, 21 Aug 2023 23:29:15 +0800
|
||||
Subject: [PATCH 001/116] clk: starfive: jh7110-sys: Fix lower rate of CPUfreq
|
||||
by setting PLL0 rate to 1.5GHz
|
||||
|
||||
CPUfreq supports 4 cpu frequency loads on 375/500/750/1500MHz.
|
||||
But now PLL0 rate is 1GHz and the cpu frequency loads become
|
||||
333/500/500/1000MHz in fact.
|
||||
|
||||
So PLL0 rate should be set to 1.5GHz. Change the parent of cpu_root clock
|
||||
and the divider of cpu_core before the setting.
|
||||
|
||||
Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Fixes: e2c510d6d630 ("riscv: dts: starfive: Add cpu scaling for JH7110 SoC")
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
.../clk/starfive/clk-starfive-jh7110-sys.c | 47 ++++++++++++++++++-
|
||||
1 file changed, 46 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
|
||||
+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
|
||||
@@ -501,7 +501,52 @@ static int __init jh7110_syscrg_probe(st
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- return jh7110_reset_controller_register(priv, "rst-sys", 0);
|
||||
+ ret = jh7110_reset_controller_register(priv, "rst-sys", 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /*
|
||||
+ * Set PLL0 rate to 1.5GHz
|
||||
+ * In order to not affect the cpu when the PLL0 rate is changing,
|
||||
+ * we need to switch the parent of cpu_root clock to osc clock first,
|
||||
+ * and then switch back after setting the PLL0 rate.
|
||||
+ */
|
||||
+ pllclk = clk_get(priv->dev, "pll0_out");
|
||||
+ if (!IS_ERR(pllclk)) {
|
||||
+ struct clk *osc = clk_get(&pdev->dev, "osc");
|
||||
+ struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk;
|
||||
+ struct clk *cpu_core = priv->reg[JH7110_SYSCLK_CPU_CORE].hw.clk;
|
||||
+
|
||||
+ if (IS_ERR(osc)) {
|
||||
+ clk_put(pllclk);
|
||||
+ return PTR_ERR(osc);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * CPU need voltage regulation by CPUfreq if set 1.5GHz.
|
||||
+ * So in this driver, cpu_core need to be set the divider to be 2 first
|
||||
+ * and will be 750M after setting parent.
|
||||
+ */
|
||||
+ ret = clk_set_rate(cpu_core, clk_get_rate(cpu_core) / 2);
|
||||
+ if (ret)
|
||||
+ goto failed_set;
|
||||
+
|
||||
+ ret = clk_set_parent(cpu_root, osc);
|
||||
+ if (ret)
|
||||
+ goto failed_set;
|
||||
+
|
||||
+ ret = clk_set_rate(pllclk, 1500000000);
|
||||
+ if (ret)
|
||||
+ goto failed_set;
|
||||
+
|
||||
+ ret = clk_set_parent(cpu_root, pllclk);
|
||||
+
|
||||
+failed_set:
|
||||
+ clk_put(pllclk);
|
||||
+ clk_put(osc);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id jh7110_syscrg_match[] = {
|
@ -0,0 +1,114 @@
|
||||
From 7d0dbcbc079e4f72b69f53442b7759da6ebc4f87 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Thu, 19 Oct 2023 13:34:59 +0800
|
||||
Subject: [PATCH 002/116] dt-bindings: timer: Add timer for StarFive JH7110 SoC
|
||||
|
||||
Add bindings for the timer on the JH7110 RISC-V SoC
|
||||
by StarFive Technology Ltd.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
.../bindings/timer/starfive,jh7110-timer.yaml | 96 +++++++++++++++++++
|
||||
1 file changed, 96 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
|
||||
@@ -0,0 +1,96 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/timer/starfive,jh7110-timer.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 Timer
|
||||
+
|
||||
+maintainers:
|
||||
+ - Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+ - Samin Guo <samin.guo@starfivetech.com>
|
||||
+
|
||||
+description:
|
||||
+ This timer has four free-running 32 bit counters in StarFive JH7110 SoC.
|
||||
+ And each channel(counter) triggers an interrupt when timeout. They support
|
||||
+ one-shot mode and continuous-run mode.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-timer
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ interrupts:
|
||||
+ items:
|
||||
+ - description: channel 0
|
||||
+ - description: channel 1
|
||||
+ - description: channel 2
|
||||
+ - description: channel 3
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: timer APB
|
||||
+ - description: channel 0
|
||||
+ - description: channel 1
|
||||
+ - description: channel 2
|
||||
+ - description: channel 3
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: apb
|
||||
+ - const: ch0
|
||||
+ - const: ch1
|
||||
+ - const: ch2
|
||||
+ - const: ch3
|
||||
+
|
||||
+ resets:
|
||||
+ items:
|
||||
+ - description: timer APB
|
||||
+ - description: channel 0
|
||||
+ - description: channel 1
|
||||
+ - description: channel 2
|
||||
+ - description: channel 3
|
||||
+
|
||||
+ reset-names:
|
||||
+ items:
|
||||
+ - const: apb
|
||||
+ - const: ch0
|
||||
+ - const: ch1
|
||||
+ - const: ch2
|
||||
+ - const: ch3
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - interrupts
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - reset-names
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ timer@13050000 {
|
||||
+ compatible = "starfive,jh7110-timer";
|
||||
+ reg = <0x13050000 0x10000>;
|
||||
+ interrupts = <69>, <70>, <71> ,<72>;
|
||||
+ clocks = <&clk 124>,
|
||||
+ <&clk 125>,
|
||||
+ <&clk 126>,
|
||||
+ <&clk 127>,
|
||||
+ <&clk 128>;
|
||||
+ clock-names = "apb", "ch0", "ch1",
|
||||
+ "ch2", "ch3";
|
||||
+ resets = <&rst 117>,
|
||||
+ <&rst 118>,
|
||||
+ <&rst 119>,
|
||||
+ <&rst 120>,
|
||||
+ <&rst 121>;
|
||||
+ reset-names = "apb", "ch0", "ch1",
|
||||
+ "ch2", "ch3";
|
||||
+ };
|
||||
+
|
@ -0,0 +1,428 @@
|
||||
From 7cb47848f8a10aed6e050c0ea483b4bb5eaa62a4 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Thu, 19 Oct 2023 13:35:00 +0800
|
||||
Subject: [PATCH 003/116] clocksource: Add JH7110 timer driver
|
||||
|
||||
Add timer driver for the StarFive JH7110 SoC.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
---
|
||||
drivers/clocksource/Kconfig | 11 +
|
||||
drivers/clocksource/Makefile | 1 +
|
||||
drivers/clocksource/timer-jh7110.c | 380 +++++++++++++++++++++++++++++
|
||||
3 files changed, 392 insertions(+)
|
||||
create mode 100644 drivers/clocksource/timer-jh7110.c
|
||||
|
||||
--- a/drivers/clocksource/Kconfig
|
||||
+++ b/drivers/clocksource/Kconfig
|
||||
@@ -641,6 +641,17 @@ config RISCV_TIMER
|
||||
is accessed via both the SBI and the rdcycle instruction. This is
|
||||
required for all RISC-V systems.
|
||||
|
||||
+config STARFIVE_JH7110_TIMER
|
||||
+ bool "Timer for the STARFIVE JH7110 SoC"
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ select TIMER_OF
|
||||
+ select CLKSRC_MMIO
|
||||
+ default ARCH_STARFIVE
|
||||
+ help
|
||||
+ This enables the timer for StarFive JH7110 SoC. On RISC-V platform,
|
||||
+ the system has started RISCV_TIMER, but you can also use this timer
|
||||
+ which can provide four channels to do a lot more things on JH7110 SoC.
|
||||
+
|
||||
config CLINT_TIMER
|
||||
bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST
|
||||
depends on GENERIC_SCHED_CLOCK && RISCV
|
||||
--- a/drivers/clocksource/Makefile
|
||||
+++ b/drivers/clocksource/Makefile
|
||||
@@ -80,6 +80,7 @@ obj-$(CONFIG_INGENIC_TIMER) += ingenic-
|
||||
obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
|
||||
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
|
||||
obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
|
||||
+obj-$(CONFIG_STARFIVE_JH7110_TIMER) += timer-jh7110.o
|
||||
obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
|
||||
obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
|
||||
obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/clocksource/timer-jh7110.c
|
||||
@@ -0,0 +1,380 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Starfive JH7110 Timer driver
|
||||
+ *
|
||||
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
|
||||
+ *
|
||||
+ * Author:
|
||||
+ * Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+ * Samin Guo <samin.guo@starfivetech.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clockchips.h>
|
||||
+#include <linux/clocksource.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/sched_clock.h>
|
||||
+
|
||||
+/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */
|
||||
+#define JH7110_TIMER_CH_LEN 0x40
|
||||
+#define JH7110_TIMER_CH_BASE(x) ((x) * JH7110_TIMER_CH_LEN)
|
||||
+#define JH7110_TIMER_CH_MAX 4
|
||||
+
|
||||
+#define JH7110_CLOCK_SOURCE_RATING 200
|
||||
+#define JH7110_VALID_BITS 32
|
||||
+#define JH7110_DELAY_US 0
|
||||
+#define JH7110_TIMEOUT_US 10000
|
||||
+#define JH7110_CLOCKEVENT_RATING 300
|
||||
+#define JH7110_TIMER_MAX_TICKS 0xffffffff
|
||||
+#define JH7110_TIMER_MIN_TICKS 0xf
|
||||
+#define JH7110_TIMER_RELOAD_VALUE 0
|
||||
+
|
||||
+#define JH7110_TIMER_INT_STATUS 0x00 /* RO[0:4]: Interrupt Status for channel0~4 */
|
||||
+#define JH7110_TIMER_CTL 0x04 /* RW[0]: 0-continuous run, 1-single run */
|
||||
+#define JH7110_TIMER_LOAD 0x08 /* RW: load value to counter */
|
||||
+#define JH7110_TIMER_ENABLE 0x10 /* RW[0]: timer enable register */
|
||||
+#define JH7110_TIMER_RELOAD 0x14 /* RW: write 1 or 0 both reload counter */
|
||||
+#define JH7110_TIMER_VALUE 0x18 /* RO: timer value register */
|
||||
+#define JH7110_TIMER_INT_CLR 0x20 /* RW: timer interrupt clear register */
|
||||
+#define JH7110_TIMER_INT_MASK 0x24 /* RW[0]: timer interrupt mask register */
|
||||
+
|
||||
+#define JH7110_TIMER_INT_CLR_ENA BIT(0)
|
||||
+#define JH7110_TIMER_INT_CLR_AVA_MASK BIT(1)
|
||||
+
|
||||
+struct jh7110_clkevt {
|
||||
+ struct clock_event_device evt;
|
||||
+ struct clocksource cs;
|
||||
+ bool cs_is_valid;
|
||||
+ struct clk *clk;
|
||||
+ struct reset_control *rst;
|
||||
+ u32 rate;
|
||||
+ u32 reload_val;
|
||||
+ void __iomem *base;
|
||||
+ char name[sizeof("jh7110-timer.chX")];
|
||||
+};
|
||||
+
|
||||
+struct jh7110_timer_priv {
|
||||
+ struct clk *pclk;
|
||||
+ struct reset_control *prst;
|
||||
+ struct jh7110_clkevt clkevt[JH7110_TIMER_CH_MAX];
|
||||
+};
|
||||
+
|
||||
+/* 0:continuous-run mode, 1:single-run mode */
|
||||
+enum jh7110_timer_mode {
|
||||
+ JH7110_TIMER_MODE_CONTIN,
|
||||
+ JH7110_TIMER_MODE_SINGLE,
|
||||
+};
|
||||
+
|
||||
+/* Interrupt Mask, 0:Unmask, 1:Mask */
|
||||
+enum jh7110_timer_int_mask {
|
||||
+ JH7110_TIMER_INT_ENA,
|
||||
+ JH7110_TIMER_INT_DIS,
|
||||
+};
|
||||
+
|
||||
+enum jh7110_timer_enable {
|
||||
+ JH7110_TIMER_DIS,
|
||||
+ JH7110_TIMER_ENA,
|
||||
+};
|
||||
+
|
||||
+static inline struct jh7110_clkevt *to_jh7110_clkevt(struct clock_event_device *evt)
|
||||
+{
|
||||
+ return container_of(evt, struct jh7110_clkevt, evt);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * BIT(0): Read value represent channel int status.
|
||||
+ * Write 1 to this bit to clear interrupt. Write 0 has no effects.
|
||||
+ * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written.
|
||||
+ */
|
||||
+static inline int jh7110_timer_int_clear(struct jh7110_clkevt *clkevt)
|
||||
+{
|
||||
+ u32 value;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Waiting interrupt can be cleared */
|
||||
+ ret = readl_poll_timeout_atomic(clkevt->base + JH7110_TIMER_INT_CLR, value,
|
||||
+ !(value & JH7110_TIMER_INT_CLR_AVA_MASK),
|
||||
+ JH7110_DELAY_US, JH7110_TIMEOUT_US);
|
||||
+ if (!ret)
|
||||
+ writel(JH7110_TIMER_INT_CLR_ENA, clkevt->base + JH7110_TIMER_INT_CLR);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_timer_start(struct jh7110_clkevt *clkevt)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Disable and clear interrupt first */
|
||||
+ writel(JH7110_TIMER_INT_DIS, clkevt->base + JH7110_TIMER_INT_MASK);
|
||||
+ ret = jh7110_timer_int_clear(clkevt);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ writel(JH7110_TIMER_INT_ENA, clkevt->base + JH7110_TIMER_INT_MASK);
|
||||
+ writel(JH7110_TIMER_ENA, clkevt->base + JH7110_TIMER_ENABLE);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_timer_shutdown(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
|
||||
+
|
||||
+ writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE);
|
||||
+ return jh7110_timer_int_clear(clkevt);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_timer_suspend(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
|
||||
+
|
||||
+ clkevt->reload_val = readl(clkevt->base + JH7110_TIMER_LOAD);
|
||||
+ jh7110_timer_shutdown(evt);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_timer_resume(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
|
||||
+
|
||||
+ writel(clkevt->reload_val, clkevt->base + JH7110_TIMER_LOAD);
|
||||
+ writel(JH7110_TIMER_RELOAD_VALUE, clkevt->base + JH7110_TIMER_RELOAD);
|
||||
+ jh7110_timer_start(clkevt);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_timer_tick_resume(struct clock_event_device *evt)
|
||||
+{
|
||||
+ jh7110_timer_resume(evt);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* IRQ handler for the timer */
|
||||
+static irqreturn_t jh7110_timer_interrupt(int irq, void *priv)
|
||||
+{
|
||||
+ struct clock_event_device *evt = (struct clock_event_device *)priv;
|
||||
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
|
||||
+
|
||||
+ if (jh7110_timer_int_clear(clkevt))
|
||||
+ return IRQ_NONE;
|
||||
+
|
||||
+ if (evt->event_handler)
|
||||
+ evt->event_handler(evt);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_timer_set_periodic(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
|
||||
+ u32 periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
|
||||
+
|
||||
+ writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL);
|
||||
+ writel(periodic, clkevt->base + JH7110_TIMER_LOAD);
|
||||
+
|
||||
+ return jh7110_timer_start(clkevt);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_timer_set_oneshot(struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
|
||||
+
|
||||
+ writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL);
|
||||
+ writel(JH7110_TIMER_MAX_TICKS, clkevt->base + JH7110_TIMER_LOAD);
|
||||
+
|
||||
+ return jh7110_timer_start(clkevt);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_timer_set_next_event(unsigned long next,
|
||||
+ struct clock_event_device *evt)
|
||||
+{
|
||||
+ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
|
||||
+
|
||||
+ writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL);
|
||||
+ writel(next, clkevt->base + JH7110_TIMER_LOAD);
|
||||
+
|
||||
+ return jh7110_timer_start(clkevt);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_set_clockevent(struct clock_event_device *evt)
|
||||
+{
|
||||
+ evt->features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
+ CLOCK_EVT_FEAT_ONESHOT |
|
||||
+ CLOCK_EVT_FEAT_DYNIRQ;
|
||||
+ evt->set_state_shutdown = jh7110_timer_shutdown;
|
||||
+ evt->set_state_periodic = jh7110_timer_set_periodic;
|
||||
+ evt->set_state_oneshot = jh7110_timer_set_oneshot;
|
||||
+ evt->set_state_oneshot_stopped = jh7110_timer_shutdown;
|
||||
+ evt->tick_resume = jh7110_timer_tick_resume;
|
||||
+ evt->set_next_event = jh7110_timer_set_next_event;
|
||||
+ evt->suspend = jh7110_timer_suspend;
|
||||
+ evt->resume = jh7110_timer_resume;
|
||||
+ evt->rating = JH7110_CLOCKEVENT_RATING;
|
||||
+}
|
||||
+
|
||||
+static u64 jh7110_timer_clocksource_read(struct clocksource *cs)
|
||||
+{
|
||||
+ struct jh7110_clkevt *clkevt = container_of(cs, struct jh7110_clkevt, cs);
|
||||
+
|
||||
+ return (u64)readl(clkevt->base + JH7110_TIMER_VALUE);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_clocksource_init(struct jh7110_clkevt *clkevt)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ clkevt->cs.name = clkevt->name;
|
||||
+ clkevt->cs.rating = JH7110_CLOCK_SOURCE_RATING;
|
||||
+ clkevt->cs.read = jh7110_timer_clocksource_read;
|
||||
+ clkevt->cs.mask = CLOCKSOURCE_MASK(JH7110_VALID_BITS);
|
||||
+ clkevt->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
|
||||
+
|
||||
+ ret = clocksource_register_hz(&clkevt->cs, clkevt->rate);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ clkevt->cs_is_valid = true; /* clocksource register done */
|
||||
+ writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL);
|
||||
+ writel(JH7110_TIMER_MAX_TICKS, clkevt->base + JH7110_TIMER_LOAD);
|
||||
+
|
||||
+ return jh7110_timer_start(clkevt);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_clockevents_register(struct jh7110_clkevt *clkevt)
|
||||
+{
|
||||
+ clkevt->rate = clk_get_rate(clkevt->clk);
|
||||
+
|
||||
+ jh7110_set_clockevent(&clkevt->evt);
|
||||
+ clkevt->evt.name = clkevt->name;
|
||||
+ clkevt->evt.cpumask = cpu_possible_mask;
|
||||
+
|
||||
+ clockevents_config_and_register(&clkevt->evt, clkevt->rate,
|
||||
+ JH7110_TIMER_MIN_TICKS, JH7110_TIMER_MAX_TICKS);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_timer_release(void *data)
|
||||
+{
|
||||
+ struct jh7110_timer_priv *priv = data;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < JH7110_TIMER_CH_MAX; i++) {
|
||||
+ /* Disable each channel of timer */
|
||||
+ if (priv->clkevt[i].base)
|
||||
+ writel(JH7110_TIMER_DIS, priv->clkevt[i].base + JH7110_TIMER_ENABLE);
|
||||
+
|
||||
+ /* Avoid no initialization in the loop of the probe */
|
||||
+ if (!IS_ERR_OR_NULL(priv->clkevt[i].rst))
|
||||
+ reset_control_assert(priv->clkevt[i].rst);
|
||||
+
|
||||
+ if (priv->clkevt[i].cs_is_valid)
|
||||
+ clocksource_unregister(&priv->clkevt[i].cs);
|
||||
+ }
|
||||
+
|
||||
+ reset_control_assert(priv->prst);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_timer_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh7110_timer_priv *priv;
|
||||
+ struct jh7110_clkevt *clkevt;
|
||||
+ char name[sizeof("chX")];
|
||||
+ int ch;
|
||||
+ int ret;
|
||||
+ void __iomem *base;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(base))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(base),
|
||||
+ "failed to map registers\n");
|
||||
+
|
||||
+ priv->prst = devm_reset_control_get_exclusive(&pdev->dev, "apb");
|
||||
+ if (IS_ERR(priv->prst))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->prst),
|
||||
+ "failed to get apb reset\n");
|
||||
+
|
||||
+ priv->pclk = devm_clk_get_enabled(&pdev->dev, "apb");
|
||||
+ if (IS_ERR(priv->pclk))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk),
|
||||
+ "failed to get & enable apb clock\n");
|
||||
+
|
||||
+ ret = reset_control_deassert(priv->prst);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(&pdev->dev, ret, "failed to deassert apb reset\n");
|
||||
+
|
||||
+ ret = devm_add_action_or_reset(&pdev->dev, jh7110_timer_release, priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (ch = 0; ch < JH7110_TIMER_CH_MAX; ch++) {
|
||||
+ clkevt = &priv->clkevt[ch];
|
||||
+ snprintf(name, sizeof(name), "ch%d", ch);
|
||||
+
|
||||
+ clkevt->base = base + JH7110_TIMER_CH_BASE(ch);
|
||||
+ /* Ensure timer is disabled */
|
||||
+ writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE);
|
||||
+
|
||||
+ clkevt->rst = devm_reset_control_get_exclusive(&pdev->dev, name);
|
||||
+ if (IS_ERR(clkevt->rst))
|
||||
+ return PTR_ERR(clkevt->rst);
|
||||
+
|
||||
+ clkevt->clk = devm_clk_get_enabled(&pdev->dev, name);
|
||||
+ if (IS_ERR(clkevt->clk))
|
||||
+ return PTR_ERR(clkevt->clk);
|
||||
+
|
||||
+ ret = reset_control_deassert(clkevt->rst);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ clkevt->evt.irq = platform_get_irq(pdev, ch);
|
||||
+ if (clkevt->evt.irq < 0)
|
||||
+ return clkevt->evt.irq;
|
||||
+
|
||||
+ snprintf(clkevt->name, sizeof(clkevt->name), "jh7110-timer.ch%d", ch);
|
||||
+ jh7110_clockevents_register(clkevt);
|
||||
+
|
||||
+ ret = devm_request_irq(&pdev->dev, clkevt->evt.irq, jh7110_timer_interrupt,
|
||||
+ IRQF_TIMER | IRQF_IRQPOLL,
|
||||
+ clkevt->name, &clkevt->evt);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = jh7110_clocksource_init(clkevt);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7110_timer_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-timer", },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_timer_match);
|
||||
+
|
||||
+static struct platform_driver jh7110_timer_driver = {
|
||||
+ .probe = jh7110_timer_probe,
|
||||
+ .driver = {
|
||||
+ .name = "jh7110-timer",
|
||||
+ .of_match_table = jh7110_timer_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(jh7110_timer_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 timer driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,34 @@
|
||||
From b513eb2cabee212ba1a23839f18c0026a21e653e Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Fri, 22 Sep 2023 14:28:32 +0800
|
||||
Subject: [PATCH 004/116] dt-bindings: mmc: starfive: Remove properties from
|
||||
required
|
||||
|
||||
Due to the change of tuning implementation, it's no longer necessary to
|
||||
use the "starfive,sysreg" property in dts, so remove it from required.
|
||||
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Link: https://lore.kernel.org/r/20230922062834.39212-2-william.qiu@starfivetech.com
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
|
||||
+++ b/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
|
||||
@@ -55,7 +55,6 @@ required:
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- - starfive,sysreg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
@@ -73,5 +72,4 @@ examples:
|
||||
fifo-depth = <32>;
|
||||
fifo-watermark-aligned;
|
||||
data-addr = <0>;
|
||||
- starfive,sysreg = <&sys_syscon 0x14 0x1a 0x7c000000>;
|
||||
};
|
@ -0,0 +1,199 @@
|
||||
From 3ae8cec8fd28e18847edb67dfea04718c2f3369f Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Fri, 22 Sep 2023 14:28:33 +0800
|
||||
Subject: [PATCH 005/116] mmc: starfive: Change tuning implementation
|
||||
|
||||
Before, we used syscon to achieve tuning, but the actual measurement
|
||||
showed little effect, so the tuning implementation was modified here,
|
||||
and it was realized by reading and writing the UHS_REG_EXT register.
|
||||
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
|
||||
Link: https://lore.kernel.org/r/20230922062834.39212-3-william.qiu@starfivetech.com
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/mmc/host/dw_mmc-starfive.c | 137 +++++++++--------------------
|
||||
1 file changed, 40 insertions(+), 97 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/dw_mmc-starfive.c
|
||||
+++ b/drivers/mmc/host/dw_mmc-starfive.c
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright (c) 2022 StarFive Technology Co., Ltd.
|
||||
*/
|
||||
|
||||
+#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
@@ -20,13 +21,7 @@
|
||||
#define ALL_INT_CLR 0x1ffff
|
||||
#define MAX_DELAY_CHAIN 32
|
||||
|
||||
-struct starfive_priv {
|
||||
- struct device *dev;
|
||||
- struct regmap *reg_syscon;
|
||||
- u32 syscon_offset;
|
||||
- u32 syscon_shift;
|
||||
- u32 syscon_mask;
|
||||
-};
|
||||
+#define STARFIVE_SMPL_PHASE GENMASK(20, 16)
|
||||
|
||||
static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *ios)
|
||||
{
|
||||
@@ -44,117 +39,65 @@ static void dw_mci_starfive_set_ios(stru
|
||||
}
|
||||
}
|
||||
|
||||
+static void dw_mci_starfive_set_sample_phase(struct dw_mci *host, u32 smpl_phase)
|
||||
+{
|
||||
+ /* change driver phase and sample phase */
|
||||
+ u32 reg_value = mci_readl(host, UHS_REG_EXT);
|
||||
+
|
||||
+ /* In UHS_REG_EXT, only 5 bits valid in DRV_PHASE and SMPL_PHASE */
|
||||
+ reg_value &= ~STARFIVE_SMPL_PHASE;
|
||||
+ reg_value |= FIELD_PREP(STARFIVE_SMPL_PHASE, smpl_phase);
|
||||
+ mci_writel(host, UHS_REG_EXT, reg_value);
|
||||
+
|
||||
+ /* We should delay 1ms wait for timing setting finished. */
|
||||
+ mdelay(1);
|
||||
+}
|
||||
+
|
||||
static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
|
||||
u32 opcode)
|
||||
{
|
||||
static const int grade = MAX_DELAY_CHAIN;
|
||||
struct dw_mci *host = slot->host;
|
||||
- struct starfive_priv *priv = host->priv;
|
||||
- int rise_point = -1, fall_point = -1;
|
||||
- int err, prev_err = 0;
|
||||
- int i;
|
||||
- bool found = 0;
|
||||
- u32 regval;
|
||||
-
|
||||
- /*
|
||||
- * Use grade as the max delay chain, and use the rise_point and
|
||||
- * fall_point to ensure the best sampling point of a data input
|
||||
- * signals.
|
||||
- */
|
||||
- for (i = 0; i < grade; i++) {
|
||||
- regval = i << priv->syscon_shift;
|
||||
- err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
|
||||
- priv->syscon_mask, regval);
|
||||
- if (err)
|
||||
- return err;
|
||||
- mci_writel(host, RINTSTS, ALL_INT_CLR);
|
||||
-
|
||||
- err = mmc_send_tuning(slot->mmc, opcode, NULL);
|
||||
- if (!err)
|
||||
- found = 1;
|
||||
-
|
||||
- if (i > 0) {
|
||||
- if (err && !prev_err)
|
||||
- fall_point = i - 1;
|
||||
- if (!err && prev_err)
|
||||
- rise_point = i;
|
||||
- }
|
||||
+ int smpl_phase, smpl_raise = -1, smpl_fall = -1;
|
||||
+ int ret;
|
||||
|
||||
- if (rise_point != -1 && fall_point != -1)
|
||||
- goto tuning_out;
|
||||
+ for (smpl_phase = 0; smpl_phase < grade; smpl_phase++) {
|
||||
+ dw_mci_starfive_set_sample_phase(host, smpl_phase);
|
||||
+ mci_writel(host, RINTSTS, ALL_INT_CLR);
|
||||
|
||||
- prev_err = err;
|
||||
- err = 0;
|
||||
- }
|
||||
+ ret = mmc_send_tuning(slot->mmc, opcode, NULL);
|
||||
|
||||
-tuning_out:
|
||||
- if (found) {
|
||||
- if (rise_point == -1)
|
||||
- rise_point = 0;
|
||||
- if (fall_point == -1)
|
||||
- fall_point = grade - 1;
|
||||
- if (fall_point < rise_point) {
|
||||
- if ((rise_point + fall_point) >
|
||||
- (grade - 1))
|
||||
- i = fall_point / 2;
|
||||
- else
|
||||
- i = (rise_point + grade - 1) / 2;
|
||||
- } else {
|
||||
- i = (rise_point + fall_point) / 2;
|
||||
+ if (!ret && smpl_raise < 0) {
|
||||
+ smpl_raise = smpl_phase;
|
||||
+ } else if (ret && smpl_raise >= 0) {
|
||||
+ smpl_fall = smpl_phase - 1;
|
||||
+ break;
|
||||
}
|
||||
-
|
||||
- regval = i << priv->syscon_shift;
|
||||
- err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
|
||||
- priv->syscon_mask, regval);
|
||||
- if (err)
|
||||
- return err;
|
||||
- mci_writel(host, RINTSTS, ALL_INT_CLR);
|
||||
-
|
||||
- dev_info(host->dev, "Found valid delay chain! use it [delay=%d]\n", i);
|
||||
- } else {
|
||||
- dev_err(host->dev, "No valid delay chain! use default\n");
|
||||
- err = -EINVAL;
|
||||
}
|
||||
|
||||
- mci_writel(host, RINTSTS, ALL_INT_CLR);
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-static int dw_mci_starfive_parse_dt(struct dw_mci *host)
|
||||
-{
|
||||
- struct of_phandle_args args;
|
||||
- struct starfive_priv *priv;
|
||||
- int ret;
|
||||
+ if (smpl_phase >= grade)
|
||||
+ smpl_fall = grade - 1;
|
||||
|
||||
- priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- ret = of_parse_phandle_with_fixed_args(host->dev->of_node,
|
||||
- "starfive,sysreg", 3, 0, &args);
|
||||
- if (ret) {
|
||||
- dev_err(host->dev, "Failed to parse starfive,sysreg\n");
|
||||
- return -EINVAL;
|
||||
+ if (smpl_raise < 0) {
|
||||
+ smpl_phase = 0;
|
||||
+ dev_err(host->dev, "No valid delay chain! use default\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
- priv->reg_syscon = syscon_node_to_regmap(args.np);
|
||||
- of_node_put(args.np);
|
||||
- if (IS_ERR(priv->reg_syscon))
|
||||
- return PTR_ERR(priv->reg_syscon);
|
||||
-
|
||||
- priv->syscon_offset = args.args[0];
|
||||
- priv->syscon_shift = args.args[1];
|
||||
- priv->syscon_mask = args.args[2];
|
||||
-
|
||||
- host->priv = priv;
|
||||
+ smpl_phase = (smpl_raise + smpl_fall) / 2;
|
||||
+ dev_dbg(host->dev, "Found valid delay chain! use it [delay=%d]\n", smpl_phase);
|
||||
+ ret = 0;
|
||||
|
||||
- return 0;
|
||||
+out:
|
||||
+ dw_mci_starfive_set_sample_phase(host, smpl_phase);
|
||||
+ mci_writel(host, RINTSTS, ALL_INT_CLR);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static const struct dw_mci_drv_data starfive_data = {
|
||||
.common_caps = MMC_CAP_CMD23,
|
||||
.set_ios = dw_mci_starfive_set_ios,
|
||||
- .parse_dt = dw_mci_starfive_parse_dt,
|
||||
.execute_tuning = dw_mci_starfive_execute_tuning,
|
||||
};
|
||||
|
@ -0,0 +1,79 @@
|
||||
From e366df2ff64e9f93a5b35eea6a198b005d5a0911 Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Fri, 22 Dec 2023 17:45:45 +0800
|
||||
Subject: [PATCH 006/116] dt-bindings: pwm: Add bindings for OpenCores PWM
|
||||
Controller
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add bindings for OpenCores PWM Controller.
|
||||
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
|
||||
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
|
||||
---
|
||||
.../bindings/pwm/opencores,pwm.yaml | 55 +++++++++++++++++++
|
||||
1 file changed, 55 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
|
||||
@@ -0,0 +1,55 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/pwm/opencores,pwm.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: OpenCores PWM controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - William Qiu <william.qiu@starfivetech.com>
|
||||
+
|
||||
+description:
|
||||
+ The OpenCores PTC ip core contains a PWM controller. When operating in PWM
|
||||
+ mode, the PTC core generates binary signal with user-programmable low and
|
||||
+ high periods. All PTC counters and registers are 32-bit.
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: pwm.yaml#
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ items:
|
||||
+ - enum:
|
||||
+ - starfive,jh7100-pwm
|
||||
+ - starfive,jh7110-pwm
|
||||
+ - const: opencores,pwm-v1
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ resets:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ "#pwm-cells":
|
||||
+ const: 3
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ pwm@12490000 {
|
||||
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
|
||||
+ reg = <0x12490000 0x10000>;
|
||||
+ clocks = <&clkgen 181>;
|
||||
+ resets = <&rstgen 109>;
|
||||
+ #pwm-cells = <3>;
|
||||
+ };
|
@ -0,0 +1,285 @@
|
||||
From 644bfe581dde9b762460a4916da4d71c148be06e Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Fri, 22 Dec 2023 17:45:46 +0800
|
||||
Subject: [PATCH 007/116] pwm: opencores: Add PWM driver support
|
||||
|
||||
Add driver for OpenCores PWM Controller. And add compatibility code
|
||||
which based on StarFive SoC.
|
||||
|
||||
Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
---
|
||||
drivers/pwm/Kconfig | 12 ++
|
||||
drivers/pwm/Makefile | 1 +
|
||||
drivers/pwm/pwm-ocores.c | 233 +++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 246 insertions(+)
|
||||
create mode 100644 drivers/pwm/pwm-ocores.c
|
||||
|
||||
--- a/drivers/pwm/Kconfig
|
||||
+++ b/drivers/pwm/Kconfig
|
||||
@@ -434,6 +434,18 @@ config PWM_NTXEC
|
||||
controller found in certain e-book readers designed by the original
|
||||
design manufacturer Netronix.
|
||||
|
||||
+config PWM_OCORES
|
||||
+ tristate "OpenCores PWM support"
|
||||
+ depends on HAS_IOMEM && OF
|
||||
+ depends on COMMON_CLK
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ help
|
||||
+ If you say yes to this option, support will be included for the
|
||||
+ OpenCores PWM. For details see https://opencores.org/projects/ptc.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called pwm-ocores.
|
||||
+
|
||||
config PWM_OMAP_DMTIMER
|
||||
tristate "OMAP Dual-Mode Timer PWM support"
|
||||
depends on OF
|
||||
--- a/drivers/pwm/Makefile
|
||||
+++ b/drivers/pwm/Makefile
|
||||
@@ -39,6 +39,7 @@ obj-$(CONFIG_PWM_MICROCHIP_CORE) += pwm-
|
||||
obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
|
||||
obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
|
||||
obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o
|
||||
+obj-$(CONFIG_PWM_OCORES) += pwm-ocores.o
|
||||
obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
|
||||
obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o
|
||||
obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/pwm/pwm-ocores.c
|
||||
@@ -0,0 +1,233 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * OpenCores PWM Driver
|
||||
+ *
|
||||
+ * https://opencores.org/projects/ptc
|
||||
+ *
|
||||
+ * Copyright (C) 2018-2023 StarFive Technology Co., Ltd.
|
||||
+ *
|
||||
+ * Limitations:
|
||||
+ * - The hardware only do inverted polarity.
|
||||
+ * - The hardware minimum period / duty_cycle is (1 / pwm_apb clock frequency) ns.
|
||||
+ * - The hardware maximum period / duty_cycle is (U32_MAX / pwm_apb clock frequency) ns.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pwm.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+/* OCPWM_CTRL register bits*/
|
||||
+#define REG_OCPWM_EN BIT(0)
|
||||
+#define REG_OCPWM_ECLK BIT(1)
|
||||
+#define REG_OCPWM_NEC BIT(2)
|
||||
+#define REG_OCPWM_OE BIT(3)
|
||||
+#define REG_OCPWM_SIGNLE BIT(4)
|
||||
+#define REG_OCPWM_INTE BIT(5)
|
||||
+#define REG_OCPWM_INT BIT(6)
|
||||
+#define REG_OCPWM_CNTRRST BIT(7)
|
||||
+#define REG_OCPWM_CAPTE BIT(8)
|
||||
+
|
||||
+struct ocores_pwm_device {
|
||||
+ struct pwm_chip chip;
|
||||
+ struct clk *clk;
|
||||
+ struct reset_control *rst;
|
||||
+ const struct ocores_pwm_data *data;
|
||||
+ void __iomem *regs;
|
||||
+ u32 clk_rate; /* PWM APB clock frequency */
|
||||
+};
|
||||
+
|
||||
+struct ocores_pwm_data {
|
||||
+ void __iomem *(*get_ch_base)(void __iomem *base, unsigned int channel);
|
||||
+};
|
||||
+
|
||||
+static inline u32 ocores_readl(struct ocores_pwm_device *ddata,
|
||||
+ unsigned int channel,
|
||||
+ unsigned int offset)
|
||||
+{
|
||||
+ void __iomem *base = ddata->data->get_ch_base ?
|
||||
+ ddata->data->get_ch_base(ddata->regs, channel) : ddata->regs;
|
||||
+
|
||||
+ return readl(base + offset);
|
||||
+}
|
||||
+
|
||||
+static inline void ocores_writel(struct ocores_pwm_device *ddata,
|
||||
+ unsigned int channel,
|
||||
+ unsigned int offset, u32 val)
|
||||
+{
|
||||
+ void __iomem *base = ddata->data->get_ch_base ?
|
||||
+ ddata->data->get_ch_base(ddata->regs, channel) : ddata->regs;
|
||||
+
|
||||
+ writel(val, base + offset);
|
||||
+}
|
||||
+
|
||||
+static inline struct ocores_pwm_device *chip_to_ocores(struct pwm_chip *chip)
|
||||
+{
|
||||
+ return container_of(chip, struct ocores_pwm_device, chip);
|
||||
+}
|
||||
+
|
||||
+static void __iomem *starfive_jh71x0_get_ch_base(void __iomem *base,
|
||||
+ unsigned int channel)
|
||||
+{
|
||||
+ unsigned int offset = (channel > 3 ? 1 << 15 : 0) + (channel & 3) * 0x10;
|
||||
+
|
||||
+ return base + offset;
|
||||
+}
|
||||
+
|
||||
+static int ocores_pwm_get_state(struct pwm_chip *chip,
|
||||
+ struct pwm_device *pwm,
|
||||
+ struct pwm_state *state)
|
||||
+{
|
||||
+ struct ocores_pwm_device *ddata = chip_to_ocores(chip);
|
||||
+ u32 period_data, duty_data, ctrl_data;
|
||||
+
|
||||
+ period_data = ocores_readl(ddata, pwm->hwpwm, 0x8);
|
||||
+ duty_data = ocores_readl(ddata, pwm->hwpwm, 0x4);
|
||||
+ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
|
||||
+
|
||||
+ state->period = DIV_ROUND_UP_ULL((u64)period_data * NSEC_PER_SEC, ddata->clk_rate);
|
||||
+ state->duty_cycle = DIV_ROUND_UP_ULL((u64)duty_data * NSEC_PER_SEC, ddata->clk_rate);
|
||||
+ state->polarity = PWM_POLARITY_INVERSED;
|
||||
+ state->enabled = (ctrl_data & REG_OCPWM_EN) ? true : false;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ocores_pwm_apply(struct pwm_chip *chip,
|
||||
+ struct pwm_device *pwm,
|
||||
+ const struct pwm_state *state)
|
||||
+{
|
||||
+ struct ocores_pwm_device *ddata = chip_to_ocores(chip);
|
||||
+ u32 ctrl_data = 0;
|
||||
+ u64 period_data, duty_data;
|
||||
+
|
||||
+ if (state->polarity != PWM_POLARITY_INVERSED)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
|
||||
+ ocores_writel(ddata, pwm->hwpwm, 0xC, 0);
|
||||
+
|
||||
+ period_data = DIV_ROUND_DOWN_ULL(state->period * ddata->clk_rate, NSEC_PER_SEC);
|
||||
+ if (period_data <= U32_MAX)
|
||||
+ ocores_writel(ddata, pwm->hwpwm, 0x8, (u32)period_data);
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ duty_data = DIV_ROUND_DOWN_ULL(state->duty_cycle * ddata->clk_rate, NSEC_PER_SEC);
|
||||
+ if (duty_data <= U32_MAX)
|
||||
+ ocores_writel(ddata, pwm->hwpwm, 0x4, (u32)duty_data);
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ocores_writel(ddata, pwm->hwpwm, 0xC, 0);
|
||||
+
|
||||
+ if (state->enabled) {
|
||||
+ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
|
||||
+ ocores_writel(ddata, pwm->hwpwm, 0xC, ctrl_data | REG_OCPWM_EN | REG_OCPWM_OE);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct pwm_ops ocores_pwm_ops = {
|
||||
+ .get_state = ocores_pwm_get_state,
|
||||
+ .apply = ocores_pwm_apply,
|
||||
+};
|
||||
+
|
||||
+static const struct ocores_pwm_data jh7100_pwm_data = {
|
||||
+ .get_ch_base = starfive_jh71x0_get_ch_base,
|
||||
+};
|
||||
+
|
||||
+static const struct ocores_pwm_data jh7110_pwm_data = {
|
||||
+ .get_ch_base = starfive_jh71x0_get_ch_base,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id ocores_pwm_of_match[] = {
|
||||
+ { .compatible = "opencores,pwm-v1" },
|
||||
+ { .compatible = "starfive,jh7100-pwm", .data = &jh7100_pwm_data},
|
||||
+ { .compatible = "starfive,jh7110-pwm", .data = &jh7110_pwm_data},
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ocores_pwm_of_match);
|
||||
+
|
||||
+static void ocores_reset_control_assert(void *data)
|
||||
+{
|
||||
+ reset_control_assert(data);
|
||||
+}
|
||||
+
|
||||
+static int ocores_pwm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ const struct of_device_id *id;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct ocores_pwm_device *ddata;
|
||||
+ struct pwm_chip *chip;
|
||||
+ int ret;
|
||||
+
|
||||
+ id = of_match_device(ocores_pwm_of_match, dev);
|
||||
+ if (!id)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
|
||||
+ if (!ddata)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ddata->data = id->data;
|
||||
+ chip = &ddata->chip;
|
||||
+ chip->dev = dev;
|
||||
+ chip->ops = &ocores_pwm_ops;
|
||||
+ chip->npwm = 8;
|
||||
+ chip->of_pwm_n_cells = 3;
|
||||
+
|
||||
+ ddata->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(ddata->regs))
|
||||
+ return dev_err_probe(dev, PTR_ERR(ddata->regs),
|
||||
+ "Unable to map IO resources\n");
|
||||
+
|
||||
+ ddata->clk = devm_clk_get_enabled(dev, NULL);
|
||||
+ if (IS_ERR(ddata->clk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(ddata->clk),
|
||||
+ "Unable to get pwm's clock\n");
|
||||
+
|
||||
+ ddata->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
|
||||
+ if (IS_ERR(ddata->rst))
|
||||
+ return dev_err_probe(dev, PTR_ERR(ddata->rst),
|
||||
+ "Unable to get pwm's reset\n");
|
||||
+
|
||||
+ reset_control_deassert(ddata->rst);
|
||||
+
|
||||
+ ret = devm_add_action_or_reset(dev, ocores_reset_control_assert, ddata->rst);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ddata->clk_rate = clk_get_rate(ddata->clk);
|
||||
+ if (ddata->clk_rate <= 0)
|
||||
+ return dev_err_probe(dev, ddata->clk_rate,
|
||||
+ "Unable to get clock's rate\n");
|
||||
+
|
||||
+ ret = devm_pwmchip_add(dev, chip);
|
||||
+ if (ret < 0)
|
||||
+ return dev_err_probe(dev, ret, "Could not register PWM chip\n");
|
||||
+
|
||||
+ platform_set_drvdata(pdev, ddata);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver ocores_pwm_driver = {
|
||||
+ .probe = ocores_pwm_probe,
|
||||
+ .driver = {
|
||||
+ .name = "ocores-pwm",
|
||||
+ .of_match_table = ocores_pwm_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(ocores_pwm_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Jieqin Chen");
|
||||
+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("OpenCores PWM PTC driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,117 @@
|
||||
From 7d9521cad6474d45e9056176982e6da54d40bc19 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Biggers <ebiggers@google.com>
|
||||
Date: Sun, 22 Oct 2023 01:10:42 -0700
|
||||
Subject: [PATCH 008/116] crypto: starfive - remove unnecessary alignmask for
|
||||
ahashes
|
||||
|
||||
The crypto API's support for alignmasks for ahash algorithms is nearly
|
||||
useless, as its only effect is to cause the API to align the key and
|
||||
result buffers. The drivers that happen to be specifying an alignmask
|
||||
for ahash rarely actually need it. When they do, it's easily fixable,
|
||||
especially considering that these buffers cannot be used for DMA.
|
||||
|
||||
In preparation for removing alignmask support from ahash, this patch
|
||||
makes the starfive driver no longer use it. This driver did actually
|
||||
rely on it, but only for storing to the result buffer using int stores
|
||||
in starfive_hash_copy_hash(). This patch makes
|
||||
starfive_hash_copy_hash() use put_unaligned() instead. (It really
|
||||
should use a specific endianness, but that's an existing bug.)
|
||||
|
||||
Signed-off-by: Eric Biggers <ebiggers@google.com>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
drivers/crypto/starfive/jh7110-hash.c | 13 ++-----------
|
||||
1 file changed, 2 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/crypto/starfive/jh7110-hash.c
|
||||
+++ b/drivers/crypto/starfive/jh7110-hash.c
|
||||
@@ -209,7 +209,8 @@ static int starfive_hash_copy_hash(struc
|
||||
data = (u32 *)req->result;
|
||||
|
||||
for (count = 0; count < mlen; count++)
|
||||
- data[count] = readl(ctx->cryp->base + STARFIVE_HASH_SHARDR);
|
||||
+ put_unaligned(readl(ctx->cryp->base + STARFIVE_HASH_SHARDR),
|
||||
+ &data[count]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -628,7 +629,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA224_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
@@ -658,7 +658,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA224_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
@@ -687,7 +686,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA256_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
@@ -717,7 +715,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA256_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
@@ -746,7 +743,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA384_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
@@ -776,7 +772,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA384_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
@@ -805,7 +800,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA512_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
@@ -835,7 +829,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA512_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
@@ -864,7 +857,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SM3_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
||||
@@ -894,7 +886,6 @@ static struct ahash_engine_alg algs_sha2
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SM3_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
},
|
@ -0,0 +1,25 @@
|
||||
From 52de0270ed6453727936b5a793dc367d75280e84 Mon Sep 17 00:00:00 2001
|
||||
From: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Date: Wed, 15 Nov 2023 01:12:13 +0800
|
||||
Subject: [PATCH 009/116] crypto: starfive - Update driver dependencies
|
||||
|
||||
Change AMBA_PL08X to required dependency as the hash ops depends on it
|
||||
for data transfer.
|
||||
|
||||
Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
drivers/crypto/starfive/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/crypto/starfive/Kconfig
|
||||
+++ b/drivers/crypto/starfive/Kconfig
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
config CRYPTO_DEV_JH7110
|
||||
tristate "StarFive JH7110 cryptographic engine driver"
|
||||
- depends on SOC_STARFIVE || AMBA_PL08X || COMPILE_TEST
|
||||
+ depends on (SOC_STARFIVE && AMBA_PL08X) || COMPILE_TEST
|
||||
depends on HAS_DMA
|
||||
select CRYPTO_ENGINE
|
||||
select CRYPTO_HMAC
|
@ -0,0 +1,200 @@
|
||||
From 68a1bbb99455fd5ea80b7e21ec726f369abc9572 Mon Sep 17 00:00:00 2001
|
||||
From: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Date: Wed, 15 Nov 2023 01:12:14 +0800
|
||||
Subject: [PATCH 010/116] crypto: starfive - RSA poll csr for done status
|
||||
|
||||
Hardware could not clear irq status without resetting the entire module.
|
||||
Driver receives irq immediately when mask bit is cleared causing
|
||||
intermittent errors in RSA calculations. Switch to use csr polling for
|
||||
done status instead.
|
||||
|
||||
Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
drivers/crypto/starfive/jh7110-cryp.c | 8 -----
|
||||
drivers/crypto/starfive/jh7110-cryp.h | 10 +++++-
|
||||
drivers/crypto/starfive/jh7110-rsa.c | 49 +++++++--------------------
|
||||
3 files changed, 22 insertions(+), 45 deletions(-)
|
||||
|
||||
--- a/drivers/crypto/starfive/jh7110-cryp.c
|
||||
+++ b/drivers/crypto/starfive/jh7110-cryp.c
|
||||
@@ -109,12 +109,6 @@ static irqreturn_t starfive_cryp_irq(int
|
||||
tasklet_schedule(&cryp->hash_done);
|
||||
}
|
||||
|
||||
- if (status & STARFIVE_IE_FLAG_PKA_DONE) {
|
||||
- mask |= STARFIVE_IE_MASK_PKA_DONE;
|
||||
- writel(mask, cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
- complete(&cryp->pka_done);
|
||||
- }
|
||||
-
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -159,8 +153,6 @@ static int starfive_cryp_probe(struct pl
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
|
||||
"Error getting hardware reset line\n");
|
||||
|
||||
- init_completion(&cryp->pka_done);
|
||||
-
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
--- a/drivers/crypto/starfive/jh7110-cryp.h
|
||||
+++ b/drivers/crypto/starfive/jh7110-cryp.h
|
||||
@@ -125,6 +125,15 @@ union starfive_pka_cacr {
|
||||
};
|
||||
};
|
||||
|
||||
+union starfive_pka_casr {
|
||||
+ u32 v;
|
||||
+ struct {
|
||||
+#define STARFIVE_PKA_DONE BIT(0)
|
||||
+ u32 done :1;
|
||||
+ u32 rsvd_0 :31;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
struct starfive_rsa_key {
|
||||
u8 *n;
|
||||
u8 *e;
|
||||
@@ -183,7 +192,6 @@ struct starfive_cryp_dev {
|
||||
struct crypto_engine *engine;
|
||||
struct tasklet_struct aes_done;
|
||||
struct tasklet_struct hash_done;
|
||||
- struct completion pka_done;
|
||||
size_t assoclen;
|
||||
size_t total_in;
|
||||
size_t total_out;
|
||||
--- a/drivers/crypto/starfive/jh7110-rsa.c
|
||||
+++ b/drivers/crypto/starfive/jh7110-rsa.c
|
||||
@@ -6,13 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/crypto.h>
|
||||
-#include <linux/delay.h>
|
||||
-#include <linux/device.h>
|
||||
-#include <linux/dma-direct.h>
|
||||
-#include <linux/interrupt.h>
|
||||
#include <linux/iopoll.h>
|
||||
-#include <linux/io.h>
|
||||
-#include <linux/mod_devicetable.h>
|
||||
#include <crypto/akcipher.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/internal/akcipher.h>
|
||||
@@ -28,13 +22,13 @@
|
||||
#define STARFIVE_PKA_CAER_OFFSET (STARFIVE_PKA_REGS_OFFSET + 0x108)
|
||||
#define STARFIVE_PKA_CANR_OFFSET (STARFIVE_PKA_REGS_OFFSET + 0x208)
|
||||
|
||||
-// R^2 mod N and N0'
|
||||
+/* R ^ 2 mod N and N0' */
|
||||
#define CRYPTO_CMD_PRE 0x0
|
||||
-// A * R mod N ==> A
|
||||
+/* A * R mod N ==> A */
|
||||
#define CRYPTO_CMD_ARN 0x5
|
||||
-// A * E * R mod N ==> A
|
||||
+/* A * E * R mod N ==> A */
|
||||
#define CRYPTO_CMD_AERN 0x6
|
||||
-// A * A * R mod N ==> A
|
||||
+/* A * A * R mod N ==> A */
|
||||
#define CRYPTO_CMD_AARN 0x7
|
||||
|
||||
#define STARFIVE_RSA_MAX_KEYSZ 256
|
||||
@@ -43,21 +37,10 @@
|
||||
static inline int starfive_pka_wait_done(struct starfive_cryp_ctx *ctx)
|
||||
{
|
||||
struct starfive_cryp_dev *cryp = ctx->cryp;
|
||||
+ u32 status;
|
||||
|
||||
- return wait_for_completion_timeout(&cryp->pka_done,
|
||||
- usecs_to_jiffies(100000));
|
||||
-}
|
||||
-
|
||||
-static inline void starfive_pka_irq_mask_clear(struct starfive_cryp_ctx *ctx)
|
||||
-{
|
||||
- struct starfive_cryp_dev *cryp = ctx->cryp;
|
||||
- u32 stat;
|
||||
-
|
||||
- stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
- stat &= ~STARFIVE_IE_MASK_PKA_DONE;
|
||||
- writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET);
|
||||
-
|
||||
- reinit_completion(&cryp->pka_done);
|
||||
+ return readl_relaxed_poll_timeout(cryp->base + STARFIVE_PKA_CASR_OFFSET, status,
|
||||
+ status & STARFIVE_PKA_DONE, 10, 100000);
|
||||
}
|
||||
|
||||
static void starfive_rsa_free_key(struct starfive_rsa_key *key)
|
||||
@@ -114,10 +97,9 @@ static int starfive_rsa_montgomery_form(
|
||||
rctx->csr.pka.not_r2 = 1;
|
||||
rctx->csr.pka.ie = 1;
|
||||
|
||||
- starfive_pka_irq_mask_clear(ctx);
|
||||
writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
|
||||
|
||||
- if (!starfive_pka_wait_done(ctx))
|
||||
+ if (starfive_pka_wait_done(ctx))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
for (loop = 0; loop <= opsize; loop++)
|
||||
@@ -136,10 +118,9 @@ static int starfive_rsa_montgomery_form(
|
||||
rctx->csr.pka.start = 1;
|
||||
rctx->csr.pka.ie = 1;
|
||||
|
||||
- starfive_pka_irq_mask_clear(ctx);
|
||||
writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
|
||||
|
||||
- if (!starfive_pka_wait_done(ctx))
|
||||
+ if (starfive_pka_wait_done(ctx))
|
||||
return -ETIMEDOUT;
|
||||
} else {
|
||||
rctx->csr.pka.v = 0;
|
||||
@@ -151,10 +132,9 @@ static int starfive_rsa_montgomery_form(
|
||||
rctx->csr.pka.pre_expf = 1;
|
||||
rctx->csr.pka.ie = 1;
|
||||
|
||||
- starfive_pka_irq_mask_clear(ctx);
|
||||
writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
|
||||
|
||||
- if (!starfive_pka_wait_done(ctx))
|
||||
+ if (starfive_pka_wait_done(ctx))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
for (loop = 0; loop <= count; loop++)
|
||||
@@ -172,10 +152,9 @@ static int starfive_rsa_montgomery_form(
|
||||
rctx->csr.pka.start = 1;
|
||||
rctx->csr.pka.ie = 1;
|
||||
|
||||
- starfive_pka_irq_mask_clear(ctx);
|
||||
writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
|
||||
|
||||
- if (!starfive_pka_wait_done(ctx))
|
||||
+ if (starfive_pka_wait_done(ctx))
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -226,11 +205,10 @@ static int starfive_rsa_cpu_start(struct
|
||||
rctx->csr.pka.start = 1;
|
||||
rctx->csr.pka.ie = 1;
|
||||
|
||||
- starfive_pka_irq_mask_clear(ctx);
|
||||
writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
|
||||
|
||||
ret = -ETIMEDOUT;
|
||||
- if (!starfive_pka_wait_done(ctx))
|
||||
+ if (starfive_pka_wait_done(ctx))
|
||||
goto rsa_err;
|
||||
|
||||
if (mlen) {
|
||||
@@ -242,10 +220,9 @@ static int starfive_rsa_cpu_start(struct
|
||||
rctx->csr.pka.start = 1;
|
||||
rctx->csr.pka.ie = 1;
|
||||
|
||||
- starfive_pka_irq_mask_clear(ctx);
|
||||
writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
|
||||
|
||||
- if (!starfive_pka_wait_done(ctx))
|
||||
+ if (starfive_pka_wait_done(ctx))
|
||||
goto rsa_err;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
From eea9f2c55cf944bbd5cdd43eb655416a867846af Mon Sep 17 00:00:00 2001
|
||||
From: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Date: Mon, 20 Nov 2023 11:12:42 +0800
|
||||
Subject: [PATCH 011/116] crypto: starfive - Pad adata with zeroes
|
||||
|
||||
Aad requires padding with zeroes up to 15 bytes in some cases. This
|
||||
patch increases the allocated buffer size for aad and prevents the
|
||||
driver accessing uninitialized memory region.
|
||||
|
||||
v1->v2: Specify reason for alloc size change in descriptions.
|
||||
|
||||
Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
drivers/crypto/starfive/jh7110-aes.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/crypto/starfive/jh7110-aes.c
|
||||
+++ b/drivers/crypto/starfive/jh7110-aes.c
|
||||
@@ -500,7 +500,7 @@ static int starfive_aes_prepare_req(stru
|
||||
scatterwalk_start(&cryp->out_walk, rctx->out_sg);
|
||||
|
||||
if (cryp->assoclen) {
|
||||
- rctx->adata = kzalloc(ALIGN(cryp->assoclen, AES_BLOCK_SIZE), GFP_KERNEL);
|
||||
+ rctx->adata = kzalloc(cryp->assoclen + AES_BLOCK_SIZE, GFP_KERNEL);
|
||||
if (!rctx->adata)
|
||||
return dev_err_probe(cryp->dev, -ENOMEM,
|
||||
"Failed to alloc memory for adata");
|
||||
@@ -569,7 +569,7 @@ static int starfive_aes_aead_do_one_req(
|
||||
struct starfive_cryp_ctx *ctx =
|
||||
crypto_aead_ctx(crypto_aead_reqtfm(req));
|
||||
struct starfive_cryp_dev *cryp = ctx->cryp;
|
||||
- struct starfive_cryp_request_ctx *rctx = ctx->rctx;
|
||||
+ struct starfive_cryp_request_ctx *rctx;
|
||||
u32 block[AES_BLOCK_32];
|
||||
u32 stat;
|
||||
int err;
|
||||
@@ -579,6 +579,8 @@ static int starfive_aes_aead_do_one_req(
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ rctx = ctx->rctx;
|
||||
+
|
||||
if (!cryp->assoclen)
|
||||
goto write_text;
|
||||
|
@ -0,0 +1,125 @@
|
||||
From 922b213ad22f93fb2788ce119084622ab3d25bf8 Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Date: Thu, 30 Nov 2023 18:12:55 +0800
|
||||
Subject: [PATCH 012/116] crypto: starfive - Remove cfb and ofb
|
||||
|
||||
Remove the unused CFB/OFB implementation.
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
drivers/crypto/starfive/jh7110-aes.c | 71 +--------------------------
|
||||
drivers/crypto/starfive/jh7110-cryp.h | 2 -
|
||||
2 files changed, 1 insertion(+), 72 deletions(-)
|
||||
|
||||
--- a/drivers/crypto/starfive/jh7110-aes.c
|
||||
+++ b/drivers/crypto/starfive/jh7110-aes.c
|
||||
@@ -262,12 +262,7 @@ static int starfive_aes_hw_init(struct s
|
||||
rctx->csr.aes.mode = hw_mode;
|
||||
rctx->csr.aes.cmode = !is_encrypt(cryp);
|
||||
rctx->csr.aes.ie = 1;
|
||||
-
|
||||
- if (hw_mode == STARFIVE_AES_MODE_CFB ||
|
||||
- hw_mode == STARFIVE_AES_MODE_OFB)
|
||||
- rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_128;
|
||||
- else
|
||||
- rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_1;
|
||||
+ rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_1;
|
||||
|
||||
if (cryp->side_chan) {
|
||||
rctx->csr.aes.delay_aes = 1;
|
||||
@@ -294,8 +289,6 @@ static int starfive_aes_hw_init(struct s
|
||||
starfive_aes_ccm_init(ctx);
|
||||
starfive_aes_aead_hw_start(ctx, hw_mode);
|
||||
break;
|
||||
- case STARFIVE_AES_MODE_OFB:
|
||||
- case STARFIVE_AES_MODE_CFB:
|
||||
case STARFIVE_AES_MODE_CBC:
|
||||
case STARFIVE_AES_MODE_CTR:
|
||||
starfive_aes_write_iv(ctx, (void *)cryp->req.sreq->iv);
|
||||
@@ -785,26 +778,6 @@ static int starfive_aes_cbc_decrypt(stru
|
||||
return starfive_aes_crypt(req, STARFIVE_AES_MODE_CBC);
|
||||
}
|
||||
|
||||
-static int starfive_aes_cfb_encrypt(struct skcipher_request *req)
|
||||
-{
|
||||
- return starfive_aes_crypt(req, STARFIVE_AES_MODE_CFB | FLG_ENCRYPT);
|
||||
-}
|
||||
-
|
||||
-static int starfive_aes_cfb_decrypt(struct skcipher_request *req)
|
||||
-{
|
||||
- return starfive_aes_crypt(req, STARFIVE_AES_MODE_CFB);
|
||||
-}
|
||||
-
|
||||
-static int starfive_aes_ofb_encrypt(struct skcipher_request *req)
|
||||
-{
|
||||
- return starfive_aes_crypt(req, STARFIVE_AES_MODE_OFB | FLG_ENCRYPT);
|
||||
-}
|
||||
-
|
||||
-static int starfive_aes_ofb_decrypt(struct skcipher_request *req)
|
||||
-{
|
||||
- return starfive_aes_crypt(req, STARFIVE_AES_MODE_OFB);
|
||||
-}
|
||||
-
|
||||
static int starfive_aes_ctr_encrypt(struct skcipher_request *req)
|
||||
{
|
||||
return starfive_aes_crypt(req, STARFIVE_AES_MODE_CTR | FLG_ENCRYPT);
|
||||
@@ -903,48 +876,6 @@ static struct skcipher_engine_alg skciph
|
||||
.cra_priority = 200,
|
||||
.cra_flags = CRYPTO_ALG_ASYNC,
|
||||
.cra_blocksize = 1,
|
||||
- .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 0xf,
|
||||
- .cra_module = THIS_MODULE,
|
||||
- },
|
||||
- .op = {
|
||||
- .do_one_request = starfive_aes_do_one_req,
|
||||
- },
|
||||
-}, {
|
||||
- .base.init = starfive_aes_init_tfm,
|
||||
- .base.setkey = starfive_aes_setkey,
|
||||
- .base.encrypt = starfive_aes_cfb_encrypt,
|
||||
- .base.decrypt = starfive_aes_cfb_decrypt,
|
||||
- .base.min_keysize = AES_MIN_KEY_SIZE,
|
||||
- .base.max_keysize = AES_MAX_KEY_SIZE,
|
||||
- .base.ivsize = AES_BLOCK_SIZE,
|
||||
- .base.base = {
|
||||
- .cra_name = "cfb(aes)",
|
||||
- .cra_driver_name = "starfive-cfb-aes",
|
||||
- .cra_priority = 200,
|
||||
- .cra_flags = CRYPTO_ALG_ASYNC,
|
||||
- .cra_blocksize = 1,
|
||||
- .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
- .cra_alignmask = 0xf,
|
||||
- .cra_module = THIS_MODULE,
|
||||
- },
|
||||
- .op = {
|
||||
- .do_one_request = starfive_aes_do_one_req,
|
||||
- },
|
||||
-}, {
|
||||
- .base.init = starfive_aes_init_tfm,
|
||||
- .base.setkey = starfive_aes_setkey,
|
||||
- .base.encrypt = starfive_aes_ofb_encrypt,
|
||||
- .base.decrypt = starfive_aes_ofb_decrypt,
|
||||
- .base.min_keysize = AES_MIN_KEY_SIZE,
|
||||
- .base.max_keysize = AES_MAX_KEY_SIZE,
|
||||
- .base.ivsize = AES_BLOCK_SIZE,
|
||||
- .base.base = {
|
||||
- .cra_name = "ofb(aes)",
|
||||
- .cra_driver_name = "starfive-ofb-aes",
|
||||
- .cra_priority = 200,
|
||||
- .cra_flags = CRYPTO_ALG_ASYNC,
|
||||
- .cra_blocksize = 1,
|
||||
.cra_ctxsize = sizeof(struct starfive_cryp_ctx),
|
||||
.cra_alignmask = 0xf,
|
||||
.cra_module = THIS_MODULE,
|
||||
--- a/drivers/crypto/starfive/jh7110-cryp.h
|
||||
+++ b/drivers/crypto/starfive/jh7110-cryp.h
|
||||
@@ -50,8 +50,6 @@ union starfive_aes_csr {
|
||||
u32 ccm_start :1;
|
||||
#define STARFIVE_AES_MODE_ECB 0x0
|
||||
#define STARFIVE_AES_MODE_CBC 0x1
|
||||
-#define STARFIVE_AES_MODE_CFB 0x2
|
||||
-#define STARFIVE_AES_MODE_OFB 0x3
|
||||
#define STARFIVE_AES_MODE_CTR 0x4
|
||||
#define STARFIVE_AES_MODE_CCM 0x5
|
||||
#define STARFIVE_AES_MODE_GCM 0x6
|
@ -0,0 +1,33 @@
|
||||
From 0dbdc763f10c5cfa968dffc290a7c060ee740172 Mon Sep 17 00:00:00 2001
|
||||
From: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Date: Mon, 4 Dec 2023 11:02:39 +0800
|
||||
Subject: [PATCH 013/116] crypto: starfive - Remove unneeded NULL checks
|
||||
|
||||
NULL check before kfree_sensitive function is not needed.
|
||||
|
||||
Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Closes: https://lore.kernel.org/oe-kbuild-all/202311301702.LxswfETY-lkp@intel.com/
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
drivers/crypto/starfive/jh7110-rsa.c | 9 +++------
|
||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/crypto/starfive/jh7110-rsa.c
|
||||
+++ b/drivers/crypto/starfive/jh7110-rsa.c
|
||||
@@ -45,12 +45,9 @@ static inline int starfive_pka_wait_done
|
||||
|
||||
static void starfive_rsa_free_key(struct starfive_rsa_key *key)
|
||||
{
|
||||
- if (key->d)
|
||||
- kfree_sensitive(key->d);
|
||||
- if (key->e)
|
||||
- kfree_sensitive(key->e);
|
||||
- if (key->n)
|
||||
- kfree_sensitive(key->n);
|
||||
+ kfree_sensitive(key->d);
|
||||
+ kfree_sensitive(key->e);
|
||||
+ kfree_sensitive(key->n);
|
||||
memset(key, 0, sizeof(*key));
|
||||
}
|
||||
|
@ -0,0 +1,183 @@
|
||||
From 708695ebf1a779de9a1fd2f72f7938afa6c14ada Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:05:51 +0800
|
||||
Subject: [PATCH 014/116] dt-bindings: PCI: Add PLDA XpressRICH PCIe host
|
||||
common properties
|
||||
|
||||
Add PLDA XpressRICH PCIe host common properties dt-binding doc.
|
||||
PolarFire PCIe host using PLDA IP. Move common properties from Microchip
|
||||
PolarFire PCIe host to PLDA files.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Tested-by: John Clark <inindev@gmail.com>
|
||||
---
|
||||
.../bindings/pci/microchip,pcie-host.yaml | 55 +-------------
|
||||
.../pci/plda,xpressrich3-axi-common.yaml | 75 +++++++++++++++++++
|
||||
2 files changed, 76 insertions(+), 54 deletions(-)
|
||||
create mode 100644 Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
|
||||
|
||||
--- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
|
||||
+++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
|
||||
@@ -10,21 +10,13 @@ maintainers:
|
||||
- Daire McNamara <daire.mcnamara@microchip.com>
|
||||
|
||||
allOf:
|
||||
- - $ref: /schemas/pci/pci-bus.yaml#
|
||||
+ - $ref: plda,xpressrich3-axi-common.yaml#
|
||||
- $ref: /schemas/interrupt-controller/msi-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: microchip,pcie-host-1.0 # PolarFire
|
||||
|
||||
- reg:
|
||||
- maxItems: 2
|
||||
-
|
||||
- reg-names:
|
||||
- items:
|
||||
- - const: cfg
|
||||
- - const: apb
|
||||
-
|
||||
clocks:
|
||||
description:
|
||||
Fabric Interface Controllers, FICs, are the interface between the FPGA
|
||||
@@ -52,18 +44,6 @@ properties:
|
||||
items:
|
||||
pattern: '^fic[0-3]$'
|
||||
|
||||
- interrupts:
|
||||
- minItems: 1
|
||||
- items:
|
||||
- - description: PCIe host controller
|
||||
- - description: builtin MSI controller
|
||||
-
|
||||
- interrupt-names:
|
||||
- minItems: 1
|
||||
- items:
|
||||
- - const: pcie
|
||||
- - const: msi
|
||||
-
|
||||
ranges:
|
||||
maxItems: 1
|
||||
|
||||
@@ -71,39 +51,6 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 6
|
||||
|
||||
- msi-controller:
|
||||
- description: Identifies the node as an MSI controller.
|
||||
-
|
||||
- msi-parent:
|
||||
- description: MSI controller the device is capable of using.
|
||||
-
|
||||
- interrupt-controller:
|
||||
- type: object
|
||||
- properties:
|
||||
- '#address-cells':
|
||||
- const: 0
|
||||
-
|
||||
- '#interrupt-cells':
|
||||
- const: 1
|
||||
-
|
||||
- interrupt-controller: true
|
||||
-
|
||||
- required:
|
||||
- - '#address-cells'
|
||||
- - '#interrupt-cells'
|
||||
- - interrupt-controller
|
||||
-
|
||||
- additionalProperties: false
|
||||
-
|
||||
-required:
|
||||
- - reg
|
||||
- - reg-names
|
||||
- - "#interrupt-cells"
|
||||
- - interrupts
|
||||
- - interrupt-map-mask
|
||||
- - interrupt-map
|
||||
- - msi-controller
|
||||
-
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
|
||||
@@ -0,0 +1,75 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/pci/plda,xpressrich3-axi-common.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: PLDA XpressRICH PCIe host common properties
|
||||
+
|
||||
+maintainers:
|
||||
+ - Daire McNamara <daire.mcnamara@microchip.com>
|
||||
+ - Kevin Xie <kevin.xie@starfivetech.com>
|
||||
+
|
||||
+description:
|
||||
+ Generic PLDA XpressRICH PCIe host common properties.
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: /schemas/pci/pci-bus.yaml#
|
||||
+
|
||||
+properties:
|
||||
+ reg:
|
||||
+ maxItems: 2
|
||||
+
|
||||
+ reg-names:
|
||||
+ items:
|
||||
+ - const: cfg
|
||||
+ - const: apb
|
||||
+
|
||||
+ interrupts:
|
||||
+ minItems: 1
|
||||
+ items:
|
||||
+ - description: PCIe host controller
|
||||
+ - description: builtin MSI controller
|
||||
+
|
||||
+ interrupt-names:
|
||||
+ minItems: 1
|
||||
+ items:
|
||||
+ - const: pcie
|
||||
+ - const: msi
|
||||
+
|
||||
+ msi-controller:
|
||||
+ description: Identifies the node as an MSI controller.
|
||||
+
|
||||
+ msi-parent:
|
||||
+ description: MSI controller the device is capable of using.
|
||||
+
|
||||
+ interrupt-controller:
|
||||
+ type: object
|
||||
+ properties:
|
||||
+ '#address-cells':
|
||||
+ const: 0
|
||||
+
|
||||
+ '#interrupt-cells':
|
||||
+ const: 1
|
||||
+
|
||||
+ interrupt-controller: true
|
||||
+
|
||||
+ required:
|
||||
+ - '#address-cells'
|
||||
+ - '#interrupt-cells'
|
||||
+ - interrupt-controller
|
||||
+
|
||||
+ additionalProperties: false
|
||||
+
|
||||
+required:
|
||||
+ - reg
|
||||
+ - reg-names
|
||||
+ - interrupts
|
||||
+ - msi-controller
|
||||
+ - "#interrupt-cells"
|
||||
+ - interrupt-map-mask
|
||||
+ - interrupt-map
|
||||
+
|
||||
+additionalProperties: true
|
||||
+
|
||||
+...
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,259 @@
|
||||
From eca1b864bb2d4e8d9811506979560a89351c2e37 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:05:53 +0800
|
||||
Subject: [PATCH 016/116] PCI: microchip: Move PLDA IP register macros to
|
||||
pcie-plda.h
|
||||
|
||||
Move PLDA PCIe host controller IP registers macros to pcie-plda.h,
|
||||
including bridge registers and local IRQ event number.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 108 +++---------------
|
||||
drivers/pci/controller/plda/pcie-plda.h | 108 ++++++++++++++++++
|
||||
2 files changed, 124 insertions(+), 92 deletions(-)
|
||||
create mode 100644 drivers/pci/controller/plda/pcie-plda.h
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "../../pci.h"
|
||||
+#include "pcie-plda.h"
|
||||
|
||||
/* Number of MSI IRQs */
|
||||
#define MC_MAX_NUM_MSI_IRQS 32
|
||||
@@ -30,84 +31,6 @@
|
||||
#define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
|
||||
#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
|
||||
|
||||
-/* PCIe Bridge Phy Regs */
|
||||
-#define PCIE_PCI_IRQ_DW0 0xa8
|
||||
-#define MSIX_CAP_MASK BIT(31)
|
||||
-#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
|
||||
-#define NUM_MSI_MSGS_SHIFT 4
|
||||
-
|
||||
-#define IMASK_LOCAL 0x180
|
||||
-#define DMA_END_ENGINE_0_MASK 0x00000000u
|
||||
-#define DMA_END_ENGINE_0_SHIFT 0
|
||||
-#define DMA_END_ENGINE_1_MASK 0x00000000u
|
||||
-#define DMA_END_ENGINE_1_SHIFT 1
|
||||
-#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
|
||||
-#define DMA_ERROR_ENGINE_0_SHIFT 8
|
||||
-#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
|
||||
-#define DMA_ERROR_ENGINE_1_SHIFT 9
|
||||
-#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
|
||||
-#define A_ATR_EVT_POST_ERR_SHIFT 16
|
||||
-#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
|
||||
-#define A_ATR_EVT_FETCH_ERR_SHIFT 17
|
||||
-#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
|
||||
-#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
|
||||
-#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
|
||||
-#define A_ATR_EVT_DOORBELL_SHIFT 19
|
||||
-#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
|
||||
-#define P_ATR_EVT_POST_ERR_SHIFT 20
|
||||
-#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
|
||||
-#define P_ATR_EVT_FETCH_ERR_SHIFT 21
|
||||
-#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
|
||||
-#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
|
||||
-#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
|
||||
-#define P_ATR_EVT_DOORBELL_SHIFT 23
|
||||
-#define PM_MSI_INT_INTA_MASK 0x01000000u
|
||||
-#define PM_MSI_INT_INTA_SHIFT 24
|
||||
-#define PM_MSI_INT_INTB_MASK 0x02000000u
|
||||
-#define PM_MSI_INT_INTB_SHIFT 25
|
||||
-#define PM_MSI_INT_INTC_MASK 0x04000000u
|
||||
-#define PM_MSI_INT_INTC_SHIFT 26
|
||||
-#define PM_MSI_INT_INTD_MASK 0x08000000u
|
||||
-#define PM_MSI_INT_INTD_SHIFT 27
|
||||
-#define PM_MSI_INT_INTX_MASK 0x0f000000u
|
||||
-#define PM_MSI_INT_INTX_SHIFT 24
|
||||
-#define PM_MSI_INT_MSI_MASK 0x10000000u
|
||||
-#define PM_MSI_INT_MSI_SHIFT 28
|
||||
-#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
|
||||
-#define PM_MSI_INT_AER_EVT_SHIFT 29
|
||||
-#define PM_MSI_INT_EVENTS_MASK 0x40000000u
|
||||
-#define PM_MSI_INT_EVENTS_SHIFT 30
|
||||
-#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
|
||||
-#define PM_MSI_INT_SYS_ERR_SHIFT 31
|
||||
-#define NUM_LOCAL_EVENTS 15
|
||||
-#define ISTATUS_LOCAL 0x184
|
||||
-#define IMASK_HOST 0x188
|
||||
-#define ISTATUS_HOST 0x18c
|
||||
-#define IMSI_ADDR 0x190
|
||||
-#define ISTATUS_MSI 0x194
|
||||
-
|
||||
-/* PCIe Master table init defines */
|
||||
-#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
|
||||
-#define ATR0_PCIE_ATR_SIZE 0x25
|
||||
-#define ATR0_PCIE_ATR_SIZE_SHIFT 1
|
||||
-#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
|
||||
-#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
|
||||
-#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
|
||||
-#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
|
||||
-
|
||||
-/* PCIe AXI slave table init defines */
|
||||
-#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
|
||||
-#define ATR_SIZE_SHIFT 1
|
||||
-#define ATR_IMPL_ENABLE 1
|
||||
-#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
|
||||
-#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
|
||||
-#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
|
||||
-#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
|
||||
-#define PCIE_TX_RX_INTERFACE 0x00000000u
|
||||
-#define PCIE_CONFIG_INTERFACE 0x00000001u
|
||||
-
|
||||
-#define ATR_ENTRY_SIZE 32
|
||||
-
|
||||
/* PCIe Controller Phy Regs */
|
||||
#define SEC_ERROR_EVENT_CNT 0x20
|
||||
#define DED_ERROR_EVENT_CNT 0x24
|
||||
@@ -179,20 +102,21 @@
|
||||
#define EVENT_LOCAL_DMA_END_ENGINE_1 12
|
||||
#define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13
|
||||
#define EVENT_LOCAL_DMA_ERROR_ENGINE_1 14
|
||||
-#define EVENT_LOCAL_A_ATR_EVT_POST_ERR 15
|
||||
-#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR 16
|
||||
-#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR 17
|
||||
-#define EVENT_LOCAL_A_ATR_EVT_DOORBELL 18
|
||||
-#define EVENT_LOCAL_P_ATR_EVT_POST_ERR 19
|
||||
-#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR 20
|
||||
-#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR 21
|
||||
-#define EVENT_LOCAL_P_ATR_EVT_DOORBELL 22
|
||||
-#define EVENT_LOCAL_PM_MSI_INT_INTX 23
|
||||
-#define EVENT_LOCAL_PM_MSI_INT_MSI 24
|
||||
-#define EVENT_LOCAL_PM_MSI_INT_AER_EVT 25
|
||||
-#define EVENT_LOCAL_PM_MSI_INT_EVENTS 26
|
||||
-#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR 27
|
||||
-#define NUM_EVENTS 28
|
||||
+#define NUM_MC_EVENTS 15
|
||||
+#define EVENT_LOCAL_A_ATR_EVT_POST_ERR (NUM_MC_EVENTS + PLDA_AXI_POST_ERR)
|
||||
+#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + PLDA_AXI_FETCH_ERR)
|
||||
+#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + PLDA_AXI_DISCARD_ERR)
|
||||
+#define EVENT_LOCAL_A_ATR_EVT_DOORBELL (NUM_MC_EVENTS + PLDA_AXI_DOORBELL)
|
||||
+#define EVENT_LOCAL_P_ATR_EVT_POST_ERR (NUM_MC_EVENTS + PLDA_PCIE_POST_ERR)
|
||||
+#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + PLDA_PCIE_FETCH_ERR)
|
||||
+#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + PLDA_PCIE_DISCARD_ERR)
|
||||
+#define EVENT_LOCAL_P_ATR_EVT_DOORBELL (NUM_MC_EVENTS + PLDA_PCIE_DOORBELL)
|
||||
+#define EVENT_LOCAL_PM_MSI_INT_INTX (NUM_MC_EVENTS + PLDA_INTX)
|
||||
+#define EVENT_LOCAL_PM_MSI_INT_MSI (NUM_MC_EVENTS + PLDA_MSI)
|
||||
+#define EVENT_LOCAL_PM_MSI_INT_AER_EVT (NUM_MC_EVENTS + PLDA_AER_EVENT)
|
||||
+#define EVENT_LOCAL_PM_MSI_INT_EVENTS (NUM_MC_EVENTS + PLDA_MISC_EVENTS)
|
||||
+#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR (NUM_MC_EVENTS + PLDA_SYS_ERR)
|
||||
+#define NUM_EVENTS (NUM_MC_EVENTS + PLDA_INT_EVENT_NUM)
|
||||
|
||||
#define PCIE_EVENT_CAUSE(x, s) \
|
||||
[EVENT_PCIE_ ## x] = { __stringify(x), s }
|
||||
--- /dev/null
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -0,0 +1,108 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * PLDA PCIe host controller driver
|
||||
+ */
|
||||
+
|
||||
+#ifndef _PCIE_PLDA_H
|
||||
+#define _PCIE_PLDA_H
|
||||
+
|
||||
+/* PCIe Bridge Phy Regs */
|
||||
+#define PCIE_PCI_IRQ_DW0 0xa8
|
||||
+#define MSIX_CAP_MASK BIT(31)
|
||||
+#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
|
||||
+#define NUM_MSI_MSGS_SHIFT 4
|
||||
+
|
||||
+#define IMASK_LOCAL 0x180
|
||||
+#define DMA_END_ENGINE_0_MASK 0x00000000u
|
||||
+#define DMA_END_ENGINE_0_SHIFT 0
|
||||
+#define DMA_END_ENGINE_1_MASK 0x00000000u
|
||||
+#define DMA_END_ENGINE_1_SHIFT 1
|
||||
+#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
|
||||
+#define DMA_ERROR_ENGINE_0_SHIFT 8
|
||||
+#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
|
||||
+#define DMA_ERROR_ENGINE_1_SHIFT 9
|
||||
+#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
|
||||
+#define A_ATR_EVT_POST_ERR_SHIFT 16
|
||||
+#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
|
||||
+#define A_ATR_EVT_FETCH_ERR_SHIFT 17
|
||||
+#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
|
||||
+#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
|
||||
+#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
|
||||
+#define A_ATR_EVT_DOORBELL_SHIFT 19
|
||||
+#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
|
||||
+#define P_ATR_EVT_POST_ERR_SHIFT 20
|
||||
+#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
|
||||
+#define P_ATR_EVT_FETCH_ERR_SHIFT 21
|
||||
+#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
|
||||
+#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
|
||||
+#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
|
||||
+#define P_ATR_EVT_DOORBELL_SHIFT 23
|
||||
+#define PM_MSI_INT_INTA_MASK 0x01000000u
|
||||
+#define PM_MSI_INT_INTA_SHIFT 24
|
||||
+#define PM_MSI_INT_INTB_MASK 0x02000000u
|
||||
+#define PM_MSI_INT_INTB_SHIFT 25
|
||||
+#define PM_MSI_INT_INTC_MASK 0x04000000u
|
||||
+#define PM_MSI_INT_INTC_SHIFT 26
|
||||
+#define PM_MSI_INT_INTD_MASK 0x08000000u
|
||||
+#define PM_MSI_INT_INTD_SHIFT 27
|
||||
+#define PM_MSI_INT_INTX_MASK 0x0f000000u
|
||||
+#define PM_MSI_INT_INTX_SHIFT 24
|
||||
+#define PM_MSI_INT_MSI_MASK 0x10000000u
|
||||
+#define PM_MSI_INT_MSI_SHIFT 28
|
||||
+#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
|
||||
+#define PM_MSI_INT_AER_EVT_SHIFT 29
|
||||
+#define PM_MSI_INT_EVENTS_MASK 0x40000000u
|
||||
+#define PM_MSI_INT_EVENTS_SHIFT 30
|
||||
+#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
|
||||
+#define PM_MSI_INT_SYS_ERR_SHIFT 31
|
||||
+#define NUM_LOCAL_EVENTS 15
|
||||
+#define ISTATUS_LOCAL 0x184
|
||||
+#define IMASK_HOST 0x188
|
||||
+#define ISTATUS_HOST 0x18c
|
||||
+#define IMSI_ADDR 0x190
|
||||
+#define ISTATUS_MSI 0x194
|
||||
+
|
||||
+/* PCIe Master table init defines */
|
||||
+#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
|
||||
+#define ATR0_PCIE_ATR_SIZE 0x25
|
||||
+#define ATR0_PCIE_ATR_SIZE_SHIFT 1
|
||||
+#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
|
||||
+#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
|
||||
+#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
|
||||
+#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
|
||||
+
|
||||
+/* PCIe AXI slave table init defines */
|
||||
+#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
|
||||
+#define ATR_SIZE_SHIFT 1
|
||||
+#define ATR_IMPL_ENABLE 1
|
||||
+#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
|
||||
+#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
|
||||
+#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
|
||||
+#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
|
||||
+#define PCIE_TX_RX_INTERFACE 0x00000000u
|
||||
+#define PCIE_CONFIG_INTERFACE 0x00000001u
|
||||
+
|
||||
+#define ATR_ENTRY_SIZE 32
|
||||
+
|
||||
+enum plda_int_event {
|
||||
+ PLDA_AXI_POST_ERR,
|
||||
+ PLDA_AXI_FETCH_ERR,
|
||||
+ PLDA_AXI_DISCARD_ERR,
|
||||
+ PLDA_AXI_DOORBELL,
|
||||
+ PLDA_PCIE_POST_ERR,
|
||||
+ PLDA_PCIE_FETCH_ERR,
|
||||
+ PLDA_PCIE_DISCARD_ERR,
|
||||
+ PLDA_PCIE_DOORBELL,
|
||||
+ PLDA_INTX,
|
||||
+ PLDA_MSI,
|
||||
+ PLDA_AER_EVENT,
|
||||
+ PLDA_MISC_EVENTS,
|
||||
+ PLDA_SYS_ERR,
|
||||
+ PLDA_INT_EVENT_NUM
|
||||
+};
|
||||
+
|
||||
+#define PLDA_NUM_DMA_EVENTS 16
|
||||
+
|
||||
+#define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
|
||||
+
|
||||
+#endif
|
@ -0,0 +1,107 @@
|
||||
From 6ee4d4568314425079ae88229bb9abbff9b92b8b Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:05:54 +0800
|
||||
Subject: [PATCH 017/116] PCI: microchip: Add bridge_addr field to struct
|
||||
mc_pcie
|
||||
|
||||
For bridge address base is common PLDA field, Add this to struct mc_pcie
|
||||
first.
|
||||
|
||||
INTx and MSI codes interrupts codes will get the bridge base address from
|
||||
port->bridge_addr. These codes will be changed to common codes.
|
||||
axi_base_addr is Microchip its own data.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 23 ++++++++-----------
|
||||
1 file changed, 9 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -195,6 +195,7 @@ struct mc_pcie {
|
||||
struct irq_domain *event_domain;
|
||||
raw_spinlock_t lock;
|
||||
struct mc_msi msi;
|
||||
+ void __iomem *bridge_addr;
|
||||
};
|
||||
|
||||
struct cause {
|
||||
@@ -339,8 +340,7 @@ static void mc_handle_msi(struct irq_des
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
struct device *dev = port->dev;
|
||||
struct mc_msi *msi = &port->msi;
|
||||
- void __iomem *bridge_base_addr =
|
||||
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
+ void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
unsigned long status;
|
||||
u32 bit;
|
||||
int ret;
|
||||
@@ -365,8 +365,7 @@ static void mc_handle_msi(struct irq_des
|
||||
static void mc_msi_bottom_irq_ack(struct irq_data *data)
|
||||
{
|
||||
struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
- void __iomem *bridge_base_addr =
|
||||
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
+ void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
u32 bitpos = data->hwirq;
|
||||
|
||||
writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
|
||||
@@ -488,8 +487,7 @@ static void mc_handle_intx(struct irq_de
|
||||
struct mc_pcie *port = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
struct device *dev = port->dev;
|
||||
- void __iomem *bridge_base_addr =
|
||||
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
+ void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
unsigned long status;
|
||||
u32 bit;
|
||||
int ret;
|
||||
@@ -514,8 +512,7 @@ static void mc_handle_intx(struct irq_de
|
||||
static void mc_ack_intx_irq(struct irq_data *data)
|
||||
{
|
||||
struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
- void __iomem *bridge_base_addr =
|
||||
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
+ void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
|
||||
|
||||
writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
|
||||
@@ -524,8 +521,7 @@ static void mc_ack_intx_irq(struct irq_d
|
||||
static void mc_mask_intx_irq(struct irq_data *data)
|
||||
{
|
||||
struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
- void __iomem *bridge_base_addr =
|
||||
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
+ void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
unsigned long flags;
|
||||
u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
|
||||
u32 val;
|
||||
@@ -540,8 +536,7 @@ static void mc_mask_intx_irq(struct irq_
|
||||
static void mc_unmask_intx_irq(struct irq_data *data)
|
||||
{
|
||||
struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
- void __iomem *bridge_base_addr =
|
||||
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
+ void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
unsigned long flags;
|
||||
u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
|
||||
u32 val;
|
||||
@@ -896,8 +891,7 @@ static void mc_pcie_setup_window(void __
|
||||
static int mc_pcie_setup_windows(struct platform_device *pdev,
|
||||
struct mc_pcie *port)
|
||||
{
|
||||
- void __iomem *bridge_base_addr =
|
||||
- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
+ void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
|
||||
struct resource_entry *entry;
|
||||
u64 pci_addr;
|
||||
@@ -1081,6 +1075,7 @@ static int mc_host_probe(struct platform
|
||||
mc_disable_interrupts(port);
|
||||
|
||||
bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
+ port->bridge_addr = bridge_base_addr;
|
||||
|
||||
/* Allow enabling MSI by disabling MSI-X */
|
||||
val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
|
@ -0,0 +1,347 @@
|
||||
From 7c1c679bdd0b6b727248edbee77836024c935f91 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:05:55 +0800
|
||||
Subject: [PATCH 018/116] PCI: microchip: Rename two PCIe data structures
|
||||
|
||||
Add PLDA PCIe related data structures by rename data structure name from
|
||||
mc_* to plda_*.
|
||||
|
||||
axi_base_addr is stayed in struct mc_pcie for it's microchip its own data.
|
||||
|
||||
The event interrupt codes is still using struct mc_pcie because the event
|
||||
interrupt codes can not be re-used.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 96 ++++++++++---------
|
||||
1 file changed, 53 insertions(+), 43 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "pcie-plda.h"
|
||||
|
||||
/* Number of MSI IRQs */
|
||||
-#define MC_MAX_NUM_MSI_IRQS 32
|
||||
+#define PLDA_MAX_NUM_MSI_IRQS 32
|
||||
|
||||
/* PCIe Bridge Phy and Controller Phy offsets */
|
||||
#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
|
||||
@@ -179,25 +179,29 @@ struct event_map {
|
||||
u32 event_bit;
|
||||
};
|
||||
|
||||
-struct mc_msi {
|
||||
+struct plda_msi {
|
||||
struct mutex lock; /* Protect used bitmap */
|
||||
struct irq_domain *msi_domain;
|
||||
struct irq_domain *dev_domain;
|
||||
u32 num_vectors;
|
||||
u64 vector_phy;
|
||||
- DECLARE_BITMAP(used, MC_MAX_NUM_MSI_IRQS);
|
||||
+ DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS);
|
||||
};
|
||||
|
||||
-struct mc_pcie {
|
||||
- void __iomem *axi_base_addr;
|
||||
+struct plda_pcie_rp {
|
||||
struct device *dev;
|
||||
struct irq_domain *intx_domain;
|
||||
struct irq_domain *event_domain;
|
||||
raw_spinlock_t lock;
|
||||
- struct mc_msi msi;
|
||||
+ struct plda_msi msi;
|
||||
void __iomem *bridge_addr;
|
||||
};
|
||||
|
||||
+struct mc_pcie {
|
||||
+ struct plda_pcie_rp plda;
|
||||
+ void __iomem *axi_base_addr;
|
||||
+};
|
||||
+
|
||||
struct cause {
|
||||
const char *sym;
|
||||
const char *str;
|
||||
@@ -313,7 +317,7 @@ static struct mc_pcie *port;
|
||||
|
||||
static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)
|
||||
{
|
||||
- struct mc_msi *msi = &port->msi;
|
||||
+ struct plda_msi *msi = &port->plda.msi;
|
||||
u16 reg;
|
||||
u8 queue_size;
|
||||
|
||||
@@ -336,10 +340,10 @@ static void mc_pcie_enable_msi(struct mc
|
||||
|
||||
static void mc_handle_msi(struct irq_desc *desc)
|
||||
{
|
||||
- struct mc_pcie *port = irq_desc_get_handler_data(desc);
|
||||
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
struct device *dev = port->dev;
|
||||
- struct mc_msi *msi = &port->msi;
|
||||
+ struct plda_msi *msi = &port->msi;
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
unsigned long status;
|
||||
u32 bit;
|
||||
@@ -364,7 +368,7 @@ static void mc_handle_msi(struct irq_des
|
||||
|
||||
static void mc_msi_bottom_irq_ack(struct irq_data *data)
|
||||
{
|
||||
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
u32 bitpos = data->hwirq;
|
||||
|
||||
@@ -373,7 +377,7 @@ static void mc_msi_bottom_irq_ack(struct
|
||||
|
||||
static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
||||
{
|
||||
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
phys_addr_t addr = port->msi.vector_phy;
|
||||
|
||||
msg->address_lo = lower_32_bits(addr);
|
||||
@@ -400,8 +404,8 @@ static struct irq_chip mc_msi_bottom_irq
|
||||
static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
unsigned int nr_irqs, void *args)
|
||||
{
|
||||
- struct mc_pcie *port = domain->host_data;
|
||||
- struct mc_msi *msi = &port->msi;
|
||||
+ struct plda_pcie_rp *port = domain->host_data;
|
||||
+ struct plda_msi *msi = &port->msi;
|
||||
unsigned long bit;
|
||||
|
||||
mutex_lock(&msi->lock);
|
||||
@@ -425,8 +429,8 @@ static void mc_irq_msi_domain_free(struc
|
||||
unsigned int nr_irqs)
|
||||
{
|
||||
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
|
||||
- struct mc_pcie *port = irq_data_get_irq_chip_data(d);
|
||||
- struct mc_msi *msi = &port->msi;
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
|
||||
+ struct plda_msi *msi = &port->msi;
|
||||
|
||||
mutex_lock(&msi->lock);
|
||||
|
||||
@@ -456,11 +460,11 @@ static struct msi_domain_info mc_msi_dom
|
||||
.chip = &mc_msi_irq_chip,
|
||||
};
|
||||
|
||||
-static int mc_allocate_msi_domains(struct mc_pcie *port)
|
||||
+static int mc_allocate_msi_domains(struct plda_pcie_rp *port)
|
||||
{
|
||||
struct device *dev = port->dev;
|
||||
struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
|
||||
- struct mc_msi *msi = &port->msi;
|
||||
+ struct plda_msi *msi = &port->msi;
|
||||
|
||||
mutex_init(&port->msi.lock);
|
||||
|
||||
@@ -484,7 +488,7 @@ static int mc_allocate_msi_domains(struc
|
||||
|
||||
static void mc_handle_intx(struct irq_desc *desc)
|
||||
{
|
||||
- struct mc_pcie *port = irq_desc_get_handler_data(desc);
|
||||
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
struct device *dev = port->dev;
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
@@ -511,7 +515,7 @@ static void mc_handle_intx(struct irq_de
|
||||
|
||||
static void mc_ack_intx_irq(struct irq_data *data)
|
||||
{
|
||||
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
|
||||
|
||||
@@ -520,7 +524,7 @@ static void mc_ack_intx_irq(struct irq_d
|
||||
|
||||
static void mc_mask_intx_irq(struct irq_data *data)
|
||||
{
|
||||
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
unsigned long flags;
|
||||
u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
|
||||
@@ -535,7 +539,7 @@ static void mc_mask_intx_irq(struct irq_
|
||||
|
||||
static void mc_unmask_intx_irq(struct irq_data *data)
|
||||
{
|
||||
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
unsigned long flags;
|
||||
u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
|
||||
@@ -625,21 +629,22 @@ static u32 local_events(struct mc_pcie *
|
||||
return val;
|
||||
}
|
||||
|
||||
-static u32 get_events(struct mc_pcie *port)
|
||||
+static u32 get_events(struct plda_pcie_rp *port)
|
||||
{
|
||||
+ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
|
||||
u32 events = 0;
|
||||
|
||||
- events |= pcie_events(port);
|
||||
- events |= sec_errors(port);
|
||||
- events |= ded_errors(port);
|
||||
- events |= local_events(port);
|
||||
+ events |= pcie_events(mc_port);
|
||||
+ events |= sec_errors(mc_port);
|
||||
+ events |= ded_errors(mc_port);
|
||||
+ events |= local_events(mc_port);
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
static irqreturn_t mc_event_handler(int irq, void *dev_id)
|
||||
{
|
||||
- struct mc_pcie *port = dev_id;
|
||||
+ struct plda_pcie_rp *port = dev_id;
|
||||
struct device *dev = port->dev;
|
||||
struct irq_data *data;
|
||||
|
||||
@@ -655,7 +660,7 @@ static irqreturn_t mc_event_handler(int
|
||||
|
||||
static void mc_handle_event(struct irq_desc *desc)
|
||||
{
|
||||
- struct mc_pcie *port = irq_desc_get_handler_data(desc);
|
||||
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
|
||||
unsigned long events;
|
||||
u32 bit;
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
@@ -672,12 +677,13 @@ static void mc_handle_event(struct irq_d
|
||||
|
||||
static void mc_ack_event_irq(struct irq_data *data)
|
||||
{
|
||||
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
|
||||
u32 event = data->hwirq;
|
||||
void __iomem *addr;
|
||||
u32 mask;
|
||||
|
||||
- addr = port->axi_base_addr + event_descs[event].base +
|
||||
+ addr = mc_port->axi_base_addr + event_descs[event].base +
|
||||
event_descs[event].offset;
|
||||
mask = event_descs[event].mask;
|
||||
mask |= event_descs[event].enb_mask;
|
||||
@@ -687,13 +693,14 @@ static void mc_ack_event_irq(struct irq_
|
||||
|
||||
static void mc_mask_event_irq(struct irq_data *data)
|
||||
{
|
||||
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
|
||||
u32 event = data->hwirq;
|
||||
void __iomem *addr;
|
||||
u32 mask;
|
||||
u32 val;
|
||||
|
||||
- addr = port->axi_base_addr + event_descs[event].base +
|
||||
+ addr = mc_port->axi_base_addr + event_descs[event].base +
|
||||
event_descs[event].mask_offset;
|
||||
mask = event_descs[event].mask;
|
||||
if (event_descs[event].enb_mask) {
|
||||
@@ -717,13 +724,14 @@ static void mc_mask_event_irq(struct irq
|
||||
|
||||
static void mc_unmask_event_irq(struct irq_data *data)
|
||||
{
|
||||
- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
+ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
|
||||
u32 event = data->hwirq;
|
||||
void __iomem *addr;
|
||||
u32 mask;
|
||||
u32 val;
|
||||
|
||||
- addr = port->axi_base_addr + event_descs[event].base +
|
||||
+ addr = mc_port->axi_base_addr + event_descs[event].base +
|
||||
event_descs[event].mask_offset;
|
||||
mask = event_descs[event].mask;
|
||||
|
||||
@@ -811,7 +819,7 @@ static int mc_pcie_init_clks(struct devi
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int mc_pcie_init_irq_domains(struct mc_pcie *port)
|
||||
+static int mc_pcie_init_irq_domains(struct plda_pcie_rp *port)
|
||||
{
|
||||
struct device *dev = port->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
@@ -889,7 +897,7 @@ static void mc_pcie_setup_window(void __
|
||||
}
|
||||
|
||||
static int mc_pcie_setup_windows(struct platform_device *pdev,
|
||||
- struct mc_pcie *port)
|
||||
+ struct plda_pcie_rp *port)
|
||||
{
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
|
||||
@@ -970,7 +978,7 @@ static void mc_disable_interrupts(struct
|
||||
writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
|
||||
}
|
||||
|
||||
-static int mc_init_interrupts(struct platform_device *pdev, struct mc_pcie *port)
|
||||
+static int mc_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
int irq;
|
||||
@@ -1043,12 +1051,12 @@ static int mc_platform_init(struct pci_c
|
||||
mc_pcie_enable_msi(port, cfg->win);
|
||||
|
||||
/* Configure non-config space outbound ranges */
|
||||
- ret = mc_pcie_setup_windows(pdev, port);
|
||||
+ ret = mc_pcie_setup_windows(pdev, &port->plda);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Address translation is up; safe to enable interrupts */
|
||||
- ret = mc_init_interrupts(pdev, port);
|
||||
+ ret = mc_init_interrupts(pdev, &port->plda);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1059,6 +1067,7 @@ static int mc_host_probe(struct platform
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
void __iomem *bridge_base_addr;
|
||||
+ struct plda_pcie_rp *plda;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
@@ -1066,7 +1075,8 @@ static int mc_host_probe(struct platform
|
||||
if (!port)
|
||||
return -ENOMEM;
|
||||
|
||||
- port->dev = dev;
|
||||
+ plda = &port->plda;
|
||||
+ plda->dev = dev;
|
||||
|
||||
port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (IS_ERR(port->axi_base_addr))
|
||||
@@ -1075,7 +1085,7 @@ static int mc_host_probe(struct platform
|
||||
mc_disable_interrupts(port);
|
||||
|
||||
bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
- port->bridge_addr = bridge_base_addr;
|
||||
+ plda->bridge_addr = bridge_base_addr;
|
||||
|
||||
/* Allow enabling MSI by disabling MSI-X */
|
||||
val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
|
||||
@@ -1087,10 +1097,10 @@ static int mc_host_probe(struct platform
|
||||
val &= NUM_MSI_MSGS_MASK;
|
||||
val >>= NUM_MSI_MSGS_SHIFT;
|
||||
|
||||
- port->msi.num_vectors = 1 << val;
|
||||
+ plda->msi.num_vectors = 1 << val;
|
||||
|
||||
/* Pick vector address from design */
|
||||
- port->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
|
||||
+ plda->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
|
||||
|
||||
ret = mc_pcie_init_clks(dev);
|
||||
if (ret) {
|
@ -0,0 +1,87 @@
|
||||
From a53cf9b237dd53c9538b51a8df592888935c8411 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:05:56 +0800
|
||||
Subject: [PATCH 019/116] PCI: microchip: Move PCIe host data structures to
|
||||
plda-pcie.h
|
||||
|
||||
Move the common data structures definition to head file for these two data
|
||||
structures can be re-used.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 20 ------------------
|
||||
drivers/pci/controller/plda/pcie-plda.h | 21 +++++++++++++++++++
|
||||
2 files changed, 21 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -21,9 +21,6 @@
|
||||
#include "../../pci.h"
|
||||
#include "pcie-plda.h"
|
||||
|
||||
-/* Number of MSI IRQs */
|
||||
-#define PLDA_MAX_NUM_MSI_IRQS 32
|
||||
-
|
||||
/* PCIe Bridge Phy and Controller Phy offsets */
|
||||
#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
|
||||
#define MC_PCIE1_CTRL_ADDR 0x0000a000u
|
||||
@@ -179,23 +176,6 @@ struct event_map {
|
||||
u32 event_bit;
|
||||
};
|
||||
|
||||
-struct plda_msi {
|
||||
- struct mutex lock; /* Protect used bitmap */
|
||||
- struct irq_domain *msi_domain;
|
||||
- struct irq_domain *dev_domain;
|
||||
- u32 num_vectors;
|
||||
- u64 vector_phy;
|
||||
- DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS);
|
||||
-};
|
||||
-
|
||||
-struct plda_pcie_rp {
|
||||
- struct device *dev;
|
||||
- struct irq_domain *intx_domain;
|
||||
- struct irq_domain *event_domain;
|
||||
- raw_spinlock_t lock;
|
||||
- struct plda_msi msi;
|
||||
- void __iomem *bridge_addr;
|
||||
-};
|
||||
|
||||
struct mc_pcie {
|
||||
struct plda_pcie_rp plda;
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -6,6 +6,9 @@
|
||||
#ifndef _PCIE_PLDA_H
|
||||
#define _PCIE_PLDA_H
|
||||
|
||||
+/* Number of MSI IRQs */
|
||||
+#define PLDA_MAX_NUM_MSI_IRQS 32
|
||||
+
|
||||
/* PCIe Bridge Phy Regs */
|
||||
#define PCIE_PCI_IRQ_DW0 0xa8
|
||||
#define MSIX_CAP_MASK BIT(31)
|
||||
@@ -105,4 +108,22 @@ enum plda_int_event {
|
||||
|
||||
#define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
|
||||
|
||||
+struct plda_msi {
|
||||
+ struct mutex lock; /* Protect used bitmap */
|
||||
+ struct irq_domain *msi_domain;
|
||||
+ struct irq_domain *dev_domain;
|
||||
+ u32 num_vectors;
|
||||
+ u64 vector_phy;
|
||||
+ DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS);
|
||||
+};
|
||||
+
|
||||
+struct plda_pcie_rp {
|
||||
+ struct device *dev;
|
||||
+ struct irq_domain *intx_domain;
|
||||
+ struct irq_domain *event_domain;
|
||||
+ raw_spinlock_t lock;
|
||||
+ struct plda_msi msi;
|
||||
+ void __iomem *bridge_addr;
|
||||
+};
|
||||
+
|
||||
#endif
|
@ -0,0 +1,76 @@
|
||||
From d0e56d1ef7398bbf76be6e48d77943cbf644688e Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:05:57 +0800
|
||||
Subject: [PATCH 020/116] PCI: microchip: Rename two setup functions
|
||||
|
||||
Rename two setup functions to plda prefix. Prepare to re-use these two
|
||||
setup function.
|
||||
|
||||
For two setup functions names are similar, rename mc_pcie_setup_windows()
|
||||
to plda_pcie_setup_iomems().
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 24 +++++++++----------
|
||||
1 file changed, 12 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -838,9 +838,9 @@ static int mc_pcie_init_irq_domains(stru
|
||||
return mc_allocate_msi_domains(port);
|
||||
}
|
||||
|
||||
-static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
|
||||
- phys_addr_t axi_addr, phys_addr_t pci_addr,
|
||||
- size_t size)
|
||||
+static void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
|
||||
+ phys_addr_t axi_addr, phys_addr_t pci_addr,
|
||||
+ size_t size)
|
||||
{
|
||||
u32 atr_sz = ilog2(size) - 1;
|
||||
u32 val;
|
||||
@@ -876,8 +876,8 @@ static void mc_pcie_setup_window(void __
|
||||
writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
|
||||
}
|
||||
|
||||
-static int mc_pcie_setup_windows(struct platform_device *pdev,
|
||||
- struct plda_pcie_rp *port)
|
||||
+static int plda_pcie_setup_iomems(struct platform_device *pdev,
|
||||
+ struct plda_pcie_rp *port)
|
||||
{
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
|
||||
@@ -888,9 +888,9 @@ static int mc_pcie_setup_windows(struct
|
||||
resource_list_for_each_entry(entry, &bridge->windows) {
|
||||
if (resource_type(entry->res) == IORESOURCE_MEM) {
|
||||
pci_addr = entry->res->start - entry->offset;
|
||||
- mc_pcie_setup_window(bridge_base_addr, index,
|
||||
- entry->res->start, pci_addr,
|
||||
- resource_size(entry->res));
|
||||
+ plda_pcie_setup_window(bridge_base_addr, index,
|
||||
+ entry->res->start, pci_addr,
|
||||
+ resource_size(entry->res));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
@@ -1023,15 +1023,15 @@ static int mc_platform_init(struct pci_c
|
||||
int ret;
|
||||
|
||||
/* Configure address translation table 0 for PCIe config space */
|
||||
- mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
|
||||
- cfg->res.start,
|
||||
- resource_size(&cfg->res));
|
||||
+ plda_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
|
||||
+ cfg->res.start,
|
||||
+ resource_size(&cfg->res));
|
||||
|
||||
/* Need some fixups in config space */
|
||||
mc_pcie_enable_msi(port, cfg->win);
|
||||
|
||||
/* Configure non-config space outbound ranges */
|
||||
- ret = mc_pcie_setup_windows(pdev, &port->plda);
|
||||
+ ret = plda_pcie_setup_iomems(pdev, &port->plda);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 2fd7c88ef318fd39023ce1eb73f37a29fbd25d74 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:05:58 +0800
|
||||
Subject: [PATCH 021/116] PCI: microchip: Change the argument of
|
||||
plda_pcie_setup_iomems()
|
||||
|
||||
If other vendor do not select PCI_HOST_COMMON, the driver data is not
|
||||
struct pci_host_bridge.
|
||||
|
||||
Move calling platform_get_drvdata() to mc_platform_init().
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/pci/controller/plda/pcie-microchip-host.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -876,11 +876,10 @@ static void plda_pcie_setup_window(void
|
||||
writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
|
||||
}
|
||||
|
||||
-static int plda_pcie_setup_iomems(struct platform_device *pdev,
|
||||
+static int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
|
||||
struct plda_pcie_rp *port)
|
||||
{
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
- struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
|
||||
struct resource_entry *entry;
|
||||
u64 pci_addr;
|
||||
u32 index = 1;
|
||||
@@ -1018,6 +1017,7 @@ static int mc_platform_init(struct pci_c
|
||||
{
|
||||
struct device *dev = cfg->parent;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
+ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
|
||||
void __iomem *bridge_base_addr =
|
||||
port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
int ret;
|
||||
@@ -1031,7 +1031,7 @@ static int mc_platform_init(struct pci_c
|
||||
mc_pcie_enable_msi(port, cfg->win);
|
||||
|
||||
/* Configure non-config space outbound ranges */
|
||||
- ret = plda_pcie_setup_iomems(pdev, &port->plda);
|
||||
+ ret = plda_pcie_setup_iomems(bridge, &port->plda);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -0,0 +1,200 @@
|
||||
From 201ce99897ff5fff2612cb633406e90c1b2acbcf Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:05:59 +0800
|
||||
Subject: [PATCH 022/116] PCI: microchip: Move setup functions to
|
||||
pcie-plda-host.c
|
||||
|
||||
Move setup functions to common pcie-plda-host.c. So these two functions
|
||||
can be re-used.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/pci/controller/plda/Kconfig | 4 +
|
||||
drivers/pci/controller/plda/Makefile | 1 +
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 59 ---------------
|
||||
drivers/pci/controller/plda/pcie-plda-host.c | 74 +++++++++++++++++++
|
||||
drivers/pci/controller/plda/pcie-plda.h | 5 ++
|
||||
5 files changed, 84 insertions(+), 59 deletions(-)
|
||||
create mode 100644 drivers/pci/controller/plda/pcie-plda-host.c
|
||||
|
||||
--- a/drivers/pci/controller/plda/Kconfig
|
||||
+++ b/drivers/pci/controller/plda/Kconfig
|
||||
@@ -3,10 +3,14 @@
|
||||
menu "PLDA-based PCIe controllers"
|
||||
depends on PCI
|
||||
|
||||
+config PCIE_PLDA_HOST
|
||||
+ bool
|
||||
+
|
||||
config PCIE_MICROCHIP_HOST
|
||||
tristate "Microchip AXI PCIe controller"
|
||||
depends on PCI_MSI && OF
|
||||
select PCI_HOST_COMMON
|
||||
+ select PCIE_PLDA_HOST
|
||||
help
|
||||
Say Y here if you want kernel to support the Microchip AXI PCIe
|
||||
Host Bridge driver.
|
||||
--- a/drivers/pci/controller/plda/Makefile
|
||||
+++ b/drivers/pci/controller/plda/Makefile
|
||||
@@ -1,2 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_PCIE_PLDA_HOST) += pcie-plda-host.o
|
||||
obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -838,65 +838,6 @@ static int mc_pcie_init_irq_domains(stru
|
||||
return mc_allocate_msi_domains(port);
|
||||
}
|
||||
|
||||
-static void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
|
||||
- phys_addr_t axi_addr, phys_addr_t pci_addr,
|
||||
- size_t size)
|
||||
-{
|
||||
- u32 atr_sz = ilog2(size) - 1;
|
||||
- u32 val;
|
||||
-
|
||||
- if (index == 0)
|
||||
- val = PCIE_CONFIG_INTERFACE;
|
||||
- else
|
||||
- val = PCIE_TX_RX_INTERFACE;
|
||||
-
|
||||
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
- ATR0_AXI4_SLV0_TRSL_PARAM);
|
||||
-
|
||||
- val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
|
||||
- ATR_IMPL_ENABLE;
|
||||
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
- ATR0_AXI4_SLV0_SRCADDR_PARAM);
|
||||
-
|
||||
- val = upper_32_bits(axi_addr);
|
||||
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
- ATR0_AXI4_SLV0_SRC_ADDR);
|
||||
-
|
||||
- val = lower_32_bits(pci_addr);
|
||||
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
- ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
|
||||
-
|
||||
- val = upper_32_bits(pci_addr);
|
||||
- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
- ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
|
||||
-
|
||||
- val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
|
||||
- val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
|
||||
- writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
|
||||
- writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
|
||||
-}
|
||||
-
|
||||
-static int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
|
||||
- struct plda_pcie_rp *port)
|
||||
-{
|
||||
- void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
- struct resource_entry *entry;
|
||||
- u64 pci_addr;
|
||||
- u32 index = 1;
|
||||
-
|
||||
- resource_list_for_each_entry(entry, &bridge->windows) {
|
||||
- if (resource_type(entry->res) == IORESOURCE_MEM) {
|
||||
- pci_addr = entry->res->start - entry->offset;
|
||||
- plda_pcie_setup_window(bridge_base_addr, index,
|
||||
- entry->res->start, pci_addr,
|
||||
- resource_size(entry->res));
|
||||
- index++;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static inline void mc_clear_secs(struct mc_pcie *port)
|
||||
{
|
||||
void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
|
||||
--- /dev/null
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda-host.c
|
||||
@@ -0,0 +1,74 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * PLDA PCIe XpressRich host controller driver
|
||||
+ *
|
||||
+ * Copyright (C) 2023 Microchip Co. Ltd
|
||||
+ *
|
||||
+ * Author: Daire McNamara <daire.mcnamara@microchip.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/pci_regs.h>
|
||||
+#include <linux/pci-ecam.h>
|
||||
+
|
||||
+#include "pcie-plda.h"
|
||||
+
|
||||
+void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
|
||||
+ phys_addr_t axi_addr, phys_addr_t pci_addr,
|
||||
+ size_t size)
|
||||
+{
|
||||
+ u32 atr_sz = ilog2(size) - 1;
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (index == 0)
|
||||
+ val = PCIE_CONFIG_INTERFACE;
|
||||
+ else
|
||||
+ val = PCIE_TX_RX_INTERFACE;
|
||||
+
|
||||
+ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
+ ATR0_AXI4_SLV0_TRSL_PARAM);
|
||||
+
|
||||
+ val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
|
||||
+ ATR_IMPL_ENABLE;
|
||||
+ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
+ ATR0_AXI4_SLV0_SRCADDR_PARAM);
|
||||
+
|
||||
+ val = upper_32_bits(axi_addr);
|
||||
+ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
+ ATR0_AXI4_SLV0_SRC_ADDR);
|
||||
+
|
||||
+ val = lower_32_bits(pci_addr);
|
||||
+ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
+ ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
|
||||
+
|
||||
+ val = upper_32_bits(pci_addr);
|
||||
+ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
|
||||
+ ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
|
||||
+
|
||||
+ val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
|
||||
+ val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
|
||||
+ writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
|
||||
+ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(plda_pcie_setup_window);
|
||||
+
|
||||
+int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
|
||||
+ struct plda_pcie_rp *port)
|
||||
+{
|
||||
+ void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
+ struct resource_entry *entry;
|
||||
+ u64 pci_addr;
|
||||
+ u32 index = 1;
|
||||
+
|
||||
+ resource_list_for_each_entry(entry, &bridge->windows) {
|
||||
+ if (resource_type(entry->res) == IORESOURCE_MEM) {
|
||||
+ pci_addr = entry->res->start - entry->offset;
|
||||
+ plda_pcie_setup_window(bridge_base_addr, index,
|
||||
+ entry->res->start, pci_addr,
|
||||
+ resource_size(entry->res));
|
||||
+ index++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -126,4 +126,9 @@ struct plda_pcie_rp {
|
||||
void __iomem *bridge_addr;
|
||||
};
|
||||
|
||||
+void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
|
||||
+ phys_addr_t axi_addr, phys_addr_t pci_addr,
|
||||
+ size_t size);
|
||||
+int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
|
||||
+ struct plda_pcie_rp *port);
|
||||
#endif
|
@ -0,0 +1,336 @@
|
||||
From 2a48bc45dcf8cbe736b594d013cfa9d682214c43 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:00 +0800
|
||||
Subject: [PATCH 023/116] PCI: microchip: Rename interrupt related functions
|
||||
|
||||
Rename mc_* to plda_* for IRQ functions and related IRQ domain ops data
|
||||
instances.
|
||||
|
||||
MSI, INTx interrupt code and IRQ init code are all can be re-used.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 109 +++++++++---------
|
||||
1 file changed, 57 insertions(+), 52 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -318,7 +318,7 @@ static void mc_pcie_enable_msi(struct mc
|
||||
ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
|
||||
}
|
||||
|
||||
-static void mc_handle_msi(struct irq_desc *desc)
|
||||
+static void plda_handle_msi(struct irq_desc *desc)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
@@ -346,7 +346,7 @@ static void mc_handle_msi(struct irq_des
|
||||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
-static void mc_msi_bottom_irq_ack(struct irq_data *data)
|
||||
+static void plda_msi_bottom_irq_ack(struct irq_data *data)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
@@ -355,7 +355,7 @@ static void mc_msi_bottom_irq_ack(struct
|
||||
writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
|
||||
}
|
||||
|
||||
-static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
||||
+static void plda_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
phys_addr_t addr = port->msi.vector_phy;
|
||||
@@ -368,21 +368,23 @@ static void mc_compose_msi_msg(struct ir
|
||||
(int)data->hwirq, msg->address_hi, msg->address_lo);
|
||||
}
|
||||
|
||||
-static int mc_msi_set_affinity(struct irq_data *irq_data,
|
||||
- const struct cpumask *mask, bool force)
|
||||
+static int plda_msi_set_affinity(struct irq_data *irq_data,
|
||||
+ const struct cpumask *mask, bool force)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
-static struct irq_chip mc_msi_bottom_irq_chip = {
|
||||
- .name = "Microchip MSI",
|
||||
- .irq_ack = mc_msi_bottom_irq_ack,
|
||||
- .irq_compose_msi_msg = mc_compose_msi_msg,
|
||||
- .irq_set_affinity = mc_msi_set_affinity,
|
||||
+static struct irq_chip plda_msi_bottom_irq_chip = {
|
||||
+ .name = "PLDA MSI",
|
||||
+ .irq_ack = plda_msi_bottom_irq_ack,
|
||||
+ .irq_compose_msi_msg = plda_compose_msi_msg,
|
||||
+ .irq_set_affinity = plda_msi_set_affinity,
|
||||
};
|
||||
|
||||
-static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
- unsigned int nr_irqs, void *args)
|
||||
+static int plda_irq_msi_domain_alloc(struct irq_domain *domain,
|
||||
+ unsigned int virq,
|
||||
+ unsigned int nr_irqs,
|
||||
+ void *args)
|
||||
{
|
||||
struct plda_pcie_rp *port = domain->host_data;
|
||||
struct plda_msi *msi = &port->msi;
|
||||
@@ -397,7 +399,7 @@ static int mc_irq_msi_domain_alloc(struc
|
||||
|
||||
set_bit(bit, msi->used);
|
||||
|
||||
- irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
|
||||
+ irq_domain_set_info(domain, virq, bit, &plda_msi_bottom_irq_chip,
|
||||
domain->host_data, handle_edge_irq, NULL, NULL);
|
||||
|
||||
mutex_unlock(&msi->lock);
|
||||
@@ -405,8 +407,9 @@ static int mc_irq_msi_domain_alloc(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq,
|
||||
- unsigned int nr_irqs)
|
||||
+static void plda_irq_msi_domain_free(struct irq_domain *domain,
|
||||
+ unsigned int virq,
|
||||
+ unsigned int nr_irqs)
|
||||
{
|
||||
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
|
||||
struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
|
||||
@@ -423,24 +426,24 @@ static void mc_irq_msi_domain_free(struc
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops msi_domain_ops = {
|
||||
- .alloc = mc_irq_msi_domain_alloc,
|
||||
- .free = mc_irq_msi_domain_free,
|
||||
+ .alloc = plda_irq_msi_domain_alloc,
|
||||
+ .free = plda_irq_msi_domain_free,
|
||||
};
|
||||
|
||||
-static struct irq_chip mc_msi_irq_chip = {
|
||||
- .name = "Microchip PCIe MSI",
|
||||
+static struct irq_chip plda_msi_irq_chip = {
|
||||
+ .name = "PLDA PCIe MSI",
|
||||
.irq_ack = irq_chip_ack_parent,
|
||||
.irq_mask = pci_msi_mask_irq,
|
||||
.irq_unmask = pci_msi_unmask_irq,
|
||||
};
|
||||
|
||||
-static struct msi_domain_info mc_msi_domain_info = {
|
||||
+static struct msi_domain_info plda_msi_domain_info = {
|
||||
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
|
||||
MSI_FLAG_PCI_MSIX),
|
||||
- .chip = &mc_msi_irq_chip,
|
||||
+ .chip = &plda_msi_irq_chip,
|
||||
};
|
||||
|
||||
-static int mc_allocate_msi_domains(struct plda_pcie_rp *port)
|
||||
+static int plda_allocate_msi_domains(struct plda_pcie_rp *port)
|
||||
{
|
||||
struct device *dev = port->dev;
|
||||
struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
|
||||
@@ -455,7 +458,8 @@ static int mc_allocate_msi_domains(struc
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info,
|
||||
+ msi->msi_domain = pci_msi_create_irq_domain(fwnode,
|
||||
+ &plda_msi_domain_info,
|
||||
msi->dev_domain);
|
||||
if (!msi->msi_domain) {
|
||||
dev_err(dev, "failed to create MSI domain\n");
|
||||
@@ -466,7 +470,7 @@ static int mc_allocate_msi_domains(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void mc_handle_intx(struct irq_desc *desc)
|
||||
+static void plda_handle_intx(struct irq_desc *desc)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
@@ -493,7 +497,7 @@ static void mc_handle_intx(struct irq_de
|
||||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
-static void mc_ack_intx_irq(struct irq_data *data)
|
||||
+static void plda_ack_intx_irq(struct irq_data *data)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
@@ -502,7 +506,7 @@ static void mc_ack_intx_irq(struct irq_d
|
||||
writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
|
||||
}
|
||||
|
||||
-static void mc_mask_intx_irq(struct irq_data *data)
|
||||
+static void plda_mask_intx_irq(struct irq_data *data)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
@@ -517,7 +521,7 @@ static void mc_mask_intx_irq(struct irq_
|
||||
raw_spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
-static void mc_unmask_intx_irq(struct irq_data *data)
|
||||
+static void plda_unmask_intx_irq(struct irq_data *data)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
void __iomem *bridge_base_addr = port->bridge_addr;
|
||||
@@ -532,24 +536,24 @@ static void mc_unmask_intx_irq(struct ir
|
||||
raw_spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
-static struct irq_chip mc_intx_irq_chip = {
|
||||
- .name = "Microchip PCIe INTx",
|
||||
- .irq_ack = mc_ack_intx_irq,
|
||||
- .irq_mask = mc_mask_intx_irq,
|
||||
- .irq_unmask = mc_unmask_intx_irq,
|
||||
+static struct irq_chip plda_intx_irq_chip = {
|
||||
+ .name = "PLDA PCIe INTx",
|
||||
+ .irq_ack = plda_ack_intx_irq,
|
||||
+ .irq_mask = plda_mask_intx_irq,
|
||||
+ .irq_unmask = plda_unmask_intx_irq,
|
||||
};
|
||||
|
||||
-static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
|
||||
- irq_hw_number_t hwirq)
|
||||
+static int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
|
||||
+ irq_hw_number_t hwirq)
|
||||
{
|
||||
- irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_level_irq);
|
||||
+ irq_set_chip_and_handler(irq, &plda_intx_irq_chip, handle_level_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops intx_domain_ops = {
|
||||
- .map = mc_pcie_intx_map,
|
||||
+ .map = plda_pcie_intx_map,
|
||||
};
|
||||
|
||||
static inline u32 reg_to_event(u32 reg, struct event_map field)
|
||||
@@ -609,7 +613,7 @@ static u32 local_events(struct mc_pcie *
|
||||
return val;
|
||||
}
|
||||
|
||||
-static u32 get_events(struct plda_pcie_rp *port)
|
||||
+static u32 mc_get_events(struct plda_pcie_rp *port)
|
||||
{
|
||||
struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
|
||||
u32 events = 0;
|
||||
@@ -638,7 +642,7 @@ static irqreturn_t mc_event_handler(int
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
-static void mc_handle_event(struct irq_desc *desc)
|
||||
+static void plda_handle_event(struct irq_desc *desc)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
|
||||
unsigned long events;
|
||||
@@ -647,7 +651,7 @@ static void mc_handle_event(struct irq_d
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
- events = get_events(port);
|
||||
+ events = mc_get_events(port);
|
||||
|
||||
for_each_set_bit(bit, &events, NUM_EVENTS)
|
||||
generic_handle_domain_irq(port->event_domain, bit);
|
||||
@@ -741,8 +745,8 @@ static struct irq_chip mc_event_irq_chip
|
||||
.irq_unmask = mc_unmask_event_irq,
|
||||
};
|
||||
|
||||
-static int mc_pcie_event_map(struct irq_domain *domain, unsigned int irq,
|
||||
- irq_hw_number_t hwirq)
|
||||
+static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
|
||||
+ irq_hw_number_t hwirq)
|
||||
{
|
||||
irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
@@ -750,8 +754,8 @@ static int mc_pcie_event_map(struct irq_
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct irq_domain_ops event_domain_ops = {
|
||||
- .map = mc_pcie_event_map,
|
||||
+static const struct irq_domain_ops plda_event_domain_ops = {
|
||||
+ .map = plda_pcie_event_map,
|
||||
};
|
||||
|
||||
static inline void mc_pcie_deinit_clk(void *data)
|
||||
@@ -799,7 +803,7 @@ static int mc_pcie_init_clks(struct devi
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int mc_pcie_init_irq_domains(struct plda_pcie_rp *port)
|
||||
+static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
|
||||
{
|
||||
struct device *dev = port->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
@@ -813,7 +817,8 @@ static int mc_pcie_init_irq_domains(stru
|
||||
}
|
||||
|
||||
port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
|
||||
- &event_domain_ops, port);
|
||||
+ &plda_event_domain_ops,
|
||||
+ port);
|
||||
if (!port->event_domain) {
|
||||
dev_err(dev, "failed to get event domain\n");
|
||||
of_node_put(pcie_intc_node);
|
||||
@@ -835,7 +840,7 @@ static int mc_pcie_init_irq_domains(stru
|
||||
of_node_put(pcie_intc_node);
|
||||
raw_spin_lock_init(&port->lock);
|
||||
|
||||
- return mc_allocate_msi_domains(port);
|
||||
+ return plda_allocate_msi_domains(port);
|
||||
}
|
||||
|
||||
static inline void mc_clear_secs(struct mc_pcie *port)
|
||||
@@ -898,14 +903,14 @@ static void mc_disable_interrupts(struct
|
||||
writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
|
||||
}
|
||||
|
||||
-static int mc_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
|
||||
+static int plda_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
int irq;
|
||||
int i, intx_irq, msi_irq, event_irq;
|
||||
int ret;
|
||||
|
||||
- ret = mc_pcie_init_irq_domains(port);
|
||||
+ ret = plda_pcie_init_irq_domains(port);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed creating IRQ domains\n");
|
||||
return ret;
|
||||
@@ -938,7 +943,7 @@ static int mc_init_interrupts(struct pla
|
||||
}
|
||||
|
||||
/* Plug the INTx chained handler */
|
||||
- irq_set_chained_handler_and_data(intx_irq, mc_handle_intx, port);
|
||||
+ irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
|
||||
|
||||
msi_irq = irq_create_mapping(port->event_domain,
|
||||
EVENT_LOCAL_PM_MSI_INT_MSI);
|
||||
@@ -946,10 +951,10 @@ static int mc_init_interrupts(struct pla
|
||||
return -ENXIO;
|
||||
|
||||
/* Plug the MSI chained handler */
|
||||
- irq_set_chained_handler_and_data(msi_irq, mc_handle_msi, port);
|
||||
+ irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
|
||||
|
||||
/* Plug the main event chained handler */
|
||||
- irq_set_chained_handler_and_data(irq, mc_handle_event, port);
|
||||
+ irq_set_chained_handler_and_data(irq, plda_handle_event, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -977,7 +982,7 @@ static int mc_platform_init(struct pci_c
|
||||
return ret;
|
||||
|
||||
/* Address translation is up; safe to enable interrupts */
|
||||
- ret = mc_init_interrupts(pdev, &port->plda);
|
||||
+ ret = plda_init_interrupts(pdev, &port->plda);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -0,0 +1,65 @@
|
||||
From ab04dadb45a4150c9fd55b97fdd7397f4739a629 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:01 +0800
|
||||
Subject: [PATCH 024/116] PCI: microchip: Add num_events field to struct
|
||||
plda_pcie_rp
|
||||
|
||||
The number of events is different across platforms. In order to share
|
||||
interrupt processing code, add a variable that defines the number of
|
||||
events so that it can be set per-platform instead of hardcoding it.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/pci/controller/plda/pcie-microchip-host.c | 8 +++++---
|
||||
drivers/pci/controller/plda/pcie-plda.h | 1 +
|
||||
2 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -653,7 +653,7 @@ static void plda_handle_event(struct irq
|
||||
|
||||
events = mc_get_events(port);
|
||||
|
||||
- for_each_set_bit(bit, &events, NUM_EVENTS)
|
||||
+ for_each_set_bit(bit, &events, port->num_events)
|
||||
generic_handle_domain_irq(port->event_domain, bit);
|
||||
|
||||
chained_irq_exit(chip, desc);
|
||||
@@ -816,7 +816,8 @@ static int plda_pcie_init_irq_domains(st
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
|
||||
+ port->event_domain = irq_domain_add_linear(pcie_intc_node,
|
||||
+ port->num_events,
|
||||
&plda_event_domain_ops,
|
||||
port);
|
||||
if (!port->event_domain) {
|
||||
@@ -920,7 +921,7 @@ static int plda_init_interrupts(struct p
|
||||
if (irq < 0)
|
||||
return -ENODEV;
|
||||
|
||||
- for (i = 0; i < NUM_EVENTS; i++) {
|
||||
+ for (i = 0; i < port->num_events; i++) {
|
||||
event_irq = irq_create_mapping(port->event_domain, i);
|
||||
if (!event_irq) {
|
||||
dev_err(dev, "failed to map hwirq %d\n", i);
|
||||
@@ -1012,6 +1013,7 @@ static int mc_host_probe(struct platform
|
||||
|
||||
bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
|
||||
plda->bridge_addr = bridge_base_addr;
|
||||
+ plda->num_events = NUM_EVENTS;
|
||||
|
||||
/* Allow enabling MSI by disabling MSI-X */
|
||||
val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -124,6 +124,7 @@ struct plda_pcie_rp {
|
||||
raw_spinlock_t lock;
|
||||
struct plda_msi msi;
|
||||
void __iomem *bridge_addr;
|
||||
+ int num_events;
|
||||
};
|
||||
|
||||
void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
|
@ -0,0 +1,114 @@
|
||||
From 9f202f211cc79eefecbb03715c884e54eb95a62c Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:02 +0800
|
||||
Subject: [PATCH 025/116] PCI: microchip: Add request_event_irq() callback
|
||||
function
|
||||
|
||||
As PLDA dts binding doc(Documentation/devicetree/bindings/pci/
|
||||
plda,xpressrich3-axi-common.yaml) showes, PLDA PCIe contains an interrupt
|
||||
controller. Microchip Polarfire PCIe add some PCIe interrupts base on
|
||||
PLDA IP interrupt controller.
|
||||
|
||||
Microchip Polarfire PCIe additional intrerrupts:
|
||||
EVENT_PCIE_L2_EXIT
|
||||
EVENT_PCIE_HOTRST_EXIT
|
||||
EVENT_PCIE_DLUP_EXIT
|
||||
EVENT_SEC_TX_RAM_SEC_ERR
|
||||
EVENT_SEC_RX_RAM_SEC_ERR
|
||||
....
|
||||
|
||||
Both codes of register interrupts and mc_event_handler() contain
|
||||
additional interrupts symbol names, these can not be re-used. So add a
|
||||
new plda_event_handler() functions, which implements PLDA interrupt
|
||||
defalt handler. Add request_event_irq() callback function to
|
||||
compat Microchip Polorfire PCIe additional interrupts.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 31 ++++++++++++++++---
|
||||
drivers/pci/controller/plda/pcie-plda.h | 5 +++
|
||||
2 files changed, 32 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -642,6 +642,11 @@ static irqreturn_t mc_event_handler(int
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static irqreturn_t plda_event_handler(int irq, void *dev_id)
|
||||
+{
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
static void plda_handle_event(struct irq_desc *desc)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
|
||||
@@ -803,6 +808,17 @@ static int mc_pcie_init_clks(struct devi
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int mc_request_event_irq(struct plda_pcie_rp *plda, int event_irq,
|
||||
+ int event)
|
||||
+{
|
||||
+ return devm_request_irq(plda->dev, event_irq, mc_event_handler,
|
||||
+ 0, event_cause[event].sym, plda);
|
||||
+}
|
||||
+
|
||||
+static const struct plda_event mc_event = {
|
||||
+ .request_event_irq = mc_request_event_irq,
|
||||
+};
|
||||
+
|
||||
static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
|
||||
{
|
||||
struct device *dev = port->dev;
|
||||
@@ -904,7 +920,9 @@ static void mc_disable_interrupts(struct
|
||||
writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
|
||||
}
|
||||
|
||||
-static int plda_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
|
||||
+static int plda_init_interrupts(struct platform_device *pdev,
|
||||
+ struct plda_pcie_rp *port,
|
||||
+ const struct plda_event *event)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
int irq;
|
||||
@@ -928,8 +946,13 @@ static int plda_init_interrupts(struct p
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
- ret = devm_request_irq(dev, event_irq, mc_event_handler,
|
||||
- 0, event_cause[i].sym, port);
|
||||
+ if (event->request_event_irq)
|
||||
+ ret = event->request_event_irq(port, event_irq, i);
|
||||
+ else
|
||||
+ ret = devm_request_irq(dev, event_irq,
|
||||
+ plda_event_handler,
|
||||
+ 0, NULL, port);
|
||||
+
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to request IRQ %d\n", event_irq);
|
||||
return ret;
|
||||
@@ -983,7 +1006,7 @@ static int mc_platform_init(struct pci_c
|
||||
return ret;
|
||||
|
||||
/* Address translation is up; safe to enable interrupts */
|
||||
- ret = plda_init_interrupts(pdev, &port->plda);
|
||||
+ ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -127,6 +127,11 @@ struct plda_pcie_rp {
|
||||
int num_events;
|
||||
};
|
||||
|
||||
+struct plda_event {
|
||||
+ int (*request_event_irq)(struct plda_pcie_rp *pcie,
|
||||
+ int event_irq, int event);
|
||||
+};
|
||||
+
|
||||
void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
|
||||
phys_addr_t axi_addr, phys_addr_t pci_addr,
|
||||
size_t size);
|
@ -0,0 +1,56 @@
|
||||
From 3cdc20d9cc029ba9444be111bf4e55fd5331ccbe Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:03 +0800
|
||||
Subject: [PATCH 026/116] PCI: microchip: Add INTx and MSI event num to struct
|
||||
plda_event
|
||||
|
||||
The INTx and MSI interrupt event num is different in Microchip and
|
||||
StarFive platform.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
drivers/pci/controller/plda/pcie-microchip-host.c | 6 ++++--
|
||||
drivers/pci/controller/plda/pcie-plda.h | 2 ++
|
||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -817,6 +817,8 @@ static int mc_request_event_irq(struct p
|
||||
|
||||
static const struct plda_event mc_event = {
|
||||
.request_event_irq = mc_request_event_irq,
|
||||
+ .intx_event = EVENT_LOCAL_PM_MSI_INT_INTX,
|
||||
+ .msi_event = EVENT_LOCAL_PM_MSI_INT_MSI,
|
||||
};
|
||||
|
||||
static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
|
||||
@@ -960,7 +962,7 @@ static int plda_init_interrupts(struct p
|
||||
}
|
||||
|
||||
intx_irq = irq_create_mapping(port->event_domain,
|
||||
- EVENT_LOCAL_PM_MSI_INT_INTX);
|
||||
+ event->intx_event);
|
||||
if (!intx_irq) {
|
||||
dev_err(dev, "failed to map INTx interrupt\n");
|
||||
return -ENXIO;
|
||||
@@ -970,7 +972,7 @@ static int plda_init_interrupts(struct p
|
||||
irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
|
||||
|
||||
msi_irq = irq_create_mapping(port->event_domain,
|
||||
- EVENT_LOCAL_PM_MSI_INT_MSI);
|
||||
+ event->msi_event);
|
||||
if (!msi_irq)
|
||||
return -ENXIO;
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -130,6 +130,8 @@ struct plda_pcie_rp {
|
||||
struct plda_event {
|
||||
int (*request_event_irq)(struct plda_pcie_rp *pcie,
|
||||
int event_irq, int event);
|
||||
+ int intx_event;
|
||||
+ int msi_event;
|
||||
};
|
||||
|
||||
void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
|
@ -0,0 +1,167 @@
|
||||
From b4a38ef87661f21fe2fb3e085ae98f25f78aaf99 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:04 +0800
|
||||
Subject: [PATCH 027/116] PCI: microchip: Add get_events() callback and add
|
||||
PLDA get_event()
|
||||
|
||||
As PLDA dts binding doc(Documentation/devicetree/bindings/pci/
|
||||
plda,xpressrich3-axi-common.yaml) showes, PLDA PCIe contains an interrupt
|
||||
controller.
|
||||
|
||||
PolarFire implements its own PCIe interrupts, additional to the regular
|
||||
PCIe interrupts, due to lack of an MSI controller, so the interrupt to
|
||||
event number mapping is different to the PLDA regular interrupts,
|
||||
necessitating a custom get_events() implementation.
|
||||
|
||||
Microchip Polarfire PCIe additional intrerrupts:
|
||||
EVENT_PCIE_L2_EXIT
|
||||
EVENT_PCIE_HOTRST_EXIT
|
||||
EVENT_PCIE_DLUP_EXIT
|
||||
EVENT_SEC_TX_RAM_SEC_ERR
|
||||
EVENT_SEC_RX_RAM_SEC_ERR
|
||||
....
|
||||
|
||||
plda_get_events() adds interrupt register to PLDA local event num mapping
|
||||
codes. All The PLDA interrupts can be seen in new added graph.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 35 ++++++++++++++++++-
|
||||
drivers/pci/controller/plda/pcie-plda.h | 32 +++++++++++++++++
|
||||
2 files changed, 66 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -626,6 +626,26 @@ static u32 mc_get_events(struct plda_pci
|
||||
return events;
|
||||
}
|
||||
|
||||
+static u32 plda_get_events(struct plda_pcie_rp *port)
|
||||
+{
|
||||
+ u32 events, val, origin;
|
||||
+
|
||||
+ origin = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL);
|
||||
+
|
||||
+ /* MSI event and sys events */
|
||||
+ val = (origin & SYS_AND_MSI_MASK) >> PM_MSI_INT_MSI_SHIFT;
|
||||
+ events = val << (PM_MSI_INT_MSI_SHIFT - PCI_NUM_INTX + 1);
|
||||
+
|
||||
+ /* INTx events */
|
||||
+ if (origin & PM_MSI_INT_INTX_MASK)
|
||||
+ events |= BIT(PM_MSI_INT_INTX_SHIFT);
|
||||
+
|
||||
+ /* remains are same with register */
|
||||
+ events |= origin & GENMASK(P_ATR_EVT_DOORBELL_SHIFT, 0);
|
||||
+
|
||||
+ return events;
|
||||
+}
|
||||
+
|
||||
static irqreturn_t mc_event_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct plda_pcie_rp *port = dev_id;
|
||||
@@ -656,7 +676,7 @@ static void plda_handle_event(struct irq
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
- events = mc_get_events(port);
|
||||
+ events = port->event_ops->get_events(port);
|
||||
|
||||
for_each_set_bit(bit, &events, port->num_events)
|
||||
generic_handle_domain_irq(port->event_domain, bit);
|
||||
@@ -750,6 +770,10 @@ static struct irq_chip mc_event_irq_chip
|
||||
.irq_unmask = mc_unmask_event_irq,
|
||||
};
|
||||
|
||||
+static const struct plda_event_ops plda_event_ops = {
|
||||
+ .get_events = plda_get_events,
|
||||
+};
|
||||
+
|
||||
static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
@@ -815,6 +839,10 @@ static int mc_request_event_irq(struct p
|
||||
0, event_cause[event].sym, plda);
|
||||
}
|
||||
|
||||
+static const struct plda_event_ops mc_event_ops = {
|
||||
+ .get_events = mc_get_events,
|
||||
+};
|
||||
+
|
||||
static const struct plda_event mc_event = {
|
||||
.request_event_irq = mc_request_event_irq,
|
||||
.intx_event = EVENT_LOCAL_PM_MSI_INT_INTX,
|
||||
@@ -931,6 +959,9 @@ static int plda_init_interrupts(struct p
|
||||
int i, intx_irq, msi_irq, event_irq;
|
||||
int ret;
|
||||
|
||||
+ if (!port->event_ops)
|
||||
+ port->event_ops = &plda_event_ops;
|
||||
+
|
||||
ret = plda_pcie_init_irq_domains(port);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed creating IRQ domains\n");
|
||||
@@ -1007,6 +1038,8 @@ static int mc_platform_init(struct pci_c
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ port->plda.event_ops = &mc_event_ops;
|
||||
+
|
||||
/* Address translation is up; safe to enable interrupts */
|
||||
ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
|
||||
if (ret)
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -58,6 +58,7 @@
|
||||
#define PM_MSI_INT_EVENTS_SHIFT 30
|
||||
#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
|
||||
#define PM_MSI_INT_SYS_ERR_SHIFT 31
|
||||
+#define SYS_AND_MSI_MASK GENMASK(31, 28)
|
||||
#define NUM_LOCAL_EVENTS 15
|
||||
#define ISTATUS_LOCAL 0x184
|
||||
#define IMASK_HOST 0x188
|
||||
@@ -108,6 +109,36 @@ enum plda_int_event {
|
||||
|
||||
#define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
|
||||
|
||||
+/*
|
||||
+ * PLDA interrupt register
|
||||
+ *
|
||||
+ * 31 27 23 15 7 0
|
||||
+ * +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+
|
||||
+ * |12|11|10|9| intx |7|6|5|4|3|2|1|0| DMA error | DMA end |
|
||||
+ * +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+
|
||||
+ * bit 0-7 DMA interrupt end : reserved for vendor implement
|
||||
+ * bit 8-15 DMA error : reserved for vendor implement
|
||||
+ * 0: AXI post error (PLDA_AXI_POST_ERR)
|
||||
+ * 1: AXI fetch error (PLDA_AXI_FETCH_ERR)
|
||||
+ * 2: AXI discard error (PLDA_AXI_DISCARD_ERR)
|
||||
+ * 3: AXI doorbell (PLDA_PCIE_DOORBELL)
|
||||
+ * 4: PCIe post error (PLDA_PCIE_POST_ERR)
|
||||
+ * 5: PCIe fetch error (PLDA_PCIE_FETCH_ERR)
|
||||
+ * 6: PCIe discard error (PLDA_PCIE_DISCARD_ERR)
|
||||
+ * 7: PCIe doorbell (PLDA_PCIE_DOORBELL)
|
||||
+ * 8: 4 INTx interruts (PLDA_INTX)
|
||||
+ * 9: MSI interrupt (PLDA_MSI)
|
||||
+ * 10: AER event (PLDA_AER_EVENT)
|
||||
+ * 11: PM/LTR/Hotplug (PLDA_MISC_EVENTS)
|
||||
+ * 12: System error (PLDA_SYS_ERR)
|
||||
+ */
|
||||
+
|
||||
+struct plda_pcie_rp;
|
||||
+
|
||||
+struct plda_event_ops {
|
||||
+ u32 (*get_events)(struct plda_pcie_rp *pcie);
|
||||
+};
|
||||
+
|
||||
struct plda_msi {
|
||||
struct mutex lock; /* Protect used bitmap */
|
||||
struct irq_domain *msi_domain;
|
||||
@@ -123,6 +154,7 @@ struct plda_pcie_rp {
|
||||
struct irq_domain *event_domain;
|
||||
raw_spinlock_t lock;
|
||||
struct plda_msi msi;
|
||||
+ const struct plda_event_ops *event_ops;
|
||||
void __iomem *bridge_addr;
|
||||
int num_events;
|
||||
};
|
@ -0,0 +1,144 @@
|
||||
From 229ea8e7b674eb5c9bc4f70d43df1bd02a79862a Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:05 +0800
|
||||
Subject: [PATCH 028/116] PCI: microchip: Add event irqchip field to host port
|
||||
and add PLDA irqchip
|
||||
|
||||
As PLDA dts binding doc(Documentation/devicetree/bindings/pci/
|
||||
plda,xpressrich3-axi-common.yaml) showes, PLDA PCIe contains an interrupt
|
||||
controller.
|
||||
|
||||
Microchip PolarFire PCIE event IRQs includes PLDA interrupts and
|
||||
Polarfire their own interrupts. The interrupt irqchip ops includes
|
||||
ack/mask/unmask interrupt ops, which will write correct registers.
|
||||
Microchip Polarfire PCIe additional interrupts require to write Polarfire
|
||||
SoC self-defined registers. So Microchip PCIe event irqchip ops can not
|
||||
be re-used.
|
||||
|
||||
To support PLDA its own event IRQ process, implements PLDA irqchip ops and
|
||||
add event irqchip field to struct pcie_plda_rp.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
.../pci/controller/plda/pcie-microchip-host.c | 66 ++++++++++++++++++-
|
||||
drivers/pci/controller/plda/pcie-plda.h | 5 +-
|
||||
2 files changed, 69 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -770,6 +770,64 @@ static struct irq_chip mc_event_irq_chip
|
||||
.irq_unmask = mc_unmask_event_irq,
|
||||
};
|
||||
|
||||
+static u32 plda_hwirq_to_mask(int hwirq)
|
||||
+{
|
||||
+ u32 mask;
|
||||
+
|
||||
+ /* hwirq 23 - 0 are the same with register */
|
||||
+ if (hwirq < EVENT_PM_MSI_INT_INTX)
|
||||
+ mask = BIT(hwirq);
|
||||
+ else if (hwirq == EVENT_PM_MSI_INT_INTX)
|
||||
+ mask = PM_MSI_INT_INTX_MASK;
|
||||
+ else
|
||||
+ mask = BIT(hwirq + PCI_NUM_INTX - 1);
|
||||
+
|
||||
+ return mask;
|
||||
+}
|
||||
+
|
||||
+static void plda_ack_event_irq(struct irq_data *data)
|
||||
+{
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
+
|
||||
+ writel_relaxed(plda_hwirq_to_mask(data->hwirq),
|
||||
+ port->bridge_addr + ISTATUS_LOCAL);
|
||||
+}
|
||||
+
|
||||
+static void plda_mask_event_irq(struct irq_data *data)
|
||||
+{
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
+ u32 mask, val;
|
||||
+
|
||||
+ mask = plda_hwirq_to_mask(data->hwirq);
|
||||
+
|
||||
+ raw_spin_lock(&port->lock);
|
||||
+ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
|
||||
+ val &= ~mask;
|
||||
+ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
|
||||
+ raw_spin_unlock(&port->lock);
|
||||
+}
|
||||
+
|
||||
+static void plda_unmask_event_irq(struct irq_data *data)
|
||||
+{
|
||||
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
|
||||
+ u32 mask, val;
|
||||
+
|
||||
+ mask = plda_hwirq_to_mask(data->hwirq);
|
||||
+
|
||||
+ raw_spin_lock(&port->lock);
|
||||
+ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
|
||||
+ val |= mask;
|
||||
+ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
|
||||
+ raw_spin_unlock(&port->lock);
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip plda_event_irq_chip = {
|
||||
+ .name = "PLDA PCIe EVENT",
|
||||
+ .irq_ack = plda_ack_event_irq,
|
||||
+ .irq_mask = plda_mask_event_irq,
|
||||
+ .irq_unmask = plda_unmask_event_irq,
|
||||
+};
|
||||
+
|
||||
static const struct plda_event_ops plda_event_ops = {
|
||||
.get_events = plda_get_events,
|
||||
};
|
||||
@@ -777,7 +835,9 @@ static const struct plda_event_ops plda_
|
||||
static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
- irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
|
||||
+ struct plda_pcie_rp *port = (void *)domain->host_data;
|
||||
+
|
||||
+ irq_set_chip_and_handler(irq, port->event_irq_chip, handle_level_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
|
||||
return 0;
|
||||
@@ -962,6 +1022,9 @@ static int plda_init_interrupts(struct p
|
||||
if (!port->event_ops)
|
||||
port->event_ops = &plda_event_ops;
|
||||
|
||||
+ if (!port->event_irq_chip)
|
||||
+ port->event_irq_chip = &plda_event_irq_chip;
|
||||
+
|
||||
ret = plda_pcie_init_irq_domains(port);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed creating IRQ domains\n");
|
||||
@@ -1039,6 +1102,7 @@ static int mc_platform_init(struct pci_c
|
||||
return ret;
|
||||
|
||||
port->plda.event_ops = &mc_event_ops;
|
||||
+ port->plda.event_irq_chip = &mc_event_irq_chip;
|
||||
|
||||
/* Address translation is up; safe to enable interrupts */
|
||||
ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -107,7 +107,9 @@ enum plda_int_event {
|
||||
|
||||
#define PLDA_NUM_DMA_EVENTS 16
|
||||
|
||||
-#define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
|
||||
+#define EVENT_PM_MSI_INT_INTX (PLDA_NUM_DMA_EVENTS + PLDA_INTX)
|
||||
+#define EVENT_PM_MSI_INT_MSI (PLDA_NUM_DMA_EVENTS + PLDA_MSI)
|
||||
+#define PLDA_MAX_EVENT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
|
||||
|
||||
/*
|
||||
* PLDA interrupt register
|
||||
@@ -155,6 +157,7 @@ struct plda_pcie_rp {
|
||||
raw_spinlock_t lock;
|
||||
struct plda_msi msi;
|
||||
const struct plda_event_ops *event_ops;
|
||||
+ const struct irq_chip *event_irq_chip;
|
||||
void __iomem *bridge_addr;
|
||||
int num_events;
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
||||
From 142fc300fd7511a217783dcfa342031d8ad70188 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:07 +0800
|
||||
Subject: [PATCH 030/116] pci: plda: Add event bitmap field to struct
|
||||
plda_pcie_rp
|
||||
|
||||
For PLDA DMA interrupts are not all implemented. The non-implemented
|
||||
interrupts should be masked. So add a bitmap field to mask the non-
|
||||
implemented interrupts.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
---
|
||||
drivers/pci/controller/plda/pcie-microchip-host.c | 1 +
|
||||
drivers/pci/controller/plda/pcie-plda-host.c | 6 ++++--
|
||||
drivers/pci/controller/plda/pcie-plda.h | 1 +
|
||||
3 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
@@ -636,6 +636,7 @@ static int mc_platform_init(struct pci_c
|
||||
|
||||
port->plda.event_ops = &mc_event_ops;
|
||||
port->plda.event_irq_chip = &mc_event_irq_chip;
|
||||
+ port->plda.events_bitmap = GENMASK(NUM_EVENTS - 1, 0);
|
||||
|
||||
/* Address translation is up; safe to enable interrupts */
|
||||
ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
|
||||
--- a/drivers/pci/controller/plda/pcie-plda-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda-host.c
|
||||
@@ -290,6 +290,7 @@ static void plda_handle_event(struct irq
|
||||
|
||||
events = port->event_ops->get_events(port);
|
||||
|
||||
+ events &= port->events_bitmap;
|
||||
for_each_set_bit(bit, &events, port->num_events)
|
||||
generic_handle_domain_irq(port->event_domain, bit);
|
||||
|
||||
@@ -420,8 +421,9 @@ int plda_init_interrupts(struct platform
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
int irq;
|
||||
- int i, intx_irq, msi_irq, event_irq;
|
||||
+ int intx_irq, msi_irq, event_irq;
|
||||
int ret;
|
||||
+ u32 i;
|
||||
|
||||
if (!port->event_ops)
|
||||
port->event_ops = &plda_event_ops;
|
||||
@@ -439,7 +441,7 @@ int plda_init_interrupts(struct platform
|
||||
if (irq < 0)
|
||||
return -ENODEV;
|
||||
|
||||
- for (i = 0; i < port->num_events; i++) {
|
||||
+ for_each_set_bit(i, &port->events_bitmap, port->num_events) {
|
||||
event_irq = irq_create_mapping(port->event_domain, i);
|
||||
if (!event_irq) {
|
||||
dev_err(dev, "failed to map hwirq %d\n", i);
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -159,6 +159,7 @@ struct plda_pcie_rp {
|
||||
const struct plda_event_ops *event_ops;
|
||||
const struct irq_chip *event_irq_chip;
|
||||
void __iomem *bridge_addr;
|
||||
+ unsigned long events_bitmap;
|
||||
int num_events;
|
||||
};
|
||||
|
@ -0,0 +1,256 @@
|
||||
From 3b9991438094dc472dacb4555603bdc379653411 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:08 +0800
|
||||
Subject: [PATCH 031/116] PCI: plda: Add host init/deinit and map bus functions
|
||||
|
||||
Add PLDA host plda_pcie_host_init()/plda_pcie_host_deinit() and map bus
|
||||
function. So vendor can use it to init PLDA PCIe host core.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
|
||||
---
|
||||
drivers/pci/controller/plda/pcie-plda-host.c | 131 +++++++++++++++++--
|
||||
drivers/pci/controller/plda/pcie-plda.h | 22 ++++
|
||||
2 files changed, 139 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/plda/pcie-plda-host.c
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda-host.c
|
||||
@@ -3,6 +3,7 @@
|
||||
* PLDA PCIe XpressRich host controller driver
|
||||
*
|
||||
* Copyright (C) 2023 Microchip Co. Ltd
|
||||
+ * StarFive Co. Ltd
|
||||
*
|
||||
* Author: Daire McNamara <daire.mcnamara@microchip.com>
|
||||
*/
|
||||
@@ -15,6 +16,15 @@
|
||||
|
||||
#include "pcie-plda.h"
|
||||
|
||||
+void __iomem *plda_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int where)
|
||||
+{
|
||||
+ struct plda_pcie_rp *pcie = bus->sysdata;
|
||||
+
|
||||
+ return pcie->config_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(plda_pcie_map_bus);
|
||||
+
|
||||
static void plda_handle_msi(struct irq_desc *desc)
|
||||
{
|
||||
struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
|
||||
@@ -420,9 +430,7 @@ int plda_init_interrupts(struct platform
|
||||
const struct plda_event *event)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
- int irq;
|
||||
- int intx_irq, msi_irq, event_irq;
|
||||
- int ret;
|
||||
+ int event_irq, ret;
|
||||
u32 i;
|
||||
|
||||
if (!port->event_ops)
|
||||
@@ -437,8 +445,8 @@ int plda_init_interrupts(struct platform
|
||||
return ret;
|
||||
}
|
||||
|
||||
- irq = platform_get_irq(pdev, 0);
|
||||
- if (irq < 0)
|
||||
+ port->irq = platform_get_irq(pdev, 0);
|
||||
+ if (port->irq < 0)
|
||||
return -ENODEV;
|
||||
|
||||
for_each_set_bit(i, &port->events_bitmap, port->num_events) {
|
||||
@@ -461,26 +469,26 @@ int plda_init_interrupts(struct platform
|
||||
}
|
||||
}
|
||||
|
||||
- intx_irq = irq_create_mapping(port->event_domain,
|
||||
- event->intx_event);
|
||||
- if (!intx_irq) {
|
||||
+ port->intx_irq = irq_create_mapping(port->event_domain,
|
||||
+ event->intx_event);
|
||||
+ if (!port->intx_irq) {
|
||||
dev_err(dev, "failed to map INTx interrupt\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Plug the INTx chained handler */
|
||||
- irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
|
||||
+ irq_set_chained_handler_and_data(port->intx_irq, plda_handle_intx, port);
|
||||
|
||||
- msi_irq = irq_create_mapping(port->event_domain,
|
||||
- event->msi_event);
|
||||
- if (!msi_irq)
|
||||
+ port->msi_irq = irq_create_mapping(port->event_domain,
|
||||
+ event->msi_event);
|
||||
+ if (!port->msi_irq)
|
||||
return -ENXIO;
|
||||
|
||||
/* Plug the MSI chained handler */
|
||||
- irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
|
||||
+ irq_set_chained_handler_and_data(port->msi_irq, plda_handle_msi, port);
|
||||
|
||||
/* Plug the main event chained handler */
|
||||
- irq_set_chained_handler_and_data(irq, plda_handle_event, port);
|
||||
+ irq_set_chained_handler_and_data(port->irq, plda_handle_event, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -546,3 +554,98 @@ int plda_pcie_setup_iomems(struct pci_ho
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);
|
||||
+
|
||||
+static void plda_pcie_irq_domain_deinit(struct plda_pcie_rp *pcie)
|
||||
+{
|
||||
+ irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
|
||||
+ irq_set_chained_handler_and_data(pcie->msi_irq, NULL, NULL);
|
||||
+ irq_set_chained_handler_and_data(pcie->intx_irq, NULL, NULL);
|
||||
+
|
||||
+ irq_domain_remove(pcie->msi.msi_domain);
|
||||
+ irq_domain_remove(pcie->msi.dev_domain);
|
||||
+
|
||||
+ irq_domain_remove(pcie->intx_domain);
|
||||
+ irq_domain_remove(pcie->event_domain);
|
||||
+}
|
||||
+
|
||||
+int plda_pcie_host_init(struct plda_pcie_rp *port, struct pci_ops *ops,
|
||||
+ const struct plda_event *plda_event)
|
||||
+{
|
||||
+ struct device *dev = port->dev;
|
||||
+ struct pci_host_bridge *bridge;
|
||||
+ struct platform_device *pdev = to_platform_device(dev);
|
||||
+ struct resource *cfg_res;
|
||||
+ int ret;
|
||||
+
|
||||
+ pdev = to_platform_device(dev);
|
||||
+
|
||||
+ port->bridge_addr =
|
||||
+ devm_platform_ioremap_resource_byname(pdev, "apb");
|
||||
+
|
||||
+ if (IS_ERR(port->bridge_addr))
|
||||
+ return dev_err_probe(dev, PTR_ERR(port->bridge_addr),
|
||||
+ "failed to map reg memory\n");
|
||||
+
|
||||
+ cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
|
||||
+ if (!cfg_res)
|
||||
+ return dev_err_probe(dev, -ENODEV,
|
||||
+ "failed to get config memory\n");
|
||||
+
|
||||
+ port->config_base = devm_ioremap_resource(dev, cfg_res);
|
||||
+ if (IS_ERR(port->config_base))
|
||||
+ return dev_err_probe(dev, PTR_ERR(port->config_base),
|
||||
+ "failed to map config memory\n");
|
||||
+
|
||||
+ bridge = devm_pci_alloc_host_bridge(dev, 0);
|
||||
+ if (!bridge)
|
||||
+ return dev_err_probe(dev, -ENOMEM,
|
||||
+ "failed to alloc bridge\n");
|
||||
+
|
||||
+ if (port->host_ops && port->host_ops->host_init) {
|
||||
+ ret = port->host_ops->host_init(port);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ port->bridge = bridge;
|
||||
+ plda_pcie_setup_window(port->bridge_addr, 0, cfg_res->start, 0,
|
||||
+ resource_size(cfg_res));
|
||||
+ plda_pcie_setup_iomems(bridge, port);
|
||||
+ plda_set_default_msi(&port->msi);
|
||||
+ ret = plda_init_interrupts(pdev, port, plda_event);
|
||||
+ if (ret)
|
||||
+ goto err_host;
|
||||
+
|
||||
+ /* Set default bus ops */
|
||||
+ bridge->ops = ops;
|
||||
+ bridge->sysdata = port;
|
||||
+
|
||||
+ ret = pci_host_probe(bridge);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err_probe(dev, ret, "failed to probe pci host\n");
|
||||
+ goto err_probe;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+err_probe:
|
||||
+ plda_pcie_irq_domain_deinit(port);
|
||||
+err_host:
|
||||
+ if (port->host_ops && port->host_ops->host_deinit)
|
||||
+ port->host_ops->host_deinit(port);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(plda_pcie_host_init);
|
||||
+
|
||||
+void plda_pcie_host_deinit(struct plda_pcie_rp *port)
|
||||
+{
|
||||
+ pci_stop_root_bus(port->bridge->bus);
|
||||
+ pci_remove_root_bus(port->bridge->bus);
|
||||
+
|
||||
+ plda_pcie_irq_domain_deinit(port);
|
||||
+
|
||||
+ if (port->host_ops && port->host_ops->host_deinit)
|
||||
+ port->host_ops->host_deinit(port);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(plda_pcie_host_deinit);
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -141,6 +141,11 @@ struct plda_event_ops {
|
||||
u32 (*get_events)(struct plda_pcie_rp *pcie);
|
||||
};
|
||||
|
||||
+struct plda_pcie_host_ops {
|
||||
+ int (*host_init)(struct plda_pcie_rp *pcie);
|
||||
+ void (*host_deinit)(struct plda_pcie_rp *pcie);
|
||||
+};
|
||||
+
|
||||
struct plda_msi {
|
||||
struct mutex lock; /* Protect used bitmap */
|
||||
struct irq_domain *msi_domain;
|
||||
@@ -152,14 +157,20 @@ struct plda_msi {
|
||||
|
||||
struct plda_pcie_rp {
|
||||
struct device *dev;
|
||||
+ struct pci_host_bridge *bridge;
|
||||
struct irq_domain *intx_domain;
|
||||
struct irq_domain *event_domain;
|
||||
raw_spinlock_t lock;
|
||||
struct plda_msi msi;
|
||||
const struct plda_event_ops *event_ops;
|
||||
const struct irq_chip *event_irq_chip;
|
||||
+ const struct plda_pcie_host_ops *host_ops;
|
||||
void __iomem *bridge_addr;
|
||||
+ void __iomem *config_base;
|
||||
unsigned long events_bitmap;
|
||||
+ int irq;
|
||||
+ int msi_irq;
|
||||
+ int intx_irq;
|
||||
int num_events;
|
||||
};
|
||||
|
||||
@@ -170,6 +181,8 @@ struct plda_event {
|
||||
int msi_event;
|
||||
};
|
||||
|
||||
+void __iomem *plda_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int where);
|
||||
int plda_init_interrupts(struct platform_device *pdev,
|
||||
struct plda_pcie_rp *port,
|
||||
const struct plda_event *event);
|
||||
@@ -178,4 +191,13 @@ void plda_pcie_setup_window(void __iomem
|
||||
size_t size);
|
||||
int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
|
||||
struct plda_pcie_rp *port);
|
||||
+int plda_pcie_host_init(struct plda_pcie_rp *port, struct pci_ops *ops,
|
||||
+ const struct plda_event *plda_event);
|
||||
+void plda_pcie_host_deinit(struct plda_pcie_rp *pcie);
|
||||
+
|
||||
+static inline void plda_set_default_msi(struct plda_msi *msi)
|
||||
+{
|
||||
+ msi->vector_phy = IMSI_ADDR;
|
||||
+ msi->num_vectors = PLDA_MAX_NUM_MSI_IRQS;
|
||||
+}
|
||||
#endif
|
@ -0,0 +1,140 @@
|
||||
From bc3f8207d9f0af3cb96a7eae232074a644a175f6 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:09 +0800
|
||||
Subject: [PATCH 032/116] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
|
||||
|
||||
Add StarFive JH7110 SoC PCIe controller dt-bindings. JH7110 using PLDA
|
||||
XpressRICH PCIe host controller IP.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
---
|
||||
.../bindings/pci/starfive,jh7110-pcie.yaml | 120 ++++++++++++++++++
|
||||
1 file changed, 120 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
|
||||
@@ -0,0 +1,120 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 PCIe host controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - Kevin Xie <kevin.xie@starfivetech.com>
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: plda,xpressrich3-axi-common.yaml#
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-pcie
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: NOC bus clock
|
||||
+ - description: Transport layer clock
|
||||
+ - description: AXI MST0 clock
|
||||
+ - description: APB clock
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: noc
|
||||
+ - const: tl
|
||||
+ - const: axi_mst0
|
||||
+ - const: apb
|
||||
+
|
||||
+ resets:
|
||||
+ items:
|
||||
+ - description: AXI MST0 reset
|
||||
+ - description: AXI SLAVE0 reset
|
||||
+ - description: AXI SLAVE reset
|
||||
+ - description: PCIE BRIDGE reset
|
||||
+ - description: PCIE CORE reset
|
||||
+ - description: PCIE APB reset
|
||||
+
|
||||
+ reset-names:
|
||||
+ items:
|
||||
+ - const: mst0
|
||||
+ - const: slv0
|
||||
+ - const: slv
|
||||
+ - const: brg
|
||||
+ - const: core
|
||||
+ - const: apb
|
||||
+
|
||||
+ starfive,stg-syscon:
|
||||
+ $ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
+ description:
|
||||
+ The phandle to System Register Controller syscon node.
|
||||
+
|
||||
+ perst-gpios:
|
||||
+ description: GPIO controlled connection to PERST# signal
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ phys:
|
||||
+ description:
|
||||
+ Specified PHY is attached to PCIe controller.
|
||||
+ maxItems: 1
|
||||
+
|
||||
+required:
|
||||
+ - clocks
|
||||
+ - resets
|
||||
+ - starfive,stg-syscon
|
||||
+
|
||||
+unevaluatedProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/gpio/gpio.h>
|
||||
+ soc {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ pcie@940000000 {
|
||||
+ compatible = "starfive,jh7110-pcie";
|
||||
+ reg = <0x9 0x40000000 0x0 0x10000000>,
|
||||
+ <0x0 0x2b000000 0x0 0x1000000>;
|
||||
+ reg-names = "cfg", "apb";
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ device_type = "pci";
|
||||
+ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
|
||||
+ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
|
||||
+ starfive,stg-syscon = <&stg_syscon>;
|
||||
+ bus-range = <0x0 0xff>;
|
||||
+ interrupt-parent = <&plic>;
|
||||
+ interrupts = <56>;
|
||||
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
|
||||
+ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
|
||||
+ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
|
||||
+ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
|
||||
+ msi-controller;
|
||||
+ clocks = <&syscrg 86>,
|
||||
+ <&stgcrg 10>,
|
||||
+ <&stgcrg 8>,
|
||||
+ <&stgcrg 9>;
|
||||
+ clock-names = "noc", "tl", "axi_mst0", "apb";
|
||||
+ resets = <&stgcrg 11>,
|
||||
+ <&stgcrg 12>,
|
||||
+ <&stgcrg 13>,
|
||||
+ <&stgcrg 14>,
|
||||
+ <&stgcrg 15>,
|
||||
+ <&stgcrg 16>;
|
||||
+ perst-gpios = <&gpios 26 GPIO_ACTIVE_LOW>;
|
||||
+ phys = <&pciephy0>;
|
||||
+
|
||||
+ pcie_intc0: interrupt-controller {
|
||||
+ #address-cells = <0>;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ interrupt-controller;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
@ -0,0 +1,55 @@
|
||||
From abb20b7b8f5e3a7f36dbd6264e6d346275434154 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Xie <kevin.xie@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:10 +0800
|
||||
Subject: [PATCH 033/116] PCI: Add PCIE_RESET_CONFIG_DEVICE_WAIT_MS waiting
|
||||
time value
|
||||
|
||||
Add the PCIE_RESET_CONFIG_DEVICE_WAIT_MS macro to define the minimum
|
||||
waiting time between exit from a conventional reset and sending the
|
||||
first configuration request to the device.
|
||||
|
||||
As described in PCI base specification r6.0, section 6.6.1 <Conventional
|
||||
Reset>, there are two different use cases of the value:
|
||||
|
||||
- "With a Downstream Port that does not support Link speeds greater
|
||||
than 5.0 GT/s, software must wait a minimum of 100 ms following exit
|
||||
from a Conventional Reset before sending a Configuration Request to
|
||||
the device immediately below that Port."
|
||||
|
||||
- "With a Downstream Port that supports Link speeds greater than
|
||||
5.0 GT/s, software must wait a minimum of 100 ms after Link training
|
||||
completes before sending a Configuration Request to the device
|
||||
immediately below that Port."
|
||||
|
||||
Signed-off-by: Kevin Xie <kevin.xie@starfivetech.com>
|
||||
Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
|
||||
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
---
|
||||
drivers/pci/pci.h | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
--- a/drivers/pci/pci.h
|
||||
+++ b/drivers/pci/pci.h
|
||||
@@ -19,6 +19,22 @@
|
||||
*/
|
||||
#define PCIE_PME_TO_L2_TIMEOUT_US 10000
|
||||
|
||||
+/*
|
||||
+ * As described in PCI base specification r6.0, section 6.6.1 <Conventional
|
||||
+ * Reset>, there are two different use cases of the value:
|
||||
+ *
|
||||
+ * - "With a Downstream Port that does not support Link speeds greater
|
||||
+ * than 5.0 GT/s, software must wait a minimum of 100 ms following exit
|
||||
+ * from a Conventional Reset before sending a Configuration Request to
|
||||
+ * the device immediately below that Port."
|
||||
+ *
|
||||
+ * - "With a Downstream Port that supports Link speeds greater than
|
||||
+ * 5.0 GT/s, software must wait a minimum of 100 ms after Link training
|
||||
+ * completes before sending a Configuration Request to the device
|
||||
+ * immediately below that Port."
|
||||
+ */
|
||||
+#define PCIE_RESET_CONFIG_DEVICE_WAIT_MS 100
|
||||
+
|
||||
extern const unsigned char pcie_link_speed[];
|
||||
extern bool pci_early_dump;
|
||||
|
@ -0,0 +1,623 @@
|
||||
From 323aedef34315b758dc30ba23e2cabca259bb4b2 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Mon, 8 Jan 2024 19:06:11 +0800
|
||||
Subject: [PATCH 034/116] PCI: starfive: Add JH7110 PCIe controller
|
||||
|
||||
Add StarFive JH7110 SoC PCIe controller platform driver codes, JH7110
|
||||
with PLDA host PCIe core.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Co-developed-by: Kevin Xie <kevin.xie@starfivetech.com>
|
||||
Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
|
||||
---
|
||||
drivers/pci/controller/plda/Kconfig | 12 +
|
||||
drivers/pci/controller/plda/Makefile | 1 +
|
||||
drivers/pci/controller/plda/pcie-plda.h | 71 ++-
|
||||
drivers/pci/controller/plda/pcie-starfive.c | 473 ++++++++++++++++++++
|
||||
4 files changed, 556 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/pci/controller/plda/pcie-starfive.c
|
||||
|
||||
--- a/drivers/pci/controller/plda/Kconfig
|
||||
+++ b/drivers/pci/controller/plda/Kconfig
|
||||
@@ -15,4 +15,16 @@ config PCIE_MICROCHIP_HOST
|
||||
Say Y here if you want kernel to support the Microchip AXI PCIe
|
||||
Host Bridge driver.
|
||||
|
||||
+config PCIE_STARFIVE_HOST
|
||||
+ tristate "StarFive PCIe host controller"
|
||||
+ depends on PCI_MSI && OF
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ select PCIE_PLDA_HOST
|
||||
+ help
|
||||
+ Say Y here if you want to support the StarFive PCIe controller in
|
||||
+ host mode. StarFive PCIe controller uses PLDA PCIe core.
|
||||
+
|
||||
+ If you choose to build this driver as module it will be dynamically
|
||||
+ linked and module will be called pcie-starfive.ko.
|
||||
+
|
||||
endmenu
|
||||
--- a/drivers/pci/controller/plda/Makefile
|
||||
+++ b/drivers/pci/controller/plda/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_PCIE_PLDA_HOST) += pcie-plda-host.o
|
||||
obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
|
||||
+obj-$(CONFIG_PCIE_STARFIVE_HOST) += pcie-starfive.o
|
||||
--- a/drivers/pci/controller/plda/pcie-plda.h
|
||||
+++ b/drivers/pci/controller/plda/pcie-plda.h
|
||||
@@ -10,10 +10,20 @@
|
||||
#define PLDA_MAX_NUM_MSI_IRQS 32
|
||||
|
||||
/* PCIe Bridge Phy Regs */
|
||||
+#define GEN_SETTINGS 0x80
|
||||
+#define RP_ENABLE 1
|
||||
+#define PCIE_PCI_IDS_DW1 0x9c
|
||||
+#define IDS_CLASS_CODE_SHIFT 16
|
||||
+#define REVISION_ID_MASK GENMASK(7, 0)
|
||||
+#define CLASS_CODE_ID_MASK GENMASK(31, 8)
|
||||
#define PCIE_PCI_IRQ_DW0 0xa8
|
||||
#define MSIX_CAP_MASK BIT(31)
|
||||
#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
|
||||
#define NUM_MSI_MSGS_SHIFT 4
|
||||
+#define PCI_MISC 0xb4
|
||||
+#define PHY_FUNCTION_DIS BIT(15)
|
||||
+#define PCIE_WINROM 0xfc
|
||||
+#define PREF_MEM_WIN_64_SUPPORT BIT(3)
|
||||
|
||||
#define IMASK_LOCAL 0x180
|
||||
#define DMA_END_ENGINE_0_MASK 0x00000000u
|
||||
@@ -65,6 +75,8 @@
|
||||
#define ISTATUS_HOST 0x18c
|
||||
#define IMSI_ADDR 0x190
|
||||
#define ISTATUS_MSI 0x194
|
||||
+#define PMSG_SUPPORT_RX 0x3f0
|
||||
+#define PMSG_LTR_SUPPORT BIT(2)
|
||||
|
||||
/* PCIe Master table init defines */
|
||||
#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
|
||||
@@ -86,6 +98,8 @@
|
||||
#define PCIE_TX_RX_INTERFACE 0x00000000u
|
||||
#define PCIE_CONFIG_INTERFACE 0x00000001u
|
||||
|
||||
+#define CONFIG_SPACE_ADDR_OFFSET 0x1000u
|
||||
+
|
||||
#define ATR_ENTRY_SIZE 32
|
||||
|
||||
enum plda_int_event {
|
||||
@@ -200,4 +214,59 @@ static inline void plda_set_default_msi(
|
||||
msi->vector_phy = IMSI_ADDR;
|
||||
msi->num_vectors = PLDA_MAX_NUM_MSI_IRQS;
|
||||
}
|
||||
-#endif
|
||||
+
|
||||
+static inline void plda_pcie_enable_root_port(struct plda_pcie_rp *plda)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = readl_relaxed(plda->bridge_addr + GEN_SETTINGS);
|
||||
+ value |= RP_ENABLE;
|
||||
+ writel_relaxed(value, plda->bridge_addr + GEN_SETTINGS);
|
||||
+}
|
||||
+
|
||||
+static inline void plda_pcie_set_standard_class(struct plda_pcie_rp *plda)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ /* set class code and reserve revision id */
|
||||
+ value = readl_relaxed(plda->bridge_addr + PCIE_PCI_IDS_DW1);
|
||||
+ value &= REVISION_ID_MASK;
|
||||
+ value |= (PCI_CLASS_BRIDGE_PCI << IDS_CLASS_CODE_SHIFT);
|
||||
+ writel_relaxed(value, plda->bridge_addr + PCIE_PCI_IDS_DW1);
|
||||
+}
|
||||
+
|
||||
+static inline void plda_pcie_set_pref_win_64bit(struct plda_pcie_rp *plda)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = readl_relaxed(plda->bridge_addr + PCIE_WINROM);
|
||||
+ value |= PREF_MEM_WIN_64_SUPPORT;
|
||||
+ writel_relaxed(value, plda->bridge_addr + PCIE_WINROM);
|
||||
+}
|
||||
+
|
||||
+static inline void plda_pcie_disable_ltr(struct plda_pcie_rp *plda)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = readl_relaxed(plda->bridge_addr + PMSG_SUPPORT_RX);
|
||||
+ value &= ~PMSG_LTR_SUPPORT;
|
||||
+ writel_relaxed(value, plda->bridge_addr + PMSG_SUPPORT_RX);
|
||||
+}
|
||||
+
|
||||
+static inline void plda_pcie_disable_func(struct plda_pcie_rp *plda)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = readl_relaxed(plda->bridge_addr + PCI_MISC);
|
||||
+ value |= PHY_FUNCTION_DIS;
|
||||
+ writel_relaxed(value, plda->bridge_addr + PCI_MISC);
|
||||
+}
|
||||
+
|
||||
+static inline void plda_pcie_write_rc_bar(struct plda_pcie_rp *plda, u64 val)
|
||||
+{
|
||||
+ void __iomem *addr = plda->bridge_addr + CONFIG_SPACE_ADDR_OFFSET;
|
||||
+
|
||||
+ writel_relaxed(lower_32_bits(val), addr + PCI_BASE_ADDRESS_0);
|
||||
+ writel_relaxed(upper_32_bits(val), addr + PCI_BASE_ADDRESS_1);
|
||||
+}
|
||||
+#endif /* _PCIE_PLDA_H */
|
||||
--- /dev/null
|
||||
+++ b/drivers/pci/controller/plda/pcie-starfive.c
|
||||
@@ -0,0 +1,473 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/*
|
||||
+ * PCIe host controller driver for StarFive JH7110 Soc.
|
||||
+ *
|
||||
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/gpio/consumer.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_pci.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/phy/phy.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include "../../pci.h"
|
||||
+
|
||||
+#include "pcie-plda.h"
|
||||
+
|
||||
+#define PCIE_FUNC_NUM 4
|
||||
+
|
||||
+/* system control */
|
||||
+#define STG_SYSCON_PCIE0_BASE 0x48
|
||||
+#define STG_SYSCON_PCIE1_BASE 0x1f8
|
||||
+
|
||||
+#define STG_SYSCON_AR_OFFSET 0x78
|
||||
+#define STG_SYSCON_AXI4_SLVL_AR_MASK GENMASK(22, 8)
|
||||
+#define STG_SYSCON_AXI4_SLVL_PHY_AR(x) FIELD_PREP(GENMASK(20, 17), x)
|
||||
+#define STG_SYSCON_AW_OFFSET 0x7c
|
||||
+#define STG_SYSCON_AXI4_SLVL_AW_MASK GENMASK(14, 0)
|
||||
+#define STG_SYSCON_AXI4_SLVL_PHY_AW(x) FIELD_PREP(GENMASK(12, 9), x)
|
||||
+#define STG_SYSCON_CLKREQ BIT(22)
|
||||
+#define STG_SYSCON_CKREF_SRC_MASK GENMASK(19, 18)
|
||||
+#define STG_SYSCON_RP_NEP_OFFSET 0xe8
|
||||
+#define STG_SYSCON_K_RP_NEP BIT(8)
|
||||
+#define STG_SYSCON_LNKSTA_OFFSET 0x170
|
||||
+#define DATA_LINK_ACTIVE BIT(5)
|
||||
+
|
||||
+/* Parameters for the waiting for link up routine */
|
||||
+#define LINK_WAIT_MAX_RETRIES 10
|
||||
+#define LINK_WAIT_USLEEP_MIN 90000
|
||||
+#define LINK_WAIT_USLEEP_MAX 100000
|
||||
+
|
||||
+struct starfive_jh7110_pcie {
|
||||
+ struct plda_pcie_rp plda;
|
||||
+ struct reset_control *resets;
|
||||
+ struct clk_bulk_data *clks;
|
||||
+ struct regmap *reg_syscon;
|
||||
+ struct gpio_desc *power_gpio;
|
||||
+ struct gpio_desc *reset_gpio;
|
||||
+ struct phy *phy;
|
||||
+
|
||||
+ unsigned int stg_pcie_base;
|
||||
+ int num_clks;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * The BAR0/1 of bridge should be hidden during enumeration to
|
||||
+ * avoid the sizing and resource allocation by PCIe core.
|
||||
+ */
|
||||
+static bool starfive_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int offset)
|
||||
+{
|
||||
+ if (pci_is_root_bus(bus) && !devfn &&
|
||||
+ (offset == PCI_BASE_ADDRESS_0 || offset == PCI_BASE_ADDRESS_1))
|
||||
+ return true;
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static int starfive_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int where, int size, u32 value)
|
||||
+{
|
||||
+ if (starfive_pcie_hide_rc_bar(bus, devfn, where))
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+
|
||||
+ return pci_generic_config_write(bus, devfn, where, size, value);
|
||||
+}
|
||||
+
|
||||
+static int starfive_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
|
||||
+ int where, int size, u32 *value)
|
||||
+{
|
||||
+ if (starfive_pcie_hide_rc_bar(bus, devfn, where)) {
|
||||
+ *value = 0;
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+ }
|
||||
+
|
||||
+ return pci_generic_config_read(bus, devfn, where, size, value);
|
||||
+}
|
||||
+
|
||||
+static int starfive_pcie_parse_dt(struct starfive_jh7110_pcie *pcie,
|
||||
+ struct device *dev)
|
||||
+{
|
||||
+ int domain_nr;
|
||||
+
|
||||
+ pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
|
||||
+ if (pcie->num_clks < 0)
|
||||
+ return dev_err_probe(dev, pcie->num_clks,
|
||||
+ "failed to get pcie clocks\n");
|
||||
+
|
||||
+ pcie->resets = devm_reset_control_array_get_exclusive(dev);
|
||||
+ if (IS_ERR(pcie->resets))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pcie->resets),
|
||||
+ "failed to get pcie resets");
|
||||
+
|
||||
+ pcie->reg_syscon =
|
||||
+ syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
+ "starfive,stg-syscon");
|
||||
+
|
||||
+ if (IS_ERR(pcie->reg_syscon))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pcie->reg_syscon),
|
||||
+ "failed to parse starfive,stg-syscon\n");
|
||||
+
|
||||
+ pcie->phy = devm_phy_optional_get(dev, NULL);
|
||||
+ if (IS_ERR(pcie->phy))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pcie->phy),
|
||||
+ "failed to get pcie phy\n");
|
||||
+
|
||||
+ domain_nr = of_get_pci_domain_nr(dev->of_node);
|
||||
+
|
||||
+ if (domain_nr < 0 || domain_nr > 1)
|
||||
+ return dev_err_probe(dev, -ENODEV,
|
||||
+ "failed to get valid pcie domain\n");
|
||||
+
|
||||
+ if (domain_nr == 0)
|
||||
+ pcie->stg_pcie_base = STG_SYSCON_PCIE0_BASE;
|
||||
+ else
|
||||
+ pcie->stg_pcie_base = STG_SYSCON_PCIE1_BASE;
|
||||
+
|
||||
+ pcie->reset_gpio = devm_gpiod_get_optional(dev, "perst",
|
||||
+ GPIOD_OUT_HIGH);
|
||||
+ if (IS_ERR(pcie->reset_gpio))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pcie->reset_gpio),
|
||||
+ "failed to get perst-gpio\n");
|
||||
+
|
||||
+ pcie->power_gpio = devm_gpiod_get_optional(dev, "enable",
|
||||
+ GPIOD_OUT_LOW);
|
||||
+ if (IS_ERR(pcie->power_gpio))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pcie->power_gpio),
|
||||
+ "failed to get power-gpio\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct pci_ops starfive_pcie_ops = {
|
||||
+ .map_bus = plda_pcie_map_bus,
|
||||
+ .read = starfive_pcie_config_read,
|
||||
+ .write = starfive_pcie_config_write,
|
||||
+};
|
||||
+
|
||||
+static int starfive_pcie_clk_rst_init(struct starfive_jh7110_pcie *pcie)
|
||||
+{
|
||||
+ struct device *dev = pcie->plda.dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "failed to enable clocks\n");
|
||||
+
|
||||
+ ret = reset_control_deassert(pcie->resets);
|
||||
+ if (ret) {
|
||||
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
|
||||
+ dev_err_probe(dev, ret, "failed to deassert resets\n");
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void starfive_pcie_clk_rst_deinit(struct starfive_jh7110_pcie *pcie)
|
||||
+{
|
||||
+ reset_control_assert(pcie->resets);
|
||||
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
|
||||
+}
|
||||
+
|
||||
+static bool starfive_pcie_link_up(struct plda_pcie_rp *plda)
|
||||
+{
|
||||
+ struct starfive_jh7110_pcie *pcie =
|
||||
+ container_of(plda, struct starfive_jh7110_pcie, plda);
|
||||
+ int ret;
|
||||
+ u32 stg_reg_val;
|
||||
+
|
||||
+ ret = regmap_read(pcie->reg_syscon,
|
||||
+ pcie->stg_pcie_base + STG_SYSCON_LNKSTA_OFFSET,
|
||||
+ &stg_reg_val);
|
||||
+ if (ret) {
|
||||
+ dev_err(pcie->plda.dev, "failed to read link status\n");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return !!(stg_reg_val & DATA_LINK_ACTIVE);
|
||||
+}
|
||||
+
|
||||
+static int starfive_pcie_host_wait_for_link(struct starfive_jh7110_pcie *pcie)
|
||||
+{
|
||||
+ int retries;
|
||||
+
|
||||
+ /* Check if the link is up or not */
|
||||
+ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
|
||||
+ if (starfive_pcie_link_up(&pcie->plda)) {
|
||||
+ dev_info(pcie->plda.dev, "port link up\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
|
||||
+ }
|
||||
+
|
||||
+ return -ETIMEDOUT;
|
||||
+}
|
||||
+
|
||||
+static int starfive_pcie_enable_phy(struct device *dev,
|
||||
+ struct starfive_jh7110_pcie *pcie)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!pcie->phy)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = phy_init(pcie->phy);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret,
|
||||
+ "failed to initialize pcie phy\n");
|
||||
+
|
||||
+ ret = phy_set_mode(pcie->phy, PHY_MODE_PCIE);
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(dev, ret, "failed to set pcie mode\n");
|
||||
+ goto err_phy_on;
|
||||
+ }
|
||||
+
|
||||
+ ret = phy_power_on(pcie->phy);
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(dev, ret, "failed to power on pcie phy\n");
|
||||
+ goto err_phy_on;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_phy_on:
|
||||
+ phy_exit(pcie->phy);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void starfive_pcie_disable_phy(struct starfive_jh7110_pcie *pcie)
|
||||
+{
|
||||
+ phy_power_off(pcie->phy);
|
||||
+ phy_exit(pcie->phy);
|
||||
+}
|
||||
+
|
||||
+static void starfive_pcie_host_deinit(struct plda_pcie_rp *plda)
|
||||
+{
|
||||
+ struct starfive_jh7110_pcie *pcie =
|
||||
+ container_of(plda, struct starfive_jh7110_pcie, plda);
|
||||
+
|
||||
+ starfive_pcie_clk_rst_deinit(pcie);
|
||||
+ if (pcie->power_gpio)
|
||||
+ gpiod_set_value_cansleep(pcie->power_gpio, 0);
|
||||
+ starfive_pcie_disable_phy(pcie);
|
||||
+}
|
||||
+
|
||||
+static int starfive_pcie_host_init(struct plda_pcie_rp *plda)
|
||||
+{
|
||||
+ struct starfive_jh7110_pcie *pcie =
|
||||
+ container_of(plda, struct starfive_jh7110_pcie, plda);
|
||||
+ struct device *dev = plda->dev;
|
||||
+ int ret;
|
||||
+ int i;
|
||||
+
|
||||
+ ret = starfive_pcie_enable_phy(dev, pcie);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ regmap_update_bits(pcie->reg_syscon,
|
||||
+ pcie->stg_pcie_base + STG_SYSCON_RP_NEP_OFFSET,
|
||||
+ STG_SYSCON_K_RP_NEP, STG_SYSCON_K_RP_NEP);
|
||||
+
|
||||
+ regmap_update_bits(pcie->reg_syscon,
|
||||
+ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
|
||||
+ STG_SYSCON_CKREF_SRC_MASK,
|
||||
+ FIELD_PREP(STG_SYSCON_CKREF_SRC_MASK, 2));
|
||||
+
|
||||
+ regmap_update_bits(pcie->reg_syscon,
|
||||
+ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
|
||||
+ STG_SYSCON_CLKREQ, STG_SYSCON_CLKREQ);
|
||||
+
|
||||
+ ret = starfive_pcie_clk_rst_init(pcie);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (pcie->power_gpio)
|
||||
+ gpiod_set_value_cansleep(pcie->power_gpio, 1);
|
||||
+
|
||||
+ if (pcie->reset_gpio)
|
||||
+ gpiod_set_value_cansleep(pcie->reset_gpio, 1);
|
||||
+
|
||||
+ /* Disable physical functions except #0 */
|
||||
+ for (i = 1; i < PCIE_FUNC_NUM; i++) {
|
||||
+ regmap_update_bits(pcie->reg_syscon,
|
||||
+ pcie->stg_pcie_base + STG_SYSCON_AR_OFFSET,
|
||||
+ STG_SYSCON_AXI4_SLVL_AR_MASK,
|
||||
+ STG_SYSCON_AXI4_SLVL_PHY_AR(i));
|
||||
+
|
||||
+ regmap_update_bits(pcie->reg_syscon,
|
||||
+ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
|
||||
+ STG_SYSCON_AXI4_SLVL_AW_MASK,
|
||||
+ STG_SYSCON_AXI4_SLVL_PHY_AW(i));
|
||||
+
|
||||
+ plda_pcie_disable_func(plda);
|
||||
+ }
|
||||
+
|
||||
+ regmap_update_bits(pcie->reg_syscon,
|
||||
+ pcie->stg_pcie_base + STG_SYSCON_AR_OFFSET,
|
||||
+ STG_SYSCON_AXI4_SLVL_AR_MASK, 0);
|
||||
+ regmap_update_bits(pcie->reg_syscon,
|
||||
+ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
|
||||
+ STG_SYSCON_AXI4_SLVL_AW_MASK, 0);
|
||||
+
|
||||
+ plda_pcie_enable_root_port(plda);
|
||||
+ plda_pcie_write_rc_bar(plda, 0);
|
||||
+
|
||||
+ /* PCIe PCI Standard Configuration Identification Settings. */
|
||||
+ plda_pcie_set_standard_class(plda);
|
||||
+
|
||||
+ /*
|
||||
+ * The LTR message forwarding of PCIe Message Reception was set by core
|
||||
+ * as default, but the forward id & addr are also need to be reset.
|
||||
+ * If we do not disable LTR message forwarding here, or set a legal
|
||||
+ * forwarding address, the kernel will get stuck after the driver probe.
|
||||
+ * To workaround, disable the LTR message forwarding support on
|
||||
+ * PCIe Message Reception.
|
||||
+ */
|
||||
+ plda_pcie_disable_ltr(plda);
|
||||
+
|
||||
+ /* Prefetchable memory window 64-bit addressing support */
|
||||
+ plda_pcie_set_pref_win_64bit(plda);
|
||||
+
|
||||
+ /*
|
||||
+ * Ensure that PERST has been asserted for at least 100 ms,
|
||||
+ * the sleep value is T_PVPERL from PCIe CEM spec r2.0 (Table 2-4)
|
||||
+ */
|
||||
+ msleep(100);
|
||||
+ if (pcie->reset_gpio)
|
||||
+ gpiod_set_value_cansleep(pcie->reset_gpio, 0);
|
||||
+
|
||||
+ /*
|
||||
+ * With a Downstream Port (<=5GT/s), software must wait a minimum
|
||||
+ * of 100ms following exit from a conventional reset before
|
||||
+ * sending a configuration request to the device.
|
||||
+ */
|
||||
+ msleep(PCIE_RESET_CONFIG_DEVICE_WAIT_MS);
|
||||
+
|
||||
+ if (starfive_pcie_host_wait_for_link(pcie))
|
||||
+ dev_info(dev, "port link down\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct plda_pcie_host_ops sf_host_ops = {
|
||||
+ .host_init = starfive_pcie_host_init,
|
||||
+ .host_deinit = starfive_pcie_host_deinit,
|
||||
+};
|
||||
+
|
||||
+static const struct plda_event stf_pcie_event = {
|
||||
+ .intx_event = EVENT_PM_MSI_INT_INTX,
|
||||
+ .msi_event = EVENT_PM_MSI_INT_MSI
|
||||
+};
|
||||
+
|
||||
+static int starfive_pcie_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct starfive_jh7110_pcie *pcie;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct plda_pcie_rp *plda;
|
||||
+ int ret;
|
||||
+
|
||||
+ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
|
||||
+ if (!pcie)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ plda = &pcie->plda;
|
||||
+ plda->dev = dev;
|
||||
+
|
||||
+ ret = starfive_pcie_parse_dt(pcie, dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ plda->host_ops = &sf_host_ops;
|
||||
+ plda->num_events = PLDA_MAX_EVENT_NUM;
|
||||
+ /* mask doorbell event */
|
||||
+ plda->events_bitmap = GENMASK(PLDA_INT_EVENT_NUM - 1, 0)
|
||||
+ & ~BIT(PLDA_AXI_DOORBELL)
|
||||
+ & ~BIT(PLDA_PCIE_DOORBELL);
|
||||
+ plda->events_bitmap <<= PLDA_NUM_DMA_EVENTS;
|
||||
+ ret = plda_pcie_host_init(&pcie->plda, &starfive_pcie_ops,
|
||||
+ &stf_pcie_event);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ pm_runtime_enable(&pdev->dev);
|
||||
+ pm_runtime_get_sync(&pdev->dev);
|
||||
+ platform_set_drvdata(pdev, pcie);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void starfive_pcie_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct starfive_jh7110_pcie *pcie = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ pm_runtime_put(&pdev->dev);
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+ plda_pcie_host_deinit(&pcie->plda);
|
||||
+ platform_set_drvdata(pdev, NULL);
|
||||
+}
|
||||
+
|
||||
+static int starfive_pcie_suspend_noirq(struct device *dev)
|
||||
+{
|
||||
+ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
|
||||
+
|
||||
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
|
||||
+ starfive_pcie_disable_phy(pcie);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int starfive_pcie_resume_noirq(struct device *dev)
|
||||
+{
|
||||
+ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = starfive_pcie_enable_phy(dev, pcie);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to enable clocks\n");
|
||||
+ starfive_pcie_disable_phy(pcie);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct dev_pm_ops starfive_pcie_pm_ops = {
|
||||
+ NOIRQ_SYSTEM_SLEEP_PM_OPS(starfive_pcie_suspend_noirq,
|
||||
+ starfive_pcie_resume_noirq)
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id starfive_pcie_of_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-pcie", },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, starfive_pcie_of_match);
|
||||
+
|
||||
+static struct platform_driver starfive_pcie_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "pcie-starfive",
|
||||
+ .of_match_table = of_match_ptr(starfive_pcie_of_match),
|
||||
+ .pm = pm_sleep_ptr(&starfive_pcie_pm_ops),
|
||||
+ },
|
||||
+ .probe = starfive_pcie_probe,
|
||||
+ .remove_new = starfive_pcie_remove,
|
||||
+};
|
||||
+module_platform_driver(starfive_pcie_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 PCIe host driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
@ -0,0 +1,97 @@
|
||||
From a306724fd4f32808d1e27efbd87019d56f60db20 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Mon, 14 Aug 2023 16:06:16 +0800
|
||||
Subject: [PATCH 035/116] ASoC: dt-bindings: Add StarFive JH7110 PWM-DAC
|
||||
controller
|
||||
|
||||
Add bindings for the PWM-DAC controller on the JH7110
|
||||
RISC-V SoC by StarFive Ltd.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Link: https://lore.kernel.org/r/20230814080618.10036-2-hal.feng@starfivetech.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
.../sound/starfive,jh7110-pwmdac.yaml | 76 +++++++++++++++++++
|
||||
1 file changed, 76 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
|
||||
@@ -0,0 +1,76 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/sound/starfive,jh7110-pwmdac.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: StarFive JH7110 PWM-DAC Controller
|
||||
+
|
||||
+description:
|
||||
+ The PWM-DAC Controller uses PWM square wave generators plus RC filters to
|
||||
+ form a DAC for audio play in StarFive JH7110 SoC. This audio play controller
|
||||
+ supports 16 bit audio format, up to 48K sampling frequency, up to left and
|
||||
+ right dual channels.
|
||||
+
|
||||
+maintainers:
|
||||
+ - Hal Feng <hal.feng@starfivetech.com>
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: dai-common.yaml#
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-pwmdac
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: PWMDAC APB
|
||||
+ - description: PWMDAC CORE
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: apb
|
||||
+ - const: core
|
||||
+
|
||||
+ resets:
|
||||
+ maxItems: 1
|
||||
+ description: PWMDAC APB
|
||||
+
|
||||
+ dmas:
|
||||
+ maxItems: 1
|
||||
+ description: TX DMA Channel
|
||||
+
|
||||
+ dma-names:
|
||||
+ const: tx
|
||||
+
|
||||
+ "#sound-dai-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - dmas
|
||||
+ - dma-names
|
||||
+ - "#sound-dai-cells"
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ pwmdac@100b0000 {
|
||||
+ compatible = "starfive,jh7110-pwmdac";
|
||||
+ reg = <0x100b0000 0x1000>;
|
||||
+ clocks = <&syscrg 157>,
|
||||
+ <&syscrg 158>;
|
||||
+ clock-names = "apb", "core";
|
||||
+ resets = <&syscrg 96>;
|
||||
+ dmas = <&dma 22>;
|
||||
+ dma-names = "tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ };
|
@ -0,0 +1,574 @@
|
||||
From a79d2ec524012e35e32a2c4ae2401d0aa763697d Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Mon, 14 Aug 2023 16:06:17 +0800
|
||||
Subject: [PATCH 036/116] ASoC: starfive: Add JH7110 PWM-DAC driver
|
||||
|
||||
Add PWM-DAC driver support for the StarFive JH7110 SoC.
|
||||
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
Link: https://lore.kernel.org/r/20230814080618.10036-3-hal.feng@starfivetech.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/starfive/Kconfig | 9 +
|
||||
sound/soc/starfive/Makefile | 1 +
|
||||
sound/soc/starfive/jh7110_pwmdac.c | 529 +++++++++++++++++++++++++++++
|
||||
3 files changed, 539 insertions(+)
|
||||
create mode 100644 sound/soc/starfive/jh7110_pwmdac.c
|
||||
|
||||
--- a/sound/soc/starfive/Kconfig
|
||||
+++ b/sound/soc/starfive/Kconfig
|
||||
@@ -7,6 +7,15 @@ config SND_SOC_STARFIVE
|
||||
the Starfive SoCs' Audio interfaces. You will also need to
|
||||
select the audio interfaces to support below.
|
||||
|
||||
+config SND_SOC_JH7110_PWMDAC
|
||||
+ tristate "JH7110 PWM-DAC device driver"
|
||||
+ depends on HAVE_CLK && SND_SOC_STARFIVE
|
||||
+ select SND_SOC_GENERIC_DMAENGINE_PCM
|
||||
+ select SND_SOC_SPDIF
|
||||
+ help
|
||||
+ Say Y or M if you want to add support for StarFive JH7110
|
||||
+ PWM-DAC driver.
|
||||
+
|
||||
config SND_SOC_JH7110_TDM
|
||||
tristate "JH7110 TDM device driver"
|
||||
depends on HAVE_CLK && SND_SOC_STARFIVE
|
||||
--- a/sound/soc/starfive/Makefile
|
||||
+++ b/sound/soc/starfive/Makefile
|
||||
@@ -1,2 +1,3 @@
|
||||
# StarFive Platform Support
|
||||
+obj-$(CONFIG_SND_SOC_JH7110_PWMDAC) += jh7110_pwmdac.o
|
||||
obj-$(CONFIG_SND_SOC_JH7110_TDM) += jh7110_tdm.o
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/starfive/jh7110_pwmdac.c
|
||||
@@ -0,0 +1,529 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * jh7110_pwmdac.c -- StarFive JH7110 PWM-DAC driver
|
||||
+ *
|
||||
+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
|
||||
+ *
|
||||
+ * Authors: Jenny Zhang
|
||||
+ * Curry Zhang
|
||||
+ * Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+ * Hal Feng <hal.feng@starfivetech.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <sound/dmaengine_pcm.h>
|
||||
+#include <sound/pcm.h>
|
||||
+#include <sound/pcm_params.h>
|
||||
+#include <sound/soc.h>
|
||||
+
|
||||
+#define JH7110_PWMDAC_WDATA 0x00
|
||||
+#define JH7110_PWMDAC_CTRL 0x04
|
||||
+ #define JH7110_PWMDAC_ENABLE BIT(0)
|
||||
+ #define JH7110_PWMDAC_SHIFT BIT(1)
|
||||
+ #define JH7110_PWMDAC_DUTY_CYCLE_SHIFT 2
|
||||
+ #define JH7110_PWMDAC_DUTY_CYCLE_MASK GENMASK(3, 2)
|
||||
+ #define JH7110_PWMDAC_CNT_N_SHIFT 4
|
||||
+ #define JH7110_PWMDAC_CNT_N_MASK GENMASK(12, 4)
|
||||
+ #define JH7110_PWMDAC_DATA_CHANGE BIT(13)
|
||||
+ #define JH7110_PWMDAC_DATA_MODE BIT(14)
|
||||
+ #define JH7110_PWMDAC_DATA_SHIFT_SHIFT 15
|
||||
+ #define JH7110_PWMDAC_DATA_SHIFT_MASK GENMASK(17, 15)
|
||||
+
|
||||
+enum JH7110_PWMDAC_SHIFT_VAL {
|
||||
+ PWMDAC_SHIFT_8 = 0,
|
||||
+ PWMDAC_SHIFT_10,
|
||||
+};
|
||||
+
|
||||
+enum JH7110_PWMDAC_DUTY_CYCLE_VAL {
|
||||
+ PWMDAC_CYCLE_LEFT = 0,
|
||||
+ PWMDAC_CYCLE_RIGHT,
|
||||
+ PWMDAC_CYCLE_CENTER,
|
||||
+};
|
||||
+
|
||||
+enum JH7110_PWMDAC_CNT_N_VAL {
|
||||
+ PWMDAC_SAMPLE_CNT_1 = 1,
|
||||
+ PWMDAC_SAMPLE_CNT_2,
|
||||
+ PWMDAC_SAMPLE_CNT_3,
|
||||
+ PWMDAC_SAMPLE_CNT_512 = 512, /* max */
|
||||
+};
|
||||
+
|
||||
+enum JH7110_PWMDAC_DATA_CHANGE_VAL {
|
||||
+ NO_CHANGE = 0,
|
||||
+ CHANGE,
|
||||
+};
|
||||
+
|
||||
+enum JH7110_PWMDAC_DATA_MODE_VAL {
|
||||
+ UNSIGNED_DATA = 0,
|
||||
+ INVERTER_DATA_MSB,
|
||||
+};
|
||||
+
|
||||
+enum JH7110_PWMDAC_DATA_SHIFT_VAL {
|
||||
+ PWMDAC_DATA_LEFT_SHIFT_BIT_0 = 0,
|
||||
+ PWMDAC_DATA_LEFT_SHIFT_BIT_1,
|
||||
+ PWMDAC_DATA_LEFT_SHIFT_BIT_2,
|
||||
+ PWMDAC_DATA_LEFT_SHIFT_BIT_3,
|
||||
+ PWMDAC_DATA_LEFT_SHIFT_BIT_4,
|
||||
+ PWMDAC_DATA_LEFT_SHIFT_BIT_5,
|
||||
+ PWMDAC_DATA_LEFT_SHIFT_BIT_6,
|
||||
+ PWMDAC_DATA_LEFT_SHIFT_BIT_7,
|
||||
+};
|
||||
+
|
||||
+struct jh7110_pwmdac_cfg {
|
||||
+ enum JH7110_PWMDAC_SHIFT_VAL shift;
|
||||
+ enum JH7110_PWMDAC_DUTY_CYCLE_VAL duty_cycle;
|
||||
+ u16 cnt_n;
|
||||
+ enum JH7110_PWMDAC_DATA_CHANGE_VAL data_change;
|
||||
+ enum JH7110_PWMDAC_DATA_MODE_VAL data_mode;
|
||||
+ enum JH7110_PWMDAC_DATA_SHIFT_VAL data_shift;
|
||||
+};
|
||||
+
|
||||
+struct jh7110_pwmdac_dev {
|
||||
+ void __iomem *base;
|
||||
+ resource_size_t mapbase;
|
||||
+ struct jh7110_pwmdac_cfg cfg;
|
||||
+
|
||||
+ struct clk_bulk_data clks[2];
|
||||
+ struct reset_control *rst_apb;
|
||||
+ struct device *dev;
|
||||
+ struct snd_dmaengine_dai_dma_data play_dma_data;
|
||||
+ u32 saved_ctrl;
|
||||
+};
|
||||
+
|
||||
+static inline void jh7110_pwmdac_write_reg(void __iomem *io_base, int reg, u32 val)
|
||||
+{
|
||||
+ writel(val, io_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline u32 jh7110_pwmdac_read_reg(void __iomem *io_base, int reg)
|
||||
+{
|
||||
+ return readl(io_base + reg);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_pwmdac_set_enable(struct jh7110_pwmdac_dev *dev, bool enable)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
|
||||
+ if (enable)
|
||||
+ value |= JH7110_PWMDAC_ENABLE;
|
||||
+ else
|
||||
+ value &= ~JH7110_PWMDAC_ENABLE;
|
||||
+
|
||||
+ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_pwmdac_set_shift(struct jh7110_pwmdac_dev *dev)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
|
||||
+ if (dev->cfg.shift == PWMDAC_SHIFT_8)
|
||||
+ value &= ~JH7110_PWMDAC_SHIFT;
|
||||
+ else if (dev->cfg.shift == PWMDAC_SHIFT_10)
|
||||
+ value |= JH7110_PWMDAC_SHIFT;
|
||||
+
|
||||
+ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_pwmdac_set_duty_cycle(struct jh7110_pwmdac_dev *dev)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
|
||||
+ value &= ~JH7110_PWMDAC_DUTY_CYCLE_MASK;
|
||||
+ value |= (dev->cfg.duty_cycle & 0x3) << JH7110_PWMDAC_DUTY_CYCLE_SHIFT;
|
||||
+
|
||||
+ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_pwmdac_set_cnt_n(struct jh7110_pwmdac_dev *dev)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
|
||||
+ value &= ~JH7110_PWMDAC_CNT_N_MASK;
|
||||
+ value |= ((dev->cfg.cnt_n - 1) & 0x1ff) << JH7110_PWMDAC_CNT_N_SHIFT;
|
||||
+
|
||||
+ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_pwmdac_set_data_change(struct jh7110_pwmdac_dev *dev)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
|
||||
+ if (dev->cfg.data_change == NO_CHANGE)
|
||||
+ value &= ~JH7110_PWMDAC_DATA_CHANGE;
|
||||
+ else if (dev->cfg.data_change == CHANGE)
|
||||
+ value |= JH7110_PWMDAC_DATA_CHANGE;
|
||||
+
|
||||
+ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_pwmdac_set_data_mode(struct jh7110_pwmdac_dev *dev)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
|
||||
+ if (dev->cfg.data_mode == UNSIGNED_DATA)
|
||||
+ value &= ~JH7110_PWMDAC_DATA_MODE;
|
||||
+ else if (dev->cfg.data_mode == INVERTER_DATA_MSB)
|
||||
+ value |= JH7110_PWMDAC_DATA_MODE;
|
||||
+
|
||||
+ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_pwmdac_set_data_shift(struct jh7110_pwmdac_dev *dev)
|
||||
+{
|
||||
+ u32 value;
|
||||
+
|
||||
+ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
|
||||
+ value &= ~JH7110_PWMDAC_DATA_SHIFT_MASK;
|
||||
+ value |= (dev->cfg.data_shift & 0x7) << JH7110_PWMDAC_DATA_SHIFT_SHIFT;
|
||||
+
|
||||
+ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_pwmdac_set(struct jh7110_pwmdac_dev *dev)
|
||||
+{
|
||||
+ jh7110_pwmdac_set_shift(dev);
|
||||
+ jh7110_pwmdac_set_duty_cycle(dev);
|
||||
+ jh7110_pwmdac_set_cnt_n(dev);
|
||||
+ jh7110_pwmdac_set_enable(dev, true);
|
||||
+
|
||||
+ jh7110_pwmdac_set_data_change(dev);
|
||||
+ jh7110_pwmdac_set_data_mode(dev);
|
||||
+ jh7110_pwmdac_set_data_shift(dev);
|
||||
+}
|
||||
+
|
||||
+static void jh7110_pwmdac_stop(struct jh7110_pwmdac_dev *dev)
|
||||
+{
|
||||
+ jh7110_pwmdac_set_enable(dev, false);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_startup(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
|
||||
+
|
||||
+ dai_link->trigger_stop = SND_SOC_TRIGGER_ORDER_LDC;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct jh7110_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
|
||||
+ unsigned long core_clk_rate;
|
||||
+ int ret;
|
||||
+
|
||||
+ switch (params_rate(params)) {
|
||||
+ case 8000:
|
||||
+ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_3;
|
||||
+ core_clk_rate = 6144000;
|
||||
+ break;
|
||||
+ case 11025:
|
||||
+ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_2;
|
||||
+ core_clk_rate = 5644800;
|
||||
+ break;
|
||||
+ case 16000:
|
||||
+ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_3;
|
||||
+ core_clk_rate = 12288000;
|
||||
+ break;
|
||||
+ case 22050:
|
||||
+ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
|
||||
+ core_clk_rate = 5644800;
|
||||
+ break;
|
||||
+ case 32000:
|
||||
+ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
|
||||
+ core_clk_rate = 8192000;
|
||||
+ break;
|
||||
+ case 44100:
|
||||
+ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
|
||||
+ core_clk_rate = 11289600;
|
||||
+ break;
|
||||
+ case 48000:
|
||||
+ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
|
||||
+ core_clk_rate = 12288000;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(dai->dev, "%d rate not supported\n",
|
||||
+ params_rate(params));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (params_channels(params)) {
|
||||
+ case 1:
|
||||
+ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(dai->dev, "%d channels not supported\n",
|
||||
+ params_channels(params));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * The clock rate always rounds down when using clk_set_rate()
|
||||
+ * so increase the rate a bit
|
||||
+ */
|
||||
+ core_clk_rate += 64;
|
||||
+ jh7110_pwmdac_set(dev);
|
||||
+
|
||||
+ ret = clk_set_rate(dev->clks[1].clk, core_clk_rate);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dai->dev, ret,
|
||||
+ "failed to set rate %lu for core clock\n",
|
||||
+ core_clk_rate);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct jh7110_pwmdac_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SNDRV_PCM_TRIGGER_START:
|
||||
+ case SNDRV_PCM_TRIGGER_RESUME:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
+ jh7110_pwmdac_set(dev);
|
||||
+ break;
|
||||
+
|
||||
+ case SNDRV_PCM_TRIGGER_STOP:
|
||||
+ case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
+ jh7110_pwmdac_stop(dev);
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_crg_enable(struct jh7110_pwmdac_dev *dev, bool enable)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (enable) {
|
||||
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(dev->clks), dev->clks);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev->dev, ret,
|
||||
+ "failed to enable pwmdac clocks\n");
|
||||
+
|
||||
+ ret = reset_control_deassert(dev->rst_apb);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev->dev, "failed to deassert pwmdac apb reset\n");
|
||||
+ goto err_rst_apb;
|
||||
+ }
|
||||
+ } else {
|
||||
+ clk_bulk_disable_unprepare(ARRAY_SIZE(dev->clks), dev->clks);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_rst_apb:
|
||||
+ clk_bulk_disable_unprepare(ARRAY_SIZE(dev->clks), dev->clks);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_dai_probe(struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct jh7110_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
|
||||
+
|
||||
+ snd_soc_dai_init_dma_data(dai, &dev->play_dma_data, NULL);
|
||||
+ snd_soc_dai_set_drvdata(dai, dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_dai_ops jh7110_pwmdac_dai_ops = {
|
||||
+ .startup = jh7110_pwmdac_startup,
|
||||
+ .hw_params = jh7110_pwmdac_hw_params,
|
||||
+ .trigger = jh7110_pwmdac_trigger,
|
||||
+};
|
||||
+
|
||||
+static const struct snd_soc_component_driver jh7110_pwmdac_component = {
|
||||
+ .name = "jh7110-pwmdac",
|
||||
+};
|
||||
+
|
||||
+static struct snd_soc_dai_driver jh7110_pwmdac_dai = {
|
||||
+ .name = "jh7110-pwmdac",
|
||||
+ .id = 0,
|
||||
+ .probe = jh7110_pwmdac_dai_probe,
|
||||
+ .playback = {
|
||||
+ .channels_min = 1,
|
||||
+ .channels_max = 2,
|
||||
+ .rates = SNDRV_PCM_RATE_8000_48000,
|
||||
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
+ },
|
||||
+ .ops = &jh7110_pwmdac_dai_ops,
|
||||
+};
|
||||
+
|
||||
+static int jh7110_pwmdac_runtime_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
|
||||
+
|
||||
+ return jh7110_pwmdac_crg_enable(pwmdac, false);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
|
||||
+
|
||||
+ return jh7110_pwmdac_crg_enable(pwmdac, true);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_system_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
|
||||
+
|
||||
+ /* save the CTRL register value */
|
||||
+ pwmdac->saved_ctrl = jh7110_pwmdac_read_reg(pwmdac->base,
|
||||
+ JH7110_PWMDAC_CTRL);
|
||||
+ return pm_runtime_force_suspend(dev);
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_system_resume(struct device *dev)
|
||||
+{
|
||||
+ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pm_runtime_force_resume(dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* restore the CTRL register value */
|
||||
+ jh7110_pwmdac_write_reg(pwmdac->base, JH7110_PWMDAC_CTRL,
|
||||
+ pwmdac->saved_ctrl);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct dev_pm_ops jh7110_pwmdac_pm_ops = {
|
||||
+ RUNTIME_PM_OPS(jh7110_pwmdac_runtime_suspend,
|
||||
+ jh7110_pwmdac_runtime_resume, NULL)
|
||||
+ SYSTEM_SLEEP_PM_OPS(jh7110_pwmdac_system_suspend,
|
||||
+ jh7110_pwmdac_system_resume)
|
||||
+};
|
||||
+
|
||||
+static void jh7110_pwmdac_init_params(struct jh7110_pwmdac_dev *dev)
|
||||
+{
|
||||
+ dev->cfg.shift = PWMDAC_SHIFT_8;
|
||||
+ dev->cfg.duty_cycle = PWMDAC_CYCLE_CENTER;
|
||||
+ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
|
||||
+ dev->cfg.data_change = NO_CHANGE;
|
||||
+ dev->cfg.data_mode = INVERTER_DATA_MSB;
|
||||
+ dev->cfg.data_shift = PWMDAC_DATA_LEFT_SHIFT_BIT_0;
|
||||
+
|
||||
+ dev->play_dma_data.addr = dev->mapbase + JH7110_PWMDAC_WDATA;
|
||||
+ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
+ dev->play_dma_data.fifo_size = 1;
|
||||
+ dev->play_dma_data.maxburst = 16;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct jh7110_pwmdac_dev *dev;
|
||||
+ struct resource *res;
|
||||
+ int ret;
|
||||
+
|
||||
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
|
||||
+ if (!dev)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
+ if (IS_ERR(dev->base))
|
||||
+ return PTR_ERR(dev->base);
|
||||
+
|
||||
+ dev->mapbase = res->start;
|
||||
+
|
||||
+ dev->clks[0].id = "apb";
|
||||
+ dev->clks[1].id = "core";
|
||||
+
|
||||
+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(dev->clks), dev->clks);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(&pdev->dev, ret,
|
||||
+ "failed to get pwmdac clocks\n");
|
||||
+
|
||||
+ dev->rst_apb = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(dev->rst_apb))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(dev->rst_apb),
|
||||
+ "failed to get pwmdac apb reset\n");
|
||||
+
|
||||
+ jh7110_pwmdac_init_params(dev);
|
||||
+
|
||||
+ dev->dev = &pdev->dev;
|
||||
+ dev_set_drvdata(&pdev->dev, dev);
|
||||
+ ret = devm_snd_soc_register_component(&pdev->dev,
|
||||
+ &jh7110_pwmdac_component,
|
||||
+ &jh7110_pwmdac_dai, 1);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(&pdev->dev, ret, "failed to register dai\n");
|
||||
+
|
||||
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(&pdev->dev, ret, "failed to register pcm\n");
|
||||
+
|
||||
+ pm_runtime_enable(dev->dev);
|
||||
+ if (!pm_runtime_enabled(&pdev->dev)) {
|
||||
+ ret = jh7110_pwmdac_runtime_resume(&pdev->dev);
|
||||
+ if (ret)
|
||||
+ goto err_pm_disable;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_pm_disable:
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int jh7110_pwmdac_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id jh7110_pwmdac_of_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-pwmdac" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_pwmdac_of_match);
|
||||
+
|
||||
+static struct platform_driver jh7110_pwmdac_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "jh7110-pwmdac",
|
||||
+ .of_match_table = jh7110_pwmdac_of_match,
|
||||
+ .pm = pm_ptr(&jh7110_pwmdac_pm_ops),
|
||||
+ },
|
||||
+ .probe = jh7110_pwmdac_probe,
|
||||
+ .remove = jh7110_pwmdac_remove,
|
||||
+};
|
||||
+module_platform_driver(jh7110_pwmdac_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Jenny Zhang");
|
||||
+MODULE_AUTHOR("Curry Zhang");
|
||||
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
|
||||
+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive JH7110 PWM-DAC driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,32 @@
|
||||
From c6b693f990e1f89ab5af0a139da31401b8cda74f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Brown <broonie@kernel.org>
|
||||
Date: Mon, 11 Sep 2023 23:48:39 +0100
|
||||
Subject: [PATCH 037/116] ASoC: Update jh7110 PWM DAC for ops move
|
||||
|
||||
For some reason the JH7110 PWM DAC driver made it through build testing
|
||||
in spite of not being updated for the move of probe() to the ops struct.
|
||||
Make the required update.
|
||||
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/starfive/jh7110_pwmdac.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/sound/soc/starfive/jh7110_pwmdac.c
|
||||
+++ b/sound/soc/starfive/jh7110_pwmdac.c
|
||||
@@ -357,6 +357,7 @@ static int jh7110_pwmdac_dai_probe(struc
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops jh7110_pwmdac_dai_ops = {
|
||||
+ .probe = jh7110_pwmdac_dai_probe,
|
||||
.startup = jh7110_pwmdac_startup,
|
||||
.hw_params = jh7110_pwmdac_hw_params,
|
||||
.trigger = jh7110_pwmdac_trigger,
|
||||
@@ -369,7 +370,6 @@ static const struct snd_soc_component_dr
|
||||
static struct snd_soc_dai_driver jh7110_pwmdac_dai = {
|
||||
.name = "jh7110-pwmdac",
|
||||
.id = 0,
|
||||
- .probe = jh7110_pwmdac_dai_probe,
|
||||
.playback = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
@ -0,0 +1,52 @@
|
||||
From 312c3c407c363f0ec7417d2d389cbe936c503729 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
|
||||
Date: Sat, 14 Oct 2023 00:19:49 +0200
|
||||
Subject: [PATCH 038/116] ASoC: starfive/jh7110-pwmdac: Convert to platform
|
||||
remove callback returning void
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The .remove() callback for a platform driver returns an int which makes
|
||||
many driver authors wrongly assume it's possible to do error handling by
|
||||
returning an error code. However the value returned is ignored (apart
|
||||
from emitting a warning) and this typically results in resource leaks.
|
||||
|
||||
To improve here there is a quest to make the remove callback return
|
||||
void. In the first step of this quest all drivers are converted to
|
||||
.remove_new(), which already returns void. Eventually after all drivers
|
||||
are converted, .remove_new() will be renamed to .remove().
|
||||
|
||||
Trivially convert this driver from always returning zero in the remove
|
||||
callback to the void returning variant.
|
||||
|
||||
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
|
||||
Link: https://lore.kernel.org/r/20231013221945.1489203-12-u.kleine-koenig@pengutronix.de
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/starfive/jh7110_pwmdac.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/sound/soc/starfive/jh7110_pwmdac.c
|
||||
+++ b/sound/soc/starfive/jh7110_pwmdac.c
|
||||
@@ -498,10 +498,9 @@ err_pm_disable:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int jh7110_pwmdac_remove(struct platform_device *pdev)
|
||||
+static void jh7110_pwmdac_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
- return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id jh7110_pwmdac_of_match[] = {
|
||||
@@ -517,7 +516,7 @@ static struct platform_driver jh7110_pwm
|
||||
.pm = pm_ptr(&jh7110_pwmdac_pm_ops),
|
||||
},
|
||||
.probe = jh7110_pwmdac_probe,
|
||||
- .remove = jh7110_pwmdac_remove,
|
||||
+ .remove_new = jh7110_pwmdac_remove,
|
||||
};
|
||||
module_platform_driver(jh7110_pwmdac_driver);
|
||||
|
@ -0,0 +1,35 @@
|
||||
From 8d84bac6d7471ba2e29b33d19a2ef887822e9cce Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Wed, 13 Sep 2023 14:54:25 +0100
|
||||
Subject: [PATCH 039/116] dt-bindings: power: Add power-domain header for
|
||||
JH7110
|
||||
|
||||
Add power-domain header for JH7110 SoC, it can use to operate dphy
|
||||
power.
|
||||
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20230913-grumbly-rewrite-34c85539f2ed@spud
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
include/dt-bindings/power/starfive,jh7110-pmu.h | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
+++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
|
||||
* Author: Walker Chen <walker.chen@starfivetech.com>
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
|
||||
@@ -14,4 +14,7 @@
|
||||
#define JH7110_PD_ISP 5
|
||||
#define JH7110_PD_VENC 6
|
||||
|
||||
+#define JH7110_PD_DPHY_TX 0
|
||||
+#define JH7110_PD_DPHY_RX 1
|
||||
+
|
||||
#endif
|
@ -0,0 +1,31 @@
|
||||
From 0ac8e8b0e65d242f455401df0cc6c6d4772216e6 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Wed, 13 Sep 2023 14:54:26 +0100
|
||||
Subject: [PATCH 040/116] pmdomain: starfive: Replace SOC_STARFIVE with
|
||||
ARCH_STARFIVE
|
||||
|
||||
Using ARCH_FOO symbol is preferred than SOC_FOO.
|
||||
|
||||
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20230913-legibly-treachery-567cffcb5604@spud
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/soc/starfive/Kconfig | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/soc/starfive/Kconfig
|
||||
+++ b/drivers/soc/starfive/Kconfig
|
||||
@@ -3,8 +3,8 @@
|
||||
config JH71XX_PMU
|
||||
bool "Support PMU for StarFive JH71XX Soc"
|
||||
depends on PM
|
||||
- depends on SOC_STARFIVE || COMPILE_TEST
|
||||
- default SOC_STARFIVE
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ default ARCH_STARFIVE
|
||||
select PM_GENERIC_DOMAINS
|
||||
help
|
||||
Say 'y' here to enable support power domain support.
|
@ -0,0 +1,179 @@
|
||||
From a1ba60e35ca7f1b85243054556ecde2e259619e1 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Wed, 13 Sep 2023 14:54:27 +0100
|
||||
Subject: [PATCH 041/116] pmdomain: starfive: Extract JH7110 pmu private
|
||||
operations
|
||||
|
||||
Move JH7110 private operation into private data of compatible. Convenient
|
||||
to add AON PMU which would not have interrupts property.
|
||||
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20230913-slideshow-luckiness-38ff17de84c6@spud
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/pmdomain/starfive/jh71xx-pmu.c | 89 ++++++++++++++++++--------
|
||||
1 file changed, 62 insertions(+), 27 deletions(-)
|
||||
|
||||
--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
|
||||
+++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
|
||||
@@ -51,9 +51,17 @@ struct jh71xx_domain_info {
|
||||
u8 bit;
|
||||
};
|
||||
|
||||
+struct jh71xx_pmu;
|
||||
+struct jh71xx_pmu_dev;
|
||||
+
|
||||
struct jh71xx_pmu_match_data {
|
||||
const struct jh71xx_domain_info *domain_info;
|
||||
int num_domains;
|
||||
+ unsigned int pmu_status;
|
||||
+ int (*pmu_parse_irq)(struct platform_device *pdev,
|
||||
+ struct jh71xx_pmu *pmu);
|
||||
+ int (*pmu_set_state)(struct jh71xx_pmu_dev *pmd,
|
||||
+ u32 mask, bool on);
|
||||
};
|
||||
|
||||
struct jh71xx_pmu {
|
||||
@@ -79,12 +87,12 @@ static int jh71xx_pmu_get_state(struct j
|
||||
if (!mask)
|
||||
return -EINVAL;
|
||||
|
||||
- *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
|
||||
+ *is_on = readl(pmu->base + pmu->match_data->pmu_status) & mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
+static int jh7110_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
{
|
||||
struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
unsigned long flags;
|
||||
@@ -92,22 +100,8 @@ static int jh71xx_pmu_set_state(struct j
|
||||
u32 mode;
|
||||
u32 encourage_lo;
|
||||
u32 encourage_hi;
|
||||
- bool is_on;
|
||||
int ret;
|
||||
|
||||
- ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
|
||||
- if (ret) {
|
||||
- dev_dbg(pmu->dev, "unable to get current state for %s\n",
|
||||
- pmd->genpd.name);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- if (is_on == on) {
|
||||
- dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
|
||||
- pmd->genpd.name, on ? "en" : "dis");
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
spin_lock_irqsave(&pmu->lock, flags);
|
||||
|
||||
/*
|
||||
@@ -166,6 +160,29 @@ static int jh71xx_pmu_set_state(struct j
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
+{
|
||||
+ struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
+ const struct jh71xx_pmu_match_data *match_data = pmu->match_data;
|
||||
+ bool is_on;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
|
||||
+ if (ret) {
|
||||
+ dev_dbg(pmu->dev, "unable to get current state for %s\n",
|
||||
+ pmd->genpd.name);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (is_on == on) {
|
||||
+ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
|
||||
+ pmd->genpd.name, on ? "en" : "dis");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return match_data->pmu_set_state(pmd, mask, on);
|
||||
+}
|
||||
+
|
||||
static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct jh71xx_pmu_dev *pmd = container_of(genpd,
|
||||
@@ -226,6 +243,25 @@ static irqreturn_t jh71xx_pmu_interrupt(
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static int jh7110_pmu_parse_irq(struct platform_device *pdev, struct jh71xx_pmu *pmu)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ pmu->irq = platform_get_irq(pdev, 0);
|
||||
+ if (pmu->irq < 0)
|
||||
+ return pmu->irq;
|
||||
+
|
||||
+ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
|
||||
+ 0, pdev->name, pmu);
|
||||
+ if (ret)
|
||||
+ dev_err(dev, "failed to request irq\n");
|
||||
+
|
||||
+ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
|
||||
{
|
||||
struct jh71xx_pmu_dev *pmd;
|
||||
@@ -275,19 +311,18 @@ static int jh71xx_pmu_probe(struct platf
|
||||
if (IS_ERR(pmu->base))
|
||||
return PTR_ERR(pmu->base);
|
||||
|
||||
- pmu->irq = platform_get_irq(pdev, 0);
|
||||
- if (pmu->irq < 0)
|
||||
- return pmu->irq;
|
||||
-
|
||||
- ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
|
||||
- 0, pdev->name, pmu);
|
||||
- if (ret)
|
||||
- dev_err(dev, "failed to request irq\n");
|
||||
+ spin_lock_init(&pmu->lock);
|
||||
|
||||
match_data = of_device_get_match_data(dev);
|
||||
if (!match_data)
|
||||
return -EINVAL;
|
||||
|
||||
+ ret = match_data->pmu_parse_irq(pdev, pmu);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to parse irq\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
|
||||
sizeof(struct generic_pm_domain *),
|
||||
GFP_KERNEL);
|
||||
@@ -307,9 +342,6 @@ static int jh71xx_pmu_probe(struct platf
|
||||
}
|
||||
}
|
||||
|
||||
- spin_lock_init(&pmu->lock);
|
||||
- jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
|
||||
-
|
||||
ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register genpd driver: %d\n", ret);
|
||||
@@ -357,6 +389,9 @@ static const struct jh71xx_domain_info j
|
||||
static const struct jh71xx_pmu_match_data jh7110_pmu = {
|
||||
.num_domains = ARRAY_SIZE(jh7110_power_domains),
|
||||
.domain_info = jh7110_power_domains,
|
||||
+ .pmu_status = JH71XX_PMU_CURR_POWER_MODE,
|
||||
+ .pmu_parse_irq = jh7110_pmu_parse_irq,
|
||||
+ .pmu_set_state = jh7110_pmu_set_state,
|
||||
};
|
||||
|
||||
static const struct of_device_id jh71xx_pmu_of_match[] = {
|
@ -0,0 +1,122 @@
|
||||
From 1bf849b606d0b4cae643f96685d3d3981643683d Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Wed, 13 Sep 2023 14:54:28 +0100
|
||||
Subject: [PATCH 042/116] pmdomain: starfive: Add JH7110 AON PMU support
|
||||
|
||||
Add AON PMU for StarFive JH7110 SoC. It can be used to turn on/off the
|
||||
dphy rx/tx power switch.
|
||||
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Link: https://lore.kernel.org/r/20230913-dude-imprecise-fc32622bc947@spud
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/pmdomain/starfive/jh71xx-pmu.c | 57 +++++++++++++++++++++++---
|
||||
1 file changed, 52 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
|
||||
+++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* StarFive JH71XX PMU (Power Management Unit) Controller Driver
|
||||
*
|
||||
- * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
@@ -24,6 +24,9 @@
|
||||
#define JH71XX_PMU_EVENT_STATUS 0x88
|
||||
#define JH71XX_PMU_INT_STATUS 0x8C
|
||||
|
||||
+/* aon pmu register offset */
|
||||
+#define JH71XX_AON_PMU_SWITCH 0x00
|
||||
+
|
||||
/* sw encourage cfg */
|
||||
#define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
|
||||
#define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
|
||||
@@ -160,6 +163,26 @@ static int jh7110_pmu_set_state(struct j
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int jh7110_aon_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
+{
|
||||
+ struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
+ unsigned long flags;
|
||||
+ u32 val;
|
||||
+
|
||||
+ spin_lock_irqsave(&pmu->lock, flags);
|
||||
+ val = readl(pmu->base + JH71XX_AON_PMU_SWITCH);
|
||||
+
|
||||
+ if (on)
|
||||
+ val |= mask;
|
||||
+ else
|
||||
+ val &= ~mask;
|
||||
+
|
||||
+ writel(val, pmu->base + JH71XX_AON_PMU_SWITCH);
|
||||
+ spin_unlock_irqrestore(&pmu->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
|
||||
{
|
||||
struct jh71xx_pmu *pmu = pmd->pmu;
|
||||
@@ -317,10 +340,12 @@ static int jh71xx_pmu_probe(struct platf
|
||||
if (!match_data)
|
||||
return -EINVAL;
|
||||
|
||||
- ret = match_data->pmu_parse_irq(pdev, pmu);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "failed to parse irq\n");
|
||||
- return ret;
|
||||
+ if (match_data->pmu_parse_irq) {
|
||||
+ ret = match_data->pmu_parse_irq(pdev, pmu);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to parse irq\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
|
||||
pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
|
||||
@@ -394,11 +419,32 @@ static const struct jh71xx_pmu_match_dat
|
||||
.pmu_set_state = jh7110_pmu_set_state,
|
||||
};
|
||||
|
||||
+static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
|
||||
+ [JH7110_PD_DPHY_TX] = {
|
||||
+ .name = "DPHY-TX",
|
||||
+ .bit = 30,
|
||||
+ },
|
||||
+ [JH7110_PD_DPHY_RX] = {
|
||||
+ .name = "DPHY-RX",
|
||||
+ .bit = 31,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct jh71xx_pmu_match_data jh7110_aon_pmu = {
|
||||
+ .num_domains = ARRAY_SIZE(jh7110_aon_power_domains),
|
||||
+ .domain_info = jh7110_aon_power_domains,
|
||||
+ .pmu_status = JH71XX_AON_PMU_SWITCH,
|
||||
+ .pmu_set_state = jh7110_aon_pmu_set_state,
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id jh71xx_pmu_of_match[] = {
|
||||
{
|
||||
.compatible = "starfive,jh7110-pmu",
|
||||
.data = (void *)&jh7110_pmu,
|
||||
}, {
|
||||
+ .compatible = "starfive,jh7110-aon-syscon",
|
||||
+ .data = (void *)&jh7110_aon_pmu,
|
||||
+ }, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
@@ -414,5 +460,6 @@ static struct platform_driver jh71xx_pmu
|
||||
builtin_platform_driver(jh71xx_pmu_driver);
|
||||
|
||||
MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
|
||||
+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
|
||||
MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,36 @@
|
||||
From dff6605dcd1fc1e2af1437e59187a6f71ce389cd Mon Sep 17 00:00:00 2001
|
||||
From: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Date: Mon, 11 Sep 2023 17:22:15 +0200
|
||||
Subject: [PATCH 043/116] pmdomain: Prepare to move Kconfig files into the
|
||||
pmdomain subsystem
|
||||
|
||||
Rather than having the various Kconfig files for the genpd providers
|
||||
sprinkled across subsystems, let's prepare to move them into the pmdomain
|
||||
subsystem along with the implementations.
|
||||
|
||||
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/Kconfig | 2 ++
|
||||
drivers/pmdomain/Kconfig | 4 ++++
|
||||
2 files changed, 6 insertions(+)
|
||||
create mode 100644 drivers/pmdomain/Kconfig
|
||||
|
||||
--- a/drivers/Kconfig
|
||||
+++ b/drivers/Kconfig
|
||||
@@ -175,6 +175,8 @@ source "drivers/soundwire/Kconfig"
|
||||
|
||||
source "drivers/soc/Kconfig"
|
||||
|
||||
+source "drivers/pmdomain/Kconfig"
|
||||
+
|
||||
source "drivers/devfreq/Kconfig"
|
||||
|
||||
source "drivers/extcon/Kconfig"
|
||||
--- /dev/null
|
||||
+++ b/drivers/pmdomain/Kconfig
|
||||
@@ -0,0 +1,4 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only
|
||||
+menu "PM Domains"
|
||||
+
|
||||
+endmenu
|
@ -0,0 +1,69 @@
|
||||
From de12fe43dbd0ea9fa980ffa05822bd7fd5eed330 Mon Sep 17 00:00:00 2001
|
||||
From: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Date: Tue, 12 Sep 2023 13:31:44 +0200
|
||||
Subject: [PATCH 044/116] pmdomain: starfive: Move Kconfig file to the pmdomain
|
||||
subsystem
|
||||
|
||||
The Kconfig belongs closer to the corresponding implementation, hence let's
|
||||
move it from the soc subsystem to the pmdomain subsystem.
|
||||
|
||||
Cc: Walker Chen <walker.chen@starfivetech.com>
|
||||
Cc: Conor Dooley <conor@kernel.org>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/pmdomain/Kconfig | 2 ++
|
||||
drivers/{soc => pmdomain}/starfive/Kconfig | 0
|
||||
drivers/soc/Kconfig | 1 -
|
||||
3 files changed, 2 insertions(+), 1 deletion(-)
|
||||
rename drivers/{soc => pmdomain}/starfive/Kconfig (100%)
|
||||
|
||||
--- a/drivers/pmdomain/Kconfig
|
||||
+++ b/drivers/pmdomain/Kconfig
|
||||
@@ -1,4 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
menu "PM Domains"
|
||||
|
||||
+source "drivers/pmdomain/starfive/Kconfig"
|
||||
+
|
||||
endmenu
|
||||
--- a/drivers/soc/Kconfig
|
||||
+++ b/drivers/soc/Kconfig
|
||||
@@ -24,7 +24,6 @@ source "drivers/soc/renesas/Kconfig"
|
||||
source "drivers/soc/rockchip/Kconfig"
|
||||
source "drivers/soc/samsung/Kconfig"
|
||||
source "drivers/soc/sifive/Kconfig"
|
||||
-source "drivers/soc/starfive/Kconfig"
|
||||
source "drivers/soc/sunxi/Kconfig"
|
||||
source "drivers/soc/tegra/Kconfig"
|
||||
source "drivers/soc/ti/Kconfig"
|
||||
--- /dev/null
|
||||
+++ b/drivers/pmdomain/starfive/Kconfig
|
||||
@@ -0,0 +1,12 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+config JH71XX_PMU
|
||||
+ bool "Support PMU for StarFive JH71XX Soc"
|
||||
+ depends on PM
|
||||
+ depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
+ default ARCH_STARFIVE
|
||||
+ select PM_GENERIC_DOMAINS
|
||||
+ help
|
||||
+ Say 'y' here to enable support power domain support.
|
||||
+ In order to meet low power requirements, a Power Management Unit (PMU)
|
||||
+ is designed for controlling power resources in StarFive JH71XX SoCs.
|
||||
--- a/drivers/soc/starfive/Kconfig
|
||||
+++ /dev/null
|
||||
@@ -1,12 +0,0 @@
|
||||
-# SPDX-License-Identifier: GPL-2.0
|
||||
-
|
||||
-config JH71XX_PMU
|
||||
- bool "Support PMU for StarFive JH71XX Soc"
|
||||
- depends on PM
|
||||
- depends on ARCH_STARFIVE || COMPILE_TEST
|
||||
- default ARCH_STARFIVE
|
||||
- select PM_GENERIC_DOMAINS
|
||||
- help
|
||||
- Say 'y' here to enable support power domain support.
|
||||
- In order to meet low power requirements, a Power Management Unit (PMU)
|
||||
- is designed for controlling power resources in StarFive JH71XX SoCs.
|
@ -0,0 +1,31 @@
|
||||
From cac9ce9c7f388a741389b1ec47af65420254db55 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Wed, 27 Sep 2023 06:07:33 -0700
|
||||
Subject: [PATCH 045/116] dt-bindings: power: Update prefixes for AON power
|
||||
domain
|
||||
|
||||
Use "JH7110_AON_PD_" prefix for AON power domain for JH7110 SoC.
|
||||
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Link: https://lore.kernel.org/r/20230927130734.9921-2-changhuang.liang@starfivetech.com
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
include/dt-bindings/power/starfive,jh7110-pmu.h | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
+++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
@@ -14,7 +14,8 @@
|
||||
#define JH7110_PD_ISP 5
|
||||
#define JH7110_PD_VENC 6
|
||||
|
||||
-#define JH7110_PD_DPHY_TX 0
|
||||
-#define JH7110_PD_DPHY_RX 1
|
||||
+/* AON Power Domain */
|
||||
+#define JH7110_AON_PD_DPHY_TX 0
|
||||
+#define JH7110_AON_PD_DPHY_RX 1
|
||||
|
||||
#endif
|
@ -0,0 +1,32 @@
|
||||
From 3ea89ffbd6cc5a15acca6bc2130572f8bd85b9d4 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Wed, 27 Sep 2023 06:07:34 -0700
|
||||
Subject: [PATCH 046/116] pmdomain: starfive: Update prefixes for AON power
|
||||
domain
|
||||
|
||||
Use "JH7110_AON_PD_" prefix for AON power doamin for JH7110 SoC.
|
||||
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Link: https://lore.kernel.org/r/20230927130734.9921-3-changhuang.liang@starfivetech.com
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
drivers/pmdomain/starfive/jh71xx-pmu.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
|
||||
+++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
|
||||
@@ -420,11 +420,11 @@ static const struct jh71xx_pmu_match_dat
|
||||
};
|
||||
|
||||
static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
|
||||
- [JH7110_PD_DPHY_TX] = {
|
||||
+ [JH7110_AON_PD_DPHY_TX] = {
|
||||
.name = "DPHY-TX",
|
||||
.bit = 30,
|
||||
},
|
||||
- [JH7110_PD_DPHY_RX] = {
|
||||
+ [JH7110_AON_PD_DPHY_RX] = {
|
||||
.name = "DPHY-RX",
|
||||
.bit = 31,
|
||||
},
|
@ -0,0 +1,30 @@
|
||||
From e7e3d62b7a470ddf15e30574232b52b2e23ba606 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Mon, 21 Aug 2023 22:41:50 +0800
|
||||
Subject: [PATCH 047/116] riscv: dts: starfive: pinfunc: Fix the pins name of
|
||||
I2STX1
|
||||
|
||||
These pins are actually I2STX1 clock input, not I2STX0,
|
||||
so their names should be changed.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
---
|
||||
arch/riscv/boot/dts/starfive/jh7110-pinfunc.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
|
||||
@@ -240,8 +240,8 @@
|
||||
#define GPI_SYS_MCLK_EXT 30
|
||||
#define GPI_SYS_I2SRX_BCLK 31
|
||||
#define GPI_SYS_I2SRX_LRCK 32
|
||||
-#define GPI_SYS_I2STX0_BCLK 33
|
||||
-#define GPI_SYS_I2STX0_LRCK 34
|
||||
+#define GPI_SYS_I2STX1_BCLK 33
|
||||
+#define GPI_SYS_I2STX1_LRCK 34
|
||||
#define GPI_SYS_TDM_CLK 35
|
||||
#define GPI_SYS_TDM_RXD 36
|
||||
#define GPI_SYS_TDM_SYNC 37
|
@ -0,0 +1,549 @@
|
||||
From a3d3f611f31fa2dca3deefa7cd443abca02e03fa Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Tue, 11 Apr 2023 16:31:15 +0800
|
||||
Subject: [PATCH 048/116] riscv: dts: starfive: Add full support (except VIN
|
||||
and VOUT) for JH7110 and VisionFive 2 board
|
||||
|
||||
Merge all StarFive dts patches together except VIN and VOUT.
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
.../jh7110-starfive-visionfive-2.dtsi | 199 +++++++++++++++
|
||||
arch/riscv/boot/dts/starfive/jh7110.dtsi | 233 ++++++++++++++++++
|
||||
2 files changed, 432 insertions(+)
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
|
||||
@@ -19,6 +19,8 @@
|
||||
i2c6 = &i2c6;
|
||||
mmc0 = &mmc0;
|
||||
mmc1 = &mmc1;
|
||||
+ pcie0 = &pcie0;
|
||||
+ pcie1 = &pcie1;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
@@ -40,6 +42,33 @@
|
||||
gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
|
||||
priority = <224>;
|
||||
};
|
||||
+
|
||||
+ pwmdac_codec: pwmdac-codec {
|
||||
+ compatible = "linux,spdif-dit";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ sound-pwmdac {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ reg = <0>;
|
||||
+ format = "left_j";
|
||||
+ bitclock-master = <&sndcpu0>;
|
||||
+ frame-master = <&sndcpu0>;
|
||||
+
|
||||
+ sndcpu0: cpu {
|
||||
+ sound-dai = <&pwmdac>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&pwmdac_codec>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&dvp_clk {
|
||||
@@ -202,8 +231,28 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&i2srx {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2srx_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2stx0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&mclk_ext_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2stx1 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2stx1_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
max-frequency = <100000000>;
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
bus-width = <8>;
|
||||
cap-mmc-highspeed;
|
||||
mmc-ddr-1_8v;
|
||||
@@ -220,6 +269,8 @@
|
||||
|
||||
&mmc1 {
|
||||
max-frequency = <100000000>;
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO1_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
bus-width = <4>;
|
||||
no-sdio;
|
||||
no-mmc;
|
||||
@@ -231,6 +282,34 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&pcie0 {
|
||||
+ perst-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>;
|
||||
+ phys = <&pciephy0>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pcie0_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie1 {
|
||||
+ perst-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>;
|
||||
+ phys = <&pciephy1>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pcie1_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pwm {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pwm_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pwmdac {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pwmdac_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&qspi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -336,6 +415,46 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ i2srx_pins: i2srx-0 {
|
||||
+ clk-sd-pins {
|
||||
+ pinmux = <GPIOMUX(38, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_SYS_I2SRX_BCLK)>,
|
||||
+ <GPIOMUX(63, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_SYS_I2SRX_LRCK)>,
|
||||
+ <GPIOMUX(38, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_SYS_I2STX1_BCLK)>,
|
||||
+ <GPIOMUX(63, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_SYS_I2STX1_LRCK)>,
|
||||
+ <GPIOMUX(61, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_SYS_I2SRX_SDIN0)>;
|
||||
+ input-enable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ i2stx1_pins: i2stx1-0 {
|
||||
+ sd-pins {
|
||||
+ pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
|
||||
+ GPOEN_ENABLE,
|
||||
+ GPI_NONE)>;
|
||||
+ bias-disable;
|
||||
+ input-disable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ mclk_ext_pins: mclk-ext-0 {
|
||||
+ mclk-ext-pins {
|
||||
+ pinmux = <GPIOMUX(4, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_SYS_MCLK_EXT)>;
|
||||
+ input-enable;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
mmc0_pins: mmc0-0 {
|
||||
rst-pins {
|
||||
pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
|
||||
@@ -400,6 +519,86 @@
|
||||
slew-rate = <0>;
|
||||
};
|
||||
};
|
||||
+
|
||||
+ pcie0_pins: pcie0-0 {
|
||||
+ clkreq-pins {
|
||||
+ pinmux = <GPIOMUX(27, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_NONE)>;
|
||||
+ bias-pull-down;
|
||||
+ drive-strength = <2>;
|
||||
+ input-enable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+
|
||||
+ wake-pins {
|
||||
+ pinmux = <GPIOMUX(32, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_NONE)>;
|
||||
+ bias-pull-up;
|
||||
+ drive-strength = <2>;
|
||||
+ input-enable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pcie1_pins: pcie1-0 {
|
||||
+ clkreq-pins {
|
||||
+ pinmux = <GPIOMUX(29, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_NONE)>;
|
||||
+ bias-pull-down;
|
||||
+ drive-strength = <2>;
|
||||
+ input-enable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+
|
||||
+ wake-pins {
|
||||
+ pinmux = <GPIOMUX(21, GPOUT_LOW,
|
||||
+ GPOEN_DISABLE,
|
||||
+ GPI_NONE)>;
|
||||
+ bias-pull-up;
|
||||
+ drive-strength = <2>;
|
||||
+ input-enable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pwm_pins: pwm-0 {
|
||||
+ pwm-pins {
|
||||
+ pinmux = <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL0,
|
||||
+ GPOEN_SYS_PWM0_CHANNEL0,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1,
|
||||
+ GPOEN_SYS_PWM0_CHANNEL1,
|
||||
+ GPI_NONE)>;
|
||||
+ bias-disable;
|
||||
+ drive-strength = <12>;
|
||||
+ input-disable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pwmdac_pins: pwmdac-0 {
|
||||
+ pwmdac-pins {
|
||||
+ pinmux = <GPIOMUX(33, GPOUT_SYS_PWMDAC_LEFT,
|
||||
+ GPOEN_ENABLE,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(34, GPOUT_SYS_PWMDAC_RIGHT,
|
||||
+ GPOEN_ENABLE,
|
||||
+ GPI_NONE)>;
|
||||
+ bias-disable;
|
||||
+ drive-strength = <2>;
|
||||
+ input-disable;
|
||||
+ input-schmitt-disable;
|
||||
+ slew-rate = <0>;
|
||||
+ };
|
||||
+ };
|
||||
|
||||
spi0_pins: spi0-0 {
|
||||
mosi-pins {
|
||||
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
|
||||
@@ -244,6 +244,7 @@
|
||||
clock-output-names = "dvp_clk";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
+
|
||||
gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
|
||||
compatible = "fixed-clock";
|
||||
clock-output-names = "gmac0_rgmii_rxin";
|
||||
@@ -512,6 +513,43 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ pwmdac: pwmdac@100b0000 {
|
||||
+ compatible = "starfive,jh7110-pwmdac";
|
||||
+ reg = <0x0 0x100b0000 0x0 0x1000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_PWMDAC_APB>,
|
||||
+ <&syscrg JH7110_SYSCLK_PWMDAC_CORE>;
|
||||
+ clock-names = "apb", "core";
|
||||
+ resets = <&syscrg JH7110_SYSRST_PWMDAC_APB>;
|
||||
+ dmas = <&dma 22>;
|
||||
+ dma-names = "tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2srx: i2s@100e0000 {
|
||||
+ compatible = "starfive,jh7110-i2srx";
|
||||
+ reg = <0x0 0x100e0000 0x0 0x1000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2SRX_BCLK_MST>,
|
||||
+ <&syscrg JH7110_SYSCLK_I2SRX_APB>,
|
||||
+ <&syscrg JH7110_SYSCLK_MCLK>,
|
||||
+ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
|
||||
+ <&mclk_ext>,
|
||||
+ <&syscrg JH7110_SYSCLK_I2SRX_BCLK>,
|
||||
+ <&syscrg JH7110_SYSCLK_I2SRX_LRCK>,
|
||||
+ <&i2srx_bclk_ext>,
|
||||
+ <&i2srx_lrck_ext>;
|
||||
+ clock-names = "i2sclk", "apb", "mclk",
|
||||
+ "mclk_inner", "mclk_ext", "bclk",
|
||||
+ "lrck", "bclk_ext", "lrck_ext";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2SRX_APB>,
|
||||
+ <&syscrg JH7110_SYSRST_I2SRX_BCLK>;
|
||||
+ dmas = <0>, <&dma 24>;
|
||||
+ dma-names = "tx", "rx";
|
||||
+ starfive,syscon = <&sys_syscon 0x18 0x2>;
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
usb0: usb@10100000 {
|
||||
compatible = "starfive,jh7110-usb";
|
||||
ranges = <0x0 0x0 0x10100000 0x100000>;
|
||||
@@ -736,6 +774,56 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ i2stx0: i2s@120b0000 {
|
||||
+ compatible = "starfive,jh7110-i2stx0";
|
||||
+ reg = <0x0 0x120b0000 0x0 0x1000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2STX0_BCLK_MST>,
|
||||
+ <&syscrg JH7110_SYSCLK_I2STX0_APB>,
|
||||
+ <&syscrg JH7110_SYSCLK_MCLK>,
|
||||
+ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
|
||||
+ <&mclk_ext>;
|
||||
+ clock-names = "i2sclk", "apb", "mclk",
|
||||
+ "mclk_inner","mclk_ext";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2STX0_APB>,
|
||||
+ <&syscrg JH7110_SYSRST_I2STX0_BCLK>;
|
||||
+ dmas = <&dma 47>;
|
||||
+ dma-names = "tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2stx1: i2s@120c0000 {
|
||||
+ compatible = "starfive,jh7110-i2stx1";
|
||||
+ reg = <0x0 0x120c0000 0x0 0x1000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_I2STX1_BCLK_MST>,
|
||||
+ <&syscrg JH7110_SYSCLK_I2STX1_APB>,
|
||||
+ <&syscrg JH7110_SYSCLK_MCLK>,
|
||||
+ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
|
||||
+ <&mclk_ext>,
|
||||
+ <&syscrg JH7110_SYSCLK_I2STX1_BCLK>,
|
||||
+ <&syscrg JH7110_SYSCLK_I2STX1_LRCK>,
|
||||
+ <&i2stx_bclk_ext>,
|
||||
+ <&i2stx_lrck_ext>;
|
||||
+ clock-names = "i2sclk", "apb", "mclk",
|
||||
+ "mclk_inner", "mclk_ext", "bclk",
|
||||
+ "lrck", "bclk_ext", "lrck_ext";
|
||||
+ resets = <&syscrg JH7110_SYSRST_I2STX1_APB>,
|
||||
+ <&syscrg JH7110_SYSRST_I2STX1_BCLK>;
|
||||
+ dmas = <&dma 48>;
|
||||
+ dma-names = "tx";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ pwm: pwm@120d0000 {
|
||||
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
|
||||
+ reg = <0x0 0x120d0000 0x0 0x10000>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
|
||||
+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
|
||||
+ #pwm-cells = <3>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
sfctemp: temperature-sensor@120e0000 {
|
||||
compatible = "starfive,jh7110-temp";
|
||||
reg = <0x0 0x120e0000 0x0 0x10000>;
|
||||
@@ -811,6 +899,26 @@
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
+ timer@13050000 {
|
||||
+ compatible = "starfive,jh7110-timer";
|
||||
+ reg = <0x0 0x13050000 0x0 0x10000>;
|
||||
+ interrupts = <69>, <70>, <71>, <72>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_TIMER_APB>,
|
||||
+ <&syscrg JH7110_SYSCLK_TIMER0>,
|
||||
+ <&syscrg JH7110_SYSCLK_TIMER1>,
|
||||
+ <&syscrg JH7110_SYSCLK_TIMER2>,
|
||||
+ <&syscrg JH7110_SYSCLK_TIMER3>;
|
||||
+ clock-names = "apb", "ch0", "ch1",
|
||||
+ "ch2", "ch3";
|
||||
+ resets = <&syscrg JH7110_SYSRST_TIMER_APB>,
|
||||
+ <&syscrg JH7110_SYSRST_TIMER0>,
|
||||
+ <&syscrg JH7110_SYSRST_TIMER1>,
|
||||
+ <&syscrg JH7110_SYSRST_TIMER2>,
|
||||
+ <&syscrg JH7110_SYSRST_TIMER3>;
|
||||
+ reset-names = "apb", "ch0", "ch1",
|
||||
+ "ch2", "ch3";
|
||||
+ };
|
||||
+
|
||||
watchdog@13070000 {
|
||||
compatible = "starfive,jh7110-wdt";
|
||||
reg = <0x0 0x13070000 0x0 0x10000>;
|
||||
@@ -1011,6 +1119,32 @@
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
+ csi2rx: csi-bridge@19800000 {
|
||||
+ compatible = "starfive,jh7110-csi2rx";
|
||||
+ reg = <0x0 0x19800000 0x0 0x10000>;
|
||||
+ clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>,
|
||||
+ <&ispcrg JH7110_ISPCLK_VIN_APB>,
|
||||
+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF0>,
|
||||
+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF1>,
|
||||
+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF2>,
|
||||
+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF3>;
|
||||
+ clock-names = "sys_clk", "p_clk",
|
||||
+ "pixel_if0_clk", "pixel_if1_clk",
|
||||
+ "pixel_if2_clk", "pixel_if3_clk";
|
||||
+ resets = <&ispcrg JH7110_ISPRST_VIN_SYS>,
|
||||
+ <&ispcrg JH7110_ISPRST_VIN_APB>,
|
||||
+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF0>,
|
||||
+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF1>,
|
||||
+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF2>,
|
||||
+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF3>;
|
||||
+ reset-names = "sys", "reg_bank",
|
||||
+ "pixel_if0", "pixel_if1",
|
||||
+ "pixel_if2", "pixel_if3";
|
||||
+ phys = <&csi_phy>;
|
||||
+ phy-names = "dphy";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
ispcrg: clock-controller@19810000 {
|
||||
compatible = "starfive,jh7110-ispcrg";
|
||||
reg = <0x0 0x19810000 0x0 0x10000>;
|
||||
@@ -1028,6 +1162,19 @@
|
||||
power-domains = <&pwrc JH7110_PD_ISP>;
|
||||
};
|
||||
|
||||
+ csi_phy: phy@19820000 {
|
||||
+ compatible = "starfive,jh7110-dphy-rx";
|
||||
+ reg = <0x0 0x19820000 0x0 0x10000>;
|
||||
+ clocks = <&ispcrg JH7110_ISPCLK_M31DPHY_CFG_IN>,
|
||||
+ <&ispcrg JH7110_ISPCLK_M31DPHY_REF_IN>,
|
||||
+ <&ispcrg JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0>;
|
||||
+ clock-names = "cfg", "ref", "tx";
|
||||
+ resets = <&ispcrg JH7110_ISPRST_M31DPHY_HW>,
|
||||
+ <&ispcrg JH7110_ISPRST_M31DPHY_B09_AON>;
|
||||
+ power-domains = <&aon_syscon JH7110_AON_PD_DPHY_RX>;
|
||||
+ #phy-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
voutcrg: clock-controller@295c0000 {
|
||||
compatible = "starfive,jh7110-voutcrg";
|
||||
reg = <0x0 0x295c0000 0x0 0x10000>;
|
||||
@@ -1045,5 +1192,91 @@
|
||||
#reset-cells = <1>;
|
||||
power-domains = <&pwrc JH7110_PD_VOUT>;
|
||||
};
|
||||
+
|
||||
+ pcie0: pcie@940000000 {
|
||||
+ compatible = "starfive,jh7110-pcie";
|
||||
+ reg = <0x9 0x40000000 0x0 0x1000000>,
|
||||
+ <0x0 0x2b000000 0x0 0x100000>;
|
||||
+ reg-names = "cfg", "apb";
|
||||
+ linux,pci-domain = <0>;
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
|
||||
+ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
|
||||
+ interrupts = <56>;
|
||||
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
|
||||
+ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
|
||||
+ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
|
||||
+ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
|
||||
+ msi-controller;
|
||||
+ device_type = "pci";
|
||||
+ starfive,stg-syscon = <&stg_syscon>;
|
||||
+ bus-range = <0x0 0xff>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
|
||||
+ <&stgcrg JH7110_STGCLK_PCIE0_TL>,
|
||||
+ <&stgcrg JH7110_STGCLK_PCIE0_AXI_MST0>,
|
||||
+ <&stgcrg JH7110_STGCLK_PCIE0_APB>;
|
||||
+ clock-names = "noc", "tl", "axi_mst0", "apb";
|
||||
+ resets = <&stgcrg JH7110_STGRST_PCIE0_AXI_MST0>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV0>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE0_BRG>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE0_CORE>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE0_APB>;
|
||||
+ reset-names = "mst0", "slv0", "slv", "brg",
|
||||
+ "core", "apb";
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ pcie_intc0: interrupt-controller {
|
||||
+ #address-cells = <0>;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ interrupt-controller;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pcie1: pcie@9c0000000 {
|
||||
+ compatible = "starfive,jh7110-pcie";
|
||||
+ reg = <0x9 0xc0000000 0x0 0x1000000>,
|
||||
+ <0x0 0x2c000000 0x0 0x100000>;
|
||||
+ reg-names = "cfg", "apb";
|
||||
+ linux,pci-domain = <1>;
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ ranges = <0x82000000 0x0 0x38000000 0x0 0x38000000 0x0 0x08000000>,
|
||||
+ <0xc3000000 0x9 0x80000000 0x9 0x80000000 0x0 0x40000000>;
|
||||
+ interrupts = <57>;
|
||||
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc1 0x1>,
|
||||
+ <0x0 0x0 0x0 0x2 &pcie_intc1 0x2>,
|
||||
+ <0x0 0x0 0x0 0x3 &pcie_intc1 0x3>,
|
||||
+ <0x0 0x0 0x0 0x4 &pcie_intc1 0x4>;
|
||||
+ msi-controller;
|
||||
+ device_type = "pci";
|
||||
+ starfive,stg-syscon = <&stg_syscon>;
|
||||
+ bus-range = <0x0 0xff>;
|
||||
+ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
|
||||
+ <&stgcrg JH7110_STGCLK_PCIE1_TL>,
|
||||
+ <&stgcrg JH7110_STGCLK_PCIE1_AXI_MST0>,
|
||||
+ <&stgcrg JH7110_STGCLK_PCIE1_APB>;
|
||||
+ clock-names = "noc", "tl", "axi_mst0", "apb";
|
||||
+ resets = <&stgcrg JH7110_STGRST_PCIE1_AXI_MST0>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV0>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE1_BRG>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE1_CORE>,
|
||||
+ <&stgcrg JH7110_STGRST_PCIE1_APB>;
|
||||
+ reset-names = "mst0", "slv0", "slv", "brg",
|
||||
+ "core", "apb";
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ pcie_intc1: interrupt-controller {
|
||||
+ #address-cells = <0>;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ interrupt-controller;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
};
|
@ -0,0 +1,147 @@
|
||||
From ae7b57a0c69953f5ec06a378aedeed4c86637998 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Tue, 11 Apr 2023 16:25:57 +0800
|
||||
Subject: [PATCH 049/116] MAINTAINERS: Update all StarFive entries
|
||||
|
||||
Merge all StarFive maintainers changes together.
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
MAINTAINERS | 61 +++++++++++++++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 57 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -7053,6 +7053,14 @@ T: git git://anongit.freedesktop.org/drm
|
||||
F: Documentation/devicetree/bindings/display/rockchip/
|
||||
F: drivers/gpu/drm/rockchip/
|
||||
|
||||
+DRM DRIVERS FOR STARFIVE
|
||||
+M: Keith Zhao <keith.zhao@starfivetech.com>
|
||||
+L: dri-devel@lists.freedesktop.org
|
||||
+S: Maintained
|
||||
+T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
+F: Documentation/devicetree/bindings/display/starfive/
|
||||
+F: drivers/gpu/drm/verisilicon/
|
||||
+
|
||||
DRM DRIVERS FOR STI
|
||||
M: Alain Volmat <alain.volmat@foss.st.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
@@ -16016,6 +16024,13 @@ F: Documentation/i2c/busses/i2c-ocores.r
|
||||
F: drivers/i2c/busses/i2c-ocores.c
|
||||
F: include/linux/platform_data/i2c-ocores.h
|
||||
|
||||
+OPENCORES PWM DRIVER
|
||||
+M: William Qiu <william.qiu@starfivetech.com>
|
||||
+M: Hal Feng <hal.feng@starfivetech.com>
|
||||
+S: Supported
|
||||
+F: Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
|
||||
+F: drivers/pwm/pwm-ocores.c
|
||||
+
|
||||
OPENRISC ARCHITECTURE
|
||||
M: Jonas Bonn <jonas@southpole.se>
|
||||
M: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
|
||||
@@ -16427,6 +16442,14 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
|
||||
F: drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
|
||||
|
||||
+PCI DRIVER FOR PLDA PCIE IP
|
||||
+M: Daire McNamara <daire.mcnamara@microchip.com>
|
||||
+M: Kevin Xie <kevin.xie@starfivetech.com>
|
||||
+L: linux-pci@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: Documentation/devicetree/bindings/pci/plda,*
|
||||
+F: drivers/pci/controller/plda/*plda*
|
||||
+
|
||||
PCI DRIVER FOR RENESAS R-CAR
|
||||
M: Marek Vasut <marek.vasut+renesas@gmail.com>
|
||||
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
||||
@@ -16658,7 +16681,7 @@ M: Daire McNamara <daire.mcnamara@microc
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/pci/microchip*
|
||||
-F: drivers/pci/controller/*microchip*
|
||||
+F: drivers/pci/controller/plda/*microchip*
|
||||
|
||||
PCIE DRIVER FOR QUALCOMM MSM
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
@@ -16682,6 +16705,13 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/socionext,uniphier-pcie*
|
||||
F: drivers/pci/controller/dwc/pcie-uniphier*
|
||||
|
||||
+PCIE DRIVER FOR STARFIVE JH71x0
|
||||
+M: Kevin Xie <kevin.xie@starfivetech.com>
|
||||
+L: linux-pci@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: Documentation/devicetree/bindings/pci/starfive*
|
||||
+F: drivers/pci/controller/plda/pcie-starfive.c
|
||||
+
|
||||
PCIE DRIVER FOR ST SPEAR13XX
|
||||
M: Pratyush Anand <pratyush.anand@gmail.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
@@ -18454,7 +18484,7 @@ F: drivers/char/hw_random/mpfs-rng.c
|
||||
F: drivers/clk/microchip/clk-mpfs*.c
|
||||
F: drivers/i2c/busses/i2c-microchip-corei2c.c
|
||||
F: drivers/mailbox/mailbox-mpfs.c
|
||||
-F: drivers/pci/controller/pcie-microchip-host.c
|
||||
+F: drivers/pci/controller/plda/pcie-microchip-host.c
|
||||
F: drivers/pwm/pwm-microchip-core.c
|
||||
F: drivers/reset/reset-mpfs.c
|
||||
F: drivers/rtc/rtc-mpfs.c
|
||||
@@ -20435,6 +20465,15 @@ M: Ion Badulescu <ionut@badula.org>
|
||||
S: Odd Fixes
|
||||
F: drivers/net/ethernet/adaptec/starfire*
|
||||
|
||||
+STARFIVE CAMERA SUBSYSTEM DRIVER
|
||||
+M: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
+M: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
+L: linux-media@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: Documentation/admin-guide/media/starfive_camss.rst
|
||||
+F: Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
|
||||
+F: drivers/staging/media/starfive/camss
|
||||
+
|
||||
STARFIVE CRYPTO DRIVER
|
||||
M: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
||||
M: William Qiu <william.qiu@starfivetech.com>
|
||||
@@ -20473,6 +20512,13 @@ S: Supported
|
||||
F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
|
||||
F: drivers/clk/starfive/clk-starfive-jh7110-pll.c
|
||||
|
||||
+STARFIVE JH7110 PWMDAC DRIVER
|
||||
+M: Hal Feng <hal.feng@starfivetech.com>
|
||||
+M: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+S: Supported
|
||||
+F: Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
|
||||
+F: sound/soc/starfive/jh7110_pwmdac.c
|
||||
+
|
||||
STARFIVE JH7110 SYSCON
|
||||
M: William Qiu <william.qiu@starfivetech.com>
|
||||
M: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
@@ -20520,9 +20566,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c
|
||||
|
||||
STARFIVE JH71XX PMU CONTROLLER DRIVER
|
||||
M: Walker Chen <walker.chen@starfivetech.com>
|
||||
+M: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/power/starfive*
|
||||
-F: drivers/pmdomain/starfive/jh71xx-pmu.c
|
||||
+F: drivers/pmdomain/starfive/
|
||||
F: include/dt-bindings/power/starfive,jh7110-pmu.h
|
||||
|
||||
STARFIVE SOC DRIVERS
|
||||
@@ -20530,7 +20577,13 @@ M: Conor Dooley <conor@kernel.org>
|
||||
S: Maintained
|
||||
T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
|
||||
F: Documentation/devicetree/bindings/soc/starfive/
|
||||
-F: drivers/soc/starfive/
|
||||
+
|
||||
+STARFIVE JH7110 TIMER DRIVER
|
||||
+M: Samin Guo <samin.guo@starfivetech.com>
|
||||
+M: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
+S: Supported
|
||||
+F: Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
|
||||
+F: drivers/clocksource/timer-jh7110.c
|
||||
|
||||
STARFIVE TRNG DRIVER
|
||||
M: Jia Jie Ho <jiajie.ho@starfivetech.com>
|
@ -0,0 +1,64 @@
|
||||
From e394195396995456ef98f52ac123c0cb64687748 Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Mon, 9 Oct 2023 10:59:03 +0800
|
||||
Subject: [PATCH 050/116] mmc: starfive: Change the voltage to adapt to JH7110
|
||||
EVB
|
||||
|
||||
Change the voltage, so the driver can adapt to JH7110 EVB.
|
||||
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
drivers/mmc/host/dw_mmc-starfive.c | 30 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
--- a/drivers/mmc/host/dw_mmc-starfive.c
|
||||
+++ b/drivers/mmc/host/dw_mmc-starfive.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
+#include <linux/gpio.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/module.h>
|
||||
@@ -95,10 +96,39 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int dw_mci_starfive_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
+{
|
||||
+
|
||||
+ struct dw_mci_slot *slot = mmc_priv(mmc);
|
||||
+ struct dw_mci *host = slot->host;
|
||||
+ u32 ret;
|
||||
+
|
||||
+ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
|
||||
+ ret = gpio_direction_output(25, 0);
|
||||
+ else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
|
||||
+ ret = gpio_direction_output(25, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!IS_ERR(mmc->supply.vqmmc)) {
|
||||
+ ret = mmc_regulator_set_vqmmc(mmc, ios);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(host->dev, "Regulator set error %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* We should delay 20ms wait for timing setting finished. */
|
||||
+ mdelay(20);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct dw_mci_drv_data starfive_data = {
|
||||
.common_caps = MMC_CAP_CMD23,
|
||||
.set_ios = dw_mci_starfive_set_ios,
|
||||
.execute_tuning = dw_mci_starfive_execute_tuning,
|
||||
+ .switch_voltage = dw_mci_starfive_switch_voltage,
|
||||
};
|
||||
|
||||
static const struct of_device_id dw_mci_starfive_match[] = {
|
@ -0,0 +1,60 @@
|
||||
From 2cd3e51cb76d49d8db6274ebdc1ba1eb5c872f10 Mon Sep 17 00:00:00 2001
|
||||
From: "ziv.xu" <ziv.xu@starfivetech.com>
|
||||
Date: Sun, 4 Feb 2024 10:35:24 +0800
|
||||
Subject: [PATCH 051/116] spi: spl022: Get and deassert reset in probe()
|
||||
|
||||
This fix spi1~6 communication time out.
|
||||
|
||||
Signed-off-by: ziv.xu <ziv.xu@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
drivers/spi/spi-pl022.c | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
--- a/drivers/spi/spi-pl022.c
|
||||
+++ b/drivers/spi/spi-pl022.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
+#include <linux/reset.h>
|
||||
|
||||
/*
|
||||
* This macro is used to define some register default values.
|
||||
@@ -370,6 +371,7 @@ struct pl022 {
|
||||
resource_size_t phybase;
|
||||
void __iomem *virtbase;
|
||||
struct clk *clk;
|
||||
+ struct reset_control *rst;
|
||||
struct spi_controller *host;
|
||||
struct pl022_ssp_controller *host_info;
|
||||
/* Message per-transfer pump */
|
||||
@@ -2181,6 +2183,19 @@ static int pl022_probe(struct amba_devic
|
||||
goto err_no_clk_en;
|
||||
}
|
||||
|
||||
+ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
|
||||
+ if (IS_ERR(pl022->rst)) {
|
||||
+ status = PTR_ERR(pl022->rst);
|
||||
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
|
||||
+ goto err_no_rst;
|
||||
+ }
|
||||
+
|
||||
+ status = reset_control_deassert(pl022->rst);
|
||||
+ if (status) {
|
||||
+ dev_err(&adev->dev, "could not deassert SSP/SPI bus reset\n");
|
||||
+ goto err_no_rst_de;
|
||||
+ }
|
||||
+
|
||||
/* Initialize transfer pump */
|
||||
tasklet_init(&pl022->pump_transfers, pump_transfers,
|
||||
(unsigned long)pl022);
|
||||
@@ -2240,6 +2255,8 @@ static int pl022_probe(struct amba_devic
|
||||
if (platform_info->enable_dma)
|
||||
pl022_dma_remove(pl022);
|
||||
err_no_irq:
|
||||
+ err_no_rst_de:
|
||||
+ err_no_rst:
|
||||
clk_disable_unprepare(pl022->clk);
|
||||
err_no_clk_en:
|
||||
err_no_clk:
|
@ -0,0 +1,30 @@
|
||||
From 9cc8de0cdc1600f460f618e342e1f524adad07c4 Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Wed, 21 Feb 2024 10:23:48 +0800
|
||||
Subject: [PATCH 052/116] ASoC: dwc: i2s: Fix getting platform data error for
|
||||
StarFive JH7110
|
||||
|
||||
JH7110 need to use a DT specific function to get the platform data,
|
||||
otherwise, it fails in probe().
|
||||
|
||||
Fixes: 9c97790a07dc ("ASoC: dwc: Fix non-DT instantiation")
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
sound/soc/dwc/dwc-i2s.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/sound/soc/dwc/dwc-i2s.c
|
||||
+++ b/sound/soc/dwc/dwc-i2s.c
|
||||
@@ -917,7 +917,11 @@ static int jh7110_i2stx0_clk_cfg(struct
|
||||
|
||||
static int dw_i2s_probe(struct platform_device *pdev)
|
||||
{
|
||||
+#ifdef CONFIG_OF
|
||||
+ const struct i2s_platform_data *pdata = of_device_get_match_data(&pdev->dev);
|
||||
+#else
|
||||
const struct i2s_platform_data *pdata = pdev->dev.platform_data;
|
||||
+#endif
|
||||
struct dw_i2s_dev *dev;
|
||||
struct resource *res;
|
||||
int ret, irq;
|
@ -0,0 +1,67 @@
|
||||
From 1be9bd37fdb5f50162dba0158e1fee295ebca9aa Mon Sep 17 00:00:00 2001
|
||||
From: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Date: Tue, 17 Oct 2023 17:22:52 +0800
|
||||
Subject: [PATCH 053/116] ASoC: dwc: i2s: Add RX master support for StarFive
|
||||
JH7110 SoC
|
||||
|
||||
Add JH7110 I2S RX master support, so the PDM can work on JH7110
|
||||
EVB board.
|
||||
|
||||
Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
sound/soc/dwc/dwc-i2s.c | 31 +++++++++++++++++++++++++++++++
|
||||
1 file changed, 31 insertions(+)
|
||||
|
||||
--- a/sound/soc/dwc/dwc-i2s.c
|
||||
+++ b/sound/soc/dwc/dwc-i2s.c
|
||||
@@ -906,6 +906,27 @@ static int jh7110_i2srx_crg_init(struct
|
||||
return jh7110_i2s_crg_slave_init(dev);
|
||||
}
|
||||
|
||||
+/* Special syscon initialization about RX channel with master mode on JH7110 SoC */
|
||||
+static int jh7110_i2srx_mst_crg_init(struct dw_i2s_dev *dev)
|
||||
+{
|
||||
+ struct regmap *regmap;
|
||||
+ unsigned int args[5];
|
||||
+
|
||||
+ regmap = syscon_regmap_lookup_by_phandle_args(dev->dev->of_node,
|
||||
+ "starfive,syscon",
|
||||
+ 5, args);
|
||||
+ if (IS_ERR(regmap))
|
||||
+ return dev_err_probe(dev->dev, PTR_ERR(regmap), "getting the regmap failed\n");
|
||||
+
|
||||
+ /* Enable I2Srx with syscon register, args[0]: offset, args[1]: mask */
|
||||
+ regmap_update_bits(regmap, args[0], args[1], args[1]);
|
||||
+
|
||||
+ /* Change I2Srx source (PDM) with syscon register, args[0]: offset, args[1]: mask */
|
||||
+ regmap_update_bits(regmap, args[2], args[3], args[4]);
|
||||
+
|
||||
+ return jh7110_i2s_crg_master_init(dev);
|
||||
+}
|
||||
+
|
||||
static int jh7110_i2stx0_clk_cfg(struct i2s_clk_config_data *config)
|
||||
{
|
||||
struct dw_i2s_dev *dev = container_of(config, struct dw_i2s_dev, config);
|
||||
@@ -1086,11 +1107,21 @@ static const struct i2s_platform_data jh
|
||||
.i2s_pd_init = jh7110_i2srx_crg_init,
|
||||
};
|
||||
|
||||
+static const struct i2s_platform_data jh7110_i2srx_mst_data = {
|
||||
+ .cap = DWC_I2S_RECORD | DW_I2S_MASTER,
|
||||
+ .channel = TWO_CHANNEL_SUPPORT,
|
||||
+ .snd_fmts = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
+ .snd_rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000,
|
||||
+ .i2s_clk_cfg = jh7110_i2stx0_clk_cfg,
|
||||
+ .i2s_pd_init = jh7110_i2srx_mst_crg_init,
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id dw_i2s_of_match[] = {
|
||||
{ .compatible = "snps,designware-i2s", },
|
||||
{ .compatible = "starfive,jh7110-i2stx0", .data = &jh7110_i2stx0_data, },
|
||||
{ .compatible = "starfive,jh7110-i2stx1", .data = &jh7110_i2stx1_data,},
|
||||
{ .compatible = "starfive,jh7110-i2srx", .data = &jh7110_i2srx_data,},
|
||||
+ { .compatible = "starfive,jh7110-i2srx-master", .data = &jh7110_i2srx_mst_data,},
|
||||
{},
|
||||
};
|
||||
|
@ -0,0 +1,24 @@
|
||||
From 1ec26ba377d8ae59cd09811ec78623a750a9c150 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Mon, 26 Feb 2024 11:35:44 +0800
|
||||
Subject: [PATCH 054/116] pinctrl: starfive: jh7110: Unset .strict in
|
||||
pinmux_ops
|
||||
|
||||
Allow simultaneous use of the same pin for GPIO and another function.
|
||||
This feature is used in HDMI hot plug detect.
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
|
||||
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
|
||||
@@ -327,7 +327,6 @@ static const struct pinmux_ops jh7110_pi
|
||||
.get_function_name = pinmux_generic_get_function_name,
|
||||
.get_function_groups = pinmux_generic_get_function_groups,
|
||||
.set_mux = jh7110_set_mux,
|
||||
- .strict = true,
|
||||
};
|
||||
|
||||
static const u8 jh7110_drive_strength_mA[4] = { 2, 4, 8, 12 };
|
@ -0,0 +1,22 @@
|
||||
From 005549a2bd839335b0e3dc4152f00f642b524f07 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Sat, 7 Oct 2023 18:10:20 +0800
|
||||
Subject: [PATCH 055/116] mm/pgtable-generic.c: Export symbol __pte_offset_map
|
||||
|
||||
So JH7110 vdec can call pte_offset_map() when it is built as a module.
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
mm/pgtable-generic.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/mm/pgtable-generic.c
|
||||
+++ b/mm/pgtable-generic.c
|
||||
@@ -304,6 +304,7 @@ nomap:
|
||||
rcu_read_unlock();
|
||||
return NULL;
|
||||
}
|
||||
+EXPORT_SYMBOL(__pte_offset_map);
|
||||
|
||||
pte_t *pte_offset_map_nolock(struct mm_struct *mm, pmd_t *pmd,
|
||||
unsigned long addr, spinlock_t **ptlp)
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,728 @@
|
||||
From cae7550054ca0cd940bbc1501ae5611f5d2957e6 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Wed, 20 Sep 2023 14:53:22 +0800
|
||||
Subject: [PATCH 057/116] riscv: dts: starfive: Add JH7110 EVB expanded device
|
||||
tree
|
||||
|
||||
Add JH7110 EVB expanded device tree.
|
||||
The code is ported from tag JH7110_SDK_6.1_v5.11.3
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
arch/riscv/boot/dts/starfive/Makefile | 11 +-
|
||||
.../starfive/jh7110-evb-can-pdm-pwmdac.dts | 102 ++++++++++++++++
|
||||
.../dts/starfive/jh7110-evb-dvp-rgb2hdmi.dts | 37 ++++++
|
||||
.../dts/starfive/jh7110-evb-i2s-ac108.dts | 72 ++++++++++++
|
||||
.../dts/starfive/jh7110-evb-pcie-i2s-sd.dts | 111 ++++++++++++++++++
|
||||
.../dts/starfive/jh7110-evb-spi-uart2.dts | 65 ++++++++++
|
||||
.../starfive/jh7110-evb-uart1-rgb2hdmi.dts | 57 +++++++++
|
||||
.../starfive/jh7110-evb-uart4-emmc-spdif.dts | 78 ++++++++++++
|
||||
.../starfive/jh7110-evb-uart5-pwm-i2c-tdm.dts | 95 +++++++++++++++
|
||||
.../dts/starfive/jh7110-evb-usbdevice.dts | 35 ++++++
|
||||
10 files changed, 662 insertions(+), 1 deletion(-)
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-can-pdm-pwmdac.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-dvp-rgb2hdmi.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-i2s-ac108.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-pcie-i2s-sd.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-spi-uart2.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-uart1-rgb2hdmi.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-uart4-emmc-spdif.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-uart5-pwm-i2c-tdm.dts
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/Makefile
|
||||
+++ b/arch/riscv/boot/dts/starfive/Makefile
|
||||
@@ -12,4 +12,13 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-st
|
||||
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
|
||||
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
|
||||
|
||||
-dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb
|
||||
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb \
|
||||
+ jh7110-evb-pcie-i2s-sd.dtb \
|
||||
+ jh7110-evb-spi-uart2.dtb \
|
||||
+ jh7110-evb-uart4-emmc-spdif.dtb \
|
||||
+ jh7110-evb-uart5-pwm-i2c-tdm.dtb \
|
||||
+ jh7110-evb-dvp-rgb2hdmi.dtb \
|
||||
+ jh7110-evb-can-pdm-pwmdac.dtb \
|
||||
+ jh7110-evb-i2s-ac108.dtb \
|
||||
+ jh7110-evb-usbdevice.dtb \
|
||||
+ jh7110-evb-uart1-rgb2hdmi.dtb
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-evb-can-pdm-pwmdac.dts
|
||||
@@ -0,0 +1,102 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-evb.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive JH7110 EVB";
|
||||
+ compatible = "starfive,jh7110-evb", "starfive,jh7110";
|
||||
+
|
||||
+ sound2: snd-card2 {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ simple-audio-card,name = "StarFive-PDM-Sound-Card";
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ reg = <0>;
|
||||
+ format = "i2s";
|
||||
+ bitclock-master = <&dailink_master>;
|
||||
+ frame-master = <&dailink_master>;
|
||||
+
|
||||
+ dailink_master:cpu {
|
||||
+ sound-dai = <&i2srx_mst>;
|
||||
+ };
|
||||
+
|
||||
+ dailink_slave:codec {
|
||||
+ sound-dai = <&pdm>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pwmdac_codec: pwmdac-codec {
|
||||
+ compatible = "linux,spdif-dit";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ sound3: snd-card3 {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ reg = <0>;
|
||||
+ format = "left_j";
|
||||
+ bitclock-master = <&sndcpu0>;
|
||||
+ frame-master = <&sndcpu0>;
|
||||
+
|
||||
+ sndcpu0: cpu {
|
||||
+ sound-dai = <&pwmdac>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&pwmdac_codec>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&sdcard0_pins>;
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <4>;
|
||||
+ broken-cd;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&can0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&can1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2srx_mst {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pwmdac {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pdm {
|
||||
+ status = "okay";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-evb-dvp-rgb2hdmi.dts
|
||||
@@ -0,0 +1,37 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-evb.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive JH7110 EVB";
|
||||
+ compatible = "starfive,jh7110-evb", "starfive,jh7110";
|
||||
+};
|
||||
+
|
||||
+&vin_sysctl {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&dvp_pins>;
|
||||
+};
|
||||
+
|
||||
+&rgb_output {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&tda988x_pin {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&dsi_output {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&mipi_dsi {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&mipi_dphy {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-evb-i2s-ac108.dts
|
||||
@@ -0,0 +1,72 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-evb.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive JH7110 EVB";
|
||||
+ compatible = "starfive,jh7110-evb", "starfive,jh7110";
|
||||
+
|
||||
+ /* i2s + ac108 */
|
||||
+ sound0: snd-card0 {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ simple-audio-card,name = "StarFive-AC108-Sound-Card";
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ reg = <0>;
|
||||
+ format = "i2s";
|
||||
+ bitclock-master = <&sndcodec1>;
|
||||
+ frame-master = <&sndcodec1>;
|
||||
+
|
||||
+ widgets = "Microphone", "Mic Jack",
|
||||
+ "Line", "Line In",
|
||||
+ "Line", "Line Out",
|
||||
+ "Speaker", "Speaker",
|
||||
+ "Headphone", "Headphone Jack";
|
||||
+ routing = "Headphone Jack", "HP_L",
|
||||
+ "Headphone Jack", "HP_R",
|
||||
+ "Speaker", "SPK_LP",
|
||||
+ "Speaker", "SPK_LN",
|
||||
+ "LINPUT1", "Mic Jack",
|
||||
+ "LINPUT3", "Mic Jack",
|
||||
+ "RINPUT1", "Mic Jack",
|
||||
+ "RINPUT2", "Mic Jack";
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2srx>;
|
||||
+ };
|
||||
+
|
||||
+ sndcodec1: codec {
|
||||
+ sound-dai = <&ac108>;
|
||||
+ clocks = <&ac108_mclk>;
|
||||
+ clock-names = "mclk";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&sdcard0_pins>;
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <4>;
|
||||
+ broken-cd;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2srx {
|
||||
+ status = "okay";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-evb-pcie-i2s-sd.dts
|
||||
@@ -0,0 +1,111 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-evb.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive JH7110 EVB";
|
||||
+ compatible = "starfive,jh7110-evb", "starfive,jh7110";
|
||||
+
|
||||
+ /* i2s + wm8960 */
|
||||
+ sound6: snd-card6 {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ simple-audio-card,name = "StarFive-WM8960-Sound-Card";
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ reg = <0>;
|
||||
+ status = "okay";
|
||||
+ format = "i2s";
|
||||
+ bitclock-master = <&sndcodec1>;
|
||||
+ frame-master = <&sndcodec1>;
|
||||
+
|
||||
+ widgets = "Microphone", "Mic Jack",
|
||||
+ "Line", "Line In",
|
||||
+ "Line", "Line Out",
|
||||
+ "Speaker", "Speaker",
|
||||
+ "Headphone", "Headphone Jack";
|
||||
+ routing = "Headphone Jack", "HP_L",
|
||||
+ "Headphone Jack", "HP_R",
|
||||
+ "Speaker", "SPK_LP",
|
||||
+ "Speaker", "SPK_LN",
|
||||
+ "LINPUT1", "Mic Jack",
|
||||
+ "LINPUT3", "Mic Jack",
|
||||
+ "RINPUT1", "Mic Jack",
|
||||
+ "RINPUT2", "Mic Jack";
|
||||
+ cpu0 {
|
||||
+ sound-dai = <&i2srx>;
|
||||
+ };
|
||||
+ cpu1 {
|
||||
+ sound-dai = <&i2stx1>;
|
||||
+ };
|
||||
+
|
||||
+ sndcodec1:codec {
|
||||
+ sound-dai = <&wm8960>;
|
||||
+ clocks = <&wm8960_mclk>;
|
||||
+ clock-names = "mclk";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&sdcard0_pins>;
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <4>;
|
||||
+ broken-cd;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb0 {
|
||||
+ clocks = <&stgcrg JH7110_STGCLK_USB0_LPM>,
|
||||
+ <&stgcrg JH7110_STGCLK_USB0_STB>,
|
||||
+ <&stgcrg JH7110_STGCLK_USB0_APB>,
|
||||
+ <&stgcrg JH7110_STGCLK_USB0_AXI>,
|
||||
+ <&stgcrg JH7110_STGCLK_USB0_UTMI_APB>;
|
||||
+ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb";
|
||||
+ resets = <&stgcrg JH7110_STGRST_USB0_PWRUP>,
|
||||
+ <&stgcrg JH7110_STGRST_USB0_APB>,
|
||||
+ <&stgcrg JH7110_STGRST_USB0_AXI>,
|
||||
+ <&stgcrg JH7110_STGRST_USB0_UTMI_APB>;
|
||||
+ reset-names = "pwrup", "apb", "axi", "utmi_apb";
|
||||
+ dr_mode = "host"; /*host or peripheral*/
|
||||
+ starfive,usb2-only;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&usb_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2srx {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2stx1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-evb-spi-uart2.dts
|
||||
@@ -0,0 +1,65 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-evb.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive JH7110 EVB";
|
||||
+ compatible = "starfive,jh7110-evb", "starfive,jh7110";
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&sdcard0_pins>;
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <4>;
|
||||
+ broken-cd;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart2 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi2 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi4 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi5 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi6 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-evb-uart1-rgb2hdmi.dts
|
||||
@@ -0,0 +1,57 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-evb.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive JH7110 EVB";
|
||||
+ compatible = "starfive,jh7110-evb", "starfive,jh7110";
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&sdcard0_pins>;
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <4>;
|
||||
+ broken-cd;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&rgb_output {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&tda988x_pin {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&dsi_output {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&mipi_dsi {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&mipi_dphy {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-evb-uart4-emmc-spdif.dts
|
||||
@@ -0,0 +1,78 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-evb.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive JH7110 EVB";
|
||||
+ compatible = "starfive,jh7110-evb", "starfive,jh7110";
|
||||
+
|
||||
+ spdif_transmitter: spdif_transmitter {
|
||||
+ compatible = "linux,spdif-dit";
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ sound4: snd-card4 {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ simple-audio-card,name = "StarFive-SPDIF-Sound-Card";
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ reg = <0>;
|
||||
+ format = "left_j";
|
||||
+ bitclock-master = <&sndcpu0>;
|
||||
+ frame-master = <&sndcpu0>;
|
||||
+
|
||||
+ sndcpu0: cpu {
|
||||
+ sound-dai = <&spdif>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&spdif_transmitter>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&usb0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart4 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&emmc0_pins>;
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <8>;
|
||||
+ cap-mmc-highspeed;
|
||||
+ mmc-hs200-1_8v;
|
||||
+ non-removable;
|
||||
+ cap-mmc-hw-reset;
|
||||
+ board-is-evb;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pwm {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pwm_ch6to7_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spdif {
|
||||
+ status = "okay";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-evb-uart5-pwm-i2c-tdm.dts
|
||||
@@ -0,0 +1,95 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-evb.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive JH7110 EVB";
|
||||
+ compatible = "starfive,jh7110-evb", "starfive,jh7110";
|
||||
+
|
||||
+ sound5: snd-card5 {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ simple-audio-card,name = "StarFive-TDM-Sound-Card";
|
||||
+ simple-audio-card,widgets = "Microphone", "Mic Jack",
|
||||
+ "Line", "Line In",
|
||||
+ "Line", "Line Out",
|
||||
+ "Speaker", "Speaker",
|
||||
+ "Headphone", "Headphone Jack";
|
||||
+ simple-audio-card,routing = "Headphone Jack", "HP_L",
|
||||
+ "Headphone Jack", "HP_R",
|
||||
+ "Speaker", "SPK_LP",
|
||||
+ "Speaker", "SPK_LN",
|
||||
+ "LINPUT1", "Mic Jack",
|
||||
+ "LINPUT3", "Mic Jack",
|
||||
+ "RINPUT1", "Mic Jack",
|
||||
+ "RINPUT2", "Mic Jack";
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ reg = <0>;
|
||||
+ format = "dsp_a";
|
||||
+ bitclock-master = <&dailink_master>;
|
||||
+ frame-master = <&dailink_master>;
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&tdm>;
|
||||
+ };
|
||||
+ dailink_master: codec {
|
||||
+ sound-dai = <&wm8960>;
|
||||
+ clocks = <&wm8960_mclk>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&sdcard0_pins>;
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <4>;
|
||||
+ broken-cd;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart5 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pwm {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pwm_ch0to3_pins &pwm_ch4to5_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&tdm {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c1 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts
|
||||
@@ -0,0 +1,35 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
+/*
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "jh7110-evb.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "StarFive JH7110 EVB";
|
||||
+ compatible = "starfive,jh7110-evb", "starfive,jh7110";
|
||||
+};
|
||||
+
|
||||
+/* default sd card */
|
||||
+&mmc0 {
|
||||
+ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
|
||||
+ assigned-clock-rates = <50000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&sdcard0_pins>;
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <4>;
|
||||
+ broken-cd;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb0 {
|
||||
+ dr_mode = "peripheral"; /*host or peripheral*/
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pcie1 {
|
||||
+ status = "okay";
|
||||
+};
|
@ -0,0 +1,485 @@
|
||||
From e9122ceaf2d8767753e2a126c14b29b78280446d Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Tue, 19 Sep 2023 21:35:39 +0800
|
||||
Subject: [PATCH 058/116] riscv: dts: starfive: Add evb-overlay dtso subdir
|
||||
|
||||
Create subdir evb-overlay/ and add overlay .dtso for JH7110 EVB.
|
||||
The code is ported from tag JH7110_SDK_6.1_v5.11.3
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
arch/riscv/boot/dts/starfive/Makefile | 1 +
|
||||
.../boot/dts/starfive/evb-overlay/Makefile | 7 +
|
||||
.../evb-overlay/jh7110-evb-overlay-can.dtso | 24 ++++
|
||||
.../jh7110-evb-overlay-rgb2hdmi.dtso | 24 ++++
|
||||
.../evb-overlay/jh7110-evb-overlay-sdio.dtso | 78 +++++++++++
|
||||
.../evb-overlay/jh7110-evb-overlay-spi.dtso | 72 ++++++++++
|
||||
.../jh7110-evb-overlay-uart4-emmc.dtso | 130 ++++++++++++++++++
|
||||
.../jh7110-evb-overlay-uart5-pwm.dtso | 92 +++++++++++++
|
||||
8 files changed, 428 insertions(+)
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/Makefile
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-can.dtso
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-rgb2hdmi.dtso
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-sdio.dtso
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart4-emmc.dtso
|
||||
create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart5-pwm.dtso
|
||||
|
||||
--- a/arch/riscv/boot/dts/starfive/Makefile
|
||||
+++ b/arch/riscv/boot/dts/starfive/Makefile
|
||||
@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-st
|
||||
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
|
||||
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
|
||||
|
||||
+subdir-y += evb-overlay
|
||||
dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb \
|
||||
jh7110-evb-pcie-i2s-sd.dtb \
|
||||
jh7110-evb-spi-uart2.dtb \
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/evb-overlay/Makefile
|
||||
@@ -0,0 +1,7 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb-overlay-can.dtbo \
|
||||
+ jh7110-evb-overlay-sdio.dtbo \
|
||||
+ jh7110-evb-overlay-spi.dtbo \
|
||||
+ jh7110-evb-overlay-uart4-emmc.dtbo \
|
||||
+ jh7110-evb-overlay-uart5-pwm.dtbo \
|
||||
+ jh7110-evb-overlay-rgb2hdmi.dtbo
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-can.dtso
|
||||
@@ -0,0 +1,24 @@
|
||||
+/dts-v1/;
|
||||
+/plugin/;
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include "../jh7110-pinfunc.h"
|
||||
+/ {
|
||||
+ compatible = "starfive,jh7110";
|
||||
+
|
||||
+ //can0
|
||||
+ fragment@0 {
|
||||
+ target-path = "/soc/can@130d0000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //can1
|
||||
+ fragment@1 {
|
||||
+ target-path = "/soc/can@130e0000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-rgb2hdmi.dtso
|
||||
@@ -0,0 +1,24 @@
|
||||
+/dts-v1/;
|
||||
+/plugin/;
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include "../jh7110-pinfunc.h"
|
||||
+/ {
|
||||
+ compatible = "starfive,jh7110";
|
||||
+
|
||||
+ //hdmi_output
|
||||
+ fragment@0 {
|
||||
+ target-path = "/tda988x_pin";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //uart1
|
||||
+ fragment@1 {
|
||||
+ target-path = "/soc/serial@10010000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-sdio.dtso
|
||||
@@ -0,0 +1,78 @@
|
||||
+/dts-v1/;
|
||||
+/plugin/;
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include "../jh7110-pinfunc.h"
|
||||
+/ {
|
||||
+ compatible = "starfive,jh7110";
|
||||
+
|
||||
+ //sysgpio
|
||||
+ fragment@0 {
|
||||
+ target-path = "/soc/pinctrl@13040000";
|
||||
+ __overlay__ {
|
||||
+ dt_sdcard1_pins: dt-sdcard1-0 {
|
||||
+ sdcard-pins {
|
||||
+ pinmux = <GPIOMUX(56, GPOUT_SYS_SDIO1_CLK,
|
||||
+ GPOEN_ENABLE,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(50, GPOUT_SYS_SDIO1_CMD,
|
||||
+ GPOEN_SYS_SDIO1_CMD,
|
||||
+ GPI_SYS_SDIO1_CMD)>,
|
||||
+ <GPIOMUX(49, GPOUT_SYS_SDIO1_DATA0,
|
||||
+ GPOEN_SYS_SDIO1_DATA0,
|
||||
+ GPI_SYS_SDIO1_DATA0)>,
|
||||
+ <GPIOMUX(45, GPOUT_SYS_SDIO1_DATA1,
|
||||
+ GPOEN_SYS_SDIO1_DATA1,
|
||||
+ GPI_SYS_SDIO1_DATA1)>,
|
||||
+ <GPIOMUX(62, GPOUT_SYS_SDIO1_DATA2,
|
||||
+ GPOEN_SYS_SDIO1_DATA2,
|
||||
+ GPI_SYS_SDIO1_DATA2)>,
|
||||
+ <GPIOMUX(40, GPOUT_SYS_SDIO1_DATA3,
|
||||
+ GPOEN_SYS_SDIO1_DATA3,
|
||||
+ GPI_SYS_SDIO1_DATA3)>;
|
||||
+ bias-pull-up;
|
||||
+ input-enable;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //uart3
|
||||
+ fragment@1 {
|
||||
+ target-path = "/soc/serial@12000000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //i2c0
|
||||
+ fragment@2 {
|
||||
+ target-path = "/soc/i2c@10030000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //mmc1
|
||||
+ fragment@3 {
|
||||
+ target-path = "/soc/mmc@16020000";
|
||||
+ __overlay__ {
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <4>;
|
||||
+ no-sdio;
|
||||
+ no-mmc;
|
||||
+ broken-cd;
|
||||
+ sd-uhs-sdr12;
|
||||
+ sd-uhs-sdr25;
|
||||
+ sd-uhs-sdr50;
|
||||
+ sd-uhs-sdr104;
|
||||
+ sd-uhs-ddr50;
|
||||
+ cap-sd-highspeed;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&dt_sdcard1_pins>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
|
||||
@@ -0,0 +1,72 @@
|
||||
+/dts-v1/;
|
||||
+/plugin/;
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include "../jh7110-pinfunc.h"
|
||||
+/ {
|
||||
+ compatible = "starfive,jh7110";
|
||||
+
|
||||
+ //spi0
|
||||
+ fragment@0 {
|
||||
+ target-path = "/soc/spi@10060000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //spi1
|
||||
+ fragment@1 {
|
||||
+ target-path = "/soc/spi@10070000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //spi2
|
||||
+ fragment@2 {
|
||||
+ target-path = "/soc/spi@10080000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //spi3
|
||||
+ fragment@3 {
|
||||
+ target-path = "/soc/spi@12070000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //spi4
|
||||
+ fragment@4 {
|
||||
+ target-path = "/soc/spi@12080000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //spi5
|
||||
+ fragment@5 {
|
||||
+ target-path = "/soc/spi@12090000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //spi6
|
||||
+ fragment@6 {
|
||||
+ target-path = "/soc/spi@120a0000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //uart2
|
||||
+ fragment@7 {
|
||||
+ target-path = "/soc/serial@10020000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart4-emmc.dtso
|
||||
@@ -0,0 +1,130 @@
|
||||
+/dts-v1/;
|
||||
+/plugin/;
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include "../jh7110-pinfunc.h"
|
||||
+/ {
|
||||
+ compatible = "starfive,jh7110";
|
||||
+
|
||||
+ //sysgpio
|
||||
+ fragment@0 {
|
||||
+ target-path = "/soc/pinctrl@13040000";
|
||||
+ __overlay__ {
|
||||
+ dt_emmc0_pins: dt-emmc0-0 {
|
||||
+ emmc-pins {
|
||||
+ pinmux = <GPIOMUX(22, GPOUT_SYS_SDIO0_RST,
|
||||
+ GPOEN_ENABLE,
|
||||
+ GPI_NONE)>,
|
||||
+ <PINMUX(64, 0)>,
|
||||
+ <PINMUX(65, 0)>,
|
||||
+ <PINMUX(66, 0)>,
|
||||
+ <PINMUX(67, 0)>,
|
||||
+ <PINMUX(68, 0)>,
|
||||
+ <PINMUX(69, 0)>,
|
||||
+ <PINMUX(70, 0)>,
|
||||
+ <PINMUX(71, 0)>,
|
||||
+ <PINMUX(72, 0)>,
|
||||
+ <PINMUX(73, 0)>;
|
||||
+ bias-pull-up;
|
||||
+ drive-strength = <12>;
|
||||
+ input-enable;
|
||||
+ slew-rate = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ dt_emmc1_pins: dt-emmc1-0 {
|
||||
+ emmc-pins {
|
||||
+ pinmux = <GPIOMUX(51, GPOUT_SYS_SDIO1_RST,
|
||||
+ GPOEN_ENABLE,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(38, GPOUT_SYS_SDIO1_CLK,
|
||||
+ GPOEN_ENABLE,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(36, GPOUT_SYS_SDIO1_CMD,
|
||||
+ GPOEN_SYS_SDIO1_CMD,
|
||||
+ GPI_SYS_SDIO1_CMD)>,
|
||||
+ <GPIOMUX(43, GPOUT_SYS_SDIO1_DATA0,
|
||||
+ GPOEN_SYS_SDIO1_DATA0,
|
||||
+ GPI_SYS_SDIO1_DATA0)>,
|
||||
+ <GPIOMUX(48, GPOUT_SYS_SDIO1_DATA1,
|
||||
+ GPOEN_SYS_SDIO1_DATA1,
|
||||
+ GPI_SYS_SDIO1_DATA1)>,
|
||||
+ <GPIOMUX(53, GPOUT_SYS_SDIO1_DATA2,
|
||||
+ GPOEN_SYS_SDIO1_DATA2,
|
||||
+ GPI_SYS_SDIO1_DATA2)>,
|
||||
+ <GPIOMUX(63, GPOUT_SYS_SDIO1_DATA3,
|
||||
+ GPOEN_SYS_SDIO1_DATA3,
|
||||
+ GPI_SYS_SDIO1_DATA3)>,
|
||||
+ <GPIOMUX(52, GPOUT_SYS_SDIO1_DATA4,
|
||||
+ GPOEN_SYS_SDIO1_DATA4,
|
||||
+ GPI_SYS_SDIO1_DATA4)>,
|
||||
+ <GPIOMUX(39, GPOUT_SYS_SDIO1_DATA5,
|
||||
+ GPOEN_SYS_SDIO1_DATA5,
|
||||
+ GPI_SYS_SDIO1_DATA5)>,
|
||||
+ <GPIOMUX(46, GPOUT_SYS_SDIO1_DATA6,
|
||||
+ GPOEN_SYS_SDIO1_DATA6,
|
||||
+ GPI_SYS_SDIO1_DATA6)>,
|
||||
+ <GPIOMUX(47, GPOUT_SYS_SDIO1_DATA7,
|
||||
+ GPOEN_SYS_SDIO1_DATA7,
|
||||
+ GPI_SYS_SDIO1_DATA7)>;
|
||||
+ bias-pull-up;
|
||||
+ input-enable;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //aongpio
|
||||
+ fragment@1 {
|
||||
+ target-path = "/soc/pinctrl@17020000";
|
||||
+ __overlay__ {
|
||||
+ dt_pwm_ch6to7_pins: dt-pwm-ch6to7-0 {
|
||||
+ pwm-pins {
|
||||
+ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM6, /* PAD_RGPIO0 */
|
||||
+ GPOEN_AON_PTC0_OE_N_6,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(2, GPOUT_AON_PTC0_PWM7, /* PAD_RGPIO1 */
|
||||
+ GPOEN_AON_PTC0_OE_N_7,
|
||||
+ GPI_NONE)>;
|
||||
+ drive-strength = <12>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //uart4
|
||||
+ fragment@2 {
|
||||
+ target-path = "/soc/serial@12010000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //mmc1
|
||||
+ fragment@3 {
|
||||
+ target-path = "/soc/mmc@16020000";
|
||||
+ __overlay__ {
|
||||
+ clock-frequency = <102400000>;
|
||||
+ max-frequency = <100000000>;
|
||||
+ card-detect-delay = <300>;
|
||||
+ bus-width = <8>;
|
||||
+ cap-mmc-hw-reset;
|
||||
+ non-removable;
|
||||
+ cap-mmc-highspeed;
|
||||
+ post-power-on-delay-ms = <200>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&dt_emmc1_pins>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //ptc
|
||||
+ fragment@4 {
|
||||
+ target-path = "/soc/pwm@120d0000";
|
||||
+ __overlay__ {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&dt_pwm_ch6to7_pins>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart5-pwm.dtso
|
||||
@@ -0,0 +1,92 @@
|
||||
+/dts-v1/;
|
||||
+/plugin/;
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include "../jh7110-pinfunc.h"
|
||||
+/ {
|
||||
+ compatible = "starfive,jh7110";
|
||||
+
|
||||
+ //sysgpio
|
||||
+ fragment@0 {
|
||||
+ target-path = "/soc/pinctrl@13040000";
|
||||
+ __overlay__ {
|
||||
+ dt_pwm_ch0to3_pins: dt-pwm-ch0to3-0 {
|
||||
+ pwm-pins {
|
||||
+ pinmux = <GPIOMUX(45, GPOUT_SYS_PWM_CHANNEL0,
|
||||
+ GPOEN_SYS_PWM0_CHANNEL0,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL1,
|
||||
+ GPOEN_SYS_PWM0_CHANNEL1,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(47, GPOUT_SYS_PWM_CHANNEL2,
|
||||
+ GPOEN_SYS_PWM0_CHANNEL2,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(48, GPOUT_SYS_PWM_CHANNEL3,
|
||||
+ GPOEN_SYS_PWM0_CHANNEL3,
|
||||
+ GPI_NONE)>;
|
||||
+ drive-strength = <12>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //aongpio
|
||||
+ fragment@1 {
|
||||
+ target-path = "/soc/pinctrl@17020000";
|
||||
+ __overlay__ {
|
||||
+ dt_pwm_ch4to5_pins: dt-pwm-ch4to5-0 {
|
||||
+ pwm-pins {
|
||||
+ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM4, /* PAD_RGPIO0 */
|
||||
+ GPOEN_AON_PTC0_OE_N_4,
|
||||
+ GPI_NONE)>,
|
||||
+ <GPIOMUX(2, GPOUT_AON_PTC0_PWM5, /* PAD_RGPIO1 */
|
||||
+ GPOEN_AON_PTC0_OE_N_5,
|
||||
+ GPI_NONE)>;
|
||||
+ drive-strength = <12>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //uart5
|
||||
+ fragment@2 {
|
||||
+ target-path = "/soc/serial@12020000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //ptc
|
||||
+ fragment@3 {
|
||||
+ target-path = "/soc/pwm@120d0000";
|
||||
+ __overlay__ {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&dt_pwm_ch0to3_pins &dt_pwm_ch4to5_pins>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //i2c0
|
||||
+ fragment@4 {
|
||||
+ target-path = "/soc/i2c@10030000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //i2c1
|
||||
+ fragment@5 {
|
||||
+ target-path = "/soc/i2c@10040000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ //i2c3
|
||||
+ fragment@6 {
|
||||
+ target-path = "/soc/i2c@12030000";
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
@ -0,0 +1,385 @@
|
||||
From 5c888fa081caf5d9473e733931d1c7b3d4b61e61 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Fri, 28 Jul 2023 18:42:55 +0800
|
||||
Subject: [PATCH 059/116] riscv: configs: Add starfive_jh7110_defconfig
|
||||
|
||||
Add starfive_jh7110_defconfig for JH7110 EVB.
|
||||
The code is ported from tag JH7110_SDK_6.1_v5.11.3
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
arch/riscv/configs/starfive_jh7110_defconfig | 368 +++++++++++++++++++
|
||||
1 file changed, 368 insertions(+)
|
||||
create mode 100644 arch/riscv/configs/starfive_jh7110_defconfig
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/riscv/configs/starfive_jh7110_defconfig
|
||||
@@ -0,0 +1,368 @@
|
||||
+CONFIG_COMPILE_TEST=y
|
||||
+# CONFIG_WERROR is not set
|
||||
+CONFIG_DEFAULT_HOSTNAME="StarFive"
|
||||
+CONFIG_SYSVIPC=y
|
||||
+CONFIG_POSIX_MQUEUE=y
|
||||
+CONFIG_USELIB=y
|
||||
+CONFIG_NO_HZ_IDLE=y
|
||||
+CONFIG_HIGH_RES_TIMERS=y
|
||||
+CONFIG_BPF_SYSCALL=y
|
||||
+CONFIG_IKCONFIG=y
|
||||
+CONFIG_IKCONFIG_PROC=y
|
||||
+CONFIG_CGROUPS=y
|
||||
+CONFIG_MEMCG=y
|
||||
+CONFIG_CGROUP_SCHED=y
|
||||
+CONFIG_CFS_BANDWIDTH=y
|
||||
+CONFIG_RT_GROUP_SCHED=y
|
||||
+CONFIG_CGROUP_PIDS=y
|
||||
+CONFIG_CGROUP_FREEZER=y
|
||||
+CONFIG_CGROUP_HUGETLB=y
|
||||
+CONFIG_CPUSETS=y
|
||||
+CONFIG_CGROUP_DEVICE=y
|
||||
+CONFIG_CGROUP_CPUACCT=y
|
||||
+CONFIG_CGROUP_PERF=y
|
||||
+CONFIG_CGROUP_BPF=y
|
||||
+CONFIG_NAMESPACES=y
|
||||
+CONFIG_USER_NS=y
|
||||
+CONFIG_CHECKPOINT_RESTORE=y
|
||||
+CONFIG_BLK_DEV_INITRD=y
|
||||
+CONFIG_EXPERT=y
|
||||
+# CONFIG_SYSFS_SYSCALL is not set
|
||||
+CONFIG_PROFILING=y
|
||||
+CONFIG_SOC_MICROCHIP_POLARFIRE=y
|
||||
+CONFIG_SOC_STARFIVE=y
|
||||
+CONFIG_SOC_VIRT=y
|
||||
+CONFIG_ERRATA_SIFIVE=y
|
||||
+CONFIG_NONPORTABLE=y
|
||||
+CONFIG_SMP=y
|
||||
+CONFIG_RISCV_SBI_V01=y
|
||||
+# CONFIG_RISCV_BOOT_SPINWAIT is not set
|
||||
+CONFIG_HIBERNATION=y
|
||||
+CONFIG_PM_STD_PARTITION="PARTLABEL=hibernation"
|
||||
+CONFIG_PM_DEBUG=y
|
||||
+CONFIG_PM_ADVANCED_DEBUG=y
|
||||
+CONFIG_PM_TEST_SUSPEND=y
|
||||
+CONFIG_ENERGY_MODEL=y
|
||||
+CONFIG_CPU_IDLE=y
|
||||
+CONFIG_CPU_FREQ=y
|
||||
+CONFIG_CPU_FREQ_STAT=y
|
||||
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
|
||||
+CONFIG_CPUFREQ_DT=y
|
||||
+CONFIG_VIRTUALIZATION=y
|
||||
+CONFIG_KVM=m
|
||||
+CONFIG_JUMP_LABEL=y
|
||||
+CONFIG_MODULES=y
|
||||
+CONFIG_MODULE_UNLOAD=y
|
||||
+CONFIG_BINFMT_MISC=y
|
||||
+CONFIG_CMA=y
|
||||
+CONFIG_NET=y
|
||||
+CONFIG_PACKET=y
|
||||
+CONFIG_XFRM_USER=m
|
||||
+CONFIG_IP_MULTICAST=y
|
||||
+CONFIG_IP_ADVANCED_ROUTER=y
|
||||
+CONFIG_IP_MULTIPLE_TABLES=y
|
||||
+CONFIG_IP_PNP=y
|
||||
+CONFIG_IP_PNP_DHCP=y
|
||||
+CONFIG_IP_PNP_BOOTP=y
|
||||
+CONFIG_IP_PNP_RARP=y
|
||||
+CONFIG_INET_ESP=m
|
||||
+CONFIG_NETFILTER=y
|
||||
+CONFIG_BRIDGE_NETFILTER=m
|
||||
+CONFIG_NF_CONNTRACK=m
|
||||
+CONFIG_NF_CONNTRACK_FTP=m
|
||||
+CONFIG_NF_CONNTRACK_TFTP=m
|
||||
+CONFIG_NETFILTER_XT_MARK=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
|
||||
+CONFIG_IP_VS=m
|
||||
+CONFIG_IP_VS_PROTO_TCP=y
|
||||
+CONFIG_IP_VS_PROTO_UDP=y
|
||||
+CONFIG_IP_VS_RR=m
|
||||
+CONFIG_IP_VS_NFCT=y
|
||||
+CONFIG_NF_LOG_ARP=m
|
||||
+CONFIG_NF_LOG_IPV4=m
|
||||
+CONFIG_IP_NF_IPTABLES=m
|
||||
+CONFIG_IP_NF_FILTER=m
|
||||
+CONFIG_IP_NF_TARGET_REJECT=m
|
||||
+CONFIG_IP_NF_NAT=m
|
||||
+CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
+CONFIG_IP_NF_TARGET_REDIRECT=m
|
||||
+CONFIG_IP_NF_MANGLE=m
|
||||
+CONFIG_NF_LOG_IPV6=m
|
||||
+CONFIG_IP6_NF_IPTABLES=m
|
||||
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
|
||||
+CONFIG_IP6_NF_FILTER=m
|
||||
+CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
+CONFIG_IP6_NF_MANGLE=m
|
||||
+CONFIG_BRIDGE=m
|
||||
+CONFIG_BRIDGE_VLAN_FILTERING=y
|
||||
+CONFIG_VLAN_8021Q=m
|
||||
+CONFIG_NET_SCHED=y
|
||||
+CONFIG_NET_CLS_CGROUP=m
|
||||
+CONFIG_NETLINK_DIAG=y
|
||||
+CONFIG_CGROUP_NET_PRIO=y
|
||||
+CONFIG_CAN=y
|
||||
+CONFIG_BT=y
|
||||
+CONFIG_BT_RFCOMM=y
|
||||
+CONFIG_BT_RFCOMM_TTY=y
|
||||
+CONFIG_BT_BNEP=y
|
||||
+CONFIG_BT_BNEP_MC_FILTER=y
|
||||
+CONFIG_BT_BNEP_PROTO_FILTER=y
|
||||
+CONFIG_BT_HCIUART=y
|
||||
+CONFIG_BT_HCIUART_H4=y
|
||||
+CONFIG_CFG80211=y
|
||||
+CONFIG_MAC80211=y
|
||||
+CONFIG_RFKILL=y
|
||||
+CONFIG_NET_9P=y
|
||||
+CONFIG_NET_9P_VIRTIO=y
|
||||
+CONFIG_PCI=y
|
||||
+CONFIG_PCIEPORTBUS=y
|
||||
+# CONFIG_PCIEASPM is not set
|
||||
+CONFIG_PCI_HOST_GENERIC=y
|
||||
+CONFIG_PCIE_FU740=y
|
||||
+CONFIG_PCIE_STARFIVE_HOST=y
|
||||
+CONFIG_DEVTMPFS=y
|
||||
+CONFIG_DEVTMPFS_MOUNT=y
|
||||
+CONFIG_MTD=y
|
||||
+CONFIG_MTD_BLOCK=y
|
||||
+CONFIG_MTD_SPI_NOR=y
|
||||
+CONFIG_OF_CONFIGFS=y
|
||||
+CONFIG_BLK_DEV_LOOP=y
|
||||
+CONFIG_VIRTIO_BLK=y
|
||||
+CONFIG_BLK_DEV_NVME=y
|
||||
+CONFIG_BLK_DEV_SD=y
|
||||
+CONFIG_BLK_DEV_SR=y
|
||||
+CONFIG_SCSI_VIRTIO=y
|
||||
+CONFIG_ATA=y
|
||||
+CONFIG_SATA_AHCI=y
|
||||
+CONFIG_SATA_AHCI_PLATFORM=y
|
||||
+CONFIG_MD=y
|
||||
+CONFIG_BLK_DEV_DM=m
|
||||
+CONFIG_DM_THIN_PROVISIONING=m
|
||||
+CONFIG_NETDEVICES=y
|
||||
+CONFIG_DUMMY=m
|
||||
+CONFIG_MACVLAN=m
|
||||
+CONFIG_IPVLAN=m
|
||||
+CONFIG_VXLAN=m
|
||||
+CONFIG_VETH=m
|
||||
+CONFIG_VIRTIO_NET=y
|
||||
+CONFIG_MACB=y
|
||||
+CONFIG_E1000E=y
|
||||
+CONFIG_R8169=y
|
||||
+CONFIG_STMMAC_ETH=y
|
||||
+CONFIG_DWMAC_DWC_QOS_ETH=y
|
||||
+# CONFIG_DWMAC_GENERIC is not set
|
||||
+CONFIG_DWMAC_STARFIVE=y
|
||||
+CONFIG_MARVELL_PHY=y
|
||||
+CONFIG_MICREL_PHY=y
|
||||
+CONFIG_MICROCHIP_PHY=y
|
||||
+CONFIG_MICROSEMI_PHY=y
|
||||
+CONFIG_MOTORCOMM_PHY=y
|
||||
+CONFIG_IPMS_CAN=y
|
||||
+CONFIG_IWLWIFI=y
|
||||
+CONFIG_IWLDVM=y
|
||||
+CONFIG_IWLMVM=y
|
||||
+CONFIG_INPUT_MOUSEDEV=y
|
||||
+CONFIG_INPUT_EVDEV=y
|
||||
+CONFIG_INPUT_TOUCHSCREEN=y
|
||||
+CONFIG_TOUCHSCREEN_TINKER_FT5406=y
|
||||
+CONFIG_SERIAL_8250=y
|
||||
+CONFIG_SERIAL_8250_CONSOLE=y
|
||||
+CONFIG_SERIAL_8250_NR_UARTS=6
|
||||
+CONFIG_SERIAL_8250_RUNTIME_UARTS=6
|
||||
+CONFIG_SERIAL_8250_EXTENDED=y
|
||||
+CONFIG_SERIAL_8250_MANY_PORTS=y
|
||||
+CONFIG_SERIAL_8250_DW=y
|
||||
+CONFIG_SERIAL_OF_PLATFORM=y
|
||||
+CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
|
||||
+CONFIG_TTY_PRINTK=y
|
||||
+CONFIG_VIRTIO_CONSOLE=y
|
||||
+CONFIG_HW_RANDOM=y
|
||||
+CONFIG_HW_RANDOM_VIRTIO=y
|
||||
+CONFIG_HW_RANDOM_JH7110=y
|
||||
+CONFIG_I2C_CHARDEV=y
|
||||
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||
+CONFIG_SPI=y
|
||||
+CONFIG_SPI_CADENCE_QUADSPI=y
|
||||
+CONFIG_SPI_PL022=y
|
||||
+CONFIG_SPI_SIFIVE=y
|
||||
+CONFIG_SPI_SPIDEV=y
|
||||
+# CONFIG_PTP_1588_CLOCK is not set
|
||||
+CONFIG_GPIO_SYSFS=y
|
||||
+CONFIG_GPIO_SIFIVE=y
|
||||
+CONFIG_SENSORS_SFCTEMP=y
|
||||
+CONFIG_THERMAL=y
|
||||
+CONFIG_THERMAL_WRITABLE_TRIPS=y
|
||||
+CONFIG_CPU_THERMAL=y
|
||||
+CONFIG_THERMAL_EMULATION=y
|
||||
+CONFIG_WATCHDOG=y
|
||||
+CONFIG_WATCHDOG_SYSFS=y
|
||||
+CONFIG_MFD_AXP20X_I2C=y
|
||||
+CONFIG_REGULATOR=y
|
||||
+CONFIG_REGULATOR_AXP20X=y
|
||||
+CONFIG_REGULATOR_STARFIVE_JH7110=y
|
||||
+# CONFIG_MEDIA_CEC_SUPPORT is not set
|
||||
+CONFIG_MEDIA_SUPPORT=y
|
||||
+CONFIG_MEDIA_USB_SUPPORT=y
|
||||
+CONFIG_USB_VIDEO_CLASS=y
|
||||
+CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
+CONFIG_V4L_MEM2MEM_DRIVERS=y
|
||||
+CONFIG_VIDEO_WAVE_VPU=m
|
||||
+CONFIG_VIN_SENSOR_SC2235=y
|
||||
+CONFIG_VIN_SENSOR_OV4689=y
|
||||
+CONFIG_VIN_SENSOR_IMX219=y
|
||||
+CONFIG_VIDEO_STF_VIN=y
|
||||
+CONFIG_VIDEO_IMX708=y
|
||||
+CONFIG_DRM_I2C_NXP_TDA998X=y
|
||||
+CONFIG_DRM_I2C_NXP_TDA9950=y
|
||||
+CONFIG_DRM_RADEON=m
|
||||
+CONFIG_DRM_VIRTIO_GPU=m
|
||||
+CONFIG_DRM_VERISILICON=y
|
||||
+CONFIG_STARFIVE_INNO_HDMI=y
|
||||
+CONFIG_STARFIVE_DSI=y
|
||||
+CONFIG_DRM_IMG_ROGUE=y
|
||||
+CONFIG_DRM_LEGACY=y
|
||||
+CONFIG_FB=y
|
||||
+CONFIG_SOUND=y
|
||||
+CONFIG_SND=y
|
||||
+CONFIG_SND_USB_AUDIO=y
|
||||
+CONFIG_SND_SOC=y
|
||||
+CONFIG_SND_DESIGNWARE_I2S=y
|
||||
+# CONFIG_SND_SOC_INTEL_SST_TOPLEVEL is not set
|
||||
+CONFIG_SND_SOC_STARFIVE=y
|
||||
+CONFIG_SND_SOC_JH7110_PDM=y
|
||||
+CONFIG_SND_SOC_JH7110_PWMDAC=y
|
||||
+CONFIG_SND_SOC_JH7110_SPDIF=y
|
||||
+CONFIG_SND_SOC_JH7110_TDM=y
|
||||
+CONFIG_SND_SOC_AC108=y
|
||||
+CONFIG_SND_SOC_WM8960=y
|
||||
+CONFIG_SND_SIMPLE_CARD=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_XHCI_HCD=y
|
||||
+CONFIG_USB_EHCI_HCD=y
|
||||
+CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
+CONFIG_USB_OHCI_HCD=y
|
||||
+CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||
+CONFIG_USB_STORAGE=y
|
||||
+CONFIG_USB_UAS=y
|
||||
+CONFIG_USB_CDNS_SUPPORT=y
|
||||
+CONFIG_USB_CDNS3=y
|
||||
+CONFIG_USB_CDNS3_GADGET=y
|
||||
+CONFIG_USB_CDNS3_HOST=y
|
||||
+CONFIG_USB_CDNS3_STARFIVE=y
|
||||
+CONFIG_USB_GADGET=y
|
||||
+CONFIG_USB_CONFIGFS=y
|
||||
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
|
||||
+CONFIG_USB_CONFIGFS_F_FS=y
|
||||
+CONFIG_MMC=y
|
||||
+CONFIG_MMC_SDHCI=y
|
||||
+CONFIG_MMC_SDHCI_PLTFM=y
|
||||
+CONFIG_MMC_SDHCI_CADENCE=y
|
||||
+CONFIG_MMC_SPI=y
|
||||
+CONFIG_MMC_DW=y
|
||||
+CONFIG_MMC_DW_STARFIVE=y
|
||||
+CONFIG_RTC_CLASS=y
|
||||
+# CONFIG_RTC_DRV_SPEAR is not set
|
||||
+CONFIG_RTC_DRV_STARFIVE=y
|
||||
+CONFIG_DMADEVICES=y
|
||||
+CONFIG_AMBA_PL08X=y
|
||||
+CONFIG_DW_AXI_DMAC=y
|
||||
+# CONFIG_SH_DMAE_BASE is not set
|
||||
+# CONFIG_TI_EDMA is not set
|
||||
+# CONFIG_DMA_OMAP is not set
|
||||
+CONFIG_DMATEST=y
|
||||
+CONFIG_VIRTIO_PCI=y
|
||||
+CONFIG_VIRTIO_BALLOON=y
|
||||
+CONFIG_VIRTIO_INPUT=y
|
||||
+CONFIG_VIRTIO_MMIO=y
|
||||
+CONFIG_STAGING=y
|
||||
+CONFIG_STAGING_MEDIA=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_AON=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_STG=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_ISP=y
|
||||
+CONFIG_CLK_STARFIVE_JH7110_VOUT=y
|
||||
+CONFIG_MAILBOX=y
|
||||
+CONFIG_STARFIVE_MBOX=m
|
||||
+CONFIG_STARFIVE_MBOX_TEST=m
|
||||
+CONFIG_RPMSG_CHAR=y
|
||||
+CONFIG_RPMSG_CTRL=y
|
||||
+CONFIG_RPMSG_VIRTIO=y
|
||||
+CONFIG_SIFIVE_CCACHE=y
|
||||
+CONFIG_PWM=y
|
||||
+CONFIG_PWM_OCORES=y
|
||||
+CONFIG_PHY_STARFIVE_JH7110_PCIE=y
|
||||
+CONFIG_PHY_STARFIVE_JH7110_USB=y
|
||||
+CONFIG_PHY_M31_DPHY_RX0=y
|
||||
+CONFIG_EXT4_FS=y
|
||||
+CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
+CONFIG_EXT4_FS_SECURITY=y
|
||||
+CONFIG_BTRFS_FS=m
|
||||
+CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
+CONFIG_AUTOFS_FS=y
|
||||
+CONFIG_FUSE_FS=y
|
||||
+CONFIG_OVERLAY_FS=y
|
||||
+CONFIG_OVERLAY_FS_INDEX=y
|
||||
+CONFIG_OVERLAY_FS_XINO_AUTO=y
|
||||
+CONFIG_OVERLAY_FS_METACOPY=y
|
||||
+CONFIG_ISO9660_FS=y
|
||||
+CONFIG_JOLIET=y
|
||||
+CONFIG_ZISOFS=y
|
||||
+CONFIG_MSDOS_FS=y
|
||||
+CONFIG_VFAT_FS=y
|
||||
+CONFIG_EXFAT_FS=y
|
||||
+CONFIG_TMPFS=y
|
||||
+CONFIG_TMPFS_POSIX_ACL=y
|
||||
+CONFIG_HUGETLBFS=y
|
||||
+CONFIG_JFFS2_FS=y
|
||||
+CONFIG_NFS_FS=y
|
||||
+CONFIG_NFS_V4=y
|
||||
+CONFIG_NFS_V4_1=y
|
||||
+CONFIG_NFS_V4_2=y
|
||||
+CONFIG_ROOT_NFS=y
|
||||
+CONFIG_9P_FS=y
|
||||
+CONFIG_NLS_CODEPAGE_437=y
|
||||
+CONFIG_NLS_ISO8859_1=m
|
||||
+CONFIG_SECURITY=y
|
||||
+CONFIG_SECURITY_SELINUX=y
|
||||
+CONFIG_SECURITY_APPARMOR=y
|
||||
+CONFIG_DEFAULT_SECURITY_DAC=y
|
||||
+CONFIG_LSM=""
|
||||
+CONFIG_INIT_STACK_NONE=y
|
||||
+CONFIG_CRYPTO_USER=y
|
||||
+CONFIG_CRYPTO_ZSTD=y
|
||||
+CONFIG_CRYPTO_USER_API_HASH=y
|
||||
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
|
||||
+CONFIG_CRYPTO_USER_API_AEAD=y
|
||||
+CONFIG_CRYPTO_STATS=y
|
||||
+CONFIG_CRYPTO_DEV_VIRTIO=y
|
||||
+CONFIG_CRYPTO_DEV_JH7110=y
|
||||
+CONFIG_DMA_CMA=y
|
||||
+CONFIG_PRINTK_TIME=y
|
||||
+CONFIG_DEBUG_FS=y
|
||||
+CONFIG_DEBUG_PAGEALLOC=y
|
||||
+CONFIG_SCHED_STACK_END_CHECK=y
|
||||
+CONFIG_DEBUG_VM=y
|
||||
+CONFIG_DEBUG_VM_PGFLAGS=y
|
||||
+CONFIG_DEBUG_MEMORY_INIT=y
|
||||
+CONFIG_DEBUG_PER_CPU_MAPS=y
|
||||
+CONFIG_SOFTLOCKUP_DETECTOR=y
|
||||
+CONFIG_WQ_WATCHDOG=y
|
||||
+CONFIG_DEBUG_TIMEKEEPING=y
|
||||
+CONFIG_DEBUG_RT_MUTEXES=y
|
||||
+CONFIG_DEBUG_SPINLOCK=y
|
||||
+CONFIG_DEBUG_MUTEXES=y
|
||||
+CONFIG_DEBUG_RWSEMS=y
|
||||
+CONFIG_DEBUG_LIST=y
|
||||
+CONFIG_DEBUG_PLIST=y
|
||||
+CONFIG_DEBUG_SG=y
|
||||
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
|
||||
+# CONFIG_RCU_TRACE is not set
|
||||
+CONFIG_RCU_EQS_DEBUG=y
|
||||
+# CONFIG_FTRACE is not set
|
||||
+# CONFIG_RUNTIME_TESTING_MENU is not set
|
||||
+CONFIG_MEMTEST=y
|
@ -0,0 +1,318 @@
|
||||
From 95c702022f5e4cb786719fcf90170334b1e562cc Mon Sep 17 00:00:00 2001
|
||||
From: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Date: Thu, 16 Jun 2022 17:13:57 +0800
|
||||
Subject: [PATCH 060/116] of: configfs: Add configfs function
|
||||
|
||||
Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
drivers/of/Kconfig | 7 ++
|
||||
drivers/of/Makefile | 1 +
|
||||
drivers/of/configfs.c | 277 ++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 285 insertions(+)
|
||||
create mode 100644 drivers/of/configfs.c
|
||||
|
||||
--- a/drivers/of/Kconfig
|
||||
+++ b/drivers/of/Kconfig
|
||||
@@ -102,4 +102,11 @@ config OF_OVERLAY
|
||||
config OF_NUMA
|
||||
bool
|
||||
|
||||
+config OF_CONFIGFS
|
||||
+ bool "Device Tree Overlay ConfigFS interface"
|
||||
+ select CONFIGFS_FS
|
||||
+ select OF_OVERLAY
|
||||
+ help
|
||||
+ Enable a simple user-space driven DT overlay interface.
|
||||
+
|
||||
endif # OF
|
||||
--- a/drivers/of/Makefile
|
||||
+++ b/drivers/of/Makefile
|
||||
@@ -11,6 +11,7 @@ obj-$(CONFIG_OF_UNITTEST) += unittest.o
|
||||
obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
|
||||
obj-$(CONFIG_OF_RESOLVE) += resolver.o
|
||||
obj-$(CONFIG_OF_OVERLAY) += overlay.o
|
||||
+obj-$(CONFIG_OF_CONFIGFS) += configfs.o
|
||||
obj-$(CONFIG_OF_NUMA) += of_numa.o
|
||||
|
||||
ifdef CONFIG_KEXEC_FILE
|
||||
--- /dev/null
|
||||
+++ b/drivers/of/configfs.c
|
||||
@@ -0,0 +1,277 @@
|
||||
+/*
|
||||
+ * Configfs entries for device-tree
|
||||
+ *
|
||||
+ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License
|
||||
+ * as published by the Free Software Foundation; either version
|
||||
+ * 2 of the License, or (at your option) any later version.
|
||||
+ */
|
||||
+#include <linux/ctype.h>
|
||||
+#include <linux/cpu.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_fdt.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/proc_fs.h>
|
||||
+#include <linux/configfs.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/stat.h>
|
||||
+#include <linux/limits.h>
|
||||
+#include <linux/file.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/firmware.h>
|
||||
+#include <linux/sizes.h>
|
||||
+
|
||||
+#include "of_private.h"
|
||||
+
|
||||
+struct cfs_overlay_item {
|
||||
+ struct config_item item;
|
||||
+
|
||||
+ char path[PATH_MAX];
|
||||
+
|
||||
+ const struct firmware *fw;
|
||||
+ struct device_node *overlay;
|
||||
+ int ov_id;
|
||||
+
|
||||
+ void *dtbo;
|
||||
+ int dtbo_size;
|
||||
+};
|
||||
+
|
||||
+static inline struct cfs_overlay_item *to_cfs_overlay_item(
|
||||
+ struct config_item *item)
|
||||
+{
|
||||
+ return item ? container_of(item, struct cfs_overlay_item, item) : NULL;
|
||||
+}
|
||||
+
|
||||
+static ssize_t cfs_overlay_item_path_show(struct config_item *item,
|
||||
+ char *page)
|
||||
+{
|
||||
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
|
||||
+ return sprintf(page, "%s\n", overlay->path);
|
||||
+}
|
||||
+
|
||||
+static ssize_t cfs_overlay_item_path_store(struct config_item *item,
|
||||
+ const char *page, size_t count)
|
||||
+{
|
||||
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
|
||||
+ const char *p = page;
|
||||
+ char *s;
|
||||
+ int err;
|
||||
+
|
||||
+ /* if it's set do not allow changes */
|
||||
+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ /* copy to path buffer (and make sure it's always zero terminated */
|
||||
+ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p);
|
||||
+ overlay->path[sizeof(overlay->path) - 1] = '\0';
|
||||
+
|
||||
+ /* strip trailing newlines */
|
||||
+ s = overlay->path + strlen(overlay->path);
|
||||
+ while (s > overlay->path && *--s == '\n')
|
||||
+ *s = '\0';
|
||||
+
|
||||
+ pr_debug("%s: path is '%s'\n", __func__, overlay->path);
|
||||
+
|
||||
+ err = request_firmware(&overlay->fw, overlay->path, NULL);
|
||||
+ if (err != 0)
|
||||
+ return err;
|
||||
+
|
||||
+ err = of_overlay_fdt_apply((void *)overlay->fw->data,
|
||||
+ (u32)overlay->fw->size, &overlay->ov_id, NULL);
|
||||
+ if (err != 0)
|
||||
+ goto out_err;
|
||||
+
|
||||
+ return count;
|
||||
+
|
||||
+out_err:
|
||||
+
|
||||
+ release_firmware(overlay->fw);
|
||||
+ overlay->fw = NULL;
|
||||
+
|
||||
+ overlay->path[0] = '\0';
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static ssize_t cfs_overlay_item_status_show(struct config_item *item,
|
||||
+ char *page)
|
||||
+{
|
||||
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
|
||||
+
|
||||
+ return sprintf(page, "%s\n",
|
||||
+ overlay->ov_id > 0 ? "applied" : "unapplied");
|
||||
+}
|
||||
+
|
||||
+CONFIGFS_ATTR(cfs_overlay_item_, path);
|
||||
+CONFIGFS_ATTR_RO(cfs_overlay_item_, status);
|
||||
+
|
||||
+static struct configfs_attribute *cfs_overlay_attrs[] = {
|
||||
+ &cfs_overlay_item_attr_path,
|
||||
+ &cfs_overlay_item_attr_status,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+ssize_t cfs_overlay_item_dtbo_read(struct config_item *item,
|
||||
+ void *buf, size_t max_count)
|
||||
+{
|
||||
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
|
||||
+
|
||||
+ pr_debug("%s: buf=%p max_count=%zu\n", __func__,
|
||||
+ buf, max_count);
|
||||
+
|
||||
+ if (overlay->dtbo == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* copy if buffer provided */
|
||||
+ if (buf != NULL) {
|
||||
+ /* the buffer must be large enough */
|
||||
+ if (overlay->dtbo_size > max_count)
|
||||
+ return -ENOSPC;
|
||||
+
|
||||
+ memcpy(buf, overlay->dtbo, overlay->dtbo_size);
|
||||
+ }
|
||||
+
|
||||
+ return overlay->dtbo_size;
|
||||
+}
|
||||
+
|
||||
+ssize_t cfs_overlay_item_dtbo_write(struct config_item *item,
|
||||
+ const void *buf, size_t count)
|
||||
+{
|
||||
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
|
||||
+ int err;
|
||||
+
|
||||
+ /* if it's set do not allow changes */
|
||||
+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ /* copy the contents */
|
||||
+ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL);
|
||||
+ if (overlay->dtbo == NULL)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ overlay->dtbo_size = count;
|
||||
+
|
||||
+ err = of_overlay_fdt_apply(overlay->dtbo, overlay->dtbo_size,
|
||||
+ &overlay->ov_id, NULL);
|
||||
+ if (err != 0)
|
||||
+ goto out_err;
|
||||
+
|
||||
+ return count;
|
||||
+
|
||||
+out_err:
|
||||
+ kfree(overlay->dtbo);
|
||||
+ overlay->dtbo = NULL;
|
||||
+ overlay->dtbo_size = 0;
|
||||
+ overlay->ov_id = 0;
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M);
|
||||
+
|
||||
+static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = {
|
||||
+ &cfs_overlay_item_attr_dtbo,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static void cfs_overlay_release(struct config_item *item)
|
||||
+{
|
||||
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
|
||||
+
|
||||
+ if (overlay->ov_id > 0)
|
||||
+ of_overlay_remove(&overlay->ov_id);
|
||||
+ if (overlay->fw)
|
||||
+ release_firmware(overlay->fw);
|
||||
+ /* kfree with NULL is safe */
|
||||
+ kfree(overlay->dtbo);
|
||||
+ kfree(overlay);
|
||||
+}
|
||||
+
|
||||
+static struct configfs_item_operations cfs_overlay_item_ops = {
|
||||
+ .release = cfs_overlay_release,
|
||||
+};
|
||||
+
|
||||
+static struct config_item_type cfs_overlay_type = {
|
||||
+ .ct_item_ops = &cfs_overlay_item_ops,
|
||||
+ .ct_attrs = cfs_overlay_attrs,
|
||||
+ .ct_bin_attrs = cfs_overlay_bin_attrs,
|
||||
+ .ct_owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static struct config_item *cfs_overlay_group_make_item(
|
||||
+ struct config_group *group, const char *name)
|
||||
+{
|
||||
+ struct cfs_overlay_item *overlay;
|
||||
+
|
||||
+ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
|
||||
+ if (!overlay)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type);
|
||||
+ return &overlay->item;
|
||||
+}
|
||||
+
|
||||
+static void cfs_overlay_group_drop_item(struct config_group *group,
|
||||
+ struct config_item *item)
|
||||
+{
|
||||
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
|
||||
+
|
||||
+ config_item_put(&overlay->item);
|
||||
+}
|
||||
+
|
||||
+static struct configfs_group_operations overlays_ops = {
|
||||
+ .make_item = cfs_overlay_group_make_item,
|
||||
+ .drop_item = cfs_overlay_group_drop_item,
|
||||
+};
|
||||
+
|
||||
+static struct config_item_type overlays_type = {
|
||||
+ .ct_group_ops = &overlays_ops,
|
||||
+ .ct_owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static struct configfs_group_operations of_cfs_ops = {
|
||||
+ /* empty - we don't allow anything to be created */
|
||||
+};
|
||||
+
|
||||
+static struct config_item_type of_cfs_type = {
|
||||
+ .ct_group_ops = &of_cfs_ops,
|
||||
+ .ct_owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+struct config_group of_cfs_overlay_group;
|
||||
+
|
||||
+static struct configfs_subsystem of_cfs_subsys = {
|
||||
+ .su_group = {
|
||||
+ .cg_item = {
|
||||
+ .ci_namebuf = "device-tree",
|
||||
+ .ci_type = &of_cfs_type,
|
||||
+ },
|
||||
+ },
|
||||
+ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex),
|
||||
+};
|
||||
+
|
||||
+static int __init of_cfs_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ pr_info("%s\n", __func__);
|
||||
+
|
||||
+ config_group_init(&of_cfs_subsys.su_group);
|
||||
+ config_group_init_type_name(&of_cfs_overlay_group, "overlays",
|
||||
+ &overlays_type);
|
||||
+ configfs_add_default_group(&of_cfs_overlay_group,
|
||||
+ &of_cfs_subsys.su_group);
|
||||
+
|
||||
+ ret = configfs_register_subsystem(&of_cfs_subsys);
|
||||
+ if (ret != 0) {
|
||||
+ pr_err("%s: failed to register subsys\n", __func__);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ pr_info("%s: OK\n", __func__);
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+late_initcall(of_cfs_init);
|
@ -0,0 +1,344 @@
|
||||
From 7891826f8c2de9ee0f6459cf969f7b082e29b154 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Thu, 1 Jun 2023 23:10:09 -0700
|
||||
Subject: [PATCH 061/116] usr: Add gen_initramfs_list.sh
|
||||
|
||||
Add gen_initramfs_list.sh
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
usr/gen_initramfs_list.sh | 328 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 328 insertions(+)
|
||||
create mode 100644 usr/gen_initramfs_list.sh
|
||||
|
||||
--- /dev/null
|
||||
+++ b/usr/gen_initramfs_list.sh
|
||||
@@ -0,0 +1,328 @@
|
||||
+#!/bin/sh
|
||||
+# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
|
||||
+# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
|
||||
+#
|
||||
+# Released under the terms of the GNU GPL
|
||||
+#
|
||||
+# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
|
||||
+# the cpio archive, and then compresses it.
|
||||
+# The script may also be used to generate the inputfile used for gen_init_cpio
|
||||
+# This script assumes that gen_init_cpio is located in usr/ directory
|
||||
+
|
||||
+# error out on errors
|
||||
+set -e
|
||||
+
|
||||
+usage() {
|
||||
+cat << EOF
|
||||
+Usage:
|
||||
+$0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
|
||||
+ -o <file> Create compressed initramfs file named <file> using
|
||||
+ gen_init_cpio and compressor depending on the extension
|
||||
+ -u <uid> User ID to map to user ID 0 (root).
|
||||
+ <uid> is only meaningful if <cpio_source> is a
|
||||
+ directory. "squash" forces all files to uid 0.
|
||||
+ -g <gid> Group ID to map to group ID 0 (root).
|
||||
+ <gid> is only meaningful if <cpio_source> is a
|
||||
+ directory. "squash" forces all files to gid 0.
|
||||
+ <cpio_source> File list or directory for cpio archive.
|
||||
+ If <cpio_source> is a .cpio file it will be used
|
||||
+ as direct input to initramfs.
|
||||
+ -d Output the default cpio list.
|
||||
+
|
||||
+All options except -o and -l may be repeated and are interpreted
|
||||
+sequentially and immediately. -u and -g states are preserved across
|
||||
+<cpio_source> options so an explicit "-u 0 -g 0" is required
|
||||
+to reset the root/group mapping.
|
||||
+EOF
|
||||
+}
|
||||
+
|
||||
+# awk style field access
|
||||
+# $1 - field number; rest is argument string
|
||||
+field() {
|
||||
+ shift $1 ; echo $1
|
||||
+}
|
||||
+
|
||||
+list_default_initramfs() {
|
||||
+ # echo usr/kinit/kinit
|
||||
+ :
|
||||
+}
|
||||
+
|
||||
+default_initramfs() {
|
||||
+ cat <<-EOF >> ${output}
|
||||
+ # This is a very simple, default initramfs
|
||||
+
|
||||
+ dir /dev 0755 0 0
|
||||
+ nod /dev/console 0600 0 0 c 5 1
|
||||
+ dir /root 0700 0 0
|
||||
+ # file /kinit usr/kinit/kinit 0755 0 0
|
||||
+ # slink /init kinit 0755 0 0
|
||||
+ EOF
|
||||
+}
|
||||
+
|
||||
+filetype() {
|
||||
+ local argv1="$1"
|
||||
+
|
||||
+ # symlink test must come before file test
|
||||
+ if [ -L "${argv1}" ]; then
|
||||
+ echo "slink"
|
||||
+ elif [ -f "${argv1}" ]; then
|
||||
+ echo "file"
|
||||
+ elif [ -d "${argv1}" ]; then
|
||||
+ echo "dir"
|
||||
+ elif [ -b "${argv1}" -o -c "${argv1}" ]; then
|
||||
+ echo "nod"
|
||||
+ elif [ -p "${argv1}" ]; then
|
||||
+ echo "pipe"
|
||||
+ elif [ -S "${argv1}" ]; then
|
||||
+ echo "sock"
|
||||
+ else
|
||||
+ echo "invalid"
|
||||
+ fi
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+list_print_mtime() {
|
||||
+ :
|
||||
+}
|
||||
+
|
||||
+print_mtime() {
|
||||
+ local my_mtime="0"
|
||||
+
|
||||
+ if [ -e "$1" ]; then
|
||||
+ my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
|
||||
+ fi
|
||||
+
|
||||
+ echo "# Last modified: ${my_mtime}" >> ${output}
|
||||
+ echo "" >> ${output}
|
||||
+}
|
||||
+
|
||||
+list_parse() {
|
||||
+ if [ -L "$1" ]; then
|
||||
+ return
|
||||
+ fi
|
||||
+ echo "$1" | sed 's/:/\\:/g; s/$/ \\/'
|
||||
+}
|
||||
+
|
||||
+# for each file print a line in following format
|
||||
+# <filetype> <name> <path to file> <octal mode> <uid> <gid>
|
||||
+# for links, devices etc the format differs. See gen_init_cpio for details
|
||||
+parse() {
|
||||
+ local location="$1"
|
||||
+ local name="/${location#${srcdir}}"
|
||||
+ # change '//' into '/'
|
||||
+ name=$(echo "$name" | sed -e 's://*:/:g')
|
||||
+ local mode="$2"
|
||||
+ local uid="$3"
|
||||
+ local gid="$4"
|
||||
+ local ftype=$(filetype "${location}")
|
||||
+ # remap uid/gid to 0 if necessary
|
||||
+ [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
|
||||
+ [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0
|
||||
+ local str="${mode} ${uid} ${gid}"
|
||||
+
|
||||
+ [ "${ftype}" = "invalid" ] && return 0
|
||||
+ [ "${location}" = "${srcdir}" ] && return 0
|
||||
+
|
||||
+ case "${ftype}" in
|
||||
+ "file")
|
||||
+ str="${ftype} ${name} ${location} ${str}"
|
||||
+ ;;
|
||||
+ "nod")
|
||||
+ local dev=`LC_ALL=C ls -l "${location}"`
|
||||
+ local maj=`field 5 ${dev}`
|
||||
+ local min=`field 6 ${dev}`
|
||||
+ maj=${maj%,}
|
||||
+
|
||||
+ [ -b "${location}" ] && dev="b" || dev="c"
|
||||
+
|
||||
+ str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
|
||||
+ ;;
|
||||
+ "slink")
|
||||
+ local target=`readlink "${location}"`
|
||||
+ str="${ftype} ${name} ${target} ${str}"
|
||||
+ ;;
|
||||
+ *)
|
||||
+ str="${ftype} ${name} ${str}"
|
||||
+ ;;
|
||||
+ esac
|
||||
+
|
||||
+ echo "${str}" >> ${output}
|
||||
+
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+unknown_option() {
|
||||
+ printf "ERROR: unknown option \"$arg\"\n" >&2
|
||||
+ printf "If the filename validly begins with '-', " >&2
|
||||
+ printf "then it must be prefixed\n" >&2
|
||||
+ printf "by './' so that it won't be interpreted as an option." >&2
|
||||
+ printf "\n" >&2
|
||||
+ usage >&2
|
||||
+ exit 1
|
||||
+}
|
||||
+
|
||||
+list_header() {
|
||||
+ :
|
||||
+}
|
||||
+
|
||||
+header() {
|
||||
+ printf "\n#####################\n# $1\n" >> ${output}
|
||||
+}
|
||||
+
|
||||
+# process one directory (incl sub-directories)
|
||||
+dir_filelist() {
|
||||
+ ${dep_list}header "$1"
|
||||
+
|
||||
+ srcdir=$(echo "$1" | sed -e 's://*:/:g')
|
||||
+ dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LANG=C sort)
|
||||
+
|
||||
+ # If $dirlist is only one line, then the directory is empty
|
||||
+ if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
|
||||
+ ${dep_list}print_mtime "$1"
|
||||
+
|
||||
+ echo "${dirlist}" | \
|
||||
+ while read x; do
|
||||
+ ${dep_list}parse ${x}
|
||||
+ done
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+# if only one file is specified and it is .cpio file then use it direct as fs
|
||||
+# if a directory is specified then add all files in given direcotry to fs
|
||||
+# if a regular file is specified assume it is in gen_initramfs format
|
||||
+input_file() {
|
||||
+ source="$1"
|
||||
+ if [ -f "$1" ]; then
|
||||
+ ${dep_list}header "$1"
|
||||
+ is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\{0,1\}/cpio/')"
|
||||
+ if [ $2 -eq 0 -a ${is_cpio} = "cpio" ]; then
|
||||
+ cpio_file=$1
|
||||
+ echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed"
|
||||
+ [ ! -z ${dep_list} ] && echo "$1"
|
||||
+ return 0
|
||||
+ fi
|
||||
+ if [ -z ${dep_list} ]; then
|
||||
+ print_mtime "$1" >> ${output}
|
||||
+ cat "$1" >> ${output}
|
||||
+ else
|
||||
+ echo "$1 \\"
|
||||
+ cat "$1" | while read type dir file perm ; do
|
||||
+ if [ "$type" = "file" ]; then
|
||||
+ echo "$file \\";
|
||||
+ fi
|
||||
+ done
|
||||
+ fi
|
||||
+ elif [ -d "$1" ]; then
|
||||
+ dir_filelist "$1"
|
||||
+ else
|
||||
+ echo " ${prog}: Cannot open '$1'" >&2
|
||||
+ exit 1
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+prog=$0
|
||||
+root_uid=0
|
||||
+root_gid=0
|
||||
+dep_list=
|
||||
+cpio_file=
|
||||
+cpio_list=
|
||||
+output="/dev/stdout"
|
||||
+output_file=""
|
||||
+is_cpio_compressed=
|
||||
+compr="gzip -n -9 -f"
|
||||
+
|
||||
+arg="$1"
|
||||
+case "$arg" in
|
||||
+ "-l") # files included in initramfs - used by kbuild
|
||||
+ dep_list="list_"
|
||||
+ echo "deps_initramfs := $0 \\"
|
||||
+ shift
|
||||
+ ;;
|
||||
+ "-o") # generate compressed cpio image named $1
|
||||
+ shift
|
||||
+ output_file="$1"
|
||||
+ cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
|
||||
+ output=${cpio_list}
|
||||
+ echo "$output_file" | grep -q "\.gz$" \
|
||||
+ && [ -x "`which gzip 2> /dev/null`" ] \
|
||||
+ && compr="gzip -n -9 -f"
|
||||
+ echo "$output_file" | grep -q "\.bz2$" \
|
||||
+ && [ -x "`which bzip2 2> /dev/null`" ] \
|
||||
+ && compr="bzip2 -9 -f"
|
||||
+ echo "$output_file" | grep -q "\.lzma$" \
|
||||
+ && [ -x "`which lzma 2> /dev/null`" ] \
|
||||
+ && compr="lzma -9 -f"
|
||||
+ echo "$output_file" | grep -q "\.xz$" \
|
||||
+ && [ -x "`which xz 2> /dev/null`" ] \
|
||||
+ && compr="xz --check=crc32 --lzma2=dict=1MiB"
|
||||
+ echo "$output_file" | grep -q "\.lzo$" \
|
||||
+ && [ -x "`which lzop 2> /dev/null`" ] \
|
||||
+ && compr="lzop -9 -f"
|
||||
+ echo "$output_file" | grep -q "\.lz4$" \
|
||||
+ && [ -x "`which lz4 2> /dev/null`" ] \
|
||||
+ && compr="lz4 -l -9 -f"
|
||||
+ echo "$output_file" | grep -q "\.cpio$" && compr="cat"
|
||||
+ shift
|
||||
+ ;;
|
||||
+esac
|
||||
+while [ $# -gt 0 ]; do
|
||||
+ arg="$1"
|
||||
+ shift
|
||||
+ case "$arg" in
|
||||
+ "-u") # map $1 to uid=0 (root)
|
||||
+ root_uid="$1"
|
||||
+ [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
|
||||
+ shift
|
||||
+ ;;
|
||||
+ "-g") # map $1 to gid=0 (root)
|
||||
+ root_gid="$1"
|
||||
+ [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
|
||||
+ shift
|
||||
+ ;;
|
||||
+ "-d") # display default initramfs list
|
||||
+ default_list="$arg"
|
||||
+ ${dep_list}default_initramfs
|
||||
+ ;;
|
||||
+ "-h")
|
||||
+ usage
|
||||
+ exit 0
|
||||
+ ;;
|
||||
+ *)
|
||||
+ case "$arg" in
|
||||
+ "-"*)
|
||||
+ unknown_option
|
||||
+ ;;
|
||||
+ *) # input file/dir - process it
|
||||
+ input_file "$arg" "$#"
|
||||
+ ;;
|
||||
+ esac
|
||||
+ ;;
|
||||
+ esac
|
||||
+done
|
||||
+
|
||||
+# If output_file is set we will generate cpio archive and compress it
|
||||
+# we are careful to delete tmp files
|
||||
+if [ ! -z ${output_file} ]; then
|
||||
+ if [ -z ${cpio_file} ]; then
|
||||
+ timestamp=
|
||||
+ if test -n "$KBUILD_BUILD_TIMESTAMP"; then
|
||||
+ timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
|
||||
+ if test -n "$timestamp"; then
|
||||
+ timestamp="-t $timestamp"
|
||||
+ fi
|
||||
+ fi
|
||||
+ cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
|
||||
+ usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
|
||||
+ else
|
||||
+ cpio_tfile=${cpio_file}
|
||||
+ fi
|
||||
+ rm ${cpio_list}
|
||||
+ if [ "${is_cpio_compressed}" = "compressed" ]; then
|
||||
+ cat ${cpio_tfile} > ${output_file}
|
||||
+ else
|
||||
+ (cat ${cpio_tfile} | ${compr} - > ${output_file}) \
|
||||
+ || (rm -f ${output_file} ; false)
|
||||
+ fi
|
||||
+ [ -z ${cpio_file} ] && rm ${cpio_tfile}
|
||||
+fi
|
||||
+exit 0
|
@ -0,0 +1,33 @@
|
||||
From dcc2827ed6e701a65731c05b0297745559837217 Mon Sep 17 00:00:00 2001
|
||||
From: Hal Feng <hal.feng@starfivetech.com>
|
||||
Date: Fri, 12 May 2023 17:33:20 +0800
|
||||
Subject: [PATCH 062/116] i2c: designware: Delete SMBus functionalities
|
||||
|
||||
The driver didn't implement the smbus interface,
|
||||
so replace the SMBus functionalities with
|
||||
I2C_FUNC_SMBUS_EMUL.
|
||||
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
drivers/i2c/busses/i2c-designware-core.h | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/i2c/busses/i2c-designware-core.h
|
||||
+++ b/drivers/i2c/busses/i2c-designware-core.h
|
||||
@@ -18,12 +18,10 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
-#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
|
||||
- I2C_FUNC_SMBUS_BYTE | \
|
||||
- I2C_FUNC_SMBUS_BYTE_DATA | \
|
||||
- I2C_FUNC_SMBUS_WORD_DATA | \
|
||||
- I2C_FUNC_SMBUS_BLOCK_DATA | \
|
||||
- I2C_FUNC_SMBUS_I2C_BLOCK)
|
||||
+#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL \
|
||||
+ & ~I2C_FUNC_SMBUS_QUICK \
|
||||
+ & ~I2C_FUNC_SMBUS_PROC_CALL \
|
||||
+ & ~I2C_FUNC_SMBUS_PEC))
|
||||
|
||||
#define DW_IC_CON_MASTER BIT(0)
|
||||
#define DW_IC_CON_SPEED_STD (1 << 1)
|
@ -0,0 +1,26 @@
|
||||
From b61cefc6c785aa8a7177a0b535db746fd0047bd8 Mon Sep 17 00:00:00 2001
|
||||
From: Ziv Xu <ziv.xu@starfivetech.com>
|
||||
Date: Fri, 19 Jan 2024 15:22:55 +0800
|
||||
Subject: [PATCH 063/116] drivers: mtd: gigadevice: add gd25lq256d 32M flash
|
||||
support
|
||||
|
||||
add gd25lq256d 32M flash support
|
||||
|
||||
Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/gigadevice.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/gigadevice.c
|
||||
+++ b/drivers/mtd/spi-nor/gigadevice.c
|
||||
@@ -66,6 +66,10 @@ static const struct flash_info gigadevic
|
||||
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
|
||||
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
|
||||
SPI_NOR_QUAD_READ) },
|
||||
+ { "gd25lq256d", INFO(0xc86019, 0, 64 * 1024, 512)
|
||||
+ FLAGS( SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_QUAD_PP)
|
||||
+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
|
||||
+ SPI_NOR_QUAD_READ) },
|
||||
{ "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512)
|
||||
PARSE_SFDP
|
||||
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
|
@ -0,0 +1,808 @@
|
||||
From 76bc13aa12bd111f5da01e107f8d487b20b5a40c Mon Sep 17 00:00:00 2001
|
||||
From: "shanlong.li" <shanlong.li@starfivetech.com>
|
||||
Date: Thu, 8 Jun 2023 00:07:15 -0700
|
||||
Subject: [PATCH 064/116] driver: mailbox: Add mailbox driver
|
||||
|
||||
Add mailbox driver.
|
||||
|
||||
Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
drivers/mailbox/Kconfig | 13 +
|
||||
drivers/mailbox/Makefile | 4 +
|
||||
drivers/mailbox/starfive_mailbox-test.c | 407 ++++++++++++++++++++++++
|
||||
drivers/mailbox/starfive_mailbox.c | 347 ++++++++++++++++++++
|
||||
4 files changed, 771 insertions(+)
|
||||
create mode 100644 drivers/mailbox/starfive_mailbox-test.c
|
||||
create mode 100644 drivers/mailbox/starfive_mailbox.c
|
||||
|
||||
--- a/drivers/mailbox/Kconfig
|
||||
+++ b/drivers/mailbox/Kconfig
|
||||
@@ -295,4 +295,17 @@ config QCOM_IPCC
|
||||
acts as an interrupt controller for receiving interrupts from clients.
|
||||
Say Y here if you want to build this driver.
|
||||
|
||||
+config STARFIVE_MBOX
|
||||
+ tristate "Platform Starfive Mailbox"
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ Say Y here if you want to build a platform specific variant RISCV
|
||||
+ controller driver.
|
||||
+
|
||||
+config STARFIVE_MBOX_TEST
|
||||
+ tristate "Starfive Mailbox Test Client"
|
||||
+ depends on OF
|
||||
+ depends on HAS_IOMEM
|
||||
+ help
|
||||
+ Test client to help with testing new Controller driver implementations.
|
||||
endif
|
||||
--- a/drivers/mailbox/Makefile
|
||||
+++ b/drivers/mailbox/Makefile
|
||||
@@ -62,3 +62,7 @@ obj-$(CONFIG_SPRD_MBOX) += sprd-mailbox
|
||||
obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o
|
||||
|
||||
obj-$(CONFIG_APPLE_MAILBOX) += apple-mailbox.o
|
||||
+
|
||||
+obj-$(CONFIG_STARFIVE_MBOX) += starfive_mailbox.o
|
||||
+
|
||||
+obj-$(CONFIG_STARFIVE_MBOX_TEST) += starfive_mailbox-test.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/mailbox/starfive_mailbox-test.c
|
||||
@@ -0,0 +1,407 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * Copyright (C) 2015 ST Microelectronics
|
||||
+ *
|
||||
+ * Author: Lee Jones <lee.jones@linaro.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/debugfs.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/fs.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mailbox_client.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/poll.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/sched/signal.h>
|
||||
+
|
||||
+#include <linux/mailbox_controller.h>
|
||||
+
|
||||
+#define MBOX_MAX_SIG_LEN 8
|
||||
+#define MBOX_MAX_MSG_LEN 16
|
||||
+#define MBOX_BYTES_PER_LINE 16
|
||||
+#define MBOX_HEXDUMP_LINE_LEN ((MBOX_BYTES_PER_LINE * 4) + 2)
|
||||
+#define MBOX_HEXDUMP_MAX_LEN (MBOX_HEXDUMP_LINE_LEN * (MBOX_MAX_MSG_LEN / MBOX_BYTES_PER_LINE))
|
||||
+
|
||||
+static bool mbox_data_ready;
|
||||
+
|
||||
+struct mbox_test_device {
|
||||
+ struct device *dev;
|
||||
+ void __iomem *tx_mmio;
|
||||
+ void __iomem *rx_mmio;
|
||||
+ struct mbox_chan *tx_channel;
|
||||
+ struct mbox_chan *rx_channel;
|
||||
+ char *rx_buffer;
|
||||
+ char *signal;
|
||||
+ char *message;
|
||||
+ spinlock_t lock;
|
||||
+ wait_queue_head_t waitq;
|
||||
+ struct fasync_struct *async_queue;
|
||||
+ struct dentry *root_debugfs_dir;
|
||||
+};
|
||||
+
|
||||
+static ssize_t mbox_test_signal_write(struct file *filp,
|
||||
+ const char __user *userbuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct mbox_test_device *tdev = filp->private_data;
|
||||
+
|
||||
+ if (!tdev->tx_channel) {
|
||||
+ dev_err(tdev->dev, "Channel cannot do Tx\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (count > MBOX_MAX_SIG_LEN) {
|
||||
+ dev_err(tdev->dev,
|
||||
+ "Signal length %zd greater than max allowed %d\n",
|
||||
+ count, MBOX_MAX_SIG_LEN);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Only allocate memory if we need to */
|
||||
+ if (!tdev->signal) {
|
||||
+ tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL);
|
||||
+ if (!tdev->signal)
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ if (copy_from_user(tdev->signal, userbuf, count)) {
|
||||
+ kfree(tdev->signal);
|
||||
+ tdev->signal = NULL;
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations mbox_test_signal_ops = {
|
||||
+ .write = mbox_test_signal_write,
|
||||
+ .open = simple_open,
|
||||
+ .llseek = generic_file_llseek,
|
||||
+};
|
||||
+
|
||||
+static int mbox_test_message_fasync(int fd, struct file *filp, int on)
|
||||
+{
|
||||
+ struct mbox_test_device *tdev = filp->private_data;
|
||||
+
|
||||
+ return fasync_helper(fd, filp, on, &tdev->async_queue);
|
||||
+}
|
||||
+
|
||||
+static ssize_t mbox_test_message_write(struct file *filp,
|
||||
+ const char __user *userbuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct mbox_test_device *tdev = filp->private_data;
|
||||
+ void *data;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!tdev->tx_channel) {
|
||||
+ dev_err(tdev->dev, "Channel cannot do Tx\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (count > MBOX_MAX_MSG_LEN) {
|
||||
+ dev_err(tdev->dev,
|
||||
+ "Message length %zd greater than max allowed %d\n",
|
||||
+ count, MBOX_MAX_MSG_LEN);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
|
||||
+ if (!tdev->message)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = copy_from_user(tdev->message, userbuf, count);
|
||||
+ if (ret) {
|
||||
+ ret = -EFAULT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (tdev->tx_mmio && tdev->signal) {
|
||||
+ print_hex_dump_bytes("Client: Sending: Signal: ", DUMP_PREFIX_ADDRESS,
|
||||
+ tdev->signal, MBOX_MAX_SIG_LEN);
|
||||
+
|
||||
+ data = tdev->signal;
|
||||
+ } else
|
||||
+ data = tdev->message;
|
||||
+
|
||||
+ print_hex_dump_bytes("Client: Sending: Message: ", DUMP_PREFIX_ADDRESS,
|
||||
+ tdev->message, MBOX_MAX_MSG_LEN);
|
||||
+
|
||||
+ ret = mbox_send_message(tdev->tx_channel, data);
|
||||
+ mbox_chan_txdone(tdev->tx_channel, ret);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(tdev->dev, "Failed to send message via mailbox\n");
|
||||
+
|
||||
+out:
|
||||
+ kfree(tdev->signal);
|
||||
+ kfree(tdev->message);
|
||||
+ tdev->signal = NULL;
|
||||
+
|
||||
+ return ret < 0 ? ret : count;
|
||||
+}
|
||||
+
|
||||
+static bool mbox_test_message_data_ready(struct mbox_test_device *tdev)
|
||||
+{
|
||||
+ bool data_ready;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&tdev->lock, flags);
|
||||
+ data_ready = mbox_data_ready;
|
||||
+ spin_unlock_irqrestore(&tdev->lock, flags);
|
||||
+
|
||||
+ return data_ready;
|
||||
+}
|
||||
+
|
||||
+static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct mbox_test_device *tdev = filp->private_data;
|
||||
+ unsigned long flags;
|
||||
+ char *touser, *ptr;
|
||||
+ int ret;
|
||||
+
|
||||
+ touser = kzalloc(MBOX_HEXDUMP_MAX_LEN + 1, GFP_KERNEL);
|
||||
+ if (!touser)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (!tdev->rx_channel) {
|
||||
+ ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n");
|
||||
+ ret = simple_read_from_buffer(userbuf, count, ppos,
|
||||
+ touser, ret);
|
||||
+ goto kfree_err;
|
||||
+ }
|
||||
+
|
||||
+ do {
|
||||
+ if (mbox_test_message_data_ready(tdev))
|
||||
+ break;
|
||||
+
|
||||
+ if (filp->f_flags & O_NONBLOCK) {
|
||||
+ ret = -EAGAIN;
|
||||
+ goto waitq_err;
|
||||
+ }
|
||||
+
|
||||
+ if (signal_pending(current)) {
|
||||
+ ret = -ERESTARTSYS;
|
||||
+ goto waitq_err;
|
||||
+ }
|
||||
+ schedule();
|
||||
+
|
||||
+ } while (1);
|
||||
+
|
||||
+ spin_lock_irqsave(&tdev->lock, flags);
|
||||
+
|
||||
+ ptr = tdev->rx_buffer;
|
||||
+
|
||||
+ mbox_data_ready = false;
|
||||
+
|
||||
+ spin_unlock_irqrestore(&tdev->lock, flags);
|
||||
+ if (copy_to_user((void __user *)userbuf, ptr, 4))
|
||||
+ ret = -EFAULT;
|
||||
+
|
||||
+waitq_err:
|
||||
+ __set_current_state(TASK_RUNNING);
|
||||
+kfree_err:
|
||||
+ kfree(touser);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static __poll_t
|
||||
+mbox_test_message_poll(struct file *filp, struct poll_table_struct *wait)
|
||||
+{
|
||||
+ struct mbox_test_device *tdev = filp->private_data;
|
||||
+
|
||||
+ poll_wait(filp, &tdev->waitq, wait);
|
||||
+
|
||||
+ if (mbox_test_message_data_ready(tdev))
|
||||
+ return EPOLLIN | EPOLLRDNORM;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations mbox_test_message_ops = {
|
||||
+ .write = mbox_test_message_write,
|
||||
+ .read = mbox_test_message_read,
|
||||
+ .fasync = mbox_test_message_fasync,
|
||||
+ .poll = mbox_test_message_poll,
|
||||
+ .open = simple_open,
|
||||
+ .llseek = generic_file_llseek,
|
||||
+};
|
||||
+
|
||||
+static int mbox_test_add_debugfs(struct platform_device *pdev,
|
||||
+ struct mbox_test_device *tdev)
|
||||
+{
|
||||
+ if (!debugfs_initialized())
|
||||
+ return 0;
|
||||
+
|
||||
+ tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
|
||||
+ if (!tdev->root_debugfs_dir) {
|
||||
+ dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ debugfs_create_file("message", 0600, tdev->root_debugfs_dir,
|
||||
+ tdev, &mbox_test_message_ops);
|
||||
+
|
||||
+ debugfs_create_file("signal", 0200, tdev->root_debugfs_dir,
|
||||
+ tdev, &mbox_test_signal_ops);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mbox_test_receive_message(struct mbox_client *client, void *message)
|
||||
+{
|
||||
+ struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&tdev->lock, flags);
|
||||
+ if (tdev->rx_mmio) {
|
||||
+ memcpy_fromio(tdev->rx_buffer, tdev->rx_mmio, MBOX_MAX_MSG_LEN);
|
||||
+ print_hex_dump_bytes("Client: Received [MMIO]: ", DUMP_PREFIX_ADDRESS,
|
||||
+ tdev->rx_buffer, MBOX_MAX_MSG_LEN);
|
||||
+ } else if (message) {
|
||||
+ print_hex_dump_bytes("Client: Received [API]: ", DUMP_PREFIX_ADDRESS,
|
||||
+ message, MBOX_MAX_MSG_LEN);
|
||||
+ memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN);
|
||||
+ }
|
||||
+ mbox_data_ready = true;
|
||||
+ spin_unlock_irqrestore(&tdev->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void mbox_test_prepare_message(struct mbox_client *client, void *message)
|
||||
+{
|
||||
+ struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
|
||||
+
|
||||
+ if (tdev->tx_mmio) {
|
||||
+ if (tdev->signal)
|
||||
+ memcpy_toio(tdev->tx_mmio, tdev->message, MBOX_MAX_MSG_LEN);
|
||||
+ else
|
||||
+ memcpy_toio(tdev->tx_mmio, message, MBOX_MAX_MSG_LEN);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct mbox_chan *
|
||||
+mbox_test_request_channel(struct platform_device *pdev, const char *name)
|
||||
+{
|
||||
+ struct mbox_client *client;
|
||||
+ struct mbox_chan *channel;
|
||||
+
|
||||
+ client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
|
||||
+ if (!client)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ client->dev = &pdev->dev;
|
||||
+ client->rx_callback = mbox_test_receive_message;
|
||||
+ client->tx_prepare = mbox_test_prepare_message;
|
||||
+ client->tx_block = false;
|
||||
+ client->knows_txdone = false;
|
||||
+ client->tx_tout = 500;
|
||||
+
|
||||
+ channel = mbox_request_channel_byname(client, name);
|
||||
+ if (IS_ERR(channel)) {
|
||||
+ dev_warn(&pdev->dev, "Failed to request %s channel\n", name);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return channel;
|
||||
+}
|
||||
+
|
||||
+static int mbox_test_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mbox_test_device *tdev;
|
||||
+ struct resource *res;
|
||||
+ resource_size_t size;
|
||||
+ int ret;
|
||||
+
|
||||
+ tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
|
||||
+ if (!tdev)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* It's okay for MMIO to be NULL */
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (PTR_ERR(tdev->tx_mmio) == -EBUSY) {
|
||||
+ /* if reserved area in SRAM, try just ioremap */
|
||||
+ size = resource_size(res);
|
||||
+ tdev->tx_mmio = devm_ioremap(&pdev->dev, res->start, size);
|
||||
+ } else if (IS_ERR(tdev->tx_mmio)) {
|
||||
+ tdev->tx_mmio = NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* If specified, second reg entry is Rx MMIO */
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
+ tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (PTR_ERR(tdev->rx_mmio) == -EBUSY) {
|
||||
+ size = resource_size(res);
|
||||
+ tdev->rx_mmio = devm_ioremap(&pdev->dev, res->start, size);
|
||||
+ } else if (IS_ERR(tdev->rx_mmio)) {
|
||||
+ tdev->rx_mmio = tdev->tx_mmio;
|
||||
+ }
|
||||
+
|
||||
+ tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
|
||||
+ tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
|
||||
+
|
||||
+ if (!tdev->tx_channel && !tdev->rx_channel)
|
||||
+ return -EPROBE_DEFER;
|
||||
+
|
||||
+ /* If Rx is not specified but has Rx MMIO, then Rx = Tx */
|
||||
+ if (!tdev->rx_channel && (tdev->rx_mmio != tdev->tx_mmio))
|
||||
+ tdev->rx_channel = tdev->tx_channel;
|
||||
+
|
||||
+ tdev->dev = &pdev->dev;
|
||||
+ platform_set_drvdata(pdev, tdev);
|
||||
+
|
||||
+ spin_lock_init(&tdev->lock);
|
||||
+
|
||||
+ if (tdev->rx_channel) {
|
||||
+ tdev->rx_buffer = devm_kzalloc(&pdev->dev,
|
||||
+ MBOX_MAX_MSG_LEN, GFP_KERNEL);
|
||||
+ if (!tdev->rx_buffer)
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = mbox_test_add_debugfs(pdev, tdev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ dev_info(&pdev->dev, "Successfully registered\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mbox_test_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mbox_test_device *tdev = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ debugfs_remove_recursive(tdev->root_debugfs_dir);
|
||||
+
|
||||
+ if (tdev->tx_channel)
|
||||
+ mbox_free_channel(tdev->tx_channel);
|
||||
+ if (tdev->rx_channel)
|
||||
+ mbox_free_channel(tdev->rx_channel);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mbox_test_match[] = {
|
||||
+ { .compatible = "starfive,mailbox-test" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mbox_test_match);
|
||||
+
|
||||
+static struct platform_driver mbox_test_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "mailbox_test",
|
||||
+ .of_match_table = mbox_test_match,
|
||||
+ },
|
||||
+ .probe = mbox_test_probe,
|
||||
+ .remove = mbox_test_remove,
|
||||
+};
|
||||
+module_platform_driver(mbox_test_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Generic Mailbox Testing Facility");
|
||||
+MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--- /dev/null
|
||||
+++ b/drivers/mailbox/starfive_mailbox.c
|
||||
@@ -0,0 +1,347 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * mailbox driver for StarFive JH7110 SoC
|
||||
+ *
|
||||
+ * Copyright (c) 2021 StarFive Technology Co., Ltd.
|
||||
+ * Author: Shanlong Li <shanlong.li@starfivetech.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/mailbox_controller.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+
|
||||
+#include "mailbox.h"
|
||||
+
|
||||
+#define MBOX_CHAN_MAX 4
|
||||
+
|
||||
+#define MBOX_BASE(mbox, ch) ((mbox)->base + ((ch) * 0x10))
|
||||
+#define MBOX_IRQ_REG 0x00
|
||||
+#define MBOX_SET_REG 0x04
|
||||
+#define MBOX_CLR_REG 0x08
|
||||
+#define MBOX_CMD_REG 0x0c
|
||||
+#define MBC_PEND_SMRY 0x100
|
||||
+
|
||||
+typedef enum {
|
||||
+ MAILBOX_CORE_U7 = 0,
|
||||
+ MAILBOX_CORE_HIFI4,
|
||||
+ MAILBOX_CORE_E2,
|
||||
+ MAILBOX_CORE_RSVD0,
|
||||
+ MAILBOX_CORE_NUM,
|
||||
+} mailbox_core_t;
|
||||
+
|
||||
+struct mailbox_irq_name_c{
|
||||
+ int id;
|
||||
+ char name[16];
|
||||
+};
|
||||
+
|
||||
+static const struct mailbox_irq_name_c irq_peer_name[MBOX_CHAN_MAX] = {
|
||||
+ {MAILBOX_CORE_U7, "u74_core"},
|
||||
+ {MAILBOX_CORE_HIFI4, "hifi4_core"},
|
||||
+ {MAILBOX_CORE_E2, "e24_core"},
|
||||
+ {MAILBOX_CORE_RSVD0, "" },
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * starfive mailbox channel information
|
||||
+ *
|
||||
+ * A channel can be used for TX or RX, it can trigger remote
|
||||
+ * processor interrupt to notify remote processor and can receive
|
||||
+ * interrupt if has incoming message.
|
||||
+ *
|
||||
+ * @dst_irq: Interrupt vector for remote processor
|
||||
+ * @core_id: id for remote processor
|
||||
+ */
|
||||
+struct starfive_chan_info {
|
||||
+ unsigned int dst_irq;
|
||||
+ mailbox_core_t core_id;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * starfive mailbox controller data
|
||||
+ *
|
||||
+ * Mailbox controller includes 4 channels and can allocate
|
||||
+ * channel for message transferring.
|
||||
+ *
|
||||
+ * @dev: Device to which it is attached
|
||||
+ * @base: Base address of the register mapping region
|
||||
+ * @chan: Representation of channels in mailbox controller
|
||||
+ * @mchan: Representation of channel info
|
||||
+ * @controller: Representation of a communication channel controller
|
||||
+ */
|
||||
+struct starfive_mbox {
|
||||
+ struct device *dev;
|
||||
+ void __iomem *base;
|
||||
+ struct mbox_chan chan[MBOX_CHAN_MAX];
|
||||
+ struct starfive_chan_info mchan[MBOX_CHAN_MAX];
|
||||
+ struct mbox_controller controller;
|
||||
+ struct clk *clk;
|
||||
+ struct reset_control *rst_rresetn;
|
||||
+};
|
||||
+
|
||||
+static struct starfive_mbox *to_starfive_mbox(struct mbox_controller *mbox)
|
||||
+{
|
||||
+ return container_of(mbox, struct starfive_mbox, controller);
|
||||
+}
|
||||
+
|
||||
+static struct mbox_chan *
|
||||
+starfive_of_mbox_index_xlate(struct mbox_controller *mbox,
|
||||
+ const struct of_phandle_args *sp)
|
||||
+{
|
||||
+ struct starfive_mbox *sbox;
|
||||
+
|
||||
+ int ind = sp->args[0];
|
||||
+ int core_id = sp->args[1];
|
||||
+
|
||||
+ if (ind >= mbox->num_chans || core_id >= MAILBOX_CORE_NUM)
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+
|
||||
+ sbox = to_starfive_mbox(mbox);
|
||||
+
|
||||
+ sbox->mchan[ind].core_id = core_id;
|
||||
+
|
||||
+ return &mbox->chans[ind];
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t starfive_rx_irq_handler(int irq, void *p)
|
||||
+{
|
||||
+ struct mbox_chan *chan = p;
|
||||
+ unsigned long ch = (unsigned long)chan->con_priv;
|
||||
+ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
|
||||
+ void __iomem *base = MBOX_BASE(mbox, ch);
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(base + MBOX_CMD_REG);
|
||||
+ if (!val)
|
||||
+ return IRQ_NONE;
|
||||
+
|
||||
+ mbox_chan_received_data(chan, (void *)&val);
|
||||
+ writel(val, base + MBOX_CLR_REG);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int starfive_mbox_check_state(struct mbox_chan *chan)
|
||||
+{
|
||||
+ unsigned long ch = (unsigned long)chan->con_priv;
|
||||
+ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
|
||||
+ unsigned long irq_flag = IRQF_SHARED;
|
||||
+ long ret = 0;
|
||||
+
|
||||
+ pm_runtime_get_sync(mbox->dev);
|
||||
+ /* MAILBOX should be with IRQF_NO_SUSPEND set */
|
||||
+ if (!mbox->dev->pm_domain)
|
||||
+ irq_flag |= IRQF_NO_SUSPEND;
|
||||
+
|
||||
+ /* Mailbox is idle so directly bail out */
|
||||
+ if (readl(mbox->base + MBC_PEND_SMRY) & BIT(ch))
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ if (mbox->mchan[ch].dst_irq > 0) {
|
||||
+ dev_dbg(mbox->dev, "%s: host IRQ = %d, ch:%ld", __func__, mbox->mchan[ch].dst_irq, ch);
|
||||
+ ret = devm_request_irq(mbox->dev, mbox->mchan[ch].dst_irq, starfive_rx_irq_handler,
|
||||
+ irq_flag, irq_peer_name[ch].name, chan);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(mbox->dev, "request_irq %d failed\n", mbox->mchan[ch].dst_irq);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int starfive_mbox_startup(struct mbox_chan *chan)
|
||||
+{
|
||||
+ return starfive_mbox_check_state(chan);
|
||||
+}
|
||||
+
|
||||
+static void starfive_mbox_shutdown(struct mbox_chan *chan)
|
||||
+{
|
||||
+ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
|
||||
+ unsigned long ch = (unsigned long)chan->con_priv;
|
||||
+ void __iomem *base = MBOX_BASE(mbox, ch);
|
||||
+
|
||||
+ writel(0x0, base + MBOX_IRQ_REG);
|
||||
+ writel(0x0, base + MBOX_CLR_REG);
|
||||
+
|
||||
+ if (mbox->mchan[ch].dst_irq > 0)
|
||||
+ devm_free_irq(mbox->dev, mbox->mchan[ch].dst_irq, chan);
|
||||
+ pm_runtime_put_sync(mbox->dev);
|
||||
+}
|
||||
+
|
||||
+static int starfive_mbox_send_data(struct mbox_chan *chan, void *msg)
|
||||
+{
|
||||
+ unsigned long ch = (unsigned long)chan->con_priv;
|
||||
+ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
|
||||
+ struct starfive_chan_info *mchan = &mbox->mchan[ch];
|
||||
+ void __iomem *base = MBOX_BASE(mbox, ch);
|
||||
+ u32 *buf = msg;
|
||||
+
|
||||
+ /* Ensure channel is released */
|
||||
+ if (readl(mbox->base + MBC_PEND_SMRY) & BIT(ch)) {
|
||||
+ pr_debug("%s:%d. busy\n", __func__, __LINE__);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ /* Clear mask for destination interrupt */
|
||||
+ writel(BIT(mchan->core_id), base + MBOX_IRQ_REG);
|
||||
+
|
||||
+ /* Fill message data */
|
||||
+ writel(*buf, base + MBOX_SET_REG);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct mbox_chan_ops starfive_mbox_ops = {
|
||||
+ .startup = starfive_mbox_startup,
|
||||
+ .send_data = starfive_mbox_send_data,
|
||||
+ .shutdown = starfive_mbox_shutdown,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id starfive_mbox_of_match[] = {
|
||||
+ { .compatible = "starfive,mail_box",},
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, starfive_mbox_of_match);
|
||||
+
|
||||
+void starfive_mailbox_init(struct starfive_mbox *mbox)
|
||||
+{
|
||||
+ mbox->clk = devm_clk_get_optional(mbox->dev, "clk_apb");
|
||||
+ if (IS_ERR(mbox->clk)) {
|
||||
+ dev_err(mbox->dev, "failed to get mailbox\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ mbox->rst_rresetn = devm_reset_control_get_exclusive(mbox->dev, "mbx_rre");
|
||||
+ if (IS_ERR(mbox->rst_rresetn)) {
|
||||
+ dev_err(mbox->dev, "failed to get mailbox reset\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ clk_prepare_enable(mbox->clk);
|
||||
+ reset_control_deassert(mbox->rst_rresetn);
|
||||
+}
|
||||
+
|
||||
+static int starfive_mbox_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct starfive_mbox *mbox;
|
||||
+ struct mbox_chan *chan;
|
||||
+ struct resource *res;
|
||||
+ unsigned long ch;
|
||||
+ int err;
|
||||
+
|
||||
+ mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
|
||||
+ if (!mbox)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ mbox->base = devm_ioremap_resource(dev, res);
|
||||
+ mbox->dev = dev;
|
||||
+
|
||||
+ if (IS_ERR(mbox->base))
|
||||
+ return PTR_ERR(mbox->base);
|
||||
+
|
||||
+ starfive_mailbox_init(mbox);
|
||||
+
|
||||
+ mbox->controller.dev = dev;
|
||||
+ mbox->controller.chans = mbox->chan;
|
||||
+ mbox->controller.num_chans = MBOX_CHAN_MAX;
|
||||
+ mbox->controller.ops = &starfive_mbox_ops;
|
||||
+ mbox->controller.of_xlate = starfive_of_mbox_index_xlate;
|
||||
+ mbox->controller.txdone_irq = true;
|
||||
+ mbox->controller.txdone_poll = false;
|
||||
+
|
||||
+ /* Initialize mailbox channel data */
|
||||
+ chan = mbox->chan;
|
||||
+ for (ch = 0; ch < MBOX_CHAN_MAX; ch++) {
|
||||
+ mbox->mchan[ch].dst_irq = 0;
|
||||
+ mbox->mchan[ch].core_id = (mailbox_core_t)ch;
|
||||
+ chan[ch].con_priv = (void *)ch;
|
||||
+ }
|
||||
+ mbox->mchan[MAILBOX_CORE_HIFI4].dst_irq = platform_get_irq(pdev, 0);
|
||||
+ mbox->mchan[MAILBOX_CORE_E2].dst_irq = platform_get_irq(pdev, 1);
|
||||
+
|
||||
+ err = mbox_controller_register(&mbox->controller);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "Failed to register mailbox %d\n", err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, mbox);
|
||||
+ dev_info(dev, "Mailbox enabled\n");
|
||||
+ pm_runtime_set_active(dev);
|
||||
+ pm_runtime_enable(dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int starfive_mbox_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct starfive_mbox *mbox = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ mbox_controller_unregister(&mbox->controller);
|
||||
+ devm_clk_put(mbox->dev, mbox->clk);
|
||||
+ pm_runtime_disable(mbox->dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused starfive_mbox_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct starfive_mbox *mbox = dev_get_drvdata(dev);
|
||||
+
|
||||
+ clk_disable_unprepare(mbox->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __maybe_unused starfive_mbox_resume(struct device *dev)
|
||||
+{
|
||||
+ struct starfive_mbox *mbox = dev_get_drvdata(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(mbox->clk);
|
||||
+ if (ret)
|
||||
+ dev_err(dev, "failed to enable clock\n");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct dev_pm_ops starfive_mbox_pm_ops = {
|
||||
+ .suspend = starfive_mbox_suspend,
|
||||
+ .resume = starfive_mbox_resume,
|
||||
+ SET_RUNTIME_PM_OPS(starfive_mbox_suspend, starfive_mbox_resume, NULL)
|
||||
+};
|
||||
+static struct platform_driver starfive_mbox_driver = {
|
||||
+ .probe = starfive_mbox_probe,
|
||||
+ .remove = starfive_mbox_remove,
|
||||
+ .driver = {
|
||||
+ .name = "mailbox",
|
||||
+ .of_match_table = starfive_mbox_of_match,
|
||||
+ .pm = &starfive_mbox_pm_ops,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init starfive_mbox_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&starfive_mbox_driver);
|
||||
+}
|
||||
+core_initcall(starfive_mbox_init);
|
||||
+
|
||||
+static void __exit starfive_mbox_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&starfive_mbox_driver);
|
||||
+}
|
||||
+module_exit(starfive_mbox_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("StarFive Mailbox Controller driver");
|
||||
+MODULE_AUTHOR("Shanlong Li <shanlong.li@starfivetech.com>");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,789 @@
|
||||
From 0f44bd6bec708782f38bba4d03deecf927d1c83d Mon Sep 17 00:00:00 2001
|
||||
From: "ziv.xu" <ziv.xu@starfivetech.com>
|
||||
Date: Fri, 9 Jun 2023 15:31:53 +0800
|
||||
Subject: [PATCH 065/116] driver: rtc: Add StarFive JH7110 rtc driver
|
||||
|
||||
Add RTC driver and support for StarFive JH7110 SoC.
|
||||
|
||||
Signed-off-by: ziv.xu <ziv.xu@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
drivers/rtc/Kconfig | 8 +
|
||||
drivers/rtc/Makefile | 1 +
|
||||
drivers/rtc/rtc-starfive.c | 743 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 752 insertions(+)
|
||||
create mode 100644 drivers/rtc/rtc-starfive.c
|
||||
|
||||
--- a/drivers/rtc/Kconfig
|
||||
+++ b/drivers/rtc/Kconfig
|
||||
@@ -1327,6 +1327,14 @@ config RTC_DRV_NTXEC
|
||||
embedded controller found in certain e-book readers designed by the
|
||||
original design manufacturer Netronix.
|
||||
|
||||
+config RTC_DRV_STARFIVE
|
||||
+ tristate "StarFive 32.768k-RTC"
|
||||
+ depends on ARCH_STARFIVE
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ If you say Y here you will get support for the RTC found on
|
||||
+ StarFive SOCS.
|
||||
+
|
||||
comment "on-CPU RTC drivers"
|
||||
|
||||
config RTC_DRV_ASM9260
|
||||
--- a/drivers/rtc/Makefile
|
||||
+++ b/drivers/rtc/Makefile
|
||||
@@ -163,6 +163,7 @@ obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
|
||||
obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
|
||||
obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
|
||||
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
|
||||
+obj-$(CONFIG_RTC_DRV_STARFIVE) += rtc-starfive.o
|
||||
obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
|
||||
obj-$(CONFIG_RTC_DRV_ST_LPC) += rtc-st-lpc.o
|
||||
obj-$(CONFIG_RTC_DRV_STM32) += rtc-stm32.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/rtc/rtc-starfive.c
|
||||
@@ -0,0 +1,743 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * RTC driver for the StarFive JH7110 SoC
|
||||
+ *
|
||||
+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+
|
||||
+#include <asm/delay.h>
|
||||
+#include <linux/bcd.h>
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/completion.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/rtc.h>
|
||||
+
|
||||
+/* Registers */
|
||||
+#define SFT_RTC_CFG 0x00
|
||||
+#define SFT_RTC_SW_CAL_VALUE 0x04
|
||||
+#define SFT_RTC_HW_CAL_CFG 0x08
|
||||
+#define SFT_RTC_CMP_CFG 0x0C
|
||||
+#define SFT_RTC_IRQ_EN 0x10
|
||||
+#define SFT_RTC_IRQ_EVEVT 0x14
|
||||
+#define SFT_RTC_IRQ_STATUS 0x18
|
||||
+#define SFT_RTC_CAL_VALUE 0x24
|
||||
+#define SFT_RTC_CFG_TIME 0x28
|
||||
+#define SFT_RTC_CFG_DATE 0x2C
|
||||
+#define SFT_RTC_ACT_TIME 0x34
|
||||
+#define SFT_RTC_ACT_DATE 0x38
|
||||
+#define SFT_RTC_TIME 0x3C
|
||||
+#define SFT_RTC_DATE 0x40
|
||||
+#define SFT_RTC_TIME_LATCH 0x44
|
||||
+#define SFT_RTC_DATE_LATCH 0x48
|
||||
+
|
||||
+/* RTC_CFG */
|
||||
+#define RTC_CFG_ENABLE_SHIFT 0 /* RW: RTC Enable. */
|
||||
+#define RTC_CFG_CAL_EN_HW_SHIFT 1 /* RW: Enable of hardware calibretion. */
|
||||
+#define RTC_CFG_CAL_SEL_SHIFT 2 /* RW: select the hw/sw calibretion mode.*/
|
||||
+#define RTC_CFG_HOUR_MODE_SHIFT 3 /* RW: time hour mode. 24h|12h */
|
||||
+
|
||||
+/* RTC_SW_CAL_VALUE */
|
||||
+#define RTC_SW_CAL_VALUE_MASK GENMASK(15, 0)
|
||||
+#define RTC_SW_CAL_MAX RTC_SW_CAL_VALUE_MASK
|
||||
+#define RTC_SW_CAL_MIN 0
|
||||
+#define RTC_TICKS_PER_SEC 32768 /* Number of ticks per second */
|
||||
+#define RTC_PPB_MULT 1000000000LL /* Multiplier for ppb conversions */
|
||||
+
|
||||
+/* RTC_HW_CAL_CFG */
|
||||
+#define RTC_HW_CAL_REF_SEL_SHIFT 0
|
||||
+#define RTC_HW_CAL_FRQ_SEL_SHIFT 1
|
||||
+
|
||||
+/* IRQ_EN/IRQ_EVEVT/IRQ_STATUS */
|
||||
+#define RTC_IRQ_CAL_START BIT(0)
|
||||
+#define RTC_IRQ_CAL_FINISH BIT(1)
|
||||
+#define RTC_IRQ_CMP BIT(2)
|
||||
+#define RTC_IRQ_1SEC BIT(3)
|
||||
+#define RTC_IRQ_ALAEM BIT(4)
|
||||
+#define RTC_IRQ_EVT_UPDATE_PSE BIT(31) /* WO: Enable of update time&&date, IRQ_EVEVT only */
|
||||
+#define RTC_IRQ_ALL (RTC_IRQ_CAL_START \
|
||||
+ | RTC_IRQ_CAL_FINISH \
|
||||
+ | RTC_IRQ_CMP \
|
||||
+ | RTC_IRQ_1SEC \
|
||||
+ | RTC_IRQ_ALAEM)
|
||||
+
|
||||
+/* CAL_VALUE */
|
||||
+#define RTC_CAL_VALUE_MASK GENMASK(15, 0)
|
||||
+
|
||||
+/* CFG_TIME/ACT_TIME/RTC_TIME */
|
||||
+#define TIME_SEC_MASK GENMASK(6, 0)
|
||||
+#define TIME_MIN_MASK GENMASK(13, 7)
|
||||
+#define TIME_HOUR_MASK GENMASK(20, 14)
|
||||
+
|
||||
+/* CFG_DATE/ACT_DATE/RTC_DATE */
|
||||
+#define DATE_DAY_MASK GENMASK(5, 0)
|
||||
+#define DATE_MON_MASK GENMASK(10, 6)
|
||||
+#define DATE_YEAR_MASK GENMASK(18, 11)
|
||||
+
|
||||
+#define INT_TIMEOUT_US 180
|
||||
+
|
||||
+enum RTC_HOUR_MODE {
|
||||
+ RTC_HOUR_MODE_12H = 0,
|
||||
+ RTC_HOUR_MODE_24H = 1
|
||||
+};
|
||||
+
|
||||
+enum RTC_CAL_MODE {
|
||||
+ RTC_CAL_MODE_SW = 0,
|
||||
+ RTC_CAL_MODE_HW = 1
|
||||
+};
|
||||
+
|
||||
+enum RTC_HW_CAL_REF_MODE {
|
||||
+ RTC_CAL_CLK_REF = 0,
|
||||
+ RTC_CAL_CLK_MARK = 1
|
||||
+};
|
||||
+
|
||||
+static const unsigned long refclk_list[] = {
|
||||
+ 1000000,
|
||||
+ 2000000,
|
||||
+ 4000000,
|
||||
+ 5927000,
|
||||
+ 6000000,
|
||||
+ 7200000,
|
||||
+ 8000000,
|
||||
+ 10250000,
|
||||
+ 11059200,
|
||||
+ 12000000,
|
||||
+ 12288000,
|
||||
+ 13560000,
|
||||
+ 16000000,
|
||||
+ 19200000,
|
||||
+ 20000000,
|
||||
+ 22118000,
|
||||
+ 24000000,
|
||||
+ 24567000,
|
||||
+ 25000000,
|
||||
+ 26000000,
|
||||
+ 27000000,
|
||||
+ 30000000,
|
||||
+ 32000000,
|
||||
+ 33868800,
|
||||
+ 36000000,
|
||||
+ 36860000,
|
||||
+ 40000000,
|
||||
+ 44000000,
|
||||
+ 50000000,
|
||||
+ 54000000,
|
||||
+ 28224000,
|
||||
+ 28000000,
|
||||
+};
|
||||
+
|
||||
+struct sft_rtc {
|
||||
+ struct rtc_device *rtc_dev;
|
||||
+ struct completion cal_done;
|
||||
+ struct completion onesec_done;
|
||||
+ struct clk *pclk;
|
||||
+ struct clk *cal_clk;
|
||||
+ struct reset_control *rst_array;
|
||||
+ int hw_cal_map;
|
||||
+ void __iomem *regs;
|
||||
+ int rtc_irq;
|
||||
+ int ms_pulse_irq;
|
||||
+ int one_sec_pulse_irq;
|
||||
+};
|
||||
+
|
||||
+static inline void sft_rtc_set_enabled(struct sft_rtc *srtc, bool enabled)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (enabled) {
|
||||
+ val = readl(srtc->regs + SFT_RTC_CFG);
|
||||
+ val |= BIT(RTC_CFG_ENABLE_SHIFT);
|
||||
+ writel(val, srtc->regs + SFT_RTC_CFG);
|
||||
+ } else {
|
||||
+ val = readl(srtc->regs + SFT_RTC_CFG);
|
||||
+ val &= ~BIT(RTC_CFG_ENABLE_SHIFT);
|
||||
+ writel(val, srtc->regs + SFT_RTC_CFG);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline bool sft_rtc_get_enabled(struct sft_rtc *srtc)
|
||||
+{
|
||||
+ return !!(readl(srtc->regs + SFT_RTC_CFG) & BIT(RTC_CFG_ENABLE_SHIFT));
|
||||
+}
|
||||
+
|
||||
+static inline void sft_rtc_set_mode(struct sft_rtc *srtc, enum RTC_HOUR_MODE mode)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(srtc->regs + SFT_RTC_CFG);
|
||||
+ val |= mode << RTC_CFG_HOUR_MODE_SHIFT;
|
||||
+ writel(val, srtc->regs + SFT_RTC_CFG);
|
||||
+}
|
||||
+
|
||||
+static inline int sft_rtc_irq_enable(struct sft_rtc *srtc, u32 irq, bool enable)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (!(irq & RTC_IRQ_ALL))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (enable) {
|
||||
+ val = readl(srtc->regs + SFT_RTC_IRQ_EN);
|
||||
+ val |= irq;
|
||||
+ writel(val, srtc->regs + SFT_RTC_IRQ_EN);
|
||||
+ } else {
|
||||
+ val = readl(srtc->regs + SFT_RTC_IRQ_EN);
|
||||
+ val &= ~irq;
|
||||
+ writel(val, srtc->regs + SFT_RTC_IRQ_EN);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+sft_rtc_set_cal_hw_enable(struct sft_rtc *srtc, bool enable)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (enable) {
|
||||
+ val = readl(srtc->regs + SFT_RTC_CFG);
|
||||
+ val |= BIT(RTC_CFG_CAL_EN_HW_SHIFT);
|
||||
+ writel(val, srtc->regs + SFT_RTC_CFG);
|
||||
+ } else {
|
||||
+ val = readl(srtc->regs + SFT_RTC_CFG);
|
||||
+ val &= ~BIT(RTC_CFG_CAL_EN_HW_SHIFT);
|
||||
+ writel(val, srtc->regs + SFT_RTC_CFG);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+sft_rtc_set_cal_mode(struct sft_rtc *srtc, enum RTC_CAL_MODE mode)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(srtc->regs + SFT_RTC_CFG);
|
||||
+ val |= mode << RTC_CFG_CAL_SEL_SHIFT;
|
||||
+ writel(val, srtc->regs + SFT_RTC_CFG);
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_get_hw_calclk(struct device *dev, unsigned long freq)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(refclk_list); i++)
|
||||
+ if (refclk_list[i] == freq)
|
||||
+ return i;
|
||||
+
|
||||
+ dev_err(dev, "refclk: %ldHz do not support.\n", freq);
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static inline void sft_rtc_reg2time(struct rtc_time *tm, u32 reg)
|
||||
+{
|
||||
+ tm->tm_hour = bcd2bin(FIELD_GET(TIME_HOUR_MASK, reg));
|
||||
+ tm->tm_min = bcd2bin(FIELD_GET(TIME_MIN_MASK, reg));
|
||||
+ tm->tm_sec = bcd2bin(FIELD_GET(TIME_SEC_MASK, reg));
|
||||
+}
|
||||
+
|
||||
+static inline void sft_rtc_reg2date(struct rtc_time *tm, u32 reg)
|
||||
+{
|
||||
+ tm->tm_year = bcd2bin(FIELD_GET(DATE_YEAR_MASK, reg)) + 100;
|
||||
+ tm->tm_mon = bcd2bin(FIELD_GET(DATE_MON_MASK, reg)) - 1;
|
||||
+ tm->tm_mday = bcd2bin(FIELD_GET(DATE_DAY_MASK, reg));
|
||||
+}
|
||||
+
|
||||
+static inline u32 sft_rtc_time2reg(struct rtc_time *tm)
|
||||
+{
|
||||
+ return FIELD_PREP(TIME_HOUR_MASK, bin2bcd(tm->tm_hour)) |
|
||||
+ FIELD_PREP(TIME_MIN_MASK, bin2bcd(tm->tm_min)) |
|
||||
+ FIELD_PREP(TIME_SEC_MASK, bin2bcd(tm->tm_sec));
|
||||
+}
|
||||
+
|
||||
+static inline u32 sft_rtc_date2reg(struct rtc_time *tm)
|
||||
+{
|
||||
+ return FIELD_PREP(DATE_YEAR_MASK, bin2bcd(tm->tm_year - 100)) |
|
||||
+ FIELD_PREP(DATE_MON_MASK, bin2bcd(tm->tm_mon + 1)) |
|
||||
+ FIELD_PREP(DATE_DAY_MASK, bin2bcd(tm->tm_mday));
|
||||
+}
|
||||
+
|
||||
+static inline void sft_rtc_update_pulse(struct sft_rtc *srtc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(srtc->regs + SFT_RTC_IRQ_EVEVT);
|
||||
+ val |= RTC_IRQ_EVT_UPDATE_PSE;
|
||||
+ writel(val, srtc->regs + SFT_RTC_IRQ_EVEVT);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t sft_rtc_irq_handler(int irq, void *data)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = data;
|
||||
+ struct timerqueue_node *next;
|
||||
+ u32 irq_flags = 0;
|
||||
+ u32 irq_mask = 0;
|
||||
+ u32 val;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ val = readl(srtc->regs + SFT_RTC_IRQ_EVEVT);
|
||||
+ if (val & RTC_IRQ_CAL_START)
|
||||
+ irq_mask |= RTC_IRQ_CAL_START;
|
||||
+
|
||||
+ if (val & RTC_IRQ_CAL_FINISH) {
|
||||
+ irq_mask |= RTC_IRQ_CAL_FINISH;
|
||||
+ complete(&srtc->cal_done);
|
||||
+ }
|
||||
+
|
||||
+ if (val & RTC_IRQ_CMP)
|
||||
+ irq_mask |= RTC_IRQ_CMP;
|
||||
+
|
||||
+ if (val & RTC_IRQ_1SEC) {
|
||||
+ irq_flags |= RTC_PF;
|
||||
+ irq_mask |= RTC_IRQ_1SEC;
|
||||
+ complete(&srtc->onesec_done);
|
||||
+ }
|
||||
+
|
||||
+ if (val & RTC_IRQ_ALAEM) {
|
||||
+ irq_flags |= RTC_AF;
|
||||
+ irq_mask |= RTC_IRQ_ALAEM;
|
||||
+
|
||||
+ next = timerqueue_getnext(&srtc->rtc_dev->timerqueue);
|
||||
+ if (next == &srtc->rtc_dev->aie_timer.node)
|
||||
+ dev_info(&srtc->rtc_dev->dev, "alarm expires");
|
||||
+ }
|
||||
+
|
||||
+ writel(irq_mask, srtc->regs + SFT_RTC_IRQ_EVEVT);
|
||||
+
|
||||
+ /* Wait interrupt flag clear */
|
||||
+ ret = readl_poll_timeout_atomic(srtc->regs + SFT_RTC_IRQ_EVEVT, val,
|
||||
+ (val & irq_mask) == 0, 0, INT_TIMEOUT_US);
|
||||
+ if (ret)
|
||||
+ dev_warn(&srtc->rtc_dev->dev, "fail to clear rtc interrupt flag\n");
|
||||
+
|
||||
+ if (irq_flags)
|
||||
+ rtc_update_irq(srtc->rtc_dev, 1, irq_flags | RTC_IRQF);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+ u32 val;
|
||||
+ int irq_1sec_state_start, irq_1sec_state_end;
|
||||
+
|
||||
+ /* If the RTC is disabled, assume the values are invalid */
|
||||
+ if (!sft_rtc_get_enabled(srtc))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ irq_1sec_state_start =
|
||||
+ (readl(srtc->regs + SFT_RTC_IRQ_STATUS) & RTC_IRQ_1SEC) == 0 ? 0 : 1;
|
||||
+
|
||||
+read_again:
|
||||
+ val = readl(srtc->regs + SFT_RTC_TIME);
|
||||
+ sft_rtc_reg2time(tm, val);
|
||||
+
|
||||
+ val = readl(srtc->regs + SFT_RTC_DATE);
|
||||
+ sft_rtc_reg2date(tm, val);
|
||||
+
|
||||
+ if (irq_1sec_state_start == 0) {
|
||||
+ irq_1sec_state_end =
|
||||
+ (readl(srtc->regs + SFT_RTC_IRQ_STATUS) & RTC_IRQ_1SEC) == 0 ? 0 : 1;
|
||||
+ if (irq_1sec_state_end == 1) {
|
||||
+ irq_1sec_state_start = 1;
|
||||
+ goto read_again;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ val = sft_rtc_time2reg(tm);
|
||||
+ writel(val, srtc->regs + SFT_RTC_CFG_TIME);
|
||||
+
|
||||
+ val = sft_rtc_date2reg(tm);
|
||||
+ writel(val, srtc->regs + SFT_RTC_CFG_DATE);
|
||||
+
|
||||
+ /* Update pulse */
|
||||
+ sft_rtc_update_pulse(srtc);
|
||||
+
|
||||
+ /* Ensure that data is fully written */
|
||||
+ ret = wait_for_completion_interruptible_timeout(&srtc->onesec_done,
|
||||
+ usecs_to_jiffies(120));
|
||||
+ if (ret) {
|
||||
+ dev_warn(dev,
|
||||
+ "rtc wait for completion interruptible timeout.\n");
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+
|
||||
+ return sft_rtc_irq_enable(srtc, RTC_IRQ_ALAEM, enabled);
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(srtc->regs + SFT_RTC_ACT_TIME);
|
||||
+ sft_rtc_reg2time(&alarm->time, val);
|
||||
+
|
||||
+ val = readl(srtc->regs + SFT_RTC_ACT_DATE);
|
||||
+ sft_rtc_reg2date(&alarm->time, val);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+ u32 val;
|
||||
+
|
||||
+ sft_rtc_alarm_irq_enable(dev, 0);
|
||||
+
|
||||
+ val = sft_rtc_time2reg(&alarm->time);
|
||||
+ writel(val, srtc->regs + SFT_RTC_ACT_TIME);
|
||||
+
|
||||
+ val = sft_rtc_date2reg(&alarm->time);
|
||||
+ writel(val, srtc->regs + SFT_RTC_ACT_DATE);
|
||||
+
|
||||
+ sft_rtc_alarm_irq_enable(dev, alarm->enabled);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_get_offset(struct device *dev, long *offset)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+ s64 tmp;
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(srtc->regs + SFT_RTC_CAL_VALUE)
|
||||
+ & RTC_SW_CAL_VALUE_MASK;
|
||||
+ val += 1;
|
||||
+ /*
|
||||
+ * the adjust val range is [0x0000-0xffff],
|
||||
+ * the default val is 0x7fff (32768-1),mapping offset=0 ;
|
||||
+ */
|
||||
+ tmp = (s64)val - RTC_TICKS_PER_SEC;
|
||||
+ tmp *= RTC_PPB_MULT;
|
||||
+ tmp = div_s64(tmp, RTC_TICKS_PER_SEC);
|
||||
+
|
||||
+ /* Offset value operates in negative way, so swap sign */
|
||||
+ *offset = -tmp;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_set_offset(struct device *dev, long offset)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+ s64 tmp;
|
||||
+ u32 val;
|
||||
+
|
||||
+ tmp = offset * RTC_TICKS_PER_SEC;
|
||||
+ tmp = div_s64(tmp, RTC_PPB_MULT);
|
||||
+
|
||||
+ tmp = RTC_TICKS_PER_SEC - tmp;
|
||||
+ tmp -= 1;
|
||||
+ if (tmp > RTC_SW_CAL_MAX || tmp < RTC_SW_CAL_MIN) {
|
||||
+ dev_err(dev, "offset is out of range.\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ val = tmp & RTC_SW_CAL_VALUE_MASK;
|
||||
+ /* set software calibration value */
|
||||
+ writel(val, srtc->regs + SFT_RTC_SW_CAL_VALUE);
|
||||
+
|
||||
+ /* set CFG_RTC-cal_sel to select calibretion by software. */
|
||||
+ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_SW);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static __maybe_unused int
|
||||
+sft_rtc_hw_adjustment(struct device *dev, unsigned int enable)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (srtc->hw_cal_map <= 0) {
|
||||
+ dev_err(dev, "fail to get cal-clock-freq.\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ if (enable) {
|
||||
+ sft_rtc_irq_enable(srtc, RTC_IRQ_CAL_FINISH, true);
|
||||
+
|
||||
+ /* Set reference clock frequency value */
|
||||
+ val = readl(srtc->regs + SFT_RTC_HW_CAL_CFG);
|
||||
+ val |= (srtc->hw_cal_map << RTC_HW_CAL_FRQ_SEL_SHIFT);
|
||||
+ writel(val, srtc->regs + SFT_RTC_HW_CAL_CFG);
|
||||
+
|
||||
+ /* Set CFG_RTC-cal_sel to select calibretion by hardware. */
|
||||
+ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_HW);
|
||||
+
|
||||
+ /* Set CFG_RTC-cal_en_hw to launch hardware calibretion.*/
|
||||
+ sft_rtc_set_cal_hw_enable(srtc, true);
|
||||
+
|
||||
+ wait_for_completion_interruptible_timeout(&srtc->cal_done,
|
||||
+ usecs_to_jiffies(100));
|
||||
+
|
||||
+ sft_rtc_irq_enable(srtc, RTC_IRQ_CAL_FINISH, false);
|
||||
+ } else {
|
||||
+ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_SW);
|
||||
+ sft_rtc_set_cal_hw_enable(srtc, false);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_get_cal_clk(struct device *dev, struct sft_rtc *srtc)
|
||||
+{
|
||||
+ struct device_node *np = dev->of_node;
|
||||
+ unsigned long cal_clk_freq;
|
||||
+ u32 freq;
|
||||
+ int ret;
|
||||
+
|
||||
+ srtc->cal_clk = devm_clk_get(dev, "cal_clk");
|
||||
+ if (IS_ERR(srtc->cal_clk))
|
||||
+ return PTR_ERR(srtc->cal_clk);
|
||||
+
|
||||
+ clk_prepare_enable(srtc->cal_clk);
|
||||
+
|
||||
+ cal_clk_freq = clk_get_rate(srtc->cal_clk);
|
||||
+ if (!cal_clk_freq) {
|
||||
+ dev_warn(dev,
|
||||
+ "get rate failed, next try to get from dts.\n");
|
||||
+ ret = of_property_read_u32(np, "rtc,cal-clock-freq", &freq);
|
||||
+ if (!ret) {
|
||||
+ cal_clk_freq = (u64)freq;
|
||||
+ } else {
|
||||
+ dev_err(dev,
|
||||
+ "Need rtc,cal-clock-freq define in dts.\n");
|
||||
+ goto err_disable_cal_clk;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ srtc->hw_cal_map = sft_rtc_get_hw_calclk(dev, cal_clk_freq);
|
||||
+ if (srtc->hw_cal_map < 0) {
|
||||
+ ret = srtc->hw_cal_map;
|
||||
+ goto err_disable_cal_clk;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_disable_cal_clk:
|
||||
+ clk_disable_unprepare(srtc->cal_clk);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_get_irq(struct platform_device *pdev, struct sft_rtc *srtc)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ srtc->rtc_irq = platform_get_irq_byname(pdev, "rtc");
|
||||
+ if (srtc->rtc_irq < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = devm_request_irq(&pdev->dev, srtc->rtc_irq,
|
||||
+ sft_rtc_irq_handler, 0,
|
||||
+ KBUILD_MODNAME, srtc);
|
||||
+ if (ret)
|
||||
+ dev_err(&pdev->dev, "Failed to request interrupt, %d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct rtc_class_ops starfive_rtc_ops = {
|
||||
+ .read_time = sft_rtc_read_time,
|
||||
+ .set_time = sft_rtc_set_time,
|
||||
+ .read_alarm = sft_rtc_read_alarm,
|
||||
+ .set_alarm = sft_rtc_set_alarm,
|
||||
+ .alarm_irq_enable = sft_rtc_alarm_irq_enable,
|
||||
+ .set_offset = sft_rtc_set_offset,
|
||||
+ .read_offset = sft_rtc_get_offset,
|
||||
+};
|
||||
+
|
||||
+static int sft_rtc_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct sft_rtc *srtc;
|
||||
+ struct rtc_time tm;
|
||||
+ struct irq_desc *desc;
|
||||
+ int ret;
|
||||
+
|
||||
+ srtc = devm_kzalloc(dev, sizeof(*srtc), GFP_KERNEL);
|
||||
+ if (!srtc)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ srtc->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(srtc->regs))
|
||||
+ return PTR_ERR(srtc->regs);
|
||||
+
|
||||
+ srtc->pclk = devm_clk_get(dev, "pclk");
|
||||
+ if (IS_ERR(srtc->pclk)) {
|
||||
+ ret = PTR_ERR(srtc->pclk);
|
||||
+ dev_err(dev,
|
||||
+ "Failed to retrieve the peripheral clock, %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ srtc->rst_array = devm_reset_control_array_get_exclusive(dev);
|
||||
+ if (IS_ERR(srtc->rst_array)) {
|
||||
+ ret = PTR_ERR(srtc->rst_array);
|
||||
+ dev_err(dev,
|
||||
+ "Failed to retrieve the rtc reset, %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ init_completion(&srtc->cal_done);
|
||||
+ init_completion(&srtc->onesec_done);
|
||||
+
|
||||
+ ret = clk_prepare_enable(srtc->pclk);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev,
|
||||
+ "Failed to enable the peripheral clock, %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = sft_rtc_get_cal_clk(dev, srtc);
|
||||
+ if (ret)
|
||||
+ goto err_disable_pclk;
|
||||
+
|
||||
+ ret = reset_control_deassert(srtc->rst_array);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev,
|
||||
+ "Failed to deassert rtc resets, %d\n", ret);
|
||||
+ goto err_disable_cal_clk;
|
||||
+ }
|
||||
+
|
||||
+ ret = sft_rtc_get_irq(pdev, srtc);
|
||||
+ if (ret)
|
||||
+ goto err_disable_cal_clk;
|
||||
+
|
||||
+ srtc->rtc_dev = devm_rtc_allocate_device(dev);
|
||||
+ if (IS_ERR(srtc->rtc_dev))
|
||||
+ return PTR_ERR(srtc->rtc_dev);
|
||||
+
|
||||
+ platform_set_drvdata(pdev, srtc);
|
||||
+
|
||||
+ /* The RTC supports 01.01.2001 - 31.12.2099 */
|
||||
+ srtc->rtc_dev->range_min = mktime64(2001, 1, 1, 0, 0, 0);
|
||||
+ srtc->rtc_dev->range_max = mktime64(2099, 12, 31, 23, 59, 59);
|
||||
+
|
||||
+ srtc->rtc_dev->ops = &starfive_rtc_ops;
|
||||
+ device_init_wakeup(dev, true);
|
||||
+
|
||||
+ desc = irq_to_desc(srtc->rtc_irq);
|
||||
+ irq_desc_get_chip(desc)->flags = IRQCHIP_SKIP_SET_WAKE;
|
||||
+
|
||||
+ /* Always use 24-hour mode and keep the RTC values */
|
||||
+ sft_rtc_set_mode(srtc, RTC_HOUR_MODE_24H);
|
||||
+
|
||||
+ sft_rtc_set_enabled(srtc, true);
|
||||
+
|
||||
+ if (device_property_read_bool(dev, "rtc,hw-adjustment"))
|
||||
+ sft_rtc_hw_adjustment(dev, true);
|
||||
+
|
||||
+ /*
|
||||
+ * If rtc time is out of supported range, reset it to the minimum time.
|
||||
+ * notice that, actual year = 1900 + tm.tm_year
|
||||
+ * actual month = 1 + tm.tm_mon
|
||||
+ */
|
||||
+ sft_rtc_read_time(dev, &tm);
|
||||
+ if (tm.tm_year < 101 || tm.tm_year > 199 || tm.tm_mon < 0 || tm.tm_mon > 11 ||
|
||||
+ tm.tm_mday < 1 || tm.tm_mday > 31 || tm.tm_hour < 0 || tm.tm_hour > 23 ||
|
||||
+ tm.tm_min < 0 || tm.tm_min > 59 || tm.tm_sec < 0 || tm.tm_sec > 59) {
|
||||
+ rtc_time64_to_tm(srtc->rtc_dev->range_min, &tm);
|
||||
+ sft_rtc_set_time(dev, &tm);
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_rtc_register_device(srtc->rtc_dev);
|
||||
+ if (ret)
|
||||
+ goto err_disable_wakeup;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_disable_wakeup:
|
||||
+ device_init_wakeup(dev, false);
|
||||
+
|
||||
+err_disable_cal_clk:
|
||||
+ clk_disable_unprepare(srtc->cal_clk);
|
||||
+
|
||||
+err_disable_pclk:
|
||||
+ clk_disable_unprepare(srtc->pclk);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ sft_rtc_alarm_irq_enable(&pdev->dev, 0);
|
||||
+ device_init_wakeup(&pdev->dev, 0);
|
||||
+
|
||||
+ clk_disable_unprepare(srtc->pclk);
|
||||
+ clk_disable_unprepare(srtc->cal_clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+static int sft_rtc_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+
|
||||
+ if (device_may_wakeup(dev))
|
||||
+ enable_irq_wake(srtc->rtc_irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sft_rtc_resume(struct device *dev)
|
||||
+{
|
||||
+ struct sft_rtc *srtc = dev_get_drvdata(dev);
|
||||
+
|
||||
+ if (device_may_wakeup(dev))
|
||||
+ disable_irq_wake(srtc->rtc_irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static SIMPLE_DEV_PM_OPS(sft_rtc_pm_ops, sft_rtc_suspend, sft_rtc_resume);
|
||||
+
|
||||
+static const struct of_device_id sft_rtc_of_match[] = {
|
||||
+ { .compatible = "starfive,jh7110-rtc" },
|
||||
+ { },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sft_rtc_of_match);
|
||||
+
|
||||
+static struct platform_driver starfive_rtc_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "starfive-rtc",
|
||||
+ .of_match_table = sft_rtc_of_match,
|
||||
+ .pm = &sft_rtc_pm_ops,
|
||||
+ },
|
||||
+ .probe = sft_rtc_probe,
|
||||
+ .remove = sft_rtc_remove,
|
||||
+};
|
||||
+module_platform_driver(starfive_rtc_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
|
||||
+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("StarFive RTC driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_ALIAS("platform:starfive-rtc");
|
@ -0,0 +1,96 @@
|
||||
From 552114b8cbbd956ad8466261b5f11b059eba82ca Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Sun, 25 Jun 2023 09:40:29 +0800
|
||||
Subject: [PATCH 066/116] uart: 8250: Add dw auto flow ctrl support
|
||||
|
||||
Add designeware 8250 auto flow ctrl support. Enable
|
||||
it by add auto-flow-control in dts.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
---
|
||||
drivers/tty/serial/8250/8250_core.c | 2 ++
|
||||
drivers/tty/serial/8250/8250_dw.c | 3 +++
|
||||
drivers/tty/serial/8250/8250_port.c | 14 +++++++++++++-
|
||||
include/linux/serial_8250.h | 1 +
|
||||
include/uapi/linux/serial_core.h | 2 ++
|
||||
5 files changed, 21 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/tty/serial/8250/8250_core.c
|
||||
+++ b/drivers/tty/serial/8250/8250_core.c
|
||||
@@ -1129,6 +1129,8 @@ int serial8250_register_8250_port(const
|
||||
uart->dl_read = up->dl_read;
|
||||
if (up->dl_write)
|
||||
uart->dl_write = up->dl_write;
|
||||
+ if (up->probe)
|
||||
+ uart->probe = up->probe;
|
||||
|
||||
if (uart->port.type != PORT_8250_CIR) {
|
||||
if (serial8250_isa_config != NULL)
|
||||
--- a/drivers/tty/serial/8250/8250_dw.c
|
||||
+++ b/drivers/tty/serial/8250/8250_dw.c
|
||||
@@ -612,6 +612,9 @@ static int dw8250_probe(struct platform_
|
||||
data->msr_mask_off |= UART_MSR_TERI;
|
||||
}
|
||||
|
||||
+ if (device_property_read_bool(dev, "auto-flow-control"))
|
||||
+ up->probe |= UART_PROBE_AFE;
|
||||
+
|
||||
/* If there is separate baudclk, get the rate from it. */
|
||||
data->clk = devm_clk_get_optional(dev, "baudclk");
|
||||
if (data->clk == NULL)
|
||||
--- a/drivers/tty/serial/8250/8250_port.c
|
||||
+++ b/drivers/tty/serial/8250/8250_port.c
|
||||
@@ -330,6 +330,14 @@ static const struct serial8250_config ua
|
||||
.rxtrig_bytes = {1, 8, 16, 30},
|
||||
.flags = UART_CAP_FIFO | UART_CAP_AFE,
|
||||
},
|
||||
+ [PORT_16550A_AFE] = {
|
||||
+ .name = "16550A_AFE",
|
||||
+ .fifo_size = 16,
|
||||
+ .tx_loadsz = 16,
|
||||
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
|
||||
+ .rxtrig_bytes = {1, 4, 8, 14},
|
||||
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
|
||||
+ },
|
||||
};
|
||||
|
||||
/* Uart divisor latch read */
|
||||
@@ -1143,6 +1151,11 @@ static void autoconfig_16550a(struct uar
|
||||
up->port.type = PORT_U6_16550A;
|
||||
up->capabilities |= UART_CAP_AFE;
|
||||
}
|
||||
+
|
||||
+ if ((up->port.type == PORT_16550A) && (up->probe & UART_PROBE_AFE)) {
|
||||
+ up->port.type = PORT_16550A_AFE;
|
||||
+ up->capabilities |= UART_CAP_AFE;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2813,7 +2826,6 @@ serial8250_do_set_termios(struct uart_po
|
||||
if (termios->c_cflag & CRTSCTS)
|
||||
up->mcr |= UART_MCR_AFE;
|
||||
}
|
||||
-
|
||||
/*
|
||||
* Update the per-port timeout.
|
||||
*/
|
||||
--- a/include/linux/serial_8250.h
|
||||
+++ b/include/linux/serial_8250.h
|
||||
@@ -141,6 +141,7 @@ struct uart_8250_port {
|
||||
unsigned char probe;
|
||||
struct mctrl_gpios *gpios;
|
||||
#define UART_PROBE_RSA (1 << 0)
|
||||
+#define UART_PROBE_AFE (1 << 1)
|
||||
|
||||
/*
|
||||
* Some bits in registers are cleared on a read, so they must
|
||||
--- a/include/uapi/linux/serial_core.h
|
||||
+++ b/include/uapi/linux/serial_core.h
|
||||
@@ -245,4 +245,6 @@
|
||||
/* Sunplus UART */
|
||||
#define PORT_SUNPLUS 123
|
||||
|
||||
+#define PORT_16550A_AFE 124
|
||||
+
|
||||
#endif /* _UAPILINUX_SERIAL_CORE_H */
|
@ -0,0 +1,29 @@
|
||||
From 6edee93a89254f30c3387c88231e7ecec06ba84a Mon Sep 17 00:00:00 2001
|
||||
From: "shanlong.li" <shanlong.li@starfivetech.com>
|
||||
Date: Mon, 10 Jul 2023 03:07:57 -0700
|
||||
Subject: [PATCH 067/116] driver:uart: fix up uart communicate fail
|
||||
|
||||
fix up uart communicate fail
|
||||
|
||||
Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
|
||||
---
|
||||
drivers/tty/serial/8250/8250_dw.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/tty/serial/8250/8250_dw.c
|
||||
+++ b/drivers/tty/serial/8250/8250_dw.c
|
||||
@@ -652,10 +652,10 @@ static int dw8250_probe(struct platform_
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- data->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
|
||||
- if (IS_ERR(data->rst))
|
||||
- return PTR_ERR(data->rst);
|
||||
-
|
||||
+ data->rst = devm_reset_control_array_get_exclusive(dev);
|
||||
+ if (IS_ERR(data->rst)) {
|
||||
+ err = PTR_ERR(data->rst);
|
||||
+ }
|
||||
reset_control_deassert(data->rst);
|
||||
|
||||
err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst);
|
@ -0,0 +1,32 @@
|
||||
From 777d288f03a0b350f6c2d4367b01a80d9f25cd6e Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Wed, 20 Sep 2023 17:19:59 +0800
|
||||
Subject: [PATCH 068/116] uart: 8250: add reset operation in runtime PM
|
||||
|
||||
add reset operation in runtime PM
|
||||
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
---
|
||||
drivers/tty/serial/8250/8250_dw.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/tty/serial/8250/8250_dw.c
|
||||
+++ b/drivers/tty/serial/8250/8250_dw.c
|
||||
@@ -745,6 +745,8 @@ static int dw8250_runtime_suspend(struct
|
||||
{
|
||||
struct dw8250_data *data = dev_get_drvdata(dev);
|
||||
|
||||
+ reset_control_assert(data->rst);
|
||||
+
|
||||
clk_disable_unprepare(data->clk);
|
||||
|
||||
clk_disable_unprepare(data->pclk);
|
||||
@@ -760,6 +762,8 @@ static int dw8250_runtime_resume(struct
|
||||
|
||||
clk_prepare_enable(data->clk);
|
||||
|
||||
+ reset_control_deassert(data->rst);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,113 @@
|
||||
From 5eda2331a252436756fb40861f01a7a38b1502c7 Mon Sep 17 00:00:00 2001
|
||||
From: William Qiu <william.qiu@starfivetech.com>
|
||||
Date: Thu, 15 Jun 2023 20:14:22 +0800
|
||||
Subject: [PATCH 069/116] dt-bindings: CAN: Add StarFive CAN module
|
||||
|
||||
Add documentation to describe StarFive CAN engine.
|
||||
|
||||
Signed-off-by: William Qiu <william.qiu@starfivetech.com>
|
||||
---
|
||||
.../devicetree/bindings/net/can/ipms-can.yaml | 97 +++++++++++++++++++
|
||||
1 file changed, 97 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/net/can/ipms-can.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/net/can/ipms-can.yaml
|
||||
@@ -0,0 +1,97 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+#$id: http://devicetree.org/schemas/net/can/ipms-can.yaml#
|
||||
+#$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: IPMS CAN/CANFD controller Device Tree Bindings
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const:ipms,can
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+ items:
|
||||
+ - description:CAN controller registers
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ minItems: 1
|
||||
+ items:
|
||||
+ - description:apb_clk clock
|
||||
+ - description:core_clk clock
|
||||
+ - description:timer_clk clock
|
||||
+
|
||||
+ clock-names:
|
||||
+ minItems: 1
|
||||
+ items:
|
||||
+ - const:apb_clk
|
||||
+ - const:core_clk
|
||||
+ - const:timer_clk
|
||||
+ resets:
|
||||
+ minItems: 1
|
||||
+ items:
|
||||
+ - description:apb_clk reset
|
||||
+ - description:core_clk reset
|
||||
+ - description:timer_clk reset
|
||||
+ reset-names:
|
||||
+ minItems: 1
|
||||
+ items:
|
||||
+ - const:rst_apb
|
||||
+ - const:rst_core
|
||||
+ - const:rst_timer
|
||||
+ starfive,sys-syscon:
|
||||
+ format:
|
||||
+ starfive,sys-syscon = <&arg0 arg1 arg2 arg3>
|
||||
+ description:
|
||||
+ arg0:arg0 is sys_syscon.
|
||||
+ arg1:arg1 is syscon register offset, used to enable can2.0/canfd function, can0 is 0x10, can1 is 0x88.
|
||||
+ arg2:arg2 is used to enable the register shift of the can2.0/canfd function, can0 is 0x3, can1 is 0x12.
|
||||
+ arg3:arg3 is used to enable the register mask of the can2.0/canfd function, can0 is 0x8, can1 is 0x40000
|
||||
+
|
||||
+ syscon,can_or_canfd:
|
||||
+ description:
|
||||
+ IPMS CAN-CTRL core is a serial communications controller that performs serial communication according to the CAN protocol.
|
||||
+ This CAN bus interface uses the basic CAN principle and meets all constraints of the CAN-specification 2.0B active.
|
||||
+ Furthermore this CAN core can be configured to meet the specification of CAN with flexible data rate CAN FD.
|
||||
+ When syscon,can_or_canfd is set to 0, use CAN2.0B.
|
||||
+ when syscon,can_or_canfd is set to 1, use CAN FD.
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - interrupts
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - reset-names
|
||||
+ - starfive,sys-syscon
|
||||
+ - syscon,can_or_canfd
|
||||
+additionalProperties:false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ can0: can@130d0000{
|
||||
+ compatible = "ipms,can";
|
||||
+ reg = <0x0 0x130d0000 0x0 0x1000>;
|
||||
+ interrupts = <112>;
|
||||
+ interrupt-parent = <&plic>;
|
||||
+ clocks = <&clkgen JH7110_CAN0_CTRL_CLK_APB>,
|
||||
+ <&clkgen JH7110_CAN0_CTRL_CLK_CAN>,
|
||||
+ <&clkgen JH7110_CAN0_CTRL_CLK_TIMER>;
|
||||
+ clock-names = "apb_clk",
|
||||
+ "core_clk",
|
||||
+ "timer_clk";
|
||||
+ resets = <&rstgen RSTN_U0_CAN_CTRL_APB>,
|
||||
+ <&rstgen RSTN_U0_CAN_CTRL_CORE>,
|
||||
+ <&rstgen RSTN_U0_CAN_CTRL_TIMER>;
|
||||
+ reset-names = "rst_apb",
|
||||
+ "rst_core",
|
||||
+ "rst_timer";
|
||||
+ starfive,sys-syscon = <&sys_syscon, 0x10 0x3 0x8>;
|
||||
+ syscon,can_or_canfd = <0>;
|
||||
+ };
|
||||
+
|
||||
+...
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,204 @@
|
||||
From b12213d474966fbf47e7afa36a6655b5b241cf36 Mon Sep 17 00:00:00 2001
|
||||
From: "Kevin.xie" <kevin.xie@starfivetech.com>
|
||||
Date: Fri, 9 Jun 2023 14:57:13 +0800
|
||||
Subject: [PATCH 071/116] regulator: starfive-jh7110: Add regulator support for
|
||||
JH7110 A type EVB.
|
||||
|
||||
Add 7 regulators base on regulator framework for
|
||||
JH7110 evb HW design.
|
||||
|
||||
Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
|
||||
---
|
||||
drivers/regulator/Kconfig | 10 ++
|
||||
drivers/regulator/Makefile | 1 +
|
||||
drivers/regulator/starfive-jh7110-regulator.c | 126 ++++++++++++++++++
|
||||
include/linux/regulator/jh7110.h | 24 ++++
|
||||
4 files changed, 161 insertions(+)
|
||||
create mode 100644 drivers/regulator/starfive-jh7110-regulator.c
|
||||
create mode 100644 include/linux/regulator/jh7110.h
|
||||
|
||||
--- a/drivers/regulator/Kconfig
|
||||
+++ b/drivers/regulator/Kconfig
|
||||
@@ -1335,6 +1335,16 @@ config REGULATOR_SM5703
|
||||
This driver provides support for voltage regulators of SM5703
|
||||
multi-function device.
|
||||
|
||||
+config REGULATOR_STARFIVE_JH7110
|
||||
+ tristate "Starfive JH7110 PMIC"
|
||||
+ depends on I2C
|
||||
+ select REGMAP_I2C
|
||||
+ help
|
||||
+ Say y here to select this option to enable the power regulator of
|
||||
+ Starfive JH7110 PMIC.
|
||||
+ This driver supports the control of different power rails of device
|
||||
+ through regulator interface.
|
||||
+
|
||||
config REGULATOR_STM32_BOOSTER
|
||||
tristate "STMicroelectronics STM32 BOOSTER"
|
||||
depends on ARCH_STM32 || COMPILE_TEST
|
||||
--- a/drivers/regulator/Makefile
|
||||
+++ b/drivers/regulator/Makefile
|
||||
@@ -156,6 +156,7 @@ obj-$(CONFIG_REGULATOR_SC2731) += sc2731
|
||||
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_SM5703) += sm5703-regulator.o
|
||||
+obj-$(CONFIG_REGULATOR_STARFIVE_JH7110) += starfive-jh7110-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o
|
||||
obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
|
||||
obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/regulator/starfive-jh7110-regulator.c
|
||||
@@ -0,0 +1,126 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Copyright (c) 2022 Starfive Technology Co., Ltd.
|
||||
+ * Author: Mason Huo <mason.huo@starfivetech.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/regulator/driver.h>
|
||||
+#include <linux/regulator/machine.h>
|
||||
+#include <linux/regulator/of_regulator.h>
|
||||
+#include <linux/regulator/jh7110.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#define JH7110_PM_POWER_SW_0 0x80
|
||||
+#define JH7110_PM_POWER_SW_1 0x81
|
||||
+#define ENABLE_MASK(id) BIT(id)
|
||||
+
|
||||
+
|
||||
+static const struct regmap_config jh7110_regmap_config = {
|
||||
+ .reg_bits = 8,
|
||||
+ .val_bits = 8,
|
||||
+ .max_register = JH7110_PM_POWER_SW_1,
|
||||
+ .cache_type = REGCACHE_FLAT,
|
||||
+};
|
||||
+
|
||||
+static const struct regulator_ops jh7110_ldo_ops = {
|
||||
+ .enable = regulator_enable_regmap,
|
||||
+ .disable = regulator_disable_regmap,
|
||||
+ .is_enabled = regulator_is_enabled_regmap,
|
||||
+};
|
||||
+
|
||||
+#define JH7110_LDO(_id, _name, en_reg, en_mask) \
|
||||
+{\
|
||||
+ .name = (_name),\
|
||||
+ .ops = &jh7110_ldo_ops,\
|
||||
+ .of_match = of_match_ptr(_name),\
|
||||
+ .regulators_node = of_match_ptr("regulators"),\
|
||||
+ .type = REGULATOR_VOLTAGE,\
|
||||
+ .id = JH7110_ID_##_id,\
|
||||
+ .owner = THIS_MODULE,\
|
||||
+ .enable_reg = JH7110_PM_POWER_SW_##en_reg,\
|
||||
+ .enable_mask = ENABLE_MASK(en_mask),\
|
||||
+}
|
||||
+
|
||||
+static const struct regulator_desc jh7110_regulators[] = {
|
||||
+ JH7110_LDO(LDO_REG1, "hdmi_1p8", 0, 0),
|
||||
+ JH7110_LDO(LDO_REG2, "mipitx_1p8", 0, 1),
|
||||
+ JH7110_LDO(LDO_REG3, "mipirx_1p8", 0, 2),
|
||||
+ JH7110_LDO(LDO_REG4, "hdmi_0p9", 0, 3),
|
||||
+ JH7110_LDO(LDO_REG5, "mipitx_0p9", 0, 4),
|
||||
+ JH7110_LDO(LDO_REG6, "mipirx_0p9", 0, 5),
|
||||
+ JH7110_LDO(LDO_REG7, "sdio_vdd", 1, 0),
|
||||
+};
|
||||
+
|
||||
+static int jh7110_i2c_probe(struct i2c_client *i2c)
|
||||
+{
|
||||
+ struct regulator_config config = { };
|
||||
+ struct regulator_dev *rdev;
|
||||
+ struct regulator_init_data *init_data;
|
||||
+ struct regmap *regmap;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ regmap = devm_regmap_init_i2c(i2c, &jh7110_regmap_config);
|
||||
+ if (IS_ERR(regmap)) {
|
||||
+ ret = PTR_ERR(regmap);
|
||||
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
|
||||
+ ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ init_data = of_get_regulator_init_data(&i2c->dev, i2c->dev.of_node, NULL);
|
||||
+ if (!init_data)
|
||||
+ return -ENOMEM;
|
||||
+ config.init_data = init_data;
|
||||
+
|
||||
+ for (i = 0; i < JH7110_MAX_REGULATORS; i++) {
|
||||
+ config.dev = &i2c->dev;
|
||||
+ config.regmap = regmap;
|
||||
+
|
||||
+ rdev = devm_regulator_register(&i2c->dev,
|
||||
+ &jh7110_regulators[i], &config);
|
||||
+ if (IS_ERR(rdev)) {
|
||||
+ dev_err(&i2c->dev,
|
||||
+ "Failed to register JH7110 regulator\n");
|
||||
+ return PTR_ERR(rdev);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_device_id jh7110_i2c_id[] = {
|
||||
+ {"jh7110_evb_reg", 0},
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(i2c, jh7110_i2c_id);
|
||||
+
|
||||
+#ifdef CONFIG_OF
|
||||
+static const struct of_device_id jh7110_dt_ids[] = {
|
||||
+ { .compatible = "starfive,jh7110-evb-regulator",
|
||||
+ .data = &jh7110_i2c_id[0] },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, jh7110_dt_ids);
|
||||
+#endif
|
||||
+
|
||||
+static struct i2c_driver jh7110_regulator_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "jh7110-evb-regulator",
|
||||
+ .of_match_table = of_match_ptr(jh7110_dt_ids),
|
||||
+ },
|
||||
+ .probe = jh7110_i2c_probe,
|
||||
+ .id_table = jh7110_i2c_id,
|
||||
+};
|
||||
+
|
||||
+module_i2c_driver(jh7110_regulator_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Mason Huo <mason.huo@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("Regulator device driver for Starfive JH7110");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--- /dev/null
|
||||
+++ b/include/linux/regulator/jh7110.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
+/*
|
||||
+ * Copyright (c) 2022 Starfive Technology Co., Ltd.
|
||||
+ * Author: Mason Huo <mason.huo@starfivetech.com>
|
||||
+ */
|
||||
+
|
||||
+#ifndef __LINUX_REGULATOR_JH7110_H
|
||||
+#define __LINUX_REGULATOR_JH7110_H
|
||||
+
|
||||
+#define JH7110_MAX_REGULATORS 7
|
||||
+
|
||||
+
|
||||
+enum jh7110_reg_id {
|
||||
+ JH7110_ID_LDO_REG1 = 0,
|
||||
+ JH7110_ID_LDO_REG2,
|
||||
+ JH7110_ID_LDO_REG3,
|
||||
+ JH7110_ID_LDO_REG4,
|
||||
+ JH7110_ID_LDO_REG5,
|
||||
+ JH7110_ID_LDO_REG6,
|
||||
+ JH7110_ID_LDO_REG7,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#endif /* __LINUX_REGULATOR_JH7110_H */
|
@ -0,0 +1,40 @@
|
||||
From f0b4cffe4d1813305f783d208f260747ecc56c50 Mon Sep 17 00:00:00 2001
|
||||
From: "Kevin.xie" <kevin.xie@starfivetech.com>
|
||||
Date: Thu, 24 Nov 2022 16:59:12 +0800
|
||||
Subject: [PATCH 072/116] drivers: nvme: Add precheck and delay for CQE pending
|
||||
status.
|
||||
|
||||
To workaroud the NVMe I/O timeout problem in bootup S10udev case
|
||||
which caused by the CQE update lantancy.
|
||||
|
||||
Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
|
||||
---
|
||||
drivers/nvme/host/pci.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/nvme/host/pci.c
|
||||
+++ b/drivers/nvme/host/pci.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/io-64-nonatomic-hi-lo.h>
|
||||
#include <linux/sed-opal.h>
|
||||
#include <linux/pci-p2pdma.h>
|
||||
+#include <linux/delay.h>
|
||||
|
||||
#include "trace.h"
|
||||
#include "nvme.h"
|
||||
@@ -1062,6 +1063,15 @@ static inline int nvme_poll_cq(struct nv
|
||||
{
|
||||
int found = 0;
|
||||
|
||||
+ /*
|
||||
+ * In some cases, such as udev trigger, cqe status may update
|
||||
+ * a little bit later than MSI, which cause an irq handle missing.
|
||||
+ * To workaound, here we will prefetch the status first, and wait
|
||||
+ * 1us if we get nothing.
|
||||
+ */
|
||||
+ if (!nvme_cqe_pending(nvmeq))
|
||||
+ udelay(1);
|
||||
+
|
||||
while (nvme_cqe_pending(nvmeq)) {
|
||||
found++;
|
||||
/*
|
@ -0,0 +1,93 @@
|
||||
From eb294df4b9fab46bc5dbf676edf51e28e06d1968 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
|
||||
<joao.mario@tecnico.ulisboa.pt>
|
||||
Date: Tue, 16 Nov 2021 15:48:09 +0000
|
||||
Subject: [PATCH 073/116] RISC-V: Create unique identification for SoC PMU
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The SBI PMU platform driver did not provide any identification for
|
||||
perf events matching. This patch introduces a new sysfs file inside the
|
||||
platform device (soc:pmu/id) for pmu identification.
|
||||
|
||||
The identification is a 64-bit value generated as:
|
||||
[63-32]: mvendorid;
|
||||
[31]: marchid[MSB];
|
||||
[30-16]: marchid[15-0];
|
||||
[15-0]: mimpid[15MSBs];
|
||||
|
||||
The CSRs are detailed in the RISC-V privileged spec [1].
|
||||
The marchid is split in MSB + 15LSBs, due to the MSB being used for
|
||||
open-source architecture identification.
|
||||
|
||||
[1] https://github.com/riscv/riscv-isa-manual
|
||||
|
||||
Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
|
||||
---
|
||||
drivers/perf/riscv_pmu_sbi.c | 47 ++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 47 insertions(+)
|
||||
|
||||
--- a/drivers/perf/riscv_pmu_sbi.c
|
||||
+++ b/drivers/perf/riscv_pmu_sbi.c
|
||||
@@ -1019,6 +1019,46 @@ static struct ctl_table sbi_pmu_sysctl_t
|
||||
{ }
|
||||
};
|
||||
|
||||
+static uint64_t pmu_sbi_get_pmu_id(void)
|
||||
+{
|
||||
+ union sbi_pmu_id {
|
||||
+ uint64_t value;
|
||||
+ struct {
|
||||
+ uint16_t imp:16;
|
||||
+ uint16_t arch:16;
|
||||
+ uint32_t vendor:32;
|
||||
+ };
|
||||
+ } pmuid;
|
||||
+
|
||||
+ pmuid.value = 0;
|
||||
+ pmuid.vendor = (uint32_t) sbi_get_mvendorid();
|
||||
+ pmuid.arch = (sbi_get_marchid() >> (63 - 15) & (1 << 15)) | (sbi_get_marchid() & 0x7FFF);
|
||||
+ pmuid.imp = (sbi_get_mimpid() >> 16);
|
||||
+
|
||||
+ return pmuid.value;
|
||||
+}
|
||||
+
|
||||
+static ssize_t pmu_sbi_id_show(struct device *dev,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
+{
|
||||
+ int len;
|
||||
+
|
||||
+ len = sprintf(buf, "0x%llx\n", pmu_sbi_get_pmu_id());
|
||||
+ if (len <= 0)
|
||||
+ dev_err(dev, "mydrv: Invalid sprintf len: %dn", len);
|
||||
+
|
||||
+ return len;
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, pmu_sbi_id_show, 0);
|
||||
+
|
||||
+static struct attribute *pmu_sbi_attrs[] = {
|
||||
+ &dev_attr_id.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+ATTRIBUTE_GROUPS(pmu_sbi);
|
||||
+
|
||||
static int pmu_sbi_device_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct riscv_pmu *pmu = NULL;
|
||||
@@ -1067,6 +1107,13 @@ static int pmu_sbi_device_probe(struct p
|
||||
pmu->event_unmapped = pmu_sbi_event_unmapped;
|
||||
pmu->csr_index = pmu_sbi_csr_index;
|
||||
|
||||
+ ret = sysfs_create_group(&pdev->dev.kobj, &pmu_sbi_group);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "sysfs creation failed\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ pdev->dev.groups = pmu_sbi_groups;
|
||||
+
|
||||
ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
|
||||
if (ret)
|
||||
return ret;
|
@ -0,0 +1,55 @@
|
||||
From 1dc069ffadf4ce7817a716f9df2f480254e9b01d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
|
||||
<joao.mario@tecnico.ulisboa.pt>
|
||||
Date: Tue, 16 Nov 2021 15:48:10 +0000
|
||||
Subject: [PATCH 074/116] RISC-V: Support CPUID for risc-v in perf
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch creates the header.c file for the risc-v architecture and introduces support for
|
||||
PMU identification through sysfs.
|
||||
It is now possible to configure pmu-events in risc-v.
|
||||
|
||||
Depends on patch [1], that introduces the id sysfs file.
|
||||
|
||||
Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
|
||||
Signed-off-by: minda.chen <minda.chen@starfivetech.com>
|
||||
---
|
||||
drivers/perf/riscv_pmu.c | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
--- a/drivers/perf/riscv_pmu.c
|
||||
+++ b/drivers/perf/riscv_pmu.c
|
||||
@@ -18,6 +18,23 @@
|
||||
|
||||
#include <asm/sbi.h>
|
||||
|
||||
+PMU_FORMAT_ATTR(event, "config:0-63");
|
||||
+
|
||||
+static struct attribute *riscv_arch_formats_attr[] = {
|
||||
+ &format_attr_event.attr,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group riscv_pmu_format_group = {
|
||||
+ .name = "format",
|
||||
+ .attrs = riscv_arch_formats_attr,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group *riscv_pmu_attr_groups[] = {
|
||||
+ &riscv_pmu_format_group,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
static bool riscv_perf_user_access(struct perf_event *event)
|
||||
{
|
||||
return ((event->attr.type == PERF_TYPE_HARDWARE) ||
|
||||
@@ -410,6 +427,7 @@ struct riscv_pmu *riscv_pmu_alloc(void)
|
||||
cpuc->events[i] = NULL;
|
||||
}
|
||||
pmu->pmu = (struct pmu) {
|
||||
+ .attr_groups = riscv_pmu_attr_groups,
|
||||
.event_init = riscv_pmu_event_init,
|
||||
.event_mapped = riscv_pmu_event_mapped,
|
||||
.event_unmapped = riscv_pmu_event_unmapped,
|
@ -0,0 +1,42 @@
|
||||
From 3e6ea12dda276c01a756764fcafa315b19860c33 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
|
||||
<joao.mario@tecnico.ulisboa.pt>
|
||||
Date: Tue, 16 Nov 2021 15:48:11 +0000
|
||||
Subject: [PATCH 075/116] RISC-V: Added generic pmu-events mapfile
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The pmu-events now supports custom events for RISC-V, plus the cycle,
|
||||
time and instret events were defined.
|
||||
|
||||
Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
|
||||
---
|
||||
.../pmu-events/arch/riscv/riscv-generic.json | 20 +++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
create mode 100644 tools/perf/pmu-events/arch/riscv/riscv-generic.json
|
||||
|
||||
--- /dev/null
|
||||
+++ b/tools/perf/pmu-events/arch/riscv/riscv-generic.json
|
||||
@@ -0,0 +1,20 @@
|
||||
+[
|
||||
+ {
|
||||
+ "PublicDescription": "CPU Cycles",
|
||||
+ "EventCode": "0x00",
|
||||
+ "EventName": "riscv_cycles",
|
||||
+ "BriefDescription": "CPU cycles RISC-V generic counter"
|
||||
+ },
|
||||
+ {
|
||||
+ "PublicDescription": "CPU Time",
|
||||
+ "EventCode": "0x01",
|
||||
+ "EventName": "riscv_time",
|
||||
+ "BriefDescription": "CPU time RISC-V generic counter"
|
||||
+ },
|
||||
+ {
|
||||
+ "PublicDescription": "CPU Instructions",
|
||||
+ "EventCode": "0x02",
|
||||
+ "EventName": "riscv_instret",
|
||||
+ "BriefDescription": "CPU retired instructions RISC-V generic counter"
|
||||
+ }
|
||||
+]
|
||||
\ No newline at end of file
|
@ -0,0 +1,30 @@
|
||||
From 30e0cdcf9e05faa65ecde4ed8b70039568fdb660 Mon Sep 17 00:00:00 2001
|
||||
From: Minda Chen <minda.chen@starfivetech.com>
|
||||
Date: Thu, 2 Mar 2023 17:16:01 +0800
|
||||
Subject: [PATCH 076/116] perf: sbi: disable cpu hotplug callback.
|
||||
|
||||
register cpu hotplug callback will cause dhrystone
|
||||
and coremark benchmark reduce the scores. this CPU
|
||||
hotplug ops will do in sbi cpu/on and off. So disable
|
||||
this no side effect.
|
||||
|
||||
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
|
||||
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
|
||||
---
|
||||
drivers/perf/riscv_pmu_sbi.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/perf/riscv_pmu_sbi.c
|
||||
+++ b/drivers/perf/riscv_pmu_sbi.c
|
||||
@@ -1114,9 +1114,11 @@ static int pmu_sbi_device_probe(struct p
|
||||
}
|
||||
pdev->dev.groups = pmu_sbi_groups;
|
||||
|
||||
+#ifndef CONFIG_ARCH_STARFIVE
|
||||
ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
|
||||
if (ret)
|
||||
return ret;
|
||||
+#endif
|
||||
|
||||
ret = riscv_pm_pmu_register(pmu);
|
||||
if (ret)
|
@ -0,0 +1,24 @@
|
||||
From fc4b5c7c27e1b56b1f848e50511c4fd081b1b6c5 Mon Sep 17 00:00:00 2001
|
||||
From: Walker Chen <walker.chen@starfivetech.com>
|
||||
Date: Mon, 12 Jun 2023 21:21:45 +0800
|
||||
Subject: [PATCH 077/116] dmaengine: dw-axi-dmac: Drop unused print message
|
||||
|
||||
Removed printing information which is not related to StarFive
|
||||
platform.
|
||||
|
||||
Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
---
|
||||
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
|
||||
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
|
||||
@@ -523,7 +523,7 @@ static void dw_axi_dma_set_hw_channel(st
|
||||
unsigned long reg_value, val;
|
||||
|
||||
if (!chip->apb_regs) {
|
||||
- dev_err(chip->dev, "apb_regs not initialized\n");
|
||||
+ dev_dbg(chip->dev, "apb_regs not initialized\n");
|
||||
return;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,537 @@
|
||||
From 9c4858f9fe4d8f8fe5cf347b3ca727016b7ba492 Mon Sep 17 00:00:00 2001
|
||||
From: Walker Chen <walker.chen@starfivetech.com>
|
||||
Date: Tue, 20 Jun 2023 15:57:53 +0800
|
||||
Subject: [PATCH 081/116] ASoC: starfive: Add JH7110 PDM driver
|
||||
|
||||
Add pdm driver support for the StarFive JH7110 SoC.
|
||||
|
||||
Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
|
||||
---
|
||||
sound/soc/starfive/Kconfig | 8 +
|
||||
sound/soc/starfive/Makefile | 2 +
|
||||
sound/soc/starfive/jh7110_pdm.c | 493 ++++++++++++++++++++++++++++++++
|
||||
3 files changed, 503 insertions(+)
|
||||
create mode 100644 sound/soc/starfive/jh7110_pdm.c
|
||||
|
||||
--- a/sound/soc/starfive/Kconfig
|
||||
+++ b/sound/soc/starfive/Kconfig
|
||||
@@ -7,6 +7,14 @@ config SND_SOC_STARFIVE
|
||||
the Starfive SoCs' Audio interfaces. You will also need to
|
||||
select the audio interfaces to support below.
|
||||
|
||||
+config SND_SOC_JH7110_PDM
|
||||
+ tristate "JH7110 PDM device driver"
|
||||
+ depends on HAVE_CLK && SND_SOC_STARFIVE
|
||||
+ select SND_SOC_JH7110_I2S
|
||||
+ select REGMAP_MMIO
|
||||
+ help
|
||||
+ Say Y or M if you want to add support for StarFive pdm driver.
|
||||
+
|
||||
config SND_SOC_JH7110_PWMDAC
|
||||
tristate "JH7110 PWM-DAC device driver"
|
||||
depends on HAVE_CLK && SND_SOC_STARFIVE
|
||||
--- a/sound/soc/starfive/Makefile
|
||||
+++ b/sound/soc/starfive/Makefile
|
||||
@@ -1,4 +1,6 @@
|
||||
# StarFive Platform Support
|
||||
+obj-$(CONFIG_SND_SOC_JH7110_PDM) += jh7110_pdm.o
|
||||
+
|
||||
obj-$(CONFIG_SND_SOC_JH7110_PWMDAC) += jh7110_pwmdac.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_JH7110_SPDIF) += spdif.o
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/starfive/jh7110_pdm.c
|
||||
@@ -0,0 +1,493 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * PDM driver for the StarFive JH7110 SoC
|
||||
+ *
|
||||
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
|
||||
+ */
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/dmaengine.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <sound/dmaengine_pcm.h>
|
||||
+#include <sound/initval.h>
|
||||
+#include <sound/pcm.h>
|
||||
+#include <sound/pcm_params.h>
|
||||
+#include <sound/soc.h>
|
||||
+#include <sound/soc-dai.h>
|
||||
+#include <sound/tlv.h>
|
||||
+
|
||||
+#define PDM_DMIC_CTRL0 0x00
|
||||
+#define PDM_DC_SCALE0 0x04
|
||||
+#define PDM_DMIC_CTRL1 0x10
|
||||
+#define PDM_DC_SCALE1 0x14
|
||||
+
|
||||
+/* PDM CTRL OFFSET */
|
||||
+#define PDM_DMIC_MSB_SHIFT 1
|
||||
+#define PDM_DMIC_MSB_MASK (0x7 << PDM_DMIC_MSB_SHIFT)
|
||||
+#define PDM_DMIC_VOL_SHIFT 16
|
||||
+#define PDM_DMIC_VOL_MASK (0x3f << PDM_DMIC_VOL_SHIFT)
|
||||
+#define PDM_VOL_DB_MUTE (0x3f << PDM_DMIC_VOL_SHIFT)
|
||||
+#define PDM_VOL_DB_MAX 0
|
||||
+
|
||||
+#define PDM_DMIC_RVOL_MASK BIT(22)
|
||||
+#define PDM_DMIC_LVOL_MASK BIT(23)
|
||||
+#define PDM_DMIC_I2S_SLAVE BIT(24)
|
||||
+#define PDM_DMIC_HPF_EN BIT(28)
|
||||
+#define PDM_DMIC_FASTMODE_MASK BIT(29)
|
||||
+#define PDM_DMIC_DC_BYPASS_MASK BIT(30)
|
||||
+#define PDM_SW_RST_MASK BIT(31)
|
||||
+#define PDM_SW_RST_RELEASE BIT(31)
|
||||
+
|
||||
+/* PDM SCALE OFFSET */
|
||||
+#define DMIC_DCOFF3_SHIFT 24
|
||||
+#define DMIC_DCOFF2_SHIFT 16
|
||||
+#define DMIC_DCOFF1_SHIFT 8
|
||||
+
|
||||
+#define DMIC_DCOFF3_MASK (0xf << DMIC_DCOFF3_SHIFT)
|
||||
+#define DMIC_DCOFF3_VAL (0xc << DMIC_DCOFF3_SHIFT)
|
||||
+#define DMIC_DCOFF1_MASK (0xff << DMIC_DCOFF1_SHIFT)
|
||||
+#define DMIC_DCOFF1_VAL (0x5 << DMIC_DCOFF1_SHIFT)
|
||||
+#define DMIC_SCALE_MASK 0x3f
|
||||
+#define DMIC_SCALE_DEF_VAL 0x8
|
||||
+
|
||||
+enum PDM_MSB_SHIFT {
|
||||
+ PDM_MSB_SHIFT_NONE = 0,
|
||||
+ PDM_MSB_SHIFT_1,
|
||||
+ PDM_MSB_SHIFT_2,
|
||||
+ PDM_MSB_SHIFT_3,
|
||||
+ PDM_MSB_SHIFT_4,
|
||||
+ PDM_MSB_SHIFT_5,
|
||||
+ PDM_MSB_SHIFT_6,
|
||||
+ PDM_MSB_SHIFT_7,
|
||||
+};
|
||||
+
|
||||
+struct sf_pdm {
|
||||
+ struct regmap *pdm_map;
|
||||
+ struct device *dev;
|
||||
+ struct clk *clk_pdm_apb;
|
||||
+ struct clk *clk_pdm_mclk;
|
||||
+ struct clk *clk_mclk;
|
||||
+ struct clk *clk_mclk_ext;
|
||||
+ struct reset_control *rst_pdm_dmic;
|
||||
+ struct reset_control *rst_pdm_apb;
|
||||
+ unsigned char flag_first;
|
||||
+ unsigned int saved_ctrl0;
|
||||
+ unsigned int saved_scale0;
|
||||
+};
|
||||
+
|
||||
+static const DECLARE_TLV_DB_SCALE(volume_tlv, -9450, 150, 0);
|
||||
+
|
||||
+static const struct snd_kcontrol_new sf_pdm_snd_controls[] = {
|
||||
+ SOC_SINGLE("DC compensation Control", PDM_DMIC_CTRL0, 30, 1, 0),
|
||||
+ SOC_SINGLE("High Pass Filter Control", PDM_DMIC_CTRL0, 28, 1, 0),
|
||||
+ SOC_SINGLE("Left Channel Volume Control", PDM_DMIC_CTRL0, 23, 1, 0),
|
||||
+ SOC_SINGLE("Right Channel Volume Control", PDM_DMIC_CTRL0, 22, 1, 0),
|
||||
+ SOC_SINGLE_TLV("Volume", PDM_DMIC_CTRL0, 16, 0x3F, 1, volume_tlv),
|
||||
+ SOC_SINGLE("Data MSB Shift", PDM_DMIC_CTRL0, 1, 7, 0),
|
||||
+ SOC_SINGLE("SCALE", PDM_DC_SCALE0, 0, 0x3F, 0),
|
||||
+ SOC_SINGLE("DC offset", PDM_DC_SCALE0, 8, 0xFFFFF, 0),
|
||||
+};
|
||||
+
|
||||
+static void sf_pdm_enable(struct regmap *map)
|
||||
+{
|
||||
+ /* Left and Right Channel Volume Control Enable */
|
||||
+ regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_RVOL_MASK, 0);
|
||||
+ regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_LVOL_MASK, 0);
|
||||
+}
|
||||
+
|
||||
+static void sf_pdm_disable(struct regmap *map)
|
||||
+{
|
||||
+ /* Left and Right Channel Volume Control Disable */
|
||||
+ regmap_update_bits(map, PDM_DMIC_CTRL0,
|
||||
+ PDM_DMIC_RVOL_MASK, PDM_DMIC_RVOL_MASK);
|
||||
+ regmap_update_bits(map, PDM_DMIC_CTRL0,
|
||||
+ PDM_DMIC_LVOL_MASK, PDM_DMIC_LVOL_MASK);
|
||||
+}
|
||||
+
|
||||
+static int sf_pdm_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SNDRV_PCM_TRIGGER_START:
|
||||
+ case SNDRV_PCM_TRIGGER_RESUME:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
+ if (priv->flag_first) {
|
||||
+ priv->flag_first = 0;
|
||||
+ mdelay(200);
|
||||
+ }
|
||||
+
|
||||
+ sf_pdm_enable(priv->pdm_map);
|
||||
+ return 0;
|
||||
+
|
||||
+ case SNDRV_PCM_TRIGGER_STOP:
|
||||
+ case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
+ sf_pdm_disable(priv->pdm_map);
|
||||
+ return 0;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int sf_pdm_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+ unsigned int sample_rate;
|
||||
+ unsigned int data_width;
|
||||
+ int ret;
|
||||
+ const int pdm_mul = 128;
|
||||
+
|
||||
+ sample_rate = params_rate(params);
|
||||
+ switch (sample_rate) {
|
||||
+ case 8000:
|
||||
+ case 11025:
|
||||
+ case 16000:
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(priv->dev, "can't support sample rate:%d\n", sample_rate);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ data_width = params_width(params);
|
||||
+ switch (data_width) {
|
||||
+ case 16:
|
||||
+ case 32:
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(priv->dev, "can't support bit width %d\n", data_width);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* set pdm_mclk, PDM MCLK = 128 * LRCLK */
|
||||
+ ret = clk_set_rate(priv->clk_pdm_mclk, pdm_mul * sample_rate);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "Can't set pdm_mclk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_dai_ops sf_pdm_dai_ops = {
|
||||
+ .trigger = sf_pdm_trigger,
|
||||
+ .hw_params = sf_pdm_hw_params,
|
||||
+};
|
||||
+
|
||||
+static void sf_pdm_module_init(struct sf_pdm *priv)
|
||||
+{
|
||||
+ /* Reset */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
|
||||
+ PDM_SW_RST_MASK, 0x00);
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
|
||||
+ PDM_SW_RST_MASK, PDM_SW_RST_RELEASE);
|
||||
+
|
||||
+ /* Make sure the device is initially disabled */
|
||||
+ sf_pdm_disable(priv->pdm_map);
|
||||
+
|
||||
+ /* MUTE */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
|
||||
+ PDM_DMIC_VOL_MASK, PDM_VOL_DB_MUTE);
|
||||
+
|
||||
+ /* UNMUTE */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
|
||||
+ PDM_DMIC_VOL_MASK, PDM_VOL_DB_MAX);
|
||||
+
|
||||
+ /* enable high pass filter */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
|
||||
+ PDM_DMIC_HPF_EN, PDM_DMIC_HPF_EN);
|
||||
+
|
||||
+ /* PDM work as slave mode */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
|
||||
+ PDM_DMIC_I2S_SLAVE, PDM_DMIC_I2S_SLAVE);
|
||||
+
|
||||
+ /* disable fast mode */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
|
||||
+ PDM_DMIC_FASTMODE_MASK, 0);
|
||||
+
|
||||
+ /* dmic msb shift 0 */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
|
||||
+ PDM_DMIC_MSB_MASK, 0);
|
||||
+
|
||||
+ /* scale: 0x8 */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
|
||||
+ DMIC_SCALE_MASK, DMIC_SCALE_DEF_VAL);
|
||||
+
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
|
||||
+ DMIC_DCOFF1_MASK, DMIC_DCOFF1_VAL);
|
||||
+
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
|
||||
+ DMIC_DCOFF3_MASK, DMIC_DCOFF3_VAL);
|
||||
+
|
||||
+ /* scale: 0x3f */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
|
||||
+ DMIC_SCALE_MASK, DMIC_SCALE_MASK);
|
||||
+
|
||||
+ /* dmic msb shift 2 */
|
||||
+ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
|
||||
+ PDM_DMIC_MSB_MASK, PDM_MSB_SHIFT_4);
|
||||
+}
|
||||
+
|
||||
+#define SF_PDM_RATES (SNDRV_PCM_RATE_8000 | \
|
||||
+ SNDRV_PCM_RATE_11025 | \
|
||||
+ SNDRV_PCM_RATE_16000)
|
||||
+
|
||||
+#define SF_PDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
+ SNDRV_PCM_FMTBIT_S32_LE)
|
||||
+
|
||||
+static struct snd_soc_dai_driver sf_pdm_dai_drv = {
|
||||
+ .name = "PDM",
|
||||
+ .id = 0,
|
||||
+ .capture = {
|
||||
+ .stream_name = "Capture",
|
||||
+ .channels_min = 2,
|
||||
+ .channels_max = 2,
|
||||
+ .rates = SF_PDM_RATES,
|
||||
+ .formats = SF_PDM_FORMATS,
|
||||
+ },
|
||||
+ .ops = &sf_pdm_dai_ops,
|
||||
+ .symmetric_rate = 1,
|
||||
+};
|
||||
+
|
||||
+static int sf_pdm_component_probe(struct snd_soc_component *component)
|
||||
+{
|
||||
+ struct sf_pdm *priv = snd_soc_component_get_drvdata(component);
|
||||
+
|
||||
+ snd_soc_component_init_regmap(component, priv->pdm_map);
|
||||
+ snd_soc_add_component_controls(component, sf_pdm_snd_controls,
|
||||
+ ARRAY_SIZE(sf_pdm_snd_controls));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sf_pdm_clock_enable(struct sf_pdm *priv)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(priv->clk_pdm_mclk);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "failed to prepare enable clk_pdm_mclk\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(priv->clk_pdm_apb);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "failed to prepare enable clk_pdm_apb\n");
|
||||
+ goto disable_pdm_mclk;
|
||||
+ }
|
||||
+
|
||||
+ ret = reset_control_deassert(priv->rst_pdm_dmic);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "failed to deassert pdm_dmic\n");
|
||||
+ goto disable_pdm_apb;
|
||||
+ }
|
||||
+
|
||||
+ ret = reset_control_deassert(priv->rst_pdm_apb);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "failed to deassert pdm_apb\n");
|
||||
+ goto disable_pdm_apb;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_set_parent(priv->clk_mclk, priv->clk_mclk_ext);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "failed to set parent clk_mclk ret=%d\n", ret);
|
||||
+ goto disable_pdm_apb;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+disable_pdm_apb:
|
||||
+ clk_disable_unprepare(priv->clk_pdm_apb);
|
||||
+disable_pdm_mclk:
|
||||
+ clk_disable_unprepare(priv->clk_pdm_mclk);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM
|
||||
+static int sf_pdm_runtime_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct sf_pdm *priv = dev_get_drvdata(dev);
|
||||
+
|
||||
+ clk_disable_unprepare(priv->clk_pdm_apb);
|
||||
+ clk_disable_unprepare(priv->clk_pdm_mclk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sf_pdm_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ struct sf_pdm *priv = dev_get_drvdata(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = sf_pdm_clock_enable(priv);
|
||||
+ if (!ret)
|
||||
+ sf_pdm_module_init(priv);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+static int sf_pdm_suspend(struct snd_soc_component *component)
|
||||
+{
|
||||
+ return pm_runtime_force_suspend(component->dev);
|
||||
+}
|
||||
+
|
||||
+static int sf_pdm_resume(struct snd_soc_component *component)
|
||||
+{
|
||||
+ return pm_runtime_force_resume(component->dev);
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+#define sf_pdm_suspend NULL
|
||||
+#define sf_pdm_resume NULL
|
||||
+#endif
|
||||
+
|
||||
+static const struct snd_soc_component_driver sf_pdm_component_drv = {
|
||||
+ .name = "jh7110-pdm",
|
||||
+ .probe = sf_pdm_component_probe,
|
||||
+ .suspend = sf_pdm_suspend,
|
||||
+ .resume = sf_pdm_resume,
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_config sf_pdm_regmap_cfg = {
|
||||
+ .reg_bits = 32,
|
||||
+ .val_bits = 32,
|
||||
+ .reg_stride = 4,
|
||||
+ .max_register = 0x20,
|
||||
+};
|
||||
+
|
||||
+static int sf_pdm_clock_get(struct platform_device *pdev, struct sf_pdm *priv)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ static struct clk_bulk_data clks[] = {
|
||||
+ { .id = "pdm_mclk" },
|
||||
+ { .id = "pdm_apb" },
|
||||
+ { .id = "clk_mclk" },
|
||||
+ { .id = "mclk_ext" },
|
||||
+ };
|
||||
+
|
||||
+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to get pdm clocks\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ priv->clk_pdm_mclk = clks[0].clk;
|
||||
+ priv->clk_pdm_apb = clks[1].clk;
|
||||
+ priv->clk_mclk = clks[2].clk;
|
||||
+ priv->clk_mclk_ext = clks[3].clk;
|
||||
+
|
||||
+ priv->rst_pdm_dmic = devm_reset_control_get_exclusive(&pdev->dev, "pdm_dmic");
|
||||
+ if (IS_ERR(priv->rst_pdm_dmic)) {
|
||||
+ dev_err(&pdev->dev, "failed to get pdm_dmic reset control\n");
|
||||
+ ret = PTR_ERR(priv->rst_pdm_dmic);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ priv->rst_pdm_apb = devm_reset_control_get_exclusive(&pdev->dev, "pdm_apb");
|
||||
+ if (IS_ERR(priv->rst_pdm_apb)) {
|
||||
+ dev_err(&pdev->dev, "failed to get pdm_apb reset control\n");
|
||||
+ ret = PTR_ERR(priv->rst_pdm_apb);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * pdm clock must always be enabled as hardware issue that
|
||||
+ * no data in the first 4 seconds of the first recording
|
||||
+ */
|
||||
+ ret = sf_pdm_clock_enable(priv);
|
||||
+
|
||||
+exit:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int sf_pdm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct sf_pdm *priv;
|
||||
+ struct resource *res;
|
||||
+ void __iomem *regs;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+
|
||||
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pdm");
|
||||
+ regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(regs))
|
||||
+ return PTR_ERR(regs);
|
||||
+
|
||||
+ priv->pdm_map = devm_regmap_init_mmio(&pdev->dev, regs, &sf_pdm_regmap_cfg);
|
||||
+ if (IS_ERR(priv->pdm_map)) {
|
||||
+ dev_err(&pdev->dev, "failed to init regmap: %ld\n",
|
||||
+ PTR_ERR(priv->pdm_map));
|
||||
+ return PTR_ERR(priv->pdm_map);
|
||||
+ }
|
||||
+
|
||||
+ priv->dev = &pdev->dev;
|
||||
+ priv->flag_first = 1;
|
||||
+
|
||||
+ ret = sf_pdm_clock_get(pdev, priv);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to enable audio-pdm clock\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dev_set_drvdata(&pdev->dev, priv);
|
||||
+
|
||||
+ ret = devm_snd_soc_register_component(&pdev->dev, &sf_pdm_component_drv,
|
||||
+ &sf_pdm_dai_drv, 1);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to register pdm dai\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ pm_runtime_enable(&pdev->dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sf_pdm_dev_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id sf_pdm_of_match[] = {
|
||||
+ {.compatible = "starfive,jh7110-pdm",},
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sf_pdm_of_match);
|
||||
+
|
||||
+static const struct dev_pm_ops sf_pdm_pm_ops = {
|
||||
+ SET_RUNTIME_PM_OPS(sf_pdm_runtime_suspend,
|
||||
+ sf_pdm_runtime_resume, NULL)
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver sf_pdm_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "jh7110-pdm",
|
||||
+ .of_match_table = sf_pdm_of_match,
|
||||
+ .pm = &sf_pdm_pm_ops,
|
||||
+ },
|
||||
+ .probe = sf_pdm_probe,
|
||||
+ .remove = sf_pdm_dev_remove,
|
||||
+};
|
||||
+module_platform_driver(sf_pdm_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
|
||||
+MODULE_DESCRIPTION("Starfive PDM Controller Driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
@ -0,0 +1,55 @@
|
||||
From 59cbdfeee0fc1ad382a0bc8f7fa897a9f5d03df0 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Fri, 9 Jun 2023 16:54:36 +0800
|
||||
Subject: [PATCH 082/116] dt-binding: input: Add tink_ft5406
|
||||
|
||||
Add tink_ft5406.
|
||||
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
---
|
||||
.../bindings/input/tinker_ft5406.yaml | 39 +++++++++++++++++++
|
||||
1 file changed, 39 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/input/tinker_ft5406.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/input/tinker_ft5406.yaml
|
||||
@@ -0,0 +1,39 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/input/touchscreen/goodix.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Tinker FT5406 touchscreen controller Bindings
|
||||
+
|
||||
+maintainers:
|
||||
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: touchscreen.yaml#
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: tinker_ft5406
|
||||
+
|
||||
+ reg:
|
||||
+ const: 0x38
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ i2c {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ tinker_ft5406@38 {
|
||||
+ compatible = "tinker_ft5406";
|
||||
+ reg = <0x38>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+...
|
@ -0,0 +1,444 @@
|
||||
From 4800b6e0f2190d991cd4e5352167a9422841f195 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Wed, 21 Dec 2022 16:20:04 +0800
|
||||
Subject: [PATCH 083/116] input: touchscreen: Add tinker_ft5406 driver support
|
||||
|
||||
Add tinker_ft5406 driver support
|
||||
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
---
|
||||
drivers/input/touchscreen/Kconfig | 6 +
|
||||
drivers/input/touchscreen/Makefile | 1 +
|
||||
drivers/input/touchscreen/tinker_ft5406.c | 406 ++++++++++++++++++++++
|
||||
3 files changed, 413 insertions(+)
|
||||
create mode 100644 drivers/input/touchscreen/tinker_ft5406.c
|
||||
|
||||
--- a/drivers/input/touchscreen/Kconfig
|
||||
+++ b/drivers/input/touchscreen/Kconfig
|
||||
@@ -1399,4 +1399,10 @@ config TOUCHSCREEN_HIMAX_HX83112B
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called himax_hx83112b.
|
||||
|
||||
+config TOUCHSCREEN_TINKER_FT5406
|
||||
+ tristate "tinker ft5406"
|
||||
+ depends on I2C
|
||||
+ help
|
||||
+ Control ft5406 touch ic.
|
||||
+
|
||||
endif
|
||||
--- a/drivers/input/touchscreen/Makefile
|
||||
+++ b/drivers/input/touchscreen/Makefile
|
||||
@@ -118,3 +118,4 @@ obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5
|
||||
obj-$(CONFIG_TOUCHSCREEN_IQS7211) += iqs7211.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ZINITIX) += zinitix.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_HIMAX_HX83112B) += himax_hx83112b.o
|
||||
+obj-$(CONFIG_TOUCHSCREEN_TINKER_FT5406) += tinker_ft5406.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/touchscreen/tinker_ft5406.c
|
||||
@@ -0,0 +1,406 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ *
|
||||
+ * TINKER BOARD FT5406 touch driver.
|
||||
+ *
|
||||
+ * Copyright (c) 2016 ASUSTek Computer Inc.
|
||||
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
|
||||
+ *
|
||||
+ * This software is licensed under the terms of the GNU General Public
|
||||
+ * License version 2, as published by the Free Software Foundation, and
|
||||
+ * may be copied, distributed, and modified under those terms.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/input/mt.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/workqueue.h>
|
||||
+
|
||||
+#define RETRY_COUNT 10
|
||||
+#define FT_ONE_TCH_LEN 6
|
||||
+
|
||||
+#define FT_REG_FW_VER 0xA6
|
||||
+#define FT_REG_FW_MIN_VER 0xB2
|
||||
+#define FT_REG_FW_SUB_MIN_VER 0xB3
|
||||
+
|
||||
+#define VALID_TD_STATUS_VAL 10
|
||||
+#define MAX_TOUCH_POINTS 5
|
||||
+
|
||||
+#define FT_PRESS 0x7F
|
||||
+#define FT_MAX_ID 0x0F
|
||||
+
|
||||
+#define FT_TOUCH_X_H 0
|
||||
+#define FT_TOUCH_X_L 1
|
||||
+#define FT_TOUCH_Y_H 2
|
||||
+#define FT_TOUCH_Y_L 3
|
||||
+#define FT_TOUCH_EVENT 0
|
||||
+#define FT_TOUCH_ID 2
|
||||
+
|
||||
+#define FT_TOUCH_X_H_REG 3
|
||||
+#define FT_TOUCH_X_L_REG 4
|
||||
+#define FT_TOUCH_Y_H_REG 5
|
||||
+#define FT_TOUCH_Y_L_REG 6
|
||||
+#define FT_TD_STATUS_REG 2
|
||||
+#define FT_TOUCH_EVENT_REG 3
|
||||
+#define FT_TOUCH_ID_REG 5
|
||||
+
|
||||
+#define FT_TOUCH_DOWN 0
|
||||
+#define FT_TOUCH_CONTACT 2
|
||||
+
|
||||
+struct ts_event {
|
||||
+ u16 au16_x[MAX_TOUCH_POINTS]; /*x coordinate */
|
||||
+ u16 au16_y[MAX_TOUCH_POINTS]; /*y coordinate */
|
||||
+ u8 au8_touch_event[MAX_TOUCH_POINTS]; /*touch event: 0:down; 1:up; 2:contact */
|
||||
+ u8 au8_finger_id[MAX_TOUCH_POINTS]; /*touch ID */
|
||||
+ u16 pressure;
|
||||
+ u8 touch_point;
|
||||
+ u8 point_num;
|
||||
+};
|
||||
+
|
||||
+struct tinker_ft5406_data {
|
||||
+ struct device *dev;
|
||||
+ struct i2c_client *client;
|
||||
+ struct input_dev *input_dev;
|
||||
+ struct ts_event event;
|
||||
+ struct work_struct ft5406_work;
|
||||
+
|
||||
+ int screen_width;
|
||||
+ int screen_height;
|
||||
+ int xy_reverse;
|
||||
+ int known_ids;
|
||||
+ int retry_count;
|
||||
+ bool finish_work;
|
||||
+};
|
||||
+
|
||||
+struct tinker_ft5406_data *g_ts_data;
|
||||
+
|
||||
+static int fts_i2c_read(struct i2c_client *client, char *writebuf,
|
||||
+ int writelen, char *readbuf, int readlen)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (writelen > 0) {
|
||||
+ struct i2c_msg msgs[] = {
|
||||
+ {
|
||||
+ .addr = client->addr,
|
||||
+ .flags = 0,
|
||||
+ .len = writelen,
|
||||
+ .buf = writebuf,
|
||||
+ },
|
||||
+ {
|
||||
+ .addr = client->addr,
|
||||
+ .flags = I2C_M_RD,
|
||||
+ .len = readlen,
|
||||
+ .buf = readbuf,
|
||||
+ },
|
||||
+ };
|
||||
+ ret = i2c_transfer(client->adapter, msgs, 2);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(&client->dev, "i2c read error, %d\n", ret);
|
||||
+ } else {
|
||||
+ struct i2c_msg msgs[] = {
|
||||
+ {
|
||||
+ .addr = client->addr,
|
||||
+ .flags = I2C_M_RD,
|
||||
+ .len = readlen,
|
||||
+ .buf = readbuf,
|
||||
+ },
|
||||
+ };
|
||||
+ ret = i2c_transfer(client->adapter, msgs, 1);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(&client->dev, "i2c read error, %d\n", ret);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int fts_read_reg(struct i2c_client *client, u8 addr, u8 *val)
|
||||
+{
|
||||
+ return fts_i2c_read(client, &addr, 1, val, 1);
|
||||
+}
|
||||
+
|
||||
+static int fts_check_fw_ver(struct i2c_client *client)
|
||||
+{
|
||||
+ u8 reg_addr, fw_ver[3];
|
||||
+ int ret;
|
||||
+
|
||||
+ reg_addr = FT_REG_FW_VER;
|
||||
+ ret = fts_i2c_read(client, ®_addr, 1, &fw_ver[0], 1);
|
||||
+ if (ret < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ reg_addr = FT_REG_FW_MIN_VER;
|
||||
+ ret = fts_i2c_read(client, ®_addr, 1, &fw_ver[1], 1);
|
||||
+ if (ret < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ reg_addr = FT_REG_FW_SUB_MIN_VER;
|
||||
+ ret = fts_i2c_read(client, ®_addr, 1, &fw_ver[2], 1);
|
||||
+ if (ret < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ dev_info(&client->dev, "Firmware version = %d.%d.%d\n",
|
||||
+ fw_ver[0], fw_ver[1], fw_ver[2]);
|
||||
+ return 0;
|
||||
+
|
||||
+error:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int fts_read_td_status(struct tinker_ft5406_data *ts_data)
|
||||
+{
|
||||
+ u8 td_status;
|
||||
+ int ret = -1;
|
||||
+
|
||||
+ ret = fts_read_reg(ts_data->client, FT_TD_STATUS_REG, &td_status);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&ts_data->client->dev,
|
||||
+ "Get reg td_status failed, %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return (int)td_status;
|
||||
+}
|
||||
+
|
||||
+static int fts_read_touchdata(struct tinker_ft5406_data *ts_data)
|
||||
+{
|
||||
+ struct ts_event *event = &ts_data->event;
|
||||
+ int ret = -1, i;
|
||||
+ u8 buf[FT_ONE_TCH_LEN-2] = { 0 };
|
||||
+ u8 reg_addr, pointid = FT_MAX_ID;
|
||||
+
|
||||
+ for (i = 0; i < event->touch_point && i < MAX_TOUCH_POINTS; i++) {
|
||||
+ reg_addr = FT_TOUCH_X_H_REG + (i * FT_ONE_TCH_LEN);
|
||||
+ ret = fts_i2c_read(ts_data->client, ®_addr, 1, buf, FT_ONE_TCH_LEN-2);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&ts_data->client->dev, "Read touchdata failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ pointid = (buf[FT_TOUCH_ID]) >> 4;
|
||||
+ if (pointid >= MAX_TOUCH_POINTS)
|
||||
+ break;
|
||||
+ event->au8_finger_id[i] = pointid;
|
||||
+ event->au16_x[i] = (s16) (buf[FT_TOUCH_X_H] & 0x0F) << 8 | (s16) buf[FT_TOUCH_X_L];
|
||||
+ event->au16_y[i] = (s16) (buf[FT_TOUCH_Y_H] & 0x0F) << 8 | (s16) buf[FT_TOUCH_Y_L];
|
||||
+ event->au8_touch_event[i] = buf[FT_TOUCH_EVENT] >> 6;
|
||||
+
|
||||
+ if (ts_data->xy_reverse) {
|
||||
+ event->au16_x[i] = ts_data->screen_width - event->au16_x[i] - 1;
|
||||
+ event->au16_y[i] = ts_data->screen_height - event->au16_y[i] - 1;
|
||||
+ }
|
||||
+ }
|
||||
+ event->pressure = FT_PRESS;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void fts_report_value(struct tinker_ft5406_data *ts_data)
|
||||
+{
|
||||
+ struct ts_event *event = &ts_data->event;
|
||||
+ int i, modified_ids = 0, released_ids;
|
||||
+
|
||||
+ for (i = 0; i < event->touch_point && i < MAX_TOUCH_POINTS; i++) {
|
||||
+ if (event->au8_touch_event[i] == FT_TOUCH_DOWN ||
|
||||
+ event->au8_touch_event[i] == FT_TOUCH_CONTACT) {
|
||||
+ modified_ids |= 1 << event->au8_finger_id[i];
|
||||
+ input_mt_slot(ts_data->input_dev, event->au8_finger_id[i]);
|
||||
+ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER,
|
||||
+ true);
|
||||
+ input_report_abs(ts_data->input_dev, ABS_MT_TOUCH_MAJOR,
|
||||
+ event->pressure);
|
||||
+ input_report_abs(ts_data->input_dev, ABS_MT_POSITION_X,
|
||||
+ event->au16_x[i]);
|
||||
+ input_report_abs(ts_data->input_dev, ABS_MT_POSITION_Y,
|
||||
+ event->au16_y[i]);
|
||||
+
|
||||
+ if (!((1 << event->au8_finger_id[i]) & ts_data->known_ids))
|
||||
+ dev_dbg(&ts_data->client->dev, "Touch id-%d: x = %d, y = %d\n",
|
||||
+ event->au8_finger_id[i],
|
||||
+ event->au16_x[i],
|
||||
+ event->au16_y[i]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ released_ids = ts_data->known_ids & ~modified_ids;
|
||||
+ for (i = 0; released_ids && i < MAX_TOUCH_POINTS; i++) {
|
||||
+ if (released_ids & (1<<i)) {
|
||||
+ dev_dbg(&ts_data->client->dev, "Release id-%d, known = %x modified = %x\n",
|
||||
+ i, ts_data->known_ids, modified_ids);
|
||||
+ input_mt_slot(ts_data->input_dev, i);
|
||||
+ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, false);
|
||||
+ modified_ids &= ~(1 << i);
|
||||
+ }
|
||||
+ }
|
||||
+ ts_data->known_ids = modified_ids;
|
||||
+ input_mt_report_pointer_emulation(ts_data->input_dev, true);
|
||||
+ input_sync(ts_data->input_dev);
|
||||
+}
|
||||
+
|
||||
+static void fts_retry_clear(struct tinker_ft5406_data *ts_data)
|
||||
+{
|
||||
+ if (ts_data->retry_count != 0)
|
||||
+ ts_data->retry_count = 0;
|
||||
+}
|
||||
+
|
||||
+static int fts_retry_wait(struct tinker_ft5406_data *ts_data)
|
||||
+{
|
||||
+ if (ts_data->retry_count < RETRY_COUNT) {
|
||||
+ dev_info(&ts_data->client->dev,
|
||||
+ "Wait and retry, count = %d\n", ts_data->retry_count);
|
||||
+ ts_data->retry_count++;
|
||||
+ msleep(1000);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ dev_err(&ts_data->client->dev, "Attach retry count\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void tinker_ft5406_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct ts_event *event = &g_ts_data->event;
|
||||
+ int ret = 0, td_status;
|
||||
+
|
||||
+ /* polling 60fps */
|
||||
+ while (!g_ts_data->finish_work) {
|
||||
+ td_status = fts_read_td_status(g_ts_data);
|
||||
+ if (td_status < 0) {
|
||||
+ ret = fts_retry_wait(g_ts_data);
|
||||
+ if (ret == 0) {
|
||||
+ dev_err(&g_ts_data->client->dev, "Stop touch polling\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ } else if (td_status < VALID_TD_STATUS_VAL + 1 &&
|
||||
+ (td_status > 0 || g_ts_data->known_ids != 0)) {
|
||||
+ fts_retry_clear(g_ts_data);
|
||||
+ memset(event, -1, sizeof(struct ts_event));
|
||||
+ event->touch_point = td_status;
|
||||
+ ret = fts_read_touchdata(g_ts_data);
|
||||
+ if (ret == 0)
|
||||
+ fts_report_value(g_ts_data);
|
||||
+ }
|
||||
+ msleep_interruptible(17);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int tinker_ft5406_open(struct input_dev *dev)
|
||||
+{
|
||||
+ schedule_work(&g_ts_data->ft5406_work);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void tinker_ft5406_close(struct input_dev *dev)
|
||||
+{
|
||||
+ g_ts_data->finish_work = true;
|
||||
+ cancel_work_sync(&g_ts_data->ft5406_work);
|
||||
+ g_ts_data->finish_work = false;
|
||||
+}
|
||||
+
|
||||
+static int tinker_ft5406_probe(struct i2c_client *client)
|
||||
+{
|
||||
+ struct input_dev *input_dev;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ dev_info(&client->dev, "Address = 0x%x\n", client->addr);
|
||||
+
|
||||
+ g_ts_data = kzalloc(sizeof(struct tinker_ft5406_data), GFP_KERNEL);
|
||||
+ if (g_ts_data == NULL) {
|
||||
+ dev_err(&client->dev, "No memory for device\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ g_ts_data->client = client;
|
||||
+ i2c_set_clientdata(client, g_ts_data);
|
||||
+
|
||||
+ g_ts_data->screen_width = 800;
|
||||
+ g_ts_data->screen_height = 480;
|
||||
+ g_ts_data->xy_reverse = 1;
|
||||
+
|
||||
+ dev_info(&client->dev, "width = %d, height = %d, reverse = %d\n",
|
||||
+ g_ts_data->screen_width, g_ts_data->screen_height, g_ts_data->xy_reverse);
|
||||
+
|
||||
+ ret = fts_check_fw_ver(g_ts_data->client);
|
||||
+ if (ret) {
|
||||
+ dev_err(&client->dev, "Checking touch ic failed\n");
|
||||
+ goto check_fw_err;
|
||||
+ }
|
||||
+
|
||||
+ input_dev = input_allocate_device();
|
||||
+ if (!input_dev) {
|
||||
+ dev_err(&client->dev, "Failed to allocate input device\n");
|
||||
+ goto input_allocate_failed;
|
||||
+ }
|
||||
+ input_dev->name = "fts_ts";
|
||||
+ input_dev->id.bustype = BUS_I2C;
|
||||
+ input_dev->dev.parent = &g_ts_data->client->dev;
|
||||
+ input_dev->open = tinker_ft5406_open;
|
||||
+ input_dev->close = tinker_ft5406_close;
|
||||
+
|
||||
+ g_ts_data->input_dev = input_dev;
|
||||
+ input_set_drvdata(input_dev, g_ts_data);
|
||||
+
|
||||
+ __set_bit(EV_SYN, input_dev->evbit);
|
||||
+ __set_bit(EV_KEY, input_dev->evbit);
|
||||
+ __set_bit(EV_ABS, input_dev->evbit);
|
||||
+ __set_bit(BTN_TOUCH, input_dev->keybit);
|
||||
+
|
||||
+ input_mt_init_slots(input_dev, MAX_TOUCH_POINTS, 0);
|
||||
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, g_ts_data->screen_width, 0, 0);
|
||||
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, g_ts_data->screen_height, 0, 0);
|
||||
+
|
||||
+ ret = input_register_device(input_dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(&client->dev, "Input device registration failed\n");
|
||||
+ goto input_register_failed;
|
||||
+ }
|
||||
+
|
||||
+ INIT_WORK(&g_ts_data->ft5406_work, tinker_ft5406_work);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+input_register_failed:
|
||||
+ input_free_device(input_dev);
|
||||
+input_allocate_failed:
|
||||
+check_fw_err:
|
||||
+ kfree(g_ts_data);
|
||||
+ g_ts_data = NULL;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void tinker_ft5406_remove(struct i2c_client *client)
|
||||
+{
|
||||
+ cancel_work_sync(&g_ts_data->ft5406_work);
|
||||
+ if (g_ts_data->input_dev) {
|
||||
+ input_unregister_device(g_ts_data->input_dev);
|
||||
+ input_free_device(g_ts_data->input_dev);
|
||||
+ }
|
||||
+ kfree(g_ts_data);
|
||||
+ g_ts_data = NULL;
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_device_id tinker_ft5406_id[] = {
|
||||
+ {"tinker_ft5406", 0},
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+static struct i2c_driver tinker_ft5406_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "tinker_ft5406",
|
||||
+ },
|
||||
+ .probe = tinker_ft5406_probe,
|
||||
+ .remove = tinker_ft5406_remove,
|
||||
+ .id_table = tinker_ft5406_id,
|
||||
+};
|
||||
+module_i2c_driver(tinker_ft5406_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("TINKER BOARD FT5406 Touch driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
@ -0,0 +1,246 @@
|
||||
From b477a1a53553336edcfeb83be1b35817928daed8 Mon Sep 17 00:00:00 2001
|
||||
From: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Date: Mon, 5 Jun 2023 14:46:16 +0800
|
||||
Subject: [PATCH 084/116] dt-binding: media: Add JH7110 Camera Subsystem.
|
||||
|
||||
Add the bindings documentation for Starfive JH7110 Camera Subsystem
|
||||
which is used for handing image sensor data.
|
||||
|
||||
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
|
||||
---
|
||||
.../bindings/media/starfive,jh7110-camss.yaml | 228 ++++++++++++++++++
|
||||
1 file changed, 228 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
|
||||
@@ -0,0 +1,228 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/media/starfive,jh7110-camss.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Starfive SoC CAMSS ISP
|
||||
+
|
||||
+maintainers:
|
||||
+ - Jack Zhu <jack.zhu@starfivetech.com>
|
||||
+ - Changhuang Liang <changhuang.liang@starfivetech.com>
|
||||
+
|
||||
+description:
|
||||
+ The Starfive CAMSS ISP is a Camera interface for Starfive JH7110 SoC. It
|
||||
+ consists of a VIN controller (Video In Controller, a top-level control unit)
|
||||
+ and an ISP.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: starfive,jh7110-vin
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 8
|
||||
+
|
||||
+ reg-names:
|
||||
+ items:
|
||||
+ - const: csi2rx
|
||||
+ - const: vclk
|
||||
+ - const: vrst
|
||||
+ - const: sctrl
|
||||
+ - const: isp
|
||||
+ - const: trst
|
||||
+ - const: pmu
|
||||
+ - const: syscrg
|
||||
+
|
||||
+ clocks:
|
||||
+ maxItems: 16
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: clk_apb_func
|
||||
+ - const: clk_pclk
|
||||
+ - const: clk_sys_clk
|
||||
+ - const: clk_wrapper_clk_c
|
||||
+ - const: clk_dvp_inv
|
||||
+ - const: clk_axiwr
|
||||
+ - const: clk_mipi_rx0_pxl
|
||||
+ - const: clk_pixel_clk_if0
|
||||
+ - const: clk_pixel_clk_if1
|
||||
+ - const: clk_pixel_clk_if2
|
||||
+ - const: clk_pixel_clk_if3
|
||||
+ - const: clk_m31dphy_cfgclk_in
|
||||
+ - const: clk_m31dphy_refclk_in
|
||||
+ - const: clk_m31dphy_txclkesc_lan0
|
||||
+ - const: clk_ispcore_2x
|
||||
+ - const: clk_isp_axi
|
||||
+
|
||||
+ resets:
|
||||
+ maxItems: 14
|
||||
+
|
||||
+ reset-names:
|
||||
+ items:
|
||||
+ - const: rst_wrapper_p
|
||||
+ - const: rst_wrapper_c
|
||||
+ - const: rst_pclk
|
||||
+ - const: rst_sys_clk
|
||||
+ - const: rst_axird
|
||||
+ - const: rst_axiwr
|
||||
+ - const: rst_pixel_clk_if0
|
||||
+ - const: rst_pixel_clk_if1
|
||||
+ - const: rst_pixel_clk_if2
|
||||
+ - const: rst_pixel_clk_if3
|
||||
+ - const: rst_m31dphy_hw
|
||||
+ - const: rst_m31dphy_b09_always_on
|
||||
+ - const: rst_isp_top_n
|
||||
+ - const: rst_isp_top_axi
|
||||
+
|
||||
+ power-domains:
|
||||
+ items:
|
||||
+ - description: JH7110 ISP Power Domain Switch Controller.
|
||||
+
|
||||
+ interrupts:
|
||||
+ maxItems: 5
|
||||
+
|
||||
+ ports:
|
||||
+ $ref: /schemas/graph.yaml#/properties/ports
|
||||
+
|
||||
+ properties:
|
||||
+ port@0:
|
||||
+ $ref: /schemas/graph.yaml#/$defs/port-base
|
||||
+ unevaluatedProperties: false
|
||||
+ description: Input port for receiving DVP data.
|
||||
+
|
||||
+ properties:
|
||||
+ endpoint:
|
||||
+ $ref: video-interfaces.yaml#
|
||||
+ unevaluatedProperties: false
|
||||
+
|
||||
+ properties:
|
||||
+ bus-type:
|
||||
+ enum: [5, 6]
|
||||
+
|
||||
+ bus-width:
|
||||
+ enum: [8, 10, 12]
|
||||
+
|
||||
+ data-shift:
|
||||
+ enum: [0, 2]
|
||||
+ default: 0
|
||||
+
|
||||
+ hsync-active:
|
||||
+ enum: [0, 1]
|
||||
+ default: 1
|
||||
+
|
||||
+ vsync-active:
|
||||
+ enum: [0, 1]
|
||||
+ default: 1
|
||||
+
|
||||
+ required:
|
||||
+ - bus-type
|
||||
+ - bus-width
|
||||
+
|
||||
+ port@1:
|
||||
+ $ref: /schemas/graph.yaml#/properties/port
|
||||
+ description: Input port for receiving CSI data.
|
||||
+
|
||||
+ required:
|
||||
+ - port@0
|
||||
+ - port@1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - reg-names
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+ - reset-names
|
||||
+ - power-domains
|
||||
+ - interrupts
|
||||
+ - ports
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ vin_sysctl: vin_sysctl@19800000 {
|
||||
+ compatible = "starfive,jh7110-vin";
|
||||
+ reg = <0x0 0x19800000 0x0 0x10000>,
|
||||
+ <0x0 0x19810000 0x0 0x10000>,
|
||||
+ <0x0 0x19820000 0x0 0x10000>,
|
||||
+ <0x0 0x19840000 0x0 0x10000>,
|
||||
+ <0x0 0x19870000 0x0 0x30000>,
|
||||
+ <0x0 0x11840000 0x0 0x10000>,
|
||||
+ <0x0 0x17030000 0x0 0x10000>,
|
||||
+ <0x0 0x13020000 0x0 0x10000>;
|
||||
+ reg-names = "csi2rx", "vclk", "vrst", "sctrl",
|
||||
+ "isp", "trst", "pmu", "syscrg";
|
||||
+ clocks = <&clkisp JH7110_DOM4_APB_FUNC>,
|
||||
+ <&clkisp JH7110_U0_VIN_PCLK>,
|
||||
+ <&clkisp JH7110_U0_VIN_SYS_CLK>,
|
||||
+ <&clkisp JH7110_U0_ISPV2_TOP_WRAPPER_CLK_C>,
|
||||
+ <&clkisp JH7110_DVP_INV>,
|
||||
+ <&clkisp JH7110_U0_VIN_CLK_P_AXIWR>,
|
||||
+ <&clkisp JH7110_MIPI_RX0_PXL>,
|
||||
+ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF0>,
|
||||
+ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF1>,
|
||||
+ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF2>,
|
||||
+ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF3>,
|
||||
+ <&clkisp JH7110_U0_M31DPHY_CFGCLK_IN>,
|
||||
+ <&clkisp JH7110_U0_M31DPHY_REFCLK_IN>,
|
||||
+ <&clkisp JH7110_U0_M31DPHY_TXCLKESC_LAN0>,
|
||||
+ <&clkgen JH7110_ISP_TOP_CLK_ISPCORE_2X>,
|
||||
+ <&clkgen JH7110_ISP_TOP_CLK_ISP_AXI>;
|
||||
+ clock-names = "clk_apb_func", "clk_pclk", "clk_sys_clk",
|
||||
+ "clk_wrapper_clk_c", "clk_dvp_inv", "clk_axiwr",
|
||||
+ "clk_mipi_rx0_pxl", "clk_pixel_clk_if0",
|
||||
+ "clk_pixel_clk_if1", "clk_pixel_clk_if2",
|
||||
+ "clk_pixel_clk_if3", "clk_m31dphy_cfgclk_in",
|
||||
+ "clk_m31dphy_refclk_in", "clk_m31dphy_txclkesc_lan0",
|
||||
+ "clk_ispcore_2x", "clk_isp_axi";
|
||||
+ resets = <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_P>,
|
||||
+ <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_C>,
|
||||
+ <&rstgen RSTN_U0_VIN_N_PCLK>,
|
||||
+ <&rstgen RSTN_U0_VIN_N_SYS_CLK>,
|
||||
+ <&rstgen RSTN_U0_VIN_P_AXIRD>,
|
||||
+ <&rstgen RSTN_U0_VIN_P_AXIWR>,
|
||||
+ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF0>,
|
||||
+ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF1>,
|
||||
+ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF2>,
|
||||
+ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF3>,
|
||||
+ <&rstgen RSTN_U0_M31DPHY_HW>,
|
||||
+ <&rstgen RSTN_U0_M31DPHY_B09_ALWAYS_ON>,
|
||||
+ <&rstgen RSTN_U0_DOM_ISP_TOP_N>,
|
||||
+ <&rstgen RSTN_U0_DOM_ISP_TOP_AXI>;
|
||||
+ reset-names = "rst_wrapper_p", "rst_wrapper_c", "rst_pclk",
|
||||
+ "rst_sys_clk", "rst_axird", "rst_axiwr", "rst_pixel_clk_if0",
|
||||
+ "rst_pixel_clk_if1", "rst_pixel_clk_if2", "rst_pixel_clk_if3",
|
||||
+ "rst_m31dphy_hw", "rst_m31dphy_b09_always_on",
|
||||
+ "rst_isp_top_n", "rst_isp_top_axi";
|
||||
+ starfive,aon-syscon = <&aon_syscon 0x00>;
|
||||
+ power-domains = <&pwrc JH7110_PD_ISP>;
|
||||
+ /* irq nr: vin, isp, isp_csi, isp_scd, isp_csiline */
|
||||
+ interrupts = <92>, <87>, <88>, <89>, <90>;
|
||||
+
|
||||
+ ports {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ port@0 {
|
||||
+ reg = <0>;
|
||||
+ vin_from_sc2235: endpoint {
|
||||
+ remote-endpoint = <&sc2235_to_vin>;
|
||||
+ bus-type = <5>;
|
||||
+ bus-width = <8>;
|
||||
+ data-shift = <2>;
|
||||
+ hsync-active = <1>;
|
||||
+ vsync-active = <0>;
|
||||
+ pclk-sample = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ port@1 {
|
||||
+ reg = <1>;
|
||||
+ vin_from_csi2rx: endpoint {
|
||||
+ remote-endpoint = <&csi2rx_to_vin>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user