mirror of
https://github.com/archr-linux/Arch-R.git
synced 2026-07-12 18:19:42 -07:00
projects: add modifications for ROCKNIX
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
<dtb>
|
||||
<H700 bootmethod="extlinux">
|
||||
<file>sun50i-h700-anbernic-rg35xx-plus</file>
|
||||
<file>sun50i-h700-anbernic-rg35xx-plus-rev6-panel</file>
|
||||
<file>sun50i-h700-anbernic-rg35xx-pro</file>
|
||||
<file>sun50i-h700-anbernic-rg35xx-h</file>
|
||||
<file>sun50i-h700-anbernic-rg35xx-h-rev6-panel</file>
|
||||
<file>sun50i-h700-anbernic-rg35xx-sp</file>
|
||||
<file>sun50i-h700-anbernic-rg35xx-sp-v2-panel</file>
|
||||
<file>sun50i-h700-anbernic-rg35xx-2024</file>
|
||||
<file>sun50i-h700-anbernic-rg35xx-2024-rev6-panel</file>
|
||||
<file>sun50i-h700-anbernic-rg40xx-h</file>
|
||||
<file>sun50i-h700-anbernic-rg40xx-v</file>
|
||||
<file>sun50i-h700-anbernic-rgcubexx</file>
|
||||
<file>sun50i-h700-anbernic-rg28xx</file>
|
||||
<file>sun50i-h700-anbernic-rg34xx</file>
|
||||
<file>sun50i-h700-anbernic-rg34xx-sp</file>
|
||||
</H700>
|
||||
<RK3326>
|
||||
<a bootmethod="bootini">
|
||||
<file>rk3326-anbernic-rg351m</file>
|
||||
<file>rk3326-anbernic-rg351v</file>
|
||||
<file>rk3326-gameconsole-r33s</file>
|
||||
<file>rk3326-gameconsole-r36s</file>
|
||||
<file>rk3326-magicx-xu10</file>
|
||||
<file>rk3326-odroid-go2</file>
|
||||
<file>rk3326-odroid-go2-v11</file>
|
||||
<file>rk3326-odroid-go3</file>
|
||||
<file>rk3326-powkiddy-rgb10</file>
|
||||
<file>rk3326-powkiddy-rgb20s</file>
|
||||
</a>
|
||||
<b bootmethod="bootini">
|
||||
<file>rk3326-powkiddy-rgb10x</file>
|
||||
<file>rk3326-magicx-xu10</file>
|
||||
<file>rk3326-magicx-xu-mini-m</file>
|
||||
<file>rk3326-gameconsole-r36max</file>
|
||||
</b>
|
||||
</RK3326>
|
||||
<RK3399 bootmethod="extlinux">
|
||||
<file>rk3399-anbernic-rg552</file>
|
||||
</RK3399>
|
||||
<RK3566>
|
||||
<Generic bootmethod="extlinux_fdtdir">
|
||||
<file>rk3566-anbernic-rg-arc-d</file>
|
||||
<file>rk3566-anbernic-rg-arc-s</file>
|
||||
<file>rk3566-anbernic-rg353p</file>
|
||||
<file>rk3566-anbernic-rg353ps</file>
|
||||
<file>rk3566-anbernic-rg353v</file>
|
||||
<file>rk3566-anbernic-rg353vs</file>
|
||||
<file>rk3566-anbernic-rg503</file>
|
||||
<file>rk3566-powkiddy-rgb10max3</file>
|
||||
<file>rk3566-powkiddy-rgb20-pro</file>
|
||||
<file>rk3566-powkiddy-rgb20sx</file>
|
||||
<file>rk3566-powkiddy-rgb30</file>
|
||||
<file>rk3566-powkiddy-rk2023</file>
|
||||
</Generic>
|
||||
<Powkiddy_x55 bootmethod="extlinux">
|
||||
<file>rk3566-powkiddy-x55</file>
|
||||
<file>rk3566-powkiddy-x35s</file>
|
||||
</Powkiddy_x55>
|
||||
</RK3566>
|
||||
<RK3588 bootmethod="extlinux">
|
||||
<file>rk3588s-gameforce-ace</file>
|
||||
<file>rk3588-orangepi-5-plus</file>
|
||||
<file>rk3588-orangepi-5-max</file>
|
||||
<file>rk3588-rock-5b</file>
|
||||
<file>rk3588-rock-5b-plus</file>
|
||||
<file>rk3588s-orangepi-5</file>
|
||||
<file>rk3588s-orangepi-5-pro</file>
|
||||
<file>rk3588s-retro-lite-cm5</file>
|
||||
<file>rk3588s-retroled-cm5</file>
|
||||
<file>rk3588s-rock-5a</file>
|
||||
</RK3588>
|
||||
<S922X bootmethod="extlinux_fdtdir">
|
||||
<file>meson-g12b-odroid-go-ultra</file>
|
||||
<file>meson-g12b-powkiddy-rgb10-max-3-pro</file>
|
||||
</S922X>
|
||||
</dtb>
|
||||
@@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2024-present ROCKNIX (https://github.com/ROCKNIX)
|
||||
|
||||
mkdir -p ${RELEASE_DIR}/3rdparty/bootloader
|
||||
cp -a ${INSTALL}/usr/share/bootloader/* ${RELEASE_DIR}/3rdparty/bootloader
|
||||
@@ -0,0 +1,60 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2024-present ROCKNIX (https://rocknix.org)
|
||||
|
||||
PKG_SOC="${DEVICE/RK/rk}"
|
||||
|
||||
# Make idbloader.img
|
||||
case "${DEVICE}" in
|
||||
RK3326)
|
||||
# mkimage does not support packing second level bootloader on rk3326
|
||||
${PKG_BUILD}/tools/mkimage -n px30 -T rksd -d "${PKG_DDR_BIN}" -C bzip2 idbloader.img
|
||||
cat ${PKG_MINILOADER} >> idbloader.img
|
||||
;;
|
||||
RK3399|RK3566|RK3588)
|
||||
[ "${PKG_SOC}" = "rk3566" ] && PKG_SOC="rk3568"
|
||||
${PKG_BUILD}/tools/mkimage -n "${PKG_SOC}" -T rksd -d "${PKG_DDR_BIN}":"${PKG_MINILOADER}" -C bzip2 idbloader.img
|
||||
;;
|
||||
esac
|
||||
|
||||
# Pack uboot.img
|
||||
case "${DEVICE}" in
|
||||
RK3326|RK3399)
|
||||
${PKG_RKBIN}/tools/loaderimage --pack --uboot u-boot-dtb.bin uboot.img 0x00200000
|
||||
;;
|
||||
esac
|
||||
|
||||
# Merge trust.img
|
||||
case "${DEVICE}" in
|
||||
RK3326)
|
||||
cat >trust.ini <<EOF
|
||||
[BL30_OPTION]
|
||||
SEC=0
|
||||
[BL31_OPTION]
|
||||
SEC=1
|
||||
PATH=${PKG_BL31}
|
||||
ADDR=0x00010000
|
||||
[BL32_OPTION]
|
||||
SEC=0
|
||||
[BL33_OPTION]
|
||||
SEC=0
|
||||
[OUTPUT]
|
||||
PATH=trust.img
|
||||
EOF
|
||||
${PKG_RKBIN}/tools/trust_merger --verbose trust.ini
|
||||
;;
|
||||
RK3399)
|
||||
${PKG_RKBIN}/tools/trust_merger --ignore-bl32 --prepath "${PKG_RKBIN}"/ "${PKG_ATF_INI}"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Build a unified uboot.bin image
|
||||
dd if=idbloader.img of=uboot.bin bs=512 seek=0 conv=fsync,notrunc
|
||||
for BOOT_IMAGE in uboot.img u-boot.itb; do
|
||||
if [ -f "$BOOT_IMAGE" ]; then
|
||||
dd if=$BOOT_IMAGE of=uboot.bin bs=512 seek=16320 conv=fsync,notrunc
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ -f "trust.img" ]; then
|
||||
dd if=trust.img of=uboot.bin bs=512 seek=24512 conv=fsync,notrunc
|
||||
fi
|
||||
@@ -0,0 +1,41 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2024-present ROCKNIX (https://github.com/ROCKNIX)
|
||||
|
||||
mkimage_uboot() {
|
||||
if [ -f "${RELEASE_DIR}/3rdparty/bootloader/u-boot-sunxi-with-spl.bin" ]; then
|
||||
echo "image: writing u-boot-sunxi-with-spl.bin to $(basename ${DISK})..."
|
||||
dd if="${RELEASE_DIR}/3rdparty/bootloader/u-boot-sunxi-with-spl.bin" of="${DISK}" bs=1K seek=8 conv=fsync,notrunc >"${SAVE_ERROR}" 2>&1 || show_error
|
||||
fi
|
||||
}
|
||||
|
||||
mkimage_extlinux(){
|
||||
echo "image: set exlinux.conf to FDT /dtb.img..."
|
||||
mkdir -p "${IMG_TMP}/extlinux"
|
||||
cat << EOF > "${IMG_TMP}/extlinux/extlinux.conf"
|
||||
LABEL ${DISTRO}
|
||||
LINUX /${KERNEL_NAME}
|
||||
FDT /dtb.img
|
||||
APPEND boot=LABEL=${DISTRO_BOOTLABEL} disk=LABEL=${DISTRO_DISKLABEL} ${EXTRA_CMDLINE}
|
||||
EOF
|
||||
echo "image: copying exlinux.conf..."
|
||||
mcopy -s -o "${IMG_TMP}/extlinux" ::
|
||||
}
|
||||
|
||||
mkimage_dtb() {
|
||||
if [ -d ${RELEASE_DIR}/3rdparty/bootloader/device_trees ]; then
|
||||
echo "image: copying device trees..."
|
||||
mcopy -s ${RELEASE_DIR}/3rdparty/bootloader/device_trees ::
|
||||
fi
|
||||
if [ -d ${RELEASE_DIR}/3rdparty/bootloader/overlays ]; then
|
||||
echo "image: copying device tree overlays..."
|
||||
mcopy -s ${RELEASE_DIR}/3rdparty/bootloader/overlays ::
|
||||
fi
|
||||
}
|
||||
|
||||
DTBXML="${PROJECT_DIR}/${PROJECT}/bootloader/dtb.xml"
|
||||
readarray -t DTB < <(xmlstarlet sel -t -v "//dtb/${DEVICE}/${SUBDEVICE}/file" ${DTBXML})
|
||||
BOOTMETHOD=$(xmlstarlet sel -t -v "//dtb/${DEVICE}/${SUBDEVICE}/@bootmethod" ${DTBXML})
|
||||
|
||||
mkimage_dtb
|
||||
mkimage_${BOOTMETHOD}
|
||||
mkimage_uboot
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2024-present ROCKNIX (https://github.com/ROCKNIX)
|
||||
|
||||
[ -z "$SYSTEM_ROOT" ] && SYSTEM_ROOT=""
|
||||
[ -z "$BOOT_ROOT" ] && BOOT_ROOT="/flash"
|
||||
[ -z "$BOOT_PART" ] && BOOT_PART=$(df "$BOOT_ROOT" | tail -1 | awk {' print $1 '})
|
||||
|
||||
# identify the boot device
|
||||
if [ -z "$BOOT_DISK" ]; then
|
||||
case $BOOT_PART in
|
||||
/dev/mmcblk*)
|
||||
BOOT_DISK=$(echo $BOOT_PART | sed -e "s,p[0-9]*,,g")
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# mount $BOOT_ROOT rw
|
||||
mount -o remount,rw $BOOT_ROOT
|
||||
|
||||
echo "Updating device trees..."
|
||||
cp -f $SYSTEM_ROOT/usr/share/bootloader/device_trees/* $BOOT_ROOT/device_trees
|
||||
|
||||
DT_ID=$(cat /proc/device-tree/rocknix-dt-id)
|
||||
|
||||
# TODO remove - workaround for RG34XXSP incorrect DT bug
|
||||
[[ ${DT_ID} = "sun50i-h700-anbernic-rg35xx-plus" ]] &&
|
||||
[[ $(cat /sys/class/graphics/fb0/virtual_size) = "720,480" ]] &&
|
||||
DT_ID="sun50i-h700-anbernic-rg34xx-sp"
|
||||
|
||||
UPDATE_DTB_SOURCE="$BOOT_ROOT/device_trees/$DT_ID.dtb"
|
||||
if [ -f "$UPDATE_DTB_SOURCE" ]; then
|
||||
echo "Updating dtb.img from $(basename $UPDATE_DTB_SOURCE)..."
|
||||
cp -f "$UPDATE_DTB_SOURCE" "$BOOT_ROOT/dtb.img"
|
||||
fi
|
||||
|
||||
# update bootloader
|
||||
if [ -f $SYSTEM_ROOT/usr/share/bootloader/u-boot-sunxi-with-spl.bin ]; then
|
||||
echo "Updating u-boot on: $BOOT_DISK..."
|
||||
dd if=$SYSTEM_ROOT/usr/share/bootloader/u-boot-sunxi-with-spl.bin of=$BOOT_DISK bs=1K seek=8 conv=fsync,notrunc &>/dev/null
|
||||
fi
|
||||
|
||||
# mount $BOOT_ROOT ro
|
||||
sync
|
||||
mount -o remount,ro $BOOT_ROOT
|
||||
|
||||
echo "UPDATE" > /storage/.boot.hint
|
||||
@@ -0,0 +1,16 @@
|
||||
# RTW_88
|
||||
rtw88/rtw8821c_fw.bin
|
||||
|
||||
# RTL_8821CS
|
||||
rtl_bt/rtl8821cs_config.bin
|
||||
rtl_bt/rtl8821cs_fw.bin
|
||||
|
||||
# Panels
|
||||
panels/anbernic,rg28xx-panel.panel
|
||||
panels/anbernic,rgcubexx-panel.panel
|
||||
panels/anbernic,rg40xx-panel.panel
|
||||
panels/anbernic,rg35xx-plus-rev6-panel.panel
|
||||
panels/anbernic,rg35xx-plus-panel.panel
|
||||
panels/anbernic,rg35xx-sp-v2-panel.panel
|
||||
panels/anbernic,rg34xx-panel.panel
|
||||
panels/anbernic,rg34xx-sp-panel.panel
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,78 @@
|
||||
################################################################################
|
||||
# setup device defaults
|
||||
################################################################################
|
||||
|
||||
# The TARGET_CPU variable controls which processor should be targeted for
|
||||
# generated code.
|
||||
case ${TARGET_ARCH} in
|
||||
aarch64)
|
||||
TARGET_KERNEL_ARCH="arm64"
|
||||
TARGET_KERNEL_PATCH_ARCH="aarch64"
|
||||
TARGET_CPU="cortex-a53"
|
||||
TARGET_ARCH_FLAGS="+crc+fp+simd"
|
||||
TARGET_FEATURES="64bit"
|
||||
;;
|
||||
arm)
|
||||
TARGET_KERNEL_ARCH="arm64"
|
||||
TARGET_KERNEL_PATCH_ARCH="aarch64"
|
||||
TARGET_FLOAT="hard"
|
||||
TARGET_CPU="cortex-a53"
|
||||
TARGET_ARCH_FLAGS="+crc"
|
||||
TARGET_FPU="crypto-neon-fp-armv8"
|
||||
TARGET_FEATURES="32bit"
|
||||
;;
|
||||
esac
|
||||
|
||||
DEVICE_NAME="H700"
|
||||
PARTITION_TABLE="msdos"
|
||||
HW_CPU="Allwinner H700"
|
||||
|
||||
# Kernel target
|
||||
KERNEL_TARGET="Image"
|
||||
|
||||
# Kernel extra targets to build
|
||||
KERNEL_MAKE_EXTRACMD=" $(xmlstarlet sel -t -m "//dtb/${DEVICE}//file" -o "allwinner/" -v "." -o ".dtb " "${PROJECT_DIR}/${PROJECT}/bootloader/dtb.xml")"
|
||||
|
||||
# Kernel cmdline
|
||||
EXTRA_CMDLINE="quiet console=ttyS0,115200 console=tty0 systemd.debug_shell=ttyS0"
|
||||
|
||||
# Bootloader to use (syslinux / u-boot)
|
||||
BOOTLOADER="u-boot"
|
||||
|
||||
# U-Boot firmware package(s) to use
|
||||
UBOOT_FIRMWARE+=" atf"
|
||||
ATF_PLATFORM="sun50i_h616"
|
||||
ATF_BL31_BINARY="bl31.bin"
|
||||
|
||||
# Mali GPU family
|
||||
MALI_FAMILY="g31"
|
||||
GRAPHIC_DRIVERS="panfrost"
|
||||
|
||||
# For maximum cross compatbility
|
||||
PREFER_GLES="yes"
|
||||
|
||||
# Displayserver to use (wl / no)
|
||||
DISPLAYSERVER="wl"
|
||||
|
||||
# Windowmanager to use (weston / swaywm-env / no)
|
||||
WINDOWMANAGER="swaywm-env"
|
||||
|
||||
# Additional drivers to install:
|
||||
# for a list of additional drivers see packages/linux-drivers
|
||||
# Space separated list is supported,
|
||||
# e.g. ADDITIONAL_DRIVERS="DRIVER1 DRIVER2"
|
||||
ADDITIONAL_DRIVERS=""
|
||||
|
||||
# Additional Firmware to use ( )
|
||||
# Space separated list is supported,
|
||||
# e.g. FIRMWARE=""
|
||||
FIRMWARE=""
|
||||
|
||||
# Additional packages to install
|
||||
ADDITIONAL_PACKAGES=""
|
||||
|
||||
# Debug tty path
|
||||
DEBUG_TTY="/dev/ttyS0"
|
||||
|
||||
# ROCKNIX Subdevices
|
||||
SUBDEVICES=$(xmlstarlet sel -t -m "//dtb/${DEVICE}/*[@bootmethod]" -v "name()" -n "${PROJECT_DIR}/${PROJECT}/bootloader/dtb.xml")
|
||||
@@ -0,0 +1,42 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2024-present ROCKNIX (https://github.com/ROCKNIX)
|
||||
|
||||
PKG_NAME="u-boot"
|
||||
PKG_VERSION="v2025.07-rc3"
|
||||
PKG_LICENSE="GPL"
|
||||
PKG_SITE="https://www.denx.de/wiki/U-Boot"
|
||||
PKG_URL="https://github.com/u-boot/u-boot/archive/${PKG_VERSION}.tar.gz"
|
||||
PKG_DEPENDS_TARGET="toolchain Python3 swig:host pyelftools:host"
|
||||
PKG_LONGDESC="Das U-Boot is a cross-platform bootloader for embedded systems."
|
||||
PKG_TOOLCHAIN="manual"
|
||||
|
||||
PKG_NEED_UNPACK="${PROJECT_DIR}/${PROJECT}/bootloader ${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/bootloader"
|
||||
PKG_NEED_UNPACK+=" ${PROJECT_DIR}/${PROJECT}/options ${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/options"
|
||||
|
||||
if [ -n "${UBOOT_FIRMWARE}" ]; then
|
||||
PKG_DEPENDS_TARGET+=" ${UBOOT_FIRMWARE}"
|
||||
PKG_DEPENDS_UNPACK+=" ${UBOOT_FIRMWARE}"
|
||||
fi
|
||||
|
||||
configure_package() {
|
||||
PKG_UBOOT_CONFIG="anbernic_rg35xx_h700_defconfig"
|
||||
PKG_BL31="$(get_build_dir atf)/build/sun50i_h616/release/bl31.bin"
|
||||
}
|
||||
|
||||
make_target() {
|
||||
[ "${BUILD_WITH_DEBUG}" = "yes" ] && PKG_DEBUG=1 || PKG_DEBUG=0
|
||||
setup_pkg_config_host
|
||||
|
||||
DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm make mrproper
|
||||
DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm make ${PKG_UBOOT_CONFIG}
|
||||
DEBUG=${PKG_DEBUG} CROSS_COMPILE="${TARGET_KERNEL_PREFIX}" LDFLAGS="" ARCH=arm _python_sysroot="${TOOLCHAIN}" _python_prefix=/ _python_exec_prefix=/ make BL31="${PKG_BL31}" HOSTCC="${HOST_CC}" HOSTCFLAGS="-I${TOOLCHAIN}/include" HOSTLDFLAGS="${HOST_LDFLAGS}" CONFIG_MKIMAGE_DTC_PATH="scripts/dtc/dtc"
|
||||
}
|
||||
|
||||
makeinstall_target() {
|
||||
mkdir -p $INSTALL/usr/share/bootloader
|
||||
|
||||
# Always install the update script
|
||||
find_file_path bootloader/update.sh && cp -av ${FOUND_PATH} ${INSTALL}/usr/share/bootloader
|
||||
|
||||
cp -av u-boot-sunxi-with-spl.bin $INSTALL/usr/share/bootloader
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
574987574987--- u-boot.orig/configs/anbernic_rg35xx_h700_defconfig 2024-10-29 17:03:21.768276666 +0100
|
||||
+++ u-boot/configs/anbernic_rg35xx_h700_defconfig 2024-10-29 17:17:21.719469834 +0100
|
||||
@@ -25,3 +25,10 @@ CONFIG_REGULATOR_AXP=y
|
||||
CONFIG_AXP717_POWER=y
|
||||
CONFIG_AXP_DCDC2_VOLT=940
|
||||
CONFIG_AXP_DCDC3_VOLT=1100
|
||||
+CONFIG_EFI_LOADER=n
|
||||
+CONFIG_BOOTDELAY=0
|
||||
+CONFIG_LED_STATUS=y
|
||||
+CONFIG_LED_STATUS_GPIO=y
|
||||
+CONFIG_LED_STATUS0=y
|
||||
+CONFIG_LED_STATUS_BIT=267
|
||||
+CONFIG_LED_STATUS_STATE=2
|
||||
\ No newline at end of file
|
||||
+1246
File diff suppressed because it is too large
Load Diff
+656
File diff suppressed because it is too large
Load Diff
+49
@@ -0,0 +1,49 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH v3 4/5] arm64: dts: allwinner: h700: Add hp-det-gpios for
|
||||
Anbernic RG35XX
|
||||
From: Chris Morgan <macromorgan@hotmail.com>
|
||||
Date: Sat, 15 Feb 2025 11:02:26 +1300
|
||||
Message-Id: <20250214220247.10810-5-ryan@testtoast.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Add support for headphone insertion detection via GPIO for the
|
||||
RG35XX series, and add the corresponding routing to the codec node.
|
||||
|
||||
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
|
||||
Signed-off-by: Ryan Walklin <ryan@testtoast.com>
|
||||
Tested-by: Philippe Simons <simons.philippe@gmail.com>
|
||||
|
||||
--
|
||||
Changelog v1..v2:
|
||||
- Remove vendor prefix from GPIO description.
|
||||
- Whitespace fix
|
||||
|
||||
Changelog v2..v3:
|
||||
- Add Tested-by tag
|
||||
|
||||
---
|
||||
.../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
|
||||
index a231abf1684ad..b482fdf1fdba8 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
|
||||
@@ -178,8 +178,11 @@ reg_vcc5v: regulator-vcc5v { /* USB-C power input */
|
||||
};
|
||||
|
||||
&codec {
|
||||
- allwinner,audio-routing = "Line Out", "LINEOUT";
|
||||
+ /* Both speakers and headphone jack connected to 74HC4052D analog mux*/
|
||||
+ allwinner,audio-routing = "Speaker", "LINEOUT",
|
||||
+ "Headphone", "LINEOUT";
|
||||
allwinner,pa-gpios = <&pio 8 5 GPIO_ACTIVE_HIGH>; // PI5
|
||||
+ hp-det-gpios = <&pio 8 3 GPIO_ACTIVE_HIGH>; // PI3
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
||||
+599
File diff suppressed because it is too large
Load Diff
+260
@@ -0,0 +1,260 @@
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH v2 1/3] drm/panfrost: Add PM runtime flag
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
Date: Thu, 03 Apr 2025 07:52:08 +0200
|
||||
Message-Id: <20250403055210.54486-2-simons.philippe@gmail.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
When the GPU is the only device attached to a single power domain,
|
||||
core genpd disable and enable it when gpu enter and leave runtime suspend.
|
||||
|
||||
Some power-domain requires a sequence before disabled,
|
||||
and the reverse when enabled.
|
||||
|
||||
Add GPU_PM_RT flag, and implement in
|
||||
panfrost_device_runtime_suspend/resume.
|
||||
|
||||
Reviewed-by: Steven Price <steven.price@arm.com>
|
||||
Signed-off-by: Philippe Simons <simons.philippe@gmail.com>
|
||||
---
|
||||
drivers/gpu/drm/panfrost/panfrost_device.c | 33 ++++++++++++++++++++++
|
||||
drivers/gpu/drm/panfrost/panfrost_device.h | 3 ++
|
||||
2 files changed, 36 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
|
||||
index a45e4addcc19..93d48e97ce10 100644
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
|
||||
@@ -406,11 +406,36 @@ void panfrost_device_reset(struct panfrost_device *pfdev)
|
||||
static int panfrost_device_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct panfrost_device *pfdev = dev_get_drvdata(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) {
|
||||
+ ret = reset_control_deassert(pfdev->rstc);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_enable(pfdev->clock);
|
||||
+ if (ret)
|
||||
+ goto err_clk;
|
||||
+
|
||||
+ if (pfdev->bus_clock) {
|
||||
+ ret = clk_enable(pfdev->bus_clock);
|
||||
+ if (ret)
|
||||
+ goto err_bus_clk;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
panfrost_device_reset(pfdev);
|
||||
panfrost_devfreq_resume(pfdev);
|
||||
|
||||
return 0;
|
||||
+
|
||||
+err_bus_clk:
|
||||
+ if (pfdev->comp->pm_features & BIT(GPU_PM_RT))
|
||||
+ clk_disable(pfdev->clock);
|
||||
+err_clk:
|
||||
+ if (pfdev->comp->pm_features & BIT(GPU_PM_RT))
|
||||
+ reset_control_assert(pfdev->rstc);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int panfrost_device_runtime_suspend(struct device *dev)
|
||||
@@ -426,6 +451,14 @@ static int panfrost_device_runtime_suspend(struct device *dev)
|
||||
panfrost_gpu_suspend_irq(pfdev);
|
||||
panfrost_gpu_power_off(pfdev);
|
||||
|
||||
+ if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) {
|
||||
+ if (pfdev->bus_clock)
|
||||
+ clk_disable(pfdev->bus_clock);
|
||||
+
|
||||
+ clk_disable(pfdev->clock);
|
||||
+ reset_control_assert(pfdev->rstc);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h
|
||||
index cffcb0ac7c11..861555ceea65 100644
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
|
||||
@@ -36,10 +36,13 @@ enum panfrost_drv_comp_bits {
|
||||
* enum panfrost_gpu_pm - Supported kernel power management features
|
||||
* @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend
|
||||
* @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend
|
||||
+ * @GPU_PM_RT: Allow disabling clocks and asserting the reset control during
|
||||
+ * system runtime suspend
|
||||
*/
|
||||
enum panfrost_gpu_pm {
|
||||
GPU_PM_CLK_DIS,
|
||||
GPU_PM_VREG_OFF,
|
||||
+ GPU_PM_RT
|
||||
};
|
||||
|
||||
struct panfrost_features {
|
||||
--
|
||||
2.49.0
|
||||
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH v2 2/3] drm/panfrost: add h616 compatible string
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
Date: Thu, 03 Apr 2025 07:52:09 +0200
|
||||
Message-Id: <20250403055210.54486-3-simons.philippe@gmail.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Tie the Allwinner compatible string to the GPU_PM_RT feature bits that will
|
||||
toggle the clocks and the reset line whenever the power domain is changing
|
||||
state.
|
||||
|
||||
Signed-off-by: Philippe Simons <simons.philippe@gmail.com>
|
||||
---
|
||||
drivers/gpu/drm/panfrost/panfrost_drv.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
|
||||
index 0f3935556ac7..9470c04c5487 100644
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
|
||||
@@ -776,6 +776,13 @@ static const struct panfrost_compatible default_data = {
|
||||
.pm_domain_names = NULL,
|
||||
};
|
||||
|
||||
+static const struct panfrost_compatible allwinner_h616_data = {
|
||||
+ .num_supplies = ARRAY_SIZE(default_supplies) - 1,
|
||||
+ .supply_names = default_supplies,
|
||||
+ .num_pm_domains = 1,
|
||||
+ .pm_features = BIT(GPU_PM_RT),
|
||||
+};
|
||||
+
|
||||
static const struct panfrost_compatible amlogic_data = {
|
||||
.num_supplies = ARRAY_SIZE(default_supplies) - 1,
|
||||
.supply_names = default_supplies,
|
||||
@@ -859,6 +866,7 @@ static const struct of_device_id dt_match[] = {
|
||||
{ .compatible = "mediatek,mt8186-mali", .data = &mediatek_mt8186_data },
|
||||
{ .compatible = "mediatek,mt8188-mali", .data = &mediatek_mt8188_data },
|
||||
{ .compatible = "mediatek,mt8192-mali", .data = &mediatek_mt8192_data },
|
||||
+ { .compatible = "allwinner,sun50i-h616-mali", .data = &allwinner_h616_data },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dt_match);
|
||||
--
|
||||
2.49.0
|
||||
|
||||
From git@z Thu Jan 1 00:00:00 1970
|
||||
Subject: [PATCH v2 3/3] drm/panfrost: reorder pd/clk/rst sequence
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
Date: Thu, 03 Apr 2025 07:52:10 +0200
|
||||
Message-Id: <20250403055210.54486-4-simons.philippe@gmail.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
According to Mali manuals, the powerup sequence should be
|
||||
enable pd, asserting the reset then enabling the clock and
|
||||
the reverse for powerdown.
|
||||
|
||||
Tested-by: John Williams <porschemad911@gmail.com>
|
||||
Signed-off-by: Philippe Simons <simons.philippe@gmail.com>
|
||||
---
|
||||
drivers/gpu/drm/panfrost/panfrost_device.c | 38 +++++++++++-----------
|
||||
1 file changed, 19 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
|
||||
index 93d48e97ce10..5d35076b2e6d 100644
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
|
||||
@@ -209,10 +209,20 @@ int panfrost_device_init(struct panfrost_device *pfdev)
|
||||
|
||||
spin_lock_init(&pfdev->cycle_counter.lock);
|
||||
|
||||
+ err = panfrost_pm_domain_init(pfdev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = panfrost_reset_init(pfdev);
|
||||
+ if (err) {
|
||||
+ dev_err(pfdev->dev, "reset init failed %d\n", err);
|
||||
+ goto out_pm_domain;
|
||||
+ }
|
||||
+
|
||||
err = panfrost_clk_init(pfdev);
|
||||
if (err) {
|
||||
dev_err(pfdev->dev, "clk init failed %d\n", err);
|
||||
- return err;
|
||||
+ goto out_reset;
|
||||
}
|
||||
|
||||
err = panfrost_devfreq_init(pfdev);
|
||||
@@ -229,25 +239,15 @@ int panfrost_device_init(struct panfrost_device *pfdev)
|
||||
goto out_devfreq;
|
||||
}
|
||||
|
||||
- err = panfrost_reset_init(pfdev);
|
||||
- if (err) {
|
||||
- dev_err(pfdev->dev, "reset init failed %d\n", err);
|
||||
- goto out_regulator;
|
||||
- }
|
||||
-
|
||||
- err = panfrost_pm_domain_init(pfdev);
|
||||
- if (err)
|
||||
- goto out_reset;
|
||||
-
|
||||
pfdev->iomem = devm_platform_ioremap_resource(pfdev->pdev, 0);
|
||||
if (IS_ERR(pfdev->iomem)) {
|
||||
err = PTR_ERR(pfdev->iomem);
|
||||
- goto out_pm_domain;
|
||||
+ goto out_regulator;
|
||||
}
|
||||
|
||||
err = panfrost_gpu_init(pfdev);
|
||||
if (err)
|
||||
- goto out_pm_domain;
|
||||
+ goto out_regulator;
|
||||
|
||||
err = panfrost_mmu_init(pfdev);
|
||||
if (err)
|
||||
@@ -268,16 +268,16 @@ int panfrost_device_init(struct panfrost_device *pfdev)
|
||||
panfrost_mmu_fini(pfdev);
|
||||
out_gpu:
|
||||
panfrost_gpu_fini(pfdev);
|
||||
-out_pm_domain:
|
||||
- panfrost_pm_domain_fini(pfdev);
|
||||
-out_reset:
|
||||
- panfrost_reset_fini(pfdev);
|
||||
out_regulator:
|
||||
panfrost_regulator_fini(pfdev);
|
||||
out_devfreq:
|
||||
panfrost_devfreq_fini(pfdev);
|
||||
out_clk:
|
||||
panfrost_clk_fini(pfdev);
|
||||
+out_reset:
|
||||
+ panfrost_reset_fini(pfdev);
|
||||
+out_pm_domain:
|
||||
+ panfrost_pm_domain_fini(pfdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -287,11 +287,11 @@ void panfrost_device_fini(struct panfrost_device *pfdev)
|
||||
panfrost_job_fini(pfdev);
|
||||
panfrost_mmu_fini(pfdev);
|
||||
panfrost_gpu_fini(pfdev);
|
||||
- panfrost_pm_domain_fini(pfdev);
|
||||
- panfrost_reset_fini(pfdev);
|
||||
panfrost_devfreq_fini(pfdev);
|
||||
panfrost_regulator_fini(pfdev);
|
||||
panfrost_clk_fini(pfdev);
|
||||
+ panfrost_reset_fini(pfdev);
|
||||
+ panfrost_pm_domain_fini(pfdev);
|
||||
}
|
||||
|
||||
#define PANFROST_EXCEPTION(id) \
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
From c2907f97fc1e40f41093f96e252b826d2e0e702b Mon Sep 17 00:00:00 2001
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
Date: Tue, 22 Apr 2025 12:39:49 +0200
|
||||
Subject: [PATCH] rg35xx add gpu opp table
|
||||
|
||||
---
|
||||
.../sun50i-h700-anbernic-rg35xx-2024.dts | 34 +++++++++++++++++--
|
||||
1 file changed, 32 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
|
||||
index f76391d8027d..1433345567ae 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
|
||||
@@ -224,6 +224,35 @@ panel_in_rgb: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ gpu_opp_table: opp-table-1 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+
|
||||
+ opp-420000000 {
|
||||
+ opp-hz = /bits/ 64 <420000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ };
|
||||
+ opp-456000000 {
|
||||
+ opp-hz = /bits/ 64 <456000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ };
|
||||
+ opp-504000000 {
|
||||
+ opp-hz = /bits/ 64 <504000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ };
|
||||
+ opp-552000000 {
|
||||
+ opp-hz = /bits/ 64 <552000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ };
|
||||
+ opp-600000000 {
|
||||
+ opp-hz = /bits/ 64 <600000000>;
|
||||
+ opp-microvolt = <900000>;
|
||||
+ };
|
||||
+ opp-648000000 {
|
||||
+ opp-hz = /bits/ 64 <648000000>;
|
||||
+ opp-microvolt = <960000>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&codec {
|
||||
@@ -249,6 +278,7 @@ &ehci0 {
|
||||
|
||||
&gpu {
|
||||
mali-supply = <®_dcdc2>;
|
||||
+ operating-points-v2 = <&gpu_opp_table>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -311,8 +341,8 @@ reg_dcdc1: dcdc1 {
|
||||
|
||||
reg_dcdc2: dcdc2 {
|
||||
regulator-always-on;
|
||||
- regulator-min-microvolt = <940000>;
|
||||
- regulator-max-microvolt = <940000>;
|
||||
+ regulator-min-microvolt = <900000>;
|
||||
+ regulator-max-microvolt = <960000>;
|
||||
regulator-name = "vdd-gpu-sys";
|
||||
};
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -0,0 +1,495 @@
|
||||
From 83753f7dd56bbb36af578f0152d66cbe46272109 Mon Sep 17 00:00:00 2001
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
Date: Thu, 23 Jan 2025 23:39:15 +0100
|
||||
Subject: [PATCH 7/9] sun20i: add pwm driver
|
||||
|
||||
---
|
||||
arch/arm64/configs/defconfig | 1 +
|
||||
drivers/pwm/Kconfig | 10 +
|
||||
drivers/pwm/Makefile | 1 +
|
||||
drivers/pwm/pwm-sun20i.c | 428 +++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 440 insertions(+)
|
||||
create mode 100644 drivers/pwm/pwm-sun20i.c
|
||||
|
||||
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
|
||||
index c62831e61..7d631556b 100644
|
||||
--- a/arch/arm64/configs/defconfig
|
||||
+++ b/arch/arm64/configs/defconfig
|
||||
@@ -1517,6 +1517,7 @@ CONFIG_PWM_RZ_MTU3=m
|
||||
CONFIG_PWM_SAMSUNG=y
|
||||
CONFIG_PWM_SL28CPLD=m
|
||||
CONFIG_PWM_SUN4I=m
|
||||
+CONFIG_PWM_SUN20I=m
|
||||
CONFIG_PWM_TEGRA=m
|
||||
CONFIG_PWM_TIECAP=m
|
||||
CONFIG_PWM_TIEHRPWM=m
|
||||
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
|
||||
index 0915c1e7d..a4a7eb286 100644
|
||||
--- a/drivers/pwm/Kconfig
|
||||
+++ b/drivers/pwm/Kconfig
|
||||
@@ -652,6 +652,16 @@ config PWM_SUN4I
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called pwm-sun4i.
|
||||
|
||||
+config PWM_SUN20I
|
||||
+ tristate "Allwinner D1/H616 PWM support"
|
||||
+ depends on ARCH_SUNXI || COMPILE_TEST
|
||||
+ depends on HAS_IOMEM && COMMON_CLK
|
||||
+ help
|
||||
+ Generic PWM framework driver for Newer Allwinner SoCs.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called pwm-sun20i.
|
||||
+
|
||||
config PWM_SUNPLUS
|
||||
tristate "Sunplus PWM support"
|
||||
depends on ARCH_SUNPLUS || COMPILE_TEST
|
||||
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
|
||||
index 9081e0c0e..85ad1fe0d 100644
|
||||
--- a/drivers/pwm/Makefile
|
||||
+++ b/drivers/pwm/Makefile
|
||||
@@ -60,6 +60,7 @@ obj-$(CONFIG_PWM_STM32) += pwm-stm32.o
|
||||
obj-$(CONFIG_PWM_STM32_LP) += pwm-stm32-lp.o
|
||||
obj-$(CONFIG_PWM_STMPE) += pwm-stmpe.o
|
||||
obj-$(CONFIG_PWM_SUN4I) += pwm-sun4i.o
|
||||
+obj-$(CONFIG_PWM_SUN20I) += pwm-sun20i.o
|
||||
obj-$(CONFIG_PWM_SUNPLUS) += pwm-sunplus.o
|
||||
obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
|
||||
obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
|
||||
diff --git a/drivers/pwm/pwm-sun20i.c b/drivers/pwm/pwm-sun20i.c
|
||||
new file mode 100644
|
||||
index 000000000..7262a99ab
|
||||
--- /dev/null
|
||||
+++ b/drivers/pwm/pwm-sun20i.c
|
||||
@@ -0,0 +1,428 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Driver for Allwinner's new PWM Controller (such as D1 / H616 / T5 series)
|
||||
+ *
|
||||
+ * Copyright (C) 2024 Hironori KIKUCHI <kikuchan98@gmail.com>
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/gcd.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/jiffies.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pwm.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/time.h>
|
||||
+
|
||||
+// SoC specific offsets
|
||||
+#define SUN20I_REG_OFFSET_PER_SUN20I (0x0080)
|
||||
+#define SUN20I_REG_OFFSET_PCR_SUN20I (0x0100 + 0x0000)
|
||||
+#define SUN20I_REG_OFFSET_PPR_SUN20I (0x0100 + 0x0004)
|
||||
+#define SUN20I_REG_OFFSET_PER_SUN50I (0x0040)
|
||||
+#define SUN20I_REG_OFFSET_PCR_SUN50I (0x0060 + 0x0000)
|
||||
+#define SUN20I_REG_OFFSET_PPR_SUN50I (0x0060 + 0x0004)
|
||||
+
|
||||
+// Register offsets
|
||||
+#define SUN20I_REG_OFFSET_PCCR(chip, ch) (0x0020 + 0x04 * ((ch) >> 1))
|
||||
+#define SUN20I_REG_OFFSET_PCGR(chip, ch) (0x0040)
|
||||
+#define SUN20I_REG_OFFSET_PER(chip, ch) ((chip)->data->reg_per)
|
||||
+#define SUN20I_REG_OFFSET_PCR(chip, ch) ((chip)->data->reg_pcr + 0x20 * (ch))
|
||||
+#define SUN20I_REG_OFFSET_PPR(chip, ch) ((chip)->data->reg_ppr + 0x20 * (ch))
|
||||
+
|
||||
+// PCCR: PWMxx Clock Configuration Register
|
||||
+#define SUN20I_REG_PCCR_CLK_SRC_MASK GENMASK(8, 7)
|
||||
+#define SUN20I_REG_PCCR_CLK_DIV_M_MASK GENMASK(3, 0)
|
||||
+#define SUN20I_REG_PCCR_CLK_BYPASS(ch) BIT(5 + ((ch) & 1))
|
||||
+#define SUN20I_REG_PCCR_CLK_GATING(ch) BIT(4)
|
||||
+
|
||||
+// PCGR: PWM Clock Gating Register
|
||||
+#define SUN20I_REG_PCGR_CLK_BYPASS(ch) BIT(16 + (ch))
|
||||
+#define SUN20I_REG_PCGR_CLK_GATING(ch) BIT(ch)
|
||||
+
|
||||
+// PER: PWM Enable Regsiter
|
||||
+#define SUN20I_REG_PER_ENABLE(ch) BIT(ch)
|
||||
+
|
||||
+// PCR: PWM Control Register
|
||||
+#define SUN20I_REG_PCR_ACT_STA BIT(8)
|
||||
+#define SUN20I_REG_PCR_PRESCAL_K_MASK GENMASK(7, 0)
|
||||
+
|
||||
+// PPR: PWM Period Register
|
||||
+#define SUN20I_REG_PPR_ENTIRE_CYCLE_MASK GENMASK(31, 16)
|
||||
+#define SUN20I_REG_PPR_ACT_CYCLE_MASK GENMASK(15, 0)
|
||||
+
|
||||
+// Constants
|
||||
+#define SUN20I_PWM_CHANNELS_MAX (16)
|
||||
+#define SUN20I_PWM_CLOCK_SRC_HOSC (0)
|
||||
+#define SUN20I_PWM_CLOCK_SRC_APB (1)
|
||||
+#define SUN20I_PWM_DIV_M_SHIFT_MAX (8)
|
||||
+#define SUN20I_PWM_PRESCALE_K_MAX (256)
|
||||
+#define SUN20I_PWM_ENT_CYCLE_MAX (0xffffULL)
|
||||
+
|
||||
+// Configuration
|
||||
+#define SUN20I_PWM_DIV_M_SHIFT_DEFAULT (0)
|
||||
+#define SUN20I_PWM_CLOCK_SRC_DEFAULT SUN20I_PWM_CLOCK_SRC_HOSC
|
||||
+
|
||||
+struct sun20i_pwm_data {
|
||||
+ unsigned long reg_per;
|
||||
+ unsigned long reg_pcr;
|
||||
+ unsigned long reg_ppr;
|
||||
+ bool has_pcgr;
|
||||
+};
|
||||
+
|
||||
+struct sun20i_pwm_chip {
|
||||
+ struct clk *clk_bus;
|
||||
+ struct clk *clk_hosc;
|
||||
+ struct clk *clk_apb;
|
||||
+ struct reset_control *rst;
|
||||
+ void __iomem *base;
|
||||
+ spinlock_t ctrl_lock;
|
||||
+ const struct sun20i_pwm_data *data;
|
||||
+
|
||||
+ unsigned int clk_src[(SUN20I_PWM_CHANNELS_MAX + 1) / 2];
|
||||
+ unsigned int div_m_shift[(SUN20I_PWM_CHANNELS_MAX + 1) / 2];
|
||||
+};
|
||||
+
|
||||
+static inline struct sun20i_pwm_chip *to_sun20i_pwm_chip(struct pwm_chip *chip)
|
||||
+{
|
||||
+ return pwmchip_get_drvdata(chip);
|
||||
+}
|
||||
+
|
||||
+static inline u32 sun20i_pwm_readl(struct sun20i_pwm_chip *sun20i_chip, unsigned long offset)
|
||||
+{
|
||||
+ return readl(sun20i_chip->base + offset);
|
||||
+}
|
||||
+
|
||||
+static inline void sun20i_pwm_writel(struct sun20i_pwm_chip *sun20i_chip, u32 val, unsigned long offset)
|
||||
+{
|
||||
+ writel(val, sun20i_chip->base + offset);
|
||||
+}
|
||||
+
|
||||
+static inline bool sun20i_pwm_is_channel_enabled(struct sun20i_pwm_chip *sun20i_chip, int hwpwm)
|
||||
+{
|
||||
+ u32 val;
|
||||
+ val = sun20i_pwm_readl(sun20i_chip, SUN20I_REG_OFFSET_PER(sun20i_chip, hwpwm));
|
||||
+ return val & SUN20I_REG_PER_ENABLE(hwpwm) ? true : false;
|
||||
+}
|
||||
+
|
||||
+static inline void sun20i_pwm_enable_channel(struct sun20i_pwm_chip *sun20i_chip, struct pwm_device *pwm, bool enable)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ // PWM Clock Configuration Register
|
||||
+ u32 pccr = sun20i_pwm_readl(sun20i_chip, SUN20I_REG_OFFSET_PCCR(sun20i_chip, pwm->hwpwm));
|
||||
+ if (enable) {
|
||||
+ unsigned int idx = pwm->hwpwm / 2;
|
||||
+ // Set clock source
|
||||
+ pccr &= ~SUN20I_REG_PCCR_CLK_SRC_MASK;
|
||||
+ pccr |= FIELD_PREP(SUN20I_REG_PCCR_CLK_SRC_MASK, sun20i_chip->clk_src[idx]);
|
||||
+
|
||||
+ // Set DIV_M shift
|
||||
+ pccr &= ~SUN20I_REG_PCCR_CLK_DIV_M_MASK;
|
||||
+ pccr |= FIELD_PREP(SUN20I_REG_PCCR_CLK_DIV_M_MASK, sun20i_chip->div_m_shift[idx]);
|
||||
+ }
|
||||
+
|
||||
+ if (sun20i_chip->data->has_pcgr) {
|
||||
+ // PWM Clock Gating Register
|
||||
+ val = sun20i_pwm_readl(sun20i_chip, SUN20I_REG_OFFSET_PCGR(sun20i_chip, pwm->hwpwm));
|
||||
+ if (enable) {
|
||||
+ val &= ~SUN20I_REG_PCGR_CLK_BYPASS(pwm->hwpwm);
|
||||
+ val |= SUN20I_REG_PCGR_CLK_GATING(pwm->hwpwm);
|
||||
+ } else {
|
||||
+ val &= ~SUN20I_REG_PCGR_CLK_GATING(pwm->hwpwm);
|
||||
+ }
|
||||
+ sun20i_pwm_writel(sun20i_chip, val, SUN20I_REG_OFFSET_PCGR(sun20i_chip, pwm->hwpwm));
|
||||
+ } else {
|
||||
+ // CLK_BYPASS and CLK_GATING are in PCCR otherwise
|
||||
+ if (enable) {
|
||||
+ pccr &= ~SUN20I_REG_PCCR_CLK_BYPASS(pwm->hwpwm);
|
||||
+ pccr |= SUN20I_REG_PCCR_CLK_GATING(pwm->hwpwm);
|
||||
+ } else if (!sun20i_pwm_is_channel_enabled(sun20i_chip, pwm->hwpwm ^ 1)) {
|
||||
+ // drop the flag if and only if the counterpart is disabled
|
||||
+ pccr &= ~SUN20I_REG_PCCR_CLK_GATING(pwm->hwpwm);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ sun20i_pwm_writel(sun20i_chip, pccr, SUN20I_REG_OFFSET_PCCR(sun20i_chip, pwm->hwpwm));
|
||||
+
|
||||
+ // PWM Enabling
|
||||
+ val = sun20i_pwm_readl(sun20i_chip, SUN20I_REG_OFFSET_PER(sun20i_chip, pwm->hwpwm));
|
||||
+ if (enable)
|
||||
+ val |= SUN20I_REG_PER_ENABLE(pwm->hwpwm);
|
||||
+ else
|
||||
+ val &= ~SUN20I_REG_PER_ENABLE(pwm->hwpwm);
|
||||
+
|
||||
+ sun20i_pwm_writel(sun20i_chip, val, SUN20I_REG_OFFSET_PER(sun20i_chip, pwm->hwpwm));
|
||||
+}
|
||||
+
|
||||
+static inline u64 sun20i_pwm_get_clock_rate(struct sun20i_pwm_chip *sun20i_chip, unsigned int clksrc)
|
||||
+{
|
||||
+ switch (clksrc) {
|
||||
+ case SUN20I_PWM_CLOCK_SRC_HOSC:
|
||||
+ return clk_get_rate(sun20i_chip->clk_hosc);
|
||||
+
|
||||
+ case SUN20I_PWM_CLOCK_SRC_APB:
|
||||
+ return clk_get_rate(sun20i_chip->clk_apb);
|
||||
+
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int sun20i_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state)
|
||||
+{
|
||||
+ struct sun20i_pwm_chip *sun20i_chip = to_sun20i_pwm_chip(chip);
|
||||
+ u64 clk_rate;
|
||||
+
|
||||
+ u32 pccr = sun20i_pwm_readl(sun20i_chip, SUN20I_REG_OFFSET_PCCR(sun20i_chip, pwm->hwpwm));
|
||||
+ u32 pcr = sun20i_pwm_readl(sun20i_chip, SUN20I_REG_OFFSET_PCR(sun20i_chip, pwm->hwpwm));
|
||||
+ u32 ppr = sun20i_pwm_readl(sun20i_chip, SUN20I_REG_OFFSET_PPR(sun20i_chip, pwm->hwpwm));
|
||||
+
|
||||
+ clk_rate = sun20i_pwm_get_clock_rate(sun20i_chip, FIELD_GET(SUN20I_REG_PCCR_CLK_SRC_MASK, pccr));
|
||||
+ if (!clk_rate) {
|
||||
+ dev_err(pwmchip_parent(chip), "Invalid CLK_SRC is detected\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ unsigned int prescale_k = FIELD_GET(SUN20I_REG_PCR_PRESCAL_K_MASK, pcr) + 1;
|
||||
+ u32 ent_cycle = FIELD_GET(SUN20I_REG_PPR_ENTIRE_CYCLE_MASK, ppr) + 1;
|
||||
+ u32 act_cycle = min(ent_cycle, FIELD_GET(SUN20I_REG_PPR_ACT_CYCLE_MASK, ppr));
|
||||
+
|
||||
+ unsigned int div_m_shift = FIELD_GET(SUN20I_REG_PCCR_CLK_DIV_M_MASK, pccr);
|
||||
+ if (div_m_shift > SUN20I_PWM_DIV_M_SHIFT_MAX) {
|
||||
+ dev_err(pwmchip_parent(chip), "Invalid DIV_M is detected\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ unsigned int div_m = 1 << div_m_shift;
|
||||
+
|
||||
+ // set to the state
|
||||
+ state->enabled = sun20i_pwm_is_channel_enabled(sun20i_chip, pwm->hwpwm);
|
||||
+ state->polarity = (pcr & SUN20I_REG_PCR_ACT_STA) ? PWM_POLARITY_NORMAL : PWM_POLARITY_INVERSED;
|
||||
+ state->period = DIV_ROUND_CLOSEST_ULL(ent_cycle * prescale_k * div_m * NSEC_PER_SEC, clk_rate);
|
||||
+ state->duty_cycle = DIV_ROUND_CLOSEST_ULL(act_cycle * prescale_k * div_m * NSEC_PER_SEC, clk_rate);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline unsigned long sun20i_pwm_find_prescale_k(unsigned long long ent_cycle, unsigned long long act_cycle)
|
||||
+{
|
||||
+ if (ent_cycle == 0 || ent_cycle > SUN20I_PWM_ENT_CYCLE_MAX * SUN20I_PWM_PRESCALE_K_MAX || ent_cycle < act_cycle)
|
||||
+ return 0;
|
||||
+
|
||||
+ return clamp(DIV_ROUND_UP_ULL(ent_cycle, SUN20I_PWM_ENT_CYCLE_MAX), 1, SUN20I_PWM_PRESCALE_K_MAX);
|
||||
+}
|
||||
+
|
||||
+static int sun20i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state)
|
||||
+{
|
||||
+ struct sun20i_pwm_chip *sun20i_chip = to_sun20i_pwm_chip(chip);
|
||||
+ u64 clk_rate;
|
||||
+ u32 ctrl;
|
||||
+
|
||||
+ spin_lock(&sun20i_chip->ctrl_lock);
|
||||
+
|
||||
+ // Period and Duty cycle
|
||||
+ if (state->duty_cycle != pwm->state.duty_cycle || state->period != pwm->state.period) {
|
||||
+ unsigned int idx = pwm->hwpwm / 2;
|
||||
+ clk_rate = sun20i_pwm_get_clock_rate(sun20i_chip, sun20i_chip->clk_src[idx]);
|
||||
+ unsigned long div_m = 1U << sun20i_chip->div_m_shift[idx];
|
||||
+ unsigned long long ent_cycle = DIV_ROUND_CLOSEST(state->period * clk_rate, NSEC_PER_SEC * div_m);
|
||||
+ unsigned long long act_cycle = min(DIV_ROUND_CLOSEST(state->duty_cycle * clk_rate, NSEC_PER_SEC * div_m), ent_cycle);
|
||||
+
|
||||
+ unsigned long prescale_k = sun20i_pwm_find_prescale_k(ent_cycle, act_cycle);
|
||||
+ if (!prescale_k)
|
||||
+ goto err;
|
||||
+
|
||||
+ ent_cycle = clamp(DIV_ROUND_CLOSEST_ULL(ent_cycle, prescale_k), 1, SUN20I_PWM_ENT_CYCLE_MAX);
|
||||
+ act_cycle = clamp(DIV_ROUND_CLOSEST_ULL(act_cycle, prescale_k), 0, ent_cycle);
|
||||
+
|
||||
+ // Set prescale_k
|
||||
+ ctrl = sun20i_pwm_readl(sun20i_chip, SUN20I_REG_OFFSET_PCR(sun20i_chip, pwm->hwpwm));
|
||||
+ ctrl &= ~SUN20I_REG_PCR_PRESCAL_K_MASK;
|
||||
+ ctrl |= FIELD_PREP(SUN20I_REG_PCR_PRESCAL_K_MASK, prescale_k - 1);
|
||||
+ sun20i_pwm_writel(sun20i_chip, ctrl, SUN20I_REG_OFFSET_PCR(sun20i_chip, pwm->hwpwm));
|
||||
+
|
||||
+ // Set period and duty cycle
|
||||
+ ctrl = (((ent_cycle - 1) & 0xFFFF) << 16) | (act_cycle & 0xFFFF);
|
||||
+ sun20i_pwm_writel(sun20i_chip, ctrl, SUN20I_REG_OFFSET_PPR(sun20i_chip, pwm->hwpwm));
|
||||
+ }
|
||||
+
|
||||
+ // Polarity
|
||||
+ if (state->polarity != pwm->state.polarity) {
|
||||
+ ctrl = sun20i_pwm_readl(sun20i_chip, SUN20I_REG_OFFSET_PCR(sun20i_chip, pwm->hwpwm));
|
||||
+ if (state->polarity == PWM_POLARITY_NORMAL) {
|
||||
+ ctrl |= SUN20I_REG_PCR_ACT_STA;
|
||||
+ } else {
|
||||
+ ctrl &= ~SUN20I_REG_PCR_ACT_STA;
|
||||
+ }
|
||||
+ sun20i_pwm_writel(sun20i_chip, ctrl, SUN20I_REG_OFFSET_PCR(sun20i_chip, pwm->hwpwm));
|
||||
+ }
|
||||
+
|
||||
+ // Enable
|
||||
+ if (state->enabled != pwm->state.enabled)
|
||||
+ sun20i_pwm_enable_channel(sun20i_chip, pwm, state->enabled);
|
||||
+
|
||||
+ spin_unlock(&sun20i_chip->ctrl_lock);
|
||||
+ return 0;
|
||||
+
|
||||
+err:
|
||||
+ spin_unlock(&sun20i_chip->ctrl_lock);
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static const struct pwm_ops sun20i_pwm_ops = {
|
||||
+ .apply = sun20i_pwm_apply,
|
||||
+ .get_state = sun20i_pwm_get_state,
|
||||
+};
|
||||
+
|
||||
+static const struct sun20i_pwm_data sun20i_d1_pwm_data = {
|
||||
+ .reg_per = SUN20I_REG_OFFSET_PER_SUN20I,
|
||||
+ .reg_pcr = SUN20I_REG_OFFSET_PCR_SUN20I,
|
||||
+ .reg_ppr = SUN20I_REG_OFFSET_PPR_SUN20I,
|
||||
+ .has_pcgr = true,
|
||||
+};
|
||||
+
|
||||
+static const struct sun20i_pwm_data sun50i_h616_pwm_data = {
|
||||
+ .reg_per = SUN20I_REG_OFFSET_PER_SUN50I,
|
||||
+ .reg_pcr = SUN20I_REG_OFFSET_PCR_SUN50I,
|
||||
+ .reg_ppr = SUN20I_REG_OFFSET_PPR_SUN50I,
|
||||
+ .has_pcgr = false,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id sun20i_pwm_dt_ids[] = {
|
||||
+ {
|
||||
+ .compatible = "allwinner,sun20i-d1-pwm",
|
||||
+ .data = &sun20i_d1_pwm_data,
|
||||
+ },
|
||||
+ {
|
||||
+ .compatible = "allwinner,sun50i-h616-pwm",
|
||||
+ .data = &sun50i_h616_pwm_data,
|
||||
+ },
|
||||
+ {
|
||||
+ /* sentinel */
|
||||
+ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sun20i_pwm_dt_ids);
|
||||
+
|
||||
+static int sun20i_pwm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct pwm_chip *chip;
|
||||
+ const struct sun20i_pwm_data *data;
|
||||
+ struct sun20i_pwm_chip *sun20i_chip;
|
||||
+ u32 npwm;
|
||||
+ int ret;
|
||||
+
|
||||
+ struct device_node *node = pdev->dev.of_node;
|
||||
+
|
||||
+ data = of_device_get_match_data(&pdev->dev);
|
||||
+ if (!data)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ret = of_property_read_u32(node, "allwinner,pwm-channels", &npwm);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(&pdev->dev, -EINVAL, "No PWM channels are configured\n");
|
||||
+
|
||||
+ if (npwm > SUN20I_PWM_CHANNELS_MAX)
|
||||
+ return dev_err_probe(&pdev->dev, -EINVAL, "Too many PWM channels are configured\n");
|
||||
+
|
||||
+ chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*sun20i_chip));
|
||||
+ if (IS_ERR(chip))
|
||||
+ return PTR_ERR(chip);
|
||||
+ sun20i_chip = to_sun20i_pwm_chip(chip);
|
||||
+
|
||||
+ sun20i_chip->data = data;
|
||||
+
|
||||
+ for (int i = 0; i < (npwm + 1) / 2; i++) {
|
||||
+ sun20i_chip->clk_src[i] = SUN20I_PWM_CLOCK_SRC_DEFAULT;
|
||||
+ sun20i_chip->div_m_shift[i] = SUN20I_PWM_DIV_M_SHIFT_DEFAULT;
|
||||
+
|
||||
+ const char *source;
|
||||
+ ret = of_property_read_string_index(node, "allwinner,pwm-paired-channel-clock-sources", i, &source);
|
||||
+ if (!ret) {
|
||||
+ if (!strcasecmp(source, "hosc"))
|
||||
+ sun20i_chip->clk_src[i] = SUN20I_PWM_CLOCK_SRC_HOSC;
|
||||
+ else if (!strcasecmp(source, "apb"))
|
||||
+ sun20i_chip->clk_src[i] = SUN20I_PWM_CLOCK_SRC_APB;
|
||||
+ else
|
||||
+ return dev_err_probe(&pdev->dev, -EINVAL, "Unknown clock source: %s\n", source);
|
||||
+ }
|
||||
+
|
||||
+ u32 value;
|
||||
+ ret = of_property_read_u32_index(node, "allwinner,pwm-paired-channel-clock-prescales", i, &value);
|
||||
+ if (!ret) {
|
||||
+ if (value <= SUN20I_PWM_DIV_M_SHIFT_MAX)
|
||||
+ sun20i_chip->div_m_shift[i] = value;
|
||||
+ else
|
||||
+ return dev_err_probe(&pdev->dev, -EINVAL, "Invalid prescale value: %u\n", value);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ sun20i_chip->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(sun20i_chip->base))
|
||||
+ return PTR_ERR(sun20i_chip->base);
|
||||
+
|
||||
+ sun20i_chip->clk_bus = devm_clk_get_enabled(&pdev->dev, "bus");
|
||||
+ if (IS_ERR(sun20i_chip->clk_bus))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_bus), "Failed to get `bus` clock\n");
|
||||
+
|
||||
+ sun20i_chip->clk_hosc = devm_clk_get_enabled(&pdev->dev, "hosc");
|
||||
+ if (IS_ERR(sun20i_chip->clk_hosc))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_hosc), "Failed to get `hosc` clock\n");
|
||||
+
|
||||
+ sun20i_chip->clk_apb = devm_clk_get_enabled(&pdev->dev, "apb");
|
||||
+ if (IS_ERR(sun20i_chip->clk_apb))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_apb), "Failed to get `apb` clock\n");
|
||||
+
|
||||
+ sun20i_chip->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(sun20i_chip->rst))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->rst), "Failed to get bus reset\n");
|
||||
+
|
||||
+ ret = reset_control_deassert(sun20i_chip->rst);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(&pdev->dev, ret, "Failed to deassert reset control\n");
|
||||
+
|
||||
+ chip->ops = &sun20i_pwm_ops;
|
||||
+
|
||||
+ spin_lock_init(&sun20i_chip->ctrl_lock);
|
||||
+
|
||||
+ ret = pwmchip_add(chip);
|
||||
+ if (ret < 0) {
|
||||
+ reset_control_assert(sun20i_chip->rst);
|
||||
+ return dev_err_probe(&pdev->dev, ret, "Failed to add PWM chip\n");
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, chip);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void sun20i_pwm_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct pwm_chip *chip = platform_get_drvdata(pdev);
|
||||
+ struct sun20i_pwm_chip *sun20i_chip = to_sun20i_pwm_chip(chip);
|
||||
+
|
||||
+ pwmchip_remove(chip);
|
||||
+
|
||||
+ reset_control_assert(sun20i_chip->rst);
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver sun20i_pwm_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "sun20i-pwm",
|
||||
+ .of_match_table = sun20i_pwm_dt_ids,
|
||||
+ },
|
||||
+ .probe = sun20i_pwm_probe,
|
||||
+ .remove = sun20i_pwm_remove,
|
||||
+};
|
||||
+module_platform_driver(sun20i_pwm_driver);
|
||||
+
|
||||
+MODULE_ALIAS("platform:sun20i-pwm");
|
||||
+MODULE_AUTHOR("Hironori KIKUCHI <kikuchan98@gmail.com>");
|
||||
+MODULE_DESCRIPTION("Allwinner sun20i PWM driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 193e59a21f1a828e1860cd6fdfcb3fbf041a3f19 Mon Sep 17 00:00:00 2001
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
Date: Thu, 23 Jan 2025 23:39:47 +0100
|
||||
Subject: [PATCH 8/9] h616: add pwm node
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
|
||||
index c335e81a5..7417a214a 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
|
||||
@@ -257,6 +257,20 @@ ccu: clock@3001000 {
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
+ pwm: pwm@300a000 {
|
||||
+ compatible = "allwinner,sun50i-h616-pwm";
|
||||
+ reg = <0x0300a000 0x400>;
|
||||
+ clocks = <&ccu CLK_BUS_PWM>,
|
||||
+ <&osc24M>,
|
||||
+ <&ccu CLK_APB1>;
|
||||
+ clock-names = "bus", "hosc", "apb";
|
||||
+ resets = <&ccu RST_BUS_PWM>;
|
||||
+ #pwm-cells = <0x3>;
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ allwinner,pwm-channels = <6>;
|
||||
+ };
|
||||
+
|
||||
dma: dma-controller@3002000 {
|
||||
compatible = "allwinner,sun50i-h616-dma",
|
||||
"allwinner,sun50i-a100-dma";
|
||||
--
|
||||
2.47.1
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
From e82b0cfa996e55f6e5f70815ac04cda0b58bf9c4 Mon Sep 17 00:00:00 2001
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
Date: Thu, 23 Jan 2025 23:41:16 +0100
|
||||
Subject: [PATCH 9/9] rg35xx: enable pwm backlight
|
||||
|
||||
---
|
||||
.../sun50i-h700-anbernic-rg35xx-2024.dts | 18 +++++++++++++++---
|
||||
1 file changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
|
||||
index 5d2b13aa7..3397cad0c 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
|
||||
@@ -22,9 +22,10 @@ aliases {
|
||||
};
|
||||
|
||||
backlight: backlight {
|
||||
- compatible = "gpio-backlight";
|
||||
- gpios = <&pio 3 28 GPIO_ACTIVE_HIGH>; // PD28
|
||||
- default-on;
|
||||
+ compatible = "pwm-backlight";
|
||||
+ pwms = <&pwm 0 50000 0>;
|
||||
+ pinctrl-0 = <&lcd_backlight_pin>;
|
||||
+ pinctrl-names = "default";
|
||||
};
|
||||
|
||||
battery: battery {
|
||||
@@ -304,6 +305,11 @@ &pio {
|
||||
vcc-pg-supply = <®_aldo4>;
|
||||
vcc-ph-supply = <®_cldo3>;
|
||||
vcc-pi-supply = <®_cldo3>;
|
||||
+
|
||||
+ lcd_backlight_pin: pwm0-pin {
|
||||
+ pins = "PD28";
|
||||
+ function = "pwm0";
|
||||
+ };
|
||||
};
|
||||
|
||||
&r_i2c {
|
||||
@@ -458,3 +464,9 @@ &usbotg {
|
||||
&usbphy {
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+&pwm {
|
||||
+ allwinner,pwm-paired-channel-clock-sources = "hosc", "hosc", "hosc";
|
||||
+ allwinner,pwm-paired-channel-clock-prescales = <0>, <0>, <0>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
--
|
||||
2.47.1
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
From 8e7f804d1f1aedf946b229b3f59501ddee840149 Mon Sep 17 00:00:00 2001
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
Date: Sat, 19 Apr 2025 18:36:09 +0200
|
||||
Subject: [PATCH] Revert "usb: musb: Fix hardware lockup on first Rx endpoint
|
||||
request"
|
||||
|
||||
This reverts commit 3fc137386c4620305bbc2a216868c53f9245670a.
|
||||
---
|
||||
drivers/usb/musb/musb_gadget.c | 13 +++----------
|
||||
1 file changed, 3 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
|
||||
index 6869c58367f2..661c6a16f4f7 100644
|
||||
--- a/drivers/usb/musb/musb_gadget.c
|
||||
+++ b/drivers/usb/musb/musb_gadget.c
|
||||
@@ -1162,19 +1162,12 @@ void musb_free_request(struct usb_ep *ep, struct usb_request *req)
|
||||
*/
|
||||
void musb_ep_restart(struct musb *musb, struct musb_request *req)
|
||||
{
|
||||
- u16 csr;
|
||||
- void __iomem *epio = req->ep->hw_ep->regs;
|
||||
-
|
||||
trace_musb_req_start(req);
|
||||
musb_ep_select(musb->mregs, req->epnum);
|
||||
- if (req->tx) {
|
||||
+ if (req->tx)
|
||||
txstate(musb, req);
|
||||
- } else {
|
||||
- csr = musb_readw(epio, MUSB_RXCSR);
|
||||
- csr |= MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_P_WZC_BITS;
|
||||
- musb_writew(epio, MUSB_RXCSR, csr);
|
||||
- musb_writew(epio, MUSB_RXCSR, csr);
|
||||
- }
|
||||
+ else
|
||||
+ rxstate(musb, req);
|
||||
}
|
||||
|
||||
static int musb_ep_restart_resume_work(struct musb *musb, void *data)
|
||||
--
|
||||
2.49.0
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user