summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/xe/xe_sysctrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/xe/xe_sysctrl.c')
-rw-r--r--drivers/gpu/drm/xe/xe_sysctrl.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/drivers/gpu/drm/xe/xe_sysctrl.c b/drivers/gpu/drm/xe/xe_sysctrl.c
new file mode 100644
index 000000000000..1db20be8158b
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_sysctrl.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/mutex.h>
+
+#include <drm/drm_managed.h>
+
+#include "regs/xe_irq_regs.h"
+#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"
+#include "xe_sysctrl_types.h"
+
+/**
+ * DOC: System Controller (sysctrl)
+ *
+ * System Controller (sysctrl) is a firmware-managed entity on Intel dGPUs
+ * responsible for selected low-level platform management functions.
+ * Communication between driver and System Controller is performed
+ * via a mailbox interface, enabling command and response exchange.
+ *
+ * This module provides initialization and support code for interacting
+ * with System Controller through the mailbox interface.
+ */
+static void sysctrl_fini(void *arg)
+{
+ struct xe_device *xe = arg;
+ struct xe_sysctrl *sc = &xe->sc;
+
+ disable_work_sync(&sc->work);
+ xe->soc_remapper.set_sysctrl_region(xe, 0);
+}
+
+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);
+}
+
+/**
+ * xe_sysctrl_init() - Initialize System Controller subsystem
+ * @xe: xe device instance
+ *
+ * Entry point for System Controller initialization, called from xe_device_probe.
+ * This function checks platform support and initializes the system controller.
+ *
+ * Return: 0 on success, error code on failure
+ */
+int xe_sysctrl_init(struct xe_device *xe)
+{
+ struct xe_tile *tile = xe_device_get_root_tile(xe);
+ struct xe_sysctrl *sc = &xe->sc;
+ int ret;
+
+ if (!xe->info.has_soc_remapper_sysctrl)
+ return 0;
+
+ if (!xe->info.has_sysctrl)
+ return 0;
+
+ sc->mmio = devm_kzalloc(xe->drm.dev, sizeof(*sc->mmio), GFP_KERNEL);
+ if (!sc->mmio)
+ return -ENOMEM;
+
+ xe_mmio_init(sc->mmio, tile, tile->mmio.regs, tile->mmio.regs_size);
+ sc->mmio->adj_offset = SYSCTRL_BASE;
+ sc->mmio->adj_limit = U32_MAX;
+
+ ret = devm_mutex_init(xe->drm.dev, &sc->cmd_lock);
+ 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);
+
+ return devm_add_action_or_reset(xe->drm.dev, sysctrl_fini, xe);
+}
+
+/**
+ * xe_sysctrl_irq_handler() - Handler for System Controller interrupts
+ * @xe: xe device instance
+ * @master_ctl: interrupt register
+ *
+ * Handle interrupts generated by System Controller.
+ */
+void xe_sysctrl_irq_handler(struct xe_device *xe, u32 master_ctl)
+{
+ struct xe_sysctrl *sc = &xe->sc;
+
+ if (!xe->info.has_sysctrl || !sc->work.func)
+ return;
+
+ if (master_ctl & SYSCTRL_IRQ)
+ schedule_work(&sc->work);
+}
+
+/**
+ * xe_sysctrl_pm_resume() - System Controller resume handler
+ * @xe: xe device instance
+ *
+ * Invoked during system resume (S3/S4 to S0) and runtime resume from D3cold.
+ * Restores SoC remapper configuration and reinitializes mailbox interface.
+ */
+void xe_sysctrl_pm_resume(struct xe_device *xe)
+{
+ struct xe_sysctrl *sc = &xe->sc;
+
+ if (!xe->info.has_soc_remapper_sysctrl)
+ return;
+
+ if (!xe->info.has_sysctrl)
+ return;
+
+ xe->soc_remapper.set_sysctrl_region(xe, SYSCTRL_MAILBOX_INDEX);
+
+ xe_sysctrl_mailbox_init(sc);
+}