consolidate rk322x and rockchip 32 bit families

* merge patches from rockchip and rk322x families for current and edge
   kernels
 * adjust patches for tinkerboard to remove some cruft and overclocking
 * rework kernel configs
 * fix rk322x dmc to avoid lockup on rk3288
 * migrate rockchip-6.6 into patch series, rename all patches with
   more understandable names
 * add gen-series.sh script in tools directory (it is a naive tool to
   create patch series when you don't want to rebase everything)
This commit is contained in:
Paolo Sabatino 2023-12-25 18:30:47 +01:00 committed by Paolo
parent 670172dcb0
commit 562d96128b
224 changed files with 143560 additions and 4450 deletions

View File

@ -1,9 +1,10 @@
# RK322X TVBox quad core 1GB/2GB DDR2/DDR3 eMMC/NAND SoC FE WiFi
BOARD_NAME="rk322x-box"
BOARDFAMILY="rk322x"
BOARDFAMILY="rockchip"
BOARD_MAINTAINER=""
BOOTCONFIG="rk322x-box_defconfig"
BOOT_FDT_FILE="rk322x-box.dtb"
MODULES_LEGACY="hci_uart rfcomm hidp"
MODULES_BLACKLIST_LEGACY="ssv6051 8723cs r8188eu ssv6x5x"
KERNEL_TARGET="legacy,current,edge"
BOOT_SOC="rk322x"

View File

@ -8,3 +8,4 @@ DEFAULT_OVERLAYS="i2c1 i2c4 spi2 spidev2 uart1 uart2"
KERNEL_TARGET="current,edge"
KERNEL_TEST_TARGET="current"
FULL_DESKTOP="yes"
BOOT_SOC="rk3288"

View File

@ -1,2 +1,3 @@
verbosity=1
extraargs=coherent_pool=2M
bootlogo=false

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,21 +7,45 @@
# https://github.com/armbian/build/
#
enable_extension "rkbin-tools"
# BOOT_SOC has to be set in the board configuration file; if not set
# we resort to rk3288
BOOT_SOC=${BOOT_SOC:="rk3288"}
ARCH=armhf
BOOTSCRIPT="boot-rockchip.cmd:boot.cmd"
BOOTENV_FILE='rockchip.txt'
OVERLAY_PREFIX='rockchip'
UBOOT_TARGET_MAP=";;$SRC/packages/blobs/rockchip/rk3288_boot.bin u-boot-rockchip-with-spl.bin"
BOOTDELAY=1
if [[ $BOARD == miqi ]]; then
BOOTBRANCH='tag:v2017.11'
BOOTPATCHDIR='legacy'
else
SERIALCON=ttyS2
if [[ "$BOOT_SOC" == "rk3288" ]]; then
BOOTSCRIPT="boot-rockchip.cmd:boot.cmd"
BOOTENV_FILE='rockchip.txt'
OVERLAY_PREFIX='rockchip'
UBOOT_TARGET_MAP=";;$SRC/packages/blobs/rockchip/rk3288_boot.bin u-boot-rockchip-with-spl.bin"
BOOTBRANCH='tag:v2022.04'
BOOTPATCHDIR='v2022.04'
fi
SERIALCON=ttyS2
if [[ $BOARD == miqi ]]; then
BOOTBRANCH='tag:v2017.11'
BOOTPATCHDIR='legacy'
fi
elif [[ "$BOOT_SOC" == "rk322x" ]]; then
# enable extension to fix autodetection for Lima driver and x.org
# on non-legacy kernels
enable_extension xorg-lima-serverflags
BOOTSCRIPT="boot-rk322x.cmd:boot.cmd"
BOOTENV_FILE='rk322x.txt'
OVERLAY_PREFIX='rk322x'
UBOOT_TARGET_MAP="all u-boot.itb;;u-boot-rk322x-with-spl.bin"
BOOTBRANCH='tag:v2022.04'
BOOTPATCHDIR='v2022.04'
fi
case $BRANCH in
@ -45,30 +69,119 @@ CPUMAX="1900000"
GOVERNOR="ondemand"
write_uboot_platform() {
dd if=/dev/zero of=$2 bs=1k count=1023 seek=1 status=noxfer > /dev/null 2>&1
dd if=$1/u-boot-rockchip-with-spl.bin of=$2 seek=64 conv=notrunc > /dev/null 2>&1
# Extract the Command Rate bit from existing loader.
# Some DDR memories have issues with different Command Rate, so we
# restore the same value after installing the new loader.
# Note: this has to be done only on live installations (DIR variable
# is present only during boot loader upgrade on running system)
# while loop is only for convenient break syntax
while [[ -n $DIR ]]; do
# Only applicable to rk322x
[[ "$BOOT_SOC" != "rk322x" ]] && break
# Find the signature "a7866565" in the first 128k of the stored running image
SIGNATURE_OFFSET=$(dd if=$2 bs=128k count=1 2> /dev/null | od -A o -w4 -tx4 | grep 'a7866565' | cut -d " " -f 1)
# Some command failed, skip the rest
[[ $? -ne 0 ]] && break
# No signature found, skip the rest
[[ -z $SIGNATURE_OFFSET ]] && break
# Command rate bit is 16 bytes before signature
CMD_RATE_OFFSET=$(($SIGNATURE_OFFSET - 16))
CR_BYTE=$(od -A n -t dI -j $CMD_RATE_OFFSET -N 1 $2)
# No command rate byte for some reason, skip the rest
[[ -z $CR_BYTE ]] && break
# Invalid command rate byte (should be 0 or 1), skip the rest
[[ "$CR_BYTE" -ne 0 && "$CR_BYTE" -ne 1 ]] && break
# Proceed patching u-boot-rk322x-with-spl.bin, do find the
# cr bit there too to verify that the position of the CR bit is right
SIGNATURE_OFFSET=$(dd if=$1/u-boot-rk322x-with-spl.bin bs=128k count=1 2> /dev/null | od -A o -w4 -tx4 | grep 'a7866565' | cut -d " " -f 1)
# Some command failed, skip the rest
[[ $? -ne 0 ]] && break
# No signature found, skip the rest
[[ -z $SIGNATURE_OFFSET ]] && break
# Command rate bit is 16 bytes before signature
CMD_RATE_OFFSET=$(($SIGNATURE_OFFSET - 16))
DST_BYTE=$(od -A n -t dI -j $CMD_RATE_OFFSET -N 1 $1/u-boot-rk322x-with-spl.bin)
# Verify command rate byte is 0 or 1
[[ "$DST_BYTE" -ne 0 && "$DST_BYTE" -ne 1 ]] && break
# Patch the file
[[ "$CR_BYTE" -eq 0 ]] && HEX_CR="\x00"
[[ "$CR_BYTE" -eq 1 ]] && HEX_CR="\x01"
echo -e $HEX_CR | dd of=$1/u-boot-rk322x-with-spl.bin bs=1 seek=$CMD_RATE_OFFSET count=1 conv=notrunc > /dev/null 2>&1
# always break the while loop
break
done
if [[ "$BOOT_SOC" == "rk3288" ]]; then
UBOOT_SRC="u-boot-rockchip-with-spl.bin"
elif [[ "$BOOT_SOC" == "rk322x" ]]; then
UBOOT_SRC="u-boot-rk322x-with-spl.bin"
fi
dd if=/dev/zero of=$2 bs=32k count=63 seek=1 status=noxfer > /dev/null 2>&1
dd if=$1/$UBOOT_SRC of=$2 bs=32k seek=1 conv=notrunc
}
uboot_custom_postprocess() {
# xt-q8l-v10 requires the original DDR init blob because u-boot does not support LPDDR2 initialization
# for rk3288 SoC (binary is in sources/rkbin-tools/rk32 path). U-boot is configured to produce a TPL
# which is thrown away. SPL does some more initial configurations, expecially pinmux for power hold,
# so reset works more reliably. U-boot image is set to be at sector 0x200 on the eMMC/SD,
# so we burn it 0x200-0x40 because of the rockchip 0x40 sectors offset.
if [[ $BOARD == xt-q8l-v10 ]]; then
tools/mkimage -n rk3288 -T rksd -d $SRC/cache/sources/rkbin-tools/rk32/rk3288_ddr_400MHz_v1.08.bin u-boot-rockchip-with-spl.bin
cat spl/u-boot-spl-dtb.bin >> u-boot-rockchip-with-spl.bin
dd if=u-boot-dtb.img of=u-boot-rockchip-with-spl.bin seek=$((0x200 - 0x40)) conv=notrunc
else
tools/mkimage -n rk3288 -T rksd -d tpl/u-boot-tpl.bin u-boot-rockchip-with-spl.bin
if [[ "$BOOT_SOC" == "rk3288" ]]; then
# xt-q8l-v10 requires the original DDR init blob because u-boot does not support LPDDR2 initialization
# for rk3288 SoC (binary is in sources/rkbin-tools/rk32 path). U-boot is configured to produce a TPL
# which is thrown away. SPL does some more initial configurations, expecially pinmux for power hold,
# so reset works more reliably. U-boot image is set to be at sector 0x200 on the eMMC/SD,
# so we burn it 0x200-0x40 because of the rockchip 0x40 sectors offset.
if [[ $BOARD == xt-q8l-v10 ]]; then
run_host_command_logged tools/mkimage -n rk3288 -T rksd -d $SRC/cache/sources/rkbin-tools/rk32/rk3288_ddr_400MHz_v1.08.bin u-boot-rockchip-with-spl.bin
else
run_host_command_logged tools/mkimage -n rk3288 -T rksd -d tpl/u-boot-tpl.bin u-boot-rockchip-with-spl.bin
fi
cat spl/u-boot-spl-dtb.bin >> u-boot-rockchip-with-spl.bin
dd if=u-boot-dtb.img of=u-boot-rockchip-with-spl.bin seek=$((0x200 - 0x40)) conv=notrunc
elif [[ "$BOOT_SOC" == "rk322x" ]]; then
# We use the rockchip proprietary blob to initialize memory chips
# instead of letting u-boot doing the job. Such devices, like xt-mx4vr-v01, have DDR2
# or LPDDR2 memories and the blob is better suited for the job.
# Also it may come handy when there are different memory flavours among boards, with
# different timings, specs and frequencies.
# The rockchip proprietary blob is a drop-in substitute for the u-boot tpl.
# In case you want to use the u-boot TPL remember to set the proper timing
# registers in device tree and this command line instead of the other one:
#
# tools/mkimage -n rk322x -T rksd -d tpl/u-boot-tpl.bin u-boot-rk322x-with-spl.bin
#
run_host_command_logged tools/mkimage -n rk322x -T rksd -d $SRC/packages/blobs/rockchip/rk322x_ddr_333MHz_v1.11_2t.bin u-boot-rk322x-with-spl.bin
run_host_command_logged cat spl/u-boot-spl.bin ">>" u-boot-rk322x-with-spl.bin
run_host_command_logged dd if=u-boot.itb of=u-boot-rk322x-with-spl.bin seek=$((0x200 - 0x40)) conv=notrunc
fi
}
family_tweaks() {
if [[ $BOARD == tinkerboard ]]; then
chroot_sdcard_apt_get_install rfkill bluetooth bluez bluez-tools
if [[ -f "$SDCARD/etc/pulse/default.pa" ]]; then
@ -84,6 +197,7 @@ family_tweaks() {
chroot_sdcard addgroup --system --quiet --gid 901 i2c
return 0
}
family_tweaks_bsp() {
@ -101,6 +215,10 @@ family_tweaks_bsp() {
cp $SRC/packages/bsp/rockchip/70-gpio.rules $destination/etc/udev/rules.d
cp $SRC/packages/bsp/rockchip/71-i2c.rules $destination/etc/udev/rules.d
# Bluetooth
install -m 755 $SRC/packages/bsp/rk322x/rtk_hciattach $destination/usr/bin
cp $SRC/packages/bsp/rk322x/rtk-bluetooth.service $destination/lib/systemd/system/
# Sound
cp $SRC/packages/bsp/rockchip/asound.conf $destination/etc/
cp $SRC/packages/bsp/rockchip/89-pulseaudio-usb.rules $destination/etc/udev/rules.d
@ -109,5 +227,17 @@ family_tweaks_bsp() {
mkdir -p $destination/etc/initramfs-tools/hooks
install -m 550 $SRC/packages/bsp/rockchip/ap6330-initramfs-firmware $destination/etc/initramfs-tools/hooks
# esp8089 wifi driver modprobe default configuration options, only for legacy kernel
mkdir -p $destination/etc/modprobe.d
if [[ "$BOOT_SOC" == "rk322x" && "$BRANCH" == "legacy" ]]; then
cp $SRC/packages/bsp/rk322x/esp8089.conf $destination/etc/modprobe.d/esp8089.conf
fi
# Board selection script, only for rk322x-box
if [[ "$BOARD" == "rk322x-box" ]]; then
install -m 755 $SRC/packages/bsp/rk322x/rk322x-config $destination/usr/sbin
fi
return 0 # exit with success
}

View File

@ -0,0 +1,38 @@
config:
# Just some info stuff; not used by the patching scripts
name: rockchip-6.1
kind: kernel
type: mainline # or: vendor
branch: linux-6.1.y
last-known-good-tag: v6.1
maintainers:
- { github: paolo.sabatino, name: Paolo Sabatino, email: paolo.sabatino@gmail.com, armbian-forum: jock }
# .dts files in these directories will be copied as-is to the build tree; later ones overwrite earlier ones.
# This is meant to provide a way to "add a board DTS" without having to null-patch them in.
dts-directories:
- { source: "dt", target: "arch/arm/boot/dts" }
# every file in these directories will be copied as-is to the build tree; later ones overwrite earlier ones
# This is meant as a way to have overlays, bare, in a directory, without having to null-patch them in.
# @TODO need a solution to auto-Makefile the overlays as well
overlay-directories:
- { source: "overlay", target: "arch/arm/boot/dts/overlay" }
# the Makefile in each of these directories will be magically patched to include the dts files copied
# or patched-in; overlay subdir will be included "-y" if it exists.
# No more Makefile patching needed, yay!
# IMPORTANT: this can't be enabled for 6.1, since that carries a single flat directory for armhf DT's
#auto-patch-dt-makefile:
# - { directory: "arch/arm/boot/dts/rockchip", config-var: "CONFIG_ARCH_ROCKCHIP" }
# configuration for when applying patches to git / auto-rewriting patches (development cycle helpers)
patches-to-git:
do-not-commit-files:
- "MAINTAINERS" # constant churn, drop them. sorry.
- "Documentation/devicetree/bindings/arm/rockchip.yaml" # constant churn, conflicts on every bump, drop it. sorry.
# DISABLED, we've to manually patch Makefiles for 6.1 on armhf (subdirs were only introduced in 6.5-rc1)
#do-not-commit-regexes: # Python-style regexes
# - "^arch/([a-zA-Z0-9]+)/boot/dts/([a-zA-Z0-9]+)/Makefile$" # ignore DT Makefile patches, we've an auto-patcher now

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
From 6408e6688b18e5c712c711110d196a4e95f3f870 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Thu, 9 Sep 2021 16:37:28 +0000
Subject: [PATCH 2/4] 01-linux-1000-export-mm_trace_rss_stat
---
mm/memory.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/mm/memory.c b/mm/memory.c
index 25fc46e87..7ef0adaa5 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -171,6 +171,7 @@ void mm_trace_rss_stat(struct mm_struct *mm, int member, long count)
{
trace_rss_stat(mm, member, count);
}
+EXPORT_SYMBOL(mm_trace_rss_stat);
#if defined(SPLIT_RSS_COUNTING)
--
2.25.1

View File

@ -0,0 +1,782 @@
From 92a42b2df843c0f6c2937dc6bdbfe72332c9e557 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Thu, 9 Sep 2021 16:46:33 +0000
Subject: [PATCH 3/4] 01-linux-1000-rockchip-wip
---
arch/arm/boot/dts/rk322x.dtsi | 101 +++++++++++++++++-
arch/arm/boot/dts/rk3xxx.dtsi | 2 +
drivers/clk/rockchip/clk-rk3228.c | 61 ++++-------
drivers/net/ethernet/arc/emac.h | 14 +++
drivers/net/ethernet/arc/emac_main.c | 81 ++++++++++++--
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 38 ++++++-
drivers/soc/rockchip/pm_domains.c | 23 ++++
drivers/usb/dwc2/core.c | 2 +-
8 files changed, 266 insertions(+), 56 deletions(-)
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 75af99c76..c50b2ccd7 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -15,6 +15,7 @@ / {
interrupt-parent = <&gic>;
aliases {
+ ethernet0 = &gmac;
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
@@ -105,6 +106,22 @@ arm-pmu {
interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
};
+ hdmi_sound: hdmi-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "hdmi-sound";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+ status = "disabled";
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&hdmi>;
+ };
+ };
+
psci {
compatible = "arm,psci-1.0", "arm,psci-0.2";
method = "smc";
@@ -132,6 +149,17 @@ display_subsystem: display-subsystem {
ports = <&vop_out>;
};
+ crypto: cypto-controller@100a0000 {
+ compatible = "rockchip,rk3288-crypto";
+ reg = <0x100a0000 0x4000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_M_CRYPTO>, <&cru HCLK_S_CRYPTO>,
+ <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC>;
+ clock-names = "aclk", "hclk", "sclk", "apb_pclk";
+ resets = <&cru SRST_CRYPTO>;
+ reset-names = "crypto-rst";
+ };
+
i2s1: i2s1@100b0000 {
compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s";
reg = <0x100b0000 0x4000>;
@@ -142,6 +170,7 @@ i2s1: i2s1@100b0000 {
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&i2s1_bus>;
+ #sound-dai-cells = <0>;
status = "disabled";
};
@@ -153,6 +182,7 @@ i2s0: i2s0@100c0000 {
clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0_8CH>;
dmas = <&pdma 11>, <&pdma 12>;
dma-names = "tx", "rx";
+ #sound-dai-cells = <0>;
status = "disabled";
};
@@ -166,6 +196,7 @@ spdif: spdif@100d0000 {
dma-names = "tx";
pinctrl-names = "default";
pinctrl-0 = <&spdif_tx>;
+ #sound-dai-cells = <0>;
status = "disabled";
};
@@ -337,7 +368,7 @@ uart2: serial@11030000 {
clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
clock-names = "baudclk", "apb_pclk";
pinctrl-names = "default";
- pinctrl-0 = <&uart2_xfer>;
+ pinctrl-0 = <&uart21_xfer>;
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -358,6 +389,10 @@ efuse_id: id@7 {
cpu_leakage: cpu_leakage@17 {
reg = <0x17 0x1>;
};
+ hdmi_phy_flag: hdmi-phy-flag@1d {
+ reg = <0x1d 0x1>;
+ bits = <1 1>;
+ };
};
i2c0: i2c@11050000 {
@@ -554,6 +589,11 @@ map1 {
<&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
+ map2 {
+ trip = <&cpu_alert1>;
+ cooling-device =
+ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
};
};
};
@@ -584,6 +624,8 @@ hdmi_phy: hdmi-phy@12030000 {
clock-names = "sysclk", "refoclk", "refpclk";
#clock-cells = <0>;
clock-output-names = "hdmiphy_phy";
+ nvmem-cells = <&hdmi_phy_flag>;
+ nvmem-cell-names = "hdmi-phy-flag";
#phy-cells = <0>;
status = "disabled";
};
@@ -607,7 +649,27 @@ gpu: gpu@20000000 {
clock-names = "bus", "core";
power-domains = <&power RK3228_PD_GPU>;
resets = <&cru SRST_GPU_A>;
- status = "disabled";
+ operating-points-v2 = <&gpu_opp_table>;
+ #cooling-cells = <2>; /* min followed by max */
+ };
+
+ gpu_opp_table: opp-table2 {
+ compatible = "operating-points-v2";
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ opp-microvolt = <1050000>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-microvolt = <1050000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <1150000>;
+ };
};
vpu: video-codec@20020000 {
@@ -727,6 +789,7 @@ hdmi: hdmi@200a0000 {
phys = <&hdmi_phy>;
phy-names = "hdmi";
rockchip,grf = <&grf>;
+ #sound-dai-cells = <0>;
status = "disabled";
ports {
@@ -748,9 +811,13 @@ sdmmc: mmc@30000000 {
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ bus-width = <4>;
fifo-depth = <0x100>;
+ max-frequency = <150000000>;
pinctrl-names = "default";
- pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4 &sdmmc_pwr>;
+ resets = <&cru SRST_SDMMC>;
+ reset-names = "reset";
status = "disabled";
};
@@ -760,10 +827,14 @@ sdio: mmc@30010000 {
interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
<&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+ bus-width = <4>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
fifo-depth = <0x100>;
+ max-frequency = <150000000>;
pinctrl-names = "default";
pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>;
+ resets = <&cru SRST_SDIO>;
+ reset-names = "reset";
status = "disabled";
};
@@ -771,14 +842,13 @@ emmc: mmc@30020000 {
compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x30020000 0x4000>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
- clock-frequency = <37500000>;
- max-frequency = <37500000>;
clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
<&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
bus-width = <8>;
rockchip,default-sample-phase = <158>;
fifo-depth = <0x100>;
+ max-frequency = <150000000>;
pinctrl-names = "default";
pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
resets = <&cru SRST_EMMC>;
@@ -1029,6 +1099,10 @@ sdmmc_bus4: sdmmc-bus4 {
<1 RK_PC4 1 &pcfg_pull_none_drv_12ma>,
<1 RK_PC5 1 &pcfg_pull_none_drv_12ma>;
};
+
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
};
sdio {
@@ -1261,13 +1335,30 @@ uart1_xfer: uart1-xfer {
<1 RK_PB2 1 &pcfg_pull_none>;
};
+ uart11_xfer: uart11-xfer {
+ rockchip,pins = <3 RK_PB6 1 &pcfg_pull_up>,
+ <3 RK_PB5 1 &pcfg_pull_none>;
+ };
+
uart1_cts: uart1-cts {
rockchip,pins = <1 RK_PB0 1 &pcfg_pull_none>;
};
+ uart11_cts: uart11-cts {
+ rockchip,pins = <3 RK_PA7 1 &pcfg_pull_none>;
+ };
+
uart1_rts: uart1-rts {
rockchip,pins = <1 RK_PB3 1 &pcfg_pull_none>;
};
+
+ uart11_rts: uart11-rts {
+ rockchip,pins = <3 RK_PA6 1 &pcfg_pull_none>;
+ };
+
+ uart11_rts_gpio: uart11-rts-gpio {
+ rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
};
uart2 {
diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index 616a828e0..f233b7a77 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -64,6 +64,8 @@ L2: cache-controller@10138000 {
reg = <0x10138000 0x1000>;
cache-unified;
cache-level = <2>;
+ prefetch-data = <1>;
+ prefetch-instr = <1>;
};
scu@1013c000 {
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
index aca1a483a..7250adc64 100644
--- a/drivers/clk/rockchip/clk-rk3228.c
+++ b/drivers/clk/rockchip/clk-rk3228.c
@@ -135,24 +135,22 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = {
PNAME(mux_pll_p) = { "clk_24m", "xin24m" };
-PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr", "apll_ddr" };
+PNAME(mux_ddrphy_p) = { "dpll", "gpll", "apll" };
PNAME(mux_armclk_p) = { "apll_core", "gpll_core", "dpll_core" };
PNAME(mux_usb480m_phy_p) = { "usb480m_phy0", "usb480m_phy1" };
PNAME(mux_usb480m_p) = { "usb480m_phy", "xin24m" };
PNAME(mux_hdmiphy_p) = { "hdmiphy_phy", "xin24m" };
-PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu", "hdmiphy_aclk_cpu" };
PNAME(mux_pll_src_4plls_p) = { "cpll", "gpll", "hdmiphy", "usb480m" };
PNAME(mux_pll_src_3plls_p) = { "cpll", "gpll", "hdmiphy" };
PNAME(mux_pll_src_2plls_p) = { "cpll", "gpll" };
PNAME(mux_sclk_hdmi_cec_p) = { "cpll", "gpll", "xin24m" };
-PNAME(mux_aclk_peri_src_p) = { "cpll_peri", "gpll_peri", "hdmiphy_peri" };
PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "usb480m" };
PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" };
PNAME(mux_sclk_rga_p) = { "gpll", "cpll", "sclk_rga_src" };
-PNAME(mux_sclk_vop_src_p) = { "gpll_vop", "cpll_vop" };
+PNAME(mux_sclk_vop_src_p) = { "gpll", "cpll" };
PNAME(mux_dclk_vop_p) = { "hdmiphy", "sclk_vop_pre" };
PNAME(mux_i2s0_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" };
@@ -221,27 +219,23 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
RK2928_CLKSEL_CON(4), 8, 5, DFLAGS),
/* PD_DDR */
- GATE(0, "apll_ddr", "apll", CLK_IGNORE_UNUSED,
+ COMPOSITE(0, "clk_ddrphy_src", mux_ddrphy_p, CLK_IGNORE_UNUSED,
+ RK2928_CLKSEL_CON(26), 8, 2, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
RK2928_CLKGATE_CON(0), 2, GFLAGS),
- GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
- RK2928_CLKGATE_CON(0), 2, GFLAGS),
- GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
- RK2928_CLKGATE_CON(0), 2, GFLAGS),
- COMPOSITE(0, "ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
- RK2928_CLKSEL_CON(26), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+ GATE(0, "ddrphy4x", "clk_ddrphy_src", CLK_IGNORE_UNUSED,
RK2928_CLKGATE_CON(7), 1, GFLAGS),
- GATE(0, "ddrc", "ddrphy_pre", CLK_IGNORE_UNUSED,
+ FACTOR_GATE(0, "ddrc", "clk_ddrphy_src", CLK_IGNORE_UNUSED, 1, 4,
RK2928_CLKGATE_CON(8), 5, GFLAGS),
- FACTOR_GATE(0, "ddrphy", "ddrphy4x", CLK_IGNORE_UNUSED, 1, 4,
+ FACTOR_GATE(0, "ddrphy", "clk_ddrphy_src", CLK_IGNORE_UNUSED, 1, 4,
RK2928_CLKGATE_CON(7), 0, GFLAGS),
/* PD_CORE */
- GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED,
- RK2928_CLKGATE_CON(0), 6, GFLAGS),
GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
RK2928_CLKGATE_CON(0), 6, GFLAGS),
GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
RK2928_CLKGATE_CON(0), 6, GFLAGS),
+ GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED,
+ RK2928_CLKGATE_CON(0), 6, GFLAGS),
COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
RK2928_CLKGATE_CON(4), 1, GFLAGS),
@@ -258,14 +252,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
RK2928_MISC_CON, 15, 1, MFLAGS),
/* PD_BUS */
- GATE(0, "hdmiphy_aclk_cpu", "hdmiphy", CLK_IGNORE_UNUSED,
+ COMPOSITE(0, "aclk_cpu_src", mux_pll_src_3plls_p, 0,
+ RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS,
RK2928_CLKGATE_CON(0), 1, GFLAGS),
- GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED,
- RK2928_CLKGATE_CON(0), 1, GFLAGS),
- GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED,
- RK2928_CLKGATE_CON(0), 1, GFLAGS),
- COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0,
- RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS),
GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0,
RK2928_CLKGATE_CON(6), 0, GFLAGS),
COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0,
@@ -338,14 +327,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
RK2928_CLKGATE_CON(3), 8, GFLAGS),
/* PD_PERI */
- GATE(0, "cpll_peri", "cpll", CLK_IGNORE_UNUSED,
- RK2928_CLKGATE_CON(2), 0, GFLAGS),
- GATE(0, "gpll_peri", "gpll", CLK_IGNORE_UNUSED,
+ COMPOSITE(0, "aclk_peri_src", mux_pll_src_3plls_p, 0,
+ RK2928_CLKSEL_CON(10), 10, 2, MFLAGS, 0, 5, DFLAGS,
RK2928_CLKGATE_CON(2), 0, GFLAGS),
- GATE(0, "hdmiphy_peri", "hdmiphy", CLK_IGNORE_UNUSED,
- RK2928_CLKGATE_CON(2), 0, GFLAGS),
- COMPOSITE_NOGATE(0, "aclk_peri_src", mux_aclk_peri_src_p, 0,
- RK2928_CLKSEL_CON(10), 10, 2, MFLAGS, 0, 5, DFLAGS),
COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0,
RK2928_CLKSEL_CON(10), 12, 3, DFLAGS,
RK2928_CLKGATE_CON(5), 2, GFLAGS),
@@ -380,7 +364,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
RK2928_CLKGATE_CON(10), 12, GFLAGS),
COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0,
- RK2928_CLKSEL_CON(23), 5, 2, MFLAGS, 0, 6, DFLAGS,
+ RK2928_CLKSEL_CON(23), 5, 2, MFLAGS, 0, 5, DFLAGS,
RK2928_CLKGATE_CON(2), 15, GFLAGS),
COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0,
@@ -403,12 +387,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
* Clock-Architecture Diagram 2
*/
- GATE(0, "gpll_vop", "gpll", 0,
- RK2928_CLKGATE_CON(3), 1, GFLAGS),
- GATE(0, "cpll_vop", "cpll", 0,
+ COMPOSITE_NODIV(0, "sclk_vop_src", mux_sclk_vop_src_p, 0,
+ RK2928_CLKSEL_CON(27), 0, 1, MFLAGS,
RK2928_CLKGATE_CON(3), 1, GFLAGS),
- MUX(0, "sclk_vop_src", mux_sclk_vop_src_p, 0,
- RK2928_CLKSEL_CON(27), 0, 1, MFLAGS),
DIV(DCLK_HDMI_PHY, "dclk_hdmiphy", "sclk_vop_src", 0,
RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
@@ -640,13 +621,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
/* PD_MMC */
MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1),
- MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 0),
+ MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 1),
MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3228_SDIO_CON0, 1),
- MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 0),
+ MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 1),
MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3228_EMMC_CON0, 1),
- MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0),
+ MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 1),
};
static const char *const rk3228_critical_clocks[] __initconst = {
@@ -661,6 +642,7 @@ static const char *const rk3228_critical_clocks[] __initconst = {
"aclk_vop_noc",
"aclk_hdcp_noc",
"hclk_vio_ahb_arbi",
+ "hclk_vio_h2p",
"hclk_vio_noc",
"hclk_vop_noc",
"hclk_host0_arb",
@@ -678,10 +660,13 @@ static const char *const rk3228_critical_clocks[] __initconst = {
"pclk_ddrphy",
"pclk_acodecphy",
"pclk_phy_noc",
+ "pclk_vio_h2p",
"aclk_vpu_noc",
"aclk_rkvdec_noc",
+ "aclk_rkvdec",
"hclk_vpu_noc",
"hclk_rkvdec_noc",
+ "hclk_rkvdec",
};
static void __init rk3228_clk_init(struct device_node *np)
diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
index d820ae03a..0ac87288b 100644
--- a/drivers/net/ethernet/arc/emac.h
+++ b/drivers/net/ethernet/arc/emac.h
@@ -91,6 +91,20 @@ struct arc_emac_bd {
#define RX_RING_SZ (RX_BD_NUM * sizeof(struct arc_emac_bd))
#define TX_RING_SZ (TX_BD_NUM * sizeof(struct arc_emac_bd))
+/* PHY fixups */
+#define RTL_8201F_PHY_ID 0x001cc816
+
+#define RTL_8201F_PG_SELECT_REG 0x1f
+#define RTL_8201F_PG4_EEE_REG 0x10
+#define RTL_8201F_PG4_EEE_RX_QUIET_EN BIT(8)
+#define RTL_8201F_PG4_EEE_TX_QUIET_EN BIT(9)
+#define RTL_8201F_PG4_EEE_NWAY_EN BIT(12)
+#define RTL_8201F_PG4_EEE_10M_CAP BIT(13)
+#define RTL_8201F_PG7_RMSR_REG 0x10
+#define RTL_8201F_PG7_RMSR_CLK_DIR_IN BIT(12)
+#define RTL_8201F_PG0_PSMR_REG 0x18
+#define RTL_8201F_PG0_PSMR_PWRSVE_EN BIT(15)
+
/**
* struct buffer_state - Stores Rx/Tx buffer state.
* @sk_buff: Pointer to socket buffer.
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index 67b8113a2..40332a976 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -140,7 +140,7 @@ static void arc_emac_tx_clean(struct net_device *ndev)
stats->tx_bytes += skb->len;
}
- dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr),
+ dma_unmap_single(ndev->dev.parent, dma_unmap_addr(tx_buff, addr),
dma_unmap_len(tx_buff, len), DMA_TO_DEVICE);
/* return the sk_buff to system */
@@ -223,9 +223,9 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
continue;
}
- addr = dma_map_single(&ndev->dev, (void *)skb->data,
+ addr = dma_map_single(ndev->dev.parent, (void *)skb->data,
EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(&ndev->dev, addr)) {
+ if (dma_mapping_error(ndev->dev.parent, addr)) {
if (net_ratelimit())
netdev_err(ndev, "cannot map dma buffer\n");
dev_kfree_skb(skb);
@@ -237,7 +237,7 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
}
/* unmap previosly mapped skb */
- dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
+ dma_unmap_single(ndev->dev.parent, dma_unmap_addr(rx_buff, addr),
dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
pktlen = info & LEN_MASK;
@@ -445,9 +445,9 @@ static int arc_emac_open(struct net_device *ndev)
if (unlikely(!rx_buff->skb))
return -ENOMEM;
- addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
+ addr = dma_map_single(ndev->dev.parent, (void *)rx_buff->skb->data,
EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(&ndev->dev, addr)) {
+ if (dma_mapping_error(ndev->dev.parent, addr)) {
netdev_err(ndev, "cannot dma map\n");
dev_kfree_skb(rx_buff->skb);
return -ENOMEM;
@@ -555,7 +555,7 @@ static void arc_free_tx_queue(struct net_device *ndev)
struct buffer_state *tx_buff = &priv->tx_buff[i];
if (tx_buff->skb) {
- dma_unmap_single(&ndev->dev,
+ dma_unmap_single(ndev->dev.parent,
dma_unmap_addr(tx_buff, addr),
dma_unmap_len(tx_buff, len),
DMA_TO_DEVICE);
@@ -586,7 +586,7 @@ static void arc_free_rx_queue(struct net_device *ndev)
struct buffer_state *rx_buff = &priv->rx_buff[i];
if (rx_buff->skb) {
- dma_unmap_single(&ndev->dev,
+ dma_unmap_single(ndev->dev.parent,
dma_unmap_addr(rx_buff, addr),
dma_unmap_len(rx_buff, len),
DMA_FROM_DEVICE);
@@ -692,10 +692,10 @@ static netdev_tx_t arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_BUSY;
}
- addr = dma_map_single(&ndev->dev, (void *)skb->data, len,
+ addr = dma_map_single(ndev->dev.parent, (void *)skb->data, len,
DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(&ndev->dev, addr))) {
+ if (unlikely(dma_mapping_error(ndev->dev.parent, addr))) {
stats->tx_dropped++;
stats->tx_errors++;
dev_kfree_skb_any(skb);
@@ -850,6 +850,62 @@ static const struct net_device_ops arc_emac_netdev_ops = {
#endif
};
+/**
+ * arc_emac_rtl8201f_phy_fixup
+ * @phydev: Pointer to phy_device structure.
+ *
+ * This function registers a fixup in case RTL8201F's phy
+ * clockout is used as reference for the mac interface
+ * and disable EEE, since emac can't handle it
+ */
+static int arc_emac_rtl8201f_phy_fixup(struct phy_device *phydev)
+{
+ unsigned int reg, curr_pg;
+ int err = 0;
+
+ curr_pg = phy_read(phydev, RTL_8201F_PG_SELECT_REG);
+ err = phy_write(phydev, RTL_8201F_PG_SELECT_REG, 4);
+ if (err)
+ goto out_err;
+ mdelay(10);
+
+ /* disable EEE */
+ reg = phy_read(phydev, RTL_8201F_PG4_EEE_REG);
+ reg &= ~RTL_8201F_PG4_EEE_RX_QUIET_EN &
+ ~RTL_8201F_PG4_EEE_TX_QUIET_EN &
+ ~RTL_8201F_PG4_EEE_NWAY_EN &
+ ~RTL_8201F_PG4_EEE_10M_CAP;
+ err = phy_write(phydev, RTL_8201F_PG4_EEE_REG, reg);
+ if (err)
+ goto out_err;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RMII) {
+ err = phy_write(phydev, RTL_8201F_PG_SELECT_REG, 7);
+ if (err)
+ goto out_err;
+ mdelay(10);
+
+ reg = phy_read(phydev, RTL_8201F_PG7_RMSR_REG);
+ err = phy_write(phydev, RTL_8201F_PG_SELECT_REG, 0);
+ if (err)
+ goto out_err;
+ mdelay(10);
+
+ if (!(reg & RTL_8201F_PG7_RMSR_CLK_DIR_IN)) {
+ /* disable powersave if phy's clock output is used */
+ reg = phy_read(phydev, RTL_8201F_PG0_PSMR_REG);
+ reg &= ~RTL_8201F_PG0_PSMR_PWRSVE_EN & 0xffff;
+ err = phy_write(phydev, RTL_8201F_PG0_PSMR_REG, reg);
+ }
+ }
+
+out_err:
+ phy_write(phydev, RTL_8201F_PG_SELECT_REG, curr_pg);
+ mdelay(10);
+
+ return err;
+};
+
int arc_emac_probe(struct net_device *ndev, int interface)
{
struct device *dev = ndev->dev.parent;
@@ -970,6 +1026,11 @@ int arc_emac_probe(struct net_device *ndev, int interface)
goto out_clken;
}
+ err = phy_register_fixup_for_uid(RTL_8201F_PHY_ID, 0xfffff0,
+ arc_emac_rtl8201f_phy_fixup);
+ if (err)
+ dev_warn(dev, "Cannot register PHY board fixup.\n");
+
phydev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0,
interface);
if (!phydev) {
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
index 1889e78e1..6209f51b3 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
@@ -237,6 +237,9 @@ struct inno_hdmi_phy {
struct clk *refoclk;
struct clk *refpclk;
+ /* phy_flag flag */
+ bool phy_flag;
+
/* platform data */
const struct inno_hdmi_phy_drv_data *plat_data;
int chip_version;
@@ -471,6 +474,7 @@ static const struct pre_pll_config pre_pll_cfg_table[] = {
static const struct post_pll_config post_pll_cfg_table[] = {
{33750000, 1, 40, 8, 1},
{33750000, 1, 80, 8, 2},
+ {33750000, 1, 10, 2, 4},
{74250000, 1, 40, 8, 1},
{74250000, 18, 80, 8, 2},
{148500000, 2, 40, 4, 3},
@@ -621,8 +625,11 @@ static int inno_hdmi_phy_power_on(struct phy *phy)
return -EINVAL;
for (; cfg->tmdsclock != 0; cfg++)
- if (tmdsclock <= cfg->tmdsclock &&
- cfg->version & inno->chip_version)
+ if (((!inno->phy_flag || tmdsclock > 33750000)
+ && tmdsclock <= cfg->tmdsclock
+ && cfg->version & inno->chip_version) ||
+ (inno->phy_flag && tmdsclock <= 33750000
+ && cfg->version & 4))
break;
for (; phy_cfg->tmdsclock != 0; phy_cfg++)
@@ -1033,6 +1040,10 @@ static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno)
static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno)
{
+ struct nvmem_cell *cell;
+ unsigned char *efuse_buf;
+ size_t len;
+
/*
* Use phy internal register control
* rxsense/poweron/pllpd/pdataen signal.
@@ -1047,7 +1058,28 @@ static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno)
inno_update_bits(inno, 0xaa, RK3228_POST_PLL_CTRL_MANUAL,
RK3228_POST_PLL_CTRL_MANUAL);
+
inno->chip_version = 1;
+ inno->phy_flag = false;
+
+ cell = nvmem_cell_get(inno->dev, "hdmi-phy-flag");
+ if (IS_ERR(cell)) {
+ if (PTR_ERR(cell) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ return 0;
+ }
+
+ efuse_buf = nvmem_cell_read(cell, &len);
+ nvmem_cell_put(cell);
+
+ if (IS_ERR(efuse_buf))
+ return 0;
+ if (len == 1)
+ inno->phy_flag = (efuse_buf[0] & BIT(1)) ? true : false;
+ kfree(efuse_buf);
+
+ dev_info(inno->dev, "phy_flag is: %d\n", inno->phy_flag);
return 0;
}
@@ -1147,6 +1179,8 @@ static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno)
/* try to read the chip-version */
inno->chip_version = 1;
+ inno->phy_flag = false;
+
cell = nvmem_cell_get(inno->dev, "cpu-version");
if (IS_ERR(cell)) {
if (PTR_ERR(cell) == -EPROBE_DEFER)
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
index fddb4022c..9583c76b4 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -73,6 +73,7 @@ struct rockchip_pm_domain {
struct regmap **qos_regmap;
u32 *qos_save_regs[MAX_QOS_REGS_NUM];
int num_clks;
+ bool is_ignore_pwr;
struct clk_bulk_data *clks;
};
@@ -361,6 +362,9 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain)
{
struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+ if (pd->is_ignore_pwr)
+ return 0;
+
return rockchip_pd_power(pd, true);
}
@@ -368,6 +372,9 @@ static int rockchip_pd_power_off(struct generic_pm_domain *domain)
{
struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+ if (pd->is_ignore_pwr)
+ return 0;
+
return rockchip_pd_power(pd, false);
}
@@ -447,6 +454,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
pd->info = pd_info;
pd->pmu = pmu;
+ if (!pd_info->pwr_mask)
+ pd->is_ignore_pwr = true;
+
pd->num_clks = of_clk_get_parent_count(node);
if (pd->num_clks > 0) {
pd->clks = devm_kcalloc(pmu->dev, pd->num_clks,
@@ -600,6 +610,7 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
{
struct device_node *np;
struct generic_pm_domain *child_domain, *parent_domain;
+ struct rockchip_pm_domain *child_pd, *parent_pd;
int error;
for_each_child_of_node(parent, np) {
@@ -640,6 +651,18 @@ static int rockchip_pm_add_subdomain(struct rockchip_pmu *pmu,
parent_domain->name, child_domain->name);
}
+ /*
+ * If child_pd doesn't do idle request or power on/off,
+ * parent_pd may fail to do power on/off, so if parent_pd
+ * need to power on/off, child_pd can't ignore to do idle
+ * request and power on/off.
+ */
+ child_pd = to_rockchip_pd(child_domain);
+ parent_pd = to_rockchip_pd(parent_domain);
+ if (!parent_pd->is_ignore_pwr)
+ child_pd->is_ignore_pwr = false;
+
+
rockchip_pm_add_subdomain(pmu, np);
}
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 272ae5722..cec178404 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -607,7 +607,7 @@ void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg)
* platforms on their host-only dwc2.
*/
if (!dwc2_hw_is_otg(hsotg))
- msleep(50);
+ msleep(200);
break;
case USB_DR_MODE_PERIPHERAL:
--
2.25.1

View File

@ -0,0 +1,12 @@
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 08011dc8c..4bee5c4cd 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -923,6 +923,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3228-evb.dtb \
rk3229-evb.dtb \
rk3229-xms6.dtb \
+ rk322x-box.dtb \
rk3288-evb-act8846.dtb \
rk3288-evb-rk808.dtb \
rk3288-firefly-beta.dtb \

View File

@ -0,0 +1,93 @@
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 48e6e8d44..1dfd27f9f 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -712,6 +712,22 @@ emmc: mmc@30020000 {
status = "disabled";
};
+ nfc: nand-controller@30030000 {
+ compatible = "rockchip,rk3228-nfc", "rockchip,rk2928-nfc";
+ reg = <0x30030000 0x4000>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_NANDC>, <&cru HCLK_NANDC>;
+ clock-names = "nfc", "ahb";
+ assigned-clocks = <&cru SCLK_NANDC>;
+ assigned-clock-rates = <150000000>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&flash_cs0 &flash_rdy &flash_ale &flash_cle
+ &flash_wrn &flash_rdn &flash_bus8>;
+ status = "disabled";
+
+ };
+
usb_otg: usb@30040000 {
compatible = "rockchip,rk3228-usb", "rockchip,rk3066-usb",
"snps,dwc2";
@@ -950,6 +966,65 @@ emmc_bus8: emmc-bus8 {
};
};
+ flash {
+
+ flash_cs0: flash-cs0 {
+ rockchip,pins = <2 RK_PA6 1 &pcfg_pull_up>;
+ };
+
+ flash_cs1: flash-cs1 {
+ rockchip,pins = <0 RK_PC7 1 &pcfg_pull_up>;
+ };
+
+ flash_cs2: flash-cs2 {
+ rockchip,pins = <1 RK_PC6 1 &pcfg_pull_up>;
+ };
+
+ flash_cs3: flash-cs3 {
+ rockchip,pins = <1 RK_PC7 1 &pcfg_pull_up>;
+ };
+
+ flash_rdy: flash-rdy {
+ rockchip,pins = <2 RK_PA4 1 &pcfg_pull_up>;
+ };
+
+ flash_ale: flash-ale {
+ rockchip,pins = <2 RK_PA0 1 &pcfg_pull_down>;
+ };
+
+ flash_cle: flash-cle {
+ rockchip,pins = <2 RK_PA1 1 &pcfg_pull_down>;
+ };
+
+ flash_wrn: flash-wrn {
+ rockchip,pins = <2 RK_PA2 1 &pcfg_pull_up>;
+ };
+
+ flash_rdn: flash-rdn {
+ rockchip,pins = <2 RK_PA3 1 &pcfg_pull_up>;
+ };
+
+ flash_bus8: flash-bus8 {
+ rockchip,pins = <1 RK_PD0 1 &pcfg_pull_up>,
+ <1 RK_PD1 1 &pcfg_pull_up>,
+ <1 RK_PD2 1 &pcfg_pull_up>,
+ <1 RK_PD3 1 &pcfg_pull_up>,
+ <1 RK_PD4 1 &pcfg_pull_up>,
+ <1 RK_PD5 1 &pcfg_pull_up>,
+ <1 RK_PD6 1 &pcfg_pull_up>,
+ <1 RK_PD7 1 &pcfg_pull_up>;
+ };
+
+ flash_dqs: flash-dqs {
+ rockchip,pins = <2 RK_PA7 1 &pcfg_pull_up>;
+ };
+
+ flash_wp: flash-wp {
+ rockchip,pins = <2 RK_PA5 1 &pcfg_pull_down>;
+ };
+
+ };
+
gmac {
rgmii_pins: rgmii-pins {
rockchip,pins = <2 RK_PB6 1 &pcfg_pull_none>,

View File

@ -0,0 +1,66 @@
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 73d24c6bbf05..d4ac6e161ef2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -614,6 +614,44 @@ static const struct vop_common rk3288_common = {
.dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0),
};
+static const struct vop_win_phy rk3228_win0_data = {
+ .scl = &rk3288_win_full_scl,
+ .data_formats = formats_win_full,
+ .nformats = ARRAY_SIZE(formats_win_full),
+ .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
+ .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
+ .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
+ .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
+ .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
+ .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
+ .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
+ .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
+ .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
+ .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
+ .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
+ .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
+};
+
+static const struct vop_win_phy rk3228_win1_data = {
+ .scl = &rk3288_win_full_scl,
+ .data_formats = formats_win_lite,
+ .nformats = ARRAY_SIZE(formats_win_lite),
+ .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
+ .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
+ .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
+ .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
+ .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
+ .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
+ .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
+ .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
+ .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
+ .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
+ .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
+ .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
+};
+
/*
* Note: rk3288 has a dedicated 'cursor' window, however, that window requires
* special support to get alpha blending working. For now, just use overlay
@@ -864,10 +902,10 @@ static const struct vop_data rk3399_vop_lit = {
};
static const struct vop_win_data rk3228_vop_win_data[] = {
- { .base = 0x00, .phy = &rk3288_win01_data,
+ { .base = 0x00, .phy = &rk3228_win0_data,
.type = DRM_PLANE_TYPE_PRIMARY },
- { .base = 0x40, .phy = &rk3288_win01_data,
- .type = DRM_PLANE_TYPE_CURSOR },
+ { .base = 0x40, .phy = &rk3228_win1_data,
+ .type = DRM_PLANE_TYPE_OVERLAY },
};
static const struct vop_data rk3228_vop = {
--
2.17.1

View File

@ -0,0 +1,34 @@
From adecdd57a0155e0d96af2c84cc4fa52309fbb535 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Thu, 9 Sep 2021 19:14:08 +0000
Subject: [PATCH] add iep node for rk322x
---
arch/arm/boot/dts/rk322x.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 0ae753c1d..271e7835f 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -834,6 +834,17 @@ rga: rga@20060000 {
reset-names = "core", "axi", "ahb";
};
+ iep: iep@20070000 {
+ compatible = "rockchip,rk3228-iep";
+ reg = <0x20070000 0x800>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>;
+ clock-names = "axi", "ahb";
+ iommus = <&iep_mmu>;
+ power-domains = <&power RK3228_PD_VIO>;
+ status = "disabled";
+ };
+
iep_mmu: iommu@20070800 {
compatible = "rockchip,iommu";
reg = <0x20070800 0x100>;
--
2.25.1

View File

@ -0,0 +1,44 @@
From 2d42546642fa4299d88fa4ae414fa1ab205dad70 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Sat, 11 Sep 2021 17:38:48 +0000
Subject: [PATCH] rk322x: enable YUV modes for win1, 10-bit for win0/win1
---
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 70930b410..3fd00b323 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -719,10 +719,11 @@ static const struct vop_common rk3288_common = {
static const struct vop_win_phy rk3228_win0_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_full,
- .nformats = ARRAY_SIZE(formats_win_full),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
@@ -738,10 +739,11 @@ static const struct vop_win_phy rk3228_win0_data = {
static const struct vop_win_phy rk3228_win1_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_lite,
- .nformats = ARRAY_SIZE(formats_win_lite),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
--
2.25.1

View File

@ -0,0 +1,913 @@
From b4f40590a4f946d8ee704faf8579930e53ef4650 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Sun, 12 Sep 2021 10:15:56 +0000
Subject: [PATCH] rk322x: analog audio codec
---
.../bindings/sound/rockchip,rk3228-codec.txt | 22 +
arch/arm/boot/dts/rk322x.dtsi | 9 +
drivers/clk/rockchip/clk-rk3228.c | 2 +-
include/dt-bindings/clock/rk3228-cru.h | 1 +
sound/soc/codecs/Kconfig | 5 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/rk3228_codec.c | 545 ++++++++++++++++++
sound/soc/codecs/rk3228_codec.h | 218 +++++++
8 files changed, 803 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt
create mode 100644 sound/soc/codecs/rk3228_codec.c
create mode 100644 sound/soc/codecs/rk3228_codec.h
diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt
new file mode 100644
index 000000000..9191a8593
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip,rk3228-codec.txt
@@ -0,0 +1,22 @@
+* Rockchip Rk3228 internal codec
+
+Required properties:
+
+- compatible: "rockchip,rk3228-codec"
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names.
+- clock-names: a list of clock names, one for each entry in clocks.
+- spk-en-gpio: speaker enable gpio.
+- spk-depop-time-ms: speaker depop time msec.
+
+Example for rk3228 internal codec:
+
+codec: codec@12010000 {
+ compatible = "rockchip,rk3228-codec";
+ reg = <0x12010000 0x1000>;
+ clocks = <&cru SCLK_I2S_OUT>, <&cru PCLK_ACODECPHY>, <&cru SCLK_I2S1>;
+ clock-names = "mclk", "pclk", "sclk";
+ spk-en-gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 75af99c76..c2670d498 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -145,6 +145,15 @@ i2s1: i2s1@100b0000 {
status = "disabled";
};
+ codec: codec@12010000 {
+ compatible = "rockchip,rk3228-codec";
+ reg = <0x12010000 0x1000>;
+ clocks = <&cru SCLK_I2S_OUT>, <&cru PCLK_ACODECPHY>, <&cru SCLK_I2S1>;
+ clock-names = "mclk", "pclk", "sclk";
+ spk-en-gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
i2s0: i2s0@100c0000 {
compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s";
reg = <0x100c0000 0x4000>;
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
index a24a35553..69f8c792f 100644
--- a/drivers/clk/rockchip/clk-rk3228.c
+++ b/drivers/clk/rockchip/clk-rk3228.c
@@ -620,7 +620,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
GATE(0, "pclk_sim", "pclk_cpu", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS),
GATE(0, "pclk_ddrphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS),
- GATE(0, "pclk_acodecphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 5, GFLAGS),
+ GATE(PCLK_ACODECPHY, "pclk_acodecphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 5, GFLAGS),
GATE(PCLK_HDMI_PHY, "pclk_hdmiphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 7, GFLAGS),
GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS),
GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS),
diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h
index de550ea56..30d44ce90 100644
--- a/include/dt-bindings/clock/rk3228-cru.h
+++ b/include/dt-bindings/clock/rk3228-cru.h
@@ -115,6 +115,7 @@
#define PCLK_HDMI_CTRL 364
#define PCLK_HDMI_PHY 365
#define PCLK_GMAC 367
+#define PCLK_ACODECPHY 368
/* hclk gates */
#define HCLK_I2S0_8CH 442
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index db1607120..5f7f01102 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -154,6 +154,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_PCM5102A
imply SND_SOC_PCM512x_I2C
imply SND_SOC_PCM512x_SPI
+ imply SND_SOC_RK3228
imply SND_SOC_RK3328
imply SND_SOC_RK817
imply SND_SOC_RT274
@@ -1063,6 +1064,10 @@ config SND_SOC_PCM512x_SPI
select SND_SOC_PCM512x
select REGMAP_SPI
+config SND_SOC_RK3228
+ select REGMAP_MMIO
+ tristate "Rockchip RK3228 CODEC"
+
config SND_SOC_RK3328
tristate "Rockchip RK3328 audio CODEC"
select REGMAP_MMIO
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 7bb38c370..232b5c43e 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -165,6 +165,7 @@ snd-soc-pcm5102a-objs := pcm5102a.o
snd-soc-pcm512x-objs := pcm512x.o
snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
+snd-soc-rk3228-objs := rk3228_codec.o
snd-soc-rk3328-objs := rk3328_codec.o
snd-soc-rk817-objs := rk817_codec.o
snd-soc-rl6231-objs := rl6231.o
@@ -491,6 +492,7 @@ obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o
obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
+obj-$(CONFIG_SND_SOC_RK3228) += snd-soc-rk3228.o
obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o
obj-$(CONFIG_SND_SOC_RK817) += snd-soc-rk817.o
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
diff --git a/sound/soc/codecs/rk3228_codec.c b/sound/soc/codecs/rk3228_codec.c
new file mode 100644
index 000000000..b65307435
--- /dev/null
+++ b/sound/soc/codecs/rk3228_codec.c
@@ -0,0 +1,545 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// rk3228_codec.c -- rk3228 ALSA Soc Audio driver
+//
+// Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
+#include "rk3228_codec.h"
+
+/*
+ * volume setting
+ * 0: -39dB
+ * 26: 0dB
+ * 31: 6dB
+ * Step: 1.5dB
+ */
+#define OUT_VOLUME (0x18)
+#define INITIAL_FREQ (11289600)
+
+struct rk3228_codec_priv {
+ struct regmap *regmap;
+ struct clk *mclk;
+ struct clk *pclk;
+ struct clk *sclk;
+ struct gpio_desc *spk_en_gpio;
+ int spk_depop_time; /* msec */
+};
+
+static const struct reg_default rk3228_codec_reg_defaults[] = {
+ { CODEC_RESET, 0x03 },
+ { DAC_INIT_CTRL1, 0x00 },
+ { DAC_INIT_CTRL2, 0x50 },
+ { DAC_INIT_CTRL3, 0x0e },
+ { DAC_PRECHARGE_CTRL, 0x01 },
+ { DAC_PWR_CTRL, 0x00 },
+ { DAC_CLK_CTRL, 0x00 },
+ { HPMIX_CTRL, 0x00 },
+ { HPOUT_CTRL, 0x00 },
+ { HPOUTL_GAIN_CTRL, 0x00 },
+ { HPOUTR_GAIN_CTRL, 0x00 },
+ { HPOUT_POP_CTRL, 0x11 },
+};
+
+static int rk3228_codec_reset(struct snd_soc_component *component)
+{
+ struct rk3228_codec_priv *rk3228 = snd_soc_component_get_drvdata(component);
+
+ regmap_write(rk3228->regmap, CODEC_RESET, 0);
+ mdelay(10);
+ regmap_write(rk3228->regmap, CODEC_RESET, 0x03);
+
+ return 0;
+}
+
+static int rk3228_set_dai_fmt(struct snd_soc_dai *dai,
+ unsigned int fmt)
+{
+ struct snd_soc_component *component = dai->component;
+ struct rk3228_codec_priv *rk3228 = snd_soc_component_get_drvdata(component);
+ unsigned int val = 0;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ val |= PIN_DIRECTION_IN | DAC_I2S_MODE_SLAVE;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ val |= PIN_DIRECTION_OUT | DAC_I2S_MODE_MASTER;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap_update_bits(rk3228->regmap, DAC_INIT_CTRL1,
+ PIN_DIRECTION_MASK | DAC_I2S_MODE_MASK, val);
+
+ val = 0;
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_DSP_B:
+ val |= DAC_MODE_PCM;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ val |= DAC_MODE_I2S;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ val |= DAC_MODE_RJM;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ val |= DAC_MODE_LJM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap_update_bits(rk3228->regmap, DAC_INIT_CTRL2,
+ DAC_MODE_MASK, val);
+ return 0;
+}
+
+static void rk3228_analog_output(struct rk3228_codec_priv *rk3228, int mute)
+{
+ if (rk3228->spk_en_gpio)
+ gpiod_set_value(rk3228->spk_en_gpio, mute);
+}
+
+static int rk3228_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
+{
+ struct snd_soc_component *component = dai->component;
+ struct rk3228_codec_priv *rk3228 = snd_soc_component_get_drvdata(component);
+ unsigned int val = 0;
+
+ if (direction != SNDRV_PCM_STREAM_PLAYBACK)
+ return 0;
+
+ if (mute)
+ val = HPOUTL_MUTE | HPOUTR_MUTE;
+ else
+ val = HPOUTL_UNMUTE | HPOUTR_UNMUTE;
+
+ regmap_update_bits(rk3228->regmap, HPOUT_CTRL,
+ HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK, val);
+ return 0;
+}
+
+static int rk3228_codec_power_on(struct snd_soc_component *component, int wait_ms)
+{
+ struct rk3228_codec_priv *rk3228 = snd_soc_component_get_drvdata(component);
+
+ regmap_update_bits(rk3228->regmap, DAC_PRECHARGE_CTRL,
+ DAC_CHARGE_XCHARGE_MASK, DAC_CHARGE_PRECHARGE);
+ mdelay(10);
+ regmap_update_bits(rk3228->regmap, DAC_PRECHARGE_CTRL,
+ DAC_CHARGE_CURRENT_ALL_MASK,
+ DAC_CHARGE_CURRENT_ALL_ON);
+
+ mdelay(wait_ms);
+
+ return 0;
+}
+
+static int rk3228_codec_power_off(struct snd_soc_component *component, int wait_ms)
+{
+ struct rk3228_codec_priv *rk3228 = snd_soc_component_get_drvdata(component);
+
+ regmap_update_bits(rk3228->regmap, DAC_PRECHARGE_CTRL,
+ DAC_CHARGE_XCHARGE_MASK, DAC_CHARGE_DISCHARGE);
+ mdelay(10);
+ regmap_update_bits(rk3228->regmap, DAC_PRECHARGE_CTRL,
+ DAC_CHARGE_CURRENT_ALL_MASK,
+ DAC_CHARGE_CURRENT_ALL_ON);
+
+ mdelay(wait_ms);
+
+ return 0;
+}
+
+static struct rk3228_reg_msk_val playback_open_list[] = {
+ { DAC_PWR_CTRL, DAC_PWR_MASK, DAC_PWR_ON },
+ { DAC_PWR_CTRL, DACL_PATH_REFV_MASK | DACR_PATH_REFV_MASK,
+ DACL_PATH_REFV_ON | DACR_PATH_REFV_ON },
+ { DAC_PWR_CTRL, HPOUTL_ZERO_CROSSING_ON | HPOUTR_ZERO_CROSSING_ON,
+ HPOUTL_ZERO_CROSSING_ON | HPOUTR_ZERO_CROSSING_ON },
+ { HPOUT_POP_CTRL, HPOUTR_POP_MASK | HPOUTL_POP_MASK,
+ HPOUTR_POP_WORK | HPOUTL_POP_WORK },
+ { HPMIX_CTRL, HPMIXL_MASK | HPMIXR_MASK, HPMIXL_EN | HPMIXR_EN },
+ { HPMIX_CTRL, HPMIXL_INIT_MASK | HPMIXR_INIT_MASK,
+ HPMIXL_INIT_EN | HPMIXR_INIT_EN },
+ { HPOUT_CTRL, HPOUTL_MASK | HPOUTR_MASK, HPOUTL_EN | HPOUTR_EN },
+ { HPOUT_CTRL, HPOUTL_INIT_MASK | HPOUTR_INIT_MASK,
+ HPOUTL_INIT_EN | HPOUTR_INIT_EN },
+ { DAC_CLK_CTRL, DACL_REFV_MASK | DACR_REFV_MASK,
+ DACL_REFV_ON | DACR_REFV_ON },
+ { DAC_CLK_CTRL, DACL_CLK_MASK | DACR_CLK_MASK,
+ DACL_CLK_ON | DACR_CLK_ON },
+ { DAC_CLK_CTRL, DACL_MASK | DACR_MASK, DACL_ON | DACR_ON },
+ { DAC_CLK_CTRL, DACL_INIT_MASK | DACR_INIT_MASK,
+ DACL_INIT_ON | DACR_INIT_ON },
+ { DAC_SELECT, DACL_SELECT_MASK | DACR_SELECT_MASK,
+ DACL_SELECT | DACR_SELECT },
+ { HPMIX_CTRL, HPMIXL_INIT2_MASK | HPMIXR_INIT2_MASK,
+ HPMIXL_INIT2_EN | HPMIXR_INIT2_EN },
+ { HPOUT_CTRL, HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK,
+ HPOUTL_UNMUTE | HPOUTR_UNMUTE },
+};
+
+#define PLAYBACK_OPEN_LIST_LEN ARRAY_SIZE(playback_open_list)
+
+static int rk3228_codec_open_playback(struct snd_soc_component *component)
+{
+ struct rk3228_codec_priv *rk3228 = snd_soc_component_get_drvdata(component);
+ int i = 0;
+
+ regmap_update_bits(rk3228->regmap, DAC_PRECHARGE_CTRL,
+ DAC_CHARGE_CURRENT_ALL_MASK,
+ DAC_CHARGE_CURRENT_I);
+
+ for (i = 0; i < PLAYBACK_OPEN_LIST_LEN; i++) {
+ regmap_update_bits(rk3228->regmap,
+ playback_open_list[i].reg,
+ playback_open_list[i].msk,
+ playback_open_list[i].val);
+ mdelay(1);
+ }
+
+ msleep(rk3228->spk_depop_time);
+ rk3228_analog_output(rk3228, 1);
+
+ regmap_update_bits(rk3228->regmap, HPOUTL_GAIN_CTRL,
+ HPOUTL_GAIN_MASK, OUT_VOLUME);
+ regmap_update_bits(rk3228->regmap, HPOUTR_GAIN_CTRL,
+ HPOUTR_GAIN_MASK, OUT_VOLUME);
+ return 0;
+}
+
+static struct rk3228_reg_msk_val playback_close_list[] = {
+ { HPMIX_CTRL, HPMIXL_INIT2_MASK | HPMIXR_INIT2_MASK,
+ HPMIXL_INIT2_DIS | HPMIXR_INIT2_DIS },
+ { DAC_SELECT, DACL_SELECT_MASK | DACR_SELECT_MASK,
+ DACL_DESELECT | DACR_DESELECT },
+ { HPOUT_CTRL, HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK,
+ HPOUTL_MUTE | HPOUTR_MUTE },
+ { HPOUT_CTRL, HPOUTL_INIT_MASK | HPOUTR_INIT_MASK,
+ HPOUTL_INIT_DIS | HPOUTR_INIT_DIS },
+ { HPOUT_CTRL, HPOUTL_MASK | HPOUTR_MASK, HPOUTL_DIS | HPOUTR_DIS },
+ { HPMIX_CTRL, HPMIXL_MASK | HPMIXR_MASK, HPMIXL_DIS | HPMIXR_DIS },
+ { DAC_CLK_CTRL, DACL_MASK | DACR_MASK, DACL_OFF | DACR_OFF },
+ { DAC_CLK_CTRL, DACL_CLK_MASK | DACR_CLK_MASK,
+ DACL_CLK_OFF | DACR_CLK_OFF },
+ { DAC_CLK_CTRL, DACL_REFV_MASK | DACR_REFV_MASK,
+ DACL_REFV_OFF | DACR_REFV_OFF },
+ { HPOUT_POP_CTRL, HPOUTR_POP_MASK | HPOUTL_POP_MASK,
+ HPOUTR_POP_XCHARGE | HPOUTL_POP_XCHARGE },
+ { DAC_PWR_CTRL, DACL_PATH_REFV_MASK | DACR_PATH_REFV_MASK,
+ DACL_PATH_REFV_OFF | DACR_PATH_REFV_OFF },
+ { DAC_PWR_CTRL, DAC_PWR_MASK, DAC_PWR_OFF },
+ { HPMIX_CTRL, HPMIXL_INIT_MASK | HPMIXR_INIT_MASK,
+ HPMIXL_INIT_DIS | HPMIXR_INIT_DIS },
+ { DAC_CLK_CTRL, DACL_INIT_MASK | DACR_INIT_MASK,
+ DACL_INIT_OFF | DACR_INIT_OFF },
+};
+
+#define PLAYBACK_CLOSE_LIST_LEN ARRAY_SIZE(playback_close_list)
+
+static int rk3228_codec_close_playback(struct snd_soc_component *component)
+{
+ struct rk3228_codec_priv *rk3228 = snd_soc_component_get_drvdata(component);
+ int i = 0;
+
+ rk3228_analog_output(rk3228, 0);
+
+ regmap_update_bits(rk3228->regmap, HPOUTL_GAIN_CTRL,
+ HPOUTL_GAIN_MASK, 0);
+ regmap_update_bits(rk3228->regmap, HPOUTR_GAIN_CTRL,
+ HPOUTR_GAIN_MASK, 0);
+
+ for (i = 0; i < PLAYBACK_CLOSE_LIST_LEN; i++) {
+ regmap_update_bits(rk3228->regmap,
+ playback_close_list[i].reg,
+ playback_close_list[i].msk,
+ playback_close_list[i].val);
+ mdelay(1);
+ }
+
+ regmap_update_bits(rk3228->regmap, DAC_PRECHARGE_CTRL,
+ DAC_CHARGE_CURRENT_ALL_MASK,
+ DAC_CHARGE_CURRENT_I);
+ return 0;
+}
+
+static int rk3228_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_component *component = dai->component;
+ struct rk3228_codec_priv *rk3228 = snd_soc_component_get_drvdata(component);
+ unsigned int val = 0;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ val |= DAC_VDL_16BITS;
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ val |= DAC_VDL_20BITS;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ val |= DAC_VDL_24BITS;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ val |= DAC_VDL_32BITS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap_update_bits(rk3228->regmap, DAC_INIT_CTRL2, DAC_VDL_MASK, val);
+ val = DAC_WL_32BITS | DAC_RST_DIS;
+ regmap_update_bits(rk3228->regmap, DAC_INIT_CTRL3,
+ DAC_WL_MASK | DAC_RST_MASK, val);
+
+ return 0;
+}
+
+static int rk3228_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_component *component = dai->component;
+
+ return rk3228_codec_open_playback(component);
+}
+
+static void rk3228_pcm_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_component *component = dai->component;
+
+ rk3228_codec_close_playback(component);
+}
+
+static struct snd_soc_dai_ops rk3228_dai_ops = {
+ .hw_params = rk3228_hw_params,
+ .set_fmt = rk3228_set_dai_fmt,
+ .mute_stream = rk3228_mute_stream,
+ .startup = rk3228_pcm_startup,
+ .shutdown = rk3228_pcm_shutdown,
+};
+
+static struct snd_soc_dai_driver rk3228_dai[] = {
+ {
+ .name = "rk3228-hifi",
+ .id = RK3228_HIFI,
+ .playback = {
+ .stream_name = "HIFI Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S20_3LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ },
+ /*.capture = {
+ .stream_name = "HIFI Capture",
+ .channels_min = 2,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S20_3LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ },*/
+ .ops = &rk3228_dai_ops,
+ },
+};
+
+static int rk3228_codec_probe(struct snd_soc_component *component)
+{
+ rk3228_codec_reset(component);
+ rk3228_codec_power_on(component, 0);
+
+ return 0;
+}
+
+static void rk3228_codec_remove(struct snd_soc_component *component)
+{
+ rk3228_codec_close_playback(component);
+ rk3228_codec_power_off(component, 0);
+}
+
+static struct snd_soc_component_driver soc_codec_dev_rk3228 = {
+ .probe = rk3228_codec_probe,
+ .remove = rk3228_codec_remove,
+};
+
+static bool rk3228_codec_write_read_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CODEC_RESET:
+ case DAC_INIT_CTRL1:
+ case DAC_INIT_CTRL2:
+ case DAC_INIT_CTRL3:
+ case DAC_PRECHARGE_CTRL:
+ case DAC_PWR_CTRL:
+ case DAC_CLK_CTRL:
+ case HPMIX_CTRL:
+ case DAC_SELECT:
+ case HPOUT_CTRL:
+ case HPOUTL_GAIN_CTRL:
+ case HPOUTR_GAIN_CTRL:
+ case HPOUT_POP_CTRL:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool rk3228_codec_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CODEC_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config rk3228_codec_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = HPOUT_POP_CTRL,
+ .writeable_reg = rk3228_codec_write_read_reg,
+ .readable_reg = rk3228_codec_write_read_reg,
+ .volatile_reg = rk3228_codec_volatile_reg,
+ .reg_defaults = rk3228_codec_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(rk3228_codec_reg_defaults),
+ .cache_type = REGCACHE_FLAT,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id rk3228codec_of_match[] = {
+ { .compatible = "rockchip,rk3228-codec", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rk3228codec_of_match);
+#endif
+
+static int rk3228_platform_probe(struct platform_device *pdev)
+{
+ struct device_node *rk3228_np = pdev->dev.of_node;
+ struct rk3228_codec_priv *rk3228;
+ struct resource *res;
+ void __iomem *base;
+ int ret = 0;
+
+ rk3228 = devm_kzalloc(&pdev->dev, sizeof(*rk3228), GFP_KERNEL);
+ if (!rk3228)
+ return -ENOMEM;
+
+ rk3228->mclk = devm_clk_get(&pdev->dev, "mclk");
+ if (PTR_ERR(rk3228->mclk) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ rk3228->pclk = devm_clk_get(&pdev->dev, "pclk");
+ if (IS_ERR(rk3228->pclk))
+ return PTR_ERR(rk3228->pclk);
+
+ rk3228->sclk = devm_clk_get(&pdev->dev, "sclk");
+ if (IS_ERR(rk3228->sclk))
+ return PTR_ERR(rk3228->sclk);
+
+ rk3228->spk_en_gpio = devm_gpiod_get_optional(&pdev->dev,
+ "spk-en",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(rk3228->spk_en_gpio))
+ return PTR_ERR(rk3228->spk_en_gpio);
+
+ ret = of_property_read_u32(rk3228_np, "spk-depop-time-ms",
+ &rk3228->spk_depop_time);
+ if (ret < 0) {
+ dev_info(&pdev->dev, "spk_depop_time use default value.\n");
+ rk3228->spk_depop_time = 100;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ ret = clk_prepare_enable(rk3228->mclk);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(rk3228->pclk);
+ if (ret < 0)
+ goto err_pclk;
+
+ ret = clk_prepare_enable(rk3228->sclk);
+ if (ret)
+ goto err_sclk;
+
+ clk_set_rate(rk3228->sclk, INITIAL_FREQ);
+
+ rk3228->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+ &rk3228_codec_regmap_config);
+ if (IS_ERR(rk3228->regmap)) {
+ ret = PTR_ERR(rk3228->regmap);
+ goto err_clk;
+ }
+
+ platform_set_drvdata(pdev, rk3228);
+
+ ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_rk3228,
+ rk3228_dai, ARRAY_SIZE(rk3228_dai));
+ if (!ret)
+ return 0;
+
+err_clk:
+ clk_disable_unprepare(rk3228->sclk);
+err_sclk:
+ clk_disable_unprepare(rk3228->pclk);
+err_pclk:
+ clk_disable_unprepare(rk3228->mclk);
+
+ return ret;
+}
+
+static int rk3228_platform_remove(struct platform_device *pdev)
+{
+ struct rk3228_codec_priv *rk3228 = platform_get_drvdata(pdev);
+
+ if (!IS_ERR(rk3228->mclk))
+ clk_disable_unprepare(rk3228->mclk);
+
+ if (!IS_ERR(rk3228->pclk))
+ clk_disable_unprepare(rk3228->pclk);
+
+ if (!IS_ERR(rk3228->sclk))
+ clk_disable_unprepare(rk3228->sclk);
+
+ return 0;
+}
+
+static struct platform_driver rk3228_codec_driver = {
+ .driver = {
+ .name = "rk3228-codec",
+ .of_match_table = of_match_ptr(rk3228codec_of_match),
+ },
+ .probe = rk3228_platform_probe,
+ .remove = rk3228_platform_remove,
+};
+module_platform_driver(rk3228_codec_driver);
+
+MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
+MODULE_DESCRIPTION("ASoC rk3228 codec driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rk3228_codec.h b/sound/soc/codecs/rk3228_codec.h
new file mode 100644
index 000000000..7283d0ba8
--- /dev/null
+++ b/sound/soc/codecs/rk3228_codec.h
@@ -0,0 +1,218 @@
+/*
+ * rk3228_codec.h -- rk3228 ALSA Soc Audio driver
+ *
+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef _RK3228_CODEC_H
+#define _RK3228_CODEC_H
+
+/* codec register */
+#define CODEC_RESET (0x00 << 2)
+#define DAC_INIT_CTRL1 (0x03 << 2)
+#define DAC_INIT_CTRL2 (0x04 << 2)
+#define DAC_INIT_CTRL3 (0x05 << 2)
+#define DAC_PRECHARGE_CTRL (0x22 << 2)
+#define DAC_PWR_CTRL (0x23 << 2)
+#define DAC_CLK_CTRL (0x24 << 2)
+#define HPMIX_CTRL (0x25 << 2)
+#define DAC_SELECT (0x26 << 2)
+#define HPOUT_CTRL (0x27 << 2)
+#define HPOUTL_GAIN_CTRL (0x28 << 2)
+#define HPOUTR_GAIN_CTRL (0x29 << 2)
+#define HPOUT_POP_CTRL (0x2a << 2)
+
+/* REG00: CODEC_RESET */
+#define PWR_RST_BYPASS_DIS BIT(6)
+#define PWR_RST_BYPASS_EN BIT(6)
+#define DIG_CORE_RST (0 << 1)
+#define DIG_CORE_WORK BIT(1)
+#define SYS_RST (0)
+#define SYS_WORK BIT(0)
+
+/* REG03: DAC_INIT_CTRL1 */
+#define PIN_DIRECTION_MASK BIT(5)
+#define PIN_DIRECTION_IN (0 << 5)
+#define PIN_DIRECTION_OUT BIT(5)
+#define DAC_I2S_MODE_MASK BIT(4)
+#define DAC_I2S_MODE_SLAVE (0 << 4)
+#define DAC_I2S_MODE_MASTER BIT(4)
+
+/* REG04: DAC_INIT_CTRL2 */
+#define DAC_I2S_LRP_MASK BIT(7)
+#define DAC_I2S_LRP_NORMAL (0 << 7)
+#define DAC_I2S_LRP_REVERSAL BIT(7)
+#define DAC_VDL_MASK (3 << 5)
+#define DAC_VDL_16BITS (0 << 5)
+#define DAC_VDL_20BITS BIT(5)
+#define DAC_VDL_24BITS (2 << 5)
+#define DAC_VDL_32BITS (3 << 5)
+#define DAC_MODE_MASK (3 << 3)
+#define DAC_MODE_RJM (0 << 3)
+#define DAC_MODE_LJM BIT(3)
+#define DAC_MODE_I2S (2 << 3)
+#define DAC_MODE_PCM (3 << 3)
+#define DAC_LR_SWAP_MASK BIT(2)
+#define DAC_LR_SWAP_DIS (0 << 2)
+#define DAC_LR_SWAP_EN BIT(2)
+
+/* REG05: DAC_INIT_CTRL3 */
+#define DAC_WL_MASK (3 << 2)
+#define DAC_WL_16BITS (0 << 2)
+#define DAC_WL_20BITS BIT(2)
+#define DAC_WL_24BITS (2 << 2)
+#define DAC_WL_32BITS (3 << 2)
+#define DAC_RST_MASK BIT(1)
+#define DAC_RST_EN (0 << 1)
+#define DAC_RST_DIS BIT(1)
+#define DAC_BCP_MASK BIT(0)
+#define DAC_BCP_NORMAL (0 << 0)
+#define DAC_BCP_REVERSAL BIT(0)
+
+/* REG22: DAC_PRECHARGE_CTRL */
+#define DAC_CHARGE_PRECHARGE BIT(7)
+#define DAC_CHARGE_DISCHARGE (0 << 7)
+#define DAC_CHARGE_XCHARGE_MASK BIT(7)
+#define DAC_CHARGE_CURRENT_64I BIT(6)
+#define DAC_CHARGE_CURRENT_64I_MASK BIT(6)
+#define DAC_CHARGE_CURRENT_32I BIT(5)
+#define DAC_CHARGE_CURRENT_32I_MASK BIT(5)
+#define DAC_CHARGE_CURRENT_16I BIT(4)
+#define DAC_CHARGE_CURRENT_16I_MASK BIT(4)
+#define DAC_CHARGE_CURRENT_08I BIT(3)
+#define DAC_CHARGE_CURRENT_08I_MASK BIT(3)
+#define DAC_CHARGE_CURRENT_04I BIT(2)
+#define DAC_CHARGE_CURRENT_04I_MASK BIT(2)
+#define DAC_CHARGE_CURRENT_02I BIT(1)
+#define DAC_CHARGE_CURRENT_02I_MASK BIT(1)
+#define DAC_CHARGE_CURRENT_I BIT(0)
+#define DAC_CHARGE_CURRENT_I_MASK BIT(0)
+#define DAC_CHARGE_CURRENT_ALL_MASK (0x7f)
+#define DAC_CHARGE_CURRENT_ALL_OFF (0x0)
+#define DAC_CHARGE_CURRENT_ALL_ON (0x7f)
+
+/* REG23: DAC_PWR_CTRL */
+#define DAC_PWR_OFF (0 << 6)
+#define DAC_PWR_ON BIT(6)
+#define DAC_PWR_MASK BIT(6)
+#define DACL_PATH_REFV_OFF (0 << 5)
+#define DACL_PATH_REFV_ON BIT(5)
+#define DACL_PATH_REFV_MASK BIT(5)
+#define HPOUTL_ZERO_CROSSING_OFF (0 << 4)
+#define HPOUTL_ZERO_CROSSING_ON BIT(4)
+#define DACR_PATH_REFV_OFF (0 << 1)
+#define DACR_PATH_REFV_ON BIT(1)
+#define DACR_PATH_REFV_MASK BIT(1)
+#define HPOUTR_ZERO_CROSSING_OFF (0 << 0)
+#define HPOUTR_ZERO_CROSSING_ON BIT(0)
+
+/* REG24: DAC_CLK_CTRL */
+#define DACL_REFV_OFF (0 << 7)
+#define DACL_REFV_ON BIT(7)
+#define DACL_REFV_MASK BIT(7)
+#define DACL_CLK_OFF (0 << 6)
+#define DACL_CLK_ON BIT(6)
+#define DACL_CLK_MASK BIT(6)
+#define DACL_OFF (0 << 5)
+#define DACL_ON BIT(5)
+#define DACL_MASK BIT(5)
+#define DACL_INIT_OFF (0 << 4)
+#define DACL_INIT_ON BIT(4)
+#define DACL_INIT_MASK BIT(4)
+#define DACR_REFV_OFF (0 << 3)
+#define DACR_REFV_ON BIT(3)
+#define DACR_REFV_MASK BIT(3)
+#define DACR_CLK_OFF (0 << 2)
+#define DACR_CLK_ON BIT(2)
+#define DACR_CLK_MASK BIT(2)
+#define DACR_OFF (0 << 1)
+#define DACR_ON BIT(1)
+#define DACR_MASK BIT(1)
+#define DACR_INIT_OFF (0 << 0)
+#define DACR_INIT_ON BIT(0)
+#define DACR_INIT_MASK BIT(0)
+
+/* REG25: HPMIX_CTRL*/
+#define HPMIXL_DIS (0 << 6)
+#define HPMIXL_EN BIT(6)
+#define HPMIXL_MASK BIT(6)
+#define HPMIXL_INIT_DIS (0 << 5)
+#define HPMIXL_INIT_EN BIT(5)
+#define HPMIXL_INIT_MASK BIT(5)
+#define HPMIXL_INIT2_DIS (0 << 4)
+#define HPMIXL_INIT2_EN BIT(4)
+#define HPMIXL_INIT2_MASK BIT(4)
+#define HPMIXR_DIS (0 << 2)
+#define HPMIXR_EN BIT(2)
+#define HPMIXR_MASK BIT(2)
+#define HPMIXR_INIT_DIS (0 << 1)
+#define HPMIXR_INIT_EN BIT(1)
+#define HPMIXR_INIT_MASK BIT(1)
+#define HPMIXR_INIT2_DIS (0 << 0)
+#define HPMIXR_INIT2_EN BIT(0)
+#define HPMIXR_INIT2_MASK BIT(0)
+
+/* REG26: DAC_SELECT */
+#define DACL_SELECT BIT(4)
+#define DACL_SELECT_MASK BIT(4)
+#define DACL_DESELECT (0 << 4)
+#define DACR_SELECT BIT(0)
+#define DACR_SELECT_MASK BIT(0)
+#define DACR_DESELECT (0 << 0)
+
+/* REG27: HPOUT_CTRL */
+#define HPOUTL_DIS (0 << 7)
+#define HPOUTL_EN BIT(7)
+#define HPOUTL_MASK BIT(7)
+#define HPOUTL_INIT_DIS (0 << 6)
+#define HPOUTL_INIT_EN BIT(6)
+#define HPOUTL_INIT_MASK BIT(6)
+#define HPOUTL_MUTE (0 << 5)
+#define HPOUTL_UNMUTE BIT(5)
+#define HPOUTL_MUTE_MASK BIT(5)
+#define HPOUTR_DIS (0 << 4)
+#define HPOUTR_EN BIT(4)
+#define HPOUTR_MASK BIT(4)
+#define HPOUTR_INIT_DIS (0 << 3)
+#define HPOUTR_INIT_EN BIT(3)
+#define HPOUTR_INIT_MASK BIT(3)
+#define HPOUTR_MUTE (0 << 2)
+#define HPOUTR_UNMUTE BIT(2)
+#define HPOUTR_MUTE_MASK BIT(2)
+
+/* REG28: HPOUTL_GAIN_CTRL */
+#define HPOUTL_GAIN_MASK (0X1f << 0)
+
+/* REG29: HPOUTR_GAIN_CTRL */
+#define HPOUTR_GAIN_MASK (0X1f << 0)
+
+/* REG2a: HPOUT_POP_CTRL */
+#define HPOUTR_POP_XCHARGE BIT(4)
+#define HPOUTR_POP_WORK (2 << 4)
+#define HPOUTR_POP_MASK (3 << 4)
+#define HPOUTL_POP_XCHARGE BIT(0)
+#define HPOUTL_POP_WORK (2 << 0)
+#define HPOUTL_POP_MASK (3 << 0)
+
+#define RK3228_HIFI (0)
+
+struct rk3228_reg_msk_val {
+ unsigned int reg;
+ unsigned int msk;
+ unsigned int val;
+};
+
+#endif
--
2.25.1

View File

@ -0,0 +1,38 @@
From 9e105544fcb63f8f79b199d1b194a36a354519b3 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Sun, 2 Apr 2023 10:53:07 +0000
Subject: [PATCH 2/2] rk322x: better handle mmc/sdio clocks
---
drivers/clk/rockchip/clk-rk3228.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
index 996f8bfee..0f690dd84 100644
--- a/drivers/clk/rockchip/clk-rk3228.c
+++ b/drivers/clk/rockchip/clk-rk3228.c
@@ -371,17 +371,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS,
RK2928_CLKGATE_CON(2), 11, GFLAGS),
- COMPOSITE_NODIV(SCLK_SDIO_SRC, "sclk_sdio_src", mux_mmc_src_p, 0,
+ COMPOSITE_DIV_OFFSET(SCLK_SDIO, "sclk_sdio", mux_mmc_src_p, 0,
RK2928_CLKSEL_CON(11), 10, 2, MFLAGS,
+ RK2928_CLKSEL_CON(12), 0, 8, DFLAGS,
RK2928_CLKGATE_CON(2), 13, GFLAGS),
- DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
- RK2928_CLKSEL_CON(12), 0, 8, DFLAGS),
- COMPOSITE_NODIV(0, "sclk_emmc_src", mux_mmc_src_p, 0,
+ COMPOSITE_DIV_OFFSET(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0,
RK2928_CLKSEL_CON(11), 12, 2, MFLAGS,
+ RK2928_CLKSEL_CON(12), 8, 8, DFLAGS,
RK2928_CLKGATE_CON(2), 14, GFLAGS),
- DIV(SCLK_EMMC, "sclk_emmc", "sclk_emmc_src", 0,
- RK2928_CLKSEL_CON(12), 8, 8, DFLAGS),
/*
* Clock-Architecture Diagram 2
--
2.34.1

View File

@ -0,0 +1,234 @@
From e039790fb29227f646e91e6d7ec7c3e89c584243 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Tue, 6 Jul 2021 14:21:52 +0000
Subject: [PATCH 1/5] rk3228/rk3328: fix ddr clock gate, add SIP v2 calls
---
drivers/clk/rockchip/clk-ddr.c | 130 ++++++++++++++++++++++++++++++
drivers/clk/rockchip/clk-rk3228.c | 14 ++--
drivers/clk/rockchip/clk-rk3328.c | 7 +-
drivers/clk/rockchip/clk.h | 3 +-
4 files changed, 143 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
index 86718c54e..b16b3795f 100644
--- a/drivers/clk/rockchip/clk-ddr.c
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -87,6 +87,133 @@ static const struct clk_ops rockchip_ddrclk_sip_ops = {
.get_parent = rockchip_ddrclk_get_parent,
};
+/* See v4.4/include/dt-bindings/display/rk_fb.h */
+#define SCREEN_NULL 0
+#define SCREEN_HDMI 6
+
+static inline int rk_drm_get_lcdc_type(void)
+{
+ return SCREEN_NULL;
+}
+
+struct share_params {
+ u32 hz;
+ u32 lcdc_type;
+ u32 vop;
+ u32 vop_dclk_mode;
+ u32 sr_idle_en;
+ u32 addr_mcu_el3;
+ /*
+ * 1: need to wait flag1
+ * 0: never wait flag1
+ */
+ u32 wait_flag1;
+ /*
+ * 1: need to wait flag1
+ * 0: never wait flag1
+ */
+ u32 wait_flag0;
+ u32 complt_hwirq;
+ /* if need, add parameter after */
+};
+
+struct rockchip_ddrclk_data {
+ u32 inited_flag;
+ void __iomem *share_memory;
+};
+
+static struct rockchip_ddrclk_data ddr_data;
+
+static void rockchip_ddrclk_data_init(void)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(ROCKCHIP_SIP_SHARE_MEM,
+ 1, SHARE_PAGE_TYPE_DDR, 0,
+ 0, 0, 0, 0, &res);
+
+ if (!res.a0) {
+ ddr_data.share_memory = (void __iomem *)ioremap(res.a1, 1<<12);
+ ddr_data.inited_flag = 1;
+ }
+}
+
+static int rockchip_ddrclk_sip_set_rate_v2(struct clk_hw *hw,
+ unsigned long drate,
+ unsigned long prate)
+{
+ struct share_params *p;
+ struct arm_smccc_res res;
+
+ if (!ddr_data.inited_flag)
+ rockchip_ddrclk_data_init();
+
+ p = (struct share_params *)ddr_data.share_memory;
+
+ p->hz = drate;
+ p->lcdc_type = rk_drm_get_lcdc_type();
+ p->wait_flag1 = 1;
+ p->wait_flag0 = 1;
+
+ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ,
+ SHARE_PAGE_TYPE_DDR, 0,
+ ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE,
+ 0, 0, 0, 0, &res);
+
+ if ((int)res.a1 == -6) {
+ pr_err("%s: timeout, drate = %lumhz\n", __func__, drate/1000000);
+ /* TODO: rockchip_dmcfreq_wait_complete(); */
+ }
+
+ return res.a0;
+}
+
+static unsigned long rockchip_ddrclk_sip_recalc_rate_v2
+ (struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ,
+ SHARE_PAGE_TYPE_DDR, 0,
+ ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE,
+ 0, 0, 0, 0, &res);
+ if (!res.a0)
+ return res.a1;
+ else
+ return 0;
+}
+
+static long rockchip_ddrclk_sip_round_rate_v2(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long *prate)
+{
+ struct share_params *p;
+ struct arm_smccc_res res;
+
+ if (!ddr_data.inited_flag)
+ rockchip_ddrclk_data_init();
+
+ p = (struct share_params *)ddr_data.share_memory;
+
+ p->hz = rate;
+
+ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ,
+ SHARE_PAGE_TYPE_DDR, 0,
+ ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE,
+ 0, 0, 0, 0, &res);
+ if (!res.a0)
+ return res.a1;
+ else
+ return 0;
+}
+
+static const struct clk_ops rockchip_ddrclk_sip_ops_v2 = {
+ .recalc_rate = rockchip_ddrclk_sip_recalc_rate_v2,
+ .set_rate = rockchip_ddrclk_sip_set_rate_v2,
+ .round_rate = rockchip_ddrclk_sip_round_rate_v2,
+ .get_parent = rockchip_ddrclk_get_parent,
+};
+
struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
const char *const *parent_names,
u8 num_parents, int mux_offset,
@@ -114,6 +241,9 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
case ROCKCHIP_DDRCLK_SIP:
init.ops = &rockchip_ddrclk_sip_ops;
break;
+ case ROCKCHIP_DDRCLK_SIP_V2:
+ init.ops = &rockchip_ddrclk_sip_ops_v2;
+ break;
default:
pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
kfree(ddrclk);
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
index 1f9176a5c..96393aa16 100644
--- a/drivers/clk/rockchip/clk-rk3228.c
+++ b/drivers/clk/rockchip/clk-rk3228.c
@@ -218,9 +218,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
RK2928_CLKSEL_CON(4), 8, 5, DFLAGS),
/* PD_DDR */
- COMPOSITE(0, "clk_ddrphy_src", mux_ddrphy_p, CLK_IGNORE_UNUSED,
- RK2928_CLKSEL_CON(26), 8, 2, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
- RK2928_CLKGATE_CON(0), 2, GFLAGS),
+ COMPOSITE_DDRCLK(SCLK_DDRCLK, "sclk_ddrc", mux_ddrphy_p, 0,
+ RK2928_CLKSEL_CON(26), 8, 2, 0, 2,
+ ROCKCHIP_DDRCLK_SIP_V2),
GATE(0, "ddrphy4x", "clk_ddrphy_src", CLK_IGNORE_UNUSED,
RK2928_CLKGATE_CON(7), 1, GFLAGS),
FACTOR_GATE(0, "ddrc", "clk_ddrphy_src", CLK_IGNORE_UNUSED, 1, 4,
@@ -576,8 +576,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
GATE(HCLK_M_CRYPTO, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
GATE(HCLK_S_CRYPTO, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS),
- GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS),
- GATE(0, "pclk_ddrmon", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS),
+ GATE(0, "pclk_ddr_upctl", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS),
+ GATE(0, "pclk_ddr_mon", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS),
GATE(0, "pclk_msch_noc", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(10), 2, GFLAGS),
GATE(PCLK_EFUSE_1024, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS),
@@ -652,8 +652,8 @@ static const char *const rk3228_critical_clocks[] __initconst = {
"sclk_initmem_mbist",
"aclk_initmem",
"hclk_rom",
- "pclk_ddrupctl",
- "pclk_ddrmon",
+ "pclk_ddr_upctl",
+ "pclk_ddr_mon",
"pclk_msch_noc",
"pclk_stimer",
"pclk_ddrphy",
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
index cc18dbc18..5fdd611bb 100644
--- a/drivers/clk/rockchip/clk-rk3328.c
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -317,9 +317,10 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
RK3328_CLKGATE_CON(14), 1, GFLAGS),
/* PD_DDR */
- COMPOSITE(0, "clk_ddr", mux_ddrphy_p, CLK_IGNORE_UNUSED,
- RK3328_CLKSEL_CON(3), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
- RK3328_CLKGATE_CON(0), 4, GFLAGS),
+ COMPOSITE_DDRCLK(SCLK_DDRCLK, "sclk_ddrc", mux_ddrphy_p, 0,
+ RK3328_CLKSEL_CON(3), 8, 2, 0, 3,
+ ROCKCHIP_DDRCLK_SIP_V2),
+
GATE(0, "clk_ddrmsch", "clk_ddr", CLK_IGNORE_UNUSED,
RK3328_CLKGATE_CON(18), 6, GFLAGS),
GATE(0, "clk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED,
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index ae059b774..fdaa81ebb 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -363,7 +363,8 @@ struct clk *rockchip_clk_register_mmc(const char *name,
* DDRCLK flags, including method of setting the rate
* ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
*/
-#define ROCKCHIP_DDRCLK_SIP BIT(0)
+#define ROCKCHIP_DDRCLK_SIP 0x01
+#define ROCKCHIP_DDRCLK_SIP_V2 0x03
struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
const char *const *parent_names,
--
2.25.1

View File

@ -0,0 +1,67 @@
From 95358ea4a4434ad4af5545b3f762508e4f015fc3 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Tue, 6 Jul 2021 14:23:36 +0000
Subject: [PATCH 2/5] rk3228/rk3328: add ddr clock and SIP related constants
and defines
---
include/dt-bindings/clock/rk3228-cru.h | 1 +
include/soc/rockchip/rockchip_sip.h | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h
index de550ea56..911824731 100644
--- a/include/dt-bindings/clock/rk3228-cru.h
+++ b/include/dt-bindings/clock/rk3228-cru.h
@@ -15,6 +15,7 @@
#define ARMCLK 5
/* sclk gates (special clocks) */
+#define SCLK_DDRCLK 64
#define SCLK_SPI0 65
#define SCLK_NANDC 67
#define SCLK_SDMMC 68
diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
index c46a9ae2a..34e653751 100644
--- a/include/soc/rockchip/rockchip_sip.h
+++ b/include/soc/rockchip/rockchip_sip.h
@@ -6,6 +6,7 @@
#ifndef __SOC_ROCKCHIP_SIP_H
#define __SOC_ROCKCHIP_SIP_H
+#define ROCKCHIP_SIP_ATF_VERSION 0x82000001
#define ROCKCHIP_SIP_DRAM_FREQ 0x82000008
#define ROCKCHIP_SIP_CONFIG_DRAM_INIT 0x00
#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE 0x01
@@ -16,5 +17,28 @@
#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06
#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07
#define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD 0x08
+#define ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION 0x08
+#define ROCKCHIP_SIP_CONFIG_DRAM_POST_SET_RATE 0x09
+#define ROCKCHIP_SIP_CONFIG_DRAM_SET_MSCH_RL 0x0a
+#define ROCKCHIP_SIP_CONFIG_DRAM_DEBUG 0x0b
+
+#define ROCKCHIP_SIP_SHARE_MEM 0x82000009
+#define ROCKCHIP_SIP_SIP_VERSION 0x8200000a
+
+/* Rockchip Sip version */
+#define ROCKCHIP_SIP_IMPLEMENT_V1 (1)
+#define ROCKCHIP_SIP_IMPLEMENT_V2 (2)
+
+/* SIP_ACCESS_REG: read or write */
+#define SECURE_REG_RD 0x0
+#define SECURE_REG_WR 0x1
+
+/* Share mem page types */
+typedef enum {
+ SHARE_PAGE_TYPE_INVALID = 0,
+ SHARE_PAGE_TYPE_UARTDBG,
+ SHARE_PAGE_TYPE_DDR,
+ SHARE_PAGE_TYPE_MAX,
+} share_page_type_t;
#endif
--
2.25.1

View File

@ -0,0 +1,745 @@
From 415ed43c9b64ca38bc433bd5dc0359292dd80380 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Tue, 6 Jul 2021 14:25:41 +0000
Subject: [PATCH 3/5] rk3228/rk3328: extend rockchip dfi driver
---
arch/arm/boot/dts/rk322x.dtsi | 7 +
drivers/devfreq/event/rockchip-dfi.c | 598 ++++++++++++++++++++++++---
2 files changed, 557 insertions(+), 48 deletions(-)
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index ad98fcf37..7e06acc31 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -97,6 +97,13 @@ opp-1200000000 {
};
};
+ dfi: dfi@11210000 {
+ reg = <0x11210000 0x400>;
+ compatible = "rockchip,rk3228-dfi";
+ rockchip,grf = <&grf>;
+ status = "okay";
+ };
+
arm-pmu {
compatible = "arm,cortex-a7-pmu";
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
index 9a88faaf8..01fb84b99 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -18,25 +18,68 @@
#include <linux/list.h>
#include <linux/of.h>
-#include <soc/rockchip/rk3399_grf.h>
-
-#define RK3399_DMC_NUM_CH 2
-
+#define PX30_PMUGRF_OS_REG2 0x208
+
+#define RK3128_GRF_SOC_CON0 0x140
+#define RK3128_GRF_OS_REG1 0x1cc
+#define RK3128_GRF_DFI_WRNUM 0x220
+#define RK3128_GRF_DFI_RDNUM 0x224
+#define RK3128_GRF_DFI_TIMERVAL 0x22c
+#define RK3128_DDR_MONITOR_EN ((1 << (16 + 6)) + (1 << 6))
+#define RK3128_DDR_MONITOR_DISB ((1 << (16 + 6)) + (0 << 6))
+
+#define RK3228_GRF_OS_REG2 0x5d0
+
+#define RK3288_PMU_SYS_REG2 0x9c
+#define RK3288_GRF_SOC_CON4 0x254
+#define RK3288_GRF_SOC_STATUS(n) (0x280 + (n) * 4)
+#define RK3288_DFI_EN (0x30003 << 14)
+#define RK3288_DFI_DIS (0x30000 << 14)
+#define RK3288_LPDDR_SEL (0x10001 << 13)
+#define RK3288_DDR3_SEL (0x10000 << 13)
+
+#define RK3328_GRF_OS_REG2 0x5d0
+
+#define RK3368_GRF_DDRC0_CON0 0x600
+#define RK3368_GRF_SOC_STATUS5 0x494
+#define RK3368_GRF_SOC_STATUS6 0x498
+#define RK3368_GRF_SOC_STATUS8 0x4a0
+#define RK3368_GRF_SOC_STATUS9 0x4a4
+#define RK3368_GRF_SOC_STATUS10 0x4a8
+#define RK3368_DFI_EN (0x30003 << 5)
+#define RK3368_DFI_DIS (0x30000 << 5)
+
+#define MAX_DMC_NUM_CH 2
+#define READ_DRAMTYPE_INFO(n) (((n) >> 13) & 0x7)
+#define READ_CH_INFO(n) (((n) >> 28) & 0x3)
/* DDRMON_CTRL */
-#define DDRMON_CTRL 0x04
-#define CLR_DDRMON_CTRL (0x1f0000 << 0)
-#define LPDDR4_EN (0x10001 << 4)
-#define HARDWARE_EN (0x10001 << 3)
-#define LPDDR3_EN (0x10001 << 2)
-#define SOFTWARE_EN (0x10001 << 1)
-#define SOFTWARE_DIS (0x10000 << 1)
-#define TIME_CNT_EN (0x10001 << 0)
+#define DDRMON_CTRL 0x04
+#define CLR_DDRMON_CTRL (0x3f0000 << 0)
+#define DDR4_EN (0x10001 << 5)
+#define LPDDR4_EN (0x10001 << 4)
+#define HARDWARE_EN (0x10001 << 3)
+#define LPDDR2_3_EN (0x10001 << 2)
+#define SOFTWARE_EN (0x10001 << 1)
+#define SOFTWARE_DIS (0x10000 << 1)
+#define TIME_CNT_EN (0x10001 << 0)
#define DDRMON_CH0_COUNT_NUM 0x28
#define DDRMON_CH0_DFI_ACCESS_NUM 0x2c
#define DDRMON_CH1_COUNT_NUM 0x3c
#define DDRMON_CH1_DFI_ACCESS_NUM 0x40
+/* pmu grf */
+#define PMUGRF_OS_REG2 0x308
+
+enum {
+ DDR4 = 0,
+ DDR3 = 3,
+ LPDDR2 = 5,
+ LPDDR3 = 6,
+ LPDDR4 = 7,
+ UNUSED = 0xFF
+};
+
struct dmc_usage {
u32 access;
u32 total;
@@ -50,33 +93,261 @@ struct dmc_usage {
struct rockchip_dfi {
struct devfreq_event_dev *edev;
struct devfreq_event_desc *desc;
- struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
+ struct dmc_usage ch_usage[MAX_DMC_NUM_CH];
struct device *dev;
void __iomem *regs;
struct regmap *regmap_pmu;
+ struct regmap *regmap_grf;
+ struct regmap *regmap_pmugrf;
struct clk *clk;
+ u32 dram_type;
+ /*
+ * available mask, 1: available, 0: not available
+ * each bit represent a channel
+ */
+ u32 ch_msk;
+};
+
+static void rk3128_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+
+ regmap_write(info->regmap_grf,
+ RK3128_GRF_SOC_CON0,
+ RK3128_DDR_MONITOR_EN);
+}
+
+static void rk3128_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+
+ regmap_write(info->regmap_grf,
+ RK3128_GRF_SOC_CON0,
+ RK3128_DDR_MONITOR_DISB);
+}
+
+static int rk3128_dfi_disable(struct devfreq_event_dev *edev)
+{
+ rk3128_dfi_stop_hardware_counter(edev);
+
+ return 0;
+}
+
+static int rk3128_dfi_enable(struct devfreq_event_dev *edev)
+{
+ rk3128_dfi_start_hardware_counter(edev);
+
+ return 0;
+}
+
+static int rk3128_dfi_set_event(struct devfreq_event_dev *edev)
+{
+ return 0;
+}
+
+static int rk3128_dfi_get_event(struct devfreq_event_dev *edev,
+ struct devfreq_event_data *edata)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+ unsigned long flags;
+ u32 dfi_wr, dfi_rd, dfi_timer;
+
+ local_irq_save(flags);
+
+ rk3128_dfi_stop_hardware_counter(edev);
+
+ regmap_read(info->regmap_grf, RK3128_GRF_DFI_WRNUM, &dfi_wr);
+ regmap_read(info->regmap_grf, RK3128_GRF_DFI_RDNUM, &dfi_rd);
+ regmap_read(info->regmap_grf, RK3128_GRF_DFI_TIMERVAL, &dfi_timer);
+
+ edata->load_count = (dfi_wr + dfi_rd) * 4;
+ edata->total_count = dfi_timer;
+
+ rk3128_dfi_start_hardware_counter(edev);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static const struct devfreq_event_ops rk3128_dfi_ops = {
+ .disable = rk3128_dfi_disable,
+ .enable = rk3128_dfi_enable,
+ .get_event = rk3128_dfi_get_event,
+ .set_event = rk3128_dfi_set_event,
+};
+
+static void rk3288_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+
+ regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_EN);
+}
+
+static void rk3288_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+
+ regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_DIS);
+}
+
+static int rk3288_dfi_disable(struct devfreq_event_dev *edev)
+{
+ rk3288_dfi_stop_hardware_counter(edev);
+
+ return 0;
+}
+
+static int rk3288_dfi_enable(struct devfreq_event_dev *edev)
+{
+ rk3288_dfi_start_hardware_counter(edev);
+
+ return 0;
+}
+
+static int rk3288_dfi_set_event(struct devfreq_event_dev *edev)
+{
+ return 0;
+}
+
+static int rk3288_dfi_get_busier_ch(struct devfreq_event_dev *edev)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+ u32 tmp, max = 0;
+ u32 i, busier_ch = 0;
+ u32 rd_count, wr_count, total_count;
+
+ rk3288_dfi_stop_hardware_counter(edev);
+
+ /* Find out which channel is busier */
+ for (i = 0; i < MAX_DMC_NUM_CH; i++) {
+ if (!(info->ch_msk & BIT(i)))
+ continue;
+ regmap_read(info->regmap_grf,
+ RK3288_GRF_SOC_STATUS(11 + i * 4), &wr_count);
+ regmap_read(info->regmap_grf,
+ RK3288_GRF_SOC_STATUS(12 + i * 4), &rd_count);
+ regmap_read(info->regmap_grf,
+ RK3288_GRF_SOC_STATUS(14 + i * 4), &total_count);
+ info->ch_usage[i].access = (wr_count + rd_count) * 4;
+ info->ch_usage[i].total = total_count;
+ tmp = info->ch_usage[i].access;
+ if (tmp > max) {
+ busier_ch = i;
+ max = tmp;
+ }
+ }
+ rk3288_dfi_start_hardware_counter(edev);
+
+ return busier_ch;
+}
+
+static int rk3288_dfi_get_event(struct devfreq_event_dev *edev,
+ struct devfreq_event_data *edata)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+ int busier_ch;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ busier_ch = rk3288_dfi_get_busier_ch(edev);
+ local_irq_restore(flags);
+
+ edata->load_count = info->ch_usage[busier_ch].access;
+ edata->total_count = info->ch_usage[busier_ch].total;
+
+ return 0;
+}
+
+static const struct devfreq_event_ops rk3288_dfi_ops = {
+ .disable = rk3288_dfi_disable,
+ .enable = rk3288_dfi_enable,
+ .get_event = rk3288_dfi_get_event,
+ .set_event = rk3288_dfi_set_event,
+};
+
+static void rk3368_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+
+ regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_EN);
+}
+
+static void rk3368_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+
+ regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_DIS);
+}
+
+static int rk3368_dfi_disable(struct devfreq_event_dev *edev)
+{
+ rk3368_dfi_stop_hardware_counter(edev);
+
+ return 0;
+}
+
+static int rk3368_dfi_enable(struct devfreq_event_dev *edev)
+{
+ rk3368_dfi_start_hardware_counter(edev);
+
+ return 0;
+}
+
+static int rk3368_dfi_set_event(struct devfreq_event_dev *edev)
+{
+ return 0;
+}
+
+static int rk3368_dfi_get_event(struct devfreq_event_dev *edev,
+ struct devfreq_event_data *edata)
+{
+ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+ unsigned long flags;
+ u32 dfi0_wr, dfi0_rd, dfi1_wr, dfi1_rd, dfi_timer;
+
+ local_irq_save(flags);
+
+ rk3368_dfi_stop_hardware_counter(edev);
+
+ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS5, &dfi0_wr);
+ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS6, &dfi0_rd);
+ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS9, &dfi1_wr);
+ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS10, &dfi1_rd);
+ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS8, &dfi_timer);
+
+ edata->load_count = (dfi0_wr + dfi0_rd + dfi1_wr + dfi1_rd) * 2;
+ edata->total_count = dfi_timer;
+
+ rk3368_dfi_start_hardware_counter(edev);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static const struct devfreq_event_ops rk3368_dfi_ops = {
+ .disable = rk3368_dfi_disable,
+ .enable = rk3368_dfi_enable,
+ .get_event = rk3368_dfi_get_event,
+ .set_event = rk3368_dfi_set_event,
};
static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
{
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
void __iomem *dfi_regs = info->regs;
- u32 val;
- u32 ddr_type;
-
- /* get ddr type */
- regmap_read(info->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
- ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
- RK3399_PMUGRF_DDRTYPE_MASK;
/* clear DDRMON_CTRL setting */
writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
/* set ddr type to dfi */
- if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3)
- writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
- else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4)
+ if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2)
+ writel_relaxed(LPDDR2_3_EN, dfi_regs + DDRMON_CTRL);
+ else if (info->dram_type == LPDDR4)
writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL);
+ else if (info->dram_type == DDR4)
+ writel_relaxed(DDR4_EN, dfi_regs + DDRMON_CTRL);
/* enable count, use software mode */
writel_relaxed(SOFTWARE_EN, dfi_regs + DDRMON_CTRL);
@@ -100,12 +371,22 @@ static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
rockchip_dfi_stop_hardware_counter(edev);
/* Find out which channel is busier */
- for (i = 0; i < RK3399_DMC_NUM_CH; i++) {
- info->ch_usage[i].access = readl_relaxed(dfi_regs +
- DDRMON_CH0_DFI_ACCESS_NUM + i * 20) * 4;
+ for (i = 0; i < MAX_DMC_NUM_CH; i++) {
+ if (!(info->ch_msk & BIT(i)))
+ continue;
+
info->ch_usage[i].total = readl_relaxed(dfi_regs +
DDRMON_CH0_COUNT_NUM + i * 20);
- tmp = info->ch_usage[i].access;
+
+ /* LPDDR4 BL = 16,other DDR type BL = 8 */
+ tmp = readl_relaxed(dfi_regs +
+ DDRMON_CH0_DFI_ACCESS_NUM + i * 20);
+ if (info->dram_type == LPDDR4)
+ tmp *= 8;
+ else
+ tmp *= 4;
+ info->ch_usage[i].access = tmp;
+
if (tmp > max) {
busier_ch = i;
max = tmp;
@@ -118,10 +399,14 @@ static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
static int rockchip_dfi_disable(struct devfreq_event_dev *edev)
{
+ struct device *dev = &edev->dev;
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
rockchip_dfi_stop_hardware_counter(edev);
- clk_disable_unprepare(info->clk);
+ if (info->clk)
+ clk_disable_unprepare(info->clk);
+
+ dev_notice(dev,"Rockchip DFI interface disabled\n");
return 0;
}
@@ -129,20 +414,28 @@ static int rockchip_dfi_disable(struct devfreq_event_dev *edev)
static int rockchip_dfi_enable(struct devfreq_event_dev *edev)
{
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+ struct device *dev = &edev->dev;
int ret;
- ret = clk_prepare_enable(info->clk);
- if (ret) {
- dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ret);
- return ret;
+ if (info->clk) {
+ ret = clk_prepare_enable(info->clk);
+ if (ret) {
+ dev_err(&edev->dev, "failed to enable dfi clk: %d\n",
+ ret);
+ return ret;
+ }
}
rockchip_dfi_start_hardware_counter(edev);
+
+ dev_notice(dev,"Rockchip DFI interface enabled\n");
+
return 0;
}
static int rockchip_dfi_set_event(struct devfreq_event_dev *edev)
{
+
return 0;
}
@@ -151,8 +444,11 @@ static int rockchip_dfi_get_event(struct devfreq_event_dev *edev,
{
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
int busier_ch;
+ unsigned long flags;
+ local_irq_save(flags);
busier_ch = rockchip_dfi_get_busier_ch(edev);
+ local_irq_restore(flags);
edata->load_count = info->ch_usage[busier_ch].access;
edata->total_count = info->ch_usage[busier_ch].total;
@@ -167,22 +463,151 @@ static const struct devfreq_event_ops rockchip_dfi_ops = {
.set_event = rockchip_dfi_set_event,
};
-static const struct of_device_id rockchip_dfi_id_match[] = {
- { .compatible = "rockchip,rk3399-dfi" },
- { },
-};
-MODULE_DEVICE_TABLE(of, rockchip_dfi_id_match);
+static __init int px30_dfi_init(struct platform_device *pdev,
+ struct rockchip_dfi *data,
+ struct devfreq_event_desc *desc)
+{
+ struct device_node *np = pdev->dev.of_node, *node;
+ struct resource *res;
+ u32 val;
-static int rockchip_dfi_probe(struct platform_device *pdev)
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ data->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(data->regs))
+ return PTR_ERR(data->regs);
+
+ node = of_parse_phandle(np, "rockchip,pmugrf", 0);
+ if (node) {
+ data->regmap_pmugrf = syscon_node_to_regmap(node);
+ if (IS_ERR(data->regmap_pmugrf))
+ return PTR_ERR(data->regmap_pmugrf);
+ }
+
+ regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG2, &val);
+ data->dram_type = READ_DRAMTYPE_INFO(val);
+ data->ch_msk = 1;
+ data->clk = NULL;
+
+ desc->ops = &rockchip_dfi_ops;
+
+ return 0;
+}
+
+static __init int rk3128_dfi_init(struct platform_device *pdev,
+ struct rockchip_dfi *data,
+ struct devfreq_event_desc *desc)
+{
+ struct device_node *np = pdev->dev.of_node, *node;
+
+ node = of_parse_phandle(np, "rockchip,grf", 0);
+ if (node) {
+ data->regmap_grf = syscon_node_to_regmap(node);
+ if (IS_ERR(data->regmap_grf))
+ return PTR_ERR(data->regmap_grf);
+ }
+
+ desc->ops = &rk3128_dfi_ops;
+
+ return 0;
+}
+
+static __init int rk3228_dfi_init(struct platform_device *pdev,
+ struct rockchip_dfi *data,
+ struct devfreq_event_desc *desc)
{
+ struct device_node *np = pdev->dev.of_node, *node;
+ struct resource *res;
struct device *dev = &pdev->dev;
- struct rockchip_dfi *data;
- struct devfreq_event_desc *desc;
+ u32 val;
+
+ dev_notice(dev,"rk3228_dfi_init enter\n");
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ data->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(data->regs))
+ return PTR_ERR(data->regs);
+
+ node = of_parse_phandle(np, "rockchip,grf", 0);
+ if (node) {
+ data->regmap_grf = syscon_node_to_regmap(node);
+ if (IS_ERR(data->regmap_grf))
+ return PTR_ERR(data->regmap_grf);
+ }
+
+ regmap_read(data->regmap_grf, RK3228_GRF_OS_REG2, &val);
+ data->dram_type = READ_DRAMTYPE_INFO(val);
+ data->ch_msk = 1;
+ data->clk = NULL;
+
+ desc->ops = &rockchip_dfi_ops;
+
+ dev_notice(dev,"rk3228-dfi initialized, dram type: 0x%x, channels: %d\n", data->dram_type, data->ch_msk);
+
+ return 0;
+}
+
+static __init int rk3288_dfi_init(struct platform_device *pdev,
+ struct rockchip_dfi *data,
+ struct devfreq_event_desc *desc)
+{
struct device_node *np = pdev->dev.of_node, *node;
+ u32 val;
- data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
+ node = of_parse_phandle(np, "rockchip,pmu", 0);
+ if (node) {
+ data->regmap_pmu = syscon_node_to_regmap(node);
+ if (IS_ERR(data->regmap_pmu))
+ return PTR_ERR(data->regmap_pmu);
+ }
+
+ node = of_parse_phandle(np, "rockchip,grf", 0);
+ if (node) {
+ data->regmap_grf = syscon_node_to_regmap(node);
+ if (IS_ERR(data->regmap_grf))
+ return PTR_ERR(data->regmap_grf);
+ }
+
+ regmap_read(data->regmap_pmu, RK3288_PMU_SYS_REG2, &val);
+ data->dram_type = READ_DRAMTYPE_INFO(val);
+ data->ch_msk = READ_CH_INFO(val);
+
+ if (data->dram_type == DDR3)
+ regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4,
+ RK3288_DDR3_SEL);
+ else
+ regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4,
+ RK3288_LPDDR_SEL);
+
+ desc->ops = &rk3288_dfi_ops;
+
+ return 0;
+}
+
+static __init int rk3368_dfi_init(struct platform_device *pdev,
+ struct rockchip_dfi *data,
+ struct devfreq_event_desc *desc)
+{
+ struct device *dev = &pdev->dev;
+
+ if (!dev->parent || !dev->parent->of_node)
+ return -EINVAL;
+
+ data->regmap_grf = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(data->regmap_grf))
+ return PTR_ERR(data->regmap_grf);
+
+ desc->ops = &rk3368_dfi_ops;
+
+ return 0;
+}
+
+static __init int rockchip_dfi_init(struct platform_device *pdev,
+ struct rockchip_dfi *data,
+ struct devfreq_event_desc *desc)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = pdev->dev.of_node, *node;
+ u32 val;
data->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->regs))
@@ -202,21 +627,98 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
if (IS_ERR(data->regmap_pmu))
return PTR_ERR(data->regmap_pmu);
- data->dev = dev;
+
+ regmap_read(data->regmap_pmu, PMUGRF_OS_REG2, &val);
+ data->dram_type = READ_DRAMTYPE_INFO(val);
+ data->ch_msk = READ_CH_INFO(val);
+
+ desc->ops = &rockchip_dfi_ops;
+
+ return 0;
+}
+
+static __init int rk3328_dfi_init(struct platform_device *pdev,
+ struct rockchip_dfi *data,
+ struct devfreq_event_desc *desc)
+{
+ struct device_node *np = pdev->dev.of_node, *node;
+ struct resource *res;
+ u32 val;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ data->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(data->regs))
+ return PTR_ERR(data->regs);
+
+ node = of_parse_phandle(np, "rockchip,grf", 0);
+ if (node) {
+ data->regmap_grf = syscon_node_to_regmap(node);
+ if (IS_ERR(data->regmap_grf))
+ return PTR_ERR(data->regmap_grf);
+ }
+
+ regmap_read(data->regmap_grf, RK3328_GRF_OS_REG2, &val);
+ data->dram_type = READ_DRAMTYPE_INFO(val);
+ data->ch_msk = 1;
+ data->clk = NULL;
+
+ desc->ops = &rockchip_dfi_ops;
+
+ return 0;
+}
+
+static const struct of_device_id rockchip_dfi_id_match[] = {
+ { .compatible = "rockchip,px30-dfi", .data = px30_dfi_init },
+ { .compatible = "rockchip,rk1808-dfi", .data = px30_dfi_init },
+ { .compatible = "rockchip,rk3128-dfi", .data = rk3128_dfi_init },
+ { .compatible = "rockchip,rk3228-dfi", .data = rk3228_dfi_init },
+ { .compatible = "rockchip,rk3288-dfi", .data = rk3288_dfi_init },
+ { .compatible = "rockchip,rk3328-dfi", .data = rk3328_dfi_init },
+ { .compatible = "rockchip,rk3368-dfi", .data = rk3368_dfi_init },
+ { .compatible = "rockchip,rk3399-dfi", .data = rockchip_dfi_init },
+ { },
+};
+MODULE_DEVICE_TABLE(of, rockchip_dfi_id_match);
+
+static int rockchip_dfi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct rockchip_dfi *data;
+ struct devfreq_event_desc *desc;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *match;
+ int (*init)(struct platform_device *pdev, struct rockchip_dfi *data,
+ struct devfreq_event_desc *desc);
+
+ data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
if (!desc)
return -ENOMEM;
- desc->ops = &rockchip_dfi_ops;
+ match = of_match_node(rockchip_dfi_id_match, pdev->dev.of_node);
+ if (match) {
+ init = match->data;
+ if (init) {
+ if (init(pdev, data, desc))
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+
desc->driver_data = data;
desc->name = np->name;
data->desc = desc;
+ data->dev = dev;
- data->edev = devm_devfreq_event_add_edev(&pdev->dev, desc);
+ data->edev = devm_devfreq_event_add_edev(dev, desc);
if (IS_ERR(data->edev)) {
- dev_err(&pdev->dev,
- "failed to add devfreq-event device\n");
+ dev_err(dev, "failed to add devfreq-event device\n");
return PTR_ERR(data->edev);
}
--
2.25.1

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +1,11 @@
From d5d5c53173c484a13cda62a537cbf75a5df4b0e4 Mon Sep 17 00:00:00 2001
From: "Miouyouyou (Myy)" <myy@miouyouyou.fr>
Date: Mon, 5 Nov 2018 21:58:56 +0100
Subject: [PATCH] ARM: DTS: rk3288-tinker: Enabling SDIO and Wifi
Adding the appropriate nodes in order to exploit the WiFi capabilities
of the board.
Since these capabilities are provided through SDIO, and the SDIO
nodes were not defined, these were added too.
These seems to depend on each other so they are added in one big
patch.
Split if necessary.
Signed-off-by: Miouyouyou (Myy) <myy@miouyouyou.fr>
---
arch/arm/boot/dts/rk3288-tinker.dts | 62 +++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/arch/arm/boot/dts/rk3288-tinker.dts b/arch/arm/boot/dts/rk3288-tinker.dts
index 1e43527aa..d4df13bed 100644
--- a/arch/arm/boot/dts/rk3288-tinker.dts
+++ b/arch/arm/boot/dts/rk3288-tinker.dts
@@ -6,8 +6,70 @@
/dts-v1/;
#include "rk3288-tinker.dtsi"
+#include <dt-bindings/clock/rockchip,rk808.h>
/ {
model = "Rockchip RK3288 Asus Tinker Board";
compatible = "asus,rk3288-tinker", "rockchip,rk3288";
diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi
index 09618bb7d872..a3eaa029594a 100644
--- a/arch/arm/boot/dts/rk3288-tinker.dtsi
+++ b/arch/arm/boot/dts/rk3288-tinker.dtsi
@@ -105,6 +105,34 @@ vcc_sd: sdmmc-regulator {
startup-delay-us = <100000>;
vin-supply = <&vcc_io>;
};
+
+ /* This is essential to get SDIO devices working.
+ The Wifi depends on SDIO ! */
@ -39,7 +14,7 @@ index 1e43527aa..d4df13bed 100644
+ clocks = <&rk808 RK808_CLKOUT1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&chip_enable_h>, <&wifi_enable_h>;
+ pinctrl-0 = <&wifi_enable>;
+
+ /*
+ * On the module itself this is one of these (depending
@ -58,41 +33,86 @@ index 1e43527aa..d4df13bed 100644
+ wifi_chip_type = "8723bs";
+ WIFI,host_wake_irq = <&gpio4 30 GPIO_ACTIVE_HIGH>;
+ };
+
};
&cpu0 {
@@ -342,7 +370,32 @@ regulator-state-mem {
};
};
+&i2c1 {
+ status = "okay";
+};
+
+&io_domains {
+ wifi-supply = <&vcc_18>;
&i2c2 {
+
+ status = "okay";
+
+ afc0:af-controller@0 {
+ status = "disabled";
+ compatible = "silicon touch,vm149C-v4l2-i2c-subdev";
+ reg = <0x0 0x0c>;
+ };
+
+ eeprom:m24c08@50 {
+ compatible = "at,24c08";
+ reg = <0x50>;
+ };
+
+};
+
+&pinctrl {
+ sdio-pwrseq {
+ wifi_enable_h: wifienable-h {
+ rockchip,pins = <4 28 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+&i2c3 {
+ status = "okay";
+};
+
+ chip_enable_h: chip-enable-h {
+ rockchip,pins = <4 27 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+&i2c4 {
status = "okay";
};
@@ -441,6 +494,7 @@ wifi_enable: wifi-enable {
<4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+
};
&pwm0 {
@@ -469,6 +523,7 @@ &sdio0 {
bus-width = <4>;
cap-sd-highspeed;
cap-sdio-irq;
+ no-sd;
keep-power-in-suspend;
max-frequency = <50000000>;
mmc-pwrseq = <&sdio_pwrseq>;
@@ -489,8 +544,28 @@ &tsadc {
status = "okay";
};
-&uart0 {
+&spi2 {
+ max-freq = <50000000>;
status = "okay";
+
+ spidev@0 {
+ compatible = "rockchip,spi_tinker";
+ reg = <0x0 0>;
+ spi-max-frequency = <50000000>;
+ spi-cpha = <1>;
+ };
+
+ spidev@1 {
+ compatible = "rockchip,spi_tinker";
+ reg = <0x1>;
+ spi-max-frequency = <50000000>;
+ spi-cpha = <1>;
+ };
+};
+
+&sdio0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ clock-frequency = <50000000>;
+ clock-freq-min-max = <200000 50000000>;
+ disable-wp;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ non-removable;
+ num-slots = <1>;
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+ sd-uhs-sdr104;
+ status = "okay";
+ supports-sdio;
+ pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>;
};
--
2.16.4
&uart1 {

View File

@ -1,28 +0,0 @@
From ebc29962ac27264772a4227f5abd6900cb72fa79 Mon Sep 17 00:00:00 2001
From: "Miouyouyou (Myy)" <myy@miouyouyou.fr>
Date: Mon, 5 Nov 2018 20:16:05 +0100
Subject: [PATCH] ARM: DTSI: rk3288-tinker: Improving the CPU max voltage
Taken from the various patches provided by @TonyMac32 .
Signed-off-by: Miouyouyou (Myy) <myy@miouyouyou.fr>
---
arch/arm/boot/dts/rk3288-tinker.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi
index aa107ee41..3da1c830f 100644
--- a/arch/arm/boot/dts/rk3288-tinker.dtsi
+++ b/arch/arm/boot/dts/rk3288-tinker.dtsi
@@ -164,7 +164,7 @@
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1400000>;
+ regulator-max-microvolt = <1450000>;
regulator-name = "vdd_arm";
regulator-ramp-delay = <6000>;
regulator-state-mem {
--
2.16.4

View File

@ -1,53 +0,0 @@
From a72e0749acad92df7b854e38e97e1dc7b4799abe Mon Sep 17 00:00:00 2001
From: "Miouyouyou (Myy)" <myy@miouyouyou.fr>
Date: Mon, 5 Nov 2018 22:11:24 +0100
Subject: [PATCH] ARM: DTS: rk3288-tinker: Defined the I2C interfaces
And all the hardware behind.
Taken from @TonyMac32, Butchered by @Miouyouyou .
Signed-off-by: Miouyouyou (Myy) <myy@miouyouyou.fr>
---
arch/arm/boot/dts/rk3288-tinker.dts | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm/boot/dts/rk3288-tinker.dts b/arch/arm/boot/dts/rk3288-tinker.dts
index b92e59c1e..96d05fc6b 100644
--- a/arch/arm/boot/dts/rk3288-tinker.dts
+++ b/arch/arm/boot/dts/rk3288-tinker.dts
@@ -40,6 +40,31 @@
};
};
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ afc0:af-controller@0 {
+ status = "okay";
+ compatible = "silicon touch,vm149C-v4l2-i2c-subdev";
+ reg = <0x0 0x0c>;
+ };
+
+ eeprom:m24c08@50 {
+ compatible = "at,24c08";
+ reg = <0x50>;
+ };
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
&io_domains {
wifi-supply = <&vcc_18>;
};
--
2.16.4

View File

@ -1,46 +0,0 @@
From 4ab4f88649468dada5d609e1a6f8a71a7d5610c9 Mon Sep 17 00:00:00 2001
From: "Miouyouyou (Myy)" <myy@miouyouyou.fr>
Date: Sat, 29 Sep 2018 02:48:59 +0200
Subject: [PATCH 4/6] dts: rk3288: support for dedicating npll to a vop
This patch is taken from Urja Rannikko ( @urjaman ) patchset here :
https://github.com/urjaman/arch-c201/blob/master/linux-c201/0020-RK3288-HDMI-clock-hacks-combined.patch
https://www.spinics.net/lists/arm-kernel/msg673156.html
The original description was :
Add the VOP DCLKs to the assigned clocks list so their
parents can be set in the dts include files for
devices that do dedicate npll to a vop.
https://www.spinics.net/lists/arm-kernel/msg673162.html
Signed-off-by: Miouyouyou (Myy) <myy@miouyouyou.fr>
---
arch/arm/boot/dts/rk3288.dtsi | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index d23c7fa55..ff04aab5e 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -867,12 +867,14 @@
rockchip,grf = <&grf>;
#clock-cells = <1>;
#reset-cells = <1>;
- assigned-clocks = <&cru PLL_GPLL>, <&cru PLL_CPLL>,
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>,
+ <&cru PLL_GPLL>, <&cru PLL_CPLL>,
<&cru PLL_NPLL>, <&cru ACLK_CPU>,
<&cru HCLK_CPU>, <&cru PCLK_CPU>,
<&cru ACLK_PERI>, <&cru HCLK_PERI>,
<&cru PCLK_PERI>;
- assigned-clock-rates = <594000000>, <400000000>,
+ assigned-clock-rates = <0>, <0>,
+ <594000000>, <400000000>,
<500000000>, <300000000>,
<150000000>, <75000000>,
<300000000>, <150000000>,
--
2.16.4

View File

@ -0,0 +1,20 @@
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 511ca864c1b2..d7ecb6b4de40 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -25,10 +25,10 @@ aliases {
i2c3 = &i2c3;
i2c4 = &i2c4;
i2c5 = &i2c5;
- mshc0 = &emmc;
- mshc1 = &sdmmc;
- mshc2 = &sdio0;
- mshc3 = &sdio1;
+ mmc0 = &sdmmc;
+ mmc1 = &sdio0;
+ mmc2 = &emmc;
+ mmc3 = &sdio1;
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;

View File

@ -1,50 +0,0 @@
From e0c5a419cf5464cd02996431afa98e3b22dc6801 Mon Sep 17 00:00:00 2001
From: Myy <myy@miouyouyou.fr>
Date: Mon, 17 Jul 2017 23:14:48 +0000
Subject: [PATCH] clk: rockchip: add all known operating points to the allowed
CPU freqs
Patch from Willy Tarreau
Original commit message :
At least 1920 MHz runs stable on the MiQi even on openssl speed -multi 4,
which is by far the most intensive workload, and 1992/2016 work fine on
the CS-008 until it starts to heat too much. So add all of them so that
the device tree can simply manipulate them.
Signed-off-by: Myy <myy@miouyouyou.fr>
---
drivers/clk/rockchip/clk-rk3288.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 753c649..fd2058f 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -145,6 +145,23 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = {
}
static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = {
+ RK3288_CPUCLK_RATE(2208000000U, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(2184000000U, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(2160000000U, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(2136000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(2112000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(2088000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(2064000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(2040000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(2016000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(1992000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(1968000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(1944000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(1920000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(1896000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(1872000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(1848000000, 1, 3, 1, 3, 3),
+ RK3288_CPUCLK_RATE(1824000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE(1800000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE(1704000000, 1, 3, 1, 3, 3),
RK3288_CPUCLK_RATE(1608000000, 1, 3, 1, 3, 3),
--
2.10.2

View File

@ -0,0 +1,351 @@
From 61e72bc8b70714ba7b6418191b46489caa8db1ac Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Mon, 25 Dec 2023 18:24:11 +0100
Subject: [PATCH] add rockchip drm cursor plane
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 218 +++++++++++++++++++-
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 3 +
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 23 ++-
3 files changed, 240 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 023b406ce3c7..f2654968d68f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1189,6 +1189,207 @@ static void vop_plane_atomic_async_update(struct drm_plane *plane,
}
}
+static void vop_cursor_atomic_update(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+{
+
+ struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
+ plane);
+ struct drm_crtc *crtc = new_state->crtc;
+ struct vop_win *vop_win = to_vop_win(plane);
+ const struct vop_win_data *win = vop_win->data;
+ struct vop *vop = to_vop(new_state->crtc);
+ struct drm_framebuffer *fb = new_state->fb;
+ unsigned int actual_w, actual_h;
+ unsigned int dsp_stx, dsp_sty;
+ uint32_t dsp_st;
+ struct drm_rect *src = &new_state->src;
+ struct drm_rect *dest = &new_state->dst;
+ struct drm_gem_object *obj;
+ struct rockchip_gem_object *rk_obj;
+ dma_addr_t dma_addr;
+ uint32_t val;
+ bool rb_swap;
+ int win_index = VOP_WIN_TO_INDEX(vop_win);
+ int format;
+
+ /*
+ * can't update plane when vop is disabled.
+ */
+ if (WARN_ON(!crtc))
+ return;
+
+ if (WARN_ON(!vop->is_enabled))
+ return;
+
+ if (!new_state->visible) {
+ vop_plane_atomic_disable(plane, state);
+ return;
+ }
+
+ obj = fb->obj[0];
+ rk_obj = to_rockchip_obj(obj);
+
+// actual_w = drm_rect_width(src) >> 16;
+// actual_h = drm_rect_height(src) >> 16;
+
+ dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start;
+ dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
+ dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
+
+ dma_addr = rk_obj->dma_addr;
+
+ /*
+ * For y-mirroring we need to move address
+ * to the beginning of the last line.
+ */
+// if (new_state->rotation & DRM_MODE_REFLECT_Y)
+// dma_addr += (actual_h - 1) * fb->pitches[0];
+
+ spin_lock(&vop->reg_lock);
+
+ if (!(vop->win_enabled & BIT(win_index))) {
+
+ format = vop_convert_format(fb->format->format);
+
+ VOP_WIN_SET(vop, win, format, format);
+
+// if (win->phy->scl)
+// scl_vop_cal_scl_fac(vop, win, actual_w, actual_h,
+// drm_rect_width(dest), drm_rect_height(dest),
+// fb->format);
+
+ rb_swap = has_rb_swapped(vop->data->version, fb->format->format);
+ VOP_WIN_SET(vop, win, rb_swap, rb_swap);
+
+ /*
+ * Blending win0 with the background color doesn't seem to work
+ * correctly. We only get the background color, no matter the contents
+ * of the win0 framebuffer. However, blending pre-multiplied color
+ * with the default opaque black default background color is a no-op,
+ * so we can just disable blending to get the correct result.
+ */
+ if (fb->format->has_alpha && win_index > 0) {
+ VOP_WIN_SET(vop, win, dst_alpha_ctl,
+ DST_FACTOR_M0(ALPHA_SRC_INVERSE));
+ val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
+ SRC_ALPHA_M0(ALPHA_STRAIGHT) |
+ SRC_BLEND_M0(ALPHA_PER_PIX) |
+ SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) |
+ SRC_FACTOR_M0(ALPHA_ONE);
+ VOP_WIN_SET(vop, win, src_alpha_ctl, val);
+
+ VOP_WIN_SET(vop, win, alpha_pre_mul, ALPHA_SRC_PRE_MUL);
+ VOP_WIN_SET(vop, win, alpha_mode, ALPHA_PER_PIX);
+ VOP_WIN_SET(vop, win, alpha_en, 1);
+ } else {
+ VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0));
+ VOP_WIN_SET(vop, win, alpha_en, 0);
+ }
+
+ // 32x32 = 0, 64x64 = 1, 96x96 = 2, 128x128 = 3
+ VOP_WIN_SET(vop, win, hwc_size, (new_state->crtc_w >> 5) - 1);
+
+ VOP_WIN_SET(vop, win, enable, 1);
+ vop->win_enabled |= BIT(win_index);
+
+ }
+
+ VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
+ VOP_WIN_SET(vop, win, dsp_st, dsp_st);
+
+ spin_unlock(&vop->reg_lock);
+
+}
+
+static void vop_cursor_atomic_async_update(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+{
+
+ struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
+ plane);
+ struct vop *vop = to_vop(plane->state->crtc);
+ struct drm_framebuffer *old_fb = plane->state->fb;
+
+ plane->state->crtc_x = new_state->crtc_x;
+ plane->state->crtc_y = new_state->crtc_y;
+ plane->state->crtc_h = new_state->crtc_h;
+ plane->state->crtc_w = new_state->crtc_w;
+ plane->state->src_x = new_state->src_x;
+ plane->state->src_y = new_state->src_y;
+ plane->state->src_h = new_state->src_h;
+ plane->state->src_w = new_state->src_w;
+ swap(plane->state->fb, new_state->fb);
+
+ if (vop->is_enabled) {
+ vop_cursor_atomic_update(plane, state);
+ spin_lock(&vop->reg_lock);
+ vop_cfg_done(vop);
+ spin_unlock(&vop->reg_lock);
+
+ /*
+ * A scanout can still be occurring, so we can't drop the
+ * reference to the old framebuffer. To solve this we get a
+ * reference to old_fb and set a worker to release it later.
+ * FIXME: if we perform 500 async_update calls before the
+ * vblank, then we can have 500 different framebuffers waiting
+ * to be released.
+ */
+ if (old_fb && plane->state->fb != old_fb) {
+ drm_framebuffer_get(old_fb);
+ WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
+ drm_flip_work_queue(&vop->fb_unref_work, old_fb);
+ set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
+ }
+ }
+
+}
+
+static int vop_cursor_atomic_check(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+{
+ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
+ plane);
+ struct drm_crtc *crtc = new_plane_state->crtc;
+ struct drm_crtc_state *crtc_state;
+ struct drm_framebuffer *fb = new_plane_state->fb;
+ int ret;
+
+ if (!crtc || WARN_ON(!fb))
+ return 0;
+
+ crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
+ if (WARN_ON(!crtc_state))
+ return -EINVAL;
+
+ ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
+ DRM_PLANE_NO_SCALING, DRM_PLANE_NO_SCALING,
+ true, true);
+
+ if (ret)
+ return ret;
+
+ if (!new_plane_state->visible)
+ return 0;
+
+ ret = vop_convert_format(fb->format->format);
+ if (ret < 0)
+ return ret;
+
+ if (new_plane_state->crtc_w != new_plane_state->crtc_h)
+ return -EINVAL;
+
+ if (new_plane_state->crtc_w != 0 &&
+ new_plane_state->crtc_w != 32 &&
+ new_plane_state->crtc_w != 64 &&
+ new_plane_state->crtc_w != 96 &&
+ new_plane_state->crtc_w != 128)
+ return -EINVAL;
+
+ return 0;
+
+}
+
static const struct drm_plane_helper_funcs plane_helper_funcs = {
.atomic_check = vop_plane_atomic_check,
.atomic_update = vop_plane_atomic_update,
@@ -1197,6 +1398,15 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
.atomic_async_update = vop_plane_atomic_async_update,
};
+static const struct drm_plane_helper_funcs cursor_plane_helper_funcs = {
+ .atomic_check = vop_cursor_atomic_check,
+ .atomic_update = vop_cursor_atomic_update,
+ .atomic_disable = vop_plane_atomic_disable,
+ .atomic_async_check = vop_plane_atomic_async_check,
+ .atomic_async_update = vop_cursor_atomic_async_update,
+ .prepare_fb = drm_gem_plane_helper_prepare_fb,
+};
+
static const struct drm_plane_funcs vop_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
@@ -2022,6 +2232,7 @@ static int vop_create_crtc(struct vop *vop)
struct drm_plane *primary = NULL, *cursor = NULL, *plane, *tmp;
struct drm_crtc *crtc = &vop->crtc;
struct device_node *port;
+ const struct drm_plane_helper_funcs *helper_funcs;
int ret;
int i;
@@ -2042,7 +2253,12 @@ static int vop_create_crtc(struct vop *vop)
}
plane = &vop_win->base;
- drm_plane_helper_add(plane, &plane_helper_funcs);
+ helper_funcs = &plane_helper_funcs;
+
+ if ((plane->type == DRM_PLANE_TYPE_CURSOR) && (vop_data->feature & VOP_FEATURE_SPECIAL_CURSOR_PLANE))
+ helper_funcs = &cursor_plane_helper_funcs;
+
+ drm_plane_helper_add(plane, helper_funcs);
vop_plane_add_properties(plane, i, win_data, vop_data);
if (plane->type == DRM_PLANE_TYPE_PRIMARY)
primary = plane;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 94a615dca672..60dda489c9d3 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -207,6 +207,8 @@ struct vop_win_phy {
struct vop_reg alpha_mode;
struct vop_reg alpha_en;
struct vop_reg channel;
+
+ struct vop_reg hwc_size;
};
struct vop_win_yuv2yuv_data {
@@ -242,6 +244,7 @@ struct vop_data {
#define VOP_FEATURE_OUTPUT_RGB10 BIT(0)
#define VOP_FEATURE_INTERNAL_RGB BIT(1)
+#define VOP_FEATURE_SPECIAL_CURSOR_PLANE BIT(2)
u64 feature;
};
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index be582c1e562a..f1d432f50949 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -674,6 +674,19 @@ static const struct vop_win_phy rk3288_win23_data = {
.dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
};
+static const struct vop_win_phy rk3288_cursor_data = {
+ .data_formats = formats_win_lite,
+ .nformats = ARRAY_SIZE(formats_win_lite),
+ .enable = VOP_REG(RK3288_HWC_CTRL0, 0x1, 0),
+ .format = VOP_REG(RK3288_HWC_CTRL0, 0x7, 1),
+ .rb_swap = VOP_REG(RK3288_HWC_CTRL0, 0x1, 12),
+ .dsp_st = VOP_REG(RK3288_HWC_DSP_ST, 0x1fff1fff, 0),
+ .yrgb_mst = VOP_REG(RK3288_HWC_MST, 0xffffffff, 0),
+ .src_alpha_ctl = VOP_REG(RK3288_HWC_SRC_ALPHA_CTRL, 0xff, 0),
+ .dst_alpha_ctl = VOP_REG(RK3288_HWC_DST_ALPHA_CTRL, 0xff, 0),
+ .hwc_size = VOP_REG(RK3288_HWC_CTRL0, 0x3, 5),
+};
+
static const struct vop_modeset rk3288_modeset = {
.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
@@ -767,6 +780,8 @@ static const struct vop_win_data rk3288_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win23_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x50, .phy = &rk3288_win23_data,
+ .type = DRM_PLANE_TYPE_OVERLAY },
+ { .base = 0x00, .phy = &rk3288_cursor_data,
.type = DRM_PLANE_TYPE_CURSOR },
};
@@ -788,7 +803,7 @@ static const struct vop_intr rk3288_vop_intr = {
static const struct vop_data rk3288_vop_big = {
.version = VOP_VERSION(3, 1),
- .feature = VOP_FEATURE_OUTPUT_RGB10,
+ .feature = VOP_FEATURE_OUTPUT_RGB10 | VOP_FEATURE_SPECIAL_CURSOR_PLANE,
.max_output = { 3840, 2160 },
.intr = &rk3288_vop_intr,
.common = &rk3288_common,
@@ -801,7 +816,7 @@ static const struct vop_data rk3288_vop_big = {
static const struct vop_data rk3288_vop_lit = {
.version = VOP_VERSION(3, 1),
- .feature = VOP_FEATURE_OUTPUT_RGB10,
+ .feature = VOP_FEATURE_OUTPUT_RGB10 | VOP_FEATURE_SPECIAL_CURSOR_PLANE,
.max_output = { 2560, 1600 },
.intr = &rk3288_vop_intr,
.common = &rk3288_common,
@@ -1106,11 +1121,13 @@ static const struct vop_win_data rk3228_vop_win_data[] = {
.type = DRM_PLANE_TYPE_PRIMARY },
{ .base = 0x40, .phy = &rk3228_win1_data,
.type = DRM_PLANE_TYPE_OVERLAY },
+ { .base = 0x00, .phy = &rk3288_cursor_data,
+ .type = DRM_PLANE_TYPE_CURSOR },
};
static const struct vop_data rk3228_vop = {
.version = VOP_VERSION(3, 7),
- .feature = VOP_FEATURE_OUTPUT_RGB10,
+ .feature = VOP_FEATURE_OUTPUT_RGB10 | VOP_FEATURE_SPECIAL_CURSOR_PLANE,
.max_output = { 4096, 2160 },
.intr = &rk3366_vop_intr,
.common = &rk3288_common,
--
2.34.1

View File

@ -1,80 +0,0 @@
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 58bd91539..9c0dac199 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -153,6 +153,75 @@
opp-hz = /bits/ 64 <1608000000>;
opp-microvolt = <1350000>;
};
+ opp@1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <1350000>;
+ };
+ opp@1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <1400000>;
+ };
+ /* boot-only frequencies below */
+ opp@1896000000 {
+ opp-hz = /bits/ 64 <1896000000>;
+ opp-microvolt = <1425000>;
+ turbo-mode;
+ };
+ opp@1920000000 {
+ opp-hz = /bits/ 64 <1920000000>;
+ opp-microvolt = <1425000>;
+ turbo-mode;
+ };
+ opp@1992000000 {
+ opp-hz = /bits/ 64 <1992000000>;
+ opp-microvolt = <1450000>;
+ turbo-mode;
+ };
+ opp@2016000000 {
+ opp-hz = /bits/ 64 <2016000000>;
+ opp-microvolt = <1475000>;
+ turbo-mode;
+ };
+ opp@2040000000 {
+ opp-hz = /bits/ 64 <2040000000>;
+ opp-microvolt = <1475000>;
+ turbo-mode;
+ };
+ opp@2064000000 {
+ opp-hz = /bits/ 64 <2064000000>;
+ opp-microvolt = <1475000>;
+ turbo-mode;
+ };
+ opp@2088000000 {
+ opp-hz = /bits/ 64 <2088000000>;
+ opp-microvolt = <1500000>;
+ turbo-mode;
+ };
+ opp@2112000000 {
+ opp-hz = /bits/ 64 <2112000000>;
+ opp-microvolt = <1500000>;
+ turbo-mode;
+ };
+ opp@2136000000 {
+ opp-hz = /bits/ 64 <2136000000>;
+ opp-microvolt = <1500000>;
+ turbo-mode;
+ };
+ opp@2160000000 {
+ opp-hz = /bits/ 64 <2160000000>;
+ opp-microvolt = <1500000>;
+ turbo-mode;
+ };
+ opp@2184000000 {
+ opp-hz = /bits/ 64 <2184000000>;
+ opp-microvolt = <1500000>;
+ turbo-mode;
+ };
+ opp@2208000000 {
+ opp-hz = /bits/ 64 <2208000000>;
+ opp-microvolt = <1500000>;
+ turbo-mode;
+ };
};
amba {

View File

@ -0,0 +1,782 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/pwm/pwm.h>
#include "rk322x.dtsi"
/ {
model = "Generic RK322x Tv Box board";
compatible = "rockchip,rk3229";
/*
* No need to reserve memory manually as long as u-boot v2020.10 and
* OPTEE autoconfigure the reserved zones
*/
/delete-node/ reserved-memory;
/*
* We rebuild the cpu-opp-table by ourselves
*/
/delete-node/ opp-table-0;
/*
* Rebuild the thermal zones and cooling maps ourselved
*/
/delete-node/ thermal-zones;
/*
* Include the mmc devices into aliases table
*/
aliases {
mmc0 = &sdmmc;
mmc1 = &sdio;
mmc2 = &emmc;
};
analog-sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,name = "analog";
simple-audio-card,cpu {
sound-dai = <&i2s1>;
};
simple-audio-card,codec {
sound-dai = <&codec>;
};
};
chosen {
bootargs = "earlyprintk=uart8250,mmio32,0x11030000";
};
cpu0_opp_table: opp-table-0 {
compatible = "operating-points-v2";
opp-shared;
opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <975000>;
clock-latency-ns = <40000>;
opp-suspend;
};
opp-816000000 {
opp-hz = /bits/ 64 <816000000>;
opp-microvolt = <1000000>;
};
opp-1008000000 {
opp-hz = /bits/ 64 <1008000000>;
opp-microvolt = <1175000>;
};
opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <1275000>;
};
};
gpio_leds: gpio-leds {
compatible = "gpio-leds";
/*
* Working led, available on all boards
*/
working {
gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
label = "working";
default-state = "on";
linux,default-trigger = "timer";
pinctrl-names = "default";
pinctrl-0 = <&gpio_led_working>;
};
};
gpio_keys: gpio-keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
};
ir_receiver: ir-receiver {
compatible = "gpio-ir-receiver";
gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&ir_int>;
pinctrl-names = "default";
status = "okay";
linux,rc-map-name = "rc-rk322x-tvbox";
};
rockchip_ir_receiver: rockchip-ir-receiver {
compatible = "rockchip-ir-receiver";
reg = <0x110b0030 0x10>;
gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_LOW>;
clocks = <&cru PCLK_PWM>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
linux,rc-map-name = "rc-rk322x-tvbox";
pinctrl-names = "default", "suspend";
pinctrl-0 = <&ir_int>;
pinctrl-1 = <&pwm3_pin>;
pwm-id = <3>;
shutdown-is-virtual-poweroff;
wakeup-source;
status = "disabled";
};
sdio_pwrseq: sdio-pwrseq {
compatible = "mmc-pwrseq-simple";
pinctrl-names = "default";
pinctrl-0 = <&wifi_enable_h>;
reset-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_LOW>;
};
spdif_out: spdif-out {
status = "okay";
compatible = "linux,spdif-dit";
#sound-dai-cells = <0>;
};
spdif-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "SPDIF";
simple-audio-card,cpu {
sound-dai = <&spdif>;
};
simple-audio-card,codec {
sound-dai = <&spdif_out>;
};
};
vcc_sys: vcc-sys-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_sys";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
vcc_host: vcc-host-regulator {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&host_vbus_drv>;
regulator-name = "vcc_host";
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc_sys>;
};
vccio_1v8: vccio-1v8-regulator {
compatible = "regulator-fixed";
regulator-name = "vccio_1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
vin-supply = <&vcc_sys>;
};
vccio_3v3: vccio-3v3-regulator {
compatible = "regulator-fixed";
regulator-name = "vccio_3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
vin-supply = <&vcc_sys>;
};
vcc_otg: vcc-otg-regulator {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&otg_vbus_drv>;
regulator-name = "vcc_otg_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc_sys>;
};
vcc_phy: vcc-phy-regulator {
compatible = "regulator-fixed";
enable-active-high;
regulator-name = "vcc_phy";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
vin-supply = <&vccio_1v8>;
};
vdd_arm: vdd-arm-regulator {
compatible = "pwm-regulator";
pwms = <&pwm1 0 5000 PWM_POLARITY_INVERTED>;
pwm-supply = <&vcc_sys>;
regulator-name = "vdd_arm";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1400000>;
regulator-always-on;
regulator-boot-on;
};
vdd_log: vdd-log-regulator {
compatible = "pwm-regulator";
pwms = <&pwm2 0 5000 PWM_POLARITY_INVERTED>;
pwm-supply = <&vcc_sys>;
regulator-name = "vdd_log";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
regulator-boot-on;
};
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <1000>; /* milliseconds */
polling-delay = <5000>; /* milliseconds */
thermal-sensors = <&tsadc 0>;
trips {
cpu_alert0: cpu_alert0 {
temperature = <90000>; /* millicelsius */
hysteresis = <2000>; /* millicelsius */
type = "passive";
};
cpu_alert1: cpu_alert1 {
temperature = <95000>; /* millicelsius */
hysteresis = <2000>; /* millicelsius */
type = "passive";
};
cpu_crit: cpu_crit {
temperature = <105000>; /* millicelsius */
hysteresis = <2000>; /* millicelsius */
type = "critical";
};
};
cooling-maps {
cpu_throttle_low: map-cpu-throttle-low {
trip = <&cpu_alert0>;
cooling-device =
<&cpu0 THERMAL_NO_LIMIT 1>,
<&cpu1 THERMAL_NO_LIMIT 1>,
<&cpu2 THERMAL_NO_LIMIT 1>,
<&cpu3 THERMAL_NO_LIMIT 1>;
};
cpu_throttle_high: map-cpu-throttle-high {
trip = <&cpu_alert1>;
cooling-device =
<&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
gpu_throttle_low: map-gpu-throttle-low {
trip = <&cpu_alert0>;
cooling-device =
<&gpu THERMAL_NO_LIMIT 1>;
};
gpu_throttle_high: map-gpu-throttle-high {
trip = <&cpu_alert1>;
cooling-device =
<&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
dmc_throttle_low: map-dmc-throttle-low {
trip = <&cpu_alert0>;
cooling-device = <&dmc THERMAL_NO_LIMIT 1>;
};
dmc_throttle_high: map-dmc-throttle-high {
trip = <&cpu_alert1>;
cooling-device = <&dmc THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};
};
&codec {
#sound-dai-cells = <0>;
status = "okay";
};
&cpu0 {
cpu-supply = <&vdd_arm>;
};
&cpu1 {
cpu-supply = <&vdd_arm>;
};
&cpu2 {
cpu-supply = <&vdd_arm>;
};
&cpu3 {
cpu-supply = <&vdd_arm>;
};
&cru {
assigned-clocks = <&cru PLL_GPLL>, <&cru ARMCLK>,
<&cru PLL_CPLL>, <&cru ACLK_PERI>,
<&cru HCLK_PERI>, <&cru PCLK_PERI>,
<&cru ACLK_CPU>, <&cru HCLK_CPU>,
<&cru PCLK_CPU>, <&cru ACLK_VOP>;
assigned-clock-rates = <1200000000>, <816000000>,
<500000000>, <150000000>,
<150000000>, <75000000>,
<150000000>, <150000000>,
<75000000>, <400000000>;
};
&dmc {
logic-supply = <&vdd_log>;
};
&emmc {
cap-mmc-highspeed;
keep-power-in-suspend;
non-removable;
status = "okay";
/delete-property/ mmc-ddr-1_8v;
/delete-property/ pinctrl-names;
/delete-property/ pinctrl-0;
/delete-property/ rockchip,default-sample-phase;
rockchip,default-sample-phase = <90>;
};
&gmac {
assigned-clocks = <&cru SCLK_MAC_SRC>;
assigned-clock-rates = <50000000>;
clock_in_out = "output";
phy-handle = <&phy>;
phy-mode = "rmii";
phy-supply = <&vcc_phy>;
tx_delay = <0x26>;
rx_delay = <0x11>;
status = "okay";
mdio {
compatible = "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
phy: phy@0 {
compatible = "ethernet-phy-id1234.d400",
"ethernet-phy-ieee802.3-c22";
reg = <0>;
clocks = <&cru SCLK_MAC_PHY>;
phy-is-integrated;
resets = <&cru SRST_MACPHY>;
};
};
};
&gpu {
assigned-clocks = <&cru ACLK_GPU>;
assigned-clock-rates = <300000000>;
mali-supply = <&vdd_log>;
};
&gpu_opp_table {
opp-400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <1100000 1000000 1200000>;
};
};
&io_domains {
vccio1-supply = <&vccio_3v3>;
vccio2-supply = <&vccio_1v8>;
vccio4-supply = <&vccio_3v3>;
status = "okay";
};
&nfc {
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
/delete-property/ pinctrl-names;
/delete-property/ pinctrl-0;
nand@0 {
reg = <0>;
label = "rk-nand";
nand-bus-width = <8>;
nand-ecc-mode = "hw";
nand-ecc-step-size = <1024>;
nand-ecc-strength = <60>;
nand-is-boot-medium;
rockchip,boot-blks = <8>;
rockchip,boot-ecc-strength = <60>;
};
};
&iep {
status = "okay";
};
&iep_mmu {
status = "okay";
};
&pwm1 {
status = "okay";
};
&pwm2 {
status = "okay";
};
&hdmi {
status = "okay";
};
&hdmi_sound {
status = "okay";
};
&hdmi_phy {
status = "okay";
};
&i2s0 {
status = "okay";
};
&i2s1 {
#sound-dai-cells = <0>;
status = "okay";
};
/** Integration to pin controller */
&pinctrl {
pcfg_pull_up_12ma: pcfg-pull-up-12ma {
drive-strength = <12>;
bias-pull-up;
};
pcfg_pull_down_12ma: pcfg-pull-down-12ma {
drive-strength = <12>;
bias-pull-down;
};
pcfg_pull_none_12ma: pcfg-pull-none-12ma {
drive-strength = <12>;
bias-disable;
};
pcfg_pull_up_8ma: pcfg-pull-up-8ma {
drive-strength = <8>;
bias-pull-up;
};
pcfg_pull_down_8ma: pcfg-pull-down-8ma {
drive-strength = <8>;
bias-pull-down;
};
pcfg_pull_none_8ma: pcfg-pull-none-8ma {
drive-strength = <8>;
bias-disable;
};
pcfg_pull_up_2ma: pcfg-pull-up-2ma {
drive-strength = <2>;
bias-pull-up;
};
pcfg_pull_down_2ma: pcfg-pull-down-2ma {
drive-strength = <2>;
bias-pull-down;
};
pcfg_pull_none_2ma: pcfg-pull-none-2ma {
drive-strength = <2>;
bias-disable;
};
/*
* Some rk322x electrical schemes report this kind of pull-up/down
* pin configurations. We set them here, but we don't use it in this
* device tree. These instead are useful for overlays, because they seem
* to increase stability on at least one board I got here
*/
sdmmc {
sdmmc_clk: sdmmc-clk {
rockchip,pins = <1 16 1 &pcfg_pull_down>;
};
sdmmc_cmd: sdmmc-cmd {
rockchip,pins = <1 15 1 &pcfg_pull_up>;
};
sdmmc_bus4: sdmmc-bus4 {
rockchip,pins = <1 18 1 &pcfg_pull_up>,
<1 19 1 &pcfg_pull_up>,
<1 20 1 &pcfg_pull_up>,
<1 21 1 &pcfg_pull_up>;
};
};
/*
* Same as above, decreasing strength of SDIO pins seems to be benefical
* to stability
*/
sdio {
sdio_clk: sdio-clk {
rockchip,pins = <3 0 1 &pcfg_pull_down_2ma>;
};
sdio_cmd: sdio-cmd {
rockchip,pins = <3 1 1 &pcfg_pull_up_2ma>;
};
sdio_bus4: sdio-bus4 {
rockchip,pins = <3 2 1 &pcfg_pull_up_2ma>,
<3 3 1 &pcfg_pull_up_2ma>,
<3 4 1 &pcfg_pull_up_2ma>,
<3 5 1 &pcfg_pull_up_2ma>;
};
};
/*
* Same drill as above, electrical schemes also report this pull-up/down
* configurations.
*/
emmc {
emmc_clk: emmc-clk {
rockchip,pins = <2 7 2 &pcfg_pull_up>;
};
emmc_cmd: emmc-cmd {
rockchip,pins = <1 22 2 &pcfg_pull_up>;
};
emmc_bus8: emmc-bus8 {
rockchip,pins = <1 24 2 &pcfg_pull_up>,
<1 25 2 &pcfg_pull_up>,
<1 26 2 &pcfg_pull_up>,
<1 27 2 &pcfg_pull_up>,
<1 28 2 &pcfg_pull_up>,
<1 29 2 &pcfg_pull_up>,
<1 30 2 &pcfg_pull_up>,
<1 31 2 &pcfg_pull_up>;
};
emmc_pwr: emmc-pwr {
rockchip,pins = <2 RK_PA5 2 &pcfg_pull_down>;
};
emmc_rst: emmc-rst {
rockchip,pins = <1 RK_PC7 2 &pcfg_pull_up>;
};
};
gpio-items {
gpio_led_working: gpio-led-working {
rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
ir {
ir_int: ir-int {
rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
pwm1 {
pwm1_pin_pull_down: pwm1-pin-pull-down {
rockchip,pins = <0 RK_PD6 2 &pcfg_pull_down>;
};
};
pwm2 {
pwm2_pin_pull_up: pwm2-pin-pull-up {
rockchip,pins = <1 RK_PB4 2 &pcfg_pull_up>;
};
};
usb {
host_vbus_drv: host-vbus-drv {
rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
};
otg_vbus_drv: otg-vbus-drv {
rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
sdio-pwrseq {
wifi_enable_h: wifi-enable-h {
rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart11_xfer &uart11_rts &uart11_cts>;
};
&uart2 {
status = "okay";
};
&u2phy0 {
status = "okay";
u2phy0_host: host-port {
phy-supply = <&vcc_host>;
};
u2phy0_otg: otg-port {
phy-supply = <&vcc_otg>;
};
};
&u2phy0_otg {
status = "okay";
};
&u2phy0_host {
status = "okay";
};
&u2phy1 {
status = "okay";
u2phy1_host: host-port {
phy-supply = <&vcc_host>;
};
u2phy1_otg: otg-port {
phy-supply = <&vcc_otg>;
};
};
&u2phy1_otg {
status = "okay";
};
&u2phy1_host {
status = "okay";
};
&usb_host0_ehci {
status = "okay";
};
&usb_host0_ohci {
status = "okay";
};
&usb_host1_ehci {
status = "okay";
};
&usb_host1_ohci {
status = "okay";
};
&usb_host2_ehci {
status = "okay";
};
&usb_host2_ohci {
status = "okay";
};
&usb_otg {
dr_mode = "host";
status = "okay";
};
&sdio {
mmc-pwrseq = <&sdio_pwrseq>;
cap-sd-highspeed;
cap-sdio-irq;
keep-power-in-suspend;
non-removable;
no-sd;
status = "okay";
};
&sdmmc {
cd-gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_LOW>;
cd-debounce-delay-ms = <500>;
cap-sd-highspeed;
keep-power-in-suspend;
no-sdio;
status = "okay";
};
&spdif {
status = "okay";
};
&tsadc {
rockchip,grf = <&grf>;
rockchip,hw-tshut-mode = <0>;
rockchip,hw-tshut-polarity = <1>;
rockchip,hw-tshut-temp = <110000>;
/* delete the pinctrl-* properties because, on mainline kernel, they (in particular "default")
change the GPIO configuration of the associated PIN. On most boards that pin is not connected
so it does not do anything, but some other boards (X96-Mini) have that pin connected to
a reset pin of the soc or whatever, thus changing the configuration of the pin at boot
causes them to bootloop.
We don't really need these ones though, because since hw-tshut-mode is set to 0, the CRU
unit of the SoC does the reboot*/
/delete-property/ pinctrl-names;
/delete-property/ pinctrl-0;
/delete-property/ pinctrl-1;
/delete-property/ pinctrl-2;
status = "okay";
};
&vop {
assigned-clocks = <&cru DCLK_VOP>;
assigned-clock-parents = <&cru SCLK_HDMI_PHY>;
status = "okay";
};
&vop_mmu {
status = "okay";
};
&wdt {
status = "okay";
};

View File

@ -26,7 +26,7 @@ index 50d580d77..94bd15617 100644
@:
quiet_cmd_dtb_install = INSTALL $@
@@ -29,6 +32,15 @@ quiet_cmd_dtb_install = INSTALL $@
@@ -29,6 +32,18 @@ quiet_cmd_dtb_install = INSTALL $@
$(dst)/%.dtb: $(obj)/%.dtb
$(call cmd,dtb_install)
@ -36,6 +36,9 @@ index 50d580d77..94bd15617 100644
+$(dst)/%.scr: $(obj)/%.scr
+ $(call cmd,dtb_install)
+
+$(dst)/README.rk322x-overlays: $(src)/README.rk322x-overlays
+ $(call cmd,dtb_install)
+
+$(dst)/README.rockchip-overlays: $(src)/README.rockchip-overlays
+ $(call cmd,dtb_install)
+

View File

@ -0,0 +1,358 @@
--- /dev/null
+++ b/Documentation/devicetree/configfs-overlays.txt
@@ -0,0 +1,31 @@
+Howto use the configfs overlay interface.
+
+A device-tree configfs entry is created in /config/device-tree/overlays
+and and it is manipulated using standard file system I/O.
+Note that this is a debug level interface, for use by developers and
+not necessarily something accessed by normal users due to the
+security implications of having direct access to the kernel's device tree.
+
+* To create an overlay you mkdir the directory:
+
+ # mkdir /config/device-tree/overlays/foo
+
+* Either you echo the overlay firmware file to the path property file.
+
+ # echo foo.dtbo >/config/device-tree/overlays/foo/path
+
+* Or you cat the contents of the overlay to the dtbo file
+
+ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo
+
+The overlay file will be applied, and devices will be created/destroyed
+as required.
+
+To remove it simply rmdir the directory.
+
+ # rmdir /config/device-tree/overlays/foo
+
+The rationalle of the dual interface (firmware & direct copy) is that each is
+better suited to different use patterns. The firmware interface is what's
+intended to be used by hardware managers in the kernel, while the copy interface
+make sense for developers (since it avoids problems with namespaces).
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 37c2ccbefecdc..d3fc81a40c0e7 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -103,4 +103,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
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 663a4af0cccd5..b00a95adf5199 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-y = base.o device.o platform.o property.o
obj-$(CONFIG_OF_KOBJ) += kobj.o
+obj-$(CONFIG_OF_CONFIGFS) += configfs.o
obj-$(CONFIG_OF_DYNAMIC) += dynamic.o
obj-$(CONFIG_OF_FLATTREE) += fdt.o
obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c
new file mode 100644
index 000000000..5dd509e8f
--- /dev/null
+++ b/drivers/of/configfs.c
@@ -0,0 +1,290 @@
+/*
+ * 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 int create_overlay(struct cfs_overlay_item *overlay, void *blob, u32 blob_size)
+{
+ int err;
+
+ err = of_overlay_fdt_apply(blob, blob_size, &overlay->ov_id);
+ if (err < 0) {
+ pr_err("%s: Failed to create overlay (err=%d)\n",
+ __func__, err);
+ goto out_err;
+ }
+
+out_err:
+ return err;
+}
+
+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)
+ goto out_err;
+
+ err = create_overlay(overlay, (void *)overlay->fw->data, overlay->fw->size);
+ 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 = create_overlay(overlay, overlay->dtbo, overlay->dtbo_size);
+ if (err != 0)
+ goto out_err;
+
+ return count;
+
+out_err:
+ kfree(overlay->dtbo);
+ overlay->dtbo = NULL;
+ overlay->dtbo_size = 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);
+ overlay->ov_id = -1;
+
+ 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);

View File

@ -1,483 +0,0 @@
From f714d89ebd3ee718cb7ab8574ec92407b50b5aee Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Sun, 20 Mar 2022 09:30:24 +0000
Subject: [PATCH] rk3288: general add overlays
---
arch/arm/boot/dts/overlay/Makefile | 26 +++++++
.../boot/dts/overlay/README.rockchip-overlays | 78 +++++++++++++++++++
arch/arm/boot/dts/overlay/rockchip-ds1307.dts | 23 ++++++
.../boot/dts/overlay/rockchip-fixup.scr-cmd | 4 +
arch/arm/boot/dts/overlay/rockchip-i2c1.dts | 16 ++++
arch/arm/boot/dts/overlay/rockchip-i2c4.dts | 16 ++++
arch/arm/boot/dts/overlay/rockchip-spi0.dts | 16 ++++
arch/arm/boot/dts/overlay/rockchip-spi2.dts | 16 ++++
.../arm/boot/dts/overlay/rockchip-spidev0.dts | 35 +++++++++
.../arm/boot/dts/overlay/rockchip-spidev2.dts | 35 +++++++++
arch/arm/boot/dts/overlay/rockchip-uart1.dts | 16 ++++
arch/arm/boot/dts/overlay/rockchip-uart2.dts | 16 ++++
arch/arm/boot/dts/overlay/rockchip-uart3.dts | 16 ++++
arch/arm/boot/dts/overlay/rockchip-uart4.dts | 16 ++++
.../arm/boot/dts/overlay/rockchip-w1-gpio.dts | 23 ++++++
15 files changed, 352 insertions(+)
create mode 100644 arch/arm/boot/dts/overlay/Makefile
create mode 100644 arch/arm/boot/dts/overlay/README.rockchip-overlays
create mode 100644 arch/arm/boot/dts/overlay/rockchip-ds1307.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-fixup.scr-cmd
create mode 100644 arch/arm/boot/dts/overlay/rockchip-i2c1.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-i2c4.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-spi0.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-spi2.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-spidev0.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-spidev2.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-uart1.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-uart2.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-uart3.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-uart4.dts
create mode 100644 arch/arm/boot/dts/overlay/rockchip-w1-gpio.dts
diff --git a/arch/arm/boot/dts/overlay/Makefile b/arch/arm/boot/dts/overlay/Makefile
new file mode 100644
index 00000000000..56d8cb187aa
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/Makefile
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0
+dtbo-$(CONFIG_ARCH_ROCKCHIP) += \
+ rockchip-ds1307.dtbo \
+ rockchip-i2c1.dtbo \
+ rockchip-i2c4.dtbo \
+ rockchip-spi0.dtbo \
+ rockchip-spi2.dtbo \
+ rockchip-spidev0.dtbo \
+ rockchip-spidev2.dtbo \
+ rockchip-uart1.dtbo \
+ rockchip-uart2.dtbo \
+ rockchip-uart3.dtbo \
+ rockchip-uart4.dtbo \
+ rockchip-w1-gpio.dtbo
+
+scr-$(CONFIG_ARCH_ROCKCHIP) += \
+ rockchip-fixup.scr
+
+dtbotxt-$(CONFIG_ARCH_ROCKCHIP) += \
+ README.rockchip-overlays
+
+targets += $(dtbo-y) $(scr-y) $(dtbotxt-y)
+
+always := $(dtbo-y) $(scr-y) $(dtbotxt-y)
+clean-files := *.dtbo *.scr
+
diff --git a/arch/arm/boot/dts/overlay/README.rockchip-overlays b/arch/arm/boot/dts/overlay/README.rockchip-overlays
new file mode 100644
index 00000000000..df4559ca262
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/README.rockchip-overlays
@@ -0,0 +1,78 @@
+This document describes overlays provided in the kernel packages
+For generic Armbian overlays documentation please see
+https://docs.armbian.com/User-Guide_Allwinner_overlays/
+
+### Platform:
+
+rockchip (Rockchip)
+
+### Provided overlays:
+
+- ds1307
+- i2c1
+- i2c4
+- spi0
+- spi2
+- spidev0
+- spidev2
+- uart1
+- uart2
+- uart3
+- uart4
+- w1-gpio
+
+### Overlay details:
+
+### ds1307
+
+Activates ds1307 rtc on i2c1
+
+### i2c1
+
+Activate i2c1
+
+### i2c4
+
+Activate i2c4
+
+### spi0
+
+Activate spi0
+conflicts with uart4
+
+### spi2
+
+Activate spi2
+
+### spidev0
+
+Activate spidev on spi0
+Depends on spi0
+
+### spidev2
+
+Activate spidev on spi2
+depends on spi2
+
+### uart1
+
+Activate uart1
+
+### uart2
+
+Activate uart2
+
+### uart3
+
+Activate uart3
+
+### uart4
+
+Activate uart4
+Conflicts with spi0
+
+### w1-gpio
+
+Activates 1-wire gpio master on GPIO0 17
+
+
diff --git a/arch/arm/boot/dts/overlay/rockchip-ds1307.dts b/arch/arm/boot/dts/overlay/rockchip-ds1307.dts
new file mode 100644
index 00000000000..ab7d648c2aa
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-ds1307.dts
@@ -0,0 +1,23 @@
+/* Definitions for ds1307
+* From ASUS: https://github.com/TinkerBoard/debian_kernel/commits/develop/arch/arm/boot/dts/overlays/ds1307-overlay.dts
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+ target = <&i2c1>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rtc: ds1307@68 {
+ compatible = "dallas,ds1307";
+ reg = <0x68>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-fixup.scr-cmd b/arch/arm/boot/dts/overlay/rockchip-fixup.scr-cmd
new file mode 100644
index 00000000000..d4c39e20a3a
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-fixup.scr-cmd
@@ -0,0 +1,4 @@
+# overlays fixup script
+# implements (or rather substitutes) overlay arguments functionality
+# using u-boot scripting, environment variables and "fdt" command
+
diff --git a/arch/arm/boot/dts/overlay/rockchip-i2c1.dts b/arch/arm/boot/dts/overlay/rockchip-i2c1.dts
new file mode 100644
index 00000000000..f09f85e42cb
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-i2c1.dts
@@ -0,0 +1,16 @@
+/* Definitions for i2c1
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+ target = <&i2c1>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-i2c4.dts b/arch/arm/boot/dts/overlay/rockchip-i2c4.dts
new file mode 100644
index 00000000000..5b43b85045f
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-i2c4.dts
@@ -0,0 +1,16 @@
+/* Definitions for i2c4
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+ target = <&i2c4>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-spi0.dts b/arch/arm/boot/dts/overlay/rockchip-spi0.dts
new file mode 100644
index 00000000000..d2dfcd6220e
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-spi0.dts
@@ -0,0 +1,16 @@
+/* Definitions for spi0
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+ target = <&spi0>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-spi2.dts b/arch/arm/boot/dts/overlay/rockchip-spi2.dts
new file mode 100644
index 00000000000..2cd50ae4b9d
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-spi2.dts
@@ -0,0 +1,16 @@
+/* Definitions for spi2
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+ target = <&spi2>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-spidev0.dts b/arch/arm/boot/dts/overlay/rockchip-spidev0.dts
new file mode 100644
index 00000000000..728cde52351
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-spidev0.dts
@@ -0,0 +1,35 @@
+/* Definition for SPI0 Spidev
+ * spi port for Tinker Board
+ */
+
+/dts-v1/;
+/plugin/;
+
+/{
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+
+ target = <&spi0>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ spidev@0 {
+ compatible = "rockchip,spi_tinker";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ spi-cpha = <1>;
+ status = "okay";
+ };
+
+ spidev@1 {
+ compatible = "rockchip,spi_tinker";
+ reg = <1>;
+ spi-max-frequency = <50000000>;
+ spi-cpha = <1>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-spidev2.dts b/arch/arm/boot/dts/overlay/rockchip-spidev2.dts
new file mode 100644
index 00000000000..262bb61d959
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-spidev2.dts
@@ -0,0 +1,35 @@
+/* Definition for SPI2 Spidev
+ * spi port for Tinker Board
+ */
+
+/dts-v1/;
+/plugin/;
+
+/{
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+
+ target = <&spi2>;
+ __overlay__ {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ spidev@0 {
+ compatible = "rockchip,spi_tinker";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+ spi-cpha = <1>;
+ status = "okay";
+ };
+
+ spidev@1 {
+ compatible = "rockchip,spi_tinker";
+ reg = <1>;
+ spi-max-frequency = <50000000>;
+ spi-cpha = <1>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-uart1.dts b/arch/arm/boot/dts/overlay/rockchip-uart1.dts
new file mode 100644
index 00000000000..8604ff90d2a
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-uart1.dts
@@ -0,0 +1,16 @@
+/* Definitions for uart1
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+ target = <&uart1>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-uart2.dts b/arch/arm/boot/dts/overlay/rockchip-uart2.dts
new file mode 100644
index 00000000000..a57873d560b
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-uart2.dts
@@ -0,0 +1,16 @@
+/* Definitions for uart2
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+ target = <&uart2>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-uart3.dts b/arch/arm/boot/dts/overlay/rockchip-uart3.dts
new file mode 100644
index 00000000000..d1b77ffbf31
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-uart3.dts
@@ -0,0 +1,16 @@
+/* Definitions for uart3
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+ target = <&uart3>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-uart4.dts b/arch/arm/boot/dts/overlay/rockchip-uart4.dts
new file mode 100644
index 00000000000..13fd8f4eca9
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-uart4.dts
@@ -0,0 +1,16 @@
+/* Definitions for uart4
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+
+ fragment@0 {
+ target = <&uart4>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/overlay/rockchip-w1-gpio.dts b/arch/arm/boot/dts/overlay/rockchip-w1-gpio.dts
new file mode 100644
index 00000000000..cc1f50a91bb
--- /dev/null
+++ b/arch/arm/boot/dts/overlay/rockchip-w1-gpio.dts
@@ -0,0 +1,23 @@
+/* 1-Wire GPIO
+* From ASUS: https://github.com/TinkerBoard/debian_kernel/blob/develop/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts
+*
+*
+*/
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "rockchip,rk3288";
+ fragment@0 {
+ target-path = "/";
+ __overlay__ {
+ w1: onewire@0 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ gpios = <&gpio0 17 0>;
+ status = "okay";
+ };
+ };
+ };
+};
--
2.30.2

View File

@ -0,0 +1,784 @@
From 13498feb91614d59ebece61d0c278e31529bb8c8 Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Tue, 10 Oct 2023 21:54:51 +0200
Subject: [PATCH] rockchip gpio IR driver
---
drivers/media/rc/Kconfig | 11 +
drivers/media/rc/Makefile | 1 +
drivers/media/rc/rockchip-ir.c | 723 +++++++++++++++++++++++++++++++++
3 files changed, 735 insertions(+)
create mode 100644 drivers/media/rc/rockchip-ir.c
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index f560fc38895f..b77fa83e90e8 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -333,6 +333,17 @@ config IR_REDRAT3
To compile this driver as a module, choose M here: the
module will be called redrat3.
+config IR_ROCKCHIP_CIR
+ tristate "Rockchip GPIO IR receiver"
+ depends on (OF && GPIOLIB) || COMPILE_TEST
+ help
+ Say Y here if you want to use the Rockchip IR receiver with
+ virtual poweroff features provided by rockchip Trust OS
+
+ To compile this driver as a module, choose M here: the
+ module will be called rockchip-ir
+
+
config IR_RX51
tristate "Nokia N900 IR transmitter diode"
depends on (OMAP_DM_TIMER && PWM_OMAP_DMTIMER && ARCH_OMAP2PLUS || COMPILE_TEST) && RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index a9285266e944..057d5b64c121 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_IR_MTK) += mtk-cir.o
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
obj-$(CONFIG_IR_PWM_TX) += pwm-ir-tx.o
obj-$(CONFIG_IR_REDRAT3) += redrat3.o
+obj-$(CONFIG_IR_ROCKCHIP_CIR) += rockchip-ir.o
obj-$(CONFIG_IR_RX51) += ir-rx51.o
obj-$(CONFIG_IR_SERIAL) += serial_ir.o
obj-$(CONFIG_IR_SPI) += ir-spi.o
diff --git a/drivers/media/rc/rockchip-ir.c b/drivers/media/rc/rockchip-ir.c
new file mode 100644
index 000000000000..43ade8c4adce
--- /dev/null
+++ b/drivers/media/rc/rockchip-ir.c
@@ -0,0 +1,732 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/gpio/consumer.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
+#include <linux/irq.h>
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/reboot.h>
+#include <uapi/linux/psci.h>
+#include <media/rc-core.h>
+#include <soc/rockchip/rockchip_sip.h>
+
+#define ROCKCHIP_IR_DEVICE_NAME "rockchip_ir_recv"
+
+#ifdef CONFIG_64BIT
+#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN64_##name
+#else
+#define PSCI_FN_NATIVE(version, name) PSCI_##version##_FN_##name
+#endif
+
+/*
+* SIP/TEE constants for remote calls
+*/
+#define SIP_REMOTECTL_CFG 0x8200000b
+#define SIP_SUSPEND_MODE 0x82000003
+#define SIP_REMOTECTL_CFG 0x8200000b
+#define SUSPEND_MODE_CONFIG 0x01
+#define WKUP_SOURCE_CONFIG 0x02
+#define PWM_REGULATOR_CONFIG 0x03
+#define GPIO_POWER_CONFIG 0x04
+#define SUSPEND_DEBUG_ENABLE 0x05
+#define APIOS_SUSPEND_CONFIG 0x06
+#define VIRTUAL_POWEROFF 0x07
+
+#define REMOTECTL_SET_IRQ 0xf0
+#define REMOTECTL_SET_PWM_CH 0xf1
+#define REMOTECTL_SET_PWRKEY 0xf2
+#define REMOTECTL_GET_WAKEUP_STATE 0xf3
+#define REMOTECTL_ENABLE 0xf4
+#define REMOTECTL_PWRKEY_WAKEUP 0xdeadbeaf /* wakeup state */
+
+/*
+* PWM Registers
+* Each PWM has its own control registers
+*/
+#define PWM_REG_CNTR 0x00 /* Counter Register */
+#define PWM_REG_HPR 0x04 /* Period Register */
+#define PWM_REG_LPR 0x08 /* Duty Cycle Register */
+#define PWM_REG_CTRL 0x0c /* Control Register */
+
+/*
+* PWM General registers
+* Registers shared among PWMs
+*/
+#define PWM_REG_INT_EN 0x44
+
+/*REG_CTRL bits definitions*/
+#define PWM_ENABLE (1 << 0)
+#define PWM_DISABLE (0 << 0)
+
+/*operation mode*/
+#define PWM_MODE_ONESHOT (0x00 << 1)
+#define PWM_MODE_CONTINUMOUS (0x01 << 1)
+#define PWM_MODE_CAPTURE (0x02 << 1)
+
+/* Channel interrupt enable bit */
+#define PWM_CH_INT_ENABLE(n) BIT(n)
+
+enum pwm_div {
+ PWM_DIV1 = (0x0 << 12),
+ PWM_DIV2 = (0x1 << 12),
+ PWM_DIV4 = (0x2 << 12),
+ PWM_DIV8 = (0x3 << 12),
+ PWM_DIV16 = (0x4 << 12),
+ PWM_DIV32 = (0x5 << 12),
+ PWM_DIV64 = (0x6 << 12),
+ PWM_DIV128 = (0x7 << 12),
+};
+
+#define PWM_INT_ENABLE 1
+#define PWM_INT_DISABLE 0
+
+struct rockchip_rc_dev {
+ struct rc_dev *rcdev;
+ struct gpio_desc *gpiod;
+ int irq;
+ struct device *pmdev;
+ struct pm_qos_request qos;
+ void __iomem *pwm_base;
+ int pwm_wake_irq;
+ int pwm_id;
+ bool use_shutdown_handler; // if true, installs a shutdown handler and triggers virtual poweroff
+ bool use_suspend_handler; // if true, virtual poweroff is used as suspend mode otherwise use as regular suspend
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pinctrl_state_default;
+ struct pinctrl_state *pinctrl_state_suspend;
+};
+
+static struct arm_smccc_res __invoke_sip_fn_smc(unsigned long function_id,
+ unsigned long arg0,
+ unsigned long arg1,
+ unsigned long arg2)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+
+ return res;
+}
+
+int sip_smc_remotectl_config(u32 func, u32 data)
+{
+ struct arm_smccc_res res;
+
+ res = __invoke_sip_fn_smc(SIP_REMOTECTL_CFG, func, data, 0);
+
+ return res.a0;
+}
+
+int sip_smc_set_suspend_mode(u32 ctrl, u32 config1, u32 config2)
+{
+ struct arm_smccc_res res;
+
+ res = __invoke_sip_fn_smc(SIP_SUSPEND_MODE, ctrl, config1, config2);
+ return res.a0;
+}
+
+int sip_smc_virtual_poweroff(void)
+{
+ struct arm_smccc_res res;
+
+ res = __invoke_sip_fn_smc(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), 0, 0, 0);
+ return res.a0;
+}
+
+static irqreturn_t rockchip_ir_recv_irq(int irq, void *dev_id)
+{
+ int val;
+ struct rockchip_rc_dev *gpio_dev = dev_id;
+ struct device *pmdev = gpio_dev->pmdev;
+
+ /*
+ * For some cpuidle systems, not all:
+ * Respond to interrupt taking more latency when cpu in idle.
+ * Invoke asynchronous pm runtime get from interrupt context,
+ * this may introduce a millisecond delay to call resume callback,
+ * where to disable cpuilde.
+ *
+ * Two issues lead to fail to decode first frame, one is latency to
+ * respond to interrupt, another is delay introduced by async api.
+ */
+ if (pmdev)
+ pm_runtime_get(pmdev);
+
+ val = gpiod_get_value(gpio_dev->gpiod);
+ if (val >= 0)
+ ir_raw_event_store_edge(gpio_dev->rcdev, val == 1);
+
+ if (pmdev) {
+ pm_runtime_mark_last_busy(pmdev);
+ pm_runtime_put_autosuspend(pmdev);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void rockchip_pwm_int_ctrl(struct rockchip_rc_dev *gpio_dev, bool enable)
+{
+
+ void __iomem *pwm_base = gpio_dev->pwm_base;
+ struct device *dev = &gpio_dev->rcdev->dev;
+ int pwm_id = gpio_dev->pwm_id;
+
+ void __iomem *reg_int_ctrl;
+ int val;
+
+ reg_int_ctrl= pwm_base - (0x10 * pwm_id) + PWM_REG_INT_EN;
+
+ val = readl_relaxed(reg_int_ctrl);
+
+ if (enable) {
+ val |= PWM_CH_INT_ENABLE(pwm_id);
+ dev_info(dev, "PWM interrupt enabled, register value %x\n", val);
+ } else {
+ val &= ~PWM_CH_INT_ENABLE(pwm_id);
+ dev_info(dev, "PWM interrupt disabled, register value %x\n", val);
+ }
+
+ writel_relaxed(val, reg_int_ctrl);
+
+}
+
+static int rockchip_pwm_hw_init(struct rockchip_rc_dev *gpio_dev)
+{
+
+ void __iomem *pwm_base = gpio_dev->pwm_base;
+ int val;
+
+ //1. disabled pwm
+ val = readl_relaxed(pwm_base + PWM_REG_CTRL);
+ val = (val & 0xFFFFFFFE) | PWM_DISABLE;
+ writel_relaxed(val, pwm_base + PWM_REG_CTRL);
+
+ //2. capture mode
+ val = readl_relaxed(pwm_base + PWM_REG_CTRL);
+ val = (val & 0xFFFFFFF9) | PWM_MODE_CAPTURE;
+ writel_relaxed(val, pwm_base + PWM_REG_CTRL);
+
+ //set clk div, clk div to 64
+ val = readl_relaxed(pwm_base + PWM_REG_CTRL);
+ val = (val & 0xFF0001FF) | PWM_DIV64;
+ writel_relaxed(val, pwm_base + PWM_REG_CTRL);
+
+ //4. enabled pwm int
+ rockchip_pwm_int_ctrl(gpio_dev, true);
+
+ //5. enabled pwm
+ val = readl_relaxed(pwm_base + PWM_REG_CTRL);
+ val = (val & 0xFFFFFFFE) | PWM_ENABLE;
+ writel_relaxed(val, pwm_base + PWM_REG_CTRL);
+
+ return 0;
+
+}
+
+static int rockchip_pwm_hw_stop(struct rockchip_rc_dev *gpio_dev)
+{
+
+ void __iomem *pwm_base = gpio_dev->pwm_base;
+ int val;
+
+ //disable pwm interrupt
+ rockchip_pwm_int_ctrl(gpio_dev, false);
+
+ //disable pwm
+ val = readl_relaxed(pwm_base + PWM_REG_CTRL);
+ val = (val & 0xFFFFFFFE) | PWM_DISABLE;
+ writel_relaxed(val, pwm_base + PWM_REG_CTRL);
+
+ return 0;
+
+}
+
+static int rockchip_pwm_sip_wakeup_init(struct rockchip_rc_dev *gpio_dev)
+{
+
+ struct device *dev = &gpio_dev->rcdev->dev;
+
+ struct irq_data *irq_data;
+ long hwirq;
+ int ret;
+
+ irq_data = irq_get_irq_data(gpio_dev->pwm_wake_irq);
+ if (!irq_data) {
+ dev_err(dev, "could not get irq data\n");
+ return -1;
+ }
+
+ hwirq = irq_data->hwirq;
+ dev_info(dev, "use hwirq %ld, pwm chip id %d for PWM SIP wakeup\n", hwirq, gpio_dev->pwm_id);
+
+ ret = 0;
+
+ ret |= sip_smc_remotectl_config(REMOTECTL_SET_IRQ, (int)hwirq);
+ ret |= sip_smc_remotectl_config(REMOTECTL_SET_PWM_CH, gpio_dev->pwm_id);
+ ret |= sip_smc_remotectl_config(REMOTECTL_ENABLE, 1);
+
+ if (ret) {
+ dev_err(dev, "SIP remote controller mode, TEE does not support feature\n");
+ return ret;
+ }
+
+ sip_smc_set_suspend_mode(SUSPEND_MODE_CONFIG, 0x10042, 0);
+ sip_smc_set_suspend_mode(WKUP_SOURCE_CONFIG, 0x0, 0);
+ sip_smc_set_suspend_mode(PWM_REGULATOR_CONFIG, 0x0, 0);
+ //sip_smc_set_suspend_mode(GPIO_POWER_CONFIG, i, gpio_temp[i]);
+ sip_smc_set_suspend_mode(SUSPEND_DEBUG_ENABLE, 0x1, 0);
+ sip_smc_set_suspend_mode(APIOS_SUSPEND_CONFIG, 0x0, 0);
+ sip_smc_set_suspend_mode(VIRTUAL_POWEROFF, 0, 1);
+
+ dev_info(dev, "TEE remote controller wakeup installed\n");
+
+ return 0;
+
+}
+
+static int rockchip_ir_recv_remove(struct platform_device *pdev)
+{
+ struct rockchip_rc_dev *gpio_dev = platform_get_drvdata(pdev);
+ struct device *pmdev = gpio_dev->pmdev;
+
+ if (pmdev) {
+ pm_runtime_get_sync(pmdev);
+ cpu_latency_qos_remove_request(&gpio_dev->qos);
+
+ pm_runtime_disable(pmdev);
+ pm_runtime_put_noidle(pmdev);
+ pm_runtime_set_suspended(pmdev);
+ }
+
+ // Disable the remote controller handling of the Trust OS
+ sip_smc_remotectl_config(REMOTECTL_ENABLE, 0);
+
+ // Disable the virtual poweroff of the Trust OS
+ sip_smc_set_suspend_mode(VIRTUAL_POWEROFF, 0, 0);
+
+ return 0;
+}
+
+static int rockchip_ir_register_power_key(struct device *dev)
+{
+
+ struct rockchip_rc_dev *gpio_dev = dev_get_drvdata(dev);
+
+ struct rc_map *key_map;
+ struct rc_map_table *key;
+ int idx, key_scancode, rev_scancode;
+ int tee_scancode;
+
+ key_map = &gpio_dev->rcdev->rc_map;
+
+ dev_info(dev, "remote key table %s, key map of %d items\n", key_map->name, key_map->len);
+
+ for (idx = 0; idx < key_map->len; idx++) {
+
+ key = &key_map->scan[idx];
+
+ if (key->keycode != KEY_POWER)
+ continue;
+
+ key_scancode = key->scancode;
+ rev_scancode = ~key_scancode;
+
+ // If key_scancode has higher 16 bits set to 0, then the scancode is NEC protocol, otherwise it is NECX/NEC32
+ if ((key_scancode & 0xffff) == key_scancode)
+ tee_scancode = (key_scancode & 0xff00) | ((rev_scancode & 0xff00) << 8); // NEC protocol
+ else
+ tee_scancode = ((key_scancode & 0xff0000) >> 8) | ((key_scancode & 0xff00) << 8); // NECX/NEC32 protocol
+
+ tee_scancode |= rev_scancode & 0xff;
+ tee_scancode <<= 8;
+
+ sip_smc_remotectl_config(REMOTECTL_SET_PWRKEY, tee_scancode);
+
+ dev_info(dev, "registered scancode %08x (SIP: %8x)\n", key_scancode, tee_scancode);
+
+ }
+
+ return 0;
+
+}
+
+static int rockchip_ir_recv_suspend_prepare(struct device *dev)
+{
+ struct rockchip_rc_dev *gpio_dev = dev_get_drvdata(dev);
+ int ret;
+
+ dev_info(dev, "initialize rockchip SIP virtual poweroff\n");
+ ret = rockchip_pwm_sip_wakeup_init(gpio_dev);
+
+ if (ret)
+ return ret;
+
+ rockchip_ir_register_power_key(dev);
+
+ disable_irq(gpio_dev->irq);
+ dev_info(dev, "GPIO IRQ disabled\n");
+
+ ret = pinctrl_select_state(gpio_dev->pinctrl, gpio_dev->pinctrl_state_suspend);
+ if (ret) {
+ dev_err(dev, "unable to set pin in PWM mode\n");
+ return ret;
+ }
+
+ dev_info(dev, "set pin configuration to PWM mode\n");
+
+ rockchip_pwm_hw_init(gpio_dev);
+ dev_info(dev, "started pin PWM mode\n");
+
+ return 0;
+
+}
+
+#ifdef CONFIG_PM
+static int rockchip_ir_recv_suspend(struct device *dev)
+{
+ struct rockchip_rc_dev *gpio_dev = dev_get_drvdata(dev);
+
+ /*
+ * if property suspend-is-virtual-poweroff is set, we can disable
+ * the regular gpio wakeup and enable the PWM mode for the Trust OS
+ * to take control and react to remote control.
+ * If the property is not set, we instead enable the wake up for the
+ * regular gpio.
+ */
+ if (gpio_dev->use_suspend_handler) {
+
+ rockchip_ir_recv_suspend_prepare(dev);
+
+ } else {
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(gpio_dev->irq);
+ else
+ disable_irq(gpio_dev->irq);
+
+ }
+
+ return 0;
+}
+
+static int rockchip_ir_recv_resume(struct device *dev)
+{
+ struct rockchip_rc_dev *gpio_dev = dev_get_drvdata(dev);
+ int ret;
+
+ /*
+ * In case suspend-is-virtual-poweroff property is set,
+ * restore the pin from PWM mode to regular GPIO configuration
+ * and stop the PWM function.
+ * Otherwise, just enable the regular GPIO irq
+ */
+ if (gpio_dev->use_suspend_handler) {
+
+ rockchip_pwm_hw_stop(gpio_dev);
+ dev_info(dev, "stopped pin PWM mode\n");
+
+ ret = pinctrl_select_state(gpio_dev->pinctrl, gpio_dev->pinctrl_state_default);
+ if (ret) {
+ dev_err(dev, "unable to restore pin in GPIO mode\n");
+ return ret;
+ }
+ dev_info(dev, "restored pin configuration di GPIO\n");
+
+ enable_irq(gpio_dev->irq);
+ dev_info(dev, "restored GPIO IRQ\n");
+
+ } else {
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(gpio_dev->irq);
+ else
+ enable_irq(gpio_dev->irq);
+
+ }
+
+ return 0;
+}
+
+static void rockchip_ir_recv_shutdown(struct platform_device *pdev)
+{
+
+ struct device *dev = &pdev->dev;
+ struct rockchip_rc_dev *gpio_dev = dev_get_drvdata(dev);
+
+ if (gpio_dev->use_shutdown_handler)
+ rockchip_ir_recv_suspend_prepare(dev);
+
+ return;
+
+}
+
+static int rockchip_ir_recv_sys_off(struct sys_off_data *data)
+{
+
+ sip_smc_virtual_poweroff();
+
+ return 0;
+
+}
+
+static int rockchip_ir_recv_init_sip(void)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(ROCKCHIP_SIP_SIP_VERSION, ROCKCHIP_SIP_IMPLEMENT_V2, SECURE_REG_WR, 0, 0, 0, 0, 0, &res);
+
+ if (res.a0)
+ return 0;
+
+ return res.a1;
+
+}
+
+static int rockchip_ir_recv_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct rockchip_rc_dev *gpio_dev;
+ struct rc_dev *rcdev;
+ struct clk *clk;
+ struct clk *p_clk;
+ struct resource *res;
+ u32 period = 0;
+ int rc;
+ int ret;
+ int pwm_wake_irq;
+ int clocks;
+
+ if (!np)
+ return -ENODEV;
+
+ gpio_dev = devm_kzalloc(dev, sizeof(*gpio_dev), GFP_KERNEL);
+ if (!gpio_dev)
+ return -ENOMEM;
+
+ gpio_dev->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN);
+ if (IS_ERR(gpio_dev->gpiod)) {
+ rc = PTR_ERR(gpio_dev->gpiod);
+ /* Just try again if this happens */
+ if (rc != -EPROBE_DEFER)
+ dev_err(dev, "error getting gpio (%d)\n", rc);
+ return rc;
+ }
+ gpio_dev->irq = gpiod_to_irq(gpio_dev->gpiod);
+ if (gpio_dev->irq < 0)
+ return gpio_dev->irq;
+
+ rcdev = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
+ if (!rcdev)
+ return -ENOMEM;
+
+ rcdev->priv = gpio_dev;
+ rcdev->device_name = ROCKCHIP_IR_DEVICE_NAME;
+ rcdev->input_phys = ROCKCHIP_IR_DEVICE_NAME "/input0";
+ rcdev->input_id.bustype = BUS_HOST;
+ rcdev->input_id.vendor = 0x0001;
+ rcdev->input_id.product = 0x0001;
+ rcdev->input_id.version = 0x0100;
+ rcdev->dev.parent = dev;
+ rcdev->driver_name = KBUILD_MODNAME;
+ rcdev->min_timeout = 1;
+ rcdev->timeout = IR_DEFAULT_TIMEOUT;
+ rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
+ rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
+ rcdev->map_name = of_get_property(np, "linux,rc-map-name", NULL);
+ if (!rcdev->map_name)
+ rcdev->map_name = RC_MAP_EMPTY;
+
+ gpio_dev->rcdev = rcdev;
+ if (of_property_read_bool(np, "wakeup-source")) {
+
+ ret = device_init_wakeup(dev, true);
+
+ if (ret)
+ dev_err(dev, "could not init wakeup device\n");
+
+ }
+
+ rc = devm_rc_register_device(dev, rcdev);
+ if (rc < 0) {
+ dev_err(dev, "failed to register rc device (%d)\n", rc);
+ return rc;
+ }
+
+ of_property_read_u32(np, "linux,autosuspend-period", &period);
+ if (period) {
+ gpio_dev->pmdev = dev;
+ pm_runtime_set_autosuspend_delay(dev, period);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_enable(dev);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "no memory resources defined\n");
+ return -ENODEV;
+ }
+
+ gpio_dev->pwm_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(gpio_dev->pwm_base))
+ return PTR_ERR(gpio_dev->pwm_base);
+
+ clocks = of_property_count_strings(np, "clock-names");
+ if (clocks == 2) {
+ clk = devm_clk_get(dev, "pwm");
+ p_clk = devm_clk_get(dev, "pclk");
+ } else {
+ clk = devm_clk_get(dev, NULL);
+ p_clk = clk;
+ }
+
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Can't get bus clock: %d\n", ret);
+ return ret;
+ }
+
+ if (IS_ERR(p_clk)) {
+ ret = PTR_ERR(p_clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Can't get peripheral clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(clk);
+ if (ret) {
+ dev_err(dev, "Can't enable bus clk: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(p_clk);
+ if (ret) {
+ dev_err(dev, "Can't enable peripheral clk: %d\n", ret);
+ goto error_clk;
+ }
+
+ pwm_wake_irq = platform_get_irq(pdev, 0);
+ if (pwm_wake_irq < 0) {
+ dev_err(&pdev->dev, "cannot find PWM wake interrupt\n");
+ goto error_pclk;
+ }
+
+ gpio_dev->pwm_wake_irq = pwm_wake_irq;
+ ret = enable_irq_wake(pwm_wake_irq);
+ if (ret) {
+ dev_err(dev, "could not enable IRQ wakeup\n");
+ }
+
+ ret = of_property_read_u32(np, "pwm-id", &gpio_dev->pwm_id);
+ if (ret) {
+ dev_err(dev, "missing pwm-id property\n");
+ goto error_pclk;
+ }
+
+ if (gpio_dev->pwm_id > 3) {
+ dev_err(dev, "invalid pwm-id property\n");
+ goto error_pclk;
+ }
+
+ gpio_dev->use_shutdown_handler = of_property_read_bool(np, "shutdown-is-virtual-poweroff");
+ gpio_dev->use_suspend_handler = of_property_read_bool(np, "suspend-is-virtual-poweroff");
+
+ gpio_dev->pinctrl = devm_pinctrl_get(dev);
+ if (IS_ERR(gpio_dev->pinctrl)) {
+ dev_err(dev, "Unable to get pinctrl\n");
+ goto error_pclk;
+ }
+
+ gpio_dev->pinctrl_state_default = pinctrl_lookup_state(gpio_dev->pinctrl, "default");
+ if (IS_ERR(gpio_dev->pinctrl_state_default)) {
+ dev_err(dev, "Unable to get default pinctrl state\n");
+ goto error_pclk;
+ }
+
+ gpio_dev->pinctrl_state_suspend = pinctrl_lookup_state(gpio_dev->pinctrl, "suspend");
+ if (IS_ERR(gpio_dev->pinctrl_state_suspend)) {
+ dev_err(dev, "Unable to get suspend pinctrl state\n");
+ goto error_pclk;
+ }
+
+ platform_set_drvdata(pdev, gpio_dev);
+
+ ret = devm_request_irq(dev, gpio_dev->irq, rockchip_ir_recv_irq,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "gpio-ir-recv-irq", gpio_dev);
+ if (ret) {
+ dev_err(dev, "Can't request GPIO interrupt\n");
+ goto error_pclk;
+ }
+
+ if (gpio_dev->use_shutdown_handler) {
+
+ ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF,
+ SYS_OFF_PRIO_FIRMWARE, rockchip_ir_recv_sys_off, NULL);
+
+ if (ret)
+ dev_err(dev, "could not register sys_off handler\n");
+
+ }
+
+ ret = rockchip_ir_recv_init_sip();
+ if (!ret) {
+ dev_err(dev, "Unable to initialize Rockchip SIP v2, virtual poweroff unavailable\n");
+ gpio_dev->use_shutdown_handler = false;
+ gpio_dev->use_suspend_handler = false;
+ } else {
+ dev_info(dev, "rockchip SIP initialized, version 0x%x\n", ret);
+ }
+
+ return 0;
+
+error_pclk:
+ clk_unprepare(p_clk);
+error_clk:
+ clk_unprepare(clk);
+
+ return -ENODEV;
+
+}
+
+static const struct dev_pm_ops rockchip_ir_recv_pm_ops = {
+ .suspend = rockchip_ir_recv_suspend,
+ .resume = rockchip_ir_recv_resume,
+};
+#endif
+
+static const struct of_device_id rockchip_ir_recv_of_match[] = {
+ { .compatible = "rockchip-ir-receiver", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, rockchip_ir_recv_of_match);
+
+static struct platform_driver rockchip_ir_recv_driver = {
+ .probe = rockchip_ir_recv_probe,
+ .remove = rockchip_ir_recv_remove,
+ .shutdown = rockchip_ir_recv_shutdown,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = of_match_ptr(rockchip_ir_recv_of_match),
+#ifdef CONFIG_PM
+ .pm = &rockchip_ir_recv_pm_ops,
+#endif
+ },
+};
+module_platform_driver(rockchip_ir_recv_driver);
+
+MODULE_DESCRIPTION("Rockchip IR Receiver driver");
+MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,119 @@
From f14539f8d08328ae5aad165a4deea25c7d6b09bf Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Mon, 25 Apr 2022 13:25:09 +0000
Subject: [PATCH] add generic rk322x tv box remote controller keymap
---
drivers/media/rc/keymaps/Makefile | 1 +
drivers/media/rc/keymaps/rc-rk322x-tvbox.c | 74 ++++++++++++++++++++++
include/media/rc-map.h | 1 +
3 files changed, 77 insertions(+)
create mode 100644 drivers/media/rc/keymaps/rc-rk322x-tvbox.c
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 5fe5c9e1a46..1aa49b78a65 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-rc6-mce.o \
rc-real-audio-220-32-keys.o \
rc-reddo.o \
+ rc-rk322x-tvbox.o \
rc-snapstream-firefly.o \
rc-streamzap.o \
rc-tanix-tx3mini.o \
diff --git a/drivers/media/rc/keymaps/rc-rk322x-tvbox.c b/drivers/media/rc/keymaps/rc-rk322x-tvbox.c
new file mode 100644
index 00000000000..91e24ee52ee
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-rk322x-tvbox.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+// rc-rk322x-tvbox.c - Keytable for rk322x generic tv box remote controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2022 Paolo Sabatino
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+/*
+
+*/
+
+static struct rc_map_table rk322x_tvbox[] = {
+
+ { 0x40400d, KEY_ENTER },
+ { 0x40404d, KEY_POWER },
+ { 0x40401e, KEY_PREVIOUSSONG },
+ { 0x40401f, KEY_NEXTSONG },
+ { 0x404001, KEY_1 },
+ { 0x404002, KEY_2 },
+ { 0x404003, KEY_3 },
+ { 0x404004, KEY_4 },
+ { 0x404005, KEY_5 },
+ { 0x404006, KEY_6 },
+ { 0x404007, KEY_7 },
+ { 0x404008, KEY_8 },
+ { 0x404009, KEY_9 },
+ { 0x404000, KEY_0 },
+ { 0x40400c, KEY_BACKSPACE },
+ { 0x404044, KEY_F6 },
+ { 0x40401a, KEY_HOME },
+ { 0x404042, KEY_BACK },
+ { 0x404045, KEY_MENU },
+ { 0x40400f, KEY_TEXT },
+ { 0x404010, KEY_LEFT },
+ { 0x404011, KEY_RIGHT },
+ { 0x40400e, KEY_DOWN },
+ { 0x40400b, KEY_UP },
+ { 0x40401c, KEY_VOLUMEDOWN },
+ { 0x404043, KEY_MUTE },
+ { 0x404015, KEY_VOLUMEUP },
+ { 0x404053, KEY_F1 },
+ { 0x40405b, KEY_F2 },
+ { 0x404057, KEY_F3 },
+ { 0x404054, KEY_F4 },
+
+};
+
+static struct rc_map_list rk322x_tvbox_map = {
+ .map = {
+ .scan = rk322x_tvbox,
+ .size = ARRAY_SIZE(rk322x_tvbox),
+ .rc_proto = RC_PROTO_NEC, /* Legacy IR type */
+ .name = RC_MAP_RK322X_TVBOX,
+ }
+};
+
+static int __init init_rc_map_rk322x_tvbox(void)
+{
+ return rc_map_register(&rk322x_tvbox_map);
+}
+
+static void __exit exit_rc_map_rk322x_tvbox(void)
+{
+ rc_map_unregister(&rk322x_tvbox_map);
+}
+
+module_init(init_rc_map_rk322x_tvbox)
+module_exit(exit_rc_map_rk322x_tvbox)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Paolo Sabatino");
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 793b54342df..35aba84be9f 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -310,6 +310,7 @@ struct rc_map *rc_map_get(const char *name);
#define RC_MAP_RC6_MCE "rc-rc6-mce"
#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
#define RC_MAP_REDDO "rc-reddo"
+#define RC_MAP_RK322X_TVBOX "rc-rk322x-tvbox"
#define RC_MAP_SNAPSTREAM_FIREFLY "rc-snapstream-firefly"
#define RC_MAP_STREAMZAP "rc-streamzap"
#define RC_MAP_SU3000 "rc-su3000"
--
2.30.2

View File

@ -0,0 +1,54 @@
# SPDX-License-Identifier: GPL-2.0
dtbo-$(CONFIG_ARCH_ROCKCHIP) += \
rockchip-ds1307.dtbo \
rockchip-i2c1.dtbo \
rockchip-i2c4.dtbo \
rockchip-spi0.dtbo \
rockchip-spi2.dtbo \
rockchip-spidev0.dtbo \
rockchip-spidev2.dtbo \
rockchip-uart1.dtbo \
rockchip-uart2.dtbo \
rockchip-uart3.dtbo \
rockchip-uart4.dtbo \
rockchip-w1-gpio.dtbo \
rk322x-emmc.dtbo \
rk322x-emmc-pins.dtbo \
rk322x-emmc-ddr-ph45.dtbo \
rk322x-emmc-ddr-ph180.dtbo \
rk322x-emmc-hs200.dtbo \
rk322x-nand.dtbo \
rk322x-led-conf-default.dtbo \
rk322x-led-conf1.dtbo \
rk322x-led-conf2.dtbo \
rk322x-led-conf3.dtbo \
rk322x-led-conf4.dtbo \
rk322x-led-conf5.dtbo \
rk322x-led-conf6.dtbo \
rk322x-led-conf7.dtbo \
rk322x-led-conf8.dtbo \
rk322x-cpu-hs.dtbo \
rk322x-cpu-hs-lv.dtbo \
rk322x-wlan-alt-wiring.dtbo \
rk322x-cpu-stability.dtbo \
rk322x-ir-wakeup.dtbo \
rk322x-ddr3-330.dtbo \
rk322x-ddr3-528.dtbo \
rk322x-ddr3-660.dtbo \
rk322x-ddr3-800.dtbo \
rk322x-bt-8723cs.dtbo \
rk322x-usb-otg-peripheral.dtbo
scr-$(CONFIG_ARCH_ROCKCHIP) += \
rk322x-fixup.scr \
rockchip-fixup.scr
dtbotxt-$(CONFIG_ARCH_ROCKCHIP) += \
README.rk322x-overlays \
README.rockchip-overlays
targets += $(dtbo-y) $(scr-y) $(dtbotxt-y)
always := $(dtbo-y) $(scr-y) $(dtbotxt-y)
clean-files := *.dtbo *.scr

View File

@ -0,0 +1,99 @@
This document describes overlays provided in the kernel packages
For generic Armbian overlays documentation please see
https://docs.armbian.com/User-Guide_Allwinner_overlays/
### Platform:
rk322x (Rockchip)
### Provided overlays:
- rk322x-cpu-hs
- rk322x-cpu-stability
- rk322x-emmc*
- rk322x-nand
- rk322x-emmc-nand
- rk322x-led-conf*
- rk322x-wlan-alt-wiring
- rk322x-ddr3-*
- rk322x-bt-*
- rk322x-usb-otg-peripheral
- rk322x-ir-wakeup
### Overlay details:
### rk322x-cpu-hs
Activates higher CPU speed (up to 1.4ghz) for rk3228b/rk3229 boxes
### rk322x-cpu-stability
Increases the voltage of the lowest operating point to increase stability
on some boards which have power regulation issues. Also adds a settling
time to allow power regulator stabilize voltage.
### emmc*
rk322x-emmc activates onboard emmc device node and deactivates the
nand controller.
rk322x-emmc-pins sets the pin controller default pull up/down
configuration, not all boards are happy with this overlay, so your
mileage may vary and may want to not use it.
rk322x-emmc-ddr-ph45/ph180 sets the emmc ddr mode. First overlay
sets the default phase clock shifting to 45 degrees, the second
overlay to 180 degrees. They are alternative, choose the one that
makes your emmc perform better.
rk322x-emmc-hs200 enables the hs200 mode. It is preferable to
ddr mode because it is more stable, but old emmc parts don't
support it.
### nand
Activates onboard nand device node and deactivates the emmc controller.
Also sets up the pin controller default pull up/down configuration
### rk322x-led-conf*
Each device tree of this kind provides a different known wiring configuration
(ie: gpio and active low/high) of the onboard leds. Each board manufacturer
usually choose a different GPIO for the auxiliary led, but the main "working"
led is always wired to the same gpio (although it may be active high or low)
led-conf1 is commonly found in boards made by Chiptrip manufacturer
led-conf2 is found in other boards with R329Q and MXQ_RK3229 marking
led-conf3 is found in boards with R28-MXQ marking
led-conf4 is found on boards with T066 marking
led-conf5 is found on boards with IPB900 marking from AEMS PVT
led-conf6 is found on boards with MXQ_PRO_V72 and similar markings, possibly
with eMCP module.
led-conf7 is found on boards with R29_MXQ, R2B_MXQ and H20 markings
led-conf8 is specific for H20_221_V1.71 boards, but may work on other variants
### rk322x-alt-wiring
Some boards have different SDIO wiring setup for wifi chips. This overlay
enables the different pin controller wiring and power enable
### rk322x-ddr3-*
Enable DRAM memory controller and sets the speed to the given speed bin.
The DRAM memory controller reclocking only works with DDR3/LPDDR3, if
you enable one of these overlays on boards with DDR2 memory the system
will not boot anymore
### rk322x-bt-*
Overlays that enable bluetooth devices. Most common bluetooth chips are
realtek ones.
rk322x-bt-8723cs: enable this overlay for 8723cs and 8703bs wifi/bluetooth
### rk322x-usb-otg-peripheral
Set the OTG USB port to peripheral mode to be used as USB slave instead
of USB host
### rk322x-ir-wakeup
Enable the rockchip-ir-driver in place of the standard gpio-ir-receiver.
The rockchip-specific driver exploits the Trust OS and Virtual Poweroff mode
to allow power up via remote controller power button.

View File

@ -0,0 +1,78 @@
This document describes overlays provided in the kernel packages
For generic Armbian overlays documentation please see
https://docs.armbian.com/User-Guide_Allwinner_overlays/
### Platform:
rockchip (Rockchip)
### Provided overlays:
- ds1307
- i2c1
- i2c4
- spi0
- spi2
- spidev0
- spidev2
- uart1
- uart2
- uart3
- uart4
- w1-gpio
### Overlay details:
### ds1307
Activates ds1307 rtc on i2c1
### i2c1
Activate i2c1
### i2c4
Activate i2c4
### spi0
Activate spi0
conflicts with uart4
### spi2
Activate spi2
### spidev0
Activate spidev on spi0
Depends on spi0
### spidev2
Activate spidev on spi2
depends on spi2
### uart1
Activate uart1
### uart2
Activate uart2
### uart3
Activate uart3
### uart4
Activate uart4
Conflicts with spi0
### w1-gpio
Activates 1-wire gpio master on GPIO0 17

View File

@ -0,0 +1,19 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
&uart1 {
pinctrl-0 = <&uart11_xfer>, <&uart11_rts>, <&uart11_cts>;
pinctrl-names = "default";
uart-has-rtscts;
status = "okay";
bluetooth {
compatible = "realtek,rtl8723cs-bt";
enable-gpios = <&gpio2 RK_PD5 GPIO_ACTIVE_HIGH>;
device-wake-gpios = <&gpio3 RK_PD3 GPIO_ACTIVE_HIGH>;
host-wake-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>;
};
};

View File

@ -0,0 +1,68 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&cpu0_opp_table>;
__overlay__ {
opp-600000000 {
opp-microvolt = <950000 950000 1275000>;
};
opp-816000000 {
opp-microvolt = <950000 950000 1275000>;
};
opp-1008000000 {
opp-microvolt = <1000000 1000000 1275000>;
};
opp-1200000000 {
opp-microvolt = <1100000 1100000 1275000>;
};
opp-1296000000 {
opp-hz = /bits/ 64 <1296000000>;
opp-microvolt = <1150000 1150000 1275000>;
};
opp-1392000000 {
opp-hz = /bits/ 64 <1392000000>;
opp-microvolt = <1225000 1225000 1275000>;
};
};
};
fragment@1 {
target = <&gpu_opp_table>;
__overlay__ {
opp-200000000 {
opp-microvolt = <1050000 1050000 1200000>;
};
opp-300000000 {
opp-microvolt = <1050000 1050000 1200000>;
};
opp-400000000 {
opp-microvolt = <1050000 1050000 1200000>;
};
opp-500000000 {
opp-microvolt = <1050000 1050000 1200000>;
};
};
};
fragment@2 {
target = <&dmc_opp_table>;
__overlay__ {
opp-330000000 {
opp-microvolt = <1050000 1050000 1200000>;
};
opp-534000000 {
opp-microvolt = <1050000 1050000 1200000>;
};
opp-660000000 {
opp-microvolt = <1050000 1050000 1200000>;
};
opp-786000000 {
opp-microvolt = <1100000 1050000 1200000>;
};
};
};
};

View File

@ -0,0 +1,28 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&cpu0_opp_table>;
__overlay__ {
opp-1296000000 {
opp-hz = /bits/ 64 <1296000000>;
opp-microvolt = <1325000 1325000 1400000>;
};
opp-1392000000 {
opp-hz = /bits/ 64 <1392000000>;
opp-microvolt = <1350000 1350000 1400000>;
};
/*
opp-1464000000 {
opp-hz = /bits/ 64 <1464000000>;
opp-microvolt = <1400000 1400000 1400000>;
};
*/
};
};
};

View File

@ -0,0 +1,52 @@
/dts-v1/;
/plugin/;
/ {
/*
Device tree overlay that tries to overcome issues on power regulators (expecially ARM
power regulator) increasing lowest voltage and adding settling time to allow voltage
stabilization
*/
fragment@0 {
target = <&cpu0_opp_table>;
__overlay__ {
/*
Increase 600 and 800 Mhz operating points voltage to decrease the range
between minimum and maximum voltages
*/
opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1100000>;
};
opp-816000000 {
opp-hz = /bits/ 64 <816000000>;
opp-microvolt = <1100000>;
};
};
};
fragment@1 {
target = <&vdd_arm>;
__overlay__ {
regulator-ramp-delay = <300>; // 30 uV/us, so 0.3v transition settling time is 1ms
};
};
fragment@2 {
target = <&vdd_log>;
__overlay__ {
regulator-ramp-delay = <600>; // 600 uV/us, so 0,3v transition settling time is 0.5ms
};
};
};

View File

@ -0,0 +1,28 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&dmc>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&dmc_opp_table>;
__overlay__ {
opp-534000000 {
status = "disabled";
};
opp-660000000 {
status = "disabled";
};
opp-786000000 {
status = "disabled";
};
};
};
};

View File

@ -0,0 +1,28 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&dmc>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&dmc_opp_table>;
__overlay__ {
opp-534000000 {
status = "okay";
};
opp-660000000 {
status = "disabled";
};
opp-786000000 {
status = "disabled";
};
};
};
};

