1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2007 4 * Sascha Hauer, Pengutronix 5 * 6 * (C) Copyright 2009 Freescale Semiconductor, Inc. 7 */ 8 9 #include <bootm.h> 10 #include <common.h> 11 #include <netdev.h> 12 #include <linux/errno.h> 13 #include <asm/io.h> 14 #include <asm/arch/imx-regs.h> 15 #include <asm/arch/clock.h> 16 #include <asm/arch/sys_proto.h> 17 #include <asm/arch/crm_regs.h> 18 #include <asm/mach-imx/boot_mode.h> 19 #include <imx_thermal.h> 20 #include <ipu_pixfmt.h> 21 #include <thermal.h> 22 #include <sata.h> 23 24 #ifdef CONFIG_FSL_ESDHC 25 #include <fsl_esdhc.h> 26 #endif 27 28 static u32 reset_cause = -1; 29 30 u32 get_imx_reset_cause(void) 31 { 32 struct src *src_regs = (struct src *)SRC_BASE_ADDR; 33 34 if (reset_cause == -1) { 35 reset_cause = readl(&src_regs->srsr); 36 /* preserve the value for U-Boot proper */ 37 #if !defined(CONFIG_SPL_BUILD) 38 writel(reset_cause, &src_regs->srsr); 39 #endif 40 } 41 42 return reset_cause; 43 } 44 45 #if defined(CONFIG_DISPLAY_CPUINFO) && !defined(CONFIG_SPL_BUILD) 46 static char *get_reset_cause(void) 47 { 48 switch (get_imx_reset_cause()) { 49 case 0x00001: 50 case 0x00011: 51 return "POR"; 52 case 0x00004: 53 return "CSU"; 54 case 0x00008: 55 return "IPP USER"; 56 case 0x00010: 57 #ifdef CONFIG_MX7 58 return "WDOG1"; 59 #else 60 return "WDOG"; 61 #endif 62 case 0x00020: 63 return "JTAG HIGH-Z"; 64 case 0x00040: 65 return "JTAG SW"; 66 case 0x00080: 67 return "WDOG3"; 68 #ifdef CONFIG_MX7 69 case 0x00100: 70 return "WDOG4"; 71 case 0x00200: 72 return "TEMPSENSE"; 73 #elif defined(CONFIG_IMX8M) 74 case 0x00100: 75 return "WDOG2"; 76 case 0x00200: 77 return "TEMPSENSE"; 78 #else 79 case 0x00100: 80 return "TEMPSENSE"; 81 case 0x10000: 82 return "WARM BOOT"; 83 #endif 84 default: 85 return "unknown reset"; 86 } 87 } 88 #endif 89 90 #if defined(CONFIG_MX53) || defined(CONFIG_MX6) 91 #if defined(CONFIG_MX53) 92 #define MEMCTL_BASE ESDCTL_BASE_ADDR 93 #else 94 #define MEMCTL_BASE MMDC_P0_BASE_ADDR 95 #endif 96 static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9}; 97 static const unsigned char bank_lookup[] = {3, 2}; 98 99 /* these MMDC registers are common to the IMX53 and IMX6 */ 100 struct esd_mmdc_regs { 101 uint32_t ctl; 102 uint32_t pdc; 103 uint32_t otc; 104 uint32_t cfg0; 105 uint32_t cfg1; 106 uint32_t cfg2; 107 uint32_t misc; 108 }; 109 110 #define ESD_MMDC_CTL_GET_ROW(mdctl) ((ctl >> 24) & 7) 111 #define ESD_MMDC_CTL_GET_COLUMN(mdctl) ((ctl >> 20) & 7) 112 #define ESD_MMDC_CTL_GET_WIDTH(mdctl) ((ctl >> 16) & 3) 113 #define ESD_MMDC_CTL_GET_CS1(mdctl) ((ctl >> 30) & 1) 114 #define ESD_MMDC_MISC_GET_BANK(mdmisc) ((misc >> 5) & 1) 115 116 /* 117 * imx_ddr_size - return size in bytes of DRAM according MMDC config 118 * The MMDC MDCTL register holds the number of bits for row, col, and data 119 * width and the MMDC MDMISC register holds the number of banks. Combine 120 * all these bits to determine the meme size the MMDC has been configured for 121 */ 122 unsigned imx_ddr_size(void) 123 { 124 struct esd_mmdc_regs *mem = (struct esd_mmdc_regs *)MEMCTL_BASE; 125 unsigned ctl = readl(&mem->ctl); 126 unsigned misc = readl(&mem->misc); 127 int bits = 11 + 0 + 0 + 1; /* row + col + bank + width */ 128 129 bits += ESD_MMDC_CTL_GET_ROW(ctl); 130 bits += col_lookup[ESD_MMDC_CTL_GET_COLUMN(ctl)]; 131 bits += bank_lookup[ESD_MMDC_MISC_GET_BANK(misc)]; 132 bits += ESD_MMDC_CTL_GET_WIDTH(ctl); 133 bits += ESD_MMDC_CTL_GET_CS1(ctl); 134 135 /* The MX6 can do only 3840 MiB of DRAM */ 136 if (bits == 32) 137 return 0xf0000000; 138 139 return 1 << bits; 140 } 141 #endif 142 143 #if defined(CONFIG_DISPLAY_CPUINFO) && !defined(CONFIG_SPL_BUILD) 144 145 const char *get_imx_type(u32 imxtype) 146 { 147 switch (imxtype) { 148 case MXC_CPU_IMX8MQ: 149 return "8MQ"; /* Quad-core version of the imx8m */ 150 case MXC_CPU_MX7S: 151 return "7S"; /* Single-core version of the mx7 */ 152 case MXC_CPU_MX7D: 153 return "7D"; /* Dual-core version of the mx7 */ 154 case MXC_CPU_MX6QP: 155 return "6QP"; /* Quad-Plus version of the mx6 */ 156 case MXC_CPU_MX6DP: 157 return "6DP"; /* Dual-Plus version of the mx6 */ 158 case MXC_CPU_MX6Q: 159 return "6Q"; /* Quad-core version of the mx6 */ 160 case MXC_CPU_MX6D: 161 return "6D"; /* Dual-core version of the mx6 */ 162 case MXC_CPU_MX6DL: 163 return "6DL"; /* Dual Lite version of the mx6 */ 164 case MXC_CPU_MX6SOLO: 165 return "6SOLO"; /* Solo version of the mx6 */ 166 case MXC_CPU_MX6SL: 167 return "6SL"; /* Solo-Lite version of the mx6 */ 168 case MXC_CPU_MX6SLL: 169 return "6SLL"; /* SLL version of the mx6 */ 170 case MXC_CPU_MX6SX: 171 return "6SX"; /* SoloX version of the mx6 */ 172 case MXC_CPU_MX6UL: 173 return "6UL"; /* Ultra-Lite version of the mx6 */ 174 case MXC_CPU_MX6ULL: 175 return "6ULL"; /* ULL version of the mx6 */ 176 case MXC_CPU_MX51: 177 return "51"; 178 case MXC_CPU_MX53: 179 return "53"; 180 default: 181 return "??"; 182 } 183 } 184 185 int print_cpuinfo(void) 186 { 187 u32 cpurev; 188 __maybe_unused u32 max_freq; 189 190 cpurev = get_cpu_rev(); 191 192 #if defined(CONFIG_IMX_THERMAL) 193 struct udevice *thermal_dev; 194 int cpu_tmp, minc, maxc, ret; 195 196 printf("CPU: Freescale i.MX%s rev%d.%d", 197 get_imx_type((cpurev & 0xFF000) >> 12), 198 (cpurev & 0x000F0) >> 4, 199 (cpurev & 0x0000F) >> 0); 200 max_freq = get_cpu_speed_grade_hz(); 201 if (!max_freq || max_freq == mxc_get_clock(MXC_ARM_CLK)) { 202 printf(" at %dMHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000); 203 } else { 204 printf(" %d MHz (running at %d MHz)\n", max_freq / 1000000, 205 mxc_get_clock(MXC_ARM_CLK) / 1000000); 206 } 207 #else 208 printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n", 209 get_imx_type((cpurev & 0xFF000) >> 12), 210 (cpurev & 0x000F0) >> 4, 211 (cpurev & 0x0000F) >> 0, 212 mxc_get_clock(MXC_ARM_CLK) / 1000000); 213 #endif 214 215 #if defined(CONFIG_IMX_THERMAL) 216 puts("CPU: "); 217 switch (get_cpu_temp_grade(&minc, &maxc)) { 218 case TEMP_AUTOMOTIVE: 219 puts("Automotive temperature grade "); 220 break; 221 case TEMP_INDUSTRIAL: 222 puts("Industrial temperature grade "); 223 break; 224 case TEMP_EXTCOMMERCIAL: 225 puts("Extended Commercial temperature grade "); 226 break; 227 default: 228 puts("Commercial temperature grade "); 229 break; 230 } 231 printf("(%dC to %dC)", minc, maxc); 232 ret = uclass_get_device(UCLASS_THERMAL, 0, &thermal_dev); 233 if (!ret) { 234 ret = thermal_get_temp(thermal_dev, &cpu_tmp); 235 236 if (!ret) 237 printf(" at %dC\n", cpu_tmp); 238 else 239 debug(" - invalid sensor data\n"); 240 } else { 241 debug(" - invalid sensor device\n"); 242 } 243 #endif 244 245 printf("Reset cause: %s\n", get_reset_cause()); 246 return 0; 247 } 248 #endif 249 250 int cpu_eth_init(bd_t *bis) 251 { 252 int rc = -ENODEV; 253 254 #if defined(CONFIG_FEC_MXC) 255 rc = fecmxc_initialize(bis); 256 #endif 257 258 return rc; 259 } 260 261 #ifdef CONFIG_FSL_ESDHC 262 /* 263 * Initializes on-chip MMC controllers. 264 * to override, implement board_mmc_init() 265 */ 266 int cpu_mmc_init(bd_t *bis) 267 { 268 return fsl_esdhc_mmc_init(bis); 269 } 270 #endif 271 272 #if !(defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) 273 u32 get_ahb_clk(void) 274 { 275 struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 276 u32 reg, ahb_podf; 277 278 reg = __raw_readl(&imx_ccm->cbcdr); 279 reg &= MXC_CCM_CBCDR_AHB_PODF_MASK; 280 ahb_podf = reg >> MXC_CCM_CBCDR_AHB_PODF_OFFSET; 281 282 return get_periph_clk() / (ahb_podf + 1); 283 } 284 #endif 285 286 void arch_preboot_os(void) 287 { 288 #if defined(CONFIG_PCIE_IMX) 289 imx_pcie_remove(); 290 #endif 291 #if defined(CONFIG_SATA) 292 sata_remove(0); 293 #if defined(CONFIG_MX6) 294 disable_sata_clock(); 295 #endif 296 #endif 297 #if defined(CONFIG_VIDEO_IPUV3) 298 /* disable video before launching O/S */ 299 ipuv3_fb_shutdown(); 300 #endif 301 #if defined(CONFIG_VIDEO_MXS) 302 lcdif_power_down(); 303 #endif 304 } 305 306 #ifndef CONFIG_IMX8M 307 void set_chipselect_size(int const cs_size) 308 { 309 unsigned int reg; 310 struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; 311 reg = readl(&iomuxc_regs->gpr[1]); 312 313 switch (cs_size) { 314 case CS0_128: 315 reg &= ~0x7; /* CS0=128MB, CS1=0, CS2=0, CS3=0 */ 316 reg |= 0x5; 317 break; 318 case CS0_64M_CS1_64M: 319 reg &= ~0x3F; /* CS0=64MB, CS1=64MB, CS2=0, CS3=0 */ 320 reg |= 0x1B; 321 break; 322 case CS0_64M_CS1_32M_CS2_32M: 323 reg &= ~0x1FF; /* CS0=64MB, CS1=32MB, CS2=32MB, CS3=0 */ 324 reg |= 0x4B; 325 break; 326 case CS0_32M_CS1_32M_CS2_32M_CS3_32M: 327 reg &= ~0xFFF; /* CS0=32MB, CS1=32MB, CS2=32MB, CS3=32MB */ 328 reg |= 0x249; 329 break; 330 default: 331 printf("Unknown chip select size: %d\n", cs_size); 332 break; 333 } 334 335 writel(reg, &iomuxc_regs->gpr[1]); 336 } 337 #endif 338 339 #if defined(CONFIG_MX7) || defined(CONFIG_IMX8M) 340 /* 341 * OCOTP_TESTER3[9:8] (see Fusemap Description Table offset 0x440) 342 * defines a 2-bit SPEED_GRADING 343 */ 344 #define OCOTP_TESTER3_SPEED_SHIFT 8 345 enum cpu_speed { 346 OCOTP_TESTER3_SPEED_GRADE0, 347 OCOTP_TESTER3_SPEED_GRADE1, 348 OCOTP_TESTER3_SPEED_GRADE2, 349 OCOTP_TESTER3_SPEED_GRADE3, 350 }; 351 352 u32 get_cpu_speed_grade_hz(void) 353 { 354 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; 355 struct fuse_bank *bank = &ocotp->bank[1]; 356 struct fuse_bank1_regs *fuse = 357 (struct fuse_bank1_regs *)bank->fuse_regs; 358 uint32_t val; 359 360 val = readl(&fuse->tester3); 361 val >>= OCOTP_TESTER3_SPEED_SHIFT; 362 val &= 0x3; 363 364 switch(val) { 365 case OCOTP_TESTER3_SPEED_GRADE0: 366 return 800000000; 367 case OCOTP_TESTER3_SPEED_GRADE1: 368 return is_mx7() ? 500000000 : 1000000000; 369 case OCOTP_TESTER3_SPEED_GRADE2: 370 return is_mx7() ? 1000000000 : 1300000000; 371 case OCOTP_TESTER3_SPEED_GRADE3: 372 return is_mx7() ? 1200000000 : 1500000000; 373 } 374 375 return 0; 376 } 377 378 /* 379 * OCOTP_TESTER3[7:6] (see Fusemap Description Table offset 0x440) 380 * defines a 2-bit SPEED_GRADING 381 */ 382 #define OCOTP_TESTER3_TEMP_SHIFT 6 383 384 u32 get_cpu_temp_grade(int *minc, int *maxc) 385 { 386 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; 387 struct fuse_bank *bank = &ocotp->bank[1]; 388 struct fuse_bank1_regs *fuse = 389 (struct fuse_bank1_regs *)bank->fuse_regs; 390 uint32_t val; 391 392 val = readl(&fuse->tester3); 393 val >>= OCOTP_TESTER3_TEMP_SHIFT; 394 val &= 0x3; 395 396 if (minc && maxc) { 397 if (val == TEMP_AUTOMOTIVE) { 398 *minc = -40; 399 *maxc = 125; 400 } else if (val == TEMP_INDUSTRIAL) { 401 *minc = -40; 402 *maxc = 105; 403 } else if (val == TEMP_EXTCOMMERCIAL) { 404 *minc = -20; 405 *maxc = 105; 406 } else { 407 *minc = 0; 408 *maxc = 95; 409 } 410 } 411 return val; 412 } 413 #endif 414 415 #if defined(CONFIG_MX7) || defined(CONFIG_IMX8M) 416 enum boot_device get_boot_device(void) 417 { 418 struct bootrom_sw_info **p = 419 (struct bootrom_sw_info **)(ulong)ROM_SW_INFO_ADDR; 420 421 enum boot_device boot_dev = SD1_BOOT; 422 u8 boot_type = (*p)->boot_dev_type; 423 u8 boot_instance = (*p)->boot_dev_instance; 424 425 switch (boot_type) { 426 case BOOT_TYPE_SD: 427 boot_dev = boot_instance + SD1_BOOT; 428 break; 429 case BOOT_TYPE_MMC: 430 boot_dev = boot_instance + MMC1_BOOT; 431 break; 432 case BOOT_TYPE_NAND: 433 boot_dev = NAND_BOOT; 434 break; 435 case BOOT_TYPE_QSPI: 436 boot_dev = QSPI_BOOT; 437 break; 438 case BOOT_TYPE_WEIM: 439 boot_dev = WEIM_NOR_BOOT; 440 break; 441 case BOOT_TYPE_SPINOR: 442 boot_dev = SPI_NOR_BOOT; 443 break; 444 #ifdef CONFIG_IMX8M 445 case BOOT_TYPE_USB: 446 boot_dev = USB_BOOT; 447 break; 448 #endif 449 default: 450 break; 451 } 452 453 return boot_dev; 454 } 455 #endif 456 457 #ifdef CONFIG_NXP_BOARD_REVISION 458 int nxp_board_rev(void) 459 { 460 /* 461 * Get Board ID information from OCOTP_GP1[15:8] 462 * RevA: 0x1 463 * RevB: 0x2 464 * RevC: 0x3 465 */ 466 struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; 467 struct fuse_bank *bank = &ocotp->bank[4]; 468 struct fuse_bank4_regs *fuse = 469 (struct fuse_bank4_regs *)bank->fuse_regs; 470 471 return (readl(&fuse->gp1) >> 8 & 0x0F); 472 } 473 474 char nxp_board_rev_string(void) 475 { 476 const char *rev = "A"; 477 478 return (*rev + nxp_board_rev() - 1); 479 } 480 #endif 481