@@ -17,6 +17,7 @@ etnaviv-y := \
etnaviv_perfmon.o \
etnaviv_sched.o
+etnaviv-$(CONFIG_DEBUG_FS) += etnaviv_debugfs.o
etnaviv-$(CONFIG_DRM_ETNAVIV_PCI_DRIVER) += etnaviv_pci_drv.o \
pcie_ip_setup.o
new file mode 100644
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <drm/drm_debugfs.h>
+
+#include "etnaviv_debugfs.h"
+#include "etnaviv_drv.h"
+#include "etnaviv_gem.h"
+#include "etnaviv_gem_vram.h"
+
+static void bo_test_write_to_vram_by_cpu(void *addr, unsigned int num)
+{
+ u32 val = 0;
+
+ while (num--) {
+ writel(val, addr);
+ ++val;
+ addr += 4;
+ }
+}
+
+static unsigned int bo_test_read_from_vram_by_cpu(void *addr, unsigned int num)
+{
+ unsigned int i = 0;
+
+ while (i < num) {
+ u32 val = readl(addr);
+
+ if (val != i)
+ return i;
+
+ addr += 4;
+ ++i;
+ }
+
+ return 0;
+}
+
+void etnaviv_sanity_test_vram_impl(struct drm_device *drm, struct drm_printer *p)
+{
+ struct etnaviv_gem_object *etnaviv_obj;
+ unsigned int size = 1920 * 1080 * 4;
+ void *addr;
+ int ret;
+
+ size = ALIGN(size, PAGE_SIZE);
+
+ drm_printf(p, "Test Write to VRAM %u bytes\n", size);
+
+ ret = etnaviv_gem_new_private(drm, size, ETNA_BO_UNCACHED, false,
+ etnaviv_gem_get_vram_ops(),
+ &etnaviv_obj);
+ if (ret) {
+ drm_printf(p, "create dst bo failed\n");
+ return;
+ }
+
+ addr = etnaviv_gem_vmap(&etnaviv_obj->base);
+ if (!addr) {
+ drm_printf(p, "write to vram by cpu failed: vmap\n");
+ goto out;
+ }
+
+ etnaviv_gem_vunmap(&etnaviv_obj->base);
+
+ addr = etnaviv_gem_vmap(&etnaviv_obj->base);
+
+ bo_test_write_to_vram_by_cpu(addr, size / 4);
+
+ ret = bo_test_read_from_vram_by_cpu(addr, size / 4);
+
+ drm_printf(p, "Write to VRAM %s: %u bytes\n",
+ ret ? "not pass" : "Passed", ret ? ret : size);
+
+ etnaviv_gem_vunmap(&etnaviv_obj->base);
+out:
+ drm_gem_object_put(&etnaviv_obj->base);
+}
+
+void etnaviv_sanity_test_shmem_impl(struct drm_device *drm, struct drm_printer *p)
+{
+ struct etnaviv_gem_object *etnaviv_obj;
+ unsigned int size = 1920 * 1080 * 4;
+ void *addr;
+ int ret;
+
+ size = ALIGN(size, PAGE_SIZE);
+
+ drm_printf(p, "Test Write to SHMEM %u bytes\n", size);
+
+ ret = etnaviv_gem_new_private(drm, size, ETNA_BO_CACHED, true,
+ etnaviv_gem_get_shmem_ops(),
+ &etnaviv_obj);
+ if (ret) {
+ drm_printf(p, "create dst bo failed\n");
+ return;
+ }
+
+ addr = etnaviv_gem_vmap(&etnaviv_obj->base);
+ if (!addr) {
+ drm_printf(p, "write to shmem by cpu failed: vmap\n");
+ goto out;
+ }
+
+ etnaviv_gem_vunmap(&etnaviv_obj->base);
+
+ addr = etnaviv_gem_vmap(&etnaviv_obj->base);
+
+ bo_test_write_to_vram_by_cpu(addr, size / 4);
+
+ ret = bo_test_read_from_vram_by_cpu(addr, size / 4);
+
+ drm_printf(p, "Write to SHMEM %s: %u bytes\n",
+ ret ? "not pass" : "Passed", ret ? ret : size);
+
+ etnaviv_gem_vunmap(&etnaviv_obj->base);
+out:
+ drm_gem_object_put(&etnaviv_obj->base);
+}
new file mode 100644
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ETNAVIV_DEBUGFS_H__
+#define __ETNAVIV_DEBUGFS_H__
+
+#include "etnaviv_drv.h"
+#include "etnaviv_gem.h"
+
+void etnaviv_sanity_test_vram_impl(struct drm_device *ddev,
+ struct drm_printer *p);
+
+void etnaviv_sanity_test_shmem_impl(struct drm_device *ddev,
+ struct drm_printer *p);
+
+#endif
@@ -20,6 +20,7 @@
#include <drm/drm_prime.h>
#include "etnaviv_cmdbuf.h"
+#include "etnaviv_debugfs.h"
#include "etnaviv_drv.h"
#include "etnaviv_gpu.h"
#include "etnaviv_gem.h"
@@ -183,6 +184,16 @@ static int etnaviv_gem_show(struct drm_device *dev, struct seq_file *m)
return 0;
}
+static int etnaviv_sanity_test_show(struct drm_device *dev, struct seq_file *m)
+{
+ struct drm_printer printer = drm_seq_file_printer(m);
+
+ etnaviv_sanity_test_vram_impl(dev, &printer);
+ etnaviv_sanity_test_shmem_impl(dev, &printer);
+
+ return 0;
+}
+
static int etnaviv_mm_show(struct drm_device *dev, struct seq_file *m)
{
struct drm_printer p = drm_seq_file_printer(m);
@@ -296,6 +307,7 @@ static struct drm_info_list etnaviv_debugfs_list[] = {
{ "mm", show_unlocked, 0, etnaviv_mm_show },
{"mmu", show_each_gpu, 0, etnaviv_mmu_show},
{"ring", show_each_gpu, 0, etnaviv_ring_show},
+ {"sanity", show_unlocked, 0, etnaviv_sanity_test_show },
};
static void etnaviv_debugfs_init(struct drm_minor *minor)
@@ -553,6 +553,11 @@ static const struct etnaviv_gem_ops etnaviv_gem_shmem_ops = {
.mmap = etnaviv_gem_mmap_obj,
};
+const struct etnaviv_gem_ops *etnaviv_gem_get_shmem_ops(void)
+{
+ return &etnaviv_gem_shmem_ops;
+}
+
void etnaviv_gem_free_object(struct drm_gem_object *obj)
{
struct drm_device *drm = obj->dev;
@@ -134,4 +134,6 @@ void etnaviv_gem_mapping_unreference(struct etnaviv_vram_mapping *mapping);
u64 etnaviv_obj_gpu_phys_addr(struct etnaviv_gem_object *etnaviv_obj);
+const struct etnaviv_gem_ops *etnaviv_gem_get_shmem_ops(void);
+
#endif /* __ETNAVIV_GEM_H__ */
@@ -4,6 +4,7 @@
#include "etnaviv_drv.h"
#include "etnaviv_gem.h"
+#include "etnaviv_gem_vram.h"
#include "etnaviv_pci_drv.h"
static struct lock_class_key etnaviv_vram_lock_class;
@@ -171,6 +172,11 @@ static const struct etnaviv_gem_ops etnaviv_gem_vram_ops = {
.mmap = etnaviv_gem_vram_mmap,
};
+const struct etnaviv_gem_ops *etnaviv_gem_get_vram_ops(void)
+{
+ return &etnaviv_gem_vram_ops;
+}
+
int etnaviv_gem_new_vram(struct drm_device *dev, struct drm_file *file,
u32 size, u32 flags, u32 *handle)
{
@@ -3,6 +3,8 @@
#ifndef __ETNAVIV_GEM_VRAM_H__
#define __ETNAVIV_GEM_VRAM_H__
+const struct etnaviv_gem_ops *etnaviv_gem_get_vram_ops(void);
+
int etnaviv_gem_new_vram(struct drm_device *dev, struct drm_file *file,
u32 size, u32 flags, u32 *handle);
To test the correctess of the implemented vmap() and vunmap() operations, to see if is works correctly on dedicated VRAM. Usage: cd /sys/kernel/debug/dri/etnaviv cat sanity My test is able to pass on x86-64 with a JM9230P card, see below log: Test Write to VRAM 8294400 bytes Write to VRAM Passed: 8294400 bytes Test Write to SHMEM 8294400 bytes Write to SHMEM Passed: 8294400 bytes Signed-off-by: Sui Jingfeng <sui.jingfeng@linux.dev> --- drivers/gpu/drm/etnaviv/Makefile | 1 + drivers/gpu/drm/etnaviv/etnaviv_debugfs.c | 118 +++++++++++++++++++++ drivers/gpu/drm/etnaviv/etnaviv_debugfs.h | 15 +++ drivers/gpu/drm/etnaviv/etnaviv_drv.c | 12 +++ drivers/gpu/drm/etnaviv/etnaviv_gem.c | 5 + drivers/gpu/drm/etnaviv/etnaviv_gem.h | 2 + drivers/gpu/drm/etnaviv/etnaviv_gem_vram.c | 6 ++ drivers/gpu/drm/etnaviv/etnaviv_gem_vram.h | 2 + 8 files changed, 161 insertions(+) create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_debugfs.c create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_debugfs.h