Skip to content

Commit

Permalink
drm/msm/dpu: Disable MDP vsync source selection on DPU 5.0.0 and above
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Dmitry Baryshkov <[email protected]>
Patchwork: https://patchwork.freedesktop.org/patch/534220/
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Dmitry Baryshkov <[email protected]>
  • Loading branch information
MarijnS95 authored and lumag committed May 22, 2023
1 parent fe9d66c commit a2ff096
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 17 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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
};

Expand Down
50 changes: 35 additions & 15 deletions drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit a2ff096

Please sign in to comment.