linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v11 0/6] Add LVTS thermal architecture
@ 2023-01-24 13:17 bchihi
  2023-01-24 13:17 ` [PATCH v11 1/6] thermal/drivers/mediatek: Relocate driver to mediatek folder bchihi
                   ` (5 more replies)
  0 siblings, 6 replies; 57+ messages in thread
From: bchihi @ 2023-01-24 13:17 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

The LVTS (Low Voltage Thermal Sensor) driver is capable of monitoring
multiple hot points. For that, it contains 7 thermal control blocks
dedicated to specific devices on the die. Each control block can handle
up to 4 sensors. 

The thermal controller supports several interrupts. One for the cold
trip point, the hot trip point, the return to the normal trip point,
and a specific programmable trip point to monitor the temperature
dynamically.

The temperature measurement can be done in two ways, the immediate mode
where the temperature read is instantaneous and the filtered mode where
the controller uses, by configuration, an average of a set of values
removing the minimum and the maximum.

Finally, it is composed of 2 finite-state machines responsible for
the state of the temperature (cold, hot, hot 2 normal, hot hot),
the triggering of the interrupts, and the monitoring of the temperature.

As requested, the thermal driver has been reworked to reduce
the complexity of the code. At this time, the 4 little CPUs and
the 4 big CPUs are supported by the thermal driver.They are described
in a data structure and more devices can be added later.
The calibration routine has been simplified also.

The series provide the following changes:
 - Move the Mediatek drivers inside a dedicated folder as their number
   is increasing
 - Add the DT bindings for the controller
 - Add the efuse node for the mt8195
 - The LVTS driver
 - The thermal zones description in the DT

Changelog:
  v11:
     - Rebase on top of "thermal/linux-next" :
       base=0d568e144ead70189e7f16066dcb155b78ff9266
     - Remove unsupported SoC (mt8192) from dt-binding definition
     - Fix coding style issues :
       - Move litterals to define
       - Add interrupt macros
       - Remove wildcard : only mt8195 is supported for now

  v10:
     - Rebase on top of "thermal/linux-next" : thermal-v6.3-rc1
     - Rework the LVTS driver
     - Add the thermal trip temperature and cooling devices
       for the sensors supported by the driver

  v9:
     - Rebase on top of 6.0.0-rc1
     - Fix coding style issues
     - Fix commit titles and commit messages
     - Update dt-bindings :
     - Add "allOf:if:then:"
     - Use mt8192 as example (instead of mt8195)
     - Fix dt-binding errors
     - Fix DTS errors

  v8:
     - Fix coding style issues
     - Rebase on top of next-20220803
     - Add multi-instance support :
       - Rewrite DT-binding and DTS :
         - Add DT-binding and DTS for LVTS_v4 (MT8192 and MT8195)
           - One LVTS node for each HW Domain (AP and MCU)
         - One SW Instance for each HW Domain
         - Add a Kconfig sub-menu entry for LVTS and LVTS_v4 SoCs
     - Replace platform_get_resource by platform_get_mem_or_io to get
       Base Address
     - Replace platform_get_resource by platform_get_irq to get
       Interrupt Number
     - Add "lvts_" prefix to functions and structs

 v7:
     - Fix coding style issues
     - Rewrite dt bindings
       - was not accurate
       - Use mt8195 for example (instead of mt8192)
       - Rename mt6873 to mt8192
       - Remove clock name
     - Rebased on top of to series:
       - patchwork.kernel.org/project/linux-mediatek/list/?series=637849
       - patchwork.kernel.org/project/linux-pm/list/?series=639386

 v6:
     - Remove temperature aggregation (it will be added in another
       series)
     - Update the way to read the temperature (read one sensor
       instead of all)
     - Add support of mt8195

  v5:
     - Use 'git mv' for the relocated file.

  v4:
     - Rebase to kernel-v5.13-rc1

  v3:
     - change the expression in the lvts_temp_to_raw to dev_s64.

  v2:
     - Rebase to kernel-5.11-rc1.
     - sort headers
     - remove initial value 0 of msr_raw in the lvts_temp_to_raw.
     - disconstruct the api of lvts_read_tc_msr_raw.
     - add the initial value max_temp = 0 and compare e.q.
       in the lvts_read_all_tc_temperature.
     - add the return with an invalid number in the lvts_init.

Balsam CHIHI (6):
  thermal/drivers/mediatek: Relocate driver to mediatek folder
  dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding
    definition
  arm64/dts/mt8195: Add efuse node to mt8195
  thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver
  arm64/dts/mt8195: Add thermal zones and thermal nodes
  arm64/dts/mt8195: Add temperature mitigation threshold

 .../thermal/mediatek,lvts-thermal.yaml        |  107 ++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      |  272 ++++
 drivers/thermal/Kconfig                       |   14 +-
 drivers/thermal/Makefile                      |    2 +-
 drivers/thermal/mediatek/Kconfig              |   36 +
 drivers/thermal/mediatek/Makefile             |    2 +
 .../auxadc_thermal.c}                         |    2 +-
 drivers/thermal/mediatek/lvts_thermal.c       | 1261 +++++++++++++++++
 include/dt-bindings/thermal/mediatek-lvts.h   |   19 +
 9 files changed, 1703 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
 create mode 100644 drivers/thermal/mediatek/Kconfig
 create mode 100644 drivers/thermal/mediatek/Makefile
 rename drivers/thermal/{mtk_thermal.c => mediatek/auxadc_thermal.c} (99%)
 create mode 100644 drivers/thermal/mediatek/lvts_thermal.c
 create mode 100644 include/dt-bindings/thermal/mediatek-lvts.h


base-commit: 0d568e144ead70189e7f16066dcb155b78ff9266
-- 
2.34.1


^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH v11 1/6] thermal/drivers/mediatek: Relocate driver to mediatek folder
  2023-01-24 13:17 [PATCH v11 0/6] Add LVTS thermal architecture bchihi
@ 2023-01-24 13:17 ` bchihi
  2023-01-24 15:37   ` AngeloGioacchino Del Regno
  2023-01-24 13:17 ` [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition bchihi
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 57+ messages in thread
From: bchihi @ 2023-01-24 13:17 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

Add MediaTek proprietary folder to upstream more thermal zone and cooler
drivers, relocate the original thermal controller driver to it, and rename it
as "auxadc_thermal.c" to show its purpose more clearly.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
---
 drivers/thermal/Kconfig                       | 14 ++++---------
 drivers/thermal/Makefile                      |  2 +-
 drivers/thermal/mediatek/Kconfig              | 21 +++++++++++++++++++
 drivers/thermal/mediatek/Makefile             |  1 +
 .../auxadc_thermal.c}                         |  2 +-
 5 files changed, 28 insertions(+), 12 deletions(-)
 create mode 100644 drivers/thermal/mediatek/Kconfig
 create mode 100644 drivers/thermal/mediatek/Makefile
 rename drivers/thermal/{mtk_thermal.c => mediatek/auxadc_thermal.c} (99%)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index eaeb2b2ee6e9..4cd7ab707315 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -416,16 +416,10 @@ config DA9062_THERMAL
 	  zone.
 	  Compatible with the DA9062 and DA9061 PMICs.
 
-config MTK_THERMAL
-	tristate "Temperature sensor driver for mediatek SoCs"
-	depends on ARCH_MEDIATEK || COMPILE_TEST
-	depends on HAS_IOMEM
-	depends on NVMEM || NVMEM=n
-	depends on RESET_CONTROLLER
-	default y
-	help
-	  Enable this option if you want to have support for thermal management
-	  controller present in Mediatek SoCs
+menu "Mediatek thermal drivers"
+depends on ARCH_MEDIATEK || COMPILE_TEST
+source "drivers/thermal/mediatek/Kconfig"
+endmenu
 
 config AMLOGIC_THERMAL
 	tristate "Amlogic Thermal Support"
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 60f0dfa9aae2..1c460d189bd7 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -56,7 +56,7 @@ obj-y				+= st/
 obj-y				+= qcom/
 obj-y				+= tegra/
 obj-$(CONFIG_HISI_THERMAL)     += hisi_thermal.o
-obj-$(CONFIG_MTK_THERMAL)	+= mtk_thermal.o
+obj-y				+= mediatek/
 obj-$(CONFIG_GENERIC_ADC_THERMAL)	+= thermal-generic-adc.o
 obj-$(CONFIG_UNIPHIER_THERMAL)	+= uniphier_thermal.o
 obj-$(CONFIG_AMLOGIC_THERMAL)     += amlogic_thermal.o
diff --git a/drivers/thermal/mediatek/Kconfig b/drivers/thermal/mediatek/Kconfig
new file mode 100644
index 000000000000..7558a847d4e9
--- /dev/null
+++ b/drivers/thermal/mediatek/Kconfig
@@ -0,0 +1,21 @@
+config MTK_THERMAL
+	tristate "MediaTek thermal drivers"
+	depends on THERMAL_OF
+	help
+	  This is the option for MediaTek thermal software solutions.
+	  Please enable corresponding options to get temperature
+	  information from thermal sensors or turn on throttle
+	  mechaisms for thermal mitigation.
+
+if MTK_THERMAL
+
+config MTK_SOC_THERMAL
+	tristate "AUXADC temperature sensor driver for MediaTek SoCs"
+	depends on HAS_IOMEM
+	help
+	  Enable this option if you want to get SoC temperature
+	  information for MediaTek platforms.
+	  This driver configures thermal controllers to collect
+	  temperature via AUXADC interface.
+
+endif
diff --git a/drivers/thermal/mediatek/Makefile b/drivers/thermal/mediatek/Makefile
new file mode 100644
index 000000000000..53e86e30b26f
--- /dev/null
+++ b/drivers/thermal/mediatek/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MTK_SOC_THERMAL)	+= auxadc_thermal.o
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mediatek/auxadc_thermal.c
similarity index 99%
rename from drivers/thermal/mtk_thermal.c
rename to drivers/thermal/mediatek/auxadc_thermal.c
index 9a8b107900e9..90ae6b5c530e 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mediatek/auxadc_thermal.c
@@ -23,7 +23,7 @@
 #include <linux/reset.h>
 #include <linux/types.h>
 
-#include "thermal_hwmon.h"
+#include "../thermal_hwmon.h"
 
 /* AUXADC Registers */
 #define AUXADC_CON1_SET_V	0x008
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-24 13:17 [PATCH v11 0/6] Add LVTS thermal architecture bchihi
  2023-01-24 13:17 ` [PATCH v11 1/6] thermal/drivers/mediatek: Relocate driver to mediatek folder bchihi
@ 2023-01-24 13:17 ` bchihi
  2023-01-25 11:14   ` Daniel Lezcano
                     ` (2 more replies)
  2023-01-24 13:17 ` [PATCH v11 3/6] arm64/dts/mt8195: Add efuse node to mt8195 bchihi
                   ` (3 subsequent siblings)
  5 siblings, 3 replies; 57+ messages in thread
From: bchihi @ 2023-01-24 13:17 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

Add LVTS thermal controllers dt-binding definition for mt8195.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
---
 .../thermal/mediatek,lvts-thermal.yaml        | 107 ++++++++++++++++++
 include/dt-bindings/thermal/mediatek-lvts.h   |  19 ++++
 2 files changed, 126 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
 create mode 100644 include/dt-bindings/thermal/mediatek-lvts.h

diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
new file mode 100644
index 000000000000..12bfbdd8ff89
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
+
+maintainers:
+  - Balsam CHIHI <bchihi@baylibre.com>
+
+description: |
+  LVTS is a thermal management architecture composed of three subsystems,
+  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
+  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
+  a Digital controller (LVTS_CTRL).
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8195-lvts-ap
+      - mediatek,mt8195-lvts-mcu
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+    description: LVTS reset for clearing temporary data on AP/MCU.
+
+  nvmem-cells:
+    minItems: 1
+    items:
+      - description: Calibration eFuse data 1 for LVTS
+      - description: Calibration eFuse data 2 for LVTS
+
+  nvmem-cell-names:
+    minItems: 1
+    items:
+      - const: lvts-calib-data-1
+      - const: lvts-calib-data-2
+
+  "#thermal-sensor-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+  - nvmem-cells
+  - nvmem-cell-names
+  - "#thermal-sensor-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/reset/mt8195-resets.h>
+    #include <dt-bindings/thermal/mediatek-lvts.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      lvts_mcu: thermal-sensor@11278000 {
+        compatible = "mediatek,mt8195-lvts-mcu";
+        reg = <0 0x11278000 0 0x1000>;
+        interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
+        resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
+        nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
+        nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
+        #thermal-sensor-cells = <1>;
+      };
+    };
+
+    thermal_zones: thermal-zones {
+      cpu0-thermal {
+        polling-delay = <1000>;
+        polling-delay-passive = <250>;
+        thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
+
+        trips {
+          cpu0_alert: trip-alert {
+            temperature = <85000>;
+            hysteresis = <2000>;
+            type = "passive";
+          };
+
+          cpu0_crit: trip-crit {
+            temperature = <100000>;
+            hysteresis = <2000>;
+            type = "critical";
+          };
+        };
+      };
+    };
diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
new file mode 100644
index 000000000000..428a95c18509
--- /dev/null
+++ b/include/dt-bindings/thermal/mediatek-lvts.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Balsam CHIHI <bchihi@baylibre.com>
+ */
+
+#ifndef __MEDIATEK_LVTS_DT_H
+#define __MEDIATEK_LVTS_DT_H
+
+#define MT8195_MCU_BIG_CPU0	0
+#define MT8195_MCU_BIG_CPU1	1
+#define MT8195_MCU_BIG_CPU2	2
+#define MT8195_MCU_BIG_CPU3	3
+#define MT8195_MCU_LITTLE_CPU0	4
+#define MT8195_MCU_LITTLE_CPU1	5
+#define MT8195_MCU_LITTLE_CPU2	6
+#define MT8195_MCU_LITTLE_CPU3	7
+
+#endif /* __MEDIATEK_LVTS_DT_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v11 3/6] arm64/dts/mt8195: Add efuse node to mt8195
  2023-01-24 13:17 [PATCH v11 0/6] Add LVTS thermal architecture bchihi
  2023-01-24 13:17 ` [PATCH v11 1/6] thermal/drivers/mediatek: Relocate driver to mediatek folder bchihi
  2023-01-24 13:17 ` [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition bchihi
@ 2023-01-24 13:17 ` bchihi
  2023-01-25 14:25   ` Matthias Brugger
  2023-01-24 13:17 ` [PATCH v11 4/6] thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver bchihi
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 57+ messages in thread
From: bchihi @ 2023-01-24 13:17 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

Add efuse node.
This will be required by the thermal driver to get the calibration data.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 5d31536f4c48..09df105f4606 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1380,6 +1380,12 @@ pciephy_glb_intr: pciephy-glb-intr@193 {
 			dp_calibration: dp-data@1ac {
 				reg = <0x1ac 0x10>;
 			};
+			lvts_efuse_data1: lvts1-calib@1bc {
+				reg = <0x1bc 0x14>;
+			};
+			lvts_efuse_data2: lvts2-calib@1d0 {
+				reg = <0x1d0 0x38>;
+			};
 		};
 
 		u3phy2: t-phy@11c40000 {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v11 4/6] thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver
  2023-01-24 13:17 [PATCH v11 0/6] Add LVTS thermal architecture bchihi
                   ` (2 preceding siblings ...)
  2023-01-24 13:17 ` [PATCH v11 3/6] arm64/dts/mt8195: Add efuse node to mt8195 bchihi
