chimp.c 9.8 KB

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