From nobody Tue Jun 9 20:05:39 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CB9D5C4332F for ; Mon, 11 Apr 2022 15:44:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348158AbiDKPqh (ORCPT ); Mon, 11 Apr 2022 11:46:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44410 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348160AbiDKPqX (ORCPT ); Mon, 11 Apr 2022 11:46:23 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EBAA81025 for ; Mon, 11 Apr 2022 08:44:06 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id i27so31742307ejd.9 for ; Mon, 11 Apr 2022 08:44:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=IfKH2CI9M//LkZvjQ2ovL0RNbL5cFQ7ZiAOaiFFFhfo=; b=ibV3kGQKwcinaS1/iTDMsTIAihVjTtojxDgUre25vi954+OrzzCXK8ImxtuxVEAkb2 Hg9OL2s+Yf0sIU3ag62n4Ww/agXCDQNz5u+5hwgF3rM8FvjzAS/cv77t3QdhbGi2/mD+ 0XAUrkKofi8LF/r3ulNzcVqr+YwXdWMoGhBIYA87ahdPZYM6pBWZKbmdU4Nkd0MRshwZ TA5ctc+Tgvmf8HPMTDqH+EPOlDdJv554KFI0zXq3pxu6zIQCOA1h93UhRBD5MSLmuJeD KvMLtcYHgtnubwq5Kasz3jHltnu7vd9PdyRo1xU3wl4I2ZXZnDcU9HfKbs2KU2m5cEhV LH3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IfKH2CI9M//LkZvjQ2ovL0RNbL5cFQ7ZiAOaiFFFhfo=; b=1k7HHJhaYJydxUDKbUpYWbFE6OhhmuSmQ/+J0/bjDH1k2a7XzZxa6PmCR0vA27OT4t AbqKk8zzgB29+9aty961oTuUWWYxQwEAzZ4qoT8Gz5Mn0J4QkaS5C2BFT7ROgs49FG4+ Y/R9swAoNtIUByY6w9fy4n9x6WVl2dg0V6zov4tvYvxcgXaQ7Na0OhI2D4c2bPT/g4Fk ug/3nPZALl5T52JiZoaMZX+DzZhX13TQEMTSFvsvZezxfvcYx96S9RAOo9vxxpe1vVuw higIIrXON60FZlIAY3XFbp8KXkZvz0IdYW//o7MG+MscvrT5jXyplcA/UJmbypa+fjFZ fP3Q== X-Gm-Message-State: AOAM530HK9s5EgGS4ZmlTZcGtaPVFXjgyE5tSWoFFh6xwFTDldBVRBRX F/tP4LplkTM/qOBLh7xSzuytTQ== X-Google-Smtp-Source: ABdhPJxV0mCjni3ixH3ficisiO0VgzkFHoIXlralC8ju8qT8Yv+egeY0tlkfaqMPsRNcX8XOEFMyjg== X-Received: by 2002:a17:907:628e:b0:6d9:c6fa:6168 with SMTP id nd14-20020a170907628e00b006d9c6fa6168mr30508428ejc.132.1649691845390; Mon, 11 Apr 2022 08:44:05 -0700 (PDT) Received: from localhost.localdomain (xdsl-188-155-201-27.adslplus.ch. [188.155.201.27]) by smtp.gmail.com with ESMTPSA id t14-20020a170906608e00b006d1455acc62sm12173177ejj.74.2022.04.11.08.44.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Apr 2022 08:44:04 -0700 (PDT) From: Krzysztof Kozlowski To: Andy Gross , Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , "Rafael J. Wysocki" , Taniya Das , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-scsi@vger.kernel.org Cc: Krzysztof Kozlowski Subject: [RFC PATCH v2 1/6] dt-bindings: clock: qcom,gcc-sdm845: add parent power domain Date: Mon, 11 Apr 2022 17:43:42 +0200 Message-Id: <20220411154347.491396-2-krzysztof.kozlowski@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> References: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Allow Qualcomm GCC to register its parent power domain (e.g. RPMHPD) to properly pass performance state from children. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Reviewed-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml b= /Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml index d902f137ab17..daf7906ebc40 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sdm845.yaml @@ -43,6 +43,9 @@ properties: '#reset-cells': const: 1 =20 + power-domains: + maxItems: 1 + '#power-domain-cells': const: 1 =20 --=20 2.32.0 From nobody Tue Jun 9 20:05:39 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58562C433EF for ; Mon, 11 Apr 2022 15:44:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348168AbiDKPqm (ORCPT ); Mon, 11 Apr 2022 11:46:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348169AbiDKPqY (ORCPT ); Mon, 11 Apr 2022 11:46:24 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 33900272D for ; Mon, 11 Apr 2022 08:44:08 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id g18so6797701ejc.10 for ; Mon, 11 Apr 2022 08:44:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=K/VH4iXX/HSvKxY6FnWRf9tFEMBnPZdBMAJ6em5xnqg=; b=UGGTSUjSAL9NJgQLtybygrDJb4vXO3cNduQvPayzRK+bZW0CJAg/czgJYYpwUkCkz/ g2sVarYA4gjU4dM3pX/7gZQJJV0Rf3mP673DCCsOSXT2a5wv0OR+lDBY9UIbgVk5fPEj Hmj11yCdw1n7nlh2Iptx3Bjw3oUf27qh5v2nVFKVdT/bcBzwz9jxxJMW1goeUwzgyVa6 y8+HnYKi19tDgn18Vk6ieukuQVPeLbijXrNeTGVZNoCKcKPqFQbTUD3bGT/6AxqcrEyj n/nv/lqpTOcTxkcfHs6oaiA3R65VSov7sb/iBdypQzoO4eb+tGYdvmQt4gF5v0KXsvjD Grbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=K/VH4iXX/HSvKxY6FnWRf9tFEMBnPZdBMAJ6em5xnqg=; b=Dwh92ZcZ5CTglfwl2aR/KywE8r82LNumwSjzlSZtWRzASUv0kjEtw6A2wcNTjiXDnE ksQvkKC9gfZ5hM2QLWiBQhjDtFRG8Z0u/0wgJ/eiMvzDykvPBVqxSvgwmzkHoYZMXoD+ 1hInN9JoUf+Gx7v1Dhi+plnNnkGNdzgk3SXoRTMNE58jJDvXdgNfv7i5REMhRUcj+ncQ 6xIsQWdDd7klhplqMpHl4hT6QSyh9Nn9+OrJxvuCma32zLcMtOghgsNxTpaTskKWxm3C URfx489ijcKQ03T10T2OuOdvB1M821Yb+a8WRqJhcVkhpc821Cn7XbeUAqmFEFz06psN 5e1w== X-Gm-Message-State: AOAM532C7Rx6fGV/p6u3bGbMIvtBsKZ7tEH5bRzEhnkvF5weLnpw0k5u B1m/twksZT1j0/hiy6xEns0INA== X-Google-Smtp-Source: ABdhPJyyTzBko5kSxEeXxWHuBtOf1c1YnoIFTwVmCQmEzWG+0S2JVR3bspyNTYSGSf/bPjPbl7Ff2Q== X-Received: by 2002:a17:907:7ea3:b0:6e8:92eb:3dcc with SMTP id qb35-20020a1709077ea300b006e892eb3dccmr5019092ejc.75.1649691846674; Mon, 11 Apr 2022 08:44:06 -0700 (PDT) Received: from localhost.localdomain (xdsl-188-155-201-27.adslplus.ch. [188.155.201.27]) by smtp.gmail.com with ESMTPSA id t14-20020a170906608e00b006d1455acc62sm12173177ejj.74.2022.04.11.08.44.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Apr 2022 08:44:06 -0700 (PDT) From: Krzysztof Kozlowski To: Andy Gross , Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , "Rafael J. Wysocki" , Taniya Das , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-scsi@vger.kernel.org Cc: Krzysztof Kozlowski Subject: [RFC PATCH v2 2/6] dt-bindings: opp: accept array of frequencies Date: Mon, 11 Apr 2022 17:43:43 +0200 Message-Id: <20220411154347.491396-3-krzysztof.kozlowski@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> References: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Devices might need to control several clocks when scaling the frequency and voltage. Allow passing array of clock frequencies, similarly to the voltages. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Reviewed-by: Bjorn Andersson --- Documentation/devicetree/bindings/opp/opp-v2-base.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/opp/opp-v2-base.yaml b/Docum= entation/devicetree/bindings/opp/opp-v2-base.yaml index 76c8acd981b3..1d7216008f95 100644 --- a/Documentation/devicetree/bindings/opp/opp-v2-base.yaml +++ b/Documentation/devicetree/bindings/opp/opp-v2-base.yaml @@ -50,6 +50,14 @@ patternProperties: property to uniquely identify the OPP nodes exists. Devices like= power domains must have another (implementation dependent) property. =20 + This can be also an array of frequencies for each clock provided= to the + device. In such case value of 0 means the clock frequency shoul= d not + be configured for given clock. + minItems: 1 + maxItems: 16 + items: + maxItems: 1 + opp-microvolt: description: | Voltage for the OPP --=20 2.32.0 From nobody Tue Jun 9 20:05:39 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B358C433EF for ; Mon, 11 Apr 2022 15:44:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348200AbiDKPq4 (ORCPT ); Mon, 11 Apr 2022 11:46:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348179AbiDKPqY (ORCPT ); Mon, 11 Apr 2022 11:46:24 -0400 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 607FD6242 for ; Mon, 11 Apr 2022 08:44:09 -0700 (PDT) Received: by mail-ej1-x62a.google.com with SMTP id r13so31783180ejd.5 for ; Mon, 11 Apr 2022 08:44:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mbNpbkkEChotn+zfIrEUISzZtq6Ebit9E8w1dEveKi4=; b=aYr0ukfkZGIsCt/4FT/QKR69G8IU6TdAGT0VhxtNMxD/ZM2av3R60rfzy0Lr+z2jqX RNffGh7JAzN/ky5V6U8TCJAnWdy3iGs3KhP04uuK3EugGOnpLwwcGZ2fTIgLFM56bQaF tbuWxvmlORJFEJxu81ME/WoTRcDnrFtKZ4M8HuZecRxEPgqPKITFt+ju1BeHb2YcHKUa iR8iLpWXca6o/Mwk8EvwYFqlUBxH0JRF0IUfHs1g6bPNU08wkfwWhQOP7w/whgOjQjfI YX1kzMwC0NEyR+1iPz3swS1o1S5TWeDzVAip9VKO1Jfd+vnYpKHzQSkH5s+HiHLRM0Jw MFvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mbNpbkkEChotn+zfIrEUISzZtq6Ebit9E8w1dEveKi4=; b=YLoFfbxnNxbkj3XP/1G+ZLovDqYMuBHZ4NX+Jc1RfmnPqXb/DKNAG7BJBZNRKDxIzh K+b9CUizWe4ojladf82xunSAjZxpkDEw53XxAVhkfgP0g45JnEKG2/MyDidgLkRi4Ng+ MWGzGLyouN+Idu99elhSOityEtQ+NgI79XxrBHr56O+XWAqfhkKLV6o+qRBfCUJeudYw g78FqE75VipHU+lvO02WPhEHJFxnLiHQw7WGod5A5hSaXV98OlWQs4udn5BptybqZ932 RVPGM69XS1VO9xxqyLRSn5ywtVIfFAVbYVx7NC+BB4s/TvuypO4Iz8XLybG0fc35OCFb 1Eyw== X-Gm-Message-State: AOAM531GEZXvZhYMT3LJUOmXJh3IFpAIa0SLQVt50F+ZZr0OTBRejbZX e4cQ7bTMUSMws9YQHxg+8BMAAg== X-Google-Smtp-Source: ABdhPJwrK+vLq5FHXsKcsbi/1tugMQSwYKotl7aV7TAwegLV/VGDWOX0mMt4H3we7pNjfWm9PA2Pzg== X-Received: by 2002:a17:906:d108:b0:6e8:7765:a70b with SMTP id b8-20020a170906d10800b006e87765a70bmr8961267ejz.436.1649691847786; Mon, 11 Apr 2022 08:44:07 -0700 (PDT) Received: from localhost.localdomain (xdsl-188-155-201-27.adslplus.ch. [188.155.201.27]) by smtp.gmail.com with ESMTPSA id t14-20020a170906608e00b006d1455acc62sm12173177ejj.74.2022.04.11.08.44.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Apr 2022 08:44:07 -0700 (PDT) From: Krzysztof Kozlowski To: Andy Gross , Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , "Rafael J. Wysocki" , Taniya Das , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-scsi@vger.kernel.org Cc: Krzysztof Kozlowski Subject: [RFC PATCH v2 3/6] dt-bindings: ufs: common: add OPP table Date: Mon, 11 Apr 2022 17:43:44 +0200 Message-Id: <20220411154347.491396-4-krzysztof.kozlowski@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> References: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Except scaling UFS and bus clocks, it's necessary to scale also the voltages of regulators or power domain performance state levels. Adding Operating Performance Points table allows to adjust power domain performance state, depending on the UFS clock speed. OPPv2 deprecates previous property limited to clock scaling: freq-table-hz. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring --- Not adding Rob's review tag because patch changed significantly. --- .../devicetree/bindings/ufs/ufs-common.yaml | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/ufs/ufs-common.yaml b/Docume= ntation/devicetree/bindings/ufs/ufs-common.yaml index 47a4e9e1a775..d7d2c8a136bb 100644 --- a/Documentation/devicetree/bindings/ufs/ufs-common.yaml +++ b/Documentation/devicetree/bindings/ufs/ufs-common.yaml @@ -20,11 +20,24 @@ properties: items: - description: Minimum frequency for given clock in Hz - description: Maximum frequency for given clock in Hz + deprecated: true description: | + Preferred is operating-points-v2. + Array of operating frequencies in Hz stored in the same or= der - as the clocks property. If this property is not defined or a value i= n the - array is "0" then it is assumed that the frequency is set by the par= ent - clock or a fixed rate clock source. + as the clocks property. If either this property or operating-points-= v2 is + not defined or a value in the array is "0" then it is assumed that t= he + frequency is set by the parent clock or a fixed rate clock source. + + operating-points-v2: + description: + Preferred over freq-table-hz. + If present, each OPP must contain array of frequencies stored in the= same + order for each clock. If clock frequency in the array is "0" then i= t is + assumed that the frequency is set by the parent clock or a fixed rate + clock source. + + opp-table: true =20 interrupts: maxItems: 1 @@ -75,8 +88,23 @@ properties: =20 dependencies: freq-table-hz: [ 'clocks' ] + operating-points-v2: [ 'clocks', 'clock-names' ] =20 required: - interrupts =20 +allOf: + - if: + required: + - freq-table-hz + then: + properties: + operating-points-v2: false + - if: + required: + - operating-points-v2 + then: + properties: + freq-table-hz: false + additionalProperties: true --=20 2.32.0 From nobody Tue Jun 9 20:05:39 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAE3CC433F5 for ; Mon, 11 Apr 2022 15:44:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231600AbiDKPqr (ORCPT ); Mon, 11 Apr 2022 11:46:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348187AbiDKPq1 (ORCPT ); Mon, 11 Apr 2022 11:46:27 -0400 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F58D108D for ; Mon, 11 Apr 2022 08:44:10 -0700 (PDT) Received: by mail-ej1-x632.google.com with SMTP id u15so13104960ejf.11 for ; Mon, 11 Apr 2022 08:44:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bUHecTwVVvrne6C2zn7NEqF69WKs5io5wOl9BsR+pdo=; b=BaMULQQDH7+BY7SGNbOzUIqSAU7zrXml4onrxL4y4kDEEBKfZZ/bxvgYRMvA8nZB4y HGKNJHTI2Q54ob0+Rm+ceREjsPZrO+X5JYdUGI7pEIL95bJAlXHH/acTk3aqCLogGolG vsUFz93L4n6nI6UbeVVAFl98x13XvQtJ8zlOuro8bzhskFn5hn3Kap2o5d62qzicWJUD nGJzBH/IsQZ1NP4Cu5olOQN2X8l1QeN7oZ1HXZXl4r3S8+pn/iuIyTeWIKX2Zpgi5ZTw yBsGhkgqf727wDaQ2/rgiAe1GVW0FLHmnUoMD0BbfrbRdWM/FullRXxWoRXK5Nfy6WAw 0nfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bUHecTwVVvrne6C2zn7NEqF69WKs5io5wOl9BsR+pdo=; b=B3dcIf/kgLCHKXrvXUiZu238tp6KHKpwodMA60LJ12SdWNUVpZFVJNxzdkhghlq5j5 rB1AcwdELgsrD1y0Al4hWeKDjKyto09C11vJYnbbt/5I2FVpnRnLknUbYO6k9MCmd7+m xQsNK2sVQ0u08OXBNW2d+J5WHmaaZaqgPCaKG6wcnj5aeEs264harkhvNM5/+b0GxAZK 10aiDMm67ZJpEwypk4/8zfNDZt03n5yMXYl84MiBx/OoRlcZM32dWUY41mlK/ctzA8ZG OSl2yIjVbNk6qfGtUCXsUW/xftnC+u4OUjGvBMU5rcrKE/V8GG3RUWD/D+hAAsvS8Kgy thYQ== X-Gm-Message-State: AOAM532OLjkGflfB0F29qTrkHr+6YqN2zSezhtnSqsYnvb6z1BW0PUZB 72xStpJbHBr3aF7ycnQQ0WnhqQ== X-Google-Smtp-Source: ABdhPJwwG9Grjj6nk3K3sUNY+XKJcYXGnzmhTUqb0CMKRGbYy5SXYghPI801vigi57Cv8+gkb+cPHA== X-Received: by 2002:a17:906:e110:b0:6e6:75e0:946c with SMTP id gj16-20020a170906e11000b006e675e0946cmr29924830ejb.611.1649691849033; Mon, 11 Apr 2022 08:44:09 -0700 (PDT) Received: from localhost.localdomain (xdsl-188-155-201-27.adslplus.ch. [188.155.201.27]) by smtp.gmail.com with ESMTPSA id t14-20020a170906608e00b006d1455acc62sm12173177ejj.74.2022.04.11.08.44.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Apr 2022 08:44:08 -0700 (PDT) From: Krzysztof Kozlowski To: Andy Gross , Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , "Rafael J. Wysocki" , Taniya Das , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-scsi@vger.kernel.org Cc: Krzysztof Kozlowski Subject: [RFC PATCH v2 4/6] PM: opp: allow control of multiple clocks Date: Mon, 11 Apr 2022 17:43:45 +0200 Message-Id: <20220411154347.491396-5-krzysztof.kozlowski@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> References: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Devices might need to control several clocks when scaling the frequency and voltage. Example is the Universal Flash Storage (UFS) which scales several independent clocks with change of performance levels. Add parsing of multiple clocks and clock names and scale all of them, when needed. If only one clock is provided, the code should behave the same as before. Signed-off-by: Krzysztof Kozlowski --- drivers/opp/core.c | 205 ++++++++++++++++++++++++++++++++--------- drivers/opp/of.c | 48 ++++++++++ drivers/opp/opp.h | 9 +- include/linux/pm_opp.h | 23 +++++ 4 files changed, 242 insertions(+), 43 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 2945f3c1ce09..5dcd7157f6ab 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -66,6 +66,21 @@ static struct opp_table *_find_opp_table_unlocked(struct= device *dev) return ERR_PTR(-ENODEV); } =20 +static void _put_clocks(struct opp_table *opp_table) +{ + int i; + + if (!opp_table->clks) + return; + + for (i =3D opp_table->clk_count - 1; i >=3D 0; i--) + clk_put(opp_table->clks[i]); + + kfree(opp_table->clks); + opp_table->clks =3D NULL; + opp_table->clk_count =3D -1; +}; + /** * _find_opp_table() - find opp_table struct using device pointer * @dev: device pointer used to lookup OPP table @@ -772,6 +787,30 @@ static inline int _generic_set_opp_clk_only(struct dev= ice *dev, struct clk *clk, return ret; } =20 +static int _generic_set_opp_clks_only(struct device *dev, + struct opp_table *opp_table, + struct dev_pm_opp *opp) +{ + int i, ret; + + if (!opp_table->clks) + return 0; + + for (i =3D 0; i < opp_table->clk_count; i++) { + if (opp->rates[i]) { + ret =3D _generic_set_opp_clk_only(dev, opp_table->clks[i], + opp->rates[i]); + if (ret) { + dev_err(dev, "%s: failed to set clock %pC rate: %d\n", + __func__, opp_table->clks[i], ret); + return ret; + } + } + } + + return 0; +} + static int _generic_set_opp_regulator(struct opp_table *opp_table, struct device *dev, struct dev_pm_opp *opp, @@ -796,7 +835,7 @@ static int _generic_set_opp_regulator(struct opp_table = *opp_table, } =20 /* Change frequency */ - ret =3D _generic_set_opp_clk_only(dev, opp_table->clk, freq); + ret =3D _generic_set_opp_clks_only(dev, opp_table, opp); if (ret) goto restore_voltage; =20 @@ -820,7 +859,7 @@ static int _generic_set_opp_regulator(struct opp_table = *opp_table, return 0; =20 restore_freq: - if (_generic_set_opp_clk_only(dev, opp_table->clk, old_opp->rate)) + if (_generic_set_opp_clks_only(dev, opp_table, old_opp)) dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", __func__, old_opp->rate); restore_voltage: @@ -880,7 +919,7 @@ static int _set_opp_custom(const struct opp_table *opp_= table, } =20 data->regulators =3D opp_table->regulators; - data->clk =3D opp_table->clk; + data->clk =3D (opp_table->clks ? opp_table->clks[0] : NULL); data->dev =3D dev; data->old_opp.rate =3D old_opp->rate; data->new_opp.rate =3D freq; @@ -969,8 +1008,8 @@ static void _find_current_opp(struct device *dev, stru= ct opp_table *opp_table) struct dev_pm_opp *opp =3D ERR_PTR(-ENODEV); unsigned long freq; =20 - if (!IS_ERR(opp_table->clk)) { - freq =3D clk_get_rate(opp_table->clk); + if (opp_table->clks && !IS_ERR(opp_table->clks[0])) { + freq =3D clk_get_rate(opp_table->clks[0]); opp =3D _find_freq_ceil(opp_table, &freq); } =20 @@ -1070,7 +1109,7 @@ static int _set_opp(struct device *dev, struct opp_ta= ble *opp_table, scaling_down); } else { /* Only frequency scaling */ - ret =3D _generic_set_opp_clk_only(dev, opp_table->clk, freq); + ret =3D _generic_set_opp_clks_only(dev, opp_table, opp); } =20 if (ret) @@ -1135,11 +1174,15 @@ int dev_pm_opp_set_rate(struct device *dev, unsigne= d long target_freq) * equivalent to a clk_set_rate() */ if (!_get_opp_count(opp_table)) { - ret =3D _generic_set_opp_clk_only(dev, opp_table->clk, target_freq); + if (opp_table->clks) + ret =3D _generic_set_opp_clk_only(dev, + opp_table->clks[0], + target_freq); goto put_opp_table; } =20 - freq =3D clk_round_rate(opp_table->clk, target_freq); + if (opp_table->clks) + freq =3D clk_round_rate(opp_table->clks[0], target_freq); if ((long)freq <=3D 0) freq =3D target_freq; =20 @@ -1156,6 +1199,11 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned= long target_freq) __func__, freq, ret); goto put_opp_table; } + /* + * opp->rates are used for scaling clocks, so be sure accurate + * 'freq' is used, instead what was defined via e.g. Devicetree. + */ + opp->rates[0] =3D freq; } =20 ret =3D _set_opp(dev, opp_table, opp, freq); @@ -1246,7 +1294,8 @@ static struct opp_table *_allocate_opp_table(struct d= evice *dev, int index) INIT_LIST_HEAD(&opp_table->dev_list); INIT_LIST_HEAD(&opp_table->lazy); =20 - /* Mark regulator count uninitialized */ + /* Mark regulator/clk count uninitialized */ + opp_table->clk_count =3D -1; opp_table->regulator_count =3D -1; =20 opp_dev =3D _add_opp_dev(dev, opp_table); @@ -1295,21 +1344,32 @@ static struct opp_table *_update_opp_table_clk(stru= ct device *dev, * Return early if we don't need to get clk or we have already tried it * earlier. */ - if (!getclk || IS_ERR(opp_table) || opp_table->clk) + if (!getclk || IS_ERR(opp_table) || opp_table->clks) return opp_table; =20 + opp_table->clks =3D kmalloc_array(1, sizeof(*opp_table->clks), + GFP_KERNEL); + if (!opp_table->clks) + return ERR_PTR(-ENOMEM); + /* Find clk for the device */ - opp_table->clk =3D clk_get(dev, NULL); + opp_table->clks[0] =3D clk_get(dev, NULL); =20 - ret =3D PTR_ERR_OR_ZERO(opp_table->clk); - if (!ret) + ret =3D PTR_ERR_OR_ZERO(opp_table->clks[0]); + if (!ret) { + opp_table->clk_count =3D 1; return opp_table; + } =20 if (ret =3D=3D -ENOENT) { + opp_table->clk_count =3D 0; dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__, ret); return opp_table; } =20 + kfree(opp_table->clks); + opp_table->clks =3D NULL; + opp_table->clk_count =3D -1; dev_pm_opp_put_opp_table(opp_table); dev_err_probe(dev, ret, "Couldn't find clock\n"); =20 @@ -1408,9 +1468,7 @@ static void _opp_table_kref_release(struct kref *kref) =20 _of_clear_opp_table(opp_table); =20 - /* Release clk */ - if (!IS_ERR(opp_table->clk)) - clk_put(opp_table->clk); + _put_clocks(opp_table); =20 if (opp_table->paths) { for (i =3D 0; i < opp_table->path_count; i++) @@ -2144,9 +2202,51 @@ EXPORT_SYMBOL_GPL(devm_pm_opp_set_regulators); * This must be called before any OPPs are initialized for the device. */ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *n= ame) +{ + return dev_pm_opp_set_clknames(dev, &name, 1); +} +EXPORT_SYMBOL_GPL(dev_pm_opp_set_clkname); + +/** + * dev_pm_opp_put_clkname() - Releases resources blocked for clk. + * @opp_table: OPP table returned from dev_pm_opp_set_clkname(). + */ +void dev_pm_opp_put_clkname(struct opp_table *opp_table) +{ + return dev_pm_opp_put_clknames(opp_table); +} +EXPORT_SYMBOL_GPL(dev_pm_opp_put_clkname); + +/** + * devm_pm_opp_set_clkname() - Set clk name for the device + * @dev: Device for which clk name is being set. + * @name: Clk name. + * + * This is a resource-managed variant of dev_pm_opp_set_clkname(). + * + * Return: 0 on success and errorno otherwise. + */ +int devm_pm_opp_set_clkname(struct device *dev, const char *name) +{ + return devm_pm_opp_set_clknames(dev, &name, 1); +} +EXPORT_SYMBOL_GPL(devm_pm_opp_set_clkname); + +/** + * dev_pm_opp_set_clknames() - Set clk names for the device + * @dev: Device for which clock names are being set. + * @names: Array of pointers to the names of the clocks. + * @count: Number of clocks. + * + * See: dev_pm_opp_set_clkname() + */ +struct opp_table *dev_pm_opp_set_clknames(struct device *dev, + const char * const names[], + unsigned int count) { struct opp_table *opp_table; - int ret; + struct clk *clk; + int ret, i; =20 opp_table =3D _add_opp_table(dev, false); if (IS_ERR(opp_table)) @@ -2159,70 +2259,92 @@ struct opp_table *dev_pm_opp_set_clkname(struct dev= ice *dev, const char *name) } =20 /* clk shouldn't be initialized at this point */ - if (WARN_ON(opp_table->clk)) { + if (WARN_ON(opp_table->clks)) { ret =3D -EBUSY; goto err; } =20 - /* Find clk for the device */ - opp_table->clk =3D clk_get(dev, name); - if (IS_ERR(opp_table->clk)) { - ret =3D dev_err_probe(dev, PTR_ERR(opp_table->clk), - "%s: Couldn't find clock\n", __func__); + opp_table->clks =3D kmalloc_array(count, sizeof(*opp_table->clks), + GFP_KERNEL); + if (!opp_table->clks) { + ret =3D -ENOMEM; goto err; } =20 + for (i =3D 0; i < count; i++) { + clk =3D clk_get(dev, names[i]); + if (IS_ERR(clk)) { + ret =3D dev_err_probe(dev, PTR_ERR(clk), + "%s: Couldn't find clock %s\n", + __func__, names[i]); + goto free_clks; + } + + opp_table->clks[i] =3D clk; + } + + opp_table->clk_count =3D count; + return opp_table; =20 +free_clks: + while (i !=3D 0) + clk_put(opp_table->clks[--i]); + + kfree(opp_table->clks); + opp_table->clks =3D NULL; + opp_table->clk_count =3D -1; err: dev_pm_opp_put_opp_table(opp_table); =20 return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(dev_pm_opp_set_clkname); +EXPORT_SYMBOL_GPL(dev_pm_opp_set_clknames); =20 /** - * dev_pm_opp_put_clkname() - Releases resources blocked for clk. - * @opp_table: OPP table returned from dev_pm_opp_set_clkname(). + * dev_pm_opp_put_clknames() - Releases resources blocked for clk. + * @opp_table: OPP table returned from dev_pm_opp_set_clknames(). */ -void dev_pm_opp_put_clkname(struct opp_table *opp_table) +void dev_pm_opp_put_clknames(struct opp_table *opp_table) { if (unlikely(!opp_table)) return; =20 - clk_put(opp_table->clk); - opp_table->clk =3D ERR_PTR(-EINVAL); + _put_clocks(opp_table); =20 dev_pm_opp_put_opp_table(opp_table); } -EXPORT_SYMBOL_GPL(dev_pm_opp_put_clkname); +EXPORT_SYMBOL_GPL(dev_pm_opp_put_clknames); =20 -static void devm_pm_opp_clkname_release(void *data) +static void devm_pm_opp_clknames_release(void *data) { - dev_pm_opp_put_clkname(data); + dev_pm_opp_put_clknames(data); } =20 /** - * devm_pm_opp_set_clkname() - Set clk name for the device - * @dev: Device for which clk name is being set. - * @name: Clk name. + * devm_pm_opp_set_clknames() - Set clock names for the device + * @dev: Device for which clock names are being set. + * @names: Array of pointers to the names of the clocks. + * @count: Number of clocks. * - * This is a resource-managed variant of dev_pm_opp_set_clkname(). + * This is a resource-managed variant of dev_pm_opp_set_clknames(). * * Return: 0 on success and errorno otherwise. */ -int devm_pm_opp_set_clkname(struct device *dev, const char *name) +int devm_pm_opp_set_clknames(struct device *dev, + const char * const names[], + unsigned int count) { struct opp_table *opp_table; =20 - opp_table =3D dev_pm_opp_set_clkname(dev, name); + opp_table =3D dev_pm_opp_set_clknames(dev, names, count); if (IS_ERR(opp_table)) return PTR_ERR(opp_table); =20 - return devm_add_action_or_reset(dev, devm_pm_opp_clkname_release, + return devm_add_action_or_reset(dev, devm_pm_opp_clknames_release, opp_table); } -EXPORT_SYMBOL_GPL(devm_pm_opp_set_clkname); +EXPORT_SYMBOL_GPL(devm_pm_opp_set_clknames); =20 /** * dev_pm_opp_register_set_opp_helper() - Register custom set OPP helper @@ -2637,7 +2759,8 @@ int dev_pm_opp_add(struct device *dev, unsigned long = freq, unsigned long u_volt) if (IS_ERR(opp_table)) return PTR_ERR(opp_table); =20 - /* Fix regulator count for dynamic OPPs */ + /* Fix regulator/clk count for dynamic OPPs */ + opp_table->clk_count =3D 1; opp_table->regulator_count =3D 1; =20 ret =3D _opp_add_v1(opp_table, dev, freq, u_volt, true); diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 440ab5a03df9..26ab58b71c2d 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -767,6 +767,47 @@ void dev_pm_opp_of_remove_table(struct device *dev) } EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); =20 +static int _read_clocks(struct dev_pm_opp *opp, struct opp_table *opp_tabl= e, + struct device_node *np) +{ + int count, ret; + u64 *freq; + + count =3D of_property_count_u64_elems(np, "opp-hz"); + if (count < 0) { + pr_err("%s: Invalid %s property (%d)\n", + __func__, of_node_full_name(np), count); + return count; + } + + if (count !=3D opp_table->clk_count) { + pr_err("%s: number of rates %d does not match number of clocks %d in %s\= n", + __func__, count, opp_table->clk_count, + of_node_full_name(np)); + return -EINVAL; + } + + freq =3D kmalloc_array(count, sizeof(*freq), GFP_KERNEL); + if (!freq) + return -ENOMEM; + + ret =3D of_property_read_u64_array(np, "opp-hz", freq, count); + if (ret) { + pr_err("%s: error parsing %s: %d\n", __func__, + of_node_full_name(np), ret); + ret =3D -EINVAL; + goto free_freq; + } + + opp->rates =3D freq; + return 0; + +free_freq: + kfree(freq); + + return ret; +} + static int _read_bw(struct dev_pm_opp *new_opp, struct opp_table *table, struct device_node *np, bool peak) { @@ -827,6 +868,13 @@ static int _read_opp_key(struct dev_pm_opp *new_opp, s= truct opp_table *table, } *rate_not_available =3D !!ret; =20 + if (!ret) { + ret =3D _read_clocks(new_opp, table, np); + /* The properties were found but we failed to parse them */ + if (ret && ret !=3D -ENODEV) + return ret; + } + /* * Bandwidth consists of peak and average (optional) values: * opp-peak-kBps =3D ; diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 45e3a55239a1..2c4502cff3b2 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -60,6 +60,7 @@ extern struct list_head opp_tables, lazy_opp_tables; * @pstate: Device's power domain's performance state. * @rate: Frequency in hertz * @level: Performance level + * @rates: Frequency rates for the clocks. * @supplies: Power supplies voltage/current values * @bandwidth: Interconnect bandwidth values * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's @@ -84,6 +85,7 @@ struct dev_pm_opp { unsigned long rate; unsigned int level; =20 + u64 *rates; struct dev_pm_opp_supply *supplies; struct dev_pm_opp_icc_bw *bandwidth; =20 @@ -149,7 +151,9 @@ enum opp_table_access { * @supported_hw: Array of version number to support. * @supported_hw_count: Number of elements in supported_hw array. * @prop_name: A name to postfix to many DT properties, while parsing them. - * @clk: Device's clock handle + * @clks: Device clocks handles + * @clk_count: Number of clocks. Its value can be -1 (uninitialized), 0 (no + * clock handle provided) or > 0 (has clock handles). * @regulators: Supply regulators * @regulator_count: Number of power supply regulators. Its value can be -1 * (uninitialized), 0 (no opp-microvolt property) or > 0 (has opp-microvolt @@ -200,7 +204,8 @@ struct opp_table { unsigned int *supported_hw; unsigned int supported_hw_count; const char *prop_name; - struct clk *clk; + struct clk **clks; + int clk_count; struct regulator **regulators; int regulator_count; struct icc_path **paths; diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 0d85a63a1f78..cb50ccf6f818 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -158,6 +158,13 @@ int devm_pm_opp_set_regulators(struct device *dev, con= st char * const names[], u struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *n= ame); void dev_pm_opp_put_clkname(struct opp_table *opp_table); int devm_pm_opp_set_clkname(struct device *dev, const char *name); +struct opp_table *dev_pm_opp_set_clknames(struct device *dev, + const char * const names[], + unsigned int count); +void dev_pm_opp_put_clknames(struct opp_table *opp_table); +int devm_pm_opp_set_clknames(struct device *dev, + const char * const names[], + unsigned int count); struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, i= nt (*set_opp)(struct dev_pm_set_opp_data *data)); void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table); int devm_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)= (struct dev_pm_set_opp_data *data)); @@ -386,6 +393,22 @@ static inline int devm_pm_opp_set_clkname(struct devic= e *dev, const char *name) return -EOPNOTSUPP; } =20 +static inline struct opp_table *dev_pm_opp_set_clknames(struct device *dev, + const char * const names[], + unsigned int count) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline void dev_pm_opp_put_clknames(struct opp_table *opp_table) {} + +static inline int devm_pm_opp_set_clknames(struct device *dev, + const char * const names[], + unsigned int count) +{ + return -EOPNOTSUPP; +} + static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev= , const char * const *names, struct device ***virt_devs) { return ERR_PTR(-EOPNOTSUPP); --=20 2.32.0 From nobody Tue Jun 9 20:05:39 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C24BC433F5 for ; Mon, 11 Apr 2022 15:45:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348205AbiDKPrR (ORCPT ); Mon, 11 Apr 2022 11:47:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348198AbiDKPq3 (ORCPT ); Mon, 11 Apr 2022 11:46:29 -0400 Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 093D7103E for ; Mon, 11 Apr 2022 08:44:11 -0700 (PDT) Received: by mail-ej1-x62e.google.com with SMTP id bv19so8737173ejb.6 for ; Mon, 11 Apr 2022 08:44:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wCfBJPHXx8k4ir3OUI2uyi8QPO52lWPfvV1p+DNSB0Q=; b=UIlxNrnv6VcwwbOIQefzk3mlWWdFKWUL3916hZfps/KAkUEKlIICiqKZkyB67+QMEb X9xqivPfoknTX+zYpe3kNDHqTedfXSX6Ebu6YAx6V2t1PFqhzDZqYJPt0kjPK1KkNzD3 HgGI2ISWrMzdjzffZzucGGa4xLD2GO4TSkKo0Gq6NCajmjuTra/DvRfWKEBhn8dnuKoQ Nr+yyS8UkAxiz/CZKJGf69s4l0Pr+lckEQ3mj0b+dU+EvY64Yr0K3QKyRZ1thuT6A5Bt srx+3GYAQpNEfAsqChOkPAlynfnnmm43noHGTsq6aUJX9zcv2mPwgkSp7dmtdutYQQvQ Hoqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wCfBJPHXx8k4ir3OUI2uyi8QPO52lWPfvV1p+DNSB0Q=; b=Cgs6fzdXLhwUmFZNnTm3jlMexoZTP580wYQrTws4whvPFOGZfs16In6HBRdeZ6P/g+ NClkFUEaUagbIVwprfAJk6SLwrx+sS0tlOJooL1nZnzKIcUqWTk5XRGj0JVhpIPWZKPX Ko/gtQ0tXjYCmLumrH/e8d9xTXPyVO8galAk7Jb7TZQXaidU9HPnwsEvY15cAdN04OBQ t6/aPvYYXeSHM2UlybPZYSlR5Zh4rAcQ3Mcc/aE6RV6k2F9Hv1QCcObvktfR+hjg3ajt 2c4Z/08miGtshbXK+Q1H8Mo7wtMWV5GRhAPGXVKCEQvvH/vkLDNhdAFs2s+2wnf0Y1+B wDaw== X-Gm-Message-State: AOAM533gyrPkVdeRhJAG1nZii6AuQ/mJyLePeCoxeLndwCTSXA6UPZts Z7aH4Sq4mPX7zx1aCdNkTfkWgQ== X-Google-Smtp-Source: ABdhPJyYGhNKPINalNmL6ayvgX7kbAHjy2JB3wRp7G4GT9TaojwoktHJe/sfoJsMT67C5alhHgFdsA== X-Received: by 2002:a17:907:968f:b0:6db:a3c5:ae3e with SMTP id hd15-20020a170907968f00b006dba3c5ae3emr30896744ejc.770.1649691850288; Mon, 11 Apr 2022 08:44:10 -0700 (PDT) Received: from localhost.localdomain (xdsl-188-155-201-27.adslplus.ch. [188.155.201.27]) by smtp.gmail.com with ESMTPSA id t14-20020a170906608e00b006d1455acc62sm12173177ejj.74.2022.04.11.08.44.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Apr 2022 08:44:09 -0700 (PDT) From: Krzysztof Kozlowski To: Andy Gross , Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , "Rafael J. Wysocki" , Taniya Das , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-scsi@vger.kernel.org Cc: Krzysztof Kozlowski Subject: [RFC PATCH v2 5/6] ufs: use PM OPP when scaling gears Date: Mon, 11 Apr 2022 17:43:46 +0200 Message-Id: <20220411154347.491396-6-krzysztof.kozlowski@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> References: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Scaling gears requires not only scaling clocks, but also voltage levels, e.g. via performance states. Use the provided OPP table, to set proper OPP frequency which through required-opps will trigger performance state change. This deprecates the old freq-table-hz Devicetree property and old clock scaling method in favor of PM core code. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson --- drivers/scsi/ufs/ufshcd-pltfrm.c | 69 +++++++++++++++++++ drivers/scsi/ufs/ufshcd.c | 115 +++++++++++++++++++++++-------- drivers/scsi/ufs/ufshcd.h | 4 ++ 3 files changed, 158 insertions(+), 30 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-plt= frm.c index c1d8b6f46868..edba585db0c1 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -107,6 +107,69 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba) return ret; } =20 +static int ufshcd_parse_operating_points(struct ufs_hba *hba) +{ + struct device *dev =3D hba->dev; + struct device_node *np =3D dev->of_node; + struct ufs_clk_info *clki; + const char *names[16]; + bool clocks_done; + int cnt, i, ret; + + if (!of_find_property(dev->of_node, "operating-points-v2", NULL)) + return 0; + + cnt =3D of_property_count_strings(np, "clock-names"); + if (cnt <=3D 0) { + dev_warn(dev, "%s: Missing clock-names\n", + __func__); + return -EINVAL; + } + + if (cnt > ARRAY_SIZE(names)) { + dev_info(dev, "%s: Too many clock-names\n", __func__); + return -EINVAL; + } + + /* clocks parsed by ufshcd_parse_clock_info() */ + clocks_done =3D !!of_find_property(np, "freq-table-hz", NULL); + + for (i =3D 0; i < cnt; i++) { + ret =3D of_property_read_string_index(np, "clock-names", i, + &names[i]); + if (ret) + return ret; + + if (clocks_done) + continue; + + clki =3D devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL); + if (!clki) + return -ENOMEM; + + clki->name =3D devm_kstrdup(dev, names[i], GFP_KERNEL); + if (!clki->name) + return -ENOMEM; + + if (!strcmp(names[i], "ref_clk")) + clki->keep_link_active =3D true; + + list_add_tail(&clki->list, &hba->clk_list_head); + } + + ret =3D devm_pm_opp_set_clknames(dev, names, i); + if (ret) + return ret; + + ret =3D devm_pm_opp_of_add_table(dev); + if (ret) + return ret; + + hba->use_pm_opp =3D true; + + return 0; +} + #define MAX_PROP_SIZE 32 static int ufshcd_populate_vreg(struct device *dev, const char *name, struct ufs_vreg **out_vreg) @@ -360,6 +423,12 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, goto dealloc_host; } =20 + err =3D ufshcd_parse_operating_points(hba); + if (err) { + dev_err(dev, "%s: OPP parse failed %d\n", __func__, err); + goto dealloc_host; + } + ufshcd_init_lanes_per_dir(hba); =20 err =3D ufshcd_init(hba, mmio_base, irq); diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 5bfa62fa288a..aec7da18a550 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1022,6 +1022,9 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, boo= l scale_up) int ret =3D 0; ktime_t start =3D ktime_get(); =20 + if (hba->use_pm_opp) + return 0; + ret =3D ufshcd_vops_clk_scale_notify(hba, scale_up, PRE_CHANGE); if (ret) goto out; @@ -1044,11 +1047,13 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, b= ool scale_up) /** * ufshcd_is_devfreq_scaling_required - check if scaling is required or not * @hba: per adapter instance + * @freq: Target frequency * @scale_up: True if scaling up and false if scaling down * * Returns true if scaling is required, false otherwise. */ static bool ufshcd_is_devfreq_scaling_required(struct ufs_hba *hba, + unsigned long freq, bool scale_up) { struct ufs_clk_info *clki; @@ -1057,6 +1062,9 @@ static bool ufshcd_is_devfreq_scaling_required(struct= ufs_hba *hba, if (list_empty(head)) return false; =20 + if (hba->use_pm_opp) + return freq !=3D hba->clk_scaling.target_freq; + list_for_each_entry(clki, head, list) { if (!IS_ERR_OR_NULL(clki->clk)) { if (scale_up && clki->max_freq) { @@ -1155,13 +1163,15 @@ static int ufshcd_wait_for_doorbell_clr(struct ufs_= hba *hba, /** * ufshcd_scale_gear - scale up/down UFS gear * @hba: per adapter instance + * @freq: Target frequency * @scale_up: True for scaling up gear and false for scaling down * * Returns 0 for success, * Returns -EBUSY if scaling can't happen at this time * Returns non-zero for any other errors */ -static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up) +static int ufshcd_scale_gear(struct ufs_hba *hba, unsigned long freq, + bool scale_up) { int ret =3D 0; struct ufs_pa_layer_attr new_pwr_info; @@ -1186,6 +1196,12 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bo= ol scale_up) } } =20 + if (hba->use_pm_opp && scale_up) { + ret =3D dev_pm_opp_set_rate(hba->dev, freq); + if (ret) + return ret; + } + /* check if the power mode needs to be changed or not? */ ret =3D ufshcd_config_pwr_mode(hba, &new_pwr_info); if (ret) @@ -1194,6 +1210,11 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bo= ol scale_up) hba->pwr_info.gear_tx, hba->pwr_info.gear_rx, new_pwr_info.gear_tx, new_pwr_info.gear_rx); =20 + if (ret && hba->use_pm_opp && scale_up) + dev_pm_opp_set_rate(hba->dev, hba->devfreq->previous_freq); + else if (hba->use_pm_opp && !scale_up) + ret =3D dev_pm_opp_set_rate(hba->dev, freq); + return ret; } =20 @@ -1236,13 +1257,15 @@ static void ufshcd_clock_scaling_unprepare(struct u= fs_hba *hba, bool writelock) /** * ufshcd_devfreq_scale - scale up/down UFS clocks and gear * @hba: per adapter instance + * @freq: Target frequency * @scale_up: True for scaling up and false for scalin down * * Returns 0 for success, * Returns -EBUSY if scaling can't happen at this time * Returns non-zero for any other errors */ -static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up) +static int ufshcd_devfreq_scale(struct ufs_hba *hba, unsigned long freq, + bool scale_up) { int ret =3D 0; bool is_writelock =3D true; @@ -1253,7 +1276,7 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, = bool scale_up) =20 /* scale down the gear before scaling down clocks */ if (!scale_up) { - ret =3D ufshcd_scale_gear(hba, false); + ret =3D ufshcd_scale_gear(hba, freq, false); if (ret) goto out_unprepare; } @@ -1261,13 +1284,14 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba= , bool scale_up) ret =3D ufshcd_scale_clks(hba, scale_up); if (ret) { if (!scale_up) - ufshcd_scale_gear(hba, true); + ufshcd_scale_gear(hba, hba->clk_scaling.target_freq, + true); goto out_unprepare; } =20 /* scale up the gear after scaling up clocks */ if (scale_up) { - ret =3D ufshcd_scale_gear(hba, true); + ret =3D ufshcd_scale_gear(hba, freq, true); if (ret) { ufshcd_scale_clks(hba, false); goto out_unprepare; @@ -1332,9 +1356,20 @@ static int ufshcd_devfreq_target(struct device *dev, if (!ufshcd_is_clkscaling_supported(hba)) return -EINVAL; =20 - clki =3D list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); /* Override with the closest supported frequency */ - *freq =3D (unsigned long) clk_round_rate(clki->clk, *freq); + if (hba->use_pm_opp) { + struct dev_pm_opp *opp; + + opp =3D devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR(opp)) + return PTR_ERR(opp); + dev_pm_opp_put(opp); + } else { + clki =3D list_first_entry(&hba->clk_list_head, struct ufs_clk_info, + list); + *freq =3D (unsigned long) clk_round_rate(clki->clk, *freq); + } + spin_lock_irqsave(hba->host->host_lock, irq_flags); if (ufshcd_eh_in_progress(hba)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); @@ -1350,11 +1385,11 @@ static int ufshcd_devfreq_target(struct device *dev, } =20 /* Decide based on the rounded-off frequency and update */ - scale_up =3D (*freq =3D=3D clki->max_freq) ? true : false; - if (!scale_up) + scale_up =3D (*freq > hba->clk_scaling.target_freq) ? true : false; + if (!hba->use_pm_opp && !scale_up) *freq =3D clki->min_freq; /* Update the frequency */ - if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) { + if (!ufshcd_is_devfreq_scaling_required(hba, *freq, scale_up)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ret =3D 0; goto out; /* no state change required */ @@ -1362,7 +1397,9 @@ static int ufshcd_devfreq_target(struct device *dev, spin_unlock_irqrestore(hba->host->host_lock, irq_flags); =20 start =3D ktime_get(); - ret =3D ufshcd_devfreq_scale(hba, scale_up); + ret =3D ufshcd_devfreq_scale(hba, *freq, scale_up); + if (!ret) + hba->clk_scaling.target_freq =3D *freq; =20 trace_ufshcd_profile_clk_scaling(dev_name(hba->dev), (scale_up ? "up" : "down"), @@ -1382,8 +1419,6 @@ static int ufshcd_devfreq_get_dev_status(struct devic= e *dev, struct ufs_hba *hba =3D dev_get_drvdata(dev); struct ufs_clk_scaling *scaling =3D &hba->clk_scaling; unsigned long flags; - struct list_head *clk_list =3D &hba->clk_list_head; - struct ufs_clk_info *clki; ktime_t curr_t; =20 if (!ufshcd_is_clkscaling_supported(hba)) @@ -1396,13 +1431,20 @@ static int ufshcd_devfreq_get_dev_status(struct dev= ice *dev, if (!scaling->window_start_t) goto start_window; =20 - clki =3D list_first_entry(clk_list, struct ufs_clk_info, list); - /* - * If current frequency is 0, then the ondemand governor considers - * there's no initial frequency set. And it always requests to set - * to max. frequency. - */ - stat->current_frequency =3D clki->curr_freq; + if (hba->use_pm_opp) { + stat->current_frequency =3D hba->clk_scaling.target_freq; + } else { + struct list_head *clk_list =3D &hba->clk_list_head; + struct ufs_clk_info *clki; + + clki =3D list_first_entry(clk_list, struct ufs_clk_info, list); + /* + * If current frequency is 0, then the ondemand governor considers + * there's no initial frequency set. And it always requests to set + * to max. frequency. + */ + stat->current_frequency =3D clki->curr_freq; + } if (scaling->is_busy_started) scaling->tot_busy_t +=3D ktime_us_delta(curr_t, scaling->busy_start_t); @@ -1435,9 +1477,11 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) if (list_empty(clk_list)) return 0; =20 - clki =3D list_first_entry(clk_list, struct ufs_clk_info, list); - dev_pm_opp_add(hba->dev, clki->min_freq, 0); - dev_pm_opp_add(hba->dev, clki->max_freq, 0); + if (!hba->use_pm_opp) { + clki =3D list_first_entry(clk_list, struct ufs_clk_info, list); + dev_pm_opp_add(hba->dev, clki->min_freq, 0); + dev_pm_opp_add(hba->dev, clki->max_freq, 0); + } =20 ufshcd_vops_config_scaling_param(hba, &hba->vps->devfreq_profile, &hba->vps->ondemand_data); @@ -1449,8 +1493,10 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) ret =3D PTR_ERR(devfreq); dev_err(hba->dev, "Unable to register with devfreq %d\n", ret); =20 - dev_pm_opp_remove(hba->dev, clki->min_freq); - dev_pm_opp_remove(hba->dev, clki->max_freq); + if (!hba->use_pm_opp) { + dev_pm_opp_remove(hba->dev, clki->min_freq); + dev_pm_opp_remove(hba->dev, clki->max_freq); + } return ret; } =20 @@ -1462,7 +1508,6 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) static void ufshcd_devfreq_remove(struct ufs_hba *hba) { struct list_head *clk_list =3D &hba->clk_list_head; - struct ufs_clk_info *clki; =20 if (!hba->devfreq) return; @@ -1470,9 +1515,13 @@ static void ufshcd_devfreq_remove(struct ufs_hba *hb= a) devfreq_remove_device(hba->devfreq); hba->devfreq =3D NULL; =20 - clki =3D list_first_entry(clk_list, struct ufs_clk_info, list); - dev_pm_opp_remove(hba->dev, clki->min_freq); - dev_pm_opp_remove(hba->dev, clki->max_freq); + if (!hba->use_pm_opp) { + struct ufs_clk_info *clki; + + clki =3D list_first_entry(clk_list, struct ufs_clk_info, list); + dev_pm_opp_remove(hba->dev, clki->min_freq); + dev_pm_opp_remove(hba->dev, clki->max_freq); + } } =20 static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba) @@ -1556,8 +1605,14 @@ static ssize_t ufshcd_clkscale_enable_store(struct d= evice *dev, if (value) { ufshcd_resume_clkscaling(hba); } else { + struct dev_pm_opp *opp; + unsigned long freq =3D ULONG_MAX; + + opp =3D dev_pm_opp_find_freq_floor(dev, &freq); + dev_pm_opp_put(opp); + ufshcd_suspend_clkscaling(hba); - err =3D ufshcd_devfreq_scale(hba, true); + err =3D ufshcd_devfreq_scale(hba, freq, true); if (err) dev_err(hba->dev, "%s: failed to scale clocks up %d\n", __func__, err); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 1a8f7b8977e6..c224a55fd9ee 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -443,6 +443,7 @@ struct ufs_clk_scaling { bool is_initialized; bool is_busy_started; bool is_suspended; + unsigned long target_freq; }; =20 #define UFS_EVENT_HIST_LENGTH 8 @@ -776,6 +777,8 @@ struct ufs_hba_monitor { * @auto_bkops_enabled: to track whether bkops is enabled in device * @vreg_info: UFS device voltage regulator information * @clk_list_head: UFS host controller clocks list node head + * @use_pm_opp: whether OPP table is provided and scaling gears should tri= gger + * setting OPP * @pwr_info: holds current power mode * @max_pwr_info: keeps the device max valid pwm * @clk_scaling_lock: used to serialize device commands and clock scaling @@ -892,6 +895,7 @@ struct ufs_hba { bool auto_bkops_enabled; struct ufs_vreg_info vreg_info; struct list_head clk_list_head; + bool use_pm_opp; =20 /* Number of requests aborts */ int req_abort_count; --=20 2.32.0 From nobody Tue Jun 9 20:05:39 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1312C433F5 for ; Mon, 11 Apr 2022 15:45:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348294AbiDKPrL (ORCPT ); Mon, 11 Apr 2022 11:47:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44824 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348205AbiDKPq3 (ORCPT ); Mon, 11 Apr 2022 11:46:29 -0400 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 898D6B7C0 for ; Mon, 11 Apr 2022 08:44:13 -0700 (PDT) Received: by mail-ed1-x535.google.com with SMTP id w18so18918524edi.13 for ; Mon, 11 Apr 2022 08:44:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fU0hWQzn7l8dJNLIMz5BIxCZUns693+M8CLZSpbHGLA=; b=TMn/tnTA+w5TRa4vNuxS5vEJFOk5yiXG5dLIwTHI+6D9zp71rfgpAnjTEpO4zmD3di hSiK6prSo1T1hrLP4OM47zkcxCeGCa5N71/Mh043fmIZmyoawgPhb9oyqm0hnNcttIgq eo8c0K35dQmvk2Xi29V4HadfSMbrnFl0dnIKXUtPyuve7F32+GnsbY8KZUlrIxV8NU3K ON+HX/M+XVMrMprIQ/U1GhyrBbFH5yKRUhju/TgdlQUnk5iI7nSaznj2TIZXRmxYRGdg qYa+8sxevq25oPSMmILdZRNnK7rSZKDE3eEbIYoFm0jHR1/SjtBBdQosvohu0P5PBLY6 fI4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fU0hWQzn7l8dJNLIMz5BIxCZUns693+M8CLZSpbHGLA=; b=oCY1pT0lxDWjkSiY+i8Xvkxq6MsR0W5P+eu1fGcixXgNKIbEh72Lbbfr5gDkBvFML7 BHi0w/iXBmtowWAxY94Hh2yuWabcHzvgyDWllydoQyv6TS28yDCgJemGEj310qReKrKf K6F3s5DuM6IVb49pLlDn1CYyLn2QWkDIs5aXoSAseIXgHu+eUStnFd/ZP5gN1JWPZ+ih TUXUDc3nRD/VoIx81oGU0I+vDoPoX4Lui1pDsJbi8mITuZ3Y23B0EQVL4JUgFytHo3jU 0oH91Ae3ciGwVv5NPn6S5jcNcQUbtq8+DN9mpfUlYRcHvMdHahpbrp34TPNAzD4CdZda Cr9A== X-Gm-Message-State: AOAM5338Ix1MehepZoB5jxX6qVglKSK15ZWYglqvI1YXCA6aR/0VVL0a AQa/koHVxVK2q9I6VWvbyPzjqA== X-Google-Smtp-Source: ABdhPJyBq4Yl6LDEdydbHJ5/4b8uC0V4SNm/51/Z48/ZlLGb4PTPG74I33M/AeumvQmbioftCHhorw== X-Received: by 2002:a05:6402:11cf:b0:41c:dbc7:79d2 with SMTP id j15-20020a05640211cf00b0041cdbc779d2mr34495460edw.50.1649691851702; Mon, 11 Apr 2022 08:44:11 -0700 (PDT) Received: from localhost.localdomain (xdsl-188-155-201-27.adslplus.ch. [188.155.201.27]) by smtp.gmail.com with ESMTPSA id t14-20020a170906608e00b006d1455acc62sm12173177ejj.74.2022.04.11.08.44.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Apr 2022 08:44:11 -0700 (PDT) From: Krzysztof Kozlowski To: Andy Gross , Bjorn Andersson , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , "Rafael J. Wysocki" , Taniya Das , linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-scsi@vger.kernel.org Cc: Krzysztof Kozlowski Subject: [RFC PATCH v2 6/6] arm64: dts: qcom: sdm845: control RPMHPD performance states with UFS Date: Mon, 11 Apr 2022 17:43:47 +0200 Message-Id: <20220411154347.491396-7-krzysztof.kozlowski@linaro.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> References: <20220411154347.491396-1-krzysztof.kozlowski@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" UFS, when scaling gears, should choose appropriate performance state of RPMHPD power domain controller. Since UFS belongs to UFS_PHY_GDSC power domain, add necessary parent power domain to GCC. Signed-off-by: Krzysztof Kozlowski --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 43 +++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qco= m/sdm845.dtsi index b31bf62e8680..920e4b0c71cf 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1078,6 +1078,7 @@ gcc: clock-controller@100000 { #clock-cells =3D <1>; #reset-cells =3D <1>; #power-domain-cells =3D <1>; + power-domains =3D <&rpmhpd SDM845_CX>; }; =20 qfprom@784000 { @@ -2326,18 +2327,40 @@ ufs_mem_hc: ufshc@1d84000 { <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>, <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>, <&gcc GCC_UFS_PHY_ICE_CORE_CLK>; - freq-table-hz =3D - <50000000 200000000>, - <0 0>, - <0 0>, - <37500000 150000000>, - <0 0>, - <0 0>, - <0 0>, - <0 0>, - <0 300000000>; =20 + operating-points-v2 =3D <&ufs_opp_table>; status =3D "disabled"; + + ufs_opp_table: opp-table { + compatible =3D "operating-points-v2"; + + opp-50000000 { + opp-hz =3D /bits/ 64 <50000000 + 0 + 0 + 37500000 + 0 + 0 + 0 + 0 + // FIXME: value 0 copied from freq-table-hz + 0>; + required-opps =3D <&rpmhpd_opp_svs>; + }; + + opp-200000000 { + opp-hz =3D /bits/ 64 <200000000 + 0 + 0 + 150000000 + 0 + 0 + 0 + 0 + 300000000>; + required-opps =3D <&rpmhpd_opp_nom>; + }; + }; }; =20 ufs_mem_phy: phy@1d87000 { --=20 2.32.0