From nobody Mon Feb 9 06:50:54 2026 Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B85F217A2F7 for ; Thu, 27 Feb 2025 02:31:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740623519; cv=none; b=PV28oCak6pAKCS2Gq622ff/ay74YrCBSXlY1zvUxWazoxh4+FjTq40NWsjTjyqq34HeCjulYBmA9lyGcGLd+1IfXJkh2TMUnpB42GFadThd6ONfN1T6KYSo6S9nAgPUx8lCXQQGnaq2iVA9EtTWamfeTGpOaiE7LtX0/Qc+3zbY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740623519; c=relaxed/simple; bh=luHG1Y5KsNSo/DhWFzwtutrMted5f6Dk0kFRk2t85Ng=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=EgbEtyVwCg1epid1mBOK5U4eiTGcZKb01gdCaqlWEiYWIAarV/YWEquCN8FvPXSCWACY2YqMWZF7gIYTdmqAGiJT/7/lbRAQaPtODfAxYk63E2K7KDvA3e+GI60An/D1FgQLW8tJ8IVym8QOxU5MKWPw/EbH3/LRIt0W+EeUedk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=GYKMU42J; arc=none smtp.client-ip=209.85.167.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="GYKMU42J" Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-54527a7270eso396153e87.0 for ; Wed, 26 Feb 2025 18:31:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1740623513; x=1741228313; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:from:to:cc:subject:date:message-id:reply-to; bh=Pe28A92x1GiXAYhXNOQnMWm/JVmD+9I9ysLZzus4GUg=; b=GYKMU42JmnyIzyz5K2yChRbPSqvpSGSbRE2QU6TPpi86PVYnqoP6Wqx+Clam0CexT8 jVteud+imQSNqLykTa9hc+LOcNiUe+ZdzpRbdxUn6L2RCGMDU3w8u3kRX9/4xvGXN5ZX lGZU0zZFXxZX28BZLVHN9a8B1cYwVlhnOS4HSjvgeBCHBw1PlNwHDPyG8MHPNvvwCF6S rgyHcn10I/d3Q0Wg3UoZ5d1UWdS31RY2LEVjfnu850hCBBTt8YdTxVLwlRWvp3vpMwRX sMULrSPqBRigVaDt0EFKqgmSKrY/IPLDPbdl0rjyWLq9WT1kqfIAqbR41EhN5HyWjXSC jTWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740623513; x=1741228313; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Pe28A92x1GiXAYhXNOQnMWm/JVmD+9I9ysLZzus4GUg=; b=oLSLMV4S1PQ4cYouLayXUugrhd4iiVuHkeeqrDCyjzLDVCrtDV/uHfY6lyNGAECjNP l4o+k9ZE/lf/i4ghWjE41GkP8DKvV4+GPkqqG6qCqTm3MrLIMA3EqELXDKa2ZUbdvle4 lxCTmDHaQFl/DH3VTHdWnoWyOGHLeZiz7FecCR5MliRtsne4c/6Udoq6lnk52tde5ZlB t0VlAt/CKBnBOvTqiFKI/WsHssX5+WRFs26HBB18wH6duChyyJX0ASsOAd7bYKHNLOxv ppPKeV4gK1UI+NUTtF8ZOarXFUrc1++vstPpdRDy5XauKlAbwMGsbPT8R5hFOfa/uA7X rPfQ== X-Forwarded-Encrypted: i=1; AJvYcCWsPhhXRmFgjpvWUibhKp0OUFHrauhqTOAe0Y5de5xiPd+b8qOzbKj0fdECDF6q3bw0RrGgdHlf68U3g24=@vger.kernel.org X-Gm-Message-State: AOJu0YzqXCOxLq4YMSGREaxJC7p6tL1xauhiCaEUu7ooZp+JLi5V9+3V y+yVSZ6DDrsgLI//2N60XFmRR0sogKzitF5nUnBwRVtGhO+myWaFFCTB3q9m5Vo= X-Gm-Gg: ASbGncs/zFV1tNXcuXe8Y3gjZDW/hT3uCmLzHkKYLUIb6Q0fiB5nUs0HysubWqp1784 kHDWKb3OUGYCkSikZYtBRBLe14BCORgU8yYYalAO/MnWCZbTlTbTkUfiDKNDvxPkhvVTvFnt7Qr l5zqow589LmJXYgDUpSEKiggjqLBegmEZYwMRXXqs/9ApaeSb6PZRpwarthJii/nFp+mbNp/eEb 5FypgJH5KZVMMlBACZqwY6gX8h615SckYbR6u7gNc7hN0CcgNB75buo4c2Hjt/egORFA0PnHjUx r9lV5TXfaCcoegmQcRyqABRr6Qi3TrAYFw== X-Google-Smtp-Source: AGHT+IGsG9tTMBoFX+p4C5ZcgIDjAg5knIHTqwpKvZsGh7bP+qxxtuuQn/PArlbHj3skC9/mmGbWww== X-Received: by 2002:a05:6512:3b2b:b0:545:a1a:5576 with SMTP id 2adb3069b0e04-5483914012cmr11505631e87.22.1740623513446; Wed, 26 Feb 2025 18:31:53 -0800 (PST) Received: from umbar.lan ([192.130.178.90]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-549443be377sm49269e87.167.2025.02.26.18.31.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Feb 2025 18:31:52 -0800 (PST) From: Dmitry Baryshkov Date: Thu, 27 Feb 2025 04:31:49 +0200 Subject: [PATCH v6] drm/msm/dpu: allow sharing SSPP between planes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250227-dpu-share-sspp-v6-1-4d469910f399@linaro.org> X-B4-Tracking: v=1; b=H4sIAJTOv2cC/3XMQQrCQAyF4auUrI04oxOrK+8hXQxt2gakMyRal NK7O3bv8n/wvgWMVdjgWi2gPItJmkrQroJ2jNPAKF1p8Ad/ct4F7PILbYzKaJYznkMMRMytqwO UU1bu5b2B96b0KPZM+tn8OfzWv9Qc0CFR6DyRq4/95faQKWraJx2gWdf1C20uMr+tAAAA X-Change-ID: 20241215-dpu-share-sspp-75a566eec185 To: Rob Clark , Abhinav Kumar , Sean Paul , Marijn Suijten , David Airlie , Simona Vetter Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=10508; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=luHG1Y5KsNSo/DhWFzwtutrMted5f6Dk0kFRk2t85Ng=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBnv86W44TO3Fj2x1ye0TDqmCpBPagsJ4F3ft1JR M/feYMd/SKJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZ7/OlgAKCRCLPIo+Aiko 1ZTxB/9s+6yAAjS+vBIq/IS7czbaoyjphlANfKv5w/YKkG+fIrAk/OL+eqNN1gI5AHMZEwOmSyE p/DFI9mKilYWMkWlPrW9RLEzUoNZGu3taB3ldKhhw8ZWhYcpQb+6pYYEPqHpsDQFUR2TOlimoBc g+ZHeV82UGtHCAzSjSvVVesQo59vejgFTXXdu6OB+FjqJ3dyfDp3NMkWrF5Vw+6idkFlQ8UY4us bGr3kamsz7KljeTtmCFQMCdrZA7s/4HE8B7WrxQNavmtLJNMNFTuF3Xgt3X441E95COMGYcxKtl V5oqG5sSYwwEicrNtqhc6EyYPEpK7ZYz6O3bvTZi1oWfzK3L X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A Since SmartDMA planes provide two rectangles, it is possible to use them to drive two different DRM planes, first plane getting the rect_0, another one using rect_1 of the same SSPP. The sharing algorithm is pretty simple, it requires that each of the planes can be driven by the single rectangle and only consecutive planes are considered. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- This patch has been deferred from v4 of virtual wide patchset to simplify the merging path. Now as the wide planes have been merged, pick up the patch that allows sharing of the SSPPs between two planes. --- Changes in v6: - Fixed typo (consecutive) in the commit message (Abhinav) - Renamed prev_plane_state to prev_adjancent_plane_state (Abhinav) - Renamed prev_pstate to prev_adjancent_pstate as a followup to the previous change - Link to v5: https://lore.kernel.org/r/20241215-dpu-share-sspp-v5-1-665d26= 6183f9@linaro.org Changes in v5: - Rebased on top of the current msm-next-lumag - Renamed dpu_plane_try_multirect() to dpu_plane_try_multirect_shared() (Abhinav) - Link to v4: https://lore.kernel.org/dri-devel/20240314000216.392549-11-dm= itry.baryshkov@linaro.org/ --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 156 +++++++++++++++++++++++++-= ---- 1 file changed, 130 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/ms= m/disp/dpu1/dpu_plane.c index af3e541f60c303eb5212524e877129359b5ca98c..11c4d5dfd9703b27b7ffde34e9b= 4f92ec956c3c0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -887,10 +887,9 @@ static int dpu_plane_atomic_check_nosspp(struct drm_pl= ane *plane, return 0; } =20 -static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *ssp= p, - struct dpu_sw_pipe_cfg *pipe_cfg, - const struct msm_format *fmt, - uint32_t max_linewidth) +static int dpu_plane_is_multirect_capable(struct dpu_hw_sspp *sspp, + struct dpu_sw_pipe_cfg *pipe_cfg, + const struct msm_format *fmt) { if (drm_rect_width(&pipe_cfg->src_rect) !=3D drm_rect_width(&pipe_cfg->ds= t_rect) || drm_rect_height(&pipe_cfg->src_rect) !=3D drm_rect_height(&pipe_cfg->= dst_rect)) @@ -902,10 +901,6 @@ static int dpu_plane_is_multirect_parallel_capable(str= uct dpu_hw_sspp *sspp, if (MSM_FORMAT_IS_YUV(fmt)) return false; =20 - if (MSM_FORMAT_IS_UBWC(fmt) && - drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2) - return false; - if (!test_bit(DPU_SSPP_SMART_DMA_V1, &sspp->cap->features) && !test_bit(DPU_SSPP_SMART_DMA_V2, &sspp->cap->features)) return false; @@ -913,6 +908,27 @@ static int dpu_plane_is_multirect_parallel_capable(str= uct dpu_hw_sspp *sspp, return true; } =20 +static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg, + const struct msm_format *fmt, + uint32_t max_linewidth) +{ + if (MSM_FORMAT_IS_UBWC(fmt) && + drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2) + return false; + + return true; +} + +static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *ssp= p, + struct dpu_sw_pipe_cfg *pipe_cfg, + const struct msm_format *fmt, + uint32_t max_linewidth) +{ + return dpu_plane_is_multirect_capable(sspp, pipe_cfg, fmt) && + dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth); +} + + static int dpu_plane_atomic_check_sspp(struct drm_plane *plane, struct drm_atomic_state *state, const struct drm_crtc_state *crtc_state) @@ -1001,6 +1017,69 @@ static bool dpu_plane_try_multirect_parallel(struct = dpu_sw_pipe *pipe, struct dp return true; } =20 +static int dpu_plane_try_multirect_shared(struct dpu_plane_state *pstate, + struct dpu_plane_state *prev_adjancent_pstate, + const struct msm_format *fmt, + uint32_t max_linewidth) +{ + struct dpu_sw_pipe *pipe =3D &pstate->pipe; + struct dpu_sw_pipe *r_pipe =3D &pstate->r_pipe; + struct dpu_sw_pipe_cfg *pipe_cfg =3D &pstate->pipe_cfg; + struct dpu_sw_pipe *prev_pipe =3D &prev_adjancent_pstate->pipe; + struct dpu_sw_pipe_cfg *prev_pipe_cfg =3D &prev_adjancent_pstate->pipe_cf= g; + const struct msm_format *prev_fmt =3D msm_framebuffer_format(prev_adjance= nt_pstate->base.fb); + u16 max_tile_height =3D 1; + + if (prev_adjancent_pstate->r_pipe.sspp !=3D NULL || + prev_pipe->multirect_mode !=3D DPU_SSPP_MULTIRECT_NONE) + return false; + + if (!dpu_plane_is_multirect_capable(pipe->sspp, pipe_cfg, fmt) || + !dpu_plane_is_multirect_capable(prev_pipe->sspp, prev_pipe_cfg, prev_= fmt)) + return false; + + if (MSM_FORMAT_IS_UBWC(fmt)) + max_tile_height =3D max(max_tile_height, fmt->tile_height); + + if (MSM_FORMAT_IS_UBWC(prev_fmt)) + max_tile_height =3D max(max_tile_height, prev_fmt->tile_height); + + r_pipe->multirect_index =3D DPU_SSPP_RECT_SOLO; + r_pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_NONE; + + r_pipe->sspp =3D NULL; + + if (dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth) && + dpu_plane_is_parallel_capable(prev_pipe_cfg, prev_fmt, max_linewidth)= && + (pipe_cfg->dst_rect.x1 >=3D prev_pipe_cfg->dst_rect.x2 || + prev_pipe_cfg->dst_rect.x1 >=3D pipe_cfg->dst_rect.x2)) { + pipe->sspp =3D prev_pipe->sspp; + + pipe->multirect_index =3D DPU_SSPP_RECT_1; + pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_PARALLEL; + + prev_pipe->multirect_index =3D DPU_SSPP_RECT_0; + prev_pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_PARALLEL; + + return true; + } + + if (pipe_cfg->dst_rect.y1 >=3D prev_pipe_cfg->dst_rect.y2 + 2 * max_tile_= height || + prev_pipe_cfg->dst_rect.y1 >=3D pipe_cfg->dst_rect.y2 + 2 * max_tile_= height) { + pipe->sspp =3D prev_pipe->sspp; + + pipe->multirect_index =3D DPU_SSPP_RECT_1; + pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_TIME_MX; + + prev_pipe->multirect_index =3D DPU_SSPP_RECT_0; + prev_pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_TIME_MX; + + return true; + } + + return false; +} + static int dpu_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -1098,13 +1177,14 @@ static int dpu_plane_virtual_atomic_check(struct dr= m_plane *plane, static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc, struct dpu_global_state *global_state, struct drm_atomic_state *state, - struct drm_plane_state *plane_state) + struct drm_plane_state *plane_state, + struct drm_plane_state *prev_adjancent_plane_state) { const struct drm_crtc_state *crtc_state =3D NULL; struct drm_plane *plane =3D plane_state->plane; struct dpu_kms *dpu_kms =3D _dpu_plane_get_kms(plane); struct dpu_rm_sspp_requirements reqs; - struct dpu_plane_state *pstate; + struct dpu_plane_state *pstate, *prev_adjancent_pstate; struct dpu_sw_pipe *pipe; struct dpu_sw_pipe *r_pipe; struct dpu_sw_pipe_cfg *pipe_cfg; @@ -1116,6 +1196,8 @@ static int dpu_plane_virtual_assign_resources(struct = drm_crtc *crtc, plane_state->crtc); =20 pstate =3D to_dpu_plane_state(plane_state); + prev_adjancent_pstate =3D prev_adjancent_plane_state ? + to_dpu_plane_state(prev_adjancent_plane_state) : NULL; pipe =3D &pstate->pipe; r_pipe =3D &pstate->r_pipe; pipe_cfg =3D &pstate->pipe_cfg; @@ -1134,24 +1216,42 @@ static int dpu_plane_virtual_assign_resources(struc= t drm_crtc *crtc, =20 reqs.rot90 =3D drm_rotation_90_or_270(plane_state->rotation); =20 - pipe->sspp =3D dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &req= s); - if (!pipe->sspp) - return -ENODEV; + if (drm_rect_width(&r_pipe_cfg->src_rect) =3D=3D 0) { + if (!prev_adjancent_pstate || + !dpu_plane_try_multirect_shared(pstate, prev_adjancent_pstate, fmt, + dpu_kms->catalog->caps->max_linewidth)) { + pipe->sspp =3D dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &r= eqs); + if (!pipe->sspp) + return -ENODEV; =20 - 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 =3D dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &= reqs); - if (!r_pipe->sspp) + r_pipe->sspp =3D NULL; + + pipe->multirect_index =3D DPU_SSPP_RECT_SOLO; + pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_NONE; + + r_pipe->multirect_index =3D DPU_SSPP_RECT_SOLO; + r_pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_NONE; + } + } else { + pipe->sspp =3D dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &re= qs); + if (!pipe->sspp) return -ENODEV; =20 - pipe->multirect_index =3D DPU_SSPP_RECT_SOLO; - pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_NONE; + 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 =3D dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, = &reqs); + if (!r_pipe->sspp) + return -ENODEV; =20 - r_pipe->multirect_index =3D DPU_SSPP_RECT_SOLO; - r_pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_NONE; + pipe->multirect_index =3D DPU_SSPP_RECT_SOLO; + pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_NONE; + + r_pipe->multirect_index =3D DPU_SSPP_RECT_SOLO; + r_pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_NONE; + } } =20 return dpu_plane_atomic_check_sspp(plane, state, crtc_state); @@ -1164,6 +1264,7 @@ int dpu_assign_plane_resources(struct dpu_global_stat= e *global_state, unsigned int num_planes) { unsigned int i; + struct drm_plane_state *prev_adjancent_plane_state =3D NULL; =20 for (i =3D 0; i < num_planes; i++) { struct drm_plane_state *plane_state =3D states[i]; @@ -1173,9 +1274,12 @@ int dpu_assign_plane_resources(struct dpu_global_sta= te *global_state, continue; =20 int ret =3D dpu_plane_virtual_assign_resources(crtc, global_state, - state, plane_state); + state, plane_state, + prev_adjancent_plane_state); if (ret) - return ret; + break; + + prev_adjancent_plane_state =3D plane_state; } =20 return 0; --- base-commit: 89839e69f6154feecd79bd01171375225b0296e9 change-id: 20241215-dpu-share-sspp-75a566eec185 Best regards, --=20 Dmitry Baryshkov