From d5c38284a1e4f97267b3e57d437445f96c53087e Mon Sep 17 00:00:00 2001 From: Lech Betlej Date: Fri, 19 Oct 2018 14:44:08 +0200 Subject: [PATCH] Set SRAM LDO off on power down - additional power gating on D0->D3 path. Added assembly macros to control state of LDO for LP and HP SRAM. Macros are used during power down procedure to properly handle LDO state. LDO handling sequence in power down procedure is specific for cAVS 1.5. Signed-off-by: Lech Betlej --- .../apollolake/include/platform/Makefile.am | 3 +- .../include/platform/asm_ldo_management.h | 131 ++++++++++++++++++ .../apollolake/include/platform/shim.h | 17 ++- src/platform/apollolake/power_down.S | 20 ++- 4 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 src/platform/apollolake/include/platform/asm_ldo_management.h diff --git a/src/platform/apollolake/include/platform/Makefile.am b/src/platform/apollolake/include/platform/Makefile.am index 47e70257e31d..0a7c3eab92d0 100644 --- a/src/platform/apollolake/include/platform/Makefile.am +++ b/src/platform/apollolake/include/platform/Makefile.am @@ -12,4 +12,5 @@ noinst_HEADERS = \ shim.h \ timer.h \ asm_memory_management.h \ - power_down.h \ No newline at end of file + asm_ldo_management.h \ + power_down.h diff --git a/src/platform/apollolake/include/platform/asm_ldo_management.h b/src/platform/apollolake/include/platform/asm_ldo_management.h new file mode 100644 index 000000000000..304117332d3f --- /dev/null +++ b/src/platform/apollolake/include/platform/asm_ldo_management.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2018, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Intel Corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Author: Lech Betlej + */ + +/** + * \file platform/apollolake/include/platform/asm_ldo_management.h + * \brief Macros for controlling LDO state specific for cAVS 1.5 + * \author Lech Betlej + */ +#ifndef ASM_LDO_MANAGEMENT_H +#define ASM_LDO_MANAGEMENT_H + +#ifndef ASSEMBLY +#warning "Header can only be used by assembly sources." +#endif + +#include + +.macro m_cavs_set_ldo_state state, ax +movi \ax, (SHIM_BASE + SHIM_LDOCTL) +s32i \state, \ax, 0 +memw +// wait loop > 300ns (min 100ns required) +movi \ax, 128 +1 : +addi \ax, \ax, -1 +nop +bnez \ax, 1b +.endm + +.macro m_cavs_set_hpldo_state state, ax, ay +movi \ax, (SHIM_BASE + SHIM_LDOCTL) +l32i \ay, \ax, 0 + +movi \ax, ~(SHIM_LDOCTL_HP_SRAM_MASK) +and \ay, \ax, \ay +or \state, \ay, \state + +m_cavs_set_ldo_state \state, \ax +.endm + +.macro m_cavs_set_lpldo_state state, ax, ay +movi \ax, (SHIM_BASE + SHIM_LDOCTL) +l32i \ay, \ax, 0 +// LP SRAM mask +movi \ax, ~(SHIM_LDOCTL_LP_SRAM_MASK) +and \ay, \ax, \ay +or \state, \ay, \state + +m_cavs_set_ldo_state \state, \ax +.endm + +.macro m_cavs_set_ldo_on_state ax, ay, az +movi \ay, (SHIM_BASE + SHIM_LDOCTL) +l32i \az, \ay, 0 + +movi \ax, ~(SHIM_LDOCTL_HP_SRAM_MASK | SHIM_LDOCTL_LP_SRAM_MASK) +and \az, \ax, \az +movi \ax, (SHIM_LDOCTL_HP_SRAM_LDO_ON | SHIM_LDOCTL_LP_SRAM_LDO_ON) +or \ax, \az, \ax + +m_cavs_set_ldo_state \ax, \ay +.endm + +.macro m_cavs_set_ldo_off_state ax, ay, az +// wait loop > 300ns (min 100ns required) +movi \ax, 128 +1 : + addi \ax, \ax, -1 + nop + bnez \ax, 1b +movi \ay, (SHIM_BASE + SHIM_LDOCTL) +l32i \az, \ay, 0 + +movi \ax, ~(SHIM_LDOCTL_HP_SRAM_MASK | SHIM_LDOCTL_LP_SRAM_MASK) +and \az, \az, \ax + +movi \ax, (SHIM_LDOCTL_HP_SRAM_LDO_OFF | SHIM_LDOCTL_LP_SRAM_LDO_OFF) +or \ax, \ax, \az + +s32i \ax, \ay, 0 +l32i \ax, \ay, 0 +.endm + +.macro m_cavs_set_ldo_bypass_state ax, ay, az +// wait loop > 300ns (min 100ns required) +movi \ax, 128 +1 : + addi \ax, \ax, -1 + nop + bnez \ax, 1b +movi \ay, (SHIM_BASE + SHIM_LDOCTL) +l32i \az, \ay, 0 + +movi \ax, ~(SHIM_LDOCTL_HP_SRAM_MASK | SHIM_LDOCTL_LP_SRAM_MASK) +and \az, \az, \ax + +movi \ax, (SHIM_LDOCTL_HP_SRAM_LDO_BYPASS | SHIM_LDOCTL_LP_SRAM_LDO_BYPASS) +or \ax, \ax, \az + +s32i \ax, \ay, 0 +l32i \ax, \ay, 0 +.endm + +#endif /* ASM_LDO_MANAGEMENT_H */ diff --git a/src/platform/apollolake/include/platform/shim.h b/src/platform/apollolake/include/platform/shim.h index cfa10b533d72..b658cc4afbb4 100644 --- a/src/platform/apollolake/include/platform/shim.h +++ b/src/platform/apollolake/include/platform/shim.h @@ -145,9 +145,6 @@ #define SHIM_DSPWCTCS_T1A (0x1 << 1) /* Timer 1 armed */ #define SHIM_DSPWCTCS_T0A (0x1 << 0) /* Timer 0 armed */ -/** \brief LDO Control */ -#define SHIM_LDOCTL 0xA4 - /** \brief Clock control */ #define SHIM_CLKCTL 0x78 @@ -219,10 +216,22 @@ /* HP & LP SRAM Power Gating */ #define SHIM_HSPGCTL 0x80 #define SHIM_LSPGCTL 0x84 -#define SHIM_SPSREQ 0xa0 +#define SHIM_SPSREQ 0xa0 #define SHIM_SPSREQ_RVNNP (0x1 << 0) +/** \brief LDO Control */ +#define SHIM_LDOCTL 0xA4 + +#define SHIM_LDOCTL_HP_SRAM_MASK (3 << 0) +#define SHIM_LDOCTL_LP_SRAM_MASK (3 << 2) +#define SHIM_LDOCTL_HP_SRAM_LDO_ON (3 << 0) +#define SHIM_LDOCTL_LP_SRAM_LDO_ON (3 << 2) +#define SHIM_LDOCTL_HP_SRAM_LDO_BYPASS BIT(0) +#define SHIM_LDOCTL_LP_SRAM_LDO_BYPASS BIT(2) +#define SHIM_LDOCTL_HP_SRAM_LDO_OFF (0 << 0) +#define SHIM_LDOCTL_LP_SRAM_LDO_OFF (0 << 2) + #define SHIM_HSPGISTS 0xb0 #define SHIM_LSPGISTS 0xb4 diff --git a/src/platform/apollolake/power_down.S b/src/platform/apollolake/power_down.S index b75c7b4cfbe0..1074e602b6b1 100644 --- a/src/platform/apollolake/power_down.S +++ b/src/platform/apollolake/power_down.S @@ -34,6 +34,7 @@ * \author Lech Betlej */ #include +#include .section .text, "ax" .align 64 @@ -86,12 +87,17 @@ power_down: // if b_enable_lpsram = 0 (bool disable_lpsram) - do not disable lpsram. beqz b_enable_lpsram, _PD_DISABLE_HPSRAM - _PD_DISABLE_LPSRAM: - m_cavs_lpsram_power_off temp_reg0, temp_reg1, temp_reg2 + movi temp_reg0, SHIM_LDOCTL_LP_SRAM_LDO_ON + m_cavs_set_lpldo_state temp_reg0, temp_reg1, temp_reg2 + + m_cavs_lpsram_power_off temp_reg0, temp_reg1, temp_reg2 + + movi temp_reg0, SHIM_LDOCTL_LP_SRAM_LDO_OFF + m_cavs_set_lpldo_state temp_reg0, temp_reg1, temp_reg2 - // DISABLE_HPSRAM is aligned so there can be zeros between it - // and last instr. + // DISABLE_HPSRAM is aligned so there can be zeros between + //it and last instr. j _PD_DISABLE_HPSRAM // workaround for incidental gnu assembler bug - no alignment here @@ -103,10 +109,14 @@ _PD_DISABLE_HPSRAM: l32i temp_reg0, pu32_hpsram_mask, 0 beqz temp_reg0, _PD_SLEEP - // TODO: add full support switching off LDO incl. HW W/A + movi temp_reg0, SHIM_LDOCTL_HP_SRAM_LDO_ON + m_cavs_set_hpldo_state temp_reg0, temp_reg1, temp_reg2 + // Disable L2 cache in case it would be enabled m_cavs_hpsram_power_off temp_reg0, temp_reg1, temp_reg2 + movi temp_reg0, SHIM_LDOCTL_HP_SRAM_LDO_OFF + m_cavs_set_hpldo_state temp_reg0, temp_reg1, temp_reg2 // For BXT-P we need to deassert VNN request and select slow XTAL // as clock source