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