Merge pull request #561 from lbetlej/cnl_pg_sram_on_d3

Added SRAM power gating on D3 entry for cAVS 1.8 (i.e. Cannonlake).
This commit is contained in:
Liam Girdwood 2018-11-13 14:59:18 +00:00 committed by GitHub
commit 4c8deb72a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 341 additions and 11 deletions

View File

@ -50,8 +50,14 @@
#include <platform/platform.h>
#include <sof/audio/component.h>
#include <sof/audio/pipeline.h>
//<<<<<<< HEAD
#include <uapi/ipc/header.h>
//=======
//#include <uapi/ipc.h>
//#include <sof/intel-ipc.h>
#include <platform/pm_runtime.h>
//>>>>>>> Added SRAM power gating on D3 entry for cAVS 1.8 (i.e. Cannonlake).
extern struct ipc *_ipc;
/* test code to check working IRQ */
@ -139,8 +145,14 @@ done:
// TODO: signal audio work to enter D3 in normal context
/* are we about to enter D3 ? */
if (iipc->pm_prepare_D3) {
#if defined(CONFIG_CANNONLAKE)
/* no return - memory will be powered off */
platform_pm_runtime_power_off();
#else
//TODO: add support for Icelake, consider a spearate file icl-ipc.c
while (1)
wait_for_interrupt(0);
#endif
}
tracev_ipc("CmD");

View File

@ -8,7 +8,7 @@ noinst_LTLIBRARIES = libplatform.la
libplatform_la_LIBADD = ../intel/cavs/libcavsplatform.la
libplatform_la_SOURCES =
libplatform_la_SOURCES = power_down.S
libplatform_la_CFLAGS = \
$(AM_CFLAGS) \
@ -17,6 +17,12 @@ libplatform_la_CFLAGS = \
$(PLATFORM_INCDIR) \
$(SOF_INCDIR)
libplatform_la_CCASFLAGS = \
$(ARCH_INCDIR) \
$(ASFLAGS) \
$(ARCH_ASFLAGS) \
$(PLATFORM_INCDIR)
noinst_PROGRAMS = module boot_module
module_SOURCES = \

View File

@ -10,4 +10,6 @@ noinst_HEADERS = \
platform.h \
pm_runtime.h \
shim.h \
timer.h
timer.h \
asm_memory_management.h \
power_down.h

View File

@ -0,0 +1,112 @@
/*
* 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 <lech.betlej@linux.intel.com>
*/
/**
* \file platform/cannonlake/include/platform/asm_memory_management.h
* \brief Macros for power gating memory banks specific for cAVS 1.8
* \(CannonLake)
* \author Lech Betlej <lech.betlej@linux.intel.com>
*/
#ifndef ASM_MEMORY_MANAGEMENT_H
#define ASM_MEMORY_MANAGEMENT_H
#ifndef ASSEMBLY
#warning "ASSEMBLY macro not defined. Header can't be inluded in C files"
#warning "The file is intended to be includded in assembly files only."
#endif
#include <platform/shim.h>
#include <platform/platcfg.h>
#define MAX_EBB_BANKS_IN_SEGMENT 32
#define HPSRAM_MASK(seg_idx)\
((1 << (PLATFORM_HPSRAM_EBB_COUNT\
- MAX_EBB_BANKS_IN_SEGMENT * seg_idx)) - 1)
#define LPSRAM_MASK ((1 << PLATFORM_LPSRAM_EBB_COUNT) - 1)
#define MAX_MEMORY_SEGMENTS ((PLATFORM_HPSRAM_EBB_COUNT + \
MAX_EBB_BANKS_IN_SEGMENT - 1) / MAX_EBB_BANKS_IN_SEGMENT)
/**
* powers down entire hpsram. on entry lirerals and code for section from
* where this code is executed needs to be placed in memory which is not
* HPSRAM (in case when this code is located in HPSRAM, lock memory in L1$ or
* L1 SRAM)
*/
.macro m_cavs_hpsram_power_down_entire ax, ay, az
//TODO: add LDO control
// SEGMENT #0
movi \az, SHIM_HSPGCTL(0)
movi \ax, SHIM_HSPGISTS(0)
movi \ay, HPSRAM_MASK(0)
s32i \ay, \ax, 0
memw
1 :
l32i \ax, \az, 0
bne \ax, \ay, 1b
// SEGMENT #1
movi \az, SHIM_HSPGCTL(1)
movi \ax, SHIM_HSPGISTS(1)
movi \ay, HPSRAM_MASK(1)
s32i \ay, \ax, 0
memw
1 :
l32i \ax, \az, 0
bne \ax, \ay, 1b
// TODO: Add LDO control
.endm
.macro m_cavs_hpsram_power_change segment_index, mask, ax, ay, az
// TODO: Add LDO Control
movi \ax, SHIM_HSPGCTL(\segment_index)
movi \ay, SHIM_HSPGISTS(\segment_index)
s32i \mask, \ax, 0
memw
// assumed that HDA shared dma buffer will be in LPSRAM
1 :
l32i \ax, \ay, 0
bne \ax, \mask, 1b
// TODO: Add LDO Control
.endm
.macro m_cavs_lpsram_power_down_entire ax, ay, az
movi \az, LSPGISTS
movi \ax, LSPGCTL
movi \ay, LPSRAM_MASK
s32i \ay, \ax, 0
memw
// assumed that HDA shared dma buffer will be in LPSRAM
movi \ax, 4096
1 :
addi \ax, \ax, -1
bnez \ax, 1b
.endm
#endif /* ASM_MEMORY_MANAGEMENT_H */

