aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/arch-imx9/imx-regs.h3
-rw-r--r--arch/arm/mach-imx/imx9/soc.c81
2 files changed, 83 insertions, 1 deletions
diff --git a/arch/arm/include/asm/arch-imx9/imx-regs.h b/arch/arm/include/asm/arch-imx9/imx-regs.h
index 065fd1f..76d241e 100644
--- a/arch/arm/include/asm/arch-imx9/imx-regs.h
+++ b/arch/arm/include/asm/arch-imx9/imx-regs.h
@@ -48,6 +48,9 @@
#define BCTRL_GPR_ENET_QOS_INTF_SEL_RGMII (0x1 << 1)
#define BCTRL_GPR_ENET_QOS_CLK_GEN_EN (0x1 << 0)
+#define MARKETING_GRADING_MASK GENMASK(5, 4)
+#define SPEED_GRADING_MASK GENMASK(11, 6)
+
#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
#include <asm/types.h>
#include <stdbool.h>
diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c
index e476581..ca312ff 100644
--- a/arch/arm/mach-imx/imx9/soc.c
+++ b/arch/arm/mach-imx/imx9/soc.c
@@ -26,12 +26,15 @@
#include <env_internal.h>
#include <errno.h>
#include <fdt_support.h>
+#include <imx_thermal.h>
#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <thermal.h>
#include <asm/setup.h>
#include <asm/bootm.h>
#include <asm/arch-imx/cpu.h>
#include <asm/mach-imx/s400_api.h>
-#include <linux/delay.h>
#include <fuse.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -73,6 +76,82 @@ int mmc_get_env_dev(void)
}
#endif
+/*
+ * SPEED_GRADE[5:4] SPEED_GRADE[3:0] MHz
+ * xx 0000 2300
+ * xx 0001 2200
+ * xx 0010 2100
+ * xx 0011 2000
+ * xx 0100 1900
+ * xx 0101 1800
+ * xx 0110 1700
+ * xx 0111 1600
+ * xx 1000 1500
+ * xx 1001 1400
+ * xx 1010 1300
+ * xx 1011 1200
+ * xx 1100 1100
+ * xx 1101 1000
+ * xx 1110 900
+ * xx 1111 800
+ */
+u32 get_cpu_speed_grade_hz(void)
+{
+ u32 speed, max_speed;
+ u32 val;
+
+ fuse_read(2, 3, &val);
+ val = FIELD_GET(SPEED_GRADING_MASK, val) & 0xF;
+
+ speed = MHZ(2300) - val * MHZ(100);
+
+ if (is_imx93())
+ max_speed = MHZ(1700);
+
+ /* In case the fuse of speed grade not programmed */
+ if (speed > max_speed)
+ speed = max_speed;
+
+ return speed;
+}
+
+/*
+ * `00` - Consumer 0C to 95C
+ * `01` - Ext. Consumer -20C to 105C
+ * `10` - Industrial -40C to 105C
+ * `11` - Automotive -40C to 125C
+ */
+u32 get_cpu_temp_grade(int *minc, int *maxc)
+{
+ u32 val;
+
+ fuse_read(2, 3, &val);
+ val = FIELD_GET(MARKETING_GRADING_MASK, val);
+
+ 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) {
+ if (is_imx93()) {
+ /* imx93 only has extended industrial*/
+ *minc = -40;
+ *maxc = 125;
+ } else {
+ *minc = -20;
+ *maxc = 105;
+ }
+ } else {
+ *minc = 0;
+ *maxc = 95;
+ }
+ }
+ return val;
+}
+
static void set_cpu_info(struct sentinel_get_info_data *info)
{
gd->arch.soc_rev = info->soc;