diff --git a/patch/kernel/archive/rockchip-6.6/patches.armbian/rk322x-dmc-driver-04-driver.patch b/patch/kernel/archive/rockchip-6.6/patches.armbian/rk322x-dmc-driver-04-driver.patch index 8ff4e255cf..3dfa3754e5 100644 --- a/patch/kernel/archive/rockchip-6.6/patches.armbian/rk322x-dmc-driver-04-driver.patch +++ b/patch/kernel/archive/rockchip-6.6/patches.armbian/rk322x-dmc-driver-04-driver.patch @@ -1,23 +1,22 @@ -From e7c97c57e2d5040e90662459239bc28c8ea89be5 Mon Sep 17 00:00:00 2001 +From 8529e1141bf84ff4e0120eeb42e45a59c8e666c7 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino -Date: Wed, 7 Jul 2021 19:27:03 +0000 -Subject: [PATCH] rk3228/rk3328: add dmc driver +Date: Wed, 27 Dec 2023 15:29:29 +0100 +Subject: [PATCH] rockchip: add rk3228 dmc driver --- - arch/arm/boot/dts/rockchip/rk322x.dtsi | 69 +- - drivers/devfreq/Kconfig | 24 + - drivers/devfreq/Makefile | 2 + - drivers/devfreq/rk3228_dmc.c | 623 ++++++++++++++ - include/dt-bindings/clock/rockchip-ddr.h | 63 ++ - include/dt-bindings/memory/rockchip,rk322x.h | 90 ++ - 7 files changed, 1714 insertions(+), 3 deletions(-) + arch/arm/boot/dts/rockchip/rk322x.dtsi | 70 +- + drivers/devfreq/Kconfig | 12 + + drivers/devfreq/Makefile | 1 + + drivers/devfreq/rk3228_dmc.c | 696 +++++++++++++++++++ + include/dt-bindings/clock/rockchip-ddr.h | 63 ++ + include/dt-bindings/memory/rockchip,rk322x.h | 90 +++ + 6 files changed, 929 insertions(+), 3 deletions(-) create mode 100644 drivers/devfreq/rk3228_dmc.c - create mode 100644 drivers/devfreq/rk3328_dmc.c create mode 100644 include/dt-bindings/clock/rockchip-ddr.h create mode 100644 include/dt-bindings/memory/rockchip,rk322x.h diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi -index 88e33eb11..22da2e3cd 100644 +index 41374aff62c8..c9d71a776587 100644 --- a/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi @@ -7,6 +7,8 @@ @@ -29,7 +28,7 @@ index 88e33eb11..22da2e3cd 100644 / { #address-cells = <1>; -@@ -106,6 +106,68 @@ dfi: dfi@11210000 { +@@ -104,6 +106,68 @@ dfi: dfi@11210000 { status = "okay"; }; @@ -98,7 +97,7 @@ index 88e33eb11..22da2e3cd 100644 arm-pmu { compatible = "arm,cortex-a7-pmu"; interrupts = , -@@ -673,17 +736,17 @@ gpu_opp_table: opp-table2 { +@@ -676,17 +740,17 @@ gpu_opp_table: opp-table2 { opp-200000000 { opp-hz = /bits/ 64 <200000000>; @@ -120,12 +119,12 @@ index 88e33eb11..22da2e3cd 100644 }; diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig -index 37dc40d1f..5f864a855 100644 +index 3c4862a752b5..066be239a16a 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig -@@ -131,6 +131,18 @@ config ARM_TEGRA20_DEVFREQ - It reads Memory Controller counters and adjusts the operating - frequencies and voltages with OPP support. +@@ -129,6 +129,18 @@ config ARM_MEDIATEK_CCI_DEVFREQ + buck voltages and update a proper CCI frequency. Use the notification + to get the regulator status. +config ARM_RK3228_DMC_DEVFREQ + tristate "ARM RK3228 DMC DEVFREQ Driver" @@ -143,7 +142,7 @@ index 37dc40d1f..5f864a855 100644 tristate "ARM RK3399 DMC DEVFREQ Driver" depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \ diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile -index bf40d04928d..059712bfe5f 100644 +index bf40d04928d0..059712bfe5f5 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o @@ -156,7 +155,7 @@ index bf40d04928d..059712bfe5f 100644 diff --git a/include/dt-bindings/clock/rockchip-ddr.h b/include/dt-bindings/clock/rockchip-ddr.h new file mode 100644 -index 000000000..b065432e7 +index 000000000000..b065432e7793 --- /dev/null +++ b/include/dt-bindings/clock/rockchip-ddr.h @@ -0,0 +1,63 @@ @@ -225,7 +224,7 @@ index 000000000..b065432e7 +#endif diff --git a/include/dt-bindings/memory/rockchip,rk322x.h b/include/dt-bindings/memory/rockchip,rk322x.h new file mode 100644 -index 000000000..1ab3317d7 +index 000000000000..1ab3317d700e --- /dev/null +++ b/include/dt-bindings/memory/rockchip,rk322x.h @@ -0,0 +1,90 @@ @@ -319,13 +318,12 @@ index 000000000..1ab3317d7 +#define PHY_LP23_RON_RTT_20ohm (31) + +#endif /* _DT_BINDINGS_DRAM_ROCKCHIP_RK322X_H */ - diff --git a/drivers/devfreq/rk3228_dmc.c b/drivers/devfreq/rk3228_dmc.c new file mode 100644 -index 000000000000..59c012b91ac0 +index 000000000000..1dbf53043f69 --- /dev/null +++ b/drivers/devfreq/rk3228_dmc.c -@@ -0,0 +1,670 @@ +@@ -0,0 +1,827 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd. @@ -487,6 +485,7 @@ index 000000000000..59c012b91ac0 + struct devfreq_event_dev *edev; + struct clk *dmc_clk; + struct rk3228_devfreq devfreq; ++ u32 load; + + uint32_t dram_type; + @@ -590,6 +589,7 @@ index 000000000000..59c012b91ac0 + stat->current_frequency = rdev->rate; + stat->busy_time = edata.load_count; + stat->total_time = edata.total_count; ++ rdev->load = (edata.load_count * 100) / edata.total_count; + + return ret; +} @@ -853,6 +853,157 @@ index 000000000000..59c012b91ac0 + +} + ++/** ++ * Callback to return the current load on DRAM in percentage exported via sysfs; see DEVICE_ATTR_RO(SYSFS_LOAD) ++ */ ++#define SYSFS_LOAD load ++static ssize_t load_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ ++ int ret; ++ struct rk3228_dmc *rdev = dev_get_drvdata(dev); ++ ++ mutex_lock(&rdev->devfreq.devfreq->lock); ++ ++ ret = sysfs_emit(buf, "%u", rdev->load); ++ ++ mutex_unlock(&rdev->devfreq.devfreq->lock); ++ ++ return ret; ++ ++} ++static DEVICE_ATTR_RO(SYSFS_LOAD); ++ ++#define SYSFS_UPTHRESHOLD upthreshold ++static ssize_t upthreshold_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ ++ int ret; ++ struct rk3228_dmc *rdev = dev_get_drvdata(dev); ++ ++ mutex_lock(&rdev->devfreq.devfreq->lock); ++ ++ ret = sysfs_emit(buf, "%u", rdev->ondemand_data.upthreshold); ++ ++ mutex_unlock(&rdev->devfreq.devfreq->lock); ++ ++ return ret; ++ ++} ++ ++static ssize_t upthreshold_store(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ ++ int ret; ++ u32 upthreshold; ++ struct rk3228_dmc *rdev = dev_get_drvdata(dev); ++ ++ mutex_lock(&rdev->devfreq.devfreq->lock); ++ ++ ret = kstrtouint(buf, 0, &upthreshold); ++ ++ if (ret < 0) ++ goto out; ++ ++ if (upthreshold > 100) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ rdev->ondemand_data.upthreshold = upthreshold; ++ ++ ret = count; ++ ++out: ++ mutex_unlock(&rdev->devfreq.devfreq->lock); ++ ++ return ret; ++ ++} ++static DEVICE_ATTR_RW(SYSFS_UPTHRESHOLD); ++ ++#define SYSFS_DOWNDIFFERENTIAL downdifferential ++static ssize_t downdifferential_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ ++ int ret; ++ struct rk3228_dmc *rdev = dev_get_drvdata(dev); ++ ++ mutex_lock(&rdev->devfreq.devfreq->lock); ++ ++ ret = sysfs_emit(buf, "%u", rdev->ondemand_data.downdifferential); ++ ++ mutex_unlock(&rdev->devfreq.devfreq->lock); ++ ++ return ret; ++ ++} ++ ++static ssize_t downdifferential_store(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ ++ int ret; ++ u32 downdifferential; ++ struct rk3228_dmc *rdev = dev_get_drvdata(dev); ++ ++ mutex_lock(&rdev->devfreq.devfreq->lock); ++ ++ ret = kstrtouint(buf, 0, &downdifferential); ++ ++ if (ret < 0) ++ goto out; ++ ++ if (downdifferential > 100) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ rdev->ondemand_data.downdifferential = downdifferential; ++ ++ ret = count; ++ ++out: ++ mutex_unlock(&rdev->devfreq.devfreq->lock); ++ ++ return ret; ++ ++} ++static DEVICE_ATTR_RW(SYSFS_DOWNDIFFERENTIAL); ++ ++static int rk3228_dmc_sysfs_create(struct device *dev) ++{ ++ ++ int ret; ++ ++ ret = device_create_file(dev, &dev_attr_SYSFS_LOAD); ++ if (ret < 0) ++ goto out; ++ ++ ret = device_create_file(dev, &dev_attr_SYSFS_UPTHRESHOLD); ++ if (ret < 0) ++ goto out; ++ ++ ret = device_create_file(dev, &dev_attr_SYSFS_DOWNDIFFERENTIAL); ++ if (ret < 0) ++ goto out; ++ ++out: ++ return ret; ++ ++} ++ ++static void rk3228_dmc_sysfs_remove(struct device *dev) ++{ ++ ++ device_remove_file(dev, &dev_attr_SYSFS_LOAD); ++ device_remove_file(dev, &dev_attr_SYSFS_UPTHRESHOLD); ++ device_remove_file(dev, &dev_attr_SYSFS_DOWNDIFFERENTIAL); ++ ++} ++ ++ +static int rk3228_dmc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; @@ -954,6 +1105,10 @@ index 000000000000..59c012b91ac0 + + platform_set_drvdata(pdev, data); + ++ ret = rk3228_dmc_sysfs_create(dev); ++ if (ret < 0) ++ dev_err(dev, "could not create sysfs interface files, ret=%d\n", ret); ++ + return 0; + +} @@ -962,6 +1117,8 @@ index 000000000000..59c012b91ac0 +{ + struct rk3228_dmc *rdev = dev_get_drvdata(&pdev->dev); + ++ rk3228_dmc_sysfs_remove(&pdev->dev); ++ + /* + * Before remove the opp table we need to unregister the opp notifier. + */ @@ -970,9 +1127,6 @@ index 000000000000..59c012b91ac0 + if (ddr_psci_param) + iounmap(ddr_psci_param); + -+ if (rdev->iomem) -+ iounmap(rdev->iomem); -+ + return 0; +} + @@ -995,7 +1149,7 @@ index 000000000000..59c012b91ac0 + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Lin Huang "); ++MODULE_AUTHOR("Paolo Sabatino "); +MODULE_DESCRIPTION("RK3228 dmcfreq driver with devfreq framework"); - -- -2.25.1 +2.34.1