From f26e0acc3e07ebec228503a995492925690380db Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 8 Apr 2023 03:27:47 +0300 Subject: drm/msm/dpu: enable DPU_CTL_SPLIT_DISPLAY for sc8280xp Theoretically, since sm8150 we should be using a single CTL for the split panel case, but since we do not support it for now, fallback to DPU_CTL_SPLIT_DISPLAY. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/531489/ Link: https://lore.kernel.org/r/20230408002750.2722304-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 706d0f13b598..88b8226e6f75 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -42,17 +42,18 @@ static const struct dpu_mdp_cfg sc8280xp_mdp[] = { }, }; +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sc8280xp_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x204, - .features = CTL_SC7280_MASK, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x16000, .len = 0x204, - .features = CTL_SC7280_MASK, + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { -- cgit v1.2.3 From 800d28a4988d842d11e95d3dea491520ebf4991d Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 8 Apr 2023 03:27:48 +0300 Subject: drm/msm/dpu: enable DSPP_2/3 for LM_2/3 on sm8450 Mark DSPP_2 and DSPP_3 as used for LM_2 and LM_3 Fixes: 100d7ef6995d ("drm/msm/dpu: add support for SM8450") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/531491/ Link: https://lore.kernel.org/r/20230408002750.2722304-3-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 4ecb3df5cbc0..8bd4bb97e639 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -107,9 +107,9 @@ static const struct dpu_lm_cfg sm8450_lm[] = { LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1), LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_2, LM_3, 0), + &sdm845_lm_sblk, PINGPONG_2, LM_3, DSPP_2), LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_3, LM_2, 0), + &sdm845_lm_sblk, PINGPONG_3, LM_2, DSPP_3), LM_BLK("lm_4", LM_4, 0x48000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_4, LM_5, 0), LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, -- cgit v1.2.3 From f5abecfe339e4d8183fbb208da674f4a49b7f722 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 8 Apr 2023 03:27:49 +0300 Subject: drm/msm/dpu: enable DSPP and DSC on sc8180x Enable DSPP and DSC hardware blocks on sc8180x platform. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/531490/ Link: https://lore.kernel.org/r/20230408002750.2722304-4-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 28 ++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index e3bdfe7b30f1..3911ae492540 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -102,9 +102,9 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { static const struct dpu_lm_cfg sc8180x_lm[] = { LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_0, LM_1, 0), + &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0), LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_1, LM_0, 0), + &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1), LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_2, LM_3, 0), LM_BLK("lm_3", LM_3, 0x47000, MIXER_SDM845_MASK, @@ -115,6 +115,17 @@ static const struct dpu_lm_cfg sc8180x_lm[] = { &sdm845_lm_sblk, PINGPONG_5, LM_4, 0), }; +static const struct dpu_dspp_cfg sc8180x_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), + DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), + DSPP_BLK("dspp_2", DSPP_2, 0x58000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), + DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), +}; + static const struct dpu_pingpong_cfg sc8180x_pp[] = { PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), @@ -142,6 +153,15 @@ static const struct dpu_merge_3d_cfg sc8180x_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200), }; +static const struct dpu_dsc_cfg sc8180x_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x80000, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_4", DSC_4, 0x81000, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_5", DSC_5, 0x81400, BIT(DPU_DSC_OUTPUT_CTRL)), +}; + static const struct dpu_intf_cfg sc8180x_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), @@ -190,6 +210,10 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { .sspp = sc8180x_sspp, .mixer_count = ARRAY_SIZE(sc8180x_lm), .mixer = sc8180x_lm, + .dspp_count = ARRAY_SIZE(sc8180x_dspp), + .dspp = sc8180x_dspp, + .dsc_count = ARRAY_SIZE(sc8180x_dsc), + .dsc = sc8180x_dsc, .pingpong_count = ARRAY_SIZE(sc8180x_pp), .pingpong = sc8180x_pp, .merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d), -- cgit v1.2.3 From 23bdc972daf436412d55ad7fb2f1bf430a001ffd Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 8 Apr 2023 03:27:50 +0300 Subject: drm/msm/dpu: use CTL_SC7280_MASK for sm8450's ctl_0 On sm8450 platform the CTL_0 doesn't differ from the rest of CTL blocks, so switch it to CTL_SC7280_MASK too. Some background: original commit 100d7ef6995d ("drm/msm/dpu: add support for SM8450") had all (relevant at that time) bit spelled individually. Then commit 0e91bcbb0016 ("drm/msm/dpu: Add SM8350 to hw catalog"), despite being a mismerge, correctly changed all other CTL entries to use CTL_SC7280_MASK, except CTL_0. While the current BLOCK_SOC_MASK style is not ideal (and while we are working on a better scheme), let's follow its usage as a least minimal surprise. For example, sc8280xp, a close associate of sm8450, also uses CTL_SC7280_MASK. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/531493/ Link: https://lore.kernel.org/r/20230408002750.2722304-5-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 8bd4bb97e639..cb83d25834ce 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -47,7 +47,7 @@ static const struct dpu_ctl_cfg sm8450_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x204, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY) | BIT(DPU_CTL_FETCH_ACTIVE), + .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { -- cgit v1.2.3 From 5a7a86bfa2cd79c80e4f3bdb01feb15edd08b92b Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 15 Apr 2023 20:19:25 +0300 Subject: drm/msm/dpu: simplify intf allocation code Rather than passing DRM_MODE_ENCODER_* and letting dpu_encoder to guess, which intf type we mean, pass INTF_DSI/INTF_DP directly. This is required to support HDMI output in DPU, as both DP and HDMI encoders are DRM_MODE_ENCODER_TMDS. Thus dpu_encoder code can not make a difference between HDMI and DP outputs. Reviewed-by: Bjorn Andersson Signed-off-by: Dmitry Baryshkov Reviewed-by: Arnaud Vrac Tested-by: Arnaud Vrac Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/532370/ Link: https://lore.kernel.org/r/20230415171926.85774-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 39 ++++++++++------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 4 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 6 ++--- 3 files changed, 18 insertions(+), 31 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 1dc5dbe58572..b34416cbd0f5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -495,7 +495,7 @@ void dpu_encoder_helper_split_config( hw_mdptop = phys_enc->hw_mdptop; disp_info = &dpu_enc->disp_info; - if (disp_info->intf_type != DRM_MODE_ENCODER_DSI) + if (disp_info->intf_type != INTF_DSI) return; /** @@ -1127,7 +1127,7 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) } - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_TMDS && + if (dpu_enc->disp_info.intf_type == INTF_DP && dpu_enc->cur_master->hw_mdptop && dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select) dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select( @@ -1135,7 +1135,7 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) _dpu_encoder_update_vsync_source(dpu_enc, &dpu_enc->disp_info); - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI && + if (dpu_enc->disp_info.intf_type == INTF_DSI && !WARN_ON(dpu_enc->num_phys_encs == 0)) { unsigned bpc = dpu_enc->connector->display_info.bpc; for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { @@ -1977,7 +1977,7 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc) phys->ops.handle_post_kickoff(phys); } - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI && + if (dpu_enc->disp_info.intf_type == INTF_DSI && !dpu_encoder_vsync_time(drm_enc, &wakeup_time)) { trace_dpu_enc_early_kickoff(DRMID(drm_enc), ktime_to_ms(wakeup_time)); @@ -2182,7 +2182,7 @@ static int dpu_encoder_virt_add_phys_encs( } - if (disp_info->intf_type == DRM_MODE_ENCODER_VIRTUAL) { + if (disp_info->intf_type == INTF_WB) { enc = dpu_encoder_phys_wb_init(params); if (IS_ERR(enc)) { @@ -2231,7 +2231,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, { int ret = 0; int i = 0; - enum dpu_intf_type intf_type = INTF_NONE; struct dpu_enc_phys_init_params phys_params; if (!dpu_enc) { @@ -2246,23 +2245,11 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, phys_params.parent = &dpu_enc->base; phys_params.enc_spinlock = &dpu_enc->enc_spinlock; - switch (disp_info->intf_type) { - case DRM_MODE_ENCODER_DSI: - intf_type = INTF_DSI; - break; - case DRM_MODE_ENCODER_TMDS: - intf_type = INTF_DP; - break; - case DRM_MODE_ENCODER_VIRTUAL: - intf_type = INTF_WB; - break; - } - WARN_ON(disp_info->num_of_h_tiles < 1); DPU_DEBUG("dsi_info->num_of_h_tiles %d\n", disp_info->num_of_h_tiles); - if (disp_info->intf_type != DRM_MODE_ENCODER_VIRTUAL) + if (disp_info->intf_type != INTF_WB) dpu_enc->idle_pc_supported = dpu_kms->catalog->caps->has_idle_pc; @@ -2290,11 +2277,11 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, i, controller_id, phys_params.split_role); phys_params.intf_idx = dpu_encoder_get_intf(dpu_kms->catalog, - intf_type, - controller_id); + disp_info->intf_type, + controller_id); phys_params.wb_idx = dpu_encoder_get_wb(dpu_kms->catalog, - intf_type, controller_id); + disp_info->intf_type, controller_id); /* * The phys_params might represent either an INTF or a WB unit, but not * both of them at the same time. @@ -2302,14 +2289,14 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, if ((phys_params.intf_idx == INTF_MAX) && (phys_params.wb_idx == WB_MAX)) { DPU_ERROR_ENC(dpu_enc, "could not get intf or wb: type %d, id %d\n", - intf_type, controller_id); + disp_info->intf_type, controller_id); ret = -EINVAL; } if ((phys_params.intf_idx != INTF_MAX) && (phys_params.wb_idx != WB_MAX)) { DPU_ERROR_ENC(dpu_enc, "both intf and wb present: type %d, id %d\n", - intf_type, controller_id); + disp_info->intf_type, controller_id); ret = -EINVAL; } @@ -2409,11 +2396,11 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, timer_setup(&dpu_enc->frame_done_timer, dpu_encoder_frame_done_timeout, 0); - if (disp_info->intf_type == DRM_MODE_ENCODER_DSI) + if (disp_info->intf_type == INTF_DSI) timer_setup(&dpu_enc->vsync_event_timer, dpu_encoder_vsync_event_handler, 0); - else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS) + else if (disp_info->intf_type == INTF_DP) dpu_enc->wide_bus_en = msm_dp_wide_bus_available( priv->dp[disp_info->h_tile_instance[0]]); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 2c9ef8d1b877..6d14f84dd43f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -21,7 +21,7 @@ /** * struct msm_display_info - defines display properties - * @intf_type: DRM_MODE_ENCODER_ type + * @intf_type: INTF_ type * @num_of_h_tiles: Number of horizontal tiles in case of split interface * @h_tile_instance: Controller instance used per tile. Number of elements is * based on num_of_h_tiles @@ -31,7 +31,7 @@ * @dsc: DSC configuration data for DSC-enabled displays */ struct msm_display_info { - int intf_type; + enum dpu_intf_type intf_type; uint32_t num_of_h_tiles; uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY]; bool is_cmd_mode; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 0e7a68714e9e..e85e3721d2c7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -542,7 +542,7 @@ static int _dpu_kms_initialize_dsi(struct drm_device *dev, } memset(&info, 0, sizeof(info)); - info.intf_type = encoder->encoder_type; + info.intf_type = INTF_DSI; rc = msm_dsi_modeset_init(priv->dsi[i], dev, encoder); if (rc) { @@ -605,7 +605,7 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev, info.num_of_h_tiles = 1; info.h_tile_instance[0] = i; - info.intf_type = encoder->encoder_type; + info.intf_type = INTF_DP; rc = dpu_encoder_setup(dev, encoder, &info); if (rc) { DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n", @@ -644,7 +644,7 @@ static int _dpu_kms_initialize_writeback(struct drm_device *dev, info.num_of_h_tiles = 1; /* use only WB idx 2 instance for DPU */ info.h_tile_instance[0] = WB_2; - info.intf_type = encoder->encoder_type; + info.intf_type = INTF_WB; rc = dpu_encoder_setup(dev, encoder, &info); if (rc) { -- cgit v1.2.3 From 9e15123eca7942caa8a3e1f58ec0df7d088df149 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 31 Jan 2023 14:18:25 -0800 Subject: drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset time"), we moved powering up DSI hosts to modeset time. This wasn't because it was an elegant design, but there were no better options. That commit actually ended up breaking ps8640, and thus was born commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for parade-ps8640") as a temporary hack to un-break ps8640 by moving it to the old way of doing things. It turns out that ps8640 _really_ doesn't like its pre_enable() function to be called after dsi_mgr_bridge_power_on(). Specifically (from experimentation, not because I have any inside knowledge), it looks like the assertion of "RST#" in the ps8640 runtime resume handler seems like it's not allowed to happen after dsi_mgr_bridge_power_on() Recently, Dave Stevenson's series landed allowing bridges some control over pre_enable ordering. The meaty commit for our purposes is commit 4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter bridge init order"). As documented by that series, if a bridge doesn't set "pre_enable_prev_first" then we should use the old ordering. Now that we have the commit ("drm/bridge: tc358762: Set pre_enable_prev_first") we can go back to the old ordering, which also allows us to remove the ps8640 special case. One last note is that even without reverting commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset time"), if you _just_ revert the ps8640 special case and try it out then it doesn't seem to fail anymore. I spent time bisecting / debugging this and it turns out to be mostly luck, so we still want this patch to make sure it's solid. Specifically the reason it sorta works these days is because we implemented wait_hpd_asserted() in ps8640 now, plus the magic of "pm_runtime" autosuspend. The fact that we have wait_hpd_asserted() implemented means that we actually power the bridge chip up just a wee bit earlier and then the bridge happens to stay on because of autosuspend and thus ends up powered before dsi_mgr_bridge_power_on(). Cc: Dave Stevenson Cc: Dmitry Baryshkov Cc: Abhinav Kumar Signed-off-by: Douglas Anderson Reviewed-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/521058/ Link: https://lore.kernel.org/r/20230131141756.RFT.v2.2.I4cfeab9d0e07e98ead23dd0736ab4461e6c69002@changeid Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_manager.c | 38 +---------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 1bbac72dad35..2197a54b9b96 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -34,32 +34,6 @@ static struct msm_dsi_manager msm_dsim_glb; #define IS_SYNC_NEEDED() (msm_dsim_glb.is_sync_needed) #define IS_MASTER_DSI_LINK(id) (msm_dsim_glb.master_dsi_link_id == id) -#ifdef CONFIG_OF -static bool dsi_mgr_power_on_early(struct drm_bridge *bridge) -{ - struct drm_bridge *next_bridge = drm_bridge_get_next_bridge(bridge); - - /* - * If the next bridge in the chain is the Parade ps8640 bridge chip - * then don't power on early since it seems to violate the expectations - * of the firmware that the bridge chip is running. - * - * NOTE: this is expected to be a temporary special case. It's expected - * that we'll eventually have a framework that allows the next level - * bridge to indicate whether it needs us to power on before it or - * after it. When that framework is in place then we'll use it and - * remove this special case. - */ - return !(next_bridge && next_bridge->of_node && - of_device_is_compatible(next_bridge->of_node, "parade,ps8640")); -} -#else -static inline bool dsi_mgr_power_on_early(struct drm_bridge *bridge) -{ - return true; -} -#endif - static inline struct msm_dsi *dsi_mgr_get_dsi(int id) { return msm_dsim_glb.dsi[id]; @@ -265,12 +239,6 @@ static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge) int ret; DBG("id=%d", id); - if (!msm_dsi_device_connected(msm_dsi)) - return; - - /* Do nothing with the host if it is slave-DSI in case of bonded DSI */ - if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) - return; ret = dsi_mgr_phy_enable(id, phy_shared_timings); if (ret) @@ -327,8 +295,7 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) return; - if (!dsi_mgr_power_on_early(bridge)) - dsi_mgr_bridge_power_on(bridge); + dsi_mgr_bridge_power_on(bridge); ret = msm_dsi_host_enable(host); if (ret) { @@ -438,9 +405,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, msm_dsi_host_set_display_mode(host, adjusted_mode); if (is_bonded_dsi && other_dsi) msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode); - - if (dsi_mgr_power_on_early(bridge)) - dsi_mgr_bridge_power_on(bridge); } static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge, -- cgit v1.2.3 From d8dd416cb420163f9631a01ddcce78628a6a5962 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 31 Jan 2023 14:18:26 -0800 Subject: drm/msm/dsi: More properly handle errors in regards to dsi_mgr_bridge_power_on() In commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset time") the error handling with regards to dsi_mgr_bridge_power_on() got a bit worse. Specifically if we failed to power the bridge on then nothing would really notice. The modeset function couldn't return an error and thus we'd blindly go forward and try to do the pre-enable. In commit ec7981e6c614 ("drm/msm/dsi: don't powerup at modeset time for parade-ps8640") we added a special case to move the powerup back to pre-enable time for ps8640. When we did that, we didn't try to recover the old/better error handling just for ps8640. In the patch ("drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset") we've now moved the powering up back to exclusively being during pre-enable. That means we can add the better error handling back in, so let's do it. To do so we'll add a new function dsi_mgr_bridge_power_off() that's matches how errors were handled prior to commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset time"). NOTE: Now that we have dsi_mgr_bridge_power_off(), it feels as if we should be calling it in dsi_mgr_bridge_post_disable(). That would make some sense, but doing so would change the current behavior and thus should be a separate patch. Specifically: * dsi_mgr_bridge_post_disable() always calls dsi_mgr_phy_disable() even in the slave-DSI case of bonded DSI. We'd need to add special handling for this if it's truly needed. * dsi_mgr_bridge_post_disable() calls msm_dsi_phy_pll_save_state() midway through the poweroff. * dsi_mgr_bridge_post_disable() has a different order of some of the poweroffs / IRQ disables. For now we'll leave dsi_mgr_bridge_post_disable() alone. Signed-off-by: Douglas Anderson Reviewed-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/521059/ Link: https://lore.kernel.org/r/20230131141756.RFT.v2.3.I3c87b53c4ab61a7d5e05f601a4eb44c7e3809a01@changeid Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_manager.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 2197a54b9b96..28b8012a21f2 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -228,7 +228,7 @@ static void msm_dsi_manager_set_split_display(u8 id) } } -static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge) +static int dsi_mgr_bridge_power_on(struct drm_bridge *bridge) { int id = dsi_mgr_bridge_get_id(bridge); struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); @@ -268,14 +268,31 @@ static void dsi_mgr_bridge_power_on(struct drm_bridge *bridge) if (is_bonded_dsi && msm_dsi1) msm_dsi_host_enable_irq(msm_dsi1->host); - return; + return 0; host1_on_fail: msm_dsi_host_power_off(host); host_on_fail: dsi_mgr_phy_disable(id); phy_en_fail: - return; + return ret; +} + +static void dsi_mgr_bridge_power_off(struct drm_bridge *bridge) +{ + int id = dsi_mgr_bridge_get_id(bridge); + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); + struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); + struct mipi_dsi_host *host = msm_dsi->host; + bool is_bonded_dsi = IS_BONDED_DSI(); + + msm_dsi_host_disable_irq(host); + if (is_bonded_dsi && msm_dsi1) { + msm_dsi_host_disable_irq(msm_dsi1->host); + msm_dsi_host_power_off(msm_dsi1->host); + } + msm_dsi_host_power_off(host); + dsi_mgr_phy_disable(id); } static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) @@ -295,7 +312,11 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) return; - dsi_mgr_bridge_power_on(bridge); + ret = dsi_mgr_bridge_power_on(bridge); + if (ret) { + dev_err(&msm_dsi->pdev->dev, "Power on failed: %d\n", ret); + return; + } ret = msm_dsi_host_enable(host); if (ret) { @@ -316,8 +337,7 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) host1_en_fail: msm_dsi_host_disable(host); host_en_fail: - - return; + dsi_mgr_bridge_power_off(bridge); } void msm_dsi_manager_tpg_enable(void) -- cgit v1.2.3 From 1e0a97f84d73ea1182740f62069690c7f3271abb Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 1 May 2023 04:12:57 +0300 Subject: drm/msm/dsi: don't allow enabling 14nm VCO with unprogrammed rate If the dispcc uses CLK_OPS_PARENT_ENABLE (e.g. on QCM2290), CCF can try enabling VCO before the rate has been programmed. This can cause clock lockups and/or other boot issues. Program the VCO to the minimal PLL rate if the read rate is 0 Hz. Cc: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Reported-by: Vladimir Zapolskiy Reported-by: Konrad Dybcio Reviewed-by: Konrad Dybcio Fixes: f079f6d999cb ("drm/msm/dsi: Add PHY/PLL for 8x96") Patchwork: https://patchwork.freedesktop.org/patch/534813/ Link: https://lore.kernel.org/r/20230501011257.3460103-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 9f488adea7f5..3ce45b023e63 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -539,6 +539,9 @@ static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) if (unlikely(pll_14nm->phy->pll_on)) return 0; + if (dsi_pll_14nm_vco_recalc_rate(hw, VCO_REF_CLK_RATE) == 0) + dsi_pll_14nm_vco_set_rate(hw, pll_14nm->phy->cfg->min_pll_rate, VCO_REF_CLK_RATE); + dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1); -- cgit v1.2.3 From e6f756af381f80c064d1f94077b150f8d95b3dab Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 15 Apr 2023 20:19:26 +0300 Subject: drm/msm/dpu: add HDMI output support MSM8998 and the older Qualcomm platforms support HDMI outputs. Now as DPU encoder is ready, add support for using INTF_HDMI. Signed-off-by: Dmitry Baryshkov Reviewed-by: Arnaud Vrac Tested-by: Arnaud Vrac # on msm8998 Patchwork: https://patchwork.freedesktop.org/patch/532371/ Link: https://lore.kernel.org/r/20230415171926.85774-3-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index e85e3721d2c7..717a44f135eb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -617,6 +617,44 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev, return 0; } +static int _dpu_kms_initialize_hdmi(struct drm_device *dev, + struct msm_drm_private *priv, + struct dpu_kms *dpu_kms) +{ + struct drm_encoder *encoder = NULL; + struct msm_display_info info; + int rc; + + if (!priv->hdmi) + return 0; + + encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS); + if (IS_ERR(encoder)) { + DPU_ERROR("encoder init failed for HDMI display\n"); + return PTR_ERR(encoder); + } + + memset(&info, 0, sizeof(info)); + rc = msm_hdmi_modeset_init(priv->hdmi, dev, encoder); + if (rc) { + DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); + drm_encoder_cleanup(encoder); + return rc; + } + + info.num_of_h_tiles = 1; + info.h_tile_instance[0] = 0; + info.intf_type = INTF_HDMI; + rc = dpu_encoder_setup(dev, encoder, &info); + if (rc) { + DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n", + encoder->base.id, rc); + return rc; + } + + return 0; +} + static int _dpu_kms_initialize_writeback(struct drm_device *dev, struct msm_drm_private *priv, struct dpu_kms *dpu_kms, const u32 *wb_formats, int n_formats) @@ -683,6 +721,12 @@ static int _dpu_kms_setup_displays(struct drm_device *dev, return rc; } + rc = _dpu_kms_initialize_hdmi(dev, priv, dpu_kms); + if (rc) { + DPU_ERROR("initialize HDMI failed, rc = %d\n", rc); + return rc; + } + /* Since WB isn't a driver check the catalog before initializing */ if (dpu_kms->catalog->wb_count) { for (i = 0; i < dpu_kms->catalog->wb_count; i++) { -- cgit v1.2.3 From 95a808328e9918e5716610313f6aec7600108ede Mon Sep 17 00:00:00 2001 From: Arnaud Vrac Date: Wed, 19 Apr 2023 16:41:10 +0200 Subject: drm/msm/dpu: use hsync/vsync polarity set by the encoder Do not override the hsync/vsync polarity passed by the encoder when setting up intf timings. The same logic was used in both the encoder and intf code to set the DP and DSI polarities, so those interfaces are not impacted. However for HDMI, the polarities were overriden to static values based on the vertical resolution, instead of using the actual mode polarities. Signed-off-by: Arnaud Vrac Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/532901/ Link: https://lore.kernel.org/r/20230419-dpu-tweaks-v1-3-d1bac46db075@freebox.fr Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index b9dddf576c02..c665d59f88f5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -99,7 +99,7 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, u32 active_h_start, active_h_end; u32 active_v_start, active_v_end; u32 active_hctl, display_hctl, hsync_ctl; - u32 polarity_ctl, den_polarity, hsync_polarity, vsync_polarity; + u32 polarity_ctl, den_polarity; u32 panel_format; u32 intf_cfg, intf_cfg2 = 0; u32 display_data_hctl = 0, active_data_hctl = 0; @@ -186,19 +186,9 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, } den_polarity = 0; - if (ctx->cap->type == INTF_HDMI) { - hsync_polarity = p->yres >= 720 ? 0 : 1; - vsync_polarity = p->yres >= 720 ? 0 : 1; - } else if (ctx->cap->type == INTF_DP) { - hsync_polarity = p->hsync_polarity; - vsync_polarity = p->vsync_polarity; - } else { - hsync_polarity = 0; - vsync_polarity = 0; - } polarity_ctl = (den_polarity << 2) | /* DEN Polarity */ - (vsync_polarity << 1) | /* VSYNC Polarity */ - (hsync_polarity << 0); /* HSYNC Polarity */ + (p->vsync_polarity << 1) | /* VSYNC Polarity */ + (p->hsync_polarity << 0); /* HSYNC Polarity */ if (!DPU_FORMAT_IS_YUV(fmt)) panel_format = (fmt->bits[C0_G_Y] | -- cgit v1.2.3 From c95771905c494aa5c2abbb56b3e2f7d4aa3b34f9 Mon Sep 17 00:00:00 2001 From: Arnaud Vrac Date: Wed, 19 Apr 2023 16:41:15 +0200 Subject: drm/msm/dpu: fix cursor block register bit offset in msm8998 hw catalog This matches the value for both fbdev and sde implementations in the downstream msm-4.4 repository. Signed-off-by: Arnaud Vrac Fixes: 94391a14fc27 ("drm/msm/dpu1: Add MSM8998 to hw catalog") Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/532899/ Link: https://lore.kernel.org/r/20230419-dpu-tweaks-v1-8-d1bac46db075@freebox.fr Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index bdcd554fc8a8..911612952779 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -39,8 +39,8 @@ static const struct dpu_mdp_cfg msm8998_mdp[] = { .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 12 }, - .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 15 }, - .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x3b0, .bit_off = 15 }, + .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 16 }, + .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x3b0, .bit_off = 16 }, }, }; -- cgit v1.2.3 From 8d6dad490afcc05ca7306ee2bac32774302e4aec Mon Sep 17 00:00:00 2001 From: Arnaud Vrac Date: Wed, 19 Apr 2023 16:41:16 +0200 Subject: drm/msm/dpu: set max cursor width to 512x512 Override the default max cursor size reported to userspace of 64x64. MSM8998 hw cursor planes support 512x512 size, and other chips use DMA SSPPs. Signed-off-by: Arnaud Vrac Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/532903/ Link: https://lore.kernel.org/r/20230419-dpu-tweaks-v1-9-d1bac46db075@freebox.fr Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 717a44f135eb..aebc1dd50a14 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1049,6 +1049,9 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_kms = to_dpu_kms(kms); dev = dpu_kms->dev; + dev->mode_config.cursor_width = 512; + dev->mode_config.cursor_height = 512; + rc = dpu_kms_global_obj_init(dpu_kms); if (rc) return rc; -- cgit v1.2.3 From 078f766e165097c03629cc1a8f7e1a7b7ec0e79b Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 21 Apr 2023 01:25:57 +0300 Subject: drm/msm/dpu: drop the regdma configuration The regdma is currently not used by the current driver. We have no way to practically verify that the regdma is described correctly. Drop it now. Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/533148/ Link: https://lore.kernel.org/r/20230420222558.1208887-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 1 - .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 2 -- .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 2 -- .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 2 -- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 2 -- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 2 -- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 2 -- .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 2 -- .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 2 -- .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 40 ---------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 18 ---------- 12 files changed, 77 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 911612952779..4cd8d7871c4a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -195,7 +195,6 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { .intf = msm8998_intf, .vbif_count = ARRAY_SIZE(msm8998_vbif), .vbif = msm8998_vbif, - .reg_dma_count = 0, .perf = &msm8998_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index ceca741e93c9..63009435e258 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -193,8 +193,6 @@ const struct dpu_mdss_cfg dpu_sdm845_cfg = { .intf = sdm845_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, - .reg_dma_count = 1, - .dma_cfg = &sdm845_regdma, .perf = &sdm845_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 42b0e58624d0..b3f67710a48d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -220,8 +220,6 @@ const struct dpu_mdss_cfg dpu_sm8150_cfg = { .intf = sm8150_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, - .reg_dma_count = 1, - .dma_cfg = &sm8150_regdma, .perf = &sm8150_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index 3911ae492540..1aef11a25834 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -222,8 +222,6 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { .intf = sc8180x_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, - .reg_dma_count = 1, - .dma_cfg = &sm8150_regdma, .perf = &sc8180x_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index ed130582873c..903efc580aef 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -228,8 +228,6 @@ const struct dpu_mdss_cfg dpu_sm8250_cfg = { .vbif = sdm845_vbif, .wb_count = ARRAY_SIZE(sm8250_wb), .wb = sm8250_wb, - .reg_dma_count = 1, - .dma_cfg = &sm8250_regdma, .perf = &sm8250_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index a46b11730a4d..3ab5fbada08f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -143,8 +143,6 @@ const struct dpu_mdss_cfg dpu_sc7180_cfg = { .wb = sc7180_wb, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, - .reg_dma_count = 1, - .dma_cfg = &sdm845_regdma, .perf = &sc7180_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 4f6a965bcd90..9e8d6632a192 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -211,8 +211,6 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .intf = sm8350_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, - .reg_dma_count = 1, - .dma_cfg = &sm8350_regdma, .perf = &sm8350_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 88b8226e6f75..8e4d0bc4aa70 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -203,8 +203,6 @@ const struct dpu_mdss_cfg dpu_sc8280xp_cfg = { .intf = sc8280xp_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, - .reg_dma_count = 1, - .dma_cfg = &sc8280xp_regdma, .perf = &sc8280xp_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index cb83d25834ce..014922ac03db 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -219,8 +219,6 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = { .intf = sm8450_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, - .reg_dma_count = 1, - .dma_cfg = &sm8450_regdma, .perf = &sm8450_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index d0ab351b6a8b..be2f37728aa0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -224,8 +224,6 @@ const struct dpu_mdss_cfg dpu_sm8550_cfg = { .intf = sm8550_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, - .reg_dma_count = 1, - .dma_cfg = &sm8450_regdma, .perf = &sm8550_perf_data, .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 5d994bce696f..afe667121dc7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -650,46 +650,6 @@ static const struct dpu_vbif_cfg sdm845_vbif[] = { }, }; -static const struct dpu_reg_dma_cfg sc8280xp_regdma = { - .base = 0x0, - .version = 0x00020000, - .trigger_sel_off = 0x119c, - .xin_id = 7, - .clk_ctrl = DPU_CLK_CTRL_REG_DMA, -}; - -static const struct dpu_reg_dma_cfg sdm845_regdma = { - .base = 0x0, .version = 0x1, .trigger_sel_off = 0x119c -}; - -static const struct dpu_reg_dma_cfg sm8150_regdma = { - .base = 0x0, .version = 0x00010001, .trigger_sel_off = 0x119c -}; - -static const struct dpu_reg_dma_cfg sm8250_regdma = { - .base = 0x0, - .version = 0x00010002, - .trigger_sel_off = 0x119c, - .xin_id = 7, - .clk_ctrl = DPU_CLK_CTRL_REG_DMA, -}; - -static const struct dpu_reg_dma_cfg sm8350_regdma = { - .base = 0x400, - .version = 0x00020000, - .trigger_sel_off = 0x119c, - .xin_id = 7, - .clk_ctrl = DPU_CLK_CTRL_REG_DMA, -}; - -static const struct dpu_reg_dma_cfg sm8450_regdma = { - .base = 0x0, - .version = 0x00020000, - .trigger_sel_off = 0x119c, - .xin_id = 7, - .clk_ctrl = DPU_CLK_CTRL_REG_DMA, -}; - /************************************************************* * PERF data config *************************************************************/ 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 71584cd56fd7..8d62c21b051a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -720,21 +720,6 @@ struct dpu_vbif_cfg { u32 memtype_count; u32 memtype[MAX_XIN_COUNT]; }; -/** - * struct dpu_reg_dma_cfg - information of lut dma blocks - * @id enum identifying this block - * @base register offset of this block - * @features bit mask identifying sub-blocks/features - * @version version of lutdma hw block - * @trigger_sel_off offset to trigger select registers of lutdma - */ -struct dpu_reg_dma_cfg { - DPU_HW_BLK_INFO; - u32 version; - u32 trigger_sel_off; - u32 xin_id; - enum dpu_clk_ctrl_type clk_ctrl; -}; /** * Define CDP use cases @@ -850,9 +835,6 @@ struct dpu_mdss_cfg { u32 wb_count; const struct dpu_wb_cfg *wb; - u32 reg_dma_count; - const struct dpu_reg_dma_cfg *dma_cfg; - u32 ad_count; u32 dspp_count; -- cgit v1.2.3 From 10036161efbf573fa5b2e42463e5bffe6f9bfb6d Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 21 Apr 2023 01:25:58 +0300 Subject: drm/msm/dpu: stop mapping the regdma region Stop mapping the regdma region. The driver does not support regdma. Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/533150/ Link: https://lore.kernel.org/r/20230420222558.1208887-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 6 ------ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index aebc1dd50a14..e5f02ff9d8e0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1080,12 +1080,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) DPU_DEBUG("VBIF NRT is not defined"); } - dpu_kms->reg_dma = msm_ioremap_quiet(dpu_kms->pdev, "regdma"); - if (IS_ERR(dpu_kms->reg_dma)) { - dpu_kms->reg_dma = NULL; - DPU_DEBUG("REG_DMA is not defined"); - } - dpu_kms_parse_data_bus_icc_path(dpu_kms); rc = pm_runtime_resume_and_get(&dpu_kms->pdev->dev); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index aca39a4689f4..15111e433f21 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -71,7 +71,7 @@ struct dpu_kms { const struct dpu_mdss_cfg *catalog; /* io/register spaces: */ - void __iomem *mmio, *vbif[VBIF_MAX], *reg_dma; + void __iomem *mmio, *vbif[VBIF_MAX]; struct regulator *vdd; struct regulator *mmagic; -- cgit v1.2.3 From 94fdd55b93b46fcd6bc8415ad15b008b45031b1b Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 26 Apr 2023 01:11:10 +0200 Subject: drm/msm/dpu: Drop unused members from HW structs Some of these members were initialized while never read, while others were not even assigned any pointer value at all. Drop them to save some space, and above all confusion when looking at or accidentally dereferencing these members. Signed-off-by: Marijn Suijten Reviewed-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/533862/ Link: https://lore.kernel.org/r/20230418-dpu-drop-useless-for-lookup-v3-2-e8d869eea455@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 5 ----- 6 files changed, 11 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index c665d59f88f5..ac9cc916eabc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -359,7 +359,6 @@ struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx, */ c->idx = idx; c->cap = cfg; - c->mdss = m; _setup_intf_ops(&c->ops, c->cap->features); return c; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 643dd10bc030..e07b2e33af3e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -90,7 +90,6 @@ struct dpu_hw_intf { /* intf */ enum dpu_intf idx; const struct dpu_intf_cfg *cap; - const struct dpu_mdss_cfg *mdss; /* ops */ struct dpu_hw_intf_ops ops; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index cf70a9bd1034..bb3ddec5c7d7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -812,7 +812,6 @@ struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx, } /* Assign ops */ - hw_pipe->catalog = catalog; hw_pipe->ubwc = catalog->ubwc; hw_pipe->idx = idx; hw_pipe->cap = cfg; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 74b98b6b3bc3..5004a02fd61e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -341,7 +341,6 @@ struct dpu_hw_sspp_ops { * struct dpu_hw_sspp - pipe description * @base: hardware block base structure * @hw: block hardware details - * @catalog: back pointer to catalog * @ubwc: ubwc configuration data * @idx: pipe index * @cap: pointer to layer_cfg @@ -350,7 +349,6 @@ struct dpu_hw_sspp_ops { struct dpu_hw_sspp { struct dpu_hw_blk base; struct dpu_hw_blk_reg_map hw; - const struct dpu_mdss_cfg *catalog; const struct dpu_ubwc_cfg *ubwc; /* Pipe */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c index a3e413d27717..f33b48045b5c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -263,7 +263,6 @@ struct dpu_hw_wb *dpu_hw_wb_init(enum dpu_wb idx, } /* Assign ops */ - c->mdp = &m->mdp[0]; c->idx = idx; c->caps = cfg; _setup_wb_ops(&c->ops, c->caps->features); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h index 3ff5a48541e2..b91923f879f1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h @@ -76,15 +76,12 @@ struct dpu_hw_wb_ops { /** * struct dpu_hw_wb : WB driver object * @hw: block hardware details - * @mdp: pointer to associated mdp portion of the catalog * @idx: hardware index number within type * @wb_hw_caps: hardware capabilities * @ops: function pointers - * @hw_mdp: MDP top level hardware block */ struct dpu_hw_wb { struct dpu_hw_blk_reg_map hw; - const struct dpu_mdp_cfg *mdp; /* wb path */ int idx; @@ -92,8 +89,6 @@ struct dpu_hw_wb { /* ops */ struct dpu_hw_wb_ops ops; - - struct dpu_hw_mdp *hw_mdp; }; /** -- cgit v1.2.3 From babdb815ef04572a940e78e533d7e90fc505b77f Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 26 Apr 2023 01:11:11 +0200 Subject: drm/msm/dpu: Pass catalog pointers in RM to replace for-loop ID lookups The Resource Manager already iterates over all available blocks from the catalog, only to pass their ID to a dpu_hw_xxx_init() function which uses an _xxx_offset() helper to search for and find the exact same catalog pointer again to initialize the block with, fallible error handling and all. Instead, pass const pointers to the catalog entries directly to these _init functions and drop the for loops entirely, saving on both readability complexity and unnecessary cycles at boot. Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/533861/ Link: https://lore.kernel.org/r/20230418-dpu-drop-useless-for-lookup-v3-3-e8d869eea455@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 37 +++++---------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 14 ++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 32 +++--------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 11 +++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c | 38 ++++----------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h | 12 +++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 40 ++++++----------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 12 +++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 38 ++++----------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h | 10 +++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c | 33 +++---------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h | 14 ++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 33 +++---------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 14 ++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 39 ++++------------------ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 12 +++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c | 33 +++---------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h | 11 +++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 33 ++++--------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 11 +++---- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 17 +++++----- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 22 +++++-------- 23 files changed, 139 insertions(+), 379 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index bbdc95ce374a..4f7cfa9a00f6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -53,23 +53,6 @@ static const u32 fetch_tbl[SSPP_MAX] = {CTL_INVALID_BIT, 16, 17, 18, 19, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, 0, 1, 2, 3, CTL_INVALID_BIT, CTL_INVALID_BIT}; -static const struct dpu_ctl_cfg *_ctl_offset(enum dpu_ctl ctl, - const struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->ctl_count; i++) { - if (ctl == m->ctl[i].id) { - b->blk_addr = addr + m->ctl[i].base; - b->log_mask = DPU_DBG_MASK_CTL; - return &m->ctl[i]; - } - } - return ERR_PTR(-ENOMEM); -} - static int _mixer_stages(const struct dpu_lm_cfg *mixer, int count, enum dpu_lm lm) { @@ -676,29 +659,25 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active; }; -struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx, +struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg, void __iomem *addr, - const struct dpu_mdss_cfg *m) + u32 mixer_count, + const struct dpu_lm_cfg *mixer) { struct dpu_hw_ctl *c; - const struct dpu_ctl_cfg *cfg; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); - cfg = _ctl_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(c); - pr_err("failed to create dpu_hw_ctl %d\n", idx); - return ERR_PTR(-EINVAL); - } + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_CTL; c->caps = cfg; _setup_ctl_ops(&c->ops, c->caps->features); - c->idx = idx; - c->mixer_count = m->mixer_count; - c->mixer_hw_caps = m->mixer; + c->idx = cfg->id; + c->mixer_count = mixer_count; + c->mixer_hw_caps = mixer; return c; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index 78611a831697..6292002faba2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -261,15 +261,17 @@ static inline struct dpu_hw_ctl *to_dpu_hw_ctl(struct dpu_hw_blk *hw) } /** - * dpu_hw_ctl_init(): Initializes the ctl_path hw driver object. - * should be called before accessing every ctl path registers. - * @idx: ctl_path index for which driver object is required + * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object. + * Should be called before accessing any ctl_path register. + * @cfg: ctl_path catalog entry for which driver object is required * @addr: mapped register io address of MDP - * @m : pointer to mdss catalog data + * @mixer_count: Number of mixers in @mixer + * @mixer: Pointer to an array of Layer Mixers defined in the catalog */ -struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx, +struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg, void __iomem *addr, - const struct dpu_mdss_cfg *m); + u32 mixer_count, + const struct dpu_lm_cfg *mixer); /** * dpu_hw_ctl_destroy(): Destroys ctl driver context diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 4e1396575e6a..89e1a9f945c7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -175,24 +175,6 @@ static void dpu_hw_dsc_bind_pingpong_blk( DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg); } -static const struct dpu_dsc_cfg *_dsc_offset(enum dpu_dsc dsc, - const struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->dsc_count; i++) { - if (dsc == m->dsc[i].id) { - b->blk_addr = addr + m->dsc[i].base; - b->log_mask = DPU_DBG_MASK_DSC; - return &m->dsc[i]; - } - } - - return NULL; -} - static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops, unsigned long cap) { @@ -203,23 +185,19 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops, ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk; }; -struct dpu_hw_dsc *dpu_hw_dsc_init(enum dpu_dsc idx, void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, + void __iomem *addr) { struct dpu_hw_dsc *c; - const struct dpu_dsc_cfg *cfg; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); - cfg = _dsc_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(c); - return ERR_PTR(-EINVAL); - } + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_DSC; - c->idx = idx; + c->idx = cfg->id; c->caps = cfg; _setup_dsc_ops(&c->ops, c->caps->features); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index ae9b5db53d7f..287ec5f1e170 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -61,14 +61,13 @@ struct dpu_hw_dsc { }; /** - * dpu_hw_dsc_init - initializes the dsc block for the passed dsc idx. - * @idx: DSC index for which driver object is required + * dpu_hw_dsc_init() - Initializes the DSC hw driver object. + * @cfg: DSC catalog entry for which driver object is required * @addr: Mapped register io address of MDP - * @m: Pointer to mdss catalog data - * Returns: Error code or allocated dpu_hw_dsc context + * Return: Error code or allocated dpu_hw_dsc context */ -struct dpu_hw_dsc *dpu_hw_dsc_init(enum dpu_dsc idx, void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, + void __iomem *addr); /** * dpu_hw_dsc_destroy - destroys dsc driver context diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c index 8ab5ace34a2d..9419b2209af8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c @@ -68,49 +68,23 @@ static void _setup_dspp_ops(struct dpu_hw_dspp *c, c->ops.setup_pcc = dpu_setup_dspp_pcc; } -static const struct dpu_dspp_cfg *_dspp_offset(enum dpu_dspp dspp, - const struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - if (!m || !addr || !b) - return ERR_PTR(-EINVAL); - - for (i = 0; i < m->dspp_count; i++) { - if (dspp == m->dspp[i].id) { - b->blk_addr = addr + m->dspp[i].base; - b->log_mask = DPU_DBG_MASK_DSPP; - return &m->dspp[i]; - } - } - - return ERR_PTR(-EINVAL); -} - -struct dpu_hw_dspp *dpu_hw_dspp_init(enum dpu_dspp idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg, + void __iomem *addr) { struct dpu_hw_dspp *c; - const struct dpu_dspp_cfg *cfg; - if (!addr || !m) + if (!addr) return ERR_PTR(-EINVAL); c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); - cfg = _dspp_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(c); - return ERR_PTR(-EINVAL); - } + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_DSPP; /* Assign ops */ - c->idx = idx; + c->idx = cfg->id; c->cap = cfg; _setup_dspp_ops(c, c->cap->features); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h index 05ecfdfac93b..bea965681330 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h @@ -79,14 +79,14 @@ static inline struct dpu_hw_dspp *to_dpu_hw_dspp(struct dpu_hw_blk *hw) } /** - * dpu_hw_dspp_init - initializes the dspp hw driver object. - * should be called once before accessing every dspp. - * @idx: DSPP index for which driver object is required + * dpu_hw_dspp_init() - Initializes the DSPP hw driver object. + * should be called once before accessing every DSPP. + * @cfg: DSPP catalog entry for which driver object is required * @addr: Mapped register io address of MDP - * @Return: pointer to structure or ERR_PTR + * Return: pointer to structure or ERR_PTR */ -struct dpu_hw_dspp *dpu_hw_dspp_init(enum dpu_dspp idx, - void __iomem *addr, const struct dpu_mdss_cfg *m); +struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg, + void __iomem *addr); /** * dpu_hw_dspp_destroy(): Destroys DSPP driver context diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h index 425465011c80..bbf475a1cb45 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h @@ -67,7 +67,7 @@ struct dpu_hw_intr { /** * dpu_hw_intr_init(): Initializes the interrupts hw object * @addr: mapped register io address of MDP - * @m : pointer to mdss catalog data + * @m: pointer to MDSS catalog data */ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, const struct dpu_mdss_cfg *m); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index ac9cc916eabc..f0271283a3a7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -68,25 +68,6 @@ #define INTF_MISR_CTRL 0x180 #define INTF_MISR_SIGNATURE 0x184 -static const struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf, - const struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->intf_count; i++) { - if ((intf == m->intf[i].id) && - (m->intf[i].type != INTF_NONE)) { - b->blk_addr = addr + m->intf[i].base; - b->log_mask = DPU_DBG_MASK_INTF; - return &m->intf[i]; - } - } - - return ERR_PTR(-EINVAL); -} - static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, const struct intf_timing_params *p, const struct dpu_format *fmt) @@ -336,28 +317,27 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->collect_misr = dpu_hw_intf_collect_misr; } -struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, + void __iomem *addr) { struct dpu_hw_intf *c; - const struct dpu_intf_cfg *cfg; + + if (cfg->type == INTF_NONE) { + DPU_DEBUG("Skip intf %d with type NONE\n", cfg->id - INTF_0); + return NULL; + } c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); - cfg = _intf_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(c); - pr_err("failed to create dpu_hw_intf %d\n", idx); - return ERR_PTR(-EINVAL); - } + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_INTF; /* * Assign ops */ - c->idx = idx; + c->idx = cfg->id; c->cap = cfg; _setup_intf_ops(&c->ops, c->cap->features); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index e07b2e33af3e..102c4f0e812b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -96,15 +96,13 @@ struct dpu_hw_intf { }; /** - * dpu_hw_intf_init(): Initializes the intf driver for the passed - * interface idx. - * @idx: interface index for which driver object is required + * dpu_hw_intf_init() - Initializes the INTF driver for the passed + * interface catalog entry. + * @cfg: interface catalog entry for which driver object is required * @addr: mapped register io address of MDP - * @m : pointer to mdss catalog data */ -struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, + void __iomem *addr); /** * dpu_hw_intf_destroy(): Destroys INTF driver context diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index f5120ea91ede..214f207ddf8a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -30,24 +30,6 @@ #define LM_MISR_SIGNATURE 0x314 -static const struct dpu_lm_cfg *_lm_offset(enum dpu_lm mixer, - const struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->mixer_count; i++) { - if (mixer == m->mixer[i].id) { - b->blk_addr = addr + m->mixer[i].base; - b->log_mask = DPU_DBG_MASK_LM; - return &m->mixer[i]; - } - } - - return ERR_PTR(-ENOMEM); -} - /** * _stage_offset(): returns the relative offset of the blend registers * for the stage to be setup @@ -160,8 +142,7 @@ static void dpu_hw_lm_setup_color3(struct dpu_hw_mixer *ctx, DPU_REG_WRITE(c, LM_OP_MODE, op_mode); } -static void _setup_mixer_ops(const struct dpu_mdss_cfg *m, - struct dpu_hw_lm_ops *ops, +static void _setup_mixer_ops(struct dpu_hw_lm_ops *ops, unsigned long features) { ops->setup_mixer_out = dpu_hw_lm_setup_out; @@ -175,27 +156,22 @@ static void _setup_mixer_ops(const struct dpu_mdss_cfg *m, ops->collect_misr = dpu_hw_lm_collect_misr; } -struct dpu_hw_mixer *dpu_hw_lm_init(enum dpu_lm idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg, + void __iomem *addr) { struct dpu_hw_mixer *c; - const struct dpu_lm_cfg *cfg; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); - cfg = _lm_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(c); - return ERR_PTR(-EINVAL); - } + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_LM; /* Assign ops */ - c->idx = idx; + c->idx = cfg->id; c->cap = cfg; - _setup_mixer_ops(m, &c->ops, c->cap->features); + _setup_mixer_ops(&c->ops, c->cap->features); return c; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h index 652ddfdedec3..36992d046a53 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h @@ -93,15 +93,13 @@ static inline struct dpu_hw_mixer *to_dpu_hw_mixer(struct dpu_hw_blk *hw) } /** - * dpu_hw_lm_init(): Initializes the mixer hw driver object. + * dpu_hw_lm_init() - Initializes the mixer hw driver object. * should be called once before accessing every mixer. - * @idx: mixer index for which driver object is required + * @cfg: mixer catalog entry for which driver object is required * @addr: mapped register io address of MDP - * @m : pointer to mdss catalog data */ -struct dpu_hw_mixer *dpu_hw_lm_init(enum dpu_lm idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg, + void __iomem *addr); /** * dpu_hw_lm_destroy(): Destroys layer mixer driver context diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c index def0a87fdba5..90e0e05eff8d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c @@ -14,24 +14,6 @@ #define MERGE_3D_MUX 0x000 #define MERGE_3D_MODE 0x004 -static const struct dpu_merge_3d_cfg *_merge_3d_offset(enum dpu_merge_3d idx, - const struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->merge_3d_count; i++) { - if (idx == m->merge_3d[i].id) { - b->blk_addr = addr + m->merge_3d[i].base; - b->log_mask = DPU_DBG_MASK_PINGPONG; - return &m->merge_3d[i]; - } - } - - return ERR_PTR(-EINVAL); -} - static void dpu_hw_merge_3d_setup_3d_mode(struct dpu_hw_merge_3d *merge_3d, enum dpu_3d_blend_mode mode_3d) { @@ -55,24 +37,19 @@ static void _setup_merge_3d_ops(struct dpu_hw_merge_3d *c, c->ops.setup_3d_mode = dpu_hw_merge_3d_setup_3d_mode; }; -struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(enum dpu_merge_3d idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg, + void __iomem *addr) { struct dpu_hw_merge_3d *c; - const struct dpu_merge_3d_cfg *cfg; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); - cfg = _merge_3d_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(c); - return ERR_PTR(-EINVAL); - } + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_PINGPONG; - c->idx = idx; + c->idx = cfg->id; c->caps = cfg; _setup_merge_3d_ops(c, c->caps->features); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h index 81fd1d5f718e..19cec5e88722 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h @@ -46,16 +46,14 @@ static inline struct dpu_hw_merge_3d *to_dpu_hw_merge_3d(struct dpu_hw_blk *hw) } /** - * dpu_hw_merge_3d_init - initializes the merge_3d driver for the passed - * merge_3d idx. - * @idx: Pingpong index for which driver object is required + * dpu_hw_merge_3d_init() - Initializes the merge_3d driver for the passed + * merge3d catalog entry. + * @cfg: Pingpong catalog entry for which driver object is required * @addr: Mapped register io address of MDP - * @m: Pointer to mdss catalog data - * Returns: Error code or allocated dpu_hw_merge_3d context + * Return: Error code or allocated dpu_hw_merge_3d context */ -struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(enum dpu_merge_3d idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg, + void __iomem *addr); /** * dpu_hw_merge_3d_destroy - destroys merge_3d driver context diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index 0fcad9760b6f..3822e0657767 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -42,24 +42,6 @@ static u32 dither_depth_map[DITHER_DEPTH_MAP_INDEX] = { 0, 0, 0, 0, 0, 0, 0, 1, 2 }; -static const struct dpu_pingpong_cfg *_pingpong_offset(enum dpu_pingpong pp, - const struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->pingpong_count; i++) { - if (pp == m->pingpong[i].id) { - b->blk_addr = addr + m->pingpong[i].base; - b->log_mask = DPU_DBG_MASK_PINGPONG; - return &m->pingpong[i]; - } - } - - return ERR_PTR(-EINVAL); -} - static void dpu_hw_pp_setup_dither(struct dpu_hw_pingpong *pp, struct dpu_hw_dither_cfg *cfg) { @@ -290,24 +272,19 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, c->ops.setup_dither = dpu_hw_pp_setup_dither; }; -struct dpu_hw_pingpong *dpu_hw_pingpong_init(enum dpu_pingpong idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg, + void __iomem *addr) { struct dpu_hw_pingpong *c; - const struct dpu_pingpong_cfg *cfg; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); - cfg = _pingpong_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(c); - return ERR_PTR(-EINVAL); - } + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_PINGPONG; - c->idx = idx; + c->idx = cfg->id; c->caps = cfg; _setup_pingpong_ops(c, c->caps->features); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h index c00223441d99..51e9093621a7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h @@ -165,16 +165,14 @@ static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw) } /** - * dpu_hw_pingpong_init - initializes the pingpong driver for the passed - * pingpong idx. - * @idx: Pingpong index for which driver object is required + * dpu_hw_pingpong_init() - initializes the pingpong driver for the passed + * pingpong catalog entry. + * @cfg: Pingpong catalog entry for which driver object is required * @addr: Mapped register io address of MDP - * @m: Pointer to mdss catalog data - * Returns: Error code or allocated dpu_hw_pingpong context + * Return: Error code or allocated dpu_hw_pingpong context */ -struct dpu_hw_pingpong *dpu_hw_pingpong_init(enum dpu_pingpong idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg, + void __iomem *addr); /** * dpu_hw_pingpong_destroy - destroys pingpong driver context diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index bb3ddec5c7d7..31348ff5d493 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -771,49 +771,24 @@ int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, } #endif - -static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp, - void __iomem *addr, - const struct dpu_mdss_cfg *catalog, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - if ((sspp < SSPP_MAX) && catalog && addr && b) { - for (i = 0; i < catalog->sspp_count; i++) { - if (sspp == catalog->sspp[i].id) { - b->blk_addr = addr + catalog->sspp[i].base; - b->log_mask = DPU_DBG_MASK_SSPP; - return &catalog->sspp[i]; - } - } - } - - return ERR_PTR(-ENOMEM); -} - -struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx, - void __iomem *addr, const struct dpu_mdss_cfg *catalog) +struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg, + void __iomem *addr, const struct dpu_ubwc_cfg *ubwc) { struct dpu_hw_sspp *hw_pipe; - const struct dpu_sspp_cfg *cfg; - if (!addr || !catalog) + if (!addr || !ubwc) return ERR_PTR(-EINVAL); hw_pipe = kzalloc(sizeof(*hw_pipe), GFP_KERNEL); if (!hw_pipe) return ERR_PTR(-ENOMEM); - cfg = _sspp_offset(idx, addr, catalog, &hw_pipe->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(hw_pipe); - return ERR_PTR(-EINVAL); - } + hw_pipe->hw.blk_addr = addr + cfg->base; + hw_pipe->hw.log_mask = DPU_DBG_MASK_SSPP; /* Assign ops */ - hw_pipe->ubwc = catalog->ubwc; - hw_pipe->idx = idx; + hw_pipe->ubwc = ubwc; + hw_pipe->idx = cfg->id; hw_pipe->cap = cfg; _setup_layer_ops(hw_pipe, hw_pipe->cap->features); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 5004a02fd61e..7a8d11ba618d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -341,7 +341,7 @@ struct dpu_hw_sspp_ops { * struct dpu_hw_sspp - pipe description * @base: hardware block base structure * @hw: block hardware details - * @ubwc: ubwc configuration data + * @ubwc: UBWC configuration data * @idx: pipe index * @cap: pointer to layer_cfg * @ops: pointer to operations possible for this pipe @@ -361,14 +361,14 @@ struct dpu_hw_sspp { struct dpu_kms; /** - * dpu_hw_sspp_init - initializes the sspp hw driver object. + * dpu_hw_sspp_init() - Initializes the sspp hw driver object. * Should be called once before accessing every pipe. - * @idx: Pipe index for which driver object is required + * @cfg: Pipe catalog entry for which driver object is required * @addr: Mapped register io address of MDP - * @catalog : Pointer to mdss catalog data + * @ubwc: UBWC configuration data */ -struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx, - void __iomem *addr, const struct dpu_mdss_cfg *catalog); +struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg, + void __iomem *addr, const struct dpu_ubwc_cfg *ubwc); /** * dpu_hw_sspp_destroy(): Destroys SSPP driver context diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c index 16c56e240706..a5121a50b2bb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c @@ -211,45 +211,22 @@ static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops, ops->set_write_gather_en = dpu_hw_set_write_gather_en; } -static const struct dpu_vbif_cfg *_top_offset(enum dpu_vbif vbif, - const struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->vbif_count; i++) { - if (vbif == m->vbif[i].id) { - b->blk_addr = addr + m->vbif[i].base; - b->log_mask = DPU_DBG_MASK_VBIF; - return &m->vbif[i]; - } - } - - return ERR_PTR(-EINVAL); -} - -struct dpu_hw_vbif *dpu_hw_vbif_init(enum dpu_vbif idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg, + void __iomem *addr) { struct dpu_hw_vbif *c; - const struct dpu_vbif_cfg *cfg; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); - cfg = _top_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(c); - return ERR_PTR(-EINVAL); - } + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_VBIF; /* * Assign ops */ - c->idx = idx; + c->idx = cfg->id; c->cap = cfg; _setup_vbif_ops(&c->ops, c->cap->features); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h index 6417aa28d32c..7e10d2a172b4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h @@ -106,14 +106,13 @@ struct dpu_hw_vbif { }; /** - * dpu_hw_vbif_init - initializes the vbif driver for the passed interface idx - * @idx: Interface index for which driver object is required + * dpu_hw_vbif_init() - Initializes the VBIF driver for the passed + * VBIF catalog entry. + * @cfg: VBIF catalog entry for which driver object is required * @addr: Mapped register io address of MDSS - * @m: Pointer to mdss catalog data */ -struct dpu_hw_vbif *dpu_hw_vbif_init(enum dpu_vbif idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg, + void __iomem *addr); void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c index f33b48045b5c..4834866d72fd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -52,22 +52,6 @@ /* WB_QOS_CTRL */ #define WB_QOS_CTRL_DANGER_SAFE_EN BIT(0) -static const struct dpu_wb_cfg *_wb_offset(enum dpu_wb wb, - const struct dpu_mdss_cfg *m, void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->wb_count; i++) { - if (wb == m->wb[i].id) { - b->blk_addr = addr + m->wb[i].base; - b->log_mask = DPU_DBG_MASK_WB; - return &m->wb[i]; - } - } - return ERR_PTR(-EINVAL); -} - static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx, struct dpu_hw_wb_cfg *data) { @@ -242,28 +226,23 @@ static void _setup_wb_ops(struct dpu_hw_wb_ops *ops, ops->bind_pingpong_blk = dpu_hw_wb_bind_pingpong_blk; } -struct dpu_hw_wb *dpu_hw_wb_init(enum dpu_wb idx, - void __iomem *addr, const struct dpu_mdss_cfg *m) +struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg, + void __iomem *addr) { struct dpu_hw_wb *c; - const struct dpu_wb_cfg *cfg; - if (!addr || !m) + if (!addr) return ERR_PTR(-EINVAL); c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); - cfg = _wb_offset(idx, m, addr, &c->hw); - if (IS_ERR(cfg)) { - WARN(1, "Unable to find wb idx=%d\n", idx); - kfree(c); - return ERR_PTR(-EINVAL); - } + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_WB; /* Assign ops */ - c->idx = idx; + c->idx = cfg->id; c->caps = cfg; _setup_wb_ops(&c->ops, c->caps->features); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h index b91923f879f1..e4f85409c624 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h @@ -92,14 +92,13 @@ struct dpu_hw_wb { }; /** - * dpu_hw_wb_init(): Initializes and return writeback hw driver object. - * @idx: wb_path index for which driver object is required + * dpu_hw_wb_init() - Initializes the writeback hw driver object. + * @cfg: wb_path catalog entry for which driver object is required * @addr: mapped register io address of MDP - * @m : pointer to mdss catalog data + * Return: Error code or allocated dpu_hw_wb context */ -struct dpu_hw_wb *dpu_hw_wb_init(enum dpu_wb idx, - void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg, + void __iomem *addr); /** * dpu_hw_wb_destroy(): Destroy writeback hw driver object. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index e5f02ff9d8e0..8ce057cc9374 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1125,16 +1125,17 @@ static int dpu_kms_hw_init(struct msm_kms *kms) } for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { - u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - - dpu_kms->hw_vbif[vbif_idx] = dpu_hw_vbif_init(vbif_idx, - dpu_kms->vbif[vbif_idx], dpu_kms->catalog); - if (IS_ERR(dpu_kms->hw_vbif[vbif_idx])) { - rc = PTR_ERR(dpu_kms->hw_vbif[vbif_idx]); - DPU_ERROR("failed to init vbif %d: %d\n", vbif_idx, rc); - dpu_kms->hw_vbif[vbif_idx] = NULL; + struct dpu_hw_vbif *hw; + const struct dpu_vbif_cfg *vbif = &dpu_kms->catalog->vbif[i]; + + hw = dpu_hw_vbif_init(vbif, dpu_kms->vbif[vbif->id]); + if (IS_ERR(hw)) { + rc = PTR_ERR(hw); + DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc); goto power_error; } + + dpu_kms->hw_vbif[vbif->id] = hw; } rc = dpu_core_perf_init(&dpu_kms->perf, dev, dpu_kms->catalog, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index f4dda88a73f7..f0fc70422e56 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -126,7 +126,7 @@ int dpu_rm_init(struct dpu_rm *rm, DPU_ERROR("skip mixer %d with invalid id\n", lm->id); continue; } - hw = dpu_hw_lm_init(lm->id, mmio, cat); + hw = dpu_hw_lm_init(lm, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed lm object creation: err %d\n", rc); @@ -143,7 +143,7 @@ int dpu_rm_init(struct dpu_rm *rm, DPU_ERROR("skip merge_3d %d with invalid id\n", merge_3d->id); continue; } - hw = dpu_hw_merge_3d_init(merge_3d->id, mmio, cat); + hw = dpu_hw_merge_3d_init(merge_3d, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed merge_3d object creation: err %d\n", @@ -161,7 +161,7 @@ int dpu_rm_init(struct dpu_rm *rm, DPU_ERROR("skip pingpong %d with invalid id\n", pp->id); continue; } - hw = dpu_hw_pingpong_init(pp->id, mmio, cat); + hw = dpu_hw_pingpong_init(pp, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed pingpong object creation: err %d\n", @@ -177,15 +177,11 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_intf *hw; const struct dpu_intf_cfg *intf = &cat->intf[i]; - if (intf->type == INTF_NONE) { - DPU_DEBUG("skip intf %d with type none\n", i); - continue; - } if (intf->id < INTF_0 || intf->id >= INTF_MAX) { DPU_ERROR("skip intf %d with invalid id\n", intf->id); continue; } - hw = dpu_hw_intf_init(intf->id, mmio, cat); + hw = dpu_hw_intf_init(intf, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed intf object creation: err %d\n", rc); @@ -203,7 +199,7 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } - hw = dpu_hw_wb_init(wb->id, mmio, cat); + hw = dpu_hw_wb_init(wb, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed wb object creation: err %d\n", rc); @@ -220,7 +216,7 @@ int dpu_rm_init(struct dpu_rm *rm, DPU_ERROR("skip ctl %d with invalid id\n", ctl->id); continue; } - hw = dpu_hw_ctl_init(ctl->id, mmio, cat); + hw = dpu_hw_ctl_init(ctl, mmio, cat->mixer_count, cat->mixer); if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed ctl object creation: err %d\n", rc); @@ -237,7 +233,7 @@ int dpu_rm_init(struct dpu_rm *rm, DPU_ERROR("skip dspp %d with invalid id\n", dspp->id); continue; } - hw = dpu_hw_dspp_init(dspp->id, mmio, cat); + hw = dpu_hw_dspp_init(dspp, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed dspp object creation: err %d\n", rc); @@ -250,7 +246,7 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_dsc *hw; const struct dpu_dsc_cfg *dsc = &cat->dsc[i]; - hw = dpu_hw_dsc_init(dsc->id, mmio, cat); + hw = dpu_hw_dsc_init(dsc, mmio); if (IS_ERR_OR_NULL(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed dsc object creation: err %d\n", rc); @@ -268,7 +264,7 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } - hw = dpu_hw_sspp_init(sspp->id, mmio, cat); + hw = dpu_hw_sspp_init(sspp, mmio, cat->ubwc); if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed sspp object creation: err %d\n", rc); -- cgit v1.2.3 From 198d8c9c0abf0d952756480b020e3b453df01695 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Fri, 28 Apr 2023 15:36:43 -0700 Subject: drm/msm/dpu: remove DPU_DSPP_GC handling in dspp flush Gamma correction blocks (GC) are not used today so lets remove the usage of DPU_DSPP_GC in the dspp flush to make it easier to remove GC from the catalog. We can add this back when GC is properly supported in DPU with one of the standard DRM properties. changes in v3: - drop the link tag which was auto added before Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/534723/ Link: https://lore.kernel.org/r/20230428223646.23595-1-quic_abhinavk@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 4f7cfa9a00f6..cfdefacbc5a2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -319,9 +319,6 @@ static void dpu_hw_ctl_update_pending_flush_dspp_sub_blocks( case DPU_DSPP_PCC: ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(4); break; - case DPU_DSPP_GC: - ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(5); - break; default: return; } -- cgit v1.2.3 From 7debb6bb699db088d7b3c14ccef634e7241b3831 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Fri, 28 Apr 2023 15:36:44 -0700 Subject: drm/msm/dpu: remove DPU_DSPP_IGC handling in dspp flush Inverse gamma correction blocks (IGC) are not used today so lets remove the usage of DPU_DSPP_IGC in the DSPP flush to make it easier to remove IGC from the catalog. We can add this back when IGC is properly supported in DPU with one of the standard DRM properties. changes in v3: - minor change dspp -> DSPP in commit text Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/534724/ Link: https://lore.kernel.org/r/20230428223646.23595-2-quic_abhinavk@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index cfdefacbc5a2..07bcacedf4b0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -313,9 +313,6 @@ static void dpu_hw_ctl_update_pending_flush_dspp_sub_blocks( return; switch (dspp_sub_blk) { - case DPU_DSPP_IGC: - ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(2); - break; case DPU_DSPP_PCC: ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(4); break; -- cgit v1.2.3 From 9fd5aa5ae701a2c6fd7111e7365533c28439c00e Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Fri, 28 Apr 2023 15:36:45 -0700 Subject: drm/msm/dpu: remove GC and IGC related code from dpu catalog Gamma Correction (GC) and Inverse Gamma Correction(IGC) is currently unused. In addition dpu_dspp_sub_blks didn't even have an igc member describing the block. Drop related code from the dpu hardware catalog otherwise this becomes a burden to carry across chipsets in the catalog. changes in v3: - drop IGC related code from dpu_hw_catalog too - update commit text accordingly Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/534725/ Link: https://lore.kernel.org/r/20230428223646.23595-3-quic_abhinavk@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 10 ---------- 2 files changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index afe667121dc7..da3234a6f35a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -91,7 +91,7 @@ #define MERGE_3D_SM8150_MASK (0) -#define DSPP_MSM8998_MASK BIT(DPU_DSPP_PCC) | BIT(DPU_DSPP_GC) +#define DSPP_MSM8998_MASK BIT(DPU_DSPP_PCC) #define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC) @@ -449,8 +449,6 @@ static const struct dpu_lm_sub_blks qcm2290_lm_sblk = { static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = { .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700, .len = 0x90, .version = 0x10007}, - .gc = { .id = DPU_DSPP_GC, .base = 0x17c0, - .len = 0x90, .version = 0x10007}, }; static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = { 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 8d62c21b051a..0dc9e7d585c7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -127,13 +127,9 @@ enum { /** * DSPP sub-blocks * @DPU_DSPP_PCC Panel color correction block - * @DPU_DSPP_GC Gamma correction block - * @DPU_DSPP_IGC Inverse gamma correction block */ enum { DPU_DSPP_PCC = 0x1, - DPU_DSPP_GC, - DPU_DSPP_IGC, DPU_DSPP_MAX }; @@ -398,7 +394,6 @@ struct dpu_caps { * @hsic: * @memcolor: * @pcc_blk: - * @igc_blk: * @format_list: Pointer to list of supported formats * @num_formats: Number of supported formats * @virt_format_list: Pointer to list of supported formats for virtual planes @@ -419,7 +414,6 @@ struct dpu_sspp_sub_blks { struct dpu_pp_blk hsic_blk; struct dpu_pp_blk memcolor_blk; struct dpu_pp_blk pcc_blk; - struct dpu_pp_blk igc_blk; const u32 *format_list; u32 num_formats; @@ -433,22 +427,18 @@ struct dpu_sspp_sub_blks { * @maxwidth: Max pixel width supported by this mixer * @maxblendstages: Max number of blend-stages supported * @blendstage_base: Blend-stage register base offset - * @gc: gamma correction block */ struct dpu_lm_sub_blks { u32 maxwidth; u32 maxblendstages; u32 blendstage_base[MAX_BLOCKS]; - struct dpu_pp_blk gc; }; /** * struct dpu_dspp_sub_blks: Information of DSPP block - * @gc : gamma correction block * @pcc: pixel color correction block */ struct dpu_dspp_sub_blks { - struct dpu_pp_blk gc; struct dpu_pp_blk pcc; }; -- cgit v1.2.3 From 732c2c5298219bc21da3396bc09deb3589295349 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Fri, 28 Apr 2023 15:36:46 -0700 Subject: drm/msm/dpu: drop DSPP_MSM8998_MASK from hw catalog Since GC and IGC masks have now been dropped, DSPP_MSM8998_MASK is the same as DSPP_SC7180_MASK. Since DSPP_SC7180_MASK is used more than DSPP_MSM8998_MASK, lets drop the latter. Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/534726/ Link: https://lore.kernel.org/r/20230428223646.23595-4-quic_abhinavk@quicinc.com [DB: fixed typo in commit message] Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 4cd8d7871c4a..886aaf4b213a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -127,9 +127,9 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = { }; static const struct dpu_dspp_cfg msm8998_dspp[] = { - DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK, + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, &msm8998_dspp_sblk), - DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_MSM8998_MASK, + DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_SC7180_MASK, &msm8998_dspp_sblk), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index da3234a6f35a..9fa581f0b415 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -91,8 +91,6 @@ #define MERGE_3D_SM8150_MASK (0) -#define DSPP_MSM8998_MASK BIT(DPU_DSPP_PCC) - #define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC) #define INTF_SDM845_MASK (0) -- cgit v1.2.3 From 52788338110c06846cb62ad54569659b0cc59970 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 30 Apr 2023 00:25:12 +0300 Subject: drm/msm/dpu: drop unused SSPP sub-block information The driver doesn't support hsic/memcolor and pcc SSPP subblocks. Drop corresponding definitions. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/534766/ Link: https://lore.kernel.org/r/20230429212512.2947245-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/gpu/drm') 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 0dc9e7d585c7..c6eb5a8a66da 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -391,9 +391,6 @@ struct dpu_caps { * @src_blk: * @scaler_blk: * @csc_blk: - * @hsic: - * @memcolor: - * @pcc_blk: * @format_list: Pointer to list of supported formats * @num_formats: Number of supported formats * @virt_format_list: Pointer to list of supported formats for virtual planes @@ -411,9 +408,6 @@ struct dpu_sspp_sub_blks { struct dpu_src_blk src_blk; struct dpu_scaler_blk scaler_blk; struct dpu_pp_blk csc_blk; - struct dpu_pp_blk hsic_blk; - struct dpu_pp_blk memcolor_blk; - struct dpu_pp_blk pcc_blk; const u32 *format_list; u32 num_formats; -- cgit v1.2.3 From 3ce166380567d8385b776d7b72b603e0d2379e18 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 3 May 2023 15:39:05 -0700 Subject: drm/msm/dpu: add writeback support for sc7280 Add writeback support for sc7280. This was validated with kms_writeback test case in IGT. Signed-off-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/535244/ Link: https://lore.kernel.org/r/20230503223905.24754-1-quic_abhinavk@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 6b2c7eae71d9..b4cf445b74bf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -31,6 +31,7 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = { .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, }, }; @@ -93,6 +94,11 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), }; +static const struct dpu_wb_cfg sc7280_wb[] = { + WB_BLK("wb_2", WB_2, 0x65000, WB_SM8250_MASK, DPU_CLK_CTRL_WB2, 6, + VBIF_RT, MDP_SSPP_TOP0_INTR, 4096, 4), +}; + static const struct dpu_intf_cfg sc7280_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25), INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27), @@ -142,6 +148,8 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { .mixer = sc7280_lm, .pingpong_count = ARRAY_SIZE(sc7280_pp), .pingpong = sc7280_pp, + .wb_count = ARRAY_SIZE(sc7280_wb), + .wb = sc7280_wb, .intf_count = ARRAY_SIZE(sc7280_intf), .intf = sc7280_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), -- cgit v1.2.3 From 853b292b92d50d1b30628c92229e93d670304e51 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 18 May 2023 23:29:08 +0200 Subject: drm/msm/dpu: Use V4.0 PCC DSPP sub-block in SC7[12]80 According to various downstream sources the PCC sub-block inside DSPP is version 4.0 since DPU 4.0 and higher, including SC7[12]80 at DPU version 6.2 and 7.2 respectively. After correcting the version this struct becomes identical to sm8150_dspp_sblk which is used all across the catalog: replace uses of sc7180_dspp_sblk with that and remove the struct definition for sc7180_dspp_sblk entirely. Fixes: 4259ff7ae509e ("drm/msm/dpu: add support for pcc color block in dpu driver") Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/537899/ Link: https://lore.kernel.org/r/20230518-dpu-sc7180-pcc-version-v1-1-ec9ca4949e3e@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 5 ----- 3 files changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 3ab5fbada08f..911479cb1675 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -76,7 +76,7 @@ static const struct dpu_lm_cfg sc7180_lm[] = { static const struct dpu_dspp_cfg sc7180_dspp[] = { DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, - &sc7180_dspp_sblk), + &sm8150_dspp_sblk), }; static const struct dpu_pingpong_cfg sc7180_pp[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index b4cf445b74bf..ec9047cd60fd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -84,7 +84,7 @@ static const struct dpu_lm_cfg sc7280_lm[] = { static const struct dpu_dspp_cfg sc7280_dspp[] = { DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, - &sc7180_dspp_sblk), + &sm8150_dspp_sblk), }; static const struct dpu_pingpong_cfg sc7280_pp[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 9fa581f0b415..da758510fbfe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -449,11 +449,6 @@ static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = { .len = 0x90, .version = 0x10007}, }; -static const struct dpu_dspp_sub_blks sc7180_dspp_sblk = { - .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700, - .len = 0x90, .version = 0x10000}, -}; - static const struct dpu_dspp_sub_blks sm8150_dspp_sblk = { .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700, .len = 0x90, .version = 0x40000}, -- cgit v1.2.3 From d9388af508436091adc1bce492caebab4586b2dd Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:23 +0200 Subject: drm/msm/dpu: Remove extraneous register define indentation A bunch of registers are indented with two extra spaces, looking as if these are values corresponding to the previous register which is not the case, rather these are simply also register offsets and should only have a single space separating them and the #define keyword. Signed-off-by: Marijn Suijten Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/534218/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-9-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 41 +++++++++++++++-------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index f0271283a3a7..24ede498799f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -38,26 +38,27 @@ #define INTF_ACTIVE_DATA_HCTL 0x068 #define INTF_FRAME_LINE_COUNT_EN 0x0A8 #define INTF_FRAME_COUNT 0x0AC -#define INTF_LINE_COUNT 0x0B0 - -#define INTF_DEFLICKER_CONFIG 0x0F0 -#define INTF_DEFLICKER_STRNG_COEFF 0x0F4 -#define INTF_DEFLICKER_WEAK_COEFF 0x0F8 - -#define INTF_DSI_CMD_MODE_TRIGGER_EN 0x084 -#define INTF_PANEL_FORMAT 0x090 -#define INTF_TPG_ENABLE 0x100 -#define INTF_TPG_MAIN_CONTROL 0x104 -#define INTF_TPG_VIDEO_CONFIG 0x108 -#define INTF_TPG_COMPONENT_LIMITS 0x10C -#define INTF_TPG_RECTANGLE 0x110 -#define INTF_TPG_INITIAL_VALUE 0x114 -#define INTF_TPG_BLK_WHITE_PATTERN_FRAMES 0x118 -#define INTF_TPG_RGB_MAPPING 0x11C -#define INTF_PROG_FETCH_START 0x170 -#define INTF_PROG_ROT_START 0x174 -#define INTF_MUX 0x25C -#define INTF_STATUS 0x26C +#define INTF_LINE_COUNT 0x0B0 + +#define INTF_DEFLICKER_CONFIG 0x0F0 +#define INTF_DEFLICKER_STRNG_COEFF 0x0F4 +#define INTF_DEFLICKER_WEAK_COEFF 0x0F8 + +#define INTF_DSI_CMD_MODE_TRIGGER_EN 0x084 +#define INTF_PANEL_FORMAT 0x090 +#define INTF_TPG_ENABLE 0x100 +#define INTF_TPG_MAIN_CONTROL 0x104 +#define INTF_TPG_VIDEO_CONFIG 0x108 +#define INTF_TPG_COMPONENT_LIMITS 0x10C +#define INTF_TPG_RECTANGLE 0x110 +#define INTF_TPG_INITIAL_VALUE 0x114 +#define INTF_TPG_BLK_WHITE_PATTERN_FRAMES 0x118 +#define INTF_TPG_RGB_MAPPING 0x11C +#define INTF_PROG_FETCH_START 0x170 +#define INTF_PROG_ROT_START 0x174 + +#define INTF_MUX 0x25C +#define INTF_STATUS 0x26C #define INTF_CFG_ACTIVE_H_EN BIT(29) #define INTF_CFG_ACTIVE_V_EN BIT(30) -- cgit v1.2.3 From d80d7f8912a8cbec16ec55793f4b20fc5e76640f Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:24 +0200 Subject: drm/msm/dpu: Sort INTF registers numerically A bunch of registers were appended at the end in e.g. commit 91143873a05d ("drm/msm/dpu: Add MISR register support for interface") rather than being inserted in a place that maintains numerical sorting: restore said numerical sorting. Signed-off-by: Marijn Suijten Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534213/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-10-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 24ede498799f..0bd99f380a49 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -36,6 +36,10 @@ #define INTF_CONFIG2 0x060 #define INTF_DISPLAY_DATA_HCTL 0x064 #define INTF_ACTIVE_DATA_HCTL 0x068 + +#define INTF_DSI_CMD_MODE_TRIGGER_EN 0x084 +#define INTF_PANEL_FORMAT 0x090 + #define INTF_FRAME_LINE_COUNT_EN 0x0A8 #define INTF_FRAME_COUNT 0x0AC #define INTF_LINE_COUNT 0x0B0 @@ -44,8 +48,6 @@ #define INTF_DEFLICKER_STRNG_COEFF 0x0F4 #define INTF_DEFLICKER_WEAK_COEFF 0x0F8 -#define INTF_DSI_CMD_MODE_TRIGGER_EN 0x084 -#define INTF_PANEL_FORMAT 0x090 #define INTF_TPG_ENABLE 0x100 #define INTF_TPG_MAIN_CONTROL 0x104 #define INTF_TPG_VIDEO_CONFIG 0x108 @@ -57,6 +59,9 @@ #define INTF_PROG_FETCH_START 0x170 #define INTF_PROG_ROT_START 0x174 +#define INTF_MISR_CTRL 0x180 +#define INTF_MISR_SIGNATURE 0x184 + #define INTF_MUX 0x25C #define INTF_STATUS 0x26C @@ -66,8 +71,6 @@ #define INTF_CFG2_DATABUS_WIDEN BIT(0) #define INTF_CFG2_DATA_HCTL_EN BIT(4) -#define INTF_MISR_CTRL 0x180 -#define INTF_MISR_SIGNATURE 0x184 static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, const struct intf_timing_params *p, -- cgit v1.2.3 From f0408020bfdaeef168e46eead3cbcfc7fd16f314 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:25 +0200 Subject: drm/msm/dpu: Take INTF index as parameter in interrupt register defines Instead of hardcoding many register defines for every INTF and AD4 index with a fixed stride, turn the defines into singular chunks of math that compute the address using the base and this fixed stride multiplied by the index given as argument to the definitions. MDP_SSPP_TOP0_OFF is dropped as that constant is zero anyway, and all register offsets related to it live in dpu_hwio.h. Suggested-by: Dmitry Baryshkov Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534221/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-11-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 156 ++++++++++------------ 1 file changed, 72 insertions(+), 84 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index 17f3e7e4f194..152d4272a087 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -17,30 +17,18 @@ * Register offsets in MDSS register file for the interrupt registers * w.r.t. the MDP base */ -#define MDP_SSPP_TOP0_OFF 0x0 -#define MDP_INTF_0_OFF 0x6A000 -#define MDP_INTF_1_OFF 0x6A800 -#define MDP_INTF_2_OFF 0x6B000 -#define MDP_INTF_3_OFF 0x6B800 -#define MDP_INTF_4_OFF 0x6C000 -#define MDP_INTF_5_OFF 0x6C800 -#define INTF_INTR_EN 0x1c0 -#define INTF_INTR_STATUS 0x1c4 -#define INTF_INTR_CLEAR 0x1c8 -#define MDP_AD4_0_OFF 0x7C000 -#define MDP_AD4_1_OFF 0x7D000 -#define MDP_AD4_INTR_EN_OFF 0x41c -#define MDP_AD4_INTR_CLEAR_OFF 0x424 -#define MDP_AD4_INTR_STATUS_OFF 0x420 -#define MDP_INTF_0_OFF_REV_7xxx 0x34000 -#define MDP_INTF_1_OFF_REV_7xxx 0x35000 -#define MDP_INTF_2_OFF_REV_7xxx 0x36000 -#define MDP_INTF_3_OFF_REV_7xxx 0x37000 -#define MDP_INTF_4_OFF_REV_7xxx 0x38000 -#define MDP_INTF_5_OFF_REV_7xxx 0x39000 -#define MDP_INTF_6_OFF_REV_7xxx 0x3a000 -#define MDP_INTF_7_OFF_REV_7xxx 0x3b000 -#define MDP_INTF_8_OFF_REV_7xxx 0x3c000 +#define MDP_INTF_OFF(intf) (0x6A000 + 0x800 * (intf)) +#define MDP_INTF_INTR_EN(intf) (MDP_INTF_OFF(intf) + 0x1c0) +#define MDP_INTF_INTR_STATUS(intf) (MDP_INTF_OFF(intf) + 0x1c4) +#define MDP_INTF_INTR_CLEAR(intf) (MDP_INTF_OFF(intf) + 0x1c8) +#define MDP_AD4_OFF(ad4) (0x7C000 + 0x1000 * (ad4)) +#define MDP_AD4_INTR_EN_OFF(ad4) (MDP_AD4_OFF(ad4) + 0x41c) +#define MDP_AD4_INTR_CLEAR_OFF(ad4) (MDP_AD4_OFF(ad4) + 0x424) +#define MDP_AD4_INTR_STATUS_OFF(ad4) (MDP_AD4_OFF(ad4) + 0x420) +#define MDP_INTF_REV_7xxx_OFF(intf) (0x34000 + 0x1000 * (intf)) +#define MDP_INTF_REV_7xxx_INTR_EN(intf) (MDP_INTF_REV_7xxx_OFF(intf) + 0x1c0) +#define MDP_INTF_REV_7xxx_INTR_STATUS(intf) (MDP_INTF_REV_7xxx_OFF(intf) + 0x1c4) +#define MDP_INTF_REV_7xxx_INTR_CLEAR(intf) (MDP_INTF_REV_7xxx_OFF(intf) + 0x1c8) /** * struct dpu_intr_reg - array of DPU register sets @@ -61,104 +49,104 @@ struct dpu_intr_reg { */ static const struct dpu_intr_reg dpu_intr_set[] = { [MDP_SSPP_TOP0_INTR] = { - MDP_SSPP_TOP0_OFF+INTR_CLEAR, - MDP_SSPP_TOP0_OFF+INTR_EN, - MDP_SSPP_TOP0_OFF+INTR_STATUS + INTR_CLEAR, + INTR_EN, + INTR_STATUS }, [MDP_SSPP_TOP0_INTR2] = { - MDP_SSPP_TOP0_OFF+INTR2_CLEAR, - MDP_SSPP_TOP0_OFF+INTR2_EN, - MDP_SSPP_TOP0_OFF+INTR2_STATUS + INTR2_CLEAR, + INTR2_EN, + INTR2_STATUS }, [MDP_SSPP_TOP0_HIST_INTR] = { - MDP_SSPP_TOP0_OFF+HIST_INTR_CLEAR, - MDP_SSPP_TOP0_OFF+HIST_INTR_EN, - MDP_SSPP_TOP0_OFF+HIST_INTR_STATUS + HIST_INTR_CLEAR, + HIST_INTR_EN, + HIST_INTR_STATUS }, [MDP_INTF0_INTR] = { - MDP_INTF_0_OFF+INTF_INTR_CLEAR, - MDP_INTF_0_OFF+INTF_INTR_EN, - MDP_INTF_0_OFF+INTF_INTR_STATUS + MDP_INTF_INTR_CLEAR(0), + MDP_INTF_INTR_EN(0), + MDP_INTF_INTR_STATUS(0) }, [MDP_INTF1_INTR] = { - MDP_INTF_1_OFF+INTF_INTR_CLEAR, - MDP_INTF_1_OFF+INTF_INTR_EN, - MDP_INTF_1_OFF+INTF_INTR_STATUS + MDP_INTF_INTR_CLEAR(1), + MDP_INTF_INTR_EN(1), + MDP_INTF_INTR_STATUS(1) }, [MDP_INTF2_INTR] = { - MDP_INTF_2_OFF+INTF_INTR_CLEAR, - MDP_INTF_2_OFF+INTF_INTR_EN, - MDP_INTF_2_OFF+INTF_INTR_STATUS + MDP_INTF_INTR_CLEAR(2), + MDP_INTF_INTR_EN(2), + MDP_INTF_INTR_STATUS(2) }, [MDP_INTF3_INTR] = { - MDP_INTF_3_OFF+INTF_INTR_CLEAR, - MDP_INTF_3_OFF+INTF_INTR_EN, - MDP_INTF_3_OFF+INTF_INTR_STATUS + MDP_INTF_INTR_CLEAR(3), + MDP_INTF_INTR_EN(3), + MDP_INTF_INTR_STATUS(3) }, [MDP_INTF4_INTR] = { - MDP_INTF_4_OFF+INTF_INTR_CLEAR, - MDP_INTF_4_OFF+INTF_INTR_EN, - MDP_INTF_4_OFF+INTF_INTR_STATUS + MDP_INTF_INTR_CLEAR(4), + MDP_INTF_INTR_EN(4), + MDP_INTF_INTR_STATUS(4) }, [MDP_INTF5_INTR] = { - MDP_INTF_5_OFF+INTF_INTR_CLEAR, - MDP_INTF_5_OFF+INTF_INTR_EN, - MDP_INTF_5_OFF+INTF_INTR_STATUS + MDP_INTF_INTR_CLEAR(5), + MDP_INTF_INTR_EN(5), + MDP_INTF_INTR_STATUS(5) }, [MDP_AD4_0_INTR] = { - MDP_AD4_0_OFF + MDP_AD4_INTR_CLEAR_OFF, - MDP_AD4_0_OFF + MDP_AD4_INTR_EN_OFF, - MDP_AD4_0_OFF + MDP_AD4_INTR_STATUS_OFF, + MDP_AD4_INTR_CLEAR_OFF(0), + MDP_AD4_INTR_EN_OFF(0), + MDP_AD4_INTR_STATUS_OFF(0), }, [MDP_AD4_1_INTR] = { - MDP_AD4_1_OFF + MDP_AD4_INTR_CLEAR_OFF, - MDP_AD4_1_OFF + MDP_AD4_INTR_EN_OFF, - MDP_AD4_1_OFF + MDP_AD4_INTR_STATUS_OFF, + MDP_AD4_INTR_CLEAR_OFF(1), + MDP_AD4_INTR_EN_OFF(1), + MDP_AD4_INTR_STATUS_OFF(1), }, [MDP_INTF0_7xxx_INTR] = { - MDP_INTF_0_OFF_REV_7xxx+INTF_INTR_CLEAR, - MDP_INTF_0_OFF_REV_7xxx+INTF_INTR_EN, - MDP_INTF_0_OFF_REV_7xxx+INTF_INTR_STATUS + MDP_INTF_REV_7xxx_INTR_CLEAR(0), + MDP_INTF_REV_7xxx_INTR_EN(0), + MDP_INTF_REV_7xxx_INTR_STATUS(0) }, [MDP_INTF1_7xxx_INTR] = { - MDP_INTF_1_OFF_REV_7xxx+INTF_INTR_CLEAR, - MDP_INTF_1_OFF_REV_7xxx+INTF_INTR_EN, - MDP_INTF_1_OFF_REV_7xxx+INTF_INTR_STATUS + MDP_INTF_REV_7xxx_INTR_CLEAR(1), + MDP_INTF_REV_7xxx_INTR_EN(1), + MDP_INTF_REV_7xxx_INTR_STATUS(1) }, [MDP_INTF2_7xxx_INTR] = { - MDP_INTF_2_OFF_REV_7xxx+INTF_INTR_CLEAR, - MDP_INTF_2_OFF_REV_7xxx+INTF_INTR_EN, - MDP_INTF_2_OFF_REV_7xxx+INTF_INTR_STATUS + MDP_INTF_REV_7xxx_INTR_CLEAR(2), + MDP_INTF_REV_7xxx_INTR_EN(2), + MDP_INTF_REV_7xxx_INTR_STATUS(2) }, [MDP_INTF3_7xxx_INTR] = { - MDP_INTF_3_OFF_REV_7xxx+INTF_INTR_CLEAR, - MDP_INTF_3_OFF_REV_7xxx+INTF_INTR_EN, - MDP_INTF_3_OFF_REV_7xxx+INTF_INTR_STATUS + MDP_INTF_REV_7xxx_INTR_CLEAR(3), + MDP_INTF_REV_7xxx_INTR_EN(3), + MDP_INTF_REV_7xxx_INTR_STATUS(3) }, [MDP_INTF4_7xxx_INTR] = { - MDP_INTF_4_OFF_REV_7xxx+INTF_INTR_CLEAR, - MDP_INTF_4_OFF_REV_7xxx+INTF_INTR_EN, - MDP_INTF_4_OFF_REV_7xxx+INTF_INTR_STATUS + MDP_INTF_REV_7xxx_INTR_CLEAR(4), + MDP_INTF_REV_7xxx_INTR_EN(4), + MDP_INTF_REV_7xxx_INTR_STATUS(4) }, [MDP_INTF5_7xxx_INTR] = { - MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_CLEAR, - MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_EN, - MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_STATUS + MDP_INTF_REV_7xxx_INTR_CLEAR(5), + MDP_INTF_REV_7xxx_INTR_EN(5), + MDP_INTF_REV_7xxx_INTR_STATUS(5) }, [MDP_INTF6_7xxx_INTR] = { - MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_CLEAR, - MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_EN, - MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_STATUS + MDP_INTF_REV_7xxx_INTR_CLEAR(6), + MDP_INTF_REV_7xxx_INTR_EN(6), + MDP_INTF_REV_7xxx_INTR_STATUS(6) }, [MDP_INTF7_7xxx_INTR] = { - MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_CLEAR, - MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_EN, - MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_STATUS + MDP_INTF_REV_7xxx_INTR_CLEAR(7), + MDP_INTF_REV_7xxx_INTR_EN(7), + MDP_INTF_REV_7xxx_INTR_STATUS(7) }, [MDP_INTF8_7xxx_INTR] = { - MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_CLEAR, - MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_EN, - MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_STATUS + MDP_INTF_REV_7xxx_INTR_CLEAR(8), + MDP_INTF_REV_7xxx_INTR_EN(8), + MDP_INTF_REV_7xxx_INTR_STATUS(8) }, }; -- cgit v1.2.3 From a2623e72c52b2cf258b34675a8ff38c66e7d26fb Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:26 +0200 Subject: drm/msm/dpu: Drop unused poll_timeout_wr_ptr PINGPONG callback This callback was migrated from downstream when DPU1 was first introduced to mainline, but never used by any component. Drop it to save some lines and unnecessary confusion. Suggested-by: Dmitry Baryshkov Signed-off-by: Marijn Suijten Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534215/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-12-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 18 ------------------ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 6 ------ 2 files changed, 24 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index 3822e0657767..1dcbb75b80d3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -126,23 +126,6 @@ static bool dpu_hw_pp_get_autorefresh_config(struct dpu_hw_pingpong *pp, return !!((val & BIT(31)) >> 31); } -static int dpu_hw_pp_poll_timeout_wr_ptr(struct dpu_hw_pingpong *pp, - u32 timeout_us) -{ - struct dpu_hw_blk_reg_map *c; - u32 val; - int rc; - - if (!pp) - return -EINVAL; - - c = &pp->hw; - rc = readl_poll_timeout(c->blk_addr + PP_LINE_COUNT, - val, (val & 0xffff) >= 1, 10, timeout_us); - - return rc; -} - static int dpu_hw_pp_enable_te(struct dpu_hw_pingpong *pp, bool enable) { struct dpu_hw_blk_reg_map *c; @@ -262,7 +245,6 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info; c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config; c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config; - c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr; c->ops.get_line_count = dpu_hw_pp_get_line_count; c->ops.setup_dsc = dpu_hw_pp_setup_dsc; c->ops.enable_dsc = dpu_hw_pp_dsc_enable; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h index 51e9093621a7..42af9e5b865e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h @@ -107,12 +107,6 @@ struct dpu_hw_pingpong_ops { bool (*get_autorefresh)(struct dpu_hw_pingpong *pp, u32 *frame_count); - /** - * poll until write pointer transmission starts - * @Return: 0 on success, -ETIMEDOUT on timeout - */ - int (*poll_timeout_wr_ptr)(struct dpu_hw_pingpong *pp, u32 timeout_us); - /** * Obtain current vertical line counter */ -- cgit v1.2.3 From 4a7c38ec7d8efe96c4d8b4d5fc0efb5b06db58e9 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:27 +0200 Subject: drm/msm/dpu: Move autorefresh disable from CMD encoder to pingpong This autorefresh disable logic in the physical command-mode encoder consumes three callbacks to the pingpong block, and will explode in unnecessary complexity when the same callbacks need to be called on the interface block instead to accommodate INTF TE support. To clean this up, move the logic into the pingpong block under a disable_autorefresh callback, replacing the aforementioned three get_autorefresh, setup_autorefresh and get_vsync_info callbacks. The same logic will have to be replicated to the interface block when it receives INTF TE support, but it is less complex than constantly switching on a "has_intf_te" boolean to choose a callback. Suggested-by: Dmitry Baryshkov Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534230/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-13-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 60 ++-------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 47 +++++++++++++++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 25 ++------- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 ++ 4 files changed, 57 insertions(+), 79 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 74470d068622..a60fb8d3736b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -36,10 +36,6 @@ #define DEFAULT_TEARCHECK_SYNC_THRESH_START 4 #define DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE 4 -#define DPU_ENC_WR_PTR_START_TIMEOUT_US 20000 - -#define DPU_ENC_MAX_POLL_TIMEOUT_US 2000 - static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc); static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc) @@ -574,28 +570,8 @@ static void dpu_encoder_phys_cmd_prepare_for_kickoff( atomic_read(&phys_enc->pending_kickoff_cnt)); } -static bool dpu_encoder_phys_cmd_is_ongoing_pptx( - struct dpu_encoder_phys *phys_enc) -{ - struct dpu_hw_pp_vsync_info info; - - if (!phys_enc) - return false; - - phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info); - if (info.wr_ptr_line_count > 0 && - info.wr_ptr_line_count < phys_enc->cached_mode.vdisplay) - return true; - - return false; -} - static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc) { - struct dpu_encoder_phys_cmd *cmd_enc = - to_dpu_encoder_phys_cmd(phys_enc); - int trial = 0; - if (!phys_enc) return; if (!phys_enc->hw_pp) @@ -603,37 +579,11 @@ static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc) if (!dpu_encoder_phys_cmd_is_master(phys_enc)) return; - /* If autorefresh is already disabled, we have nothing to do */ - if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL)) - return; - - /* - * If autorefresh is enabled, disable it and make sure it is safe to - * proceed with current frame commit/push. Sequence fallowed is, - * 1. Disable TE - * 2. Disable autorefresh config - * 4. Poll for frame transfer ongoing to be false - * 5. Enable TE back - */ - _dpu_encoder_phys_cmd_connect_te(phys_enc, false); - phys_enc->hw_pp->ops.setup_autorefresh(phys_enc->hw_pp, 0, false); - - do { - udelay(DPU_ENC_MAX_POLL_TIMEOUT_US); - if ((trial * DPU_ENC_MAX_POLL_TIMEOUT_US) - > (KICKOFF_TIMEOUT_MS * USEC_PER_MSEC)) { - DPU_ERROR_CMDENC(cmd_enc, - "disable autorefresh failed\n"); - break; - } - - trial++; - } while (dpu_encoder_phys_cmd_is_ongoing_pptx(phys_enc)); - - _dpu_encoder_phys_cmd_connect_te(phys_enc, true); - - DPU_DEBUG_CMDENC(to_dpu_encoder_phys_cmd(phys_enc), - "disabled autorefresh\n"); + if (phys_enc->hw_pp->ops.disable_autorefresh) { + phys_enc->hw_pp->ops.disable_autorefresh(phys_enc->hw_pp, + DRMID(phys_enc->parent), + phys_enc->cached_mode.vdisplay); + } } static int _dpu_encoder_phys_cmd_wait_for_ctl_start( diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index 1dcbb75b80d3..e366d752bd07 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -210,6 +210,49 @@ static u32 dpu_hw_pp_get_line_count(struct dpu_hw_pingpong *pp) return line; } +static void dpu_hw_pp_disable_autorefresh(struct dpu_hw_pingpong *pp, + uint32_t encoder_id, u16 vdisplay) +{ + struct dpu_hw_pp_vsync_info info; + int trial = 0; + + /* If autorefresh is already disabled, we have nothing to do */ + if (!dpu_hw_pp_get_autorefresh_config(pp, NULL)) + return; + + /* + * If autorefresh is enabled, disable it and make sure it is safe to + * proceed with current frame commit/push. Sequence followed is, + * 1. Disable TE + * 2. Disable autorefresh config + * 4. Poll for frame transfer ongoing to be false + * 5. Enable TE back + */ + + dpu_hw_pp_connect_external_te(pp, false); + dpu_hw_pp_setup_autorefresh_config(pp, 0, false); + + do { + udelay(DPU_ENC_MAX_POLL_TIMEOUT_US); + if ((trial * DPU_ENC_MAX_POLL_TIMEOUT_US) + > (KICKOFF_TIMEOUT_MS * USEC_PER_MSEC)) { + DPU_ERROR("enc%d pp%d disable autorefresh failed\n", + encoder_id, pp->idx - PINGPONG_0); + break; + } + + trial++; + + dpu_hw_pp_get_vsync_info(pp, &info); + } while (info.wr_ptr_line_count > 0 && + info.wr_ptr_line_count < vdisplay); + + dpu_hw_pp_connect_external_te(pp, true); + + DPU_DEBUG("enc%d pp%d disabled autorefresh\n", + encoder_id, pp->idx - PINGPONG_0); +} + static int dpu_hw_pp_dsc_enable(struct dpu_hw_pingpong *pp) { struct dpu_hw_blk_reg_map *c = &pp->hw; @@ -242,10 +285,8 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config; c->ops.enable_tearcheck = dpu_hw_pp_enable_te; c->ops.connect_external_te = dpu_hw_pp_connect_external_te; - c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info; - c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config; - c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config; c->ops.get_line_count = dpu_hw_pp_get_line_count; + c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; c->ops.setup_dsc = dpu_hw_pp_setup_dsc; c->ops.enable_dsc = dpu_hw_pp_dsc_enable; c->ops.disable_dsc = dpu_hw_pp_dsc_disable; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h index 42af9e5b865e..336d383f8b64 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h @@ -61,9 +61,6 @@ struct dpu_hw_dither_cfg { * Assumption is these functions will be called after clocks are enabled * @setup_tearcheck : program tear check values * @enable_tearcheck : enables tear check - * @get_vsync_info : retries timing info of the panel - * @setup_autorefresh : configure and enable the autorefresh config - * @get_autorefresh : retrieve autorefresh config from hardware * @setup_dither : function to program the dither hw block * @get_line_count: obtain current vertical line counter */ @@ -89,28 +86,14 @@ struct dpu_hw_pingpong_ops { bool enable_external_te); /** - * provides the programmed and current - * line_count - */ - int (*get_vsync_info)(struct dpu_hw_pingpong *pp, - struct dpu_hw_pp_vsync_info *info); - - /** - * configure and enable the autorefresh config - */ - void (*setup_autorefresh)(struct dpu_hw_pingpong *pp, - u32 frame_count, bool enable); - - /** - * retrieve autorefresh config from hardware + * Obtain current vertical line counter */ - bool (*get_autorefresh)(struct dpu_hw_pingpong *pp, - u32 *frame_count); + u32 (*get_line_count)(struct dpu_hw_pingpong *pp); /** - * Obtain current vertical line counter + * Disable autorefresh if enabled */ - u32 (*get_line_count)(struct dpu_hw_pingpong *pp); + void (*disable_autorefresh)(struct dpu_hw_pingpong *pp, uint32_t encoder_id, u16 vdisplay); /** * Setup dither matix for pingpong block diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 15111e433f21..cd6287524557 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -118,6 +118,10 @@ struct vsync_info { u32 line_count; }; +#define DPU_ENC_WR_PTR_START_TIMEOUT_US 20000 + +#define DPU_ENC_MAX_POLL_TIMEOUT_US 2000 + #define to_dpu_kms(x) container_of(x, struct dpu_kms, base) #define to_dpu_global_state(x) container_of(x, struct dpu_global_state, base) -- cgit v1.2.3 From fe9d66cf6e8d2f6651e55ae57026464a080c2f2a Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:28 +0200 Subject: drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above Since hardware revision 5.0.0 the TE configuration moved out of the PINGPONG block into the INTF block. Writing these registers has no effect, and is omitted downstream via the DPU/SDE_PINGPONG_TE feature flag. This flag is only added to PINGPONG blocks used by hardware prior to 5.0.0. The existing PP_BLK_TE macro has been removed in favour of directly passing this feature flag, which has thus far been the only difference with PP_BLK. PP_BLK_DITHER has been left in place as its embedded feature flag already excludes this DPU_PINGPONG_TE bit and differs by setting the block length to zero, as it only contains a DITHER subblock. The code that writes to these registers in the INTF block will follow in subsequent patches. Signed-off-by: Marijn Suijten Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534240/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-14-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 8 ++++---- .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 ++++---- .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 12 ++++++------ .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 12 ++++++------ .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 12 ++++++------ .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +- .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 22 ++++++++-------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 12 +++++++----- 10 files changed, 45 insertions(+), 49 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 886aaf4b213a..3d01840ef64b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg msm8998_lm[] = { }; static const struct dpu_pingpong_cfg msm8998_pp[] = { - PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te, + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), - PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), - PP_BLK("pingpong_2", PINGPONG_2, 0x71000, 0, sdm845_pp_sblk, + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), - PP_BLK("pingpong_3", PINGPONG_3, 0x71800, 0, sdm845_pp_sblk, + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 63009435e258..84159f8cbdae 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[] = { }; static const struct dpu_pingpong_cfg sdm845_pp[] = { - PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te, + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), - PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), - PP_BLK("pingpong_2", PINGPONG_2, 0x71000, 0, sdm845_pp_sblk, + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), - PP_BLK("pingpong_3", PINGPONG_3, 0x71800, 0, sdm845_pp_sblk, + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index b3f67710a48d..266c525f8daa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -128,22 +128,22 @@ static const struct dpu_dspp_cfg sm8150_dspp[] = { }; static const struct dpu_pingpong_cfg sm8150_pp[] = { - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk, + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk, + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), - PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk, + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), - PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk, + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), - PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk, + PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1), - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk, + PP_BLK("pingpong_5", PINGPONG_5, 0x72800, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index 1aef11a25834..b05bd561e140 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -127,22 +127,22 @@ static const struct dpu_dspp_cfg sc8180x_dspp[] = { }; static const struct dpu_pingpong_cfg sc8180x_pp[] = { - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk, + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk, + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), - PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk, + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), - PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk, + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), - PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk, + PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1), - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk, + PP_BLK("pingpong_5", PINGPONG_5, 0x72800, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index 903efc580aef..8660d04d0f58 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -129,22 +129,22 @@ static const struct dpu_dspp_cfg sm8250_dspp[] = { }; static const struct dpu_pingpong_cfg sm8250_pp[] = { - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk, + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk, + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), - PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk, + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), - PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk, + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), - PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk, + PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1), - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk, + PP_BLK("pingpong_5", PINGPONG_5, 0x72800, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 911479cb1675..63056439d412 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = { }; static const struct dpu_pingpong_cfg sc7180_pp[] = { - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk, -1, -1), - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk, -1, -1), + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, -1, -1), + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, -1, -1), }; static const struct dpu_intf_cfg sc7180_intf[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h index 988d820f7ef2..e15dc96f1286 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = { }; static const struct dpu_pingpong_cfg sm6115_pp[] = { - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk, + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h index c9003dcc1a59..2ff98ef6999f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[] = { }; static const struct dpu_pingpong_cfg qcm2290_pp[] = { - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk, + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index da758510fbfe..fad12ba0eab6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -75,11 +75,15 @@ #define MIXER_QCM2290_MASK \ (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) -#define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER) +#define PINGPONG_SDM845_MASK \ + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE)) -#define PINGPONG_SDM845_SPLIT_MASK \ +#define PINGPONG_SDM845_TE2_MASK \ (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) +#define PINGPONG_SM8150_MASK \ + (BIT(DPU_PINGPONG_DITHER)) + #define CTL_SC7280_MASK \ (BIT(DPU_CTL_ACTIVE_CFG) | \ BIT(DPU_CTL_FETCH_ACTIVE) | \ @@ -492,21 +496,11 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { .intr_done = _done, \ .intr_rdptr = _rdptr, \ } -#define PP_BLK_TE(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \ - {\ - .name = _name, .id = _id, \ - .base = _base, .len = 0xd4, \ - .features = PINGPONG_SDM845_SPLIT_MASK, \ - .merge_3d = _merge_3d, \ - .sblk = &_sblk, \ - .intr_done = _done, \ - .intr_rdptr = _rdptr, \ - } -#define PP_BLK(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \ +#define PP_BLK(_name, _id, _base, _features, _merge_3d, _sblk, _done, _rdptr) \ {\ .name = _name, .id = _id, \ .base = _base, .len = 0xd4, \ - .features = PINGPONG_SDM845_MASK, \ + .features = _features, \ .merge_3d = _merge_3d, \ .sblk = &_sblk, \ .intr_done = _done, \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index e366d752bd07..c70f6ff018f2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -282,11 +282,13 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp) static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, unsigned long features) { - c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config; - c->ops.enable_tearcheck = dpu_hw_pp_enable_te; - c->ops.connect_external_te = dpu_hw_pp_connect_external_te; - c->ops.get_line_count = dpu_hw_pp_get_line_count; - c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; + if (test_bit(DPU_PINGPONG_TE, &features)) { + c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config; + c->ops.enable_tearcheck = dpu_hw_pp_enable_te; + c->ops.connect_external_te = dpu_hw_pp_connect_external_te; + c->ops.get_line_count = dpu_hw_pp_get_line_count; + c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; + } c->ops.setup_dsc = dpu_hw_pp_setup_dsc; c->ops.enable_dsc = dpu_hw_pp_dsc_enable; c->ops.disable_dsc = dpu_hw_pp_dsc_disable; -- cgit v1.2.3 From a2ff096803b30de95c6428ade638726ee3897b8e Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:29 +0200 Subject: drm/msm/dpu: Disable MDP vsync source selection on DPU 5.0.0 and above Since hardware revision 5.0.0 the TE configuration moved out of the PINGPONG block into the INTF block, including vsync source selection that was previously part of MDP top. Writing to the MDP_VSYNC_SEL register has no effect anymore and is omitted downstream via the DPU/SDE_MDP_VSYNC_SEL feature flag. This flag is only added to INTF blocks used by hardware prior to 5.0.0. The code that writes to these registers in the INTF block will follow in subsequent patches. Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534220/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-15-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 2 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 3 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 50 +++++++++++++++------- 4 files changed, 40 insertions(+), 17 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 3d01840ef64b..dc2c8972afd7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -30,7 +30,7 @@ static const struct dpu_mdp_cfg msm8998_mdp[] = { { .name = "top_0", .id = MDP_TOP, .base = 0x0, .len = 0x458, - .features = 0, + .features = BIT(DPU_MDP_VSYNC_SEL), .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 84159f8cbdae..41e4c1e362d3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -30,7 +30,7 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = { { .name = "top_0", .id = MDP_TOP, .base = 0x0, .len = 0x45c, - .features = BIT(DPU_MDP_AUDIO_SELECT), + .features = BIT(DPU_MDP_AUDIO_SELECT) | BIT(DPU_MDP_VSYNC_SEL), .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, .clk_ctrls[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, .clk_ctrls[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, 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 c6eb5a8a66da..917272fa7f80 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -48,6 +48,8 @@ enum { * @DPU_MDP_UBWC_1_5, Universal Bandwidth compression version 1.5 * @DPU_MDP_PERIPH_0_REMOVED Indicates that access to periph top0 block results * in a failure + * @DPU_MDP_VSYNC_SEL Enables vsync source selection via MDP_VSYNC_SEL register + * (moved into INTF block since DPU 5.0.0) * @DPU_MDP_MAX Maximum value */ @@ -59,6 +61,7 @@ enum { DPU_MDP_UBWC_1_5, DPU_MDP_AUDIO_SELECT, DPU_MDP_PERIPH_0_REMOVED, + DPU_MDP_VSYNC_SEL, DPU_MDP_MAX }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index 2bb02e17ee52..963bdb5e0252 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -130,24 +130,12 @@ static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp, struct dpu_vsync_source_cfg *cfg) { struct dpu_hw_blk_reg_map *c; - u32 reg, wd_load_value, wd_ctl, wd_ctl2, i; - static const u32 pp_offset[PINGPONG_MAX] = {0xC, 0x8, 0x4, 0x13, 0x18}; + u32 reg, wd_load_value, wd_ctl, wd_ctl2; - if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber))) + if (!mdp || !cfg) return; c = &mdp->hw; - reg = DPU_REG_READ(c, MDP_VSYNC_SEL); - for (i = 0; i < cfg->pp_count; i++) { - int pp_idx = cfg->ppnumber[i] - PINGPONG_0; - - if (pp_idx >= ARRAY_SIZE(pp_offset)) - continue; - - reg &= ~(0xf << pp_offset[pp_idx]); - reg |= (cfg->vsync_source & 0xf) << pp_offset[pp_idx]; - } - DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg); if (cfg->vsync_source >= DPU_VSYNC_SOURCE_WD_TIMER_4 && cfg->vsync_source <= DPU_VSYNC_SOURCE_WD_TIMER_0) { @@ -194,6 +182,33 @@ static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp, } } +static void dpu_hw_setup_vsync_source_and_vsync_sel(struct dpu_hw_mdp *mdp, + struct dpu_vsync_source_cfg *cfg) +{ + struct dpu_hw_blk_reg_map *c; + u32 reg, i; + static const u32 pp_offset[PINGPONG_MAX] = {0xC, 0x8, 0x4, 0x13, 0x18}; + + if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber))) + return; + + c = &mdp->hw; + + reg = DPU_REG_READ(c, MDP_VSYNC_SEL); + for (i = 0; i < cfg->pp_count; i++) { + int pp_idx = cfg->ppnumber[i] - PINGPONG_0; + + if (pp_idx >= ARRAY_SIZE(pp_offset)) + continue; + + reg &= ~(0xf << pp_offset[pp_idx]); + reg |= (cfg->vsync_source & 0xf) << pp_offset[pp_idx]; + } + DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg); + + dpu_hw_setup_vsync_source(mdp, cfg); +} + static void dpu_hw_get_safe_status(struct dpu_hw_mdp *mdp, struct dpu_danger_safe_status *status) { @@ -241,7 +256,12 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, ops->setup_split_pipe = dpu_hw_setup_split_pipe; ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl; ops->get_danger_status = dpu_hw_get_danger_status; - ops->setup_vsync_source = dpu_hw_setup_vsync_source; + + if (cap & BIT(DPU_MDP_VSYNC_SEL)) + ops->setup_vsync_source = dpu_hw_setup_vsync_source_and_vsync_sel; + else + ops->setup_vsync_source = dpu_hw_setup_vsync_source; + ops->get_safe_status = dpu_hw_get_safe_status; if (cap & BIT(DPU_MDP_AUDIO_SELECT)) -- cgit v1.2.3 From c31ec42ebb45aaa4f668037525b8df140563ca6a Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Thu, 27 Apr 2023 00:37:30 +0200 Subject: drm/msm/dpu: Move dpu_hw_{tear_check, pp_vsync_info} to dpu_hw_mdss.h Now that newer SoCs since DPU 5.0.0 manage tearcheck in the INTF instead of PINGPONG block, move the struct definition to a common file. Also, bring in documentation from msm-4.19 techpack while at it. Signed-off-by: Konrad Dybcio [Marijn: Also move dpu_hw_pp_vsync_info] Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534232/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-16-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 46 +++++++++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 22 ------------ 2 files changed, 46 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 2d9192a6ce00..6ed12fd0505b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -463,4 +463,50 @@ struct dpu_mdss_color { #define DPU_DBG_MASK_DSPP (1 << 10) #define DPU_DBG_MASK_DSC (1 << 11) +/** + * struct dpu_hw_tear_check - Struct contains parameters to configure + * tear-effect module. This structure is used to configure tear-check + * logic present either in ping-pong or in interface module. + * @vsync_count: Ratio of MDP VSYNC clk freq(Hz) to refresh rate divided + * by no of lines + * @sync_cfg_height: Total vertical lines (display height - 1) + * @vsync_init_val: Init value to which the read pointer gets loaded at + * vsync edge + * @sync_threshold_start: Read pointer threshold start ROI for write operation + * @sync_threshold_continue: The minimum number of lines the write pointer + * needs to be above the read pointer + * @start_pos: The position from which the start_threshold value is added + * @rd_ptr_irq: The read pointer line at which interrupt has to be generated + * @hw_vsync_mode: Sync with external frame sync input + */ +struct dpu_hw_tear_check { + /* + * This is ratio of MDP VSYNC clk freq(Hz) to + * refresh rate divided by no of lines + */ + u32 vsync_count; + u32 sync_cfg_height; + u32 vsync_init_val; + u32 sync_threshold_start; + u32 sync_threshold_continue; + u32 start_pos; + u32 rd_ptr_irq; + u8 hw_vsync_mode; +}; + +/** + * struct dpu_hw_pp_vsync_info - Struct contains parameters to configure + * read and write pointers for command mode panels + * @rd_ptr_init_val: Value of rd pointer at vsync edge + * @rd_ptr_frame_count: Num frames sent since enabling interface + * @rd_ptr_line_count: Current line on panel (rd ptr) + * @wr_ptr_line_count: Current line within pp fifo (wr ptr) + */ +struct dpu_hw_pp_vsync_info { + u32 rd_ptr_init_val; + u32 rd_ptr_frame_count; + u32 rd_ptr_line_count; + u32 wr_ptr_line_count; +}; + #endif /* _DPU_HW_MDSS_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h index 336d383f8b64..08ba9d76f061 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h @@ -13,28 +13,6 @@ struct dpu_hw_pingpong; -struct dpu_hw_tear_check { - /* - * This is ratio of MDP VSYNC clk freq(Hz) to - * refresh rate divided by no of lines - */ - u32 vsync_count; - u32 sync_cfg_height; - u32 vsync_init_val; - u32 sync_threshold_start; - u32 sync_threshold_continue; - u32 start_pos; - u32 rd_ptr_irq; - u8 hw_vsync_mode; -}; - -struct dpu_hw_pp_vsync_info { - u32 rd_ptr_init_val; /* value of rd pointer at vsync edge */ - u32 rd_ptr_frame_count; /* num frames sent since enabling interface */ - u32 rd_ptr_line_count; /* current line on panel (rd ptr) */ - u32 wr_ptr_line_count; /* current line within pp fifo (wr ptr) */ -}; - /** * struct dpu_hw_dither_cfg - dither feature structure * @flags: for customizing operations -- cgit v1.2.3 From a38a9949a96399ecbe213837b2341babe3262423 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:31 +0200 Subject: drm/msm/dpu: Factor out shared interrupt register in INTF_BLK macro As the INTF block is going to attain more interrupts that don't share the same MDP_SSPP_TOP0_INTR register, factor out the _reg argument for the caller to construct the right interrupt index (register and bit index) to not make the interrupt bit arguments depend on one of multiple interrupt register indices. This brings us more in line with how PP_BLK specifies its interrupts and allows for better wrapping in the arrays. Signed-off-by: Marijn Suijten Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534222/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-17-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 16 +++++++--- .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 16 +++++++--- .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 16 +++++++--- .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 24 +++++++++++---- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 16 +++++++--- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 8 +++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 6 ++-- .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 6 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 16 +++++++--- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 12 ++++++-- .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 36 ++++++++++++++++------ .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 16 +++++++--- .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 16 +++++++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 6 ++-- 14 files changed, 155 insertions(+), 55 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index dc2c8972afd7..37a52b4ef8d3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -134,10 +134,18 @@ static const struct dpu_dspp_cfg msm8998_dspp[] = { }; static const struct dpu_intf_cfg msm8998_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 21, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x280, INTF_DSI, 0, 21, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x280, INTF_DSI, 1, 21, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_HDMI, 0, 21, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 21, INTF_SDM845_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x280, INTF_DSI, 0, 21, INTF_SDM845_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_2", INTF_2, 0x6b000, 0x280, INTF_DSI, 1, 21, INTF_SDM845_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_HDMI, 0, 21, INTF_SDM845_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), }; static const struct dpu_perf_cfg msm8998_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 41e4c1e362d3..0b727252671c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -132,10 +132,18 @@ static const struct dpu_dsc_cfg sdm845_dsc[] = { }; static const struct dpu_intf_cfg sdm845_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x280, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x280, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SDM845_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x280, INTF_DSI, 0, 24, INTF_SDM845_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_2", INTF_2, 0x6b000, 0x280, INTF_DSI, 1, 24, INTF_SDM845_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SDM845_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), }; static const struct dpu_perf_cfg sdm845_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 266c525f8daa..9089fededd89 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -162,10 +162,18 @@ static const struct dpu_dsc_cfg sm8150_dsc[] = { }; static const struct dpu_intf_cfg sm8150_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), }; static const struct dpu_perf_cfg sm8150_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index b05bd561e140..aab355c78970 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -163,13 +163,25 @@ static const struct dpu_dsc_cfg sc8180x_dsc[] = { }; static const struct dpu_intf_cfg sc8180x_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29), + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is supported */ - INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31), - INTF_BLK("intf_4", INTF_4, 0x6c000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21), - INTF_BLK("intf_5", INTF_5, 0x6c800, 0x280, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23), + INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 999, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), + INTF_BLK("intf_4", INTF_4, 0x6c000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 20), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 21)), + INTF_BLK("intf_5", INTF_5, 0x6c800, 0x280, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 22), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 23)), }; static const struct dpu_perf_cfg sc8180x_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index 8660d04d0f58..63fd46f98727 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -163,10 +163,18 @@ static const struct dpu_dsc_cfg sm8250_dsc[] = { }; static const struct dpu_intf_cfg sm8250_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2c0, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2c0, INTF_DSI, 1, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), }; static const struct dpu_wb_cfg sm8250_wb[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 63056439d412..301287e05c82 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -85,8 +85,12 @@ static const struct dpu_pingpong_cfg sc7180_pp[] = { }; static const struct dpu_intf_cfg sc7180_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), }; static const struct dpu_wb_cfg sc7180_wb[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h index e15dc96f1286..88a0d6119ad5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -66,8 +66,10 @@ static const struct dpu_pingpong_cfg sm6115_pp[] = { }; static const struct dpu_intf_cfg sm6115_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0, 0), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), }; static const struct dpu_perf_cfg sm6115_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h index 2ff98ef6999f..cd6f4048f286 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h @@ -63,8 +63,10 @@ static const struct dpu_pingpong_cfg qcm2290_pp[] = { }; static const struct dpu_intf_cfg qcm2290_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0, 0), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), + INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0), + INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), }; static const struct dpu_perf_cfg qcm2290_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 9e8d6632a192..6117c9fbc73f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -154,10 +154,18 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = { }; static const struct dpu_intf_cfg sm8350_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x36000, 0x2c4, INTF_DSI, 1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_2", INTF_2, 0x36000, 0x2c4, INTF_DSI, 1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), }; static const struct dpu_perf_cfg sm8350_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index ec9047cd60fd..208c97e8d7e1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -100,9 +100,15 @@ static const struct dpu_wb_cfg sc7280_wb[] = { }; static const struct dpu_intf_cfg sc7280_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23), + INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 22), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 23)), }; static const struct dpu_perf_cfg sc7280_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 8e4d0bc4aa70..cf81133540dd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -144,15 +144,33 @@ static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] = { /* TODO: INTF 3, 8 and 7 are used for MST, marked as INTF_NONE for now */ static const struct dpu_intf_cfg sc8280xp_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_NONE, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 30, 31), - INTF_BLK("intf_4", INTF_4, 0x38000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 20, 21), - INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_3, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23), - INTF_BLK("intf_6", INTF_6, 0x3a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 16, 17), - INTF_BLK("intf_7", INTF_7, 0x3b000, 0x280, INTF_NONE, MSM_DP_CONTROLLER_2, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 18, 19), - INTF_BLK("intf_8", INTF_8, 0x3c000, 0x280, INTF_NONE, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 12, 13), + INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_NONE, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), + INTF_BLK("intf_4", INTF_4, 0x38000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 20), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 21)), + INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_3, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 22), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 23)), + INTF_BLK("intf_6", INTF_6, 0x3a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 16), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 17)), + INTF_BLK("intf_7", INTF_7, 0x3b000, 0x280, INTF_NONE, MSM_DP_CONTROLLER_2, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 18), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 19)), + INTF_BLK("intf_8", INTF_8, 0x3c000, 0x280, INTF_NONE, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), }; static const struct dpu_perf_cfg sc8280xp_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 014922ac03db..9a95386b7a94 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -162,10 +162,18 @@ static const struct dpu_merge_3d_cfg sm8450_merge_3d[] = { }; static const struct dpu_intf_cfg sm8450_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25), - INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), }; static const struct dpu_perf_cfg sm8450_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index be2f37728aa0..cf366be79b1c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -166,11 +166,19 @@ static const struct dpu_merge_3d_cfg sm8550_merge_3d[] = { }; static const struct dpu_intf_cfg sm8550_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25), + INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), /* TODO TE sub-blocks for intf1 & intf2 */ - INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27), - INTF_BLK("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 28, 29), - INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 30, 31), + INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + INTF_BLK("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), }; static const struct dpu_perf_cfg sm8550_perf_data = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index fad12ba0eab6..f2482e500a1b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -531,7 +531,7 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { /************************************************************* * INTF sub blocks config *************************************************************/ -#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit) \ +#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, _progfetch, _features, _underrun, _vsync) \ {\ .name = _name, .id = _id, \ .base = _base, .len = _len, \ @@ -539,8 +539,8 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { .type = _type, \ .controller_id = _ctrl_id, \ .prog_fetch_lines_worst_case = _progfetch, \ - .intr_underrun = DPU_IRQ_IDX(_reg, _underrun_bit), \ - .intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \ + .intr_underrun = _underrun, \ + .intr_vsync = _vsync, \ } /************************************************************* -- cgit v1.2.3 From ec6e9b673ad56d019716298c15901d3a46e65c77 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:32 +0200 Subject: drm/msm/dpu: Describe TEAR interrupt registers for DSI interfaces All SoCs since DPU 5.0.0 have the tear interrupt registers moved out of the PINGPONG block and into the INTF block. Wire up the IRQ register masks in the interrupt table for enabling, reading and clearing them. Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534244/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-18-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 28 +++++++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 4 ++++ 2 files changed, 32 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index 152d4272a087..5e2d68ebb113 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -21,6 +21,10 @@ #define MDP_INTF_INTR_EN(intf) (MDP_INTF_OFF(intf) + 0x1c0) #define MDP_INTF_INTR_STATUS(intf) (MDP_INTF_OFF(intf) + 0x1c4) #define MDP_INTF_INTR_CLEAR(intf) (MDP_INTF_OFF(intf) + 0x1c8) +#define MDP_INTF_TEAR_OFF(intf) (0x6D700 + 0x100 * (intf)) +#define MDP_INTF_INTR_TEAR_EN(intf) (MDP_INTF_TEAR_OFF(intf) + 0x000) +#define MDP_INTF_INTR_TEAR_STATUS(intf) (MDP_INTF_TEAR_OFF(intf) + 0x004) +#define MDP_INTF_INTR_TEAR_CLEAR(intf) (MDP_INTF_TEAR_OFF(intf) + 0x008) #define MDP_AD4_OFF(ad4) (0x7C000 + 0x1000 * (ad4)) #define MDP_AD4_INTR_EN_OFF(ad4) (MDP_AD4_OFF(ad4) + 0x41c) #define MDP_AD4_INTR_CLEAR_OFF(ad4) (MDP_AD4_OFF(ad4) + 0x424) @@ -29,6 +33,10 @@ #define MDP_INTF_REV_7xxx_INTR_EN(intf) (MDP_INTF_REV_7xxx_OFF(intf) + 0x1c0) #define MDP_INTF_REV_7xxx_INTR_STATUS(intf) (MDP_INTF_REV_7xxx_OFF(intf) + 0x1c4) #define MDP_INTF_REV_7xxx_INTR_CLEAR(intf) (MDP_INTF_REV_7xxx_OFF(intf) + 0x1c8) +#define MDP_INTF_REV_7xxx_TEAR_OFF(intf) (0x34800 + 0x1000 * (intf)) +#define MDP_INTF_REV_7xxx_INTR_TEAR_EN(intf) (MDP_INTF_REV_7xxx_TEAR_OFF(intf) + 0x000) +#define MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(intf) (MDP_INTF_REV_7xxx_TEAR_OFF(intf) + 0x004) +#define MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(intf) (MDP_INTF_REV_7xxx_TEAR_OFF(intf) + 0x008) /** * struct dpu_intr_reg - array of DPU register sets @@ -93,6 +101,16 @@ static const struct dpu_intr_reg dpu_intr_set[] = { MDP_INTF_INTR_EN(5), MDP_INTF_INTR_STATUS(5) }, + [MDP_INTF1_TEAR_INTR] = { + MDP_INTF_INTR_TEAR_CLEAR(1), + MDP_INTF_INTR_TEAR_EN(1), + MDP_INTF_INTR_TEAR_STATUS(1) + }, + [MDP_INTF2_TEAR_INTR] = { + MDP_INTF_INTR_TEAR_CLEAR(2), + MDP_INTF_INTR_TEAR_EN(2), + MDP_INTF_INTR_TEAR_STATUS(2) + }, [MDP_AD4_0_INTR] = { MDP_AD4_INTR_CLEAR_OFF(0), MDP_AD4_INTR_EN_OFF(0), @@ -113,11 +131,21 @@ static const struct dpu_intr_reg dpu_intr_set[] = { MDP_INTF_REV_7xxx_INTR_EN(1), MDP_INTF_REV_7xxx_INTR_STATUS(1) }, + [MDP_INTF1_7xxx_TEAR_INTR] = { + MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(1), + MDP_INTF_REV_7xxx_INTR_TEAR_EN(1), + MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(1) + }, [MDP_INTF2_7xxx_INTR] = { MDP_INTF_REV_7xxx_INTR_CLEAR(2), MDP_INTF_REV_7xxx_INTR_EN(2), MDP_INTF_REV_7xxx_INTR_STATUS(2) }, + [MDP_INTF2_7xxx_TEAR_INTR] = { + MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(2), + MDP_INTF_REV_7xxx_INTR_TEAR_EN(2), + MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(2) + }, [MDP_INTF3_7xxx_INTR] = { MDP_INTF_REV_7xxx_INTR_CLEAR(3), MDP_INTF_REV_7xxx_INTR_EN(3), diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h index bbf475a1cb45..1f2dabc54c22 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h @@ -23,11 +23,15 @@ enum dpu_hw_intr_reg { MDP_INTF3_INTR, MDP_INTF4_INTR, MDP_INTF5_INTR, + MDP_INTF1_TEAR_INTR, + MDP_INTF2_TEAR_INTR, MDP_AD4_0_INTR, MDP_AD4_1_INTR, MDP_INTF0_7xxx_INTR, MDP_INTF1_7xxx_INTR, + MDP_INTF1_7xxx_TEAR_INTR, MDP_INTF2_7xxx_INTR, + MDP_INTF2_7xxx_TEAR_INTR, MDP_INTF3_7xxx_INTR, MDP_INTF4_7xxx_INTR, MDP_INTF5_7xxx_INTR, -- cgit v1.2.3 From 0272b9c3b5729ba4170b15953747259dbcde5c88 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:33 +0200 Subject: drm/msm/dpu: Add TEAR-READ-pointer interrupt to INTF block All SoCs since DPU 5.0.0 have the tear interrupt registers moved out of the PINGPONG block and into the INTF block. The new interrupts are described in dpu_hw_interrupts.c, now wire them up in individual SoC catalog files by setting the intr_tear_rd_ptr to the IRQ index spcified in the offset table and enabling this set of DPU interrupts via the mdss_irqs bitmask. Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534236/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-19-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 12 ++++++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 12 ++++++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 12 ++++++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 8 +++++--- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 8 +++++--- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 8 +++++--- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 12 ++++++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 6 ++++-- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 12 ++++++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 12 ++++++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 13 ++++++++----- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 15 +++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++ 13 files changed, 92 insertions(+), 40 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 9089fededd89..561022b8dfd6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -165,12 +165,14 @@ static const struct dpu_intf_cfg sm8150_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), + INTF_BLK_DSI_TE("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), + DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2)), INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), @@ -234,7 +236,9 @@ const struct dpu_mdss_cfg dpu_sm8150_cfg = { BIT(MDP_SSPP_TOP0_HIST_INTR) | \ BIT(MDP_INTF0_INTR) | \ BIT(MDP_INTF1_INTR) | \ + BIT(MDP_INTF1_TEAR_INTR) | \ BIT(MDP_INTF2_INTR) | \ + BIT(MDP_INTF2_TEAR_INTR) | \ BIT(MDP_INTF3_INTR) | \ BIT(MDP_AD4_0_INTR) | \ BIT(MDP_AD4_1_INTR), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index aab355c78970..d1f306c89567 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -166,12 +166,14 @@ static const struct dpu_intf_cfg sc8180x_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), + INTF_BLK_DSI_TE("intf_2", INTF_2, 0x6b000, 0x2bc, INTF_DSI, 1, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), + DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2)), /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is supported */ INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 999, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), @@ -240,7 +242,9 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { BIT(MDP_SSPP_TOP0_HIST_INTR) | \ BIT(MDP_INTF0_INTR) | \ BIT(MDP_INTF1_INTR) | \ + BIT(MDP_INTF1_TEAR_INTR) | \ BIT(MDP_INTF2_INTR) | \ + BIT(MDP_INTF2_TEAR_INTR) | \ BIT(MDP_INTF3_INTR) | \ BIT(MDP_INTF4_INTR) | \ BIT(MDP_INTF5_INTR) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index 63fd46f98727..10d67db8423f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -166,12 +166,14 @@ static const struct dpu_intf_cfg sm8250_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), - INTF_BLK("intf_2", INTF_2, 0x6b000, 0x2c0, INTF_DSI, 1, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), + INTF_BLK_DSI_TE("intf_2", INTF_2, 0x6b000, 0x2c0, INTF_DSI, 1, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), + DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2)), INTF_BLK("intf_3", INTF_3, 0x6b800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), @@ -242,7 +244,9 @@ const struct dpu_mdss_cfg dpu_sm8250_cfg = { BIT(MDP_SSPP_TOP0_HIST_INTR) | \ BIT(MDP_INTF0_INTR) | \ BIT(MDP_INTF1_INTR) | \ + BIT(MDP_INTF1_TEAR_INTR) | \ BIT(MDP_INTF2_INTR) | \ + BIT(MDP_INTF2_TEAR_INTR) | \ BIT(MDP_INTF3_INTR) | \ BIT(MDP_INTF4_INTR), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 301287e05c82..0b05da2592c0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -88,9 +88,10 @@ static const struct dpu_intf_cfg sc7180_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), }; static const struct dpu_wb_cfg sc7180_wb[] = { @@ -152,7 +153,8 @@ const struct dpu_mdss_cfg dpu_sc7180_cfg = { BIT(MDP_SSPP_TOP0_INTR2) | \ BIT(MDP_SSPP_TOP0_HIST_INTR) | \ BIT(MDP_INTF0_INTR) | \ - BIT(MDP_INTF1_INTR), + BIT(MDP_INTF1_INTR) | \ + BIT(MDP_INTF1_TEAR_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h index 88a0d6119ad5..5509ceb5d55b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -67,9 +67,10 @@ static const struct dpu_pingpong_cfg sm6115_pp[] = { static const struct dpu_intf_cfg sm6115_intf[] = { INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), }; static const struct dpu_perf_cfg sm6115_perf_data = { @@ -124,7 +125,8 @@ const struct dpu_mdss_cfg dpu_sm6115_cfg = { .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ BIT(MDP_SSPP_TOP0_HIST_INTR) | \ - BIT(MDP_INTF1_INTR), + BIT(MDP_INTF1_INTR) | \ + BIT(MDP_INTF1_TEAR_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h index cd6f4048f286..22b8a173d214 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h @@ -64,9 +64,10 @@ static const struct dpu_pingpong_cfg qcm2290_pp[] = { static const struct dpu_intf_cfg qcm2290_intf[] = { INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0), - INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), }; static const struct dpu_perf_cfg qcm2290_perf_data = { @@ -114,7 +115,8 @@ const struct dpu_mdss_cfg dpu_qcm2290_cfg = { .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ BIT(MDP_SSPP_TOP0_INTR2) | \ BIT(MDP_SSPP_TOP0_HIST_INTR) | \ - BIT(MDP_INTF1_INTR), + BIT(MDP_INTF1_INTR) | \ + BIT(MDP_INTF1_TEAR_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 6117c9fbc73f..2dcfe18bc8c9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -157,12 +157,14 @@ static const struct dpu_intf_cfg sm8350_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), - INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), - INTF_BLK("intf_2", INTF_2, 0x36000, 0x2c4, INTF_DSI, 1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), + INTF_BLK_DSI_TE("intf_2", INTF_2, 0x36000, 0x2c4, INTF_DSI, 1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), + DPU_IRQ_IDX(MDP_INTF2_7xxx_TEAR_INTR, 2)), INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), @@ -225,7 +227,9 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { BIT(MDP_SSPP_TOP0_HIST_INTR) | \ BIT(MDP_INTF0_7xxx_INTR) | \ BIT(MDP_INTF1_7xxx_INTR) | \ + BIT(MDP_INTF1_7xxx_TEAR_INTR) | \ BIT(MDP_INTF2_7xxx_INTR) | \ + BIT(MDP_INTF2_7xxx_TEAR_INTR) | \ BIT(MDP_INTF3_7xxx_INTR), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 208c97e8d7e1..5d894cbb0a62 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -103,9 +103,10 @@ static const struct dpu_intf_cfg sc7280_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), - INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 22), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 23)), @@ -166,6 +167,7 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { BIT(MDP_SSPP_TOP0_HIST_INTR) | \ BIT(MDP_INTF0_7xxx_INTR) | \ BIT(MDP_INTF1_7xxx_INTR) | \ + BIT(MDP_INTF1_7xxx_TEAR_INTR) | \ BIT(MDP_INTF5_7xxx_INTR), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index cf81133540dd..c3f1ae000a21 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -147,12 +147,14 @@ static const struct dpu_intf_cfg sc8280xp_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), - INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), - INTF_BLK("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), + INTF_BLK_DSI_TE("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), + DPU_IRQ_IDX(MDP_INTF2_7xxx_TEAR_INTR, 2)), INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_NONE, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), @@ -227,7 +229,9 @@ const struct dpu_mdss_cfg dpu_sc8280xp_cfg = { BIT(MDP_SSPP_TOP0_HIST_INTR) | \ BIT(MDP_INTF0_7xxx_INTR) | \ BIT(MDP_INTF1_7xxx_INTR) | \ + BIT(MDP_INTF1_7xxx_TEAR_INTR) | \ BIT(MDP_INTF2_7xxx_INTR) | \ + BIT(MDP_INTF2_7xxx_TEAR_INTR) | \ BIT(MDP_INTF3_7xxx_INTR) | \ BIT(MDP_INTF4_7xxx_INTR) | \ BIT(MDP_INTF5_7xxx_INTR) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 9a95386b7a94..279fe8f4e1e3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -165,12 +165,14 @@ static const struct dpu_intf_cfg sm8450_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), - INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), - INTF_BLK("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), + INTF_BLK_DSI_TE("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), + DPU_IRQ_IDX(MDP_INTF2_7xxx_TEAR_INTR, 2)), INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), @@ -233,7 +235,9 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = { BIT(MDP_SSPP_TOP0_HIST_INTR) | \ BIT(MDP_INTF0_7xxx_INTR) | \ BIT(MDP_INTF1_7xxx_INTR) | \ + BIT(MDP_INTF1_7xxx_TEAR_INTR) | \ BIT(MDP_INTF2_7xxx_INTR) | \ + BIT(MDP_INTF2_7xxx_TEAR_INTR) | \ BIT(MDP_INTF3_7xxx_INTR), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index cf366be79b1c..85dc34458b88 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -169,13 +169,14 @@ static const struct dpu_intf_cfg sm8550_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), - /* TODO TE sub-blocks for intf1 & intf2 */ - INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27)), - INTF_BLK("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), + INTF_BLK_DSI_TE("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29)), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), + DPU_IRQ_IDX(MDP_INTF2_7xxx_TEAR_INTR, 2)), INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), @@ -238,7 +239,9 @@ const struct dpu_mdss_cfg dpu_sm8550_cfg = { BIT(MDP_SSPP_TOP0_HIST_INTR) | \ BIT(MDP_INTF0_7xxx_INTR) | \ BIT(MDP_INTF1_7xxx_INTR) | \ + BIT(MDP_INTF1_7xxx_TEAR_INTR) | \ BIT(MDP_INTF2_7xxx_INTR) | \ + BIT(MDP_INTF2_7xxx_TEAR_INTR) | \ BIT(MDP_INTF3_7xxx_INTR), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index f2482e500a1b..81b44a394f03 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -541,6 +541,21 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { .prog_fetch_lines_worst_case = _progfetch, \ .intr_underrun = _underrun, \ .intr_vsync = _vsync, \ + .intr_tear_rd_ptr = -1, \ + } + +/* DSI Interface sub-block with TEAR registers (since DPU 5.0.0) */ +#define INTF_BLK_DSI_TE(_name, _id, _base, _len, _type, _ctrl_id, _progfetch, _features, _underrun, _vsync, _tear_rd_ptr) \ + {\ + .name = _name, .id = _id, \ + .base = _base, .len = _len, \ + .features = _features, \ + .type = _type, \ + .controller_id = _ctrl_id, \ + .prog_fetch_lines_worst_case = _progfetch, \ + .intr_underrun = _underrun, \ + .intr_vsync = _vsync, \ + .intr_tear_rd_ptr = _tear_rd_ptr, \ } /************************************************************* 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 917272fa7f80..a2ef61d4f7fa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -615,6 +615,7 @@ struct dpu_dsc_cfg { * @prog_fetch_lines_worst_case Worst case latency num lines needed to prefetch * @intr_underrun: index for INTF underrun interrupt * @intr_vsync: index for INTF VSYNC interrupt + * @intr_tear_rd_ptr: Index for INTF TEAR_RD_PTR interrupt */ struct dpu_intf_cfg { DPU_HW_BLK_INFO; @@ -623,6 +624,7 @@ struct dpu_intf_cfg { u32 prog_fetch_lines_worst_case; s32 intr_underrun; s32 intr_vsync; + s32 intr_tear_rd_ptr; }; /** -- cgit v1.2.3 From bb9f1880ca902114569e17887626ee80c759a47c Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:34 +0200 Subject: drm/msm/dpu: Merge setup_- and enable_tearcheck pingpong callbacks These functions are always called consecutively and are best bundled together for simplicity, especially when the same structure of callbacks will be replicated later on the interface block for INTF TE support. The enable_tearcheck(false) case is now replaced with a more obvious disable_tearcheck(), encapsulating the original register write with 0. Suggested-by: Dmitry Baryshkov Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534217/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-20-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 10 ++++------ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 10 ++++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 11 +++++------ 3 files changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index a60fb8d3736b..1df3745224f5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -327,8 +327,7 @@ static void dpu_encoder_phys_cmd_tearcheck_config( DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0); - if (!phys_enc->hw_pp->ops.setup_tearcheck || - !phys_enc->hw_pp->ops.enable_tearcheck) { + if (!phys_enc->hw_pp->ops.enable_tearcheck) { DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); return; } @@ -383,8 +382,7 @@ static void dpu_encoder_phys_cmd_tearcheck_config( phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.sync_cfg_height, tc_cfg.sync_threshold_start, tc_cfg.sync_threshold_continue); - phys_enc->hw_pp->ops.setup_tearcheck(phys_enc->hw_pp, &tc_cfg); - phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, tc_enable); + phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, &tc_cfg); } static void _dpu_encoder_phys_cmd_pingpong_config( @@ -511,8 +509,8 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc) return; } - if (phys_enc->hw_pp->ops.enable_tearcheck) - phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, false); + if (phys_enc->hw_pp->ops.disable_tearcheck) + phys_enc->hw_pp->ops.disable_tearcheck(phys_enc->hw_pp); if (phys_enc->hw_intf->ops.bind_pingpong_blk) { phys_enc->hw_intf->ops.bind_pingpong_blk( diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index c70f6ff018f2..79e45768eae5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -73,7 +73,7 @@ static void dpu_hw_pp_setup_dither(struct dpu_hw_pingpong *pp, DPU_REG_WRITE(c, base + PP_DITHER_EN, 1); } -static int dpu_hw_pp_setup_te_config(struct dpu_hw_pingpong *pp, +static int dpu_hw_pp_enable_te(struct dpu_hw_pingpong *pp, struct dpu_hw_tear_check *te) { struct dpu_hw_blk_reg_map *c; @@ -100,6 +100,8 @@ static int dpu_hw_pp_setup_te_config(struct dpu_hw_pingpong *pp, DPU_REG_WRITE(c, PP_SYNC_WRCOUNT, (te->start_pos + te->sync_threshold_start + 1)); + DPU_REG_WRITE(c, PP_TEAR_CHECK_EN, 1); + return 0; } @@ -126,7 +128,7 @@ static bool dpu_hw_pp_get_autorefresh_config(struct dpu_hw_pingpong *pp, return !!((val & BIT(31)) >> 31); } -static int dpu_hw_pp_enable_te(struct dpu_hw_pingpong *pp, bool enable) +static int dpu_hw_pp_disable_te(struct dpu_hw_pingpong *pp) { struct dpu_hw_blk_reg_map *c; @@ -134,7 +136,7 @@ static int dpu_hw_pp_enable_te(struct dpu_hw_pingpong *pp, bool enable) return -EINVAL; c = &pp->hw; - DPU_REG_WRITE(c, PP_TEAR_CHECK_EN, enable); + DPU_REG_WRITE(c, PP_TEAR_CHECK_EN, 0); return 0; } @@ -283,8 +285,8 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, unsigned long features) { if (test_bit(DPU_PINGPONG_TE, &features)) { - c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config; c->ops.enable_tearcheck = dpu_hw_pp_enable_te; + c->ops.disable_tearcheck = dpu_hw_pp_disable_te; c->ops.connect_external_te = dpu_hw_pp_connect_external_te; c->ops.get_line_count = dpu_hw_pp_get_line_count; c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h index 08ba9d76f061..d3246a9a5808 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h @@ -37,8 +37,8 @@ struct dpu_hw_dither_cfg { * * struct dpu_hw_pingpong_ops : Interface to the pingpong Hw driver functions * Assumption is these functions will be called after clocks are enabled - * @setup_tearcheck : program tear check values - * @enable_tearcheck : enables tear check + * @enable_tearcheck: program and enable tear check block + * @disable_tearcheck: disable able tear check block * @setup_dither : function to program the dither hw block * @get_line_count: obtain current vertical line counter */ @@ -47,14 +47,13 @@ struct dpu_hw_pingpong_ops { * enables vysnc generation and sets up init value of * read pointer and programs the tear check cofiguration */ - int (*setup_tearcheck)(struct dpu_hw_pingpong *pp, + int (*enable_tearcheck)(struct dpu_hw_pingpong *pp, struct dpu_hw_tear_check *cfg); /** - * enables tear check block + * disables tear check block */ - int (*enable_tearcheck)(struct dpu_hw_pingpong *pp, - bool enable); + int (*disable_tearcheck)(struct dpu_hw_pingpong *pp); /** * read, modify, write to either set or clear listening to external TE -- cgit v1.2.3 From e955a3f0d86e4a789364af62495ac37546eb71c8 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:35 +0200 Subject: drm/msm/dpu: Implement tearcheck support on INTF block Since DPU 5.0.0 the TEARCHECK registers and interrupts moved out of the PINGPONG block and into the INTF. Implement the necessary callbacks in the INTF block, and use these callbacks together with the INTF_TEAR interrupts. Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/534234/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-21-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 10 +- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 160 +++++++++------ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 214 +++++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 25 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 + drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 14 ++ 7 files changed, 378 insertions(+), 58 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index b34416cbd0f5..d7cd4734dc7d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -666,6 +666,7 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc, struct dpu_kms *dpu_kms; struct dpu_hw_mdp *hw_mdptop; struct drm_encoder *drm_enc; + struct dpu_encoder_phys *phys_enc; int i; if (!dpu_enc || !disp_info) { @@ -696,12 +697,22 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc, vsync_cfg.ppnumber[i] = dpu_enc->hw_pp[i]->idx; vsync_cfg.pp_count = dpu_enc->num_phys_encs; + vsync_cfg.frame_rate = drm_mode_vrefresh(&dpu_enc->base.crtc->state->adjusted_mode); + if (disp_info->is_te_using_watchdog_timer) vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_WD_TIMER_0; else vsync_cfg.vsync_source = DPU_VSYNC0_SOURCE_GPIO; hw_mdptop->ops.setup_vsync_source(hw_mdptop, &vsync_cfg); + + for (i = 0; i < dpu_enc->num_phys_encs; i++) { + phys_enc = dpu_enc->phys_encs[i]; + + if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.vsync_sel) + phys_enc->hw_intf->ops.vsync_sel(phys_enc->hw_intf, + vsync_cfg.vsync_source); + } } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 1d434b22180d..90f177e43262 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -129,10 +129,10 @@ struct dpu_encoder_phys_ops { /** * enum dpu_intr_idx - dpu encoder interrupt index * @INTR_IDX_VSYNC: Vsync interrupt for video mode panel - * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel - * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel - * @INTR_IDX_RDPTR: Readpointer done unterrupt for cmd mode panel - * @INTR_IDX_WB_DONE: Writeback fone interrupt for virtual connector + * @INTR_IDX_PINGPONG: Pingpong done interrupt for cmd mode panel + * @INTR_IDX_UNDERRUN: Underrun interrupt for video and cmd mode panel + * @INTR_IDX_RDPTR: Readpointer done interrupt for cmd mode panel + * @INTR_IDX_WB_DONE: Writeback done interrupt for virtual connector */ enum dpu_intr_idx { INTR_IDX_VSYNC, @@ -176,6 +176,7 @@ enum dpu_intr_idx { * pending. * @pending_kickoff_wq: Wait queue for blocking until kickoff completes * @irq: IRQ indices + * @has_intf_te: Interface TE configuration support */ struct dpu_encoder_phys { struct drm_encoder *parent; @@ -200,6 +201,7 @@ struct dpu_encoder_phys { atomic_t pending_kickoff_cnt; wait_queue_head_t pending_kickoff_wq; int irq[INTR_IDX_MAX]; + bool has_intf_te; }; static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 1df3745224f5..d8ed85a238af 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -97,13 +97,18 @@ static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) DPU_ATRACE_END("pp_done_irq"); } -static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx) +static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg, int irq_idx) { struct dpu_encoder_phys *phys_enc = arg; struct dpu_encoder_phys_cmd *cmd_enc; - if (!phys_enc->hw_pp) - return; + if (phys_enc->has_intf_te) { + if (!phys_enc->hw_intf) + return; + } else { + if (!phys_enc->hw_pp) + return; + } DPU_ATRACE_BEGIN("rd_ptr_irq"); cmd_enc = to_dpu_encoder_phys_cmd(phys_enc); @@ -144,7 +149,10 @@ static void dpu_encoder_phys_cmd_atomic_mode_set( phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done; - phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr; + if (phys_enc->has_intf_te) + phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_intf->cap->intr_tear_rd_ptr; + else + phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr; phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun; } @@ -255,7 +263,7 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, phys_enc->irq[INTR_IDX_RDPTR], - dpu_encoder_phys_cmd_pp_rd_ptr_irq, + dpu_encoder_phys_cmd_te_rd_ptr_irq, phys_enc); else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0) ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, @@ -319,19 +327,26 @@ static void dpu_encoder_phys_cmd_tearcheck_config( u32 vsync_hz; struct dpu_kms *dpu_kms; - if (!phys_enc->hw_pp) { - DPU_ERROR("invalid encoder\n"); - return; - } - mode = &phys_enc->cached_mode; + if (phys_enc->has_intf_te) { + if (!phys_enc->hw_intf || + !phys_enc->hw_intf->ops.enable_tearcheck) { + DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); + return; + } - DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0); + DPU_DEBUG_CMDENC(cmd_enc, ""); + } else { + if (!phys_enc->hw_pp || + !phys_enc->hw_pp->ops.enable_tearcheck) { + DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); + return; + } - if (!phys_enc->hw_pp->ops.enable_tearcheck) { - DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n"); - return; + DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0); } + mode = &phys_enc->cached_mode; + dpu_kms = phys_enc->dpu_kms; /* @@ -366,23 +381,24 @@ static void dpu_encoder_phys_cmd_tearcheck_config( tc_cfg.rd_ptr_irq = mode->vdisplay + 1; DPU_DEBUG_CMDENC(cmd_enc, - "tc %d vsync_clk_speed_hz %u vtotal %u vrefresh %u\n", - phys_enc->hw_pp->idx - PINGPONG_0, vsync_hz, - mode->vtotal, drm_mode_vrefresh(mode)); + "tc vsync_clk_speed_hz %u vtotal %u vrefresh %u\n", + vsync_hz, mode->vtotal, drm_mode_vrefresh(mode)); DPU_DEBUG_CMDENC(cmd_enc, - "tc %d enable %u start_pos %u rd_ptr_irq %u\n", - phys_enc->hw_pp->idx - PINGPONG_0, tc_enable, tc_cfg.start_pos, - tc_cfg.rd_ptr_irq); + "tc enable %u start_pos %u rd_ptr_irq %u\n", + tc_enable, tc_cfg.start_pos, tc_cfg.rd_ptr_irq); DPU_DEBUG_CMDENC(cmd_enc, - "tc %d hw_vsync_mode %u vsync_count %u vsync_init_val %u\n", - phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.hw_vsync_mode, - tc_cfg.vsync_count, tc_cfg.vsync_init_val); + "tc hw_vsync_mode %u vsync_count %u vsync_init_val %u\n", + tc_cfg.hw_vsync_mode, tc_cfg.vsync_count, + tc_cfg.vsync_init_val); DPU_DEBUG_CMDENC(cmd_enc, - "tc %d cfgheight %u thresh_start %u thresh_cont %u\n", - phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.sync_cfg_height, - tc_cfg.sync_threshold_start, tc_cfg.sync_threshold_continue); - - phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, &tc_cfg); + "tc cfgheight %u thresh_start %u thresh_cont %u\n", + tc_cfg.sync_cfg_height, tc_cfg.sync_threshold_start, + tc_cfg.sync_threshold_continue); + + if (phys_enc->has_intf_te) + phys_enc->hw_intf->ops.enable_tearcheck(phys_enc->hw_intf, &tc_cfg); + else + phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, &tc_cfg); } static void _dpu_encoder_phys_cmd_pingpong_config( @@ -459,11 +475,19 @@ static void dpu_encoder_phys_cmd_enable(struct dpu_encoder_phys *phys_enc) static void _dpu_encoder_phys_cmd_connect_te( struct dpu_encoder_phys *phys_enc, bool enable) { - if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.connect_external_te) - return; + if (phys_enc->has_intf_te) { + if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.connect_external_te) + return; - trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable); - phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable); + trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable); + phys_enc->hw_intf->ops.connect_external_te(phys_enc->hw_intf, enable); + } else { + if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.connect_external_te) + return; + + trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable); + phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable); + } } static void dpu_encoder_phys_cmd_prepare_idle_pc( @@ -476,17 +500,21 @@ static int dpu_encoder_phys_cmd_get_line_count( struct dpu_encoder_phys *phys_enc) { struct dpu_hw_pingpong *hw_pp; - - if (!phys_enc->hw_pp) - return -EINVAL; + struct dpu_hw_intf *hw_intf; if (!dpu_encoder_phys_cmd_is_master(phys_enc)) return -EINVAL; + if (phys_enc->has_intf_te) { + hw_intf = phys_enc->hw_intf; + if (!hw_intf || !hw_intf->ops.get_line_count) + return -EINVAL; + return hw_intf->ops.get_line_count(hw_intf); + } + hw_pp = phys_enc->hw_pp; - if (!hw_pp->ops.get_line_count) + if (!hw_pp || !hw_pp->ops.get_line_count) return -EINVAL; - return hw_pp->ops.get_line_count(hw_pp); } @@ -496,21 +524,31 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc) to_dpu_encoder_phys_cmd(phys_enc); struct dpu_hw_ctl *ctl; - if (!phys_enc->hw_pp) { - DPU_ERROR("invalid encoder\n"); - return; - } - DRM_DEBUG_KMS("id:%u pp:%d state:%d\n", DRMID(phys_enc->parent), - phys_enc->hw_pp->idx - PINGPONG_0, - phys_enc->enable_state); - if (phys_enc->enable_state == DPU_ENC_DISABLED) { DPU_ERROR_CMDENC(cmd_enc, "already disabled\n"); return; } - if (phys_enc->hw_pp->ops.disable_tearcheck) - phys_enc->hw_pp->ops.disable_tearcheck(phys_enc->hw_pp); + if (phys_enc->has_intf_te) { + DRM_DEBUG_KMS("id:%u intf:%d state:%d\n", DRMID(phys_enc->parent), + phys_enc->hw_intf->idx - INTF_0, + phys_enc->enable_state); + + if (phys_enc->hw_intf->ops.disable_tearcheck) + phys_enc->hw_intf->ops.disable_tearcheck(phys_enc->hw_intf); + } else { + if (!phys_enc->hw_pp) { + DPU_ERROR("invalid encoder\n"); + return; + } + + DRM_DEBUG_KMS("id:%u pp:%d state:%d\n", DRMID(phys_enc->parent), + phys_enc->hw_pp->idx - PINGPONG_0, + phys_enc->enable_state); + + if (phys_enc->hw_pp->ops.disable_tearcheck) + phys_enc->hw_pp->ops.disable_tearcheck(phys_enc->hw_pp); + } if (phys_enc->hw_intf->ops.bind_pingpong_blk) { phys_enc->hw_intf->ops.bind_pingpong_blk( @@ -572,15 +610,26 @@ static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc) { if (!phys_enc) return; - if (!phys_enc->hw_pp) - return; if (!dpu_encoder_phys_cmd_is_master(phys_enc)) return; - if (phys_enc->hw_pp->ops.disable_autorefresh) { - phys_enc->hw_pp->ops.disable_autorefresh(phys_enc->hw_pp, - DRMID(phys_enc->parent), - phys_enc->cached_mode.vdisplay); + if (phys_enc->has_intf_te) { + if (!phys_enc->hw_intf->ops.disable_autorefresh) + return; + + phys_enc->hw_intf->ops.disable_autorefresh( + phys_enc->hw_intf, + DRMID(phys_enc->parent), + phys_enc->cached_mode.vdisplay); + } else { + if (!phys_enc->hw_pp || + !phys_enc->hw_pp->ops.disable_autorefresh) + return; + + phys_enc->hw_pp->ops.disable_autorefresh( + phys_enc->hw_pp, + DRMID(phys_enc->parent), + phys_enc->cached_mode.vdisplay); } } @@ -658,7 +707,7 @@ static int dpu_encoder_phys_cmd_wait_for_vblank( rc = dpu_encoder_helper_wait_for_irq(phys_enc, phys_enc->irq[INTR_IDX_RDPTR], - dpu_encoder_phys_cmd_pp_rd_ptr_irq, + dpu_encoder_phys_cmd_te_rd_ptr_irq, &wait_info); return rc; @@ -732,6 +781,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++) phys_enc->irq[i] = -EINVAL; + phys_enc->has_intf_te = test_bit(DPU_INTF_TE, + &phys_enc->dpu_kms->catalog->intf[p->intf_idx - INTF_0].features); + atomic_set(&phys_enc->vblank_refcount, 0); atomic_set(&phys_enc->pending_kickoff_cnt, 0); atomic_set(&phys_enc->pending_ctlstart_cnt, 0); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 0bd99f380a49..5dce18236d87 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -8,6 +8,9 @@ #include "dpu_hw_catalog.h" #include "dpu_hw_intf.h" #include "dpu_kms.h" +#include "dpu_trace.h" + +#include #define INTF_TIMING_ENGINE_EN 0x000 #define INTF_CONFIG 0x004 @@ -64,6 +67,24 @@ #define INTF_MUX 0x25C #define INTF_STATUS 0x26C +#define INTF_AVR_CONTROL 0x270 +#define INTF_AVR_MODE 0x274 +#define INTF_AVR_TRIGGER 0x278 +#define INTF_AVR_VTOTAL 0x27C +#define INTF_TEAR_MDP_VSYNC_SEL 0x280 +#define INTF_TEAR_TEAR_CHECK_EN 0x284 +#define INTF_TEAR_SYNC_CONFIG_VSYNC 0x288 +#define INTF_TEAR_SYNC_CONFIG_HEIGHT 0x28C +#define INTF_TEAR_SYNC_WRCOUNT 0x290 +#define INTF_TEAR_VSYNC_INIT_VAL 0x294 +#define INTF_TEAR_INT_COUNT_VAL 0x298 +#define INTF_TEAR_SYNC_THRESH 0x29C +#define INTF_TEAR_START_POS 0x2A0 +#define INTF_TEAR_RD_PTR_IRQ 0x2A4 +#define INTF_TEAR_WR_PTR_IRQ 0x2A8 +#define INTF_TEAR_OUT_LINE_COUNT 0x2AC +#define INTF_TEAR_LINE_COUNT 0x2B0 +#define INTF_TEAR_AUTOREFRESH_CONFIG 0x2B4 #define INTF_CFG_ACTIVE_H_EN BIT(29) #define INTF_CFG_ACTIVE_V_EN BIT(30) @@ -307,6 +328,191 @@ static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) return dpu_hw_collect_misr(&intf->hw, INTF_MISR_CTRL, INTF_MISR_SIGNATURE, misr_value); } +static int dpu_hw_intf_enable_te(struct dpu_hw_intf *intf, + struct dpu_hw_tear_check *te) +{ + struct dpu_hw_blk_reg_map *c; + int cfg; + + if (!intf) + return -EINVAL; + + c = &intf->hw; + + cfg = BIT(19); /* VSYNC_COUNTER_EN */ + if (te->hw_vsync_mode) + cfg |= BIT(20); + + cfg |= te->vsync_count; + + DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg); + DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_HEIGHT, te->sync_cfg_height); + DPU_REG_WRITE(c, INTF_TEAR_VSYNC_INIT_VAL, te->vsync_init_val); + DPU_REG_WRITE(c, INTF_TEAR_RD_PTR_IRQ, te->rd_ptr_irq); + DPU_REG_WRITE(c, INTF_TEAR_START_POS, te->start_pos); + DPU_REG_WRITE(c, INTF_TEAR_SYNC_THRESH, + ((te->sync_threshold_continue << 16) | + te->sync_threshold_start)); + DPU_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, + (te->start_pos + te->sync_threshold_start + 1)); + + DPU_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, 1); + + return 0; +} + +static void dpu_hw_intf_setup_autorefresh_config(struct dpu_hw_intf *intf, + u32 frame_count, bool enable) +{ + struct dpu_hw_blk_reg_map *c; + u32 refresh_cfg; + + c = &intf->hw; + refresh_cfg = DPU_REG_READ(c, INTF_TEAR_AUTOREFRESH_CONFIG); + if (enable) + refresh_cfg = BIT(31) | frame_count; + else + refresh_cfg &= ~BIT(31); + + DPU_REG_WRITE(c, INTF_TEAR_AUTOREFRESH_CONFIG, refresh_cfg); +} + +/* + * dpu_hw_intf_get_autorefresh_config - Get autorefresh config from HW + * @intf: DPU intf structure + * @frame_count: Used to return the current frame count from hw + * + * Returns: True if autorefresh enabled, false if disabled. + */ +static bool dpu_hw_intf_get_autorefresh_config(struct dpu_hw_intf *intf, + u32 *frame_count) +{ + u32 val = DPU_REG_READ(&intf->hw, INTF_TEAR_AUTOREFRESH_CONFIG); + + if (frame_count != NULL) + *frame_count = val & 0xffff; + return !!((val & BIT(31)) >> 31); +} + +static int dpu_hw_intf_disable_te(struct dpu_hw_intf *intf) +{ + struct dpu_hw_blk_reg_map *c; + + if (!intf) + return -EINVAL; + + c = &intf->hw; + DPU_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, 0); + return 0; +} + +static int dpu_hw_intf_connect_external_te(struct dpu_hw_intf *intf, + bool enable_external_te) +{ + struct dpu_hw_blk_reg_map *c = &intf->hw; + u32 cfg; + int orig; + + if (!intf) + return -EINVAL; + + c = &intf->hw; + cfg = DPU_REG_READ(c, INTF_TEAR_SYNC_CONFIG_VSYNC); + orig = (bool)(cfg & BIT(20)); + if (enable_external_te) + cfg |= BIT(20); + else + cfg &= ~BIT(20); + DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg); + trace_dpu_intf_connect_ext_te(intf->idx - INTF_0, cfg); + + return orig; +} + +static int dpu_hw_intf_get_vsync_info(struct dpu_hw_intf *intf, + struct dpu_hw_pp_vsync_info *info) +{ + struct dpu_hw_blk_reg_map *c = &intf->hw; + u32 val; + + if (!intf || !info) + return -EINVAL; + + c = &intf->hw; + + val = DPU_REG_READ(c, INTF_TEAR_VSYNC_INIT_VAL); + info->rd_ptr_init_val = val & 0xffff; + + val = DPU_REG_READ(c, INTF_TEAR_INT_COUNT_VAL); + info->rd_ptr_frame_count = (val & 0xffff0000) >> 16; + info->rd_ptr_line_count = val & 0xffff; + + val = DPU_REG_READ(c, INTF_TEAR_LINE_COUNT); + info->wr_ptr_line_count = val & 0xffff; + + val = DPU_REG_READ(c, INTF_FRAME_COUNT); + info->intf_frame_count = val; + + return 0; +} + +static void dpu_hw_intf_vsync_sel(struct dpu_hw_intf *intf, + u32 vsync_source) +{ + struct dpu_hw_blk_reg_map *c; + + if (!intf) + return; + + c = &intf->hw; + + DPU_REG_WRITE(c, INTF_TEAR_MDP_VSYNC_SEL, (vsync_source & 0xf)); +} + +static void dpu_hw_intf_disable_autorefresh(struct dpu_hw_intf *intf, + uint32_t encoder_id, u16 vdisplay) +{ + struct dpu_hw_pp_vsync_info info; + int trial = 0; + + /* If autorefresh is already disabled, we have nothing to do */ + if (!dpu_hw_intf_get_autorefresh_config(intf, NULL)) + return; + + /* + * If autorefresh is enabled, disable it and make sure it is safe to + * proceed with current frame commit/push. Sequence followed is, + * 1. Disable TE + * 2. Disable autorefresh config + * 4. Poll for frame transfer ongoing to be false + * 5. Enable TE back + */ + + dpu_hw_intf_connect_external_te(intf, false); + dpu_hw_intf_setup_autorefresh_config(intf, 0, false); + + do { + udelay(DPU_ENC_MAX_POLL_TIMEOUT_US); + if ((trial * DPU_ENC_MAX_POLL_TIMEOUT_US) + > (KICKOFF_TIMEOUT_MS * USEC_PER_MSEC)) { + DPU_ERROR("enc%d intf%d disable autorefresh failed\n", + encoder_id, intf->idx - INTF_0); + break; + } + + trial++; + + dpu_hw_intf_get_vsync_info(intf, &info); + } while (info.wr_ptr_line_count > 0 && + info.wr_ptr_line_count < vdisplay); + + dpu_hw_intf_connect_external_te(intf, true); + + DPU_DEBUG("enc%d intf%d disabled autorefresh\n", + encoder_id, intf->idx - INTF_0); + +} + static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, unsigned long cap) { @@ -319,6 +525,14 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk; ops->setup_misr = dpu_hw_intf_setup_misr; ops->collect_misr = dpu_hw_intf_collect_misr; + + if (cap & BIT(DPU_INTF_TE)) { + ops->enable_tearcheck = dpu_hw_intf_enable_te; + ops->disable_tearcheck = dpu_hw_intf_disable_te; + ops->connect_external_te = dpu_hw_intf_connect_external_te; + ops->vsync_sel = dpu_hw_intf_vsync_sel; + ops->disable_autorefresh = dpu_hw_intf_disable_autorefresh; + } } struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 102c4f0e812b..73b0885918f8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -60,6 +60,16 @@ struct intf_status { * feed pixels to this interface * @setup_misr: enable/disable MISR * @collect_misr: read MISR signature + * @enable_tearcheck: Enables vsync generation and sets up init value of read + * pointer and programs the tear check configuration + * @disable_tearcheck: Disables tearcheck block + * @connect_external_te: Read, modify, write to either set or clear listening to external TE + * Return: 1 if TE was originally connected, 0 if not, or -ERROR + * @get_vsync_info: Provides the programmed and current line_count + * @setup_autorefresh: Configure and enable the autorefresh config + * @get_autorefresh: Retrieve autorefresh config from hardware + * Return: 0 on success, -ETIMEDOUT on timeout + * @vsync_sel: Select vsync signal for tear-effect configuration */ struct dpu_hw_intf_ops { void (*setup_timing_gen)(struct dpu_hw_intf *intf, @@ -82,6 +92,21 @@ struct dpu_hw_intf_ops { const enum dpu_pingpong pp); void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count); int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); + + // Tearcheck on INTF since DPU 5.0.0 + + int (*enable_tearcheck)(struct dpu_hw_intf *intf, struct dpu_hw_tear_check *cfg); + + int (*disable_tearcheck)(struct dpu_hw_intf *intf); + + int (*connect_external_te)(struct dpu_hw_intf *intf, bool enable_external_te); + + void (*vsync_sel)(struct dpu_hw_intf *intf, u32 vsync_source); + + /** + * Disable autorefresh if enabled + */ + void (*disable_autorefresh)(struct dpu_hw_intf *intf, uint32_t encoder_id, u16 vdisplay); }; struct dpu_hw_intf { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 6ed12fd0505b..1913a19de733 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -501,12 +501,14 @@ struct dpu_hw_tear_check { * @rd_ptr_frame_count: Num frames sent since enabling interface * @rd_ptr_line_count: Current line on panel (rd ptr) * @wr_ptr_line_count: Current line within pp fifo (wr ptr) + * @intf_frame_count: Frames read from intf */ struct dpu_hw_pp_vsync_info { u32 rd_ptr_init_val; u32 rd_ptr_frame_count; u32 rd_ptr_line_count; u32 wr_ptr_line_count; + u32 intf_frame_count; }; #endif /* _DPU_HW_MDSS_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index 0ad148cc2fb8..1a92d21094f4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -871,6 +871,20 @@ TRACE_EVENT(dpu_pp_connect_ext_te, TP_printk("pp:%d cfg:%u", __entry->pp, __entry->cfg) ); +TRACE_EVENT(dpu_intf_connect_ext_te, + TP_PROTO(enum dpu_intf intf, u32 cfg), + TP_ARGS(intf, cfg), + TP_STRUCT__entry( + __field( enum dpu_intf, intf ) + __field( u32, cfg ) + ), + TP_fast_assign( + __entry->intf = intf; + __entry->cfg = cfg; + ), + TP_printk("intf:%d cfg:%u", __entry->intf, __entry->cfg) +); + TRACE_EVENT(dpu_core_irq_register_callback, TP_PROTO(int irq_idx, void *callback), TP_ARGS(irq_idx, callback), -- cgit v1.2.3 From f1584d89c1cdf893c11e2da645b0101c857cf77e Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 27 Apr 2023 00:37:36 +0200 Subject: drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config Now that newer DPU platforms use a readpointer-done interrupt on the INTF block, stop providing the unused interrupt on the PINGPONG block. Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/534238/ Link: https://lore.kernel.org/r/20230411-dpu-intf-te-v4-22-27ce1a5ab5c6@somainline.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 8 ++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 8 ++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 8 ++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 8 ++++---- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 10 +++++----- 7 files changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 561022b8dfd6..b5f751354267 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -130,16 +130,16 @@ static const struct dpu_dspp_cfg sm8150_dspp[] = { static const struct dpu_pingpong_cfg sm8150_pp[] = { PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + -1), PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + -1), PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + -1), PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), + -1), PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index d1f306c89567..8ed2b263c5ea 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -129,16 +129,16 @@ static const struct dpu_dspp_cfg sc8180x_dspp[] = { static const struct dpu_pingpong_cfg sc8180x_pp[] = { PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + -1), PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + -1), PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + -1), PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), + -1), PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index 10d67db8423f..daebd2170041 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -131,16 +131,16 @@ static const struct dpu_dspp_cfg sm8250_dspp[] = { static const struct dpu_pingpong_cfg sm8250_pp[] = { PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + -1), PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, MERGE_3D_0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + -1), PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + -1), PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), + -1), PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h index 5509ceb5d55b..ba9de008519b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -62,7 +62,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = { static const struct dpu_pingpong_cfg sm6115_pp[] = { PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + -1), }; static const struct dpu_intf_cfg sm6115_intf[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h index 22b8a173d214..92ac348eea6b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h @@ -59,7 +59,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[] = { static const struct dpu_pingpong_cfg qcm2290_pp[] = { PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + -1), }; static const struct dpu_intf_cfg qcm2290_intf[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 2dcfe18bc8c9..3c1b2c13398d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -129,16 +129,16 @@ static const struct dpu_dspp_cfg sm8350_dspp[] = { static const struct dpu_pingpong_cfg sm8350_pp[] = { PP_BLK_DITHER("pingpong_0", PINGPONG_0, 0x69000, MERGE_3D_0, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + -1), PP_BLK_DITHER("pingpong_1", PINGPONG_1, 0x6a000, MERGE_3D_0, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + -1), PP_BLK_DITHER("pingpong_2", PINGPONG_2, 0x6b000, MERGE_3D_1, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + -1), PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, MERGE_3D_1, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), + -1), PP_BLK_DITHER("pingpong_4", PINGPONG_4, 0x6d000, MERGE_3D_2, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 279fe8f4e1e3..86c2e68ebd2c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -126,20 +126,20 @@ static const struct dpu_dspp_cfg sm8450_dspp[] = { DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK, &sm8150_dspp_sblk), }; -/* FIXME: interrupts */ + static const struct dpu_pingpong_cfg sm8450_pp[] = { PP_BLK_DITHER("pingpong_0", PINGPONG_0, 0x69000, MERGE_3D_0, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)), + -1), PP_BLK_DITHER("pingpong_1", PINGPONG_1, 0x6a000, MERGE_3D_0, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)), + -1), PP_BLK_DITHER("pingpong_2", PINGPONG_2, 0x6b000, MERGE_3D_1, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)), + -1), PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, MERGE_3D_1, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), + -1), PP_BLK_DITHER("pingpong_4", PINGPONG_4, 0x6d000, MERGE_3D_2, sc7280_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1), -- cgit v1.2.3 From 7e3d6c548b4de7018aa74bb2416d14cff11ea5a1 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 29 Apr 2023 04:23:51 +0300 Subject: drm/msm/dpu: drop SSPP's SRC subblock The src_blk declares a lame copy of main SSPP register space. It's offset is always 0. It's length has been fixed to 0x150, while SSPP's length is now correct. Drop the src_blk and access SSPP registers without additional subblock lookup. Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/534745/ Link: https://lore.kernel.org/r/20230429012353.2569481-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 14 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 14 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 128 +++++++++++-------------- 3 files changed, 58 insertions(+), 98 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 81b44a394f03..70600f8abe91 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -13,7 +13,7 @@ #include "dpu_kms.h" #define VIG_BASE_MASK \ - (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\ + (BIT(DPU_SSPP_QOS) |\ BIT(DPU_SSPP_CDP) |\ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT)) @@ -39,7 +39,7 @@ #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL)) #define DMA_MSM8998_MASK \ - (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\ + (BIT(DPU_SSPP_QOS) |\ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) @@ -50,7 +50,7 @@ (VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) #define DMA_SDM845_MASK \ - (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\ + (BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) @@ -254,8 +254,6 @@ static const uint32_t wb2_formats[] = { .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ .smart_dma_priority = sdma_pri, \ - .src_blk = {.name = STRCAT("sspp_src_", num), \ - .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \ .scaler_blk = {.name = STRCAT("sspp_scaler", num), \ .id = qseed_ver, \ .base = 0xa00, .len = 0xa0,}, \ @@ -274,8 +272,6 @@ static const uint32_t wb2_formats[] = { .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ .smart_dma_priority = sdma_pri, \ - .src_blk = {.name = STRCAT("sspp_src_", num), \ - .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \ .scaler_blk = {.name = STRCAT("sspp_scaler", num), \ .id = qseed_ver, \ .base = 0xa00, .len = 0xa0,}, \ @@ -294,8 +290,6 @@ static const uint32_t wb2_formats[] = { .maxdwnscale = SSPP_UNITY_SCALE, \ .maxupscale = SSPP_UNITY_SCALE, \ .smart_dma_priority = sdma_pri, \ - .src_blk = {.name = STRCAT("sspp_src_", num), \ - .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \ .format_list = plane_formats, \ .num_formats = ARRAY_SIZE(plane_formats), \ .virt_format_list = plane_formats, \ @@ -377,8 +371,6 @@ static const struct dpu_sspp_sub_blks sm8550_dma_sblk_5 = _DMA_SBLK("13", 6); .maxdwnscale = SSPP_UNITY_SCALE, \ .maxupscale = SSPP_UNITY_SCALE, \ .smart_dma_priority = sdma_pri, \ - .src_blk = {.name = STRCAT("sspp_src_", num), \ - .id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ .virt_format_list = plane_formats, \ 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 a2ef61d4f7fa..1cb5699a5a47 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -67,7 +67,6 @@ enum { /** * SSPP sub-blocks/features - * @DPU_SSPP_SRC Src and fetch part of the pipes, * @DPU_SSPP_SCALER_QSEED2, QSEED2 algorithm support * @DPU_SSPP_SCALER_QSEED3, QSEED3 alogorithm support * @DPU_SSPP_SCALER_QSEED3LITE, QSEED3 Lite alogorithm support @@ -88,8 +87,7 @@ enum { * @DPU_SSPP_MAX maximum value */ enum { - DPU_SSPP_SRC = 0x1, - DPU_SSPP_SCALER_QSEED2, + DPU_SSPP_SCALER_QSEED2 = 0x1, DPU_SSPP_SCALER_QSEED3, DPU_SSPP_SCALER_QSEED3LITE, DPU_SSPP_SCALER_QSEED4, @@ -277,14 +275,6 @@ enum { u32 base; \ u32 len -/** - * struct dpu_src_blk: SSPP part of the source pipes - * @info: HW register and features supported by this sub-blk - */ -struct dpu_src_blk { - DPU_HW_SUBBLK_INFO; -}; - /** * struct dpu_scaler_blk: Scaler information * @info: HW register and features supported by this sub-blk @@ -391,7 +381,6 @@ struct dpu_caps { * @smart_dma_priority: hw priority of rect1 of multirect pipe * @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps * @qseed_ver: qseed version - * @src_blk: * @scaler_blk: * @csc_blk: * @format_list: Pointer to list of supported formats @@ -408,7 +397,6 @@ struct dpu_sspp_sub_blks { u32 smart_dma_priority; u32 max_per_pipe_bw; u32 qseed_ver; - struct dpu_src_blk src_blk; struct dpu_scaler_blk scaler_blk; struct dpu_pp_blk csc_blk; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 31348ff5d493..a93e311afa71 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -12,7 +12,7 @@ #define DPU_FETCH_CONFIG_RESET_VALUE 0x00000087 -/* DPU_SSPP_SRC */ +/* SSPP registers */ #define SSPP_SRC_SIZE 0x00 #define SSPP_SRC_XY 0x08 #define SSPP_OUT_SIZE 0x0c @@ -149,9 +149,6 @@ static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx, sblk = ctx->cap->sblk; switch (s_id) { - case DPU_SSPP_SRC: - *idx = sblk->src_blk.base; - break; case DPU_SSPP_SCALER_QSEED2: case DPU_SSPP_SCALER_QSEED3: case DPU_SSPP_SCALER_RGB: @@ -172,9 +169,8 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe) { struct dpu_hw_sspp *ctx = pipe->sspp; u32 mode_mask; - u32 idx; - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) + if (!ctx) return; if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) { @@ -185,7 +181,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe) */ mode_mask = 0; } else { - mode_mask = DPU_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx); + mode_mask = DPU_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE); mode_mask |= pipe->multirect_index; if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX) mode_mask |= BIT(2); @@ -193,7 +189,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe) mode_mask &= ~BIT(2); } - DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask); + DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE, mode_mask); } static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx, @@ -247,9 +243,8 @@ static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe, u32 opmode = 0; u32 fast_clear = 0; u32 op_mode_off, unpack_pat_off, format_off; - u32 idx; - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx) || !fmt) + if (!ctx || !fmt) return; if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || @@ -264,7 +259,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe, } c = &ctx->hw; - opmode = DPU_REG_READ(c, op_mode_off + idx); + opmode = DPU_REG_READ(c, op_mode_off); opmode &= ~(MDSS_MDP_OP_FLIP_LR | MDSS_MDP_OP_FLIP_UD | MDSS_MDP_OP_BWC_EN | MDSS_MDP_OP_PE_OVERRIDE); @@ -352,12 +347,12 @@ static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe, VIG_CSC_10_EN | VIG_CSC_10_SRC_DATAFMT, DPU_FORMAT_IS_YUV(fmt)); - DPU_REG_WRITE(c, format_off + idx, src_format); - DPU_REG_WRITE(c, unpack_pat_off + idx, unpack); - DPU_REG_WRITE(c, op_mode_off + idx, opmode); + DPU_REG_WRITE(c, format_off, src_format); + DPU_REG_WRITE(c, unpack_pat_off, unpack); + DPU_REG_WRITE(c, op_mode_off, opmode); /* clear previous UBWC error */ - DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31)); + DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS, BIT(31)); } static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx, @@ -368,9 +363,8 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx, u32 lr_pe[4], tb_pe[4], tot_req_pixels[4]; const u32 bytemask = 0xff; const u32 shortmask = 0xffff; - u32 idx; - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx) || !pe_ext) + if (!ctx || !pe_ext) return; c = &ctx->hw; @@ -400,21 +394,21 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx, } /* color 0 */ - DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR + idx, lr_pe[0]); - DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB + idx, tb_pe[0]); - DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS + idx, + DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR, lr_pe[0]); + DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB, tb_pe[0]); + DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS, tot_req_pixels[0]); /* color 1 and color 2 */ - DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR + idx, lr_pe[1]); - DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB + idx, tb_pe[1]); - DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS + idx, + DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR, lr_pe[1]); + DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB, tb_pe[1]); + DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS, tot_req_pixels[1]); /* color 3 */ - DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR + idx, lr_pe[3]); - DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB + idx, lr_pe[3]); - DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS + idx, + DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR, lr_pe[3]); + DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB, lr_pe[3]); + DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS, tot_req_pixels[3]); } @@ -453,9 +447,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe, struct dpu_hw_blk_reg_map *c; u32 src_size, src_xy, dst_size, dst_xy; u32 src_size_off, src_xy_off, out_size_off, out_xy_off; - u32 idx; - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx) || !cfg) + if (!ctx || !cfg) return; c = &ctx->hw; @@ -483,10 +476,10 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe, drm_rect_width(&cfg->dst_rect); /* rectangle register programming */ - DPU_REG_WRITE(c, src_size_off + idx, src_size); - DPU_REG_WRITE(c, src_xy_off + idx, src_xy); - DPU_REG_WRITE(c, out_size_off + idx, dst_size); - DPU_REG_WRITE(c, out_xy_off + idx, dst_xy); + DPU_REG_WRITE(c, src_size_off, src_size); + DPU_REG_WRITE(c, src_xy_off, src_xy); + DPU_REG_WRITE(c, out_size_off, dst_size); + DPU_REG_WRITE(c, out_xy_off, dst_xy); } static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe, @@ -495,24 +488,23 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe, struct dpu_hw_sspp *ctx = pipe->sspp; u32 ystride0, ystride1; int i; - u32 idx; - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) + if (!ctx) return; if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) { for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++) - DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4, + DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + i * 0x4, layout->plane_addr[i]); } else if (pipe->multirect_index == DPU_SSPP_RECT_0) { - DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx, + DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR, layout->plane_addr[0]); - DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR + idx, + DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR, layout->plane_addr[2]); } else { - DPU_REG_WRITE(&ctx->hw, SSPP_SRC1_ADDR + idx, + DPU_REG_WRITE(&ctx->hw, SSPP_SRC1_ADDR, layout->plane_addr[0]); - DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx, + DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR, layout->plane_addr[2]); } @@ -522,8 +514,8 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe, ystride1 = (layout->plane_pitch[2]) | (layout->plane_pitch[3] << 16); } else { - ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx); - ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx); + ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0); + ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1); if (pipe->multirect_index == DPU_SSPP_RECT_0) { ystride0 = (ystride0 & 0xFFFF0000) | @@ -540,8 +532,8 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe, } } - DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx, ystride0); - DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx, ystride1); + DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE0, ystride0); + DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE1, ystride1); } static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx, @@ -565,9 +557,8 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color) { struct dpu_hw_sspp *ctx = pipe->sspp; struct dpu_hw_fmt_layout cfg; - u32 idx; - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) + if (!ctx) return; /* cleanup source addresses */ @@ -576,9 +567,9 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color) if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || pipe->multirect_index == DPU_SSPP_RECT_0) - DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color); + DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR, color); else - DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR_REC1 + idx, + DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR_REC1, color); } @@ -586,39 +577,34 @@ static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_sspp *ctx, u32 danger_lut, u32 safe_lut) { - u32 idx; - - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) + if (!ctx) return; - DPU_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, danger_lut); - DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut); + DPU_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT, danger_lut); + DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT, safe_lut); } static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_sspp *ctx, u64 creq_lut) { - u32 idx; - - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) + if (!ctx) return; if (ctx->cap && test_bit(DPU_SSPP_QOS_8LVL, &ctx->cap->features)) { - DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0 + idx, creq_lut); - DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_1 + idx, + DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0, creq_lut); + DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_1, creq_lut >> 32); } else { - DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, creq_lut); + DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT, creq_lut); } } static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx, struct dpu_hw_pipe_qos_cfg *cfg) { - u32 idx; u32 qos_ctrl = 0; - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) + if (!ctx) return; if (cfg->vblank_en) { @@ -634,23 +620,19 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx, if (cfg->danger_safe_en) qos_ctrl |= SSPP_QOS_CTRL_DANGER_SAFE_EN; - DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl); + DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL, qos_ctrl); } static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe, struct dpu_hw_cdp_cfg *cfg) { struct dpu_hw_sspp *ctx = pipe->sspp; - u32 idx; u32 cdp_cntl = 0; u32 cdp_cntl_offset = 0; if (!ctx || !cfg) return; - if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) - return; - if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || pipe->multirect_index == DPU_SSPP_RECT_0) cdp_cntl_offset = SSPP_CDP_CNTL; @@ -672,13 +654,11 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe, static void _setup_layer_ops(struct dpu_hw_sspp *c, unsigned long features) { - if (test_bit(DPU_SSPP_SRC, &features)) { - c->ops.setup_format = dpu_hw_sspp_setup_format; - c->ops.setup_rects = dpu_hw_sspp_setup_rects; - c->ops.setup_sourceaddress = dpu_hw_sspp_setup_sourceaddress; - c->ops.setup_solidfill = dpu_hw_sspp_setup_solidfill; - c->ops.setup_pe = dpu_hw_sspp_setup_pe_config; - } + c->ops.setup_format = dpu_hw_sspp_setup_format; + c->ops.setup_rects = dpu_hw_sspp_setup_rects; + c->ops.setup_sourceaddress = dpu_hw_sspp_setup_sourceaddress; + c->ops.setup_solidfill = dpu_hw_sspp_setup_solidfill; + c->ops.setup_pe = dpu_hw_sspp_setup_pe_config; if (test_bit(DPU_SSPP_QOS, &features)) { c->ops.setup_danger_safe_lut = @@ -728,8 +708,8 @@ int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, /* add register dump support */ dpu_debugfs_create_regset32("src_blk", 0400, debugfs_root, - sblk->src_blk.base + cfg->base, - sblk->src_blk.len, + cfg->base, + cfg->len, kms); if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) || -- cgit v1.2.3 From be7057e0d40be7f2d938c809d93f5efa9b365246 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 29 Apr 2023 04:23:52 +0300 Subject: drm/msm/dpu: access QSEED registers directly Stop using _sspp_subblk_offset() to get offset of the scaler_blk. Inline this function and use ctx->cap->sblk->scaler_blk.base directly. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/534746/ Link: https://lore.kernel.org/r/20230429012353.2569481-3-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index a93e311afa71..4f58cdcb20e2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -149,11 +149,6 @@ static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx, sblk = ctx->cap->sblk; switch (s_id) { - case DPU_SSPP_SCALER_QSEED2: - case DPU_SSPP_SCALER_QSEED3: - case DPU_SSPP_SCALER_RGB: - *idx = sblk->scaler_blk.base; - break; case DPU_SSPP_CSC: case DPU_SSPP_CSC_10BIT: *idx = sblk->csc_blk.base; @@ -195,22 +190,21 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe) static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx, u32 mask, u8 en) { - u32 idx; + const struct dpu_sspp_sub_blks *sblk = ctx->cap->sblk; u32 opmode; if (!test_bit(DPU_SSPP_SCALER_QSEED2, &ctx->cap->features) || - _sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED2, &idx) || !test_bit(DPU_SSPP_CSC, &ctx->cap->features)) return; - opmode = DPU_REG_READ(&ctx->hw, SSPP_VIG_OP_MODE + idx); + opmode = DPU_REG_READ(&ctx->hw, sblk->scaler_blk.base + SSPP_VIG_OP_MODE); if (en) opmode |= mask; else opmode &= ~mask; - DPU_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode); + DPU_REG_WRITE(&ctx->hw, sblk->scaler_blk.base + SSPP_VIG_OP_MODE, opmode); } static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx, @@ -416,25 +410,22 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx, struct dpu_hw_scaler3_cfg *scaler3_cfg, const struct dpu_format *format) { - u32 idx; - - if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) - || !scaler3_cfg) + if (!ctx || !scaler3_cfg) return; - dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx, + dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, + ctx->cap->sblk->scaler_blk.base, ctx->cap->sblk->scaler_blk.version, format); } static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx) { - u32 idx; - - if (!ctx || _sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx)) + if (!ctx) return 0; - return dpu_hw_get_scaler3_ver(&ctx->hw, idx); + return dpu_hw_get_scaler3_ver(&ctx->hw, + ctx->cap->sblk->scaler_blk.base); } /* -- cgit v1.2.3 From babbd0a5f3c5239cc081fed870b7f010d41bacde Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 29 Apr 2023 04:23:53 +0300 Subject: drm/msm/dpu: access CSC/CSC10 registers directly Stop using _sspp_subblk_offset() to get offset of the csc_blk. Inline this function and use ctx->cap->sblk->csc_blk.base directly. As this was the last user, drop _sspp_subblk_offset() too. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/534747/ Link: https://lore.kernel.org/r/20230429012353.2569481-4-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 43 ++++++----------------------- 1 file changed, 9 insertions(+), 34 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 4f58cdcb20e2..6b68ec5c7a5a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -136,30 +136,6 @@ #define TS_CLK 19200000 -static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx, - int s_id, - u32 *idx) -{ - int rc = 0; - const struct dpu_sspp_sub_blks *sblk; - - if (!ctx || !ctx->cap || !ctx->cap->sblk) - return -EINVAL; - - sblk = ctx->cap->sblk; - - switch (s_id) { - case DPU_SSPP_CSC: - case DPU_SSPP_CSC_10BIT: - *idx = sblk->csc_blk.base; - break; - default: - rc = -EINVAL; - } - - return rc; -} - static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe) { struct dpu_hw_sspp *ctx = pipe->sspp; @@ -210,19 +186,16 @@ static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx, static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx, u32 mask, u8 en) { - u32 idx; + const struct dpu_sspp_sub_blks *sblk = ctx->cap->sblk; u32 opmode; - if (_sspp_subblk_offset(ctx, DPU_SSPP_CSC_10BIT, &idx)) - return; - - opmode = DPU_REG_READ(&ctx->hw, SSPP_VIG_CSC_10_OP_MODE + idx); + opmode = DPU_REG_READ(&ctx->hw, sblk->csc_blk.base + SSPP_VIG_CSC_10_OP_MODE); if (en) opmode |= mask; else opmode &= ~mask; - DPU_REG_WRITE(&ctx->hw, SSPP_VIG_CSC_10_OP_MODE + idx, opmode); + DPU_REG_WRITE(&ctx->hw, sblk->csc_blk.base + SSPP_VIG_CSC_10_OP_MODE, opmode); } /* @@ -530,18 +503,20 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe, static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx, const struct dpu_csc_cfg *data) { - u32 idx; + u32 offset; bool csc10 = false; - if (_sspp_subblk_offset(ctx, DPU_SSPP_CSC, &idx) || !data) + if (!ctx || !data) return; + offset = ctx->cap->sblk->csc_blk.base; + if (test_bit(DPU_SSPP_CSC_10BIT, &ctx->cap->features)) { - idx += CSC_10BIT_OFFSET; + offset += CSC_10BIT_OFFSET; csc10 = true; } - dpu_hw_csc_setup(&ctx->hw, idx, data, csc10); + dpu_hw_csc_setup(&ctx->hw, offset, data, csc10); } static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color) -- cgit v1.2.3 From a7129231edf329a00e92dbd2d741f6da728a4a06 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 19 May 2023 20:49:59 +0200 Subject: drm/msm/dpu: Set DPU_DATA_HCTL_EN for in INTF_SC7180_MASK DPU5 and newer targets enable this unconditionally. Move it from the SC7280 mask to the SC7180 one. Fixes: 7e6ee55320f0 ("drm/msm/disp/dpu1: enable DATA_HCTL_EN for sc7280 target") Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Signed-off-by: Konrad Dybcio Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/538159/ Link: https://lore.kernel.org/r/20230508-topic-hctl_en-v2-1-e7bea9f1f5dd@linaro.org [DB: removed BIT(DPU_INTF_DATA_COMPRESS), which is not yet merged] Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 70600f8abe91..1dee5ba2b312 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -100,9 +100,12 @@ #define INTF_SDM845_MASK (0) #define INTF_SC7180_MASK \ - (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED)) + (BIT(DPU_INTF_INPUT_CTRL) | \ + BIT(DPU_INTF_TE) | \ + BIT(DPU_INTF_STATUS_SUPPORTED) | \ + BIT(DPU_DATA_HCTL_EN)) -#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) +#define INTF_SC7280_MASK (INTF_SC7180_MASK) #define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \ BIT(DPU_WB_UBWC) | \ -- cgit v1.2.3 From 50883f733c8ec10dd2d36466d3e53e3cb341bc10 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 20 May 2023 02:40:22 +0300 Subject: drm/msm/dpu: replace IS_ERR_OR_NULL with IS_ERR during DSC init Using IS_ERR_OR_NULL() together with PTR_ERR() is a typical mistake. If the value is NULL, then the function will return 0 instead of a proper return code. Moreover dpu_hw_dsc_init() can not return NULL. Replace the IS_ERR_OR_NULL() call with IS_ERR(). This follows the commit 740828c73a36 ("drm/msm/dpu: fix error handling in dpu_rm_init"), which removed IS_ERR_OR_NULL() from RM init code, but then the commit f2803ee91a41 ("drm/msm/disp/dpu1: Add DSC support in RM") added it for DSC init. Suggested-by: Marijn Suijten Reviewed-by: Marijn Suijten Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/538203/ Link: https://lore.kernel.org/r/20230519234025.2864377-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index f0fc70422e56..dffd3dd0a877 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -247,7 +247,7 @@ int dpu_rm_init(struct dpu_rm *rm, const struct dpu_dsc_cfg *dsc = &cat->dsc[i]; hw = dpu_hw_dsc_init(dsc, mmio); - if (IS_ERR_OR_NULL(hw)) { + if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed dsc object creation: err %d\n", rc); goto fail; -- cgit v1.2.3 From f89fdc862be4c390652116d22b5c20b0837cc8cd Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 20 May 2023 02:40:23 +0300 Subject: drm/msm/dpu: remove futile checks from dpu_rm_init() dpu_rm_init() contains checks for block->id values. These were logical in the vendor driver, when one can not be sure which values were passed from DT. In the upstream driver this is not necessary: the catalog is a part of the driver, we control specified IDs. Suggested-by: Marijn Suijten Reviewed-by: Marijn Suijten Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/538204/ Link: https://lore.kernel.org/r/20230519234025.2864377-3-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index dffd3dd0a877..d5a06628885e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -122,10 +122,6 @@ int dpu_rm_init(struct dpu_rm *rm, continue; } - if (lm->id < LM_0 || lm->id >= LM_MAX) { - DPU_ERROR("skip mixer %d with invalid id\n", lm->id); - continue; - } hw = dpu_hw_lm_init(lm, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); @@ -139,10 +135,6 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_merge_3d *hw; const struct dpu_merge_3d_cfg *merge_3d = &cat->merge_3d[i]; - if (merge_3d->id < MERGE_3D_0 || merge_3d->id >= MERGE_3D_MAX) { - DPU_ERROR("skip merge_3d %d with invalid id\n", merge_3d->id); - continue; - } hw = dpu_hw_merge_3d_init(merge_3d, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); @@ -157,10 +149,6 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_pingpong *hw; const struct dpu_pingpong_cfg *pp = &cat->pingpong[i]; - if (pp->id < PINGPONG_0 || pp->id >= PINGPONG_MAX) { - DPU_ERROR("skip pingpong %d with invalid id\n", pp->id); - continue; - } hw = dpu_hw_pingpong_init(pp, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); @@ -177,10 +165,6 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_intf *hw; const struct dpu_intf_cfg *intf = &cat->intf[i]; - if (intf->id < INTF_0 || intf->id >= INTF_MAX) { - DPU_ERROR("skip intf %d with invalid id\n", intf->id); - continue; - } hw = dpu_hw_intf_init(intf, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); @@ -194,11 +178,6 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_wb *hw; const struct dpu_wb_cfg *wb = &cat->wb[i]; - if (wb->id < WB_0 || wb->id >= WB_MAX) { - DPU_ERROR("skip intf %d with invalid id\n", wb->id); - continue; - } - hw = dpu_hw_wb_init(wb, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); @@ -212,10 +191,6 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_ctl *hw; const struct dpu_ctl_cfg *ctl = &cat->ctl[i]; - if (ctl->id < CTL_0 || ctl->id >= CTL_MAX) { - DPU_ERROR("skip ctl %d with invalid id\n", ctl->id); - continue; - } hw = dpu_hw_ctl_init(ctl, mmio, cat->mixer_count, cat->mixer); if (IS_ERR(hw)) { rc = PTR_ERR(hw); @@ -229,10 +204,6 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_dspp *hw; const struct dpu_dspp_cfg *dspp = &cat->dspp[i]; - if (dspp->id < DSPP_0 || dspp->id >= DSPP_MAX) { - DPU_ERROR("skip dspp %d with invalid id\n", dspp->id); - continue; - } hw = dpu_hw_dspp_init(dspp, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); @@ -259,11 +230,6 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_sspp *hw; const struct dpu_sspp_cfg *sspp = &cat->sspp[i]; - if (sspp->id < SSPP_NONE || sspp->id >= SSPP_MAX) { - DPU_ERROR("skip intf %d with invalid id\n", sspp->id); - continue; - } - hw = dpu_hw_sspp_init(sspp, mmio, cat->ubwc); if (IS_ERR(hw)) { rc = PTR_ERR(hw); -- cgit v1.2.3 From 76c40f1463585ab0927a832be302ebae0178e5a0 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 20 May 2023 02:40:24 +0300 Subject: drm/msm/dpu: use PINGPONG_NONE for LMs with no PP attached On msm8998/sdm845 some LM blocks do not have corresponding PINGPONG block. Currently the driver uses PINGPONG_MAX for such cases. Switch that to use PINGPONG_NONE instead, which is more logical. Reviewed-by: Marijn Suijten Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/538205/ Link: https://lore.kernel.org/r/20230519234025.2864377-4-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 37a52b4ef8d3..3c732a0360c7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -104,9 +104,9 @@ static const struct dpu_lm_cfg msm8998_lm[] = { LM_BLK("lm_2", LM_2, 0x46000, MIXER_MSM8998_MASK, &msm8998_lm_sblk, PINGPONG_2, LM_5, 0), LM_BLK("lm_3", LM_3, 0x47000, MIXER_MSM8998_MASK, - &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), + &msm8998_lm_sblk, PINGPONG_NONE, 0, 0), LM_BLK("lm_4", LM_4, 0x48000, MIXER_MSM8998_MASK, - &msm8998_lm_sblk, PINGPONG_MAX, 0, 0), + &msm8998_lm_sblk, PINGPONG_NONE, 0, 0), LM_BLK("lm_5", LM_5, 0x49000, MIXER_MSM8998_MASK, &msm8998_lm_sblk, PINGPONG_3, LM_2, 0), }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 0b727252671c..36ea1af10894 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -102,9 +102,9 @@ static const struct dpu_lm_cfg sdm845_lm[] = { LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_2, LM_5, 0), LM_BLK("lm_3", LM_3, 0x0, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_MAX, 0, 0), + &sdm845_lm_sblk, PINGPONG_NONE, 0, 0), LM_BLK("lm_4", LM_4, 0x0, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_MAX, 0, 0), + &sdm845_lm_sblk, PINGPONG_NONE, 0, 0), LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_3, LM_2, 0), }; 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 1cb5699a5a47..677048cc3b7d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -529,7 +529,7 @@ struct dpu_sspp_cfg { * @base register offset of this block * @features bit mask identifying sub-blocks/features * @sblk: LM Sub-blocks information - * @pingpong: ID of connected PingPong, PINGPONG_MAX if unsupported + * @pingpong: ID of connected PingPong, PINGPONG_NONE if unsupported * @lm_pair_mask: Bitmask of LMs that can be controlled by same CTL */ struct dpu_lm_cfg { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 1913a19de733..02a0f48aac94 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -191,7 +191,8 @@ enum dpu_dsc { }; enum dpu_pingpong { - PINGPONG_0 = 1, + PINGPONG_NONE, + PINGPONG_0, PINGPONG_1, PINGPONG_2, PINGPONG_3, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index d5a06628885e..bf7b8e7c45b1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -117,7 +117,7 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_mixer *hw; const struct dpu_lm_cfg *lm = &cat->mixer[i]; - if (lm->pingpong == PINGPONG_MAX) { + if (lm->pingpong == PINGPONG_NONE) { DPU_DEBUG("skip mixer %d without pingpong\n", lm->id); continue; } -- cgit v1.2.3 From 6c93a21d92666b44787ee32d054d48751799aad0 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 20 May 2023 02:40:25 +0300 Subject: drm/msm/dpu: move PINGPONG_NONE check to dpu_lm_init() Move the check for lm->pingpong being not NONE from dpu_rm_init() to dpu_lm_init(), following the change to dpu_hw_intf_init(). Suggested-by: Marijn Suijten Reviewed-by: Marijn Suijten Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/538206/ Link: https://lore.kernel.org/r/20230519234025.2864377-5-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 5 +++++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index 214f207ddf8a..d1c3bd8379ea 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -161,6 +161,11 @@ struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg, { struct dpu_hw_mixer *c; + if (cfg->pingpong == PINGPONG_NONE) { + DPU_DEBUG("skip mixer %d without pingpong\n", cfg->id); + return NULL; + } + c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index bf7b8e7c45b1..2ca3c666e22f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -117,11 +117,6 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_mixer *hw; const struct dpu_lm_cfg *lm = &cat->mixer[i]; - if (lm->pingpong == PINGPONG_NONE) { - DPU_DEBUG("skip mixer %d without pingpong\n", lm->id); - continue; - } - hw = dpu_hw_lm_init(lm, mmio); if (IS_ERR(hw)) { rc = PTR_ERR(hw); -- cgit v1.2.3 From 5f31d7e61ddf5ca8db06455b30d3b3e16d656944 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 19 May 2023 01:22:30 +0300 Subject: drm/msm/dpu: fix SSPP register definitions Reorder SSPP register definitions to sort them in the ascending order. Move register bitfields after the register definitions. Signed-off-by: Dmitry Baryshkov Reviewed-by: Jeykumar Sankaran Patchwork: https://patchwork.freedesktop.org/patch/537903/ Link: https://lore.kernel.org/r/20230518222238.3815293-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 64 ++++++++++++++--------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 6b68ec5c7a5a..08098880b7d5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -26,45 +26,18 @@ #define SSPP_SRC_FORMAT 0x30 #define SSPP_SRC_UNPACK_PATTERN 0x34 #define SSPP_SRC_OP_MODE 0x38 - -/* SSPP_MULTIRECT*/ -#define SSPP_SRC_SIZE_REC1 0x16C -#define SSPP_SRC_XY_REC1 0x168 -#define SSPP_OUT_SIZE_REC1 0x160 -#define SSPP_OUT_XY_REC1 0x164 -#define SSPP_SRC_FORMAT_REC1 0x174 -#define SSPP_SRC_UNPACK_PATTERN_REC1 0x178 -#define SSPP_SRC_OP_MODE_REC1 0x17C -#define SSPP_MULTIRECT_OPMODE 0x170 -#define SSPP_SRC_CONSTANT_COLOR_REC1 0x180 -#define SSPP_EXCL_REC_SIZE_REC1 0x184 -#define SSPP_EXCL_REC_XY_REC1 0x188 - -#define MDSS_MDP_OP_DEINTERLACE BIT(22) -#define MDSS_MDP_OP_DEINTERLACE_ODD BIT(23) -#define MDSS_MDP_OP_IGC_ROM_1 BIT(18) -#define MDSS_MDP_OP_IGC_ROM_0 BIT(17) -#define MDSS_MDP_OP_IGC_EN BIT(16) -#define MDSS_MDP_OP_FLIP_UD BIT(14) -#define MDSS_MDP_OP_FLIP_LR BIT(13) -#define MDSS_MDP_OP_BWC_EN BIT(0) -#define MDSS_MDP_OP_PE_OVERRIDE BIT(31) -#define MDSS_MDP_OP_BWC_LOSSLESS (0 << 1) -#define MDSS_MDP_OP_BWC_Q_HIGH (1 << 1) -#define MDSS_MDP_OP_BWC_Q_MED (2 << 1) - #define SSPP_SRC_CONSTANT_COLOR 0x3c #define SSPP_EXCL_REC_CTL 0x40 #define SSPP_UBWC_STATIC_CTRL 0x44 -#define SSPP_FETCH_CONFIG 0x048 +#define SSPP_FETCH_CONFIG 0x48 #define SSPP_DANGER_LUT 0x60 #define SSPP_SAFE_LUT 0x64 #define SSPP_CREQ_LUT 0x68 #define SSPP_QOS_CTRL 0x6C -#define SSPP_DECIMATION_CONFIG 0xB4 #define SSPP_SRC_ADDR_SW_STATUS 0x70 #define SSPP_CREQ_LUT_0 0x74 #define SSPP_CREQ_LUT_1 0x78 +#define SSPP_DECIMATION_CONFIG 0xB4 #define SSPP_SW_PIX_EXT_C0_LR 0x100 #define SSPP_SW_PIX_EXT_C0_TB 0x104 #define SSPP_SW_PIX_EXT_C0_REQ_PIXELS 0x108 @@ -81,11 +54,33 @@ #define SSPP_TRAFFIC_SHAPER_PREFILL 0x150 #define SSPP_TRAFFIC_SHAPER_REC1_PREFILL 0x154 #define SSPP_TRAFFIC_SHAPER_REC1 0x158 +#define SSPP_OUT_SIZE_REC1 0x160 +#define SSPP_OUT_XY_REC1 0x164 +#define SSPP_SRC_XY_REC1 0x168 +#define SSPP_SRC_SIZE_REC1 0x16C +#define SSPP_MULTIRECT_OPMODE 0x170 +#define SSPP_SRC_FORMAT_REC1 0x174 +#define SSPP_SRC_UNPACK_PATTERN_REC1 0x178 +#define SSPP_SRC_OP_MODE_REC1 0x17C +#define SSPP_SRC_CONSTANT_COLOR_REC1 0x180 +#define SSPP_EXCL_REC_SIZE_REC1 0x184 +#define SSPP_EXCL_REC_XY_REC1 0x188 #define SSPP_EXCL_REC_SIZE 0x1B4 #define SSPP_EXCL_REC_XY 0x1B8 -#define SSPP_VIG_OP_MODE 0x0 -#define SSPP_VIG_CSC_10_OP_MODE 0x0 -#define SSPP_TRAFFIC_SHAPER_BPC_MAX 0xFF + +/* SSPP_SRC_OP_MODE & OP_MODE_REC1 */ +#define MDSS_MDP_OP_DEINTERLACE BIT(22) +#define MDSS_MDP_OP_DEINTERLACE_ODD BIT(23) +#define MDSS_MDP_OP_IGC_ROM_1 BIT(18) +#define MDSS_MDP_OP_IGC_ROM_0 BIT(17) +#define MDSS_MDP_OP_IGC_EN BIT(16) +#define MDSS_MDP_OP_FLIP_UD BIT(14) +#define MDSS_MDP_OP_FLIP_LR BIT(13) +#define MDSS_MDP_OP_BWC_EN BIT(0) +#define MDSS_MDP_OP_PE_OVERRIDE BIT(31) +#define MDSS_MDP_OP_BWC_LOSSLESS (0 << 1) +#define MDSS_MDP_OP_BWC_Q_HIGH (1 << 1) +#define MDSS_MDP_OP_BWC_Q_MED (2 << 1) /* SSPP_QOS_CTRL */ #define SSPP_QOS_CTRL_VBLANK_EN BIT(16) @@ -96,6 +91,7 @@ #define SSPP_QOS_CTRL_CREQ_VBLANK_OFF 20 /* DPU_SSPP_SCALER_QSEED2 */ +#define SSPP_VIG_OP_MODE 0x0 #define SCALE_CONFIG 0x04 #define COMP0_3_PHASE_STEP_X 0x10 #define COMP0_3_PHASE_STEP_Y 0x14 @@ -107,6 +103,9 @@ #define COMP1_2_INIT_PHASE_Y 0x2C #define VIG_0_QSEED2_SHARP 0x30 +/* SSPP_TRAFFIC_SHAPER and _REC1 */ +#define SSPP_TRAFFIC_SHAPER_BPC_MAX 0xFF + /* * Definitions for ViG op modes */ @@ -128,6 +127,7 @@ /* * Definitions for CSC 10 op modes */ +#define SSPP_VIG_CSC_10_OP_MODE 0x0 #define VIG_CSC_10_SRC_DATAFMT BIT(1) #define VIG_CSC_10_EN BIT(0) #define CSC_10BIT_OFFSET 4 -- cgit v1.2.3 From 48b3207e4ed9e5140c69e229b697373f233419c8 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 19 May 2023 01:22:31 +0300 Subject: drm/msm/dpu: simplify CDP programming Get rid of intermediatory configuration structure and defines. Pass the format and the enablement bit directly to the new helper. The WB_CDP_CNTL register ignores BIT(2), so we can write it for both SSPP and WB CDP settings. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/537910/ Link: https://lore.kernel.org/r/20230518222238.3815293-3-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 17 ++++------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 17 ++++------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 14 ++++---------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 21 +++++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 19 +++---------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 19 ++++--------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 11 ++--------- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 16 +++------------- 8 files changed, 45 insertions(+), 89 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index bac4aa807b4b..e7b65f6f53d6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -140,7 +140,6 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); struct dpu_hw_wb *hw_wb; struct dpu_hw_wb_cfg *wb_cfg; - struct dpu_hw_cdp_cfg cdp_cfg; if (!phys_enc || !phys_enc->dpu_kms || !phys_enc->dpu_kms->catalog) { DPU_ERROR("invalid encoder\n"); @@ -163,18 +162,10 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, hw_wb->ops.setup_outformat(hw_wb, wb_cfg); if (hw_wb->ops.setup_cdp) { - memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg)); - - cdp_cfg.enable = phys_enc->dpu_kms->catalog->perf->cdp_cfg - [DPU_PERF_CDP_USAGE_NRT].wr_enable; - cdp_cfg.ubwc_meta_enable = - DPU_FORMAT_IS_UBWC(wb_cfg->dest.format); - cdp_cfg.tile_amortize_enable = - DPU_FORMAT_IS_UBWC(wb_cfg->dest.format) || - DPU_FORMAT_IS_TILE(wb_cfg->dest.format); - cdp_cfg.preload_ahead = DPU_WB_CDP_PRELOAD_AHEAD_64; - - hw_wb->ops.setup_cdp(hw_wb, &cdp_cfg); + const struct dpu_perf_cfg *perf = phys_enc->dpu_kms->catalog->perf; + + hw_wb->ops.setup_cdp(hw_wb, wb_cfg->dest.format, + perf->cdp_cfg[DPU_PERF_CDP_USAGE_NRT].wr_enable); } if (hw_wb->ops.setup_outaddress) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 08098880b7d5..78d928065b7b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -590,13 +590,13 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx, } static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe, - struct dpu_hw_cdp_cfg *cfg) + const struct dpu_format *fmt, + bool enable) { struct dpu_hw_sspp *ctx = pipe->sspp; - u32 cdp_cntl = 0; u32 cdp_cntl_offset = 0; - if (!ctx || !cfg) + if (!ctx) return; if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || @@ -605,16 +605,7 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe, else cdp_cntl_offset = SSPP_CDP_CNTL_REC1; - if (cfg->enable) - cdp_cntl |= BIT(0); - if (cfg->ubwc_meta_enable) - cdp_cntl |= BIT(1); - if (cfg->tile_amortize_enable) - cdp_cntl |= BIT(2); - if (cfg->preload_ahead == DPU_SSPP_CDP_PRELOAD_AHEAD_64) - cdp_cntl |= BIT(3); - - DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl); + dpu_setup_cdp(&ctx->hw, cdp_cntl_offset, fmt, enable); } static void _setup_layer_ops(struct dpu_hw_sspp *c, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 7a8d11ba618d..86bf4b2cda77 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -177,14 +177,6 @@ struct dpu_hw_pipe_qos_cfg { bool danger_safe_en; }; -/** - * enum CDP preload ahead address size - */ -enum { - DPU_SSPP_CDP_PRELOAD_AHEAD_32, - DPU_SSPP_CDP_PRELOAD_AHEAD_64 -}; - /** * struct dpu_hw_pipe_ts_cfg - traffic shaper configuration * @size: size to prefill in bytes, or zero to disable @@ -331,10 +323,12 @@ struct dpu_hw_sspp_ops { /** * setup_cdp - setup client driven prefetch * @pipe: Pointer to software pipe context - * @cfg: Pointer to cdp configuration + * @fmt: format used by the sw pipe + * @enable: whether the CDP should be enabled for this pipe */ void (*setup_cdp)(struct dpu_sw_pipe *pipe, - struct dpu_hw_cdp_cfg *cfg); + const struct dpu_format *fmt, + bool enable); }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c index 8062228eada6..95d20b9a3f2f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c @@ -494,3 +494,24 @@ int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, return 0; } + +#define CDP_ENABLE BIT(0) +#define CDP_UBWC_META_ENABLE BIT(1) +#define CDP_TILE_AMORTIZE_ENABLE BIT(2) +#define CDP_PRELOAD_AHEAD_64 BIT(3) + +void dpu_setup_cdp(struct dpu_hw_blk_reg_map *c, u32 offset, + const struct dpu_format *fmt, bool enable) +{ + u32 cdp_cntl = CDP_PRELOAD_AHEAD_64; + + if (enable) + cdp_cntl |= CDP_ENABLE; + if (DPU_FORMAT_IS_UBWC(fmt)) + cdp_cntl |= CDP_UBWC_META_ENABLE; + if (DPU_FORMAT_IS_UBWC(fmt) || + DPU_FORMAT_IS_TILE(fmt)) + cdp_cntl |= CDP_TILE_AMORTIZE_ENABLE; + + DPU_REG_WRITE(c, offset, cdp_cntl); +} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h index 27f4c39e35ab..dc6e3b795aef 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h @@ -305,22 +305,6 @@ struct dpu_drm_scaler_v2 { struct dpu_drm_de_v1 de; }; -/** - * struct dpu_hw_cdp_cfg : CDP configuration - * @enable: true to enable CDP - * @ubwc_meta_enable: true to enable ubwc metadata preload - * @tile_amortize_enable: true to enable amortization control for tile format - * @preload_ahead: number of request to preload ahead - * DPU_*_CDP_PRELOAD_AHEAD_32, - * DPU_*_CDP_PRELOAD_AHEAD_64 - */ -struct dpu_hw_cdp_cfg { - bool enable; - bool ubwc_meta_enable; - bool tile_amortize_enable; - u32 preload_ahead; -}; - u32 *dpu_hw_util_get_log_mask_ptr(void); void dpu_reg_write(struct dpu_hw_blk_reg_map *c, @@ -346,6 +330,9 @@ void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, u32 csc_reg_off, const struct dpu_csc_cfg *data, bool csc10); +void dpu_setup_cdp(struct dpu_hw_blk_reg_map *c, u32 offset, + const struct dpu_format *fmt, bool enable); + u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, u32 total_fl); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c index 4834866d72fd..a6de4b82a188 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -164,24 +164,13 @@ static void dpu_hw_wb_setup_qos_lut(struct dpu_hw_wb *ctx, } static void dpu_hw_wb_setup_cdp(struct dpu_hw_wb *ctx, - struct dpu_hw_cdp_cfg *cfg) + const struct dpu_format *fmt, + bool enable) { - struct dpu_hw_blk_reg_map *c; - u32 cdp_cntl = 0; - - if (!ctx || !cfg) + if (!ctx) return; - c = &ctx->hw; - - if (cfg->enable) - cdp_cntl |= BIT(0); - if (cfg->ubwc_meta_enable) - cdp_cntl |= BIT(1); - if (cfg->preload_ahead == DPU_WB_CDP_PRELOAD_AHEAD_64) - cdp_cntl |= BIT(3); - - DPU_REG_WRITE(c, WB_CDP_CNTL, cdp_cntl); + dpu_setup_cdp(&ctx->hw, WB_CDP_CNTL, fmt, enable); } static void dpu_hw_wb_bind_pingpong_blk( diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h index e4f85409c624..ab3541856258 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h @@ -21,14 +21,6 @@ struct dpu_hw_wb_cfg { struct drm_rect crop; }; -/** - * enum CDP preload ahead address size - */ -enum { - DPU_WB_CDP_PRELOAD_AHEAD_32, - DPU_WB_CDP_PRELOAD_AHEAD_64 -}; - /** * struct dpu_hw_wb_qos_cfg : Writeback pipe QoS configuration * @danger_lut: LUT for generate danger level based on fill level @@ -67,7 +59,8 @@ struct dpu_hw_wb_ops { struct dpu_hw_wb_qos_cfg *cfg); void (*setup_cdp)(struct dpu_hw_wb *ctx, - struct dpu_hw_cdp_cfg *cfg); + const struct dpu_format *fmt, + bool enable); void (*bind_pingpong_blk)(struct dpu_hw_wb *ctx, bool enable, const enum dpu_pingpong pp); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 14b5cfe30611..3b210320ea62 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1116,20 +1116,10 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, pipe->sspp->ops.setup_format(pipe, fmt, src_flags); if (pipe->sspp->ops.setup_cdp) { - struct dpu_hw_cdp_cfg cdp_cfg; + const struct dpu_perf_cfg *perf = pdpu->catalog->perf; - memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg)); - - cdp_cfg.enable = pdpu->catalog->perf->cdp_cfg - [DPU_PERF_CDP_USAGE_RT].rd_enable; - cdp_cfg.ubwc_meta_enable = - DPU_FORMAT_IS_UBWC(fmt); - cdp_cfg.tile_amortize_enable = - DPU_FORMAT_IS_UBWC(fmt) || - DPU_FORMAT_IS_TILE(fmt); - cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64; - - pipe->sspp->ops.setup_cdp(pipe, &cdp_cfg); + pipe->sspp->ops.setup_cdp(pipe, fmt, + perf->cdp_cfg[DPU_PERF_CDP_USAGE_RT].rd_enable); } } -- cgit v1.2.3 From 2defa907ed5018fb7520bc9c3dc224961df5eda9 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 19 May 2023 01:22:32 +0300 Subject: drm/msm/dpu: fix the condition for (not) applying QoS to CURSOR SSPP The function dpu_plane_sspp_update_pipe() contains code to skip enabling the QoS and OT limitis for CURSOR pipes. However all DPU since sdm845 repurpose DMA SSPP for the cursor planes because they lack the real CURSOR SSPP. Fix the condition to actually check that the plane is CURSOR or not. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/537911/ Link: https://lore.kernel.org/r/20230518222238.3815293-4-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 3b210320ea62..b8ed7247a6af 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1126,7 +1126,8 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, _dpu_plane_set_qos_lut(plane, pipe, fmt, pipe_cfg); _dpu_plane_set_danger_lut(plane, pipe, fmt); - if (plane->type != DRM_PLANE_TYPE_CURSOR) { + if (pipe->sspp->idx != SSPP_CURSOR0 && + pipe->sspp->idx != SSPP_CURSOR1) { _dpu_plane_set_qos_ctrl(plane, pipe, true, DPU_PLANE_QOS_PANIC_CTRL); _dpu_plane_set_ot_limit(plane, pipe, pipe_cfg, frame_rate); } -- cgit v1.2.3 From 78c2925de971095e45aad4359f040dbe547714bd Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 19 May 2023 01:22:33 +0300 Subject: drm/msm/dpu: rearrange QoS setting code Slightly rearrainge code in dpu_plane_sspp_update_pipe() to group QoS/LUT related functions. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/537906/ Link: https://lore.kernel.org/r/20230518222238.3815293-5-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index b8ed7247a6af..586f089756fa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1079,10 +1079,10 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, pipe->sspp->ops.setup_sourceaddress(pipe, layout); } - _dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL); - /* override for color fill */ if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) { + _dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL); + /* skip remaining processing on color fill */ return; } @@ -1125,12 +1125,14 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, _dpu_plane_set_qos_lut(plane, pipe, fmt, pipe_cfg); _dpu_plane_set_danger_lut(plane, pipe, fmt); + _dpu_plane_set_qos_ctrl(plane, pipe, + pipe->sspp->idx != SSPP_CURSOR0 && + pipe->sspp->idx != SSPP_CURSOR1, + DPU_PLANE_QOS_PANIC_CTRL); if (pipe->sspp->idx != SSPP_CURSOR0 && - pipe->sspp->idx != SSPP_CURSOR1) { - _dpu_plane_set_qos_ctrl(plane, pipe, true, DPU_PLANE_QOS_PANIC_CTRL); + pipe->sspp->idx != SSPP_CURSOR1) _dpu_plane_set_ot_limit(plane, pipe, pipe_cfg, frame_rate); - } if (pstate->needs_qos_remap) _dpu_plane_set_qos_remap(plane, pipe); -- cgit v1.2.3 From d5f86e50f0319966503cbd54a2116d838d5984bc Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 19 May 2023 01:22:34 +0300 Subject: drm/msm/dpu: drop DPU_PLANE_QOS_VBLANK_CTRL Drop support for DPU_PLANE_QOS_VBLANK_CTRL flag. It is not used both in upstream driver and in vendor SDE driver. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/537907/ Link: https://lore.kernel.org/r/20230518222238.3815293-6-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 ---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 8 -------- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 10 ---------- 3 files changed, 22 deletions(-) (limited to 'drivers/gpu/drm') 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 677048cc3b7d..6b1e8383d2c4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -374,8 +374,6 @@ struct dpu_caps { /** * struct dpu_sspp_sub_blks : SSPP sub-blocks * common: Pointer to common configurations shared by sub blocks - * @creq_vblank: creq priority during vertical blanking - * @danger_vblank: danger priority during vertical blanking * @maxdwnscale: max downscale ratio supported(without DECIMATION) * @maxupscale: maxupscale ratio supported * @smart_dma_priority: hw priority of rect1 of multirect pipe @@ -390,8 +388,6 @@ struct dpu_caps { * @dpu_rotation_cfg: inline rotation configuration */ struct dpu_sspp_sub_blks { - u32 creq_vblank; - u32 danger_vblank; u32 maxdwnscale; u32 maxupscale; u32 smart_dma_priority; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 78d928065b7b..dde02278e006 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -695,14 +695,6 @@ int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, 0400, debugfs_root, (u32 *) &cfg->clk_ctrl); - debugfs_create_x32("creq_vblank", - 0600, - debugfs_root, - (u32 *) &sblk->creq_vblank); - debugfs_create_x32("danger_vblank", - 0600, - debugfs_root, - (u32 *) &sblk->danger_vblank); return 0; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 586f089756fa..3cb891917b65 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -73,13 +73,11 @@ static const uint32_t qcom_compressed_supported_formats[] = { /** * enum dpu_plane_qos - Different qos configurations for each pipe * - * @DPU_PLANE_QOS_VBLANK_CTRL: Setup VBLANK qos for the pipe. * @DPU_PLANE_QOS_VBLANK_AMORTIZE: Enables Amortization within pipe. * this configuration is mutually exclusive from VBLANK_CTRL. * @DPU_PLANE_QOS_PANIC_CTRL: Setup panic for the pipe. */ enum dpu_plane_qos { - DPU_PLANE_QOS_VBLANK_CTRL = BIT(0), DPU_PLANE_QOS_VBLANK_AMORTIZE = BIT(1), DPU_PLANE_QOS_PANIC_CTRL = BIT(2), }; @@ -361,15 +359,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg)); - if (flags & DPU_PLANE_QOS_VBLANK_CTRL) { - pipe_qos_cfg.creq_vblank = pipe->sspp->cap->sblk->creq_vblank; - pipe_qos_cfg.danger_vblank = - pipe->sspp->cap->sblk->danger_vblank; - pipe_qos_cfg.vblank_en = enable; - } - if (flags & DPU_PLANE_QOS_VBLANK_AMORTIZE) { - /* this feature overrules previous VBLANK_CTRL */ pipe_qos_cfg.vblank_en = false; pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */ } -- cgit v1.2.3 From f68098003dc351c06e1aba1fbccddfbbf7fa2110 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 19 May 2023 01:22:35 +0300 Subject: drm/msm/dpu: simplify qos_ctrl handling After removal of DPU_PLANE_QOS_VBLANK_CTRL, several fields of struct dpu_hw_pipe_qos_cfg are fixed to false/0. Drop them from the structure (and drop the corresponding code from the functions). The DPU_PLANE_QOS_VBLANK_AMORTIZE flag is also removed, since it is now a NOP. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/537909/ Link: https://lore.kernel.org/r/20230518222238.3815293-7-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 10 ---------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 6 ------ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 17 ++--------------- 3 files changed, 2 insertions(+), 31 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index dde02278e006..925689dc77f0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -573,16 +573,6 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx, if (!ctx) return; - if (cfg->vblank_en) { - qos_ctrl |= ((cfg->creq_vblank & - SSPP_QOS_CTRL_CREQ_VBLANK_MASK) << - SSPP_QOS_CTRL_CREQ_VBLANK_OFF); - qos_ctrl |= ((cfg->danger_vblank & - SSPP_QOS_CTRL_DANGER_VBLANK_MASK) << - SSPP_QOS_CTRL_DANGER_VBLANK_OFF); - qos_ctrl |= SSPP_QOS_CTRL_VBLANK_EN; - } - if (cfg->danger_safe_en) qos_ctrl |= SSPP_QOS_CTRL_DANGER_SAFE_EN; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 86bf4b2cda77..aaf6f41d546c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -165,15 +165,9 @@ struct dpu_sw_pipe_cfg { /** * struct dpu_hw_pipe_qos_cfg : Source pipe QoS configuration - * @creq_vblank: creq value generated to vbif during vertical blanking - * @danger_vblank: danger value generated during vertical blanking - * @vblank_en: enable creq_vblank and danger_vblank during vblank * @danger_safe_en: enable danger safe generation */ struct dpu_hw_pipe_qos_cfg { - u32 creq_vblank; - u32 danger_vblank; - bool vblank_en; bool danger_safe_en; }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 3cb891917b65..0ed350776775 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -73,12 +73,9 @@ static const uint32_t qcom_compressed_supported_formats[] = { /** * enum dpu_plane_qos - Different qos configurations for each pipe * - * @DPU_PLANE_QOS_VBLANK_AMORTIZE: Enables Amortization within pipe. - * this configuration is mutually exclusive from VBLANK_CTRL. * @DPU_PLANE_QOS_PANIC_CTRL: Setup panic for the pipe. */ enum dpu_plane_qos { - DPU_PLANE_QOS_VBLANK_AMORTIZE = BIT(1), DPU_PLANE_QOS_PANIC_CTRL = BIT(2), }; @@ -359,25 +356,15 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg)); - if (flags & DPU_PLANE_QOS_VBLANK_AMORTIZE) { - pipe_qos_cfg.vblank_en = false; - pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */ - } - if (flags & DPU_PLANE_QOS_PANIC_CTRL) pipe_qos_cfg.danger_safe_en = enable; - if (!pdpu->is_rt_pipe) { - pipe_qos_cfg.vblank_en = false; + if (!pdpu->is_rt_pipe) pipe_qos_cfg.danger_safe_en = false; - } - DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d vb:%d pri[0x%x, 0x%x] is_rt:%d\n", + DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d is_rt:%d\n", pdpu->pipe - SSPP_VIG0, pipe_qos_cfg.danger_safe_en, - pipe_qos_cfg.vblank_en, - pipe_qos_cfg.creq_vblank, - pipe_qos_cfg.danger_vblank, pdpu->is_rt_pipe); pipe->sspp->ops.setup_qos_ctrl(pipe->sspp, -- cgit v1.2.3 From 9ccff1d2c062302fe20ebbdee1831d0933d32a04 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 19 May 2023 01:22:36 +0300 Subject: drm/msm/dpu: drop DPU_PLANE_QOS_PANIC_CTRL This flag is always passed to _dpu_plane_set_qos_ctrl(), so drop it and remove corresponding conditions from the mentioned function. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/537916/ Link: https://lore.kernel.org/r/20230518222238.3815293-8-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 0ed350776775..d1443c4b2915 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -70,15 +70,6 @@ static const uint32_t qcom_compressed_supported_formats[] = { DRM_FORMAT_P010, }; -/** - * enum dpu_plane_qos - Different qos configurations for each pipe - * - * @DPU_PLANE_QOS_PANIC_CTRL: Setup panic for the pipe. - */ -enum dpu_plane_qos { - DPU_PLANE_QOS_PANIC_CTRL = BIT(2), -}; - /* * struct dpu_plane - local dpu plane structure * @aspace: address space pointer @@ -349,15 +340,14 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane, */ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, struct dpu_sw_pipe *pipe, - bool enable, u32 flags) + bool enable) { struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_hw_pipe_qos_cfg pipe_qos_cfg; memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg)); - if (flags & DPU_PLANE_QOS_PANIC_CTRL) - pipe_qos_cfg.danger_safe_en = enable; + pipe_qos_cfg.danger_safe_en = enable; if (!pdpu->is_rt_pipe) pipe_qos_cfg.danger_safe_en = false; @@ -1058,7 +1048,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, /* override for color fill */ if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) { - _dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL); + _dpu_plane_set_qos_ctrl(plane, pipe, false); /* skip remaining processing on color fill */ return; @@ -1104,8 +1094,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, _dpu_plane_set_danger_lut(plane, pipe, fmt); _dpu_plane_set_qos_ctrl(plane, pipe, pipe->sspp->idx != SSPP_CURSOR0 && - pipe->sspp->idx != SSPP_CURSOR1, - DPU_PLANE_QOS_PANIC_CTRL); + pipe->sspp->idx != SSPP_CURSOR1); if (pipe->sspp->idx != SSPP_CURSOR0 && pipe->sspp->idx != SSPP_CURSOR1) @@ -1224,10 +1213,10 @@ static void dpu_plane_destroy(struct drm_plane *plane) if (pdpu) { pstate = to_dpu_plane_state(plane->state); - _dpu_plane_set_qos_ctrl(plane, &pstate->pipe, false, DPU_PLANE_QOS_PANIC_CTRL); + _dpu_plane_set_qos_ctrl(plane, &pstate->pipe, false); if (pstate->r_pipe.sspp) - _dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, false, DPU_PLANE_QOS_PANIC_CTRL); + _dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, false); mutex_destroy(&pdpu->lock); @@ -1384,9 +1373,9 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) return; pm_runtime_get_sync(&dpu_kms->pdev->dev); - _dpu_plane_set_qos_ctrl(plane, &pstate->pipe, enable, DPU_PLANE_QOS_PANIC_CTRL); + _dpu_plane_set_qos_ctrl(plane, &pstate->pipe, enable); if (pstate->r_pipe.sspp) - _dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, enable, DPU_PLANE_QOS_PANIC_CTRL); + _dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, enable); pm_runtime_put_sync(&dpu_kms->pdev->dev); } #endif -- cgit v1.2.3 From a5ebb27bffcc2c1e785abc6782202d9e4041e71c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 19 May 2023 01:22:37 +0300 Subject: drm/msm/dpu: remove struct dpu_hw_pipe_qos_cfg Now as the struct dpu_hw_pipe_qos_cfg consists of only one bool field, drop the structure and use corresponding bool directly. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/537918/ Link: https://lore.kernel.org/r/20230518222238.3815293-9-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 10 +++------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 13 ++----------- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +++-------- 3 files changed, 8 insertions(+), 26 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 925689dc77f0..1abe1eca4f42 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -566,17 +566,13 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_sspp *ctx, } static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx, - struct dpu_hw_pipe_qos_cfg *cfg) + bool danger_safe_en) { - u32 qos_ctrl = 0; - if (!ctx) return; - if (cfg->danger_safe_en) - qos_ctrl |= SSPP_QOS_CTRL_DANGER_SAFE_EN; - - DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL, qos_ctrl); + DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL, + danger_safe_en ? SSPP_QOS_CTRL_DANGER_SAFE_EN : 0); } static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index aaf6f41d546c..4278c421b6ac 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -163,14 +163,6 @@ struct dpu_sw_pipe_cfg { struct drm_rect dst_rect; }; -/** - * struct dpu_hw_pipe_qos_cfg : Source pipe QoS configuration - * @danger_safe_en: enable danger safe generation - */ -struct dpu_hw_pipe_qos_cfg { - bool danger_safe_en; -}; - /** * struct dpu_hw_pipe_ts_cfg - traffic shaper configuration * @size: size to prefill in bytes, or zero to disable @@ -285,11 +277,10 @@ struct dpu_hw_sspp_ops { /** * setup_qos_ctrl - setup QoS control * @ctx: Pointer to pipe context - * @cfg: Pointer to pipe QoS configuration - * + * @danger_safe_en: flags controlling enabling of danger/safe QoS/LUT */ void (*setup_qos_ctrl)(struct dpu_hw_sspp *ctx, - struct dpu_hw_pipe_qos_cfg *cfg); + bool danger_safe_en); /** * setup_histogram - setup histograms diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d1443c4b2915..c8837d0aa0c3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -343,22 +343,17 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, bool enable) { struct dpu_plane *pdpu = to_dpu_plane(plane); - struct dpu_hw_pipe_qos_cfg pipe_qos_cfg; - - memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg)); - - pipe_qos_cfg.danger_safe_en = enable; if (!pdpu->is_rt_pipe) - pipe_qos_cfg.danger_safe_en = false; + enable = false; DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d is_rt:%d\n", pdpu->pipe - SSPP_VIG0, - pipe_qos_cfg.danger_safe_en, + enable, pdpu->is_rt_pipe); pipe->sspp->ops.setup_qos_ctrl(pipe->sspp, - &pipe_qos_cfg); + enable); } /** -- cgit v1.2.3 From 5fe0faa62461adb578785169f29f3c4638ca4e9a Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 19 May 2023 01:22:38 +0300 Subject: drm/msm/dpu: use common helper for WB and SSPP QoS setup Rework SSPP and WB code to use common helper for programming QoS settings. Reviewed-by: Jeykumar Sankaran Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/537912/ Link: https://lore.kernel.org/r/20230518222238.3815293-10-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 4 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 31 ++------ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 19 +---- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 31 ++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 21 ++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 29 +------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 16 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 85 ++++++++-------------- 8 files changed, 100 insertions(+), 136 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index e7b65f6f53d6..023a9c4ad1db 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -102,7 +102,7 @@ static void dpu_encoder_phys_wb_set_qos_remap( static void dpu_encoder_phys_wb_set_qos(struct dpu_encoder_phys *phys_enc) { struct dpu_hw_wb *hw_wb; - struct dpu_hw_wb_qos_cfg qos_cfg; + struct dpu_hw_qos_cfg qos_cfg; const struct dpu_mdss_cfg *catalog; const struct dpu_qos_lut_tbl *qos_lut_tb; @@ -115,7 +115,7 @@ static void dpu_encoder_phys_wb_set_qos(struct dpu_encoder_phys *phys_enc) hw_wb = phys_enc->hw_wb; - memset(&qos_cfg, 0, sizeof(struct dpu_hw_wb_qos_cfg)); + memset(&qos_cfg, 0, sizeof(struct dpu_hw_qos_cfg)); qos_cfg.danger_safe_en = true; qos_cfg.danger_lut = catalog->perf->danger_lut_tbl[DPU_QOS_LUT_USAGE_NRT]; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 1abe1eca4f42..b364cf75bb3f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -539,30 +539,15 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color) color); } -static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_sspp *ctx, - u32 danger_lut, - u32 safe_lut) +static void dpu_hw_sspp_setup_qos_lut(struct dpu_hw_sspp *ctx, + struct dpu_hw_qos_cfg *cfg) { - if (!ctx) - return; - - DPU_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT, danger_lut); - DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT, safe_lut); -} - -static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_sspp *ctx, - u64 creq_lut) -{ - if (!ctx) + if (!ctx || !cfg) return; - if (ctx->cap && test_bit(DPU_SSPP_QOS_8LVL, &ctx->cap->features)) { - DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0, creq_lut); - DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_1, - creq_lut >> 32); - } else { - DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT, creq_lut); - } + _dpu_hw_setup_qos_lut(&ctx->hw, SSPP_DANGER_LUT, + test_bit(DPU_SSPP_QOS_8LVL, &ctx->cap->features), + cfg); } static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx, @@ -604,9 +589,7 @@ static void _setup_layer_ops(struct dpu_hw_sspp *c, c->ops.setup_pe = dpu_hw_sspp_setup_pe_config; if (test_bit(DPU_SSPP_QOS, &features)) { - c->ops.setup_danger_safe_lut = - dpu_hw_sspp_setup_danger_safe_lut; - c->ops.setup_creq_lut = dpu_hw_sspp_setup_creq_lut; + c->ops.setup_qos_lut = dpu_hw_sspp_setup_qos_lut; c->ops.setup_qos_ctrl = dpu_hw_sspp_setup_qos_ctrl; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 4278c421b6ac..085f34bc6b88 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -254,25 +254,14 @@ struct dpu_hw_sspp_ops { void (*setup_sharpening)(struct dpu_hw_sspp *ctx, struct dpu_hw_sharp_cfg *cfg); - /** - * setup_danger_safe_lut - setup danger safe LUTs - * @ctx: Pointer to pipe context - * @danger_lut: LUT for generate danger level based on fill level - * @safe_lut: LUT for generate safe level based on fill level - * - */ - void (*setup_danger_safe_lut)(struct dpu_hw_sspp *ctx, - u32 danger_lut, - u32 safe_lut); /** - * setup_creq_lut - setup CREQ LUT + * setup_qos_lut - setup QoS LUTs * @ctx: Pointer to pipe context - * @creq_lut: LUT for generate creq level based on fill level - * + * @cfg: LUT configuration */ - void (*setup_creq_lut)(struct dpu_hw_sspp *ctx, - u64 creq_lut); + void (*setup_qos_lut)(struct dpu_hw_sspp *ctx, + struct dpu_hw_qos_cfg *cfg); /** * setup_qos_ctrl - setup QoS control diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c index 95d20b9a3f2f..9d2273fd2fed 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c @@ -73,6 +73,19 @@ static u32 dpu_hw_util_log_mask = DPU_DBG_MASK_NONE; #define QSEED3LITE_SEP_LUT_SIZE \ (QSEED3LITE_LUT_SIZE * QSEED3LITE_SEPARABLE_LUTS * sizeof(u32)) +/* QOS_LUT */ +#define QOS_DANGER_LUT 0x00 +#define QOS_SAFE_LUT 0x04 +#define QOS_CREQ_LUT 0x08 +#define QOS_QOS_CTRL 0x0C +#define QOS_CREQ_LUT_0 0x14 +#define QOS_CREQ_LUT_1 0x18 + +/* QOS_QOS_CTRL */ +#define QOS_QOS_CTRL_DANGER_SAFE_EN BIT(0) +#define QOS_QOS_CTRL_DANGER_VBLANK_MASK GENMASK(5, 4) +#define QOS_QOS_CTRL_VBLANK_EN BIT(16) +#define QOS_QOS_CTRL_CREQ_VBLANK_MASK GENMASK(21, 20) void dpu_reg_write(struct dpu_hw_blk_reg_map *c, u32 reg_off, @@ -450,6 +463,24 @@ u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, return 0; } +void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset, + bool qos_8lvl, + const struct dpu_hw_qos_cfg *cfg) +{ + DPU_REG_WRITE(c, offset + QOS_DANGER_LUT, cfg->danger_lut); + DPU_REG_WRITE(c, offset + QOS_SAFE_LUT, cfg->safe_lut); + + if (qos_8lvl) { + DPU_REG_WRITE(c, offset + QOS_CREQ_LUT_0, cfg->creq_lut); + DPU_REG_WRITE(c, offset + QOS_CREQ_LUT_1, cfg->creq_lut >> 32); + } else { + DPU_REG_WRITE(c, offset + QOS_CREQ_LUT, cfg->creq_lut); + } + + DPU_REG_WRITE(c, offset + QOS_QOS_CTRL, + cfg->danger_safe_en ? QOS_QOS_CTRL_DANGER_SAFE_EN : 0); +} + void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, u32 misr_ctrl_offset, bool enable, u32 frame_count) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h index dc6e3b795aef..1f6079f47071 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h @@ -305,6 +305,23 @@ struct dpu_drm_scaler_v2 { struct dpu_drm_de_v1 de; }; +/** + * struct dpu_hw_qos_cfg: pipe QoS configuration + * @danger_lut: LUT for generate danger level based on fill level + * @safe_lut: LUT for generate safe level based on fill level + * @creq_lut: LUT for generate creq level based on fill level + * @creq_vblank: creq value generated to vbif during vertical blanking + * @danger_vblank: danger value generated during vertical blanking + * @vblank_en: enable creq_vblank and danger_vblank during vblank + * @danger_safe_en: enable danger safe generation + */ +struct dpu_hw_qos_cfg { + u32 danger_lut; + u32 safe_lut; + u64 creq_lut; + bool danger_safe_en; +}; + u32 *dpu_hw_util_get_log_mask_ptr(void); void dpu_reg_write(struct dpu_hw_blk_reg_map *c, @@ -336,6 +353,10 @@ void dpu_setup_cdp(struct dpu_hw_blk_reg_map *c, u32 offset, u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, u32 total_fl); +void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset, + bool qos_8lvl, + const struct dpu_hw_qos_cfg *cfg); + void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, u32 misr_ctrl_offset, bool enable, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c index a6de4b82a188..dcffd6cc47fc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -49,9 +49,6 @@ #define WB_OUT_IMAGE_SIZE 0x2C0 #define WB_OUT_XY 0x2C4 -/* WB_QOS_CTRL */ -#define WB_QOS_CTRL_DANGER_SAFE_EN BIT(0) - static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx, struct dpu_hw_wb_cfg *data) { @@ -135,32 +132,14 @@ static void dpu_hw_wb_roi(struct dpu_hw_wb *ctx, struct dpu_hw_wb_cfg *wb) } static void dpu_hw_wb_setup_qos_lut(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_qos_cfg *cfg) + struct dpu_hw_qos_cfg *cfg) { - struct dpu_hw_blk_reg_map *c = &ctx->hw; - u32 qos_ctrl = 0; - if (!ctx || !cfg) return; - DPU_REG_WRITE(c, WB_DANGER_LUT, cfg->danger_lut); - DPU_REG_WRITE(c, WB_SAFE_LUT, cfg->safe_lut); - - /* - * for chipsets not using DPU_WB_QOS_8LVL but still using DPU - * driver such as msm8998, the reset value of WB_CREQ_LUT is - * sufficient for writeback to work. SW doesn't need to explicitly - * program a value. - */ - if (ctx->caps && test_bit(DPU_WB_QOS_8LVL, &ctx->caps->features)) { - DPU_REG_WRITE(c, WB_CREQ_LUT_0, cfg->creq_lut); - DPU_REG_WRITE(c, WB_CREQ_LUT_1, cfg->creq_lut >> 32); - } - - if (cfg->danger_safe_en) - qos_ctrl |= WB_QOS_CTRL_DANGER_SAFE_EN; - - DPU_REG_WRITE(c, WB_QOS_CTRL, qos_ctrl); + _dpu_hw_setup_qos_lut(&ctx->hw, WB_DANGER_LUT, + test_bit(DPU_WB_QOS_8LVL, &ctx->caps->features), + cfg); } static void dpu_hw_wb_setup_cdp(struct dpu_hw_wb *ctx, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h index ab3541856258..c7f792eeb55c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h @@ -21,20 +21,6 @@ struct dpu_hw_wb_cfg { struct drm_rect crop; }; -/** - * struct dpu_hw_wb_qos_cfg : Writeback pipe QoS configuration - * @danger_lut: LUT for generate danger level based on fill level - * @safe_lut: LUT for generate safe level based on fill level - * @creq_lut: LUT for generate creq level based on fill level - * @danger_safe_en: enable danger safe generation - */ -struct dpu_hw_wb_qos_cfg { - u32 danger_lut; - u32 safe_lut; - u64 creq_lut; - bool danger_safe_en; -}; - /** * * struct dpu_hw_wb_ops : Interface to the wb hw driver functions @@ -56,7 +42,7 @@ struct dpu_hw_wb_ops { struct dpu_hw_wb_cfg *wb); void (*setup_qos_lut)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_qos_cfg *cfg); + struct dpu_hw_qos_cfg *cfg); void (*setup_cdp)(struct dpu_hw_wb *ctx, const struct dpu_format *fmt, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index c8837d0aa0c3..d66745115917 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -190,12 +190,14 @@ static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode, * _dpu_plane_calc_fill_level - calculate fill level of the given source format * @plane: Pointer to drm plane * @pipe: Pointer to software pipe + * @lut_usage: LUT usecase * @fmt: Pointer to source buffer format * @src_width: width of source buffer * Return: fill level corresponding to the source buffer/format or 0 if error */ static int _dpu_plane_calc_fill_level(struct drm_plane *plane, struct dpu_sw_pipe *pipe, + enum dpu_qos_lut_usage lut_usage, const struct dpu_format *fmt, u32 src_width) { struct dpu_plane *pdpu; @@ -207,6 +209,9 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane, return 0; } + if (lut_usage == DPU_QOS_LUT_USAGE_NRT) + return 0; + pdpu = to_dpu_plane(plane); fixed_buff_size = pdpu->catalog->caps->pixel_ram_size; @@ -252,83 +257,58 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, const struct dpu_format *fmt, struct dpu_sw_pipe_cfg *pipe_cfg) { struct dpu_plane *pdpu = to_dpu_plane(plane); - u64 qos_lut; - u32 total_fl = 0, lut_usage; + struct dpu_hw_qos_cfg cfg; + u32 total_fl, lut_usage; if (!pdpu->is_rt_pipe) { lut_usage = DPU_QOS_LUT_USAGE_NRT; } else { - total_fl = _dpu_plane_calc_fill_level(plane, pipe, fmt, - drm_rect_width(&pipe_cfg->src_rect)); - if (fmt && DPU_FORMAT_IS_LINEAR(fmt)) lut_usage = DPU_QOS_LUT_USAGE_LINEAR; else lut_usage = DPU_QOS_LUT_USAGE_MACROTILE; } - qos_lut = _dpu_hw_get_qos_lut( - &pdpu->catalog->perf->qos_lut_tbl[lut_usage], total_fl); + total_fl = _dpu_plane_calc_fill_level(plane, pipe, lut_usage, fmt, + drm_rect_width(&pipe_cfg->src_rect)); + + cfg.creq_lut = _dpu_hw_get_qos_lut(&pdpu->catalog->perf->qos_lut_tbl[lut_usage], total_fl); + cfg.danger_lut = pdpu->catalog->perf->danger_lut_tbl[lut_usage]; + cfg.safe_lut = pdpu->catalog->perf->safe_lut_tbl[lut_usage]; + + if (pipe->sspp->idx != SSPP_CURSOR0 && + pipe->sspp->idx != SSPP_CURSOR1 && + pdpu->is_rt_pipe) + cfg.danger_safe_en = true; + + DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d is_rt:%d\n", + pdpu->pipe - SSPP_VIG0, + cfg.danger_safe_en, + pdpu->is_rt_pipe); trace_dpu_perf_set_qos_luts(pipe->sspp->idx - SSPP_VIG0, (fmt) ? fmt->base.pixel_format : 0, - pdpu->is_rt_pipe, total_fl, qos_lut, lut_usage); + pdpu->is_rt_pipe, total_fl, cfg.creq_lut, lut_usage); DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s rt:%d fl:%u lut:0x%llx\n", pdpu->pipe - SSPP_VIG0, fmt ? (char *)&fmt->base.pixel_format : NULL, - pdpu->is_rt_pipe, total_fl, qos_lut); - - pipe->sspp->ops.setup_creq_lut(pipe->sspp, qos_lut); -} - -/** - * _dpu_plane_set_danger_lut - set danger/safe LUT of the given plane - * @plane: Pointer to drm plane - * @pipe: Pointer to software pipe - * @fmt: Pointer to source buffer format - */ -static void _dpu_plane_set_danger_lut(struct drm_plane *plane, - struct dpu_sw_pipe *pipe, - const struct dpu_format *fmt) -{ - struct dpu_plane *pdpu = to_dpu_plane(plane); - u32 danger_lut, safe_lut; - - if (!pdpu->is_rt_pipe) { - danger_lut = pdpu->catalog->perf->danger_lut_tbl - [DPU_QOS_LUT_USAGE_NRT]; - safe_lut = pdpu->catalog->perf->safe_lut_tbl - [DPU_QOS_LUT_USAGE_NRT]; - } else { - if (fmt && DPU_FORMAT_IS_LINEAR(fmt)) { - danger_lut = pdpu->catalog->perf->danger_lut_tbl - [DPU_QOS_LUT_USAGE_LINEAR]; - safe_lut = pdpu->catalog->perf->safe_lut_tbl - [DPU_QOS_LUT_USAGE_LINEAR]; - } else { - danger_lut = pdpu->catalog->perf->danger_lut_tbl - [DPU_QOS_LUT_USAGE_MACROTILE]; - safe_lut = pdpu->catalog->perf->safe_lut_tbl - [DPU_QOS_LUT_USAGE_MACROTILE]; - } - } + pdpu->is_rt_pipe, total_fl, cfg.creq_lut); trace_dpu_perf_set_danger_luts(pdpu->pipe - SSPP_VIG0, (fmt) ? fmt->base.pixel_format : 0, (fmt) ? fmt->fetch_mode : 0, - danger_lut, - safe_lut); + cfg.danger_lut, + cfg.safe_lut); DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s mode:%d luts[0x%x, 0x%x]\n", pdpu->pipe - SSPP_VIG0, fmt ? (char *)&fmt->base.pixel_format : NULL, fmt ? fmt->fetch_mode : -1, - danger_lut, - safe_lut); + cfg.danger_lut, + cfg.safe_lut); - pipe->sspp->ops.setup_danger_safe_lut(pipe->sspp, - danger_lut, safe_lut); + pipe->sspp->ops.setup_qos_lut(pipe->sspp, &cfg); } /** @@ -336,7 +316,6 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane, * @plane: Pointer to drm plane * @pipe: Pointer to software pipe * @enable: true to enable QoS control - * @flags: QoS control mode (enum dpu_plane_qos) */ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, struct dpu_sw_pipe *pipe, @@ -1086,10 +1065,6 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, } _dpu_plane_set_qos_lut(plane, pipe, fmt, pipe_cfg); - _dpu_plane_set_danger_lut(plane, pipe, fmt); - _dpu_plane_set_qos_ctrl(plane, pipe, - pipe->sspp->idx != SSPP_CURSOR0 && - pipe->sspp->idx != SSPP_CURSOR1); if (pipe->sspp->idx != SSPP_CURSOR0 && pipe->sspp->idx != SSPP_CURSOR1) -- cgit v1.2.3 From 6de6c28d97c02b5abdb208975cf392942e462424 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 20 May 2023 23:01:02 +0300 Subject: drm/msm/dsi: remove extra call to dsi_get_pclk_rate() In dsi_calc_clk_rate_v2() there is no need to call dsi_get_pclk_rate(). This function has just been called (from dsi_calc_pclk()) and its result is stored at msm_host->pixel_clk_rate. Use this variable directly. Reviewed-by: Marijn Suijten Signed-off-by: Dmitry Baryshkov Reviewed-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/538272/ Link: https://lore.kernel.org/r/20230520200103.4019607-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 961689a255c4..2b257b459974 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -633,7 +633,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi) dsi_calc_pclk(msm_host, is_bonded_dsi); - pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp; + pclk_bpp = (u64)msm_host->pixel_clk_rate * bpp; do_div(pclk_bpp, 8); msm_host->src_clk_rate = pclk_bpp; -- cgit v1.2.3 From 374918d2c396c7099c4bcd04ee044e8b0456afce Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 20 May 2023 23:01:03 +0300 Subject: drm/msm/dsi: use mult_frac for pclk_bpp calculation Simplify calculations around pixel_clk_rate division. Replace common pattern of doing 64-bit multiplication and then a do_div() call with simpler mult_frac() invocation. Reviewed-by: Marijn Suijten Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/538273/ Link: https://lore.kernel.org/r/20230520200103.4019607-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 2b257b459974..744f2398a6d6 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -585,7 +585,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d u8 lanes = msm_host->lanes; u32 bpp = dsi_get_bpp(msm_host->format); unsigned long pclk_rate = dsi_get_pclk_rate(mode, is_bonded_dsi); - u64 pclk_bpp = (u64)pclk_rate * bpp; + unsigned long pclk_bpp; if (lanes == 0) { pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__); @@ -594,9 +594,9 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d /* CPHY "byte_clk" is in units of 16 bits */ if (msm_host->cphy_mode) - do_div(pclk_bpp, (16 * lanes)); + pclk_bpp = mult_frac(pclk_rate, bpp, 16 * lanes); else - do_div(pclk_bpp, (8 * lanes)); + pclk_bpp = mult_frac(pclk_rate, bpp, 8 * lanes); return pclk_bpp; } @@ -627,15 +627,12 @@ int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi) int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { u32 bpp = dsi_get_bpp(msm_host->format); - u64 pclk_bpp; unsigned int esc_mhz, esc_div; unsigned long byte_mhz; dsi_calc_pclk(msm_host, is_bonded_dsi); - pclk_bpp = (u64)msm_host->pixel_clk_rate * bpp; - do_div(pclk_bpp, 8); - msm_host->src_clk_rate = pclk_bpp; + msm_host->src_clk_rate = mult_frac(msm_host->pixel_clk_rate, bpp, 8); /* * esc clock is byte clock followed by a 4 bit divider, -- cgit v1.2.3 From 95666ca7431c0217ce65d932526c0dbe32f85265 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 21 May 2023 22:22:28 +0300 Subject: drm/msm/dpu: drop dpu_encoder_phys_ops::late_register() This callback has been unused since the driver being added. Drop it now. Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/538302/ Link: https://lore.kernel.org/r/20230521192230.9747-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 7 ------- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 --- 2 files changed, 10 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 1dc5dbe58572..c771383446f2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2115,7 +2115,6 @@ DEFINE_SHOW_ATTRIBUTE(_dpu_encoder_status); static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); - int i; char name[DPU_NAME_SIZE]; @@ -2134,12 +2133,6 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) debugfs_create_file("status", 0600, dpu_enc->debugfs_root, dpu_enc, &_dpu_encoder_status_fops); - for (i = 0; i < dpu_enc->num_phys_encs; i++) - if (dpu_enc->phys_encs[i]->ops.late_register) - dpu_enc->phys_encs[i]->ops.late_register( - dpu_enc->phys_encs[i], - dpu_enc->debugfs_root); - return 0; } #else diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 1d434b22180d..9e29079a6fc4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -63,7 +63,6 @@ struct dpu_encoder_phys; /** * struct dpu_encoder_phys_ops - Interface the physical encoders provide to * the containing virtual encoder. - * @late_register: DRM Call. Add Userspace interfaces, debugfs. * @prepare_commit: MSM Atomic Call, start of atomic commit sequence * @is_master: Whether this phys_enc is the current master * encoder. Can be switched at enable time. Based @@ -93,8 +92,6 @@ struct dpu_encoder_phys; */ struct dpu_encoder_phys_ops { - int (*late_register)(struct dpu_encoder_phys *encoder, - struct dentry *debugfs_root); void (*prepare_commit)(struct dpu_encoder_phys *encoder); bool (*is_master)(struct dpu_encoder_phys *encoder); void (*atomic_mode_set)(struct dpu_encoder_phys *encoder, -- cgit v1.2.3 From a659098d78d607c150a45276b6e9726f43646619 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 21 May 2023 22:22:29 +0300 Subject: drm/msm/dpu: drop (mostly) unused DPU_NAME_SIZE define This define is used only in one place, in dpu_encoder debugfs code. Inline the value and drop the define completely. Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/538303/ Link: https://lore.kernel.org/r/20230521192230.9747-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 -- 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index c771383446f2..af34932729db 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2116,14 +2116,14 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); - char name[DPU_NAME_SIZE]; + char name[12]; if (!drm_enc->dev) { DPU_ERROR("invalid encoder or kms\n"); return -EINVAL; } - snprintf(name, DPU_NAME_SIZE, "encoder%u", drm_enc->base.id); + snprintf(name, sizeof(name), "encoder%u", drm_enc->base.id); /* create overall sub-directory for the encoder */ dpu_enc->debugfs_root = debugfs_create_dir(name, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index aca39a4689f4..197f352fe89b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -63,8 +63,6 @@ #define ktime_compare_safe(A, B) \ ktime_compare(ktime_sub((A), (B)), ktime_set(0, 0)) -#define DPU_NAME_SIZE 12 - struct dpu_kms { struct msm_kms base; struct drm_device *dev; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 14b5cfe30611..ac75ba13aa01 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -42,8 +42,6 @@ #define SHARP_SMOOTH_THR_DEFAULT 8 #define SHARP_NOISE_THR_DEFAULT 2 -#define DPU_NAME_SIZE 12 - #define DPU_PLANE_COLOR_FILL_FLAG BIT(31) #define DPU_ZPOS_MAX 255 -- cgit v1.2.3 From 4fb5ad612c5cb1dfc72bd6bb9150d0112bfb0d27 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 22 May 2023 21:17:01 +0200 Subject: drm/msm: Use struct fb_info.screen_buffer The fbdev framebuffer is in system memory. Store the address in the field 'screen_buffer'. Fixes the following sparse warning. ../drivers/gpu/drm/msm/msm_fbdev.c:124:26: warning: incorrect type in assignment (different address spaces) ../drivers/gpu/drm/msm/msm_fbdev.c:124:26: expected char [noderef] __iomem *screen_base ../drivers/gpu/drm/msm/msm_fbdev.c:124:26: got void * Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/538531/ Link: https://lore.kernel.org/r/20230522191701.13406-1-tzimmermann@suse.de Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_fbdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 2ebc86381e1c..ce0ba6d1979a 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -121,9 +121,9 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, drm_fb_helper_fill_info(fbi, helper, sizes); - fbi->screen_base = msm_gem_get_vaddr(bo); - if (IS_ERR(fbi->screen_base)) { - ret = PTR_ERR(fbi->screen_base); + fbi->screen_buffer = msm_gem_get_vaddr(bo); + if (IS_ERR(fbi->screen_buffer)) { + ret = PTR_ERR(fbi->screen_buffer); goto fail; } fbi->screen_size = bo->size; -- cgit v1.2.3 From 12cef323c903bd8b13d1f6ff24a9695c2cdc360b Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Thu, 25 May 2023 10:40:49 -0700 Subject: drm/msm/dpu: set DSC flush bit correctly at MDP CTL flush register The CTL_FLUSH register should be programmed with the 22th bit (DSC_IDX) to flush the DSC hardware blocks, not the literal value of 22 (which corresponds to flushing VIG1, VIG2 and RGB1 instead). Changes in V12: -- split this patch out of "separate DSC flush update out of interface" Changes in V13: -- rewording the commit text Changes in V14: -- drop 'DSC" from "The DSC CTL_FLUSH register" at commit text Fixes: 77f6da90487c ("drm/msm/disp/dpu1: Add DSC support in hw_ctl") Signed-off-by: Kuogee Hsieh Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/539496/ Link: https://lore.kernel.org/r/1685036458-22683-2-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 07bcacedf4b0..231737e92c77 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -519,7 +519,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); if (cfg->dsc) { - DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, DSC_IDX); + DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, BIT(DSC_IDX)); DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); } } -- cgit v1.2.3 From c20c44403e11d572c1adebf557c64017fd9868fd Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Thu, 25 May 2023 10:40:51 -0700 Subject: drm/msm/dpu: add DPU_PINGPONG_DSC feature bit for DPU < 7.0.0 DPU < 7.0.0 requires the PINGPONG block to be involved during DSC setting up. Since DPU >= 7.0.0, enabling and starting the DSC encoder engine was moved to INTF with the help of the flush mechanism. Add a DPU_PINGPONG_DSC feature bit to restrict the availability of dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() on the PINGPONG block to DPU < 7.0.0 hardware, as the registers are not available on DPU 7.0.0 and higher anymore. Add DPU_PINGPONG_DSC to PINGPONG_SDM845_MASK, PINGPONG_SDM845_TE2_MASK and PINGPONG_SM8150_MASK which is used for all DPU < 7.0 chipsets. changes in v6: -- split patches and rearrange to keep catalog related files at this patch changes in v7: -- rewording commit text as suggested at review comments changes in v9: -- delete BIT(DPU_PINGPONG_DSC) from PINGPONG_SDM845_TE2_MASK changes in v10: -- correct order of commit text Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/539502/ Link: https://lore.kernel.org/r/1685036458-22683-4-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 1dee5ba2b312..f07eab738008 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -76,13 +76,13 @@ (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) #define PINGPONG_SDM845_MASK \ - (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE)) + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE) | BIT(DPU_PINGPONG_DSC)) #define PINGPONG_SDM845_TE2_MASK \ (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) #define PINGPONG_SM8150_MASK \ - (BIT(DPU_PINGPONG_DITHER)) + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) #define CTL_SC7280_MASK \ (BIT(DPU_CTL_ACTIVE_CFG) | \ 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 6b1e8383d2c4..d59a9027c4b6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -140,7 +140,8 @@ enum { * @DPU_PINGPONG_TE2 Additional tear check block for split pipes * @DPU_PINGPONG_SPLIT PP block supports split fifo * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo - * @DPU_PINGPONG_DITHER, Dither blocks + * @DPU_PINGPONG_DITHER Dither blocks + * @DPU_PINGPONG_DSC PP block supports DSC * @DPU_PINGPONG_MAX */ enum { @@ -149,6 +150,7 @@ enum { DPU_PINGPONG_SPLIT, DPU_PINGPONG_SLAVE, DPU_PINGPONG_DITHER, + DPU_PINGPONG_DSC, DPU_PINGPONG_MAX }; -- cgit v1.2.3 From 108ff1417795eb991ce5c3af77c119e0841136f2 Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Thu, 25 May 2023 10:40:52 -0700 Subject: drm/msm/dpu: Guard PINGPONG DSC ops behind DPU_PINGPONG_DSC bit DPU < 7.0.0 has DPU_PINGPONG_DSC feature bit set to indicate it requires both dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() to be executed to complete DSC configuration if DSC hardware block is present. Hence test DPU_PINGPONG_DSC feature bit and assign DSC related functions to the ops of PINGPONG block accordingly if DPU_PINGPONG_DSC bit is set. Changes in v6: -- split patches, this patch has function handles DPU_PINGPONG_DSC bit Changes in v9: -- the original code of assigning dsc related functions to the ops of pingpong block without testing the DPU_PINGPONG_DSC feature bit was restored back due to rebase error which defeat the purpose of this patch. Remove those error code. Changes in v10: -- change commit title -- correct texts at changes in v9 Changes in v12: -- fixed length too long at Changes in v9 Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/539504/ Link: https://lore.kernel.org/r/1685036458-22683-5-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index 79e45768eae5..437d9e62a841 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -291,9 +291,12 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, c->ops.get_line_count = dpu_hw_pp_get_line_count; c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; } - c->ops.setup_dsc = dpu_hw_pp_setup_dsc; - c->ops.enable_dsc = dpu_hw_pp_dsc_enable; - c->ops.disable_dsc = dpu_hw_pp_dsc_disable; + + if (test_bit(DPU_PINGPONG_DSC, &features)) { + c->ops.setup_dsc = dpu_hw_pp_setup_dsc; + c->ops.enable_dsc = dpu_hw_pp_dsc_enable; + c->ops.disable_dsc = dpu_hw_pp_dsc_disable; + } if (test_bit(DPU_PINGPONG_DITHER, &features)) c->ops.setup_dither = dpu_hw_pp_setup_dither; -- cgit v1.2.3 From d45be1ccd3303201e8f7c28aefe28e6e4b168ab8 Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Thu, 25 May 2023 10:40:53 -0700 Subject: drm/msm/dpu: Introduce PINGPONG_NONE to disconnect DSC from PINGPONG Disabling the crossbar mux between DSC and PINGPONG currently requires a bogus enum dpu_pingpong value to be passed when calling dsc_bind_pingpong_blk() with enable=false, even though the register value written is independent of the current PINGPONG block. Replace that `bool enable` parameter with a new PINGPONG_NONE dpu_pingpong flag that triggers the write of the "special" 0xF "crossbar disabled" value to the register instead. Changes in v4: -- more details to commit text Changes in v5: -- rewording commit text suggested by Marijn -- add DRM_DEBUG_KMS for DSC unbinding case Changes in v8: -- fix checkpatch warning Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/539505/ Link: https://lore.kernel.org/r/1685036458-22683-6-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 14 +++++++------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index d7cd4734dc7d..9e0b6302ce23 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1850,7 +1850,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, hw_pp->ops.setup_dsc(hw_pp); if (hw_dsc->ops.dsc_bind_pingpong_blk) - hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, true, hw_pp->idx); + hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, hw_pp->idx); if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 89e1a9f945c7..64847912a20f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -154,7 +154,6 @@ static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc, static void dpu_hw_dsc_bind_pingpong_blk( struct dpu_hw_dsc *hw_dsc, - bool enable, const enum dpu_pingpong pp) { struct dpu_hw_blk_reg_map *c = &hw_dsc->hw; @@ -163,14 +162,15 @@ static void dpu_hw_dsc_bind_pingpong_blk( dsc_ctl_offset = DSC_CTL(hw_dsc->idx); - if (enable) + if (pp) mux_cfg = (pp - PINGPONG_0) & 0x7; - DRM_DEBUG_KMS("%s dsc:%d %s pp:%d\n", - enable ? "Binding" : "Unbinding", - hw_dsc->idx - DSC_0, - enable ? "to" : "from", - pp - PINGPONG_0); + if (pp) + DRM_DEBUG_KMS("Binding dsc:%d to pp:%d\n", + hw_dsc->idx - DSC_0, pp - PINGPONG_0); + else + DRM_DEBUG_KMS("Unbinding dsc:%d from any pp\n", + hw_dsc->idx - DSC_0); DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 287ec5f1e170..138080aed9dd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -44,7 +44,6 @@ struct dpu_hw_dsc_ops { struct drm_dsc_config *dsc); void (*dsc_bind_pingpong_blk)(struct dpu_hw_dsc *hw_dsc, - bool enable, enum dpu_pingpong pp); }; -- cgit v1.2.3 From 625cbb077007698060b12d0ae5657a4d8411b153 Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Thu, 25 May 2023 10:40:55 -0700 Subject: drm/msm/dpu: always clear every individual pending flush mask There are two tiers of pending flush control, top level and individual hardware block. Currently only the top level of flush mask is reset to 0 but the individual pending flush masks of particular hardware blocks are left at their previous values, eventually accumulating all possible bit values and typically flushing more than necessary. Reset all individual hardware block flush masks to 0 to avoid accidentally flushing them. Changes in V13: -- rewording commit text -- add an empty space line as suggested Changes in V14: -- add Fixes tag Fixes: 73bfb790ac78 ("msm:disp:dpu1: setup display datapath for SC7180 target") Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/539508/ Link: https://lore.kernel.org/r/1685036458-22683-8-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 231737e92c77..911848bc0c85 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -100,6 +100,9 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask, dpu_hw_ctl_get_flush_register(ctx)); ctx->pending_flush_mask = 0x0; + ctx->pending_intf_flush_mask = 0; + ctx->pending_wb_flush_mask = 0; + ctx->pending_merge_3d_flush_mask = 0; memset(ctx->pending_dspp_flush_mask, 0, sizeof(ctx->pending_dspp_flush_mask)); -- cgit v1.2.3 From 761c629d186009517477a0c415ecfbff3063ecbb Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Thu, 25 May 2023 10:40:56 -0700 Subject: drm/msm/dpu: separate DSC flush update out of interface Currently DSC flushing happens during interface configuration at dpu_hw_ctl_intf_cfg_v1(). Separate DSC flush away from dpu_hw_ctl_intf_cfg_v1() by adding dpu_hw_ctl_update_pending_flush_dsc_v1() to handle both per-DSC engine and DSC flush bits at same time to make it consistent with the location of flush programming of other DPU sub-blocks. Changes in v10: -- rewording commit text -- pass ctl directly instead of dpu_enc to dsc_pipe_cfg() -- ctx->pending_dsc_flush_mask = 0; Changes in v11: -- add Fixes tag Changes in v12: -- move dsc parameter to next line at dpu_encoder_dsc_pipe_cfg() Changes in v14: -- Fixes tag had been move to 1st patch of this series Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/539506/ Link: https://lore.kernel.org/r/1685036458-22683-9-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 ++++++++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 23 +++++++++++++++++------ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 11 +++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 9e0b6302ce23..95b2bd9cc7ab 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1834,7 +1834,8 @@ dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc, return DIV_ROUND_UP(total_pixels, dsc->slice_width); } -static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, +static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_ctl *ctl, + struct dpu_hw_dsc *hw_dsc, struct dpu_hw_pingpong *hw_pp, struct drm_dsc_config *dsc, u32 common_mode, @@ -1854,6 +1855,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); + + if (ctl->ops.update_pending_flush_dsc) + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); } static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, @@ -1861,6 +1865,7 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, { /* coding only for 2LM, 2enc, 1 dsc config */ struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; + struct dpu_hw_ctl *ctl = enc_master->hw_ctl; struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; int this_frame_slices; @@ -1898,7 +1903,8 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) - dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], dsc, dsc_common_mode, initial_lines); + dpu_encoder_dsc_pipe_cfg(ctl, hw_dsc[i], hw_pp[i], + dsc, dsc_common_mode, initial_lines); } void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 911848bc0c85..0007d14cecda 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -103,6 +103,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) ctx->pending_intf_flush_mask = 0; ctx->pending_wb_flush_mask = 0; ctx->pending_merge_3d_flush_mask = 0; + ctx->pending_dsc_flush_mask = 0; memset(ctx->pending_dspp_flush_mask, 0, sizeof(ctx->pending_dspp_flush_mask)); @@ -142,6 +143,11 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) CTL_DSPP_n_FLUSH(dspp - DSPP_0), ctx->pending_dspp_flush_mask[dspp - DSPP_0]); } + + if (ctx->pending_flush_mask & BIT(DSC_IDX)) + DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, + ctx->pending_dsc_flush_mask); + DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); } @@ -288,6 +294,13 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx, ctx->pending_flush_mask |= BIT(MERGE_3D_IDX); } +static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx, + enum dpu_dsc dsc_num) +{ + ctx->pending_dsc_flush_mask |= BIT(dsc_num - DSC_0); + ctx->pending_flush_mask |= BIT(DSC_IDX); +} + static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, enum dpu_dspp dspp, u32 dspp_sub_blk) { @@ -499,9 +512,6 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features))) mode_sel = CTL_DEFAULT_GROUP_ID << 28; - if (cfg->dsc) - DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, cfg->dsc); - if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD) mode_sel |= BIT(17); @@ -521,10 +531,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if (cfg->merge_3d) DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); - if (cfg->dsc) { - DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, BIT(DSC_IDX)); + + if (cfg->dsc) DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); - } } static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, @@ -627,6 +636,8 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->update_pending_flush_merge_3d = dpu_hw_ctl_update_pending_flush_merge_3d_v1; ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1; + ops->update_pending_flush_dsc = + dpu_hw_ctl_update_pending_flush_dsc_v1; } else { ops->trigger_flush = dpu_hw_ctl_trigger_flush; ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index 6292002faba2..1c242298ff2e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -157,6 +157,15 @@ struct dpu_hw_ctl_ops { void (*update_pending_flush_dspp)(struct dpu_hw_ctl *ctx, enum dpu_dspp blk, u32 dspp_sub_blk); + /** + * OR in the given flushbits to the cached pending_(dsc_)flush_mask + * No effect on hardware + * @ctx: ctl path ctx pointer + * @blk: interface block index + */ + void (*update_pending_flush_dsc)(struct dpu_hw_ctl *ctx, + enum dpu_dsc blk); + /** * Write the value of the pending_flush_mask to hardware * @ctx : ctl path ctx pointer @@ -229,6 +238,7 @@ struct dpu_hw_ctl_ops { * @pending_flush_mask: storage for pending ctl_flush managed via ops * @pending_intf_flush_mask: pending INTF flush * @pending_wb_flush_mask: pending WB flush + * @pending_dsc_flush_mask: pending DSC flush * @ops: operation list */ struct dpu_hw_ctl { @@ -245,6 +255,7 @@ struct dpu_hw_ctl { u32 pending_wb_flush_mask; u32 pending_merge_3d_flush_mask; u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0]; + u32 pending_dsc_flush_mask; /* ops */ struct dpu_hw_ctl_ops ops; -- cgit v1.2.3 From 997ed53dd69379d266fee206774e1c6b1244c178 Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Thu, 25 May 2023 10:40:58 -0700 Subject: drm/msm/dpu: Tear down DSC datapath on encoder cleanup Unset DSC_ACTIVE bit at dpu_hw_ctl_reset_intf_cfg_v1(), dpu_encoder_unprep_dsc() and dpu_encoder_dsc_pipe_clr() functions to tear down DSC data path if DSC data path was setup previous. Changes in V10: -- pass ctl directly instead of dpu_enc to dsc_pipe_cfg() -- move both dpu_encoder_unprep_dsc() and dpu_encoder_dsc_pipe_clr() to above phys_cleanup() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/539515/ Link: https://lore.kernel.org/r/1685036458-22683-11-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 39 +++++++++++++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 7 ++++++ 2 files changed, 46 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 95b2bd9cc7ab..2c9af33c0911 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2036,6 +2036,41 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc) } } +static void dpu_encoder_dsc_pipe_clr(struct dpu_hw_ctl *ctl, + struct dpu_hw_dsc *hw_dsc, + struct dpu_hw_pingpong *hw_pp) +{ + if (hw_dsc->ops.dsc_disable) + hw_dsc->ops.dsc_disable(hw_dsc); + + if (hw_pp->ops.disable_dsc) + hw_pp->ops.disable_dsc(hw_pp); + + if (hw_dsc->ops.dsc_bind_pingpong_blk) + hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, PINGPONG_NONE); + + if (ctl->ops.update_pending_flush_dsc) + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); +} + +static void dpu_encoder_unprep_dsc(struct dpu_encoder_virt *dpu_enc) +{ + /* coding only for 2LM, 2enc, 1 dsc config */ + struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; + struct dpu_hw_ctl *ctl = enc_master->hw_ctl; + struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; + struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; + int i; + + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + hw_pp[i] = dpu_enc->hw_pp[i]; + hw_dsc[i] = dpu_enc->hw_dsc[i]; + + if (hw_pp[i] && hw_dsc[i]) + dpu_encoder_dsc_pipe_clr(ctl, hw_dsc[i], hw_pp[i]); + } +} + void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) { struct dpu_hw_ctl *ctl = phys_enc->hw_ctl; @@ -2086,8 +2121,12 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) phys_enc->hw_pp->merge_3d->idx); } + if (dpu_enc->dsc) + dpu_encoder_unprep_dsc(dpu_enc); + intf_cfg.stream_sel = 0; /* Don't care value for video mode */ intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); + intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); if (phys_enc->hw_intf) intf_cfg.intf = phys_enc->hw_intf->idx; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 0007d14cecda..c278fb9d2b5b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -576,6 +576,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, u32 intf_active = 0; u32 wb_active = 0; u32 merge3d_active = 0; + u32 dsc_active; /* * This API resets each portion of the CTL path namely, @@ -605,6 +606,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, wb_active &= ~BIT(cfg->wb - WB_0); DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); } + + if (cfg->dsc) { + dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE); + dsc_active &= ~cfg->dsc; + DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); + } } static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, -- cgit v1.2.3 From 025e3d97867c55e4519edde2fda9363b9a4da795 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 26 May 2023 14:51:59 +0300 Subject: drm/msm/dpu: clean up dpu_kms_get_clk_rate() returns Static analysis tools complain about the -EINVAL error code being stored in an unsigned variable. Let's change this to match the clk_get_rate() function which is type unsigned long and returns zero on error. Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Dan Carpenter Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/539626/ Link: https://lore.kernel.org/r/28644c5e-950e-41cd-8389-67f37b067bdc@kili.mountain Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 8ce057cc9374..7f87ac6d68ac 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1023,13 +1023,13 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) return 0; } -u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name) +unsigned long dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name) { struct clk *clk; clk = msm_clk_bulk_get_clock(dpu_kms->clocks, dpu_kms->num_clocks, clock_name); if (!clk) - return -EINVAL; + return 0; return clk_get_rate(clk); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index cd6287524557..781034286537 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -205,6 +205,6 @@ void dpu_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); * * Return: current clock rate */ -u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name); +unsigned long dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name); #endif /* __dpu_kms_H__ */ -- cgit v1.2.3 From eea9cf72b718b1d2c935f2be2610d05e7527f2d8 Mon Sep 17 00:00:00 2001 From: Su Hui Date: Mon, 22 May 2023 09:32:13 +0800 Subject: drm/msm: Remove unnecessary (void*) conversions Pointer variables of (void*) type do not require type cast. Signed-off-by: Su Hui Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/540599/ Link: https://lore.kernel.org/r/20230522013213.25876-1-suhui@nfschina.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/adreno/a5xx_debugfs.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 2 +- drivers/gpu/drm/msm/msm_debugfs.c | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c index 6bd397a85834..169b8fe688f8 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c @@ -69,7 +69,7 @@ static void roq_print(struct msm_gpu *gpu, struct drm_printer *p) static int show(struct seq_file *m, void *arg) { - struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct msm_drm_private *priv = dev->dev_private; struct drm_printer p = drm_seq_file_printer(m); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index cc66ddffe672..6e684a7b49a1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1392,7 +1392,7 @@ DEFINE_SHOW_ATTRIBUTE(_dpu_debugfs_status); static int dpu_crtc_debugfs_state_show(struct seq_file *s, void *v) { - struct drm_crtc *crtc = (struct drm_crtc *) s->private; + struct drm_crtc *crtc = s->private; struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); seq_printf(s, "client type: %d\n", dpu_crtc_get_client_type(crtc)); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 0e7a68714e9e..3b307ce637a6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -57,8 +57,8 @@ static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms); static int _dpu_danger_signal_status(struct seq_file *s, bool danger_status) { - struct dpu_kms *kms = (struct dpu_kms *)s->private; struct dpu_danger_safe_status status; + struct dpu_kms *kms = s->private; int i; if (!kms->hw_mdp) { diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 29ae5c9613f3..323079cfd698 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -229,7 +229,7 @@ static void mdp5_kms_destroy(struct msm_kms *kms) #ifdef CONFIG_DEBUG_FS static int smp_show(struct seq_file *m, void *arg) { - struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct msm_drm_private *priv = dev->dev_private; struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 9c0e633a3a61..a0a936f80ae3 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -211,7 +211,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(shrink_fops, static int msm_gem_show(struct seq_file *m, void *arg) { - struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct msm_drm_private *priv = dev->dev_private; int ret; @@ -229,7 +229,7 @@ static int msm_gem_show(struct seq_file *m, void *arg) static int msm_mm_show(struct seq_file *m, void *arg) { - struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_printer p = drm_seq_file_printer(m); @@ -240,7 +240,7 @@ static int msm_mm_show(struct seq_file *m, void *arg) static int msm_fb_show(struct seq_file *m, void *arg) { - struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; struct drm_framebuffer *fb, *fbdev_fb = NULL; -- cgit v1.2.3 From 82cf4954a0d5f50fa546753cbf0388e69755c54d Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Thu, 1 Jun 2023 19:00:12 +0200 Subject: drm/msm/dsi: Add configuration for MSM8226 Add the config for the v1.0.2 DSI found on MSM8226. We can reuse existing bits from other revisions that are identical for v1.0.2. Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Luca Weiss Patchwork: https://patchwork.freedesktop.org/patch/540616/ Link: https://lore.kernel.org/r/20230308-msm8226-mdp-v3-5-b6284145d67a@z3ntu.xyz Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_cfg.c | 2 ++ drivers/gpu/drm/msm/dsi/dsi_cfg.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c index 29ccd755cc2e..8a5fb6df7210 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c @@ -245,6 +245,8 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { &apq8064_dsi_cfg, &msm_dsi_v2_host_ops}, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_0, &msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops}, + {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_0_2, + &msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops}, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1, &msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops}, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1_1, diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h index 91bdaf50bb1a..43f0dd74edb6 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h @@ -11,6 +11,7 @@ #define MSM_DSI_VER_MAJOR_V2 0x02 #define MSM_DSI_VER_MAJOR_6G 0x03 #define MSM_DSI_6G_VER_MINOR_V1_0 0x10000000 +#define MSM_DSI_6G_VER_MINOR_V1_0_2 0x10000002 #define MSM_DSI_6G_VER_MINOR_V1_1 0x10010000 #define MSM_DSI_6G_VER_MINOR_V1_1_1 0x10010001 #define MSM_DSI_6G_VER_MINOR_V1_2 0x10020000 -- cgit v1.2.3 From 1531d0b9235e5c8e959fbfe02c90ecd5b2b8de05 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Thu, 1 Jun 2023 19:00:13 +0200 Subject: drm/msm/dsi: Add phy configuration for MSM8226 MSM8226 uses a modified PLL lock sequence compared to MSM8974, which is based on the function dsi_pll_enable_seq_m in the msm-3.10 kernel. Worth noting that the msm-3.10 downstream kernel also will try other sequences in case this one doesn't work, but during testing it has shown that the _m sequence succeeds first time also: .pll_enable_seqs[0] = dsi_pll_enable_seq_m, .pll_enable_seqs[1] = dsi_pll_enable_seq_m, .pll_enable_seqs[2] = dsi_pll_enable_seq_d, .pll_enable_seqs[3] = dsi_pll_enable_seq_d, .pll_enable_seqs[4] = dsi_pll_enable_seq_f1, .pll_enable_seqs[5] = dsi_pll_enable_seq_c, .pll_enable_seqs[6] = dsi_pll_enable_seq_e, We may need to expand this in the future. Signed-off-by: Luca Weiss Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/540618/ Link: https://lore.kernel.org/r/20230308-msm8226-mdp-v3-6-b6284145d67a@z3ntu.xyz Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 2 + drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 3 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 97 ++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index bb09cbe8ff86..9d5795c58a98 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -541,6 +541,8 @@ static const struct of_device_id dsi_phy_dt_match[] = { .data = &dsi_phy_28nm_hpm_famb_cfgs }, { .compatible = "qcom,dsi-phy-28nm-lp", .data = &dsi_phy_28nm_lp_cfgs }, + { .compatible = "qcom,dsi-phy-28nm-8226", + .data = &dsi_phy_28nm_8226_cfgs }, #endif #ifdef CONFIG_DRM_MSM_DSI_20NM_PHY { .compatible = "qcom,dsi-phy-20nm", diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 7137a17ae523..8b640d174785 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -46,8 +46,9 @@ struct msm_dsi_phy_cfg { extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs; -extern const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs; +extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8226_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs; +extern const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_14nm_2290_cfgs; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index 4c1bf55c5f38..ceec7bb87bf1 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -37,6 +37,7 @@ /* v2.0.0 28nm LP implementation */ #define DSI_PHY_28NM_QUIRK_PHY_LP BIT(0) +#define DSI_PHY_28NM_QUIRK_PHY_8226 BIT(1) #define LPFR_LUT_SIZE 10 struct lpfr_cfg { @@ -377,6 +378,74 @@ static int dsi_pll_28nm_vco_prepare_hpm(struct clk_hw *hw) return ret; } +static int dsi_pll_28nm_vco_prepare_8226(struct clk_hw *hw) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); + struct device *dev = &pll_28nm->phy->pdev->dev; + void __iomem *base = pll_28nm->phy->pll_base; + u32 max_reads = 5, timeout_us = 100; + bool locked; + u32 val; + int i; + + DBG("id=%d", pll_28nm->phy->id); + + pll_28nm_software_reset(pll_28nm); + + /* + * PLL power up sequence. + * Add necessary delays recommended by hardware. + */ + dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34); + + val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600); + + for (i = 0; i < 7; i++) { + /* DSI Uniphy lock detect setting */ + dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, + 0x0c, 100); + dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); + + /* poll for PLL ready status */ + locked = pll_28nm_poll_for_ready(pll_28nm, + max_reads, timeout_us); + if (locked) + break; + + pll_28nm_software_reset(pll_28nm); + + /* + * PLL power up sequence. + * Add necessary delays recommended by hardware. + */ + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00, 50); + + val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 100); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; + dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600); + } + + if (unlikely(!locked)) + DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); + else + DBG("DSI PLL Lock success"); + + return locked ? 0 : -EINVAL; +} + static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); @@ -471,6 +540,15 @@ static const struct clk_ops clk_ops_dsi_pll_28nm_vco_lp = { .is_enabled = dsi_pll_28nm_clk_is_enabled, }; +static const struct clk_ops clk_ops_dsi_pll_28nm_vco_8226 = { + .round_rate = dsi_pll_28nm_clk_round_rate, + .set_rate = dsi_pll_28nm_clk_set_rate, + .recalc_rate = dsi_pll_28nm_clk_recalc_rate, + .prepare = dsi_pll_28nm_vco_prepare_8226, + .unprepare = dsi_pll_28nm_vco_unprepare, + .is_enabled = dsi_pll_28nm_clk_is_enabled, +}; + /* * PLL Callbacks */ @@ -536,6 +614,8 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) vco_init.ops = &clk_ops_dsi_pll_28nm_vco_lp; + else if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_8226) + vco_init.ops = &clk_ops_dsi_pll_28nm_vco_8226; else vco_init.ops = &clk_ops_dsi_pll_28nm_vco_hpm; @@ -820,3 +900,20 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = { .quirks = DSI_PHY_28NM_QUIRK_PHY_LP, }; +const struct msm_dsi_phy_cfg dsi_phy_28nm_8226_cfgs = { + .has_phy_regulator = true, + .regulator_data = dsi_phy_28nm_regulators, + .num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators), + .ops = { + .enable = dsi_28nm_phy_enable, + .disable = dsi_28nm_phy_disable, + .pll_init = dsi_pll_28nm_init, + .save_pll_state = dsi_28nm_pll_save_state, + .restore_pll_state = dsi_28nm_pll_restore_state, + }, + .min_pll_rate = VCO_MIN_RATE, + .max_pll_rate = VCO_MAX_RATE, + .io_start = { 0xfd922b00 }, + .num_dsi_phy = 1, + .quirks = DSI_PHY_28NM_QUIRK_PHY_8226, +}; -- cgit v1.2.3 From eed3f9c7c36a2dbf01b6a3529a17b015df68b456 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Thu, 1 Jun 2023 19:00:11 +0200 Subject: drm/msm/mdp5: Add MDP5 configuration for MSM8226 Add the required config for the v1.1 MDP5 found on MSM8226. Reviewed-by: Dmitry Baryshkov Signed-off-by: Luca Weiss Patchwork: https://patchwork.freedesktop.org/patch/540612/ Link: https://lore.kernel.org/r/20230308-msm8226-mdp-v3-4-b6284145d67a@z3ntu.xyz Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 82 ++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c index 2eec2d78f32a..694d54341337 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c @@ -103,6 +103,87 @@ static const struct mdp5_cfg_hw msm8x74v1_config = { .max_clk = 200000000, }; +static const struct mdp5_cfg_hw msm8x26_config = { + .name = "msm8x26", + .mdp = { + .count = 1, + .caps = MDP_CAP_SMP | + 0, + }, + .smp = { + .mmb_count = 7, + .mmb_size = 4096, + .clients = { + [SSPP_VIG0] = 1, + [SSPP_DMA0] = 4, + [SSPP_RGB0] = 7, + }, + }, + .ctl = { + .count = 2, + .base = { 0x00500, 0x00600 }, + .flush_hw_mask = 0x0003ffff, + }, + .pipe_vig = { + .count = 1, + .base = { 0x01100 }, + .caps = MDP_PIPE_CAP_HFLIP | + MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_SCALE | + MDP_PIPE_CAP_CSC | + 0, + }, + .pipe_rgb = { + .count = 1, + .base = { 0x01d00 }, + .caps = MDP_PIPE_CAP_HFLIP | + MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_SCALE | + 0, + }, + .pipe_dma = { + .count = 1, + .base = { 0x02900 }, + .caps = MDP_PIPE_CAP_HFLIP | + MDP_PIPE_CAP_VFLIP | + 0, + }, + .lm = { + .count = 2, + .base = { 0x03100, 0x03d00 }, + .instances = { + { .id = 0, .pp = 0, .dspp = 0, + .caps = MDP_LM_CAP_DISPLAY, }, + { .id = 1, .pp = -1, .dspp = -1, + .caps = MDP_LM_CAP_WB }, + }, + .nb_stages = 2, + .max_width = 2048, + .max_height = 0xFFFF, + }, + .dspp = { + .count = 1, + .base = { 0x04500 }, + }, + .pp = { + .count = 1, + .base = { 0x21a00 }, + }, + .intf = { + .base = { 0x00000, 0x21200 }, + .connect = { + [0] = INTF_DISABLED, + [1] = INTF_DSI, + }, + }, + .perf = { + .ab_inefficiency = 100, + .ib_inefficiency = 200, + .clk_inefficiency = 125 + }, + .max_clk = 200000000, +}; + static const struct mdp5_cfg_hw msm8x74v2_config = { .name = "msm8x74", .mdp = { @@ -1236,6 +1317,7 @@ static const struct mdp5_cfg_hw sdm660_config = { static const struct mdp5_cfg_handler cfg_handlers_v1[] = { { .revision = 0, .config = { .hw = &msm8x74v1_config } }, + { .revision = 1, .config = { .hw = &msm8x26_config } }, { .revision = 2, .config = { .hw = &msm8x74v2_config } }, { .revision = 3, .config = { .hw = &apq8084_config } }, { .revision = 6, .config = { .hw = &msm8x16_config } }, -- cgit v1.2.3 From 9b930f14e530135e0f90bb809a1d8d72f50b1143 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 1 Jun 2023 20:22:30 +0300 Subject: drm/msm/dpu: merge dpu_encoder_init() and dpu_encoder_setup() There is no reason to split the dpu_encoder interface into separate _init() and _setup() phases. Merge them into a single function. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov Tested-by: Abhinav Kumar # sc7280 Patchwork: https://patchwork.freedesktop.org/patch/540628/ Link: https://lore.kernel.org/r/20230601172236.564445-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 55 +++++++----------- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 14 +---- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 87 +++++++++++------------------ 3 files changed, 56 insertions(+), 100 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 2c9af33c0911..4f44a49f8816 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2433,7 +2433,8 @@ static const struct drm_encoder_funcs dpu_encoder_funcs = { .early_unregister = dpu_encoder_early_unregister, }; -int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, +struct drm_encoder *dpu_encoder_init(struct drm_device *dev, + int drm_enc_mode, struct msm_display_info *disp_info) { struct msm_drm_private *priv = dev->dev_private; @@ -2442,7 +2443,23 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, struct dpu_encoder_virt *dpu_enc = NULL; int ret = 0; - dpu_enc = to_dpu_encoder_virt(enc); + dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); + if (!dpu_enc) + return ERR_PTR(-ENOMEM); + + ret = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs, + drm_enc_mode, NULL); + if (ret) { + devm_kfree(dev->dev, dpu_enc); + return ERR_PTR(ret); + } + + drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs); + + spin_lock_init(&dpu_enc->enc_spinlock); + dpu_enc->enabled = false; + mutex_init(&dpu_enc->enc_lock); + mutex_init(&dpu_enc->rc_lock); ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); if (ret) @@ -2471,44 +2488,14 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, DPU_DEBUG_ENC(dpu_enc, "created\n"); - return ret; + return &dpu_enc->base; fail: DPU_ERROR("failed to create encoder\n"); if (drm_enc) dpu_encoder_destroy(drm_enc); - return ret; - - -} - -struct drm_encoder *dpu_encoder_init(struct drm_device *dev, - int drm_enc_mode) -{ - struct dpu_encoder_virt *dpu_enc = NULL; - int rc = 0; - - dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); - if (!dpu_enc) - return ERR_PTR(-ENOMEM); - - - rc = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs, - drm_enc_mode, NULL); - if (rc) { - devm_kfree(dev->dev, dpu_enc); - return ERR_PTR(rc); - } - - drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs); - - spin_lock_init(&dpu_enc->enc_spinlock); - dpu_enc->enabled = false; - mutex_init(&dpu_enc->enc_lock); - mutex_init(&dpu_enc->rc_lock); - - return &dpu_enc->base; + return ERR_PTR(ret); } int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 6d14f84dd43f..90e1925d7770 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -130,20 +130,12 @@ void dpu_encoder_virt_runtime_resume(struct drm_encoder *encoder); /** * dpu_encoder_init - initialize virtual encoder object * @dev: Pointer to drm device structure + * @drm_enc_mode: corresponding DRM_MODE_ENCODER_* constant * @disp_info: Pointer to display information structure * Returns: Pointer to newly created drm encoder */ -struct drm_encoder *dpu_encoder_init( - struct drm_device *dev, - int drm_enc_mode); - -/** - * dpu_encoder_setup - setup dpu_encoder for the display probed - * @dev: Pointer to drm device structure - * @enc: Pointer to the drm_encoder - * @disp_info: Pointer to the display info - */ -int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, +struct drm_encoder *dpu_encoder_init(struct drm_device *dev, + int drm_enc_mode, struct msm_display_info *disp_info); /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 7f87ac6d68ac..801300e6626f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -535,15 +535,23 @@ static int _dpu_kms_initialize_dsi(struct drm_device *dev, !msm_dsi_is_master_dsi(priv->dsi[i])) continue; - encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI); + memset(&info, 0, sizeof(info)); + info.intf_type = INTF_DSI; + + info.h_tile_instance[info.num_of_h_tiles++] = i; + if (msm_dsi_is_bonded_dsi(priv->dsi[i])) + info.h_tile_instance[info.num_of_h_tiles++] = other; + + info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]); + + info.dsc = msm_dsi_get_dsc_config(priv->dsi[i]); + + encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI, &info); if (IS_ERR(encoder)) { DPU_ERROR("encoder init failed for dsi display\n"); return PTR_ERR(encoder); } - memset(&info, 0, sizeof(info)); - info.intf_type = INTF_DSI; - rc = msm_dsi_modeset_init(priv->dsi[i], dev, encoder); if (rc) { DPU_ERROR("modeset_init failed for dsi[%d], rc = %d\n", @@ -551,11 +559,6 @@ static int _dpu_kms_initialize_dsi(struct drm_device *dev, break; } - info.h_tile_instance[info.num_of_h_tiles++] = i; - info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]); - - info.dsc = msm_dsi_get_dsc_config(priv->dsi[i]); - if (msm_dsi_is_bonded_dsi(priv->dsi[i]) && priv->dsi[other]) { rc = msm_dsi_modeset_init(priv->dsi[other], dev, encoder); if (rc) { @@ -563,14 +566,7 @@ static int _dpu_kms_initialize_dsi(struct drm_device *dev, other, rc); break; } - - info.h_tile_instance[info.num_of_h_tiles++] = other; } - - rc = dpu_encoder_setup(dev, encoder, &info); - if (rc) - DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n", - encoder->base.id, rc); } return rc; @@ -589,29 +585,23 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev, if (!priv->dp[i]) continue; - encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS); + memset(&info, 0, sizeof(info)); + info.num_of_h_tiles = 1; + info.h_tile_instance[0] = i; + info.intf_type = INTF_DP; + + encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS, &info); if (IS_ERR(encoder)) { DPU_ERROR("encoder init failed for dsi display\n"); return PTR_ERR(encoder); } - memset(&info, 0, sizeof(info)); rc = msm_dp_modeset_init(priv->dp[i], dev, encoder); if (rc) { DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); drm_encoder_cleanup(encoder); return rc; } - - info.num_of_h_tiles = 1; - info.h_tile_instance[0] = i; - info.intf_type = INTF_DP; - rc = dpu_encoder_setup(dev, encoder, &info); - if (rc) { - DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n", - encoder->base.id, rc); - return rc; - } } return 0; @@ -628,13 +618,17 @@ static int _dpu_kms_initialize_hdmi(struct drm_device *dev, if (!priv->hdmi) return 0; - encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS); + memset(&info, 0, sizeof(info)); + info.num_of_h_tiles = 1; + info.h_tile_instance[0] = 0; + info.intf_type = INTF_HDMI; + + encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS, &info); if (IS_ERR(encoder)) { DPU_ERROR("encoder init failed for HDMI display\n"); return PTR_ERR(encoder); } - memset(&info, 0, sizeof(info)); rc = msm_hdmi_modeset_init(priv->hdmi, dev, encoder); if (rc) { DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); @@ -642,16 +636,6 @@ static int _dpu_kms_initialize_hdmi(struct drm_device *dev, return rc; } - info.num_of_h_tiles = 1; - info.h_tile_instance[0] = 0; - info.intf_type = INTF_HDMI; - rc = dpu_encoder_setup(dev, encoder, &info); - if (rc) { - DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n", - encoder->base.id, rc); - return rc; - } - return 0; } @@ -663,14 +647,19 @@ static int _dpu_kms_initialize_writeback(struct drm_device *dev, struct msm_display_info info; int rc; - encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_VIRTUAL); + memset(&info, 0, sizeof(info)); + + info.num_of_h_tiles = 1; + /* use only WB idx 2 instance for DPU */ + info.h_tile_instance[0] = WB_2; + info.intf_type = INTF_WB; + + encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_VIRTUAL, &info); if (IS_ERR(encoder)) { DPU_ERROR("encoder init failed for dsi display\n"); return PTR_ERR(encoder); } - memset(&info, 0, sizeof(info)); - rc = dpu_writeback_init(dev, encoder, wb_formats, n_formats); if (rc) { @@ -679,18 +668,6 @@ static int _dpu_kms_initialize_writeback(struct drm_device *dev, return rc; } - info.num_of_h_tiles = 1; - /* use only WB idx 2 instance for DPU */ - info.h_tile_instance[0] = WB_2; - info.intf_type = INTF_WB; - - rc = dpu_encoder_setup(dev, encoder, &info); - if (rc) { - DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n", - encoder->base.id, rc); - return rc; - } - return 0; } -- cgit v1.2.3 From 7731ee3b06c12b3eb46957b054629e1bb88e99ce Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 1 Jun 2023 20:22:31 +0300 Subject: drm/msm/dpu: separate common function to init physical encoder Move common DPU physical encoder initialization code to the new function dpu_encoder_phys_init(). Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov Tested-by: Abhinav Kumar # sc7280 Patchwork: https://patchwork.freedesktop.org/patch/540630/ Link: https://lore.kernel.org/r/20230601172236.564445-3-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 29 ++++++++++++++++++++-- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 +++ .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 17 +++---------- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 17 ++----------- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 17 ++----------- 5 files changed, 37 insertions(+), 46 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 4f44a49f8816..692874344351 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2366,8 +2366,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, for (i = 0; i < dpu_enc->num_phys_encs; i++) { struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; - atomic_set(&phys->vsync_cnt, 0); - atomic_set(&phys->underrun_cnt, 0); if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); @@ -2569,3 +2567,30 @@ unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc) return dpu_enc->dsc_mask; } + +void dpu_encoder_phys_init(struct dpu_encoder_phys *phys_enc, + struct dpu_enc_phys_init_params *p) +{ + int i; + + phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; + phys_enc->intf_idx = p->intf_idx; + phys_enc->wb_idx = p->wb_idx; + phys_enc->parent = p->parent; + phys_enc->dpu_kms = p->dpu_kms; + phys_enc->split_role = p->split_role; + phys_enc->enc_spinlock = p->enc_spinlock; + phys_enc->enable_state = DPU_ENC_DISABLED; + + for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++) + phys_enc->irq[i] = -EINVAL; + + atomic_set(&phys_enc->vblank_refcount, 0); + atomic_set(&phys_enc->pending_kickoff_cnt, 0); + atomic_set(&phys_enc->pending_ctlstart_cnt, 0); + + atomic_set(&phys_enc->vsync_cnt, 0); + atomic_set(&phys_enc->underrun_cnt, 0); + + init_waitqueue_head(&phys_enc->pending_kickoff_wq); +} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 90f177e43262..aa98bfb70a26 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -407,4 +407,7 @@ void dpu_encoder_frame_done_callback( struct drm_encoder *drm_enc, struct dpu_encoder_phys *ready_phys, u32 event); +void dpu_encoder_phys_init(struct dpu_encoder_phys *phys, + struct dpu_enc_phys_init_params *p); + #endif /* __dpu_encoder_phys_H__ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index d8ed85a238af..2bd806c51882 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -756,7 +756,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( { struct dpu_encoder_phys *phys_enc = NULL; struct dpu_encoder_phys_cmd *cmd_enc = NULL; - int i, ret = 0; + int ret = 0; DPU_DEBUG("intf %d\n", p->intf_idx - INTF_0); @@ -767,28 +767,17 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( return ERR_PTR(ret); } phys_enc = &cmd_enc->base; - phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; - phys_enc->intf_idx = p->intf_idx; + + dpu_encoder_phys_init(phys_enc, p); dpu_encoder_phys_cmd_init_ops(&phys_enc->ops); - phys_enc->parent = p->parent; - phys_enc->dpu_kms = p->dpu_kms; - phys_enc->split_role = p->split_role; phys_enc->intf_mode = INTF_MODE_CMD; - phys_enc->enc_spinlock = p->enc_spinlock; cmd_enc->stream_sel = 0; - phys_enc->enable_state = DPU_ENC_DISABLED; - for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++) - phys_enc->irq[i] = -EINVAL; phys_enc->has_intf_te = test_bit(DPU_INTF_TE, &phys_enc->dpu_kms->catalog->intf[p->intf_idx - INTF_0].features); - atomic_set(&phys_enc->vblank_refcount, 0); - atomic_set(&phys_enc->pending_kickoff_cnt, 0); - atomic_set(&phys_enc->pending_ctlstart_cnt, 0); atomic_set(&cmd_enc->pending_vblank_cnt, 0); - init_waitqueue_head(&phys_enc->pending_kickoff_wq); init_waitqueue_head(&cmd_enc->pending_vblank_wq); DPU_DEBUG_CMDENC(cmd_enc, "created\n"); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 3a374292f311..dc951fdf473b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -699,7 +699,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( struct dpu_enc_phys_init_params *p) { struct dpu_encoder_phys *phys_enc = NULL; - int i; if (!p) { DPU_ERROR("failed to create encoder due to invalid parameter\n"); @@ -712,24 +711,12 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( return ERR_PTR(-ENOMEM); } - phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; - phys_enc->intf_idx = p->intf_idx; - DPU_DEBUG_VIDENC(phys_enc, "\n"); + dpu_encoder_phys_init(phys_enc, p); + dpu_encoder_phys_vid_init_ops(&phys_enc->ops); - phys_enc->parent = p->parent; - phys_enc->dpu_kms = p->dpu_kms; - phys_enc->split_role = p->split_role; phys_enc->intf_mode = INTF_MODE_VIDEO; - phys_enc->enc_spinlock = p->enc_spinlock; - for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++) - phys_enc->irq[i] = -EINVAL; - - atomic_set(&phys_enc->vblank_refcount, 0); - atomic_set(&phys_enc->pending_kickoff_cnt, 0); - init_waitqueue_head(&phys_enc->pending_kickoff_wq); - phys_enc->enable_state = DPU_ENC_DISABLED; DPU_DEBUG_VIDENC(phys_enc, "created intf idx:%d\n", p->intf_idx); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 023a9c4ad1db..008d1d09b9ba 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -685,7 +685,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init( struct dpu_encoder_phys *phys_enc = NULL; struct dpu_encoder_phys_wb *wb_enc = NULL; int ret = 0; - int i; DPU_DEBUG("\n"); @@ -703,28 +702,16 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init( } phys_enc = &wb_enc->base; - phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; - phys_enc->wb_idx = p->wb_idx; + + dpu_encoder_phys_init(phys_enc, p); dpu_encoder_phys_wb_init_ops(&phys_enc->ops); - phys_enc->parent = p->parent; - phys_enc->dpu_kms = p->dpu_kms; - phys_enc->split_role = p->split_role; phys_enc->intf_mode = INTF_MODE_WB_LINE; - phys_enc->wb_idx = p->wb_idx; - phys_enc->enc_spinlock = p->enc_spinlock; atomic_set(&wb_enc->wbirq_refcount, 0); - for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++) - phys_enc->irq[i] = -EINVAL; - - atomic_set(&phys_enc->pending_kickoff_cnt, 0); - atomic_set(&phys_enc->vblank_refcount, 0); wb_enc->wb_done_timeout_cnt = 0; - init_waitqueue_head(&phys_enc->pending_kickoff_wq); - phys_enc->enable_state = DPU_ENC_DISABLED; DPU_DEBUG("Created dpu_encoder_phys for wb %d\n", phys_enc->wb_idx); -- cgit v1.2.3 From 8ea432b8428e9b324eee2bbfafbded99f80e3414 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 1 Jun 2023 20:22:32 +0300 Subject: drm/msm/dpu: drop duplicated intf/wb indices from encoder structs Remove intf_idx and wb_idx fields from struct dpu_encoder_phys and struct dpu_enc_phys_init_params. Set the hw_intf and hw_wb directly and use them to get the instance index. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov Tested-by: Abhinav Kumar # sc7280 Patchwork: https://patchwork.freedesktop.org/patch/540635/ Link: https://lore.kernel.org/r/20230601172236.564445-4-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 72 +++++++++------------- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 18 +++--- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 8 +-- 5 files changed, 47 insertions(+), 65 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 692874344351..51484d842c82 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -339,7 +339,8 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc, DRM_ERROR("irq timeout id=%u, intf_mode=%s intf=%d wb=%d, pp=%d, intr=%d\n", DRMID(phys_enc->parent), dpu_encoder_helper_get_intf_type(phys_enc->intf_mode), - phys_enc->intf_idx - INTF_0, phys_enc->wb_idx - WB_0, + phys_enc->hw_intf ? phys_enc->hw_intf->idx - INTF_0 : -1, + phys_enc->hw_wb ? phys_enc->hw_wb->idx - WB_0 : -1, phys_enc->hw_pp->idx - PINGPONG_0, intr_idx); dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, @@ -1419,7 +1420,8 @@ void dpu_encoder_frame_done_callback( */ trace_dpu_enc_frame_done_cb_not_busy(DRMID(drm_enc), event, dpu_encoder_helper_get_intf_type(ready_phys->intf_mode), - ready_phys->intf_idx, ready_phys->wb_idx); + ready_phys->hw_intf ? ready_phys->hw_intf->idx : -1, + ready_phys->hw_wb ? ready_phys->hw_wb->idx : -1); return; } @@ -1499,7 +1501,8 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, trace_dpu_enc_trigger_flush(DRMID(drm_enc), dpu_encoder_helper_get_intf_type(phys->intf_mode), - phys->intf_idx, phys->wb_idx, + phys->hw_intf ? phys->hw_intf->idx : -1, + phys->hw_wb ? phys->hw_wb->idx : -1, pending_kickoff_cnt, ctl->idx, extra_flush_bits, ret); } @@ -2155,7 +2158,8 @@ static int _dpu_encoder_status_show(struct seq_file *s, void *data) struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; seq_printf(s, "intf:%d wb:%d vsync:%8d underrun:%8d ", - phys->intf_idx - INTF_0, phys->wb_idx - WB_0, + phys->hw_intf ? phys->hw_intf->idx - INTF_0 : -1, + phys->hw_wb ? phys->hw_wb->idx - WB_0 : -1, atomic_read(&phys->vsync_cnt), atomic_read(&phys->underrun_cnt)); @@ -2319,6 +2323,8 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right */ u32 controller_id = disp_info->h_tile_instance[i]; + enum dpu_intf intf_idx; + enum dpu_wb wb_idx; if (disp_info->num_of_h_tiles > 1) { if (i == 0) @@ -2332,57 +2338,39 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, DPU_DEBUG("h_tile_instance %d = %d, split_role %d\n", i, controller_id, phys_params.split_role); - phys_params.intf_idx = dpu_encoder_get_intf(dpu_kms->catalog, + intf_idx = dpu_encoder_get_intf(dpu_kms->catalog, disp_info->intf_type, controller_id); - phys_params.wb_idx = dpu_encoder_get_wb(dpu_kms->catalog, + wb_idx = dpu_encoder_get_wb(dpu_kms->catalog, disp_info->intf_type, controller_id); - /* - * The phys_params might represent either an INTF or a WB unit, but not - * both of them at the same time. - */ - if ((phys_params.intf_idx == INTF_MAX) && - (phys_params.wb_idx == WB_MAX)) { - DPU_ERROR_ENC(dpu_enc, "could not get intf or wb: type %d, id %d\n", - disp_info->intf_type, controller_id); - ret = -EINVAL; - } - if ((phys_params.intf_idx != INTF_MAX) && - (phys_params.wb_idx != WB_MAX)) { - DPU_ERROR_ENC(dpu_enc, "both intf and wb present: type %d, id %d\n", - disp_info->intf_type, controller_id); - ret = -EINVAL; - } + if (intf_idx >= INTF_0 && intf_idx < INTF_MAX) + phys_params.hw_intf = dpu_rm_get_intf(&dpu_kms->rm, intf_idx); - if (!ret) { - ret = dpu_encoder_virt_add_phys_encs(disp_info, - dpu_enc, &phys_params); - if (ret) - DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n"); - } - } + if (wb_idx >= WB_0 && wb_idx < WB_MAX) + phys_params.hw_wb = dpu_rm_get_wb(&dpu_kms->rm, wb_idx); - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; - - if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) - phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, phys->intf_idx); - - if (phys->wb_idx >= WB_0 && phys->wb_idx < WB_MAX) - phys->hw_wb = dpu_rm_get_wb(&dpu_kms->rm, phys->wb_idx); - - if (!phys->hw_intf && !phys->hw_wb) { + if (!phys_params.hw_intf && !phys_params.hw_wb) { DPU_ERROR_ENC(dpu_enc, "no intf or wb block assigned at idx: %d\n", i); ret = -EINVAL; + break; } - if (phys->hw_intf && phys->hw_wb) { + if (phys_params.hw_intf && phys_params.hw_wb) { DPU_ERROR_ENC(dpu_enc, "invalid phys both intf and wb block at idx: %d\n", i); ret = -EINVAL; + break; } + + ret = dpu_encoder_virt_add_phys_encs(disp_info, + dpu_enc, &phys_params); + if (ret) { + DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n"); + break; + } + } mutex_unlock(&dpu_enc->enc_lock); @@ -2574,8 +2562,8 @@ void dpu_encoder_phys_init(struct dpu_encoder_phys *phys_enc, int i; phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; - phys_enc->intf_idx = p->intf_idx; - phys_enc->wb_idx = p->wb_idx; + phys_enc->hw_intf = p->hw_intf; + phys_enc->hw_wb = p->hw_wb; phys_enc->parent = p->parent; phys_enc->dpu_kms = p->dpu_kms; phys_enc->split_role = p->split_role; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index aa98bfb70a26..cf64d7f608fd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -161,8 +161,6 @@ enum dpu_intr_idx { * @enabled: Whether the encoder has enabled and running a mode * @split_role: Role to play in a split-panel configuration * @intf_mode: Interface mode - * @intf_idx: Interface index on dpu hardware - * @wb_idx: Writeback index on dpu hardware * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes * @enable_state: Enable state tracking * @vblank_refcount: Reference count of vblank request @@ -190,8 +188,6 @@ struct dpu_encoder_phys { struct drm_display_mode cached_mode; enum dpu_enc_split_role split_role; enum dpu_intf_mode intf_mode; - enum dpu_intf intf_idx; - enum dpu_wb wb_idx; spinlock_t *enc_spinlock; enum dpu_enc_enable_state enable_state; atomic_t vblank_refcount; @@ -258,16 +254,16 @@ struct dpu_encoder_phys_cmd { * @parent: Pointer to the containing virtual encoder * @parent_ops: Callbacks exposed by the parent to the phys_enc * @split_role: Role to play in a split-panel configuration - * @intf_idx: Interface index this phys_enc will control - * @wb_idx: Writeback index this phys_enc will control + * @hw_intf: Hardware interface to the intf registers + * @hw_wb: Hardware interface to the wb registers * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes */ struct dpu_enc_phys_init_params { struct dpu_kms *dpu_kms; struct drm_encoder *parent; enum dpu_enc_split_role split_role; - enum dpu_intf intf_idx; - enum dpu_wb wb_idx; + struct dpu_hw_intf *hw_intf; + struct dpu_hw_wb *hw_wb; spinlock_t *enc_spinlock; }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 2bd806c51882..2cc6b0cd2710 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -16,12 +16,12 @@ #define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ (e) && (e)->base.parent ? \ (e)->base.parent->base.id : -1, \ - (e) ? (e)->base.intf_idx - INTF_0 : -1, ##__VA_ARGS__) + (e) ? (e)->base.hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__) #define DPU_ERROR_CMDENC(e, fmt, ...) DPU_ERROR("enc%d intf%d " fmt, \ (e) && (e)->base.parent ? \ (e)->base.parent->base.id : -1, \ - (e) ? (e)->base.intf_idx - INTF_0 : -1, ##__VA_ARGS__) + (e) ? (e)->base.hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__) #define to_dpu_encoder_phys_cmd(x) \ container_of(x, struct dpu_encoder_phys_cmd, base) @@ -55,7 +55,7 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( if (!ctl->ops.setup_intf_cfg) return; - intf_cfg.intf = phys_enc->intf_idx; + intf_cfg.intf = phys_enc->hw_intf->idx; intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD; intf_cfg.stream_sel = cmd_enc->stream_sel; intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); @@ -440,7 +440,7 @@ static void dpu_encoder_phys_cmd_enable_helper( return; } - dpu_encoder_helper_split_config(phys_enc, phys_enc->intf_idx); + dpu_encoder_helper_split_config(phys_enc, phys_enc->hw_intf->idx); _dpu_encoder_phys_cmd_pingpong_config(phys_enc); @@ -448,7 +448,7 @@ static void dpu_encoder_phys_cmd_enable_helper( return; ctl = phys_enc->hw_ctl; - ctl->ops.update_pending_flush_intf(ctl, phys_enc->intf_idx); + ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); } static void dpu_encoder_phys_cmd_enable(struct dpu_encoder_phys *phys_enc) @@ -557,7 +557,7 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc) phys_enc->hw_pp->idx); ctl = phys_enc->hw_ctl; - ctl->ops.update_pending_flush_intf(ctl, phys_enc->intf_idx); + ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); } phys_enc->enable_state = DPU_ENC_DISABLED; @@ -667,7 +667,7 @@ static int dpu_encoder_phys_cmd_wait_for_tx_complete( if (rc) { DRM_ERROR("failed wait_for_idle: id:%u ret:%d intf:%d\n", DRMID(phys_enc->parent), rc, - phys_enc->intf_idx - INTF_0); + phys_enc->hw_intf->idx - INTF_0); } return rc; @@ -758,7 +758,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( struct dpu_encoder_phys_cmd *cmd_enc = NULL; int ret = 0; - DPU_DEBUG("intf %d\n", p->intf_idx - INTF_0); + DPU_DEBUG("intf\n"); cmd_enc = kzalloc(sizeof(*cmd_enc), GFP_KERNEL); if (!cmd_enc) { @@ -775,7 +775,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( cmd_enc->stream_sel = 0; phys_enc->has_intf_te = test_bit(DPU_INTF_TE, - &phys_enc->dpu_kms->catalog->intf[p->intf_idx - INTF_0].features); + &phys_enc->hw_intf->cap->features); atomic_set(&cmd_enc->pending_vblank_cnt, 0); init_waitqueue_head(&cmd_enc->pending_vblank_wq); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index dc951fdf473b..e26629e9e303 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -718,7 +718,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( dpu_encoder_phys_vid_init_ops(&phys_enc->ops); phys_enc->intf_mode = INTF_MODE_VIDEO; - DPU_DEBUG_VIDENC(phys_enc, "created intf idx:%d\n", p->intf_idx); + DPU_DEBUG_VIDENC(phys_enc, "created intf idx:%d\n", p->hw_intf->idx); return phys_enc; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 008d1d09b9ba..6608c00e3c33 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -240,7 +240,7 @@ static int dpu_encoder_phys_wb_atomic_check( const struct drm_display_mode *mode = &crtc_state->mode; DPU_DEBUG("[atomic_check:%d, \"%s\",%d,%d]\n", - phys_enc->wb_idx, mode->name, mode->hdisplay, mode->vdisplay); + phys_enc->hw_wb->idx, mode->name, mode->hdisplay, mode->vdisplay); if (!conn_state || !conn_state->connector) { DPU_ERROR("invalid connector state\n"); @@ -561,7 +561,7 @@ static void dpu_encoder_phys_wb_destroy(struct dpu_encoder_phys *phys_enc) if (!phys_enc) return; - DPU_DEBUG("[wb:%d]\n", phys_enc->wb_idx - WB_0); + DPU_DEBUG("[wb:%d]\n", phys_enc->hw_wb->idx - WB_0); kfree(phys_enc); } @@ -712,9 +712,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init( wb_enc->wb_done_timeout_cnt = 0; - - DPU_DEBUG("Created dpu_encoder_phys for wb %d\n", - phys_enc->wb_idx); + DPU_DEBUG("Created dpu_encoder_phys for wb %d\n", phys_enc->hw_wb->idx); return phys_enc; -- cgit v1.2.3 From 04ada3d8380ac8623fc79b172427b984535f8215 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 1 Jun 2023 20:22:33 +0300 Subject: drm/msm/dpu: inline dpu_encoder_get_wb() The function dpu_encoder_get_wb() returns controller_id if the corresponding WB is present in the catalog. We can inline this function and rely on dpu_rm_get_wb() returning NULL for indices for which the WB is not present on the device. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov Tested-by: Abhinav Kumar # sc7280 Patchwork: https://patchwork.freedesktop.org/patch/540634/ Link: https://lore.kernel.org/r/20230601172236.564445-5-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 51484d842c82..bb89ee2ad958 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1288,22 +1288,6 @@ static enum dpu_intf dpu_encoder_get_intf(const struct dpu_mdss_cfg *catalog, return INTF_MAX; } -static enum dpu_wb dpu_encoder_get_wb(const struct dpu_mdss_cfg *catalog, - enum dpu_intf_type type, u32 controller_id) -{ - int i = 0; - - if (type != INTF_WB) - return WB_MAX; - - for (i = 0; i < catalog->wb_count; i++) { - if (catalog->wb[i].id == controller_id) - return catalog->wb[i].id; - } - - return WB_MAX; -} - void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, struct dpu_encoder_phys *phy_enc) { @@ -2324,7 +2308,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, */ u32 controller_id = disp_info->h_tile_instance[i]; enum dpu_intf intf_idx; - enum dpu_wb wb_idx; if (disp_info->num_of_h_tiles > 1) { if (i == 0) @@ -2342,14 +2325,11 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, disp_info->intf_type, controller_id); - wb_idx = dpu_encoder_get_wb(dpu_kms->catalog, - disp_info->intf_type, controller_id); - if (intf_idx >= INTF_0 && intf_idx < INTF_MAX) phys_params.hw_intf = dpu_rm_get_intf(&dpu_kms->rm, intf_idx); - if (wb_idx >= WB_0 && wb_idx < WB_MAX) - phys_params.hw_wb = dpu_rm_get_wb(&dpu_kms->rm, wb_idx); + if (disp_info->intf_type == INTF_WB && controller_id < WB_MAX) + phys_params.hw_wb = dpu_rm_get_wb(&dpu_kms->rm, controller_id); if (!phys_params.hw_intf && !phys_params.hw_wb) { DPU_ERROR_ENC(dpu_enc, "no intf or wb block assigned at idx: %d\n", i); -- cgit v1.2.3 From 004be38657f45f6ecba4158dde2754bc4b75081d Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 1 Jun 2023 20:22:34 +0300 Subject: drm/msm/dpu: call dpu_rm_get_intf() from dpu_encoder_get_intf() There is little sense to get intf index just to call dpu_rm_get_intf() on it. Move dpu_rm_get_intf() call to dpu_encoder_get_intf() function. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov Tested-by: Abhinav Kumar # sc7280 Patchwork: https://patchwork.freedesktop.org/patch/540632/ Link: https://lore.kernel.org/r/20230601172236.564445-6-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index bb89ee2ad958..f32882e83255 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1270,22 +1270,23 @@ static void dpu_encoder_virt_atomic_disable(struct drm_encoder *drm_enc, mutex_unlock(&dpu_enc->enc_lock); } -static enum dpu_intf dpu_encoder_get_intf(const struct dpu_mdss_cfg *catalog, +static struct dpu_hw_intf *dpu_encoder_get_intf(const struct dpu_mdss_cfg *catalog, + struct dpu_rm *dpu_rm, enum dpu_intf_type type, u32 controller_id) { int i = 0; if (type == INTF_WB) - return INTF_MAX; + return NULL; for (i = 0; i < catalog->intf_count; i++) { if (catalog->intf[i].type == type && catalog->intf[i].controller_id == controller_id) { - return catalog->intf[i].id; + return dpu_rm_get_intf(dpu_rm, catalog->intf[i].id); } } - return INTF_MAX; + return NULL; } void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, @@ -2307,7 +2308,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right */ u32 controller_id = disp_info->h_tile_instance[i]; - enum dpu_intf intf_idx; if (disp_info->num_of_h_tiles > 1) { if (i == 0) @@ -2321,12 +2321,9 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, DPU_DEBUG("h_tile_instance %d = %d, split_role %d\n", i, controller_id, phys_params.split_role); - intf_idx = dpu_encoder_get_intf(dpu_kms->catalog, - disp_info->intf_type, - controller_id); - - if (intf_idx >= INTF_0 && intf_idx < INTF_MAX) - phys_params.hw_intf = dpu_rm_get_intf(&dpu_kms->rm, intf_idx); + phys_params.hw_intf = dpu_encoder_get_intf(dpu_kms->catalog, &dpu_kms->rm, + disp_info->intf_type, + controller_id); if (disp_info->intf_type == INTF_WB && controller_id < WB_MAX) phys_params.hw_wb = dpu_rm_get_wb(&dpu_kms->rm, controller_id); @@ -2350,7 +2347,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n"); break; } - } mutex_unlock(&dpu_enc->enc_lock); -- cgit v1.2.3 From ed02d3dd18dc35a8f8ca0527c1eaebb992585ec6 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 1 Jun 2023 20:22:35 +0300 Subject: drm/msm/dpu: drop temp variable from dpu_encoder_phys_cmd_init() There is no need to assign a result to temp varable just to return it two lines below. Drop the temporary variable. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov Tested-by: Abhinav Kumar # sc7280 Patchwork: https://patchwork.freedesktop.org/patch/540637/ Link: https://lore.kernel.org/r/20230601172236.564445-7-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 2cc6b0cd2710..4f8c9187f76d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -756,15 +756,13 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( { struct dpu_encoder_phys *phys_enc = NULL; struct dpu_encoder_phys_cmd *cmd_enc = NULL; - int ret = 0; DPU_DEBUG("intf\n"); cmd_enc = kzalloc(sizeof(*cmd_enc), GFP_KERNEL); if (!cmd_enc) { - ret = -ENOMEM; DPU_ERROR("failed to allocate\n"); - return ERR_PTR(ret); + return ERR_PTR(-ENOMEM); } phys_enc = &cmd_enc->base; -- cgit v1.2.3 From 5d1227d1c7a38adb26a0203ecaf5873b2bbbf7b6 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 1 Jun 2023 20:22:36 +0300 Subject: drm/msm/dpu: simplify dpu_encoder_phys_wb_init() There is no need to assign a result to temp varable just to return it after a goto. Drop the temporary variable and goto and return the result directly. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov Tested-by: Abhinav Kumar # sc7280 Patchwork: https://patchwork.freedesktop.org/patch/540639/ Link: https://lore.kernel.org/r/20230601172236.564445-8-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 6608c00e3c33..e9325cafb1a8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -684,21 +684,18 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init( { struct dpu_encoder_phys *phys_enc = NULL; struct dpu_encoder_phys_wb *wb_enc = NULL; - int ret = 0; DPU_DEBUG("\n"); if (!p || !p->parent) { DPU_ERROR("invalid params\n"); - ret = -EINVAL; - goto fail_alloc; + return ERR_PTR(-EINVAL); } wb_enc = kzalloc(sizeof(*wb_enc), GFP_KERNEL); if (!wb_enc) { DPU_ERROR("failed to allocate wb phys_enc enc\n"); - ret = -ENOMEM; - goto fail_alloc; + return ERR_PTR(-ENOMEM); } phys_enc = &wb_enc->base; @@ -715,7 +712,4 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init( DPU_DEBUG("Created dpu_encoder_phys for wb %d\n", phys_enc->hw_wb->idx); return phys_enc; - -fail_alloc: - return ERR_PTR(ret); } -- cgit v1.2.3 From 1c5f6051ffdfdc633af088e565bc028e459b57d2 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 20 May 2023 21:20:50 +0300 Subject: drm/msm/dp: remove most of usbpd-related remains Remove most of remains of downstream usbpd code. Mainline kernel uses different approach for managing Type-C / USB-PD, so this remains unused. Signed-off-by: Dmitry Baryshkov Reviewed-by: Bjorn Andersson Patchwork: https://patchwork.freedesktop.org/patch/538270/ Link: https://lore.kernel.org/r/20230520182050.4014143-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Makefile | 1 - drivers/gpu/drm/msm/dp/dp_ctrl.h | 1 - drivers/gpu/drm/msm/dp/dp_debug.c | 6 +-- drivers/gpu/drm/msm/dp/dp_debug.h | 5 +-- drivers/gpu/drm/msm/dp/dp_display.c | 34 +--------------- drivers/gpu/drm/msm/dp/dp_hpd.c | 67 ------------------------------- drivers/gpu/drm/msm/dp/dp_hpd.h | 78 ------------------------------------- drivers/gpu/drm/msm/dp/dp_panel.h | 1 - drivers/gpu/drm/msm/dp/dp_power.c | 2 +- drivers/gpu/drm/msm/dp/dp_power.h | 3 +- 10 files changed, 8 insertions(+), 190 deletions(-) delete mode 100644 drivers/gpu/drm/msm/dp/dp_hpd.c delete mode 100644 drivers/gpu/drm/msm/dp/dp_hpd.h (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7274c41228ed..39d9ac05c4b6 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -122,7 +122,6 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \ dp/dp_ctrl.o \ dp/dp_display.o \ dp/dp_drm.o \ - dp/dp_hpd.o \ dp/dp_link.o \ dp/dp_panel.o \ dp/dp_parser.o \ diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.h b/drivers/gpu/drm/msm/dp/dp_ctrl.h index f712780149fd..b2c27d3532bf 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.h +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.h @@ -14,7 +14,6 @@ #include "dp_catalog.h" struct dp_ctrl { - bool orientation; atomic_t aborted; bool wide_bus_en; }; diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c b/drivers/gpu/drm/msm/dp/dp_debug.c index 5e35033ba3e4..3bba901afe33 100644 --- a/drivers/gpu/drm/msm/dp/dp_debug.c +++ b/drivers/gpu/drm/msm/dp/dp_debug.c @@ -21,7 +21,6 @@ struct dp_debug_private { struct dentry *root; - struct dp_usbpd *usbpd; struct dp_link *link; struct dp_panel *panel; struct drm_connector *connector; @@ -232,14 +231,14 @@ static void dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) } struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, - struct dp_usbpd *usbpd, struct dp_link *link, + struct dp_link *link, struct drm_connector *connector, struct drm_minor *minor) { struct dp_debug_private *debug; struct dp_debug *dp_debug; int rc; - if (!dev || !panel || !usbpd || !link) { + if (!dev || !panel || !link) { DRM_ERROR("invalid input\n"); rc = -EINVAL; goto error; @@ -252,7 +251,6 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, } debug->dp_debug.debug_en = false; - debug->usbpd = usbpd; debug->link = link; debug->panel = panel; debug->dev = dev; diff --git a/drivers/gpu/drm/msm/dp/dp_debug.h b/drivers/gpu/drm/msm/dp/dp_debug.h index 8c0d0b5178fd..124227873d58 100644 --- a/drivers/gpu/drm/msm/dp/dp_debug.h +++ b/drivers/gpu/drm/msm/dp/dp_debug.h @@ -32,7 +32,6 @@ struct dp_debug { * * @dev: device instance of the caller * @panel: instance of panel module - * @usbpd: instance of usbpd module * @link: instance of link module * @connector: double pointer to display connector * @minor: pointer to drm minor number after device registration @@ -42,7 +41,7 @@ struct dp_debug { * for debugfs input to be communicated with existing modules */ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, - struct dp_usbpd *usbpd, struct dp_link *link, + struct dp_link *link, struct drm_connector *connector, struct drm_minor *minor); @@ -59,7 +58,7 @@ void dp_debug_put(struct dp_debug *dp_debug); static inline struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, - struct dp_usbpd *usbpd, struct dp_link *link, + struct dp_link *link, struct drm_connector *connector, struct drm_minor *minor) { return ERR_PTR(-EINVAL); diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 99a38dbe51c0..3d8fa2e73583 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -14,7 +14,6 @@ #include "msm_drv.h" #include "msm_kms.h" -#include "dp_hpd.h" #include "dp_parser.h" #include "dp_power.h" #include "dp_catalog.h" @@ -88,7 +87,6 @@ struct dp_display_private { struct platform_device *pdev; struct dentry *root; - struct dp_usbpd *usbpd; struct dp_parser *parser; struct dp_power *power; struct dp_catalog *catalog; @@ -98,7 +96,6 @@ struct dp_display_private { struct dp_ctrl *ctrl; struct dp_debug *debug; - struct dp_usbpd_cb usbpd_cb; struct dp_display_mode dp_mode; struct msm_dp dp_display; @@ -463,7 +460,7 @@ static void dp_display_host_init(struct dp_display_private *dp) dp->dp_display.connector_type, dp->core_initialized, dp->phy_initialized); - dp_power_init(dp->power, false); + dp_power_init(dp->power); dp_ctrl_reset_irq_ctrl(dp->ctrl, true); dp_aux_init(dp->aux); dp->core_initialized = true; @@ -490,11 +487,6 @@ static int dp_display_usbpd_configure_cb(struct device *dev) return dp_display_process_hpd_high(dp); } -static int dp_display_usbpd_disconnect_cb(struct device *dev) -{ - return 0; -} - static int dp_display_notify_disconnect(struct device *dev) { struct dp_display_private *dp = dev_get_dp_display_private(dev); @@ -579,13 +571,9 @@ static int dp_display_usbpd_attention_cb(struct device *dev) static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) { - struct dp_usbpd *hpd = dp->usbpd; u32 state; int ret; - if (!hpd) - return 0; - mutex_lock(&dp->event_mutex); state = dp->hpd_state; @@ -646,12 +634,8 @@ static void dp_display_handle_plugged_change(struct msm_dp *dp_display, static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) { - struct dp_usbpd *hpd = dp->usbpd; u32 state; - if (!hpd) - return 0; - mutex_lock(&dp->event_mutex); state = dp->hpd_state; @@ -764,24 +748,10 @@ static int dp_init_sub_modules(struct dp_display_private *dp) { int rc = 0; struct device *dev = &dp->pdev->dev; - struct dp_usbpd_cb *cb = &dp->usbpd_cb; struct dp_panel_in panel_in = { .dev = dev, }; - /* Callback APIs used for cable status change event */ - cb->configure = dp_display_usbpd_configure_cb; - cb->disconnect = dp_display_usbpd_disconnect_cb; - cb->attention = dp_display_usbpd_attention_cb; - - dp->usbpd = dp_hpd_get(dev, cb); - if (IS_ERR(dp->usbpd)) { - rc = PTR_ERR(dp->usbpd); - DRM_ERROR("failed to initialize hpd, rc = %d\n", rc); - dp->usbpd = NULL; - goto error; - } - dp->parser = dp_parser_get(dp->pdev); if (IS_ERR(dp->parser)) { rc = PTR_ERR(dp->parser); @@ -1541,7 +1511,7 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) dp = container_of(dp_display, struct dp_display_private, dp_display); dev = &dp->pdev->dev; - dp->debug = dp_debug_get(dev, dp->panel, dp->usbpd, + dp->debug = dp_debug_get(dev, dp->panel, dp->link, dp->dp_display.connector, minor); if (IS_ERR(dp->debug)) { diff --git a/drivers/gpu/drm/msm/dp/dp_hpd.c b/drivers/gpu/drm/msm/dp/dp_hpd.c deleted file mode 100644 index db98a1d431eb..000000000000 --- a/drivers/gpu/drm/msm/dp/dp_hpd.c +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. - */ - -#define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__ - -#include -#include - -#include "dp_hpd.h" - -/* DP specific VDM commands */ -#define DP_USBPD_VDM_STATUS 0x10 -#define DP_USBPD_VDM_CONFIGURE 0x11 - -/* USBPD-TypeC specific Macros */ -#define VDM_VERSION 0x0 -#define USB_C_DP_SID 0xFF01 - -struct dp_hpd_private { - struct device *dev; - struct dp_usbpd_cb *dp_cb; - struct dp_usbpd dp_usbpd; -}; - -int dp_hpd_connect(struct dp_usbpd *dp_usbpd, bool hpd) -{ - int rc = 0; - struct dp_hpd_private *hpd_priv; - - hpd_priv = container_of(dp_usbpd, struct dp_hpd_private, - dp_usbpd); - - if (!hpd_priv->dp_cb || !hpd_priv->dp_cb->configure - || !hpd_priv->dp_cb->disconnect) { - pr_err("hpd dp_cb not initialized\n"); - return -EINVAL; - } - if (hpd) - hpd_priv->dp_cb->configure(hpd_priv->dev); - else - hpd_priv->dp_cb->disconnect(hpd_priv->dev); - - return rc; -} - -struct dp_usbpd *dp_hpd_get(struct device *dev, struct dp_usbpd_cb *cb) -{ - struct dp_hpd_private *dp_hpd; - - if (!cb) { - pr_err("invalid cb data\n"); - return ERR_PTR(-EINVAL); - } - - dp_hpd = devm_kzalloc(dev, sizeof(*dp_hpd), GFP_KERNEL); - if (!dp_hpd) - return ERR_PTR(-ENOMEM); - - dp_hpd->dev = dev; - dp_hpd->dp_cb = cb; - - dp_hpd->dp_usbpd.connect = dp_hpd_connect; - - return &dp_hpd->dp_usbpd; -} diff --git a/drivers/gpu/drm/msm/dp/dp_hpd.h b/drivers/gpu/drm/msm/dp/dp_hpd.h deleted file mode 100644 index 8feec5aa5027..000000000000 --- a/drivers/gpu/drm/msm/dp/dp_hpd.h +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. - */ - -#ifndef _DP_HPD_H_ -#define _DP_HPD_H_ - -//#include - -#include -#include - -enum plug_orientation { - ORIENTATION_NONE, - ORIENTATION_CC1, - ORIENTATION_CC2, -}; - -/** - * struct dp_usbpd - DisplayPort status - * - * @orientation: plug orientation configuration - * @low_pow_st: low power state - * @adaptor_dp_en: adaptor functionality enabled - * @multi_func: multi-function preferred - * @usb_config_req: request to switch to usb - * @exit_dp_mode: request exit from displayport mode - * @hpd_irq: Change in the status since last message - * @alt_mode_cfg_done: bool to specify alt mode status - * @debug_en: bool to specify debug mode - * @connect: simulate disconnect or connect for debug mode - */ -struct dp_usbpd { - enum plug_orientation orientation; - bool low_pow_st; - bool adaptor_dp_en; - bool multi_func; - bool usb_config_req; - bool exit_dp_mode; - bool hpd_irq; - bool alt_mode_cfg_done; - bool debug_en; - - int (*connect)(struct dp_usbpd *dp_usbpd, bool hpd); -}; - -/** - * struct dp_usbpd_cb - callback functions provided by the client - * - * @configure: called by usbpd module when PD communication has - * been completed and the usb peripheral has been configured on - * dp mode. - * @disconnect: notify the cable disconnect issued by usb. - * @attention: notify any attention message issued by usb. - */ -struct dp_usbpd_cb { - int (*configure)(struct device *dev); - int (*disconnect)(struct device *dev); - int (*attention)(struct device *dev); -}; - -/** - * dp_hpd_get() - setup hpd module - * - * @dev: device instance of the caller - * @cb: struct containing callback function pointers. - * - * This function allows the client to initialize the usbpd - * module. The module will communicate with HPD module. - */ -struct dp_usbpd *dp_hpd_get(struct device *dev, struct dp_usbpd_cb *cb); - -int dp_hpd_register(struct dp_usbpd *dp_usbpd); -void dp_hpd_unregister(struct dp_usbpd *dp_usbpd); -int dp_hpd_connect(struct dp_usbpd *dp_usbpd, bool hpd); - -#endif /* _DP_HPD_H_ */ diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h index 45208b45eb53..ed1030e17e1b 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.h +++ b/drivers/gpu/drm/msm/dp/dp_panel.h @@ -10,7 +10,6 @@ #include "dp_aux.h" #include "dp_link.h" -#include "dp_hpd.h" struct edid; diff --git a/drivers/gpu/drm/msm/dp/dp_power.c b/drivers/gpu/drm/msm/dp/dp_power.c index c0aaabb03389..6f88c344db99 100644 --- a/drivers/gpu/drm/msm/dp/dp_power.c +++ b/drivers/gpu/drm/msm/dp/dp_power.c @@ -195,7 +195,7 @@ void dp_power_client_deinit(struct dp_power *dp_power) pm_runtime_disable(&power->pdev->dev); } -int dp_power_init(struct dp_power *dp_power, bool flip) +int dp_power_init(struct dp_power *dp_power) { int rc = 0; struct dp_power_private *power = NULL; diff --git a/drivers/gpu/drm/msm/dp/dp_power.h b/drivers/gpu/drm/msm/dp/dp_power.h index e3f959ffae12..a3dec200785e 100644 --- a/drivers/gpu/drm/msm/dp/dp_power.h +++ b/drivers/gpu/drm/msm/dp/dp_power.h @@ -26,13 +26,12 @@ struct dp_power { * dp_power_init() - enable power supplies for display controller * * @power: instance of power module - * @flip: bool for flipping gpio direction * return: 0 if success or error if failure. * * This API will turn on the regulators and configures gpio's * aux/hpd. */ -int dp_power_init(struct dp_power *power, bool flip); +int dp_power_init(struct dp_power *power); /** * dp_power_deinit() - turn off regulators and gpios. -- cgit v1.2.3 From 9f93258549dbc677898224b8c20d56d1eb96b66e Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Sun, 14 May 2023 20:02:55 -0700 Subject: drm/msm/dp: Clean up logs dp_power module The clk_bulk API already provides error messages indicating which specific clock in the request for which the operation failed, further more these errors are associated with the specific DisplayPort controller (rather than the shared drm_device). The additional error messages int he dp_power module does thereby not provide any benefit. While at it, none of the dp_power handles passed to these functions are dynamic in nature, so there should not be any need for runtime checking them. Drop these as well. Signed-off-by: Bjorn Andersson Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/536938/ Link: https://lore.kernel.org/r/20230515030256.300104-2-quic_bjorande@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_power.c | 62 ++++++--------------------------------- 1 file changed, 9 insertions(+), 53 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dp/dp_power.c b/drivers/gpu/drm/msm/dp/dp_power.c index 6f88c344db99..cb7e1139fba5 100644 --- a/drivers/gpu/drm/msm/dp/dp_power.c +++ b/drivers/gpu/drm/msm/dp/dp_power.c @@ -35,25 +35,16 @@ static int dp_power_clk_init(struct dp_power_private *power) stream = &power->parser->mp[DP_STREAM_PM]; rc = devm_clk_bulk_get(dev, core->num_clk, core->clocks); - if (rc) { - DRM_ERROR("failed to get %s clk. err=%d\n", - dp_parser_pm_name(DP_CORE_PM), rc); + if (rc) return rc; - } rc = devm_clk_bulk_get(dev, ctrl->num_clk, ctrl->clocks); - if (rc) { - DRM_ERROR("failed to get %s clk. err=%d\n", - dp_parser_pm_name(DP_CTRL_PM), rc); + if (rc) return -ENODEV; - } rc = devm_clk_bulk_get(dev, stream->num_clk, stream->clocks); - if (rc) { - DRM_ERROR("failed to get %s clk. err=%d\n", - dp_parser_pm_name(DP_CTRL_PM), rc); + if (rc) return -ENODEV; - } return 0; } @@ -121,11 +112,9 @@ int dp_power_clk_enable(struct dp_power *dp_power, mp = &power->parser->mp[DP_CORE_PM]; rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks); - if (rc) { - DRM_ERROR("fail to enable clks: %s. err=%d\n", - dp_parser_pm_name(DP_CORE_PM), rc); + if (rc) return rc; - } + dp_power->core_clks_on = true; } } @@ -133,10 +122,8 @@ int dp_power_clk_enable(struct dp_power *dp_power, mp = &power->parser->mp[pm_type]; if (enable) { rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks); - if (rc) { - DRM_ERROR("failed to enable clks, err: %d\n", rc); + if (rc) return rc; - } } else { clk_bulk_disable_unprepare(mp->num_clk, mp->clocks); } @@ -162,34 +149,19 @@ int dp_power_clk_enable(struct dp_power *dp_power, int dp_power_client_init(struct dp_power *dp_power) { - int rc = 0; struct dp_power_private *power; - if (!dp_power) { - DRM_ERROR("invalid power data\n"); - return -EINVAL; - } - power = container_of(dp_power, struct dp_power_private, dp_power); pm_runtime_enable(&power->pdev->dev); - rc = dp_power_clk_init(power); - if (rc) - DRM_ERROR("failed to init clocks %d\n", rc); - - return rc; + return dp_power_clk_init(power); } void dp_power_client_deinit(struct dp_power *dp_power) { struct dp_power_private *power; - if (!dp_power) { - DRM_ERROR("invalid power data\n"); - return; - } - power = container_of(dp_power, struct dp_power_private, dp_power); pm_runtime_disable(&power->pdev->dev); @@ -200,25 +172,14 @@ int dp_power_init(struct dp_power *dp_power) int rc = 0; struct dp_power_private *power = NULL; - if (!dp_power) { - DRM_ERROR("invalid power data\n"); - return -EINVAL; - } - power = container_of(dp_power, struct dp_power_private, dp_power); pm_runtime_get_sync(&power->pdev->dev); rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true); - if (rc) { - DRM_ERROR("failed to enable DP core clocks, %d\n", rc); - goto exit; - } - - return 0; + if (rc) + pm_runtime_put_sync(&power->pdev->dev); -exit: - pm_runtime_put_sync(&power->pdev->dev); return rc; } @@ -238,11 +199,6 @@ struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser) struct dp_power_private *power; struct dp_power *dp_power; - if (!parser) { - DRM_ERROR("invalid input\n"); - return ERR_PTR(-EINVAL); - } - power = devm_kzalloc(&parser->pdev->dev, sizeof(*power), GFP_KERNEL); if (!power) return ERR_PTR(-ENOMEM); -- cgit v1.2.3 From 9edac2eec47c82dcb679a285c6d9bb4b6f21a1a9 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Sun, 14 May 2023 20:02:56 -0700 Subject: drm/msm/dp: Clean up pdev/dev duplication in dp_power The dp_power module keeps track of both the DP controller's struct platform_device and struct device - with the prior pulled out of the dp_parser module. Clean up the duplication by dropping the platform_device reference and just track the passed struct device. Signed-off-by: Bjorn Andersson Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/536939/ Link: https://lore.kernel.org/r/20230515030256.300104-3-quic_bjorande@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_power.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dp/dp_power.c b/drivers/gpu/drm/msm/dp/dp_power.c index cb7e1139fba5..5cb84ca40e9e 100644 --- a/drivers/gpu/drm/msm/dp/dp_power.c +++ b/drivers/gpu/drm/msm/dp/dp_power.c @@ -14,7 +14,6 @@ struct dp_power_private { struct dp_parser *parser; - struct platform_device *pdev; struct device *dev; struct drm_device *drm_dev; struct clk *link_clk_src; @@ -28,7 +27,7 @@ static int dp_power_clk_init(struct dp_power_private *power) { int rc = 0; struct dss_module_power *core, *ctrl, *stream; - struct device *dev = &power->pdev->dev; + struct device *dev = power->dev; core = &power->parser->mp[DP_CORE_PM]; ctrl = &power->parser->mp[DP_CTRL_PM]; @@ -153,7 +152,7 @@ int dp_power_client_init(struct dp_power *dp_power) power = container_of(dp_power, struct dp_power_private, dp_power); - pm_runtime_enable(&power->pdev->dev); + pm_runtime_enable(power->dev); return dp_power_clk_init(power); } @@ -164,7 +163,7 @@ void dp_power_client_deinit(struct dp_power *dp_power) power = container_of(dp_power, struct dp_power_private, dp_power); - pm_runtime_disable(&power->pdev->dev); + pm_runtime_disable(power->dev); } int dp_power_init(struct dp_power *dp_power) @@ -174,11 +173,11 @@ int dp_power_init(struct dp_power *dp_power) power = container_of(dp_power, struct dp_power_private, dp_power); - pm_runtime_get_sync(&power->pdev->dev); + pm_runtime_get_sync(power->dev); rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true); if (rc) - pm_runtime_put_sync(&power->pdev->dev); + pm_runtime_put_sync(power->dev); return rc; } @@ -190,7 +189,7 @@ int dp_power_deinit(struct dp_power *dp_power) power = container_of(dp_power, struct dp_power_private, dp_power); dp_power_clk_enable(dp_power, DP_CORE_PM, false); - pm_runtime_put_sync(&power->pdev->dev); + pm_runtime_put_sync(power->dev); return 0; } @@ -199,12 +198,11 @@ struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser) struct dp_power_private *power; struct dp_power *dp_power; - power = devm_kzalloc(&parser->pdev->dev, sizeof(*power), GFP_KERNEL); + power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL); if (!power) return ERR_PTR(-ENOMEM); power->parser = parser; - power->pdev = parser->pdev; power->dev = dev; dp_power = &power->dp_power; -- cgit v1.2.3 From a03b7c4698d78b2e4d0c06a439d01cce8a3823bc Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 4 Jun 2023 06:13:07 +0300 Subject: drm/msm/dpu: use PINGPONG_NONE to unbind INTF from PP Currently the driver passes the PINGPONG index to dpu_hw_intf_ops::bind_pingpong_blk() callback and uses separate boolean flag to tell whether INTF should be bound or unbound. Simplify this by passing PINGPONG_NONE in case of unbinding and drop the flag completely. Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/540968/ Link: https://lore.kernel.org/r/20230604031308.894274-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 3 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 1 - 5 files changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index f32882e83255..d219a1359906 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2090,8 +2090,8 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) for (i = 0; i < dpu_enc->num_phys_encs; i++) { if (dpu_enc->phys_encs[i] && phys_enc->hw_intf->ops.bind_pingpong_blk) phys_enc->hw_intf->ops.bind_pingpong_blk( - dpu_enc->phys_encs[i]->hw_intf, false, - dpu_enc->phys_encs[i]->hw_pp->idx); + dpu_enc->phys_encs[i]->hw_intf, + PINGPONG_NONE); /* mark INTF flush as pending */ if (phys_enc->hw_ctl->ops.update_pending_flush_intf) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 4f8c9187f76d..107f0eff958c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -66,7 +66,6 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) && phys_enc->hw_intf->ops.bind_pingpong_blk) phys_enc->hw_intf->ops.bind_pingpong_blk( phys_enc->hw_intf, - true, phys_enc->hw_pp->idx); } @@ -553,8 +552,7 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc) if (phys_enc->hw_intf->ops.bind_pingpong_blk) { phys_enc->hw_intf->ops.bind_pingpong_blk( phys_enc->hw_intf, - false, - phys_enc->hw_pp->idx); + PINGPONG_NONE); ctl = phys_enc->hw_ctl; ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index e26629e9e303..662d74ded1b9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -287,7 +287,6 @@ static void dpu_encoder_phys_vid_setup_timing_engine( if (phys_enc->hw_intf->ops.bind_pingpong_blk) phys_enc->hw_intf->ops.bind_pingpong_blk( phys_enc->hw_intf, - true, phys_enc->hw_pp->idx); if (phys_enc->hw_pp->merge_3d) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 5dce18236d87..530f82e34c1e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -267,7 +267,6 @@ static void dpu_hw_intf_setup_prg_fetch( static void dpu_hw_intf_bind_pingpong_blk( struct dpu_hw_intf *intf, - bool enable, const enum dpu_pingpong pp) { struct dpu_hw_blk_reg_map *c = &intf->hw; @@ -276,7 +275,7 @@ static void dpu_hw_intf_bind_pingpong_blk( mux_cfg = DPU_REG_READ(c, INTF_MUX); mux_cfg &= ~0xf; - if (enable) + if (pp) mux_cfg |= (pp - PINGPONG_0) & 0x7; else mux_cfg |= 0xf; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 73b0885918f8..33895eca1211 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -88,7 +88,6 @@ struct dpu_hw_intf_ops { u32 (*get_line_count)(struct dpu_hw_intf *intf); void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, - bool enable, const enum dpu_pingpong pp); void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count); int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); -- cgit v1.2.3 From 0f86d9c980a3e4cc8b8ca604cfb5ac3537c3fba7 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 4 Jun 2023 06:13:08 +0300 Subject: drm/msm/dpu: use PINGPONG_NONE to unbind WB from PP Currently the driver passes the PINGPONG index to dpu_hw_wb_ops::bind_pingpong_blk() callback and uses separate boolean flag to tell whether WB should be bound or unbound. Simplify this by passing PINGPONG_NONE in case of unbinding and drop the flag completely. Suggested-by: Marijn Suijten Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/540969/ Link: https://lore.kernel.org/r/20230604031308.894274-2-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index d219a1359906..625f89c4d3de 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2080,8 +2080,7 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) if (phys_enc->hw_wb) { /* disable the PP block */ if (phys_enc->hw_wb->ops.bind_pingpong_blk) - phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, false, - phys_enc->hw_pp->idx); + phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, PINGPONG_NONE); /* mark WB flush as pending */ if (phys_enc->hw_ctl->ops.update_pending_flush_wb) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index e9325cafb1a8..a466ff70a4d6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -210,7 +210,7 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc) /* setup which pp blk will connect to this wb */ if (hw_pp && phys_enc->hw_wb->ops.bind_pingpong_blk) - phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, true, + phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, phys_enc->hw_pp->idx); phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c index dcffd6cc47fc..ebc416400382 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -154,7 +154,7 @@ static void dpu_hw_wb_setup_cdp(struct dpu_hw_wb *ctx, static void dpu_hw_wb_bind_pingpong_blk( struct dpu_hw_wb *ctx, - bool enable, const enum dpu_pingpong pp) + const enum dpu_pingpong pp) { struct dpu_hw_blk_reg_map *c; int mux_cfg; @@ -167,7 +167,7 @@ static void dpu_hw_wb_bind_pingpong_blk( mux_cfg = DPU_REG_READ(c, WB_MUX); mux_cfg &= ~0xf; - if (enable) + if (pp) mux_cfg |= (pp - PINGPONG_0) & 0x7; else mux_cfg |= 0xf; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h index c7f792eeb55c..2d7db2efa3d0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h @@ -49,7 +49,7 @@ struct dpu_hw_wb_ops { bool enable); void (*bind_pingpong_blk)(struct dpu_hw_wb *ctx, - bool enable, const enum dpu_pingpong pp); + const enum dpu_pingpong pp); }; /** -- cgit v1.2.3 From 3186acba5cdc10b5eb0f45a5ff7ce8c1c6e8c16c Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Tue, 6 Jun 2023 14:43:57 +0200 Subject: drm/msm/dpu: Add SM6350 support Add SM6350 support to the DPU1 driver to enable display output. It's worth noting that one entry dpu_qos_lut_entry was trimmed off: {.fl = 0, .lut = 0x0011223344556677 }, due to the lack of support for selecting between portrait and landscape LUT settings (for danger and safe LUTs) and no full support for qseed/non-qseed usescases (for QoS LUT). Signed-off-by: Konrad Dybcio Reviewed-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/541287/ Link: https://lore.kernel.org/r/20230411-topic-straitlagoon_mdss-v6-6-dee6a882571b@linaro.org Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h | 173 +++++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 5 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 1 + 4 files changed, 180 insertions(+) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h new file mode 100644 index 000000000000..06eba23b0236 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _DPU_6_4_SM6350_H +#define _DPU_6_4_SM6350_H + +static const struct dpu_caps sm6350_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0x7, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sm6350_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_20, + .ubwc_swizzle = 6, + .highest_bank_bit = 1, +}; + +static const struct dpu_mdp_cfg sm6350_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = 0, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, +}; + +static const struct dpu_ctl_cfg sm6350_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, + { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, + { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, + { + .name = "ctl_3", .id = CTL_3, + .base = 0x1600, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, +}; + +static const struct dpu_sspp_cfg sm6350_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_SC7180_MASK, + sc7180_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f8, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, 0x1f8, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, 0x1f8, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2), +}; + +static const struct dpu_lm_cfg sm6350_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, + &sc7180_lm_sblk, PINGPONG_0, LM_1, DSPP_0), + LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, + &sc7180_lm_sblk, PINGPONG_1, LM_0, 0), +}; + +static const struct dpu_dspp_cfg sm6350_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), +}; + +static struct dpu_pingpong_cfg sm6350_pp[] = { + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + -1), + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + -1), +}; + +static const struct dpu_dsc_cfg sm6350_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x80000, BIT(DPU_DSC_OUTPUT_CTRL)), +}; + +static const struct dpu_intf_cfg sm6350_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, 0, 35, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25)), + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 35, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), +}; + +static const struct dpu_perf_cfg sm6350_perf_data = { + .max_bw_low = 4200000, + .max_bw_high = 5100000, + .min_core_ib = 2500000, + .min_llcc_ib = 0, + .min_dram_ib = 1600000, + .min_prefill_lines = 35, + /* TODO: confirm danger_lut_tbl */ + .danger_lut_tbl = {0xffff, 0xffff, 0x0}, + .safe_lut_tbl = {0xff00, 0xff00, 0xffff}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile), + .entries = sm6350_qos_linear_macrotile + }, + {.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile), + .entries = sm6350_qos_linear_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +const struct dpu_mdss_cfg dpu_sm6350_cfg = { + .caps = &sm6350_dpu_caps, + .ubwc = &sm6350_ubwc_cfg, + .mdp_count = ARRAY_SIZE(sm6350_mdp), + .mdp = sm6350_mdp, + .ctl_count = ARRAY_SIZE(sm6350_ctl), + .ctl = sm6350_ctl, + .sspp_count = ARRAY_SIZE(sm6350_sspp), + .sspp = sm6350_sspp, + .mixer_count = ARRAY_SIZE(sm6350_lm), + .mixer = sm6350_lm, + .dspp_count = ARRAY_SIZE(sm6350_dspp), + .dspp = sm6350_dspp, + .dsc_count = ARRAY_SIZE(sm6350_dsc), + .dsc = sm6350_dsc, + .pingpong_count = ARRAY_SIZE(sm6350_pp), + .pingpong = sm6350_pp, + .intf_count = ARRAY_SIZE(sm6350_intf), + .intf = sm6350_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), + .vbif = sdm845_vbif, + .perf = &sm6350_perf_data, + .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ + BIT(MDP_SSPP_TOP0_INTR2) | \ + BIT(MDP_SSPP_TOP0_HIST_INTR) | \ + BIT(MDP_INTF0_INTR) | \ + BIT(MDP_INTF1_INTR) | \ + BIT(MDP_INTF1_TEAR_INTR), +}; + +#endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index f07eab738008..8bf6562f39e8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -689,6 +689,10 @@ static const struct dpu_qos_lut_entry sc7180_qos_linear[] = { {.fl = 0, .lut = 0x0011222222335777}, }; +static const struct dpu_qos_lut_entry sm6350_qos_linear_macrotile[] = { + {.fl = 0, .lut = 0x0011223445566777 }, +}; + static const struct dpu_qos_lut_entry sm8150_qos_linear[] = { {.fl = 0, .lut = 0x0011222222223357 }, }; @@ -744,6 +748,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { #include "catalog/dpu_6_0_sm8250.h" #include "catalog/dpu_6_2_sc7180.h" #include "catalog/dpu_6_3_sm6115.h" +#include "catalog/dpu_6_4_sm6350.h" #include "catalog/dpu_6_5_qcm2290.h" #include "catalog/dpu_7_0_sm8350.h" 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 d59a9027c4b6..e89edbe0ab98 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -832,6 +832,7 @@ extern const struct dpu_mdss_cfg dpu_sc8180x_cfg; extern const struct dpu_mdss_cfg dpu_sm8250_cfg; extern const struct dpu_mdss_cfg dpu_sc7180_cfg; extern const struct dpu_mdss_cfg dpu_sm6115_cfg; +extern const struct dpu_mdss_cfg dpu_sm6350_cfg; extern const struct dpu_mdss_cfg dpu_qcm2290_cfg; extern const struct dpu_mdss_cfg dpu_sm8350_cfg; extern const struct dpu_mdss_cfg dpu_sc7280_cfg; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 801300e6626f..6715f3762e74 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1305,6 +1305,7 @@ static const struct of_device_id dpu_dt_match[] = { { .compatible = "qcom,sc8180x-dpu", .data = &dpu_sc8180x_cfg, }, { .compatible = "qcom,sc8280xp-dpu", .data = &dpu_sc8280xp_cfg, }, { .compatible = "qcom,sm6115-dpu", .data = &dpu_sm6115_cfg, }, + { .compatible = "qcom,sm6350-dpu", .data = &dpu_sm6350_cfg, }, { .compatible = "qcom,sm8150-dpu", .data = &dpu_sm8150_cfg, }, { .compatible = "qcom,sm8250-dpu", .data = &dpu_sm8250_cfg, }, { .compatible = "qcom,sm8350-dpu", .data = &dpu_sm8350_cfg, }, -- cgit v1.2.3 From 27f0df03f3ffd3905bc320a8da4050cd645bd685 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Tue, 6 Jun 2023 14:43:59 +0200 Subject: drm/msm/dpu: Add SM6375 support Add basic SM6375 support to the DPU1 driver to enable display output. Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/541293/ Link: https://lore.kernel.org/r/20230411-topic-straitlagoon_mdss-v6-8-dee6a882571b@linaro.org Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h | 139 +++++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 1 + 4 files changed, 142 insertions(+) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h new file mode 100644 index 000000000000..d7aae45e3e66 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _DPU_6_9_SM6375_H +#define _DPU_6_9_SM6375_H + +static const struct dpu_caps sm6375_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, + .max_mixer_blendstages = 0x4, + .qseed_type = DPU_SSPP_SCALER_QSEED4, + .has_dim_layer = true, + .has_idle_pc = true, + .max_linewidth = 2160, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_ubwc_cfg sm6375_ubwc_cfg = { + .ubwc_version = DPU_HW_UBWC_VER_20, + .ubwc_swizzle = 6, + .highest_bank_bit = 1, +}; + +static const struct dpu_mdp_cfg sm6375_mdp[] = { + { + .name = "top_0", .id = MDP_TOP, + .base = 0x0, .len = 0x494, + .features = 0, + .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + }, +}; + +static const struct dpu_ctl_cfg sm6375_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x1dc, + .features = BIT(DPU_CTL_ACTIVE_CFG), + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, +}; + +static const struct dpu_sspp_cfg sm6375_sspp[] = { + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, 0x1f8, VIG_SC7180_MASK, + sm6115_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, 0x1f8, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), +}; + +static const struct dpu_lm_cfg sm6375_lm[] = { + LM_BLK("lm_0", LM_0, 0x44000, MIXER_QCM2290_MASK, + &qcm2290_lm_sblk, PINGPONG_0, 0, DSPP_0), +}; + +static const struct dpu_dspp_cfg sm6375_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), +}; + +static const struct dpu_pingpong_cfg sm6375_pp[] = { + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + -1), +}; + +static const struct dpu_dsc_cfg sm6375_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x80000, BIT(DPU_DSC_OUTPUT_CTRL)), +}; + +static const struct dpu_intf_cfg sm6375_intf[] = { + INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0), + INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), +}; + +static const struct dpu_perf_cfg sm6375_perf_data = { + .max_bw_low = 5200000, + .max_bw_high = 6200000, + .min_core_ib = 2500000, + .min_llcc_ib = 0, /* No LLCC on this SoC */ + .min_dram_ib = 1600000, + .min_prefill_lines = 24, + /* TODO: confirm danger_lut_tbl */ + .danger_lut_tbl = {0xffff, 0xffff, 0x0}, + .safe_lut_tbl = {0xfe00, 0xfe00, 0xffff}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile), + .entries = sm6350_qos_linear_macrotile + }, + {.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile), + .entries = sm6350_qos_linear_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +const struct dpu_mdss_cfg dpu_sm6375_cfg = { + .caps = &sm6375_dpu_caps, + .ubwc = &sm6375_ubwc_cfg, + .mdp_count = ARRAY_SIZE(sm6375_mdp), + .mdp = sm6375_mdp, + .ctl_count = ARRAY_SIZE(sm6375_ctl), + .ctl = sm6375_ctl, + .sspp_count = ARRAY_SIZE(sm6375_sspp), + .sspp = sm6375_sspp, + .mixer_count = ARRAY_SIZE(sm6375_lm), + .mixer = sm6375_lm, + .dspp_count = ARRAY_SIZE(sm6375_dspp), + .dspp = sm6375_dspp, + .dsc_count = ARRAY_SIZE(sm6375_dsc), + .dsc = sm6375_dsc, + .pingpong_count = ARRAY_SIZE(sm6375_pp), + .pingpong = sm6375_pp, + .intf_count = ARRAY_SIZE(sm6375_intf), + .intf = sm6375_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), + .vbif = sdm845_vbif, + .perf = &sm6375_perf_data, + .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ + BIT(MDP_SSPP_TOP0_INTR2) | \ + BIT(MDP_SSPP_TOP0_HIST_INTR) | \ + BIT(MDP_INTF1_INTR) | \ + BIT(MDP_INTF1_TEAR_INTR), +}; + +#endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 8bf6562f39e8..b9f1d58a6cac 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -750,6 +750,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { #include "catalog/dpu_6_3_sm6115.h" #include "catalog/dpu_6_4_sm6350.h" #include "catalog/dpu_6_5_qcm2290.h" +#include "catalog/dpu_6_9_sm6375.h" #include "catalog/dpu_7_0_sm8350.h" #include "catalog/dpu_7_2_sc7280.h" 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 e89edbe0ab98..ac4a9e73705c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -834,6 +834,7 @@ extern const struct dpu_mdss_cfg dpu_sc7180_cfg; extern const struct dpu_mdss_cfg dpu_sm6115_cfg; extern const struct dpu_mdss_cfg dpu_sm6350_cfg; extern const struct dpu_mdss_cfg dpu_qcm2290_cfg; +extern const struct dpu_mdss_cfg dpu_sm6375_cfg; extern const struct dpu_mdss_cfg dpu_sm8350_cfg; extern const struct dpu_mdss_cfg dpu_sc7280_cfg; extern const struct dpu_mdss_cfg dpu_sc8280xp_cfg; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 6715f3762e74..e97570287f31 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1306,6 +1306,7 @@ static const struct of_device_id dpu_dt_match[] = { { .compatible = "qcom,sc8280xp-dpu", .data = &dpu_sc8280xp_cfg, }, { .compatible = "qcom,sm6115-dpu", .data = &dpu_sm6115_cfg, }, { .compatible = "qcom,sm6350-dpu", .data = &dpu_sm6350_cfg, }, + { .compatible = "qcom,sm6375-dpu", .data = &dpu_sm6375_cfg, }, { .compatible = "qcom,sm8150-dpu", .data = &dpu_sm8150_cfg, }, { .compatible = "qcom,sm8250-dpu", .data = &dpu_sm8250_cfg, }, { .compatible = "qcom,sm8350-dpu", .data = &dpu_sm8350_cfg, }, -- cgit v1.2.3 From c2c1217e61bd80b1d21963ec7c2f8ebb9f77c2a0 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Tue, 6 Jun 2023 14:43:58 +0200 Subject: drm/msm: mdss: Add SM6350 support Add support for MDSS on SM6350. Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/541291/ Link: https://lore.kernel.org/r/20230411-topic-straitlagoon_mdss-v6-7-dee6a882571b@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_mdss.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index e8c93731aaa1..4e3a5f0c303c 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -538,6 +538,14 @@ static const struct msm_mdss_data sdm845_data = { .highest_bank_bit = 2, }; +static const struct msm_mdss_data sm6350_data = { + .ubwc_version = UBWC_2_0, + .ubwc_dec_version = UBWC_2_0, + .ubwc_swizzle = 6, + .ubwc_static = 0x1e, + .highest_bank_bit = 1, +}; + static const struct msm_mdss_data sm8150_data = { .ubwc_version = UBWC_3_0, .ubwc_dec_version = UBWC_3_0, @@ -571,6 +579,7 @@ static const struct of_device_id mdss_dt_match[] = { { .compatible = "qcom,sc8180x-mdss", .data = &sc8180x_data }, { .compatible = "qcom,sc8280xp-mdss", .data = &sc8280xp_data }, { .compatible = "qcom,sm6115-mdss", .data = &sm6115_data }, + { .compatible = "qcom,sm6350-mdss", .data = &sm6350_data }, { .compatible = "qcom,sm8150-mdss", .data = &sm8150_data }, { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data }, { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data }, -- cgit v1.2.3 From 5ff3d3a0a09ecf86f7de6089905d8c9297503da2 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Tue, 6 Jun 2023 14:44:00 +0200 Subject: drm/msm: mdss: Add SM6375 support Add support for MDSS on SM6375. Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/541295/ Link: https://lore.kernel.org/r/20230411-topic-straitlagoon_mdss-v6-9-dee6a882571b@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_mdss.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index 4e3a5f0c303c..05648c910c68 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -580,6 +580,7 @@ static const struct of_device_id mdss_dt_match[] = { { .compatible = "qcom,sc8280xp-mdss", .data = &sc8280xp_data }, { .compatible = "qcom,sm6115-mdss", .data = &sm6115_data }, { .compatible = "qcom,sm6350-mdss", .data = &sm6350_data }, + { .compatible = "qcom,sm6375-mdss", .data = &sm6350_data }, { .compatible = "qcom,sm8150-mdss", .data = &sm8150_data }, { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data }, { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data }, -- cgit v1.2.3 From 203b2019b3acc4ec851ba0461f1b30a3fd4449f5 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Tue, 6 Jun 2023 13:11:12 -0700 Subject: drm/msm/dpu: add DSC blocks to the catalog of MSM8998 MSM8998 doesn't have DSC blocks declared in the catalog. Complete DSC 1.1 support for all platforms by adding the missing blocks to MSM8998. Changes in v9: -- add MSM8998 and SC8180x to commit title Changes in v10: -- fix grammar at commit text Changes in v12: -- fix "titil" with "title" at changes in v9 Changes in v14: -- "dsc" tp "DSC" at commit title Changes in v15: -- fix merge conflicts at dpu_5_1_sc8180x.h Changes in v16 -- fix cherry-pick error by deleting both redundant .dsc and .dsc_count assignment from dpu_5_1_sc8180x.h Changes in v17 -- remove sc8180x from both commit title and text -- remove Reviewed-by Signed-off-by: Abhinav Kumar Reviewed-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/541371/ Link: https://lore.kernel.org/r/1686082272-22191-1-git-send-email-quic_khsieh@quicinc.com [DB: fixed commit message as agreed in the email discussion] Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 3c732a0360c7..7d0d0e74c3b0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -126,6 +126,11 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = { DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), }; +static const struct dpu_dsc_cfg msm8998_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x80000, 0), + DSC_BLK("dsc_1", DSC_1, 0x80400, 0), +}; + static const struct dpu_dspp_cfg msm8998_dspp[] = { DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, &msm8998_dspp_sblk), @@ -199,6 +204,8 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { .dspp = msm8998_dspp, .pingpong_count = ARRAY_SIZE(msm8998_pp), .pingpong = msm8998_pp, + .dsc_count = ARRAY_SIZE(msm8998_dsc), + .dsc = msm8998_dsc, .intf_count = ARRAY_SIZE(msm8998_intf), .intf = msm8998_intf, .vbif_count = ARRAY_SIZE(msm8998_vbif), -- cgit v1.2.3 From e7a2cf8e058e24218067694113938726db8696c9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 6 Jun 2023 11:33:03 +0300 Subject: drm/msm/dpu: tidy up some error checking The "vsync_hz" variable is unsigned int so it can't be less than zero. The dpu_kms_get_clk_rate() function used to return a u64 but I previously changed it to return an unsigned long and zero on error so it matches clk_get_rate(). Change the "vsync_hz" type to unsigned long as well and change the error checking to check for zero instead of negatives. This change does not affect runtime at all. It's just a clean up. Signed-off-by: Dan Carpenter Reviewed-by: Abhinav Kumar Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/541225/ Link: https://lore.kernel.org/r/ZH7vP2Swu8CYpgUL@moroto [DB: fixed debug message] Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 107f0eff958c..63ba0082b6ee 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -323,7 +323,7 @@ static void dpu_encoder_phys_cmd_tearcheck_config( struct dpu_hw_tear_check tc_cfg = { 0 }; struct drm_display_mode *mode; bool tc_enable = true; - u32 vsync_hz; + unsigned long vsync_hz; struct dpu_kms *dpu_kms; if (phys_enc->has_intf_te) { @@ -358,9 +358,8 @@ static void dpu_encoder_phys_cmd_tearcheck_config( * frequency divided by the no. of rows (lines) in the LCDpanel. */ vsync_hz = dpu_kms_get_clk_rate(dpu_kms, "vsync"); - if (vsync_hz <= 0) { - DPU_DEBUG_CMDENC(cmd_enc, "invalid - vsync_hz %u\n", - vsync_hz); + if (!vsync_hz) { + DPU_DEBUG_CMDENC(cmd_enc, "invalid - no vsync clock\n"); return; } @@ -380,7 +379,7 @@ static void dpu_encoder_phys_cmd_tearcheck_config( tc_cfg.rd_ptr_irq = mode->vdisplay + 1; DPU_DEBUG_CMDENC(cmd_enc, - "tc vsync_clk_speed_hz %u vtotal %u vrefresh %u\n", + "tc vsync_clk_speed_hz %lu vtotal %u vrefresh %u\n", vsync_hz, mode->vtotal, drm_mode_vrefresh(mode)); DPU_DEBUG_CMDENC(cmd_enc, "tc enable %u start_pos %u rd_ptr_irq %u\n", -- cgit v1.2.3 From a52b66172927a2a7b861b34c908850d76bc33024 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 11 Apr 2023 01:40:34 +0300 Subject: drm/msm/adreno: fix sparse warnings in a6xx code Sparse reports plenty of warnings against the a6xx code because of a6xx_gmu::mmio and a6xx_gmu::rscc members. For some reason they were defined as __iomem pointers rather than pointers to __iomem memory. Correct the __iomem attribute. Fixes: 02ef80c54e7c ("drm/msm/a6xx: update pdc/rscc GMU registers for A640/A650") Reported-by: kernel test robot Link: https://lore.kernel.org/oe-kbuild-all/202304070550.NrbhJCvP-lkp@intel.com/ Reviewed-by: Javier Martinez Canillas Reviewed-by: Stephen Boyd Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/531583/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 0bc3eb443fec..4759a8ce51e4 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -51,8 +51,8 @@ struct a6xx_gmu { struct msm_gem_address_space *aspace; - void * __iomem mmio; - void * __iomem rscc; + void __iomem *mmio; + void __iomem *rscc; int hfi_irq; int gmu_irq; -- cgit v1.2.3 From 635455260d06b5189bdf9b400d591fabd9ef90b2 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 29 Mar 2023 03:55:29 +0300 Subject: drm/msm: drop unused ring variable in msm_ioctl_gem_submit() The variable ring is not used by msm_parse_deps() and msm_ioctl_gem_submit() and thus can be dropped. Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/529340/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem_submit.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 9f5933c75e3d..38aa048471a8 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -558,8 +558,7 @@ static struct drm_syncobj **msm_parse_deps(struct msm_gem_submit *submit, struct drm_file *file, uint64_t in_syncobjs_addr, uint32_t nr_in_syncobjs, - size_t syncobj_stride, - struct msm_ringbuffer *ring) + size_t syncobj_stride) { struct drm_syncobj **syncobjs = NULL; struct drm_msm_gem_submit_syncobj syncobj_desc = {0}; @@ -808,7 +807,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, syncobjs_to_reset = msm_parse_deps(submit, file, args->in_syncobjs, args->nr_in_syncobjs, - args->syncobj_stride, ring); + args->syncobj_stride); if (IS_ERR(syncobjs_to_reset)) { ret = PTR_ERR(syncobjs_to_reset); goto out_unlock; -- cgit v1.2.3 From 38e27a6fbf2206b18417c5985dbcdeca0f2026b8 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 10 Apr 2023 21:52:26 +0300 Subject: drm/msm/a6xx: don't set IO_PGTABLE_QUIRK_ARM_OUTER_WBWA with coherent SMMU If the Adreno SMMU is dma-coherent, allocation will fail unless we disable IO_PGTABLE_QUIRK_ARM_OUTER_WBWA. Skip setting this quirk for the coherent SMMUs (like we have on sm8350 platform). Fixes: 54af0ceb7595 ("arm64: dts: qcom: sm8350: add GPU, GMU, GPU CC and SMMU nodes") Reported-by: David Heidelberg Signed-off-by: Dmitry Baryshkov Tested-by: David Heidelberg Reviewed-by: Konrad Dybcio Tested-by: Konrad Dybcio # SM8450 HDK Patchwork: https://patchwork.freedesktop.org/patch/531562/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 52da3795b175..411b7a5fa2f3 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1744,7 +1744,8 @@ a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev) * This allows GPU to set the bus attributes required to use system * cache on behalf of the iommu page table walker. */ - if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice)) + if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice) && + !device_iommu_capable(&pdev->dev, IOMMU_CAP_CACHE_COHERENCY)) quirks |= IO_PGTABLE_QUIRK_ARM_OUTER_WBWA; return adreno_iommu_create_address_space(gpu, pdev, quirks); -- cgit v1.2.3 From 171f580e32096e0cbd19e458d704b9330197d627 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 17 Apr 2023 15:55:10 -0700 Subject: drm/msm: Move cmdstream dumping out of sched kthread This is something that can block for arbitrary amounts of time as userspace consumes from the FIFO. So we don't really want this to be in the fence signaling path. Signed-off-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/532617/ --- drivers/gpu/drm/msm/msm_gem_submit.c | 2 ++ drivers/gpu/drm/msm/msm_gpu.c | 4 ---- drivers/gpu/drm/msm/msm_rd.c | 24 ++++++++---------------- 3 files changed, 10 insertions(+), 20 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 38aa048471a8..3f1aa4de3b87 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -948,6 +948,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, /* The scheduler owns a ref now: */ msm_gem_submit_get(submit); + msm_rd_dump_submit(priv->rd, submit, NULL); + drm_sched_entity_push_job(&submit->base); args->fence = submit->fence_id; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 26ebda40be4f..b1647b851018 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -748,8 +748,6 @@ void msm_gpu_retire(struct msm_gpu *gpu) /* add bo's to gpu's ring, and kick gpu: */ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) { - struct drm_device *dev = gpu->dev; - struct msm_drm_private *priv = dev->dev_private; struct msm_ringbuffer *ring = submit->ring; unsigned long flags; @@ -761,8 +759,6 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) submit->seqno = submit->hw_fence->seqno; - msm_rd_dump_submit(priv->rd, submit, NULL); - update_sw_cntrs(gpu); /* diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index db2f847c8535..8d5687d5ed78 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -83,15 +83,10 @@ struct msm_rd_state { bool open; - /* current submit to read out: */ - struct msm_gem_submit *submit; - /* fifo access is synchronized on the producer side by - * gpu->lock held by submit code (otherwise we could - * end up w/ cmds logged in different order than they - * were executed). And read_lock synchronizes the reads + * write_lock. And read_lock synchronizes the reads */ - struct mutex read_lock; + struct mutex read_lock, write_lock; wait_queue_head_t fifo_event; struct circ_buf fifo; @@ -243,6 +238,7 @@ static void rd_cleanup(struct msm_rd_state *rd) return; mutex_destroy(&rd->read_lock); + mutex_destroy(&rd->write_lock); kfree(rd); } @@ -258,6 +254,7 @@ static struct msm_rd_state *rd_init(struct drm_minor *minor, const char *name) rd->fifo.buf = rd->buf; mutex_init(&rd->read_lock); + mutex_init(&rd->write_lock); init_waitqueue_head(&rd->fifo_event); @@ -338,19 +335,15 @@ static void snapshot_buf(struct msm_rd_state *rd, if (!(submit->bos[idx].flags & MSM_SUBMIT_BO_READ)) return; - msm_gem_lock(&obj->base); buf = msm_gem_get_vaddr_active(&obj->base); if (IS_ERR(buf)) - goto out_unlock; + return; buf += offset; rd_write_section(rd, RD_BUFFER_CONTENTS, buf, size); msm_gem_put_vaddr_locked(&obj->base); - -out_unlock: - msm_gem_unlock(&obj->base); } /* called under gpu->lock */ @@ -364,10 +357,7 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, if (!rd->open) return; - /* writing into fifo is serialized by caller, and - * rd->read_lock is used to serialize the reads - */ - WARN_ON(!mutex_is_locked(&submit->gpu->lock)); + mutex_lock(&rd->write_lock); if (fmt) { va_list args; @@ -424,5 +414,7 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, break; } } + + mutex_unlock(&rd->write_lock); } #endif -- cgit v1.2.3 From 5e7665b5e484b32872bc1f44263940f094ccd814 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 30 May 2023 20:09:43 -0700 Subject: drm/msm/adreno: Add Adreno A690 support Introduce support for the Adreno A690, found in Qualcomm SC8280XP. Tested-by: Steev Klimaszewski Reviewed-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Signed-off-by: Bjorn Andersson Patchwork: https://patchwork.freedesktop.org/patch/540335/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 113 ++++++++++++++++++++++++++++- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 33 +++++++++ drivers/gpu/drm/msm/adreno/adreno_device.c | 14 ++++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 11 ++- 4 files changed, 166 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 411b7a5fa2f3..3c2488e63e06 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -588,6 +588,63 @@ const struct adreno_reglist a660_hwcg[] = { {}, }; +const struct adreno_reglist a690_hwcg[] = { + {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220}, + {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080}, + {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF}, + {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222}, + {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111}, + {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111}, + {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111}, + {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111}, + {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777}, + {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777}, + {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777}, + {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777}, + {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222}, + {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220}, + {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00}, + {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022}, + {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555}, + {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011}, + {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044}, + {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222}, + {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222}, + {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222}, + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002}, + {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222}, + {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000}, + {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}, + {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200}, + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, + {REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222}, + {REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111}, + {REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004}, + {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002}, + {REG_A6XX_RBBM_CLOCK_CNTL, 0x8AA8AA82}, + {REG_A6XX_RBBM_ISDB_CNT, 0x00000182}, + {REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000}, + {REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222}, + {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111}, + {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555}, + {REG_A6XX_GPU_GMU_AO_GMU_CGC_MODE_CNTL, 0x20200}, + {REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL, 0x10111}, + {REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL, 0x5555}, + {} +}; + static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -747,6 +804,45 @@ static const u32 a660_protect[] = { A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */ }; +/* These are for a690 */ +static const u32 a690_protect[] = { + A6XX_PROTECT_RDONLY(0x00000, 0x004ff), + A6XX_PROTECT_RDONLY(0x00501, 0x00001), + A6XX_PROTECT_RDONLY(0x0050b, 0x002f4), + A6XX_PROTECT_NORDWR(0x0050e, 0x00000), + A6XX_PROTECT_NORDWR(0x00510, 0x00000), + A6XX_PROTECT_NORDWR(0x00534, 0x00000), + A6XX_PROTECT_NORDWR(0x00800, 0x00082), + A6XX_PROTECT_NORDWR(0x008a0, 0x00008), + A6XX_PROTECT_NORDWR(0x008ab, 0x00024), + A6XX_PROTECT_RDONLY(0x008d0, 0x000bc), + A6XX_PROTECT_NORDWR(0x00900, 0x0004d), + A6XX_PROTECT_NORDWR(0x0098d, 0x00272), + A6XX_PROTECT_NORDWR(0x00e00, 0x00001), + A6XX_PROTECT_NORDWR(0x00e03, 0x0000c), + A6XX_PROTECT_NORDWR(0x03c00, 0x000c3), + A6XX_PROTECT_RDONLY(0x03cc4, 0x01fff), + A6XX_PROTECT_NORDWR(0x08630, 0x001cf), + A6XX_PROTECT_NORDWR(0x08e00, 0x00000), + A6XX_PROTECT_NORDWR(0x08e08, 0x00008), + A6XX_PROTECT_NORDWR(0x08e50, 0x0001f), + A6XX_PROTECT_NORDWR(0x08e80, 0x0027f), + A6XX_PROTECT_NORDWR(0x09624, 0x001db), + A6XX_PROTECT_NORDWR(0x09e60, 0x00011), + A6XX_PROTECT_NORDWR(0x09e78, 0x00187), + A6XX_PROTECT_NORDWR(0x0a630, 0x001cf), + A6XX_PROTECT_NORDWR(0x0ae02, 0x00000), + A6XX_PROTECT_NORDWR(0x0ae50, 0x0012f), + A6XX_PROTECT_NORDWR(0x0b604, 0x00000), + A6XX_PROTECT_NORDWR(0x0b608, 0x00006), + A6XX_PROTECT_NORDWR(0x0be02, 0x00001), + A6XX_PROTECT_NORDWR(0x0be20, 0x0015f), + A6XX_PROTECT_NORDWR(0x0d000, 0x005ff), + A6XX_PROTECT_NORDWR(0x0f000, 0x00bff), + A6XX_PROTECT_RDONLY(0x0fc00, 0x01fff), + A6XX_PROTECT_NORDWR(0x11c00, 0x00000), /*note: infiite range */ +}; + static void a6xx_set_cp_protect(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -758,6 +854,11 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) count = ARRAY_SIZE(a650_protect); count_max = 48; BUILD_BUG_ON(ARRAY_SIZE(a650_protect) > 48); + } else if (adreno_is_a690(adreno_gpu)) { + regs = a690_protect; + count = ARRAY_SIZE(a690_protect); + count_max = 48; + BUILD_BUG_ON(ARRAY_SIZE(a690_protect) > 48); } else if (adreno_is_a660_family(adreno_gpu)) { regs = a660_protect; count = ARRAY_SIZE(a660_protect); @@ -806,6 +907,13 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) uavflagprd_inv = 2; } + if (adreno_is_a690(adreno_gpu)) { + lower_bit = 2; + amsbc = 1; + rgb565_predicator = 1; + uavflagprd_inv = 2; + } + if (adreno_is_7c3(adreno_gpu)) { lower_bit = 1; amsbc = 1; @@ -1084,7 +1192,7 @@ static int hw_init(struct msm_gpu *gpu) /* Setting the primFifo thresholds default values, * and vccCacheSkipDis=1 bit (0x200) for A640 and newer */ - if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) + if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu) || adreno_is_a690(adreno_gpu)) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200); else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu)) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200); @@ -1994,7 +2102,8 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) info = adreno_info(config->rev); if (info && (info->revn == 650 || info->revn == 660 || - adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), info->rev))) + info->revn == 690 || + adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), info->rev))) adreno_gpu->base.hw_apriv = true; a6xx_llc_slices_init(pdev, a6xx_gpu); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c index 2cc83e049613..25b235b49ebc 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c @@ -414,6 +414,37 @@ static void a650_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) msg->cnoc_cmds_data[1][0] = 0x60000001; } +static void a690_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) +{ + /* + * Send a single "off" entry just to get things running + * TODO: bus scaling + */ + msg->bw_level_num = 1; + + msg->ddr_cmds_num = 3; + msg->ddr_wait_bitmask = 0x01; + + msg->ddr_cmds_addrs[0] = 0x50004; + msg->ddr_cmds_addrs[1] = 0x50000; + msg->ddr_cmds_addrs[2] = 0x500ac; + + msg->ddr_cmds_data[0][0] = 0x40000000; + msg->ddr_cmds_data[0][1] = 0x40000000; + msg->ddr_cmds_data[0][2] = 0x40000000; + + /* + * These are the CX (CNOC) votes - these are used by the GMU but the + * votes are known and fixed for the target + */ + msg->cnoc_cmds_num = 1; + msg->cnoc_wait_bitmask = 0x01; + + msg->cnoc_cmds_addrs[0] = 0x5003c; + msg->cnoc_cmds_data[0][0] = 0x40000000; + msg->cnoc_cmds_data[1][0] = 0x60000001; +} + static void a660_build_bw_table(struct a6xx_hfi_msg_bw_table *msg) { /* @@ -531,6 +562,8 @@ static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu) adreno_7c3_build_bw_table(&msg); else if (adreno_is_a660(adreno_gpu)) a660_build_bw_table(&msg); + else if (adreno_is_a690(adreno_gpu)) + a690_build_bw_table(&msg); else a6xx_build_bw_table(&msg); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 8cff86e9d35c..e5a865024e94 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -355,6 +355,20 @@ static const struct adreno_info gpulist[] = { .init = a6xx_gpu_init, .zapfw = "a640_zap.mdt", .hwcg = a640_hwcg, + }, { + .rev = ADRENO_REV(6, 9, 0, ANY_ID), + .revn = 690, + .name = "A690", + .fw = { + [ADRENO_FW_SQE] = "a660_sqe.fw", + [ADRENO_FW_GMU] = "a690_gmu.bin", + }, + .gmem = SZ_4M, + .inactive_period = DRM_MSM_INACTIVE_PERIOD, + .init = a6xx_gpu_init, + .zapfw = "a690_zap.mdt", + .hwcg = a690_hwcg, + .address_space_size = SZ_16G, }, }; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index f62612a5c70f..ac9c429ca07b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -55,7 +55,7 @@ struct adreno_reglist { u32 value; }; -extern const struct adreno_reglist a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[], a660_hwcg[]; +extern const struct adreno_reglist a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[], a660_hwcg[], a690_hwcg[]; struct adreno_info { struct adreno_rev rev; @@ -272,6 +272,11 @@ static inline int adreno_is_a660(struct adreno_gpu *gpu) return gpu->revn == 660; } +static inline int adreno_is_a690(struct adreno_gpu *gpu) +{ + return gpu->revn == 690; +}; + /* check for a615, a616, a618, a619 or any derivatives */ static inline int adreno_is_a615_family(struct adreno_gpu *gpu) { @@ -280,13 +285,13 @@ static inline int adreno_is_a615_family(struct adreno_gpu *gpu) static inline int adreno_is_a660_family(struct adreno_gpu *gpu) { - return adreno_is_a660(gpu) || adreno_is_7c3(gpu); + return adreno_is_a660(gpu) || adreno_is_a690(gpu) || adreno_is_7c3(gpu); } /* check for a650, a660, or any derivatives */ static inline int adreno_is_a650_family(struct adreno_gpu *gpu) { - return gpu->revn == 650 || gpu->revn == 620 || adreno_is_a660_family(gpu); + return gpu->revn == 650 || gpu->revn == 620 || adreno_is_a660_family(gpu); } u64 adreno_private_address_space_size(struct msm_gpu *gpu); -- cgit v1.2.3 From bf08e9791ca4e598f7088f24189dc3ef802b2a9f Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 3 Jun 2023 09:43:56 -0700 Subject: drm/msm/a6xx: Fix a690 CP_PROTECT settings Allow access to CP_PERFCTR_CP_SEL[n] and RB_PERFCTR_RB_SEL which are used by fdperf and pps-provider (perfetto). Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 3c2488e63e06..ab5c446e4409 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -815,7 +815,7 @@ static const u32 a690_protect[] = { A6XX_PROTECT_NORDWR(0x00800, 0x00082), A6XX_PROTECT_NORDWR(0x008a0, 0x00008), A6XX_PROTECT_NORDWR(0x008ab, 0x00024), - A6XX_PROTECT_RDONLY(0x008d0, 0x000bc), + A6XX_PROTECT_RDONLY(0x008de, 0x000ae), A6XX_PROTECT_NORDWR(0x00900, 0x0004d), A6XX_PROTECT_NORDWR(0x0098d, 0x00272), A6XX_PROTECT_NORDWR(0x00e00, 0x00001), @@ -824,7 +824,7 @@ static const u32 a690_protect[] = { A6XX_PROTECT_RDONLY(0x03cc4, 0x01fff), A6XX_PROTECT_NORDWR(0x08630, 0x001cf), A6XX_PROTECT_NORDWR(0x08e00, 0x00000), - A6XX_PROTECT_NORDWR(0x08e08, 0x00008), + A6XX_PROTECT_NORDWR(0x08e08, 0x00007), A6XX_PROTECT_NORDWR(0x08e50, 0x0001f), A6XX_PROTECT_NORDWR(0x08e80, 0x0027f), A6XX_PROTECT_NORDWR(0x09624, 0x001db), -- cgit v1.2.3 From 736a9327365644b460e4498b1ce172ca411efcbc Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 9 Apr 2023 04:13:29 +0300 Subject: drm/msm/a5xx: really check for A510 in a5xx_gpu_init The commit 010c8bbad2cb ("drm: msm: adreno: Disable preemption on Adreno 510") added special handling for a510 (this SKU doesn't seem to support preemption, so the driver should clamp nr_rings to 1). However the gpu->revn is not yet set (it is set later, in adreno_gpu_init()) and thus the condition is always false. Check config->rev instead. Fixes: 010c8bbad2cb ("drm: msm: adreno: Disable preemption on Adreno 510") Reported-by: Adam Skladowski Signed-off-by: Dmitry Baryshkov Tested-by: Adam Skladowski Patchwork: https://patchwork.freedesktop.org/patch/531511/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 1e8d2982d603..a99310b68793 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1743,6 +1743,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; + struct adreno_platform_config *config = pdev->dev.platform_data; struct a5xx_gpu *a5xx_gpu = NULL; struct adreno_gpu *adreno_gpu; struct msm_gpu *gpu; @@ -1769,7 +1770,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) nr_rings = 4; - if (adreno_is_a510(adreno_gpu)) + if (adreno_cmp_rev(ADRENO_REV(5, 1, 0, ANY_ID), config->rev)) nr_rings = 1; ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, nr_rings); -- cgit v1.2.3 From cc943f43ece7be313617ccb8425c31e02b73cbbe Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 11 Apr 2023 19:19:02 +0300 Subject: drm/msm/adreno: warn if chip revn is verified before being set The commit 010c8bbad2cb ("drm: msm: adreno: Disable preemption on Adreno 510") tried to check GPU's revn before revn being set. Add WARN_ON_ONCE to prevent such bugs from happening again. A separate helper is necessary so that the warning is displayed really just once instead of being displayed for each of comparisons. Suggested-by: Stephen Boyd Signed-off-by: Dmitry Baryshkov Reviewed-by: Stephen Boyd Patchwork: https://patchwork.freedesktop.org/patch/531705/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 63 +++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index ac9c429ca07b..4fee467c8075 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -145,40 +145,51 @@ struct adreno_platform_config { bool adreno_cmp_rev(struct adreno_rev rev1, struct adreno_rev rev2); +static inline bool adreno_is_revn(const struct adreno_gpu *gpu, uint32_t revn) +{ + WARN_ON_ONCE(!gpu->revn); + + return gpu->revn == revn; +} + static inline bool adreno_is_a2xx(struct adreno_gpu *gpu) { + WARN_ON_ONCE(!gpu->revn); + return (gpu->revn < 300); } static inline bool adreno_is_a20x(struct adreno_gpu *gpu) { + WARN_ON_ONCE(!gpu->revn); + return (gpu->revn < 210); } static inline bool adreno_is_a225(struct adreno_gpu *gpu) { - return gpu->revn == 225; + return adreno_is_revn(gpu, 225); } static inline bool adreno_is_a305(struct adreno_gpu *gpu) { - return gpu->revn == 305; + return adreno_is_revn(gpu, 305); } static inline bool adreno_is_a306(struct adreno_gpu *gpu) { /* yes, 307, because a305c is 306 */ - return gpu->revn == 307; + return adreno_is_revn(gpu, 307); } static inline bool adreno_is_a320(struct adreno_gpu *gpu) { - return gpu->revn == 320; + return adreno_is_revn(gpu, 320); } static inline bool adreno_is_a330(struct adreno_gpu *gpu) { - return gpu->revn == 330; + return adreno_is_revn(gpu, 330); } static inline bool adreno_is_a330v2(struct adreno_gpu *gpu) @@ -188,77 +199,78 @@ static inline bool adreno_is_a330v2(struct adreno_gpu *gpu) static inline int adreno_is_a405(struct adreno_gpu *gpu) { - return gpu->revn == 405; + return adreno_is_revn(gpu, 405); } static inline int adreno_is_a420(struct adreno_gpu *gpu) { - return gpu->revn == 420; + return adreno_is_revn(gpu, 420); } static inline int adreno_is_a430(struct adreno_gpu *gpu) { - return gpu->revn == 430; + return adreno_is_revn(gpu, 430); } static inline int adreno_is_a506(struct adreno_gpu *gpu) { - return gpu->revn == 506; + return adreno_is_revn(gpu, 506); } static inline int adreno_is_a508(struct adreno_gpu *gpu) { - return gpu->revn == 508; + return adreno_is_revn(gpu, 508); } static inline int adreno_is_a509(struct adreno_gpu *gpu) { - return gpu->revn == 509; + return adreno_is_revn(gpu, 509); } static inline int adreno_is_a510(struct adreno_gpu *gpu) { - return gpu->revn == 510; + return adreno_is_revn(gpu, 510); } static inline int adreno_is_a512(struct adreno_gpu *gpu) { - return gpu->revn == 512; + return adreno_is_revn(gpu, 512); } static inline int adreno_is_a530(struct adreno_gpu *gpu) { - return gpu->revn == 530; + return adreno_is_revn(gpu, 530); } static inline int adreno_is_a540(struct adreno_gpu *gpu) { - return gpu->revn == 540; + return adreno_is_revn(gpu, 540); } static inline int adreno_is_a618(struct adreno_gpu *gpu) { - return gpu->revn == 618; + return adreno_is_revn(gpu, 618); } static inline int adreno_is_a619(struct adreno_gpu *gpu) { - return gpu->revn == 619; + return adreno_is_revn(gpu, 619); } static inline int adreno_is_a630(struct adreno_gpu *gpu) { - return gpu->revn == 630; + return adreno_is_revn(gpu, 630); } static inline int adreno_is_a640_family(struct adreno_gpu *gpu) { - return (gpu->revn == 640) || (gpu->revn == 680); + return adreno_is_revn(gpu, 640) || + adreno_is_revn(gpu, 680); } static inline int adreno_is_a650(struct adreno_gpu *gpu) { - return gpu->revn == 650; + return adreno_is_revn(gpu, 650); } static inline int adreno_is_7c3(struct adreno_gpu *gpu) @@ -269,7 +281,7 @@ static inline int adreno_is_7c3(struct adreno_gpu *gpu) static inline int adreno_is_a660(struct adreno_gpu *gpu) { - return gpu->revn == 660; + return adreno_is_revn(gpu, 660); } static inline int adreno_is_a690(struct adreno_gpu *gpu) @@ -280,7 +292,10 @@ static inline int adreno_is_a690(struct adreno_gpu *gpu) /* check for a615, a616, a618, a619 or any derivatives */ static inline int adreno_is_a615_family(struct adreno_gpu *gpu) { - return gpu->revn == 615 || gpu->revn == 616 || gpu->revn == 618 || gpu->revn == 619; + return adreno_is_revn(gpu, 615) || + adreno_is_revn(gpu, 616) || + adreno_is_revn(gpu, 618) || + adreno_is_revn(gpu, 619); } static inline int adreno_is_a660_family(struct adreno_gpu *gpu) @@ -291,7 +306,9 @@ static inline int adreno_is_a660_family(struct adreno_gpu *gpu) /* check for a650, a660, or any derivatives */ static inline int adreno_is_a650_family(struct adreno_gpu *gpu) { - return gpu->revn == 650 || gpu->revn == 620 || adreno_is_a660_family(gpu); + return adreno_is_revn(gpu, 650) || + adreno_is_revn(gpu, 620) || + adreno_is_a660_family(gpu); } u64 adreno_private_address_space_size(struct msm_gpu *gpu); -- cgit v1.2.3 From 1b90e8f8879c64d4f77dd1f25134397ac075b7bd Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 11 Apr 2023 19:19:03 +0300 Subject: drm/msm/adreno: change adreno_is_* functions to accept const argument All adreno_is_*() functions do not modify their argument in any way, so they can be changed to accept const struct adreno_gpu pointer. Suggested-by: Stephen Boyd Signed-off-by: Dmitry Baryshkov Reviewed-by: Stephen Boyd Patchwork: https://patchwork.freedesktop.org/patch/531706/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 56 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 4fee467c8075..1283e5fe22d2 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -152,134 +152,134 @@ static inline bool adreno_is_revn(const struct adreno_gpu *gpu, uint32_t revn) return gpu->revn == revn; } -static inline bool adreno_is_a2xx(struct adreno_gpu *gpu) +static inline bool adreno_is_a2xx(const struct adreno_gpu *gpu) { WARN_ON_ONCE(!gpu->revn); return (gpu->revn < 300); } -static inline bool adreno_is_a20x(struct adreno_gpu *gpu) +static inline bool adreno_is_a20x(const struct adreno_gpu *gpu) { WARN_ON_ONCE(!gpu->revn); return (gpu->revn < 210); } -static inline bool adreno_is_a225(struct adreno_gpu *gpu) +static inline bool adreno_is_a225(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 225); } -static inline bool adreno_is_a305(struct adreno_gpu *gpu) +static inline bool adreno_is_a305(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 305); } -static inline bool adreno_is_a306(struct adreno_gpu *gpu) +static inline bool adreno_is_a306(const struct adreno_gpu *gpu) { /* yes, 307, because a305c is 306 */ return adreno_is_revn(gpu, 307); } -static inline bool adreno_is_a320(struct adreno_gpu *gpu) +static inline bool adreno_is_a320(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 320); } -static inline bool adreno_is_a330(struct adreno_gpu *gpu) +static inline bool adreno_is_a330(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 330); } -static inline bool adreno_is_a330v2(struct adreno_gpu *gpu) +static inline bool adreno_is_a330v2(const struct adreno_gpu *gpu) { return adreno_is_a330(gpu) && (gpu->rev.patchid > 0); } -static inline int adreno_is_a405(struct adreno_gpu *gpu) +static inline int adreno_is_a405(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 405); } -static inline int adreno_is_a420(struct adreno_gpu *gpu) +static inline int adreno_is_a420(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 420); } -static inline int adreno_is_a430(struct adreno_gpu *gpu) +static inline int adreno_is_a430(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 430); } -static inline int adreno_is_a506(struct adreno_gpu *gpu) +static inline int adreno_is_a506(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 506); } -static inline int adreno_is_a508(struct adreno_gpu *gpu) +static inline int adreno_is_a508(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 508); } -static inline int adreno_is_a509(struct adreno_gpu *gpu) +static inline int adreno_is_a509(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 509); } -static inline int adreno_is_a510(struct adreno_gpu *gpu) +static inline int adreno_is_a510(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 510); } -static inline int adreno_is_a512(struct adreno_gpu *gpu) +static inline int adreno_is_a512(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 512); } -static inline int adreno_is_a530(struct adreno_gpu *gpu) +static inline int adreno_is_a530(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 530); } -static inline int adreno_is_a540(struct adreno_gpu *gpu) +static inline int adreno_is_a540(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 540); } -static inline int adreno_is_a618(struct adreno_gpu *gpu) +static inline int adreno_is_a618(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 618); } -static inline int adreno_is_a619(struct adreno_gpu *gpu) +static inline int adreno_is_a619(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 619); } -static inline int adreno_is_a630(struct adreno_gpu *gpu) +static inline int adreno_is_a630(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 630); } -static inline int adreno_is_a640_family(struct adreno_gpu *gpu) +static inline int adreno_is_a640_family(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 640) || adreno_is_revn(gpu, 680); } -static inline int adreno_is_a650(struct adreno_gpu *gpu) +static inline int adreno_is_a650(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 650); } -static inline int adreno_is_7c3(struct adreno_gpu *gpu) +static inline int adreno_is_7c3(const struct adreno_gpu *gpu) { /* The order of args is important here to handle ANY_ID correctly */ return adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), gpu->rev); } -static inline int adreno_is_a660(struct adreno_gpu *gpu) +static inline int adreno_is_a660(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 660); } @@ -290,7 +290,7 @@ static inline int adreno_is_a690(struct adreno_gpu *gpu) }; /* check for a615, a616, a618, a619 or any derivatives */ -static inline int adreno_is_a615_family(struct adreno_gpu *gpu) +static inline int adreno_is_a615_family(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 615) || adreno_is_revn(gpu, 616) || @@ -298,13 +298,13 @@ static inline int adreno_is_a615_family(struct adreno_gpu *gpu) adreno_is_revn(gpu, 619); } -static inline int adreno_is_a660_family(struct adreno_gpu *gpu) +static inline int adreno_is_a660_family(const struct adreno_gpu *gpu) { return adreno_is_a660(gpu) || adreno_is_a690(gpu) || adreno_is_7c3(gpu); } /* check for a650, a660, or any derivatives */ -static inline int adreno_is_a650_family(struct adreno_gpu *gpu) +static inline int adreno_is_a650_family(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 650) || adreno_is_revn(gpu, 620) || -- cgit v1.2.3 From b263325b4f341a0e85c1d5dc4451df2c5e4349fa Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 12 Jun 2023 21:25:27 +0300 Subject: drm/msm/adreno: make adreno_is_a690()'s argument const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change adreno_is_a690() prototype to accept the const struct adreno_gpu pointer instead of a non-const one. This fixes the following warning: In file included from drivers/gpu/drm/msm/msm_drv.c:33: drivers/gpu/drm/msm/adreno/adreno_gpu.h: In function ‘adreno_is_a660_family’: drivers/gpu/drm/msm/adreno/adreno_gpu.h:303:54: warning: passing argument 1 of ‘adreno_is_a690’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers] 303 | return adreno_is_a660(gpu) || adreno_is_a690(gpu) || adreno_is_7c3(gpu); Fixes: 1b90e8f8879c ("drm/msm/adreno: change adreno_is_* functions to accept const argument") Signed-off-by: Dmitry Baryshkov Reviewed-by: Rob Clark Reviewed-by: Douglas Anderson Patchwork: https://patchwork.freedesktop.org/patch/542138/ Link: https://lore.kernel.org/r/20230612182527.3345786-1-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 1283e5fe22d2..9a7626c7ac4d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -284,7 +284,7 @@ static inline int adreno_is_a660(const struct adreno_gpu *gpu) return adreno_is_revn(gpu, 660); } -static inline int adreno_is_a690(struct adreno_gpu *gpu) +static inline int adreno_is_a690(const struct adreno_gpu *gpu) { return gpu->revn == 690; }; -- cgit v1.2.3 From 3bcfc7b90465efd337d39b91b43972162f0d1908 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 12 Jun 2023 21:25:33 +0300 Subject: drm/msm/dpu: do not enable color-management if DSPPs are not available We can not support color management without DSPP blocks being provided in the HW catalog. Do not enable color management for CRTCs if num_dspps is 0. Fixes: 4259ff7ae509 ("drm/msm/dpu: add support for pcc color block in dpu driver") Reported-by: Yongqin Liu Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Marijn Suijten Reviewed-by: Sumit Semwal Tested-by: Yongqin Liu Patchwork: https://patchwork.freedesktop.org/patch/542141/ Link: https://lore.kernel.org/r/20230612182534.3345805-1-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 6e684a7b49a1..1edf2b6b0a26 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1463,6 +1463,8 @@ static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = { struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, struct drm_plane *cursor) { + struct msm_drm_private *priv = dev->dev_private; + struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); struct drm_crtc *crtc = NULL; struct dpu_crtc *dpu_crtc = NULL; int i, ret; @@ -1494,7 +1496,8 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); - drm_crtc_enable_color_mgmt(crtc, 0, true, 0); + if (dpu_kms->catalog->dspp_count) + drm_crtc_enable_color_mgmt(crtc, 0, true, 0); /* save user friendly CRTC name for later */ snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id); -- cgit v1.2.3 From c72375172194a371935c78b0edaae75cd0c408ea Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 12 Jun 2023 21:25:34 +0300 Subject: drm/msm/dpu/catalog: define DSPP blocks found on sdm845 Add definitions of DSPP blocks present on the sdm845 platform. This should enable color-management on sdm845-bassed devices. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Marijn Suijten Reviewed-by: Sumit Semwal Patchwork: https://patchwork.freedesktop.org/patch/542142/ Link: https://lore.kernel.org/r/20230612182534.3345805-2-dmitry.baryshkov@linaro.org --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 36ea1af10894..b6098141bb9b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -96,19 +96,30 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { static const struct dpu_lm_cfg sdm845_lm[] = { LM_BLK("lm_0", LM_0, 0x44000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_0, LM_1, 0), + &sdm845_lm_sblk, PINGPONG_0, LM_1, DSPP_0), LM_BLK("lm_1", LM_1, 0x45000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_1, LM_0, 0), + &sdm845_lm_sblk, PINGPONG_1, LM_0, DSPP_1), LM_BLK("lm_2", LM_2, 0x46000, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_2, LM_5, 0), + &sdm845_lm_sblk, PINGPONG_2, LM_5, DSPP_2), LM_BLK("lm_3", LM_3, 0x0, MIXER_SDM845_MASK, - &sdm845_lm_sblk, PINGPONG_NONE, 0, 0), + &sdm845_lm_sblk, PINGPONG_NONE, 0, DSPP_3), LM_BLK("lm_4", LM_4, 0x0, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_NONE, 0, 0), LM_BLK("lm_5", LM_5, 0x49000, MIXER_SDM845_MASK, &sdm845_lm_sblk, PINGPONG_3, LM_2, 0), }; +static const struct dpu_dspp_cfg sdm845_dspp[] = { + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), + DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), + DSPP_BLK("dspp_2", DSPP_2, 0x58000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), + DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK, + &sm8150_dspp_sblk), +}; + static const struct dpu_pingpong_cfg sdm845_pp[] = { PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), @@ -193,6 +204,8 @@ const struct dpu_mdss_cfg dpu_sdm845_cfg = { .sspp = sdm845_sspp, .mixer_count = ARRAY_SIZE(sdm845_lm), .mixer = sdm845_lm, + .dspp_count = ARRAY_SIZE(sdm845_dspp), + .dspp = sdm845_dspp, .pingpong_count = ARRAY_SIZE(sdm845_pp), .pingpong = sdm845_pp, .dsc_count = ARRAY_SIZE(sdm845_dsc), -- cgit v1.2.3 From 7df1ed6ddf3da52b020ef3c3f5597bc628c3e58e Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Wed, 24 May 2023 10:45:14 -0700 Subject: drm/display/dsc: Add flatness and initial scale value calculations Add helpers to calculate det_thresh_flatness and initial_scale_value as these calculations are defined within the DSC spec. Reviewed-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/539282/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-1-bafc7be95691@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_dsc_helper.c | 24 ++++++++++++++++++++++++ include/drm/display/drm_dsc_helper.h | 2 ++ 2 files changed, 26 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/display/drm_dsc_helper.c b/drivers/gpu/drm/display/drm_dsc_helper.c index fc187a8d8873..4efb6236d22c 100644 --- a/drivers/gpu/drm/display/drm_dsc_helper.c +++ b/drivers/gpu/drm/display/drm_dsc_helper.c @@ -1413,3 +1413,27 @@ int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg) return 0; } EXPORT_SYMBOL(drm_dsc_compute_rc_parameters); + +/** + * drm_dsc_initial_scale_value() - Calculate the initial scale value for the given DSC config + * @dsc: Pointer to DRM DSC config struct + * + * Return: Calculated initial scale value + */ +u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc) +{ + return 8 * dsc->rc_model_size / (dsc->rc_model_size - dsc->initial_offset); +} +EXPORT_SYMBOL(drm_dsc_initial_scale_value); + +/** + * drm_dsc_flatness_det_thresh() - Calculate the flatness_det_thresh for the given DSC config + * @dsc: Pointer to DRM DSC config struct + * + * Return: Calculated flatness det thresh value + */ +u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc) +{ + return 2 << (dsc->bits_per_component - 8); +} +EXPORT_SYMBOL(drm_dsc_flatness_det_thresh); diff --git a/include/drm/display/drm_dsc_helper.h b/include/drm/display/drm_dsc_helper.h index fc2104415dcb..71789fb34e17 100644 --- a/include/drm/display/drm_dsc_helper.h +++ b/include/drm/display/drm_dsc_helper.h @@ -24,6 +24,8 @@ void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_sdp, void drm_dsc_set_rc_buf_thresh(struct drm_dsc_config *vdsc_cfg); int drm_dsc_setup_rc_params(struct drm_dsc_config *vdsc_cfg, enum drm_dsc_params_type type); int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg); +u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc); +u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc); #endif /* _DRM_DSC_HELPER_H_ */ -- cgit v1.2.3 From e871a70d8ccd6dbcb30f081f5d3d8854380422fe Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 24 May 2023 10:45:15 -0700 Subject: drm/display/dsc: add helper to set semi-const parameters Add a helper setting config values which are typically constant across operating modes (table E-4 of the standard) and mux_word_size (which is a const according to 3.5.2). Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/539280/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-2-bafc7be95691@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_dsc_helper.c | 22 ++++++++++++++++++++++ include/drm/display/drm_dsc_helper.h | 1 + 2 files changed, 23 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/display/drm_dsc_helper.c b/drivers/gpu/drm/display/drm_dsc_helper.c index 4efb6236d22c..b31fe9849784 100644 --- a/drivers/gpu/drm/display/drm_dsc_helper.c +++ b/drivers/gpu/drm/display/drm_dsc_helper.c @@ -270,6 +270,28 @@ void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_payload, } EXPORT_SYMBOL(drm_dsc_pps_payload_pack); +/** + * drm_dsc_set_const_params() - Set DSC parameters considered typically + * constant across operation modes + * + * @vdsc_cfg: + * DSC Configuration data partially filled by driver + */ +void drm_dsc_set_const_params(struct drm_dsc_config *vdsc_cfg) +{ + if (!vdsc_cfg->rc_model_size) + vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST; + vdsc_cfg->rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST; + vdsc_cfg->rc_tgt_offset_high = DSC_RC_TGT_OFFSET_HI_CONST; + vdsc_cfg->rc_tgt_offset_low = DSC_RC_TGT_OFFSET_LO_CONST; + + if (vdsc_cfg->bits_per_component <= 10) + vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC; + else + vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC; +} +EXPORT_SYMBOL(drm_dsc_set_const_params); + /* From DSC_v1.11 spec, rc_parameter_Set syntax element typically constant */ static const u16 drm_dsc_rc_buf_thresh[] = { 896, 1792, 2688, 3584, 4480, 5376, 6272, 6720, 7168, 7616, diff --git a/include/drm/display/drm_dsc_helper.h b/include/drm/display/drm_dsc_helper.h index 71789fb34e17..f4e18e5d077a 100644 --- a/include/drm/display/drm_dsc_helper.h +++ b/include/drm/display/drm_dsc_helper.h @@ -21,6 +21,7 @@ void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header); int drm_dsc_dp_rc_buffer_size(u8 rc_buffer_block_size, u8 rc_buffer_size); void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_sdp, const struct drm_dsc_config *dsc_cfg); +void drm_dsc_set_const_params(struct drm_dsc_config *vdsc_cfg); void drm_dsc_set_rc_buf_thresh(struct drm_dsc_config *vdsc_cfg); int drm_dsc_setup_rc_params(struct drm_dsc_config *vdsc_cfg, enum drm_dsc_params_type type); int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg); -- cgit v1.2.3 From 68858328124162b9b42bc7b8232eee1915cc1d8f Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Wed, 24 May 2023 10:45:16 -0700 Subject: drm/display/dsc: Add drm_dsc_get_bpp_int helper Add helper to get the integer value of drm_dsc_config.bits_per_pixel Reviewed-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/539268/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-3-bafc7be95691@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_dsc_helper.c | 13 +++++++++++++ include/drm/display/drm_dsc_helper.h | 1 + 2 files changed, 14 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/display/drm_dsc_helper.c b/drivers/gpu/drm/display/drm_dsc_helper.c index b31fe9849784..4424380c6cb6 100644 --- a/drivers/gpu/drm/display/drm_dsc_helper.c +++ b/drivers/gpu/drm/display/drm_dsc_helper.c @@ -1436,6 +1436,19 @@ int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg) } EXPORT_SYMBOL(drm_dsc_compute_rc_parameters); +/** + * drm_dsc_get_bpp_int() - Get integer bits per pixel value for the given DRM DSC config + * @vdsc_cfg: Pointer to DRM DSC config struct + * + * Return: Integer BPP value + */ +u32 drm_dsc_get_bpp_int(const struct drm_dsc_config *vdsc_cfg) +{ + WARN_ON_ONCE(vdsc_cfg->bits_per_pixel & 0xf); + return vdsc_cfg->bits_per_pixel >> 4; +} +EXPORT_SYMBOL(drm_dsc_get_bpp_int); + /** * drm_dsc_initial_scale_value() - Calculate the initial scale value for the given DSC config * @dsc: Pointer to DRM DSC config struct diff --git a/include/drm/display/drm_dsc_helper.h b/include/drm/display/drm_dsc_helper.h index f4e18e5d077a..913aa2071232 100644 --- a/include/drm/display/drm_dsc_helper.h +++ b/include/drm/display/drm_dsc_helper.h @@ -27,6 +27,7 @@ int drm_dsc_setup_rc_params(struct drm_dsc_config *vdsc_cfg, enum drm_dsc_params int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg); u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc); u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc); +u32 drm_dsc_get_bpp_int(const struct drm_dsc_config *vdsc_cfg); #endif /* _DRM_DSC_HELPER_H_ */ -- cgit v1.2.3 From 49fd30a7153be027b7ae9895e9061dec15e836f7 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 24 May 2023 10:45:17 -0700 Subject: drm/msm/dsi: use DRM DSC helpers for DSC setup Use new DRM DSC helpers to setup DSI DSC configuration. The initial_scale_value needs to be adjusted according to the standard, but this is a separate change. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/539276/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-4-bafc7be95691@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 61 +++++--------------------------------- 1 file changed, 8 insertions(+), 53 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 744f2398a6d6..7892b9de9736 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1728,28 +1728,9 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, return -EINVAL; } -static u32 dsi_dsc_rc_buf_thresh[DSC_NUM_BUF_RANGES - 1] = { - 0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, - 0x69, 0x70, 0x77, 0x79, 0x7b, 0x7d, 0x7e -}; - -/* only 8bpc, 8bpp added */ -static char min_qp[DSC_NUM_BUF_RANGES] = { - 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13 -}; - -static char max_qp[DSC_NUM_BUF_RANGES] = { - 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15 -}; - -static char bpg_offset[DSC_NUM_BUF_RANGES] = { - 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12 -}; - static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc) { - int i; - u16 bpp = dsc->bits_per_pixel >> 4; + int ret; if (dsc->bits_per_pixel & 0xf) { DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n"); @@ -1761,49 +1742,23 @@ static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc return -EOPNOTSUPP; } - dsc->rc_model_size = 8192; - dsc->first_line_bpg_offset = 12; - dsc->rc_edge_factor = 6; - dsc->rc_tgt_offset_high = 3; - dsc->rc_tgt_offset_low = 3; dsc->simple_422 = 0; dsc->convert_rgb = 1; dsc->vbr_enable = 0; - /* handle only bpp = bpc = 8 */ - for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++) - dsc->rc_buf_thresh[i] = dsi_dsc_rc_buf_thresh[i]; + drm_dsc_set_const_params(dsc); + drm_dsc_set_rc_buf_thresh(dsc); - for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { - dsc->rc_range_params[i].range_min_qp = min_qp[i]; - dsc->rc_range_params[i].range_max_qp = max_qp[i]; - /* - * Range BPG Offset contains two's-complement signed values that fill - * 8 bits, yet the registers and DCS PPS field are only 6 bits wide. - */ - dsc->rc_range_params[i].range_bpg_offset = bpg_offset[i] & DSC_RANGE_BPG_OFFSET_MASK; + /* handle only bpp = bpc = 8, pre-SCR panels */ + ret = drm_dsc_setup_rc_params(dsc, DRM_DSC_1_1_PRE_SCR); + if (ret) { + DRM_DEV_ERROR(&msm_host->pdev->dev, "could not find DSC RC parameters\n"); + return ret; } - dsc->initial_offset = 6144; /* Not bpp 12 */ - if (bpp != 8) - dsc->initial_offset = 2048; /* bpp = 12 */ - - if (dsc->bits_per_component <= 10) - dsc->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC; - else - dsc->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC; - - dsc->initial_xmit_delay = 512; dsc->initial_scale_value = 32; - dsc->first_line_bpg_offset = 12; dsc->line_buf_depth = dsc->bits_per_component + 1; - /* bpc 8 */ - dsc->flatness_min_qp = 3; - dsc->flatness_max_qp = 12; - dsc->rc_quant_incr_limit0 = 11; - dsc->rc_quant_incr_limit1 = 11; - return drm_dsc_compute_rc_parameters(dsc); } -- cgit v1.2.3 From b50f06f83e0e859d93bd7bb80a2d1911f2dc176b Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Wed, 24 May 2023 10:45:18 -0700 Subject: drm/msm: Add MSM-specific DSC helper methods Introduce MSM-specific DSC helper methods, as some calculations are common between DP and DSC. Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/539272/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-5-bafc7be95691@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_dsc_helper.h | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 drivers/gpu/drm/msm/msm_dsc_helper.h (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/msm_dsc_helper.h b/drivers/gpu/drm/msm/msm_dsc_helper.h new file mode 100644 index 000000000000..b9049fe1e279 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_dsc_helper.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved + * + * Helper methods for MSM-specific DSC calculations that are common between timing engine, + * DSI, and DP. + */ + +#ifndef MSM_DSC_HELPER_H_ +#define MSM_DSC_HELPER_H_ + +#include +#include + +/** + * msm_dsc_get_slices_per_intf() - calculate number of slices per interface + * @dsc: Pointer to drm dsc config struct + * @intf_width: interface width in pixels + * Returns: Integer representing the number of slices for the given interface + */ +static inline u32 msm_dsc_get_slices_per_intf(const struct drm_dsc_config *dsc, u32 intf_width) +{ + return DIV_ROUND_UP(intf_width, dsc->slice_width); +} + +/** + * msm_dsc_get_bytes_per_line() - calculate bytes per line + * @dsc: Pointer to drm dsc config struct + * Returns: Integer value representing bytes per line. DSI and DP need + * to perform further calculations to turn this into pclk_per_intf, + * such as dividing by different values depending on if widebus is enabled. + */ +static inline u32 msm_dsc_get_bytes_per_line(const struct drm_dsc_config *dsc) +{ + return dsc->slice_count * dsc->slice_chunk_size; +} + +#endif /* MSM_DSC_HELPER_H_ */ -- cgit v1.2.3 From 44346191a210f04c52f8389b3bd989d4a2a3e1ba Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Wed, 24 May 2023 10:45:19 -0700 Subject: drm/msm/dpu: Use fixed DRM DSC helper for det_thresh_flatness The current dpu_hw_dsc calculation for det_thresh_flatness does not match the downstream calculation or the DSC spec. Use the DRM DSC helper for det_thresh_flatness to match downstream implementation and the DSC spec. Fixes: c110cfd1753e ("drm/msm/disp/dpu1: Add support for DSC") Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/539275/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-6-bafc7be95691@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 64847912a20f..99ba7eebf5a4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -3,6 +3,8 @@ * Copyright (c) 2020-2022, Linaro Limited */ +#include + #include "dpu_kms.h" #include "dpu_hw_catalog.h" #include "dpu_hwio.h" @@ -102,7 +104,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, data |= dsc->final_offset; DPU_REG_WRITE(c, DSC_DSC_OFFSET, data); - det_thresh_flatness = 7 + 2 * (dsc->bits_per_component - 8); + det_thresh_flatness = drm_dsc_flatness_det_thresh(dsc); data = det_thresh_flatness << 10; data |= dsc->flatness_max_qp << 5; data |= dsc->flatness_min_qp; -- cgit v1.2.3 From c223059e6f8340f7eac2319470984cbfc39c433b Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Wed, 24 May 2023 10:45:20 -0700 Subject: drm/msm/dpu: Fix slice_last_group_size calculation Correct the math for slice_last_group_size so that it matches the calculations downstream. Fixes: c110cfd1753e ("drm/msm/disp/dpu1: Add support for DSC") Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/539269/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-7-bafc7be95691@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 99ba7eebf5a4..509dbaa51d87 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -56,9 +56,10 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, if (is_cmd_mode) initial_lines += 1; - slice_last_group_size = 3 - (dsc->slice_width % 3); + slice_last_group_size = (dsc->slice_width + 2) % 3; + data = (initial_lines << 20); - data |= ((slice_last_group_size - 1) << 18); + data |= (slice_last_group_size << 18); /* bpp is 6.4 format, 4 LSBs bits are for fractional part */ data |= (dsc->bits_per_pixel << 8); data |= (dsc->block_pred_enable << 7); -- cgit v1.2.3 From ed1498f77419f2a636a07825492230c5562cc333 Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Wed, 24 May 2023 10:45:21 -0700 Subject: drm/msm/dsi: Use MSM and DRM DSC helper methods Use MSM and DRM DSC helper methods to configure DSC for DSI. Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/539274/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-8-bafc7be95691@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 7892b9de9736..e693022ef79f 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -28,6 +28,7 @@ #include "dsi.xml.h" #include "sfpb.xml.h" #include "dsi_cfg.h" +#include "msm_dsc_helper.h" #include "msm_kms.h" #include "msm_gem.h" #include "phy/dsi_phy.h" @@ -845,7 +846,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod /* first calculate dsc parameters and then program * compress mode registers */ - slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width); + slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay); /* * If slice_count is greater than slice_per_intf @@ -1756,7 +1757,7 @@ static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc return ret; } - dsc->initial_scale_value = 32; + dsc->initial_scale_value = drm_dsc_initial_scale_value(dsc); dsc->line_buf_depth = dsc->bits_per_component + 1; return drm_dsc_compute_rc_parameters(dsc); -- cgit v1.2.3 From 149419396a9200075de8d75becd740ae48721524 Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Wed, 24 May 2023 10:45:22 -0700 Subject: drm/msm/dsi: update hdisplay calculation for dsi_timing_setup Currently, hdisplay is being divided by 3 for DSC. However, this calculation only works for cases where BPP = 8. Update hdisplay calculation to be bytes_per_line / 3, so that it accounts for cases where BPP != 8. Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/539271/ Link: https://lore.kernel.org/r/20230329-rfc-msm-dsc-helper-v14-9-bafc7be95691@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index e693022ef79f..1a99d75025dc 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -949,7 +949,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) * pulse width same */ h_total -= hdisplay; - hdisplay /= 3; + hdisplay = msm_dsc_get_bytes_per_line(msm_host->dsc) / 3; h_total += hdisplay; ha_end = ha_start + hdisplay; } -- cgit v1.2.3 From 8c4094b275f66d725a785d2314c27e00db2141dd Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Thu, 25 May 2023 10:40:54 -0700 Subject: drm/msm/dpu: add support for DSC encoder v1.2 engine Add support for DSC 1.2 by providing the necessary hooks to program the DPU DSC 1.2 encoder. Changes in v3: -- fixed kernel test rebot report that "__iomem *off" is declared but not used at dpu_hw_dsc_config_1_2() -- unrolling thresh loops Changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- delete off and used real register name directly Changes in v7: -- replace offset with sblk->enc.base -- replace ss with slice Changes in v8: -- fixed checkpatch warning Changes in v9: -- replaced __dsc_calc_ob_max_addr() with __dsc_calc_output_buf_max_addr() -- replaced variable num_ss with num_softslice -- remove inline from function declaration changes in v10: -- rewording text of changes in v9 -- replace DPU_DSC_NATIVE_422_EN with DPU_DSC_NATIVE_42x_EN -- replace drm_dsc_calculate_flatness_det_thresh() with drm_dsc_flatness_det_thresh() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/539500/ Link: https://lore.kernel.org/r/1685036458-22683-7-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 31 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 387 +++++++++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- 5 files changed, 436 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 39d9ac05c4b6..8d02d8c33069 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ disp/dpu1/dpu_hw_dsc.o \ + disp/dpu1/dpu_hw_dsc_1_2.o \ disp/dpu1/dpu_hw_interrupts.o \ disp/dpu1/dpu_hw_intf.o \ disp/dpu1/dpu_hw_lm.o \ 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 ac4a9e73705c..d3598dd9d448 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. */ @@ -240,12 +240,18 @@ enum { }; /** - * DSC features + * DSC sub-blocks/features * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets * the pixel output from this DSC. + * @DPU_DSC_HW_REV_1_2 DSC block supports DSC 1.1 and 1.2 + * @DPU_DSC_NATIVE_42x_EN Supports NATIVE_422_EN and NATIVE_420_EN encoding + * @DPU_DSC_MAX */ enum { DPU_DSC_OUTPUT_CTRL = 0x1, + DPU_DSC_HW_REV_1_2, + DPU_DSC_NATIVE_42x_EN, + DPU_DSC_MAX }; /** @@ -301,6 +307,14 @@ struct dpu_pp_blk { u32 version; }; +/** + * struct dpu_dsc_blk - DSC Encoder sub-blk information + * @info: HW register and features supported by this sub-blk + */ +struct dpu_dsc_blk { + DPU_HW_SUBBLK_INFO; +}; + /** * enum dpu_qos_lut_usage - define QoS LUT use cases */ @@ -431,6 +445,16 @@ struct dpu_pingpong_sub_blks { struct dpu_pp_blk dither; }; +/** + * struct dpu_dsc_sub_blks - DSC sub-blks + * @enc: DSC encoder sub-block + * @ctl: DSC controller sub-block + */ +struct dpu_dsc_sub_blks { + struct dpu_dsc_blk enc; + struct dpu_dsc_blk ctl; +}; + /** * dpu_clk_ctrl_type - Defines top level clock control signals */ @@ -585,10 +609,13 @@ struct dpu_merge_3d_cfg { * struct dpu_dsc_cfg - information of DSC blocks * @id enum identifying this block * @base register offset of this block + * @len: length of hardware block * @features bit mask identifying sub-blocks/features + * @sblk: sub-blocks information */ struct dpu_dsc_cfg { DPU_HW_BLK_INFO; + const struct dpu_dsc_sub_blks *sblk; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 138080aed9dd..d5b597ab8c5c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2020-2022, Linaro Limited */ +/* + * Copyright (c) 2020-2022, Linaro Limited + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved + */ #ifndef _DPU_HW_DSC_H #define _DPU_HW_DSC_H @@ -68,6 +71,15 @@ struct dpu_hw_dsc { struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, void __iomem *addr); +/** + * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object + * @cfg: DSC catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Returns: Error code or allocated dpu_hw_dsc context + */ +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg, + void __iomem *addr); + /** * dpu_hw_dsc_destroy - destroys dsc driver context * @dsc: Pointer to dsc driver context returned by dpu_hw_dsc_init diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c new file mode 100644 index 000000000000..24fe1d98eb86 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved + */ + +#include + +#include "dpu_kms.h" +#include "dpu_hw_catalog.h" +#include "dpu_hwio.h" +#include "dpu_hw_mdss.h" +#include "dpu_hw_dsc.h" + +#define DSC_CMN_MAIN_CNF 0x00 + +/* DPU_DSC_ENC register offsets */ +#define ENC_DF_CTRL 0x00 +#define ENC_GENERAL_STATUS 0x04 +#define ENC_HSLICE_STATUS 0x08 +#define ENC_OUT_STATUS 0x0C +#define ENC_INT_STAT 0x10 +#define ENC_INT_CLR 0x14 +#define ENC_INT_MASK 0x18 +#define DSC_MAIN_CONF 0x30 +#define DSC_PICTURE_SIZE 0x34 +#define DSC_SLICE_SIZE 0x38 +#define DSC_MISC_SIZE 0x3C +#define DSC_HRD_DELAYS 0x40 +#define DSC_RC_SCALE 0x44 +#define DSC_RC_SCALE_INC_DEC 0x48 +#define DSC_RC_OFFSETS_1 0x4C +#define DSC_RC_OFFSETS_2 0x50 +#define DSC_RC_OFFSETS_3 0x54 +#define DSC_RC_OFFSETS_4 0x58 +#define DSC_FLATNESS_QP 0x5C +#define DSC_RC_MODEL_SIZE 0x60 +#define DSC_RC_CONFIG 0x64 +#define DSC_RC_BUF_THRESH_0 0x68 +#define DSC_RC_BUF_THRESH_1 0x6C +#define DSC_RC_BUF_THRESH_2 0x70 +#define DSC_RC_BUF_THRESH_3 0x74 +#define DSC_RC_MIN_QP_0 0x78 +#define DSC_RC_MIN_QP_1 0x7C +#define DSC_RC_MIN_QP_2 0x80 +#define DSC_RC_MAX_QP_0 0x84 +#define DSC_RC_MAX_QP_1 0x88 +#define DSC_RC_MAX_QP_2 0x8C +#define DSC_RC_RANGE_BPG_OFFSETS_0 0x90 +#define DSC_RC_RANGE_BPG_OFFSETS_1 0x94 +#define DSC_RC_RANGE_BPG_OFFSETS_2 0x98 + +/* DPU_DSC_CTL register offsets */ +#define DSC_CTL 0x00 +#define DSC_CFG 0x04 +#define DSC_DATA_IN_SWAP 0x08 +#define DSC_CLK_CTRL 0x0C + +static int _dsc_calc_output_buf_max_addr(struct dpu_hw_dsc *hw_dsc, int num_softslice) +{ + int max_addr = 2400 / num_softslice; + + if (hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_42x_EN)) + max_addr /= 2; + + return max_addr - 1; +}; + +static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc) +{ + struct dpu_hw_blk_reg_map *hw; + const struct dpu_dsc_sub_blks *sblk; + + if (!hw_dsc) + return; + + hw = &hw_dsc->hw; + sblk = hw_dsc->caps->sblk; + DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CFG, 0); + + DPU_REG_WRITE(hw, sblk->enc.base + ENC_DF_CTRL, 0); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_MAIN_CONF, 0); +} + +static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc, + struct drm_dsc_config *dsc, + u32 mode, + u32 initial_lines) +{ + struct dpu_hw_blk_reg_map *hw; + const struct dpu_dsc_sub_blks *sblk; + u32 data = 0; + u32 det_thresh_flatness; + u32 num_active_slice_per_enc; + u32 bpp; + + if (!hw_dsc || !dsc) + return; + + hw = &hw_dsc->hw; + + sblk = hw_dsc->caps->sblk; + + if (mode & DSC_MODE_SPLIT_PANEL) + data |= BIT(0); + + if (mode & DSC_MODE_MULTIPLEX) + data |= BIT(1); + + num_active_slice_per_enc = dsc->slice_count; + if (mode & DSC_MODE_MULTIPLEX) + num_active_slice_per_enc = dsc->slice_count / 2; + + data |= (num_active_slice_per_enc & 0x3) << 7; + + DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data); + + data = (initial_lines & 0xff); + + if (mode & DSC_MODE_VIDEO) + data |= BIT(9); + + data |= (_dsc_calc_output_buf_max_addr(hw_dsc, num_active_slice_per_enc) << 18); + + DPU_REG_WRITE(hw, sblk->enc.base + ENC_DF_CTRL, data); + + data = (dsc->dsc_version_minor & 0xf) << 28; + if (dsc->dsc_version_minor == 0x2) { + if (dsc->native_422) + data |= BIT(22); + if (dsc->native_420) + data |= BIT(21); + } + + bpp = dsc->bits_per_pixel; + /* as per hw requirement bpp should be programmed + * twice the actual value in case of 420 or 422 encoding + */ + if (dsc->native_422 || dsc->native_420) + bpp = 2 * bpp; + + data |= bpp << 10; + + if (dsc->block_pred_enable) + data |= BIT(20); + + if (dsc->convert_rgb) + data |= BIT(4); + + data |= (dsc->line_buf_depth & 0xf) << 6; + data |= dsc->bits_per_component & 0xf; + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_MAIN_CONF, data); + + data = (dsc->pic_width & 0xffff) | + ((dsc->pic_height & 0xffff) << 16); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_PICTURE_SIZE, data); + + data = (dsc->slice_width & 0xffff) | + ((dsc->slice_height & 0xffff) << 16); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_SLICE_SIZE, data); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_MISC_SIZE, + (dsc->slice_chunk_size) & 0xffff); + + data = (dsc->initial_xmit_delay & 0xffff) | + ((dsc->initial_dec_delay & 0xffff) << 16); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_HRD_DELAYS, data); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_SCALE, + dsc->initial_scale_value & 0x3f); + + data = (dsc->scale_increment_interval & 0xffff) | + ((dsc->scale_decrement_interval & 0x7ff) << 16); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_SCALE_INC_DEC, data); + + data = (dsc->first_line_bpg_offset & 0x1f) | + ((dsc->second_line_bpg_offset & 0x1f) << 5); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_1, data); + + data = (dsc->nfl_bpg_offset & 0xffff) | + ((dsc->slice_bpg_offset & 0xffff) << 16); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_2, data); + + data = (dsc->initial_offset & 0xffff) | + ((dsc->final_offset & 0xffff) << 16); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_3, data); + + data = (dsc->nsl_bpg_offset & 0xffff) | + ((dsc->second_line_offset_adj & 0xffff) << 16); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_4, data); + + det_thresh_flatness = drm_dsc_flatness_det_thresh(dsc); + data = (dsc->flatness_min_qp & 0x1f) | + ((dsc->flatness_max_qp & 0x1f) << 5) | + ((det_thresh_flatness & 0xff) << 10); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_FLATNESS_QP, data); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MODEL_SIZE, + (dsc->rc_model_size) & 0xffff); + + data = dsc->rc_edge_factor & 0xf; + data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8; + data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13; + data |= (dsc->rc_tgt_offset_high & 0xf) << 20; + data |= (dsc->rc_tgt_offset_low & 0xf) << 24; + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_CONFIG, data); + + /* program the dsc wrapper */ + data = BIT(0); /* encoder enable */ + if (dsc->native_422) + data |= BIT(8); + else if (dsc->native_420) + data |= BIT(9); + if (!dsc->convert_rgb) + data |= BIT(10); + if (dsc->bits_per_component == 8) + data |= BIT(11); + if (mode & DSC_MODE_SPLIT_PANEL) + data |= BIT(12); + if (mode & DSC_MODE_MULTIPLEX) + data |= BIT(13); + if (!(mode & DSC_MODE_VIDEO)) + data |= BIT(17); + + DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CFG, data); +} + +static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc, + struct drm_dsc_config *dsc) +{ + struct dpu_hw_blk_reg_map *hw; + const struct dpu_dsc_sub_blks *sblk; + struct drm_dsc_rc_range_parameters *rc; + + if (!hw_dsc || !dsc) + return; + + hw = &hw_dsc->hw; + + sblk = hw_dsc->caps->sblk; + + rc = dsc->rc_range_params; + + /* + * With BUF_THRESH -- 14 in total + * each register contains 4 thresh values with the last register + * containing only 2 thresh values + */ + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_0, + (dsc->rc_buf_thresh[0] << 0) | + (dsc->rc_buf_thresh[1] << 8) | + (dsc->rc_buf_thresh[2] << 16) | + (dsc->rc_buf_thresh[3] << 24)); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_1, + (dsc->rc_buf_thresh[4] << 0) | + (dsc->rc_buf_thresh[5] << 8) | + (dsc->rc_buf_thresh[6] << 16) | + (dsc->rc_buf_thresh[7] << 24)); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_2, + (dsc->rc_buf_thresh[8] << 0) | + (dsc->rc_buf_thresh[9] << 8) | + (dsc->rc_buf_thresh[10] << 16) | + (dsc->rc_buf_thresh[11] << 24)); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_3, + (dsc->rc_buf_thresh[12] << 0) | + (dsc->rc_buf_thresh[13] << 8)); + + /* + * with min/max_QP -- 5 bits + * each register contains 5 min_qp or max_qp for total of 15 + * + * With BPG_OFFSET -- 6 bits + * each register contains 5 BPG_offset for total of 15 + */ + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MIN_QP_0, + (rc[0].range_min_qp << 0) | + (rc[1].range_min_qp << 5) | + (rc[2].range_min_qp << 10) | + (rc[3].range_min_qp << 15) | + (rc[4].range_min_qp << 20)); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MAX_QP_0, + (rc[0].range_max_qp << 0) | + (rc[1].range_max_qp << 5) | + (rc[2].range_max_qp << 10) | + (rc[3].range_max_qp << 15) | + (rc[4].range_max_qp << 20)); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_RANGE_BPG_OFFSETS_0, + (rc[0].range_bpg_offset << 0) | + (rc[1].range_bpg_offset << 6) | + (rc[2].range_bpg_offset << 12) | + (rc[3].range_bpg_offset << 18) | + (rc[4].range_bpg_offset << 24)); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MIN_QP_1, + (rc[5].range_min_qp << 0) | + (rc[6].range_min_qp << 5) | + (rc[7].range_min_qp << 10) | + (rc[8].range_min_qp << 15) | + (rc[9].range_min_qp << 20)); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MAX_QP_1, + (rc[5].range_max_qp << 0) | + (rc[6].range_max_qp << 5) | + (rc[7].range_max_qp << 10) | + (rc[8].range_max_qp << 15) | + (rc[9].range_max_qp << 20)); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_RANGE_BPG_OFFSETS_1, + (rc[5].range_bpg_offset << 0) | + (rc[6].range_bpg_offset << 6) | + (rc[7].range_bpg_offset << 12) | + (rc[8].range_bpg_offset << 18) | + (rc[9].range_bpg_offset << 24)); + + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MIN_QP_2, + (rc[10].range_min_qp << 0) | + (rc[11].range_min_qp << 5) | + (rc[12].range_min_qp << 10) | + (rc[13].range_min_qp << 15) | + (rc[14].range_min_qp << 20)); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MAX_QP_2, + (rc[10].range_max_qp << 0) | + (rc[11].range_max_qp << 5) | + (rc[12].range_max_qp << 10) | + (rc[13].range_max_qp << 15) | + (rc[14].range_max_qp << 20)); + DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_RANGE_BPG_OFFSETS_2, + (rc[10].range_bpg_offset << 0) | + (rc[11].range_bpg_offset << 6) | + (rc[12].range_bpg_offset << 12) | + (rc[13].range_bpg_offset << 18) | + (rc[14].range_bpg_offset << 24)); +} + +static void dpu_hw_dsc_bind_pingpong_blk_1_2(struct dpu_hw_dsc *hw_dsc, + const enum dpu_pingpong pp) +{ + struct dpu_hw_blk_reg_map *hw; + const struct dpu_dsc_sub_blks *sblk; + int mux_cfg = 0xf; /* Disabled */ + + hw = &hw_dsc->hw; + + sblk = hw_dsc->caps->sblk; + + if (pp) + mux_cfg = (pp - PINGPONG_0) & 0x7; + + DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CTL, mux_cfg); +} + +static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops, + const unsigned long features) +{ + ops->dsc_disable = dpu_hw_dsc_disable_1_2; + ops->dsc_config = dpu_hw_dsc_config_1_2; + ops->dsc_config_thresh = dpu_hw_dsc_config_thresh_1_2; + ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2; +} + +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg, + void __iomem *addr) +{ + struct dpu_hw_dsc *c; + + c = kzalloc(sizeof(*c), GFP_KERNEL); + if (!c) + return ERR_PTR(-ENOMEM); + + c->hw.blk_addr = addr + cfg->base; + c->hw.log_mask = DPU_DBG_MASK_DSC; + + c->idx = cfg->id; + c->caps = cfg; + _setup_dcs_ops_1_2(&c->ops, c->caps->features); + + return c; +} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 2ca3c666e22f..471842bbb950 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s] " fmt, __func__ @@ -212,7 +213,11 @@ int dpu_rm_init(struct dpu_rm *rm, struct dpu_hw_dsc *hw; const struct dpu_dsc_cfg *dsc = &cat->dsc[i]; - hw = dpu_hw_dsc_init(dsc, mmio); + if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features)) + hw = dpu_hw_dsc_init_1_2(dsc, mmio); + else + hw = dpu_hw_dsc_init(dsc, mmio); + if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed dsc object creation: err %d\n", rc); -- cgit v1.2.3 From 0d1b10c633468e84e64412b8061f6f7f678f14cb Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Thu, 25 May 2023 10:40:57 -0700 Subject: drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and feature flag information. Each display compression engine (DCE) contains dual DSC encoders so both share same base address but with its own different sub block address. changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- re arrange sc8280xp_dsc[] changes in v4: -- fix checkpatch warning changes in v10: -- remove hard slice from commit text -- replace DPU_DSC_NATIVE_422_EN with DPU_DSC_NATIVE_42x_EN -- change DSC_BLK_1_2 .len from 0x100 to 0x29c changes in v11: -- remove comment at DSC_BLK_1_2 marco Signed-off-by: Abhinav Kumar Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/539507/ Link: https://lore.kernel.org/r/1685036458-22683-10-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 ++++++++++++++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 +++++++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 ++++++++++++++++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 ++++++++++++++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 ++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 20 +++++++++++++++++++- 6 files changed, 84 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 3c1b2c13398d..8da424eaee6a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -153,6 +153,18 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x50000), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sm8350_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x80000, 0x29c, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x80000, 0x29c, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), +}; + static const struct dpu_intf_cfg sm8350_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -215,6 +227,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .dspp = sm8350_dspp, .pingpong_count = ARRAY_SIZE(sm8350_pp), .pingpong = sm8350_pp, + .dsc_count = ARRAY_SIZE(sm8350_dsc), + .dsc = sm8350_dsc, .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), .merge_3d = sm8350_merge_3d, .intf_count = ARRAY_SIZE(sm8350_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 5d894cbb0a62..9cd361be28fa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -94,6 +94,11 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), }; +/* NOTE: sc7280 only has one DSC hard slice encoder */ +static const struct dpu_dsc_cfg sc7280_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x80000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), +}; + static const struct dpu_wb_cfg sc7280_wb[] = { WB_BLK("wb_2", WB_2, 0x65000, WB_SM8250_MASK, DPU_CLK_CTRL_WB2, 6, VBIF_RT, MDP_SSPP_TOP0_INTR, 4096, 4), @@ -155,6 +160,8 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { .mixer = sc7280_lm, .pingpong_count = ARRAY_SIZE(sc7280_pp), .pingpong = sc7280_pp, + .dsc_count = ARRAY_SIZE(sc7280_dsc), + .dsc = sc7280_dsc, .wb_count = ARRAY_SIZE(sc7280_wb), .wb = sc7280_wb, .intf_count = ARRAY_SIZE(sc7280_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index c3f1ae000a21..f6ce6b090f71 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -142,6 +142,20 @@ static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x50000), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sc8280xp_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x80000, 0x29c, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x80000, 0x29c, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), + DSC_BLK_1_2("dce_2_0", DSC_4, 0x82000, 0x29c, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_2_1", DSC_5, 0x82000, 0x29c, 0, dsc_sblk_1), +}; + /* TODO: INTF 3, 8 and 7 are used for MST, marked as INTF_NONE for now */ static const struct dpu_intf_cfg sc8280xp_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, @@ -217,6 +231,8 @@ const struct dpu_mdss_cfg dpu_sc8280xp_cfg = { .dspp = sc8280xp_dspp, .pingpong_count = ARRAY_SIZE(sc8280xp_pp), .pingpong = sc8280xp_pp, + .dsc_count = ARRAY_SIZE(sc8280xp_dsc), + .dsc = sc8280xp_dsc, .merge_3d_count = ARRAY_SIZE(sc8280xp_merge_3d), .merge_3d = sc8280xp_merge_3d, .intf_count = ARRAY_SIZE(sc8280xp_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 86c2e68ebd2c..8d13c369213c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -161,6 +161,18 @@ static const struct dpu_merge_3d_cfg sm8450_merge_3d[] = { MERGE_3D_BLK("merge_3d_3", MERGE_3D_3, 0x65f00), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sm8450_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x80000, 0x29c, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x80000, 0x29c, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), +}; + static const struct dpu_intf_cfg sm8450_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -223,6 +235,8 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = { .dspp = sm8450_dspp, .pingpong_count = ARRAY_SIZE(sm8450_pp), .pingpong = sm8450_pp, + .dsc_count = ARRAY_SIZE(sm8450_dsc), + .dsc = sm8450_dsc, .merge_3d_count = ARRAY_SIZE(sm8450_merge_3d), .merge_3d = sm8450_merge_3d, .intf_count = ARRAY_SIZE(sm8450_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index 85dc34458b88..f17b9a7fee85 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -165,6 +165,18 @@ static const struct dpu_merge_3d_cfg sm8550_merge_3d[] = { MERGE_3D_BLK("merge_3d_3", MERGE_3D_3, 0x66700), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sm8550_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x80000, 0x29c, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x80000, 0x29c, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), +}; + static const struct dpu_intf_cfg sm8550_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -227,6 +239,8 @@ const struct dpu_mdss_cfg dpu_sm8550_cfg = { .dspp = sm8550_dspp, .pingpong_count = ARRAY_SIZE(sm8550_pp), .pingpong = sm8550_pp, + .dsc_count = ARRAY_SIZE(sm8550_dsc), + .dsc = sm8550_dsc, .merge_3d_count = ARRAY_SIZE(sm8550_merge_3d), .merge_3d = sm8550_merge_3d, .intf_count = ARRAY_SIZE(sm8550_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index b9f1d58a6cac..008df60b00f0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -516,6 +516,16 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { /************************************************************* * DSC sub blocks config *************************************************************/ +static const struct dpu_dsc_sub_blks dsc_sblk_0 = { + .enc = {.base = 0x100, .len = 0x100}, + .ctl = {.base = 0xF00, .len = 0x10}, +}; + +static const struct dpu_dsc_sub_blks dsc_sblk_1 = { + .enc = {.base = 0x200, .len = 0x100}, + .ctl = {.base = 0xF80, .len = 0x10}, +}; + #define DSC_BLK(_name, _id, _base, _features) \ {\ .name = _name, .id = _id, \ @@ -523,6 +533,14 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { .features = _features, \ } +#define DSC_BLK_1_2(_name, _id, _base, _len, _features, _sblk) \ + {\ + .name = _name, .id = _id, \ + .base = _base, .len = _len, \ + .features = BIT(DPU_DSC_HW_REV_1_2) | _features, \ + .sblk = &_sblk, \ + } + /************************************************************* * INTF sub blocks config *************************************************************/ -- cgit v1.2.3 From 21bf617110bab03001bd86ec1a822164bacbc747 Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Fri, 9 Jun 2023 15:57:13 -0700 Subject: msm/drm/dsi: Round up DSC hdisplay calculation Currently, when compression is enabled, hdisplay is reduced via integer division. This causes issues for modes where the original hdisplay is not a multiple of 3. To fix this, use DIV_ROUND_UP to divide hdisplay. Suggested-by: Marijn Suijten Fixes: 08802f515c3cf ("drm/msm/dsi: Add support for DSC configuration") Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/541970/ Link: https://lore.kernel.org/r/20230405-add-dsc-support-v6-1-95eab864d1b6@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 1a99d75025dc..a448931af804 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -949,7 +949,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) * pulse width same */ h_total -= hdisplay; - hdisplay = msm_dsc_get_bytes_per_line(msm_host->dsc) / 3; + hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3); h_total += hdisplay; ha_end = ha_start + hdisplay; } -- cgit v1.2.3 From 7c9e4a554d4a712bc6891a49d52b1ec030ed5b4a Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Fri, 9 Jun 2023 15:57:14 -0700 Subject: drm/msm/dsi: Reduce pclk rate for compression Adjust the pclk rate to divide hdisplay by the compression ratio when DSC is enabled. Signed-off-by: Jessica Zhang Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/541972/ Link: https://lore.kernel.org/r/20230405-add-dsc-support-v6-2-95eab864d1b6@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index a448931af804..98ea1da492c7 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -561,12 +561,27 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host) clk_disable_unprepare(msm_host->byte_clk); } -static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool is_bonded_dsi) +static unsigned long dsi_adjust_pclk_for_compression(const struct drm_display_mode *mode, + const struct drm_dsc_config *dsc) +{ + int new_hdisplay = DIV_ROUND_UP(mode->hdisplay * drm_dsc_get_bpp_int(dsc), + dsc->bits_per_component * 3); + + int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay; + + return new_htotal * mode->vtotal * drm_mode_vrefresh(mode); +} + +static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, + const struct drm_dsc_config *dsc, bool is_bonded_dsi) { unsigned long pclk_rate; pclk_rate = mode->clock * 1000; + if (dsc) + pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc); + /* * For bonded DSI mode, the current DRM mode has the complete width of the * panel. Since, the complete panel is driven by two DSI controllers, @@ -585,7 +600,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d struct msm_dsi_host *msm_host = to_msm_dsi_host(host); u8 lanes = msm_host->lanes; u32 bpp = dsi_get_bpp(msm_host->format); - unsigned long pclk_rate = dsi_get_pclk_rate(mode, is_bonded_dsi); + unsigned long pclk_rate = dsi_get_pclk_rate(mode, msm_host->dsc, is_bonded_dsi); unsigned long pclk_bpp; if (lanes == 0) { @@ -604,7 +619,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { - msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi); + msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, msm_host->dsc, is_bonded_dsi); msm_host->byte_clk_rate = dsi_byte_clk_get_rate(&msm_host->base, is_bonded_dsi, msm_host->mode); -- cgit v1.2.3 From 22598cfc94bb1d6590c49ea749c785e79463cb2f Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Fri, 9 Jun 2023 15:57:15 -0700 Subject: drm/msm/dpu: Add DPU_INTF_DATA_COMPRESS feature flag for DPU >= 7.0 In DPU 7.x and later, DSC/DCE enablement registers have been moved from PINGPONG to INTF. Thus, add a DPU_INTF_DATA_COMPRESS feature flag that will be set if the DATA_COMPRESS register is in the INTF block. Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/541967/ Link: https://lore.kernel.org/r/20230405-add-dsc-support-v6-3-95eab864d1b6@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 008df60b00f0..36ba3f58dcdf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -105,7 +105,7 @@ BIT(DPU_INTF_STATUS_SUPPORTED) | \ BIT(DPU_DATA_HCTL_EN)) -#define INTF_SC7280_MASK (INTF_SC7180_MASK) +#define INTF_SC7280_MASK (INTF_SC7180_MASK | BIT(DPU_INTF_DATA_COMPRESS)) #define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \ BIT(DPU_WB_UBWC) | \ 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 d3598dd9d448..b860784ade72 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -181,6 +181,7 @@ enum { * @DPU_DATA_HCTL_EN Allows data to be transferred at different rate * than video timing * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register + * @DPU_INTF_DATA_COMPRESS INTF block has DATA_COMPRESS register * @DPU_INTF_MAX */ enum { @@ -188,6 +189,7 @@ enum { DPU_INTF_TE, DPU_DATA_HCTL_EN, DPU_INTF_STATUS_SUPPORTED, + DPU_INTF_DATA_COMPRESS, DPU_INTF_MAX }; -- cgit v1.2.3 From 1642b580347372a985ff4fbe295c7af44090c51a Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Fri, 9 Jun 2023 15:57:16 -0700 Subject: drm/msm/dpu: Set DATA_COMPRESS on command mode for DCE/DSC 1.2 Add a DPU INTF op to set the DCE_DATA_COMPRESS bit to enable the DCE/DSC 1.2 datapath Note: For now, this op is called for command mode encoders only. Changes to set DATA_COMPRESS for video mode encoders will be posted along with DSC v1.2 support for DP. Signed-off-by: Jessica Zhang Reviewed-by: Abhinav Kumar Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/541966/ Link: https://lore.kernel.org/r/20230405-add-dsc-support-v6-4-95eab864d1b6@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 13 +++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 3 +++ 3 files changed, 19 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 63ba0082b6ee..b856c6286c85 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -67,6 +67,9 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( phys_enc->hw_intf->ops.bind_pingpong_blk( phys_enc->hw_intf, phys_enc->hw_pp->idx); + + if (intf_cfg.dsc != 0 && phys_enc->hw_intf->ops.enable_compression) + phys_enc->hw_intf->ops.enable_compression(phys_enc->hw_intf); } static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 530f82e34c1e..5b0f6627e29b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -91,6 +91,7 @@ #define INTF_CFG2_DATABUS_WIDEN BIT(0) #define INTF_CFG2_DATA_HCTL_EN BIT(4) +#define INTF_CFG2_DCE_DATA_COMPRESS BIT(12) static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, @@ -512,6 +513,15 @@ static void dpu_hw_intf_disable_autorefresh(struct dpu_hw_intf *intf, } +static void dpu_hw_intf_enable_compression(struct dpu_hw_intf *ctx) +{ + u32 intf_cfg2 = DPU_REG_READ(&ctx->hw, INTF_CONFIG2); + + intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS; + + DPU_REG_WRITE(&ctx->hw, INTF_CONFIG2, intf_cfg2); +} + static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, unsigned long cap) { @@ -532,6 +542,9 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->vsync_sel = dpu_hw_intf_vsync_sel; ops->disable_autorefresh = dpu_hw_intf_disable_autorefresh; } + + if (cap & BIT(DPU_INTF_DATA_COMPRESS)) + ops->enable_compression = dpu_hw_intf_enable_compression; } struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 33895eca1211..99e21c4137f9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -70,6 +70,7 @@ struct intf_status { * @get_autorefresh: Retrieve autorefresh config from hardware * Return: 0 on success, -ETIMEDOUT on timeout * @vsync_sel: Select vsync signal for tear-effect configuration + * @enable_compression: Enable data compression */ struct dpu_hw_intf_ops { void (*setup_timing_gen)(struct dpu_hw_intf *intf, @@ -106,6 +107,8 @@ struct dpu_hw_intf_ops { * Disable autorefresh if enabled */ void (*disable_autorefresh)(struct dpu_hw_intf *intf, uint32_t encoder_id, u16 vdisplay); + + void (*enable_compression)(struct dpu_hw_intf *intf); }; struct dpu_hw_intf { -- cgit v1.2.3 From 155fa3a91d64221eb0885fd221cc8085dbef908f Mon Sep 17 00:00:00 2001 From: Jessica Zhang Date: Fri, 9 Jun 2023 15:57:17 -0700 Subject: drm/msm/dsi: Remove incorrect references to slice_count Currently, slice_count is being used to calculate word count and pkt_per_line. Instead, these values should be calculated using slice per packet, which is not the same as slice_count. Slice count represents the number of slices per interface, and its value will not always match that of slice per packet. For example, it is possible to have cases where there are multiple slices per interface but the panel specifies only one slice per packet. Thus, use the default value of one slice per packet and remove slice_count from the aforementioned calculations. Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration") Fixes: bc6b6ff8135c ("drm/msm/dsi: Use DSC slice(s) packet size to compute word count") Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang Patchwork: https://patchwork.freedesktop.org/patch/541965/ Link: https://lore.kernel.org/r/20230405-add-dsc-support-v6-5-95eab864d1b6@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi_host.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 98ea1da492c7..fb1d3a25765f 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -863,18 +863,17 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod */ slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay); - /* - * If slice_count is greater than slice_per_intf - * then default to 1. This can happen during partial - * update. - */ - if (dsc->slice_count > slice_per_intf) - dsc->slice_count = 1; - total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; eol_byte_num = total_bytes_per_intf % 3; - pkt_per_line = slice_per_intf / dsc->slice_count; + + /* + * Typically, pkt_per_line = slice_per_intf * slice_per_pkt. + * + * Since the current driver only supports slice_per_pkt = 1, + * pkt_per_line will be equal to slice per intf for now. + */ + pkt_per_line = slice_per_intf; if (is_cmd_mode) /* packet data type */ reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE); @@ -998,7 +997,14 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) if (!msm_host->dsc) wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; else - wc = msm_host->dsc->slice_chunk_size * msm_host->dsc->slice_count + 1; + /* + * When DSC is enabled, WC = slice_chunk_size * slice_per_pkt + 1. + * Currently, the driver only supports default value of slice_per_pkt = 1 + * + * TODO: Expand mipi_dsi_device struct to hold slice_per_pkt info + * and adjust DSC math to account for slice_per_pkt. + */ + wc = msm_host->dsc->slice_chunk_size + 1; dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL, DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) | -- cgit v1.2.3 From fda520976ef49d3ab66f6157053b084721d86712 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 12 Jun 2023 06:16:15 +0300 Subject: drm/msm: provide fb_dirty implemenation Since commit 93e81e38e197 ("drm/fb_helper: Minimize damage-helper overhead") the drm_fb_helper_funcs::fb_dirty helper is required for proper dirty/damage processing. The drm/msm driver requires that to function to let CMD panels to work. Use simplified version of drm_fbdev_generic_helper_fb_dirty() to fix support for CMD mode panels. Reported-by: Degdag Mohamed Fixes: 93e81e38e197 ("drm/fb_helper: Minimize damage-helper overhead") Cc: Thomas Zimmermann Signed-off-by: Dmitry Baryshkov Reviewed-by: Thomas Zimmermann Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/542002/ Link: https://lore.kernel.org/r/20230612031616.3620134-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_fbdev.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index fa9c1cbffae3..b933a85420f6 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -139,8 +139,28 @@ fail: return ret; } +static int msm_fbdev_fb_dirty(struct drm_fb_helper *helper, + struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) { + ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) + return ret; + } + + return 0; +} + static const struct drm_fb_helper_funcs msm_fb_helper_funcs = { .fb_probe = msm_fbdev_create, + .fb_dirty = msm_fbdev_fb_dirty, }; /* -- cgit v1.2.3 From a7bfb2ad2184a1fba78be35209b6019aa8cc8d4d Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 12 Jun 2023 15:01:06 -0700 Subject: drm/msm/dp: Drop aux devices together with DP controller Using devres to depopulate the aux bus made sure that upon a probe deferral the EDP panel device would be destroyed and recreated upon next attempt. But the struct device which the devres is tied to is the DPUs (drm_dev->dev), which may be happen after the DP controller is torn down. Indications of this can be seen in the commonly seen EDID-hexdump full of zeros in the log, or the occasional/rare KASAN fault where the panel's attempt to read the EDID information causes a use after free on DP resources. It's tempting to move the devres to the DP controller's struct device, but the resources used by the device(s) on the aux bus are explicitly torn down in the error path. The KASAN-reported use-after-free also remains, as the DP aux "module" explicitly frees its devres-allocated memory in this code path. As such, explicitly depopulate the aux bus in the error path, and in the component unbind path, to avoid these issues. Fixes: 2b57f726611e ("drm/msm/dp: fix aux-bus EP lifetime") Signed-off-by: Bjorn Andersson Reviewed-by: Dmitry Baryshkov Reviewed-by: Douglas Anderson Patchwork: https://patchwork.freedesktop.org/patch/542163/ Link: https://lore.kernel.org/r/20230612220106.1884039-1-quic_bjorande@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index f7d4c2b709bd..727aab2522de 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -326,6 +326,8 @@ static void dp_display_unbind(struct device *dev, struct device *master, kthread_stop(dp->ev_tsk); + of_dp_aux_depopulate_bus(dp->aux); + dp_power_client_deinit(dp->power); dp_unregister_audio_driver(dev, dp->audio); dp_aux_unregister(dp->aux); @@ -1479,11 +1481,6 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) } } -static void of_dp_aux_depopulate_bus_void(void *data) -{ - of_dp_aux_depopulate_bus(data); -} - static int dp_display_get_next_bridge(struct msm_dp *dp) { int rc; @@ -1511,12 +1508,6 @@ static int dp_display_get_next_bridge(struct msm_dp *dp) of_node_put(aux_bus); if (rc) goto error; - - rc = devm_add_action_or_reset(dp->drm_dev->dev, - of_dp_aux_depopulate_bus_void, - dp_priv->aux); - if (rc) - goto error; } else if (dp->is_edp) { DRM_ERROR("eDP aux_bus not found\n"); return -ENODEV; @@ -1540,6 +1531,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp) error: if (dp->is_edp) { + of_dp_aux_depopulate_bus(dp_priv->aux); dp_display_host_phy_exit(dp_priv); dp_display_host_deinit(dp_priv); } -- cgit v1.2.3 From fa0048a4b1fa7a50c8b0e514f5b428abdf69a6f8 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 12 Jun 2023 15:02:59 -0700 Subject: drm/msm/dp: Free resources after unregistering them The DP component's unbind operation walks through the submodules to unregister and clean things up. But if the unbind happens because the DP controller itself is being removed, all the memory for those submodules has just been freed. Change the order of these operations to avoid the many use-after-free that otherwise happens in this code path. Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support") Signed-off-by: Bjorn Andersson Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/542166/ Link: https://lore.kernel.org/r/20230612220259.1884381-1-quic_bjorande@quicinc.com Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 727aab2522de..76f13954015b 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1300,9 +1300,9 @@ static int dp_display_remove(struct platform_device *pdev) { struct dp_display_private *dp = dev_get_dp_display_private(&pdev->dev); + component_del(&pdev->dev, &dp_display_comp_ops); dp_display_deinit_sub_modules(dp); - component_del(&pdev->dev, &dp_display_comp_ops); platform_set_drvdata(pdev, NULL); return 0; -- cgit v1.2.3 From 0b78be614c503ec03636f82cea52ad735c5085e7 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 13 Jun 2023 03:09:40 +0300 Subject: drm/msm/dpu: fix sc7280 and sc7180 PINGPONG done interrupts During IRQ conversion we have lost the PP_DONE interrupts for sc7280 platform. This was left unnoticed, because this interrupt is only used for CMD outputs and probably no sc7[12]80 systems use DSI CMD panels. Fixes: 667e9985ee24 ("drm/msm/dpu: replace IRQ lookup with the data in hw catalog") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/542175/ Link: https://lore.kernel.org/r/20230613001004.3426676-2-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 8 ++++++-- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 0b05da2592c0..67566b07195a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -80,8 +80,12 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = { }; static const struct dpu_pingpong_cfg sc7180_pp[] = { - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, -1, -1), - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, -1, -1), + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + -1), + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + -1), }; static const struct dpu_intf_cfg sc7180_intf[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 9cd361be28fa..900fee410e11 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -88,10 +88,18 @@ static const struct dpu_dspp_cfg sc7280_dspp[] = { }; static const struct dpu_pingpong_cfg sc7280_pp[] = { - PP_BLK_DITHER("pingpong_0", PINGPONG_0, 0x69000, 0, sc7280_pp_sblk, -1, -1), - PP_BLK_DITHER("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1), - PP_BLK_DITHER("pingpong_2", PINGPONG_2, 0x6b000, 0, sc7280_pp_sblk, -1, -1), - PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), + PP_BLK_DITHER("pingpong_0", PINGPONG_0, 0x69000, 0, sc7280_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + -1), + PP_BLK_DITHER("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + -1), + PP_BLK_DITHER("pingpong_2", PINGPONG_2, 0x6b000, 0, sc7280_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), + -1), + PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, + DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), + -1), }; /* NOTE: sc7280 only has one DSC hard slice encoder */ -- cgit v1.2.3 From 9a6c13b847d61b0c3796820ca6e976789df59cd8 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 13 Jun 2023 03:09:41 +0300 Subject: drm/msm/dpu: correct MERGE_3D length Each MERGE_3D block has just two registers. Correct the block length accordingly. Fixes: 4369c93cf36b ("drm/msm/dpu: initial support for merge3D hardware block") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/542177/ Reviewed-by: Marijn Suijten Link: https://lore.kernel.org/r/20230613001004.3426676-3-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 36ba3f58dcdf..0de507d4d7b7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -508,7 +508,7 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { #define MERGE_3D_BLK(_name, _id, _base) \ {\ .name = _name, .id = _id, \ - .base = _base, .len = 0x100, \ + .base = _base, .len = 0x8, \ .features = MERGE_3D_SM8150_MASK, \ .sblk = NULL \ } -- cgit v1.2.3 From c7c4afd943cc98a123d0ee4f482bd9ea96ff18db Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 13 Jun 2023 03:09:42 +0300 Subject: drm/msm/dpu: remove unused INTF_NONE interfaces sm6115, sm6375 and qcm2290 do not have INTF_0. Drop corresponding interface definitions. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/542180/ Link: https://lore.kernel.org/r/20230613001004.3426676-4-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h | 1 - 3 files changed, 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h index ba9de008519b..031fc8dae3c6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -66,7 +66,6 @@ static const struct dpu_pingpong_cfg sm6115_pp[] = { }; static const struct dpu_intf_cfg sm6115_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0), INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h index 92ac348eea6b..f2808098af39 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h @@ -63,7 +63,6 @@ static const struct dpu_pingpong_cfg qcm2290_pp[] = { }; static const struct dpu_intf_cfg qcm2290_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0), INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h index d7aae45e3e66..241fa6746674 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h @@ -71,7 +71,6 @@ static const struct dpu_dsc_cfg sm6375_dsc[] = { }; static const struct dpu_intf_cfg sm6375_intf[] = { - INTF_BLK("intf_0", INTF_0, 0x00000, 0x280, INTF_NONE, 0, 0, 0, 0, 0), INTF_BLK_DSI_TE("intf_1", INTF_1, 0x6a800, 0x2c0, INTF_DSI, 0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), -- cgit v1.2.3 From e2fd7dda3bb867012836500f1816a4837ddb5079 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 15 Jun 2023 01:44:01 +0300 Subject: drm/msm/dsi: dsi_host: drop unused clocks Several source clocks are not used anymore, so stop handling them. Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/542558/ Link: https://lore.kernel.org/r/20230614224402.296825-1-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/msm/dsi/dsi_host.c | 33 --------------------------------- 1 file changed, 33 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index fb1d3a25765f..eaee621aa6c8 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -118,8 +118,6 @@ struct msm_dsi_host { struct clk *byte_clk; struct clk *esc_clk; struct clk *pixel_clk; - struct clk *byte_clk_src; - struct clk *pixel_clk_src; struct clk *byte_intf_clk; unsigned long byte_clk_rate; @@ -129,8 +127,6 @@ struct msm_dsi_host { /* DSI v2 specific clocks */ struct clk *src_clk; - struct clk *esc_clk_src; - struct clk *dsi_clk_src; unsigned long src_clk_rate; @@ -267,21 +263,6 @@ int dsi_clk_init_v2(struct msm_dsi_host *msm_host) return ret; } - msm_host->esc_clk_src = clk_get_parent(msm_host->esc_clk); - if (!msm_host->esc_clk_src) { - ret = -ENODEV; - pr_err("%s: can't get esc clock parent. ret=%d\n", - __func__, ret); - return ret; - } - - msm_host->dsi_clk_src = clk_get_parent(msm_host->src_clk); - if (!msm_host->dsi_clk_src) { - ret = -ENODEV; - pr_err("%s: can't get src clock parent. ret=%d\n", - __func__, ret); - } - return ret; } @@ -346,20 +327,6 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host) goto exit; } - msm_host->byte_clk_src = clk_get_parent(msm_host->byte_clk); - if (IS_ERR(msm_host->byte_clk_src)) { - ret = PTR_ERR(msm_host->byte_clk_src); - pr_err("%s: can't find byte_clk clock. ret=%d\n", __func__, ret); - goto exit; - } - - msm_host->pixel_clk_src = clk_get_parent(msm_host->pixel_clk); - if (IS_ERR(msm_host->pixel_clk_src)) { - ret = PTR_ERR(msm_host->pixel_clk_src); - pr_err("%s: can't find pixel_clk clock. ret=%d\n", __func__, ret); - goto exit; - } - if (cfg_hnd->ops->clk_init_ver) ret = cfg_hnd->ops->clk_init_ver(msm_host); exit: -- cgit v1.2.3 From 452c46ccf603ab181e7d0866f3137e3ae62b5f49 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 15 Jun 2023 01:44:02 +0300 Subject: drm/msm/dsi: split dsi_ctrl_config() function It makes no sense to pass NULL parameters to dsi_ctrl_config() in the disable case. Split dsi_ctrl_config() into enable and disable parts and drop unused params. Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten Patchwork: https://patchwork.freedesktop.org/patch/542559/ Link: https://lore.kernel.org/r/20230614224402.296825-2-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/msm/dsi/dsi_host.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index eaee621aa6c8..3f6dfb4f9d5a 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -705,7 +705,12 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt( } } -static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, +static void dsi_ctrl_disable(struct msm_dsi_host *msm_host) +{ + dsi_write(msm_host, REG_DSI_CTRL, 0); +} + +static void dsi_ctrl_enable(struct msm_dsi_host *msm_host, struct msm_dsi_phy_shared_timings *phy_shared_timings, struct msm_dsi_phy *phy) { u32 flags = msm_host->mode_flags; @@ -713,11 +718,6 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; u32 data = 0, lane_ctrl = 0; - if (!enable) { - dsi_write(msm_host, REG_DSI_CTRL, 0); - return; - } - if (flags & MIPI_DSI_MODE_VIDEO) { if (flags & MIPI_DSI_MODE_VIDEO_HSE) data |= DSI_VID_CFG0_PULSE_MODE_HSA_HE; @@ -802,7 +802,7 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, if (!(flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) { lane_ctrl = dsi_read(msm_host, REG_DSI_LANE_CTRL); - if (msm_dsi_phy_set_continuous_clock(phy, enable)) + if (msm_dsi_phy_set_continuous_clock(phy, true)) lane_ctrl &= ~DSI_LANE_CTRL_HS_REQ_SEL_PHY; dsi_write(msm_host, REG_DSI_LANE_CTRL, @@ -2358,7 +2358,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, dsi_timing_setup(msm_host, is_bonded_dsi); dsi_sw_reset(msm_host); - dsi_ctrl_config(msm_host, true, phy_shared_timings, phy); + dsi_ctrl_enable(msm_host, phy_shared_timings, phy); if (msm_host->disp_en_gpio) gpiod_set_value(msm_host->disp_en_gpio, 1); @@ -2390,7 +2390,7 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host) goto unlock_ret; } - dsi_ctrl_config(msm_host, false, NULL, NULL); + dsi_ctrl_disable(msm_host); if (msm_host->disp_en_gpio) gpiod_set_value(msm_host->disp_en_gpio, 0); -- cgit v1.2.3 From 87cc0d0a4204b437c4401864350e7c4ee7710f3f Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:44 +0200 Subject: drm/msm/adreno: Use adreno_is_revn for A690 The adreno_is_revn rework came at the same time as A690 introduction and that resulted in it not covering all cases. Fix it. Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542754/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 9a7626c7ac4d..5a26c8a2de7c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -286,7 +286,7 @@ static inline int adreno_is_a660(const struct adreno_gpu *gpu) static inline int adreno_is_a690(const struct adreno_gpu *gpu) { - return gpu->revn == 690; + return adreno_is_revn(gpu, 690); }; /* check for a615, a616, a618, a619 or any derivatives */ -- cgit v1.2.3 From bd31afe010ea72de2323c9d95b540f08aeada732 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:45 +0200 Subject: drm/msm/a6xx: Remove static keyword from sptprac en/disable functions These two will be reused by at least A619_holi in the non-gmu paths. Turn them non-static them to make it possible. Reviewed-by: Dmitry Baryshkov Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542751/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 4 ++-- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 8914992378f2..a6fa273d700e 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -354,7 +354,7 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state) } /* Enable CPU control of SPTP power power collapse */ -static int a6xx_sptprac_enable(struct a6xx_gmu *gmu) +int a6xx_sptprac_enable(struct a6xx_gmu *gmu) { int ret; u32 val; @@ -376,7 +376,7 @@ static int a6xx_sptprac_enable(struct a6xx_gmu *gmu) } /* Disable CPU control of SPTP power power collapse */ -static void a6xx_sptprac_disable(struct a6xx_gmu *gmu) +void a6xx_sptprac_disable(struct a6xx_gmu *gmu) { u32 val; int ret; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 4759a8ce51e4..236f81a43caa 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -193,5 +193,7 @@ int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, int index); bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu); bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu); +void a6xx_sptprac_disable(struct a6xx_gmu *gmu); +int a6xx_sptprac_enable(struct a6xx_gmu *gmu); #endif -- cgit v1.2.3 From ce8f1381fd4960634e5f2a96bdf6f4eb177bca6e Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:46 +0200 Subject: drm/msm/a6xx: Move force keepalive vote removal to a6xx_gmu_force_off() As pointed out by Akhil during the review process of GMU wrapper introduction [1], it makes sense to move this write into the function that's responsible for forcibly shutting the GMU off. It is also very convenient to move this to GMU-specific code, so that it does not have to be guarded by an if-condition to avoid calling it on GMU wrapper targets. Move the write to the aforementioned a6xx_gmu_force_off() to achieve that. No effective functional change. [1] https://lore.kernel.org/linux-arm-msm/20230501194022.GA18382@akhilpo-linux.qualcomm.com/ Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542752/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 ++++++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index a6fa273d700e..32852c161aab 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -912,6 +912,12 @@ static void a6xx_gmu_force_off(struct a6xx_gmu *gmu) struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct msm_gpu *gpu = &adreno_gpu->base; + /* + * Turn off keep alive that might have been enabled by the hang + * interrupt + */ + gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 0); + /* Flush all the queues */ a6xx_hfi_stop(gmu); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ab5c446e4409..eebb4bc7c0f9 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1382,12 +1382,6 @@ static void a6xx_recover(struct msm_gpu *gpu) /* Halt SQE first */ gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 3); - /* - * Turn off keep alive that might have been enabled by the hang - * interrupt - */ - gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 0); - pm_runtime_dont_use_autosuspend(&gpu->pdev->dev); /* active_submit won't change until we make a submission */ -- cgit v1.2.3 From 6e332c99d1aac34660c22fd1dffc5d6f83d330fa Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:47 +0200 Subject: drm/msm/a6xx: Move a6xx_bus_clear_pending_transactions to a6xx_gpu This function is responsible for telling the GPU to halt transactions on all of its relevant buses, drain them and leave them in a predictable state, so that the GPU can be e.g. reset cleanly. Move the function to a6xx_gpu.c, remove the static keyword and add a prototype in a6xx_gpu.h to accomodate for the move. Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542762/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 37 ----------------------------------- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 36 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 2 ++ 3 files changed, 38 insertions(+), 37 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 32852c161aab..6402544f6849 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -868,43 +868,6 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu) (val & 1), 100, 1000); } -#define GBIF_CLIENT_HALT_MASK BIT(0) -#define GBIF_ARB_HALT_MASK BIT(1) - -static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, - bool gx_off) -{ - struct msm_gpu *gpu = &adreno_gpu->base; - - if (!a6xx_has_gbif(adreno_gpu)) { - gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0xf); - spin_until((gpu_read(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL1) & - 0xf) == 0xf); - gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0); - - return; - } - - if (gx_off) { - /* Halt the gx side of GBIF */ - gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 1); - spin_until(gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT_ACK) & 1); - } - - /* Halt new client requests on GBIF */ - gpu_write(gpu, REG_A6XX_GBIF_HALT, GBIF_CLIENT_HALT_MASK); - spin_until((gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK) & - (GBIF_CLIENT_HALT_MASK)) == GBIF_CLIENT_HALT_MASK); - - /* Halt all AXI requests on GBIF */ - gpu_write(gpu, REG_A6XX_GBIF_HALT, GBIF_ARB_HALT_MASK); - spin_until((gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK) & - (GBIF_ARB_HALT_MASK)) == GBIF_ARB_HALT_MASK); - - /* The GBIF halt needs to be explicitly cleared */ - gpu_write(gpu, REG_A6XX_GBIF_HALT, 0x0); -} - /* Force the GMU off in case it isn't responsive */ static void a6xx_gmu_force_off(struct a6xx_gmu *gmu) { diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index eebb4bc7c0f9..a48f4e3a754a 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1705,6 +1705,42 @@ static void a6xx_llc_slices_init(struct platform_device *pdev, a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL); } +#define GBIF_CLIENT_HALT_MASK BIT(0) +#define GBIF_ARB_HALT_MASK BIT(1) + +void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off) +{ + struct msm_gpu *gpu = &adreno_gpu->base; + + if (!a6xx_has_gbif(adreno_gpu)) { + gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0xf); + spin_until((gpu_read(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL1) & + 0xf) == 0xf); + gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0); + + return; + } + + if (gx_off) { + /* Halt the gx side of GBIF */ + gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 1); + spin_until(gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT_ACK) & 1); + } + + /* Halt new client requests on GBIF */ + gpu_write(gpu, REG_A6XX_GBIF_HALT, GBIF_CLIENT_HALT_MASK); + spin_until((gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK) & + (GBIF_CLIENT_HALT_MASK)) == GBIF_CLIENT_HALT_MASK); + + /* Halt all AXI requests on GBIF */ + gpu_write(gpu, REG_A6XX_GBIF_HALT, GBIF_ARB_HALT_MASK); + spin_until((gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK) & + (GBIF_ARB_HALT_MASK)) == GBIF_ARB_HALT_MASK); + + /* The GBIF halt needs to be explicitly cleared */ + gpu_write(gpu, REG_A6XX_GBIF_HALT, 0x0); +} + static int a6xx_pm_resume(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index eea2e60ce3b7..9580def06d45 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -88,4 +88,6 @@ void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu); int a6xx_gpu_state_put(struct msm_gpu_state *state); +void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off); + #endif /* __A6XX_GPU_H__ */ -- cgit v1.2.3 From 3773a57d9c55d77ad6615f7235b91fcac0e6c65e Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:48 +0200 Subject: drm/msm/a6xx: Improve a6xx_bus_clear_pending_transactions() Unify the indentation and explain the cryptic 0xF value. Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542756/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index a48f4e3a754a..d5bd008c2947 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1705,17 +1705,18 @@ static void a6xx_llc_slices_init(struct platform_device *pdev, a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL); } -#define GBIF_CLIENT_HALT_MASK BIT(0) -#define GBIF_ARB_HALT_MASK BIT(1) +#define GBIF_CLIENT_HALT_MASK BIT(0) +#define GBIF_ARB_HALT_MASK BIT(1) +#define VBIF_XIN_HALT_CTRL0_MASK GENMASK(3, 0) void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off) { struct msm_gpu *gpu = &adreno_gpu->base; if (!a6xx_has_gbif(adreno_gpu)) { - gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0xf); + gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, VBIF_XIN_HALT_CTRL0_MASK); spin_until((gpu_read(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL1) & - 0xf) == 0xf); + (VBIF_XIN_HALT_CTRL0_MASK)) == VBIF_XIN_HALT_CTRL0_MASK); gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0); return; -- cgit v1.2.3 From 277b967829aad7b24327f246087805078a62076e Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:49 +0200 Subject: drm/msm/a6xx: Add a helper for software-resetting the GPU Introduce a6xx_gpu_sw_reset() in preparation for adding GMU wrapper GPUs and reuse it in a6xx_gmu_force_off(). This helper, contrary to the original usage in GMU code paths, adds a readback+delay sequence to ensure that the reset is never deasserted too quickly due to e.g. OoO execution going crazy. Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542758/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 3 +-- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 ++++++++++++ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 6402544f6849..906bed49f27d 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -899,8 +899,7 @@ static void a6xx_gmu_force_off(struct a6xx_gmu *gmu) a6xx_bus_clear_pending_transactions(adreno_gpu, true); /* Reset GPU core blocks */ - gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, 1); - udelay(100); + a6xx_gpu_sw_reset(gpu, true); } static void a6xx_gmu_set_initial_freq(struct msm_gpu *gpu, struct a6xx_gmu *gmu) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index d5bd008c2947..b627be3f6360 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1742,6 +1742,18 @@ void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_ gpu_write(gpu, REG_A6XX_GBIF_HALT, 0x0); } +void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert) +{ + gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, assert); + /* Perform a bogus read and add a brief delay to ensure ordering. */ + gpu_read(gpu, REG_A6XX_RBBM_SW_RESET_CMD); + udelay(1); + + /* The reset line needs to be asserted for at least 100 us */ + if (assert) + udelay(100); +} + static int a6xx_pm_resume(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index 9580def06d45..aa70390ee1c6 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -89,5 +89,6 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu); int a6xx_gpu_state_put(struct msm_gpu_state *state); void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off); +void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert); #endif /* __A6XX_GPU_H__ */ -- cgit v1.2.3 From 05a23a76d35b874dcfab2ad8e8d156d7f24894bd Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:50 +0200 Subject: drm/msm/a6xx: Remove both GBIF and RBBM GBIF halt on hw init Currently we're only deasserting REG_A6XX_RBBM_GBIF_HALT, but we also need REG_A6XX_GBIF_HALT to be set to 0. This is typically done automatically on successful GX collapse, but in case that fails, we should take care of it. Also, add a memory barrier to ensure it's gone through before jumping to further initialization. Reviewed-by: Dmitry Baryshkov Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542760/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index b627be3f6360..7e0d1dfcd993 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1111,8 +1111,12 @@ static int hw_init(struct msm_gpu *gpu) a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET); /* Clear GBIF halt in case GX domain was not collapsed */ - if (a6xx_has_gbif(adreno_gpu)) + if (a6xx_has_gbif(adreno_gpu)) { + gpu_write(gpu, REG_A6XX_GBIF_HALT, 0); gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 0); + /* Let's make extra sure that the GPU can access the memory.. */ + mb(); + } gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_CNTL, 0); -- cgit v1.2.3 From df5bb404fa925a1b1fa3893f4976094227fbc1f0 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:51 +0200 Subject: drm/msm/a6xx: Extend and explain UBWC config Rename lower_bit to hbb_lo and explain what it signifies. Add explanations (wherever possible to other tunables). Port setting min_access_length, ubwc_mode and hbb_hi from downstream. Reviewed-by: Rob Clark Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542764/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 41 ++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 7e0d1dfcd993..8aa4670b4308 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -887,10 +887,25 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) static void a6xx_set_ubwc_config(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - u32 lower_bit = 2; - u32 amsbc = 0; + /* Unknown, introduced with A650 family, related to UBWC mode/ver 4 */ u32 rgb565_predicator = 0; + /* Unknown, introduced with A650 family */ u32 uavflagprd_inv = 0; + /* Whether the minimum access length is 64 bits */ + u32 min_acc_len = 0; + /* Entirely magic, per-GPU-gen value */ + u32 ubwc_mode = 0; + /* + * The Highest Bank Bit value represents the bit of the highest DDR bank. + * We then subtract 13 from it (13 is the minimum value allowed by hw) and + * write the lowest two bits of the remaining value as hbb_lo and the + * one above it as hbb_hi to the hardware. This should ideally use DRAM + * type detection. + */ + u32 hbb_hi = 0; + u32 hbb_lo = 2; + /* Unknown, introduced with A640/680 */ + u32 amsbc = 0; /* a618 is using the hw default values */ if (adreno_is_a618(adreno_gpu)) @@ -901,32 +916,38 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) { /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */ - lower_bit = 3; + hbb_lo = 3; amsbc = 1; rgb565_predicator = 1; uavflagprd_inv = 2; } if (adreno_is_a690(adreno_gpu)) { - lower_bit = 2; + hbb_lo = 2; amsbc = 1; rgb565_predicator = 1; uavflagprd_inv = 2; } if (adreno_is_7c3(adreno_gpu)) { - lower_bit = 1; + hbb_lo = 1; amsbc = 1; rgb565_predicator = 1; uavflagprd_inv = 2; } gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, - rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); - gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); - gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, - uavflagprd_inv << 4 | lower_bit << 1); - gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, lower_bit << 21); + rgb565_predicator << 11 | hbb_hi << 10 | amsbc << 4 | + min_acc_len << 3 | hbb_lo << 1 | ubwc_mode); + + gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, hbb_hi << 4 | + min_acc_len << 3 | hbb_lo << 1 | ubwc_mode); + + gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 | + uavflagprd_inv << 4 | min_acc_len << 3 | + hbb_lo << 1 | ubwc_mode); + + gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, min_acc_len << 23 | hbb_lo << 21); } static int a6xx_cp_init(struct msm_gpu *gpu) -- cgit v1.2.3 From 30f55f3f2374b53a28f08f9a670c1ba7ade3805a Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:52 +0200 Subject: drm/msm/a6xx: Move CX GMU power counter enablement to hw_init Since the introduction of A6xx support, we've been enabling the CX GMU power counter 0 in a bit of a weird spot. Move it to hw_init so that GMU wrapper GPUs can reuse the same code paths. As a bonus, this order makes it easier to compare mainline and downstream register access traces. Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542765/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 ------ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 7 +++++++ 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 906bed49f27d..aae7ea651607 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -479,12 +479,6 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu) gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0); - /* Set up CX GMU counter 0 to count busy ticks */ - gmu_write(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, 0xff000000); - gmu_rmw(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, 0xff, 0x20); - - /* Enable the power counter */ - gmu_write(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 1); return 0; } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 8aa4670b4308..0efecde2af1a 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1256,6 +1256,13 @@ static int hw_init(struct msm_gpu *gpu) 0x3f0243f0); } + /* Set up the CX GMU counter 0 to count busy ticks */ + gmu_write(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, 0xff000000); + + /* Enable the power counter */ + gmu_rmw(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, 0xff, BIT(5)); + gmu_write(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 1); + /* Protect registers from the CP */ a6xx_set_cp_protect(gpu); -- cgit v1.2.3 From 5a903a44a98471cedf0021fac0a6a64bbe86943f Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:53 +0200 Subject: drm/msm/a6xx: Introduce GMU wrapper support Some (particularly SMD_RPM, a.k.a non-RPMh) SoCs implement A6XX GPUs but don't implement the associated GMUs. This is due to the fact that the GMU directly pokes at RPMh. Sadly, this means we have to take care of enabling & scaling power rails, clocks and bandwidth ourselves. Reuse existing Adreno-common code and modify the deeply-GMU-infused A6XX code to facilitate these GPUs. This involves if-ing out lots of GMU callbacks and introducing a new type of GMU - GMU wrapper (it's the actual name that Qualcomm uses in their downstream kernels). This is essentially a register region which is convenient to model as a device. We'll use it for managing the GDSCs. The register layout matches the actual GMU_CX/GX regions on the "real GMU" devices and lets us reuse quite a bit of gmu_read/write/rmw calls. Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542766/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 72 +++++++++- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 201 ++++++++++++++++++++++++---- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 1 + drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 14 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 8 +- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 6 + 6 files changed, 266 insertions(+), 36 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index aae7ea651607..5deb79924897 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -1431,6 +1431,7 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev, void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) { + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct a6xx_gmu *gmu = &a6xx_gpu->gmu; struct platform_device *pdev = to_platform_device(gmu->dev); @@ -1456,10 +1457,12 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) gmu->mmio = NULL; gmu->rscc = NULL; - a6xx_gmu_memory_free(gmu); + if (!adreno_has_gmu_wrapper(adreno_gpu)) { + a6xx_gmu_memory_free(gmu); - free_irq(gmu->gmu_irq, gmu); - free_irq(gmu->hfi_irq, gmu); + free_irq(gmu->gmu_irq, gmu); + free_irq(gmu->hfi_irq, gmu); + } /* Drop reference taken in of_find_device_by_node */ put_device(gmu->dev); @@ -1478,6 +1481,69 @@ static int cxpd_notifier_cb(struct notifier_block *nb, return 0; } +int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) +{ + struct platform_device *pdev = of_find_device_by_node(node); + struct a6xx_gmu *gmu = &a6xx_gpu->gmu; + int ret; + + if (!pdev) + return -ENODEV; + + gmu->dev = &pdev->dev; + + of_dma_configure(gmu->dev, node, true); + + pm_runtime_enable(gmu->dev); + + /* Mark legacy for manual SPTPRAC control */ + gmu->legacy = true; + + /* Map the GMU registers */ + gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu"); + if (IS_ERR(gmu->mmio)) { + ret = PTR_ERR(gmu->mmio); + goto err_mmio; + } + + gmu->cxpd = dev_pm_domain_attach_by_name(gmu->dev, "cx"); + if (IS_ERR(gmu->cxpd)) { + ret = PTR_ERR(gmu->cxpd); + goto err_mmio; + } + + if (!device_link_add(gmu->dev, gmu->cxpd, DL_FLAG_PM_RUNTIME)) { + ret = -ENODEV; + goto detach_cxpd; + } + + init_completion(&gmu->pd_gate); + complete_all(&gmu->pd_gate); + gmu->pd_nb.notifier_call = cxpd_notifier_cb; + + /* Get a link to the GX power domain to reset the GPU */ + gmu->gxpd = dev_pm_domain_attach_by_name(gmu->dev, "gx"); + if (IS_ERR(gmu->gxpd)) { + ret = PTR_ERR(gmu->gxpd); + goto err_mmio; + } + + gmu->initialized = true; + + return 0; + +detach_cxpd: + dev_pm_domain_detach(gmu->cxpd, false); + +err_mmio: + iounmap(gmu->mmio); + + /* Drop reference taken in of_find_device_by_node */ + put_device(gmu->dev); + + return ret; +} + int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) { struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 0efecde2af1a..b91fc02eb08c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -21,7 +21,7 @@ static inline bool _a6xx_check_idle(struct msm_gpu *gpu) struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); /* Check that the GMU is idle */ - if (!a6xx_gmu_isidle(&a6xx_gpu->gmu)) + if (!adreno_has_gmu_wrapper(adreno_gpu) && !a6xx_gmu_isidle(&a6xx_gpu->gmu)) return false; /* Check tha the CX master is idle */ @@ -1126,10 +1126,13 @@ static int hw_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct a6xx_gmu *gmu = &a6xx_gpu->gmu; int ret; - /* Make sure the GMU keeps the GPU on while we set it up */ - a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET); + if (!adreno_has_gmu_wrapper(adreno_gpu)) { + /* Make sure the GMU keeps the GPU on while we set it up */ + a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET); + } /* Clear GBIF halt in case GX domain was not collapsed */ if (a6xx_has_gbif(adreno_gpu)) { @@ -1352,6 +1355,8 @@ static int hw_init(struct msm_gpu *gpu) } out: + if (adreno_has_gmu_wrapper(adreno_gpu)) + return ret; /* * Tell the GMU that we are done touching the GPU and it can start power * management @@ -1386,9 +1391,6 @@ static void a6xx_dump(struct msm_gpu *gpu) adreno_dump(gpu); } -#define VBIF_RESET_ACK_TIMEOUT 100 -#define VBIF_RESET_ACK_MASK 0x00f0 - static void a6xx_recover(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -1426,6 +1428,15 @@ static void a6xx_recover(struct msm_gpu *gpu) */ gpu->active_submits = 0; + if (adreno_has_gmu_wrapper(adreno_gpu)) { + /* Drain the outstanding traffic on memory buses */ + a6xx_bus_clear_pending_transactions(adreno_gpu, true); + + /* Reset the GPU to a clean state */ + a6xx_gpu_sw_reset(gpu, true); + a6xx_gpu_sw_reset(gpu, false); + } + reinit_completion(&gmu->pd_gate); dev_pm_genpd_add_notifier(gmu->cxpd, &gmu->pd_nb); dev_pm_genpd_synced_poweroff(gmu->cxpd); @@ -1576,7 +1587,8 @@ static void a6xx_fault_detect_irq(struct msm_gpu *gpu) * Force the GPU to stay on until after we finish * collecting information */ - gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 1); + if (!adreno_has_gmu_wrapper(adreno_gpu)) + gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 1); DRM_DEV_ERROR(&gpu->pdev->dev, "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n", @@ -1707,6 +1719,10 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu) static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu) { + /* No LLCC on non-RPMh (and by extension, non-GMU) SoCs */ + if (adreno_has_gmu_wrapper(&a6xx_gpu->base)) + return; + llcc_slice_putd(a6xx_gpu->llc_slice); llcc_slice_putd(a6xx_gpu->htw_llc_slice); } @@ -1716,6 +1732,10 @@ static void a6xx_llc_slices_init(struct platform_device *pdev, { struct device_node *phandle; + /* No LLCC on non-RPMh (and by extension, non-GMU) SoCs */ + if (adreno_has_gmu_wrapper(&a6xx_gpu->base)) + return; + /* * There is a different programming path for targets with an mmu500 * attached, so detect if that is the case @@ -1786,7 +1806,7 @@ void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert) udelay(100); } -static int a6xx_pm_resume(struct msm_gpu *gpu) +static int a6xx_gmu_pm_resume(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); @@ -1806,10 +1826,58 @@ static int a6xx_pm_resume(struct msm_gpu *gpu) a6xx_llc_activate(a6xx_gpu); - return 0; + return ret; } -static int a6xx_pm_suspend(struct msm_gpu *gpu) +static int a6xx_pm_resume(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct a6xx_gmu *gmu = &a6xx_gpu->gmu; + unsigned long freq = gpu->fast_rate; + struct dev_pm_opp *opp; + int ret; + + gpu->needs_hw_init = true; + + trace_msm_gpu_resume(0); + + mutex_lock(&a6xx_gpu->gmu.lock); + + opp = dev_pm_opp_find_freq_ceil(&gpu->pdev->dev, &freq); + if (IS_ERR(opp)) { + ret = PTR_ERR(opp); + goto err_set_opp; + } + dev_pm_opp_put(opp); + + /* Set the core clock and bus bw, having VDD scaling in mind */ + dev_pm_opp_set_opp(&gpu->pdev->dev, opp); + + pm_runtime_resume_and_get(gmu->dev); + pm_runtime_resume_and_get(gmu->gxpd); + + ret = clk_bulk_prepare_enable(gpu->nr_clocks, gpu->grp_clks); + if (ret) + goto err_bulk_clk; + + /* If anything goes south, tear the GPU down piece by piece.. */ + if (ret) { +err_bulk_clk: + pm_runtime_put(gmu->gxpd); + pm_runtime_put(gmu->dev); + dev_pm_opp_set_opp(&gpu->pdev->dev, NULL); + } +err_set_opp: + mutex_unlock(&a6xx_gpu->gmu.lock); + + if (!ret) + msm_devfreq_resume(gpu); + + return ret; +} + +static int a6xx_gmu_pm_suspend(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); @@ -1836,7 +1904,40 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) return 0; } -static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) +static int a6xx_pm_suspend(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct a6xx_gmu *gmu = &a6xx_gpu->gmu; + int i; + + trace_msm_gpu_suspend(0); + + msm_devfreq_suspend(gpu); + + mutex_lock(&a6xx_gpu->gmu.lock); + + /* Drain the outstanding traffic on memory buses */ + a6xx_bus_clear_pending_transactions(adreno_gpu, true); + + clk_bulk_disable_unprepare(gpu->nr_clocks, gpu->grp_clks); + + pm_runtime_put_sync(gmu->gxpd); + dev_pm_opp_set_opp(&gpu->pdev->dev, NULL); + pm_runtime_put_sync(gmu->dev); + + mutex_unlock(&a6xx_gpu->gmu.lock); + + if (a6xx_gpu->shadow_bo) + for (i = 0; i < gpu->nr_rings; i++) + a6xx_gpu->shadow[i] = 0; + + gpu->suspend_count++; + + return 0; +} + +static int a6xx_gmu_get_timestamp(struct msm_gpu *gpu, uint64_t *value) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); @@ -1855,6 +1956,12 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) return 0; } +static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) +{ + *value = gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER); + return 0; +} + static struct msm_ringbuffer *a6xx_active_ring(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -2121,8 +2228,8 @@ static const struct adreno_gpu_funcs funcs = { .set_param = adreno_set_param, .hw_init = a6xx_hw_init, .ucode_load = a6xx_ucode_load, - .pm_suspend = a6xx_pm_suspend, - .pm_resume = a6xx_pm_resume, + .pm_suspend = a6xx_gmu_pm_suspend, + .pm_resume = a6xx_gmu_pm_resume, .recover = a6xx_recover, .submit = a6xx_submit, .active_ring = a6xx_active_ring, @@ -2137,6 +2244,35 @@ static const struct adreno_gpu_funcs funcs = { #if defined(CONFIG_DRM_MSM_GPU_STATE) .gpu_state_get = a6xx_gpu_state_get, .gpu_state_put = a6xx_gpu_state_put, +#endif + .create_address_space = a6xx_create_address_space, + .create_private_address_space = a6xx_create_private_address_space, + .get_rptr = a6xx_get_rptr, + .progress = a6xx_progress, + }, + .get_timestamp = a6xx_gmu_get_timestamp, +}; + +static const struct adreno_gpu_funcs funcs_gmuwrapper = { + .base = { + .get_param = adreno_get_param, + .set_param = adreno_set_param, + .hw_init = a6xx_hw_init, + .ucode_load = a6xx_ucode_load, + .pm_suspend = a6xx_pm_suspend, + .pm_resume = a6xx_pm_resume, + .recover = a6xx_recover, + .submit = a6xx_submit, + .active_ring = a6xx_active_ring, + .irq = a6xx_irq, + .destroy = a6xx_destroy, +#if defined(CONFIG_DRM_MSM_GPU_STATE) + .show = a6xx_show, +#endif + .gpu_busy = a6xx_gpu_busy, +#if defined(CONFIG_DRM_MSM_GPU_STATE) + .gpu_state_get = a6xx_gpu_state_get, + .gpu_state_put = a6xx_gpu_state_put, #endif .create_address_space = a6xx_create_address_space, .create_private_address_space = a6xx_create_private_address_space, @@ -2169,16 +2305,31 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = NULL; + /* Check if there is a GMU phandle and set it up */ + node = of_parse_phandle(pdev->dev.of_node, "qcom,gmu", 0); + /* FIXME: How do we gracefully handle this? */ + BUG_ON(!node); + + adreno_gpu->gmu_is_wrapper = of_device_is_compatible(node, "qcom,adreno-gmu-wrapper"); + /* * We need to know the platform type before calling into adreno_gpu_init * so that the hw_apriv flag can be correctly set. Snoop into the info * and grab the revision number */ info = adreno_info(config->rev); - - if (info && (info->revn == 650 || info->revn == 660 || - info->revn == 690 || - adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), info->rev))) + if (!info) + return ERR_PTR(-EINVAL); + + /* Assign these early so that we can use the is_aXYZ helpers */ + /* Numeric revision IDs (e.g. 630) */ + adreno_gpu->revn = info->revn; + /* New-style ADRENO_REV()-only */ + adreno_gpu->rev = info->rev; + /* Quirk data */ + adreno_gpu->info = info; + + if (adreno_is_a650(adreno_gpu) || adreno_is_a660_family(adreno_gpu)) adreno_gpu->base.hw_apriv = true; a6xx_llc_slices_init(pdev, a6xx_gpu); @@ -2189,7 +2340,10 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) return ERR_PTR(ret); } - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); + if (adreno_has_gmu_wrapper(adreno_gpu)) + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs_gmuwrapper, 1); + else + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret); @@ -2202,13 +2356,10 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) if (adreno_is_a618(adreno_gpu) || adreno_is_7c3(adreno_gpu)) priv->gpu_clamp_to_idle = true; - /* Check if there is a GMU phandle and set it up */ - node = of_parse_phandle(pdev->dev.of_node, "qcom,gmu", 0); - - /* FIXME: How do we gracefully handle this? */ - BUG_ON(!node); - - ret = a6xx_gmu_init(a6xx_gpu, node); + if (adreno_has_gmu_wrapper(adreno_gpu)) + ret = a6xx_gmu_wrapper_init(a6xx_gpu, node); + else + ret = a6xx_gmu_init(a6xx_gpu, node); of_node_put(node); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index aa70390ee1c6..c788b06e72da 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -76,6 +76,7 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node); +int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node); void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu); void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp, diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 30ecdff363e7..4e5d650578c6 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -1041,16 +1041,18 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) /* Get the generic state from the adreno core */ adreno_gpu_state_get(gpu, &a6xx_state->base); - a6xx_get_gmu_registers(gpu, a6xx_state); + if (!adreno_has_gmu_wrapper(adreno_gpu)) { + a6xx_get_gmu_registers(gpu, a6xx_state); - a6xx_state->gmu_log = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.log); - a6xx_state->gmu_hfi = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.hfi); - a6xx_state->gmu_debug = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.debug); + a6xx_state->gmu_log = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.log); + a6xx_state->gmu_hfi = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.hfi); + a6xx_state->gmu_debug = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.debug); - a6xx_snapshot_gmu_hfi_history(gpu, a6xx_state); + a6xx_snapshot_gmu_hfi_history(gpu, a6xx_state); + } /* If GX isn't on the rest of the data isn't going to be accessible */ - if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) + if (!adreno_has_gmu_wrapper(adreno_gpu) && !a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) return &a6xx_state->base; /* Get the banks of indexed registers */ diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 6934cee07d42..5c5901d65950 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -528,6 +528,10 @@ int adreno_load_fw(struct adreno_gpu *adreno_gpu) if (!adreno_gpu->info->fw[i]) continue; + /* Skip loading GMU firwmare with GMU Wrapper */ + if (adreno_has_gmu_wrapper(adreno_gpu) && i == ADRENO_FW_GMU) + continue; + /* Skip if the firmware has already been loaded */ if (adreno_gpu->fw[i]) continue; @@ -1074,8 +1078,8 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, u32 speedbin; int ret; - /* Only handle the core clock when GMU is not in use */ - if (config->rev.core < 6) { + /* Only handle the core clock when GMU is not in use (or is absent). */ + if (adreno_has_gmu_wrapper(adreno_gpu) || config->rev.core < 6) { /* * This can only be done before devm_pm_opp_of_add_table(), or * dev_pm_opp_set_config() will WARN_ON() diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 5a26c8a2de7c..de0b03a4b594 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -115,6 +115,7 @@ struct adreno_gpu { * code (a3xx_gpu.c) and stored in this common location. */ const unsigned int *reg_offsets; + bool gmu_is_wrapper; }; #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base) @@ -152,6 +153,11 @@ static inline bool adreno_is_revn(const struct adreno_gpu *gpu, uint32_t revn) return gpu->revn == revn; } +static inline bool adreno_has_gmu_wrapper(const struct adreno_gpu *gpu) +{ + return gpu->gmu_is_wrapper; +} + static inline bool adreno_is_a2xx(const struct adreno_gpu *gpu) { WARN_ON_ONCE(!gpu->revn); -- cgit v1.2.3 From 9bad37600c89eb6b3ac65faabbb26da21b48ccad Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:54 +0200 Subject: drm/msm/adreno: Disable has_cached_coherent in GMU wrapper configurations A610 and A619_holi don't support the feature. Disable it to make the GPU stop crashing after almost each and every submission - the received data on the GPU end was simply incomplete in garbled, resulting in almost nothing being executed properly. Extend the disablement to adreno_has_gmu_wrapper, as none of the GMU wrapper Adrenos that don't support yet seem to feature it. Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542774/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index e5a865024e94..6ea24b8ddcf8 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -565,7 +565,6 @@ static int adreno_bind(struct device *dev, struct device *master, void *data) config.rev.minor, config.rev.patchid); priv->is_a2xx = config.rev.core == 2; - priv->has_cached_coherent = config.rev.core >= 6; gpu = info->init(drm); if (IS_ERR(gpu)) { @@ -577,6 +576,10 @@ static int adreno_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; + if (config.rev.core >= 6) + if (!adreno_has_gmu_wrapper(to_adreno_gpu(gpu))) + priv->has_cached_coherent = true; + return 0; } -- cgit v1.2.3 From 8296ff0afdf22656683c9cf908ee8abdfa96d03a Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:55 +0200 Subject: drm/msm/a6xx: Add support for A619_holi A619_holi is a GMU-less variant of the already-supported A619 GPU. It's present on at least SM4350 (holi) and SM6375 (blair). No mesa changes are required. Add the required kernel-side support for it. Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542775/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 27 +++++++++++++++++++++++++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 5 +++++ 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index b91fc02eb08c..2ca9e0440396 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -911,6 +911,9 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) if (adreno_is_a618(adreno_gpu)) return; + if (adreno_is_a619_holi(adreno_gpu)) + hbb_lo = 0; + if (adreno_is_a640_family(adreno_gpu)) amsbc = 1; @@ -1135,7 +1138,12 @@ static int hw_init(struct msm_gpu *gpu) } /* Clear GBIF halt in case GX domain was not collapsed */ - if (a6xx_has_gbif(adreno_gpu)) { + if (adreno_is_a619_holi(adreno_gpu)) { + gpu_write(gpu, REG_A6XX_GBIF_HALT, 0); + gpu_write(gpu, REG_A6XX_RBBM_GPR0_CNTL, 0); + /* Let's make extra sure that the GPU can access the memory.. */ + mb(); + } else if (a6xx_has_gbif(adreno_gpu)) { gpu_write(gpu, REG_A6XX_GBIF_HALT, 0); gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 0); /* Let's make extra sure that the GPU can access the memory.. */ @@ -1144,6 +1152,9 @@ static int hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_CNTL, 0); + if (adreno_is_a619_holi(adreno_gpu)) + a6xx_sptprac_enable(gmu); + /* * Disable the trusted memory range - we don't actually supported secure * memory rendering at this point in time and we don't want to block off @@ -1760,12 +1771,18 @@ static void a6xx_llc_slices_init(struct platform_device *pdev, #define GBIF_CLIENT_HALT_MASK BIT(0) #define GBIF_ARB_HALT_MASK BIT(1) #define VBIF_XIN_HALT_CTRL0_MASK GENMASK(3, 0) +#define VBIF_RESET_ACK_MASK 0xF0 +#define GPR0_GBIF_HALT_REQUEST 0x1E0 void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off) { struct msm_gpu *gpu = &adreno_gpu->base; - if (!a6xx_has_gbif(adreno_gpu)) { + if (adreno_is_a619_holi(adreno_gpu)) { + gpu_write(gpu, REG_A6XX_RBBM_GPR0_CNTL, GPR0_GBIF_HALT_REQUEST); + spin_until((gpu_read(gpu, REG_A6XX_RBBM_VBIF_GX_RESET_STATUS) & + (VBIF_RESET_ACK_MASK)) == VBIF_RESET_ACK_MASK); + } else if (!a6xx_has_gbif(adreno_gpu)) { gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, VBIF_XIN_HALT_CTRL0_MASK); spin_until((gpu_read(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL1) & (VBIF_XIN_HALT_CTRL0_MASK)) == VBIF_XIN_HALT_CTRL0_MASK); @@ -1861,6 +1878,9 @@ static int a6xx_pm_resume(struct msm_gpu *gpu) if (ret) goto err_bulk_clk; + if (adreno_is_a619_holi(adreno_gpu)) + a6xx_sptprac_enable(gmu); + /* If anything goes south, tear the GPU down piece by piece.. */ if (ret) { err_bulk_clk: @@ -1920,6 +1940,9 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) /* Drain the outstanding traffic on memory buses */ a6xx_bus_clear_pending_transactions(adreno_gpu, true); + if (adreno_is_a619_holi(adreno_gpu)) + a6xx_sptprac_disable(gmu); + clk_bulk_disable_unprepare(gpu->nr_clocks, gpu->grp_clks); pm_runtime_put_sync(gmu->gxpd); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index de0b03a4b594..efd35b7bc4cf 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -263,6 +263,11 @@ static inline int adreno_is_a619(const struct adreno_gpu *gpu) return adreno_is_revn(gpu, 619); } +static inline int adreno_is_a619_holi(const struct adreno_gpu *gpu) +{ + return adreno_is_a619(gpu) && adreno_has_gmu_wrapper(gpu); +} + static inline int adreno_is_a630(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 630); -- cgit v1.2.3 From e7fc9398e608a7bc057fe7d50dbdaf3052be59b5 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:56 +0200 Subject: drm/msm/a6xx: Add A610 support A610 is one of (if not the) lowest-tier SKUs in the A6XX family. It features no GMU, as it's implemented solely on SoCs with SMD_RPM. What's more interesting is that it does not feature a VDDGX line either, being powered solely by VDDCX and has an unfortunate hardware quirk that makes its reset line broken - after a couple of assert/ deassert cycles, it will hang for good and will not wake up again. This GPU requires mesa changes for proper rendering, and lots of them at that. The command streams are quite far away from any other A6XX GPU and hence it needs special care. This patch was validated both by running an (incomplete) downstream mesa with some hacks (frames rendered correctly, though some instructions made the GPU hangcheck which is expected - garbage in, garbage out) and by replaying RD traces captured with the downstream KGSL driver - no crashes there, ever. Add support for this GPU on the kernel side, which comes down to pretty simply adding A612 HWCG tables, altering a few values and adding a special case for handling the reset line. Reviewed-by: Dmitry Baryshkov Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542779/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 99 ++++++++++++++++++++++++++---- drivers/gpu/drm/msm/adreno/adreno_device.c | 12 ++++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 8 ++- 3 files changed, 107 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 2ca9e0440396..47aafc9deaf8 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -252,6 +252,56 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) a6xx_flush(gpu, ring); } +const struct adreno_reglist a612_hwcg[] = { + {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220}, + {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081}, + {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf}, + {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222}, + {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111}, + {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111}, + {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111}, + {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111}, + {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777}, + {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777}, + {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777}, + {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777}, + {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222}, + {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220}, + {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00}, + {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022}, + {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555}, + {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011}, + {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044}, + {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222}, + {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222}, + {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222}, + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002}, + {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222}, + {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000}, + {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}, + {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200}, + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, + {REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222}, + {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004}, + {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002}, + {REG_A6XX_RBBM_ISDB_CNT, 0x00000182}, + {REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000}, + {REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000}, + {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222}, + {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111}, + {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555}, + {}, +}; + /* For a615 family (a615, a616, a618 and a619) */ const struct adreno_reglist a615_hwcg[] = { {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222}, @@ -659,6 +709,8 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state) if (adreno_is_a630(adreno_gpu)) clock_cntl_on = 0x8aa8aa02; + else if (adreno_is_a610(adreno_gpu)) + clock_cntl_on = 0xaaa8aa82; else clock_cntl_on = 0x8aa8aa82; @@ -669,13 +721,15 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state) return; /* Disable SP clock before programming HWCG registers */ - gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0); + if (!adreno_is_a610(adreno_gpu)) + gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0); for (i = 0; (reg = &adreno_gpu->info->hwcg[i], reg->offset); i++) gpu_write(gpu, reg->offset, state ? reg->value : 0); /* Enable SP clock */ - gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1); + if (!adreno_is_a610(adreno_gpu)) + gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1); gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0); } @@ -907,6 +961,13 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) /* Unknown, introduced with A640/680 */ u32 amsbc = 0; + if (adreno_is_a610(adreno_gpu)) { + /* HBB = 14 */ + hbb_lo = 1; + min_acc_len = 1; + ubwc_mode = 1; + } + /* a618 is using the hw default values */ if (adreno_is_a618(adreno_gpu)) return; @@ -1181,13 +1242,13 @@ static int hw_init(struct msm_gpu *gpu) a6xx_set_hwcg(gpu, true); /* VBIF/GBIF start*/ - if (adreno_is_a640_family(adreno_gpu) || + if (adreno_is_a610(adreno_gpu) || + adreno_is_a640_family(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) { gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE0, 0x00071620); gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE1, 0x00071620); gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE2, 0x00071620); gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620); - gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620); gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x3); } else { gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3); @@ -1215,18 +1276,26 @@ static int hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A6XX_UCHE_FILTER_CNTL, 0x804); gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, 0x4); - if (adreno_is_a640_family(adreno_gpu) || - adreno_is_a650_family(adreno_gpu)) + if (adreno_is_a640_family(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) { gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140); - else + gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c); + } else if (adreno_is_a610(adreno_gpu)) { + gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x00800060); + gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x40201b16); + } else { gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x010000c0); - gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c); + gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c); + } if (adreno_is_a660_family(adreno_gpu)) gpu_write(gpu, REG_A6XX_CP_LPAC_PROG_FIFO_SIZE, 0x00000020); /* Setting the mem pool size */ - gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128); + if (adreno_is_a610(adreno_gpu)) { + gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 48); + gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 47); + } else + gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128); /* Setting the primFifo thresholds default values, * and vccCacheSkipDis=1 bit (0x200) for A640 and newer @@ -1237,6 +1306,8 @@ static int hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200); else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200); + else if (adreno_is_a610(adreno_gpu)) + gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00080000); else gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00180000); @@ -1252,8 +1323,10 @@ static int hw_init(struct msm_gpu *gpu) a6xx_set_ubwc_config(gpu); /* Enable fault detection */ - gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, - (1 << 30) | 0x1fffff); + if (adreno_is_a610(adreno_gpu)) + gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3ffff); + else + gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff); gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, 1); @@ -1813,6 +1886,10 @@ void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_ void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert) { + /* 11nm chips (e.g. ones with A610) have hw issues with the reset line! */ + if (adreno_is_a610(to_adreno_gpu(gpu))) + return; + gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, assert); /* Perform a bogus read and add a brief delay to ensure ordering. */ gpu_read(gpu, REG_A6XX_RBBM_SW_RESET_CMD); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 6ea24b8ddcf8..cb94cfd137a8 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -253,6 +253,18 @@ static const struct adreno_info gpulist[] = { .quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE, .init = a5xx_gpu_init, .zapfw = "a540_zap.mdt", + }, { + .rev = ADRENO_REV(6, 1, 0, ANY_ID), + .revn = 610, + .name = "A610", + .fw = { + [ADRENO_FW_SQE] = "a630_sqe.fw", + }, + .gmem = (SZ_128K + SZ_4K), + .inactive_period = DRM_MSM_INACTIVE_PERIOD, + .init = a6xx_gpu_init, + .zapfw = "a610_zap.mdt", + .hwcg = a612_hwcg, }, { .rev = ADRENO_REV(6, 1, 8, ANY_ID), .revn = 618, diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index efd35b7bc4cf..3a8af5fdaea8 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -55,7 +55,8 @@ struct adreno_reglist { u32 value; }; -extern const struct adreno_reglist a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[], a660_hwcg[], a690_hwcg[]; +extern const struct adreno_reglist a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[]; +extern const struct adreno_reglist a660_hwcg[], a690_hwcg[]; struct adreno_info { struct adreno_rev rev; @@ -253,6 +254,11 @@ static inline int adreno_is_a540(const struct adreno_gpu *gpu) return adreno_is_revn(gpu, 540); } +static inline int adreno_is_a610(const struct adreno_gpu *gpu) +{ + return adreno_is_revn(gpu, 610); +} + static inline int adreno_is_a618(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 618); -- cgit v1.2.3 From 3e90044d3e4941efafbfcfad8b1b7cfdb6d97a58 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:57 +0200 Subject: drm/msm/a6xx: Fix some A619 tunables Adreno 619 expects some tunables to be set differently. Make up for it. Fixes: b7616b5c69e6 ("drm/msm/adreno: Add A619 support") Reviewed-by: Dmitry Baryshkov Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542782/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 47aafc9deaf8..97e261d33312 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1306,6 +1306,8 @@ static int hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200); else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200); + else if (adreno_is_a619(adreno_gpu)) + gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00018000); else if (adreno_is_a610(adreno_gpu)) gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00080000); else @@ -1323,7 +1325,9 @@ static int hw_init(struct msm_gpu *gpu) a6xx_set_ubwc_config(gpu); /* Enable fault detection */ - if (adreno_is_a610(adreno_gpu)) + if (adreno_is_a619(adreno_gpu)) + gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff); + else if (adreno_is_a610(adreno_gpu)) gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3ffff); else gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff); -- cgit v1.2.3 From ac926549651140243c6f4e234ca83fcb29d29ecf Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:58 +0200 Subject: drm/msm/a6xx: Use "else if" in GPU speedbin rev matching The GPU can only be one at a time. Turn a series of ifs into if + elseifs to save some CPU cycles. Reviewed-by: Dmitry Baryshkov Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542770/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 97e261d33312..d0ba0844079c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -2276,16 +2276,16 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev)) val = a618_get_speed_bin(fuse); - if (adreno_cmp_rev(ADRENO_REV(6, 1, 9, ANY_ID), rev)) + else if (adreno_cmp_rev(ADRENO_REV(6, 1, 9, ANY_ID), rev)) val = a619_get_speed_bin(fuse); - if (adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), rev)) + else if (adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), rev)) val = adreno_7c3_get_speed_bin(fuse); - if (adreno_cmp_rev(ADRENO_REV(6, 4, 0, ANY_ID), rev)) + else if (adreno_cmp_rev(ADRENO_REV(6, 4, 0, ANY_ID), rev)) val = a640_get_speed_bin(fuse); - if (adreno_cmp_rev(ADRENO_REV(6, 5, 0, ANY_ID), rev)) + else if (adreno_cmp_rev(ADRENO_REV(6, 5, 0, ANY_ID), rev)) val = a650_get_speed_bin(fuse); if (val == UINT_MAX) { -- cgit v1.2.3 From b3bcd583fa6f963be9c8a08405b2cbaeea797a3c Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:20:59 +0200 Subject: drm/msm/a6xx: Use adreno_is_aXYZ macros in speedbin matching Before transitioning to using per-SoC and not per-Adreno speedbin fuse values (need another patchset to land elsewhere), a good improvement/stopgap solution is to use adreno_is_aXYZ macros in place of explicit revision matching. Do so to allow differentiating between A619 and A619_holi. Reviewed-by: Dmitry Baryshkov Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542777/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 18 +++++++++--------- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 15 ++++++++++++--- 2 files changed, 21 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index d0ba0844079c..d7139eae0f73 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -2269,23 +2269,23 @@ static u32 adreno_7c3_get_speed_bin(u32 fuse) return UINT_MAX; } -static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) +static u32 fuse_to_supp_hw(struct device *dev, struct adreno_gpu *adreno_gpu, u32 fuse) { u32 val = UINT_MAX; - if (adreno_cmp_rev(ADRENO_REV(6, 1, 8, ANY_ID), rev)) + if (adreno_is_a618(adreno_gpu)) val = a618_get_speed_bin(fuse); - else if (adreno_cmp_rev(ADRENO_REV(6, 1, 9, ANY_ID), rev)) + else if (adreno_is_a619(adreno_gpu)) val = a619_get_speed_bin(fuse); - else if (adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), rev)) + else if (adreno_is_7c3(adreno_gpu)) val = adreno_7c3_get_speed_bin(fuse); - else if (adreno_cmp_rev(ADRENO_REV(6, 4, 0, ANY_ID), rev)) + else if (adreno_is_a640(adreno_gpu)) val = a640_get_speed_bin(fuse); - else if (adreno_cmp_rev(ADRENO_REV(6, 5, 0, ANY_ID), rev)) + else if (adreno_is_a650(adreno_gpu)) val = a650_get_speed_bin(fuse); if (val == UINT_MAX) { @@ -2298,7 +2298,7 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse) return (1 << val); } -static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) +static int a6xx_set_supported_hw(struct device *dev, struct adreno_gpu *adreno_gpu) { u32 supp_hw; u32 speedbin; @@ -2317,7 +2317,7 @@ static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev) return ret; } - supp_hw = fuse_to_supp_hw(dev, rev, speedbin); + supp_hw = fuse_to_supp_hw(dev, adreno_gpu, speedbin); ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1); if (ret) @@ -2438,7 +2438,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) a6xx_llc_slices_init(pdev, a6xx_gpu); - ret = a6xx_set_supported_hw(&pdev->dev, config->rev); + ret = a6xx_set_supported_hw(&pdev->dev, adreno_gpu); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 3a8af5fdaea8..d8c9e8cc3753 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -279,10 +279,9 @@ static inline int adreno_is_a630(const struct adreno_gpu *gpu) return adreno_is_revn(gpu, 630); } -static inline int adreno_is_a640_family(const struct adreno_gpu *gpu) +static inline int adreno_is_a640(const struct adreno_gpu *gpu) { - return adreno_is_revn(gpu, 640) || - adreno_is_revn(gpu, 680); + return adreno_is_revn(gpu, 640); } static inline int adreno_is_a650(const struct adreno_gpu *gpu) @@ -301,6 +300,11 @@ static inline int adreno_is_a660(const struct adreno_gpu *gpu) return adreno_is_revn(gpu, 660); } +static inline int adreno_is_a680(const struct adreno_gpu *gpu) +{ + return adreno_is_revn(gpu, 680); +} + static inline int adreno_is_a690(const struct adreno_gpu *gpu) { return adreno_is_revn(gpu, 690); @@ -328,6 +332,11 @@ static inline int adreno_is_a650_family(const struct adreno_gpu *gpu) adreno_is_a660_family(gpu); } +static inline int adreno_is_a640_family(const struct adreno_gpu *gpu) +{ + return adreno_is_a640(gpu) || adreno_is_a680(gpu); +} + u64 adreno_private_address_space_size(struct msm_gpu *gpu); int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, uint32_t param, uint64_t *value, uint32_t *len); -- cgit v1.2.3 From 20c8e39985b9a4442123e0fa6496183d9418e422 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:21:00 +0200 Subject: drm/msm/a6xx: Add A619_holi speedbin support A619_holi is implemented on at least two SoCs: SM4350 (holi) and SM6375 (blair). This is what seems to be a first occurrence of this happening, but it's easy to overcome by guarding the SoC-specific fuse values with of_machine_is_compatible(). Do just that to enable frequency limiting on these SoCs. Reviewed-by: Dmitry Baryshkov Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542772/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index d7139eae0f73..ff9a8d342c77 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -2216,6 +2216,34 @@ static u32 a618_get_speed_bin(u32 fuse) return UINT_MAX; } +static u32 a619_holi_get_speed_bin(u32 fuse) +{ + /* + * There are (at least) two SoCs implementing A619_holi: SM4350 (holi) + * and SM6375 (blair). Limit the fuse matching to the corresponding + * SoC to prevent bogus frequency setting (as improbable as it may be, + * given unexpected fuse values are.. unexpected! But still possible.) + */ + + if (fuse == 0) + return 0; + + if (of_machine_is_compatible("qcom,sm4350")) { + if (fuse == 138) + return 1; + else if (fuse == 92) + return 2; + } else if (of_machine_is_compatible("qcom,sm6375")) { + if (fuse == 190) + return 1; + else if (fuse == 177) + return 2; + } else + pr_warn("Unknown SoC implementing A619_holi!\n"); + + return UINT_MAX; +} + static u32 a619_get_speed_bin(u32 fuse) { if (fuse == 0) @@ -2276,6 +2304,9 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_gpu *adreno_gpu, u3 if (adreno_is_a618(adreno_gpu)) val = a618_get_speed_bin(fuse); + else if (adreno_is_a619_holi(adreno_gpu)) + val = a619_holi_get_speed_bin(fuse); + else if (adreno_is_a619(adreno_gpu)) val = a619_get_speed_bin(fuse); -- cgit v1.2.3 From cd036d542afb82adfbbd43c5dbeb7010e8e91ee7 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 16 Jun 2023 01:21:01 +0200 Subject: drm/msm/a6xx: Add A610 speedbin support A610 is implemented on at least three SoCs: SM6115 (bengal), SM6125 (trinket) and SM6225 (khaje). Trinket does not support speed binning (only a single SKU exists) and we don't yet support khaje upstream. Hence, add a fuse mapping table for bengal to allow for per-chip frequency limiting. Reviewed-by: Dmitry Baryshkov Reviewed-by: Akhil P Oommen Signed-off-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/542780/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ff9a8d342c77..b3ada1e7b598 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -2204,6 +2204,30 @@ static bool a6xx_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring) return progress; } +static u32 a610_get_speed_bin(u32 fuse) +{ + /* + * There are (at least) three SoCs implementing A610: SM6125 (trinket), + * SM6115 (bengal) and SM6225 (khaje). Trinket does not have speedbinning, + * as only a single SKU exists and we don't support khaje upstream yet. + * Hence, this matching table is only valid for bengal and can be easily + * expanded if need be. + */ + + if (fuse == 0) + return 0; + else if (fuse == 206) + return 1; + else if (fuse == 200) + return 2; + else if (fuse == 157) + return 3; + else if (fuse == 127) + return 4; + + return UINT_MAX; +} + static u32 a618_get_speed_bin(u32 fuse) { if (fuse == 0) @@ -2301,6 +2325,9 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_gpu *adreno_gpu, u3 { u32 val = UINT_MAX; + if (adreno_is_a610(adreno_gpu)) + val = a610_get_speed_bin(fuse); + if (adreno_is_a618(adreno_gpu)) val = a618_get_speed_bin(fuse); -- cgit v1.2.3