[U-Boot] [PATCH v3 0/2] imx: mx6: use OTP for freq grade

use CPU frequency grade in print_cpuinfo() -- v3: - fix typo in a commit message - add tested-by v2: - split into two series: 1 for CPU frequency, other for Temperature grade
Tim Harvey (2): imx: mx6: add get_cpu_speed_grade_hz func to return MHz speed grade from OTP imx: mx6: display max cpu frequency in print_cpuinfo()
arch/arm/cpu/armv7/mx6/soc.c | 41 +++++++++++++++++++++++++++++++ arch/arm/imx-common/cpu.c | 16 +++++++++++- arch/arm/include/asm/arch-mx6/sys_proto.h | 1 + 3 files changed, 57 insertions(+), 1 deletion(-)

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 --- v3: - no changes v2: - no changes
--- arch/arm/cpu/armv7/mx6/soc.c | 41 +++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx6/sys_proto.h | 1 + 2 files changed, 42 insertions(+)
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index dd34138..71fa1fb 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -83,6 +83,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) { diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 28ba844..a2cd0a9 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -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)

Display the max CPU frequency as well as the current running CPU frequency if the max CPU frequency is available and differs from the current CPU frequency.
Before: CPU: Freescale i.MX6Q rev1.2 at 792 MHz
After - using an 800MHz IMX6DL (running at its max) CPU: Freescale i.MX6DL rev1.1 at 792 MHz
After - using a 1GHz IMX6Q (not running at its max): CPU: Freescale i.MX6Q rev1.2 996 MHz (running at 792 MHz)
Cc: Stefan Roese sr@denx.de Cc: Eric Nelson eric.nelson@boundarydevices.com Cc: Heiko Schocher hs@denx.de Cc: Nikita Kiryanov nikita@compulab.co.il Cc: Jon Nettleton jon.nettleton@gmail.com Cc: Jason Liu r64343@freescale.com Cc: Ye Li b37916@freescale.com Cc: Fabio Estevam fabio.estevam@freescale.com Cc: Christian Gmeiner christian.gmeiner@gmail.com Cc: Markus Niebel Markus.Niebel@tq-group.com Cc: Peng Fan b51431@freescale.com Tested-by: Nikolay Dimitrov picmaster@mail.bg Signed-off-by: Tim Harvey tharvey@gateworks.com --- v3: - fix commit message (mx: mx6 -> imx: mx6) - added Nikolay's tested by v2: - split out from patch that obtains the max cpu freq - add before/after example and more description of change
Signed-off-by: Tim Harvey tharvey@gateworks.com v2: --- arch/arm/imx-common/cpu.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c index 067d08f..6b20482 100644 --- a/arch/arm/imx-common/cpu.c +++ b/arch/arm/imx-common/cpu.c @@ -142,7 +142,7 @@ const char *get_imx_type(u32 imxtype)
int print_cpuinfo(void) { - u32 cpurev; + u32 cpurev, max_freq;
#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL) struct udevice *thermal_dev; @@ -151,11 +151,25 @@ int print_cpuinfo(void)
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); + max_freq = get_cpu_speed_grade_hz(); + if (!max_freq || max_freq == mxc_get_clock(MXC_ARM_CLK)) { + printf(" at %dMHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000); + } else { + printf(" %d MHz (running at %d MHz)\n", max_freq / 1000000, + mxc_get_clock(MXC_ARM_CLK) / 1000000); + } +#else printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n", get_imx_type((cpurev & 0xFF000) >> 12), (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0, mxc_get_clock(MXC_ARM_CLK) / 1000000); +#endif
#if defined(CONFIG_MX6) && defined(CONFIG_IMX6_THERMAL) ret = uclass_get_device(UCLASS_THERMAL, 0, &thermal_dev);
participants (1)
-
Tim Harvey