1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2016 Freescale Semiconductor, Inc. 4 * Copyright 2021 NXP 5 */ 6 7#include <common.h> 8#include <cpu_func.h> 9#include <init.h> 10#include <log.h> 11#include <asm/io.h> 12#include <asm/arch/clock.h> 13#include <asm/arch/imx-regs.h> 14#include <asm/arch/sys_proto.h> 15#include <asm/mach-imx/boot_mode.h> 16#include <asm/mach-imx/hab.h> 17#include <asm/mach-imx/sys_proto.h> 18#include <asm/setup.h> 19#include <linux/bitops.h> 20#include <dm.h> 21 22#define PMC0_BASE_ADDR 0x410a1000 23#define PMC0_CTRL 0x28 24#define PMC0_CTRL_LDOEN BIT(31) 25#define PMC0_CTRL_LDOOKDIS BIT(30) 26#define PMC0_CTRL_PMC1ON BIT(24) 27#define PMC1_BASE_ADDR 0x40400000 28#define PMC1_RUN 0x8 29#define PMC1_STOP 0x10 30#define PMC1_VLPS 0x14 31#define PMC1_LDOVL_SHIFT 16 32#define PMC1_LDOVL_MASK (0x3f << PMC1_LDOVL_SHIFT) 33#define PMC1_LDOVL_900 0x1e 34#define PMC1_LDOVL_950 0x23 35#define PMC1_STATUS 0x20 36#define PMC1_STATUS_LDOVLF BIT(8) 37 38static char *get_reset_cause(char *); 39 40#if defined(CONFIG_IMX_HAB) 41struct imx_sec_config_fuse_t const imx_sec_config_fuse = { 42 .bank = 29, 43 .word = 6, 44}; 45#endif 46 47#define ROM_VERSION_ADDR 0x80 48u32 get_cpu_rev(void) 49{ 50 /* Check the ROM version for cpu revision */ 51 u32 rom_version = readl((void __iomem *)ROM_VERSION_ADDR); 52 53 return (MXC_CPU_MX7ULP << 12) | (rom_version & 0xFF); 54} 55 56#ifdef CONFIG_REVISION_TAG 57u32 __weak get_board_rev(void) 58{ 59 return get_cpu_rev(); 60} 61#endif 62 63enum bt_mode get_boot_mode(void) 64{ 65 u32 bt0_cfg = 0; 66 67 bt0_cfg = readl(CMC0_RBASE + 0x40); 68 bt0_cfg &= (BT0CFG_LPBOOT_MASK | BT0CFG_DUALBOOT_MASK); 69 70 if (!(bt0_cfg & BT0CFG_LPBOOT_MASK)) { 71 /* No low power boot */ 72 if (bt0_cfg & BT0CFG_DUALBOOT_MASK) 73 return DUAL_BOOT; 74 else 75 return SINGLE_BOOT; 76 } 77 78 return LOW_POWER_BOOT; 79} 80 81int arch_cpu_init(void) 82{ 83 enable_ca7_smp(); 84 return 0; 85} 86 87#if defined(CONFIG_ARCH_MISC_INIT) 88int arch_misc_init(void) 89{ 90 if (IS_ENABLED(CONFIG_FSL_CAAM)) { 91 struct udevice *dev; 92 int ret; 93 94 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); 95 if (ret) 96 printf("Failed to initialize caam_jr: %d\n", ret); 97 } 98 99 return 0; 100} 101#endif 102 103#ifdef CONFIG_BOARD_POSTCLK_INIT 104int board_postclk_init(void) 105{ 106 return 0; 107} 108#endif 109 110#define UNLOCK_WORD0 0xC520 /* 1st unlock word */ 111#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */ 112#define REFRESH_WORD0 0xA602 /* 1st refresh word */ 113#define REFRESH_WORD1 0xB480 /* 2nd refresh word */ 114 115static void disable_wdog(u32 wdog_base) 116{ 117 u32 val_cs = readl(wdog_base + 0x00); 118 119 if (!(val_cs & 0x80)) 120 return; 121 122 dmb(); 123 __raw_writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */ 124 __raw_writel(REFRESH_WORD1, (wdog_base + 0x04)); 125 dmb(); 126 127 if (!(val_cs & 800)) { 128 dmb(); 129 __raw_writel(UNLOCK_WORD0, (wdog_base + 0x04)); 130 __raw_writel(UNLOCK_WORD1, (wdog_base + 0x04)); 131 dmb(); 132 133 while (!(readl(wdog_base + 0x00) & 0x800)); 134 } 135 dmb(); 136 __raw_writel(0x0, wdog_base + 0x0C); /* Set WIN to 0 */ 137 __raw_writel(0x400, wdog_base + 0x08); /* Set timeout to default 0x400 */ 138 __raw_writel(0x120, wdog_base + 0x00); /* Disable it and set update */ 139 dmb(); 140 141 while (!(readl(wdog_base + 0x00) & 0x400)); 142} 143 144void init_wdog(void) 145{ 146 /* 147 * ROM will configure WDOG1, disable it or enable it 148 * depending on FUSE. The update bit is set for reconfigurable. 149 * We have to use unlock sequence to reconfigure it. 150 * WDOG2 is not touched by ROM, so it will have default value 151 * which is enabled. We can directly configure it. 152 * To simplify the codes, we still use same reconfigure 153 * process as WDOG1. Because the update bit is not set for 154 * WDOG2, the unlock sequence won't take effect really. 155 * It actually directly configure the wdog. 156 * In this function, we will disable both WDOG1 and WDOG2, 157 * and set update bit for both. So that kernel can reconfigure them. 158 */ 159 disable_wdog(WDG1_RBASE); 160 disable_wdog(WDG2_RBASE); 161} 162 163static bool ldo_mode_is_enabled(void) 164{ 165 unsigned int reg; 166 167 reg = readl(PMC0_BASE_ADDR + PMC0_CTRL); 168 if (reg & PMC0_CTRL_LDOEN) 169 return true; 170 else 171 return false; 172} 173 174#if !defined(CONFIG_SPL) || (defined(CONFIG_SPL) && defined(CONFIG_SPL_BUILD)) 175#if defined(CONFIG_LDO_ENABLED_MODE) 176static void init_ldo_mode(void) 177{ 178 unsigned int reg; 179 180 if (ldo_mode_is_enabled()) 181 return; 182 183 /* Set LDOOKDIS */ 184 setbits_le32(PMC0_BASE_ADDR + PMC0_CTRL, PMC0_CTRL_LDOOKDIS); 185 186 /* Set LDOVL to 0.95V in PMC1_RUN */ 187 reg = readl(PMC1_BASE_ADDR + PMC1_RUN); 188 reg &= ~PMC1_LDOVL_MASK; 189 reg |= (PMC1_LDOVL_950 << PMC1_LDOVL_SHIFT); 190 writel(PMC1_BASE_ADDR + PMC1_RUN, reg); 191 192 /* Wait for LDOVLF to be cleared */ 193 reg = readl(PMC1_BASE_ADDR + PMC1_STATUS); 194 while (reg & PMC1_STATUS_LDOVLF) 195 ; 196 197 /* Set LDOVL to 0.95V in PMC1_STOP */ 198 reg = readl(PMC1_BASE_ADDR + PMC1_STOP); 199 reg &= ~PMC1_LDOVL_MASK; 200 reg |= (PMC1_LDOVL_950 << PMC1_LDOVL_SHIFT); 201 writel(PMC1_BASE_ADDR + PMC1_STOP, reg); 202 203 /* Set LDOVL to 0.90V in PMC1_VLPS */ 204 reg = readl(PMC1_BASE_ADDR + PMC1_VLPS); 205 reg &= ~PMC1_LDOVL_MASK; 206 reg |= (PMC1_LDOVL_900 << PMC1_LDOVL_SHIFT); 207 writel(PMC1_BASE_ADDR + PMC1_VLPS, reg); 208 209 /* Set LDOEN bit */ 210 setbits_le32(PMC0_BASE_ADDR + PMC0_CTRL, PMC0_CTRL_LDOEN); 211 212 /* Set the PMC1ON bit */ 213 setbits_le32(PMC0_BASE_ADDR + PMC0_CTRL, PMC0_CTRL_PMC1ON); 214} 215#endif 216 217void s_init(void) 218{ 219 /* Disable wdog */ 220 init_wdog(); 221 222 /* clock configuration. */ 223 clock_init(); 224 225 if (soc_rev() < CHIP_REV_2_0) { 226 /* enable dumb pmic */ 227 writel((readl(SNVS_LP_LPCR) | SNVS_LPCR_DPEN), SNVS_LP_LPCR); 228 } 229 230#if defined(CONFIG_LDO_ENABLED_MODE) 231 init_ldo_mode(); 232#endif 233 return; 234} 235#endif 236 237#ifndef CONFIG_ULP_WATCHDOG 238void reset_cpu(void) 239{ 240 setbits_le32(SIM0_RBASE, SIM_SOPT1_A7_SW_RESET); 241 while (1) 242 ; 243} 244#endif 245 246#if defined(CONFIG_DISPLAY_CPUINFO) 247const char *get_imx_type(u32 imxtype) 248{ 249 return "7ULP"; 250} 251 252int print_cpuinfo(void) 253{ 254 u32 cpurev; 255 char cause[18]; 256 257 cpurev = get_cpu_rev(); 258 259 printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n", 260 get_imx_type((cpurev & 0xFF000) >> 12), 261 (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0, 262 mxc_get_clock(MXC_ARM_CLK) / 1000000); 263 264 printf("Reset cause: %s\n", get_reset_cause(cause)); 265 266 printf("Boot mode: "); 267 switch (get_boot_mode()) { 268 case LOW_POWER_BOOT: 269 printf("Low power boot\n"); 270 break; 271 case DUAL_BOOT: 272 printf("Dual boot\n"); 273 break; 274 case SINGLE_BOOT: 275 default: 276 printf("Single boot\n"); 277 break; 278 } 279 280 if (ldo_mode_is_enabled()) 281 printf("PMC1: LDO enabled mode\n"); 282 else 283 printf("PMC1: LDO bypass mode\n"); 284 285 return 0; 286} 287#endif 288 289#define CMC_SRS_TAMPER (1 << 31) 290#define CMC_SRS_SECURITY (1 << 30) 291#define CMC_SRS_TZWDG (1 << 29) 292#define CMC_SRS_JTAG_RST (1 << 28) 293#define CMC_SRS_CORE1 (1 << 16) 294#define CMC_SRS_LOCKUP (1 << 15) 295#define CMC_SRS_SW (1 << 14) 296#define CMC_SRS_WDG (1 << 13) 297#define CMC_SRS_PIN_RESET (1 << 8) 298#define CMC_SRS_WARM (1 << 4) 299#define CMC_SRS_HVD (1 << 3) 300#define CMC_SRS_LVD (1 << 2) 301#define CMC_SRS_POR (1 << 1) 302#define CMC_SRS_WUP (1 << 0) 303 304static u32 reset_cause = -1; 305 306static char *get_reset_cause(char *ret) 307{ 308 u32 cause1, cause = 0, srs = 0; 309 u32 *reg_ssrs = (u32 *)(SRC_BASE_ADDR + 0x28); 310 u32 *reg_srs = (u32 *)(SRC_BASE_ADDR + 0x20); 311 312 if (!ret) 313 return "null"; 314 315 srs = readl(reg_srs); 316 cause1 = readl(reg_ssrs); 317 writel(cause1, reg_ssrs); 318 319 reset_cause = cause1; 320 321 cause = cause1 & (CMC_SRS_POR | CMC_SRS_WUP | CMC_SRS_WARM); 322 323 switch (cause) { 324 case CMC_SRS_POR: 325 sprintf(ret, "%s", "POR"); 326 break; 327 case CMC_SRS_WUP: 328 sprintf(ret, "%s", "WUP"); 329 break; 330 case CMC_SRS_WARM: 331 cause = cause1 & (CMC_SRS_WDG | CMC_SRS_SW | 332 CMC_SRS_JTAG_RST); 333 switch (cause) { 334 case CMC_SRS_WDG: 335 sprintf(ret, "%s", "WARM-WDG"); 336 break; 337 case CMC_SRS_SW: 338 sprintf(ret, "%s", "WARM-SW"); 339 break; 340 case CMC_SRS_JTAG_RST: 341 sprintf(ret, "%s", "WARM-JTAG"); 342 break; 343 default: 344 sprintf(ret, "%s", "WARM-UNKN"); 345 break; 346 } 347 break; 348 default: 349 sprintf(ret, "%s-%X", "UNKN", cause1); 350 break; 351 } 352 353 debug("[%X] SRS[%X] %X - ", cause1, srs, srs^cause1); 354 return ret; 355} 356 357#ifdef CONFIG_ENV_IS_IN_MMC 358__weak int board_mmc_get_env_dev(int devno) 359{ 360 return CONFIG_SYS_MMC_ENV_DEV; 361} 362 363int mmc_get_env_dev(void) 364{ 365 int devno = 0; 366 u32 bt1_cfg = 0; 367 368 /* If not boot from sd/mmc, use default value */ 369 if (get_boot_mode() == LOW_POWER_BOOT) 370 return CONFIG_SYS_MMC_ENV_DEV; 371 372 bt1_cfg = readl(CMC1_RBASE + 0x40); 373 devno = (bt1_cfg >> 9) & 0x7; 374 375 return board_mmc_get_env_dev(devno); 376} 377#endif 378 379enum boot_device get_boot_device(void) 380{ 381 struct bootrom_sw_info **p = 382 (struct bootrom_sw_info **)ROM_SW_INFO_ADDR; 383 384 enum boot_device boot_dev = SD1_BOOT; 385 u8 boot_type = (*p)->boot_dev_type; 386 u8 boot_instance = (*p)->boot_dev_instance; 387 388 switch (boot_type) { 389 case BOOT_TYPE_SD: 390 boot_dev = boot_instance + SD1_BOOT; 391 break; 392 case BOOT_TYPE_MMC: 393 boot_dev = boot_instance + MMC1_BOOT; 394 break; 395 case BOOT_TYPE_USB: 396 boot_dev = USB_BOOT; 397 break; 398 default: 399 break; 400 } 401 402 return boot_dev; 403} 404 405#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 406/* 407 * OCOTP_CFG (SJC CHALLENGE, Unique ID) 408 * i.MX 7ULP Applications Processor Reference Manual, Rev. 0, 09/2020 409 * 410 * OCOTP_CFG0 offset 0x4B0: 15:0 -> 15:0 bits of Unique ID 411 * OCOTP_CFG1 offset 0x4C0: 15:0 -> 31:16 bits of Unique ID 412 * OCOTP_CFG2 offset 0x4D0: 15:0 -> 47:32 bits of Unique ID 413 * OCOTP_CFG3 offset 0x4E0: 15:0 -> 63:48 bits of Unique ID 414 */ 415void get_board_serial(struct tag_serialnr *serialnr) 416{ 417 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; 418 struct fuse_bank *bank = &ocotp->bank[1]; 419 struct fuse_bank1_regs *fuse = 420 (struct fuse_bank1_regs *)bank->fuse_regs; 421 422 serialnr->low = (fuse->cfg0 & 0xFFFF) + ((fuse->cfg1 & 0xFFFF) << 16); 423 serialnr->high = (fuse->cfg2 & 0xFFFF) + ((fuse->cfg3 & 0xFFFF) << 16); 424} 425#endif /* CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG */ 426