summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/etnaviv
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/etnaviv')
-rw-r--r--drivers/gpu/drm/etnaviv/Makefile1
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_buffer.c75
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_buffer.h99
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.c3
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.h3
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c224
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_flop_reset.h21
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c11
-rw-r--r--drivers/gpu/drm/etnaviv/state_3d.xml.h95
9 files changed, 463 insertions, 69 deletions
diff --git a/drivers/gpu/drm/etnaviv/Makefile b/drivers/gpu/drm/etnaviv/Makefile
index 46e5ffad69a6..903101e8751a 100644
--- a/drivers/gpu/drm/etnaviv/Makefile
+++ b/drivers/gpu/drm/etnaviv/Makefile
@@ -14,6 +14,7 @@ etnaviv-y := \
etnaviv_iommu.o \
etnaviv_mmu.o \
etnaviv_perfmon.o \
+ etnaviv_flop_reset.o \
etnaviv_sched.o
obj-$(CONFIG_DRM_ETNAVIV) += etnaviv.o
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
index ad5e6f7b23f9..03b2576af67f 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
@@ -10,6 +10,7 @@
#include "etnaviv_gpu.h"
#include "etnaviv_gem.h"
#include "etnaviv_mmu.h"
+#include "etnaviv_buffer.h"
#include "common.xml.h"
#include "state.xml.h"
@@ -18,75 +19,7 @@
#include "state_3d.xml.h"
#include "cmdstream.xml.h"
-/*
- * Command Buffer helper:
- */
-
-
-static inline void OUT(struct etnaviv_cmdbuf *buffer, u32 data)
-{
- u32 *vaddr = (u32 *)buffer->vaddr;
-
- BUG_ON(buffer->user_size >= buffer->size);
-
- vaddr[buffer->user_size / 4] = data;
- buffer->user_size += 4;
-}
-
-static inline void CMD_LOAD_STATE(struct etnaviv_cmdbuf *buffer,
- u32 reg, u32 value)
-{
- u32 index = reg >> VIV_FE_LOAD_STATE_HEADER_OFFSET__SHR;
-
- buffer->user_size = ALIGN(buffer->user_size, 8);
-
- /* write a register via cmd stream */
- OUT(buffer, VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE |
- VIV_FE_LOAD_STATE_HEADER_COUNT(1) |
- VIV_FE_LOAD_STATE_HEADER_OFFSET(index));
- OUT(buffer, value);
-}
-
-static inline void CMD_END(struct etnaviv_cmdbuf *buffer)
-{
- buffer->user_size = ALIGN(buffer->user_size, 8);
-
- OUT(buffer, VIV_FE_END_HEADER_OP_END);
-}
-
-static inline void CMD_WAIT(struct etnaviv_cmdbuf *buffer,
- unsigned int waitcycles)
-{
- buffer->user_size = ALIGN(buffer->user_size, 8);
-
- OUT(buffer, VIV_FE_WAIT_HEADER_OP_WAIT | waitcycles);
-}
-
-static inline void CMD_LINK(struct etnaviv_cmdbuf *buffer,
- u16 prefetch, u32 address)
-{
- buffer->user_size = ALIGN(buffer->user_size, 8);
-
- OUT(buffer, VIV_FE_LINK_HEADER_OP_LINK |
- VIV_FE_LINK_HEADER_PREFETCH(prefetch));
- OUT(buffer, address);
-}
-
-static inline void CMD_STALL(struct etnaviv_cmdbuf *buffer,
- u32 from, u32 to)
-{
- buffer->user_size = ALIGN(buffer->user_size, 8);
-
- OUT(buffer, VIV_FE_STALL_HEADER_OP_STALL);
- OUT(buffer, VIV_FE_STALL_TOKEN_FROM(from) | VIV_FE_STALL_TOKEN_TO(to));
-}
-
-static inline void CMD_SEM(struct etnaviv_cmdbuf *buffer, u32 from, u32 to)
-{
- CMD_LOAD_STATE(buffer, VIVS_GL_SEMAPHORE_TOKEN,
- VIVS_GL_SEMAPHORE_TOKEN_FROM(from) |
- VIVS_GL_SEMAPHORE_TOKEN_TO(to));
-}
+#include "etnaviv_flop_reset.h"
static void etnaviv_cmd_select_pipe(struct etnaviv_gpu *gpu,
struct etnaviv_cmdbuf *buffer, u8 pipe)
@@ -170,6 +103,10 @@ u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu)
/* initialize buffer */
buffer->user_size = 0;
+ /* Queue in PPU flop reset */
+ if (etnaviv_flop_reset_ppu_require(&gpu->identity))
+ etnaviv_flop_reset_ppu_run(gpu);
+
CMD_WAIT(buffer, gpu->fe_waitcycles);
CMD_LINK(buffer, 2,
etnaviv_cmdbuf_get_va(buffer, &gpu->mmu_context->cmdbuf_mapping)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.h b/drivers/gpu/drm/etnaviv/etnaviv_buffer.h
new file mode 100644
index 000000000000..4331ca8aac47
--- /dev/null
+++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.h
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2014-2025 Etnaviv Project
+ */
+
+#ifndef __ETNAVIV_BUFFER_H__
+#define __ETNAVIV_BUFFER_H__
+
+#include "etnaviv_cmdbuf.h"
+#include "etnaviv_gpu.h"
+#include "etnaviv_gem.h"
+#include "etnaviv_mmu.h"
+
+#include "common.xml.h"
+#include "linux/printk.h"
+#include "state.xml.h"
+#include "state_blt.xml.h"
+#include "state_hi.xml.h"
+#include "state_3d.xml.h"
+#include "cmdstream.xml.h"
+
+static inline void OUT(struct etnaviv_cmdbuf *buffer, u32 data)
+{
+ u32 *vaddr = (u32 *)buffer->vaddr;
+
+ BUG_ON(buffer->user_size >= buffer->size);
+
+ vaddr[buffer->user_size / 4] = data;
+ buffer->user_size += 4;
+}
+
+static inline void CMD_LOAD_STATE(struct etnaviv_cmdbuf *buffer, u32 reg,
+ u32 value)
+{
+ u32 index = reg >> VIV_FE_LOAD_STATE_HEADER_OFFSET__SHR;
+
+ buffer->user_size = ALIGN(buffer->user_size, 8);
+
+ /* write a register via cmd stream */
+ OUT(buffer, VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE |
+ VIV_FE_LOAD_STATE_HEADER_COUNT(1) |
+ VIV_FE_LOAD_STATE_HEADER_OFFSET(index));
+ OUT(buffer, value);
+}
+
+static inline void CMD_LOAD_STATES_START(struct etnaviv_cmdbuf *buffer, u32 reg,
+ u32 nvalues)
+{
+ u32 index = reg >> VIV_FE_LOAD_STATE_HEADER_OFFSET__SHR;
+
+ buffer->user_size = ALIGN(buffer->user_size, 8);
+
+ /* write a register via cmd stream */
+ OUT(buffer, VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE |
+ VIV_FE_LOAD_STATE_HEADER_OFFSET(index) |
+ VIV_FE_LOAD_STATE_HEADER_COUNT(nvalues));
+}
+
+static inline void CMD_END(struct etnaviv_cmdbuf *buffer)
+{
+ buffer->user_size = ALIGN(buffer->user_size, 8);
+
+ OUT(buffer, VIV_FE_END_HEADER_OP_END);
+}
+
+static inline void CMD_WAIT(struct etnaviv_cmdbuf *buffer,
+ unsigned int waitcycles)
+{
+ buffer->user_size = ALIGN(buffer->user_size, 8);
+
+ OUT(buffer, VIV_FE_WAIT_HEADER_OP_WAIT | waitcycles);
+}
+
+static inline void CMD_LINK(struct etnaviv_cmdbuf *buffer, u16 prefetch,
+ u32 address)
+{
+ buffer->user_size = ALIGN(buffer->user_size, 8);
+
+ OUT(buffer,
+ VIV_FE_LINK_HEADER_OP_LINK | VIV_FE_LINK_HEADER_PREFETCH(prefetch));
+ OUT(buffer, address);
+}
+
+static inline void CMD_STALL(struct etnaviv_cmdbuf *buffer, u32 from, u32 to)
+{
+ buffer->user_size = ALIGN(buffer->user_size, 8);
+
+ OUT(buffer, VIV_FE_STALL_HEADER_OP_STALL);
+ OUT(buffer, VIV_FE_STALL_TOKEN_FROM(from) | VIV_FE_STALL_TOKEN_TO(to));
+}
+
+static inline void CMD_SEM(struct etnaviv_cmdbuf *buffer, u32 from, u32 to)
+{
+ CMD_LOAD_STATE(buffer, VIVS_GL_SEMAPHORE_TOKEN,
+ VIVS_GL_SEMAPHORE_TOKEN_FROM(from) |
+ VIVS_GL_SEMAPHORE_TOKEN_TO(to));
+}
+
+#endif /* __ETNAVIV_BUFFER_H__ */
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 54ceae87b401..bb1b84eecec8 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -601,6 +601,9 @@ static void etnaviv_unbind(struct device *dev)
component_unbind_all(dev, drm);
+ etnaviv_cmdbuf_free(priv->flop_reset_data_ppu);
+ kfree(priv->flop_reset_data_ppu);
+
etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
xa_destroy(&priv->active_contexts);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index b3eb1662e90c..20dad16fd554 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -48,6 +48,9 @@ struct etnaviv_drm_private {
/* list of GEM objects: */
struct mutex gem_lock;
struct list_head gem_list;
+
+ /* ppu flop reset data */
+ struct etnaviv_cmdbuf *flop_reset_data_ppu;
};
int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c b/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c
new file mode 100644
index 000000000000..58d957ee861d
--- /dev/null
+++ b/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Etnaviv Project
+ */
+
+#include <linux/errno.h>
+#include <linux/dev_printk.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "etnaviv_buffer.h"
+#include "etnaviv_cmdbuf.h"
+#include "etnaviv_gpu.h"
+#include "state_3d.xml.h"
+
+#include "etnaviv_flop_reset.h"
+
+static int etnaviv_force_flop_reset;
+module_param_named(force_flop_reset, etnaviv_force_flop_reset, int, 0);
+
+#define PPU_IMAGE_STRIDE 64
+#define PPU_IMAGE_XSIZE 64
+#define PPU_IMAGE_YSIZE 6
+
+#define PPU_FLOP_RESET_INSTR_DWORD_COUNT 16
+
+static void etnaviv_emit_flop_reset_state_ppu(struct etnaviv_cmdbuf *cmdbuf,
+ u32 buffer_base, u32 input_offset,
+ u32 output_offset,
+ u32 shader_offset,
+ u32 shader_size,
+ u32 shader_register_count)
+{
+ CMD_LOAD_STATE(cmdbuf, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENCL);
+ CMD_SEM(cmdbuf, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
+ CMD_STALL(cmdbuf, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
+
+ CMD_LOAD_STATES_START(cmdbuf, VIVS_SH_HALTI5_UNIFORMS(0), 4);
+
+ OUT(cmdbuf, buffer_base + input_offset);
+ OUT(cmdbuf, PPU_IMAGE_STRIDE);
+ OUT(cmdbuf, PPU_IMAGE_XSIZE | (PPU_IMAGE_YSIZE << 16));
+ OUT(cmdbuf, 0x444051f0);
+ OUT(cmdbuf, 0xffffffff);
+
+ CMD_LOAD_STATES_START(cmdbuf, VIVS_SH_HALTI5_UNIFORMS(4), 4);
+ OUT(cmdbuf, buffer_base + output_offset);
+ OUT(cmdbuf, PPU_IMAGE_STRIDE);
+ OUT(cmdbuf, PPU_IMAGE_XSIZE | (PPU_IMAGE_YSIZE << 16));
+ OUT(cmdbuf, 0x444051f0);
+ OUT(cmdbuf, 0xffffffff);
+
+ CMD_LOAD_STATE(cmdbuf, VIVS_CL_CONFIG,
+ VIVS_CL_CONFIG_DIMENSIONS(2) |
+ VIVS_CL_CONFIG_VALUE_ORDER(3));
+ CMD_LOAD_STATE(cmdbuf, VIVS_VS_ICACHE_INVALIDATE, 0x1f);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_VARYING_NUM_COMPONENTS(0), 0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_TEMP_REGISTER_CONTROL,
+ shader_register_count);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_SAMPLER_BASE, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_UNIFORM_BASE, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_NEWRANGE_LOW, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_NEWRANGE_HIGH, shader_size / 16);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_INST_ADDR, buffer_base + shader_offset);
+ CMD_LOAD_STATE(cmdbuf, VIVS_SH_CONFIG, VIVS_SH_CONFIG_RTNE_ROUNDING);
+ CMD_LOAD_STATE(cmdbuf, VIVS_VS_ICACHE_CONTROL,
+ VIVS_VS_ICACHE_CONTROL_ENABLE);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_ICACHE_COUNT, shader_size / 16 - 1);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_INPUT_COUNT, 0x1f01);
+ CMD_LOAD_STATE(cmdbuf, VIVS_VS_HALTI5_UNK008A0, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PA_VS_OUTPUT_COUNT, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_GL_VARYING_TOTAL_COMPONENTS, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_CONTROL_EXT, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_VS_OUTPUT_COUNT, 0x1);
+ CMD_LOAD_STATE(cmdbuf, VIVS_GL_HALTI5_SH_SPECIALS, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_PS_ICACHE_PREFETCH, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_CL_UNK00924, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_CL_THREAD_ALLOCATION, 0x1);
+
+ CMD_LOAD_STATE(cmdbuf, VIVS_CL_GLOBAL_WORK_OFFSET_X, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_CL_GLOBAL_WORK_OFFSET_Y, 0x0);
+ CMD_LOAD_STATE(cmdbuf, VIVS_CL_GLOBAL_WORK_OFFSET_Z, 0x0);
+
+ CMD_LOAD_STATES_START(cmdbuf, VIVS_CL_WORKGROUP_COUNT_X, 9);
+ OUT(cmdbuf, 0xf);
+ OUT(cmdbuf, 0x5);
+ OUT(cmdbuf, 0xffffffff);
+ OUT(cmdbuf, 0x0);
+ OUT(cmdbuf, 0x0);
+ OUT(cmdbuf, 0x3ff);
+ OUT(cmdbuf, 0x0);
+ OUT(cmdbuf, 0x4);
+ OUT(cmdbuf, 0x1);
+ OUT(cmdbuf, 0x0);
+
+ CMD_LOAD_STATE(cmdbuf, VIVS_CL_KICKER, 0xbadabeeb);
+ CMD_LOAD_STATE(cmdbuf, VIVS_GL_FLUSH_CACHE,
+ VIVS_GL_FLUSH_CACHE_SHADER_L1 |
+ VIVS_GL_FLUSH_CACHE_UNK10 |
+ VIVS_GL_FLUSH_CACHE_UNK11);
+}
+
+static void etnaviv_flop_reset_ppu_fill_input(u32 *buffer, u32 size)
+{
+ memset32(buffer, 0x01010101, size / 4);
+}
+
+static void etnaviv_flop_reset_ppu_set_shader(u8 *dest)
+{
+ static const u32 inst[PPU_FLOP_RESET_INSTR_DWORD_COUNT] = {
+ /* img_load.u8 r1, c0, r0.xy */
+ 0x78011779,
+ 0x39000804,
+ 0x00A90050,
+ 0x00000000,
+ /* img_load.u8 r2, c0, r0.xy */
+ 0x78021779,
+ 0x39000804,
+ 0x00A90050,
+ 0x00000000,
+ /* dp2x8 r1, r1, r2, c3_512 */
+ 0xB8017145,
+ 0x390018FC,
+ 0x01C90140,
+ 0x40390028,
+ /* img_store.u8 r1, c2, r0.xy, r1 */
+ 0x380007BA,
+ 0x39001804,
+ 0x00A90050,
+ 0x00390018,
+ };
+ memcpy(dest, inst, sizeof(inst));
+}
+
+static const struct etnaviv_flop_reset_entry {
+ u16 chip_model;
+ u16 revision;
+ u32 flags;
+} etnaviv_flop_reset_db[] = {
+ {
+ .chip_model = 0x8000,
+ .revision = 0x6205,
+ },
+};
+
+bool etnaviv_flop_reset_ppu_require(const struct etnaviv_chip_identity *chip_id)
+{
+ const struct etnaviv_flop_reset_entry *e = etnaviv_flop_reset_db;
+
+ for (int i = 0; i < ARRAY_SIZE(etnaviv_flop_reset_db); ++i, ++e) {
+ if (chip_id->model == e->chip_model &&
+ chip_id->revision == e->revision)
+ return true;
+ }
+
+ if (etnaviv_force_flop_reset) {
+ if (!(chip_id->features & chipFeatures_PIPE_3D)) {
+ pr_warn("Etnaviv: model: 0x%04x, revision: 0x%04x does not support PIPE_3D\n",
+ chip_id->model, chip_id->revision);
+ pr_warn("Request to force PPU flop reset ignored.\n");
+ return false;
+ }
+
+ pr_info("Force PPU flop reset for model: 0x%04x, revision: 0x%04x\n",
+ chip_id->model, chip_id->revision);
+ return true;
+ }
+
+ return false;
+}
+
+static const u32 image_data_size = PPU_IMAGE_STRIDE * PPU_IMAGE_YSIZE;
+static const u32 output_offset = ALIGN(image_data_size, 64);
+static const u32 shader_offset = ALIGN(output_offset + image_data_size, 64);
+static const u32 shader_size = PPU_FLOP_RESET_INSTR_DWORD_COUNT * sizeof(u32);
+static const u32 shader_register_count = 3;
+static const u32 buffer_size = shader_offset + shader_size;
+
+int etnaviv_flop_reset_ppu_init(struct etnaviv_drm_private *priv)
+{
+ /* Get some space from the ring buffer to put the payload
+ * (input and output image, and shader), we keep this buffer
+ * for the whole life time the driver is bound
+ */
+ priv->flop_reset_data_ppu =
+ kzalloc(sizeof(*priv->flop_reset_data_ppu), GFP_KERNEL);
+
+ if (!priv->flop_reset_data_ppu)
+ return -ENOMEM;
+
+ int ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc,
+ priv->flop_reset_data_ppu, buffer_size);
+ if (ret) {
+ kfree(priv->flop_reset_data_ppu);
+ return ret;
+ }
+
+ void *buffer_base = priv->flop_reset_data_ppu->vaddr;
+ u32 *input_data = (u32 *)buffer_base;
+ u8 *shader_data = (u8 *)buffer_base + shader_offset;
+
+ etnaviv_flop_reset_ppu_fill_input(input_data, image_data_size);
+ etnaviv_flop_reset_ppu_set_shader(shader_data);
+
+ return 0;
+}
+
+void etnaviv_flop_reset_ppu_run(struct etnaviv_gpu *gpu)
+{
+ struct etnaviv_drm_private *priv = gpu->drm->dev_private;
+
+ if (!priv->flop_reset_data_ppu) {
+ dev_err(gpu->dev,
+ "Oops: Flop reset data was not initialized, skipping\n");
+ return;
+ }
+
+ u32 buffer_base = etnaviv_cmdbuf_get_va(priv->flop_reset_data_ppu,
+ &gpu->mmu_context->cmdbuf_mapping);
+
+ etnaviv_emit_flop_reset_state_ppu(&gpu->buffer, buffer_base, 0,
+ output_offset, shader_offset,
+ shader_size, shader_register_count);
+}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.h b/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.h
new file mode 100644
index 000000000000..e6dee1db788f
--- /dev/null
+++ b/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2025 Etnaviv Project
+ */
+
+#ifndef _ETNAVIV_FLOP_RESET_H_
+#define _ETNAVIV_FLOP_RESET_H_
+
+#include <linux/types.h>
+
+struct etnaviv_chip_identity;
+struct etnaviv_drm_private;
+struct etnaviv_gpu;
+
+bool etnaviv_flop_reset_ppu_require(const struct etnaviv_chip_identity *chip_id);
+
+int etnaviv_flop_reset_ppu_init(struct etnaviv_drm_private *priv);
+
+void etnaviv_flop_reset_ppu_run(struct etnaviv_gpu *gpu);
+
+#endif
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index ca0be293f5fe..94326dddaf6f 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -20,6 +20,7 @@
#include "etnaviv_cmdbuf.h"
#include "etnaviv_dump.h"
+#include "etnaviv_flop_reset.h"
#include "etnaviv_gpu.h"
#include "etnaviv_gem.h"
#include "etnaviv_mmu.h"
@@ -839,6 +840,16 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
goto fail;
}
+ if (etnaviv_flop_reset_ppu_require(&gpu->identity) &&
+ !priv->flop_reset_data_ppu) {
+ ret = etnaviv_flop_reset_ppu_init(priv);
+ if (ret) {
+ dev_err(gpu->dev,
+ "Unable to initialize PPU flop reset data\n");
+ goto fail;
+ }
+ }
+
if (gpu->identity.nn_core_count > 0)
dev_warn(gpu->dev, "etnaviv has been instantiated on a NPU, "
"for which the UAPI is still experimental\n");
diff --git a/drivers/gpu/drm/etnaviv/state_3d.xml.h b/drivers/gpu/drm/etnaviv/state_3d.xml.h
index ebbd4fcf3096..a654c05414ec 100644
--- a/drivers/gpu/drm/etnaviv/state_3d.xml.h
+++ b/drivers/gpu/drm/etnaviv/state_3d.xml.h
@@ -4,6 +4,101 @@
/* This is a cut-down version of the state_3d.xml.h file */
+#define VIVS_CL_CONFIG 0x00000900
+#define VIVS_CL_CONFIG_DIMENSIONS__MASK 0x00000003
+#define VIVS_CL_CONFIG_DIMENSIONS__SHIFT 0
+#define VIVS_CL_CONFIG_DIMENSIONS(x) (((x) << VIVS_CL_CONFIG_DIMENSIONS__SHIFT) & VIVS_CL_CONFIG_DIMENSIONS__MASK)
+#define VIVS_CL_CONFIG_TRAVERSE_ORDER__MASK 0x00000070
+#define VIVS_CL_CONFIG_TRAVERSE_ORDER__SHIFT 4
+#define VIVS_CL_CONFIG_TRAVERSE_ORDER(x) (((x) << VIVS_CL_CONFIG_TRAVERSE_ORDER__SHIFT) & VIVS_CL_CONFIG_TRAVERSE_ORDER__MASK)
+#define VIVS_CL_CONFIG_ENABLE_SWATH_X 0x00000100
+#define VIVS_CL_CONFIG_ENABLE_SWATH_Y 0x00000200
+#define VIVS_CL_CONFIG_ENABLE_SWATH_Z 0x00000400
+#define VIVS_CL_CONFIG_SWATH_SIZE_X__MASK 0x0000f000
+#define VIVS_CL_CONFIG_SWATH_SIZE_X__SHIFT 12
+#define VIVS_CL_CONFIG_SWATH_SIZE_X(x) (((x) << VIVS_CL_CONFIG_SWATH_SIZE_X__SHIFT) & VIVS_CL_CONFIG_SWATH_SIZE_X__MASK)
+#define VIVS_CL_CONFIG_SWATH_SIZE_Y__MASK 0x000f0000
+#define VIVS_CL_CONFIG_SWATH_SIZE_Y__SHIFT 16
+#define VIVS_CL_CONFIG_SWATH_SIZE_Y(x) (((x) << VIVS_CL_CONFIG_SWATH_SIZE_Y__SHIFT) & VIVS_CL_CONFIG_SWATH_SIZE_Y__MASK)
+#define VIVS_CL_CONFIG_SWATH_SIZE_Z__MASK 0x00f00000
+#define VIVS_CL_CONFIG_SWATH_SIZE_Z__SHIFT 20
+#define VIVS_CL_CONFIG_SWATH_SIZE_Z(x) (((x) << VIVS_CL_CONFIG_SWATH_SIZE_Z__SHIFT) & VIVS_CL_CONFIG_SWATH_SIZE_Z__MASK)
+
+#define VIVS_CL_CONFIG_DIMENSIONS__MASK 0x00000003
+#define VIVS_CL_CONFIG_DIMENSIONS__SHIFT 0
+#define VIVS_CL_CONFIG_DIMENSIONS(x) (((x) << VIVS_CL_CONFIG_DIMENSIONS__SHIFT) & VIVS_CL_CONFIG_DIMENSIONS__MASK)
+
+#define VIVS_CL_CONFIG_VALUE_ORDER__MASK 0x07000000
+#define VIVS_CL_CONFIG_VALUE_ORDER__SHIFT 24
+#define VIVS_CL_CONFIG_VALUE_ORDER(x) (((x) << VIVS_CL_CONFIG_VALUE_ORDER__SHIFT) & VIVS_CL_CONFIG_VALUE_ORDER__MASK)
+
+#define VIVS_CL_GLOBAL_WORK_OFFSET_X 0x0000092c
+#define VIVS_CL_GLOBAL_WORK_OFFSET_Y 0x00000934
+#define VIVS_CL_GLOBAL_WORK_OFFSET_Z 0x0000093c
+
+#define VIVS_CL_KICKER 0x00000920
+#define VIVS_CL_THREAD_ALLOCATION 0x0000091c
+#define VIVS_CL_UNK00924 0x00000924
+
+#define VIVS_CL_WORKGROUP_COUNT_X 0x00000940
+#define VIVS_CL_WORKGROUP_COUNT_Y 0x00000944
+#define VIVS_CL_WORKGROUP_COUNT_Z 0x00000948
+#define VIVS_CL_WORKGROUP_SIZE_X 0x0000094c
+#define VIVS_CL_WORKGROUP_SIZE_Y 0x00000950
+#define VIVS_CL_WORKGROUP_SIZE_Z 0x00000954
+
+#define VIVS_CL_GLOBAL_SCALE_X 0x00000958
+#define VIVS_CL_GLOBAL_SCALE_Y 0x0000095c
+#define VIVS_CL_GLOBAL_SCALE_Z 0x00000960
+
+#define VIVS_PA_VS_OUTPUT_COUNT 0x00000aa8
+#define VIVS_PS_CONTROL_EXT 0x00001030
+#define VIVS_PS_ICACHE_COUNT 0x00001094
+#define VIVS_PS_ICACHE_PREFETCH 0x00001048
+
+#define VIVS_PS_INPUT_COUNT 0x00001008
+#define VIVS_PS_INPUT_COUNT_COUNT__MASK 0x0000001f
+#define VIVS_PS_INPUT_COUNT_COUNT__SHIFT 0
+#define VIVS_PS_INPUT_COUNT_COUNT(x) (((x) << VIVS_PS_INPUT_COUNT_COUNT__SHIFT) & VIVS_PS_INPUT_COUNT_COUNT__MASK)
+
+#define VIVS_PS_NEWRANGE_LOW 0x0000087c
+#define VIVS_PS_NEWRANGE_HIGH 0x00001090
+#define VIVS_PS_SAMPLER_BASE 0x00001058
+
+#define VIVS_PS_UNIFORM_BASE 0x00001024
+#define VIVS_PS_INST_ADDR 0x00001028
+
+#define VIVS_PS_TEMP_REGISTER_CONTROL 0x0000100c
+#define VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS__MASK 0x0000003f
+#define VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS__SHIFT 0
+#define VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(x) (((x) << VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS__SHIFT) & VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS__MASK)
+
+#define VIVS_PS_VARYING_NUM_COMPONENTS(i0) (0x00001080 + 0x4*(i0))
+#define VIVS_PS_VARYING_NUM_COMPONENTS__ESIZE 0x00000004
+#define VIVS_PS_VARYING_NUM_COMPONENTS__LEN 0x00000004
+
+#define VIVS_SH_CONFIG 0x00015600
+#define VIVS_SH_CONFIG_RTNE_ROUNDING 0x00000002
+
+#define VIVS_SH_HALTI5_UNIFORMS(i0) (0x00036000 + 0x4*(i0))
+#define VIVS_SH_HALTI5_UNIFORMS__ESIZE 0x00000004
+#define VIVS_SH_HALTI5_UNIFORMS__LEN 0x00000800
+
+#define VIVS_VS_HALTI5_UNK008A0 0x000008a0
+#define VIVS_VS_HALTI5_UNK008A0_A__MASK 0x0000003f
+#define VIVS_VS_HALTI5_UNK008A0_A__SHIFT 0
+#define VIVS_VS_HALTI5_UNK008A0_A(x) (((x) << VIVS_VS_HALTI5_UNK008A0_A__SHIFT) & VIVS_VS_HALTI5_UNK008A0_A__MASK)
+
+#define VIVS_VS_ICACHE_CONTROL 0x00000868
+#define VIVS_VS_ICACHE_CONTROL_ENABLE 0x00000001
+
+#define VIVS_VS_ICACHE_INVALIDATE 0x000008b0
+
+#define VIVS_VS_OUTPUT_COUNT 0x00000804
+#define VIVS_VS_OUTPUT_COUNT_COUNT__MASK 0x000000ff
+#define VIVS_VS_OUTPUT_COUNT_COUNT__SHIFT 0
+#define VIVS_VS_OUTPUT_COUNT_COUNT(x) (((x) << VIVS_VS_OUTPUT_COUNT_COUNT__SHIFT) & VIVS_VS_OUTPUT_COUNT_COUNT__MASK)
+
#define VIVS_TS_FLUSH_CACHE 0x00001650
#define VIVS_TS_FLUSH_CACHE_FLUSH 0x00000001