summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiu Ying <victor.liu@nxp.com>2018-11-27 15:23:26 +0800
committerBryan O'Donoghue <bryan.odonoghue@linaro.org>2019-01-25 16:14:18 +0000
commit0d13b8c25adfbef8b41dd344801e645bb8508424 (patch)
tree26bd0cb5e1b38b644e8beb1a7ca36f184f112d93
parent40198df9966e8434c7fec872d44f665a3536d164 (diff)
MLK-20470 drm/imx: dpu: plane: Do full modeset for tile to linear fb switch
When pixel combiner is used, it turns out that on-the-fly switch from tile framebuffer to linear framebuffer would cause hardware malfunction - right half display would be missing and master&slave content shadow load done event won't come. Thus, go for a full modeset as a workaround. Note that we check if the original framebuffer is tile or not for both primary and overlay planes. So, this could be over-kill. The issue was found when we use 32bit GPU super tile as the original framebuffer on the primary plane(restart Weston frequently). However, since we usually don't do this kind of switch in real graphics, it should be fine. Signed-off-by: Liu Ying <victor.liu@nxp.com> (cherry picked from commit 9245bbf650fdeb79ebf869d48b6bd1b43c2bcf3b)
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-plane.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/gpu/drm/imx/dpu/dpu-plane.c b/drivers/gpu/drm/imx/dpu/dpu-plane.c
index 63309552857e..0a62b003d473 100644
--- a/drivers/gpu/drm/imx/dpu/dpu-plane.c
+++ b/drivers/gpu/drm/imx/dpu/dpu-plane.c
@@ -20,6 +20,7 @@
#include <drm/drm_plane_helper.h>
#include <video/dpu.h>
#include <video/imx8-prefetch.h>
+#include "dpu-crtc.h"
#include "dpu-plane.h"
#include "imx-drm.h"
@@ -245,7 +246,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
struct dpu_plane_state *old_dpstate = to_dpu_plane_state(plane->state);
struct dpu_plane_res *res = &dplane->grp->res;
struct drm_crtc_state *crtc_state;
+ struct imx_crtc_state *imx_crtc_state;
+ struct dpu_crtc_state *dcstate;
struct drm_framebuffer *fb = state->fb;
+ struct drm_framebuffer *old_fb = plane->state->fb;
struct dpu_fetchunit *fu;
struct dprc *dprc;
dma_addr_t baseaddr, uv_baseaddr = 0;
@@ -331,6 +335,22 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
(dpstate->base_y != old_dpstate->base_y))
crtc_state->mode_changed = true;
+ /*
+ * FIXME:
+ * When pixel combiner is used, it turns out that on-the-fly
+ * switch from tile fb to linear fb would cause hardware
+ * malfunction - right half display would be missing and
+ * master&slave content shadow load done event won't come.
+ * Thus, go for a full modeset as a workaround. This could
+ * be over-kill for some cases, however, since we usually
+ * don't do this kind of switch in real graphics, it should
+ * be fine.
+ */
+ imx_crtc_state = to_imx_crtc_state(crtc_state);
+ dcstate = to_dpu_crtc_state(imx_crtc_state);
+ if (dcstate->use_pc && old_fb && old_fb->modifier && !fb->modifier)
+ crtc_state->mode_changed = true;
+
if (state->crtc_x + state->crtc_w >
crtc_state->adjusted_mode.hdisplay)
return -EINVAL;