View File

@ -0,0 +1,28 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&dmc>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&dmc_opp_table>;
__overlay__ {
opp-534000000 {
status = "okay";
};
opp-660000000 {
status = "okay";
};
opp-786000000 {
status = "disabled";
};
};
};
};

View File

@ -0,0 +1,28 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&dmc>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&dmc_opp_table>;
__overlay__ {
opp-534000000 {
status = "okay";
};
opp-660000000 {
status = "okay";
};
opp-786000000 {
status = "okay";
};
};
};
};

View File

@ -0,0 +1,14 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&emmc>;
__overlay__ {
mmc-ddr-1_8v;
rockchip,default-sample-phase = <180>;
};
};
};

View File

@ -0,0 +1,14 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&emmc>;
__overlay__ {
mmc-ddr-1_8v;
rockchip,default-sample-phase = <45>;
};
};
};

View File

@ -0,0 +1,13 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&emmc>;
__overlay__ {
mmc-hs200-1_8v;
};
};
};

View File

@ -0,0 +1,22 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&emmc>;
__overlay__ {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8 &emmc_pwr &emmc_rst>;
};
};
fragment@1 {
target = <&nfc>;
__overlay__ {
status = "disabled";
};
};
};

View File

@ -0,0 +1,20 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&emmc>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&nfc>;
__overlay__ {
status = "disabled";
};
};
};

