Skip to content
Snippets Groups Projects
bd_common.c 7.82 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * Copyright (C) 2017, Boundary Devices <info@boundarydevices.com>
     *
     * SPDX-License-Identifier:	GPL-2.0+
     */
    #include <common.h>
    #include <asm/arch/clock.h>
    #ifndef CONFIG_MX7D
    #ifndef CONFIG_MX51
    #include <asm/arch/iomux.h>
    #endif
    #endif
    #include <asm/arch/sys_proto.h>
    #include <asm/gpio.h>
    
    #include <asm/mach-imx/fbpanel.h>
    #include <asm/mach-imx/mxc_i2c.h>
    #include <asm/mach-imx/sata.h>
    #include <environment.h>
    
    #include <i2c.h>
    #include <linux/fb.h>
    #include <version.h>
    #include "bd_common.h"
    
    DECLARE_GLOBAL_DATA_PTR;
    
    int dram_init(void)
    {
    #if defined(CONFIG_MX51) || defined(CONFIG_MX7D)
    	gd->ram_size = ((ulong)CONFIG_DDR_MB * 1024 * 1024);
    #else
    	gd->ram_size = imx_ddr_size();
    #endif
    //	printf("%s:%p *%p=0x%lx\n", __func__, gd, &gd->ram_size, gd->ram_size);
    
    	return 0;
    }
    
    /*
     * Do not overwrite the console
     * Use always serial for U-Boot console
     */
    int overwrite_console(void)
    {
    	return 1;
    }
    
    void set_gpios_in(const unsigned short *p, int cnt)
    {
    	int i;
    
    	for (i = 0; i < cnt; i++)
    		gpio_direction_input(*p++);
    }
    
    void set_gpios(const unsigned short *p, int cnt, int val)
    {
    	int i;
    
    	for (i = 0; i < cnt; i++)
    		gpio_direction_output(*p++, val);
    }
    
    #ifdef CONFIG_FSL_ESDHC
    int board_mmc_getcd(struct mmc *mmc)
    {
    	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
    	int gp_cd = cfg->gp_cd;
    
    	if (!gp_cd)
    		return 1;	/* eMMC always present */
    	return !gpio_get_value(gp_cd);
    }
    
    #if defined(CONFIG_MX51)
    #define BASE1 MMC_SDHC1_BASE_ADDR
    #define BASE2 MMC_SDHC2_BASE_ADDR
    #define CNT CONFIG_SYS_FSL_ESDHC_NUM
    #else
    #define BASE1 USDHC1_BASE_ADDR
    #define BASE2 USDHC2_BASE_ADDR
    #define BASE3 USDHC3_BASE_ADDR
    #define BASE4 USDHC4_BASE_ADDR
    #define CNT CONFIG_SYS_FSL_USDHC_NUM
    #endif
    
    int board_mmc_init(bd_t *bis)
    {
    	int ret;
    	u32 index = 0;
    
    	for (index = 0; index < CNT; index++) {
    		struct fsl_esdhc_cfg *cfg = &board_usdhc_cfg[index];
    
    		if (cfg->esdhc_base == BASE1) {
    			cfg->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
    		} else if (cfg->esdhc_base == BASE2) {
    			cfg->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
    #ifndef CONFIG_MX51
    		} else if (cfg->esdhc_base == BASE3) {
    			cfg->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
    #ifndef CONFIG_MX7D
    		} else if (cfg->esdhc_base == BASE4) {
    			cfg->sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
    #endif
    #endif
    		} else {
    			printf("unknown esdhc base %lx\n", cfg->esdhc_base);
    			break;
    		}
    
    		if (cfg->gp_cd)
    			gpio_request(cfg->gp_cd, "usdhcx_cd");
    
    		if (cfg->gp_reset) {
    			gpio_request(cfg->gp_reset, "usdhcx_reset");
    			gpio_set_value(cfg->gp_reset, 1); /* release reset */
    		}
    
    		ret = fsl_esdhc_initialize(bis, cfg);
    		if (ret)
    			return ret;
    	}
    	return 0;
    }
    #endif
    
    #ifdef CONFIG_SPLASH_SCREEN
    int splash_screen_prepare(void)
    {
    	char *env_loadsplash;
    
    
    	if (!env_get("splashimage") || !env_get("splashsize")) {
    
    	env_loadsplash = env_get("loadsplash");
    
    	if (env_loadsplash == NULL) {
    		printf("Environment variable loadsplash not found!\n");
    		return -1;
    	}
    
    	if (run_command_list(env_loadsplash, -1, 0)) {
    		printf("failed to run loadsplash %s\n\n", env_loadsplash);
    		return -1;
    	}
    
    	return 0;
    }
    #endif
    
    #ifdef CONFIG_CMD_FBPANEL
    int board_cfb_skip(void)
    {
    
    	return NULL != env_get("novideo");
    
    }
    #endif
    
    void common_board_init(const struct i2c_pads_info *p, int i2c_bus_cnt, int otg_id,
    		const struct display_info_t *displays, int display_cnt,
    		int gp_hd_detect)
    {
    	int i;
    #ifdef IOMUXC_GPR1_OTG_ID_MASK
    	struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
    
    	/* needed for i.mx6q, duallite doesn't need it, but doesn't hurt */
    	clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_OTG_ID_MASK, otg_id);
    #endif
    	p += i2c_get_info_entry_offset();
    
    	/* address of boot parameters */
    	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
    	for (i = 0; i < i2c_bus_cnt; i++) {
    	        setup_i2c(p->bus_index, CONFIG_SYS_I2C_SPEED, 0x7f, p);
    		p += I2C_PADS_INFO_ENTRY_SPACING;
    	}
    #ifdef CONFIG_FAN53526
    	fan53526_init();
    #endif
    #ifdef CONFIG_MAX77823
    	max77823_init();
    #endif
    #ifdef CONFIG_TAMPER
    	check_tamper();
    #endif
    
    #ifdef CONFIG_CMD_SATA
    	if (!gp_hd_detect || gpio_get_value(gp_hd_detect))
    		setup_sata();
    #endif
    #ifdef CONFIG_CMD_FBPANEL
    	fbp_setup_display(displays, display_cnt);
    #endif
    }
    
    int misc_init_r(void)
    {
    #ifdef CONFIG_PREBOOT
    	board_preboot_keys();
    #endif
    
    #ifdef CONFIG_CMD_BMODE
    	add_board_boot_modes(board_boot_modes);
    #endif
    	/*
    	 * Not really needed as script checks for magic value in memory,
    	 * but shouldn't hurt.
    	 */
    
    	env_set_hex("reset_cause", get_imx_reset_cause());
    
    
    #ifdef CONFIG_MX7D
    	set_wdog_reset((struct wdog_regs *)WDOG1_BASE_ADDR);
    #endif
    	return 0;
    }
    
    #ifdef CONFIG_PRINT_TIME_RV4162
    
    /* RV4162 particulars */
    #define RTC_I2CADDR 0x68
    #define RTC_YEAR 7
    #define RTC_MON  6
    #define RTC_DAY  5
    #define RTC_HOUR 3
    #define RTC_MIN  2
    #define RTC_SEC  1
    
    static int frombcd(u8 val)
    {
    	return (10*(val>>4))+(val&0x0f);
    }
    
    static void print_time_rv4162(void)
    {
    	u8 orig_i2c_bus;
    
    	orig_i2c_bus = i2c_get_bus_num();
    	/* display date and time from RTC */
    	if (!i2c_set_bus_num(0) &&
    			!i2c_probe(RTC_I2CADDR)) {
    		u8 buffer[16];
    		int ret = i2c_read(RTC_I2CADDR, 0, 1, buffer, sizeof(buffer));
    
    		if (ret)
    			printf("Error %d reading RTC\n", ret);
    		else
    			printf("time: %04u-%02u-%02u %02u:%02u:%02u UTC\n",
    			       2000+frombcd(buffer[RTC_YEAR]),
    			       frombcd(buffer[RTC_MON]&0x1f),
    			       frombcd(buffer[RTC_DAY]),
    			       frombcd(buffer[RTC_HOUR]),
    			       frombcd(buffer[RTC_MIN]),
    			       frombcd(buffer[RTC_SEC]));
    	}
    	i2c_set_bus_num(orig_i2c_bus);
    }
    #else
    static void print_time_rv4162(void) {}
    #endif
    
    #ifdef CONFIG_FEC_MXC
    #define ADDMAC_OFFSET	0x800000
    #else
    #define ADDMAC_OFFSET	0
    #endif
    
    #if defined(CONFIG_ENV_WLMAC) || defined(CONFIG_ENV_BD_ADDR)
    static void addmac_env(const char* env_var)
    {
    	unsigned char mac_address[8];
    	char macbuf[20];
    
    
    	if (!env_get(env_var)) {
    
    		imx_get_mac_from_fuse(ADDMAC_OFFSET, mac_address);
    		if (is_valid_ethaddr(mac_address)) {
    			snprintf(macbuf, sizeof(macbuf), "%pM", mac_address);
    
    			env_set(env_var, macbuf);
    
    		}
    	}
    }
    #endif
    
    #if defined(CONFIG_CMD_FASTBOOT) || defined(CONFIG_CMD_DFU)
    static void addserial_env(const char* env_var)
    {
    	unsigned char mac_address[8];
    	char serialbuf[20];
    
    
    	if (!env_get(env_var)) {
    
    		imx_get_mac_from_fuse(0, mac_address);
    		snprintf(serialbuf, sizeof(serialbuf), "%02x%02x%02x%02x%02x%02x",
    			 mac_address[0], mac_address[1], mac_address[2],
    			 mac_address[3], mac_address[4], mac_address[5]);
    
    		env_set(env_var, serialbuf);
    
    	}
    }
    #endif
    
    #ifndef CONFIG_SYS_BOARD
    /* CANNOT be in BSS section, will clobber relocation table */
    const char *board_type = (void*)1;
    #endif
    
    int checkboard(void)
    {
    #ifdef CONFIG_SYS_BOARD
    	puts("Board: " CONFIG_SYS_BOARD "\n");
    #else
    	board_type = board_get_board_type();
    	puts("Board: ");
    	puts(board_type);
    	puts("\n");
    #endif
    	return 0;
    }
    
    static const char str_uboot_release[] = "uboot_release";
    static const char cur_uboot_release[] = PLAIN_VERSION;
    
    int board_late_init(void)
    {
    	char *uboot_release;
    	int cpurev = get_cpu_rev();
    
    #ifdef CONFIG_BOARD_LATE_SPECIFIC_INIT
    	board_late_specific_init();
    #endif
    
    	env_set("cpu", get_imx_type((cpurev & 0xFF000) >> 12));
    	env_set("imx_cpu", get_imx_type((cpurev & 0xFF000) >> 12));
    
    #ifndef CONFIG_SYS_BOARD
    	/*
    	 * These lines are specific to nitrogen6x, as
    	 * everyone else has board in their default environment.
    	 */
    
    	if (!env_get("board"))
    		env_set("board", board_type);
    
    	env_set("uboot_defconfig", CONFIG_DEFCONFIG);
    
    #ifdef CONFIG_ENV_WLMAC
    	addmac_env("wlmac");
    #endif
    #ifdef CONFIG_ENV_BD_ADDR
    	addmac_env("bd_addr");
    #endif
    #if defined(CONFIG_CMD_FASTBOOT) || defined(CONFIG_CMD_DFU)
    	addserial_env("serial#");
    #endif
    	print_time_rv4162();
    
    #if !defined(CONFIG_ENV_IS_NOWHERE)
    
    	uboot_release = env_get(str_uboot_release);
    
    	if (!uboot_release || strcmp(cur_uboot_release, uboot_release)) {
    
    		env_set(str_uboot_release, cur_uboot_release);
    
    		if (uboot_release) {
    			/*
    			 * if already saved in environment, correct value
    			 */
    
    			env_save();