From: Mikko Perttunen <mperttunen@nvidia.com>
To: Thierry Reding <thierry.reding@kernel.org>,
Jonathan Hunter <jonathanh@nvidia.com>,
David Airlie <airlied@gmail.com>,
Simona Vetter <simona@ffwll.ch>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>
Cc: linux-tegra@vger.kernel.org, dri-devel@lists.freedesktop.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
Mikko Perttunen <mperttunen@nvidia.com>
Subject: [PATCH v2 4/4] gpu: host1x: Allow limiting usable channel and syncpoint ranges
Date: Thu, 02 Jul 2026 13:10:29 +0900 [thread overview]
Message-ID: <20260702-host1x-nohv-v2-4-e6d88bac0af6@nvidia.com> (raw)
In-Reply-To: <20260702-host1x-nohv-v2-0-e6d88bac0af6@nvidia.com>
Allow specifying usable channel, and allocatable syncpoint ranges
through the device tree. This is necessary when Host1x resources
are shared between multiple operating systems or independent hardware
units and Linux has limited access to them.
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
drivers/gpu/host1x/channel.c | 6 +++---
drivers/gpu/host1x/dev.c | 37 +++++++++++++++++++++++++++++++++++++
drivers/gpu/host1x/dev.h | 3 +++
drivers/gpu/host1x/syncpt.c | 21 +++++++++++++--------
4 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c
index ca5d0f51cf7d..38fcdda8388a 100644
--- a/drivers/gpu/host1x/channel.c
+++ b/drivers/gpu/host1x/channel.c
@@ -121,13 +121,13 @@ EXPORT_SYMBOL(host1x_channel_put);
static struct host1x_channel *acquire_unused_channel(struct host1x *host)
{
struct host1x_channel_list *chlist = &host->channel_list;
- unsigned int max_channels = host->info->nb_channels;
unsigned int index;
mutex_lock(&chlist->lock);
- index = find_first_zero_bit(chlist->allocated_channels, max_channels);
- if (index >= max_channels) {
+ index = find_next_zero_bit(chlist->allocated_channels,
+ host->channel_end, host->channel_base);
+ if (index >= host->channel_end) {
mutex_unlock(&chlist->lock);
dev_err(host->dev, "failed to find free channel\n");
return NULL;
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 545fa2e3f180..7103f018cb1b 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -331,6 +331,39 @@ static void host1x_setup_virtualization_tables(struct host1x *host)
}
}
+static int host1x_get_assigned_resources(struct host1x *host)
+{
+ struct device_node *np = host->dev->of_node;
+ u32 vals[2];
+ int err;
+
+ err = of_property_read_u32_array(np, "nvidia,channels", vals, 2);
+ if (err == 0) {
+ host->channel_base = vals[0];
+ host->channel_end = vals[0] + vals[1];
+ } else if (err == -EINVAL) {
+ host->channel_base = 0;
+ host->channel_end = host->info->nb_channels;
+ } else {
+ dev_err(host->dev, "invalid nvidia,channels property: %d\n", err);
+ return err;
+ }
+
+ err = of_property_read_u32_array(np, "nvidia,syncpoints", vals, 2);
+ if (err == 0) {
+ host->syncpt_base = vals[0];
+ host->syncpt_end = vals[0] + vals[1];
+ } else if (err == -EINVAL) {
+ host->syncpt_base = 0;
+ host->syncpt_end = host->info->nb_pts;
+ } else {
+ dev_err(host->dev, "invalid nvidia,syncpoints property: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
static bool host1x_wants_iommu(struct host1x *host1x)
{
/* Our IOMMU usage policy doesn't currently play well with GART */
@@ -602,6 +635,10 @@ static int host1x_probe(struct platform_device *pdev)
if (IS_ERR(host->clk))
return dev_err_probe(&pdev->dev, PTR_ERR(host->clk), "failed to get clock\n");
+ err = host1x_get_assigned_resources(host);
+ if (err)
+ return err;
+
err = host1x_get_resets(host);
if (err)
return err;
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index ef44618ed88a..89f1fc838a1c 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -141,6 +141,9 @@ struct host1x {
struct reset_control_bulk_data resets[2];
unsigned int nresets;
+ unsigned int syncpt_base, syncpt_end;
+ unsigned int channel_base, channel_end;
+
struct iommu_group *group;
struct iommu_domain *domain;
struct iova_domain iova;
diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
index 807c74fc6a0a..7760252b3394 100644
--- a/drivers/gpu/host1x/syncpt.c
+++ b/drivers/gpu/host1x/syncpt.c
@@ -59,7 +59,7 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
unsigned long flags,
const char *name)
{
- struct host1x_syncpt *sp = host->syncpt;
+ struct host1x_syncpt *sp = host->syncpt + host->syncpt_base;
char *full_name;
unsigned int i;
@@ -68,10 +68,10 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
mutex_lock(&host->syncpt_mutex);
- for (i = 0; i < host->info->nb_pts && kref_read(&sp->ref); i++, sp++)
+ for (i = host->syncpt_base; i < host->syncpt_end && kref_read(&sp->ref); i++, sp++)
;
- if (i >= host->info->nb_pts)
+ if (i >= host->syncpt_end)
goto unlock;
if (flags & HOST1X_SYNCPT_HAS_BASE) {
@@ -138,7 +138,7 @@ void host1x_syncpt_restore(struct host1x *host)
struct host1x_syncpt *sp_base = host->syncpt;
unsigned int i;
- for (i = 0; i < host1x_syncpt_nb_pts(host); i++) {
+ for (i = host->syncpt_base; i < host->syncpt_end; i++) {
/*
* Unassign syncpt from channels for purposes of Tegra186
* syncpoint protection. This prevents any channel from
@@ -301,6 +301,9 @@ int host1x_syncpt_init(struct host1x *host)
for (i = 0; i < host->info->nb_pts; i++) {
syncpt[i].id = i;
syncpt[i].host = host;
+
+ /* Default to client managed for syncpoints not owned by us */
+ syncpt[i].client_managed = true;
}
for (i = 0; i < host->info->nb_bases; i++)
@@ -310,10 +313,12 @@ int host1x_syncpt_init(struct host1x *host)
host->syncpt = syncpt;
host->bases = bases;
- /* Allocate sync point to use for clearing waits for expired fences */
- host->nop_sp = host1x_syncpt_alloc(host, 0, "reserved-nop");
- if (!host->nop_sp)
- return -ENOMEM;
+ /* Prevent syncpoint 0 from being allocated by users */
+ if (host->syncpt_base == 0) {
+ host->nop_sp = host1x_syncpt_alloc(host, 0, "reserved-nop");
+ if (!host->nop_sp)
+ return -ENOMEM;
+ }
if (host->info->reserve_vblank_syncpts) {
kref_init(&host->syncpt[26].ref);
--
2.53.0
next prev parent reply other threads:[~2026-07-02 4:11 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-02 4:10 [PATCH v2 0/4] Support partitioned Host1x Mikko Perttunen
2026-07-02 4:10 ` [PATCH v2 1/4] dt-bindings: display: tegra: Make non-vm registers optional Mikko Perttunen
2026-07-03 6:56 ` Krzysztof Kozlowski
2026-07-02 4:10 ` [PATCH v2 2/4] dt-bindings: display: tegra: Add channel/syncpoint range properties Mikko Perttunen
2026-07-03 7:09 ` Krzysztof Kozlowski
2026-07-02 4:10 ` [PATCH v2 3/4] gpu: host1x: Support running without hv/common registers Mikko Perttunen
2026-07-02 4:10 ` Mikko Perttunen [this message]
2026-07-02 4:22 ` [PATCH v2 4/4] gpu: host1x: Allow limiting usable channel and syncpoint ranges sashiko-bot
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=20260702-host1x-nohv-v2-4-e6d88bac0af6@nvidia.com \
--to=mperttunen@nvidia.com \
--cc=airlied@gmail.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=jonathanh@nvidia.com \
--cc=krzk+dt@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=robh@kernel.org \
--cc=simona@ffwll.ch \
--cc=thierry.reding@kernel.org \
--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