@ 2023-01-24 13:17 ` bchihi
  2023-01-24 15:31   ` AngeloGioacchino Del Regno
  2023-01-31 15:38   ` [PATCH v12] thermal: drivers: mediatek: " bchihi
  2023-01-24 13:17 ` [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes bchihi
  2023-01-24 13:17 ` [PATCH v11 6/6] arm64/dts/mt8195: Add temperature mitigation threshold bchihi
  5 siblings, 2 replies; 57+ messages in thread
From: bchihi @ 2023-01-24 13:17 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
controllers contained in a thermal domain.

A thermal domains can be the MCU or the AP.

Each thermal domains contain up to seven controllers, each thermal
controller handle up to four thermal sensors.

The LVTS has two Finite State Machines (FSM), one to handle the
functionin temperatures range like hot or cold temperature and another
one to handle monitoring trip point. The FSM notifies via interrupts
when a trip point is crossed.

The interrupt is managed at the thermal controller level, so when an
interrupt occurs, the driver has to find out which sensor triggered
such an interrupt.

The sampling of the thermal can be filtered or immediate. For the
former, the LVTS measures several points and applies a low pass
filter.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
---
 drivers/thermal/mediatek/Kconfig        |   15 +
 drivers/thermal/mediatek/Makefile       |    1 +
 drivers/thermal/mediatek/lvts_thermal.c | 1261 +++++++++++++++++++++++
 3 files changed, 1277 insertions(+)
 create mode 100644 drivers/thermal/mediatek/lvts_thermal.c

diff --git a/drivers/thermal/mediatek/Kconfig b/drivers/thermal/mediatek/Kconfig
index 7558a847d4e9..99597d7b9890 100644
--- a/drivers/thermal/mediatek/Kconfig
+++ b/drivers/thermal/mediatek/Kconfig
@@ -18,4 +18,19 @@ config MTK_SOC_THERMAL
 	  This driver configures thermal controllers to collect
 	  temperature via AUXADC interface.
 
+config MTK_LVTS_THERMAL
+        tristate "LVTS Thermal Driver for MediaTek SoCs"
+        depends on HAS_IOMEM
+        help
+          Enable this option if you want to get SoC temperature
+          information for supported MediaTek platforms.
+          This driver configures LVTS (Low Voltage Thermal Sensor)
+          thermal controllers to collect temperatures via ASIF
+          (Analog Serial Interface).
+
+config MTK_LVTS_THERMAL_DEBUGFS
+       bool "LVTS thermal debugfs"
+       depends on MTK_LVTS_THERMAL && DEBUG_FS
+       help
+         Enable this option to debug the internals of the device driver.
 endif
diff --git a/drivers/thermal/mediatek/Makefile b/drivers/thermal/mediatek/Makefile
index 53e86e30b26f..1c6daa1e644b 100644
--- a/drivers/thermal/mediatek/Makefile
+++ b/drivers/thermal/mediatek/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_MTK_SOC_THERMAL)	+= auxadc_thermal.o
+obj-$(CONFIG_MTK_LVTS_THERMAL)	+= lvts_thermal.o
diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
new file mode 100644
index 000000000000..1e51af728aff
--- /dev/null
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -0,0 +1,1261 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Balsam CHIHI <bchihi@baylibre.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/thermal.h>
+#include <dt-bindings/thermal/mediatek-lvts.h>
+
+#define LVTS_MONCTL0(__base)	(__base + 0x0000)
+#define LVTS_MONCTL1(__base)	(__base + 0x0004)
+#define LVTS_MONCTL2(__base)	(__base + 0x0008)
+#define LVTS_MONINT(__base)		(__base + 0x000C)
+#define LVTS_MONINTSTS(__base)	(__base + 0x0010)
+#define LVTS_MONIDET0(__base)	(__base + 0x0014)
+#define LVTS_MONIDET1(__base)	(__base + 0x0018)
+#define LVTS_MONIDET2(__base)	(__base + 0x001C)
+#define LVTS_MONIDET3(__base)	(__base + 0x0020)
+#define LVTS_H2NTHRE(__base)	(__base + 0x0024)
+#define LVTS_HTHRE(__base)		(__base + 0x0028)
+#define LVTS_OFFSETH(__base)	(__base + 0x0030)
+#define LVTS_OFFSETL(__base)	(__base + 0x0034)
+#define LVTS_MSRCTL0(__base)	(__base + 0x0038)
+#define LVTS_MSRCTL1(__base)	(__base + 0x003C)
+#define LVTS_TSSEL(__base)		(__base + 0x0040)
+#define LVTS_CALSCALE(__base)	(__base + 0x0048)
+#define LVTS_ID(__base)			(__base + 0x004C)
+#define LVTS_CONFIG(__base)		(__base + 0x0050)
+#define LVTS_EDATA00(__base)	(__base + 0x0054)
+#define LVTS_EDATA01(__base)	(__base + 0x0058)
+#define LVTS_EDATA02(__base)	(__base + 0x005C)
+#define LVTS_EDATA03(__base)	(__base + 0x0060)
+#define LVTS_MSR0(__base)		(__base + 0x0090)
+#define LVTS_MSR1(__base)		(__base + 0x0094)
+#define LVTS_MSR2(__base)		(__base + 0x0098)
+#define LVTS_MSR3(__base)		(__base + 0x009C)
+#define LVTS_IMMD0(__base)		(__base + 0x00A0)
+#define LVTS_IMMD1(__base)		(__base + 0x00A4)
+#define LVTS_IMMD2(__base)		(__base + 0x00A8)
+#define LVTS_IMMD3(__base)		(__base + 0x00AC)
+#define LVTS_PROTCTL(__base)	(__base + 0x00C0)
+#define LVTS_PROTTA(__base)		(__base + 0x00C4)
+#define LVTS_PROTTB(__base)		(__base + 0x00C8)
+#define LVTS_PROTTC(__base)		(__base + 0x00CC)
+#define LVTS_CLKEN(__base)		(__base + 0x00E4)
+
+#define LVTS_PERIOD_UNIT			((118 * 1000) / (256 * 38))
+#define LVTS_GROUP_INTERVAL			1
+#define LVTS_FILTER_INTERVAL		1
+#define LVTS_SENSOR_INTERVAL		1
+#define LVTS_HW_FILTER				0x2
+#define LVTS_TSSEL_CONF				0x13121110
+#define LVTS_CALSCALE_CONF			0x300
+#define LVTS_MONINT_CONF			0x9FBF7BDE
+
+#define LVTS_INT_SENSOR0			0x0009001F
+#define LVTS_INT_SENSOR1			0X000881F0
+#define LVTS_INT_SENSOR2			0x00247C00
+#define LVTS_INT_SENSOR3			0x1FC00000
+
+#define LVTS_SENSOR_MAX				4
+#define LVTS_GOLDEN_TEMP_MAX		62
+#define LVTS_GOLDEN_TEMP_DEFAULT	50
+#define LVTS_COEFF_A				-250460
+#define LVTS_COEFF_B				250460
+
+#define LVTS_MSR_IMMEDIATE_MODE		0
+#define LVTS_MSR_FILTERED_MODE		1
+
+#define LVTS_HW_SHUTDOWN_MT8195		105000
+
+static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
+static int coeff_b = LVTS_COEFF_B;
+
+struct lvts_sensor_data {
+	int dt_id;
+};
+
+struct lvts_ctrl_data {
+	struct lvts_sensor_data lvts_sensor[LVTS_SENSOR_MAX];
+	int cal_offset[LVTS_SENSOR_MAX];
+	int hw_tshut_temp;
+	int num_lvts_sensor;
+	int offset;
+	int mode;
+};
+
+struct lvts_data {
+	struct lvts_ctrl_data *lvts_ctrl;
+	int num_lvts_ctrl;
+};
+
+struct lvts_sensor {
+	struct thermal_zone_device *tz;
+	void __iomem *msr;
+	void __iomem *base;
+	int id;
+	int dt_id;
+};
+
+struct lvts_ctrl {
+	struct lvts_sensor sensors[LVTS_SENSOR_MAX];
+	u32 calibration[LVTS_SENSOR_MAX];
+	u32 hw_tshut_raw_temp;
+	int num_lvts_sensor;
+	int mode;
+	void __iomem *base;
+};
+
+struct lvts_domain {
+	struct lvts_ctrl *lvts_ctrl;
+	struct reset_control *reset;
+	struct clk *clk;
+	int num_lvts_ctrl;
+	void __iomem *base;
+	size_t calib_len;
+	u8 *calib;
+};
+
+#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
+
+static struct dentry *root;
+
+#define LVTS_DEBUG_FS_REGS(__reg)		\
+{						\
+	.name = __stringify(__reg),		\
+	.offset = __reg(0),			\
+}
+
+static const struct debugfs_reg32 lvts_regs[] = {
+	LVTS_DEBUG_FS_REGS(LVTS_MONCTL0),
+	LVTS_DEBUG_FS_REGS(LVTS_MONCTL1),
+	LVTS_DEBUG_FS_REGS(LVTS_MONCTL2),
+	LVTS_DEBUG_FS_REGS(LVTS_MONINT),
+	LVTS_DEBUG_FS_REGS(LVTS_MONINTSTS),
+	LVTS_DEBUG_FS_REGS(LVTS_MONIDET0),
+	LVTS_DEBUG_FS_REGS(LVTS_MONIDET1),
+	LVTS_DEBUG_FS_REGS(LVTS_MONIDET2),
+	LVTS_DEBUG_FS_REGS(LVTS_MONIDET3),
+	LVTS_DEBUG_FS_REGS(LVTS_H2NTHRE),
+	LVTS_DEBUG_FS_REGS(LVTS_HTHRE),
+	LVTS_DEBUG_FS_REGS(LVTS_OFFSETH),
+	LVTS_DEBUG_FS_REGS(LVTS_OFFSETL),
+	LVTS_DEBUG_FS_REGS(LVTS_MSRCTL0),
+	LVTS_DEBUG_FS_REGS(LVTS_MSRCTL1),
+	LVTS_DEBUG_FS_REGS(LVTS_TSSEL),
+	LVTS_DEBUG_FS_REGS(LVTS_CALSCALE),
+	LVTS_DEBUG_FS_REGS(LVTS_ID),
+	LVTS_DEBUG_FS_REGS(LVTS_CONFIG),
+	LVTS_DEBUG_FS_REGS(LVTS_EDATA00),
+	LVTS_DEBUG_FS_REGS(LVTS_EDATA01),
+	LVTS_DEBUG_FS_REGS(LVTS_EDATA02),
+	LVTS_DEBUG_FS_REGS(LVTS_EDATA03),
+	LVTS_DEBUG_FS_REGS(LVTS_MSR0),
+	LVTS_DEBUG_FS_REGS(LVTS_MSR1),
+	LVTS_DEBUG_FS_REGS(LVTS_MSR2),
+	LVTS_DEBUG_FS_REGS(LVTS_MSR3),
+	LVTS_DEBUG_FS_REGS(LVTS_IMMD0),
+	LVTS_DEBUG_FS_REGS(LVTS_IMMD1),
+	LVTS_DEBUG_FS_REGS(LVTS_IMMD2),
+	LVTS_DEBUG_FS_REGS(LVTS_IMMD3),
+	LVTS_DEBUG_FS_REGS(LVTS_PROTCTL),
+	LVTS_DEBUG_FS_REGS(LVTS_PROTTA),
+	LVTS_DEBUG_FS_REGS(LVTS_PROTTB),
+	LVTS_DEBUG_FS_REGS(LVTS_PROTTC),
+	LVTS_DEBUG_FS_REGS(LVTS_CLKEN),
+};
+
+static int lvts_debugfs_init(struct device *dev,
+			     struct lvts_domain *lvts_td)
+{
+	struct debugfs_regset32 *regset;
+	struct lvts_ctrl *lvts_ctrl;
+	struct dentry *dentry;
+	struct dentry *dom_dentry;
+	char name[64];
+	int i;
+
+	if (!root)
+		root = debugfs_create_dir("lvts", NULL);
+
+	dom_dentry = debugfs_create_dir(dev_name(dev), root);
+	if (!dom_dentry)
+		return 0;
+
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+
+		lvts_ctrl = &lvts_td->lvts_ctrl[i];
+
+		sprintf(name, "controller%d", i);
+		dentry = debugfs_create_dir(name, dom_dentry);
+		if (!dentry)
+			continue;
+
+		regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
+		if (!regset)
+			continue;
+
+		regset->base = lvts_ctrl->base;
+		regset->regs = lvts_regs;
+		regset->nregs = ARRAY_SIZE(lvts_regs);
+
+		debugfs_create_regset32("registers", 0400, dentry, regset);
+	}
+
+	return 0;
+}
+
+static void lvts_debugfs_exit(void)
+{
+	debugfs_remove_recursive(root);
+}
+
+#else
+
+static inline int lvts_debugfs_init(struct device *dev,
+				    struct lvts_domain *lvts_td)
+{
+	return 0;
+}
+
+static void lvts_debugfs_exit(void) { }
+
+#endif
+
+static int lvts_raw_to_temp(u32 raw_temp)
+{
+	int temperature;
+
+	temperature = ((s64)(raw_temp & 0xFFFF) * LVTS_COEFF_A) >> 14;
+	temperature += coeff_b;
+
+	return temperature;
+}
+
+static u32 lvts_temp_to_raw(int temperature)
+{
+	u32 raw_temp = ((s64)(coeff_b - temperature)) << 14;
+
+	raw_temp = div_s64(raw_temp, -LVTS_COEFF_A);
+
+	return raw_temp;
+}
+
+static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+	struct lvts_sensor *lvts_sensor = tz->devdata;
+	void __iomem *msr = lvts_sensor->msr;
+	u32 value;
+
+	/*
+	 * Measurement registers:
+	 *
+	 * LVTS_MSR[0-3] / LVTS_IMMD[0-3]
+	 *
+	 * Bits:
+	 *
+	 * 32-17: Unused
+	 * 16	: Valid temperature
+	 * 15-0	: Raw temperature
+	 */
+	value = readl(msr);
+
+	/*
+	 * As the thermal zone temperature will read before the
+	 * hardware sensor is fully initialized, we have to check the
+	 * validity of the temperature returned when reading the
+	 * measurement register. The thermal controller will set the
+	 * valid bit temperature only when it is totally initialized.
+	 *
+	 * Otherwise, we may end up with garbage values out of the
+	 * functionning temperature and directly jump to a system
+	 * shutdown.
+	 */
+	if (!(value & BIT(16)))
+		return -EAGAIN;
+
+	*temp = lvts_raw_to_temp(value & 0xFFFF);
+
+	return 0;
+}
+
+static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+{
+	struct lvts_sensor *lvts_sensor = tz->devdata;
+	void __iomem *base = lvts_sensor->base;
+	u32 raw_low = lvts_temp_to_raw(low);
+	u32 raw_high = lvts_temp_to_raw(high);
+
+	/*
+	 * Hot to normal temperature threshold
+	 *
+	 * LVTS_H2NTHRE
+	 *
+	 * Bits:
+	 *
+	 * 14-0 : Raw temperature for threshold
+	 */
+	if (low != -INT_MAX) {
+		dev_dbg(&tz->device, "Setting low limit temperature interrupt: %d\n", low);
+		writel(raw_low, LVTS_H2NTHRE(base));
+	}
+
+	/*
+	 * Hot temperature threshold
+	 *
+	 * LVTS_HTHRE
+	 *
+	 * Bits:
+	 *
+	 * 14-0 : Raw temperature for threshold
+	 */
+	dev_dbg(&tz->device, "Setting high limit temperature interrupt: %d\n", high);
+	writel(raw_high, LVTS_HTHRE(base));
+
+	return 0;
+}
+
+static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
+{
+	irqreturn_t iret = IRQ_NONE;
+	u32 value, masks[] = {
+		LVTS_INT_SENSOR0,
+		LVTS_INT_SENSOR1,
+		LVTS_INT_SENSOR2,
+		LVTS_INT_SENSOR3
+	};
+	int i;
+
+	/*
+	 * Interrupt monitoring status
+	 *
+	 * LVTS_MONINTST
+	 *
+	 * Bits:
+	 *
+	 * 31 : Interrupt for stage 3
+	 * 30 : Interrupt for stage 2
+	 * 29 : Interrupt for state 1
+	 * 28 : Interrupt using filter on sensor 3
+	 *
+	 * 27 : Interrupt using immediate on sensor 3
+	 * 26 : Interrupt normal to hot on sensor 3
+	 * 25 : Interrupt high offset on sensor 3
+	 * 24 : Interrupt low offset on sensor 3
+	 *
+	 * 23 : Interrupt hot threshold on sensor 3
+	 * 22 : Interrupt cold threshold on sensor 3
+	 * 21 : Interrupt using filter on sensor 2
+	 * 20 : Interrupt using filter on sensor 1
+	 *
+	 * 19 : Interrupt using filter on sensor 0
+	 * 18 : Interrupt using immediate on sensor 2
+	 * 17 : Interrupt using immediate on sensor 1
+	 * 16 : Interrupt using immediate on sensor 0
+	 *
+	 * 15 : Interrupt device access timeout interrupt
+	 * 14 : Interrupt normal to hot on sensor 2
+	 * 13 : Interrupt high offset interrupt on sensor 2
+	 * 12 : Interrupt low offset interrupt on sensor 2
+	 *
+	 * 11 : Interrupt hot threshold on sensor 2
+	 * 10 : Interrupt cold threshold on sensor 2
+	 *  9 : Interrupt normal to hot on sensor 1
+	 *  8 : Interrupt high offset interrupt on sensor 1
+	 *
+	 *  7 : Interrupt low offset interrupt on sensor 1
+	 *  6 : Interrupt hot threshold on sensor 1
+	 *  5 : Interrupt cold threshold on sensor 1
+	 *  4 : Interrupt normal to hot on sensor 0
+	 *
+	 *  3 : Interrupt high offset interrupt on sensor 0
+	 *  2 : Interrupt low offset interrupt on sensor 0
+	 *  1 : Interrupt hot threshold on sensor 0
+	 *  0 : Interrupt cold threshold on sensor 0
+	 *
+	 * We are interested in the sensor(s) responsible of the
+	 * interrupt event. We update the thermal framework with the
+	 * thermal zone associated with the sensor. The framework will
+	 * take care of the rest whatever the kind of interrupt, we
+	 * are only interested in which sensor raised the interrupt.
+	 *
+	 * sensor 3 interrupt: 0001 1111 1100 0000 0000 0000 0000 0000
+	 *                  => 0x1FC00000
+	 * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000
+	 *                  => 0x00247C00
+	 * sensor 1 interrupt: 0000 0000 0001 0001 0000 0011 1110 0000
+	 *                  => 0X000881F0
+	 * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111
+	 *                  => 0x0009001F
+	 */
+	value = readl(LVTS_MONINTSTS(lvts_ctrl->base));
+
+	/*
+	 * Let's figure out which sensors raised the interrupt
+	 *
+	 * NOTE: the masks array must be ordered with the index
+	 * corresponding to the sensor id eg. index=0, mask for
+	 * sensor0.
+	 */
+	for (i = 0; i < ARRAY_SIZE(masks); i++) {
+
+		if (!(value & masks[i]))
+			continue;
+
+		thermal_zone_device_update(lvts_ctrl->sensors[i].tz,
+					   THERMAL_TRIP_VIOLATED);
+		iret = IRQ_HANDLED;
+	}
+
+	/*
+	 * Write back to clear the interrupt status (W1C)
+	 */
+	writel(value, LVTS_MONINTSTS(lvts_ctrl->base));
+
+	return iret;
+}
+
+/*
+ * Temperature interrupt handler. Even if the driver supports more
+ * interrupt modes, we use the interrupt when the temperature crosses
+ * the hot threshold the way up and the way down (modulo the
+ * hysteresis).
+ *
+ * Each thermal domain has a couple of interrupts, one for hardware
+ * reset and another one for all the thermal events happening on the
+ * different sensors.
+ *
+ * The interrupt is configured for thermal events when crossing the
+ * hot temperature limit. At each interrupt, we check in every
+ * controller if there is an interrupt pending.
+ */
+static irqreturn_t lvts_irq_handler(int irq, void *data)
+{
+	struct lvts_domain *lvts_td = data;
+	irqreturn_t aux, iret = IRQ_NONE;
+	int i;
+
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+
+		aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl);
+		if (aux != IRQ_HANDLED)
+			continue;
+
+		iret = IRQ_HANDLED;
+	}
+
+	return iret;
+}
+
+static struct thermal_zone_device_ops lvts_ops = {
+	.get_temp = lvts_get_temp,
+	.set_trips = lvts_set_trips,
+};
+
+static int __init lvts_sensor_init(struct device *dev,
+				   struct lvts_ctrl *lvts_ctrl,
+				   struct lvts_ctrl_data *lvts_ctrl_data)
+{
+	struct lvts_sensor *lvts_sensor = lvts_ctrl->sensors;
+	void __iomem *msr_regs[] = {
+		LVTS_MSR0(lvts_ctrl->base),
+		LVTS_MSR1(lvts_ctrl->base),
+		LVTS_MSR2(lvts_ctrl->base),
+		LVTS_MSR3(lvts_ctrl->base)
+	};
+
+	void __iomem *imm_regs[] = {
+		LVTS_IMMD0(lvts_ctrl->base),
+		LVTS_IMMD1(lvts_ctrl->base),
+		LVTS_IMMD2(lvts_ctrl->base),
+		LVTS_IMMD3(lvts_ctrl->base)
+	};
+
+	int i;
+
+	for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++) {
+
+		int dt_id = lvts_ctrl_data->lvts_sensor[i].dt_id;
+
+		/*
+		 * At this point, we don't know which id matches which
+		 * sensor. Let's set arbitrally the id from the index.
+		 */
+		lvts_sensor[i].id = i;
+
+		/*
+		 * The thermal zone registration will set the trip
+		 * point interrupt in the thermal controller
+		 * register. But this one will be reset in the
+		 * initialization after. So we need to post pone the
+		 * thermal zone creation after the controller is
+		 * setup. For this reason, we store the device tree
+		 * node id from the data in the sensor structure
+		 */
+		lvts_sensor[i].dt_id = dt_id;
+
+		/*
+		 * We assign the base address of the thermal
+		 * controller as a back pointer. So it will be
+		 * accessible from the different thermal framework ops
+		 * as we pass the lvts_sensor pointer as thermal zone
+		 * private data.
+		 */
+		lvts_sensor[i].base = lvts_ctrl->base;
+
+		/*
+		 * Each sensor has its own register address to read from.
+		 */
+		lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
+			imm_regs[i] : msr_regs[i];
+	};
+
+	lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
+
+	return 0;
+}
+
+/*
+ * The efuse blob values follows the sensor enumeration per thermal
+ * controller. The decoding of the stream is as follow:
+ *
+ *                        <--?-> <----big0 ???---> <-sensor0-> <-0->
+ *                        ------------------------------------------
+ * index in the stream: : | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 |
+ *                        ------------------------------------------
+ *
+ *                        <--sensor1--><-0-> <----big1 ???---> <-sen
+ *                        ------------------------------------------
+ *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
+ *                        ------------------------------------------
+ *
+ *                        sor0-> <-0-> <-sensor1-> <-0-> ..........
+ *                        ------------------------------------------
+ *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
+ *                        ------------------------------------------
+ *
+ * And so on ...
+ *
+ * The data description gives the offset of the calibration data in
+ * this bytes stream for each sensor.
+ *
+ * Each thermal controller can handle up to 4 sensors max, we don't
+ * care if there are less as the array of calibration is sized to 4
+ * anyway. The unused sensor slot will be zeroed.
+ */
+static int __init lvts_calibration_init(struct device *dev,
+					struct lvts_ctrl *lvts_ctrl,
+					struct lvts_ctrl_data *lvts_ctrl_data,
+					u8 *efuse_calibration)
+{
+	int i;
+
+	for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++)
+		memcpy(&lvts_ctrl->calibration[i],
+		       efuse_calibration + lvts_ctrl_data->cal_offset[i], 2);
+
+	return 0;
+}
+
+/*
+ * The efuse bytes stream can be split into different chunk of
+ * nvmems. This function reads and concatenate those into a single
+ * buffer so it can be read sequentially when initializing the
+ * calibration data.
+ */
+static int lvts_calibration_read(struct device *dev, struct lvts_domain *lvts_td,
+				 struct lvts_data *lvts_data)
+{
+	struct device_node *np = dev_of_node(dev);
+	struct nvmem_cell *cell;
+	struct property *prop;
+	const char *cell_name;
+
+	of_property_for_each_string(np, "nvmem-cell-names", prop, cell_name) {
+		size_t len;
+		u8 *efuse;
+
+		cell = of_nvmem_cell_get(np, cell_name);
+		if (IS_ERR(cell)) {
+			dev_dbg(dev, "Failed to get cell '%s'\n", cell_name);
+			return PTR_ERR(cell);
+		}
+
+		efuse = nvmem_cell_read(cell, &len);
+
+		nvmem_cell_put(cell);
+
+		if (IS_ERR(efuse)) {
+			dev_dbg(dev, "Failed to read cell '%s'\n", cell_name);
+			return PTR_ERR(efuse);
+		}
+
+		lvts_td->calib = devm_krealloc(dev, lvts_td->calib,
+					       lvts_td->calib_len + len, GFP_KERNEL);
+		if (!lvts_td->calib)
+			return -ENOMEM;
+
+		memcpy(lvts_td->calib + lvts_td->calib_len, efuse, len);
+
+		lvts_td->calib_len += len;
+
+		kfree(efuse);
+	}
+
+	return 0;
+}
+
+static int __init lvts_golden_temp_init(struct device *dev, u32 *value)
+{
+	u32 gt;
+
+	gt = (*value) >> 24;
+
+	if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
+		golden_temp = gt;
+
+	coeff_b = golden_temp * 500 + LVTS_COEFF_B;
+
+	return 0;
+}
+
+static int __init lvts_ctrl_init(struct device *dev,
+				 struct lvts_domain *lvts_td,
+				 struct lvts_data *lvts_data)
+{
+	size_t size = sizeof(*lvts_td->lvts_ctrl) * lvts_data->num_lvts_ctrl;
+	struct lvts_ctrl *lvts_ctrl;
+	int i, ret;
+
+	/*
+	 * Create the calibration bytes stream from efuse data
+	 */
+	ret = lvts_calibration_read(dev, lvts_td, lvts_data);
+	if (ret)
+		return ret;
+
+	/*
+	 * The golden temp information is contained in the first chunk
+	 * of efuse data.
+	 */
+	ret = lvts_golden_temp_init(dev, (u32 *)lvts_td->calib);
+	if (ret)
+		return ret;
+
+	lvts_ctrl = devm_kzalloc(dev, size, GFP_KERNEL);
+	if (!lvts_ctrl)
+		return -ENOMEM;
+
+	for (i = 0; i < lvts_data->num_lvts_ctrl; i++) {
+
+		lvts_ctrl[i].base = lvts_td->base + lvts_data->lvts_ctrl[i].offset;
+
+		ret = lvts_sensor_init(dev, &lvts_ctrl[i],
+				       &lvts_data->lvts_ctrl[i]);
+		if (ret)
+			return ret;
+
+		ret = lvts_calibration_init(dev, &lvts_ctrl[i],
+					    &lvts_data->lvts_ctrl[i],
+					    lvts_td->calib);
+		if (ret)
+			return ret;
+
+		/*
+		 * The mode the ctrl will use to read the temperature
+		 * (filtered or immediate)
+		 */
+		lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode;
+
+		/*
+		 * The temperature to raw temperature must be done
+		 * after initializing the calibration.
+		 */
+		lvts_ctrl[i].hw_tshut_raw_temp =
+			lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
+	}
+
+	/*
+	 * We no longer need the efuse bytes stream, let's free it
+	 */
+	devm_kfree(dev, lvts_td->calib);
+
+	lvts_td->lvts_ctrl = lvts_ctrl;
+	lvts_td->num_lvts_ctrl = lvts_data->num_lvts_ctrl;
+
+	return 0;
+}
+
+/*
+ * At this point the configuration register is the only place in the
+ * driver where we write multiple values. Per hardware constraint,
+ * each write in the configuration register must be separated by a
+ * delay of 2 us.
+ */
+static void lvts_write_config(struct lvts_ctrl *lvts_ctrl, u32 *cmds, int nr_cmds)
+{
+	int i;
+
+	/*
+	 * Configuration register
+	 */
+	for (i = 0; i < nr_cmds; i++) {
+		writel(cmds[i], LVTS_CONFIG(lvts_ctrl->base));
+		usleep_range(2, 4);
+	}
+}
+
+static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
+{
+	/*
+	 * LVTS_PROTCTL : Thermal Protection Sensor Selection
+	 *
+	 * Bits:
+	 *
+	 * 19-18 : Sensor to base the protection on
+	 * 17-16 : Strategy:
+	 *         00 : Average of 4 sensors
+	 *         01 : Max of 4 sensors
+	 *         10 : Selected sensor with bits 19-18
+	 *         11 : Reserved
+	 */
+	writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));
+
+	/*
+	 * LVTS_PROTTA : Stage 1 temperature threshold
+	 * LVTS_PROTTB : Stage 2 temperature threshold
+	 * LVTS_PROTTC : Stage 3 temperature threshold
+	 *
+	 * Bits:
+	 *
+	 * 14-0: Raw temperature threshold
+	 *
+	 * writel(0x0, LVTS_PROTTA(lvts_ctrl->base));
+	 * writel(0x0, LVTS_PROTTB(lvts_ctrl->base));
+	 */
+	writel(lvts_ctrl->hw_tshut_raw_temp, LVTS_PROTTC(lvts_ctrl->base));
+
+	/*
+	 * LVTS_MONINT : Interrupt configuration register
+	 *
+	 * The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS
+	 * register, except we set the bits to enable the interrupt.
+	 */
+	writel(LVTS_MONINT_CONF, LVTS_MONINT(lvts_ctrl->base));
+
+	return 0;
+}
+
+static int lvts_domain_reset(struct device *dev, struct reset_control *reset)
+{
+	int ret;
+
+	ret = reset_control_assert(reset);
+	if (ret)
+		return ret;
+
+	return reset_control_deassert(reset);
+}
+
+/*
+ * Enable or disable the clocks of a specified thermal controller
+ */
+static int lvts_ctrl_set_enable(struct lvts_ctrl *lvts_ctrl, int enable)
+{
+	/*
+	 * LVTS_CLKEN : Internal LVTS clock
+	 *
+	 * Bits:
+	 *
+	 * 0 : enable / disable clock
+	 */
+	writel(enable, LVTS_CLKEN(lvts_ctrl->base));
+
+	return 0;
+}
+
+static inline int lvts_ctrl_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	return lvts_ctrl_set_enable(lvts_ctrl, 1);
+}
+
+static inline int lvts_ctrl_disable(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	return lvts_ctrl_set_enable(lvts_ctrl, 0);
+}
+
+static int lvts_ctrl_connect(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	u32 id, cmds[] = { 0xC103FFFF, 0xC502FF55 };
+
+	lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
+
+	/*
+	 * LVTS_ID : Get ID and status of the thermal controller
+	 *
+	 * Bits:
+	 *
+	 * 0-5	: thermal controller id
+	 *   7	: thermal controller connection is valid
+	 */
+	id = readl(LVTS_ID(lvts_ctrl->base));
+	if (!(id & BIT(7)))
+		return -EIO;
+
+	return 0;
+}
+
+static int lvts_ctrl_initialize(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	/*
+	 * Write device mask: 0xC1030000
+	 */
+	u32 cmds[] = {
+		0xC1030E01, 0xC1030CFC, 0xC1030A8C, 0xC103098D, 0xC10308F1,
+		0xC10307A6, 0xC10306B8, 0xC1030500, 0xC1030420, 0xC1030300,
+		0xC1030030, 0xC10300F6, 0xC1030050, 0xC1030060, 0xC10300AC,
+		0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
+	};
+
+	lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
+
+	return 0;
+}
+
+static int lvts_ctrl_calibrate(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	int i;
+	void __iomem *lvts_edata[] = {
+		LVTS_EDATA00(lvts_ctrl->base),
+		LVTS_EDATA01(lvts_ctrl->base),
+		LVTS_EDATA02(lvts_ctrl->base),
+		LVTS_EDATA03(lvts_ctrl->base)
+	};
+
+	/*
+	 * LVTS_EDATA0X : Efuse calibration reference value for sensor X
+	 *
+	 * Bits:
+	 *
+	 * 20-0 : Efuse value for normalization data
+	 */
+	for (i = 0; i < LVTS_SENSOR_MAX; i++)
+		writel(lvts_ctrl->calibration[i], lvts_edata[i]);
+
+	return 0;
+}
+
+static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	u32 value;
+
+	/*
+	 * LVTS_TSSEL : Sensing point index numbering
+	 *
+	 * Bits:
+	 *
+	 * 31-24: ADC Sense 3
+	 * 23-16: ADC Sense 2
+	 * 15-8	: ADC Sense 1
+	 * 7-0	: ADC Sense 0
+	 */
+	value = LVTS_TSSEL_CONF;
+	writel(value, LVTS_TSSEL(lvts_ctrl->base));
+
+	/*
+	 * LVTS_CALSCALE : ADC voltage round
+	 */
+	value = 0x300;
+	value = LVTS_CALSCALE_CONF;
+
+	/*
+	 * LVTS_MSRCTL0 : Sensor filtering strategy
+	 *
+	 * Filters:
+	 *
+	 * 000 : One sample
+	 * 001 : Avg 2 samples
+	 * 010 : 4 samples, drop min and max, avg 2 samples
+	 * 011 : 6 samples, drop min and max, avg 4 samples
+	 * 100 : 10 samples, drop min and max, avg 8 samples
+	 * 101 : 18 samples, drop min and max, avg 16 samples
+	 *
+	 * Bits:
+	 *
+	 * 0-2  : Sensor0 filter
+	 * 3-5  : Sensor1 filter
+	 * 6-8  : Sensor2 filter
+	 * 9-11 : Sensor3 filter
+	 */
+	value = LVTS_HW_FILTER << 9 |  LVTS_HW_FILTER << 6 |
+			LVTS_HW_FILTER << 3 | LVTS_HW_FILTER;
+	writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
+
+	/*
+	 * LVTS_MSRCTL1 : Measurement control
+	 *
+	 * Bits:
+	 *
+	 * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
+	 * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
+	 * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
+	 * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
+	 *
+	 * That configuration will ignore the filtering and the delays
+	 * introduced below in MONCTL1 and MONCTL2
+	 */
+	if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
+		value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
+		writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
+	}
+
+	/*
+	 * LVTS_MONCTL1 : Period unit and group interval configuration
+	 *
+	 * The clock source of LVTS thermal controller is 26MHz.
+	 *
+	 * The period unit is a time base for all the interval delays
+	 * specified in the registers. By default we use 12. The time
+	 * conversion is done by multiplying by 256 and 1/26.10^6
+	 *
+	 * An interval delay multiplied by the period unit gives the
+	 * duration in seconds.
+	 *
+	 * - Filter interval delay is a delay between two samples of
+	 * the same sensor.
+	 *
+	 * - Sensor interval delay is a delay between two samples of
+	 * different sensors.
+	 *
+	 * - Group interval delay is a delay between different rounds.
+	 *
+	 * For example:
+	 *     If Period unit = C, filter delay = 1, sensor delay = 2, group delay = 1,
+	 *     and two sensors, TS1 and TS2, are in a LVTS thermal controller
+	 *     and then
+	 *     Period unit time = C * 1/26M * 256 = 12 * 38.46ns * 256 = 118.149us
+	 *     Filter interval delay = 1 * Period unit = 118.149us
+	 *     Sensor interval delay = 2 * Period unit = 236.298us
+	 *     Group interval delay = 1 * Period unit = 118.149us
+	 *
+	 *     TS1    TS1 ... TS1    TS2    TS2 ... TS2    TS1...
+	 *        <--> Filter interval delay
+	 *                       <--> Sensor interval delay
+	 *                                             <--> Group interval delay
+	 * Bits:
+	 *      29 - 20 : Group interval
+	 *      16 - 13 : Send a single interrupt when crossing the hot threshold (1)
+	 *                or an interrupt everytime the hot threshold is crossed (0)
+	 *       9 - 0  : Period unit
+	 *
+	 */
+	value = LVTS_GROUP_INTERVAL << 20 | LVTS_PERIOD_UNIT;
+	writel(value, LVTS_MONCTL1(lvts_ctrl->base));
+
+	/*
+	 * LVTS_MONCTL2 : Filtering and sensor interval
+	 *
+	 * Bits:
+	 *
+	 *      25-16 : Interval unit in PERIOD_UNIT between sample on
+	 *              the same sensor, filter interval
+	 *       9-0  : Interval unit in PERIOD_UNIT between each sensor
+	 *
+	 */
+	value = LVTS_FILTER_INTERVAL << 16 | LVTS_SENSOR_INTERVAL;
+	writel(value, LVTS_MONCTL2(lvts_ctrl->base));
+
+	return lvts_irq_init(lvts_ctrl);
+}
+
+static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	struct lvts_sensor *lvts_sensors = lvts_ctrl->sensors;
+	struct thermal_zone_device *tz;
+	u32 sensor_map = 0;
+	int i;
+
+	for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
+
+		int dt_id = lvts_sensors[i].dt_id;
+
+		tz = devm_thermal_of_zone_register(dev, dt_id, &lvts_sensors[i],
+						   &lvts_ops);
+		if (IS_ERR(tz)) {
+			/*
+			 * This thermal zone is not described in the
+			 * device tree. It is not an error from the
+			 * thermal OF code POV, we just continue.
+			 */
+			if (PTR_ERR(tz) == -ENODEV)
+				continue;
+
+			return PTR_ERR(tz);
+		}
+
+		/*
+		 * The thermal zone pointer will be needed in the
+		 * interrupt handler, we store it in the sensor
+		 * structure. The thermal domain structure will be
+		 * passed to the interrupt handler private data as the
+		 * interrupt is shared for all the controller
+		 * belonging to the thermal domain.
+		 */
+		lvts_sensors[i].tz = tz;
+
+		/*
+		 * This sensor was correctly associated with a thermal
+		 * zone, let's set the corresponding bit in the sensor
+		 * map, so we can enable the temperature monitoring in
+		 * the hardware thermal controller.
+		 */
+		sensor_map |= BIT(i);
+	}
+
+	/*
+	 * Bits:
+	 *      9: Single point access flow
+	 *    0-3: Enable sensing point 0-3
+	 *
+	 * The initialization of the thermal zones give us
+	 * which sensor point to enable. If any thermal zone
+	 * was not described in the device tree, it won't be
+	 * enabled here in the sensor map.
+	 */
+	writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
+
+	return 0;
+}
+
+static int lvts_domain_init(struct device *dev, struct lvts_domain *lvts_td,
+			    struct lvts_data *lvts_data)
+{
+	struct lvts_ctrl *lvts_ctrl;
+	int i, ret;
+
+	ret = lvts_ctrl_init(dev, lvts_td, lvts_data);
+	if (ret)
+		return ret;
+
+	ret = lvts_domain_reset(dev, lvts_td->reset);
+	if (ret) {
+		dev_dbg(dev, "Failed to reset domain");
+		return ret;
+	}
+
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+
+		lvts_ctrl = &lvts_td->lvts_ctrl[i];
+
+		/*
+		 * Initialization steps:
+		 *
+		 * - Enable the clock
+		 * - Connect to the LVTS
+		 * - Initialize the LVTS
+		 * - Prepare the calibration data
+		 * - Select monitored sensors
+		 * [ Configure sampling ]
+		 * [ Configure the interrupt ]
+		 * - Start measurement
+		 */
+		ret = lvts_ctrl_enable(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to enable LVTS clock");
+			return ret;
+		}
+
+		ret = lvts_ctrl_connect(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to connect to LVTS controller");
+			return ret;
+		}
+
+		ret = lvts_ctrl_initialize(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to initialize controller");
+			return ret;
+		}
+
+		ret = lvts_ctrl_calibrate(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to calibrate controller");
+			return ret;
+		}
+
+		ret = lvts_ctrl_configure(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to configure controller");
+			return ret;
+		}
+
+		ret = lvts_ctrl_start(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to start controller");
+			return ret;
+		}
+	}
+
+	return lvts_debugfs_init(dev, lvts_td);
+}
+
+static int lvts_probe(struct platform_device *pdev)
+{
+	struct lvts_data *lvts_data;
+	struct lvts_domain *lvts_td;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int irq, ret;
+
+	lvts_td = devm_kzalloc(dev, sizeof(*lvts_td), GFP_KERNEL);
+	if (!lvts_td)
+		return -ENOMEM;
+
+	lvts_data = (struct lvts_data *)of_device_get_match_data(dev);
+	if (!lvts_data) {
+		dev_dbg(dev, "No platforme data");
+		return -ENODATA;
+	};
+
+	lvts_td->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(lvts_td->clk)) {
+		dev_dbg(dev, "Failed to retrieve clock\n");
+		return PTR_ERR(lvts_td->clk);
+	}
+
+	res = platform_get_mem_or_io(pdev, 0);
+	if (!res) {
+		dev_dbg(dev, "No IO resource\n");
+		return -ENXIO;
+	}
+
+	lvts_td->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(lvts_td->base)) {
+		dev_dbg(dev, "Failed to map io resource\n");
+		return PTR_ERR(lvts_td->base);
+	}
+
+	lvts_td->reset = devm_reset_control_get_by_index(dev, 0);
+	if (IS_ERR(lvts_td->reset)) {
+		dev_dbg(dev, "Failed to get reset control\n");
+		return PTR_ERR(lvts_td->reset);
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_dbg(dev, "No irq resource\n");
+		return irq;
+	}
+
+	ret = lvts_domain_init(dev, lvts_td, lvts_data);
+	if (ret) {
+		dev_dbg(dev, "Failed to initialize the lvts domain\n");
+		return ret;
+	}
+
+	/*
+	 * At this point the LVTS is initialized and enabled. We can
+	 * safely enable the interrupt.
+	 */
+	ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
+					IRQF_ONESHOT, dev_name(dev), lvts_td);
+	if (ret) {
+		dev_dbg(dev, "Failed to request interrupt\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, lvts_td);
+
+	return 0;
+}
+
+static int lvts_remove(struct platform_device *pdev)
+{
+	struct lvts_domain *lvts_td;
+	struct device *dev = &pdev->dev;
+	int i;
+
+	lvts_td = platform_get_drvdata(pdev);
+
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
+		lvts_ctrl_disable(dev, &lvts_td->lvts_ctrl[i]);
+
+	lvts_debugfs_exit();
+
+	return 0;
+}
+
+static struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {
+	{
+		.cal_offset = { 0x4, 0x7 },
+		.lvts_sensor = {
+			{ .dt_id = MT8195_MCU_BIG_CPU0 },
+			{ .dt_id = MT8195_MCU_BIG_CPU1 }
+		},
+		.num_lvts_sensor = 2,
+		.offset = 0x0,
+		.hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
+	},
+
+	{
+		.cal_offset = { 0xd, 0x10 },
+		.lvts_sensor = {
+			{ .dt_id = MT8195_MCU_BIG_CPU2 },
+			{ .dt_id = MT8195_MCU_BIG_CPU3 }
+		},
+		.num_lvts_sensor = 2,
+		.offset = 0x100,
+		.hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
+	},
+
+	{
+		.cal_offset = { 0x16, 0x19, 0x1c, 0x1f },
+		.lvts_sensor = {
+			{ .dt_id = MT8195_MCU_LITTLE_CPU0 },
+			{ .dt_id = MT8195_MCU_LITTLE_CPU1 },
+			{ .dt_id = MT8195_MCU_LITTLE_CPU2 },
+			{ .dt_id = MT8195_MCU_LITTLE_CPU3 }
+		},
+		.num_lvts_sensor = 4,
+		.offset = 0x200,
+		.hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
+	}
+};
+
+static struct lvts_data mt8195_lvts_mcu_data = {
+	.lvts_ctrl	= mt8195_lvts_data_ctrl,
+	.num_lvts_ctrl	= ARRAY_SIZE(mt8195_lvts_data_ctrl),
+};
+
+static const struct of_device_id lvts_of_match[] = {
+	{ .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, lvts_of_match);
+
+static struct platform_driver lvts_driver = {
+	.probe = lvts_probe,
+	.remove = lvts_remove,
+	.driver = {
+		.name = "mtk-lvts-thermal",
+		.of_match_table = lvts_of_match,
+	},
+};
+module_platform_driver(lvts_driver);
+
+MODULE_AUTHOR("Balsam CHIHI <bchihi@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek LVTS Thermal Driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes
  2023-01-24 13:17 [PATCH v11 0/6] Add LVTS thermal architecture bchihi
                   ` (3 preceding siblings ...)
  2023-01-24 13:17 ` [PATCH v11 4/6] thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver bchihi
@ 2023-01-24 13:17 ` bchihi
  2023-01-24 15:36   ` AngeloGioacchino Del Regno
  2023-01-31 15:37   ` [PATCH v12] arm64: dts: mediatek: mt8195: " bchihi
  2023-01-24 13:17 ` [PATCH v11 6/6] arm64/dts/mt8195: Add temperature mitigation threshold bchihi
  5 siblings, 2 replies; 57+ messages in thread
From: bchihi @ 2023-01-24 13:17 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

Add thermal zones and thermal nodes for the mt8195.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 129 +++++++++++++++++++++++
 1 file changed, 129 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 09df105f4606..636676f4ba25 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -14,6 +14,7 @@
 #include <dt-bindings/pinctrl/mt8195-pinfunc.h>
 #include <dt-bindings/power/mt8195-power.h>
 #include <dt-bindings/reset/mt8195-resets.h>
+#include <dt-bindings/thermal/mediatek-lvts.h>
 
 / {
 	compatible = "mediatek,mt8195";
@@ -954,6 +955,17 @@ spi0: spi@1100a000 {
 			status = "disabled";
 		};
 
+		lvts_ap: thermal-sensor@1100b000 {
+			compatible = "mediatek,mt8195-lvts-ap";
+			reg = <0 0x1100b000 0 0x1000>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
+			resets = <&infracfg_ao MT8195_INFRA_RST0_THERM_CTRL_SWRST>;
+			nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
+			nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
+			#thermal-sensor-cells = <1>;
+		};
+
 		spi1: spi@11010000 {
 			compatible = "mediatek,mt8195-spi",
 				     "mediatek,mt6765-spi";
@@ -1114,6 +1126,17 @@ mmc2: mmc@11250000 {
 			status = "disabled";
 		};
 
+		lvts_mcu: thermal-sensor@11278000 {
+			compatible = "mediatek,mt8195-lvts-mcu";
+			reg = <0 0x11278000 0 0x1000>;
+			interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
+			resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
+			nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
+			nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
+			#thermal-sensor-cells = <1>;
+		};
+
 		xhci1: usb@11290000 {
 			compatible = "mediatek,mt8195-xhci",
 				     "mediatek,mtk-xhci";
@@ -2387,4 +2410,110 @@ dp_tx: dp-tx@1c600000 {
 			status = "disabled";
 		};
 	};
+
+	thermal_zones: thermal-zones {
+		cpu0-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
+			trips {
+				cpu0_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu1-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU1>;
+			trips {
+				cpu1_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu2-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU2>;
+			trips {
+				cpu2_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu3-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU3>;
+			trips {
+				cpu3_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu4-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU0>;
+			trips {
+				cpu4_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu5-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU1>;
+			trips {
+				cpu5_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu6-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU2>;
+			trips {
+				cpu6_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu7-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU3>;
+			trips {
+				cpu7_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
 };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v11 6/6] arm64/dts/mt8195: Add temperature mitigation threshold
  2023-01-24 13:17 [PATCH v11 0/6] Add LVTS thermal architecture bchihi
                   ` (4 preceding siblings ...)
  2023-01-24 13:17 ` [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes bchihi
@ 2023-01-24 13:17 ` bchihi
  2023-01-24 15:36   ` AngeloGioacchino Del Regno
  5 siblings, 1 reply; 57+ messages in thread
From: bchihi @ 2023-01-24 13:17 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

The mt8195 SoC has several hotspots around the CPUs. Specify the
targeted temperature threshold when to apply the mitigation and define
the associated cooling devices.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 169 ++++++++++++++++++++---
 1 file changed, 153 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 636676f4ba25..9544ae91379a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -14,6 +14,7 @@
 #include <dt-bindings/pinctrl/mt8195-pinfunc.h>
 #include <dt-bindings/power/mt8195-power.h>
 #include <dt-bindings/reset/mt8195-resets.h>
+#include <dt-bindings/thermal/thermal.h>
 #include <dt-bindings/thermal/mediatek-lvts.h>
 
 / {
@@ -2413,107 +2414,243 @@ dp_tx: dp-tx@1c600000 {
 
 	thermal_zones: thermal-zones {
 		cpu0-thermal {
-			polling-delay = <0>;
-			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
+
 			trips {
+				cpu0_alert: trip-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
 				cpu0_crit: trip-crit {
 					temperature = <100000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu0_alert>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu1-thermal {
-			polling-delay = <0>;
-			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU1>;
+
 			trips {
+				cpu1_alert: trip-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
 				cpu1_crit: trip-crit {
 					temperature = <100000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu1_alert>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu2-thermal {
-			polling-delay = <0>;
-			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU2>;
+
 			trips {
+				cpu2_alert: trip-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
 				cpu2_crit: trip-crit {
 					temperature = <100000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu2_alert>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu3-thermal {
-			polling-delay = <0>;
-			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU3>;
+
 			trips {
+				cpu3_alert: trip-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
 				cpu3_crit: trip-crit {
 					temperature = <100000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu3_alert>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu4-thermal {
-			polling-delay = <0>;
-			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU0>;
+
 			trips {
+				cpu4_alert: trip-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
 				cpu4_crit: trip-crit {
 					temperature = <100000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu4_alert>;
+					cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu5-thermal {
-			polling-delay = <0>;
-			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU1>;
+
 			trips {
+				cpu5_alert: trip-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
 				cpu5_crit: trip-crit {
 					temperature = <100000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu5_alert>;
+					cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu6-thermal {
-			polling-delay = <0>;
-			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU2>;
+
 			trips {
+				cpu6_alert: trip-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
 				cpu6_crit: trip-crit {
 					temperature = <100000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu6_alert>;
+					cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 
 		cpu7-thermal {
-			polling-delay = <0>;
-			polling-delay-passive = <0>;
+			polling-delay = <1000>;
+			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU3>;
+
 			trips {
+				cpu7_alert: trip-alert {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
 				cpu7_crit: trip-crit {
 					temperature = <100000>;
 					hysteresis = <2000>;
 					type = "critical";
 				};
 			};
+
+			cooling-maps {
+				map0 {
+					trip = <&cpu7_alert>;
+					cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+								<&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
 		};
 	};
 };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 4/6] thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver
  2023-01-24 13:17 ` [PATCH v11 4/6] thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver bchihi
@ 2023-01-24 15:31   ` AngeloGioacchino Del Regno
  2023-01-25 15:06     ` Balsam CHIHI
  2023-01-31 15:38   ` [PATCH v12] thermal: drivers: mediatek: " bchihi
  1 sibling, 1 reply; 57+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-01-24 15:31 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, rafael, amitk, rui.zhang, matthias.bgg,
	robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

Il 24/01/23 14:17, bchihi@baylibre.com ha scritto:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
> controllers contained in a thermal domain.
> 
> A thermal domains can be the MCU or the AP.
> 
> Each thermal domains contain up to seven controllers, each thermal
> controller handle up to four thermal sensors.
> 
> The LVTS has two Finite State Machines (FSM), one to handle the
> functionin temperatures range like hot or cold temperature and another
> one to handle monitoring trip point. The FSM notifies via interrupts
> when a trip point is crossed.
> 
> The interrupt is managed at the thermal controller level, so when an
> interrupt occurs, the driver has to find out which sensor triggered
> such an interrupt.
> 
> The sampling of the thermal can be filtered or immediate. For the
> former, the LVTS measures several points and applies a low pass
> filter.
> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

On MT8195 Tomato Chromebook:
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 6/6] arm64/dts/mt8195: Add temperature mitigation threshold
  2023-01-24 13:17 ` [PATCH v11 6/6] arm64/dts/mt8195: Add temperature mitigation threshold bchihi
@ 2023-01-24 15:36   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 57+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-01-24 15:36 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, rafael, amitk, rui.zhang, matthias.bgg,
	robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

Il 24/01/23 14:17, bchihi@baylibre.com ha scritto:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> The mt8195 SoC has several hotspots around the CPUs. Specify the
> targeted temperature threshold when to apply the mitigation and define
> the associated cooling devices.
> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>

Commit title prefix
- arm64: dts: mt8195:
or
- arm64: dts: mediatek: mt8195:

otherwise,

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes
  2023-01-24 13:17 ` [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes bchihi
@ 2023-01-24 15:36   ` AngeloGioacchino Del Regno
  2023-01-25 15:10     ` Balsam CHIHI
  2023-01-31 15:37   ` [PATCH v12] arm64: dts: mediatek: mt8195: " bchihi
  1 sibling, 1 reply; 57+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-01-24 15:36 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, rafael, amitk, rui.zhang, matthias.bgg,
	robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

Il 24/01/23 14:17, bchihi@baylibre.com ha scritto:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> Add thermal zones and thermal nodes for the mt8195.
> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>

You should change the commit title to reflect the same syntax that you can find
in a `git log --oneline arch/arm64/boot/dts/mediatek/`.

arm64: dts: mediatek: mt8195: Add thermal zones and thermal nodes

or

arm64: dts: mt8195: Add thermal zones and thermal nodes


...otherwise:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 1/6] thermal/drivers/mediatek: Relocate driver to mediatek folder
  2023-01-24 13:17 ` [PATCH v11 1/6] thermal/drivers/mediatek: Relocate driver to mediatek folder bchihi
@ 2023-01-24 15:37   ` AngeloGioacchino Del Regno
  2023-01-25 15:02     ` Balsam CHIHI
  0 siblings, 1 reply; 57+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-01-24 15:37 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, rafael, amitk, rui.zhang, matthias.bgg,
	robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

Il 24/01/23 14:17, bchihi@baylibre.com ha scritto:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> Add MediaTek proprietary folder to upstream more thermal zone and cooler
> drivers, relocate the original thermal controller driver to it, and rename it
> as "auxadc_thermal.c" to show its purpose more clearly.
> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-24 13:17 ` [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition bchihi
@ 2023-01-25 11:14   ` Daniel Lezcano
  2023-01-25 20:35     ` Rob Herring
  2023-01-25 20:34   ` Rob Herring
  2023-01-26 16:10   ` [PATCH v12 2/6] dt-bindings: thermal: mediatek: " bchihi
  2 siblings, 1 reply; 57+ messages in thread
From: Daniel Lezcano @ 2023-01-25 11:14 UTC (permalink / raw)
  To: bchihi, angelogioacchino.delregno, rafael, amitk, rui.zhang,
	matthias.bgg, robh+dt, krzysztof.kozlowski+dt, rdunlap,
	ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

On 24/01/2023 14:17, bchihi@baylibre.com wrote:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> Add LVTS thermal controllers dt-binding definition for mt8195.
> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> ---

Krzysztof, Rob,

are you ok with these changes ?


>   .../thermal/mediatek,lvts-thermal.yaml        | 107 ++++++++++++++++++
>   include/dt-bindings/thermal/mediatek-lvts.h   |  19 ++++
>   2 files changed, 126 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
>   create mode 100644 include/dt-bindings/thermal/mediatek-lvts.h
> 
> diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> new file mode 100644
> index 000000000000..12bfbdd8ff89
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> @@ -0,0 +1,107 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
> +
> +maintainers:
> +  - Balsam CHIHI <bchihi@baylibre.com>
> +
> +description: |
> +  LVTS is a thermal management architecture composed of three subsystems,
> +  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
> +  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
> +  a Digital controller (LVTS_CTRL).
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt8195-lvts-ap
> +      - mediatek,mt8195-lvts-mcu
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 1
> +    description: LVTS reset for clearing temporary data on AP/MCU.
> +
> +  nvmem-cells:
> +    minItems: 1
> +    items:
> +      - description: Calibration eFuse data 1 for LVTS
> +      - description: Calibration eFuse data 2 for LVTS
> +
> +  nvmem-cell-names:
> +    minItems: 1
> +    items:
> +      - const: lvts-calib-data-1
> +      - const: lvts-calib-data-2
> +
> +  "#thermal-sensor-cells":
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - resets
> +  - nvmem-cells
> +  - nvmem-cell-names
> +  - "#thermal-sensor-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/mt8195-clk.h>
> +    #include <dt-bindings/reset/mt8195-resets.h>
> +    #include <dt-bindings/thermal/mediatek-lvts.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      lvts_mcu: thermal-sensor@11278000 {
> +        compatible = "mediatek,mt8195-lvts-mcu";
> +        reg = <0 0x11278000 0 0x1000>;
> +        interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
> +        clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
> +        resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
> +        nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
> +        nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
> +        #thermal-sensor-cells = <1>;
> +      };
> +    };
> +
> +    thermal_zones: thermal-zones {
> +      cpu0-thermal {
> +        polling-delay = <1000>;
> +        polling-delay-passive = <250>;
> +        thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
> +
> +        trips {
> +          cpu0_alert: trip-alert {
> +            temperature = <85000>;
> +            hysteresis = <2000>;
> +            type = "passive";
> +          };
> +
> +          cpu0_crit: trip-crit {
> +            temperature = <100000>;
> +            hysteresis = <2000>;
> +            type = "critical";
> +          };
> +        };
> +      };
> +    };
> diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
> new file mode 100644
> index 000000000000..428a95c18509
> --- /dev/null
> +++ b/include/dt-bindings/thermal/mediatek-lvts.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + * Author: Balsam CHIHI <bchihi@baylibre.com>
> + */
> +
> +#ifndef __MEDIATEK_LVTS_DT_H
> +#define __MEDIATEK_LVTS_DT_H
> +
> +#define MT8195_MCU_BIG_CPU0	0
> +#define MT8195_MCU_BIG_CPU1	1
> +#define MT8195_MCU_BIG_CPU2	2
> +#define MT8195_MCU_BIG_CPU3	3
> +#define MT8195_MCU_LITTLE_CPU0	4
> +#define MT8195_MCU_LITTLE_CPU1	5
> +#define MT8195_MCU_LITTLE_CPU2	6
> +#define MT8195_MCU_LITTLE_CPU3	7
> +
> +#endif /* __MEDIATEK_LVTS_DT_H */

