blob: 3e89874b538db921639e9d71a2ec2c31268a058e [file] [log] [blame]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include <blk.h>
#include <board_variant.h>
#include <chromecast/partition.h>
#include <chromecast/factory.h>
#include <common.h>
#include <asm/io.h>
#include <malloc.h>
#include <errno.h>
#include <emmc_partitions.h>
#include <environment.h>
#include <stdio.h>
#include <asm/arch/secure_apb.h>
#include <asm/arch/pinctrl_init.h>
#include <asm-generic/gpio.h>
#include <dm.h>
#include <asm/armv8/mmu.h>
#include <amlogic/aml_v3_burning.h>
#include <amlogic/aml_v2_burning.h>
#include <amlogic/aml_efuse.h>
#include <amlogic/storage.h>
#include <asm/arch/bl31_apis.h>
#include <asm/gpio.h>
#include "partition_table.h"
#ifdef CONFIG_AML_VPU
#include <amlogic/media/vpu/vpu.h>
#endif
#ifdef CONFIG_AML_VPP
#include <amlogic/media/vpp/vpp.h>
#endif
#ifdef CONFIG_AML_HDMITX20
#include <amlogic/media/vout/hdmitx/hdmitx_module.h>
#endif
#ifdef CONFIG_AML_CVBS
#include <amlogic/media/vout/aml_cvbs.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
extern unsigned char res_images_logo_bmp_gz[];
extern unsigned int res_images_logo_bmp_gz_len;
#define BOOT_INDEX_EMMC_USER 0x10
#define BOOT_INDEX_EMMC_BOOT0 0x11
#define BOOT_INDEX_EMMC_BOOT1 0x12
#define BOOT_INDEX_USB 0x50
#define GPIOZ_4 "GPIOZ_4"
#define GPIOZ_6 "GPIOZ_6"
#define GPIOZ_7 "GPIOZ_7"
static int get_boot_index(void)
{
return readl(SYSCTRL_SEC_STATUS_REG2) & 0xff;
}
int get_board_variant(void)
{
#ifdef CONFIG_DEBUG_BOARD_VARIANT_PROD
return BOARD_VARIANT_PROD;
#else
static int board_variant = BOARD_VARIANT_UNKNOWN;
if (board_variant == BOARD_VARIANT_UNKNOWN) {
if (IS_FEAT_DIS_NORMAL_DEVICE_ROOTCERT_0() == 0 &&
IS_FEAT_DIS_DFU_DEVICE_ROOTCERT_0() == 0)
board_variant = BOARD_VARIANT_DEV;
else
board_variant = BOARD_VARIANT_PROD;
}
return board_variant;
#endif
}
int dram_init(void)
{
gd->ram_size = PHYS_SDRAM_1_SIZE;
return 0;
}
#ifdef CONFIG_AML_HDMITX20
static void hdmitx_set_hdmi_5v(void)
{
/*Power on VCC_5V for HDMI_5V*/
run_command("gpio set GPIOH_7", 0);
}
#endif
void board_init_mem(void) {
#if 1
/* config bootm low size, make sure whole dram/psram space can be used */
phys_size_t ram_size;
char *env_tmp;
env_tmp = env_get("bootm_size");
if (!env_tmp) {
ram_size = (((readl(SYSCTRL_SEC_STATUS_REG4)) & 0xFFF80000) << 4);
env_set_hex("bootm_low", 0);
env_set_hex("bootm_size", ram_size);
}
#endif
}
int board_init(void)
{
printf("board init\n");
/* The non-secure watchdog is enabled in BL2 TEE, disable it */
run_command("watchdog off", 0);
printf("watchdog disable\n");
aml_set_bootsequence(0);
pinctrl_devices_active(PIN_CONTROLLER_NUM);
#ifdef CONFIG_AML_HDMITX20
hdmitx_set_hdmi_5v();
hdmitx_init();
#endif
return 0;
}
int read_gpio(const char *str_gpio)
{
unsigned int gpio;
int ret;
ret = gpio_lookup_name(str_gpio, NULL, NULL, &gpio);
if (ret) {
printf("GPIO: '%s' not found\n", str_gpio);
return -1;
}
/* grab the pin before we tweak it */
ret = gpio_request(gpio, "cmd_gpio");
if (ret && ret != -EBUSY) {
printf("gpio: requesting pin %u failed\n", gpio);
return -1;
}
gpio_direction_input(gpio);
int value = gpio_get_value(gpio);
gpio_free(gpio);
return value;
}
void env_set_board_id(void)
{
// See go/boreal-pinmux.
int hw_id[] = {read_gpio(GPIOZ_6), read_gpio(GPIOZ_7), read_gpio(GPIOZ_4)};
int hw_id_length = (int) (sizeof(hw_id) / sizeof(hw_id[0]));
int board_id = 0;
for (int i = 0; i < hw_id_length; i++)
{
if (hw_id[i] < 0) {
printf("Failed to read board id from hw_id[%d]\n", i);
return;
}
board_id += (hw_id[i] << i);
}
printf("Store board id: %d\n", board_id);
env_set_ulong("board_id", board_id);
}
int board_late_init(void)
{
printf("board late init\n");
char *env_fstab_suffix;
env_fstab_suffix = env_get("fstab_suffix");
if (!env_fstab_suffix) {
env_set("fstab_suffix", "ext4");
}
run_command("defenv_reserv", 0);
void *bootloader_buf = NULL;
int boot_idx = get_boot_index();
printf("%s: boot_idx: %#x\n", __func__, boot_idx);
if (boot_idx == BOOT_INDEX_EMMC_USER) {
// Migrate from AML partition table to GPT
// The boot address in the user partition will be occupied by GPT
bootloader_buf = malloc(CHROMECAST_BOOTLOADER_SIZE);
if (!bootloader_buf) {
printf("%s: unable to allocate memory for bootloader_buf\n",
__func__);
} else {
printf("%s: copy bootloader to boot0 and boot1\n",
__func__);
store_boot_read("bootloader", 0,
CHROMECAST_BOOTLOADER_SIZE,
bootloader_buf);
store_boot_write("bootloader", 1,
CHROMECAST_BOOTLOADER_SIZE,
bootloader_buf);
store_boot_write("bootloader", 2,
CHROMECAST_BOOTLOADER_SIZE,
bootloader_buf);
}
}
struct blk_desc *dev_desc = NULL;
dev_desc = blk_get_dev("mmc", 1);
if (dev_desc) {
init_chromecast_partitions(dev_desc, &boreal_partition_table);
load_chromecast_factory_configs(dev_desc);
} else {
printf("%s: failed to get mmc 1\n", __func__);
}
// reinit aml mmc partitions
mmc_device_init(find_mmc_device(1));
if (bootloader_buf) {
printf("%s: copy bootloader to bootloader_a/b\n", __func__);
store_write("bootloader_a", 0,
CHROMECAST_BOOTLOADER_SIZE, bootloader_buf);
store_write("bootloader_b", 0,
CHROMECAST_BOOTLOADER_SIZE, bootloader_buf);
free(bootloader_buf);
}
env_set_board_id();
// The env partition could be changed, save the env.
env_save();
env_set_hex("logo_addr", (ulong) res_images_logo_bmp_gz);
if (get_board_variant() != BOARD_VARIANT_DEV) {
// set bootdelay to -2 to not check for abort
env_set("bootdelay", "-2");
env_set("consoleargs", "console=ttynull");
env_set("board_variant", "prod");
} else {
// autoboot with no delay but can be stopped by key input
env_set("bootdelay", "0");
env_set("consoleargs", "console=ttyS0,921600 no_console_suspend earlycon=aml-uart,0xfe07a000");
env_set("board_variant", "dev");
}
if (boot_idx == BOOT_INDEX_USB) {
run_command("fastboot 0", 0);
}
board_init_mem();
run_command("run bcb_cmd", 0);
#ifdef CONFIG_AML_VPU
vpu_probe();
#endif
#ifdef CONFIG_AML_VPP
vpp_init();
#endif
#ifdef CONFIG_AML_CVBS
cvbs_init();
#endif
run_command("amlsecurecheck", 0);
run_command("update_tries", 0);
return 0;
}
phys_size_t get_effective_memsize(void)
{
// >>16 -> MB, <<20 -> real size, so >>16<<20 = <<4
#if defined(CONFIG_SYS_MEM_TOP_HIDE)
return ((readl(SYSCTRL_SEC_STATUS_REG4) & 0xFFF80000) << 4) > 0xf1000000 ? 0xf1000000 : \
(((readl(SYSCTRL_SEC_STATUS_REG4) & 0xFFF80000) << 4) - CONFIG_SYS_MEM_TOP_HIDE);
#else
return ((readl(SYSCTRL_SEC_STATUS_REG4) & 0xFFF80000) << 4) > 0xf1000000 ? 0xf1000000 : \
((readl(SYSCTRL_SEC_STATUS_REG4) & 0xFFF80000) << 4);
#endif /* CONFIG_SYS_MEM_TOP_HIDE */
}
static struct mm_region bd_mem_map[] = {
{
.virt = 0x00000000UL,
.phys = 0x00000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
.virt = 0xf1000000UL,
.phys = 0xf1000000UL,
.size = 0x0f000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* List terminator */
0,
}
};
struct mm_region *mem_map = bd_mem_map;
int mach_cpu_init(void) {
/* update mmu table from bl2 ddr auto detect size */
#ifdef CONFIG_UPDATE_MMU_TABLE
unsigned long nddrSize = ((readl(SYSCTRL_SEC_STATUS_REG4) & 0xFFF80000) << 4) > 0xf1000000 ? 0xf1000000 : \
((readl(SYSCTRL_SEC_STATUS_REG4) & 0xFFF80000) << 4);
bd_mem_map[0].size = nddrSize;
#endif
//printf("\nmach_cpu_init\n");
return 0;
}
int ft_board_setup(void *blob, bd_t *bd)
{
/* eg: bl31/32 rsv */
return 0;
}
const char * const _env_args_reserve_[] =
{
"lock",
"fstab_suffix",
"bootloader_version",
"hdr_policy",
"hdr_priority",
"hdmichecksum",
"hdmimode",
"outputmode",
"colorattribute",
"hdmi_colorspace",
"hdmi_colordepth",
"1080p60hz_deepcolor",
"1080p50hz_deepcolor",
"1080p30hz_deepcolor",
"1080p25hz_deepcolor",
"1080p24hz_deepcolor",
"720p60hz_deepcolor",
"720p50hz_deepcolor",
"1080i60hz_deepcolor",
"1080i50hz_deepcolor",
"576p50hz_deepcolor",
"480p60hz_deepcolor",
"digitaudiooutput",
"is.bestmode",
NULL//Keep NULL be last to tell END
};