Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / arm / mach-imx / imx8m / soc.c
index 89229da3b62ac131a651711164a3178b40f11e11..1d2c8e6db281a5c19bed552c4a9f545c5d034f68 100644 (file)
@@ -1,12 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright 2017 NXP
+ * Copyright 2017-2019 NXP
  *
  * Peng Fan <peng.fan@nxp.com>
  */
 
 #include <common.h>
 #include <cpu_func.h>
+#include <init.h>
+#include <log.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
@@ -20,6 +22,7 @@
 #include <fdt_support.h>
 #include <fsl_wdog.h>
 #include <imx_sip.h>
+#include <linux/bitops.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -448,3 +451,76 @@ int arch_misc_init(void)
        return 0;
 }
 #endif
+
+void imx_tmu_arch_init(void *reg_base)
+{
+       if (is_imx8mm() || is_imx8mn()) {
+               /* Load TCALIV and TASR from fuses */
+               struct ocotp_regs *ocotp =
+                       (struct ocotp_regs *)OCOTP_BASE_ADDR;
+               struct fuse_bank *bank = &ocotp->bank[3];
+               struct fuse_bank3_regs *fuse =
+                       (struct fuse_bank3_regs *)bank->fuse_regs;
+
+               u32 tca_rt, tca_hr, tca_en;
+               u32 buf_vref, buf_slope;
+
+               tca_rt = fuse->ana0 & 0xFF;
+               tca_hr = (fuse->ana0 & 0xFF00) >> 8;
+               tca_en = (fuse->ana0 & 0x2000000) >> 25;
+
+               buf_vref = (fuse->ana0 & 0x1F00000) >> 20;
+               buf_slope = (fuse->ana0 & 0xF0000) >> 16;
+
+               writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
+               writel((tca_en << 31) | (tca_hr << 16) | tca_rt,
+                      (ulong)reg_base + 0x30);
+       }
+#ifdef CONFIG_IMX8MP
+       /* Load TCALIV0/1/m40 and TRIM from fuses */
+       struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+       struct fuse_bank *bank = &ocotp->bank[38];
+       struct fuse_bank38_regs *fuse =
+               (struct fuse_bank38_regs *)bank->fuse_regs;
+       struct fuse_bank *bank2 = &ocotp->bank[39];
+       struct fuse_bank39_regs *fuse2 =
+               (struct fuse_bank39_regs *)bank2->fuse_regs;
+       u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr;
+       u32 reg;
+       u32 tca40[2], tca25[2], tca105[2];
+
+       /* For blank sample */
+       if (!fuse->ana_trim2 && !fuse->ana_trim3 &&
+           !fuse->ana_trim4 && !fuse2->ana_trim5) {
+               /* Use a default 25C binary codes */
+               tca25[0] = 1596;
+               tca25[1] = 1596;
+               writel(tca25[0], (ulong)reg_base + 0x30);
+               writel(tca25[1], (ulong)reg_base + 0x34);
+               return;
+       }
+
+       buf_vref = (fuse->ana_trim2 & 0xc0) >> 6;
+       buf_slope = (fuse->ana_trim2 & 0xF00) >> 8;
+       bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12;
+       bgr = (fuse->ana_trim2 & 0xF0000) >> 16;
+       vlsb = (fuse->ana_trim2 & 0xF00000) >> 20;
+       writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
+
+       reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | (1 << 7);
+       writel(reg, (ulong)reg_base + 0x3c);
+
+       tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16;
+       tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28;
+       tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4);
+       tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8;
+       tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20;
+       tca25[1] = fuse2->ana_trim5 & 0xFFF;
+       tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12;
+
+       /* use 25c for 1p calibration */
+       writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30);
+       writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34);
+       writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38);
+#endif
+}