linux/drivers/gpu/drm/xe/xe_sysctrl.c
Raag Jadav 21677c5ea9 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>
2026-04-30 11:31:45 +05:30

133 lines
3.3 KiB
C

// 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);
}