1/* Copyright (c) 2022 Intel Corporation 2 * SPDX-License-Identifier: Apache-2.0 3 */ 4 5#include "asm_ldo_management.h" 6#include "asm_memory_management.h" 7#include "adsp_memory.h" 8 9#define IPC_HOST_BASE 0x00071E00 10#define IPC_DIPCIDD 0x18 11#define IPC_DIPCIDR 0x10 12 13 .section .text, "ax" 14 .align 64 15power_down_literals: 16 .literal_position 17set_dx_reply: 18 /* BUSY (bit31), MODULE_MSG (bit30), reply (bit29), SET_DX (bit 24-28: 7) */ 19 .word 0xE7000000 20sram_dis_loop_cnt: 21 .word 4096 22 23 .global power_down_cavs 24 .type power_down_cavs, @function 25 26/** 27 * Perform power down. 28 * 29 * Depending on arguments, memories are switched off. 30 * A2 - argument for LPSRAM 31 * A3 - pointer to array containing power gating mask. 32 *Size of array is determined by MEMORY_SEGMENTS define. 33 * A4 - platform type 34 * A5 - response_to_ipc 35 */ 36 37#define b_enable_lpsram a2 38#define pu32_hpsram_mask a3 39#define temp_reg0 a6 40#define temp_reg1 a7 41#define temp_reg2 a8 42#define temp_reg3 a9 43#define host_base a10 44#define pfl_reg a15 45 46power_down_cavs: 47 entry sp, 32 48 /** 49 * effectively executes: 50 * xthal_dcache_region_lock(&literals, 128); 51 * xthal_icache_region_lock(&powerdown, 256); 52 * xthal_dcache_region_lock(&pu32_hpsram_mask, 64); 53 */ 54 movi pfl_reg, power_down_literals 55 dpfl pfl_reg, 0 56 dpfl pfl_reg, 64 57 58 movi pfl_reg, power_down_cavs 59 ipfl pfl_reg, 0 60 ipfl pfl_reg, 64 61 ipfl pfl_reg, 128 62 ipfl pfl_reg, 192 63 64 mov pfl_reg, pu32_hpsram_mask 65 dpfl pfl_reg, 0 66 67 movi host_base, IPC_HOST_BASE 68 69_PD_DISABLE_LPSRAM: 70/* effectively executes: 71 * if (b_enable_lpsram){ 72 * cavs_lpsram_power_down_entire(); 73 * } 74 */ 75 beqz b_enable_lpsram, _PD_DISABLE_HPSRAM 76 m_cavs_lpsram_power_down_entire temp_reg0, temp_reg1, temp_reg2, sram_dis_loop_cnt 77 j _PD_DISABLE_HPSRAM 78 79_PD_DISABLE_HPSRAM: 80 /* if value in memory pointed by pu32_hpsram_mask = 0 81 (hpsram_pwrgating_mask) - do not disable hpsram. */ 82 beqz pu32_hpsram_mask, _PD_SEND_IPC 83 84/* mandatory sequence for LDO ON - effectively executes: 85 * m_cavs_s_set_ldo_hpsram_on_state(); 86 * WAIT_300NS(); 87 */ 88 movi temp_reg0, SHIM_LDOCTL_HPSRAM_LDO_ON 89 m_cavs_set_hpldo_state temp_reg0, temp_reg1, temp_reg2 90 movi temp_reg0, 128 911 : 92 addi temp_reg0, temp_reg0, -1 93 bnez temp_reg0, 1b 94 95 96/* effectively executes: 97 * for (size_t seg_index = (MAX_MEMORY_SEGMENTS - 1); seg_index >= 0; 98 * --seg_index) { 99 * cavs_hpsram_power_change(seg_index, mask[seg_index]); 100 * } 101 * where mask is given in pu32_hpsram_mask register 102 */ 103 104 .set seg_index, HPSRAM_SEGMENTS - 1 105 .rept HPSRAM_SEGMENTS 106 l32i temp_reg0, pu32_hpsram_mask, 4 * seg_index 107 m_cavs_hpsram_power_change\ 108 /*segment_index=*/ seg_index,\ 109 /*mask=*/ temp_reg0,\ 110 temp_reg1,\ 111 temp_reg2,\ 112 temp_reg3 113 .set seg_index, seg_index - 1 114 .endr 115 116 117/* mandatory sequence for LDO OFF - effectively executes: 118 * WAIT_300NS(); 119 * m_cavs_set_ldo_hpsram_on_state() 120 */ 121 movi temp_reg0, 128 1221 : 123 addi temp_reg0, temp_reg0, -1 124 bnez temp_reg0, 1b 125 126 movi temp_reg0, SHIM_LDOCTL_HPSRAM_LDO_OFF 127 m_cavs_set_hpldo_state temp_reg0, temp_reg1, temp_reg2 128 129_PD_SEND_IPC: 130/* Send IPC reply for SET_DX message */ 131 movi temp_reg1, 0 132 s32i temp_reg1, host_base, IPC_DIPCIDD 133 134 movi temp_reg1, set_dx_reply 135 l32i temp_reg1, temp_reg1, 0 136 s32i temp_reg1, host_base, IPC_DIPCIDR 137 138_PD_SLEEP: 139/* effecfively executes: 140 * xmp_spin() 141 * waiti 5 142 */ 143 movi temp_reg0, 128 144loop: 145 addi temp_reg0, temp_reg0, -1 146 bnez temp_reg0, loop 147 148 extw 149 extw 150 waiti 5 151 1: 152 j 1b 153 154.size power_down_cavs , . - power_down_cavs 155 156 157