summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/panthor
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
commit8f9aa2c90530ab92301a82231ae44f3722becd93 (patch)
treefb282e955b0a880b07131a135257fe3ec764e928 /drivers/gpu/drm/panthor
parent93467b31bec6da512b51544e5e4584f2745e995e (diff)
parent155b42bec9cbb6b8cdc47dd9bd09503a81fbe493 (diff)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu/drm/panthor')
-rw-r--r--drivers/gpu/drm/panthor/panthor_device.c9
-rw-r--r--drivers/gpu/drm/panthor/panthor_device.h100
-rw-r--r--drivers/gpu/drm/panthor/panthor_drv.c8
-rw-r--r--drivers/gpu/drm/panthor/panthor_fw.c29
-rw-r--r--drivers/gpu/drm/panthor/panthor_fw_regs.h32
-rw-r--r--drivers/gpu/drm/panthor/panthor_gpu.c50
-rw-r--r--drivers/gpu/drm/panthor/panthor_gpu_regs.h123
-rw-r--r--drivers/gpu/drm/panthor/panthor_heap.c2
-rw-r--r--drivers/gpu/drm/panthor/panthor_hw.c50
-rw-r--r--drivers/gpu/drm/panthor/panthor_hw.h2
-rw-r--r--drivers/gpu/drm/panthor/panthor_mmu.c37
-rw-r--r--drivers/gpu/drm/panthor/panthor_mmu_regs.h73
-rw-r--r--drivers/gpu/drm/panthor/panthor_pwr.c73
-rw-r--r--drivers/gpu/drm/panthor/panthor_pwr_regs.h83
-rw-r--r--drivers/gpu/drm/panthor/panthor_regs.h291
-rw-r--r--drivers/gpu/drm/panthor/panthor_sched.c111
16 files changed, 568 insertions, 505 deletions
diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
index 54fbb1aa07c5..4f522a912d89 100644
--- a/drivers/gpu/drm/panthor/panthor_device.c
+++ b/drivers/gpu/drm/panthor/panthor_device.c
@@ -18,12 +18,13 @@
#include "panthor_devfreq.h"
#include "panthor_device.h"
#include "panthor_fw.h"
+#include "panthor_fw_regs.h"
#include "panthor_gem.h"
#include "panthor_gpu.h"
+#include "panthor_gpu_regs.h"
#include "panthor_hw.h"
#include "panthor_mmu.h"
#include "panthor_pwr.h"
-#include "panthor_regs.h"
#include "panthor_sched.h"
static int panthor_gpu_coherency_init(struct panthor_device *ptdev)
@@ -42,7 +43,7 @@ static int panthor_gpu_coherency_init(struct panthor_device *ptdev)
/* Check if the ACE-Lite coherency protocol is actually supported by the GPU.
* ACE protocol has never been supported for command stream frontend GPUs.
*/
- if ((gpu_read(ptdev, GPU_COHERENCY_FEATURES) &
+ if ((gpu_read(ptdev->iomem, GPU_COHERENCY_FEATURES) &
GPU_COHERENCY_PROT_BIT(ACE_LITE))) {
ptdev->gpu_info.selected_coherency = GPU_COHERENCY_ACE_LITE;
return 0;
@@ -231,6 +232,7 @@ int panthor_device_init(struct panthor_device *ptdev)
*dummy_page_virt = 1;
INIT_WORK(&ptdev->reset.work, panthor_device_reset_work);
+ disable_work(&ptdev->reset.work);
ptdev->reset.wq = alloc_ordered_workqueue("panthor-reset-wq", 0);
if (!ptdev->reset.wq)
return -ENOMEM;
@@ -305,6 +307,9 @@ int panthor_device_init(struct panthor_device *ptdev)
panthor_gem_init(ptdev);
+ /* Now that everything is initialized, we can enable the reset work. */
+ enable_work(&ptdev->reset.work);
+
/* ~3 frames */
pm_runtime_set_autosuspend_delay(ptdev->base.dev, 50);
pm_runtime_use_autosuspend(ptdev->base.dev);
diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h
index b6696f73a536..724b4aeaf23e 100644
--- a/drivers/gpu/drm/panthor/panthor_device.h
+++ b/drivers/gpu/drm/panthor/panthor_device.h
@@ -81,6 +81,9 @@ struct panthor_irq {
/** @ptdev: Panthor device */
struct panthor_device *ptdev;
+ /** @iomem: CPU mapping of IRQ base address */
+ void __iomem *iomem;
+
/** @irq: IRQ number. */
int irq;
@@ -415,6 +418,11 @@ panthor_exception_is_fault(u32 exception_code)
const char *panthor_exception_name(struct panthor_device *ptdev,
u32 exception_code);
+#define INT_RAWSTAT 0x0
+#define INT_CLEAR 0x4
+#define INT_MASK 0x8
+#define INT_STAT 0xc
+
/**
* PANTHOR_IRQ_HANDLER() - Define interrupt handlers and the interrupt
* registration function.
@@ -425,16 +433,12 @@ const char *panthor_exception_name(struct panthor_device *ptdev,
*
* void (*handler)(struct panthor_device *, u32 status);
*/
-#define PANTHOR_IRQ_HANDLER(__name, __reg_prefix, __handler) \
+#define PANTHOR_IRQ_HANDLER(__name, __handler) \
static irqreturn_t panthor_ ## __name ## _irq_raw_handler(int irq, void *data) \
{ \
struct panthor_irq *pirq = data; \
- struct panthor_device *ptdev = pirq->ptdev; \
enum panthor_irq_state old_state; \
\
- if (!gpu_read(ptdev, __reg_prefix ## _INT_STAT)) \
- return IRQ_NONE; \
- \
guard(spinlock_irqsave)(&pirq->mask_lock); \
old_state = atomic_cmpxchg(&pirq->state, \
PANTHOR_IRQ_STATE_ACTIVE, \
@@ -442,7 +446,14 @@ static irqreturn_t panthor_ ## __name ## _irq_raw_handler(int irq, void *data)
if (old_state != PANTHOR_IRQ_STATE_ACTIVE) \
return IRQ_NONE; \
\
- gpu_write(ptdev, __reg_prefix ## _INT_MASK, 0); \
+ if (!gpu_read(pirq->iomem, INT_STAT)) { \
+ atomic_cmpxchg(&pirq->state, \
+ PANTHOR_IRQ_STATE_PROCESSING, \
+ PANTHOR_IRQ_STATE_ACTIVE); \
+ return IRQ_NONE; \
+ } \
+ \
+ gpu_write(pirq->iomem, INT_MASK, 0); \
return IRQ_WAKE_THREAD; \
} \
\
@@ -461,7 +472,7 @@ static irqreturn_t panthor_ ## __name ## _irq_threaded_handler(int irq, void *da
* right before the HW event kicks in. TLDR; it's all expected races we're \
* covered for. \
*/ \
- u32 status = gpu_read(ptdev, __reg_prefix ## _INT_RAWSTAT) & pirq->mask; \
+ u32 status = gpu_read(pirq->iomem, INT_RAWSTAT) & pirq->mask; \
\
if (!status) \
break; \
@@ -477,7 +488,7 @@ static irqreturn_t panthor_ ## __name ## _irq_threaded_handler(int irq, void *da
PANTHOR_IRQ_STATE_PROCESSING, \
PANTHOR_IRQ_STATE_ACTIVE); \
if (old_state == PANTHOR_IRQ_STATE_PROCESSING) \
- gpu_write(ptdev, __reg_prefix ## _INT_MASK, pirq->mask); \
+ gpu_write(pirq->iomem, INT_MASK, pirq->mask); \
} \
\
return ret; \
@@ -487,7 +498,7 @@ static inline void panthor_ ## __name ## _irq_suspend(struct panthor_irq *pirq)
{ \
scoped_guard(spinlock_irqsave, &pirq->mask_lock) { \
atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDING); \
- gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, 0); \
+ gpu_write(pirq->iomem, INT_MASK, 0); \
} \
synchronize_irq(pirq->irq); \
atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDED); \
@@ -498,17 +509,18 @@ static inline void panthor_ ## __name ## _irq_resume(struct panthor_irq *pirq)
guard(spinlock_irqsave)(&pirq->mask_lock); \
\
atomic_set(&pirq->state, PANTHOR_IRQ_STATE_ACTIVE); \
- gpu_write(pirq->ptdev, __reg_prefix ## _INT_CLEAR, pirq->mask); \
- gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, pirq->mask); \
+ gpu_write(pirq->iomem, INT_CLEAR, pirq->mask); \
+ gpu_write(pirq->iomem, INT_MASK, pirq->mask); \
} \
\
static int panthor_request_ ## __name ## _irq(struct panthor_device *ptdev, \
struct panthor_irq *pirq, \
- int irq, u32 mask) \
+ int irq, u32 mask, void __iomem *iomem) \
{ \
pirq->ptdev = ptdev; \
pirq->irq = irq; \
pirq->mask = mask; \
+ pirq->iomem = iomem; \
spin_lock_init(&pirq->mask_lock); \
panthor_ ## __name ## _irq_resume(pirq); \
\
@@ -530,7 +542,7 @@ static inline void panthor_ ## __name ## _irq_enable_events(struct panthor_irq *
* If the IRQ is suspended/suspending, the mask is restored at resume time. \
*/ \
if (atomic_read(&pirq->state) == PANTHOR_IRQ_STATE_ACTIVE) \
- gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, pirq->mask); \
+ gpu_write(pirq->iomem, INT_MASK, pirq->mask); \
} \
\
static inline void panthor_ ## __name ## _irq_disable_events(struct panthor_irq *pirq, u32 mask)\
@@ -544,80 +556,80 @@ static inline void panthor_ ## __name ## _irq_disable_events(struct panthor_irq
* If the IRQ is suspended/suspending, the mask is restored at resume time. \
*/ \
if (atomic_read(&pirq->state) == PANTHOR_IRQ_STATE_ACTIVE) \
- gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, pirq->mask); \
+ gpu_write(pirq->iomem, INT_MASK, pirq->mask); \
}
extern struct workqueue_struct *panthor_cleanup_wq;
-static inline void gpu_write(struct panthor_device *ptdev, u32 reg, u32 data)
+static inline void gpu_write(void __iomem *iomem, u32 reg, u32 data)
{
- writel(data, ptdev->iomem + reg);
+ writel(data, iomem + reg);
}
-static inline u32 gpu_read(struct panthor_device *ptdev, u32 reg)
+static inline u32 gpu_read(void __iomem *iomem, u32 reg)
{
- return readl(ptdev->iomem + reg);
+ return readl(iomem + reg);
}
-static inline u32 gpu_read_relaxed(struct panthor_device *ptdev, u32 reg)
+static inline u32 gpu_read_relaxed(void __iomem *iomem, u32 reg)
{
- return readl_relaxed(ptdev->iomem + reg);
+ return readl_relaxed(iomem + reg);
}
-static inline void gpu_write64(struct panthor_device *ptdev, u32 reg, u64 data)
+static inline void gpu_write64(void __iomem *iomem, u32 reg, u64 data)
{
- gpu_write(ptdev, reg, lower_32_bits(data));
- gpu_write(ptdev, reg + 4, upper_32_bits(data));
+ gpu_write(iomem, reg, lower_32_bits(data));
+ gpu_write(iomem, reg + 4, upper_32_bits(data));
}
-static inline u64 gpu_read64(struct panthor_device *ptdev, u32 reg)
+static inline u64 gpu_read64(void __iomem *iomem, u32 reg)
{
- return (gpu_read(ptdev, reg) | ((u64)gpu_read(ptdev, reg + 4) << 32));
+ return (gpu_read(iomem, reg) | ((u64)gpu_read(iomem, reg + 4) << 32));
}
-static inline u64 gpu_read64_relaxed(struct panthor_device *ptdev, u32 reg)
+static inline u64 gpu_read64_relaxed(void __iomem *iomem, u32 reg)
{
- return (gpu_read_relaxed(ptdev, reg) |
- ((u64)gpu_read_relaxed(ptdev, reg + 4) << 32));
+ return (gpu_read_relaxed(iomem, reg) |
+ ((u64)gpu_read_relaxed(iomem, reg + 4) << 32));
}
-static inline u64 gpu_read64_counter(struct panthor_device *ptdev, u32 reg)
+static inline u64 gpu_read64_counter(void __iomem *iomem, u32 reg)
{
u32 lo, hi1, hi2;
do {
- hi1 = gpu_read(ptdev, reg + 4);
- lo = gpu_read(ptdev, reg);
- hi2 = gpu_read(ptdev, reg + 4);
+ hi1 = gpu_read(iomem, reg + 4);
+ lo = gpu_read(iomem, reg);
+ hi2 = gpu_read(iomem, reg + 4);
} while (hi1 != hi2);
return lo | ((u64)hi2 << 32);
}
-#define gpu_read_poll_timeout(dev, reg, val, cond, delay_us, timeout_us) \
+#define gpu_read_poll_timeout(iomem, reg, val, cond, delay_us, timeout_us) \
read_poll_timeout(gpu_read, val, cond, delay_us, timeout_us, false, \
- dev, reg)
+ iomem, reg)
-#define gpu_read_poll_timeout_atomic(dev, reg, val, cond, delay_us, \
+#define gpu_read_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \
timeout_us) \
read_poll_timeout_atomic(gpu_read, val, cond, delay_us, timeout_us, \
- false, dev, reg)
+ false, iomem, reg)
-#define gpu_read64_poll_timeout(dev, reg, val, cond, delay_us, timeout_us) \
+#define gpu_read64_poll_timeout(iomem, reg, val, cond, delay_us, timeout_us) \
read_poll_timeout(gpu_read64, val, cond, delay_us, timeout_us, false, \
- dev, reg)
+ iomem, reg)
-#define gpu_read64_poll_timeout_atomic(dev, reg, val, cond, delay_us, \
+#define gpu_read64_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \
timeout_us) \
read_poll_timeout_atomic(gpu_read64, val, cond, delay_us, timeout_us, \
- false, dev, reg)
+ false, iomem, reg)
-#define gpu_read_relaxed_poll_timeout_atomic(dev, reg, val, cond, delay_us, \
+#define gpu_read_relaxed_poll_timeout_atomic(iomem, reg, val, cond, delay_us, \
timeout_us) \
read_poll_timeout_atomic(gpu_read_relaxed, val, cond, delay_us, \
- timeout_us, false, dev, reg)
+ timeout_us, false, iomem, reg)
-#define gpu_read64_relaxed_poll_timeout(dev, reg, val, cond, delay_us, \
+#define gpu_read64_relaxed_poll_timeout(iomem, reg, val, cond, delay_us, \
timeout_us) \
read_poll_timeout(gpu_read64_relaxed, val, cond, delay_us, timeout_us, \
- false, dev, reg)
+ false, iomem, reg)
#endif
diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
index 87d27c3c1456..3bf0bf3a6a2b 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -33,9 +33,9 @@
#include "panthor_fw.h"
#include "panthor_gem.h"
#include "panthor_gpu.h"
+#include "panthor_gpu_regs.h"
#include "panthor_heap.h"
#include "panthor_mmu.h"
-#include "panthor_regs.h"
#include "panthor_sched.h"
/**
@@ -838,7 +838,7 @@ static int panthor_query_timestamp_info(struct panthor_device *ptdev,
}
if (flags & DRM_PANTHOR_TIMESTAMP_GPU_OFFSET)
- arg->timestamp_offset = gpu_read64(ptdev, GPU_TIMESTAMP_OFFSET);
+ arg->timestamp_offset = gpu_read64(ptdev->iomem, GPU_TIMESTAMP_OFFSET);
else
arg->timestamp_offset = 0;
@@ -853,7 +853,7 @@ static int panthor_query_timestamp_info(struct panthor_device *ptdev,
query_start_time = 0;
if (flags & DRM_PANTHOR_TIMESTAMP_GPU)
- arg->current_timestamp = gpu_read64_counter(ptdev, GPU_TIMESTAMP);
+ arg->current_timestamp = gpu_read64_counter(ptdev->iomem, GPU_TIMESTAMP);
else
arg->current_timestamp = 0;
@@ -869,7 +869,7 @@ static int panthor_query_timestamp_info(struct panthor_device *ptdev,
}
if (flags & DRM_PANTHOR_TIMESTAMP_GPU_CYCLE_COUNT)
- arg->cycle_count = gpu_read64_counter(ptdev, GPU_CYCLE_COUNT);
+ arg->cycle_count = gpu_read64_counter(ptdev->iomem, GPU_CYCLE_COUNT);
else
arg->cycle_count = 0;
diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c
index 8886002e1d31..834c48e368fc 100644
--- a/drivers/gpu/drm/panthor/panthor_fw.c
+++ b/drivers/gpu/drm/panthor/panthor_fw.c
@@ -20,11 +20,11 @@
#include "panthor_device.h"
#include "panthor_fw.h"
+#include "panthor_fw_regs.h"
#include "panthor_gem.h"
#include "panthor_gpu.h"
#include "panthor_hw.h"
#include "panthor_mmu.h"
-#include "panthor_regs.h"
#include "panthor_sched.h"
#include "panthor_trace.h"
@@ -1052,7 +1052,7 @@ static void panthor_fw_init_global_iface(struct panthor_device *ptdev)
GLB_CFG_POWEROFF_TIMER |
GLB_CFG_PROGRESS_TIMER);
- gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1);
+ gpu_write(ptdev->iomem, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1);
/* Kick the watchdog. */
mod_delayed_work(ptdev->reset.wq, &ptdev->fw->watchdog.ping_work,
@@ -1067,7 +1067,7 @@ static void panthor_job_irq_handler(struct panthor_device *ptdev, u32 status)
if (tracepoint_enabled(gpu_job_irq))
start = ktime_get_ns();
- gpu_write(ptdev, JOB_INT_CLEAR, status);
+ gpu_write(ptdev->iomem, JOB_INT_CLEAR, status);
if (!ptdev->fw->booted && (status & JOB_INT_GLOBAL_IF))
ptdev->fw->booted = true;
@@ -1086,7 +1086,7 @@ static void panthor_job_irq_handler(struct panthor_device *ptdev, u32 status)
trace_gpu_job_irq(ptdev->base.dev, status, duration);
}
}
-PANTHOR_IRQ_HANDLER(job, JOB, panthor_job_irq_handler);
+PANTHOR_IRQ_HANDLER(job, panthor_job_irq_handler);
static int panthor_fw_start(struct panthor_device *ptdev)
{
@@ -1095,13 +1095,13 @@ static int panthor_fw_start(struct panthor_device *ptdev)
ptdev->fw->booted = false;
panthor_job_irq_enable_events(&ptdev->fw->irq, ~0);
panthor_job_irq_resume(&ptdev->fw->irq);
- gpu_write(ptdev, MCU_CONTROL, MCU_CONTROL_AUTO);
+ gpu_write(ptdev->iomem, MCU_CONTROL, MCU_CONTROL_AUTO);
if (!wait_event_timeout(ptdev->fw->req_waitqueue,
ptdev->fw->booted,
msecs_to_jiffies(1000))) {
if (!ptdev->fw->booted &&
- !(gpu_read(ptdev, JOB_INT_STAT) & JOB_INT_GLOBAL_IF))
+ !(gpu_read(ptdev->iomem, JOB_INT_STAT) & JOB_INT_GLOBAL_IF))
timedout = true;
}
@@ -1112,7 +1112,7 @@ static int panthor_fw_start(struct panthor_device *ptdev)
[MCU_STATUS_HALT] = "halt",
[MCU_STATUS_FATAL] = "fatal",
};
- u32 status = gpu_read(ptdev, MCU_STATUS);
+ u32 status = gpu_read(ptdev->iomem, MCU_STATUS);
drm_err(&ptdev->base, "Failed to boot MCU (status=%s)",
status < ARRAY_SIZE(status_str) ? status_str[status] : "unknown");
@@ -1126,8 +1126,8 @@ static void panthor_fw_stop(struct panthor_device *ptdev)
{
u32 status;
- gpu_write(ptdev, MCU_CONTROL, MCU_CONTROL_DISABLE);
- if (gpu_read_poll_timeout(ptdev, MCU_STATUS, status,
+ gpu_write(ptdev->iomem, MCU_CONTROL, MCU_CONTROL_DISABLE);
+ if (gpu_read_poll_timeout(ptdev->iomem, MCU_STATUS, status,
status == MCU_STATUS_DISABLED, 10, 100000))
drm_err(&ptdev->base, "Failed to stop MCU");
}
@@ -1137,7 +1137,7 @@ static bool panthor_fw_mcu_halted(struct panthor_device *ptdev)
struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev);
bool halted;
- halted = gpu_read(ptdev, MCU_STATUS) == MCU_STATUS_HALT;
+ halted = gpu_read(ptdev->iomem, MCU_STATUS) == MCU_STATUS_HALT;
if (panthor_fw_has_glb_state(ptdev))
halted &= (GLB_STATE_GET(glb_iface->output->ack) == GLB_STATE_HALT);
@@ -1154,7 +1154,7 @@ static void panthor_fw_halt_mcu(struct panthor_device *ptdev)
else
panthor_fw_update_reqs(glb_iface, req, GLB_HALT, GLB_HALT);
- gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1);
+ gpu_write(ptdev->iomem, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1);
}
static bool panthor_fw_wait_mcu_halted(struct panthor_device *ptdev)
@@ -1412,7 +1412,7 @@ void panthor_fw_ring_csg_doorbells(struct panthor_device *ptdev, u32 csg_mask)
struct panthor_fw_global_iface *glb_iface = panthor_fw_get_glb_iface(ptdev);
panthor_fw_toggle_reqs(glb_iface, doorbell_req, doorbell_ack, csg_mask);
- gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1);
+ gpu_write(ptdev->iomem, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1);
}
static void panthor_fw_ping_work(struct work_struct *work)
@@ -1427,7 +1427,7 @@ static void panthor_fw_ping_work(struct work_struct *work)
return;
panthor_fw_toggle_reqs(glb_iface, req, ack, GLB_PING);
- gpu_write(ptdev, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1);
+ gpu_write(ptdev->iomem, CSF_DOORBELL(CSF_GLB_DOORBELL_ID), 1);
ret = panthor_fw_glb_wait_acks(ptdev, GLB_PING, &acked, 100);
if (ret) {
@@ -1463,7 +1463,8 @@ int panthor_fw_init(struct panthor_device *ptdev)
if (irq <= 0)
return -ENODEV;
- ret = panthor_request_job_irq(ptdev, &fw->irq, irq, 0);
+ ret = panthor_request_job_irq(ptdev, &fw->irq, irq, 0,
+ ptdev->iomem + JOB_INT_BASE);
if (ret) {
drm_err(&ptdev->base, "failed to request job irq");
return ret;
diff --git a/drivers/gpu/drm/panthor/panthor_fw_regs.h b/drivers/gpu/drm/panthor/panthor_fw_regs.h
new file mode 100644
index 000000000000..eeb41aff249b
--- /dev/null
+++ b/drivers/gpu/drm/panthor/panthor_fw_regs.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+/* Copyright 2026 ARM Limited. All rights reserved. */
+
+#ifndef __PANTHOR_FW_REGS_H__
+#define __PANTHOR_FW_REGS_H__
+
+#define MCU_CONTROL 0x700
+#define MCU_CONTROL_ENABLE 1
+#define MCU_CONTROL_AUTO 2
+#define MCU_CONTROL_DISABLE 0
+
+#define MCU_STATUS 0x704
+#define MCU_STATUS_DISABLED 0
+#define MCU_STATUS_ENABLED 1
+#define MCU_STATUS_HALT 2
+#define MCU_STATUS_FATAL 3
+
+#define JOB_INT_BASE 0x1000
+
+#define JOB_INT_RAWSTAT 0x1000
+#define JOB_INT_CLEAR 0x1004
+#define JOB_INT_MASK 0x1008
+#define JOB_INT_STAT 0x100c
+#define JOB_INT_GLOBAL_IF BIT(31)
+#define JOB_INT_CSG_IF(x) BIT(x)
+
+#define CSF_GPU_LATEST_FLUSH_ID 0x10000
+
+#define CSF_DOORBELL(i) (0x80000 + ((i) * 0x10000))
+#define CSF_GLB_DOORBELL_ID 0
+
+#endif /* __PANTHOR_FW_REGS_H__ */
diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c
index 2ab444ee8c71..d8e5283e9a1c 100644
--- a/drivers/gpu/drm/panthor/panthor_gpu.c
+++ b/drivers/gpu/drm/panthor/panthor_gpu.c
@@ -19,8 +19,8 @@
#include "panthor_device.h"
#include "panthor_gpu.h"
+#include "panthor_gpu_regs.h"
#include "panthor_hw.h"
-#include "panthor_regs.h"
#define CREATE_TRACE_POINTS
#include "panthor_trace.h"
@@ -56,7 +56,7 @@ struct panthor_gpu {
static void panthor_gpu_coherency_set(struct panthor_device *ptdev)
{
- gpu_write(ptdev, GPU_COHERENCY_PROTOCOL,
+ gpu_write(ptdev->iomem, GPU_COHERENCY_PROTOCOL,
ptdev->gpu_info.selected_coherency);
}
@@ -75,26 +75,26 @@ static void panthor_gpu_l2_config_set(struct panthor_device *ptdev)
}
for (i = 0; i < ARRAY_SIZE(data->asn_hash); i++)
- gpu_write(ptdev, GPU_ASN_HASH(i), data->asn_hash[i]);
+ gpu_write(ptdev->iomem, GPU_ASN_HASH(i), data->asn_hash[i]);
- l2_config = gpu_read(ptdev, GPU_L2_CONFIG);
+ l2_config = gpu_read(ptdev->iomem, GPU_L2_CONFIG);
l2_config |= GPU_L2_CONFIG_ASN_HASH_ENABLE;
- gpu_write(ptdev, GPU_L2_CONFIG, l2_config);
+ gpu_write(ptdev->iomem, GPU_L2_CONFIG, l2_config);
}
static void panthor_gpu_irq_handler(struct panthor_device *ptdev, u32 status)
{
- gpu_write(ptdev, GPU_INT_CLEAR, status);
+ gpu_write(ptdev->iomem, GPU_INT_CLEAR, status);
if (tracepoint_enabled(gpu_power_status) && (status & GPU_POWER_INTERRUPTS_MASK))
trace_gpu_power_status(ptdev->base.dev,
- gpu_read64(ptdev, SHADER_READY),
- gpu_read64(ptdev, TILER_READY),
- gpu_read64(ptdev, L2_READY));
+ gpu_read64(ptdev->iomem, SHADER_READY),
+ gpu_read64(ptdev->iomem, TILER_READY),
+ gpu_read64(ptdev->iomem, L2_READY));
if (status & GPU_IRQ_FAULT) {
- u32 fault_status = gpu_read(ptdev, GPU_FAULT_STATUS);
- u64 address = gpu_read64(ptdev, GPU_FAULT_ADDR);
+ u32 fault_status = gpu_read(ptdev->iomem, GPU_FAULT_STATUS);
+ u64 address = gpu_read64(ptdev->iomem, GPU_FAULT_ADDR);
drm_warn(&ptdev->base, "GPU Fault 0x%08x (%s) at 0x%016llx\n",
fault_status, panthor_exception_name(ptdev, fault_status & 0xFF),
@@ -110,7 +110,7 @@ static void panthor_gpu_irq_handler(struct panthor_device *ptdev, u32 status)
}
spin_unlock(&ptdev->gpu->reqs_lock);
}
-PANTHOR_IRQ_HANDLER(gpu, GPU, panthor_gpu_irq_handler);
+PANTHOR_IRQ_HANDLER(gpu, panthor_gpu_irq_handler);
/**
* panthor_gpu_unplug() - Called when the GPU is unplugged.
@@ -162,7 +162,9 @@ int panthor_gpu_init(struct panthor_device *ptdev)
if (irq < 0)
return irq;
- ret = panthor_request_gpu_irq(ptdev, &ptdev->gpu->irq, irq, GPU_INTERRUPTS_MASK);
+ ret = panthor_request_gpu_irq(ptdev, &ptdev->gpu->irq, irq,
+ GPU_INTERRUPTS_MASK,
+ ptdev->iomem + GPU_INT_BASE);
if (ret)
return ret;
@@ -204,7 +206,7 @@ int panthor_gpu_block_power_off(struct panthor_device *ptdev,
u32 val;
int ret;
- ret = gpu_read64_relaxed_poll_timeout(ptdev, pwrtrans_reg, val,
+ ret = gpu_read64_relaxed_poll_timeout(ptdev->iomem, pwrtrans_reg, val,
!(mask & val), 100, timeout_us);
if (ret) {
drm_err(&ptdev->base,
@@ -213,9 +215,9 @@ int panthor_gpu_block_power_off(struct panthor_device *ptdev,
return ret;
}
- gpu_write64(ptdev, pwroff_reg, mask);
+ gpu_write64(ptdev->iomem, pwroff_reg, mask);
- ret = gpu_read64_relaxed_poll_timeout(ptdev, pwrtrans_reg, val,
+ ret = gpu_read64_relaxed_poll_timeout(ptdev->iomem, pwrtrans_reg, val,
!(mask & val), 100, timeout_us);
if (ret) {
drm_err(&ptdev->base,
@@ -247,7 +249,7 @@ int panthor_gpu_block_power_on(struct panthor_device *ptdev,
u32 val;
int ret;
- ret = gpu_read64_relaxed_poll_timeout(ptdev, pwrtrans_reg, val,
+ ret = gpu_read64_relaxed_poll_timeout(ptdev->iomem, pwrtrans_reg, val,
!(mask & val), 100, timeout_us);
if (ret) {
drm_err(&ptdev->base,
@@ -256,9 +258,9 @@ int panthor_gpu_block_power_on(struct panthor_device *ptdev,
return ret;
}
- gpu_write64(ptdev, pwron_reg, mask);
+ gpu_write64(ptdev->iomem, pwron_reg, mask);
- ret = gpu_read64_relaxed_poll_timeout(ptdev, rdy_reg, val,
+ ret = gpu_read64_relaxed_poll_timeout(ptdev->iomem, rdy_reg, val,
(mask & val) == val,
100, timeout_us);
if (ret) {
@@ -326,7 +328,7 @@ int panthor_gpu_flush_caches(struct panthor_device *ptdev,
spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
- gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
+ gpu_write(ptdev->iomem, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
} else {
ret = -EIO;
}
@@ -340,7 +342,7 @@ int panthor_gpu_flush_caches(struct panthor_device *ptdev,
msecs_to_jiffies(100))) {
spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
- !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
+ !(gpu_read(ptdev->iomem, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
ret = -ETIMEDOUT;
else
ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
@@ -370,8 +372,8 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
if (!drm_WARN_ON(&ptdev->base,
ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED)) {
ptdev->gpu->pending_reqs |= GPU_IRQ_RESET_COMPLETED;
- gpu_write(ptdev, GPU_INT_CLEAR, GPU_IRQ_RESET_COMPLETED);
- gpu_write(ptdev, GPU_CMD, GPU_SOFT_RESET);
+ gpu_write(ptdev->iomem, GPU_INT_CLEAR, GPU_IRQ_RESET_COMPLETED);
+ gpu_write(ptdev->iomem, GPU_CMD, GPU_SOFT_RESET);
}
spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
@@ -380,7 +382,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
msecs_to_jiffies(100))) {
spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
if ((ptdev->gpu->pending_reqs & GPU_IRQ_RESET_COMPLETED) != 0 &&
- !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_RESET_COMPLETED))
+ !(gpu_read(ptdev->iomem, GPU_INT_RAWSTAT) & GPU_IRQ_RESET_COMPLETED))
timedout = true;
else
ptdev->gpu->pending_reqs &= ~GPU_IRQ_RESET_COMPLETED;
diff --git a/drivers/gpu/drm/panthor/panthor_gpu_regs.h b/drivers/gpu/drm/panthor/panthor_gpu_regs.h
new file mode 100644
index 000000000000..3f60c45985a7
--- /dev/null
+++ b/drivers/gpu/drm/panthor/panthor_gpu_regs.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+/* Copyright 2026 ARM Limited. All rights reserved. */
+
+#ifndef __PANTHOR_GPU_REGS_H__
+#define __PANTHOR_GPU_REGS_H__
+
+#define GPU_CONTROL_BASE 0x0
+
+#define GPU_ID 0x0
+#define GPU_ARCH_MAJOR(x) ((x) >> 28)
+#define GPU_ARCH_MINOR(x) (((x) & GENMASK(27, 24)) >> 24)
+#define GPU_ARCH_REV(x) (((x) & GENMASK(23, 20)) >> 20)
+#define GPU_PROD_MAJOR(x) (((x) & GENMASK(19, 16)) >> 16)
+#define GPU_VER_MAJOR(x) (((x) & GENMASK(15, 12)) >> 12)
+#define GPU_VER_MINOR(x) (((x) & GENMASK(11, 4)) >> 4)
+#define GPU_VER_STATUS(x) ((x) & GENMASK(3, 0))
+
+#define GPU_L2_FEATURES 0x4
+#define GPU_L2_FEATURES_LINE_SIZE(x) (1 << ((x) & GENMASK(7, 0)))
+
+#define GPU_CORE_FEATURES 0x8
+
+#define GPU_TILER_FEATURES 0xC
+#define GPU_MEM_FEATURES 0x10
+#define GROUPS_L2_COHERENT BIT(0)
+
+#define GPU_MMU_FEATURES 0x14
+#define GPU_MMU_FEATURES_VA_BITS(x) ((x) & GENMASK(7, 0))
+#define GPU_MMU_FEATURES_PA_BITS(x) (((x) >> 8) & GENMASK(7, 0))
+#define GPU_AS_PRESENT 0x18
+#define GPU_CSF_ID 0x1C
+
+#define GPU_INT_BASE 0x20
+#define GPU_INT_RAWSTAT 0x20
+#define GPU_INT_CLEAR 0x24
+#define GPU_INT_MASK 0x28
+#define GPU_INT_STAT 0x2c
+#define GPU_IRQ_FAULT BIT(0)
+#define GPU_IRQ_PROTM_FAULT BIT(1)
+#define GPU_IRQ_RESET_COMPLETED BIT(8)
+#define GPU_IRQ_POWER_CHANGED BIT(9)
+#define GPU_IRQ_POWER_CHANGED_ALL BIT(10)
+#define GPU_IRQ_CLEAN_CACHES_COMPLETED BIT(17)
+#define GPU_IRQ_DOORBELL_MIRROR BIT(18)
+#define GPU_IRQ_MCU_STATUS_CHANGED BIT(19)
+#define GPU_CMD 0x30
+#define GPU_CMD_DEF(type, payload) ((type) | ((payload) << 8))
+#define GPU_SOFT_RESET GPU_CMD_DEF(1, 1)
+#define GPU_HARD_RESET GPU_CMD_DEF(1, 2)
+#define CACHE_CLEAN BIT(0)
+#define CACHE_INV BIT(1)
+#define GPU_FLUSH_CACHES(l2, lsc, oth) \
+ GPU_CMD_DEF(4, ((l2) << 0) | ((lsc) << 4) | ((oth) << 8))
+
+#define GPU_STATUS 0x34
+#define GPU_STATUS_ACTIVE BIT(0)
+#define GPU_STATUS_PWR_ACTIVE BIT(1)
+#define GPU_STATUS_PAGE_FAULT BIT(4)
+#define GPU_STATUS_PROTM_ACTIVE BIT(7)
+#define GPU_STATUS_DBG_ENABLED BIT(8)
+
+#define GPU_FAULT_STATUS 0x3C
+#define GPU_FAULT_ADDR 0x40
+#define GPU_L2_CONFIG 0x48
+#define GPU_L2_CONFIG_ASN_HASH_ENABLE BIT(24)
+
+#define GPU_PWR_KEY 0x50
+#define GPU_PWR_KEY_UNLOCK 0x2968A819
+#define GPU_PWR_OVERRIDE0 0x54
+#define GPU_PWR_OVERRIDE1 0x58
+
+#define GPU_FEATURES 0x60
+#define GPU_FEATURES_RAY_INTERSECTION BIT(2)
+#define GPU_FEATURES_RAY_TRAVERSAL BIT(5)
+
+#define GPU_TIMESTAMP_OFFSET 0x88
+#define GPU_CYCLE_COUNT 0x90
+#define GPU_TIMESTAMP 0x98
+
+#define GPU_THREAD_MAX_THREADS 0xA0
+#define GPU_THREAD_MAX_WORKGROUP_SIZE 0xA4
+#define GPU_THREAD_MAX_BARRIER_SIZE 0xA8
+#define GPU_THREAD_FEATURES 0xAC
+
+#define GPU_TEXTURE_FEATURES(n) (0xB0 + ((n) * 4))
+
+#define GPU_SHADER_PRESENT 0x100
+#define GPU_TILER_PRESENT 0x110
+#define GPU_L2_PRESENT 0x120
+
+#define SHADER_READY 0x140
+#define TILER_READY 0x150
+#define L2_READY 0x160
+
+#define SHADER_PWRON 0x180
+#define TILER_PWRON 0x190
+#define L2_PWRON 0x1A0
+
+#define SHADER_PWROFF 0x1C0
+#define TILER_PWROFF 0x1D0
+#define L2_PWROFF 0x1E0
+
+#define SHADER_PWRTRANS 0x200
+#define TILER_PWRTRANS 0x210
+#define L2_PWRTRANS 0x220
+
+#define SHADER_PWRACTIVE 0x240
+#define TILER_PWRACTIVE 0x250
+#define L2_PWRACTIVE 0x260
+
+#define GPU_REVID 0x280
+
+#define GPU_ASN_HASH(n) (0x2C0 + ((n) * 4))
+
+#define GPU_COHERENCY_FEATURES 0x300
+#define GPU_COHERENCY_PROT_BIT(name) BIT(GPU_COHERENCY_ ## name)
+
+#define GPU_COHERENCY_PROTOCOL 0x304
+#define GPU_COHERENCY_ACE_LITE 0
+#define GPU_COHERENCY_ACE 1
+#define GPU_COHERENCY_NONE 31
+
+#endif /* __PANTHOR_GPU_REGS_H__ */
diff --git a/drivers/gpu/drm/panthor/panthor_heap.c b/drivers/gpu/drm/panthor/panthor_heap.c
index 1ee30dc7066f..99311abdf1e9 100644
--- a/drivers/gpu/drm/panthor/panthor_heap.c
+++ b/drivers/gpu/drm/panthor/panthor_heap.c
@@ -9,9 +9,9 @@
#include "panthor_device.h"
#include "panthor_gem.h"
+#include "panthor_gpu_regs.h"
#include "panthor_heap.h"
#include "panthor_mmu.h"
-#include "panthor_regs.h"
/*
* The GPU heap context is an opaque structure used by the GPU to track the
diff --git a/drivers/gpu/drm/panthor/panthor_hw.c b/drivers/gpu/drm/panthor/panthor_hw.c
index d135aa6724fa..9431f16d950f 100644
--- a/drivers/gpu/drm/panthor/panthor_hw.c
+++ b/drivers/gpu/drm/panthor/panthor_hw.c
@@ -8,9 +8,10 @@
#include "panthor_device.h"
#include "panthor_gpu.h"
+#include "panthor_gpu_regs.h"
#include "panthor_hw.h"
#include "panthor_pwr.h"
-#include "panthor_regs.h"
+#include "panthor_pwr_regs.h"
#define GPU_PROD_ID_MAKE(arch_major, prod_major) \
(((arch_major) << 24) | (prod_major))
@@ -194,35 +195,38 @@ static int panthor_gpu_info_init(struct panthor_device *ptdev)
{
unsigned int i;
- ptdev->gpu_info.csf_id = gpu_read(ptdev, GPU_CSF_ID);
- ptdev->gpu_info.gpu_rev = gpu_read(ptdev, GPU_REVID);
- ptdev->gpu_info.core_features = gpu_read(ptdev, GPU_CORE_FEATURES);
- ptdev->gpu_info.l2_features = gpu_read(ptdev, GPU_L2_FEATURES);
- ptdev->gpu_info.tiler_features = gpu_read(ptdev, GPU_TILER_FEATURES);
- ptdev->gpu_info.mem_features = gpu_read(ptdev, GPU_MEM_FEATURES);
- ptdev->gpu_info.mmu_features = gpu_read(ptdev, GPU_MMU_FEATURES);
- ptdev->gpu_info.thread_features = gpu_read(ptdev, GPU_THREAD_FEATURES);
- ptdev->gpu_info.max_threads = gpu_read(ptdev, GPU_THREAD_MAX_THREADS);
- ptdev->gpu_info.thread_max_workgroup_size = gpu_read(ptdev, GPU_THREAD_MAX_WORKGROUP_SIZE);
- ptdev->gpu_info.thread_max_barrier_size = gpu_read(ptdev, GPU_THREAD_MAX_BARRIER_SIZE);
- ptdev->gpu_info.coherency_features = gpu_read(ptdev, GPU_COHERENCY_FEATURES);
+ ptdev->gpu_info.csf_id = gpu_read(ptdev->iomem, GPU_CSF_ID);
+ ptdev->gpu_info.gpu_rev = gpu_read(ptdev->iomem, GPU_REVID);
+ ptdev->gpu_info.core_features = gpu_read(ptdev->iomem, GPU_CORE_FEATURES);
+ ptdev->gpu_info.l2_features = gpu_read(ptdev->iomem, GPU_L2_FEATURES);
+ ptdev->gpu_info.tiler_features = gpu_read(ptdev->iomem, GPU_TILER_FEATURES);
+ ptdev->gpu_info.mem_features = gpu_read(ptdev->iomem, GPU_MEM_FEATURES);
+ ptdev->gpu_info.mmu_features = gpu_read(ptdev->iomem, GPU_MMU_FEATURES);
+ ptdev->gpu_info.thread_features = gpu_read(ptdev->iomem, GPU_THREAD_FEATURES);
+ ptdev->gpu_info.max_threads = gpu_read(ptdev->iomem, GPU_THREAD_MAX_THREADS);
+ ptdev->gpu_info.thread_max_workgroup_size =
+ gpu_read(ptdev->iomem, GPU_THREAD_MAX_WORKGROUP_SIZE);
+ ptdev->gpu_info.thread_max_barrier_size =
+ gpu_read(ptdev->iomem, GPU_THREAD_MAX_BARRIER_SIZE);
+ ptdev->gpu_info.coherency_features = gpu_read(ptdev->iomem, GPU_COHERENCY_FEATURES);
for (i = 0; i < 4; i++)
- ptdev->gpu_info.texture_features[i] = gpu_read(ptdev, GPU_TEXTURE_FEATURES(i));
+ ptdev->gpu_info.texture_features[i] =
+ gpu_read(ptdev->iomem, GPU_TEXTURE_FEATURES(i));
- ptdev->gpu_info.as_present = gpu_read(ptdev, GPU_AS_PRESENT);
+ ptdev->gpu_info.as_present = gpu_read(ptdev->iomem, GPU_AS_PRESENT);
/* Introduced in arch 11.x */
- ptdev->gpu_info.gpu_features = gpu_read64(ptdev, GPU_FEATURES);
+ ptdev->gpu_info.gpu_features = gpu_read64(ptdev->iomem, GPU_FEATURES);
if (panthor_hw_has_pwr_ctrl(ptdev)) {
/* Introduced in arch 14.x */
- ptdev->gpu_info.l2_present = gpu_read64(ptdev, PWR_L2_PRESENT);
- ptdev->gpu_info.tiler_present = gpu_read64(ptdev, PWR_TILER_PRESENT);
- ptdev->gpu_info.shader_present = gpu_read64(ptdev, PWR_SHADER_PRESENT);
+ ptdev->gpu_info.l2_present = gpu_read64(ptdev->iomem, PWR_L2_PRESENT);
+ ptdev->gpu_info.tiler_present = gpu_read64(ptdev->iomem, PWR_TILER_PRESENT);
+ ptdev->gpu_info.shader_present = gpu_read64(ptdev->iomem, PWR_SHADER_PRESENT);
} else {
- ptdev->gpu_info.shader_present = gpu_read64(ptdev, GPU_SHADER_PRESENT);
- ptdev->gpu_info.tiler_present = gpu_read64(ptdev, GPU_TILER_PRESENT);
- ptdev->gpu_info.l2_present = gpu_read64(ptdev, GPU_L2_PRESENT);
+ ptdev->gpu_info.shader_present = gpu_read64(ptdev->iomem, GPU_SHADER_PRESENT);
+ ptdev->gpu_info.tiler_present = gpu_read64(ptdev->iomem, GPU_TILER_PRESENT);
+ ptdev->gpu_info.l2_present = gpu_read64(ptdev->iomem, GPU_L2_PRESENT);
}
return overload_shader_present(ptdev);
@@ -287,7 +291,7 @@ static int panthor_hw_bind_device(struct panthor_device *ptdev)
static int panthor_hw_gpu_id_init(struct panthor_device *ptdev)
{
- ptdev->gpu_info.gpu_id = gpu_read(ptdev, GPU_ID);
+ ptdev->gpu_info.gpu_id = gpu_read(ptdev->iomem, GPU_ID);
if (!ptdev->gpu_info.gpu_id)
return -ENXIO;
diff --git a/drivers/gpu/drm/panthor/panthor_hw.h b/drivers/gpu/drm/panthor/panthor_hw.h
index 2c28aea82841..f797663893b2 100644
--- a/drivers/gpu/drm/panthor/panthor_hw.h
+++ b/drivers/gpu/drm/panthor/panthor_hw.h
@@ -5,7 +5,7 @@
#define __PANTHOR_HW_H__
#include "panthor_device.h"
-#include "panthor_regs.h"
+#include "panthor_gpu_regs.h"
/**
* struct panthor_hw_ops - HW operations that are specific to a GPU
diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
index 75d98dad7b1d..263a22f7b393 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.c
+++ b/drivers/gpu/drm/panthor/panthor_mmu.c
@@ -31,9 +31,10 @@
#include "panthor_device.h"
#include "panthor_gem.h"
#include "panthor_gpu.h"
+#include "panthor_gpu_regs.h"
#include "panthor_heap.h"
#include "panthor_mmu.h"
-#include "panthor_regs.h"
+#include "panthor_mmu_regs.h"
#include "panthor_sched.h"
#define MAX_AS_SLOTS 32
@@ -507,9 +508,8 @@ static int wait_ready(struct panthor_device *ptdev, u32 as_nr)
/* Wait for the MMU status to indicate there is no active command, in
* case one is pending.
*/
- ret = gpu_read_relaxed_poll_timeout_atomic(ptdev, AS_STATUS(as_nr), val,
- !(val & AS_STATUS_AS_ACTIVE),
- 10, 100000);
+ ret = gpu_read_relaxed_poll_timeout_atomic(ptdev->iomem, AS_STATUS(as_nr), val,
+ !(val & AS_STATUS_AS_ACTIVE), 10, 100000);
if (ret) {
panthor_device_schedule_reset(ptdev);
@@ -526,7 +526,7 @@ static int as_send_cmd_and_wait(struct panthor_device *ptdev, u32 as_nr, u32 cmd
/* write AS_COMMAND when MMU is ready to accept another command */
status = wait_ready(ptdev, as_nr);
if (!status) {
- gpu_write(ptdev, AS_COMMAND(as_nr), cmd);
+ gpu_write(ptdev->iomem, AS_COMMAND(as_nr), cmd);
status = wait_ready(ptdev, as_nr);
}
@@ -569,7 +569,7 @@ static u32 panthor_mmu_as_fault_mask(struct panthor_device *ptdev, u32 as)
/* Forward declaration to call helpers within as_enable/disable */
static void panthor_mmu_irq_handler(struct panthor_device *ptdev, u32 status);
-PANTHOR_IRQ_HANDLER(mmu, MMU, panthor_mmu_irq_handler);
+PANTHOR_IRQ_HANDLER(mmu, panthor_mmu_irq_handler);
static int panthor_mmu_as_enable(struct panthor_device *ptdev, u32 as_nr,
u64 transtab, u64 transcfg, u64 memattr)
@@ -577,9 +577,9 @@ static int panthor_mmu_as_enable(struct panthor_device *ptdev, u32 as_nr,
panthor_mmu_irq_enable_events(&ptdev->mmu->irq,
panthor_mmu_as_fault_mask(ptdev, as_nr));
- gpu_write64(ptdev, AS_TRANSTAB(as_nr), transtab);
- gpu_write64(ptdev, AS_MEMATTR(as_nr), memattr);
- gpu_write64(ptdev, AS_TRANSCFG(as_nr), transcfg);
+ gpu_write64(ptdev->iomem, AS_TRANSTAB(as_nr), transtab);
+ gpu_write64(ptdev->iomem, AS_MEMATTR(as_nr), memattr);
+ gpu_write64(ptdev->iomem, AS_TRANSCFG(as_nr), transcfg);
return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
}
@@ -614,9 +614,9 @@ static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr,
if (recycle_slot)
return 0;
- gpu_write64(ptdev, AS_TRANSTAB(as_nr), 0);
- gpu_write64(ptdev, AS_MEMATTR(as_nr), 0);
- gpu_write64(ptdev, AS_TRANSCFG(as_nr), AS_TRANSCFG_ADRMODE_UNMAPPED);
+ gpu_write64(ptdev->iomem, AS_TRANSTAB(as_nr), 0);
+ gpu_write64(ptdev->iomem, AS_MEMATTR(as_nr), 0);
+ gpu_write64(ptdev->iomem, AS_TRANSCFG(as_nr), AS_TRANSCFG_ADRMODE_UNMAPPED);
return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
}
@@ -759,7 +759,7 @@ out_enable_as:
*/
fault_mask = panthor_mmu_as_fault_mask(ptdev, as);
if (ptdev->mmu->as.faulty_mask & fault_mask) {
- gpu_write(ptdev, MMU_INT_CLEAR, fault_mask);
+ gpu_write(ptdev->iomem, MMU_INT_CLEAR, fault_mask);
ptdev->mmu->as.faulty_mask &= ~fault_mask;
}
@@ -1670,7 +1670,7 @@ static int panthor_vm_lock_region(struct panthor_vm *vm, u64 start, u64 size)
mutex_lock(&ptdev->mmu->as.slots_lock);
if (vm->as.id >= 0 && size) {
/* Lock the region that needs to be updated */
- gpu_write64(ptdev, AS_LOCKADDR(vm->as.id),
+ gpu_write64(ptdev->iomem, AS_LOCKADDR(vm->as.id),
pack_region_range(ptdev, &start, &size));
/* If the lock succeeded, update the locked_region info. */
@@ -1731,8 +1731,8 @@ static void panthor_mmu_irq_handler(struct panthor_device *ptdev, u32 status)
u32 access_type;
u32 source_id;
- fault_status = gpu_read(ptdev, AS_FAULTSTATUS(as));
- addr = gpu_read64(ptdev, AS_FAULTADDRESS(as));
+ fault_status = gpu_read(ptdev->iomem, AS_FAULTSTATUS(as));
+ addr = gpu_read64(ptdev->iomem, AS_FAULTADDRESS(as));
/* decode the fault status */
exception_type = fault_status & 0xFF;
@@ -1763,7 +1763,7 @@ static void panthor_mmu_irq_handler(struct panthor_device *ptdev, u32 status)
* Note that COMPLETED irqs are never cleared, but this is fine
* because they are always masked.
*/
- gpu_write(ptdev, MMU_INT_CLEAR, mask);
+ gpu_write(ptdev->iomem, MMU_INT_CLEAR, mask);
if (ptdev->mmu->as.slots[as].vm)
ptdev->mmu->as.slots[as].vm->unhandled_fault = true;
@@ -2888,7 +2888,8 @@ int panthor_mmu_init(struct panthor_device *ptdev)
return -ENODEV;
ret = panthor_request_mmu_irq(ptdev, &mmu->irq, irq,
- panthor_mmu_fault_mask(ptdev, ~0));
+ panthor_mmu_fault_mask(ptdev, ~0),
+ ptdev->iomem + MMU_INT_BASE);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/panthor/panthor_mmu_regs.h b/drivers/gpu/drm/panthor/panthor_mmu_regs.h
new file mode 100644
index 000000000000..de460042651d
--- /dev/null
+++ b/drivers/gpu/drm/panthor/panthor_mmu_regs.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+/* Copyright 2026 ARM Limited. All rights reserved. */
+
+#ifndef __PANTHOR_MMU_REGS_H__
+#define __PANTHOR_MMU_REGS_H__
+
+/* MMU regs */
+
+#define MMU_INT_BASE 0x2000
+
+#define MMU_INT_RAWSTAT 0x2000
+#define MMU_INT_CLEAR 0x2004
+#define MMU_INT_MASK 0x2008
+#define MMU_INT_STAT 0x200c
+
+/* AS_COMMAND register commands */
+
+#define MMU_BASE 0x2400
+#define MMU_AS_SHIFT 6
+#define MMU_AS(as) (MMU_BASE + ((as) << MMU_AS_SHIFT))
+
+#define AS_TRANSTAB(as) (MMU_AS(as) + 0x0)
+#define AS_MEMATTR(as) (MMU_AS(as) + 0x8)
+#define AS_MEMATTR_AARCH64_INNER_ALLOC_IMPL (2 << 2)
+#define AS_MEMATTR_AARCH64_INNER_ALLOC_EXPL(w, r) ((3 << 2) | \
+ ((w) ? BIT(0) : 0) | \
+ ((r) ? BIT(1) : 0))
+#define AS_MEMATTR_AARCH64_SH_MIDGARD_INNER (0 << 4)
+#define AS_MEMATTR_AARCH64_SH_CPU_INNER (1 << 4)
+#define AS_MEMATTR_AARCH64_SH_CPU_INNER_SHADER_COH (2 << 4)
+#define AS_MEMATTR_AARCH64_SHARED (0 << 6)
+#define AS_MEMATTR_AARCH64_INNER_OUTER_NC (1 << 6)
+#define AS_MEMATTR_AARCH64_INNER_OUTER_WB (2 << 6)
+#define AS_MEMATTR_AARCH64_FAULT (3 << 6)
+#define AS_LOCKADDR(as) (MMU_AS(as) + 0x10)
+#define AS_COMMAND(as) (MMU_AS(as) + 0x18)
+#define AS_COMMAND_NOP 0
+#define AS_COMMAND_UPDATE 1
+#define AS_COMMAND_LOCK 2
+#define AS_COMMAND_UNLOCK 3
+#define AS_COMMAND_FLUSH_PT 4
+#define AS_COMMAND_FLUSH_MEM 5
+#define AS_LOCK_REGION_MIN_SIZE (1ULL << 15)
+#define AS_FAULTSTATUS(as) (MMU_AS(as) + 0x1C)
+#define AS_FAULTSTATUS_ACCESS_TYPE_MASK (0x3 << 8)
+#define AS_FAULTSTATUS_ACCESS_TYPE_ATOMIC (0x0 << 8)
+#define AS_FAULTSTATUS_ACCESS_TYPE_EX (0x1 << 8)
+#define AS_FAULTSTATUS_ACCESS_TYPE_READ (0x2 << 8)
+#define AS_FAULTSTATUS_ACCESS_TYPE_WRITE (0x3 << 8)
+#define AS_FAULTADDRESS(as) (MMU_AS(as) + 0x20)
+#define AS_STATUS(as) (MMU_AS(as) + 0x28)
+#define AS_STATUS_AS_ACTIVE BIT(0)
+#define AS_TRANSCFG(as) (MMU_AS(as) + 0x30)
+#define AS_TRANSCFG_ADRMODE_UNMAPPED (1 << 0)
+#define AS_TRANSCFG_ADRMODE_IDENTITY (2 << 0)
+#define AS_TRANSCFG_ADRMODE_AARCH64_4K (6 << 0)
+#define AS_TRANSCFG_ADRMODE_AARCH64_64K (8 << 0)
+#define AS_TRANSCFG_INA_BITS(x) ((x) << 6)
+#define AS_TRANSCFG_OUTA_BITS(x) ((x) << 14)
+#define AS_TRANSCFG_SL_CONCAT BIT(22)
+#define AS_TRANSCFG_PTW_MEMATTR_NC (1 << 24)
+#define AS_TRANSCFG_PTW_MEMATTR_WB (2 << 24)
+#define AS_TRANSCFG_PTW_SH_NS (0 << 28)
+#define AS_TRANSCFG_PTW_SH_OS (2 << 28)
+#define AS_TRANSCFG_PTW_SH_IS (3 << 28)
+#define AS_TRANSCFG_PTW_RA BIT(30)
+#define AS_TRANSCFG_DISABLE_HIER_AP BIT(33)
+#define AS_TRANSCFG_DISABLE_AF_FAULT BIT(34)
+#define AS_TRANSCFG_WXN BIT(35)
+#define AS_TRANSCFG_XREADABLE BIT(36)
+#define AS_FAULTEXTRA(as) (MMU_AS(as) + 0x38)
+
+#endif /* __PANTHOR_MMU_REGS_H__ */
diff --git a/drivers/gpu/drm/panthor/panthor_pwr.c b/drivers/gpu/drm/panthor/panthor_pwr.c
index ed3b2b4479ca..dda5159a5271 100644
--- a/drivers/gpu/drm/panthor/panthor_pwr.c
+++ b/drivers/gpu/drm/panthor/panthor_pwr.c
@@ -11,9 +11,10 @@
#include <drm/drm_print.h>
#include "panthor_device.h"
+#include "panthor_gpu_regs.h"
#include "panthor_hw.h"
#include "panthor_pwr.h"
-#include "panthor_regs.h"
+#include "panthor_pwr_regs.h"
#define PWR_INTERRUPTS_MASK \
(PWR_IRQ_POWER_CHANGED_SINGLE | \
@@ -55,7 +56,7 @@ struct panthor_pwr {
static void panthor_pwr_irq_handler(struct panthor_device *ptdev, u32 status)
{
spin_lock(&ptdev->pwr->reqs_lock);
- gpu_write(ptdev, PWR_INT_CLEAR, status);
+ gpu_write(ptdev->iomem, PWR_INT_CLEAR, status);
if (unlikely(status & PWR_IRQ_COMMAND_NOT_ALLOWED))
drm_err(&ptdev->base, "PWR_IRQ: COMMAND_NOT_ALLOWED");
@@ -69,19 +70,19 @@ static void panthor_pwr_irq_handler(struct panthor_device *ptdev, u32 status)
}
spin_unlock(&ptdev->pwr->reqs_lock);
}
-PANTHOR_IRQ_HANDLER(pwr, PWR, panthor_pwr_irq_handler);
+PANTHOR_IRQ_HANDLER(pwr, panthor_pwr_irq_handler);
static void panthor_pwr_write_command(struct panthor_device *ptdev, u32 command, u64 args)
{
if (args)
- gpu_write64(ptdev, PWR_CMDARG, args);
+ gpu_write64(ptdev->iomem, PWR_CMDARG, args);
- gpu_write(ptdev, PWR_COMMAND, command);
+ gpu_write(ptdev->iomem, PWR_COMMAND, command);
}
static bool reset_irq_raised(struct panthor_device *ptdev)
{
- return gpu_read(ptdev, PWR_INT_RAWSTAT) & PWR_IRQ_RESET_COMPLETED;
+ return gpu_read(ptdev->iomem, PWR_INT_RAWSTAT) & PWR_IRQ_RESET_COMPLETED;
}
static bool reset_pending(struct panthor_device *ptdev)
@@ -96,7 +97,7 @@ static int panthor_pwr_reset(struct panthor_device *ptdev, u32 reset_cmd)
drm_WARN(&ptdev->base, 1, "Reset already pending");
} else {
ptdev->pwr->pending_reqs |= PWR_IRQ_RESET_COMPLETED;
- gpu_write(ptdev, PWR_INT_CLEAR, PWR_IRQ_RESET_COMPLETED);
+ gpu_write(ptdev->iomem, PWR_INT_CLEAR, PWR_IRQ_RESET_COMPLETED);
panthor_pwr_write_command(ptdev, reset_cmd, 0);
}
}
@@ -185,7 +186,7 @@ static int panthor_pwr_domain_wait_transition(struct panthor_device *ptdev, u32
u64 val;
int ret = 0;
- ret = gpu_read64_poll_timeout(ptdev, pwrtrans_reg, val, !(PWR_ALL_CORES_MASK & val), 100,
+ ret = gpu_read64_poll_timeout(ptdev->iomem, pwrtrans_reg, val, !(PWR_ALL_CORES_MASK & val), 100,
timeout_us);
if (ret) {
drm_err(&ptdev->base, "%s domain power in transition, pwrtrans(0x%llx)",
@@ -198,17 +199,17 @@ static int panthor_pwr_domain_wait_transition(struct panthor_device *ptdev, u32
static void panthor_pwr_debug_info_show(struct panthor_device *ptdev)
{
- drm_info(&ptdev->base, "GPU_FEATURES: 0x%016llx", gpu_read64(ptdev, GPU_FEATURES));
- drm_info(&ptdev->base, "PWR_STATUS: 0x%016llx", gpu_read64(ptdev, PWR_STATUS));
- drm_info(&ptdev->base, "L2_PRESENT: 0x%016llx", gpu_read64(ptdev, PWR_L2_PRESENT));
- drm_info(&ptdev->base, "L2_PWRTRANS: 0x%016llx", gpu_read64(ptdev, PWR_L2_PWRTRANS));
- drm_info(&ptdev->base, "L2_READY: 0x%016llx", gpu_read64(ptdev, PWR_L2_READY));
- drm_info(&ptdev->base, "TILER_PRESENT: 0x%016llx", gpu_read64(ptdev, PWR_TILER_PRESENT));
- drm_info(&ptdev->base, "TILER_PWRTRANS: 0x%016llx", gpu_read64(ptdev, PWR_TILER_PWRTRANS));
- drm_info(&ptdev->base, "TILER_READY: 0x%016llx", gpu_read64(ptdev, PWR_TILER_READY));
- drm_info(&ptdev->base, "SHADER_PRESENT: 0x%016llx", gpu_read64(ptdev, PWR_SHADER_PRESENT));
- drm_info(&ptdev->base, "SHADER_PWRTRANS: 0x%016llx", gpu_read64(ptdev, PWR_SHADER_PWRTRANS));
- drm_info(&ptdev->base, "SHADER_READY: 0x%016llx", gpu_read64(ptdev, PWR_SHADER_READY));
+ drm_info(&ptdev->base, "GPU_FEATURES: 0x%016llx", gpu_read64(ptdev->iomem, GPU_FEATURES));
+ drm_info(&ptdev->base, "PWR_STATUS: 0x%016llx", gpu_read64(ptdev->iomem, PWR_STATUS));
+ drm_info(&ptdev->base, "L2_PRESENT: 0x%016llx", gpu_read64(ptdev->iomem, PWR_L2_PRESENT));
+ drm_info(&ptdev->base, "L2_PWRTRANS: 0x%016llx", gpu_read64(ptdev->iomem, PWR_L2_PWRTRANS));
+ drm_info(&ptdev->base, "L2_READY: 0x%016llx", gpu_read64(ptdev->iomem, PWR_L2_READY));
+ drm_info(&ptdev->base, "TILER_PRESENT: 0x%016llx", gpu_read64(ptdev->iomem, PWR_TILER_PRESENT));
+ drm_info(&ptdev->base, "TILER_PWRTRANS: 0x%016llx", gpu_read64(ptdev->iomem, PWR_TILER_PWRTRANS));
+ drm_info(&ptdev->base, "TILER_READY: 0x%016llx", gpu_read64(ptdev->iomem, PWR_TILER_READY));
+ drm_info(&ptdev->base, "SHADER_PRESENT: 0x%016llx", gpu_read64(ptdev->iomem, PWR_SHADER_PRESENT));
+ drm_info(&ptdev->base, "SHADER_PWRTRANS: 0x%016llx", gpu_read64(ptdev->iomem, PWR_SHADER_PWRTRANS));
+ drm_info(&ptdev->base, "SHADER_READY: 0x%016llx", gpu_read64(ptdev->iomem, PWR_SHADER_READY));
}
static int panthor_pwr_domain_transition(struct panthor_device *ptdev, u32 cmd, u32 domain,
@@ -240,13 +241,13 @@ static int panthor_pwr_domain_transition(struct panthor_device *ptdev, u32 cmd,
return ret;
/* domain already in target state, return early */
- if ((gpu_read64(ptdev, ready_reg) & mask) == expected_val)
+ if ((gpu_read64(ptdev->iomem, ready_reg) & mask) == expected_val)
return 0;
panthor_pwr_write_command(ptdev, pwr_cmd, mask);
- ret = gpu_read64_poll_timeout(ptdev, ready_reg, val, (mask & val) == expected_val, 100,
- timeout_us);
+ ret = gpu_read64_poll_timeout(ptdev->iomem, ready_reg, val, (mask & val) == expected_val,
+ 100, timeout_us);
if (ret) {
drm_err(&ptdev->base,
"timeout waiting on %s power domain transition, cmd(0x%x), arg(0x%llx)",
@@ -279,7 +280,7 @@ static int panthor_pwr_domain_transition(struct panthor_device *ptdev, u32 cmd,
static int retract_domain(struct panthor_device *ptdev, u32 domain)
{
const u32 pwr_cmd = PWR_COMMAND_DEF(PWR_COMMAND_RETRACT, domain, 0);
- const u64 pwr_status = gpu_read64(ptdev, PWR_STATUS);
+ const u64 pwr_status = gpu_read64(ptdev->iomem, PWR_STATUS);
const u64 delegated_mask = PWR_STATUS_DOMAIN_DELEGATED(domain);
const u64 allow_mask = PWR_STATUS_DOMAIN_ALLOWED(domain);
u64 val;
@@ -288,8 +289,9 @@ static int retract_domain(struct panthor_device *ptdev, u32 domain)
if (drm_WARN_ON(&ptdev->base, domain == PWR_COMMAND_DOMAIN_L2))
return -EPERM;
- ret = gpu_read64_poll_timeout(ptdev, PWR_STATUS, val, !(PWR_STATUS_RETRACT_PENDING & val),
- 0, PWR_RETRACT_TIMEOUT_US);
+ ret = gpu_read64_poll_timeout(ptdev->iomem, PWR_STATUS, val,
+ !(PWR_STATUS_RETRACT_PENDING & val), 0,
+ PWR_RETRACT_TIMEOUT_US);
if (ret) {
drm_err(&ptdev->base, "%s domain retract pending", get_domain_name(domain));
return ret;
@@ -306,7 +308,7 @@ static int retract_domain(struct panthor_device *ptdev, u32 domain)
* On successful retraction
* allow-flag will be set with delegated-flag being cleared.
*/
- ret = gpu_read64_poll_timeout(ptdev, PWR_STATUS, val,
+ ret = gpu_read64_poll_timeout(ptdev->iomem, PWR_STATUS, val,
((delegated_mask | allow_mask) & val) == allow_mask, 10,
PWR_TRANSITION_TIMEOUT_US);
if (ret) {
@@ -333,7 +335,7 @@ static int retract_domain(struct panthor_device *ptdev, u32 domain)
static int delegate_domain(struct panthor_device *ptdev, u32 domain)
{
const u32 pwr_cmd = PWR_COMMAND_DEF(PWR_COMMAND_DELEGATE, domain, 0);
- const u64 pwr_status = gpu_read64(ptdev, PWR_STATUS);
+ const u64 pwr_status = gpu_read64(ptdev->iomem, PWR_STATUS);
const u64 allow_mask = PWR_STATUS_DOMAIN_ALLOWED(domain);
const u64 delegated_mask = PWR_STATUS_DOMAIN_DELEGATED(domain);
u64 val;
@@ -362,7 +364,7 @@ static int delegate_domain(struct panthor_device *ptdev, u32 domain)
* On successful delegation
* allow-flag will be cleared with delegated-flag being set.
*/
- ret = gpu_read64_poll_timeout(ptdev, PWR_STATUS, val,
+ ret = gpu_read64_poll_timeout(ptdev->iomem, PWR_STATUS, val,
((delegated_mask | allow_mask) & val) == delegated_mask,
10, PWR_TRANSITION_TIMEOUT_US);
if (ret) {
@@ -410,7 +412,7 @@ err_retract_shader:
*/
static int panthor_pwr_domain_force_off(struct panthor_device *ptdev, u32 domain)
{
- const u64 domain_ready = gpu_read64(ptdev, get_domain_ready_reg(domain));
+ const u64 domain_ready = gpu_read64(ptdev->iomem, get_domain_ready_reg(domain));
int ret;
/* Domain already powered down, early exit. */
@@ -433,7 +435,8 @@ void panthor_pwr_unplug(struct panthor_device *ptdev)
return;
/* Make sure the IRQ handler is not running after that point. */
- panthor_pwr_irq_suspend(&ptdev->pwr->irq);
+ if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev))
+ panthor_pwr_irq_suspend(&ptdev->pwr->irq);
/* Wake-up all waiters. */
spin_lock_irqsave(&ptdev->pwr->reqs_lock, flags);
@@ -462,7 +465,9 @@ int panthor_pwr_init(struct panthor_device *ptdev)
if (irq < 0)
return irq;
- err = panthor_request_pwr_irq(ptdev, &pwr->irq, irq, PWR_INTERRUPTS_MASK);
+ err = panthor_request_pwr_irq(
+ ptdev, &pwr->irq, irq, PWR_INTERRUPTS_MASK,
+ ptdev->iomem + PWR_CONTROL_BASE);
if (err)
return err;
@@ -471,7 +476,7 @@ int panthor_pwr_init(struct panthor_device *ptdev)
int panthor_pwr_reset_soft(struct panthor_device *ptdev)
{
- if (!(gpu_read64(ptdev, PWR_STATUS) & PWR_STATUS_ALLOW_SOFT_RESET)) {
+ if (!(gpu_read64(ptdev->iomem, PWR_STATUS) & PWR_STATUS_ALLOW_SOFT_RESET)) {
drm_err(&ptdev->base, "RESET_SOFT not allowed");
return -EOPNOTSUPP;
}
@@ -482,7 +487,7 @@ int panthor_pwr_reset_soft(struct panthor_device *ptdev)
void panthor_pwr_l2_power_off(struct panthor_device *ptdev)
{
const u64 l2_allow_mask = PWR_STATUS_DOMAIN_ALLOWED(PWR_COMMAND_DOMAIN_L2);
- const u64 pwr_status = gpu_read64(ptdev, PWR_STATUS);
+ const u64 pwr_status = gpu_read64(ptdev->iomem, PWR_STATUS);
/* Abort if L2 power off constraints are not satisfied */
if (!(pwr_status & l2_allow_mask)) {
@@ -508,7 +513,7 @@ void panthor_pwr_l2_power_off(struct panthor_device *ptdev)
int panthor_pwr_l2_power_on(struct panthor_device *ptdev)
{
- const u32 pwr_status = gpu_read64(ptdev, PWR_STATUS);
+ const u32 pwr_status = gpu_read64(ptdev->iomem, PWR_STATUS);
const u32 l2_allow_mask = PWR_STATUS_DOMAIN_ALLOWED(PWR_COMMAND_DOMAIN_L2);
int ret;
diff --git a/drivers/gpu/drm/panthor/panthor_pwr_regs.h b/drivers/gpu/drm/panthor/panthor_pwr_regs.h
new file mode 100644
index 000000000000..ad3e446971db
--- /dev/null
+++ b/drivers/gpu/drm/panthor/panthor_pwr_regs.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+/* Copyright 2026 ARM Limited. All rights reserved. */
+
+#ifndef __PANTHOR_PWR_REGS_H__
+#define __PANTHOR_PWR_REGS_H__
+
+#define PWR_CONTROL_BASE 0x800
+#define PWR_CTRL_REG(x) (PWR_CONTROL_BASE + (x))
+
+#define PWR_INT_RAWSTAT PWR_CTRL_REG(0x0)
+#define PWR_INT_CLEAR PWR_CTRL_REG(0x4)
+#define PWR_INT_MASK PWR_CTRL_REG(0x8)
+#define PWR_INT_STAT PWR_CTRL_REG(0xc)
+#define PWR_IRQ_POWER_CHANGED_SINGLE BIT(0)
+#define PWR_IRQ_POWER_CHANGED_ALL BIT(1)
+#define PWR_IRQ_DELEGATION_CHANGED BIT(2)
+#define PWR_IRQ_RESET_COMPLETED BIT(3)
+#define PWR_IRQ_RETRACT_COMPLETED BIT(4)
+#define PWR_IRQ_INSPECT_COMPLETED BIT(5)
+#define PWR_IRQ_COMMAND_NOT_ALLOWED BIT(30)
+#define PWR_IRQ_COMMAND_INVALID BIT(31)
+
+#define PWR_STATUS PWR_CTRL_REG(0x20)
+#define PWR_STATUS_ALLOW_L2 BIT_U64(0)
+#define PWR_STATUS_ALLOW_TILER BIT_U64(1)
+#define PWR_STATUS_ALLOW_SHADER BIT_U64(8)
+#define PWR_STATUS_ALLOW_BASE BIT_U64(14)
+#define PWR_STATUS_ALLOW_STACK BIT_U64(15)
+#define PWR_STATUS_DOMAIN_ALLOWED(x) BIT_U64(x)
+#define PWR_STATUS_DELEGATED_L2 BIT_U64(16)
+#define PWR_STATUS_DELEGATED_TILER BIT_U64(17)
+#define PWR_STATUS_DELEGATED_SHADER BIT_U64(24)
+#define PWR_STATUS_DELEGATED_BASE BIT_U64(30)
+#define PWR_STATUS_DELEGATED_STACK BIT_U64(31)
+#define PWR_STATUS_DELEGATED_SHIFT 16
+#define PWR_STATUS_DOMAIN_DELEGATED(x) BIT_U64((x) + PWR_STATUS_DELEGATED_SHIFT)
+#define PWR_STATUS_ALLOW_SOFT_RESET BIT_U64(33)
+#define PWR_STATUS_ALLOW_FAST_RESET BIT_U64(34)
+#define PWR_STATUS_POWER_PENDING BIT_U64(41)
+#define PWR_STATUS_RESET_PENDING BIT_U64(42)
+#define PWR_STATUS_RETRACT_PENDING BIT_U64(43)
+#define PWR_STATUS_INSPECT_PENDING BIT_U64(44)
+
+#define PWR_COMMAND PWR_CTRL_REG(0x28)
+#define PWR_COMMAND_POWER_UP 0x10
+#define PWR_COMMAND_POWER_DOWN 0x11
+#define PWR_COMMAND_DELEGATE 0x20
+#define PWR_COMMAND_RETRACT 0x21
+#define PWR_COMMAND_RESET_SOFT 0x31
+#define PWR_COMMAND_RESET_FAST 0x32
+#define PWR_COMMAND_INSPECT 0xF0
+#define PWR_COMMAND_DOMAIN_L2 0
+#define PWR_COMMAND_DOMAIN_TILER 1
+#define PWR_COMMAND_DOMAIN_SHADER 8
+#define PWR_COMMAND_DOMAIN_BASE 14
+#define PWR_COMMAND_DOMAIN_STACK 15
+#define PWR_COMMAND_SUBDOMAIN_RTU BIT(0)
+#define PWR_COMMAND_DEF(cmd, domain, subdomain) \
+ (((subdomain) << 16) | ((domain) << 8) | (cmd))
+
+#define PWR_CMDARG PWR_CTRL_REG(0x30)
+
+#define PWR_L2_PRESENT PWR_CTRL_REG(0x100)
+#define PWR_L2_READY PWR_CTRL_REG(0x108)
+#define PWR_L2_PWRTRANS PWR_CTRL_REG(0x110)
+#define PWR_L2_PWRACTIVE PWR_CTRL_REG(0x118)
+#define PWR_TILER_PRESENT PWR_CTRL_REG(0x140)
+#define PWR_TILER_READY PWR_CTRL_REG(0x148)
+#define PWR_TILER_PWRTRANS PWR_CTRL_REG(0x150)
+#define PWR_TILER_PWRACTIVE PWR_CTRL_REG(0x158)
+#define PWR_SHADER_PRESENT PWR_CTRL_REG(0x200)
+#define PWR_SHADER_READY PWR_CTRL_REG(0x208)
+#define PWR_SHADER_PWRTRANS PWR_CTRL_REG(0x210)
+#define PWR_SHADER_PWRACTIVE PWR_CTRL_REG(0x218)
+#define PWR_BASE_PRESENT PWR_CTRL_REG(0x380)
+#define PWR_BASE_READY PWR_CTRL_REG(0x388)
+#define PWR_BASE_PWRTRANS PWR_CTRL_REG(0x390)
+#define PWR_BASE_PWRACTIVE PWR_CTRL_REG(0x398)
+#define PWR_STACK_PRESENT PWR_CTRL_REG(0x3c0)
+#define PWR_STACK_READY PWR_CTRL_REG(0x3c8)
+#define PWR_STACK_PWRTRANS PWR_CTRL_REG(0x3d0)
+
+#endif /* __PANTHOR_PWR_REGS_H__ */
diff --git a/drivers/gpu/drm/panthor/panthor_regs.h b/drivers/gpu/drm/panthor/panthor_regs.h
deleted file mode 100644
index 08bf06c452d6..000000000000
--- a/drivers/gpu/drm/panthor/panthor_regs.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 or MIT */
-/* Copyright 2018 Marty E. Plummer <hanetzer@startmail.com> */
-/* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
-/* Copyright 2023 Collabora ltd. */
-/*
- * Register definitions based on mali_kbase_gpu_regmap.h and
- * mali_kbase_gpu_regmap_csf.h
- * (C) COPYRIGHT 2010-2022 ARM Limited. All rights reserved.
- */
-#ifndef __PANTHOR_REGS_H__
-#define __PANTHOR_REGS_H__
-
-#define GPU_ID 0x0
-#define GPU_ARCH_MAJOR(x) ((x) >> 28)
-#define GPU_ARCH_MINOR(x) (((x) & GENMASK(27, 24)) >> 24)
-#define GPU_ARCH_REV(x) (((x) & GENMASK(23, 20)) >> 20)
-#define GPU_PROD_MAJOR(x) (((x) & GENMASK(19, 16)) >> 16)
-#define GPU_VER_MAJOR(x) (((x) & GENMASK(15, 12)) >> 12)
-#define GPU_VER_MINOR(x) (((x) & GENMASK(11, 4)) >> 4)
-#define GPU_VER_STATUS(x) ((x) & GENMASK(3, 0))
-
-#define GPU_L2_FEATURES 0x4
-#define GPU_L2_FEATURES_LINE_SIZE(x) (1 << ((x) & GENMASK(7, 0)))
-
-#define GPU_CORE_FEATURES 0x8
-
-#define GPU_TILER_FEATURES 0xC
-#define GPU_MEM_FEATURES 0x10
-#define GROUPS_L2_COHERENT BIT(0)
-
-#define GPU_MMU_FEATURES 0x14
-#define GPU_MMU_FEATURES_VA_BITS(x) ((x) & GENMASK(7, 0))
-#define GPU_MMU_FEATURES_PA_BITS(x) (((x) >> 8) & GENMASK(7, 0))
-#define GPU_AS_PRESENT 0x18
-#define GPU_CSF_ID 0x1C
-
-#define GPU_INT_RAWSTAT 0x20
-#define GPU_INT_CLEAR 0x24
-#define GPU_INT_MASK 0x28
-#define GPU_INT_STAT 0x2c
-#define GPU_IRQ_FAULT BIT(0)
-#define GPU_IRQ_PROTM_FAULT BIT(1)
-#define GPU_IRQ_RESET_COMPLETED BIT(8)
-#define GPU_IRQ_POWER_CHANGED BIT(9)
-#define GPU_IRQ_POWER_CHANGED_ALL BIT(10)
-#define GPU_IRQ_CLEAN_CACHES_COMPLETED BIT(17)
-#define GPU_IRQ_DOORBELL_MIRROR BIT(18)
-#define GPU_IRQ_MCU_STATUS_CHANGED BIT(19)
-#define GPU_CMD 0x30
-#define GPU_CMD_DEF(type, payload) ((type) | ((payload) << 8))
-#define GPU_SOFT_RESET GPU_CMD_DEF(1, 1)
-#define GPU_HARD_RESET GPU_CMD_DEF(1, 2)
-#define CACHE_CLEAN BIT(0)
-#define CACHE_INV BIT(1)
-#define GPU_FLUSH_CACHES(l2, lsc, oth) \
- GPU_CMD_DEF(4, ((l2) << 0) | ((lsc) << 4) | ((oth) << 8))
-
-#define GPU_STATUS 0x34
-#define GPU_STATUS_ACTIVE BIT(0)
-#define GPU_STATUS_PWR_ACTIVE BIT(1)
-#define GPU_STATUS_PAGE_FAULT BIT(4)
-#define GPU_STATUS_PROTM_ACTIVE BIT(7)
-#define GPU_STATUS_DBG_ENABLED BIT(8)
-
-#define GPU_FAULT_STATUS 0x3C
-#define GPU_FAULT_ADDR 0x40
-#define GPU_L2_CONFIG 0x48
-#define GPU_L2_CONFIG_ASN_HASH_ENABLE BIT(24)
-
-#define GPU_PWR_KEY 0x50
-#define GPU_PWR_KEY_UNLOCK 0x2968A819
-#define GPU_PWR_OVERRIDE0 0x54
-#define GPU_PWR_OVERRIDE1 0x58
-
-#define GPU_FEATURES 0x60
-#define GPU_FEATURES_RAY_INTERSECTION BIT(2)
-#define GPU_FEATURES_RAY_TRAVERSAL BIT(5)
-
-#define GPU_TIMESTAMP_OFFSET 0x88
-#define GPU_CYCLE_COUNT 0x90
-#define GPU_TIMESTAMP 0x98
-
-#define GPU_THREAD_MAX_THREADS 0xA0
-#define GPU_THREAD_MAX_WORKGROUP_SIZE 0xA4
-#define GPU_THREAD_MAX_BARRIER_SIZE 0xA8
-#define GPU_THREAD_FEATURES 0xAC
-
-#define GPU_TEXTURE_FEATURES(n) (0xB0 + ((n) * 4))
-
-#define GPU_SHADER_PRESENT 0x100
-#define GPU_TILER_PRESENT 0x110
-#define GPU_L2_PRESENT 0x120
-
-#define SHADER_READY 0x140
-#define TILER_READY 0x150
-#define L2_READY 0x160
-
-#define SHADER_PWRON 0x180
-#define TILER_PWRON 0x190
-#define L2_PWRON 0x1A0
-
-#define SHADER_PWROFF 0x1C0
-#define TILER_PWROFF 0x1D0
-#define L2_PWROFF 0x1E0
-
-#define SHADER_PWRTRANS 0x200
-#define TILER_PWRTRANS 0x210
-#define L2_PWRTRANS 0x220
-
-#define SHADER_PWRACTIVE 0x240
-#define TILER_PWRACTIVE 0x250
-#define L2_PWRACTIVE 0x260
-
-#define GPU_REVID 0x280
-
-#define GPU_ASN_HASH(n) (0x2C0 + ((n) * 4))
-
-#define GPU_COHERENCY_FEATURES 0x300
-#define GPU_COHERENCY_PROT_BIT(name) BIT(GPU_COHERENCY_ ## name)
-
-#define GPU_COHERENCY_PROTOCOL 0x304
-#define GPU_COHERENCY_ACE_LITE 0
-#define GPU_COHERENCY_ACE 1
-#define GPU_COHERENCY_NONE 31
-
-#define MCU_CONTROL 0x700
-#define MCU_CONTROL_ENABLE 1
-#define MCU_CONTROL_AUTO 2
-#define MCU_CONTROL_DISABLE 0
-
-#define MCU_STATUS 0x704
-#define MCU_STATUS_DISABLED 0
-#define MCU_STATUS_ENABLED 1
-#define MCU_STATUS_HALT 2
-#define MCU_STATUS_FATAL 3
-
-/* Job Control regs */
-#define JOB_INT_RAWSTAT 0x1000
-#define JOB_INT_CLEAR 0x1004
-#define JOB_INT_MASK 0x1008
-#define JOB_INT_STAT 0x100c
-#define JOB_INT_GLOBAL_IF BIT(31)
-#define JOB_INT_CSG_IF(x) BIT(x)
-
-/* MMU regs */
-#define MMU_INT_RAWSTAT 0x2000
-#define MMU_INT_CLEAR 0x2004
-#define MMU_INT_MASK 0x2008
-#define MMU_INT_STAT 0x200c
-
-/* AS_COMMAND register commands */
-
-#define MMU_BASE 0x2400
-#define MMU_AS_SHIFT 6
-#define MMU_AS(as) (MMU_BASE + ((as) << MMU_AS_SHIFT))
-
-#define AS_TRANSTAB(as) (MMU_AS(as) + 0x0)
-#define AS_MEMATTR(as) (MMU_AS(as) + 0x8)
-#define AS_MEMATTR_AARCH64_INNER_ALLOC_IMPL (2 << 2)
-#define AS_MEMATTR_AARCH64_INNER_ALLOC_EXPL(w, r) ((3 << 2) | \
- ((w) ? BIT(0) : 0) | \
- ((r) ? BIT(1) : 0))
-#define AS_MEMATTR_AARCH64_SH_MIDGARD_INNER (0 << 4)
-#define AS_MEMATTR_AARCH64_SH_CPU_INNER (1 << 4)
-#define AS_MEMATTR_AARCH64_SH_CPU_INNER_SHADER_COH (2 << 4)
-#define AS_MEMATTR_AARCH64_SHARED (0 << 6)
-#define AS_MEMATTR_AARCH64_INNER_OUTER_NC (1 << 6)
-#define AS_MEMATTR_AARCH64_INNER_OUTER_WB (2 << 6)
-#define AS_MEMATTR_AARCH64_FAULT (3 << 6)
-#define AS_LOCKADDR(as) (MMU_AS(as) + 0x10)
-#define AS_COMMAND(as) (MMU_AS(as) + 0x18)
-#define AS_COMMAND_NOP 0
-#define AS_COMMAND_UPDATE 1
-#define AS_COMMAND_LOCK 2
-#define AS_COMMAND_UNLOCK 3
-#define AS_COMMAND_FLUSH_PT 4
-#define AS_COMMAND_FLUSH_MEM 5
-#define AS_LOCK_REGION_MIN_SIZE (1ULL << 15)
-#define AS_FAULTSTATUS(as) (MMU_AS(as) + 0x1C)
-#define AS_FAULTSTATUS_ACCESS_TYPE_MASK (0x3 << 8)
-#define AS_FAULTSTATUS_ACCESS_TYPE_ATOMIC (0x0 << 8)
-#define AS_FAULTSTATUS_ACCESS_TYPE_EX (0x1 << 8)
-#define AS_FAULTSTATUS_ACCESS_TYPE_READ (0x2 << 8)
-#define AS_FAULTSTATUS_ACCESS_TYPE_WRITE (0x3 << 8)
-#define AS_FAULTADDRESS(as) (MMU_AS(as) + 0x20)
-#define AS_STATUS(as) (MMU_AS(as) + 0x28)
-#define AS_STATUS_AS_ACTIVE BIT(0)
-#define AS_TRANSCFG(as) (MMU_AS(as) + 0x30)
-#define AS_TRANSCFG_ADRMODE_UNMAPPED (1 << 0)
-#define AS_TRANSCFG_ADRMODE_IDENTITY (2 << 0)
-#define AS_TRANSCFG_ADRMODE_AARCH64_4K (6 << 0)
-#define AS_TRANSCFG_ADRMODE_AARCH64_64K (8 << 0)
-#define AS_TRANSCFG_INA_BITS(x) ((x) << 6)
-#define AS_TRANSCFG_OUTA_BITS(x) ((x) << 14)
-#define AS_TRANSCFG_SL_CONCAT BIT(22)
-#define AS_TRANSCFG_PTW_MEMATTR_NC (1 << 24)
-#define AS_TRANSCFG_PTW_MEMATTR_WB (2 << 24)
-#define AS_TRANSCFG_PTW_SH_NS (0 << 28)
-#define AS_TRANSCFG_PTW_SH_OS (2 << 28)
-#define AS_TRANSCFG_PTW_SH_IS (3 << 28)
-#define AS_TRANSCFG_PTW_RA BIT(30)
-#define AS_TRANSCFG_DISABLE_HIER_AP BIT(33)
-#define AS_TRANSCFG_DISABLE_AF_FAULT BIT(34)
-#define AS_TRANSCFG_WXN BIT(35)
-#define AS_TRANSCFG_XREADABLE BIT(36)
-#define AS_FAULTEXTRA(as) (MMU_AS(as) + 0x38)
-
-#define CSF_GPU_LATEST_FLUSH_ID 0x10000
-
-#define CSF_DOORBELL(i) (0x80000 + ((i) * 0x10000))
-#define CSF_GLB_DOORBELL_ID 0
-
-/* PWR Control registers */
-
-#define PWR_CONTROL_BASE 0x800
-#define PWR_CTRL_REG(x) (PWR_CONTROL_BASE + (x))
-
-#define PWR_INT_RAWSTAT PWR_CTRL_REG(0x0)
-#define PWR_INT_CLEAR PWR_CTRL_REG(0x4)
-#define PWR_INT_MASK PWR_CTRL_REG(0x8)
-#define PWR_INT_STAT PWR_CTRL_REG(0xc)
-#define PWR_IRQ_POWER_CHANGED_SINGLE BIT(0)
-#define PWR_IRQ_POWER_CHANGED_ALL BIT(1)
-#define PWR_IRQ_DELEGATION_CHANGED BIT(2)
-#define PWR_IRQ_RESET_COMPLETED BIT(3)
-#define PWR_IRQ_RETRACT_COMPLETED BIT(4)
-#define PWR_IRQ_INSPECT_COMPLETED BIT(5)
-#define PWR_IRQ_COMMAND_NOT_ALLOWED BIT(30)
-#define PWR_IRQ_COMMAND_INVALID BIT(31)
-
-#define PWR_STATUS PWR_CTRL_REG(0x20)
-#define PWR_STATUS_ALLOW_L2 BIT_U64(0)
-#define PWR_STATUS_ALLOW_TILER BIT_U64(1)
-#define PWR_STATUS_ALLOW_SHADER BIT_U64(8)
-#define PWR_STATUS_ALLOW_BASE BIT_U64(14)
-#define PWR_STATUS_ALLOW_STACK BIT_U64(15)
-#define PWR_STATUS_DOMAIN_ALLOWED(x) BIT_U64(x)
-#define PWR_STATUS_DELEGATED_L2 BIT_U64(16)
-#define PWR_STATUS_DELEGATED_TILER BIT_U64(17)
-#define PWR_STATUS_DELEGATED_SHADER BIT_U64(24)
-#define PWR_STATUS_DELEGATED_BASE BIT_U64(30)
-#define PWR_STATUS_DELEGATED_STACK BIT_U64(31)
-#define PWR_STATUS_DELEGATED_SHIFT 16
-#define PWR_STATUS_DOMAIN_DELEGATED(x) BIT_U64((x) + PWR_STATUS_DELEGATED_SHIFT)
-#define PWR_STATUS_ALLOW_SOFT_RESET BIT_U64(33)
-#define PWR_STATUS_ALLOW_FAST_RESET BIT_U64(34)
-#define PWR_STATUS_POWER_PENDING BIT_U64(41)
-#define PWR_STATUS_RESET_PENDING BIT_U64(42)
-#define PWR_STATUS_RETRACT_PENDING BIT_U64(43)
-#define PWR_STATUS_INSPECT_PENDING BIT_U64(44)
-
-#define PWR_COMMAND PWR_CTRL_REG(0x28)
-#define PWR_COMMAND_POWER_UP 0x10
-#define PWR_COMMAND_POWER_DOWN 0x11
-#define PWR_COMMAND_DELEGATE 0x20
-#define PWR_COMMAND_RETRACT 0x21
-#define PWR_COMMAND_RESET_SOFT 0x31
-#define PWR_COMMAND_RESET_FAST 0x32
-#define PWR_COMMAND_INSPECT 0xF0
-#define PWR_COMMAND_DOMAIN_L2 0
-#define PWR_COMMAND_DOMAIN_TILER 1
-#define PWR_COMMAND_DOMAIN_SHADER 8
-#define PWR_COMMAND_DOMAIN_BASE 14
-#define PWR_COMMAND_DOMAIN_STACK 15
-#define PWR_COMMAND_SUBDOMAIN_RTU BIT(0)
-#define PWR_COMMAND_DEF(cmd, domain, subdomain) \
- (((subdomain) << 16) | ((domain) << 8) | (cmd))
-
-#define PWR_CMDARG PWR_CTRL_REG(0x30)
-
-#define PWR_L2_PRESENT PWR_CTRL_REG(0x100)
-#define PWR_L2_READY PWR_CTRL_REG(0x108)
-#define PWR_L2_PWRTRANS PWR_CTRL_REG(0x110)
-#define PWR_L2_PWRACTIVE PWR_CTRL_REG(0x118)
-#define PWR_TILER_PRESENT PWR_CTRL_REG(0x140)
-#define PWR_TILER_READY PWR_CTRL_REG(0x148)
-#define PWR_TILER_PWRTRANS PWR_CTRL_REG(0x150)
-#define PWR_TILER_PWRACTIVE PWR_CTRL_REG(0x158)
-#define PWR_SHADER_PRESENT PWR_CTRL_REG(0x200)
-#define PWR_SHADER_READY PWR_CTRL_REG(0x208)
-#define PWR_SHADER_PWRTRANS PWR_CTRL_REG(0x210)
-#define PWR_SHADER_PWRACTIVE PWR_CTRL_REG(0x218)
-#define PWR_BASE_PRESENT PWR_CTRL_REG(0x380)
-#define PWR_BASE_READY PWR_CTRL_REG(0x388)
-#define PWR_BASE_PWRTRANS PWR_CTRL_REG(0x390)
-#define PWR_BASE_PWRACTIVE PWR_CTRL_REG(0x398)
-#define PWR_STACK_PRESENT PWR_CTRL_REG(0x3c0)
-#define PWR_STACK_READY PWR_CTRL_REG(0x3c8)
-#define PWR_STACK_PWRTRANS PWR_CTRL_REG(0x3d0)
-
-#endif
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 2fe04d0f0e3a..b09953ac0bd6 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -28,11 +28,12 @@
#include "panthor_devfreq.h"
#include "panthor_device.h"
#include "panthor_fw.h"
+#include "panthor_fw_regs.h"
#include "panthor_gem.h"
#include "panthor_gpu.h"
+#include "panthor_gpu_regs.h"
#include "panthor_heap.h"
#include "panthor_mmu.h"
-#include "panthor_regs.h"
#include "panthor_sched.h"
/**
@@ -1057,7 +1058,8 @@ group_unbind_locked(struct panthor_group *group)
/* Tiler OOM events will be re-issued next time the group is scheduled. */
atomic_set(&group->tiler_oom, 0);
- cancel_work(&group->tiler_oom_work);
+ if (cancel_work(&group->tiler_oom_work))
+ group_put(group);
for (u32 i = 0; i < group->queue_count; i++)
group->queues[i]->doorbell_id = -1;
@@ -1151,15 +1153,14 @@ queue_suspend_timeout_locked(struct panthor_queue *queue)
static void
queue_suspend_timeout(struct panthor_queue *queue)
{
- spin_lock(&queue->fence_ctx.lock);
+ guard(spinlock_irqsave)(&queue->fence_ctx.lock);
queue_suspend_timeout_locked(queue);
- spin_unlock(&queue->fence_ctx.lock);
}
static void
queue_resume_timeout(struct panthor_queue *queue)
{
- spin_lock(&queue->fence_ctx.lock);
+ guard(spinlock_irqsave)(&queue->fence_ctx.lock);
if (queue_timeout_is_suspended(queue)) {
mod_delayed_work(queue->scheduler.timeout_wq,
@@ -1168,8 +1169,6 @@ queue_resume_timeout(struct panthor_queue *queue)
queue->timeout.remaining = MAX_SCHEDULE_TIMEOUT;
}
-
- spin_unlock(&queue->fence_ctx.lock);
}
/**
@@ -1542,7 +1541,7 @@ cs_slot_process_fault_event_locked(struct panthor_device *ptdev,
u64 cs_extract = queue->iface.output->extract;
struct panthor_job *job;
- spin_lock(&queue->fence_ctx.lock);
+ guard(spinlock_irqsave)(&queue->fence_ctx.lock);
list_for_each_entry(job, &queue->fence_ctx.in_flight_jobs, node) {
if (cs_extract >= job->ringbuf.end)
continue;
@@ -1552,7 +1551,6 @@ cs_slot_process_fault_event_locked(struct panthor_device *ptdev,
dma_fence_set_error(job->done_fence, -EINVAL);
}
- spin_unlock(&queue->fence_ctx.lock);
}
if (group) {
@@ -1604,7 +1602,10 @@ static int group_process_tiler_oom(struct panthor_group *group, u32 cs_id)
if (unlikely(csg_id < 0))
return 0;
- if (IS_ERR(heaps) || frag_end > vt_end || vt_end >= vt_start) {
+ if (IS_ERR(heaps)) {
+ ret = -EINVAL;
+ heaps = NULL;
+ } else if (frag_end > vt_end || vt_end >= vt_start) {
ret = -EINVAL;
} else {
/* We do the allocation without holding the scheduler lock to avoid
@@ -2181,13 +2182,13 @@ group_term_post_processing(struct panthor_group *group)
if (!queue)
continue;
- spin_lock(&queue->fence_ctx.lock);
- list_for_each_entry_safe(job, tmp, &queue->fence_ctx.in_flight_jobs, node) {
- list_move_tail(&job->node, &faulty_jobs);
- dma_fence_set_error(job->done_fence, err);
- dma_fence_signal_locked(job->done_fence);
+ scoped_guard(spinlock_irqsave, &queue->fence_ctx.lock) {
+ list_for_each_entry_safe(job, tmp, &queue->fence_ctx.in_flight_jobs, node) {
+ list_move_tail(&job->node, &faulty_jobs);
+ dma_fence_set_error(job->done_fence, err);
+ dma_fence_signal_locked(job->done_fence);
+ }
}
- spin_unlock(&queue->fence_ctx.lock);
/* Manually update the syncobj seqno to unblock waiters. */
syncobj = group->syncobjs->kmap + (i * sizeof(*syncobj));
@@ -2366,7 +2367,13 @@ tick_ctx_apply(struct panthor_scheduler *sched, struct panthor_sched_tick_ctx *c
csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id);
csg_slot = &sched->csg_slots[csg_id];
- group_bind_locked(group, csg_id);
+ ret = group_bind_locked(group, csg_id);
+ if (ret) {
+ panthor_device_schedule_reset(ptdev);
+ ctx->csg_upd_failed_mask |= BIT(csg_id);
+ return;
+ }
+
csg_slot_prog_locked(ptdev, csg_id, new_csg_prio--);
csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id,
group->state == PANTHOR_CS_GROUP_SUSPENDED ?
@@ -2666,7 +2673,14 @@ static void sched_resume_tick(struct panthor_device *ptdev)
else
delay_jiffies = 0;
- sched_queue_delayed_work(sched, tick, delay_jiffies);
+ /* We schedule immediate ticks when we need to process events on CSGs,
+ * but those don't change the resched_target because we want the other
+ * groups to stay scheduled for the remaining of the GPU timeslot they
+ * were given. Make sure those immediate ticks don't get overruled by
+ * a sched_queue_delayed_work() that would delay the tick execution.
+ */
+ if (!delayed_work_pending(&sched->tick_work))
+ sched_queue_delayed_work(sched, tick, delay_jiffies);
}
static void group_schedule_locked(struct panthor_group *group, u32 queue_mask)
@@ -3046,39 +3060,39 @@ static bool queue_check_job_completion(struct panthor_queue *queue)
LIST_HEAD(done_jobs);
cookie = dma_fence_begin_signalling();
- spin_lock(&queue->fence_ctx.lock);
- list_for_each_entry_safe(job, job_tmp, &queue->fence_ctx.in_flight_jobs, node) {
- if (!syncobj) {
- struct panthor_group *group = job->group;
+ scoped_guard(spinlock_irqsave, &queue->fence_ctx.lock) {
+ list_for_each_entry_safe(job, job_tmp, &queue->fence_ctx.in_flight_jobs, node) {
+ if (!syncobj) {
+ struct panthor_group *group = job->group;
- syncobj = group->syncobjs->kmap +
- (job->queue_idx * sizeof(*syncobj));
- }
+ syncobj = group->syncobjs->kmap +
+ (job->queue_idx * sizeof(*syncobj));
+ }
- if (syncobj->seqno < job->done_fence->seqno)
- break;
+ if (syncobj->seqno < job->done_fence->seqno)
+ break;
- list_move_tail(&job->node, &done_jobs);
- dma_fence_signal_locked(job->done_fence);
- }
+ list_move_tail(&job->node, &done_jobs);
+ dma_fence_signal_locked(job->done_fence);
+ }
- if (list_empty(&queue->fence_ctx.in_flight_jobs)) {
- /* If we have no job left, we cancel the timer, and reset remaining
- * time to its default so it can be restarted next time
- * queue_resume_timeout() is called.
- */
- queue_suspend_timeout_locked(queue);
+ if (list_empty(&queue->fence_ctx.in_flight_jobs)) {
+ /* If we have no job left, we cancel the timer, and reset remaining
+ * time to its default so it can be restarted next time
+ * queue_resume_timeout() is called.
+ */
+ queue_suspend_timeout_locked(queue);
- /* If there's no job pending, we consider it progress to avoid a
- * spurious timeout if the timeout handler and the sync update
- * handler raced.
- */
- progress = true;
- } else if (!list_empty(&done_jobs)) {
- queue_reset_timeout_locked(queue);
- progress = true;
+ /* If there's no job pending, we consider it progress to avoid a
+ * spurious timeout if the timeout handler and the sync update
+ * handler raced.
+ */
+ progress = true;
+ } else if (!list_empty(&done_jobs)) {
+ queue_reset_timeout_locked(queue);
+ progress = true;
+ }
}
- spin_unlock(&queue->fence_ctx.lock);
dma_fence_end_signalling(cookie);
list_for_each_entry_safe(job, job_tmp, &done_jobs, node) {
@@ -3343,9 +3357,8 @@ queue_run_job(struct drm_sched_job *sched_job)
job->ringbuf.end = job->ringbuf.start + (instrs.count * sizeof(u64));
panthor_job_get(&job->base);
- spin_lock(&queue->fence_ctx.lock);
- list_add_tail(&job->node, &queue->fence_ctx.in_flight_jobs);
- spin_unlock(&queue->fence_ctx.lock);
+ scoped_guard(spinlock_irqsave, &queue->fence_ctx.lock)
+ list_add_tail(&job->node, &queue->fence_ctx.in_flight_jobs);
/* Make sure the ring buffer is updated before the INSERT
* register.
@@ -3370,7 +3383,7 @@ queue_run_job(struct drm_sched_job *sched_job)
if (resume_tick)
sched_resume_tick(ptdev);
- gpu_write(ptdev, CSF_DOORBELL(queue->doorbell_id), 1);
+ gpu_write(ptdev->iomem, CSF_DOORBELL(queue->doorbell_id), 1);
if (!sched->pm.has_ref &&
!(group->blocked_queues & BIT(job->queue_idx))) {
pm_runtime_get(ptdev->base.dev);