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