thermal: imx: add imx7d soc thermal support
Subsystems (2)
PATCH v2 1/1 thermal: imx: add imx7d soc thermal support
Add imx7 SoC thermal driver support
---
Changes for V2: Fix build error for missin macro check ;P
drivers/thermal/imx_thermal.c | 86 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 5 deletions(-)
drivers/thermal/imx_thermal.c +81 -5
@@ -25,6 +25,9 @@#define FACTOR1 15976#define FACTOR2 4297157#define MEASURE_FREQ 327 +#define TEMPERATURE_MIN -40 +#define TEMPERATURE_HOT 85 +#define TEMPERATURE_MAX 125#define TEMPSENSE0_TEMP_CNT_SHIFT 8#define TEMPSENSE0_TEMP_CNT_MASK (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT)
@@ -41,7 +44,8 @@ struct thermal_data {int maxc; }; -static int read_cpu_temperature_mx6 (struct udevice *dev) +#if defined(CONFIG_MX6 ) +static int read_cpu_temperature (struct udevice *dev) {int temperature;unsigned int reg, n_meas;
@@ -123,22 +127,87 @@ static int read_cpu_temperature_mx6(struct udevice *dev)return temperature; } +#elif defined(CONFIG_MX7 ) +static int read_cpu_temperature (struct udevice *dev) +{ +unsigned int reg, tmp, start; +unsigned int raw_25c, te1; +int temperature; +unsigned int *priv =dev_get_priv (dev); +u32 fuse = *priv; +struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) +ANATOP_BASE_ADDR ; +/* +* fuse data layout: +* [31:21] sensor value @ 25C +* [20:18] hot temperature value +* [17:9] sensor value of room +* [8:0] sensor value of hot +*/ + + raw_25c = fuse >>21 ; +if (raw_25c ==0 ) + raw_25c =25 ; + + te1 = (fuse >>9 ) &0x1ff ; + +/* +* now we only use single measure, every time we read +* the temperature, we will power on/down anadig thermal +* module +*/ +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_POWER_DOWN_MASK , &ccm_anatop->tempsense1_clr); +writel (PMU_REF_REFTOP_SELFBIASOFF_MASK , &ccm_anatop->ref_set); + +/* write measure freq */ + reg =readl (&ccm_anatop->tempsense1); + reg &= ~TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_FREQ_MASK ; + reg |=TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_FREQ (MEASURE_FREQ ); +writel (reg, &ccm_anatop->tempsense1); + +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MASK , &ccm_anatop->tempsense1_clr); +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK , &ccm_anatop->tempsense1_clr); +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MASK , &ccm_anatop->tempsense1_set); + + start =get_timer (0 ); +/* Wait max 100ms */ +do { +/* +* Since we can not rely on finish bit, use 1ms delay to get +* temperature. From RM, 17us is enough to get data, but +* to gurantee to get the data, delay 100ms here. +*/ + reg =readl (&ccm_anatop->tempsense1); + tmp = (reg &TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK ) + >>TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT ; + }while (get_timer (0 ) < (start +100 )); + +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK , &ccm_anatop->tempsense1_clr); + +/* power down anatop thermal sensor */ +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_POWER_DOWN_MASK , &ccm_anatop->tempsense1_set); +writel (PMU_REF_REFTOP_SELFBIASOFF_MASK , &ccm_anatop->ref_clr); + +/* Single point */ + temperature = tmp - (te1 - raw_25c); + +return temperature; +} +#endif int imx_thermal_get_temp (struct udevice *dev,int *temp) {struct thermal_data *priv =dev_get_priv (dev);int cpu_tmp =0 ; -if (is_soc_type (MXC_SOC_MX6 )) - cpu_tmp =read_cpu_temperature_mx6 (dev); + cpu_tmp =read_cpu_temperature (dev);while (cpu_tmp >= priv->critical) {printf ("CPU Temperature (%dC) too close to max (%dC)" , cpu_tmp, priv->maxc);puts (" waiting...\n" );udelay (5000000 ); -if (is_soc_type (MXC_SOC_MX6 )) - cpu_tmp =read_cpu_temperature_mx6 (dev); + cpu_tmp =read_cpu_temperature (dev); } *temp = cpu_tmp;
@@ -167,6 +236,13 @@ static int imx_thermal_probe(struct udevice *dev) fuse);return -EPERM ; } + }else if (is_soc_type (MXC_SOC_MX7 )) { +/* No Calibration data in FUSE? */ +if ((fuse &0x3ffff ) ==0 ) +return -EPERM ; +/* We do not support 105C TE2 */ +if (((fuse &0x1c0000 ) >>18 ) ==0x6 ) +return -EPERM ; }/* set critical cooling temp */
Signature · 1 line
2.1.4
PATCH v2 1/1 thermal: imx: add imx7d soc thermal support
Hi Adrian,
Quoted 34 lines · Adrian Alonso
Add imx7 SoC thermal driver support
Signed-off-by Adrian Alonso <[email protected]>---
Changes for V2: Fix build error for missin macro check ;Pdrivers/thermal/imx_thermal.c | 86 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 5 deletions(-)drivers/thermal/imx_thermal.c +5
-1@@ -25,6 +25,9 @@#define FACTOR1 15976#define FACTOR2 4297157#define MEASURE_FREQ 327 +#define TEMPERATURE_MIN -40 +#define TEMPERATURE_HOT 85 +#define TEMPERATURE_MAX 125#define TEMPSENSE0_TEMP_CNT_SHIFT 8#define TEMPSENSE0_TEMP_CNT_MASK (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT)@@ -41,7 +44,8 @@ struct thermal_data {int maxc; }; -static int read_cpu_temperature_mx6 (struct udevice *dev) +#if defined(CONFIG_MX6 ) +static int read_cpu_temperature (struct udevice *dev) {int temperature;unsigned int reg, n_meas;
drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct udevice *dev) · line 130
Quoted 4 lines
drivers/thermal/imx_thermal.c +1
-0@@ -123,22 +127,87 @@ static int read_cpu_temperature_mx6(struct udevice *dev) return temperature; } +#elif defined(CONFIG_MX7)
Patch is ok for me. I want only to ask if it works dropping the #ifdef, doing as:
static int read_cpu_temperature(struct udevice *dev)
{
......
if (is_soc_type(MXC_SOC_MX7)) {
<mx7 specific read_temperature>
} else {
<read_cpu_temperature_mx6>
}(I have not checked myself if there are some conflicts with the defines..)
Quoted 92 lines
drivers/thermal/imx_thermal.c +68
-4+static int read_cpu_temperature (struct udevice *dev) +{ +unsigned int reg, tmp, start; +unsigned int raw_25c, te1; +int temperature; +unsigned int *priv =dev_get_priv (dev); +u32 fuse = *priv; +struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) +ANATOP_BASE_ADDR ; +/* +* fuse data layout: +* [31:21] sensor value @ 25C +* [20:18] hot temperature value +* [17:9] sensor value of room +* [8:0] sensor value of hot +*/ + + raw_25c = fuse >>21 ; +if (raw_25c ==0 ) + raw_25c =25 ; + + te1 = (fuse >>9 ) &0x1ff ; + +/* +* now we only use single measure, every time we read +* the temperature, we will power on/down anadig thermal +* module +*/ +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_POWER_DOWN_MASK , &ccm_anatop->tempsense1_clr); +writel (PMU_REF_REFTOP_SELFBIASOFF_MASK , &ccm_anatop->ref_set); + +/* write measure freq */ + reg =readl (&ccm_anatop->tempsense1); + reg &= ~TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_FREQ_MASK ; + reg |=TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_FREQ (MEASURE_FREQ ); +writel (reg, &ccm_anatop->tempsense1); + +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MASK , &ccm_anatop->tempsense1_clr); +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK , &ccm_anatop->tempsense1_clr); +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MASK , &ccm_anatop->tempsense1_set); + + start =get_timer (0 ); +/* Wait max 100ms */ +do { +/* +* Since we can not rely on finish bit, use 1ms delay to get +* temperature. From RM, 17us is enough to get data, but +* to gurantee to get the data, delay 100ms here. +*/ + reg =readl (&ccm_anatop->tempsense1); + tmp = (reg &TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK ) + >>TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT ; + }while (get_timer (0 ) < (start +100 )); + +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK , &ccm_anatop->tempsense1_clr); + +/* power down anatop thermal sensor */ +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_POWER_DOWN_MASK , &ccm_anatop->tempsense1_set); +writel (PMU_REF_REFTOP_SELFBIASOFF_MASK , &ccm_anatop->ref_clr); + +/* Single point */ + temperature = tmp - (te1 - raw_25c); + +return temperature; +} +#endif int imx_thermal_get_temp (struct udevice *dev,int *temp) {struct thermal_data *priv =dev_get_priv (dev);int cpu_tmp =0 ; -if (is_soc_type (MXC_SOC_MX6 )) - cpu_tmp =read_cpu_temperature_mx6 (dev); + cpu_tmp =read_cpu_temperature (dev);while (cpu_tmp >= priv->critical) {printf ("CPU Temperature (%dC) too close to max (%dC)" , cpu_tmp, priv->maxc);puts (" waiting...\n" );udelay (5000000 ); -if (is_soc_type (MXC_SOC_MX6 )) - cpu_tmp =read_cpu_temperature_mx6 (dev); + cpu_tmp =read_cpu_temperature (dev); } *temp = cpu_tmp;@@ -167,6 +236,13 @@ static int imx_thermal_probe(struct udevice *dev) fuse);return -EPERM ; }
drivers/thermal/imx_thermal.c static int imx_thermal_probe(struct udevice *dev) · line 248
Quoted 10 lines
drivers/thermal/imx_thermal.c +7
-0+ }else if (is_soc_type (MXC_SOC_MX7 )) { +/* No Calibration data in FUSE? */ +if ((fuse &0x3ffff ) ==0 ) +return -EPERM ; +/* We do not support 105C TE2 */ +if (((fuse &0x1c0000 ) >>18 ) ==0x6 ) +return -EPERM ; }/* set critical cooling temp */
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================
PATCH v2 1/1 thermal: imx: add imx7d soc thermal support
Hi Stefano,
Quoted 66 lines
-----Original Message-----
From: Stefano Babic [mailto:sbabic at denx.de]
Sent: Monday, August 31, 2015 11:40 AM
To: Alonso Lazcano Adrian-B38018 <[email protected]>; u- boot at lists.denx.de; sbabic at denx.de
Cc: otavio at ossystems.com.br; Estevam Fabio-R49496 <[email protected]>; Li Frank-B20596 <[email protected]>; Garg Nitin-B37173 <[email protected]>
Subject: Re: [PATCH][v2] thermal: imx: add imx7d soc thermal supportHi Adrian,
Quoted 15 lines · Adrian Alonso
Add imx7 SoC thermal driver support
Signed-off-by Adrian Alonso <[email protected]>---
Changes for V2: Fix build error for missin macro check ;Pdrivers/thermal/imx_thermal.c | 86 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 5 deletions(-)(quoted diff) +0
-0
b/drivers/thermal/imx_thermal.cindex 7848dc3..f3b0ac3 100644drivers/thermal/imx_thermal.c line 33
Quoted 9 lines
drivers/thermal/imx_thermal.c +3
-0@@ -25,6 +25,9 @@#define FACTOR1 15976#define FACTOR2 4297157#define MEASURE_FREQ 327 +#define TEMPERATURE_MIN -40 +#define TEMPERATURE_HOT 85 +#define TEMPERATURE_MAX 125#define TEMPSENSE0_TEMP_CNT_SHIFT 8#define TEMPSENSE0_TEMP_CNT_MASK (0xfff <<
TEMPSENSE0_TEMP_CNT_SHIFT)Quoted 11 lines
drivers/thermal/imx_thermal.c +2
-1@@ -41,7 +44,8 @@ struct thermal_data {int maxc; }; -static int read_cpu_temperature_mx6 (struct udevice *dev) +#if defined(CONFIG_MX6 ) +static int read_cpu_temperature (struct udevice *dev) {int temperature;unsigned int reg, n_meas;drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct · line 131
Quoted 5 lines
drivers/thermal/imx_thermal.c +1
-0@@ -123,22 +127,87 @@ static int read_cpu_temperature_mx6(struct udevice *dev) return temperature; } +#elif defined(CONFIG_MX7)Patch is ok for me. I want only to ask if it works dropping the #ifdef, doing as:
static int read_cpu_temperature(struct udevice *dev) { ...... if (is_soc_type(MXC_SOC_MX7)) { <mx7 specific read_temperature> } else { <read_cpu_temperature_mx6> }
Quoted 2 lines
(I have not checked myself if there are some conflicts with the defines..)
[Adrian] The problem is that without the platform CONFIG_MX6/7 defines there will be build errors as The anatop register structs differs for each SoC;
Quoted 130 lines
drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct udevice *dev)
Quoted 7 lines
drivers/thermal/imx_thermal.c +7
-0+static int read_cpu_temperature (struct udevice *dev) { +unsigned int reg, tmp, start; +unsigned int raw_25c, te1; +int temperature; +unsigned int *priv =dev_get_priv (dev); +u32 fuse = *priv; + struct mxc_ccm_anatop_reg *ccm_anatop = (struct
mxc_ccm_anatop_reg*)Quoted 11 lines
drivers/thermal/imx_thermal.c +11
-0+ANATOP_BASE_ADDR ; +/* +* fuse data layout: +* [31:21] sensor value @ 25C +* [20:18] hot temperature value +* [17:9] sensor value of room +* [8:0] sensor value of hot +*/ + + raw_25c = fuse >>21 ; +if (raw_25c ==0 )drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct udevice *dev) · line 161
Quoted 10 lines
drivers/thermal/imx_thermal.c +10
-0+ raw_25c =25 ; + + te1 = (fuse >>9 ) &0x1ff ; + +/* +* now we only use single measure, every time we read +* the temperature, we will power on/down anadig thermal +* module +*/ +writel(TEMPMON_HW_ANADIG_TEMPSENSE1_POWER_DOWN_MASK
,&ccm_anatop->tempsense1_clr);drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct udevice *dev)
Quoted 6 lines
drivers/thermal/imx_thermal.c +5
-0+writel (PMU_REF_REFTOP_SELFBIASOFF_MASK , &ccm_anatop- ref_set); + +/* write measure freq */ + reg =readl (&ccm_anatop->tempsense1); + reg &=~TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_FREQ_MASK;
drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct · line 166
Quoted 1 line
drivers/thermal/imx_thermal.c +1
-0+ reg |=
TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_FREQ(MEASURE_FREQ);drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct udevice *dev) · line 171
Quoted 3 lines
drivers/thermal/imx_thermal.c +3
-0+writel (reg, &ccm_anatop->tempsense1); + +writel(TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MAS
K,&ccm_anatop->tempsense1_clr);drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct · line 170
Quoted 1 line
drivers/thermal/imx_thermal.c +1
-0+ writel(TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK,
&ccm_anatop->tempsense1_clr);drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct · line 171
Quoted 1 line
drivers/thermal/imx_thermal.c +1
-0+writel(TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MAS
K,drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct udevice *dev)
Quoted 12 lines
drivers/thermal/imx_thermal.c +12
-0+&ccm_anatop->tempsense1_set); + + start =get_timer (0 ); +/* Wait max 100ms */ + do { + /* + * Since we can not rely on finish bit, use 1ms delay to get + * temperature. From RM, 17us is enough to get data, but + * to gurantee to get the data, delay 100ms here. + */ + reg = readl(&ccm_anatop->tempsense1); + tmp = (reg &
TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK)drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct · line 184
Quoted 1 line
drivers/thermal/imx_thermal.c +1
-0+ >>
TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT;drivers/thermal/imx_thermal.c static int read_cpu_temperature_mx6(struct udevice *dev) · line 190
Quoted 7 lines
drivers/thermal/imx_thermal.c +7
-0+ }while (get_timer (0 ) < (start +100 )); + +writel (TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK , +&ccm_anatop->tempsense1_clr); + +/* power down anatop thermal sensor */ +writel(TEMPMON_HW_ANADIG_TEMPSENSE1_POWER_DOWN_MASK
,&ccm_anatop->tempsense1_set);Quoted 34 lines
drivers/thermal/imx_thermal.c +10
-4+writel (PMU_REF_REFTOP_SELFBIASOFF_MASK , &ccm_anatop- ref_clr); + +/* Single point */ + temperature = tmp - (te1 - raw_25c); + + return temperature; +} +#endif int imx_thermal_get_temp (struct udevice *dev,int *temp) {struct thermal_data *priv =dev_get_priv (dev);int cpu_tmp =0 ; -if (is_soc_type (MXC_SOC_MX6 )) - cpu_tmp =read_cpu_temperature_mx6 (dev); + cpu_tmp =read_cpu_temperature (dev);while (cpu_tmp >= priv->critical) {printf ("CPU Temperature (%dC) too close to max (%dC)" , cpu_tmp, priv->maxc);puts (" waiting...\n" );udelay (5000000 ); -if (is_soc_type (MXC_SOC_MX6 )) - cpu_tmp =read_cpu_temperature_mx6 (dev); + cpu_tmp =read_cpu_temperature (dev); } *temp = cpu_tmp;@@ -167,6 +236,13 @@ static int imx_thermal_probe(struct udevice *dev) fuse);return -EPERM ; }drivers/thermal/imx_thermal.c static int imx_thermal_probe(struct udevice *dev) · line 248
Quoted 10 lines
drivers/thermal/imx_thermal.c +7
-0+ }else if (is_soc_type (MXC_SOC_MX7 )) { +/* No Calibration data in FUSE? */ +if ((fuse &0x3ffff ) ==0 ) +return -EPERM ; +/* We do not support 105C TE2 */ +if (((fuse &0x1c0000 ) >>18 ) ==0x6 ) +return -EPERM ; }/* set critical cooling temp */ Best regards,
Stefano Babic--
============================================================
=========
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
============================================================
=========