drm/xe/sysctrl: Add system controller event support

System controller reports different types of events to GFX endpoint for
different usecases, add initial support for them. This will be further
extended to service those usecases.

Signed-off-by: Raag Jadav <raag.jadav@intel.com>
Reviewed-by: Mallesh Koujalagi <mallesh.koujalagi@intel.com>
Link: https://patch.msgid.link/20260428054826.1202076-3-raag.jadav@intel.com
Signed-off-by: Riana Tauro <riana.tauro@intel.com>
This commit is contained in:
Raag Jadav 2026-04-28 11:18:25 +05:30 committed by Riana Tauro
parent a68247371b
commit 21677c5ea9
7 changed files with 177 additions and 0 deletions

View File

@ -125,6 +125,7 @@ xe-y += xe_bb.o \
xe_survivability_mode.o \
xe_sync.o \
xe_sysctrl.o \
xe_sysctrl_event.o \
xe_sysctrl_mailbox.o \
xe_tile.o \
xe_tile_sysfs.o \

View File

@ -12,6 +12,7 @@
#include "regs/xe_sysctrl_regs.h"
#include "xe_device.h"
#include "xe_mmio.h"
#include "xe_pm.h"
#include "xe_soc_remapper.h"
#include "xe_sysctrl.h"
#include "xe_sysctrl_mailbox.h"
@ -39,6 +40,11 @@ static void sysctrl_fini(void *arg)
static void xe_sysctrl_work(struct work_struct *work)
{
struct xe_sysctrl *sc = container_of(work, struct xe_sysctrl, work);
struct xe_device *xe = sc_to_xe(sc);
guard(xe_pm_runtime)(xe);
xe_sysctrl_event(sc);
}
/**
@ -74,6 +80,10 @@ int xe_sysctrl_init(struct xe_device *xe)
if (ret)
return ret;
ret = devm_mutex_init(xe->drm.dev, &sc->event_lock);
if (ret)
return ret;
xe->soc_remapper.set_sysctrl_region(xe, SYSCTRL_MAILBOX_INDEX);
xe_sysctrl_mailbox_init(sc);
INIT_WORK(&sc->work, xe_sysctrl_work);

View File

@ -16,6 +16,7 @@ static inline struct xe_device *sc_to_xe(struct xe_sysctrl *sc)
return container_of(sc, struct xe_device, sc);
}
void xe_sysctrl_event(struct xe_sysctrl *sc);
int xe_sysctrl_init(struct xe_device *xe);
void xe_sysctrl_irq_handler(struct xe_device *xe, u32 master_ctl);
void xe_sysctrl_pm_resume(struct xe_device *xe);

View File

@ -0,0 +1,87 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2026 Intel Corporation
*/
#include "xe_device.h"
#include "xe_irq.h"
#include "xe_printk.h"
#include "xe_sysctrl.h"
#include "xe_sysctrl_event_types.h"
#include "xe_sysctrl_mailbox.h"
#include "xe_sysctrl_mailbox_types.h"
static void get_pending_event(struct xe_sysctrl *sc, struct xe_sysctrl_mailbox_command *command)
{
struct xe_sysctrl_event_response *response = command->data_out;
struct xe_device *xe = sc_to_xe(sc);
u32 count = XE_SYSCTRL_EVENT_FLOOD;
size_t len;
int ret;
do {
memset(response, 0, sizeof(*response));
ret = xe_sysctrl_send_command(sc, command, &len);
if (ret) {
xe_err(xe, "sysctrl: failed to get pending event %d\n", ret);
return;
}
if (len != sizeof(*response)) {
xe_err(xe, "sysctrl: unexpected event response length %zu (expected %zu)\n",
len, sizeof(*response));
return;
}
if (response->event == XE_SYSCTRL_EVENT_THRESHOLD_CROSSED)
xe_warn(xe, "[RAS]: counter threshold crossed\n");
else
xe_warn(xe, "sysctrl: unexpected event %#x\n", response->event);
if (!--count) {
xe_err(xe, "sysctrl: event flooding\n");
return;
}
xe_dbg(xe, "sysctrl: %u events pending\n", response->count);
} while (response->count);
}
static void event_request_prepare(struct xe_device *xe, struct xe_sysctrl_app_msg_hdr *header,
struct xe_sysctrl_event_request *request)
{
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
header->data = REG_FIELD_PREP(APP_HDR_GROUP_ID_MASK, XE_SYSCTRL_GROUP_GFSP) |
REG_FIELD_PREP(APP_HDR_COMMAND_MASK, XE_SYSCTRL_CMD_GET_PENDING_EVENT);
request->vector = xe_device_has_msix(xe) ? XE_IRQ_DEFAULT_MSIX : 0;
request->fn = PCI_FUNC(pdev->devfn);
}
/**
* xe_sysctrl_event() - Handler for System Controller events
* @sc: System Controller instance
*
* Handle events generated by System Controller.
*/
void xe_sysctrl_event(struct xe_sysctrl *sc)
{
struct xe_sysctrl_mailbox_command command = {};
struct xe_sysctrl_event_response response = {};
struct xe_sysctrl_event_request request = {};
struct xe_sysctrl_app_msg_hdr header = {};
xe_device_assert_mem_access(sc_to_xe(sc));
event_request_prepare(sc_to_xe(sc), &header, &request);
command.header = header;
command.data_in = &request;
command.data_in_len = sizeof(request);
command.data_out = &response;
command.data_out_len = sizeof(response);
guard(mutex)(&sc->event_lock);
get_pending_event(sc, &command);
}

