Skip to content

Commit

Permalink
drm/msm/dpu: Configure CWB in writeback encoder
Browse files Browse the repository at this point in the history
Cache the CWB block mask in the DPU virtual encoder and configure CWB
according to the CWB block mask within the writeback phys encoder

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/637501/
Link: https://lore.kernel.org/r/20250214-concurrent-wb-v6-8-a44c293cf422@quicinc.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
  • Loading branch information
Jessica Zhang authored and Dmitry Baryshkov committed Mar 5, 2025
1 parent 5008375 commit dd33140
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 3 deletions.
75 changes: 74 additions & 1 deletion drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "dpu_hw_catalog.h"
#include "dpu_hw_intf.h"
#include "dpu_hw_ctl.h"
#include "dpu_hw_cwb.h"
#include "dpu_hw_dspp.h"
#include "dpu_hw_dsc.h"
#include "dpu_hw_merge3d.h"
Expand Down Expand Up @@ -139,6 +140,7 @@ enum dpu_enc_rc_states {
* num_phys_encs.
* @hw_dsc: Handle to the DSC blocks used for the display.
* @dsc_mask: Bitmask of used DSC blocks.
* @cwb_mask Bitmask of used CWB muxes
* @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
* for partial update right-only cases, such as pingpong
* split where virtual pingpong does not generate IRQs
Expand Down Expand Up @@ -185,6 +187,7 @@ struct dpu_encoder_virt {
struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];

unsigned int dsc_mask;
unsigned int cwb_mask;

bool intfs_swapped;

Expand Down Expand Up @@ -1159,6 +1162,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
int num_cwb = 0;
bool is_cwb_encoder;
unsigned int dsc_mask = 0;
unsigned int cwb_mask = 0;
int i;

if (!drm_enc) {
Expand Down Expand Up @@ -1199,8 +1203,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
ARRAY_SIZE(hw_pp));
}

for (i = 0; i < num_cwb; i++)
for (i = 0; i < num_cwb; i++) {
dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]);
cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0);
}

dpu_enc->cwb_mask = cwb_mask;

num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
Expand Down Expand Up @@ -2237,6 +2245,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
if (phys_enc->hw_pp && phys_enc->hw_pp->ops.setup_dither)
phys_enc->hw_pp->ops.setup_dither(phys_enc->hw_pp, NULL);

if (dpu_enc->cwb_mask)
dpu_encoder_helper_phys_setup_cwb(phys_enc, false);

/* reset the merge 3D HW block */
if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
Expand Down Expand Up @@ -2280,6 +2291,56 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
ctl->ops.clear_pending_flush(ctl);
}

void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
bool enable)
{
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
struct dpu_hw_cwb *hw_cwb;
struct dpu_hw_cwb_setup_cfg cwb_cfg;

struct dpu_kms *dpu_kms;
struct dpu_global_state *global_state;
struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC];
int num_pp;

if (!phys_enc->hw_wb)
return;

dpu_kms = phys_enc->dpu_kms;
global_state = dpu_kms_get_existing_global_state(dpu_kms);
num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
phys_enc->parent->crtc,
DPU_HW_BLK_PINGPONG, rt_pp_list,
ARRAY_SIZE(rt_pp_list));

if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) {
DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp);
return;
}

/*
* The CWB mux supports using LM or DSPP as tap points. For now,
* always use LM tap point
*/
cwb_cfg.input = INPUT_MODE_LM_OUT;

for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
hw_cwb = dpu_enc->hw_cwb[i];
if (!hw_cwb)
continue;

if (enable) {
struct dpu_hw_pingpong *hw_pp =
to_dpu_hw_pingpong(rt_pp_list[i]);
cwb_cfg.pp_idx = hw_pp->idx;
} else {
cwb_cfg.pp_idx = PINGPONG_NONE;
}

hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);
}
}

/**
* dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
* @phys_enc: Pointer to physical encoder
Expand Down Expand Up @@ -2740,6 +2801,18 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
return INTF_MODE_NONE;
}

/**
* dpu_encoder_helper_get_cwb_mask - get CWB blocks mask for the DPU encoder
* @phys_enc: Pointer to physical encoder structure
*/
unsigned int dpu_encoder_helper_get_cwb_mask(struct dpu_encoder_phys *phys_enc)
{
struct drm_encoder *encoder = phys_enc->parent;
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);

return dpu_enc->cwb_mask;
}

/**
* dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
* This helper function is used by physical encoder to get DSC blocks mask
Expand Down
7 changes: 6 additions & 1 deletion drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
*/

Expand Down Expand Up @@ -309,6 +309,8 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
return BLEND_3D_NONE;
}

unsigned int dpu_encoder_helper_get_cwb_mask(struct dpu_encoder_phys *phys_enc);

unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc);

struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc);
Expand All @@ -331,6 +333,9 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,

void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);

void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
bool enable);

void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
const struct msm_format *dpu_fmt,
u32 output_type);
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/

#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
Expand Down Expand Up @@ -340,6 +340,8 @@ static void dpu_encoder_phys_wb_setup(

dpu_encoder_helper_phys_setup_cdm(phys_enc, format, CDM_CDWN_OUTPUT_WB);

dpu_encoder_helper_phys_setup_cwb(phys_enc, true);

dpu_encoder_phys_wb_setup_ctl(phys_enc);
}

Expand Down

0 comments on commit dd33140

Please sign in to comment.