From: Stefano Babic <sbabic@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] thermal: imx_thermal: rework driver to be reused
Date: Tue, 25 Aug 2015 19:22:44 +0200 [thread overview]
Message-ID: <55DCA464.8010404@denx.de> (raw)
In-Reply-To: <1440518873-22844-1-git-send-email-aalonso@freescale.com>
Hi Adrian,
On 25/08/2015 18:07, Adrian Alonso wrote:
> - Rework imx_thermal driver to be used across i.MX
> processor that support thermal sensors
ok
> - Make read_cpu_temperature SoC dependent
Agree on that, but why moving into the soc / cpu file ?
We have a driver for a specific hardware. The driver supports more as
one SOC. it is a common case. We have already such a cases, and the
driver must have code for both of them.
Take as example the SPI driver (on u-boot or Linux). It supports
multiple i.MXes without demanding code outside of the driver itself.
Aomething like:
read_cpu_temperature_mx6(....)
{
}
read_cpu_temperature_mx7(....)
{
}
int read_cpu_temperature(struct udevice *dev)
{
<check cpu type, call right function>
}
I think moving "read_cpu_temperature" is wrong because everybody expects
that all stuff related to the thermal is in the corresponding driver,
that is imx-thermal.
>
> Signed-off-by: Adrian Alonso <aalonso@freescale.com>
> Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
> ---
> arch/arm/cpu/armv7/mx6/soc.c | 86 +++++++++++++++++++++++-
> arch/arm/imx-common/cpu.c | 13 ++--
> arch/arm/include/asm/arch-mx6/sys_proto.h | 2 +
> drivers/thermal/Makefile | 2 +-
> drivers/thermal/imx_thermal.c | 106 ------------------------------
> include/configs/cgtqmx6eval.h | 4 +-
> 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/mx6ul_14x14_evk.h | 2 +-
> include/configs/tbs2910.h | 2 +-
> include/imx_thermal.h | 26 ++++++++
> 15 files changed, 130 insertions(+), 125 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
> index 8ad8da8..68f4507 100644
> --- a/arch/arm/cpu/armv7/mx6/soc.c
> +++ b/arch/arm/cpu/armv7/mx6/soc.c
> @@ -22,6 +22,7 @@
> #include <asm/arch/mxc_hdmi.h>
> #include <asm/arch/crm_regs.h>
> #include <dm.h>
> +#include <div64.h>
> #include <imx_thermal.h>
>
> enum ldo_reg {
> @@ -38,7 +39,7 @@ struct scu_regs {
> u32 fpga_rev;
> };
>
> -#if defined(CONFIG_IMX6_THERMAL)
> +#if defined(CONFIG_IMX_THERMAL)
> static const struct imx_thermal_plat imx6_thermal_plat = {
> .regs = (void *)ANATOP_BASE_ADDR,
> .fuse_bank = 1,
> @@ -171,6 +172,89 @@ u32 get_cpu_temp_grade(int *minc, int *maxc)
> return val;
> }
>
> +int read_cpu_temperature(struct udevice *dev)
> +{
> + int temperature;
> + unsigned int reg, n_meas;
> + const struct imx_thermal_plat *pdata = dev_get_platdata(dev);
> + struct anatop_regs *anatop = (struct anatop_regs *)pdata->regs;
> + struct thermal_data *priv = dev_get_priv(dev);
> + u32 fuse = priv->fuse;
> + int t1, n1;
> + u32 c1, c2;
> + u64 temp64;
> +
> + /*
> + * Sensor data layout:
> + * [31:20] - sensor value @ 25C
> + * We use universal formula now and only need sensor value @ 25C
> + * slope = 0.4297157 - (0.0015976 * 25C fuse)
> + */
> + n1 = fuse >> 20;
> + t1 = 25; /* t1 always 25C */
> +
> + /*
> + * Derived from linear interpolation:
> + * slope = 0.4297157 - (0.0015976 * 25C fuse)
> + * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
> + * (Nmeas - n1) / (Tmeas - t1) = slope
> + * We want to reduce this down to the minimum computation necessary
> + * for each temperature read. Also, we want Tmeas in millicelsius
> + * and we don't want to lose precision from integer division. So...
> + * Tmeas = (Nmeas - n1) / slope + t1
> + * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
> + * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
> + * Let constant c1 = (-1000 / slope)
> + * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
> + * Let constant c2 = n1 *c1 + 1000 * t1
> + * milli_Tmeas = c2 - Nmeas * c1
> + */
> + temp64 = FACTOR0;
> + temp64 *= 1000;
> + do_div(temp64, FACTOR1 * n1 - FACTOR2);
> + c1 = temp64;
> + c2 = n1 * c1 + 1000 * t1;
> +
> + /*
> + * now we only use single measure, every time we read
> + * the temperature, we will power on/down anadig thermal
> + * module
> + */
> + writel(TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_clr);
> + writel(MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
> +
> + /* setup measure freq */
> + reg = readl(&anatop->tempsense1);
> + reg &= ~TEMPSENSE1_MEASURE_FREQ;
> + reg |= MEASURE_FREQ;
> + writel(reg, &anatop->tempsense1);
> +
> + /* start the measurement process */
> + writel(TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_clr);
> + writel(TEMPSENSE0_FINISHED, &anatop->tempsense0_clr);
> + writel(TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_set);
> +
> + /* make sure that the latest temp is valid */
> + while ((readl(&anatop->tempsense0) &
> + TEMPSENSE0_FINISHED) == 0)
> + udelay(10000);
> +
> + /* read temperature count */
> + reg = readl(&anatop->tempsense0);
> + n_meas = (reg & TEMPSENSE0_TEMP_CNT_MASK)
> + >> TEMPSENSE0_TEMP_CNT_SHIFT;
> + writel(TEMPSENSE0_FINISHED, &anatop->tempsense0_clr);
> +
> + /* milli_Tmeas = c2 - Nmeas * c1 */
> + temperature = (long)(c2 - n_meas * c1)/1000;
> +
> + /* power down anatop thermal sensor */
> + writel(TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_set);
> + writel(MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_clr);
> +
> + return temperature;
> +}
> +
> #ifdef CONFIG_REVISION_TAG
> u32 __weak get_board_rev(void)
> {
> diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c
> index e27546c..a5efbd5 100644
> --- a/arch/arm/imx-common/cpu.c
> +++ b/arch/arm/imx-common/cpu.c
> @@ -154,14 +154,13 @@ int print_cpuinfo(void)
> u32 cpurev;
> __maybe_unused u32 max_freq;
>
> -#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)
> - struct udevice *thermal_dev;
> - int cpu_tmp, minc, maxc, ret;
> -#endif
> -
> cpurev = get_cpu_rev();
>
> -#if defined(CONFIG_MX6)
> +#if defined(CONFIG_IMX_THERMAL)
> + struct udevice *thermal_dev;
> + int cpu_tmp, ret;
> + int minc, maxc;
> +
> printf("CPU: Freescale i.MX%s rev%d.%d",
> get_imx_type((cpurev & 0xFF000) >> 12),
> (cpurev & 0x000F0) >> 4,
> @@ -181,7 +180,7 @@ int print_cpuinfo(void)
> mxc_get_clock(MXC_ARM_CLK) / 1000000);
> #endif
>
> -#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)
> +#if defined(CONFIG_IMX_THERMAL)
> puts("CPU: ");
> switch (get_cpu_temp_grade(&minc, &maxc)) {
> case TEMP_AUTOMOTIVE:
> diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
> index eee8ca8..c4e6ddc 100644
> --- a/arch/arm/include/asm/arch-mx6/sys_proto.h
> +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
> @@ -8,6 +8,7 @@
> #ifndef _SYS_PROTO_H_
> #define _SYS_PROTO_H_
>
> +#include <dm.h>
> #include <asm/imx-common/regs-common.h>
> #include "../arch-imx/cpu.h"
>
> @@ -18,6 +19,7 @@ u32 get_nr_cpus(void);
> u32 get_cpu_rev(void);
> u32 get_cpu_speed_grade_hz(void);
> u32 get_cpu_temp_grade(int *minc, int *maxc);
> +int read_cpu_temperature(struct udevice *dev);
>
> /* returns MXC_CPU_ value */
> #define cpu_type(rev) (((rev) >> 12) & 0xff)
> 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..f037f81 100644
> --- a/drivers/thermal/imx_thermal.c
> +++ b/drivers/thermal/imx_thermal.c
> @@ -8,7 +8,6 @@
>
> #include <config.h>
> #include <common.h>
> -#include <div64.h>
> #include <fuse.h>
> #include <asm/io.h>
> #include <asm/arch/clock.h>
> @@ -19,111 +18,6 @@
> #include <thermal.h>
> #include <imx_thermal.h>
>
> -/* board will busyloop until this many degrees C below CPU max temperature */
> -#define TEMPERATURE_HOT_DELTA 5 /* CPU maxT - 5C */
> -#define FACTOR0 10000000
> -#define FACTOR1 15976
> -#define FACTOR2 4297157
> -#define MEASURE_FREQ 327
> -
> -#define TEMPSENSE0_TEMP_CNT_SHIFT 8
> -#define TEMPSENSE0_TEMP_CNT_MASK (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT)
> -#define TEMPSENSE0_FINISHED (1 << 2)
> -#define TEMPSENSE0_MEASURE_TEMP (1 << 1)
> -#define TEMPSENSE0_POWER_DOWN (1 << 0)
> -#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;
> - unsigned int reg, n_meas;
> - const struct imx_thermal_plat *pdata = dev_get_platdata(dev);
> - struct anatop_regs *anatop = (struct anatop_regs *)pdata->regs;
> - struct thermal_data *priv = dev_get_priv(dev);
> - u32 fuse = priv->fuse;
> - int t1, n1;
> - u32 c1, c2;
> - u64 temp64;
> -
> - /*
> - * Sensor data layout:
> - * [31:20] - sensor value @ 25C
> - * We use universal formula now and only need sensor value @ 25C
> - * slope = 0.4297157 - (0.0015976 * 25C fuse)
> - */
> - n1 = fuse >> 20;
> - t1 = 25; /* t1 always 25C */
> -
> - /*
> - * Derived from linear interpolation:
> - * slope = 0.4297157 - (0.0015976 * 25C fuse)
> - * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
> - * (Nmeas - n1) / (Tmeas - t1) = slope
> - * We want to reduce this down to the minimum computation necessary
> - * for each temperature read. Also, we want Tmeas in millicelsius
> - * and we don't want to lose precision from integer division. So...
> - * Tmeas = (Nmeas - n1) / slope + t1
> - * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
> - * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
> - * Let constant c1 = (-1000 / slope)
> - * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
> - * Let constant c2 = n1 *c1 + 1000 * t1
> - * milli_Tmeas = c2 - Nmeas * c1
> - */
> - temp64 = FACTOR0;
> - temp64 *= 1000;
> - do_div(temp64, FACTOR1 * n1 - FACTOR2);
> - c1 = temp64;
> - c2 = n1 * c1 + 1000 * t1;
> -
> - /*
> - * now we only use single measure, every time we read
> - * the temperature, we will power on/down anadig thermal
> - * module
> - */
> - writel(TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_clr);
> - writel(MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
> -
> - /* setup measure freq */
> - reg = readl(&anatop->tempsense1);
> - reg &= ~TEMPSENSE1_MEASURE_FREQ;
> - reg |= MEASURE_FREQ;
> - writel(reg, &anatop->tempsense1);
> -
> - /* start the measurement process */
> - writel(TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_clr);
> - writel(TEMPSENSE0_FINISHED, &anatop->tempsense0_clr);
> - writel(TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_set);
> -
> - /* make sure that the latest temp is valid */
> - while ((readl(&anatop->tempsense0) &
> - TEMPSENSE0_FINISHED) == 0)
> - udelay(10000);
> -
> - /* read temperature count */
> - reg = readl(&anatop->tempsense0);
> - n_meas = (reg & TEMPSENSE0_TEMP_CNT_MASK)
> - >> TEMPSENSE0_TEMP_CNT_SHIFT;
> - writel(TEMPSENSE0_FINISHED, &anatop->tempsense0_clr);
> -
> - /* milli_Tmeas = c2 - Nmeas * c1 */
> - temperature = (long)(c2 - n_meas * c1)/1000;
> -
> - /* power down anatop thermal sensor */
> - writel(TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_set);
> - writel(MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_clr);
> -
> - return temperature;
> -}
> -
> int imx_thermal_get_temp(struct udevice *dev, int *temp)
> {
> struct thermal_data *priv = dev_get_priv(dev);
> diff --git a/include/configs/cgtqmx6eval.h b/include/configs/cgtqmx6eval.h
> index fb5b82e..c21f178 100644
> --- a/include/configs/cgtqmx6eval.h
> +++ b/include/configs/cgtqmx6eval.h
> @@ -33,10 +33,10 @@
> #define CONFIG_CMD_BMODE
>
> /* Thermal support */
> -#define CONFIG_IMX6_THERMAL
> +#define CONFIG_IMX_THERMAL
>
> #define CONFIG_CMD_FUSE
> -#if defined(CONFIG_CMD_FUSE) || defined(CONFIG_IMX6_THERMAL)
> +#if defined(CONFIG_CMD_FUSE) || defined(CONFIG_IMX_THERMAL)
> #define CONFIG_MXC_OCOTP
> #endif
>
> 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 8b9d922..231bea7 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/mx6ul_14x14_evk.h b/include/configs/mx6ul_14x14_evk.h
> index 6ae736f..7c48313 100644
> --- a/include/configs/mx6ul_14x14_evk.h
> +++ b/include/configs/mx6ul_14x14_evk.h
> @@ -221,6 +221,6 @@
> #define CONFIG_USB_MAX_CONTROLLER_COUNT 2
> #endif
>
> -#define CONFIG_IMX6_THERMAL
> +#define CONFIG_IMX_THERMAL
>
> #endif
> diff --git a/include/configs/tbs2910.h b/include/configs/tbs2910.h
> index 66cb274..70b4403 100644
> --- a/include/configs/tbs2910.h
> +++ b/include/configs/tbs2910.h
> @@ -20,7 +20,7 @@
>
> #define CONFIG_SYS_HZ 1000
>
> -#define CONFIG_IMX6_THERMAL
> +#define CONFIG_IMX_THERMAL
>
> /* Physical Memory Map */
> #define CONFIG_NR_DRAM_BANKS 1
> diff --git a/include/imx_thermal.h b/include/imx_thermal.h
> index 8ce333c..62fed3b 100644
> --- a/include/imx_thermal.h
> +++ b/include/imx_thermal.h
> @@ -20,4 +20,30 @@ struct imx_thermal_plat {
> int fuse_word;
> };
>
> +struct thermal_data {
> + unsigned int fuse;
> + int critical;
> + int minc;
> + int maxc;
> +};
> +
> +/* board will busyloop until this many degrees C below CPU max temperature */
> +#define TEMPERATURE_HOT_DELTA 5 /* CPU maxT - 5C */
> +#define FACTOR0 10000000
> +#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)
> +#define TEMPSENSE0_FINISHED (1 << 2)
> +#define TEMPSENSE0_MEASURE_TEMP (1 << 1)
> +#define TEMPSENSE0_POWER_DOWN (1 << 0)
> +#define MISC0_REFTOP_SELBIASOFF (1 << 3)
> +#define TEMPSENSE1_MEASURE_FREQ 0xffff
> +
> #endif /* _IMX_THERMAL_H_ */
>
Regards,
Stefano
--
=====================================================================
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
=====================================================================
next prev parent reply other threads:[~2015-08-25 17:22 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-25 16:07 [U-Boot] [PATCH] thermal: imx_thermal: rework driver to be reused Adrian Alonso
2015-08-25 17:22 ` Stefano Babic [this message]
2015-08-25 18:56 ` Alonso Adrian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55DCA464.8010404@denx.de \
--to=sbabic@denx.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.