1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2015 Freescale Semiconductor, Inc. 4 */ 5 6 #include <common.h> 7 #include <asm/io.h> 8 #include <asm/arch/imx-regs.h> 9 #include <asm/arch/clock.h> 10 #include <asm/arch/sys_proto.h> 11 #include <asm/mach-imx/dma.h> 12 #include <asm/mach-imx/hab.h> 13 #include <asm/mach-imx/rdc-sema.h> 14 #include <asm/arch/imx-rdc.h> 15 #include <asm/arch/crm_regs.h> 16 #include <dm.h> 17 #include <imx_thermal.h> 18 #include <fsl_sec.h> 19 #include <asm/setup.h> 20 21 #define IOMUXC_GPR1 0x4 22 #define BM_IOMUXC_GPR1_IRQ 0x1000 23 24 #define GPC_LPCR_A7_BSC 0x0 25 #define GPC_LPCR_M4 0x8 26 #define GPC_SLPCR 0x14 27 #define GPC_PGC_ACK_SEL_A7 0x24 28 #define GPC_IMR1_CORE0 0x30 29 #define GPC_IMR1_CORE1 0x40 30 #define GPC_IMR1_M4 0x50 31 #define GPC_PGC_CPU_MAPPING 0xec 32 #define GPC_PGC_C0_PUPSCR 0x804 33 #define GPC_PGC_SCU_TIMING 0x890 34 #define GPC_PGC_C1_PUPSCR 0x844 35 36 #define BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP 0x70000000 37 #define BM_LPCR_A7_BSC_CPU_CLK_ON_LPM 0x4000 38 #define BM_LPCR_M4_MASK_DSM_TRIGGER 0x80000000 39 #define BM_SLPCR_EN_DSM 0x80000000 40 #define BM_SLPCR_RBC_EN 0x40000000 41 #define BM_SLPCR_REG_BYPASS_COUNT 0x3f000000 42 #define BM_SLPCR_VSTBY 0x4 43 #define BM_SLPCR_SBYOS 0x2 44 #define BM_SLPCR_BYPASS_PMIC_READY 0x1 45 #define BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE 0x10000 46 47 #define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK 0x80000000 48 #define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK 0x8000 49 50 #define BM_GPC_PGC_CORE_PUPSCR 0x7fff80 51 52 #if defined(CONFIG_IMX_THERMAL) 53 static const struct imx_thermal_plat imx7_thermal_plat = { 54 .regs = (void *)ANATOP_BASE_ADDR, 55 .fuse_bank = 3, 56 .fuse_word = 3, 57 }; 58 59 U_BOOT_DEVICE(imx7_thermal) = { 60 .name = "imx_thermal", 61 .platdata = &imx7_thermal_plat, 62 }; 63 #endif 64 65 #if CONFIG_IS_ENABLED(IMX_RDC) 66 /* 67 * In current design, if any peripheral was assigned to both A7 and M4, 68 * it will receive ipg_stop or ipg_wait when any of the 2 platforms enter 69 * low power mode. So M4 sleep will cause some peripherals fail to work 70 * at A7 core side. At default, all resources are in domain 0 - 3. 71 * 72 * There are 26 peripherals impacted by this IC issue: 73 * SIM2(sim2/emvsim2) 74 * SIM1(sim1/emvsim1) 75 * UART1/UART2/UART3/UART4/UART5/UART6/UART7 76 * SAI1/SAI2/SAI3 77 * WDOG1/WDOG2/WDOG3/WDOG4 78 * GPT1/GPT2/GPT3/GPT4 79 * PWM1/PWM2/PWM3/PWM4 80 * ENET1/ENET2 81 * Software Workaround: 82 * Here we setup some resources to domain 0 where M4 codes will move 83 * the M4 out of this domain. Then M4 is not able to access them any longer. 84 * This is a workaround for ic issue. So the peripherals are not shared 85 * by them. This way requires the uboot implemented the RDC driver and 86 * set the 26 IPs above to domain 0 only. M4 code will assign resource 87 * to its own domain, if it want to use the resource. 88 */ 89 static rdc_peri_cfg_t const resources[] = { 90 (RDC_PER_SIM1 | RDC_DOMAIN(0)), 91 (RDC_PER_SIM2 | RDC_DOMAIN(0)), 92 (RDC_PER_UART1 | RDC_DOMAIN(0)), 93 (RDC_PER_UART2 | RDC_DOMAIN(0)), 94 (RDC_PER_UART3 | RDC_DOMAIN(0)), 95 (RDC_PER_UART4 | RDC_DOMAIN(0)), 96 (RDC_PER_UART5 | RDC_DOMAIN(0)), 97 (RDC_PER_UART6 | RDC_DOMAIN(0)), 98 (RDC_PER_UART7 | RDC_DOMAIN(0)), 99 (RDC_PER_SAI1 | RDC_DOMAIN(0)), 100 (RDC_PER_SAI2 | RDC_DOMAIN(0)), 101 (RDC_PER_SAI3 | RDC_DOMAIN(0)), 102 (RDC_PER_WDOG1 | RDC_DOMAIN(0)), 103 (RDC_PER_WDOG2 | RDC_DOMAIN(0)), 104 (RDC_PER_WDOG3 | RDC_DOMAIN(0)), 105 (RDC_PER_WDOG4 | RDC_DOMAIN(0)), 106 (RDC_PER_GPT1 | RDC_DOMAIN(0)), 107 (RDC_PER_GPT2 | RDC_DOMAIN(0)), 108 (RDC_PER_GPT3 | RDC_DOMAIN(0)), 109 (RDC_PER_GPT4 | RDC_DOMAIN(0)), 110 (RDC_PER_PWM1 | RDC_DOMAIN(0)), 111 (RDC_PER_PWM2 | RDC_DOMAIN(0)), 112 (RDC_PER_PWM3 | RDC_DOMAIN(0)), 113 (RDC_PER_PWM4 | RDC_DOMAIN(0)), 114 (RDC_PER_ENET1 | RDC_DOMAIN(0)), 115 (RDC_PER_ENET2 | RDC_DOMAIN(0)), 116 }; 117 118 static void isolate_resource(void) 119 { 120 imx_rdc_setup_peripherals(resources, ARRAY_SIZE(resources)); 121 } 122 #endif 123 124 #if defined(CONFIG_SECURE_BOOT) 125 struct imx_sec_config_fuse_t const imx_sec_config_fuse = { 126 .bank = 1, 127 .word = 3, 128 }; 129 #endif 130 131 static bool is_mx7d(void) 132 { 133 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; 134 struct fuse_bank *bank = &ocotp->bank[1]; 135 struct fuse_bank1_regs *fuse = 136 (struct fuse_bank1_regs *)bank->fuse_regs; 137 int val; 138 139 val = readl(&fuse->tester4); 140 if (val & 1) 141 return false; 142 else 143 return true; 144 } 145 146 u32 get_cpu_rev(void) 147 { 148 struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) 149 ANATOP_BASE_ADDR; 150 u32 reg = readl(&ccm_anatop->digprog); 151 u32 type = (reg >> 16) & 0xff; 152 153 if (!is_mx7d()) 154 type = MXC_CPU_MX7S; 155 156 reg &= 0xff; 157 return (type << 12) | reg; 158 } 159 160 #ifdef CONFIG_REVISION_TAG 161 u32 __weak get_board_rev(void) 162 { 163 return get_cpu_rev(); 164 } 165 #endif 166 167 #ifndef CONFIG_SKIP_LOWLEVEL_INIT 168 /* enable all periherial can be accessed in nosec mode */ 169 static void init_csu(void) 170 { 171 int i = 0; 172 for (i = 0; i < CSU_NUM_REGS; i++) 173 writel(CSU_INIT_SEC_LEVEL0, CSU_IPS_BASE_ADDR + i * 4); 174 } 175 176 static void imx_enet_mdio_fixup(void) 177 { 178 struct iomuxc_gpr_base_regs *gpr_regs = 179 (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; 180 181 /* 182 * The management data input/output (MDIO) requires open-drain, 183 * i.MX7D TO1.0 ENET MDIO pin has no open drain, but TO1.1 supports 184 * this feature. So to TO1.1, need to enable open drain by setting 185 * bits GPR0[8:7]. 186 */ 187 188 if (soc_rev() >= CHIP_REV_1_1) { 189 setbits_le32(&gpr_regs->gpr[0], 190 IOMUXC_GPR_GPR0_ENET_MDIO_OPEN_DRAIN_MASK); 191 } 192 } 193 194 static void imx_gpcv2_init(void) 195 { 196 u32 val, i; 197 198 /* 199 * Force IOMUXC irq pending, so that the interrupt to GPC can be 200 * used to deassert dsm_request signal when the signal gets 201 * asserted unexpectedly. 202 */ 203 val = readl(IOMUXC_GPR_BASE_ADDR + IOMUXC_GPR1); 204 val |= BM_IOMUXC_GPR1_IRQ; 205 writel(val, IOMUXC_GPR_BASE_ADDR + IOMUXC_GPR1); 206 207 /* Initially mask all interrupts */ 208 for (i = 0; i < 4; i++) { 209 writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4); 210 writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE1 + i * 4); 211 writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_M4 + i * 4); 212 } 213 214 /* set SCU timing */ 215 writel((0x59 << 10) | 0x5B | (0x2 << 20), 216 GPC_IPS_BASE_ADDR + GPC_PGC_SCU_TIMING); 217 218 /* only external IRQs to wake up LPM and core 0/1 */ 219 val = readl(GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC); 220 val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP; 221 writel(val, GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC); 222 223 /* set C0 power up timming per design requirement */ 224 val = readl(GPC_IPS_BASE_ADDR + GPC_PGC_C0_PUPSCR); 225 val &= ~BM_GPC_PGC_CORE_PUPSCR; 226 val |= (0x1A << 7); 227 writel(val, GPC_IPS_BASE_ADDR + GPC_PGC_C0_PUPSCR); 228 229 /* set C1 power up timming per design requirement */ 230 val = readl(GPC_IPS_BASE_ADDR + GPC_PGC_C1_PUPSCR); 231 val &= ~BM_GPC_PGC_CORE_PUPSCR; 232 val |= (0x1A << 7); 233 writel(val, GPC_IPS_BASE_ADDR + GPC_PGC_C1_PUPSCR); 234 235 /* dummy ack for time slot by default */ 236 writel(BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK | 237 BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK, 238 GPC_IPS_BASE_ADDR + GPC_PGC_ACK_SEL_A7); 239 240 /* mask M4 DSM trigger */ 241 writel(readl(GPC_IPS_BASE_ADDR + GPC_LPCR_M4) | 242 BM_LPCR_M4_MASK_DSM_TRIGGER, 243 GPC_IPS_BASE_ADDR + GPC_LPCR_M4); 244 245 /* set mega/fast mix in A7 domain */ 246 writel(0x1, GPC_IPS_BASE_ADDR + GPC_PGC_CPU_MAPPING); 247 248 /* DSM related settings */ 249 val = readl(GPC_IPS_BASE_ADDR + GPC_SLPCR); 250 val &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN | 251 BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY | 252 BM_SLPCR_REG_BYPASS_COUNT); 253 val |= BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE; 254 writel(val, GPC_IPS_BASE_ADDR + GPC_SLPCR); 255 256 /* 257 * disabling RBC need to delay at least 2 cycles of CKIL(32K) 258 * due to hardware design requirement, which is 259 * ~61us, here we use 65us for safe 260 */ 261 udelay(65); 262 } 263 264 int arch_cpu_init(void) 265 { 266 init_aips(); 267 268 init_csu(); 269 /* Disable PDE bit of WMCR register */ 270 imx_wdog_disable_powerdown(); 271 272 imx_enet_mdio_fixup(); 273 274 #ifdef CONFIG_APBH_DMA 275 /* Start APBH DMA */ 276 mxs_dma_init(); 277 #endif 278 279 #if CONFIG_IS_ENABLED(IMX_RDC) 280 isolate_resource(); 281 #endif 282 283 init_snvs(); 284 285 imx_gpcv2_init(); 286 287 return 0; 288 } 289 #endif 290 291 #ifdef CONFIG_ARCH_MISC_INIT 292 int arch_misc_init(void) 293 { 294 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 295 if (is_mx7d()) 296 env_set("soc", "imx7d"); 297 else 298 env_set("soc", "imx7s"); 299 #endif 300 301 #ifdef CONFIG_FSL_CAAM 302 sec_init(); 303 #endif 304 305 return 0; 306 } 307 #endif 308 309 #ifdef CONFIG_SERIAL_TAG 310 /* 311 * OCOTP_TESTER 312 * i.MX 7Solo Applications Processor Reference Manual, Rev. 0.1, 08/2016 313 * OCOTP_TESTER describes a unique ID based on silicon wafer 314 * and die X/Y position 315 * 316 * OCOTOP_TESTER offset 0x410 317 * 31:0 fuse 0 318 * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID 319 * 320 * OCOTP_TESTER1 offset 0x420 321 * 31:24 fuse 1 322 * The X-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID 323 * 23:16 fuse 1 324 * The Y-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID 325 * 15:11 fuse 1 326 * The wafer number of the wafer on which the device was fabricated/SJC 327 * CHALLENGE/ Unique ID 328 * 10:0 fuse 1 329 * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID 330 */ 331 void get_board_serial(struct tag_serialnr *serialnr) 332 { 333 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; 334 struct fuse_bank *bank = &ocotp->bank[0]; 335 struct fuse_bank0_regs *fuse = 336 (struct fuse_bank0_regs *)bank->fuse_regs; 337 338 serialnr->low = fuse->tester0; 339 serialnr->high = fuse->tester1; 340 } 341 #endif 342 343 void set_wdog_reset(struct wdog_regs *wdog) 344 { 345 u32 reg = readw(&wdog->wcr); 346 /* 347 * Output WDOG_B signal to reset external pmic or POR_B decided by 348 * the board desgin. Without external reset, the peripherals/DDR/ 349 * PMIC are not reset, that may cause system working abnormal. 350 */ 351 reg = readw(&wdog->wcr); 352 reg |= 1 << 3; 353 /* 354 * WDZST bit is write-once only bit. Align this bit in kernel, 355 * otherwise kernel code will have no chance to set this bit. 356 */ 357 reg |= 1 << 0; 358 writew(reg, &wdog->wcr); 359 } 360 361 void s_init(void) 362 { 363 /* clock configuration. */ 364 clock_init(); 365 366 return; 367 } 368 369 void reset_misc(void) 370 { 371 #ifndef CONFIG_SPL_BUILD 372 #ifdef CONFIG_VIDEO_MXS 373 lcdif_power_down(); 374 #endif 375 #endif 376 } 377 378