layerscape: add patches-5.4
[openwrt/staging/wigyori.git] / target / linux / layerscape / patches-5.4 / 818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch
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 (file)
index 0000000..4777ce9
--- /dev/null
@@ -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);
+       }