aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-5.4/818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch145
1 files changed, 145 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch b/target/linux/layerscape/patches-5.4/818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch
new file mode 100644
index 0000000000..4777ce939c
--- /dev/null
+++ b/target/linux/layerscape/patches-5.4/818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch
@@ -0,0 +1,145 @@
+From 0a5d1b571ba5bca9c6737572ea4c8b1ad896c3fc Mon Sep 17 00:00:00 2001
+From: Anson Huang <Anson.Huang@nxp.com>
+Date: Wed, 7 Aug 2019 13:24:26 +0800
+Subject: [PATCH] thermal: qoriq: Add device cooling support
+
+Register device cooling for first thermal zone manually, when
+temperature exceeds passive trip, system wide cooling notification
+will be triggered.
+
+Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
+---
+ drivers/thermal/qoriq_thermal.c | 80 ++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 79 insertions(+), 1 deletion(-)
+
+--- a/drivers/thermal/qoriq_thermal.c
++++ b/drivers/thermal/qoriq_thermal.c
+@@ -3,6 +3,7 @@
+ // Copyright 2016 Freescale Semiconductor, Inc.
+
+ #include <linux/clk.h>
++#include <linux/device_cooling.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/err.h>
+@@ -14,6 +15,7 @@
+ #include "thermal_core.h"
+
+ #define SITES_MAX 16
++#define TMU_TEMP_PASSIVE_COOL_DELTA 10000
+
+ /*
+ * QorIQ TMU Registers
+@@ -69,6 +71,9 @@ struct qoriq_sensor {
+ struct thermal_zone_device *tzd;
+ struct qoriq_tmu_data *qdata;
+ int id;
++ int temp_passive;
++ int temp_critical;
++ struct thermal_cooling_device *cdev;
+ };
+
+ struct qoriq_tmu_data {
+@@ -78,6 +83,12 @@ struct qoriq_tmu_data {
+ struct qoriq_sensor *sensor[SITES_MAX];
+ };
+
++enum tmu_trip {
++ TMU_TRIP_PASSIVE,
++ TMU_TRIP_CRITICAL,
++ TMU_TRIP_NUM,
++};
++
+ static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr)
+ {
+ if (p->little_endian)
+@@ -106,14 +117,51 @@ static int tmu_get_temp(void *p, int *te
+ return 0;
+ }
+
++static int tmu_get_trend(void *p, int trip, enum thermal_trend *trend)
++{
++ struct qoriq_sensor *qsensor = p;
++ int trip_temp;
++
++ if (!qsensor->tzd)
++ return 0;
++
++ trip_temp = (trip == TMU_TRIP_PASSIVE) ? qsensor->temp_passive :
++ qsensor->temp_critical;
++
++ if (qsensor->tzd->temperature >=
++ (trip_temp - TMU_TEMP_PASSIVE_COOL_DELTA))
++ *trend = THERMAL_TREND_RAISE_FULL;
++ else
++ *trend = THERMAL_TREND_DROP_FULL;
++
++ return 0;
++}
++
++static int tmu_set_trip_temp(void *p, int trip,
++ int temp)
++{
++ struct qoriq_sensor *qsensor = p;
++
++ if (trip == TMU_TRIP_CRITICAL)
++ qsensor->temp_critical = temp;
++
++ if (trip == TMU_TRIP_PASSIVE)
++ qsensor->temp_passive = temp;
++
++ return 0;
++}
++
+ static const struct thermal_zone_of_device_ops tmu_tz_ops = {
+ .get_temp = tmu_get_temp,
++ .get_trend = tmu_get_trend,
++ .set_trip_temp = tmu_set_trip_temp,
+ };
+
+ static int qoriq_tmu_register_tmu_zone(struct platform_device *pdev)
+ {
+ struct qoriq_tmu_data *qdata = platform_get_drvdata(pdev);
+- int id, sites = 0;
++ const struct thermal_trip *trip;
++ int id, sites = 0, ret;
+
+ for (id = 0; id < SITES_MAX; id++) {
+ qdata->sensor[id] = devm_kzalloc(&pdev->dev,
+@@ -132,6 +180,36 @@ static int qoriq_tmu_register_tmu_zone(s
+ return PTR_ERR(qdata->sensor[id]->tzd);
+ }
+
++ /* first thermal zone takes care of system-wide device cooling */
++ if (id == 0) {
++ qdata->sensor[id]->cdev = devfreq_cooling_register();
++ if (IS_ERR(qdata->sensor[id]->cdev)) {
++ ret = PTR_ERR(qdata->sensor[id]->cdev);
++ pr_err("failed to register devfreq cooling device: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = thermal_zone_bind_cooling_device(qdata->sensor[id]->tzd,
++ TMU_TRIP_PASSIVE,
++ qdata->sensor[id]->cdev,
++ THERMAL_NO_LIMIT,
++ THERMAL_NO_LIMIT,
++ THERMAL_WEIGHT_DEFAULT);
++ if (ret) {
++ pr_err("binding zone %s with cdev %s failed:%d\n",
++ qdata->sensor[id]->tzd->type,
++ qdata->sensor[id]->cdev->type,
++ ret);
++ devfreq_cooling_unregister(qdata->sensor[id]->cdev);
++ return ret;
++ }
++
++ trip = of_thermal_get_trip_points(qdata->sensor[id]->tzd);
++ qdata->sensor[id]->temp_passive = trip[0].temperature;
++ qdata->sensor[id]->temp_critical = trip[1].temperature;
++ }
++
+ sites |= 0x1 << (15 - id);
+ }
+