summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv7/mx7/clock.c5
-rw-r--r--arch/arm/cpu/armv7/mx7/soc.c123
-rw-r--r--arch/arm/imx-common/cpu.c5
-rw-r--r--arch/arm/include/asm/arch-mx7/clock.h1
-rw-r--r--drivers/thermal/imx_thermal.c85
-rw-r--r--include/configs/mx7d_arm2.h1
6 files changed, 108 insertions, 112 deletions
diff --git a/arch/arm/cpu/armv7/mx7/clock.c b/arch/arm/cpu/armv7/mx7/clock.c
index 96017d31cc..f8d17dfe41 100644
--- a/arch/arm/cpu/armv7/mx7/clock.c
+++ b/arch/arm/cpu/armv7/mx7/clock.c
@@ -67,6 +67,11 @@ void enable_ocotp_clk(unsigned char enable)
{
clock_enable(CCGR_OCOTP, enable);
}
+
+void enable_thermal_clk(void)
+{
+ enable_ocotp_clk(1);
+}
#endif
void enable_usboh3_clk(unsigned char enable)
diff --git a/arch/arm/cpu/armv7/mx7/soc.c b/arch/arm/cpu/armv7/mx7/soc.c
index 829e30cf80..a9e351fdb6 100644
--- a/arch/arm/cpu/armv7/mx7/soc.c
+++ b/arch/arm/cpu/armv7/mx7/soc.c
@@ -15,6 +15,8 @@
#include <asm/imx-common/dma.h>
#include <stdbool.h>
#include <asm/arch/crm_regs.h>
+#include <dm.h>
+#include <imx_thermal.h>
#ifdef CONFIG_FASTBOOT
#ifdef CONFIG_ANDROID_RECOVERY
#include <recovery.h>
@@ -25,19 +27,20 @@
#include <usb/imx_udc.h>
#endif
-#define TEMPERATURE_MIN -40
-#define TEMPERATURE_HOT 80
-#define TEMPERATURE_MAX 125
-#define FACTOR1 15976
-#define FACTOR2 4297157
-#define MEASURE_FREQ 327
-
-#define REG_VALUE_TO_CEL(ratio, raw) \
- ((raw_n40c - raw) * 100 / ratio - 40)
+struct src *src_reg = (struct src *)SRC_BASE_ADDR;
-static unsigned int fuse = ~0;
+#if defined(CONFIG_IMX_THERMAL)
+static const struct imx_thermal_plat imx7_thermal_plat = {
+ .regs = (void *)ANATOP_BASE_ADDR,
+ .fuse_bank = 3,
+ .fuse_word = 3,
+};
-struct src *src_reg = (struct src *)SRC_BASE_ADDR;
+U_BOOT_DEVICE(imx7_thermal) = {
+ .name = "imx_thermal",
+ .platdata = &imx7_thermal_plat,
+};
+#endif
u32 get_cpu_rev(void)
{
@@ -63,104 +66,6 @@ u32 __weak get_board_rev(void)
}
#endif
-static int read_cpu_temperature(void)
-{
- int temperature;
- unsigned int reg, tmp;
- unsigned int raw_25c, raw_n40c, ratio;
- struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *)
- ANATOP_BASE_ADDR;
- struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
- struct fuse_bank *bank = &ocotp->bank[3];
- struct fuse_bank3_regs *fuse_bank3 =
- (struct fuse_bank3_regs *)bank->fuse_regs;
-
- enable_ocotp_clk(1);
- fuse = readl(&fuse_bank3->ana1);
-
- if (fuse == 0 || fuse == 0xffffffff || (fuse & 0xfff00000) == 0)
- return TEMPERATURE_MIN;
-
- /*
- * fuse data layout:
- * [31:20] sensor value @ 25C
- * [19:8] sensor value of hot
- * [7:0] hot temperature value
- */
- raw_25c = fuse >> 20;
-
- /*
- * The universal equation for thermal sensor
- * is slope = 0.4297157 - (0.0015976 * 25C fuse),
- * here we convert them to integer to make them
- * easy for counting, FACTOR1 is 15976,
- * FACTOR2 is 4297157. Our ratio = -100 * slope
- */
- ratio = ((FACTOR1 * raw_25c - FACTOR2) + 50000) / 100000;
-
- debug("Thermal sensor with ratio = %d\n", ratio);
-
- raw_n40c = raw_25c + (13 * ratio) / 20;
-
- /*
- * 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->tempsense0_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);
-
- while ((readl(&ccm_anatop->tempsense1) &
- TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK) == 0)
- udelay(10000);
-
- reg = readl(&ccm_anatop->tempsense1);
- tmp = (reg & TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK)
- >> TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT;
- writel(TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK, &ccm_anatop->tempsense1_clr);
-
- if (tmp <= raw_n40c)
- temperature = REG_VALUE_TO_CEL(ratio, tmp);
- else
- temperature = TEMPERATURE_MIN;
- /* power down anatop thermal sensor */
- writel(TEMPMON_HW_ANADIG_TEMPSENSE1_POWER_DOWN_MASK, &ccm_anatop->tempsense0_set);
- writel(PMU_REF_REFTOP_SELFBIASOFF_MASK, &ccm_anatop->ref_clr);
-
- return temperature;
-}
-
-void check_cpu_temperature(void)
-{
- int cpu_tmp = 0;
-
- cpu_tmp = read_cpu_temperature();
- while (cpu_tmp > TEMPERATURE_MIN && cpu_tmp < TEMPERATURE_MAX) {
- if (cpu_tmp >= TEMPERATURE_HOT) {
- printf("CPU is %d C, too hot to boot, waiting...\n",
- cpu_tmp);
- udelay(5000000);
- cpu_tmp = read_cpu_temperature();
- } else
- break;
- }
- if (cpu_tmp > TEMPERATURE_MIN && cpu_tmp < TEMPERATURE_MAX)
- printf("CPU: Temperature %d C, calibration data: 0x%x\n",
- cpu_tmp, fuse);
- else
- printf("CPU: Temperature: can't get valid data!\n");
-}
-
static void init_aips(void)
{
struct aipstz_regs *aips1, *aips2, *aips3;
diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c
index 6e3e61744f..da2629ad0d 100644
--- a/arch/arm/imx-common/cpu.c
+++ b/arch/arm/imx-common/cpu.c
@@ -168,7 +168,7 @@ int print_cpuinfo(void)
(struct dbg_monitor_regs *)DEBUG_MONITOR_BASE_ADDR;
#endif
-#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)
+#if defined(CONFIG_IMX_THERMAL)
struct udevice *thermal_dev;
int cpu_tmp, ret;
#endif
@@ -181,8 +181,7 @@ int print_cpuinfo(void)
(cpurev & 0x0000F) >> 0,
mxc_get_clock(MXC_ARM_CLK) / 1000000);
-#if (defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)) || \
- (defined(CONFIG_MX7) && defined(CONFIG_IMX7_THERMAL))
+#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/arch/arm/include/asm/arch-mx7/clock.h b/arch/arm/include/asm/arch-mx7/clock.h
index cd128ce750..290de9f542 100644
--- a/arch/arm/include/asm/arch-mx7/clock.h
+++ b/arch/arm/include/asm/arch-mx7/clock.h
@@ -345,4 +345,5 @@ void hab_caam_clock_enable(void);
void hab_caam_clock_disable(void);
#endif
void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq);
+void enable_thermal_clk(void);
#endif
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 4e1e41299c..cc355b330b 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -18,6 +18,7 @@
#include <thermal.h>
#include <imx_thermal.h>
+#if defined(CONFIG_MX6)
#define TEMPERATURE_MIN -40
#define TEMPERATURE_HOT 80
#define TEMPERATURE_MAX 125
@@ -116,6 +117,78 @@ 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 2s */
+ do {
+ reg = readl(&ccm_anatop->tempsense1);
+ tmp = (reg & TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK)
+ >> TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT;
+ if (tmp != 0)
+ break;
+ } while (get_timer(0) < (start + 2000));
+ /* Still not get invalid temperature? */
+ if (tmp == 0)
+ return -EINVAL;
+
+ writel(TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK, &ccm_anatop->tempsense1_clr);
+
+ /* Single point */
+ temperature = tmp - (te1 - raw_25c);
+
+ /* 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);
+
+ return temperature;
+}
+#endif
int imx_thermal_get_temp(struct udevice *dev, int *temp)
{
@@ -152,11 +225,23 @@ 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 || (fuse & 0xfff00000) == 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)
+ return -EPERM;
+
+ /* We do not support 105C TE2 */
+ if (((fuse & 0x1c0000) >> 18) == 0x6)
+ return -EPERM;
+#else
+#error "Not support thermal driver"
+#endif
*priv = fuse;
diff --git a/include/configs/mx7d_arm2.h b/include/configs/mx7d_arm2.h
index 06ff695550..118e94c64a 100644
--- a/include/configs/mx7d_arm2.h
+++ b/include/configs/mx7d_arm2.h
@@ -42,6 +42,7 @@
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE UART1_IPS_BASE_ADDR
+#define CONFIG_IMX_THERMAL
#define CONFIG_CMD_FUSE
#ifdef CONFIG_CMD_FUSE
#define CONFIG_MXC_OCOTP