add nanopi-r4s support

* linux-6.1
This commit is contained in:
sbwml 2023-01-03 01:18:49 +08:00
parent bb63c927fd
commit 34df2da64e
14 changed files with 882 additions and 5 deletions

View File

@ -16,7 +16,7 @@ endef
include $(INCLUDE_DIR)/target.mk
DEFAULT_PACKAGES += uboot-envtools partx-utils e2fsprogs mkf2fs kmod-gpio-button-hotplug \
automount autocore-arm fdisk e2fsprogs ethtool
autocore-arm fdisk e2fsprogs ethtool
KERNELNAME:=Image dtbs

View File

@ -8,6 +8,10 @@ boardname="${board##*,}"
board_config_update
case $board in
friendlyarm,nanopi-r4s)
ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth0"
ucidef_set_led_netdev "lan" "LAN" "green:lan" "eth1"
;;
friendlyarm,nanopi-r5s)
ucidef_set_led_default "power" "POWER" "red:power" "1"
ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth0"

View File

@ -7,6 +7,9 @@ rockchip_setup_interfaces()
local board="$1"
case "$board" in
friendlyarm,nanopi-r4s)
ucidef_set_interfaces_lan_wan 'eth1' 'eth0'
;;
friendlyarm,nanopi-r5s)
ucidef_set_interfaces_lan_wan 'eth1 eth2' 'eth0'
;;
@ -16,10 +19,10 @@ rockchip_setup_interfaces()
esac
}
nanopi_r5s_generate_mac()
nanopi_generate_mac()
{
local emmc_hash=$(sha256sum /sys/block/mmcblk*/device/cid | head -n 1)
local mac_base=$(macaddr_canonicalize "$(echo "${emmc_hash}" | dd bs=1 count=12 2>/dev/null)")
local mmc_hash=$(sha256sum /sys/block/mmcblk*/device/cid | head -n 1)
local mac_base=$(macaddr_canonicalize "$(echo "${mmc_hash}" | dd bs=1 count=12 2>/dev/null)")
echo "$(macaddr_unsetbit_mc "$(macaddr_setbit_la "${mac_base}")")"
}
@ -31,8 +34,16 @@ rockchip_setup_macs()
local label_mac=""
case "$board" in
friendlyarm,nanopi-r4s)
if [ -f /sys/bus/i2c/devices/2-0051/eeprom ]; then
wan_mac=$(get_mac_binary "/sys/bus/i2c/devices/2-0051/eeprom" 0xfa)
else
wan_mac=$(nanopi_generate_mac)
fi
lan_mac=$(macaddr_setbit_la "$wan_mac")
;;
friendlyarm,nanopi-r5s)
wan_mac=$(nanopi_r5s_generate_mac)
wan_mac=$(nanopi_generate_mac)
lan_mac=$(macaddr_add "$wan_mac" +1)
;;
esac

View File

@ -29,6 +29,10 @@ set_interface_core() {
}
case "$(board_name)" in
friendlyarm,nanopi-r4s)
set_interface_core 10 "eth0"
set_interface_core 20 "eth1"
;;
friendlyarm,nanopi-r5s)
set_interface_core 8 "eth0"
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus

View File

