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/errno.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/vmalloc.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 nvdla_sync_device {
struct platform_device *pdev; struct platform_device *pdev;
@@ -22,11 +31,24 @@ struct nvdla_sync_context {
dma_addr_t address; 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 nvdla_sync_device *nvdla_sync_device_create_syncpoint(
struct platform_device *pdev) 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; struct nvdla_sync_device *device = NULL;
phys_addr_t base;
u32 stride;
u32 num_syncpts;
int32_t err;
if (pdev == NULL) if (pdev == NULL)
goto fail; goto fail;
@@ -38,17 +60,47 @@ struct nvdla_sync_device *nvdla_sync_device_create_syncpoint(
goto fail; goto fail;
} }
err = nvhost_syncpt_unit_interface_init(pdev); pdata = platform_get_drvdata(pdev);
if (err < 0) { syncpt_if = devm_kzalloc(&pdev->dev, sizeof(*syncpt_if), GFP_KERNEL);
nvdla_dbg_err(pdev, "failed to init syncpt interface. err=%d\n", if (!syncpt_if) {
err); err = -ENOMEM;
goto free_device; 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; device->pdev = pdev;
return device; return device;
free_syncpt_if:
devm_kfree(&pdev->dev, syncpt_if);
free_device: free_device:
vfree(device); vfree(device);
fail: fail:
@@ -57,13 +109,31 @@ fail:
void nvdla_sync_device_destroy(struct nvdla_sync_device *device) 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) if (device == NULL)
goto done; goto done;
if (device->pdev == NULL) if (device->pdev == NULL)
goto free_device; 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: free_device:
device->pdev = NULL; device->pdev = NULL;
@@ -79,7 +149,7 @@ dma_addr_t nvdla_sync_get_address_by_syncptid(
dma_addr_t address = 0ULL; dma_addr_t address = 0ULL;
if (device != NULL) if (device != NULL)
address = nvhost_syncpt_address(device->pdev, syncptid); address = nvdla_syncpt_address(device->pdev, syncptid);
return address; 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 *nvdla_sync_create(struct nvdla_sync_device *device)
{ {
struct nvdla_sync_context *context = NULL; struct nvdla_sync_context *context = NULL;
struct host1x_syncpt *sp = NULL;
struct nvhost_device_data *pdata = NULL;
if ((device == NULL) || (device->pdev == NULL)) if ((device == NULL) || (device->pdev == NULL))
goto fail; goto fail;
@@ -99,27 +171,50 @@ struct nvdla_sync_context *nvdla_sync_create(struct nvdla_sync_device *device)
goto fail; 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; context->device = device;
return context; return context;
free_context:
vfree(context);
fail: fail:
return NULL; return NULL;
} }
void nvdla_sync_destroy(struct nvdla_sync_context *context) void nvdla_sync_destroy(struct nvdla_sync_context *context)
{ {
struct host1x_syncpt *sp = NULL;
struct nvhost_device_data *pdata;
if (context == NULL) if (context == NULL)
goto done; goto done;
if ((context->device == NULL) || (context->device->pdev == NULL)) if ((context->device == NULL) || (context->device->pdev == NULL))
goto free_context; goto free_context;
/* Release the syncpoint ID */ pdata = platform_get_drvdata(context->device->pdev);
nvhost_syncpt_put_ref_ext(context->device->pdev, context->syncptid); sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
if (WARN_ON(!sp))
goto free_context;
host1x_syncpt_put(sp);
free_context: free_context:
context->device = NULL; context->device = NULL;
@@ -142,13 +237,18 @@ uint32_t nvdla_sync_increment_max_value(struct nvdla_sync_context *context,
uint32_t increment) uint32_t increment)
{ {
uint32_t maxval = 0U; uint32_t maxval = 0U;
struct nvhost_device_data *pdata;
struct host1x_syncpt *sp;
if ((context == NULL) || (context->device == NULL)) if ((context == NULL) || (context->device == NULL))
goto fail; goto fail;
maxval = nvhost_syncpt_incr_max_ext(context->device->pdev, pdata = platform_get_drvdata(context->device->pdev);
context->syncptid, sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
increment); if (WARN_ON(!sp))
goto fail;
maxval = host1x_syncpt_incr_max(sp, increment);
fail: fail:
return maxval; return maxval;
@@ -157,12 +257,18 @@ fail:
uint32_t nvdla_sync_get_max_value(struct nvdla_sync_context *context) uint32_t nvdla_sync_get_max_value(struct nvdla_sync_context *context)
{ {
int32_t maxval = 0U; int32_t maxval = 0U;
struct nvhost_device_data *pdata;
struct host1x_syncpt *sp;
if ((context == NULL) || (context->device == NULL)) if ((context == NULL) || (context->device == NULL))
goto fail; goto fail;
maxval = nvhost_syncpt_read_maxval(context->device->pdev, pdata = platform_get_drvdata(context->device->pdev);
context->syncptid); sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
if (WARN_ON(!sp))
goto fail;
maxval = host1x_syncpt_read_max(sp);
fail: fail:
return maxval; return maxval;
@@ -175,6 +281,8 @@ int32_t nvdla_sync_wait(struct nvdla_sync_context *context,
int32_t err = 0; int32_t err = 0;
int wait_complete; int wait_complete;
struct nvdla_sync_device *device; struct nvdla_sync_device *device;
struct nvhost_device_data *pdata;
struct host1x_syncpt *sp;
if ((context == NULL) || (context->device == NULL)) { if ((context == NULL) || (context->device == NULL)) {
err = -EINVAL; err = -EINVAL;
@@ -183,10 +291,15 @@ int32_t nvdla_sync_wait(struct nvdla_sync_context *context,
device = context->device; device = context->device;
if (timeout == 0ULL) { if (timeout == 0ULL) {
wait_complete = nvhost_syncpt_is_expired_ext(device->pdev, pdata = platform_get_drvdata(device->pdev);
context->syncptid, sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
threshold); if (WARN_ON(!sp)) {
if (wait_complete == 0) { err = -EINVAL;
goto fail;
}
wait_complete = (host1x_syncpt_wait(sp, threshold, 0, NULL) == 0);
if (!wait_complete) {
nvdla_dbg_err(device->pdev, nvdla_dbg_err(device->pdev,
"Wait on sp[%u] for threshold[%u] timedout\n", "Wait on sp[%u] for threshold[%u] timedout\n",
context->syncptid, threshold); context->syncptid, threshold);
@@ -209,15 +322,28 @@ int32_t nvdla_sync_signal(struct nvdla_sync_context *context,
uint32_t signal_value) uint32_t signal_value)
{ {
int err = 0; int err = 0;
struct nvhost_device_data *pdata;
struct host1x_syncpt *sp;
uint32_t cur;
if ((context == NULL) || (context->device == NULL)) { if ((context == NULL) || (context->device == NULL)) {
err = -EINVAL; err = -EINVAL;
goto fail; goto fail;
} }
nvhost_syncpt_set_min_update(context->device->pdev, pdata = platform_get_drvdata(context->device->pdev);
context->syncptid, sp = host1x_syncpt_get_by_id_noref(pdata->host1x, context->syncptid);
signal_value); 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: fail:
return err; return err;