* [PATCH 0/3] soc: qcom: qcom_stats: Add DDR stats
@ 2025-04-29 3:52 Maulik Shah
2025-04-29 3:52 ` [PATCH 1/3] soc: qcom: qcom_stats: Add support to read DDR statistic Maulik Shah
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Maulik Shah @ 2025-04-29 3:52 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson, Maulik Shah
This series adds support to read various DDR low power mode and frequency
stats. This was added in past with series [1] but reverted with [4] due
to some SoCs boot up failures. This series is more aligned to downstream
implementation and fixes the issues mentioned in [4].
The series [1] tried to add three feature support
A. Reading DDR Frequency and low power stats from MSG RAM
(targets where DDR stats are readily available in MSG RAM to read)
B. Trigger QMP to ask AOP to populate DDR Frequency and low power stats
(targets where DDR stats are available but duration field syncing
requires QMP message to be sent to AOP)
C. Trigger QMP to ask AOP to populate DDR vote table information
(To read different DRV / Direct Resource Voter, CPUSS, DSPs's votes
for DDR frequency)
Current series do not include reading the DDR vote table information (C)
part from [1] which is to be separately sent potentially including reading
other resources votes like Cx Rail level vote information. These vote
tables details are not strictly related to DDR Frequency and low power
stats (A) and (B) this series is adding.
This series updates respective SoC devicetree with QMP handle (where DDR
stats syncing is required) and it is backward compatible with older
devicetree as without the QMP handle present, ddr stats can be still be
read (duration field will be read as 0).
Note that [1] was only partially reverted and hence device binding update
for QMP handle [2] is already present along with the fix to have
dependency on AOSS QMP driver in Kconfig [3].
[1] https://lore.kernel.org/all/20231130-topic-ddr_sleep_stats-v1-0-5981c2e764b6@linaro.org/
[2] https://lore.kernel.org/all/20231130-topic-ddr_sleep_stats-v1-2-5981c2e764b6@linaro.org/
[3] https://lore.kernel.org/lkml/20231205-qcom_stats-aoss_qmp-dependency-v1-1-8dabe1b5c32a@quicinc.com/T/
[4] https://lore.kernel.org/all/20231214-topic-undo_ddr_stats-v1-1-1fe32c258e56@linaro.org/
Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
---
Maulik Shah (3):
soc: qcom: qcom_stats: Add support to read DDR statistic
soc: qcom: qcom_stats: Add QMP support for syncing ddr stats
arm64: dts: qcom: Add QMP handle for qcom_stats
arch/arm64/boot/dts/qcom/sm8450.dtsi | 1 +
arch/arm64/boot/dts/qcom/sm8550.dtsi | 1 +
arch/arm64/boot/dts/qcom/sm8650.dtsi | 1 +
arch/arm64/boot/dts/qcom/sm8750.dtsi | 1 +
drivers/soc/qcom/qcom_stats.c | 127 +++++++++++++++++++++++++++++++++++
5 files changed, 131 insertions(+)
---
base-commit: 393d0c54cae31317deaa9043320c5fd9454deabc
change-id: 20250426-ddr_stats_-391505b3da6a
Best regards,
--
Maulik Shah <maulik.shah@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] soc: qcom: qcom_stats: Add support to read DDR statistic
2025-04-29 3:52 [PATCH 0/3] soc: qcom: qcom_stats: Add DDR stats Maulik Shah
@ 2025-04-29 3:52 ` Maulik Shah
2025-04-29 10:34 ` Konrad Dybcio
2025-04-29 3:52 ` [PATCH 2/3] soc: qcom: qcom_stats: Add QMP support for syncing ddr stats Maulik Shah
2025-04-29 3:52 ` [PATCH 3/3] arm64: dts: qcom: Add QMP handle for qcom_stats Maulik Shah
2 siblings, 1 reply; 10+ messages in thread
From: Maulik Shah @ 2025-04-29 3:52 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson, Maulik Shah
DDR statistic provide different DDR LPM and DDR frequency statistic.
Add support to read from MSGRAM and display via debugfs.
Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
---
drivers/soc/qcom/qcom_stats.c | 99 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c
index 5de99cf59b9fbe32c0580e371c3cc362dfabb895..ee11fb0919742454d40442112787c087ba8f6598 100644
--- a/drivers/soc/qcom/qcom_stats.c
+++ b/drivers/soc/qcom/qcom_stats.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved.
*/
+#include <linux/bitfield.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/io.h>
@@ -24,6 +26,17 @@
#define ACCUMULATED_OFFSET 0x18
#define CLIENT_VOTES_OFFSET 0x20
+#define DDR_STATS_MAGIC_KEY 0xA1157A75
+#define DDR_STATS_MAX_NUM_MODES 0x14
+#define DDR_STATS_MAGIC_KEY_ADDR 0x0
+#define DDR_STATS_NUM_MODES_ADDR 0x4
+#define DDR_STATS_ENTRY_START_ADDR 0x8
+
+#define DDR_STATS_CP_IDX(data) FIELD_GET(GENMASK(4, 0), data)
+#define DDR_STATS_LPM_NAME(data) FIELD_GET(GENMASK(7, 0), data)
+#define DDR_STATS_TYPE(data) FIELD_GET(GENMASK(15, 8), data)
+#define DDR_STATS_FREQ(data) FIELD_GET(GENMASK(31, 16), data)
+
struct subsystem_data {
const char *name;
u32 smem_item;
@@ -48,12 +61,19 @@ static const struct subsystem_data subsystems[] = {
struct stats_config {
size_t stats_offset;
+ size_t ddr_stats_offset;
size_t num_records;
bool appended_stats_avail;
bool dynamic_offset;
bool subsystem_stats_in_smem;
};
+struct ddr_stats_entry {
+ u32 name;
+ u32 count;
+ u64 duration;
+};
+
struct stats_data {
bool appended_stats_avail;
void __iomem *base;
@@ -122,8 +142,85 @@ static int qcom_soc_sleep_stats_show(struct seq_file *s, void *unused)
return 0;
}
+static void qcom_ddr_stats_print(struct seq_file *s, struct ddr_stats_entry *data)
+{
+ u32 cp_idx, name;
+
+ /*
+ * DDR statistic have two different types of details encoded.
+ * (1) DDR LPM Stats
+ * (2) DDR Frequency Stats
+ *
+ * The name field have details like which type of DDR stat (bits 8:15)
+ * along with other details as explained below
+ *
+ * In case of DDR LPM stat, name field will be encoded as,
+ * Bits - Meaning
+ * 0:7 - DDR LPM name, can be of 0xd4, 0xd3, 0x11 and 0xd0.
+ * 8:15 - 0x0 (indicates its a LPM stat)
+ * 16:31 - Unused
+ *
+ * In case of DDR FREQ stats, name field will be encoded as,
+ * Bits - Meaning
+ * 0:4 - DDR Clock plan index (CP IDX)
+ * 5:7 - Unused
+ * 8:15 - 0x1 (indicates its Freq stat)
+ * 16:31 - Frequency value in Mhz
+ */
+ name = DDR_STATS_TYPE(data->name);
+ if (name == 0x0) {
+ name = DDR_STATS_LPM_NAME(data->name);
+ seq_printf(s, "DDR LPM Stat Name:0x%x\tcount:%u\tDuration (ticks):%llu\n",
+ name, data->count, data->duration);
+ } else if (name == 0x1) {
+ name = DDR_STATS_FREQ(data->name);
+ if (!name || !data->count)
+ return;
+
+ cp_idx = DDR_STATS_CP_IDX(data->name);
+ seq_printf(s, "DDR Freq %uMhz:\tCP IDX:%u\tcount:%u\tDuration (ticks):%llu\n",
+ name, cp_idx, data->count, data->duration);
+ }
+}
+
+static int qcom_ddr_stats_show(struct seq_file *s, void *d)
+{
+ struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES];
+ void __iomem *reg = (void __iomem *)s->private;
+ u32 entry_count;
+ int i;
+
+ entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR);
+ if (entry_count > DDR_STATS_MAX_NUM_MODES)
+ return 0;
+
+ reg += DDR_STATS_ENTRY_START_ADDR;
+ memcpy_fromio(data, reg, sizeof(struct ddr_stats_entry) * entry_count);
+
+ for (i = 0; i < entry_count; i++)
+ qcom_ddr_stats_print(s, &data[i]);
+
+ return 0;
+}
+
DEFINE_SHOW_ATTRIBUTE(qcom_soc_sleep_stats);
DEFINE_SHOW_ATTRIBUTE(qcom_subsystem_sleep_stats);
+DEFINE_SHOW_ATTRIBUTE(qcom_ddr_stats);
+
+static void qcom_create_ddr_stat_files(struct dentry *root, void __iomem *reg,
+ const struct stats_config *config)
+{
+ u32 key;
+
+ if (!config->ddr_stats_offset)
+ return;
+
+ key = readl_relaxed(reg + config->ddr_stats_offset + DDR_STATS_MAGIC_KEY_ADDR);
+ if (key == DDR_STATS_MAGIC_KEY)
+ debugfs_create_file("ddr_stats", 0400, root,
+ (__force void *)reg + config->ddr_stats_offset,
+ &qcom_ddr_stats_fops);
+}
static void qcom_create_soc_sleep_stat_files(struct dentry *root, void __iomem *reg,
struct stats_data *d,
@@ -212,6 +309,7 @@ static int qcom_stats_probe(struct platform_device *pdev)
qcom_create_subsystem_stat_files(root, config);
qcom_create_soc_sleep_stat_files(root, reg, d, config);
+ qcom_create_ddr_stat_files(root, reg, config);
platform_set_drvdata(pdev, root);
@@ -254,6 +352,7 @@ static const struct stats_config rpmh_data_sdm845 = {
static const struct stats_config rpmh_data = {
.stats_offset = 0x48,
+ .ddr_stats_offset = 0xb8,
.num_records = 3,
.appended_stats_avail = false,
.dynamic_offset = false,
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] soc: qcom: qcom_stats: Add QMP support for syncing ddr stats
2025-04-29 3:52 [PATCH 0/3] soc: qcom: qcom_stats: Add DDR stats Maulik Shah
2025-04-29 3:52 ` [PATCH 1/3] soc: qcom: qcom_stats: Add support to read DDR statistic Maulik Shah
@ 2025-04-29 3:52 ` Maulik Shah
2025-04-29 10:39 ` Konrad Dybcio
2025-04-29 3:52 ` [PATCH 3/3] arm64: dts: qcom: Add QMP handle for qcom_stats Maulik Shah
2 siblings, 1 reply; 10+ messages in thread
From: Maulik Shah @ 2025-04-29 3:52 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson, Maulik Shah
Recent SoCs (SM8450 onwards) require QMP command to be sent before reading
ddr stats. The duration field of ddr stats will get populated only if QMP
command is sent.
Add support to send ddr stats freqsync QMP command.
Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
---
drivers/soc/qcom/qcom_stats.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c
index ee11fb0919742454d40442112787c087ba8f6598..15bdb8e6a542bbab34f788ac4270f7759ca83e3c 100644
--- a/drivers/soc/qcom/qcom_stats.c
+++ b/drivers/soc/qcom/qcom_stats.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/seq_file.h>
+#include <linux/soc/qcom/qcom_aoss.h>
#include <linux/soc/qcom/smem.h>
#include <clocksource/arm_arch_timer.h>
@@ -37,6 +38,8 @@
#define DDR_STATS_TYPE(data) FIELD_GET(GENMASK(15, 8), data)
#define DDR_STATS_FREQ(data) FIELD_GET(GENMASK(31, 16), data)
+static struct qmp *qcom_stats_qmp;
+
struct subsystem_data {
const char *name;
u32 smem_item;
@@ -188,12 +191,28 @@ static int qcom_ddr_stats_show(struct seq_file *s, void *d)
struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES];
void __iomem *reg = (void __iomem *)s->private;
u32 entry_count;
- int i;
+ int i, ret;
entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR);
if (entry_count > DDR_STATS_MAX_NUM_MODES)
return 0;
+ if (qcom_stats_qmp) {
+ /*
+ * Recent SoCs (SM8450 onwards) do not have duration field
+ * populated from boot up onwards for both DDR LPM Stats
+ * and DDR Frequency Stats.
+ *
+ * Send QMP message to Always on processor which will
+ * populate duration field into MSG RAM area.
+ *
+ * Sent everytime to read latest data.
+ */
+ ret = qmp_send(qcom_stats_qmp, "{class: ddr, action: freqsync}");
+ if (ret)
+ seq_printf(s, "Error updating duration field %d\n", ret);
+ }
+
reg += DDR_STATS_ENTRY_START_ADDR;
memcpy_fromio(data, reg, sizeof(struct ddr_stats_entry) * entry_count);
@@ -310,6 +329,15 @@ static int qcom_stats_probe(struct platform_device *pdev)
qcom_create_subsystem_stat_files(root, config);
qcom_create_soc_sleep_stat_files(root, reg, d, config);
qcom_create_ddr_stat_files(root, reg, config);
+ /*
+ * QMP is used for DDR stats syncing to MSG RAM for certain SoCs having
+ * (SM8450 onwards). The prior SoCs do not need QMP handle as the required
+ * stats are already present in MSG RAM, provided the DDR_STATS_MAGIC_KEY
+ * matches.
+ */
+ qcom_stats_qmp = qmp_get(&pdev->dev);
+ if (IS_ERR(qcom_stats_qmp))
+ qcom_stats_qmp = NULL;
platform_set_drvdata(pdev, root);
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] arm64: dts: qcom: Add QMP handle for qcom_stats
2025-04-29 3:52 [PATCH 0/3] soc: qcom: qcom_stats: Add DDR stats Maulik Shah
2025-04-29 3:52 ` [PATCH 1/3] soc: qcom: qcom_stats: Add support to read DDR statistic Maulik Shah
2025-04-29 3:52 ` [PATCH 2/3] soc: qcom: qcom_stats: Add QMP support for syncing ddr stats Maulik Shah
@ 2025-04-29 3:52 ` Maulik Shah
2 siblings, 0 replies; 10+ messages in thread
From: Maulik Shah @ 2025-04-29 3:52 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson, Maulik Shah
Add QMP handle which is used to send QMP command to always on processor
to populate DDR stats. Add QMP handle for SM8450/SM8550/SM8650/SM8750.
Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/sm8450.dtsi | 1 +
arch/arm64/boot/dts/qcom/sm8550.dtsi | 1 +
arch/arm64/boot/dts/qcom/sm8650.dtsi | 1 +
arch/arm64/boot/dts/qcom/sm8750.dtsi | 1 +
4 files changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index 54c6d0fdb2afa51084c510eddc341d6087189611..33574ad706b915136546c7f92c7cd0b8a0d62b7e 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -3739,6 +3739,7 @@ aoss_qmp: power-management@c300000 {
sram@c3f0000 {
compatible = "qcom,rpmh-stats";
reg = <0 0x0c3f0000 0 0x400>;
+ qcom,qmp = <&aoss_qmp>;
};
spmi_bus: spmi@c400000 {
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
index 82cabf777cd2c1dc87457aeede913873e7322ec2..e8371a90b9b98fbc12a429def8f6246c6418540a 100644
--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
@@ -3943,6 +3943,7 @@ aoss_qmp: power-management@c300000 {
sram@c3f0000 {
compatible = "qcom,rpmh-stats";
reg = <0 0x0c3f0000 0 0x400>;
+ qcom,qmp = <&aoss_qmp>;
};
spmi_bus: spmi@c400000 {
diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
index c2937f7217943c4ca91a91eadc8259b2d6a01372..875b5a89d2555f258665c881ee3d96965b6d7a6a 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -5725,6 +5725,7 @@ aoss_qmp: power-management@c300000 {
sram@c3f0000 {
compatible = "qcom,rpmh-stats";
reg = <0 0x0c3f0000 0 0x400>;
+ qcom,qmp = <&aoss_qmp>;
};
spmi_bus: spmi@c400000 {
diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi
index 149d2ed17641a085d510f3a8eab5a96304787f0c..4c54ed84e2d1ec836438448e2a02b6fe028f4c24 100644
--- a/arch/arm64/boot/dts/qcom/sm8750.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
@@ -2490,6 +2490,7 @@ aoss_qmp: power-management@c300000 {
sram@c3f0000 {
compatible = "qcom,rpmh-stats";
reg = <0x0 0x0c3f0000 0x0 0x400>;
+ qcom,qmp = <&aoss_qmp>;
};
spmi_bus: spmi@c400000 {
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] soc: qcom: qcom_stats: Add support to read DDR statistic
2025-04-29 3:52 ` [PATCH 1/3] soc: qcom: qcom_stats: Add support to read DDR statistic Maulik Shah
@ 2025-04-29 10:34 ` Konrad Dybcio
2025-05-20 9:59 ` Maulik Shah (mkshah)
0 siblings, 1 reply; 10+ messages in thread
From: Konrad Dybcio @ 2025-04-29 10:34 UTC (permalink / raw)
To: Maulik Shah, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson
On 4/29/25 5:52 AM, Maulik Shah wrote:
> DDR statistic provide different DDR LPM and DDR frequency statistic.
> Add support to read from MSGRAM and display via debugfs.
>
> Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
> ---
> drivers/soc/qcom/qcom_stats.c | 99 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 99 insertions(+)
>
> diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c
> index 5de99cf59b9fbe32c0580e371c3cc362dfabb895..ee11fb0919742454d40442112787c087ba8f6598 100644
> --- a/drivers/soc/qcom/qcom_stats.c
> +++ b/drivers/soc/qcom/qcom_stats.c
> @@ -1,8 +1,10 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /*
> * Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved.
> */
>
> +#include <linux/bitfield.h>
> #include <linux/debugfs.h>
> #include <linux/device.h>
> #include <linux/io.h>
> @@ -24,6 +26,17 @@
> #define ACCUMULATED_OFFSET 0x18
> #define CLIENT_VOTES_OFFSET 0x20
>
> +#define DDR_STATS_MAGIC_KEY 0xA1157A75
> +#define DDR_STATS_MAX_NUM_MODES 0x14
Numbers (count) make more sense in decimal
> +#define DDR_STATS_MAGIC_KEY_ADDR 0x0
> +#define DDR_STATS_NUM_MODES_ADDR 0x4
> +#define DDR_STATS_ENTRY_START_ADDR 0x8
[...]
> +static void qcom_ddr_stats_print(struct seq_file *s, struct ddr_stats_entry *data)
> +{
> + u32 cp_idx, name;
> +
> + /*
> + * DDR statistic have two different types of details encoded.
> + * (1) DDR LPM Stats
> + * (2) DDR Frequency Stats
> + *
> + * The name field have details like which type of DDR stat (bits 8:15)
> + * along with other details as explained below
> + *
> + * In case of DDR LPM stat, name field will be encoded as,
> + * Bits - Meaning
> + * 0:7 - DDR LPM name, can be of 0xd4, 0xd3, 0x11 and 0xd0.
> + * 8:15 - 0x0 (indicates its a LPM stat)
> + * 16:31 - Unused
> + *
> + * In case of DDR FREQ stats, name field will be encoded as,
> + * Bits - Meaning
> + * 0:4 - DDR Clock plan index (CP IDX)
> + * 5:7 - Unused
> + * 8:15 - 0x1 (indicates its Freq stat)
> + * 16:31 - Frequency value in Mhz
> + */
> + name = DDR_STATS_TYPE(data->name);
> + if (name == 0x0) {
> + name = DDR_STATS_LPM_NAME(data->name);
I'm not super keen on reusing the 'name' variable, maybe turn the
outer if-condition to switch(DDR_STATS_TYPE(data->name))
> + seq_printf(s, "DDR LPM Stat Name:0x%x\tcount:%u\tDuration (ticks):%llu\n",
> + name, data->count, data->duration);
> + } else if (name == 0x1) {
> + name = DDR_STATS_FREQ(data->name);
> + if (!name || !data->count)
> + return;
> +
> + cp_idx = DDR_STATS_CP_IDX(data->name);
> + seq_printf(s, "DDR Freq %uMhz:\tCP IDX:%u\tcount:%u\tDuration (ticks):%llu\n",
> + name, cp_idx, data->count, data->duration);
> + }
> +}
> +
> +static int qcom_ddr_stats_show(struct seq_file *s, void *d)
> +{
> + struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES];
> + void __iomem *reg = (void __iomem *)s->private;
> + u32 entry_count;
> + int i;
> +
> + entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR);
> + if (entry_count > DDR_STATS_MAX_NUM_MODES)
> + return 0;
-EINVAL
Konrad
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] soc: qcom: qcom_stats: Add QMP support for syncing ddr stats
2025-04-29 3:52 ` [PATCH 2/3] soc: qcom: qcom_stats: Add QMP support for syncing ddr stats Maulik Shah
@ 2025-04-29 10:39 ` Konrad Dybcio
2025-05-20 9:55 ` Maulik Shah (mkshah)
0 siblings, 1 reply; 10+ messages in thread
From: Konrad Dybcio @ 2025-04-29 10:39 UTC (permalink / raw)
To: Maulik Shah, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson
On 4/29/25 5:52 AM, Maulik Shah wrote:
> Recent SoCs (SM8450 onwards) require QMP command to be sent before reading
> ddr stats. The duration field of ddr stats will get populated only if QMP
> command is sent.
>
> Add support to send ddr stats freqsync QMP command.
>
> Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
> ---
> drivers/soc/qcom/qcom_stats.c | 30 +++++++++++++++++++++++++++++-
> 1 file changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c
> index ee11fb0919742454d40442112787c087ba8f6598..15bdb8e6a542bbab34f788ac4270f7759ca83e3c 100644
> --- a/drivers/soc/qcom/qcom_stats.c
> +++ b/drivers/soc/qcom/qcom_stats.c
> @@ -13,6 +13,7 @@
> #include <linux/platform_device.h>
> #include <linux/seq_file.h>
>
> +#include <linux/soc/qcom/qcom_aoss.h>
> #include <linux/soc/qcom/smem.h>
> #include <clocksource/arm_arch_timer.h>
>
> @@ -37,6 +38,8 @@
> #define DDR_STATS_TYPE(data) FIELD_GET(GENMASK(15, 8), data)
> #define DDR_STATS_FREQ(data) FIELD_GET(GENMASK(31, 16), data)
>
> +static struct qmp *qcom_stats_qmp;
> +
> struct subsystem_data {
> const char *name;
> u32 smem_item;
> @@ -188,12 +191,28 @@ static int qcom_ddr_stats_show(struct seq_file *s, void *d)
> struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES];
> void __iomem *reg = (void __iomem *)s->private;
> u32 entry_count;
> - int i;
> + int i, ret;
>
> entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR);
> if (entry_count > DDR_STATS_MAX_NUM_MODES)
> return 0;
>
> + if (qcom_stats_qmp) {
> + /*
> + * Recent SoCs (SM8450 onwards) do not have duration field
> + * populated from boot up onwards for both DDR LPM Stats
> + * and DDR Frequency Stats.
> + *
> + * Send QMP message to Always on processor which will
> + * populate duration field into MSG RAM area.
> + *
> + * Sent everytime to read latest data.
> + */
> + ret = qmp_send(qcom_stats_qmp, "{class: ddr, action: freqsync}");
> + if (ret)
> + seq_printf(s, "Error updating duration field %d\n", ret);
let's just return some error, instead of printing "error" successfully
> + }
> +
> reg += DDR_STATS_ENTRY_START_ADDR;
> memcpy_fromio(data, reg, sizeof(struct ddr_stats_entry) * entry_count);
>
> @@ -310,6 +329,15 @@ static int qcom_stats_probe(struct platform_device *pdev)
> qcom_create_subsystem_stat_files(root, config);
> qcom_create_soc_sleep_stat_files(root, reg, d, config);
> qcom_create_ddr_stat_files(root, reg, config);
> + /*
> + * QMP is used for DDR stats syncing to MSG RAM for certain SoCs having
having what? (you could drop that word and the sentence would still make sense)
> + * (SM8450 onwards). The prior SoCs do not need QMP handle as the required
> + * stats are already present in MSG RAM, provided the DDR_STATS_MAGIC_KEY
> + * matches.
> + */
Konrad
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] soc: qcom: qcom_stats: Add QMP support for syncing ddr stats
2025-04-29 10:39 ` Konrad Dybcio
@ 2025-05-20 9:55 ` Maulik Shah (mkshah)
2025-05-20 14:44 ` Konrad Dybcio
0 siblings, 1 reply; 10+ messages in thread
From: Maulik Shah (mkshah) @ 2025-05-20 9:55 UTC (permalink / raw)
To: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson
On 4/29/2025 4:09 PM, Konrad Dybcio wrote:
> On 4/29/25 5:52 AM, Maulik Shah wrote:
>> + if (qcom_stats_qmp) {
>> + /*
>> + * Recent SoCs (SM8450 onwards) do not have duration field
>> + * populated from boot up onwards for both DDR LPM Stats
>> + * and DDR Frequency Stats.
>> + *
>> + * Send QMP message to Always on processor which will
>> + * populate duration field into MSG RAM area.
>> + *
>> + * Sent everytime to read latest data.
>> + */
>> + ret = qmp_send(qcom_stats_qmp, "{class: ddr, action: freqsync}");
>> + if (ret)
>> + seq_printf(s, "Error updating duration field %d\n", ret);
>
> let's just return some error, instead of printing "error" successfully
Should i drop the print and also error, From details given in commit message of [1]
which made the qcom_subsystem_sleep_stats_show() function return 0
in order to run command like below to collect the stats without interspersed errors
grep ^ /sys/kernel/debug/qcom_stats/*
The same may break if return error from ddr stats too.
[1] https://lore.kernel.org/r/20230119032329.2909383-1-swboyd@chromium.org
>
>> + }
>> +
>> reg += DDR_STATS_ENTRY_START_ADDR;
>> memcpy_fromio(data, reg, sizeof(struct ddr_stats_entry) * entry_count);
>>
>> @@ -310,6 +329,15 @@ static int qcom_stats_probe(struct platform_device *pdev)
>> qcom_create_subsystem_stat_files(root, config);
>> qcom_create_soc_sleep_stat_files(root, reg, d, config);
>> qcom_create_ddr_stat_files(root, reg, config);
>> + /*
>> + * QMP is used for DDR stats syncing to MSG RAM for certain SoCs having
>
> having what? (you could drop that word and the sentence would still make sense)
I will update the sentence in v2.
Thanks,
Maulik
>
>> + * (SM8450 onwards). The prior SoCs do not need QMP handle as the required
>> + * stats are already present in MSG RAM, provided the DDR_STATS_MAGIC_KEY
>> + * matches.
>> + */
>
> Konrad
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] soc: qcom: qcom_stats: Add support to read DDR statistic
2025-04-29 10:34 ` Konrad Dybcio
@ 2025-05-20 9:59 ` Maulik Shah (mkshah)
2025-05-20 14:41 ` Konrad Dybcio
0 siblings, 1 reply; 10+ messages in thread
From: Maulik Shah (mkshah) @ 2025-05-20 9:59 UTC (permalink / raw)
To: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson
On 4/29/2025 4:04 PM, Konrad Dybcio wrote:
> On 4/29/25 5:52 AM, Maulik Shah wrote:
>> DDR statistic provide different DDR LPM and DDR frequency statistic.
>> +#define DDR_STATS_MAGIC_KEY 0xA1157A75
>> +#define DDR_STATS_MAX_NUM_MODES 0x14
>
> Numbers (count) make more sense in decimal
>
I will change to decimal.
>> +#define DDR_STATS_MAGIC_KEY_ADDR 0x0
>> +#define DDR_STATS_NUM_MODES_ADDR 0x4
>> +#define DDR_STATS_ENTRY_START_ADDR 0x8
>
> [...]
>
>> + */
>> + name = DDR_STATS_TYPE(data->name);
>> + if (name == 0x0) {
>> + name = DDR_STATS_LPM_NAME(data->name);
>
> I'm not super keen on reusing the 'name' variable, maybe turn the
> outer if-condition to switch(DDR_STATS_TYPE(data->name))
Okay. I will use switch-case.
>
>
>> +}
>> +
>> +static int qcom_ddr_stats_show(struct seq_file *s, void *d)
>> +{
>> + struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES];
>> + void __iomem *reg = (void __iomem *)s->private;
>> + u32 entry_count;
>> + int i;
>> +
>> + entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR);
>> + if (entry_count > DDR_STATS_MAX_NUM_MODES)
>> + return 0;
>
> -EINVAL
>
> Konrad
I kept this return as success from details given in commit message of [1]
which made the qcom_subsystem_sleep_stats_show() function return 0
in order to run command like below to collect the stats without interspersed errors
grep ^ /sys/kernel/debug/qcom_stats/*
The same may break if return error from ddr stats too.
[1] https://lore.kernel.org/r/20230119032329.2909383-1-swboyd@chromium.org
Thanks,
Maulik
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] soc: qcom: qcom_stats: Add support to read DDR statistic
2025-05-20 9:59 ` Maulik Shah (mkshah)
@ 2025-05-20 14:41 ` Konrad Dybcio
0 siblings, 0 replies; 10+ messages in thread
From: Konrad Dybcio @ 2025-05-20 14:41 UTC (permalink / raw)
To: Maulik Shah (mkshah), Konrad Dybcio, Bjorn Andersson,
Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson
On 5/20/25 11:59 AM, Maulik Shah (mkshah) wrote:
>
[...]
>>> +static int qcom_ddr_stats_show(struct seq_file *s, void *d)
>>> +{
>>> + struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES];
>>> + void __iomem *reg = (void __iomem *)s->private;
>>> + u32 entry_count;
>>> + int i;
>>> +
>>> + entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR);
>>> + if (entry_count > DDR_STATS_MAX_NUM_MODES)
>>> + return 0;
>>
>> -EINVAL
>>
>> Konrad
>
> I kept this return as success from details given in commit message of [1]
> which made the qcom_subsystem_sleep_stats_show() function return 0
> in order to run command like below to collect the stats without interspersed errors
> grep ^ /sys/kernel/debug/qcom_stats/*
>
> The same may break if return error from ddr stats too.
Stephen mentioned that the errors may have appeared because the subsystems
may only populate data after the probe of the stats driver.
I would assume and hope the DDR stats aren't affected by this..
Konrad
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] soc: qcom: qcom_stats: Add QMP support for syncing ddr stats
2025-05-20 9:55 ` Maulik Shah (mkshah)
@ 2025-05-20 14:44 ` Konrad Dybcio
0 siblings, 0 replies; 10+ messages in thread
From: Konrad Dybcio @ 2025-05-20 14:44 UTC (permalink / raw)
To: Maulik Shah (mkshah), Konrad Dybcio, Bjorn Andersson,
Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, devicetree, Marijn Suijten,
Doug Anderson
On 5/20/25 11:55 AM, Maulik Shah (mkshah) wrote:
>
>
> On 4/29/2025 4:09 PM, Konrad Dybcio wrote:
>> On 4/29/25 5:52 AM, Maulik Shah wrote:
>>> + if (qcom_stats_qmp) {
>>> + /*
>>> + * Recent SoCs (SM8450 onwards) do not have duration field
>>> + * populated from boot up onwards for both DDR LPM Stats
>>> + * and DDR Frequency Stats.
>>> + *
>>> + * Send QMP message to Always on processor which will
>>> + * populate duration field into MSG RAM area.
>>> + *
>>> + * Sent everytime to read latest data.
>>> + */
>>> + ret = qmp_send(qcom_stats_qmp, "{class: ddr, action: freqsync}");
>>> + if (ret)
>>> + seq_printf(s, "Error updating duration field %d\n", ret);
>>
>> let's just return some error, instead of printing "error" successfully
>
> Should i drop the print and also error, From details given in commit message of [1]
> which made the qcom_subsystem_sleep_stats_show() function return 0
> in order to run command like below to collect the stats without interspersed errors
> grep ^ /sys/kernel/debug/qcom_stats/*
>
> The same may break if return error from ddr stats too.
You're trying to print potentially garbage data if this fails
Konrad
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-05-20 14:44 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-29 3:52 [PATCH 0/3] soc: qcom: qcom_stats: Add DDR stats Maulik Shah
2025-04-29 3:52 ` [PATCH 1/3] soc: qcom: qcom_stats: Add support to read DDR statistic Maulik Shah
2025-04-29 10:34 ` Konrad Dybcio
2025-05-20 9:59 ` Maulik Shah (mkshah)
2025-05-20 14:41 ` Konrad Dybcio
2025-04-29 3:52 ` [PATCH 2/3] soc: qcom: qcom_stats: Add QMP support for syncing ddr stats Maulik Shah
2025-04-29 10:39 ` Konrad Dybcio
2025-05-20 9:55 ` Maulik Shah (mkshah)
2025-05-20 14:44 ` Konrad Dybcio
2025-04-29 3:52 ` [PATCH 3/3] arm64: dts: qcom: Add QMP handle for qcom_stats Maulik Shah
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).