projects/linux·blob master · refs

88 lines · 2.4 KiB

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
15static 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_FLOOD_LIMIT;
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
52static 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 */
70void 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}