nvdla: Replace deprecated syncpt API in EMU driver

This commit replaces the deprecated nvhost_syncpt_unit_interface_init()
and other related deprecated nvhost syncpoint functions
in nvdla_sync_syncpt_emu.c with direct implementations
using the host1x API

Key changes include:
- Added a local nvhost_syncpt_interface structure definition
- Replaced nvhost_syncpt_unit_interface_init()
   with direct initialization code
- Added nvdla_syncpt_address() function to replace nvhost_syncpt_address()
- Updated nvhost_syncpt_put_ref_ext() -> host1x_syncpt_put()
- Updated nvhost_get_syncpt_host_managed() ->
   host1x_syncpt_alloc() + host1x_syncpt_id()
- Updated nvhost_syncpt_incr_max_ext() -> host1x_syncpt_incr_max()
- Updated nvhost_syncpt_read_maxval() -> host1x_syncpt_read_max()
- Updated nvhost_syncpt_is_expired_ext() -> host1x_syncpt_wait()
- Updated nvhost_syncpt_set_min_update() ->
   host1x_syncpt_read() + host1x_syncpt_incr()

Bug 4921461

Jira HOSTX-5971

Change-Id: Ief353770bfcf87ef48abcc598f5ca84bcf72bd22
Signed-off-by: Mainak Sen <msen@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3330688
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Mitch Harwell <mharwell@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Arvind M <am@nvidia.com>
This commit is contained in:
Mainak Sen
2025-04-01 10:40:58 +00:00
committed by Jon Hunter
parent 9597e077cd
commit d3e0d8bb36

View File

