From d3e0d8bb363ee7d1642c1f5715b094f162021c21 Mon Sep 17 00:00:00 2001 From: Mainak Sen Date: Tue, 1 Apr 2025 10:40:58 +0000 Subject: [PATCH] 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 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3330688 Reviewed-by: svcacv Reviewed-by: Mitch Harwell GVS: buildbot_gerritrpt Reviewed-by: Arvind M --- .../nvdla/port/sync/nvdla_sync_syncpt_emu.c | 172 +++++++++++++++--- 1 file changed, 149 insertions(+), 23 deletions(-) diff --git a/drivers/video/tegra/host/nvdla/port/sync/nvdla_sync_syncpt_emu.c b/drivers/video/tegra/host/nvdla/port/sync/nvdla_sync_syncpt_emu.c index 03fb45c8..976add4b 100644 --- a/drivers/video/tegra/host/nvdla/port/sync/nvdla_sync_syncpt_emu.c +++ b/drivers/video/tegra/host/nvdla/port/sync/nvdla_sync_syncpt_emu.c @@ -11,6 +11,15 @@ #include #include #include +#include +#include + +/* 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;