From: Karunika Choo <karunika.choo@arm.com>
To: dri-devel@lists.freedesktop.org
Cc: nd@arm.com, Boris Brezillon <boris.brezillon@collabora.com>,
Steven Price <steven.price@arm.com>,
Liviu Dudau <liviu.dudau@arm.com>,
linux-kernel@vger.kernel.org,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>
Subject: [PATCH v1 19/27] drm/panthor: Add AW assignment tracking
Date: Tue, 22 Sep 2026 21:45:13 +0100 [thread overview]
Message-ID: <20260922204535.2850094-20-karunika.choo@arm.com> (raw)
In-Reply-To: <20260922204535.2850094-1-karunika.choo@arm.com>
Track the scheduler assignment for each access window using the default
access-window masks parsed from device properties.
Use the mapping to route request, idle, stopped, grant, stop, and close
events through the scheduler associated with the access window, and keep
schedulers disabled while they have no assigned access windows.
Signed-off-by: Karunika Choo <karunika.choo@arm.com>
---
.../panthor/arbitration/panthor_arbitration.h | 15 ++
.../arbitration/panthor_arbitration_drv.c | 201 ++++++++++++++++--
.../arbitration/panthor_arbitration_sched.c | 2 +
.../arbitration/panthor_arbitration_sched.h | 3 +
4 files changed, 209 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/panthor/arbitration/panthor_arbitration.h b/drivers/gpu/drm/panthor/arbitration/panthor_arbitration.h
index 149221333eb1e..e1d569158ac6c 100644
--- a/drivers/gpu/drm/panthor/arbitration/panthor_arbitration.h
+++ b/drivers/gpu/drm/panthor/arbitration/panthor_arbitration.h
@@ -7,6 +7,7 @@
#include <linux/ioport.h>
#include <linux/fwnode.h>
#include <linux/types.h>
+#include <linux/mutex.h>
struct device;
struct panthor_arbitration_sched;
@@ -26,6 +27,11 @@ struct panthor_arbitration_resource {
u32 id;
};
+struct panthor_arbitration_dt_info {
+ /** @default_aw_masks: Default per-partition AW assignments */
+ u32 default_aw_masks[AM_ARB_MAX_PC_COUNT];
+};
+
/**
* struct panthor_arbitration - Arbitration device
*/
@@ -44,6 +50,15 @@ struct panthor_arbitration {
/** @sched: Pointer to scheduler data. 1 sched per partition */
struct panthor_arbitration_sched *sched[AM_ARB_MAX_PC_COUNT];
+
+ /** @dt_info: Properties parsed from the device tree */
+ struct panthor_arbitration_dt_info dt_info;
+
+ /** @assignment_lock: Protects AW and slice assignment */
+ struct mutex assignment_lock;
+
+ /** @aw_sched_map: Tracks assignment of AW to sched instance */
+ s8 aw_sched_map[AM_ARB_MAX_AW_COUNT];
};
int panthor_arbitration_parse_resource(struct device *dev,
diff --git a/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_drv.c b/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_drv.c
index 723cf605e16a3..f44cd45ea342e 100644
--- a/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_drv.c
+++ b/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_drv.c
@@ -1,11 +1,13 @@
// SPDX-License-Identifier: GPL-2.0 or MIT
/* Copyright 2026 ARM Limited. All rights reserved. */
+#include <linux/bits.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/types.h>
#include <linux/of_address.h>
#include <linux/of.h>
@@ -17,8 +19,27 @@
#define PANTHOR_PM_AUTOSUSPEND_DELAY_MS 100
+#define DT_ASSIGNED_AW "arm,access-window-mask"
#define DT_ID "arm,id"
+static int to_assigned_sched_idx(struct panthor_arbitration *adev, u8 aw_id)
+{
+ int idx = -1;
+
+ if (aw_id >= AM_ARB_MAX_AW_COUNT) {
+ dev_err(adev->dev, "Invalid AW ID (%u)", aw_id);
+ return -EINVAL;
+ }
+
+ idx = READ_ONCE(adev->aw_sched_map[aw_id]);
+ if (idx < 0 || idx >= AM_ARB_MAX_PC_COUNT || !adev->sched[idx]) {
+ dev_warn(adev->dev, "AW%u not assigned to any sched", aw_id);
+ return -ENOENT;
+ }
+
+ return idx;
+};
+
int panthor_arbitration_parse_resource(struct device *dev,
const struct fwnode_handle *child,
struct panthor_arbitration_resource *res)
@@ -95,42 +116,186 @@ static int panthor_arbitration_runtime_resume(struct device *dev)
return 0;
}
+static u32 arbitration_get_sched_aw_mask(struct panthor_arbitration *adev,
+ u8 sched_id)
+{
+ u32 aw_mask = 0;
+
+ lockdep_assert_held(&adev->assignment_lock);
+
+ for (int i = 0; i < AM_ARB_MAX_AW_COUNT; i++) {
+ if (adev->aw_sched_map[i] == sched_id)
+ aw_mask |= BIT(i);
+ }
+
+ return aw_mask;
+}
+
+static int arbitration_dt_parse_assigned_aw(struct panthor_arbitration *adev)
+{
+ struct panthor_arbitration_dt_info *dt_info = &adev->dt_info;
+ struct device *dev = adev->dev;
+ u32 seen_mask = 0;
+ u8 seen_partitions = 0;
+ int ret;
+
+ device_for_each_named_child_node_scoped(dev, child, "partition") {
+ struct panthor_arbitration_resource res;
+
+ if (panthor_arbitration_parse_resource(dev, child, &res))
+ continue;
+
+ if (res.id >= AM_ARB_MAX_PC_COUNT) {
+ dev_warn(dev,
+ "partition@%llx: id (%u) >= %u not supported",
+ res.res.start, res.id, AM_ARB_MAX_PC_COUNT);
+ continue;
+ }
+
+ if (BIT(res.id) & seen_partitions) {
+ dev_warn(dev, "partition@%llx: id (%u) already present",
+ res.res.start, res.id);
+ continue;
+ }
+
+ seen_partitions |= BIT(res.id);
+
+ if (!fwnode_property_present(child, DT_ASSIGNED_AW))
+ continue;
+
+ ret = fwnode_property_read_u32(child, DT_ASSIGNED_AW,
+ &dt_info->default_aw_masks[res.id]);
+ if (ret)
+ continue;
+ }
+
+ for (int i = 0; i < AM_ARB_MAX_PC_COUNT; i++) {
+ u32 aw_mask = dt_info->default_aw_masks[i];
+
+ if (aw_mask & ~GENMASK(AM_ARB_MAX_AW_COUNT - 1, 0))
+ return dev_err_probe(dev, -EINVAL, "%s[%d] entry exceeds max AW count",
+ DT_ASSIGNED_AW, i);
+
+ if (aw_mask & seen_mask)
+ return dev_err_probe(dev, -EINVAL, "%s entries overlap",
+ DT_ASSIGNED_AW);
+
+ seen_mask |= aw_mask;
+ }
+
+ return 0;
+}
+
+static int arbitration_dt_parse_properties(struct panthor_arbitration *adev)
+{
+ return arbitration_dt_parse_assigned_aw(adev);
+}
+
+static int arbitration_sched_try_start(struct panthor_arbitration *adev, u8 sched_id)
+{
+ struct panthor_arbitration_sched *sched;
+ u32 aw_mask;
+
+ if (!adev->sched[sched_id])
+ return -EINVAL;
+
+ sched = adev->sched[sched_id];
+
+ scoped_guard(mutex, &adev->assignment_lock)
+ aw_mask = arbitration_get_sched_aw_mask(adev, sched_id);
+
+ if (aw_mask)
+ panthor_arbitration_sched_disable_clear(sched, ARB_SCHED_DISABLE_RESOURCE);
+ else
+ panthor_arbitration_sched_disable_set(sched, ARB_SCHED_DISABLE_RESOURCE);
+
+ return panthor_arbitration_sched_start(sched);
+}
+
+static int arbitration_resource_init(struct panthor_arbitration *adev)
+{
+ struct panthor_arbitration_dt_info *dt_info = &adev->dt_info;
+
+ for (int i = 0; i < AM_ARB_MAX_PC_COUNT; i++) {
+ unsigned long pc_aw_mask = dt_info->default_aw_masks[i];
+ u8 aw_id;
+ int ret;
+
+ if (!adev->pc[i] || !adev->sched[i])
+ continue;
+
+ scoped_guard(mutex, &adev->assignment_lock) {
+ for_each_set_bit(aw_id, &pc_aw_mask, AM_ARB_MAX_AW_COUNT)
+ WRITE_ONCE(adev->aw_sched_map[aw_id], i);
+ }
+
+ ret = arbitration_sched_try_start(adev, i);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
/* AW to Arbiter events */
int panthor_arbitration_on_request(struct panthor_arbitration *adev, u8 aw_id)
{
- /* TODO: AW to PC assignment */
- return panthor_arbitration_sched_on_request(adev->sched[0], aw_id);
+ int idx = to_assigned_sched_idx(adev, aw_id);
+
+ if (idx < 0)
+ return idx;
+
+ return panthor_arbitration_sched_on_request(adev->sched[idx], aw_id);
}
int panthor_arbitration_on_idle(struct panthor_arbitration *adev, u8 aw_id)
{
- /* TODO: AW to PC assignment */
- return panthor_arbitration_sched_on_idle(adev->sched[0], aw_id);
+ int idx = to_assigned_sched_idx(adev, aw_id);
+
+ if (idx < 0)
+ return idx;
+
+ return panthor_arbitration_sched_on_idle(adev->sched[idx], aw_id);
}
int panthor_arbitration_on_stopped(struct panthor_arbitration *adev, u8 aw_id)
{
- /* TODO: AW to PC assignment */
- return panthor_arbitration_sched_on_stopped(adev->sched[0], aw_id);
+ int idx = to_assigned_sched_idx(adev, aw_id);
+
+ if (idx < 0)
+ return idx;
+
+ return panthor_arbitration_sched_on_stopped(adev->sched[idx], aw_id);
}
/* Arbiter to AW events */
int panthor_arbitration_on_grant(struct panthor_arbitration *adev, u8 aw_id)
{
- /* TODO: AW to PC assignment */
- return panthor_partition_control_open_window(adev->pc[0], aw_id);
+ int idx = to_assigned_sched_idx(adev, aw_id);
+
+ if (idx < 0)
+ return idx;
+
+ return panthor_partition_control_open_window(adev->pc[idx], aw_id);
}
int panthor_arbitration_on_stop(struct panthor_arbitration *adev, u8 aw_id)
{
- /* TODO: AW to PC assignment */
- return panthor_partition_control_yield_now(adev->pc[0]);
+ int idx = to_assigned_sched_idx(adev, aw_id);
+
+ if (idx < 0)
+ return idx;
+
+ return panthor_partition_control_yield_now(adev->pc[idx]);
}
int panthor_arbitration_on_close(struct panthor_arbitration *adev, u8 aw_id)
{
- /* TODO: AW to PC assignment */
- return panthor_partition_control_close_window(adev->pc[0]);
+ int idx = to_assigned_sched_idx(adev, aw_id);
+
+ if (idx < 0)
+ return idx;
+
+ return panthor_partition_control_close_window(adev->pc[idx]);
}
static int panthor_arbitration_probe(struct platform_device *pdev)
@@ -148,8 +313,16 @@ static int panthor_arbitration_probe(struct platform_device *pdev)
adev->dev = dev;
+ mutex_init(&adev->assignment_lock);
+ for (int i = 0; i < AM_ARB_MAX_AW_COUNT; i++)
+ adev->aw_sched_map[i] = -1;
+
dev_set_drvdata(dev, adev);
+ ret = arbitration_dt_parse_properties(adev);
+ if (ret)
+ return ret;
+
ret = devm_pm_runtime_enable(dev);
if (ret)
return ret;
@@ -170,6 +343,10 @@ static int panthor_arbitration_probe(struct platform_device *pdev)
if (ret)
goto err_term_sched;
+ ret = arbitration_resource_init(adev);
+ if (ret)
+ goto err_term_sched;
+
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
if (ret)
goto err_depopulate;
diff --git a/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_sched.c b/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_sched.c
index 41f06af92ce0c..9e26b8f92b69a 100644
--- a/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_sched.c
+++ b/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_sched.c
@@ -585,6 +585,8 @@ static int arbitration_sched_init(struct panthor_arbitration *adev, int i)
INIT_KFIFO(sched->queue);
sched->active_aw_id = -1;
sched->phase = ARB_SCHED_PHASE_IDLE;
+ /* Scheduler is disabled until its resources are configured */
+ sched->disabled = BIT(ARB_SCHED_DISABLE_RESOURCE);
hrtimer_setup(&sched->grant_timer.timer,
panthor_arbitration_sched_on_grant_timeout,
diff --git a/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_sched.h b/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_sched.h
index f1f50316a2fff..803a405964a4e 100644
--- a/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_sched.h
+++ b/drivers/gpu/drm/panthor/arbitration/panthor_arbitration_sched.h
@@ -15,6 +15,9 @@ enum panthor_arb_sched_disable_reason {
/** @ARB_SCHED_DISABLE_TERM: scheduler disabled for termination */
ARB_SCHED_DISABLE_TERM,
+
+ /** @ARB_SCHED_DISABLE_RESOURCE: No resource assigned. scheduler disabled. */
+ ARB_SCHED_DISABLE_RESOURCE,
};
int panthor_arbitration_sched_init(struct panthor_arbitration *adev);
--
2.43.0
next prev parent reply other threads:[~2026-09-22 20:48 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 20:44 [PATCH v1 00/27] drm/panthor: Add Mali v15 virtualization support Karunika Choo
2026-09-22 20:44 ` [PATCH v1 01/27] drm/panthor: Ignore -EOPNOTSUPP for shader-present nvmem lookup Karunika Choo
2026-10-28 15:51 ` Liviu Dudau
2026-09-22 20:44 ` [PATCH v1 02/27] drm/panthor: Move register access helpers out of panthor_device.h Karunika Choo
2026-10-28 15:52 ` Liviu Dudau
2026-09-22 20:44 ` [PATCH v1 03/27] drm/panthor: Parse and store GPU_ID fields Karunika Choo
2026-10-28 15:57 ` Liviu Dudau
2026-09-22 20:44 ` [PATCH v1 04/27] drm/panthor: Add 64-bit GPU_ID decoding for v15 GPUs Karunika Choo
2026-09-22 23:23 ` Deborah Brouwer
2026-10-28 15:58 ` Liviu Dudau
2026-09-22 20:44 ` [PATCH v1 05/27] drm/panthor: Move register base offsets to the HW description Karunika Choo
2026-10-28 16:03 ` Liviu Dudau
2026-09-22 20:45 ` [PATCH v1 06/27] drm/panthor: Derive MMU AS register addresses from base and stride Karunika Choo
2026-10-28 16:06 ` Liviu Dudau
2026-09-22 20:45 ` [PATCH v1 07/27] dt-bindings: gpu: mali-valhall-csf: Add Mali Gen5 AM compatible Karunika Choo
2026-09-28 10:02 ` Krzysztof Kozlowski
2026-09-22 20:45 ` [PATCH v1 08/27] drm/panthor: Add Mali v15 hardware support Karunika Choo
2026-10-28 13:21 ` Liviu Dudau
2026-10-28 16:20 ` Liviu Dudau
2026-09-22 20:45 ` [PATCH v1 09/27] drm/panthor: Skip devfreq when no OPP table is present Karunika Choo
2026-10-28 16:26 ` Liviu Dudau
2026-09-22 20:45 ` [PATCH v1 10/27] dt-bindings: gpu: panthor: Document panthor-system bindings Karunika Choo
2026-09-28 10:05 ` Krzysztof Kozlowski
2026-09-22 20:45 ` [PATCH v1 11/27] drm/panthor: Add AM_SYSTEM platform driver Karunika Choo
2026-09-22 20:45 ` [PATCH v1 12/27] dt-bindings: gpu: panthor: Document panthor-arbitration bindings Karunika Choo
2026-09-28 10:06 ` Krzysztof Kozlowski
2026-09-22 20:45 ` [PATCH v1 13/27] drm/panthor: Add AM_PARTITION_CONTROL support Karunika Choo
2026-09-22 20:45 ` [PATCH v1 14/27] drm/panthor: Add AM message helpers Karunika Choo
2026-09-22 20:45 ` [PATCH v1 15/27] drm/panthor: Add AM_RESOURCE_GROUP support Karunika Choo
2026-09-22 20:45 ` [PATCH v1 16/27] drm/panthor: Add arbitration scheduler Karunika Choo
2026-09-22 20:45 ` [PATCH v1 17/27] drm/panthor: Route arbitration events Karunika Choo
2026-09-22 20:45 ` [PATCH v1 18/27] dt-bindings: gpu: panthor: Document AW assignment DT property Karunika Choo
2026-09-28 10:06 ` Krzysztof Kozlowski
2026-09-22 20:45 ` Karunika Choo [this message]
2026-09-22 20:45 ` [PATCH v1 20/27] drm/panthor: Handle partition control INVALID_COMMAND interrupt Karunika Choo
2026-09-22 20:45 ` [PATCH v1 21/27] drm/panthor: Request AW to yield GPU access on idle Karunika Choo
2026-09-22 20:45 ` [PATCH v1 22/27] drm/panthor: Add access-window support Karunika Choo
2026-09-22 20:45 ` [PATCH v1 23/27] drm/panthor: Synchronize HW component PM transitions Karunika Choo
2026-09-22 20:45 ` [PATCH v1 24/27] drm/panthor: Route HW component PM through access windows Karunika Choo
2026-09-22 20:45 ` [PATCH v1 25/27] drm/panthor: Tolerate access-window loss during HW waits Karunika Choo
2026-09-22 20:45 ` [PATCH v1 26/27] drm/panthor: Prevent missed post-yield cleanup due to reset Karunika Choo
2026-09-22 20:45 ` [PATCH v1 27/27] drm/panthor: Release GPU access immediately for out-of-band grants Karunika Choo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260922204535.2850094-20-karunika.choo@arm.com \
--to=karunika.choo@arm.com \
--cc=airlied@gmail.com \
--cc=boris.brezillon@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=liviu.dudau@arm.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=nd@arm.com \
--cc=simona@ffwll.ch \
--cc=steven.price@arm.com \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®