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 /* enable all periherial can be accessed in nosec mode */ 168 static void init_csu(void) 169 { 170 int i = 0; 171 for (i = 0; i < CSU_NUM_REGS; i++) 172 writel(CSU_INIT_SEC_LEVEL0, CSU_IPS_BASE_ADDR + i * 4); 173 } 174 175 static void imx_enet_mdio_fixup(void) 176 { 177 struct iomuxc_gpr_base_regs *gpr_regs = 178 (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; 179 180 /* 181 * The management data input/output (MDIO) requires open-drain, 182 * i.MX7D TO1.0 ENET MDIO pin has no open drain, but TO1.1 supports 183 * this feature. So to TO1.1, need to enable open drain by setting 184 * bits GPR0[8:7]. 185 */ 186 187 if (soc_rev() >= CHIP_REV_1_1) { 188 setbits_le32(&gpr_regs->gpr[0], 189 IOMUXC_GPR_GPR0_ENET_MDIO_OPEN_DRAIN_MASK); 190 } 191 } 192 193 static void imx_gpcv2_init(void) 194 { 195 u32 val, i; 196 197 /* 198 * Force IOMUXC irq pending, so that the interrupt to GPC can be 199 * used to deassert dsm_request signal when the signal gets 200 * asserted unexpectedly. 201 */ 202 val = readl(IOMUXC_GPR_BASE_ADDR + IOMUXC_GPR1); 203 val |= BM_IOMUXC_GPR1_IRQ; 204 writel(val, IOMUXC_GPR_BASE_ADDR + IOMUXC_GPR1); 205 206 /* Initially mask all interrupts */ 207 for (i = 0; i < 4; i++) { 208 writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4); 209 writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE1 + i * 4); 210 writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_M4 + i * 4); 211 } 212 213 /* set SCU timing */ 214 writel((0x59 << 10) | 0x5B | (0x2 << 20), 215 GPC_IPS_BASE_ADDR + GPC_PGC_SCU_TIMING); 216 217 /* only external IRQs to wake up LPM and core 0/1 */ 218 val = readl(GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC); 219 val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP; 220 writel(val, GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC); 221 222 /* set C0 power up timming per design requirement */ 223 val = readl(GPC_IPS_BASE_ADDR + GPC_PGC_C0_PUPSCR); 224 val &= ~BM_GPC_PGC_CORE_PUPSCR; 225 val |= (0x1A << 7); 226 writel(val, GPC_IPS_BASE_ADDR + GPC_PGC_C0_PUPSCR); 227 228 /* set C1 power up timming per design requirement */ 229 val = readl(GPC_IPS_BASE_ADDR + GPC_PGC_C1_PUPSCR); 230 val &= ~BM_GPC_PGC_CORE_PUPSCR; 231 val |= (0x1A << 7); 232 writel(val, GPC_IPS_BASE_ADDR + GPC_PGC_C1_PUPSCR); 233 234 /* dummy ack for time slot by default */ 235 writel(BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK | 236 BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK, 237 GPC_IPS_BASE_ADDR + GPC_PGC_ACK_SEL_A7); 238 239 /* mask M4 DSM trigger */ 240 writel(readl(GPC_IPS_BASE_ADDR + GPC_LPCR_M4) | 241 BM_LPCR_M4_MASK_DSM_TRIGGER, 242 GPC_IPS_BASE_ADDR + GPC_LPCR_M4); 243 244 /* set mega/fast mix in A7 domain */ 245 writel(0x1, GPC_IPS_BASE_ADDR + GPC_PGC_CPU_MAPPING); 246 247 /* DSM related settings */ 248 val = readl(GPC_IPS_BASE_ADDR + GPC_SLPCR); 249 val &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN | 250 BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY | 251 BM_SLPCR_REG_BYPASS_COUNT); 252 val |= BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE; 253 writel(val, GPC_IPS_BASE_ADDR + GPC_SLPCR); 254 255 /* 256 * disabling RBC need to delay at least 2 cycles of CKIL(32K) 257 * due to hardware design requirement, which is 258 * ~61us, here we use 65us for safe 259 */ 260 udelay(65); 261 } 262 263 int arch_cpu_init(void) 264 { 265 init_aips(); 266 267 init_csu(); 268 /* Disable PDE bit of WMCR register */ 269 imx_wdog_disable_powerdown(); 270 271 imx_enet_mdio_fixup(); 272 273 #ifdef CONFIG_APBH_DMA 274 /* Start APBH DMA */ 275 mxs_dma_init(); 276 #endif 277 278 #if CONFIG_IS_ENABLED(IMX_RDC) 279 isolate_resource(); 280 #endif 281 282 init_snvs(); 283 284 imx_gpcv2_init(); 285 286 return 0; 287 } 288 289 #ifdef CONFIG_ARCH_MISC_INIT 290 int arch_misc_init(void) 291 { 292 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 293 if (is_mx7d()) 294 env_set("soc", "imx7d"); 295 else 296 env_set("soc", "imx7s"); 297 #endif 298 299 #ifdef CONFIG_FSL_CAAM 300 sec_init(); 301 #endif 302 303 return 0; 304 } 305 #endif 306 307 #ifdef CONFIG_SERIAL_TAG 308 /* 309 * OCOTP_TESTER 310 * i.MX 7Solo Applications Processor Reference Manual, Rev. 0.1, 08/2016 311 * OCOTP_TESTER describes a unique ID based on silicon wafer 312 * and die X/Y position 313 * 314 * OCOTOP_TESTER offset 0x410 315 * 31:0 fuse 0 316 * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID 317 * 318 * OCOTP_TESTER1 offset 0x420 319 * 31:24 fuse 1 320 * The X-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID 321 * 23:16 fuse 1 322 * The Y-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID 323 * 15:11 fuse 1 324 * The wafer number of the wafer on which the device was fabricated/SJC 325 * CHALLENGE/ Unique ID 326 * 10:0 fuse 1 327 * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID 328 */ 329 void get_board_serial(struct tag_serialnr *serialnr) 330 { 331 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; 332 struct fuse_bank *bank = &ocotp->bank[0]; 333 struct fuse_bank0_regs *fuse = 334 (struct fuse_bank0_regs *)bank->fuse_regs; 335 336 serialnr->low = fuse->tester0; 337 serialnr->high = fuse->tester1; 338 } 339 #endif 340 341 void set_wdog_reset(struct wdog_regs *wdog) 342 { 343 u32 reg = readw(&wdog->wcr); 344 /* 345 * Output WDOG_B signal to reset external pmic or POR_B decided by 346 * the board desgin. Without external reset, the peripherals/DDR/ 347 * PMIC are not reset, that may cause system working abnormal. 348 */ 349 reg = readw(&wdog->wcr); 350 reg |= 1 << 3; 351 /* 352 * WDZST bit is write-once only bit. Align this bit in kernel, 353 * otherwise kernel code will have no chance to set this bit. 354 */ 355 reg |= 1 << 0; 356 writew(reg, &wdog->wcr); 357 } 358 359 void s_init(void) 360 { 361 /* clock configuration. */ 362 clock_init(); 363 364 return; 365 } 366 367 void reset_misc(void) 368 { 369 #ifdef CONFIG_VIDEO_MXS 370 lcdif_power_down(); 371 #endif 372 } 373 374