121677c5eSRaag Jadav // SPDX-License-Identifier: MIT 221677c5eSRaag Jadav /* 321677c5eSRaag Jadav * Copyright © 2026 Intel Corporation 421677c5eSRaag Jadav */ 521677c5eSRaag Jadav 621677c5eSRaag Jadav #include "xe_device.h" 721677c5eSRaag Jadav #include "xe_irq.h" 821677c5eSRaag Jadav #include "xe_printk.h" 9*d34b42ffSRaag Jadav #include "xe_ras.h" 1021677c5eSRaag Jadav #include "xe_sysctrl.h" 1121677c5eSRaag Jadav #include "xe_sysctrl_event_types.h" 1221677c5eSRaag Jadav #include "xe_sysctrl_mailbox.h" 1321677c5eSRaag Jadav #include "xe_sysctrl_mailbox_types.h" 1421677c5eSRaag Jadav 1521677c5eSRaag Jadav static void get_pending_event(struct xe_sysctrl *sc, struct xe_sysctrl_mailbox_command *command) 1621677c5eSRaag Jadav { 1721677c5eSRaag Jadav struct xe_sysctrl_event_response *response = command->data_out; 1821677c5eSRaag Jadav struct xe_device *xe = sc_to_xe(sc); 1921677c5eSRaag Jadav u32 count = XE_SYSCTRL_EVENT_FLOOD; 2021677c5eSRaag Jadav size_t len; 2121677c5eSRaag Jadav int ret; 2221677c5eSRaag Jadav 2321677c5eSRaag Jadav do { 2421677c5eSRaag Jadav memset(response, 0, sizeof(*response)); 2521677c5eSRaag Jadav 2621677c5eSRaag Jadav ret = xe_sysctrl_send_command(sc, command, &len); 2721677c5eSRaag Jadav if (ret) { 2821677c5eSRaag Jadav xe_err(xe, "sysctrl: failed to get pending event %d\n", ret); 2921677c5eSRaag Jadav return; 3021677c5eSRaag Jadav } 3121677c5eSRaag Jadav 3221677c5eSRaag Jadav if (len != sizeof(*response)) { 3321677c5eSRaag Jadav xe_err(xe, "sysctrl: unexpected event response length %zu (expected %zu)\n", 3421677c5eSRaag Jadav len, sizeof(*response)); 3521677c5eSRaag Jadav return; 3621677c5eSRaag Jadav } 3721677c5eSRaag Jadav 3821677c5eSRaag Jadav if (response->event == XE_SYSCTRL_EVENT_THRESHOLD_CROSSED) 39*d34b42ffSRaag Jadav xe_ras_counter_threshold_crossed(xe, response); 4021677c5eSRaag Jadav else 4121677c5eSRaag Jadav xe_warn(xe, "sysctrl: unexpected event %#x\n", response->event); 4221677c5eSRaag Jadav 4321677c5eSRaag Jadav if (!--count) { 4421677c5eSRaag Jadav xe_err(xe, "sysctrl: event flooding\n"); 4521677c5eSRaag Jadav return; 4621677c5eSRaag Jadav } 4721677c5eSRaag Jadav 4821677c5eSRaag Jadav xe_dbg(xe, "sysctrl: %u events pending\n", response->count); 4921677c5eSRaag Jadav } while (response->count); 5021677c5eSRaag Jadav } 5121677c5eSRaag Jadav 5221677c5eSRaag Jadav static void event_request_prepare(struct xe_device *xe, struct xe_sysctrl_app_msg_hdr *header, 5321677c5eSRaag Jadav struct xe_sysctrl_event_request *request) 5421677c5eSRaag Jadav { 5521677c5eSRaag Jadav struct pci_dev *pdev = to_pci_dev(xe->drm.dev); 5621677c5eSRaag Jadav 5721677c5eSRaag Jadav header->data = REG_FIELD_PREP(APP_HDR_GROUP_ID_MASK, XE_SYSCTRL_GROUP_GFSP) | 5821677c5eSRaag Jadav REG_FIELD_PREP(APP_HDR_COMMAND_MASK, XE_SYSCTRL_CMD_GET_PENDING_EVENT); 5921677c5eSRaag Jadav 6021677c5eSRaag Jadav request->vector = xe_device_has_msix(xe) ? XE_IRQ_DEFAULT_MSIX : 0; 6121677c5eSRaag Jadav request->fn = PCI_FUNC(pdev->devfn); 6221677c5eSRaag Jadav } 6321677c5eSRaag Jadav 6421677c5eSRaag Jadav /** 6521677c5eSRaag Jadav * xe_sysctrl_event() - Handler for System Controller events 6621677c5eSRaag Jadav * @sc: System Controller instance 6721677c5eSRaag Jadav * 6821677c5eSRaag Jadav * Handle events generated by System Controller. 6921677c5eSRaag Jadav */ 7021677c5eSRaag Jadav void xe_sysctrl_event(struct xe_sysctrl *sc) 7121677c5eSRaag Jadav { 7221677c5eSRaag Jadav struct xe_sysctrl_mailbox_command command = {}; 7321677c5eSRaag Jadav struct xe_sysctrl_event_response response = {}; 7421677c5eSRaag Jadav struct xe_sysctrl_event_request request = {}; 7521677c5eSRaag Jadav struct xe_sysctrl_app_msg_hdr header = {}; 7621677c5eSRaag Jadav 7721677c5eSRaag Jadav xe_device_assert_mem_access(sc_to_xe(sc)); 7821677c5eSRaag Jadav event_request_prepare(sc_to_xe(sc), &header, &request); 7921677c5eSRaag Jadav 8021677c5eSRaag Jadav command.header = header; 8121677c5eSRaag Jadav command.data_in = &request; 8221677c5eSRaag Jadav command.data_in_len = sizeof(request); 8321677c5eSRaag Jadav command.data_out = &response; 8421677c5eSRaag Jadav command.data_out_len = sizeof(response); 8521677c5eSRaag Jadav 8621677c5eSRaag Jadav guard(mutex)(&sc->event_lock); 8721677c5eSRaag Jadav get_pending_event(sc, &command); 8821677c5eSRaag Jadav } 89