View File

@ -35,6 +35,12 @@
#define PLATFORM_CORE_COUNT 4
#define PLATFORM_LPSRAM_EBB_COUNT 1
#define PLATFORM_HPSRAM_EBB_COUNT 47
#define PLATFORM_HPSRAM_SEGMENTS 2
#define PLATFORM_MASTER_CORE_ID 0
#endif

View File

@ -70,4 +70,9 @@ void platform_pm_runtime_get(enum pm_runtime_context context, uint32_t index,
void platform_pm_runtime_put(enum pm_runtime_context context, uint32_t index,
uint32_t flags);
/**
* \brief Power gates platform specific hardware resources.
*/
void platform_pm_runtime_power_off(void);
#endif /* __INCLUDE_PLATFORM_PM_RUNTIME__ */

View File

@ -0,0 +1,43 @@
/*
* 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 <lech.betlej@linux.intel.com>
*/
#ifndef CANNONLAKE_INCLUDE_PLATFORM_POWER_DOWN_H
#define CANNONLAKE_INCLUDE_PLATFORM_POWER_DOWN_H
#include <stdbool.h>
/**
* Power down procedure.
* Locks its code in L1 cache and shuts down memories.
* @param disable_lpsram flag if LPSRAM is to be disabled (whole)
* @param hpsram_pwrgating_mask pointer to memory segments power gating mask
* (each bit corresponds to one ebb)
* @return nothing returned - this function never quits
*/
void power_down(bool disable_lpsram, uint32_t *hpsram_pwrgating_mask);
#endif /* CANNONLAKE_INCLUDE_PLATFORM_POWER_DOWN_H */

View File

@ -196,6 +196,9 @@
#define HSRMCTL1 0x71D24
#define HSPGISTS1 0x71D28
#define SHIM_HSPGCTL(x) (HSPGCTL0 + 0x10 * (x))
#define SHIM_HSPGISTS(x) (HSPGISTS0 + 0x18 * (x))
#define LSPGCTL 0x71D50
#define LSRMCTL 0x71D54
#define LSPGISTS 0x71D58

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2016, 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 <lech.betlej@linux.intel.com>
*/
/**
* \file platform/apollolake/power_down.S
* \brief Power gating memory banks - implementation specific for Apollolake
* \author Lech Betlej <lech.betlej@linux.intel.com>
*/
#include <platform/asm_memory_management.h>
.section .text, "ax"
.align 64
literals:
.literal_position
.global power_down
.type power_down, @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
*/
//TODO: add IPC reply sending before core enters waiti
#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 pfl_reg a15
power_down:
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, literals
dpfl pfl_reg, 0
dpfl pfl_reg, 64
movi pfl_reg, power_down
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
_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
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_SLEEP
/* 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, MAX_MEMORY_SEGMENTS - 1
.rept MAX_MEMORY_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
//TODO: add LDO Control
//TODO: add sending IPC reply from L1$ locked code
_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
j _PD_SLEEP
.size power_down , . - power_down

View File

@ -40,8 +40,8 @@
#include <platform/pm_runtime.h>
#include <platform/dai.h>
#if defined(CONFIG_APOLLOLAKE)
//TODO: add support or at least stub api for Cannonlake & Icelake
#if defined(CONFIG_APOLLOLAKE) || defined(CONFIG_CANNONLAKE)
//TODO: add support or at least stub api for Icelake based on Cannonlake
#include <platform/power_down.h>
#endif
@ -229,15 +229,16 @@ void platform_pm_runtime_put(enum pm_runtime_context context, uint32_t index,
}
}
#if defined(CONFIG_APOLLOLAKE)
#if defined(CONFIG_APOLLOLAKE) || defined(CONFIG_CANNONLAKE)
void platform_pm_runtime_power_off(void)
{
uint32_t hpsram_mask[PLATFORM_HPSRAM_SEGMENTS];
uint32_t hpsram_mask[PLATFORM_HPSRAM_SEGMENTS], i;
//TODO: add LDO control for LP SRAM - set LDO BYPASS & LDO ON
//TODO: mask to be used in the future for run-time power management of
//SRAM banks
//TODO: hpsram_mask to be used in the future for run-time
//power management of SRAM banks i.e use. HPSRAM_MASK() macro
/* power down entire HPSRAM */
hpsram_mask[0] = 0x1;
for (i = 0; i < PLATFORM_HPSRAM_SEGMENTS; i++)
hpsram_mask[i] = UINT32_MAX;
power_down(true, hpsram_mask);
}