drm/sde: fix smmu fault while running DRM test

DRM test failed in 4K display. It is caused by
wrong configuration of physical pipe and flush
mask for layer mixer.

Change-Id: I0d2d50cf24ba2265c9f5b874526c5e4013e47d9e
CRs-Fixed: 2065974
Signed-off-by: Yujun Zhang <yujunzhang@codeaurora.org>
This commit is contained in:
Yujun Zhang 2017-08-05 00:39:53 +08:00 committed by Gerrit - the friendly Code Review server
parent 6f777b2385
commit 4fda2bf83c
2 changed files with 20 additions and 14 deletions

View file

@ -204,10 +204,15 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
idx = left_crtc_zpos_cnt[pstate->stage]++;
}
/* stage plane on right LM if it crosses the boundary */
lm_right = (lm_idx == LEFT_MIXER) &&
(plane->state->crtc_x + plane->state->crtc_w >
crtc_split_width);
/*
* program each mixer with two hw pipes in dual mixer mode,
*/
if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS) {
if (sde_crtc->num_mixers == CRTC_DUAL_MIXERS && lm_right) {
stage_cfg->stage[LEFT_MIXER][pstate->stage][1] =
sde_plane_pipe(plane, 1);
@ -218,10 +223,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
flush_mask |= ctl->ops.get_bitmask_sspp(ctl,
sde_plane_pipe(plane, lm_idx ? 1 : 0));
/* stage plane on right LM if it crosses the boundary */
lm_right = (lm_idx == LEFT_MIXER) &&
(plane->state->crtc_x + plane->state->crtc_w >
crtc_split_width);
stage_cfg->stage[lm_idx][pstate->stage][idx] =
sde_plane_pipe(plane, lm_idx ? 1 : 0);

View file

@ -1237,8 +1237,10 @@ static int _sde_plane_mode_set(struct drm_plane *plane,
bool q16_data = true;
int idx;
struct sde_phy_plane *pp;
uint32_t num_of_phy_planes = 0, maxlinewidth = 0xFFFF;
uint32_t num_of_phy_planes = 0;
int mode = 0;
uint32_t crtc_split_width;
bool is_across_mixer_boundary = false;
if (!plane) {
SDE_ERROR("invalid plane\n");
@ -1252,6 +1254,7 @@ static int _sde_plane_mode_set(struct drm_plane *plane,
pstate = to_sde_plane_state(plane->state);
crtc = state->crtc;
crtc_split_width = get_crtc_split_width(crtc);
fb = state->fb;
if (!crtc || !fb) {
SDE_ERROR_PLANE(psde, "invalid crtc %d or fb %d\n",
@ -1348,17 +1351,17 @@ static int _sde_plane_mode_set(struct drm_plane *plane,
}
}
list_for_each_entry(pp, &psde->phy_plane_head, phy_plane_list) {
if (maxlinewidth > pp->pipe_sblk->maxlinewidth)
maxlinewidth = pp->pipe_sblk->maxlinewidth;
list_for_each_entry(pp, &psde->phy_plane_head, phy_plane_list)
num_of_phy_planes++;
}
/*
* Only need to use one physical plane if plane width is still within
* the limitation.
*/
if (maxlinewidth >= (src.x + src.w))
is_across_mixer_boundary = (plane->state->crtc_x < crtc_split_width) &&
(plane->state->crtc_x + plane->state->crtc_w >
crtc_split_width);
if (crtc_split_width >= (src.x + src.w) && !is_across_mixer_boundary)
num_of_phy_planes = 1;
if (num_of_phy_planes > 1) {
@ -1369,9 +1372,10 @@ static int _sde_plane_mode_set(struct drm_plane *plane,
list_for_each_entry(pp, &psde->phy_plane_head, phy_plane_list) {
/* Adjust offset for multi-pipe */
src.x += src.w * pp->index;
dst.x += dst.w * pp->index;
if (num_of_phy_planes > 1) {
src.x += src.w * pp->index;
dst.x += dst.w * pp->index;
}
pp->pipe_cfg.src_rect = src;
pp->pipe_cfg.dst_rect = dst;