mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
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:
@@ -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/
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user