rockchip: implement governor attribute sysfs for rk322x-dmc

This commit is contained in:
Paolo Sabatino 2023-12-31 17:36:04 +01:00 committed by Gunjan Gupta
parent 69d0ec7218
commit cba4c033b0

View File

@ -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 <paolo.sabatino@gmail.com>
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 = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
@@ -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 <hl@rock-chips.com>");
+MODULE_AUTHOR("Paolo Sabatino <paolo.sabatino@gmail.com>");
+MODULE_DESCRIPTION("RK3228 dmcfreq driver with devfreq framework");
--
2.25.1
2.34.1