View File

@ -0,0 +1,57 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2026 Intel Corporation
*/
#ifndef _XE_SYSCTRL_EVENT_TYPES_H_
#define _XE_SYSCTRL_EVENT_TYPES_H_
#include <linux/types.h>
#define XE_SYSCTRL_EVENT_DATA_LEN 59
/* Modify as needed */
#define XE_SYSCTRL_EVENT_FLOOD 16
/**
* enum xe_sysctrl_event - Events reported by System Controller
*
* @XE_SYSCTRL_EVENT_THRESHOLD_CROSSED: Error counter threshold crossed
*/
enum xe_sysctrl_event {
XE_SYSCTRL_EVENT_THRESHOLD_CROSSED = 0x01,
};
/**
* struct xe_sysctrl_event_request - Request structure for pending event
*/
struct xe_sysctrl_event_request {
/** @vector: MSI-X vector that was triggered */
u32 vector;
/** @fn: Function index (0-7) of PCIe device */
u32 fn:8;
/** @reserved: Reserved for future use */
u32 reserved:24;
/** @reserved1: Reserved for future use */
u32 reserved1[2];
} __packed;
/**
* struct xe_sysctrl_event_response - Response structure for pending event
*/
struct xe_sysctrl_event_response {
/** @count: Pending event count after this response */
u32 count;
/** @event: Pending event type */
u32 event;
/** @timestamp: Timestamp of most recent event */
u64 timestamp;
/** @extended: Event has extended payload */
u32 extended:1;
/** @reserved: Reserved for future use */
u32 reserved:31;
/** @data: Generic event data */
u32 data[XE_SYSCTRL_EVENT_DATA_LEN];
} __packed;
#endif /* _XE_SYSCTRL_EVENT_TYPES_H_ */

View File

@ -10,6 +10,24 @@
#include "abi/xe_sysctrl_abi.h"
/**
* enum xe_sysctrl_group - System Controller command groups
*
* @XE_SYSCTRL_GROUP_GFSP: GFSP group
*/
enum xe_sysctrl_group {
XE_SYSCTRL_GROUP_GFSP = 0x01,
};
/**
* enum xe_sysctrl_gfsp_cmd - Commands supported by GFSP group
*
* @XE_SYSCTRL_CMD_GET_PENDING_EVENT: Retrieve pending event
*/
enum xe_sysctrl_gfsp_cmd {
XE_SYSCTRL_CMD_GET_PENDING_EVENT = 0x07,
};
/**
* struct xe_sysctrl_mailbox_command - System Controller mailbox command
*/

View File

@ -31,6 +31,9 @@ struct xe_sysctrl {
/** @work: Pending events worker */
struct work_struct work;
/** @event_lock: Mutex protecting pending events */
struct mutex event_lock;
};
#endif