1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2026 Intel Corporation 4 */ 5 6 #include "xe_device.h" 7 #include "xe_irq.h" 8 #include "xe_printk.h" 9 #include "xe_sysctrl.h" 10 #include "xe_sysctrl_event_types.h" 11 #include "xe_sysctrl_mailbox.h" 12 #include "xe_sysctrl_mailbox_types.h" 13 14 static void get_pending_event(struct xe_sysctrl *sc, struct xe_sysctrl_mailbox_command *command) 15 { 16 struct xe_sysctrl_event_response *response = command->data_out; 17 struct xe_device *xe = sc_to_xe(sc); 18 u32 count = XE_SYSCTRL_EVENT_FLOOD; 19 size_t len; 20 int ret; 21 22 do { 23 memset(response, 0, sizeof(*response)); 24 25 ret = xe_sysctrl_send_command(sc, command, &len); 26 if (ret) { 27 xe_err(xe, "sysctrl: failed to get pending event %d\n", ret); 28 return; 29 } 30 31 if (len != sizeof(*response)) { 32 xe_err(xe, "sysctrl: unexpected event response length %zu (expected %zu)\n", 33 len, sizeof(*response)); 34 return; 35 } 36 37 if (response->event == XE_SYSCTRL_EVENT_THRESHOLD_CROSSED) 38 xe_warn(xe, "[RAS]: counter threshold crossed\n"); 39 else 40 xe_warn(xe, "sysctrl: unexpected event %#x\n", response->event); 41 42 if (!--count) { 43 xe_err(xe, "sysctrl: event flooding\n"); 44 return; 45 } 46 47 xe_dbg(xe, "sysctrl: %u events pending\n", response->count); 48 } while (response->count); 49 } 50 51 static void event_request_prepare(struct xe_device *xe, struct xe_sysctrl_app_msg_hdr *header, 52 struct xe_sysctrl_event_request *request) 53 { 54 struct pci_dev *pdev = to_pci_dev(xe->drm.dev); 55 56 header->data = REG_FIELD_PREP(APP_HDR_GROUP_ID_MASK, XE_SYSCTRL_GROUP_GFSP) | 57 REG_FIELD_PREP(APP_HDR_COMMAND_MASK, XE_SYSCTRL_CMD_GET_PENDING_EVENT); 58 59 request->vector = xe_device_has_msix(xe) ? XE_IRQ_DEFAULT_MSIX : 0; 60 request->fn = PCI_FUNC(pdev->devfn); 61 } 62 63 /** 64 * xe_sysctrl_event() - Handler for System Controller events 65 * @sc: System Controller instance 66 * 67 * Handle events generated by System Controller. 68 */ 69 void xe_sysctrl_event(struct xe_sysctrl *sc) 70 { 71 struct xe_sysctrl_mailbox_command command = {}; 72 struct xe_sysctrl_event_response response = {}; 73 struct xe_sysctrl_event_request request = {}; 74 struct xe_sysctrl_app_msg_hdr header = {}; 75 76 xe_device_assert_mem_access(sc_to_xe(sc)); 77 event_request_prepare(sc_to_xe(sc), &header, &request); 78 79 command.header = header; 80 command.data_in = &request; 81 command.data_in_len = sizeof(request); 82 command.data_out = &response; 83 command.data_out_len = sizeof(response); 84 85 guard(mutex)(&sc->event_lock); 86 get_pending_event(sc, &command); 87 } 88