gpu: host1x: syncpoint base support for chips <= t186

As syncpoint base feature is not supported from T194 onwards,
moving the related driver code under CONFIG_HOST1X_HAVE_SYNCPT_BASE
accordingly.

Jira HOSTX-5833

Change-Id: I388dea16527acd0153331710312efc477aa2bbde
Signed-off-by: Santosh BS <santoshb@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3292180
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Santosh BS
2025-01-28 11:28:54 +00:00
committed by Jon Hunter
parent 69055dd639
commit 8bfe83d4ee
6 changed files with 53 additions and 8 deletions

View File

@@ -1,5 +1,12 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. # Copyright (c) 2022-2025, NVIDIA CORPORATION. All rights reserved.
ifneq ($(filter y, $(CONFIG_ARCH_TEGRA_2x_SOC) $(CONFIG_ARCH_TEGRA_3x_SOC) \
$(CONFIG_ARCH_TEGRA_114_SOC) $(CONFIG_ARCH_TEGRA_124_SOC) $(CONFIG_ARCH_TEGRA_132_SOC) \
$(CONFIG_ARCH_TEGRA_210_SOC) $(CONFIG_ARCH_TEGRA_186_SOC)),)
export CONFIG_HOST1X_HAVE_SYNCPT_BASE=y
subdir-ccflags-y += -DCONFIG_HOST1X_HAVE_SYNCPT_BASE
endif
ifdef CONFIG_DRM ifdef CONFIG_DRM
obj-m += drm/tegra/ obj-m += drm/tegra/

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2010 Google, Inc. * Copyright (C) 2010 Google, Inc.
* Author: Erik Gilling <konkers@android.com> * Author: Erik Gilling <konkers@android.com>
* *
* Copyright (C) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * Copyright (C) 2011-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/ */
#include <linux/debugfs.h> #include <linux/debugfs.h>
@@ -109,6 +109,7 @@ static void show_syncpts(struct host1x *m, struct output *o, bool show_all)
i, m->syncpt[i].name, min, max, waiters); i, m->syncpt[i].name, min, max, waiters);
} }
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
for (i = 0; i < host1x_syncpt_nb_bases(m); i++) { for (i = 0; i < host1x_syncpt_nb_bases(m); i++) {
u32 base_val; u32 base_val;
@@ -117,6 +118,7 @@ static void show_syncpts(struct host1x *m, struct output *o, bool show_all)
host1x_debug_output(o, "waitbase id %u val %d\n", i, host1x_debug_output(o, "waitbase id %u val %d\n", i,
base_val); base_val);
} }
#endif
pm_runtime_put(m->dev); pm_runtime_put(m->dev);

View File

@@ -2,7 +2,7 @@
/* /*
* Tegra host1x Channel * Tegra host1x Channel
* *
* Copyright (c) 2010-2013, NVIDIA Corporation. * Copyright (c) 2010-2025, NVIDIA Corporation.
*/ */
#include <linux/host1x-next.h> #include <linux/host1x-next.h>
@@ -163,6 +163,7 @@ static void submit_gathers(struct host1x_job *job, struct host1x_job_cmd *cmds,
} }
} }
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
static inline void synchronize_syncpt_base(struct host1x_job *job) static inline void synchronize_syncpt_base(struct host1x_job *job)
{ {
struct host1x_syncpt *sp = job->syncpt; struct host1x_syncpt *sp = job->syncpt;
@@ -178,6 +179,7 @@ static inline void synchronize_syncpt_base(struct host1x_job *job)
HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(id) | HOST1X_UCLASS_LOAD_SYNCPT_BASE_BASE_INDX_F(id) |
HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(value)); HOST1X_UCLASS_LOAD_SYNCPT_BASE_VALUE_F(value));
} }
#endif
static void host1x_channel_set_streamid(struct host1x_channel *channel) static void host1x_channel_set_streamid(struct host1x_channel *channel)
{ {
@@ -297,9 +299,11 @@ prefences_done:
host1x_syncpt_read_max(sp))); host1x_syncpt_read_max(sp)));
} }
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
/* Synchronize base register to allow using it for relative waiting */ /* Synchronize base register to allow using it for relative waiting */
if (sp->base) if (sp->base)
synchronize_syncpt_base(job); synchronize_syncpt_base(job);
#endif
/* add a setclass for modules that require it */ /* add a setclass for modules that require it */
if (job->class) if (job->class)

View File

