Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'zynqmp-soc-for-6.18' of https://github.com/Xilinx/linux-xlnx into soc/drivers

arm64: Xilinx SOC changes for 6.18

firmware:
- Add debugfs interface
- Wire versal-net compatible string
- Change SOC family detection

* tag 'zynqmp-soc-for-6.18' of https://github.com/Xilinx/linux-xlnx:
drivers: firmware: xilinx: Switch to new family code in zynqmp_pm_get_family_info()
drivers: firmware: xilinx: Add unique family code for all platforms
firmware: xilinx: Add Versal NET platform compatible string
firmware: xilinx: Add debugfs support for PM_GET_NODE_STATUS

+128 -54
+13
drivers/firmware/xilinx/zynqmp-debug.c
··· 3 3 * Xilinx Zynq MPSoC Firmware layer for debugfs APIs 4 4 * 5 5 * Copyright (C) 2014-2018 Xilinx, Inc. 6 + * Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc. 6 7 * 7 8 * Michal Simek <michal.simek@amd.com> 8 9 * Davorin Mista <davorin.mista@aggios.com> ··· 39 38 PM_API(PM_RELEASE_NODE), 40 39 PM_API(PM_SET_REQUIREMENT), 41 40 PM_API(PM_GET_API_VERSION), 41 + PM_API(PM_GET_NODE_STATUS), 42 42 PM_API(PM_REGISTER_NOTIFIER), 43 43 PM_API(PM_RESET_ASSERT), 44 44 PM_API(PM_RESET_GET_STATUS), ··· 168 166 pm_api_arg[2] : 0, 169 167 pm_api_arg[3] ? pm_api_arg[3] : 170 168 ZYNQMP_PM_REQUEST_ACK_BLOCKING); 169 + break; 170 + case PM_GET_NODE_STATUS: 171 + ret = zynqmp_pm_get_node_status(pm_api_arg[0], 172 + &pm_api_ret[0], 173 + &pm_api_ret[1], 174 + &pm_api_ret[2]); 175 + if (!ret) 176 + sprintf(debugfs_buf, 177 + "GET_NODE_STATUS:\n\tNodeId: %llu\n\tStatus: %u\n\tRequirements: %u\n\tUsage: %u\n", 178 + pm_api_arg[0], pm_api_ret[0], 179 + pm_api_ret[1], pm_api_ret[2]); 171 180 break; 172 181 case PM_REGISTER_NOTIFIER: 173 182 ret = zynqmp_pm_register_notifier(pm_api_arg[0],
+85 -29
drivers/firmware/xilinx/zynqmp.c
··· 3 3 * Xilinx Zynq MPSoC Firmware layer 4 4 * 5 5 * Copyright (C) 2014-2022 Xilinx, Inc. 6 - * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. 6 + * Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc. 7 7 * 8 8 * Michal Simek <michal.simek@amd.com> 9 9 * Davorin Mista <davorin.mista@aggios.com> ··· 71 71 int feature_status; 72 72 struct hlist_node hentry; 73 73 }; 74 + 75 + struct platform_fw_data { 76 + /* 77 + * Family code for platform. 78 + */ 79 + const u32 family_code; 80 + }; 81 + 82 + static struct platform_fw_data *active_platform_fw_data; 74 83 75 84 static const struct mfd_cell firmware_devs[] = { 76 85 { ··· 473 464 474 465 static u32 pm_api_version; 475 466 static u32 pm_tz_version; 476 - static u32 pm_family_code; 477 - static u32 pm_sub_family_code; 478 467 479 468 int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset) 480 469 { ··· 539 532 /** 540 533 * zynqmp_pm_get_family_info() - Get family info of platform 541 534 * @family: Returned family code value 542 - * @subfamily: Returned sub-family code value 543 535 * 544 536 * Return: Returns status, either success or error+reason 545 537 */ 546 - int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily) 538 + int zynqmp_pm_get_family_info(u32 *family) 547 539 { 548 - u32 ret_payload[PAYLOAD_ARG_CNT]; 549 - u32 idcode; 550 - int ret; 540 + if (!active_platform_fw_data) 541 + return -ENODEV; 551 542 552 - /* Check is family or sub-family code already received */ 553 - if (pm_family_code && pm_sub_family_code) { 554 - *family = pm_family_code; 555 - *subfamily = pm_sub_family_code; 556 - return 0; 557 - } 543 + if (!family) 544 + return -EINVAL; 558 545 559 - ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, ret_payload, 0); 560 - if (ret < 0) 561 - return ret; 562 - 563 - idcode = ret_payload[1]; 564 - pm_family_code = FIELD_GET(FAMILY_CODE_MASK, idcode); 565 - pm_sub_family_code = FIELD_GET(SUB_FAMILY_CODE_MASK, idcode); 566 - *family = pm_family_code; 567 - *subfamily = pm_sub_family_code; 546 + *family = active_platform_fw_data->family_code; 568 547 569 548 return 0; 570 549 } ··· 1231 1238 u32 value) 1232 1239 { 1233 1240 int ret; 1241 + u32 pm_family_code; 1234 1242 1235 - if (pm_family_code == ZYNQMP_FAMILY_CODE && 1243 + ret = zynqmp_pm_get_family_info(&pm_family_code); 1244 + if (ret) 1245 + return ret; 1246 + 1247 + if (pm_family_code == PM_ZYNQMP_FAMILY_CODE && 1236 1248 param == PM_PINCTRL_CONFIG_TRI_STATE) { 1237 1249 ret = zynqmp_pm_feature(PM_PINCTRL_CONFIG_PARAM_SET); 1238 1250 if (ret < PM_PINCTRL_PARAM_SET_VERSION) { ··· 1410 1412 (u32)tcm_mode); 1411 1413 } 1412 1414 EXPORT_SYMBOL_GPL(zynqmp_pm_set_tcm_config); 1415 + 1416 + /** 1417 + * zynqmp_pm_get_node_status - PM call to request a node's current power state 1418 + * @node: ID of the component or sub-system in question 1419 + * @status: Current operating state of the requested node 1420 + * @requirements: Current requirements asserted on the node, 1421 + * used for slave nodes only. 1422 + * @usage: Usage information, used for slave nodes only: 1423 + * PM_USAGE_NO_MASTER - No master is currently using 1424 + * the node 1425 + * PM_USAGE_CURRENT_MASTER - Only requesting master is 1426 + * currently using the node 1427 + * PM_USAGE_OTHER_MASTER - Only other masters are 1428 + * currently using the node 1429 + * PM_USAGE_BOTH_MASTERS - Both the current and at least 1430 + * one other master is currently 1431 + * using the node 1432 + * 1433 + * Return: Returns status, either success or error+reason 1434 + */ 1435 + int zynqmp_pm_get_node_status(const u32 node, u32 *const status, 1436 + u32 *const requirements, u32 *const usage) 1437 + { 1438 + u32 ret_payload[PAYLOAD_ARG_CNT]; 1439 + int ret; 1440 + 1441 + if (!status || !requirements || !usage) 1442 + return -EINVAL; 1443 + 1444 + ret = zynqmp_pm_invoke_fn(PM_GET_NODE_STATUS, ret_payload, 1, node); 1445 + if (ret_payload[0] == XST_PM_SUCCESS) { 1446 + *status = ret_payload[1]; 1447 + *requirements = ret_payload[2]; 1448 + *usage = ret_payload[3]; 1449 + } 1450 + 1451 + return ret; 1452 + } 1453 + EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status); 1413 1454 1414 1455 /** 1415 1456 * zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to ··· 2044 2007 { 2045 2008 struct device *dev = &pdev->dev; 2046 2009 struct zynqmp_devinfo *devinfo; 2010 + u32 pm_family_code; 2047 2011 int ret; 2048 2012 2049 2013 ret = get_set_conduit_method(dev->of_node); 2050 2014 if (ret) 2051 2015 return ret; 2016 + 2017 + /* Get platform-specific firmware data from device tree match */ 2018 + active_platform_fw_data = (struct platform_fw_data *)device_get_match_data(dev); 2019 + if (!active_platform_fw_data) 2020 + return -EINVAL; 2052 2021 2053 2022 /* Get SiP SVC version number */ 2054 2023 ret = zynqmp_pm_get_sip_svc_version(&sip_svc_version); ··· 2088 2045 pr_info("%s Platform Management API v%d.%d\n", __func__, 2089 2046 pm_api_version >> 16, pm_api_version & 0xFFFF); 2090 2047 2091 - /* Get the Family code and sub family code of platform */ 2092 - ret = zynqmp_pm_get_family_info(&pm_family_code, &pm_sub_family_code); 2048 + /* Get the Family code of platform */ 2049 + ret = zynqmp_pm_get_family_info(&pm_family_code); 2093 2050 if (ret < 0) 2094 2051 return ret; 2095 2052 ··· 2116 2073 2117 2074 zynqmp_pm_api_debugfs_init(); 2118 2075 2119 - if (pm_family_code == VERSAL_FAMILY_CODE) { 2076 + if (pm_family_code != PM_ZYNQMP_FAMILY_CODE) { 2120 2077 em_dev = platform_device_register_data(&pdev->dev, "xlnx_event_manager", 2121 2078 -1, NULL, 0); 2122 2079 if (IS_ERR(em_dev)) ··· 2156 2113 dev_warn(dev, "failed to release power management to firmware\n"); 2157 2114 } 2158 2115 2116 + static const struct platform_fw_data platform_fw_data_versal = { 2117 + .family_code = PM_VERSAL_FAMILY_CODE, 2118 + }; 2119 + 2120 + static const struct platform_fw_data platform_fw_data_versal_net = { 2121 + .family_code = PM_VERSAL_NET_FAMILY_CODE, 2122 + }; 2123 + 2124 + static const struct platform_fw_data platform_fw_data_zynqmp = { 2125 + .family_code = PM_ZYNQMP_FAMILY_CODE, 2126 + }; 2127 + 2159 2128 static const struct of_device_id zynqmp_firmware_of_match[] = { 2160 - {.compatible = "xlnx,zynqmp-firmware"}, 2161 - {.compatible = "xlnx,versal-firmware"}, 2129 + {.compatible = "xlnx,zynqmp-firmware", .data = &platform_fw_data_zynqmp}, 2130 + {.compatible = "xlnx,versal-firmware", .data = &platform_fw_data_versal}, 2131 + {.compatible = "xlnx,versal-net-firmware", .data = &platform_fw_data_versal_net}, 2162 2132 {}, 2163 2133 }; 2164 2134 MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match);
+3 -4
drivers/pinctrl/pinctrl-zynqmp.c
··· 100 100 101 101 static struct pinctrl_desc zynqmp_desc; 102 102 static u32 family_code; 103 - static u32 sub_family_code; 104 103 105 104 static int zynqmp_pctrl_get_groups_count(struct pinctrl_dev *pctldev) 106 105 { ··· 604 605 return -ENOMEM; 605 606 606 607 for (pin = 0; pin < groups[resp[i]].npins; pin++) { 607 - if (family_code == ZYNQMP_FAMILY_CODE) 608 + if (family_code == PM_ZYNQMP_FAMILY_CODE) 608 609 __set_bit(groups[resp[i]].pins[pin], used_pins); 609 610 else 610 611 __set_bit((u8)groups[resp[i]].pins[pin] - 1, used_pins); ··· 957 958 if (!pctrl) 958 959 return -ENOMEM; 959 960 960 - ret = zynqmp_pm_get_family_info(&family_code, &sub_family_code); 961 + ret = zynqmp_pm_get_family_info(&family_code); 961 962 if (ret < 0) 962 963 return ret; 963 964 964 - if (family_code == ZYNQMP_FAMILY_CODE) { 965 + if (family_code == PM_ZYNQMP_FAMILY_CODE) { 965 966 ret = zynqmp_pinctrl_prepare_pin_desc(&pdev->dev, &zynqmp_desc.pins, 966 967 &zynqmp_desc.npins); 967 968 } else {
+4 -4
drivers/soc/xilinx/xlnx_event_manager.c
··· 77 77 78 78 static bool xlnx_is_error_event(const u32 node_id) 79 79 { 80 - u32 pm_family_code, pm_sub_family_code; 80 + u32 pm_family_code; 81 81 82 - zynqmp_pm_get_family_info(&pm_family_code, &pm_sub_family_code); 82 + zynqmp_pm_get_family_info(&pm_family_code); 83 83 84 - if (pm_sub_family_code == VERSAL_SUB_FAMILY_CODE) { 84 + if (pm_family_code == PM_VERSAL_FAMILY_CODE) { 85 85 if (node_id == VERSAL_EVENT_ERROR_PMC_ERR1 || 86 86 node_id == VERSAL_EVENT_ERROR_PMC_ERR2 || 87 87 node_id == VERSAL_EVENT_ERROR_PSM_ERR1 || 88 88 node_id == VERSAL_EVENT_ERROR_PSM_ERR2) 89 89 return true; 90 - } else { 90 + } else if (pm_family_code == PM_VERSAL_NET_FAMILY_CODE) { 91 91 if (node_id == VERSAL_NET_EVENT_ERROR_PMC_ERR1 || 92 92 node_id == VERSAL_NET_EVENT_ERROR_PMC_ERR2 || 93 93 node_id == VERSAL_NET_EVENT_ERROR_PMC_ERR3 ||
+6 -4
drivers/soc/xilinx/zynqmp_power.c
··· 285 285 static int zynqmp_pm_probe(struct platform_device *pdev) 286 286 { 287 287 int ret, irq; 288 - u32 pm_api_version, pm_family_code, pm_sub_family_code, node_id; 288 + u32 pm_api_version, pm_family_code, node_id; 289 289 struct mbox_client *client; 290 290 291 291 ret = zynqmp_pm_get_api_version(&pm_api_version); ··· 315 315 INIT_WORK(&zynqmp_pm_init_suspend_work->callback_work, 316 316 zynqmp_pm_init_suspend_work_fn); 317 317 318 - ret = zynqmp_pm_get_family_info(&pm_family_code, &pm_sub_family_code); 318 + ret = zynqmp_pm_get_family_info(&pm_family_code); 319 319 if (ret < 0) 320 320 return ret; 321 321 322 - if (pm_sub_family_code == VERSALNET_SUB_FAMILY_CODE) 322 + if (pm_family_code == PM_VERSAL_NET_FAMILY_CODE) 323 323 node_id = PM_DEV_ACPU_0_0; 324 - else 324 + else if (pm_family_code == PM_VERSAL_FAMILY_CODE) 325 325 node_id = PM_DEV_ACPU_0; 326 + else 327 + return -ENODEV; 326 328 327 329 ret = register_event(&pdev->dev, PM_NOTIFY_CB, node_id, EVENT_SUBSYSTEM_RESTART, 328 330 false, subsystem_restart_event_callback);
+17 -13
include/linux/firmware/xlnx-zynqmp.h
··· 3 3 * Xilinx Zynq MPSoC Firmware layer 4 4 * 5 5 * Copyright (C) 2014-2021 Xilinx 6 - * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. 6 + * Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc. 7 7 * 8 8 * Michal Simek <michal.simek@amd.com> 9 9 * Davorin Mista <davorin.mista@aggios.com> ··· 51 51 52 52 #define PM_PINCTRL_PARAM_SET_VERSION 2 53 53 54 - #define ZYNQMP_FAMILY_CODE 0x23 55 - #define VERSAL_FAMILY_CODE 0x26 56 - 57 - /* When all subfamily of platform need to support */ 58 - #define ALL_SUB_FAMILY_CODE 0x00 59 - #define VERSAL_SUB_FAMILY_CODE 0x01 60 - #define VERSALNET_SUB_FAMILY_CODE 0x03 61 - 62 - #define FAMILY_CODE_MASK GENMASK(27, 21) 63 - #define SUB_FAMILY_CODE_MASK GENMASK(20, 19) 54 + /* Family codes */ 55 + #define PM_ZYNQMP_FAMILY_CODE 0x1 /* ZynqMP family code */ 56 + #define PM_VERSAL_FAMILY_CODE 0x2 /* Versal family code */ 57 + #define PM_VERSAL_NET_FAMILY_CODE 0x3 /* Versal NET family code */ 64 58 65 59 #define API_ID_MASK GENMASK(7, 0) 66 60 #define MODULE_ID_MASK GENMASK(11, 8) ··· 158 164 enum pm_api_id { 159 165 PM_API_FEATURES = 0, 160 166 PM_GET_API_VERSION = 1, 167 + PM_GET_NODE_STATUS = 3, 161 168 PM_REGISTER_NOTIFIER = 5, 162 169 PM_FORCE_POWERDOWN = 8, 163 170 PM_REQUEST_WAKEUP = 10, ··· 559 564 #if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE) 560 565 int zynqmp_pm_get_api_version(u32 *version); 561 566 int zynqmp_pm_get_chipid(u32 *idcode, u32 *version); 562 - int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily); 567 + int zynqmp_pm_get_family_info(u32 *family); 563 568 int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out); 564 569 int zynqmp_pm_clock_enable(u32 clock_id); 565 570 int zynqmp_pm_clock_disable(u32 clock_id); ··· 624 629 int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode); 625 630 int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode); 626 631 int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode); 632 + int zynqmp_pm_get_node_status(const u32 node, u32 *const status, 633 + u32 *const requirements, u32 *const usage); 627 634 int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value); 628 635 int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config, 629 636 u32 value); ··· 640 643 return -ENODEV; 641 644 } 642 645 643 - static inline int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily) 646 + static inline int zynqmp_pm_get_family_info(u32 *family) 644 647 { 645 648 return -ENODEV; 646 649 } ··· 924 927 } 925 928 926 929 static inline int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode) 930 + { 931 + return -ENODEV; 932 + } 933 + 934 + static inline int zynqmp_pm_get_node_status(const u32 node, u32 *const status, 935 + u32 *const requirements, 936 + u32 *const usage) 927 937 { 928 938 return -ENODEV; 929 939 }