i.mx8mm cpureq cooling issue

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.mx8mm cpureq cooling issue

Jump to solution
1,039 Views
matt67
Contributor III

Hello,

I am using kernel 4.14-2.0, with i.mx8m mini.

I notice a bug on the cpufreq cooling mechanism, if the SoC temperature during Linux boot is higher that the passive cooling threshold, the maximum frequency is not set to the lowest.

 

CPUFreqCooling.png

My assumption is that the driver /driver/cpufreq/imx8mq-cpufreq.c is loaded after /driver/thermal/imx8mm_thermal.c (you can verifity that in the boot log).

I made my test in a climatic chamber, but for testing purpose one can simulate an internal temp to 88°C in imx8mm_thermal.c as shown :

 

static int tmu_get_temp(void *data, int *temp)
{
	struct imx8mm_tmu *tmu = data;
	u32 val;
//printk("tmu_get_temp\n");
	/* the temp sensor need about 1ms to finish the measurement */
	msleep(1);

	/* read the calibrated temp value */
	val = readl_relaxed(tmu->tmu_base + TRITSR) & TEMP_VAL_MASK;

	/* check if the temp in the sensor's range */
	if (val < TEMP_LOW_LIMIT)
		return -EAGAIN;

	//*temp = val * 1000;
	*temp = 88 * 1000;
	return 0;
}

 

Could you please give me a patch or idea to fix that ? Switching to kernel 5.2 is not possible, the hardware qualification is done with 4.14

 

0 Kudos
1 Solution
1,026 Views
matt67
Contributor III

I solved it by modifing a bit the initialization of cpufreq implementation. I haven't found any patch regarding that in any mailing list... and seems that all kernel 4.14 and above have the same impl. 

My patch :

diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 908a8014cf76..1321b74fa6d1 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -768,14 +768,6 @@ __cpufreq_cooling_register(struct device_node *np,
cooling_ops = &cpufreq_cooling_ops;
}

- cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,
- cooling_ops);
- if (IS_ERR(cdev))
- goto remove_ida;
-
- cpufreq_cdev->clipped_freq = cpufreq_cdev->freq_table[0].frequency;
- cpufreq_cdev->cdev = cdev;
-
mutex_lock(&cooling_list_lock);
/* Register the notifier for first cpufreq cooling device */
first = list_empty(&cpufreq_cdev_list);
@@ -786,6 +778,20 @@ __cpufreq_cooling_register(struct device_node *np,
cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
CPUFREQ_POLICY_NOTIFIER);

+ /* Bugfix matt67 */
+ /*
+ If cdev is registered before the notifier, the clipped_freq is erased
+ resulting in booting above the passive cooling setpoint doesn't handle well
+ the clipped freq and min/max CPU freq range is wrong.
+ */
+ cpufreq_cdev->clipped_freq = cpufreq_cdev->freq_table[0].frequency;
+ cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,
+ cooling_ops);
+ if (IS_ERR(cdev))
+ goto remove_ida;
+
+ cpufreq_cdev->cdev = cdev;
+
return cdev;

remove_ida:

 

View solution in original post

0 Kudos
1 Reply
1,027 Views
matt67
Contributor III

I solved it by modifing a bit the initialization of cpufreq implementation. I haven't found any patch regarding that in any mailing list... and seems that all kernel 4.14 and above have the same impl. 

My patch :

diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 908a8014cf76..1321b74fa6d1 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -768,14 +768,6 @@ __cpufreq_cooling_register(struct device_node *np,
cooling_ops = &cpufreq_cooling_ops;
}

- cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,
- cooling_ops);
- if (IS_ERR(cdev))
- goto remove_ida;
-
- cpufreq_cdev->clipped_freq = cpufreq_cdev->freq_table[0].frequency;
- cpufreq_cdev->cdev = cdev;
-
mutex_lock(&cooling_list_lock);
/* Register the notifier for first cpufreq cooling device */
first = list_empty(&cpufreq_cdev_list);
@@ -786,6 +778,20 @@ __cpufreq_cooling_register(struct device_node *np,
cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
CPUFREQ_POLICY_NOTIFIER);

+ /* Bugfix matt67 */
+ /*
+ If cdev is registered before the notifier, the clipped_freq is erased
+ resulting in booting above the passive cooling setpoint doesn't handle well
+ the clipped freq and min/max CPU freq range is wrong.
+ */
+ cpufreq_cdev->clipped_freq = cpufreq_cdev->freq_table[0].frequency;
+ cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,
+ cooling_ops);
+ if (IS_ERR(cdev))
+ goto remove_ida;
+
+ cpufreq_cdev->cdev = cdev;
+
return cdev;

remove_ida:

 

0 Kudos