From nobody Tue Feb 10 10:58:02 2026 Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.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 EA6AE1A00D1 for ; Wed, 26 Feb 2025 12:33:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740573239; cv=none; b=URsOrwb0bdOHRu07S3a6uq8bIsEJ6w3hL78CM9oXz5g//RhVpxAeQrpJJL+6JA6KqMk+8bk9EFwLujjqgUkjkL7PUEPMwh0H82ckTkFE/vNgOChchu+IsOz5zK4fXP4I/kT46CYNn8p5ziPgDhRWpGfwIjhHqe3/tV1Pbq1SYDc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740573239; c=relaxed/simple; bh=AfzDCzWE61/RiHp3arR4nrjqrt9najhrZrp7qskeOcw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Wr9BD5fKpAFblJxb3y8DgTGjqGlqAvEhYFQojGOLvoGZ9XC4N0pnW8DmAt8h5kuYtHBYq5JnFzJ5kYI7CyRx3MzcNn2OI3yjWmvrXLZB7QuNesbwmF7wuLjD62Zev7x1WHE4Dd3nN/Mb9xOPlBrcYJLseixoiduA6oh9ThhvAHM= 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=m2ocKLYj; arc=none smtp.client-ip=209.85.216.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="m2ocKLYj" Received: by mail-pj1-f50.google.com with SMTP id 98e67ed59e1d1-2fa8ada6662so13190429a91.1 for ; Wed, 26 Feb 2025 04:33:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1740573237; x=1741178037; 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=7iP8OZkcuS6exm7vZyYBnerJLmEEFA+57WDXglQPLxM=; b=m2ocKLYjJKl18D7NCKcjFp9st1++2Wtadn3XWc0hp7HDR6W37Bi1oQvsYzgN0eOBzd WLP8owbe+vQVhQtioDL3so67czsDnaNiU7IKyCJ07hHVwUpaSJMKDex+q/inRQ2FOj3k fQ6c3SL7GF3NL+GkpzKFX21i8nvP4fWgtZpgpxA5/GQhvf6zqCDJBJGY2gZCZOWJdUl/ 8pMPlrM8I0BzlYLhBVF7Biv5FsTmSMtIrFd2SLQRG8B/VoKtiouddwqTV8TVaBGQ/RYL MCkmJLF/PIu1fShZCdk6yzRg8wUZZgpzQ65RJzsSvJSES3sRMdUhOx4QthtU08F6Cigi HvCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740573237; x=1741178037; 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=7iP8OZkcuS6exm7vZyYBnerJLmEEFA+57WDXglQPLxM=; b=Y/8P7zZzYKCNUX4f8KuGBiYllSrzjAUgIegfr8RrESkOCREbhL3bZUXdv6R7s55TWz mfJ8Pb3bQ+4kYVlG2UVBimO0G0Q/sjzisXS/8nwIA1QeUlSGy19JPaykqvjjZ+seQWY+ sNxYIjw+vDIe0du7f2Ii9h1w+A8cYF3/cYrQ8fpB7mHVO8VVe0o+WL4mJFjRGjcNQ4Q+ ND00Qx67k64Xczu8s712h554j8q1s+Uw6atQ2qY1wFQdK5PZ602CswS3X1OBf6aekiyO XxHFd7hnEESrKmpzNHNzmLiqibVTWFp+41NvAOkfkq9KcfHBN2dVgfNJgedXFkS5Eon/ ME6g== X-Forwarded-Encrypted: i=1; AJvYcCWOK+PO+CuRTyWGYmcDiFMPUKJkE9FMw/FEQPMayVF5PSjVYz38Be109g5xrU1wNRWBPiadFsNd8YAxX8I=@vger.kernel.org X-Gm-Message-State: AOJu0YyLGuuNe0JS106ADDhgJupyw7vgOgmw/OmsN74DMssfRKJZVAVs 65TqiQvIVQ4hzl4m3v6IVF71rSSGPkTXRxidJpvR0FQzAWzUWbuQw0djaBX1lrQ= X-Gm-Gg: ASbGncslrP6giAqID35yZeN8PaNq9if+o5v90bdRY2478Q+vLdclGfS2McaExb7cRYq 6a/yQLQWT/R3db/Wt+roIZc73GrJWYXMAruU+87Bz4ZXxGxJu7lbG9ixUljOIu9yblfDZxf9bkm BAtWWgusw441svQPNKyhcn9Fl/9a56qenRBig+2c6UU1Zu1ZC3YzrnaBmDEPGsh1Z/h0+B3v7bx lfo8x6coHpLv6EWPoBbqFt9vYfnWIvH27g1nhNMUEQcms4EOBvIrzsv/0OeOyzXcujtiOR4i8to Dpb1WoMtE0TRzb29/Wn/8LU= X-Google-Smtp-Source: AGHT+IFszgvLiJWfa+wYqOxFTnqZSeEGBpni9e6FRIXlXgfgCcHY7CCFgHpi7Jpv05DR2zQ0K1tN+g== X-Received: by 2002:a17:90b:548f:b0:2ee:5958:828 with SMTP id 98e67ed59e1d1-2fce86adf6cmr37102419a91.9.1740573237310; Wed, 26 Feb 2025 04:33:57 -0800 (PST) Received: from [127.0.1.1] ([112.64.61.158]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2fe825d2ed3sm1352479a91.29.2025.02.26.04.33.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Feb 2025 04:33:56 -0800 (PST) From: Jun Nie Date: Wed, 26 Feb 2025 20:31:03 +0800 Subject: [PATCH v7 14/15] drm/msm/dpu: support plane splitting in quad-pipe case 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: <20250226-sm8650-v6-14-hmd-deckard-mdss-quad-upstream-oldbootwrapper-36-prep-v7-14-8d5f5f426eb2@linaro.org> References: <20250226-sm8650-v6-14-hmd-deckard-mdss-quad-upstream-oldbootwrapper-36-prep-v7-0-8d5f5f426eb2@linaro.org> In-Reply-To: <20250226-sm8650-v6-14-hmd-deckard-mdss-quad-upstream-oldbootwrapper-36-prep-v7-0-8d5f5f426eb2@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=1740573128; l=8117; i=jun.nie@linaro.org; s=20240403; h=from:subject:message-id; bh=AfzDCzWE61/RiHp3arR4nrjqrt9najhrZrp7qskeOcw=; b=Fa8B2QmM4H5DG8oUt+TL7FC2MI9Nb/SLt+ty9ByIeGuozXhNv77cv6W5n00odcJiPdkAT3zv6 pvC3f8f5oMsBx5w7yLqCBimcQGNSUJDMdEIesLOXvFf+Nv7JwzuCFYM X-Developer-Key: i=jun.nie@linaro.org; a=ed25519; pk=MNiBt/faLPvo+iJoP1hodyY2x6ozVXL8QMptmsKg3cc= 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/ms= m/disp/dpu1/dpu_plane.c index d1d6c91ed0f8e1c62b757ca42546fbc421609f72..39e3126d7b5f64ea3dabe341f36= 6cd3c4298d303 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_pl= ane *plane, struct dpu_plane_state *pstate =3D 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 =3D { 0 }; + const struct drm_display_mode *mode =3D &crtc_state->adjusted_mode; uint32_t max_linewidth; + u32 num_lm; + int stage_id, num_stages; =20 min_scale =3D FRAC_16_16(1, MAX_UPSCALE_RATIO); max_scale =3D MAX_DOWNSCALE_RATIO << 16; @@ -855,13 +859,10 @@ static int dpu_plane_atomic_check_nosspp(struct drm_p= lane *plane, return -EINVAL; } =20 - /* move the assignment here, to ease handling to another pairs later */ - pipe_cfg =3D &pstate->pipe_cfg[0]; - r_pipe_cfg =3D &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 =3D dpu_crtc_get_num_lm(crtc_state); =20 - pipe_cfg->dst_rect =3D 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); =20 fb_rect.x2 =3D new_plane_state->fb->width; fb_rect.y2 =3D new_plane_state->fb->height; @@ -886,35 +887,91 @@ static int dpu_plane_atomic_check_nosspp(struct drm_p= lane *plane, =20 max_linewidth =3D pdpu->catalog->caps->max_linewidth; =20 - 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); =20 - 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 =3D (num_lm + 1) / 2; + /* iterate mixer configs for this plane, to separate left/right with the = id */ + for (stage_id =3D 0; stage_id < num_stages; stage_id++) { + struct drm_rect mixer_rect =3D {stage_id * mode->hdisplay / num_stages, = 0, + (stage_id + 1) * mode->hdisplay / num_stages, + mode->vdisplay}; + int cfg_idx =3D stage_id * PIPES_PER_STAGE; + + pipe_cfg =3D &pstate->pipe_cfg[cfg_idx]; + r_pipe_cfg =3D &pstate->pipe_cfg[cfg_idx + 1]; + + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src); + pipe_cfg->dst_rect =3D 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; } =20 - *r_pipe_cfg =3D *pipe_cfg; - pipe_cfg->src_rect.x2 =3D (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2= ) >> 1; - pipe_cfg->dst_rect.x2 =3D (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2= ) >> 1; - r_pipe_cfg->src_rect.x1 =3D pipe_cfg->src_rect.x2; - r_pipe_cfg->dst_rect.x1 =3D pipe_cfg->dst_rect.x2; - } else { - memset(r_pipe_cfg, 0, sizeof(*r_pipe_cfg)); - } + pipe_cfg->dst_rect.x1 -=3D mixer_rect.x1; + pipe_cfg->dst_rect.x2 -=3D 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)); =20 - 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) !=3D 0) - drm_rect_rotate_inv(&r_pipe_cfg->src_rect, - new_plane_state->fb->width, new_plane_state->fb->height, + /* 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 =3D (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x= 2) >> 1; + pipe_cfg->dst_rect.x2 =3D (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x= 2) >> 1; + r_pipe_cfg->src_rect.x1 =3D pipe_cfg->src_rect.x2; + r_pipe_cfg->dst_rect.x1 =3D 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); =20 + 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); + } + pstate->needs_qos_remap =3D drm_atomic_crtc_needs_modeset(crtc_state); =20 return 0; @@ -954,20 +1011,17 @@ static int dpu_plane_atomic_check_sspp(struct drm_pl= ane *plane, drm_atomic_get_new_plane_state(state, plane); struct dpu_plane *pdpu =3D to_dpu_plane(plane); struct dpu_plane_state *pstate =3D to_dpu_plane_state(new_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]; - int ret =3D 0; - - ret =3D 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 =3D 0, i; =20 - if (drm_rect_width(&r_pipe_cfg->src_rect) !=3D 0) { - ret =3D dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, + for (i =3D 0; i < PIPES_PER_PLANE; i++) { + pipe =3D &pstate->pipe[i]; + pipe_cfg =3D &pstate->pipe_cfg[i]; + if (!pipe->sspp) + continue; + DPU_DEBUG_PLANE(pdpu, "pipe %d is in use, validate it\n", i); + ret =3D dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, &crtc_state->adjusted_mode, new_plane_state); if (ret) --=20 2.34.1