mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-15 21:23:23 +00:00
arm64: ZynqMP SoC changes for 6.13
event_manager: - cleanup error path firmware: - add support for new SMC layout - fix feature check logic - extend debug interface - update reset ID format - report about unsupported feature in pinctrl -----BEGIN PGP SIGNATURE----- iF0EABECAB0WIQQbPNTMvXmYlBPRwx7KSWXLKUoMIQUCZyTGoAAKCRDKSWXLKUoM IbdnAJ9x+L4yeJLz60yyoPTWDchO5C71dQCfeRd1sZOhKsypWOA0c2YpdUJE2m4= =awm8 -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEiK/NIGsWEZVxh/FrYKtH/8kJUicFAmcozKQACgkQYKtH/8kJ UifaIQ//UuIndHDt6Mnc+ghqg09LBm7499jYoGVA2r8nWS9LFAazU1v6SuBmcOf7 udYPqExtlosVMMvYkQxato8AAemsNyDU1djsIdXyfftWPrguGuPW7uCt09P8PVju t9c2WP4jQqomoJ22J3Tu8BKvecp3yOslZ1TvYcbbhDvuR/AE73k68Yz1YbE5/o9L rS7sYz4JJRLGanxfJ7WeWA8IReBSkWjkdDl14ImP5316Tq0KVZq1UBD4uOFxu4cJ k6Dgs3KoYy1rlLwgHTnbmy8uvhsGetuW4dRTm6GCyrL5/jZgxRHxoM8vBp9eu+YC k5plRwcesxJvO/UpY4cWX3ysHWDBHLmc0PDpQnxpbb2g4rNjTF0gVUXVTwy0t4uI FIPoxiDFPTtyl4JT6gB+Z7AmbcLMAzljmCRRE1EczVNhJxBniJVJ0IUyV40OLBok spGCfEJ9fCZ4BM0A8e+5T6A5MSfLOLQWcXbfkjVkmhLYiYO4D59+YTEJIvj05/vV zL5mxVeRs3fYtfTPGtAsJOT/QPUuA+Tayhtyrrgq9NJlxN7CPi+i/GJ2sMxnQeNv dTyxtGXY+P7cujbwSxjx2PZxUQ3+tqM7mP72Twz9jBxdj9ylz1KSKLbmSS+7w+yK pc2CHos7QkhYVUY32kzKHVc2ObwfS1t24i+ofD3g8qcLIlnCOzk= =O+nQ -----END PGP SIGNATURE----- Merge tag 'zynqmp-soc-for-6.13' of https://github.com/Xilinx/linux-xlnx into arm/drivers arm64: ZynqMP SoC changes for 6.13 event_manager: - cleanup error path firmware: - add support for new SMC layout - fix feature check logic - extend debug interface - update reset ID format - report about unsupported feature in pinctrl * tag 'zynqmp-soc-for-6.13' of https://github.com/Xilinx/linux-xlnx: firmware: xilinx: fix feature check logic for TF-A specific APIs firmware: xilinx: add support for new SMC call format firmware: xilinx: add a warning print for unsupported feature firmware: xilinx: use u32 for reset ID in reset APIs firmware: xilinx: Add missing debug firmware interfaces drivers: soc: xilinx: add the missing kfree in xlnx_add_cb_for_suspend() Link: https://lore.kernel.org/r/CAHTX3dK9PKmG_UG4MW=x5KmZCrd5PkcAZiNVgPFQ_zsPRgu+dg@mail.gmail.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
04d4d0a446
@ -31,12 +31,50 @@ static char debugfs_buf[PAGE_SIZE];
|
||||
|
||||
#define PM_API(id) {id, #id, strlen(#id)}
|
||||
static struct pm_api_info pm_api_list[] = {
|
||||
PM_API(PM_FORCE_POWERDOWN),
|
||||
PM_API(PM_REQUEST_WAKEUP),
|
||||
PM_API(PM_SYSTEM_SHUTDOWN),
|
||||
PM_API(PM_REQUEST_NODE),
|
||||
PM_API(PM_RELEASE_NODE),
|
||||
PM_API(PM_SET_REQUIREMENT),
|
||||
PM_API(PM_GET_API_VERSION),
|
||||
PM_API(PM_REGISTER_NOTIFIER),
|
||||
PM_API(PM_RESET_ASSERT),
|
||||
PM_API(PM_RESET_GET_STATUS),
|
||||
PM_API(PM_GET_CHIPID),
|
||||
PM_API(PM_PINCTRL_SET_FUNCTION),
|
||||
PM_API(PM_PINCTRL_CONFIG_PARAM_GET),
|
||||
PM_API(PM_PINCTRL_CONFIG_PARAM_SET),
|
||||
PM_API(PM_IOCTL),
|
||||
PM_API(PM_CLOCK_ENABLE),
|
||||
PM_API(PM_CLOCK_DISABLE),
|
||||
PM_API(PM_CLOCK_GETSTATE),
|
||||
PM_API(PM_CLOCK_SETDIVIDER),
|
||||
PM_API(PM_CLOCK_GETDIVIDER),
|
||||
PM_API(PM_CLOCK_SETPARENT),
|
||||
PM_API(PM_CLOCK_GETPARENT),
|
||||
PM_API(PM_QUERY_DATA),
|
||||
};
|
||||
|
||||
static struct dentry *firmware_debugfs_root;
|
||||
|
||||
/**
|
||||
* zynqmp_pm_ioctl - PM IOCTL for device control and configs
|
||||
* @node: Node ID of the device
|
||||
* @ioctl: ID of the requested IOCTL
|
||||
* @arg1: Argument 1 of requested IOCTL call
|
||||
* @arg2: Argument 2 of requested IOCTL call
|
||||
* @arg3: Argument 3 of requested IOCTL call
|
||||
* @out: Returned output value
|
||||
*
|
||||
* Return: Returns status, either success or error+reason
|
||||
*/
|
||||
static int zynqmp_pm_ioctl(const u32 node, const u32 ioctl, const u32 arg1,
|
||||
const u32 arg2, const u32 arg3, u32 *out)
|
||||
{
|
||||
return zynqmp_pm_invoke_fn(PM_IOCTL, out, 5, node, ioctl, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
/**
|
||||
* zynqmp_pm_argument_value() - Extract argument value from a PM-API request
|
||||
* @arg: Entered PM-API argument in string format
|
||||
@ -95,6 +133,128 @@ static int process_api_request(u32 pm_id, u64 *pm_api_arg, u32 *pm_api_ret)
|
||||
sprintf(debugfs_buf, "PM-API Version = %d.%d\n",
|
||||
pm_api_version >> 16, pm_api_version & 0xffff);
|
||||
break;
|
||||
case PM_FORCE_POWERDOWN:
|
||||
ret = zynqmp_pm_force_pwrdwn(pm_api_arg[0],
|
||||
pm_api_arg[1] ? pm_api_arg[1] :
|
||||
ZYNQMP_PM_REQUEST_ACK_NO);
|
||||
break;
|
||||
case PM_REQUEST_WAKEUP:
|
||||
ret = zynqmp_pm_request_wake(pm_api_arg[0],
|
||||
pm_api_arg[1], pm_api_arg[2],
|
||||
pm_api_arg[3] ? pm_api_arg[3] :
|
||||
ZYNQMP_PM_REQUEST_ACK_NO);
|
||||
break;
|
||||
case PM_SYSTEM_SHUTDOWN:
|
||||
ret = zynqmp_pm_system_shutdown(pm_api_arg[0], pm_api_arg[1]);
|
||||
break;
|
||||
case PM_REQUEST_NODE:
|
||||
ret = zynqmp_pm_request_node(pm_api_arg[0],
|
||||
pm_api_arg[1] ? pm_api_arg[1] :
|
||||
ZYNQMP_PM_CAPABILITY_ACCESS,
|
||||
pm_api_arg[2] ? pm_api_arg[2] : 0,
|
||||
pm_api_arg[3] ? pm_api_arg[3] :
|
||||
ZYNQMP_PM_REQUEST_ACK_BLOCKING);
|
||||
break;
|
||||
case PM_RELEASE_NODE:
|
||||
ret = zynqmp_pm_release_node(pm_api_arg[0]);
|
||||
break;
|
||||
case PM_SET_REQUIREMENT:
|
||||
ret = zynqmp_pm_set_requirement(pm_api_arg[0],
|
||||
pm_api_arg[1] ? pm_api_arg[1] :
|
||||
ZYNQMP_PM_CAPABILITY_CONTEXT,
|
||||
pm_api_arg[2] ?
|
||||
pm_api_arg[2] : 0,
|
||||
pm_api_arg[3] ? pm_api_arg[3] :
|
||||
ZYNQMP_PM_REQUEST_ACK_BLOCKING);
|
||||
break;
|
||||
case PM_REGISTER_NOTIFIER:
|
||||
ret = zynqmp_pm_register_notifier(pm_api_arg[0],
|
||||
pm_api_arg[1] ?
|
||||
pm_api_arg[1] : 0,
|
||||
pm_api_arg[2] ?
|
||||
pm_api_arg[2] : 0,
|
||||
pm_api_arg[3] ?
|
||||
pm_api_arg[3] : 0);
|
||||
break;
|
||||
case PM_RESET_ASSERT:
|
||||
ret = zynqmp_pm_reset_assert(pm_api_arg[0], pm_api_arg[1]);
|
||||
break;
|
||||
case PM_RESET_GET_STATUS:
|
||||
ret = zynqmp_pm_reset_get_status(pm_api_arg[0], &pm_api_ret[0]);
|
||||
if (!ret)
|
||||
sprintf(debugfs_buf, "Reset status: %u\n",
|
||||
pm_api_ret[0]);
|
||||
break;
|
||||
case PM_GET_CHIPID:
|
||||
ret = zynqmp_pm_get_chipid(&pm_api_ret[0], &pm_api_ret[1]);
|
||||
if (!ret)
|
||||
sprintf(debugfs_buf, "Idcode: %#x, Version:%#x\n",
|
||||
pm_api_ret[0], pm_api_ret[1]);
|
||||
break;
|
||||
case PM_PINCTRL_SET_FUNCTION:
|
||||
ret = zynqmp_pm_pinctrl_set_function(pm_api_arg[0],
|
||||
pm_api_arg[1]);
|
||||
break;
|
||||
case PM_PINCTRL_CONFIG_PARAM_GET:
|
||||
ret = zynqmp_pm_pinctrl_get_config(pm_api_arg[0], pm_api_arg[1],
|
||||
&pm_api_ret[0]);
|
||||
if (!ret)
|
||||
sprintf(debugfs_buf,
|
||||
"Pin: %llu, Param: %llu, Value: %u\n",
|
||||
pm_api_arg[0], pm_api_arg[1],
|
||||
pm_api_ret[0]);
|
||||
break;
|
||||
case PM_PINCTRL_CONFIG_PARAM_SET:
|
||||
ret = zynqmp_pm_pinctrl_set_config(pm_api_arg[0],
|
||||
pm_api_arg[1],
|
||||
pm_api_arg[2]);
|
||||
break;
|
||||
case PM_IOCTL:
|
||||
ret = zynqmp_pm_ioctl(pm_api_arg[0], pm_api_arg[1],
|
||||
pm_api_arg[2], pm_api_arg[3],
|
||||
pm_api_arg[4], &pm_api_ret[0]);
|
||||
if (!ret && (pm_api_arg[1] == IOCTL_GET_RPU_OPER_MODE ||
|
||||
pm_api_arg[1] == IOCTL_GET_PLL_FRAC_MODE ||
|
||||
pm_api_arg[1] == IOCTL_GET_PLL_FRAC_DATA ||
|
||||
pm_api_arg[1] == IOCTL_READ_GGS ||
|
||||
pm_api_arg[1] == IOCTL_READ_PGGS ||
|
||||
pm_api_arg[1] == IOCTL_READ_REG))
|
||||
sprintf(debugfs_buf, "IOCTL return value: %u\n",
|
||||
pm_api_ret[1]);
|
||||
if (!ret && pm_api_arg[1] == IOCTL_GET_QOS)
|
||||
sprintf(debugfs_buf, "Default QoS: %u\nCurrent QoS: %u\n",
|
||||
pm_api_ret[1], pm_api_ret[2]);
|
||||
break;
|
||||
case PM_CLOCK_ENABLE:
|
||||
ret = zynqmp_pm_clock_enable(pm_api_arg[0]);
|
||||
break;
|
||||
case PM_CLOCK_DISABLE:
|
||||
ret = zynqmp_pm_clock_disable(pm_api_arg[0]);
|
||||
break;
|
||||
case PM_CLOCK_GETSTATE:
|
||||
ret = zynqmp_pm_clock_getstate(pm_api_arg[0], &pm_api_ret[0]);
|
||||
if (!ret)
|
||||
sprintf(debugfs_buf, "Clock state: %u\n",
|
||||
pm_api_ret[0]);
|
||||
break;
|
||||
case PM_CLOCK_SETDIVIDER:
|
||||
ret = zynqmp_pm_clock_setdivider(pm_api_arg[0], pm_api_arg[1]);
|
||||
break;
|
||||
case PM_CLOCK_GETDIVIDER:
|
||||
ret = zynqmp_pm_clock_getdivider(pm_api_arg[0], &pm_api_ret[0]);
|
||||
if (!ret)
|
||||
sprintf(debugfs_buf, "Divider Value: %d\n",
|
||||
pm_api_ret[0]);
|
||||
break;
|
||||
case PM_CLOCK_SETPARENT:
|
||||
ret = zynqmp_pm_clock_setparent(pm_api_arg[0], pm_api_arg[1]);
|
||||
break;
|
||||
case PM_CLOCK_GETPARENT:
|
||||
ret = zynqmp_pm_clock_getparent(pm_api_arg[0], &pm_api_ret[0]);
|
||||
if (!ret)
|
||||
sprintf(debugfs_buf,
|
||||
"Clock parent Index: %u\n", pm_api_ret[0]);
|
||||
break;
|
||||
case PM_QUERY_DATA:
|
||||
qdata.qid = pm_api_arg[0];
|
||||
qdata.arg1 = pm_api_arg[1];
|
||||
@ -150,7 +310,7 @@ static ssize_t zynqmp_pm_debugfs_api_write(struct file *file,
|
||||
char *kern_buff, *tmp_buff;
|
||||
char *pm_api_req;
|
||||
u32 pm_id = 0;
|
||||
u64 pm_api_arg[4] = {0, 0, 0, 0};
|
||||
u64 pm_api_arg[5] = {0, 0, 0, 0, 0};
|
||||
/* Return values from PM APIs calls */
|
||||
u32 pm_api_ret[4] = {0, 0, 0, 0};
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Xilinx Zynq MPSoC Firmware layer
|
||||
*
|
||||
* Copyright (C) 2014-2022 Xilinx, Inc.
|
||||
* Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Michal Simek <michal.simek@amd.com>
|
||||
* Davorin Mista <davorin.mista@aggios.com>
|
||||
@ -46,6 +46,7 @@ static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER);
|
||||
static u32 ioctl_features[FEATURE_PAYLOAD_SIZE];
|
||||
static u32 query_features[FEATURE_PAYLOAD_SIZE];
|
||||
|
||||
static u32 sip_svc_version;
|
||||
static struct platform_device *em_dev;
|
||||
|
||||
/**
|
||||
@ -151,6 +152,9 @@ static noinline int do_fw_call_smc(u32 *ret_payload, u32 num_args, ...)
|
||||
ret_payload[1] = upper_32_bits(res.a0);
|
||||
ret_payload[2] = lower_32_bits(res.a1);
|
||||
ret_payload[3] = upper_32_bits(res.a1);
|
||||
ret_payload[4] = lower_32_bits(res.a2);
|
||||
ret_payload[5] = upper_32_bits(res.a2);
|
||||
ret_payload[6] = lower_32_bits(res.a3);
|
||||
}
|
||||
|
||||
return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
|
||||
@ -191,6 +195,9 @@ static noinline int do_fw_call_hvc(u32 *ret_payload, u32 num_args, ...)
|
||||
ret_payload[1] = upper_32_bits(res.a0);
|
||||
ret_payload[2] = lower_32_bits(res.a1);
|
||||
ret_payload[3] = upper_32_bits(res.a1);
|
||||
ret_payload[4] = lower_32_bits(res.a2);
|
||||
ret_payload[5] = upper_32_bits(res.a2);
|
||||
ret_payload[6] = lower_32_bits(res.a3);
|
||||
}
|
||||
|
||||
return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
|
||||
@ -218,11 +225,14 @@ static int __do_feature_check_call(const u32 api_id, u32 *ret_payload)
|
||||
* Feature check of TF-A APIs is done in the TF-A layer and it expects for
|
||||
* MODULE_ID_MASK bits of SMC's arg[0] to be the same as PM_MODULE_ID.
|
||||
*/
|
||||
if (module_id == TF_A_MODULE_ID)
|
||||
if (module_id == TF_A_MODULE_ID) {
|
||||
module_id = PM_MODULE_ID;
|
||||
smc_arg[1] = api_id;
|
||||
} else {
|
||||
smc_arg[1] = (api_id & API_ID_MASK);
|
||||
}
|
||||
|
||||
smc_arg[0] = PM_SIP_SVC | FIELD_PREP(MODULE_ID_MASK, module_id) | feature_check_api_id;
|
||||
smc_arg[1] = (api_id & API_ID_MASK);
|
||||
|
||||
ret = do_fw_call(ret_payload, 2, smc_arg[0], smc_arg[1]);
|
||||
if (ret)
|
||||
@ -331,6 +341,70 @@ int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(zynqmp_pm_is_function_supported);
|
||||
|
||||
/**
|
||||
* zynqmp_pm_invoke_fw_fn() - Invoke the system-level platform management layer
|
||||
* caller function depending on the configuration
|
||||
* @pm_api_id: Requested PM-API call
|
||||
* @ret_payload: Returned value array
|
||||
* @num_args: Number of arguments to requested PM-API call
|
||||
*
|
||||
* Invoke platform management function for SMC or HVC call, depending on
|
||||
* configuration.
|
||||
* Following SMC Calling Convention (SMCCC) for SMC64:
|
||||
* Pm Function Identifier,
|
||||
* PM_SIP_SVC + PASS_THROUGH_FW_CMD_ID =
|
||||
* ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)
|
||||
* ((SMC_64) << FUNCID_CC_SHIFT)
|
||||
* ((SIP_START) << FUNCID_OEN_SHIFT)
|
||||
* (PASS_THROUGH_FW_CMD_ID))
|
||||
*
|
||||
* PM_SIP_SVC - Registered ZynqMP SIP Service Call.
|
||||
* PASS_THROUGH_FW_CMD_ID - Fixed SiP SVC call ID for FW specific calls.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason
|
||||
*/
|
||||
int zynqmp_pm_invoke_fw_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...)
|
||||
{
|
||||
/*
|
||||
* Added SIP service call Function Identifier
|
||||
* Make sure to stay in x0 register
|
||||
*/
|
||||
u64 smc_arg[SMC_ARG_CNT_64];
|
||||
int ret, i;
|
||||
va_list arg_list;
|
||||
u32 args[SMC_ARG_CNT_32] = {0};
|
||||
u32 module_id;
|
||||
|
||||
if (num_args > SMC_ARG_CNT_32)
|
||||
return -EINVAL;
|
||||
|
||||
va_start(arg_list, num_args);
|
||||
|
||||
/* Check if feature is supported or not */
|
||||
ret = zynqmp_pm_feature(pm_api_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < num_args; i++)
|
||||
args[i] = va_arg(arg_list, u32);
|
||||
|
||||
va_end(arg_list);
|
||||
|
||||
module_id = FIELD_GET(PLM_MODULE_ID_MASK, pm_api_id);
|
||||
|
||||
if (module_id == 0)
|
||||
module_id = XPM_MODULE_ID;
|
||||
|
||||
smc_arg[0] = PM_SIP_SVC | PASS_THROUGH_FW_CMD_ID;
|
||||
smc_arg[1] = ((u64)args[0] << 32U) | FIELD_PREP(PLM_MODULE_ID_MASK, module_id) |
|
||||
(pm_api_id & API_ID_MASK);
|
||||
for (i = 1; i < (SMC_ARG_CNT_64 - 1); i++)
|
||||
smc_arg[i + 1] = ((u64)args[(i * 2)] << 32U) | args[(i * 2) - 1];
|
||||
|
||||
return do_fw_call(ret_payload, 8, smc_arg[0], smc_arg[1], smc_arg[2], smc_arg[3],
|
||||
smc_arg[4], smc_arg[5], smc_arg[6], smc_arg[7]);
|
||||
}
|
||||
|
||||
/**
|
||||
* zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer
|
||||
* caller function depending on the configuration
|
||||
@ -488,6 +562,35 @@ int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(zynqmp_pm_get_family_info);
|
||||
|
||||
/**
|
||||
* zynqmp_pm_get_sip_svc_version() - Get SiP service call version
|
||||
* @version: Returned version value
|
||||
*
|
||||
* Return: Returns status, either success or error+reason
|
||||
*/
|
||||
static int zynqmp_pm_get_sip_svc_version(u32 *version)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
u64 args[SMC_ARG_CNT_64] = {0};
|
||||
|
||||
if (!version)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check if SiP SVC version already verified */
|
||||
if (sip_svc_version > 0) {
|
||||
*version = sip_svc_version;
|
||||
return 0;
|
||||
}
|
||||
|
||||
args[0] = GET_SIP_SVC_VERSION;
|
||||
|
||||
arm_smccc_smc(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], &res);
|
||||
|
||||
*version = ((lower_32_bits(res.a0) << 16U) | lower_32_bits(res.a1));
|
||||
|
||||
return zynqmp_pm_ret_code(XST_PM_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* zynqmp_pm_get_trustzone_version() - Get secure trustzone firmware version
|
||||
* @version: Returned version value
|
||||
@ -552,10 +655,34 @@ static int get_set_conduit_method(struct device_node *np)
|
||||
*/
|
||||
int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out)
|
||||
{
|
||||
int ret;
|
||||
int ret, i = 0;
|
||||
u32 ret_payload[PAYLOAD_ARG_CNT] = {0};
|
||||
|
||||
ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, out, 4, qdata.qid, qdata.arg1, qdata.arg2,
|
||||
qdata.arg3);
|
||||
if (sip_svc_version >= SIP_SVC_PASSTHROUGH_VERSION) {
|
||||
ret = zynqmp_pm_invoke_fw_fn(PM_QUERY_DATA, ret_payload, 4,
|
||||
qdata.qid, qdata.arg1,
|
||||
qdata.arg2, qdata.arg3);
|
||||
/* To support backward compatibility */
|
||||
if (!ret && !ret_payload[0]) {
|
||||
/*
|
||||
* TF-A passes return status on 0th index but
|
||||
* api to get clock name reads data from 0th
|
||||
* index so pass data at 0th index instead of
|
||||
* return status
|
||||
*/
|
||||
if (qdata.qid == PM_QID_CLOCK_GET_NAME ||
|
||||
qdata.qid == PM_QID_PINCTRL_GET_FUNCTION_NAME)
|
||||
i = 1;
|
||||
|
||||
for (; i < PAYLOAD_ARG_CNT; i++, out++)
|
||||
*out = ret_payload[i];
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, out, 4, qdata.qid,
|
||||
qdata.arg1, qdata.arg2, qdata.arg3);
|
||||
|
||||
/*
|
||||
* For clock name query, all bytes in SMC response are clock name
|
||||
@ -920,7 +1047,7 @@ int zynqmp_pm_set_boot_health_status(u32 value)
|
||||
*
|
||||
* Return: Returns status, either success or error+reason
|
||||
*/
|
||||
int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
|
||||
int zynqmp_pm_reset_assert(const u32 reset,
|
||||
const enum zynqmp_pm_reset_action assert_flag)
|
||||
{
|
||||
return zynqmp_pm_invoke_fn(PM_RESET_ASSERT, NULL, 2, reset, assert_flag);
|
||||
@ -934,7 +1061,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_reset_assert);
|
||||
*
|
||||
* Return: Returns status, either success or error+reason
|
||||
*/
|
||||
int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status)
|
||||
int zynqmp_pm_reset_get_status(const u32 reset, u32 *status)
|
||||
{
|
||||
u32 ret_payload[PAYLOAD_ARG_CNT];
|
||||
int ret;
|
||||
@ -1118,8 +1245,11 @@ int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param,
|
||||
if (pm_family_code == ZYNQMP_FAMILY_CODE &&
|
||||
param == PM_PINCTRL_CONFIG_TRI_STATE) {
|
||||
ret = zynqmp_pm_feature(PM_PINCTRL_CONFIG_PARAM_SET);
|
||||
if (ret < PM_PINCTRL_PARAM_SET_VERSION)
|
||||
if (ret < PM_PINCTRL_PARAM_SET_VERSION) {
|
||||
pr_warn("The requested pinctrl feature is not supported in the current firmware.\n"
|
||||
"Expected firmware version is 2023.1 and above for this feature to work.\r\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
return zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_SET, NULL, 3, pin, param, value);
|
||||
@ -1887,6 +2017,11 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Get SiP SVC version number */
|
||||
ret = zynqmp_pm_get_sip_svc_version(&sip_svc_version);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = do_feature_check_call(PM_FEATURE_CHECK);
|
||||
if (ret >= 0 && ((ret & FIRMWARE_VERSION_MASK) >= PM_API_VERSION_1))
|
||||
feature_check_enabled = true;
|
||||
|
@ -188,8 +188,10 @@ static int xlnx_add_cb_for_suspend(event_cb_func_t cb_fun, void *data)
|
||||
INIT_LIST_HEAD(&eve_data->cb_list_head);
|
||||
|
||||
cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL);
|
||||
if (!cb_data)
|
||||
if (!cb_data) {
|
||||
kfree(eve_data);
|
||||
return -ENOMEM;
|
||||
}
|
||||
cb_data->eve_cb = cb_fun;
|
||||
cb_data->agent_data = data;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Xilinx Zynq MPSoC Firmware layer
|
||||
*
|
||||
* Copyright (C) 2014-2021 Xilinx
|
||||
* Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Michal Simek <michal.simek@amd.com>
|
||||
* Davorin Mista <davorin.mista@aggios.com>
|
||||
@ -32,6 +32,19 @@
|
||||
/* SMC SIP service Call Function Identifier Prefix */
|
||||
#define PM_SIP_SVC 0xC2000000
|
||||
|
||||
/* SMC function ID to get SiP SVC version */
|
||||
#define GET_SIP_SVC_VERSION (0x8200ff03U)
|
||||
|
||||
/* SiP Service Calls version numbers */
|
||||
#define SIP_SVC_VERSION_MAJOR (0U)
|
||||
#define SIP_SVC_VERSION_MINOR (2U)
|
||||
|
||||
#define SIP_SVC_PASSTHROUGH_VERSION ((SIP_SVC_VERSION_MAJOR << 16) | \
|
||||
SIP_SVC_VERSION_MINOR)
|
||||
|
||||
/* Fixed ID for FW specific APIs */
|
||||
#define PASS_THROUGH_FW_CMD_ID GENMASK(11, 0)
|
||||
|
||||
/* PM API versions */
|
||||
#define PM_API_VERSION_1 1
|
||||
#define PM_API_VERSION_2 2
|
||||
@ -51,6 +64,7 @@
|
||||
|
||||
#define API_ID_MASK GENMASK(7, 0)
|
||||
#define MODULE_ID_MASK GENMASK(11, 8)
|
||||
#define PLM_MODULE_ID_MASK GENMASK(15, 8)
|
||||
|
||||
/* Firmware feature check version mask */
|
||||
#define FIRMWARE_VERSION_MASK 0xFFFFU
|
||||
@ -62,7 +76,13 @@
|
||||
#define GET_CALLBACK_DATA 0xa01
|
||||
|
||||
/* Number of 32bits values in payload */
|
||||
#define PAYLOAD_ARG_CNT 4U
|
||||
#define PAYLOAD_ARG_CNT 7U
|
||||
|
||||
/* Number of 64bits arguments for SMC call */
|
||||
#define SMC_ARG_CNT_64 8U
|
||||
|
||||
/* Number of 32bits arguments for SMC call */
|
||||
#define SMC_ARG_CNT_32 13U
|
||||
|
||||
/* Number of arguments for a callback */
|
||||
#define CB_ARG_CNT 4
|
||||
@ -130,6 +150,7 @@
|
||||
|
||||
enum pm_module_id {
|
||||
PM_MODULE_ID = 0x0,
|
||||
XPM_MODULE_ID = 0x2,
|
||||
XSEM_MODULE_ID = 0x3,
|
||||
TF_A_MODULE_ID = 0xa,
|
||||
};
|
||||
@ -218,9 +239,13 @@ enum pm_ioctl_id {
|
||||
/* Runtime feature configuration */
|
||||
IOCTL_SET_FEATURE_CONFIG = 26,
|
||||
IOCTL_GET_FEATURE_CONFIG = 27,
|
||||
/* IOCTL for Secure Read/Write Interface */
|
||||
IOCTL_READ_REG = 28,
|
||||
/* Dynamic SD/GEM configuration */
|
||||
IOCTL_SET_SD_CONFIG = 30,
|
||||
IOCTL_SET_GEM_CONFIG = 31,
|
||||
/* IOCTL to get default/current QoS */
|
||||
IOCTL_GET_QOS = 34,
|
||||
};
|
||||
|
||||
enum pm_query_id {
|
||||
@ -533,6 +558,7 @@ struct zynqmp_pm_query_data {
|
||||
};
|
||||
|
||||
int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...);
|
||||
int zynqmp_pm_invoke_fw_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...);
|
||||
|
||||
#if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE)
|
||||
int zynqmp_pm_get_api_version(u32 *version);
|
||||
@ -553,9 +579,9 @@ int zynqmp_pm_get_pll_frac_data(u32 clk_id, u32 *data);
|
||||
int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value);
|
||||
int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type);
|
||||
int zynqmp_pm_ospi_mux_select(u32 dev_id, u32 select);
|
||||
int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
|
||||
int zynqmp_pm_reset_assert(const u32 reset,
|
||||
const enum zynqmp_pm_reset_action assert_flag);
|
||||
int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status);
|
||||
int zynqmp_pm_reset_get_status(const u32 reset, u32 *status);
|
||||
unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode);
|
||||
int zynqmp_pm_bootmode_write(u32 ps_mode);
|
||||
int zynqmp_pm_init_finalize(void);
|
||||
@ -698,14 +724,13 @@ static inline int zynqmp_pm_ospi_mux_select(u32 dev_id, u32 select)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
|
||||
static inline int zynqmp_pm_reset_assert(const u32 reset,
|
||||
const enum zynqmp_pm_reset_action assert_flag)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset,
|
||||
u32 *status)
|
||||
static inline int zynqmp_pm_reset_get_status(const u32 reset, u32 *status)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user