* Re: [PATCH 3/4] PM: EM: Add em_dev_update_chip_binning()
From: Lukasz Luba @ 2024-03-22 10:26 UTC (permalink / raw)
To: Christian Loehle
Cc: dietmar.eggemann, linux-pm, linux-kernel, linux-arm-kernel, sboyd,
nm, linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <aefbb61c-8e15-4e40-9459-30bbbcb8d6f5@arm.com>
Hi Christian,
On 3/14/24 14:32, Christian Loehle wrote:
> On 14/03/2024 14:04, Lukasz Luba wrote:
>> Add a function which allows to modify easily the EM after the new voltage
>> information is available. The device drivers for the chip can adjust
>> the voltage values after setup. The voltage for the same frequency in OPP
>> can be different due to chip binning. The voltage impacts the power usage
>> and the EM power values can be updated to reflect that.
>>
>> Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
>> ---
>> include/linux/energy_model.h | 5 ++++
>> kernel/power/energy_model.c | 51 ++++++++++++++++++++++++++++++++++++
>> 2 files changed, 56 insertions(+)
>>
>> diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
>> index 770755df852f1..d30d67c2f07cf 100644
>> --- a/include/linux/energy_model.h
>> +++ b/include/linux/energy_model.h
>> @@ -172,6 +172,7 @@ struct em_perf_table __rcu *em_table_alloc(struct em_perf_domain *pd);
>> void em_table_free(struct em_perf_table __rcu *table);
>> int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
>> int nr_states);
>> +int em_dev_update_chip_binning(struct device *dev);
>>
>> /**
>> * em_pd_get_efficient_state() - Get an efficient performance state from the EM
>> @@ -387,6 +388,10 @@ int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
>> {
>> return -EINVAL;
>> }
>> +static inline int em_dev_update_chip_binning(struct device *dev)
>> +{
>> + return -EINVAL;
>> +}
>> #endif
>>
>> #endif
>> diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
>> index 6960dd7393b2d..1494a909844a4 100644
>> --- a/kernel/power/energy_model.c
>> +++ b/kernel/power/energy_model.c
>> @@ -808,3 +808,54 @@ static void em_update_workfn(struct work_struct *work)
>> {
>> em_check_capacity_update();
>> }
>> +
>> +/**
>> + * em_dev_update_chip_binning() - Update Energy Model with new values after
>> + * the new voltage information is present in the OPPs.
>> + * @dev : Device for which the Energy Model has to be updated.
>> + *
>> + * This function allows to update easily the EM with new values available in
>> + * the OPP framework and DT. It can be used after the chip has been properly
>> + * verified by device drivers and the voltages adjusted for the 'chip binning'.
>> + * It uses the "dynamic-power-coefficient" DT property to calculate the power
>> + * values for EM. For power calculation it uses the new adjusted voltage
>> + * values known for OPPs, which might be changed after boot.
>> + */
>> +int em_dev_update_chip_binning(struct device *dev)
>> +{
>> + struct em_perf_table __rcu *em_table;
>> + struct em_perf_domain *pd;
>> + int i, ret;
>> +
>> + if (IS_ERR_OR_NULL(dev))
>> + return -EINVAL;
>> +
>> + pd = em_pd_get(dev);
>> + if (!pd) {
>> + dev_warn(dev, "Couldn't find Energy Model %d\n", ret);
>
> ret is uninitialized at this point, I guess just
> + dev_warn(dev, "Couldn't find Energy Model\n");
> already contains everything relevant.
>
Good catch, thanks! Yes, I agree it contains enough. I'm going
to send v2 with this.
Regards,
Lukasz
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 2/2] ARM: dts: imx6sx-nitrogen6sx: drop incorrect cpu-dai property
From: Shengjiu Wang @ 2024-03-22 10:13 UTC (permalink / raw)
To: lgirdwood, broonie, robh+dt, krzysztof.kozlowski+dt, conor+dt,
shengjiu.wang, linux-sound, devicetree, linux-kernel, shawnguo,
s.hauer, kernel, festevam, imx, linux-arm-kernel
In-Reply-To: <1711102406-8399-1-git-send-email-shengjiu.wang@nxp.com>
drop incorrect cpu-dai property, change it to ssi-controller
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts b/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
index cd9cbc9ccc9e..b82d91a7d76d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
@@ -83,7 +83,7 @@ reg_wlan: regulator-wlan {
sound {
compatible = "fsl,imx-audio-sgtl5000";
model = "imx6sx-nitrogen6sx-sgtl5000";
- cpu-dai = <&ssi1>;
+ ssi-controller = <&ssi1>;
audio-codec = <&codec>;
audio-routing =
"MIC_IN", "Mic Jack",
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 0/2] ASoC: dt-bindings: convert fsl-asoc-card.txt to YAML
From: Shengjiu Wang @ 2024-03-22 10:13 UTC (permalink / raw)
To: lgirdwood, broonie, robh+dt, krzysztof.kozlowski+dt, conor+dt,
shengjiu.wang, linux-sound, devicetree, linux-kernel, shawnguo,
s.hauer, kernel, festevam, imx, linux-arm-kernel
Convert fsl-asoc-card.txt to YAML. In order to pass the checking,
add some used compatible string from devicetree.
change cpu-dai in imx6sx-nitrogen6sx to ssi-controller.
Shengjiu Wang (2):
ASoC: dt-bindings: fsl-asoc-card: convert to YAML
ARM: dts: imx6sx-nitrogen6sx: drop incorrect cpu-dai property
.../bindings/sound/fsl-asoc-card.txt | 117 -----------
.../bindings/sound/fsl-asoc-card.yaml | 196 ++++++++++++++++++
.../boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts | 2 +-
3 files changed, 197 insertions(+), 118 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
create mode 100644 Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 1/2] ASoC: dt-bindings: fsl-asoc-card: convert to YAML
From: Shengjiu Wang @ 2024-03-22 10:13 UTC (permalink / raw)
To: lgirdwood, broonie, robh+dt, krzysztof.kozlowski+dt, conor+dt,
shengjiu.wang, linux-sound, devicetree, linux-kernel, shawnguo,
s.hauer, kernel, festevam, imx, linux-arm-kernel
In-Reply-To: <1711102406-8399-1-git-send-email-shengjiu.wang@nxp.com>
Convert the fsl-asoc-card binding to YAML.
In order to pass the checking, add some used compatible
string from devicetree.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
.../bindings/sound/fsl-asoc-card.txt | 117 -----------
.../bindings/sound/fsl-asoc-card.yaml | 196 ++++++++++++++++++
2 files changed, 196 insertions(+), 117 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
create mode 100644 Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
deleted file mode 100644
index 4e8dbc5abfd1..000000000000
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ /dev/null
@@ -1,117 +0,0 @@
-Freescale Generic ASoC Sound Card with ASRC support
-
-The Freescale Generic ASoC Sound Card can be used, ideally, for all Freescale
-SoCs connecting with external CODECs.
-
-The idea of this generic sound card is a bit like ASoC Simple Card. However,
-for Freescale SoCs (especially those released in recent years), most of them
-have ASRC (Documentation/devicetree/bindings/sound/fsl,asrc.txt) inside. And
-this is a specific feature that might be painstakingly controlled and merged
-into the Simple Card.
-
-So having this generic sound card allows all Freescale SoC users to benefit
-from the simplification of a new card support and the capability of the wide
-sample rates support through ASRC.
-
-Note: The card is initially designed for those sound cards who use AC'97, I2S
- and PCM DAI formats. However, it'll be also possible to support those non
- AC'97/I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as
- long as the driver has been properly upgraded.
-
-
-The compatible list for this generic sound card currently:
- "fsl,imx-audio-ac97"
-
- "fsl,imx-audio-cs42888"
-
- "fsl,imx-audio-cs427x"
- (compatible with CS4271 and CS4272)
-
- "fsl,imx-audio-wm8962"
-
- "fsl,imx-audio-sgtl5000"
- (compatible with Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt)
-
- "fsl,imx-audio-wm8960"
-
- "fsl,imx-audio-mqs"
-
- "fsl,imx-audio-wm8524"
-
- "fsl,imx-audio-tlv320aic32x4"
-
- "fsl,imx-audio-tlv320aic31xx"
-
- "fsl,imx-audio-si476x"
-
- "fsl,imx-audio-wm8958"
-
- "fsl,imx-audio-nau8822"
-
-Required properties:
-
- - compatible : Contains one of entries in the compatible list.
-
- - model : The user-visible name of this sound complex
-
- - audio-cpu : The phandle of an CPU DAI controller
-
- - audio-codec : The phandle of an audio codec
-
-Optional properties:
-
- - audio-asrc : The phandle of ASRC. It can be absent if there's no
- need to add ASRC support via DPCM.
-
- - audio-routing : A list of the connections between audio components.
- Each entry is a pair of strings, the first being the
- connection's sink, the second being the connection's
- source. There're a few pre-designed board connectors:
- * Line Out Jack
- * Line In Jack
- * Headphone Jack
- * Mic Jack
- * Ext Spk
- * AMIC (stands for Analog Microphone Jack)
- * DMIC (stands for Digital Microphone Jack)
-
- Note: The "Mic Jack" and "AMIC" are redundant while
- coexisting in order to support the old bindings
- of wm8962 and sgtl5000.
-
- - hp-det-gpio : The GPIO that detect headphones are plugged in
- - mic-det-gpio : The GPIO that detect microphones are plugged in
- - bitclock-master : Indicates dai-link bit clock master; for details see simple-card.yaml.
- - frame-master : Indicates dai-link frame master; for details see simple-card.yaml.
- - dai-format : audio format, for details see simple-card.yaml.
- - frame-inversion : dai-link uses frame clock inversion, for details see simple-card.yaml.
- - bitclock-inversion : dai-link uses bit clock inversion, for details see simple-card.yaml.
- - mclk-id : main clock id, specific for each card configuration.
-
-Optional unless SSI is selected as a CPU DAI:
-
- - mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
-
- - mux-ext-port : The external port of the i.MX audio muxer
-
-Example:
-sound-cs42888 {
- compatible = "fsl,imx-audio-cs42888";
- model = "cs42888-audio";
- audio-cpu = <&esai>;
- audio-asrc = <&asrc>;
- audio-codec = <&cs42888>;
- audio-routing =
- "Line Out Jack", "AOUT1L",
- "Line Out Jack", "AOUT1R",
- "Line Out Jack", "AOUT2L",
- "Line Out Jack", "AOUT2R",
- "Line Out Jack", "AOUT3L",
- "Line Out Jack", "AOUT3R",
- "Line Out Jack", "AOUT4L",
- "Line Out Jack", "AOUT4R",
- "AIN1L", "Line In Jack",
- "AIN1R", "Line In Jack",
- "AIN2L", "Line In Jack",
- "AIN2R", "Line In Jack";
-};
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml b/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml
new file mode 100644
index 000000000000..48051655230d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml
@@ -0,0 +1,196 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl-asoc-card.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale Generic ASoC Sound Card with ASRC support
+
+description:
+ The Freescale Generic ASoC Sound Card can be used, ideally,
+ for all Freescale SoCs connecting with external CODECs.
+
+ The idea of this generic sound card is a bit like ASoC Simple Card.
+ However, for Freescale SoCs (especially those released in recent years),
+ most of them have ASRC
+ (Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml) inside. And
+ this is a specific feature that might be painstakingly controlled and
+ merged into the Simple Card.
+
+ So having this generic sound card allows all Freescale SoC users to
+ benefit from the simplification of a new card support and the capability
+ of the wide sample rates support through ASRC.
+
+ Note, The card is initially designed for those sound cards who use AC'97, I2S
+ and PCM DAI formats. However, it'll be also possible to support those non
+ AC'97/I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as
+ long as the driver has been properly upgraded.
+
+maintainers:
+ - Shengjiu Wang <shengjiu.wang@nxp.com>
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - fsl,imx-sgtl5000
+ - fsl,imx53-cpuvo-sgtl5000
+ - fsl,imx51-babbage-sgtl5000
+ - fsl,imx53-m53evk-sgtl5000
+ - fsl,imx53-qsb-sgtl5000
+ - fsl,imx53-voipac-sgtl5000
+ - fsl,imx6-armadeus-sgtl5000
+ - fsl,imx6-rex-sgtl5000
+ - fsl,imx6-sabreauto-cs42888
+ - fsl,imx6-wandboard-sgtl5000
+ - fsl,imx6dl-nit6xlite-sgtl5000
+ - fsl,imx6q-ba16-sgtl5000
+ - fsl,imx6q-nitrogen6_max-sgtl5000
+ - fsl,imx6q-nitrogen6_som2-sgtl5000
+ - fsl,imx6q-nitrogen6x-sgtl5000
+ - fsl,imx6q-sabrelite-sgtl5000
+ - fsl,imx6q-sabresd-wm8962
+ - fsl,imx6q-udoo-ac97
+ - fsl,imx6q-ventana-sgtl5000
+ - fsl,imx6sl-evk-wm8962
+ - fsl,imx6sx-sdb-mqs
+ - fsl,imx6sx-sdb-wm8962
+ - fsl,imx7d-evk-wm8960
+ - karo,tx53-audio-sgtl5000
+ - tq,imx53-mba53-sgtl5000
+ - enum:
+ - fsl,imx-audio-ac97
+ - fsl,imx-audio-cs42888
+ - fsl,imx-audio-mqs
+ - fsl,imx-audio-sgtl5000
+ - fsl,imx-audio-wm8960
+ - fsl,imx-audio-wm8962
+ - items:
+ - enum:
+ - fsl,imx-audio-ac97
+ - fsl,imx-audio-cs42888
+ - fsl,imx-audio-cs427x
+ - fsl,imx-audio-mqs
+ - fsl,imx-audio-nau8822
+ - fsl,imx-audio-sgtl5000
+ - fsl,imx-audio-si476x
+ - fsl,imx-audio-tlv320aic31xx
+ - fsl,imx-audio-tlv320aic32x4
+ - fsl,imx-audio-wm8524
+ - fsl,imx-audio-wm8960
+ - fsl,imx-audio-wm8962
+ - fsl,imx-audio-wm8958
+
+ model:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: The user-visible name of this sound complex
+
+ audio-asrc:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ The phandle of ASRC. It can be absent if there's no
+ need to add ASRC support via DPCM.
+
+ audio-codec:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: The phandle of an audio codec
+
+ audio-cpu:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: The phandle of an CPU DAI controller
+
+ audio-routing:
+ $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+ description:
+ A list of the connections between audio components. Each entry is a
+ pair of strings, the first being the connection's sink, the second
+ being the connection's source. There're a few pre-designed board
+ connectors.
+ * Line Out Jack
+ * Line In Jack
+ * Headphone Jack
+ * Mic Jack
+ * Ext Spk
+ * AMIC (stands for Analog Microphone Jack)
+ * DMIC (stands for Digital Microphone Jack)
+ Note, The "Mic Jack" and "AMIC" are redundant while coexisting in
+ order to support the old bindings of wm8962 and sgtl5000.
+
+ hp-det-gpio:
+ maxItems: 1
+ description: The GPIO that detect headphones are plugged in
+
+ hp-det-gpios:
+ maxItems: 1
+ description: The GPIO that detect headphones are plugged in
+
+ mic-det-gpio:
+ maxItems: 1
+ description: The GPIO that detect microphones are plugged in
+
+ mic-det-gpios:
+ maxItems: 1
+ description: The GPIO that detect microphones are plugged in
+
+ bitclock-master:
+ description: Indicates dai-link bit clock master; for details see simple-card.yaml.
+
+ frame-master:
+ description: Indicates dai-link frame master; for details see simple-card.yaml.
+
+ dai-format:
+ description: audio format, for details see simple-card.yaml.
+
+ frame-inversion:
+ description: dai-link uses frame clock inversion, for details see simple-card.yaml.
+
+ bitclock-inversion:
+ description: dai-link uses bit clock inversion, for details see simple-card.yaml.
+
+ mclk-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: main clock id, specific for each card configuration.
+
+ mux-int-port:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [1, 2, 7]
+ description: The internal port of the i.MX audio muxer (AUDMUX)
+
+ mux-ext-port:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [3, 4, 5, 6]
+ description: The external port of the i.MX audio muxer
+
+ ssi-controller:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: The phandle of an CPU DAI controller
+
+required:
+ - compatible
+ - model
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ sound-cs42888 {
+ compatible = "fsl,imx-audio-cs42888";
+ model = "cs42888-audio";
+ audio-cpu = <&esai>;
+ audio-asrc = <&asrc>;
+ audio-codec = <&cs42888>;
+ audio-routing =
+ "Line Out Jack", "AOUT1L",
+ "Line Out Jack", "AOUT1R",
+ "Line Out Jack", "AOUT2L",
+ "Line Out Jack", "AOUT2R",
+ "Line Out Jack", "AOUT3L",
+ "Line Out Jack", "AOUT3R",
+ "Line Out Jack", "AOUT4L",
+ "Line Out Jack", "AOUT4R",
+ "AIN1L", "Line In Jack",
+ "AIN1R", "Line In Jack",
+ "AIN2L", "Line In Jack",
+ "AIN2R", "Line In Jack";
+ };
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [v10,20/27] drm/connector: hdmi: Add Infoframes generation
From: Maxime Ripard @ 2024-03-22 10:31 UTC (permalink / raw)
To: Sui Jingfeng
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Daniel Vetter,
Jonathan Corbet, Sandy Huang, Heiko Stübner, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Hans Verkuil, Sebastian Wick,
Ville Syrjälä, dri-devel, linux-arm-kernel, linux-doc,
linux-kernel, linux-media, linux-rockchip, linux-sunxi
In-Reply-To: <07125064-2a78-4515-bb48-655f2aec140f@linux.dev>
[-- Attachment #1.1: Type: text/plain, Size: 1792 bytes --]
Hi,
On Fri, Mar 22, 2024 at 05:53:07AM +0800, Sui Jingfeng wrote:
> Hi,
>
>
> On 2024/3/21 23:29, Maxime Ripard wrote:
> > Infoframes in KMS is usually handled by a bunch of low-level helpers
> > that require quite some boilerplate for drivers. This leads to
> > discrepancies with how drivers generate them, and which are actually
> > sent.
> >
> > Now that we have everything needed to generate them in the HDMI
> > connector state, we can generate them in our common logic so that
> > drivers can simply reuse what we precomputed.
> >
> > Signed-off-by: Maxime Ripard <mripard@kernel.org>
> > ---
> > drivers/gpu/drm/Kconfig | 1 +
> > drivers/gpu/drm/drm_atomic_state_helper.c | 338 +++++++++++++++++++++
> > drivers/gpu/drm/drm_connector.c | 14 +
> > .../gpu/drm/tests/drm_atomic_state_helper_test.c | 1 +
> > drivers/gpu/drm/tests/drm_connector_test.c | 12 +
> > include/drm/drm_atomic_state_helper.h | 8 +
> > include/drm/drm_connector.h | 109 +++++++
> > 7 files changed, 483 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> > index 16029435b750..3d3193c7aa5f 100644
> > --- a/drivers/gpu/drm/Kconfig
> > +++ b/drivers/gpu/drm/Kconfig
> > @@ -97,10 +97,11 @@ config DRM_KUNIT_TEST
> > If in doubt, say "N".
> > config DRM_KMS_HELPER
> > tristate
> > depends on DRM
> > + select DRM_DISPLAY_HDMI_HELPER
>
> Should we select DRM_DISPLAY_HELPER here? Otherwise there will have
> some compile error emerged with default config.
Which default config are you talking about? This compiles fine with all
drm-misc defconfig, x86 defconfig and allmodconfig.
Maxime
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 0/4] Update Energy Model after chip binning adjusted voltages
From: Lukasz Luba @ 2024-03-22 10:32 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
Hi all,
This is a follow-up patch aiming to add EM modification due to chip binning.
The first RFC and the discussion can be found here [1].
It uses Exynos chip driver code as a 1st user. The EM framework has been
extended to handle this use case easily, when the voltage has been changed
after setup. On my Odroid-xu4 in some OPPs I can observe ~20% power difference.
According to that data in driver tables it could be up to ~29%.
This chip binning is applicable to a lot of SoCs, so the EM framework should
make it easy to update. It uses the existing OPP and DT information to
re-calculate the new power values.
Changes:
v2:
- removed 'ret' from error message which wasn't initialized (Christian)
v1:
- exported the OPP calculation function from the OPP/OF so it can be
used from EM fwk (Viresh)
- refactored EM updating function to re-use common code
- added new EM function which can be used by chip device drivers which
modify the voltage in OPPs
RFC is at [1]
Regards,
Lukasz Luba
[1] https://lore.kernel.org/lkml/20231220110339.1065505-1-lukasz.luba@arm.com/
Lukasz Luba (4):
OPP: OF: Export dev_opp_pm_calc_power() for usage from EM
PM: EM: Change the em_adjust_new_capacity() to re-use code
PM: EM: Add em_dev_update_chip_binning()
soc: samsung: exynos-asv: Update Energy Model after adjusting voltage
drivers/opp/of.c | 17 +++--
drivers/soc/samsung/exynos-asv.c | 11 +++-
include/linux/energy_model.h | 5 ++
include/linux/pm_opp.h | 8 +++
kernel/power/energy_model.c | 109 +++++++++++++++++++++++++------
5 files changed, 125 insertions(+), 25 deletions(-)
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 1/4] OPP: OF: Export dev_opp_pm_calc_power() for usage from EM
From: Lukasz Luba @ 2024-03-22 10:32 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <20240322103221.47594-1-lukasz.luba@arm.com>
There are device drivers which can modify voltage values for OPPs. It
could be due to the chip binning and those drivers have specific chip
knowledge about it. This adjustment can happen after Energy Model is
registered, thus EM can have stale data about power.
Export dev_opp_pm_calc_power() which can be used by Energy Model to
calculate new power with the new voltage for OPPs.
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
---
drivers/opp/of.c | 17 ++++++++++++-----
include/linux/pm_opp.h | 8 ++++++++
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index f9f0b22bccbb4..282eb5966fd03 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -1494,20 +1494,26 @@ _get_dt_power(struct device *dev, unsigned long *uW, unsigned long *kHz)
return 0;
}
-/*
- * Callback function provided to the Energy Model framework upon registration.
+/**
+ * dev_pm_opp_calc_power() - Calculate power value for device with EM
+ * @dev : Device for which an Energy Model has to be registered
+ * @uW : New power value that is calculated
+ * @kHz : Frequency for which the new power is calculated
+ *
* This computes the power estimated by @dev at @kHz if it is the frequency
* of an existing OPP, or at the frequency of the first OPP above @kHz otherwise
* (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled
* frequency and @uW to the associated power. The power is estimated as
* P = C * V^2 * f with C being the device's capacitance and V and f
* respectively the voltage and frequency of the OPP.
+ * It is also used as a callback function provided to the Energy Model
+ * framework upon registration.
*
* Returns -EINVAL if the power calculation failed because of missing
* parameters, 0 otherwise.
*/
-static int __maybe_unused _get_power(struct device *dev, unsigned long *uW,
- unsigned long *kHz)
+int dev_pm_opp_calc_power(struct device *dev, unsigned long *uW,
+ unsigned long *kHz)
{
struct dev_pm_opp *opp;
struct device_node *np;
@@ -1544,6 +1550,7 @@ static int __maybe_unused _get_power(struct device *dev, unsigned long *uW,
return 0;
}
+EXPORT_SYMBOL_GPL(dev_pm_opp_calc_power);
static bool _of_has_opp_microwatt_property(struct device *dev)
{
@@ -1619,7 +1626,7 @@ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus)
goto failed;
}
- EM_SET_ACTIVE_POWER_CB(em_cb, _get_power);
+ EM_SET_ACTIVE_POWER_CB(em_cb, dev_pm_opp_calc_power);
register_em:
ret = em_dev_register_perf_domain(dev, nr_opp, &em_cb, cpus, true);
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 065a47382302c..31370deb9905f 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -476,6 +476,8 @@ struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp);
int of_get_required_opp_performance_state(struct device_node *np, int index);
int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_table *opp_table);
int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus);
+int dev_pm_opp_calc_power(struct device *dev, unsigned long *uW,
+ unsigned long *kHz);
static inline void dev_pm_opp_of_unregister_em(struct device *dev)
{
em_dev_unregister_perf_domain(dev);
@@ -539,6 +541,12 @@ static inline void dev_pm_opp_of_unregister_em(struct device *dev)
{
}
+static inline int dev_pm_opp_calc_power(struct device *dev, unsigned long *uW,
+ unsigned long *kHz)
+{
+ return -EOPNOTSUPP;
+}
+
static inline int of_get_required_opp_performance_state(struct device_node *np, int index)
{
return -EOPNOTSUPP;
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 2/4] PM: EM: Change the em_adjust_new_capacity() to re-use code
From: Lukasz Luba @ 2024-03-22 10:32 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <20240322103221.47594-1-lukasz.luba@arm.com>
There is going to be a new update function addressing chip binning.
Therefore, some common code which can be refactored and called from
upcoming changes and em_adjust_new_capacity(). In this way the code
duplication can be avoided.
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
---
kernel/power/energy_model.c | 58 +++++++++++++++++++++++++------------
1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 9e1c9aa399ea9..6960dd7393b2d 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -674,23 +674,15 @@ void em_dev_unregister_perf_domain(struct device *dev)
}
EXPORT_SYMBOL_GPL(em_dev_unregister_perf_domain);
-/*
- * Adjustment of CPU performance values after boot, when all CPUs capacites
- * are correctly calculated.
- */
-static void em_adjust_new_capacity(struct device *dev,
- struct em_perf_domain *pd,
- u64 max_cap)
+static struct em_perf_table __rcu *em_table_dup(struct em_perf_domain *pd)
{
struct em_perf_table __rcu *em_table;
struct em_perf_state *ps, *new_ps;
- int ret, ps_size;
+ int ps_size;
em_table = em_table_alloc(pd);
- if (!em_table) {
- dev_warn(dev, "EM: allocation failed\n");
- return;
- }
+ if (!em_table)
+ return NULL;
new_ps = em_table->state;
@@ -702,24 +694,52 @@ static void em_adjust_new_capacity(struct device *dev,
rcu_read_unlock();
- em_init_performance(dev, pd, new_ps, pd->nr_perf_states);
- ret = em_compute_costs(dev, new_ps, NULL, pd->nr_perf_states,
+ return em_table;
+}
+
+static int em_recalc_and_update(struct device *dev, struct em_perf_domain *pd,
+ struct em_perf_table __rcu *em_table)
+{
+ int ret;
+
+ ret = em_compute_costs(dev, em_table->state, NULL, pd->nr_perf_states,
pd->flags);
- if (ret) {
- dev_warn(dev, "EM: compute costs failed\n");
- return;
- }
+ if (ret)
+ goto free_em_table;
ret = em_dev_update_perf_domain(dev, em_table);
if (ret)
- dev_warn(dev, "EM: update failed %d\n", ret);
+ goto free_em_table;
/*
* This is one-time-update, so give up the ownership in this updater.
* The EM framework has incremented the usage counter and from now
* will keep the reference (then free the memory when needed).
*/
+free_em_table:
em_table_free(em_table);
+ return ret;
+}
+
+/*
+ * Adjustment of CPU performance values after boot, when all CPUs capacites
+ * are correctly calculated.
+ */
+static void em_adjust_new_capacity(struct device *dev,
+ struct em_perf_domain *pd,
+ u64 max_cap)
+{
+ struct em_perf_table __rcu *em_table;
+
+ em_table = em_table_dup(pd);
+ if (!em_table) {
+ dev_warn(dev, "EM: allocation failed\n");
+ return;
+ }
+
+ em_init_performance(dev, pd, em_table->state, pd->nr_perf_states);
+
+ em_recalc_and_update(dev, pd, em_table);
}
static void em_check_capacity_update(void)
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 3/4] PM: EM: Add em_dev_update_chip_binning()
From: Lukasz Luba @ 2024-03-22 10:32 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <20240322103221.47594-1-lukasz.luba@arm.com>
Add a function which allows to modify easily the EM after the new voltage
information is available. The device drivers for the chip can adjust
the voltage values after setup. The voltage for the same frequency in OPP
can be different due to chip binning. The voltage impacts the power usage
and the EM power values can be updated to reflect that.
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
---
include/linux/energy_model.h | 5 ++++
kernel/power/energy_model.c | 51 ++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
index 770755df852f1..d30d67c2f07cf 100644
--- a/include/linux/energy_model.h
+++ b/include/linux/energy_model.h
@@ -172,6 +172,7 @@ struct em_perf_table __rcu *em_table_alloc(struct em_perf_domain *pd);
void em_table_free(struct em_perf_table __rcu *table);
int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
int nr_states);
+int em_dev_update_chip_binning(struct device *dev);
/**
* em_pd_get_efficient_state() - Get an efficient performance state from the EM
@@ -387,6 +388,10 @@ int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
{
return -EINVAL;
}
+static inline int em_dev_update_chip_binning(struct device *dev)
+{
+ return -EINVAL;
+}
#endif
#endif
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 6960dd7393b2d..1494a909844a4 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -808,3 +808,54 @@ static void em_update_workfn(struct work_struct *work)
{
em_check_capacity_update();
}
+
+/**
+ * em_dev_update_chip_binning() - Update Energy Model with new values after
+ * the new voltage information is present in the OPPs.
+ * @dev : Device for which the Energy Model has to be updated.
+ *
+ * This function allows to update easily the EM with new values available in
+ * the OPP framework and DT. It can be used after the chip has been properly
+ * verified by device drivers and the voltages adjusted for the 'chip binning'.
+ * It uses the "dynamic-power-coefficient" DT property to calculate the power
+ * values for EM. For power calculation it uses the new adjusted voltage
+ * values known for OPPs, which might be changed after boot.
+ */
+int em_dev_update_chip_binning(struct device *dev)
+{
+ struct em_perf_table __rcu *em_table;
+ struct em_perf_domain *pd;
+ int i, ret;
+
+ if (IS_ERR_OR_NULL(dev))
+ return -EINVAL;
+
+ pd = em_pd_get(dev);
+ if (!pd) {
+ dev_warn(dev, "Couldn't find Energy Model %d\n", ret);
+ return -EINVAL;
+ }
+
+ em_table = em_table_dup(pd);
+ if (!em_table) {
+ dev_warn(dev, "EM: allocation failed\n");
+ return -ENOMEM;
+ }
+
+ /* Update power values which might change due to new voltage in OPPs */
+ for (i = 0; i < pd->nr_perf_states; i++) {
+ unsigned long freq = em_table->state[i].frequency;
+ unsigned long power;
+
+ ret = dev_pm_opp_calc_power(dev, &power, &freq);
+ if (ret) {
+ em_table_free(em_table);
+ return ret;
+ }
+
+ em_table->state[i].power = power;
+ }
+
+ return em_recalc_and_update(dev, pd, em_table);
+}
+EXPORT_SYMBOL_GPL(em_dev_update_chip_binning);
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 4/4] soc: samsung: exynos-asv: Update Energy Model after adjusting voltage
From: Lukasz Luba @ 2024-03-22 10:32 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <20240322103221.47594-1-lukasz.luba@arm.com>
When the voltage for OPPs is adjusted there is a need to also update
Energy Model framework. The EM data contains power values which depend
on voltage values. The EM structure is used for thermal (IPA governor)
and in scheduler task placement (EAS) so it should reflect the real HW
model as best as possible to operate properly.
Based on data on Exynos5422 ASV tables the maximum power difference might
be ~29%. An Odroid-XU4 (with a random sample SoC in this chip lottery)
showed power difference for some OPPs ~20%. Therefore, it's worth to
update the EM.
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
---
drivers/soc/samsung/exynos-asv.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
index d60af8acc3916..bd6bb2cab2cd8 100644
--- a/drivers/soc/samsung/exynos-asv.c
+++ b/drivers/soc/samsung/exynos-asv.c
@@ -11,6 +11,7 @@
#include <linux/cpu.h>
#include <linux/device.h>
+#include <linux/energy_model.h>
#include <linux/errno.h>
#include <linux/of.h>
#include <linux/pm_opp.h>
@@ -97,9 +98,17 @@ static int exynos_asv_update_opps(struct exynos_asv *asv)
last_opp_table = opp_table;
ret = exynos_asv_update_cpu_opps(asv, cpu);
- if (ret < 0)
+ if (!ret) {
+ /*
+ * When the voltage for OPPs successfully
+ * changed, update the EM power values to
+ * reflect the reality and not use stale data
+ */
+ em_dev_update_chip_binning(cpu);
+ } else {
dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
cpuid);
+ }
}
dev_pm_opp_put_opp_table(opp_table);
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH 0/0] (proposed?) Add ACPI binding to Rockchip RK3xxx I2C bus
From: Jonathan Cameron @ 2024-03-22 10:35 UTC (permalink / raw)
To: Shimrra Shai
Cc: linux-kernel, linux-rockchip, linux-arm-kernel, heiko,
max.schwarz, niyas.sait
In-Reply-To: <20240321173447.15660-1-shimmyshai00@gmail.com>
On Thu, 21 Mar 2024 12:34:47 -0500
Shimrra Shai <shimmyshai00@gmail.com> wrote:
> Hi! I have been contributing to a firmware project for Rockchip RK3588-
> based board using the TianoCore EDK2 firmware development kit, at
> https://github.com/edk2-porting/edk2-rk3588. I am seeking to get it
> possible to seamlessly boot mainline kernels using it on these platforms,
> especially given how that mainline support for this platform has progressed
> far since its debut. Since this is not a firmware from a board vendor, I'm
> actually not really sure how to best interface or integrate its development
> with the Linux kernel community. Particularly the question of Device Tree
> Blob (DTB) vs. ACPI binding for configuration bindings, for which previous
> discussions have always seemed to center around situations where the
> firmware was not controllable by the kernel developer, but that is not the
> case with this situation here and now. However, I've found, particularly
> given the firmware has an HDMI driver that the currnet kernel does not,
> that I am able to get a quicker path to mainline boot on this platform
> going through the ACPI route, which inspires the following patch.
>
> In particular, I found one small issue that obstructs immediate direct
> booting of the off-the-shelf downloaded 6.8.x kernel series on my platform
> (Firefly ITX-3588J, with no mainline device tree blob support) which is
> that the I2C bus lacks code to configure it in the ACPI boot mode. The
> firmware came with ACPI bindings for it, nonetheless, and so this patch
> acts to enable and document those bindings for future use.
It would be good to highlight in this description what is missing for
doing a standard ACPI binding and not using any specific hacks in the
driver (get clocks as normal etc).
There are ACPI clock bindings, but Linux doesn't support the yet (I think?)
See ACPICA commit
https://github.com/acpica/acpica/commit/661feab5ee01a34af95a389a18c82e79f1aba05a
I've seen prototype code but was a while back. I'd like to see that
work compled rather than having every driver need to paper over the hole.
The alias is a different question that needs to be addressed.
If this is a common pattern, push it up in to the i2c core, not
a specific driver. I see there is already code related to that
in i2c_add_adapter - that just wants an ACPI option.
Jonathan
>
> Signed-off-by: Shimrra Shai <shimmyshai00@gmail.com>
> ---
>
> Documentation/firmware-guide/acpi/dsd/soc/general.rst | 32 ++++++++
> Documentation/firmware-guide/acpi/dsd/soc/soc-i2c.rst | 50 ++++++++++++
> drivers/i2c/busses/i2c-rk3x.c | 105 +++++++++++++++++++++++---
> 3 files changed, 177 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/firmware-guide/acpi/dsd/soc/general.rst b/Documentation/firmware-guide/acpi/dsd/soc/general.rst
> new file mode 100644
> index 000000000..d21ccad2d
> --- /dev/null
> +++ b/Documentation/firmware-guide/acpi/dsd/soc/general.rst
> @@ -0,0 +1,32 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +==========================================
> +System-on-Chip (SoC) facility descriptions
> +==========================================
> +
> +These documents describe how to create ACPI profiles for devices compsed into
composed
Spell check the whole thing.
> +system-on-chip (SoC) architectures. Currently, we only describe the options
> +availed in the _DSD block for select platforms; other considerations are not
> +yet applied. The inspiration for these documents are based around the advent
> +(as of March 2024) of hefty, non-Apple ARM SoC systems such as the Rockchip
> +RK3588 and newer chips that have desktop-like performance and thus are prime
> +candidates for a UEFI-based desktop-like boot system with the goal being to
> +deliver the same user-friendly ease of loading operating systems as on the
> +Intel x86 sphere. Open-source UEFI-based firmware engines, such as TianoCore
> +[1], mean it is possible on such platforms for the open-source developer to
> +control both firmware and kernel simultaneously, which is not the case for
> +the situation with Intel-based PC boards where boards are provided with pre-
> +baked, vendor-selected and opaque firmwares.
> +
> +The description of ACPI usage here is not meant to suggest that ACPI replace
> +Deviec Tree altogether for such SoCs; rather, we recognize that given they
> +often will have a variety of applications that may include embedded usage where
> +that more hard-wired boot loader setups such as U-Boot still shine, the
> +maintenance of ACPI and DTB-based configuration options should be in parallel,
> +and it may be possible for the same firmware to deploy both options.
> +
> +References
> +==========
> +
> +[1] EDK2-RK3588 port of TianoCore EDK2 firmware.
> + https://github.com/edk2-porting/edk2-rk3588
> diff --git a/Documentation/firmware-guide/acpi/dsd/soc/soc-i2c.rst b/Documentation/firmware-guide/acpi/dsd/soc/soc-i2c.rst
> new file mode 100644
> index 000000000..47ff69db4
> --- /dev/null
> +++ b/Documentation/firmware-guide/acpi/dsd/soc/soc-i2c.rst
> @@ -0,0 +1,50 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +=================
> +I2C buses on SoCs
> +=================
> +
> +This document describes the ACPI _DSD parameters currently being employed for
> +Inter-Integrated Circuit (I2C) buses in the Linux kernel. It is based off the
> +conventions used in the Rockchip RK3588 firmware project [1], which is also the
> +first SoC documented here.
> +
> +General considerations
> +======================
> +
> +For general use, we recommend indicating I2C busses in the ACPI firmware table
> +in the following manner. First, they should be named I2Cx, where "x" is the bus
> +index, and that index should also be used for the _UID component, e.g. on
> +Rockchip RK3588 (see below), we use:
> +
> + Device (I2Cx) {
> + Name (_HID, "RKCP3001")
> + Name (_CID, "PRP0001")
That implies that the kernel can cope with the device tree wrapped up in
ACPI path. If that's the case, why do you need RKCP3001 as you can
match on the compatible?
> + Name (_UID, x)
> + Name (_CCA, 0)
> +
> + ...
> + }
> +
> +Interrupts should be specified in the usual ACPI manner. Parameters specific to
> +the Rockchip and I2C devices are indicated in the _DSD block as given below.
> +The parameters are a curated selection from the Device Tree Blob (DTB)
> +representation.
> +
> +_DSD parameters for different SoCs
> +==================================
> +
> +Rockchip RK3588
> +---------------
> +
> +The following parameters are accepted for the I2C on Rockchip RK3588.
> +
> +- i2c,clk-rate Describe the pclk rate for the I2C bus, in Hz.
> +- rockchip,bclk Describe the bclk rate for the I2C bus, in Hz.
> +
> +References
> +==========
> +
> +[1] EDK2-RK3588 port of TianoCore EDK2 firmware.
> + https://github.com/edk2-porting/edk2-rk3588
> +
> diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
> index 086fdf262..5a5e1d551 100644
> --- a/drivers/i2c/busses/i2c-rk3x.c
> +++ b/drivers/i2c/busses/i2c-rk3x.c
> @@ -19,6 +19,9 @@
> #include <linux/of_irq.h>
> #include <linux/spinlock.h>
> #include <linux/clk.h>
> +#ifdef CONFIG_ACPI
> +#include <linux/clk-provider.h>
> +#endif
> #include <linux/wait.h>
> #include <linux/mfd/syscon.h>
> #include <linux/regmap.h>
> @@ -1235,6 +1238,15 @@ static const struct of_device_id rk3x_i2c_match[] = {
> };
> MODULE_DEVICE_TABLE(of, rk3x_i2c_match);
>
> +#ifdef CONFIG_ACPI
> +/* for RK3588 and at least when loaded with EDK2-RK3588 Tianocore firmware */
> +static const struct acpi_device_id rk3x_i2c_acpi_match[] = {
> + { .id = "RKCP3001", .driver_data = (kernel_ulong_t)&rk3399_soc_data },
> + { },
> +};
> +MODULE_DEVICE_TABLE(acpi, rk3x_i2c_acpi_match);
> +#endif
> +
> static int rk3x_i2c_probe(struct platform_device *pdev)
> {
> struct device_node *np = pdev->dev.of_node;
> @@ -1243,6 +1255,10 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
> int ret = 0;
> int bus_nr;
> u32 value;
> +#ifdef CONFIG_ACPI
> + u64 value64;
> + char clk_name[20];
> +#endif
> int irq;
> unsigned long clk_rate;
>
> @@ -1250,8 +1266,12 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
> if (!i2c)
> return -ENOMEM;
>
> - match = of_match_node(rk3x_i2c_match, np);
> - i2c->soc_data = match->data;
> + if (acpi_disabled) {
> + match = of_match_node(rk3x_i2c_match, np);
> + i2c->soc_data = match->data;
> + } else {
> + i2c->soc_data = device_get_match_data(&pdev->dev);
> + }
>
> /* use common interface to get I2C timing properties */
> i2c_parse_fw_timings(&pdev->dev, &i2c->t, true);
> @@ -1266,6 +1286,9 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
>
> i2c->dev = &pdev->dev;
>
> + if (!acpi_disabled)
> + ACPI_COMPANION_SET(&i2c->adap.dev, ACPI_COMPANION(&pdev->dev));
> +
> spin_lock_init(&i2c->lock);
> init_waitqueue_head(&i2c->wait);
>
> @@ -1273,8 +1296,25 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
> if (IS_ERR(i2c->regs))
> return PTR_ERR(i2c->regs);
>
> - /* Try to set the I2C adapter number from dt */
> - bus_nr = of_alias_get_id(np, "i2c");
> + if (acpi_disabled) {
> + /* Try to set the I2C adapter number from dt */
> + bus_nr = of_alias_get_id(np, "i2c");
> + } else {
> + ret = acpi_dev_uid_to_integer(ACPI_COMPANION(&pdev->dev),
> + &value64);
> + if (ret) {
> + dev_err(&pdev->dev, "Cannot retrieve UID\n");
> + return ret;
> + }
> +
> + if (value64 < INT_MAX) {
> + bus_nr = (int) value64;
> + } else {
> + /* shouldn't happen!!! */
> + dev_err(&pdev->dev, "Too big UID\n");
> + return -EINVAL;
> + }
> + }
>
> /*
> * Switch to new interface if the SoC also offers the old one.
> @@ -1325,13 +1365,58 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, i2c);
>
> - if (i2c->soc_data->calc_timings == rk3x_i2c_v0_calc_timings) {
> - /* Only one clock to use for bus clock and peripheral clock */
> - i2c->clk = devm_clk_get(&pdev->dev, NULL);
> - i2c->pclk = i2c->clk;
> + if (acpi_disabled) {
> + if (i2c->soc_data->calc_timings == rk3x_i2c_v0_calc_timings) {
> + /* Only one clock to use for bus clock and peripheral
> + * clock
> + */
> + i2c->clk = devm_clk_get(&pdev->dev, NULL);
> + i2c->pclk = i2c->clk;
> + } else {
> + i2c->clk = devm_clk_get(&pdev->dev, "i2c");
> + i2c->pclk = devm_clk_get(&pdev->dev, "pclk");
> + }
> } else {
> - i2c->clk = devm_clk_get(&pdev->dev, "i2c");
> - i2c->pclk = devm_clk_get(&pdev->dev, "pclk");
> + if (i2c->soc_data->calc_timings != rk3x_i2c_v0_calc_timings) {
> + u32 bclkrate = 0;
> + u32 pclkrate = 0;
> +
> + device_property_read_u32(&pdev->dev, "rockchip,bclk",
> + &bclkrate);
> + device_property_read_u32(&pdev->dev, "i2c,clk-rate",
> + &pclkrate);
> +
> + if (bclkrate != 0) {
> + sprintf(clk_name, "rockchip,i2c-clk.%d", bus_nr);
> + i2c->clk = clk_register_fixed_rate(&pdev->dev,
> + clk_name,
> + NULL,
> + 0, bclkrate);
> + dev_dbg(&pdev->dev,
> + "registered i2c clk at %u Hz\n",
> + bclkrate);
> + }
> +
> + if (pclkrate != 0) {
> + sprintf(clk_name, "rockchip,i2c-pclk.%d",
> + bus_nr);
> + i2c->pclk = clk_register_fixed_rate(&pdev->dev,
> + clk_name,
> + NULL, 0,
> + pclkrate);
> + dev_dbg(&pdev->dev,
> + "registered i2c pclk at %u Hz\n",
> + pclkrate);
> + }
> + } else {
> + /* NB: currently not expected w/UEFI firmware given
> + * these are not super performant RK3xxx
> + */
> + dev_err(&pdev->dev,
> + "ACPI not supported for this RK3xxx\n");
> +
> + return -EINVAL;
> + }
> }
>
> if (IS_ERR(i2c->clk))
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V3 2/2] cpufreq: scmi: Register for limit change notifications
From: Lukasz Luba @ 2024-03-22 10:45 UTC (permalink / raw)
To: Sibi Sankar
Cc: sudeep.holla, Cristian Marussi, linux-arm-kernel, pierre.gondois,
dietmar.eggemann, morten.rasmussen, viresh.kumar, rafael,
linux-pm, linux-kernel, quic_mdtipton, linux-arm-msm
In-Reply-To: <08018d07-79cf-cebd-aba5-214afbc5001d@quicinc.com>
Hi Sibi,
On 3/1/24 05:31, Sibi Sankar wrote:
>
>
> On 2/29/24 19:45, Lukasz Luba wrote:
>>
>>
>> On 2/29/24 12:11, Cristian Marussi wrote:
>>> On Thu, Feb 29, 2024 at 11:45:41AM +0000, Lukasz Luba wrote:
>>>>
>>>>
>>>> On 2/29/24 11:28, Cristian Marussi wrote:
>>>>> On Thu, Feb 29, 2024 at 10:22:39AM +0000, Lukasz Luba wrote:
>>>>>>
>>>>>>
>>>>>> On 2/29/24 09:59, Lukasz Luba wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 2/28/24 17:00, Sibi Sankar wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 2/28/24 18:54, Lukasz Luba wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 2/27/24 18:16, Sibi Sankar wrote:
>>>>>>>>>> Register for limit change notifications if supported and use
>>>>>>>>>> the throttled
>>>>>>>>>> frequency from the notification to apply HW pressure.
>>>>>>>>
>>>>>>>> Lukasz,
>>>>>>>>
>>>>>>>> Thanks for taking time to review the series!
>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
>>>>>>>>>> ---
>>>>>>>>>>
>>>>>>>>>> v3:
>>>>>>>>>> * Sanitize range_max received from the notifier. [Pierre]
>>>>>>>>>> * Update commit message.
>>>>>>>>>>
>>>>>>>>>> � drivers/cpufreq/scmi-cpufreq.c | 29
>>>>>>>>>> ++++++++++++++++++++++++++++-
>>>>>>>>>> � 1 file changed, 28 insertions(+), 1 deletion(-)
>>>>>>>>>>
>>>>>>>>>> diff --git a/drivers/cpufreq/scmi-cpufreq.c
>>>>>>>>>> b/drivers/cpufreq/scmi-cpufreq.c
>>>>>>>>>> index 76a0ddbd9d24..78b87b72962d 100644
>>>>>>>>>> --- a/drivers/cpufreq/scmi-cpufreq.c
>>>>>>>>>> +++ b/drivers/cpufreq/scmi-cpufreq.c
>>>>>>>>>> @@ -25,9 +25,13 @@ struct scmi_data {
>>>>>>>>>> ����� int domain_id;
>>>>>>>>>> ����� int nr_opp;
>>>>>>>>>> ����� struct device *cpu_dev;
>>>>>>>>>> +��� struct cpufreq_policy *policy;
>>>>>>>>>> ����� cpumask_var_t opp_shared_cpus;
>>>>>>>>>> +��� struct notifier_block limit_notify_nb;
>>>>>>>>>> � };
>>>>>>>>>> +const struct scmi_handle *handle;
>>>>>>>
>>>>>>> I've missed this bit here.
>>>>>>
>>>>>> So for this change we actually have to ask Cristian or Sudeep
>>>>>> because I'm not sure if we have only one 'handle' instance
>>>>>> for all cpufreq devices.
>>>>>>
>>>>>> If we have different 'handle' we cannot move it to the
>>>>>> global single pointer.
>>>>>>
>>>>>> Sudeep, Cristian what do you think?
>>>>>
>>>>> I was just replying noticing this :D .... since SCMI drivers can be
>>>>> probed multiple times IF you defined multiple scmi top nodes in
>>>>> your DT
>>>>> containing the same protocol nodes, they receive a distinct
>>>>> sdev/handle/ph
>>>>> for each probe...so any attempt to globalize these wont work...BUT...
>>>>>
>>>>> ...this is a bit of a weird setup BUT it is not against the spec
>>>>> and it can
>>>>> be used to parallelize more the SCMI accesses to disjont set of
>>>>> resources
>>>>> within the same protocol (a long story here...) AND this type of
>>>>> setup is
>>>>> something that it is already used by some other colleagues of Sibi
>>>>> working
>>>>> on a different line of products (AFAIK)...
>>>>>
>>>>> So, for these reasons, usually, all the other SCMI drivers have
>>>>> per-instance
>>>>> non-global references to handle/sdev/ph....
>>>>>
>>>>> ...having said that, thought, looking at the structure of CPUFReq
>>>>> drivers, I am not sure that they can stand such a similar setup
>>>>> where multiple instances of this same driver are probed
>>>>>
>>>>> .... indeed the existent *ph refs above is already global....so it
>>>>> wont already
>>>>> work anyway in case of multiple instances now...
>>>>>
>>>>> ...and if I look at how CPUFreq expects the signature of
>>>>> scmi_cpufreq_get_rate()
>>>>> to be annd how it is implemented now using the global *ph
>>>>> reference, it is
>>>>> clearly already not working cleanly on a multi-instance setup...
>>>>>
>>>>> ...now...I can imagine how to (maybe) fix the above removing the
>>>>> globals and
>>>>> fixing this, BUT the question, more generally, is CPUFreq supposed
>>>>> to work at all in
>>>>> this multi-probed mode of operation ?
>>>>> Does it even make sense to be able to support this in CPUFREQ ?
>>>>>
>>>>> (as an example in cpufreq,c there is static global cpufreq_driver
>>>>> pointing to the arch-specific configured driver BUT that also holds
>>>>> some .driver_data AND that cleraly wont be instance specific if you
>>>>> probe multiple times and register with CPUFreq multiple times...)
>>>>>
>>>>> More questions than answers here :D
>>>>>
>>>>
>>>> Thanks Cristian for instant response. Yes, indeed now we have more
>>>> questions :) (which is good). But that's good description of the
>>>> situation.
>>>>
>>>> So lets consider a few option what we could do now:
>>>> 1. Let Sibi add another global state the 'handle' but add
>>>> a BUG_ON() or WARN_ON() in the probe path if the next
>>>> 'handle' instance is different than already set in global.
>>>> This would simply mean that we don't support (yet)
>>>> such configuration in a platform. As you said, we
>>>> already have the *ph global, so maybe such platforms
>>>> with multiple instances for this particular cpufreq and
>>>> performance protocol don't exist yet.
>>>
>>> Yes this is the quickst way (and a WARN_ON() is better I'd say) but
>>> there
>>> are similar issues of "unicity" currently already with another vendor
>>> SCMI
>>> drivers and custom protocol currently under review, so I was thinking to
>>> add a new common mechanism in SCMI to handle this ... not thought about
>>> this really in depth and I want to chat with Sudeep about this...
>>>
>>>> 2. Ask Sibi to wait with this change, till we refactor the
>>>> exiting driver such that it could support easily those
>>>> multiple instances. Then pick up this patch set.
>>>> Although, we would also like to have those notifications from our
>>>> Juno SCP reference FW, so the feature is useful.
>>>> 3. Ask Sibi to refactor his patch to somehow get the 'handle'
>>>> in different way, using exiting code and not introduce this global.
>>>>
>>>
>>>> IHMO we could do this in steps: 1. and then 2. When
>>>> we create some mock platform to test this refactoring we can
>>>> start cleaning it.
>
> I should be able to volunteer a platform to test against when
> we have things ready.
>
>>>>
>>>
>>> Both of these options really beg an answer to my original previous q
>>> question...if we somehow enable this multi-probe support in the
>>> scmi-cpufreq.c driver by avoiding glbals refs, does this work at all in
>>> the context of CPUFreq ?
>>
>> I don't know yet.
>>
>>>
>>> ...or it is just that CPUFreq cannot handle such a configuration (and
>>> maybe dont want to) and so the only solution here is just 1. at first
>>> and
>>> then a common refined mechanism (as mentioned above) to ensure this
>>> "unicity"
>>> of the probes for some drivers ?
>>
>> This sounds reasonable.
>>
>>>
>>> I'm not familiar enough to grasp if this "multi-probed" mode of
>>> operation is
>>> allowed/supported by CPUFreq and, more important, if it makes any sense
>>> at all to be a supported mode...
>>>
>>
>> OK, let me check some stuff in the code and think for a while on that.
>> Thanks Cristian!
>>
>> Sibi, please give me a few days. In the meantime you can continue
>> on the 'boost' patch set probably.
>
> sure, thanks. I've plenty things to send out so no hurry ;)
>
> -Sibi
>
I've went through the cpufreq. It's quite complicated how those
policies, cpus, drivers are setup. Although, IHMO we should be
safe with you current proposal in this patch.
As we discussed with Cristian, we can take that approach further.
Therefore, you can add:
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Regards,
Lukasz
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] drm/stm: dsi: relax mode_valid clock tolerance
From: Sean Nyekjaer @ 2024-03-22 10:47 UTC (permalink / raw)
To: Yannick Fertre, Raphael Gallais-Pou, Philippe Cornu,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Daniel Vetter, Maxime Coquelin, Alexandre Torgue, Robert Foss,
Antonio Borneo
Cc: Sean Nyekjaer, dri-devel, linux-stm32, linux-arm-kernel,
linux-kernel
When using the DSI interface via DSI2LVDS bridge, it seems a bit harsh
to reguire the requested and the actual px clock to be within
50Hz. A typical LVDS display requires the px clock to be within +-10%.
In case for HDMI .5% tolerance is required.
Fixes: e01356d18273 ("drm/stm: dsi: provide the implementation of mode_valid()")
Signed-off-by: Sean Nyekjaer <sean@geanix.com>
---
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index d5f8c923d7bc..97936b0ef702 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -322,8 +322,6 @@ dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
return 0;
}
-#define CLK_TOLERANCE_HZ 50
-
static enum drm_mode_status
dw_mipi_dsi_stm_mode_valid(void *priv_data,
const struct drm_display_mode *mode,
@@ -375,9 +373,10 @@ dw_mipi_dsi_stm_mode_valid(void *priv_data,
/*
* Filter modes according to the clock value, particularly useful for
* hdmi modes that require precise pixel clocks.
+ * Check that px_clock is within .5% tolerance.
*/
- if (px_clock_hz < target_px_clock_hz - CLK_TOLERANCE_HZ ||
- px_clock_hz > target_px_clock_hz + CLK_TOLERANCE_HZ)
+ if (px_clock_hz < mult_frac(target_px_clock_hz, 995, 1000) ||
+ px_clock_hz > mult_frac(target_px_clock_hz, 1005, 1000))
return MODE_CLOCK_RANGE;
/* sync packets are codes as DSI short packets (4 bytes) */
--
2.44.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [v10,20/27] drm/connector: hdmi: Add Infoframes generation
From: Maxime Ripard @ 2024-03-22 10:57 UTC (permalink / raw)
To: Jani Nikula
Cc: Sui Jingfeng, Maarten Lankhorst, Thomas Zimmermann, David Airlie,
Daniel Vetter, Jonathan Corbet, Sandy Huang, Heiko Stübner,
Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Hans Verkuil,
Sebastian Wick, Ville Syrjälä, dri-devel,
linux-arm-kernel, linux-doc, linux-kernel, linux-media,
linux-rockchip, linux-sunxi
In-Reply-To: <87sf0iliyh.fsf@intel.com>
[-- Attachment #1.1: Type: text/plain, Size: 2282 bytes --]
On Fri, Mar 22, 2024 at 11:22:14AM +0200, Jani Nikula wrote:
> On Fri, 22 Mar 2024, Sui Jingfeng <sui.jingfeng@linux.dev> wrote:
> > Hi,
> >
> >
> > On 2024/3/21 23:29, Maxime Ripard wrote:
> >> Infoframes in KMS is usually handled by a bunch of low-level helpers
> >> that require quite some boilerplate for drivers. This leads to
> >> discrepancies with how drivers generate them, and which are actually
> >> sent.
> >>
> >> Now that we have everything needed to generate them in the HDMI
> >> connector state, we can generate them in our common logic so that
> >> drivers can simply reuse what we precomputed.
> >>
> >> Signed-off-by: Maxime Ripard <mripard@kernel.org>
> >> ---
> >> drivers/gpu/drm/Kconfig | 1 +
> >> drivers/gpu/drm/drm_atomic_state_helper.c | 338 +++++++++++++++++++++
> >> drivers/gpu/drm/drm_connector.c | 14 +
> >> .../gpu/drm/tests/drm_atomic_state_helper_test.c | 1 +
> >> drivers/gpu/drm/tests/drm_connector_test.c | 12 +
> >> include/drm/drm_atomic_state_helper.h | 8 +
> >> include/drm/drm_connector.h | 109 +++++++
> >> 7 files changed, 483 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> >> index 16029435b750..3d3193c7aa5f 100644
> >> --- a/drivers/gpu/drm/Kconfig
> >> +++ b/drivers/gpu/drm/Kconfig
> >> @@ -97,10 +97,11 @@ config DRM_KUNIT_TEST
> >> If in doubt, say "N".
> >>
> >> config DRM_KMS_HELPER
> >> tristate
> >> depends on DRM
> >> + select DRM_DISPLAY_HDMI_HELPER
> >
> > Should we select DRM_DISPLAY_HELPER here? Otherwise there will have some compile error
> > emerged with default config.
>
> Can we stop abusing select instead of adding more selects to paper over
> the issues?
>
> Use select only for non-visible symbols (no prompts anywhere) and for
> symbols with no dependencies.
I don't really have an opinion there, but it looks like all the other
helpers Kconfig symbols are using select everywhere, and I don't really
see how we could turn them into visible symbols with depends on without
breaking a number of defconfig.
Could you expand a bit what you have in mind here?
Maxime
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v10 2/8] PCI: dwc: ep: Add Kernel-doc comments for APIs
From: Niklas Cassel @ 2024-03-22 11:02 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Jingoo Han, Gustavo Pimentel, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Marek Vasut, Yoshihiro Shimoda, Thierry Reding, Jonathan Hunter,
Kishon Vijay Abraham I, Vidya Sagar, Vignesh Raghavendra,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
Minghuan Lian, Mingkai Hu, Roy Zang, Kunihiko Hayashi,
Masami Hiramatsu, Kishon Vijay Abraham I, Jesper Nilsson,
Srikanth Thokala, linux-pci, linux-kernel, linux-renesas-soc,
linux-arm-msm, linux-tegra, linux-omap, linux-arm-kernel,
linuxppc-dev, linux-arm-kernel, Frank Li
In-Reply-To: <20240314-pci-dbi-rework-v10-2-14a45c5a938e@linaro.org>
On Thu, Mar 14, 2024 at 01:18:00PM +0530, Manivannan Sadhasivam wrote:
> All of the APIs are missing the Kernel-doc comments. Hence, add them.
>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
> drivers/pci/controller/dwc/pcie-designware-ep.c | 78 +++++++++++++++++++++++++
> 1 file changed, 78 insertions(+)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index c05304eabb89..d7e8f2dda6ce 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -14,6 +14,10 @@
> #include <linux/pci-epc.h>
> #include <linux/pci-epf.h>
>
> +/**
> + * dw_pcie_ep_linkup - Notify EPF drivers about link up event
> + * @ep: DWC EP device
> + */
> void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
> {
> struct pci_epc *epc = ep->epc;
> @@ -22,6 +26,11 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
> }
> EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup);
>
> +/**
> + * dw_pcie_ep_init_notify - Notify EPF drivers about EPC initialization
> + * complete
Nit: "complete" can be on previous line without exceeding 80 chars.
> + * @ep: DWC EP device
> + */
> void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
> {
> struct pci_epc *epc = ep->epc;
> @@ -30,6 +39,14 @@ void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep)
> }
> EXPORT_SYMBOL_GPL(dw_pcie_ep_init_notify);
>
> +/**
> + * dw_pcie_ep_get_func_from_ep - Get the struct dw_pcie_ep_func corresponding to
> + * the endpoint function
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint device
> + *
> + * Return: struct dw_pcie_ep_func if success, NULL otherwise.
> + */
> struct dw_pcie_ep_func *
> dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
> {
> @@ -60,6 +77,11 @@ static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no,
> dw_pcie_dbi_ro_wr_dis(pci);
> }
>
> +/**
> + * dw_pcie_ep_reset_bar - Reset endpoint BAR
> + * @pci: DWC PCI device
> + * @bar: BAR number of the endpoint
> + */
> void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
> {
> u8 func_no, funcs;
> @@ -439,6 +461,13 @@ static const struct pci_epc_ops epc_ops = {
> .get_features = dw_pcie_ep_get_features,
> };
>
> +/**
> + * dw_pcie_ep_raise_intx_irq - Raise INTx IRQ to the host
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint
> + *
> + * Return: 0 if success, errono otherwise.
> + */
> int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)
> {
> struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> @@ -450,6 +479,14 @@ int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)
> }
> EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_intx_irq);
>
> +/**
> + * dw_pcie_ep_raise_msi_irq - Raise MSI IRQ to the host
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint
> + * @interrupt_num: Interrupt number to be raised
> + *
> + * Return: 0 if success, errono otherwise.
> + */
> int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
> u8 interrupt_num)
> {
> @@ -498,6 +535,15 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
> }
> EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_msi_irq);
>
> +/**
> + * dw_pcie_ep_raise_msix_irq_doorbell - Raise MSIX to the host using Doorbell
Nit: s/MSIX/MSI-X/
> + * method
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint device
> + * @interrupt_num: Interrupt number to be raised
> + *
> + * Return: 0 if success, errno otherwise.
> + */
> int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
> u16 interrupt_num)
> {
> @@ -517,6 +563,14 @@ int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
> return 0;
> }
>
> +/**
> + * dw_pcie_ep_raise_msix_irq - Raise MSIX to the host
Nit: s/MSIX/MSI-X/
> + * @ep: DWC EP device
> + * @func_no: Function number of the endpoint device
> + * @interrupt_num: Interrupt number to be raised
> + *
> + * Return: 0 if success, errno otherwise.
> + */
> int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
> u16 interrupt_num)
> {
> @@ -564,6 +618,13 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
> return 0;
> }
>
> +/**
> + * dw_pcie_ep_exit - Deinitialize the endpoint device
> + * @ep: DWC EP device
> + *
> + * Deinitialize the endpoint device. EPC device is not destroyed since that will
> + * taken care by Devres.
Nit: s/will/will be/
> + */
> void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
> {
> struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> @@ -599,6 +660,14 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap)
> return 0;
> }
>
> +/**
> + * dw_pcie_ep_init_complete - Complete DWC EP initialization
> + * @ep: DWC EP device
> + *
> + * Complete the initialization of the registers (CSRs) specific to DWC EP. This
> + * API should be called only when the endpoint receives an active refclk (either
> + * from host or generated locally).
> + */
> int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
> {
> struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> @@ -716,6 +785,15 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep)
> }
> EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete);
>
> +/**
> + * dw_pcie_ep_init - Initialize the endpoint device
> + * @ep: DWC EP device
> + *
> + * Initialize the endpoint device. Allocate resources and create the EPC
> + * device with the endpoint framework.
> + *
> + * Return: 0 if success, errno otherwise.
> + */
> int dw_pcie_ep_init(struct dw_pcie_ep *ep)
> {
> int ret;
>
> --
> 2.25.1
>
With nits fixed:
Reviewed-by: Niklas Cassel <cassel@kernel.org>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v10 7/8] PCI: dwc: ep: Call dw_pcie_ep_init_registers() API directly from all glue drivers
From: Niklas Cassel @ 2024-03-22 11:03 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Jingoo Han, Gustavo Pimentel, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Marek Vasut, Yoshihiro Shimoda, Thierry Reding, Jonathan Hunter,
Kishon Vijay Abraham I, Vidya Sagar, Vignesh Raghavendra,
Richard Zhu, Lucas Stach, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, NXP Linux Team,
Minghuan Lian, Mingkai Hu, Roy Zang, Kunihiko Hayashi,
Masami Hiramatsu, Kishon Vijay Abraham I, Jesper Nilsson,
Srikanth Thokala, linux-pci, linux-kernel, linux-renesas-soc,
linux-arm-msm, linux-tegra, linux-omap, linux-arm-kernel,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20240314-pci-dbi-rework-v10-7-14a45c5a938e@linaro.org>
On Thu, Mar 14, 2024 at 01:18:05PM +0530, Manivannan Sadhasivam wrote:
> Currently, dw_pcie_ep_init_registers() API is directly called by the glue
> drivers requiring active refclk from host. But for the other drivers, it is
> getting called implicitly by dw_pcie_ep_init(). This is due to the fact
> that this API initializes DWC EP specific registers and that requires an
> active refclk (either from host or generated locally by endpoint itsef).
>
> But, this causes a discrepancy among the glue drivers. So to avoid this
> confusion, let's call this API directly from all glue drivers irrespective
> of refclk dependency. Only difference here is that the drivers requiring
> refclk from host will call this API only after the refclk is received and
> other drivers without refclk dependency will call this API right after
> dw_pcie_ep_init().
>
> With this change, the check for 'core_init_notifier' flag can now be
> dropped from dw_pcie_ep_init() API. This will also allow us to remove the
> 'core_init_notifier' flag completely in the later commits.
>
> Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
Reviewed-by: Niklas Cassel <cassel@kernel.org>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 0/4] Update Energy Model after chip binning adjusted voltages
From: Lukasz Luba @ 2024-03-22 11:06 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: dietmar.eggemann, linux-arm-kernel, sboyd, nm, linux-samsung-soc,
daniel.lezcano, rafael, viresh.kumar, krzysztof.kozlowski,
alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <20240322103221.47594-1-lukasz.luba@arm.com>
On 3/22/24 10:32, Lukasz Luba wrote:
> Hi all,
>
> This is a follow-up patch aiming to add EM modification due to chip binning.
> The first RFC and the discussion can be found here [1].
>
> It uses Exynos chip driver code as a 1st user. The EM framework has been
> extended to handle this use case easily, when the voltage has been changed
> after setup. On my Odroid-xu4 in some OPPs I can observe ~20% power difference.
> According to that data in driver tables it could be up to ~29%.
>
> This chip binning is applicable to a lot of SoCs, so the EM framework should
> make it easy to update. It uses the existing OPP and DT information to
> re-calculate the new power values.
>
>
> Changes:
> v2:
> - removed 'ret' from error message which wasn't initialized (Christian)
> v1:
> - exported the OPP calculation function from the OPP/OF so it can be
> used from EM fwk (Viresh)
> - refactored EM updating function to re-use common code
> - added new EM function which can be used by chip device drivers which
> modify the voltage in OPPs
> RFC is at [1]
>
> Regards,
> Lukasz Luba
>
> [1] https://lore.kernel.org/lkml/20231220110339.1065505-1-lukasz.luba@arm.com/
>
> Lukasz Luba (4):
> OPP: OF: Export dev_opp_pm_calc_power() for usage from EM
> PM: EM: Change the em_adjust_new_capacity() to re-use code
> PM: EM: Add em_dev_update_chip_binning()
> soc: samsung: exynos-asv: Update Energy Model after adjusting voltage
>
> drivers/opp/of.c | 17 +++--
> drivers/soc/samsung/exynos-asv.c | 11 +++-
> include/linux/energy_model.h | 5 ++
> include/linux/pm_opp.h | 8 +++
> kernel/power/energy_model.c | 109 +++++++++++++++++++++++++------
> 5 files changed, 125 insertions(+), 25 deletions(-)
>
Please ignore this version. It still has that 'ret'. I've fixed in
different repo, but sent patches from different terminal.
I'll resend it in a second...
Regards,
Lukasz
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RESEND][PATCH v2 0/4] Update Energy Model after chip binning adjusted voltages
From: Lukasz Luba @ 2024-03-22 11:08 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
Hi all,
This is a follow-up patch aiming to add EM modification due to chip binning.
The first RFC and the discussion can be found here [1].
It uses Exynos chip driver code as a 1st user. The EM framework has been
extended to handle this use case easily, when the voltage has been changed
after setup. On my Odroid-xu4 in some OPPs I can observe ~20% power difference.
According to that data in driver tables it could be up to ~29%.
This chip binning is applicable to a lot of SoCs, so the EM framework should
make it easy to update. It uses the existing OPP and DT information to
re-calculate the new power values.
Changes:
v2:
- removed 'ret' from error message which wasn't initialized (Christian)
v1:
- exported the OPP calculation function from the OPP/OF so it can be
used from EM fwk (Viresh)
- refactored EM updating function to re-use common code
- added new EM function which can be used by chip device drivers which
modify the voltage in OPPs
RFC is at [1]
Regards,
Lukasz Luba
[1] https://lore.kernel.org/lkml/20231220110339.1065505-1-lukasz.luba@arm.com/
Lukasz Luba (4):
OPP: OF: Export dev_opp_pm_calc_power() for usage from EM
PM: EM: Change the em_adjust_new_capacity() to re-use code
PM: EM: Add em_dev_update_chip_binning()
soc: samsung: exynos-asv: Update Energy Model after adjusting voltage
drivers/opp/of.c | 17 +++--
drivers/soc/samsung/exynos-asv.c | 11 +++-
include/linux/energy_model.h | 5 ++
include/linux/pm_opp.h | 8 +++
kernel/power/energy_model.c | 109 +++++++++++++++++++++++++------
5 files changed, 125 insertions(+), 25 deletions(-)
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RESEND][PATCH v2 1/4] OPP: OF: Export dev_opp_pm_calc_power() for usage from EM
From: Lukasz Luba @ 2024-03-22 11:08 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <20240322110850.77086-1-lukasz.luba@arm.com>
There are device drivers which can modify voltage values for OPPs. It
could be due to the chip binning and those drivers have specific chip
knowledge about it. This adjustment can happen after Energy Model is
registered, thus EM can have stale data about power.
Export dev_opp_pm_calc_power() which can be used by Energy Model to
calculate new power with the new voltage for OPPs.
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
---
drivers/opp/of.c | 17 ++++++++++++-----
include/linux/pm_opp.h | 8 ++++++++
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index f9f0b22bccbb4..282eb5966fd03 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -1494,20 +1494,26 @@ _get_dt_power(struct device *dev, unsigned long *uW, unsigned long *kHz)
return 0;
}
-/*
- * Callback function provided to the Energy Model framework upon registration.
+/**
+ * dev_pm_opp_calc_power() - Calculate power value for device with EM
+ * @dev : Device for which an Energy Model has to be registered
+ * @uW : New power value that is calculated
+ * @kHz : Frequency for which the new power is calculated
+ *
* This computes the power estimated by @dev at @kHz if it is the frequency
* of an existing OPP, or at the frequency of the first OPP above @kHz otherwise
* (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled
* frequency and @uW to the associated power. The power is estimated as
* P = C * V^2 * f with C being the device's capacitance and V and f
* respectively the voltage and frequency of the OPP.
+ * It is also used as a callback function provided to the Energy Model
+ * framework upon registration.
*
* Returns -EINVAL if the power calculation failed because of missing
* parameters, 0 otherwise.
*/
-static int __maybe_unused _get_power(struct device *dev, unsigned long *uW,
- unsigned long *kHz)
+int dev_pm_opp_calc_power(struct device *dev, unsigned long *uW,
+ unsigned long *kHz)
{
struct dev_pm_opp *opp;
struct device_node *np;
@@ -1544,6 +1550,7 @@ static int __maybe_unused _get_power(struct device *dev, unsigned long *uW,
return 0;
}
+EXPORT_SYMBOL_GPL(dev_pm_opp_calc_power);
static bool _of_has_opp_microwatt_property(struct device *dev)
{
@@ -1619,7 +1626,7 @@ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus)
goto failed;
}
- EM_SET_ACTIVE_POWER_CB(em_cb, _get_power);
+ EM_SET_ACTIVE_POWER_CB(em_cb, dev_pm_opp_calc_power);
register_em:
ret = em_dev_register_perf_domain(dev, nr_opp, &em_cb, cpus, true);
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 065a47382302c..31370deb9905f 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -476,6 +476,8 @@ struct device_node *dev_pm_opp_get_of_node(struct dev_pm_opp *opp);
int of_get_required_opp_performance_state(struct device_node *np, int index);
int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_table *opp_table);
int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus);
+int dev_pm_opp_calc_power(struct device *dev, unsigned long *uW,
+ unsigned long *kHz);
static inline void dev_pm_opp_of_unregister_em(struct device *dev)
{
em_dev_unregister_perf_domain(dev);
@@ -539,6 +541,12 @@ static inline void dev_pm_opp_of_unregister_em(struct device *dev)
{
}
+static inline int dev_pm_opp_calc_power(struct device *dev, unsigned long *uW,
+ unsigned long *kHz)
+{
+ return -EOPNOTSUPP;
+}
+
static inline int of_get_required_opp_performance_state(struct device_node *np, int index)
{
return -EOPNOTSUPP;
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RESEND][PATCH v2 2/4] PM: EM: Change the em_adjust_new_capacity() to re-use code
From: Lukasz Luba @ 2024-03-22 11:08 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <20240322110850.77086-1-lukasz.luba@arm.com>
There is going to be a new update function addressing chip binning.
Therefore, some common code which can be refactored and called from
upcoming changes and em_adjust_new_capacity(). In this way the code
duplication can be avoided.
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
---
kernel/power/energy_model.c | 58 +++++++++++++++++++++++++------------
1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 9e1c9aa399ea9..6960dd7393b2d 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -674,23 +674,15 @@ void em_dev_unregister_perf_domain(struct device *dev)
}
EXPORT_SYMBOL_GPL(em_dev_unregister_perf_domain);
-/*
- * Adjustment of CPU performance values after boot, when all CPUs capacites
- * are correctly calculated.
- */
-static void em_adjust_new_capacity(struct device *dev,
- struct em_perf_domain *pd,
- u64 max_cap)
+static struct em_perf_table __rcu *em_table_dup(struct em_perf_domain *pd)
{
struct em_perf_table __rcu *em_table;
struct em_perf_state *ps, *new_ps;
- int ret, ps_size;
+ int ps_size;
em_table = em_table_alloc(pd);
- if (!em_table) {
- dev_warn(dev, "EM: allocation failed\n");
- return;
- }
+ if (!em_table)
+ return NULL;
new_ps = em_table->state;
@@ -702,24 +694,52 @@ static void em_adjust_new_capacity(struct device *dev,
rcu_read_unlock();
- em_init_performance(dev, pd, new_ps, pd->nr_perf_states);
- ret = em_compute_costs(dev, new_ps, NULL, pd->nr_perf_states,
+ return em_table;
+}
+
+static int em_recalc_and_update(struct device *dev, struct em_perf_domain *pd,
+ struct em_perf_table __rcu *em_table)
+{
+ int ret;
+
+ ret = em_compute_costs(dev, em_table->state, NULL, pd->nr_perf_states,
pd->flags);
- if (ret) {
- dev_warn(dev, "EM: compute costs failed\n");
- return;
- }
+ if (ret)
+ goto free_em_table;
ret = em_dev_update_perf_domain(dev, em_table);
if (ret)
- dev_warn(dev, "EM: update failed %d\n", ret);
+ goto free_em_table;
/*
* This is one-time-update, so give up the ownership in this updater.
* The EM framework has incremented the usage counter and from now
* will keep the reference (then free the memory when needed).
*/
+free_em_table:
em_table_free(em_table);
+ return ret;
+}
+
+/*
+ * Adjustment of CPU performance values after boot, when all CPUs capacites
+ * are correctly calculated.
+ */
+static void em_adjust_new_capacity(struct device *dev,
+ struct em_perf_domain *pd,
+ u64 max_cap)
+{
+ struct em_perf_table __rcu *em_table;
+
+ em_table = em_table_dup(pd);
+ if (!em_table) {
+ dev_warn(dev, "EM: allocation failed\n");
+ return;
+ }
+
+ em_init_performance(dev, pd, em_table->state, pd->nr_perf_states);
+
+ em_recalc_and_update(dev, pd, em_table);
}
static void em_check_capacity_update(void)
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RESEND][PATCH v2 3/4] PM: EM: Add em_dev_update_chip_binning()
From: Lukasz Luba @ 2024-03-22 11:08 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <20240322110850.77086-1-lukasz.luba@arm.com>
Add a function which allows to modify easily the EM after the new voltage
information is available. The device drivers for the chip can adjust
the voltage values after setup. The voltage for the same frequency in OPP
can be different due to chip binning. The voltage impacts the power usage
and the EM power values can be updated to reflect that.
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
---
include/linux/energy_model.h | 5 ++++
kernel/power/energy_model.c | 51 ++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
index 770755df852f1..d30d67c2f07cf 100644
--- a/include/linux/energy_model.h
+++ b/include/linux/energy_model.h
@@ -172,6 +172,7 @@ struct em_perf_table __rcu *em_table_alloc(struct em_perf_domain *pd);
void em_table_free(struct em_perf_table __rcu *table);
int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
int nr_states);
+int em_dev_update_chip_binning(struct device *dev);
/**
* em_pd_get_efficient_state() - Get an efficient performance state from the EM
@@ -387,6 +388,10 @@ int em_dev_compute_costs(struct device *dev, struct em_perf_state *table,
{
return -EINVAL;
}
+static inline int em_dev_update_chip_binning(struct device *dev)
+{
+ return -EINVAL;
+}
#endif
#endif
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 6960dd7393b2d..f7f7ae34ec552 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -808,3 +808,54 @@ static void em_update_workfn(struct work_struct *work)
{
em_check_capacity_update();
}
+
+/**
+ * em_dev_update_chip_binning() - Update Energy Model with new values after
+ * the new voltage information is present in the OPPs.
+ * @dev : Device for which the Energy Model has to be updated.
+ *
+ * This function allows to update easily the EM with new values available in
+ * the OPP framework and DT. It can be used after the chip has been properly
+ * verified by device drivers and the voltages adjusted for the 'chip binning'.
+ * It uses the "dynamic-power-coefficient" DT property to calculate the power
+ * values for EM. For power calculation it uses the new adjusted voltage
+ * values known for OPPs, which might be changed after boot.
+ */
+int em_dev_update_chip_binning(struct device *dev)
+{
+ struct em_perf_table __rcu *em_table;
+ struct em_perf_domain *pd;
+ int i, ret;
+
+ if (IS_ERR_OR_NULL(dev))
+ return -EINVAL;
+
+ pd = em_pd_get(dev);
+ if (!pd) {
+ dev_warn(dev, "Couldn't find Energy Model\n");
+ return -EINVAL;
+ }
+
+ em_table = em_table_dup(pd);
+ if (!em_table) {
+ dev_warn(dev, "EM: allocation failed\n");
+ return -ENOMEM;
+ }
+
+ /* Update power values which might change due to new voltage in OPPs */
+ for (i = 0; i < pd->nr_perf_states; i++) {
+ unsigned long freq = em_table->state[i].frequency;
+ unsigned long power;
+
+ ret = dev_pm_opp_calc_power(dev, &power, &freq);
+ if (ret) {
+ em_table_free(em_table);
+ return ret;
+ }
+
+ em_table->state[i].power = power;
+ }
+
+ return em_recalc_and_update(dev, pd, em_table);
+}
+EXPORT_SYMBOL_GPL(em_dev_update_chip_binning);
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RESEND][PATCH v2 4/4] soc: samsung: exynos-asv: Update Energy Model after adjusting voltage
From: Lukasz Luba @ 2024-03-22 11:08 UTC (permalink / raw)
To: linux-kernel, linux-pm
Cc: lukasz.luba, dietmar.eggemann, linux-arm-kernel, sboyd, nm,
linux-samsung-soc, daniel.lezcano, rafael, viresh.kumar,
krzysztof.kozlowski, alim.akhtar, m.szyprowski, mhiramat
In-Reply-To: <20240322110850.77086-1-lukasz.luba@arm.com>
When the voltage for OPPs is adjusted there is a need to also update
Energy Model framework. The EM data contains power values which depend
on voltage values. The EM structure is used for thermal (IPA governor)
and in scheduler task placement (EAS) so it should reflect the real HW
model as best as possible to operate properly.
Based on data on Exynos5422 ASV tables the maximum power difference might
be ~29%. An Odroid-XU4 (with a random sample SoC in this chip lottery)
showed power difference for some OPPs ~20%. Therefore, it's worth to
update the EM.
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
---
drivers/soc/samsung/exynos-asv.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
index d60af8acc3916..bd6bb2cab2cd8 100644
--- a/drivers/soc/samsung/exynos-asv.c
+++ b/drivers/soc/samsung/exynos-asv.c
@@ -11,6 +11,7 @@
#include <linux/cpu.h>
#include <linux/device.h>
+#include <linux/energy_model.h>
#include <linux/errno.h>
#include <linux/of.h>
#include <linux/pm_opp.h>
@@ -97,9 +98,17 @@ static int exynos_asv_update_opps(struct exynos_asv *asv)
last_opp_table = opp_table;
ret = exynos_asv_update_cpu_opps(asv, cpu);
- if (ret < 0)
+ if (!ret) {
+ /*
+ * When the voltage for OPPs successfully
+ * changed, update the EM power values to
+ * reflect the reality and not use stale data
+ */
+ em_dev_update_chip_binning(cpu);
+ } else {
dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
cpuid);
+ }
}
dev_pm_opp_put_opp_table(opp_table);
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [v10,20/27] drm/connector: hdmi: Add Infoframes generation
From: Sui Jingfeng @ 2024-03-22 11:13 UTC (permalink / raw)
To: Maxime Ripard
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Daniel Vetter,
Jonathan Corbet, Sandy Huang, Heiko Stübner, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Hans Verkuil, Sebastian Wick,
Ville Syrjälä, dri-devel, linux-arm-kernel, linux-doc,
linux-kernel, linux-media, linux-rockchip, linux-sunxi
In-Reply-To: <20240322-loose-resourceful-bullmastiff-92cfaf@houat>
Hi,
On 2024/3/22 18:31, Maxime Ripard wrote:
> Which default config are you talking about? This compiles fine with all
> drm-misc defconfig, x86 defconfig and allmodconfig.
The drm_hdmi_avi_infoframe_colorimetry() function is belong to the drm_display_helper.ko
kernel module, it get called from hdmi_generate_avi_infoframe() in drm_atomic_state_helper.c.
While drm_atomic_state_helper.c belongs to drm_kms_helper.ko. Therefore drm_kms_helper.ko
is dependent on drm_display_helper.ko implicitly. So we probably should select it.
--
Best regards,
Sui
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [v10,20/27] drm/connector: hdmi: Add Infoframes generation
From: Sui Jingfeng @ 2024-03-22 11:28 UTC (permalink / raw)
To: Jani Nikula, Maxime Ripard, Maarten Lankhorst, Thomas Zimmermann,
David Airlie, Daniel Vetter, Jonathan Corbet, Sandy Huang,
Heiko Stübner, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: Hans Verkuil, Sebastian Wick, Ville Syrjälä, dri-devel,
linux-arm-kernel, linux-doc, linux-kernel, linux-media,
linux-rockchip, linux-sunxi
In-Reply-To: <87sf0iliyh.fsf@intel.com>
Hi,
On 2024/3/22 17:22, Jani Nikula wrote:
> On Fri, 22 Mar 2024, Sui Jingfeng <sui.jingfeng@linux.dev> wrote:
>> Hi,
>>
>>
>> On 2024/3/21 23:29, Maxime Ripard wrote:
>>> Infoframes in KMS is usually handled by a bunch of low-level helpers
>>> that require quite some boilerplate for drivers. This leads to
>>> discrepancies with how drivers generate them, and which are actually
>>> sent.
>>>
>>> Now that we have everything needed to generate them in the HDMI
>>> connector state, we can generate them in our common logic so that
>>> drivers can simply reuse what we precomputed.
>>>
>>> Signed-off-by: Maxime Ripard <mripard@kernel.org>
>>> ---
>>> drivers/gpu/drm/Kconfig | 1 +
>>> drivers/gpu/drm/drm_atomic_state_helper.c | 338 +++++++++++++++++++++
>>> drivers/gpu/drm/drm_connector.c | 14 +
>>> .../gpu/drm/tests/drm_atomic_state_helper_test.c | 1 +
>>> drivers/gpu/drm/tests/drm_connector_test.c | 12 +
>>> include/drm/drm_atomic_state_helper.h | 8 +
>>> include/drm/drm_connector.h | 109 +++++++
>>> 7 files changed, 483 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
>>> index 16029435b750..3d3193c7aa5f 100644
>>> --- a/drivers/gpu/drm/Kconfig
>>> +++ b/drivers/gpu/drm/Kconfig
>>> @@ -97,10 +97,11 @@ config DRM_KUNIT_TEST
>>> If in doubt, say "N".
>>>
>>> config DRM_KMS_HELPER
>>> tristate
>>> depends on DRM
>>> + select DRM_DISPLAY_HDMI_HELPER
>> Should we select DRM_DISPLAY_HELPER here? Otherwise there will have some compile error
>> emerged with default config.
> Can we stop abusing select instead of adding more selects to paper over
> the issues?
>
> Use select only for non-visible symbols (no prompts anywhere) and for
> symbols with no dependencies.
OK, fine.
You probably want to tell us a concrete method, then we will follow.
But I guess that is up to Maxime will adopt it or not. Probably need
some discussion then.
>
> BR,
> Jani.
>
--
Best regards,
Sui
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 0/1] THP_SWAP support for ARM64 SoC with MTE
From: Barry Song @ 2024-03-22 11:41 UTC (permalink / raw)
To: catalin.marinas, will, akpm, hughd, linux-mm, linux-arm-kernel
Cc: chrisl, mark.rutland, ryan.roberts, steven.price, david, willy,
Barry Song
From: Barry Song <v-songbaohua@oppo.com>
The patch has been extracted from the larger folios swap-in series [1],
incorporating some new modifications.
Introducing THP_SWAP support for ARM64 SoCs with MTE is essential, particularly
due to its significance for widely used ARM64 products in the market. Without
this support, Ryan's mTHP swap-out without splitting series won't operate
effectively on these SoCs.
Therefore, it's imperative for this update to be implemented sooner
rather than later.
There are a couple of differences with the code in [1]:
1. minor code cleanup, Ryan
2. always pass the first swap entry of a folio to arch_swap_restore, Ryan
[1] https://lore.kernel.org/linux-mm/20240304081348.197341-2-21cnbao@gmail.com/
Barry Song (1):
arm64: mm: swap: support THP_SWAP on hardware with MTE
arch/arm64/include/asm/pgtable.h | 19 ++------------
arch/arm64/mm/mteswap.c | 45 ++++++++++++++++++++++++++++++++
include/linux/huge_mm.h | 12 ---------
include/linux/pgtable.h | 2 +-
mm/internal.h | 14 ++++++++++
mm/memory.c | 2 +-
mm/page_io.c | 2 +-
mm/shmem.c | 2 +-
mm/swap_slots.c | 2 +-
mm/swapfile.c | 2 +-
10 files changed, 67 insertions(+), 35 deletions(-)
Appendix
I also have a small test program specifically designed for running MTE
on a THP that I can share with those who are interested in this subject.
/*
* To be compiled with -march=armv8.5-a+memtag
*/
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/auxv.h>
#include <sys/mman.h>
#include <sys/prctl.h>
/*
* From arch/arm64/include/uapi/asm/hwcap.h
*/
#define HWCAP2_MTE (1 << 18)
/*
* From arch/arm64/include/uapi/asm/mman.h
*/
#define PROT_MTE 0x20
/*
* From include/uapi/linux/prctl.h
*/
#define PR_SET_TAGGED_ADDR_CTRL 55
#define PR_GET_TAGGED_ADDR_CTRL 56
# define PR_TAGGED_ADDR_ENABLE (1UL << 0)
# define PR_MTE_TCF_SHIFT 1
# define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TAG_SHIFT 3
# define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT)
/*
* Insert a random logical tag into the given pointer.
*/
#define insert_random_tag(ptr) ({ \
uint64_t __val; \
asm("irg %0, %1" : "=r" (__val) : "r" (ptr)); \
__val; \
})
/*
* Set the allocation tag on the destination address.
*/
#define set_tag(tagged_addr) do { \
asm volatile("stg %0, [%0]" : : "r" (tagged_addr) : "memory"); \
} while (0)
int main()
{
unsigned char *a, *p[512];
unsigned long page_sz = 4 * 1024UL;
unsigned long mem_sz = 2 * 1024 * 1024UL;
unsigned long hwcap2 = getauxval(AT_HWCAP2);
int i;
if (!(hwcap2 & HWCAP2_MTE))
return EXIT_FAILURE;
if (prctl(PR_SET_TAGGED_ADDR_CTRL,
PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC |
(0xfffe << PR_MTE_TAG_SHIFT),
0, 0, 0)) {
perror("prctl() failed");
return EXIT_FAILURE;
}
a = mmap(0, mem_sz * 2, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (a == MAP_FAILED) {
perror("mmap() failed");
return EXIT_FAILURE;
}
/* make sure a is aligned with 2MiB THP */
a = (unsigned char *)(((unsigned long)a + mem_sz - 1) & ~(mem_sz - 1));
madvise(a, mem_sz, MADV_HUGEPAGE);
memset(a, 0x11, mem_sz);
if (mprotect(a, mem_sz, PROT_READ | PROT_WRITE | PROT_MTE)) {
perror("mprotect() failed");
return EXIT_FAILURE;
}
printf("set tag for each 4KiB page\n");
for (i = 0; i < 512; i++) {
p[i] = a + i * page_sz;
p[i] = (unsigned char *)insert_random_tag(p[i]);
set_tag(p[i]);
p[i][0] = 0x33;
}
printf("swap-out the whole THP\n");
madvise(a, mem_sz, MADV_PAGEOUT);
printf("swap-in each page of the original THP\n");
for (i = 0; i < 512; i++) {
if (p[i][0] != 0x33) {
printf("test fails, unmatched value after swap-in\n");
return EXIT_FAILURE;
}
}
printf("we should get here\n");
for (i = 0; i < 512; i++) {
printf("page :%d val: expect segment fault, is %02x\n", i, p[i][16]);
}
printf("we shouldn't get here\n");
return EXIT_FAILURE;
}
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox