xref: /linux/drivers/gpu/drm/xe/xe_sysctrl.c (revision 0eaed89c18aeedf0898baf2dbf5ff027c6795152)
15ea3f0dcSAnoop Vijay // SPDX-License-Identifier: MIT
25ea3f0dcSAnoop Vijay /*
35ea3f0dcSAnoop Vijay  * Copyright © 2026 Intel Corporation
45ea3f0dcSAnoop Vijay  */
55ea3f0dcSAnoop Vijay 
65ea3f0dcSAnoop Vijay #include <linux/device.h>
75ea3f0dcSAnoop Vijay #include <linux/mutex.h>
85ea3f0dcSAnoop Vijay 
95ea3f0dcSAnoop Vijay #include <drm/drm_managed.h>
105ea3f0dcSAnoop Vijay 
11a6824737SRaag Jadav #include "regs/xe_irq_regs.h"
125ea3f0dcSAnoop Vijay #include "regs/xe_sysctrl_regs.h"
135ea3f0dcSAnoop Vijay #include "xe_device.h"
145ea3f0dcSAnoop Vijay #include "xe_mmio.h"
15*21677c5eSRaag Jadav #include "xe_pm.h"
165ea3f0dcSAnoop Vijay #include "xe_soc_remapper.h"
175ea3f0dcSAnoop Vijay #include "xe_sysctrl.h"
185ea3f0dcSAnoop Vijay #include "xe_sysctrl_mailbox.h"
195ea3f0dcSAnoop Vijay #include "xe_sysctrl_types.h"
205ea3f0dcSAnoop Vijay 
215ea3f0dcSAnoop Vijay /**
225ea3f0dcSAnoop Vijay  * DOC: System Controller (sysctrl)
235ea3f0dcSAnoop Vijay  *
245ea3f0dcSAnoop Vijay  * System Controller (sysctrl) is a firmware-managed entity on Intel dGPUs
255ea3f0dcSAnoop Vijay  * responsible for selected low-level platform management functions.
265ea3f0dcSAnoop Vijay  * Communication between driver and System Controller is performed
275ea3f0dcSAnoop Vijay  * via a mailbox interface, enabling command and response exchange.
285ea3f0dcSAnoop Vijay  *
295ea3f0dcSAnoop Vijay  * This module provides initialization and support code for interacting
305ea3f0dcSAnoop Vijay  * with System Controller through the mailbox interface.
315ea3f0dcSAnoop Vijay  */
325ea3f0dcSAnoop Vijay static void sysctrl_fini(void *arg)
335ea3f0dcSAnoop Vijay {
345ea3f0dcSAnoop Vijay 	struct xe_device *xe = arg;
35a6824737SRaag Jadav 	struct xe_sysctrl *sc = &xe->sc;
365ea3f0dcSAnoop Vijay 
37a6824737SRaag Jadav 	disable_work_sync(&sc->work);
385ea3f0dcSAnoop Vijay 	xe->soc_remapper.set_sysctrl_region(xe, 0);
395ea3f0dcSAnoop Vijay }
405ea3f0dcSAnoop Vijay 
41a6824737SRaag Jadav static void xe_sysctrl_work(struct work_struct *work)
42a6824737SRaag Jadav {
43*21677c5eSRaag Jadav 	struct xe_sysctrl *sc = container_of(work, struct xe_sysctrl, work);
44*21677c5eSRaag Jadav 	struct xe_device *xe = sc_to_xe(sc);
45*21677c5eSRaag Jadav 
46*21677c5eSRaag Jadav 	guard(xe_pm_runtime)(xe);
47*21677c5eSRaag Jadav 	xe_sysctrl_event(sc);
48a6824737SRaag Jadav }
49a6824737SRaag Jadav 
505ea3f0dcSAnoop Vijay /**
515ea3f0dcSAnoop Vijay  * xe_sysctrl_init() - Initialize System Controller subsystem
525ea3f0dcSAnoop Vijay  * @xe: xe device instance
535ea3f0dcSAnoop Vijay  *
545ea3f0dcSAnoop Vijay  * Entry point for System Controller initialization, called from xe_device_probe.
555ea3f0dcSAnoop Vijay  * This function checks platform support and initializes the system controller.
565ea3f0dcSAnoop Vijay  *
575ea3f0dcSAnoop Vijay  * Return: 0 on success, error code on failure
585ea3f0dcSAnoop Vijay  */
595ea3f0dcSAnoop Vijay int xe_sysctrl_init(struct xe_device *xe)
605ea3f0dcSAnoop Vijay {
615ea3f0dcSAnoop Vijay 	struct xe_tile *tile = xe_device_get_root_tile(xe);
625ea3f0dcSAnoop Vijay 	struct xe_sysctrl *sc = &xe->sc;
635ea3f0dcSAnoop Vijay 	int ret;
645ea3f0dcSAnoop Vijay 
655ea3f0dcSAnoop Vijay 	if (!xe->info.has_soc_remapper_sysctrl)
665ea3f0dcSAnoop Vijay 		return 0;
675ea3f0dcSAnoop Vijay 
685ea3f0dcSAnoop Vijay 	if (!xe->info.has_sysctrl)
695ea3f0dcSAnoop Vijay 		return 0;
705ea3f0dcSAnoop Vijay 
715ea3f0dcSAnoop Vijay 	sc->mmio = devm_kzalloc(xe->drm.dev, sizeof(*sc->mmio), GFP_KERNEL);
725ea3f0dcSAnoop Vijay 	if (!sc->mmio)
735ea3f0dcSAnoop Vijay 		return -ENOMEM;
745ea3f0dcSAnoop Vijay 
755ea3f0dcSAnoop Vijay 	xe_mmio_init(sc->mmio, tile, tile->mmio.regs, tile->mmio.regs_size);
765ea3f0dcSAnoop Vijay 	sc->mmio->adj_offset = SYSCTRL_BASE;
775ea3f0dcSAnoop Vijay 	sc->mmio->adj_limit = U32_MAX;
785ea3f0dcSAnoop Vijay 
795ea3f0dcSAnoop Vijay 	ret = devm_mutex_init(xe->drm.dev, &sc->cmd_lock);
805ea3f0dcSAnoop Vijay 	if (ret)
815ea3f0dcSAnoop Vijay 		return ret;
825ea3f0dcSAnoop Vijay 
83*21677c5eSRaag Jadav 	ret = devm_mutex_init(xe->drm.dev, &sc->event_lock);
84*21677c5eSRaag Jadav 	if (ret)
85*21677c5eSRaag Jadav 		return ret;
86*21677c5eSRaag Jadav 
87a6824737SRaag Jadav 	xe->soc_remapper.set_sysctrl_region(xe, SYSCTRL_MAILBOX_INDEX);
881f95f618SAnoop Vijay 	xe_sysctrl_mailbox_init(sc);
89a6824737SRaag Jadav 	INIT_WORK(&sc->work, xe_sysctrl_work);
901f95f618SAnoop Vijay 
91a6824737SRaag Jadav 	return devm_add_action_or_reset(xe->drm.dev, sysctrl_fini, xe);
92a6824737SRaag Jadav }
93a6824737SRaag Jadav 
94a6824737SRaag Jadav /**
95a6824737SRaag Jadav  * xe_sysctrl_irq_handler() - Handler for System Controller interrupts
96a6824737SRaag Jadav  * @xe: xe device instance
97a6824737SRaag Jadav  * @master_ctl: interrupt register
98a6824737SRaag Jadav  *
99a6824737SRaag Jadav  * Handle interrupts generated by System Controller.
100a6824737SRaag Jadav  */
101a6824737SRaag Jadav void xe_sysctrl_irq_handler(struct xe_device *xe, u32 master_ctl)
102a6824737SRaag Jadav {
103a6824737SRaag Jadav 	struct xe_sysctrl *sc = &xe->sc;
104a6824737SRaag Jadav 
105a6824737SRaag Jadav 	if (!xe->info.has_sysctrl || !sc->work.func)
106a6824737SRaag Jadav 		return;
107a6824737SRaag Jadav 
108a6824737SRaag Jadav 	if (master_ctl & SYSCTRL_IRQ)
109a6824737SRaag Jadav 		schedule_work(&sc->work);
1105ea3f0dcSAnoop Vijay }
11102eca6edSAnoop Vijay 
11202eca6edSAnoop Vijay /**
11302eca6edSAnoop Vijay  * xe_sysctrl_pm_resume() - System Controller resume handler
11402eca6edSAnoop Vijay  * @xe: xe device instance
11502eca6edSAnoop Vijay  *
11602eca6edSAnoop Vijay  * Invoked during system resume (S3/S4 to S0) and runtime resume from D3cold.
11702eca6edSAnoop Vijay  * Restores SoC remapper configuration and reinitializes mailbox interface.
11802eca6edSAnoop Vijay  */
11902eca6edSAnoop Vijay void xe_sysctrl_pm_resume(struct xe_device *xe)
12002eca6edSAnoop Vijay {
12102eca6edSAnoop Vijay 	struct xe_sysctrl *sc = &xe->sc;
12202eca6edSAnoop Vijay 
12302eca6edSAnoop Vijay 	if (!xe->info.has_soc_remapper_sysctrl)
12402eca6edSAnoop Vijay 		return;
12502eca6edSAnoop Vijay 
12602eca6edSAnoop Vijay 	if (!xe->info.has_sysctrl)
12702eca6edSAnoop Vijay 		return;
12802eca6edSAnoop Vijay 
12902eca6edSAnoop Vijay 	xe->soc_remapper.set_sysctrl_region(xe, SYSCTRL_MAILBOX_INDEX);
13002eca6edSAnoop Vijay 
13102eca6edSAnoop Vijay 	xe_sysctrl_mailbox_init(sc);
13202eca6edSAnoop Vijay }
133