195bec10aSVikas Gupta // SPDX-License-Identifier: BSD-2-Clause
295bec10aSVikas Gupta /*
395bec10aSVikas Gupta * Copyright 2019 Broadcom.
495bec10aSVikas Gupta */
595bec10aSVikas Gupta
695bec10aSVikas Gupta #include <drivers/bcm/bnxt.h>
795bec10aSVikas Gupta #include <stdint.h>
895bec10aSVikas Gupta #include <stdlib.h>
995bec10aSVikas Gupta #include <string.h>
1095bec10aSVikas Gupta #include <util.h>
1195bec10aSVikas Gupta
1295bec10aSVikas Gupta #define BNXT_FW_NS3_IMAGE_SIG 0xFF12345A
1395bec10aSVikas Gupta #define BNXT_NS3_CFG_IMAGE_SIG 0xCF54321A
1495bec10aSVikas Gupta
1595bec10aSVikas Gupta #define BNXT_BSPD_CFG_LEN 512
1695bec10aSVikas Gupta
1795bec10aSVikas Gupta #define QSPI_BASE QSPI_MEM_BASE
1895bec10aSVikas Gupta #define QSPI_BNXT_IMG (QSPI_BASE + 0x400000)
1995bec10aSVikas Gupta #define QSPI_BSPD_ADDR (QSPI_BASE + 0x700000)
2095bec10aSVikas Gupta
2195bec10aSVikas Gupta #define BCM_NS3 1
2295bec10aSVikas Gupta
235f2bc144SVikas Gupta static void set_bnxt_images_info(struct bnxt_images_info *bnxt_info,
245f2bc144SVikas Gupta int chip_type, vaddr_t src, vaddr_t dst);
255f2bc144SVikas Gupta
2695bec10aSVikas Gupta static struct bnxt_img_header {
2795bec10aSVikas Gupta uint32_t bnxt_fw_ns3_sig;
2895bec10aSVikas Gupta uint32_t bnxt_fw_ns3_size;
2995bec10aSVikas Gupta uint32_t bnxt_ns3_cfg_sig;
3095bec10aSVikas Gupta uint32_t bnxt_ns3_cfg_size;
3195bec10aSVikas Gupta } *img_header;
3295bec10aSVikas Gupta
verify_header(vaddr_t mem)335f2bc144SVikas Gupta static int verify_header(vaddr_t mem)
3495bec10aSVikas Gupta {
355f2bc144SVikas Gupta img_header = (struct bnxt_img_header *)mem;
3695bec10aSVikas Gupta
375f2bc144SVikas Gupta if (img_header->bnxt_fw_ns3_sig == BNXT_FW_NS3_IMAGE_SIG &&
385f2bc144SVikas Gupta img_header->bnxt_ns3_cfg_sig == BNXT_NS3_CFG_IMAGE_SIG)
395f2bc144SVikas Gupta return BNXT_SUCCESS;
4095bec10aSVikas Gupta return BNXT_FAILURE;
4195bec10aSVikas Gupta }
4295bec10aSVikas Gupta
set_bnxt_images_info(struct bnxt_images_info * bnxt_info,int chip_type,vaddr_t src,vaddr_t dst)435f2bc144SVikas Gupta static void set_bnxt_images_info(struct bnxt_images_info *bnxt_info,
445f2bc144SVikas Gupta int chip_type, vaddr_t src, vaddr_t dst)
455f2bc144SVikas Gupta {
465f2bc144SVikas Gupta uint32_t len = 0;
475f2bc144SVikas Gupta struct bnxt_img_header *dst_header = NULL;
485f2bc144SVikas Gupta uint32_t fw_image_offset = sizeof(struct bnxt_img_header);
495f2bc144SVikas Gupta
505f2bc144SVikas Gupta img_header = (struct bnxt_img_header *)src;
515f2bc144SVikas Gupta if (dst) {
525f2bc144SVikas Gupta dst_header = (struct bnxt_img_header *)dst;
535f2bc144SVikas Gupta memcpy(dst_header, img_header, sizeof(*img_header));
545f2bc144SVikas Gupta dst += sizeof(*img_header);
555f2bc144SVikas Gupta
565f2bc144SVikas Gupta if (chip_type != BCM_NS3) {
575f2bc144SVikas Gupta dst_header->bnxt_fw_ns3_size = 0;
585f2bc144SVikas Gupta dst_header->bnxt_ns3_cfg_size = 0;
595f2bc144SVikas Gupta }
605f2bc144SVikas Gupta }
6195bec10aSVikas Gupta
6295bec10aSVikas Gupta if (chip_type == BCM_NS3) {
635f2bc144SVikas Gupta len = img_header->bnxt_fw_ns3_size;
645f2bc144SVikas Gupta bnxt_info->bnxt_fw_vaddr = src + fw_image_offset;
6595bec10aSVikas Gupta bnxt_info->bnxt_fw_len = len;
665f2bc144SVikas Gupta if (dst) {
675f2bc144SVikas Gupta memcpy((void *)dst, (void *)(src + fw_image_offset),
685f2bc144SVikas Gupta len);
695f2bc144SVikas Gupta dst += len;
7095bec10aSVikas Gupta }
7195bec10aSVikas Gupta
7295bec10aSVikas Gupta fw_image_offset += len;
7395bec10aSVikas Gupta
745f2bc144SVikas Gupta len = img_header->bnxt_ns3_cfg_size;
755f2bc144SVikas Gupta bnxt_info->bnxt_cfg_vaddr = src + fw_image_offset;
765f2bc144SVikas Gupta bnxt_info->bnxt_cfg_len = len;
775f2bc144SVikas Gupta if (dst) {
785f2bc144SVikas Gupta memcpy((void *)dst, (void *)(src + fw_image_offset),
795f2bc144SVikas Gupta len);
805f2bc144SVikas Gupta }
815f2bc144SVikas Gupta }
825f2bc144SVikas Gupta }
835f2bc144SVikas Gupta
get_bnxt_images_info(struct bnxt_images_info * bnxt_info,int chip_type,vaddr_t ddr_dest)845f2bc144SVikas Gupta int get_bnxt_images_info(struct bnxt_images_info *bnxt_info, int chip_type,
855f2bc144SVikas Gupta vaddr_t ddr_dest)
865f2bc144SVikas Gupta {
875f2bc144SVikas Gupta vaddr_t flash_dev_vaddr = 0;
885f2bc144SVikas Gupta
895f2bc144SVikas Gupta bnxt_info->bnxt_bspd_cfg_len = BNXT_BSPD_CFG_LEN;
905f2bc144SVikas Gupta
915f2bc144SVikas Gupta /* First verify if images are on sec mem */
925f2bc144SVikas Gupta if (verify_header(ddr_dest + BNXT_IMG_SECMEM_OFFSET) == BNXT_SUCCESS) {
935f2bc144SVikas Gupta DMSG("Images found on sec memory");
945f2bc144SVikas Gupta
955f2bc144SVikas Gupta bnxt_info->bnxt_bspd_cfg_vaddr = ddr_dest;
965f2bc144SVikas Gupta
975f2bc144SVikas Gupta set_bnxt_images_info(bnxt_info, chip_type,
985f2bc144SVikas Gupta ddr_dest + BNXT_IMG_SECMEM_OFFSET, 0);
995f2bc144SVikas Gupta } else {
100*c2e4eb43SAnton Rybakov flash_dev_vaddr = (vaddr_t)
101*c2e4eb43SAnton Rybakov phys_to_virt(QSPI_BNXT_IMG, MEM_AREA_IO_NSEC,
102*c2e4eb43SAnton Rybakov sizeof(struct bnxt_img_header));
1035f2bc144SVikas Gupta
1045f2bc144SVikas Gupta if (verify_header(flash_dev_vaddr) != BNXT_SUCCESS) {
1055f2bc144SVikas Gupta EMSG("failed to load fw images");
10695bec10aSVikas Gupta return BNXT_FAILURE;
10795bec10aSVikas Gupta }
10895bec10aSVikas Gupta
1095f2bc144SVikas Gupta DMSG("Images loading from flash memory");
1105f2bc144SVikas Gupta bnxt_info->bnxt_bspd_cfg_vaddr =
1115f2bc144SVikas Gupta (vaddr_t)phys_to_virt(QSPI_BSPD_ADDR,
112*c2e4eb43SAnton Rybakov MEM_AREA_IO_NSEC,
113*c2e4eb43SAnton Rybakov BNXT_BSPD_CFG_LEN);
1145f2bc144SVikas Gupta memcpy((void *)ddr_dest, (void *)bnxt_info->bnxt_bspd_cfg_vaddr,
1155f2bc144SVikas Gupta BNXT_BSPD_CFG_LEN);
11695bec10aSVikas Gupta
1175f2bc144SVikas Gupta set_bnxt_images_info(bnxt_info, chip_type, flash_dev_vaddr,
1185f2bc144SVikas Gupta ddr_dest + BNXT_IMG_SECMEM_OFFSET);
11995bec10aSVikas Gupta }
12095bec10aSVikas Gupta
12195bec10aSVikas Gupta return BNXT_SUCCESS;
12295bec10aSVikas Gupta }
123