1 /* 2 * (C) Copyright 2013 SAMSUNG Electronics 3 * Rajeshwari Shinde <rajeshwari.s@samsung.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <cros_ec.h> 10 #include <errno.h> 11 #include <fdtdec.h> 12 #include <spi.h> 13 #include <tmu.h> 14 #include <netdev.h> 15 #include <asm/io.h> 16 #include <asm/arch/board.h> 17 #include <asm/arch/cpu.h> 18 #include <asm/arch/dwmmc.h> 19 #include <asm/arch/gpio.h> 20 #include <asm/arch/mmc.h> 21 #include <asm/arch/pinmux.h> 22 #include <asm/arch/power.h> 23 #include <asm/arch/system.h> 24 #include <power/pmic.h> 25 #include <asm/arch/sromc.h> 26 #include <lcd.h> 27 #include <samsung/misc.h> 28 29 DECLARE_GLOBAL_DATA_PTR; 30 31 int __exynos_early_init_f(void) 32 { 33 return 0; 34 } 35 int exynos_early_init_f(void) 36 __attribute__((weak, alias("__exynos_early_init_f"))); 37 38 int __exynos_power_init(void) 39 { 40 return 0; 41 } 42 int exynos_power_init(void) 43 __attribute__((weak, alias("__exynos_power_init"))); 44 45 #if defined CONFIG_EXYNOS_TMU 46 /* Boot Time Thermal Analysis for SoC temperature threshold breach */ 47 static void boot_temp_check(void) 48 { 49 int temp; 50 51 switch (tmu_monitor(&temp)) { 52 case TMU_STATUS_NORMAL: 53 break; 54 case TMU_STATUS_TRIPPED: 55 /* 56 * Status TRIPPED ans WARNING means corresponding threshold 57 * breach 58 */ 59 puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n"); 60 set_ps_hold_ctrl(); 61 hang(); 62 break; 63 case TMU_STATUS_WARNING: 64 puts("EXYNOS_TMU: WARNING! Temperature very high\n"); 65 break; 66 case TMU_STATUS_INIT: 67 /* 68 * TMU_STATUS_INIT means something is wrong with temperature 69 * sensing and TMU status was changed back from NORMAL to INIT. 70 */ 71 puts("EXYNOS_TMU: WARNING! Temperature sensing not done\n"); 72 break; 73 default: 74 debug("EXYNOS_TMU: Unknown TMU state\n"); 75 } 76 } 77 #endif 78 79 int board_init(void) 80 { 81 gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); 82 #if defined CONFIG_EXYNOS_TMU 83 if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) { 84 debug("%s: Failed to init TMU\n", __func__); 85 return -1; 86 } 87 boot_temp_check(); 88 #endif 89 90 #ifdef CONFIG_EXYNOS_SPI 91 spi_init(); 92 #endif 93 return exynos_init(); 94 } 95 96 int dram_init(void) 97 { 98 int i; 99 u32 addr; 100 101 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 102 addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE); 103 gd->ram_size += get_ram_size((long *)addr, SDRAM_BANK_SIZE); 104 } 105 return 0; 106 } 107 108 void dram_init_banksize(void) 109 { 110 int i; 111 u32 addr, size; 112 113 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 114 addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE); 115 size = get_ram_size((long *)addr, SDRAM_BANK_SIZE); 116 117 gd->bd->bi_dram[i].start = addr; 118 gd->bd->bi_dram[i].size = size; 119 } 120 } 121 122 static int board_uart_init(void) 123 { 124 int err, uart_id, ret = 0; 125 126 for (uart_id = PERIPH_ID_UART0; uart_id <= PERIPH_ID_UART3; uart_id++) { 127 err = exynos_pinmux_config(uart_id, PINMUX_FLAG_NONE); 128 if (err) { 129 debug("UART%d not configured\n", 130 (uart_id - PERIPH_ID_UART0)); 131 ret |= err; 132 } 133 } 134 return ret; 135 } 136 137 #ifdef CONFIG_BOARD_EARLY_INIT_F 138 int board_early_init_f(void) 139 { 140 int err; 141 #ifdef CONFIG_BOARD_TYPES 142 set_board_type(); 143 #endif 144 err = board_uart_init(); 145 if (err) { 146 debug("UART init failed\n"); 147 return err; 148 } 149 150 #ifdef CONFIG_SYS_I2C_INIT_BOARD 151 board_i2c_init(gd->fdt_blob); 152 #endif 153 154 #if defined(CONFIG_OF_CONTROL) && defined(CONFIG_EXYNOS_FB) 155 /* 156 * board_init_f(arch/arm/lib/board.c) calls lcd_setmem() which needs 157 * panel_info.vl_col, panel_info.vl_row and panel_info.vl_bpix, to reserve 158 * FB memory at a very early stage. So, we need to fill panel_info.vl_col, 159 * panel_info.vl_row and panel_info.vl_bpix before lcd_setmem() is called. 160 */ 161 err = exynos_lcd_early_init(gd->fdt_blob); 162 if (err) { 163 debug("LCD early init failed\n"); 164 return err; 165 } 166 #endif 167 168 return exynos_early_init_f(); 169 } 170 #endif 171 172 #if defined(CONFIG_POWER) 173 int power_init_board(void) 174 { 175 set_ps_hold_ctrl(); 176 177 return exynos_power_init(); 178 } 179 #endif 180 181 #ifdef CONFIG_OF_CONTROL 182 #ifdef CONFIG_SMC911X 183 static int decode_sromc(const void *blob, struct fdt_sromc *config) 184 { 185 int err; 186 int node; 187 188 node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC); 189 if (node < 0) { 190 debug("Could not find SROMC node\n"); 191 return node; 192 } 193 194 config->bank = fdtdec_get_int(blob, node, "bank", 0); 195 config->width = fdtdec_get_int(blob, node, "width", 2); 196 197 err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing, 198 FDT_SROM_TIMING_COUNT); 199 if (err < 0) { 200 debug("Could not decode SROMC configuration Error: %s\n", 201 fdt_strerror(err)); 202 return -FDT_ERR_NOTFOUND; 203 } 204 return 0; 205 } 206 #endif 207 208 int board_eth_init(bd_t *bis) 209 { 210 #ifdef CONFIG_SMC911X 211 u32 smc_bw_conf, smc_bc_conf; 212 struct fdt_sromc config; 213 fdt_addr_t base_addr; 214 int node; 215 216 node = decode_sromc(gd->fdt_blob, &config); 217 if (node < 0) { 218 debug("%s: Could not find sromc configuration\n", __func__); 219 return 0; 220 } 221 node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215); 222 if (node < 0) { 223 debug("%s: Could not find lan9215 configuration\n", __func__); 224 return 0; 225 } 226 227 /* We now have a node, so any problems from now on are errors */ 228 base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg"); 229 if (base_addr == FDT_ADDR_T_NONE) { 230 debug("%s: Could not find lan9215 address\n", __func__); 231 return -1; 232 } 233 234 /* Ethernet needs data bus width of 16 bits */ 235 if (config.width != 2) { 236 debug("%s: Unsupported bus width %d\n", __func__, 237 config.width); 238 return -1; 239 } 240 smc_bw_conf = SROMC_DATA16_WIDTH(config.bank) 241 | SROMC_BYTE_ENABLE(config.bank); 242 243 smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) | 244 SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) | 245 SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) | 246 SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) | 247 SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) | 248 SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) | 249 SROMC_BC_PMC(config.timing[FDT_SROM_PMC]); 250 251 /* Select and configure the SROMC bank */ 252 exynos_pinmux_config(PERIPH_ID_SROMC, config.bank); 253 s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf); 254 return smc911x_initialize(0, base_addr); 255 #endif 256 return 0; 257 } 258 259 #ifdef CONFIG_GENERIC_MMC 260 static int init_mmc(void) 261 { 262 #ifdef CONFIG_SDHCI 263 return exynos_mmc_init(gd->fdt_blob); 264 #else 265 return 0; 266 #endif 267 } 268 269 static int init_dwmmc(void) 270 { 271 #ifdef CONFIG_DWMMC 272 return exynos_dwmmc_init(gd->fdt_blob); 273 #else 274 return 0; 275 #endif 276 } 277 278 int board_mmc_init(bd_t *bis) 279 { 280 int ret; 281 282 if (get_boot_mode() == BOOT_MODE_SD) { 283 ret = init_mmc(); 284 ret |= init_dwmmc(); 285 } else { 286 ret = init_dwmmc(); 287 ret |= init_mmc(); 288 } 289 290 if (ret) 291 debug("mmc init failed\n"); 292 293 return ret; 294 } 295 #endif 296 297 #ifdef CONFIG_DISPLAY_BOARDINFO 298 int checkboard(void) 299 { 300 const char *board_info; 301 302 board_info = fdt_getprop(gd->fdt_blob, 0, "model", NULL); 303 printf("Board: %s\n", board_info ? board_info : "unknown"); 304 #ifdef CONFIG_BOARD_TYPES 305 board_info = get_board_type(); 306 307 printf("Model: %s\n", board_info ? board_info : "unknown"); 308 #endif 309 return 0; 310 } 311 #endif 312 #endif /* CONFIG_OF_CONTROL */ 313 314 #ifdef CONFIG_BOARD_LATE_INIT 315 int board_late_init(void) 316 { 317 stdio_print_current_devices(); 318 319 if (cros_ec_get_error()) { 320 /* Force console on */ 321 gd->flags &= ~GD_FLG_SILENT; 322 323 printf("cros-ec communications failure %d\n", 324 cros_ec_get_error()); 325 puts("\nPlease reset with Power+Refresh\n\n"); 326 panic("Cannot init cros-ec device"); 327 return -1; 328 } 329 return 0; 330 } 331 #endif 332 333 int arch_early_init_r(void) 334 { 335 #ifdef CONFIG_CROS_EC 336 if (cros_ec_board_init()) { 337 printf("%s: Failed to init EC\n", __func__); 338 return 0; 339 } 340 #endif 341 342 return 0; 343 } 344 345 #ifdef CONFIG_MISC_INIT_R 346 int misc_init_r(void) 347 { 348 #ifdef CONFIG_SET_DFU_ALT_INFO 349 set_dfu_alt_info(); 350 #endif 351 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 352 set_board_info(); 353 #endif 354 #ifdef CONFIG_LCD_MENU 355 keys_init(); 356 check_boot_mode(); 357 #endif 358 #ifdef CONFIG_CMD_BMP 359 if (panel_info.logo_on) 360 draw_logo(); 361 #endif 362 return 0; 363 } 364 #endif 365