mt_adsp.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2018. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <stdint.h>
  32. #include <string.h>
  33. #include <debug.h>
  34. #include <platform.h>
  35. #include <platform/mt_gpt.h>
  36. #include <platform/boot_mode.h>
  37. #include <part_interface.h>
  38. #include <pal_typedefs.h>
  39. #include <pal_assert.h>
  40. #include <pal_log.h>
  41. #include <platform/verified_boot.h>
  42. #include <env.h>
  43. #ifdef DEVICE_TREE_SUPPORT
  44. #include <libfdt.h>
  45. #include <fdt_op.h>
  46. #endif
  47. #include <assert.h>
  48. #include <platform/mt_adsp.h>
  49. #if ENABLE_ADSP_EMI_PROTECTION
  50. #include <platform/mt_emi_mpu.h>
  51. #endif
  52. #include <platform/errno.h>
  53. #include <spm.h> //mtcmos
  54. #include <arch/ops.h> //for arch_sync_cache_range()
  55. #define ALIGN_TO(x, n) \
  56. (((x) + ((n) - 1)) & ~((n) - 1))
  57. static char module_prefix[] = "[ADSP]";
  58. extern BOOT_ARGUMENT *g_boot_arg;
  59. static uint32_t g_dram_size = ADSP_DRAM_SIZE;
  60. static uint32_t g_total_dram_size = 0;
  61. static unsigned int adsp_load_status = 0;
  62. static void *dram_phys_addr;
  63. static char *adsp_part_name = "audio_dsp"; /* name registered in partition */
  64. struct adsp_mem_attr {
  65. uint32_t enable; /* default setting */
  66. uint32_t size;
  67. };
  68. static struct adsp_mem_attr mem_attr[AUDIO_MEM_TOTAL_NUM];
  69. struct image_node image_table[ADSP_NUM_IMAGE] = {
  70. [ADSP_A_IMAGE_ITCM] = IMAGE_UNIT(ADSP_A_ITCM_NAME, ADSP_A_ITCM_BASE, ADSP_A_ITCM_SIZE),
  71. [ADSP_A_IMAGE_DTCM] = IMAGE_UNIT(ADSP_A_DTCM_NAME, ADSP_A_DTCM_BASE, ADSP_A_DTCM_SIZE),
  72. [ADSP_A_IMAGE_DRAM] = IMAGE_UNIT(ADSP_A_DRAM_NAME, 0, ADSP_A_DRAM_SIZE),
  73. };
  74. static char *adsp_audio_mem_name[AUDIO_MEM_TOTAL_NUM] = {
  75. [AUDIO_MEM_VOIP_ID] = "mtk_dsp_voip",
  76. [AUDIO_MEM_PRIMARY_ID] = "mtk_dsp_primary",
  77. [AUDIO_MEM_OFFLOAD_ID] = "mtk_dsp_offload",
  78. [AUDIO_MEM_DEEPBUFFER_ID] = "mtk_dsp_deep",
  79. [AUDIO_MEM_PLAYBACK_ID] = "mtk_dsp_playback",
  80. [AUDIO_MEM_MUSIC_ID] = "mtk_dsp_music",
  81. [AUDIO_MEM_CAPTURE_UL1_ID] = "mtk_dsp_capture1",
  82. [AUDIO_MEM_A2DP_ID] = "mtk_dsp_a2dp",
  83. [AUDIO_MEM_DATAPROVIDER_ID] = "mtk_dsp_dataprovider",
  84. [AUDIO_MEM_CALL_FINAL_ID] = "mtk_dsp_call_final",
  85. [AUDIO_MEM_FAST_ID] = "mtk_dsp_fast",
  86. [AUDIO_MEM_KTV_ID] = "mtk_dsp_ktv",
  87. [AUDIO_MEM_AFE_ID] = "mtk_dsp_mem_afe",
  88. };
  89. static char *adsp_rsv_name[ADSP_RSV_TOTAL_NUM] = {
  90. [ADSP_RSV_IPIDMA_A] = "adsp-rsv-ipidma-a",
  91. [ADSP_RSV_LOGGER_A] = "adsp-rsv-logger-a",
  92. [ADSP_RSV_DBG_DUMP_A] = "adsp-rsv-dbg-dump-a",
  93. [ADSP_RSV_CORE_DUMP_A] = "adsp-rsv-core-dump-a",
  94. [ADSP_RSV_AUDIO] = "adsp-rsv-audio",
  95. };
  96. extern void dsb(void);
  97. extern int mboot_common_load_part(char *part_name, char *img_name, unsigned long addr);
  98. extern int verify_load_adsp_image(char *part_name, void *addr);
  99. static int calc_and_update_audio_rsv(void);
  100. static int update_and_set_adsp_rsv_size(void);
  101. static int get_adsp_sysram_info_from_dt(void);
  102. static uint32_t parse_adsp_memory_from_dt(void);
  103. static void set_adsp_image_base(uint32_t id, void *base);
  104. static void set_adsp_image_size(uint32_t id, uint32_t size);
  105. static void set_adsp_mpu_region(void);
  106. static void print_adsp_image_info(void);
  107. static char *adsp_partition_name(void)
  108. {
  109. return adsp_part_name;
  110. }
  111. int load_adsp_image(char *part_name, char *img_name, void *addr)
  112. {
  113. int ret = 0;
  114. dprintf(CRITICAL, "%s load %s addr=0x%x\n",__func__, img_name, (uint32_t)addr);
  115. #ifdef MTK_SECURITY_SW_SUPPORT
  116. /* we use this API because audio dsp TCM 8 byte access
  117. * limitation */
  118. ret = img_auth_stor(part_name, img_name, 0x1);
  119. if (ret != 0) {
  120. pal_log_err("<ASSERT> %s:line %d\n", __FILE__, __LINE__);
  121. PAL_ASSERT(0);
  122. }
  123. #endif /* MTK_SECURITY_SW_SUPPORT */
  124. ret = mboot_common_load_part(part_name, img_name, (unsigned long)addr);
  125. dprintf(CRITICAL, "[ADSP]mboot_common_load_part ret=%d\n",ret);
  126. if (ret <= 0)
  127. ret = -1;
  128. return ret;
  129. }
  130. int load_adsp(void)
  131. {
  132. int ret;
  133. char *part_name;
  134. #ifdef DEVICE_TREE_SUPPORT
  135. g_dram_size = parse_adsp_memory_from_dt();
  136. if (!g_dram_size)
  137. goto error;
  138. #else
  139. dprintf(CRITICAL, "[ADSP] \"DEVICE_TREE_SUPPORT\" is not defined\n");
  140. #endif
  141. /* memory to store i/dtcm image from partition loader */
  142. g_total_dram_size= ALIGN_TO(g_dram_size + ADSP_TCM_TOTAL_SIZE, RESERVED_MEM_ALIGN);
  143. dram_phys_addr = (void *)(uint32_t)mblock_reserve_ext(&g_boot_arg->mblock_info, g_total_dram_size,
  144. ADSP_DRAM_ADDR_ALIGN, ADSP_DRAM_ADDR_MAX, 0, ADSP_MEM_RESERVED_KEY);
  145. if (!dram_phys_addr) {
  146. dprintf(CRITICAL, "[ADSP] mblock_reserve address fail. phys view=0x%x, adsp view=0x%x\n",
  147. (uint32_t)dram_phys_addr, (uint32_t)image_table[ADSP_A_IMAGE_DRAM].base);
  148. } else {
  149. /* update target(adsp a & b) dram address */
  150. dprintf(INFO, "[ADSP] mblock_reserve success. phys view=0x%x, size=0x%x\n",
  151. (uint32_t)dram_phys_addr, g_total_dram_size);
  152. print_adsp_image_info();
  153. }
  154. part_name = adsp_partition_name();
  155. if(!part_name) {
  156. dprintf(CRITICAL, "[ADSP]get partition failed\n");
  157. goto error;
  158. }
  159. /* enable adsp clock & release CPU to access hifi3 */
  160. switch_adsp_power(true, false);
  161. adsp_sw_reset();
  162. /* load adsp image */
  163. ret = verify_load_adsp_image(part_name, dram_phys_addr);
  164. if (ret < 0) {
  165. dprintf(CRITICAL, "[ADSP]verify %s failed, ret=%d(-1: load image fail, -5:sram size<0, -6:sram size not 32*N)\n", part_name, ret);
  166. goto error;
  167. }
  168. set_adsp_mpu_region();
  169. /* disable adsp clock */
  170. //#ifndef BRINGUP_WR
  171. // switch_adsp_power(false, true);
  172. //#endif
  173. /* clean dcache & icache before set up EMI MPU */
  174. arch_sync_cache_range((addr_t)dram_phys_addr, g_total_dram_size);
  175. /* setup EMI MPU
  176. * domain 0: AP
  177. * domain 10: ADSP
  178. */
  179. #if ENABLE_ADSP_EMI_PROTECTION
  180. struct emi_region_info_t region_info;
  181. region_info.start = (unsigned long long)(uint32_t)dram_phys_addr;
  182. region_info.end = (unsigned long long)((uint32_t)dram_phys_addr + g_total_dram_size - 0x1);
  183. region_info.region = MPU_REGION_ID_ADSP_RO_MEM;
  184. SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
  185. FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
  186. FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN,
  187. FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
  188. FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_R_NSEC_R);
  189. emi_mpu_set_protection(&region_info);
  190. #endif
  191. adsp_load_status = 1;
  192. dprintf(INFO, "%s(): done\n", __func__);
  193. return 0;
  194. error:
  195. /*
  196. * @ret = 0, malloc() error
  197. * @ret < 0, eror code from load_adsp_image()
  198. */
  199. adsp_load_status = 0;
  200. return -1;
  201. }
  202. #ifdef DEVICE_TREE_SUPPORT
  203. static int update_and_set_adsp_rsv_size(void)
  204. {
  205. int nodeoffset, len;
  206. void *fdt = get_kernel_fdt();
  207. const void *data;
  208. uint32_t mem_id, size, total_size = 0;
  209. fdt64_t rsv_size;
  210. if (fdt == NULL)
  211. panic("kernel fdt is NULL!\n");
  212. nodeoffset = fdt_node_offset_by_compatible(fdt, -1, ADSP_COMMON_DTS_COMPATIBLE);
  213. if (nodeoffset < 0) {
  214. dprintf(CRITICAL, "[ADSP] Failed to find %s in dtb\n",
  215. ADSP_COMMON_DTS_COMPATIBLE);
  216. return -1;
  217. }
  218. for (mem_id = 0; mem_id < ADSP_RSV_TOTAL_NUM; mem_id ++) {
  219. data = fdt_getprop(fdt, nodeoffset, adsp_rsv_name[mem_id], &len);
  220. if (data) {
  221. size = fdt32_to_cpu(*(uint32_t *)data);
  222. total_size += size;
  223. } else {
  224. dprintf(CRITICAL, "[ADSP] get \"%s\" fail\n", adsp_rsv_name[mem_id]);
  225. continue;
  226. }
  227. }
  228. nodeoffset = fdt_node_offset_by_compatible(fdt, -1, ADSP_SHARE_DTS_COMPATIBLE);
  229. if (nodeoffset < 0) {
  230. dprintf(CRITICAL, "[ADSP] %s is not found\n", ADSP_SHARE_DTS_COMPATIBLE);
  231. return -1;
  232. }
  233. /* update reserve memory size */
  234. rsv_size = cpu_to_fdt64((uint64_t)ALIGN_TO(total_size, RESERVED_MEM_ALIGN));
  235. fdt_setprop_inplace(fdt, nodeoffset, "size", &rsv_size, sizeof(rsv_size));
  236. return 0;
  237. }
  238. /* return value: size of total dram images */
  239. static uint32_t parse_adsp_memory_from_dt(void)
  240. {
  241. uint32_t adsp_dram_tail, adsp_dram_head;
  242. int ret = 0;
  243. /* audio feature from dts */
  244. calc_and_update_audio_rsv();
  245. update_and_set_adsp_rsv_size();
  246. /* system from dts */
  247. ret = get_adsp_sysram_info_from_dt();
  248. if (ret) {
  249. dprintf(CRITICAL, "get adsp sysrm info fail. ret=%d\n", ret);
  250. }
  251. adsp_dram_head = (uint32_t)image_table[ADSP_A_IMAGE_DRAM].base;
  252. adsp_dram_tail = (uint32_t)image_table[ADSP_A_IMAGE_DRAM].base + image_table[ADSP_A_IMAGE_DRAM].size;
  253. if (!adsp_dram_head || !adsp_dram_tail ) {
  254. dprintf(CRITICAL, "%s error: adsp dram size is NULL!\n", __func__);
  255. return 0;
  256. }
  257. return (uint32_t)image_table[ADSP_A_IMAGE_DRAM].size;
  258. }
  259. static int calc_and_update_audio_rsv(void)
  260. {
  261. int nodeoffset, len;
  262. void *fdt = get_kernel_fdt();
  263. const void *data;
  264. uint32_t mem_id, mem_offset;
  265. uint32_t total_mem = 0;
  266. bool afe_enable;
  267. fdt32_t rsv_size;
  268. /* get snd_audio_dsp node,
  269. check audio feature set and calc total memory size
  270. */
  271. nodeoffset = fdt_node_offset_by_compatible(fdt, -1, SND_ADSP_DTS_COMPATIBLE);
  272. if (nodeoffset < 0) {
  273. dprintf(CRITICAL, "[ADSP] %s is not found\n", SND_ADSP_DTS_COMPATIBLE);
  274. return -1;
  275. }
  276. for (mem_id = 0; mem_id < AUDIO_MEM_TOTAL_NUM; mem_id ++) {
  277. if (mem_id < AUDIO_MEM_TASK_NUM)
  278. mem_offset = 4;
  279. else
  280. mem_offset = 1;
  281. data = fdt_getprop(fdt, nodeoffset, adsp_audio_mem_name[mem_id], &len);
  282. if (data) {
  283. mem_attr[mem_id].enable = fdt32_to_cpu(*(uint32_t *)data);
  284. mem_attr[mem_id].size = fdt32_to_cpu(*((uint32_t *)data + mem_offset));
  285. if (mem_attr[mem_id].size != 0 && mem_attr[mem_id].size < MIN_SIZE_MEM_SEGMENT) {
  286. dprintf(CRITICAL, "[ADSP] %s memory size invalid\n", adsp_audio_mem_name[mem_id]);
  287. return -2;
  288. }
  289. } else {
  290. dprintf(CRITICAL, "[ADSP] get \"%s\" fail\n", adsp_audio_mem_name[mem_id]);
  291. continue;
  292. }
  293. if (mem_id < AUDIO_MEM_TASK_NUM && mem_attr[mem_id].enable != 0) {
  294. total_mem += mem_attr[mem_id].size;
  295. afe_enable = true;
  296. }
  297. }
  298. /* architecture-specific */
  299. if (afe_enable && mem_attr[AUDIO_MEM_AFE_ID].enable)
  300. total_mem += mem_attr[AUDIO_MEM_AFE_ID].size;
  301. if (mem_attr[AUDIO_MEM_CALL_FINAL_ID].enable)
  302. total_mem -= mem_attr[AUDIO_MEM_CALL_FINAL_ID].size;
  303. /* write audio reserved memory back to adsp_common node */
  304. nodeoffset = fdt_node_offset_by_compatible(fdt, -1, ADSP_COMMON_DTS_COMPATIBLE);
  305. if (nodeoffset < 0) {
  306. dprintf(CRITICAL, "[ADSP] %s is not found\n", ADSP_COMMON_DTS_COMPATIBLE);
  307. return -1;
  308. }
  309. rsv_size = cpu_to_fdt32(total_mem);
  310. fdt_setprop_inplace(fdt, nodeoffset, adsp_rsv_name[ADSP_RSV_AUDIO], &rsv_size, sizeof(rsv_size));
  311. dprintf(INFO, "%s update audio feature memory = 0x%x\n", __func__, total_mem);
  312. return 0;
  313. }
  314. static int get_adsp_sysram_info_from_dt(void)
  315. {
  316. int nodeoffset, len;
  317. int n = 0;
  318. char compat_name[32];
  319. void *base = NULL;
  320. void *fdt = get_kernel_fdt();
  321. const void *fdt_data;
  322. uint32_t idx, size = 0, core_id = 0;
  323. uint32_t *data;
  324. for (idx = 0; idx < ADSP_NUM_IMAGE; idx++) {
  325. if (strstr(image_table[idx].name, "sram") == NULL) {
  326. continue;
  327. }
  328. memset(compat_name, 0, sizeof(compat_name));
  329. n = snprintf(compat_name, sizeof(compat_name), "%s_%d",
  330. ADSP_CORE_DTS_COMPATIBLE, core_id);
  331. if (n < 0 || n > (int)sizeof(compat_name))
  332. return -2;
  333. nodeoffset = fdt_node_offset_by_compatible(fdt, -1, compat_name);
  334. if (nodeoffset < 0) {
  335. dprintf(CRITICAL, "%s failed to find %s in dtb\n",
  336. __func__, compat_name);
  337. return -1;
  338. }
  339. fdt_data = fdt_getprop(fdt, nodeoffset, "system", &len);
  340. if (!fdt_data) {
  341. return -1;
  342. }
  343. data = (uint32_t *)fdt_data + 1;
  344. base = (void *)fdt32_to_cpu(*data);
  345. data = (uint32_t *)fdt_data + 3;
  346. size = fdt32_to_cpu(*data);
  347. set_adsp_image_base(idx, base);
  348. set_adsp_image_size(idx, size);
  349. core_id ++;
  350. }
  351. return 0;
  352. }
  353. int platform_fdt_adsp(void *fdt)
  354. {
  355. int nodeoffset, ret = 0;
  356. uint32_t idx, coreid = 0;
  357. char compat_name[32];
  358. fdt32_t dram_base, dram_size, load;
  359. int n = 0;
  360. nodeoffset = fdt_node_offset_by_compatible(fdt, -1, ADSP_COMMON_DTS_COMPATIBLE);
  361. if (nodeoffset < 0) {
  362. dprintf(CRITICAL, "[ADSP] Failed to find %s in dtb\n",
  363. ADSP_COMMON_DTS_COMPATIBLE);
  364. return -1;
  365. }
  366. load = cpu_to_fdt32(adsp_load_status);
  367. ret = fdt_setprop(fdt, nodeoffset, "load", &load, sizeof(load));
  368. if (ret < 0)
  369. return ret;
  370. /* dram base/size: image naming rule: hifi3_x_sram */
  371. for (idx = 0; idx < ADSP_NUM_IMAGE; idx++) {
  372. if (strstr(image_table[idx].name, "sram") != NULL) {
  373. memset(compat_name, 0, sizeof(compat_name));
  374. n = snprintf(compat_name, sizeof(compat_name), "%s_%d",
  375. ADSP_CORE_DTS_COMPATIBLE, coreid);
  376. if (n < 0 || n > (int)sizeof(compat_name))
  377. return -2;
  378. nodeoffset = fdt_node_offset_by_compatible(fdt, -1, compat_name);
  379. if (nodeoffset < 0) {
  380. dprintf(CRITICAL, "[ADSP] Failed to find %s in dtb\n", compat_name);
  381. return -1;
  382. }
  383. /* pass parameter to kernel */
  384. dram_base = cpu_to_fdt32((uint32_t)image_table[idx].base);
  385. dram_size = cpu_to_fdt32(image_table[idx].size);
  386. ret = fdt_setprop(fdt, nodeoffset, "sysram",
  387. &dram_base, sizeof(dram_base));
  388. if (ret < 0)
  389. return ret;
  390. ret = fdt_setprop(fdt, nodeoffset, "sysram_size",
  391. &dram_size, sizeof(dram_size));
  392. if (ret < 0)
  393. return ret;
  394. dprintf(INFO, "[ADSP] set core_%d sysram base=0x%x, size=0x%x\n",
  395. coreid, (uint32_t)image_table[idx].base, image_table[idx].size);
  396. coreid ++;
  397. }
  398. }
  399. return ret;
  400. }
  401. #endif
  402. int verify_load_adsp_image(char *part_name, void *addr)
  403. {
  404. uint32_t idx, image_size;
  405. void *image_base;
  406. void *load_tcm_base;
  407. load_tcm_base = dram_phys_addr + g_dram_size;
  408. /* load/verify audio dsp images */
  409. for (idx = 0; idx < ADSP_NUM_IMAGE; idx ++) {
  410. if (strstr(image_table[idx].name, "iram") || strstr(image_table[idx].name, "dram")) {
  411. image_base = load_tcm_base;
  412. } else {
  413. image_base = image_table[idx].base;
  414. }
  415. image_size = load_adsp_image(part_name, image_table[idx].name, image_base);
  416. if (image_size > image_table[idx].size || image_size == 0) {
  417. dprintf(CRITICAL, "[ADSP] load_adsp_image fail %s(addr=0x%x, size=0x%x, expected size=0x%x)\n",
  418. image_table[idx].name, (uint32_t)image_table[idx].base, image_size, image_table[idx].size);
  419. return -1;
  420. } else {
  421. dprintf(INFO, "[ADSP] load image #%d %s success.(addr=0x%x, size=0x%x)\n",
  422. idx, image_table[idx].name, (uint32_t)image_base, image_size);
  423. }
  424. if (strstr(image_table[idx].name, "iram") || strstr(image_table[idx].name, "dram")) {
  425. memcpy(image_table[idx].base, load_tcm_base, image_size);
  426. load_tcm_base += image_size;
  427. }
  428. }
  429. return 0;
  430. }
  431. /* adsp power off (DSP suspend) */
  432. void disable_adsp_hw(void)
  433. {
  434. switch_adsp_power(false, true);
  435. dprintf(CRITICAL, "DISABLE ADSP\n");
  436. }
  437. /* platform driver */
  438. static void set_adsp_image_base(uint32_t id, void *base)
  439. {
  440. if (id >= ADSP_NUM_IMAGE) {
  441. dprintf(CRITICAL, "%s fail. id=%d\n", __func__, id);
  442. return;
  443. }
  444. image_table[id].base = base;
  445. }
  446. static void set_adsp_image_size(uint32_t id, uint32_t size)
  447. {
  448. if (id >= ADSP_NUM_IMAGE) {
  449. dprintf(CRITICAL, "%s fail. id=%d\n", __func__, id);
  450. return;
  451. }
  452. image_table[id].size = size;
  453. }
  454. void switch_adsp_power(bool on, bool dormant)
  455. {
  456. dprintf(CRITICAL, "%s on=%d dormant=%d\n", module_prefix, on, dormant);
  457. if (on) {
  458. DRV_SetReg32(MODULE_SW_CG_3_CLR, (CG_ENABLE << CG_OFFSET));
  459. } else {
  460. DRV_SetReg32(MODULE_SW_CG_3_SET, (CG_ENABLE << CG_OFFSET));
  461. }
  462. }
  463. void adsp_sw_reset(void)
  464. {
  465. DRV_SetReg32(ADSP_CFGREG_SW_RSTN, ADSP_SW_RSTN);
  466. udelay(1);
  467. DRV_ClrReg32(ADSP_CFGREG_SW_RSTN, ADSP_SW_RSTN);
  468. }
  469. static void set_adsp_mpu_region(void)
  470. {
  471. struct adsp_region_info_t *adsp_region_info = MPUINFO_REGION_BASE;
  472. memset(MPUINFO_REGION_BASE, 0xFF, MPUINFO_TOTAL_SIZE);
  473. adsp_region_info->adsp_region_start = (uint32_t)dram_phys_addr;
  474. adsp_region_info->adsp_region_size = (uint32_t)g_dram_size;
  475. dsb();
  476. }
  477. static void print_adsp_image_info(void)
  478. {
  479. uint32_t id;
  480. for (id = 0; id < ADSP_NUM_IMAGE; id++) {
  481. dprintf(INFO, "%s id=%d, base=0x%x, size=0x%x\n",
  482. __func__, id, (uint32_t)image_table[id].base, image_table[id].size);
  483. }
  484. }