summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2016-08-19 23:53:59 +0200
committerLucas Stach <l.stach@pengutronix.de>2016-09-15 15:29:41 +0200
commitde08e8ef71cd7fbc4a89107b295571c4d50f0d66 (patch)
tree4d0184d93c7a9a949843ea4edafa8c54eff1ebf6
parente68f270f210776eed956884d1fc3ce1aab0912a3 (diff)
drm/etnaviv: add function to construct MMUv2 init buffer
Both the safe/scratch address and the master TLB address are per pipe with the CPU mapped registers not properly propagating to the different translation units. The only way to correctly configure all translation units is to have a command stream snipped executed by the FE, before any other execution can start. Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_buffer.c34
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.h1
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
index 46d13f49883e..47b93427fecb 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
@@ -21,6 +21,7 @@
#include "common.xml.h"
#include "state.xml.h"
+#include "state_hi.xml.h"
#include "state_3d.xml.h"
#include "cmdstream.xml.h"
@@ -174,6 +175,39 @@ u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu)
return buffer->user_size / 8;
}
+u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr)
+{
+ struct etnaviv_cmdbuf *buffer = gpu->buffer;
+
+ buffer->user_size = 0;
+
+ if (gpu->identity.features & chipFeatures_PIPE_3D) {
+ CMD_LOAD_STATE(buffer, VIVS_GL_PIPE_SELECT,
+ VIVS_GL_PIPE_SELECT_PIPE(ETNA_PIPE_3D));
+ CMD_LOAD_STATE(buffer, VIVS_MMUv2_CONFIGURATION,
+ mtlb_addr | VIVS_MMUv2_CONFIGURATION_MODE_MODE4_K);
+ CMD_LOAD_STATE(buffer, VIVS_MMUv2_SAFE_ADDRESS, safe_addr);
+ CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
+ CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
+ }
+
+ if (gpu->identity.features & chipFeatures_PIPE_2D) {
+ CMD_LOAD_STATE(buffer, VIVS_GL_PIPE_SELECT,
+ VIVS_GL_PIPE_SELECT_PIPE(ETNA_PIPE_2D));
+ CMD_LOAD_STATE(buffer, VIVS_MMUv2_CONFIGURATION,
+ mtlb_addr | VIVS_MMUv2_CONFIGURATION_MODE_MODE4_K);
+ CMD_LOAD_STATE(buffer, VIVS_MMUv2_SAFE_ADDRESS, safe_addr);
+ CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
+ CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
+ }
+
+ CMD_END(buffer);
+
+ buffer->user_size = ALIGN(buffer->user_size, 8);
+
+ return buffer->user_size / 8;
+}
+
void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
{
struct etnaviv_cmdbuf *buffer = gpu->buffer;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index 115c5bc6d7c8..65e057639653 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -96,6 +96,7 @@ struct drm_gem_object *etnaviv_gem_new(struct drm_device *dev,
int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file,
uintptr_t ptr, u32 size, u32 flags, u32 *handle);
u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu);
+u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr);
void etnaviv_buffer_end(struct etnaviv_gpu *gpu);
void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
struct etnaviv_cmdbuf *cmdbuf);