-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 3/6] arm64/dts/mt8195: Add efuse node to mt8195
  2023-01-24 13:17 ` [PATCH v11 3/6] arm64/dts/mt8195: Add efuse node to mt8195 bchihi
@ 2023-01-25 14:25   ` Matthias Brugger
  2023-01-25 15:04     ` Balsam CHIHI
  0 siblings, 1 reply; 57+ messages in thread
From: Matthias Brugger @ 2023-01-25 14:25 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen,
	p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen



On 24/01/2023 14:17, bchihi@baylibre.com wrote:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> Add efuse node.
> This will be required by the thermal driver to get the calibration data.
> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

I fixed the subject prefix to:
arm64: dts: mt8195: ...
to be in line with other commits.
Please take that into account for future patches you send.

Applied thanks!

> ---
>   arch/arm64/boot/dts/mediatek/mt8195.dtsi | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> index 5d31536f4c48..09df105f4606 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> @@ -1380,6 +1380,12 @@ pciephy_glb_intr: pciephy-glb-intr@193 {
>   			dp_calibration: dp-data@1ac {
>   				reg = <0x1ac 0x10>;
>   			};
> +			lvts_efuse_data1: lvts1-calib@1bc {
> +				reg = <0x1bc 0x14>;
> +			};
> +			lvts_efuse_data2: lvts2-calib@1d0 {
> +				reg = <0x1d0 0x38>;
> +			};
>   		};
>   
>   		u3phy2: t-phy@11c40000 {

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 1/6] thermal/drivers/mediatek: Relocate driver to mediatek folder
  2023-01-24 15:37   ` AngeloGioacchino Del Regno
@ 2023-01-25 15:02     ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-01-25 15:02 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: daniel.lezcano, rafael, amitk, rui.zhang, matthias.bgg, robh+dt,
	krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel, linux-pm,
	linux-kernel, linux-arm-kernel, linux-mediatek, devicetree,
	khilman, james.lo, rex-bc.chen

On Tue, Jan 24, 2023 at 4:37 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> Il 24/01/23 14:17, bchihi@baylibre.com ha scritto:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> >
> > Add MediaTek proprietary folder to upstream more thermal zone and cooler
> > drivers, relocate the original thermal controller driver to it, and rename it
> > as "auxadc_thermal.c" to show its purpose more clearly.
> >
> > Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
>

Hi Angelo,

Thank you.

Best regards,
Balsam

> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>
>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 3/6] arm64/dts/mt8195: Add efuse node to mt8195
  2023-01-25 14:25   ` Matthias Brugger
@ 2023-01-25 15:04     ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-01-25 15:04 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen,
	p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On Wed, Jan 25, 2023 at 3:25 PM Matthias Brugger <matthias.bgg@gmail.com> wrote:
>
>
>
> On 24/01/2023 14:17, bchihi@baylibre.com wrote:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> >
> > Add efuse node.
> > This will be required by the thermal driver to get the calibration data.
> >
> > Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> > Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
> > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>
> I fixed the subject prefix to:
> arm64: dts: mt8195: ...
> to be in line with other commits.
> Please take that into account for future patches you send.
>
> Applied thanks!
>

Hi Matthias,

Thank you for the fix and for applying the patch!

Best regards,
Balsam

> > ---
> >   arch/arm64/boot/dts/mediatek/mt8195.dtsi | 6 ++++++
> >   1 file changed, 6 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > index 5d31536f4c48..09df105f4606 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > @@ -1380,6 +1380,12 @@ pciephy_glb_intr: pciephy-glb-intr@193 {
> >                       dp_calibration: dp-data@1ac {
> >                               reg = <0x1ac 0x10>;
> >                       };
> > +                     lvts_efuse_data1: lvts1-calib@1bc {
> > +                             reg = <0x1bc 0x14>;
> > +                     };
> > +                     lvts_efuse_data2: lvts2-calib@1d0 {
> > +                             reg = <0x1d0 0x38>;
> > +                     };
> >               };
> >
> >               u3phy2: t-phy@11c40000 {

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 4/6] thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver
  2023-01-24 15:31   ` AngeloGioacchino Del Regno
@ 2023-01-25 15:06     ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-01-25 15:06 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: daniel.lezcano, rafael, amitk, rui.zhang, matthias.bgg, robh+dt,
	krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel, linux-pm,
	linux-kernel, linux-arm-kernel, linux-mediatek, devicetree,
	khilman, james.lo, rex-bc.chen

On Tue, Jan 24, 2023 at 4:31 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> Il 24/01/23 14:17, bchihi@baylibre.com ha scritto:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> >
> > The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
> > controllers contained in a thermal domain.
> >
> > A thermal domains can be the MCU or the AP.
> >
> > Each thermal domains contain up to seven controllers, each thermal
> > controller handle up to four thermal sensors.
> >
> > The LVTS has two Finite State Machines (FSM), one to handle the
> > functionin temperatures range like hot or cold temperature and another
> > one to handle monitoring trip point. The FSM notifies via interrupts
> > when a trip point is crossed.
> >
> > The interrupt is managed at the thermal controller level, so when an
> > interrupt occurs, the driver has to find out which sensor triggered
> > such an interrupt.
> >
> > The sampling of the thermal can be filtered or immediate. For the
> > former, the LVTS measures several points and applies a low pass
> > filter.
> >
> > Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>
> On MT8195 Tomato Chromebook:
> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

Hi Angelo,

Thank you for reviewing and testing it.

Best regards,
Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes
  2023-01-24 15:36   ` AngeloGioacchino Del Regno
@ 2023-01-25 15:10     ` Balsam CHIHI
  2023-01-25 19:09       ` Matthias Brugger
  0 siblings, 1 reply; 57+ messages in thread
From: Balsam CHIHI @ 2023-01-25 15:10 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: daniel.lezcano, rafael, amitk, rui.zhang, matthias.bgg, robh+dt,
	krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel, linux-pm,
	linux-kernel, linux-arm-kernel, linux-mediatek, devicetree,
	khilman, james.lo, rex-bc.chen

On Tue, Jan 24, 2023 at 4:37 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> Il 24/01/23 14:17, bchihi@baylibre.com ha scritto:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> >
> > Add thermal zones and thermal nodes for the mt8195.
> >
> > Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
>
> You should change the commit title to reflect the same syntax that you can find
> in a `git log --oneline arch/arm64/boot/dts/mediatek/`.
>
> arm64: dts: mediatek: mt8195: Add thermal zones and thermal nodes
>
> or
>
> arm64: dts: mt8195: Add thermal zones and thermal nodes
>

Hi Angelo,

Thank you for the review.
Should I resend with the fix?
Or you would fix it when applying it like Matthias did for "[PATCH v11
3/6] arm64/dts/mt8195: Add efuse node to mt8195"?

Best regards,
Balsam

>
> ...otherwise:
>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes
  2023-01-25 15:10     ` Balsam CHIHI
@ 2023-01-25 19:09       ` Matthias Brugger
  2023-01-26  9:43         ` Balsam CHIHI
  0 siblings, 1 reply; 57+ messages in thread
From: Matthias Brugger @ 2023-01-25 19:09 UTC (permalink / raw)
  To: Balsam CHIHI, AngeloGioacchino Del Regno
  Cc: daniel.lezcano, rafael, amitk, rui.zhang, robh+dt,
	krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel, linux-pm,
	linux-kernel, linux-arm-kernel, linux-mediatek, devicetree,
	khilman, james.lo, rex-bc.chen



On 25/01/2023 16:10, Balsam CHIHI wrote:
> On Tue, Jan 24, 2023 at 4:37 PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno@collabora.com> wrote:
>>
>> Il 24/01/23 14:17, bchihi@baylibre.com ha scritto:
>>> From: Balsam CHIHI <bchihi@baylibre.com>
>>>
>>> Add thermal zones and thermal nodes for the mt8195.
>>>
>>> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
>>
>> You should change the commit title to reflect the same syntax that you can find
>> in a `git log --oneline arch/arm64/boot/dts/mediatek/`.
>>
>> arm64: dts: mediatek: mt8195: Add thermal zones and thermal nodes
>>
>> or
>>
>> arm64: dts: mt8195: Add thermal zones and thermal nodes
>>
> 
> Hi Angelo,
> 
> Thank you for the review.
> Should I resend with the fix?
> Or you would fix it when applying it like Matthias did for "[PATCH v11
> 3/6] arm64/dts/mt8195: Add efuse node to mt8195"?
> 

If you need to send a new version for any reason, then please update. Otherwise 
I'll fix it once I can take it.

Regards,
Matthias

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-24 13:17 ` [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition bchihi
  2023-01-25 11:14   ` Daniel Lezcano
@ 2023-01-25 20:34   ` Rob Herring
  2023-01-26 10:33     ` Balsam CHIHI
  2023-01-26 16:10   ` [PATCH v12 2/6] dt-bindings: thermal: mediatek: " bchihi
  2 siblings, 1 reply; 57+ messages in thread
From: Rob Herring @ 2023-01-25 20:34 UTC (permalink / raw)
  To: bchihi
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, krzysztof.kozlowski+dt, rdunlap,
	ye.xingchen, p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On Tue, Jan 24, 2023 at 02:17:13PM +0100, bchihi@baylibre.com wrote:
> From: Balsam CHIHI <bchihi@baylibre.com>
>

dt-bindings: thermal: ... for the subject
 
> Add LVTS thermal controllers dt-binding definition for mt8195.
> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> ---
>  .../thermal/mediatek,lvts-thermal.yaml        | 107 ++++++++++++++++++
>  include/dt-bindings/thermal/mediatek-lvts.h   |  19 ++++
>  2 files changed, 126 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
>  create mode 100644 include/dt-bindings/thermal/mediatek-lvts.h
> 
> diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> new file mode 100644
> index 000000000000..12bfbdd8ff89
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> @@ -0,0 +1,107 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
> +
> +maintainers:
> +  - Balsam CHIHI <bchihi@baylibre.com>
> +
> +description: |
> +  LVTS is a thermal management architecture composed of three subsystems,
> +  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
> +  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
> +  a Digital controller (LVTS_CTRL).
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt8195-lvts-ap
> +      - mediatek,mt8195-lvts-mcu
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 1
> +    description: LVTS reset for clearing temporary data on AP/MCU.
> +
> +  nvmem-cells:
> +    minItems: 1
> +    items:
> +      - description: Calibration eFuse data 1 for LVTS
> +      - description: Calibration eFuse data 2 for LVTS
> +
> +  nvmem-cell-names:
> +    minItems: 1
> +    items:
> +      - const: lvts-calib-data-1
> +      - const: lvts-calib-data-2
> +
> +  "#thermal-sensor-cells":
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - resets
> +  - nvmem-cells
> +  - nvmem-cell-names
> +  - "#thermal-sensor-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/mt8195-clk.h>
> +    #include <dt-bindings/reset/mt8195-resets.h>
> +    #include <dt-bindings/thermal/mediatek-lvts.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      lvts_mcu: thermal-sensor@11278000 {
> +        compatible = "mediatek,mt8195-lvts-mcu";
> +        reg = <0 0x11278000 0 0x1000>;
> +        interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
> +        clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
> +        resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
> +        nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
> +        nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
> +        #thermal-sensor-cells = <1>;
> +      };
> +    };
> +
> +    thermal_zones: thermal-zones {
> +      cpu0-thermal {
> +        polling-delay = <1000>;
> +        polling-delay-passive = <250>;
> +        thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
> +
> +        trips {
> +          cpu0_alert: trip-alert {
> +            temperature = <85000>;
> +            hysteresis = <2000>;
> +            type = "passive";
> +          };
> +
> +          cpu0_crit: trip-crit {
> +            temperature = <100000>;
> +            hysteresis = <2000>;
> +            type = "critical";
> +          };
> +        };
> +      };
> +    };
> diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
> new file mode 100644
> index 000000000000..428a95c18509
> --- /dev/null
> +++ b/include/dt-bindings/thermal/mediatek-lvts.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */

Okay with GPL 4? GPL-2.0-only

Dual license please. Consistent with your .dts files.

> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + * Author: Balsam CHIHI <bchihi@baylibre.com>
> + */
> +
> +#ifndef __MEDIATEK_LVTS_DT_H
> +#define __MEDIATEK_LVTS_DT_H
> +
> +#define MT8195_MCU_BIG_CPU0	0
> +#define MT8195_MCU_BIG_CPU1	1
> +#define MT8195_MCU_BIG_CPU2	2
> +#define MT8195_MCU_BIG_CPU3	3
> +#define MT8195_MCU_LITTLE_CPU0	4
> +#define MT8195_MCU_LITTLE_CPU1	5
> +#define MT8195_MCU_LITTLE_CPU2	6
> +#define MT8195_MCU_LITTLE_CPU3	7
> +
> +#endif /* __MEDIATEK_LVTS_DT_H */
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-25 11:14   ` Daniel Lezcano
@ 2023-01-25 20:35     ` Rob Herring
  2023-01-25 21:13       ` Daniel Lezcano
  0 siblings, 1 reply; 57+ messages in thread
From: Rob Herring @ 2023-01-25 20:35 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: bchihi, angelogioacchino.delregno, rafael, amitk, rui.zhang,
	matthias.bgg, krzysztof.kozlowski+dt, rdunlap, ye.xingchen,
	p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On Wed, Jan 25, 2023 at 12:14:17PM +0100, Daniel Lezcano wrote:
> On 24/01/2023 14:17, bchihi@baylibre.com wrote:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> > 
> > Add LVTS thermal controllers dt-binding definition for mt8195.
> > 
> > Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> > ---
> 
> Krzysztof, Rob,
> 
> are you ok with these changes ?

It says v11, but I sure don't recall the 10 other versions...

Rob

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-25 20:35     ` Rob Herring
@ 2023-01-25 21:13       ` Daniel Lezcano
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel Lezcano @ 2023-01-25 21:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: bchihi, angelogioacchino.delregno, rafael, amitk, rui.zhang,
	matthias.bgg, krzysztof.kozlowski+dt, rdunlap, ye.xingchen,
	p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On 25/01/2023 21:35, Rob Herring wrote:
> On Wed, Jan 25, 2023 at 12:14:17PM +0100, Daniel Lezcano wrote:
>> On 24/01/2023 14:17, bchihi@baylibre.com wrote:
>>> From: Balsam CHIHI <bchihi@baylibre.com>
>>>
>>> Add LVTS thermal controllers dt-binding definition for mt8195.
>>>
>>> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
>>> ---
>>
>> Krzysztof, Rob,
>>
>> are you ok with these changes ?
> 
> It says v11, but I sure don't recall the 10 other versions...

Ah, yes indeed. I remember Krzysztof told Balsam to fix the recipient 
list because some maintainers were missing.


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes
  2023-01-25 19:09       ` Matthias Brugger
@ 2023-01-26  9:43         ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-01-26  9:43 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: AngeloGioacchino Del Regno, daniel.lezcano, rafael, amitk,
	rui.zhang, robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen,
	p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On Wed, Jan 25, 2023 at 8:09 PM Matthias Brugger <matthias.bgg@gmail.com> wrote:
>
>
>
> On 25/01/2023 16:10, Balsam CHIHI wrote:
> > On Tue, Jan 24, 2023 at 4:37 PM AngeloGioacchino Del Regno
> > <angelogioacchino.delregno@collabora.com> wrote:
> >>
> >> Il 24/01/23 14:17, bchihi@baylibre.com ha scritto:
> >>> From: Balsam CHIHI <bchihi@baylibre.com>
> >>>
> >>> Add thermal zones and thermal nodes for the mt8195.
> >>>
> >>> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> >>
> >> You should change the commit title to reflect the same syntax that you can find
> >> in a `git log --oneline arch/arm64/boot/dts/mediatek/`.
> >>
> >> arm64: dts: mediatek: mt8195: Add thermal zones and thermal nodes
> >>
> >> or
> >>
> >> arm64: dts: mt8195: Add thermal zones and thermal nodes
> >>
> >
> > Hi Angelo,
> >
> > Thank you for the review.
> > Should I resend with the fix?
> > Or you would fix it when applying it like Matthias did for "[PATCH v11
> > 3/6] arm64/dts/mt8195: Add efuse node to mt8195"?
> >
>
> If you need to send a new version for any reason, then please update. Otherwise
> I'll fix it once I can take it.

Hi Matthias,

OK.
I appreciate it,
thank you.

Best regards,
Balsam

>
> Regards,
> Matthias

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-25 20:34   ` Rob Herring
@ 2023-01-26 10:33     ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-01-26 10:33 UTC (permalink / raw)
  To: Rob Herring
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, krzysztof.kozlowski+dt, rdunlap,
	ye.xingchen, p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

Hi Rob,

On Wed, Jan 25, 2023 at 9:34 PM Rob Herring <robh@kernel.org> wrote:
>
> On Tue, Jan 24, 2023 at 02:17:13PM +0100, bchihi@baylibre.com wrote:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> >
>
> dt-bindings: thermal: ... for the subject

I will fix it.

>
> > Add LVTS thermal controllers dt-binding definition for mt8195.
> >
> > Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> > ---
> >  .../thermal/mediatek,lvts-thermal.yaml        | 107 ++++++++++++++++++
> >  include/dt-bindings/thermal/mediatek-lvts.h   |  19 ++++
> >  2 files changed, 126 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> >  create mode 100644 include/dt-bindings/thermal/mediatek-lvts.h
> >
> > diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> > new file mode 100644
> > index 000000000000..12bfbdd8ff89
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> > @@ -0,0 +1,107 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
> > +
> > +maintainers:
> > +  - Balsam CHIHI <bchihi@baylibre.com>
> > +
> > +description: |
> > +  LVTS is a thermal management architecture composed of three subsystems,
> > +  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
> > +  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
> > +  a Digital controller (LVTS_CTRL).
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - mediatek,mt8195-lvts-ap
> > +      - mediatek,mt8195-lvts-mcu
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 1
> > +
> > +  resets:
> > +    maxItems: 1
> > +    description: LVTS reset for clearing temporary data on AP/MCU.
> > +
> > +  nvmem-cells:
> > +    minItems: 1
> > +    items:
> > +      - description: Calibration eFuse data 1 for LVTS
> > +      - description: Calibration eFuse data 2 for LVTS
> > +
> > +  nvmem-cell-names:
> > +    minItems: 1
> > +    items:
> > +      - const: lvts-calib-data-1
> > +      - const: lvts-calib-data-2
> > +
> > +  "#thermal-sensor-cells":
> > +    const: 1
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - clocks
> > +  - resets
> > +  - nvmem-cells
> > +  - nvmem-cell-names
> > +  - "#thermal-sensor-cells"
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/clock/mt8195-clk.h>
> > +    #include <dt-bindings/reset/mt8195-resets.h>
> > +    #include <dt-bindings/thermal/mediatek-lvts.h>
> > +
> > +    soc {
> > +      #address-cells = <2>;
> > +      #size-cells = <2>;
> > +
> > +      lvts_mcu: thermal-sensor@11278000 {
> > +        compatible = "mediatek,mt8195-lvts-mcu";
> > +        reg = <0 0x11278000 0 0x1000>;
> > +        interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
> > +        resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
> > +        nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
> > +        nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
> > +        #thermal-sensor-cells = <1>;
> > +      };
> > +    };
> > +
> > +    thermal_zones: thermal-zones {
> > +      cpu0-thermal {
> > +        polling-delay = <1000>;
> > +        polling-delay-passive = <250>;
> > +        thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
> > +
> > +        trips {
> > +          cpu0_alert: trip-alert {
> > +            temperature = <85000>;
> > +            hysteresis = <2000>;
> > +            type = "passive";
> > +          };
> > +
> > +          cpu0_crit: trip-crit {
> > +            temperature = <100000>;
> > +            hysteresis = <2000>;
> > +            type = "critical";
> > +          };
> > +        };
> > +      };
> > +    };
> > diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
> > new file mode 100644
> > index 000000000000..428a95c18509
> > --- /dev/null
> > +++ b/include/dt-bindings/thermal/mediatek-lvts.h
> > @@ -0,0 +1,19 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
>
> Okay with GPL 4? GPL-2.0-only
>
> Dual license please. Consistent with your .dts files.

I will fix this too.

>
> > +/*
> > + * Copyright (c) 2023 MediaTek Inc.
> > + * Author: Balsam CHIHI <bchihi@baylibre.com>
> > + */
> > +
> > +#ifndef __MEDIATEK_LVTS_DT_H
> > +#define __MEDIATEK_LVTS_DT_H
> > +
> > +#define MT8195_MCU_BIG_CPU0  0
> > +#define MT8195_MCU_BIG_CPU1  1
> > +#define MT8195_MCU_BIG_CPU2  2
> > +#define MT8195_MCU_BIG_CPU3  3
> > +#define MT8195_MCU_LITTLE_CPU0       4
> > +#define MT8195_MCU_LITTLE_CPU1       5
> > +#define MT8195_MCU_LITTLE_CPU2       6
> > +#define MT8195_MCU_LITTLE_CPU3       7
> > +
> > +#endif /* __MEDIATEK_LVTS_DT_H */
> > --
> > 2.34.1
> >

Thank you for the review.

Best regards,
Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-24 13:17 ` [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition bchihi
  2023-01-25 11:14   ` Daniel Lezcano
  2023-01-25 20:34   ` Rob Herring
@ 2023-01-26 16:10   ` bchihi
  2023-01-27 22:10     ` Daniel Lezcano
                       ` (3 more replies)
  2 siblings, 4 replies; 57+ messages in thread
From: bchihi @ 2023-01-26 16:10 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

Add LVTS thermal controllers dt-binding definition for mt8195.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
---
Changelog:
  v12:
     - Fixed subject prefix
     - Fixed licences GPL-2.0+ to GPL-2.0
     - Added dual licenses
  v11:
     - Rebase on top of "thermal/linux-next" :
       base=0d568e144ead70189e7f16066dcb155b78ff9266
     - Remove unsupported SoC (mt8192) from dt-binding definition
  v10:
     - Rebase on top of "thermal/linux-next" : thermal-v6.3-rc1
  v9:
     - Rebase on top of 6.0.0-rc1
     - Update dt-bindings :
       - Add "allOf:if:then:"
       - Use mt8192 as example (instead of mt8195)
       - Fix dt-binding errors
       - Fix DTS errors
  v8:
     - Fix coding style issues
     - Rebase on top of next-20220803
     - Add multi-instance support :
       - Rewrite DT-binding and DTS :
         - Add DT-binding and DTS for LVTS_v4 (MT8192 and MT8195)
           - One LVTS node for each HW Domain (AP and MCU)
         - One SW Instance for each HW Domain
  v7:
     - Fix coding style issues
     - Rewrite dt bindings
       - was not accurate
       - Use mt8195 for example (instead of mt8192)
       - Rename mt6873 to mt8192
       - Remove clock name
---
---
 .../thermal/mediatek,lvts-thermal.yaml        | 107 ++++++++++++++++++
 include/dt-bindings/thermal/mediatek-lvts.h   |  19 ++++
 2 files changed, 126 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
 create mode 100644 include/dt-bindings/thermal/mediatek-lvts.h

diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
new file mode 100644
index 000000000000..12bfbdd8ff89
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
+
+maintainers:
+  - Balsam CHIHI <bchihi@baylibre.com>
+
+description: |
+  LVTS is a thermal management architecture composed of three subsystems,
+  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
+  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
+  a Digital controller (LVTS_CTRL).
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8195-lvts-ap
+      - mediatek,mt8195-lvts-mcu
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+    description: LVTS reset for clearing temporary data on AP/MCU.
+
+  nvmem-cells:
+    minItems: 1
+    items:
+      - description: Calibration eFuse data 1 for LVTS
+      - description: Calibration eFuse data 2 for LVTS
+
+  nvmem-cell-names:
+    minItems: 1
+    items:
+      - const: lvts-calib-data-1
+      - const: lvts-calib-data-2
+
+  "#thermal-sensor-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+  - nvmem-cells
+  - nvmem-cell-names
+  - "#thermal-sensor-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/reset/mt8195-resets.h>
+    #include <dt-bindings/thermal/mediatek-lvts.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      lvts_mcu: thermal-sensor@11278000 {
+        compatible = "mediatek,mt8195-lvts-mcu";
+        reg = <0 0x11278000 0 0x1000>;
+        interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
+        resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
+        nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
+        nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
+        #thermal-sensor-cells = <1>;
+      };
+    };
+
+    thermal_zones: thermal-zones {
+      cpu0-thermal {
+        polling-delay = <1000>;
+        polling-delay-passive = <250>;
+        thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
+
+        trips {
+          cpu0_alert: trip-alert {
+            temperature = <85000>;
+            hysteresis = <2000>;
+            type = "passive";
+          };
+
+          cpu0_crit: trip-crit {
+            temperature = <100000>;
+            hysteresis = <2000>;
+            type = "critical";
+          };
+        };
+      };
+    };
diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
new file mode 100644
index 000000000000..902d5b1e4f43
--- /dev/null
+++ b/include/dt-bindings/thermal/mediatek-lvts.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0 or MIT) */
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Balsam CHIHI <bchihi@baylibre.com>
+ */
+
+#ifndef __MEDIATEK_LVTS_DT_H
+#define __MEDIATEK_LVTS_DT_H
+
+#define MT8195_MCU_BIG_CPU0	0
+#define MT8195_MCU_BIG_CPU1	1
+#define MT8195_MCU_BIG_CPU2	2
+#define MT8195_MCU_BIG_CPU3	3
+#define MT8195_MCU_LITTLE_CPU0	4
+#define MT8195_MCU_LITTLE_CPU1	5
+#define MT8195_MCU_LITTLE_CPU2	6
+#define MT8195_MCU_LITTLE_CPU3	7
+
+#endif /* __MEDIATEK_LVTS_DT_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-26 16:10   ` [PATCH v12 2/6] dt-bindings: thermal: mediatek: " bchihi
@ 2023-01-27 22:10     ` Daniel Lezcano
  2023-01-28 10:50       ` Krzysztof Kozlowski
  2023-01-28 10:48     ` Krzysztof Kozlowski
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 57+ messages in thread
From: Daniel Lezcano @ 2023-01-27 22:10 UTC (permalink / raw)
  To: bchihi, angelogioacchino.delregno, rafael, amitk, rui.zhang,
	matthias.bgg, robh+dt, krzysztof.kozlowski+dt, rdunlap,
	ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen


Hi Rob,

I think Balsam took into account your comments. Is it fine for you ?


On 26/01/2023 17:10, bchihi@baylibre.com wrote:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> Add LVTS thermal controllers dt-binding definition for mt8195.
> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> ---
> Changelog:
>    v12:
>       - Fixed subject prefix
>       - Fixed licences GPL-2.0+ to GPL-2.0
>       - Added dual licenses
>    v11:
>       - Rebase on top of "thermal/linux-next" :
>         base=0d568e144ead70189e7f16066dcb155b78ff9266
>       - Remove unsupported SoC (mt8192) from dt-binding definition
>    v10:
>       - Rebase on top of "thermal/linux-next" : thermal-v6.3-rc1
>    v9:
>       - Rebase on top of 6.0.0-rc1
>       - Update dt-bindings :
>         - Add "allOf:if:then:"
>         - Use mt8192 as example (instead of mt8195)
>         - Fix dt-binding errors
>         - Fix DTS errors
>    v8:
>       - Fix coding style issues
>       - Rebase on top of next-20220803
>       - Add multi-instance support :
>         - Rewrite DT-binding and DTS :
>           - Add DT-binding and DTS for LVTS_v4 (MT8192 and MT8195)
>             - One LVTS node for each HW Domain (AP and MCU)
>           - One SW Instance for each HW Domain
>    v7:
>       - Fix coding style issues
>       - Rewrite dt bindings
>         - was not accurate
>         - Use mt8195 for example (instead of mt8192)
>         - Rename mt6873 to mt8192
>         - Remove clock name
> ---
> ---
>   .../thermal/mediatek,lvts-thermal.yaml        | 107 ++++++++++++++++++
>   include/dt-bindings/thermal/mediatek-lvts.h   |  19 ++++
>   2 files changed, 126 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
>   create mode 100644 include/dt-bindings/thermal/mediatek-lvts.h
> 
> diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> new file mode 100644
> index 000000000000..12bfbdd8ff89
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> @@ -0,0 +1,107 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
> +
> +maintainers:
> +  - Balsam CHIHI <bchihi@baylibre.com>
> +
> +description: |
> +  LVTS is a thermal management architecture composed of three subsystems,
> +  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
> +  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
> +  a Digital controller (LVTS_CTRL).
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt8195-lvts-ap
> +      - mediatek,mt8195-lvts-mcu
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 1
> +    description: LVTS reset for clearing temporary data on AP/MCU.
> +
> +  nvmem-cells:
> +    minItems: 1
> +    items:
> +      - description: Calibration eFuse data 1 for LVTS
> +      - description: Calibration eFuse data 2 for LVTS
> +
> +  nvmem-cell-names:
> +    minItems: 1
> +    items:
> +      - const: lvts-calib-data-1
> +      - const: lvts-calib-data-2
> +
> +  "#thermal-sensor-cells":
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - resets
> +  - nvmem-cells
> +  - nvmem-cell-names
> +  - "#thermal-sensor-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/mt8195-clk.h>
> +    #include <dt-bindings/reset/mt8195-resets.h>
> +    #include <dt-bindings/thermal/mediatek-lvts.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      lvts_mcu: thermal-sensor@11278000 {
> +        compatible = "mediatek,mt8195-lvts-mcu";
> +        reg = <0 0x11278000 0 0x1000>;
> +        interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
> +        clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
> +        resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
> +        nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
> +        nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
> +        #thermal-sensor-cells = <1>;
> +      };
> +    };
> +
> +    thermal_zones: thermal-zones {
> +      cpu0-thermal {
> +        polling-delay = <1000>;
> +        polling-delay-passive = <250>;
> +        thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
> +
> +        trips {
> +          cpu0_alert: trip-alert {
> +            temperature = <85000>;
> +            hysteresis = <2000>;
> +            type = "passive";
> +          };
> +
> +          cpu0_crit: trip-crit {
> +            temperature = <100000>;
> +            hysteresis = <2000>;
> +            type = "critical";
> +          };
> +        };
> +      };
> +    };
> diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
> new file mode 100644
> index 000000000000..902d5b1e4f43
> --- /dev/null
> +++ b/include/dt-bindings/thermal/mediatek-lvts.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: (GPL-2.0 or MIT) */
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + * Author: Balsam CHIHI <bchihi@baylibre.com>
> + */
> +
> +#ifndef __MEDIATEK_LVTS_DT_H
> +#define __MEDIATEK_LVTS_DT_H
> +
> +#define MT8195_MCU_BIG_CPU0	0
> +#define MT8195_MCU_BIG_CPU1	1
> +#define MT8195_MCU_BIG_CPU2	2
> +#define MT8195_MCU_BIG_CPU3	3
> +#define MT8195_MCU_LITTLE_CPU0	4
> +#define MT8195_MCU_LITTLE_CPU1	5
> +#define MT8195_MCU_LITTLE_CPU2	6
> +#define MT8195_MCU_LITTLE_CPU3	7
> +
> +#endif /* __MEDIATEK_LVTS_DT_H */

-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-26 16:10   ` [PATCH v12 2/6] dt-bindings: thermal: mediatek: " bchihi
  2023-01-27 22:10     ` Daniel Lezcano
@ 2023-01-28 10:48     ` Krzysztof Kozlowski
  2023-01-30 10:40       ` Balsam CHIHI
  2023-01-31 14:04     ` [PATCH v3] dt-bindings: thermal: mediatek: Add LVTS thermal controllers bchihi
  2023-03-07 13:42     ` [PATCH] thermal/drivers/mediatek/lvts_thermal: fix memcpy's number of bytes in lvts_calibration_init() bchihi
  3 siblings, 1 reply; 57+ messages in thread
From: Krzysztof Kozlowski @ 2023-01-28 10:48 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

On 26/01/2023 17:10, bchihi@baylibre.com wrote:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> Add LVTS thermal controllers dt-binding definition for mt8195.

Subject: drop second/last, redundant "dt-binding definition". The
"dt-bindings" prefix is already stating that these are bindings.

Plus two comments at the end.

> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> ---
> Changelog:
>   v12:
>      - Fixed subject prefix
>      - Fixed licences GPL-2.0+ to GPL-2.0
>      - Added dual licenses


> +    };
> diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
> new file mode 100644
> index 000000000000..902d5b1e4f43
> --- /dev/null
> +++ b/include/dt-bindings/thermal/mediatek-lvts.h

Same filename as bindings.

> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: (GPL-2.0 or MIT) */

Although this is correct, any reason why not using exactly the same
license as bindings?

> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + * Author: Balsam CHIHI <bchihi@baylibre.com>
> + */

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-27 22:10     ` Daniel Lezcano
@ 2023-01-28 10:50       ` Krzysztof Kozlowski
  2023-01-30 10:49         ` Balsam CHIHI
  0 siblings, 1 reply; 57+ messages in thread
From: Krzysztof Kozlowski @ 2023-01-28 10:50 UTC (permalink / raw)
  To: Daniel Lezcano, bchihi, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

On 27/01/2023 23:10, Daniel Lezcano wrote:
> 
> Hi Rob,
> 
> I think Balsam took into account your comments. Is it fine for you ?
> 

