@@ -109,6 +109,38 @@ u32 get_cpu_speed_grade_hz(void)
return 792000000;
}
+#define OCOTP_MEM0_TEMP_SHIFT 6
+
+u32 get_cpu_temp_grade(int *minc, int *maxc)
+{
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+ struct fuse_bank *bank = &ocotp->bank[1];
+ struct fuse_bank1_regs *fuse =
+ (struct fuse_bank1_regs *)bank->fuse_regs;
+ uint32_t val;
+
+ val = readl(&fuse->mem0);
+ val >>= OCOTP_MEM0_TEMP_SHIFT;
+ val &= 0x3;
+
+ if (minc && maxc) {
+ if (val == TEMP_AUTOMOTIVE) {
+ *minc = -40;
+ *maxc = 125;
+ } else if (val == TEMP_INDUSTRIAL) {
+ *minc = -40;
+ *maxc = 105;
+ } else if (val == TEMP_EXTCOMMERCIAL) {
+ *minc = -20;
+ *maxc = 105;
+ } else {
+ *minc = 0;
+ *maxc = 95;
+ }
+ }
+ return val;
+}
+
#ifdef CONFIG_REVISION_TAG
u32 __weak get_board_rev(void)
{
@@ -16,6 +16,7 @@
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/crm_regs.h>
+#include <imx_thermal.h>
#include <ipu_pixfmt.h>
#include <thermal.h>
#include <sata.h>
@@ -146,24 +147,41 @@ int print_cpuinfo(void)
#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)
struct udevice *thermal_dev;
- int cpu_tmp, ret;
+ int cpu_tmp, minc, maxc, ret;
#endif
cpurev = get_cpu_rev();
#if defined(CONFIG_MX6)
printf("CPU: Freescale i.MX%s rev%d.%d",
- get_imx_type((cpurev & 0xFF000) >> 12),
- (cpurev & 0x000F0) >> 4,
- (cpurev & 0x0000F) >> 0);
+ get_imx_type((cpurev & 0xFF000) >> 12),
+ (cpurev & 0x000F0) >> 4,
+ (cpurev & 0x0000F) >> 0);
if (is_cpu_type(MXC_CPU_MX6SX))
printf(" at %d MHz", mxc_get_clock(MXC_ARM_CLK) / 1000000);
else {
+#if defined(CONFIG_IMX6_THERMAL)
+ switch (get_cpu_temp_grade(&minc, &maxc)) {
+ case TEMP_AUTOMOTIVE:
+ puts(" automotive");
+ break;
+ case TEMP_INDUSTRIAL:
+ puts(" industrial");
+ break;
+ case TEMP_EXTCOMMERCIAL:
+ puts(" extended commercial");
+ break;
+ default:
+ puts(" commercial");
+ break;
+ }
+ printf(" (%dC to %dC)", minc, maxc);
printf(" %d MHz", get_cpu_speed_grade_hz() / 1000000);
if (get_cpu_speed_grade_hz() != mxc_get_clock(MXC_ARM_CLK)) {
printf(" (at %d MHz)",
mxc_get_clock(MXC_ARM_CLK) / 1000000);
}
+#endif /* #if defined(CONFIG_IMX6_THERMAL) */
}
puts("\n");
#else
@@ -172,7 +190,7 @@ int print_cpuinfo(void)
(cpurev & 0x000F0) >> 4,
(cpurev & 0x0000F) >> 0,
mxc_get_clock(MXC_ARM_CLK) / 1000000);
-#endif
+#endif /* #if defined(CONFIG_MX6) */
#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL)
ret = uclass_get_device(UCLASS_THERMAL, 0, &thermal_dev);
@@ -17,6 +17,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);
/* returns MXC_CPU_ value */
#define cpu_type(rev) (((rev) >> 12)&0xff)
@@ -8,6 +8,12 @@
#ifndef _IMX_THERMAL_H_
#define _IMX_THERMAL_H_
+/* CPU Temperature Grades */
+#define TEMP_COMMERCIAL 0
+#define TEMP_EXTCOMMERCIAL 1
+#define TEMP_INDUSTRIAL 2
+#define TEMP_AUTOMOTIVE 3
+
struct imx_thermal_plat {
void *regs;
int fuse_bank;
The MX6 has a temperature grade defined by OCOTP_MEM0[7:6]. While the MX6SX also has temperature grades, I see no mention in the reference manual where that information is stored in the OTP. Signed-off-by: Tim Harvey <tharvey@gateworks.com> --- arch/arm/cpu/armv7/mx6/soc.c | 32 +++++++++++++++++++++++++++++++ arch/arm/imx-common/cpu.c | 28 ++++++++++++++++++++++----- arch/arm/include/asm/arch-mx6/sys_proto.h | 1 + include/imx_thermal.h | 6 ++++++ 4 files changed, 62 insertions(+), 5 deletions(-)