View File

@ -0,0 +1,4 @@
# overlays fixup script
# implements (or rather substitutes) overlay arguments functionality
# using u-boot scripting, environment variables and "fdt" command

View File

@ -0,0 +1,16 @@
/dts-v1/;
/plugin/;
/*
* Disable regular gpio-ir-receiver and enable
* rockchip-ir-receiver driver; also enables virtual
* poweroff on shutdown to allow restart with power key
* on remote controller
*/
&ir_receiver {
status = "disabled";
};
&rockchip_ir_receiver {
status = "okay";
};

View File

@ -0,0 +1,22 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
fragment@0 {
target-path = "/gpio-leds";
__overlay__ {
working {
gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
};
};
};
};

View File

@ -0,0 +1,64 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
fragment@0 {
target-path = "/gpio-leds";
__overlay__ {
working {
gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
};
auxiliary {
gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;
label = "auxiliary";
linux,default-trigger = "mmc2";
default-state = "off";
pinctrl-names = "default";
pinctrl-0 = <&gpio_led_aux>;
};
};
};
fragment@1 {
target-path = "/pinctrl/gpio-items";
__overlay__ {
gpio_led_aux: gpio-led-aux {
rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
};
reset_key: reset-key {
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
fragment@2 {
target = <&gpio_keys>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&reset_key>;
reset {
gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>;
label = "reset";
linux,code = <KEY_RESTART>;
debounce-interval = <200>;
wakeup-source;
};
};
};
};

View File

@ -0,0 +1,64 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
fragment@0 {
target-path = "/gpio-leds";
__overlay__ {
working {
gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>;
linux,default-trigger = "none";
};
auxiliary {
gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>;
label = "auxiliary";
linux,default-trigger = "mmc2";
default-state = "off";
pinctrl-names = "default";
pinctrl-0 = <&gpio_led_aux>;
};
};
};
fragment@1 {
target-path = "/pinctrl/gpio-items";
__overlay__ {
gpio_led_aux: gpio-led-aux {
rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
};
reset_key: reset-key {
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
fragment@2 {
target = <&gpio_keys>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&reset_key>;
reset {
gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>;
label = "reset";
linux,code = <KEY_RESTART>;
debounce-interval = <200>;
wakeup-source;
};
};
};
};

View File

@ -0,0 +1,64 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
fragment@0 {
target-path = "/gpio-leds";
__overlay__ {
working {
gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
};
auxiliary {
gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
label = "auxiliary";
linux,default-trigger = "mmc2";
default-state = "off";
pinctrl-names = "default";
pinctrl-0 = <&gpio_led_aux>;
};
};
};
fragment@1 {
target-path = "/pinctrl/gpio-items";
__overlay__ {
gpio_led_aux: gpio-led-aux {
rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
reset_key: reset-key {
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
fragment@2 {
target = <&gpio_keys>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&reset_key>;
reset {
gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>;
label = "reset";
linux,code = <KEY_RESTART>;
debounce-interval = <200>;
wakeup-source;
};
};
};
};

View File

@ -0,0 +1,96 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
fragment@0 {
target-path = "/gpio-leds";
__overlay__ {
working {
gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
};
auxiliary {
gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>;
label = "auxiliary";
linux,default-trigger = "mmc2";
default-state = "off";
pinctrl-names = "default";
pinctrl-0 = <&gpio_led_aux>;
};
};
};
fragment@1 {
target-path = "/pinctrl/gpio-items";
__overlay__ {
gpio_led_working: gpio-led-working {
rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
};
gpio_led_aux: gpio-led-aux {
rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
fragment@2 {
target = <&gpio_keys>;
__overlay__ {
reset {
gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>;
label = "reset";
linux,code = <KEY_RESTART>;
debounce-interval = <200>;
wakeup-source;
};
};
};
fragment@3 {
target = <&sdio_pwrseq>;
__overlay__ {
reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; /* GPIO2_D3 */
};
};
fragment@4 {
target = <&wifi_enable_h>;
__overlay__ {
rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
fragment@5 {
target = <&sdio>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
wifi@1 {
compatible = "esp,esp8089";
reg = <1>;
esp,crystal-26M-en = <0>;
};
};
};
};

View File

@ -0,0 +1,97 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
/*
* gpio configuration for AEMS IPB900 boards
*
* - enables working and auxiliary leds
* - fixes low strength on sdio pins for wifi
*/
/ {
fragment@0 {
target-path = "/gpio-leds";
__overlay__ {
working {
gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>;
linux,default-trigger = "none";
};
auxiliary {
gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_LOW>;
label = "auxiliary";
linux,default-trigger = "mmc2";
default-state = "off";
pinctrl-names = "default";
pinctrl-0 = <&gpio_led_aux>;
};
};
};
fragment@1 {
target-path = "/pinctrl/gpio-items";
__overlay__ {
gpio_led_aux: gpio-led-aux {
rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
};
reset_key: reset-key {
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
fragment@2 {
target = <&gpio_keys>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&reset_key>;
reset {
gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>;
label = "reset";
linux,code = <KEY_RESTART>;
debounce-interval = <200>;
wakeup-source;
};
};
};
fragment@3 {
target = <&sdio_bus4>;
__overlay__ {
rockchip,pins = <3 2 1 &pcfg_pull_none_8ma>,
<3 3 1 &pcfg_pull_none_8ma>,
<3 4 1 &pcfg_pull_none_8ma>,
<3 5 1 &pcfg_pull_none_8ma>;
};
};
fragment@4 {
target = <&sdio_clk>;
__overlay__ {
rockchip,pins = <3 0 1 &pcfg_pull_none_8ma>;
};
};
fragment@5 {
target = <&sdio_cmd>;
__overlay__ {
rockchip,pins = <3 1 1 &pcfg_pull_none_8ma>;
};
};
};

View File

@ -0,0 +1,96 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
/*
* gpio configuration for MXQ_PRO eMCP boards
*
* - fixes low strength on sdio pins for wifi
* - correct gpio pins for wifi
* - set emmc pins and default phase shift
*/
/ {
fragment@0 {
target-path = "/pinctrl/gpio-items";
__overlay__ {
reset_key: reset-key {
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
fragment@1 {
target = <&gpio_keys>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&reset_key>;
reset {
gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>;
label = "reset";
linux,code = <KEY_RESTART>;
debounce-interval = <200>;
wakeup-source;
};
};
};
fragment@2 {
target = <&sdio_bus4>;
__overlay__ {
rockchip,pins = <3 2 1 &pcfg_pull_up>,
<3 3 1 &pcfg_pull_up>,
<3 4 1 &pcfg_pull_up>,
<3 5 1 &pcfg_pull_up>;
};
};
fragment@3 {
target = <&sdio_clk>;
__overlay__ {
rockchip,pins = <3 0 1 &pcfg_pull_none>;
};
};
fragment@4 {
target = <&sdio_cmd>;
__overlay__ {
rockchip,pins = <3 1 1 &pcfg_pull_up>;
};
};
fragment@5 {
target = <&sdio_pwrseq>;
__overlay__ {
post-power-on-delay-ms = <300>;
power-off-delay-us = <200000>;
reset-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_LOW>;
};
};
fragment@6 {
target = <&sdio>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
wifi@1 {
compatible = "esp,esp8089";
reg = <1>;
esp,crystal-26M-en = <1>;
};
};
};
};

View File

@ -0,0 +1,180 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
/*
* gpio configuration for R29_MXQ boards
*
*/
&{/gpio-leds} {
working {
gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
pinctrl-0 = <&gpio_led_working>;
};
auxiliary {
gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
label = "auxiliary";
linux,default-trigger = "mmc2";
default-state = "off";
pinctrl-names = "default";
pinctrl-0 = <&gpio_led_auxiliary>;
};
};
&{/pinctrl/gpio-items} {
gpio_led_working: gpio-led-working {
rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
};
gpio_led_auxiliary: gpio-led-auxiliary {
rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
gpio_led_ethlink: gpio-led-ethlink{
rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
gpio_led_ethled: gpio-led-ethled{
rockchip,pins = <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
reset_key: reset-key {
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
&gpio_keys {
pinctrl-names = "default";
pinctrl-0 = <&reset_key>;
reset {
gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>;
label = "reset";
linux,code = <KEY_RESTART>;
debounce-interval = <200>;
wakeup-source;
};
};
&emmc {
rockchip,default-sample-phase = <112>;
bus-width = <8>;
clock-frequency = <125000000>;
max-frequency = <125000000>;
};
&vdd_arm {
compatible = "regulator-fixed";
regulator-name = "vdd_arm";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc_sys>;
};
&vdd_log {
compatible = "regulator-fixed";
regulator-name = "vdd_log";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc_sys>;
};
/*
* R29, R2B ad H20 boards require a GPIO to be turned low to enable HDMI output, we simulate it
* here as a regulator that must be always on.
* Also these boards don't have the necessary power regulators for CPU and Logic.
* R29 and R2B have a single power regulator fixed to 1.2v, hence the CPU can't go over 1.0 ghz
*/
&{/} {
vdd_hdmi_phy: vdd-hdmi-phy-regulator {
compatible = "regulator-fixed";
gpio = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_phy_enable>;
regulator-name = "vdd-hdmi-phy";
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc_sys>;
};
cpu_opp_table_r29: cpu-opp-table-r29 {
compatible = "operating-points-v2";
opp-shared;
opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1200000>;
clock-latency-ns = <40000>;
opp-suspend;
};
opp-816000000 {
opp-hz = /bits/ 64 <816000000>;
opp-microvolt = <1200000>;
};
opp-1008000000 {
opp-hz = /bits/ 64 <1008000000>;
opp-microvolt = <1200000>;
};
};
};
&pinctrl {
hdmi-phy {
hdmi_phy_enable: hdmi-phy-enable {
rockchip,pins = <2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
&pwm1 {
status = "disabled";
};
&pwm2 {
status = "disabled";
};
&cpu0 {
operating-points-v2 = <&cpu_opp_table_r29>;
};
&cpu1 {
operating-points-v2 = <&cpu_opp_table_r29>;
};
&cpu2 {
operating-points-v2 = <&cpu_opp_table_r29>;
};
&cpu3 {
operating-points-v2 = <&cpu_opp_table_r29>;
};

View File

@ -0,0 +1,109 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
/*
* gpio configuration for H20_221_V1.71 boards
*
*/
&{/gpio-leds} {
working {
gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
pinctrl-0 = <&gpio_led_working>;
};
auxiliary {
gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
label = "auxiliary";
linux,default-trigger = "mmc2";
default-state = "off";
pinctrl-names = "default";
pinctrl-0 = <&gpio_led_auxiliary>;
};
};
&{/pinctrl/gpio-items} {
gpio_led_working: gpio-led-working {
rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
};
gpio_led_auxiliary: gpio-led-auxiliary {
rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
gpio_led_ethlink: gpio-led-ethlink{
rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
};
gpio_led_ethled: gpio-led-ethled{
rockchip,pins = <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
reset_key: reset-key {
rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
&gpio_keys {
pinctrl-names = "default";
pinctrl-0 = <&reset_key>;
reset {
gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_LOW>;
label = "reset";
linux,code = <KEY_RESTART>;
debounce-interval = <200>;
wakeup-source;
};
};
&emmc {
rockchip,default-sample-phase = <112>;
bus-width = <8>;
clock-frequency = <125000000>;
max-frequency = <125000000>;
};
/*
* R29, R2B ad H20 boards require a GPIO to be turned low to enable HDMI output, we simulate it
* here as a regulator that must be always on.
* Also these boards don't have the necessary power regulators for CPU and Logic.
* R29 and R2B have a single power regulator fixed to 1.2v, hence the CPU can't go over 1.0 ghz
*/
&{/} {
vdd_hdmi_phy: vdd-hdmi-phy-regulator {
compatible = "regulator-fixed";
gpio = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_phy_enable>;
regulator-name = "vdd-hdmi-phy";
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc_sys>;
};
};
&pinctrl {
hdmi-phy {
hdmi_phy_enable: hdmi-phy-enable {
rockchip,pins = <2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};

View File

@ -0,0 +1,22 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&nfc>;
__overlay__ {
status = "okay";
pinctrl-0 = <&flash_cs0 &flash_cs1 &flash_cs2 &flash_cs3 &flash_rdy &flash_ale &flash_cle &flash_wrn &flash_bus8 &flash_dqs &flash_wp>;
pinctrl-names = "default";
};
};
fragment@1 {
target = <&emmc>;
__overlay__ {
status = "disabled";
};
};
};

View File

@ -0,0 +1,11 @@
/dts-v1/;
/plugin/;
/*
* change OTG USB port mode to "peripheral"
*
*/
&usb_otg {
dr_mode = "peripheral";
};

View File

@ -0,0 +1,67 @@
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
fragment@0 {
target = <&pinctrl>;
__overlay__ {
pcfg_pull_none_drv_4ma: pcfg-pull-none-drv-4ma {
bias-disable;
drive-strength = <0x04>;
};
pcfg_pull_up_drv_4ma: pcfg-pull-up-drv-4ma {
bias-pull-up;
drive-strength = <0x04>;
};
sdio {
sdio_clk: sdio-clk {
rockchip,pins = <1 0 1 &pcfg_pull_none_drv_4ma>;
};
sdio_cmd: sdio-cmd {
rockchip,pins = <0 3 2 &pcfg_pull_up_drv_4ma>;
};
sdio_bus4: sdio-bus4 {
rockchip,pins = <1 1 1 &pcfg_pull_up_drv_4ma>,
<1 2 1 &pcfg_pull_up_drv_4ma>,
<1 4 1 &pcfg_pull_up_drv_4ma>,
<1 5 1 &pcfg_pull_up_drv_4ma>;
};
};
};
};
fragment@1 {
target = <&sdio_pwrseq>;
__overlay__ {
reset-gpios = <&gpio2 RK_PD5 GPIO_ACTIVE_HIGH>;
};
};
fragment@2 {
target = <&wifi_enable_h>;
__overlay__ {
rockchip,pins = <2 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
fragment@3 {
target = <&sdio>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>;
};
};
};

View File

@ -0,0 +1,23 @@
/* Definitions for ds1307
* From ASUS: https://github.com/TinkerBoard/debian_kernel/commits/develop/arch/arm/boot/dts/overlays/ds1307-overlay.dts
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
rtc: ds1307@68 {
compatible = "dallas,ds1307";
reg = <0x68>;
status = "okay";
};
};
};
};

View File

@ -0,0 +1,4 @@
# overlays fixup script
# implements (or rather substitutes) overlay arguments functionality
# using u-boot scripting, environment variables and "fdt" command

View File

@ -0,0 +1,16 @@
/* Definitions for i2c1
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target = <&i2c1>;
__overlay__ {
status = "okay";
};
};
};

View File

@ -0,0 +1,16 @@
/* Definitions for i2c4
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target = <&i2c4>;
__overlay__ {
status = "okay";
};
};
};

View File

@ -0,0 +1,16 @@
/* Definitions for spi0
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
};
};
};

View File

@ -0,0 +1,16 @@
/* Definitions for spi2
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target = <&spi2>;
__overlay__ {
status = "okay";
};
};
};

View File

@ -0,0 +1,35 @@
/* Definition for SPI0 Spidev
* spi port for Tinker Board
*/
/dts-v1/;
/plugin/;
/{
compatible = "rockchip,rk3288";
fragment@0 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
spidev@0 {
compatible = "rockchip,spi_tinker";
reg = <0>;
spi-max-frequency = <50000000>;
spi-cpha = <1>;
status = "okay";
};
spidev@1 {
compatible = "rockchip,spi_tinker";
reg = <1>;
spi-max-frequency = <50000000>;
spi-cpha = <1>;
status = "okay";
};
};
};
};

View File

@ -0,0 +1,35 @@
/* Definition for SPI2 Spidev
* spi port for Tinker Board
*/
/dts-v1/;
/plugin/;
/{
compatible = "rockchip,rk3288";
fragment@0 {
target = <&spi2>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
spidev@0 {
compatible = "rockchip,spi_tinker";
reg = <0>;
spi-max-frequency = <50000000>;
spi-cpha = <1>;
status = "okay";
};
spidev@1 {
compatible = "rockchip,spi_tinker";
reg = <1>;
spi-max-frequency = <50000000>;
spi-cpha = <1>;
status = "okay";
};
};
};
};

View File

@ -0,0 +1,16 @@
/* Definitions for uart1
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target = <&uart1>;
__overlay__ {
status = "okay";
};
};
};

View File

@ -0,0 +1,16 @@
/* Definitions for uart2
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target = <&uart2>;
__overlay__ {
status = "okay";
};
};
};

View File

@ -0,0 +1,16 @@
/* Definitions for uart3
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target = <&uart3>;
__overlay__ {
status = "okay";
};
};
};

View File

@ -0,0 +1,16 @@
/* Definitions for uart4
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target = <&uart4>;
__overlay__ {
status = "okay";
};
};
};

View File

@ -0,0 +1,23 @@
/* 1-Wire GPIO
* From ASUS: https://github.com/TinkerBoard/debian_kernel/blob/develop/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts
*
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "rockchip,rk3288";
fragment@0 {
target-path = "/";
__overlay__ {
w1: onewire@0 {
compatible = "w1-gpio";
pinctrl-names = "default";
gpios = <&gpio0 17 0>;
status = "okay";
};
};
};
};

View File

@ -0,0 +1,45 @@
From 01b579a527b5c77e6adfbb2c277fb2c7cc158b8b Mon Sep 17 00:00:00 2001
From: Paolo Sabatino <paolo.sabatino@gmail.com>
Date: Thu, 10 Feb 2022 21:30:54 +0000
Subject: [PATCH] add broadcom bcm43342 chip id
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 ++
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 8effeb7a726..f45c1056e42 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -611,6 +611,7 @@ BRCMF_FW_DEF(4329, "brcmfmac4329-sdio");
BRCMF_FW_DEF(4330, "brcmfmac4330-sdio");
BRCMF_FW_DEF(4334, "brcmfmac4334-sdio");
BRCMF_FW_DEF(43340, "brcmfmac43340-sdio");
+BRCMF_FW_DEF(43342, "brcmfmac43342-sdio");
BRCMF_FW_DEF(4335, "brcmfmac4335-sdio");
BRCMF_FW_DEF(43362, "brcmfmac43362-sdio");
BRCMF_FW_DEF(4339, "brcmfmac4339-sdio");
@@ -644,6 +645,7 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334),
BRCMF_FW_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340),
BRCMF_FW_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340),
+ BRCMF_FW_ENTRY(BRCM_CC_43342_CHIP_ID, 0xFFFFFFFF, 43342),
BRCMF_FW_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335),
BRCMF_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362),
BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 9d81320164c..71de0dce4f4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -27,6 +27,7 @@
#define BRCM_CC_4334_CHIP_ID 0x4334
#define BRCM_CC_43340_CHIP_ID 43340
#define BRCM_CC_43341_CHIP_ID 43341
+#define BRCM_CC_43342_CHIP_ID 43342
#define BRCM_CC_43362_CHIP_ID 43362
#define BRCM_CC_4335_CHIP_ID 0x4335
#define BRCM_CC_4339_CHIP_ID 0x4339
--
2.30.2

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
config:
# Just some info stuff; not used by the patching scripts
name: rockchip-6.6
kind: kernel
type: mainline # or: vendor
branch: linux-6.6.y
last-known-good-tag: v6.6.8
maintainers:
- { github: paolo.sabatino, name: Paolo Sabatino, email: paolo.sabatino@gmail.com, armbian-forum: jock }
# .dts files in these directories will be copied as-is to the build tree; later ones overwrite earlier ones.
# This is meant to provide a way to "add a board DTS" without having to null-patch them in.
dts-directories:
- { source: "dt", target: "arch/arm/boot/dts/rockchip" }
# every file in these directories will be copied as-is to the build tree; later ones overwrite earlier ones
# This is meant as a way to have overlays, bare, in a directory, without having to null-patch them in.
# @TODO need a solution to auto-Makefile the overlays as well
overlay-directories:
- { source: "overlay", target: "arch/arm/boot/dts/rockchip/overlay" }
# the Makefile in each of these directories will be magically patched to include the dts files copied
# or patched-in; overlay subdir will be included "-y" if it exists.
# No more Makefile patching needed, yay!
auto-patch-dt-makefile:
- { directory: "arch/arm/boot/dts/rockchip", config-var: "CONFIG_ARCH_ROCKCHIP" }
# configuration for when applying patches to git / auto-rewriting patches (development cycle helpers)
patches-to-git:
do-not-commit-files:
- "MAINTAINERS" # constant churn, drop them. sorry.
- "Documentation/devicetree/bindings/arm/rockchip.yaml" # constant churn, conflicts on every bump, drop it. sorry.
do-not-commit-regexes: # Python-style regexes
- "^arch/([a-zA-Z0-9]+)/boot/dts/([a-zA-Z0-9]+)/Makefile$" # ignore DT Makefile patches, we've an auto-patcher now

View File

@ -1,28 +0,0 @@
From ebc29962ac27264772a4227f5abd6900cb72fa79 Mon Sep 17 00:00:00 2001
From: "Miouyouyou (Myy)" <myy@miouyouyou.fr>
Date: Mon, 5 Nov 2018 20:16:05 +0100
Subject: [PATCH] ARM: DTSI: rk3288-tinker: Improving the CPU max voltage
Taken from the various patches provided by @TonyMac32 .
Signed-off-by: Miouyouyou (Myy) <myy@miouyouyou.fr>
---
arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi
index aa107ee41..3da1c830f 100644
--- a/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi
@@ -164,7 +164,7 @@
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <1400000>;
+ regulator-max-microvolt = <1450000>;
regulator-name = "vdd_arm";
regulator-ramp-delay = <6000>;
regulator-state-mem {
--
2.16.4

Some files were not shown because too many files have changed in this diff Show More