The patchset was not sent to us at all, so it is the second version we
see. Therefore it's not v12 for us. It's v2 and it still needs fixes.

I replied with minor comments (which could be fixed during applying) and
the license concern (which you rather cannot change while applying).

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-28 10:48     ` Krzysztof Kozlowski
@ 2023-01-30 10:40       ` Balsam CHIHI
  2023-01-30 11:18         ` Matthias Brugger
  2023-01-31 16:53         ` Krzysztof Kozlowski
  0 siblings, 2 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-01-30 10:40 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

Hi Krzysztof,

Thank you for the feedback.

On Sat, Jan 28, 2023 at 11:48 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 26/01/2023 17:10, bchihi@baylibre.com wrote:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> >
> > Add LVTS thermal controllers dt-binding definition for mt8195.
>
> Subject: drop second/last, redundant "dt-binding definition". The
> "dt-bindings" prefix is already stating that these are bindings.

fixed.
The patch title has been fixed as you suggested :
"dt-bindings: thermal: mediatek: Add LVTS thermal controllers"

>
> Plus two comments at the end.
>
> >
> > Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> > ---
> > Changelog:
> >   v12:
> >      - Fixed subject prefix
> >      - Fixed licences GPL-2.0+ to GPL-2.0
> >      - Added dual licenses
>
>
> > +    };
> > diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
> > new file mode 100644
> > index 000000000000..902d5b1e4f43
> > --- /dev/null
> > +++ b/include/dt-bindings/thermal/mediatek-lvts.h
>
> Same filename as bindings.

fixed.
rename :
include/dt-bindings/thermal/mediatek-lvts.h =>
include/dt-bindings/thermal/mediatek-lvts-thermal.h

>
> > @@ -0,0 +1,19 @@
> > +/* SPDX-License-Identifier: (GPL-2.0 or MIT) */
>
> Although this is correct, any reason why not using exactly the same
> license as bindings?

fixed.
both files are now using the same license :
"SPDX-License-Identifier: (GPL-2.0 or MIT)"

>
> > +/*
> > + * Copyright (c) 2023 MediaTek Inc.
> > + * Author: Balsam CHIHI <bchihi@baylibre.com>
> > + */
>
> Best regards,
> Krzysztof
>

I'll send the changes soon.

Best regards,
Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-28 10:50       ` Krzysztof Kozlowski
@ 2023-01-30 10:49         ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-01-30 10:49 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Daniel Lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

Hi Krzysztof,

On Sat, Jan 28, 2023 at 11:50 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 27/01/2023 23:10, Daniel Lezcano wrote:
> >
> > Hi Rob,
> >
> > I think Balsam took into account your comments. Is it fine for you ?
> >
>
> The patchset was not sent to us at all, so it is the second version we
> see. Therefore it's not v12 for us. It's v2 and it still needs fixes.
>
> I replied with minor comments (which could be fixed during applying) and
> the license concern (which you rather cannot change while applying).

I apologize for forgetting to add some email addresses while sending
previous versions.
The changes you asked in your preview comment are taken in account and
ready to be sent.
Please let me know what version number should the patch have.

>
> Best regards,
> Krzysztof
>

Best regards,
Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-30 10:40       ` Balsam CHIHI
@ 2023-01-30 11:18         ` Matthias Brugger
  2023-01-30 12:19           ` Balsam CHIHI
  2023-01-31 16:53         ` Krzysztof Kozlowski
  1 sibling, 1 reply; 57+ messages in thread
From: Matthias Brugger @ 2023-01-30 11:18 UTC (permalink / raw)
  To: Balsam CHIHI, Krzysztof Kozlowski
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen,
	p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen



On 30/01/2023 11:40, Balsam CHIHI wrote:
> Hi Krzysztof,
> 
> Thank you for the feedback.
> 
> On Sat, Jan 28, 2023 at 11:48 AM Krzysztof Kozlowski
> <krzysztof.kozlowski@linaro.org> wrote:
>>
>> On 26/01/2023 17:10, bchihi@baylibre.com wrote:
>>> From: Balsam CHIHI <bchihi@baylibre.com>
>>>
>>> Add LVTS thermal controllers dt-binding definition for mt8195.
>>
>> Subject: drop second/last, redundant "dt-binding definition". The
>> "dt-bindings" prefix is already stating that these are bindings.
> 
> fixed.
> The patch title has been fixed as you suggested :
> "dt-bindings: thermal: mediatek: Add LVTS thermal controllers"
> 
>>
>> Plus two comments at the end.
>>
>>>
>>> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
>>> ---
>>> Changelog:
>>>    v12:
>>>       - Fixed subject prefix
>>>       - Fixed licences GPL-2.0+ to GPL-2.0
>>>       - Added dual licenses
>>
>>
>>> +    };
>>> diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
>>> new file mode 100644
>>> index 000000000000..902d5b1e4f43
>>> --- /dev/null
>>> +++ b/include/dt-bindings/thermal/mediatek-lvts.h
>>
>> Same filename as bindings.
> 
> fixed.
> rename :
> include/dt-bindings/thermal/mediatek-lvts.h =>
> include/dt-bindings/thermal/mediatek-lvts-thermal.h
> 

I think it should be
include/dt-bindings/thermal/mediatek,lvts-thermal.yaml

Regards,
Matthias

>>
>>> @@ -0,0 +1,19 @@
>>> +/* SPDX-License-Identifier: (GPL-2.0 or MIT) */
>>
>> Although this is correct, any reason why not using exactly the same
>> license as bindings?
> 
> fixed.
> both files are now using the same license :
> "SPDX-License-Identifier: (GPL-2.0 or MIT)"
> 
>>
>>> +/*
>>> + * Copyright (c) 2023 MediaTek Inc.
>>> + * Author: Balsam CHIHI <bchihi@baylibre.com>
>>> + */
>>
>> Best regards,
>> Krzysztof
>>
> 
> I'll send the changes soon.
> 
> Best regards,
> Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-30 11:18         ` Matthias Brugger
@ 2023-01-30 12:19           ` Balsam CHIHI
  2023-01-30 16:07             ` Matthias Brugger
  0 siblings, 1 reply; 57+ messages in thread
From: Balsam CHIHI @ 2023-01-30 12:19 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Krzysztof Kozlowski, daniel.lezcano, angelogioacchino.delregno,
	rafael, amitk, rui.zhang, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

Hi Matthias,

On Mon, Jan 30, 2023 at 12:18 PM Matthias Brugger
<matthias.bgg@gmail.com> wrote:
>
>
>
> On 30/01/2023 11:40, Balsam CHIHI wrote:
> > Hi Krzysztof,
> >
> > Thank you for the feedback.
> >
> > On Sat, Jan 28, 2023 at 11:48 AM Krzysztof Kozlowski
> > <krzysztof.kozlowski@linaro.org> wrote:
> >>
> >> On 26/01/2023 17:10, bchihi@baylibre.com wrote:
> >>> From: Balsam CHIHI <bchihi@baylibre.com>
> >>>
> >>> Add LVTS thermal controllers dt-binding definition for mt8195.
> >>
> >> Subject: drop second/last, redundant "dt-binding definition". The
> >> "dt-bindings" prefix is already stating that these are bindings.
> >
> > fixed.
> > The patch title has been fixed as you suggested :
> > "dt-bindings: thermal: mediatek: Add LVTS thermal controllers"
> >
> >>
> >> Plus two comments at the end.
> >>
> >>>
> >>> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> >>> ---
> >>> Changelog:
> >>>    v12:
> >>>       - Fixed subject prefix
> >>>       - Fixed licences GPL-2.0+ to GPL-2.0
> >>>       - Added dual licenses
> >>
> >>
> >>> +    };
> >>> diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
> >>> new file mode 100644
> >>> index 000000000000..902d5b1e4f43
> >>> --- /dev/null
> >>> +++ b/include/dt-bindings/thermal/mediatek-lvts.h
> >>
> >> Same filename as bindings.
> >
> > fixed.
> > rename :
> > include/dt-bindings/thermal/mediatek-lvts.h =>
> > include/dt-bindings/thermal/mediatek-lvts-thermal.h
> >
>
> I think it should be
> include/dt-bindings/thermal/mediatek,lvts-thermal.yaml

OK,
I will change it like that.
(".h" and not ".yaml" I believe (just to be sure).).

>
> Regards,
> Matthias
>
> >>
> >>> @@ -0,0 +1,19 @@
> >>> +/* SPDX-License-Identifier: (GPL-2.0 or MIT) */
> >>
> >> Although this is correct, any reason why not using exactly the same
> >> license as bindings?
> >
> > fixed.
> > both files are now using the same license :
> > "SPDX-License-Identifier: (GPL-2.0 or MIT)"
> >
> >>
> >>> +/*
> >>> + * Copyright (c) 2023 MediaTek Inc.
> >>> + * Author: Balsam CHIHI <bchihi@baylibre.com>
> >>> + */
> >>
> >> Best regards,
> >> Krzysztof
> >>
> >
> > I'll send the changes soon.
> >
> > Best regards,
> > Balsam

Best regards,
Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-30 12:19           ` Balsam CHIHI
@ 2023-01-30 16:07             ` Matthias Brugger
  0 siblings, 0 replies; 57+ messages in thread
From: Matthias Brugger @ 2023-01-30 16:07 UTC (permalink / raw)
  To: Balsam CHIHI
  Cc: Krzysztof Kozlowski, daniel.lezcano, angelogioacchino.delregno,
	rafael, amitk, rui.zhang, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen



On 30/01/2023 13:19, Balsam CHIHI wrote:
> Hi Matthias,
> 
> On Mon, Jan 30, 2023 at 12:18 PM Matthias Brugger
> <matthias.bgg@gmail.com> wrote:
>>
>>
>>
>> On 30/01/2023 11:40, Balsam CHIHI wrote:
>>> Hi Krzysztof,
>>>
>>> Thank you for the feedback.
>>>
>>> On Sat, Jan 28, 2023 at 11:48 AM Krzysztof Kozlowski
>>> <krzysztof.kozlowski@linaro.org> wrote:
>>>>
>>>> On 26/01/2023 17:10, bchihi@baylibre.com wrote:
>>>>> From: Balsam CHIHI <bchihi@baylibre.com>
>>>>>
>>>>> Add LVTS thermal controllers dt-binding definition for mt8195.
>>>>
>>>> Subject: drop second/last, redundant "dt-binding definition". The
>>>> "dt-bindings" prefix is already stating that these are bindings.
>>>
>>> fixed.
>>> The patch title has been fixed as you suggested :
>>> "dt-bindings: thermal: mediatek: Add LVTS thermal controllers"
>>>
>>>>
>>>> Plus two comments at the end.
>>>>
>>>>>
>>>>> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
>>>>> ---
>>>>> Changelog:
>>>>>     v12:
>>>>>        - Fixed subject prefix
>>>>>        - Fixed licences GPL-2.0+ to GPL-2.0
>>>>>        - Added dual licenses
>>>>
>>>>
>>>>> +    };
>>>>> diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
>>>>> new file mode 100644
>>>>> index 000000000000..902d5b1e4f43
>>>>> --- /dev/null
>>>>> +++ b/include/dt-bindings/thermal/mediatek-lvts.h
>>>>
>>>> Same filename as bindings.
>>>
>>> fixed.
>>> rename :
>>> include/dt-bindings/thermal/mediatek-lvts.h =>
>>> include/dt-bindings/thermal/mediatek-lvts-thermal.h
>>>
>>
>> I think it should be
>> include/dt-bindings/thermal/mediatek,lvts-thermal.yaml
> 
> OK,
> I will change it like that.
> (".h" and not ".yaml" I believe (just to be sure).).
> 

Yes sure, .h. Sorry for the confusion.

Regards,
Matthias

>>
>> Regards,
>> Matthias
>>
>>>>
>>>>> @@ -0,0 +1,19 @@
>>>>> +/* SPDX-License-Identifier: (GPL-2.0 or MIT) */
>>>>
>>>> Although this is correct, any reason why not using exactly the same
>>>> license as bindings?
>>>
>>> fixed.
>>> both files are now using the same license :
>>> "SPDX-License-Identifier: (GPL-2.0 or MIT)"
>>>
>>>>
>>>>> +/*
>>>>> + * Copyright (c) 2023 MediaTek Inc.
>>>>> + * Author: Balsam CHIHI <bchihi@baylibre.com>
>>>>> + */
>>>>
>>>> Best regards,
>>>> Krzysztof
>>>>
>>>
>>> I'll send the changes soon.
>>>
>>> Best regards,
>>> Balsam
> 
> Best regards,
> Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH v3] dt-bindings: thermal: mediatek: Add LVTS thermal controllers
  2023-01-26 16:10   ` [PATCH v12 2/6] dt-bindings: thermal: mediatek: " bchihi
  2023-01-27 22:10     ` Daniel Lezcano
  2023-01-28 10:48     ` Krzysztof Kozlowski
@ 2023-01-31 14:04     ` bchihi
  2023-02-01  7:46       ` Krzysztof Kozlowski
  2023-03-07 13:42     ` [PATCH] thermal/drivers/mediatek/lvts_thermal: fix memcpy's number of bytes in lvts_calibration_init() bchihi
  3 siblings, 1 reply; 57+ messages in thread
From: bchihi @ 2023-01-31 14:04 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

Add LVTS thermal controllers dt-binding definition for mt8195.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
---
Changelog:
  v3:
     - Fixed subject prefix
     - Fixed licenses GPL-2.0-only OR BSD-2-Clause
       to GPL-2.0 OR MIT (to match DT)
     - Fixed matching dt-binding file names
  v2:
     - Fixed subject prefix
     - Fixed licenses GPL-2.0+ to GPL-2.0
     - Added dual licenses
---
---
 .../thermal/mediatek,lvts-thermal.yaml        | 107 ++++++++++++++++++
 .../thermal/mediatek,lvts-thermal.h           |  19 ++++
 2 files changed, 126 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
 create mode 100644 include/dt-bindings/thermal/mediatek,lvts-thermal.h

diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
new file mode 100644
index 000000000000..5fa5c7a1a417
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0 OR MIT)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
+
+maintainers:
+  - Balsam CHIHI <bchihi@baylibre.com>
+
+description: |
+  LVTS is a thermal management architecture composed of three subsystems,
+  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
+  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
+  a Digital controller (LVTS_CTRL).
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8195-lvts-ap
+      - mediatek,mt8195-lvts-mcu
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+    description: LVTS reset for clearing temporary data on AP/MCU.
+
+  nvmem-cells:
+    minItems: 1
+    items:
+      - description: Calibration eFuse data 1 for LVTS
+      - description: Calibration eFuse data 2 for LVTS
+
+  nvmem-cell-names:
+    minItems: 1
+    items:
+      - const: lvts-calib-data-1
+      - const: lvts-calib-data-2
+
+  "#thermal-sensor-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+  - nvmem-cells
+  - nvmem-cell-names
+  - "#thermal-sensor-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/reset/mt8195-resets.h>
+    #include <dt-bindings/thermal/mediatek,lvts-thermal.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      lvts_mcu: thermal-sensor@11278000 {
+        compatible = "mediatek,mt8195-lvts-mcu";
+        reg = <0 0x11278000 0 0x1000>;
+        interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
+        resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
+        nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
+        nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
+        #thermal-sensor-cells = <1>;
+      };
+    };
+
+    thermal_zones: thermal-zones {
+      cpu0-thermal {
+        polling-delay = <1000>;
+        polling-delay-passive = <250>;
+        thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
+
+        trips {
+          cpu0_alert: trip-alert {
+            temperature = <85000>;
+            hysteresis = <2000>;
+            type = "passive";
+          };
+
+          cpu0_crit: trip-crit {
+            temperature = <100000>;
+            hysteresis = <2000>;
+            type = "critical";
+          };
+        };
+      };
+    };
diff --git a/include/dt-bindings/thermal/mediatek,lvts-thermal.h b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
new file mode 100644
index 000000000000..ca1ef29a8fee
--- /dev/null
+++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Balsam CHIHI <bchihi@baylibre.com>
+ */
+
+#ifndef __MEDIATEK_LVTS_DT_H
+#define __MEDIATEK_LVTS_DT_H
+
+#define MT8195_MCU_BIG_CPU0		0
+#define MT8195_MCU_BIG_CPU1		1
+#define MT8195_MCU_BIG_CPU2		2
+#define MT8195_MCU_BIG_CPU3		3
+#define MT8195_MCU_LITTLE_CPU0	4
+#define MT8195_MCU_LITTLE_CPU1	5
+#define MT8195_MCU_LITTLE_CPU2	6
+#define MT8195_MCU_LITTLE_CPU3	7
+
+#endif /* __MEDIATEK_LVTS_DT_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v12] arm64: dts: mediatek: mt8195: Add thermal zones and thermal nodes
  2023-01-24 13:17 ` [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes bchihi
  2023-01-24 15:36   ` AngeloGioacchino Del Regno
@ 2023-01-31 15:37   ` bchihi
  1 sibling, 0 replies; 57+ messages in thread
From: bchihi @ 2023-01-31 15:37 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

Add thermal zones and thermal nodes for the mt8195.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
Changelog:
v12:
     - Fixed subject prefix
     - Rename "include/dt-bindings/thermal/mediatek-lvts.h"
       to "include/dt-bindings/thermal/mediatek,lvts-thermal.h"
       due to this patch
       https://lore.kernel.org/all/20230131140439.600164-1-bchihi@baylibre.com/
---
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 129 +++++++++++++++++++++++
 1 file changed, 129 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 09df105f4606..c7e958f8f1b5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -14,6 +14,7 @@
 #include <dt-bindings/pinctrl/mt8195-pinfunc.h>
 #include <dt-bindings/power/mt8195-power.h>
 #include <dt-bindings/reset/mt8195-resets.h>
+#include <dt-bindings/thermal/mediatek,lvts-thermal.h>
 
 / {
 	compatible = "mediatek,mt8195";
@@ -954,6 +955,17 @@ spi0: spi@1100a000 {
 			status = "disabled";
 		};
 
+		lvts_ap: thermal-sensor@1100b000 {
+			compatible = "mediatek,mt8195-lvts-ap";
+			reg = <0 0x1100b000 0 0x1000>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
+			resets = <&infracfg_ao MT8195_INFRA_RST0_THERM_CTRL_SWRST>;
+			nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
+			nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
+			#thermal-sensor-cells = <1>;
+		};
+
 		spi1: spi@11010000 {
 			compatible = "mediatek,mt8195-spi",
 				     "mediatek,mt6765-spi";
@@ -1114,6 +1126,17 @@ mmc2: mmc@11250000 {
 			status = "disabled";
 		};
 
+		lvts_mcu: thermal-sensor@11278000 {
+			compatible = "mediatek,mt8195-lvts-mcu";
+			reg = <0 0x11278000 0 0x1000>;
+			interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
+			resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
+			nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
+			nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
+			#thermal-sensor-cells = <1>;
+		};
+
 		xhci1: usb@11290000 {
 			compatible = "mediatek,mt8195-xhci",
 				     "mediatek,mtk-xhci";
@@ -2387,4 +2410,110 @@ dp_tx: dp-tx@1c600000 {
 			status = "disabled";
 		};
 	};
+
+	thermal_zones: thermal-zones {
+		cpu0-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
+			trips {
+				cpu0_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu1-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU1>;
+			trips {
+				cpu1_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu2-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU2>;
+			trips {
+				cpu2_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu3-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU3>;
+			trips {
+				cpu3_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu4-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU0>;
+			trips {
+				cpu4_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu5-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU1>;
+			trips {
+				cpu5_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu6-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU2>;
+			trips {
+				cpu6_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu7-thermal {
+			polling-delay = <0>;
+			polling-delay-passive = <0>;
+			thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU3>;
+			trips {
+				cpu7_crit: trip-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
 };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-01-24 13:17 ` [PATCH v11 4/6] thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver bchihi
  2023-01-24 15:31   ` AngeloGioacchino Del Regno
@ 2023-01-31 15:38   ` bchihi
  2023-02-01  3:09     ` kernel test robot
  2023-02-01  7:55     ` Krzysztof Kozlowski
  1 sibling, 2 replies; 57+ messages in thread
From: bchihi @ 2023-01-31 15:38 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
controllers contained in a thermal domain.

A thermal domains can be the MCU or the AP.

Each thermal domains contain up to seven controllers, each thermal
controller handle up to four thermal sensors.

The LVTS has two Finite State Machines (FSM), one to handle the
functionin temperatures range like hot or cold temperature and another
one to handle monitoring trip point. The FSM notifies via interrupts
when a trip point is crossed.

The interrupt is managed at the thermal controller level, so when an
interrupt occurs, the driver has to find out which sensor triggered
such an interrupt.

The sampling of the thermal can be filtered or immediate. For the
former, the LVTS measures several points and applies a low pass
filter.

Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

On MT8195 Tomato Chromebook:
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
Changelog:
  v12:
     - Fixed subject prefix
     - Rename "include/dt-bindings/thermal/mediatek-lvts.h"
       to "include/dt-bindings/thermal/mediatek,lvts-thermal.h"
       due to this patch
       https://lore.kernel.org/all/20230131140439.600164-1-bchihi@baylibre.com/
---
---
 drivers/thermal/mediatek/Kconfig        |   16 +
 drivers/thermal/mediatek/Makefile       |    1 +
 drivers/thermal/mediatek/lvts_thermal.c | 1261 +++++++++++++++++++++++
 3 files changed, 1278 insertions(+)
 create mode 100644 drivers/thermal/mediatek/lvts_thermal.c

diff --git a/drivers/thermal/mediatek/Kconfig b/drivers/thermal/mediatek/Kconfig
index 7558a847d4e9..d82c86d9be56 100644
--- a/drivers/thermal/mediatek/Kconfig
+++ b/drivers/thermal/mediatek/Kconfig
@@ -18,4 +18,20 @@ config MTK_SOC_THERMAL
 	  This driver configures thermal controllers to collect
 	  temperature via AUXADC interface.
 
+config MTK_LVTS_THERMAL
+        tristate "LVTS Thermal Driver for MediaTek SoCs"
+        depends on HAS_IOMEM
+        help
+          Enable this option if you want to get SoC temperature
+          information for supported MediaTek platforms.
+          This driver configures LVTS (Low Voltage Thermal Sensor)
+          thermal controllers to collect temperatures via ASIF
+          (Analog Serial Interface).
+
+config MTK_LVTS_THERMAL_DEBUGFS
+       bool "LVTS thermal debugfs"
+       depends on MTK_LVTS_THERMAL && DEBUG_FS
+       help
+         Enable this option to debug the internals of the device driver.
+
 endif
