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/gpio.h> 17 #include <asm/arch/board.h> 18 #include <asm/arch/cpu.h> 19 #include <asm/arch/dwmmc.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 #include <usb.h> 29 30 DECLARE_GLOBAL_DATA_PTR; 31 32 __weak int exynos_early_init_f(void) 33 { 34 return 0; 35 } 36 37 __weak int exynos_power_init(void) 38 { 39 return 0; 40 } 41 42 #if defined CONFIG_EXYNOS_TMU 43 /* Boot Time Thermal Analysis for SoC temperature threshold breach */ 44 static void boot_temp_check(void) 45 { 46 int temp; 47 48 switch (tmu_monitor(&temp)) { 49 case TMU_STATUS_NORMAL: 50 break; 51 case TMU_STATUS_TRIPPED: 52 /* 53 * Status TRIPPED ans WARNING means corresponding threshold 54 * breach 55 */ 56 puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n"); 57 set_ps_hold_ctrl(); 58 hang(); 59 break; 60 case TMU_STATUS_WARNING: 61 puts("EXYNOS_TMU: WARNING! Temperature very high\n"); 62 break; 63 case TMU_STATUS_INIT: 64 /* 65 * TMU_STATUS_INIT means something is wrong with temperature 66 * sensing and TMU status was changed back from NORMAL to INIT. 67 */ 68 puts("EXYNOS_TMU: WARNING! Temperature sensing not done\n"); 69 break; 70 default: 71 debug("EXYNOS_TMU: Unknown TMU state\n"); 72 } 73 } 74 #endif 75 76 int board_init(void) 77 { 78 gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); 79 #if defined CONFIG_EXYNOS_TMU 80 if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) { 81 debug("%s: Failed to init TMU\n", __func__); 82 return -1; 83 } 84 boot_temp_check(); 85 #endif 86 #ifdef CONFIG_TZSW_RESERVED_DRAM_SIZE 87 /* The last few MB of memory can be reserved for secure firmware */ 88 ulong size = CONFIG_TZSW_RESERVED_DRAM_SIZE; 89 90 gd->ram_size -= size; 91 gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS - 1].size -= size; 92 #endif 93 return exynos_init(); 94 } 95 96 int dram_init(void) 97 { 98 unsigned 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 unsigned 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 #ifdef CONFIG_MISC_INIT_R 334 int misc_init_r(void) 335 { 336 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 337 set_board_info(); 338 #endif 339 #ifdef CONFIG_LCD_MENU 340 keys_init(); 341 check_boot_mode(); 342 #endif 343 #ifdef CONFIG_CMD_BMP 344 if (panel_info.logo_on) 345 draw_logo(); 346 #endif 347 return 0; 348 } 349 #endif 350 351 void reset_misc(void) 352 { 353 struct gpio_desc gpio = {}; 354 int node; 355 356 node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, 357 "samsung,emmc-reset"); 358 if (node < 0) 359 return; 360 361 gpio_request_by_name_nodev(gd->fdt_blob, node, "reset-gpio", 0, &gpio, 362 GPIOD_IS_OUT); 363 364 if (dm_gpio_is_valid(&gpio)) { 365 /* 366 * Reset eMMC 367 * 368 * FIXME: Need to optimize delay time. Minimum 1usec pulse is 369 * required by 'JEDEC Standard No.84-A441' (eMMC) 370 * document but real delay time is expected to greater 371 * than 1usec. 372 */ 373 dm_gpio_set_value(&gpio, 0); 374 mdelay(10); 375 dm_gpio_set_value(&gpio, 1); 376 } 377 } 378 379 int board_usb_cleanup(int index, enum usb_init_type init) 380 { 381 return 0; 382 } 383