lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240829-sm8650-v6-11-hmd-pocf-mdss-quad-upstream-8-v1-15-bdb05b4b5a2e@linaro.org>
Date: Thu, 29 Aug 2024 18:17:44 +0800
From: Jun Nie <jun.nie@...aro.org>
To: Rob Clark <robdclark@...il.com>, 
 Abhinav Kumar <quic_abhinavk@...cinc.com>, 
 Dmitry Baryshkov <dmitry.baryshkov@...aro.org>, Sean Paul <sean@...rly.run>, 
 Marijn Suijten <marijn.suijten@...ainline.org>, 
 David Airlie <airlied@...il.com>, Daniel Vetter <daniel@...ll.ch>, 
 Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>, 
 Maxime Ripard <mripard@...nel.org>, Thomas Zimmermann <tzimmermann@...e.de>
Cc: linux-arm-msm@...r.kernel.org, dri-devel@...ts.freedesktop.org, 
 freedreno@...ts.freedesktop.org, linux-kernel@...r.kernel.org, 
 Jun Nie <jun.nie@...aro.org>
Subject: [PATCH 15/21] drm/msm/dpu: support plane splitting in quad-pipe
 case

Clip plane into SSPPs per left and right half screen per ROI if topology
is quad pipe. Then split the split rectangle by half if the clip
width still exceed limit.

Signed-off-by: Jun Nie <jun.nie@...aro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 97 ++++++++++++++++++++++---------
 1 file changed, 71 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 78bf8f0292f62..95cb2575c63b4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -836,10 +836,12 @@ static int dpu_plane_atomic_check_nopipe(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 drm_rect fb_rect = { 0 };
+	const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 	uint32_t max_linewidth;
+	u32 lm_num;
+	int cfg_idx = 0, cfg_id, mixercfg_num;
 
 	min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO);
 	max_scale = MAX_DOWNSCALE_RATIO << 16;
@@ -862,10 +864,10 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane *plane,
 		return -EINVAL;
 	}
 
-	/* state->src is 16.16, src_rect is not */
-	drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
+	lm_num = dpu_crtc_get_lm_num(crtc_state);
 
-	pipe_cfg->dst_rect = new_plane_state->dst;
+	/* state->src is 16.16, src_rect is not */
+	drm_rect_fp_to_int(&pipe_cfg.src_rect, &new_plane_state->src);
 
 	fb_rect.x2 = new_plane_state->fb->width;
 	fb_rect.y2 = new_plane_state->fb->height;
@@ -880,34 +882,77 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane *plane,
 
 	max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-	drm_rect_rotate(&pipe_cfg->src_rect,
+	drm_rect_rotate(&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 cfg for 1:1:1 and 2:2:1 topology, 2 mixer configs
+	 * for left and right half screen in case of 4:4:2 topology.
+	 * But we may have 2 SSPP to split plane with 1 mixer config for 2:2:1.
+	 * So need to handle super wide plane splitting, and plane on right half
+	 * for dual-DSI case. Check dest rectangle left/right splitting
+	 * first, then check super wide rectangle splitting next.
+	 */
+	mixercfg_num = lm_num / 2;
+	mixercfg_num = mixercfg_num == 0 ? 1 : mixercfg_num;
+	/* iterate mixer configs for this plane, to separate left/right with the id */
+	for (cfg_id = 0; cfg_id < mixercfg_num; cfg_id++) {
+		struct drm_rect mixer_rect = {cfg_id * mode->hdisplay / mixercfg_num, 0,
+					(cfg_id + 1) * mode->hdisplay / mixercfg_num, mode->vdisplay};
+		struct dpu_sw_pipe_cfg *cur_cfg = &pstate->pipe_cfg[cfg_idx];
+
+		drm_rect_fp_to_int(&cur_cfg->src_rect, &new_plane_state->src);
+		cur_cfg->dst_rect = new_plane_state->dst;
+
+		DPU_DEBUG_PLANE(pdpu, "checking src " DRM_RECT_FMT " vs clip " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&cur_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(&cur_cfg->src_rect, &cur_cfg->dst_rect, &mixer_rect))
+			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));
-	}
+		cur_cfg->visible = true;
+		cur_cfg->mxcfg_id = cfg_id;
+		cur_cfg->dst_rect.x1 -= mixer_rect.x1;
+		cur_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(&cur_cfg->src_rect), DRM_RECT_ARG(&cur_cfg->dst_rect));
+
+		/* Split super wide rect into 2 rect */
+		if ((drm_rect_width(&cur_cfg->src_rect) > max_linewidth) ||
+		     _dpu_plane_calc_clk(mode, cur_cfg) > max_mdp_clk_rate) {
+			struct dpu_sw_pipe_cfg *next_cfg = &pstate->pipe_cfg[cfg_idx + 1];
+
+			if (drm_rect_width(&cur_cfg->src_rect) > 2 * max_linewidth) {
+				DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
+						DRM_RECT_ARG(&cur_cfg->src_rect), max_linewidth);
+				return -E2BIG;
+			}
+
+			memcpy(next_cfg, cur_cfg, sizeof(struct dpu_sw_pipe_cfg));
+			cur_cfg->src_rect.x2 = (cur_cfg->src_rect.x1 + cur_cfg->src_rect.x2) >> 1;
+			cur_cfg->dst_rect.x2 = (cur_cfg->dst_rect.x1 + cur_cfg->dst_rect.x2) >> 1;
+			next_cfg->src_rect.x1 = cur_cfg->src_rect.x2;
+			next_cfg->dst_rect.x1 = cur_cfg->dst_rect.x2;
+			next_cfg->visible = true;
+			next_cfg->mxcfg_id = cfg_id;
+			DPU_DEBUG_PLANE(pdpu, "Split super wide plane into:" DRM_RECT_FMT "and" DRM_RECT_FMT "\n",
+					DRM_RECT_ARG(&cur_cfg->src_rect), DRM_RECT_ARG(&next_cfg->src_rect));
+			cfg_idx++;
+		}
 
-	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(&cur_cfg->src_rect,
 				    new_plane_state->fb->width, new_plane_state->fb->height,
 				    new_plane_state->rotation);
+		cfg_idx++;
+	}
+
+	for (; cfg_idx < MIX_CFGS_IN_CRTC; cfg_idx++) {
+		memset(&pstate->pipe_cfg[cfg_idx], 0, sizeof(struct dpu_sw_pipe_cfg));
+		memset(&pstate->pipe[cfg_idx], 0, sizeof(struct dpu_sw_pipe));
+	}
 
 	pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
 

-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