qcs6490-edge: bump to 6.17
This commit is contained in:
parent
3ad0696e00
commit
fc0a8039c4
@ -17,7 +17,7 @@ declare -g SERIALCON="ttyMSM0"
|
||||
case $BRANCH in
|
||||
|
||||
edge)
|
||||
declare -g KERNEL_MAJOR_MINOR="6.16" # Major and minor versions of this kernel.
|
||||
declare -g KERNEL_MAJOR_MINOR="6.17" # Major and minor versions of this kernel.
|
||||
declare -g -i KERNEL_GIT_CACHE_TTL=120 # 2 minutes; this is a high-traffic repo
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -1,173 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Maulik Shah <maulik.shah@oss.qualcomm.com>
|
||||
Date: Wed, 11 Jun 2025 11:33:45 +0530
|
||||
Subject: soc: qcom: qcom_stats: Add support to read DDR statistic
|
||||
|
||||
DDR statistic provide different DDR LPM and DDR frequency statistic.
|
||||
Add support to read from MSGRAM and display via debugfs.
|
||||
|
||||
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
|
||||
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 111111111111..222222222222 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 20
|
||||
+#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;
|
||||
+
|
||||
+ /*
|
||||
+ * 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
|
||||
+ */
|
||||
+ switch (DDR_STATS_TYPE(data->name)) {
|
||||
+ case 0:
|
||||
+ seq_printf(s, "DDR LPM Stat Name:0x%lx\tcount:%u\tDuration (ticks):%llu\n",
|
||||
+ DDR_STATS_LPM_NAME(data->name), data->count, data->duration);
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ if (!data->count || !DDR_STATS_FREQ(data->name))
|
||||
+ return;
|
||||
+
|
||||
+ cp_idx = DDR_STATS_CP_IDX(data->name);
|
||||
+ seq_printf(s, "DDR Freq %luMhz:\tCP IDX:%u\tcount:%u\tDuration (ticks):%llu\n",
|
||||
+ DDR_STATS_FREQ(data->name), cp_idx, data->count, data->duration);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+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 -EINVAL;
|
||||
+
|
||||
+ 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,
|
||||
--
|
||||
Armbian
|
||||
|
||||
@ -1,93 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Maulik Shah <maulik.shah@oss.qualcomm.com>
|
||||
Date: Wed, 11 Jun 2025 11:33:46 +0530
|
||||
Subject: soc: qcom: qcom_stats: Add QMP support for syncing ddr stats
|
||||
|
||||
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>
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
|
||||
---
|
||||
drivers/soc/qcom/qcom_stats.c | 36 +++++++++-
|
||||
1 file changed, 35 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c
|
||||
index 111111111111..222222222222 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 -EINVAL;
|
||||
|
||||
+ 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 every time to read latest data.
|
||||
+ */
|
||||
+ ret = qmp_send(qcom_stats_qmp, "{class: ddr, action: freqsync}");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
reg += DDR_STATS_ENTRY_START_ADDR;
|
||||
memcpy_fromio(data, reg, sizeof(struct ddr_stats_entry) * entry_count);
|
||||
|
||||
@@ -304,6 +323,21 @@ static int qcom_stats_probe(struct platform_device *pdev)
|
||||
|
||||
for (i = 0; i < config->num_records; i++)
|
||||
d[i].appended_stats_avail = config->appended_stats_avail;
|
||||
+ /*
|
||||
+ * QMP is used for DDR stats syncing to MSG RAM for recent SoCs (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)) {
|
||||
+ /* We ignore error if QMP is not defined/needed */
|
||||
+ if (!of_property_present(pdev->dev.of_node, "qcom,qmp"))
|
||||
+ qcom_stats_qmp = NULL;
|
||||
+ else if (PTR_ERR(qcom_stats_qmp) == -EPROBE_DEFER)
|
||||
+ return -EPROBE_DEFER;
|
||||
+ else
|
||||
+ return PTR_ERR(qcom_stats_qmp);
|
||||
+ }
|
||||
|
||||
root = debugfs_create_dir("qcom_stats", NULL);
|
||||
|
||||
--
|
||||
Armbian
|
||||
|
||||
@ -33,9 +33,9 @@ index 111111111111..222222222222 100644
|
||||
},
|
||||
};
|
||||
|
||||
@@ -128,32 +131,45 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = {
|
||||
@@ -128,29 +131,42 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = {
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x69000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
- .merge_3d = 0,
|
||||
+ .merge_3d = MERGE_3D_0,
|
||||
@ -43,7 +43,6 @@ index 111111111111..222222222222 100644
|
||||
}, {
|
||||
.name = "pingpong_1", .id = PINGPONG_1,
|
||||
.base = 0x6a000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
- .merge_3d = 0,
|
||||
+ .merge_3d = MERGE_3D_0,
|
||||
@ -51,7 +50,6 @@ index 111111111111..222222222222 100644
|
||||
}, {
|
||||
.name = "pingpong_2", .id = PINGPONG_2,
|
||||
.base = 0x6b000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
- .merge_3d = 0,
|
||||
+ .merge_3d = MERGE_3D_1,
|
||||
@ -59,7 +57,6 @@ index 111111111111..222222222222 100644
|
||||
}, {
|
||||
.name = "pingpong_3", .id = PINGPONG_3,
|
||||
.base = 0x6c000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
- .merge_3d = 0,
|
||||
+ .merge_3d = MERGE_3D_1,
|
||||
Loading…
Reference in New Issue
Block a user