Files
Anoop Vijay a62212b35a drm/xe/sysctrl: Read mailbox phase bit from hardware
The mailbox PHASE bit in SYSCTRL_MB_CTRL is toggled per-message and
was tracked in software as sc->phase_bit, reset to 0 on error paths.
If the cached value ever drifts from what the hardware last saw, all
following messages carry the wrong phase and get silently misread by
firmware.

Drop the cache and read PHASE directly from SYSCTRL_MB_CTRL before
each frame instead, removing xe_sysctrl_mailbox_init() and its call
sites along with it.

Fixes: 1f95f61818 ("drm/xe/xe_sysctrl: Add System Controller mailbox communication support")
Signed-off-by: Anoop Vijay <[email protected]>
Reviewed-by: Umesh Nerlige Ramappa <[email protected]>
Reviewed-by: Rodrigo Vivi <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Rodrigo Vivi <[email protected]>
(cherry picked from commit 04984fcdbf6876c940c01026a7404c1e9cc91ba7)
Signed-off-by: Rodrigo Vivi <[email protected]>
2026-08-27 12:00:17 -04:00

128 lines
3.2 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);
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.
*/
void xe_sysctrl_pm_resume(struct xe_device *xe)
{
if (!xe->info.has_soc_remapper_sysctrl)
return;
if (!xe->info.has_sysctrl)
return;
xe->soc_remapper.set_sysctrl_region(xe, SYSCTRL_MAILBOX_INDEX);
}