@ -44,6 +44,26 @@ define Build/pine64-img
dd if="$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-u-boot.itb of="$@" seek=16384 conv=notrunc
endef
define Build/pine64-bin
# Typical Rockchip boot flow with Rockchip miniloader
# Rockchp idbLoader which is combinded by Rockchip ddr init bin
# and miniloader bin from Rockchip rkbin project
# Generate a new partition table in $@ with 32 MiB of alignment
# padding for the idbloader, uboot and trust image to fit:
# http://opensource.rock-chips.com/wiki_Boot_option#Boot_flow
PADDING=1 $(SCRIPT_DIR)/gen_image_generic.sh \
$@ \
$(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
32768
# Copy the idbloader, uboot and trust image to the image at sector 0x40, 0x4000 and 0x6000
dd if="$(STAGING_DIR_IMAGE)"/$(SOC)-idbloader.bin of="$@" seek=64 conv=notrunc
dd if="$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-uboot.img of="$@" seek=16384 conv=notrunc
dd if="$(STAGING_DIR_IMAGE)"/$(SOC)-trust.bin of="$@" seek=24576 conv=notrunc
endef
### Devices ###
define Device/Default
PROFILES := Default

View File

@ -5,6 +5,16 @@
# FIT will be loaded at 0x02080000. Leave 16M for that, align it to 2M and load the kernel after it.
KERNEL_LOADADDR := 0x03200000
define Device/friendlyarm_nanopi-r4s
DEVICE_VENDOR := FriendlyARM
DEVICE_MODEL := NanoPi R4S
SOC := rk3399
UBOOT_DEVICE_NAME := nanopi-r4s-rk3399
IMAGE/sysupgrade.img.gz := boot-common | boot-script nanopi-r4s | pine64-bin | gzip | append-metadata
DEVICE_PACKAGES := kmod-r8168
endef
TARGET_DEVICES += friendlyarm_nanopi-r4s
define Device/friendlyarm_nanopi-r5s
DEVICE_VENDOR := FriendlyARM
DEVICE_MODEL := NanoPi R5S

View File

@ -0,0 +1,7 @@
part uuid mmc ${devnum}:2 uuid
setenv bootargs "console=ttyS2,1500000 earlycon=uart8250,mmio32,0xff1a0000 root=PARTUUID=${uuid} rw rootwait mitigations=off"
load mmc ${devnum}:1 ${kernel_addr_r} kernel.img
bootm ${kernel_addr_r}

View File

@ -0,0 +1,20 @@
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
index fe5b52610..993d85f47 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
@@ -68,6 +68,15 @@ &emmc_phy {
status = "disabled";
};
+&i2c2 {
+ eeprom@51 {
+ compatible = "microchip,24c02", "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ read-only; /* This holds our MAC */
+ };
+};
+
&i2c4 {
status = "disabled";
};

View File

@ -0,0 +1,18 @@
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
index 993d85f47..15feab9a4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
@@ -19,6 +19,13 @@ / {
model = "FriendlyElec NanoPi R4S";
compatible = "friendlyarm,nanopi-r4s", "rockchip,rk3399";
+ aliases {
+ led-boot = &sys_led;
+ led-failsafe = &sys_led;
+ led-running = &sys_led;
+ led-upgrade = &sys_led;
+ };
+
/delete-node/ display-subsystem;
gpio-leds {

View File

@ -0,0 +1,16 @@
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
index 15feab9a4..038d17276 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
@@ -128,6 +128,11 @@ &sdio0 {
status = "disabled";
};
+&sdmmc {
+ /delete-property/ sd-uhs-sdr104;
+ cap-sd-highspeed;
+};
+
&u2phy0_host {
phy-supply = <&vdd_5v>;
};

View File

@ -0,0 +1,24 @@
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
index 038d17276..16d2d8cc2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
@@ -92,6 +92,19 @@ &pcie0 {
max-link-speed = <1>;
num-lanes = <1>;
vpcie3v3-supply = <&vcc3v3_sys>;
+
+ pcie@0 {
+ reg = <0x00000000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ pcie-eth@0,0 {
+ compatible = "pci10ec,8168";
+ reg = <0x000000 0 0 0 0>;
+
+ realtek,led-data = <0x870>;
+ };
+ };
};
&pinctrl {

View File

@ -0,0 +1,35 @@
From 0d329112c709d6cfedf0fffb19f0cc6b19043f6b Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 20 Feb 2019 07:38:34 +0000
Subject: [PATCH] mmc: core: set initial signal voltage on power off
Some boards have SD card connectors where the power rail cannot be switched
off by the driver. If the card has not been power cycled, it may still be
using 1.8V signaling after a warm re-boot. Bootroms expecting 3.3V signaling
will fail to boot from a UHS card that continue to use 1.8V signaling.
Set initial signal voltage in mmc_power_off() to allow re-boot to function.
This fixes re-boot with UHS cards on Asus Tinker Board (Rockchip RK3288),
same issue have been seen on some Rockchip RK3399 boards.
I am sending this as a RFC because I have no insights into SD/MMC subsystem,
this change fix a re-boot issue on my boards and does not break emmc/sdio.
Is this an acceptable workaround? Any advice is appreciated.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/mmc/core/core.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1366,6 +1366,8 @@ void mmc_power_off(struct mmc_host *host
mmc_pwrseq_power_off(host);
+ mmc_set_initial_signal_voltage(host);
+
host->ios.clock = 0;
host->ios.vdd = 0;

View File

@ -0,0 +1,662 @@
From 4db93c6dad0c71750b86163df2fdb21c35f00d9a Mon Sep 17 00:00:00 2001
From: hmz007 <hmz007@gmail.com>
Date: Tue, 19 Nov 2019 12:49:48 +0800
Subject: [PATCH] PM / devfreq: rockchip-dfi: add more soc support
Signed-off-by: hmz007 <hmz007@gmail.com>
---
drivers/devfreq/event/rockchip-dfi.c | 554 ++++++++++++++++++++++++---
1 file changed, 505 insertions(+), 49 deletions(-)
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -18,25 +18,66 @@
#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 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 +91,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 +369,22 @@ static int rockchip_dfi_get_busier_ch(st
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;
@@ -121,7 +400,8 @@ static int rockchip_dfi_disable(struct d
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);
return 0;
}
@@ -131,10 +411,13 @@ static int rockchip_dfi_enable(struct de
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
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);
@@ -151,8 +434,11 @@ static int rockchip_dfi_get_event(struct
{
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 +453,116 @@ static const struct devfreq_event_ops ro
.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 *dev = &pdev->dev;
- struct rockchip_dfi *data;
- struct devfreq_event_desc *desc;
struct device_node *np = pdev->dev.of_node, *node;
- data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
+ 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 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;
+
+ 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))
@@ -201,21 +581,97 @@ static int rockchip_dfi_probe(struct pla
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,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);
}

View File

@ -0,0 +1,46 @@
From 04202df5cb497b1934c95211cf43784ef62245a4 Mon Sep 17 00:00:00 2001
From: Tianling Shen <cnsztl@immortalwrt.org>
Date: Mon, 18 Oct 2021 12:47:30 +0800
Subject: [PATCH] rockchip: rk3399: overclock to 2.2/1.8 GHz
It's stable enough to overclock cpu frequency to 2.2/1.8 GHz,
and for better performance.
Co-development-by: gzelvis <gzelvis@gmail.com>
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
---
arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
--- a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi
@@ -33,6 +33,14 @@
opp-hz = /bits/ 64 <1416000000>;
opp-microvolt = <1125000 1125000 1250000>;
};
+ opp06 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <1225000>;
+ };
+ opp07 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <1275000>;
+ };
};
cluster1_opp: opp-table-1 {
@@ -72,6 +80,14 @@
opp-hz = /bits/ 64 <1800000000>;
opp-microvolt = <1200000 1200000 1250000>;
};
+ opp08 {
+ opp-hz = /bits/ 64 <2016000000>;
+ opp-microvolt = <1250000>;
+ };
+ opp09 {
+ opp-hz = /bits/ 64 <2208000000>;
+ opp-microvolt = <1325000>;
+ };
};
gpu_opp_table: opp-table-2 {