* [PATCH v3 00/15] (no cover subject)
@ 2024-12-19 7:49 Jun Nie
2024-12-19 7:49 ` [PATCH v3 01/15] drm/msm/dpu: Do not fix number of DSC Jun Nie
` (15 more replies)
0 siblings, 16 replies; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
To: Rob Clark <robdclark@gmail.com>
To: Abhinav Kumar <quic_abhinavk@quicinc.com>
To: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
To: Sean Paul <sean@poorly.run>
To: Marijn Suijten <marijn.suijten@somainline.org>
To: David Airlie <airlied@gmail.com>
To: Simona Vetter <simona@ffwll.ch>
Cc: linux-arm-msm@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: freedreno@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
drm/msm/dpu: Support quad pipe with dual-DSI
2 or more SSPPs and dual-DSI interface are need for super wide DSI panel.
And 4 DSC are preferred for power optimal in this case. This patch set
extend number of pipes to 4 and revise related mixer blending logic
to support quad pipe. All these changes depends on the virtual plane
feature to split a super wide drm plane horizontally into 2 or more sub
clip. Thus DMA of multiple SSPPs can share the effort of fetching the
whole drm plane.
The first pipe pair co-work with the first mixer pair to cover the left
half of screen and 2nd pair of pipes and mixers are for the right half
of screen. If a plane is only for the right half of screen, only one
or two of pipes in the 2nd pipe pair are valid, and no SSPP or mixer is
assinged for invalid pipe.
For those panel that does not require quad-pipe, only 1 or 2 pipes in
the 1st pipe pair will be used. There is no concept of right half of
screen.
For legacy non virtual plane mode, the first 1 or 2 pipes are used for
the single SSPP and its multi-rect mode.
This patch set depends on virtual plane patch set v7:
https://lore.kernel.org/all/20241130-dpu-virtual-wide-v7-0-991053fcf63c@linaro.org/
Changes in v3:
- Split change in trace into a separate patch.
- Rebase to latest msm-next branch.
- Reorder patch sequence to make sure valid flag is set in earlier patch
- Rectify rewrite patch to move logic change into other patch
- Polish commit messages and code comments.
- Link to v2: https://lore.kernel.org/dri-devel/20241009-sm8650-v6-11-hmd-pocf-mdss-quad-upstream-21-v2-0-76d4f5d413bf@linaro.org/
Changes in v2:
- Revise the patch sequence with changing to 2 pipes topology first. Then
prepare for quad-pipe setup, then enable quad-pipe at last.
- Split DSI patches into other patch set.
- Link to v1: https://lore.kernel.org/all/20240829-sm8650-v6-11-hmd-pocf-mdss-quad-upstream-8-v1-0-bdb05b4b5a2e@linaro.org/
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
Jun Nie (15):
drm/msm/dpu: Do not fix number of DSC
drm/msm/dpu: configure DSC per number in use
drm/msm/dpu: polish log for resource allocation
drm/msm/dpu: decide right side per last bit
drm/msm/dpu: fix mixer number counter on allocation
drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation
drm/msm/dpu: bind correct pingpong for quad pipe
drm/msm/dpu: handle pipes as array
drm/msm/dpu: split PIPES_PER_STAGE definition per plane and mixer
drm/msm/dpu: Add pipe as trace argument
drm/msm/dpu: blend pipes per mixer pairs config
drm/msm/dpu: support plane splitting in quad-pipe case
drm/msm/dpu: Support quad-pipe in SSPP checking
drm/msm/dpu: support SSPP assignment for quad-pipe case
drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 77 +++--
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 12 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 74 +++--
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 2 +
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 12 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 403 ++++++++++++++---------
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 12 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 219 ++++++------
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 32 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 +-
13 files changed, 511 insertions(+), 348 deletions(-)
---
base-commit: a9b9ea7b45d661fff0f3fd2937703a536f528cd2
change-id: 20241219-sm8650-v6-13-hmd-deckard-mdss-quad-upstream-32-2bdbc22f5131
Best regards,
--
Jun Nie <jun.nie@linaro.org>
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH v3 01/15] drm/msm/dpu: Do not fix number of DSC
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 22:08 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 02/15] drm/msm/dpu: configure DSC per number in use Jun Nie
` (14 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
If DSC is enabled, the only case is with 2 DSC engines so far. More
usage case will be added, such as 4 DSC in 4:4:2 topoplogy.
So get real number of DSCs to decide whether DSC merge is needed.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index ddc60e658d63f..650df585138cd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -164,6 +164,7 @@ enum dpu_enc_rc_states {
* clks and resources after IDLE_TIMEOUT time.
* @topology: topology of the display
* @idle_timeout: idle timeout duration in milliseconds
+ * @num_dscs: Number of DSCs in use
* @wide_bus_en: wide bus is enabled on this interface
* @dsc: drm_dsc_config pointer, for DSC-enabled encoders
*/
@@ -204,6 +205,7 @@ struct dpu_encoder_virt {
struct msm_display_topology topology;
u32 idle_timeout;
+ u32 num_dscs;
bool wide_bus_en;
@@ -622,9 +624,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
if (dpu_enc->phys_encs[i])
intf_count++;
- /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
if (dpu_enc->dsc)
- num_dsc = 2;
+ num_dsc = dpu_enc->num_dscs;
return (num_dsc > 0) && (num_dsc > intf_count);
}
@@ -1261,6 +1262,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
dsc_mask |= BIT(dpu_enc->hw_dsc[i]->idx - DSC_0);
}
+ dpu_enc->num_dscs = num_dsc;
dpu_enc->dsc_mask = dsc_mask;
if ((dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) ||
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 02/15] drm/msm/dpu: configure DSC per number in use
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
2024-12-19 7:49 ` [PATCH v3 01/15] drm/msm/dpu: Do not fix number of DSC Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 22:06 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 03/15] drm/msm/dpu: polish log for resource allocation Jun Nie
` (13 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Currently if DSC support is requested, the driver only supports using
2 DSC blocks. We need 4 DSC in quad-pipe topology in future. So let's
only configure DSC engines in use, instead of the maximum number of
DSC engines.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 650df585138cd..cc23f364dd080 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2028,6 +2028,7 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
struct drm_dsc_config *dsc)
{
/* coding only for 2LM, 2enc, 1 dsc config */
+ int num_dsc = dpu_enc->num_dscs;
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];
@@ -2039,7 +2040,7 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
u32 initial_lines;
int i;
- for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
+ for (i = 0; i < num_dsc; i++) {
hw_pp[i] = dpu_enc->hw_pp[i];
hw_dsc[i] = dpu_enc->hw_dsc[i];
@@ -2068,7 +2069,7 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
enc_ip_w = intf_ip_w / 2;
initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
- for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
+ for (i = 0; i < num_dsc; i++)
dpu_encoder_dsc_pipe_cfg(ctl, hw_dsc[i], hw_pp[i],
dsc, dsc_common_mode, initial_lines);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 03/15] drm/msm/dpu: polish log for resource allocation
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
2024-12-19 7:49 ` [PATCH v3 01/15] drm/msm/dpu: Do not fix number of DSC Jun Nie
2024-12-19 7:49 ` [PATCH v3 02/15] drm/msm/dpu: configure DSC per number in use Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 22:07 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 04/15] drm/msm/dpu: decide right side per last bit Jun Nie
` (12 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Add resource type info on allocation failure.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 6dc3fa79e6425..cde3c5616f9bc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -814,6 +814,21 @@ void dpu_rm_release_all_sspp(struct dpu_global_state *global_state,
ARRAY_SIZE(global_state->sspp_to_crtc_id), crtc_id);
}
+static char *dpu_hw_blk_type_name[] = {
+ [DPU_HW_BLK_TOP] = "TOP",
+ [DPU_HW_BLK_SSPP] = "SSPP",
+ [DPU_HW_BLK_LM] = "LM",
+ [DPU_HW_BLK_CTL] = "CTL",
+ [DPU_HW_BLK_PINGPONG] = "pingpong",
+ [DPU_HW_BLK_INTF] = "INTF",
+ [DPU_HW_BLK_WB] = "WB",
+ [DPU_HW_BLK_DSPP] = "DSPP",
+ [DPU_HW_BLK_MERGE_3D] = "merge_3d",
+ [DPU_HW_BLK_DSC] = "DSC",
+ [DPU_HW_BLK_CDM] = "CDM",
+ [DPU_HW_BLK_MAX] = "none",
+};
+
/**
* dpu_rm_get_assigned_resources - Get hw resources of the given type that are
* assigned to this encoder
@@ -874,13 +889,13 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
continue;
if (num_blks == blks_size) {
- DPU_ERROR("More than %d resources assigned to enc %d\n",
- blks_size, enc_id);
+ DPU_ERROR("More than %d %s assigned to enc %d\n",
+ blks_size, dpu_hw_blk_type_name[type], enc_id);
break;
}
if (!hw_blks[i]) {
- DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n",
- type, enc_id);
+ DPU_ERROR("%s unavailable to assign to enc %d\n",
+ dpu_hw_blk_type_name[type], enc_id);
break;
}
blks[num_blks++] = hw_blks[i];
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 04/15] drm/msm/dpu: decide right side per last bit
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (2 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 03/15] drm/msm/dpu: polish log for resource allocation Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 22:09 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation Jun Nie
` (11 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
decide right side of a pair per last bit, in case of multiple
mixer pairs.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 7191b1a6d41b3..41c9d3e3e3c7c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -369,11 +369,10 @@ static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer,
static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
{
struct dpu_crtc_state *crtc_state;
- int lm_idx, lm_horiz_position;
+ int lm_idx;
crtc_state = to_dpu_crtc_state(crtc->state);
- lm_horiz_position = 0;
for (lm_idx = 0; lm_idx < crtc_state->num_mixers; lm_idx++) {
const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
struct dpu_hw_mixer *hw_lm = crtc_state->mixers[lm_idx].hw_lm;
@@ -384,7 +383,7 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
cfg.out_width = drm_rect_width(lm_roi);
cfg.out_height = drm_rect_height(lm_roi);
- cfg.right_mixer = lm_horiz_position++;
+ cfg.right_mixer = lm_idx & 0x1;
cfg.flags = 0;
hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (3 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 04/15] drm/msm/dpu: decide right side per last bit Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 22:14 ` Dmitry Baryshkov
2025-01-09 1:29 ` Jessica Zhang
2024-12-19 7:49 ` [PATCH v3 06/15] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation Jun Nie
` (10 subsequent siblings)
15 siblings, 2 replies; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Add the case to reserve multiple pairs mixers for high resolution.
Current code only supports one pair of mixer usage case. To support
quad-pipe usage case, two pairs of mixers are needed.
Current code resets number of mixer on failure of pair's peer test and
retry on another pair. If two pairs are needed, the failure on the test
of 2nd pair results clearing to the 1st pair. This patch only clear the
bit for the 2nd pair allocation before retry on another pair.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index cde3c5616f9bc..a8b01b78c02c7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -316,7 +316,11 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
if (!rm->mixer_blks[i])
continue;
- lm_count = 0;
+ /*
+ * Clear the last bit to drop the previous primary mixer if
+ * fail to find its peer.
+ */
+ lm_count &= 0xfe;
lm_idx[lm_count] = i;
if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 06/15] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (4 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 7:49 ` [PATCH v3 07/15] drm/msm/dpu: bind correct pingpong for quad pipe Jun Nie
` (9 subsequent siblings)
15 siblings, 0 replies; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Up to now the driver has been using encoder to allocate hardware resources.
Switch it to use CRTC id so that mixer number can be known in
dpu_plane_virtual_assign_resources() via CRTC id for sspp alloation.
Because the mixer allocation is done in drm_atomic_helper_check_modeset()
as part of CRTC operation. While the sspp assignment is in
drm_atomic_helper_check_planes() call tree. So CRTC is more central
than encoder. Siwtching the id achieves above goal.
Co-developed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 20 +--
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 12 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 198 ++++++++++++++--------------
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 32 ++++-
4 files changed, 139 insertions(+), 123 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index cc23f364dd080..fd32ef468d5f9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -716,11 +716,11 @@ static void dpu_encoder_assign_crtc_resources(struct dpu_kms *dpu_kms,
memset(cstate->mixers, 0, sizeof(cstate->mixers));
num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
+ crtc_state->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+ crtc_state->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
+ crtc_state->crtc, DPU_HW_BLK_DSPP, hw_dspp,
ARRAY_SIZE(hw_dspp));
for (i = 0; i < num_lm; i++) {
@@ -797,11 +797,11 @@ static int dpu_encoder_virt_atomic_check(
* Dont allocate when active is false.
*/
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
- dpu_rm_release(global_state, drm_enc);
+ dpu_rm_release(global_state, crtc_state->crtc);
if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
- drm_enc, crtc_state, topology);
+ crtc_state->crtc, topology);
if (!ret)
dpu_encoder_assign_crtc_resources(dpu_kms, drm_enc,
global_state, crtc_state);
@@ -1245,17 +1245,17 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
/* Query resource that have been reserved in atomic check step. */
num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_PINGPONG, hw_pp,
+ drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
ARRAY_SIZE(hw_pp));
num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
+ drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
: NULL;
num_dsc = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_DSC,
+ drm_enc->crtc, DPU_HW_BLK_DSC,
hw_dsc, ARRAY_SIZE(hw_dsc));
for (i = 0; i < num_dsc; i++) {
dpu_enc->hw_dsc[i] = to_dpu_hw_dsc(hw_dsc[i]);
@@ -1270,7 +1270,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
struct dpu_hw_blk *hw_cdm = NULL;
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_CDM,
+ drm_enc->crtc, DPU_HW_BLK_CDM,
&hw_cdm, 1);
dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
}
@@ -2197,7 +2197,7 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
global_state = dpu_kms_get_existing_global_state(phys_enc->dpu_kms);
num_lm = dpu_rm_get_assigned_resources(&phys_enc->dpu_kms->rm, global_state,
- phys_enc->parent->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+ phys_enc->parent->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
for (i = 0; i < num_lm; i++) {
hw_mixer[i] = to_dpu_hw_mixer(hw_lm[i]);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 547cdb2c0c788..54ef6cfa2485a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -124,12 +124,12 @@ struct dpu_global_state {
struct dpu_rm *rm;
- uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0];
- uint32_t mixer_to_enc_id[LM_MAX - LM_0];
- uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
- uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
- uint32_t dsc_to_enc_id[DSC_MAX - DSC_0];
- uint32_t cdm_to_enc_id;
+ uint32_t pingpong_to_crtc_id[PINGPONG_MAX - PINGPONG_0];
+ uint32_t mixer_to_crtc_id[LM_MAX - LM_0];
+ uint32_t ctl_to_crtc_id[CTL_MAX - CTL_0];
+ uint32_t dspp_to_crtc_id[DSPP_MAX - DSPP_0];
+ uint32_t dsc_to_crtc_id[DSC_MAX - DSC_0];
+ uint32_t cdm_to_crtc_id;
uint32_t sspp_to_crtc_id[SSPP_MAX - SSPP_NONE];
};
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index a8b01b78c02c7..a6a410e301abd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -21,9 +21,9 @@
static inline bool reserved_by_other(uint32_t *res_map, int idx,
- uint32_t enc_id)
+ uint32_t crtc_id)
{
- return res_map[idx] && res_map[idx] != enc_id;
+ return res_map[idx] && res_map[idx] != crtc_id;
}
/**
@@ -235,7 +235,7 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx)
* pingpong
* @rm: dpu resource manager handle
* @global_state: resources shared across multiple kms objects
- * @enc_id: encoder id requesting for allocation
+ * @crtc_id: crtc id requesting for allocation
* @lm_idx: index of proposed layer mixer in rm->mixer_blks[], function checks
* if lm, and all other hardwired blocks connected to the lm (pp) is
* available and appropriate
@@ -249,14 +249,14 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx)
*/
static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx,
+ uint32_t crtc_id, int lm_idx, int *pp_idx, int *dspp_idx,
struct dpu_rm_requirements *reqs)
{
const struct dpu_lm_cfg *lm_cfg;
int idx;
/* Already reserved? */
- if (reserved_by_other(global_state->mixer_to_enc_id, lm_idx, enc_id)) {
+ if (reserved_by_other(global_state->mixer_to_crtc_id, lm_idx, crtc_id)) {
DPU_DEBUG("lm %d already reserved\n", lm_idx + LM_0);
return false;
}
@@ -268,7 +268,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
return false;
}
- if (reserved_by_other(global_state->pingpong_to_enc_id, idx, enc_id)) {
+ if (reserved_by_other(global_state->pingpong_to_crtc_id, idx, crtc_id)) {
DPU_DEBUG("lm %d pp %d already reserved\n", lm_cfg->id,
lm_cfg->pingpong);
return false;
@@ -284,7 +284,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
return false;
}
- if (reserved_by_other(global_state->dspp_to_enc_id, idx, enc_id)) {
+ if (reserved_by_other(global_state->dspp_to_crtc_id, idx, crtc_id)) {
DPU_DEBUG("lm %d dspp %d already reserved\n", lm_cfg->id,
lm_cfg->dspp);
return false;
@@ -296,7 +296,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id,
+ uint32_t crtc_id,
struct dpu_rm_requirements *reqs)
{
@@ -324,7 +324,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
lm_idx[lm_count] = i;
if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
- enc_id, i, &pp_idx[lm_count],
+ crtc_id, i, &pp_idx[lm_count],
&dspp_idx[lm_count], reqs)) {
continue;
}
@@ -343,7 +343,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
continue;
if (!_dpu_rm_check_lm_and_get_connected_blks(rm,
- global_state, enc_id, j,
+ global_state, crtc_id, j,
&pp_idx[lm_count], &dspp_idx[lm_count],
reqs)) {
continue;
@@ -360,13 +360,16 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
}
for (i = 0; i < lm_count; i++) {
- global_state->mixer_to_enc_id[lm_idx[i]] = enc_id;
- global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id;
- global_state->dspp_to_enc_id[dspp_idx[i]] =
- reqs->topology.num_dspp ? enc_id : 0;
+ global_state->mixer_to_crtc_id[lm_idx[i]] = crtc_id;
+ global_state->pingpong_to_crtc_id[pp_idx[i]] = crtc_id;
+ global_state->dspp_to_crtc_id[dspp_idx[i]] =
+ reqs->topology.num_dspp ? crtc_id : 0;
- trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id,
+ trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, crtc_id,
pp_idx[i] + PINGPONG_0);
+
+ DPU_DEBUG("reserve lm[%d]:%d, pp_idx[%d]:%d, dspp[%d]:%d for crtc_id %d\n",
+ i, lm_idx[i], i, pp_idx[i], i, dspp_idx[i], crtc_id);
}
return 0;
@@ -375,7 +378,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
static int _dpu_rm_reserve_ctls(
struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id,
+ uint32_t crtc_id,
const struct msm_display_topology *top)
{
int ctl_idx[MAX_BLOCKS];
@@ -399,7 +402,7 @@ static int _dpu_rm_reserve_ctls(
if (!rm->ctl_blks[j])
continue;
- if (reserved_by_other(global_state->ctl_to_enc_id, j, enc_id))
+ if (reserved_by_other(global_state->ctl_to_crtc_id, j, crtc_id))
continue;
ctl = to_dpu_hw_ctl(rm->ctl_blks[j]);
@@ -423,8 +426,8 @@ static int _dpu_rm_reserve_ctls(
return -ENAVAIL;
for (i = 0; i < ARRAY_SIZE(ctl_idx) && i < num_ctls; i++) {
- global_state->ctl_to_enc_id[ctl_idx[i]] = enc_id;
- trace_dpu_rm_reserve_ctls(i + CTL_0, enc_id);
+ global_state->ctl_to_crtc_id[ctl_idx[i]] = crtc_id;
+ trace_dpu_rm_reserve_ctls(i + CTL_0, crtc_id);
}
return 0;
@@ -432,12 +435,12 @@ static int _dpu_rm_reserve_ctls(
static int _dpu_rm_pingpong_next_index(struct dpu_global_state *global_state,
int start,
- uint32_t enc_id)
+ uint32_t crtc_id)
{
int i;
for (i = start; i < (PINGPONG_MAX - PINGPONG_0); i++) {
- if (global_state->pingpong_to_enc_id[i] == enc_id)
+ if (global_state->pingpong_to_crtc_id[i] == crtc_id)
return i;
}
@@ -458,7 +461,7 @@ static int _dpu_rm_pingpong_dsc_check(int dsc_idx, int pp_idx)
static int _dpu_rm_dsc_alloc(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id,
+ uint32_t crtc_id,
const struct msm_display_topology *top)
{
int num_dsc = 0;
@@ -471,10 +474,10 @@ static int _dpu_rm_dsc_alloc(struct dpu_rm *rm,
if (!rm->dsc_blks[dsc_idx])
continue;
- if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id))
+ if (reserved_by_other(global_state->dsc_to_crtc_id, dsc_idx, crtc_id))
continue;
- pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id);
+ pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, crtc_id);
if (pp_idx < 0)
return -ENAVAIL;
@@ -482,7 +485,7 @@ static int _dpu_rm_dsc_alloc(struct dpu_rm *rm,
if (ret)
return -ENAVAIL;
- global_state->dsc_to_enc_id[dsc_idx] = enc_id;
+ global_state->dsc_to_crtc_id[dsc_idx] = crtc_id;
num_dsc++;
pp_idx++;
}
@@ -498,7 +501,7 @@ static int _dpu_rm_dsc_alloc(struct dpu_rm *rm,
static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- uint32_t enc_id,
+ uint32_t crtc_id,
const struct msm_display_topology *top)
{
int num_dsc = 0;
@@ -513,11 +516,11 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
continue;
/* consective dsc index to be paired */
- if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id) ||
- reserved_by_other(global_state->dsc_to_enc_id, dsc_idx + 1, enc_id))
+ if (reserved_by_other(global_state->dsc_to_crtc_id, dsc_idx, crtc_id) ||
+ reserved_by_other(global_state->dsc_to_crtc_id, dsc_idx + 1, crtc_id))
continue;
- pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id);
+ pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, crtc_id);
if (pp_idx < 0)
return -ENAVAIL;
@@ -527,7 +530,7 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
continue;
}
- pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, enc_id);
+ pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, crtc_id);
if (pp_idx < 0)
return -ENAVAIL;
@@ -537,8 +540,8 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
continue;
}
- global_state->dsc_to_enc_id[dsc_idx] = enc_id;
- global_state->dsc_to_enc_id[dsc_idx + 1] = enc_id;
+ global_state->dsc_to_crtc_id[dsc_idx] = crtc_id;
+ global_state->dsc_to_crtc_id[dsc_idx + 1] = crtc_id;
num_dsc += 2;
pp_idx++; /* start for next pair */
}
@@ -554,11 +557,9 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm,
static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *enc,
+ uint32_t crtc_id,
const struct msm_display_topology *top)
{
- uint32_t enc_id = enc->base.id;
-
if (!top->num_dsc || !top->num_intf)
return 0;
@@ -568,22 +569,22 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
* 2) DSC pair starts from even index, such as index(0,1), (2,3), etc
* 3) even PINGPONG connects to even DSC
* 4) odd PINGPONG connects to odd DSC
- * 5) pair: encoder +--> pp_idx_0 --> dsc_idx_0
+ * 5) pair: crtc +--> pp_idx_0 --> dsc_idx_0
* +--> pp_idx_1 --> dsc_idx_1
*/
/* num_dsc should be either 1, 2 or 4 */
if (top->num_dsc > top->num_intf) /* merge mode */
- return _dpu_rm_dsc_alloc_pair(rm, global_state, enc_id, top);
+ return _dpu_rm_dsc_alloc_pair(rm, global_state, crtc_id, top);
else
- return _dpu_rm_dsc_alloc(rm, global_state, enc_id, top);
+ return _dpu_rm_dsc_alloc(rm, global_state, crtc_id, top);
return 0;
}
static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *enc)
+ uint32_t crtc_id)
{
/* try allocating only one CDM block */
if (!rm->cdm_blk) {
@@ -591,12 +592,12 @@ static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
return -EIO;
}
- if (global_state->cdm_to_enc_id) {
+ if (global_state->cdm_to_crtc_id) {
DPU_ERROR("CDM_0 is already allocated\n");
return -EIO;
}
- global_state->cdm_to_enc_id = enc->base.id;
+ global_state->cdm_to_crtc_id = crtc_id;
return 0;
}
@@ -604,30 +605,30 @@ static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
static int _dpu_rm_make_reservation(
struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *enc,
+ uint32_t crtc_id,
struct dpu_rm_requirements *reqs)
{
int ret;
- ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, reqs);
+ ret = _dpu_rm_reserve_lms(rm, global_state, crtc_id, reqs);
if (ret) {
DPU_ERROR("unable to find appropriate mixers\n");
return ret;
}
- ret = _dpu_rm_reserve_ctls(rm, global_state, enc->base.id,
+ ret = _dpu_rm_reserve_ctls(rm, global_state, crtc_id,
&reqs->topology);
if (ret) {
DPU_ERROR("unable to find appropriate CTL\n");
return ret;
}
- ret = _dpu_rm_reserve_dsc(rm, global_state, enc, &reqs->topology);
+ ret = _dpu_rm_reserve_dsc(rm, global_state, crtc_id, &reqs->topology);
if (ret)
return ret;
if (reqs->topology.needs_cdm) {
- ret = _dpu_rm_reserve_cdm(rm, global_state, enc);
+ ret = _dpu_rm_reserve_cdm(rm, global_state, crtc_id);
if (ret) {
DPU_ERROR("unable to find CDM blk\n");
return ret;
@@ -638,7 +639,7 @@ static int _dpu_rm_make_reservation(
}
static int _dpu_rm_populate_requirements(
- struct drm_encoder *enc,
+ struct drm_crtc *crtc,
struct dpu_rm_requirements *reqs,
struct msm_display_topology req_topology)
{
@@ -652,12 +653,12 @@ static int _dpu_rm_populate_requirements(
}
static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt,
- uint32_t enc_id)
+ uint32_t crtc_id)
{
int i;
for (i = 0; i < cnt; i++) {
- if (res_mapping[i] == enc_id)
+ if (res_mapping[i] == crtc_id)
res_mapping[i] = 0;
}
}
@@ -666,23 +667,24 @@ static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt,
* dpu_rm_release - Given the encoder for the display chain, release any
* HW blocks previously reserved for that use case.
* @global_state: resources shared across multiple kms objects
- * @enc: DRM Encoder handle
+ * @crtc: DRM CRTC handle
* @return: 0 on Success otherwise -ERROR
*/
void dpu_rm_release(struct dpu_global_state *global_state,
- struct drm_encoder *enc)
+ struct drm_crtc *crtc)
{
- _dpu_rm_clear_mapping(global_state->pingpong_to_enc_id,
- ARRAY_SIZE(global_state->pingpong_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(global_state->mixer_to_enc_id,
- ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(global_state->ctl_to_enc_id,
- ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(global_state->dsc_to_enc_id,
- ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(global_state->dspp_to_enc_id,
- ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id);
- _dpu_rm_clear_mapping(&global_state->cdm_to_enc_id, 1, enc->base.id);
+ uint32_t crtc_id = crtc->base.id;
+
+ _dpu_rm_clear_mapping(global_state->pingpong_to_crtc_id,
+ ARRAY_SIZE(global_state->pingpong_to_crtc_id), crtc_id);
+ _dpu_rm_clear_mapping(global_state->mixer_to_crtc_id,
+ ARRAY_SIZE(global_state->mixer_to_crtc_id), crtc_id);
+ _dpu_rm_clear_mapping(global_state->ctl_to_crtc_id,
+ ARRAY_SIZE(global_state->ctl_to_crtc_id), crtc_id);
+ _dpu_rm_clear_mapping(global_state->dsc_to_crtc_id,
+ ARRAY_SIZE(global_state->dsc_to_crtc_id), crtc_id);
+ _dpu_rm_clear_mapping(global_state->dspp_to_crtc_id,
+ ARRAY_SIZE(global_state->dspp_to_crtc_id), crtc_id);
}
/**
@@ -694,45 +696,36 @@ void dpu_rm_release(struct dpu_global_state *global_state,
* HW Reservations should be released via dpu_rm_release_hw.
* @rm: DPU Resource Manager handle
* @global_state: resources shared across multiple kms objects
- * @enc: DRM Encoder handle
- * @crtc_state: Proposed Atomic DRM CRTC State handle
+ * @crtc: DRM CRTC handle
* @topology: Pointer to topology info for the display
* @return: 0 on Success otherwise -ERROR
*/
int dpu_rm_reserve(
struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *enc,
- struct drm_crtc_state *crtc_state,
+ struct drm_crtc *crtc,
struct msm_display_topology topology)
{
struct dpu_rm_requirements reqs;
int ret;
- /* Check if this is just a page-flip */
- if (!drm_atomic_crtc_needs_modeset(crtc_state))
- return 0;
-
if (IS_ERR(global_state)) {
DPU_ERROR("failed to global state\n");
return PTR_ERR(global_state);
}
- DRM_DEBUG_KMS("reserving hw for enc %d crtc %d\n",
- enc->base.id, crtc_state->crtc->base.id);
+ DRM_DEBUG_KMS("reserving hw for crtc %d\n", crtc->base.id);
- ret = _dpu_rm_populate_requirements(enc, &reqs, topology);
+ ret = _dpu_rm_populate_requirements(crtc, &reqs, topology);
if (ret) {
DPU_ERROR("failed to populate hw requirements\n");
return ret;
}
- ret = _dpu_rm_make_reservation(rm, global_state, enc, &reqs);
+ ret = _dpu_rm_make_reservation(rm, global_state, crtc->base.id, &reqs);
if (ret)
DPU_ERROR("failed to reserve hw resources: %d\n", ret);
-
-
return ret;
}
@@ -806,7 +799,7 @@ struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm,
/**
* dpu_rm_release_all_sspp - Given the CRTC, release all SSPP
* blocks previously reserved for that use case.
- * @rm: DPU Resource Manager handle
+ * @global_state: resources shared across multiple kms objects
* @crtc: DRM CRTC handle
*/
void dpu_rm_release_all_sspp(struct dpu_global_state *global_state,
@@ -838,48 +831,49 @@ static char *dpu_hw_blk_type_name[] = {
* assigned to this encoder
* @rm: DPU Resource Manager handle
* @global_state: resources shared across multiple kms objects
- * @enc_id: encoder id requesting for allocation
+ * @crtc: DRM CRTC handle
* @type: resource type to return data for
* @blks: pointer to the array to be filled by HW resources
* @blks_size: size of the @blks array
*/
int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
- struct dpu_global_state *global_state, uint32_t enc_id,
+ struct dpu_global_state *global_state, struct drm_crtc *crtc,
enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size)
{
+ uint32_t crtc_id = crtc->base.id;
struct dpu_hw_blk **hw_blks;
- uint32_t *hw_to_enc_id;
+ uint32_t *hw_to_crtc_id;
int i, num_blks, max_blks;
switch (type) {
case DPU_HW_BLK_PINGPONG:
hw_blks = rm->pingpong_blks;
- hw_to_enc_id = global_state->pingpong_to_enc_id;
+ hw_to_crtc_id = global_state->pingpong_to_crtc_id;
max_blks = ARRAY_SIZE(rm->pingpong_blks);
break;
case DPU_HW_BLK_LM:
hw_blks = rm->mixer_blks;
- hw_to_enc_id = global_state->mixer_to_enc_id;
+ hw_to_crtc_id = global_state->mixer_to_crtc_id;
max_blks = ARRAY_SIZE(rm->mixer_blks);
break;
case DPU_HW_BLK_CTL:
hw_blks = rm->ctl_blks;
- hw_to_enc_id = global_state->ctl_to_enc_id;
+ hw_to_crtc_id = global_state->ctl_to_crtc_id;
max_blks = ARRAY_SIZE(rm->ctl_blks);
break;
case DPU_HW_BLK_DSPP:
hw_blks = rm->dspp_blks;
- hw_to_enc_id = global_state->dspp_to_enc_id;
+ hw_to_crtc_id = global_state->dspp_to_crtc_id;
max_blks = ARRAY_SIZE(rm->dspp_blks);
break;
case DPU_HW_BLK_DSC:
hw_blks = rm->dsc_blks;
- hw_to_enc_id = global_state->dsc_to_enc_id;
+ hw_to_crtc_id = global_state->dsc_to_crtc_id;
max_blks = ARRAY_SIZE(rm->dsc_blks);
break;
case DPU_HW_BLK_CDM:
hw_blks = &rm->cdm_blk;
- hw_to_enc_id = &global_state->cdm_to_enc_id;
+ hw_to_crtc_id = &global_state->cdm_to_crtc_id;
max_blks = 1;
break;
default:
@@ -889,17 +883,17 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
num_blks = 0;
for (i = 0; i < max_blks; i++) {
- if (hw_to_enc_id[i] != enc_id)
+ if (hw_to_crtc_id[i] != crtc_id)
continue;
if (num_blks == blks_size) {
- DPU_ERROR("More than %d %s assigned to enc %d\n",
- blks_size, dpu_hw_blk_type_name[type], enc_id);
+ DPU_ERROR("More than %d resources assigned to crtc %d\n",
+ blks_size, crtc_id);
break;
}
if (!hw_blks[i]) {
- DPU_ERROR("%s unavailable to assign to enc %d\n",
- dpu_hw_blk_type_name[type], enc_id);
+ DPU_ERROR("%s unavailable to assign to crtc %d\n",
+ dpu_hw_blk_type_name[type], crtc_id);
break;
}
blks[num_blks++] = hw_blks[i];
@@ -934,38 +928,38 @@ void dpu_rm_print_state(struct drm_printer *p,
drm_puts(p, "resource mapping:\n");
drm_puts(p, "\tpingpong=");
- for (i = 0; i < ARRAY_SIZE(global_state->pingpong_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->pingpong_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->pingpong_blks[i],
- global_state->pingpong_to_enc_id[i]);
+ global_state->pingpong_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tmixer=");
- for (i = 0; i < ARRAY_SIZE(global_state->mixer_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->mixer_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->mixer_blks[i],
- global_state->mixer_to_enc_id[i]);
+ global_state->mixer_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tctl=");
- for (i = 0; i < ARRAY_SIZE(global_state->ctl_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->ctl_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->ctl_blks[i],
- global_state->ctl_to_enc_id[i]);
+ global_state->ctl_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tdspp=");
- for (i = 0; i < ARRAY_SIZE(global_state->dspp_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->dspp_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->dspp_blks[i],
- global_state->dspp_to_enc_id[i]);
+ global_state->dspp_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tdsc=");
- for (i = 0; i < ARRAY_SIZE(global_state->dsc_to_enc_id); i++)
+ for (i = 0; i < ARRAY_SIZE(global_state->dsc_to_crtc_id); i++)
dpu_rm_print_state_helper(p, rm->dsc_blks[i],
- global_state->dsc_to_enc_id[i]);
+ global_state->dsc_to_crtc_id[i]);
drm_puts(p, "\n");
drm_puts(p, "\tcdm=");
dpu_rm_print_state_helper(p, rm->cdm_blk,
- global_state->cdm_to_enc_id);
+ global_state->cdm_to_crtc_id);
drm_puts(p, "\n");
drm_puts(p, "\tsspp=");
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 227a486b2b83a..ba2d9bc1cc687 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -66,14 +66,33 @@ int dpu_rm_init(struct drm_device *dev,
const struct msm_mdss_data *mdss_data,
void __iomem *mmio);
-int dpu_rm_reserve(struct dpu_rm *rm,
+/**
+ * dpu_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze
+ * the use connections and user requirements, specified through related
+ * topology control properties, and reserve hardware blocks to that
+ * display chain.
+ * HW blocks can then be accessed through dpu_rm_get_* functions.
+ * HW Reservations should be released via dpu_rm_release_hw.
+ * @rm: DPU Resource Manager handle
+ * @crtc: DRM CRTC handle
+ * @topology: Pointer to topology info for the display
+ * @Return: 0 on Success otherwise -ERROR
+ */
+int dpu_rm_reserve(
+ struct dpu_rm *rm,
struct dpu_global_state *global_state,
- struct drm_encoder *drm_enc,
- struct drm_crtc_state *crtc_state,
+ struct drm_crtc *crtc,
struct msm_display_topology topology);
+/**
+ * dpu_rm_release - Given the crtc for the display chain, release any
+ * HW blocks previously reserved for that use case.
+ * @rm: DPU Resource Manager handle
+ * @crtc: DRM CRTC handle
+ * @Return: 0 on Success otherwise -ERROR
+ */
void dpu_rm_release(struct dpu_global_state *global_state,
- struct drm_encoder *enc);
+ struct drm_crtc *crtc);
struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm,
struct dpu_global_state *global_state,
@@ -83,8 +102,11 @@ struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm,
void dpu_rm_release_all_sspp(struct dpu_global_state *global_state,
struct drm_crtc *crtc);
+/**
+ * Get hw resources of the given type that are assigned to this crtc.
+ */
int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
- struct dpu_global_state *global_state, uint32_t enc_id,
+ struct dpu_global_state *global_state, struct drm_crtc *crtc,
enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size);
void dpu_rm_print_state(struct drm_printer *p,
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 07/15] drm/msm/dpu: bind correct pingpong for quad pipe
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (5 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 06/15] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2025-01-09 18:12 ` Jessica Zhang
2024-12-19 7:49 ` [PATCH v3 08/15] drm/msm/dpu: handle pipes as array Jun Nie
` (8 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
There are 2 interfaces and 4 pingpong in quad pipe. Map the 2nd
interface to 3rd PP instead of the 2nd PP.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index fd32ef468d5f9..96d06db3e4be5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1220,7 +1220,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
- int num_ctl, num_pp, num_dsc;
+ struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
+ int num_lm, num_ctl, num_pp, num_dsc, num_pp_per_intf;
unsigned int dsc_mask = 0;
int i;
@@ -1275,11 +1276,21 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
}
+ num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+ drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+
+
+ /*
+ * There may be 4 PP and 2 INTF for quad pipe case, so INTF is not
+ * mapped to PP 1:1. Let's calculate the stride with pipe/INTF
+ */
+ num_pp_per_intf = num_lm / dpu_enc->num_phys_encs;
+
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
struct dpu_hw_ctl *ctl0 = to_dpu_hw_ctl(hw_ctl[0]);
- phys->hw_pp = dpu_enc->hw_pp[i];
+ phys->hw_pp = dpu_enc->hw_pp[num_pp_per_intf * i];
if (!phys->hw_pp) {
DPU_ERROR_ENC(dpu_enc,
"no pp block assigned at idx: %d\n", i);
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 08/15] drm/msm/dpu: handle pipes as array
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (6 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 07/15] drm/msm/dpu: bind correct pingpong for quad pipe Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 22:26 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 09/15] drm/msm/dpu: split PIPES_PER_STAGE definition per plane and mixer Jun Nie
` (7 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Store pipes in array with removing dedicated r_pipe. There are
2 pipes in a drm plane at most currently. While 4 pipes are
needed for new usage case. This change generalize the handling
to pipe pair and ease handling to another pipe pair later.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 35 +++---
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 170 +++++++++++++++++-------------
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 12 +--
3 files changed, 113 insertions(+), 104 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 41c9d3e3e3c7c..a0284b1425b1f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -442,7 +442,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
const struct msm_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
- uint32_t lm_idx;
+ uint32_t lm_idx, i;
bool bg_alpha_enable = false;
DECLARE_BITMAP(fetch_active, SSPP_MAX);
@@ -463,20 +463,15 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
bg_alpha_enable = true;
- set_bit(pstate->pipe.sspp->idx, fetch_active);
- _dpu_crtc_blend_setup_pipe(crtc, plane,
- mixer, cstate->num_mixers,
- pstate->stage,
- format, fb ? fb->modifier : 0,
- &pstate->pipe, 0, stage_cfg);
-
- if (pstate->r_pipe.sspp) {
- set_bit(pstate->r_pipe.sspp->idx, fetch_active);
+ for (i = 0; i < PIPES_PER_STAGE; i++) {
+ if (!pstate->pipe[i].sspp)
+ continue;
+ set_bit(pstate->pipe[i].sspp->idx, fetch_active);
_dpu_crtc_blend_setup_pipe(crtc, plane,
mixer, cstate->num_mixers,
pstate->stage,
format, fb ? fb->modifier : 0,
- &pstate->r_pipe, 1, stage_cfg);
+ &pstate->pipe[i], i, stage_cfg);
}
/* blend config update */
@@ -1440,15 +1435,15 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
seq_printf(s, "\tdst x:%4d dst_y:%4d dst_w:%4d dst_h:%4d\n",
state->crtc_x, state->crtc_y, state->crtc_w,
state->crtc_h);
- seq_printf(s, "\tsspp[0]:%s\n",
- pstate->pipe.sspp->cap->name);
- seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
- pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
- if (pstate->r_pipe.sspp) {
- seq_printf(s, "\tsspp[1]:%s\n",
- pstate->r_pipe.sspp->cap->name);
- seq_printf(s, "\tmultirect[1]: mode: %d index: %d\n",
- pstate->r_pipe.multirect_mode, pstate->r_pipe.multirect_index);
+
+ for (i = 0; i < PIPES_PER_STAGE; i++) {
+ if (pstate->pipe[i].sspp) {
+ seq_printf(s, "\tsspp[%d]:%s\n",
+ i, pstate->pipe[i].sspp->cap->name);
+ seq_printf(s, "\tmultirect[%d]: mode: %d index: %d\n",
+ i, pstate->pipe[i].multirect_mode,
+ pstate->pipe[i].multirect_index);
+ }
}
seq_puts(s, "\n");
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 098abc2c0003c..aaf934ec96be5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -619,6 +619,7 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
struct msm_drm_private *priv = plane->dev->dev_private;
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
u32 fill_color = (color & 0xFFFFFF) | ((alpha & 0xFF) << 24);
+ int i;
DPU_DEBUG_PLANE(pdpu, "\n");
@@ -632,12 +633,12 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
return;
/* update sspp */
- _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg.dst_rect,
- fill_color, fmt);
-
- if (pstate->r_pipe.sspp)
- _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg.dst_rect,
- fill_color, fmt);
+ for (i = 0; i < PIPES_PER_STAGE; i++) {
+ if (pstate->pipe[i].sspp)
+ _dpu_plane_color_fill_pipe(pstate, &pstate->pipe[i],
+ &pstate->pipe_cfg[i].dst_rect,
+ fill_color, fmt);
+ }
}
static int dpu_plane_prepare_fb(struct drm_plane *plane,
@@ -799,8 +800,8 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate;
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
- struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
- struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+ struct dpu_sw_pipe_cfg *pipe_cfg;
+ struct dpu_sw_pipe_cfg *r_pipe_cfg;
struct drm_rect fb_rect = { 0 };
uint32_t max_linewidth;
@@ -825,6 +826,9 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
return -EINVAL;
}
+ /* move the assignment here, to ease handling to another pairs later */
+ pipe_cfg = &pstate->pipe_cfg[0];
+ r_pipe_cfg = &pstate->pipe_cfg[1];
/* state->src is 16.16, src_rect is not */
drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
@@ -921,11 +925,11 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
drm_atomic_get_new_plane_state(state, plane);
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
- struct dpu_sw_pipe *pipe = &pstate->pipe;
- struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
const struct msm_format *fmt;
- struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
- struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+ struct dpu_sw_pipe *pipe = &pstate->pipe[0];
+ struct dpu_sw_pipe *r_pipe = &pstate->pipe[1];
+ struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[0];
+ struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[1];
uint32_t supported_rotations;
const struct dpu_sspp_cfg *pipe_hw_caps;
const struct dpu_sspp_sub_blks *sblk;
@@ -1010,10 +1014,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
- struct dpu_sw_pipe *pipe = &pstate->pipe;
- struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
- struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
- struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+ struct dpu_sw_pipe *pipe = &pstate->pipe[0];
+ struct dpu_sw_pipe *r_pipe = &pstate->pipe[1];
+ struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[0];
+ struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[1];
const struct drm_crtc_state *crtc_state = NULL;
uint32_t max_linewidth = dpu_kms->catalog->caps->max_linewidth;
@@ -1057,7 +1061,7 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
drm_atomic_get_old_plane_state(state, plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(plane_state);
struct drm_crtc_state *crtc_state;
- int ret;
+ int ret, i;
if (plane_state->crtc)
crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -1072,8 +1076,8 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
* resources are freed by dpu_crtc_assign_plane_resources(),
* but clean them here.
*/
- pstate->pipe.sspp = NULL;
- pstate->r_pipe.sspp = NULL;
+ for (i = 0; i < PIPES_PER_STAGE; i++)
+ pstate->pipe[i].sspp = NULL;
return 0;
}
@@ -1110,19 +1114,22 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
struct dpu_sw_pipe_cfg *pipe_cfg;
struct dpu_sw_pipe_cfg *r_pipe_cfg;
const struct msm_format *fmt;
+ int i;
if (plane_state->crtc)
crtc_state = drm_atomic_get_new_crtc_state(state,
plane_state->crtc);
pstate = to_dpu_plane_state(plane_state);
- pipe = &pstate->pipe;
- r_pipe = &pstate->r_pipe;
- pipe_cfg = &pstate->pipe_cfg;
- r_pipe_cfg = &pstate->r_pipe_cfg;
- pipe->sspp = NULL;
- r_pipe->sspp = NULL;
+ /* TODO: loop below code for another pair later */
+ pipe = &pstate->pipe[0];
+ r_pipe = &pstate->pipe[1];
+ pipe_cfg = &pstate->pipe_cfg[0];
+ r_pipe_cfg = &pstate->pipe_cfg[1];
+
+ for (i = 0; i < PIPES_PER_STAGE; i++)
+ pstate->pipe[i].sspp = NULL;
if (!plane_state->fb)
return -EINVAL;
@@ -1212,6 +1219,7 @@ void dpu_plane_flush(struct drm_plane *plane)
{
struct dpu_plane *pdpu;
struct dpu_plane_state *pstate;
+ int i;
if (!plane || !plane->state) {
DPU_ERROR("invalid plane\n");
@@ -1232,8 +1240,8 @@ void dpu_plane_flush(struct drm_plane *plane)
/* force 100% alpha */
_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
else {
- dpu_plane_flush_csc(pdpu, &pstate->pipe);
- dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
+ for (i = 0; i < PIPES_PER_STAGE; i++)
+ dpu_plane_flush_csc(pdpu, &pstate->pipe[i]);
}
/* flag h/w flush complete */
@@ -1334,15 +1342,19 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane,
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct drm_plane_state *state = plane->state;
struct dpu_plane_state *pstate = to_dpu_plane_state(state);
- struct dpu_sw_pipe *pipe = &pstate->pipe;
- struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
struct drm_crtc *crtc = state->crtc;
struct drm_framebuffer *fb = state->fb;
bool is_rt_pipe;
const struct msm_format *fmt =
msm_framebuffer_format(fb);
- struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
- struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+ struct dpu_hw_fmt_layout layout;
+ int ret, i;
+
+ ret = dpu_format_populate_plane_sizes(fb, &layout);
+ if (ret) {
+ DPU_ERROR_PLANE(pdpu, "failed to get format plane sizes, %d\n", ret);
+ return;
+ }
pstate->pending = true;
@@ -1357,12 +1369,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane,
crtc->base.id, DRM_RECT_ARG(&state->dst),
&fmt->pixel_format, MSM_FORMAT_IS_UBWC(fmt));
- dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
- drm_mode_vrefresh(&crtc->mode),
- &pstate->layout);
-
- if (r_pipe->sspp) {
- dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
+ /* move the assignment here, to ease handling to another pairs later */
+ for (i = 0; i < PIPES_PER_STAGE; i++) {
+ if (!pstate->pipe[i].sspp)
+ continue;
+ dpu_plane_sspp_update_pipe(plane, &pstate->pipe[i],
+ &pstate->pipe_cfg[i], fmt,
drm_mode_vrefresh(&crtc->mode),
&pstate->layout);
}
@@ -1370,15 +1382,17 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane,
if (pstate->needs_qos_remap)
pstate->needs_qos_remap = false;
- pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt,
- &crtc->mode, pipe_cfg);
-
- pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
-
- if (r_pipe->sspp) {
- pstate->plane_fetch_bw += _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, r_pipe_cfg);
+ pstate->plane_fetch_bw = 0;
+ pstate->plane_clk = 0;
+ for (i = 0; i < PIPES_PER_STAGE; i++) {
+ if (!pstate->pipe[i].sspp)
+ continue;
+ pstate->plane_fetch_bw += _dpu_plane_calc_bw(pdpu->catalog, fmt,
+ &crtc->mode, &pstate->pipe_cfg[i]);
- pstate->plane_clk = max(pstate->plane_clk, _dpu_plane_calc_clk(&crtc->mode, r_pipe_cfg));
+ pstate->plane_clk = max(pstate->plane_clk,
+ _dpu_plane_calc_clk(&crtc->mode,
+ &pstate->pipe_cfg[i]));
}
}
@@ -1386,17 +1400,24 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
{
struct drm_plane_state *state = plane->state;
struct dpu_plane_state *pstate = to_dpu_plane_state(state);
- struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+ struct dpu_sw_pipe *pipe;
+ int i;
- trace_dpu_plane_disable(DRMID(plane), false,
- pstate->pipe.multirect_mode);
+ for (i = 0; i < PIPES_PER_STAGE; i += 1) {
+ pipe = &pstate->pipe[i];
+ if (!pipe->sspp)
+ continue;
- if (r_pipe->sspp) {
- r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
- r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+ trace_dpu_plane_disable(DRMID(plane), false,
+ pstate->pipe[i].multirect_mode);
- if (r_pipe->sspp->ops.setup_multirect)
- r_pipe->sspp->ops.setup_multirect(r_pipe);
+ if (pipe->sspp && i == 1) {
+ pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+ pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+ if (pipe->sspp->ops.setup_multirect)
+ pipe->sspp->ops.setup_multirect(pipe);
+ }
}
pstate->pending = true;
@@ -1491,31 +1512,26 @@ static void dpu_plane_atomic_print_state(struct drm_printer *p,
const struct drm_plane_state *state)
{
const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
- const struct dpu_sw_pipe *pipe = &pstate->pipe;
- const struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
- const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
- const struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+ const struct dpu_sw_pipe *pipe;
+ const struct dpu_sw_pipe_cfg *pipe_cfg;
+ int i;
drm_printf(p, "\tstage=%d\n", pstate->stage);
- if (pipe->sspp) {
- drm_printf(p, "\tsspp[0]=%s\n", pipe->sspp->cap->name);
- drm_printf(p, "\tmultirect_mode[0]=%s\n",
+ for (i = 0; i < PIPES_PER_STAGE; i++) {
+ pipe = &pstate->pipe[i];
+ if (!pipe->sspp)
+ continue;
+ pipe_cfg = &pstate->pipe_cfg[i];
+ drm_printf(p, "\tsspp[%d]=%s\n", i, pipe->sspp->cap->name);
+ drm_printf(p, "\tmultirect_mode[%d]=%s\n", i,
dpu_get_multirect_mode(pipe->multirect_mode));
- drm_printf(p, "\tmultirect_index[0]=%s\n",
+ drm_printf(p, "\tmultirect_index[%d]=%s\n", i,
dpu_get_multirect_index(pipe->multirect_index));
- drm_printf(p, "\tsrc[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->src_rect));
- drm_printf(p, "\tdst[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->dst_rect));
- }
-
- if (r_pipe->sspp) {
- drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
- drm_printf(p, "\tmultirect_mode[1]=%s\n",
- dpu_get_multirect_mode(r_pipe->multirect_mode));
- drm_printf(p, "\tmultirect_index[1]=%s\n",
- dpu_get_multirect_index(r_pipe->multirect_index));
- drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
- drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
+ drm_printf(p, "\tsrc[%d]=" DRM_RECT_FMT "\n", i,
+ DRM_RECT_ARG(&pipe_cfg->src_rect));
+ drm_printf(p, "\tdst[%d]=" DRM_RECT_FMT "\n", i,
+ DRM_RECT_ARG(&pipe_cfg->dst_rect));
}
}
@@ -1553,14 +1569,16 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
+ int i;
if (!pdpu->is_rt_pipe)
return;
pm_runtime_get_sync(&dpu_kms->pdev->dev);
- _dpu_plane_set_qos_ctrl(plane, &pstate->pipe, enable);
- if (pstate->r_pipe.sspp)
- _dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, enable);
+ for (i = 0; i < PIPES_PER_STAGE; i++) {
+ if (pstate->pipe[i].sspp)
+ _dpu_plane_set_qos_ctrl(plane, &pstate->pipe[i], enable);
+ }
pm_runtime_put_sync(&dpu_kms->pdev->dev);
}
#endif
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index acd5725175cdd..052fd046e8463 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -18,10 +18,8 @@
* struct dpu_plane_state: Define dpu extension of drm plane state object
* @base: base drm plane state object
* @aspace: pointer to address space for input/output buffers
- * @pipe: software pipe description
- * @r_pipe: software pipe description of the second pipe
- * @pipe_cfg: software pipe configuration
- * @r_pipe_cfg: software pipe configuration for the second pipe
+ * @pipe: software pipe description array
+ * @pipe_cfg: software pipe configuration array
* @stage: assigned by crtc blender
* @needs_qos_remap: qos remap settings need to be updated
* @multirect_index: index of the rectangle of SSPP
@@ -35,10 +33,8 @@
struct dpu_plane_state {
struct drm_plane_state base;
struct msm_gem_address_space *aspace;
- struct dpu_sw_pipe pipe;
- struct dpu_sw_pipe r_pipe;
- struct dpu_sw_pipe_cfg pipe_cfg;
- struct dpu_sw_pipe_cfg r_pipe_cfg;
+ struct dpu_sw_pipe pipe[PIPES_PER_STAGE];
+ struct dpu_sw_pipe_cfg pipe_cfg[PIPES_PER_STAGE];
enum dpu_stage stage;
bool needs_qos_remap;
bool pending;
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 09/15] drm/msm/dpu: split PIPES_PER_STAGE definition per plane and mixer
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (7 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 08/15] drm/msm/dpu: handle pipes as array Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 22:28 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 10/15] drm/msm/dpu: Add pipe as trace argument Jun Nie
` (6 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Split PIPES_PER_STAGE definition per plane and mixer pair. Because
there are more than 2 pipes in quad pipe case, while 2 pipes at most
per mixer pair. A stage struct serve a mixer pair, so pipes per
plane is split out as PIPES_PER_PLANE.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 4 ++--
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 1 +
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 +++++++++---------
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 4 ++--
4 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index a0284b1425b1f..72ed8749cd716 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -463,7 +463,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
bg_alpha_enable = true;
- for (i = 0; i < PIPES_PER_STAGE; i++) {
+ for (i = 0; i < PIPES_PER_PLANE; i++) {
if (!pstate->pipe[i].sspp)
continue;
set_bit(pstate->pipe[i].sspp->idx, fetch_active);
@@ -1436,7 +1436,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
state->crtc_x, state->crtc_y, state->crtc_w,
state->crtc_h);
- for (i = 0; i < PIPES_PER_STAGE; i++) {
+ for (i = 0; i < PIPES_PER_PLANE; i++) {
if (pstate->pipe[i].sspp) {
seq_printf(s, "\tsspp[%d]:%s\n",
i, pstate->pipe[i].sspp->cap->name);
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 f8806a4d317be..68867c2f40d4b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -32,6 +32,7 @@
#define DPU_MAX_PLANES 4
#endif
+#define PIPES_PER_PLANE 2
#define PIPES_PER_STAGE 2
#ifndef DPU_MAX_DE_CURVES
#define DPU_MAX_DE_CURVES 3
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index aaf934ec96be5..46c6b6126fe5c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -633,7 +633,7 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
return;
/* update sspp */
- for (i = 0; i < PIPES_PER_STAGE; i++) {
+ for (i = 0; i < PIPES_PER_PLANE; i++) {
if (pstate->pipe[i].sspp)
_dpu_plane_color_fill_pipe(pstate, &pstate->pipe[i],
&pstate->pipe_cfg[i].dst_rect,
@@ -1076,7 +1076,7 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
* resources are freed by dpu_crtc_assign_plane_resources(),
* but clean them here.
*/
- for (i = 0; i < PIPES_PER_STAGE; i++)
+ for (i = 0; i < PIPES_PER_PLANE; i++)
pstate->pipe[i].sspp = NULL;
return 0;
@@ -1128,7 +1128,7 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
pipe_cfg = &pstate->pipe_cfg[0];
r_pipe_cfg = &pstate->pipe_cfg[1];
- for (i = 0; i < PIPES_PER_STAGE; i++)
+ for (i = 0; i < PIPES_PER_PLANE; i++)
pstate->pipe[i].sspp = NULL;
if (!plane_state->fb)
@@ -1240,7 +1240,7 @@ void dpu_plane_flush(struct drm_plane *plane)
/* force 100% alpha */
_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
else {
- for (i = 0; i < PIPES_PER_STAGE; i++)
+ for (i = 0; i < PIPES_PER_PLANE; i++)
dpu_plane_flush_csc(pdpu, &pstate->pipe[i]);
}
@@ -1370,7 +1370,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane,
&fmt->pixel_format, MSM_FORMAT_IS_UBWC(fmt));
/* move the assignment here, to ease handling to another pairs later */
- for (i = 0; i < PIPES_PER_STAGE; i++) {
+ for (i = 0; i < PIPES_PER_PLANE; i++) {
if (!pstate->pipe[i].sspp)
continue;
dpu_plane_sspp_update_pipe(plane, &pstate->pipe[i],
@@ -1384,7 +1384,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane,
pstate->plane_fetch_bw = 0;
pstate->plane_clk = 0;
- for (i = 0; i < PIPES_PER_STAGE; i++) {
+ for (i = 0; i < PIPES_PER_PLANE; i++) {
if (!pstate->pipe[i].sspp)
continue;
pstate->plane_fetch_bw += _dpu_plane_calc_bw(pdpu->catalog, fmt,
@@ -1403,7 +1403,7 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
struct dpu_sw_pipe *pipe;
int i;
- for (i = 0; i < PIPES_PER_STAGE; i += 1) {
+ for (i = 0; i < PIPES_PER_PLANE; i += 1) {
pipe = &pstate->pipe[i];
if (!pipe->sspp)
continue;
@@ -1518,7 +1518,7 @@ static void dpu_plane_atomic_print_state(struct drm_printer *p,
drm_printf(p, "\tstage=%d\n", pstate->stage);
- for (i = 0; i < PIPES_PER_STAGE; i++) {
+ for (i = 0; i < PIPES_PER_PLANE; i++) {
pipe = &pstate->pipe[i];
if (!pipe->sspp)
continue;
@@ -1575,7 +1575,7 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
return;
pm_runtime_get_sync(&dpu_kms->pdev->dev);
- for (i = 0; i < PIPES_PER_STAGE; i++) {
+ for (i = 0; i < PIPES_PER_PLANE; i++) {
if (pstate->pipe[i].sspp)
_dpu_plane_set_qos_ctrl(plane, &pstate->pipe[i], enable);
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 052fd046e8463..18ff5ec2603ed 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -33,8 +33,8 @@
struct dpu_plane_state {
struct drm_plane_state base;
struct msm_gem_address_space *aspace;
- struct dpu_sw_pipe pipe[PIPES_PER_STAGE];
- struct dpu_sw_pipe_cfg pipe_cfg[PIPES_PER_STAGE];
+ struct dpu_sw_pipe pipe[PIPES_PER_PLANE];
+ struct dpu_sw_pipe_cfg pipe_cfg[PIPES_PER_PLANE];
enum dpu_stage stage;
bool needs_qos_remap;
bool pending;
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 10/15] drm/msm/dpu: Add pipe as trace argument
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (8 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 09/15] drm/msm/dpu: split PIPES_PER_STAGE definition per plane and mixer Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 22:29 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 11/15] drm/msm/dpu: blend pipes per mixer pairs config Jun Nie
` (5 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Add pipe as trace argument to ease converting pipe into
pipe array later.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 72ed8749cd716..6841d0504d450 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -411,7 +411,7 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
state, to_dpu_plane_state(state), stage_idx,
- format->pixel_format,
+ format->pixel_format, pipe,
modifier);
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d multirect_idx %d\n",
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 5307cbc2007c5..cb24ad2a6d8d3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -651,9 +651,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
struct drm_plane_state *state, struct dpu_plane_state *pstate,
uint32_t stage_idx, uint32_t pixel_format,
- uint64_t modifier),
+ struct dpu_sw_pipe *pipe, uint64_t modifier),
TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
- pixel_format, modifier),
+ pixel_format, pipe, modifier),
TP_STRUCT__entry(
__field( uint32_t, crtc_id )
__field( uint32_t, plane_id )
@@ -676,9 +676,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
__entry->dst_rect = drm_plane_state_dest(state);
__entry->stage_idx = stage_idx;
__entry->stage = pstate->stage;
- __entry->sspp = pstate->pipe.sspp->idx;
- __entry->multirect_idx = pstate->pipe.multirect_index;
- __entry->multirect_mode = pstate->pipe.multirect_mode;
+ __entry->sspp = pipe->sspp->idx;
+ __entry->multirect_idx = pipe->multirect_index;
+ __entry->multirect_mode = pipe->multirect_mode;
__entry->pixel_format = pixel_format;
__entry->modifier = modifier;
),
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 11/15] drm/msm/dpu: blend pipes per mixer pairs config
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (9 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 10/15] drm/msm/dpu: Add pipe as trace argument Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 22:40 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 12/15] drm/msm/dpu: support plane splitting in quad-pipe case Jun Nie
` (4 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Blend pipes by set of mixer pair config. The first 2 pipes are for left
half screen with the first set of mixer pair config. And the later 2 pipes
are for right in quad pipe case. A stage structure serves a mixer pair,
that is coupled with 2 pipes. So the stage array number is defined as
STAGES_PER_PLANE.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 38 ++++++++++++++++++-----------
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 1 +
2 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 6841d0504d450..6ef7e6ed00238 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -442,7 +442,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
const struct msm_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
- uint32_t lm_idx, i;
+ uint32_t lm_idx, stage, i, pipe_idx;
bool bg_alpha_enable = false;
DECLARE_BITMAP(fetch_active, SSPP_MAX);
@@ -463,15 +463,20 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
bg_alpha_enable = true;
- for (i = 0; i < PIPES_PER_PLANE; i++) {
- if (!pstate->pipe[i].sspp)
- continue;
- set_bit(pstate->pipe[i].sspp->idx, fetch_active);
- _dpu_crtc_blend_setup_pipe(crtc, plane,
- mixer, cstate->num_mixers,
- pstate->stage,
- format, fb ? fb->modifier : 0,
- &pstate->pipe[i], i, stage_cfg);
+ /* loop pipe per mixer pair that's served by a stage structure */
+ for (stage = 0; stage < PIPES_PER_PLANE / STAGES_PER_PLANE; stage++) {
+ for (i = 0; i < PIPES_PER_STAGE; i++) {
+ pipe_idx = i + stage * PIPES_PER_STAGE;
+ if (!pstate->pipe[pipe_idx].sspp)
+ continue;
+ set_bit(pstate->pipe[pipe_idx].sspp->idx, fetch_active);
+ _dpu_crtc_blend_setup_pipe(crtc, plane,
+ mixer, cstate->num_mixers,
+ pstate->stage,
+ format, fb ? fb->modifier : 0,
+ &pstate->pipe[pipe_idx], i,
+ &stage_cfg[stage]);
+ }
}
/* blend config update */
@@ -503,7 +508,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
struct dpu_crtc_mixer *mixer = cstate->mixers;
struct dpu_hw_ctl *ctl;
struct dpu_hw_mixer *lm;
- struct dpu_hw_stage_cfg stage_cfg;
+ struct dpu_hw_stage_cfg stage_cfg[STAGES_PER_PLANE];
int i;
DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
@@ -516,9 +521,9 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
}
/* initialize stage cfg */
- memset(&stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
+ memset(&stage_cfg, 0, sizeof(stage_cfg));
- _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg);
+ _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg[0]);
for (i = 0; i < cstate->num_mixers; i++) {
ctl = mixer[i].lm_ctl;
@@ -535,8 +540,13 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
mixer[i].mixer_op_mode,
ctl->idx - CTL_0);
+ /*
+ * call dpu_hw_ctl_setup_blendstage() to blend layers per stage cfg.
+ * There is 4 mixers at most. The first 2 are for the left half, and
+ * the later 2 are for the right half.
+ */
ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
- &stage_cfg);
+ &stage_cfg[i / 2]);
}
}
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 68867c2f40d4b..27ef0771da5d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -32,6 +32,7 @@
#define DPU_MAX_PLANES 4
#endif
+#define STAGES_PER_PLANE 2
#define PIPES_PER_PLANE 2
#define PIPES_PER_STAGE 2
#ifndef DPU_MAX_DE_CURVES
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 12/15] drm/msm/dpu: support plane splitting in quad-pipe case
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (10 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 11/15] drm/msm/dpu: blend pipes per mixer pairs config Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 23:16 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 13/15] drm/msm/dpu: Support quad-pipe in SSPP checking Jun Nie
` (3 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
The content of every half of screen is sent out via one interface in
dual-DSI case. The content for every interface is blended by a LM
pair, thus no content of any pipe shall cross the LM pair. We need
to clip plane into pipes per left and right half screen ROI if topology
is quad pipe.
The clipped rectangle on every half of screen will be split further
by half if its width still exceeds limit.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 7 ++
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 2 +
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 108 +++++++++++++++++++++-------
4 files changed, 97 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 6ef7e6ed00238..bad75af4e50ab 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1363,6 +1363,13 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)
return 0;
}
+unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state)
+{
+ struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
+
+ return cstate->num_mixers;
+}
+
#ifdef CONFIG_DEBUG_FS
static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
{
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 0b148f3ce0d7a..d1bb3f84fe440 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -264,4 +264,10 @@ static inline enum dpu_crtc_client_type dpu_crtc_get_client_type(
void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
+/**
+ * dpu_crtc_get_num_lm - Get mixer number in this CRTC pipeline
+ * state: Pointer to drm crtc state object
+ */
+unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state);
+
#endif /* _DPU_CRTC_H_ */
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 56a0edf2a57c6..39fe338e76691 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -145,11 +145,13 @@ struct dpu_hw_pixel_ext {
* such as decimation, flip etc to program this field
* @dest_rect: destination ROI.
* @rotation: simplified drm rotation hint
+ * @valid: notify that this pipe and config is in use
*/
struct dpu_sw_pipe_cfg {
struct drm_rect src_rect;
struct drm_rect dst_rect;
unsigned int rotation;
+ bool valid;
};
/**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 46c6b6126fe5c..fca6e609898a6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -802,8 +802,14 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
struct dpu_sw_pipe_cfg *pipe_cfg;
struct dpu_sw_pipe_cfg *r_pipe_cfg;
+ struct dpu_sw_pipe *pipe;
+ struct dpu_sw_pipe *r_pipe;
+ struct dpu_sw_pipe_cfg init_pipe_cfg;
struct drm_rect fb_rect = { 0 };
+ const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
uint32_t max_linewidth;
+ u32 num_lm;
+ int stage_id, num_stages;
min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO);
max_scale = MAX_DOWNSCALE_RATIO << 16;
@@ -826,13 +832,10 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
return -EINVAL;
}
- /* move the assignment here, to ease handling to another pairs later */
- pipe_cfg = &pstate->pipe_cfg[0];
- r_pipe_cfg = &pstate->pipe_cfg[1];
- /* state->src is 16.16, src_rect is not */
- drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
+ num_lm = dpu_crtc_get_num_lm(crtc_state);
- pipe_cfg->dst_rect = new_plane_state->dst;
+ /* state->src is 16.16, src_rect is not */
+ drm_rect_fp_to_int(&init_pipe_cfg.src_rect, &new_plane_state->src);
fb_rect.x2 = new_plane_state->fb->width;
fb_rect.y2 = new_plane_state->fb->height;
@@ -857,34 +860,87 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
max_linewidth = pdpu->catalog->caps->max_linewidth;
- drm_rect_rotate(&pipe_cfg->src_rect,
+ drm_rect_rotate(&init_pipe_cfg.src_rect,
new_plane_state->fb->width, new_plane_state->fb->height,
new_plane_state->rotation);
- if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
- _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) {
- if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) {
- DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
- DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
- return -E2BIG;
+ /*
+ * We have 1 mixer pair cfg for 1:1:1 and 2:2:1 topology, 2 mixer pair
+ * configs for left and right half screen in case of 4:4:2 topology.
+ * But we may have 2 rect to split plane with 1 config for 2:2:1.
+ * So need to handle super wide plane splitting, and plane on right half
+ * for quad-pipe case. Check dest rectangle left/right clipping
+ * first, then check super wide rectangle splitting in every half next.
+ */
+ num_stages = (num_lm + 1) / 2;
+ /* iterate mixer configs for this plane, to separate left/right with the id */
+ for (stage_id = 0; stage_id < num_stages; stage_id++) {
+ struct drm_rect mixer_rect = {stage_id * mode->hdisplay / num_stages, 0,
+ (stage_id + 1) * mode->hdisplay / num_stages,
+ mode->vdisplay};
+ int cfg_idx = stage_id * PIPES_PER_STAGE;
+
+ pipe = &pstate->pipe[cfg_idx];
+ r_pipe = &pstate->pipe[cfg_idx + 1];
+ pipe_cfg = &pstate->pipe_cfg[cfg_idx];
+ r_pipe_cfg = &pstate->pipe_cfg[cfg_idx + 1];
+
+ drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
+ pipe_cfg->dst_rect = new_plane_state->dst;
+
+ DPU_DEBUG_PLANE(pdpu, "checking src " DRM_RECT_FMT
+ " vs clip window " DRM_RECT_FMT "\n",
+ DRM_RECT_ARG(&pipe_cfg->src_rect),
+ DRM_RECT_ARG(&mixer_rect));
+
+ /*
+ * If this plane does not fall into mixer rect, check next
+ * mixer rect.
+ */
+ if (!drm_rect_clip_scaled(&pipe_cfg->src_rect,
+ &pipe_cfg->dst_rect,
+ &mixer_rect)) {
+ memset(pipe_cfg, 0, 2 * sizeof(struct dpu_sw_pipe_cfg));
+ memset(pipe, 0, 2 * sizeof(struct dpu_sw_pipe));
+ continue;
}
- *r_pipe_cfg = *pipe_cfg;
- pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1;
- pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1;
- r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2;
- r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
- } else {
- memset(r_pipe_cfg, 0, sizeof(*r_pipe_cfg));
- }
+ pipe_cfg->valid = true;
+ pipe_cfg->dst_rect.x1 -= mixer_rect.x1;
+ pipe_cfg->dst_rect.x2 -= mixer_rect.x1;
+
+ DPU_DEBUG_PLANE(pdpu, "Got clip src:" DRM_RECT_FMT " dst: " DRM_RECT_FMT "\n",
+ DRM_RECT_ARG(&pipe_cfg->src_rect), DRM_RECT_ARG(&pipe_cfg->dst_rect));
+
+ /* Split super wide rect into 2 rect */
+ if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
+ _dpu_plane_calc_clk(mode, pipe_cfg) > max_mdp_clk_rate) {
+
+ if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) {
+ DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
+ DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
+ return -E2BIG;
+ }
+
+ memcpy(r_pipe_cfg, pipe_cfg, sizeof(struct dpu_sw_pipe_cfg));
+ pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1;
+ pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1;
+ r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2;
+ r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
+ r_pipe_cfg->valid = true;
+ DPU_DEBUG_PLANE(pdpu, "Split super wide plane into:"
+ DRM_RECT_FMT " and " DRM_RECT_FMT "\n",
+ DRM_RECT_ARG(&pipe_cfg->src_rect),
+ DRM_RECT_ARG(&r_pipe_cfg->src_rect));
+ } else {
+ memset(r_pipe_cfg, 0, sizeof(struct dpu_sw_pipe_cfg));
+ memset(r_pipe, 0, sizeof(struct dpu_sw_pipe));
+ }
- drm_rect_rotate_inv(&pipe_cfg->src_rect,
- new_plane_state->fb->width, new_plane_state->fb->height,
- new_plane_state->rotation);
- if (drm_rect_width(&r_pipe_cfg->src_rect) != 0)
- drm_rect_rotate_inv(&r_pipe_cfg->src_rect,
+ drm_rect_rotate_inv(&pipe_cfg->src_rect,
new_plane_state->fb->width, new_plane_state->fb->height,
new_plane_state->rotation);
+ }
pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 13/15] drm/msm/dpu: Support quad-pipe in SSPP checking
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (11 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 12/15] drm/msm/dpu: support plane splitting in quad-pipe case Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 23:23 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 14/15] drm/msm/dpu: support SSPP assignment for quad-pipe case Jun Nie
` (2 subsequent siblings)
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Move requreiment check to routine of every pipe check. There will be
multiple SSPPs for quad-pipe case in future. Only check valid pipe
as some pipes are for multi-rect or right half of screen that may
not be used.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 86 +++++++++++++++----------------
1 file changed, 42 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index fca6e609898a6..1cd98892898a4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -730,12 +730,40 @@ static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
struct dpu_sw_pipe *pipe,
struct dpu_sw_pipe_cfg *pipe_cfg,
- const struct msm_format *fmt,
- const struct drm_display_mode *mode)
+ const struct drm_display_mode *mode,
+ struct drm_plane_state *new_plane_state)
{
uint32_t min_src_size;
struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
int ret;
+ const struct msm_format *fmt;
+ uint32_t supported_rotations;
+ const struct dpu_sspp_cfg *pipe_hw_caps;
+ const struct dpu_sspp_sub_blks *sblk;
+
+ pipe_hw_caps = pipe->sspp->cap;
+ sblk = pipe->sspp->cap->sblk;
+
+ /*
+ * We already have verified scaling against platform limitations.
+ * Now check if the SSPP supports scaling at all.
+ */
+ if (!sblk->scaler_blk.len &&
+ ((drm_rect_width(&new_plane_state->src) >> 16 !=
+ drm_rect_width(&new_plane_state->dst)) ||
+ (drm_rect_height(&new_plane_state->src) >> 16 !=
+ drm_rect_height(&new_plane_state->dst))))
+ return -ERANGE;
+
+ fmt = msm_framebuffer_format(new_plane_state->fb);
+
+ supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
+
+ if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
+ supported_rotations |= DRM_MODE_ROTATE_90;
+
+ pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation,
+ supported_rotations);
min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1;
@@ -981,49 +1009,19 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
drm_atomic_get_new_plane_state(state, plane);
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
- const struct msm_format *fmt;
- struct dpu_sw_pipe *pipe = &pstate->pipe[0];
- struct dpu_sw_pipe *r_pipe = &pstate->pipe[1];
- struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[0];
- struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[1];
- uint32_t supported_rotations;
- const struct dpu_sspp_cfg *pipe_hw_caps;
- const struct dpu_sspp_sub_blks *sblk;
- int ret = 0;
-
- pipe_hw_caps = pipe->sspp->cap;
- sblk = pipe->sspp->cap->sblk;
-
- /*
- * We already have verified scaling against platform limitations.
- * Now check if the SSPP supports scaling at all.
- */
- if (!sblk->scaler_blk.len &&
- ((drm_rect_width(&new_plane_state->src) >> 16 !=
- drm_rect_width(&new_plane_state->dst)) ||
- (drm_rect_height(&new_plane_state->src) >> 16 !=
- drm_rect_height(&new_plane_state->dst))))
- return -ERANGE;
-
- fmt = msm_framebuffer_format(new_plane_state->fb);
-
- supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
-
- if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
- supported_rotations |= DRM_MODE_ROTATE_90;
-
- pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation,
- supported_rotations);
- r_pipe_cfg->rotation = pipe_cfg->rotation;
-
- ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt,
- &crtc_state->adjusted_mode);
- if (ret)
- return ret;
+ struct dpu_sw_pipe *pipe;
+ struct dpu_sw_pipe_cfg *pipe_cfg;
+ int ret = 0, i;
- if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) {
- ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt,
- &crtc_state->adjusted_mode);
+ for (i = 0; i < PIPES_PER_PLANE; i++) {
+ pipe = &pstate->pipe[i];
+ pipe_cfg = &pstate->pipe_cfg[i];
+ if (!pipe_cfg->valid || !pipe->sspp)
+ continue;
+ DPU_DEBUG_PLANE(pdpu, "pipe %d is in use, validate it\n", i);
+ ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg,
+ &crtc_state->adjusted_mode,
+ new_plane_state);
if (ret)
return ret;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 14/15] drm/msm/dpu: support SSPP assignment for quad-pipe case
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (12 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 13/15] drm/msm/dpu: Support quad-pipe in SSPP checking Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 23:30 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case Jun Nie
2024-12-19 7:53 ` [PATCH v3 00/15] drm/msm/dpu: Support quad pipe with dual-DSI Jun Nie
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Support SSPP assignment for quad-pipe case with unified method.
The first 2 pipes can share a set of mixer config and enable
multi-rect mode if condition is met. It is also the case for
the later 2 pipes.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 67 ++++++++++++++++++-------------
1 file changed, 38 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 1cd98892898a4..57ccb73c45683 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1163,12 +1163,9 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
struct dpu_rm_sspp_requirements reqs;
struct dpu_plane_state *pstate;
- struct dpu_sw_pipe *pipe;
- struct dpu_sw_pipe *r_pipe;
- struct dpu_sw_pipe_cfg *pipe_cfg;
- struct dpu_sw_pipe_cfg *r_pipe_cfg;
+ struct dpu_plane *pdpu = to_dpu_plane(plane);
const struct msm_format *fmt;
- int i;
+ int i, num_lm, stage_id, num_stages;
if (plane_state->crtc)
crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -1176,12 +1173,6 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
pstate = to_dpu_plane_state(plane_state);
- /* TODO: loop below code for another pair later */
- pipe = &pstate->pipe[0];
- r_pipe = &pstate->pipe[1];
- pipe_cfg = &pstate->pipe_cfg[0];
- r_pipe_cfg = &pstate->pipe_cfg[1];
-
for (i = 0; i < PIPES_PER_PLANE; i++)
pstate->pipe[i].sspp = NULL;
@@ -1195,24 +1186,42 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
reqs.rot90 = drm_rotation_90_or_270(plane_state->rotation);
- pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
- if (!pipe->sspp)
- return -ENODEV;
-
- if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
- pipe->sspp,
- msm_framebuffer_format(plane_state->fb),
- dpu_kms->catalog->caps->max_linewidth)) {
- /* multirect is not possible, use two SSPP blocks */
- r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
- if (!r_pipe->sspp)
- return -ENODEV;
-
- pipe->multirect_index = DPU_SSPP_RECT_SOLO;
- pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-
- r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
- r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+ num_lm = dpu_crtc_get_num_lm(crtc_state);
+ num_stages = (num_lm + 1) / 2;
+ for (stage_id = 0; stage_id < num_stages; stage_id++) {
+ for (i = stage_id * PIPES_PER_STAGE; i < (stage_id + 1) * PIPES_PER_STAGE; i++) {
+ struct dpu_sw_pipe *pipe = &pstate->pipe[i];
+ struct dpu_sw_pipe *r_pipe = &pstate->pipe[i + 1];
+ struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[i];
+ struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[i + 1];
+
+ if (!pipe_cfg->valid)
+ break;
+
+ pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
+ if (!pipe->sspp)
+ return -ENODEV;
+
+ /*
+ * If current pipe is the first pipe in pipe pair, check
+ * multi-rect opportunity for the 2nd pipe in the pair.
+ * SSPP multi-rect mode cross mixer pairs is not supported.
+ */
+ if ((i % PIPES_PER_STAGE == 0) &&
+ r_pipe_cfg->valid &&
+ !dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
+ pipe->sspp,
+ msm_framebuffer_format(plane_state->fb),
+ dpu_kms->catalog->caps->max_linewidth)) {
+ i++;
+ } else {
+ /* multirect is not possible, use two SSPP blocks */
+ pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+ pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+ DPU_DEBUG_PLANE(pdpu, "allocating sspp_%d for pipe %d.\n",
+ pipe->sspp->idx - SSPP_NONE, i);
+ }
+ }
}
return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (13 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 14/15] drm/msm/dpu: support SSPP assignment for quad-pipe case Jun Nie
@ 2024-12-19 7:49 ` Jun Nie
2024-12-19 23:46 ` Dmitry Baryshkov
2024-12-19 7:53 ` [PATCH v3 00/15] drm/msm/dpu: Support quad pipe with dual-DSI Jun Nie
15 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:49 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel, Jun Nie
Request 4 mixers and 4 DSC for the case that both dual-DSI and DSC are
enabled. We prefer to use 4 pipes for dual DSI case for it is power optimal
for DSC.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 28 ++++++++++++++++++------
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 ++-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +-
7 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index bad75af4e50ab..3c51c199f3e05 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -200,7 +200,7 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc,
struct dpu_crtc_state *crtc_state)
{
struct dpu_crtc_mixer *m;
- u32 crcs[CRTC_DUAL_MIXERS];
+ u32 crcs[CRTC_QUAD_MIXERS];
int rc = 0;
int i;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index d1bb3f84fe440..ce41fb364f3db 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -210,7 +210,7 @@ struct dpu_crtc_state {
bool bw_control;
bool bw_split_vote;
- struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
+ struct drm_rect lm_bounds[CRTC_QUAD_MIXERS];
uint64_t input_fence_timeout_ns;
@@ -218,10 +218,10 @@ struct dpu_crtc_state {
/* HW Resources reserved for the crtc */
u32 num_mixers;
- struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
+ struct dpu_crtc_mixer mixers[CRTC_QUAD_MIXERS];
u32 num_ctls;
- struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
+ struct dpu_hw_ctl *hw_ctls[CRTC_QUAD_MIXERS];
enum dpu_crtc_crc_source crc_source;
int crc_frame_skip_count;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 96d06db3e4be5..6e54ddeaffacd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -54,7 +54,7 @@
#define MAX_PHYS_ENCODERS_PER_VIRTUAL \
(MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
-#define MAX_CHANNELS_PER_ENC 2
+#define MAX_CHANNELS_PER_ENC 4
#define IDLE_SHORT_TIMEOUT 1
@@ -664,15 +664,19 @@ static struct msm_display_topology dpu_encoder_get_topology(
/* Datapath topology selection
*
- * Dual display
+ * Dual display without DSC
* 2 LM, 2 INTF ( Split display using 2 interfaces)
*
+ * Dual display with DSC
+ * 4 LM, 2 INTF ( Split display using 2 interfaces)
+ *
* Single display
* 1 LM, 1 INTF
* 2 LM, 1 INTF (stream merge to support high resolution interfaces)
*
* Add dspps to the reservation requirements if ctm is requested
*/
+
if (intf_count == 2)
topology.num_lm = 2;
else if (!dpu_kms->catalog->caps->has_3d_merge)
@@ -691,10 +695,20 @@ static struct msm_display_topology dpu_encoder_get_topology(
* 2 DSC encoders, 2 layer mixers and 1 interface
* this is power optimal and can drive up to (including) 4k
* screens
+ * But for dual display case, we prefer 4 layer mixers. Because
+ * the resolution is always high in the case and 4 DSCs are more
+ * power optimal.
*/
- topology.num_dsc = 2;
- topology.num_lm = 2;
- topology.num_intf = 1;
+
+ if (intf_count == 2) {
+ topology.num_dsc = 4;
+ topology.num_lm = 4;
+ topology.num_intf = 2;
+ } else {
+ topology.num_dsc = 2;
+ topology.num_lm = 2;
+ topology.num_intf = 1;
+ }
}
return topology;
@@ -2195,8 +2209,8 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
struct dpu_hw_mixer_cfg mixer;
int i, num_lm;
struct dpu_global_state *global_state;
- struct dpu_hw_blk *hw_lm[2];
- struct dpu_hw_mixer *hw_mixer[2];
+ struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
+ struct dpu_hw_mixer *hw_mixer[MAX_CHANNELS_PER_ENC];
struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
memset(&mixer, 0, sizeof(mixer));
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 63f09857025c2..d378a990cc0fb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -302,7 +302,8 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
/* Use merge_3d unless DSC MERGE topology is used */
if (phys_enc->split_role == ENC_ROLE_SOLO &&
- dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
+ (dpu_cstate->num_mixers == CRTC_DUAL_MIXERS ||
+ dpu_cstate->num_mixers == CRTC_QUAD_MIXERS) &&
!dpu_encoder_use_dsc_merge(phys_enc->parent))
return BLEND_3D_H_ROW_INT;
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 3ab79092a7f25..d9cc84b081b1f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -25,6 +25,7 @@
#define DPU_MAX_IMG_HEIGHT 0x3fff
#define CRTC_DUAL_MIXERS 2
+#define CRTC_QUAD_MIXERS 4
#define MAX_XIN_COUNT 16
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 27ef0771da5d2..1fe21087a141a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -33,8 +33,8 @@
#endif
#define STAGES_PER_PLANE 2
-#define PIPES_PER_PLANE 2
#define PIPES_PER_STAGE 2
+#define PIPES_PER_PLANE (STAGES_PER_PLANE * STAGES_PER_PLANE)
#ifndef DPU_MAX_DE_CURVES
#define DPU_MAX_DE_CURVES 3
#endif
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 57ccb73c45683..b5c1ad2a75594 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1474,7 +1474,7 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
trace_dpu_plane_disable(DRMID(plane), false,
pstate->pipe[i].multirect_mode);
- if (pipe->sspp && i == 1) {
+ if (pipe->sspp && pipe->multirect_index == DPU_SSPP_RECT_1) {
pipe->multirect_index = DPU_SSPP_RECT_SOLO;
pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
--
2.34.1
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v3 00/15] drm/msm/dpu: Support quad pipe with dual-DSI
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
` (14 preceding siblings ...)
2024-12-19 7:49 ` [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case Jun Nie
@ 2024-12-19 7:53 ` Jun Nie
15 siblings, 0 replies; 43+ messages in thread
From: Jun Nie @ 2024-12-19 7:53 UTC (permalink / raw)
To: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, Linux Kernel Mailing List
Jun Nie <jun.nie@linaro.org> 于2024年12月19日周四 15:49写道:
>
> To: Rob Clark <robdclark@gmail.com>
> To: Abhinav Kumar <quic_abhinavk@quicinc.com>
> To: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> To: Sean Paul <sean@poorly.run>
> To: Marijn Suijten <marijn.suijten@somainline.org>
> To: David Airlie <airlied@gmail.com>
> To: Simona Vetter <simona@ffwll.ch>
> Cc: linux-arm-msm@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: freedreno@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
> drm/msm/dpu: Support quad pipe with dual-DSI
>
> 2 or more SSPPs and dual-DSI interface are need for super wide DSI panel.
> And 4 DSC are preferred for power optimal in this case. This patch set
> extend number of pipes to 4 and revise related mixer blending logic
> to support quad pipe. All these changes depends on the virtual plane
> feature to split a super wide drm plane horizontally into 2 or more sub
> clip. Thus DMA of multiple SSPPs can share the effort of fetching the
> whole drm plane.
>
> The first pipe pair co-work with the first mixer pair to cover the left
> half of screen and 2nd pair of pipes and mixers are for the right half
> of screen. If a plane is only for the right half of screen, only one
> or two of pipes in the 2nd pipe pair are valid, and no SSPP or mixer is
> assinged for invalid pipe.
>
> For those panel that does not require quad-pipe, only 1 or 2 pipes in
> the 1st pipe pair will be used. There is no concept of right half of
> screen.
>
> For legacy non virtual plane mode, the first 1 or 2 pipes are used for
> the single SSPP and its multi-rect mode.
>
> This patch set depends on virtual plane patch set v7:
> https://lore.kernel.org/all/20241130-dpu-virtual-wide-v7-0-991053fcf63c@linaro.org/
>
> Changes in v3:
> - Split change in trace into a separate patch.
> - Rebase to latest msm-next branch.
> - Reorder patch sequence to make sure valid flag is set in earlier patch
> - Rectify rewrite patch to move logic change into other patch
> - Polish commit messages and code comments.
> - Link to v2: https://lore.kernel.org/dri-devel/20241009-sm8650-v6-11-hmd-pocf-mdss-quad-upstream-21-v2-0-76d4f5d413bf@linaro.org/
>
> Changes in v2:
> - Revise the patch sequence with changing to 2 pipes topology first. Then
> prepare for quad-pipe setup, then enable quad-pipe at last.
> - Split DSI patches into other patch set.
> - Link to v1: https://lore.kernel.org/all/20240829-sm8650-v6-11-hmd-pocf-mdss-quad-upstream-8-v1-0-bdb05b4b5a2e@linaro.org/
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> Jun Nie (15):
> drm/msm/dpu: Do not fix number of DSC
> drm/msm/dpu: configure DSC per number in use
> drm/msm/dpu: polish log for resource allocation
> drm/msm/dpu: decide right side per last bit
> drm/msm/dpu: fix mixer number counter on allocation
> drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation
> drm/msm/dpu: bind correct pingpong for quad pipe
> drm/msm/dpu: handle pipes as array
> drm/msm/dpu: split PIPES_PER_STAGE definition per plane and mixer
> drm/msm/dpu: Add pipe as trace argument
> drm/msm/dpu: blend pipes per mixer pairs config
> drm/msm/dpu: support plane splitting in quad-pipe case
> drm/msm/dpu: Support quad-pipe in SSPP checking
> drm/msm/dpu: support SSPP assignment for quad-pipe case
> drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case
>
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 77 +++--
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 12 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 74 +++--
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 2 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 12 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 403 ++++++++++++++---------
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 12 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 219 ++++++------
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 32 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 +-
> 13 files changed, 511 insertions(+), 348 deletions(-)
> ---
> base-commit: a9b9ea7b45d661fff0f3fd2937703a536f528cd2
> change-id: 20241219-sm8650-v6-13-hmd-deckard-mdss-quad-upstream-32-2bdbc22f5131
>
> Best regards,
> --
> Jun Nie <jun.nie@linaro.org>
>
Sorry to have no title for cover due to miss handling the b4 tool . So
reply to this thread with the title in it.
- Jun
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 02/15] drm/msm/dpu: configure DSC per number in use
2024-12-19 7:49 ` [PATCH v3 02/15] drm/msm/dpu: configure DSC per number in use Jun Nie
@ 2024-12-19 22:06 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 22:06 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:20PM +0800, Jun Nie wrote:
> Currently if DSC support is requested, the driver only supports using
> 2 DSC blocks. We need 4 DSC in quad-pipe topology in future. So let's
> only configure DSC engines in use, instead of the maximum number of
> DSC engines.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 650df585138cd..cc23f364dd080 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -2028,6 +2028,7 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
> struct drm_dsc_config *dsc)
> {
> /* coding only for 2LM, 2enc, 1 dsc config */
Is the comment still relevant?
> + int num_dsc = dpu_enc->num_dscs;
> 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];
> @@ -2039,7 +2040,7 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
> u32 initial_lines;
> int i;
>
> - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
> + for (i = 0; i < num_dsc; i++) {
> hw_pp[i] = dpu_enc->hw_pp[i];
> hw_dsc[i] = dpu_enc->hw_dsc[i];
>
> @@ -2068,7 +2069,7 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
> enc_ip_w = intf_ip_w / 2;
> initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
>
> - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
> + for (i = 0; i < num_dsc; i++)
> dpu_encoder_dsc_pipe_cfg(ctl, hw_dsc[i], hw_pp[i],
> dsc, dsc_common_mode, initial_lines);
> }
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 03/15] drm/msm/dpu: polish log for resource allocation
2024-12-19 7:49 ` [PATCH v3 03/15] drm/msm/dpu: polish log for resource allocation Jun Nie
@ 2024-12-19 22:07 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 22:07 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:21PM +0800, Jun Nie wrote:
> Add resource type info on allocation failure.
Add where? Also describe why, not what.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 23 +++++++++++++++++++----
> 1 file changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index 6dc3fa79e6425..cde3c5616f9bc 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -814,6 +814,21 @@ void dpu_rm_release_all_sspp(struct dpu_global_state *global_state,
> ARRAY_SIZE(global_state->sspp_to_crtc_id), crtc_id);
> }
>
> +static char *dpu_hw_blk_type_name[] = {
> + [DPU_HW_BLK_TOP] = "TOP",
> + [DPU_HW_BLK_SSPP] = "SSPP",
> + [DPU_HW_BLK_LM] = "LM",
> + [DPU_HW_BLK_CTL] = "CTL",
> + [DPU_HW_BLK_PINGPONG] = "pingpong",
> + [DPU_HW_BLK_INTF] = "INTF",
> + [DPU_HW_BLK_WB] = "WB",
> + [DPU_HW_BLK_DSPP] = "DSPP",
> + [DPU_HW_BLK_MERGE_3D] = "merge_3d",
> + [DPU_HW_BLK_DSC] = "DSC",
> + [DPU_HW_BLK_CDM] = "CDM",
> + [DPU_HW_BLK_MAX] = "none",
unknown or ???, not none
Other than that LGTM.
> +};
> +
> /**
> * dpu_rm_get_assigned_resources - Get hw resources of the given type that are
> * assigned to this encoder
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 01/15] drm/msm/dpu: Do not fix number of DSC
2024-12-19 7:49 ` [PATCH v3 01/15] drm/msm/dpu: Do not fix number of DSC Jun Nie
@ 2024-12-19 22:08 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 22:08 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:19PM +0800, Jun Nie wrote:
> If DSC is enabled, the only case is with 2 DSC engines so far. More
> usage case will be added,
Can't parse this, excuse me. The patch LGTM.
> such as 4 DSC in 4:4:2 topoplogy.
> So get real number of DSCs to decide whether DSC merge is needed.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 04/15] drm/msm/dpu: decide right side per last bit
2024-12-19 7:49 ` [PATCH v3 04/15] drm/msm/dpu: decide right side per last bit Jun Nie
@ 2024-12-19 22:09 ` Dmitry Baryshkov
2025-01-08 23:41 ` Jessica Zhang
0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 22:09 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:22PM +0800, Jun Nie wrote:
> decide right side of a pair per last bit, in case of multiple
> mixer pairs.
Proper English sentences, please. Also describe why, not what.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 7191b1a6d41b3..41c9d3e3e3c7c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -369,11 +369,10 @@ static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer,
> static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
> {
> struct dpu_crtc_state *crtc_state;
> - int lm_idx, lm_horiz_position;
> + int lm_idx;
>
> crtc_state = to_dpu_crtc_state(crtc->state);
>
> - lm_horiz_position = 0;
> for (lm_idx = 0; lm_idx < crtc_state->num_mixers; lm_idx++) {
> const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
> struct dpu_hw_mixer *hw_lm = crtc_state->mixers[lm_idx].hw_lm;
> @@ -384,7 +383,7 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>
> cfg.out_width = drm_rect_width(lm_roi);
> cfg.out_height = drm_rect_height(lm_roi);
> - cfg.right_mixer = lm_horiz_position++;
> + cfg.right_mixer = lm_idx & 0x1;
> cfg.flags = 0;
> hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
> }
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation
2024-12-19 7:49 ` [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation Jun Nie
@ 2024-12-19 22:14 ` Dmitry Baryshkov
2025-01-09 1:29 ` Jessica Zhang
1 sibling, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 22:14 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:23PM +0800, Jun Nie wrote:
> Add the case to reserve multiple pairs mixers for high resolution.
You are not adding anything.
> Current code only supports one pair of mixer usage case. To support
> quad-pipe usage case, two pairs of mixers are needed.
>
> Current code resets number of mixer on failure of pair's peer test and
> retry on another pair. If two pairs are needed, the failure on the test
> of 2nd pair results clearing to the 1st pair. This patch only clear the
> bit for the 2nd pair allocation before retry on another pair.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index cde3c5616f9bc..a8b01b78c02c7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -316,7 +316,11 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
> if (!rm->mixer_blks[i])
> continue;
>
> - lm_count = 0;
> + /*
> + * Clear the last bit to drop the previous primary mixer if
> + * fail to find its peer.
if the driver failed
> + */
> + lm_count &= 0xfe;
> lm_idx[lm_count] = i;
>
> if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 08/15] drm/msm/dpu: handle pipes as array
2024-12-19 7:49 ` [PATCH v3 08/15] drm/msm/dpu: handle pipes as array Jun Nie
@ 2024-12-19 22:26 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 22:26 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:26PM +0800, Jun Nie wrote:
> Store pipes in array with removing dedicated r_pipe. There are
> 2 pipes in a drm plane at most currently. While 4 pipes are
, while
> needed for new usage case.
What is "usage case"? Which use case is a new one?
> This change generalize the handling
> to pipe pair and ease handling to another pipe pair later.
See Documentation/process/submitting-patches.rst, look for "This patch"
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 35 +++---
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 170 +++++++++++++++++-------------
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 12 +--
> 3 files changed, 113 insertions(+), 104 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 41c9d3e3e3c7c..a0284b1425b1f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -442,7 +442,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> const struct msm_format *format;
> struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>
> - uint32_t lm_idx;
> + uint32_t lm_idx, i;
> bool bg_alpha_enable = false;
> DECLARE_BITMAP(fetch_active, SSPP_MAX);
>
> @@ -463,20 +463,15 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
> bg_alpha_enable = true;
>
> - set_bit(pstate->pipe.sspp->idx, fetch_active);
> - _dpu_crtc_blend_setup_pipe(crtc, plane,
> - mixer, cstate->num_mixers,
> - pstate->stage,
> - format, fb ? fb->modifier : 0,
> - &pstate->pipe, 0, stage_cfg);
> -
> - if (pstate->r_pipe.sspp) {
> - set_bit(pstate->r_pipe.sspp->idx, fetch_active);
> + for (i = 0; i < PIPES_PER_STAGE; i++) {
> + if (!pstate->pipe[i].sspp)
> + continue;
> + set_bit(pstate->pipe[i].sspp->idx, fetch_active);
> _dpu_crtc_blend_setup_pipe(crtc, plane,
> mixer, cstate->num_mixers,
> pstate->stage,
> format, fb ? fb->modifier : 0,
> - &pstate->r_pipe, 1, stage_cfg);
> + &pstate->pipe[i], i, stage_cfg);
> }
>
> /* blend config update */
> @@ -1440,15 +1435,15 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
> seq_printf(s, "\tdst x:%4d dst_y:%4d dst_w:%4d dst_h:%4d\n",
> state->crtc_x, state->crtc_y, state->crtc_w,
> state->crtc_h);
> - seq_printf(s, "\tsspp[0]:%s\n",
> - pstate->pipe.sspp->cap->name);
> - seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
> - pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
> - if (pstate->r_pipe.sspp) {
> - seq_printf(s, "\tsspp[1]:%s\n",
> - pstate->r_pipe.sspp->cap->name);
> - seq_printf(s, "\tmultirect[1]: mode: %d index: %d\n",
> - pstate->r_pipe.multirect_mode, pstate->r_pipe.multirect_index);
> +
> + for (i = 0; i < PIPES_PER_STAGE; i++) {
> + if (pstate->pipe[i].sspp) {
Here and further on: please make the code uniform. I liked the
`if (!sspp) continue;' style. Could you please switch all the places to
use the same pattern.
> + seq_printf(s, "\tsspp[%d]:%s\n",
> + i, pstate->pipe[i].sspp->cap->name);
> + seq_printf(s, "\tmultirect[%d]: mode: %d index: %d\n",
> + i, pstate->pipe[i].multirect_mode,
> + pstate->pipe[i].multirect_index);
> + }
> }
>
> seq_puts(s, "\n");
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 098abc2c0003c..aaf934ec96be5 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -619,6 +619,7 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
> struct msm_drm_private *priv = plane->dev->dev_private;
> struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
> u32 fill_color = (color & 0xFFFFFF) | ((alpha & 0xFF) << 24);
> + int i;
>
> DPU_DEBUG_PLANE(pdpu, "\n");
>
> @@ -632,12 +633,12 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
> return;
>
> /* update sspp */
> - _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg.dst_rect,
> - fill_color, fmt);
> -
> - if (pstate->r_pipe.sspp)
> - _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg.dst_rect,
> - fill_color, fmt);
> + for (i = 0; i < PIPES_PER_STAGE; i++) {
> + if (pstate->pipe[i].sspp)
> + _dpu_plane_color_fill_pipe(pstate, &pstate->pipe[i],
> + &pstate->pipe_cfg[i].dst_rect,
> + fill_color, fmt);
> + }
> }
>
> static int dpu_plane_prepare_fb(struct drm_plane *plane,
> @@ -799,8 +800,8 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
> struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate;
> struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
> - struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
> - struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> + struct dpu_sw_pipe_cfg *pipe_cfg;
> + struct dpu_sw_pipe_cfg *r_pipe_cfg;
> struct drm_rect fb_rect = { 0 };
> uint32_t max_linewidth;
>
> @@ -825,6 +826,9 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
> return -EINVAL;
> }
>
> + /* move the assignment here, to ease handling to another pairs later */
> + pipe_cfg = &pstate->pipe_cfg[0];
> + r_pipe_cfg = &pstate->pipe_cfg[1];
> /* state->src is 16.16, src_rect is not */
> drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
>
> @@ -921,11 +925,11 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
> drm_atomic_get_new_plane_state(state, plane);
> struct dpu_plane *pdpu = to_dpu_plane(plane);
> struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
> - struct dpu_sw_pipe *pipe = &pstate->pipe;
> - struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> const struct msm_format *fmt;
> - struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
> - struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> + struct dpu_sw_pipe *pipe = &pstate->pipe[0];
> + struct dpu_sw_pipe *r_pipe = &pstate->pipe[1];
> + struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[0];
> + struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[1];
> uint32_t supported_rotations;
> const struct dpu_sspp_cfg *pipe_hw_caps;
> const struct dpu_sspp_sub_blks *sblk;
> @@ -1010,10 +1014,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> struct dpu_plane *pdpu = to_dpu_plane(plane);
> struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
> struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
> - struct dpu_sw_pipe *pipe = &pstate->pipe;
> - struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> - struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
> - struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> + struct dpu_sw_pipe *pipe = &pstate->pipe[0];
> + struct dpu_sw_pipe *r_pipe = &pstate->pipe[1];
> + struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[0];
> + struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[1];
> const struct drm_crtc_state *crtc_state = NULL;
> uint32_t max_linewidth = dpu_kms->catalog->caps->max_linewidth;
>
> @@ -1057,7 +1061,7 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
> drm_atomic_get_old_plane_state(state, plane);
> struct dpu_plane_state *pstate = to_dpu_plane_state(plane_state);
> struct drm_crtc_state *crtc_state;
> - int ret;
> + int ret, i;
>
> if (plane_state->crtc)
> crtc_state = drm_atomic_get_new_crtc_state(state,
> @@ -1072,8 +1076,8 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
> * resources are freed by dpu_crtc_assign_plane_resources(),
> * but clean them here.
> */
> - pstate->pipe.sspp = NULL;
> - pstate->r_pipe.sspp = NULL;
> + for (i = 0; i < PIPES_PER_STAGE; i++)
> + pstate->pipe[i].sspp = NULL;
>
> return 0;
> }
> @@ -1110,19 +1114,22 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> struct dpu_sw_pipe_cfg *pipe_cfg;
> struct dpu_sw_pipe_cfg *r_pipe_cfg;
> const struct msm_format *fmt;
> + int i;
>
> if (plane_state->crtc)
> crtc_state = drm_atomic_get_new_crtc_state(state,
> plane_state->crtc);
>
> pstate = to_dpu_plane_state(plane_state);
> - pipe = &pstate->pipe;
> - r_pipe = &pstate->r_pipe;
> - pipe_cfg = &pstate->pipe_cfg;
> - r_pipe_cfg = &pstate->r_pipe_cfg;
>
> - pipe->sspp = NULL;
> - r_pipe->sspp = NULL;
> + /* TODO: loop below code for another pair later */
Drop the comment, it is not relevant for this patch.
> + pipe = &pstate->pipe[0];
> + r_pipe = &pstate->pipe[1];
> + pipe_cfg = &pstate->pipe_cfg[0];
> + r_pipe_cfg = &pstate->pipe_cfg[1];
> +
> + for (i = 0; i < PIPES_PER_STAGE; i++)
> + pstate->pipe[i].sspp = NULL;
>
> if (!plane_state->fb)
> return -EINVAL;
> @@ -1212,6 +1219,7 @@ void dpu_plane_flush(struct drm_plane *plane)
> {
> struct dpu_plane *pdpu;
> struct dpu_plane_state *pstate;
> + int i;
>
> if (!plane || !plane->state) {
> DPU_ERROR("invalid plane\n");
> @@ -1232,8 +1240,8 @@ void dpu_plane_flush(struct drm_plane *plane)
> /* force 100% alpha */
> _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> else {
> - dpu_plane_flush_csc(pdpu, &pstate->pipe);
> - dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> + for (i = 0; i < PIPES_PER_STAGE; i++)
> + dpu_plane_flush_csc(pdpu, &pstate->pipe[i]);
> }
>
> /* flag h/w flush complete */
> @@ -1334,15 +1342,19 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane,
> struct dpu_plane *pdpu = to_dpu_plane(plane);
> struct drm_plane_state *state = plane->state;
> struct dpu_plane_state *pstate = to_dpu_plane_state(state);
> - struct dpu_sw_pipe *pipe = &pstate->pipe;
> - struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> struct drm_crtc *crtc = state->crtc;
> struct drm_framebuffer *fb = state->fb;
> bool is_rt_pipe;
> const struct msm_format *fmt =
> msm_framebuffer_format(fb);
> - struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
> - struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> + struct dpu_hw_fmt_layout layout;
> + int ret, i;
> +
> + ret = dpu_format_populate_plane_sizes(fb, &layout);
> + if (ret) {
> + DPU_ERROR_PLANE(pdpu, "failed to get format plane sizes, %d\n", ret);
> + return;
> + }
The patch is supposed to change pipe/r_pipe and pipe_cfg / r_pipe_cfg
into arrays. How did it get this chunk? Is it releavent for this patch
or did it come from another patch?
>
> pstate->pending = true;
>
> @@ -1357,12 +1369,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane,
> crtc->base.id, DRM_RECT_ARG(&state->dst),
> &fmt->pixel_format, MSM_FORMAT_IS_UBWC(fmt));
>
> - dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
> - drm_mode_vrefresh(&crtc->mode),
> - &pstate->layout);
> -
> - if (r_pipe->sspp) {
> - dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
> + /* move the assignment here, to ease handling to another pairs later */
> + for (i = 0; i < PIPES_PER_STAGE; i++) {
> + if (!pstate->pipe[i].sspp)
> + continue;
> + dpu_plane_sspp_update_pipe(plane, &pstate->pipe[i],
> + &pstate->pipe_cfg[i], fmt,
> drm_mode_vrefresh(&crtc->mode),
> &pstate->layout);
> }
> @@ -1370,15 +1382,17 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane,
> if (pstate->needs_qos_remap)
> pstate->needs_qos_remap = false;
>
> - pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt,
> - &crtc->mode, pipe_cfg);
> -
> - pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
> -
> - if (r_pipe->sspp) {
> - pstate->plane_fetch_bw += _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, r_pipe_cfg);
> + pstate->plane_fetch_bw = 0;
> + pstate->plane_clk = 0;
> + for (i = 0; i < PIPES_PER_STAGE; i++) {
> + if (!pstate->pipe[i].sspp)
> + continue;
> + pstate->plane_fetch_bw += _dpu_plane_calc_bw(pdpu->catalog, fmt,
> + &crtc->mode, &pstate->pipe_cfg[i]);
>
> - pstate->plane_clk = max(pstate->plane_clk, _dpu_plane_calc_clk(&crtc->mode, r_pipe_cfg));
> + pstate->plane_clk = max(pstate->plane_clk,
> + _dpu_plane_calc_clk(&crtc->mode,
> + &pstate->pipe_cfg[i]));
> }
> }
>
> @@ -1386,17 +1400,24 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
> {
> struct drm_plane_state *state = plane->state;
> struct dpu_plane_state *pstate = to_dpu_plane_state(state);
> - struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> + struct dpu_sw_pipe *pipe;
> + int i;
>
> - trace_dpu_plane_disable(DRMID(plane), false,
> - pstate->pipe.multirect_mode);
> + for (i = 0; i < PIPES_PER_STAGE; i += 1) {
> + pipe = &pstate->pipe[i];
> + if (!pipe->sspp)
> + continue;
>
> - if (r_pipe->sspp) {
> - r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> - r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> + trace_dpu_plane_disable(DRMID(plane), false,
> + pstate->pipe[i].multirect_mode);
>
> - if (r_pipe->sspp->ops.setup_multirect)
> - r_pipe->sspp->ops.setup_multirect(r_pipe);
> + if (pipe->sspp && i == 1) {
Add a comment, why this is being done. It was idiomatic (more or less)
when it was r_pipe, not it demands some words. E.g. "clear multirect for
the right pipe so that the SSPP can be further reused in the solo mode"
> + pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> + pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> +
> + if (pipe->sspp->ops.setup_multirect)
> + pipe->sspp->ops.setup_multirect(pipe);
> + }
> }
>
> pstate->pending = true;
> @@ -1491,31 +1512,26 @@ static void dpu_plane_atomic_print_state(struct drm_printer *p,
> const struct drm_plane_state *state)
> {
> const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
> - const struct dpu_sw_pipe *pipe = &pstate->pipe;
> - const struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
> - const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> - const struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> + const struct dpu_sw_pipe *pipe;
> + const struct dpu_sw_pipe_cfg *pipe_cfg;
> + int i;
>
> drm_printf(p, "\tstage=%d\n", pstate->stage);
>
> - if (pipe->sspp) {
> - drm_printf(p, "\tsspp[0]=%s\n", pipe->sspp->cap->name);
> - drm_printf(p, "\tmultirect_mode[0]=%s\n",
> + for (i = 0; i < PIPES_PER_STAGE; i++) {
> + pipe = &pstate->pipe[i];
> + if (!pipe->sspp)
> + continue;
> + pipe_cfg = &pstate->pipe_cfg[i];
> + drm_printf(p, "\tsspp[%d]=%s\n", i, pipe->sspp->cap->name);
> + drm_printf(p, "\tmultirect_mode[%d]=%s\n", i,
> dpu_get_multirect_mode(pipe->multirect_mode));
> - drm_printf(p, "\tmultirect_index[0]=%s\n",
> + drm_printf(p, "\tmultirect_index[%d]=%s\n", i,
> dpu_get_multirect_index(pipe->multirect_index));
> - drm_printf(p, "\tsrc[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->src_rect));
> - drm_printf(p, "\tdst[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->dst_rect));
> - }
> -
> - if (r_pipe->sspp) {
> - drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
> - drm_printf(p, "\tmultirect_mode[1]=%s\n",
> - dpu_get_multirect_mode(r_pipe->multirect_mode));
> - drm_printf(p, "\tmultirect_index[1]=%s\n",
> - dpu_get_multirect_index(r_pipe->multirect_index));
> - drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
> - drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
> + drm_printf(p, "\tsrc[%d]=" DRM_RECT_FMT "\n", i,
> + DRM_RECT_ARG(&pipe_cfg->src_rect));
> + drm_printf(p, "\tdst[%d]=" DRM_RECT_FMT "\n", i,
> + DRM_RECT_ARG(&pipe_cfg->dst_rect));
> }
> }
>
> @@ -1553,14 +1569,16 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
> struct dpu_plane *pdpu = to_dpu_plane(plane);
> struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
> struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
> + int i;
>
> if (!pdpu->is_rt_pipe)
> return;
>
> pm_runtime_get_sync(&dpu_kms->pdev->dev);
> - _dpu_plane_set_qos_ctrl(plane, &pstate->pipe, enable);
> - if (pstate->r_pipe.sspp)
> - _dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, enable);
> + for (i = 0; i < PIPES_PER_STAGE; i++) {
> + if (pstate->pipe[i].sspp)
> + _dpu_plane_set_qos_ctrl(plane, &pstate->pipe[i], enable);
> + }
> pm_runtime_put_sync(&dpu_kms->pdev->dev);
> }
> #endif
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index acd5725175cdd..052fd046e8463 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -18,10 +18,8 @@
> * struct dpu_plane_state: Define dpu extension of drm plane state object
> * @base: base drm plane state object
> * @aspace: pointer to address space for input/output buffers
> - * @pipe: software pipe description
> - * @r_pipe: software pipe description of the second pipe
> - * @pipe_cfg: software pipe configuration
> - * @r_pipe_cfg: software pipe configuration for the second pipe
> + * @pipe: software pipe description array
> + * @pipe_cfg: software pipe configuration array
> * @stage: assigned by crtc blender
> * @needs_qos_remap: qos remap settings need to be updated
> * @multirect_index: index of the rectangle of SSPP
> @@ -35,10 +33,8 @@
> struct dpu_plane_state {
> struct drm_plane_state base;
> struct msm_gem_address_space *aspace;
> - struct dpu_sw_pipe pipe;
> - struct dpu_sw_pipe r_pipe;
> - struct dpu_sw_pipe_cfg pipe_cfg;
> - struct dpu_sw_pipe_cfg r_pipe_cfg;
> + struct dpu_sw_pipe pipe[PIPES_PER_STAGE];
> + struct dpu_sw_pipe_cfg pipe_cfg[PIPES_PER_STAGE];
> enum dpu_stage stage;
> bool needs_qos_remap;
> bool pending;
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 09/15] drm/msm/dpu: split PIPES_PER_STAGE definition per plane and mixer
2024-12-19 7:49 ` [PATCH v3 09/15] drm/msm/dpu: split PIPES_PER_STAGE definition per plane and mixer Jun Nie
@ 2024-12-19 22:28 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 22:28 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:27PM +0800, Jun Nie wrote:
> Split PIPES_PER_STAGE definition per plane and mixer pair. Because
> there are more than 2 pipes in quad pipe case, while 2 pipes at most
> per mixer pair. A stage struct serve a mixer pair, so pipes per
> plane is split out as PIPES_PER_PLANE.
I can barely understand this. The patch itself LGTM.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 4 ++--
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 1 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 +++++++++---------
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 4 ++--
> 4 files changed, 14 insertions(+), 13 deletions(-)
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 10/15] drm/msm/dpu: Add pipe as trace argument
2024-12-19 7:49 ` [PATCH v3 10/15] drm/msm/dpu: Add pipe as trace argument Jun Nie
@ 2024-12-19 22:29 ` Dmitry Baryshkov
2024-12-31 13:24 ` Jun Nie
0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 22:29 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:28PM +0800, Jun Nie wrote:
> Add pipe as trace argument to ease converting pipe into
> pipe array later.
Isn't it already converted in on of the previous patches? Also you are
adding it to a particular trace function, trace_dpu_crtc_setup_mixer().
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 +++++-----
> 2 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 72ed8749cd716..6841d0504d450 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -411,7 +411,7 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
>
> trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
> state, to_dpu_plane_state(state), stage_idx,
> - format->pixel_format,
> + format->pixel_format, pipe,
> modifier);
>
> DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d multirect_idx %d\n",
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> index 5307cbc2007c5..cb24ad2a6d8d3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> @@ -651,9 +651,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
> TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
> struct drm_plane_state *state, struct dpu_plane_state *pstate,
> uint32_t stage_idx, uint32_t pixel_format,
> - uint64_t modifier),
> + struct dpu_sw_pipe *pipe, uint64_t modifier),
> TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
> - pixel_format, modifier),
> + pixel_format, pipe, modifier),
> TP_STRUCT__entry(
> __field( uint32_t, crtc_id )
> __field( uint32_t, plane_id )
> @@ -676,9 +676,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
> __entry->dst_rect = drm_plane_state_dest(state);
> __entry->stage_idx = stage_idx;
> __entry->stage = pstate->stage;
> - __entry->sspp = pstate->pipe.sspp->idx;
> - __entry->multirect_idx = pstate->pipe.multirect_index;
> - __entry->multirect_mode = pstate->pipe.multirect_mode;
> + __entry->sspp = pipe->sspp->idx;
> + __entry->multirect_idx = pipe->multirect_index;
> + __entry->multirect_mode = pipe->multirect_mode;
> __entry->pixel_format = pixel_format;
> __entry->modifier = modifier;
> ),
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 11/15] drm/msm/dpu: blend pipes per mixer pairs config
2024-12-19 7:49 ` [PATCH v3 11/15] drm/msm/dpu: blend pipes per mixer pairs config Jun Nie
@ 2024-12-19 22:40 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 22:40 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:29PM +0800, Jun Nie wrote:
> Blend pipes by set of mixer pair config.
You are repeating commit subject, so this phrase can be dropped. But
more importantly, I don't understand it. What do you mean?
> The first 2 pipes are for left
> half screen with the first set of mixer pair config. And the later 2 pipes
> are for right in quad pipe case. A stage structure serves a mixer pair,
> that is coupled with 2 pipes. So the stage array number is defined as
> STAGES_PER_PLANE.
And I still have problems understanding your commit message. This might
sound like a joke, but it is not. If my commit message are not clear,
I'm getting more or less the same response. Please consider asking one
of your colleagues to help you with the commit messages.
And another usual comment: describe why, not what. Start by describing
the problem instead of writing a text about the change itself.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 38 ++++++++++++++++++-----------
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 1 +
> 2 files changed, 25 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 6841d0504d450..6ef7e6ed00238 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -442,7 +442,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> const struct msm_format *format;
> struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>
> - uint32_t lm_idx, i;
> + uint32_t lm_idx, stage, i, pipe_idx;
> bool bg_alpha_enable = false;
> DECLARE_BITMAP(fetch_active, SSPP_MAX);
>
> @@ -463,15 +463,20 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
> bg_alpha_enable = true;
>
> - for (i = 0; i < PIPES_PER_PLANE; i++) {
> - if (!pstate->pipe[i].sspp)
> - continue;
> - set_bit(pstate->pipe[i].sspp->idx, fetch_active);
> - _dpu_crtc_blend_setup_pipe(crtc, plane,
> - mixer, cstate->num_mixers,
> - pstate->stage,
> - format, fb ? fb->modifier : 0,
> - &pstate->pipe[i], i, stage_cfg);
> + /* loop pipe per mixer pair that's served by a stage structure */
served?
> + for (stage = 0; stage < PIPES_PER_PLANE / STAGES_PER_PLANE; stage++) {
> + for (i = 0; i < PIPES_PER_STAGE; i++) {
> + pipe_idx = i + stage * PIPES_PER_STAGE;
> + if (!pstate->pipe[pipe_idx].sspp)
> + continue;
> + set_bit(pstate->pipe[pipe_idx].sspp->idx, fetch_active);
> + _dpu_crtc_blend_setup_pipe(crtc, plane,
> + mixer, cstate->num_mixers,
> + pstate->stage,
> + format, fb ? fb->modifier : 0,
> + &pstate->pipe[pipe_idx], i,
> + &stage_cfg[stage]);
This is not correct. It will make all LM CTLs to be programmed to flush
this SSPP, while actually they should only be flushed for a
corresponding pair.
> + }
> }
>
> /* blend config update */
> @@ -503,7 +508,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
> struct dpu_crtc_mixer *mixer = cstate->mixers;
> struct dpu_hw_ctl *ctl;
> struct dpu_hw_mixer *lm;
> - struct dpu_hw_stage_cfg stage_cfg;
> + struct dpu_hw_stage_cfg stage_cfg[STAGES_PER_PLANE];
> int i;
>
> DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
> @@ -516,9 +521,9 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
> }
>
> /* initialize stage cfg */
> - memset(&stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
> + memset(&stage_cfg, 0, sizeof(stage_cfg));
>
> - _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg);
> + _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg[0]);
stage_cfg instead of &stage_cfg[0], unless you are passing just one
stage config.
>
> for (i = 0; i < cstate->num_mixers; i++) {
> ctl = mixer[i].lm_ctl;
> @@ -535,8 +540,13 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
> mixer[i].mixer_op_mode,
> ctl->idx - CTL_0);
>
> + /*
> + * call dpu_hw_ctl_setup_blendstage() to blend layers per stage cfg.
> + * There is 4 mixers at most. The first 2 are for the left half, and
There is 1 mixer, there are 4 mixers.
> + * the later 2 are for the right half.
> + */
> ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
> - &stage_cfg);
> + &stage_cfg[i / 2]);
> }
> }
>
> 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 68867c2f40d4b..27ef0771da5d2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> @@ -32,6 +32,7 @@
> #define DPU_MAX_PLANES 4
> #endif
>
> +#define STAGES_PER_PLANE 2
> #define PIPES_PER_PLANE 2
> #define PIPES_PER_STAGE 2
> #ifndef DPU_MAX_DE_CURVES
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 12/15] drm/msm/dpu: support plane splitting in quad-pipe case
2024-12-19 7:49 ` [PATCH v3 12/15] drm/msm/dpu: support plane splitting in quad-pipe case Jun Nie
@ 2024-12-19 23:16 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 23:16 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:30PM +0800, Jun Nie wrote:
> The content of every half of screen is sent out via one interface in
> dual-DSI case. The content for every interface is blended by a LM
> pair,
Only in case of the quad-pipe topology.
> thus no content of any pipe shall cross the LM pair.
You have swapped the cause and the consequence.
> We need
> to clip plane into pipes per left and right half screen ROI if topology
> is quad pipe.
>
> The clipped rectangle on every half of screen will be split further
> by half if its width still exceeds limit.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 7 ++
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 2 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 108 +++++++++++++++++++++-------
> 4 files changed, 97 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 6ef7e6ed00238..bad75af4e50ab 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1363,6 +1363,13 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)
> return 0;
> }
>
> +unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state)
> +{
> + struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
> +
> + return cstate->num_mixers;
> +}
> +
> #ifdef CONFIG_DEBUG_FS
> static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
> {
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> index 0b148f3ce0d7a..d1bb3f84fe440 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> @@ -264,4 +264,10 @@ static inline enum dpu_crtc_client_type dpu_crtc_get_client_type(
>
> void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
>
> +/**
> + * dpu_crtc_get_num_lm - Get mixer number in this CRTC pipeline
> + * state: Pointer to drm crtc state object
> + */
Rewrite to be a proper kerneldoc, move it to the function body.
> +unsigned int dpu_crtc_get_num_lm(const struct drm_crtc_state *state);
> +
> #endif /* _DPU_CRTC_H_ */
> 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 56a0edf2a57c6..39fe338e76691 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -145,11 +145,13 @@ struct dpu_hw_pixel_ext {
> * such as decimation, flip etc to program this field
> * @dest_rect: destination ROI.
> * @rotation: simplified drm rotation hint
> + * @valid: notify that this pipe and config is in use
> */
> struct dpu_sw_pipe_cfg {
> struct drm_rect src_rect;
> struct drm_rect dst_rect;
> unsigned int rotation;
> + bool valid;
> };
>
> /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 46c6b6126fe5c..fca6e609898a6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -802,8 +802,14 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
> struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
> struct dpu_sw_pipe_cfg *pipe_cfg;
> struct dpu_sw_pipe_cfg *r_pipe_cfg;
> + struct dpu_sw_pipe *pipe;
> + struct dpu_sw_pipe *r_pipe;
> + struct dpu_sw_pipe_cfg init_pipe_cfg;
> struct drm_rect fb_rect = { 0 };
> + const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
> uint32_t max_linewidth;
> + u32 num_lm;
> + int stage_id, num_stages;
>
> min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO);
> max_scale = MAX_DOWNSCALE_RATIO << 16;
> @@ -826,13 +832,10 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
> return -EINVAL;
> }
>
> - /* move the assignment here, to ease handling to another pairs later */
> - pipe_cfg = &pstate->pipe_cfg[0];
> - r_pipe_cfg = &pstate->pipe_cfg[1];
> - /* state->src is 16.16, src_rect is not */
> - drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
> + num_lm = dpu_crtc_get_num_lm(crtc_state);
>
> - pipe_cfg->dst_rect = new_plane_state->dst;
> + /* state->src is 16.16, src_rect is not */
> + drm_rect_fp_to_int(&init_pipe_cfg.src_rect, &new_plane_state->src);
>
> fb_rect.x2 = new_plane_state->fb->width;
> fb_rect.y2 = new_plane_state->fb->height;
> @@ -857,34 +860,87 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
>
> max_linewidth = pdpu->catalog->caps->max_linewidth;
>
> - drm_rect_rotate(&pipe_cfg->src_rect,
> + drm_rect_rotate(&init_pipe_cfg.src_rect,
> new_plane_state->fb->width, new_plane_state->fb->height,
> new_plane_state->rotation);
>
> - if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
> - _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) {
> - if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) {
> - DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
> - DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
> - return -E2BIG;
> + /*
> + * We have 1 mixer pair cfg for 1:1:1 and 2:2:1 topology, 2 mixer pair
> + * configs for left and right half screen in case of 4:4:2 topology.
> + * But we may have 2 rect to split plane with 1 config for 2:2:1.
> + * So need to handle super wide plane splitting, and plane on right half
What is 'super wide'?
> + * for quad-pipe case. Check dest rectangle left/right clipping
> + * first, then check super wide rectangle splitting in every half next.
> + */
> + num_stages = (num_lm + 1) / 2;
> + /* iterate mixer configs for this plane, to separate left/right with the id */
> + for (stage_id = 0; stage_id < num_stages; stage_id++) {
> + struct drm_rect mixer_rect = {stage_id * mode->hdisplay / num_stages, 0,
> + (stage_id + 1) * mode->hdisplay / num_stages,
> + mode->vdisplay};
> + int cfg_idx = stage_id * PIPES_PER_STAGE;
> +
> + pipe = &pstate->pipe[cfg_idx];
> + r_pipe = &pstate->pipe[cfg_idx + 1];
> + pipe_cfg = &pstate->pipe_cfg[cfg_idx];
> + r_pipe_cfg = &pstate->pipe_cfg[cfg_idx + 1];
> +
> + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
> + pipe_cfg->dst_rect = new_plane_state->dst;
> +
> + DPU_DEBUG_PLANE(pdpu, "checking src " DRM_RECT_FMT
> + " vs clip window " DRM_RECT_FMT "\n",
> + DRM_RECT_ARG(&pipe_cfg->src_rect),
> + DRM_RECT_ARG(&mixer_rect));
> +
> + /*
> + * If this plane does not fall into mixer rect, check next
> + * mixer rect.
> + */
> + if (!drm_rect_clip_scaled(&pipe_cfg->src_rect,
> + &pipe_cfg->dst_rect,
> + &mixer_rect)) {
> + memset(pipe_cfg, 0, 2 * sizeof(struct dpu_sw_pipe_cfg));
> + memset(pipe, 0, 2 * sizeof(struct dpu_sw_pipe));
No need to memset, just set valid to false.
Also it is incorrect to memset the pipe, you've just lost the
pipe->sspp, which is set if the non-virtual implementation is in play.
> + continue;
> }
>
> - *r_pipe_cfg = *pipe_cfg;
> - pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1;
> - pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1;
> - r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2;
> - r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
> - } else {
> - memset(r_pipe_cfg, 0, sizeof(*r_pipe_cfg));
> - }
> + pipe_cfg->valid = true;
> + pipe_cfg->dst_rect.x1 -= mixer_rect.x1;
> + pipe_cfg->dst_rect.x2 -= mixer_rect.x1;
> +
> + DPU_DEBUG_PLANE(pdpu, "Got clip src:" DRM_RECT_FMT " dst: " DRM_RECT_FMT "\n",
> + DRM_RECT_ARG(&pipe_cfg->src_rect), DRM_RECT_ARG(&pipe_cfg->dst_rect));
> +
> + /* Split super wide rect into 2 rect */
Why is it super wide? Just wide.
> + if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
> + _dpu_plane_calc_clk(mode, pipe_cfg) > max_mdp_clk_rate) {
> +
> + if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) {
> + DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
> + DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
> + return -E2BIG;
> + }
> +
> + memcpy(r_pipe_cfg, pipe_cfg, sizeof(struct dpu_sw_pipe_cfg));
> + pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1;
> + pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1;
> + r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2;
> + r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
> + r_pipe_cfg->valid = true;
> + DPU_DEBUG_PLANE(pdpu, "Split super wide plane into:"
> + DRM_RECT_FMT " and " DRM_RECT_FMT "\n",
> + DRM_RECT_ARG(&pipe_cfg->src_rect),
> + DRM_RECT_ARG(&r_pipe_cfg->src_rect));
> + } else {
> + memset(r_pipe_cfg, 0, sizeof(struct dpu_sw_pipe_cfg));
> + memset(r_pipe, 0, sizeof(struct dpu_sw_pipe));
Again, drop the memsets.
> + }
>
> - drm_rect_rotate_inv(&pipe_cfg->src_rect,
> - new_plane_state->fb->width, new_plane_state->fb->height,
> - new_plane_state->rotation);
> - if (drm_rect_width(&r_pipe_cfg->src_rect) != 0)
> - drm_rect_rotate_inv(&r_pipe_cfg->src_rect,
> + drm_rect_rotate_inv(&pipe_cfg->src_rect,
> new_plane_state->fb->width, new_plane_state->fb->height,
> new_plane_state->rotation);
You've dropped the rotation of the right rectangle. Why?
> + }
>
> pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
>
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 13/15] drm/msm/dpu: Support quad-pipe in SSPP checking
2024-12-19 7:49 ` [PATCH v3 13/15] drm/msm/dpu: Support quad-pipe in SSPP checking Jun Nie
@ 2024-12-19 23:23 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 23:23 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:31PM +0800, Jun Nie wrote:
> Move requreiment check to routine of every pipe check. There will be
> multiple SSPPs for quad-pipe case in future. Only check valid pipe
> as some pipes are for multi-rect or right half of screen that may
> not be used.
This highlights an issue in the current wide planes implelentation.
Please move this to the top of the series, provide a proper commit
message, describing the issue, and add a proper Fixes tag.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 86 +++++++++++++++----------------
> 1 file changed, 42 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index fca6e609898a6..1cd98892898a4 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -730,12 +730,40 @@ static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
> static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
> struct dpu_sw_pipe *pipe,
> struct dpu_sw_pipe_cfg *pipe_cfg,
> - const struct msm_format *fmt,
> - const struct drm_display_mode *mode)
> + const struct drm_display_mode *mode,
> + struct drm_plane_state *new_plane_state)
> {
> uint32_t min_src_size;
> struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> int ret;
> + const struct msm_format *fmt;
> + uint32_t supported_rotations;
> + const struct dpu_sspp_cfg *pipe_hw_caps;
> + const struct dpu_sspp_sub_blks *sblk;
> +
> + pipe_hw_caps = pipe->sspp->cap;
> + sblk = pipe->sspp->cap->sblk;
> +
> + /*
> + * We already have verified scaling against platform limitations.
> + * Now check if the SSPP supports scaling at all.
> + */
> + if (!sblk->scaler_blk.len &&
> + ((drm_rect_width(&new_plane_state->src) >> 16 !=
> + drm_rect_width(&new_plane_state->dst)) ||
> + (drm_rect_height(&new_plane_state->src) >> 16 !=
> + drm_rect_height(&new_plane_state->dst))))
> + return -ERANGE;
> +
> + fmt = msm_framebuffer_format(new_plane_state->fb);
> +
> + supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
> +
> + if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
> + supported_rotations |= DRM_MODE_ROTATE_90;
> +
> + pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation,
> + supported_rotations);
>
> min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1;
>
> @@ -981,49 +1009,19 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
> drm_atomic_get_new_plane_state(state, plane);
> struct dpu_plane *pdpu = to_dpu_plane(plane);
> struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
> - const struct msm_format *fmt;
> - struct dpu_sw_pipe *pipe = &pstate->pipe[0];
> - struct dpu_sw_pipe *r_pipe = &pstate->pipe[1];
> - struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[0];
> - struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[1];
> - uint32_t supported_rotations;
> - const struct dpu_sspp_cfg *pipe_hw_caps;
> - const struct dpu_sspp_sub_blks *sblk;
> - int ret = 0;
> -
> - pipe_hw_caps = pipe->sspp->cap;
> - sblk = pipe->sspp->cap->sblk;
> -
> - /*
> - * We already have verified scaling against platform limitations.
> - * Now check if the SSPP supports scaling at all.
> - */
> - if (!sblk->scaler_blk.len &&
> - ((drm_rect_width(&new_plane_state->src) >> 16 !=
> - drm_rect_width(&new_plane_state->dst)) ||
> - (drm_rect_height(&new_plane_state->src) >> 16 !=
> - drm_rect_height(&new_plane_state->dst))))
> - return -ERANGE;
> -
> - fmt = msm_framebuffer_format(new_plane_state->fb);
> -
> - supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
> -
> - if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
> - supported_rotations |= DRM_MODE_ROTATE_90;
> -
> - pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation,
> - supported_rotations);
> - r_pipe_cfg->rotation = pipe_cfg->rotation;
> -
> - ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt,
> - &crtc_state->adjusted_mode);
> - if (ret)
> - return ret;
> + struct dpu_sw_pipe *pipe;
> + struct dpu_sw_pipe_cfg *pipe_cfg;
> + int ret = 0, i;
>
> - if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) {
> - ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt,
> - &crtc_state->adjusted_mode);
> + for (i = 0; i < PIPES_PER_PLANE; i++) {
> + pipe = &pstate->pipe[i];
> + pipe_cfg = &pstate->pipe_cfg[i];
> + if (!pipe_cfg->valid || !pipe->sspp)
> + continue;
> + DPU_DEBUG_PLANE(pdpu, "pipe %d is in use, validate it\n", i);
> + ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg,
> + &crtc_state->adjusted_mode,
> + new_plane_state);
> if (ret)
> return ret;
> }
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 14/15] drm/msm/dpu: support SSPP assignment for quad-pipe case
2024-12-19 7:49 ` [PATCH v3 14/15] drm/msm/dpu: support SSPP assignment for quad-pipe case Jun Nie
@ 2024-12-19 23:30 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 23:30 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:32PM +0800, Jun Nie wrote:
> Support SSPP assignment for quad-pipe case with unified method.
> The first 2 pipes can share a set of mixer config and enable
> multi-rect mode if condition is met. It is also the case for
> the later 2 pipes.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 67 ++++++++++++++++++-------------
> 1 file changed, 38 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 1cd98892898a4..57ccb73c45683 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1163,12 +1163,9 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
> struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
> struct dpu_rm_sspp_requirements reqs;
> struct dpu_plane_state *pstate;
> - struct dpu_sw_pipe *pipe;
> - struct dpu_sw_pipe *r_pipe;
> - struct dpu_sw_pipe_cfg *pipe_cfg;
> - struct dpu_sw_pipe_cfg *r_pipe_cfg;
> + struct dpu_plane *pdpu = to_dpu_plane(plane);
> const struct msm_format *fmt;
> - int i;
> + int i, num_lm, stage_id, num_stages;
>
> if (plane_state->crtc)
> crtc_state = drm_atomic_get_new_crtc_state(state,
> @@ -1176,12 +1173,6 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
>
> pstate = to_dpu_plane_state(plane_state);
>
> - /* TODO: loop below code for another pair later */
> - pipe = &pstate->pipe[0];
> - r_pipe = &pstate->pipe[1];
> - pipe_cfg = &pstate->pipe_cfg[0];
> - r_pipe_cfg = &pstate->pipe_cfg[1];
> -
> for (i = 0; i < PIPES_PER_PLANE; i++)
> pstate->pipe[i].sspp = NULL;
>
> @@ -1195,24 +1186,42 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
>
> reqs.rot90 = drm_rotation_90_or_270(plane_state->rotation);
>
> - pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
> - if (!pipe->sspp)
> - return -ENODEV;
> -
> - if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
> - pipe->sspp,
> - msm_framebuffer_format(plane_state->fb),
> - dpu_kms->catalog->caps->max_linewidth)) {
> - /* multirect is not possible, use two SSPP blocks */
> - r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
> - if (!r_pipe->sspp)
> - return -ENODEV;
> -
> - pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> - pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> -
> - r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> - r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> + num_lm = dpu_crtc_get_num_lm(crtc_state);
> + num_stages = (num_lm + 1) / 2;
> + for (stage_id = 0; stage_id < num_stages; stage_id++) {
> + for (i = stage_id * PIPES_PER_STAGE; i < (stage_id + 1) * PIPES_PER_STAGE; i++) {
> + struct dpu_sw_pipe *pipe = &pstate->pipe[i];
> + struct dpu_sw_pipe *r_pipe = &pstate->pipe[i + 1];
> + struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[i];
> + struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[i + 1];
I'd rather not have r_pipe / r_pipe_cfg for the second pipe in the pair.
Please move them under the if.
Also take a look at [1]. I'm not asking to rebase on top of that change,
it need to be reviewed by other parties, but please keep it in mind.
[1] https://lore.kernel.org/r/20241215-dpu-share-sspp-v5-1-665d266183f9@linaro.org
> +
> + if (!pipe_cfg->valid)
> + break;
> +
> + pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
> + if (!pipe->sspp)
> + return -ENODEV;
> +
> + /*
> + * If current pipe is the first pipe in pipe pair, check
> + * multi-rect opportunity for the 2nd pipe in the pair.
> + * SSPP multi-rect mode cross mixer pairs is not supported.
> + */
> + if ((i % PIPES_PER_STAGE == 0) &&
> + r_pipe_cfg->valid &&
> + !dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
> + pipe->sspp,
> + msm_framebuffer_format(plane_state->fb),
> + dpu_kms->catalog->caps->max_linewidth)) {
> + i++;
> + } else {
> + /* multirect is not possible, use two SSPP blocks */
> + pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> + pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> + DPU_DEBUG_PLANE(pdpu, "allocating sspp_%d for pipe %d.\n",
> + pipe->sspp->idx - SSPP_NONE, i);
> + }
> + }
> }
>
> return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case
2024-12-19 7:49 ` [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case Jun Nie
@ 2024-12-19 23:46 ` Dmitry Baryshkov
2025-01-03 15:49 ` Jun Nie
0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-19 23:46 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Thu, Dec 19, 2024 at 03:49:33PM +0800, Jun Nie wrote:
> Request 4 mixers and 4 DSC for the case that both dual-DSI and DSC are
> enabled. We prefer to use 4 pipes for dual DSI case for it is power optimal
> for DSC.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 28 ++++++++++++++++++------
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 ++-
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +-
> 7 files changed, 30 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index bad75af4e50ab..3c51c199f3e05 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -200,7 +200,7 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc,
> struct dpu_crtc_state *crtc_state)
> {
> struct dpu_crtc_mixer *m;
> - u32 crcs[CRTC_DUAL_MIXERS];
> + u32 crcs[CRTC_QUAD_MIXERS];
>
> int rc = 0;
> int i;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> index d1bb3f84fe440..ce41fb364f3db 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> @@ -210,7 +210,7 @@ struct dpu_crtc_state {
>
> bool bw_control;
> bool bw_split_vote;
> - struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
> + struct drm_rect lm_bounds[CRTC_QUAD_MIXERS];
>
> uint64_t input_fence_timeout_ns;
>
> @@ -218,10 +218,10 @@ struct dpu_crtc_state {
>
> /* HW Resources reserved for the crtc */
> u32 num_mixers;
> - struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
> + struct dpu_crtc_mixer mixers[CRTC_QUAD_MIXERS];
>
> u32 num_ctls;
> - struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
> + struct dpu_hw_ctl *hw_ctls[CRTC_QUAD_MIXERS];
>
> enum dpu_crtc_crc_source crc_source;
> int crc_frame_skip_count;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 96d06db3e4be5..6e54ddeaffacd 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -54,7 +54,7 @@
> #define MAX_PHYS_ENCODERS_PER_VIRTUAL \
> (MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
>
> -#define MAX_CHANNELS_PER_ENC 2
> +#define MAX_CHANNELS_PER_ENC 4
>
> #define IDLE_SHORT_TIMEOUT 1
>
> @@ -664,15 +664,19 @@ static struct msm_display_topology dpu_encoder_get_topology(
>
> /* Datapath topology selection
> *
> - * Dual display
> + * Dual display without DSC
> * 2 LM, 2 INTF ( Split display using 2 interfaces)
> *
> + * Dual display with DSC
> + * 4 LM, 2 INTF ( Split display using 2 interfaces)
> + *
> * Single display
> * 1 LM, 1 INTF
> * 2 LM, 1 INTF (stream merge to support high resolution interfaces)
> *
> * Add dspps to the reservation requirements if ctm is requested
> */
> +
> if (intf_count == 2)
> topology.num_lm = 2;
> else if (!dpu_kms->catalog->caps->has_3d_merge)
> @@ -691,10 +695,20 @@ static struct msm_display_topology dpu_encoder_get_topology(
> * 2 DSC encoders, 2 layer mixers and 1 interface
> * this is power optimal and can drive up to (including) 4k
> * screens
> + * But for dual display case, we prefer 4 layer mixers. Because
> + * the resolution is always high in the case and 4 DSCs are more
> + * power optimal.
> */
> - topology.num_dsc = 2;
> - topology.num_lm = 2;
> - topology.num_intf = 1;
> +
> + if (intf_count == 2) {
> + topology.num_dsc = 4;
> + topology.num_lm = 4;
> + topology.num_intf = 2;
> + } else {
> + topology.num_dsc = 2;
> + topology.num_lm = 2;
> + topology.num_intf = 1;
Why is it only enabled for the DSC case? Also I'd like to point out
platforms like sm7150 or msm8998 which have only 2 DSC blocks. The
condition here needs more work to work with those platforms too.
> + }
> }
>
> return topology;
> @@ -2195,8 +2209,8 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
> struct dpu_hw_mixer_cfg mixer;
> int i, num_lm;
> struct dpu_global_state *global_state;
> - struct dpu_hw_blk *hw_lm[2];
> - struct dpu_hw_mixer *hw_mixer[2];
> + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
> + struct dpu_hw_mixer *hw_mixer[MAX_CHANNELS_PER_ENC];
> struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
>
> memset(&mixer, 0, sizeof(mixer));
> 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 63f09857025c2..d378a990cc0fb 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> @@ -302,7 +302,8 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
>
> /* Use merge_3d unless DSC MERGE topology is used */
> if (phys_enc->split_role == ENC_ROLE_SOLO &&
> - dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
> + (dpu_cstate->num_mixers == CRTC_DUAL_MIXERS ||
> + dpu_cstate->num_mixers == CRTC_QUAD_MIXERS) &&
Misaligned. Also isn't it enough to check that num_mixers != 1?
> !dpu_encoder_use_dsc_merge(phys_enc->parent))
> return BLEND_3D_H_ROW_INT;
>
> 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 3ab79092a7f25..d9cc84b081b1f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -25,6 +25,7 @@
> #define DPU_MAX_IMG_HEIGHT 0x3fff
>
> #define CRTC_DUAL_MIXERS 2
Do we still need this define?
> +#define CRTC_QUAD_MIXERS 4
>
> #define MAX_XIN_COUNT 16
>
> 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 27ef0771da5d2..1fe21087a141a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> @@ -33,8 +33,8 @@
> #endif
>
> #define STAGES_PER_PLANE 2
> -#define PIPES_PER_PLANE 2
> #define PIPES_PER_STAGE 2
> +#define PIPES_PER_PLANE (STAGES_PER_PLANE * STAGES_PER_PLANE)
This is incorrect.
> #ifndef DPU_MAX_DE_CURVES
> #define DPU_MAX_DE_CURVES 3
> #endif
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 57ccb73c45683..b5c1ad2a75594 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1474,7 +1474,7 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
> trace_dpu_plane_disable(DRMID(plane), false,
> pstate->pipe[i].multirect_mode);
>
> - if (pipe->sspp && i == 1) {
> + if (pipe->sspp && pipe->multirect_index == DPU_SSPP_RECT_1) {
Separate change, please. Also I'm not sure how does that work with the
shared SSPP case that I pointed to in one of the previous replies.
> pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 10/15] drm/msm/dpu: Add pipe as trace argument
2024-12-19 22:29 ` Dmitry Baryshkov
@ 2024-12-31 13:24 ` Jun Nie
2024-12-31 14:04 ` Dmitry Baryshkov
0 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2024-12-31 13:24 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 于2024年12月20日周五 06:29写道:
>
> On Thu, Dec 19, 2024 at 03:49:28PM +0800, Jun Nie wrote:
> > Add pipe as trace argument to ease converting pipe into
> > pipe array later.
>
> Isn't it already converted in on of the previous patches? Also you are
> adding it to a particular trace function, trace_dpu_crtc_setup_mixer().
It is converted in this patch. But this patch should be earlier than
the patch to
convert pipe into array actually. Will reverse the sequence in next version.
Yes, I am adding it to a particular trace function. Do you mean I should mention
the specific function in title?
>
> >
> > Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > ---
> > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
> > drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 +++++-----
> > 2 files changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index 72ed8749cd716..6841d0504d450 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -411,7 +411,7 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
> >
> > trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
> > state, to_dpu_plane_state(state), stage_idx,
> > - format->pixel_format,
> > + format->pixel_format, pipe,
> > modifier);
> >
> > DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d multirect_idx %d\n",
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> > index 5307cbc2007c5..cb24ad2a6d8d3 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> > @@ -651,9 +651,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
> > TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
> > struct drm_plane_state *state, struct dpu_plane_state *pstate,
> > uint32_t stage_idx, uint32_t pixel_format,
> > - uint64_t modifier),
> > + struct dpu_sw_pipe *pipe, uint64_t modifier),
> > TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
> > - pixel_format, modifier),
> > + pixel_format, pipe, modifier),
> > TP_STRUCT__entry(
> > __field( uint32_t, crtc_id )
> > __field( uint32_t, plane_id )
> > @@ -676,9 +676,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
> > __entry->dst_rect = drm_plane_state_dest(state);
> > __entry->stage_idx = stage_idx;
> > __entry->stage = pstate->stage;
> > - __entry->sspp = pstate->pipe.sspp->idx;
> > - __entry->multirect_idx = pstate->pipe.multirect_index;
> > - __entry->multirect_mode = pstate->pipe.multirect_mode;
> > + __entry->sspp = pipe->sspp->idx;
> > + __entry->multirect_idx = pipe->multirect_index;
> > + __entry->multirect_mode = pipe->multirect_mode;
> > __entry->pixel_format = pixel_format;
> > __entry->modifier = modifier;
> > ),
> >
> > --
> > 2.34.1
> >
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 10/15] drm/msm/dpu: Add pipe as trace argument
2024-12-31 13:24 ` Jun Nie
@ 2024-12-31 14:04 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2024-12-31 14:04 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Tue, 31 Dec 2024 at 15:24, Jun Nie <jun.nie@linaro.org> wrote:
>
> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 于2024年12月20日周五 06:29写道:
>
>
> >
> > On Thu, Dec 19, 2024 at 03:49:28PM +0800, Jun Nie wrote:
> > > Add pipe as trace argument to ease converting pipe into
> > > pipe array later.
> >
> > Isn't it already converted in on of the previous patches? Also you are
> > adding it to a particular trace function, trace_dpu_crtc_setup_mixer().
>
> It is converted in this patch. But this patch should be earlier than
> the patch to
> convert pipe into array actually. Will reverse the sequence in next version.
> Yes, I am adding it to a particular trace function. Do you mean I should mention
> the specific function in title?
Mentioning it in the commit message is enough.
>
> >
> > >
> > > Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > > ---
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 +++++-----
> > > 2 files changed, 6 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > index 72ed8749cd716..6841d0504d450 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > @@ -411,7 +411,7 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
> > >
> > > trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
> > > state, to_dpu_plane_state(state), stage_idx,
> > > - format->pixel_format,
> > > + format->pixel_format, pipe,
> > > modifier);
> > >
> > > DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d multirect_idx %d\n",
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> > > index 5307cbc2007c5..cb24ad2a6d8d3 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> > > @@ -651,9 +651,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
> > > TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
> > > struct drm_plane_state *state, struct dpu_plane_state *pstate,
> > > uint32_t stage_idx, uint32_t pixel_format,
> > > - uint64_t modifier),
> > > + struct dpu_sw_pipe *pipe, uint64_t modifier),
> > > TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
> > > - pixel_format, modifier),
> > > + pixel_format, pipe, modifier),
> > > TP_STRUCT__entry(
> > > __field( uint32_t, crtc_id )
> > > __field( uint32_t, plane_id )
> > > @@ -676,9 +676,9 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
> > > __entry->dst_rect = drm_plane_state_dest(state);
> > > __entry->stage_idx = stage_idx;
> > > __entry->stage = pstate->stage;
> > > - __entry->sspp = pstate->pipe.sspp->idx;
> > > - __entry->multirect_idx = pstate->pipe.multirect_index;
> > > - __entry->multirect_mode = pstate->pipe.multirect_mode;
> > > + __entry->sspp = pipe->sspp->idx;
> > > + __entry->multirect_idx = pipe->multirect_index;
> > > + __entry->multirect_mode = pipe->multirect_mode;
> > > __entry->pixel_format = pixel_format;
> > > __entry->modifier = modifier;
> > > ),
> > >
> > > --
> > > 2.34.1
> > >
> >
> > --
> > With best wishes
> > Dmitry
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case
2024-12-19 23:46 ` Dmitry Baryshkov
@ 2025-01-03 15:49 ` Jun Nie
2025-01-03 17:51 ` Dmitry Baryshkov
0 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2025-01-03 15:49 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 于2024年12月20日周五 07:46写道:
>
> On Thu, Dec 19, 2024 at 03:49:33PM +0800, Jun Nie wrote:
> > Request 4 mixers and 4 DSC for the case that both dual-DSI and DSC are
> > enabled. We prefer to use 4 pipes for dual DSI case for it is power optimal
> > for DSC.
> >
> > Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > ---
> > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
> > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++---
> > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 28 ++++++++++++++++++------
> > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 ++-
> > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
> > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +-
> > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +-
> > 7 files changed, 30 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index bad75af4e50ab..3c51c199f3e05 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -200,7 +200,7 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc,
> > struct dpu_crtc_state *crtc_state)
> > {
> > struct dpu_crtc_mixer *m;
> > - u32 crcs[CRTC_DUAL_MIXERS];
> > + u32 crcs[CRTC_QUAD_MIXERS];
> >
> > int rc = 0;
> > int i;
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > index d1bb3f84fe440..ce41fb364f3db 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > @@ -210,7 +210,7 @@ struct dpu_crtc_state {
> >
> > bool bw_control;
> > bool bw_split_vote;
> > - struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
> > + struct drm_rect lm_bounds[CRTC_QUAD_MIXERS];
> >
> > uint64_t input_fence_timeout_ns;
> >
> > @@ -218,10 +218,10 @@ struct dpu_crtc_state {
> >
> > /* HW Resources reserved for the crtc */
> > u32 num_mixers;
> > - struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
> > + struct dpu_crtc_mixer mixers[CRTC_QUAD_MIXERS];
> >
> > u32 num_ctls;
> > - struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
> > + struct dpu_hw_ctl *hw_ctls[CRTC_QUAD_MIXERS];
> >
> > enum dpu_crtc_crc_source crc_source;
> > int crc_frame_skip_count;
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > index 96d06db3e4be5..6e54ddeaffacd 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > @@ -54,7 +54,7 @@
> > #define MAX_PHYS_ENCODERS_PER_VIRTUAL \
> > (MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
> >
> > -#define MAX_CHANNELS_PER_ENC 2
> > +#define MAX_CHANNELS_PER_ENC 4
> >
> > #define IDLE_SHORT_TIMEOUT 1
> >
> > @@ -664,15 +664,19 @@ static struct msm_display_topology dpu_encoder_get_topology(
> >
> > /* Datapath topology selection
> > *
> > - * Dual display
> > + * Dual display without DSC
> > * 2 LM, 2 INTF ( Split display using 2 interfaces)
> > *
> > + * Dual display with DSC
> > + * 4 LM, 2 INTF ( Split display using 2 interfaces)
> > + *
> > * Single display
> > * 1 LM, 1 INTF
> > * 2 LM, 1 INTF (stream merge to support high resolution interfaces)
> > *
> > * Add dspps to the reservation requirements if ctm is requested
> > */
> > +
> > if (intf_count == 2)
> > topology.num_lm = 2;
> > else if (!dpu_kms->catalog->caps->has_3d_merge)
> > @@ -691,10 +695,20 @@ static struct msm_display_topology dpu_encoder_get_topology(
> > * 2 DSC encoders, 2 layer mixers and 1 interface
> > * this is power optimal and can drive up to (including) 4k
> > * screens
> > + * But for dual display case, we prefer 4 layer mixers. Because
> > + * the resolution is always high in the case and 4 DSCs are more
> > + * power optimal.
> > */
> > - topology.num_dsc = 2;
> > - topology.num_lm = 2;
> > - topology.num_intf = 1;
> > +
> > + if (intf_count == 2) {
> > + topology.num_dsc = 4;
> > + topology.num_lm = 4;
> > + topology.num_intf = 2;
> > + } else {
> > + topology.num_dsc = 2;
> > + topology.num_lm = 2;
> > + topology.num_intf = 1;
>
> Why is it only enabled for the DSC case? Also I'd like to point out
> platforms like sm7150 or msm8998 which have only 2 DSC blocks. The
> condition here needs more work to work with those platforms too.
Because the DSC + quad-pipe is assumed with wide LCD case that dual
pipe can not handle due to width limitation. If DSC is not involved, the
resolution is not too big to involve DSC together with 2 interfaces. Do you
think there is need to support quad-pipe without DSC?
Of course, it is a valid case to use 2 DSC with 2 interfaces. Below logic shall
be better.
if (intf_count == 2) {
topology.num_dsc = dpu_kms->catalog->dsc_count >= 4 ? 4 : 2;
topology.num_lm = topology.num_dsc;
topology.num_intf = 2;
} else {
topology.num_dsc = 2;
topology.num_lm = 2;
topology.num_intf = 1;
}
>
> > + }
> > }
> >
> > return topology;
> > @@ -2195,8 +2209,8 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
> > struct dpu_hw_mixer_cfg mixer;
> > int i, num_lm;
> > struct dpu_global_state *global_state;
> > - struct dpu_hw_blk *hw_lm[2];
> > - struct dpu_hw_mixer *hw_mixer[2];
> > + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
> > + struct dpu_hw_mixer *hw_mixer[MAX_CHANNELS_PER_ENC];
> > struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
> >
> > memset(&mixer, 0, sizeof(mixer));
> > 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 63f09857025c2..d378a990cc0fb 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> > @@ -302,7 +302,8 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
> >
> > /* Use merge_3d unless DSC MERGE topology is used */
> > if (phys_enc->split_role == ENC_ROLE_SOLO &&
> > - dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
> > + (dpu_cstate->num_mixers == CRTC_DUAL_MIXERS ||
> > + dpu_cstate->num_mixers == CRTC_QUAD_MIXERS) &&
>
> Misaligned. Also isn't it enough to check that num_mixers != 1?
Yeah, num_mixers != 1 should work.
>
> > !dpu_encoder_use_dsc_merge(phys_enc->parent))
> > return BLEND_3D_H_ROW_INT;
> >
> > 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 3ab79092a7f25..d9cc84b081b1f 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> > @@ -25,6 +25,7 @@
> > #define DPU_MAX_IMG_HEIGHT 0x3fff
> >
> > #define CRTC_DUAL_MIXERS 2
>
> Do we still need this define?
>
> > +#define CRTC_QUAD_MIXERS 4
> >
> > #define MAX_XIN_COUNT 16
> >
> > 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 27ef0771da5d2..1fe21087a141a 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > @@ -33,8 +33,8 @@
> > #endif
> >
> > #define STAGES_PER_PLANE 2
> > -#define PIPES_PER_PLANE 2
> > #define PIPES_PER_STAGE 2
> > +#define PIPES_PER_PLANE (STAGES_PER_PLANE * STAGES_PER_PLANE)
>
> This is incorrect.
>
> > #ifndef DPU_MAX_DE_CURVES
> > #define DPU_MAX_DE_CURVES 3
> > #endif
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index 57ccb73c45683..b5c1ad2a75594 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -1474,7 +1474,7 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
> > trace_dpu_plane_disable(DRMID(plane), false,
> > pstate->pipe[i].multirect_mode);
> >
> > - if (pipe->sspp && i == 1) {
> > + if (pipe->sspp && pipe->multirect_index == DPU_SSPP_RECT_1) {
>
> Separate change, please. Also I'm not sure how does that work with the
> shared SSPP case that I pointed to in one of the previous replies.
Maybe we can add a peer member in the pipe to reference each other, then we have
chance to use multirect across all pipes in all planes.
>
> > pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> > pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> >
> >
> > --
> > 2.34.1
> >
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case
2025-01-03 15:49 ` Jun Nie
@ 2025-01-03 17:51 ` Dmitry Baryshkov
2025-01-06 8:21 ` Jun Nie
0 siblings, 1 reply; 43+ messages in thread
From: Dmitry Baryshkov @ 2025-01-03 17:51 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Fri, Jan 03, 2025 at 11:49:07PM +0800, Jun Nie wrote:
> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 于2024年12月20日周五 07:46写道:
> >
> > On Thu, Dec 19, 2024 at 03:49:33PM +0800, Jun Nie wrote:
> > > Request 4 mixers and 4 DSC for the case that both dual-DSI and DSC are
> > > enabled. We prefer to use 4 pipes for dual DSI case for it is power optimal
> > > for DSC.
> > >
> > > Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > > ---
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++---
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 28 ++++++++++++++++++------
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 ++-
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +-
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +-
> > > 7 files changed, 30 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > index bad75af4e50ab..3c51c199f3e05 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > @@ -200,7 +200,7 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc,
> > > struct dpu_crtc_state *crtc_state)
> > > {
> > > struct dpu_crtc_mixer *m;
> > > - u32 crcs[CRTC_DUAL_MIXERS];
> > > + u32 crcs[CRTC_QUAD_MIXERS];
> > >
> > > int rc = 0;
> > > int i;
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > index d1bb3f84fe440..ce41fb364f3db 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > @@ -210,7 +210,7 @@ struct dpu_crtc_state {
> > >
> > > bool bw_control;
> > > bool bw_split_vote;
> > > - struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
> > > + struct drm_rect lm_bounds[CRTC_QUAD_MIXERS];
> > >
> > > uint64_t input_fence_timeout_ns;
> > >
> > > @@ -218,10 +218,10 @@ struct dpu_crtc_state {
> > >
> > > /* HW Resources reserved for the crtc */
> > > u32 num_mixers;
> > > - struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
> > > + struct dpu_crtc_mixer mixers[CRTC_QUAD_MIXERS];
> > >
> > > u32 num_ctls;
> > > - struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
> > > + struct dpu_hw_ctl *hw_ctls[CRTC_QUAD_MIXERS];
> > >
> > > enum dpu_crtc_crc_source crc_source;
> > > int crc_frame_skip_count;
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > > index 96d06db3e4be5..6e54ddeaffacd 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > > @@ -54,7 +54,7 @@
> > > #define MAX_PHYS_ENCODERS_PER_VIRTUAL \
> > > (MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
> > >
> > > -#define MAX_CHANNELS_PER_ENC 2
> > > +#define MAX_CHANNELS_PER_ENC 4
> > >
> > > #define IDLE_SHORT_TIMEOUT 1
> > >
> > > @@ -664,15 +664,19 @@ static struct msm_display_topology dpu_encoder_get_topology(
> > >
> > > /* Datapath topology selection
> > > *
> > > - * Dual display
> > > + * Dual display without DSC
> > > * 2 LM, 2 INTF ( Split display using 2 interfaces)
> > > *
> > > + * Dual display with DSC
> > > + * 4 LM, 2 INTF ( Split display using 2 interfaces)
> > > + *
> > > * Single display
> > > * 1 LM, 1 INTF
> > > * 2 LM, 1 INTF (stream merge to support high resolution interfaces)
> > > *
> > > * Add dspps to the reservation requirements if ctm is requested
> > > */
> > > +
> > > if (intf_count == 2)
> > > topology.num_lm = 2;
> > > else if (!dpu_kms->catalog->caps->has_3d_merge)
> > > @@ -691,10 +695,20 @@ static struct msm_display_topology dpu_encoder_get_topology(
> > > * 2 DSC encoders, 2 layer mixers and 1 interface
> > > * this is power optimal and can drive up to (including) 4k
> > > * screens
> > > + * But for dual display case, we prefer 4 layer mixers. Because
> > > + * the resolution is always high in the case and 4 DSCs are more
> > > + * power optimal.
> > > */
> > > - topology.num_dsc = 2;
> > > - topology.num_lm = 2;
> > > - topology.num_intf = 1;
> > > +
> > > + if (intf_count == 2) {
> > > + topology.num_dsc = 4;
> > > + topology.num_lm = 4;
> > > + topology.num_intf = 2;
> > > + } else {
> > > + topology.num_dsc = 2;
> > > + topology.num_lm = 2;
> > > + topology.num_intf = 1;
> >
> > Why is it only enabled for the DSC case? Also I'd like to point out
> > platforms like sm7150 or msm8998 which have only 2 DSC blocks. The
> > condition here needs more work to work with those platforms too.
>
> Because the DSC + quad-pipe is assumed with wide LCD case that dual
> pipe can not handle due to width limitation. If DSC is not involved, the
> resolution is not too big to involve DSC together with 2 interfaces. Do you
> think there is need to support quad-pipe without DSC?
Yes, of course. The same logic: ultra wide resolutions. If two LMs are
not enough for the panel / monitor.
>
> Of course, it is a valid case to use 2 DSC with 2 interfaces. Below logic shall
> be better.
>
> if (intf_count == 2) {
> topology.num_dsc = dpu_kms->catalog->dsc_count >= 4 ? 4 : 2;
> topology.num_lm = topology.num_dsc;
> topology.num_intf = 2;
> } else {
> topology.num_dsc = 2;
> topology.num_lm = 2;
> topology.num_intf = 1;
> }
It all starts to look like a collection of use-case quirks. But indeed,
it should work.
>
> >
> > > + }
> > > }
> > >
> > > return topology;
> > > @@ -2195,8 +2209,8 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
> > > struct dpu_hw_mixer_cfg mixer;
> > > int i, num_lm;
> > > struct dpu_global_state *global_state;
> > > - struct dpu_hw_blk *hw_lm[2];
> > > - struct dpu_hw_mixer *hw_mixer[2];
> > > + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
> > > + struct dpu_hw_mixer *hw_mixer[MAX_CHANNELS_PER_ENC];
> > > struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
> > >
> > > memset(&mixer, 0, sizeof(mixer));
> > > 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 63f09857025c2..d378a990cc0fb 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> > > @@ -302,7 +302,8 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
> > >
> > > /* Use merge_3d unless DSC MERGE topology is used */
> > > if (phys_enc->split_role == ENC_ROLE_SOLO &&
> > > - dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
> > > + (dpu_cstate->num_mixers == CRTC_DUAL_MIXERS ||
> > > + dpu_cstate->num_mixers == CRTC_QUAD_MIXERS) &&
> >
> > Misaligned. Also isn't it enough to check that num_mixers != 1?
>
> Yeah, num_mixers != 1 should work.
> >
> > > !dpu_encoder_use_dsc_merge(phys_enc->parent))
> > > return BLEND_3D_H_ROW_INT;
> > >
> > > 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 3ab79092a7f25..d9cc84b081b1f 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> > > @@ -25,6 +25,7 @@
> > > #define DPU_MAX_IMG_HEIGHT 0x3fff
> > >
> > > #define CRTC_DUAL_MIXERS 2
> >
> > Do we still need this define?
> >
> > > +#define CRTC_QUAD_MIXERS 4
> > >
> > > #define MAX_XIN_COUNT 16
> > >
> > > 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 27ef0771da5d2..1fe21087a141a 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > > @@ -33,8 +33,8 @@
> > > #endif
> > >
> > > #define STAGES_PER_PLANE 2
> > > -#define PIPES_PER_PLANE 2
> > > #define PIPES_PER_STAGE 2
> > > +#define PIPES_PER_PLANE (STAGES_PER_PLANE * STAGES_PER_PLANE)
> >
> > This is incorrect.
> >
> > > #ifndef DPU_MAX_DE_CURVES
> > > #define DPU_MAX_DE_CURVES 3
> > > #endif
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > index 57ccb73c45683..b5c1ad2a75594 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > @@ -1474,7 +1474,7 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
> > > trace_dpu_plane_disable(DRMID(plane), false,
> > > pstate->pipe[i].multirect_mode);
> > >
> > > - if (pipe->sspp && i == 1) {
> > > + if (pipe->sspp && pipe->multirect_index == DPU_SSPP_RECT_1) {
> >
> > Separate change, please. Also I'm not sure how does that work with the
> > shared SSPP case that I pointed to in one of the previous replies.
>
> Maybe we can add a peer member in the pipe to reference each other, then we have
> chance to use multirect across all pipes in all planes.
I'd rather not. We have pairs of pipes. I'd rather see the code stay the
same way: processing one pair at the same time.
>
>
> >
> > > pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> > > pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> > >
> > >
> > > --
> > > 2.34.1
> > >
> >
> > --
> > With best wishes
> > Dmitry
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case
2025-01-03 17:51 ` Dmitry Baryshkov
@ 2025-01-06 8:21 ` Jun Nie
2025-01-07 22:25 ` Dmitry Baryshkov
0 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2025-01-06 8:21 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 于2025年1月4日周六 01:51写道:
>
> On Fri, Jan 03, 2025 at 11:49:07PM +0800, Jun Nie wrote:
> > Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 于2024年12月20日周五 07:46写道:
> > >
> > > On Thu, Dec 19, 2024 at 03:49:33PM +0800, Jun Nie wrote:
> > > > Request 4 mixers and 4 DSC for the case that both dual-DSI and DSC are
> > > > enabled. We prefer to use 4 pipes for dual DSI case for it is power optimal
> > > > for DSC.
> > > >
> > > > Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > > > ---
> > > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
> > > > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++---
> > > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 28 ++++++++++++++++++------
> > > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 ++-
> > > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
> > > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 2 +-
> > > > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +-
> > > > 7 files changed, 30 insertions(+), 14 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > > index bad75af4e50ab..3c51c199f3e05 100644
> > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > > @@ -200,7 +200,7 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc,
> > > > struct dpu_crtc_state *crtc_state)
> > > > {
> > > > struct dpu_crtc_mixer *m;
> > > > - u32 crcs[CRTC_DUAL_MIXERS];
> > > > + u32 crcs[CRTC_QUAD_MIXERS];
> > > >
> > > > int rc = 0;
> > > > int i;
> > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > > index d1bb3f84fe440..ce41fb364f3db 100644
> > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > > @@ -210,7 +210,7 @@ struct dpu_crtc_state {
> > > >
> > > > bool bw_control;
> > > > bool bw_split_vote;
> > > > - struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
> > > > + struct drm_rect lm_bounds[CRTC_QUAD_MIXERS];
> > > >
> > > > uint64_t input_fence_timeout_ns;
> > > >
> > > > @@ -218,10 +218,10 @@ struct dpu_crtc_state {
> > > >
> > > > /* HW Resources reserved for the crtc */
> > > > u32 num_mixers;
> > > > - struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
> > > > + struct dpu_crtc_mixer mixers[CRTC_QUAD_MIXERS];
> > > >
> > > > u32 num_ctls;
> > > > - struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
> > > > + struct dpu_hw_ctl *hw_ctls[CRTC_QUAD_MIXERS];
> > > >
> > > > enum dpu_crtc_crc_source crc_source;
> > > > int crc_frame_skip_count;
> > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > > > index 96d06db3e4be5..6e54ddeaffacd 100644
> > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > > > @@ -54,7 +54,7 @@
> > > > #define MAX_PHYS_ENCODERS_PER_VIRTUAL \
> > > > (MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
> > > >
> > > > -#define MAX_CHANNELS_PER_ENC 2
> > > > +#define MAX_CHANNELS_PER_ENC 4
> > > >
> > > > #define IDLE_SHORT_TIMEOUT 1
> > > >
> > > > @@ -664,15 +664,19 @@ static struct msm_display_topology dpu_encoder_get_topology(
> > > >
> > > > /* Datapath topology selection
> > > > *
> > > > - * Dual display
> > > > + * Dual display without DSC
> > > > * 2 LM, 2 INTF ( Split display using 2 interfaces)
> > > > *
> > > > + * Dual display with DSC
> > > > + * 4 LM, 2 INTF ( Split display using 2 interfaces)
> > > > + *
> > > > * Single display
> > > > * 1 LM, 1 INTF
> > > > * 2 LM, 1 INTF (stream merge to support high resolution interfaces)
> > > > *
> > > > * Add dspps to the reservation requirements if ctm is requested
> > > > */
> > > > +
> > > > if (intf_count == 2)
> > > > topology.num_lm = 2;
> > > > else if (!dpu_kms->catalog->caps->has_3d_merge)
> > > > @@ -691,10 +695,20 @@ static struct msm_display_topology dpu_encoder_get_topology(
> > > > * 2 DSC encoders, 2 layer mixers and 1 interface
> > > > * this is power optimal and can drive up to (including) 4k
> > > > * screens
> > > > + * But for dual display case, we prefer 4 layer mixers. Because
> > > > + * the resolution is always high in the case and 4 DSCs are more
> > > > + * power optimal.
> > > > */
> > > > - topology.num_dsc = 2;
> > > > - topology.num_lm = 2;
> > > > - topology.num_intf = 1;
> > > > +
> > > > + if (intf_count == 2) {
> > > > + topology.num_dsc = 4;
> > > > + topology.num_lm = 4;
> > > > + topology.num_intf = 2;
> > > > + } else {
> > > > + topology.num_dsc = 2;
> > > > + topology.num_lm = 2;
> > > > + topology.num_intf = 1;
> > >
> > > Why is it only enabled for the DSC case? Also I'd like to point out
> > > platforms like sm7150 or msm8998 which have only 2 DSC blocks. The
> > > condition here needs more work to work with those platforms too.
> >
> > Because the DSC + quad-pipe is assumed with wide LCD case that dual
> > pipe can not handle due to width limitation. If DSC is not involved, the
> > resolution is not too big to involve DSC together with 2 interfaces. Do you
> > think there is need to support quad-pipe without DSC?
>
> Yes, of course. The same logic: ultra wide resolutions. If two LMs are
> not enough for the panel / monitor.
>
> >
> > Of course, it is a valid case to use 2 DSC with 2 interfaces. Below logic shall
> > be better.
> >
> > if (intf_count == 2) {
> > topology.num_dsc = dpu_kms->catalog->dsc_count >= 4 ? 4 : 2;
> > topology.num_lm = topology.num_dsc;
> > topology.num_intf = 2;
> > } else {
> > topology.num_dsc = 2;
> > topology.num_lm = 2;
> > topology.num_intf = 1;
> > }
>
> It all starts to look like a collection of use-case quirks. But indeed,
> it should work.
>
> >
> > >
> > > > + }
> > > > }
> > > >
> > > > return topology;
> > > > @@ -2195,8 +2209,8 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
> > > > struct dpu_hw_mixer_cfg mixer;
> > > > int i, num_lm;
> > > > struct dpu_global_state *global_state;
> > > > - struct dpu_hw_blk *hw_lm[2];
> > > > - struct dpu_hw_mixer *hw_mixer[2];
> > > > + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
> > > > + struct dpu_hw_mixer *hw_mixer[MAX_CHANNELS_PER_ENC];
> > > > struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
> > > >
> > > > memset(&mixer, 0, sizeof(mixer));
> > > > 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 63f09857025c2..d378a990cc0fb 100644
> > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> > > > @@ -302,7 +302,8 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
> > > >
> > > > /* Use merge_3d unless DSC MERGE topology is used */
> > > > if (phys_enc->split_role == ENC_ROLE_SOLO &&
> > > > - dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
> > > > + (dpu_cstate->num_mixers == CRTC_DUAL_MIXERS ||
> > > > + dpu_cstate->num_mixers == CRTC_QUAD_MIXERS) &&
> > >
> > > Misaligned. Also isn't it enough to check that num_mixers != 1?
> >
> > Yeah, num_mixers != 1 should work.
> > >
> > > > !dpu_encoder_use_dsc_merge(phys_enc->parent))
> > > > return BLEND_3D_H_ROW_INT;
> > > >
> > > > 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 3ab79092a7f25..d9cc84b081b1f 100644
> > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> > > > @@ -25,6 +25,7 @@
> > > > #define DPU_MAX_IMG_HEIGHT 0x3fff
> > > >
> > > > #define CRTC_DUAL_MIXERS 2
> > >
> > > Do we still need this define?
> > >
> > > > +#define CRTC_QUAD_MIXERS 4
> > > >
> > > > #define MAX_XIN_COUNT 16
> > > >
> > > > 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 27ef0771da5d2..1fe21087a141a 100644
> > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > > > @@ -33,8 +33,8 @@
> > > > #endif
> > > >
> > > > #define STAGES_PER_PLANE 2
> > > > -#define PIPES_PER_PLANE 2
> > > > #define PIPES_PER_STAGE 2
> > > > +#define PIPES_PER_PLANE (STAGES_PER_PLANE * STAGES_PER_PLANE)
> > >
> > > This is incorrect.
> > >
> > > > #ifndef DPU_MAX_DE_CURVES
> > > > #define DPU_MAX_DE_CURVES 3
> > > > #endif
> > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > > index 57ccb73c45683..b5c1ad2a75594 100644
> > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > > @@ -1474,7 +1474,7 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
> > > > trace_dpu_plane_disable(DRMID(plane), false,
> > > > pstate->pipe[i].multirect_mode);
> > > >
> > > > - if (pipe->sspp && i == 1) {
> > > > + if (pipe->sspp && pipe->multirect_index == DPU_SSPP_RECT_1) {
> > >
> > > Separate change, please. Also I'm not sure how does that work with the
> > > shared SSPP case that I pointed to in one of the previous replies.
> >
> > Maybe we can add a peer member in the pipe to reference each other, then we have
> > chance to use multirect across all pipes in all planes.
>
> I'd rather not. We have pairs of pipes. I'd rather see the code stay the
> same way: processing one pair at the same time.
I mean only use the peer only when the SSPP multi-rect pips cross
planes. This shall not change
too much to current SSPP management.
>
> >
> >
> > >
> > > > pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> > > > pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> > > >
> > > >
> > > > --
> > > > 2.34.1
> > > >
> > >
> > > --
> > > With best wishes
> > > Dmitry
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case
2025-01-06 8:21 ` Jun Nie
@ 2025-01-07 22:25 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2025-01-07 22:25 UTC (permalink / raw)
To: Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On Mon, Jan 06, 2025 at 04:21:43PM +0800, Jun Nie wrote:
> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 于2025年1月4日周六 01:51写道:
> >
> > On Fri, Jan 03, 2025 at 11:49:07PM +0800, Jun Nie wrote:
> > > Dmitry Baryshkov <dmitry.baryshkov@linaro.org> 于2024年12月20日周五 07:46写道:
> > > >
> > > > On Thu, Dec 19, 2024 at 03:49:33PM +0800, Jun Nie wrote:
> > > >
> > > > > #ifndef DPU_MAX_DE_CURVES
> > > > > #define DPU_MAX_DE_CURVES 3
> > > > > #endif
> > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > > > index 57ccb73c45683..b5c1ad2a75594 100644
> > > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > > > @@ -1474,7 +1474,7 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
> > > > > trace_dpu_plane_disable(DRMID(plane), false,
> > > > > pstate->pipe[i].multirect_mode);
> > > > >
> > > > > - if (pipe->sspp && i == 1) {
> > > > > + if (pipe->sspp && pipe->multirect_index == DPU_SSPP_RECT_1) {
> > > >
> > > > Separate change, please. Also I'm not sure how does that work with the
> > > > shared SSPP case that I pointed to in one of the previous replies.
> > >
> > > Maybe we can add a peer member in the pipe to reference each other, then we have
> > > chance to use multirect across all pipes in all planes.
> >
> > I'd rather not. We have pairs of pipes. I'd rather see the code stay the
> > same way: processing one pair at the same time.
>
> I mean only use the peer only when the SSPP multi-rect pips cross
> planes. This shall not change
> too much to current SSPP management.
Still no. Please please don't add extra 'peer' member. There should be
no need to have one.
> >
> > >
> > >
> > > >
> > > > > pipe->multirect_index = DPU_SSPP_RECT_SOLO;
> > > > > pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> > > > >
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 04/15] drm/msm/dpu: decide right side per last bit
2024-12-19 22:09 ` Dmitry Baryshkov
@ 2025-01-08 23:41 ` Jessica Zhang
2025-01-09 4:35 ` Jun Nie
0 siblings, 1 reply; 43+ messages in thread
From: Jessica Zhang @ 2025-01-08 23:41 UTC (permalink / raw)
To: Dmitry Baryshkov, Jun Nie
Cc: Rob Clark, Abhinav Kumar, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, linux-arm-msm, dri-devel, freedreno, linux-kernel
On 12/19/2024 2:09 PM, Dmitry Baryshkov wrote:
> On Thu, Dec 19, 2024 at 03:49:22PM +0800, Jun Nie wrote:
>> decide right side of a pair per last bit, in case of multiple
>> mixer pairs.
>
> Proper English sentences, please. Also describe why, not what.
Hi Jun,
Can we also add a note in the commit message on why the last bit check
works?
Thanks,
Jessica Zhang
>
>>
>> Signed-off-by: Jun Nie <jun.nie@linaro.org>
>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++---
>> 1 file changed, 2 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index 7191b1a6d41b3..41c9d3e3e3c7c 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -369,11 +369,10 @@ static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer,
>> static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>> {
>> struct dpu_crtc_state *crtc_state;
>> - int lm_idx, lm_horiz_position;
>> + int lm_idx;
>>
>> crtc_state = to_dpu_crtc_state(crtc->state);
>>
>> - lm_horiz_position = 0;
>> for (lm_idx = 0; lm_idx < crtc_state->num_mixers; lm_idx++) {
>> const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
>> struct dpu_hw_mixer *hw_lm = crtc_state->mixers[lm_idx].hw_lm;
>> @@ -384,7 +383,7 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>>
>> cfg.out_width = drm_rect_width(lm_roi);
>> cfg.out_height = drm_rect_height(lm_roi);
>> - cfg.right_mixer = lm_horiz_position++;
>> + cfg.right_mixer = lm_idx & 0x1;
>> cfg.flags = 0;
>> hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
>> }
>>
>> --
>> 2.34.1
>>
>
> --
> With best wishes
> Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation
2024-12-19 7:49 ` [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation Jun Nie
2024-12-19 22:14 ` Dmitry Baryshkov
@ 2025-01-09 1:29 ` Jessica Zhang
2025-01-09 4:40 ` Jun Nie
1 sibling, 1 reply; 43+ messages in thread
From: Jessica Zhang @ 2025-01-09 1:29 UTC (permalink / raw)
To: Jun Nie, Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel
On 12/18/2024 11:49 PM, Jun Nie wrote:
> Add the case to reserve multiple pairs mixers for high resolution.
> Current code only supports one pair of mixer usage case. To support
> quad-pipe usage case, two pairs of mixers are needed.
>
> Current code resets number of mixer on failure of pair's peer test and
> retry on another pair. If two pairs are needed, the failure on the test
> of 2nd pair results clearing to the 1st pair. This patch only clear the
> bit for the 2nd pair allocation before retry on another pair.
Hi Jun,
I think the commit message wording is a bit unclear. Maybe something
like "Reset the current lm_count to an even number instead of completely
clearing it. This prevents all pairs from being cleared in cases where
multiple LM pairs are needed"
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index cde3c5616f9bc..a8b01b78c02c7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -316,7 +316,11 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
> if (!rm->mixer_blks[i])
> continue;
>
> - lm_count = 0;
> + /*
> + * Clear the last bit to drop the previous primary mixer if
> + * fail to find its peer.
Same here can we reword it to something like "Reset lm_count to an even
index. This will drop the previous primary mixer if ..."
> + */
> + lm_count &= 0xfe;
Nit: Can we directly clear the first bit instead of doing an 8-bit bitmask?
Thanks,
Jessica Zhang
> lm_idx[lm_count] = i;
>
> if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 04/15] drm/msm/dpu: decide right side per last bit
2025-01-08 23:41 ` Jessica Zhang
@ 2025-01-09 4:35 ` Jun Nie
2025-01-09 12:14 ` Dmitry Baryshkov
0 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2025-01-09 4:35 UTC (permalink / raw)
To: Jessica Zhang
Cc: Dmitry Baryshkov, Rob Clark, Abhinav Kumar, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm,
dri-devel, freedreno, linux-kernel
Jessica Zhang <quic_jesszhan@quicinc.com> 于2025年1月9日周四 07:41写道:
>
>
>
> On 12/19/2024 2:09 PM, Dmitry Baryshkov wrote:
> > On Thu, Dec 19, 2024 at 03:49:22PM +0800, Jun Nie wrote:
> >> decide right side of a pair per last bit, in case of multiple
> >> mixer pairs.
> >
> > Proper English sentences, please. Also describe why, not what.
>
> Hi Jun,
>
> Can we also add a note in the commit message on why the last bit check
> works?
Sure. How about this?
Currently we only support one pair of mixer, so counter's
non-zero value is enough to mark the right one. There will
be case with multiple mixer pairs, so let's use the last bit to
mark the right mixer in a mixer pair. If the last bit is set, it
marks the right mixer in the pair, it's left mixer otherwise.
>
> Thanks,
>
> Jessica Zhang
>
> >
> >>
> >> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> >> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >> ---
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++---
> >> 1 file changed, 2 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >> index 7191b1a6d41b3..41c9d3e3e3c7c 100644
> >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >> @@ -369,11 +369,10 @@ static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer,
> >> static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
> >> {
> >> struct dpu_crtc_state *crtc_state;
> >> - int lm_idx, lm_horiz_position;
> >> + int lm_idx;
> >>
> >> crtc_state = to_dpu_crtc_state(crtc->state);
> >>
> >> - lm_horiz_position = 0;
> >> for (lm_idx = 0; lm_idx < crtc_state->num_mixers; lm_idx++) {
> >> const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
> >> struct dpu_hw_mixer *hw_lm = crtc_state->mixers[lm_idx].hw_lm;
> >> @@ -384,7 +383,7 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
> >>
> >> cfg.out_width = drm_rect_width(lm_roi);
> >> cfg.out_height = drm_rect_height(lm_roi);
> >> - cfg.right_mixer = lm_horiz_position++;
> >> + cfg.right_mixer = lm_idx & 0x1;
> >> cfg.flags = 0;
> >> hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
> >> }
> >>
> >> --
> >> 2.34.1
> >>
> >
> > --
> > With best wishes
> > Dmitry
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation
2025-01-09 1:29 ` Jessica Zhang
@ 2025-01-09 4:40 ` Jun Nie
2025-01-09 12:15 ` Dmitry Baryshkov
0 siblings, 1 reply; 43+ messages in thread
From: Jun Nie @ 2025-01-09 4:40 UTC (permalink / raw)
To: Jessica Zhang
Cc: Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm,
dri-devel, freedreno, linux-kernel
Jessica Zhang <quic_jesszhan@quicinc.com> 于2025年1月9日周四 09:29写道:
>
>
>
> On 12/18/2024 11:49 PM, Jun Nie wrote:
> > Add the case to reserve multiple pairs mixers for high resolution.
> > Current code only supports one pair of mixer usage case. To support
> > quad-pipe usage case, two pairs of mixers are needed.
> >
> > Current code resets number of mixer on failure of pair's peer test and
> > retry on another pair. If two pairs are needed, the failure on the test
> > of 2nd pair results clearing to the 1st pair. This patch only clear the
> > bit for the 2nd pair allocation before retry on another pair.
>
> Hi Jun,
>
> I think the commit message wording is a bit unclear. Maybe something
> like "Reset the current lm_count to an even number instead of completely
> clearing it. This prevents all pairs from being cleared in cases where
> multiple LM pairs are needed"
Thanks for the suggestion! Will adopt it.
>
> >
> > Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > ---
> > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 6 +++++-
> > 1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > index cde3c5616f9bc..a8b01b78c02c7 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > @@ -316,7 +316,11 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
> > if (!rm->mixer_blks[i])
> > continue;
> >
> > - lm_count = 0;
> > + /*
> > + * Clear the last bit to drop the previous primary mixer if
> > + * fail to find its peer.
>
> Same here can we reword it to something like "Reset lm_count to an even
> index. This will drop the previous primary mixer if ..."
Will do.
>
> > + */
> > + lm_count &= 0xfe;
>
> Nit: Can we directly clear the first bit instead of doing an 8-bit bitmask?
Could you elaborate on it? Or you are suggesting to mask 0xFFFFFFFE?
- Jun
>
> Thanks,
>
> Jessica Zhang
>
> > lm_idx[lm_count] = i;
> >
> > if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
> >
> > --
> > 2.34.1
> >
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 04/15] drm/msm/dpu: decide right side per last bit
2025-01-09 4:35 ` Jun Nie
@ 2025-01-09 12:14 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2025-01-09 12:14 UTC (permalink / raw)
To: Jun Nie
Cc: Jessica Zhang, Rob Clark, Abhinav Kumar, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm,
dri-devel, freedreno, linux-kernel
On Thu, Jan 09, 2025 at 12:35:48PM +0800, Jun Nie wrote:
> Jessica Zhang <quic_jesszhan@quicinc.com> 于2025年1月9日周四 07:41写道:
> >
> >
> >
> > On 12/19/2024 2:09 PM, Dmitry Baryshkov wrote:
> > > On Thu, Dec 19, 2024 at 03:49:22PM +0800, Jun Nie wrote:
> > >> decide right side of a pair per last bit, in case of multiple
> > >> mixer pairs.
> > >
> > > Proper English sentences, please. Also describe why, not what.
> >
> > Hi Jun,
> >
> > Can we also add a note in the commit message on why the last bit check
> > works?
>
> Sure. How about this?
>
> Currently we only support one pair of mixer, so counter's
> non-zero value is enough to mark the right one. There will
> be case with multiple mixer pairs, so let's use the last bit to
> mark the right mixer in a mixer pair. If the last bit is set, it
> marks the right mixer in the pair, it's left mixer otherwise.
You are not marking the right mixer, so it is not suitable.
>
> >
> > Thanks,
> >
> > Jessica Zhang
> >
> > >
> > >>
> > >> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > >> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > >> ---
> > >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++---
> > >> 1 file changed, 2 insertions(+), 3 deletions(-)
> > >>
> > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > >> index 7191b1a6d41b3..41c9d3e3e3c7c 100644
> > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > >> @@ -369,11 +369,10 @@ static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer,
> > >> static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
> > >> {
> > >> struct dpu_crtc_state *crtc_state;
> > >> - int lm_idx, lm_horiz_position;
> > >> + int lm_idx;
> > >>
> > >> crtc_state = to_dpu_crtc_state(crtc->state);
> > >>
> > >> - lm_horiz_position = 0;
> > >> for (lm_idx = 0; lm_idx < crtc_state->num_mixers; lm_idx++) {
> > >> const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
> > >> struct dpu_hw_mixer *hw_lm = crtc_state->mixers[lm_idx].hw_lm;
> > >> @@ -384,7 +383,7 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
> > >>
> > >> cfg.out_width = drm_rect_width(lm_roi);
> > >> cfg.out_height = drm_rect_height(lm_roi);
> > >> - cfg.right_mixer = lm_horiz_position++;
> > >> + cfg.right_mixer = lm_idx & 0x1;
> > >> cfg.flags = 0;
> > >> hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
> > >> }
> > >>
> > >> --
> > >> 2.34.1
> > >>
> > >
> > > --
> > > With best wishes
> > > Dmitry
> >
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation
2025-01-09 4:40 ` Jun Nie
@ 2025-01-09 12:15 ` Dmitry Baryshkov
0 siblings, 0 replies; 43+ messages in thread
From: Dmitry Baryshkov @ 2025-01-09 12:15 UTC (permalink / raw)
To: Jun Nie
Cc: Jessica Zhang, Rob Clark, Abhinav Kumar, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter, linux-arm-msm,
dri-devel, freedreno, linux-kernel
On Thu, Jan 09, 2025 at 12:40:23PM +0800, Jun Nie wrote:
> Jessica Zhang <quic_jesszhan@quicinc.com> 于2025年1月9日周四 09:29写道:
> >
> >
> >
> > On 12/18/2024 11:49 PM, Jun Nie wrote:
> > > Add the case to reserve multiple pairs mixers for high resolution.
> > > Current code only supports one pair of mixer usage case. To support
> > > quad-pipe usage case, two pairs of mixers are needed.
> > >
> > > Current code resets number of mixer on failure of pair's peer test and
> > > retry on another pair. If two pairs are needed, the failure on the test
> > > of 2nd pair results clearing to the 1st pair. This patch only clear the
> > > bit for the 2nd pair allocation before retry on another pair.
> >
> > Hi Jun,
> >
> > I think the commit message wording is a bit unclear. Maybe something
> > like "Reset the current lm_count to an even number instead of completely
> > clearing it. This prevents all pairs from being cleared in cases where
> > multiple LM pairs are needed"
>
> Thanks for the suggestion! Will adopt it.
> >
> > >
> > > Signed-off-by: Jun Nie <jun.nie@linaro.org>
> > > ---
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 6 +++++-
> > > 1 file changed, 5 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > > index cde3c5616f9bc..a8b01b78c02c7 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > > @@ -316,7 +316,11 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
> > > if (!rm->mixer_blks[i])
> > > continue;
> > >
> > > - lm_count = 0;
> > > + /*
> > > + * Clear the last bit to drop the previous primary mixer if
> > > + * fail to find its peer.
> >
> > Same here can we reword it to something like "Reset lm_count to an even
> > index. This will drop the previous primary mixer if ..."
>
> Will do.
>
> >
> > > + */
> > > + lm_count &= 0xfe;
> >
> > Nit: Can we directly clear the first bit instead of doing an 8-bit bitmask?
>
> Could you elaborate on it? Or you are suggesting to mask 0xFFFFFFFE?
I assume it is &= ~1
>
> - Jun
>
> >
> > Thanks,
> >
> > Jessica Zhang
> >
> > > lm_idx[lm_count] = i;
> > >
> > > if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
> > >
> > > --
> > > 2.34.1
> > >
> >
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [PATCH v3 07/15] drm/msm/dpu: bind correct pingpong for quad pipe
2024-12-19 7:49 ` [PATCH v3 07/15] drm/msm/dpu: bind correct pingpong for quad pipe Jun Nie
@ 2025-01-09 18:12 ` Jessica Zhang
0 siblings, 0 replies; 43+ messages in thread
From: Jessica Zhang @ 2025-01-09 18:12 UTC (permalink / raw)
To: Jun Nie, Rob Clark, Abhinav Kumar, Dmitry Baryshkov, Sean Paul,
Marijn Suijten, David Airlie, Simona Vetter
Cc: linux-arm-msm, dri-devel, freedreno, linux-kernel
On 12/18/2024 11:49 PM, Jun Nie wrote:
> There are 2 interfaces and 4 pingpong in quad pipe. Map the 2nd
> interface to 3rd PP instead of the 2nd PP.
>
> Signed-off-by: Jun Nie <jun.nie@linaro.org>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index fd32ef468d5f9..96d06db3e4be5 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -1220,7 +1220,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
> struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
> struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
> - int num_ctl, num_pp, num_dsc;
> + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
> + int num_lm, num_ctl, num_pp, num_dsc, num_pp_per_intf;
> unsigned int dsc_mask = 0;
> int i;
>
> @@ -1275,11 +1276,21 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
> dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
> }
>
> + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
> + drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
> +
> +
> + /*
> + * There may be 4 PP and 2 INTF for quad pipe case, so INTF is not
> + * mapped to PP 1:1. Let's calculate the stride with pipe/INTF
> + */
> + num_pp_per_intf = num_lm / dpu_enc->num_phys_encs;
> +
> for (i = 0; i < dpu_enc->num_phys_encs; i++) {
> struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
> struct dpu_hw_ctl *ctl0 = to_dpu_hw_ctl(hw_ctl[0]);
>
> - phys->hw_pp = dpu_enc->hw_pp[i];
> + phys->hw_pp = dpu_enc->hw_pp[num_pp_per_intf * i];
> if (!phys->hw_pp) {
> DPU_ERROR_ENC(dpu_enc,
> "no pp block assigned at idx: %d\n", i);
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2025-01-09 18:12 UTC | newest]
Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-19 7:49 [PATCH v3 00/15] (no cover subject) Jun Nie
2024-12-19 7:49 ` [PATCH v3 01/15] drm/msm/dpu: Do not fix number of DSC Jun Nie
2024-12-19 22:08 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 02/15] drm/msm/dpu: configure DSC per number in use Jun Nie
2024-12-19 22:06 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 03/15] drm/msm/dpu: polish log for resource allocation Jun Nie
2024-12-19 22:07 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 04/15] drm/msm/dpu: decide right side per last bit Jun Nie
2024-12-19 22:09 ` Dmitry Baryshkov
2025-01-08 23:41 ` Jessica Zhang
2025-01-09 4:35 ` Jun Nie
2025-01-09 12:14 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 05/15] drm/msm/dpu: fix mixer number counter on allocation Jun Nie
2024-12-19 22:14 ` Dmitry Baryshkov
2025-01-09 1:29 ` Jessica Zhang
2025-01-09 4:40 ` Jun Nie
2025-01-09 12:15 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 06/15] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation Jun Nie
2024-12-19 7:49 ` [PATCH v3 07/15] drm/msm/dpu: bind correct pingpong for quad pipe Jun Nie
2025-01-09 18:12 ` Jessica Zhang
2024-12-19 7:49 ` [PATCH v3 08/15] drm/msm/dpu: handle pipes as array Jun Nie
2024-12-19 22:26 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 09/15] drm/msm/dpu: split PIPES_PER_STAGE definition per plane and mixer Jun Nie
2024-12-19 22:28 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 10/15] drm/msm/dpu: Add pipe as trace argument Jun Nie
2024-12-19 22:29 ` Dmitry Baryshkov
2024-12-31 13:24 ` Jun Nie
2024-12-31 14:04 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 11/15] drm/msm/dpu: blend pipes per mixer pairs config Jun Nie
2024-12-19 22:40 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 12/15] drm/msm/dpu: support plane splitting in quad-pipe case Jun Nie
2024-12-19 23:16 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 13/15] drm/msm/dpu: Support quad-pipe in SSPP checking Jun Nie
2024-12-19 23:23 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 14/15] drm/msm/dpu: support SSPP assignment for quad-pipe case Jun Nie
2024-12-19 23:30 ` Dmitry Baryshkov
2024-12-19 7:49 ` [PATCH v3 15/15] drm/msm/dpu: Enable quad-pipe for DSC and dual-DSI case Jun Nie
2024-12-19 23:46 ` Dmitry Baryshkov
2025-01-03 15:49 ` Jun Nie
2025-01-03 17:51 ` Dmitry Baryshkov
2025-01-06 8:21 ` Jun Nie
2025-01-07 22:25 ` Dmitry Baryshkov
2024-12-19 7:53 ` [PATCH v3 00/15] drm/msm/dpu: Support quad pipe with dual-DSI Jun Nie
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).