From nobody Thu Dec 26 19:24:24 2024 Received: from mail-lf1-f52.google.com (mail-lf1-f52.google.com [209.85.167.52]) (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 42CC239ACC for ; Sat, 30 Nov 2024 01:55:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732931728; cv=none; b=Z6LZzKw2E9P0JtXPsSD44j9sXgj6PkDCcJVAwAxFgtbQ62Xr1ZZwQxxCLY5zi/4KXjMnapIQVeIF43WbLTBOwM2iMZIaG47OK6wlERBIoGJUCLwI/SwfK5u2jILTSdjbPsr8nwuboMreGdob1Go/nzZ5DdhmueHDPx3GQGGOlK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732931728; c=relaxed/simple; bh=PWfj3Jvnff2hurmNN67nZfIITRvLrVRjVnbqovw8/II=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OBZBlp61IKlyVXdXuNTBObTvfBdi15vPj5+vRMxeFl6oA9MqK1I5oLcwyRy6kQ0QjXqOSt2mm/A92dg1AzXKYPZrXyCqF6Gya6ZhmW7IYWUkcZGgWJWJy4WB7I/8cYnSwVpnlmJPbNTtlrtTAtBA1/ZXAAKf4WA7r72vOUsuLnQ= 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=CUK6KcYo; arc=none smtp.client-ip=209.85.167.52 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="CUK6KcYo" Received: by mail-lf1-f52.google.com with SMTP id 2adb3069b0e04-53de8ecb39bso2868881e87.2 for ; Fri, 29 Nov 2024 17:55:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732931724; x=1733536524; 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=pJyvZI5sTNDWojPX/Iu1Zvq/k8S3hu5RWr4FZdwTI5M=; b=CUK6KcYowY1948LQeG6eQBHUgSVlv8UmlfffsalVB7R+QxNhg80sJzVRRSWqrPNy+d GoCywLO93D5XqHYpKnO03GUwo+Xw8xMFesZqoFz1W6G6aCkWtwn94ZBan/Zcdy0m9M6U VBTdGXnFVz66yMJvG5EJWNjN7pe3fjVW9haZcQjTw8XnOno4MnmVV5nF8MSjoEx8glJH cxMiqFPEgmvzWl+saHd9O3q/71A+KBpt3kwz6mqyGPywBu6pnMUTsYiz8WfjmGnrtJmA E9Gmh15VQZDIK2WuNAiF2XTruwzUhg43n17Lx7nwZ6+98JWMXCu/LS7eoqyDcH0TFdRZ Gz1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732931724; x=1733536524; 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=pJyvZI5sTNDWojPX/Iu1Zvq/k8S3hu5RWr4FZdwTI5M=; b=K7rq7J5QH8/1XHyjprUCeIX/gizPFavzuMUU/GLpGgQTz/7NPq8iezWjr9wp98EW5j WzUV1Zcx4p4eNiBx3iaKEbGkqwSlVx87k6dXUICueTpc221GXKlhlyeFMWvmH0Ojsssv 2CGz7IYed7IcLwjUtfZNGJFgyApNaSSqEntI9e6KJbmkmREMhFWtn1DzH4ZwFth6llS0 rmft2+TaGarxHPRpYEbKD5siWIlSSzpCCJ8djzzjPDQ7+f6zsM0IxFMHrtlMC191RJeA 8/ueWcEgEN3yliGo/xBPnntLBXZ65QFDevF579As0L25IeMTpLhTzy8aXnlIn9AknD7o VV2A== X-Forwarded-Encrypted: i=1; AJvYcCWVZGYid+tI9u28LpwDUDsPp3wbx+OdArew1FWbhymqiJPFTL4+a7YXsQk9WVo+baK8LOGOZrJKvbq2umY=@vger.kernel.org X-Gm-Message-State: AOJu0YzVZi1vehjY7vWw2AMvBwQ4MKr+uYSCtotUywTWSGppU8o1C0jB 6epD9XcOWIhwrAIgJsROeEB1MZ7Oe+GOS0VsmGXw8AqS2HX51S4I+Pb79LVm3bD2BPmv8eDJUJ+ J X-Gm-Gg: ASbGncscAkqKQ3YiFZeRM5McA0s7X+J7Dga9WXnh2PbeflOuhcaEso3JMETRi4S/3R1 0rVUT6Gy2FXqNGhXqtQ/5Puna1FxXqi4E9bsFGLd1iEPOE7fGzAeYHRIxuHO8ljfdrJphu2yGak KUA+srimaySrDzAX4UzrEpeUDbnt2UDLtBSnT8Ai4cUe4xldB2V3mW9qe4QaUEQbZsMyq4J5Dss 65bAz73ys5BTYkNDeq7kqlgub2ddSQKE/g2SHYoL3jN+ja+wvNGkXX2uQ== X-Google-Smtp-Source: AGHT+IEcw47JPaJ6tonLgMFlkgFPhP8c4eYx+2VdRj+IVx6CK0rHe5iOu9r8CVbz1c5FMtUIUxKxQA== X-Received: by 2002:a05:6512:3502:b0:53d:d3c1:9fc4 with SMTP id 2adb3069b0e04-53df010473amr9137540e87.41.1732931724362; Fri, 29 Nov 2024 17:55:24 -0800 (PST) Received: from umbar.lan ([192.130.178.90]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-53df6430cc8sm635601e87.31.2024.11.29.17.55.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Nov 2024 17:55:23 -0800 (PST) From: Dmitry Baryshkov Date: Sat, 30 Nov 2024 03:55:17 +0200 Subject: [PATCH v7 1/3] drm/msm/dpu: add support for virtual 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: <20241130-dpu-virtual-wide-v7-1-991053fcf63c@linaro.org> References: <20241130-dpu-virtual-wide-v7-0-991053fcf63c@linaro.org> In-Reply-To: <20241130-dpu-virtual-wide-v7-0-991053fcf63c@linaro.org> 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=22492; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=PWfj3Jvnff2hurmNN67nZfIITRvLrVRjVnbqovw8/II=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBnSnCHT9APtblwc5cC1AQc2fjISKIIo63BNTRW7 uie/kzEt8WJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZ0pwhwAKCRCLPIo+Aiko 1deeB/4xmeIB+bWVcr+cWP7Fm+kqjFH0FwXRhnX5TZYvrPOlG7ELJT33UGRbqs4+vE9V7JpX6yq zi1aXc8FD7sHf34E+j3Dpg2JQVduMv/NVt2aVqJHRARsxUbixiKSTeoxCQwlT209hImMM2x48Cc 0tdsuwfonyPYaWdkCmxgng/vN0czNKhQkfJTd67UK/4Y8PCvi9Zlo+hgkdfmXWCSfUQAoFbnZ6G pMYCYj7OVxIE/irvVDqDHPcVwy7ObqoNgMmKKKe8WaRbpz/gtFsWX9a+A+eTfnSlVnojwjteWRV +CSv70IWV6PRN3gqcHp9L71hdwCx+7HhCVQWUEIsNal8QLpT X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A Only several SSPP blocks support such features as YUV output or scaling, thus different DRM planes have different features. Properly utilizing all planes requires the attention of the compositor, who should prefer simpler planes to YUV-supporting ones. Otherwise it is very easy to end up in a situation when all featureful planes are already allocated for simple windows, leaving no spare plane for YUV playback. To solve this problem make all planes virtual. Each plane is registered as if it supports all possible features, but then at the runtime during the atomic_check phase the driver selects backing SSPP block for each plane. As the planes are attached to the CRTC and not the encoder, the SSPP blocks are also allocated per CRTC ID (all other resources are currently allocated per encoder ID). This also matches the hardware requirement, where both rectangles of a single SSPP can only be used with the LM pair. Note, this does not provide support for using two different SSPP blocks for a single plane or using two rectangles of an SSPP to drive two planes. Each plane still gets its own SSPP and can utilize either a solo rectangle or both multirect rectangles depending on the resolution. Note #2: By default support for virtual planes is turned off and the driver still uses old code path with preallocated SSPP block for each plane. To enable virtual planes, pass 'msm.dpu_use_virtual_planes=3D1' kernel parameter. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 50 ++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 + drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 264 ++++++++++++++++++++++++++= ---- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 13 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 82 ++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 14 ++ 7 files changed, 399 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm= /disp/dpu1/dpu_crtc.c index 9f6ffd344693ecfb633095772a31ada5613345dc..fcbcac00c8500cfff8546279524= 638e1f5ae3f18 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1182,6 +1182,49 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_s= tate *cstate) return false; } =20 +static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc= _state *crtc_state) +{ + int total_planes =3D crtc->dev->mode_config.num_total_plane; + struct drm_atomic_state *state =3D crtc_state->state; + struct dpu_global_state *global_state; + struct drm_plane_state **states; + struct drm_plane *plane; + int ret; + + 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); + + if (!crtc_state->enable) + return 0; + + states =3D kcalloc(total_planes, sizeof(*states), GFP_KERNEL); + if (!states) + return -ENOMEM; + + drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { + struct drm_plane_state *plane_state =3D + drm_atomic_get_plane_state(state, plane); + + if (IS_ERR(plane_state)) { + ret =3D PTR_ERR(plane_state); + goto done; + } + + states[plane_state->normalized_zpos] =3D plane_state; + } + + ret =3D dpu_assign_plane_resources(global_state, state, crtc, states, tot= al_planes); + +done: + kfree(states); + return ret; + + return 0; +} + static int dpu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { @@ -1197,6 +1240,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *cr= tc, =20 bool needs_dirtyfb =3D dpu_crtc_needs_dirtyfb(crtc_state); =20 + if (dpu_use_virtual_planes && + (crtc_state->planes_changed || crtc_state->zpos_changed)) { + rc =3D dpu_crtc_reassign_planes(crtc, crtc_state); + if (rc < 0) + return rc; + } + if (!crtc_state->enable || !drm_atomic_crtc_effectively_active(crtc_state= )) { DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n", crtc->base.id, crtc_state->enable, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/= disp/dpu1/dpu_kms.c index ca4847b2b73876c59dedff1e3ec4188ea70860a7..afb2ee309772b1aa7b93eddde96= 0028bdb612a1e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -51,6 +51,9 @@ #define DPU_DEBUGFS_DIR "msm_dpu" #define DPU_DEBUGFS_HWMASKNAME "hw_log_mask" =20 +bool dpu_use_virtual_planes; +module_param(dpu_use_virtual_planes, bool, 0); + static int dpu_kms_hw_init(struct msm_kms *kms); static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms); =20 @@ -829,8 +832,11 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_k= ms) type, catalog->sspp[i].features, catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR)); =20 - plane =3D dpu_plane_init(dev, catalog->sspp[i].id, type, - (1UL << max_crtc_count) - 1); + if (dpu_use_virtual_planes) + plane =3D dpu_plane_init_virtual(dev, type, (1UL << max_crtc_count) - 1= ); + else + plane =3D dpu_plane_init(dev, catalog->sspp[i].id, type, + (1UL << max_crtc_count) - 1); if (IS_ERR(plane)) { DPU_ERROR("dpu_plane_init failed\n"); ret =3D PTR_ERR(plane); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/= disp/dpu1/dpu_kms.h index 88d64d43ea1a8226b414f04bf76551f7dda94ef6..547cdb2c0c788a031685e397e2c= 8ef73ca6290d7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -54,6 +54,8 @@ #define ktime_compare_safe(A, B) \ ktime_compare(ktime_sub((A), (B)), ktime_set(0, 0)) =20 +extern bool dpu_use_virtual_planes; + struct dpu_kms { struct msm_kms base; struct drm_device *dev; @@ -128,6 +130,8 @@ struct dpu_global_state { 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 sspp_to_crtc_id[SSPP_MAX - SSPP_NONE]; }; =20 struct dpu_global_state diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/ms= m/disp/dpu1/dpu_plane.c index 3ffac24333a2a5b01135d4ece418432d4a74dc04..309a8cdaafcf3dacd1c7ba4e0cd= db7f3f56423c0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -878,7 +878,7 @@ static int dpu_plane_atomic_check_nosspp(struct drm_pla= ne *plane, drm_rect_rotate_inv(&pipe_cfg->src_rect, new_plane_state->fb->width, new_plane_state->fb->height, new_plane_state->rotation); - if (r_pipe_cfg->src_rect.x1 !=3D 0) + if (drm_rect_width(&r_pipe_cfg->src_rect) !=3D 0) drm_rect_rotate_inv(&r_pipe_cfg->src_rect, new_plane_state->fb->width, new_plane_state->fb->height, new_plane_state->rotation); @@ -1001,8 +1001,13 @@ static int dpu_plane_atomic_check(struct drm_plane *= plane, crtc_state =3D drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); =20 - pipe->sspp =3D dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); - r_pipe->sspp =3D NULL; + if (pdpu->pipe !=3D SSPP_NONE) { + pipe->sspp =3D dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); + r_pipe->sspp =3D NULL; + } + + if (!pipe->sspp) + return -EINVAL; =20 ret =3D dpu_plane_atomic_check_nosspp(plane, new_plane_state, crtc_state); if (ret) @@ -1019,6 +1024,112 @@ static int dpu_plane_atomic_check(struct drm_plane = *plane, return dpu_plane_atomic_check_sspp(plane, state, crtc_state); } =20 +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); + struct drm_crtc_state *crtc_state; + int ret; + + if (plane_state->crtc) + crtc_state =3D drm_atomic_get_new_crtc_state(state, + plane_state->crtc); + + ret =3D dpu_plane_atomic_check_nosspp(plane, plane_state, crtc_state); + if (ret) + return ret; + + if (!plane_state->visible) { + /* + * resources are freed by dpu_crtc_assign_plane_resources(), + * but clean them here. + */ + pstate->pipe.sspp =3D NULL; + pstate->r_pipe.sspp =3D NULL; + + return 0; + } + + /* force resource reallocation if the format of FB has changed */ + if (!old_plane_state || !old_plane_state->fb || + msm_framebuffer_format(old_plane_state->fb) !=3D + msm_framebuffer_format(plane_state->fb)) + crtc_state->planes_changed =3D true; + + return 0; +} + +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 =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_sw_pipe *pipe; + struct dpu_sw_pipe *r_pipe; + const struct msm_format *fmt; + + 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); + pipe =3D &pstate->pipe; + r_pipe =3D &pstate->r_pipe; + + pipe->sspp =3D NULL; + r_pipe->sspp =3D NULL; + + if (!plane_state->fb) + return -EINVAL; + + 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) || + (plane_state->src_h >> 16 !=3D plane_state->crtc_h); + + reqs.rot90 =3D drm_rotation_90_or_270(plane_state->rotation); + + pipe->sspp =3D dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &req= s); + if (!pipe->sspp) + return -ENODEV; + + 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; + int ret; + + for (i =3D 0; i < num_planes; i++) { + struct drm_plane_state *plane_state =3D states[i]; + + if (!plane_state || + !plane_state->visible) + continue; + + ret =3D dpu_plane_virtual_assign_resources(crtc, global_state, + state, plane_state); + if (ret) + break; + } + + return ret; +} + static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe= *pipe) { const struct msm_format *format =3D @@ -1335,12 +1446,15 @@ static void dpu_plane_atomic_print_state(struct drm= _printer *p, =20 drm_printf(p, "\tstage=3D%d\n", pstate->stage); =20 - drm_printf(p, "\tsspp[0]=3D%s\n", pipe->sspp->cap->name); - drm_printf(p, "\tmultirect_mode[0]=3D%s\n", dpu_get_multirect_mode(pipe->= multirect_mode)); - drm_printf(p, "\tmultirect_index[0]=3D%s\n", - dpu_get_multirect_index(pipe->multirect_index)); - drm_printf(p, "\tsrc[0]=3D" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->sr= c_rect)); - drm_printf(p, "\tdst[0]=3D" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->ds= t_rect)); + if (pipe->sspp) { + drm_printf(p, "\tsspp[0]=3D%s\n", pipe->sspp->cap->name); + drm_printf(p, "\tmultirect_mode[0]=3D%s\n", + dpu_get_multirect_mode(pipe->multirect_mode)); + drm_printf(p, "\tmultirect_index[0]=3D%s\n", + dpu_get_multirect_index(pipe->multirect_index)); + drm_printf(p, "\tsrc[0]=3D" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->s= rc_rect)); + drm_printf(p, "\tdst[0]=3D" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->d= st_rect)); + } =20 if (r_pipe->sspp) { drm_printf(p, "\tsspp[1]=3D%s\n", r_pipe->sspp->cap->name); @@ -1433,39 +1547,29 @@ static const struct drm_plane_helper_funcs dpu_plan= e_helper_funcs =3D { .atomic_update =3D dpu_plane_atomic_update, }; =20 -/** - * dpu_plane_init - create new dpu plane for the given pipe - * @dev: Pointer to DRM device - * @pipe: dpu hardware pipe identifier - * @type: Plane type - PRIMARY/OVERLAY/CURSOR - * @possible_crtcs: bitmask of crtc that can be attached to the given pipe - * - * Initialize the plane. - */ -struct drm_plane *dpu_plane_init(struct drm_device *dev, - uint32_t pipe, enum drm_plane_type type, - unsigned long possible_crtcs) +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_update =3D dpu_plane_atomic_update, +}; + +/* initialize plane */ +static struct drm_plane *dpu_plane_init_common(struct drm_device *dev, + enum drm_plane_type type, + unsigned long possible_crtcs, + bool inline_rotation, + const uint32_t *format_list, + uint32_t num_formats, + enum dpu_sspp pipe) { struct drm_plane *plane =3D NULL; - const uint32_t *format_list; struct dpu_plane *pdpu; struct msm_drm_private *priv =3D dev->dev_private; struct dpu_kms *kms =3D to_dpu_kms(priv->kms); - struct dpu_hw_sspp *pipe_hw; - uint32_t num_formats; uint32_t supported_rotations; int ret; =20 - /* initialize underlying h/w driver */ - pipe_hw =3D dpu_rm_get_sspp(&kms->rm, pipe); - if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) { - DPU_ERROR("[%u]SSPP is invalid\n", pipe); - return ERR_PTR(-EINVAL); - } - - format_list =3D pipe_hw->cap->sblk->format_list; - num_formats =3D pipe_hw->cap->sblk->num_formats; - pdpu =3D drmm_universal_plane_alloc(dev, struct dpu_plane, base, 0xff, &dpu_plane_funcs, format_list, num_formats, @@ -1491,7 +1595,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *d= ev, =20 supported_rotations =3D DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0 | DRM_M= ODE_ROTATE_180; =20 - if (pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION)) + if (inline_rotation) supported_rotations |=3D DRM_MODE_ROTATE_MASK; =20 drm_plane_create_rotation_property(plane, @@ -1499,10 +1603,98 @@ struct drm_plane *dpu_plane_init(struct drm_device = *dev, =20 drm_plane_enable_fb_damage_clips(plane); =20 - /* success! finalize initialization */ + DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name, + pipe, plane->base.id); + return plane; +} + +/** + * dpu_plane_init - create new dpu plane for the given pipe + * @dev: Pointer to DRM device + * @pipe: dpu hardware pipe identifier + * @type: Plane type - PRIMARY/OVERLAY/CURSOR + * @possible_crtcs: bitmask of crtc that can be attached to the given pipe + * + * Initialize the plane. + */ +struct drm_plane *dpu_plane_init(struct drm_device *dev, + uint32_t pipe, enum drm_plane_type type, + unsigned long possible_crtcs) +{ + struct drm_plane *plane =3D NULL; + struct msm_drm_private *priv =3D dev->dev_private; + struct dpu_kms *kms =3D to_dpu_kms(priv->kms); + struct dpu_hw_sspp *pipe_hw; + + /* initialize underlying h/w driver */ + pipe_hw =3D dpu_rm_get_sspp(&kms->rm, pipe); + if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) { + DPU_ERROR("[%u]SSPP is invalid\n", pipe); + return ERR_PTR(-EINVAL); + } + + + plane =3D dpu_plane_init_common(dev, type, possible_crtcs, + pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION), + pipe_hw->cap->sblk->format_list, + pipe_hw->cap->sblk->num_formats, + pipe); + if (IS_ERR(plane)) + return plane; + drm_plane_helper_add(plane, &dpu_plane_helper_funcs); =20 DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name, pipe, plane->base.id); + + return plane; +} + +/** + * dpu_plane_init_virtual - create new virtualized DPU plane + * @dev: Pointer to DRM device + * @type: Plane type - PRIMARY/OVERLAY/CURSOR + * @possible_crtcs: bitmask of crtc that can be attached to the given pipe + * + * Initialize the virtual plane with no backing SSPP / pipe. + */ +struct drm_plane *dpu_plane_init_virtual(struct drm_device *dev, + enum drm_plane_type type, + unsigned long possible_crtcs) +{ + struct drm_plane *plane =3D NULL; + struct msm_drm_private *priv =3D dev->dev_private; + struct dpu_kms *kms =3D to_dpu_kms(priv->kms); + bool has_inline_rotation =3D false; + const u32 *format_list =3D NULL; + u32 num_formats =3D 0; + int i; + + /* Determine the largest configuration that we can implement */ + for (i =3D 0; i < kms->catalog->sspp_count; i++) { + const struct dpu_sspp_cfg *cfg =3D &kms->catalog->sspp[i]; + + if (test_bit(DPU_SSPP_INLINE_ROTATION, &cfg->features)) + has_inline_rotation =3D true; + + if (!format_list || + cfg->sblk->csc_blk.len) { + format_list =3D cfg->sblk->format_list; + num_formats =3D cfg->sblk->num_formats; + } + } + + plane =3D dpu_plane_init_common(dev, type, possible_crtcs, + has_inline_rotation, + format_list, + num_formats, + SSPP_NONE); + if (IS_ERR(plane)) + return plane; + + drm_plane_helper_add(plane, &dpu_plane_virtual_helper_funcs); + + DPU_DEBUG("%s created virtual id:%u\n", plane->name, plane->base.id); + return plane; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/ms= m/disp/dpu1/dpu_plane.h index 97090ca7842b41c697090665d89194a87c02cba1..acd5725175cdde4fcf7a9f71bb4= 46251c5a14d22 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h @@ -62,10 +62,23 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, uint32_t pipe, enum drm_plane_type type, unsigned long possible_crtcs); =20 +struct drm_plane *dpu_plane_init_virtual(struct drm_device *dev, + enum drm_plane_type type, + unsigned long possible_crtcs); + +int dpu_plane_color_fill(struct drm_plane *plane, + uint32_t color, uint32_t alpha); + #ifdef CONFIG_DEBUG_FS void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable); #else static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, b= ool enable) {} #endif =20 +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); + #endif /* _DPU_PLANE_H_ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/d= isp/dpu1/dpu_rm.c index c247af03dc8ef7174eedf3d5cc267d64f17a8656..4964aa92ce18f9da3b9ca4e599b= 13ffb02dd81e4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -725,6 +725,88 @@ int dpu_rm_reserve( return ret; } =20 +static struct dpu_hw_sspp *dpu_rm_try_sspp(struct dpu_rm *rm, + struct dpu_global_state *global_state, + struct drm_crtc *crtc, + struct dpu_rm_sspp_requirements *reqs, + unsigned int type) +{ + uint32_t crtc_id =3D crtc->base.id; + struct dpu_hw_sspp *hw_sspp; + int i; + + for (i =3D 0; i < ARRAY_SIZE(rm->hw_sspp); i++) { + if (!rm->hw_sspp[i]) + continue; + + if (global_state->sspp_to_crtc_id[i]) + continue; + + hw_sspp =3D rm->hw_sspp[i]; + + if (hw_sspp->cap->type !=3D type) + continue; + + if (reqs->scale && !hw_sspp->cap->sblk->scaler_blk.len) + continue; + + // TODO: QSEED2 and RGB scalers are not yet supported + if (reqs->scale && !hw_sspp->ops.setup_scaler) + continue; + + if (reqs->yuv && !hw_sspp->cap->sblk->csc_blk.len) + continue; + + if (reqs->rot90 && !(hw_sspp->cap->features & DPU_SSPP_INLINE_ROTATION)) + continue; + + global_state->sspp_to_crtc_id[i] =3D crtc_id; + + return rm->hw_sspp[i]; + } + + return NULL; +} + +/** + * dpu_rm_reserve_sspp - Reserve the required SSPP for the provided CRTC + * @rm: DPU Resource Manager handle + * @global_state: private global state + * @crtc: DRM CRTC handle + * @reqs: SSPP required features + */ +struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm, + struct dpu_global_state *global_state, + struct drm_crtc *crtc, + struct dpu_rm_sspp_requirements *reqs) +{ + struct dpu_hw_sspp *hw_sspp =3D NULL; + + if (!reqs->scale && !reqs->yuv) + hw_sspp =3D dpu_rm_try_sspp(rm, global_state, crtc, reqs, SSPP_TYPE_DMA); + if (!hw_sspp && reqs->scale) + hw_sspp =3D dpu_rm_try_sspp(rm, global_state, crtc, reqs, SSPP_TYPE_RGB); + if (!hw_sspp) + hw_sspp =3D dpu_rm_try_sspp(rm, global_state, crtc, reqs, SSPP_TYPE_VIG); + + return hw_sspp; +} + +/** + * dpu_rm_release_all_sspp - Given the CRTC, release all SSPP + * blocks previously reserved for that use case. + * @rm: DPU Resource Manager handle + * @crtc: DRM CRTC handle + */ +void dpu_rm_release_all_sspp(struct dpu_global_state *global_state, + struct drm_crtc *crtc) +{ + uint32_t crtc_id =3D crtc->base.id; + + _dpu_rm_clear_mapping(global_state->sspp_to_crtc_id, + ARRAY_SIZE(global_state->sspp_to_crtc_id), crtc_id); +} + /** * dpu_rm_get_assigned_resources - Get hw resources of the given type that= are * assigned to this encoder diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/d= isp/dpu1/dpu_rm.h index ea0e49cb7b0d3e05dfa57442784c83acb69c3ada..9cdfa53d7173d41dfefe985fdc7= 7f1885dbec4ff 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -37,6 +37,12 @@ struct dpu_rm { struct dpu_hw_blk *cdm_blk; }; =20 +struct dpu_rm_sspp_requirements { + bool yuv; + bool scale; + bool rot90; +}; + /** * struct msm_display_topology - defines a display topology pipeline * @num_lm: number of layer mixers used @@ -68,6 +74,14 @@ int dpu_rm_reserve(struct dpu_rm *rm, void dpu_rm_release(struct dpu_global_state *global_state, struct drm_encoder *enc); =20 +struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm, + struct dpu_global_state *global_state, + struct drm_crtc *crtc, + struct dpu_rm_sspp_requirements *reqs); + +void dpu_rm_release_all_sspp(struct dpu_global_state *global_state, + struct drm_crtc *crtc); + int dpu_rm_get_assigned_resources(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t enc_id, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size); --=20 2.39.5 From nobody Thu Dec 26 19:24:24 2024 Received: from mail-lf1-f50.google.com (mail-lf1-f50.google.com [209.85.167.50]) (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 B806A12CD8B for ; Sat, 30 Nov 2024 01:55:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732931730; cv=none; b=SATw5h4dE3sDcCXw5KtSHw/QZrFesm5yJQ1KdzP5hswLJSH1DEXA++pmWca8zQ775RornhmETcjoR3NG5HtME27XbNTQWKZa/gJOW0wCKmbqdw6nATBX/8JgxAb4A271b8+603C2c5WOcQXxxw1mx16U3kSDcmIe/zXEZuK802w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732931730; c=relaxed/simple; bh=tnabCVU1SaNGNfJfuPGtjX+5svo205A46mZ25LOgd7c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cLTE0ZWjOQciWoldz1lqWAZmsiKDlObFdiSORzoEv6EnOs11m2N8B7GU2uMQm7N4wm7ssN03pRr0rC0I8Pq1ogyBorjsXwxeaEulaEoSaCTsoDR4ZMlXWshTVdiMm2i9sx9fekF85Zr3cfp8YDXElG8pXBpY6Wb9j4v/U+OA9Fc= 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=CxImv9+/; arc=none smtp.client-ip=209.85.167.50 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="CxImv9+/" Received: by mail-lf1-f50.google.com with SMTP id 2adb3069b0e04-53de556ecdaso2547328e87.1 for ; Fri, 29 Nov 2024 17:55:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732931727; x=1733536527; 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=261PimRoKlrpsFq5MeoCEW7BIk620Ollnqdg7IYILxM=; b=CxImv9+/RYhZ11cZgMtSOxbINcGHbkLf8BnnMz2jSGV0hNgjIYPYOtg2AmBbLW2aOz G6NqjkoYIfRUXVizzsxPTR1AjlY99PteyluiiwRAIIO6vqpIx6MPeBN1Wl2cWmfqPz4U 3VEi+wfqAFeuRVSL2fr43A5wT1R7nQ9cRyKwDFrmpcyMh/vCjCvZOqfohnH0JqGM9BBN p8eT43/lbRTu6OCHWAv9m8i9bn9HGbf0F6WhZjlq4QfFvwZ3et8N/uenKMhOMMuXbisJ yLTWIOAs8u34dgY8MC9SaouobqddrRo/bCxKH90PuMn37D+b9SnVigLnSu0JU2yzCZU/ FuIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732931727; x=1733536527; 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=261PimRoKlrpsFq5MeoCEW7BIk620Ollnqdg7IYILxM=; b=s00XtNT10L6iBUoojOr556Iek+2khBO9psN2NQJ/2kmTbuO8zJKIIDVdNFfnwc2QPy mcvG79PCFe7MJH2l/nwtB8FvzyhxFJLkhRCYwrEWb9cnR0RL+N70eV92y6DOGXf/jnMg pY0EWgTvX20qo0bAsKXKBRdnxoMsf+IRRtZeurXnzhMJF9c/ylvCPKRxHxn82LmGJKF1 Q1Kjq1O4XPww92x4hIf6wz1y36Ay8SY35uSnJPecrs2HkH2wm+3eXwh4Ek4s6CYsClv0 IaYY0Eu3vJcuU5sQQ0ozOnhP2Qz2JTZ4lWoyF/L0lTLXHh6M1tyYC4qQV4FpLV0qFloq QQVA== X-Forwarded-Encrypted: i=1; AJvYcCVQGlEcLRrR0nZRZ2z6ffC4WHfKlpfhGW2Dvu0CUCnPgZIrF3VMCYSYQN8vNpAP/FNpVRhhZDgqoiT77hY=@vger.kernel.org X-Gm-Message-State: AOJu0Yy4IUhokvrTdaQZXAi2S+Fv/ud76/URlEI3bLbHjUXA6qbJ/j72 GMrUWORWwV09v50abT05B1kKH+R2Q6oK+bo1w9yR1q0QEQ+erHZ+UHa7gc9/vns= X-Gm-Gg: ASbGncsrs26lKbqy9B74zxK4seDfF0tDUIPrIHeTHbcTEdaw+lgKCcLlAzA5AcmZiGe suAwxrxIdWNmj5XoK6wkzciVycHheZxAOt/kZ+Np35WCPfRaFRYkkAT1Mc9XxtLdA1Nusj/M9Rf kmIBBnnlseIJDetPo+fJ52GVLXIEZIrsRhxmzHK+jDVTHV+7a7NbI5d9850KJD+akajri6mH+Zn jW9ZI2s/wTz31EWGEOI+daxnWKm8CGe/w1peziohZctV9mFPNu1zhiPsQ== X-Google-Smtp-Source: AGHT+IFOOIPTtn6KR/WtjysReR/LUG2OFBudpST3Ur89aymaHdky9RA2243KKYdLtY9RzNbHPwIonQ== X-Received: by 2002:a05:6512:a94:b0:53d:e397:2dd2 with SMTP id 2adb3069b0e04-53df00aa1c9mr7921612e87.2.1732931726833; Fri, 29 Nov 2024 17:55:26 -0800 (PST) Received: from umbar.lan ([192.130.178.90]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-53df6430cc8sm635601e87.31.2024.11.29.17.55.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Nov 2024 17:55:25 -0800 (PST) From: Dmitry Baryshkov Date: Sat, 30 Nov 2024 03:55:18 +0200 Subject: [PATCH v7 2/3] drm/msm/dpu: allow using two SSPP blocks for a single plane 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: <20241130-dpu-virtual-wide-v7-2-991053fcf63c@linaro.org> References: <20241130-dpu-virtual-wide-v7-0-991053fcf63c@linaro.org> In-Reply-To: <20241130-dpu-virtual-wide-v7-0-991053fcf63c@linaro.org> 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=10016; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=tnabCVU1SaNGNfJfuPGtjX+5svo205A46mZ25LOgd7c=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBnSnCHScBaUh+cOZL423003QuXwpn6b8mUYyBzv 6IB41XdNCSJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZ0pwhwAKCRCLPIo+Aiko 1a2QB/4tQX5o2eHeN9nCjARC/3AOX/bLesJhtdOpwDMO8IOHlhLcjRo4tTz374pMGdZ+exlSDvS l4xMYQaQh957h0dFg/qQ++Xqx2I4eonSJZuMTBQzTbe+yZJIqW7E/KIlPGnpbQE22IwqsyK6Uu1 70hp4qGGlu3gu0oMcice/En0ZMn39nO7hg9EkL1TjTmrp/pzu2C618mn08t7eRC5fWU6laIFJdy DMwLGpb85EXSpRFv07vNaWqE0c96bOKxJ32M5ZC7PH4a6OnU0PR2B9obbokXxtcW81+EYPYKuq1 T6t4ldzEVis+SREokaLzkaOuiobgeXbMuBX953W0FdXcOSLo X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A Virtual wide planes give high amount of flexibility, but it is not always enough: In parallel multirect case only the half of the usual width is supported for tiled formats. Thus the whole width of two tiled multirect rectangles can not be greater than max_linewidth, which is not enough for some platforms/compositors. Another example is as simple as wide YUV plane. YUV planes can not use multirect, so currently they are limited to max_linewidth too. Now that the planes are fully virtualized, add support for allocating two SSPP blocks to drive a single DRM plane. This fixes both mentioned cases and allows all planes to go up to 2*max_linewidth (at the cost of making some of the planes unavailable to the user). Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 144 ++++++++++++++++++++------= ---- 1 file changed, 98 insertions(+), 46 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 309a8cdaafcf3dacd1c7ba4e0cddb7f3f56423c0..098abc2c0003cde90ce6219c97e= e18fa055a92a5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -20,7 +20,6 @@ #include "msm_drv.h" #include "msm_mdss.h" #include "dpu_kms.h" -#include "dpu_formats.h" #include "dpu_hw_sspp.h" #include "dpu_hw_util.h" #include "dpu_trace.h" @@ -888,6 +887,32 @@ 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) +{ + 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)) + return false; + + if (pipe_cfg->rotation & DRM_MODE_ROTATE_90) + return false; + + if (MSM_FORMAT_IS_YUV(fmt)) + return false; + + 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; + + return true; +} + static int dpu_plane_atomic_check_sspp(struct drm_plane *plane, struct drm_atomic_state *state, const struct drm_crtc_state *crtc_state) @@ -901,7 +926,6 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane= *plane, const struct msm_format *fmt; struct dpu_sw_pipe_cfg *pipe_cfg =3D &pstate->pipe_cfg; struct dpu_sw_pipe_cfg *r_pipe_cfg =3D &pstate->r_pipe_cfg; - uint32_t max_linewidth; uint32_t supported_rotations; const struct dpu_sspp_cfg *pipe_hw_caps; const struct dpu_sspp_sub_blks *sblk; @@ -923,8 +947,6 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane= *plane, =20 fmt =3D msm_framebuffer_format(new_plane_state->fb); =20 - max_linewidth =3D pdpu->catalog->caps->max_linewidth; - supported_rotations =3D DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0; =20 if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) @@ -940,48 +962,43 @@ static int dpu_plane_atomic_check_sspp(struct drm_pla= ne *plane, return ret; =20 if (drm_rect_width(&r_pipe_cfg->src_rect) !=3D 0) { - /* - * In parallel multirect case only the half of the usual width - * is supported for tiled formats. If we are here, we know that - * full width is more than max_linewidth, thus each rect is - * wider than allowed. - */ - if (MSM_FORMAT_IS_UBWC(fmt) && - drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) { - DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, tiled form= at\n", - DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); - return -E2BIG; - } + ret =3D dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt, + &crtc_state->adjusted_mode); + if (ret) + return ret; + } =20 - if (drm_rect_width(&pipe_cfg->src_rect) !=3D drm_rect_width(&pipe_cfg->d= st_rect) || - drm_rect_height(&pipe_cfg->src_rect) !=3D drm_rect_height(&pipe_cfg-= >dst_rect) || - (!test_bit(DPU_SSPP_SMART_DMA_V1, &pipe->sspp->cap->features) && - !test_bit(DPU_SSPP_SMART_DMA_V2, &pipe->sspp->cap->features)) || - pipe_cfg->rotation & DRM_MODE_ROTATE_90 || - MSM_FORMAT_IS_YUV(fmt)) { - DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, can't use = split source\n", - DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); - return -E2BIG; - } + return 0; +} + +static bool dpu_plane_try_multirect_parallel(struct dpu_sw_pipe *pipe, str= uct dpu_sw_pipe_cfg *pipe_cfg, + struct dpu_sw_pipe *r_pipe, struct dpu_sw_pipe_cfg *r_pipe_cfg, + struct dpu_hw_sspp *sspp, const struct msm_format *fmt, + uint32_t max_linewidth) +{ + 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; + + if (drm_rect_width(&r_pipe_cfg->src_rect) !=3D 0) { + if (!dpu_plane_is_multirect_parallel_capable(pipe->sspp, pipe_cfg, fmt, = max_linewidth) || + !dpu_plane_is_multirect_parallel_capable(pipe->sspp, r_pipe_cfg, fmt= , max_linewidth)) + return false; + + r_pipe->sspp =3D pipe->sspp; =20 - /* - * Use multirect for wide plane. We do not support dynamic - * assignment of SSPPs, so we know the configuration. - */ pipe->multirect_index =3D DPU_SSPP_RECT_0; pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_PARALLEL; =20 - r_pipe->sspp =3D pipe->sspp; r_pipe->multirect_index =3D DPU_SSPP_RECT_1; r_pipe->multirect_mode =3D DPU_SSPP_MULTIRECT_PARALLEL; - - ret =3D dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt, - &crtc_state->adjusted_mode); - if (ret) - return ret; } =20 - return 0; + return true; } =20 static int dpu_plane_atomic_check(struct drm_plane *plane, @@ -995,16 +1012,16 @@ static int dpu_plane_atomic_check(struct drm_plane *= plane, struct dpu_kms *dpu_kms =3D _dpu_plane_get_kms(plane); 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_cfg *r_pipe_cfg =3D &pstate->r_pipe_cfg; const struct drm_crtc_state *crtc_state =3D NULL; + uint32_t max_linewidth =3D dpu_kms->catalog->caps->max_linewidth; =20 if (new_plane_state->crtc) crtc_state =3D drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); =20 - if (pdpu->pipe !=3D SSPP_NONE) { - pipe->sspp =3D dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); - r_pipe->sspp =3D NULL; - } + pipe->sspp =3D dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); =20 if (!pipe->sspp) return -EINVAL; @@ -1016,10 +1033,17 @@ static int dpu_plane_atomic_check(struct drm_plane = *plane, if (!new_plane_state->visible) return 0; =20 - 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; + 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; + } =20 return dpu_plane_atomic_check_sspp(plane, state, crtc_state); } @@ -1054,8 +1078,16 @@ static int dpu_plane_virtual_atomic_check(struct drm= _plane *plane, return 0; } =20 - /* force resource reallocation if the format of FB has changed */ + /* + * Force resource reallocation if the format of FB or src/dst have + * changed. We might need to allocate different SSPP or SSPPs for this + * plane than the one used previously. + */ if (!old_plane_state || !old_plane_state->fb || + old_plane_state->src_w !=3D plane_state->src_w || + old_plane_state->src_h !=3D plane_state->src_h || + old_plane_state->src_w !=3D plane_state->src_w || + old_plane_state->crtc_h !=3D plane_state->crtc_h || msm_framebuffer_format(old_plane_state->fb) !=3D msm_framebuffer_format(plane_state->fb)) crtc_state->planes_changed =3D true; @@ -1075,6 +1107,8 @@ static int dpu_plane_virtual_assign_resources(struct = drm_crtc *crtc, 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; const struct msm_format *fmt; =20 if (plane_state->crtc) @@ -1084,6 +1118,8 @@ static int dpu_plane_virtual_assign_resources(struct = drm_crtc *crtc, pstate =3D to_dpu_plane_state(plane_state); pipe =3D &pstate->pipe; r_pipe =3D &pstate->r_pipe; + pipe_cfg =3D &pstate->pipe_cfg; + r_pipe_cfg =3D &pstate->r_pipe_cfg; =20 pipe->sspp =3D NULL; r_pipe->sspp =3D NULL; @@ -1102,6 +1138,22 @@ static int dpu_plane_virtual_assign_resources(struct= drm_crtc *crtc, 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) + return -ENODEV; + + 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; + } + return dpu_plane_atomic_check_sspp(plane, state, crtc_state); } =20 --=20 2.39.5 From nobody Thu Dec 26 19:24:24 2024 Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (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 0C3A113BACC for ; Sat, 30 Nov 2024 01:55:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732931732; cv=none; b=U3t2TLUEhuSvOoHuBp38QUF0NzSF7AQ6gECc5sk2KzNafp2sUhu94bWbcjs3mTCbOxpH+Nfq3QdMc+7Xj4+zSFS8awVaGIMUPQTjFc6yg4bceGFT96AmJe2vIxsXrg9pY+q2ic6i4+QQg1m2vNLyFhHSbAqPo9NW9LK1tqSS7rE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732931732; c=relaxed/simple; bh=0H6B6m4YfEscj5/eTxfCR+sI5ay0GD8NDcl46LffCeo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ooVgQJ7Z6aGTudW0Id6+LffxPDbty6EOcz3Jg7gpK6WNnqStF7vuiYrhhr1FHJTs+y4/lBoT8RIH9qPj+DUJ0K0BLHzpXMgSdHkRLAOUe7qlcAWw7cMJ1Vz6NrkB3dQyAQJmeaumMz/4kMWIdtahFKLlGF3WNW2gJ0FwBiPoPaU= 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=OBVepebq; arc=none smtp.client-ip=209.85.167.43 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="OBVepebq" Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-53dd2fdcebcso2887399e87.0 for ; Fri, 29 Nov 2024 17:55:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732931729; x=1733536529; 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=IUEcAbfuBPO7l5+gt8OvRpERGEOEeXxRlakeMrm+69Y=; b=OBVepebqpxz1zziwtfDCbATItEwTP4VVFB4uJq+BiSGn3HsmwTDojRZ4LFuMyeGTG/ E+rSHXEBnNQxSLRXeqoNxcG/Mdwtbs1Fvno4AKBpUZ6ko1jh654yXVJhAtCw6JIP9bsB SjLQXkMz71n3jY3Vth0XrYLRVpJdbD1GC7eMFn9TpJLZeFNDZHLVI46peBfECiKYEAs+ wuwKSJkhj18vSNLayIReRlC4azrKtUeae+A+zNOBNpDpYidJ1goEW0IYKQsC6Q3sV1Dw dozCsH24/Wdh8+m+uibMwqiEFer5sjoTkzSKprM3OAkjAVHNczB41v4NZHZFKKiOZpN5 ireg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732931729; x=1733536529; 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=IUEcAbfuBPO7l5+gt8OvRpERGEOEeXxRlakeMrm+69Y=; b=G6QIBd/syN2/iwk3un1tLL+jMvLUKEvSs2c7bVM5FTmS1Xw0GNiWAZPm0B4ZAXiVhf /Y/RPlUH24m2rJb4bSgWfYQliq2H1E7V9s+r9xGP+A1sw0cZmFMblBwwihGHWkznkvyA 6AQuCCkXJOhNOvmUD0XsRX5dYW5MMJChSP/uaOGj76QdhE8YyQUfN5CACLpt4KAtOWAp F7laexbo0G7u8nfsG/tfuWVUDHn80BR/3iH3oqZuSHTpM4iNb9B0waVMGSPoJ+Gk+/AG 0k2vL3VN5/0hbTPSTQl+2l/d1KbJbeAFUDYkUbY65kOLXM9ffVhMIBzTF1icuA/O26sE nU3w== X-Forwarded-Encrypted: i=1; AJvYcCWCT2uHt6Db5vLJBP6iCkhXc94y+vS/+JgTCh6DHPBDw11yJg/7eLLZjiNSoZCyhMaXiDmZpNyTY/oT/iU=@vger.kernel.org X-Gm-Message-State: AOJu0YwgJyGIn4f1+YY9kGZmf/dUa6PU7BBdGrV7EJwZncq+LGa2o969 sbsdvBrg8VihPk9VAHNNfq6l5Nz40lz2DS8V+enkF4DjsgOZGm7tUQSvMT3n5DQ= X-Gm-Gg: ASbGncs3VPPMSY0uFDYBkeMySLA4/d2a6+5tMhjNye+OweUN7B7Wcir399Y43hnA/xP 6IySVuUTVGaF10Y0Ps5XUbGf7ahAlngIhhNLrDhx8jDW+ZrCqGmoCuQjOdQFdj7dR0oIKhb7T1+ rxN8BrOlJ4vGXinwdOMvOTYKtm5Zksl9Ha9TLnG0W4fGD+6O4QY9DxzDINWZoZc2BBTFJkVE2ck MJ4LwcVYZCtN+QjIGGk+dekYUQxmRgmENxSVxfDBr3cpGIXKrl7FThxXQ== X-Google-Smtp-Source: AGHT+IHOqKLHvt93hDrBLQHJsz24OXfaq0tMtK/gwb31csC9y6TkKpbJBJNrYlaSsNcduvA1snTmhA== X-Received: by 2002:a05:6512:b9d:b0:53d:dc1c:60e4 with SMTP id 2adb3069b0e04-53df00d112fmr7905016e87.21.1732931729176; Fri, 29 Nov 2024 17:55:29 -0800 (PST) Received: from umbar.lan ([192.130.178.90]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-53df6430cc8sm635601e87.31.2024.11.29.17.55.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Nov 2024 17:55:27 -0800 (PST) From: Dmitry Baryshkov Date: Sat, 30 Nov 2024 03:55:19 +0200 Subject: [PATCH v7 3/3] drm/msm/dpu: include SSPP allocation state into the dumped state 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: <20241130-dpu-virtual-wide-v7-3-991053fcf63c@linaro.org> References: <20241130-dpu-virtual-wide-v7-0-991053fcf63c@linaro.org> In-Reply-To: <20241130-dpu-virtual-wide-v7-0-991053fcf63c@linaro.org> 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=1066; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=0H6B6m4YfEscj5/eTxfCR+sI5ay0GD8NDcl46LffCeo=; b=owGbwMvMwMXYbdNlx6SpcZXxtFoSQ7pXQbvK5u6p0guEDC9uusod3qr5+nq35q6ptWffRLCIi hTdiVDsZDRmYWDkYpAVU2TxKWiZGrMpOezDjqn1MINYmUCmMHBxCsBExL04GDZP27Zrs+uNCgef WRNuiti6ZDYY8UQ/5Wa5/Jr33rKSpPAiUfm2E9+XdxUXbE1y5hHfpl8SJhEs95P1z9t3nSm+Ijd 8kvwDr9m55djvE+FkC1q75o3Dm01zjgW2axoZBTx+nfV47adveZYsmqW3DMx6VNNY9biDgh6U9D BViva1X78sdMHI7ZNj/PO9k2XjJr+2bFf0Dpyt6leQ+2LnnMUK/YxVu+rUPx2L232wm0Vl24VlK 25eDXOaxPToq/S86Yk+zwRjJQ+Kt3zpUCq9Z/vpTaPy+usb9e5/cjwUG7c76ucKT4vZe6es/B0S kHXu3bPpoclmfz652NdsS3v/t4FFvUWvJeQX4zzrikVbAA== X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A Make dpu_rm_print_state() also output the SSPP allocation state. Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/d= isp/dpu1/dpu_rm.c index 4964aa92ce18f9da3b9ca4e599b13ffb02dd81e4..278ed58004f655e20f8c4d9e84e= 92d0031f7a105 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -941,4 +941,11 @@ void dpu_rm_print_state(struct drm_printer *p, dpu_rm_print_state_helper(p, rm->cdm_blk, global_state->cdm_to_enc_id); drm_puts(p, "\n"); + + drm_puts(p, "\tsspp=3D"); + /* skip SSPP_NONE and start from the next index */ + for (i =3D SSPP_NONE + 1; i < ARRAY_SIZE(global_state->sspp_to_crtc_id); = i++) + dpu_rm_print_state_helper(p, rm->hw_sspp[i] ? &rm->hw_sspp[i]->base : NU= LL, + global_state->sspp_to_crtc_id[i]); + drm_puts(p, "\n"); } --=20 2.39.5