Message ID | 20230112135224.3837820-1-quic_bjorande@quicinc.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp3892373wrt; Thu, 12 Jan 2023 05:57:23 -0800 (PST) X-Google-Smtp-Source: AMrXdXv/h2y+AziuyIlU7TQ8bx1szkrj4LuYG28onf+bu+Yq0ce5TOmu1q+1a1/tPZFeJITASD0d X-Received: by 2002:a05:6a20:3b25:b0:b6:3e6e:af94 with SMTP id c37-20020a056a203b2500b000b63e6eaf94mr8018485pzh.32.1673531843448; Thu, 12 Jan 2023 05:57:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673531843; cv=none; d=google.com; s=arc-20160816; b=ewfZEEBnQA6VWPmJqqLwmu0xZ4iZdFaJhujPsk2tDMmTpAr/llrP7YYtRWVL3P8RHt 8FPTUGBAxCdIV3VwWIdpq5B9HRuDoj8Rq2Ae4yqMhScoxTXV04GZuKK9MmaZ90pSEEVt abvZJMgYjSiarWv7ewHANsSOO3jdz5PhTiOjk6/FKer6vDNRHkBYjWuc4chmGMTHtG+u agU5Bqfpnp2lbeUs0sSw2npYL2IXp7gPxN8rt12Y6Kp5wsdQQKAcdrhuaBQLLLsrVXSW EjmXKuFADzL35h7L+rjQ9/eUs6ayXif47ih4Z3Y2OWH5TV1SHIvHwsQ/lcJ+C3SA3uqw eWxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=SYIvEG8pmrpBPywF9py6RlwQ1BL6zQFVc3QP7tQ9KFs=; b=pUeYMHAHH/Hsg7RKSMJHVdX9BBb6+ro+G0F812gQNGPxqMM3kq47npgJN/UQmEAbFj qiqB/NR9HVItws2wyzZKvbCgVZ07d4EH6k/tWCoONuX9krycoEGTT9DSfGvlFJu7WGUx yzhkFzcaI1lB5b3+uJ1CfHbm0Q+wY9HNVRJHbEwLA8SyTAdBZmJ3eOzSrEpSX1yezYKo 97KbgpVfolxU79DeLpnlgJ7dVnptNTGhxjLtriibLm63Ls74k28kf7r1bgWNnooPxCG2 M9c5GZXpubwzkfVMJWvFoS2WLe8uSCh03CdxWCW2wm2JTds+eLo2QsY3dE7AA/cdNbSj 4Ojw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=gcWD7Ehn; 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 w62-20020a638241000000b004b62737357esi7340346pgd.176.2023.01.12.05.57.06; Thu, 12 Jan 2023 05:57:23 -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=gcWD7Ehn; 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 S231960AbjALNwl (ORCPT <rfc822;zhuangel570@gmail.com> + 99 others); Thu, 12 Jan 2023 08:52:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48702 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229971AbjALNwh (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 12 Jan 2023 08:52:37 -0500 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A45E51169; Thu, 12 Jan 2023 05:52:36 -0800 (PST) Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 30CARCei009736; Thu, 12 Jan 2023 13:52:33 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-transfer-encoding : content-type; s=qcppdkim1; bh=SYIvEG8pmrpBPywF9py6RlwQ1BL6zQFVc3QP7tQ9KFs=; b=gcWD7EhnOYuyJ193CVHYjL/D1r50XImE2FIt8wL2rRro59p+VIcjDAWJp2Zt7fzNGJAp alMHdj23+HK2L/zLyRsCBA2BINJKUPyoFI269C19PBaKhV6Y7ZkJvgQmMmqhuys8BWfP ygQDtl2m+MuD2dFWMmIOv2B2l6MBietV2JNigV21w+fi7Pm1GC6BS6CqXRcujnshZwEB eDbbXciaFhPSvFw3nCxRfTrzkUSBAr5rhdWMjv4ich8rp3/V/nJ/rVyIFW78+8KnkMSc jx5rU83035oi6h0+ZXKoKy7v7lvo0aBVXLZpBEQRbw5LDWXgCgTbzIVRjoyP+qJC4AQW pw== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3n2d750y9j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 12 Jan 2023 13:52:31 +0000 Received: from nalasex01c.na.qualcomm.com (nalasex01c.na.qualcomm.com [10.47.97.35]) by NALASPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 30CDqUOv031106 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 12 Jan 2023 13:52:30 GMT Received: from hu-bjorande-lv.qualcomm.com (10.49.16.6) by nalasex01c.na.qualcomm.com (10.47.97.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.36; Thu, 12 Jan 2023 05:52:29 -0800 From: Bjorn Andersson <quic_bjorande@quicinc.com> To: Bjorn Andersson <andersson@kernel.org>, Andy Gross <agross@kernel.org>, Konrad Dybcio <konrad.dybcio@linaro.org>, Michael Turquette <mturquette@baylibre.com>, Stephen Boyd <sboyd@kernel.org>, Taniya Das <quic_tdas@quicinc.com>, Abel Vesa <abel.vesa@linaro.org> CC: <linux-arm-msm@vger.kernel.org>, <linux-clk@vger.kernel.org>, <linux-kernel@vger.kernel.org> Subject: [PATCH] clk: qcom: gdsc: Disable HW control until supported Date: Thu, 12 Jan 2023 05:52:24 -0800 Message-ID: <20230112135224.3837820-1-quic_bjorande@quicinc.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.49.16.6] X-ClientProxiedBy: nalasex01c.na.qualcomm.com (10.47.97.35) To nalasex01c.na.qualcomm.com (10.47.97.35) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: AQpynj6-zGzN2bRDomeYvYhomB2fsL1j X-Proofpoint-GUID: AQpynj6-zGzN2bRDomeYvYhomB2fsL1j X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2023-01-12_08,2023-01-12_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 phishscore=0 adultscore=0 malwarescore=0 bulkscore=0 priorityscore=1501 lowpriorityscore=0 clxscore=1011 mlxlogscore=999 impostorscore=0 spamscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2301120100 X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE, SPF_PASS autolearn=ham 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?1754825326261639184?= X-GMAIL-MSGID: =?utf-8?q?1754825326261639184?= |
Series |
clk: qcom: gdsc: Disable HW control until supported
|
|
Commit Message
Bjorn Andersson
Jan. 12, 2023, 1:52 p.m. UTC
Software normally uses the SW_COLLAPSE bit to collapse a GDSC, but in
some scenarios it's beneficial to let the hardware perform this without
software intervention.
This is done by configuring the GDSC in "hardware control" state, in
which case the SW_COLLAPSE bit is ignored and some hardware signal is
relies upon instead.
The GDSCs are modelled as power-domains in Linux and as such it's
reasonable to assume that the device drivers intend for the hardware
block to be accessible when their power domain is active.
But in the current implementation, any GDSC that is marked to support
hardware control, gets hardware control unconditionally while the
client driver requests it to be active. It's therefor conceivable that
the hardware collapses a GDSC while Linux is accessing resources
depending on it.
There are ongoing discussions about how to properly expose this control
to the client drivers, but until conclusion in that discussion is
reached, the safer option would be to keep the GDSC in software control
mode.
Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
---
drivers/clk/qcom/gdsc.c | 48 ++++++-----------------------------------
1 file changed, 7 insertions(+), 41 deletions(-)
Comments
Quoting Bjorn Andersson (2023-01-12 05:52:24) > Software normally uses the SW_COLLAPSE bit to collapse a GDSC, but in > some scenarios it's beneficial to let the hardware perform this without > software intervention. > > This is done by configuring the GDSC in "hardware control" state, in > which case the SW_COLLAPSE bit is ignored and some hardware signal is > relies upon instead. > > The GDSCs are modelled as power-domains in Linux and as such it's > reasonable to assume that the device drivers intend for the hardware > block to be accessible when their power domain is active. > > But in the current implementation, any GDSC that is marked to support > hardware control, gets hardware control unconditionally while the > client driver requests it to be active. It's therefor conceivable that > the hardware collapses a GDSC while Linux is accessing resources > depending on it. Why would software want the GDSC to be enabled and accessing resources while the hardware signals that it isn't required? It sounds like hardware control isn't complete? > > There are ongoing discussions about how to properly expose this control Any link? When we implemented hardware clk gating years ago the design was to have software override hardware control when the clk was enabled in software and let the hardware control go into effect when the clk was disabled in software. Hopefully with power domains this could be implemented in a better way by connecting hardware mode to some performance state so that enabling the power domain goes to software mode and then transitioning to a performance state switches to hardware control mode. > to the client drivers, but until conclusion in that discussion is > reached, the safer option would be to keep the GDSC in software control > mode. > > Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com> > --- > drivers/clk/qcom/gdsc.c | 48 ++++++----------------------------------- > 1 file changed, 7 insertions(+), 41 deletions(-) > > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c > index 9e4d6ce891aa..6d3b36a52a48 100644 > --- a/drivers/clk/qcom/gdsc.c > +++ b/drivers/clk/qcom/gdsc.c > @@ -439,6 +398,13 @@ static int gdsc_init(struct gdsc *sc) > on = true; > } > > + /* Disable HW trigger mode until propertly supported */ > + if (sc->flags & HW_CTRL) { > + ret = gdsc_hwctrl(sc, false); > + if (ret < 0) > + return ret; > + } > + Is it a problem for all hardware controlled gdscs? Or just some of them? Should we backport this to stable kernels? I seem to recall that hardware mode was required for some drivers like camera and video? Are they going to keep working if we simply knock out the hardware control mode here?
On Thu, Jan 12, 2023 at 11:10:40AM -0800, Stephen Boyd wrote: > Quoting Bjorn Andersson (2023-01-12 05:52:24) > > Software normally uses the SW_COLLAPSE bit to collapse a GDSC, but in > > some scenarios it's beneficial to let the hardware perform this without > > software intervention. > > > > This is done by configuring the GDSC in "hardware control" state, in > > which case the SW_COLLAPSE bit is ignored and some hardware signal is > > relies upon instead. > > > > The GDSCs are modelled as power-domains in Linux and as such it's > > reasonable to assume that the device drivers intend for the hardware > > block to be accessible when their power domain is active. > > > > But in the current implementation, any GDSC that is marked to support > > hardware control, gets hardware control unconditionally while the > > client driver requests it to be active. It's therefor conceivable that > > the hardware collapses a GDSC while Linux is accessing resources > > depending on it. > > Why would software want the GDSC to be enabled and accessing resources > while the hardware signals that it isn't required? Wouldn't you want a logical OR between these two? As currently written, no attention is given to the software's need for keeping the GDSC active. > It sounds like hardware control isn't complete? > Correct, we're lacking the means for a client driver to affect the hardware vs software control. > > > > There are ongoing discussions about how to properly expose this control > > Any link? When we implemented hardware clk gating years ago the design > was to have software override hardware control when the clk was enabled > in software and let the hardware control go into effect when the clk was > disabled in software. That sounds very reasonable, but it is not what's implemented in this file. In gdsc_enable() we disable SW_COLLAPSE and then immediately give the control to the hardware, and in gdsc_disable() we disable hardware control and then set SW_COLLAPSE. So effectively the GDSC state is either off when Linux says so, or in hardware control. > Hopefully with power domains this could be > implemented in a better way by connecting hardware mode to some > performance state so that enabling the power domain goes to software > mode and then transitioning to a performance state switches to hardware > control mode. > Right, this would allow the software to keep the GDSC on, give the control to the hardware or collapse it. The question is how the "some performance state" should be implemented. > > to the client drivers, but until conclusion in that discussion is > > reached, the safer option would be to keep the GDSC in software control > > mode. > > > > Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com> > > --- > > drivers/clk/qcom/gdsc.c | 48 ++++++----------------------------------- > > 1 file changed, 7 insertions(+), 41 deletions(-) > > > > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c > > index 9e4d6ce891aa..6d3b36a52a48 100644 > > --- a/drivers/clk/qcom/gdsc.c > > +++ b/drivers/clk/qcom/gdsc.c > > @@ -439,6 +398,13 @@ static int gdsc_init(struct gdsc *sc) > > on = true; > > } > > > > + /* Disable HW trigger mode until propertly supported */ > > + if (sc->flags & HW_CTRL) { > > + ret = gdsc_hwctrl(sc, false); > > + if (ret < 0) > > + return ret; > > + } > > + > > Is it a problem for all hardware controlled gdscs? Or just some of them? > Should we backport this to stable kernels? Sorry, I probably wasn't clear enough. There is no observed problem, this simply knocks out the hardware control mode. The reason for sending this ahead of a design conclusion is that the current behavior doesn't make sense to me (Linux says "enable!" and we just ignore that) and consider how the "some performance state" would relate to this, I don't see that it will be an amendment to the current flow. > I seem to recall that hardware mode was required for some drivers like > camera and video? Given that the current implementation only adhere to the hardware signal in-between gdsc_enable() and gdsc_disable(), the drivers for these blocks must have been written such that the software-state covers the needs of the hardware. As mentioned above, the opposite is however not clear. The GDSC might be collapsed at any time, even if Linux thinks it has the GDSC non-collapsed. I not clear to me why the current logic hasn't caused strange issues for us over the years... > Are they going to keep working if we simply knock out the hardware > control mode here? If anything, we might keep the light on longer than today by missing opportunities where the hardware control currently collapses the GDSC behind Linux's back - and we haven't noticed. Regards, Bjorn
On 23-01-12 15:50:38, Bjorn Andersson wrote: > On Thu, Jan 12, 2023 at 11:10:40AM -0800, Stephen Boyd wrote: > > Quoting Bjorn Andersson (2023-01-12 05:52:24) > > > Software normally uses the SW_COLLAPSE bit to collapse a GDSC, but in > > > some scenarios it's beneficial to let the hardware perform this without > > > software intervention. > > > > > > This is done by configuring the GDSC in "hardware control" state, in > > > which case the SW_COLLAPSE bit is ignored and some hardware signal is > > > relies upon instead. > > > > > > The GDSCs are modelled as power-domains in Linux and as such it's > > > reasonable to assume that the device drivers intend for the hardware > > > block to be accessible when their power domain is active. > > > > > > But in the current implementation, any GDSC that is marked to support > > > hardware control, gets hardware control unconditionally while the > > > client driver requests it to be active. It's therefor conceivable that > > > the hardware collapses a GDSC while Linux is accessing resources > > > depending on it. > > > > Why would software want the GDSC to be enabled and accessing resources > > while the hardware signals that it isn't required? > > Wouldn't you want a logical OR between these two? As currently written, > no attention is given to the software's need for keeping the GDSC > active. Looking at this more closely, it is weird nobody complained about GDSC consumers collapsing out of the blue yet. > > > It sounds like hardware control isn't complete? > > > > Correct, we're lacking the means for a client driver to affect the > hardware vs software control. > > > > > > > There are ongoing discussions about how to properly expose this control > > > > Any link? When we implemented hardware clk gating years ago the design > > was to have software override hardware control when the clk was enabled > > in software and let the hardware control go into effect when the clk was > > disabled in software. Discussion is off list for now. > > That sounds very reasonable, but it is not what's implemented in this > file. > > In gdsc_enable() we disable SW_COLLAPSE and then immediately give the > control to the hardware, and in gdsc_disable() we disable hardware > control and then set SW_COLLAPSE. > > So effectively the GDSC state is either off when Linux says so, or in > hardware control. > The discussed solution is the have a generic genpd API that is specifically for marking a PD in HW-controlled mode, while keeping other resources enabled from the consumer driver. > > Hopefully with power domains this could be > > implemented in a better way by connecting hardware mode to some > > performance state so that enabling the power domain goes to software > > mode and then transitioning to a performance state switches to hardware > > control mode. > > > > Right, this would allow the software to keep the GDSC on, give the > control to the hardware or collapse it. > > The question is how the "some performance state" should be implemented. > > > > to the client drivers, but until conclusion in that discussion is > > > reached, the safer option would be to keep the GDSC in software control > > > mode. > > > > > > Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com> > > > --- > > > drivers/clk/qcom/gdsc.c | 48 ++++++----------------------------------- > > > 1 file changed, 7 insertions(+), 41 deletions(-) > > > > > > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c > > > index 9e4d6ce891aa..6d3b36a52a48 100644 > > > --- a/drivers/clk/qcom/gdsc.c > > > +++ b/drivers/clk/qcom/gdsc.c > > > @@ -439,6 +398,13 @@ static int gdsc_init(struct gdsc *sc) > > > on = true; > > > } > > > > > > + /* Disable HW trigger mode until propertly supported */ > > > + if (sc->flags & HW_CTRL) { > > > + ret = gdsc_hwctrl(sc, false); > > > + if (ret < 0) > > > + return ret; > > > + } > > > + > > > > Is it a problem for all hardware controlled gdscs? Or just some of them? > > Should we backport this to stable kernels? > > Sorry, I probably wasn't clear enough. There is no observed problem, > this simply knocks out the hardware control mode. > > The reason for sending this ahead of a design conclusion is that the > current behavior doesn't make sense to me (Linux says "enable!" and we > just ignore that) and consider how the "some performance state" would > relate to this, I don't see that it will be an amendment to the current > flow. I agree. The fact that this did not create any issues yet doesn't mean we should stick with the current implementation. In fact, disabling HW-control altogether (for now) is more reasonable. > > > I seem to recall that hardware mode was required for some drivers like > > camera and video? > > Given that the current implementation only adhere to the hardware signal > in-between gdsc_enable() and gdsc_disable(), the drivers for these > blocks must have been written such that the software-state covers the > needs of the hardware. > > As mentioned above, the opposite is however not clear. The GDSC might be > collapsed at any time, even if Linux thinks it has the GDSC > non-collapsed. I not clear to me why the current logic hasn't caused > strange issues for us over the years... > > > Are they going to keep working if we simply knock out the hardware > > control mode here? > > If anything, we might keep the light on longer than today by missing > opportunities where the hardware control currently collapses the GDSC > behind Linux's back - and we haven't noticed. > > Regards, > Bjorn
On 23-01-12 05:52:24, Bjorn Andersson wrote: > Software normally uses the SW_COLLAPSE bit to collapse a GDSC, but in > some scenarios it's beneficial to let the hardware perform this without > software intervention. > > This is done by configuring the GDSC in "hardware control" state, in > which case the SW_COLLAPSE bit is ignored and some hardware signal is > relies upon instead. > > The GDSCs are modelled as power-domains in Linux and as such it's > reasonable to assume that the device drivers intend for the hardware > block to be accessible when their power domain is active. > > But in the current implementation, any GDSC that is marked to support > hardware control, gets hardware control unconditionally while the > client driver requests it to be active. It's therefor conceivable that > the hardware collapses a GDSC while Linux is accessing resources > depending on it. > > There are ongoing discussions about how to properly expose this control > to the client drivers, but until conclusion in that discussion is > reached, the safer option would be to keep the GDSC in software control > mode. > > Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com> Reviewed-by: Abel Vesa <abel.vesa@linaro.org> > --- > drivers/clk/qcom/gdsc.c | 48 ++++++----------------------------------- > 1 file changed, 7 insertions(+), 41 deletions(-) > > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c > index 9e4d6ce891aa..6d3b36a52a48 100644 > --- a/drivers/clk/qcom/gdsc.c > +++ b/drivers/clk/qcom/gdsc.c > @@ -291,22 +291,6 @@ static int gdsc_enable(struct generic_pm_domain *domain) > */ > udelay(1); > > - /* Turn on HW trigger mode if supported */ > - if (sc->flags & HW_CTRL) { > - ret = gdsc_hwctrl(sc, true); > - if (ret) > - return ret; > - /* > - * Wait for the GDSC to go through a power down and > - * up cycle. In case a firmware ends up polling status > - * bits for the gdsc, it might read an 'on' status before > - * the GDSC can finish the power cycle. > - * We wait 1us before returning to ensure the firmware > - * can't immediately poll the status bits. > - */ > - udelay(1); > - } > - > if (sc->flags & RETAIN_FF_ENABLE) > gdsc_retain_ff_on(sc); > > @@ -321,24 +305,6 @@ static int gdsc_disable(struct generic_pm_domain *domain) > if (sc->pwrsts == PWRSTS_ON) > return gdsc_assert_reset(sc); > > - /* Turn off HW trigger mode if supported */ > - if (sc->flags & HW_CTRL) { > - ret = gdsc_hwctrl(sc, false); > - if (ret < 0) > - return ret; > - /* > - * Wait for the GDSC to go through a power down and > - * up cycle. In case we end up polling status > - * bits for the gdsc before the power cycle is completed > - * it might read an 'on' status wrongly. > - */ > - udelay(1); > - > - ret = gdsc_poll_status(sc, GDSC_ON); > - if (ret) > - return ret; > - } > - > if (sc->pwrsts & PWRSTS_OFF) > gdsc_clear_mem_on(sc); > > @@ -419,13 +385,6 @@ static int gdsc_init(struct gdsc *sc) > goto err_disable_supply; > } > > - /* Turn on HW trigger mode if supported */ > - if (sc->flags & HW_CTRL) { > - ret = gdsc_hwctrl(sc, true); > - if (ret < 0) > - goto err_disable_supply; > - } > - > /* > * Make sure the retain bit is set if the GDSC is already on, > * otherwise we end up turning off the GDSC and destroying all > @@ -439,6 +398,13 @@ static int gdsc_init(struct gdsc *sc) > on = true; > } > > + /* Disable HW trigger mode until propertly supported */ > + if (sc->flags & HW_CTRL) { > + ret = gdsc_hwctrl(sc, false); > + if (ret < 0) > + return ret; > + } > + > if (on || (sc->pwrsts & PWRSTS_RET)) > gdsc_force_mem_on(sc); > else > -- > 2.37.3 >
Quoting Abel Vesa (2023-01-27 08:15:03) > On 23-01-12 15:50:38, Bjorn Andersson wrote: > > On Thu, Jan 12, 2023 at 11:10:40AM -0800, Stephen Boyd wrote: > > > Quoting Bjorn Andersson (2023-01-12 05:52:24) > > > > Software normally uses the SW_COLLAPSE bit to collapse a GDSC, but in > > > > some scenarios it's beneficial to let the hardware perform this without > > > > software intervention. > > > > > > > > This is done by configuring the GDSC in "hardware control" state, in > > > > which case the SW_COLLAPSE bit is ignored and some hardware signal is > > > > relies upon instead. > > > > > > > > The GDSCs are modelled as power-domains in Linux and as such it's > > > > reasonable to assume that the device drivers intend for the hardware > > > > block to be accessible when their power domain is active. > > > > > > > > But in the current implementation, any GDSC that is marked to support > > > > hardware control, gets hardware control unconditionally while the > > > > client driver requests it to be active. It's therefor conceivable that > > > > the hardware collapses a GDSC while Linux is accessing resources > > > > depending on it. > > > > > > Why would software want the GDSC to be enabled and accessing resources > > > while the hardware signals that it isn't required? > > > > Wouldn't you want a logical OR between these two? As currently written, > > no attention is given to the software's need for keeping the GDSC > > active. > > Looking at this more closely, it is weird nobody complained about GDSC > consumers collapsing out of the blue yet. Probably the hardware requests the gdsc to be enabled by default and only drops the request when it knows it is idle and not doing anything? I'm imagining an open drain sort of signal where the hardware pulls the line when it wants to power down and then lets go when it wants to operate normally. > > > > > > It sounds like hardware control isn't complete? > > > > > > > Correct, we're lacking the means for a client driver to affect the > > hardware vs software control. > > > > > > > > > > There are ongoing discussions about how to properly expose this control > > > > > > Any link? When we implemented hardware clk gating years ago the design > > > was to have software override hardware control when the clk was enabled > > > in software and let the hardware control go into effect when the clk was > > > disabled in software. > > Discussion is off list for now. 😎 > > > > > That sounds very reasonable, but it is not what's implemented in this > > file. > > > > In gdsc_enable() we disable SW_COLLAPSE and then immediately give the > > control to the hardware, and in gdsc_disable() we disable hardware > > control and then set SW_COLLAPSE. > > > > So effectively the GDSC state is either off when Linux says so, or in > > hardware control. > > > > The discussed solution is the have a generic genpd API that is > specifically for marking a PD in HW-controlled mode, while keeping other > resources enabled from the consumer driver. Alright. > > > > Hopefully with power domains this could be > > > implemented in a better way by connecting hardware mode to some > > > performance state so that enabling the power domain goes to software > > > mode and then transitioning to a performance state switches to hardware > > > control mode. > > > > > > > Right, this would allow the software to keep the GDSC on, give the > > control to the hardware or collapse it. > > > > The question is how the "some performance state" should be implemented. > > > > > > to the client drivers, but until conclusion in that discussion is > > > > reached, the safer option would be to keep the GDSC in software control > > > > mode. > > > > > > > > Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com> > > > > --- > > > > drivers/clk/qcom/gdsc.c | 48 ++++++----------------------------------- > > > > 1 file changed, 7 insertions(+), 41 deletions(-) > > > > > > > > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c > > > > index 9e4d6ce891aa..6d3b36a52a48 100644 > > > > --- a/drivers/clk/qcom/gdsc.c > > > > +++ b/drivers/clk/qcom/gdsc.c > > > > @@ -439,6 +398,13 @@ static int gdsc_init(struct gdsc *sc) > > > > on = true; > > > > } > > > > > > > > + /* Disable HW trigger mode until propertly supported */ > > > > + if (sc->flags & HW_CTRL) { > > > > + ret = gdsc_hwctrl(sc, false); > > > > + if (ret < 0) > > > > + return ret; > > > > + } > > > > + > > > > > > Is it a problem for all hardware controlled gdscs? Or just some of them? > > > Should we backport this to stable kernels? > > > > Sorry, I probably wasn't clear enough. There is no observed problem, > > this simply knocks out the hardware control mode. > > > > The reason for sending this ahead of a design conclusion is that the > > current behavior doesn't make sense to me (Linux says "enable!" and we > > just ignore that) and consider how the "some performance state" would > > relate to this, I don't see that it will be an amendment to the current > > flow. > > I agree. The fact that this did not create any issues yet doesn't mean > we should stick with the current implementation. In fact, disabling > HW-control altogether (for now) is more reasonable. Any change needs testing. For all I know, this breaks drivers or firmware that are expecting power control to be hardware based (e.g. maybe video firmware is polling the gdsc to make sure it turns off). Or it causes a large power regression in the active use case because now the gdsc is on far more often. Has any of this sort of testing been done? Changing things because they don't make sense is not a great argument. > > > > > > I seem to recall that hardware mode was required for some drivers like > > > camera and video? > > > > Given that the current implementation only adhere to the hardware signal > > in-between gdsc_enable() and gdsc_disable(), the drivers for these > > blocks must have been written such that the software-state covers the > > needs of the hardware. > > > > As mentioned above, the opposite is however not clear. The GDSC might be > > collapsed at any time, even if Linux thinks it has the GDSC > > non-collapsed. I not clear to me why the current logic hasn't caused > > strange issues for us over the years... Ok, but it hasn't caused us any issues so far. For all I know this patch will cause problems. I don't see the harm in waiting for the final solution to appear at a later time. > > > > > Are they going to keep working if we simply knock out the hardware > > > control mode here? > > > > If anything, we might keep the light on longer than today by missing > > opportunities where the hardware control currently collapses the GDSC > > behind Linux's back - and we haven't noticed. > > Yep!
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 9e4d6ce891aa..6d3b36a52a48 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -291,22 +291,6 @@ static int gdsc_enable(struct generic_pm_domain *domain) */ udelay(1); - /* Turn on HW trigger mode if supported */ - if (sc->flags & HW_CTRL) { - ret = gdsc_hwctrl(sc, true); - if (ret) - return ret; - /* - * Wait for the GDSC to go through a power down and - * up cycle. In case a firmware ends up polling status - * bits for the gdsc, it might read an 'on' status before - * the GDSC can finish the power cycle. - * We wait 1us before returning to ensure the firmware - * can't immediately poll the status bits. - */ - udelay(1); - } - if (sc->flags & RETAIN_FF_ENABLE) gdsc_retain_ff_on(sc); @@ -321,24 +305,6 @@ static int gdsc_disable(struct generic_pm_domain *domain) if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); - /* Turn off HW trigger mode if supported */ - if (sc->flags & HW_CTRL) { - ret = gdsc_hwctrl(sc, false); - if (ret < 0) - return ret; - /* - * Wait for the GDSC to go through a power down and - * up cycle. In case we end up polling status - * bits for the gdsc before the power cycle is completed - * it might read an 'on' status wrongly. - */ - udelay(1); - - ret = gdsc_poll_status(sc, GDSC_ON); - if (ret) - return ret; - } - if (sc->pwrsts & PWRSTS_OFF) gdsc_clear_mem_on(sc); @@ -419,13 +385,6 @@ static int gdsc_init(struct gdsc *sc) goto err_disable_supply; } - /* Turn on HW trigger mode if supported */ - if (sc->flags & HW_CTRL) { - ret = gdsc_hwctrl(sc, true); - if (ret < 0) - goto err_disable_supply; - } - /* * Make sure the retain bit is set if the GDSC is already on, * otherwise we end up turning off the GDSC and destroying all @@ -439,6 +398,13 @@ static int gdsc_init(struct gdsc *sc) on = true; } + /* Disable HW trigger mode until propertly supported */ + if (sc->flags & HW_CTRL) { + ret = gdsc_hwctrl(sc, false); + if (ret < 0) + return ret; + } + if (on || (sc->pwrsts & PWRSTS_RET)) gdsc_force_mem_on(sc); else