[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260114-thames-v2-5-e94a6636e050@tomeuvizoso.net>
Date: Wed, 14 Jan 2026 09:46:52 +0100
From: Tomeu Vizoso <tomeu@...euvizoso.net>
To: Nishanth Menon <nm@...com>, "Andrew F. Davis" <afd@...com>,
Randolph Sapp <rs@...com>, Jonathan Humphreys <j-humphreys@...com>,
Andrei Aldea <a-aldea@...com>, Chirag Shilwant <c-shilwant@...com>,
Vignesh Raghavendra <vigneshr@...com>, Tero Kristo <kristo@...nel.org>,
Rob Herring <robh@...nel.org>, Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>, Oded Gabbay <ogabbay@...nel.org>,
Jonathan Corbet <corbet@....net>, Sumit Semwal <sumit.semwal@...aro.org>,
Christian König <christian.koenig@....com>,
Robert Nelson <robertcnelson@...il.com>, David Airlie <airlied@...il.com>,
Simona Vetter <simona@...ll.ch>,
Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
Maxime Ripard <mripard@...nel.org>, Thomas Zimmermann <tzimmermann@...e.de>
Cc: linux-arm-kernel@...ts.infradead.org, devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org, dri-devel@...ts.freedesktop.org,
linux-doc@...r.kernel.org, linux-media@...r.kernel.org,
linaro-mm-sig@...ts.linaro.org, Tomeu Vizoso <tomeu@...euvizoso.net>
Subject: [PATCH v2 5/5] accel/thames: Add IOCTL for memory synchronization
The DSP cores have their own access to the memory bus, and it isn't
cache coherent with the CPUs.
Add IOCTLs so userspace can mark when the caches need to be flushed, and
also when a writer job needs to be waited for before the buffer can be
accessed from the CPU.
Initially based on the same IOCTLs from the Etnaviv driver.
v2:
- Add thames_accel.h UAPI header (Robert Nelson).
Signed-off-by: Tomeu Vizoso <tomeu@...euvizoso.net>
---
drivers/accel/thames/thames_drv.c | 2 ++
drivers/accel/thames/thames_gem.c | 52 +++++++++++++++++++++++++++++++++++++++
drivers/accel/thames/thames_gem.h | 4 +++
include/uapi/drm/thames_accel.h | 31 +++++++++++++++++++++++
4 files changed, 89 insertions(+)
diff --git a/drivers/accel/thames/thames_drv.c b/drivers/accel/thames/thames_drv.c
index 1ff01428e6c80765cb741ae45c67971b7b0f28c8..6993d503139d3aaef830cdf5cfcf38476c5f9d99 100644
--- a/drivers/accel/thames/thames_drv.c
+++ b/drivers/accel/thames/thames_drv.c
@@ -76,6 +76,8 @@ static const struct drm_ioctl_desc thames_drm_driver_ioctls[] = {
THAMES_IOCTL(BO_CREATE, bo_create),
THAMES_IOCTL(BO_MMAP_OFFSET, bo_mmap_offset),
THAMES_IOCTL(SUBMIT, submit),
+ THAMES_IOCTL(BO_PREP, bo_prep),
+ THAMES_IOCTL(BO_FINI, bo_fini),
};
DEFINE_DRM_ACCEL_FOPS(thames_accel_driver_fops);
diff --git a/drivers/accel/thames/thames_gem.c b/drivers/accel/thames/thames_gem.c
index 5a01ddaeb2448117d400a79e53d2c6123ecb5390..4ded8fab0f3ff6f75a1446c5661fdbc68f1f2ac7 100644
--- a/drivers/accel/thames/thames_gem.c
+++ b/drivers/accel/thames/thames_gem.c
@@ -351,3 +351,55 @@ int thames_ioctl_bo_mmap_offset(struct drm_device *ddev, void *data, struct drm_
return 0;
}
+
+int thames_ioctl_bo_prep(struct drm_device *ddev, void *data, struct drm_file *file)
+{
+ struct drm_thames_bo_prep *args = data;
+ struct drm_gem_object *gem_obj;
+ struct drm_gem_shmem_object *shmem_obj;
+ unsigned long timeout = drm_timeout_abs_to_jiffies(args->timeout_ns);
+ long ret = 0;
+
+ if (args->reserved != 0)
+ return -EINVAL;
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ return -ENOENT;
+
+ ret = dma_resv_wait_timeout(gem_obj->resv, DMA_RESV_USAGE_WRITE, true, timeout);
+ if (!ret)
+ ret = timeout ? -ETIMEDOUT : -EBUSY;
+
+ shmem_obj = &to_thames_bo(gem_obj)->base;
+
+ dma_sync_sgtable_for_cpu(ddev->dev, shmem_obj->sgt, DMA_FROM_DEVICE);
+
+ drm_gem_object_put(gem_obj);
+
+ return ret;
+}
+
+int thames_ioctl_bo_fini(struct drm_device *ddev, void *data, struct drm_file *file)
+{
+ struct drm_thames_bo_fini *args = data;
+ struct drm_gem_shmem_object *shmem_obj;
+ struct thames_gem_object *thames_obj;
+ struct drm_gem_object *gem_obj;
+
+ if (args->reserved != 0)
+ return -EINVAL;
+
+ gem_obj = drm_gem_object_lookup(file, args->handle);
+ if (!gem_obj)
+ return -ENOENT;
+
+ thames_obj = to_thames_bo(gem_obj);
+ shmem_obj = &thames_obj->base;
+
+ dma_sync_sgtable_for_device(ddev->dev, shmem_obj->sgt, DMA_TO_DEVICE);
+
+ drm_gem_object_put(gem_obj);
+
+ return 0;
+}
diff --git a/drivers/accel/thames/thames_gem.h b/drivers/accel/thames/thames_gem.h
index 785843c40a89a9e84ab634aad77e9ec46111693e..e5a8278e98c578c2903cf23aea1bf887be0389e8 100644
--- a/drivers/accel/thames/thames_gem.h
+++ b/drivers/accel/thames/thames_gem.h
@@ -29,6 +29,10 @@ int thames_ioctl_bo_create(struct drm_device *ddev, void *data, struct drm_file
int thames_ioctl_bo_mmap_offset(struct drm_device *ddev, void *data, struct drm_file *file);
+int thames_ioctl_bo_prep(struct drm_device *ddev, void *data, struct drm_file *file);
+
+int thames_ioctl_bo_fini(struct drm_device *ddev, void *data, struct drm_file *file);
+
int thames_context_create(struct thames_file_priv *priv);
void thames_context_destroy(struct thames_file_priv *priv);
diff --git a/include/uapi/drm/thames_accel.h b/include/uapi/drm/thames_accel.h
index 5b35e50826ed95bfcc3709bef33416d2b6d11c70..07477087211c14721298ff52a1f3d253a6e65d58 100644
--- a/include/uapi/drm/thames_accel.h
+++ b/include/uapi/drm/thames_accel.h
@@ -31,6 +31,12 @@ enum drm_thames_ioctl_id {
/** @DRM_THAMES_SUBMIT: Submit a job and BOs to run. */
DRM_THAMES_SUBMIT,
+
+ /** @DRM_THAMES_BO_PREP: Prepare a BO for CPU access after DSP writes. */
+ DRM_THAMES_BO_PREP,
+
+ /** @DRM_THAMES_BO_FINI: Finish CPU access and prepare BO for DSP access. */
+ DRM_THAMES_BO_FINI,
};
/**
@@ -127,6 +133,27 @@ struct drm_thames_submit {
__u32 pad;
};
+/**
+ * struct drm_thames_bo_prep - ioctl argument for preparing a BO for CPU access.
+ *
+ * This invalidates CPU caches and waits for pending DSP operations to complete.
+ */
+struct drm_thames_bo_prep {
+ __u32 handle;
+ __u32 reserved;
+ __s64 timeout_ns; /* absolute */
+};
+
+/**
+ * struct drm_thames_bo_fini - ioctl argument for finishing CPU access to a BO.
+ *
+ * This flushes CPU caches to make CPU writes visible to the DSP.
+ */
+struct drm_thames_bo_fini {
+ __u32 handle;
+ __u32 reserved;
+};
+
/**
* DRM_IOCTL_THAMES() - Build a thames IOCTL number
* @__access: Access type. Must be R, W or RW.
@@ -149,6 +176,10 @@ enum {
DRM_IOCTL_THAMES(WR, BO_MMAP_OFFSET, bo_mmap_offset),
DRM_IOCTL_THAMES_SUBMIT =
DRM_IOCTL_THAMES(WR, SUBMIT, submit),
+ DRM_IOCTL_THAMES_BO_PREP =
+ DRM_IOCTL_THAMES(WR, BO_PREP, bo_prep),
+ DRM_IOCTL_THAMES_BO_FINI =
+ DRM_IOCTL_THAMES(WR, BO_FINI, bo_fini),
};
#if defined(__cplusplus)
--
2.52.0
Powered by blists - more mailing lists