imx: mx6: add get_cpu_speed_grade_hz func to return MHz speed grade from OTP
authorTim Harvey <tharvey@gateworks.com>
Mon, 18 May 2015 14:02:24 +0000 (07:02 -0700)
committerLothar Waßmann <LW@KARO-electronics.de>
Tue, 1 Sep 2015 13:03:55 +0000 (15:03 +0200)
The IMX6 has four different speed grades determined by eFUSE SPEED_GRADING
indicated by OCOTP_CFG3[17:16] which is at 0x440 in the Fusemap Description
Table. Return this frequency so that it can be used elsewhere.

Note that the IMX6SDLRM and the IMX6SXRM do not indicate this in the
their Fusemap Description Table however Freescale has confirmed that these
eFUSE bits match the description within the IMX6DQRM and that they will
be added to the next revision of the respective reference manuals.

These have been tested with IMX6 Quad/Solo/Dual-light 800Mhz and 1GHz grades.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/include/asm/arch-mx6/sys_proto.h

index 6309c25..f49dd37 100644 (file)
@@ -108,6 +108,47 @@ u32 get_cpu_rev(void)
        return (type << 12) | (reg + 0x10);
 }
 
+/*
+ * OCOTP_CFG3[17:16] (see Fusemap Description Table offset 0x440)
+ * defines a 2-bit SPEED_GRADING
+ */
+#define OCOTP_CFG3_SPEED_SHIFT 16
+#define OCOTP_CFG3_SPEED_800MHZ        0
+#define OCOTP_CFG3_SPEED_850MHZ        1
+#define OCOTP_CFG3_SPEED_1GHZ  2
+#define OCOTP_CFG3_SPEED_1P2GHZ        3
+
+u32 get_cpu_speed_grade_hz(void)
+{
+       struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+       struct fuse_bank *bank = &ocotp->bank[0];
+       struct fuse_bank0_regs *fuse =
+               (struct fuse_bank0_regs *)bank->fuse_regs;
+       uint32_t val;
+
+       val = readl(&fuse->cfg3);
+       val >>= OCOTP_CFG3_SPEED_SHIFT;
+       val &= 0x3;
+
+       switch (val) {
+       /* Valid for IMX6DQ */
+       case OCOTP_CFG3_SPEED_1P2GHZ:
+               if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D))
+                       return 1200000000;
+       /* Valid for IMX6SX/IMX6SDL/IMX6DQ */
+       case OCOTP_CFG3_SPEED_1GHZ:
+               return 996000000;
+       /* Valid for IMX6DQ */
+       case OCOTP_CFG3_SPEED_850MHZ:
+               if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D))
+                       return 852000000;
+       /* Valid for IMX6SX/IMX6SDL/IMX6DQ */
+       case OCOTP_CFG3_SPEED_800MHZ:
+               return 792000000;
+       }
+       return 0;
+}
+
 #ifdef CONFIG_REVISION_TAG
 u32 __weak get_board_rev(void)
 {
index 8e92e85..0db28f4 100644 (file)
@@ -16,6 +16,7 @@
 
 u32 get_nr_cpus(void);
 u32 get_cpu_rev(void);
+u32 get_cpu_speed_grade_hz(void);
 
 /* returns MXC_CPU_ value */
 #define cpu_type(rev) (((rev) >> 12)&0xff)