From 939fcf7b8691b9e9ac80e92eedeb14476069021b Mon Sep 17 00:00:00 2001 From: Justin Stitt Date: Mon, 18 Sep 2023 13:34:08 +0000 Subject: [PATCH 01/11] drm/etnaviv: Replace strncpy with strscpy_pad `strncpy` is deprecated for use on NUL-terminated destination strings [1]. We should prefer more robust and less ambiguous string interfaces. A suitable replacement is `strscpy_pad` due to the fact that it guarantees NUL-termination on the destination buffer whilst maintaining the NUL-padding behavior that strncpy provides. Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1] Link: https://github.com/KSPP/linux/issues/90 Cc: linux-hardening@vger.kernel.org Cc: Bo YU Signed-off-by: Justin Stitt Reviewed-by: Kees Cook Reviewed-by: Christian Gmeiner [lst: changed subject according to suggestion from Kees] Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_perfmon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c index bafdfe49c1d8..dc9dea664a28 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -511,7 +511,7 @@ int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu, domain->id = domain->iter; domain->nr_signals = dom->nr_signals; - strncpy(domain->name, dom->name, sizeof(domain->name)); + strscpy_pad(domain->name, dom->name, sizeof(domain->name)); domain->iter++; if (domain->iter == nr_domains) @@ -540,7 +540,7 @@ int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu, sig = &dom->signal[signal->iter]; signal->id = signal->iter; - strncpy(signal->name, sig->name, sizeof(signal->name)); + strscpy_pad(signal->name, sig->name, sizeof(signal->name)); signal->iter++; if (signal->iter == dom->nr_signals) From 4c6e6c01d82fc0edd8b47cb1ffbd05289029b005 Mon Sep 17 00:00:00 2001 From: Sui Jingfeng Date: Mon, 2 Oct 2023 19:12:03 +0800 Subject: [PATCH 02/11] drm/etnaviv: Drop the second argument of the etnaviv_gem_new_impl() The mentioned second parameter is the 'u32 size', but it is not get used by the etnaviv_gem_new_impl() function, so drop it. No functional change. Signed-off-by: Sui Jingfeng Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index b5f73502e3dd..be2f459c66b5 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -542,7 +542,7 @@ static const struct drm_gem_object_funcs etnaviv_gem_object_funcs = { .vm_ops = &vm_ops, }; -static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags, +static int etnaviv_gem_new_impl(struct drm_device *dev, u32 flags, const struct etnaviv_gem_ops *ops, struct drm_gem_object **obj) { struct etnaviv_gem_object *etnaviv_obj; @@ -591,8 +591,7 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, size = PAGE_ALIGN(size); - ret = etnaviv_gem_new_impl(dev, size, flags, - &etnaviv_gem_shmem_ops, &obj); + ret = etnaviv_gem_new_impl(dev, flags, &etnaviv_gem_shmem_ops, &obj); if (ret) goto fail; @@ -627,7 +626,7 @@ int etnaviv_gem_new_private(struct drm_device *dev, size_t size, u32 flags, struct drm_gem_object *obj; int ret; - ret = etnaviv_gem_new_impl(dev, size, flags, ops, &obj); + ret = etnaviv_gem_new_impl(dev, flags, ops, &obj); if (ret) return ret; From 4cb91cc2cd0d31ffc690b23c88901f4f315b9d78 Mon Sep 17 00:00:00 2001 From: Sui Jingfeng Date: Mon, 2 Oct 2023 19:12:04 +0800 Subject: [PATCH 03/11] drm/etnaviv: Fix coding style 1) Keep the curly brace aligned. 2) No indentation by double tabs where single tab indentation is enough. Signed-off-by: Sui Jingfeng Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index a8d3fa81e4ec..a3a17316a328 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -79,7 +79,7 @@ static int etnaviv_open(struct drm_device *dev, struct drm_file *file) drm_sched_entity_init(&ctx->sched_entity[i], DRM_SCHED_PRIORITY_NORMAL, &sched, 1, NULL); - } + } } file->driver_priv = ctx; @@ -233,11 +233,11 @@ static int show_each_gpu(struct seq_file *m, void *arg) } static struct drm_info_list etnaviv_debugfs_list[] = { - {"gpu", show_each_gpu, 0, etnaviv_gpu_debugfs}, - {"gem", show_unlocked, 0, etnaviv_gem_show}, - { "mm", show_unlocked, 0, etnaviv_mm_show }, - {"mmu", show_each_gpu, 0, etnaviv_mmu_show}, - {"ring", show_each_gpu, 0, etnaviv_ring_show}, + {"gpu", show_each_gpu, 0, etnaviv_gpu_debugfs}, + {"gem", show_unlocked, 0, etnaviv_gem_show}, + { "mm", show_unlocked, 0, etnaviv_mm_show }, + {"mmu", show_each_gpu, 0, etnaviv_mmu_show}, + {"ring", show_each_gpu, 0, etnaviv_ring_show}, }; static void etnaviv_debugfs_init(struct drm_minor *minor) From a10a43eee8589221d79b9050556aed2c5842d8b8 Mon Sep 17 00:00:00 2001 From: Sui Jingfeng Date: Mon, 2 Oct 2023 19:12:05 +0800 Subject: [PATCH 04/11] drm/etnaviv: Add helper functions to create and destroy platform device The newly introduced functions are etnaviv_create_platform_device() and etnaviv_destroy_platform_device(). Those two function are pure function and can be shared for other use case. Currently, the benefit is that we no longer need to call of_node_put() for three different cases, we only need to call it once in the etnaviv_init() function. Signed-off-by: Sui Jingfeng Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 57 ++++++++++++++++++--------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index a3a17316a328..8fe39e31d22d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -655,11 +655,43 @@ static struct platform_driver etnaviv_platform_driver = { }, }; +static int etnaviv_create_platform_device(const char *name, + struct platform_device **ppdev) +{ + struct platform_device *pdev; + int ret; + + pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE); + if (!pdev) + return -ENOMEM; + + ret = platform_device_add(pdev); + if (ret) { + platform_device_put(pdev); + return ret; + } + + *ppdev = pdev; + + return 0; +} + +static void etnaviv_destroy_platform_device(struct platform_device **ppdev) +{ + struct platform_device *pdev = *ppdev; + + if (!pdev) + return; + + platform_device_unregister(pdev); + + *ppdev = NULL; +} + static struct platform_device *etnaviv_drm; static int __init etnaviv_init(void) { - struct platform_device *pdev; int ret; struct device_node *np; @@ -680,23 +712,12 @@ static int __init etnaviv_init(void) for_each_compatible_node(np, NULL, "vivante,gc") { if (!of_device_is_available(np)) continue; - - pdev = platform_device_alloc("etnaviv", PLATFORM_DEVID_NONE); - if (!pdev) { - ret = -ENOMEM; - of_node_put(np); - goto unregister_platform_driver; - } - - ret = platform_device_add(pdev); - if (ret) { - platform_device_put(pdev); - of_node_put(np); - goto unregister_platform_driver; - } - - etnaviv_drm = pdev; of_node_put(np); + + ret = etnaviv_create_platform_device("etnaviv", &etnaviv_drm); + if (ret) + goto unregister_platform_driver; + break; } @@ -712,7 +733,7 @@ module_init(etnaviv_init); static void __exit etnaviv_exit(void) { - platform_device_unregister(etnaviv_drm); + etnaviv_destroy_platform_device(&etnaviv_drm); platform_driver_unregister(&etnaviv_platform_driver); platform_driver_unregister(&etnaviv_gpu_driver); } From f5cc0cbc2796627d8b9c561a8e135fe34615b654 Mon Sep 17 00:00:00 2001 From: Sui Jingfeng Date: Mon, 2 Oct 2023 19:12:06 +0800 Subject: [PATCH 05/11] drm/etnaviv: Add a helper to get the first available GPU device node This patch make the code in the etnaviv_pdev_probe() less twisted, and it also make it easier to drop the reference to device node after finished. Before apply this patch, there is no call to of_node_put() when done. We should call of_node_put() when done. Signed-off-by: Sui Jingfeng Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 8fe39e31d22d..4bdfb1c81eff 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -29,6 +29,17 @@ * DRM operations: */ +static struct device_node *etnaviv_of_first_available_node(void) +{ + struct device_node *np; + + for_each_compatible_node(np, NULL, "vivante,gc") { + if (of_device_is_available(np)) + return np; + } + + return NULL; +} static void load_gpu(struct drm_device *dev) { @@ -597,9 +608,6 @@ static int etnaviv_pdev_probe(struct platform_device *pdev) if (!of_device_is_available(core_node)) continue; - if (!first_node) - first_node = core_node; - drm_of_component_match_add(&pdev->dev, &match, component_compare_of, core_node); } @@ -634,8 +642,11 @@ static int etnaviv_pdev_probe(struct platform_device *pdev) * device as the GPU we found. This assumes that all Vivante * GPUs in the system share the same DMA constraints. */ - if (first_node) + first_node = etnaviv_of_first_available_node(); + if (first_node) { of_dma_configure(&pdev->dev, first_node, true); + of_node_put(first_node); + } return component_master_add_with_match(dev, &etnaviv_master_ops, match); } @@ -709,16 +720,13 @@ static int __init etnaviv_init(void) * If the DT contains at least one available GPU device, instantiate * the DRM platform device. */ - for_each_compatible_node(np, NULL, "vivante,gc") { - if (!of_device_is_available(np)) - continue; + np = etnaviv_of_first_available_node(); + if (np) { of_node_put(np); ret = etnaviv_create_platform_device("etnaviv", &etnaviv_drm); if (ret) goto unregister_platform_driver; - - break; } return 0; From e8491f0238625b156e2d82c49fd8c838352b7e74 Mon Sep 17 00:00:00 2001 From: Sui Jingfeng Date: Mon, 2 Oct 2023 19:12:07 +0800 Subject: [PATCH 06/11] drm/etnaviv: Clean up etnaviv_gem_get_pages As in the etnaviv_gem_get_pages() function, the point to the drm_device has already been cached to the 'dev' local variable. We can use it directly, While at it, using 'unsigned int' type to count the number of pages. As the drm_prime_pages_to_sg() function takes an unsigned int type for its third argument. No functional change. Signed-off-by: Sui Jingfeng [lst: Reword subject to make more generic and match patch content] Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index be2f459c66b5..71a6d2b1c80f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -100,11 +100,10 @@ struct page **etnaviv_gem_get_pages(struct etnaviv_gem_object *etnaviv_obj) if (!etnaviv_obj->sgt) { struct drm_device *dev = etnaviv_obj->base.dev; - int npages = etnaviv_obj->base.size >> PAGE_SHIFT; + unsigned int npages = etnaviv_obj->base.size >> PAGE_SHIFT; struct sg_table *sgt; - sgt = drm_prime_pages_to_sg(etnaviv_obj->base.dev, - etnaviv_obj->pages, npages); + sgt = drm_prime_pages_to_sg(dev, etnaviv_obj->pages, npages); if (IS_ERR(sgt)) { dev_err(dev->dev, "failed to allocate sgt: %ld\n", PTR_ERR(sgt)); From 9e2e8a5113bf452081cb1f6a13617e36f5298cbf Mon Sep 17 00:00:00 2001 From: Sui Jingfeng Date: Sat, 7 Oct 2023 15:03:12 +0800 Subject: [PATCH 07/11] drm/etnaviv: Drop the 'len' parameter of etnaviv_iommu_map() function The 'len' parameter is the 4th argument, because it is not get used, so drop it. No functional change. Signed-off-by: Sui Jingfeng Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c index 4fa72567183a..1661d589bf3e 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -70,7 +70,7 @@ static int etnaviv_context_map(struct etnaviv_iommu_context *context, } static int etnaviv_iommu_map(struct etnaviv_iommu_context *context, u32 iova, - struct sg_table *sgt, unsigned len, int prot) + struct sg_table *sgt, int prot) { struct scatterlist *sg; unsigned int da = iova; unsigned int i; @@ -314,7 +314,7 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu_context *context, goto unlock; mapping->iova = node->start; - ret = etnaviv_iommu_map(context, node->start, sgt, etnaviv_obj->base.size, + ret = etnaviv_iommu_map(context, node->start, sgt, ETNAVIV_PROT_READ | ETNAVIV_PROT_WRITE); if (ret < 0) { From b0da08559c749ddc0e9a6e378b292ffa6845fb01 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 7 Jun 2023 14:58:41 +0200 Subject: [PATCH 08/11] drm/etnaviv: disable MLCG and pulse eater on GPU reset Module level clock gating and the pulse eater might interfere with the GPU reset, as they both have the potential to stop the clock and thus reset propagation to parts of the GPU. Signed-off-by: Lucas Stach Reviewed-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 9276756e1397..1dcfa23db3be 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -513,8 +513,19 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) timeout = jiffies + msecs_to_jiffies(1000); while (time_is_after_jiffies(timeout)) { - /* enable clock */ unsigned int fscale = 1 << (6 - gpu->freq_scale); + u32 pulse_eater = 0x01590880; + + /* disable clock gating */ + gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, 0x0); + + /* disable pulse eater */ + pulse_eater |= BIT(17); + gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater); + pulse_eater |= BIT(0); + gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater); + + /* enable clock */ control = VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(fscale); etnaviv_gpu_load_clock(gpu, control); From 1dccdba084897443d116508a8ed71e0ac8a031a4 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Tue, 21 Nov 2023 07:32:59 +0100 Subject: [PATCH 09/11] drm/etnaviv: Expose a few more chipspecs to userspace These ones will be needed to make use fo the NN and TP units in the NPUs based on Vivante IP. Also fix the number of NN cores in the VIPNano-qi. Signed-off-by: Tomeu Vizoso Acked-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 20 +++++++++++++++ drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 12 +++++++++ drivers/gpu/drm/etnaviv/etnaviv_hwdb.c | 34 ++++++++++++++++++++++++++ include/uapi/drm/etnaviv_drm.h | 5 ++++ 4 files changed, 71 insertions(+) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 1dcfa23db3be..18725ff5c79b 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -164,6 +164,26 @@ int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value) *value = gpu->identity.eco_id; break; + case ETNAVIV_PARAM_GPU_NN_CORE_COUNT: + *value = gpu->identity.nn_core_count; + break; + + case ETNAVIV_PARAM_GPU_NN_MAD_PER_CORE: + *value = gpu->identity.nn_mad_per_core; + break; + + case ETNAVIV_PARAM_GPU_TP_CORE_COUNT: + *value = gpu->identity.tp_core_count; + break; + + case ETNAVIV_PARAM_GPU_ON_CHIP_SRAM_SIZE: + *value = gpu->identity.on_chip_sram_size; + break; + + case ETNAVIV_PARAM_GPU_AXI_SRAM_SIZE: + *value = gpu->identity.axi_sram_size; + break; + default: DBG("%s: invalid param: %u", dev_name(gpu->dev), param); return -EINVAL; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index 197e0037732e..7d5e9158e13c 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -54,6 +54,18 @@ struct etnaviv_chip_identity { /* Number of Neural Network cores. */ u32 nn_core_count; + /* Number of MAD units per Neural Network core. */ + u32 nn_mad_per_core; + + /* Number of Tensor Processing cores. */ + u32 tp_core_count; + + /* Size in bytes of the SRAM inside the NPU. */ + u32 on_chip_sram_size; + + /* Size in bytes of the SRAM across the AXI bus. */ + u32 axi_sram_size; + /* Size of the vertex cache. */ u32 vertex_cache_size; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c index 67201242438b..9eb8ca7c5034 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c @@ -17,6 +17,10 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { .thread_count = 128, .shader_core_count = 1, .nn_core_count = 0, + .nn_mad_per_core = 0, + .tp_core_count = 0, + .on_chip_sram_size = 0, + .axi_sram_size = 0, .vertex_cache_size = 8, .vertex_output_buffer_size = 1024, .pixel_pipes = 1, @@ -48,6 +52,11 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { .register_max = 64, .thread_count = 256, .shader_core_count = 1, + .nn_core_count = 0, + .nn_mad_per_core = 0, + .tp_core_count = 0, + .on_chip_sram_size = 0, + .axi_sram_size = 0, .vertex_cache_size = 8, .vertex_output_buffer_size = 512, .pixel_pipes = 1, @@ -80,6 +89,10 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { .thread_count = 512, .shader_core_count = 2, .nn_core_count = 0, + .nn_mad_per_core = 0, + .tp_core_count = 0, + .on_chip_sram_size = 0, + .axi_sram_size = 0, .vertex_cache_size = 16, .vertex_output_buffer_size = 1024, .pixel_pipes = 1, @@ -112,6 +125,10 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { .thread_count = 512, .shader_core_count = 2, .nn_core_count = 0, + .nn_mad_per_core = 0, + .tp_core_count = 0, + .on_chip_sram_size = 0, + .axi_sram_size = 0, .vertex_cache_size = 16, .vertex_output_buffer_size = 1024, .pixel_pipes = 1, @@ -143,6 +160,11 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { .register_max = 64, .thread_count = 512, .shader_core_count = 2, + .nn_core_count = 0, + .nn_mad_per_core = 0, + .tp_core_count = 0, + .on_chip_sram_size = 0, + .axi_sram_size = 0, .vertex_cache_size = 16, .vertex_output_buffer_size = 1024, .pixel_pipes = 1, @@ -175,6 +197,10 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { .thread_count = 1024, .shader_core_count = 4, .nn_core_count = 0, + .nn_mad_per_core = 0, + .tp_core_count = 0, + .on_chip_sram_size = 0, + .axi_sram_size = 0, .vertex_cache_size = 16, .vertex_output_buffer_size = 1024, .pixel_pipes = 2, @@ -207,6 +233,10 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { .thread_count = 256, .shader_core_count = 1, .nn_core_count = 8, + .nn_mad_per_core = 64, + .tp_core_count = 4, + .on_chip_sram_size = 524288, + .axi_sram_size = 1048576, .vertex_cache_size = 16, .vertex_output_buffer_size = 1024, .pixel_pipes = 1, @@ -239,6 +269,10 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { .thread_count = 256, .shader_core_count = 1, .nn_core_count = 6, + .nn_mad_per_core = 64, + .tp_core_count = 3, + .on_chip_sram_size = 262144, + .axi_sram_size = 0, .vertex_cache_size = 16, .vertex_output_buffer_size = 1024, .pixel_pipes = 1, diff --git a/include/uapi/drm/etnaviv_drm.h b/include/uapi/drm/etnaviv_drm.h index af024d90453d..d87410a8443a 100644 --- a/include/uapi/drm/etnaviv_drm.h +++ b/include/uapi/drm/etnaviv_drm.h @@ -77,6 +77,11 @@ struct drm_etnaviv_timespec { #define ETNAVIV_PARAM_GPU_PRODUCT_ID 0x1c #define ETNAVIV_PARAM_GPU_CUSTOMER_ID 0x1d #define ETNAVIV_PARAM_GPU_ECO_ID 0x1e +#define ETNAVIV_PARAM_GPU_NN_CORE_COUNT 0x1f +#define ETNAVIV_PARAM_GPU_NN_MAD_PER_CORE 0x20 +#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 ETNA_MAX_PIPES 4 From c9959996a8fc171bbb2c2d9c7478306f331a6cca Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Thu, 7 Dec 2023 08:43:08 +0100 Subject: [PATCH 10/11] drm/etnaviv: add sensitive state for PE_RT_ADDR_4_PIPE(3, 0|1) address 0x1540 is the address of 4th render target address pair (two pixel pipes). Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c b/drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c index b106e8b288ad..9bf47327f436 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_cmd_parser.c @@ -54,6 +54,7 @@ static const struct { ST(0x1480, 8), ST(0x1500, 8), ST(0x1520, 8), + ST(0x1540, 8), ST(0x1608, 1), ST(0x1610, 1), ST(0x1658, 1), From b735ee173f84d5d0d0733c53946a83c12d770d05 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Fri, 1 Mar 2024 14:28:11 +0100 Subject: [PATCH 11/11] drm/etnaviv: Restore some id values The hwdb selection logic as a feature that allows it to mark some fields as 'don't care'. If we match with such a field we memcpy(..) the current etnaviv_chip_identity into ident. This step can overwrite some id values read from the GPU with the 'don't care' value. Fix this issue by restoring the affected values after the memcpy(..). As this is crucial for user space to know when this feature works as expected increment the minor version too. Fixes: 4078a1186dd3 ("drm/etnaviv: update hwdb selection logic") Cc: stable@vger.kernel.org Signed-off-by: Christian Gmeiner Reviewed-by: Tomeu Vizoso Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_hwdb.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 4bdfb1c81eff..491da486c4e5 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -505,7 +505,7 @@ static const struct drm_driver etnaviv_drm_driver = { .desc = "etnaviv DRM", .date = "20151214", .major = 1, - .minor = 3, + .minor = 4, }; /* diff --git a/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c index 9eb8ca7c5034..d8e7334de8ce 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c @@ -299,6 +299,9 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu) { struct etnaviv_chip_identity *ident = &gpu->identity; + const u32 product_id = ident->product_id; + const u32 customer_id = ident->customer_id; + const u32 eco_id = ident->eco_id; int i; for (i = 0; i < ARRAY_SIZE(etnaviv_chip_identities); i++) { @@ -312,6 +315,12 @@ bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu) etnaviv_chip_identities[i].eco_id == ~0U)) { memcpy(ident, &etnaviv_chip_identities[i], sizeof(*ident)); + + /* Restore some id values as ~0U aka 'don't care' might been used. */ + ident->product_id = product_id; + ident->customer_id = customer_id; + ident->eco_id = eco_id; + return true; } }