i.mx8mm cpureq cooling issue

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

i.mx8mm cpureq cooling issue

跳至解决方案
1,108 次查看
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 项奖励
1 解答
1,095 次查看
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 项奖励
1 回复
1,096 次查看
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 项奖励