zephyr/soc/xtensa/intel_adsp/cavs/power_down_cavs.S

157 lines
3.5 KiB
ArmAsm

/* Copyright (c) 2022 Intel Corporation
* SPDX-License-Identifier: Apache-2.0
*/
#include "asm_ldo_management.h"
#include "asm_memory_management.h"
#include "adsp_memory.h"
#define IPC_HOST_BASE 0x00071E00
#define IPC_DIPCIDD 0x18
#define IPC_DIPCIDR 0x10
.section .text, "ax"
.align 64
power_down_literals:
.literal_position
set_dx_reply:
/* BUSY (bit31), MODULE_MSG (bit30), reply (bit29), SET_DX (bit 24-28: 7) */
.word 0xE7000000
sram_dis_loop_cnt:
.word 4096
.global power_down_cavs
.type power_down_cavs, @function
/**
* Perform power down.
*
* Depending on arguments, memories are switched off.
* A2 - argument for LPSRAM
* A3 - pointer to array containing power gating mask.
*Size of array is determined by MEMORY_SEGMENTS define.
* A4 - platform type
* A5 - response_to_ipc
*/
#define b_enable_lpsram a2
#define pu32_hpsram_mask a3
#define temp_reg0 a6
#define temp_reg1 a7
#define temp_reg2 a8
#define temp_reg3 a9
#define host_base a10
#define pfl_reg a15
power_down_cavs:
entry sp, 32
/**
* effectively executes:
* xthal_dcache_region_lock(&literals, 128);
* xthal_dcache_region_lock(&powerdown, 256);
* xthal_dcache_region_lock(&pu32_hpsram_mask, 64);
*/
movi pfl_reg, power_down_literals
dpfl pfl_reg, 0
dpfl pfl_reg, 64
movi pfl_reg, power_down_cavs
ipfl pfl_reg, 0
ipfl pfl_reg, 64
ipfl pfl_reg, 128
ipfl pfl_reg, 192
mov pfl_reg, pu32_hpsram_mask
dpfl pfl_reg, 0
movi host_base, IPC_HOST_BASE
_PD_DISABLE_LPSRAM:
/* effectively executes:
* if (b_enable_lpsram){
* cavs_lpsram_power_down_entire();
* }
*/
beqz b_enable_lpsram, _PD_DISABLE_HPSRAM
m_cavs_lpsram_power_down_entire temp_reg0, temp_reg1, temp_reg2, sram_dis_loop_cnt
j _PD_DISABLE_HPSRAM
_PD_DISABLE_HPSRAM:
/* if value in memory pointed by pu32_hpsram_mask = 0
(hpsram_pwrgating_mask) - do not disable hpsram. */
beqz pu32_hpsram_mask, _PD_SEND_IPC
/* mandatory sequence for LDO ON - effectively executes:
* m_cavs_s_set_ldo_hpsram_on_state();
* WAIT_300NS();
*/
movi temp_reg0, SHIM_LDOCTL_HPSRAM_LDO_ON
m_cavs_set_hpldo_state temp_reg0, temp_reg1, temp_reg2
movi temp_reg0, 128
1 :
addi temp_reg0, temp_reg0, -1
bnez temp_reg0, 1b
/* effectively executes:
* for (size_t seg_index = (MAX_MEMORY_SEGMENTS - 1); seg_index >= 0;
* --seg_index) {
* cavs_hpsram_power_change(seg_index, mask[seg_index]);
* }
* where mask is given in pu32_hpsram_mask register
*/
.set seg_index, HPSRAM_SEGMENTS - 1
.rept HPSRAM_SEGMENTS
l32i temp_reg0, pu32_hpsram_mask, 4 * seg_index
m_cavs_hpsram_power_change\
/*segment_index=*/ seg_index,\
/*mask=*/ temp_reg0,\
temp_reg1,\
temp_reg2,\
temp_reg3
.set seg_index, seg_index - 1
.endr
/* mandatory sequence for LDO OFF - effectively executes:
* WAIT_300NS();
* m_cavs_set_ldo_hpsram_on_state()
*/
movi temp_reg0, 128
1 :
addi temp_reg0, temp_reg0, -1
bnez temp_reg0, 1b
movi temp_reg0, SHIM_LDOCTL_HPSRAM_LDO_OFF
m_cavs_set_hpldo_state temp_reg0, temp_reg1, temp_reg2
_PD_SEND_IPC:
/* Send IPC reply for SET_DX message */
movi temp_reg1, 0
s32i temp_reg1, host_base, IPC_DIPCIDD
movi temp_reg1, set_dx_reply
l32i temp_reg1, temp_reg1, 0
s32i temp_reg1, host_base, IPC_DIPCIDR
_PD_SLEEP:
/* effecfively executes:
* xmp_spin()
* waiti 5
*/
movi temp_reg0, 128
loop:
addi temp_reg0, temp_reg0, -1
bnez temp_reg0, loop
extw
extw
waiti 5
1:
j 1b
.size power_down_cavs , . - power_down_cavs