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

drivers: firmware: xilinx: Switch to new family code in zynqmp_pm_get_family_info()

Currently, the family code and subfamily code are derived from the
PMC_TAP_IDCODE register. Versal, Versal NET share the same family
code. Also some platforms share the same subfamily code, making it
difficult to distinguish between platforms. Update
zynqmp_pm_get_family_info() to use IDs derived from the compatible
string instead of silicon ID codes derived from PMC_TAP_IDCODE register.

Signed-off-by: Jay Buddhabhatti <jay.buddhabhatti@amd.com>
Link: https://lore.kernel.org/r/20250701123851.1314531-4-jay.buddhabhatti@amd.com
Signed-off-by: Michal Simek <michal.simek@amd.com>

authored by

Jay Buddhabhatti and committed by
Michal Simek
25e3ae0c e66f4c35

+31 -51
+16 -26
drivers/firmware/xilinx/zynqmp.c
··· 473 473 474 474 static u32 pm_api_version; 475 475 static u32 pm_tz_version; 476 - static u32 pm_family_code; 477 - static u32 pm_sub_family_code; 478 476 479 477 int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset) 480 478 { ··· 539 541 /** 540 542 * zynqmp_pm_get_family_info() - Get family info of platform 541 543 * @family: Returned family code value 542 - * @subfamily: Returned sub-family code value 543 544 * 544 545 * Return: Returns status, either success or error+reason 545 546 */ 546 - int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily) 547 + int zynqmp_pm_get_family_info(u32 *family) 547 548 { 548 - u32 ret_payload[PAYLOAD_ARG_CNT]; 549 - u32 idcode; 550 - int ret; 549 + if (!active_platform_fw_data) 550 + return -ENODEV; 551 551 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 - } 552 + if (!family) 553 + return -EINVAL; 558 554 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; 555 + *family = active_platform_fw_data->family_code; 568 556 569 557 return 0; 570 558 } ··· 1231 1247 u32 value) 1232 1248 { 1233 1249 int ret; 1250 + u32 pm_family_code; 1234 1251 1235 - if (pm_family_code == ZYNQMP_FAMILY_CODE && 1252 + ret = zynqmp_pm_get_family_info(&pm_family_code); 1253 + if (ret) 1254 + return ret; 1255 + 1256 + if (pm_family_code == PM_ZYNQMP_FAMILY_CODE && 1236 1257 param == PM_PINCTRL_CONFIG_TRI_STATE) { 1237 1258 ret = zynqmp_pm_feature(PM_PINCTRL_CONFIG_PARAM_SET); 1238 1259 if (ret < PM_PINCTRL_PARAM_SET_VERSION) { ··· 2044 2055 { 2045 2056 struct device *dev = &pdev->dev; 2046 2057 struct zynqmp_devinfo *devinfo; 2058 + u32 pm_family_code; 2047 2059 int ret; 2048 2060 2049 2061 ret = get_set_conduit_method(dev->of_node); ··· 2088 2098 pr_info("%s Platform Management API v%d.%d\n", __func__, 2089 2099 pm_api_version >> 16, pm_api_version & 0xFFFF); 2090 2100 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); 2101 + /* Get the Family code of platform */ 2102 + ret = zynqmp_pm_get_family_info(&pm_family_code); 2093 2103 if (ret < 0) 2094 2104 return ret; 2095 2105 ··· 2116 2126 2117 2127 zynqmp_pm_api_debugfs_init(); 2118 2128 2119 - if (pm_family_code == VERSAL_FAMILY_CODE) { 2129 + if (pm_family_code != PM_ZYNQMP_FAMILY_CODE) { 2120 2130 em_dev = platform_device_register_data(&pdev->dev, "xlnx_event_manager", 2121 2131 -1, NULL, 0); 2122 2132 if (IS_ERR(em_dev))
+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);
+2 -13
include/linux/firmware/xlnx-zynqmp.h
··· 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 54 /* Family codes */ 58 55 #define PM_ZYNQMP_FAMILY_CODE 0x1 /* ZynqMP family code */ 59 56 #define PM_VERSAL_FAMILY_CODE 0x2 /* Versal family code */ 60 57 #define PM_VERSAL_NET_FAMILY_CODE 0x3 /* Versal NET family code */ 61 - 62 - /* When all subfamily of platform need to support */ 63 - #define ALL_SUB_FAMILY_CODE 0x00 64 - #define VERSAL_SUB_FAMILY_CODE 0x01 65 - #define VERSALNET_SUB_FAMILY_CODE 0x03 66 - 67 - #define FAMILY_CODE_MASK GENMASK(27, 21) 68 - #define SUB_FAMILY_CODE_MASK GENMASK(20, 19) 69 58 70 59 #define API_ID_MASK GENMASK(7, 0) 71 60 #define MODULE_ID_MASK GENMASK(11, 8) ··· 559 570 #if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE) 560 571 int zynqmp_pm_get_api_version(u32 *version); 561 572 int zynqmp_pm_get_chipid(u32 *idcode, u32 *version); 562 - int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily); 573 + int zynqmp_pm_get_family_info(u32 *family); 563 574 int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out); 564 575 int zynqmp_pm_clock_enable(u32 clock_id); 565 576 int zynqmp_pm_clock_disable(u32 clock_id); ··· 640 651 return -ENODEV; 641 652 } 642 653 643 - static inline int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily) 654 + static inline int zynqmp_pm_get_family_info(u32 *family) 644 655 { 645 656 return -ENODEV; 646 657 }