blob: 31dc66a1bff63e36b44ec8eb9cb2402b9463c7ed [file] [log] [blame]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include <common.h>
#include <asm/io.h>
#include <malloc.h>
#include <errno.h>
#include <environment.h>
#include <fdt_support.h>
#include <linux/libfdt.h>
#include <amlogic/cpu_id.h>
#include <asm/arch/secure_apb.h>
#include <asm/arch/pinctrl_init.h>
#include <linux/sizes.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 <linux/mtd/partitions.h>
#include <asm/arch/bl31_apis.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_ext.h>
#endif
#ifdef CONFIG_AML_CVBS
#include <amlogic/media/vout/aml_cvbs.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
void sys_led_init(void)
{
}
int serial_set_pin_port(unsigned long port_base)
{
return 0;
}
int dram_init(void)
{
gd->ram_size = PHYS_SDRAM_1_SIZE;
return 0;
}
/* secondary_boot_func
* this function should be write with asm, here, is is only for compiling pass
* */
void secondary_boot_func(void)
{
}
int board_eth_init(bd_t *bis)
{
return 0;
}
int active_clk(void)
{
struct udevice *clk = NULL;
int err;
err = uclass_get_device_by_name(UCLASS_CLK,
"xtal-clk", &clk);
if (err) {
pr_err("Can't find xtal-clk clock (%d)\n", err);
return err;
}
err = uclass_get_device_by_name(UCLASS_CLK,
"clock-controller@0", &clk);
if (err) {
pr_err("Can't find clock-controller@0 clock (%d)\n", err);
return err;
}
return 0;
}
#ifdef CONFIG_AML_HDMITX20
static void hdmitx_set_hdmi_5v(void)
{
/*Power on VCC_5V for HDMI_5V*/
}
#endif
static const char ddr_type_info[6][8] =
{
"DDR3\0", //CONFIG_DDR_TYPE_DDR3 //0
"DDR4\0", //CONFIG_DDR_TYPE_DDR4 //1
"LPDDR4\0", //CONFIG_DDR_TYPE_LPDDR4 //2
"LPDDR3\0", //CONFIG_DDR_TYPE_LPDDR3 //3
"LPDDR2\0", //CONFIG_DDR_TYPE_LPDDR2 //4
"LPDDR4X\0", //CONFIG_DDR_TYPE_LPDDR4X //5
};
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;
unsigned int ddr_type;
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);
}
env_tmp = env_get("boot_ddr_type");
if (!env_tmp) {
ddr_type = (((readl(SYSCTRL_SEC_STATUS_REG4)) & 0x00070000) >> 16);
env_set("boot_ddr_type", 0);
env_set("boot_ddr_type", ddr_type_info[ddr_type]);
}
#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);
//Please keep try usb boot first in board_init, as other init before usb may cause burning failure
#if defined(CONFIG_AML_V3_FACTORY_BURN) && defined(CONFIG_AML_V3_USB_TOOl)
if ((0x1b8ec003 != readl(SYSCTRL_SEC_STICKY_REG2)) && (0x1b8ec004 != readl(SYSCTRL_SEC_STICKY_REG2)))
{ aml_v3_factory_usb_burning(0, gd->bd); }
#endif//#if defined(CONFIG_AML_V3_FACTORY_BURN) && defined(CONFIG_AML_V3_USB_TOOl)
#if 0
active_clk();
#endif
pinctrl_devices_active(PIN_CONTROLLER_NUM);
run_command("gpio clr GPIOH_8", 0);
#ifdef CONFIG_AML_HDMITX20
hdmitx_set_hdmi_5v();
hdmitx_init();
#endif
return 0;
}
int board_late_init(void)
{
printf("board late init\n");
//default uboot env need before anyone use it
if (env_get("default_env")) {
printf("factory reset, need default all uboot env.\n");
run_command("defenv_reserv; setenv upgrade_step 2; saveenv;", 0);
}
run_command("echo upgrade_step $upgrade_step; if itest ${upgrade_step} == 1; then "\
"defenv_reserv; setenv upgrade_step 2; saveenv; fi;", 0);
board_init_mem();
run_command("run bcb_cmd", 0);
#ifndef CONFIG_SYSTEM_RTOS //prue rtos not need dtb
if ( run_command("run common_dtb_load", 0) ) {
printf("Fail in load dtb with cmd[%s]\n", env_get("common_dtb_load"));
} else {
//load dtb here then users can directly use 'fdt' command
run_command("if fdt addr ${dtb_mem_addr}; then else echo no valid dtb at ${dtb_mem_addr};fi;", 0);
}
#endif//#ifndef CONFIG_SYSTEM_RTOS //prue rtos not need dtb
#ifdef CONFIG_AML_FACTORY_BURN_LOCAL_UPGRADE //try auto upgrade from ext-sdcard
aml_try_factory_sdcard_burning(0, gd->bd);
#endif//#ifdef CONFIG_AML_FACTORY_BURN_LOCAL_UPGRADE
//auto enter usb mode after board_late_init if 'adnl.exe setvar burnsteps 0x1b8ec003'
#if defined(CONFIG_AML_V3_FACTORY_BURN) && defined(CONFIG_AML_V3_USB_TOOl)
if (0x1b8ec003 == readl(SYSCTRL_SEC_STICKY_REG2))
{ aml_v3_factory_usb_burning(0, gd->bd); }
#endif//#if defined(CONFIG_AML_V3_FACTORY_BURN) && defined(CONFIG_AML_V3_USB_TOOl)
/* reset vout init state */
run_command("setenv vout_init disable", 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;
}
unsigned int get_ddr_memsize(void)
{
unsigned int ddr_size;
#if 0
/*if soc don't support automatic get ddr size,
then it get ddr size with software method*/
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
ddr_size += gd->bd->bi_dram[i].size;
}
#if defined(CONFIG_SYS_MEM_TOP_HIDE)
ddr_size += CONFIG_SYS_MEM_TOP_HIDE;
#endif
#else
/*auto get ddr size from hardware method*/
ddr_size = ((readl(SYSCTRL_SEC_STATUS_REG4)) & 0xFFFF0000) << 4;
#endif
return ddr_size;
}
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) - CONFIG_SYS_MEM_TOP_HIDE;
#else
return (((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 int nddrSize = ((readl(SYSCTRL_SEC_STATUS_REG4)) & 0xFFF80000) << 4;
switch (nddrSize)
{
case (CONFIG_1G_SIZE):
case (CONFIG_2G_SIZE):
case (CONFIG_3G_SIZE):
case (CONFIG_DDR_MAX_SIZE):
bd_mem_map[0].size = nddrSize;
break;
default :
printf("aml log : ERROR DDR detect size not match MMU !");
break;
}
#endif
//printf("\nmach_cpu_init\n");
return 0;
}
int ft_board_setup(void *blob, bd_t *bd)
{
/* eg: bl31/32 rsv */
return 0;
}
/* partition table for spinor flash */
#ifdef CONFIG_SPI_FLASH
static const struct mtd_partition spiflash_partitions[] = {
{
.name = "env",
.offset = 0,
.size = 1 * SZ_256K,
},
{
.name = "dtb",
.offset = 0,
.size = 1 * SZ_256K,
},
{
.name = "boot",
.offset = 0,
.size = 1 * SZ_1M,
},
/* last partition get the rest capacity */
{
.name = "user",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};
const struct mtd_partition *get_spiflash_partition_table(int *partitions)
{
*partitions = ARRAY_SIZE(spiflash_partitions);
return spiflash_partitions;
}
uint64_t spiflash_bootloader_size(void)
{
return 3 * SZ_1M;
}
#endif /* CONFIG_SPI_FLASH */
#ifdef CONFIG_MESON_NFC
static struct mtd_partition normal_partition_info[] = {
{
.name = BOOT_BL2E,
.offset = 0,
.size = 0,
},
{
.name = BOOT_BL2X,
.offset = 0,
.size = 0,
},
{
.name = BOOT_DDRFIP,
.offset = 0,
.size = 0,
},
{
.name = BOOT_DEVFIP,
.offset = 0,
.size = 0,
},
{
.name = "logo",
.offset = 0,
.size = 2*SZ_1M,
},
{
.name = "recovery",
.offset = 0,
.size = 16*SZ_1M,
},
{
.name = "boot",
.offset = 0,
.size = 16*SZ_1M,
},
{
.name = "system",
.offset = 0,
.size = 64*SZ_1M,
},
/* last partition get the rest capacity */
{
.name = "data",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
struct mtd_partition *get_aml_mtd_partition(void)
{
return normal_partition_info;
}
int get_aml_partition_count(void)
{
return ARRAY_SIZE(normal_partition_info);
}
#endif
/* partition table */
/* partition table for spinand flash */
#if (defined(CONFIG_SPI_NAND) || defined(CONFIG_MTD_SPI_NAND))
static const struct mtd_partition spinand_partitions[] = {
{
.name = "logo",
.offset = 0,
.size = 2 * SZ_1M,
},
{
.name = "recovery",
.offset = 0,
.size = 16 * SZ_1M,
},
{
.name = "boot",
.offset = 0,
.size = 16 * SZ_1M,
},
{
.name = "system",
.offset = 0,
.size = 64 * SZ_1M,
},
/* last partition get the rest capacity */
{
.name = "data",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};
const struct mtd_partition *get_spinand_partition_table(int *partitions)
{
*partitions = ARRAY_SIZE(spinand_partitions);
return spinand_partitions;
}
#endif /* CONFIG_SPI_NAND */
#ifdef CONFIG_MULTI_DTB
int checkhw(char * name)
{
#ifdef CONFIG_AUTO_ADAPT_DDR_DTB
unsigned int ddr_size = 0;
char loc_name[64] = {0};
char *mem_size = env_get("mem_size");
ddr_size = get_ddr_memsize();
printf("%s:%d ddr_size:0x%x\r\n",__func__,__LINE__,ddr_size);
switch (ddr_size) {
case CONFIG_2G_SIZE:
strcpy(loc_name, "sc2_s905c2_232\0");
/* if limit memory size */
if (mem_size && !strcmp(mem_size, "1g")) {
strcpy(loc_name, "sc2_s905c2_232-1g\0");
}
break;
case CONFIG_1G_SIZE:
strcpy(loc_name, "sc2_s905c2_232-1g\0");
break;
case CONFIG_3G_SIZE:
strcpy(loc_name, "sc2_s905c2_232-3g\0");
break;
case CONFIG_DDR_MAX_SIZE:
strcpy(loc_name, "sc2_s905c2_232-4g\0");
break;
default:
printf("DDR size: 0x%x, multi-dt doesn't support\n", ddr_size);
strcpy(loc_name, "sc2_s905c2_232_unsupport\0");
break;
}
strcpy(name, loc_name);
env_set("aml_dt", loc_name);
return 0;
#else
strcpy(name, "sc2_s905c2_232\0");
env_set("aml_dt", "sc2_s905c2_232\0");
return 0;
#endif
}
#endif
const char * const _env_args_reserve_[] =
{
"lock",
"upgrade_step",
"bootloader_version",
NULL//Keep NULL be last to tell END
};
int __attribute__((weak)) mmc_initialize(bd_t *bis){ return 0;}
int __attribute__((weak)) do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]){ return 0;}
void __attribute__((weak)) set_working_fdt_addr(ulong addr) {}
int __attribute__((weak)) ofnode_read_u32_default(ofnode node, const char *propname, u32 def) {return 0;}
void __attribute__((weak)) md5_wd (unsigned char *input, int len, unsigned char output[16], unsigned int chunk_sz){}