Re: [U-Boot] [PATCH v7 2/4] DM: thermal: Add imx thermal DM driver
Hi, On 20 November 2014 at 06:14, Ye.Li b37...@freescale.com wrote: Add a new thermal uclass for thermal sensor and implement the imx thermal driver basing on this uclass. Signed-off-by: Ye.Li b37...@freescale.com --- drivers/Makefile |1 + drivers/thermal/Makefile |9 ++ drivers/thermal/imx_thermal.c| 177 ++ drivers/thermal/thermal-uclass.c | 30 +++ include/dm/uclass-id.h |1 + include/imx_thermal.h| 17 include/thermal.h| 42 + 7 files changed, 277 insertions(+), 0 deletions(-) [snip] diff --git a/include/thermal.h b/include/thermal.h new file mode 100644 index 000..80b549b --- /dev/null +++ b/include/thermal.h @@ -0,0 +1,42 @@ +/* + * + * (C) Copyright 2014 Freescale Semiconductor, Inc + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#ifndef _THERMAL_H_ +#define _THERMAL_H_ + +#include dm.h + +int thermal_get_temp(struct udevice *dev, int *temp); + +/** + * struct struct dm_thermal_ops - Driver model Thermal operations + * + * The uclass interface is implemented by all Thermal devices which use + * driver model. + */ +struct dm_thermal_ops { + /** +* Get the current temperature +* +* The device provided is the slave device. It's parent controller +* will be used to provide the communication. +* +* This must be called before doing any transfers with a Thermal slave. It +* will enable and initialize any Thermal hardware as necessary, and make +* sure that the SCK line is in the correct idle state. It is not +* allowed to claim the same bus for several slaves without releasing +* the bus in between. +* +* @dev:The Thermal device +* +* Returns: 0 if the bus was claimed successfully, or a negative value +* if it wasn't. +*/ I know this comment is very late - sorry but I did not see this uclass at the time. Please can you fix up the command above? It seems to be copied from SPI and makes no sense. Also please document the @temp parameter. + int (*get_temp)(struct udevice *dev, int *temp); +}; + +#endif /* _THERMAL_H_ */ Finally, all uclasses should have test code. In this case there should be something like test/dm/thermal.c with a simple test to get the device and check its temperature. You can add a driver for sandbox to make this work. If we don't follow this rule right from the start then the next person to come along and add to your uclass will not feel obliged to write tests. You will probably find test/dm/gpio.c helpful, although you will only need a few lines of it for your test (e.g. uclass_get_device() followed by thermal_get_temp()). For sandbox, drivers/misc/i2c_eeprom_emul.c might help although again it has more than you need. Regards, Simon ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH v7 2/4] DM: thermal: Add imx thermal DM driver
On 20/11/2014 14:14, Ye.Li wrote: Add a new thermal uclass for thermal sensor and implement the imx thermal driver basing on this uclass. Signed-off-by: Ye.Li b37...@freescale.com --- After fixing: WARNING: line over 80 characters #481: FILE: include/thermal.h:28: +* This must be called before doing any transfers with a Thermal slave. It WARNING: line over 80 characters #482: FILE: include/thermal.h:29: +* will enable and initialize any Thermal hardware as necessary, and make Applied to u-boot-imx, thanks ! Best regards, Stefano Babic -- = DENX Software Engineering GmbH, MD: Wolfgang Denk Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de = ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v7 2/4] DM: thermal: Add imx thermal DM driver
Add a new thermal uclass for thermal sensor and implement the imx thermal driver basing on this uclass. Signed-off-by: Ye.Li b37...@freescale.com --- drivers/Makefile |1 + drivers/thermal/Makefile |9 ++ drivers/thermal/imx_thermal.c| 177 ++ drivers/thermal/thermal-uclass.c | 30 +++ include/dm/uclass-id.h |1 + include/imx_thermal.h| 17 include/thermal.h| 42 + 7 files changed, 277 insertions(+), 0 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index 33227c8..7683c61 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -21,3 +21,4 @@ obj-y += pwm/ obj-y += input/ # SOC specific infrastructure drivers. obj-y += soc/ +obj-y += thermal/ diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile new file mode 100644 index 000..6d4cacd --- /dev/null +++ b/drivers/thermal/Makefile @@ -0,0 +1,9 @@ +# +# (C) Copyright 2014 Freescale Semiconductor, Inc. +# Author: Nitin Garg nitin.g...@freescale.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_DM_THERMAL) += thermal-uclass.o +obj-$(CONFIG_IMX6_THERMAL) += imx_thermal.o diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c new file mode 100644 index 000..1161585 --- /dev/null +++ b/drivers/thermal/imx_thermal.c @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2014 Freescale Semiconductor, Inc. + * Author: Nitin Garg nitin.g...@freescale.com + * Ye Li ye...@freescale.com + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#include config.h +#include common.h +#include div64.h +#include fuse.h +#include asm/io.h +#include asm/arch/clock.h +#include dm.h +#include errno.h +#include malloc.h +#include thermal.h +#include imx_thermal.h + +#define TEMPERATURE_MIN-40 +#define TEMPERATURE_HOT80 +#define TEMPERATURE_MAX125 +#define FACTOR01000 +#define FACTOR115976 +#define FACTOR24297157 +#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_FREQ0x + +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; + unsigned int *priv = dev_get_priv(dev); + u32 fuse = *priv; + 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) +
Re: [U-Boot] [PATCH v7 2/4] DM: thermal: Add imx thermal DM driver
Hi Ye, On 20/11/2014 14:14, Ye.Li wrote: Add a new thermal uclass for thermal sensor and implement the imx thermal driver basing on this uclass. Thanks for doing this ! Signed-off-by: Ye.Li b37...@freescale.com --- drivers/Makefile |1 + drivers/thermal/Makefile |9 ++ drivers/thermal/imx_thermal.c| 177 ++ drivers/thermal/thermal-uclass.c | 30 +++ include/dm/uclass-id.h |1 + include/imx_thermal.h| 17 include/thermal.h| 42 + 7 files changed, 277 insertions(+), 0 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index 33227c8..7683c61 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -21,3 +21,4 @@ obj-y += pwm/ obj-y += input/ # SOC specific infrastructure drivers. obj-y += soc/ +obj-y += thermal/ diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile new file mode 100644 index 000..6d4cacd --- /dev/null +++ b/drivers/thermal/Makefile @@ -0,0 +1,9 @@ +# +# (C) Copyright 2014 Freescale Semiconductor, Inc. +# Author: Nitin Garg nitin.g...@freescale.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_DM_THERMAL) += thermal-uclass.o +obj-$(CONFIG_IMX6_THERMAL) += imx_thermal.o diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c new file mode 100644 index 000..1161585 --- /dev/null +++ b/drivers/thermal/imx_thermal.c @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2014 Freescale Semiconductor, Inc. + * Author: Nitin Garg nitin.g...@freescale.com + * Ye Li ye...@freescale.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include config.h +#include common.h +#include div64.h +#include fuse.h +#include asm/io.h +#include asm/arch/clock.h +#include dm.h +#include errno.h +#include malloc.h +#include thermal.h +#include imx_thermal.h + +#define TEMPERATURE_MIN -40 +#define TEMPERATURE_HOT 80 +#define TEMPERATURE_MAX 125 +#define FACTOR0 1000 +#define FACTOR1 15976 +#define FACTOR2 4297157 +#define MEASURE_FREQ 327 + +#define TEMPSENSE0_TEMP_CNT_SHIFT8 +#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 0x + +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; + unsigned int *priv = dev_get_priv(dev); + u32 fuse = *priv; + 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