[U-Boot] [PATCH v5 05/13] imx: mx7 dm thermal driver support

Alonso Adrian aalonso at freescale.com
Tue Aug 25 18:14:21 CEST 2015


Hi Stefano,

> -----Original Message-----
> From: Stefano Babic [mailto:sbabic at denx.de]
> Sent: Sunday, August 23, 2015 11:04 AM
> To: Alonso Lazcano Adrian-B38018 <aalonso at freescale.com>; u-
> boot at lists.denx.de; sbabic at denx.de; Estevam Fabio-R49496
> <Fabio.Estevam at freescale.com>
> Cc: otavio at ossystems.com.br; Li Frank-B20596 <Frank.Li at freescale.com>;
> Garg Nitin-B37173 <nitin.garg at freescale.com>
> Subject: Re: [PATCH v5 05/13] imx: mx7 dm thermal driver support
> 
> Hi Adrian,
> 
> On 11/08/2015 18:19, Adrian Alonso wrote:
> > * Add thermal driver support for imx7 SoC
> >   read_cpu_temperature is SoC dependent
> > * Redefine config macro to support imx7 and imx6 SoC
> >
> > Signed-off-by: Adrian Alonso <aalonso at freescale.com>
> > Signed-off-by: Peng Fan <Peng.Fan at freescale.com>
> > ---
> > Changes for V2:
> > - Rework patch so it can be applyed on top of patch
> >   imx6: standardise OCOTP and fuse config to mx6_common Changes for
> > V3: Resend Changes for V4: Resend Changes for V5: Resend
> >
> >  arch/arm/imx-common/cpu.c         |  10 ++--
> >  drivers/thermal/Makefile          |   2 +-
> >  drivers/thermal/imx_thermal.c     | 100
> +++++++++++++++++++++++++++++++++++---
> >  include/configs/embestmx6boards.h |   2 +-
> >  include/configs/gw_ventana.h      |   2 +-
> >  include/configs/mx6cuboxi.h       |   2 +-
> >  include/configs/mx6sabre_common.h |   2 +-
> >  include/configs/mx6slevk.h        |   2 +-
> >  include/configs/mx6sxsabresd.h    |   2 +-
> >  include/configs/tbs2910.h         |   2 +-
> >  10 files changed, 108 insertions(+), 18 deletions(-)
> >
> 
> Agree changing the name to CONFIG_IMX_THERMAL.
> 
> > diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c
> > index e27546c..b0b75df 100644
> > --- a/arch/arm/imx-common/cpu.c
> > +++ b/arch/arm/imx-common/cpu.c
> > @@ -154,14 +154,16 @@ int print_cpuinfo(void)
> >  	u32 cpurev;
> >  	__maybe_unused u32 max_freq;
> >
> > -#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)
> > +#if defined(CONFIG_IMX_THERMAL)
> 
> >  	struct udevice *thermal_dev;
> > -	int cpu_tmp, minc, maxc, ret;
> > +	int cpu_tmp, ret;
> >  #endif
> >
> >  	cpurev = get_cpu_rev();
> >
> >  #if defined(CONFIG_MX6)
> 
> > +	int minc, maxc;
> > +
> >  	printf("CPU:   Freescale i.MX%s rev%d.%d",
> >  	       get_imx_type((cpurev & 0xFF000) >> 12),
> >  	       (cpurev & 0x000F0) >> 4,
> > @@ -181,7 +183,7 @@ int print_cpuinfo(void)
> >  		mxc_get_clock(MXC_ARM_CLK) / 1000000);  #endif
> >
> > -#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)
> > +#if defined(CONFIG_MX6) && defined(CONFIG_IMX_THERMAL)
> >  	puts("CPU:   ");
> >  	switch (get_cpu_temp_grade(&minc, &maxc)) {
> >  	case TEMP_AUTOMOTIVE:
> > @@ -198,6 +200,8 @@ int print_cpuinfo(void)
> >  		break;
> >  	}
> >  	printf("(%dC to %dC)", minc, maxc);
> > +#endif
> > +#if defined(CONFIG_IMX_THERMAL)
> >  	ret = uclass_get_device(UCLASS_THERMAL, 0, &thermal_dev);
> >  	if (!ret) {
> >  		ret = thermal_get_temp(thermal_dev, &cpu_tmp); diff --git
> > a/drivers/thermal/Makefile b/drivers/thermal/Makefile index
> > 6d4cacd..d768f5e 100644
> > --- a/drivers/thermal/Makefile
> > +++ b/drivers/thermal/Makefile
> > @@ -6,4 +6,4 @@
> >  #
> >
> >  obj-$(CONFIG_DM_THERMAL) += thermal-uclass.o
> > -obj-$(CONFIG_IMX6_THERMAL) += imx_thermal.o
> > +obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
> > diff --git a/drivers/thermal/imx_thermal.c
> > b/drivers/thermal/imx_thermal.c index 3c6c967..717f36e 100644
> > --- a/drivers/thermal/imx_thermal.c
> > +++ b/drivers/thermal/imx_thermal.c
> > @@ -19,6 +19,14 @@
> >  #include <thermal.h>
> >  #include <imx_thermal.h>
> >
> 
> 
> Because this is a driver, and I guess that we can reuse it in future and newer
> SOCs will have always this feature, I will prefer to remove CPU related  #ifdef
> (#ifdef CONFIG_MX6 and CONFIG_MX7).
> 
> Use in this case (even if sometimes they are defined at compile time) the
> is_cpu_type() accessors, or one of the related functions. For example:
> 
[Adrian] Please take a look at patch "thermal: imx_thermal: rework driver to be reused"
Seems to me that with imx_thermal driver rework as proposed could lead to a better
Reuse of existing thermal driver.
> 
> > +struct thermal_data {
> > +	unsigned int fuse;
> > +	int critical;
> > +	int minc;
> > +	int maxc;
> > +};
> > +
> > +#if defined(CONFIG_MX6)
> >  /* board will busyloop until this many degrees C below CPU max
> temperature */
> >  #define TEMPERATURE_HOT_DELTA   5 /* CPU maxT - 5C */
> >  #define FACTOR0			10000000
> > @@ -34,13 +42,6 @@
> >  #define MISC0_REFTOP_SELBIASOFF		(1 << 3)
> >  #define TEMPSENSE1_MEASURE_FREQ		0xffff
> >
> > -struct thermal_data {
> > -	unsigned int fuse;
> > -	int critical;
> > -	int minc;
> > -	int maxc;
> > -};
> > -
> >  static int read_cpu_temperature(struct udevice *dev)  {
> >  	int temperature;
> > @@ -124,6 +125,79 @@ static int read_cpu_temperature(struct udevice
> *dev)
> >  	return temperature;
> >  }
> >
> > +#elif defined(CONFIG_MX7)
> 
> Here - defines are quite independent, footprint also negligible without ifdef.
> 
> > +#define TEMPERATURE_MIN		-40
> > +#define TEMPERATURE_HOT		85
> > +#define TEMPERATURE_MAX		125
> > +#define MEASURE_FREQ		327
> > +
> > +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_MAS
> K, &ccm_anatop->tempsense1_clr);
> > +	writel(TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK,
> &ccm_anatop->tempsense1_clr);
> > +
> 	writel(TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MAS
> K,
> > +&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); @@ -157,15 +231,27
> @@
> > static int imx_thermal_probe(struct udevice *dev)
> >  	/* Read Temperature calibration data fuse */
> >  	fuse_read(pdata->fuse_bank, pdata->fuse_word, &fuse);
> >
> > +#if defined(CONFIG_MX6)
> >  	/* Check for valid fuse */
> >  	if (fuse == 0 || fuse == ~0) {
> >  		printf("CPU:   Thermal invalid data, fuse: 0x%x\n", fuse);
> >  		return -EPERM;
> >  	}
> > +#elif defined(CONFIG_MX7)
> > +	/* No Calibration data in FUSE? */
> > +	if ((fuse & 0x3ffff) == 0) {
> > +		printf("CPU:	Thermal invalid data, fuse: 0x%x\n", fuse);
> > +		return -EPERM;
> > +	}
> 
> The same here.
> 
> > +#else
> > +#error "Not support thermal driver"
> > +#endif
> >
> > +#if defined(CONFIG_MX6)
> >  	/* set critical cooling temp */
> >  	get_cpu_temp_grade(&priv->minc, &priv->maxc);
> >  	priv->critical = priv->maxc - TEMPERATURE_HOT_DELTA;
> > +#endif
> >  	priv->fuse = fuse;
> >
> >  	enable_thermal_clk();
> > diff --git a/include/configs/embestmx6boards.h
> > b/include/configs/embestmx6boards.h
> > index 12744a6..58cee96 100644
> > --- a/include/configs/embestmx6boards.h
> > +++ b/include/configs/embestmx6boards.h
> > @@ -19,7 +19,7 @@
> >
> >  #define PHYS_SDRAM_SIZE		(1u * 1024 * 1024 * 1024)
> >
> > -#define CONFIG_IMX6_THERMAL
> > +#define CONFIG_IMX_THERMAL
> >
> >  /* Size of malloc() pool */
> >  #define CONFIG_SYS_MALLOC_LEN		(10 * SZ_1M)
> > diff --git a/include/configs/gw_ventana.h
> > b/include/configs/gw_ventana.h index 7c90812..397a5ab 100644
> > --- a/include/configs/gw_ventana.h
> > +++ b/include/configs/gw_ventana.h
> > @@ -57,7 +57,7 @@
> >  #define CONFIG_CMD_GPIO
> >
> >  /* Thermal */
> > -#define CONFIG_IMX6_THERMAL
> > +#define CONFIG_IMX_THERMAL
> >
> >  /* Serial */
> >  #define CONFIG_MXC_UART
> > diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h
> > index 634a09f..6e89dd1 100644
> > --- a/include/configs/mx6cuboxi.h
> > +++ b/include/configs/mx6cuboxi.h
> > @@ -14,7 +14,7 @@
> >  #define CONFIG_SPL_MMC_SUPPORT
> >  #include "imx6_spl.h"
> >
> > -#define CONFIG_IMX6_THERMAL
> > +#define CONFIG_IMX_THERMAL
> >
> >  #define CONFIG_SYS_MALLOC_LEN		(10 * SZ_1M)
> >  #define CONFIG_BOARD_EARLY_INIT_F
> > diff --git a/include/configs/mx6sabre_common.h
> > b/include/configs/mx6sabre_common.h
> > index 6a57841..98eb042 100644
> > --- a/include/configs/mx6sabre_common.h
> > +++ b/include/configs/mx6sabre_common.h
> > @@ -11,7 +11,7 @@
> >
> >  #include "mx6_common.h"
> >
> > -#define CONFIG_IMX6_THERMAL
> > +#define CONFIG_IMX_THERMAL
> >
> >  /* Size of malloc() pool */
> >  #define CONFIG_SYS_MALLOC_LEN		(10 * SZ_1M)
> > diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h
> > index 3cecd94..58e59d8 100644
> > --- a/include/configs/mx6slevk.h
> > +++ b/include/configs/mx6slevk.h
> > @@ -190,6 +190,6 @@
> >  #define CONFIG_SYS_MMC_ENV_DEV		1	/* SDHC2*/
> >  #endif
> >
> > -#define CONFIG_IMX6_THERMAL
> > +#define CONFIG_IMX_THERMAL
> >
> >  #endif				/* __CONFIG_H */
> > diff --git a/include/configs/mx6sxsabresd.h
> > b/include/configs/mx6sxsabresd.h index 848bdcd..381eaa2 100644
> > --- a/include/configs/mx6sxsabresd.h
> > +++ b/include/configs/mx6sxsabresd.h
> > @@ -176,7 +176,7 @@
> >  #define CONFIG_PCIE_IMX_POWER_GPIO	IMX_GPIO_NR(2, 1)
> >  #endif
> >
> > -#define CONFIG_IMX6_THERMAL
> > +#define CONFIG_IMX_THERMAL
> >
> >  #define CONFIG_CMD_TIME
> >
> > diff --git a/include/configs/tbs2910.h b/include/configs/tbs2910.h
> > index 14985f8..4f390c3 100644
> > --- a/include/configs/tbs2910.h
> > +++ b/include/configs/tbs2910.h
> > @@ -21,7 +21,7 @@
> >  #define CONFIG_SYS_PROMPT		"Matrix U-Boot> "
> >  #define CONFIG_SYS_HZ			1000
> >
> > -#define CONFIG_IMX6_THERMAL
> > +#define CONFIG_IMX_THERMAL
> >
> >  /* Physical Memory Map */
> >  #define CONFIG_NR_DRAM_BANKS		1
> >
> 
> 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
> ============================================================
> =========


More information about the U-Boot mailing list