@@ -2,7 +2,7 @@
/* /*
* Tegra host1x Syncpoints * Tegra host1x Syncpoints
* *
* Copyright (c) 2010-2015, NVIDIA Corporation. * Copyright (c) 2010-2025, NVIDIA Corporation.
*/ */
#include <linux/module.h> #include <linux/module.h>
@@ -21,6 +21,7 @@
#define SYNCPT_CHECK_PERIOD (2 * HZ) #define SYNCPT_CHECK_PERIOD (2 * HZ)
#define MAX_STUCK_CHECK_COUNT 15 #define MAX_STUCK_CHECK_COUNT 15
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
static struct host1x_syncpt_base * static struct host1x_syncpt_base *
host1x_syncpt_base_request(struct host1x *host) host1x_syncpt_base_request(struct host1x *host)
{ {
@@ -43,6 +44,7 @@ static void host1x_syncpt_base_free(struct host1x_syncpt_base *base)
if (base) if (base)
base->requested = false; base->requested = false;
} }
#endif
/** /**
* host1x_syncpt_alloc() - allocate a syncpoint * host1x_syncpt_alloc() - allocate a syncpoint
@@ -92,11 +94,13 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
if (i >= host->syncpt_end) if (i >= host->syncpt_end)
goto unlock; goto unlock;
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
if (flags & HOST1X_SYNCPT_HAS_BASE) { if (flags & HOST1X_SYNCPT_HAS_BASE) {
sp->base = host1x_syncpt_base_request(host); sp->base = host1x_syncpt_base_request(host);
if (!sp->base) if (!sp->base)
goto unlock; goto unlock;
} }
#endif
full_name = kasprintf(GFP_KERNEL, "%u-%s", sp->id, name); full_name = kasprintf(GFP_KERNEL, "%u-%s", sp->id, name);
if (!full_name) if (!full_name)
@@ -115,8 +119,10 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
return sp; return sp;
free_base: free_base:
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
host1x_syncpt_base_free(sp->base); host1x_syncpt_base_free(sp->base);
sp->base = NULL; sp->base = NULL;
#endif
unlock: unlock:
mutex_unlock(&host->syncpt_mutex); mutex_unlock(&host->syncpt_mutex);
return NULL; return NULL;
@@ -166,8 +172,10 @@ void host1x_syncpt_restore(struct host1x *host)
host1x_hw_syncpt_restore(host, sp_base + i); host1x_hw_syncpt_restore(host, sp_base + i);
} }
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
for (i = 0; i < host1x_syncpt_nb_bases(host); i++) for (i = 0; i < host1x_syncpt_nb_bases(host); i++)
host1x_hw_syncpt_restore_wait_base(host, sp_base + i); host1x_hw_syncpt_restore_wait_base(host, sp_base + i);
#endif
host1x_hw_syncpt_enable_protection(host); host1x_hw_syncpt_enable_protection(host);
@@ -190,8 +198,10 @@ void host1x_syncpt_save(struct host1x *host)
WARN_ON(!host1x_syncpt_idle(sp_base + i)); WARN_ON(!host1x_syncpt_idle(sp_base + i));
} }
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
for (i = 0; i < host1x_syncpt_nb_bases(host); i++) for (i = 0; i < host1x_syncpt_nb_bases(host); i++)
host1x_hw_syncpt_load_wait_base(host, sp_base + i); host1x_hw_syncpt_load_wait_base(host, sp_base + i);
#endif
} }
/* /*
@@ -316,7 +326,9 @@ bool host1x_syncpt_is_expired(struct host1x_syncpt *sp, u32 thresh)
int host1x_syncpt_init(struct host1x *host) int host1x_syncpt_init(struct host1x *host)
{ {
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
struct host1x_syncpt_base *bases; struct host1x_syncpt_base *bases;
#endif
struct host1x_syncpt *syncpt; struct host1x_syncpt *syncpt;
unsigned int i; unsigned int i;
@@ -325,10 +337,12 @@ int host1x_syncpt_init(struct host1x *host)
if (!syncpt) if (!syncpt)
return -ENOMEM; return -ENOMEM;
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
bases = devm_kcalloc(host->dev, host->info->nb_bases, sizeof(*bases), bases = devm_kcalloc(host->dev, host->info->nb_bases, sizeof(*bases),
GFP_KERNEL); GFP_KERNEL);
if (!bases) if (!bases)
return -ENOMEM; return -ENOMEM;
#endif
for (i = 0; i < host->info->nb_pts; i++) { for (i = 0; i < host->info->nb_pts; i++) {
syncpt[i].id = i; syncpt[i].id = i;
@@ -342,8 +356,10 @@ int host1x_syncpt_init(struct host1x *host)
syncpt[i].client_managed = true; syncpt[i].client_managed = true;
} }
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
for (i = 0; i < host->info->nb_bases; i++) for (i = 0; i < host->info->nb_bases; i++)
bases[i].id = i; bases[i].id = i;
#endif
for (i = 0; i < host->num_pools; i++) { for (i = 0; i < host->num_pools; i++) {
struct host1x_syncpt_pool *pool = &host->pools[i]; struct host1x_syncpt_pool *pool = &host->pools[i];
@@ -355,7 +371,9 @@ int host1x_syncpt_init(struct host1x *host)
mutex_init(&host->syncpt_mutex); mutex_init(&host->syncpt_mutex);
host->syncpt = syncpt; host->syncpt = syncpt;
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
host->bases = bases; host->bases = bases;
#endif
/* /*
* Allocate sync point to use for clearing waits for expired fences. * Allocate sync point to use for clearing waits for expired fences.
@@ -404,9 +422,11 @@ static void syncpt_release(struct kref *ref)
mutex_lock(&sp->host->syncpt_mutex); mutex_lock(&sp->host->syncpt_mutex);
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
host1x_syncpt_base_free(sp->base); host1x_syncpt_base_free(sp->base);
kfree(sp->name);
sp->base = NULL; sp->base = NULL;
#endif
kfree(sp->name);
sp->name = NULL; sp->name = NULL;
sp->client_managed = false; sp->client_managed = false;
@@ -484,10 +504,12 @@ unsigned int host1x_syncpt_nb_pts(struct host1x *host)
return host->info->nb_pts; return host->info->nb_pts;
} }
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
unsigned int host1x_syncpt_nb_bases(struct host1x *host) unsigned int host1x_syncpt_nb_bases(struct host1x *host)
{ {
return host->info->nb_bases; return host->info->nb_bases;
} }
#endif
unsigned int host1x_syncpt_nb_mlocks(struct host1x *host) unsigned int host1x_syncpt_nb_mlocks(struct host1x *host)
{ {
@@ -540,6 +562,7 @@ struct host1x_syncpt *host1x_syncpt_get(struct host1x_syncpt *sp)
} }
EXPORT_SYMBOL(host1x_syncpt_get); EXPORT_SYMBOL(host1x_syncpt_get);
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
/** /**
* host1x_syncpt_get_base() - obtain the wait base associated with a syncpoint * host1x_syncpt_get_base() - obtain the wait base associated with a syncpoint
* @sp: host1x syncpoint * @sp: host1x syncpoint
@@ -559,6 +582,7 @@ u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base)
return base->id; return base->id;
} }
EXPORT_SYMBOL(host1x_syncpt_base_id); EXPORT_SYMBOL(host1x_syncpt_base_id);
#endif
static void do_nothing(struct kref *ref) static void do_nothing(struct kref *ref)
{ {

View File

@@ -2,7 +2,7 @@
/* /*
* Tegra host1x Syncpoints * Tegra host1x Syncpoints
* *
* Copyright (c) 2010-2013, NVIDIA Corporation. * Copyright (c) 2010-2025, NVIDIA Corporation.
*/ */
#ifndef __HOST1X_SYNCPT_H #ifndef __HOST1X_SYNCPT_H
@@ -22,10 +22,12 @@ struct host1x;
/* Reserved for replacing an expired wait with a NOP */ /* Reserved for replacing an expired wait with a NOP */
#define HOST1X_SYNCPT_RESERVED 0 #define HOST1X_SYNCPT_RESERVED 0
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
struct host1x_syncpt_base { struct host1x_syncpt_base {
unsigned int id; unsigned int id;
bool requested; bool requested;
}; };
#endif
struct host1x_syncpt { struct host1x_syncpt {
struct kref ref; struct kref ref;
@@ -37,7 +39,9 @@ struct host1x_syncpt {
const char *name; const char *name;
bool client_managed; bool client_managed;
struct host1x *host; struct host1x *host;
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
struct host1x_syncpt_base *base; struct host1x_syncpt_base *base;
#endif
struct host1x_syncpt_pool *pool; struct host1x_syncpt_pool *pool;
/* interrupt data */ /* interrupt data */
@@ -60,8 +64,10 @@ void host1x_syncpt_deinit(struct host1x *host);
/* Return number of sync point supported. */ /* Return number of sync point supported. */
unsigned int host1x_syncpt_nb_pts(struct host1x *host); unsigned int host1x_syncpt_nb_pts(struct host1x *host);
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
/* Return number of wait bases supported. */ /* Return number of wait bases supported. */
unsigned int host1x_syncpt_nb_bases(struct host1x *host); unsigned int host1x_syncpt_nb_bases(struct host1x *host);
#endif
/* Return number of mlocks supported. */ /* Return number of mlocks supported. */
unsigned int host1x_syncpt_nb_mlocks(struct host1x *host); unsigned int host1x_syncpt_nb_mlocks(struct host1x *host);

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SPDX-License-Identifier: GPL-2.0-or-later */
/* /*
* Copyright (c) 2009-2024, NVIDIA Corporation. All rights reserved. * Copyright (c) 2009-2025, NVIDIA Corporation. All rights reserved.
*/ */
#ifndef __LINUX_HOST1X_H #ifndef __LINUX_HOST1X_H
@@ -251,8 +251,10 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
unsigned long flags, unsigned long flags,
const char *name); const char *name);
#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE
struct host1x_syncpt_base *host1x_syncpt_get_base(struct host1x_syncpt *sp); struct host1x_syncpt_base *host1x_syncpt_get_base(struct host1x_syncpt *sp);
u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base); u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base);
#endif
void host1x_syncpt_release_vblank_reservation(struct host1x_client *client, void host1x_syncpt_release_vblank_reservation(struct host1x_client *client,
u32 syncpt_id); u32 syncpt_id);