mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
553 lines
19 KiB
C
Executable File
553 lines
19 KiB
C
Executable File
/**
|
|
* @file services_host_power.c
|
|
*
|
|
* @brief Low Power STOP / Global Standby services service source file
|
|
* @ingroup host_services
|
|
* @par
|
|
*
|
|
* Copyright (C) 2022 Alif Semiconductor - All Rights Reserved.
|
|
* Use, distribution and modification of this code is permitted under the
|
|
* terms stated in the Alif Semiconductor Software License Agreement
|
|
*
|
|
* You should have received a copy of the Alif Semiconductor Software
|
|
* License Agreement with this file. If not, please write to:
|
|
* contact@alifsemi.com, or visit: https://alifsemi.com/license
|
|
*
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* I N C L U D E F I L E S
|
|
*****************************************************************************/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "services_lib_api.h"
|
|
#include "services_lib_protocol.h"
|
|
#include "services_lib_ids.h"
|
|
#include "aipm.h"
|
|
|
|
/*******************************************************************************
|
|
* M A C R O D E F I N E S
|
|
******************************************************************************/
|
|
#define UNUSED(x) (void)(x)
|
|
|
|
/*******************************************************************************
|
|
* T Y P E D E F S
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* G L O B A L V A R I A B L E S
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* C O D E
|
|
******************************************************************************/
|
|
|
|
/**
|
|
* @brief aiPM RUN
|
|
*
|
|
* @param services_handle
|
|
* @param pp
|
|
* @param error_code
|
|
* @return
|
|
*/
|
|
uint32_t SERVICES_get_run_cfg(uint32_t services_handle, run_profile_t *pp,
|
|
uint32_t *error_code)
|
|
{
|
|
uint32_t srv_error_code = 0; /* Service function call return */
|
|
|
|
aipm_get_run_profile_svc_t * p_svc = (aipm_get_run_profile_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(aipm_get_run_profile_svc_t));
|
|
|
|
srv_error_code = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_GET_RUN_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
*error_code = p_svc->resp_error_code; /* return actual call error */
|
|
|
|
pp->aon_clk_src = p_svc->resp_aon_clk_src;
|
|
pp->run_clk_src = p_svc->resp_run_clk_src;
|
|
pp->cpu_clk_freq = p_svc->resp_cpu_clk_freq;
|
|
pp->scaled_clk_freq = p_svc->resp_scaled_clk_freq;
|
|
pp->dcdc_mode = p_svc->resp_dcdc_mode;
|
|
pp->dcdc_voltage = p_svc->resp_dcdc_voltage;
|
|
pp->memory_blocks = p_svc->resp_memory_blocks;
|
|
pp->ip_clock_gating = p_svc->resp_ip_clock_gating;
|
|
pp->phy_pwr_gating = p_svc->resp_phy_pwr_gating;
|
|
pp->power_domains = p_svc->resp_power_domains;
|
|
pp->vdd_ioflex_3V3 = p_svc->resp_vdd_ioflex_3V3;
|
|
|
|
return srv_error_code; /* Return */
|
|
}
|
|
|
|
/**
|
|
* @brief aiPM RUN
|
|
*
|
|
* @param services_handle
|
|
* @param pp
|
|
* @param error_code
|
|
* @return
|
|
*/
|
|
uint32_t SERVICES_set_run_cfg(uint32_t services_handle, run_profile_t *pp,
|
|
uint32_t *error_code)
|
|
{
|
|
uint32_t srv_error_code = 0; /* Service function call return */
|
|
|
|
aipm_set_run_profile_svc_t * p_svc = (aipm_set_run_profile_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(aipm_set_run_profile_svc_t));
|
|
|
|
/**
|
|
* pack ready to send
|
|
* @todo use memcpy()
|
|
*/
|
|
p_svc->send_aon_clk_src = pp->aon_clk_src; /*typedef */
|
|
p_svc->send_run_clk_src = pp->run_clk_src; /*typedef */
|
|
p_svc->send_cpu_clk_freq = pp->cpu_clk_freq;
|
|
p_svc->send_scaled_clk_freq = pp->scaled_clk_freq;
|
|
p_svc->send_dcdc_mode = pp->dcdc_mode; /* typedef */
|
|
p_svc->send_dcdc_voltage = pp->dcdc_voltage;
|
|
p_svc->send_memory_blocks = pp->memory_blocks;
|
|
p_svc->send_ip_clock_gating = pp->ip_clock_gating;
|
|
p_svc->send_phy_pwr_gating = pp->phy_pwr_gating; /*typedef */
|
|
p_svc->send_power_domains = pp->power_domains;
|
|
p_svc->send_vdd_ioflex_3V3 = pp->vdd_ioflex_3V3;
|
|
|
|
srv_error_code = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_SET_RUN_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
*error_code = p_svc->resp_error_code; /* return actual call error */
|
|
|
|
return srv_error_code; /* Return error */
|
|
}
|
|
|
|
/**
|
|
* @brief aiPM OFF
|
|
*
|
|
* @param services_handle
|
|
* @param wp
|
|
* @param error_code
|
|
* @return
|
|
*/
|
|
uint32_t SERVICES_get_off_cfg(uint32_t services_handle, off_profile_t *wp,
|
|
uint32_t *error_code)
|
|
{
|
|
uint32_t srv_error_code = 0; /* Service function call return */
|
|
|
|
aipm_get_off_profile_svc_t * p_svc = (aipm_get_off_profile_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(aipm_get_off_profile_svc_t));
|
|
|
|
srv_error_code = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_GET_OFF_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
*error_code = p_svc->resp_error_code; /* return actual call error */
|
|
|
|
wp->dcdc_voltage = p_svc->resp_dcdc_voltage;
|
|
wp->memory_blocks = p_svc->resp_memory_blocks;
|
|
wp->power_domains = p_svc->resp_power_domains;
|
|
wp->aon_clk_src = p_svc->resp_aon_clk_src;
|
|
wp->stby_clk_src = p_svc->resp_stby_clk_src;
|
|
wp->stby_clk_freq = p_svc->resp_stby_clk_freq;
|
|
wp->ip_clock_gating = p_svc->resp_ip_clock_gating;
|
|
wp->phy_pwr_gating = p_svc->resp_phy_pwr_gating;
|
|
wp->vdd_ioflex_3V3 = p_svc->resp_vdd_ioflex_3V3;
|
|
wp->vtor_address = p_svc->resp_vtor_address;
|
|
wp->vtor_address_ns = p_svc->resp_vtor_address_ns;
|
|
wp->wakeup_events = p_svc->resp_wakeup_events;
|
|
wp->ewic_cfg = p_svc->resp_ewic_cfg;
|
|
|
|
return srv_error_code; /* Return error */
|
|
}
|
|
|
|
/**
|
|
* @brief aiPM RUN
|
|
*
|
|
* @param services_handle
|
|
* @param wp
|
|
* @param error_code
|
|
* @return
|
|
*/
|
|
uint32_t SERVICES_set_off_cfg(uint32_t services_handle, off_profile_t *wp,
|
|
uint32_t *error_code)
|
|
{
|
|
uint32_t srv_error_code = 0; /* Service function call return */
|
|
|
|
aipm_set_off_profile_svc_t * p_svc = (aipm_set_off_profile_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(aipm_get_off_profile_svc_t));
|
|
|
|
/**
|
|
* pack ready to send
|
|
* @todo use memcpy()
|
|
*/
|
|
p_svc->send_dcdc_voltage = wp->dcdc_voltage;
|
|
p_svc->send_memory_blocks = wp->memory_blocks;
|
|
p_svc->send_power_domains = wp->power_domains;
|
|
p_svc->send_aon_clk_src = wp->aon_clk_src;
|
|
p_svc->send_stby_clk_src = wp->stby_clk_src;
|
|
p_svc->send_stby_clk_freq = wp->stby_clk_freq;
|
|
p_svc->send_ip_clock_gating = wp->ip_clock_gating;
|
|
p_svc->send_phy_pwr_gating = wp->phy_pwr_gating; /*typedef */
|
|
p_svc->send_vdd_ioflex_3V3 = wp->vdd_ioflex_3V3;
|
|
p_svc->send_vtor_address = wp->vtor_address;
|
|
p_svc->send_vtor_address_ns = wp->vtor_address_ns;
|
|
p_svc->send_wakeup_events = wp->wakeup_events;
|
|
p_svc->send_ewic_cfg = wp->ewic_cfg;
|
|
|
|
srv_error_code = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_SET_OFF_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
*error_code = p_svc->resp_error_code; /* return actual call error */
|
|
|
|
return srv_error_code; /* Return error */
|
|
}
|
|
|
|
/**
|
|
* @brief Function to request stop mode
|
|
* @param services_handle
|
|
* @param power_profile
|
|
* @param override
|
|
* @return
|
|
*/
|
|
uint32_t SERVICES_power_stop_mode_req(uint32_t services_handle,
|
|
services_power_profile_t power_profile,
|
|
bool override)
|
|
{
|
|
stop_mode_request_svc_t * p_svc = (stop_mode_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(stop_mode_request_svc_t));
|
|
|
|
p_svc->power_profile = power_profile;
|
|
p_svc->override = override;
|
|
p_svc->pad = 0x0;
|
|
|
|
return SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_STOP_MODE_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to disable SERAM 0, 1 or MRAM
|
|
* @param services_handle
|
|
* @param memory_request
|
|
* @param error_code
|
|
* @return
|
|
*/
|
|
uint32_t SERVICES_power_memory_req(uint32_t services_handle,
|
|
uint32_t memory_request,
|
|
uint32_t *error_code)
|
|
{
|
|
mem_power_config_request_svc_t * p_svc = (mem_power_config_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(mem_power_config_request_svc_t));
|
|
|
|
p_svc->send_memory_power = memory_request;
|
|
|
|
UNUSED(error_code);
|
|
|
|
return SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_MEMORY_POWER_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Function to configure EWIC source
|
|
* @param services_handle
|
|
* @param ewic_source
|
|
* @param power_profile
|
|
* @return
|
|
*/
|
|
uint32_t SERVICES_power_ewic_config(uint32_t services_handle,
|
|
uint32_t ewic_source,
|
|
services_power_profile_t power_profile)
|
|
{
|
|
ewic_config_request_svc_t * p_svc = (ewic_config_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(ewic_config_request_svc_t));
|
|
|
|
p_svc->send_ewic_source = ewic_source;
|
|
p_svc->power_profile = power_profile;
|
|
|
|
return SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_EWIC_CONFIG_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to configure VBAT wake up source
|
|
* @param services_handle
|
|
* @param vbat_wakeup_source
|
|
* @param power_profile
|
|
* @return
|
|
*/
|
|
uint32_t SERVICES_power_wakeup_config(uint32_t services_handle,
|
|
uint32_t vbat_wakeup_source,
|
|
services_power_profile_t power_profile)
|
|
{
|
|
vbat_wakeup_config_request_svc_t * p_svc =
|
|
(vbat_wakeup_config_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(vbat_wakeup_config_request_svc_t));
|
|
|
|
p_svc->send_vbat_wakeup_source = vbat_wakeup_source;
|
|
p_svc->power_profile = power_profile;
|
|
|
|
return SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_VBAT_WAKEUP_CONFIG_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to configure memory retention
|
|
* @param services_handle
|
|
* @param mem_retention
|
|
* @param power_profile
|
|
* @return
|
|
*/
|
|
uint32_t
|
|
SERVICES_power_mem_retention_config(uint32_t services_handle,
|
|
uint32_t mem_retention,
|
|
services_power_profile_t power_profile)
|
|
{
|
|
mem_ret_config_request_svc_t * p_svc =
|
|
(mem_ret_config_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(mem_ret_config_request_svc_t));
|
|
|
|
p_svc->send_mem_retention = mem_retention;
|
|
p_svc->power_profile = power_profile;
|
|
|
|
return SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_MEM_RETENTION_CONFIG_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to request m55-he VTOR value save for wake up
|
|
* @param services_handle
|
|
* @param ns_vtor_addr
|
|
* @param se_vtor_addr
|
|
* @param power_profile
|
|
* @return
|
|
*/
|
|
uint32_t
|
|
SERVICES_power_m55_he_vtor_save(uint32_t services_handle,
|
|
uint32_t ns_vtor_addr,
|
|
uint32_t se_vtor_addr,
|
|
services_power_profile_t power_profile)
|
|
{
|
|
m55_vtor_save_request_svc_t * p_svc =
|
|
(m55_vtor_save_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(m55_vtor_save_request_svc_t));
|
|
|
|
p_svc->ns_vtor_addr = ns_vtor_addr;
|
|
p_svc->se_vtor_addr = se_vtor_addr;
|
|
p_svc->power_profile = power_profile;
|
|
|
|
return SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_M55_HE_VTOR_SAVE_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to request m55-hp VTOR value save for wake up
|
|
* @param services_handle
|
|
* @param ns_vtor_addr
|
|
* @param se_vtor_addr
|
|
* @param power_profile
|
|
* @return
|
|
*/
|
|
uint32_t
|
|
SERVICES_power_m55_hp_vtor_save(uint32_t services_handle,
|
|
uint32_t ns_vtor_addr,
|
|
uint32_t se_vtor_addr,
|
|
services_power_profile_t power_profile)
|
|
{
|
|
m55_vtor_save_request_svc_t * p_svc =
|
|
(m55_vtor_save_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(m55_vtor_save_request_svc_t));
|
|
|
|
p_svc->ns_vtor_addr = ns_vtor_addr;
|
|
p_svc->se_vtor_addr = se_vtor_addr;
|
|
p_svc->power_profile = power_profile;
|
|
|
|
return SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_M55_HP_VTOR_SAVE_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to request standby mode
|
|
* @param services_handle
|
|
* @param host_cpu_clus_pwr_req
|
|
* @param bsys_pwr_req
|
|
* @param error_code
|
|
* @return
|
|
*/
|
|
uint32_t
|
|
SERVICES_corstone_standby_mode(uint32_t services_handle,
|
|
host_cpu_clus_pwr_req_t host_cpu_clus_pwr_req,
|
|
bsys_pwr_req_t bsys_pwr_req,
|
|
uint32_t *error_code)
|
|
{
|
|
uint32_t srv_error_code = 0; /* Service function call return */
|
|
|
|
global_standby_request_svc_t *p_svc =
|
|
(global_standby_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(global_standby_request_svc_t));
|
|
|
|
p_svc->host_cpu_clus_pwr_req.word = host_cpu_clus_pwr_req.word;
|
|
p_svc->bsys_pwr_req.word = bsys_pwr_req.word;
|
|
|
|
srv_error_code = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_GLOBAL_STANDBY_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
*error_code = p_svc->resp_error_code; /* return actual call error */
|
|
|
|
return srv_error_code; /* Return SERVICES error code */
|
|
}
|
|
|
|
/**
|
|
* @brief SE to deep sleep
|
|
*
|
|
* @param services_handle
|
|
* @param se_param
|
|
* @param error_code
|
|
* @return
|
|
*/
|
|
uint32_t SERVICES_power_se_sleep_req(uint32_t services_handle,
|
|
uint32_t se_param,
|
|
uint32_t *error_code)
|
|
{
|
|
uint32_t srv_error_code = 0; /* Service function call return */
|
|
se_sleep_svc_t *p_svc =
|
|
(se_sleep_svc_t *)SERVICES_prepare_packet_buffer(sizeof(se_sleep_svc_t));
|
|
|
|
p_svc->send_param = se_param;
|
|
|
|
srv_error_code = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_SE_SLEEP_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
*error_code = p_svc->resp_error_code; /* return actual call error */
|
|
|
|
return srv_error_code; /* Return SERVICES error code */
|
|
}
|
|
|
|
/**
|
|
* @brief Function for DCDC voltage control
|
|
* @param services_handle
|
|
* @param dcdc_vout_sel
|
|
* @param dcdc_vout_trim
|
|
* @param error_code
|
|
* @return
|
|
*/
|
|
uint32_t
|
|
SERVICES_power_dcdc_voltage_control(uint32_t services_handle,
|
|
uint32_t dcdc_vout_sel,
|
|
uint32_t dcdc_vout_trim,
|
|
uint32_t *error_code)
|
|
{
|
|
dcdc_voltage_request_svc_t * p_svc =
|
|
(dcdc_voltage_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(dcdc_voltage_request_svc_t));
|
|
|
|
p_svc->dcdc_vout_sel = dcdc_vout_sel;
|
|
p_svc->dcdc_vout_trim = dcdc_vout_trim;
|
|
|
|
uint32_t ret = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_DCDC_VOLTAGE_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
*error_code = p_svc->resp_error_code;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Function for LDO voltage control
|
|
* @param services_handle
|
|
* @param ret_ldo_voltage
|
|
* @param aon_ldo_voltage
|
|
* @param error_code
|
|
* @return
|
|
*/
|
|
uint32_t
|
|
SERVICES_power_ldo_voltage_control(uint32_t services_handle,
|
|
uint32_t ret_ldo_voltage,
|
|
uint32_t aon_ldo_voltage,
|
|
uint32_t *error_code)
|
|
{
|
|
ldo_voltage_request_svc_t * p_svc =
|
|
(ldo_voltage_request_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(ldo_voltage_request_svc_t));
|
|
|
|
p_svc->ret_ldo_voltage = ret_ldo_voltage;
|
|
p_svc->aon_ldo_voltage = aon_ldo_voltage;
|
|
|
|
uint32_t ret = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_LDO_VOLTAGE_REQ_ID,
|
|
DEFAULT_TIMEOUT);
|
|
*error_code = p_svc->resp_error_code;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @fn uint32_t SERVICES_power_setting_configure(uint32_t services_handle,
|
|
* power_setting_t setting_type,
|
|
* uint32_t value,
|
|
* uint32_t *error_code)
|
|
* @brief Configure a power-related setting
|
|
* @param services_handle
|
|
* @param setting_type Setting type
|
|
* @param value Setting value
|
|
* @param error_code Service error code
|
|
* @return Transport layer error code
|
|
*/
|
|
uint32_t SERVICES_power_setting_configure(uint32_t services_handle,
|
|
power_setting_t setting_type,
|
|
uint32_t value,
|
|
uint32_t *error_code)
|
|
{
|
|
power_setting_svc_t * p_svc =
|
|
(power_setting_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(power_setting_svc_t));
|
|
|
|
p_svc->send_setting_type = setting_type;
|
|
p_svc->value = value;
|
|
|
|
uint32_t ret = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_SETTING_CONFIG_REQ_ID, DEFAULT_TIMEOUT);
|
|
|
|
*error_code = p_svc->resp_error_code;
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @fn uint32_t SERVICES_power_setting_get(uint32_t services_handle,
|
|
* power_setting_t setting_type,
|
|
* uint32_t *value,
|
|
* uint32_t *error_code)
|
|
* @brief Get a power-related setting
|
|
* @param services_handle
|
|
* @param setting_type Setting type
|
|
* @param value Setting value
|
|
* @param error_code Service error code
|
|
* @return Transport layer error code
|
|
*/
|
|
uint32_t SERVICES_power_setting_get(uint32_t services_handle,
|
|
power_setting_t setting_type,
|
|
uint32_t *value,
|
|
uint32_t *error_code)
|
|
{
|
|
power_setting_svc_t * p_svc =
|
|
(power_setting_svc_t *)
|
|
SERVICES_prepare_packet_buffer(sizeof(power_setting_svc_t));
|
|
|
|
p_svc->send_setting_type = setting_type;
|
|
|
|
uint32_t ret = SERVICES_send_request(services_handle,
|
|
SERVICE_POWER_SETTING_GET_REQ_ID, DEFAULT_TIMEOUT);
|
|
|
|
if (SERVICES_REQ_SUCCESS == ret)
|
|
{
|
|
*value = p_svc->value;
|
|
}
|
|
|
|
*error_code = p_svc->resp_error_code;
|
|
return ret;
|
|
}
|