diff options
author | Rajesh Bhagat <rajesh.bhagat@nxp.com> | 2018-11-05 18:02:23 +0000 |
---|---|---|
committer | York Sun <york.sun@nxp.com> | 2018-12-06 14:37:42 -0800 |
commit | 382c53f94631027782ead8147847906b1dcc5d11 (patch) | |
tree | 4dc993a773088cca46d16f1bb19ef94cee7da78e | |
parent | 2e17cb8a42404201298c53fe752327f59db6ff8e (diff) |
net: fm: add TFABOOT support
Adds TFABOOT support and allows to pick FMAN firmware
on basis of boot source.
Signed-off-by: Pankit Garg <pankit.garg@nxp.com>
Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
[YS: fix checkpatch issues]
Reviewed-by: York Sun <york.sun@nxp.com>
-rw-r--r-- | drivers/net/fm/fm.c | 103 |
1 files changed, 100 insertions, 3 deletions
diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c index c5cf188f05..e19d7777dc 100644 --- a/drivers/net/fm/fm.c +++ b/drivers/net/fm/fm.c @@ -11,12 +11,14 @@ #include "fm.h" #include <fsl_qe.h> /* For struct qe_firmware */ -#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND #include <nand.h> -#elif defined(CONFIG_SYS_QE_FW_IN_SPIFLASH) #include <spi_flash.h> -#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_MMC) #include <mmc.h> +#include <environment.h> + +#ifdef CONFIG_ARM64 +#include <asm/armv8/mmu.h> +#include <asm/arch/cpu.h> #endif struct fm_muram muram[CONFIG_SYS_NUM_FMAN]; @@ -347,6 +349,100 @@ static void fm_init_qmi(struct fm_qmi_common *qmi) } /* Init common part of FM, index is fm num# like fm as above */ +#ifdef CONFIG_TFABOOT +int fm_init_common(int index, struct ccsr_fman *reg) +{ + int rc; + void *addr = NULL; + enum boot_src src = get_boot_src(); + + if (src == BOOT_SOURCE_IFC_NOR) { + addr = (void *)(CONFIG_SYS_FMAN_FW_ADDR + + CONFIG_SYS_FSL_IFC_BASE); + } else if (src == BOOT_SOURCE_IFC_NAND) { + size_t fw_length = CONFIG_SYS_QE_FMAN_FW_LENGTH; + + addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH); + + rc = nand_read(get_nand_dev_by_index(0), + (loff_t)CONFIG_SYS_FMAN_FW_ADDR, + &fw_length, (u_char *)addr); + if (rc == -EUCLEAN) { + printf("NAND read of FMAN firmware at offset 0x%x failed %d\n", + CONFIG_SYS_FMAN_FW_ADDR, rc); + } + } else if (src == BOOT_SOURCE_QSPI_NOR) { + struct spi_flash *ucode_flash; + + addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH); + int ret = 0; + +#ifdef CONFIG_DM_SPI_FLASH + struct udevice *new; + + /* speed and mode will be read from DT */ + ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, + CONFIG_ENV_SPI_CS, 0, 0, &new); + + ucode_flash = dev_get_uclass_priv(new); +#else + ucode_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, + CONFIG_ENV_SPI_CS, + CONFIG_ENV_SPI_MAX_HZ, + CONFIG_ENV_SPI_MODE); +#endif + if (!ucode_flash) { + printf("SF: probe for ucode failed\n"); + } else { + ret = spi_flash_read(ucode_flash, + CONFIG_SYS_FMAN_FW_ADDR + + CONFIG_SYS_FSL_QSPI_BASE, + CONFIG_SYS_QE_FMAN_FW_LENGTH, + addr); + if (ret) + printf("SF: read for ucode failed\n"); + spi_flash_free(ucode_flash); + } + } else if (src == BOOT_SOURCE_SD_MMC) { + int dev = CONFIG_SYS_MMC_ENV_DEV; + + addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH); + u32 cnt = CONFIG_SYS_QE_FMAN_FW_LENGTH / 512; + u32 blk = CONFIG_SYS_FMAN_FW_ADDR / 512; + struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); + + if (!mmc) { + printf("\nMMC cannot find device for ucode\n"); + } else { + printf("\nMMC read: dev # %u, block # %u, count %u ...\n", + dev, blk, cnt); + mmc_init(mmc); + (void)blk_dread(mmc_get_blk_desc(mmc), blk, cnt, + addr); + } + } else { + addr = NULL; + } + + /* Upload the Fman microcode if it's present */ + rc = fman_upload_firmware(index, ®->fm_imem, addr); + if (rc) + return rc; + env_set_addr("fman_ucode", addr); + + fm_init_muram(index, ®->muram); + fm_init_qmi(®->fm_qmi_common); + fm_init_fpm(®->fm_fpm); + + /* clear DMA status */ + setbits_be32(®->fm_dma.fmdmsr, FMDMSR_CLEAR_ALL); + + /* set DMA mode */ + setbits_be32(®->fm_dma.fmdmmr, FMDMMR_SBER); + + return fm_init_bmi(index, ®->fm_bmi_common); +} +#else int fm_init_common(int index, struct ccsr_fman *reg) { int rc; @@ -429,3 +525,4 @@ int fm_init_common(int index, struct ccsr_fman *reg) return fm_init_bmi(index, ®->fm_bmi_common); } +#endif |