* [RRC v1 0/3] Simplify Exynos TMU IRQ clean logic
@ 2025-06-16 16:38 Anand Moon
2025-06-16 16:38 ` [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references Anand Moon
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Anand Moon @ 2025-06-16 16:38 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Alim Akhtar,
open list:SAMSUNG THERMAL DRIVER,
open list:SAMSUNG THERMAL DRIVER,
moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES,
open list
Cc: Anand Moon
As per Exynos TMU user manual the interrupt status register, maps the
active rising and falling edges of interrupt to the appropriate clear bit,
and writes it to the interrupt clear register to acknowledge and
clear the interrupt.
Refactors the IRQ clear logic in the Exynos TMU driver to eliminate
redundant code to use single unified exynos_tmu_clear_irqs()
function.
Thanks
-Anand
Anand Moon (3):
thermal/drivers/exynos: Remove unused base_second mapping and
references
thermal/drivers/exynos: Handle temperature threshold interrupts and
clear corresponding IRQs
thermal/drivers/exynos: Refactor IRQ clear logic using SoC-specific
config
drivers/thermal/samsung/exynos_tmu.c | 118 +++++++++++++++++----------
1 file changed, 73 insertions(+), 45 deletions(-)
base-commit: e04c78d86a9699d136910cfc0bdcf01087e3267e
--
2.49.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references
2025-06-16 16:38 [RRC v1 0/3] Simplify Exynos TMU IRQ clean logic Anand Moon
@ 2025-06-16 16:38 ` Anand Moon
[not found] ` <CGME20250618125812eucas1p11a1ab5210d4efa95a51b3bc7c4f0924d@eucas1p1.samsung.com>
2025-06-16 16:38 ` [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs Anand Moon
2025-06-16 16:38 ` [RRC v1 3/3] thermal/drivers/exynos: Refactor IRQ clear logic using SoC-specific config Anand Moon
2 siblings, 1 reply; 14+ messages in thread
From: Anand Moon @ 2025-06-16 16:38 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Alim Akhtar,
open list:SAMSUNG THERMAL DRIVER,
open list:SAMSUNG THERMAL DRIVER,
moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES,
open list
Cc: Anand Moon
Following change removes the base_second field eliminates its mapping
in exynos_map_dt_data(), and updates the TRIMINFO access logic in
exynos4412_tmu_initialize() to use base for both Exynos5420 and
Exynos5420_TRIMINFO SoCs, as base_second is not used further in
in this code.
This cleanup simplifies the code and reduces unnecessary
memory mapping.
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
drivers/thermal/samsung/exynos_tmu.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 47a99b3c5395..c625eddcb9f3 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -139,12 +139,11 @@ enum soc_type {
* struct exynos_tmu_data : A structure to hold the private data of the TMU
* driver
* @base: base address of the single instance of the TMU controller.
- * @base_second: base address of the common registers of the TMU controller.
* @irq: irq number of the TMU controller.
* @soc: id of the SOC type.
* @lock: lock to implement synchronization.
* @clk: pointer to the clock structure.
- * @clk_sec: pointer to the clock structure for accessing the base_second.
+ * @clk_sec: pointer to the clock structure for accessing the gpu clk.
* @sclk: pointer to the clock structure for accessing the tmu special clk.
* @cal_type: calibration type for temperature
* @efuse_value: SoC defined fuse value
@@ -172,7 +171,6 @@ enum soc_type {
*/
struct exynos_tmu_data {
void __iomem *base;
- void __iomem *base_second;
int irq;
enum soc_type soc;
struct mutex lock;
@@ -460,12 +458,11 @@ static void exynos4412_tmu_initialize(struct platform_device *pdev)
}
/* On exynos5420 the triminfo register is in the shared space */
- if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
- trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
- else
+ if (data->soc == SOC_ARCH_EXYNOS5420 ||
+ data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
-
- sanitize_temp_error(data, trim_info);
+ sanitize_temp_error(data, trim_info);
+ }
}
static void exynos5433_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
@@ -964,13 +961,6 @@ static int exynos_map_dt_data(struct platform_device *pdev)
return -ENODEV;
}
- data->base_second = devm_ioremap(&pdev->dev, res.start,
- resource_size(&res));
- if (!data->base_second) {
- dev_err(&pdev->dev, "Failed to ioremap memory\n");
- return -ENOMEM;
- }
-
return 0;
}
--
2.49.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs
2025-06-16 16:38 [RRC v1 0/3] Simplify Exynos TMU IRQ clean logic Anand Moon
2025-06-16 16:38 ` [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references Anand Moon
@ 2025-06-16 16:38 ` Anand Moon
[not found] ` <CGME20250618115220eucas1p2b9d37e8cdd1997fa010f51cecdea5e4f@eucas1p2.samsung.com>
2025-06-16 16:38 ` [RRC v1 3/3] thermal/drivers/exynos: Refactor IRQ clear logic using SoC-specific config Anand Moon
2 siblings, 1 reply; 14+ messages in thread
From: Anand Moon @ 2025-06-16 16:38 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Alim Akhtar,
open list:SAMSUNG THERMAL DRIVER,
open list:SAMSUNG THERMAL DRIVER,
moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES,
open list
Cc: Anand Moon
As per the Exynos TMU user manual the interrupt status register, maps the
active rising and falling edges of interrupt to the appropriate clear bit,
and writes it to the interrupt clear register to acknowledge and
clear the interrupt. This ensures that only the relevant interrupt
is cleared and allows the system to respond appropriately to thermal
events. As per the comment Exynos4210 doesn't support FALL IRQs at all.
So add the check accordingly.
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
drivers/thermal/samsung/exynos_tmu.c | 48 ++++++++++++++++++++++------
1 file changed, 38 insertions(+), 10 deletions(-)
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index c625eddcb9f3..b7522b7b1230 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -70,6 +70,20 @@
#define EXYNOS_EMUL_DATA_MASK 0xFF
#define EXYNOS_EMUL_ENABLE 0x1
+#define INTSTAT_FALL2 BIT(24)
+#define INTSTAT_FALL1 BIT(20)
+#define INTSTAT_FALL0 BIT(16)
+#define INTSTAT_RISE2 BIT(8)
+#define INTSTAT_RISE1 BIT(4)
+#define INTSTAT_RISE0 BIT(0)
+
+#define INTCLEAR_FALL2 BIT(24)
+#define INTCLEAR_FALL1 BIT(20)
+#define INTCLEAR_FALL0 BIT(16)
+#define INTCLEAR_RISE2 BIT(8)
+#define INTCLEAR_RISE1 BIT(4)
+#define INTCLEAR_RISE0 BIT(0)
+
/* Exynos5260 specific */
#define EXYNOS5260_TMU_REG_INTEN 0xC0
#define EXYNOS5260_TMU_REG_INTSTAT 0xC4
@@ -773,7 +787,7 @@ static irqreturn_t exynos_tmu_threaded_irq(int irq, void *id)
static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
{
- unsigned int val_irq;
+ unsigned int val_irq, clearirq = 0;
u32 tmu_intstat, tmu_intclear;
if (data->soc == SOC_ARCH_EXYNOS5260) {
@@ -791,15 +805,29 @@ static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
}
val_irq = readl(data->base + tmu_intstat);
- /*
- * Clear the interrupts. Please note that the documentation for
- * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
- * states that INTCLEAR register has a different placing of bits
- * responsible for FALL IRQs than INTSTAT register. Exynos5420
- * and Exynos5440 documentation is correct (Exynos4210 doesn't
- * support FALL IRQs at all).
- */
- writel(val_irq, data->base + tmu_intclear);
+
+ if (data->soc == SOC_ARCH_EXYNOS4210) {
+ writel(val_irq, data->base + tmu_intclear);
+ return;
+ }
+
+ /* Map INTSTAT bits to INTCLEAR bits */
+ if (val_irq & INTSTAT_FALL2)
+ clearirq |= INTCLEAR_FALL2;
+ else if (val_irq & INTSTAT_FALL1)
+ clearirq |= INTCLEAR_FALL1;
+ else if (val_irq & INTSTAT_FALL0)
+ clearirq |= INTCLEAR_FALL0;
+ else if (val_irq & INTSTAT_RISE2)
+ clearirq |= INTCLEAR_RISE2;
+ else if (val_irq & INTSTAT_RISE1)
+ clearirq |= INTCLEAR_RISE1;
+ else if (val_irq & INTSTAT_RISE0)
+ clearirq |= INTCLEAR_RISE0;
+
+ /* Perform proper task for decrease temperature */
+ if (clearirq)
+ writel(clearirq, data->base + tmu_intclear);
}
static const struct of_device_id exynos_tmu_match[] = {
--
2.49.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RRC v1 3/3] thermal/drivers/exynos: Refactor IRQ clear logic using SoC-specific config
2025-06-16 16:38 [RRC v1 0/3] Simplify Exynos TMU IRQ clean logic Anand Moon
2025-06-16 16:38 ` [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references Anand Moon
2025-06-16 16:38 ` [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs Anand Moon
@ 2025-06-16 16:38 ` Anand Moon
2 siblings, 0 replies; 14+ messages in thread
From: Anand Moon @ 2025-06-16 16:38 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Alim Akhtar,
open list:SAMSUNG THERMAL DRIVER,
open list:SAMSUNG THERMAL DRIVER,
moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES,
open list
Cc: Anand Moon
Refactors the IRQ clear logic in the Exynos TMU driver to eliminate
redundant code and enhance maintainability. Previously, the driver
relied on multiple SoC-specific functions or conditional branching
based on data->soc to handle differences in IRQ register behavior.
Change introduces a unified exynos_tmu_clear_irqs() function
that adapts its behavior using SoC-specific configuration fields
(tmu_intstat, tmu_intclear, and irq_clear_direct) defined in the
exynos_tmu_data structure. These fields are initialized per SoC
during device setup.
This refactor reduces code duplication, simplifies the addition of
new SoC support, and improves overall code clarity.
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
drivers/thermal/samsung/exynos_tmu.c | 52 +++++++++++++++++-----------
1 file changed, 31 insertions(+), 21 deletions(-)
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index b7522b7b1230..cd21b36674c3 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -172,6 +172,9 @@ enum soc_type {
* 0 < reference_voltage <= 31
* @tzd: pointer to thermal_zone_device structure
* @enabled: current status of TMU device
+ * @tmu_intstat: interrupt status register
+ * @tmu_intclear: interrupt clear register
+ * @irq_clear_support: SoC supports clear IRQ
* @tmu_set_low_temp: SoC specific method to set trip (falling threshold)
* @tmu_set_high_temp: SoC specific method to set trip (rising threshold)
* @tmu_set_crit_temp: SoC specific method to set critical temperature
@@ -198,6 +201,9 @@ struct exynos_tmu_data {
u8 reference_voltage;
struct thermal_zone_device *tzd;
bool enabled;
+ u32 tmu_intstat;
+ u32 tmu_intclear;
+ bool irq_clear_support;
void (*tmu_set_low_temp)(struct exynos_tmu_data *data, u8 temp);
void (*tmu_set_high_temp)(struct exynos_tmu_data *data, u8 temp);
@@ -785,28 +791,15 @@ static irqreturn_t exynos_tmu_threaded_irq(int irq, void *id)
return IRQ_HANDLED;
}
-static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
+static void exynos_tmu_clear_irqs(struct exynos_tmu_data *data)
{
unsigned int val_irq, clearirq = 0;
- u32 tmu_intstat, tmu_intclear;
-
- if (data->soc == SOC_ARCH_EXYNOS5260) {
- tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
- tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
- } else if (data->soc == SOC_ARCH_EXYNOS7) {
- tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
- tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
- } else if (data->soc == SOC_ARCH_EXYNOS5433) {
- tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
- tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
- } else {
- tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
- tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
- }
+ u32 tmu_intstat = data->tmu_intstat;
+ u32 tmu_intclear = data->tmu_intclear;
val_irq = readl(data->base + tmu_intstat);
- if (data->soc == SOC_ARCH_EXYNOS4210) {
+ if (!data->irq_clear_support) {
writel(val_irq, data->base + tmu_intclear);
return;
}
@@ -900,12 +893,15 @@ static int exynos_map_dt_data(struct platform_device *pdev)
data->tmu_initialize = exynos4210_tmu_initialize;
data->tmu_control = exynos4210_tmu_control;
data->tmu_read = exynos4210_tmu_read;
- data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
+ data->tmu_clear_irqs = exynos_tmu_clear_irqs;
data->gain = 15;
data->reference_voltage = 7;
data->efuse_value = 55;
data->min_efuse_value = 40;
data->max_efuse_value = 100;
+ data->tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
+ data->tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
+ data->irq_clear_support = false;
break;
case SOC_ARCH_EXYNOS3250:
case SOC_ARCH_EXYNOS4412:
@@ -922,7 +918,7 @@ static int exynos_map_dt_data(struct platform_device *pdev)
data->tmu_control = exynos4210_tmu_control;
data->tmu_read = exynos4412_tmu_read;
data->tmu_set_emulation = exynos4412_tmu_set_emulation;
- data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
+ data->tmu_clear_irqs = exynos_tmu_clear_irqs;
data->gain = 8;
data->reference_voltage = 16;
data->efuse_value = 55;
@@ -932,6 +928,14 @@ static int exynos_map_dt_data(struct platform_device *pdev)
else
data->min_efuse_value = 0;
data->max_efuse_value = 100;
+ data->irq_clear_support = true;
+ if (data->soc == SOC_ARCH_EXYNOS5260) {
+ data->tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
+ data->tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
+ } else {
+ data->tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
+ data->tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
+ }
break;
case SOC_ARCH_EXYNOS5433:
data->tmu_set_low_temp = exynos5433_tmu_set_low_temp;
@@ -943,7 +947,7 @@ static int exynos_map_dt_data(struct platform_device *pdev)
data->tmu_control = exynos5433_tmu_control;
data->tmu_read = exynos4412_tmu_read;
data->tmu_set_emulation = exynos4412_tmu_set_emulation;
- data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
+ data->tmu_clear_irqs = exynos_tmu_clear_irqs;
data->gain = 8;
if (res.start == EXYNOS5433_G3D_BASE)
data->reference_voltage = 23;
@@ -952,6 +956,9 @@ static int exynos_map_dt_data(struct platform_device *pdev)
data->efuse_value = 75;
data->min_efuse_value = 40;
data->max_efuse_value = 150;
+ data->tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
+ data->tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
+ data->irq_clear_support = true;
break;
case SOC_ARCH_EXYNOS7:
data->tmu_set_low_temp = exynos7_tmu_set_low_temp;
@@ -963,12 +970,15 @@ static int exynos_map_dt_data(struct platform_device *pdev)
data->tmu_control = exynos7_tmu_control;
data->tmu_read = exynos7_tmu_read;
data->tmu_set_emulation = exynos4412_tmu_set_emulation;
- data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
+ data->tmu_clear_irqs = exynos_tmu_clear_irqs;
data->gain = 9;
data->reference_voltage = 17;
data->efuse_value = 75;
data->min_efuse_value = 15;
data->max_efuse_value = 100;
+ data->tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
+ data->tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
+ data->irq_clear_support = true;
break;
default:
dev_err(&pdev->dev, "Platform not supported\n");
--
2.49.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs
[not found] ` <CGME20250618115220eucas1p2b9d37e8cdd1997fa010f51cecdea5e4f@eucas1p2.samsung.com>
@ 2025-06-18 11:52 ` Mateusz Majewski
2025-06-19 5:45 ` Anand Moon
0 siblings, 1 reply; 14+ messages in thread
From: Mateusz Majewski @ 2025-06-18 11:52 UTC (permalink / raw)
To: linux.amoon
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba, rafael,
rui.zhang, Mateusz Majewski
Hello :)
> +#define INTSTAT_FALL2 BIT(24)
> +#define INTSTAT_FALL1 BIT(20)
> +#define INTSTAT_FALL0 BIT(16)
> +#define INTSTAT_RISE2 BIT(8)
> +#define INTSTAT_RISE1 BIT(4)
> +#define INTSTAT_RISE0 BIT(0)
> +
> +#define INTCLEAR_FALL2 BIT(24)
> +#define INTCLEAR_FALL1 BIT(20)
> +#define INTCLEAR_FALL0 BIT(16)
> +#define INTCLEAR_RISE2 BIT(8)
> +#define INTCLEAR_RISE1 BIT(4)
> +#define INTCLEAR_RISE0 BIT(0)
> + /* Map INTSTAT bits to INTCLEAR bits */
> + if (val_irq & INTSTAT_FALL2)
> + clearirq |= INTCLEAR_FALL2;
> + else if (val_irq & INTSTAT_FALL1)
> + clearirq |= INTCLEAR_FALL1;
> + else if (val_irq & INTSTAT_FALL0)
> + clearirq |= INTCLEAR_FALL0;
> + else if (val_irq & INTSTAT_RISE2)
> + clearirq |= INTCLEAR_RISE2;
> + else if (val_irq & INTSTAT_RISE1)
> + clearirq |= INTCLEAR_RISE1;
> + else if (val_irq & INTSTAT_RISE0)
> + clearirq |= INTCLEAR_RISE0;
This implies that only these 6 bits are used. Is this true for all SoCs
supported by this driver? My understanding is that Exynos 5433 in particular
uses bits 7:0 for rise interrupts and 23:16 for fall interrupts. When I tested
this patch (both alone and the whole series) on 5433 by running some CPU load,
the interrupt seemed to not fire consistently:
/sys/class/thermal/cooling_device1/cur_state would never go above 1 (which is
consistent with the interrupt firing once, not getting cleared and never firing
again; without this patch, it consistently went up to 6) and I got a quick
reboot every time.
Thank you,
Mateusz Majewski
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references
[not found] ` <CGME20250618125812eucas1p11a1ab5210d4efa95a51b3bc7c4f0924d@eucas1p1.samsung.com>
@ 2025-06-18 12:58 ` Mateusz Majewski
2025-06-19 5:45 ` Anand Moon
0 siblings, 1 reply; 14+ messages in thread
From: Mateusz Majewski @ 2025-06-18 12:58 UTC (permalink / raw)
To: linux.amoon
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba, rafael,
rui.zhang, Mateusz Majewski
> /* On exynos5420 the triminfo register is in the shared space */
> - if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
> - trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
> - else
> + if (data->soc == SOC_ARCH_EXYNOS5420 ||
> + data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
> trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
> -
> - sanitize_temp_error(data, trim_info);
> + sanitize_temp_error(data, trim_info);
> + }
If I understand correctly, this means that the triminfo will no longer
be read on other SoCs calling this function (3250, 4412, 5250, 5260). Is
this intended?
By the way, are we sure that data->base_second really is unnecessary?
According to the bindings documentation (in
Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml),
the different address is necessary because the triminfo registers are
misplaced on 5420.
Thank you,
Mateusz Majewski
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references
2025-06-18 12:58 ` Mateusz Majewski
@ 2025-06-19 5:45 ` Anand Moon
2025-06-21 7:17 ` Anand Moon
0 siblings, 1 reply; 14+ messages in thread
From: Anand Moon @ 2025-06-19 5:45 UTC (permalink / raw)
To: Mateusz Majewski
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba, rafael,
rui.zhang
Hi Mateusz,
On Wed, 18 Jun 2025 at 18:28, Mateusz Majewski <m.majewski2@samsung.com> wrote:
>
> > /* On exynos5420 the triminfo register is in the shared space */
> > - if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
> > - trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
> > - else
> > + if (data->soc == SOC_ARCH_EXYNOS5420 ||
> > + data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
> > trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
> > -
> > - sanitize_temp_error(data, trim_info);
> > + sanitize_temp_error(data, trim_info);
> > + }
>
> If I understand correctly, this means that the triminfo will no longer
> be read on other SoCs calling this function (3250, 4412, 5250, 5260). Is
> this intended?
>
Thanks for your feedback.
I will remove the data->soc check for Exynos5420 in the next patch.
> By the way, are we sure that data->base_second really is unnecessary?
> According to the bindings documentation (in
> Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml),
> the different address is necessary because the triminfo registers are
> misplaced on 5420.
As per my Exynos5422 user manual and DTS mapping
thermal-sensor tmu@10060000 is mapped to CPU0 with tmu_apbif clock
thermal-sensor tmu@10064000 is mapped to CPU1 with tmu_apbif clock
thermal-sensor tmu@10068000 is mapped to CPU2 with tmu_apbif clock
thermal-sensor tmu@1006c000 is mapped to CPU3 with tmu_apbif clock
thermal-sensor tmu@100a0000 is mapped to GPU with tmu_triminfo_apbif clock.
Well, we are using tmu_triminfo_apbif to configure clk_sec, which is
using the data->base to enable the clk.
So, data->base_second is not used any further in the code after we set triminfo
>
> Thank you,
> Mateusz Majewski
Thanks
Anand
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs
2025-06-18 11:52 ` Mateusz Majewski
@ 2025-06-19 5:45 ` Anand Moon
2025-06-21 7:16 ` Anand Moon
0 siblings, 1 reply; 14+ messages in thread
From: Anand Moon @ 2025-06-19 5:45 UTC (permalink / raw)
To: Mateusz Majewski
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba, rafael,
rui.zhang
Hi Mateusz,
On Wed, 18 Jun 2025 at 17:22, Mateusz Majewski <m.majewski2@samsung.com> wrote:
>
> Hello :)
>
> > +#define INTSTAT_FALL2 BIT(24)
> > +#define INTSTAT_FALL1 BIT(20)
> > +#define INTSTAT_FALL0 BIT(16)
> > +#define INTSTAT_RISE2 BIT(8)
> > +#define INTSTAT_RISE1 BIT(4)
> > +#define INTSTAT_RISE0 BIT(0)
> > +
> > +#define INTCLEAR_FALL2 BIT(24)
> > +#define INTCLEAR_FALL1 BIT(20)
> > +#define INTCLEAR_FALL0 BIT(16)
> > +#define INTCLEAR_RISE2 BIT(8)
> > +#define INTCLEAR_RISE1 BIT(4)
> > +#define INTCLEAR_RISE0 BIT(0)
>
> > + /* Map INTSTAT bits to INTCLEAR bits */
> > + if (val_irq & INTSTAT_FALL2)
> > + clearirq |= INTCLEAR_FALL2;
> > + else if (val_irq & INTSTAT_FALL1)
> > + clearirq |= INTCLEAR_FALL1;
> > + else if (val_irq & INTSTAT_FALL0)
> > + clearirq |= INTCLEAR_FALL0;
> > + else if (val_irq & INTSTAT_RISE2)
> > + clearirq |= INTCLEAR_RISE2;
> > + else if (val_irq & INTSTAT_RISE1)
> > + clearirq |= INTCLEAR_RISE1;
> > + else if (val_irq & INTSTAT_RISE0)
> > + clearirq |= INTCLEAR_RISE0;
>
> This implies that only these 6 bits are used. Is this true for all SoCs
> supported by this driver? My understanding is that Exynos 5433 in particular
> uses bits 7:0 for rise interrupts and 23:16 for fall interrupts. When I tested
> this patch (both alone and the whole series) on 5433 by running some CPU load,
> the interrupt seemed to not fire consistently:
> /sys/class/thermal/cooling_device1/cur_state would never go above 1 (which is
> consistent with the interrupt firing once, not getting cleared and never firing
> again; without this patch, it consistently went up to 6) and I got a quick
> reboot every time.
>
Thanks for the feedback,
As per the user manual Exynos4412
INTSTAT and INTCLEAR have a clear mapping with bits
falling 20, 16, 12 and rising 8 4 0
whereas Exyno5422 has
INTSTAT and INTCLEAR have a clear mapping with bits
falling 24, 20, 16, and rising 8 4 0
Yes, it could differ for all the SoCs,
I don't have the user manual or TRM for these SoCs
to configure correctly.
I tried to configure this, referring to the comment in the driver
/*
* Clear the interrupts. Please note that the documentation for
* Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
* states that INTCLEAR register has a different placing of bits
* responsible for FALL IRQs than INTSTAT register. Exynos5420
* and Exynos5440 documentation is correct (Exynos4210 doesn't
* support FALL IRQs at all).
*/
By the way, I don't see Exynos5433 and Exynos7 support
INTSTAT and INTCLEAR registers. We are using TMU_REG_INTPEND
to read and update the same register.
if (data->soc == SOC_ARCH_EXYNOS5260) {
tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
} else if (data->soc == SOC_ARCH_EXYNOS7) {
tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
} else if (data->soc == SOC_ARCH_EXYNOS5433) {
tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
} else {
tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
}
> Thank you,
> Mateusz Majewski
Thanks
Anand
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs
2025-06-19 5:45 ` Anand Moon
@ 2025-06-21 7:16 ` Anand Moon
[not found] ` <CGME20250624075847eucas1p2db6e908f78aa603bdf6aec38b653e9af@eucas1p2.samsung.com>
0 siblings, 1 reply; 14+ messages in thread
From: Anand Moon @ 2025-06-21 7:16 UTC (permalink / raw)
To: Mateusz Majewski
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba, rafael,
rui.zhang
Hi Mateusz,
On Thu, 19 Jun 2025 at 11:15, Anand Moon <linux.amoon@gmail.com> wrote:
>
> Hi Mateusz,
>
> On Wed, 18 Jun 2025 at 17:22, Mateusz Majewski <m.majewski2@samsung.com> wrote:
> >
> > Hello :)
> >
> > > +#define INTSTAT_FALL2 BIT(24)
> > > +#define INTSTAT_FALL1 BIT(20)
> > > +#define INTSTAT_FALL0 BIT(16)
> > > +#define INTSTAT_RISE2 BIT(8)
> > > +#define INTSTAT_RISE1 BIT(4)
> > > +#define INTSTAT_RISE0 BIT(0)
> > > +
> > > +#define INTCLEAR_FALL2 BIT(24)
> > > +#define INTCLEAR_FALL1 BIT(20)
> > > +#define INTCLEAR_FALL0 BIT(16)
> > > +#define INTCLEAR_RISE2 BIT(8)
> > > +#define INTCLEAR_RISE1 BIT(4)
> > > +#define INTCLEAR_RISE0 BIT(0)
> >
> > > + /* Map INTSTAT bits to INTCLEAR bits */
> > > + if (val_irq & INTSTAT_FALL2)
> > > + clearirq |= INTCLEAR_FALL2;
> > > + else if (val_irq & INTSTAT_FALL1)
> > > + clearirq |= INTCLEAR_FALL1;
> > > + else if (val_irq & INTSTAT_FALL0)
> > > + clearirq |= INTCLEAR_FALL0;
> > > + else if (val_irq & INTSTAT_RISE2)
> > > + clearirq |= INTCLEAR_RISE2;
> > > + else if (val_irq & INTSTAT_RISE1)
> > > + clearirq |= INTCLEAR_RISE1;
> > > + else if (val_irq & INTSTAT_RISE0)
> > > + clearirq |= INTCLEAR_RISE0;
> >
> > This implies that only these 6 bits are used. Is this true for all SoCs
> > supported by this driver? My understanding is that Exynos 5433 in particular
> > uses bits 7:0 for rise interrupts and 23:16 for fall interrupts. When I tested
> > this patch (both alone and the whole series) on 5433 by running some CPU load,
> > the interrupt seemed to not fire consistently:
> > /sys/class/thermal/cooling_device1/cur_state would never go above 1 (which is
> > consistent with the interrupt firing once, not getting cleared and never firing
> > again; without this patch, it consistently went up to 6) and I got a quick
> > reboot every time.
> >
> Thanks for the feedback,
>
> As per the user manual Exynos4412
> INTSTAT and INTCLEAR have a clear mapping with bits
> falling 20, 16, 12 and rising 8 4 0
>
> whereas Exyno5422 has
> INTSTAT and INTCLEAR have a clear mapping with bits
> falling 24, 20, 16, and rising 8 4 0
>
> Yes, it could differ for all the SoCs,
> I don't have the user manual or TRM for these SoCs
> to configure correctly.
>
> I tried to configure this, referring to the comment in the driver
> /*
> * Clear the interrupts. Please note that the documentation for
> * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
> * states that INTCLEAR register has a different placing of bits
> * responsible for FALL IRQs than INTSTAT register. Exynos5420
> * and Exynos5440 documentation is correct (Exynos4210 doesn't
> * support FALL IRQs at all).
> */
>
> By the way, I don't see Exynos5433 and Exynos7 support
> INTSTAT and INTCLEAR registers. We are using TMU_REG_INTPEND
> to read and update the same register.
>
> if (data->soc == SOC_ARCH_EXYNOS5260) {
> tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
> tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
> } else if (data->soc == SOC_ARCH_EXYNOS7) {
> tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
> tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
> } else if (data->soc == SOC_ARCH_EXYNOS5433) {
> tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
> tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
> } else {
> tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
> tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
> }
>
I don't have Exynos Arm64 boards to test on
I believe the Exynos5433 and Exynos7 also use the same
register addresses for INTSTAT and INTCLEAR.
[1] https://github.com/universal5433/android_kernel_samsung_universal5433/blob/lineage-18.1/drivers/thermal/exynos_thermal.c#L854-L892
[2] https://github.com/enesuzun2002/android_kernel_samsung_exynos7420/blob/nx-9.0/drivers/thermal/cal_tmu7420.c#L14-L221
If you have details on how INTSTAT and INTCLEAR are used
particularly regarding the update bits, please share them.
Specifically, I'm interested in how bits [7:0] correspond to rising edge
interrupts and bits [23:16] to falling edge interrupts
I feel it's the same as Exynos54222.
Can you test with these changes? If you have any suggestions,
please feel free to share them
Thanks
-Anand
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references
2025-06-19 5:45 ` Anand Moon
@ 2025-06-21 7:17 ` Anand Moon
[not found] ` <CGME20250625143825eucas1p2e95ba80552cd289b6e05db33f32ec14a@eucas1p2.samsung.com>
0 siblings, 1 reply; 14+ messages in thread
From: Anand Moon @ 2025-06-21 7:17 UTC (permalink / raw)
To: Mateusz Majewski
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba, rafael,
rui.zhang
Hi Mateusz
On Thu, 19 Jun 2025 at 11:15, Anand Moon <linux.amoon@gmail.com> wrote:
>
> Hi Mateusz,
>
> On Wed, 18 Jun 2025 at 18:28, Mateusz Majewski <m.majewski2@samsung.com> wrote:
> >
> > > /* On exynos5420 the triminfo register is in the shared space */
> > > - if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
> > > - trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
> > > - else
> > > + if (data->soc == SOC_ARCH_EXYNOS5420 ||
> > > + data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
> > > trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
> > > -
> > > - sanitize_temp_error(data, trim_info);
> > > + sanitize_temp_error(data, trim_info);
> > > + }
> >
> > If I understand correctly, this means that the triminfo will no longer
> > be read on other SoCs calling this function (3250, 4412, 5250, 5260). Is
> > this intended?
> >
> Thanks for your feedback.
> I will remove the data->soc check for Exynos5420 in the next patch.
Can you check with with following changes
diff --git a/drivers/thermal/samsung/exynos_tmu.c
b/drivers/thermal/samsung/exynos_tmu.c
index 9fc085f4ea1a..0776801fafea 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -469,14 +469,11 @@ static void exynos4412_tmu_initialize(struct
platform_device *pdev)
ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
+ return;
}
- /* On exynos5420 the triminfo register is in the shared space */
- if (data->soc == SOC_ARCH_EXYNOS5420 ||
- data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
- trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
- sanitize_temp_error(data, trim_info);
- }
+ trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
+ sanitize_temp_error(data, trim_info);
}
>
> > By the way, are we sure that data->base_second really is unnecessary?
> > According to the bindings documentation (in
> > Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml),
> > the different address is necessary because the triminfo registers are
> > misplaced on 5420.
>
> As per my Exynos5422 user manual and DTS mapping
> thermal-sensor tmu@10060000 is mapped to CPU0 with tmu_apbif clock
> thermal-sensor tmu@10064000 is mapped to CPU1 with tmu_apbif clock
> thermal-sensor tmu@10068000 is mapped to CPU2 with tmu_apbif clock
> thermal-sensor tmu@1006c000 is mapped to CPU3 with tmu_apbif clock
> thermal-sensor tmu@100a0000 is mapped to GPU with tmu_triminfo_apbif clock.
>
> Well, we are using tmu_triminfo_apbif to configure clk_sec, which is
> using the data->base to enable the clk.
> So, data->base_second is not used any further in the code after we set triminfo
Thanks
Anand
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs
[not found] ` <CGME20250624075847eucas1p2db6e908f78aa603bdf6aec38b653e9af@eucas1p2.samsung.com>
@ 2025-06-24 7:58 ` Mateusz Majewski
2025-06-26 18:21 ` Anand Moon
0 siblings, 1 reply; 14+ messages in thread
From: Mateusz Majewski @ 2025-06-24 7:58 UTC (permalink / raw)
To: linux.amoon
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba,
m.majewski2, rafael, rui.zhang
> I tried to configure this, referring to the comment in the driver
> /*
> * Clear the interrupts. Please note that the documentation for
> * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
> * states that INTCLEAR register has a different placing of bits
> * responsible for FALL IRQs than INTSTAT register. Exynos5420
> * and Exynos5440 documentation is correct (Exynos4210 doesn't
> * support FALL IRQs at all).
> */
>
> By the way, I don't see Exynos5433 and Exynos7 support
> INTSTAT and INTCLEAR registers. We are using TMU_REG_INTPEND
> to read and update the same register.
>
> if (data->soc == SOC_ARCH_EXYNOS5260) {
> tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
> tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
> } else if (data->soc == SOC_ARCH_EXYNOS7) {
> tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
> tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
> } else if (data->soc == SOC_ARCH_EXYNOS5433) {
> tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
> tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
> } else {
> tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
> tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
> }
My understanding of this comment and the situation in general is like
this:
1. On 5420, whenever there is edge interrupt, no matter if rise or fall,
a bit gets set to 1 inside INTSTAT, and we clear it by setting the
same bit to 1 inside INTCLEAR. The current code does not rely on the
concrete bit index, it will just check the temperature after the
interrupt.
2. On 4210, there is no falling edge interrupts (so
exynos4210_tmu_set_low_temp is empty, we enable polling in DT etc).
This is what the "Exynos4210 doesn't support FALL IRQs at all" means.
However, rising edge interrupts work exactly the same as on 5420:
a bit gets set to 1 inside INTSTAT, and we clear it by setting the
same bit to 1 inside INTCLEAR.
3. On 3250, 4412, 5250, 5260, it again works the same way as 5420.
However, somebody had a copy of documentation that was incorrect: it
said that bit indices does not match somehow, which is not true.
4. On 5433 and 7, it one more time works the same way as 5420, with a
single change: a bit gets set to 1 inside INTPEND, and we clear it
by setting it to 1 inside the same INTPEND.
So, all we need to do to support existing SoCs is to read the 1 bit from
one register, and set the bit with the same index in another register
(which on some SoCs is the same register). We could interpret the index
to see what kind of interrupt is this, but we read the temperature to
get similar information.
So in the end, is it helpful to interpret the INTSTAT bit index, only to
reset the exact same index inside INTCLEAR? I guess it could be valuable
if we also used the information about which interrupt it is and somehow
used it elsewhere (which could actually help with some issues), but that
is another thing to do.
> If you have details on how INTSTAT and INTCLEAR are used
> particularly regarding the update bits, please share them.
> Specifically, I'm interested in how bits [7:0] correspond to rising edge
> interrupts and bits [23:16] to falling edge interrupts
> I feel it's the same as Exynos54222.
Regarding concrete indices on 5433:
- the 0th bit corresponds to RISE0,
- the 1st bit corresponds to RISE1,
- ...
- the 7th bit corresponds to RISE7,
- the 16th bit corresponds to FALL0,
- the 17th bit corresponds to FALL1,
- ...
- the 23th bit corresponds to FALL7.
That is probably because this SoC supports more interrupts than others.
Though do note that currently, we only use part of them (one RISE, one
FALL if supported, and another RISE for critical temperature (one
supporting hardware thermal tripping if possible)). Also note that the
indices in INTSTAT/INTCLEAR/INTPEND match the ones in INTEN, though I
have not checked thoroughly if that is true for all the SoCs.
Thank you,
Mateusz Majewski
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references
[not found] ` <CGME20250625143825eucas1p2e95ba80552cd289b6e05db33f32ec14a@eucas1p2.samsung.com>
@ 2025-06-25 14:38 ` Mateusz Majewski
2025-06-26 18:22 ` Anand Moon
0 siblings, 1 reply; 14+ messages in thread
From: Mateusz Majewski @ 2025-06-25 14:38 UTC (permalink / raw)
To: linux.amoon
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba,
m.majewski2, rafael, rui.zhang
> Can you check with with following changes
>
> diff --git a/drivers/thermal/samsung/exynos_tmu.c
> b/drivers/thermal/samsung/exynos_tmu.c
> index 9fc085f4ea1a..0776801fafea 100644
> --- a/drivers/thermal/samsung/exynos_tmu.c
> +++ b/drivers/thermal/samsung/exynos_tmu.c
> @@ -469,14 +469,11 @@ static void exynos4412_tmu_initialize(struct
> platform_device *pdev)
> ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
> ctrl = EXYNOS_TRIMINFO_RELOAD_ENABLE;
> writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
> + return;
> }
>
> - /* On exynos5420 the triminfo register is in the shared space */
> - if (data->soc == SOC_ARCH_EXYNOS5420
> - data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
> - trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
> - sanitize_temp_error(data, trim_info);
> - }
> + trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
> + sanitize_temp_error(data, trim_info);
> }
This does seem to work (tested on 3250 and on 5420) in the sense that I
can read the temperatures, when they increase the state of the cooling
device gets increased, and the values look reasonable and stay in a
reasonable range. Hard to say if the trim and the temperature values are
correct, though.
(FYI I will probably have a harder time regarding the drivers from
GitHub you linked in 2/3, so no promises on testing them.)
> As per my Exynos5422 user manual and DTS mapping
> thermal-sensor tmu@10060000 is mapped to CPU0 with tmu_apbif clock
> thermal-sensor tmu@10064000 is mapped to CPU1 with tmu_apbif clock
> thermal-sensor tmu@10068000 is mapped to CPU2 with tmu_apbif clock
> thermal-sensor tmu@1006c000 is mapped to CPU3 with tmu_apbif clock
> thermal-sensor tmu@100a0000 is mapped to GPU with tmu_triminfo_apbif clock.
Hmm, I might be missing something, but I think the DTS does link to two
adresses and two clocks, for instance for GPU (in
arch/arm/boot/dts/samsung/exynos5420.dtsi):
tmu_gpu: tmu@100a0000 {
compatible = "samsung,exynos5420-tmu-ext-triminfo";
reg = <0x100a0000 0x100>, <0x10068000 0x4>;
interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>;
clock-names = "tmu_apbif", "tmu_triminfo_apbif";
#thermal-sensor-cells = <0>;
};
The manual does indeed not say anything about this, but I feel like the
current code in essence states that the manual is not correct. We
probably should have some evidence that the current code is wrong and
the manual was correct all along?
Thank you,
Mateusz Majewski
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs
2025-06-24 7:58 ` Mateusz Majewski
@ 2025-06-26 18:21 ` Anand Moon
0 siblings, 0 replies; 14+ messages in thread
From: Anand Moon @ 2025-06-26 18:21 UTC (permalink / raw)
To: Mateusz Majewski
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba, rafael,
rui.zhang
Hi Mateusz
On Tue, 24 Jun 2025 at 13:28, Mateusz Majewski <m.majewski2@samsung.com> wrote:
>
> > I tried to configure this, referring to the comment in the driver
> > /*
> > * Clear the interrupts. Please note that the documentation for
> > * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
> > * states that INTCLEAR register has a different placing of bits
> > * responsible for FALL IRQs than INTSTAT register. Exynos5420
> > * and Exynos5440 documentation is correct (Exynos4210 doesn't
> > * support FALL IRQs at all).
> > */
> >
> > By the way, I don't see Exynos5433 and Exynos7 support
> > INTSTAT and INTCLEAR registers. We are using TMU_REG_INTPEND
> > to read and update the same register.
> >
> > if (data->soc == SOC_ARCH_EXYNOS5260) {
> > tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
> > tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
> > } else if (data->soc == SOC_ARCH_EXYNOS7) {
> > tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
> > tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
> > } else if (data->soc == SOC_ARCH_EXYNOS5433) {
> > tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
> > tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
> > } else {
> > tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
> > tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
> > }
>
> My understanding of this comment and the situation in general is like
> this:
>
Thanks for clarifying this in such detail.
> 1. On 5420, whenever there is edge interrupt, no matter if rise or fall,
> a bit gets set to 1 inside INTSTAT, and we clear it by setting the
> same bit to 1 inside INTCLEAR. The current code does not rely on the
> concrete bit index, it will just check the temperature after the
> interrupt.
Correct
> 2. On 4210, there is no falling edge interrupts (so
> exynos4210_tmu_set_low_temp is empty, we enable polling in DT etc).
> This is what the "Exynos4210 doesn't support FALL IRQs at all" means.
> However, rising edge interrupts work exactly the same as on 5420:
> a bit gets set to 1 inside INTSTAT, and we clear it by setting the
> same bit to 1 inside INTCLEAR.
For Exynos4210, I am skipping this in the next patch.
> 3. On 3250, 4412, 5250, 5260, it again works the same way as 5420.
> However, somebody had a copy of documentation that was incorrect: it
> said that bit indices does not match somehow, which is not true.
> 4. On 5433 and 7, it one more time works the same way as 5420, with a
> single change: a bit gets set to 1 inside INTPEND, and we clear it
> by setting it to 1 inside the same INTPEND.
>
> So, all we need to do to support existing SoCs is to read the 1 bit from
> one register, and set the bit with the same index in another register
> (which on some SoCs is the same register). We could interpret the index
> to see what kind of interrupt is this, but we read the temperature to
> get similar information.
>
> So in the end, is it helpful to interpret the INTSTAT bit index, only to
> reset the exact same index inside INTCLEAR? I guess it could be valuable
> if we also used the information about which interrupt it is and somehow
> used it elsewhere (which could actually help with some issues), but that
> is another thing to do.
>
correct.
> > If you have details on how INTSTAT and INTCLEAR are used
> > particularly regarding the update bits, please share them.
> > Specifically, I'm interested in how bits [7:0] correspond to rising edge
> > interrupts and bits [23:16] to falling edge interrupts
> > I feel it's the same as Exynos54222.
>
> Regarding concrete indices on 5433:
> - the 0th bit corresponds to RISE0,
> - the 1st bit corresponds to RISE1,
> - ...
> - the 7th bit corresponds to RISE7,
> - the 16th bit corresponds to FALL0,
> - the 17th bit corresponds to FALL1,
> - ...
> - the 23th bit corresponds to FALL7.
>
Thanks, I will update this in the next version.
> That is probably because this SoC supports more interrupts than others.
> Though do note that currently, we only use part of them (one RISE, one
> FALL if supported, and another RISE for critical temperature (one
> supporting hardware thermal tripping if possible)). Also note that the
> indices in INTSTAT/INTCLEAR/INTPEND match the ones in INTEN, though I
> have not checked thoroughly if that is true for all the SoCs.
>
As per the manuals, we have to enable each corresponding bit for RISE and FALL
INTEN 0x0070 Interrupt enable register
INTSTAT 0x0074 Interrupt status register
INTCLEAR 0x0078 Interrupt clear register
When current temperature exceeds a threshold rise temperature, then
it generates corresponding interrupt (INTREQ_RISE[2:0]).
When current temperature goes below a threshold fall temperature, then
it generates corresponding interrupt (INTREQ_FALL[2:0].
If we correctly configure the mapping of the RISE and FALL bits along with
INTEN, INTSTAT, and INTCLEAR, the interrupt behavior should function
as expected.
The following outlines the interrupt flow as described in the user manual
[1} https://usermanual.wiki/Document/Exynos20441220SCPUsers20ManualVer01000Preliminary0.167615881
/* Read the measured data from e-fuse */
Triminfo_25 = TRIMINFO[7:0]
/* Calibrated threshold temperature is written into THRES_TEMP_RISE
and THRES_TEMP_FALL */
/* Refer to 1.6.1 */
THRES_TEMP_RISE0 = 0x40;
THRES_TEMP_RISE1 = 0x50;
THRES_TEMP_RISE2 = 0x60;
THRES_TEMP_RISE3 = 0x70;
THRES_TEMP_FALL0 = 0x3A;
THRES_TEMP_FALL1 = 0x4A;
THRES_TEMP_FALL2 = 0x5A;
/* Parameter for sampling interval is set */
SAMPLING_INTERVAL = 0x1;
/* Interrupt enable */
INTEN[24] =0x1; // for INTEN_FALL2
INTEN[20] =0x1; // for INTEN_FALL1
INTEN[16] =0x1; // for INTEN_FALL0
INTEN[8] =0x1; // for INTEN_RISE2
INTEN[4] =0x1; // for INTEN_RISE1
INTEN[0] =0x1; // for INTEN_RISE0
/* Thermal tripping mode selection */
THERM_TRIP_MODE = 0x4;
/* Thermal tripping enable */
THERM_TRIP_EN = 0x1;
/* Check sensing operation is idle */
tmu_idle = 0;
while(tmu_idle&1) {
tmu_idle = TMU_STATUS[0];
}
/* Start sensing operation */
TMU_CONTROL |= 1;
ISR_INTREQ_TMU () {
/* Read interrupt status register */
int_status = INTSTAT;
if(int_status[24]) {
ISR_INT_FALL2();
}
else if(int_status[20]) {
ISR_INT_FALL1();
}
else if(int_status[16]) {
ISR_INT_FALL0();
}
Else if(int_status[8]) {
ISR_INT_RISE2();
}
else if(int_status[4]) {
ISR_INT_RISE1();
}
else if(int_status[0]) {
ISR_INT_RISE0();
}
else {
$display("Some error occurred..!");
}
ISR_INT0 () {
/* Perform proper task for decrease temperature */
INTCLEAR[0] = 0x1;
}
Hey, if you’ve got a bit of time, could you take a look at these changes?
[2] https://lore.kernel.org/all/20250430123306.15072-2-linux.amoon@gmail.com/
> Thank you,
> Mateusz Majewski
Thanks
-Anand
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references
2025-06-25 14:38 ` Mateusz Majewski
@ 2025-06-26 18:22 ` Anand Moon
0 siblings, 0 replies; 14+ messages in thread
From: Anand Moon @ 2025-06-26 18:22 UTC (permalink / raw)
To: Mateusz Majewski
Cc: alim.akhtar, bzolnier, daniel.lezcano, krzk, linux-arm-kernel,
linux-kernel, linux-pm, linux-samsung-soc, lukasz.luba, rafael,
rui.zhang
Hi Mateusz,
On Wed, 25 Jun 2025 at 20:08, Mateusz Majewski <m.majewski2@samsung.com> wrote:
>
> > Can you check with with following changes
> >
> > diff --git a/drivers/thermal/samsung/exynos_tmu.c
> > b/drivers/thermal/samsung/exynos_tmu.c
> > index 9fc085f4ea1a..0776801fafea 100644
> > --- a/drivers/thermal/samsung/exynos_tmu.c
> > +++ b/drivers/thermal/samsung/exynos_tmu.c
> > @@ -469,14 +469,11 @@ static void exynos4412_tmu_initialize(struct
> > platform_device *pdev)
> > ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
> > ctrl = EXYNOS_TRIMINFO_RELOAD_ENABLE;
> > writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
> > + return;
> > }
> >
> > - /* On exynos5420 the triminfo register is in the shared space */
> > - if (data->soc == SOC_ARCH_EXYNOS5420
> > - data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO) {
> > - trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
> > - sanitize_temp_error(data, trim_info);
> > - }
> > + trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
> > + sanitize_temp_error(data, trim_info);
> > }
>
Thanks for the feedback,
> This does seem to work (tested on 3250 and on 5420) in the sense that I
> can read the temperatures, when they increase the state of the cooling
> device gets increased, and the values look reasonable and stay in a
> reasonable range. Hard to say if the trim and the temperature values are
> correct, though.
>
The driver should read the EXYNOS_TMU_REG_TRIMINFO register
after setting the RELOAD bit to 0x1 in the TRIMINFO_CONTROL (0x14) register.
RELOAD Trim information
Before read TRIMINFO, you shall set RELOAD to 1.
1 = Reload
> (FYI I will probably have a harder time regarding the drivers from
> GitHub you linked in 2/3, so no promises on testing them.)
>
It's just a reference point for gathering information - a few things
are missing in the driver.
> > As per my Exynos5422 user manual and DTS mapping
> > thermal-sensor tmu@10060000 is mapped to CPU0 with tmu_apbif clock
> > thermal-sensor tmu@10064000 is mapped to CPU1 with tmu_apbif clock
> > thermal-sensor tmu@10068000 is mapped to CPU2 with tmu_apbif clock
> > thermal-sensor tmu@1006c000 is mapped to CPU3 with tmu_apbif clock
> > thermal-sensor tmu@100a0000 is mapped to GPU with tmu_triminfo_apbif clock.
>
> Hmm, I might be missing something, but I think the DTS does link to two
> adresses and two clocks, for instance for GPU (in
> arch/arm/boot/dts/samsung/exynos5420.dtsi):
>
> tmu_gpu: tmu@100a0000 {
> compatible = "samsung,exynos5420-tmu-ext-triminfo";
> reg = <0x100a0000 0x100>, <0x10068000 0x4>;
> interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>;
> clock-names = "tmu_apbif", "tmu_triminfo_apbif";
> #thermal-sensor-cells = <0>;
> };
>
> The manual does indeed not say anything about this, but I feel like the
> current code in essence states that the manual is not correct. We
> probably should have some evidence that the current code is wrong and
> the manual was correct all along?
Well, I tried to fix the DTS, but it didn't work.
>
> Thank you,
> Mateusz Majewski
Thanks
-Anand
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2025-06-26 18:22 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-16 16:38 [RRC v1 0/3] Simplify Exynos TMU IRQ clean logic Anand Moon
2025-06-16 16:38 ` [RRC v1 1/3] thermal/drivers/exynos: Remove unused base_second mapping and references Anand Moon
[not found] ` <CGME20250618125812eucas1p11a1ab5210d4efa95a51b3bc7c4f0924d@eucas1p1.samsung.com>
2025-06-18 12:58 ` Mateusz Majewski
2025-06-19 5:45 ` Anand Moon
2025-06-21 7:17 ` Anand Moon
[not found] ` <CGME20250625143825eucas1p2e95ba80552cd289b6e05db33f32ec14a@eucas1p2.samsung.com>
2025-06-25 14:38 ` Mateusz Majewski
2025-06-26 18:22 ` Anand Moon
2025-06-16 16:38 ` [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs Anand Moon
[not found] ` <CGME20250618115220eucas1p2b9d37e8cdd1997fa010f51cecdea5e4f@eucas1p2.samsung.com>
2025-06-18 11:52 ` Mateusz Majewski
2025-06-19 5:45 ` Anand Moon
2025-06-21 7:16 ` Anand Moon
[not found] ` <CGME20250624075847eucas1p2db6e908f78aa603bdf6aec38b653e9af@eucas1p2.samsung.com>
2025-06-24 7:58 ` Mateusz Majewski
2025-06-26 18:21 ` Anand Moon
2025-06-16 16:38 ` [RRC v1 3/3] thermal/drivers/exynos: Refactor IRQ clear logic using SoC-specific config Anand Moon
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).