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