xref: /arm-trusted-firmware/drivers/brcm/chimp.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2016 - 2020, Broadcom
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <string.h>
8*91f16700Schasinglulu 
9*91f16700Schasinglulu #include <drivers/delay_timer.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include <chimp.h>
12*91f16700Schasinglulu #include <chimp_nv_defs.h>
13*91f16700Schasinglulu 
14*91f16700Schasinglulu #define CHIMP_DEFAULT_STARTUP_ADDR 0xb4300000
15*91f16700Schasinglulu 
16*91f16700Schasinglulu /* ChiMP's view of APE scratchpad memory for fastboot */
17*91f16700Schasinglulu #define CHIMP_FASTBOOT_ADDR 0x61000000
18*91f16700Schasinglulu 
19*91f16700Schasinglulu #define CHIMP_PREPARE_ACCESS_WINDOW(addr) \
20*91f16700Schasinglulu 	(\
21*91f16700Schasinglulu 		mmio_write_32(\
22*91f16700Schasinglulu 			NIC400_NITRO_CHIMP_S_IDM_IO_CONTROL_DIRECT, \
23*91f16700Schasinglulu 			addr & 0xffc00000)\
24*91f16700Schasinglulu 	)
25*91f16700Schasinglulu #define CHIMP_INDIRECT_TGT_ADDR(addr) \
26*91f16700Schasinglulu 	(CHIMP_INDIRECT_BASE + (addr & CHIMP_INDIRECT_ADDR_MASK))
27*91f16700Schasinglulu 
28*91f16700Schasinglulu #define CHIMP_CTRL_ADDR(x) (CHIMP_REG_CTRL_BASE + x)
29*91f16700Schasinglulu 
30*91f16700Schasinglulu /* For non-PAXC builds */
31*91f16700Schasinglulu #ifndef CHIMP_FB1_ENTRY
32*91f16700Schasinglulu #define CHIMP_FB1_ENTRY 0
33*91f16700Schasinglulu #endif
34*91f16700Schasinglulu 
35*91f16700Schasinglulu #define CHIMP_DBG	VERBOSE
36*91f16700Schasinglulu 
37*91f16700Schasinglulu void bcm_chimp_write(uintptr_t addr, uint32_t value)
38*91f16700Schasinglulu {
39*91f16700Schasinglulu 	CHIMP_PREPARE_ACCESS_WINDOW(addr);
40*91f16700Schasinglulu 	mmio_write_32(CHIMP_INDIRECT_TGT_ADDR(addr), value);
41*91f16700Schasinglulu }
42*91f16700Schasinglulu 
43*91f16700Schasinglulu uint32_t bcm_chimp_read(uintptr_t addr)
44*91f16700Schasinglulu {
45*91f16700Schasinglulu 	CHIMP_PREPARE_ACCESS_WINDOW(addr);
46*91f16700Schasinglulu 	return mmio_read_32(CHIMP_INDIRECT_TGT_ADDR(addr));
47*91f16700Schasinglulu }
48*91f16700Schasinglulu 
49*91f16700Schasinglulu void bcm_chimp_clrbits(uintptr_t addr, uint32_t bits)
50*91f16700Schasinglulu {
51*91f16700Schasinglulu 	CHIMP_PREPARE_ACCESS_WINDOW(addr);
52*91f16700Schasinglulu 	mmio_clrbits_32(CHIMP_INDIRECT_TGT_ADDR(addr), bits);
53*91f16700Schasinglulu }
54*91f16700Schasinglulu 
55*91f16700Schasinglulu void bcm_chimp_setbits(uintptr_t addr, uint32_t bits)
56*91f16700Schasinglulu {
57*91f16700Schasinglulu 	CHIMP_PREPARE_ACCESS_WINDOW(addr);
58*91f16700Schasinglulu 	mmio_setbits_32(CHIMP_INDIRECT_TGT_ADDR(addr), bits);
59*91f16700Schasinglulu }
60*91f16700Schasinglulu 
61*91f16700Schasinglulu int bcm_chimp_is_nic_mode(void)
62*91f16700Schasinglulu {
63*91f16700Schasinglulu 	uint32_t val;
64*91f16700Schasinglulu 
65*91f16700Schasinglulu 	/* Check if ChiMP straps are set */
66*91f16700Schasinglulu 	val = mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW);
67*91f16700Schasinglulu 	val &= CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK;
68*91f16700Schasinglulu 
69*91f16700Schasinglulu 	return val == CDRU_CHIP_STRAP_DATA_LSW__NIC_MODE_MASK;
70*91f16700Schasinglulu }
71*91f16700Schasinglulu 
72*91f16700Schasinglulu void bcm_chimp_fru_prog_done(bool is_done)
73*91f16700Schasinglulu {
74*91f16700Schasinglulu 	uint32_t val;
75*91f16700Schasinglulu 
76*91f16700Schasinglulu 	val = is_done ? (1 << CHIMP_FRU_PROG_DONE_BIT) : 0;
77*91f16700Schasinglulu 	bcm_chimp_setbits(CHIMP_REG_ECO_RESERVED, val);
78*91f16700Schasinglulu }
79*91f16700Schasinglulu 
80*91f16700Schasinglulu int bcm_chimp_handshake_done(void)
81*91f16700Schasinglulu {
82*91f16700Schasinglulu 	uint32_t value;
83*91f16700Schasinglulu 
84*91f16700Schasinglulu 	value = bcm_chimp_read(CHIMP_REG_ECO_RESERVED);
85*91f16700Schasinglulu 	value &= (1 << CHIMP_FLASH_ACCESS_DONE_BIT);
86*91f16700Schasinglulu 
87*91f16700Schasinglulu 	return value != 0;
88*91f16700Schasinglulu }
89*91f16700Schasinglulu 
90*91f16700Schasinglulu int bcm_chimp_wait_handshake(void)
91*91f16700Schasinglulu {
92*91f16700Schasinglulu 	uint32_t timeout = CHIMP_HANDSHAKE_TIMEOUT_MS;
93*91f16700Schasinglulu 	uint32_t status;
94*91f16700Schasinglulu 
95*91f16700Schasinglulu 	INFO("Waiting for ChiMP handshake...\n");
96*91f16700Schasinglulu 	do {
97*91f16700Schasinglulu 		if (bcm_chimp_handshake_done())
98*91f16700Schasinglulu 			break;
99*91f16700Schasinglulu 		/* No need to wait if ChiMP reported an error */
100*91f16700Schasinglulu 		status = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG);
101*91f16700Schasinglulu 		if (status & CHIMP_ERROR_MASK) {
102*91f16700Schasinglulu 			ERROR("ChiMP error 0x%x. Wait aborted\n", status);
103*91f16700Schasinglulu 			break;
104*91f16700Schasinglulu 		}
105*91f16700Schasinglulu 		mdelay(1);
106*91f16700Schasinglulu 	} while (--timeout);
107*91f16700Schasinglulu 
108*91f16700Schasinglulu 	if (!bcm_chimp_handshake_done()) {
109*91f16700Schasinglulu 		if (timeout == 0) {
110*91f16700Schasinglulu 			WARN("Timeout waiting for ChiMP handshake\n");
111*91f16700Schasinglulu 		}
112*91f16700Schasinglulu 	} else {
113*91f16700Schasinglulu 		INFO("Got handshake from ChiMP!\n");
114*91f16700Schasinglulu 	}
115*91f16700Schasinglulu 
116*91f16700Schasinglulu 	return bcm_chimp_handshake_done();
117*91f16700Schasinglulu }
118*91f16700Schasinglulu 
119*91f16700Schasinglulu uint32_t bcm_chimp_read_ctrl(uint32_t offset)
120*91f16700Schasinglulu {
121*91f16700Schasinglulu 	return bcm_chimp_read(CHIMP_CTRL_ADDR(offset));
122*91f16700Schasinglulu }
123*91f16700Schasinglulu 
124*91f16700Schasinglulu static int bcm_chimp_nitro_reset(void)
125*91f16700Schasinglulu {
126*91f16700Schasinglulu 	uint32_t timeout;
127*91f16700Schasinglulu 
128*91f16700Schasinglulu 	/* Perform tasks done by M0 in NIC mode */
129*91f16700Schasinglulu 	CHIMP_DBG("Taking Nitro out of reset\n");
130*91f16700Schasinglulu 	mmio_setbits_32(CDRU_MISC_RESET_CONTROL,
131*91f16700Schasinglulu 		/* MHB_RESET_N */
132*91f16700Schasinglulu 		(1 << CDRU_MISC_RESET_CONTROL__CDRU_MHB_RESET_N_R)  |
133*91f16700Schasinglulu 		/* PCI_RESET_N */
134*91f16700Schasinglulu 		(1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R) |
135*91f16700Schasinglulu 		/* PM_RESET_N */
136*91f16700Schasinglulu 		(1 << CDRU_MISC_RESET_CONTROL__CDRU_PM_RESET_N_R)   |
137*91f16700Schasinglulu 		/* NIC_RESET_N */
138*91f16700Schasinglulu 		(1 << CDRU_MISC_RESET_CONTROL__CDRU_NITRO_RESET_N_R)
139*91f16700Schasinglulu 	);
140*91f16700Schasinglulu 
141*91f16700Schasinglulu 	/* Wait until Nitro is out of reset */
142*91f16700Schasinglulu 	timeout = NIC_RESET_RELEASE_TIMEOUT_US;
143*91f16700Schasinglulu 	do {
144*91f16700Schasinglulu 		uint32_t value;
145*91f16700Schasinglulu 
146*91f16700Schasinglulu 		value = bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_MODE_REG);
147*91f16700Schasinglulu 		if ((value & CHIMP_BPE_MODE_ID_MASK) ==
148*91f16700Schasinglulu 				CHIMP_BPE_MODE_ID_PATTERN)
149*91f16700Schasinglulu 			break;
150*91f16700Schasinglulu 		udelay(1);
151*91f16700Schasinglulu 	} while (--timeout);
152*91f16700Schasinglulu 
153*91f16700Schasinglulu 	if (timeout == 0) {
154*91f16700Schasinglulu 		ERROR("NIC reset release timed out\n");
155*91f16700Schasinglulu 		return -1;
156*91f16700Schasinglulu 	}
157*91f16700Schasinglulu 
158*91f16700Schasinglulu 	return 0;
159*91f16700Schasinglulu }
160*91f16700Schasinglulu 
161*91f16700Schasinglulu static void bcm_nitro_secure_mode_enable(void)
162*91f16700Schasinglulu {
163*91f16700Schasinglulu 	mmio_setbits_32(CDRU_NITRO_CONTROL,
164*91f16700Schasinglulu 		(1 << CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_MODE_R) |
165*91f16700Schasinglulu 		(1 << CDRU_NITRO_CONTROL__CDRU_NITRO_SEC_OVERRIDE_R));
166*91f16700Schasinglulu 	mmio_write_32(NITRO_TZPC_TZPCDECPROT0clr,
167*91f16700Schasinglulu 		/* NITRO_TZPC */
168*91f16700Schasinglulu 		1 << NITRO_TZPC_TZPCDECPROT0clr__DECPROT0_chimp_m_clr_R);
169*91f16700Schasinglulu }
170*91f16700Schasinglulu 
171*91f16700Schasinglulu static int bcm_chimp_reset_and_initial_setup(void)
172*91f16700Schasinglulu {
173*91f16700Schasinglulu 
174*91f16700Schasinglulu 	int err;
175*91f16700Schasinglulu 	uint32_t handshake_reg;
176*91f16700Schasinglulu 
177*91f16700Schasinglulu 	err = bcm_chimp_nitro_reset();
178*91f16700Schasinglulu 	if (err)
179*91f16700Schasinglulu 		return err;
180*91f16700Schasinglulu 
181*91f16700Schasinglulu 	/* Enable Nitro secure mode */
182*91f16700Schasinglulu 	bcm_nitro_secure_mode_enable();
183*91f16700Schasinglulu 
184*91f16700Schasinglulu 	/* Force ChiMP back into reset */
185*91f16700Schasinglulu 	bcm_chimp_setbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG),
186*91f16700Schasinglulu 		1 << CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R);
187*91f16700Schasinglulu 
188*91f16700Schasinglulu 	handshake_reg = (1 << SR_IN_SMARTNIC_MODE_BIT);
189*91f16700Schasinglulu 
190*91f16700Schasinglulu 	/* Get OTP secure Chimp boot status */
191*91f16700Schasinglulu 	if (mmio_read_32(CRMU_OTP_STATUS) & (1 << CRMU_OTP_STATUS_BIT))
192*91f16700Schasinglulu 		handshake_reg |= (1 << SR_CHIMP_SECURE_BOOT_BIT);
193*91f16700Schasinglulu 
194*91f16700Schasinglulu 	bcm_chimp_write(CHIMP_REG_ECO_RESERVED, handshake_reg);
195*91f16700Schasinglulu 
196*91f16700Schasinglulu 	CHIMP_DBG("ChiMP reset and initial handshake parameters set\n");
197*91f16700Schasinglulu 
198*91f16700Schasinglulu 	return 0;
199*91f16700Schasinglulu }
200*91f16700Schasinglulu 
201*91f16700Schasinglulu static void bcm_nitro_chimp_release_reset(void)
202*91f16700Schasinglulu {
203*91f16700Schasinglulu 	bcm_chimp_clrbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG),
204*91f16700Schasinglulu 		1 << CHIMP_REG_CHIMP_REG_CTRL_BPE_MODE_REG__cm3_rst_R);
205*91f16700Schasinglulu 
206*91f16700Schasinglulu 	CHIMP_DBG("Nitro Reset Released\n");
207*91f16700Schasinglulu }
208*91f16700Schasinglulu 
209*91f16700Schasinglulu static void bcm_chimp_set_fastboot(int mode)
210*91f16700Schasinglulu {
211*91f16700Schasinglulu 	uint32_t fb_entry;
212*91f16700Schasinglulu 
213*91f16700Schasinglulu 	/* 1. Enable fastboot */
214*91f16700Schasinglulu 	bcm_chimp_setbits(CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_BPE_MODE_REG),
215*91f16700Schasinglulu 			(1 << CHIMP_FAST_BOOT_MODE_BIT));
216*91f16700Schasinglulu 	fb_entry = CHIMP_FASTBOOT_ADDR | mode;
217*91f16700Schasinglulu 	if (mode == CHIMP_FASTBOOT_JUMP_IN_PLACE)
218*91f16700Schasinglulu 		fb_entry = CHIMP_FB1_ENTRY;
219*91f16700Schasinglulu 	/* 2. Write startup address and mode */
220*91f16700Schasinglulu 	INFO("Setting fastboot type %d entry to 0x%x\n", mode, fb_entry);
221*91f16700Schasinglulu 	bcm_chimp_write(
222*91f16700Schasinglulu 			CHIMP_CTRL_ADDR(CHIMP_REG_CTRL_FSTBOOT_PTR_REG),
223*91f16700Schasinglulu 			fb_entry);
224*91f16700Schasinglulu }
225*91f16700Schasinglulu 
226*91f16700Schasinglulu #ifndef CHIMPFW_USE_SIDELOAD
227*91f16700Schasinglulu static void bcm_chimp_load_fw_from_spi(uintptr_t spi_addr, size_t size)
228*91f16700Schasinglulu {
229*91f16700Schasinglulu 	uintptr_t ape_scpad;
230*91f16700Schasinglulu 	uintptr_t dest;
231*91f16700Schasinglulu 	size_t bytes_left;
232*91f16700Schasinglulu 
233*91f16700Schasinglulu 	ape_scpad = CHIMP_REG_CHIMP_APE_SCPAD;
234*91f16700Schasinglulu 	dest = CHIMP_INDIRECT_TGT_ADDR(CHIMP_REG_CHIMP_APE_SCPAD);
235*91f16700Schasinglulu 	bytes_left = size;
236*91f16700Schasinglulu 
237*91f16700Schasinglulu 	while (bytes_left) {
238*91f16700Schasinglulu 		uint32_t delta;
239*91f16700Schasinglulu 
240*91f16700Schasinglulu 		delta = bytes_left > CHIMP_WINDOW_SIZE ?
241*91f16700Schasinglulu 			bytes_left - CHIMP_WINDOW_SIZE : bytes_left;
242*91f16700Schasinglulu 		CHIMP_PREPARE_ACCESS_WINDOW(ape_scpad);
243*91f16700Schasinglulu 		INFO("Transferring %d byte(s) from 0x%lx to 0x%lx\n",
244*91f16700Schasinglulu 			delta, spi_addr, dest);
245*91f16700Schasinglulu 	/*
246*91f16700Schasinglulu 	 * This single memcpy call takes significant amount of time
247*91f16700Schasinglulu 	 * on Palladium. Be patient
248*91f16700Schasinglulu 	 */
249*91f16700Schasinglulu 		memcpy((void *)dest, (void *)spi_addr, delta);
250*91f16700Schasinglulu 		bytes_left -= delta;
251*91f16700Schasinglulu 		INFO("Transferred %d byte(s) from 0x%lx to 0x%lx (%lu%%)\n",
252*91f16700Schasinglulu 			delta, spi_addr, dest,
253*91f16700Schasinglulu 			((size - bytes_left) * 100)/size);
254*91f16700Schasinglulu 		spi_addr += delta;
255*91f16700Schasinglulu 		dest += delta;
256*91f16700Schasinglulu 		ape_scpad += delta;
257*91f16700Schasinglulu 	}
258*91f16700Schasinglulu }
259*91f16700Schasinglulu 
260*91f16700Schasinglulu static int bcm_chimp_find_fw_in_spi(uintptr_t *addr, size_t *size)
261*91f16700Schasinglulu {
262*91f16700Schasinglulu 	int i;
263*91f16700Schasinglulu 	bnxnvm_master_block_header_t *master_block_hdr;
264*91f16700Schasinglulu 	bnxnvm_directory_block_header_t *dir_block_hdr;
265*91f16700Schasinglulu 	bnxnvm_directory_entry_t *dir_entry;
266*91f16700Schasinglulu 	int found;
267*91f16700Schasinglulu 
268*91f16700Schasinglulu 	found = 0;
269*91f16700Schasinglulu 
270*91f16700Schasinglulu 	/* Read the master block */
271*91f16700Schasinglulu 	master_block_hdr =
272*91f16700Schasinglulu 		(bnxnvm_master_block_header_t *)(uintptr_t)QSPI_BASE_ADDR;
273*91f16700Schasinglulu 	if (master_block_hdr->sig != BNXNVM_MASTER_BLOCK_SIG) {
274*91f16700Schasinglulu 		WARN("Invalid masterblock 0x%x (expected 0x%x)\n",
275*91f16700Schasinglulu 			master_block_hdr->sig,
276*91f16700Schasinglulu 			BNXNVM_MASTER_BLOCK_SIG);
277*91f16700Schasinglulu 		return -NV_NOT_NVRAM;
278*91f16700Schasinglulu 	}
279*91f16700Schasinglulu 	if ((master_block_hdr->block_size > NV_MAX_BLOCK_SIZE) ||
280*91f16700Schasinglulu 		(master_block_hdr->directory_offset >=
281*91f16700Schasinglulu 			master_block_hdr->nvram_size)) {
282*91f16700Schasinglulu 		WARN("Invalid masterblock block size 0x%x or directory offset 0x%x\n",
283*91f16700Schasinglulu 			master_block_hdr->block_size,
284*91f16700Schasinglulu 			master_block_hdr->directory_offset);
285*91f16700Schasinglulu 		return -NV_BAD_MB;
286*91f16700Schasinglulu 	}
287*91f16700Schasinglulu 
288*91f16700Schasinglulu 	/* Skip to the Directory block start */
289*91f16700Schasinglulu 	dir_block_hdr =
290*91f16700Schasinglulu 		(bnxnvm_directory_block_header_t *)
291*91f16700Schasinglulu 			((uintptr_t)QSPI_BASE_ADDR +
292*91f16700Schasinglulu 				master_block_hdr->directory_offset);
293*91f16700Schasinglulu 	if (dir_block_hdr->sig != BNXNVM_DIRECTORY_BLOCK_SIG) {
294*91f16700Schasinglulu 		WARN("Invalid directory header 0x%x (expected 0x%x)\n",
295*91f16700Schasinglulu 			dir_block_hdr->sig,
296*91f16700Schasinglulu 			BNXNVM_DIRECTORY_BLOCK_SIG);
297*91f16700Schasinglulu 		return -NV_BAD_DIR_HEADER;
298*91f16700Schasinglulu 	}
299*91f16700Schasinglulu 
300*91f16700Schasinglulu 	/* Locate the firmware */
301*91f16700Schasinglulu 	for (i = 0; i < dir_block_hdr->entries; i++) {
302*91f16700Schasinglulu 		*addr = ((uintptr_t)dir_block_hdr + dir_block_hdr->length +
303*91f16700Schasinglulu 			i * dir_block_hdr->entry_length);
304*91f16700Schasinglulu 		dir_entry = (bnxnvm_directory_entry_t *)(*addr);
305*91f16700Schasinglulu 		if ((dir_entry->type == BNX_DIR_TYPE_BOOTCODE) ||
306*91f16700Schasinglulu 				(dir_entry->type == BNX_DIR_TYPE_BOOTCODE_2)) {
307*91f16700Schasinglulu 			found = 1;
308*91f16700Schasinglulu 			break;
309*91f16700Schasinglulu 		}
310*91f16700Schasinglulu 	}
311*91f16700Schasinglulu 
312*91f16700Schasinglulu 	if (!found)
313*91f16700Schasinglulu 		return -NV_FW_NOT_FOUND;
314*91f16700Schasinglulu 
315*91f16700Schasinglulu 	*addr = QSPI_BASE_ADDR + dir_entry->item_location;
316*91f16700Schasinglulu 	*size = dir_entry->data_length;
317*91f16700Schasinglulu 
318*91f16700Schasinglulu 	INFO("Found chimp firmware at 0x%lx, size %lu byte(s)\n",
319*91f16700Schasinglulu 			*addr, *size);
320*91f16700Schasinglulu 
321*91f16700Schasinglulu 	return NV_OK;
322*91f16700Schasinglulu }
323*91f16700Schasinglulu #endif
324*91f16700Schasinglulu 
325*91f16700Schasinglulu int bcm_chimp_initiate_fastboot(int fastboot_type)
326*91f16700Schasinglulu {
327*91f16700Schasinglulu 	int err;
328*91f16700Schasinglulu 
329*91f16700Schasinglulu 	if ((fastboot_type != CHIMP_FASTBOOT_NITRO_RESET) &&
330*91f16700Schasinglulu 			(fastboot_type <= CHIMP_FASTBOOT_JUMP_DECOMPRESS)) {
331*91f16700Schasinglulu 		CHIMP_DBG("Initiating ChiMP fastboot type %d\n", fastboot_type);
332*91f16700Schasinglulu 	}
333*91f16700Schasinglulu 
334*91f16700Schasinglulu 	/*
335*91f16700Schasinglulu 	 * If we are here, M0 did not setup Nitro because NIC mode
336*91f16700Schasinglulu 	 * strap was not present
337*91f16700Schasinglulu 	 */
338*91f16700Schasinglulu 	err = bcm_chimp_reset_and_initial_setup();
339*91f16700Schasinglulu 	if (err)
340*91f16700Schasinglulu 		return err;
341*91f16700Schasinglulu 
342*91f16700Schasinglulu 	if (fastboot_type > CHIMP_FASTBOOT_JUMP_DECOMPRESS) {
343*91f16700Schasinglulu 		WARN("ChiMP setup deferred\n");
344*91f16700Schasinglulu 		return -1;
345*91f16700Schasinglulu 	}
346*91f16700Schasinglulu 
347*91f16700Schasinglulu 	if (fastboot_type != CHIMP_FASTBOOT_NITRO_RESET) {
348*91f16700Schasinglulu 
349*91f16700Schasinglulu 		if ((fastboot_type == CHIMP_FASTBOOT_JUMP_IN_PLACE) &&
350*91f16700Schasinglulu 			(CHIMP_FB1_ENTRY == 0)) {
351*91f16700Schasinglulu 			ERROR("Missing ESAL entry point for fastboot type 1.\n"
352*91f16700Schasinglulu 			"Fastboot failed\n");
353*91f16700Schasinglulu 			return -1;
354*91f16700Schasinglulu 		}
355*91f16700Schasinglulu 
356*91f16700Schasinglulu 		/*
357*91f16700Schasinglulu 		 * TODO: We need to think of the way to load the ChiMP fw.
358*91f16700Schasinglulu 		 * This could be SPI, NAND, etc.
359*91f16700Schasinglulu 		 * For now we temporarily stick to the SPI load unless
360*91f16700Schasinglulu 		 * CHIMPFW_USE_SIDELOAD is defined. Note that for the SPI NVRAM
361*91f16700Schasinglulu 		 * image we need to parse directory and get the image.
362*91f16700Schasinglulu 		 * When we load image from other media there is no need to
363*91f16700Schasinglulu 		 * parse because fw image can be directly placed into the APE's
364*91f16700Schasinglulu 		 * scratchpad.
365*91f16700Schasinglulu 		 * For sideload method we simply reset the ChiMP, set bpe_reg
366*91f16700Schasinglulu 		 * to do fastboot with the type we define, and release from
367*91f16700Schasinglulu 		 * reset so that ROM loader would initiate fastboot immediately
368*91f16700Schasinglulu 		 */
369*91f16700Schasinglulu #ifndef CHIMPFW_USE_SIDELOAD
370*91f16700Schasinglulu 		{
371*91f16700Schasinglulu 			uintptr_t spi_addr;
372*91f16700Schasinglulu 			size_t size;
373*91f16700Schasinglulu 
374*91f16700Schasinglulu 			err = bcm_chimp_find_fw_in_spi(&spi_addr, &size);
375*91f16700Schasinglulu 			if (!err) {
376*91f16700Schasinglulu 				INFO("Loading ChiMP firmware, addr 0x%lx, size %lu byte(s)\n",
377*91f16700Schasinglulu 					spi_addr, size);
378*91f16700Schasinglulu 				bcm_chimp_load_fw_from_spi(spi_addr, size);
379*91f16700Schasinglulu 			} else {
380*91f16700Schasinglulu 				ERROR("Error %d ChiMP firmware not in NVRAM directory!\n",
381*91f16700Schasinglulu 					err);
382*91f16700Schasinglulu 			}
383*91f16700Schasinglulu 		}
384*91f16700Schasinglulu #else
385*91f16700Schasinglulu 		INFO("Skip ChiMP QSPI fastboot type %d due to sideload requested\n",
386*91f16700Schasinglulu 		     fastboot_type);
387*91f16700Schasinglulu #endif
388*91f16700Schasinglulu 		if (!err) {
389*91f16700Schasinglulu 			INFO("Instruct ChiMP to fastboot\n");
390*91f16700Schasinglulu 			bcm_chimp_set_fastboot(fastboot_type);
391*91f16700Schasinglulu 			INFO("Fastboot mode set\n");
392*91f16700Schasinglulu 		}
393*91f16700Schasinglulu 	}
394*91f16700Schasinglulu 
395*91f16700Schasinglulu 	bcm_nitro_chimp_release_reset();
396*91f16700Schasinglulu 
397*91f16700Schasinglulu 	return err;
398*91f16700Schasinglulu }
399