171ebb335SRajeshwari Birje /* 271ebb335SRajeshwari Birje * (C) Copyright 2013 SAMSUNG Electronics 371ebb335SRajeshwari Birje * Rajeshwari Shinde <rajeshwari.s@samsung.com> 471ebb335SRajeshwari Birje * 571ebb335SRajeshwari Birje * SPDX-License-Identifier: GPL-2.0+ 671ebb335SRajeshwari Birje */ 771ebb335SRajeshwari Birje 871ebb335SRajeshwari Birje #include <common.h> 971ebb335SRajeshwari Birje #include <cros_ec.h> 1071ebb335SRajeshwari Birje #include <errno.h> 1171ebb335SRajeshwari Birje #include <fdtdec.h> 1271ebb335SRajeshwari Birje #include <spi.h> 1371ebb335SRajeshwari Birje #include <tmu.h> 1471ebb335SRajeshwari Birje #include <netdev.h> 1571ebb335SRajeshwari Birje #include <asm/io.h> 1671ebb335SRajeshwari Birje #include <asm/arch/board.h> 1771ebb335SRajeshwari Birje #include <asm/arch/cpu.h> 1871ebb335SRajeshwari Birje #include <asm/arch/dwmmc.h> 1971ebb335SRajeshwari Birje #include <asm/arch/gpio.h> 2071ebb335SRajeshwari Birje #include <asm/arch/mmc.h> 2171ebb335SRajeshwari Birje #include <asm/arch/pinmux.h> 2271ebb335SRajeshwari Birje #include <asm/arch/power.h> 2371ebb335SRajeshwari Birje #include <power/pmic.h> 2471ebb335SRajeshwari Birje #include <asm/arch/sromc.h> 25431a1c56SPiotr Wilczek #include <lcd.h> 26431a1c56SPiotr Wilczek #include <samsung/misc.h> 2771ebb335SRajeshwari Birje 2871ebb335SRajeshwari Birje DECLARE_GLOBAL_DATA_PTR; 2971ebb335SRajeshwari Birje 308e5e1e6aSPiotr Wilczek int __exynos_early_init_f(void) 318e5e1e6aSPiotr Wilczek { 328e5e1e6aSPiotr Wilczek return 0; 338e5e1e6aSPiotr Wilczek } 348e5e1e6aSPiotr Wilczek int exynos_early_init_f(void) 358e5e1e6aSPiotr Wilczek __attribute__((weak, alias("__exynos_early_init_f"))); 368e5e1e6aSPiotr Wilczek 378e5e1e6aSPiotr Wilczek int __exynos_power_init(void) 388e5e1e6aSPiotr Wilczek { 398e5e1e6aSPiotr Wilczek return 0; 408e5e1e6aSPiotr Wilczek } 418e5e1e6aSPiotr Wilczek int exynos_power_init(void) 428e5e1e6aSPiotr Wilczek __attribute__((weak, alias("__exynos_power_init"))); 438e5e1e6aSPiotr Wilczek 4471ebb335SRajeshwari Birje #if defined CONFIG_EXYNOS_TMU 4571ebb335SRajeshwari Birje /* Boot Time Thermal Analysis for SoC temperature threshold breach */ 4671ebb335SRajeshwari Birje static void boot_temp_check(void) 4771ebb335SRajeshwari Birje { 4871ebb335SRajeshwari Birje int temp; 4971ebb335SRajeshwari Birje 5071ebb335SRajeshwari Birje switch (tmu_monitor(&temp)) { 5171ebb335SRajeshwari Birje case TMU_STATUS_NORMAL: 5271ebb335SRajeshwari Birje break; 5371ebb335SRajeshwari Birje case TMU_STATUS_TRIPPED: 5471ebb335SRajeshwari Birje /* 5571ebb335SRajeshwari Birje * Status TRIPPED ans WARNING means corresponding threshold 5671ebb335SRajeshwari Birje * breach 5771ebb335SRajeshwari Birje */ 5871ebb335SRajeshwari Birje puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n"); 5971ebb335SRajeshwari Birje set_ps_hold_ctrl(); 6071ebb335SRajeshwari Birje hang(); 6171ebb335SRajeshwari Birje break; 6271ebb335SRajeshwari Birje case TMU_STATUS_WARNING: 6371ebb335SRajeshwari Birje puts("EXYNOS_TMU: WARNING! Temperature very high\n"); 6471ebb335SRajeshwari Birje break; 6571ebb335SRajeshwari Birje case TMU_STATUS_INIT: 6671ebb335SRajeshwari Birje /* 6771ebb335SRajeshwari Birje * TMU_STATUS_INIT means something is wrong with temperature 6871ebb335SRajeshwari Birje * sensing and TMU status was changed back from NORMAL to INIT. 6971ebb335SRajeshwari Birje */ 7071ebb335SRajeshwari Birje puts("EXYNOS_TMU: WARNING! Temperature sensing not done\n"); 7171ebb335SRajeshwari Birje break; 7271ebb335SRajeshwari Birje default: 7371ebb335SRajeshwari Birje debug("EXYNOS_TMU: Unknown TMU state\n"); 7471ebb335SRajeshwari Birje } 7571ebb335SRajeshwari Birje } 7671ebb335SRajeshwari Birje #endif 7771ebb335SRajeshwari Birje 7871ebb335SRajeshwari Birje int board_init(void) 7971ebb335SRajeshwari Birje { 8071ebb335SRajeshwari Birje gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); 8171ebb335SRajeshwari Birje #if defined CONFIG_EXYNOS_TMU 8271ebb335SRajeshwari Birje if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) { 8371ebb335SRajeshwari Birje debug("%s: Failed to init TMU\n", __func__); 8471ebb335SRajeshwari Birje return -1; 8571ebb335SRajeshwari Birje } 8671ebb335SRajeshwari Birje boot_temp_check(); 8771ebb335SRajeshwari Birje #endif 8871ebb335SRajeshwari Birje 8971ebb335SRajeshwari Birje #ifdef CONFIG_EXYNOS_SPI 9071ebb335SRajeshwari Birje spi_init(); 9171ebb335SRajeshwari Birje #endif 9271ebb335SRajeshwari Birje return exynos_init(); 9371ebb335SRajeshwari Birje } 9471ebb335SRajeshwari Birje 9571ebb335SRajeshwari Birje int dram_init(void) 9671ebb335SRajeshwari Birje { 9771ebb335SRajeshwari Birje int i; 9871ebb335SRajeshwari Birje u32 addr; 9971ebb335SRajeshwari Birje 10071ebb335SRajeshwari Birje for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 10171ebb335SRajeshwari Birje addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE); 10271ebb335SRajeshwari Birje gd->ram_size += get_ram_size((long *)addr, SDRAM_BANK_SIZE); 10371ebb335SRajeshwari Birje } 10471ebb335SRajeshwari Birje return 0; 10571ebb335SRajeshwari Birje } 10671ebb335SRajeshwari Birje 10771ebb335SRajeshwari Birje void dram_init_banksize(void) 10871ebb335SRajeshwari Birje { 10971ebb335SRajeshwari Birje int i; 11071ebb335SRajeshwari Birje u32 addr, size; 11171ebb335SRajeshwari Birje 11271ebb335SRajeshwari Birje for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 11371ebb335SRajeshwari Birje addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE); 11471ebb335SRajeshwari Birje size = get_ram_size((long *)addr, SDRAM_BANK_SIZE); 11571ebb335SRajeshwari Birje 11671ebb335SRajeshwari Birje gd->bd->bi_dram[i].start = addr; 11771ebb335SRajeshwari Birje gd->bd->bi_dram[i].size = size; 11871ebb335SRajeshwari Birje } 11971ebb335SRajeshwari Birje } 12071ebb335SRajeshwari Birje 12171ebb335SRajeshwari Birje static int board_uart_init(void) 12271ebb335SRajeshwari Birje { 12371ebb335SRajeshwari Birje int err, uart_id, ret = 0; 12471ebb335SRajeshwari Birje 12571ebb335SRajeshwari Birje for (uart_id = PERIPH_ID_UART0; uart_id <= PERIPH_ID_UART3; uart_id++) { 12671ebb335SRajeshwari Birje err = exynos_pinmux_config(uart_id, PINMUX_FLAG_NONE); 12771ebb335SRajeshwari Birje if (err) { 12871ebb335SRajeshwari Birje debug("UART%d not configured\n", 12971ebb335SRajeshwari Birje (uart_id - PERIPH_ID_UART0)); 13071ebb335SRajeshwari Birje ret |= err; 13171ebb335SRajeshwari Birje } 13271ebb335SRajeshwari Birje } 13371ebb335SRajeshwari Birje return ret; 13471ebb335SRajeshwari Birje } 13571ebb335SRajeshwari Birje 13671ebb335SRajeshwari Birje #ifdef CONFIG_BOARD_EARLY_INIT_F 13771ebb335SRajeshwari Birje int board_early_init_f(void) 13871ebb335SRajeshwari Birje { 13971ebb335SRajeshwari Birje int err; 14071ebb335SRajeshwari Birje 14171ebb335SRajeshwari Birje err = board_uart_init(); 14271ebb335SRajeshwari Birje if (err) { 14371ebb335SRajeshwari Birje debug("UART init failed\n"); 14471ebb335SRajeshwari Birje return err; 14571ebb335SRajeshwari Birje } 14671ebb335SRajeshwari Birje 14771ebb335SRajeshwari Birje #ifdef CONFIG_SYS_I2C_INIT_BOARD 14871ebb335SRajeshwari Birje board_i2c_init(gd->fdt_blob); 14971ebb335SRajeshwari Birje #endif 15071ebb335SRajeshwari Birje 1518e5e1e6aSPiotr Wilczek return exynos_early_init_f(); 15271ebb335SRajeshwari Birje } 15371ebb335SRajeshwari Birje #endif 15471ebb335SRajeshwari Birje 15571ebb335SRajeshwari Birje #if defined(CONFIG_POWER) 15671ebb335SRajeshwari Birje int power_init_board(void) 15771ebb335SRajeshwari Birje { 15871ebb335SRajeshwari Birje set_ps_hold_ctrl(); 15971ebb335SRajeshwari Birje 1608e5e1e6aSPiotr Wilczek return exynos_power_init(); 16171ebb335SRajeshwari Birje } 16271ebb335SRajeshwari Birje #endif 16371ebb335SRajeshwari Birje 16471ebb335SRajeshwari Birje #ifdef CONFIG_OF_CONTROL 165431a1c56SPiotr Wilczek #ifdef CONFIG_SMC911X 16671ebb335SRajeshwari Birje static int decode_sromc(const void *blob, struct fdt_sromc *config) 16771ebb335SRajeshwari Birje { 16871ebb335SRajeshwari Birje int err; 16971ebb335SRajeshwari Birje int node; 17071ebb335SRajeshwari Birje 17171ebb335SRajeshwari Birje node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC); 17271ebb335SRajeshwari Birje if (node < 0) { 17371ebb335SRajeshwari Birje debug("Could not find SROMC node\n"); 17471ebb335SRajeshwari Birje return node; 17571ebb335SRajeshwari Birje } 17671ebb335SRajeshwari Birje 17771ebb335SRajeshwari Birje config->bank = fdtdec_get_int(blob, node, "bank", 0); 17871ebb335SRajeshwari Birje config->width = fdtdec_get_int(blob, node, "width", 2); 17971ebb335SRajeshwari Birje 18071ebb335SRajeshwari Birje err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing, 18171ebb335SRajeshwari Birje FDT_SROM_TIMING_COUNT); 18271ebb335SRajeshwari Birje if (err < 0) { 18371ebb335SRajeshwari Birje debug("Could not decode SROMC configuration Error: %s\n", 18471ebb335SRajeshwari Birje fdt_strerror(err)); 18571ebb335SRajeshwari Birje return -FDT_ERR_NOTFOUND; 18671ebb335SRajeshwari Birje } 18771ebb335SRajeshwari Birje return 0; 18871ebb335SRajeshwari Birje } 189431a1c56SPiotr Wilczek #endif 19071ebb335SRajeshwari Birje 19171ebb335SRajeshwari Birje int board_eth_init(bd_t *bis) 19271ebb335SRajeshwari Birje { 19371ebb335SRajeshwari Birje #ifdef CONFIG_SMC911X 19471ebb335SRajeshwari Birje u32 smc_bw_conf, smc_bc_conf; 19571ebb335SRajeshwari Birje struct fdt_sromc config; 19671ebb335SRajeshwari Birje fdt_addr_t base_addr; 19771ebb335SRajeshwari Birje int node; 19871ebb335SRajeshwari Birje 19971ebb335SRajeshwari Birje node = decode_sromc(gd->fdt_blob, &config); 20071ebb335SRajeshwari Birje if (node < 0) { 20171ebb335SRajeshwari Birje debug("%s: Could not find sromc configuration\n", __func__); 20271ebb335SRajeshwari Birje return 0; 20371ebb335SRajeshwari Birje } 20471ebb335SRajeshwari Birje node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215); 20571ebb335SRajeshwari Birje if (node < 0) { 20671ebb335SRajeshwari Birje debug("%s: Could not find lan9215 configuration\n", __func__); 20771ebb335SRajeshwari Birje return 0; 20871ebb335SRajeshwari Birje } 20971ebb335SRajeshwari Birje 21071ebb335SRajeshwari Birje /* We now have a node, so any problems from now on are errors */ 21171ebb335SRajeshwari Birje base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg"); 21271ebb335SRajeshwari Birje if (base_addr == FDT_ADDR_T_NONE) { 21371ebb335SRajeshwari Birje debug("%s: Could not find lan9215 address\n", __func__); 21471ebb335SRajeshwari Birje return -1; 21571ebb335SRajeshwari Birje } 21671ebb335SRajeshwari Birje 21771ebb335SRajeshwari Birje /* Ethernet needs data bus width of 16 bits */ 21871ebb335SRajeshwari Birje if (config.width != 2) { 21971ebb335SRajeshwari Birje debug("%s: Unsupported bus width %d\n", __func__, 22071ebb335SRajeshwari Birje config.width); 22171ebb335SRajeshwari Birje return -1; 22271ebb335SRajeshwari Birje } 22371ebb335SRajeshwari Birje smc_bw_conf = SROMC_DATA16_WIDTH(config.bank) 22471ebb335SRajeshwari Birje | SROMC_BYTE_ENABLE(config.bank); 22571ebb335SRajeshwari Birje 22671ebb335SRajeshwari Birje smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) | 22771ebb335SRajeshwari Birje SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) | 22871ebb335SRajeshwari Birje SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) | 22971ebb335SRajeshwari Birje SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) | 23071ebb335SRajeshwari Birje SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) | 23171ebb335SRajeshwari Birje SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) | 23271ebb335SRajeshwari Birje SROMC_BC_PMC(config.timing[FDT_SROM_PMC]); 23371ebb335SRajeshwari Birje 23471ebb335SRajeshwari Birje /* Select and configure the SROMC bank */ 23571ebb335SRajeshwari Birje exynos_pinmux_config(PERIPH_ID_SROMC, config.bank); 23671ebb335SRajeshwari Birje s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf); 23771ebb335SRajeshwari Birje return smc911x_initialize(0, base_addr); 23871ebb335SRajeshwari Birje #endif 23971ebb335SRajeshwari Birje return 0; 24071ebb335SRajeshwari Birje } 24171ebb335SRajeshwari Birje 24271ebb335SRajeshwari Birje #ifdef CONFIG_GENERIC_MMC 24371ebb335SRajeshwari Birje int board_mmc_init(bd_t *bis) 24471ebb335SRajeshwari Birje { 24571ebb335SRajeshwari Birje int ret; 246431a1c56SPiotr Wilczek #ifdef CONFIG_DWMMC 24771ebb335SRajeshwari Birje /* dwmmc initializattion for available channels */ 24871ebb335SRajeshwari Birje ret = exynos_dwmmc_init(gd->fdt_blob); 24971ebb335SRajeshwari Birje if (ret) 25071ebb335SRajeshwari Birje debug("dwmmc init failed\n"); 251431a1c56SPiotr Wilczek #endif 25271ebb335SRajeshwari Birje 253*58209dfaSJaehoon Chung #ifdef CONFIG_SDHCI 254*58209dfaSJaehoon Chung /* mmc initializattion for available channels */ 255*58209dfaSJaehoon Chung ret = exynos_mmc_init(gd->fdt_blob); 256*58209dfaSJaehoon Chung if (ret) 257*58209dfaSJaehoon Chung debug("mmc init failed\n"); 258*58209dfaSJaehoon Chung #endif 25971ebb335SRajeshwari Birje return ret; 26071ebb335SRajeshwari Birje } 26171ebb335SRajeshwari Birje #endif 2624c1dd998SPiotr Wilczek 2634c1dd998SPiotr Wilczek #ifdef CONFIG_DISPLAY_BOARDINFO 2644c1dd998SPiotr Wilczek int checkboard(void) 2654c1dd998SPiotr Wilczek { 2664c1dd998SPiotr Wilczek const char *board_name; 2674c1dd998SPiotr Wilczek 2684c1dd998SPiotr Wilczek board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL); 2694c1dd998SPiotr Wilczek printf("Board: %s\n", board_name ? board_name : "unknown"); 2704c1dd998SPiotr Wilczek 2714c1dd998SPiotr Wilczek return 0; 2724c1dd998SPiotr Wilczek } 27371ebb335SRajeshwari Birje #endif 2744c1dd998SPiotr Wilczek #endif /* CONFIG_OF_CONTROL */ 27571ebb335SRajeshwari Birje 27671ebb335SRajeshwari Birje #ifdef CONFIG_BOARD_LATE_INIT 27771ebb335SRajeshwari Birje int board_late_init(void) 27871ebb335SRajeshwari Birje { 27971ebb335SRajeshwari Birje stdio_print_current_devices(); 28071ebb335SRajeshwari Birje 28141364f0fSVadim Bendebury if (cros_ec_get_error()) { 28271ebb335SRajeshwari Birje /* Force console on */ 28371ebb335SRajeshwari Birje gd->flags &= ~GD_FLG_SILENT; 28471ebb335SRajeshwari Birje 28571ebb335SRajeshwari Birje printf("cros-ec communications failure %d\n", 28641364f0fSVadim Bendebury cros_ec_get_error()); 28771ebb335SRajeshwari Birje puts("\nPlease reset with Power+Refresh\n\n"); 28871ebb335SRajeshwari Birje panic("Cannot init cros-ec device"); 28971ebb335SRajeshwari Birje return -1; 29071ebb335SRajeshwari Birje } 29171ebb335SRajeshwari Birje return 0; 29271ebb335SRajeshwari Birje } 29371ebb335SRajeshwari Birje #endif 29471ebb335SRajeshwari Birje 29571ebb335SRajeshwari Birje int arch_early_init_r(void) 29671ebb335SRajeshwari Birje { 29771ebb335SRajeshwari Birje #ifdef CONFIG_CROS_EC 29841364f0fSVadim Bendebury if (cros_ec_board_init()) { 29971ebb335SRajeshwari Birje printf("%s: Failed to init EC\n", __func__); 30071ebb335SRajeshwari Birje return 0; 30171ebb335SRajeshwari Birje } 30271ebb335SRajeshwari Birje #endif 30371ebb335SRajeshwari Birje 30471ebb335SRajeshwari Birje return 0; 30571ebb335SRajeshwari Birje } 306431a1c56SPiotr Wilczek 307431a1c56SPiotr Wilczek #ifdef CONFIG_MISC_INIT_R 308431a1c56SPiotr Wilczek int misc_init_r(void) 309431a1c56SPiotr Wilczek { 310431a1c56SPiotr Wilczek #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 311431a1c56SPiotr Wilczek set_board_info(); 312431a1c56SPiotr Wilczek #endif 313431a1c56SPiotr Wilczek #ifdef CONFIG_LCD_MENU 314431a1c56SPiotr Wilczek keys_init(); 315431a1c56SPiotr Wilczek check_boot_mode(); 316431a1c56SPiotr Wilczek #endif 317431a1c56SPiotr Wilczek #ifdef CONFIG_CMD_BMP 318431a1c56SPiotr Wilczek if (panel_info.logo_on) 319431a1c56SPiotr Wilczek draw_logo(); 320431a1c56SPiotr Wilczek #endif 321431a1c56SPiotr Wilczek return 0; 322431a1c56SPiotr Wilczek } 323431a1c56SPiotr Wilczek #endif 324