From 8bfe83d4eecb266a2ac579399e14b6d3c588d7e9 Mon Sep 17 00:00:00 2001 From: Santosh BS Date: Tue, 28 Jan 2025 11:28:54 +0000 Subject: [PATCH] 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 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3292180 Reviewed-by: Mikko Perttunen GVS: buildbot_gerritrpt --- drivers/gpu/Makefile | 9 ++++++++- drivers/gpu/host1x/debug.c | 4 +++- drivers/gpu/host1x/hw/channel_hw.c | 6 +++++- drivers/gpu/host1x/syncpt.c | 30 +++++++++++++++++++++++++++--- drivers/gpu/host1x/syncpt.h | 8 +++++++- include/linux/host1x-next.h | 4 +++- 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile index 33ca7936..8004ce80 100644 --- a/drivers/gpu/Makefile +++ b/drivers/gpu/Makefile @@ -1,5 +1,12 @@ # 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 obj-m += drm/tegra/ diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c index 21e4103f..2fcd1447 100644 --- a/drivers/gpu/host1x/debug.c +++ b/drivers/gpu/host1x/debug.c @@ -3,7 +3,7 @@ * Copyright (C) 2010 Google, Inc. * Author: Erik Gilling * - * Copyright (C) 2011-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) 2011-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ #include @@ -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); } +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE for (i = 0; i < host1x_syncpt_nb_bases(m); i++) { 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, base_val); } +#endif pm_runtime_put(m->dev); diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c index e7aa5505..ff14b038 100644 --- a/drivers/gpu/host1x/hw/channel_hw.c +++ b/drivers/gpu/host1x/hw/channel_hw.c @@ -2,7 +2,7 @@ /* * Tegra host1x Channel * - * Copyright (c) 2010-2013, NVIDIA Corporation. + * Copyright (c) 2010-2025, NVIDIA Corporation. */ #include @@ -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) { 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_VALUE_F(value)); } +#endif static void host1x_channel_set_streamid(struct host1x_channel *channel) { @@ -297,9 +299,11 @@ prefences_done: host1x_syncpt_read_max(sp))); } +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE /* Synchronize base register to allow using it for relative waiting */ if (sp->base) synchronize_syncpt_base(job); +#endif /* add a setclass for modules that require it */ if (job->class) diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c index 57fe545c..6ca5fae9 100644 --- a/drivers/gpu/host1x/syncpt.c +++ b/drivers/gpu/host1x/syncpt.c @@ -2,7 +2,7 @@ /* * Tegra host1x Syncpoints * - * Copyright (c) 2010-2015, NVIDIA Corporation. + * Copyright (c) 2010-2025, NVIDIA Corporation. */ #include @@ -21,6 +21,7 @@ #define SYNCPT_CHECK_PERIOD (2 * HZ) #define MAX_STUCK_CHECK_COUNT 15 +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE static struct host1x_syncpt_base * host1x_syncpt_base_request(struct host1x *host) { @@ -43,6 +44,7 @@ static void host1x_syncpt_base_free(struct host1x_syncpt_base *base) if (base) base->requested = false; } +#endif /** * host1x_syncpt_alloc() - allocate a syncpoint @@ -92,11 +94,13 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host, if (i >= host->syncpt_end) goto unlock; +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE if (flags & HOST1X_SYNCPT_HAS_BASE) { sp->base = host1x_syncpt_base_request(host); if (!sp->base) goto unlock; } +#endif full_name = kasprintf(GFP_KERNEL, "%u-%s", sp->id, name); if (!full_name) @@ -115,8 +119,10 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host, return sp; free_base: +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE host1x_syncpt_base_free(sp->base); sp->base = NULL; +#endif unlock: mutex_unlock(&host->syncpt_mutex); return NULL; @@ -166,8 +172,10 @@ void host1x_syncpt_restore(struct host1x *host) host1x_hw_syncpt_restore(host, sp_base + i); } +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE for (i = 0; i < host1x_syncpt_nb_bases(host); i++) host1x_hw_syncpt_restore_wait_base(host, sp_base + i); +#endif 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)); } +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE for (i = 0; i < host1x_syncpt_nb_bases(host); 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) { +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE struct host1x_syncpt_base *bases; +#endif struct host1x_syncpt *syncpt; unsigned int i; @@ -325,10 +337,12 @@ int host1x_syncpt_init(struct host1x *host) if (!syncpt) return -ENOMEM; +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE bases = devm_kcalloc(host->dev, host->info->nb_bases, sizeof(*bases), GFP_KERNEL); if (!bases) return -ENOMEM; +#endif for (i = 0; i < host->info->nb_pts; i++) { syncpt[i].id = i; @@ -342,8 +356,10 @@ int host1x_syncpt_init(struct host1x *host) syncpt[i].client_managed = true; } +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE for (i = 0; i < host->info->nb_bases; i++) bases[i].id = i; +#endif for (i = 0; i < host->num_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); host->syncpt = syncpt; +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE host->bases = bases; +#endif /* * 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); +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE host1x_syncpt_base_free(sp->base); - kfree(sp->name); sp->base = NULL; +#endif + kfree(sp->name); sp->name = NULL; sp->client_managed = false; @@ -484,10 +504,12 @@ unsigned int host1x_syncpt_nb_pts(struct host1x *host) return host->info->nb_pts; } +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE unsigned int host1x_syncpt_nb_bases(struct host1x *host) { return host->info->nb_bases; } +#endif 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); +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE /** * host1x_syncpt_get_base() - obtain the wait base associated with a syncpoint * @sp: host1x syncpoint @@ -559,6 +582,7 @@ u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base) return base->id; } EXPORT_SYMBOL(host1x_syncpt_base_id); +#endif static void do_nothing(struct kref *ref) { @@ -600,4 +624,4 @@ int host1x_syncpt_get_shim_info(struct host1x *host, phys_addr_t *base, u32 *str return 0; } -EXPORT_SYMBOL(host1x_syncpt_get_shim_info); \ No newline at end of file +EXPORT_SYMBOL(host1x_syncpt_get_shim_info); diff --git a/drivers/gpu/host1x/syncpt.h b/drivers/gpu/host1x/syncpt.h index 03a686f1..28da246d 100644 --- a/drivers/gpu/host1x/syncpt.h +++ b/drivers/gpu/host1x/syncpt.h @@ -2,7 +2,7 @@ /* * Tegra host1x Syncpoints * - * Copyright (c) 2010-2013, NVIDIA Corporation. + * Copyright (c) 2010-2025, NVIDIA Corporation. */ #ifndef __HOST1X_SYNCPT_H @@ -22,10 +22,12 @@ struct host1x; /* Reserved for replacing an expired wait with a NOP */ #define HOST1X_SYNCPT_RESERVED 0 +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE struct host1x_syncpt_base { unsigned int id; bool requested; }; +#endif struct host1x_syncpt { struct kref ref; @@ -37,7 +39,9 @@ struct host1x_syncpt { const char *name; bool client_managed; struct host1x *host; +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE struct host1x_syncpt_base *base; +#endif struct host1x_syncpt_pool *pool; /* interrupt data */ @@ -60,8 +64,10 @@ void host1x_syncpt_deinit(struct host1x *host); /* Return number of sync point supported. */ unsigned int host1x_syncpt_nb_pts(struct host1x *host); +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE /* Return number of wait bases supported. */ unsigned int host1x_syncpt_nb_bases(struct host1x *host); +#endif /* Return number of mlocks supported. */ unsigned int host1x_syncpt_nb_mlocks(struct host1x *host); diff --git a/include/linux/host1x-next.h b/include/linux/host1x-next.h index 19a2b3b3..750b7857 100644 --- a/include/linux/host1x-next.h +++ b/include/linux/host1x-next.h @@ -1,6 +1,6 @@ /* 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 @@ -251,8 +251,10 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host, unsigned long flags, const char *name); +#ifdef CONFIG_HOST1X_HAVE_SYNCPT_BASE struct host1x_syncpt_base *host1x_syncpt_get_base(struct host1x_syncpt *sp); u32 host1x_syncpt_base_id(struct host1x_syncpt_base *base); +#endif void host1x_syncpt_release_vblank_reservation(struct host1x_client *client, u32 syncpt_id);