From fd5426ccf0877411c160349610fe2d939e9638ea Mon Sep 17 00:00:00 2001 From: Walter Lozano Date: Fri, 28 Aug 2020 06:03:31 -0300 Subject: linux-fslc-imx: Backport mainline patches to fix GPU hangs Initial tests of AGL with etnaviv showed random GPU hangs. After discussion add some mainline patches not yet present in linux-fslc-imx in order to fix them. BUG-AGL: SPEC-3520 Signed-off-by: Walter Lozano Change-Id: I8ac51e7ec91fa033554270cd79ca1b55c5862103 Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl/+/25163 Reviewed-by: Daniel Stone Reviewed-by: Jan-Simon Moeller Tested-by: Jenkins Job builder account ci-image-build: Jenkins Job builder account ci-image-boot-test: Jenkins Job builder account --- ...-fix-TS-cache-flushing-on-GPUs-with-BLT-e.patch | 151 +++++++++++++++++++++ ...ed-Fix-passing-zero-to-PTR_ERR-warning-v2.patch | 50 +++++++ .../recipes-kernel/linux/linux-fslc-imx_%.bbappend | 2 + 3 files changed, 203 insertions(+) create mode 100644 meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx/0003-drm-etnaviv-fix-TS-cache-flushing-on-GPUs-with-BLT-e.patch create mode 100644 meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx/0004-drm-sched-Fix-passing-zero-to-PTR_ERR-warning-v2.patch diff --git a/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx/0003-drm-etnaviv-fix-TS-cache-flushing-on-GPUs-with-BLT-e.patch b/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx/0003-drm-etnaviv-fix-TS-cache-flushing-on-GPUs-with-BLT-e.patch new file mode 100644 index 000000000..d7a1f85b8 --- /dev/null +++ b/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx/0003-drm-etnaviv-fix-TS-cache-flushing-on-GPUs-with-BLT-e.patch @@ -0,0 +1,151 @@ +From f232d9ec029ce3e2543b05213e2979e01e503408 Mon Sep 17 00:00:00 2001 +From: Lucas Stach +Date: Wed, 26 Feb 2020 16:27:08 +0100 +Subject: [PATCH] drm/etnaviv: fix TS cache flushing on GPUs with BLT engine + +As seen in the Vivante kernel driver, most GPUs with the BLT engine have +a broken TS cache flush. The workaround is to temporarily set the BLT +command to CLEAR_IMAGE, without actually executing the clear. Apparently +this state change is enough to trigger the required TS cache flush. As +the BLT engine is completely asychronous, we also need a few more stall +states to synchronize the flush with the frontend. + +Root-caused-by: Jonathan Marek +Signed-off-by: Lucas Stach +--- + drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 60 ++++++++++++++++++++++-- + drivers/gpu/drm/etnaviv/state_blt.xml.h | 2 + + 2 files changed, 57 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c +index 32d9fac587f9..76d38561c910 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c +@@ -12,6 +12,7 @@ + + #include "common.xml.h" + #include "state.xml.h" ++#include "state_blt.xml.h" + #include "state_hi.xml.h" + #include "state_3d.xml.h" + #include "cmdstream.xml.h" +@@ -233,6 +234,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu) + struct etnaviv_cmdbuf *buffer = &gpu->buffer; + unsigned int waitlink_offset = buffer->user_size - 16; + u32 link_target, flush = 0; ++ bool has_blt = !!(gpu->identity.minor_features5 & ++ chipMinorFeatures5_BLT_ENGINE); + + lockdep_assert_held(&gpu->lock); + +@@ -248,16 +251,38 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu) + if (flush) { + unsigned int dwords = 7; + ++ if (has_blt) ++ dwords += 10; ++ + link_target = etnaviv_buffer_reserve(gpu, buffer, dwords); + + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } + CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush); +- if (gpu->exec_state == ETNA_PIPE_3D) +- CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, +- VIVS_TS_FLUSH_CACHE_FLUSH); ++ if (gpu->exec_state == ETNA_PIPE_3D) { ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } else { ++ CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, ++ VIVS_TS_FLUSH_CACHE_FLUSH); ++ } ++ } + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } + CMD_END(buffer); + + etnaviv_buffer_replace_wait(buffer, waitlink_offset, +@@ -323,6 +348,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, + bool switch_mmu_context = gpu->mmu_context != mmu_context; + unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq); + bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq; ++ bool has_blt = !!(gpu->identity.minor_features5 & ++ chipMinorFeatures5_BLT_ENGINE); + + lockdep_assert_held(&gpu->lock); + +@@ -433,6 +460,15 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, + * 2 semaphore stall + 1 event + 1 wait + 1 link. + */ + return_dwords = 7; ++ ++ /* ++ * When the BLT engine is present we need 6 more dwords in the return ++ * target: 3 enable/flush/disable + 4 enable/semaphore stall/disable, ++ * but we don't need the normal TS flush state. ++ */ ++ if (has_blt) ++ return_dwords += 6; ++ + return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords); + CMD_LINK(cmdbuf, return_dwords, return_target); + +@@ -447,11 +483,25 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, + CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, + VIVS_GL_FLUSH_CACHE_DEPTH | + VIVS_GL_FLUSH_CACHE_COLOR); +- CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, +- VIVS_TS_FLUSH_CACHE_FLUSH); ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } else { ++ CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, ++ VIVS_TS_FLUSH_CACHE_FLUSH); ++ } + } + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); ++ ++ if (has_blt) { ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); ++ CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); ++ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); ++ } ++ + CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) | + VIVS_GL_EVENT_FROM_PE); + CMD_WAIT(buffer); +diff --git a/drivers/gpu/drm/etnaviv/state_blt.xml.h b/drivers/gpu/drm/etnaviv/state_blt.xml.h +index daae55995def..0e8bcf9dcc93 100644 +--- a/drivers/gpu/drm/etnaviv/state_blt.xml.h ++++ b/drivers/gpu/drm/etnaviv/state_blt.xml.h +@@ -46,6 +46,8 @@ DEALINGS IN THE SOFTWARE. + + /* This is a cut-down version of the state_blt.xml.h file */ + ++#define VIVS_BLT_SET_COMMAND 0x000140ac ++ + #define VIVS_BLT_ENABLE 0x000140b8 + #define VIVS_BLT_ENABLE_ENABLE 0x00000001 + +-- +2.20.1 + diff --git a/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx/0004-drm-sched-Fix-passing-zero-to-PTR_ERR-warning-v2.patch b/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx/0004-drm-sched-Fix-passing-zero-to-PTR_ERR-warning-v2.patch new file mode 100644 index 000000000..8c141a0f5 --- /dev/null +++ b/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx/0004-drm-sched-Fix-passing-zero-to-PTR_ERR-warning-v2.patch @@ -0,0 +1,50 @@ +From d7c5782acd354bdb5ed0fa10e1e397eaed558390 Mon Sep 17 00:00:00 2001 +From: Andrey Grodzovsky +Date: Tue, 29 Oct 2019 11:03:05 -0400 +Subject: [PATCH] drm/sched: Fix passing zero to 'PTR_ERR' warning v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix a static code checker warning. + +v2: Drop PTR_ERR_OR_ZERO. + +Signed-off-by: Andrey Grodzovsky +Reviewed-by: Emily Deng +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +--- + drivers/gpu/drm/scheduler/sched_main.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c +index 2af64459b3d7..fbb6446c4f69 100644 +--- a/drivers/gpu/drm/scheduler/sched_main.c ++++ b/drivers/gpu/drm/scheduler/sched_main.c +@@ -496,8 +496,10 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched) + fence = sched->ops->run_job(s_job); + + if (IS_ERR_OR_NULL(fence)) { ++ if (IS_ERR(fence)) ++ dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); ++ + s_job->s_fence->parent = NULL; +- dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); + } else { + s_job->s_fence->parent = fence; + } +@@ -746,8 +748,9 @@ static int drm_sched_main(void *param) + r); + dma_fence_put(fence); + } else { ++ if (IS_ERR(fence)) ++ dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); + +- dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); + drm_sched_process_job(NULL, &sched_job->cb); + } + +-- +2.20.1 + diff --git a/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx_%.bbappend b/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx_%.bbappend index 549ba3994..4dc51369a 100644 --- a/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx_%.bbappend +++ b/meta-agl-bsp/meta-freescale-layer/recipes-kernel/linux/linux-fslc-imx_%.bbappend @@ -8,6 +8,8 @@ require recipes-kernel/linux/linux-agl.inc SRC_URI_append_etnaviv = " \ file://0001-enable-mhdp-with-etnaviv.patch \ file://0002-dts-enable-etnaviv.patch \ + file://0003-drm-etnaviv-fix-TS-cache-flushing-on-GPUs-with-BLT-e.patch \ + file://0004-drm-sched-Fix-passing-zero-to-PTR_ERR-warning-v2.patch \ " # Make sure these are enabled so that AGL configurations work -- cgit 1.2.3-korg