From: Jessica Zhang <[email protected]> Validate requested mode and topology based on the PINGPONG or DSC encoder max width. In addition, drop MAX_HDISPLAY_SPLIT and base LM reservation off of PINGPONG or DSC encoder max width
As noted in the patch, while DPU 8.x+ supports a max linewidth of 8960 for PINGPONG_0, there is some additional logic that needs to be added to the resource manager to specifically try and reserve PINGPONG_0 for modes that are greater than 5k. Since this is out of the scope of this series, add a helper that will get the overall minimum PINGPONG max linewidth for a given chipset. Signed-off-by: Jessica Zhang <[email protected]> Tested-by: Xilin Wu <[email protected]> # qcs6490-radxa-dragon-q6a Signed-off-by: Dmitry Baryshkov <[email protected]> --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 44 ++++++++++++++++++++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 7 ++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index c39f1908ea65..0b74d85a6142 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -762,6 +762,22 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc) _dpu_crtc_complete_flip(crtc); } +static int msm_display_get_max_pingpong_width(struct dpu_kms *dpu_kms) +{ + /* + * Note: While, for DPU 8.x+, PINGPONG_0 can technically support up to + * 8k resolutions, this requires reworking the RM to try to reserve + * PINGPONG_0 for modes greater than 5k. + * + * Once this additional logic is implemented, we can probably drop this + * helper and use the reserved PINGPONG's max_linewidth + */ + if (dpu_kms->catalog->mdss_ver->core_major_ver < 6) + return DPU_1_x_MAX_PINGPONG_WIDTH; + else + return DPU_6_x_MAX_PINGPONG_WIDTH; +} + static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -769,13 +785,14 @@ static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc, struct drm_display_mode *adj_mode = &state->adjusted_mode; u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers; struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); + int max_pingpong_width = msm_display_get_max_pingpong_width(dpu_kms); int i; /* if we cannot merge 2 LMs (no 3d mux) better to fail earlier * before even checking the width after the split */ if (!dpu_kms->catalog->caps->has_3d_merge && - adj_mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width) + adj_mode->hdisplay > max_pingpong_width) return -E2BIG; for (i = 0; i < cstate->num_mixers; i++) { @@ -787,7 +804,7 @@ static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc, trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r); - if (drm_rect_width(r) > dpu_kms->catalog->caps->max_mixer_width) + if (drm_rect_width(r) > max_pingpong_width) return -E2BIG; } @@ -1318,7 +1335,6 @@ static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc_state } #define MAX_CHANNELS_PER_CRTC PIPES_PER_PLANE -#define MAX_HDISPLAY_SPLIT 1080 static struct msm_display_topology dpu_crtc_get_topology( struct drm_crtc *crtc, @@ -1328,6 +1344,7 @@ static struct msm_display_topology dpu_crtc_get_topology( struct drm_display_mode *mode = &crtc_state->adjusted_mode; struct msm_display_topology topology = {0}; struct drm_encoder *drm_enc; + u32 max_hdisplay_split; u32 num_rt_intf; drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) @@ -1335,6 +1352,18 @@ static struct msm_display_topology dpu_crtc_get_topology( &crtc_state->adjusted_mode); topology.cwb_enabled = drm_crtc_in_clone_mode(crtc_state); + max_hdisplay_split = msm_display_get_max_pingpong_width(dpu_kms); + + if (topology.num_dsc > 0) { + u32 max_dsc_encoder_width; + + if (dpu_kms->catalog->mdss_ver->core_major_ver < 6) + max_dsc_encoder_width = DPU_1_x_MAX_DSC_ENCODER_WIDTH; + else + max_dsc_encoder_width = DPU_8_x_MAX_DSC_ENCODER_WIDTH; + + max_hdisplay_split = min(max_hdisplay_split, max_dsc_encoder_width); + } /* * Datapath topology selection @@ -1358,7 +1387,7 @@ static struct msm_display_topology dpu_crtc_get_topology( * count both the WB and real-time phys encoders. * * For non-DSC CWB usecases, have the num_lm be decided by the - * (mode->hdisplay > MAX_HDISPLAY_SPLIT) check. + * (mode->hdisplay > max_hdisplay_split) check. */ num_rt_intf = topology.num_intf; @@ -1374,7 +1403,7 @@ static struct msm_display_topology dpu_crtc_get_topology( } else if (num_rt_intf == 2) { topology.num_lm = 2; } else if (dpu_kms->catalog->caps->has_3d_merge) { - topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; + topology.num_lm = (mode->hdisplay > max_hdisplay_split) ? 2 : 1; } else { topology.num_lm = 1; } @@ -1553,13 +1582,14 @@ static enum drm_mode_status dpu_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) { struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); + int max_pingpong_width = msm_display_get_max_pingpong_width(dpu_kms); u64 adjusted_mode_clk; /* if there is no 3d_mux block we cannot merge LMs so we cannot * split the large layer into 2 LMs, filter out such modes */ if (!dpu_kms->catalog->caps->has_3d_merge && - mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width) + mode->hdisplay > max_pingpong_width) return MODE_BAD_HVALUE; adjusted_mode_clk = dpu_core_perf_adjusted_mode_clk(mode->clock, @@ -1579,7 +1609,7 @@ static enum drm_mode_status dpu_crtc_mode_valid(struct drm_crtc *crtc, * max crtc width is equal to the max mixer width * 2 and max height is 4K */ return drm_mode_validate_size(mode, - 2 * dpu_kms->catalog->caps->max_mixer_width, + 2 * max_pingpong_width, 4096); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 336757103b5a..ee94d0ccb8a3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -24,6 +24,13 @@ #define DPU_MAX_IMG_WIDTH 0x3fff #define DPU_MAX_IMG_HEIGHT 0x3fff +#define DPU_1_x_MAX_PINGPONG_WIDTH 4096 +#define DPU_6_x_MAX_PINGPONG_WIDTH 5120 +#define DPU_8_x_MAX_PINGPONG_0_WIDTH 8960 + +#define DPU_1_x_MAX_DSC_ENCODER_WIDTH 2048 +#define DPU_8_x_MAX_DSC_ENCODER_WIDTH 2560 + #define CRTC_QUAD_MIXERS 4 #define MAX_XIN_COUNT 16 -- 2.47.3
