/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright 2019 Broadcom Ltd. */ #include #include #include #include "boot_flash.h" #ifdef CONFIG_MMC #define MMC_DEV_NUM 0 #define MMC_BOOT_HWPART 1 #define MMC_USERDATA_PART 0 #endif /* for emmc and spi flash*/ void* flash_dev; int boot_flash_init(void) { flash_dev = NULL; #ifdef CONFIG_NAND nand_init(); #endif #if defined(CONFIG_MMC) && defined(CONFIG_SUPPORT_EMMC_BOOT) struct mmc *mmc; int ret; ret = mmc_initialize(NULL); if(ret) { printf("MMC Initialization Failed!!\n"); hang(); } mmc = find_mmc_device(MMC_DEV_NUM); mmc_init(mmc); #endif #if defined(CONFIG_SPL_SPI_FLASH_SUPPORT) struct udevice *dev; struct mtd_info *mtd; int ret = -1; ret = uclass_get_device_by_driver(UCLASS_SPI_FLASH, DM_GET_DRIVER(spi_flash_std), &dev); if (ret){ debug("SPI NOR failed to initialize. (error %d)\n", ret); hang(); } mtd = get_mtd_device_nm(SPIFLASH_MTDNAME); if (IS_ERR_OR_NULL(mtd)){ printf("%s:MTD device %s not found, ret %ld\n",__func__, SPIFLASH_MTDNAME, PTR_ERR(mtd)); hang(); } else flash_dev = mtd; #endif return 0; } /* return number of bytes read if success, negative value if fail */ int read_boot_device(uint32_t address, void *data, int len) { int ret; #if defined(CONFIG_SPL_SPI_FLASH_SUPPORT) size_t retlen; debug("read_boot_device:address=%d,len=%d\n",address,len); if ( flash_dev != NULL){ ret = mtd_read(flash_dev, address, len, &retlen, data); if ( ret == 0) ret = retlen; else{ debug("%s: Failed to read from SPI flash (err=%d)\n", __func__, ret); ret = -1; } } else ret = -1; #endif #ifdef CONFIG_NAND /* unfortunately nand spl api does not return the length.. */ ret = nand_spl_load_image(address, len, data); if (ret == 0) ret = len; else ret = -1; #endif #if defined(CONFIG_MMC) && defined(CONFIG_SUPPORT_EMMC_BOOT) blk_select_hwpart_devnum(IF_TYPE_MMC, MMC_DEV_NUM, MMC_BOOT_HWPART); /* Unfortunately mmc_spl_load_image has no return code */ mmc_spl_load_image(address, len, data); ret = len; blk_select_hwpart_devnum(IF_TYPE_MMC, MMC_DEV_NUM, MMC_USERDATA_PART); #endif #if defined(CONFIG_SPL_XIP_SUPPORT) memcpy((uint8_t*)data, (uint8_t*)(address+NOR_XIP_BASE_ADDR), len); #endif return ret; }