1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2016 Freescale Semiconductor, Inc. 4 */ 5 #include <asm/io.h> 6 #include <asm/arch/clock.h> 7 #include <asm/arch/imx-regs.h> 8 #include <asm/arch/sys_proto.h> 9 #include <asm/mach-imx/hab.h> 10 11 static char *get_reset_cause(char *); 12 13 #if defined(CONFIG_SECURE_BOOT) 14 struct imx_sec_config_fuse_t const imx_sec_config_fuse = { 15 .bank = 29, 16 .word = 6, 17 }; 18 #endif 19 20 u32 get_cpu_rev(void) 21 { 22 /* Temporally hard code the CPU rev to 0x73, rev 1.0. Fix it later */ 23 return (MXC_CPU_MX7ULP << 12) | (1 << 4); 24 } 25 26 #ifdef CONFIG_REVISION_TAG 27 u32 __weak get_board_rev(void) 28 { 29 return get_cpu_rev(); 30 } 31 #endif 32 33 enum bt_mode get_boot_mode(void) 34 { 35 u32 bt0_cfg = 0; 36 37 bt0_cfg = readl(CMC0_RBASE + 0x40); 38 bt0_cfg &= (BT0CFG_LPBOOT_MASK | BT0CFG_DUALBOOT_MASK); 39 40 if (!(bt0_cfg & BT0CFG_LPBOOT_MASK)) { 41 /* No low power boot */ 42 if (bt0_cfg & BT0CFG_DUALBOOT_MASK) 43 return DUAL_BOOT; 44 else 45 return SINGLE_BOOT; 46 } 47 48 return LOW_POWER_BOOT; 49 } 50 51 int arch_cpu_init(void) 52 { 53 return 0; 54 } 55 56 #ifdef CONFIG_BOARD_POSTCLK_INIT 57 int board_postclk_init(void) 58 { 59 return 0; 60 } 61 #endif 62 63 #define UNLOCK_WORD0 0xC520 /* 1st unlock word */ 64 #define UNLOCK_WORD1 0xD928 /* 2nd unlock word */ 65 #define REFRESH_WORD0 0xA602 /* 1st refresh word */ 66 #define REFRESH_WORD1 0xB480 /* 2nd refresh word */ 67 68 static void disable_wdog(u32 wdog_base) 69 { 70 writel(UNLOCK_WORD0, (wdog_base + 0x04)); 71 writel(UNLOCK_WORD1, (wdog_base + 0x04)); 72 writel(0x0, (wdog_base + 0x0C)); /* Set WIN to 0 */ 73 writel(0x400, (wdog_base + 0x08)); /* Set timeout to default 0x400 */ 74 writel(0x120, (wdog_base + 0x00)); /* Disable it and set update */ 75 76 writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */ 77 writel(REFRESH_WORD1, (wdog_base + 0x04)); 78 } 79 80 void init_wdog(void) 81 { 82 /* 83 * ROM will configure WDOG1, disable it or enable it 84 * depending on FUSE. The update bit is set for reconfigurable. 85 * We have to use unlock sequence to reconfigure it. 86 * WDOG2 is not touched by ROM, so it will have default value 87 * which is enabled. We can directly configure it. 88 * To simplify the codes, we still use same reconfigure 89 * process as WDOG1. Because the update bit is not set for 90 * WDOG2, the unlock sequence won't take effect really. 91 * It actually directly configure the wdog. 92 * In this function, we will disable both WDOG1 and WDOG2, 93 * and set update bit for both. So that kernel can reconfigure them. 94 */ 95 disable_wdog(WDG1_RBASE); 96 disable_wdog(WDG2_RBASE); 97 } 98 99 100 void s_init(void) 101 { 102 /* Disable wdog */ 103 init_wdog(); 104 105 /* clock configuration. */ 106 clock_init(); 107 108 return; 109 } 110 111 #ifndef CONFIG_ULP_WATCHDOG 112 void reset_cpu(ulong addr) 113 { 114 setbits_le32(SIM0_RBASE, SIM_SOPT1_A7_SW_RESET); 115 while (1) 116 ; 117 } 118 #endif 119 120 #if defined(CONFIG_DISPLAY_CPUINFO) 121 const char *get_imx_type(u32 imxtype) 122 { 123 return "7ULP"; 124 } 125 126 int print_cpuinfo(void) 127 { 128 u32 cpurev; 129 char cause[18]; 130 131 cpurev = get_cpu_rev(); 132 133 printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n", 134 get_imx_type((cpurev & 0xFF000) >> 12), 135 (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0, 136 mxc_get_clock(MXC_ARM_CLK) / 1000000); 137 138 printf("Reset cause: %s\n", get_reset_cause(cause)); 139 140 printf("Boot mode: "); 141 switch (get_boot_mode()) { 142 case LOW_POWER_BOOT: 143 printf("Low power boot\n"); 144 break; 145 case DUAL_BOOT: 146 printf("Dual boot\n"); 147 break; 148 case SINGLE_BOOT: 149 default: 150 printf("Single boot\n"); 151 break; 152 } 153 154 return 0; 155 } 156 #endif 157 158 #define CMC_SRS_TAMPER (1 << 31) 159 #define CMC_SRS_SECURITY (1 << 30) 160 #define CMC_SRS_TZWDG (1 << 29) 161 #define CMC_SRS_JTAG_RST (1 << 28) 162 #define CMC_SRS_CORE1 (1 << 16) 163 #define CMC_SRS_LOCKUP (1 << 15) 164 #define CMC_SRS_SW (1 << 14) 165 #define CMC_SRS_WDG (1 << 13) 166 #define CMC_SRS_PIN_RESET (1 << 8) 167 #define CMC_SRS_WARM (1 << 4) 168 #define CMC_SRS_HVD (1 << 3) 169 #define CMC_SRS_LVD (1 << 2) 170 #define CMC_SRS_POR (1 << 1) 171 #define CMC_SRS_WUP (1 << 0) 172 173 static u32 reset_cause = -1; 174 175 static char *get_reset_cause(char *ret) 176 { 177 u32 cause1, cause = 0, srs = 0; 178 u32 *reg_ssrs = (u32 *)(SRC_BASE_ADDR + 0x28); 179 u32 *reg_srs = (u32 *)(SRC_BASE_ADDR + 0x20); 180 181 if (!ret) 182 return "null"; 183 184 srs = readl(reg_srs); 185 cause1 = readl(reg_ssrs); 186 writel(cause1, reg_ssrs); 187 188 reset_cause = cause1; 189 190 cause = cause1 & (CMC_SRS_POR | CMC_SRS_WUP | CMC_SRS_WARM); 191 192 switch (cause) { 193 case CMC_SRS_POR: 194 sprintf(ret, "%s", "POR"); 195 break; 196 case CMC_SRS_WUP: 197 sprintf(ret, "%s", "WUP"); 198 break; 199 case CMC_SRS_WARM: 200 cause = cause1 & (CMC_SRS_WDG | CMC_SRS_SW | 201 CMC_SRS_JTAG_RST); 202 switch (cause) { 203 case CMC_SRS_WDG: 204 sprintf(ret, "%s", "WARM-WDG"); 205 break; 206 case CMC_SRS_SW: 207 sprintf(ret, "%s", "WARM-SW"); 208 break; 209 case CMC_SRS_JTAG_RST: 210 sprintf(ret, "%s", "WARM-JTAG"); 211 break; 212 default: 213 sprintf(ret, "%s", "WARM-UNKN"); 214 break; 215 } 216 break; 217 default: 218 sprintf(ret, "%s-%X", "UNKN", cause1); 219 break; 220 } 221 222 debug("[%X] SRS[%X] %X - ", cause1, srs, srs^cause1); 223 return ret; 224 } 225 226 #ifdef CONFIG_ENV_IS_IN_MMC 227 __weak int board_mmc_get_env_dev(int devno) 228 { 229 return CONFIG_SYS_MMC_ENV_DEV; 230 } 231 232 int mmc_get_env_dev(void) 233 { 234 int devno = 0; 235 u32 bt1_cfg = 0; 236 237 /* If not boot from sd/mmc, use default value */ 238 if (get_boot_mode() == LOW_POWER_BOOT) 239 return CONFIG_SYS_MMC_ENV_DEV; 240 241 bt1_cfg = readl(CMC1_RBASE + 0x40); 242 devno = (bt1_cfg >> 9) & 0x7; 243 244 return board_mmc_get_env_dev(devno); 245 } 246 #endif 247