1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2026 Intel Corporation 4 */ 5 6 #include <linux/device.h> 7 #include <linux/mutex.h> 8 9 #include <drm/drm_managed.h> 10 11 #include "regs/xe_irq_regs.h" 12 #include "regs/xe_sysctrl_regs.h" 13 #include "xe_device.h" 14 #include "xe_mmio.h" 15 #include "xe_soc_remapper.h" 16 #include "xe_sysctrl.h" 17 #include "xe_sysctrl_mailbox.h" 18 #include "xe_sysctrl_types.h" 19 20 /** 21 * DOC: System Controller (sysctrl) 22 * 23 * System Controller (sysctrl) is a firmware-managed entity on Intel dGPUs 24 * responsible for selected low-level platform management functions. 25 * Communication between driver and System Controller is performed 26 * via a mailbox interface, enabling command and response exchange. 27 * 28 * This module provides initialization and support code for interacting 29 * with System Controller through the mailbox interface. 30 */ 31 static void sysctrl_fini(void *arg) 32 { 33 struct xe_device *xe = arg; 34 struct xe_sysctrl *sc = &xe->sc; 35 36 disable_work_sync(&sc->work); 37 xe->soc_remapper.set_sysctrl_region(xe, 0); 38 } 39 40 static void xe_sysctrl_work(struct work_struct *work) 41 { 42 } 43 44 /** 45 * xe_sysctrl_init() - Initialize System Controller subsystem 46 * @xe: xe device instance 47 * 48 * Entry point for System Controller initialization, called from xe_device_probe. 49 * This function checks platform support and initializes the system controller. 50 * 51 * Return: 0 on success, error code on failure 52 */ 53 int xe_sysctrl_init(struct xe_device *xe) 54 { 55 struct xe_tile *tile = xe_device_get_root_tile(xe); 56 struct xe_sysctrl *sc = &xe->sc; 57 int ret; 58 59 if (!xe->info.has_soc_remapper_sysctrl) 60 return 0; 61 62 if (!xe->info.has_sysctrl) 63 return 0; 64 65 sc->mmio = devm_kzalloc(xe->drm.dev, sizeof(*sc->mmio), GFP_KERNEL); 66 if (!sc->mmio) 67 return -ENOMEM; 68 69 xe_mmio_init(sc->mmio, tile, tile->mmio.regs, tile->mmio.regs_size); 70 sc->mmio->adj_offset = SYSCTRL_BASE; 71 sc->mmio->adj_limit = U32_MAX; 72 73 ret = devm_mutex_init(xe->drm.dev, &sc->cmd_lock); 74 if (ret) 75 return ret; 76 77 xe->soc_remapper.set_sysctrl_region(xe, SYSCTRL_MAILBOX_INDEX); 78 xe_sysctrl_mailbox_init(sc); 79 INIT_WORK(&sc->work, xe_sysctrl_work); 80 81 return devm_add_action_or_reset(xe->drm.dev, sysctrl_fini, xe); 82 } 83 84 /** 85 * xe_sysctrl_irq_handler() - Handler for System Controller interrupts 86 * @xe: xe device instance 87 * @master_ctl: interrupt register 88 * 89 * Handle interrupts generated by System Controller. 90 */ 91 void xe_sysctrl_irq_handler(struct xe_device *xe, u32 master_ctl) 92 { 93 struct xe_sysctrl *sc = &xe->sc; 94 95 if (!xe->info.has_sysctrl || !sc->work.func) 96 return; 97 98 if (master_ctl & SYSCTRL_IRQ) 99 schedule_work(&sc->work); 100 } 101 102 /** 103 * xe_sysctrl_pm_resume() - System Controller resume handler 104 * @xe: xe device instance 105 * 106 * Invoked during system resume (S3/S4 to S0) and runtime resume from D3cold. 107 * Restores SoC remapper configuration and reinitializes mailbox interface. 108 */ 109 void xe_sysctrl_pm_resume(struct xe_device *xe) 110 { 111 struct xe_sysctrl *sc = &xe->sc; 112 113 if (!xe->info.has_soc_remapper_sysctrl) 114 return; 115 116 if (!xe->info.has_sysctrl) 117 return; 118 119 xe->soc_remapper.set_sysctrl_region(xe, SYSCTRL_MAILBOX_INDEX); 120 121 xe_sysctrl_mailbox_init(sc); 122 } 123