From patchwork Tue Mar 21 01:18:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 665612 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A158C761A6 for ; Tue, 21 Mar 2023 01:20:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230249AbjCUBUC (ORCPT ); Mon, 20 Mar 2023 21:20:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46590 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231193AbjCUBT5 (ORCPT ); Mon, 20 Mar 2023 21:19:57 -0400 Received: from mail-lf1-x130.google.com (mail-lf1-x130.google.com [IPv6:2a00:1450:4864:20::130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB56D12062 for ; Mon, 20 Mar 2023 18:19:27 -0700 (PDT) Received: by mail-lf1-x130.google.com with SMTP id bi9so17190528lfb.12 for ; Mon, 20 Mar 2023 18:19:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679361503; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kyKsHi3GCpQsQBL3ZUsB7GqCNqmr8gVxqyeAbsz/AVg=; b=LAcWfLlNbVJI/jBqzT3qpnzVjMdHfGZMWvIDRAV3VjocoMGwSCV+Kj8wp1DT7u9ZTH Lhj3GjvF6smFm6cIf4URzb8H7cRSDLccWI1ZpQxHDkGaIuGAnhoMg29MyELACue2BwmC 9pTkm9U64nW18OHr51H2P3Iq7VO/bLgQLdOz1MVTWrKto78XkjhnmyfKC71I+cPCKzXA PqpzZ8rV8H8wsqV9ni22c+Xsy+kNyp5fgvdTK3TnVmabZid1lHYkdKhaP/loLTpSjLgr 5g8WeEyfZ7vQvto219sIFz0DCPKO6oWGcYeaUuGFNNyqNmBptYV/XxIiPCaQkT5vZgl3 JDvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679361503; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kyKsHi3GCpQsQBL3ZUsB7GqCNqmr8gVxqyeAbsz/AVg=; b=ZUEEk6Rkxrns9ihsX3e03p3dYTnx0Z/2oNRBaaUXXROsk2kkzx/aRgr6Xm+ibrc3Xz Ottd3NG1tWsmYuxoD3a/eWpAOTY8SStRqRhR0QgdezxQhZAdR3pIaeu5CbaGtBSL2uEE ktPgKlwsuFuA+qgoXzmOmECpVNA1GO3fVYMv5nUexlkUO3JlyTCeV9SBbNLQnGWb6bHC KNe88xLkadWy35xG7vNO92ctk2msZN5fTIYQD8FOApxNZ4P0rI3+5HURcA3m2PZ7Nbir VNXXjoNdVJrB4PH/IxLH36/9A9VMDzhiCeqYuMtwxmjeotdvChrKeYFN4ZApknsMX3Jv jjwA== X-Gm-Message-State: AO0yUKUlzBMm0x5mxhK9jDi25WwPNezisBbbIqvxWQzwSkMw8gq9DpuN kdsX8X1SZKttxhxp2a8N7vxcF7BTCRh+5yNSd+Xf+PfM X-Google-Smtp-Source: AK7set8RWsq4Zrhl6918J+yefTewlO3hLlJHbTFge15wK46WfuTBOw3fO0GhCrbwotXebulBLCcsDA== X-Received: by 2002:ac2:495e:0:b0:4a4:7be4:9baf with SMTP id o30-20020ac2495e000000b004a47be49bafmr262536lfi.59.1679361503228; Mon, 20 Mar 2023 18:18:23 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c18-20020ac25312000000b004eaec70c68esm46863lfh.294.2023.03.20.18.18.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Mar 2023 18:18:22 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [RFC PATCH v2 01/13] drm/atomic-helper: split not-scaling part of drm_atomic_helper_check_plane_state Date: Tue, 21 Mar 2023 04:18:09 +0300 Message-Id: <20230321011821.635977-2-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> References: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The helper drm_atomic_helper_check_plane_state() runs several checks on plane src and dst rectangles, including the check whether required scaling fits into the required margins. The msm driver would benefit from having a function that does all these checks except the scaling one. Split them into a new helper called drm_atomic_helper_check_plane_noscale(). Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/drm_atomic_helper.c | 85 ++++++++++++++++++++++------- include/drm/drm_atomic_helper.h | 4 ++ 2 files changed, 68 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index d579fd8f7cb8..86c5e19c7bdb 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -825,11 +825,9 @@ drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder, EXPORT_SYMBOL(drm_atomic_helper_check_wb_encoder_state); /** - * drm_atomic_helper_check_plane_state() - Check plane state for validity + * drm_atomic_helper_check_plane_noscale() - Check plane state for validity * @plane_state: plane state to check * @crtc_state: CRTC state to check - * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point - * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point * @can_position: is it legal to position the plane such that it * doesn't cover the entire CRTC? This will generally * only be false for primary planes. @@ -845,19 +843,16 @@ EXPORT_SYMBOL(drm_atomic_helper_check_wb_encoder_state); * RETURNS: * Zero if update appears valid, error code on failure */ -int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, - const struct drm_crtc_state *crtc_state, - int min_scale, - int max_scale, - bool can_position, - bool can_update_disabled) +int drm_atomic_helper_check_plane_noscale(struct drm_plane_state *plane_state, + const struct drm_crtc_state *crtc_state, + bool can_position, + bool can_update_disabled) { struct drm_framebuffer *fb = plane_state->fb; struct drm_rect *src = &plane_state->src; struct drm_rect *dst = &plane_state->dst; unsigned int rotation = plane_state->rotation; struct drm_rect clip = {}; - int hscale, vscale; WARN_ON(plane_state->crtc && plane_state->crtc != crtc_state->crtc); @@ -883,17 +878,6 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation); - /* Check scaling */ - hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); - vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); - if (hscale < 0 || vscale < 0) { - drm_dbg_kms(plane_state->plane->dev, - "Invalid scaling of plane\n"); - drm_rect_debug_print("src: ", &plane_state->src, true); - drm_rect_debug_print("dst: ", &plane_state->dst, false); - return -ERANGE; - } - if (crtc_state->enable) drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2); @@ -921,6 +905,65 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, return 0; } +EXPORT_SYMBOL(drm_atomic_helper_check_plane_noscale); + +/** + * drm_atomic_helper_check_plane_state() - Check plane state for validity + * @plane_state: plane state to check + * @crtc_state: CRTC state to check + * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point + * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point + * @can_position: is it legal to position the plane such that it + * doesn't cover the entire CRTC? This will generally + * only be false for primary planes. + * @can_update_disabled: can the plane be updated while the CRTC + * is disabled? + * + * Checks that a desired plane update is valid, and updates various + * bits of derived state (clipped coordinates etc.). Drivers that provide + * their own plane handling rather than helper-provided implementations may + * still wish to call this function to avoid duplication of error checking + * code. + * + * RETURNS: + * Zero if update appears valid, error code on failure + */ +int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, + const struct drm_crtc_state *crtc_state, + int min_scale, + int max_scale, + bool can_position, + bool can_update_disabled) +{ + struct drm_framebuffer *fb = plane_state->fb; + struct drm_rect src; + struct drm_rect dst; + int hscale, vscale, ret; + + ret = drm_atomic_helper_check_plane_noscale(plane_state, crtc_state, can_position, can_update_disabled); + if (ret < 0) + return ret; + + if (!plane_state->visible) + return 0; + + src = drm_plane_state_src(plane_state); + dst = drm_plane_state_dest(plane_state); + + drm_rect_rotate(&src, fb->width << 16, fb->height << 16, plane_state->rotation); + + hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale); + vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale); + if (hscale < 0 || vscale < 0) { + drm_dbg_kms(plane_state->plane->dev, + "Invalid scaling of plane\n"); + drm_rect_debug_print("src: ", &plane_state->src, true); + drm_rect_debug_print("dst: ", &plane_state->dst, false); + return -ERANGE; + } + + return 0; +} EXPORT_SYMBOL(drm_atomic_helper_check_plane_state); /** diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 33f982cd1a27..ebf95437431d 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -52,6 +52,10 @@ int drm_atomic_helper_check_modeset(struct drm_device *dev, int drm_atomic_helper_check_wb_encoder_state(struct drm_encoder *encoder, struct drm_connector_state *conn_state); +int drm_atomic_helper_check_plane_noscale(struct drm_plane_state *plane_state, + const struct drm_crtc_state *crtc_state, + bool can_position, + bool can_update_disabled); int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, const struct drm_crtc_state *crtc_state, int min_scale, From patchwork Tue Mar 21 01:18:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 665613 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 20DE1C6FD1D for ; Tue, 21 Mar 2023 01:20:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230289AbjCUBUA (ORCPT ); Mon, 20 Mar 2023 21:20:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231185AbjCUBT4 (ORCPT ); Mon, 20 Mar 2023 21:19:56 -0400 Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A3A4A5D4 for ; Mon, 20 Mar 2023 18:19:26 -0700 (PDT) Received: by mail-lf1-x12c.google.com with SMTP id x17so17234856lfu.5 for ; Mon, 20 Mar 2023 18:19:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679361504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PYN3oYps1kExjbkf+zjFZYaGqiWBM1RDNanr9QzGX+M=; b=GrqYqhhsIMn2xfgfbCoGZNP53LWMZSCxJxVxh3b92VCfmVcZyZUhLADpEkxVp97/9c coPwD3Po75Uo65GLG/15Gvq6yTvNxeewn7Mrsnh/khiwtGIoB5LkPuns8HyzC7HeReEN C2jeqtmb6IyzG3THhmf0DKEAkahOoqU9wEQ4jWyAxBwJhtJyasCNn5+nVVA6EFOepEOS 5LSfRGmGIra2+5+hsnsm/2nNlUGjd+m0MpLQHBaknMk9o41sddol+pC0pHkiOis7TO74 bBCbSuqzwcQr7XaHb20OYQU6JHi/tuVxIMij03/ce0bwEMdwqZuMxU8+WoKmMrGhG144 WWig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679361504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PYN3oYps1kExjbkf+zjFZYaGqiWBM1RDNanr9QzGX+M=; b=ybdlfAECN9WQwcbELwPrNg/9jauWHR2x/zp5UaX3NIpdOuoK+vJvUS+T+GNtsrZKXV S4jfTn32hMyXz7bBijEHgZPlLvzHKRbJdZgq9touCoe+B5+Iw8o6YhYg8rsCzJYuyDPn n3YQxXsMsBGMHKf0xIRfelpDlb/B/YtXuRjs/0EevYOz324JfWFFyhAK08KMWA2akTOr ESK4DqpOQmLF6e/pyHP54HKVDzQohcwPUzqR+gwJ9i0mQDcKOce4nt+fb4udcXOLNlpL q1wPFTa4u9SadtK+heSDF8uraJQ4ovQve0N2pKuozWqdghW3zQObWKiip56SStvv8vES nGDg== X-Gm-Message-State: AO0yUKWssj7WSCvL6pBOWTZatd5tzYebBA8SsET19qDjd63bzepwgEQs knyULOSCzBZZ/l9nPAUxLO7yGg== X-Google-Smtp-Source: AK7set//en3R7J7A36LAkaMdnCjbcNGxUJiPViGi+MCKzk39MaPSyhBsndT6fLK50TOdhIsO+FLMfg== X-Received: by 2002:ac2:5961:0:b0:4dd:a718:31dd with SMTP id h1-20020ac25961000000b004dda71831ddmr265068lfp.12.1679361504107; Mon, 20 Mar 2023 18:18:24 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c18-20020ac25312000000b004eaec70c68esm46863lfh.294.2023.03.20.18.18.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Mar 2023 18:18:23 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [RFC PATCH v2 02/13] drm/msm/dpu: take plane rotation into account for wide planes Date: Tue, 21 Mar 2023 04:18:10 +0300 Message-Id: <20230321011821.635977-3-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> References: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Take into account the plane rotation and flipping when calculating src positions for the wide plane parts. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 27 ++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 2e63eb0a2f3f..d43e04fc4578 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -887,16 +887,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; } - pipe_cfg->src_rect = new_plane_state->src; - - /* state->src is 16.16, src_rect is not */ - pipe_cfg->src_rect.x1 >>= 16; - pipe_cfg->src_rect.x2 >>= 16; - pipe_cfg->src_rect.y1 >>= 16; - pipe_cfg->src_rect.y2 >>= 16; - - pipe_cfg->dst_rect = new_plane_state->dst; - fb_rect.x2 = new_plane_state->fb->width; fb_rect.y2 = new_plane_state->fb->height; @@ -912,6 +902,15 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, max_linewidth = pdpu->catalog->caps->max_linewidth; + /* state->src is 16.16, src_rect is not */ + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src); + + pipe_cfg->dst_rect = new_plane_state->dst; + + drm_rect_rotate(&pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) { /* * In parallel multirect case only the half of the usual width @@ -959,6 +958,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; } + 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->sspp) + drm_rect_rotate_inv(&r_pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt); if (ret) return ret; From patchwork Tue Mar 21 01:18:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 665607 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA6BFC6FD1D for ; Tue, 21 Mar 2023 01:25:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230248AbjCUBZD (ORCPT ); Mon, 20 Mar 2023 21:25:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230500AbjCUBYx (ORCPT ); Mon, 20 Mar 2023 21:24:53 -0400 Received: from mail-lf1-f44.google.com (mail-lf1-f44.google.com [209.85.167.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DC27712F2B for ; Mon, 20 Mar 2023 18:24:24 -0700 (PDT) Received: by mail-lf1-f44.google.com with SMTP id y20so17245379lfj.2 for ; Mon, 20 Mar 2023 18:24:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679361506; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gIZhnj34tFDqJ571tBldatObNZ/9X2iSU1FEGNAtdzI=; b=h2Lz8JJrX2VcM8Vh4sQrkJfCvGm0RE+pY3w2RFXg3sWRX/06kdq2rM1aOdpkX6pYLb P1FEnGA6G+NwVpQNHlN+mdEn3sbCksaHJOYM2LJUx/etRIWXp/o9ORAmjFUhoed2WBy4 5ZENnpQ9A4+AK6rEiRlvOF2l3tS6nnsb0aTtosYiLt41ojcKcNWRPj+zRBfIpJaw3GIe G5t8jeOs5my5QajzHO5VuH8wjSRQU1QwR9CayrqRfdWp4hiq0QSSN92F/UuEvL3PMNF2 QCTU3Bat6ecxPySBmKZcz2yuzDoiMzndRbJeqaR4aF6Tdnd82Ts6KuPOwkVEF3eyam+V IEXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679361506; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gIZhnj34tFDqJ571tBldatObNZ/9X2iSU1FEGNAtdzI=; b=JXa9Ts90bVjJfVmDG1lcO0FPybRwfxZ5HsEb391DMFTmbpM14d5sY3GUXumKGLZGv3 oHDxiuDVngOgict1yRkc6FMJy9JdFc/qYJ0jq+uHlFb62M8Q5SOzsk9IQQmA3IE5v2di y4V5s1Sz1B76bw9YuZXm1ngDH7U8+s8yYZYSRufinpfoMtoinWFz8u88yZlYwc72ns84 jzE1WsquRdPe9Ku9JjPf13gj/o+exHYGjJtp2OEYgLOMK+pG+2wQt0+9o21OWn+3QvXN Jc1PfnvSFyNn57PRNClD3NwVfjmTgIvNvBwFOEr9PDdGR+2N4+lTt8pLnmeAtgHXxWh6 sMlQ== X-Gm-Message-State: AO0yUKXTE+uKBcg2RqALtdTw6ccK+J7ngDDnj5+V+n3K3AlEErGojOVl RO6WJKXI4ES2hbzcT2lHFCqjbg== X-Google-Smtp-Source: AK7set/05PMdWN2X//Ae0Bm+GTyz04uZ5T0FFTJJXJP+hOgTp5M6pbfZL+V7ePC2F+bWdc2FeJem6g== X-Received: by 2002:a19:f61a:0:b0:4de:3774:2d97 with SMTP id x26-20020a19f61a000000b004de37742d97mr230467lfe.13.1679361506234; Mon, 20 Mar 2023 18:18:26 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c18-20020ac25312000000b004eaec70c68esm46863lfh.294.2023.03.20.18.18.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Mar 2023 18:18:25 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [RFC PATCH v2 05/13] drm/msm/dpu: get rid of struct dpu_rm_requirements Date: Tue, 21 Mar 2023 04:18:13 +0300 Message-Id: <20230321011821.635977-6-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> References: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The struct dpu_rm_requirements was used to wrap display topology and hw resources, which meant INTF indices. As of commit ef58e0ad3436 ("drm/msm/dpu: get INTF blocks directly rather than through RM") the hw resources struct was removed, leaving struct dpu_rm_requirements containing a single field (topology). Remove the useless wrapper. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 69 +++++++-------------- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 2 +- 3 files changed, 23 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 4ee708264f3b..a2cb23dea0b8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -638,7 +638,7 @@ static int dpu_encoder_virt_atomic_check( if (!crtc_state->active_changed || crtc_state->enable) ret = dpu_rm_reserve(&dpu_kms->rm, global_state, - drm_enc, crtc_state, topology); + drm_enc, crtc_state, &topology); } trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index f4dda88a73f7..952e139c0234 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -24,15 +24,6 @@ static inline bool reserved_by_other(uint32_t *res_map, int idx, return res_map[idx] && res_map[idx] != enc_id; } -/** - * struct dpu_rm_requirements - Reservation requirements parameter bundle - * @topology: selected topology for the display - * @hw_res: Hardware resources required as reported by the encoders - */ -struct dpu_rm_requirements { - struct msm_display_topology topology; -}; - int dpu_rm_destroy(struct dpu_rm *rm) { int i; @@ -329,14 +320,13 @@ static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int primary_idx, * mixer in rm->pingpong_blks[]. * @dspp_idx: output parameter, index of dspp block attached to the layer * mixer in rm->dspp_blks[]. - * @reqs: input parameter, rm requirements for HW blocks needed in the - * datapath. + * @topology: selected topology for the display * Return: true if lm matches all requirements, false otherwise */ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx, - struct dpu_rm_requirements *reqs) + struct msm_display_topology *topology) { const struct dpu_lm_cfg *lm_cfg; int idx; @@ -361,7 +351,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, } *pp_idx = idx; - if (!reqs->topology.num_dspp) + if (!topology->num_dspp) return true; idx = lm_cfg->dspp - DSPP_0; @@ -383,7 +373,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, static int _dpu_rm_reserve_lms(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t enc_id, - struct dpu_rm_requirements *reqs) + struct msm_display_topology *topology) { int lm_idx[MAX_BLOCKS]; @@ -391,14 +381,14 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, int dspp_idx[MAX_BLOCKS] = {0}; int i, j, lm_count = 0; - if (!reqs->topology.num_lm) { - DPU_ERROR("invalid number of lm: %d\n", reqs->topology.num_lm); + if (!topology->num_lm) { + DPU_ERROR("invalid number of lm: %d\n", topology->num_lm); return -EINVAL; } /* Find a primary mixer */ for (i = 0; i < ARRAY_SIZE(rm->mixer_blks) && - lm_count < reqs->topology.num_lm; i++) { + lm_count < topology->num_lm; i++) { if (!rm->mixer_blks[i]) continue; @@ -407,7 +397,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state, enc_id, i, &pp_idx[lm_count], - &dspp_idx[lm_count], reqs)) { + &dspp_idx[lm_count], topology)) { continue; } @@ -415,7 +405,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, /* Valid primary mixer found, find matching peers */ for (j = i + 1; j < ARRAY_SIZE(rm->mixer_blks) && - lm_count < reqs->topology.num_lm; j++) { + lm_count < topology->num_lm; j++) { if (!rm->mixer_blks[j]) continue; @@ -428,7 +418,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state, enc_id, j, &pp_idx[lm_count], &dspp_idx[lm_count], - reqs)) { + topology)) { continue; } @@ -437,7 +427,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, } } - if (lm_count != reqs->topology.num_lm) { + if (lm_count != topology->num_lm) { DPU_DEBUG("unable to find appropriate mixers\n"); return -ENAVAIL; } @@ -446,7 +436,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, global_state->mixer_to_enc_id[lm_idx[i]] = enc_id; global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id; global_state->dspp_to_enc_id[dspp_idx[i]] = - reqs->topology.num_dspp ? enc_id : 0; + topology->num_dspp ? enc_id : 0; trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id, pp_idx[i] + PINGPONG_0); @@ -539,44 +529,30 @@ static int _dpu_rm_make_reservation( struct dpu_rm *rm, struct dpu_global_state *global_state, struct drm_encoder *enc, - struct dpu_rm_requirements *reqs) + struct msm_display_topology *topology) { int ret; - ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, reqs); + ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, topology); if (ret) { DPU_ERROR("unable to find appropriate mixers\n"); return ret; } ret = _dpu_rm_reserve_ctls(rm, global_state, enc->base.id, - &reqs->topology); + topology); if (ret) { DPU_ERROR("unable to find appropriate CTL\n"); return ret; } - ret = _dpu_rm_reserve_dsc(rm, global_state, enc, &reqs->topology); + ret = _dpu_rm_reserve_dsc(rm, global_state, enc, topology); if (ret) return ret; return ret; } -static int _dpu_rm_populate_requirements( - struct drm_encoder *enc, - struct dpu_rm_requirements *reqs, - struct msm_display_topology req_topology) -{ - reqs->topology = req_topology; - - DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n", - reqs->topology.num_lm, reqs->topology.num_dsc, - reqs->topology.num_intf); - - return 0; -} - static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt, uint32_t enc_id) { @@ -608,9 +584,8 @@ int dpu_rm_reserve( struct dpu_global_state *global_state, struct drm_encoder *enc, struct drm_crtc_state *crtc_state, - struct msm_display_topology topology) + struct msm_display_topology *topology) { - struct dpu_rm_requirements reqs; int ret; /* Check if this is just a page-flip */ @@ -625,13 +600,11 @@ int dpu_rm_reserve( DRM_DEBUG_KMS("reserving hw for enc %d crtc %d\n", enc->base.id, crtc_state->crtc->base.id); - ret = _dpu_rm_populate_requirements(enc, &reqs, topology); - if (ret) { - DPU_ERROR("failed to populate hw requirements\n"); - return ret; - } + DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n", + topology->num_lm, topology->num_dsc, + topology->num_intf); - ret = _dpu_rm_make_reservation(rm, global_state, enc, &reqs); + ret = _dpu_rm_make_reservation(rm, global_state, enc, topology); if (ret) DPU_ERROR("failed to reserve hw resources: %d\n", ret); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index d62c2edb2460..f05697462856 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -71,7 +71,7 @@ int dpu_rm_reserve(struct dpu_rm *rm, struct dpu_global_state *global_state, struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, - struct msm_display_topology topology); + struct msm_display_topology *topology); /** * dpu_rm_reserve - Given the encoder for the display chain, release any From patchwork Tue Mar 21 01:18:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 665606 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26CB4C6FD1D for ; Tue, 21 Mar 2023 01:30:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230046AbjCUBaO (ORCPT ); Mon, 20 Mar 2023 21:30:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230228AbjCUBaM (ORCPT ); Mon, 20 Mar 2023 21:30:12 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6DE4D2CFCF for ; Mon, 20 Mar 2023 18:30:04 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id o12so53929537edb.9 for ; Mon, 20 Mar 2023 18:30:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679362202; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qcuLgUbx7g9v2Vy1Q8jG9BrjLhWzTu+kdHKk66znflY=; b=wd1RZG9UfL54vK2DNfvS6h2G3cGZ6tZv+BwxeATqMLCAFT+bql7TPF++rRVs4rdlUQ NDi1YKoa6erFg1QmLyGHbKE6vU+BxSb20Cw7vZC6RIN0ojjfANjL9nLC4E7JDbfngji+ VNH/9Wn35BFWr2PYAma5m9CF1LqXEOL1GDxvSKchsFBVtIhBgpu4p/epyR5sIhEQw9C5 zbOciT9ome9rUzGtZ8IQukjWizk2HZ02fYP2RwPekzN4/VbWRVNV3XdbCuyq1i4ZOzRL qHNCZiAX3Nl9Bsp+tN1ZsPcJqvtcCBkgfIxEfridTnNUtIVGoy5w2fCvf0TXgMaLMHO0 pnSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679362202; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qcuLgUbx7g9v2Vy1Q8jG9BrjLhWzTu+kdHKk66znflY=; b=ViMIhyX8cEQSBtVhbcdzsg/A1oQHyB2i+eZaRlSsfIKaCwgcPUpnLG8uYfK3tA4Acy JBHLx7sv3anwNFqBFwophu4baDbtoljpZ+44gn2JAlv/RGXcmQ+bJy7yvKXhMb9puhuG utXz2vlgdtErmlJNuIWCM8Vs05Ak8MFk/xINavEJNxYPuacEMjUbHvpLn5bJNx8M8Q8H rY4LplBeYr3nT0Fl6UvuOeUfPhJjh4gbQ+bCkuSRyQrBrRnL0vdvWMr067sO7HmsKwyG 86N0iEmc305/VGx/X+CRD1kkJtOliLDwhOMfJnXn8A9/1gn/8s6+4p+iAuioowWFfF3Q qx1A== X-Gm-Message-State: AO0yUKWUTHHzwEJvdRENswQBBwxgVHgiIhDVUNETOMN0ZtkKFaeOazmN gpUORQXAnS1OrMLi53dp5BHsadEQmQofGHACGRzHW3Pn X-Google-Smtp-Source: AK7set9IJ9TmyxKZuxZzsVQWlCZYAjsOfL+3u41SC10erZpLaPsauXq2bjMI1/usrlKBHJhC2XaaHw== X-Received: by 2002:ac2:5598:0:b0:4e9:d5e5:3ff2 with SMTP id v24-20020ac25598000000b004e9d5e53ff2mr254745lfg.40.1679361507744; Mon, 20 Mar 2023 18:18:27 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c18-20020ac25312000000b004eaec70c68esm46863lfh.294.2023.03.20.18.18.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Mar 2023 18:18:27 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [RFC PATCH v2 07/13] drm/msm/dpu: move resource allocation to CRTC Date: Tue, 21 Mar 2023 04:18:15 +0300 Message-Id: <20230321011821.635977-8-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> References: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org All resource allocation is centered around the LMs. Then other blocks (except DSCs) are allocated basing on the LMs that was selected, and LM powers up the CRTC rather than the encoder. Moreover if at some point the driver supports encoder cloning, allocating resources from the encoder will be incorrect, as all clones will have different encoder IDs, while LMs are to be shared by these encoders. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 76 ++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 88 +++------------------ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 8 ++ 3 files changed, 94 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 508e5b950e52..77226de54363 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1176,6 +1176,76 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate) return false; } +#define MAX_HDISPLAY_SPLIT 1080 + +static struct msm_display_topology dpu_crtc_get_topology( + struct drm_crtc *crtc, + struct dpu_kms *dpu_kms, + struct drm_crtc_state *crtc_state) +{ + struct drm_display_mode *mode = &crtc_state->adjusted_mode; + struct msm_display_topology topology = {0}; + struct drm_encoder *drm_enc; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) + dpu_encoder_update_topology(drm_enc, &topology); + + /* + * Datapath topology selection + * + * Dual display + * 2 LM, 2 INTF ( Split display using 2 interfaces) + * + * Single display + * 1 LM, 1 INTF + * 2 LM, 1 INTF (stream merge to support high resolution interfaces) + * + * Add dspps to the reservation requirements if ctm is requested + */ + if (topology.num_intf == 2) + topology.num_lm = 2; + else if (topology.num_dsc == 2) + topology.num_lm = 2; + else if (dpu_kms->catalog->caps->has_3d_merge) + topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; + else + topology.num_lm = 1; + + if (crtc_state->ctm) + topology.num_dspp = topology.num_lm; + + return topology; +} + +static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state) +{ + struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); + struct dpu_global_state *global_state; + struct msm_display_topology topology; + int ret; + + /* + * Release and Allocate resources on every modeset + * Dont allocate when enable is false. + */ + global_state = dpu_kms_get_global_state(crtc_state->state); + if (IS_ERR(global_state)) + return PTR_ERR(global_state); + + dpu_rm_release(global_state, crtc); + + if (!crtc_state->enable) + return 0; + + topology = dpu_crtc_get_topology(crtc, dpu_kms, crtc_state); + ret = dpu_rm_reserve(&dpu_kms->rm, global_state, + crtc, &topology); + if (ret) + return ret; + + return 0; +} + static int dpu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { @@ -1191,6 +1261,12 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state); + if (drm_atomic_crtc_needs_modeset(crtc_state)) { + rc = dpu_crtc_assign_resources(crtc, crtc_state); + if (rc < 0) + return rc; + } + if (!crtc_state->enable || !crtc_state->active) { 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_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 270c85ea898a..204360485b81 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -53,8 +53,6 @@ #define IDLE_SHORT_TIMEOUT 1 -#define MAX_HDISPLAY_SPLIT 1080 - /* timeout in frames waiting for frame done */ #define DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES 5 @@ -514,71 +512,28 @@ void dpu_encoder_helper_split_config( } } -bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) +void dpu_encoder_update_topology(struct drm_encoder *drm_enc, + struct msm_display_topology *topology) { struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); - int i, intf_count = 0, num_dsc = 0; + int i; for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++) if (dpu_enc->phys_encs[i]) - intf_count++; + topology->num_intf++; - /* See dpu_encoder_get_topology, we only support 2:2:1 topology */ + /* We only support 2 DSC mode (with 2 LM and 1 INTF) */ if (dpu_enc->dsc) - num_dsc = 2; - - return (num_dsc > 0) && (num_dsc > intf_count); + topology->num_dsc += 2; } -static struct msm_display_topology dpu_encoder_get_topology( - struct dpu_encoder_virt *dpu_enc, - struct dpu_kms *dpu_kms, - struct drm_display_mode *mode, - struct drm_crtc_state *crtc_state) +bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) { - struct msm_display_topology topology = {0}; - int i, intf_count = 0; - - for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++) - if (dpu_enc->phys_encs[i]) - intf_count++; - - /* Datapath topology selection - * - * Dual display - * 2 LM, 2 INTF ( Split display using 2 interfaces) - * - * Single display - * 1 LM, 1 INTF - * 2 LM, 1 INTF (stream merge to support high resolution interfaces) - * - * Add dspps to the reservation requirements if ctm is requested - */ - if (intf_count == 2) - topology.num_lm = 2; - else if (!dpu_kms->catalog->caps->has_3d_merge) - topology.num_lm = 1; - else - topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; - - if (crtc_state->ctm) - topology.num_dspp = topology.num_lm; + struct msm_display_topology topology = { 0 }; - topology.num_intf = intf_count; + dpu_encoder_update_topology(drm_enc, &topology); - if (dpu_enc->dsc) { - /* - * In case of Display Stream Compression (DSC), we would use - * 2 DSC encoders, 2 layer mixers and 1 interface - * this is power optimal and can drive up to (including) 4k - * screens - */ - topology.num_dsc = 2; - topology.num_lm = 2; - topology.num_intf = 1; - } - - return topology; + return (topology.num_dsc > 0) && (topology.num_dsc > topology.num_intf); } static int dpu_encoder_virt_atomic_check( @@ -587,11 +542,7 @@ static int dpu_encoder_virt_atomic_check( struct drm_connector_state *conn_state) { struct dpu_encoder_virt *dpu_enc; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; struct drm_display_mode *adj_mode; - struct msm_display_topology topology; - struct dpu_global_state *global_state; int i = 0; int ret = 0; @@ -604,12 +555,7 @@ static int dpu_encoder_virt_atomic_check( dpu_enc = to_dpu_encoder_virt(drm_enc); DPU_DEBUG_ENC(dpu_enc, "\n"); - priv = drm_enc->dev->dev_private; - dpu_kms = to_dpu_kms(priv->kms); adj_mode = &crtc_state->adjusted_mode; - global_state = dpu_kms_get_global_state(crtc_state->state); - if (IS_ERR(global_state)) - return PTR_ERR(global_state); trace_dpu_enc_atomic_check(DRMID(drm_enc)); @@ -627,20 +573,6 @@ static int dpu_encoder_virt_atomic_check( } } - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state); - - /* - * Release and Allocate resources on every modeset - * Dont allocate when active is false. - */ - if (drm_atomic_crtc_needs_modeset(crtc_state)) { - dpu_rm_release(global_state, crtc_state->crtc); - - if (!crtc_state->active_changed || crtc_state->enable) - ret = dpu_rm_reserve(&dpu_kms->rm, global_state, - crtc_state->crtc, &topology); - } - trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); return ret; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 9e7236ef34e6..88248b9faf1c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -202,6 +202,14 @@ int dpu_encoder_get_crc(const struct drm_encoder *drm_enc, u32 *crcs, int pos); */ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc); +/** + * dpu_encoder_update_topology - update topology with the requirements for the encoder + * @drm_enc: Pointer to previously created drm encoder structure + * @topology: Topology to be updated + */ +void dpu_encoder_update_topology(struct drm_encoder *drm_enc, + struct msm_display_topology *topology); + /** * dpu_encoder_prepare_wb_job - prepare writeback job for the encoder. * @drm_enc: Pointer to previously created drm encoder structure From patchwork Tue Mar 21 01:18:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 665610 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6A54C6FD1C for ; Tue, 21 Mar 2023 01:20:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230379AbjCUBUM (ORCPT ); Mon, 20 Mar 2023 21:20:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46896 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230454AbjCUBUK (ORCPT ); Mon, 20 Mar 2023 21:20:10 -0400 Received: from mail-lf1-x135.google.com (mail-lf1-x135.google.com [IPv6:2a00:1450:4864:20::135]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F087C5268 for ; Mon, 20 Mar 2023 18:19:42 -0700 (PDT) Received: by mail-lf1-x135.google.com with SMTP id x17so17235017lfu.5 for ; Mon, 20 Mar 2023 18:19:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679361508; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=C0ShU0VoJuNaKygLaJG1lCz4q0jlhQ8mz6XNRmWcdJs=; b=UI5Ui7wIUM7KtMV4pcooX6Nn/8MkGfdhXRxKsQ/k3AePUCwncAf/AwCNyKfeTeM6/g E/JIuhFwkJ/rgtoakBIl1E0c/rLsGzykagu4tEJMBljxXYkdjikkMMfq0fTT625tWxiR iLPA5AuTcS3DbBDPV6ZhsTF3FCrWEav+U+X6fvanp6D/Ympw/cT/7zLIubM+bGlTAr4u 9kp7WrM9hHOArJ7R56wiRaDxdB3AwMiVoRtqg5UGsTOoJCv7OlilwadkK284cVkYfxdJ HgPooFcRvHVovMM89YccsTlsnarAmZv2Wmm81qEvXBoVmmXzqHdsjy+rqzjk8FQMNWeK NWag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679361508; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=C0ShU0VoJuNaKygLaJG1lCz4q0jlhQ8mz6XNRmWcdJs=; b=YfE8SuoBcwqXJRD8kfyDOONkwEF5JuLMVCcWYdSeToKOQqfaytzLc4Aeq4BffnE/vy E82aqaPjNK4Jhxsssh2boTfjx116qf53mPflbW7gekeOJCMB5Vb5C/oiH2IsId1Hdbiw guzOL219GVYS0xYLroAZzx3XCnodq8ny9PnzZ7+ZxC/K4Ntm4Yf/fHUEoiCVjAgiT7hC rYMxWOkLZuDdrSNWFzlVcZT0xgwN8kOY6iUWee/qJ6y6/pOpDlHfugvNQzAGnN2eMtYM YzQ9wzWvTvmC1GTdGvFK4jJCHyJmZrbAVD6/tYH+YvT7Edh8fIzHp11wJXWZTvI4OOsI T2XA== X-Gm-Message-State: AO0yUKXC7SpSR3SajZlOWgZzdY6hSx23lpWlHyEFO9Jk1rqfVv5vxhq5 PsGiG4BJjAUQZtqT1caz4ZN6xw== X-Google-Smtp-Source: AK7set+qhT3VjPfVMqjX4XLHYsAFppTsFoCQcM9asYTAdkeMztSusgLS5MmLSoqvzQVakb5gi/AU7g== X-Received: by 2002:ac2:5151:0:b0:4ea:e640:2a58 with SMTP id q17-20020ac25151000000b004eae6402a58mr335231lfd.42.1679361508504; Mon, 20 Mar 2023 18:18:28 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c18-20020ac25312000000b004eaec70c68esm46863lfh.294.2023.03.20.18.18.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Mar 2023 18:18:28 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [RFC PATCH v2 08/13] drm/msm/dpu: fill CRTC resources in dpu_crtc.c Date: Tue, 21 Mar 2023 04:18:16 +0300 Message-Id: <20230321011821.635977-9-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> References: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Stop poking into CRTC state from dpu_encoder.c, fill CRTC HW resources from dpu_crtc_assign_resources(). Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 27 +++++++++++++++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 ++---------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 77226de54363..8ef191fd002d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1177,6 +1177,7 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate) } #define MAX_HDISPLAY_SPLIT 1080 +#define MAX_CHANNELS_PER_CRTC 2 static struct msm_display_topology dpu_crtc_get_topology( struct drm_crtc *crtc, @@ -1219,9 +1220,14 @@ static struct msm_display_topology dpu_crtc_get_topology( static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state) { + struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_CRTC]; + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_CRTC]; + struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_CRTC]; + int i, num_lm, num_ctl, num_dspp; struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); struct dpu_global_state *global_state; struct msm_display_topology topology; + struct dpu_crtc_state *cstate; int ret; /* @@ -1243,6 +1249,27 @@ static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_stat if (ret) return ret; + cstate = to_dpu_crtc_state(crtc_state); + + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); + num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + crtc, DPU_HW_BLK_DSPP, hw_dspp, + ARRAY_SIZE(hw_dspp)); + + for (i = 0; i < num_lm; i++) { + int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); + + cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]); + cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]); + if (i < num_dspp) + cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]); + } + + cstate->num_mixers = num_lm; + return 0; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 204360485b81..068d4e47eaa9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -934,14 +934,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, struct dpu_encoder_virt *dpu_enc; struct msm_drm_private *priv; struct dpu_kms *dpu_kms; - struct dpu_crtc_state *cstate; struct dpu_global_state *global_state; struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; - struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; - struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL }; struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC]; - int num_lm, num_ctl, num_pp, num_dsc; + int num_pp, num_dsc; unsigned int dsc_mask = 0; int i; @@ -968,13 +965,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp, ARRAY_SIZE(hw_pp)); - num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); - num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->crtc, DPU_HW_BLK_DSPP, hw_dspp, - ARRAY_SIZE(hw_dspp)); + drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) @@ -992,18 +984,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, dpu_enc->dsc_mask = dsc_mask; - cstate = to_dpu_crtc_state(crtc_state); - - for (i = 0; i < num_lm; i++) { - int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); - - cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]); - cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]); - cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]); - } - - cstate->num_mixers = num_lm; - dpu_enc->connector = conn_state->connector; for (i = 0; i < dpu_enc->num_phys_encs; i++) { From patchwork Tue Mar 21 01:18:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 665611 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C0A53C761AF for ; Tue, 21 Mar 2023 01:20:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230444AbjCUBUE (ORCPT ); Mon, 20 Mar 2023 21:20:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229540AbjCUBUB (ORCPT ); Mon, 20 Mar 2023 21:20:01 -0400 Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 17BB0144A3 for ; Mon, 20 Mar 2023 18:19:32 -0700 (PDT) Received: by mail-lf1-x134.google.com with SMTP id t11so17244347lfr.1 for ; Mon, 20 Mar 2023 18:19:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679361510; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=P3gZrcHEgMaoVLg/Qn82uZJfC8UCV4DXP2rS4CdikJk=; b=ubcPRMxmRwEd85TrfYF/RwP07EFJYEh945p6zqIsaVf+qEtLWvPWR+c7mYruJouS7s 8+x3swC9Glg/NfQ/cQXkppvzxZmAy5uzWwacFfgUF8P7Ed8Fo3+SUAn1DEMCSGcb91Ks R7aJ2m7pdbKLm538cec2q50wLiHgJT6SjAv3q0ZsPx0bITbjcIHUNzkqRdmTK69fl2hE 0KMGIge19xJMZQ3KrBhpu/C8Bp73iT5xOOXW3aQ3N1x8353qTu2NKmSepQnnaUkSk8CM 7GwcAZZm/odQuZkjT2IDdPWLFscTAXNBFGo83Ov6C/8jNY42qLBYf4GfnwRJ8hVOLBGV zqRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679361510; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=P3gZrcHEgMaoVLg/Qn82uZJfC8UCV4DXP2rS4CdikJk=; b=SfzP3ECFtaQWsOfvlhNVT6DK9TesET20CPf89mX4fRvIrbor5NQ4e8c8KeoHAsvT2s NPt07VKtpjbEcsz2qMrOLMDTrCg72FNzdXQd+tDKta1DLlGUIj1qFBWhQe/qvx52fL+f DzVHhx6UfBzdsbXcB5kGjl2zl/lcdQZHsGXgsx6dvzWWeIzqgnCrf32zOkwl4u9cvGK1 UZNmE0YgUkGXAmuX10L+j7IXpag5V6aPcHOFDtOmr/nWDrUmZpmYB0MVxukahpCKe9LF FM89QvYgFwyraWbDmbcYVoyXEJqCCW+LifhlNxVxn+P6862KKgCcvSIzX9sscuY2nTJC h5Cg== X-Gm-Message-State: AO0yUKVm0hRqLmKJEZtlnNqgdEoZoEVXjSdviaGIzqVkKAcPGSz/op31 TA1iNhkGsk+x41Mk0iOU+rTp/w== X-Google-Smtp-Source: AK7set/R+d/jdQwRe0GjLylJCWLzBcnmxTSOu/bfURtntrciRtQ/h/o6B+OE49fG3/rWDbQOQoc2JQ== X-Received: by 2002:ac2:5218:0:b0:4cc:96f8:f9c4 with SMTP id a24-20020ac25218000000b004cc96f8f9c4mr260566lfl.45.1679361510080; Mon, 20 Mar 2023 18:18:30 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c18-20020ac25312000000b004eaec70c68esm46863lfh.294.2023.03.20.18.18.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Mar 2023 18:18:29 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [RFC PATCH v2 10/13] drm/msm/dpu: add list of supported formats to the DPU caps Date: Tue, 21 Mar 2023 04:18:18 +0300 Message-Id: <20230321011821.635977-11-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> References: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org As we are going to add virtual planes, add the list of supported formats to the hw catalog entry. It will be used to setup universal planes, with later selecting a pipe depending on whether the YUV format is used for the framebuffer. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 26 +++++++++++++++++++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 +++ 2 files changed, 30 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 212d546b6c5d..2d6944a9679a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -315,6 +315,8 @@ static const struct dpu_caps msm8998_dpu_caps = { .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, .max_hdeci_exp = MAX_HORZ_DECIMATION, .max_vdeci_exp = MAX_VERT_DECIMATION, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps qcm2290_dpu_caps = { @@ -324,6 +326,8 @@ static const struct dpu_caps qcm2290_dpu_caps = { .has_idle_pc = true, .max_linewidth = 2160, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sdm845_dpu_caps = { @@ -339,6 +343,8 @@ static const struct dpu_caps sdm845_dpu_caps = { .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, .max_hdeci_exp = MAX_HORZ_DECIMATION, .max_vdeci_exp = MAX_VERT_DECIMATION, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sc7180_dpu_caps = { @@ -350,6 +356,8 @@ static const struct dpu_caps sc7180_dpu_caps = { .has_idle_pc = true, .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sm6115_dpu_caps = { @@ -361,6 +369,8 @@ static const struct dpu_caps sm6115_dpu_caps = { .has_idle_pc = true, .max_linewidth = 2160, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sm8150_dpu_caps = { @@ -376,6 +386,8 @@ static const struct dpu_caps sm8150_dpu_caps = { .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, .max_hdeci_exp = MAX_HORZ_DECIMATION, .max_vdeci_exp = MAX_VERT_DECIMATION, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sc8180x_dpu_caps = { @@ -391,6 +403,8 @@ static const struct dpu_caps sc8180x_dpu_caps = { .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, .max_hdeci_exp = MAX_HORZ_DECIMATION, .max_vdeci_exp = MAX_VERT_DECIMATION, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sc8280xp_dpu_caps = { @@ -404,6 +418,8 @@ static const struct dpu_caps sc8280xp_dpu_caps = { .has_3d_merge = true, .max_linewidth = 5120, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sm8250_dpu_caps = { @@ -417,6 +433,8 @@ static const struct dpu_caps sm8250_dpu_caps = { .has_3d_merge = true, .max_linewidth = 900, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sm8350_dpu_caps = { @@ -430,6 +448,8 @@ static const struct dpu_caps sm8350_dpu_caps = { .has_3d_merge = true, .max_linewidth = 4096, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sm8450_dpu_caps = { @@ -443,6 +463,8 @@ static const struct dpu_caps sm8450_dpu_caps = { .has_3d_merge = true, .max_linewidth = 5120, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sm8550_dpu_caps = { @@ -456,6 +478,8 @@ static const struct dpu_caps sm8550_dpu_caps = { .has_3d_merge = true, .max_linewidth = 5120, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_caps sc7280_dpu_caps = { @@ -467,6 +491,8 @@ static const struct dpu_caps sc7280_dpu_caps = { .has_idle_pc = true, .max_linewidth = 2400, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .format_list = plane_formats_yuv, + .num_formats = ARRAY_SIZE(plane_formats_yuv), }; static const struct dpu_mdp_cfg msm8998_mdp[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 89b372cdca92..4847aae78db2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -404,6 +404,8 @@ struct dpu_rotation_cfg { * @pixel_ram_size size of latency hiding and de-tiling buffer in bytes * @max_hdeci_exp max horizontal decimation supported (max is 2^value) * @max_vdeci_exp max vertical decimation supported (max is 2^value) + * @format_list: Pointer to list of supported formats + * @num_formats: Number of supported formats */ struct dpu_caps { u32 max_mixer_width; @@ -419,6 +421,8 @@ struct dpu_caps { u32 pixel_ram_size; u32 max_hdeci_exp; u32 max_vdeci_exp; + const u32 *format_list; + u32 num_formats; }; /** From patchwork Tue Mar 21 01:18:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 665609 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ECACFC6FD1C for ; Tue, 21 Mar 2023 01:20:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229540AbjCUBUo (ORCPT ); Mon, 20 Mar 2023 21:20:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47844 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230454AbjCUBUn (ORCPT ); Mon, 20 Mar 2023 21:20:43 -0400 Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF9925591 for ; Mon, 20 Mar 2023 18:20:14 -0700 (PDT) Received: by mail-lf1-x12e.google.com with SMTP id k37so4278762lfv.0 for ; Mon, 20 Mar 2023 18:20:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679361511; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=19Mh1AennFks/7EMfm7YcmHqybWalPcK9N+h2nso4NM=; b=E2Tm00ZfPxZRTFrHiINcrkN47RtD3K7YkBow6t5sagMcYhCs4GYZQoHGg/vR6HQmXb cF6B77vvj1ANdqtdDxsaEGY6T/qCd0qmn5Q6qof2HCIJ/ptt5w7d78cPC1xbNrZnYtXA 0AWbaPfclpDzX1iKhFc6pTvwdY0oJNu8LsjHulfdaEsXWm9h8+/0KfIKKMGxC02L0Z+X JVg5lLBVSdnCsfSf0TTes96FsomJDvRSkUqJzZIlJSx9Q7Wtg/wj7I2UvBSnz70pTy2W tMsbpy1/WZ4nNFsmIFfWp9AI5Ese0gbZthX/Vr81PLI4t/+h2Q5qUkvGuxfKM+cV7MXZ ePEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679361511; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=19Mh1AennFks/7EMfm7YcmHqybWalPcK9N+h2nso4NM=; b=vX7z8CPfJsvMITHDn1RoLd53NOiaZN6j3kpwf04pGFLA17yoxif7QSBHrUI4jDBhuH LYydMoMt5+Piwt6aLAma8/Te9xZrySdl1XZJP9PPxiJNnDSEy3r0hk03HF36X3sxeRpr 95a9uAKlrk/QU7mU7XVWAtZOgbVfMWJOLRtlo6YLaJrVGltuAo8rZVKYC3NsEJpxAeBK 4frNqrIfNACcjTvhiLGBNNljZOyK6V+EMd5f9lvRWEKS8bodAZG1KaQk7ZyQ/JqBkm2B XF8p2LPKeXfwLnFelvXIj4PCfynSOWYrSaJpDrgsEa7jMNNehcxxo69U86t1OadUE/Kt zcsA== X-Gm-Message-State: AO0yUKVn7dl96PJPQU3w44dBRBClaIenEZkeG1/FGNmkjI/2xylWqy9V zpC9epczvVE8Y+lj8IttjP8f3Q== X-Google-Smtp-Source: AK7set+aTiuu1uL1+bgmR9So63+iQYZYtju6YL2CUqZSRgh063oiaoRPpeS4LcJfucYU8Ou4ChRZJQ== X-Received: by 2002:ac2:53b6:0:b0:4dd:a445:e69d with SMTP id j22-20020ac253b6000000b004dda445e69dmr313101lfh.26.1679361510839; Mon, 20 Mar 2023 18:18:30 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c18-20020ac25312000000b004eaec70c68esm46863lfh.294.2023.03.20.18.18.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Mar 2023 18:18:30 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [RFC PATCH v2 11/13] drm/msm/dpu: add a field describing inline rotation to dpu_caps Date: Tue, 21 Mar 2023 04:18:19 +0300 Message-Id: <20230321011821.635977-12-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> References: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org We need to know if the platform supports inline rotation on any of the SSPP blocks or not. Add this information to struct dpu_caps in a form of the boolean field has_inline_rot. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 2d6944a9679a..33527ec7c938 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -489,6 +489,7 @@ static const struct dpu_caps sc7280_dpu_caps = { .ubwc_version = DPU_HW_UBWC_VER_30, .has_dim_layer = true, .has_idle_pc = true, + .has_inline_rot = true, .max_linewidth = 2400, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, .format_list = plane_formats_yuv, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 4847aae78db2..cc64fb2e815f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -400,6 +400,7 @@ struct dpu_rotation_cfg { * @has_dim_layer dim layer feature status * @has_idle_pc indicate if idle power collapse feature is supported * @has_3d_merge indicate if 3D merge is supported + * @has_inline_rot indicate if inline rotation is supported * @max_linewidth max linewidth for sspp * @pixel_ram_size size of latency hiding and de-tiling buffer in bytes * @max_hdeci_exp max horizontal decimation supported (max is 2^value) @@ -416,6 +417,7 @@ struct dpu_caps { bool has_dim_layer; bool has_idle_pc; bool has_3d_merge; + bool has_inline_rot; /* SSPP limits */ u32 max_linewidth; u32 pixel_ram_size; From patchwork Tue Mar 21 01:18:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 665608 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3E10C6FD1C for ; Tue, 21 Mar 2023 01:21:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229810AbjCUBVB (ORCPT ); Mon, 20 Mar 2023 21:21:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229749AbjCUBVA (ORCPT ); Mon, 20 Mar 2023 21:21:00 -0400 Received: from mail-lf1-f44.google.com (mail-lf1-f44.google.com [209.85.167.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 58EF922C92 for ; Mon, 20 Mar 2023 18:20:34 -0700 (PDT) Received: by mail-lf1-f44.google.com with SMTP id i13so1536735lfe.9 for ; Mon, 20 Mar 2023 18:20:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679361511; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RNxFrjjNk5OD9FmYXNKkLwbAV8jlURGfSu0y39mMqG4=; b=iHXeEsU7xNcDgY76MhN6sR2DLjbtqTcDuJjOsTZkEABys3VFwpRfC2aD1x/2CACXUx ACBYv4ruwERknKDeoPhPz6rAJu8oMnjdoGKucHq/4IrutLGE2Y16AEXd9ah32Z3uzQoE ssuDQIl0MBOCetAMH+rEOhAL4BarweK679mu+S/ypB9Xh6yyREaHEfNfodT8DWu8xv4Z BS1GkPLYtAmy1X5F5/3NjD9S4Udt+bcGV0vIYcQbL8LtXZMbB6DEpZb3vxo1KZ2P+Nda jKyeDYTHpS8v5xYwFB8yUF8Jso2edlF2ngptc7FViCcz44cHtjmLxsvD1m//AUj2EpZB NVhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679361511; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RNxFrjjNk5OD9FmYXNKkLwbAV8jlURGfSu0y39mMqG4=; b=CDxHl+ESbJrVPu6j07CRSeBPbpW6Jgng19xB3GwxJiHQD+MScOK8b98i75Ubk6TRAb eQW+YWc+8i23Pc/ZNzxcanmRtucG3KrKZ72YYU19KH/sGD+4eCrkqWoJ8nvHYjjl+bE7 8Dg7emaovfHHu8rKGvjWDP8gcqEP/eG9J5rPwona1Amf06mYF1WyKbsfFSfo7MRug33u 4qH5yEsXaVHrO87sDxFAWncIGAB2GARvJCUvaEZEPgkLDGJk3QpXbED4xdPVcYHTvDz3 gG1w093zMO+ypZxLVhjV/aEyZe/nEktRx1bPMFXdepsSR4mWM5JHESY1ae/gbkGo2oc4 lmmA== X-Gm-Message-State: AO0yUKUS3hPzFI8k6pJUDIm7bP1jY6RAmyVy+D2QXDp2paVnVwYhCeU3 8AKh2ZXtUl1BL+AFjUNPLqqPow== X-Google-Smtp-Source: AK7set/LjnkYeqL0qT9/k+/VHXRik3NzNvRxIwLhCXCD9uhKUrJDMLYzRSNiI1OAkw2WE1JjLAkLBQ== X-Received: by 2002:ac2:4a71:0:b0:4d2:c70a:fe24 with SMTP id q17-20020ac24a71000000b004d2c70afe24mr303842lfp.1.1679361511622; Mon, 20 Mar 2023 18:18:31 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c18-20020ac25312000000b004eaec70c68esm46863lfh.294.2023.03.20.18.18.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Mar 2023 18:18:31 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar Cc: Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org Subject: [RFC PATCH v2 12/13] drm/msm/dpu: add support for virtual planes Date: Tue, 21 Mar 2023 04:18:20 +0300 Message-Id: <20230321011821.635977-13-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> References: <20230321011821.635977-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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. 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=1' kernel parameter. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 59 +++++-- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 120 ++++++++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 + drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 187 ++++++++++++++++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 24 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 65 ++++++++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 24 +++ 7 files changed, 413 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 8ef191fd002d..cdece21b81c9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1273,6 +1273,29 @@ static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct drm_crtc_stat return 0; } +static int dpu_crtc_assign_plane_resources(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state) +{ + struct dpu_global_state *global_state; + struct drm_plane *plane; + int rc; + + global_state = 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); + + drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { + rc = dpu_plane_virtual_assign_resources(plane, crtc, + global_state, + crtc_state->state); + if (rc) + return rc; + } + + return 0; +} + static int dpu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { @@ -1281,7 +1304,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state); - const struct drm_plane_state *pstate; struct drm_plane *plane; int rc = 0; @@ -1294,6 +1316,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, return rc; } + if (dpu_use_virtual_planes && + crtc_state->planes_changed) { + rc = dpu_crtc_assign_plane_resources(crtc, crtc_state); + if (rc < 0) + return rc; + } + if (!crtc_state->enable || !crtc_state->active) { DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n", crtc->base.id, crtc_state->enable, @@ -1311,20 +1340,30 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, if (cstate->num_mixers) _dpu_crtc_setup_lm_bounds(crtc, crtc_state); - /* FIXME: move this to dpu_plane_atomic_check? */ - drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { - struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate); - - if (IS_ERR_OR_NULL(pstate)) { - rc = PTR_ERR(pstate); - DPU_ERROR("%s: failed to get plane%d state, %d\n", - dpu_crtc->name, plane->base.id, rc); - return rc; + drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { + const struct drm_plane_state *pstate; + struct dpu_plane_state *dpu_pstate; + + pstate = drm_atomic_get_plane_state(crtc_state->state, plane); + if (IS_ERR(pstate)) + return PTR_ERR(pstate); + + if (dpu_use_virtual_planes) { + /* + * In case of virtual planes, the plane's atomic_check + * is a shortcut. Perform actual check here, after + * allocating SSPPs. + */ + rc = dpu_plane_atomic_check(plane, crtc_state->state); + if (rc) + return rc; } if (!pstate->visible) continue; + /* FIXME: move this to dpu_plane_atomic_check? */ + dpu_pstate = to_dpu_plane_state(pstate); dpu_pstate->needs_dirtyfb = needs_dirtyfb; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 35194262e628..487bb19ee9d6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -50,6 +50,9 @@ #define DPU_DEBUGFS_DIR "msm_dpu" #define DPU_DEBUGFS_HWMASKNAME "hw_log_mask" +bool dpu_use_virtual_planes = false; +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); @@ -735,38 +738,54 @@ static int _dpu_kms_setup_displays(struct drm_device *dev, return rc; } -#define MAX_PLANES 20 -static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) +static int dpu_kms_create_virtual_planes(struct dpu_kms *dpu_kms, + int max_crtc_count, + struct drm_plane **primary_planes, + struct drm_plane **cursor_planes) { - struct drm_device *dev; - struct drm_plane *primary_planes[MAX_PLANES], *plane; - struct drm_plane *cursor_planes[MAX_PLANES] = { NULL }; - struct drm_crtc *crtc; - struct drm_encoder *encoder; - unsigned int num_encoders; + const struct dpu_mdss_cfg *catalog = dpu_kms->catalog; + struct drm_device *dev = dpu_kms->dev; + int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; + struct drm_plane *plane; - struct msm_drm_private *priv; - const struct dpu_mdss_cfg *catalog; + /* Create the planes, keeping track of one primary/cursor per crtc */ + for (i = 0; i < catalog->sspp_count; i++) { + enum drm_plane_type type; - int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; - int max_crtc_count; - dev = dpu_kms->dev; - priv = dev->dev_private; - catalog = dpu_kms->catalog; + if (primary_planes_idx < max_crtc_count) + type = DRM_PLANE_TYPE_PRIMARY; + else if (cursor_planes_idx < max_crtc_count) + type = DRM_PLANE_TYPE_CURSOR; + else + type = DRM_PLANE_TYPE_OVERLAY; - /* - * Create encoder and query display drivers to create - * bridges and connectors - */ - ret = _dpu_kms_setup_displays(dev, priv, dpu_kms); - if (ret) - return ret; + DPU_DEBUG("Create plane type %d\n", type); - num_encoders = 0; - drm_for_each_encoder(encoder, dev) - num_encoders++; + plane = dpu_plane_init_virtual(dev, type, (1UL << max_crtc_count) - 1); + if (IS_ERR(plane)) { + DPU_ERROR("dpu_plane_init failed\n"); + ret = PTR_ERR(plane); + return ret; + } - max_crtc_count = min(catalog->mixer_count, num_encoders); + if (type == DRM_PLANE_TYPE_CURSOR) + cursor_planes[cursor_planes_idx++] = plane; + else if (type == DRM_PLANE_TYPE_PRIMARY) + primary_planes[primary_planes_idx++] = plane; + } + + return primary_planes_idx; +} + +static int dpu_kms_create_planes(struct dpu_kms *dpu_kms, + int max_crtc_count, + struct drm_plane **primary_planes, + struct drm_plane **cursor_planes) +{ + const struct dpu_mdss_cfg *catalog = dpu_kms->catalog; + struct drm_device *dev = dpu_kms->dev; + int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; + struct drm_plane *plane; /* Create the planes, keeping track of one primary/cursor per crtc */ for (i = 0; i < catalog->sspp_count; i++) { @@ -784,8 +803,8 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) type, catalog->sspp[i].features, catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR)); - plane = dpu_plane_init(dev, catalog->sspp[i].id, type, - (1UL << max_crtc_count) - 1); + plane = dpu_plane_init_sspp(dev, catalog->sspp[i].id, type, + (1UL << max_crtc_count) - 1); if (IS_ERR(plane)) { DPU_ERROR("dpu_plane_init failed\n"); ret = PTR_ERR(plane); @@ -798,7 +817,50 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) primary_planes[primary_planes_idx++] = plane; } - max_crtc_count = min(max_crtc_count, primary_planes_idx); + return primary_planes_idx; +} + +#define MAX_PLANES 20 +static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) +{ + struct drm_device *dev; + struct drm_plane *primary_planes[MAX_PLANES]; + struct drm_plane *cursor_planes[MAX_PLANES] = { NULL }; + struct drm_crtc *crtc; + struct drm_encoder *encoder; + unsigned int num_encoders; + + struct msm_drm_private *priv; + const struct dpu_mdss_cfg *catalog; + int i, ret; + int max_crtc_count; + + dev = dpu_kms->dev; + priv = dev->dev_private; + catalog = dpu_kms->catalog; + + /* + * Create encoder and query display drivers to create + * bridges and connectors + */ + ret = _dpu_kms_setup_displays(dev, priv, dpu_kms); + if (ret) + return ret; + + num_encoders = 0; + drm_for_each_encoder(encoder, dev) + num_encoders++; + + max_crtc_count = min(catalog->mixer_count, num_encoders); + + if (dpu_use_virtual_planes) + ret = dpu_kms_create_virtual_planes(dpu_kms, max_crtc_count, primary_planes, cursor_planes); + else + ret = dpu_kms_create_planes(dpu_kms, max_crtc_count, primary_planes, cursor_planes); + if (ret < 0) + return ret; + + max_crtc_count = min(max_crtc_count, ret); /* Create one CRTC per encoder */ for (i = 0; i < max_crtc_count; i++) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 934874eb2248..9f6478f0ced6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -65,6 +65,8 @@ #define DPU_NAME_SIZE 12 +extern bool dpu_use_virtual_planes; + struct dpu_kms { struct msm_kms base; struct drm_device *dev; @@ -134,6 +136,8 @@ struct dpu_global_state { uint32_t ctl_to_crtc_id[CTL_MAX - CTL_0]; uint32_t dspp_to_crtc_id[DSPP_MAX - DSPP_0]; uint32_t dsc_to_crtc_id[DSC_MAX - DSC_0]; + + uint32_t sspp_to_crtc_id[SSPP_MAX - SSPP_NONE]; }; struct dpu_global_state diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index cf17075676d5..ee906c276aa5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -837,8 +837,77 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, return 0; } -static int dpu_plane_atomic_check(struct drm_plane *plane, - struct drm_atomic_state *state) +static int dpu_plane_virtual_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *plane_state = + drm_atomic_get_plane_state(state, plane); + struct dpu_plane_state *pstate = to_dpu_plane_state(plane_state); + const struct dpu_format *format; + struct drm_crtc_state *crtc_state; + + /* + * Main part of checks, including drm_atomic_helper_check_plane_state() + * is called from dpu_crtc_atomic_check(). Do minimal processing here. + */ + + if (!plane_state->fb) { + plane_state->visible = false; + + /* resources are freed by dpu_crtc_atomic_check(), but clean them here */ + pstate->pipe.sspp = NULL; + pstate->r_pipe.sspp = NULL; + + return 0; + } + + format = to_dpu_format(msm_framebuffer_format(plane_state->fb)); + crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc); + + /* force resource reallocation if the format of FB has changed */ + if (pstate->saved_fmt != format) { + crtc_state->planes_changed = true; + pstate->saved_fmt = format; + } + + return 0; +} + +int dpu_plane_virtual_assign_resources(struct drm_plane *plane, + struct drm_crtc *crtc, + struct dpu_global_state *global_state, + struct drm_atomic_state *state) +{ + struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); + struct dpu_plane_state *pstate; + struct drm_plane_state *plane_state; + struct dpu_hw_sspp *hw_sspp; + bool yuv, scale, rot90; + + plane_state = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); + + yuv = plane_state->fb ? + DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(plane_state->fb))) : + false; + scale = (plane_state->src_w >> 16 != plane_state->crtc_w) || + (plane_state->src_h >> 16 != plane_state->crtc_h); + + rot90 = drm_rotation_90_or_270(plane_state->rotation); + + hw_sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, yuv, scale, rot90); + if (!hw_sspp) + return -ENODEV; + + pstate = to_dpu_plane_state(plane_state); + pstate->pipe.sspp = hw_sspp; + + return 0; +} + +int dpu_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) { struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); @@ -863,8 +932,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, crtc_state = drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); - pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); - r_pipe->sspp = NULL; + if (pdpu->pipe != SSPP_NONE) { + pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); + r_pipe->sspp = NULL; + } pipe_hw_caps = pstate->pipe.sspp->cap; sblk = pstate->pipe.sspp->cap->sblk; @@ -1358,12 +1429,14 @@ static void dpu_plane_atomic_print_state(struct drm_printer *p, drm_printf(p, "\tstage=%d\n", pstate->stage); - drm_printf(p, "\tsspp[0]=%s\n", pipe->sspp->cap->name); - drm_printf(p, "\tmultirect_mode[0]=%s\n", dpu_get_multirect_mode(pipe->multirect_mode)); - drm_printf(p, "\tmultirect_index[0]=%s\n", - dpu_get_multirect_index(pipe->multirect_index)); - drm_printf(p, "\tsrc[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->src_rect)); - drm_printf(p, "\tdst[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->dst_rect)); + if (pipe->sspp) { + drm_printf(p, "\tsspp[0]=%s\n", pipe->sspp->cap->name); + drm_printf(p, "\tmultirect_mode[0]=%s\n", dpu_get_multirect_mode(pipe->multirect_mode)); + drm_printf(p, "\tmultirect_index[0]=%s\n", + dpu_get_multirect_index(pipe->multirect_index)); + drm_printf(p, "\tsrc[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->src_rect)); + drm_printf(p, "\tdst[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->dst_rect)); + } if (r_pipe->sspp) { drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name); @@ -1453,18 +1526,30 @@ static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = { .atomic_update = dpu_plane_atomic_update, }; +/* + * For virtual planes atomic_check is called from dpu_crtc_atomic_check(), + * after CRTC code assigning SSPP. + */ +static const struct drm_plane_helper_funcs dpu_plane_virtual_helper_funcs = { + .prepare_fb = dpu_plane_prepare_fb, + .cleanup_fb = dpu_plane_cleanup_fb, + .atomic_check = dpu_plane_virtual_atomic_check, + .atomic_update = dpu_plane_atomic_update, +}; + /* initialize plane */ -struct drm_plane *dpu_plane_init(struct drm_device *dev, - uint32_t pipe, enum drm_plane_type type, - unsigned long possible_crtcs) +static struct drm_plane *dpu_plane_init(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 = NULL; - const uint32_t *format_list; struct dpu_plane *pdpu; struct msm_drm_private *priv = dev->dev_private; struct dpu_kms *kms = to_dpu_kms(priv->kms); - struct dpu_hw_sspp *pipe_hw; - uint32_t num_formats; uint32_t supported_rotations; int ret = -EINVAL; @@ -1480,16 +1565,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, plane = &pdpu->base; pdpu->pipe = pipe; - /* initialize underlying h/w driver */ - pipe_hw = 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); - goto clean_plane; - } - - format_list = pipe_hw->cap->sblk->format_list; - num_formats = pipe_hw->cap->sblk->num_formats; - ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs, format_list, num_formats, supported_format_modifiers, type, NULL); @@ -1510,7 +1585,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180; - if (pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION)) + if (inline_rotation) supported_rotations |= DRM_MODE_ROTATE_MASK; drm_plane_create_rotation_property(plane, @@ -1519,8 +1594,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, drm_plane_enable_fb_damage_clips(plane); /* success! finalize initialization */ - drm_plane_helper_add(plane, &dpu_plane_helper_funcs); - mutex_init(&pdpu->lock); DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name, @@ -1531,3 +1604,59 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, kfree(pdpu); return ERR_PTR(ret); } + +struct drm_plane *dpu_plane_init_sspp(struct drm_device *dev, + uint32_t pipe, enum drm_plane_type type, + unsigned long possible_crtcs) +{ + struct drm_plane *plane = NULL; + struct msm_drm_private *priv = dev->dev_private; + struct dpu_kms *kms = to_dpu_kms(priv->kms); + struct dpu_hw_sspp *pipe_hw; + + /* initialize underlying h/w driver */ + pipe_hw = 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 = dpu_plane_init(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); + + DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name, + pipe, plane->base.id); + + return plane; +} + +struct drm_plane *dpu_plane_init_virtual(struct drm_device *dev, + enum drm_plane_type type, + unsigned long possible_crtcs) +{ + struct drm_plane *plane = NULL; + struct msm_drm_private *priv = dev->dev_private; + struct dpu_kms *kms = to_dpu_kms(priv->kms); + + plane = dpu_plane_init(dev, type, possible_crtcs, + kms->catalog->caps->has_inline_rot, + kms->catalog->caps->format_list, + kms->catalog->caps->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/msm/disp/dpu1/dpu_plane.h index abd6b21a049b..cb1e31ef0d3f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h @@ -31,6 +31,7 @@ * @plane_clk: calculated clk per plane * @needs_dirtyfb: whether attached CRTC needs pixel data explicitly flushed * @rotation: simplified drm rotation hint + * @saved_fmt: format used by the plane's FB, saved for for virtual plane support */ struct dpu_plane_state { struct drm_plane_state base; @@ -48,6 +49,8 @@ struct dpu_plane_state { bool needs_dirtyfb; unsigned int rotation; + + const struct dpu_format *saved_fmt; }; #define to_dpu_plane_state(x) \ @@ -66,17 +69,27 @@ void dpu_plane_flush(struct drm_plane *plane); void dpu_plane_set_error(struct drm_plane *plane, bool error); /** - * dpu_plane_init - create new dpu plane for the given pipe + * dpu_plane_init_sspp - 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 * */ -struct drm_plane *dpu_plane_init(struct drm_device *dev, +struct drm_plane *dpu_plane_init_sspp(struct drm_device *dev, uint32_t pipe, enum drm_plane_type type, unsigned long possible_crtcs); +/** + * dpu_plane_init_virtual - create new dpu virtualized 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 + */ +struct drm_plane *dpu_plane_init_virtual(struct drm_device *dev, + enum drm_plane_type type, + unsigned long possible_crtcs); + /** * dpu_plane_color_fill - enables color fill on plane * @plane: Pointer to DRM plane object @@ -93,4 +106,11 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable); static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) {} #endif +int dpu_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state); + +int dpu_plane_virtual_assign_resources(struct drm_plane *plane, + struct drm_crtc *crtc, + struct dpu_global_state *global_state, + struct drm_atomic_state *state); + #endif /* _DPU_PLANE_H_ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index f0a94008d17a..6130ac87d7e3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -607,6 +607,71 @@ int dpu_rm_reserve( return ret; } +struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm, + struct dpu_global_state *global_state, + struct drm_crtc *crtc, + bool yuv, bool scale, bool rot90) +{ + uint32_t crtc_id = crtc->base.id; + struct dpu_hw_sspp *hw_sspp; + bool retry = false; + int i; + +retry_loop: + for (i = 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 = rm->hw_sspp[i]; + + /* skip incompatible planes */ + if (scale && !(hw_sspp->cap->features & DPU_SSPP_SCALER)) + continue; + + if (yuv && !(hw_sspp->cap->features & DPU_SSPP_CSC_ANY)) + continue; + + if (rot90 && !(hw_sspp->cap->features & DPU_SSPP_INLINE_ROTATION)) + continue; + + /* + * For non-yuv, non-scaled planes try to find simple (DMA) + * plane, fallback to VIG on a second try. + * + * This way we'd leave VIG sspps to be later used for YUV formats. + */ + + if (!scale && !yuv && !rot90 && !retry && + (hw_sspp->cap->features & + (DPU_SSPP_SCALER | DPU_SSPP_CSC_ANY | DPU_SSPP_INLINE_ROTATION))) + continue; + + global_state->sspp_to_crtc_id[hw_sspp->idx - SSPP_NONE] = crtc_id; + + return hw_sspp; + } + + /* If we were looking for DMA plane, retry looking for VIG plane */ + if (!scale && !yuv && !retry) { + retry = true; + goto retry_loop; + } + + return NULL; +} + +void dpu_rm_release_all_sspp(struct dpu_global_state *global_state, + struct drm_crtc *crtc) +{ + uint32_t crtc_id = crtc->base.id; + + _dpu_rm_clear_mapping(global_state->sspp_to_crtc_id, + ARRAY_SIZE(global_state->sspp_to_crtc_id), crtc_id); +} + int dpu_rm_get_assigned_resources(struct dpu_rm *rm, struct dpu_global_state *global_state, struct drm_crtc *crtc, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index f402bec8322b..5bf6740ecb45 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -82,6 +82,30 @@ int dpu_rm_reserve( void dpu_rm_release(struct dpu_global_state *global_state, struct drm_crtc *crtc); +/** + * 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 + * @yuv: required SSPP supporting YUV formats + * @scale: required SSPP supporting scaling + * @rot90: required SSPP supporting inline 90 degree rotation + */ +struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm, + struct dpu_global_state *global_state, + struct drm_crtc *crtc, + bool yuv, bool scale, bool rot90); + +/** + * 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 + * @Return: 0 on Success otherwise -ERROR + */ +void dpu_rm_release_all_sspp(struct dpu_global_state *global_state, + struct drm_crtc *crtc); + /** * Get hw resources of the given type that are assigned to this encoder. */