blob: 4d1b5dcc79d85a09ff7c9d5baeac9a9571c62cfa [file] [log] [blame]
/*
* Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <common.h>
#include <asm/arch-qca-common/smem.h>
#include <environment.h>
#ifdef CONFIG_SDHCI_SUPPORT
#include <sdhci.h>
#endif
#ifdef CONFIG_ENV_IS_IN_NAND
extern void nand_env_relocate_spec(void);
extern int nand_env_init(void);
#endif
#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
extern void sf_env_relocate_spec(void);
extern int sf_env_init(void);
#endif
#ifdef CONFIG_QCA_MMC
extern int mmc_env_init(void);
extern void mmc_env_relocate_spec(void);
extern int mmc_init(struct mmc *mmc);
#endif
/*
* Function description: Board specific initialization.
* I/P : None
* O/P : integer, 0 - no error.
*/
int env_init(void)
{
int ret = 0;
qca_smem_flash_info_t sfi;
smem_get_boot_flash(&sfi.flash_type,
&sfi.flash_index,
&sfi.flash_chip_select,
&sfi.flash_block_size,
&sfi.flash_density);
if (sfi.flash_type == SMEM_BOOT_SPI_FLASH) {
#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
ret = sf_env_init();
#endif
#ifdef CONFIG_QCA_MMC
} else if (sfi.flash_type == SMEM_BOOT_MMC_FLASH) {
ret = mmc_env_init();
#endif
} else {
#ifdef CONFIG_ENV_IS_IN_NAND
ret = nand_env_init();
#endif
}
return ret;
}
void env_relocate_spec(void)
{
qca_smem_flash_info_t sfi;
smem_get_boot_flash(&sfi.flash_type,
&sfi.flash_index,
&sfi.flash_chip_select,
&sfi.flash_block_size,
&sfi.flash_density);
if (sfi.flash_type == SMEM_BOOT_NO_FLASH) {
set_default_env("!flashless boot");
#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
} else if (sfi.flash_type == SMEM_BOOT_SPI_FLASH) {
sf_env_relocate_spec();
#endif
#ifdef CONFIG_QCA_MMC
} else if (sfi.flash_type == SMEM_BOOT_MMC_FLASH) {
mmc_env_relocate_spec();
#endif
} else {
#ifdef CONFIG_ENV_IS_IN_NAND
nand_env_relocate_spec();
#endif
}
};
#ifdef CONFIG_QCA_MMC
#ifdef CONFIG_SDHCI_SUPPORT
int board_mmc_env_init(struct sdhci_host mmc_host)
#else
int board_mmc_env_init(qca_mmc mmc_host)
#endif
{
block_dev_desc_t *blk_dev;
disk_partition_t disk_info;
int ret;
if (mmc_init(mmc_host.mmc)) {
/* The HS mode command(cmd6) is getting timed out. So mmc card is
* not getting initialized properly. Since the env partition is not
* visible, the env default values are writing into the default
* partition (start of the mmc device). So do a reset again.
*/
if (mmc_init(mmc_host.mmc)) {
printf("MMC init failed \n");
return -1;
}
}
blk_dev = mmc_get_dev(mmc_host.dev_num);
ret = get_partition_info_efi_by_name(blk_dev,
"0:APPSBLENV", &disk_info);
if (ret)
ret = get_partition_info_efi_by_name(blk_dev,
"ubootenv", &disk_info);
if (ret == 0) {
board_env_offset = disk_info.start * disk_info.blksz;
board_env_size = disk_info.size * disk_info.blksz;
board_env_range = board_env_size;
BUG_ON(board_env_size > CONFIG_ENV_SIZE_MAX);
}
return ret;
}
#endif
void set_platform_specific_default_env(void)
{
uint32_t soc_ver_major, soc_ver_minor, soc_version;
uint32_t machid;
uint32_t soc_hw_version;
int ret;
machid = smem_get_board_platform_type();
if (machid != 0)
setenv_addr("machid", (void *)machid);
soc_hw_version = get_soc_hw_version();
if (soc_hw_version)
setenv_hex("soc_hw_version", (unsigned long)soc_hw_version);
ret = ipq_smem_get_socinfo_version((uint32_t *)&soc_version);
if (!ret) {
soc_ver_major = SOCINFO_VERSION_MAJOR(soc_version);
soc_ver_minor = SOCINFO_VERSION_MINOR(soc_version);
setenv_ulong("soc_version_major", (unsigned long)soc_ver_major);
setenv_ulong("soc_version_minor", (unsigned long)soc_ver_minor);
}
}