Skip to contentSkip to conversation

add i.MX6 thermal sensor driver

PATCH New Ye.Li 3 participants 11 messages Nov 20, 2014 – Feb 6, 2015

Subsystems (3)
lore
Share & tools
lore

Ye.Li

author
#0 lore raw

v7 cover add i.MX6 thermal sensor driver

This patch set adds i.MX6 thermal sensor driver
and enables it for mx6sabre boards. Also adds
various anadig bit definitions as required for
upcoming drivers.

Changes in v7:
-Convert the imx thermal driver to DM.
-Enable DM drivers for mx6sabre boards.

Changes in v6:
-Aligned imx thermal driver macro defines with kernel

Changes in v5:
-Don't modify the copyright of cpu.c and crm_regs.h file

Changes in v4:
-Added imx6 thermal sensor as a driver
-Renamed the config define to be more meaningful
-Move the clock code to clock.c
-Reusing ocotp driver for reading fuse
-Fix check for calibration fuse not programmed
-Aligned the slope computation with kernel
-Added Anadig register defines as seperate commit

Changes in v3:
-adds the mx6 thermal driver support
-adds the mx6 thermal support to mx6sabresd board.

Changes in v2:
-run checkpatch and fix reported issues

Nitin Garg (1):
mx6: clock: Add thermal clock enable function

Ye.Li (3):
DM: thermal: Add imx thermal DM driver
mx6: thermal: Check cpu temperature via thermal sensor
mx6: mx6sabre common: Enable i.MX thermal DM driver

 arch/arm/cpu/armv7/mx6/clock.c        |   30 ++++++
 arch/arm/cpu/armv7/mx6/soc.c          |   15 +++
 arch/arm/imx-common/cpu.c             |   21 ++++
 arch/arm/include/asm/arch-mx6/clock.h |    1 +
 drivers/Makefile                      |    1 +
 drivers/thermal/Makefile              |    9 ++
 drivers/thermal/imx_thermal.c         |  177 +++++++++++++++++++++++++++++++++
 drivers/thermal/thermal-uclass.c      |   30 ++++++
 include/configs/mx6sabre_common.h     |    7 +-
 include/dm/uclass-id.h                |    1 +
 include/imx_thermal.h                 |   17 +++
 include/thermal.h                     |   42 ++++++++
 12 files changed, 350 insertions(+), 1 deletions(-)
 create mode 100644 drivers/thermal/Makefile
 create mode 100644 drivers/thermal/imx_thermal.c
 create mode 100644 drivers/thermal/thermal-uclass.c
 create mode 100644 include/imx_thermal.h
 create mode 100644 include/thermal.h
Signature · 1 line
1.7.4.1
author
#1 lore raw

PATCH v7 1/4 mx6: clock: Add thermal clock enable function

From: Nitin Garg <[email protected]>

Add api to check and enable pll3 as required
for thermal sensor driver.

---
 arch/arm/cpu/armv7/mx6/clock.c        |   30 ++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-mx6/clock.h |    1 +
 2 files changed, 31 insertions(+), 0 deletions(-)
arch/arm/cpu/armv7/mx6/clock.c +30 -0
index 6c9c78c..144080e 100644
@@ -673,6 +673,36 @@ void hab_caam_clock_enable(unsigned char enable)
 }
 #endif
 
