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@xxxxxxxxx> --- 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 diff --git a/drivers/gpu/drm/etnaviv/Makefile b/drivers/gpu/drm/etnaviv/Makefile index aba2578966ff..f278e75ee7cd 100644 --- a/drivers/gpu/drm/etnaviv/Makefile +++ b/drivers/gpu/drm/etnaviv/Makefile @@ -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 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_debugfs.c b/drivers/gpu/drm/etnaviv/etnaviv_debugfs.c new file mode 100644 index 000000000000..0cfedbc6574c --- /dev/null +++ b/drivers/gpu/drm/etnaviv/etnaviv_debugfs.c @@ -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); +} diff --git a/drivers/gpu/drm/etnaviv/etnaviv_debugfs.h b/drivers/gpu/drm/etnaviv/etnaviv_debugfs.h new file mode 100644 index 000000000000..5214349534ef --- /dev/null +++ b/drivers/gpu/drm/etnaviv/etnaviv_debugfs.h @@ -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 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index cdc62f64b200..e500b8caf138 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -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) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index ee799c02d0aa..31bcd80770b3 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -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; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnaviv/etnaviv_gem.h index 60bbbbc2dd19..1836e1d82df2 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h @@ -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__ */ diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_vram.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_vram.c index c2942317a64e..1ca558429387 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_vram.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_vram.c @@ -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) { diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_vram.h b/drivers/gpu/drm/etnaviv/etnaviv_gem_vram.h index bbce93f118a2..54f98936ddb4 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_vram.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_vram.h @@ -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); -- 2.43.0