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