blob: 58f66a58b17bfda39b0dc1a610e3d0e041ee2ea2 [file] [log] [blame]
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright 2019 Broadcom.
*/
#include <drivers/bcm/bnxt.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <util.h>
#define BNXT_FW_NS3_IMAGE_SIG 0xFF12345A
#define BNXT_NS3_CFG_IMAGE_SIG 0xCF54321A
#define BNXT_BSPD_CFG_LEN 512
#define QSPI_BASE QSPI_MEM_BASE
#define QSPI_BNXT_IMG (QSPI_BASE + 0x400000)
#define QSPI_BSPD_ADDR (QSPI_BASE + 0x700000)
#define BCM_NS3 1
static void set_bnxt_images_info(struct bnxt_images_info *bnxt_info,
int chip_type, vaddr_t src, vaddr_t dst);
static struct bnxt_img_header {
uint32_t bnxt_fw_ns3_sig;
uint32_t bnxt_fw_ns3_size;
uint32_t bnxt_ns3_cfg_sig;
uint32_t bnxt_ns3_cfg_size;
} *img_header;
static int verify_header(vaddr_t mem)
{
img_header = (struct bnxt_img_header *)mem;
if (img_header->bnxt_fw_ns3_sig == BNXT_FW_NS3_IMAGE_SIG &&
img_header->bnxt_ns3_cfg_sig == BNXT_NS3_CFG_IMAGE_SIG)
return BNXT_SUCCESS;
return BNXT_FAILURE;
}
static void set_bnxt_images_info(struct bnxt_images_info *bnxt_info,
int chip_type, vaddr_t src, vaddr_t dst)
{
uint32_t len = 0;
struct bnxt_img_header *dst_header = NULL;
uint32_t fw_image_offset = sizeof(struct bnxt_img_header);
img_header = (struct bnxt_img_header *)src;
if (dst) {
dst_header = (struct bnxt_img_header *)dst;
memcpy(dst_header, img_header, sizeof(*img_header));
dst += sizeof(*img_header);
if (chip_type != BCM_NS3) {
dst_header->bnxt_fw_ns3_size = 0;
dst_header->bnxt_ns3_cfg_size = 0;
}
}
if (chip_type == BCM_NS3) {
len = img_header->bnxt_fw_ns3_size;
bnxt_info->bnxt_fw_vaddr = src + fw_image_offset;
bnxt_info->bnxt_fw_len = len;
if (dst) {
memcpy((void *)dst, (void *)(src + fw_image_offset),
len);
dst += len;
}
fw_image_offset += len;
len = img_header->bnxt_ns3_cfg_size;
bnxt_info->bnxt_cfg_vaddr = src + fw_image_offset;
bnxt_info->bnxt_cfg_len = len;
if (dst) {
memcpy((void *)dst, (void *)(src + fw_image_offset),
len);
}
}
}
int get_bnxt_images_info(struct bnxt_images_info *bnxt_info, int chip_type,
vaddr_t ddr_dest)
{
vaddr_t flash_dev_vaddr = 0;
bnxt_info->bnxt_bspd_cfg_len = BNXT_BSPD_CFG_LEN;
/* First verify if images are on sec mem */
if (verify_header(ddr_dest + BNXT_IMG_SECMEM_OFFSET) == BNXT_SUCCESS) {
DMSG("Images found on sec memory");
bnxt_info->bnxt_bspd_cfg_vaddr = ddr_dest;
set_bnxt_images_info(bnxt_info, chip_type,
ddr_dest + BNXT_IMG_SECMEM_OFFSET, 0);
} else {
flash_dev_vaddr = (vaddr_t)phys_to_virt(QSPI_BNXT_IMG,
MEM_AREA_IO_NSEC);
if (verify_header(flash_dev_vaddr) != BNXT_SUCCESS) {
EMSG("failed to load fw images");
return BNXT_FAILURE;
}
DMSG("Images loading from flash memory");
bnxt_info->bnxt_bspd_cfg_vaddr =
(vaddr_t)phys_to_virt(QSPI_BSPD_ADDR,
MEM_AREA_IO_NSEC);
memcpy((void *)ddr_dest, (void *)bnxt_info->bnxt_bspd_cfg_vaddr,
BNXT_BSPD_CFG_LEN);
set_bnxt_images_info(bnxt_info, chip_type, flash_dev_vaddr,
ddr_dest + BNXT_IMG_SECMEM_OFFSET);
}
return BNXT_SUCCESS;
}