mirror of https://github.com/thesofproject/sof.git
pm_memory: add functionality to handle also LP SRAM
Refactors pm_memory in order to add functionality to also power gate LP SRAM in a similar fashion. Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
This commit is contained in:
parent
91bdf1a5de
commit
11265e3e4f
|
@ -14,6 +14,8 @@
|
|||
#ifndef __CAVS_LIB_PM_MEMORY_H__
|
||||
#define __CAVS_LIB_PM_MEMORY_H__
|
||||
|
||||
#include <config.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** \brief Memory banks pm masks data. */
|
||||
|
@ -31,16 +33,51 @@ struct ebb_data {
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Set power gating of memory banks in the address range
|
||||
* \brief Sets HP SRAM enabled gating hw bit mask for memory banks.
|
||||
* \param[in] start_bank_id Id of first bank to be managed (inclusive) 0 based.
|
||||
* \param[in] ending_bank_id Id of last bank to be managed (inclusive) 0 based.
|
||||
* \param[in] enabled Deciding banks desired state (true powered false gated).
|
||||
*/
|
||||
void cavs_pm_memory_hp_sram_banks_power_gate(uint32_t start_bank_id,
|
||||
uint32_t ending_bank_id,
|
||||
bool enabled);
|
||||
|
||||
/**
|
||||
* \brief Sets HP SRAM power gating.
|
||||
*
|
||||
* Power gates address range only on full banks if given address form mid block
|
||||
* it will try to narrow down power gate to nearest full banks
|
||||
* Power gates address range only on full banks. If given address form mid block
|
||||
* it will try to narrow down power gate to nearest full banks.
|
||||
*
|
||||
* \param[in] ptr Ptr to address from which to start gating.
|
||||
* \param[in] size Size of memory to manage.
|
||||
* \param[in] enabled Boolean deciding banks desired state (1 powered 0 gated).
|
||||
* \param[in] enabled Deciding banks desired state (true powered false gated).
|
||||
*/
|
||||
void set_power_gate_for_memory_address_range(void *ptr, uint32_t size,
|
||||
uint32_t enabled);
|
||||
void cavs_pm_memory_hp_sram_power_gate(void *ptr, uint32_t size, bool enabled);
|
||||
|
||||
#if CONFIG_LP_SRAM
|
||||
|
||||
/**
|
||||
* \brief Sets LP SRAM enabled gating hw bit mask for memory banks.
|
||||
* \param[in] start_bank_id Id of first bank to be managed (inclusive) 0 based.
|
||||
* \param[in] ending_bank_id Id of last bank to be managed (inclusive) 0 based.
|
||||
* \param[in] enabled Deciding banks desired state (true powered false gated).
|
||||
*/
|
||||
void cavs_pm_memory_lp_sram_banks_power_gate(uint32_t start_bank_id,
|
||||
uint32_t ending_bank_id,
|
||||
bool enabled);
|
||||
|
||||
/**
|
||||
* \brief Sets LP SRAM power gating.
|
||||
*
|
||||
* Power gates address range only on full banks. If given address form mid block
|
||||
* it will try to narrow down power gate to nearest full banks.
|
||||
*
|
||||
* \param[in] ptr Ptr to address from which to start gating.
|
||||
* \param[in] size Size of memory to manage.
|
||||
* \param[in] enabled Deciding banks desired state (true powered false gated).
|
||||
*/
|
||||
void cavs_pm_memory_lp_sram_power_gate(void *ptr, uint32_t size, bool enabled);
|
||||
|
||||
#endif /* CONFIG_LP_SRAM */
|
||||
|
||||
#endif /* __CAVS_LIB_PM_MEMORY_H__ */
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <sof/lib/wait.h>
|
||||
#include <sof/trace/trace.h>
|
||||
#include <user/trace.h>
|
||||
#include <config.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* 14f25ab6-3a4b-4e5d-b343-2a142d4e4d92 */
|
||||
|
@ -27,6 +29,41 @@ DECLARE_TR_CTX(pm_mem_tr, SOF_UUID(pm_mem_uuid), LOG_LEVEL_INFO);
|
|||
|
||||
#define EBB_SEGMENT_SIZE_ZERO_BASE (EBB_SEGMENT_SIZE - 1)
|
||||
#define MEMORY_POWER_DOWN_DELAY 256
|
||||
|
||||
/**
|
||||
* \brief Retrieves memory banks based on start and end pointer.
|
||||
* \param[in,out] start Start address of memory range.
|
||||
* \param[in,out] end End address of memory range.
|
||||
* \param[in] base Base address of memory range.
|
||||
* \param[in,out] start_bank Start bank id calculated by this function.
|
||||
* \param[in,out] end_bank End bank id calculated by this function.
|
||||
*/
|
||||
static void memory_banks_get(void *start, void *end, uint32_t base,
|
||||
uint32_t *start_bank, uint32_t *end_bank)
|
||||
{
|
||||
/* if ptr is not aligned to bank size change it to
|
||||
* closest possible memory address at the start of bank
|
||||
* or end for end address
|
||||
*/
|
||||
if ((uintptr_t)start % SRAM_BANK_SIZE)
|
||||
start = (void *)ALIGN((uintptr_t)start, SRAM_BANK_SIZE);
|
||||
|
||||
if ((uintptr_t)end % SRAM_BANK_SIZE)
|
||||
end = (void *)ALIGN_DOWN((uintptr_t)end, SRAM_BANK_SIZE);
|
||||
|
||||
/* return if no full bank could be found for enabled gate control */
|
||||
if ((char *)end - (char *)start < SRAM_BANK_SIZE) {
|
||||
tr_info(&pm_mem_tr, "cavs_pm_memory_banks_get(): cannot find full bank to perform gating operation");
|
||||
return;
|
||||
}
|
||||
|
||||
*start_bank = ((uintptr_t)start - base) / SRAM_BANK_SIZE;
|
||||
/* Ending bank id has to be lowered by one because it is
|
||||
* calculated from memory end ptr
|
||||
*/
|
||||
*end_bank = ((uintptr_t)end - base) / SRAM_BANK_SIZE - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read masks from hw registers and prepare new masks from data
|
||||
* \param[in] ebb_data All masks data required for calculations.
|
||||
|
@ -137,14 +174,9 @@ static void write_new_masks_and_check_status(struct ebb_data *ebb)
|
|||
idelay(MEMORY_POWER_DOWN_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set memory enabled gating hw bit mask for memory banks
|
||||
* \param[in] start_bank_id Id of first bank to be managed (inclusive) 0 based.
|
||||
* \param[in] ending_bank_id Id of last bank to be managed (inclusive) 0 based.
|
||||
* \param[in] enabled Boolean deciding banks desired state (1 powered 0 gated).
|
||||
*/
|
||||
static void set_banks_gating(uint32_t start_bank_id, uint32_t ending_bank_id,
|
||||
uint32_t enabled)
|
||||
void cavs_pm_memory_hp_sram_banks_power_gate(uint32_t start_bank_id,
|
||||
uint32_t ending_bank_id,
|
||||
bool enabled)
|
||||
{
|
||||
struct ebb_data ebb = { 0 };
|
||||
|
||||
|
@ -170,37 +202,51 @@ static void set_banks_gating(uint32_t start_bank_id, uint32_t ending_bank_id,
|
|||
shim_write(SHIM_LDOCTL, SHIM_LDOCTL_HPSRAM_LDO_BYPASS);
|
||||
}
|
||||
|
||||
void set_power_gate_for_memory_address_range(void *ptr,
|
||||
uint32_t size, uint32_t enabled)
|
||||
void cavs_pm_memory_hp_sram_power_gate(void *ptr, uint32_t size, bool enabled)
|
||||
{
|
||||
uint32_t start_bank_id;
|
||||
uint32_t ending_bank_id;
|
||||
void *end_ptr = (char *)ptr + size;
|
||||
uint32_t start_bank = 0;
|
||||
uint32_t end_bank = 0;
|
||||
|
||||
/* if ptr is not aligned to bank size change it to
|
||||
* closest possible memory address at the start of bank
|
||||
* or end for end address
|
||||
*/
|
||||
if ((uintptr_t)ptr % SRAM_BANK_SIZE)
|
||||
ptr = (void *)ALIGN((uintptr_t)ptr, SRAM_BANK_SIZE);
|
||||
memory_banks_get(ptr, (char *)ptr + size, HP_SRAM_BASE, &start_bank,
|
||||
&end_bank);
|
||||
|
||||
if ((uintptr_t)end_ptr % SRAM_BANK_SIZE)
|
||||
end_ptr = (void *)ALIGN_DOWN((uintptr_t)ptr, SRAM_BANK_SIZE);
|
||||
|
||||
/* return if no full bank could be found for enabled gate control */
|
||||
if ((char *)end_ptr - (char *)ptr < SRAM_BANK_SIZE) {
|
||||
tr_info(&pm_mem_tr, "Could not find full bank to perform gating operation");
|
||||
return;
|
||||
cavs_pm_memory_hp_sram_banks_power_gate(start_bank, end_bank, enabled);
|
||||
}
|
||||
|
||||
start_bank_id = ((uintptr_t)ptr - HP_SRAM_BASE) / SRAM_BANK_SIZE;
|
||||
/* Ending bank id has to be lowered by one because it is
|
||||
* calculated from memory end ptr
|
||||
*/
|
||||
ending_bank_id = ((uintptr_t)end_ptr - HP_SRAM_BASE)
|
||||
/ SRAM_BANK_SIZE - 1;
|
||||
#if CONFIG_LP_SRAM
|
||||
|
||||
set_banks_gating(start_bank_id, ending_bank_id, enabled);
|
||||
void cavs_pm_memory_lp_sram_banks_power_gate(uint32_t start_bank_id,
|
||||
uint32_t ending_bank_id,
|
||||
bool enabled)
|
||||
{
|
||||
uint32_t mask = MASK(ending_bank_id, start_bank_id);
|
||||
uint32_t expected = enabled ? 0 : mask;
|
||||
|
||||
shim_write(SHIM_LDOCTL, SHIM_LDOCTL_LPSRAM_LDO_ON);
|
||||
|
||||
idelay(MEMORY_POWER_DOWN_DELAY);
|
||||
|
||||
io_reg_update_bits(LSPGCTL, mask, enabled ? 0 : mask);
|
||||
|
||||
idelay(MEMORY_POWER_DOWN_DELAY);
|
||||
|
||||
while ((io_reg_read(LSPGISTS) & mask) != expected)
|
||||
idelay(MEMORY_POWER_DOWN_DELAY);
|
||||
|
||||
shim_write(SHIM_LDOCTL, SHIM_LDOCTL_HPSRAM_LDO_BYPASS);
|
||||
}
|
||||
|
||||
#endif
|
||||
void cavs_pm_memory_lp_sram_power_gate(void *ptr, uint32_t size, bool enabled)
|
||||
{
|
||||
uint32_t start_bank = 0;
|
||||
uint32_t end_bank = 0;
|
||||
|
||||
memory_banks_get(ptr, (char *)ptr + size, LP_SRAM_BASE, &start_bank,
|
||||
&end_bank);
|
||||
|
||||
cavs_pm_memory_lp_sram_banks_power_gate(start_bank, end_bank, enabled);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LP_SRAM */
|
||||
|
||||
#endif /* CAVS_VERSION >= CAVS_VERSION_1_8 */
|
||||
|
|
|
@ -313,8 +313,8 @@ static inline void cavs_pm_runtime_core_dis_memory(uint32_t index)
|
|||
core_memory_ptr = (char *)&_sof_core_s_start
|
||||
+ (index - 1) * SOF_CORE_S_SIZE;
|
||||
|
||||
set_power_gate_for_memory_address_range(core_memory_ptr,
|
||||
SOF_CORE_S_SIZE, 0);
|
||||
cavs_pm_memory_hp_sram_power_gate(core_memory_ptr, SOF_CORE_S_SIZE,
|
||||
false);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -331,8 +331,8 @@ static inline void cavs_pm_runtime_core_en_memory(uint32_t index)
|
|||
core_memory_ptr = (char *)&_sof_core_s_start
|
||||
+ (index - 1) * SOF_CORE_S_SIZE;
|
||||
|
||||
set_power_gate_for_memory_address_range(core_memory_ptr,
|
||||
SOF_CORE_S_SIZE, 1);
|
||||
cavs_pm_memory_hp_sram_power_gate(core_memory_ptr, SOF_CORE_S_SIZE,
|
||||
true);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue