diff --git a/u-boot-2020.01/board/hisilicon/hi3516dv300/hi3516dv300.c b/u-boot-2020.01/board/hisilicon/hi3516dv300/hi3516dv300.c
old mode 100755
new mode 100644
index 911b89ad5150ec5bca1a37a1f2f73623440d2edf..dffee5427cfc68b40f9152b1094ec6f130d82ec1
--- a/u-boot-2020.01/board/hisilicon/hi3516dv300/hi3516dv300.c
+++ b/u-boot-2020.01/board/hisilicon/hi3516dv300/hi3516dv300.c
@@ -1,697 +1,690 @@
-/*
- * hi3516dv300.c
- *
- * The board init for hisilicon
- *
- * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#ifdef CONFIG_AUTO_OTA_UPDATE
-#include
-#endif /* CONFIG_AUTO_OTA_UPDATE */
-#include
-#include
-
-#ifndef CONFIG_SYS_DCACHE_OFF
-void enable_caches(void)
-{
- /* Enable D-cache. I-cache is already enabled in start.S */
- dcache_enable();
-}
-#endif
-static int boot_media = BOOT_MEDIA_UNKNOWN;
-
-int get_boot_media(void)
-{
- unsigned int reg_val, boot_mode, spi_device_mode;
- int boot_media = BOOT_MEDIA_UNKNOWN;
-
- reg_val = readl(SYS_CTRL_REG_BASE + REG_SYSSTAT);
- boot_mode = get_sys_boot_mode(reg_val);
-
- switch (boot_mode) {
- case BOOT_FROM_SPI:
- spi_device_mode = get_spi_device_type(reg_val);
- if (spi_device_mode)
- boot_media = BOOT_MEDIA_NAND;
- else
- boot_media = BOOT_MEDIA_SPIFLASH;
- break;
- case BOOT_FROM_EMMC:
- boot_media = BOOT_MEDIA_EMMC;
- break;
- default:
- boot_media = BOOT_MEDIA_UNKNOWN;
- break;
- }
- return boot_media;
-}
-
-#if defined(CONFIG_SHOW_BOOT_PROGRESS)
-void show_boot_progress(int progress)
-{
- printf("Boot reached stage %d\n", progress);
-}
-#endif
-
-#define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF)
-
-static inline void delay(unsigned long loops)
-{
- __asm__ volatile("1:\n"
- "subs %0, %1, #1\n"
- "bne 1b" : "=r"(loops) : "0"(loops));
-}
-
-
-int get_text_base(void)
-{
- return CONFIG_SYS_TEXT_BASE;
-}
-
-static void boot_flag_init(void)
-{
- unsigned int reg, boot_mode, spi_device_mode;
-
- /* get boot mode */
- reg = __raw_readl(SYS_CTRL_REG_BASE + REG_SYSSTAT);
- boot_mode = get_sys_boot_mode(reg);
-
- switch (boot_mode) {
- case BOOT_FROM_SPI:
- spi_device_mode = get_spi_device_type(reg);
- if (spi_device_mode)
- boot_media = BOOT_MEDIA_NAND;
- else
- boot_media = BOOT_MEDIA_SPIFLASH;
- break;
- case BOOT_FROM_EMMC: /* emmc mode */
- boot_media = BOOT_MEDIA_EMMC;
- break;
- default:
- boot_media = BOOT_MEDIA_UNKNOWN;
- break;
- }
-}
-
-int board_early_init_f(void)
-{
- return 0;
-}
-
-#define UBOOT_DATA_ADDR 0x81000000UL
-#define UBOOT_DATA_SIZE 0x80000UL
-int data_to_spiflash(void)
-{
- static struct spi_flash *flash = NULL;
- void *buf = NULL;
-
- unsigned int val;
-
- /* 0:bus 0:cs 1000000:max_hz 0x3:spi_mode */
- flash = spi_flash_probe(0, 0, 1000000, 0x3);
- if (!flash) {
- printf("Failed to initialize SPI flash\n");
- return -1; /* -1:failed */
- }
-
- /* erase the address range. */
- printf("Spi flash erase...\n");
- val = spi_flash_erase(flash, NUM_0, UBOOT_DATA_SIZE);
- if (val) {
- printf("SPI flash sector erase failed\n");
- return 1; /* 1:failed */
- }
-
- buf = map_physmem((unsigned long)UBOOT_DATA_ADDR,
- UBOOT_DATA_SIZE, MAP_WRBACK);
- if (!buf) {
- puts("Failed to map physical memory\n");
- return 1; /* 1:failed */
- }
-
- /* copy the data from RAM to FLASH */
- printf("Spi flash write...\n");
- val = flash->write(flash, NUM_0, UBOOT_DATA_SIZE, buf);
- if (val) {
- printf("SPI flash write failed, return %u\n",
- val);
- unmap_physmem(buf, UBOOT_DATA_SIZE);
- return 1; /* 1:failed */
- }
-
- unmap_physmem(buf, UBOOT_DATA_SIZE);
- return 0; /* 0:success */
-}
-
-int data_to_nandflash(void)
-{
- struct mtd_info *nand_flash = NULL;
- void *buf = NULL;
- size_t length = UBOOT_DATA_SIZE;
- unsigned int val;
-
- nand_flash = nand_info[0];
-
- printf("Nand flash erase...\n");
- val = nand_erase(nand_flash, 0, UBOOT_DATA_SIZE);
- if (val) {
- printf("Nand flash erase failed\n");
- return 1;
- }
-
- buf = map_physmem((unsigned long)UBOOT_DATA_ADDR,
- UBOOT_DATA_SIZE, MAP_WRBACK);
- if (!buf) {
- puts("Failed to map physical memory\n");
- return 1;
- }
-
- printf("Nand flash write...\n");
- val = nand_write(nand_flash, 0, &length, buf);
- if (val) {
- printf("Nand flash write failed, return %u\n",
- val);
- unmap_physmem(buf, UBOOT_DATA_SIZE);
- return 1;
- }
-
- unmap_physmem(buf, UBOOT_DATA_SIZE);
- return 0;
-}
-
-int data_to_emmc(void)
-{
- struct mmc *mmc = find_mmc_device(0);
- void *buf = NULL;
-
- if (!mmc)
- return 1;
-
- (void)mmc_init(mmc);
-
- buf = map_physmem((unsigned long)UBOOT_DATA_ADDR,
- UBOOT_DATA_SIZE, MAP_WRBACK);
- if (!buf) {
- puts("Failed to map physical memory\n");
- return 1;
- }
-
- printf("MMC write...\n");
- blk_dwrite(mmc_get_blk_desc(mmc), 0, (UBOOT_DATA_SIZE >> NUM_9), buf);
- unmap_physmem(buf, UBOOT_DATA_SIZE);
- return 0;
-}
-int save_bootdata_to_flash(void)
-{
- unsigned int sd_update_flag = 0;
- int ret = 0;
- sd_update_flag = readl(REG_BASE_SCTL + REG_SC_GEN4);
- if (sd_update_flag == START_MAGIC) {
-#if defined(CONFIG_HIFMC)
- if (boot_media == BOOT_MEDIA_SPIFLASH) {
- ret = data_to_spiflash();
- if (ret != 0)
- return ret;
- }
- if (boot_media == BOOT_MEDIA_NAND) {
- ret = data_to_nandflash();
- if (ret != 0)
- return ret;
- }
-#endif
-#if defined(CONFIG_SUPPORT_EMMC_BOOT)
- if (boot_media == BOOT_MEDIA_EMMC) {
- ret = data_to_emmc();
- if (ret != 0)
- return ret;
- }
-#endif
-
- printf("update success!\n");
- }
-
- return 0;
-}
-
-#define REG_BASE_GPIO0 0x120d0000
-#define GPIO0_0_DATA_OFST 0x4
-#define GPIO_DIR_OFST 0x400
-
-int is_bare_program(void)
-{
- return 0;
-}
-
-#ifdef CONFIG_AUTO_OTA_UPDATE
-static int g_dev_num;
-static bool is_mmc_valid(void)
-{
- struct mmc *mmc = find_mmc_device(g_dev_num);
- if (!mmc) {
- printf("No mmc %d driver found!\n", g_dev_num);
- return false;
- }
- if (((unsigned long)mmc->block_dev.vendor[0] == 0) ||
- ((unsigned long)mmc->block_dev.product[0] == 0)) {
- printf("No SD card found!\n");
- return false;
- }
- return true;
-}
-
-static bool is_ota_tag_valid(const char *path)
-{
- char buf[64] = {0}; /* 32bytes for max in OTA_TAG_FILE */
- const char *info = "package_type:ota";
- const int len = strlen(info);
- long sz = file_fat_read(path, (void *)buf, sizeof(buf));
-
- if (sz < len) {
- printf("%s: not exist, or len %ld invalid\n", path, sz);
- return false;
- }
-
- if (strncmp(info, buf, len) != 0) {
- printf("%s info invalid\n", path);
- return false;
- }
- return true;
-}
-
-static bool is_ota(void)
-{
- char name[] = "mmc";
- struct blk_desc *stor_dev = NULL;
- bool valid = false;
-
- if (!is_mmc_valid()) {
- printf("MMC not valid\n");
- return false;
- }
-
- stor_dev = blk_get_dev(name, g_dev_num);
- if (stor_dev == NULL) {
- printf("Unknow device type!\n");
- return false;
- }
-
- if (fat_register_device(stor_dev, 1) != 0) {
- printf("Unable to use %s for fat\n", name);
- return false;
- }
-
- if (file_fat_detectfs() != 0) {
- printf("Fat-detectfs failed\n");
- return false;
- }
-
- valid = is_ota_tag_valid("/update/OTA.tag");
- printf("OTA.tag valid %d\n", valid);
- return valid;
-}
-#endif /* CONFIG_AUTO_OTA_UPDATE */
-
-static int is_auto_ota_update(void)
-{
-#ifdef CONFIG_AUTO_OTA_UPDATE
- if (is_ota())
- return 1;
-#endif
- return 0;
-}
-
-int is_auto_update(void)
-{
-#if (defined CONFIG_AUTO_SD_UPDATE) || (defined CONFIG_AUTO_USB_UPDATE)
- /* to add some judgement if neccessary */
- unsigned int val[NUM_3];
-
- writel(0, REG_BASE_GPIO0 + GPIO_DIR_OFST);
-
- val[NUM_0] = readl(REG_BASE_GPIO0 + GPIO0_0_DATA_OFST);
- if (val[NUM_0])
- return is_auto_ota_update();
-
- udelay(10000); /* delay 10000 us */
- val[NUM_1] = readl(REG_BASE_GPIO0 + GPIO0_0_DATA_OFST);
- udelay(10000); /* delay 10000 us */
- val[NUM_2] = readl(REG_BASE_GPIO0 + GPIO0_0_DATA_OFST);
- udelay(10000); /* delay 10000 us */
-
- if (val[NUM_0] == val[NUM_1] && val[NUM_1] == val[NUM_2] && val[NUM_0] == NUM_0)
- return 1; /* update enable */
- else
- return is_auto_ota_update();
-
-#else
- return is_auto_ota_update();
-#endif
-}
-
-#define EMMC_SECTOR_SIZE (1<<9)
-#define M_1 (1024*1024)
-#define MISC_LOCATION 36
-#define MAX_COMMAND_SIZE 20
-#define MAX_UPDATE_SIZE 100
-struct UpdateMessage {
- char command[MAX_COMMAND_SIZE];
- char update[MAX_UPDATE_SIZE];
-};
-
-static struct mmc *mmc;
-struct mmc *MmcBlkDevInit(int dev)
-{
- struct mmc *mmcDev;
-
- mmcDev = find_mmc_device(dev);
- if (!mmcDev) {
- printf("no mmc device at slot %x\n", dev);
- return NULL;
- }
-
- if (mmc_init(mmcDev)) {
- return NULL;
- }
- return mmcDev;
-}
-
-static int MmcBlkRead(const struct mmc *mmcDev, char *buffer, u32 blk, u32 cnt)
-{
- ulong start = (ulong)buffer;
-
- debug("\nMMC read: block # 0x%x, count 0x%x to %p... ", blk, cnt, buffer);
-
- u32 n = blk_dread(mmc_get_blk_desc(mmcDev), blk, cnt, buffer);
- /* invalidate cache after read via dma */
- invalidate_dcache_range(start, start + cnt * EMMC_SECTOR_SIZE);
- debug("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
- printf("@@@ %d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
-
- return (n == cnt) ? 0 : -EIO;
-}
-
-#define NUM_BASE 10
-int BlkDevRead(char *buffer, u32 blk, u32 cnt)
-{
- if (!mmc) {
- int devNo = env_get_ulong("mmcdev", NUM_BASE, 0);
- mmc = MmcBlkDevInit(devNo);
- if (!mmc) {
- return -ENODEV;
- }
- }
- return MmcBlkRead(mmc, buffer, blk, cnt);
-}
-
-static int g_isRecovery = 0;
-#define EMMC_SECTOR_CNT 5
-#define ARG_SZ 1000
-#define MMC_LENGTH 7
-#define UPDATE_BOOT_LENGTH 12
-#define MIN_BOOTARGS_LENGTH 100
-
-char g_bootArgsStr[ARG_SZ];
-
-static void ChangeBootArgs() // get bootargs from emmc
-{
- char *emmcBootArgs = env_get("bootargs");
- if (!emmcBootArgs) {
- printf("@@@ bootArgs from emmc is bad = NULL\n");
- return;
- }
- int emmcBootArgsLen = strlen(emmcBootArgs);
- if (emmcBootArgsLen < MIN_BOOTARGS_LENGTH) {
- printf("@@@ bootArgs from emmc is bad = %s, len=%d\n", emmcBootArgs, emmcBootArgsLen);
- return;
- }
- char *initIndex = strstr(emmcBootArgs, "init");
- char *blkIndex = strstr(emmcBootArgs, "blkdevparts");
- if (!initIndex || !blkIndex) { // error
- printf("@@@ bootArgs from emmc is bad = %s\n", emmcBootArgs);
- return;
- }
-
- if (!g_isRecovery) { // hos
- memset(g_bootArgsStr, 0, ARG_SZ);
- memcpy(g_bootArgsStr, emmcBootArgs, emmcBootArgsLen);
- printf("@@@ bootArgs final from emmc = %s\n", g_bootArgsStr);
- } else {
- printf("@@@ bootArgs final from misc = %s\n", g_bootArgsStr);
- }
-}
-
-static int EmmcInitParam() // get "boot_updater" string in misc,then set env
-{
- const char rebootHead[] = "mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M "
- "clk_ignore_unused androidboot.selinux=permissive skip_initramfs rootdelay=10 init=/init "
- "root=/dev/mmcblk0p5 rootfstype=ext4 rw blkdevparts=";
- const char defaultRebootStr[] = "mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M "
- "clk_ignore_unused androidboot.selinux=permissive skip_initramfs rootdelay=10 init=/init root=/dev/mmcblk0p5 "
- "rootfstype=ext4 rw blkdevparts=mmcblk0:1M(boot),15M(kernel),20M(updater),"
- "1M(misc),3307M(system),256M(vendor),-(userdata)";
- const char updaterHead[] = "mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M clk_ignore_unused "
- "androidboot.selinux=permissive skip_initramfs "
- "rootdelay=10 init=/updaterinit root=/dev/mmcblk0p3 rootfstype=ext4 rw blkdevparts=";
- const char defaultUpdaterStr[] = "mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M "
- "clk_ignore_unused androidboot.selinux=permissive skip_initramfs "
- "rootdelay=10 init=/updaterinit root=/dev/mmcblk0p3 rootfstype=ext4 rw blkdevparts=mmcblk0:1M(boot),"
- "15M(kernel),20M(updater),1M(misc),3307M(system),256M(vendor),-(userdata)";
- char block2[EMMC_SECTOR_SIZE*EMMC_SECTOR_CNT];
- if (BlkDevRead(block2, MISC_LOCATION*(M_1/EMMC_SECTOR_SIZE), EMMC_SECTOR_CNT) < 0) {
- return -1;
- }
-
- struct UpdateMessage *p = (struct UpdateMessage *)block2;
- block2[MAX_COMMAND_SIZE - 1] = block2[MAX_COMMAND_SIZE + MAX_UPDATE_SIZE - 1] =
- block2[EMMC_SECTOR_SIZE * EMMC_SECTOR_CNT - 1] = 0;
- p->command[0] = p->command[0] == ((char)-1) ? 0 : p->command[0];
- p->update[0] = p->update[0] == ((char)-1) ? 0 : p->update[0];
- block2[EMMC_SECTOR_SIZE * (EMMC_SECTOR_CNT - 1)] = block2[EMMC_SECTOR_SIZE * (EMMC_SECTOR_CNT - 1)] ==
- (char)-1 ? 0 : block2[EMMC_SECTOR_SIZE * (EMMC_SECTOR_CNT - 1)];
-
- g_isRecovery = memcmp(p->command, "boot_updater", UPDATE_BOOT_LENGTH) ? 0 : 1;
- unsigned int partStrLen = strlen(&block2[EMMC_SECTOR_SIZE*(EMMC_SECTOR_CNT - 1)]);
-
- if (memcmp(&block2[EMMC_SECTOR_SIZE*(EMMC_SECTOR_CNT-1)], "mmcblk0", MMC_LENGTH)) {
- if (g_isRecovery) {
- memcpy(g_bootArgsStr, defaultUpdaterStr, strlen(defaultUpdaterStr) + 1);
- } else {
- memcpy(g_bootArgsStr, defaultRebootStr, strlen(defaultRebootStr) + 1);
- }
- } else {
- if (g_isRecovery) {
- memcpy(g_bootArgsStr, updaterHead, strlen(updaterHead) + 1);
- } else {
- memcpy(g_bootArgsStr, rebootHead, strlen(rebootHead) + 1);
- }
- memcpy(g_bootArgsStr + strlen(g_bootArgsStr), &block2[EMMC_SECTOR_SIZE * (EMMC_SECTOR_CNT - 1)],
- partStrLen + 1);
- }
- printf("@@@ g_isRecovery = %d\n", g_isRecovery);
- printf("@@@ bootArgs from misc = %s\n", g_bootArgsStr);
-
- return g_isRecovery;
-}
-
-int misc_init_r(void)
-{
- const char cmdBuf[] = "mmc read 0x0 0x80000000 0x800 0x4800; bootm 0x80000000";
-
-#ifdef CONFIG_RANDOM_ETHADDR
- random_init_r();
-#endif
- env_set("verify", "n");
-
-#if (CONFIG_AUTO_UPDATE == 1)
- if (EmmcInitParam() == -1) {
- return 0;
- }
- ChangeBootArgs();
-
- env_set("bootargs", g_bootArgsStr);
- env_set("bootcmd", cmdBuf);
-
-#ifdef CFG_MMU_HANDLEOK
- dcache_stop();
-#endif
-
-#ifdef CFG_MMU_HANDLEOK
- dcache_start();
-#endif
-
-#endif
-
-#if (CONFIG_AUTO_UPDATE == 1)
-#endif
- return 0;
-}
-
-int board_init(void)
-{
- DECLARE_GLOBAL_DATA_PTR;
-
- gd->bd->bi_arch_number = MACH_TYPE_HI3516DV300;
- gd->bd->bi_boot_params = CFG_BOOT_PARAMS;
-
- boot_flag_init();
-
- return 0;
-}
-
-int dram_init(void)
-{
- DECLARE_GLOBAL_DATA_PTR;
-
- gd->ram_size = PHYS_SDRAM_1_SIZE;
- return 0;
-}
-
-void reset_cpu(ulong addr)
-{
- /* 0x12345678:writing any value will cause a reset. */
- writel(0x12345678, REG_BASE_SCTL + REG_SC_SYSRES);
- while (1);
-}
-
-int timer_init(void)
-{
- /*
- * Under uboot, 0xffffffff is set to load register,]
- * timer_clk equals BUSCLK/2/256.
- * e.g. BUSCLK equals 50M, it will roll back after 0xffffffff/timer_clk
- * 43980s equals 12hours
- */
- __raw_writel(0, CFG_TIMERBASE + REG_TIMER_CONTROL);
- __raw_writel(~0, CFG_TIMERBASE + REG_TIMER_RELOAD);
-
- /* 32 bit, periodic */
- __raw_writel(CFG_TIMER_CTRL, CFG_TIMERBASE + REG_TIMER_CONTROL);
-
- return 0;
-}
-
-int board_eth_init(bd_t *bis)
-{
- int rc = 0;
-
-#ifdef CONFIG_HISFV300_ETH
- rc = hieth_initialize(bis);
-#endif
- return rc;
-}
-
-
-#ifdef CONFIG_GENERIC_MMC
-int board_mmc_init(bd_t *bis)
-{
- int ret = 0;
- int dev_num = 0;
-
-#ifdef CONFIG_SUPPORT_EMMC_BOOT
- ret = himci_add_port(dev_num, EMMC_REG_BASE, CONFIG_HIMCI_MAX_FREQ);
- if (!ret) {
- ret = himci_probe(dev_num);
- if (ret)
- printf("No EMMC device found !\n");
- }
- dev_num++;
-#endif
-
-#ifdef CONFIG_AUTO_SD_UPDATE
-#ifdef CONFIG_AUTO_OTA_UPDATE
- ret = himci_add_port(dev_num, SDIO0_REG_BASE, CONFIG_SDIO0_FREQ);
- if (!ret) {
- ret = himci_probe(dev_num);
- if (ret)
- printf("No SD device found !\n");
- else
- g_dev_num = dev_num;
- }
-#else
- if (is_auto_update()) {
- ret = himci_add_port(dev_num, SDIO0_REG_BASE, CONFIG_SDIO0_FREQ);
- if (!ret) {
- ret = himci_probe(dev_num);
- if (ret)
- printf("No SD device found !\n");
- }
- }
-#endif
-#endif
-
- return ret;
-}
-#endif
-
-int start_other_cpus(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
-{
- /* prepare two commands for cortex-a17 */
- volatile int cmd_address = 0;
- volatile int cmd = 0xe51ff004; /* 0xe51ff004:Default liteos address. */
- unsigned int regval;
-
- if (argc < NUM_2) {
- cmd_usage(cmdtp);
- return 1;
- }
-
- flush_dcache_all();
- asm("str %0, [%1]"::"r"(cmd), "r"(cmd_address): "cc");
- cmd = simple_strtoul(argv[NUM_1], NULL, 16); /* 16:base */
- printf("starting cpu1 liteos address 0x%x\n", cmd);
- asm("str %0, [%1, #4]"::"r"(cmd), "r"(cmd_address): "cc");
- /* clear the slave cpu reset */
- /* 0x12010000:CRG base address; 0x0078:PERI_CRG30 */
- regval = readl(0x12010000 + 0x0078);
- regval &= ~(NUM_1 << NUM_2);
- /* 0x12010000:CRG base address; 0x0078:PERI_CRG30 */
- writel(regval, (0x12010000 + 0x0078));
- return 0;
-}
-
-U_BOOT_CMD(
- go_cpu1, CONFIG_SYS_MAXARGS, 0, start_other_cpus,
- "Perform power on and unreset CPU1_A7",
- "go_cpu1 \n"
- );
-
-#ifdef CONFIG_ARMV7_NONSEC
-void smp_set_core_boot_addr(unsigned long addr, int corenr)
-{
-}
-
-void smp_kick_all_cpus(void)
-{
-}
-
-void smp_waitloop(unsigned previous_address)
-{
-}
-#endif
+/*
+ * hi3516dv300.c
+ *
+ * The board init for hisilicon
+ *
+ * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifdef CONFIG_AUTO_OTA_UPDATE
+#include
+#endif /* CONFIG_AUTO_OTA_UPDATE */
+#include
+#include
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+}
+#endif
+static int boot_media = BOOT_MEDIA_UNKNOWN;
+
+int get_boot_media(void)
+{
+ unsigned int reg_val, boot_mode, spi_device_mode;
+ int boot_media = BOOT_MEDIA_UNKNOWN;
+
+ reg_val = readl(SYS_CTRL_REG_BASE + REG_SYSSTAT);
+ boot_mode = get_sys_boot_mode(reg_val);
+
+ switch (boot_mode) {
+ case BOOT_FROM_SPI:
+ spi_device_mode = get_spi_device_type(reg_val);
+ if (spi_device_mode)
+ boot_media = BOOT_MEDIA_NAND;
+ else
+ boot_media = BOOT_MEDIA_SPIFLASH;
+ break;
+ case BOOT_FROM_EMMC:
+ boot_media = BOOT_MEDIA_EMMC;
+ break;
+ default:
+ boot_media = BOOT_MEDIA_UNKNOWN;
+ break;
+ }
+ return boot_media;
+}
+
+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
+void show_boot_progress(int progress)
+{
+ printf("Boot reached stage %d\n", progress);
+}
+#endif
+
+#define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF)
+
+static inline void delay(unsigned long loops)
+{
+ __asm__ volatile("1:\n"
+ "subs %0, %1, #1\n"
+ "bne 1b" : "=r"(loops) : "0"(loops));
+}
+
+
+int get_text_base(void)
+{
+ return CONFIG_SYS_TEXT_BASE;
+}
+
+static void boot_flag_init(void)
+{
+ unsigned int reg, boot_mode, spi_device_mode;
+
+ /* get boot mode */
+ reg = __raw_readl(SYS_CTRL_REG_BASE + REG_SYSSTAT);
+ boot_mode = get_sys_boot_mode(reg);
+
+ switch (boot_mode) {
+ case BOOT_FROM_SPI:
+ spi_device_mode = get_spi_device_type(reg);
+ if (spi_device_mode)
+ boot_media = BOOT_MEDIA_NAND;
+ else
+ boot_media = BOOT_MEDIA_SPIFLASH;
+ break;
+ case BOOT_FROM_EMMC: /* emmc mode */
+ boot_media = BOOT_MEDIA_EMMC;
+ break;
+ default:
+ boot_media = BOOT_MEDIA_UNKNOWN;
+ break;
+ }
+}
+
+int board_early_init_f(void)
+{
+ return 0;
+}
+
+#define UBOOT_DATA_ADDR 0x81000000UL
+#define UBOOT_DATA_SIZE 0x80000UL
+int data_to_spiflash(void)
+{
+ static struct spi_flash *flash = NULL;
+ void *buf = NULL;
+
+ unsigned int val;
+
+ /* 0:bus 0:cs 1000000:max_hz 0x3:spi_mode */
+ flash = spi_flash_probe(0, 0, 1000000, 0x3);
+ if (!flash) {
+ printf("Failed to initialize SPI flash\n");
+ return -1; /* -1:failed */
+ }
+
+ /* erase the address range. */
+ printf("Spi flash erase...\n");
+ val = spi_flash_erase(flash, NUM_0, UBOOT_DATA_SIZE);
+ if (val) {
+ printf("SPI flash sector erase failed\n");
+ return 1; /* 1:failed */
+ }
+
+ buf = map_physmem((unsigned long)UBOOT_DATA_ADDR,
+ UBOOT_DATA_SIZE, MAP_WRBACK);
+ if (!buf) {
+ puts("Failed to map physical memory\n");
+ return 1; /* 1:failed */
+ }
+
+ /* copy the data from RAM to FLASH */
+ printf("Spi flash write...\n");
+ val = flash->write(flash, NUM_0, UBOOT_DATA_SIZE, buf);
+ if (val) {
+ printf("SPI flash write failed, return %u\n",
+ val);
+ unmap_physmem(buf, UBOOT_DATA_SIZE);
+ return 1; /* 1:failed */
+ }
+
+ unmap_physmem(buf, UBOOT_DATA_SIZE);
+ return 0; /* 0:success */
+}
+
+int data_to_nandflash(void)
+{
+ struct mtd_info *nand_flash = NULL;
+ void *buf = NULL;
+ size_t length = UBOOT_DATA_SIZE;
+ unsigned int val;
+
+ nand_flash = nand_info[0];
+
+ printf("Nand flash erase...\n");
+ val = nand_erase(nand_flash, 0, UBOOT_DATA_SIZE);
+ if (val) {
+ printf("Nand flash erase failed\n");
+ return 1;
+ }
+
+ buf = map_physmem((unsigned long)UBOOT_DATA_ADDR,
+ UBOOT_DATA_SIZE, MAP_WRBACK);
+ if (!buf) {
+ puts("Failed to map physical memory\n");
+ return 1;
+ }
+
+ printf("Nand flash write...\n");
+ val = nand_write(nand_flash, 0, &length, buf);
+ if (val) {
+ printf("Nand flash write failed, return %u\n",
+ val);
+ unmap_physmem(buf, UBOOT_DATA_SIZE);
+ return 1;
+ }
+
+ unmap_physmem(buf, UBOOT_DATA_SIZE);
+ return 0;
+}
+
+int data_to_emmc(void)
+{
+ struct mmc *mmc = find_mmc_device(0);
+ void *buf = NULL;
+
+ if (!mmc)
+ return 1;
+
+ (void)mmc_init(mmc);
+
+ buf = map_physmem((unsigned long)UBOOT_DATA_ADDR,
+ UBOOT_DATA_SIZE, MAP_WRBACK);
+ if (!buf) {
+ puts("Failed to map physical memory\n");
+ return 1;
+ }
+
+ printf("MMC write...\n");
+ blk_dwrite(mmc_get_blk_desc(mmc), 0, (UBOOT_DATA_SIZE >> NUM_9), buf);
+ unmap_physmem(buf, UBOOT_DATA_SIZE);
+ return 0;
+}
+int save_bootdata_to_flash(void)
+{
+ unsigned int sd_update_flag = 0;
+ int ret = 0;
+ sd_update_flag = readl(REG_BASE_SCTL + REG_SC_GEN4);
+ if (sd_update_flag == START_MAGIC) {
+#if defined(CONFIG_HIFMC)
+ if (boot_media == BOOT_MEDIA_SPIFLASH) {
+ ret = data_to_spiflash();
+ if (ret != 0)
+ return ret;
+ }
+ if (boot_media == BOOT_MEDIA_NAND) {
+ ret = data_to_nandflash();
+ if (ret != 0)
+ return ret;
+ }
+#endif
+#if defined(CONFIG_SUPPORT_EMMC_BOOT)
+ if (boot_media == BOOT_MEDIA_EMMC) {
+ ret = data_to_emmc();
+ if (ret != 0)
+ return ret;
+ }
+#endif
+
+ printf("update success!\n");
+ }
+
+ return 0;
+}
+
+#define REG_BASE_GPIO0 0x120d0000
+#define GPIO0_0_DATA_OFST 0x4
+#define GPIO_DIR_OFST 0x400
+
+int is_bare_program(void)
+{
+ return 0;
+}
+
+#ifdef CONFIG_AUTO_OTA_UPDATE
+static int g_dev_num;
+static bool is_mmc_valid(void)
+{
+ struct mmc *mmc = find_mmc_device(g_dev_num);
+ if (!mmc) {
+ printf("No mmc %d driver found!\n", g_dev_num);
+ return false;
+ }
+ if (((unsigned long)mmc->block_dev.vendor[0] == 0) ||
+ ((unsigned long)mmc->block_dev.product[0] == 0)) {
+ printf("No SD card found!\n");
+ return false;
+ }
+ return true;
+}
+
+static bool is_ota_tag_valid(const char *path)
+{
+ char buf[64] = {0}; /* 32bytes for max in OTA_TAG_FILE */
+ const char *info = "package_type:ota";
+ const int len = strlen(info);
+ long sz = file_fat_read(path, (void *)buf, sizeof(buf));
+
+ if (sz < len) {
+ printf("%s: not exist, or len %ld invalid\n", path, sz);
+ return false;
+ }
+
+ if (strncmp(info, buf, len) != 0) {
+ printf("%s info invalid\n", path);
+ return false;
+ }
+ return true;
+}
+
+static bool is_ota(void)
+{
+ char name[] = "mmc";
+ struct blk_desc *stor_dev = NULL;
+ bool valid = false;
+
+ if (!is_mmc_valid()) {
+ printf("MMC not valid\n");
+ return false;
+ }
+
+ stor_dev = blk_get_dev(name, g_dev_num);
+ if (stor_dev == NULL) {
+ printf("Unknow device type!\n");
+ return false;
+ }
+
+ if (fat_register_device(stor_dev, 1) != 0) {
+ printf("Unable to use %s for fat\n", name);
+ return false;
+ }
+
+ if (file_fat_detectfs() != 0) {
+ printf("Fat-detectfs failed\n");
+ return false;
+ }
+
+ valid = is_ota_tag_valid("/update/OTA.tag");
+ printf("OTA.tag valid %d\n", valid);
+ return valid;
+}
+#endif /* CONFIG_AUTO_OTA_UPDATE */
+
+static int is_auto_ota_update(void)
+{
+#ifdef CONFIG_AUTO_OTA_UPDATE
+ if (is_ota())
+ return 1;
+#endif
+ return 0;
+}
+
+int is_auto_update(void)
+{
+#if (defined CONFIG_AUTO_SD_UPDATE) || (defined CONFIG_AUTO_USB_UPDATE)
+ /* to add some judgement if neccessary */
+ unsigned int val[NUM_3];
+
+ writel(0, REG_BASE_GPIO0 + GPIO_DIR_OFST);
+
+ val[NUM_0] = readl(REG_BASE_GPIO0 + GPIO0_0_DATA_OFST);
+ if (val[NUM_0])
+ return is_auto_ota_update();
+
+ udelay(10000); /* delay 10000 us */
+ val[NUM_1] = readl(REG_BASE_GPIO0 + GPIO0_0_DATA_OFST);
+ udelay(10000); /* delay 10000 us */
+ val[NUM_2] = readl(REG_BASE_GPIO0 + GPIO0_0_DATA_OFST);
+ udelay(10000); /* delay 10000 us */
+
+ if (val[NUM_0] == val[NUM_1] && val[NUM_1] == val[NUM_2] && val[NUM_0] == NUM_0)
+ return 1; /* update enable */
+ else
+ return is_auto_ota_update();
+
+#else
+ return is_auto_ota_update();
+#endif
+}
+
+#define EMMC_SECTOR_SIZE (1<<9)
+#define M_1 (1024*1024)
+#define MISC_LOCATION 36
+#define MAX_COMMAND_SIZE 20
+#define MAX_UPDATE_SIZE 100
+struct UpdateMessage {
+ char command[MAX_COMMAND_SIZE];
+ char update[MAX_UPDATE_SIZE];
+};
+
+static struct mmc *mmc;
+struct mmc *MmcBlkDevInit(int dev)
+{
+ struct mmc *mmcDev;
+
+ mmcDev = find_mmc_device(dev);
+ if (!mmcDev) {
+ printf("no mmc device at slot %x\n", dev);
+ return NULL;
+ }
+
+ if (mmc_init(mmcDev)) {
+ return NULL;
+ }
+ return mmcDev;
+}
+
+static int MmcBlkRead(const struct mmc *mmcDev, char *buffer, u32 blk, u32 cnt)
+{
+ ulong start = (ulong)buffer;
+
+ debug("\nMMC read: block # 0x%x, count 0x%x to %p... ", blk, cnt, buffer);
+
+ u32 n = blk_dread(mmc_get_blk_desc(mmcDev), blk, cnt, buffer);
+ /* invalidate cache after read via dma */
+ invalidate_dcache_range(start, start + cnt * EMMC_SECTOR_SIZE);
+ debug("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
+ printf("@@@ %d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
+
+ return (n == cnt) ? 0 : -EIO;
+}
+
+#define NUM_BASE 10
+int BlkDevRead(char *buffer, u32 blk, u32 cnt)
+{
+ if (!mmc) {
+ int devNo = env_get_ulong("mmcdev", NUM_BASE, 0);
+ mmc = MmcBlkDevInit(devNo);
+ if (!mmc) {
+ return -ENODEV;
+ }
+ }
+ return MmcBlkRead(mmc, buffer, blk, cnt);
+}
+
+static int g_isRecovery = 0;
+#define EMMC_SECTOR_CNT 5
+#define ARG_SZ 1000
+#define MMC_LENGTH 7
+#define UPDATE_BOOT_LENGTH 12
+#define MIN_BOOTARGS_LENGTH 10
+
+char g_bootArgsStr[ARG_SZ];
+
+static void ChangeBootArgs() // get bootargs from emmc
+{
+ char *emmcBootArgs = env_get("bootargs");
+ if (!emmcBootArgs) {
+ printf("@@@ bootArgs from emmc is bad = NULL\n");
+ return;
+ }
+ int emmcBootArgsLen = strlen(emmcBootArgs);
+ if (emmcBootArgsLen < MIN_BOOTARGS_LENGTH) {
+ printf("@@@ bootArgs from emmc is bad = %s, len=%d\n", emmcBootArgs, emmcBootArgsLen);
+ return;
+ }
+ if (!g_isRecovery) { // hos
+ memset(g_bootArgsStr, 0, ARG_SZ);
+ memcpy(g_bootArgsStr, emmcBootArgs, emmcBootArgsLen);
+ printf("@@@ bootArgs final from emmc = %s\n", g_bootArgsStr);
+ } else {
+ printf("@@@ bootArgs final from misc = %s\n", g_bootArgsStr);
+ }
+}
+
+static int EmmcInitParam() // get "boot_updater" string in misc,then set env
+{
+ const char rebootHead[] = "mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M "
+ "clk_ignore_unused androidboot.selinux=permissive skip_initramfs rootdelay=10 init=/init "
+ "root=/dev/mmcblk0p5 rootfstype=ext4 rw blkdevparts=";
+ const char defaultRebootStr[] = "mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M "
+ "clk_ignore_unused androidboot.selinux=permissive skip_initramfs rootdelay=10 init=/init root=/dev/mmcblk0p5 "
+ "rootfstype=ext4 rw blkdevparts=mmcblk0:1M(boot),15M(kernel),20M(updater),"
+ "1M(misc),3307M(system),256M(vendor),-(userdata)";
+ const char updaterHead[] = "mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M clk_ignore_unused "
+ "androidboot.selinux=permissive skip_initramfs "
+ "rootdelay=10 init=/updaterinit root=/dev/mmcblk0p3 rootfstype=ext4 rw blkdevparts=";
+ const char defaultUpdaterStr[] = "mem=640M console=ttyAMA0,115200 mmz=anonymous,0,0xA8000000,384M "
+ "clk_ignore_unused androidboot.selinux=permissive skip_initramfs "
+ "rootdelay=10 init=/updaterinit root=/dev/mmcblk0p3 rootfstype=ext4 rw blkdevparts=mmcblk0:1M(boot),"
+ "15M(kernel),20M(updater),1M(misc),3307M(system),256M(vendor),-(userdata)";
+ char block2[EMMC_SECTOR_SIZE*EMMC_SECTOR_CNT];
+ if (BlkDevRead(block2, MISC_LOCATION*(M_1/EMMC_SECTOR_SIZE), EMMC_SECTOR_CNT) < 0) {
+ return -1;
+ }
+
+ struct UpdateMessage *p = (struct UpdateMessage *)block2;
+ block2[MAX_COMMAND_SIZE - 1] = block2[MAX_COMMAND_SIZE + MAX_UPDATE_SIZE - 1] =
+ block2[EMMC_SECTOR_SIZE * EMMC_SECTOR_CNT - 1] = 0;
+ p->command[0] = p->command[0] == ((char)-1) ? 0 : p->command[0];
+ p->update[0] = p->update[0] == ((char)-1) ? 0 : p->update[0];
+ block2[EMMC_SECTOR_SIZE * (EMMC_SECTOR_CNT - 1)] = block2[EMMC_SECTOR_SIZE * (EMMC_SECTOR_CNT - 1)] ==
+ (char)-1 ? 0 : block2[EMMC_SECTOR_SIZE * (EMMC_SECTOR_CNT - 1)];
+
+ g_isRecovery = memcmp(p->command, "boot_updater", UPDATE_BOOT_LENGTH) ? 0 : 1;
+ unsigned int partStrLen = strlen(&block2[EMMC_SECTOR_SIZE*(EMMC_SECTOR_CNT - 1)]);
+
+ if (memcmp(&block2[EMMC_SECTOR_SIZE*(EMMC_SECTOR_CNT-1)], "mmcblk0", MMC_LENGTH)) {
+ if (g_isRecovery) {
+ memcpy(g_bootArgsStr, defaultUpdaterStr, strlen(defaultUpdaterStr) + 1);
+ } else {
+ memcpy(g_bootArgsStr, defaultRebootStr, strlen(defaultRebootStr) + 1);
+ }
+ } else {
+ if (g_isRecovery) {
+ memcpy(g_bootArgsStr, updaterHead, strlen(updaterHead) + 1);
+ } else {
+ memcpy(g_bootArgsStr, rebootHead, strlen(rebootHead) + 1);
+ }
+ memcpy(g_bootArgsStr + strlen(g_bootArgsStr), &block2[EMMC_SECTOR_SIZE * (EMMC_SECTOR_CNT - 1)],
+ partStrLen + 1);
+ }
+ printf("@@@ g_isRecovery = %d\n", g_isRecovery);
+ printf("@@@ bootArgs from misc = %s\n", g_bootArgsStr);
+
+ return g_isRecovery;
+}
+
+int misc_init_r(void)
+{
+ const char cmdBuf[] = "mmc read 0x0 0x80000000 0x800 0x4800; bootm 0x80000000";
+
+#ifdef CONFIG_RANDOM_ETHADDR
+ random_init_r();
+#endif
+ env_set("verify", "n");
+
+#if (CONFIG_AUTO_UPDATE == 1)
+ if (EmmcInitParam() == -1) {
+ return 0;
+ }
+ ChangeBootArgs();
+
+ env_set("bootargs", g_bootArgsStr);
+ env_set("bootcmd", cmdBuf);
+
+#ifdef CFG_MMU_HANDLEOK
+ dcache_stop();
+#endif
+
+#ifdef CFG_MMU_HANDLEOK
+ dcache_start();
+#endif
+
+#endif
+
+#if (CONFIG_AUTO_UPDATE == 1)
+#endif
+ return 0;
+}
+
+int board_init(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ gd->bd->bi_arch_number = MACH_TYPE_HI3516DV300;
+ gd->bd->bi_boot_params = CFG_BOOT_PARAMS;
+
+ boot_flag_init();
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ gd->ram_size = PHYS_SDRAM_1_SIZE;
+ return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+ /* 0x12345678:writing any value will cause a reset. */
+ writel(0x12345678, REG_BASE_SCTL + REG_SC_SYSRES);
+ while (1);
+}
+
+int timer_init(void)
+{
+ /*
+ * Under uboot, 0xffffffff is set to load register,]
+ * timer_clk equals BUSCLK/2/256.
+ * e.g. BUSCLK equals 50M, it will roll back after 0xffffffff/timer_clk
+ * 43980s equals 12hours
+ */
+ __raw_writel(0, CFG_TIMERBASE + REG_TIMER_CONTROL);
+ __raw_writel(~0, CFG_TIMERBASE + REG_TIMER_RELOAD);
+
+ /* 32 bit, periodic */
+ __raw_writel(CFG_TIMER_CTRL, CFG_TIMERBASE + REG_TIMER_CONTROL);
+
+ return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+ int rc = 0;
+
+#ifdef CONFIG_HISFV300_ETH
+ rc = hieth_initialize(bis);
+#endif
+ return rc;
+}
+
+
+#ifdef CONFIG_GENERIC_MMC
+int board_mmc_init(bd_t *bis)
+{
+ int ret = 0;
+ int dev_num = 0;
+
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+ ret = himci_add_port(dev_num, EMMC_REG_BASE, CONFIG_HIMCI_MAX_FREQ);
+ if (!ret) {
+ ret = himci_probe(dev_num);
+ if (ret)
+ printf("No EMMC device found !\n");
+ }
+ dev_num++;
+#endif
+
+#ifdef CONFIG_AUTO_SD_UPDATE
+#ifdef CONFIG_AUTO_OTA_UPDATE
+ ret = himci_add_port(dev_num, SDIO0_REG_BASE, CONFIG_SDIO0_FREQ);
+ if (!ret) {
+ ret = himci_probe(dev_num);
+ if (ret)
+ printf("No SD device found !\n");
+ else
+ g_dev_num = dev_num;
+ }
+#else
+ if (is_auto_update()) {
+ ret = himci_add_port(dev_num, SDIO0_REG_BASE, CONFIG_SDIO0_FREQ);
+ if (!ret) {
+ ret = himci_probe(dev_num);
+ if (ret)
+ printf("No SD device found !\n");
+ }
+ }
+#endif
+#endif
+
+ return ret;
+}
+#endif
+
+int start_other_cpus(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ /* prepare two commands for cortex-a17 */
+ volatile int cmd_address = 0;
+ volatile int cmd = 0xe51ff004; /* 0xe51ff004:Default liteos address. */
+ unsigned int regval;
+
+ if (argc < NUM_2) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ flush_dcache_all();
+ asm("str %0, [%1]"::"r"(cmd), "r"(cmd_address): "cc");
+ cmd = simple_strtoul(argv[NUM_1], NULL, 16); /* 16:base */
+ printf("starting cpu1 liteos address 0x%x\n", cmd);
+ asm("str %0, [%1, #4]"::"r"(cmd), "r"(cmd_address): "cc");
+ /* clear the slave cpu reset */
+ /* 0x12010000:CRG base address; 0x0078:PERI_CRG30 */
+ regval = readl(0x12010000 + 0x0078);
+ regval &= ~(NUM_1 << NUM_2);
+ /* 0x12010000:CRG base address; 0x0078:PERI_CRG30 */
+ writel(regval, (0x12010000 + 0x0078));
+ return 0;
+}
+
+U_BOOT_CMD(
+ go_cpu1, CONFIG_SYS_MAXARGS, 0, start_other_cpus,
+ "Perform power on and unreset CPU1_A7",
+ "go_cpu1 \n"
+ );
+
+#ifdef CONFIG_ARMV7_NONSEC
+void smp_set_core_boot_addr(unsigned long addr, int corenr)
+{
+}
+
+void smp_kick_all_cpus(void)
+{
+}
+
+void smp_waitloop(unsigned previous_address)
+{
+}
+#endif