1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2019 Broadcom.
4 */
5
6 #include <drivers/bcm/bnxt.h>
7 #include <stdint.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <util.h>
11
12 #define BNXT_FW_NS3_IMAGE_SIG 0xFF12345A
13 #define BNXT_NS3_CFG_IMAGE_SIG 0xCF54321A
14
15 #define BNXT_BSPD_CFG_LEN 512
16
17 #define QSPI_BASE QSPI_MEM_BASE
18 #define QSPI_BNXT_IMG (QSPI_BASE + 0x400000)
19 #define QSPI_BSPD_ADDR (QSPI_BASE + 0x700000)
20
21 #define BCM_NS3 1
22
23 static void set_bnxt_images_info(struct bnxt_images_info *bnxt_info,
24 int chip_type, vaddr_t src, vaddr_t dst);
25
26 static struct bnxt_img_header {
27 uint32_t bnxt_fw_ns3_sig;
28 uint32_t bnxt_fw_ns3_size;
29 uint32_t bnxt_ns3_cfg_sig;
30 uint32_t bnxt_ns3_cfg_size;
31 } *img_header;
32
verify_header(vaddr_t mem)33 static int verify_header(vaddr_t mem)
34 {
35 img_header = (struct bnxt_img_header *)mem;
36
37 if (img_header->bnxt_fw_ns3_sig == BNXT_FW_NS3_IMAGE_SIG &&
38 img_header->bnxt_ns3_cfg_sig == BNXT_NS3_CFG_IMAGE_SIG)
39 return BNXT_SUCCESS;
40 return BNXT_FAILURE;
41 }
42
set_bnxt_images_info(struct bnxt_images_info * bnxt_info,int chip_type,vaddr_t src,vaddr_t dst)43 static void set_bnxt_images_info(struct bnxt_images_info *bnxt_info,
44 int chip_type, vaddr_t src, vaddr_t dst)
45 {
46 uint32_t len = 0;
47 struct bnxt_img_header *dst_header = NULL;
48 uint32_t fw_image_offset = sizeof(struct bnxt_img_header);
49
50 img_header = (struct bnxt_img_header *)src;
51 if (dst) {
52 dst_header = (struct bnxt_img_header *)dst;
53 memcpy(dst_header, img_header, sizeof(*img_header));
54 dst += sizeof(*img_header);
55
56 if (chip_type != BCM_NS3) {
57 dst_header->bnxt_fw_ns3_size = 0;
58 dst_header->bnxt_ns3_cfg_size = 0;
59 }
60 }
61
62 if (chip_type == BCM_NS3) {
63 len = img_header->bnxt_fw_ns3_size;
64 bnxt_info->bnxt_fw_vaddr = src + fw_image_offset;
65 bnxt_info->bnxt_fw_len = len;
66 if (dst) {
67 memcpy((void *)dst, (void *)(src + fw_image_offset),
68 len);
69 dst += len;
70 }
71
72 fw_image_offset += len;
73
74 len = img_header->bnxt_ns3_cfg_size;
75 bnxt_info->bnxt_cfg_vaddr = src + fw_image_offset;
76 bnxt_info->bnxt_cfg_len = len;
77 if (dst) {
78 memcpy((void *)dst, (void *)(src + fw_image_offset),
79 len);
80 }
81 }
82 }
83
get_bnxt_images_info(struct bnxt_images_info * bnxt_info,int chip_type,vaddr_t ddr_dest)84 int get_bnxt_images_info(struct bnxt_images_info *bnxt_info, int chip_type,
85 vaddr_t ddr_dest)
86 {
87 vaddr_t flash_dev_vaddr = 0;
88
89 bnxt_info->bnxt_bspd_cfg_len = BNXT_BSPD_CFG_LEN;
90
91 /* First verify if images are on sec mem */
92 if (verify_header(ddr_dest + BNXT_IMG_SECMEM_OFFSET) == BNXT_SUCCESS) {
93 DMSG("Images found on sec memory");
94
95 bnxt_info->bnxt_bspd_cfg_vaddr = ddr_dest;
96
97 set_bnxt_images_info(bnxt_info, chip_type,
98 ddr_dest + BNXT_IMG_SECMEM_OFFSET, 0);
99 } else {
100 flash_dev_vaddr = (vaddr_t)
101 phys_to_virt(QSPI_BNXT_IMG, MEM_AREA_IO_NSEC,
102 sizeof(struct bnxt_img_header));
103
104 if (verify_header(flash_dev_vaddr) != BNXT_SUCCESS) {
105 EMSG("failed to load fw images");
106 return BNXT_FAILURE;
107 }
108
109 DMSG("Images loading from flash memory");
110 bnxt_info->bnxt_bspd_cfg_vaddr =
111 (vaddr_t)phys_to_virt(QSPI_BSPD_ADDR,
112 MEM_AREA_IO_NSEC,
113 BNXT_BSPD_CFG_LEN);
114 memcpy((void *)ddr_dest, (void *)bnxt_info->bnxt_bspd_cfg_vaddr,
115 BNXT_BSPD_CFG_LEN);
116
117 set_bnxt_images_info(bnxt_info, chip_type, flash_dev_vaddr,
118 ddr_dest + BNXT_IMG_SECMEM_OFFSET);
119 }
120
121 return BNXT_SUCCESS;
122 }
123