156 lines
3.9 KiB
C
156 lines
3.9 KiB
C
|
|
#include "k_api.h"
|
||
|
|
#include "cpu_pwr_config.h"
|
||
|
|
|
||
|
|
//#if RHINO_CONFIG_CPU_PWR_MGMT
|
||
|
|
|
||
|
|
#include "cpu_pwr_hal_lib.h"
|
||
|
|
#include "pwr_debug.h"
|
||
|
|
#include "soc.h"
|
||
|
|
|
||
|
|
#if RHINO_CONFIG_CPU_TICKLESS
|
||
|
|
#include "cpu_tickless.h"
|
||
|
|
#endif /*RHINO_CONFIG_CPU_TICKLESS*/
|
||
|
|
|
||
|
|
#ifdef CONFIG_TEE_CA
|
||
|
|
#include "drv_tee.h"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* forward declarations */
|
||
|
|
|
||
|
|
extern cpu_pwr_t *p_cpu_pwr_root_node;
|
||
|
|
|
||
|
|
#if RHINO_CONFIG_CPU_TICKLESS
|
||
|
|
extern one_shot_timer_t tim_one_shot; /* wakeup source for C1 */
|
||
|
|
#endif /* RHINO_CONFIG_CPU_TICKLESS */
|
||
|
|
|
||
|
|
static cpu_pwr_t cpu_pwr_node_package_0;
|
||
|
|
static cpu_pwr_t cpu_pwr_node_core_0;
|
||
|
|
static kstat_t board_cpu_c_state_set
|
||
|
|
(
|
||
|
|
uint32_t cpuCState,
|
||
|
|
int master
|
||
|
|
)
|
||
|
|
{
|
||
|
|
switch (cpuCState) {
|
||
|
|
case CPU_CSTATE_C0:
|
||
|
|
|
||
|
|
//printf("enter C0\n");
|
||
|
|
if (master) {
|
||
|
|
}
|
||
|
|
|
||
|
|
break;
|
||
|
|
|
||
|
|
case CPU_CSTATE_C1:
|
||
|
|
|
||
|
|
/*
|
||
|
|
* put CPU into C1 state
|
||
|
|
* to put CPU into C1 state.
|
||
|
|
*/
|
||
|
|
//printf("enter C1\n");
|
||
|
|
#ifdef CONFIG_CHIP_CH2201
|
||
|
|
*(volatile unsigned int *)(0xe000e1c0) = 0xffffffff; // reload wakeup_IRQ
|
||
|
|
//*(volatile unsigned int *)(0xe000e280) = 0xffffffff; // clear pend IRQ
|
||
|
|
csi_vic_set_wakeup_irq(RTC_IRQn);
|
||
|
|
csi_vic_set_wakeup_irq(UART2_IRQn);
|
||
|
|
csi_vic_set_wakeup_irq(UART1_IRQn);
|
||
|
|
csi_vic_set_wakeup_irq(UART0_IRQn);
|
||
|
|
csi_vic_set_wakeup_irq(CORET_IRQn);
|
||
|
|
csi_vic_set_wakeup_irq(GPIOA_IRQn);
|
||
|
|
csi_vic_set_wakeup_irq(GPIOB_IRQn);
|
||
|
|
csi_vic_set_wakeup_irq(TIMA0_IRQn);
|
||
|
|
|
||
|
|
#ifdef CONFIG_TEE_CA
|
||
|
|
csi_tee_enter_lpm(0, 0, TEE_LPM_MODE_WAIT);
|
||
|
|
#else
|
||
|
|
__WFI();
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
|
||
|
|
PWR_DBG(DBG_ERR, "invalid C state: C%d\n", cpuCState);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
return RHINO_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
kstat_t board_cpu_pwr_topo_create(void)
|
||
|
|
{
|
||
|
|
cpu_pwr_t *pCpuNode = NULL;
|
||
|
|
cpu_pwr_t *pParentL1 = NULL; /* parent of level 1 */
|
||
|
|
cpu_pwr_t *pParentL2 = NULL; /* parent of level 2 */
|
||
|
|
kstat_t retVal = RHINO_SUCCESS;
|
||
|
|
uint32_t cpuIndex = 0; /* 0 for UP */
|
||
|
|
|
||
|
|
if (p_cpu_pwr_root_node == NULL) {
|
||
|
|
return RHINO_PWR_MGMT_ERR;
|
||
|
|
}
|
||
|
|
|
||
|
|
pParentL1 = p_cpu_pwr_root_node;
|
||
|
|
|
||
|
|
pCpuNode = &cpu_pwr_node_package_0;
|
||
|
|
retVal = cpu_pwr_node_init_static(CPU_PWR_TOPO_LEVEL_1, "package", 0, pCpuNode);
|
||
|
|
|
||
|
|
if (retVal != RHINO_SUCCESS) {
|
||
|
|
return RHINO_PWR_MGMT_ERR;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* add this node as a child of p_cpu_pwr_root_node */
|
||
|
|
|
||
|
|
cpu_pwr_child_add(pParentL1, pCpuNode);
|
||
|
|
pParentL2 = pCpuNode;
|
||
|
|
|
||
|
|
pCpuNode = &cpu_pwr_node_core_0;
|
||
|
|
retVal = cpu_pwr_node_init_static(CPU_PWR_TOPO_LEVEL_2, "core", 0, pCpuNode);
|
||
|
|
|
||
|
|
if (retVal != RHINO_SUCCESS) {
|
||
|
|
return RHINO_PWR_MGMT_ERR;
|
||
|
|
}
|
||
|
|
|
||
|
|
cpu_pwr_child_add(pParentL2, pCpuNode);
|
||
|
|
|
||
|
|
/* record this node as leaf node in the topology */
|
||
|
|
|
||
|
|
retVal = cpu_pwr_leaf_node_record(pCpuNode, cpuIndex);
|
||
|
|
|
||
|
|
if (retVal == RHINO_PWR_MGMT_ERR) {
|
||
|
|
return RHINO_PWR_MGMT_ERR;
|
||
|
|
}
|
||
|
|
|
||
|
|
retVal = cpu_pwr_c_method_set_by_level(CPU_PWR_TOPO_LEVEL_2,
|
||
|
|
board_cpu_c_state_set);
|
||
|
|
|
||
|
|
if (retVal == RHINO_PWR_MGMT_ERR) {
|
||
|
|
return RHINO_PWR_MGMT_ERR;
|
||
|
|
}
|
||
|
|
|
||
|
|
retVal = cpu_pwr_c_state_capability_set_by_level(CPU_PWR_TOPO_LEVEL_2,
|
||
|
|
CPU_STATE_BIT(CPU_CSTATE_C0)
|
||
|
|
| CPU_STATE_BIT(CPU_CSTATE_C1)
|
||
|
|
);
|
||
|
|
|
||
|
|
if (retVal == RHINO_PWR_MGMT_ERR) {
|
||
|
|
return RHINO_PWR_MGMT_ERR;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
cpu_pwr_c_state_latency_save(cpuIndex, CPU_CSTATE_C0, 0);
|
||
|
|
cpu_pwr_c_state_latency_save(cpuIndex, CPU_CSTATE_C1, 0);
|
||
|
|
|
||
|
|
tickless_one_shot_timer_save(CPU_CSTATE_C1, &tim_one_shot);
|
||
|
|
|
||
|
|
#if RHINO_CONFIG_CPU_TICKLESS
|
||
|
|
|
||
|
|
tickless_c_states_add(CPU_STATE_BIT(CPU_CSTATE_C0)
|
||
|
|
| CPU_STATE_BIT(CPU_CSTATE_C1)
|
||
|
|
);
|
||
|
|
|
||
|
|
#endif /* RHINO_CONFIG_CPU_TICKLESS */
|
||
|
|
|
||
|
|
return retVal;
|
||
|
|
}
|
||
|
|
|
||
|
|
//#endif /* RHINO_CONFIG_CPU_PWR_MGMT */
|