From nobody Mon Dec 1 22:37:05 2025 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB12630102C; Wed, 26 Nov 2025 11:56:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764158216; cv=none; b=gWlY/AtpGAchAwrDJ42QQsm5GCndySTzDlYcC+IagMsIm5cJ3KelRr3oLI+fiZBrssRHF0LrIAb5Je2GgyM+FEh2JOnHsNv29N1laJoMdEchcxy2IjdvGin6zfY10yueUkeDO85Zc5hUg9ceZohOH4AZSf0ZCWQEfAFyj4uHhBk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764158216; c=relaxed/simple; bh=FL5o5y1/Twpcu8Mqfn+GwJ0PqQ90brtbtK8QQ2rfmuE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eX43e/y5BfjK3o8vjWIwH5m60N0snaEuBeA0YZq962AY9SZUagNJB6z2IPcbLYV0een3QK3f3eAY5eFOsqt7xJkI48BCTaY34hVX035EpU3HYz3IQeZk4TdCN/QvRgTbBDIUcTj387jV7JeChRCFzGS9grvXipgyzW8R9QP3wzE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=kzd2/VaW; arc=none smtp.client-ip=220.197.31.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="kzd2/VaW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Date:Subject:MIME-Version:Content-Type: Message-Id:To; bh=FsFZAa7mJuleKXtIm8+lL9WVy7it1dzq5lspUZWFQw0=; b=kzd2/VaW+u698FJU+P+tgqVd5Kr7/xilVyCY5jZAyHARzsGT4d3XZ6dTc88vHp eFJtjLlHaSWorpjUBZiUq6xiM7EwJquS7s4PJONFiFFHYU7Qj9ni6FtDGC9QJud9 smm43nQM5PMyZ5gy01CxVWptX3ik7je4WXCQIBzQLkUmI= Received: from [192.168.10.1] (unknown []) by gzsmtp3 (Coremail) with SMTP id PigvCgBnveN26iZpJOi_FQ--.56535S3; Wed, 26 Nov 2025 19:54:34 +0800 (CST) From: Shuwei Wu Date: Thu, 27 Nov 2025 02:44:07 +0800 Subject: [PATCH 1/3] dt-bindings: thermal: Add SpacemiT K1 thermal sensor Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251127-b4-k1-thermal-v1-1-f32ce47b1aba@163.com> References: <20251127-b4-k1-thermal-v1-0-f32ce47b1aba@163.com> In-Reply-To: <20251127-b4-k1-thermal-v1-0-f32ce47b1aba@163.com> To: "Rafael J. Wysocki" , Daniel Lezcano , Zhang Rui , Lukasz Luba , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Yixun Lan , Shuwei Wu , Philipp Zabel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti Cc: linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1764182662; l=2456; i=shuweiwoo@163.com; s=20251125; h=from:subject:message-id; bh=FL5o5y1/Twpcu8Mqfn+GwJ0PqQ90brtbtK8QQ2rfmuE=; b=tC7J82dJezjNQsCZQVsA75NIKy+KngltMFnBrvPel/zXVL0GCVi2i2dA4Daa06GoQkm6eJttX akAhUWCgCAJBVNhHzpxN+3UfQL6nXbuixZUYFpv1EqfyK8qO+PyFiCX X-Developer-Key: i=shuweiwoo@163.com; a=ed25519; pk=qZs6i2UZnXkmjUrwO5HJxcfpCvgSNrR4dcU5cjtfTSk= X-CM-TRANSID: PigvCgBnveN26iZpJOi_FQ--.56535S3 X-Coremail-Antispam: 1Uf129KBjvJXoW7Ar17Gr4kuF1kZFW8Gr4kWFg_yoW8tw4rpF 4fGrn8Grs7uF17Xw4SgFykAan8Kw40yFWUXrn7Ww15trn0gFySqr9Fkr1UZa48CryjgayU ZF4UurW2k3WDA3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRV6wiUUUUU= X-CM-SenderInfo: 5vkx4vplzr0qqrwthudrp/1tbiNhcSjmkm3gD8mAAAsI Document the SpacemiT K1 Thermal Sensor Unit (TSU), which supports monitoring temperatures for five zones: soc, package, gpu, cluster0, and cluster1. Signed-off-by: Shuwei Wu Reviewed-by: Krzysztof Kozlowski --- .../bindings/thermal/spacemit,k1-thermal.yaml | 76 ++++++++++++++++++= ++++ 1 file changed, 76 insertions(+) diff --git a/Documentation/devicetree/bindings/thermal/spacemit,k1-thermal.= yaml b/Documentation/devicetree/bindings/thermal/spacemit,k1-thermal.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6057161b4b00c8f869d16199a1c= c0fc964fed998 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/spacemit,k1-thermal.yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/spacemit,k1-thermal.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SpacemiT K1 Thermal Sensor Unit + +description: + The SpacemiT K1 Thermal Sensor Unit (TSU) monitors the temperature of + the SoC using multiple internal sensors (e.g., soc, package, gpu, cluste= rs). + +maintainers: + - Shuwei Wu + +$ref: thermal-sensor.yaml# + +properties: + compatible: + const: spacemit,k1-thermal + + reg: + maxItems: 1 + + clocks: + items: + - description: Core clock for thermal sensor + - description: Bus clock for thermal sensor + + clock-names: + items: + - const: core + - const: bus + + interrupts: + maxItems: 1 + + resets: + items: + - description: Reset for the thermal sensor + + "#thermal-sensor-cells": + const: 1 + description: + The first cell indicates the sensor ID. + 0 =3D soc + 1 =3D package + 2 =3D gpu + 3 =3D cluster0 + 4 =3D cluster1 + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - resets + - "#thermal-sensor-cells" + +additionalProperties: false + +examples: + - | + #include + + thermal@d4018000 { + compatible =3D "spacemit,k1-thermal"; + reg =3D <0xd4018000 0x100>; + clocks =3D <&syscon_apbc CLK_TSEN>, + <&syscon_apbc CLK_TSEN_BUS>; + clock-names =3D "core", "bus"; + interrupts =3D <61>; + resets =3D <&syscon_apbc RESET_TSEN>; + #thermal-sensor-cells =3D <1>; + }; --=20 2.51.0 From nobody Mon Dec 1 22:37:05 2025 Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4971EEED8; Wed, 26 Nov 2025 11:56:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764158219; cv=none; b=SRzDNT2wnU0wdfC61B1sz9uf8lWpf5qQ21TvbXqxafrBMO4wEM42SLsoLQAxpQKyLfJqHvuqnxAoe2HqcBDJEX/8e7R9Gvgg4u/YYsAUQbLkHpdpnm+5JwmEAlOTfFGaqCoYjU2+OVEqJQncZY1BVHDh4PjONUU6Cd0Nr9ZhGk4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764158219; c=relaxed/simple; bh=f3QVdI3twULgPhFMtbmynfm+voptnrx6wgJnuxB0WwM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MT91o3+HXDXmyUxL3Scb+O/NzbEkq8HwzpSEy0TrvA17QgKSUx+yFE/8TjR2/b54VtoRG5BK49rOzg19+itqeWyiIPibPo/1bg/8DUlwPlmE7Ews4+FS4DjtX75O5XTvrgLnKjfb8vlf3fgeYLRHkPH2L4HE34QDb8C6RwD4TtY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=Xx655r29; arc=none smtp.client-ip=117.135.210.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="Xx655r29" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Date:Subject:MIME-Version:Content-Type: Message-Id:To; bh=dx2kdwgWirBm3KYMeGELly/4Dj/JwkZmnAJ1loR5dS4=; b=Xx655r29T0sSafwdzzRW6Kn8G7JYW54naR/R3RQpCD8mrbMRM2WY3FnIhKY1RB CvSKx410aiM3Vuw0eLf7OdVqDfxUnxi4m/xx3aULy3afRpGTm71H3uJT9wVDJZ9G +z88o4lhH7fwubjSY7wG0evEWuPZpjVEq2iJtREsgY6/E= Received: from [192.168.10.1] (unknown []) by gzsmtp3 (Coremail) with SMTP id PigvCgBnveN26iZpJOi_FQ--.56535S4; Wed, 26 Nov 2025 19:54:36 +0800 (CST) From: Shuwei Wu Date: Thu, 27 Nov 2025 02:44:08 +0800 Subject: [PATCH 2/3] thermal: K1: Add driver for K1 SoC thermal sensor Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251127-b4-k1-thermal-v1-2-f32ce47b1aba@163.com> References: <20251127-b4-k1-thermal-v1-0-f32ce47b1aba@163.com> In-Reply-To: <20251127-b4-k1-thermal-v1-0-f32ce47b1aba@163.com> To: "Rafael J. Wysocki" , Daniel Lezcano , Zhang Rui , Lukasz Luba , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Yixun Lan , Shuwei Wu , Philipp Zabel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti Cc: linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1764182662; l=11634; i=shuweiwoo@163.com; s=20251125; h=from:subject:message-id; bh=f3QVdI3twULgPhFMtbmynfm+voptnrx6wgJnuxB0WwM=; b=XrvikrIbysknO61dDC5TO4rYPX3tbGuX3OMLND3wx5OG3u1jze+tEY5qcYAilvwW3sQ83Fhjv DQVtSykoEoOCNj6AcsWqFtrqJ3f1Bzd8DDKK3/G41f8hBzNvztoduo6 X-Developer-Key: i=shuweiwoo@163.com; a=ed25519; pk=qZs6i2UZnXkmjUrwO5HJxcfpCvgSNrR4dcU5cjtfTSk= X-CM-TRANSID: PigvCgBnveN26iZpJOi_FQ--.56535S4 X-Coremail-Antispam: 1Uf129KBjvJXoWfXr1xZF1DAr15Zr4kZw48Crg_yoWkZFW7pa y7AFyUGr4DCF17Cwn7AF47Jwsxtw43KFWUWr1xWw4fA3Wayry3J34fKry8Ary8uF4jga98 J3909F17CrZrW3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRAhLrUUUUU= X-CM-SenderInfo: 5vkx4vplzr0qqrwthudrp/1tbiNhoSjmkm3gD8tQAAso The thermal sensor unit (TSU) on K1 supports monitoring five temperature zones. The driver registers these sensors with the thermal framework and supports standard operations: - Reading temperature (millidegree Celsius) - Setting high/low thresholds for interrupts Signed-off-by: Shuwei Wu --- drivers/thermal/Kconfig | 14 ++ drivers/thermal/Makefile | 1 + drivers/thermal/k1_thermal.c | 307 +++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 322 insertions(+) diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index a09c188b9ad11377afe232d89c60504eb7000417..76095d2888980718b39470c0973= 1092a21f7159b 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -495,6 +495,20 @@ config SPRD_THERMAL Support for the Spreadtrum thermal sensor driver in the Linux thermal framework. =20 +config K1_THERMAL + tristate "SpacemiT K1 thermal sensor driver" + depends on ARCH_SPACEMIT || COMPILE_TEST + help + This driver provides support for the thermal sensor unit (TSU) + integrated in the SpacemiT K1 SoC. + + The TSU monitors temperatures for five thermal zones: soc, package, + gpu, cluster0, and cluster1. It supports reporting temperature + values and handling high/low threshold interrupts. + + Say Y here if you want to enable thermal monitoring on SpacemiT K1. + If compiled as a module, it will be called k1_thermal. + config KHADAS_MCU_FAN_THERMAL tristate "Khadas MCU controller FAN cooling support" depends on OF diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index d7718978db245faffba98ff95a07c7bcbc776fd2..bf28ffe7a39f916acd608ea6d59= 2c82049b0be17 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_GENERIC_ADC_THERMAL) +=3D thermal-generic-ad= c.o obj-$(CONFIG_UNIPHIER_THERMAL) +=3D uniphier_thermal.o obj-$(CONFIG_AMLOGIC_THERMAL) +=3D amlogic_thermal.o obj-$(CONFIG_SPRD_THERMAL) +=3D sprd_thermal.o +obj-$(CONFIG_K1_THERMAL) +=3D k1_thermal.o obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) +=3D khadas_mcu_fan.o obj-$(CONFIG_LOONGSON2_THERMAL) +=3D loongson2_thermal.o obj-$(CONFIG_THERMAL_CORE_TESTING) +=3D testing/ diff --git a/drivers/thermal/k1_thermal.c b/drivers/thermal/k1_thermal.c new file mode 100644 index 0000000000000000000000000000000000000000..a0e9585cbc5a4e0f7c3a47debb3= cfa8e82082d88 --- /dev/null +++ b/drivers/thermal/k1_thermal.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Thermal sensor driver for SpacemiT K1 SoC + * + * Copyright (C) 2025 Shuwei Wu + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "thermal_hwmon.h" + +#define MAX_SENSOR_NUMBER 5 +#define TEMPERATURE_OFFSET 278 + +#define K1_TSU_INT_EN 0x14 +#define K1_TSU_INT_CLR 0x10 +#define K1_TSU_INT_STA 0x18 + +#define K1_TSU_INT_EN_MASK BIT(0) +#define K1_TSU_INT_MASK(x) (GENMASK(2, 1) << ((x) * 2)) + +#define K1_TSU_EN 0x8 +#define K1_TSU_EN_MASK(x) BIT(x) + +#define K1_TSU_DATA_BASE 0x20 +#define K1_TSU_DATA(x) (K1_TSU_DATA_BASE + ((x) / 2) * 4) +#define K1_TSU_DATA_MASK(x) (((x) % 2) ? GENMASK(31, 16) : GENMASK(15, 0)) +#define K1_TSU_DATA_SHIFT(x) (((x) % 2) ? 16 : 0) + +#define K1_TSU_THRSH_BASE 0x40 +#define K1_TSU_THRSH(x) (K1_TSU_THRSH_BASE + ((x) * 4)) +#define K1_TSU_THRSH_HIGH_MASK GENMASK(31, 16) +#define K1_TSU_THRSH_LOW_MASK GENMASK(15, 0) +#define K1_TSU_THRSH_HIGH_SHIFT 16 +#define K1_TSU_THRSH_LOW_SHIFT 0 + +#define K1_TSU_TIME 0x0C +#define K1_TSU_TIME_MASK GENMASK(23, 0) +#define K1_TSU_TIME_FILTER_PERIOD GENMASK(21, 20) +#define K1_TSU_TIME_ADC_CNT_RST GENMASK(7, 4) +#define K1_TSU_TIME_WAIT_REF_CNT GENMASK(3, 0) + +#define K1_TSU_PCTRL 0x00 +#define K1_TSU_PCTRL_RAW_SEL BIT(7) +#define K1_TSU_PCTRL_TEMP_MODE BIT(3) +#define K1_TSU_PCTRL_ENABLE BIT(0) + +#define K1_TSU_PCTRL_SW_CTRL GENMASK(21, 18) +#define K1_TSU_PCTRL_CTUNE GENMASK(11, 8) +#define K1_TSU_PCTRL_HW_AUTO_MODE BIT(23) + +#define K1_TSU_PCTRL2 0x04 +#define K1_TSU_PCTRL2_CLK_SEL_MASK GENMASK(15, 14) +#define K1_TSU_PCTRL2_CLK_SEL_24M (0 << 14) + +struct k1_thermal_sensor { + struct k1_thermal_priv *priv; + struct thermal_zone_device *tzd; + int id; +}; + +struct k1_thermal_priv { + void __iomem *base; + struct device *dev; + struct clk *clk; + struct clk *bus_clk; + struct reset_control *reset; + struct k1_thermal_sensor sensors[MAX_SENSOR_NUMBER]; +}; + +static int k1_init_sensors(struct platform_device *pdev) +{ + struct k1_thermal_priv *priv =3D platform_get_drvdata(pdev); + unsigned int temp; + int i; + + /* Disable all the interrupts */ + writel(0xffffffff, priv->base + K1_TSU_INT_EN); + + /* Configure ADC sampling time and filter period */ + temp =3D readl(priv->base + K1_TSU_TIME); + temp &=3D ~K1_TSU_TIME_MASK; + temp |=3D K1_TSU_TIME_FILTER_PERIOD | + K1_TSU_TIME_ADC_CNT_RST | + K1_TSU_TIME_WAIT_REF_CNT; + writel(temp, priv->base + K1_TSU_TIME); + + /* + * Enable all sensors' auto mode, enable dither control, + * consecutive mode, and power up sensor. + */ + temp =3D readl(priv->base + K1_TSU_PCTRL); + temp |=3D K1_TSU_PCTRL_RAW_SEL | + K1_TSU_PCTRL_TEMP_MODE | + K1_TSU_PCTRL_HW_AUTO_MODE | + K1_TSU_PCTRL_ENABLE; + temp &=3D ~K1_TSU_PCTRL_SW_CTRL; + temp &=3D ~K1_TSU_PCTRL_CTUNE; + writel(temp, priv->base + K1_TSU_PCTRL); + + /* Select 24M clk for high speed mode */ + temp =3D readl(priv->base + K1_TSU_PCTRL2); + temp &=3D ~K1_TSU_PCTRL2_CLK_SEL_MASK; + temp |=3D K1_TSU_PCTRL2_CLK_SEL_24M; + writel(temp, priv->base + K1_TSU_PCTRL2); + + /* Enable thermal interrupt */ + temp =3D readl(priv->base + K1_TSU_INT_EN); + temp |=3D K1_TSU_INT_EN_MASK; + writel(temp, priv->base + K1_TSU_INT_EN); + + /* Enable each sensor */ + for (i =3D 0; i < MAX_SENSOR_NUMBER; ++i) { + temp =3D readl(priv->base + K1_TSU_EN); + temp &=3D ~K1_TSU_EN_MASK(i); + temp |=3D K1_TSU_EN_MASK(i); + writel(temp, priv->base + K1_TSU_EN); + } + + return 0; +} + +static void k1_enable_sensor_irq(struct k1_thermal_sensor *sensor) +{ + struct k1_thermal_priv *priv =3D sensor->priv; + unsigned int temp; + + temp =3D readl(priv->base + K1_TSU_INT_CLR); + temp |=3D K1_TSU_INT_MASK(sensor->id); + writel(temp, priv->base + K1_TSU_INT_CLR); + + temp =3D readl(priv->base + K1_TSU_INT_EN); + temp &=3D ~K1_TSU_INT_MASK(sensor->id); + writel(temp, priv->base + K1_TSU_INT_EN); +} + +/* + * The conversion formula used is: + * T(m=C2=B0C) =3D (((raw_value & mask) >> shift) - TEMPERATURE_OFFSET) * = 1000 + */ +static int k1_thermal_get_temp(struct thermal_zone_device *tz, int *temp) +{ + struct k1_thermal_sensor *sensor =3D thermal_zone_device_priv(tz); + struct k1_thermal_priv *priv =3D sensor->priv; + + *temp =3D readl(priv->base + K1_TSU_DATA(sensor->id)); + *temp &=3D K1_TSU_DATA_MASK(sensor->id); + *temp >>=3D K1_TSU_DATA_SHIFT(sensor->id); + + *temp -=3D TEMPERATURE_OFFSET; + + *temp *=3D 1000; + + return 0; +} + +/* + * For each sensor, the hardware threshold register is 32 bits: + * - Lower 16 bits [15:0] configure the low threshold temperature. + * - Upper 16 bits [31:16] configure the high threshold temperature. + */ +static int k1_thermal_set_trips(struct thermal_zone_device *tz, int low, i= nt high) +{ + struct k1_thermal_sensor *sensor =3D thermal_zone_device_priv(tz); + struct k1_thermal_priv *priv =3D sensor->priv; + int high_code =3D high; + int low_code =3D low; + unsigned int temp; + + if (low >=3D high) + return -EINVAL; + + if (low < 0) + low_code =3D 0; + + high_code =3D high_code / 1000 + TEMPERATURE_OFFSET; + temp =3D readl(priv->base + K1_TSU_THRSH(sensor->id)); + temp &=3D ~K1_TSU_THRSH_HIGH_MASK; + temp |=3D (high_code << K1_TSU_THRSH_HIGH_SHIFT); + writel(temp, priv->base + K1_TSU_THRSH(sensor->id)); + + low_code =3D low_code / 1000 + TEMPERATURE_OFFSET; + temp =3D readl(priv->base + K1_TSU_THRSH(sensor->id)); + temp &=3D ~K1_TSU_THRSH_LOW_MASK; + temp |=3D (low_code << K1_TSU_THRSH_LOW_SHIFT); + writel(temp, priv->base + K1_TSU_THRSH(sensor->id)); + + return 0; +} + +static const struct thermal_zone_device_ops k1_thermal_ops =3D { + .get_temp =3D k1_thermal_get_temp, + .set_trips =3D k1_thermal_set_trips, +}; + +static irqreturn_t k1_thermal_irq_thread(int irq, void *data) +{ + struct k1_thermal_priv *priv =3D (struct k1_thermal_priv *)data; + int msk, status, i; + + status =3D readl(priv->base + K1_TSU_INT_STA); + + for (i =3D 0; i < MAX_SENSOR_NUMBER; i++) { + if (status & K1_TSU_INT_MASK(i)) { + msk =3D readl(priv->base + K1_TSU_INT_CLR); + msk |=3D K1_TSU_INT_MASK(i); + writel(msk, priv->base + K1_TSU_INT_CLR); + /* Notify thermal framework to update trips */ + thermal_zone_device_update(priv->sensors[i].tzd, THERMAL_EVENT_UNSPECIF= IED); + } + } + + return IRQ_HANDLED; +} + +static int k1_thermal_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct k1_thermal_priv *priv; + int i, irq, ret; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev =3D dev; + platform_set_drvdata(pdev, priv); + + priv->base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + priv->reset =3D devm_reset_control_get_exclusive_deasserted(dev, NULL); + if (IS_ERR(priv->reset)) + return dev_err_probe(dev, PTR_ERR(priv->reset), + "Failed to get/deassert reset control\n"); + + priv->clk =3D devm_clk_get_enabled(dev, "core"); + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "Failed to get core clock\n"); + + priv->bus_clk =3D devm_clk_get_enabled(dev, "bus"); + if (IS_ERR(priv->bus_clk)) + return dev_err_probe(dev, PTR_ERR(priv->bus_clk), + "Failed to get bus clock\n"); + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + ret =3D k1_init_sensors(pdev); + + for (i =3D 0; i < MAX_SENSOR_NUMBER; ++i) { + priv->sensors[i].id =3D i; + priv->sensors[i].priv =3D priv; + priv->sensors[i].tzd =3D devm_thermal_of_zone_register(dev, + i, priv->sensors + i, + &k1_thermal_ops); + if (IS_ERR(priv->sensors[i].tzd)) + return dev_err_probe(dev, PTR_ERR(priv->sensors[i].tzd), + "Failed to register thermal zone: %d\n", i); + + /* Attach sysfs hwmon attributes for userspace monitoring */ + ret =3D devm_thermal_add_hwmon_sysfs(dev, priv->sensors[i].tzd); + if (ret) + dev_warn(dev, "Failed to add hwmon sysfs attributes\n"); + + k1_enable_sensor_irq(priv->sensors + i); + } + + ret =3D devm_request_threaded_irq(dev, irq, NULL, + k1_thermal_irq_thread, + IRQF_ONESHOT, "k1_thermal", priv); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to request IRQ\n"); + + return 0; +} + +static const struct of_device_id k1_thermal_dt_ids[] =3D { + { .compatible =3D "spacemit,k1-thermal" }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, k1_thermal_dt_ids); + +static struct platform_driver k1_thermal_driver =3D { + .driver =3D { + .name =3D "k1_thermal", + .of_match_table =3D k1_thermal_dt_ids, + }, + .probe =3D k1_thermal_probe, +}; +module_platform_driver(k1_thermal_driver); + +MODULE_DESCRIPTION("SpacemiT K1 Thermal Sensor Driver"); +MODULE_AUTHOR("Shuwei Wu "); +MODULE_LICENSE("GPL"); --=20 2.51.0 From nobody Mon Dec 1 22:37:05 2025 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 212D732572C; Wed, 26 Nov 2025 11:56:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764158220; cv=none; b=UCnRTBuGbT3QC7E2JBHxSEOj1/CAKQQ11Brew2zjqWCuCA6XH7pdTnQG75/T/e8y22VC+VcenyXgnKeWeq70uRr0VxwzIo+2lUJUHRfJwofumtCadyUeb3AQbe6/eDDexlfAMZ5Q3uEmW1v9cM81IJRWnlb08BmrjkNXhujyWr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764158220; c=relaxed/simple; bh=FbsOThTrOK1Y/J4tVtyPVao7glCLEJI4mGN39AL4NMQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qBRSgfulnPguLP0HD1Y2l+1uOnUpDivaI6bHGxeITOf1DAwPyAsMuu/FyPfuW3lJX/E78bZis2h8iyCYHpYLUw1R8lEGTYxoZvRynDiDqZRouE5/C9RhqU35eQAYSbdO5IEEVjtQLbc0xzz8nbvdXWtvHjZxGUS41x7bF30y+rM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=eqLxOJbe; arc=none smtp.client-ip=220.197.31.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="eqLxOJbe" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Date:Subject:MIME-Version:Content-Type: Message-Id:To; bh=wOF1Tb4hdKgT+VsV0pVwid5+bzJCocSTb9mIOLanReE=; b=eqLxOJbe1xoF/BP0G2y/8umG0/LHkVwmn9QwVPals7otH+ObdqjTGJDwaf5fss GVUvamd7vUSm3f9ejJ+fS9hRXppRrLDtZBqLhxwEYKaJIDQNXrzDx/yZjyNkh4QN oiq/WaK9Yk1tF5jgrER4iMg9lKBvXJEig9nmmsjiUnPpI= Received: from [192.168.10.1] (unknown []) by gzsmtp3 (Coremail) with SMTP id PigvCgBnveN26iZpJOi_FQ--.56535S5; Wed, 26 Nov 2025 19:54:38 +0800 (CST) From: Shuwei Wu Date: Thu, 27 Nov 2025 02:44:09 +0800 Subject: [PATCH 3/3] riscv: dts: spacemit: Add thermal sensor for K1 SoC Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251127-b4-k1-thermal-v1-3-f32ce47b1aba@163.com> References: <20251127-b4-k1-thermal-v1-0-f32ce47b1aba@163.com> In-Reply-To: <20251127-b4-k1-thermal-v1-0-f32ce47b1aba@163.com> To: "Rafael J. Wysocki" , Daniel Lezcano , Zhang Rui , Lukasz Luba , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Yixun Lan , Shuwei Wu , Philipp Zabel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti Cc: linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-riscv@lists.infradead.org, spacemit@lists.linux.dev, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1764182662; l=3083; i=shuweiwoo@163.com; s=20251125; h=from:subject:message-id; bh=FbsOThTrOK1Y/J4tVtyPVao7glCLEJI4mGN39AL4NMQ=; b=5qfoCVv1RYJJOaOFBlH40yx4L/yjtsCKGCP81+u/pjMb+oCIc/0VcR2naijW2pAhw8TGNO1vS /HH6dBRwZTuC75jdRRQh+JAa2XQYx9Xs3UqO17RS1WazITCSt22Jpcs X-Developer-Key: i=shuweiwoo@163.com; a=ed25519; pk=qZs6i2UZnXkmjUrwO5HJxcfpCvgSNrR4dcU5cjtfTSk= X-CM-TRANSID: PigvCgBnveN26iZpJOi_FQ--.56535S5 X-Coremail-Antispam: 1Uf129KBjvJXoWxXr1rKF48GFyfCw4xtw48Xrb_yoW5XFyDpF 1Skws5GFZrAryfXa13CryDK398Ka1vva48Xan7uryrArn0qFZI93y0k3W5tF18Gr4rW34j vryqy34DuF1qy3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07U17K3UUUUU= X-CM-SenderInfo: 5vkx4vplzr0qqrwthudrp/1tbioBMSjmkm4WqyYwAAs6 Include the Thermal Sensor Unit (TSU) node in the SpacemiT K1 dtsi with definitions for registers, clocks, and interrupts. Additionally, configure thermal zones for the soc, package, gpu, and clusters to enable temperature monitoring via the thermal framework. Signed-off-by: Shuwei Wu --- arch/riscv/boot/dts/spacemit/k1.dtsi | 101 +++++++++++++++++++++++++++++++= ++++ 1 file changed, 101 insertions(+) diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spa= cemit/k1.dtsi index 6cdcd80a7c83b3f62500f226e8ed16787ded5016..67596c230396056eea4b2cfa9c6= d7f04627c0209 100644 --- a/arch/riscv/boot/dts/spacemit/k1.dtsi +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi @@ -338,6 +338,96 @@ osc_32k: clock-32k { }; }; =20 + thermal-zones { + soc-thermal { + polling-delay-passive =3D <0>; + polling-delay =3D <0>; + thermal-sensors =3D <&thermal 0>; + + trips { + soc-crit { + temperature =3D <115000>; + hysteresis =3D <0>; + type =3D "critical"; + }; + }; + }; + + package-thermal { + polling-delay-passive =3D <0>; + polling-delay =3D <0>; + thermal-sensors =3D <&thermal 1>; + + trips { + package-crit { + temperature =3D <115000>; + hysteresis =3D <0>; + type =3D "critical"; + }; + }; + }; + + gpu-thermal { + polling-delay-passive =3D <100>; + polling-delay =3D <0>; + thermal-sensors =3D <&thermal 2>; + + trips { + gpu-alert { + temperature =3D <85000>; + hysteresis =3D <2000>; + type =3D "passive"; + }; + + gpu-crit { + temperature =3D <115000>; + hysteresis =3D <0>; + type =3D "critical"; + }; + }; + }; + + cluster0-thermal { + polling-delay-passive =3D <100>; + polling-delay =3D <0>; + thermal-sensors =3D <&thermal 3>; + + trips { + cluster0-alert { + temperature =3D <85000>; + hysteresis =3D <2000>; + type =3D "passive"; + }; + + cluster0-crit { + temperature =3D <115000>; + hysteresis =3D <0>; + type =3D "critical"; + }; + }; + }; + + cluster1-thermal { + polling-delay-passive =3D <100>; + polling-delay =3D <0>; + thermal-sensors =3D <&thermal 4>; + + trips { + cluster1-alert { + temperature =3D <85000>; + hysteresis =3D <2000>; + type =3D "passive"; + }; + + cluster1-crit { + temperature =3D <115000>; + hysteresis =3D <0>; + type =3D "critical"; + }; + }; + }; + }; + soc { compatible =3D "simple-bus"; interrupt-parent =3D <&plic>; @@ -369,6 +459,17 @@ syscon_apbc: system-controller@d4015000 { #reset-cells =3D <1>; }; =20 + thermal: thermal@d4018000 { + compatible =3D "spacemit,k1-thermal"; + reg =3D <0x0 0xd4018000 0x0 0x100>; + clocks =3D <&syscon_apbc CLK_TSEN>, + <&syscon_apbc CLK_TSEN_BUS>; + clock-names =3D "core", "bus"; + interrupts =3D <61>; + resets =3D <&syscon_apbc RESET_TSEN>; + #thermal-sensor-cells =3D <1>; + }; + gpio: gpio@d4019000 { compatible =3D "spacemit,k1-gpio"; reg =3D <0x0 0xd4019000 0x0 0x100>; --=20 2.51.0