Message ID | 1702580172-30606-1-git-send-email-quic_khsieh@quicinc.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:3b04:b0:fb:cd0c:d3e with SMTP id c4csp8773834dys; Thu, 14 Dec 2023 10:56:57 -0800 (PST) X-Google-Smtp-Source: AGHT+IHvP4YEMkmVY7hKqUKyOvJaRIyYhBqr7Ke4CdO8vMq152+9wl3ZgEqnyyDjK5m0WdzJ2Udn X-Received: by 2002:a17:902:7c04:b0:1d3:5990:fd4a with SMTP id x4-20020a1709027c0400b001d35990fd4amr1444326pll.56.1702580217203; Thu, 14 Dec 2023 10:56:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702580217; cv=none; d=google.com; s=arc-20160816; b=mKLgQ+He/o6k47Z30M4iiCrcC19a6aEDDQOnF0pIe+epZa1m2Vhs65UUFBDZgXKG4l QcB04Z564imd7pHvj18ufm/unMJ6CKmVqdlHUAh/t8LUUFBrOv3jpebMysjUMrXufGjm evNXbbMetgdimGBdsNx+4vvJqAzQkmDPkKrJxpKvDnamWM1rX6Xl1b8tLRgkRr+K3lYn Qwux7LgFji3+YyP0WgRLl3q1QsGEOHQP/crFXjAje3I1b4sUm6jon0ZpzIEThoO1EhDp ZnetoD05zuUhV1pnEMKyv9py8M0fBBLvd2FWLjz+ylDcnldaXP0ybUbrnnxMzdBHaKUa qE3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:subject:cc:to:from :dkim-signature; bh=PSVG6EZC7eLoqwshMI1KmuV+2bbF2KZMwrQE3OvelYs=; fh=WdvorNt9W2LCUPiGPsn75/bW5381IkpXRxF82JgZV7c=; b=rVXfdV1Li7sbmxvdLDKyaKxMWMmsyv9dUuWJHxw3B6fmoQ/fxdFE2ZZmBX7mo9DOw6 gZA93ppdQPWtOt2iZXp9hNjL5ESZ4ka6a3VcZipoE6Lsu35DBHaDa2O9hJaTeBKcHTAG Y2LnCw4BKBYSIVQmAdHuyO0HeA9pVu/CUZ1y4dksGvl+cawLyhWN1azrNg5vF8wIAf7k yrTX9Kp+nJtZzlc1OrI4b72xu2x3xjD31W9CskGdaTFNuXkjUaSixoTz2TBgfT+3mKFU EXl1kGWenJ3/Eajx7sTGJz3wQx/DKcDI0b5gwWUnYr5JgUFoStGvzzQ34n3Yn1t0G+Ag 7YGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=oG2VrGHo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 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 pete.vger.email (pete.vger.email. [23.128.96.36]) by mx.google.com with ESMTPS id d3-20020a170903230300b001d06eae7137si11964356plh.260.2023.12.14.10.56.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 10:56:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) client-ip=23.128.96.36; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=oG2VrGHo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 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 (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 8972382DB445; Thu, 14 Dec 2023 10:56:40 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1573132AbjLNS4b (ORCPT <rfc822;winker.wchi@gmail.com> + 99 others); Thu, 14 Dec 2023 13:56:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229519AbjLNS4a (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 14 Dec 2023 13:56:30 -0500 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 62EE610E; Thu, 14 Dec 2023 10:56:36 -0800 (PST) Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 3BEIqFRH030905; Thu, 14 Dec 2023 18:56:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:mime-version:content-type; s= qcppdkim1; bh=PSVG6EZC7eLoqwshMI1KmuV+2bbF2KZMwrQE3OvelYs=; b=oG 2VrGHo9e0Pu49Mz7c+9yOHMoPHYApL4RTk8VuDWd1Jpy3tuJAUJiUpHM6Ii/oaQq ts6tjy+2ckaQcGegoXIGkJYlam5mVVwehWQNlSI21dodnJAfnK9YgB/6nX2hTAFS qLGdeOyxXOdl1ZYi8510zpiNdUc9yGBCWeUWuB8dtY9bcCrf9wVPErV3qWOy7Grl Do/V0lv7eiOMv8KN5pDf0UUQZEy06rtJy3bPKc32TntJ3njwb/YLkecQaJSYm0Mu mXO3I0gJMPpyP9KGFY7KhbcdKKHffF85OdgQmsKp5vL+me29k1lWSpT2cwipXuUS sdiav/5lDgV29rTzNacg== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3v07c600hv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 14 Dec 2023 18:56:24 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 3BEIuNBP023216 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 14 Dec 2023 18:56:23 GMT Received: from khsieh-linux1.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Thu, 14 Dec 2023 10:56:22 -0800 From: Kuogee Hsieh <quic_khsieh@quicinc.com> To: <dri-devel@lists.freedesktop.org>, <robdclark@gmail.com>, <sean@poorly.run>, <swboyd@chromium.org>, <dianders@chromium.org>, <vkoul@kernel.org>, <daniel@ffwll.ch>, <airlied@gmail.com>, <agross@kernel.org>, <dmitry.baryshkov@linaro.org>, <andersson@kernel.org> CC: Kuogee Hsieh <quic_khsieh@quicinc.com>, <quic_abhinavk@quicinc.com>, <quic_jesszhan@quicinc.com>, <quic_sbillaka@quicinc.com>, <marijn.suijten@somainline.org>, <freedreno@lists.freedesktop.org>, <linux-arm-msm@vger.kernel.org>, <linux-kernel@vger.kernel.org> Subject: [PATCH v6] drm/msm/dpu: improve DSC allocation Date: Thu, 14 Dec 2023 10:56:12 -0800 Message-ID: <1702580172-30606-1-git-send-email-quic_khsieh@quicinc.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: _he9aTSxhhLMeMJGZ-F2wLO58Q_mdWmv X-Proofpoint-ORIG-GUID: _he9aTSxhhLMeMJGZ-F2wLO58Q_mdWmv X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-12-09_02,2023-12-07_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 mlxlogscore=810 mlxscore=0 priorityscore=1501 malwarescore=0 suspectscore=0 bulkscore=0 spamscore=0 phishscore=0 adultscore=0 impostorscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2311290000 definitions=main-2312140134 X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Thu, 14 Dec 2023 10:56:40 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785284753555765766 X-GMAIL-MSGID: 1785284753555765766 |
Series |
[v6] drm/msm/dpu: improve DSC allocation
|
|
Commit Message
Kuogee Hsieh
Dec. 14, 2023, 6:56 p.m. UTC
At DSC V1.1 DCE (Display Compression Engine) contains a DSC encoder.
However, at DSC V1.2 DCE consists of two DSC encoders, one has an odd
index and another one has an even index. Each encoder can work
independently. But only two DSC encoders from same DCE can be paired
to work together to support DSC merge mode at DSC V1.2. For DSC V1.1
two consecutive DSC encoders (start with even index) have to be paired
to support DSC merge mode. In addition, the DSC with even index have
to be mapped to even PINGPONG index and DSC with odd index have to be
mapped to odd PINGPONG index at its data path in regardless of DSC
V1.1 or V1.2. This patch improves DSC allocation mechanism with
consideration of those factors.
Changes in V6:
-- rename _dpu_rm_reserve_dsc_single to _dpu_rm_dsc_alloc
-- rename _dpu_rm_reserve_dsc_pair to _dpu_rm_dsc_alloc_pair
-- pass global_state to _dpu_rm_pingpong_next_index()
-- remove pp_max
-- fix for loop condition check at _dpu_rm_dsc_alloc()
Changes in V5:
-- delete dsc_id[]
-- update to global_state->dsc_to_enc_id[] directly
-- replace ndx with idx
-- fix indentation at function declaration
-- only one for loop at _dpu_rm_reserve_dsc_single()
Changes in V4:
-- rework commit message
-- use reserved_by_other()
-- add _dpu_rm_pingpong_next_index()
-- revise _dpu_rm_pingpong_dsc_check()
Changes in V3:
-- add dpu_rm_pingpong_dsc_check()
-- for pair allocation use i += 2 at for loop
Changes in V2:
-- split _dpu_rm_reserve_dsc() into _dpu_rm_reserve_dsc_single() and
_dpu_rm_reserve_dsc_pair()
Fixes: f2803ee91a41 ("drm/msm/disp/dpu1: Add DSC support in RM")
Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 154 +++++++++++++++++++++++++++++----
1 file changed, 139 insertions(+), 15 deletions(-)
Comments
Hi Dmitry, Anymore comments from you? On 12/14/2023 10:56 AM, Kuogee Hsieh wrote: > At DSC V1.1 DCE (Display Compression Engine) contains a DSC encoder. > However, at DSC V1.2 DCE consists of two DSC encoders, one has an odd > index and another one has an even index. Each encoder can work > independently. But only two DSC encoders from same DCE can be paired > to work together to support DSC merge mode at DSC V1.2. For DSC V1.1 > two consecutive DSC encoders (start with even index) have to be paired > to support DSC merge mode. In addition, the DSC with even index have > to be mapped to even PINGPONG index and DSC with odd index have to be > mapped to odd PINGPONG index at its data path in regardless of DSC > V1.1 or V1.2. This patch improves DSC allocation mechanism with > consideration of those factors. > > Changes in V6: > -- rename _dpu_rm_reserve_dsc_single to _dpu_rm_dsc_alloc > -- rename _dpu_rm_reserve_dsc_pair to _dpu_rm_dsc_alloc_pair > -- pass global_state to _dpu_rm_pingpong_next_index() > -- remove pp_max > -- fix for loop condition check at _dpu_rm_dsc_alloc() > > Changes in V5: > -- delete dsc_id[] > -- update to global_state->dsc_to_enc_id[] directly > -- replace ndx with idx > -- fix indentation at function declaration > -- only one for loop at _dpu_rm_reserve_dsc_single() > > Changes in V4: > -- rework commit message > -- use reserved_by_other() > -- add _dpu_rm_pingpong_next_index() > -- revise _dpu_rm_pingpong_dsc_check() > > Changes in V3: > -- add dpu_rm_pingpong_dsc_check() > -- for pair allocation use i += 2 at for loop > > Changes in V2: > -- split _dpu_rm_reserve_dsc() into _dpu_rm_reserve_dsc_single() and > _dpu_rm_reserve_dsc_pair() > > Fixes: f2803ee91a41 ("drm/msm/disp/dpu1: Add DSC support in RM") > Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com> > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 154 +++++++++++++++++++++++++++++---- > 1 file changed, 139 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > index f9215643..0ce2a25 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > @@ -461,29 +461,153 @@ static int _dpu_rm_reserve_ctls( > return 0; > } > > -static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, > - struct dpu_global_state *global_state, > - struct drm_encoder *enc, > - const struct msm_display_topology *top) > +static int _dpu_rm_pingpong_next_index(struct dpu_global_state *global_state, > + int start, > + uint32_t enc_id) > { > - int num_dsc = top->num_dsc; > int i; > > - /* check if DSC required are allocated or not */ > - for (i = 0; i < num_dsc; i++) { > - if (!rm->dsc_blks[i]) { > - DPU_ERROR("DSC %d does not exist\n", i); > - return -EIO; > + for (i = start; i < (PINGPONG_MAX - PINGPONG_0); i++) { > + if (global_state->pingpong_to_enc_id[i] == enc_id) > + return i; > + } > + > + return -ENAVAIL; > +} > + > +static int _dpu_rm_pingpong_dsc_check(int dsc_idx, int pp_idx) > +{ > + /* > + * DSC with even index must be used with the PINGPONG with even index > + * DSC with odd index must be used with the PINGPONG with odd index > + */ > + if ((dsc_idx & 0x01) != (pp_idx & 0x01)) > + return -ENAVAIL; > + > + return 0; > +} > + > +static int _dpu_rm_dsc_alloc(struct dpu_rm *rm, > + struct dpu_global_state *global_state, > + uint32_t enc_id, > + const struct msm_display_topology *top) > +{ > + int num_dsc = 0; > + int pp_idx = 0; > + int dsc_idx; > + int ret; > + > + for (dsc_idx = 0; dsc_idx < ARRAY_SIZE(rm->dsc_blks) && > + num_dsc < top->num_dsc; dsc_idx++) { > + if (!rm->dsc_blks[dsc_idx]) > + continue; > + > + if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id)) > + continue; > + > + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); > + if (pp_idx < 0) > + return -ENAVAIL; > + > + ret = _dpu_rm_pingpong_dsc_check(dsc_idx, pp_idx); > + if (ret) > + return -ENAVAIL; > + > + global_state->dsc_to_enc_id[dsc_idx] = enc_id; > + num_dsc++; > + pp_idx++; > + } > + > + if (num_dsc < top->num_dsc) { > + DPU_ERROR("DSC allocation failed num_dsc=%d required=%d\n", > + num_dsc, top->num_dsc); > + return -ENAVAIL; > + } > + > + return 0; > +} > + > +static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm, > + struct dpu_global_state *global_state, > + uint32_t enc_id, > + const struct msm_display_topology *top) > +{ > + int num_dsc = 0; > + int dsc_idx, pp_idx = 0; > + int ret; > + > + /* only start from even dsc index */ > + for (dsc_idx = 0; dsc_idx < ARRAY_SIZE(rm->dsc_blks) && > + num_dsc < top->num_dsc; dsc_idx += 2) { > + if (!rm->dsc_blks[dsc_idx] || > + !rm->dsc_blks[dsc_idx + 1]) > + continue; > + > + /* consective dsc index to be paired */ > + if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id) || > + reserved_by_other(global_state->dsc_to_enc_id, dsc_idx + 1, enc_id)) > + continue; > + > + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); > + if (pp_idx < 0) > + return -ENAVAIL; > + > + ret = _dpu_rm_pingpong_dsc_check(dsc_idx, pp_idx); > + if (ret) { > + pp_idx = 0; > + continue; > } > > - if (global_state->dsc_to_enc_id[i]) { > - DPU_ERROR("DSC %d is already allocated\n", i); > - return -EIO; > + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, enc_id); > + if (pp_idx < 0) > + return -ENAVAIL; > + > + ret = _dpu_rm_pingpong_dsc_check(dsc_idx + 1, pp_idx); > + if (ret) { > + pp_idx = 0; > + continue; > } > + > + global_state->dsc_to_enc_id[dsc_idx] = enc_id; > + global_state->dsc_to_enc_id[dsc_idx + 1] = enc_id; > + num_dsc += 2; > + pp_idx++; /* start for next pair */ > } > > - for (i = 0; i < num_dsc; i++) > - global_state->dsc_to_enc_id[i] = enc->base.id; > + if (num_dsc < top->num_dsc) { > + DPU_ERROR("DSC allocation failed num_dsc=%d required=%d\n", > + num_dsc, top->num_dsc); > + return -ENAVAIL; > + } > + > + return 0; > +} > + > +static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, > + struct dpu_global_state *global_state, > + struct drm_encoder *enc, > + const struct msm_display_topology *top) > +{ > + uint32_t enc_id = enc->base.id; > + > + if (!top->num_dsc || !top->num_intf) > + return 0; > + > + /* > + * Facts: > + * 1) no pingpong split (two layer mixers shared one pingpong) > + * 2) DSC pair starts from even index, such as index(0,1), (2,3), etc > + * 3) even PINGPONG connects to even DSC > + * 4) odd PINGPONG connects to odd DSC > + * 5) pair: encoder +--> pp_idx_0 --> dsc_idx_0 > + * +--> pp_idx_1 --> dsc_idx_1 > + */ > + > + /* num_dsc should be either 1, 2 or 4 */ > + if (top->num_dsc > top->num_intf) /* merge mode */ > + return _dpu_rm_dsc_alloc_pair(rm, global_state, enc_id, top); > + else > + return _dpu_rm_dsc_alloc(rm, global_state, enc_id, top); > > return 0; > }
On Tue, 19 Dec 2023 at 18:18, Kuogee Hsieh <quic_khsieh@quicinc.com> wrote: > > Hi Dmitry, > > Anymore comments from you? No, for some reason I missed this patch. Please excuse me. > On 12/14/2023 10:56 AM, Kuogee Hsieh wrote: > > At DSC V1.1 DCE (Display Compression Engine) contains a DSC encoder. > > However, at DSC V1.2 DCE consists of two DSC encoders, one has an odd > > index and another one has an even index. Each encoder can work > > independently. But only two DSC encoders from same DCE can be paired > > to work together to support DSC merge mode at DSC V1.2. For DSC V1.1 > > two consecutive DSC encoders (start with even index) have to be paired > > to support DSC merge mode. In addition, the DSC with even index have > > to be mapped to even PINGPONG index and DSC with odd index have to be > > mapped to odd PINGPONG index at its data path in regardless of DSC > > V1.1 or V1.2. This patch improves DSC allocation mechanism with > > consideration of those factors. > > > > Changes in V6: > > -- rename _dpu_rm_reserve_dsc_single to _dpu_rm_dsc_alloc > > -- rename _dpu_rm_reserve_dsc_pair to _dpu_rm_dsc_alloc_pair > > -- pass global_state to _dpu_rm_pingpong_next_index() > > -- remove pp_max > > -- fix for loop condition check at _dpu_rm_dsc_alloc() > > > > Changes in V5: > > -- delete dsc_id[] > > -- update to global_state->dsc_to_enc_id[] directly > > -- replace ndx with idx > > -- fix indentation at function declaration > > -- only one for loop at _dpu_rm_reserve_dsc_single() > > > > Changes in V4: > > -- rework commit message > > -- use reserved_by_other() > > -- add _dpu_rm_pingpong_next_index() > > -- revise _dpu_rm_pingpong_dsc_check() > > > > Changes in V3: > > -- add dpu_rm_pingpong_dsc_check() > > -- for pair allocation use i += 2 at for loop > > > > Changes in V2: > > -- split _dpu_rm_reserve_dsc() into _dpu_rm_reserve_dsc_single() and > > _dpu_rm_reserve_dsc_pair() > > > > Fixes: f2803ee91a41 ("drm/msm/disp/dpu1: Add DSC support in RM") > > Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com> > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 154 +++++++++++++++++++++++++++++---- > > 1 file changed, 139 insertions(+), 15 deletions(-) Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> See below for minor nit. > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > > index f9215643..0ce2a25 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c > > @@ -461,29 +461,153 @@ static int _dpu_rm_reserve_ctls( > > return 0; > > } > > > > -static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, > > - struct dpu_global_state *global_state, > > - struct drm_encoder *enc, > > - const struct msm_display_topology *top) > > +static int _dpu_rm_pingpong_next_index(struct dpu_global_state *global_state, > > + int start, I'd still prefer to see `enum dpu_pingpong` as a parameter here instead of just an index, but this is just my taste. > > + uint32_t enc_id) > > { > > - int num_dsc = top->num_dsc; > > int i; > > > > - /* check if DSC required are allocated or not */ > > - for (i = 0; i < num_dsc; i++) { > > - if (!rm->dsc_blks[i]) { > > - DPU_ERROR("DSC %d does not exist\n", i); > > - return -EIO; > > + for (i = start; i < (PINGPONG_MAX - PINGPONG_0); i++) { > > + if (global_state->pingpong_to_enc_id[i] == enc_id) > > + return i; > > + } > > + > > + return -ENAVAIL; > > +} > > + > > +static int _dpu_rm_pingpong_dsc_check(int dsc_idx, int pp_idx) > > +{ > > + /* > > + * DSC with even index must be used with the PINGPONG with even index > > + * DSC with odd index must be used with the PINGPONG with odd index > > + */ > > + if ((dsc_idx & 0x01) != (pp_idx & 0x01)) > > + return -ENAVAIL; > > + > > + return 0; > > +} > > + > > +static int _dpu_rm_dsc_alloc(struct dpu_rm *rm, > > + struct dpu_global_state *global_state, > > + uint32_t enc_id, > > + const struct msm_display_topology *top) > > +{ > > + int num_dsc = 0; > > + int pp_idx = 0; > > + int dsc_idx; > > + int ret; > > + > > + for (dsc_idx = 0; dsc_idx < ARRAY_SIZE(rm->dsc_blks) && > > + num_dsc < top->num_dsc; dsc_idx++) { > > + if (!rm->dsc_blks[dsc_idx]) > > + continue; > > + > > + if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id)) > > + continue; > > + > > + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); > > + if (pp_idx < 0) > > + return -ENAVAIL; > > + > > + ret = _dpu_rm_pingpong_dsc_check(dsc_idx, pp_idx); > > + if (ret) > > + return -ENAVAIL; > > + > > + global_state->dsc_to_enc_id[dsc_idx] = enc_id; > > + num_dsc++; > > + pp_idx++; > > + } > > + > > + if (num_dsc < top->num_dsc) { > > + DPU_ERROR("DSC allocation failed num_dsc=%d required=%d\n", > > + num_dsc, top->num_dsc); > > + return -ENAVAIL; > > + } > > + > > + return 0; > > +} > > + > > +static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm, > > + struct dpu_global_state *global_state, > > + uint32_t enc_id, > > + const struct msm_display_topology *top) > > +{ > > + int num_dsc = 0; > > + int dsc_idx, pp_idx = 0; > > + int ret; > > + > > + /* only start from even dsc index */ > > + for (dsc_idx = 0; dsc_idx < ARRAY_SIZE(rm->dsc_blks) && > > + num_dsc < top->num_dsc; dsc_idx += 2) { > > + if (!rm->dsc_blks[dsc_idx] || > > + !rm->dsc_blks[dsc_idx + 1]) > > + continue; > > + > > + /* consective dsc index to be paired */ > > + if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id) || > > + reserved_by_other(global_state->dsc_to_enc_id, dsc_idx + 1, enc_id)) > > + continue; > > + > > + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); > > + if (pp_idx < 0) > > + return -ENAVAIL; > > + > > + ret = _dpu_rm_pingpong_dsc_check(dsc_idx, pp_idx); > > + if (ret) { > > + pp_idx = 0; > > + continue; > > } > > > > - if (global_state->dsc_to_enc_id[i]) { > > - DPU_ERROR("DSC %d is already allocated\n", i); > > - return -EIO; > > + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, enc_id); > > + if (pp_idx < 0) > > + return -ENAVAIL; > > + > > + ret = _dpu_rm_pingpong_dsc_check(dsc_idx + 1, pp_idx); > > + if (ret) { > > + pp_idx = 0; > > + continue; > > } > > + > > + global_state->dsc_to_enc_id[dsc_idx] = enc_id; > > + global_state->dsc_to_enc_id[dsc_idx + 1] = enc_id; > > + num_dsc += 2; > > + pp_idx++; /* start for next pair */ > > } > > > > - for (i = 0; i < num_dsc; i++) > > - global_state->dsc_to_enc_id[i] = enc->base.id; > > + if (num_dsc < top->num_dsc) { > > + DPU_ERROR("DSC allocation failed num_dsc=%d required=%d\n", > > + num_dsc, top->num_dsc); > > + return -ENAVAIL; > > + } > > + > > + return 0; > > +} > > + > > +static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, > > + struct dpu_global_state *global_state, > > + struct drm_encoder *enc, > > + const struct msm_display_topology *top) > > +{ > > + uint32_t enc_id = enc->base.id; > > + > > + if (!top->num_dsc || !top->num_intf) > > + return 0; > > + > > + /* > > + * Facts: > > + * 1) no pingpong split (two layer mixers shared one pingpong) > > + * 2) DSC pair starts from even index, such as index(0,1), (2,3), etc > > + * 3) even PINGPONG connects to even DSC > > + * 4) odd PINGPONG connects to odd DSC > > + * 5) pair: encoder +--> pp_idx_0 --> dsc_idx_0 > > + * +--> pp_idx_1 --> dsc_idx_1 > > + */ > > + > > + /* num_dsc should be either 1, 2 or 4 */ > > + if (top->num_dsc > top->num_intf) /* merge mode */ > > + return _dpu_rm_dsc_alloc_pair(rm, global_state, enc_id, top); > > + else > > + return _dpu_rm_dsc_alloc(rm, global_state, enc_id, top); > > > > return 0; > > }
On 12/19/2023 2:32 PM, Dmitry Baryshkov wrote: > On Tue, 19 Dec 2023 at 18:18, Kuogee Hsieh <quic_khsieh@quicinc.com> wrote: >> Hi Dmitry, >> >> Anymore comments from you? > No, for some reason I missed this patch. Please excuse me. > >> On 12/14/2023 10:56 AM, Kuogee Hsieh wrote: >>> At DSC V1.1 DCE (Display Compression Engine) contains a DSC encoder. >>> However, at DSC V1.2 DCE consists of two DSC encoders, one has an odd >>> index and another one has an even index. Each encoder can work >>> independently. But only two DSC encoders from same DCE can be paired >>> to work together to support DSC merge mode at DSC V1.2. For DSC V1.1 >>> two consecutive DSC encoders (start with even index) have to be paired >>> to support DSC merge mode. In addition, the DSC with even index have >>> to be mapped to even PINGPONG index and DSC with odd index have to be >>> mapped to odd PINGPONG index at its data path in regardless of DSC >>> V1.1 or V1.2. This patch improves DSC allocation mechanism with >>> consideration of those factors. >>> >>> Changes in V6: >>> -- rename _dpu_rm_reserve_dsc_single to _dpu_rm_dsc_alloc >>> -- rename _dpu_rm_reserve_dsc_pair to _dpu_rm_dsc_alloc_pair >>> -- pass global_state to _dpu_rm_pingpong_next_index() >>> -- remove pp_max >>> -- fix for loop condition check at _dpu_rm_dsc_alloc() >>> >>> Changes in V5: >>> -- delete dsc_id[] >>> -- update to global_state->dsc_to_enc_id[] directly >>> -- replace ndx with idx >>> -- fix indentation at function declaration >>> -- only one for loop at _dpu_rm_reserve_dsc_single() >>> >>> Changes in V4: >>> -- rework commit message >>> -- use reserved_by_other() >>> -- add _dpu_rm_pingpong_next_index() >>> -- revise _dpu_rm_pingpong_dsc_check() >>> >>> Changes in V3: >>> -- add dpu_rm_pingpong_dsc_check() >>> -- for pair allocation use i += 2 at for loop >>> >>> Changes in V2: >>> -- split _dpu_rm_reserve_dsc() into _dpu_rm_reserve_dsc_single() and >>> _dpu_rm_reserve_dsc_pair() >>> >>> Fixes: f2803ee91a41 ("drm/msm/disp/dpu1: Add DSC support in RM") >>> Signed-off-by: Kuogee Hsieh <quic_khsieh@quicinc.com> >>> --- >>> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 154 +++++++++++++++++++++++++++++---- >>> 1 file changed, 139 insertions(+), 15 deletions(-) > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> > > See below for minor nit. > >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c >>> index f9215643..0ce2a25 100644 >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c >>> @@ -461,29 +461,153 @@ static int _dpu_rm_reserve_ctls( >>> return 0; >>> } >>> >>> -static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, >>> - struct dpu_global_state *global_state, >>> - struct drm_encoder *enc, >>> - const struct msm_display_topology *top) >>> +static int _dpu_rm_pingpong_next_index(struct dpu_global_state *global_state, >>> + int start, > I'd still prefer to see `enum dpu_pingpong` as a parameter here > instead of just an index, but this is just my taste. Can you please elaborate more details (pseudo code) for this? i can add it at my next DP dsc patches. > >>> + uint32_t enc_id) >>> { >>> - int num_dsc = top->num_dsc; >>> int i; >>> >>> - /* check if DSC required are allocated or not */ >>> - for (i = 0; i < num_dsc; i++) { >>> - if (!rm->dsc_blks[i]) { >>> - DPU_ERROR("DSC %d does not exist\n", i); >>> - return -EIO; >>> + for (i = start; i < (PINGPONG_MAX - PINGPONG_0); i++) { >>> + if (global_state->pingpong_to_enc_id[i] == enc_id) >>> + return i; >>> + } >>> + >>> + return -ENAVAIL; >>> +} >>> + >>> +static int _dpu_rm_pingpong_dsc_check(int dsc_idx, int pp_idx) >>> +{ >>> + /* >>> + * DSC with even index must be used with the PINGPONG with even index >>> + * DSC with odd index must be used with the PINGPONG with odd index >>> + */ >>> + if ((dsc_idx & 0x01) != (pp_idx & 0x01)) >>> + return -ENAVAIL; >>> + >>> + return 0; >>> +} >>> + >>> +static int _dpu_rm_dsc_alloc(struct dpu_rm *rm, >>> + struct dpu_global_state *global_state, >>> + uint32_t enc_id, >>> + const struct msm_display_topology *top) >>> +{ >>> + int num_dsc = 0; >>> + int pp_idx = 0; >>> + int dsc_idx; >>> + int ret; >>> + >>> + for (dsc_idx = 0; dsc_idx < ARRAY_SIZE(rm->dsc_blks) && >>> + num_dsc < top->num_dsc; dsc_idx++) { >>> + if (!rm->dsc_blks[dsc_idx]) >>> + continue; >>> + >>> + if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id)) >>> + continue; >>> + >>> + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); >>> + if (pp_idx < 0) >>> + return -ENAVAIL; >>> + >>> + ret = _dpu_rm_pingpong_dsc_check(dsc_idx, pp_idx); >>> + if (ret) >>> + return -ENAVAIL; >>> + >>> + global_state->dsc_to_enc_id[dsc_idx] = enc_id; >>> + num_dsc++; >>> + pp_idx++; >>> + } >>> + >>> + if (num_dsc < top->num_dsc) { >>> + DPU_ERROR("DSC allocation failed num_dsc=%d required=%d\n", >>> + num_dsc, top->num_dsc); >>> + return -ENAVAIL; >>> + } >>> + >>> + return 0; >>> +} >>> + >>> +static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm, >>> + struct dpu_global_state *global_state, >>> + uint32_t enc_id, >>> + const struct msm_display_topology *top) >>> +{ >>> + int num_dsc = 0; >>> + int dsc_idx, pp_idx = 0; >>> + int ret; >>> + >>> + /* only start from even dsc index */ >>> + for (dsc_idx = 0; dsc_idx < ARRAY_SIZE(rm->dsc_blks) && >>> + num_dsc < top->num_dsc; dsc_idx += 2) { >>> + if (!rm->dsc_blks[dsc_idx] || >>> + !rm->dsc_blks[dsc_idx + 1]) >>> + continue; >>> + >>> + /* consective dsc index to be paired */ >>> + if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id) || >>> + reserved_by_other(global_state->dsc_to_enc_id, dsc_idx + 1, enc_id)) >>> + continue; >>> + >>> + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); >>> + if (pp_idx < 0) >>> + return -ENAVAIL; >>> + >>> + ret = _dpu_rm_pingpong_dsc_check(dsc_idx, pp_idx); >>> + if (ret) { >>> + pp_idx = 0; >>> + continue; >>> } >>> >>> - if (global_state->dsc_to_enc_id[i]) { >>> - DPU_ERROR("DSC %d is already allocated\n", i); >>> - return -EIO; >>> + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, enc_id); >>> + if (pp_idx < 0) >>> + return -ENAVAIL; >>> + >>> + ret = _dpu_rm_pingpong_dsc_check(dsc_idx + 1, pp_idx); >>> + if (ret) { >>> + pp_idx = 0; >>> + continue; >>> } >>> + >>> + global_state->dsc_to_enc_id[dsc_idx] = enc_id; >>> + global_state->dsc_to_enc_id[dsc_idx + 1] = enc_id; >>> + num_dsc += 2; >>> + pp_idx++; /* start for next pair */ >>> } >>> >>> - for (i = 0; i < num_dsc; i++) >>> - global_state->dsc_to_enc_id[i] = enc->base.id; >>> + if (num_dsc < top->num_dsc) { >>> + DPU_ERROR("DSC allocation failed num_dsc=%d required=%d\n", >>> + num_dsc, top->num_dsc); >>> + return -ENAVAIL; >>> + } >>> + >>> + return 0; >>> +} >>> + >>> +static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, >>> + struct dpu_global_state *global_state, >>> + struct drm_encoder *enc, >>> + const struct msm_display_topology *top) >>> +{ >>> + uint32_t enc_id = enc->base.id; >>> + >>> + if (!top->num_dsc || !top->num_intf) >>> + return 0; >>> + >>> + /* >>> + * Facts: >>> + * 1) no pingpong split (two layer mixers shared one pingpong) >>> + * 2) DSC pair starts from even index, such as index(0,1), (2,3), etc >>> + * 3) even PINGPONG connects to even DSC >>> + * 4) odd PINGPONG connects to odd DSC >>> + * 5) pair: encoder +--> pp_idx_0 --> dsc_idx_0 >>> + * +--> pp_idx_1 --> dsc_idx_1 >>> + */ >>> + >>> + /* num_dsc should be either 1, 2 or 4 */ >>> + if (top->num_dsc > top->num_intf) /* merge mode */ >>> + return _dpu_rm_dsc_alloc_pair(rm, global_state, enc_id, top); >>> + else >>> + return _dpu_rm_dsc_alloc(rm, global_state, enc_id, top); >>> >>> return 0; >>> } > >
On Thu, 14 Dec 2023 10:56:12 -0800, Kuogee Hsieh wrote: > At DSC V1.1 DCE (Display Compression Engine) contains a DSC encoder. > However, at DSC V1.2 DCE consists of two DSC encoders, one has an odd > index and another one has an even index. Each encoder can work > independently. But only two DSC encoders from same DCE can be paired > to work together to support DSC merge mode at DSC V1.2. For DSC V1.1 > two consecutive DSC encoders (start with even index) have to be paired > to support DSC merge mode. In addition, the DSC with even index have > to be mapped to even PINGPONG index and DSC with odd index have to be > mapped to odd PINGPONG index at its data path in regardless of DSC > V1.1 or V1.2. This patch improves DSC allocation mechanism with > consideration of those factors. > > [...] Applied, thanks! [1/1] drm/msm/dpu: improve DSC allocation https://gitlab.freedesktop.org/lumag/msm/-/commit/858ddb64f1ff Best regards,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index f9215643..0ce2a25 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -461,29 +461,153 @@ static int _dpu_rm_reserve_ctls( return 0; } -static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, - struct dpu_global_state *global_state, - struct drm_encoder *enc, - const struct msm_display_topology *top) +static int _dpu_rm_pingpong_next_index(struct dpu_global_state *global_state, + int start, + uint32_t enc_id) { - int num_dsc = top->num_dsc; int i; - /* check if DSC required are allocated or not */ - for (i = 0; i < num_dsc; i++) { - if (!rm->dsc_blks[i]) { - DPU_ERROR("DSC %d does not exist\n", i); - return -EIO; + for (i = start; i < (PINGPONG_MAX - PINGPONG_0); i++) { + if (global_state->pingpong_to_enc_id[i] == enc_id) + return i; + } + + return -ENAVAIL; +} + +static int _dpu_rm_pingpong_dsc_check(int dsc_idx, int pp_idx) +{ + /* + * DSC with even index must be used with the PINGPONG with even index + * DSC with odd index must be used with the PINGPONG with odd index + */ + if ((dsc_idx & 0x01) != (pp_idx & 0x01)) + return -ENAVAIL; + + return 0; +} + +static int _dpu_rm_dsc_alloc(struct dpu_rm *rm, + struct dpu_global_state *global_state, + uint32_t enc_id, + const struct msm_display_topology *top) +{ + int num_dsc = 0; + int pp_idx = 0; + int dsc_idx; + int ret; + + for (dsc_idx = 0; dsc_idx < ARRAY_SIZE(rm->dsc_blks) && + num_dsc < top->num_dsc; dsc_idx++) { + if (!rm->dsc_blks[dsc_idx]) + continue; + + if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id)) + continue; + + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); + if (pp_idx < 0) + return -ENAVAIL; + + ret = _dpu_rm_pingpong_dsc_check(dsc_idx, pp_idx); + if (ret) + return -ENAVAIL; + + global_state->dsc_to_enc_id[dsc_idx] = enc_id; + num_dsc++; + pp_idx++; + } + + if (num_dsc < top->num_dsc) { + DPU_ERROR("DSC allocation failed num_dsc=%d required=%d\n", + num_dsc, top->num_dsc); + return -ENAVAIL; + } + + return 0; +} + +static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm, + struct dpu_global_state *global_state, + uint32_t enc_id, + const struct msm_display_topology *top) +{ + int num_dsc = 0; + int dsc_idx, pp_idx = 0; + int ret; + + /* only start from even dsc index */ + for (dsc_idx = 0; dsc_idx < ARRAY_SIZE(rm->dsc_blks) && + num_dsc < top->num_dsc; dsc_idx += 2) { + if (!rm->dsc_blks[dsc_idx] || + !rm->dsc_blks[dsc_idx + 1]) + continue; + + /* consective dsc index to be paired */ + if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id) || + reserved_by_other(global_state->dsc_to_enc_id, dsc_idx + 1, enc_id)) + continue; + + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); + if (pp_idx < 0) + return -ENAVAIL; + + ret = _dpu_rm_pingpong_dsc_check(dsc_idx, pp_idx); + if (ret) { + pp_idx = 0; + continue; } - if (global_state->dsc_to_enc_id[i]) { - DPU_ERROR("DSC %d is already allocated\n", i); - return -EIO; + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, enc_id); + if (pp_idx < 0) + return -ENAVAIL; + + ret = _dpu_rm_pingpong_dsc_check(dsc_idx + 1, pp_idx); + if (ret) { + pp_idx = 0; + continue; } + + global_state->dsc_to_enc_id[dsc_idx] = enc_id; + global_state->dsc_to_enc_id[dsc_idx + 1] = enc_id; + num_dsc += 2; + pp_idx++; /* start for next pair */ } - for (i = 0; i < num_dsc; i++) - global_state->dsc_to_enc_id[i] = enc->base.id; + if (num_dsc < top->num_dsc) { + DPU_ERROR("DSC allocation failed num_dsc=%d required=%d\n", + num_dsc, top->num_dsc); + return -ENAVAIL; + } + + return 0; +} + +static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, + struct dpu_global_state *global_state, + struct drm_encoder *enc, + const struct msm_display_topology *top) +{ + uint32_t enc_id = enc->base.id; + + if (!top->num_dsc || !top->num_intf) + return 0; + + /* + * Facts: + * 1) no pingpong split (two layer mixers shared one pingpong) + * 2) DSC pair starts from even index, such as index(0,1), (2,3), etc + * 3) even PINGPONG connects to even DSC + * 4) odd PINGPONG connects to odd DSC + * 5) pair: encoder +--> pp_idx_0 --> dsc_idx_0 + * +--> pp_idx_1 --> dsc_idx_1 + */ + + /* num_dsc should be either 1, 2 or 4 */ + if (top->num_dsc > top->num_intf) /* merge mode */ + return _dpu_rm_dsc_alloc_pair(rm, global_state, enc_id, top); + else + return _dpu_rm_dsc_alloc(rm, global_state, enc_id, top); return 0; }