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