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