From: Sui Jingfeng <sui.jingfeng@linux.dev>
To: Lucas Stach <l.stach@pengutronix.de>
Cc: Russell King <linux+etnaviv@armlinux.org.uk>,
Christian Gmeiner <christian.gmeiner@gmail.com>,
David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
dri-devel@lists.freedesktop.org, etnaviv@lists.freedesktop.org,
linux-kernel@vger.kernel.org,
Sui Jingfeng <sui.jingfeng@linux.dev>
Subject: [etnaviv-next v13 4/7] drm/etnaviv: Add support for cached coherent caching mode
Date: Wed, 7 Feb 2024 01:27:56 +0800 [thread overview]
Message-ID: <20240206172759.421737-5-sui.jingfeng@linux.dev> (raw)
In-Reply-To: <20240206172759.421737-1-sui.jingfeng@linux.dev>
In the etnaviv_gem_vmap_impl(), update the page property from writecombine
to PAGE_KERNEL on cached mapping. Previously, it use writecombine page
property to vmap cached buffer unconditionally. Many modern CPUs choose to
define the peripheral devices as DMA coherent by default, to be specific,
the peripheral devices are capable of snooping CPU's cache. Therefore,
cached buffers should be accessed with cached mapping.
While at it, probe cached coherent support at the host platform with the
dev_is_dma_coherent() function. This allows userspace to query on the
runtime, which avoid compile-time macros (#ifdefs). Modern CPUs choose to
define the peripheral devices as DMA coherent by default, In other words,
the peripheral devices are capable of snooping CPU's cache. This means
that device drivers do not need to maintain the coherency issue between
a processor and an peripheral I/O for the cached mapping buffers. Such a
hardware feature is implementation-defined by host CPU platform, not the
vivante GPU IP core itself. X86-64, LoongArch and Loongson Mips CPU and
some ARM64 CPU has the hardware maintain cache coherency, but ARM CPU is
not. So provide mechanism to let userspace know.
Signed-off-by: Sui Jingfeng <sui.jingfeng@linux.dev>
---
drivers/gpu/drm/etnaviv/etnaviv_drv.c | 3 +++
drivers/gpu/drm/etnaviv/etnaviv_drv.h | 8 ++++++++
drivers/gpu/drm/etnaviv/etnaviv_gem.c | 16 ++++++++++++++--
drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 4 ++++
include/uapi/drm/etnaviv_drm.h | 1 +
5 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 5ba2b3a386b3..e3a05b8b9330 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -5,6 +5,7 @@
#include <linux/component.h>
#include <linux/dma-mapping.h>
+#include <linux/dma-map-ops.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -57,6 +58,8 @@ static int etnaviv_private_init(struct device *dev,
return -ENOMEM;
}
+ priv->cached_coherent = dev_is_dma_coherent(dev);
+
return 0;
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index 1f9b50b5a6aa..9c05f503747a 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -46,6 +46,14 @@ struct etnaviv_drm_private {
struct xarray active_contexts;
u32 next_context_id;
+ /*
+ * If true, the cached mapping is consistent for all CPU cores and
+ * peripheral bus masters in the system. It means that vboth of the
+ * CPU and GPU will see the same data if the buffer being access is
+ * cached. And coherency is guaranteed by the arch specific hardware.
+ */
+ bool cached_coherent;
+
/* list of GEM objects: */
struct mutex gem_lock;
struct list_head gem_list;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index aa95a5e98374..eed98bb9e446 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -342,6 +342,7 @@ void *etnaviv_gem_vmap(struct drm_gem_object *obj)
static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj)
{
struct page **pages;
+ pgprot_t prot;
lockdep_assert_held(&obj->lock);
@@ -349,8 +350,19 @@ static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj)
if (IS_ERR(pages))
return NULL;
- return vmap(pages, obj->base.size >> PAGE_SHIFT,
- VM_MAP, pgprot_writecombine(PAGE_KERNEL));
+ switch (obj->flags) {
+ case ETNA_BO_CACHED:
+ prot = PAGE_KERNEL;
+ break;
+ case ETNA_BO_UNCACHED:
+ prot = pgprot_noncached(PAGE_KERNEL);
+ break;
+ case ETNA_BO_WC:
+ default:
+ prot = pgprot_writecombine(PAGE_KERNEL);
+ }
+
+ return vmap(pages, obj->base.size >> PAGE_SHIFT, VM_MAP, prot);
}
static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index a407c2c9e140..306973660653 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -184,6 +184,10 @@ int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value)
*value = gpu->identity.axi_sram_size;
break;
+ case ETNAVIV_PARAM_CACHED_COHERENT:
+ *value = priv->cached_coherent;
+ break;
+
default:
DBG("%s: invalid param: %u", dev_name(gpu->dev), param);
return -EINVAL;
diff --git a/include/uapi/drm/etnaviv_drm.h b/include/uapi/drm/etnaviv_drm.h
index d87410a8443a..7c5d988a5b9f 100644
--- a/include/uapi/drm/etnaviv_drm.h
+++ b/include/uapi/drm/etnaviv_drm.h
@@ -82,6 +82,7 @@ struct drm_etnaviv_timespec {
#define ETNAVIV_PARAM_GPU_TP_CORE_COUNT 0x21
#define ETNAVIV_PARAM_GPU_ON_CHIP_SRAM_SIZE 0x22
#define ETNAVIV_PARAM_GPU_AXI_SRAM_SIZE 0x23
+#define ETNAVIV_PARAM_CACHED_COHERENT 0x24
#define ETNA_MAX_PIPES 4
--
2.34.1
next prev parent reply other threads:[~2024-02-06 17:28 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-06 17:27 [etnaviv-next v13 0/7] drm/etnaviv: Add driver wrapper for vivante GPUs attached on PCI(e) device Sui Jingfeng
2024-02-06 17:27 ` [etnaviv-next v13 1/7] drm/etnaviv: Add a helper function to get clocks Sui Jingfeng
2024-02-06 17:27 ` [etnaviv-next v13 2/7] drm/etnaviv: Add constructor and destructor for the etnaviv_drm_private struct Sui Jingfeng
2024-02-06 17:27 ` [etnaviv-next v13 3/7] drm/etnaviv: Embed struct drm_device in struct etnaviv_drm_private Sui Jingfeng
2024-02-06 17:27 ` Sui Jingfeng [this message]
2024-02-06 17:27 ` [etnaviv-next v13 5/7] drm/etnaviv: Replace the '&pdev->dev' with 'dev' Sui Jingfeng
2024-02-06 17:27 ` [etnaviv-next v13 6/7] drm/etnaviv: Update the implement of etnaviv_create_platform_device() Sui Jingfeng
2024-02-06 17:27 ` [etnaviv-next v13 7/7] drm/etnaviv: Add support for vivante GPU cores attached via PCI(e) Sui Jingfeng
2024-02-07 9:35 ` Daniel Vetter
2024-02-07 15:22 ` Sui Jingfeng
2024-02-08 15:27 ` Maxime Ripard
2024-02-09 11:02 ` Daniel Vetter
2024-02-09 15:15 ` Maxime Ripard
2024-02-09 16:25 ` Sui Jingfeng
2024-02-13 14:38 ` Maxime Ripard
2024-02-13 15:48 ` Sui Jingfeng
2024-02-14 4:54 ` Sui Jingfeng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240206172759.421737-5-sui.jingfeng@linux.dev \
--to=sui.jingfeng@linux.dev \
--cc=airlied@gmail.com \
--cc=christian.gmeiner@gmail.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=etnaviv@lists.freedesktop.org \
--cc=l.stach@pengutronix.de \
--cc=linux+etnaviv@armlinux.org.uk \
--cc=linux-kernel@vger.kernel.org \
--cc=mripard@kernel.org \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®