Merge changes Ibe6fd206,Icdca3de6,I72016620,I57a2787c into integration
* changes: fix(versal): fix coverity scan warnings feat(versal): get version for ATF related EEMI APIs feat(versal): enhance PM_IOCTL EEMI API to support additional arg feat(versal): add common interfaces to handle EEMI commands
This commit is contained in:
commit
3dbbd41f39
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -25,6 +25,8 @@
|
|||
#define LOADER_MODULE_ID 0x7U
|
||||
|
||||
#define MODE 0x80000000U
|
||||
#define MODULE_ID_MASK 0x0000ff00
|
||||
|
||||
/* default shutdown/reboot scope is system(2) */
|
||||
static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM;
|
||||
|
||||
|
@ -73,38 +75,29 @@ unsigned int pm_get_shutdown_scope(void)
|
|||
/* PM API functions */
|
||||
|
||||
/**
|
||||
* pm_get_api_version() - Get version number of PMC PM firmware
|
||||
* @version Returns 32-bit version number of PMC Power Management Firmware
|
||||
* pm_handle_eemi_call() - PM call for processor to send eemi payload
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
* @x0 to x5 Arguments received per SMC64 standard
|
||||
* @result Payload received from firmware
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
* @return PM_RET_SUCCESS on success or error code
|
||||
*/
|
||||
enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag)
|
||||
enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
|
||||
uint32_t x2, uint32_t x3, uint32_t x4,
|
||||
uint32_t x5, uint64_t *result)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
uint32_t payload[PAYLOAD_ARG_CNT] = {0};
|
||||
uint32_t module_id;
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_API_VERSION);
|
||||
return pm_ipi_send_sync(primary_proc, payload, version, 1);
|
||||
}
|
||||
module_id = (x0 & MODULE_ID_MASK) >> 8;
|
||||
|
||||
/**
|
||||
* pm_init_finalize() - Call to notify PMC PM firmware that master has power
|
||||
* management enabled and that it has finished its
|
||||
* initialization
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Status returned by the PMU firmware
|
||||
*/
|
||||
enum pm_ret_status pm_init_finalize(uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
//default module id is for LIBPM
|
||||
if (module_id == 0)
|
||||
module_id = LIBPM_MODULE_ID;
|
||||
|
||||
/* Send request to the PMU */
|
||||
PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_INIT_FINALIZE);
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
|
||||
return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,134 +227,6 @@ enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
|
|||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_request_device() - Request a device
|
||||
* @device_id Device ID
|
||||
* @capabilities Requested capabilities for the device
|
||||
* @qos Required Quality of Service
|
||||
* @ack Flag to specify whether acknowledge requested
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
|
||||
uint32_t qos, uint32_t ack, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQUEST_DEVICE,
|
||||
device_id, capabilities, qos, ack);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_release_device() - Release a device
|
||||
* @device_id Device ID
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RELEASE_DEVICE,
|
||||
device_id);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_set_requirement() - Set requirement for the device
|
||||
* @device_id Device ID
|
||||
* @capabilities Requested capabilities for the device
|
||||
* @latency Requested maximum latency
|
||||
* @qos Required Quality of Service
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
|
||||
uint32_t latency, uint32_t qos,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_SET_REQUIREMENT,
|
||||
device_id, capabilities, latency, qos);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_get_device_status() - Get device's status
|
||||
* @device_id Device ID
|
||||
* @response Buffer to store device status response
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_GET_DEVICE_STATUS,
|
||||
device_id);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, response, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_reset_assert() - Assert/De-assert reset
|
||||
* @reset Reset ID
|
||||
* @assert Assert (1) or de-assert (0)
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT, reset,
|
||||
assert);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_reset_get_status() - Get current status of a reset line
|
||||
* @reset Reset ID
|
||||
* @status Returns current status of selected reset ID
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_RESET_ASSERT,
|
||||
reset);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, status, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_get_callbackdata() - Read from IPI response buffer
|
||||
* @data - array of PAYLOAD_ARG_CNT elements
|
||||
|
@ -381,295 +246,13 @@ void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag)
|
|||
pm_ipi_irq_clear(primary_proc);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_pinctrl_request() - Request a pin
|
||||
* @pin Pin ID
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_REQUEST,
|
||||
pin);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_pinctrl_release() - Release a pin
|
||||
* @pin Pin ID
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PINCTRL_RELEASE,
|
||||
pin);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_pinctrl_set_function() - Set pin function
|
||||
* @pin Pin ID
|
||||
* @function Function ID
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
|
||||
PM_PINCTRL_SET_FUNCTION, pin, function)
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_pinctrl_get_function() - Get function set on the pin
|
||||
* @pin Pin ID
|
||||
* @function Function set on the pin
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
|
||||
PM_PINCTRL_SET_FUNCTION, pin);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, function, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_pinctrl_set_pin_param() - Set configuration parameter for the pin
|
||||
* @pin Pin ID
|
||||
* @param Parameter ID
|
||||
* @value Parameter value
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
|
||||
uint32_t value, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag,
|
||||
PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_pinctrl_get_pin_param() - Get configuration parameter value for the pin
|
||||
* @pin Pin ID
|
||||
* @param Parameter ID
|
||||
* @value Buffer to store parameter value
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
|
||||
uint32_t *value, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
|
||||
PM_PINCTRL_CONFIG_PARAM_GET, pin, param);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, value, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_enable() - Enable the clock
|
||||
* @clk_id Clock ID
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_ENABLE,
|
||||
clk_id);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_disable() - Disable the clock
|
||||
* @clk_id Clock ID
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_DISABLE,
|
||||
clk_id);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_get_state() - Get clock status
|
||||
* @clk_id Clock ID
|
||||
* @state: Buffer to store clock status (1: Enabled, 0:Disabled)
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETSTATE,
|
||||
clk_id);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, state, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_set_divider() - Set divider for the clock
|
||||
* @clk_id Clock ID
|
||||
* @divider Divider value
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETDIVIDER,
|
||||
clk_id, divider);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_get_divider() - Get divider value for the clock
|
||||
* @clk_id Clock ID
|
||||
* @divider: Buffer to store clock divider value
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETDIVIDER,
|
||||
clk_id);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, divider, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_set_parent() - Set parent for the clock
|
||||
* @clk_id Clock ID
|
||||
* @parent Parent ID
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_SETPARENT,
|
||||
clk_id, parent);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_get_parent() - Get parent value for the clock
|
||||
* @clk_id Clock ID
|
||||
* @parent: Buffer to store clock parent value
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETPARENT,
|
||||
clk_id);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, parent, 1);
|
||||
}
|
||||
/**
|
||||
* pm_clock_get_rate() - Get the rate value for the clock
|
||||
* @clk_id Clock ID
|
||||
* @rate: Buffer to store clock rate value
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_CLOCK_GETRATE,
|
||||
clk_id);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, clk_rate, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_pll_set_param() - Set PLL parameter
|
||||
*
|
||||
* This API is deprecated and maintained here for backward compatibility.
|
||||
* New use of this API should be avoided for versal platform.
|
||||
* This API and its use cases will be removed for versal platform.
|
||||
*
|
||||
* @clk_id PLL clock ID
|
||||
* @param PLL parameter ID
|
||||
* @value Value to set for PLL parameter
|
||||
|
@ -692,6 +275,11 @@ enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
|
|||
|
||||
/**
|
||||
* pm_pll_get_param() - Get PLL parameter value
|
||||
*
|
||||
* This API is deprecated and maintained here for backward compatibility.
|
||||
* New use of this API should be avoided for versal platform.
|
||||
* This API and its use cases will be removed for versal platform.
|
||||
*
|
||||
* @clk_id PLL clock ID
|
||||
* @param PLL parameter ID
|
||||
* @value: Buffer to store PLL parameter value
|
||||
|
@ -714,6 +302,11 @@ enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
|
|||
|
||||
/**
|
||||
* pm_pll_set_mode() - Set PLL mode
|
||||
*
|
||||
* This API is deprecated and maintained here for backward compatibility.
|
||||
* New use of this API should be avoided for versal platform.
|
||||
* This API and its use cases will be removed for versal platform.
|
||||
*
|
||||
* @clk_id PLL clock ID
|
||||
* @mode PLL mode
|
||||
* @flag 0 - Call from secure source
|
||||
|
@ -735,6 +328,11 @@ enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
|
|||
|
||||
/**
|
||||
* pm_pll_get_mode() - Get PLL mode
|
||||
*
|
||||
* This API is deprecated and maintained here for backward compatibility.
|
||||
* New use of this API should be avoided for versal platform.
|
||||
* This API and its use cases will be removed for versal platform.
|
||||
*
|
||||
* @clk_id PLL clock ID
|
||||
* @mode: Buffer to store PLL mode
|
||||
* @flag 0 - Call from secure source
|
||||
|
@ -808,22 +406,28 @@ enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
|
|||
}
|
||||
|
||||
/**
|
||||
* pm_query_data() - PM API for querying firmware data
|
||||
* @qid The type of data to query
|
||||
* @arg1 Argument 1 to requested query data call
|
||||
* @arg2 Argument 2 to requested query data call
|
||||
* @arg3 Argument 3 to requested query data call
|
||||
* @data Returned output data
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* This function returns requested data.
|
||||
*/
|
||||
* pm_query_data() - PM API for querying firmware data
|
||||
*
|
||||
* This API is deprecated and maintained here for backward compatibility.
|
||||
* New use of this API should be avoided for versal platform.
|
||||
* This API and its use cases will be removed for versal platform.
|
||||
*
|
||||
* @qid The type of data to query
|
||||
* @arg1 Argument 1 to requested query data call
|
||||
* @arg2 Argument 2 to requested query data call
|
||||
* @arg3 Argument 3 to requested query data call
|
||||
* @data Returned output data
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @retur - 0 if success else non-zero error code of type
|
||||
* enum pm_ret_status
|
||||
*/
|
||||
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
|
||||
uint32_t arg3, uint32_t *data, uint32_t flag)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint32_t version;
|
||||
uint32_t version[PAYLOAD_ARG_CNT] = {0};
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
uint32_t fw_api_version;
|
||||
|
||||
|
@ -831,42 +435,50 @@ enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
|
|||
PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
|
||||
arg1, arg2, arg3);
|
||||
|
||||
ret = pm_feature_check(PM_QUERY_DATA, &version, flag);
|
||||
if (PM_RET_SUCCESS == ret) {
|
||||
fw_api_version = version & 0xFFFFU;
|
||||
if ((2U == fw_api_version) &&
|
||||
((XPM_QID_CLOCK_GET_NAME == qid) ||
|
||||
(XPM_QID_PINCTRL_GET_FUNCTION_NAME == qid))) {
|
||||
ret = pm_ipi_send_sync(primary_proc, payload, data, 8);
|
||||
ret = data[0];
|
||||
data[0] = data[1];
|
||||
data[1] = data[2];
|
||||
data[2] = data[3];
|
||||
ret = pm_feature_check(PM_QUERY_DATA, &version[0], flag);
|
||||
if (ret == PM_RET_SUCCESS) {
|
||||
fw_api_version = version[0] & 0xFFFF;
|
||||
if ((fw_api_version == 2U) &&
|
||||
((qid == XPM_QID_CLOCK_GET_NAME) ||
|
||||
(qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
|
||||
ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
|
||||
if (ret == PM_RET_SUCCESS) {
|
||||
ret = data[0];
|
||||
data[0] = data[1];
|
||||
data[1] = data[2];
|
||||
data[2] = data[3];
|
||||
}
|
||||
} else {
|
||||
ret = pm_ipi_send_sync(primary_proc, payload, data, 4);
|
||||
ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* pm_api_ioctl() - PM IOCTL API for device control and configs
|
||||
*
|
||||
* This API is deprecated and maintained here for backward compatibility.
|
||||
* New use of this API should be avoided for versal platform.
|
||||
* This API and its use cases will be removed for versal platform.
|
||||
*
|
||||
* @device_id Device ID
|
||||
* @ioctl_id ID of the requested IOCTL
|
||||
* @arg1 Argument 1 to requested IOCTL call
|
||||
* @arg2 Argument 2 to requested IOCTL call
|
||||
* @arg3 Argument 3 to requested IOCTL call
|
||||
* @value Returned output value
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* This function calls IOCTL to firmware for device control and configuration.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
* @return Returns status, either 0 on success or non-zero error code
|
||||
* of type enum pm_ret_status
|
||||
*/
|
||||
enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
|
||||
uint32_t arg1, uint32_t arg2, uint32_t *value,
|
||||
uint32_t flag)
|
||||
uint32_t arg1, uint32_t arg2, uint32_t arg3,
|
||||
uint32_t *value, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
enum pm_ret_status ret;
|
||||
|
||||
switch (ioctl_id) {
|
||||
|
@ -892,11 +504,7 @@ enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
|
|||
ret = PM_RET_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_IOCTL,
|
||||
device_id, ioctl_id, arg1, arg2);
|
||||
ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
|
||||
break;
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -922,117 +530,49 @@ enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
|
|||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_get_chipid() - Read silicon ID registers
|
||||
* @value Buffer for return values. Must be large enough
|
||||
* to hold 8 bytes.
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns silicon ID registers
|
||||
*/
|
||||
enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, flag, PM_GET_CHIPID);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, value, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_feature_check() - Returns the supported API version if supported
|
||||
* @api_id API ID to check
|
||||
* @value Returned supported API version
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
* @ret_payload pointer to array of PAYLOAD_ARG_CNT number of
|
||||
* words Returned supported API version and bitmasks
|
||||
* for IOCTL and QUERY ID
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
|
||||
enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT], fw_api_version;
|
||||
enum pm_ret_status status = PM_RET_ERROR_NOFEATURE;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
uint32_t module_id;
|
||||
|
||||
/* Return version of API which are implemented in ATF only */
|
||||
switch (api_id) {
|
||||
case PM_GET_CALLBACK_DATA:
|
||||
case PM_GET_TRUSTZONE_VERSION:
|
||||
ret_payload[0] = PM_API_VERSION_2;
|
||||
return PM_RET_SUCCESS;
|
||||
case PM_LOAD_PDI:
|
||||
*version = (PM_API_BASE_VERSION << 16);
|
||||
status = PM_RET_SUCCESS;
|
||||
break;
|
||||
case PM_GET_API_VERSION:
|
||||
case PM_GET_DEVICE_STATUS:
|
||||
case PM_GET_OP_CHARACTERISTIC:
|
||||
case PM_REQ_SUSPEND:
|
||||
case PM_SELF_SUSPEND:
|
||||
case PM_FORCE_POWERDOWN:
|
||||
case PM_ABORT_SUSPEND:
|
||||
case PM_REQ_WAKEUP:
|
||||
case PM_SET_WAKEUP_SOURCE:
|
||||
case PM_SYSTEM_SHUTDOWN:
|
||||
case PM_REQUEST_DEVICE:
|
||||
case PM_RELEASE_DEVICE:
|
||||
case PM_SET_REQUIREMENT:
|
||||
case PM_RESET_ASSERT:
|
||||
case PM_RESET_GET_STATUS:
|
||||
case PM_GET_CHIPID:
|
||||
case PM_PINCTRL_REQUEST:
|
||||
case PM_PINCTRL_RELEASE:
|
||||
case PM_PINCTRL_GET_FUNCTION:
|
||||
case PM_PINCTRL_SET_FUNCTION:
|
||||
case PM_PINCTRL_CONFIG_PARAM_GET:
|
||||
case PM_PINCTRL_CONFIG_PARAM_SET:
|
||||
case PM_IOCTL:
|
||||
case PM_CLOCK_ENABLE:
|
||||
case PM_CLOCK_DISABLE:
|
||||
case PM_CLOCK_GETSTATE:
|
||||
case PM_CLOCK_SETDIVIDER:
|
||||
case PM_CLOCK_GETDIVIDER:
|
||||
case PM_CLOCK_SETPARENT:
|
||||
case PM_CLOCK_GETPARENT:
|
||||
case PM_CLOCK_GETRATE:
|
||||
case PM_PLL_SET_PARAMETER:
|
||||
case PM_PLL_GET_PARAMETER:
|
||||
case PM_PLL_SET_MODE:
|
||||
case PM_PLL_GET_MODE:
|
||||
case PM_FEATURE_CHECK:
|
||||
case PM_INIT_FINALIZE:
|
||||
case PM_SET_MAX_LATENCY:
|
||||
case PM_REGISTER_NOTIFIER:
|
||||
*version = (PM_API_BASE_VERSION << 16);
|
||||
status = PM_RET_SUCCESS;
|
||||
break;
|
||||
case PM_QUERY_DATA:
|
||||
*version = (PM_API_QUERY_DATA_VERSION << 16);
|
||||
status = PM_RET_SUCCESS;
|
||||
break;
|
||||
ret_payload[0] = PM_API_BASE_VERSION;
|
||||
return PM_RET_SUCCESS;
|
||||
default:
|
||||
*version = 0U;
|
||||
status = PM_RET_ERROR_NOFEATURE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != PM_RET_SUCCESS) {
|
||||
goto done;
|
||||
module_id = (api_id & MODULE_ID_MASK) >> 8;
|
||||
|
||||
/*
|
||||
* feature check should be done only for LIBPM module
|
||||
* If module_id is 0, then we consider it LIBPM module as default id
|
||||
*/
|
||||
if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) {
|
||||
return PM_RET_SUCCESS;
|
||||
}
|
||||
|
||||
PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
|
||||
PM_FEATURE_CHECK, api_id);
|
||||
|
||||
status = pm_ipi_send_sync(primary_proc, payload, &fw_api_version, 1);
|
||||
if (status != PM_RET_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
*version |= fw_api_version;
|
||||
|
||||
status = PM_RET_SUCCESS;
|
||||
|
||||
done:
|
||||
return status;
|
||||
return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1059,54 +599,6 @@ enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
|
|||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_get_op_characteristic() - PM call to request operating characteristics
|
||||
* of a device
|
||||
* @device_id Device id
|
||||
* @type Type of the operating characteristic
|
||||
* (power, temperature and latency)
|
||||
* @result Returns the operating characteristic for the requested device,
|
||||
* specified by the type
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
|
||||
enum pm_opchar_type type,
|
||||
uint32_t *result, uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag,
|
||||
PM_GET_OP_CHARACTERISTIC, device_id, type);
|
||||
return pm_ipi_send_sync(primary_proc, payload, result, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_set_max_latency() - PM call to change in the maximum wake-up latency
|
||||
* requirements for a specific device currently
|
||||
* used by that CPU.
|
||||
* @device_id Device ID
|
||||
* @latency Latency value
|
||||
* @flag 0 - Call from secure source
|
||||
* 1 - Call from non-secure source
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
|
||||
uint32_t flag)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMC */
|
||||
PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SET_MAX_LATENCY,
|
||||
device_id, latency);
|
||||
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_register_notifier() - PM call to register a subsystem to be notified
|
||||
* about the device event
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020, Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -14,8 +14,9 @@
|
|||
* PM API function declarations
|
||||
**********************************************************/
|
||||
|
||||
enum pm_ret_status pm_get_api_version(unsigned int *version, uint32_t flag);
|
||||
enum pm_ret_status pm_init_finalize(uint32_t flag);
|
||||
enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
|
||||
uint32_t x2, uint32_t x3, uint32_t x4,
|
||||
uint32_t x5, uint64_t *result);
|
||||
enum pm_ret_status pm_self_suspend(uint32_t nid,
|
||||
unsigned int latency,
|
||||
unsigned int state,
|
||||
|
@ -29,42 +30,7 @@ enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address,
|
|||
uintptr_t address, uint8_t ack, uint32_t flag);
|
||||
enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t device_id,
|
||||
uint8_t enable, uint32_t flag);
|
||||
enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities,
|
||||
uint32_t qos, uint32_t ack, uint32_t flag);
|
||||
enum pm_ret_status pm_release_device(uint32_t device_id, uint32_t flag);
|
||||
enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities,
|
||||
uint32_t latency, uint32_t qos,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert, uint32_t flag);
|
||||
enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status,
|
||||
uint32_t flag);
|
||||
void pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag);
|
||||
enum pm_ret_status pm_pinctrl_request(uint32_t pin, uint32_t flag);
|
||||
enum pm_ret_status pm_pinctrl_release(uint32_t pin, uint32_t flag);
|
||||
enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param,
|
||||
uint32_t value, uint32_t flag);
|
||||
enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param,
|
||||
uint32_t *value, uint32_t flag);
|
||||
enum pm_ret_status pm_clock_enable(uint32_t clk_id, uint32_t flag);
|
||||
enum pm_ret_status pm_clock_disable(uint32_t clk_id, uint32_t flag);
|
||||
enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_clock_get_rate(uint32_t clk_id, uint32_t *clk_rate,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
|
||||
uint32_t value, uint32_t flag);
|
||||
enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
|
||||
|
@ -78,21 +44,15 @@ enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
|
|||
enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
|
||||
uint32_t arg1, uint32_t arg2, uint32_t *value,
|
||||
uint32_t flag);
|
||||
uint32_t arg1, uint32_t arg2, uint32_t arg3,
|
||||
uint32_t *value, uint32_t flag);
|
||||
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
|
||||
uint32_t arg3, uint32_t *data, uint32_t flag);
|
||||
unsigned int pm_get_shutdown_scope(void);
|
||||
enum pm_ret_status pm_get_chipid(uint32_t *value, uint32_t flag);
|
||||
enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version,
|
||||
enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
|
||||
uint32_t address_high, uint32_t flag);
|
||||
enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
|
||||
enum pm_opchar_type type,
|
||||
uint32_t *result, uint32_t flag);
|
||||
enum pm_ret_status pm_set_max_latency(uint32_t device_id, uint32_t latency,
|
||||
uint32_t flag);
|
||||
enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
|
||||
uint32_t wake, uint32_t enable,
|
||||
uint32_t flag);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -21,6 +21,7 @@
|
|||
#include <plat/common/platform.h>
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
#include "pm_defs.h"
|
||||
|
||||
#define UNDEFINED_CPUID (~0)
|
||||
#define IRQ_MAX 142U
|
||||
|
@ -147,14 +148,16 @@ static void pm_client_set_wakeup_sources(uint32_t node_id)
|
|||
node_idx = irq_to_pm_node_idx(irq);
|
||||
reg &= ~lowest_set;
|
||||
|
||||
if ((node_idx != XPM_NODEIDX_DEV_MIN) &&
|
||||
(pm_wakeup_nodes_set[node_idx] == 0U)) {
|
||||
/* Get device ID from node index */
|
||||
device_id = PERIPH_DEVID(node_idx);
|
||||
ret = pm_set_wakeup_source(node_id,
|
||||
device_id, 1,
|
||||
SECURE_FLAG);
|
||||
pm_wakeup_nodes_set[node_idx] = (uint8_t)(!ret);
|
||||
if (node_idx > XPM_NODEIDX_DEV_MIN && node_idx < XPM_NODEIDX_DEV_MAX) {
|
||||
if (pm_wakeup_nodes_set[node_idx] == 0U) {
|
||||
/* Get device ID from node index */
|
||||
device_id = PERIPH_DEVID(node_idx);
|
||||
ret = pm_set_wakeup_source(node_id,
|
||||
device_id, 1,
|
||||
SECURE_FLAG);
|
||||
pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ?
|
||||
1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -38,13 +38,11 @@
|
|||
|
||||
/* PM API Versions */
|
||||
#define PM_API_BASE_VERSION 1U
|
||||
#define PM_API_VERSION_2 2U
|
||||
|
||||
#define PM_API_QUERY_DATA_VERSION 2U
|
||||
|
||||
/* PM API ids */
|
||||
#define PM_GET_API_VERSION 1U
|
||||
#define PM_GET_DEVICE_STATUS 3U
|
||||
#define PM_GET_OP_CHARACTERISTIC 4U
|
||||
#define PM_REGISTER_NOTIFIER 5U
|
||||
#define PM_REQ_SUSPEND 6U
|
||||
#define PM_SELF_SUSPEND 7U
|
||||
|
@ -53,31 +51,8 @@
|
|||
#define PM_REQ_WAKEUP 10U
|
||||
#define PM_SET_WAKEUP_SOURCE 11U
|
||||
#define PM_SYSTEM_SHUTDOWN 12U
|
||||
#define PM_REQUEST_DEVICE 13U
|
||||
#define PM_RELEASE_DEVICE 14U
|
||||
#define PM_SET_REQUIREMENT 15U
|
||||
#define PM_SET_MAX_LATENCY 16U
|
||||
#define PM_RESET_ASSERT 17U
|
||||
#define PM_RESET_GET_STATUS 18U
|
||||
#define PM_INIT_FINALIZE 21U
|
||||
#define PM_GET_CHIPID 24U
|
||||
#define PM_PINCTRL_REQUEST 28U
|
||||
#define PM_PINCTRL_RELEASE 29U
|
||||
#define PM_PINCTRL_GET_FUNCTION 30U
|
||||
#define PM_PINCTRL_SET_FUNCTION 31U
|
||||
#define PM_PINCTRL_CONFIG_PARAM_GET 32U
|
||||
#define PM_PINCTRL_CONFIG_PARAM_SET 33U
|
||||
#define PM_IOCTL 34U
|
||||
#define PM_QUERY_DATA 35U
|
||||
#define PM_CLOCK_ENABLE 36U
|
||||
#define PM_CLOCK_DISABLE 37U
|
||||
#define PM_CLOCK_GETSTATE 38U
|
||||
#define PM_CLOCK_SETDIVIDER 39U
|
||||
#define PM_CLOCK_GETDIVIDER 40U
|
||||
#define PM_CLOCK_SETRATE 41U
|
||||
#define PM_CLOCK_GETRATE 42U
|
||||
#define PM_CLOCK_SETPARENT 43U
|
||||
#define PM_CLOCK_GETPARENT 44U
|
||||
#define PM_PLL_SET_PARAMETER 48U
|
||||
#define PM_PLL_GET_PARAMETER 49U
|
||||
#define PM_PLL_SET_MODE 50U
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -114,49 +114,84 @@ int pm_setup(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
|
||||
* @smc_fid - Function Identifier
|
||||
* @x1 - x4 - Arguments
|
||||
* @cookie - Unused
|
||||
* @handler - Pointer to caller's context structure
|
||||
* eemi_for_compatibility() - EEMI calls handler for deprecated calls
|
||||
*
|
||||
* @return - Unused
|
||||
* @return - If EEMI API found then, uintptr_t type address, else 0
|
||||
*
|
||||
* Determines that smc_fid is valid and supported PM SMC Function ID from the
|
||||
* list of pm_api_ids, otherwise completes the request with
|
||||
* the unknown SMC Function ID
|
||||
*
|
||||
* The SMC calls for PM service are forwarded from SIP Service SMC handler
|
||||
* function with rt_svc_handle signature
|
||||
* Some EEMI API's use case needs to be changed in Linux driver, so they
|
||||
* can take advantage of common EEMI handler in TF-A. As of now the old
|
||||
* implementation of these APIs are required to maintain backward compatibility
|
||||
* until their use case in linux driver changes.
|
||||
*/
|
||||
uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
|
||||
uint64_t x4, void *cookie, void *handle, uint64_t flags)
|
||||
static uintptr_t eemi_for_compatibility(uint32_t api_id, uint32_t *pm_arg,
|
||||
void *handle, uint32_t security_flag)
|
||||
{
|
||||
enum pm_ret_status ret;
|
||||
|
||||
uint32_t pm_arg[4];
|
||||
uint32_t security_flag = SECURE_FLAG;
|
||||
switch (api_id) {
|
||||
|
||||
/* Handle case where PM wasn't initialized properly */
|
||||
if (pm_up == false) {
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
case PM_IOCTL:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], pm_arg[4],
|
||||
&value, security_flag);
|
||||
if (ret == PM_RET_ERROR_NOTSUPPORTED)
|
||||
return (uintptr_t)0;
|
||||
|
||||
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
|
||||
}
|
||||
|
||||
pm_arg[0] = (uint32_t)x1;
|
||||
pm_arg[1] = (uint32_t)(x1 >> 32);
|
||||
pm_arg[2] = (uint32_t)x2;
|
||||
pm_arg[3] = (uint32_t)(x2 >> 32);
|
||||
case PM_QUERY_DATA:
|
||||
{
|
||||
uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
|
||||
|
||||
/*
|
||||
* Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
|
||||
* if smc called is non secure
|
||||
*/
|
||||
if (is_caller_non_secure(flags) != 0) {
|
||||
security_flag = NON_SECURE_FLAG;
|
||||
ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], data, security_flag);
|
||||
|
||||
SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32),
|
||||
(uint64_t)data[1] | ((uint64_t)data[2] << 32));
|
||||
}
|
||||
|
||||
switch (smc_fid & FUNCID_NUM_MASK) {
|
||||
/* PM API Functions */
|
||||
case PM_FEATURE_CHECK:
|
||||
{
|
||||
uint32_t result[PAYLOAD_ARG_CNT] = {0U};
|
||||
|
||||
ret = pm_feature_check(pm_arg[0], result, security_flag);
|
||||
SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32),
|
||||
(uint64_t)result[1] | ((uint64_t)result[2] << 32));
|
||||
}
|
||||
|
||||
case PM_LOAD_PDI:
|
||||
{
|
||||
ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
}
|
||||
|
||||
default:
|
||||
return (uintptr_t)0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eemi_psci_debugfs_handler() - EEMI API invoked from PSCI
|
||||
*
|
||||
* These EEMI APIs performs CPU specific power management tasks.
|
||||
* These EEMI APIs are invoked either from PSCI or from debugfs in kernel.
|
||||
* These calls require CPU specific processing before sending IPI request to
|
||||
* Platform Management Controller. For example enable/disable CPU specific
|
||||
* interrupts. This requires separate handler for these calls and may not be
|
||||
* handled using common eemi handler
|
||||
*/
|
||||
static uintptr_t eemi_psci_debugfs_handler(uint32_t api_id, uint32_t *pm_arg,
|
||||
void *handle, uint32_t security_flag)
|
||||
{
|
||||
enum pm_ret_status ret;
|
||||
|
||||
switch (api_id) {
|
||||
|
||||
case PM_SELF_SUSPEND:
|
||||
ret = pm_self_suspend(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], security_flag);
|
||||
|
@ -179,65 +214,22 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
|
|||
ret = pm_system_shutdown(pm_arg[0], pm_arg[1], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_REQ_WAKEUP:
|
||||
ret = pm_req_wakeup(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
|
||||
security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_SET_WAKEUP_SOURCE:
|
||||
ret = pm_set_wakeup_source(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_REQUEST_DEVICE:
|
||||
ret = pm_request_device(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_RELEASE_DEVICE:
|
||||
ret = pm_release_device(pm_arg[0], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_SET_REQUIREMENT:
|
||||
ret = pm_set_requirement(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_GET_API_VERSION:
|
||||
{
|
||||
uint32_t api_version;
|
||||
|
||||
ret = pm_get_api_version(&api_version, security_flag);
|
||||
SMC_RET1(handle, (u_register_t)PM_RET_SUCCESS |
|
||||
((u_register_t)api_version << 32));
|
||||
default:
|
||||
return (uintptr_t)0;
|
||||
}
|
||||
}
|
||||
|
||||
case PM_GET_DEVICE_STATUS:
|
||||
{
|
||||
uint32_t buff[3];
|
||||
|
||||
ret = pm_get_device_status(pm_arg[0], buff, security_flag);
|
||||
SMC_RET2(handle, (u_register_t)ret | ((u_register_t)buff[0] << 32),
|
||||
(u_register_t)buff[1] | ((u_register_t)buff[2] << 32));
|
||||
}
|
||||
|
||||
case PM_RESET_ASSERT:
|
||||
ret = pm_reset_assert(pm_arg[0], pm_arg[1], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_RESET_GET_STATUS:
|
||||
{
|
||||
uint32_t reset_status;
|
||||
|
||||
ret = pm_reset_get_status(pm_arg[0], &reset_status,
|
||||
security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret |
|
||||
((u_register_t)reset_status << 32));
|
||||
}
|
||||
|
||||
case PM_INIT_FINALIZE:
|
||||
ret = pm_init_finalize(security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
/**
|
||||
* TF_A_specific_handler() - SMC handler for TF-A specific functionality
|
||||
*
|
||||
* These EEMI calls performs functionality that does not require
|
||||
* IPI transaction. The handler ends in TF-A and returns requested data to
|
||||
* kernel from TF-A
|
||||
*/
|
||||
static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg,
|
||||
void *handle, uint32_t security_flag)
|
||||
{
|
||||
switch (api_id) {
|
||||
|
||||
case PM_GET_CALLBACK_DATA:
|
||||
{
|
||||
|
@ -245,192 +237,115 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
|
|||
|
||||
pm_get_callbackdata(result, ARRAY_SIZE(result), security_flag);
|
||||
SMC_RET2(handle,
|
||||
(u_register_t)result[0] | ((u_register_t)result[1] << 32),
|
||||
(u_register_t)result[2] | ((u_register_t)result[3] << 32));
|
||||
}
|
||||
|
||||
case PM_PINCTRL_REQUEST:
|
||||
ret = pm_pinctrl_request(pm_arg[0], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_PINCTRL_RELEASE:
|
||||
ret = pm_pinctrl_release(pm_arg[0], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_PINCTRL_GET_FUNCTION:
|
||||
{
|
||||
uint32_t value = 0;
|
||||
|
||||
ret = pm_pinctrl_get_function(pm_arg[0], &value, security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_PINCTRL_SET_FUNCTION:
|
||||
ret = pm_pinctrl_set_function(pm_arg[0], pm_arg[1],
|
||||
security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_PINCTRL_CONFIG_PARAM_GET:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_pinctrl_get_pin_param(pm_arg[0], pm_arg[1], &value,
|
||||
security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_PINCTRL_CONFIG_PARAM_SET:
|
||||
ret = pm_pinctrl_set_pin_param(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_IOCTL:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], &value, security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_QUERY_DATA:
|
||||
{
|
||||
uint32_t data[8] = { 0 };
|
||||
|
||||
ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], data, security_flag);
|
||||
|
||||
SMC_RET2(handle, (u_register_t)ret | ((u_register_t)data[0] << 32),
|
||||
(u_register_t)data[1] | ((u_register_t)data[2] << 32));
|
||||
|
||||
}
|
||||
case PM_CLOCK_ENABLE:
|
||||
ret = pm_clock_enable(pm_arg[0], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_CLOCK_DISABLE:
|
||||
ret = pm_clock_disable(pm_arg[0], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_CLOCK_GETSTATE:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_clock_get_state(pm_arg[0], &value, security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_CLOCK_SETDIVIDER:
|
||||
ret = pm_clock_set_divider(pm_arg[0], pm_arg[1], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_CLOCK_GETDIVIDER:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_clock_get_divider(pm_arg[0], &value, security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_CLOCK_SETPARENT:
|
||||
ret = pm_clock_set_parent(pm_arg[0], pm_arg[1], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_CLOCK_GETPARENT:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_clock_get_parent(pm_arg[0], &value, security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_CLOCK_GETRATE:
|
||||
{
|
||||
uint32_t rate[2] = { 0 };
|
||||
|
||||
ret = pm_clock_get_rate(pm_arg[0], rate, security_flag);
|
||||
SMC_RET2(handle, (u_register_t)ret | ((u_register_t)rate[0] << 32),
|
||||
(u_register_t)rate[1] | ((u_register_t)0U << 32));
|
||||
}
|
||||
|
||||
case PM_PLL_SET_PARAMETER:
|
||||
ret = pm_pll_set_param(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_PLL_GET_PARAMETER:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_pll_get_param(pm_arg[0], pm_arg[1], &value,
|
||||
security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)value << 32));
|
||||
}
|
||||
|
||||
case PM_PLL_SET_MODE:
|
||||
ret = pm_pll_set_mode(pm_arg[0], pm_arg[1], security_flag);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_PLL_GET_MODE:
|
||||
{
|
||||
uint32_t mode;
|
||||
|
||||
ret = pm_pll_get_mode(pm_arg[0], &mode, security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)mode << 32));
|
||||
(uint64_t)result[0] | ((uint64_t)result[1] << 32),
|
||||
(uint64_t)result[2] | ((uint64_t)result[3] << 32));
|
||||
}
|
||||
|
||||
case PM_GET_TRUSTZONE_VERSION:
|
||||
SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
|
||||
((uint64_t)VERSAL_TZ_VERSION << 32));
|
||||
|
||||
case PM_GET_CHIPID:
|
||||
{
|
||||
uint32_t result[2];
|
||||
|
||||
ret = pm_get_chipid(result, security_flag);
|
||||
SMC_RET2(handle, (u_register_t)ret | ((u_register_t)result[0] << 32),
|
||||
(u_register_t)result[1] | ((u_register_t)0U << 32));
|
||||
}
|
||||
|
||||
case PM_FEATURE_CHECK:
|
||||
{
|
||||
uint32_t version;
|
||||
|
||||
ret = pm_feature_check(pm_arg[0], &version, security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)version << 32));
|
||||
}
|
||||
|
||||
case PM_LOAD_PDI:
|
||||
{
|
||||
ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret);
|
||||
}
|
||||
|
||||
case PM_GET_OP_CHARACTERISTIC:
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1], &result,
|
||||
security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret | ((u_register_t)result << 32));
|
||||
}
|
||||
|
||||
case PM_SET_MAX_LATENCY:
|
||||
{
|
||||
ret = pm_set_max_latency(pm_arg[0], pm_arg[1], security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret);
|
||||
}
|
||||
|
||||
case PM_REGISTER_NOTIFIER:
|
||||
{
|
||||
ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], security_flag);
|
||||
SMC_RET1(handle, (u_register_t)ret);
|
||||
}
|
||||
|
||||
default:
|
||||
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
return (uintptr_t)0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eemi_handler() - Prepare EEMI payload and perform IPI transaction
|
||||
*
|
||||
* EEMI - Embedded Energy Management Interface is Xilinx proprietary protocol
|
||||
* to allow communication between power management controller and different
|
||||
* processing clusters.
|
||||
*
|
||||
* This handler prepares EEMI protocol payload received from kernel and performs
|
||||
* IPI transaction.
|
||||
*/
|
||||
static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
|
||||
void *handle, uint32_t security_flag)
|
||||
{
|
||||
enum pm_ret_status ret;
|
||||
uint32_t buf[PAYLOAD_ARG_CNT] = {0};
|
||||
|
||||
ret = pm_handle_eemi_call(security_flag, api_id, pm_arg[0], pm_arg[1],
|
||||
pm_arg[2], pm_arg[3], pm_arg[4],
|
||||
(uint64_t *)buf);
|
||||
/*
|
||||
* Two IOCTLs, to get clock name and pinctrl name of pm_query_data API
|
||||
* receives 5 words of respoonse from firmware. Currently linux driver can
|
||||
* receive only 4 words from TF-A. So, this needs to be handled separately
|
||||
* than other eemi calls.
|
||||
*/
|
||||
if (api_id == PM_QUERY_DATA) {
|
||||
if ((pm_arg[0] == XPM_QID_CLOCK_GET_NAME ||
|
||||
pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME) &&
|
||||
ret == PM_RET_SUCCESS) {
|
||||
SMC_RET2(handle, (uint64_t)buf[0] | ((uint64_t)buf[1] << 32),
|
||||
(uint64_t)buf[2] | ((uint64_t)buf[3] << 32));
|
||||
}
|
||||
}
|
||||
|
||||
SMC_RET2(handle, (uint64_t)ret | ((uint64_t)buf[0] << 32),
|
||||
(uint64_t)buf[1] | ((uint64_t)buf[2] << 32));
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
|
||||
* @smc_fid - Function Identifier
|
||||
* @x1 - x4 - SMC64 Arguments from kernel
|
||||
* x3 (upper 32-bits) and x4 are Unused
|
||||
* @cookie - Unused
|
||||
* @handler - Pointer to caller's context structure
|
||||
*
|
||||
* @return - Unused
|
||||
*
|
||||
* Determines that smc_fid is valid and supported PM SMC Function ID from the
|
||||
* list of pm_api_ids, otherwise completes the request with
|
||||
* the unknown SMC Function ID
|
||||
*
|
||||
* The SMC calls for PM service are forwarded from SIP Service SMC handler
|
||||
* function with rt_svc_handle signature
|
||||
*/
|
||||
uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
|
||||
uint64_t x4, void *cookie, void *handle, uint64_t flags)
|
||||
{
|
||||
uintptr_t ret;
|
||||
uint32_t pm_arg[PAYLOAD_ARG_CNT] = {0};
|
||||
uint32_t security_flag = SECURE_FLAG;
|
||||
uint32_t api_id;
|
||||
|
||||
/* Handle case where PM wasn't initialized properly */
|
||||
if (!pm_up)
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
|
||||
/*
|
||||
* Mark BIT24 payload (i.e 1st bit of pm_arg[3] ) as non-secure (1)
|
||||
* if smc called is non secure
|
||||
*/
|
||||
if (is_caller_non_secure(flags)) {
|
||||
security_flag = NON_SECURE_FLAG;
|
||||
}
|
||||
|
||||
pm_arg[0] = (uint32_t)x1;
|
||||
pm_arg[1] = (uint32_t)(x1 >> 32);
|
||||
pm_arg[2] = (uint32_t)x2;
|
||||
pm_arg[3] = (uint32_t)(x2 >> 32);
|
||||
pm_arg[4] = (uint32_t)x3;
|
||||
(void)(x4);
|
||||
api_id = smc_fid & FUNCID_NUM_MASK;
|
||||
|
||||
ret = eemi_for_compatibility(api_id, pm_arg, handle, security_flag);
|
||||
if (ret != (uintptr_t)0)
|
||||
return ret;
|
||||
|
||||
ret = eemi_psci_debugfs_handler(api_id, pm_arg, handle, flags);
|
||||
if (ret != (uintptr_t)0)
|
||||
return ret;
|
||||
|
||||
ret = TF_A_specific_handler(api_id, pm_arg, handle, security_flag);
|
||||
if (ret != (uintptr_t)0)
|
||||
return ret;
|
||||
|
||||
ret = eemi_handler(api_id, pm_arg, handle, security_flag);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue