xref: /linux/drivers/gpu/drm/xe/xe_sysctrl_event.c (revision 0eaed89c18aeedf0898baf2dbf5ff027c6795152)
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