From patchwork Mon Mar 3 15:14:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jun Nie X-Patchwork-Id: 13999015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BEC18C282D1 for ; Mon, 3 Mar 2025 15:16:29 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4C0B310E45F; Mon, 3 Mar 2025 15:16:29 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="UuAb/CXR"; dkim-atps=neutral Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9D92D10E467 for ; Mon, 3 Mar 2025 15:16:27 +0000 (UTC) Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-223a7065ff8so33792235ad.0 for ; Mon, 03 Mar 2025 07:16:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1741014987; x=1741619787; darn=lists.freedesktop.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Oc++QhoQONQQQCVNdB+FMhEMF6g1pjddZJUkAMQAE8Q=; b=UuAb/CXRKVcKSCpnSx+aIDt6a5VhSxfEPq2qpxYVbzCE2CS06MbzZ/IrijrBTbit1E yvcdzHcCkJb5sissP/OWtwc8MTy4+FPC0wSkWhe8sBfepO1g00z3OW1T0RT2wpyJCKEE ojIkkVBa3f+XhOIomkPFnIv7T6ZIVefgPQVu8ufWB1fiVhHHbF7XS7tEeC72lgeGrhgP 8EZAThBZEYWV400S+vHo/jdcZmtrfg77V+nsiizHPJj1Ow5vgFVDReA+/1cFOwlw4Xmo Wl9OaXJYQMgkz/Nuqf6GgB42rjkGfPB1j7UtfDq9kmXtNzRPV6e66poxDFpYr393rQ8s /zmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741014987; x=1741619787; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Oc++QhoQONQQQCVNdB+FMhEMF6g1pjddZJUkAMQAE8Q=; b=FAgsNrIpMR165RURCfiZ+OGdtpYzk+HXFUBCZD5EXNrhW3FOw2wCcZdGpi4LHt4FnP QkIfCEns6Qj1DCNzyJt5+m1K5xes5bmGrBUBvtTHRLaos2P8Y5w8F6AegOMCLySYsXBH VDhw0AyMzBVy04EB4hmYRb86vs6wuuldy3uTFSGdkvT5lELPO5ySztuDM+OJTdGrC+J6 Pq9BrNDJCw1uD3odbyl+C5QyRckoK3sKeKYQs0YyLDYNOTEwCOJxoerHBXw03iLxGEBR ATqbiLSM8Gb57OPLl10ysQ9XSZCiJ1s6oR9DMQ2nvEH42es2vTgQtz97HbZ1qfaTRs7E TaYw== X-Forwarded-Encrypted: i=1; AJvYcCWw9LE2t6fky74j9KsOxARpv1oVmVd5LobBHZDqTHNRNtCZ40bd4J4UUyYYpQtnHMPv8FOp9Jx5nXI=@lists.freedesktop.org X-Gm-Message-State: AOJu0YxcfOEaX3mlXyjfMCuprbjYkVjRKE1MIrcBI1UZVrSfPMNA3yrD 5Q5WMKp3A0dNsjVTONvMqTRM5oiSDMlXJz0nXenpr2qgoeW+m6KgM8/TPhWCBIc= X-Gm-Gg: ASbGncul6tbyMtkCZakdSJvB2c21g8WA+LzLZ76C0QUhmslxGzazpJbNueBKj7IF36c KwY6AMM9UZSHVmJqdFqy/96keSQ1BE/M66HrTjJOcH3KKo9BHB1eE6AQVpKp1TL/OMfql8bY/sP jj1QzIgkhN3EWJTAp/QNUFrnVvZWlRoFJMwjlXyFNeahTvjf8Gl2TcgVUxlPi7CrR/Lu+R8Hh+L oQ2nqp/R70XPqltQBGYs8oyneMeV2H0OZ4hELbcTKodZRZAndfOWuSVZ/YUYmBiY27gag451/F8 u9uWhKf6hqtCpUZKMOWUfy9iaKqqycnfxZZqEubkCg== X-Google-Smtp-Source: AGHT+IEQ1Nt1JrCf0bwlq18Plfv2BqciVq5ZCffMRG6l18kBCkJrsK8W6/j7WRECwgn7DzJ5aCF0og== X-Received: by 2002:a17:903:2b04:b0:21f:564:80a4 with SMTP id d9443c01a7336-22369258510mr206358145ad.33.1741014987121; Mon, 03 Mar 2025 07:16:27 -0800 (PST) Received: from [127.0.1.1] ([112.64.60.252]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-736584b3cffsm1851984b3a.4.2025.03.03.07.16.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Mar 2025 07:16:26 -0800 (PST) From: Jun Nie Date: Mon, 03 Mar 2025 23:14:43 +0800 Subject: [PATCH v8 14/15] drm/msm/dpu: support plane splitting in quad-pipe case MIME-Version: 1.0 Message-Id: <20250303-sm8650-v6-14-hmd-deckard-mdss-quad-upstream-oldbootwrapper-36-prep-v8-14-eb5df105c807@linaro.org> References: <20250303-sm8650-v6-14-hmd-deckard-mdss-quad-upstream-oldbootwrapper-36-prep-v8-0-eb5df105c807@linaro.org> In-Reply-To: <20250303-sm8650-v6-14-hmd-deckard-mdss-quad-upstream-oldbootwrapper-36-prep-v8-0-eb5df105c807@linaro.org> To: Rob Clark , Abhinav Kumar , Dmitry Baryshkov , Sean Paul , Marijn Suijten , David Airlie , Simona Vetter , Jessica Zhang Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org, Jun Nie X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1741014878; l=8117; i=jun.nie@linaro.org; s=20240403; h=from:subject:message-id; bh=LlIwaPbf+HH4PxIPS5YpJQVYFDplXAqOUs0Fqhpinbc=; b=65k4ibLc2eCRC7auWYBTqrfiZpe0w4E5Vyt+kuqg8k4OoqoFZEImy8xPHhV01T4M2plezRqgJ 7wx7dmAHRZWDFPhet31ew/Mp4ivBxFkt/SYVTfTrFwrVCGzAbcnefcr X-Developer-Key: i=jun.nie@linaro.org; a=ed25519; pk=MNiBt/faLPvo+iJoP1hodyY2x6ozVXL8QMptmsKg3cc= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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 in quad-pipe case, thus a LM pair should not blend any content that cross the half of screen in this case. Clip plane into pipes per left and right half screen ROI if topology is quad pipe case. The clipped rectangle on every half of screen is futher handled by two pipes if its width exceeds a limit for a single pipe. Signed-off-by: Jun Nie Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 134 +++++++++++++++++++++--------- 1 file changed, 94 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 0245f158881b5c37fffb75d78c75310ba446a0b7..850ce3a59f4dad0d1a6d6fcc3dc95a5ae00afd45 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -831,8 +831,12 @@ 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_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; @@ -855,13 +859,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; @@ -886,35 +887,91 @@ 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 wide plane that exceeds limit with 1 + * config for 2:2:1. So need to handle both wide plane splitting, and + * two halves of screen splitting for quad-pipe case. Check dest + * rectangle left/right clipping first, then check 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_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)); + + 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->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 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; + DPU_DEBUG_PLANE(pdpu, "Split 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)); + } - 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, - new_plane_state->fb->width, new_plane_state->fb->height, + 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, + 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); return 0; @@ -954,20 +1011,17 @@ 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[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]; - int ret = 0; - - ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, - &crtc_state->adjusted_mode, - new_plane_state); - 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, + for (i = 0; i < PIPES_PER_PLANE; i++) { + pipe = &pstate->pipe[i]; + pipe_cfg = &pstate->pipe_cfg[i]; + if (!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)