@@ -11,6 +11,15 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <linux/iommu.h>
#include <linux/dma-mapping.h>
/* Local definition of nvhost_syncpt_interface structure */
struct nvhost_syncpt_interface {
dma_addr_t base;
size_t size;
u32 page_size;
};
struct nvdla_sync_device {
struct platform_device *pdev;
@@ -22,11 +31,24 @@ struct nvdla_sync_context {
dma_addr_t address;
};
static dma_addr_t nvdla_syncpt_address(struct platform_device *pdev, u32 syncpt_id)
{
struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
struct nvhost_syncpt_interface *syncpt_if = pdata->syncpt_unit_interface;
return syncpt_if->base + syncpt_if->page_size * syncpt_id;
}
struct nvdla_sync_device *nvdla_sync_device_create_syncpoint(
struct platform_device *pdev)
{
int32_t err;
struct nvhost_device_data *pdata = NULL;
struct nvhost_syncpt_interface *syncpt_if = NULL;
struct nvdla_sync_device *device = NULL;
phys_addr_t base;
u32 stride;
u32 num_syncpts;
int32_t err;
if (pdev == NULL)
goto fail;
@@ -38,17 +60,47 @@ struct nvdla_sync_device *nvdla_sync_device_create_syncpoint(
goto fail;
}
err = nvhost_syncpt_unit_interface_init(pdev);
if (err < 0) {
nvdla_dbg_err(pdev, "failed to init syncpt interface. err=%d\n",
err);
pdata = platform_get_drvdata(pdev);
syncpt_if = devm_kzalloc(&pdev->dev, sizeof(*syncpt_if), GFP_KERNEL);
if (!syncpt_if) {
err = -ENOMEM;
goto free_device;
}
err = host1x_syncpt_get_shim_info(pdata->host1x, &base, &stride, &num_syncpts);
if (err) {
nvdla_dbg_err(pdev, "failed to get syncpt shim info. err=%d\n", err);
goto free_syncpt_if;
}
syncpt_if->base = base;
syncpt_if->size = stride * num_syncpts;
syncpt_if->page_size = stride;
/* If IOMMU is enabled, map it into the device memory */
if (iommu_get_domain_for_dev(&pdev->dev)) {
syncpt_if->base = dma_map_resource(&pdev->dev, base,
syncpt_if->size,
DMA_BIDIRECTIONAL,
DMA_ATTR_SKIP_CPU_SYNC);
if (dma_mapping_error(&pdev->dev, syncpt_if->base)) {
err = -ENOMEM;
goto free_syncpt_if;
}
}
pdata->syncpt_unit_interface = syncpt_if;
dev_info(&pdev->dev,
"syncpt_unit_base %llx syncpt_unit_size %zx size %x\n",
base, syncpt_if->size, syncpt_if->page_size);
device->pdev = pdev;
return device;
free_syncpt_if:
devm_kfree(&pdev->dev, syncpt_if);
free_device:
vfree(device);
fail:
@@ -57,13 +109,31 @@ fail:
void nvdla_sync_device_destroy(struct nvdla_sync_device *device)
{
struct nvhost_syncpt_interface *syncpt_if;
struct nvhost_device_data *pdata;
struct platform_device *pdev;
if (device == NULL)
goto done;
if (device->pdev == NULL)
goto free_device;
nvhost_syncpt_unit_interface_deinit(device->pdev);
pdev = device->pdev;
pdata = platform_get_drvdata(pdev);
syncpt_if = pdata->syncpt_unit_interface;
if (syncpt_if) {
/* Unmap IOMMU resources if needed */
if (iommu_get_domain_for_dev(&pdev->dev)) {
dma_unmap_resource(&pdev->dev, syncpt_if->base, syncpt_if->size,
DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC);
}
/* Free the syncpt_if memory */
devm_kfree(&pdev->dev, syncpt_if);
pdata->syncpt_unit_interface = NULL;
}
free_device:
device->pdev = NULL;
@@ -79,7 +149,7 @@ dma_addr_t nvdla_sync_get_address_by_syncptid(
dma_addr_t address = 0ULL;
if (device != NULL)
address = nvhost_syncpt_address(device->pdev, syncptid);
address = nvdla_syncpt_address(device->pdev, syncptid);
return address;
}
@@ -87,6 +157,8 @@ dma_addr_t nvdla_sync_get_address_by_syncptid(
struct nvdla_sync_context *nvdla_sync_create(struct nvdla_sync_device *device)
{
struct nvdla_sync_context *context = NULL;
struct host1x_syncpt *sp = NULL;
struct nvhost_device_data *pdata = NULL;
if ((device == NULL) || (device->pdev == NULL))
goto fail;
@@ -99,27 +171,50 @@ struct nvdla_sync_context *nvdla_sync_create(struct nvdla_sync_device *device)
goto fail;
}
context->syncptid = nvhost_get_syncpt_host_managed(device->pdev, 0U, NULL);
pdata = platform_get_drvdata(device->pdev);
sp = host1x_syncpt_alloc(pdata->host1x,
0U, /* Not client managed */
dev_name(&device->pdev->dev));
if (!sp) {
nvdla_dbg_err(device->pdev, "Failed to allocate syncpoint\n");
goto free_context;
}
context->address = nvhost_syncpt_address(device->pdev, context->syncptid);
context->syncptid = host1x_syncpt_id(sp);
if (context->syncptid == 0) {
nvdla_dbg_err(device->pdev, "Failed to get syncpoint ID\n");
host1x_syncpt_put(sp); /* Release the allocated syncpoint */
goto free_context;
}
context->address = nvdla_syncpt_address(device->pdev, context->syncptid);
context->device = device;
return context;
free_context:
vfree(context);
fail:
return NULL;
}
void nvdla_sync_destroy(struct nvdla_sync_context *context)
{
struct host1x_syncpt *sp = NULL;
struct nvhost_device_data *pdata;
if (context == NULL)
goto done;
if ((context->device == NULL) || (context->device->pdev == NULL))
goto free_context;
/* Release the syncpoint ID */
nvhost_syncpt_put_ref_ext(context->device->pdev, context->syncptid);
pdata = platform_get_drvdata(context->device->pdev);
sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
if (WARN_ON(!sp))
goto free_context;
host1x_syncpt_put(sp);
free_context:
context->device = NULL;
@@ -142,13 +237,18 @@ uint32_t nvdla_sync_increment_max_value(struct nvdla_sync_context *context,
uint32_t increment)
{
uint32_t maxval = 0U;
struct nvhost_device_data *pdata;
struct host1x_syncpt *sp;
if ((context == NULL) || (context->device == NULL))
goto fail;
maxval = nvhost_syncpt_incr_max_ext(context->device->pdev,
context->syncptid,
increment);
pdata = platform_get_drvdata(context->device->pdev);
sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
if (WARN_ON(!sp))
goto fail;
maxval = host1x_syncpt_incr_max(sp, increment);
fail:
return maxval;
@@ -157,12 +257,18 @@ fail:
uint32_t nvdla_sync_get_max_value(struct nvdla_sync_context *context)
{
int32_t maxval = 0U;
struct nvhost_device_data *pdata;
struct host1x_syncpt *sp;
if ((context == NULL) || (context->device == NULL))
goto fail;
maxval = nvhost_syncpt_read_maxval(context->device->pdev,
context->syncptid);
pdata = platform_get_drvdata(context->device->pdev);
sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
if (WARN_ON(!sp))
goto fail;
maxval = host1x_syncpt_read_max(sp);
fail:
return maxval;
@@ -175,6 +281,8 @@ int32_t nvdla_sync_wait(struct nvdla_sync_context *context,
int32_t err = 0;
int wait_complete;
struct nvdla_sync_device *device;
struct nvhost_device_data *pdata;
struct host1x_syncpt *sp;
if ((context == NULL) || (context->device == NULL)) {
err = -EINVAL;
@@ -183,10 +291,15 @@ int32_t nvdla_sync_wait(struct nvdla_sync_context *context,
device = context->device;
if (timeout == 0ULL) {
wait_complete = nvhost_syncpt_is_expired_ext(device->pdev,
context->syncptid,
threshold);
if (wait_complete == 0) {
pdata = platform_get_drvdata(device->pdev);
sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
if (WARN_ON(!sp)) {
err = -EINVAL;
goto fail;
}
wait_complete = (host1x_syncpt_wait(sp, threshold, 0, NULL) == 0);
if (!wait_complete) {
nvdla_dbg_err(device->pdev,
"Wait on sp[%u] for threshold[%u] timedout\n",
context->syncptid, threshold);
@@ -209,15 +322,28 @@ int32_t nvdla_sync_signal(struct nvdla_sync_context *context,
uint32_t signal_value)
{
int err = 0;
struct nvhost_device_data *pdata;
struct host1x_syncpt *sp;
uint32_t cur;
if ((context == NULL) || (context->device == NULL)) {
err = -EINVAL;
goto fail;
}
nvhost_syncpt_set_min_update(context->device->pdev,
context->syncptid,
signal_value);
pdata = platform_get_drvdata(context->device->pdev);
sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
if (WARN_ON(!sp)) {
err = -EINVAL;
goto fail;
}
cur = host1x_syncpt_read(sp);
while (cur++ != signal_value)
host1x_syncpt_incr(sp);
/* Read back to ensure the value has been updated */
host1x_syncpt_read(sp);
fail:
return err;