diff --git a/drivers/thermal/mediatek/Makefile b/drivers/thermal/mediatek/Makefile
index 53e86e30b26f..1c6daa1e644b 100644
--- a/drivers/thermal/mediatek/Makefile
+++ b/drivers/thermal/mediatek/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_MTK_SOC_THERMAL)	+= auxadc_thermal.o
+obj-$(CONFIG_MTK_LVTS_THERMAL)	+= lvts_thermal.o
diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
new file mode 100644
index 000000000000..29cb337c38d4
--- /dev/null
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -0,0 +1,1261 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Balsam CHIHI <bchihi@baylibre.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/thermal.h>
+#include <dt-bindings/thermal/mediatek,lvts-thermal.h>
+
+#define LVTS_MONCTL0(__base)	(__base + 0x0000)
+#define LVTS_MONCTL1(__base)	(__base + 0x0004)
+#define LVTS_MONCTL2(__base)	(__base + 0x0008)
+#define LVTS_MONINT(__base)		(__base + 0x000C)
+#define LVTS_MONINTSTS(__base)	(__base + 0x0010)
+#define LVTS_MONIDET0(__base)	(__base + 0x0014)
+#define LVTS_MONIDET1(__base)	(__base + 0x0018)
+#define LVTS_MONIDET2(__base)	(__base + 0x001C)
+#define LVTS_MONIDET3(__base)	(__base + 0x0020)
+#define LVTS_H2NTHRE(__base)	(__base + 0x0024)
+#define LVTS_HTHRE(__base)		(__base + 0x0028)
+#define LVTS_OFFSETH(__base)	(__base + 0x0030)
+#define LVTS_OFFSETL(__base)	(__base + 0x0034)
+#define LVTS_MSRCTL0(__base)	(__base + 0x0038)
+#define LVTS_MSRCTL1(__base)	(__base + 0x003C)
+#define LVTS_TSSEL(__base)		(__base + 0x0040)
+#define LVTS_CALSCALE(__base)	(__base + 0x0048)
+#define LVTS_ID(__base)			(__base + 0x004C)
+#define LVTS_CONFIG(__base)		(__base + 0x0050)
+#define LVTS_EDATA00(__base)	(__base + 0x0054)
+#define LVTS_EDATA01(__base)	(__base + 0x0058)
+#define LVTS_EDATA02(__base)	(__base + 0x005C)
+#define LVTS_EDATA03(__base)	(__base + 0x0060)
+#define LVTS_MSR0(__base)		(__base + 0x0090)
+#define LVTS_MSR1(__base)		(__base + 0x0094)
+#define LVTS_MSR2(__base)		(__base + 0x0098)
+#define LVTS_MSR3(__base)		(__base + 0x009C)
+#define LVTS_IMMD0(__base)		(__base + 0x00A0)
+#define LVTS_IMMD1(__base)		(__base + 0x00A4)
+#define LVTS_IMMD2(__base)		(__base + 0x00A8)
+#define LVTS_IMMD3(__base)		(__base + 0x00AC)
+#define LVTS_PROTCTL(__base)	(__base + 0x00C0)
+#define LVTS_PROTTA(__base)		(__base + 0x00C4)
+#define LVTS_PROTTB(__base)		(__base + 0x00C8)
+#define LVTS_PROTTC(__base)		(__base + 0x00CC)
+#define LVTS_CLKEN(__base)		(__base + 0x00E4)
+
+#define LVTS_PERIOD_UNIT			((118 * 1000) / (256 * 38))
+#define LVTS_GROUP_INTERVAL			1
+#define LVTS_FILTER_INTERVAL		1
+#define LVTS_SENSOR_INTERVAL		1
+#define LVTS_HW_FILTER				0x2
+#define LVTS_TSSEL_CONF				0x13121110
+#define LVTS_CALSCALE_CONF			0x300
+#define LVTS_MONINT_CONF			0x9FBF7BDE
+
+#define LVTS_INT_SENSOR0			0x0009001F
+#define LVTS_INT_SENSOR1			0X000881F0
+#define LVTS_INT_SENSOR2			0x00247C00
+#define LVTS_INT_SENSOR3			0x1FC00000
+
+#define LVTS_SENSOR_MAX				4
+#define LVTS_GOLDEN_TEMP_MAX		62
+#define LVTS_GOLDEN_TEMP_DEFAULT	50
+#define LVTS_COEFF_A				-250460
+#define LVTS_COEFF_B				250460
+
+#define LVTS_MSR_IMMEDIATE_MODE		0
+#define LVTS_MSR_FILTERED_MODE		1
+
+#define LVTS_HW_SHUTDOWN_MT8195		105000
+
+static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
+static int coeff_b = LVTS_COEFF_B;
+
+struct lvts_sensor_data {
+	int dt_id;
+};
+
+struct lvts_ctrl_data {
+	struct lvts_sensor_data lvts_sensor[LVTS_SENSOR_MAX];
+	int cal_offset[LVTS_SENSOR_MAX];
+	int hw_tshut_temp;
+	int num_lvts_sensor;
+	int offset;
+	int mode;
+};
+
+struct lvts_data {
+	struct lvts_ctrl_data *lvts_ctrl;
+	int num_lvts_ctrl;
+};
+
+struct lvts_sensor {
+	struct thermal_zone_device *tz;
+	void __iomem *msr;
+	void __iomem *base;
+	int id;
+	int dt_id;
+};
+
+struct lvts_ctrl {
+	struct lvts_sensor sensors[LVTS_SENSOR_MAX];
+	u32 calibration[LVTS_SENSOR_MAX];
+	u32 hw_tshut_raw_temp;
+	int num_lvts_sensor;
+	int mode;
+	void __iomem *base;
+};
+
+struct lvts_domain {
+	struct lvts_ctrl *lvts_ctrl;
+	struct reset_control *reset;
+	struct clk *clk;
+	int num_lvts_ctrl;
+	void __iomem *base;
+	size_t calib_len;
+	u8 *calib;
+};
+
+#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
+
+static struct dentry *root;
+
+#define LVTS_DEBUG_FS_REGS(__reg)		\
+{						\
+	.name = __stringify(__reg),		\
+	.offset = __reg(0),			\
+}
+
+static const struct debugfs_reg32 lvts_regs[] = {
+	LVTS_DEBUG_FS_REGS(LVTS_MONCTL0),
+	LVTS_DEBUG_FS_REGS(LVTS_MONCTL1),
+	LVTS_DEBUG_FS_REGS(LVTS_MONCTL2),
+	LVTS_DEBUG_FS_REGS(LVTS_MONINT),
+	LVTS_DEBUG_FS_REGS(LVTS_MONINTSTS),
+	LVTS_DEBUG_FS_REGS(LVTS_MONIDET0),
+	LVTS_DEBUG_FS_REGS(LVTS_MONIDET1),
+	LVTS_DEBUG_FS_REGS(LVTS_MONIDET2),
+	LVTS_DEBUG_FS_REGS(LVTS_MONIDET3),
+	LVTS_DEBUG_FS_REGS(LVTS_H2NTHRE),
+	LVTS_DEBUG_FS_REGS(LVTS_HTHRE),
+	LVTS_DEBUG_FS_REGS(LVTS_OFFSETH),
+	LVTS_DEBUG_FS_REGS(LVTS_OFFSETL),
+	LVTS_DEBUG_FS_REGS(LVTS_MSRCTL0),
+	LVTS_DEBUG_FS_REGS(LVTS_MSRCTL1),
+	LVTS_DEBUG_FS_REGS(LVTS_TSSEL),
+	LVTS_DEBUG_FS_REGS(LVTS_CALSCALE),
+	LVTS_DEBUG_FS_REGS(LVTS_ID),
+	LVTS_DEBUG_FS_REGS(LVTS_CONFIG),
+	LVTS_DEBUG_FS_REGS(LVTS_EDATA00),
+	LVTS_DEBUG_FS_REGS(LVTS_EDATA01),
+	LVTS_DEBUG_FS_REGS(LVTS_EDATA02),
+	LVTS_DEBUG_FS_REGS(LVTS_EDATA03),
+	LVTS_DEBUG_FS_REGS(LVTS_MSR0),
+	LVTS_DEBUG_FS_REGS(LVTS_MSR1),
+	LVTS_DEBUG_FS_REGS(LVTS_MSR2),
+	LVTS_DEBUG_FS_REGS(LVTS_MSR3),
+	LVTS_DEBUG_FS_REGS(LVTS_IMMD0),
+	LVTS_DEBUG_FS_REGS(LVTS_IMMD1),
+	LVTS_DEBUG_FS_REGS(LVTS_IMMD2),
+	LVTS_DEBUG_FS_REGS(LVTS_IMMD3),
+	LVTS_DEBUG_FS_REGS(LVTS_PROTCTL),
+	LVTS_DEBUG_FS_REGS(LVTS_PROTTA),
+	LVTS_DEBUG_FS_REGS(LVTS_PROTTB),
+	LVTS_DEBUG_FS_REGS(LVTS_PROTTC),
+	LVTS_DEBUG_FS_REGS(LVTS_CLKEN),
+};
+
+static int lvts_debugfs_init(struct device *dev,
+			     struct lvts_domain *lvts_td)
+{
+	struct debugfs_regset32 *regset;
+	struct lvts_ctrl *lvts_ctrl;
+	struct dentry *dentry;
+	struct dentry *dom_dentry;
+	char name[64];
+	int i;
+
+	if (!root)
+		root = debugfs_create_dir("lvts", NULL);
+
+	dom_dentry = debugfs_create_dir(dev_name(dev), root);
+	if (!dom_dentry)
+		return 0;
+
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+
+		lvts_ctrl = &lvts_td->lvts_ctrl[i];
+
+		sprintf(name, "controller%d", i);
+		dentry = debugfs_create_dir(name, dom_dentry);
+		if (!dentry)
+			continue;
+
+		regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
+		if (!regset)
+			continue;
+
+		regset->base = lvts_ctrl->base;
+		regset->regs = lvts_regs;
+		regset->nregs = ARRAY_SIZE(lvts_regs);
+
+		debugfs_create_regset32("registers", 0400, dentry, regset);
+	}
+
+	return 0;
+}
+
+static void lvts_debugfs_exit(void)
+{
+	debugfs_remove_recursive(root);
+}
+
+#else
+
+static inline int lvts_debugfs_init(struct device *dev,
+				    struct lvts_domain *lvts_td)
+{
+	return 0;
+}
+
+static void lvts_debugfs_exit(void) { }
+
+#endif
+
+static int lvts_raw_to_temp(u32 raw_temp)
+{
+	int temperature;
+
+	temperature = ((s64)(raw_temp & 0xFFFF) * LVTS_COEFF_A) >> 14;
+	temperature += coeff_b;
+
+	return temperature;
+}
+
+static u32 lvts_temp_to_raw(int temperature)
+{
+	u32 raw_temp = ((s64)(coeff_b - temperature)) << 14;
+
+	raw_temp = div_s64(raw_temp, -LVTS_COEFF_A);
+
+	return raw_temp;
+}
+
+static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+	struct lvts_sensor *lvts_sensor = tz->devdata;
+	void __iomem *msr = lvts_sensor->msr;
+	u32 value;
+
+	/*
+	 * Measurement registers:
+	 *
+	 * LVTS_MSR[0-3] / LVTS_IMMD[0-3]
+	 *
+	 * Bits:
+	 *
+	 * 32-17: Unused
+	 * 16	: Valid temperature
+	 * 15-0	: Raw temperature
+	 */
+	value = readl(msr);
+
+	/*
+	 * As the thermal zone temperature will read before the
+	 * hardware sensor is fully initialized, we have to check the
+	 * validity of the temperature returned when reading the
+	 * measurement register. The thermal controller will set the
+	 * valid bit temperature only when it is totally initialized.
+	 *
+	 * Otherwise, we may end up with garbage values out of the
+	 * functionning temperature and directly jump to a system
+	 * shutdown.
+	 */
+	if (!(value & BIT(16)))
+		return -EAGAIN;
+
+	*temp = lvts_raw_to_temp(value & 0xFFFF);
+
+	return 0;
+}
+
+static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+{
+	struct lvts_sensor *lvts_sensor = tz->devdata;
+	void __iomem *base = lvts_sensor->base;
+	u32 raw_low = lvts_temp_to_raw(low);
+	u32 raw_high = lvts_temp_to_raw(high);
+
+	/*
+	 * Hot to normal temperature threshold
+	 *
+	 * LVTS_H2NTHRE
+	 *
+	 * Bits:
+	 *
+	 * 14-0 : Raw temperature for threshold
+	 */
+	if (low != -INT_MAX) {
+		dev_dbg(&tz->device, "Setting low limit temperature interrupt: %d\n", low);
+		writel(raw_low, LVTS_H2NTHRE(base));
+	}
+
+	/*
+	 * Hot temperature threshold
+	 *
+	 * LVTS_HTHRE
+	 *
+	 * Bits:
+	 *
+	 * 14-0 : Raw temperature for threshold
+	 */
+	dev_dbg(&tz->device, "Setting high limit temperature interrupt: %d\n", high);
+	writel(raw_high, LVTS_HTHRE(base));
+
+	return 0;
+}
+
+static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
+{
+	irqreturn_t iret = IRQ_NONE;
+	u32 value, masks[] = {
+		LVTS_INT_SENSOR0,
+		LVTS_INT_SENSOR1,
+		LVTS_INT_SENSOR2,
+		LVTS_INT_SENSOR3
+	};
+	int i;
+
+	/*
+	 * Interrupt monitoring status
+	 *
+	 * LVTS_MONINTST
+	 *
+	 * Bits:
+	 *
+	 * 31 : Interrupt for stage 3
+	 * 30 : Interrupt for stage 2
+	 * 29 : Interrupt for state 1
+	 * 28 : Interrupt using filter on sensor 3
+	 *
+	 * 27 : Interrupt using immediate on sensor 3
+	 * 26 : Interrupt normal to hot on sensor 3
+	 * 25 : Interrupt high offset on sensor 3
+	 * 24 : Interrupt low offset on sensor 3
+	 *
+	 * 23 : Interrupt hot threshold on sensor 3
+	 * 22 : Interrupt cold threshold on sensor 3
+	 * 21 : Interrupt using filter on sensor 2
+	 * 20 : Interrupt using filter on sensor 1
+	 *
+	 * 19 : Interrupt using filter on sensor 0
+	 * 18 : Interrupt using immediate on sensor 2
+	 * 17 : Interrupt using immediate on sensor 1
+	 * 16 : Interrupt using immediate on sensor 0
+	 *
+	 * 15 : Interrupt device access timeout interrupt
+	 * 14 : Interrupt normal to hot on sensor 2
+	 * 13 : Interrupt high offset interrupt on sensor 2
+	 * 12 : Interrupt low offset interrupt on sensor 2
+	 *
+	 * 11 : Interrupt hot threshold on sensor 2
+	 * 10 : Interrupt cold threshold on sensor 2
+	 *  9 : Interrupt normal to hot on sensor 1
+	 *  8 : Interrupt high offset interrupt on sensor 1
+	 *
+	 *  7 : Interrupt low offset interrupt on sensor 1
+	 *  6 : Interrupt hot threshold on sensor 1
+	 *  5 : Interrupt cold threshold on sensor 1
+	 *  4 : Interrupt normal to hot on sensor 0
+	 *
+	 *  3 : Interrupt high offset interrupt on sensor 0
+	 *  2 : Interrupt low offset interrupt on sensor 0
+	 *  1 : Interrupt hot threshold on sensor 0
+	 *  0 : Interrupt cold threshold on sensor 0
+	 *
+	 * We are interested in the sensor(s) responsible of the
+	 * interrupt event. We update the thermal framework with the
+	 * thermal zone associated with the sensor. The framework will
+	 * take care of the rest whatever the kind of interrupt, we
+	 * are only interested in which sensor raised the interrupt.
+	 *
+	 * sensor 3 interrupt: 0001 1111 1100 0000 0000 0000 0000 0000
+	 *                  => 0x1FC00000
+	 * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000
+	 *                  => 0x00247C00
+	 * sensor 1 interrupt: 0000 0000 0001 0001 0000 0011 1110 0000
+	 *                  => 0X000881F0
+	 * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111
+	 *                  => 0x0009001F
+	 */
+	value = readl(LVTS_MONINTSTS(lvts_ctrl->base));
+
+	/*
+	 * Let's figure out which sensors raised the interrupt
+	 *
+	 * NOTE: the masks array must be ordered with the index
+	 * corresponding to the sensor id eg. index=0, mask for
+	 * sensor0.
+	 */
+	for (i = 0; i < ARRAY_SIZE(masks); i++) {
+
+		if (!(value & masks[i]))
+			continue;
+
+		thermal_zone_device_update(lvts_ctrl->sensors[i].tz,
+					   THERMAL_TRIP_VIOLATED);
+		iret = IRQ_HANDLED;
+	}
+
+	/*
+	 * Write back to clear the interrupt status (W1C)
+	 */
+	writel(value, LVTS_MONINTSTS(lvts_ctrl->base));
+
+	return iret;
+}
+
+/*
+ * Temperature interrupt handler. Even if the driver supports more
+ * interrupt modes, we use the interrupt when the temperature crosses
+ * the hot threshold the way up and the way down (modulo the
+ * hysteresis).
+ *
+ * Each thermal domain has a couple of interrupts, one for hardware
+ * reset and another one for all the thermal events happening on the
+ * different sensors.
+ *
+ * The interrupt is configured for thermal events when crossing the
+ * hot temperature limit. At each interrupt, we check in every
+ * controller if there is an interrupt pending.
+ */
+static irqreturn_t lvts_irq_handler(int irq, void *data)
+{
+	struct lvts_domain *lvts_td = data;
+	irqreturn_t aux, iret = IRQ_NONE;
+	int i;
+
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+
+		aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl);
+		if (aux != IRQ_HANDLED)
+			continue;
+
+		iret = IRQ_HANDLED;
+	}
+
+	return iret;
+}
+
+static struct thermal_zone_device_ops lvts_ops = {
+	.get_temp = lvts_get_temp,
+	.set_trips = lvts_set_trips,
+};
+
+static int __init lvts_sensor_init(struct device *dev,
+				   struct lvts_ctrl *lvts_ctrl,
+				   struct lvts_ctrl_data *lvts_ctrl_data)
+{
+	struct lvts_sensor *lvts_sensor = lvts_ctrl->sensors;
+	void __iomem *msr_regs[] = {
+		LVTS_MSR0(lvts_ctrl->base),
+		LVTS_MSR1(lvts_ctrl->base),
+		LVTS_MSR2(lvts_ctrl->base),
+		LVTS_MSR3(lvts_ctrl->base)
+	};
+
+	void __iomem *imm_regs[] = {
+		LVTS_IMMD0(lvts_ctrl->base),
+		LVTS_IMMD1(lvts_ctrl->base),
+		LVTS_IMMD2(lvts_ctrl->base),
+		LVTS_IMMD3(lvts_ctrl->base)
+	};
+
+	int i;
+
+	for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++) {
+
+		int dt_id = lvts_ctrl_data->lvts_sensor[i].dt_id;
+
+		/*
+		 * At this point, we don't know which id matches which
+		 * sensor. Let's set arbitrally the id from the index.
+		 */
+		lvts_sensor[i].id = i;
+
+		/*
+		 * The thermal zone registration will set the trip
+		 * point interrupt in the thermal controller
+		 * register. But this one will be reset in the
+		 * initialization after. So we need to post pone the
+		 * thermal zone creation after the controller is
+		 * setup. For this reason, we store the device tree
+		 * node id from the data in the sensor structure
+		 */
+		lvts_sensor[i].dt_id = dt_id;
+
+		/*
+		 * We assign the base address of the thermal
+		 * controller as a back pointer. So it will be
+		 * accessible from the different thermal framework ops
+		 * as we pass the lvts_sensor pointer as thermal zone
+		 * private data.
+		 */
+		lvts_sensor[i].base = lvts_ctrl->base;
+
+		/*
+		 * Each sensor has its own register address to read from.
+		 */
+		lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
+			imm_regs[i] : msr_regs[i];
+	};
+
+	lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
+
+	return 0;
+}
+
+/*
+ * The efuse blob values follows the sensor enumeration per thermal
+ * controller. The decoding of the stream is as follow:
+ *
+ *                        <--?-> <----big0 ???---> <-sensor0-> <-0->
+ *                        ------------------------------------------
+ * index in the stream: : | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 |
+ *                        ------------------------------------------
+ *
+ *                        <--sensor1--><-0-> <----big1 ???---> <-sen
+ *                        ------------------------------------------
+ *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
+ *                        ------------------------------------------
+ *
+ *                        sor0-> <-0-> <-sensor1-> <-0-> ..........
+ *                        ------------------------------------------
+ *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
+ *                        ------------------------------------------
+ *
+ * And so on ...
+ *
+ * The data description gives the offset of the calibration data in
+ * this bytes stream for each sensor.
+ *
+ * Each thermal controller can handle up to 4 sensors max, we don't
+ * care if there are less as the array of calibration is sized to 4
+ * anyway. The unused sensor slot will be zeroed.
+ */
+static int __init lvts_calibration_init(struct device *dev,
+					struct lvts_ctrl *lvts_ctrl,
+					struct lvts_ctrl_data *lvts_ctrl_data,
+					u8 *efuse_calibration)
+{
+	int i;
+
+	for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++)
+		memcpy(&lvts_ctrl->calibration[i],
+		       efuse_calibration + lvts_ctrl_data->cal_offset[i], 2);
+
+	return 0;
+}
+
+/*
+ * The efuse bytes stream can be split into different chunk of
+ * nvmems. This function reads and concatenate those into a single
+ * buffer so it can be read sequentially when initializing the
+ * calibration data.
+ */
+static int lvts_calibration_read(struct device *dev, struct lvts_domain *lvts_td,
+				 struct lvts_data *lvts_data)
+{
+	struct device_node *np = dev_of_node(dev);
+	struct nvmem_cell *cell;
+	struct property *prop;
+	const char *cell_name;
+
+	of_property_for_each_string(np, "nvmem-cell-names", prop, cell_name) {
+		size_t len;
+		u8 *efuse;
+
+		cell = of_nvmem_cell_get(np, cell_name);
+		if (IS_ERR(cell)) {
+			dev_dbg(dev, "Failed to get cell '%s'\n", cell_name);
+			return PTR_ERR(cell);
+		}
+
+		efuse = nvmem_cell_read(cell, &len);
+
+		nvmem_cell_put(cell);
+
+		if (IS_ERR(efuse)) {
+			dev_dbg(dev, "Failed to read cell '%s'\n", cell_name);
+			return PTR_ERR(efuse);
+		}
+
+		lvts_td->calib = devm_krealloc(dev, lvts_td->calib,
+					       lvts_td->calib_len + len, GFP_KERNEL);
+		if (!lvts_td->calib)
+			return -ENOMEM;
+
+		memcpy(lvts_td->calib + lvts_td->calib_len, efuse, len);
+
+		lvts_td->calib_len += len;
+
+		kfree(efuse);
+	}
+
+	return 0;
+}
+
+static int __init lvts_golden_temp_init(struct device *dev, u32 *value)
+{
+	u32 gt;
+
+	gt = (*value) >> 24;
+
+	if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
+		golden_temp = gt;
+
+	coeff_b = golden_temp * 500 + LVTS_COEFF_B;
+
+	return 0;
+}
+
+static int __init lvts_ctrl_init(struct device *dev,
+				 struct lvts_domain *lvts_td,
+				 struct lvts_data *lvts_data)
+{
+	size_t size = sizeof(*lvts_td->lvts_ctrl) * lvts_data->num_lvts_ctrl;
+	struct lvts_ctrl *lvts_ctrl;
+	int i, ret;
+
+	/*
+	 * Create the calibration bytes stream from efuse data
+	 */
+	ret = lvts_calibration_read(dev, lvts_td, lvts_data);
+	if (ret)
+		return ret;
+
+	/*
+	 * The golden temp information is contained in the first chunk
+	 * of efuse data.
+	 */
+	ret = lvts_golden_temp_init(dev, (u32 *)lvts_td->calib);
+	if (ret)
+		return ret;
+
+	lvts_ctrl = devm_kzalloc(dev, size, GFP_KERNEL);
+	if (!lvts_ctrl)
+		return -ENOMEM;
+
+	for (i = 0; i < lvts_data->num_lvts_ctrl; i++) {
+
+		lvts_ctrl[i].base = lvts_td->base + lvts_data->lvts_ctrl[i].offset;
+
+		ret = lvts_sensor_init(dev, &lvts_ctrl[i],
+				       &lvts_data->lvts_ctrl[i]);
+		if (ret)
+			return ret;
+
+		ret = lvts_calibration_init(dev, &lvts_ctrl[i],
+					    &lvts_data->lvts_ctrl[i],
+					    lvts_td->calib);
+		if (ret)
+			return ret;
+
+		/*
+		 * The mode the ctrl will use to read the temperature
+		 * (filtered or immediate)
+		 */
+		lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode;
+
+		/*
+		 * The temperature to raw temperature must be done
+		 * after initializing the calibration.
+		 */
+		lvts_ctrl[i].hw_tshut_raw_temp =
+			lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
+	}
+
+	/*
+	 * We no longer need the efuse bytes stream, let's free it
+	 */
+	devm_kfree(dev, lvts_td->calib);
+
+	lvts_td->lvts_ctrl = lvts_ctrl;
+	lvts_td->num_lvts_ctrl = lvts_data->num_lvts_ctrl;
+
+	return 0;
+}
+
+/*
+ * At this point the configuration register is the only place in the
+ * driver where we write multiple values. Per hardware constraint,
+ * each write in the configuration register must be separated by a
+ * delay of 2 us.
+ */
+static void lvts_write_config(struct lvts_ctrl *lvts_ctrl, u32 *cmds, int nr_cmds)
+{
+	int i;
+
+	/*
+	 * Configuration register
+	 */
+	for (i = 0; i < nr_cmds; i++) {
+		writel(cmds[i], LVTS_CONFIG(lvts_ctrl->base));
+		usleep_range(2, 4);
+	}
+}
+
+static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
+{
+	/*
+	 * LVTS_PROTCTL : Thermal Protection Sensor Selection
+	 *
+	 * Bits:
+	 *
+	 * 19-18 : Sensor to base the protection on
+	 * 17-16 : Strategy:
+	 *         00 : Average of 4 sensors
+	 *         01 : Max of 4 sensors
+	 *         10 : Selected sensor with bits 19-18
+	 *         11 : Reserved
+	 */
+	writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));
+
+	/*
+	 * LVTS_PROTTA : Stage 1 temperature threshold
+	 * LVTS_PROTTB : Stage 2 temperature threshold
+	 * LVTS_PROTTC : Stage 3 temperature threshold
+	 *
+	 * Bits:
+	 *
+	 * 14-0: Raw temperature threshold
+	 *
+	 * writel(0x0, LVTS_PROTTA(lvts_ctrl->base));
+	 * writel(0x0, LVTS_PROTTB(lvts_ctrl->base));
+	 */
+	writel(lvts_ctrl->hw_tshut_raw_temp, LVTS_PROTTC(lvts_ctrl->base));
+
+	/*
+	 * LVTS_MONINT : Interrupt configuration register
+	 *
+	 * The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS
+	 * register, except we set the bits to enable the interrupt.
+	 */
+	writel(LVTS_MONINT_CONF, LVTS_MONINT(lvts_ctrl->base));
+
+	return 0;
+}
+
+static int lvts_domain_reset(struct device *dev, struct reset_control *reset)
+{
+	int ret;
+
+	ret = reset_control_assert(reset);
+	if (ret)
+		return ret;
+
+	return reset_control_deassert(reset);
+}
+
+/*
+ * Enable or disable the clocks of a specified thermal controller
+ */
+static int lvts_ctrl_set_enable(struct lvts_ctrl *lvts_ctrl, int enable)
+{
+	/*
+	 * LVTS_CLKEN : Internal LVTS clock
+	 *
+	 * Bits:
+	 *
+	 * 0 : enable / disable clock
+	 */
+	writel(enable, LVTS_CLKEN(lvts_ctrl->base));
+
+	return 0;
+}
+
+static inline int lvts_ctrl_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	return lvts_ctrl_set_enable(lvts_ctrl, 1);
+}
+
+static inline int lvts_ctrl_disable(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	return lvts_ctrl_set_enable(lvts_ctrl, 0);
+}
+
+static int lvts_ctrl_connect(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	u32 id, cmds[] = { 0xC103FFFF, 0xC502FF55 };
+
+	lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
+
+	/*
+	 * LVTS_ID : Get ID and status of the thermal controller
+	 *
+	 * Bits:
+	 *
+	 * 0-5	: thermal controller id
+	 *   7	: thermal controller connection is valid
+	 */
+	id = readl(LVTS_ID(lvts_ctrl->base));
+	if (!(id & BIT(7)))
+		return -EIO;
+
+	return 0;
+}
+
+static int lvts_ctrl_initialize(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	/*
+	 * Write device mask: 0xC1030000
+	 */
+	u32 cmds[] = {
+		0xC1030E01, 0xC1030CFC, 0xC1030A8C, 0xC103098D, 0xC10308F1,
+		0xC10307A6, 0xC10306B8, 0xC1030500, 0xC1030420, 0xC1030300,
+		0xC1030030, 0xC10300F6, 0xC1030050, 0xC1030060, 0xC10300AC,
+		0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
+	};
+
+	lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
+
+	return 0;
+}
+
+static int lvts_ctrl_calibrate(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	int i;
+	void __iomem *lvts_edata[] = {
+		LVTS_EDATA00(lvts_ctrl->base),
+		LVTS_EDATA01(lvts_ctrl->base),
+		LVTS_EDATA02(lvts_ctrl->base),
+		LVTS_EDATA03(lvts_ctrl->base)
+	};
+
+	/*
+	 * LVTS_EDATA0X : Efuse calibration reference value for sensor X
+	 *
+	 * Bits:
+	 *
+	 * 20-0 : Efuse value for normalization data
+	 */
+	for (i = 0; i < LVTS_SENSOR_MAX; i++)
+		writel(lvts_ctrl->calibration[i], lvts_edata[i]);
+
+	return 0;
+}
+
+static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	u32 value;
+
+	/*
+	 * LVTS_TSSEL : Sensing point index numbering
+	 *
+	 * Bits:
+	 *
+	 * 31-24: ADC Sense 3
+	 * 23-16: ADC Sense 2
+	 * 15-8	: ADC Sense 1
+	 * 7-0	: ADC Sense 0
+	 */
+	value = LVTS_TSSEL_CONF;
+	writel(value, LVTS_TSSEL(lvts_ctrl->base));
+
+	/*
+	 * LVTS_CALSCALE : ADC voltage round
+	 */
+	value = 0x300;
+	value = LVTS_CALSCALE_CONF;
+
+	/*
+	 * LVTS_MSRCTL0 : Sensor filtering strategy
+	 *
+	 * Filters:
+	 *
+	 * 000 : One sample
+	 * 001 : Avg 2 samples
+	 * 010 : 4 samples, drop min and max, avg 2 samples
+	 * 011 : 6 samples, drop min and max, avg 4 samples
+	 * 100 : 10 samples, drop min and max, avg 8 samples
+	 * 101 : 18 samples, drop min and max, avg 16 samples
+	 *
+	 * Bits:
+	 *
+	 * 0-2  : Sensor0 filter
+	 * 3-5  : Sensor1 filter
+	 * 6-8  : Sensor2 filter
+	 * 9-11 : Sensor3 filter
+	 */
+	value = LVTS_HW_FILTER << 9 |  LVTS_HW_FILTER << 6 |
+			LVTS_HW_FILTER << 3 | LVTS_HW_FILTER;
+	writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
+
+	/*
+	 * LVTS_MSRCTL1 : Measurement control
+	 *
+	 * Bits:
+	 *
+	 * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
+	 * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
+	 * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
+	 * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
+	 *
+	 * That configuration will ignore the filtering and the delays
+	 * introduced below in MONCTL1 and MONCTL2
+	 */
+	if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
+		value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
+		writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
+	}
+
+	/*
+	 * LVTS_MONCTL1 : Period unit and group interval configuration
+	 *
+	 * The clock source of LVTS thermal controller is 26MHz.
+	 *
+	 * The period unit is a time base for all the interval delays
+	 * specified in the registers. By default we use 12. The time
+	 * conversion is done by multiplying by 256 and 1/26.10^6
+	 *
+	 * An interval delay multiplied by the period unit gives the
+	 * duration in seconds.
+	 *
+	 * - Filter interval delay is a delay between two samples of
+	 * the same sensor.
+	 *
+	 * - Sensor interval delay is a delay between two samples of
+	 * different sensors.
+	 *
+	 * - Group interval delay is a delay between different rounds.
+	 *
+	 * For example:
+	 *     If Period unit = C, filter delay = 1, sensor delay = 2, group delay = 1,
+	 *     and two sensors, TS1 and TS2, are in a LVTS thermal controller
+	 *     and then
+	 *     Period unit time = C * 1/26M * 256 = 12 * 38.46ns * 256 = 118.149us
+	 *     Filter interval delay = 1 * Period unit = 118.149us
+	 *     Sensor interval delay = 2 * Period unit = 236.298us
+	 *     Group interval delay = 1 * Period unit = 118.149us
+	 *
+	 *     TS1    TS1 ... TS1    TS2    TS2 ... TS2    TS1...
+	 *        <--> Filter interval delay
+	 *                       <--> Sensor interval delay
+	 *                                             <--> Group interval delay
+	 * Bits:
+	 *      29 - 20 : Group interval
+	 *      16 - 13 : Send a single interrupt when crossing the hot threshold (1)
+	 *                or an interrupt everytime the hot threshold is crossed (0)
+	 *       9 - 0  : Period unit
+	 *
+	 */
+	value = LVTS_GROUP_INTERVAL << 20 | LVTS_PERIOD_UNIT;
+	writel(value, LVTS_MONCTL1(lvts_ctrl->base));
+
+	/*
+	 * LVTS_MONCTL2 : Filtering and sensor interval
+	 *
+	 * Bits:
+	 *
+	 *      25-16 : Interval unit in PERIOD_UNIT between sample on
+	 *              the same sensor, filter interval
+	 *       9-0  : Interval unit in PERIOD_UNIT between each sensor
+	 *
+	 */
+	value = LVTS_FILTER_INTERVAL << 16 | LVTS_SENSOR_INTERVAL;
+	writel(value, LVTS_MONCTL2(lvts_ctrl->base));
+
+	return lvts_irq_init(lvts_ctrl);
+}
+
+static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
+{
+	struct lvts_sensor *lvts_sensors = lvts_ctrl->sensors;
+	struct thermal_zone_device *tz;
+	u32 sensor_map = 0;
+	int i;
+
+	for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
+
+		int dt_id = lvts_sensors[i].dt_id;
+
+		tz = devm_thermal_of_zone_register(dev, dt_id, &lvts_sensors[i],
+						   &lvts_ops);
+		if (IS_ERR(tz)) {
+			/*
+			 * This thermal zone is not described in the
+			 * device tree. It is not an error from the
+			 * thermal OF code POV, we just continue.
+			 */
+			if (PTR_ERR(tz) == -ENODEV)
+				continue;
+
+			return PTR_ERR(tz);
+		}
+
+		/*
+		 * The thermal zone pointer will be needed in the
+		 * interrupt handler, we store it in the sensor
+		 * structure. The thermal domain structure will be
+		 * passed to the interrupt handler private data as the
+		 * interrupt is shared for all the controller
+		 * belonging to the thermal domain.
+		 */
+		lvts_sensors[i].tz = tz;
+
+		/*
+		 * This sensor was correctly associated with a thermal
+		 * zone, let's set the corresponding bit in the sensor
+		 * map, so we can enable the temperature monitoring in
+		 * the hardware thermal controller.
+		 */
+		sensor_map |= BIT(i);
+	}
+
+	/*
+	 * Bits:
+	 *      9: Single point access flow
+	 *    0-3: Enable sensing point 0-3
+	 *
+	 * The initialization of the thermal zones give us
+	 * which sensor point to enable. If any thermal zone
+	 * was not described in the device tree, it won't be
+	 * enabled here in the sensor map.
+	 */
+	writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
+
+	return 0;
+}
+
+static int lvts_domain_init(struct device *dev, struct lvts_domain *lvts_td,
+			    struct lvts_data *lvts_data)
+{
+	struct lvts_ctrl *lvts_ctrl;
+	int i, ret;
+
+	ret = lvts_ctrl_init(dev, lvts_td, lvts_data);
+	if (ret)
+		return ret;
+
+	ret = lvts_domain_reset(dev, lvts_td->reset);
+	if (ret) {
+		dev_dbg(dev, "Failed to reset domain");
+		return ret;
+	}
+
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+
+		lvts_ctrl = &lvts_td->lvts_ctrl[i];
+
+		/*
+		 * Initialization steps:
+		 *
+		 * - Enable the clock
+		 * - Connect to the LVTS
+		 * - Initialize the LVTS
+		 * - Prepare the calibration data
+		 * - Select monitored sensors
+		 * [ Configure sampling ]
+		 * [ Configure the interrupt ]
+		 * - Start measurement
+		 */
+		ret = lvts_ctrl_enable(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to enable LVTS clock");
+			return ret;
+		}
+
+		ret = lvts_ctrl_connect(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to connect to LVTS controller");
+			return ret;
+		}
+
+		ret = lvts_ctrl_initialize(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to initialize controller");
+			return ret;
+		}
+
+		ret = lvts_ctrl_calibrate(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to calibrate controller");
+			return ret;
+		}
+
+		ret = lvts_ctrl_configure(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to configure controller");
+			return ret;
+		}
+
+		ret = lvts_ctrl_start(dev, lvts_ctrl);
+		if (ret) {
+			dev_dbg(dev, "Failed to start controller");
+			return ret;
+		}
+	}
+
+	return lvts_debugfs_init(dev, lvts_td);
+}
+
+static int lvts_probe(struct platform_device *pdev)
+{
+	struct lvts_data *lvts_data;
+	struct lvts_domain *lvts_td;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int irq, ret;
+
+	lvts_td = devm_kzalloc(dev, sizeof(*lvts_td), GFP_KERNEL);
+	if (!lvts_td)
+		return -ENOMEM;
+
+	lvts_data = (struct lvts_data *)of_device_get_match_data(dev);
+	if (!lvts_data) {
+		dev_dbg(dev, "No platforme data");
+		return -ENODATA;
+	};
+
+	lvts_td->clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(lvts_td->clk)) {
+		dev_dbg(dev, "Failed to retrieve clock\n");
+		return PTR_ERR(lvts_td->clk);
+	}
+
+	res = platform_get_mem_or_io(pdev, 0);
+	if (!res) {
+		dev_dbg(dev, "No IO resource\n");
+		return -ENXIO;
+	}
+
+	lvts_td->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(lvts_td->base)) {
+		dev_dbg(dev, "Failed to map io resource\n");
+		return PTR_ERR(lvts_td->base);
+	}
+
+	lvts_td->reset = devm_reset_control_get_by_index(dev, 0);
+	if (IS_ERR(lvts_td->reset)) {
+		dev_dbg(dev, "Failed to get reset control\n");
+		return PTR_ERR(lvts_td->reset);
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_dbg(dev, "No irq resource\n");
+		return irq;
+	}
+
+	ret = lvts_domain_init(dev, lvts_td, lvts_data);
+	if (ret) {
+		dev_dbg(dev, "Failed to initialize the lvts domain\n");
+		return ret;
+	}
+
+	/*
+	 * At this point the LVTS is initialized and enabled. We can
+	 * safely enable the interrupt.
+	 */
+	ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
+					IRQF_ONESHOT, dev_name(dev), lvts_td);
+	if (ret) {
+		dev_dbg(dev, "Failed to request interrupt\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, lvts_td);
+
+	return 0;
+}
+
+static int lvts_remove(struct platform_device *pdev)
+{
+	struct lvts_domain *lvts_td;
+	struct device *dev = &pdev->dev;
+	int i;
+
+	lvts_td = platform_get_drvdata(pdev);
+
+	for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
+		lvts_ctrl_disable(dev, &lvts_td->lvts_ctrl[i]);
+
+	lvts_debugfs_exit();
+
+	return 0;
+}
+
+static struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {
+	{
+		.cal_offset = { 0x4, 0x7 },
+		.lvts_sensor = {
+			{ .dt_id = MT8195_MCU_BIG_CPU0 },
+			{ .dt_id = MT8195_MCU_BIG_CPU1 }
+		},
+		.num_lvts_sensor = 2,
+		.offset = 0x0,
+		.hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
+	},
+
+	{
+		.cal_offset = { 0xd, 0x10 },
+		.lvts_sensor = {
+			{ .dt_id = MT8195_MCU_BIG_CPU2 },
+			{ .dt_id = MT8195_MCU_BIG_CPU3 }
+		},
+		.num_lvts_sensor = 2,
+		.offset = 0x100,
+		.hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
+	},
+
+	{
+		.cal_offset = { 0x16, 0x19, 0x1c, 0x1f },
+		.lvts_sensor = {
+			{ .dt_id = MT8195_MCU_LITTLE_CPU0 },
+			{ .dt_id = MT8195_MCU_LITTLE_CPU1 },
+			{ .dt_id = MT8195_MCU_LITTLE_CPU2 },
+			{ .dt_id = MT8195_MCU_LITTLE_CPU3 }
+		},
+		.num_lvts_sensor = 4,
+		.offset = 0x200,
+		.hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
+	}
+};
+
+static struct lvts_data mt8195_lvts_mcu_data = {
+	.lvts_ctrl	= mt8195_lvts_data_ctrl,
+	.num_lvts_ctrl	= ARRAY_SIZE(mt8195_lvts_data_ctrl),
+};
+
+static const struct of_device_id lvts_of_match[] = {
+	{ .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, lvts_of_match);
+
+static struct platform_driver lvts_driver = {
+	.probe = lvts_probe,
+	.remove = lvts_remove,
+	.driver = {
+		.name = "mtk-lvts-thermal",
+		.of_match_table = lvts_of_match,
+	},
+};
+module_platform_driver(lvts_driver);
+
+MODULE_AUTHOR("Balsam CHIHI <bchihi@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek LVTS Thermal Driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-30 10:40       ` Balsam CHIHI
  2023-01-30 11:18         ` Matthias Brugger
@ 2023-01-31 16:53         ` Krzysztof Kozlowski
  2023-01-31 17:01           ` Daniel Lezcano
  1 sibling, 1 reply; 57+ messages in thread
From: Krzysztof Kozlowski @ 2023-01-31 16:53 UTC (permalink / raw)
  To: Balsam CHIHI
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

On 30/01/2023 11:40, Balsam CHIHI wrote:
>>> diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
>>> new file mode 100644
>>> index 000000000000..902d5b1e4f43
>>> --- /dev/null
>>> +++ b/include/dt-bindings/thermal/mediatek-lvts.h
>>
>> Same filename as bindings.
> 
> fixed.
> rename :
> include/dt-bindings/thermal/mediatek-lvts.h =>
> include/dt-bindings/thermal/mediatek-lvts-thermal.h

Missing coma, so mediatek,lvts-thermal.h


Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal controllers dt-binding definition
  2023-01-31 16:53         ` Krzysztof Kozlowski
@ 2023-01-31 17:01           ` Daniel Lezcano
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel Lezcano @ 2023-01-31 17:01 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Balsam CHIHI
  Cc: angelogioacchino.delregno, rafael, amitk, rui.zhang,
	matthias.bgg, robh+dt, krzysztof.kozlowski+dt, rdunlap,
	ye.xingchen, p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On 31/01/2023 17:53, Krzysztof Kozlowski wrote:
> On 30/01/2023 11:40, Balsam CHIHI wrote:
>>>> diff --git a/include/dt-bindings/thermal/mediatek-lvts.h b/include/dt-bindings/thermal/mediatek-lvts.h
>>>> new file mode 100644
>>>> index 000000000000..902d5b1e4f43
>>>> --- /dev/null
>>>> +++ b/include/dt-bindings/thermal/mediatek-lvts.h
>>>
>>> Same filename as bindings.
>>
>> fixed.
>> rename :
>> include/dt-bindings/thermal/mediatek-lvts.h =>
>> include/dt-bindings/thermal/mediatek-lvts-thermal.h
> 
> Missing coma, so mediatek,lvts-thermal.h

Yeah, actually Balsam resent a new version but numbered v3 taking into 
account your comments.

The versioning is becoming a bit messy now but if you are ok with the 
changes I'll pick the patch as is so we can go forward for this series.

-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-01-31 15:38   ` [PATCH v12] thermal: drivers: mediatek: " bchihi
@ 2023-02-01  3:09     ` kernel test robot
  2023-02-01  7:47       ` Krzysztof Kozlowski
  2023-02-01  7:55     ` Krzysztof Kozlowski
  1 sibling, 1 reply; 57+ messages in thread
From: kernel test robot @ 2023-02-01  3:09 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: oe-kbuild-all, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

Hi Balsam,

Thank you for the patch! Yet something to improve:



url:    https://github.com/intel-lab-lkp/linux/commits/UPDATE-20230131-234122/bchihi-baylibre-com/thermal-drivers-mediatek-Relocate-driver-to-mediatek-folder/20230124-211910
base:   the 4th patch of https://lore.kernel.org/r/20230124131717.128660-5-bchihi%40baylibre.com
patch link:    https://lore.kernel.org/r/20230131153816.21709-1-bchihi%40baylibre.com
patch subject: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20230201/202302011058.17Vvc1pN-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/5646ebf6f10ff0fc60c04d8c57523f7c44526b41
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review UPDATE-20230131-234122/bchihi-baylibre-com/thermal-drivers-mediatek-Relocate-driver-to-mediatek-folder/20230124-211910
        git checkout 5646ebf6f10ff0fc60c04d8c57523f7c44526b41
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/thermal/mediatek/lvts_thermal.c:20:10: fatal error: dt-bindings/thermal/mediatek,lvts-thermal.h: No such file or directory
      20 | #include <dt-bindings/thermal/mediatek,lvts-thermal.h>
         |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   compilation terminated.


vim +20 drivers/thermal/mediatek/lvts_thermal.c

  > 20	#include <dt-bindings/thermal/mediatek,lvts-thermal.h>
    21	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3] dt-bindings: thermal: mediatek: Add LVTS thermal controllers
  2023-01-31 14:04     ` [PATCH v3] dt-bindings: thermal: mediatek: Add LVTS thermal controllers bchihi
@ 2023-02-01  7:46       ` Krzysztof Kozlowski
  2023-02-01 13:34         ` Balsam CHIHI
  0 siblings, 1 reply; 57+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-01  7:46 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

On 31/01/2023 15:04, bchihi@baylibre.com wrote:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> Add LVTS thermal controllers dt-binding definition for mt8195.
> 
> Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> ---
> Changelog:
>   v3:
>      - Fixed subject prefix
>      - Fixed licenses GPL-2.0-only OR BSD-2-Clause
>        to GPL-2.0 OR MIT (to match DT)
>      - Fixed matching dt-binding file names

If this is v3 with only one patch, where is the driver or DTS using
these bindings? Please link it. It's unusual to see only bindings,
without the users.

>   v2:
>      - Fixed subject prefix
>      - Fixed licenses GPL-2.0+ to GPL-2.0
>      - Added dual licenses

Is there a reason to make our review more difficult and keep versions
broken, threads attached to some other threads?

------------

Grabbing thread from
lore.kernel.org/all/20230131140439.600164-1-bchihi%40baylibre.com/t.mbox.gz
Checking for newer revisions on https://lore.kernel.org/all/
Analyzing 38 messages in the thread
Will use the latest revision: v12
You can pick other revisions using the -vN flag
Checking attestation on all messages, may take a moment...
---
  ✓ [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal
Sensor driver
    ✓ Signed: DKIM/baylibre-com.20210112.gappssmtp.com (From:
bchihi@baylibre.com)
    + Link:
https://lore.kernel.org/r/20230131153816.21709-1-bchihi@baylibre.com
  ✓ [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal
controllers dt-binding definition
    ✓ Signed: DKIM/baylibre-com.20210112.gappssmtp.com (From:
bchihi@baylibre.com)
    + Link:
https://lore.kernel.org/r/20230126161048.94089-1-bchihi@baylibre.com
  ERROR: missing [3/1]!
  ERROR: missing [4/1]!
  ERROR: missing [5/1]!
  ERROR: missing [6/1]!

--------

b4 diff '<20230131140439.600164-1-bchihi@baylibre.com>'
Checking for older revisions on https://lore.kernel.org/all/
---
Analyzing 38 messages in the thread
Assuming new revision: v4 ([PATCH v12] thermal: drivers: mediatek: Add
the Low Voltage Thermal Sensor driver)
Preparing fake-am for v3: dt-bindings: thermal: mediatek: Add LVTS
thermal controllers
  range: 291580cde5f6..de7fe5e0293a
Preparing fake-am for v12: arm64: dts: mediatek: mt8195: Add thermal
zones and thermal nodes
  ERROR: Could not find matching blob for
arch/arm64/boot/dts/mediatek/mt8195.dtsi (09df105f4606)
         If you know on which tree this patchset is based,
         add it as a remote and perform "git remote update"
         in order to fetch the missing objects.
---
Could not create fake-am range for upper series v12


> ---
> ---
>  .../thermal/mediatek,lvts-thermal.yaml        | 107 ++++++++++++++++++
>  .../thermal/mediatek,lvts-thermal.h           |  19 ++++
>  2 files changed, 126 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
>  create mode 100644 include/dt-bindings/thermal/mediatek,lvts-thermal.h
> 
> diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> new file mode 100644
> index 000000000000..5fa5c7a1a417
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> @@ -0,0 +1,107 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR MIT)

WARNING: DT binding documents should be licensed (GPL-2.0-only OR
BSD-2-Clause)
#24: FILE:
Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml:1:
+# SPDX-License-Identifier: (GPL-2.0 OR MIT)

I asked you to use the binding license for header file. Then you changed
binding license... why? Why do you need other SPDX text? Why do you need
MIT?

> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
> +
> +maintainers:
> +  - Balsam CHIHI <bchihi@baylibre.com>
> +
> +description: |
> +  LVTS is a thermal management architecture composed of three subsystems,
> +  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
> +  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
> +  a Digital controller (LVTS_CTRL).
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt8195-lvts-ap
> +      - mediatek,mt8195-lvts-mcu

What about other devices? You called the file name as generic for all
Mediatek SoCs, so why only one SoC is here? Is there going to be more?
If yes, why they cannot be added now?

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-01  3:09     ` kernel test robot
@ 2023-02-01  7:47       ` Krzysztof Kozlowski
  2023-02-01 15:14         ` Balsam CHIHI
  0 siblings, 1 reply; 57+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-01  7:47 UTC (permalink / raw)
  To: kernel test robot, bchihi, daniel.lezcano,
	angelogioacchino.delregno, rafael, amitk, rui.zhang,
	matthias.bgg, robh+dt, krzysztof.kozlowski+dt, rdunlap,
	ye.xingchen, p.zabel
  Cc: oe-kbuild-all, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On 01/02/2023 04:09, kernel test robot wrote:
> Hi Balsam,
> 
> Thank you for the patch! Yet something to improve:
> 
> 
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/UPDATE-20230131-234122/bchihi-baylibre-com/thermal-drivers-mediatek-Relocate-driver-to-mediatek-folder/20230124-211910
> base:   the 4th patch of https://lore.kernel.org/r/20230124131717.128660-5-bchihi%40baylibre.com
> patch link:    https://lore.kernel.org/r/20230131153816.21709-1-bchihi%40baylibre.com
> patch subject: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
> config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20230201/202302011058.17Vvc1pN-lkp@intel.com/config)
> compiler: s390-linux-gcc (GCC) 12.1.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/intel-lab-lkp/linux/commit/5646ebf6f10ff0fc60c04d8c57523f7c44526b41
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review UPDATE-20230131-234122/bchihi-baylibre-com/thermal-drivers-mediatek-Relocate-driver-to-mediatek-folder/20230124-211910
>         git checkout 5646ebf6f10ff0fc60c04d8c57523f7c44526b41
>         # save the config file
>         mkdir build_dir && cp config build_dir/.config
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 olddefconfig
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash
> 
> If you fix the issue, kindly add following tag where applicable
> | Reported-by: kernel test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>>> drivers/thermal/mediatek/lvts_thermal.c:20:10: fatal error: dt-bindings/thermal/mediatek,lvts-thermal.h: No such file or directory
>       20 | #include <dt-bindings/thermal/mediatek,lvts-thermal.h>
>          |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

So here is your driver... and you decided not only to make reviewers
life more difficult, but also to fail all automated tools.

No, that's not how patchsets should be sent. You have here clear
dependency, you cannot send them separately.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-01-31 15:38   ` [PATCH v12] thermal: drivers: mediatek: " bchihi
  2023-02-01  3:09     ` kernel test robot
@ 2023-02-01  7:55     ` Krzysztof Kozlowski
  2023-02-01 16:46       ` Balsam CHIHI
  2023-02-06 14:07       ` Daniel Lezcano
  1 sibling, 2 replies; 57+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-01  7:55 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

On 31/01/2023 16:38, bchihi@baylibre.com wrote:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
> controllers contained in a thermal domain.
> 
> A thermal domains can be the MCU or the AP.
> 
> Each thermal domains contain up to seven controllers, each thermal
> controller handle up to four thermal sensors.
> 
> The LVTS has two Finite State Machines (FSM), one to handle the
> functionin temperatures range like hot or cold temperature and another
> one to handle monitoring trip point. The FSM notifies via interrupts
> when a trip point is crossed.
> 

(...)

> +
> +struct lvts_domain {
> +	struct lvts_ctrl *lvts_ctrl;
> +	struct reset_control *reset;
> +	struct clk *clk;
> +	int num_lvts_ctrl;
> +	void __iomem *base;
> +	size_t calib_len;
> +	u8 *calib;
> +};
> +
> +#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
> +
> +static struct dentry *root;

How do you handle two instances of driver?

> +
> +#define LVTS_DEBUG_FS_REGS(__reg)		\
> +{						\
> +	.name = __stringify(__reg),		\
> +	.offset = __reg(0),			\
> +}
> +

(...)

> +
> +static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
> +{
> +	struct lvts_sensor *lvts_sensor = tz->devdata;
> +	void __iomem *base = lvts_sensor->base;
> +	u32 raw_low = lvts_temp_to_raw(low);
> +	u32 raw_high = lvts_temp_to_raw(high);
> +
> +	/*
> +	 * Hot to normal temperature threshold
> +	 *
> +	 * LVTS_H2NTHRE
> +	 *
> +	 * Bits:
> +	 *
> +	 * 14-0 : Raw temperature for threshold
> +	 */
> +	if (low != -INT_MAX) {
> +		dev_dbg(&tz->device, "Setting low limit temperature interrupt: %d\n", low);
> +		writel(raw_low, LVTS_H2NTHRE(base));
> +	}
> +
> +	/*
> +	 * Hot temperature threshold
> +	 *
> +	 * LVTS_HTHRE
> +	 *
> +	 * Bits:
> +	 *
> +	 * 14-0 : Raw temperature for threshold
> +	 */
> +	dev_dbg(&tz->device, "Setting high limit temperature interrupt: %d\n", high);
> +	writel(raw_high, LVTS_HTHRE(base));
> +
> +	return 0;
> +}
> +
> +static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
> +{
> +	irqreturn_t iret = IRQ_NONE;
> +	u32 value, masks[] = {

Don't mix different types in one declaration. u32 and a pointer are
quite different types.

> +		LVTS_INT_SENSOR0,
> +		LVTS_INT_SENSOR1,
> +		LVTS_INT_SENSOR2,
> +		LVTS_INT_SENSOR3
> +	};
> +	int i;
> +
> +	/*
> +	 * Interrupt monitoring status
> +	 *
> +	 * LVTS_MONINTST
> +	 *
> +	 * Bits:
> +	 *
> +	 * 31 : Interrupt for stage 3
> +	 * 30 : Interrupt for stage 2
> +	 * 29 : Interrupt for state 1
> +	 * 28 : Interrupt using filter on sensor 3
> +	 *
> +	 * 27 : Interrupt using immediate on sensor 3
> +	 * 26 : Interrupt normal to hot on sensor 3
> +	 * 25 : Interrupt high offset on sensor 3
> +	 * 24 : Interrupt low offset on sensor 3
> +	 *
> +	 * 23 : Interrupt hot threshold on sensor 3
> +	 * 22 : Interrupt cold threshold on sensor 3
> +	 * 21 : Interrupt using filter on sensor 2
> +	 * 20 : Interrupt using filter on sensor 1
> +	 *
> +	 * 19 : Interrupt using filter on sensor 0
> +	 * 18 : Interrupt using immediate on sensor 2
> +	 * 17 : Interrupt using immediate on sensor 1
> +	 * 16 : Interrupt using immediate on sensor 0
> +	 *
> +	 * 15 : Interrupt device access timeout interrupt
> +	 * 14 : Interrupt normal to hot on sensor 2
> +	 * 13 : Interrupt high offset interrupt on sensor 2
> +	 * 12 : Interrupt low offset interrupt on sensor 2
> +	 *
> +	 * 11 : Interrupt hot threshold on sensor 2
> +	 * 10 : Interrupt cold threshold on sensor 2
> +	 *  9 : Interrupt normal to hot on sensor 1
> +	 *  8 : Interrupt high offset interrupt on sensor 1
> +	 *
> +	 *  7 : Interrupt low offset interrupt on sensor 1
> +	 *  6 : Interrupt hot threshold on sensor 1
> +	 *  5 : Interrupt cold threshold on sensor 1
> +	 *  4 : Interrupt normal to hot on sensor 0
> +	 *
> +	 *  3 : Interrupt high offset interrupt on sensor 0
> +	 *  2 : Interrupt low offset interrupt on sensor 0
> +	 *  1 : Interrupt hot threshold on sensor 0
> +	 *  0 : Interrupt cold threshold on sensor 0
> +	 *
> +	 * We are interested in the sensor(s) responsible of the
> +	 * interrupt event. We update the thermal framework with the
> +	 * thermal zone associated with the sensor. The framework will
> +	 * take care of the rest whatever the kind of interrupt, we
> +	 * are only interested in which sensor raised the interrupt.
> +	 *
> +	 * sensor 3 interrupt: 0001 1111 1100 0000 0000 0000 0000 0000
> +	 *                  => 0x1FC00000
> +	 * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000
> +	 *                  => 0x00247C00
> +	 * sensor 1 interrupt: 0000 0000 0001 0001 0000 0011 1110 0000
> +	 *                  => 0X000881F0
> +	 * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111
> +	 *                  => 0x0009001F
> +	 */
> +	value = readl(LVTS_MONINTSTS(lvts_ctrl->base));
> +
> +	/*
> +	 * Let's figure out which sensors raised the interrupt
> +	 *
> +	 * NOTE: the masks array must be ordered with the index
> +	 * corresponding to the sensor id eg. index=0, mask for
> +	 * sensor0.
> +	 */
> +	for (i = 0; i < ARRAY_SIZE(masks); i++) {
> +
> +		if (!(value & masks[i]))
> +			continue;
> +
> +		thermal_zone_device_update(lvts_ctrl->sensors[i].tz,
> +					   THERMAL_TRIP_VIOLATED);
> +		iret = IRQ_HANDLED;
> +	}
> +
> +	/*
> +	 * Write back to clear the interrupt status (W1C)
> +	 */
> +	writel(value, LVTS_MONINTSTS(lvts_ctrl->base));
> +
> +	return iret;
> +}
> +
> +/*
> + * Temperature interrupt handler. Even if the driver supports more
> + * interrupt modes, we use the interrupt when the temperature crosses
> + * the hot threshold the way up and the way down (modulo the
> + * hysteresis).
> + *
> + * Each thermal domain has a couple of interrupts, one for hardware
> + * reset and another one for all the thermal events happening on the
> + * different sensors.
> + *
> + * The interrupt is configured for thermal events when crossing the
> + * hot temperature limit. At each interrupt, we check in every
> + * controller if there is an interrupt pending.
> + */
> +static irqreturn_t lvts_irq_handler(int irq, void *data)
> +{
> +	struct lvts_domain *lvts_td = data;
> +	irqreturn_t aux, iret = IRQ_NONE;
> +	int i;
> +
> +	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
> +
> +		aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl);
> +		if (aux != IRQ_HANDLED)
> +			continue;
> +
> +		iret = IRQ_HANDLED;
> +	}
> +
> +	return iret;
> +}
> +
> +static struct thermal_zone_device_ops lvts_ops = {
> +	.get_temp = lvts_get_temp,
> +	.set_trips = lvts_set_trips,
> +};
> +
> +static int __init lvts_sensor_init(struct device *dev,
> +				   struct lvts_ctrl *lvts_ctrl,
> +				   struct lvts_ctrl_data *lvts_ctrl_data)
> +{
> +	struct lvts_sensor *lvts_sensor = lvts_ctrl->sensors;
> +	void __iomem *msr_regs[] = {
> +		LVTS_MSR0(lvts_ctrl->base),
> +		LVTS_MSR1(lvts_ctrl->base),
> +		LVTS_MSR2(lvts_ctrl->base),
> +		LVTS_MSR3(lvts_ctrl->base)
> +	};
> +
> +	void __iomem *imm_regs[] = {
> +		LVTS_IMMD0(lvts_ctrl->base),
> +		LVTS_IMMD1(lvts_ctrl->base),
> +		LVTS_IMMD2(lvts_ctrl->base),
> +		LVTS_IMMD3(lvts_ctrl->base)
> +	};
> +
> +	int i;
> +
> +	for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++) {
> +
> +		int dt_id = lvts_ctrl_data->lvts_sensor[i].dt_id;
> +
> +		/*
> +		 * At this point, we don't know which id matches which
> +		 * sensor. Let's set arbitrally the id from the index.
> +		 */
> +		lvts_sensor[i].id = i;
> +
> +		/*
> +		 * The thermal zone registration will set the trip
> +		 * point interrupt in the thermal controller
> +		 * register. But this one will be reset in the
> +		 * initialization after. So we need to post pone the
> +		 * thermal zone creation after the controller is
> +		 * setup. For this reason, we store the device tree
> +		 * node id from the data in the sensor structure
> +		 */
> +		lvts_sensor[i].dt_id = dt_id;
> +
> +		/*
> +		 * We assign the base address of the thermal
> +		 * controller as a back pointer. So it will be
> +		 * accessible from the different thermal framework ops
> +		 * as we pass the lvts_sensor pointer as thermal zone
> +		 * private data.
> +		 */
> +		lvts_sensor[i].base = lvts_ctrl->base;
> +
> +		/*
> +		 * Each sensor has its own register address to read from.
> +		 */
> +		lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
> +			imm_regs[i] : msr_regs[i];
> +	};
> +
> +	lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
> +
> +	return 0;
> +}
> +
> +/*
> + * The efuse blob values follows the sensor enumeration per thermal
> + * controller. The decoding of the stream is as follow:
> + *
> + *                        <--?-> <----big0 ???---> <-sensor0-> <-0->
> + *                        ------------------------------------------
> + * index in the stream: : | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 |
> + *                        ------------------------------------------
> + *
> + *                        <--sensor1--><-0-> <----big1 ???---> <-sen
> + *                        ------------------------------------------
> + *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
> + *                        ------------------------------------------
> + *
> + *                        sor0-> <-0-> <-sensor1-> <-0-> ..........
> + *                        ------------------------------------------
> + *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
> + *                        ------------------------------------------
> + *
> + * And so on ...
> + *
> + * The data description gives the offset of the calibration data in
> + * this bytes stream for each sensor.
> + *
> + * Each thermal controller can handle up to 4 sensors max, we don't
> + * care if there are less as the array of calibration is sized to 4
> + * anyway. The unused sensor slot will be zeroed.
> + */
> +static int __init lvts_calibration_init(struct device *dev,
> +					struct lvts_ctrl *lvts_ctrl,
> +					struct lvts_ctrl_data *lvts_ctrl_data,
> +					u8 *efuse_calibration)
> +{
> +	int i;
> +
> +	for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++)
> +		memcpy(&lvts_ctrl->calibration[i],
> +		       efuse_calibration + lvts_ctrl_data->cal_offset[i], 2);
> +
> +	return 0;
> +}
> +
> +/*
> + * The efuse bytes stream can be split into different chunk of
> + * nvmems. This function reads and concatenate those into a single
> + * buffer so it can be read sequentially when initializing the
> + * calibration data.
> + */
> +static int lvts_calibration_read(struct device *dev, struct lvts_domain *lvts_td,
> +				 struct lvts_data *lvts_data)
> +{
> +	struct device_node *np = dev_of_node(dev);
> +	struct nvmem_cell *cell;
> +	struct property *prop;
> +	const char *cell_name;
> +
> +	of_property_for_each_string(np, "nvmem-cell-names", prop, cell_name) {
> +		size_t len;
> +		u8 *efuse;
> +
> +		cell = of_nvmem_cell_get(np, cell_name);
> +		if (IS_ERR(cell)) {
> +			dev_dbg(dev, "Failed to get cell '%s'\n", cell_name);

Is this an error? If so, why debug? dbg is not for errors.

> +			return PTR_ERR(cell);
> +		}
> +
> +		efuse = nvmem_cell_read(cell, &len);
> +
> +		nvmem_cell_put(cell);
> +
> +		if (IS_ERR(efuse)) {
> +			dev_dbg(dev, "Failed to read cell '%s'\n", cell_name);
> +			return PTR_ERR(efuse);
> +		}
> +
> +		lvts_td->calib = devm_krealloc(dev, lvts_td->calib,
> +					       lvts_td->calib_len + len, GFP_KERNEL);
> +		if (!lvts_td->calib)
> +			return -ENOMEM;
> +
> +		memcpy(lvts_td->calib + lvts_td->calib_len, efuse, len);
> +
> +		lvts_td->calib_len += len;
> +
> +		kfree(efuse);
> +	}
> +
> +	return 0;
> +}
> +
> +static int __init lvts_golden_temp_init(struct device *dev, u32 *value)

