From nobody Thu Apr 2 23:54:45 2026 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (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 6BAB332C937 for ; Thu, 12 Mar 2026 08:28:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773304124; cv=none; b=OT7Xx+pYGxvMYUn5di14R1aJSjdr3A74g/TZgN3jSBg+ALUENaeaAJJWOsB4JRgoG6T5WcMXDkYG8Jy5vp1LAw2xHp3M/jCUm5omWnMip8maXj+MfThJqlhsGSnN70/sj4YhnfwWjhtmHKzdU6IEj7R+zoViYz6Y46sVVKb0t74= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773304124; c=relaxed/simple; bh=llcAoN5oMCj08hUSIdLT6NP8xPSgK+elXOWbE1sjvd8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IJhRl2GDBxVPDNzO8k0yiSIvvBdm1hrCAqGzxhNR2SVgxhUE4u+RcTGgJWhbJYo5a08e0wwP6OHedNKAOgb2tiNf9DUZe0hTO7ZJwgAGRP6Tc9tACX9L1ES4ZvjQrXotw+umjuCpU0fsEc+zg846s9CKtFTRfin2wH6EcEN728w= 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=eBRzh6JK; arc=none smtp.client-ip=209.85.221.51 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="eBRzh6JK" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-439bc14dcf4so1381221f8f.1 for ; Thu, 12 Mar 2026 01:28:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1773304121; x=1773908921; darn=vger.kernel.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=H21vp6hR1X4O6tjqIgvx5S4K1FkSDkFIhmuzuM7d1Yg=; b=eBRzh6JK6nI+zZDejlC6IkPIb3RG63FSU08ppO1BTG6usvzzvTCio4WTl++o9m3bgI Vpv9npIEeVN9bVUDLEuJZjH4DenRya1jE/NlMJuhM6byVikoBYzCH1fNw9M96D+6GWw8 WwcFgm2W7Ru6Q/JRbnwC6iTFdZekXJMdOxcCsMJFkBgJrPtEXYixA73ehqZ00tSYUmuV KGvYBwcFDu1hquQ6lwqLL6LNkHvVIgxgwGVq5mvsBiDYSMwBnGi1vySQjgHU2GCa6nXj oKeY1X01aqdh08FQWVazn7nXpAqonACpKFDcdCUbZy0JB9VwODDtNMVYKx9QYZ5jfvRR ZVtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773304121; x=1773908921; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=H21vp6hR1X4O6tjqIgvx5S4K1FkSDkFIhmuzuM7d1Yg=; b=SpJZqXmLKvs/bzb2Eu4QrXaMM+APnW7h260U6haMLTCnCVfZ+5YF+e6Rryi9SlRQYL 6N8+iec+S/4PRNXrQfrXAzN0xtpHL4quKSSHJ33sKOSU5XIHX6EqSj6GHx3YfBfA9QR1 1jcdMNdA/XcRVIZ1BoS24OzpFdps2tKyN0lAy/ikSjCIxlNsV5padlGhokATUE3ys0Of 8ffPuH6VZ7WLjn/WmaMCqmE1wbsmXaoEp9XBk1NJAebDUfsx99xjaWm2ofNOkmvihtwU arktoy3hVoOTTxglx7UibXt9a0FavXZ95nJ9Qe0pRzZcrsKQAHlLAKw3VW1tUCJdpZA3 4KRA== X-Forwarded-Encrypted: i=1; AJvYcCWImEOnfHewijRCqTBXrrYzSPpM14hPT/+Vs/Mlu9sc6ns117wazRHHDcGFSfmHrROMRhWK4/aC1U2B2N8=@vger.kernel.org X-Gm-Message-State: AOJu0YyAwpjM5aTp2gqCX7ebB9XHtnu/J45mh43+4qpgfIE8Et/Ah+JG 2C6uj9T9/o6E88OxJCtQvk5iEvIHhogmtk79d5h6c3cQJsww9wglZ+rPCUHAXOzeKeE= X-Gm-Gg: ATEYQzxLp2UTdpurTrjD5nfBDXnP8SnzI1Eie4RSqLPvfVioNHpd8pp9Tz+uHpeGOU/ kFYzu5hPj2sQesVV5R8NGVbAwBrJr2939X/Y1raMn7KPU2UesGXrszmB47PgA3bF3+VcXZkJRFa BSqZ3eG139BLgmlAvyJQFM0lf129pEiGu/CifYuv/KscIo4KYv/6L/byiXme0ivCeDbhTJI/STU kx5dyjqRKCQ+4jXX+k+bCbeom9rSvfaML9cijIQlKom+sMe4VjYf+mXv8hHS1p+IZS3WLsOeF9d 6NVSdY5MR/a7jE9kw3xXrQuyjirY2Qh5koHc58qlJQMCVPw0eojlieaD2TvtsW9VEBIeSRxC8Jv iApOtvrwo7HbRmmSzlwH94CeHoNsDZSZqNQDhb3hmz+U30PCtwljcRVylD2Xu9JHOqLC/LTzQSG ewZT0= X-Received: by 2002:a05:6000:2c07:b0:439:c24b:ec15 with SMTP id ffacd0b85a97d-439fdf8aa4fmr4431739f8f.5.1773304120641; Thu, 12 Mar 2026 01:28:40 -0700 (PDT) Received: from [127.0.1.1] ([2a04:6f00:1::ee:b:1015]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439fe219c41sm6273780f8f.29.2026.03.12.01.28.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 Mar 2026 01:28:40 -0700 (PDT) From: Jun Nie Date: Thu, 12 Mar 2026 16:28:11 +0800 Subject: [PATCH v19 2/4] drm/msm/dpu: Defer SSPP allocation until CRTC check 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: <20260312-msm-next-quad-pipe-split-v19-2-4ffa2b06c996@linaro.org> References: <20260312-msm-next-quad-pipe-split-v19-0-4ffa2b06c996@linaro.org> In-Reply-To: <20260312-msm-next-quad-pipe-split-v19-0-4ffa2b06c996@linaro.org> To: Abhinav Kumar , Dmitry Baryshkov , Sean Paul , Marijn Suijten , David Airlie , Simona Vetter , Rob Clark , Neil Armstrong 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.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1773304094; l=10582; i=jun.nie@linaro.org; s=20240403; h=from:subject:message-id; bh=llcAoN5oMCj08hUSIdLT6NP8xPSgK+elXOWbE1sjvd8=; b=ObM16Q5nSNb6OskbUYeeMtfFvDsy/YRjzDsHTsWSpTqbAcocUYuxFSX+LmAVArbQeMPZXms/F 7C/Fus0C+7AAVDlPA2W4pFo5hC7O8rWJl4Q8VL2dM6blSK+y52r53FK X-Developer-Key: i=jun.nie@linaro.org; a=ed25519; pk=MNiBt/faLPvo+iJoP1hodyY2x6ozVXL8QMptmsKg3cc= Currently, mapping plane to SSPP occurs during the plane check phase for non-virtual plane case. The SSPP allocation and plane mapping occurs during CRTC check phase for virtual plane case. Defer these SSPP operations until CRTC check stage to unify the 2 cases, and ease later revisement for quad-pipe change. Signed-off-by: Jun Nie Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 25 ++++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 136 ++++++++++++++------------= ---- 2 files changed, 80 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm= /disp/dpu1/dpu_crtc.c index 6bf7c46379aed..e97456d4fbb8c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1325,7 +1325,7 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_st= ate *cstate) return false; } =20 -static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc= _state *crtc_state) +static int dpu_crtc_assign_planes(struct drm_crtc *crtc, struct drm_crtc_s= tate *crtc_state) { int total_planes =3D crtc->dev->mode_config.num_total_plane; struct drm_atomic_state *state =3D crtc_state->state; @@ -1338,8 +1338,6 @@ static int dpu_crtc_reassign_planes(struct drm_crtc *= crtc, struct drm_crtc_state if (IS_ERR(global_state)) return PTR_ERR(global_state); =20 - dpu_rm_release_all_sspp(global_state, crtc); - if (!crtc_state->enable) return 0; =20 @@ -1366,6 +1364,19 @@ static int dpu_crtc_reassign_planes(struct drm_crtc = *crtc, struct drm_crtc_state return ret; } =20 +static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc= _state *crtc_state) +{ + struct dpu_global_state *global_state; + + global_state =3D dpu_kms_get_global_state(crtc_state->state); + if (IS_ERR(global_state)) + return PTR_ERR(global_state); + + dpu_rm_release_all_sspp(global_state, crtc); + + return dpu_crtc_assign_planes(crtc, crtc_state); +} + #define MAX_CHANNELS_PER_CRTC PIPES_PER_PLANE #define MAX_HDISPLAY_SPLIT 1080 =20 @@ -1534,9 +1545,11 @@ static int dpu_crtc_atomic_check(struct drm_crtc *cr= tc, return rc; } =20 - if (dpu_use_virtual_planes && - (crtc_state->planes_changed || crtc_state->zpos_changed)) { - rc =3D dpu_crtc_reassign_planes(crtc, crtc_state); + if (crtc_state->planes_changed || crtc_state->zpos_changed) { + if (dpu_use_virtual_planes) + rc =3D dpu_crtc_reassign_planes(crtc, crtc_state); + else + rc =3D dpu_crtc_assign_planes(crtc, crtc_state); if (rc < 0) return rc; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/ms= m/disp/dpu1/dpu_plane.c index 4ed14f203c315..70992a4401d69 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1112,65 +1112,13 @@ static int dpu_plane_try_multirect_shared(struct dp= u_plane_state *pstate, =20 static int dpu_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) -{ - struct drm_plane_state *new_plane_state =3D drm_atomic_get_new_plane_stat= e(state, - plane); - int ret =3D 0; - struct dpu_plane *pdpu =3D to_dpu_plane(plane); - struct dpu_plane_state *pstate =3D to_dpu_plane_state(new_plane_state); - struct dpu_kms *dpu_kms =3D _dpu_plane_get_kms(plane); - struct dpu_sw_pipe *pipe =3D &pstate->pipe[0]; - struct dpu_sw_pipe *r_pipe =3D &pstate->pipe[1]; - struct dpu_sw_pipe_cfg *pipe_cfg =3D &pstate->pipe_cfg[0]; - struct dpu_sw_pipe_cfg *r_pipe_cfg =3D &pstate->pipe_cfg[1]; - const struct drm_crtc_state *crtc_state =3D NULL; - uint32_t max_linewidth =3D dpu_kms->catalog->caps->max_linewidth; - - if (new_plane_state->crtc) - crtc_state =3D drm_atomic_get_new_crtc_state(state, - new_plane_state->crtc); - - pipe->sspp =3D dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); - - if (!pipe->sspp) - return -EINVAL; - - ret =3D dpu_plane_atomic_check_nosspp(plane, new_plane_state, crtc_state); - if (ret) - return ret; - - if (!new_plane_state->visible) - return 0; - - ret =3D dpu_plane_split(plane, new_plane_state, crtc_state); - if (ret) - return ret; - - if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg, - pipe->sspp, - msm_framebuffer_format(new_plane_state->fb), - max_linewidth)) { - DPU_DEBUG_PLANE(pdpu, "invalid " DRM_RECT_FMT " /" DRM_RECT_FMT - " max_line:%u, can't use split source\n", - DRM_RECT_ARG(&pipe_cfg->src_rect), - DRM_RECT_ARG(&r_pipe_cfg->src_rect), - max_linewidth); - return -E2BIG; - } - - return dpu_plane_atomic_check_sspp(plane, state, crtc_state); -} - -static int dpu_plane_virtual_atomic_check(struct drm_plane *plane, - struct drm_atomic_state *state) { struct drm_plane_state *plane_state =3D drm_atomic_get_plane_state(state, plane); struct drm_plane_state *old_plane_state =3D drm_atomic_get_old_plane_state(state, plane); - struct dpu_plane_state *pstate =3D to_dpu_plane_state(plane_state); + int ret =3D 0; struct drm_crtc_state *crtc_state =3D NULL; - int ret, i; =20 if (IS_ERR(plane_state)) return PTR_ERR(plane_state); @@ -1183,20 +1131,8 @@ static int dpu_plane_virtual_atomic_check(struct drm= _plane *plane, if (ret) return ret; =20 - if (!plane_state->visible) { - /* - * resources are freed by dpu_crtc_assign_plane_resources(), - * but clean them here. - */ - for (i =3D 0; i < PIPES_PER_PLANE; i++) - pstate->pipe[i].sspp =3D NULL; - + if (!plane_state->visible) return 0; - } - - ret =3D dpu_plane_split(plane, plane_state, crtc_state); - if (ret) - return ret; =20 /* * Force resource reallocation if the format of FB or src/dst have @@ -1211,7 +1147,6 @@ static int dpu_plane_virtual_atomic_check(struct drm_= plane *plane, msm_framebuffer_format(old_plane_state->fb) !=3D msm_framebuffer_format(plane_state->fb)) crtc_state->planes_changed =3D true; - return 0; } =20 @@ -1258,9 +1193,9 @@ 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, + const struct drm_crtc_state *crtc_state, struct drm_plane_state **prev_adjacent_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; @@ -1270,10 +1205,6 @@ static int dpu_plane_virtual_assign_resources(struct= drm_crtc *crtc, const struct msm_format *fmt; int i, ret; =20 - if (plane_state->crtc) - crtc_state =3D drm_atomic_get_new_crtc_state(state, - plane_state->crtc); - pstate =3D to_dpu_plane_state(plane_state); for (i =3D 0; i < STAGES_PER_PLANE; i++) prev_adjacent_pstate[i] =3D prev_adjacent_plane_state[i] ? @@ -1285,6 +1216,10 @@ static int dpu_plane_virtual_assign_resources(struct= drm_crtc *crtc, if (!plane_state->fb) return -EINVAL; =20 + ret =3D dpu_plane_split(plane, plane_state, crtc_state); + if (ret) + return ret; + fmt =3D msm_framebuffer_format(plane_state->fb); reqs.yuv =3D MSM_FORMAT_IS_YUV(fmt); reqs.scale =3D (plane_state->src_w >> 16 !=3D plane_state->crtc_w) || @@ -1315,14 +1250,55 @@ static int dpu_plane_virtual_assign_resources(struc= t drm_crtc *crtc, return dpu_plane_atomic_check_sspp(plane, state, crtc_state); } =20 +static int dpu_plane_assign_resources(struct drm_crtc *crtc, + struct dpu_global_state *global_state, + struct drm_atomic_state *state, + struct drm_plane_state *plane_state, + const struct drm_crtc_state *crtc_state) +{ + struct drm_plane *plane =3D plane_state->plane; + struct dpu_kms *dpu_kms =3D _dpu_plane_get_kms(plane); + struct dpu_plane_state *pstate =3D to_dpu_plane_state(plane_state); + struct dpu_sw_pipe *pipe =3D &pstate->pipe[0]; + struct dpu_sw_pipe *r_pipe =3D &pstate->pipe[1]; + struct dpu_sw_pipe_cfg *pipe_cfg =3D &pstate->pipe_cfg[0]; + struct dpu_sw_pipe_cfg *r_pipe_cfg =3D &pstate->pipe_cfg[1]; + struct dpu_plane *pdpu =3D to_dpu_plane(plane); + int ret; + + pipe->sspp =3D dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); + if (!pipe->sspp) + return -EINVAL; + + ret =3D dpu_plane_split(plane, plane_state, crtc_state); + if (ret) + return ret; + + 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)) { + DPU_DEBUG_PLANE(pdpu, "invalid " DRM_RECT_FMT " /" DRM_RECT_FMT + " max_line:%u, can't use split source\n", + DRM_RECT_ARG(&pipe_cfg->src_rect), + DRM_RECT_ARG(&r_pipe_cfg->src_rect), + dpu_kms->catalog->caps->max_linewidth); + return -E2BIG; + } + + return dpu_plane_atomic_check_sspp(plane, state, crtc_state); +} + int dpu_assign_plane_resources(struct dpu_global_state *global_state, struct drm_atomic_state *state, struct drm_crtc *crtc, struct drm_plane_state **states, unsigned int num_planes) { - unsigned int i; struct drm_plane_state *prev_adjacent_plane_state[STAGES_PER_PLANE] =3D {= NULL }; + const struct drm_crtc_state *crtc_state =3D NULL; + unsigned int i; + int ret; =20 for (i =3D 0; i < num_planes; i++) { struct drm_plane_state *plane_state =3D states[i]; @@ -1331,8 +1307,18 @@ int dpu_assign_plane_resources(struct dpu_global_sta= te *global_state, !plane_state->visible) continue; =20 - int ret =3D dpu_plane_virtual_assign_resources(crtc, global_state, + if (plane_state->crtc) + crtc_state =3D drm_atomic_get_new_crtc_state(state, + plane_state->crtc); + + if (!dpu_use_virtual_planes) + ret =3D dpu_plane_assign_resources(crtc, global_state, + state, plane_state, + crtc_state); + else + ret =3D dpu_plane_virtual_assign_resources(crtc, global_state, state, plane_state, + crtc_state, prev_adjacent_plane_state); if (ret) return ret; @@ -1769,7 +1755,7 @@ static const struct drm_plane_helper_funcs dpu_plane_= helper_funcs =3D { static const struct drm_plane_helper_funcs dpu_plane_virtual_helper_funcs = =3D { .prepare_fb =3D dpu_plane_prepare_fb, .cleanup_fb =3D dpu_plane_cleanup_fb, - .atomic_check =3D dpu_plane_virtual_atomic_check, + .atomic_check =3D dpu_plane_atomic_check, .atomic_update =3D dpu_plane_atomic_update, }; =20 --=20 2.43.0