Message ID | 1667996206-4153-4-git-send-email-quic_kalyant@quicinc.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp300340wru; Wed, 9 Nov 2022 04:19:35 -0800 (PST) X-Google-Smtp-Source: AMsMyM7Qh59NARyBo6YkdyErgvafXONqAGxS6WZqwh//w2HIK3Si0IyAlZk732bzfcQ/CAVqKNE7 X-Received: by 2002:a05:6402:5107:b0:462:3014:3d73 with SMTP id m7-20020a056402510700b0046230143d73mr59627667edd.177.1667996375451; Wed, 09 Nov 2022 04:19:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1667996375; cv=none; d=google.com; s=arc-20160816; b=nQhhZmOPNvU53BJnxHdITaOtqVxxnTwhM/tSeKbjG4jcNQaTlyD2SRS8qm7uWkrfx9 boLV50xkKL4wVoc4ACoVgjizVXNqzRFV9y51KSGCdY/g6lol37iKdvoqVOTthgNBClyG 61dlx2kDBU/kRuGV6P0qKsKgLgmGQPljOPgkGi1h24v4YklNqwHBdS5aAC/4F1R3DJH9 D2PvXTFaVVCS2+k3VmN0aCXpaEQ205jQPDC4pmb+Dy7klLtKjgZ91AlYtHr/x8nkSiOk IQstP6Wjm1jVlTfQ+bSofsUW78PFd/pSYbo5Qkoitz+hcDePdCapA/Fb4EBOUnOOWqFq zd5w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=B7j8GdSbRe5nhKt59DsbHmAwDLpL1UFr5MzKrR0Nb5E=; b=kfTR9oVdinTSjVUA3I3SzMWj/LWWXTWgxJgnCoj6gzzdJ8GuBgJwdm9id/TCJdYMKY Ct0+8hTj7vunHd1pPieu89CGF88OGLsQtfg24v+G7X7eE9tcGvbK8YxU0tiURs7gpQtB XawYbBDrrXW+dggLuuHK30cte2AMgN327wfC6sqGnuNkBNFKR+ZwgGzT2mz7ia6gtXcb PXA7uf0IYytZ0Q96ZuPUVQ5w8xGz6xyXd3Q3sh6hFoiR0vyJR9QUoSm2VVwn5j4jehN2 FcvWWxeKzhhzWCSGpQtNgxGp9dW5ocns9ssCV4rspcQSfTFDfa8vyGHHk1Xg++BJQWvA LNrg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=UlnhgFRJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w14-20020a05640234ce00b0045cd68a2bc5si16497610edc.17.2022.11.09.04.19.09; Wed, 09 Nov 2022 04:19:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=UlnhgFRJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230077AbiKIMRi (ORCPT <rfc822;dexuan.linux@gmail.com> + 99 others); Wed, 9 Nov 2022 07:17:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229977AbiKIMRJ (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 9 Nov 2022 07:17:09 -0500 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B19914D01; Wed, 9 Nov 2022 04:17:09 -0800 (PST) Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2A9BAWvl030615; Wed, 9 Nov 2022 12:17:07 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=qcppdkim1; bh=B7j8GdSbRe5nhKt59DsbHmAwDLpL1UFr5MzKrR0Nb5E=; b=UlnhgFRJUmhW6ZZYOejXnfPIYC/YU0FeBxsOCMnpxE9TgN0E1FudJ/HaWaKAPu72XNSa nj3XPx6tBEk+P4Hg2JyztgbhP5SFft5LwjP+dv38ZDqa0+ozjPKo+ocFkVhpC/WmeV8b 6UT4RmLm2J3iwGnrYYMCxwE4U56KvFLO+hbcdYoAJVT7B68THRTW4PKkzThzK+dxB5ot 5eUA14s2hsMi24rn6jiXjwI9pFemXkzma0oOD2TGPkYtHbCgljooHhW3aFX9pcUhZ2/e UZNGh+sdBXvA8APMGzhSUrwdRn9khKKRS/FFJA68lEFBWuFcuUYlFZvRxNK8atMxhXD2 8w== Received: from apblrppmta01.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3kr68m10hh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 09 Nov 2022 12:17:06 +0000 Received: from pps.filterd (APBLRPPMTA01.qualcomm.com [127.0.0.1]) by APBLRPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTP id 2A9CGxg8008059; Wed, 9 Nov 2022 12:17:03 GMT Received: from pps.reinject (localhost [127.0.0.1]) by APBLRPPMTA01.qualcomm.com (PPS) with ESMTPS id 3kngwkn0xu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 09 Nov 2022 12:17:03 +0000 Received: from APBLRPPMTA01.qualcomm.com (APBLRPPMTA01.qualcomm.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 2A9CH2HK008537; Wed, 9 Nov 2022 12:17:02 GMT Received: from kalyant-linux.qualcomm.com (kalyant-linux.qualcomm.com [10.204.66.210]) by APBLRPPMTA01.qualcomm.com (PPS) with ESMTP id 2A9CH2bP008458; Wed, 09 Nov 2022 12:17:02 +0000 Received: by kalyant-linux.qualcomm.com (Postfix, from userid 94428) id 3421348B5; Wed, 9 Nov 2022 04:17:01 -0800 (PST) From: Kalyan Thota <quic_kalyant@quicinc.com> To: dri-devel@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, devicetree@vger.kernel.org Cc: Kalyan Thota <quic_kalyant@quicinc.com>, linux-kernel@vger.kernel.org, robdclark@chromium.org, dianders@chromium.org, swboyd@chromium.org, quic_vpolimer@quicinc.com, dmitry.baryshkov@linaro.org, quic_abhinavk@quicinc.com Subject: [PATCH 4/4] drm/msm/disp/dpu1: add color management support for the crtc Date: Wed, 9 Nov 2022 04:16:46 -0800 Message-Id: <1667996206-4153-4-git-send-email-quic_kalyant@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1667996206-4153-1-git-send-email-quic_kalyant@quicinc.com> References: <1667996206-4153-1-git-send-email-quic_kalyant@quicinc.com> X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 5K9bfaRKuKhIqAqDfr8IRXCIMFwFgale X-Proofpoint-ORIG-GUID: 5K9bfaRKuKhIqAqDfr8IRXCIMFwFgale X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.895,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-11-09_05,2022-11-09_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 bulkscore=0 suspectscore=0 spamscore=0 lowpriorityscore=0 mlxscore=0 impostorscore=0 clxscore=1015 mlxlogscore=818 adultscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2210170000 definitions=main-2211090094 X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749020967353059434?= X-GMAIL-MSGID: =?utf-8?q?1749020967353059434?= |
Series |
[1/4] drm/msm/disp/dpu1: pin 1 crtc to 1 encoder
|
|
Commit Message
Kalyan Thota
Nov. 9, 2022, 12:16 p.m. UTC
Add color management support for the crtc provided there are
enough dspps that can be allocated from the catalogue
Signed-off-by: Kalyan Thota <quic_kalyant@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 15 ++++++--
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++++
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 +++---
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53 +++++++++++++++++++++++++++++
4 files changed, 77 insertions(+), 8 deletions(-)
Comments
On 09/11/2022 15:16, Kalyan Thota wrote: > Add color management support for the crtc provided there are > enough dspps that can be allocated from the catalogue > > Signed-off-by: Kalyan Thota <quic_kalyant@quicinc.com> > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 15 ++++++-- > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++++ > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 +++--- > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53 +++++++++++++++++++++++++++++ > 4 files changed, 77 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > index 4170fbe..6bd3a64 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > @@ -18,9 +18,11 @@ > #include <drm/drm_flip_work.h> > #include <drm/drm_framebuffer.h> > #include <drm/drm_mode.h> > +#include <drm/drm_mode_object.h> > #include <drm/drm_probe_helper.h> > #include <drm/drm_rect.h> > #include <drm/drm_vblank.h> > +#include "../../../drm_crtc_internal.h" If it's internal, it is not supposed to be used by other parties, including the msm drm. At least a comment why you are including this file would be helpful. > > #include "dpu_kms.h" > #include "dpu_hw_lm.h" > @@ -553,6 +555,17 @@ static void _dpu_crtc_complete_flip(struct drm_crtc *crtc) > spin_unlock_irqrestore(&dev->event_lock, flags); > } > > +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc) > +{ > + u32 ctm_id = crtc->dev->mode_config.ctm_property->base.id; > + u32 gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id; > + u32 degamma_id = crtc->dev->mode_config.degamma_lut_property->base.id; > + > + return !!(drm_mode_obj_find_prop_id(&crtc->base, ctm_id) || > + drm_mode_obj_find_prop_id(&crtc->base, gamma_id) || > + drm_mode_obj_find_prop_id(&crtc->base, degamma_id)); > +} > + > enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) > { > struct drm_encoder *encoder; > @@ -1604,8 +1617,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, > > drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); > > - drm_crtc_enable_color_mgmt(crtc, 0, true, 0); > - > /* save user friendly CRTC name for later */ > snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id); > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h > index 539b68b..8bac395 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h > @@ -300,4 +300,10 @@ static inline enum dpu_crtc_client_type dpu_crtc_get_client_type( > return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT; > } > > +/** > + * dpu_crtc_has_color_enabled - check if the crtc has color management enabled > + * @crtc: Pointer to drm crtc object > + */ > +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc); > + > #endif /* _DPU_CRTC_H_ */ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index 4c56a16..ebc3f25 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) > 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_display_mode *mode, > + struct drm_crtc *crtc) > { > struct msm_display_topology topology = {0}; > int i, intf_count = 0; > @@ -573,11 +574,9 @@ static struct msm_display_topology dpu_encoder_get_topology( > else > topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; > > - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { > - if (dpu_kms->catalog->dspp && > - (dpu_kms->catalog->dspp_count >= topology.num_lm)) > + if (dpu_crtc_has_color_enabled(crtc) && > + (dpu_kms->catalog->dspp_count >= topology.num_lm)) See the comment to the previous patch. It still applies here. > topology.num_dspp = topology.num_lm; > - } > > topology.num_enc = 0; > topology.num_intf = intf_count; > @@ -643,7 +642,7 @@ static int dpu_encoder_virt_atomic_check( > } > } > > - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); > + topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state->crtc); > > /* Reserve dynamic resources now. */ > if (!ret) { > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > index 552a89c..47a73fa 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > @@ -13,6 +13,7 @@ > #include <linux/dma-buf.h> > #include <linux/of_irq.h> > #include <linux/pm_opp.h> > +#include <linux/bitops.h> > > #include <drm/drm_crtc.h> > #include <drm/drm_file.h> > @@ -537,6 +538,44 @@ static void dpu_kms_wait_flush(struct msm_kms *kms, unsigned crtc_mask) > dpu_kms_wait_for_commit_done(kms, crtc); > } > > +/** > + * _dpu_kms_possible_dspps - Evaluate how many dspps pairs can be facilitated > + to enable color features for crtcs. > + * @dpu_kms: Pointer to dpu kms structure > + * Returns: count of dspp pairs > + * > + * Baring single entry, if atleast 2 dspps are available in the catalogue, > + * then color can be enabled for that crtc > + */ > +static inline u32 _dpu_kms_possible_dspps(struct dpu_kms *dpu_kms) > +{ > + > + u32 num_dspps = dpu_kms->catalog->dspp_count; > + > + if (num_dspps > 1) > + num_dspps = > + !(num_dspps % 2) ? num_dspps / 2 : (num_dspps - 1) / 2; Ugh. No. Please spell this clearly rather than using nice math and ternary operators: if (num_dspps <= 1) return num_dspps; else return num_dspps / 2; You see, if num_dspps %2 ! =0, then num_dspps / 2 == (num_dspps_2 - 1) / 2. > + > + return num_dspps; > +} > + > +static u32 _dpu_kms_attach_color(struct drm_device *dev, u32 enc_mask, > + u32 num_dspps) > +{ > + struct drm_encoder *encoder; > + struct drm_crtc *crtc; > + > + drm_for_each_encoder_mask(encoder, dev, enc_mask) { > + crtc = drm_crtc_from_index(dev, ffs(encoder->possible_crtcs) - 1); > + if (num_dspps && crtc) { > + drm_crtc_enable_color_mgmt(crtc, 0, true, 0); > + num_dspps--; Please. You can do this at the time you create the crtc. It would be much simpler. > + } > + } > + > + return num_dspps; > +} > + > static int _dpu_kms_initialize_dsi(struct drm_device *dev, > struct msm_drm_private *priv, > struct dpu_kms *dpu_kms) > @@ -747,6 +786,8 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) > > int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; > int max_crtc_count; > + u32 num_dspps, primary_enc_mask = 0, external_enc_mask = 0; > + > dev = dpu_kms->dev; > priv = dev->dev_private; > catalog = dpu_kms->catalog; > @@ -796,6 +837,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) > } > > max_crtc_count = min(max_crtc_count, primary_planes_idx); > + num_dspps = _dpu_kms_possible_dspps(dpu_kms); > > /* Create one CRTC per encoder */ > encoder = list_first_entry(&(dev)->mode_config.encoder_list, > @@ -808,9 +850,20 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) > } > priv->crtcs[priv->num_crtcs++] = crtc; > encoder->possible_crtcs = 1 << drm_crtc_index(crtc); > + > + if (!dpu_encoder_is_external(encoder) && > + !dpu_encoder_is_virtual(encoder)) if (dpu_encoder_internal_output(encoder)) > + primary_enc_mask |= drm_encoder_mask(encoder); > + else if (dpu_encoder_is_external(encoder)) > + external_enc_mask |= drm_encoder_mask(encoder); > + > encoder = list_next_entry(encoder, head); > } > > + /* Prefer Primary encoders in registering for color support */ > + num_dspps = _dpu_kms_attach_color(dev, primary_enc_mask, num_dspps); > + num_dspps = _dpu_kms_attach_color(dev, external_enc_mask, num_dspps); > + > return 0; > } >
>-----Original Message----- >From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> >Sent: Wednesday, November 9, 2022 6:02 PM >To: Kalyan Thota (QUIC) <quic_kalyant@quicinc.com>; dri- >devel@lists.freedesktop.org; linux-arm-msm@vger.kernel.org; >freedreno@lists.freedesktop.org; devicetree@vger.kernel.org >Cc: linux-kernel@vger.kernel.org; robdclark@chromium.org; >dianders@chromium.org; swboyd@chromium.org; Vinod Polimera (QUIC) ><quic_vpolimer@quicinc.com>; Abhinav Kumar (QUIC) ><quic_abhinavk@quicinc.com> >Subject: Re: [PATCH 4/4] drm/msm/disp/dpu1: add color management support >for the crtc > >WARNING: This email originated from outside of Qualcomm. Please be wary of >any links or attachments, and do not enable macros. > >On 09/11/2022 15:16, Kalyan Thota wrote: >> Add color management support for the crtc provided there are enough >> dspps that can be allocated from the catalogue >> >> Signed-off-by: Kalyan Thota <quic_kalyant@quicinc.com> >> --- >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 15 ++++++-- >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++++ >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 +++--- >> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53 >+++++++++++++++++++++++++++++ >> 4 files changed, 77 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> index 4170fbe..6bd3a64 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> @@ -18,9 +18,11 @@ >> #include <drm/drm_flip_work.h> >> #include <drm/drm_framebuffer.h> >> #include <drm/drm_mode.h> >> +#include <drm/drm_mode_object.h> >> #include <drm/drm_probe_helper.h> >> #include <drm/drm_rect.h> >> #include <drm/drm_vblank.h> >> +#include "../../../drm_crtc_internal.h" > >If it's internal, it is not supposed to be used by other parties, including the msm >drm. At least a comment why you are including this file would be helpful. > This header file was included to make use of " drm_mode_obj_find_prop_id" function from DRM framework. Should I add a comment near function definition ? >> >> #include "dpu_kms.h" >> #include "dpu_hw_lm.h" >> @@ -553,6 +555,17 @@ static void _dpu_crtc_complete_flip(struct drm_crtc >*crtc) >> spin_unlock_irqrestore(&dev->event_lock, flags); >> } >> >> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc) { >> + u32 ctm_id = crtc->dev->mode_config.ctm_property->base.id; >> + u32 gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id; >> + u32 degamma_id = >> +crtc->dev->mode_config.degamma_lut_property->base.id; >> + >> + return !!(drm_mode_obj_find_prop_id(&crtc->base, ctm_id) || >> + drm_mode_obj_find_prop_id(&crtc->base, gamma_id) || >> + drm_mode_obj_find_prop_id(&crtc->base, degamma_id)); >> +} >> + >> enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) >> { >> struct drm_encoder *encoder; >> @@ -1604,8 +1617,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device >> *dev, struct drm_plane *plane, >> >> drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); >> >> - drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >> - >> /* save user friendly CRTC name for later */ >> snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", >> crtc->base.id); >> >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> index 539b68b..8bac395 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> @@ -300,4 +300,10 @@ static inline enum dpu_crtc_client_type >dpu_crtc_get_client_type( >> return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT; >> } >> >> +/** >> + * dpu_crtc_has_color_enabled - check if the crtc has color >> +management enabled >> + * @crtc: Pointer to drm crtc object >> + */ >> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc); >> + >> #endif /* _DPU_CRTC_H_ */ >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> index 4c56a16..ebc3f25 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> @@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder >*drm_enc) >> 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_display_mode *mode, >> + struct drm_crtc *crtc) >> { >> struct msm_display_topology topology = {0}; >> int i, intf_count = 0; >> @@ -573,11 +574,9 @@ static struct msm_display_topology >dpu_encoder_get_topology( >> else >> topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) >> ? 2 : 1; >> >> - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { >> - if (dpu_kms->catalog->dspp && >> - (dpu_kms->catalog->dspp_count >= topology.num_lm)) >> + if (dpu_crtc_has_color_enabled(crtc) && >> + (dpu_kms->catalog->dspp_count >= topology.num_lm)) > >See the comment to the previous patch. It still applies here. > >> topology.num_dspp = topology.num_lm; >> - } >> >> topology.num_enc = 0; >> topology.num_intf = intf_count; >> @@ -643,7 +642,7 @@ static int dpu_encoder_virt_atomic_check( >> } >> } >> >> - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); >> + topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, >> + crtc_state->crtc); >> >> /* Reserve dynamic resources now. */ >> if (!ret) { >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> index 552a89c..47a73fa 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> @@ -13,6 +13,7 @@ >> #include <linux/dma-buf.h> >> #include <linux/of_irq.h> >> #include <linux/pm_opp.h> >> +#include <linux/bitops.h> >> >> #include <drm/drm_crtc.h> >> #include <drm/drm_file.h> >> @@ -537,6 +538,44 @@ static void dpu_kms_wait_flush(struct msm_kms >*kms, unsigned crtc_mask) >> dpu_kms_wait_for_commit_done(kms, crtc); >> } >> >> +/** >> + * _dpu_kms_possible_dspps - Evaluate how many dspps pairs can be >facilitated >> + to enable color features for crtcs. >> + * @dpu_kms: Pointer to dpu kms structure >> + * Returns: count of dspp pairs >> + * >> + * Baring single entry, if atleast 2 dspps are available in the >> +catalogue, >> + * then color can be enabled for that crtc */ static inline u32 >> +_dpu_kms_possible_dspps(struct dpu_kms *dpu_kms) { >> + >> + u32 num_dspps = dpu_kms->catalog->dspp_count; >> + >> + if (num_dspps > 1) >> + num_dspps = >> + !(num_dspps % 2) ? num_dspps / 2 : (num_dspps - >> + 1) / 2; > >Ugh. No. Please spell this clearly rather than using nice math and ternary >operators: > >if (num_dspps <= 1) > return num_dspps; >else > return num_dspps / 2; > >You see, if num_dspps %2 ! =0, then num_dspps / 2 == (num_dspps_2 - 1) / 2. > > >> + >> + return num_dspps; >> +} >> + >> +static u32 _dpu_kms_attach_color(struct drm_device *dev, u32 enc_mask, >> + u32 num_dspps) { >> + struct drm_encoder *encoder; >> + struct drm_crtc *crtc; >> + >> + drm_for_each_encoder_mask(encoder, dev, enc_mask) { >> + crtc = drm_crtc_from_index(dev, ffs(encoder->possible_crtcs) - 1); >> + if (num_dspps && crtc) { >> + drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >> + num_dspps--; > >Please. You can do this at the time you create the crtc. It would be much simpler. > >> + } >> + } >> + >> + return num_dspps; >> +} >> + >> static int _dpu_kms_initialize_dsi(struct drm_device *dev, >> struct msm_drm_private *priv, >> struct dpu_kms *dpu_kms) @@ -747,6 >> +786,8 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) >> >> int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; >> int max_crtc_count; >> + u32 num_dspps, primary_enc_mask = 0, external_enc_mask = 0; >> + >> dev = dpu_kms->dev; >> priv = dev->dev_private; >> catalog = dpu_kms->catalog; >> @@ -796,6 +837,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >*dpu_kms) >> } >> >> max_crtc_count = min(max_crtc_count, primary_planes_idx); >> + num_dspps = _dpu_kms_possible_dspps(dpu_kms); >> >> /* Create one CRTC per encoder */ >> encoder = list_first_entry(&(dev)->mode_config.encoder_list, >> @@ -808,9 +850,20 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >*dpu_kms) >> } >> priv->crtcs[priv->num_crtcs++] = crtc; >> encoder->possible_crtcs = 1 << drm_crtc_index(crtc); >> + >> + if (!dpu_encoder_is_external(encoder) && >> + !dpu_encoder_is_virtual(encoder)) > >if (dpu_encoder_internal_output(encoder)) > >> + primary_enc_mask |= drm_encoder_mask(encoder); >> + else if (dpu_encoder_is_external(encoder)) >> + external_enc_mask |= drm_encoder_mask(encoder); >> + >> encoder = list_next_entry(encoder, head); >> } >> >> + /* Prefer Primary encoders in registering for color support */ >> + num_dspps = _dpu_kms_attach_color(dev, primary_enc_mask, >num_dspps); >> + num_dspps = _dpu_kms_attach_color(dev, external_enc_mask, >> + num_dspps); >> + >> return 0; >> } >> > >-- >With best wishes >Dmitry
On 09/11/2022 15:39, Kalyan Thota wrote: > > >> -----Original Message----- >> From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> >> Sent: Wednesday, November 9, 2022 6:02 PM >> To: Kalyan Thota (QUIC) <quic_kalyant@quicinc.com>; dri- >> devel@lists.freedesktop.org; linux-arm-msm@vger.kernel.org; >> freedreno@lists.freedesktop.org; devicetree@vger.kernel.org >> Cc: linux-kernel@vger.kernel.org; robdclark@chromium.org; >> dianders@chromium.org; swboyd@chromium.org; Vinod Polimera (QUIC) >> <quic_vpolimer@quicinc.com>; Abhinav Kumar (QUIC) >> <quic_abhinavk@quicinc.com> >> Subject: Re: [PATCH 4/4] drm/msm/disp/dpu1: add color management support >> for the crtc >> >> WARNING: This email originated from outside of Qualcomm. Please be wary of >> any links or attachments, and do not enable macros. >> >> On 09/11/2022 15:16, Kalyan Thota wrote: >>> Add color management support for the crtc provided there are enough >>> dspps that can be allocated from the catalogue >>> >>> Signed-off-by: Kalyan Thota <quic_kalyant@quicinc.com> >>> --- >>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 15 ++++++-- >>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++++ >>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 +++--- >>> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53 >> +++++++++++++++++++++++++++++ >>> 4 files changed, 77 insertions(+), 8 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >>> index 4170fbe..6bd3a64 100644 >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >>> @@ -18,9 +18,11 @@ >>> #include <drm/drm_flip_work.h> >>> #include <drm/drm_framebuffer.h> >>> #include <drm/drm_mode.h> >>> +#include <drm/drm_mode_object.h> >>> #include <drm/drm_probe_helper.h> >>> #include <drm/drm_rect.h> >>> #include <drm/drm_vblank.h> >>> +#include "../../../drm_crtc_internal.h" >> >> If it's internal, it is not supposed to be used by other parties, including the msm >> drm. At least a comment why you are including this file would be helpful. >> > This header file was included to make use of " drm_mode_obj_find_prop_id" function from DRM framework. > Should I add a comment near function definition ? No, it would have been better to add a comment near the #include directive. However if this is the only user, you don't need it at all. You see, you know whether the CRTC has color management propreties at the time of creation. And this can not change. So, you just add a boolean to dpu_crtc (or dpu_crtc_state, whichever suits better). >>> >>> #include "dpu_kms.h" >>> #include "dpu_hw_lm.h" >>> @@ -553,6 +555,17 @@ static void _dpu_crtc_complete_flip(struct drm_crtc >> *crtc) >>> spin_unlock_irqrestore(&dev->event_lock, flags); >>> } >>> >>> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc) { >>> + u32 ctm_id = crtc->dev->mode_config.ctm_property->base.id; >>> + u32 gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id; >>> + u32 degamma_id = >>> +crtc->dev->mode_config.degamma_lut_property->base.id; >>> + >>> + return !!(drm_mode_obj_find_prop_id(&crtc->base, ctm_id) || >>> + drm_mode_obj_find_prop_id(&crtc->base, gamma_id) || >>> + drm_mode_obj_find_prop_id(&crtc->base, degamma_id)); >>> +} >>> + >>> enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) >>> { >>> struct drm_encoder *encoder; >>> @@ -1604,8 +1617,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device >>> *dev, struct drm_plane *plane, >>> >>> drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); >>> >>> - drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >>> - >>> /* save user friendly CRTC name for later */ >>> snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", >>> crtc->base.id); >>> >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >>> index 539b68b..8bac395 100644 >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >>> @@ -300,4 +300,10 @@ static inline enum dpu_crtc_client_type >> dpu_crtc_get_client_type( >>> return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT; >>> } >>> >>> +/** >>> + * dpu_crtc_has_color_enabled - check if the crtc has color >>> +management enabled >>> + * @crtc: Pointer to drm crtc object >>> + */ >>> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc); >>> + >>> #endif /* _DPU_CRTC_H_ */ >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >>> index 4c56a16..ebc3f25 100644 >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >>> @@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder >> *drm_enc) >>> 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_display_mode *mode, >>> + struct drm_crtc *crtc) >>> { >>> struct msm_display_topology topology = {0}; >>> int i, intf_count = 0; >>> @@ -573,11 +574,9 @@ static struct msm_display_topology >> dpu_encoder_get_topology( >>> else >>> topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) >>> ? 2 : 1; >>> >>> - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { >>> - if (dpu_kms->catalog->dspp && >>> - (dpu_kms->catalog->dspp_count >= topology.num_lm)) >>> + if (dpu_crtc_has_color_enabled(crtc) && >>> + (dpu_kms->catalog->dspp_count >= topology.num_lm)) >> >> See the comment to the previous patch. It still applies here. >> >>> topology.num_dspp = topology.num_lm; >>> - } >>> >>> topology.num_enc = 0; >>> topology.num_intf = intf_count; >>> @@ -643,7 +642,7 @@ static int dpu_encoder_virt_atomic_check( >>> } >>> } >>> >>> - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); >>> + topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, >>> + crtc_state->crtc); >>> >>> /* Reserve dynamic resources now. */ >>> if (!ret) { >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >>> index 552a89c..47a73fa 100644 >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >>> @@ -13,6 +13,7 @@ >>> #include <linux/dma-buf.h> >>> #include <linux/of_irq.h> >>> #include <linux/pm_opp.h> >>> +#include <linux/bitops.h> >>> >>> #include <drm/drm_crtc.h> >>> #include <drm/drm_file.h> >>> @@ -537,6 +538,44 @@ static void dpu_kms_wait_flush(struct msm_kms >> *kms, unsigned crtc_mask) >>> dpu_kms_wait_for_commit_done(kms, crtc); >>> } >>> >>> +/** >>> + * _dpu_kms_possible_dspps - Evaluate how many dspps pairs can be >> facilitated >>> + to enable color features for crtcs. >>> + * @dpu_kms: Pointer to dpu kms structure >>> + * Returns: count of dspp pairs >>> + * >>> + * Baring single entry, if atleast 2 dspps are available in the >>> +catalogue, >>> + * then color can be enabled for that crtc */ static inline u32 >>> +_dpu_kms_possible_dspps(struct dpu_kms *dpu_kms) { >>> + >>> + u32 num_dspps = dpu_kms->catalog->dspp_count; >>> + >>> + if (num_dspps > 1) >>> + num_dspps = >>> + !(num_dspps % 2) ? num_dspps / 2 : (num_dspps - >>> + 1) / 2; >> >> Ugh. No. Please spell this clearly rather than using nice math and ternary >> operators: >> >> if (num_dspps <= 1) >> return num_dspps; >> else >> return num_dspps / 2; >> >> You see, if num_dspps %2 ! =0, then num_dspps / 2 == (num_dspps_2 - 1) / 2. >> >> >>> + >>> + return num_dspps; >>> +} >>> + >>> +static u32 _dpu_kms_attach_color(struct drm_device *dev, u32 enc_mask, >>> + u32 num_dspps) { >>> + struct drm_encoder *encoder; >>> + struct drm_crtc *crtc; >>> + >>> + drm_for_each_encoder_mask(encoder, dev, enc_mask) { >>> + crtc = drm_crtc_from_index(dev, ffs(encoder->possible_crtcs) - 1); >>> + if (num_dspps && crtc) { >>> + drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >>> + num_dspps--; >> >> Please. You can do this at the time you create the crtc. It would be much simpler. >> >>> + } >>> + } >>> + >>> + return num_dspps; >>> +} >>> + >>> static int _dpu_kms_initialize_dsi(struct drm_device *dev, >>> struct msm_drm_private *priv, >>> struct dpu_kms *dpu_kms) @@ -747,6 >>> +786,8 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) >>> >>> int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; >>> int max_crtc_count; >>> + u32 num_dspps, primary_enc_mask = 0, external_enc_mask = 0; >>> + >>> dev = dpu_kms->dev; >>> priv = dev->dev_private; >>> catalog = dpu_kms->catalog; >>> @@ -796,6 +837,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >> *dpu_kms) >>> } >>> >>> max_crtc_count = min(max_crtc_count, primary_planes_idx); >>> + num_dspps = _dpu_kms_possible_dspps(dpu_kms); >>> >>> /* Create one CRTC per encoder */ >>> encoder = list_first_entry(&(dev)->mode_config.encoder_list, >>> @@ -808,9 +850,20 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >> *dpu_kms) >>> } >>> priv->crtcs[priv->num_crtcs++] = crtc; >>> encoder->possible_crtcs = 1 << drm_crtc_index(crtc); >>> + >>> + if (!dpu_encoder_is_external(encoder) && >>> + !dpu_encoder_is_virtual(encoder)) >> >> if (dpu_encoder_internal_output(encoder)) >> >>> + primary_enc_mask |= drm_encoder_mask(encoder); >>> + else if (dpu_encoder_is_external(encoder)) >>> + external_enc_mask |= drm_encoder_mask(encoder); >>> + >>> encoder = list_next_entry(encoder, head); >>> } >>> >>> + /* Prefer Primary encoders in registering for color support */ >>> + num_dspps = _dpu_kms_attach_color(dev, primary_enc_mask, >> num_dspps); >>> + num_dspps = _dpu_kms_attach_color(dev, external_enc_mask, >>> + num_dspps); >>> + >>> return 0; >>> } >>> >> >> -- >> With best wishes >> Dmitry >
>-----Original Message----- >From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> >Sent: Wednesday, November 9, 2022 6:02 PM >To: Kalyan Thota (QUIC) <quic_kalyant@quicinc.com>; dri- >devel@lists.freedesktop.org; linux-arm-msm@vger.kernel.org; >freedreno@lists.freedesktop.org; devicetree@vger.kernel.org >Cc: linux-kernel@vger.kernel.org; robdclark@chromium.org; >dianders@chromium.org; swboyd@chromium.org; Vinod Polimera (QUIC) ><quic_vpolimer@quicinc.com>; Abhinav Kumar (QUIC) ><quic_abhinavk@quicinc.com> >Subject: Re: [PATCH 4/4] drm/msm/disp/dpu1: add color management support >for the crtc > >WARNING: This email originated from outside of Qualcomm. Please be wary of >any links or attachments, and do not enable macros. > >On 09/11/2022 15:16, Kalyan Thota wrote: >> Add color management support for the crtc provided there are enough >> dspps that can be allocated from the catalogue >> >> Signed-off-by: Kalyan Thota <quic_kalyant@quicinc.com> >> --- >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 15 ++++++-- >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++++ >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 +++--- >> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53 >+++++++++++++++++++++++++++++ >> 4 files changed, 77 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> index 4170fbe..6bd3a64 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> @@ -18,9 +18,11 @@ >> #include <drm/drm_flip_work.h> >> #include <drm/drm_framebuffer.h> >> #include <drm/drm_mode.h> >> +#include <drm/drm_mode_object.h> >> #include <drm/drm_probe_helper.h> >> #include <drm/drm_rect.h> >> #include <drm/drm_vblank.h> >> +#include "../../../drm_crtc_internal.h" > >If it's internal, it is not supposed to be used by other parties, including the msm >drm. At least a comment why you are including this file would be helpful. > >> >> #include "dpu_kms.h" >> #include "dpu_hw_lm.h" >> @@ -553,6 +555,17 @@ static void _dpu_crtc_complete_flip(struct drm_crtc >*crtc) >> spin_unlock_irqrestore(&dev->event_lock, flags); >> } >> >> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc) { >> + u32 ctm_id = crtc->dev->mode_config.ctm_property->base.id; >> + u32 gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id; >> + u32 degamma_id = >> +crtc->dev->mode_config.degamma_lut_property->base.id; >> + >> + return !!(drm_mode_obj_find_prop_id(&crtc->base, ctm_id) || >> + drm_mode_obj_find_prop_id(&crtc->base, gamma_id) || >> + drm_mode_obj_find_prop_id(&crtc->base, degamma_id)); >> +} >> + >> enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) >> { >> struct drm_encoder *encoder; >> @@ -1604,8 +1617,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device >> *dev, struct drm_plane *plane, >> >> drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); >> >> - drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >> - >> /* save user friendly CRTC name for later */ >> snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", >> crtc->base.id); >> >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> index 539b68b..8bac395 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> @@ -300,4 +300,10 @@ static inline enum dpu_crtc_client_type >dpu_crtc_get_client_type( >> return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT; >> } >> >> +/** >> + * dpu_crtc_has_color_enabled - check if the crtc has color >> +management enabled >> + * @crtc: Pointer to drm crtc object >> + */ >> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc); >> + >> #endif /* _DPU_CRTC_H_ */ >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> index 4c56a16..ebc3f25 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> @@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder >*drm_enc) >> 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_display_mode *mode, >> + struct drm_crtc *crtc) >> { >> struct msm_display_topology topology = {0}; >> int i, intf_count = 0; >> @@ -573,11 +574,9 @@ static struct msm_display_topology >dpu_encoder_get_topology( >> else >> topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) >> ? 2 : 1; >> >> - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { >> - if (dpu_kms->catalog->dspp && >> - (dpu_kms->catalog->dspp_count >= topology.num_lm)) >> + if (dpu_crtc_has_color_enabled(crtc) && >> + (dpu_kms->catalog->dspp_count >= topology.num_lm)) > >See the comment to the previous patch. It still applies here. > >> topology.num_dspp = topology.num_lm; >> - } >> >> topology.num_enc = 0; >> topology.num_intf = intf_count; >> @@ -643,7 +642,7 @@ static int dpu_encoder_virt_atomic_check( >> } >> } >> >> - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); >> + topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, >> + crtc_state->crtc); >> >> /* Reserve dynamic resources now. */ >> if (!ret) { >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> index 552a89c..47a73fa 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> @@ -13,6 +13,7 @@ >> #include <linux/dma-buf.h> >> #include <linux/of_irq.h> >> #include <linux/pm_opp.h> >> +#include <linux/bitops.h> >> >> #include <drm/drm_crtc.h> >> #include <drm/drm_file.h> >> @@ -537,6 +538,44 @@ static void dpu_kms_wait_flush(struct msm_kms >*kms, unsigned crtc_mask) >> dpu_kms_wait_for_commit_done(kms, crtc); >> } >> >> +/** >> + * _dpu_kms_possible_dspps - Evaluate how many dspps pairs can be >facilitated >> + to enable color features for crtcs. >> + * @dpu_kms: Pointer to dpu kms structure >> + * Returns: count of dspp pairs >> + * >> + * Baring single entry, if atleast 2 dspps are available in the >> +catalogue, >> + * then color can be enabled for that crtc */ static inline u32 >> +_dpu_kms_possible_dspps(struct dpu_kms *dpu_kms) { >> + >> + u32 num_dspps = dpu_kms->catalog->dspp_count; >> + >> + if (num_dspps > 1) >> + num_dspps = >> + !(num_dspps % 2) ? num_dspps / 2 : (num_dspps - >> + 1) / 2; > >Ugh. No. Please spell this clearly rather than using nice math and ternary >operators: > >if (num_dspps <= 1) > return num_dspps; >else > return num_dspps / 2; > >You see, if num_dspps %2 ! =0, then num_dspps / 2 == (num_dspps_2 - 1) / 2. > > >> + >> + return num_dspps; >> +} >> + >> +static u32 _dpu_kms_attach_color(struct drm_device *dev, u32 enc_mask, >> + u32 num_dspps) { >> + struct drm_encoder *encoder; >> + struct drm_crtc *crtc; >> + >> + drm_for_each_encoder_mask(encoder, dev, enc_mask) { >> + crtc = drm_crtc_from_index(dev, ffs(encoder->possible_crtcs) - 1); >> + if (num_dspps && crtc) { >> + drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >> + num_dspps--; > >Please. You can do this at the time you create the crtc. It would be much simpler. > Following are the cases that I have considered. 1) DP can be first among the encoder list 2) we can have more than 1 primary display. Since encoder list operation is iterative, we cannot go back and set the color, if we end up having unused dspp's Secondly, it will be a bit complex logic to save the dspps for primary assuming DSI/eDP will be later in the list, and comeback to assign to DP as well if there are enough dspps (run through the loop twice) I have used 2 encoder masks for primary and external. And i have preferred all the primary displays to get a first allocation and then move to external. Let me know if your thoughts. >> + } >> + } >> + >> + return num_dspps; >> +} >> + >> static int _dpu_kms_initialize_dsi(struct drm_device *dev, >> struct msm_drm_private *priv, >> struct dpu_kms *dpu_kms) @@ -747,6 >> +786,8 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) >> >> int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; >> int max_crtc_count; >> + u32 num_dspps, primary_enc_mask = 0, external_enc_mask = 0; >> + >> dev = dpu_kms->dev; >> priv = dev->dev_private; >> catalog = dpu_kms->catalog; >> @@ -796,6 +837,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >*dpu_kms) >> } >> >> max_crtc_count = min(max_crtc_count, primary_planes_idx); >> + num_dspps = _dpu_kms_possible_dspps(dpu_kms); >> >> /* Create one CRTC per encoder */ >> encoder = list_first_entry(&(dev)->mode_config.encoder_list, >> @@ -808,9 +850,20 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >*dpu_kms) >> } >> priv->crtcs[priv->num_crtcs++] = crtc; >> encoder->possible_crtcs = 1 << drm_crtc_index(crtc); >> + >> + if (!dpu_encoder_is_external(encoder) && >> + !dpu_encoder_is_virtual(encoder)) > >if (dpu_encoder_internal_output(encoder)) > >> + primary_enc_mask |= drm_encoder_mask(encoder); >> + else if (dpu_encoder_is_external(encoder)) >> + external_enc_mask |= drm_encoder_mask(encoder); >> + >> encoder = list_next_entry(encoder, head); >> } >> >> + /* Prefer Primary encoders in registering for color support */ >> + num_dspps = _dpu_kms_attach_color(dev, primary_enc_mask, >num_dspps); >> + num_dspps = _dpu_kms_attach_color(dev, external_enc_mask, >> + num_dspps); >> + >> return 0; >> } >> > >-- >With best wishes >Dmitry
>-----Original Message----- >From: Kalyan Thota <kalyant@qti.qualcomm.com> >Sent: Wednesday, November 9, 2022 6:53 PM >To: dmitry.baryshkov@linaro.org; Kalyan Thota (QUIC) ><quic_kalyant@quicinc.com>; dri-devel@lists.freedesktop.org; linux-arm- >msm@vger.kernel.org; freedreno@lists.freedesktop.org; >devicetree@vger.kernel.org >Cc: linux-kernel@vger.kernel.org; robdclark@chromium.org; >dianders@chromium.org; swboyd@chromium.org; Vinod Polimera (QUIC) ><quic_vpolimer@quicinc.com>; Abhinav Kumar (QUIC) ><quic_abhinavk@quicinc.com> >Subject: RE: [PATCH 4/4] drm/msm/disp/dpu1: add color management support >for the crtc > > > >>-----Original Message----- >>From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> >>Sent: Wednesday, November 9, 2022 6:02 PM >>To: Kalyan Thota (QUIC) <quic_kalyant@quicinc.com>; dri- >>devel@lists.freedesktop.org; linux-arm-msm@vger.kernel.org; >>freedreno@lists.freedesktop.org; devicetree@vger.kernel.org >>Cc: linux-kernel@vger.kernel.org; robdclark@chromium.org; >>dianders@chromium.org; swboyd@chromium.org; Vinod Polimera (QUIC) >><quic_vpolimer@quicinc.com>; Abhinav Kumar (QUIC) >><quic_abhinavk@quicinc.com> >>Subject: Re: [PATCH 4/4] drm/msm/disp/dpu1: add color management >>support for the crtc >> >>WARNING: This email originated from outside of Qualcomm. Please be wary >>of any links or attachments, and do not enable macros. >> >>On 09/11/2022 15:16, Kalyan Thota wrote: >>> Add color management support for the crtc provided there are enough >>> dspps that can be allocated from the catalogue >>> >>> Signed-off-by: Kalyan Thota <quic_kalyant@quicinc.com> >>> --- >>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 15 ++++++-- >>> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++++ >>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 +++--- >>> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53 >>+++++++++++++++++++++++++++++ >>> 4 files changed, 77 insertions(+), 8 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >>> index 4170fbe..6bd3a64 100644 >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >>> @@ -18,9 +18,11 @@ >>> #include <drm/drm_flip_work.h> >>> #include <drm/drm_framebuffer.h> >>> #include <drm/drm_mode.h> >>> +#include <drm/drm_mode_object.h> >>> #include <drm/drm_probe_helper.h> >>> #include <drm/drm_rect.h> >>> #include <drm/drm_vblank.h> >>> +#include "../../../drm_crtc_internal.h" >> >>If it's internal, it is not supposed to be used by other parties, >>including the msm drm. At least a comment why you are including this file would >be helpful. >> >>> >>> #include "dpu_kms.h" >>> #include "dpu_hw_lm.h" >>> @@ -553,6 +555,17 @@ static void _dpu_crtc_complete_flip(struct >>> drm_crtc >>*crtc) >>> spin_unlock_irqrestore(&dev->event_lock, flags); >>> } >>> >>> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc) { >>> + u32 ctm_id = crtc->dev->mode_config.ctm_property->base.id; >>> + u32 gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id; >>> + u32 degamma_id = >>> +crtc->dev->mode_config.degamma_lut_property->base.id; >>> + >>> + return !!(drm_mode_obj_find_prop_id(&crtc->base, ctm_id) || >>> + drm_mode_obj_find_prop_id(&crtc->base, gamma_id) || >>> + drm_mode_obj_find_prop_id(&crtc->base, degamma_id)); >>> +} >>> + >>> enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) >>> { >>> struct drm_encoder *encoder; >>> @@ -1604,8 +1617,6 @@ struct drm_crtc *dpu_crtc_init(struct >>> drm_device *dev, struct drm_plane *plane, >>> >>> drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); >>> >>> - drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >>> - >>> /* save user friendly CRTC name for later */ >>> snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", >>> crtc->base.id); >>> >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >>> index 539b68b..8bac395 100644 >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >>> @@ -300,4 +300,10 @@ static inline enum dpu_crtc_client_type >>dpu_crtc_get_client_type( >>> return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT; >>> } >>> >>> +/** >>> + * dpu_crtc_has_color_enabled - check if the crtc has color >>> +management enabled >>> + * @crtc: Pointer to drm crtc object */ bool >>> +dpu_crtc_has_color_enabled(struct drm_crtc *crtc); >>> + >>> #endif /* _DPU_CRTC_H_ */ >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >>> index 4c56a16..ebc3f25 100644 >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >>> @@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct >drm_encoder >>*drm_enc) >>> 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_display_mode *mode, >>> + struct drm_crtc *crtc) >>> { >>> struct msm_display_topology topology = {0}; >>> int i, intf_count = 0; >>> @@ -573,11 +574,9 @@ static struct msm_display_topology >>dpu_encoder_get_topology( >>> else >>> topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) >>> ? 2 : 1; >>> >>> - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { >>> - if (dpu_kms->catalog->dspp && >>> - (dpu_kms->catalog->dspp_count >= topology.num_lm)) >>> + if (dpu_crtc_has_color_enabled(crtc) && >>> + (dpu_kms->catalog->dspp_count >= topology.num_lm)) >> >>See the comment to the previous patch. It still applies here. >> >>> topology.num_dspp = topology.num_lm; >>> - } >>> >>> topology.num_enc = 0; >>> topology.num_intf = intf_count; @@ -643,7 +642,7 @@ static int >>> dpu_encoder_virt_atomic_check( >>> } >>> } >>> >>> - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); >>> + topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, >>> + crtc_state->crtc); >>> >>> /* Reserve dynamic resources now. */ >>> if (!ret) { >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >>> index 552a89c..47a73fa 100644 >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >>> @@ -13,6 +13,7 @@ >>> #include <linux/dma-buf.h> >>> #include <linux/of_irq.h> >>> #include <linux/pm_opp.h> >>> +#include <linux/bitops.h> >>> >>> #include <drm/drm_crtc.h> >>> #include <drm/drm_file.h> >>> @@ -537,6 +538,44 @@ static void dpu_kms_wait_flush(struct msm_kms >>*kms, unsigned crtc_mask) >>> dpu_kms_wait_for_commit_done(kms, crtc); >>> } >>> >>> +/** >>> + * _dpu_kms_possible_dspps - Evaluate how many dspps pairs can be >>facilitated >>> + to enable color features for crtcs. >>> + * @dpu_kms: Pointer to dpu kms structure >>> + * Returns: count of dspp pairs >>> + * >>> + * Baring single entry, if atleast 2 dspps are available in the >>> +catalogue, >>> + * then color can be enabled for that crtc */ static inline u32 >>> +_dpu_kms_possible_dspps(struct dpu_kms *dpu_kms) { >>> + >>> + u32 num_dspps = dpu_kms->catalog->dspp_count; >>> + >>> + if (num_dspps > 1) >>> + num_dspps = >>> + !(num_dspps % 2) ? num_dspps / 2 : (num_dspps - >>> + 1) / 2; >> >>Ugh. No. Please spell this clearly rather than using nice math and >>ternary >>operators: >> >>if (num_dspps <= 1) >> return num_dspps; >>else >> return num_dspps / 2; >> >>You see, if num_dspps %2 ! =0, then num_dspps / 2 == (num_dspps_2 - 1) / 2. >> >> >>> + >>> + return num_dspps; >>> +} >>> + >>> +static u32 _dpu_kms_attach_color(struct drm_device *dev, u32 enc_mask, >>> + u32 num_dspps) { >>> + struct drm_encoder *encoder; >>> + struct drm_crtc *crtc; >>> + >>> + drm_for_each_encoder_mask(encoder, dev, enc_mask) { >>> + crtc = drm_crtc_from_index(dev, ffs(encoder->possible_crtcs) - 1); >>> + if (num_dspps && crtc) { >>> + drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >>> + num_dspps--; >> >>Please. You can do this at the time you create the crtc. It would be much >simpler. >> >Following are the cases that I have considered. >1) DP can be first among the encoder list >2) we can have more than 1 primary display. > >Since encoder list operation is iterative, we cannot go back and set the color, if >we end up having unused dspp's Secondly, it will be a bit complex logic to save >the dspps for primary assuming DSI/eDP will be later in the list, and comeback to >assign to DP as well if there are enough dspps (run through the loop twice) > >I have used 2 encoder masks for primary and external. And i have preferred all the >primary displays to get a first allocation and then move to external. > >Let me know if your thoughts. > On second thought, with the addition of connector_type, logic can be simplified, let me add those changes > >>> + } >>> + } >>> + >>> + return num_dspps; >>> +} >>> + >>> static int _dpu_kms_initialize_dsi(struct drm_device *dev, >>> struct msm_drm_private *priv, >>> struct dpu_kms *dpu_kms) @@ -747,6 >>> +786,8 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) >>> >>> int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; >>> int max_crtc_count; >>> + u32 num_dspps, primary_enc_mask = 0, external_enc_mask = 0; >>> + >>> dev = dpu_kms->dev; >>> priv = dev->dev_private; >>> catalog = dpu_kms->catalog; >>> @@ -796,6 +837,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >>*dpu_kms) >>> } >>> >>> max_crtc_count = min(max_crtc_count, primary_planes_idx); >>> + num_dspps = _dpu_kms_possible_dspps(dpu_kms); >>> >>> /* Create one CRTC per encoder */ >>> encoder = list_first_entry(&(dev)->mode_config.encoder_list, >>> @@ -808,9 +850,20 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >>*dpu_kms) >>> } >>> priv->crtcs[priv->num_crtcs++] = crtc; >>> encoder->possible_crtcs = 1 << drm_crtc_index(crtc); >>> + >>> + if (!dpu_encoder_is_external(encoder) && >>> + !dpu_encoder_is_virtual(encoder)) >> >>if (dpu_encoder_internal_output(encoder)) >> >>> + primary_enc_mask |= drm_encoder_mask(encoder); >>> + else if (dpu_encoder_is_external(encoder)) >>> + external_enc_mask |= drm_encoder_mask(encoder); >>> + >>> encoder = list_next_entry(encoder, head); >>> } >>> >>> + /* Prefer Primary encoders in registering for color support */ >>> + num_dspps = _dpu_kms_attach_color(dev, primary_enc_mask, >>num_dspps); >>> + num_dspps = _dpu_kms_attach_color(dev, external_enc_mask, >>> + num_dspps); >>> + >>> return 0; >>> } >>> >> >>-- >>With best wishes >>Dmitry >
>-----Original Message----- >From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> >Sent: Wednesday, November 9, 2022 6:02 PM >To: Kalyan Thota (QUIC) <quic_kalyant@quicinc.com>; dri- >devel@lists.freedesktop.org; linux-arm-msm@vger.kernel.org; >freedreno@lists.freedesktop.org; devicetree@vger.kernel.org >Cc: linux-kernel@vger.kernel.org; robdclark@chromium.org; >dianders@chromium.org; swboyd@chromium.org; Vinod Polimera (QUIC) ><quic_vpolimer@quicinc.com>; Abhinav Kumar (QUIC) ><quic_abhinavk@quicinc.com> >Subject: Re: [PATCH 4/4] drm/msm/disp/dpu1: add color management support >for the crtc > >WARNING: This email originated from outside of Qualcomm. Please be wary of >any links or attachments, and do not enable macros. > >On 09/11/2022 15:16, Kalyan Thota wrote: >> Add color management support for the crtc provided there are enough >> dspps that can be allocated from the catalogue >> >> Signed-off-by: Kalyan Thota <quic_kalyant@quicinc.com> >> --- >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 15 ++++++-- >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ++++ >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 +++--- >> drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 53 >+++++++++++++++++++++++++++++ >> 4 files changed, 77 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> index 4170fbe..6bd3a64 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c >> @@ -18,9 +18,11 @@ >> #include <drm/drm_flip_work.h> >> #include <drm/drm_framebuffer.h> >> #include <drm/drm_mode.h> >> +#include <drm/drm_mode_object.h> >> #include <drm/drm_probe_helper.h> >> #include <drm/drm_rect.h> >> #include <drm/drm_vblank.h> >> +#include "../../../drm_crtc_internal.h" > >If it's internal, it is not supposed to be used by other parties, including the msm >drm. At least a comment why you are including this file would be helpful. > >> >> #include "dpu_kms.h" >> #include "dpu_hw_lm.h" >> @@ -553,6 +555,17 @@ static void _dpu_crtc_complete_flip(struct drm_crtc >*crtc) >> spin_unlock_irqrestore(&dev->event_lock, flags); >> } >> >> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc) { >> + u32 ctm_id = crtc->dev->mode_config.ctm_property->base.id; >> + u32 gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id; >> + u32 degamma_id = >> +crtc->dev->mode_config.degamma_lut_property->base.id; >> + >> + return !!(drm_mode_obj_find_prop_id(&crtc->base, ctm_id) || >> + drm_mode_obj_find_prop_id(&crtc->base, gamma_id) || >> + drm_mode_obj_find_prop_id(&crtc->base, degamma_id)); >> +} >> + >> enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) >> { >> struct drm_encoder *encoder; >> @@ -1604,8 +1617,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device >> *dev, struct drm_plane *plane, >> >> drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); >> >> - drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >> - >> /* save user friendly CRTC name for later */ >> snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", >> crtc->base.id); >> >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> index 539b68b..8bac395 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h >> @@ -300,4 +300,10 @@ static inline enum dpu_crtc_client_type >dpu_crtc_get_client_type( >> return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT; >> } >> >> +/** >> + * dpu_crtc_has_color_enabled - check if the crtc has color >> +management enabled >> + * @crtc: Pointer to drm crtc object >> + */ >> +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc); >> + >> #endif /* _DPU_CRTC_H_ */ >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> index 4c56a16..ebc3f25 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c >> @@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder >*drm_enc) >> 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_display_mode *mode, >> + struct drm_crtc *crtc) >> { >> struct msm_display_topology topology = {0}; >> int i, intf_count = 0; >> @@ -573,11 +574,9 @@ static struct msm_display_topology >dpu_encoder_get_topology( >> else >> topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) >> ? 2 : 1; >> >> - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { >> - if (dpu_kms->catalog->dspp && >> - (dpu_kms->catalog->dspp_count >= topology.num_lm)) >> + if (dpu_crtc_has_color_enabled(crtc) && >> + (dpu_kms->catalog->dspp_count >= topology.num_lm)) > >See the comment to the previous patch. It still applies here. > This function will only populate the requirements for a given topology based on mode. If there are not enough resources as per requirements, dpu_rm_reserve will fail the modeset. >> topology.num_dspp = topology.num_lm; >> - } >> >> topology.num_enc = 0; >> topology.num_intf = intf_count; >> @@ -643,7 +642,7 @@ static int dpu_encoder_virt_atomic_check( >> } >> } >> >> - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); >> + topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, >> + crtc_state->crtc); >> >> /* Reserve dynamic resources now. */ >> if (!ret) { >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> index 552a89c..47a73fa 100644 >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c >> @@ -13,6 +13,7 @@ >> #include <linux/dma-buf.h> >> #include <linux/of_irq.h> >> #include <linux/pm_opp.h> >> +#include <linux/bitops.h> >> >> #include <drm/drm_crtc.h> >> #include <drm/drm_file.h> >> @@ -537,6 +538,44 @@ static void dpu_kms_wait_flush(struct msm_kms >*kms, unsigned crtc_mask) >> dpu_kms_wait_for_commit_done(kms, crtc); >> } >> >> +/** >> + * _dpu_kms_possible_dspps - Evaluate how many dspps pairs can be >facilitated >> + to enable color features for crtcs. >> + * @dpu_kms: Pointer to dpu kms structure >> + * Returns: count of dspp pairs >> + * >> + * Baring single entry, if atleast 2 dspps are available in the >> +catalogue, >> + * then color can be enabled for that crtc */ static inline u32 >> +_dpu_kms_possible_dspps(struct dpu_kms *dpu_kms) { >> + >> + u32 num_dspps = dpu_kms->catalog->dspp_count; >> + >> + if (num_dspps > 1) >> + num_dspps = >> + !(num_dspps % 2) ? num_dspps / 2 : (num_dspps - >> + 1) / 2; > >Ugh. No. Please spell this clearly rather than using nice math and ternary >operators: > >if (num_dspps <= 1) > return num_dspps; >else > return num_dspps / 2; > >You see, if num_dspps %2 ! =0, then num_dspps / 2 == (num_dspps_2 - 1) / 2. > > >> + >> + return num_dspps; >> +} >> + >> +static u32 _dpu_kms_attach_color(struct drm_device *dev, u32 enc_mask, >> + u32 num_dspps) { >> + struct drm_encoder *encoder; >> + struct drm_crtc *crtc; >> + >> + drm_for_each_encoder_mask(encoder, dev, enc_mask) { >> + crtc = drm_crtc_from_index(dev, ffs(encoder->possible_crtcs) - 1); >> + if (num_dspps && crtc) { >> + drm_crtc_enable_color_mgmt(crtc, 0, true, 0); >> + num_dspps--; > >Please. You can do this at the time you create the crtc. It would be much simpler. > >> + } >> + } >> + >> + return num_dspps; >> +} >> + >> static int _dpu_kms_initialize_dsi(struct drm_device *dev, >> struct msm_drm_private *priv, >> struct dpu_kms *dpu_kms) @@ -747,6 >> +786,8 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) >> >> int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; >> int max_crtc_count; >> + u32 num_dspps, primary_enc_mask = 0, external_enc_mask = 0; >> + >> dev = dpu_kms->dev; >> priv = dev->dev_private; >> catalog = dpu_kms->catalog; >> @@ -796,6 +837,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >*dpu_kms) >> } >> >> max_crtc_count = min(max_crtc_count, primary_planes_idx); >> + num_dspps = _dpu_kms_possible_dspps(dpu_kms); >> >> /* Create one CRTC per encoder */ >> encoder = list_first_entry(&(dev)->mode_config.encoder_list, >> @@ -808,9 +850,20 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms >*dpu_kms) >> } >> priv->crtcs[priv->num_crtcs++] = crtc; >> encoder->possible_crtcs = 1 << drm_crtc_index(crtc); >> + >> + if (!dpu_encoder_is_external(encoder) && >> + !dpu_encoder_is_virtual(encoder)) > >if (dpu_encoder_internal_output(encoder)) > >> + primary_enc_mask |= drm_encoder_mask(encoder); >> + else if (dpu_encoder_is_external(encoder)) >> + external_enc_mask |= drm_encoder_mask(encoder); >> + >> encoder = list_next_entry(encoder, head); >> } >> >> + /* Prefer Primary encoders in registering for color support */ >> + num_dspps = _dpu_kms_attach_color(dev, primary_enc_mask, >num_dspps); >> + num_dspps = _dpu_kms_attach_color(dev, external_enc_mask, >> + num_dspps); >> + >> return 0; >> } >> > >-- >With best wishes >Dmitry
Hi Kalyan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on drm/drm-next drm-exynos/exynos-drm-next drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip linus/master v6.1-rc4 next-20221111]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Kalyan-Thota/drm-msm-disp-dpu1-pin-1-crtc-to-1-encoder/20221109-201925
base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link: https://lore.kernel.org/r/1667996206-4153-4-git-send-email-quic_kalyant%40quicinc.com
patch subject: [PATCH 4/4] drm/msm/disp/dpu1: add color management support for the crtc
config: arc-buildonly-randconfig-r005-20221111
compiler: arceb-elf-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/e3a68199ddde8a052bc837e4a7cdaed7278c5528
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Kalyan-Thota/drm-msm-disp-dpu1-pin-1-crtc-to-1-encoder/20221109-201925
git checkout e3a68199ddde8a052bc837e4a7cdaed7278c5528
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>, old ones prefixed by <<):
>> ERROR: modpost: "drm_mode_obj_find_prop_id" [drivers/gpu/drm/msm/msm.ko] undefined!
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 4170fbe..6bd3a64 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -18,9 +18,11 @@ #include <drm/drm_flip_work.h> #include <drm/drm_framebuffer.h> #include <drm/drm_mode.h> +#include <drm/drm_mode_object.h> #include <drm/drm_probe_helper.h> #include <drm/drm_rect.h> #include <drm/drm_vblank.h> +#include "../../../drm_crtc_internal.h" #include "dpu_kms.h" #include "dpu_hw_lm.h" @@ -553,6 +555,17 @@ static void _dpu_crtc_complete_flip(struct drm_crtc *crtc) spin_unlock_irqrestore(&dev->event_lock, flags); } +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc) +{ + u32 ctm_id = crtc->dev->mode_config.ctm_property->base.id; + u32 gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id; + u32 degamma_id = crtc->dev->mode_config.degamma_lut_property->base.id; + + return !!(drm_mode_obj_find_prop_id(&crtc->base, ctm_id) || + drm_mode_obj_find_prop_id(&crtc->base, gamma_id) || + drm_mode_obj_find_prop_id(&crtc->base, degamma_id)); +} + enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) { struct drm_encoder *encoder; @@ -1604,8 +1617,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); - drm_crtc_enable_color_mgmt(crtc, 0, true, 0); - /* save user friendly CRTC name for later */ snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 539b68b..8bac395 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -300,4 +300,10 @@ static inline enum dpu_crtc_client_type dpu_crtc_get_client_type( return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT; } +/** + * dpu_crtc_has_color_enabled - check if the crtc has color management enabled + * @crtc: Pointer to drm crtc object + */ +bool dpu_crtc_has_color_enabled(struct drm_crtc *crtc); + #endif /* _DPU_CRTC_H_ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 4c56a16..ebc3f25 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) 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_display_mode *mode, + struct drm_crtc *crtc) { struct msm_display_topology topology = {0}; int i, intf_count = 0; @@ -573,11 +574,9 @@ static struct msm_display_topology dpu_encoder_get_topology( else topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { - if (dpu_kms->catalog->dspp && - (dpu_kms->catalog->dspp_count >= topology.num_lm)) + if (dpu_crtc_has_color_enabled(crtc) && + (dpu_kms->catalog->dspp_count >= topology.num_lm)) topology.num_dspp = topology.num_lm; - } topology.num_enc = 0; topology.num_intf = intf_count; @@ -643,7 +642,7 @@ static int dpu_encoder_virt_atomic_check( } } - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); + topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state->crtc); /* Reserve dynamic resources now. */ if (!ret) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 552a89c..47a73fa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -13,6 +13,7 @@ #include <linux/dma-buf.h> #include <linux/of_irq.h> #include <linux/pm_opp.h> +#include <linux/bitops.h> #include <drm/drm_crtc.h> #include <drm/drm_file.h> @@ -537,6 +538,44 @@ static void dpu_kms_wait_flush(struct msm_kms *kms, unsigned crtc_mask) dpu_kms_wait_for_commit_done(kms, crtc); } +/** + * _dpu_kms_possible_dspps - Evaluate how many dspps pairs can be facilitated + to enable color features for crtcs. + * @dpu_kms: Pointer to dpu kms structure + * Returns: count of dspp pairs + * + * Baring single entry, if atleast 2 dspps are available in the catalogue, + * then color can be enabled for that crtc + */ +static inline u32 _dpu_kms_possible_dspps(struct dpu_kms *dpu_kms) +{ + + u32 num_dspps = dpu_kms->catalog->dspp_count; + + if (num_dspps > 1) + num_dspps = + !(num_dspps % 2) ? num_dspps / 2 : (num_dspps - 1) / 2; + + return num_dspps; +} + +static u32 _dpu_kms_attach_color(struct drm_device *dev, u32 enc_mask, + u32 num_dspps) +{ + struct drm_encoder *encoder; + struct drm_crtc *crtc; + + drm_for_each_encoder_mask(encoder, dev, enc_mask) { + crtc = drm_crtc_from_index(dev, ffs(encoder->possible_crtcs) - 1); + if (num_dspps && crtc) { + drm_crtc_enable_color_mgmt(crtc, 0, true, 0); + num_dspps--; + } + } + + return num_dspps; +} + static int _dpu_kms_initialize_dsi(struct drm_device *dev, struct msm_drm_private *priv, struct dpu_kms *dpu_kms) @@ -747,6 +786,8 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; int max_crtc_count; + u32 num_dspps, primary_enc_mask = 0, external_enc_mask = 0; + dev = dpu_kms->dev; priv = dev->dev_private; catalog = dpu_kms->catalog; @@ -796,6 +837,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) } max_crtc_count = min(max_crtc_count, primary_planes_idx); + num_dspps = _dpu_kms_possible_dspps(dpu_kms); /* Create one CRTC per encoder */ encoder = list_first_entry(&(dev)->mode_config.encoder_list, @@ -808,9 +850,20 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) } priv->crtcs[priv->num_crtcs++] = crtc; encoder->possible_crtcs = 1 << drm_crtc_index(crtc); + + if (!dpu_encoder_is_external(encoder) && + !dpu_encoder_is_virtual(encoder)) + primary_enc_mask |= drm_encoder_mask(encoder); + else if (dpu_encoder_is_external(encoder)) + external_enc_mask |= drm_encoder_mask(encoder); + encoder = list_next_entry(encoder, head); } + /* Prefer Primary encoders in registering for color support */ + num_dspps = _dpu_kms_attach_color(dev, primary_enc_mask, num_dspps); + num_dspps = _dpu_kms_attach_color(dev, external_enc_mask, num_dspps); + return 0; }