+static void enable_pll3(void)
+{
+	struct anatop_regs __iomem *anatop =
+		(struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
+
+	/* make sure pll3 is enabled */
+	if ((readl(&anatop->usb1_pll_480_ctrl) &
+			BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) {
+		/* enable pll's power */
+		writel(BM_ANADIG_USB1_PLL_480_CTRL_POWER,
+		       &anatop->usb1_pll_480_ctrl_set);
+		writel(0x80, &anatop->ana_misc2_clr);
+		/* wait for pll lock */
+		while ((readl(&anatop->usb1_pll_480_ctrl) &
+			BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0)
+			;
+		/* disable bypass */
+		writel(BM_ANADIG_USB1_PLL_480_CTRL_BYPASS,
+		       &anatop->usb1_pll_480_ctrl_clr);
+		/* enable pll output */
+		writel(BM_ANADIG_USB1_PLL_480_CTRL_ENABLE,
+		       &anatop->usb1_pll_480_ctrl_set);
+	}
+}
+
+void enable_thermal_clk()
+{
+	enable_pll3();
+}
+
 unsigned int mxc_get_clock(enum mxc_clock clk)
 {
 	switch (clk) {
arch/arm/include/asm/arch-mx6/clock.h +1 -0
index 3c58a0a..8e51f9b 100644
@@ -66,4 +66,5 @@ int enable_spi_clk(unsigned char enable, unsigned spi_num);
 void enable_ipu_clock(void);
 int enable_fec_anatop_clock(enum enet_freq freq);
 void enable_enet_clk(unsigned char enable);
+void enable_thermal_clk(void);
 #endif /* __ASM_ARCH_CLOCK_H */
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH v7 1/4 mx6: clock: Add thermal clock enable function

Quoted 8 lines · Ye.Li

From: Nitin Garg <[email protected]>

Add api to check and enable pll3 as required
for thermal sensor driver.

---

After fixing:
ERROR: Bad function definition - void enable_thermal_clk() should probably be void enable_thermal_clk(void)
#124: FILE: arch/arm/cpu/armv7/mx6/clock.c:701:
+void enable_thermal_clk()

Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
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: sbabic at denx.de
=====================================================================
author
#3 lore raw

PATCH v7 2/4 DM: thermal: Add imx thermal DM driver

In reply to Ye.Li

Add a new thermal uclass for thermal sensor and implement the imx thermal driver basing on this uclass.

---
 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(-)
drivers/Makefile +1 -0
index 33227c8..7683c61 100644
@@ -21,3 +21,4 @@ obj-y += pwm/
 obj-y += input/
 # SOC specific infrastructure drivers.
 obj-y += soc/
+obj-y += thermal/
drivers/thermal/Makefile new file +9 -0
new file mode 100644
index 0000000..6d4cacd
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2014 Freescale Semiconductor, Inc.
+# Author: Nitin Garg <[email protected]>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_DM_THERMAL) += thermal-uclass.o
+obj-$(CONFIG_IMX6_THERMAL) += imx_thermal.o
drivers/thermal/imx_thermal.c new file +177 -0

177 lines not on this page · raw message

drivers/thermal/thermal-uclass.c new file +30 -0
new file mode 100644
index 0000000..3bee1a7
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2014 Freescale Semiconductor, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <thermal.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <linux/list.h>
+
+
+int thermal_get_temp(struct udevice *dev, int *temp)
+{
+	const struct dm_thermal_ops *ops = device_get_ops(dev);
+
+	if (!ops->get_temp)
+		return -ENOSYS;
+
+	return ops->get_temp(dev, temp);
+}
+
+UCLASS_DRIVER(thermal) = {
+	.id		= UCLASS_THERMAL,
+	.name		= "thermal",
+};
include/dm/uclass-id.h +1 -0
index a8944c9..202f59b 100644
@@ -28,6 +28,7 @@ enum uclass_id {
 	UCLASS_SPI_GENERIC,	/* Generic SPI flash target */
 	UCLASS_SPI_FLASH,	/* SPI flash */
 	UCLASS_CROS_EC,	/* Chrome OS EC */
+	UCLASS_THERMAL,		/* Thermal sensor */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
include/imx_thermal.h new file +17 -0
new file mode 100644
index 0000000..be13652
@@ -0,0 +1,17 @@
+/*
+ *
+ * (C) Copyright 2014 Freescale Semiconductor, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _IMX_THERMAL_H_
+#define _IMX_THERMAL_H_
+
+struct imx_thermal_plat {
+	void *regs;
+	int fuse_bank;
+	int fuse_word;
+};
+
+#endif	/* _IMX_THERMAL_H_ */
include/thermal.h new file +42 -0

42 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#4 lore raw

PATCH v7 2/4 DM: thermal: Add imx thermal DM driver

Hi Ye,

Quoted 2 lines · Ye.Li

Add a new thermal uclass for thermal sensor and implement the imx thermal driver basing on this uclass.

Thanks for doing this !

Quoted 329 lines
---
 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(-)
drivers/Makefile +1 -0
index 33227c8..7683c61 100644
@@ -21,3 +21,4 @@ obj-y += pwm/
 obj-y += input/
 # SOC specific infrastructure drivers.
 obj-y += soc/
+obj-y += thermal/
drivers/thermal/Makefile new file +9 -0
new file mode 100644
index 0000000..6d4cacd
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2014 Freescale Semiconductor, Inc.
+# Author: Nitin Garg <[email protected]>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_DM_THERMAL) += thermal-uclass.o
+obj-$(CONFIG_IMX6_THERMAL) += imx_thermal.o
drivers/thermal/imx_thermal.c new file +177 -0
new file mode 100644
index 0000000..1161585
@@ -0,0 +1,177 @@
+/*
+ * (C) Copyright 2014 Freescale Semiconductor, Inc.
+ * Author: Nitin Garg <[email protected]>
+ *             Ye Li <[email protected]>
+ *
+ * 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			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
+
+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) &
+		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 = (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)
+{
+	int cpu_tmp = 0;
+
+	cpu_tmp = read_cpu_temperature(dev);
+	while (cpu_tmp > TEMPERATURE_MIN && cpu_tmp < TEMPERATURE_MAX) {
+		if (cpu_tmp >= TEMPERATURE_HOT) {
+			printf("CPU Temperature is %d C, too hot to boot, waiting...\n",
+			       cpu_tmp);
+			udelay(5000000);
+			cpu_tmp = read_cpu_temperature(dev);
+		} else {
+			break;
+		}
+	}
+
+	*temp = cpu_tmp;
+
+	return 0;
+}
+
+static const struct dm_thermal_ops imx_thermal_ops = {
+	.get_temp	= imx_thermal_get_temp,
+};
+
+static int imx_thermal_probe(struct udevice *dev)
+{
+	unsigned int fuse = ~0;
+
+	const struct imx_thermal_plat *pdata = dev_get_platdata(dev);
+	unsigned int *priv = dev_get_priv(dev);
+
+	/* Read Temperature calibration data fuse */
+	fuse_read(pdata->fuse_bank, pdata->fuse_word, &fuse);
+
+	/* Check for valid fuse */
+	if (fuse == 0 || fuse == ~0) {
+		printf("CPU:   Thermal invalid data, fuse: 0x%x\n", fuse);
+		return -EPERM;
+	} else {
+		printf("CPU:   Thermal calibration data: 0x%x\n", fuse);
+	}
+
+	*priv = fuse;
+
+	enable_thermal_clk();
+
+	return 0;
+}
+
+U_BOOT_DRIVER(imx_thermal) = {
+	.name	= "imx_thermal",
+	.id	= UCLASS_THERMAL,
+	.ops	= &imx_thermal_ops,
+	.probe	= imx_thermal_probe,
+	.priv_auto_alloc_size = sizeof(unsigned int),
+	.flags  = DM_FLAG_PRE_RELOC,
+};
drivers/thermal/thermal-uclass.c new file +30 -0
new file mode 100644
index 0000000..3bee1a7
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2014 Freescale Semiconductor, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <thermal.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <linux/list.h>
+
+
+int thermal_get_temp(struct udevice *dev, int *temp)
+{
+	const struct dm_thermal_ops *ops = device_get_ops(dev);
+
+	if (!ops->get_temp)
+		return -ENOSYS;
+
+	return ops->get_temp(dev, temp);
+}
+
+UCLASS_DRIVER(thermal) = {
+	.id		= UCLASS_THERMAL,
+	.name		= "thermal",
+};
include/dm/uclass-id.h +1 -0
index a8944c9..202f59b 100644
@@ -28,6 +28,7 @@ enum uclass_id {
 	UCLASS_SPI_GENERIC,	/* Generic SPI flash target */
 	UCLASS_SPI_FLASH,	/* SPI flash */
 	UCLASS_CROS_EC,	/* Chrome OS EC */
+	UCLASS_THERMAL,		/* Thermal sensor */
 
 	UCLASS_COUNT,
 	UCLASS_INVALID = -1,
include/imx_thermal.h new file +17 -0
new file mode 100644
index 0000000..be13652
@@ -0,0 +1,17 @@
+/*
+ *
+ * (C) Copyright 2014 Freescale Semiconductor, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _IMX_THERMAL_H_
+#define _IMX_THERMAL_H_
+
+struct imx_thermal_plat {
+	void *regs;
+	int fuse_bank;
+	int fuse_word;
+};
+
+#endif	/* _IMX_THERMAL_H_ */
include/thermal.h new file +32 -0
new file mode 100644
index 0000000..80b549b
@@ -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.

include/thermal.h line 42

Quoted 10 lines
include/thermal.h new file +10 -0
+	 *
+	 * @dev:	The Thermal device
+	 *
+	 * Returns: 0 if the bus was claimed successfully, or a negative value
+	 * if it wasn't.
+	 */
+	int (*get_temp)(struct udevice *dev, int *temp);
+};
+
+#endif	/* _THERMAL_H_ */

Fine with me.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
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: sbabic at denx.de
=====================================================================
#5 lore raw

PATCH v7 2/4 DM: thermal: Add imx thermal DM driver

In reply to Ye.Li
Quoted 5 lines · Ye.Li

Add a new thermal uclass for thermal sensor and implement the imx thermal driver basing on this uclass.

---

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

Signature · 5 lines
=====================================================================
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: sbabic at denx.de
=====================================================================
#6 lore raw

PATCH v7 2/4 DM: thermal: Add imx thermal DM driver

In reply to Ye.Li

Hi,

Quoted 14 lines · Ye.Li

Add a new thermal uclass for thermal sensor and implement the imx thermal driver basing on this uclass.

---
 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]

Quoted 34 lines
include/thermal.h new file +28 -0
new file mode 100644
index 0000000..80b549b
@@ -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

include/thermal.h line 38

Quoted 10 lines
include/thermal.h new file +10 -0
+        * 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.

include/thermal.h line 42

Quoted 4 lines
include/thermal.h new file +4 -0
+       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

author
#7 lore raw

PATCH v7 3/4 mx6: thermal: Check cpu temperature via thermal sensor

In reply to Ye.Li

Add imx6 thermal device to mx6 soc file. Read the cpu temperature using this device to access onchip thermal sensor.

---
 arch/arm/cpu/armv7/mx6/soc.c |   15 +++++++++++++++
 arch/arm/imx-common/cpu.c    |   21 +++++++++++++++++++++
 2 files changed, 36 insertions(+), 0 deletions(-)
arch/arm/cpu/armv7/mx6/soc.c +15 -0
index 5fd2a63..5f5f497 100644
@@ -22,6 +22,8 @@
 #include <asm/arch/mxc_hdmi.h>
 #include <asm/arch/crm_regs.h>
 #include <asm/bootm.h>
+#include <dm.h>
+#include <imx_thermal.h>
 
 enum ldo_reg {
 	LDO_ARM,
@@ -37,6 +39,19 @@ struct scu_regs {
 	u32	fpga_rev;
 };
 
+#if defined(CONFIG_IMX6_THERMAL)
+static const struct imx_thermal_plat imx6_thermal_plat = {
+	.regs = (void *)ANATOP_BASE_ADDR,
+	.fuse_bank = 1,
+	.fuse_word = 6,
+};
+
+U_BOOT_DEVICE(imx6_thermal) = {
+	.name = "imx_thermal",
+	.platdata = &imx6_thermal_plat,
+};
+#endif
+
 u32 get_nr_cpus(void)
 {
 	struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
arch/arm/imx-common/cpu.c +21 -0
index 09fc227..e43f188 100644
@@ -17,6 +17,7 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/crm_regs.h>
 #include <ipu_pixfmt.h>
+#include <thermal.h>
 
 #ifdef CONFIG_FSL_ESDHC
 #include <fsl_esdhc.h>
@@ -134,6 +135,11 @@ int print_cpuinfo(void)
 {
 	u32 cpurev;
 
+#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)
+	struct udevice *thermal_dev;
+	int cpu_tmp, ret;
+#endif
+
 	cpurev = get_cpu_rev();
 
 	printf("CPU:   Freescale i.MX%s rev%d.%d at %d MHz\n",
@@ -141,6 +147,21 @@ int print_cpuinfo(void)
 		(cpurev & 0x000F0) >> 4,
 		(cpurev & 0x0000F) >> 0,
 		mxc_get_clock(MXC_ARM_CLK) / 1000000);
+
+#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)
+	ret = uclass_get_device(UCLASS_THERMAL, 0, &thermal_dev);
+	if (!ret) {
+		ret = thermal_get_temp(thermal_dev, &cpu_tmp);
+
+		if (!ret)
+			printf("CPU:   Temperature %d C\n", cpu_tmp);
+		else
+			printf("CPU:   Temperature: invalid sensor data\n");
+	} else {
+		printf("CPU:   Temperature: Can't find sensor device\n");
+	}
+#endif
+
 	printf("Reset cause: %s\n", get_reset_cause());
 	return 0;
 }
Signature · 1 line
1.7.4.1
#8 lore raw

PATCH v7 3/4 mx6: thermal: Check cpu temperature via thermal sensor

Quoted 6 lines · Ye.Li

Add imx6 thermal device to mx6 soc file. Read the cpu temperature using this device to access onchip thermal sensor.

---

Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
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: sbabic at denx.de
=====================================================================
author
#9 lore raw

PATCH v7 4/4 mx6: mx6sabre common: Enable i.MX thermal DM driver

In reply to Ye.Li

Enable i.MX thermal DM driver to mx6sabre_common.h file. Since the thermal is used in init_sequence_f, so define the CONFIG_SYS_MALLOC_F_LEN to support DM driver using in pre relocation phase.

Additional, thermal driver depends on ocotp, make sure to enable CONFIG_MXC_OCOTP when CONFIG_IMX6_THERMAL is selected.

---
 include/configs/mx6sabre_common.h |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)
include/configs/mx6sabre_common.h +6 -1
index 1e10422..9fdd841 100644
@@ -25,6 +25,11 @@
 #define CONFIG_INITRD_TAG
 #define CONFIG_REVISION_TAG
 
+#define CONFIG_DM
+#define CONFIG_DM_THERMAL
+#define CONFIG_SYS_MALLOC_F_LEN	(1 << 10)
+#define CONFIG_IMX6_THERMAL
+
 #define CONFIG_SYS_GENERIC_BOARD
 
 /* Size of malloc() pool */
@@ -37,7 +42,7 @@
 #define CONFIG_MXC_UART
 
 #define CONFIG_CMD_FUSE
-#ifdef CONFIG_CMD_FUSE
+#if defined(CONFIG_CMD_FUSE) || defined(CONFIG_IMX6_THERMAL)
 #define CONFIG_MXC_OCOTP
 #endif
 
Signature · 1 line
1.7.4.1
#10 lore raw

PATCH v7 4/4 mx6: mx6sabre common: Enable i.MX thermal DM driver

Quoted 10 lines · Ye.Li

Enable i.MX thermal DM driver to mx6sabre_common.h file. Since the thermal is used in init_sequence_f, so define the CONFIG_SYS_MALLOC_F_LEN to support DM driver using in pre relocation phase.

Additional, thermal driver depends on ocotp, make sure to enable CONFIG_MXC_OCOTP when CONFIG_IMX6_THERMAL is selected.

---

Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
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: sbabic at denx.de
=====================================================================