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

Adrian Alonso aalonso at freescale.com
Fri Jul 31 00:35:18 CEST 2015


* 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

 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(-)

diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c
index 5e56cfe..2e803f3 100644
--- a/arch/arm/imx-common/cpu.c
+++ b/arch/arm/imx-common/cpu.c
@@ -148,14 +148,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,
@@ -175,7 +177,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:
@@ -192,6 +194,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 0d893c9..046c094 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -19,6 +19,14 @@
 #include <thermal.h>
 #include <imx_thermal.h>
 
+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)
+#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_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);
@@ -161,15 +235,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;
+	}
+#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 8007044..ff24027 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
-- 
2.1.4



More information about the U-Boot mailing list