You did not test it, right? Build with section mismatch analysis...

> +{
> +	u32 gt;
> +
> +	gt = (*value) >> 24;
> +
> +	if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
> +		golden_temp = gt;
> +
> +	coeff_b = golden_temp * 500 + LVTS_COEFF_B;
> +
> +	return 0;
> +}
> +
> +static int __init lvts_ctrl_init(struct device *dev,

Same problem.

> +				 struct lvts_domain *lvts_td,
> +				 struct lvts_data *lvts_data)
> +{
> +	size_t size = sizeof(*lvts_td->lvts_ctrl) * lvts_data->num_lvts_ctrl;
> +	struct lvts_ctrl *lvts_ctrl;
> +	int i, ret;
> +

> +
> +static inline int lvts_ctrl_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> +{
> +	return lvts_ctrl_set_enable(lvts_ctrl, 1);

Drop the wrapper, it's useless. true or false for enable are quite obvious.

> +}
> +
> +static inline int lvts_ctrl_disable(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> +{
> +	return lvts_ctrl_set_enable(lvts_ctrl, 0);

Drop the wrapper.

> +}
> +
> +static int lvts_ctrl_connect(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> +{
> +	u32 id, cmds[] = { 0xC103FFFF, 0xC502FF55 };
> +
> +	lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
> +
> +	/*
> +	 * LVTS_ID : Get ID and status of the thermal controller
> +	 *
> +	 * Bits:
> +	 *
> +	 * 0-5	: thermal controller id
> +	 *   7	: thermal controller connection is valid
> +	 */
> +	id = readl(LVTS_ID(lvts_ctrl->base));
> +	if (!(id & BIT(7)))
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int lvts_ctrl_initialize(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> +{
> +	/*
> +	 * Write device mask: 0xC1030000
> +	 */
> +	u32 cmds[] = {
> +		0xC1030E01, 0xC1030CFC, 0xC1030A8C, 0xC103098D, 0xC10308F1,
> +		0xC10307A6, 0xC10306B8, 0xC1030500, 0xC1030420, 0xC1030300,
> +		0xC1030030, 0xC10300F6, 0xC1030050, 0xC1030060, 0xC10300AC,
> +		0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
> +	};
> +
> +	lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
> +
> +	return 0;
> +}
> +
> +static int lvts_ctrl_calibrate(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> +{
> +	int i;
> +	void __iomem *lvts_edata[] = {
> +		LVTS_EDATA00(lvts_ctrl->base),
> +		LVTS_EDATA01(lvts_ctrl->base),
> +		LVTS_EDATA02(lvts_ctrl->base),
> +		LVTS_EDATA03(lvts_ctrl->base)
> +	};
> +
> +	/*
> +	 * LVTS_EDATA0X : Efuse calibration reference value for sensor X
> +	 *
> +	 * Bits:
> +	 *
> +	 * 20-0 : Efuse value for normalization data
> +	 */
> +	for (i = 0; i < LVTS_SENSOR_MAX; i++)
> +		writel(lvts_ctrl->calibration[i], lvts_edata[i]);
> +
> +	return 0;
> +}
> +
> +static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> +{
> +	u32 value;
> +
> +	/*
> +	 * LVTS_TSSEL : Sensing point index numbering
> +	 *
> +	 * Bits:
> +	 *
> +	 * 31-24: ADC Sense 3
> +	 * 23-16: ADC Sense 2
> +	 * 15-8	: ADC Sense 1
> +	 * 7-0	: ADC Sense 0
> +	 */
> +	value = LVTS_TSSEL_CONF;
> +	writel(value, LVTS_TSSEL(lvts_ctrl->base));
> +
> +	/*
> +	 * LVTS_CALSCALE : ADC voltage round
> +	 */
> +	value = 0x300;
> +	value = LVTS_CALSCALE_CONF;
> +
> +	/*
> +	 * LVTS_MSRCTL0 : Sensor filtering strategy
> +	 *
> +	 * Filters:
> +	 *
> +	 * 000 : One sample
> +	 * 001 : Avg 2 samples
> +	 * 010 : 4 samples, drop min and max, avg 2 samples
> +	 * 011 : 6 samples, drop min and max, avg 4 samples
> +	 * 100 : 10 samples, drop min and max, avg 8 samples
> +	 * 101 : 18 samples, drop min and max, avg 16 samples
> +	 *
> +	 * Bits:
> +	 *
> +	 * 0-2  : Sensor0 filter
> +	 * 3-5  : Sensor1 filter
> +	 * 6-8  : Sensor2 filter
> +	 * 9-11 : Sensor3 filter
> +	 */
> +	value = LVTS_HW_FILTER << 9 |  LVTS_HW_FILTER << 6 |
> +			LVTS_HW_FILTER << 3 | LVTS_HW_FILTER;
> +	writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
> +
> +	/*
> +	 * LVTS_MSRCTL1 : Measurement control
> +	 *
> +	 * Bits:
> +	 *
> +	 * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
> +	 * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
> +	 * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
> +	 * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
> +	 *
> +	 * That configuration will ignore the filtering and the delays
> +	 * introduced below in MONCTL1 and MONCTL2
> +	 */
> +	if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
> +		value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
> +		writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
> +	}
> +
> +	/*
> +	 * LVTS_MONCTL1 : Period unit and group interval configuration
> +	 *
> +	 * The clock source of LVTS thermal controller is 26MHz.
> +	 *
> +	 * The period unit is a time base for all the interval delays
> +	 * specified in the registers. By default we use 12. The time
> +	 * conversion is done by multiplying by 256 and 1/26.10^6
> +	 *
> +	 * An interval delay multiplied by the period unit gives the
> +	 * duration in seconds.
> +	 *
> +	 * - Filter interval delay is a delay between two samples of
> +	 * the same sensor.
> +	 *
> +	 * - Sensor interval delay is a delay between two samples of
> +	 * different sensors.
> +	 *
> +	 * - Group interval delay is a delay between different rounds.
> +	 *
> +	 * For example:
> +	 *     If Period unit = C, filter delay = 1, sensor delay = 2, group delay = 1,
> +	 *     and two sensors, TS1 and TS2, are in a LVTS thermal controller
> +	 *     and then
> +	 *     Period unit time = C * 1/26M * 256 = 12 * 38.46ns * 256 = 118.149us
> +	 *     Filter interval delay = 1 * Period unit = 118.149us
> +	 *     Sensor interval delay = 2 * Period unit = 236.298us
> +	 *     Group interval delay = 1 * Period unit = 118.149us
> +	 *
> +	 *     TS1    TS1 ... TS1    TS2    TS2 ... TS2    TS1...
> +	 *        <--> Filter interval delay
> +	 *                       <--> Sensor interval delay
> +	 *                                             <--> Group interval delay
> +	 * Bits:
> +	 *      29 - 20 : Group interval
> +	 *      16 - 13 : Send a single interrupt when crossing the hot threshold (1)
> +	 *                or an interrupt everytime the hot threshold is crossed (0)
> +	 *       9 - 0  : Period unit
> +	 *
> +	 */
> +	value = LVTS_GROUP_INTERVAL << 20 | LVTS_PERIOD_UNIT;
> +	writel(value, LVTS_MONCTL1(lvts_ctrl->base));
> +
> +	/*
> +	 * LVTS_MONCTL2 : Filtering and sensor interval
> +	 *
> +	 * Bits:
> +	 *
> +	 *      25-16 : Interval unit in PERIOD_UNIT between sample on
> +	 *              the same sensor, filter interval
> +	 *       9-0  : Interval unit in PERIOD_UNIT between each sensor
> +	 *
> +	 */
> +	value = LVTS_FILTER_INTERVAL << 16 | LVTS_SENSOR_INTERVAL;
> +	writel(value, LVTS_MONCTL2(lvts_ctrl->base));
> +
> +	return lvts_irq_init(lvts_ctrl);
> +}
> +
> +static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> +{
> +	struct lvts_sensor *lvts_sensors = lvts_ctrl->sensors;
> +	struct thermal_zone_device *tz;
> +	u32 sensor_map = 0;
> +	int i;
> +
> +	for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
> +
> +		int dt_id = lvts_sensors[i].dt_id;
> +
> +		tz = devm_thermal_of_zone_register(dev, dt_id, &lvts_sensors[i],
> +						   &lvts_ops);
> +		if (IS_ERR(tz)) {
> +			/*
> +			 * This thermal zone is not described in the
> +			 * device tree. It is not an error from the
> +			 * thermal OF code POV, we just continue.
> +			 */
> +			if (PTR_ERR(tz) == -ENODEV)
> +				continue;
> +
> +			return PTR_ERR(tz);
> +		}
> +
> +		/*
> +		 * The thermal zone pointer will be needed in the
> +		 * interrupt handler, we store it in the sensor
> +		 * structure. The thermal domain structure will be
> +		 * passed to the interrupt handler private data as the
> +		 * interrupt is shared for all the controller
> +		 * belonging to the thermal domain.
> +		 */
> +		lvts_sensors[i].tz = tz;
> +
> +		/*
> +		 * This sensor was correctly associated with a thermal
> +		 * zone, let's set the corresponding bit in the sensor
> +		 * map, so we can enable the temperature monitoring in
> +		 * the hardware thermal controller.
> +		 */
> +		sensor_map |= BIT(i);
> +	}
> +
> +	/*
> +	 * Bits:
> +	 *      9: Single point access flow
> +	 *    0-3: Enable sensing point 0-3
> +	 *
> +	 * The initialization of the thermal zones give us
> +	 * which sensor point to enable. If any thermal zone
> +	 * was not described in the device tree, it won't be
> +	 * enabled here in the sensor map.
> +	 */
> +	writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
> +
> +	return 0;
> +}
> +
> +static int lvts_domain_init(struct device *dev, struct lvts_domain *lvts_td,
> +			    struct lvts_data *lvts_data)
> +{
> +	struct lvts_ctrl *lvts_ctrl;
> +	int i, ret;
> +
> +	ret = lvts_ctrl_init(dev, lvts_td, lvts_data);
> +	if (ret)
> +		return ret;
> +
> +	ret = lvts_domain_reset(dev, lvts_td->reset);
> +	if (ret) {
> +		dev_dbg(dev, "Failed to reset domain");
> +		return ret;
> +	}
> +
> +	for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
> +
> +		lvts_ctrl = &lvts_td->lvts_ctrl[i];
> +
> +		/*
> +		 * Initialization steps:
> +		 *
> +		 * - Enable the clock
> +		 * - Connect to the LVTS
> +		 * - Initialize the LVTS
> +		 * - Prepare the calibration data
> +		 * - Select monitored sensors
> +		 * [ Configure sampling ]
> +		 * [ Configure the interrupt ]
> +		 * - Start measurement
> +		 */
> +		ret = lvts_ctrl_enable(dev, lvts_ctrl);
> +		if (ret) {
> +			dev_dbg(dev, "Failed to enable LVTS clock");
> +			return ret;
> +		}
> +
> +		ret = lvts_ctrl_connect(dev, lvts_ctrl);
> +		if (ret) {
> +			dev_dbg(dev, "Failed to connect to LVTS controller");
> +			return ret;
> +		}
> +
> +		ret = lvts_ctrl_initialize(dev, lvts_ctrl);
> +		if (ret) {
> +			dev_dbg(dev, "Failed to initialize controller");
> +			return ret;
> +		}
> +
> +		ret = lvts_ctrl_calibrate(dev, lvts_ctrl);
> +		if (ret) {
> +			dev_dbg(dev, "Failed to calibrate controller");
> +			return ret;
> +		}
> +
> +		ret = lvts_ctrl_configure(dev, lvts_ctrl);
> +		if (ret) {
> +			dev_dbg(dev, "Failed to configure controller");
> +			return ret;
> +		}
> +
> +		ret = lvts_ctrl_start(dev, lvts_ctrl);
> +		if (ret) {
> +			dev_dbg(dev, "Failed to start controller");
> +			return ret;
> +		}
> +	}
> +
> +	return lvts_debugfs_init(dev, lvts_td);
> +}
> +
> +static int lvts_probe(struct platform_device *pdev)
> +{
> +	struct lvts_data *lvts_data;
> +	struct lvts_domain *lvts_td;
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	int irq, ret;
> +
> +	lvts_td = devm_kzalloc(dev, sizeof(*lvts_td), GFP_KERNEL);
> +	if (!lvts_td)
> +		return -ENOMEM;
> +
> +	lvts_data = (struct lvts_data *)of_device_get_match_data(dev);

Why do you need case?

> +	if (!lvts_data) {
> +		dev_dbg(dev, "No platforme 

Drop. How is it even possible?

> +		return -ENODATA;
> +	};
> +
> +	lvts_td->clk = devm_clk_get_enabled(dev, NULL);
> +	if (IS_ERR(lvts_td->clk)) {
> +		dev_dbg(dev, "Failed to retrieve clock\n");

Drop all debug statements. Either this is an error (so return
dev_err_probe) or core handles messages.

> +		return PTR_ERR(lvts_td->clk);
> +	}
> +
> +	res = platform_get_mem_or_io(pdev, 0);
> +	if (!res) {
> +		dev_dbg(dev, "No IO resource\n");

Ditto

> +		return -ENXIO;
> +	}
> +
> +	lvts_td->base = devm_ioremap_resource(dev, res);

Why not using single wrapper for this?

> +	if (IS_ERR(lvts_td->base)) {
> +		dev_dbg(dev, "Failed to map io resource\n");

Ditto

> +		return PTR_ERR(lvts_td->base);
> +	}
> +
> +	lvts_td->reset = devm_reset_control_get_by_index(dev, 0);
> +	if (IS_ERR(lvts_td->reset)) {
> +		dev_dbg(dev, "Failed to get reset control\n");

Ditto

> +		return PTR_ERR(lvts_td->reset);
> +	}
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0) {
> +		dev_dbg(dev, "No irq resource\n");

Ditto

> +		return irq;
> +	}
> +
> +	ret = lvts_domain_init(dev, lvts_td, lvts_data);
> +	if (ret) {
> +		dev_dbg(dev, "Failed to initialize the lvts domain\n");

Why this is debug?

> +		return ret;
> +	}
> +
> +	/*
> +	 * At this point the LVTS is initialized and enabled. We can
> +	 * safely enable the interrupt.
> +	 */
> +	ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
> +					IRQF_ONESHOT, dev_name(dev), lvts_td);
> +	if (ret) {
> +		dev_dbg(dev, "Failed to request interrupt\n");

Ditto

> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, lvts_td);
> +
> +	return 0;
> +}
> +
> +static int lvts_remove(struct platform_device *pdev)
> +{
> +	struct lvts_domain *lvts_td;
> +	struct device *dev = &pdev->dev;
> +	int i;
> +
> +	lvts_td = platform_get_drvdata(pdev);
> +
> +	for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
> +		lvts_ctrl_disable(dev, &lvts_td->lvts_ctrl[i]);
> +
> +	lvts_debugfs_exit();
> +
> +	return 0;
> +}
> +
> +static struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {

Why this cannot be const?

> +	{
> +		.cal_offset = { 0x4, 0x7 },
> +		.lvts_sensor = {
> +			{ .dt_id = MT8195_MCU_BIG_CPU0 },
> +			{ .dt_id = MT8195_MCU_BIG_CPU1 }
> +		},
> +		.num_lvts_sensor = 2,
> +		.offset = 0x0,
> +		.hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
> +	},
> +

Drop blank line

> +	{

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3] dt-bindings: thermal: mediatek: Add LVTS thermal controllers
  2023-02-01  7:46       ` Krzysztof Kozlowski
@ 2023-02-01 13:34         ` Balsam CHIHI
  2023-02-01 13:37           ` Krzysztof Kozlowski
  0 siblings, 1 reply; 57+ messages in thread
From: Balsam CHIHI @ 2023-02-01 13:34 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

Hi Krzysztof

On Wed, Feb 1, 2023 at 8:46 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 31/01/2023 15:04, bchihi@baylibre.com wrote:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> >
> > Add LVTS thermal controllers dt-binding definition for mt8195.
> >
> > Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
> > ---
> > Changelog:
> >   v3:
> >      - Fixed subject prefix
> >      - Fixed licenses GPL-2.0-only OR BSD-2-Clause
> >        to GPL-2.0 OR MIT (to match DT)
> >      - Fixed matching dt-binding file names
>
> If this is v3 with only one patch, where is the driver or DTS using
> these bindings? Please link it. It's unusual to see only bindings,
> without the users.

sorry, I'll be careful next time.
and I will take into account the new change requests in the next full
version of the series.
I apologize for the mess.

>
> >   v2:
> >      - Fixed subject prefix
> >      - Fixed licenses GPL-2.0+ to GPL-2.0
> >      - Added dual licenses
>
> Is there a reason to make our review more difficult and keep versions
> broken, threads attached to some other threads?

sorry again.

>
> ------------
>
> Grabbing thread from
> lore.kernel.org/all/20230131140439.600164-1-bchihi%40baylibre.com/t.mbox.gz
> Checking for newer revisions on https://lore.kernel.org/all/
> Analyzing 38 messages in the thread
> Will use the latest revision: v12
> You can pick other revisions using the -vN flag
> Checking attestation on all messages, may take a moment...
> ---
>   ✓ [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal
> Sensor driver
>     ✓ Signed: DKIM/baylibre-com.20210112.gappssmtp.com (From:
> bchihi@baylibre.com)
>     + Link:
> https://lore.kernel.org/r/20230131153816.21709-1-bchihi@baylibre.com
>   ✓ [PATCH v12 2/6] dt-bindings: thermal: mediatek: Add LVTS thermal
> controllers dt-binding definition
>     ✓ Signed: DKIM/baylibre-com.20210112.gappssmtp.com (From:
> bchihi@baylibre.com)
>     + Link:
> https://lore.kernel.org/r/20230126161048.94089-1-bchihi@baylibre.com
>   ERROR: missing [3/1]!
>   ERROR: missing [4/1]!
>   ERROR: missing [5/1]!
>   ERROR: missing [6/1]!
>
> --------
>
> b4 diff '<20230131140439.600164-1-bchihi@baylibre.com>'
> Checking for older revisions on https://lore.kernel.org/all/
> ---
> Analyzing 38 messages in the thread
> Assuming new revision: v4 ([PATCH v12] thermal: drivers: mediatek: Add
> the Low Voltage Thermal Sensor driver)
> Preparing fake-am for v3: dt-bindings: thermal: mediatek: Add LVTS
> thermal controllers
>   range: 291580cde5f6..de7fe5e0293a
> Preparing fake-am for v12: arm64: dts: mediatek: mt8195: Add thermal
> zones and thermal nodes
>   ERROR: Could not find matching blob for
> arch/arm64/boot/dts/mediatek/mt8195.dtsi (09df105f4606)
>          If you know on which tree this patchset is based,
>          add it as a remote and perform "git remote update"
>          in order to fetch the missing objects.
> ---
> Could not create fake-am range for upper series v12
>
>
> > ---
> > ---
> >  .../thermal/mediatek,lvts-thermal.yaml        | 107 ++++++++++++++++++
> >  .../thermal/mediatek,lvts-thermal.h           |  19 ++++
> >  2 files changed, 126 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> >  create mode 100644 include/dt-bindings/thermal/mediatek,lvts-thermal.h
> >
> > diff --git a/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> > new file mode 100644
> > index 000000000000..5fa5c7a1a417
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
> > @@ -0,0 +1,107 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR MIT)
>
> WARNING: DT binding documents should be licensed (GPL-2.0-only OR
> BSD-2-Clause)
> #24: FILE:
> Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml:1:
> +# SPDX-License-Identifier: (GPL-2.0 OR MIT)
>
> I asked you to use the binding license for header file. Then you changed
> binding license... why? Why do you need other SPDX text? Why do you need
> MIT?

I will put it back "GPL-2.0-only OR BSD-2-Clause" in the binding and
do the same for the header.

>
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
> > +
> > +maintainers:
> > +  - Balsam CHIHI <bchihi@baylibre.com>
> > +
> > +description: |
> > +  LVTS is a thermal management architecture composed of three subsystems,
> > +  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
> > +  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
> > +  a Digital controller (LVTS_CTRL).
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - mediatek,mt8195-lvts-ap
> > +      - mediatek,mt8195-lvts-mcu
>
> What about other devices? You called the file name as generic for all
> Mediatek SoCs, so why only one SoC is here? Is there going to be more?
> If yes, why they cannot be added now?

Yes, there is another MTK SoC mt8192 that supports LVTS,
I was asked in v10 of the series to remove the unimplemented SoC.
It will be added later with the driver that supports it.
just let me know if you still want to add mt8192 bindings in the next
version without the driver.
(LVTS support for mt8192 will be sent in a different series).

>
> Best regards,
> Krzysztof
>

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3] dt-bindings: thermal: mediatek: Add LVTS thermal controllers
  2023-02-01 13:34         ` Balsam CHIHI
@ 2023-02-01 13:37           ` Krzysztof Kozlowski
  2023-02-01 13:56             ` Balsam CHIHI
  0 siblings, 1 reply; 57+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-01 13:37 UTC (permalink / raw)
  To: Balsam CHIHI
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

On 01/02/2023 14:34, Balsam CHIHI wrote:
>>> +
>>> +properties:
>>> +  compatible:
>>> +    enum:
>>> +      - mediatek,mt8195-lvts-ap
>>> +      - mediatek,mt8195-lvts-mcu
>>
>> What about other devices? You called the file name as generic for all
>> Mediatek SoCs, so why only one SoC is here? Is there going to be more?
>> If yes, why they cannot be added now?
> 
> Yes, there is another MTK SoC mt8192 that supports LVTS,
> I was asked in v10 of the series to remove the unimplemented SoC.
> It will be added later with the driver that supports it.
> just let me know if you still want to add mt8192 bindings in the next
> version without the driver.

The binding should be complete, if that's possible, so if you had mt8192
already there, it could stay. Anyway it's fine then.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v3] dt-bindings: thermal: mediatek: Add LVTS thermal controllers
  2023-02-01 13:37           ` Krzysztof Kozlowski
@ 2023-02-01 13:56             ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-02-01 13:56 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

Hi Krzysztof,

On Wed, Feb 1, 2023 at 2:37 PM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 01/02/2023 14:34, Balsam CHIHI wrote:
> >>> +
> >>> +properties:
> >>> +  compatible:
> >>> +    enum:
> >>> +      - mediatek,mt8195-lvts-ap
> >>> +      - mediatek,mt8195-lvts-mcu
> >>
> >> What about other devices? You called the file name as generic for all
> >> Mediatek SoCs, so why only one SoC is here? Is there going to be more?
> >> If yes, why they cannot be added now?
> >
> > Yes, there is another MTK SoC mt8192 that supports LVTS,
> > I was asked in v10 of the series to remove the unimplemented SoC.
> > It will be added later with the driver that supports it.
> > just let me know if you still want to add mt8192 bindings in the next
> > version without the driver.
>
> The binding should be complete, if that's possible, so if you had mt8192
> already there, it could stay. Anyway it's fine then.

OK, I will put back mt8192 dt-bindings.
this is the link to the v10 patch
"https://patchwork.kernel.org/project/linux-pm/patch/20230112152855.216072-3-bchihi@baylibre.com/",
it will be the same in next version (v13) of series.
it would be great if you review it in advance, so I could take into
account the new changes if needed.
is it possible to resend this patch under v13, to simplify the review
and avoid breaking the series again?

>
> Best regards,
> Krzysztof
>

Best regards,
Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-01  7:47       ` Krzysztof Kozlowski
@ 2023-02-01 15:14         ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-02-01 15:14 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: kernel test robot, daniel.lezcano, angelogioacchino.delregno,
	rafael, amitk, rui.zhang, matthias.bgg, robh+dt,
	krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel,
	oe-kbuild-all, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

Hi Krzysztof,

On Wed, Feb 1, 2023 at 8:47 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 01/02/2023 04:09, kernel test robot wrote:
> > Hi Balsam,
> >
> > Thank you for the patch! Yet something to improve:
> >
> >
> >
> > url:    https://github.com/intel-lab-lkp/linux/commits/UPDATE-20230131-234122/bchihi-baylibre-com/thermal-drivers-mediatek-Relocate-driver-to-mediatek-folder/20230124-211910
> > base:   the 4th patch of https://lore.kernel.org/r/20230124131717.128660-5-bchihi%40baylibre.com
> > patch link:    https://lore.kernel.org/r/20230131153816.21709-1-bchihi%40baylibre.com
> > patch subject: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
> > config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20230201/202302011058.17Vvc1pN-lkp@intel.com/config)
> > compiler: s390-linux-gcc (GCC) 12.1.0
> > reproduce (this is a W=1 build):
> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> >         chmod +x ~/bin/make.cross
> >         # https://github.com/intel-lab-lkp/linux/commit/5646ebf6f10ff0fc60c04d8c57523f7c44526b41
> >         git remote add linux-review https://github.com/intel-lab-lkp/linux
> >         git fetch --no-tags linux-review UPDATE-20230131-234122/bchihi-baylibre-com/thermal-drivers-mediatek-Relocate-driver-to-mediatek-folder/20230124-211910
> >         git checkout 5646ebf6f10ff0fc60c04d8c57523f7c44526b41
> >         # save the config file
> >         mkdir build_dir && cp config build_dir/.config
> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 olddefconfig
> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash
> >
> > If you fix the issue, kindly add following tag where applicable
> > | Reported-by: kernel test robot <lkp@intel.com>
> >
> > All errors (new ones prefixed by >>):
> >
> >>> drivers/thermal/mediatek/lvts_thermal.c:20:10: fatal error: dt-bindings/thermal/mediatek,lvts-thermal.h: No such file or directory
> >       20 | #include <dt-bindings/thermal/mediatek,lvts-thermal.h>
> >          |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> So here is your driver... and you decided not only to make reviewers
> life more difficult, but also to fail all automated tools.
>
> No, that's not how patchsets should be sent. You have here clear
> dependency, you cannot send them separately.

I'm sorry, I'll be careful next time.
I apologize for breaking the series.
I will take into account the new change requests in the next full
v13 the series.

>
> Best regards,
> Krzysztof
>

Best regards,
Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-01  7:55     ` Krzysztof Kozlowski
@ 2023-02-01 16:46       ` Balsam CHIHI
  2023-02-01 16:59         ` Matthias Brugger
  2023-02-01 17:12         ` Krzysztof Kozlowski
  2023-02-06 14:07       ` Daniel Lezcano
  1 sibling, 2 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-02-01 16:46 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

Hi Krzysztof,

Thank you very much for the review!

On Wed, Feb 1, 2023 at 8:55 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 31/01/2023 16:38, bchihi@baylibre.com wrote:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> >
> > The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
> > controllers contained in a thermal domain.
> >
> > A thermal domains can be the MCU or the AP.
> >
> > Each thermal domains contain up to seven controllers, each thermal
> > controller handle up to four thermal sensors.
> >
> > The LVTS has two Finite State Machines (FSM), one to handle the
> > functionin temperatures range like hot or cold temperature and another
> > one to handle monitoring trip point. The FSM notifies via interrupts
> > when a trip point is crossed.
> >
>
> (...)
>
> > +
> > +struct lvts_domain {
> > +     struct lvts_ctrl *lvts_ctrl;
> > +     struct reset_control *reset;
> > +     struct clk *clk;
> > +     int num_lvts_ctrl;
> > +     void __iomem *base;
> > +     size_t calib_len;
> > +     u8 *calib;
> > +};
> > +
> > +#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
> > +
> > +static struct dentry *root;
>
> How do you handle two instances of driver?

This root node is the topmost directory for debugfs called 'lvts', the
different driver instances are below this. It is a singleton.

>
> > +
> > +#define LVTS_DEBUG_FS_REGS(__reg)            \
> > +{                                            \
> > +     .name = __stringify(__reg),             \
> > +     .offset = __reg(0),                     \
> > +}
> > +
>
> (...)
>
> > +
> > +static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
> > +{
> > +     struct lvts_sensor *lvts_sensor = tz->devdata;
> > +     void __iomem *base = lvts_sensor->base;
> > +     u32 raw_low = lvts_temp_to_raw(low);
> > +     u32 raw_high = lvts_temp_to_raw(high);
> > +
> > +     /*
> > +      * Hot to normal temperature threshold
> > +      *
> > +      * LVTS_H2NTHRE
> > +      *
> > +      * Bits:
> > +      *
> > +      * 14-0 : Raw temperature for threshold
> > +      */
> > +     if (low != -INT_MAX) {
> > +             dev_dbg(&tz->device, "Setting low limit temperature interrupt: %d\n", low);
> > +             writel(raw_low, LVTS_H2NTHRE(base));
> > +     }
> > +
> > +     /*
> > +      * Hot temperature threshold
> > +      *
> > +      * LVTS_HTHRE
> > +      *
> > +      * Bits:
> > +      *
> > +      * 14-0 : Raw temperature for threshold
> > +      */
> > +     dev_dbg(&tz->device, "Setting high limit temperature interrupt: %d\n", high);
> > +     writel(raw_high, LVTS_HTHRE(base));
> > +
> > +     return 0;
> > +}
> > +
> > +static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
> > +{
> > +     irqreturn_t iret = IRQ_NONE;
> > +     u32 value, masks[] = {
>
> Don't mix different types in one declaration. u32 and a pointer are
> quite different types.

I'm not sure to understand.
LVTS_INT_SENSORx are not pointers but register values.

>
> > +             LVTS_INT_SENSOR0,
> > +             LVTS_INT_SENSOR1,
> > +             LVTS_INT_SENSOR2,
> > +             LVTS_INT_SENSOR3
> > +     };
> > +     int i;
> > +
> > +     /*
> > +      * Interrupt monitoring status
> > +      *
> > +      * LVTS_MONINTST
> > +      *
> > +      * Bits:
> > +      *
> > +      * 31 : Interrupt for stage 3
> > +      * 30 : Interrupt for stage 2
> > +      * 29 : Interrupt for state 1
> > +      * 28 : Interrupt using filter on sensor 3
> > +      *
> > +      * 27 : Interrupt using immediate on sensor 3
> > +      * 26 : Interrupt normal to hot on sensor 3
> > +      * 25 : Interrupt high offset on sensor 3
> > +      * 24 : Interrupt low offset on sensor 3
> > +      *
> > +      * 23 : Interrupt hot threshold on sensor 3
> > +      * 22 : Interrupt cold threshold on sensor 3
> > +      * 21 : Interrupt using filter on sensor 2
> > +      * 20 : Interrupt using filter on sensor 1
> > +      *
> > +      * 19 : Interrupt using filter on sensor 0
> > +      * 18 : Interrupt using immediate on sensor 2
> > +      * 17 : Interrupt using immediate on sensor 1
> > +      * 16 : Interrupt using immediate on sensor 0
> > +      *
> > +      * 15 : Interrupt device access timeout interrupt
> > +      * 14 : Interrupt normal to hot on sensor 2
> > +      * 13 : Interrupt high offset interrupt on sensor 2
> > +      * 12 : Interrupt low offset interrupt on sensor 2
> > +      *
> > +      * 11 : Interrupt hot threshold on sensor 2
> > +      * 10 : Interrupt cold threshold on sensor 2
> > +      *  9 : Interrupt normal to hot on sensor 1
> > +      *  8 : Interrupt high offset interrupt on sensor 1
> > +      *
> > +      *  7 : Interrupt low offset interrupt on sensor 1
> > +      *  6 : Interrupt hot threshold on sensor 1
> > +      *  5 : Interrupt cold threshold on sensor 1
> > +      *  4 : Interrupt normal to hot on sensor 0
> > +      *
> > +      *  3 : Interrupt high offset interrupt on sensor 0
> > +      *  2 : Interrupt low offset interrupt on sensor 0
> > +      *  1 : Interrupt hot threshold on sensor 0
> > +      *  0 : Interrupt cold threshold on sensor 0
> > +      *
> > +      * We are interested in the sensor(s) responsible of the
> > +      * interrupt event. We update the thermal framework with the
> > +      * thermal zone associated with the sensor. The framework will
> > +      * take care of the rest whatever the kind of interrupt, we
> > +      * are only interested in which sensor raised the interrupt.
> > +      *
> > +      * sensor 3 interrupt: 0001 1111 1100 0000 0000 0000 0000 0000
> > +      *                  => 0x1FC00000
> > +      * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000
> > +      *                  => 0x00247C00
> > +      * sensor 1 interrupt: 0000 0000 0001 0001 0000 0011 1110 0000
> > +      *                  => 0X000881F0
> > +      * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111
> > +      *                  => 0x0009001F
> > +      */
> > +     value = readl(LVTS_MONINTSTS(lvts_ctrl->base));
> > +
> > +     /*
> > +      * Let's figure out which sensors raised the interrupt
> > +      *
> > +      * NOTE: the masks array must be ordered with the index
> > +      * corresponding to the sensor id eg. index=0, mask for
> > +      * sensor0.
> > +      */
> > +     for (i = 0; i < ARRAY_SIZE(masks); i++) {
> > +
> > +             if (!(value & masks[i]))
> > +                     continue;
> > +
> > +             thermal_zone_device_update(lvts_ctrl->sensors[i].tz,
> > +                                        THERMAL_TRIP_VIOLATED);
> > +             iret = IRQ_HANDLED;
> > +     }
> > +
> > +     /*
> > +      * Write back to clear the interrupt status (W1C)
> > +      */
> > +     writel(value, LVTS_MONINTSTS(lvts_ctrl->base));
> > +
> > +     return iret;
> > +}
> > +
> > +/*
> > + * Temperature interrupt handler. Even if the driver supports more
> > + * interrupt modes, we use the interrupt when the temperature crosses
> > + * the hot threshold the way up and the way down (modulo the
> > + * hysteresis).
> > + *
> > + * Each thermal domain has a couple of interrupts, one for hardware
> > + * reset and another one for all the thermal events happening on the
> > + * different sensors.
> > + *
> > + * The interrupt is configured for thermal events when crossing the
> > + * hot temperature limit. At each interrupt, we check in every
> > + * controller if there is an interrupt pending.
> > + */
> > +static irqreturn_t lvts_irq_handler(int irq, void *data)
> > +{
> > +     struct lvts_domain *lvts_td = data;
> > +     irqreturn_t aux, iret = IRQ_NONE;
> > +     int i;
> > +
> > +     for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
> > +
> > +             aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl);
> > +             if (aux != IRQ_HANDLED)
> > +                     continue;
> > +
> > +             iret = IRQ_HANDLED;
> > +     }
> > +
> > +     return iret;
> > +}
> > +
> > +static struct thermal_zone_device_ops lvts_ops = {
> > +     .get_temp = lvts_get_temp,
> > +     .set_trips = lvts_set_trips,
> > +};
> > +
> > +static int __init lvts_sensor_init(struct device *dev,
> > +                                struct lvts_ctrl *lvts_ctrl,
> > +                                struct lvts_ctrl_data *lvts_ctrl_data)
> > +{
> > +     struct lvts_sensor *lvts_sensor = lvts_ctrl->sensors;
> > +     void __iomem *msr_regs[] = {
> > +             LVTS_MSR0(lvts_ctrl->base),
> > +             LVTS_MSR1(lvts_ctrl->base),
> > +             LVTS_MSR2(lvts_ctrl->base),
> > +             LVTS_MSR3(lvts_ctrl->base)
> > +     };
> > +
> > +     void __iomem *imm_regs[] = {
> > +             LVTS_IMMD0(lvts_ctrl->base),
> > +             LVTS_IMMD1(lvts_ctrl->base),
> > +             LVTS_IMMD2(lvts_ctrl->base),
> > +             LVTS_IMMD3(lvts_ctrl->base)
> > +     };
> > +
> > +     int i;
> > +
> > +     for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++) {
> > +
> > +             int dt_id = lvts_ctrl_data->lvts_sensor[i].dt_id;
> > +
> > +             /*
> > +              * At this point, we don't know which id matches which
> > +              * sensor. Let's set arbitrally the id from the index.
> > +              */
> > +             lvts_sensor[i].id = i;
> > +
> > +             /*
> > +              * The thermal zone registration will set the trip
> > +              * point interrupt in the thermal controller
> > +              * register. But this one will be reset in the
> > +              * initialization after. So we need to post pone the
> > +              * thermal zone creation after the controller is
> > +              * setup. For this reason, we store the device tree
> > +              * node id from the data in the sensor structure
> > +              */
> > +             lvts_sensor[i].dt_id = dt_id;
> > +
> > +             /*
> > +              * We assign the base address of the thermal
> > +              * controller as a back pointer. So it will be
> > +              * accessible from the different thermal framework ops
> > +              * as we pass the lvts_sensor pointer as thermal zone
> > +              * private data.
> > +              */
> > +             lvts_sensor[i].base = lvts_ctrl->base;
> > +
> > +             /*
> > +              * Each sensor has its own register address to read from.
> > +              */
> > +             lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
> > +                     imm_regs[i] : msr_regs[i];
> > +     };
> > +
> > +     lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
> > +
> > +     return 0;
> > +}
> > +
> > +/*
> > + * The efuse blob values follows the sensor enumeration per thermal
> > + * controller. The decoding of the stream is as follow:
> > + *
> > + *                        <--?-> <----big0 ???---> <-sensor0-> <-0->
> > + *                        ------------------------------------------
> > + * index in the stream: : | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 |
> > + *                        ------------------------------------------
> > + *
> > + *                        <--sensor1--><-0-> <----big1 ???---> <-sen
> > + *                        ------------------------------------------
> > + *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
> > + *                        ------------------------------------------
> > + *
> > + *                        sor0-> <-0-> <-sensor1-> <-0-> ..........
> > + *                        ------------------------------------------
> > + *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
> > + *                        ------------------------------------------
> > + *
> > + * And so on ...
> > + *
> > + * The data description gives the offset of the calibration data in
> > + * this bytes stream for each sensor.
> > + *
> > + * Each thermal controller can handle up to 4 sensors max, we don't
> > + * care if there are less as the array of calibration is sized to 4
> > + * anyway. The unused sensor slot will be zeroed.
> > + */
> > +static int __init lvts_calibration_init(struct device *dev,
> > +                                     struct lvts_ctrl *lvts_ctrl,
> > +                                     struct lvts_ctrl_data *lvts_ctrl_data,
> > +                                     u8 *efuse_calibration)
> > +{
> > +     int i;
> > +
> > +     for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++)
> > +             memcpy(&lvts_ctrl->calibration[i],
> > +                    efuse_calibration + lvts_ctrl_data->cal_offset[i], 2);
> > +
> > +     return 0;
> > +}
> > +
> > +/*
> > + * The efuse bytes stream can be split into different chunk of
> > + * nvmems. This function reads and concatenate those into a single
> > + * buffer so it can be read sequentially when initializing the
> > + * calibration data.
> > + */
> > +static int lvts_calibration_read(struct device *dev, struct lvts_domain *lvts_td,
> > +                              struct lvts_data *lvts_data)
> > +{
> > +     struct device_node *np = dev_of_node(dev);
> > +     struct nvmem_cell *cell;
> > +     struct property *prop;
> > +     const char *cell_name;
> > +
> > +     of_property_for_each_string(np, "nvmem-cell-names", prop, cell_name) {
> > +             size_t len;
> > +             u8 *efuse;
> > +
> > +             cell = of_nvmem_cell_get(np, cell_name);
> > +             if (IS_ERR(cell)) {
> > +                     dev_dbg(dev, "Failed to get cell '%s'\n", cell_name);
>
> Is this an error? If so, why debug? dbg is not for errors.

AFAIK using dev_dbg does not increase ELF size when DEBUG is disabled.
If this is not a good reason for you, then I will change it to dev_err.

>
> > +                     return PTR_ERR(cell);
> > +             }
> > +
> > +             efuse = nvmem_cell_read(cell, &len);
> > +
> > +             nvmem_cell_put(cell);
> > +
> > +             if (IS_ERR(efuse)) {
> > +                     dev_dbg(dev, "Failed to read cell '%s'\n", cell_name);
> > +                     return PTR_ERR(efuse);
> > +             }
> > +
> > +             lvts_td->calib = devm_krealloc(dev, lvts_td->calib,
> > +                                            lvts_td->calib_len + len, GFP_KERNEL);
> > +             if (!lvts_td->calib)
> > +                     return -ENOMEM;
> > +
> > +             memcpy(lvts_td->calib + lvts_td->calib_len, efuse, len);
> > +
> > +             lvts_td->calib_len += len;
> > +
> > +             kfree(efuse);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int __init lvts_golden_temp_init(struct device *dev, u32 *value)
>
> You did not test it, right? Build with section mismatch analysis...

I'm not sure to fully understand this comment.
Would you explain, please?

>
> > +{
> > +     u32 gt;
> > +
> > +     gt = (*value) >> 24;
> > +
> > +     if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
> > +             golden_temp = gt;
> > +
> > +     coeff_b = golden_temp * 500 + LVTS_COEFF_B;
> > +
> > +     return 0;
> > +}
> > +
> > +static int __init lvts_ctrl_init(struct device *dev,
>
> Same problem.

Would you explain, please?

>
> > +                              struct lvts_domain *lvts_td,
> > +                              struct lvts_data *lvts_data)
> > +{
> > +     size_t size = sizeof(*lvts_td->lvts_ctrl) * lvts_data->num_lvts_ctrl;
> > +     struct lvts_ctrl *lvts_ctrl;
> > +     int i, ret;
> > +
>
> > +
> > +static inline int lvts_ctrl_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> > +{
> > +     return lvts_ctrl_set_enable(lvts_ctrl, 1);
>
> Drop the wrapper, it's useless. true or false for enable are quite obvious.

OK.

>
> > +}
> > +
> > +static inline int lvts_ctrl_disable(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> > +{
> > +     return lvts_ctrl_set_enable(lvts_ctrl, 0);
>
> Drop the wrapper.

OK.

>
> > +}
> > +
> > +static int lvts_ctrl_connect(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> > +{
> > +     u32 id, cmds[] = { 0xC103FFFF, 0xC502FF55 };
> > +
> > +     lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
> > +
> > +     /*
> > +      * LVTS_ID : Get ID and status of the thermal controller
> > +      *
> > +      * Bits:
> > +      *
> > +      * 0-5  : thermal controller id
> > +      *   7  : thermal controller connection is valid
> > +      */
> > +     id = readl(LVTS_ID(lvts_ctrl->base));
> > +     if (!(id & BIT(7)))
> > +             return -EIO;
> > +
> > +     return 0;
> > +}
> > +
> > +static int lvts_ctrl_initialize(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> > +{
> > +     /*
> > +      * Write device mask: 0xC1030000
> > +      */
> > +     u32 cmds[] = {
> > +             0xC1030E01, 0xC1030CFC, 0xC1030A8C, 0xC103098D, 0xC10308F1,
> > +             0xC10307A6, 0xC10306B8, 0xC1030500, 0xC1030420, 0xC1030300,
> > +             0xC1030030, 0xC10300F6, 0xC1030050, 0xC1030060, 0xC10300AC,
> > +             0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
> > +     };
> > +
> > +     lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
> > +
> > +     return 0;
> > +}
> > +
> > +static int lvts_ctrl_calibrate(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> > +{
> > +     int i;
> > +     void __iomem *lvts_edata[] = {
> > +             LVTS_EDATA00(lvts_ctrl->base),
> > +             LVTS_EDATA01(lvts_ctrl->base),
> > +             LVTS_EDATA02(lvts_ctrl->base),
> > +             LVTS_EDATA03(lvts_ctrl->base)
> > +     };
> > +
> > +     /*
> > +      * LVTS_EDATA0X : Efuse calibration reference value for sensor X
> > +      *
> > +      * Bits:
> > +      *
> > +      * 20-0 : Efuse value for normalization data
> > +      */
> > +     for (i = 0; i < LVTS_SENSOR_MAX; i++)
> > +             writel(lvts_ctrl->calibration[i], lvts_edata[i]);
> > +
> > +     return 0;
> > +}
> > +
> > +static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> > +{
> > +     u32 value;
> > +
> > +     /*
> > +      * LVTS_TSSEL : Sensing point index numbering
> > +      *
> > +      * Bits:
> > +      *
> > +      * 31-24: ADC Sense 3
> > +      * 23-16: ADC Sense 2
> > +      * 15-8 : ADC Sense 1
> > +      * 7-0  : ADC Sense 0
> > +      */
> > +     value = LVTS_TSSEL_CONF;
> > +     writel(value, LVTS_TSSEL(lvts_ctrl->base));
> > +
> > +     /*
> > +      * LVTS_CALSCALE : ADC voltage round
> > +      */
> > +     value = 0x300;
> > +     value = LVTS_CALSCALE_CONF;
> > +
> > +     /*
> > +      * LVTS_MSRCTL0 : Sensor filtering strategy
> > +      *
> > +      * Filters:
> > +      *
> > +      * 000 : One sample
> > +      * 001 : Avg 2 samples
> > +      * 010 : 4 samples, drop min and max, avg 2 samples
> > +      * 011 : 6 samples, drop min and max, avg 4 samples
> > +      * 100 : 10 samples, drop min and max, avg 8 samples
> > +      * 101 : 18 samples, drop min and max, avg 16 samples
> > +      *
> > +      * Bits:
> > +      *
> > +      * 0-2  : Sensor0 filter
> > +      * 3-5  : Sensor1 filter
> > +      * 6-8  : Sensor2 filter
> > +      * 9-11 : Sensor3 filter
> > +      */
> > +     value = LVTS_HW_FILTER << 9 |  LVTS_HW_FILTER << 6 |
> > +                     LVTS_HW_FILTER << 3 | LVTS_HW_FILTER;
> > +     writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
> > +
> > +     /*
> > +      * LVTS_MSRCTL1 : Measurement control
> > +      *
> > +      * Bits:
> > +      *
> > +      * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
> > +      * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
> > +      * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
> > +      * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
> > +      *
> > +      * That configuration will ignore the filtering and the delays
> > +      * introduced below in MONCTL1 and MONCTL2
> > +      */
> > +     if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
> > +             value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
> > +             writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
> > +     }
> > +
> > +     /*
> > +      * LVTS_MONCTL1 : Period unit and group interval configuration
> > +      *
> > +      * The clock source of LVTS thermal controller is 26MHz.
> > +      *
> > +      * The period unit is a time base for all the interval delays
> > +      * specified in the registers. By default we use 12. The time
> > +      * conversion is done by multiplying by 256 and 1/26.10^6
> > +      *
> > +      * An interval delay multiplied by the period unit gives the
> > +      * duration in seconds.
> > +      *
> > +      * - Filter interval delay is a delay between two samples of
> > +      * the same sensor.
> > +      *
> > +      * - Sensor interval delay is a delay between two samples of
> > +      * different sensors.
> > +      *
> > +      * - Group interval delay is a delay between different rounds.
> > +      *
> > +      * For example:
> > +      *     If Period unit = C, filter delay = 1, sensor delay = 2, group delay = 1,
> > +      *     and two sensors, TS1 and TS2, are in a LVTS thermal controller
> > +      *     and then
> > +      *     Period unit time = C * 1/26M * 256 = 12 * 38.46ns * 256 = 118.149us
> > +      *     Filter interval delay = 1 * Period unit = 118.149us
> > +      *     Sensor interval delay = 2 * Period unit = 236.298us
> > +      *     Group interval delay = 1 * Period unit = 118.149us
> > +      *
> > +      *     TS1    TS1 ... TS1    TS2    TS2 ... TS2    TS1...
> > +      *        <--> Filter interval delay
> > +      *                       <--> Sensor interval delay
> > +      *                                             <--> Group interval delay
> > +      * Bits:
> > +      *      29 - 20 : Group interval
> > +      *      16 - 13 : Send a single interrupt when crossing the hot threshold (1)
> > +      *                or an interrupt everytime the hot threshold is crossed (0)
> > +      *       9 - 0  : Period unit
> > +      *
> > +      */
> > +     value = LVTS_GROUP_INTERVAL << 20 | LVTS_PERIOD_UNIT;
> > +     writel(value, LVTS_MONCTL1(lvts_ctrl->base));
> > +
> > +     /*
> > +      * LVTS_MONCTL2 : Filtering and sensor interval
> > +      *
> > +      * Bits:
> > +      *
> > +      *      25-16 : Interval unit in PERIOD_UNIT between sample on
> > +      *              the same sensor, filter interval
> > +      *       9-0  : Interval unit in PERIOD_UNIT between each sensor
> > +      *
> > +      */
> > +     value = LVTS_FILTER_INTERVAL << 16 | LVTS_SENSOR_INTERVAL;
> > +     writel(value, LVTS_MONCTL2(lvts_ctrl->base));
> > +
> > +     return lvts_irq_init(lvts_ctrl);
> > +}
> > +
> > +static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
> > +{
> > +     struct lvts_sensor *lvts_sensors = lvts_ctrl->sensors;
> > +     struct thermal_zone_device *tz;
> > +     u32 sensor_map = 0;
> > +     int i;
> > +
> > +     for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
> > +
> > +             int dt_id = lvts_sensors[i].dt_id;
> > +
> > +             tz = devm_thermal_of_zone_register(dev, dt_id, &lvts_sensors[i],
> > +                                                &lvts_ops);
> > +             if (IS_ERR(tz)) {
> > +                     /*
> > +                      * This thermal zone is not described in the
> > +                      * device tree. It is not an error from the
> > +                      * thermal OF code POV, we just continue.
> > +                      */
> > +                     if (PTR_ERR(tz) == -ENODEV)
> > +                             continue;
> > +
> > +                     return PTR_ERR(tz);
> > +             }
> > +
> > +             /*
> > +              * The thermal zone pointer will be needed in the
> > +              * interrupt handler, we store it in the sensor
> > +              * structure. The thermal domain structure will be
> > +              * passed to the interrupt handler private data as the
> > +              * interrupt is shared for all the controller
> > +              * belonging to the thermal domain.
> > +              */
> > +             lvts_sensors[i].tz = tz;
> > +
> > +             /*
> > +              * This sensor was correctly associated with a thermal
> > +              * zone, let's set the corresponding bit in the sensor
> > +              * map, so we can enable the temperature monitoring in
> > +              * the hardware thermal controller.
> > +              */
> > +             sensor_map |= BIT(i);
> > +     }
> > +
> > +     /*
> > +      * Bits:
> > +      *      9: Single point access flow
> > +      *    0-3: Enable sensing point 0-3
> > +      *
> > +      * The initialization of the thermal zones give us
> > +      * which sensor point to enable. If any thermal zone
> > +      * was not described in the device tree, it won't be
> > +      * enabled here in the sensor map.
> > +      */
> > +     writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
> > +
> > +     return 0;
> > +}
> > +
> > +static int lvts_domain_init(struct device *dev, struct lvts_domain *lvts_td,
> > +                         struct lvts_data *lvts_data)
> > +{
> > +     struct lvts_ctrl *lvts_ctrl;
> > +     int i, ret;
> > +
> > +     ret = lvts_ctrl_init(dev, lvts_td, lvts_data);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = lvts_domain_reset(dev, lvts_td->reset);
> > +     if (ret) {
> > +             dev_dbg(dev, "Failed to reset domain");
> > +             return ret;
> > +     }
> > +
> > +     for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
> > +
> > +             lvts_ctrl = &lvts_td->lvts_ctrl[i];
> > +
> > +             /*
> > +              * Initialization steps:
> > +              *
> > +              * - Enable the clock
> > +              * - Connect to the LVTS
> > +              * - Initialize the LVTS
> > +              * - Prepare the calibration data
> > +              * - Select monitored sensors
> > +              * [ Configure sampling ]
> > +              * [ Configure the interrupt ]
> > +              * - Start measurement
> > +              */
> > +             ret = lvts_ctrl_enable(dev, lvts_ctrl);
> > +             if (ret) {
> > +                     dev_dbg(dev, "Failed to enable LVTS clock");
> > +                     return ret;
> > +             }
> > +
> > +             ret = lvts_ctrl_connect(dev, lvts_ctrl);
> > +             if (ret) {
> > +                     dev_dbg(dev, "Failed to connect to LVTS controller");
> > +                     return ret;
> > +             }
> > +
> > +             ret = lvts_ctrl_initialize(dev, lvts_ctrl);
> > +             if (ret) {
> > +                     dev_dbg(dev, "Failed to initialize controller");
> > +                     return ret;
> > +             }
> > +
> > +             ret = lvts_ctrl_calibrate(dev, lvts_ctrl);
> > +             if (ret) {
> > +                     dev_dbg(dev, "Failed to calibrate controller");
> > +                     return ret;
> > +             }
> > +
> > +             ret = lvts_ctrl_configure(dev, lvts_ctrl);
> > +             if (ret) {
> > +                     dev_dbg(dev, "Failed to configure controller");
> > +                     return ret;
> > +             }
> > +
> > +             ret = lvts_ctrl_start(dev, lvts_ctrl);
> > +             if (ret) {
> > +                     dev_dbg(dev, "Failed to start controller");
> > +                     return ret;
> > +             }
> > +     }
> > +
> > +     return lvts_debugfs_init(dev, lvts_td);
> > +}
> > +
> > +static int lvts_probe(struct platform_device *pdev)
> > +{
> > +     struct lvts_data *lvts_data;
> > +     struct lvts_domain *lvts_td;
> > +     struct device *dev = &pdev->dev;
> > +     struct resource *res;
> > +     int irq, ret;
> > +
> > +     lvts_td = devm_kzalloc(dev, sizeof(*lvts_td), GFP_KERNEL);
> > +     if (!lvts_td)
> > +             return -ENOMEM;
> > +
> > +     lvts_data = (struct lvts_data *)of_device_get_match_data(dev);
>
> Why do you need case?

Would you explain, please?

>
> > +     if (!lvts_data) {
> > +             dev_dbg(dev, "No platforme
>
> Drop. How is it even possible?

OK,
All "dev_dbg" in "probe" function will be replaced by "dev_err_probe"

>
> > +             return -ENODATA;
> > +     };
> > +
> > +     lvts_td->clk = devm_clk_get_enabled(dev, NULL);
> > +     if (IS_ERR(lvts_td->clk)) {
> > +             dev_dbg(dev, "Failed to retrieve clock\n");
>
> Drop all debug statements. Either this is an error (so return
> dev_err_probe) or core handles messages.

I will change it to dev_err_probe.

>
> > +             return PTR_ERR(lvts_td->clk);
> > +     }
> > +
> > +     res = platform_get_mem_or_io(pdev, 0);
> > +     if (!res) {
> > +             dev_dbg(dev, "No IO resource\n");
>
> Ditto
>
> > +             return -ENXIO;
> > +     }
> > +
> > +     lvts_td->base = devm_ioremap_resource(dev, res);
>
> Why not using single wrapper for this?

OK,
I will chnagne it to "lvts_td->base =
devm_platform_get_and_ioremap_resource(pdev, 0, &res);"

>
> > +     if (IS_ERR(lvts_td->base)) {
> > +             dev_dbg(dev, "Failed to map io resource\n");
>
> Ditto

I will change it to dev_err_probe.

>
> > +             return PTR_ERR(lvts_td->base);
> > +     }
> > +
> > +     lvts_td->reset = devm_reset_control_get_by_index(dev, 0);
> > +     if (IS_ERR(lvts_td->reset)) {
> > +             dev_dbg(dev, "Failed to get reset control\n");
>
> Ditto

I will change it to dev_err_probe.

>
> > +             return PTR_ERR(lvts_td->reset);
> > +     }
> > +
> > +     irq = platform_get_irq(pdev, 0);
> > +     if (irq < 0) {
> > +             dev_dbg(dev, "No irq resource\n");
>
> Ditto

I will change it to dev_err_probe.

>
> > +             return irq;
> > +     }
> > +
> > +     ret = lvts_domain_init(dev, lvts_td, lvts_data);
> > +     if (ret) {
> > +             dev_dbg(dev, "Failed to initialize the lvts domain\n");
>
> Why this is debug?

I will change it to dev_err_probe.

>
> > +             return ret;
> > +     }
> > +
> > +     /*
> > +      * At this point the LVTS is initialized and enabled. We can
> > +      * safely enable the interrupt.
> > +      */
> > +     ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
> > +                                     IRQF_ONESHOT, dev_name(dev), lvts_td);
> > +     if (ret) {
> > +             dev_dbg(dev, "Failed to request interrupt\n");
>
> Ditto

I will change it to dev_err_probe.

>
> > +             return ret;
> > +     }
> > +
> > +     platform_set_drvdata(pdev, lvts_td);
> > +
> > +     return 0;
> > +}
> > +
> > +static int lvts_remove(struct platform_device *pdev)
> > +{
> > +     struct lvts_domain *lvts_td;
> > +     struct device *dev = &pdev->dev;
> > +     int i;
> > +
> > +     lvts_td = platform_get_drvdata(pdev);
> > +
> > +     for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
> > +             lvts_ctrl_disable(dev, &lvts_td->lvts_ctrl[i]);
> > +
> > +     lvts_debugfs_exit();
> > +
> > +     return 0;
> > +}
> > +
> > +static struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {
>
> Why this cannot be const?

I've got the following warning when I added "const"
drivers/thermal/mediatek/lvts_thermal.c:1286:27: warning:
initialization discards ‘const’ qualifier from pointer target type
[-Wdiscarded-qualifiers]
 1286 |         .lvts_ctrl      = mt8195_lvts_data_ctrl,
      |                           ^~~~~~~~~~~~~~~~~~~~~~~~~
Still working on it.
Any suggestion will be helpful, thanks!

>
> > +     {
> > +             .cal_offset = { 0x4, 0x7 },
> > +             .lvts_sensor = {
> > +                     { .dt_id = MT8195_MCU_BIG_CPU0 },
> > +                     { .dt_id = MT8195_MCU_BIG_CPU1 }
> > +             },
> > +             .num_lvts_sensor = 2,
> > +             .offset = 0x0,
> > +             .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
> > +     },
> > +
>
> Drop blank line

OK,
I will do the same for other blank lines.

>
> > +     {
>
> Best regards,
> Krzysztof
>

Best regards,
Balsam.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-01 16:46       ` Balsam CHIHI
@ 2023-02-01 16:59         ` Matthias Brugger
  2023-02-03 10:35           ` Balsam CHIHI
  2023-02-01 17:12         ` Krzysztof Kozlowski
  1 sibling, 1 reply; 57+ messages in thread
From: Matthias Brugger @ 2023-02-01 16:59 UTC (permalink / raw)
  To: Balsam CHIHI, Krzysztof Kozlowski
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen,
	p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen



On 01/02/2023 17:46, Balsam CHIHI wrote:
> Hi Krzysztof,
> 
> Thank you very much for the review!
> 
> On Wed, Feb 1, 2023 at 8:55 AM Krzysztof Kozlowski
> <krzysztof.kozlowski@linaro.org> wrote:
>>
>> On 31/01/2023 16:38, bchihi@baylibre.com wrote:
>>> From: Balsam CHIHI <bchihi@baylibre.com>
>>>

[...]

>>> +
>>> +static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
>>> +{
>>> +     irqreturn_t iret = IRQ_NONE;
>>> +     u32 value, masks[] = {
>>
>> Don't mix different types in one declaration. u32 and a pointer are
>> quite different types.
> 
> I'm not sure to understand.
> LVTS_INT_SENSORx are not pointers but register values.
> 

u32 mask[] is a pointer to a array of u32 values of undefined length.

[...]

>>> +static int __init lvts_golden_temp_init(struct device *dev, u32 *value)
>>
>> You did not test it, right? Build with section mismatch analysis...
> 
> I'm not sure to fully understand this comment.
> Would you explain, please?
> 

AFAIU:

lvts_golden_temp_init() and lvts_ctrl_init() are called from a function that is 
not in __init section:
lvts_domain_init()

So if you free up the first to functions after init but not the callers, things 
can explote.

[...]

>>> +
>>> +static int lvts_probe(struct platform_device *pdev)
>>> +{
>>> +     struct lvts_data *lvts_data;
>>> +     struct lvts_domain *lvts_td;
>>> +     struct device *dev = &pdev->dev;
>>> +     struct resource *res;
>>> +     int irq, ret;
>>> +
>>> +     lvts_td = devm_kzalloc(dev, sizeof(*lvts_td), GFP_KERNEL);
>>> +     if (!lvts_td)
>>> +             return -ENOMEM;
>>> +
>>> +     lvts_data = (struct lvts_data *)of_device_get_match_data(dev);
>>
>> Why do you need case?
> 
> Would you explain, please?
> 

Typo by Krysztof, he meant the cast.
lvts_data = of_device_get_match_data(dev);
should be good enough.

Regards,
Matthias

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-01 16:46       ` Balsam CHIHI
  2023-02-01 16:59         ` Matthias Brugger
@ 2023-02-01 17:12         ` Krzysztof Kozlowski
  2023-02-03 11:06           ` Balsam CHIHI
  1 sibling, 1 reply; 57+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-01 17:12 UTC (permalink / raw)
  To: Balsam CHIHI
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

On 01/02/2023 17:46, Balsam CHIHI wrote:
>>> +#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
>>> +
>>> +static struct dentry *root;
>>
>> How do you handle two instances of driver?
> 
> This root node is the topmost directory for debugfs called 'lvts', the
> different driver instances are below this. It is a singleton.

Indeed. What about removal? Aren't you remobing entire directory
structure on first device removal?

(...)

>>> +
>>> +     of_property_for_each_string(np, "nvmem-cell-names", prop, cell_name) {
>>> +             size_t len;
>>> +             u8 *efuse;
>>> +
>>> +             cell = of_nvmem_cell_get(np, cell_name);
>>> +             if (IS_ERR(cell)) {
>>> +                     dev_dbg(dev, "Failed to get cell '%s'\n", cell_name);
>>
>> Is this an error? If so, why debug? dbg is not for errors.
> 
> AFAIK using dev_dbg does not increase ELF size when DEBUG is disabled.
> If this is not a good reason for you, then I will change it to dev_err.

But also dev_dbg are not visible in error or warn level logs. If this is
not an error, then indeed dev_dbg could be fine. But errors should be
verbose.

> 
>>
>>> +                     return PTR_ERR(cell);
>>> +             }
>>> +
>>> +             efuse = nvmem_cell_read(cell, &len);
>>> +
>>> +             nvmem_cell_put(cell);
>>> +
>>> +             if (IS_ERR(efuse)) {
>>> +                     dev_dbg(dev, "Failed to read cell '%s'\n", cell_name);
>>> +                     return PTR_ERR(efuse);
>>> +             }
>>> +
>>> +             lvts_td->calib = devm_krealloc(dev, lvts_td->calib,
>>> +                                            lvts_td->calib_len + len, GFP_KERNEL);
>>> +             if (!lvts_td->calib)
>>> +                     return -ENOMEM;
>>> +
>>> +             memcpy(lvts_td->calib + lvts_td->calib_len, efuse, len);
>>> +
>>> +             lvts_td->calib_len += len;
>>> +
>>> +             kfree(efuse);
>>> +     }
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static int __init lvts_golden_temp_init(struct device *dev, u32 *value)
>>
>> You did not test it, right? Build with section mismatch analysis...
> 
> I'm not sure to fully understand this comment.
> Would you explain, please?

git grep -i "section mismatch" leads to lib/Kconfig.debug and
DEBUG_SECTION_MISMATCH

(...)

>>> +static struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {
>>
>> Why this cannot be const?
> 
> I've got the following warning when I added "const"
> drivers/thermal/mediatek/lvts_thermal.c:1286:27: warning:
> initialization discards ‘const’ qualifier from pointer target type
> [-Wdiscarded-qualifiers]
>  1286 |         .lvts_ctrl      = mt8195_lvts_data_ctrl,
>       |                           ^~~~~~~~~~~~~~~~~~~~~~~~~

As with every const... Do you need lvts_ctrl to be non-const? If yes,
then how do you handle multiple devices (singleton)?

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-01 16:59         ` Matthias Brugger
@ 2023-02-03 10:35           ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-02-03 10:35 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Krzysztof Kozlowski, daniel.lezcano, angelogioacchino.delregno,
	rafael, amitk, rui.zhang, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

Hi Matthias,

On Wed, Feb 1, 2023 at 5:59 PM Matthias Brugger <matthias.bgg@gmail.com> wrote:
>
>
>
> On 01/02/2023 17:46, Balsam CHIHI wrote:
> > Hi Krzysztof,
> >
> > Thank you very much for the review!
> >
> > On Wed, Feb 1, 2023 at 8:55 AM Krzysztof Kozlowski
> > <krzysztof.kozlowski@linaro.org> wrote:
> >>
> >> On 31/01/2023 16:38, bchihi@baylibre.com wrote:
> >>> From: Balsam CHIHI <bchihi@baylibre.com>
> >>>
>
> [...]
>
> >>> +
> >>> +static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
> >>> +{
> >>> +     irqreturn_t iret = IRQ_NONE;
> >>> +     u32 value, masks[] = {
> >>
> >> Don't mix different types in one declaration. u32 and a pointer are
> >> quite different types.
> >
> > I'm not sure to understand.
> > LVTS_INT_SENSORx are not pointers but register values.
> >
>
> u32 mask[] is a pointer to a array of u32 values of undefined length.
>

I will change this to :
u32 value;
u32 masks[] = {

> [...]
>
> >>> +static int __init lvts_golden_temp_init(struct device *dev, u32 *value)
> >>
> >> You did not test it, right? Build with section mismatch analysis...
> >
> > I'm not sure to fully understand this comment.
> > Would you explain, please?
> >
>
> AFAIU:
>
> lvts_golden_temp_init() and lvts_ctrl_init() are called from a function that is
> not in __init section:
> lvts_domain_init()
>
> So if you free up the first to functions after init but not the callers, things
> can explote.
>

__init will be removed for all functions.

> [...]
>
> >>> +
> >>> +static int lvts_probe(struct platform_device *pdev)
> >>> +{
> >>> +     struct lvts_data *lvts_data;
> >>> +     struct lvts_domain *lvts_td;
> >>> +     struct device *dev = &pdev->dev;
> >>> +     struct resource *res;
> >>> +     int irq, ret;
> >>> +
> >>> +     lvts_td = devm_kzalloc(dev, sizeof(*lvts_td), GFP_KERNEL);
> >>> +     if (!lvts_td)
> >>> +             return -ENOMEM;
> >>> +
> >>> +     lvts_data = (struct lvts_data *)of_device_get_match_data(dev);
> >>
> >> Why do you need case?
> >
> > Would you explain, please?
> >
>
> Typo by Krysztof, he meant the cast.
> lvts_data = of_device_get_match_data(dev);
> should be good enough.
>

OK,
It will be like you suggested.

> Regards,
> Matthias

Thank you for the review!

Best regards,
Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-01 17:12         ` Krzysztof Kozlowski
@ 2023-02-03 11:06           ` Balsam CHIHI
  0 siblings, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-02-03 11:06 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

Hi Krzysztof,

On Wed, Feb 1, 2023 at 6:12 PM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 01/02/2023 17:46, Balsam CHIHI wrote:
> >>> +#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
> >>> +
> >>> +static struct dentry *root;
> >>
> >> How do you handle two instances of driver?
> >
> > This root node is the topmost directory for debugfs called 'lvts', the
> > different driver instances are below this. It is a singleton.
>
> Indeed. What about removal? Aren't you remobing entire directory
> structure on first device removal?
>

For now, the driver only supports one instance.
I will find a way to handle this when the driver supports more instances.
Is this suggestion OK for you?

> (...)
>
> >>> +
> >>> +     of_property_for_each_string(np, "nvmem-cell-names", prop, cell_name) {
> >>> +             size_t len;
> >>> +             u8 *efuse;
> >>> +
> >>> +             cell = of_nvmem_cell_get(np, cell_name);
> >>> +             if (IS_ERR(cell)) {
> >>> +                     dev_dbg(dev, "Failed to get cell '%s'\n", cell_name);
> >>
> >> Is this an error? If so, why debug? dbg is not for errors.
> >
> > AFAIK using dev_dbg does not increase ELF size when DEBUG is disabled.
> > If this is not a good reason for you, then I will change it to dev_err.
>
> But also dev_dbg are not visible in error or warn level logs. If this is
> not an error, then indeed dev_dbg could be fine. But errors should be
> verbose.

OK,
I will replace all "dev_dbg" with "dev_err" in this function.

>
> >
> >>
> >>> +                     return PTR_ERR(cell);
> >>> +             }
> >>> +
> >>> +             efuse = nvmem_cell_read(cell, &len);
> >>> +
> >>> +             nvmem_cell_put(cell);
> >>> +
> >>> +             if (IS_ERR(efuse)) {
> >>> +                     dev_dbg(dev, "Failed to read cell '%s'\n", cell_name);
> >>> +                     return PTR_ERR(efuse);
> >>> +             }
> >>> +
> >>> +             lvts_td->calib = devm_krealloc(dev, lvts_td->calib,
> >>> +                                            lvts_td->calib_len + len, GFP_KERNEL);
> >>> +             if (!lvts_td->calib)
> >>> +                     return -ENOMEM;
> >>> +
> >>> +             memcpy(lvts_td->calib + lvts_td->calib_len, efuse, len);
> >>> +
> >>> +             lvts_td->calib_len += len;
> >>> +
> >>> +             kfree(efuse);
> >>> +     }
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +
> >>> +static int __init lvts_golden_temp_init(struct device *dev, u32 *value)
> >>
> >> You did not test it, right? Build with section mismatch analysis...
> >
> > I'm not sure to fully understand this comment.
> > Would you explain, please?
>
> git grep -i "section mismatch" leads to lib/Kconfig.debug and
> DEBUG_SECTION_MISMATCH

__init is removed from all functions.

>
> (...)
>
> >>> +static struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {
> >>
> >> Why this cannot be const?
> >
> > I've got the following warning when I added "const"
> > drivers/thermal/mediatek/lvts_thermal.c:1286:27: warning:
> > initialization discards ‘const’ qualifier from pointer target type
> > [-Wdiscarded-qualifiers]
> >  1286 |         .lvts_ctrl      = mt8195_lvts_data_ctrl,
> >       |                           ^~~~~~~~~~~~~~~~~~~~~~~~~
>
> As with every const... Do you need lvts_ctrl to be non-const? If yes,
> then how do you handle multiple devices (singleton)?
>

I found a fix for this it was simple.
add const here as you suggested
and in other function parameters every time we use this variable.

> Best regards,
> Krzysztof
>

Thank you for the review!

Best regards,
Balsam

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-01  7:55     ` Krzysztof Kozlowski
  2023-02-01 16:46       ` Balsam CHIHI
@ 2023-02-06 14:07       ` Daniel Lezcano
  2023-02-06 14:30         ` Krzysztof Kozlowski
  2023-02-06 14:32         ` Balsam CHIHI
  1 sibling, 2 replies; 57+ messages in thread
From: Daniel Lezcano @ 2023-02-06 14:07 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: bchihi, angelogioacchino.delregno, rafael, amitk, rui.zhang,
	matthias.bgg, robh+dt, krzysztof.kozlowski+dt, rdunlap,
	ye.xingchen, p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On Wed, Feb 01, 2023 at 08:55:07AM +0100, Krzysztof Kozlowski wrote:
> On 31/01/2023 16:38, bchihi@baylibre.com wrote:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> > 
> > The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
> > controllers contained in a thermal domain.
> > 
> > A thermal domains can be the MCU or the AP.
> > 
> > Each thermal domains contain up to seven controllers, each thermal
> > controller handle up to four thermal sensors.
> > 
> > The LVTS has two Finite State Machines (FSM), one to handle the
> > functionin temperatures range like hot or cold temperature and another
> > one to handle monitoring trip point. The FSM notifies via interrupts
> > when a trip point is crossed.
> > 
> 
> (...)
> 
> > +
> > +struct lvts_domain {
> > +	struct lvts_ctrl *lvts_ctrl;
> > +	struct reset_control *reset;
> > +	struct clk *clk;
> > +	int num_lvts_ctrl;
> > +	void __iomem *base;
> > +	size_t calib_len;
> > +	u8 *calib;
> > +};
> > +
> > +#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
> > +
> > +static struct dentry *root;
> 
> How do you handle two instances of driver?

For now, we can put the entry in /sys/kernel/debug/<dev_name>

I'm preparing a debugfs series for the thermal framework and that will provide
an entry to hook in for the sensors debugfs if available

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-06 14:07       ` Daniel Lezcano
@ 2023-02-06 14:30         ` Krzysztof Kozlowski
  2023-02-06 14:38           ` Daniel Lezcano
  2023-02-06 14:32         ` Balsam CHIHI
  1 sibling, 1 reply; 57+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-06 14:30 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: bchihi, angelogioacchino.delregno, rafael, amitk, rui.zhang,
	matthias.bgg, robh+dt, krzysztof.kozlowski+dt, rdunlap,
	ye.xingchen, p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On 06/02/2023 15:07, Daniel Lezcano wrote:
> On Wed, Feb 01, 2023 at 08:55:07AM +0100, Krzysztof Kozlowski wrote:
>> On 31/01/2023 16:38, bchihi@baylibre.com wrote:
>>> From: Balsam CHIHI <bchihi@baylibre.com>
>>>
>>> The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
>>> controllers contained in a thermal domain.
>>>
>>> A thermal domains can be the MCU or the AP.
>>>
>>> Each thermal domains contain up to seven controllers, each thermal
>>> controller handle up to four thermal sensors.
>>>
>>> The LVTS has two Finite State Machines (FSM), one to handle the
>>> functionin temperatures range like hot or cold temperature and another
>>> one to handle monitoring trip point. The FSM notifies via interrupts
>>> when a trip point is crossed.
>>>
>>
>> (...)
>>
>>> +
>>> +struct lvts_domain {
>>> +	struct lvts_ctrl *lvts_ctrl;
>>> +	struct reset_control *reset;
>>> +	struct clk *clk;
>>> +	int num_lvts_ctrl;
>>> +	void __iomem *base;
>>> +	size_t calib_len;
>>> +	u8 *calib;
>>> +};
>>> +
>>> +#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
>>> +
>>> +static struct dentry *root;
>>
>> How do you handle two instances of driver?
> 
> For now, we can put the entry in /sys/kernel/debug/<dev_name>
> 
> I'm preparing a debugfs series for the thermal framework and that will provide
> an entry to hook in for the sensors debugfs if available

The code looked like it does not support it at all. I think it would
remove entries from second instance, while unbinding the first (or the
opposite).

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-06 14:07       ` Daniel Lezcano
  2023-02-06 14:30         ` Krzysztof Kozlowski
@ 2023-02-06 14:32         ` Balsam CHIHI
  1 sibling, 0 replies; 57+ messages in thread
From: Balsam CHIHI @ 2023-02-06 14:32 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Krzysztof Kozlowski, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel, linux-pm, linux-kernel,
	linux-arm-kernel, linux-mediatek, devicetree, khilman, james.lo,
	rex-bc.chen

Hi Daniel,

On Mon, Feb 6, 2023 at 3:07 PM Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>
> On Wed, Feb 01, 2023 at 08:55:07AM +0100, Krzysztof Kozlowski wrote:
> > On 31/01/2023 16:38, bchihi@baylibre.com wrote:
> > > From: Balsam CHIHI <bchihi@baylibre.com>
> > >
> > > The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
> > > controllers contained in a thermal domain.
> > >
> > > A thermal domains can be the MCU or the AP.
> > >
> > > Each thermal domains contain up to seven controllers, each thermal
> > > controller handle up to four thermal sensors.
> > >
> > > The LVTS has two Finite State Machines (FSM), one to handle the
> > > functionin temperatures range like hot or cold temperature and another
> > > one to handle monitoring trip point. The FSM notifies via interrupts
> > > when a trip point is crossed.
> > >
> >
> > (...)
> >
> > > +
> > > +struct lvts_domain {
> > > +   struct lvts_ctrl *lvts_ctrl;
> > > +   struct reset_control *reset;
> > > +   struct clk *clk;
> > > +   int num_lvts_ctrl;
> > > +   void __iomem *base;
> > > +   size_t calib_len;
> > > +   u8 *calib;
> > > +};
> > > +
> > > +#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
> > > +
> > > +static struct dentry *root;
> >
> > How do you handle two instances of driver?
>
> For now, we can put the entry in /sys/kernel/debug/<dev_name>

Yes, sure.
I will do the necessary changes.

>
> I'm preparing a debugfs series for the thermal framework and that will provide
> an entry to hook in for the sensors debugfs if available

It would be a good feature!
good luck!


Best regards,
Balsam.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH v12] thermal: drivers: mediatek: Add the Low Voltage Thermal Sensor driver
  2023-02-06 14:30         ` Krzysztof Kozlowski
@ 2023-02-06 14:38           ` Daniel Lezcano
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel Lezcano @ 2023-02-06 14:38 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: bchihi, angelogioacchino.delregno, rafael, amitk, rui.zhang,
	matthias.bgg, robh+dt, krzysztof.kozlowski+dt, rdunlap,
	ye.xingchen, p.zabel, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, devicetree, khilman, james.lo, rex-bc.chen

On 06/02/2023 15:30, Krzysztof Kozlowski wrote:
> On 06/02/2023 15:07, Daniel Lezcano wrote:
>> On Wed, Feb 01, 2023 at 08:55:07AM +0100, Krzysztof Kozlowski wrote:
>>> On 31/01/2023 16:38, bchihi@baylibre.com wrote:
>>>> From: Balsam CHIHI <bchihi@baylibre.com>
>>>>
>>>> The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
>>>> controllers contained in a thermal domain.
>>>>
>>>> A thermal domains can be the MCU or the AP.
>>>>
>>>> Each thermal domains contain up to seven controllers, each thermal
>>>> controller handle up to four thermal sensors.
>>>>
>>>> The LVTS has two Finite State Machines (FSM), one to handle the
>>>> functionin temperatures range like hot or cold temperature and another
>>>> one to handle monitoring trip point. The FSM notifies via interrupts
>>>> when a trip point is crossed.
>>>>
>>>
>>> (...)
>>>
>>>> +
>>>> +struct lvts_domain {
>>>> +	struct lvts_ctrl *lvts_ctrl;
>>>> +	struct reset_control *reset;
>>>> +	struct clk *clk;
>>>> +	int num_lvts_ctrl;
>>>> +	void __iomem *base;
>>>> +	size_t calib_len;
>>>> +	u8 *calib;
>>>> +};
>>>> +
>>>> +#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
>>>> +
>>>> +static struct dentry *root;
>>>
>>> How do you handle two instances of driver?
>>
>> For now, we can put the entry in /sys/kernel/debug/<dev_name>
>>
>> I'm preparing a debugfs series for the thermal framework and that will provide
>> an entry to hook in for the sensors debugfs if available
> 
> The code looked like it does not support it at all. I think it would
> remove entries from second instance, while unbinding the first (or the
> opposite).

Yes, and you are right.

So instead of having:

/sys/kernel/debugfs/lvts/lvts@mcu

We will have:

/sys/kernel/debugfs/lvts@mcu

Later, when the other domain is added, we will have:

/sys/kernel/debugfs/lvts@mcu
/sys/kernel/debugfs/lvts@ap

Each instance takes care of removing its own entry

When I'll introduce thermal debugfs, I'll take care of massaging the 
driver to have them like:

/sys/kernel/debugfs/thermal/thermal_zone/0/sensors/lvts@mcu,0
/sys/kernel/debugfs/thermal/thermal_zone/1/sensors/lvts@ap,1




-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH] thermal/drivers/mediatek/lvts_thermal: fix memcpy's number of bytes in lvts_calibration_init()
  2023-01-26 16:10   ` [PATCH v12 2/6] dt-bindings: thermal: mediatek: " bchihi
                       ` (2 preceding siblings ...)
  2023-01-31 14:04     ` [PATCH v3] dt-bindings: thermal: mediatek: Add LVTS thermal controllers bchihi
@ 2023-03-07 13:42     ` bchihi
  2023-03-08  9:10       ` AngeloGioacchino Del Regno
  3 siblings, 1 reply; 57+ messages in thread
From: bchihi @ 2023-03-07 13:42 UTC (permalink / raw)
  To: daniel.lezcano, angelogioacchino.delregno, rafael, amitk,
	rui.zhang, matthias.bgg, robh+dt, krzysztof.kozlowski+dt,
	rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

From: Balsam CHIHI <bchihi@baylibre.com>

Replace memcpy 2 bytes by sizeof(int) bytes of LVTS calibration data.

Reported-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
---
Rebased on top of thermal/linux-next
base-commit: 6828e402d06f7c574430b61c05db784cd847b19f

Original email :
Hello Balsam CHIHI,

The patch f5f633b18234: "thermal/drivers/mediatek: Add the Low
Voltage Thermal Sensor driver" from Feb 9, 2023, leads to the
following Smatch static checker warning:

        drivers/thermal/mediatek/lvts_thermal.c:562 lvts_calibration_init()
        warn: not copying enough bytes for '&lvts_ctrl->calibration[i]' (4 vs 2 bytes)

drivers/thermal/mediatek/lvts_thermal.c
    555 static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
    556                                         const struct lvts_ctrl_data *lvts_ctrl_data,
    557                                         u8 *efuse_calibration)
    558 {
    559         int i;
    560
    561         for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++)
--> 562                 memcpy(&lvts_ctrl->calibration[i],
    563                        efuse_calibration + lvts_ctrl_data->cal_offset[i], 2);
                                                                                  ^
This is copying an array of known ints to a u32 array.  It should copy
sizeof(int) instead of 2.  It only works because the data you're on
little endian and the data is small.

    564
    565         return 0;
    566 }

regards,
dan carpenter
---
---
 drivers/thermal/mediatek/lvts_thermal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
index ddfdcbcf6d86..b505c6b49031 100644
--- a/drivers/thermal/mediatek/lvts_thermal.c
+++ b/drivers/thermal/mediatek/lvts_thermal.c
@@ -575,7 +575,7 @@ static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl
 
 	for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++)
 		memcpy(&lvts_ctrl->calibration[i],
-		       efuse_calibration + lvts_ctrl_data->cal_offset[i], 2);
+		       efuse_calibration + lvts_ctrl_data->cal_offset[i], sizeof(int));
 
 	return 0;
 }

base-commit: 6828e402d06f7c574430b61c05db784cd847b19f
prerequisite-patch-id: 73be949bd16979769e5b94905b244dcee4a8f687
prerequisite-patch-id: d23d83a946e5b876ef01a717fd51b07df1fa08dd
prerequisite-patch-id: d67f2455eef1c4a9ecc460dbf3c2e3ad47d213ec
prerequisite-patch-id: 9076e9b3bd3cc411b7b80344211364db5f0cca17
prerequisite-patch-id: e220d6ae26786f524c249588433f02e5f5f906ad
prerequisite-patch-id: b407d2998e57678952128b3a4bac92a379132b09
prerequisite-patch-id: fbb9212ce8c3530da17d213f56fa334ce4fa1b2b
prerequisite-patch-id: 5db9eed2659028cf4419f2de3d093af7df6c2dad
prerequisite-patch-id: a83c00c628605d1c8fbe1d97074f9f28efb1bcfc
prerequisite-patch-id: 56a245620a4f8238cf1ba3844dc348de3db33845
prerequisite-patch-id: 7df24b0bf11129ddd3356eacf192cc3fdb2bcded
prerequisite-patch-id: 3213ca70cb5b26d54a7137ff40ca8cd2a795c414
prerequisite-patch-id: 6c2202e85215d1c7e8ab16a6b85922e994c68d9b
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [PATCH] thermal/drivers/mediatek/lvts_thermal: fix memcpy's number of bytes in lvts_calibration_init()
  2023-03-07 13:42     ` [PATCH] thermal/drivers/mediatek/lvts_thermal: fix memcpy's number of bytes in lvts_calibration_init() bchihi
@ 2023-03-08  9:10       ` AngeloGioacchino Del Regno
  2023-03-09 12:37         ` Dan Carpenter
  0 siblings, 1 reply; 57+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-03-08  9:10 UTC (permalink / raw)
  To: bchihi, daniel.lezcano, rafael, amitk, rui.zhang, matthias.bgg,
	robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

Il 07/03/23 14:42, bchihi@baylibre.com ha scritto:
> From: Balsam CHIHI <bchihi@baylibre.com>
> 
> Replace memcpy 2 bytes by sizeof(int) bytes of LVTS calibration data.

sizeof(int) is architecture dependant... please use a fixed size type instead.

Also, shouldn't this be u16?!

Regards,
Angelo


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH] thermal/drivers/mediatek/lvts_thermal: fix memcpy's number of bytes in lvts_calibration_init()
  2023-03-08  9:10       ` AngeloGioacchino Del Regno
@ 2023-03-09 12:37         ` Dan Carpenter
  0 siblings, 0 replies; 57+ messages in thread
From: Dan Carpenter @ 2023-03-09 12:37 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: bchihi, daniel.lezcano, rafael, amitk, rui.zhang, matthias.bgg,
	robh+dt, krzysztof.kozlowski+dt, rdunlap, ye.xingchen, p.zabel,
	linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	devicetree, khilman, james.lo, rex-bc.chen

On Wed, Mar 08, 2023 at 10:10:34AM +0100, AngeloGioacchino Del Regno wrote:
> Il 07/03/23 14:42, bchihi@baylibre.com ha scritto:
> > From: Balsam CHIHI <bchihi@baylibre.com>
> > 
> > Replace memcpy 2 bytes by sizeof(int) bytes of LVTS calibration data.
> 
> sizeof(int) is architecture dependant...
> 

On Linux sizeof(int) is always 4.

I'm just so confused what you are talking about.  Are you thinking about
sizeof(long)?  Are you thinking about CPUs from the 1970s?  Linux wasn't
invented until the 90s so the old CPUs were already in museums at that
point.

> please use a fixed size type instead.

This is an unusual style opinion that I have not heard before.
Hopefully, you just got ints and longs confused so we can move on
without discussing it too much.  We're copying an int so sizeof(int) is
obviously correct.  It's hard to know how to respond.

> Also, shouldn't this be u16?!

What? Why would you think that?

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 57+ messages in thread

end of thread, other threads:[~2023-03-09 12:37 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-24 13:17 [PATCH v11 0/6] Add LVTS thermal architecture bchihi
2023-01-24 13:17 ` [PATCH v11 1/6] thermal/drivers/mediatek: Relocate driver to mediatek folder bchihi
2023-01-24 15:37   ` AngeloGioacchino Del Regno
2023-01-25 15:02     ` Balsam CHIHI
2023-01-24 13:17 ` [PATCH v11 2/6] dt-bindings/thermal/mediatek: Add LVTS thermal controllers dt-binding definition bchihi
2023-01-25 11:14   ` Daniel Lezcano
2023-01-25 20:35     ` Rob Herring
2023-01-25 21:13       ` Daniel Lezcano
2023-01-25 20:34   ` Rob Herring
2023-01-26 10:33     ` Balsam CHIHI
2023-01-26 16:10   ` [PATCH v12 2/6] dt-bindings: thermal: mediatek: " bchihi
2023-01-27 22:10     ` Daniel Lezcano
2023-01-28 10:50       ` Krzysztof Kozlowski
2023-01-30 10:49         ` Balsam CHIHI
2023-01-28 10:48     ` Krzysztof Kozlowski
2023-01-30 10:40       ` Balsam CHIHI
2023-01-30 11:18         ` Matthias Brugger
2023-01-30 12:19           ` Balsam CHIHI
2023-01-30 16:07             ` Matthias Brugger
2023-01-31 16:53         ` Krzysztof Kozlowski
2023-01-31 17:01           ` Daniel Lezcano
2023-01-31 14:04     ` [PATCH v3] dt-bindings: thermal: mediatek: Add LVTS thermal controllers bchihi
2023-02-01  7:46       ` Krzysztof Kozlowski
2023-02-01 13:34         ` Balsam CHIHI
2023-02-01 13:37           ` Krzysztof Kozlowski
2023-02-01 13:56             ` Balsam CHIHI
2023-03-07 13:42     ` [PATCH] thermal/drivers/mediatek/lvts_thermal: fix memcpy's number of bytes in lvts_calibration_init() bchihi
2023-03-08  9:10       ` AngeloGioacchino Del Regno
2023-03-09 12:37         ` Dan Carpenter
2023-01-24 13:17 ` [PATCH v11 3/6] arm64/dts/mt8195: Add efuse node to mt8195 bchihi
2023-01-25 14:25   ` Matthias Brugger
2023-01-25 15:04     ` Balsam CHIHI
2023-01-24 13:17 ` [PATCH v11 4/6] thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver bchihi
2023-01-24 15:31   ` AngeloGioacchino Del Regno
2023-01-25 15:06     ` Balsam CHIHI
2023-01-31 15:38   ` [PATCH v12] thermal: drivers: mediatek: " bchihi
2023-02-01  3:09     ` kernel test robot
2023-02-01  7:47       ` Krzysztof Kozlowski
2023-02-01 15:14         ` Balsam CHIHI
2023-02-01  7:55     ` Krzysztof Kozlowski
2023-02-01 16:46       ` Balsam CHIHI
2023-02-01 16:59         ` Matthias Brugger
2023-02-03 10:35           ` Balsam CHIHI
2023-02-01 17:12         ` Krzysztof Kozlowski
2023-02-03 11:06           ` Balsam CHIHI
2023-02-06 14:07       ` Daniel Lezcano
2023-02-06 14:30         ` Krzysztof Kozlowski
2023-02-06 14:38           ` Daniel Lezcano
2023-02-06 14:32         ` Balsam CHIHI
2023-01-24 13:17 ` [PATCH v11 5/6] arm64/dts/mt8195: Add thermal zones and thermal nodes bchihi
2023-01-24 15:36   ` AngeloGioacchino Del Regno
2023-01-25 15:10     ` Balsam CHIHI
2023-01-25 19:09       ` Matthias Brugger
2023-01-26  9:43         ` Balsam CHIHI
2023-01-31 15:37   ` [PATCH v12] arm64: dts: mediatek: mt8195: " bchihi
2023-01-24 13:17 ` [PATCH v11 6/6] arm64/dts/mt8195: Add temperature mitigation threshold bchihi
2023-01-24 15:36   ` AngeloGioacchino Del Regno

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).