Merge tag 'KERNEL.PLATFORM.1.0.r1-18400-kernel.0' of https://git.codelinaro.org/clo/la/kernel/msm-5.10 into android13-5.10-waipio
"KERNEL.PLATFORM.1.0.r1-18400-kernel.0" * tag 'KERNEL.PLATFORM.1.0.r1-18400-kernel.0' of https://git.codelinaro.org/clo/la/kernel/msm-5.10: drivers: dcvs: llcc_miss: Remove Secure Device Check defconfig: Enable PM8008 module for neo LE arm64: config: Enable LLCC Miss and BUS Profile drivers: dcvs: llcc_miss: Add llcc miss stats driver interconnect: qcom: icc-rpmh: enable support for no secondary display clk: qcom: gcc-anorak: Add CLK_DONT_HOLD_STATE to usb2_clkref soc: qcom: smcinvoke: Add dependent modules for smcinvoke drivers: scm: Change order of dload legacy support check i2c: i2c-master-msm-geni: add null pointer check in event call back drivers: qseecom: Define .compat_ioctl based on CONFIG_COMPAT build.config: Move smcinvoke and qseecom to early init msm: kgsl: Fix gpu work period update for legacy path Merge remote-tracking branch into HEAD UPSTREAM: af_unix: Fix garbage collector racing against connect() ANDROID: irq: put irq_resolve_mapping under protection of __irq_enter_raw UPSTREAM: af_unix: Do not use atomic ops for unix_sk(sk)->inflight. ANDROID: ABI fixup for abi break in struct dst_ops BACKPORT: net: fix __dst_negative_advice() race power: reset: Disable support of dynamic download mode (ramdump) Conflicts: android/abi_gki_aarch64.xml Change-Id: Ibf2399d85835c5e2e28569a4df8c5fd4e7b3fb72
This commit is contained in:
commit
bcf90117d7
@ -1,2 +1,2 @@
|
|||||||
c02e95e82b343fe03d03dfd6fb74ecc2077e1ee3
|
7e657aa362f21c8fb472e03a22795b18f831a178
|
||||||
android12-5.10-2024-05_r1
|
android12-5.10-2024-08_r1
|
||||||
|
@ -78522,9 +78522,9 @@
|
|||||||
<pointer-type-def type-id='512ac7cc' size-in-bits='64' id='ac58af12'/>
|
<pointer-type-def type-id='512ac7cc' size-in-bits='64' id='ac58af12'/>
|
||||||
<pointer-type-def type-id='b254b8db' size-in-bits='64' id='ac5f2363'/>
|
<pointer-type-def type-id='b254b8db' size-in-bits='64' id='ac5f2363'/>
|
||||||
<pointer-type-def type-id='49a0ad34' size-in-bits='64' id='ac6963b2'/>
|
<pointer-type-def type-id='49a0ad34' size-in-bits='64' id='ac6963b2'/>
|
||||||
<class-decl name='prot_inuse' size-in-bits='2048' is-struct='yes' visibility='default' filepath='net/core/sock.c' line='3371' column='1' id='ac763c5d'>
|
<class-decl name='prot_inuse' size-in-bits='2048' is-struct='yes' visibility='default' filepath='net/core/sock.c' line='3369' column='1' id='ac763c5d'>
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
<data-member access='public' layout-offset-in-bits='0'>
|
||||||
<var-decl name='val' type-id='93e41790' visibility='default' filepath='net/core/sock.c' line='3372' column='1'/>
|
<var-decl name='val' type-id='93e41790' visibility='default' filepath='net/core/sock.c' line='3370' column='1'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<function-type size-in-bits='64' id='ac765b39'>
|
<function-type size-in-bits='64' id='ac765b39'>
|
||||||
|
2
arch/arm64/configs/vendor/anorak.config
vendored
2
arch/arm64/configs/vendor/anorak.config
vendored
@ -214,6 +214,7 @@ CONFIG_PWM_QTI_LPG=m
|
|||||||
CONFIG_QCOM_AOSS_QMP=m
|
CONFIG_QCOM_AOSS_QMP=m
|
||||||
CONFIG_QCOM_BALANCE_ANON_FILE_RECLAIM=y
|
CONFIG_QCOM_BALANCE_ANON_FILE_RECLAIM=y
|
||||||
CONFIG_QCOM_BAM_DMA=m
|
CONFIG_QCOM_BAM_DMA=m
|
||||||
|
CONFIG_QCOM_BUS_PROF=m
|
||||||
CONFIG_QCOM_BWMON=m
|
CONFIG_QCOM_BWMON=m
|
||||||
CONFIG_QCOM_BWPROF=m
|
CONFIG_QCOM_BWPROF=m
|
||||||
# CONFIG_QCOM_CLK_APCC_MSM8996 is not set
|
# CONFIG_QCOM_CLK_APCC_MSM8996 is not set
|
||||||
@ -249,6 +250,7 @@ CONFIG_QCOM_KGSL_CONTEXT_DEBUG=y
|
|||||||
CONFIG_QCOM_KGSL_IOCOHERENCY_DEFAULT=y
|
CONFIG_QCOM_KGSL_IOCOHERENCY_DEFAULT=y
|
||||||
CONFIG_QCOM_LAZY_MAPPING=m
|
CONFIG_QCOM_LAZY_MAPPING=m
|
||||||
CONFIG_QCOM_LLCC=m
|
CONFIG_QCOM_LLCC=m
|
||||||
|
CONFIG_QCOM_LLCC_MISS=m
|
||||||
CONFIG_QCOM_LLCC_PERFMON=m
|
CONFIG_QCOM_LLCC_PERFMON=m
|
||||||
CONFIG_QCOM_LLCC_PMU=m
|
CONFIG_QCOM_LLCC_PMU=m
|
||||||
CONFIG_QCOM_LOGBUF_VENDOR_HOOKS=m
|
CONFIG_QCOM_LOGBUF_VENDOR_HOOKS=m
|
||||||
|
1
arch/arm64/configs/vendor/neo_le.config
vendored
1
arch/arm64/configs/vendor/neo_le.config
vendored
@ -369,6 +369,7 @@ CONFIG_REGMAP_QTI_DEBUGFS=m
|
|||||||
CONFIG_REGMAP_SPMI=m
|
CONFIG_REGMAP_SPMI=m
|
||||||
CONFIG_REGULATOR_DEBUG_CONTROL=y
|
CONFIG_REGULATOR_DEBUG_CONTROL=y
|
||||||
CONFIG_REGULATOR_PROXY_CONSUMER=y
|
CONFIG_REGULATOR_PROXY_CONSUMER=y
|
||||||
|
CONFIG_REGULATOR_QCOM_PM8008=m
|
||||||
CONFIG_REGULATOR_QCOM_RPMH=m
|
CONFIG_REGULATOR_QCOM_RPMH=m
|
||||||
CONFIG_REGULATOR_QTI_FIXED_VOLTAGE=y
|
CONFIG_REGULATOR_QTI_FIXED_VOLTAGE=y
|
||||||
CONFIG_REGULATOR_RPMH=m
|
CONFIG_REGULATOR_RPMH=m
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk-provider.h>
|
#include <linux/clk-provider.h>
|
||||||
@ -3773,6 +3773,7 @@ static struct clk_branch gcc_usb2_0_clkref_en = {
|
|||||||
.enable_mask = BIT(0),
|
.enable_mask = BIT(0),
|
||||||
.hw.init = &(struct clk_init_data){
|
.hw.init = &(struct clk_init_data){
|
||||||
.name = "gcc_usb2_0_clkref_en",
|
.name = "gcc_usb2_0_clkref_en",
|
||||||
|
.flags = CLK_DONT_HOLD_STATE,
|
||||||
.ops = &clk_branch2_ops,
|
.ops = &clk_branch2_ops,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -528,18 +528,15 @@ int __qcom_scm_set_dload_mode(struct device *dev, enum qcom_download_mode mode)
|
|||||||
void qcom_scm_set_download_mode(enum qcom_download_mode mode,
|
void qcom_scm_set_download_mode(enum qcom_download_mode mode,
|
||||||
phys_addr_t tcsr_boot_misc)
|
phys_addr_t tcsr_boot_misc)
|
||||||
{
|
{
|
||||||
bool avail;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct device *dev = __scm ? __scm->dev : NULL;
|
struct device *dev = __scm ? __scm->dev : NULL;
|
||||||
|
|
||||||
avail = __qcom_scm_is_call_available(dev,
|
if (tcsr_boot_misc || (__scm && __scm->dload_mode_addr)) {
|
||||||
QCOM_SCM_SVC_BOOT,
|
ret = qcom_scm_io_writel(tcsr_boot_misc ? : __scm->dload_mode_addr, mode);
|
||||||
QCOM_SCM_BOOT_SET_DLOAD_MODE);
|
} else if (__qcom_scm_is_call_available(dev,
|
||||||
if (avail) {
|
QCOM_SCM_SVC_BOOT,
|
||||||
|
QCOM_SCM_BOOT_SET_DLOAD_MODE)) {
|
||||||
ret = __qcom_scm_set_dload_mode(dev, mode);
|
ret = __qcom_scm_set_dload_mode(dev, mode);
|
||||||
} else if (tcsr_boot_misc || (__scm && __scm->dload_mode_addr)) {
|
|
||||||
ret = qcom_scm_io_writel(
|
|
||||||
tcsr_boot_misc ? : __scm->dload_mode_addr, mode);
|
|
||||||
} else {
|
} else {
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
"No available mechanism for setting download mode\n");
|
"No available mechanism for setting download mode\n");
|
||||||
@ -806,6 +803,34 @@ int qcom_scm_get_sec_dump_state(u32 *dump_state)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(qcom_scm_get_sec_dump_state);
|
EXPORT_SYMBOL(qcom_scm_get_sec_dump_state);
|
||||||
|
|
||||||
|
int __qcom_scm_get_llcc_missrate(struct device *dev, phys_addr_t in_buf,
|
||||||
|
size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct qcom_scm_desc desc = {
|
||||||
|
.svc = QCOM_SCM_SVC_MISSRATE,
|
||||||
|
.cmd = QCOM_SCM_GET_LLCC_MISSRATE_STATS_ID,
|
||||||
|
.owner = ARM_SMCCC_OWNER_SIP,
|
||||||
|
.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL),
|
||||||
|
};
|
||||||
|
|
||||||
|
desc.args[0] = in_buf;
|
||||||
|
desc.args[1] = in_buf_size;
|
||||||
|
desc.args[2] = out_buf;
|
||||||
|
desc.args[3] = out_buf_size;
|
||||||
|
ret = qcom_scm_call(dev, &desc, NULL);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qcom_scm_get_llcc_missrate(phys_addr_t in_buf,
|
||||||
|
size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size)
|
||||||
|
{
|
||||||
|
return __qcom_scm_get_llcc_missrate(__scm ? __scm->dev : NULL, in_buf,
|
||||||
|
in_buf_size, out_buf, out_buf_size);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(qcom_scm_get_llcc_missrate);
|
||||||
|
|
||||||
int qcom_scm_assign_dump_table_region(bool is_assign, phys_addr_t addr, size_t size)
|
int qcom_scm_assign_dump_table_region(bool is_assign, phys_addr_t addr, size_t size)
|
||||||
{
|
{
|
||||||
struct qcom_scm_desc desc = {
|
struct qcom_scm_desc desc = {
|
||||||
|
@ -231,6 +231,9 @@ int qcom_scm_handle_wait(struct device *dev, int scm_ret,
|
|||||||
#define QCOM_SCM_LMH_LIMIT_PROFILE_CHANGE 0x01
|
#define QCOM_SCM_LMH_LIMIT_PROFILE_CHANGE 0x01
|
||||||
#define QCOM_SCM_LMH_LIMIT_DCVSH 0x10
|
#define QCOM_SCM_LMH_LIMIT_DCVSH 0x10
|
||||||
|
|
||||||
|
#define QCOM_SCM_GET_LLCC_MISSRATE_STATS_ID 0x14
|
||||||
|
#define QCOM_SCM_SVC_MISSRATE 0x06
|
||||||
|
|
||||||
extern void __qcom_scm_init(void);
|
extern void __qcom_scm_init(void);
|
||||||
|
|
||||||
/* common error codes */
|
/* common error codes */
|
||||||
|
@ -146,11 +146,6 @@ static void log_profiling_info(struct adreno_device *adreno_dev, u32 *rcvd)
|
|||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* protected GPU work must not be reported */
|
|
||||||
if (!(context->flags & KGSL_CONTEXT_SECURE))
|
|
||||||
kgsl_work_period_update(device, context->proc_priv->period,
|
|
||||||
cmd->active);
|
|
||||||
|
|
||||||
info.timestamp = cmd->ts;
|
info.timestamp = cmd->ts;
|
||||||
info.rb_id = adreno_get_level(context);
|
info.rb_id = adreno_get_level(context);
|
||||||
info.gmu_dispatch_queue = context->gmu_dispatch_queue;
|
info.gmu_dispatch_queue = context->gmu_dispatch_queue;
|
||||||
@ -163,6 +158,10 @@ static void log_profiling_info(struct adreno_device *adreno_dev, u32 *rcvd)
|
|||||||
info.active = cmd->active;
|
info.active = cmd->active;
|
||||||
info.retired_on_gmu = cmd->retired_on_gmu;
|
info.retired_on_gmu = cmd->retired_on_gmu;
|
||||||
|
|
||||||
|
/* protected GPU work must not be reported */
|
||||||
|
if (!(context->flags & KGSL_CONTEXT_SECURE))
|
||||||
|
kgsl_work_period_update(device, context->proc_priv->period, info.active);
|
||||||
|
|
||||||
trace_adreno_cmdbatch_retired(context, &info, 0, 0, 0);
|
trace_adreno_cmdbatch_retired(context, &info, 0, 0, 0);
|
||||||
|
|
||||||
log_kgsl_cmdbatch_retired_event(context->id, cmd->ts, context->priority,
|
log_kgsl_cmdbatch_retired_event(context->id, cmd->ts, context->priority,
|
||||||
|
@ -799,8 +799,16 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
|
|||||||
static void gi2c_ev_cb(struct dma_chan *ch, struct msm_gpi_cb const *cb_str,
|
static void gi2c_ev_cb(struct dma_chan *ch, struct msm_gpi_cb const *cb_str,
|
||||||
void *ptr)
|
void *ptr)
|
||||||
{
|
{
|
||||||
struct geni_i2c_dev *gi2c = ptr;
|
struct geni_i2c_dev *gi2c;
|
||||||
u32 m_stat = cb_str->status;
|
u32 m_stat;
|
||||||
|
|
||||||
|
if (!ptr || !cb_str) {
|
||||||
|
pr_err("%s: Invalid ev_cb buffer\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gi2c = (struct geni_i2c_dev *)ptr;
|
||||||
|
m_stat = cb_str->status;
|
||||||
|
|
||||||
switch (cb_str->cb_event) {
|
switch (cb_str->cb_event) {
|
||||||
case MSM_GPI_QUP_ERROR:
|
case MSM_GPI_QUP_ERROR:
|
||||||
|
@ -324,8 +324,8 @@ static struct regmap *qcom_icc_rpmh_map(struct platform_device *pdev,
|
|||||||
|
|
||||||
static bool is_voter_disabled(char *voter)
|
static bool is_voter_disabled(char *voter)
|
||||||
{
|
{
|
||||||
if ((strnstr(voter, "disp", strlen(voter)) &&
|
if ((!strcmp(voter, "disp") && socinfo_get_part_info(PART_DISPLAY)) ||
|
||||||
(socinfo_get_part_info(PART_DISPLAY) || socinfo_get_part_info(PART_DISPLAY1))) ||
|
(!strcmp(voter, "disp2") && socinfo_get_part_info(PART_DISPLAY1)) ||
|
||||||
(strnstr(voter, "cam", strlen(voter)) && socinfo_get_part_info(PART_CAMERA)))
|
(strnstr(voter, "cam", strlen(voter)) && socinfo_get_part_info(PART_CAMERA)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -359,7 +359,12 @@ static int qcom_icc_init_disabled_parts(struct qcom_icc_provider *qp)
|
|||||||
if (!qn)
|
if (!qn)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strnstr(qn->name, voter_name, strlen(qn->name)))
|
/*
|
||||||
|
* Find the ICC node to be disabled by comparing voter_name in
|
||||||
|
* node name string, adjust the start position accordingly
|
||||||
|
*/
|
||||||
|
if (!strcmp(qn->name + (strlen(qn->name) - strlen(voter_name)),
|
||||||
|
voter_name))
|
||||||
qn->disabled = true;
|
qn->disabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8509,7 +8509,9 @@ static int qseecom_release(struct inode *inode, struct file *file)
|
|||||||
static const struct file_operations qseecom_fops = {
|
static const struct file_operations qseecom_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.unlocked_ioctl = qseecom_ioctl,
|
.unlocked_ioctl = qseecom_ioctl,
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
.compat_ioctl = compat_qseecom_ioctl,
|
.compat_ioctl = compat_qseecom_ioctl,
|
||||||
|
#endif
|
||||||
.open = qseecom_open,
|
.open = qseecom_open,
|
||||||
.release = qseecom_release
|
.release = qseecom_release
|
||||||
};
|
};
|
||||||
|
@ -98,7 +98,9 @@ static int param_set_download_mode(const char *val,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
msm_enable_dump_mode(true);
|
msm_enable_dump_mode(enable_dump);
|
||||||
|
if (!enable_dump)
|
||||||
|
qcom_scm_disable_sdi();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1171,6 +1171,7 @@ config QCOM_HUNG_TASK_ENH
|
|||||||
|
|
||||||
config QCOM_SMCINVOKE
|
config QCOM_SMCINVOKE
|
||||||
tristate "Secure QSEE Support"
|
tristate "Secure QSEE Support"
|
||||||
|
depends on QCOM_SCM && QCOM_MEM_BUF
|
||||||
help
|
help
|
||||||
Enable SMCInvoke driver which supports capability based secure
|
Enable SMCInvoke driver which supports capability based secure
|
||||||
communication between QTI Secure Execution Environment (QSEE)
|
communication between QTI Secure Execution Environment (QSEE)
|
||||||
|
@ -76,6 +76,29 @@ config QTI_HW_MEMLAT_SCMI_CLIENT
|
|||||||
driver, and interface driver will use this handle to communicate with
|
driver, and interface driver will use this handle to communicate with
|
||||||
memlat HW.
|
memlat HW.
|
||||||
|
|
||||||
|
config QCOM_LLCC_MISS
|
||||||
|
tristate "Qualcomm Technologies Inc. LLCC_MISS_STATS Driver"
|
||||||
|
depends on ARCH_QCOM && QCOM_BUS_PROF
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This enables the QCOM LLCC miss stats driver which exposes LLCC miss
|
||||||
|
stats to user space clients at modest time intervals for the intention
|
||||||
|
of profiling.
|
||||||
|
|
||||||
|
The purpose of the driver is to enable the monitoring of LLCC misses
|
||||||
|
at regular intervals and providing the miss rate data to the user
|
||||||
|
space clients upon read.
|
||||||
|
|
||||||
|
config QCOM_BUS_PROF
|
||||||
|
tristate "Qualcomm Technologies Inc. BUS_PROF Driver"
|
||||||
|
depends on ARCH_QCOM
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This enables the QCOM bus profiling common framework and ftraces,
|
||||||
|
which provide support for a variety of features. These features
|
||||||
|
include memory latency, LLCC miss, and LLCC occupancy, all of
|
||||||
|
which are supported on certain Qualcomm Technologies, Inc.
|
||||||
|
(QTI) chipsets.
|
||||||
|
|
||||||
config QTI_PMU_SCMI_CLIENT
|
config QTI_PMU_SCMI_CLIENT
|
||||||
tristate "Qualcomm Technologies Inc. SCMI client driver for PMU"
|
tristate "Qualcomm Technologies Inc. SCMI client driver for PMU"
|
||||||
|
@ -7,6 +7,8 @@ qcom-dcvs-y := dcvs.o dcvs_icc.o dcvs_epss.o trace-dcvs.o
|
|||||||
obj-$(CONFIG_QCOM_MEMLAT) += memlat.o
|
obj-$(CONFIG_QCOM_MEMLAT) += memlat.o
|
||||||
obj-$(CONFIG_QCOM_BWMON) += bwmon.o
|
obj-$(CONFIG_QCOM_BWMON) += bwmon.o
|
||||||
obj-$(CONFIG_QCOM_BWPROF) += bwprof.o
|
obj-$(CONFIG_QCOM_BWPROF) += bwprof.o
|
||||||
|
obj-$(CONFIG_QCOM_BUS_PROF) += trace-bus-prof.o
|
||||||
|
obj-$(CONFIG_QCOM_LLCC_MISS) += llcc_miss.o
|
||||||
obj-$(CONFIG_QTI_PMU_SCMI_CLIENT) += pmu_scmi.o
|
obj-$(CONFIG_QTI_PMU_SCMI_CLIENT) += pmu_scmi.o
|
||||||
obj-$(CONFIG_QTI_C1DCVS_SCMI_CLIENT) += c1dcvs_scmi.o
|
obj-$(CONFIG_QTI_C1DCVS_SCMI_CLIENT) += c1dcvs_scmi.o
|
||||||
obj-$(CONFIG_QTI_HW_MEMLAT_SCMI_CLIENT) += memlat_scmi.o
|
obj-$(CONFIG_QTI_HW_MEMLAT_SCMI_CLIENT) += memlat_scmi.o
|
||||||
|
19
drivers/soc/qcom/dcvs/bus_prof.h
Normal file
19
drivers/soc/qcom/dcvs/bus_prof.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#ifndef _QCOM_BUS_PROF_H
|
||||||
|
#define _QCOM_BUS_PROF_H
|
||||||
|
#define MAX_CONCURRENT_MASTERS 2
|
||||||
|
struct llcc_miss_buf {
|
||||||
|
u8 master_id;
|
||||||
|
uint16_t miss_info;
|
||||||
|
u32 rd_miss;
|
||||||
|
u32 wr_miss;
|
||||||
|
u32 all_access;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
#endif /* _QCOM_BUS_PROF_H */
|
497
drivers/soc/qcom/dcvs/llcc_miss.c
Normal file
497
drivers/soc/qcom/dcvs/llcc_miss.c
Normal file
@ -0,0 +1,497 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/hrtimer.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/ktime.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/qcom_scm.h>
|
||||||
|
#include <linux/qtee_shmbridge.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include "bus_prof.h"
|
||||||
|
#include "trace-bus-prof.h"
|
||||||
|
|
||||||
|
#define SAMPLE_MS 10
|
||||||
|
#define DDR_OUT_BUF_MAGIC (0xDD4)
|
||||||
|
|
||||||
|
enum cmd {
|
||||||
|
LLCC_MISS_START_PROFILING = 1,
|
||||||
|
LLCC_MISS_GET_DATA = 2,
|
||||||
|
LLCC_MISS_STOP_PROFILING = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum error {
|
||||||
|
E_SUCCESS = 0, /* Operation successful */
|
||||||
|
E_FAILURE = 1, /* Operation failed due to unknown err*/
|
||||||
|
E_NULL_PARAM = 2,/* Null Parameter */
|
||||||
|
E_INVALID_ARG = 3,/* Arg is not recognized */
|
||||||
|
E_BAD_ADDRESS = 4,/* Ptr arg is bad address */
|
||||||
|
E_INVALID_ARG_LEN = 5,/* Arg length is wrong */
|
||||||
|
E_NOT_SUPPORTED = 6,/* Operation not supported */
|
||||||
|
E_UNINITIALIZED = 7,/* Operation not permitted on platform */
|
||||||
|
E_PARTIAL_DUMP = 8,/* Operation not permitted right now */
|
||||||
|
E_RESERVED = 0x7FFFFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
enum llcc_miss_masters {
|
||||||
|
CPU = 0,
|
||||||
|
GPU,
|
||||||
|
NSP,
|
||||||
|
MAX_MASTER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *master_names[MAX_MASTER] = {"CPU", "GPU", "NSP"};
|
||||||
|
|
||||||
|
struct llcc_miss_start_req {
|
||||||
|
u32 cmd_id;
|
||||||
|
u32 active_masters;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct llcc_miss_resp {
|
||||||
|
u32 cmd_id;
|
||||||
|
enum error status;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct llcc_miss_get_req {
|
||||||
|
u32 cmd_id;
|
||||||
|
u8 *buf_ptr;
|
||||||
|
u32 buf_size;
|
||||||
|
u32 type; /* Stop : 0, Reset : 1 */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct llcc_miss_stop_req {
|
||||||
|
u32 cmd_id;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/* cmd_id is expected to be defined first for each member of the union */
|
||||||
|
union llcc_miss_req {
|
||||||
|
struct llcc_miss_start_req start_req;
|
||||||
|
struct llcc_miss_get_req get_req;
|
||||||
|
struct llcc_miss_stop_req stop_req;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct llcc_cmd_buf {
|
||||||
|
union llcc_miss_req llcc_miss_req;
|
||||||
|
struct llcc_miss_resp llcc_miss_resp;
|
||||||
|
u32 req_size;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct llcc_miss_data {
|
||||||
|
struct llcc_miss_buf master_buf[MAX_CONCURRENT_MASTERS];
|
||||||
|
enum error err;
|
||||||
|
u16 magic;
|
||||||
|
u64 qtime;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct miss_sample {
|
||||||
|
u64 ts;
|
||||||
|
u16 measured_miss_rate;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct llcc_miss_dev_data {
|
||||||
|
struct work_struct work;
|
||||||
|
struct workqueue_struct *wq;
|
||||||
|
struct hrtimer hrtimer;
|
||||||
|
u16 max_samples;
|
||||||
|
u16 size_of_line;
|
||||||
|
u32 active_masters;
|
||||||
|
u32 available_masters;
|
||||||
|
struct llcc_miss_data *data;
|
||||||
|
struct mutex lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct master_data {
|
||||||
|
u16 curr_idx;
|
||||||
|
u16 unread_samples;
|
||||||
|
struct miss_sample *miss_data;
|
||||||
|
char buf[PAGE_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct master_data mdata[MAX_MASTER];
|
||||||
|
static struct dentry *llcc_miss_dir;
|
||||||
|
static struct llcc_miss_dev_data *llcc_miss;
|
||||||
|
|
||||||
|
static ssize_t get_last_samples(struct file *file, char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
int index = 0, ret = 0, m_idx;
|
||||||
|
int i = 0, size = 0, enable;
|
||||||
|
char *master_name;
|
||||||
|
|
||||||
|
mutex_lock(&llcc_miss->lock);
|
||||||
|
if (!llcc_miss->active_masters) {
|
||||||
|
pr_err("No master is enabled for mem miss\n");
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
master_name = file->private_data;
|
||||||
|
for (m_idx = 0; m_idx < MAX_MASTER ; m_idx++) {
|
||||||
|
if (!strcasecmp(master_names[m_idx], master_name))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
enable = (llcc_miss->active_masters & BIT(m_idx));
|
||||||
|
if (!enable) {
|
||||||
|
pr_err("%s memory miss is not enabled\n", master_names[m_idx]);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = (mdata[m_idx].curr_idx - mdata[m_idx].unread_samples +
|
||||||
|
llcc_miss->max_samples) % llcc_miss->max_samples;
|
||||||
|
for (i = 0; i < mdata[m_idx].unread_samples; i++) {
|
||||||
|
size += scnprintf(mdata[m_idx].buf + size, PAGE_SIZE - size,
|
||||||
|
"%llx\t%x\n", mdata[m_idx].miss_data[index].ts,
|
||||||
|
mdata[m_idx].miss_data[index].measured_miss_rate);
|
||||||
|
index = (index + 1) % llcc_miss->max_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
mdata[m_idx].unread_samples = 0;
|
||||||
|
ret = simple_read_from_buffer(user_buf, count, ppos, mdata[m_idx].buf, size);
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&llcc_miss->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_llcc_miss_profiling_command(const void *req)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
u32 qseos_cmd_id = 0;
|
||||||
|
struct llcc_miss_resp *rsp = NULL;
|
||||||
|
size_t req_size = 0, rsp_size = 0;
|
||||||
|
struct qtee_shm shm = {0};
|
||||||
|
|
||||||
|
if (!req)
|
||||||
|
return -EINVAL;
|
||||||
|
rsp = &((struct llcc_cmd_buf *)req)->llcc_miss_resp;
|
||||||
|
rsp_size = sizeof(struct llcc_miss_resp);
|
||||||
|
req_size = ((struct llcc_cmd_buf *)req)->req_size;
|
||||||
|
qseos_cmd_id = *(u32 *)req;
|
||||||
|
ret = qtee_shmbridge_allocate_shm(PAGE_ALIGN(req_size + rsp_size), &shm);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("qtee_shmbridge_allocate_shm failed, ret :%d\n", ret);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(shm.vaddr, req, req_size);
|
||||||
|
qtee_shmbridge_flush_shm_buf(&shm);
|
||||||
|
switch (qseos_cmd_id) {
|
||||||
|
case LLCC_MISS_START_PROFILING:
|
||||||
|
case LLCC_MISS_GET_DATA:
|
||||||
|
case LLCC_MISS_STOP_PROFILING:
|
||||||
|
/* Send the command to TZ */
|
||||||
|
ret = qcom_scm_get_llcc_missrate(shm.paddr, req_size,
|
||||||
|
shm.paddr + req_size, rsp_size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("cmd_id %d is not supported.\n",
|
||||||
|
qseos_cmd_id);
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
qtee_shmbridge_inv_shm_buf(&shm);
|
||||||
|
memcpy(rsp, (char *)shm.vaddr + req_size, rsp_size);
|
||||||
|
qtee_shmbridge_free_shm(&shm);
|
||||||
|
/* Verify cmd id and Check that request succeeded. */
|
||||||
|
if (rsp->status != 0 ||
|
||||||
|
qseos_cmd_id != rsp->cmd_id) {
|
||||||
|
ret = -1;
|
||||||
|
pr_err("Status: %d,Cmd: %d\n",
|
||||||
|
rsp->status,
|
||||||
|
rsp->cmd_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int start_memory_miss_stats(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
struct llcc_cmd_buf *llcc_cmd_buf = NULL;
|
||||||
|
|
||||||
|
llcc_cmd_buf = kzalloc(sizeof(*llcc_cmd_buf), GFP_KERNEL);
|
||||||
|
if (!llcc_cmd_buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
llcc_cmd_buf->llcc_miss_req.start_req.cmd_id = LLCC_MISS_START_PROFILING;
|
||||||
|
llcc_cmd_buf->llcc_miss_req.start_req.active_masters = llcc_miss->active_masters;
|
||||||
|
llcc_cmd_buf->req_size = sizeof(struct llcc_miss_start_req);
|
||||||
|
ret = send_llcc_miss_profiling_command(llcc_cmd_buf);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("Error in %s, ret = %d\n", __func__, ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hrtimer_active(&llcc_miss->hrtimer))
|
||||||
|
hrtimer_start(&llcc_miss->hrtimer,
|
||||||
|
ms_to_ktime(SAMPLE_MS), HRTIMER_MODE_REL_PINNED);
|
||||||
|
out:
|
||||||
|
kfree(llcc_cmd_buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stop_memory_miss_stats(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct llcc_cmd_buf *llcc_cmd_buf = NULL;
|
||||||
|
|
||||||
|
hrtimer_cancel(&llcc_miss->hrtimer);
|
||||||
|
cancel_work_sync(&llcc_miss->work);
|
||||||
|
llcc_cmd_buf = kzalloc(sizeof(*llcc_cmd_buf), GFP_KERNEL);
|
||||||
|
if (!llcc_cmd_buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
llcc_cmd_buf->llcc_miss_req.stop_req.cmd_id = LLCC_MISS_STOP_PROFILING;
|
||||||
|
llcc_cmd_buf->req_size = sizeof(struct llcc_miss_stop_req);
|
||||||
|
ret = send_llcc_miss_profiling_command(llcc_cmd_buf);
|
||||||
|
if (ret)
|
||||||
|
pr_err("Error in %s, ret = %d\n", __func__, ret);
|
||||||
|
|
||||||
|
kfree(llcc_cmd_buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_mon_enabled(void *data, u64 val)
|
||||||
|
{
|
||||||
|
char *master_name = data;
|
||||||
|
int i, ret = 0;
|
||||||
|
u32 count, enable = val ? 1 : 0;
|
||||||
|
|
||||||
|
mutex_lock(&llcc_miss->lock);
|
||||||
|
for (i = 0; i < MAX_MASTER; i++) {
|
||||||
|
if (!strcasecmp(master_names[i], master_name))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (enable == (llcc_miss->active_masters & BIT(i)))
|
||||||
|
goto unlock;
|
||||||
|
count = hweight32(llcc_miss->active_masters);
|
||||||
|
if (count >= MAX_CONCURRENT_MASTERS && enable) {
|
||||||
|
pr_err("Max masters already enabled\n");
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
mutex_unlock(&llcc_miss->lock);
|
||||||
|
if (count)
|
||||||
|
stop_memory_miss_stats();
|
||||||
|
mutex_lock(&llcc_miss->lock);
|
||||||
|
llcc_miss->active_masters = (llcc_miss->active_masters ^ BIT(i));
|
||||||
|
if (llcc_miss->active_masters)
|
||||||
|
start_memory_miss_stats();
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&llcc_miss->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_mon_enabled(void *data, u64 *val)
|
||||||
|
{
|
||||||
|
char *master_name = data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mutex_lock(&llcc_miss->lock);
|
||||||
|
for (i = 0; i < MAX_MASTER; i++) {
|
||||||
|
if (!strcasecmp(master_names[i], master_name))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (llcc_miss->active_masters & BIT(i))
|
||||||
|
*val = 1;
|
||||||
|
else
|
||||||
|
*val = 0;
|
||||||
|
mutex_unlock(&llcc_miss->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_DEBUGFS_ATTRIBUTE(set_mon_enabled_ops, get_mon_enabled, set_mon_enabled, "%llu\n");
|
||||||
|
|
||||||
|
static const struct file_operations show_last_samples_ops = {
|
||||||
|
.read = get_last_samples,
|
||||||
|
.open = simple_open,
|
||||||
|
.llseek = default_llseek,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void llcc_miss_update_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
int ret = 0, i, m;
|
||||||
|
u16 magic;
|
||||||
|
struct llcc_cmd_buf *llcc_cmd_buf;
|
||||||
|
struct qtee_shm buf_shm = {0};
|
||||||
|
const int bufsize = sizeof(struct llcc_miss_data);
|
||||||
|
|
||||||
|
llcc_cmd_buf = kzalloc(sizeof(*llcc_cmd_buf), GFP_KERNEL);
|
||||||
|
if (!llcc_cmd_buf)
|
||||||
|
return;
|
||||||
|
ret = qtee_shmbridge_allocate_shm(PAGE_ALIGN(bufsize), &buf_shm);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("shmbridge alloc buf failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
llcc_cmd_buf->llcc_miss_req.get_req.cmd_id = LLCC_MISS_GET_DATA;
|
||||||
|
llcc_cmd_buf->llcc_miss_req.get_req.buf_ptr = (u8 *)buf_shm.paddr;
|
||||||
|
llcc_cmd_buf->llcc_miss_req.get_req.buf_size = bufsize;
|
||||||
|
llcc_cmd_buf->llcc_miss_req.get_req.type = 1;
|
||||||
|
llcc_cmd_buf->req_size = sizeof(struct llcc_miss_get_req);
|
||||||
|
qtee_shmbridge_flush_shm_buf(&buf_shm);
|
||||||
|
ret = send_llcc_miss_profiling_command(llcc_cmd_buf);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("send_llcc_miss_profiling_command failed\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
qtee_shmbridge_inv_shm_buf(&buf_shm);
|
||||||
|
memcpy(llcc_miss->data, (char *)buf_shm.vaddr, sizeof(*llcc_miss->data));
|
||||||
|
magic = llcc_miss->data->magic;
|
||||||
|
if (magic != DDR_OUT_BUF_MAGIC) {
|
||||||
|
pr_err("Expected magic value is %x but got %x\n", DDR_OUT_BUF_MAGIC, magic);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&llcc_miss->lock);
|
||||||
|
for (i = 0; i < MAX_CONCURRENT_MASTERS; i++) {
|
||||||
|
m = llcc_miss->data->master_buf[i].master_id;
|
||||||
|
if (m >= MAX_MASTER)
|
||||||
|
continue;
|
||||||
|
mdata[m].miss_data[mdata[m].curr_idx].ts = llcc_miss->data->qtime;
|
||||||
|
mdata[m].miss_data[mdata[m].curr_idx].measured_miss_rate =
|
||||||
|
llcc_miss->data->master_buf[i].miss_info;
|
||||||
|
mdata[m].unread_samples = min(++mdata[m].unread_samples, llcc_miss->max_samples);
|
||||||
|
mdata[m].curr_idx = (mdata[m].curr_idx + 1) % llcc_miss->max_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_memory_miss_last_sample(llcc_miss->data->qtime,
|
||||||
|
&llcc_miss->data->master_buf[0],
|
||||||
|
&llcc_miss->data->master_buf[1]);
|
||||||
|
|
||||||
|
mutex_unlock(&llcc_miss->lock);
|
||||||
|
err:
|
||||||
|
qtee_shmbridge_free_shm(&buf_shm);
|
||||||
|
kfree(llcc_cmd_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum hrtimer_restart hrtimer_handler(struct hrtimer *timer)
|
||||||
|
{
|
||||||
|
ktime_t now = ktime_get();
|
||||||
|
|
||||||
|
queue_work(llcc_miss->wq, &llcc_miss->work);
|
||||||
|
hrtimer_forward(timer, now, ms_to_ktime(SAMPLE_MS));
|
||||||
|
|
||||||
|
return HRTIMER_RESTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int llcc_miss_create_fs_entries(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct dentry *ret, *master_dir;
|
||||||
|
|
||||||
|
llcc_miss_dir = debugfs_create_dir("llcc_miss", 0);
|
||||||
|
if (IS_ERR(llcc_miss_dir)) {
|
||||||
|
pr_err("Debugfs directory creation failed for llcc_miss\n");
|
||||||
|
return PTR_ERR(llcc_miss_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_MASTER; i++) {
|
||||||
|
master_dir = debugfs_create_dir(master_names[i], llcc_miss_dir);
|
||||||
|
if (IS_ERR(master_dir)) {
|
||||||
|
pr_err("Debugfs directory creation failed for %s\n", master_names[i]);
|
||||||
|
goto error_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = debugfs_create_file("show_last_samples", 0400, master_dir,
|
||||||
|
master_names[i], &show_last_samples_ops);
|
||||||
|
if (IS_ERR(ret)) {
|
||||||
|
pr_err("Debugfs file creation failed for show_last_samples\n");
|
||||||
|
goto error_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = debugfs_create_file("enable", 0644, master_dir,
|
||||||
|
master_names[i], &set_mon_enabled_ops);
|
||||||
|
if (IS_ERR(ret)) {
|
||||||
|
pr_err("Debugfs file creation failed for enable\n");
|
||||||
|
goto error_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error_cleanup:
|
||||||
|
for (; i >= 0; i--)
|
||||||
|
debugfs_remove_recursive(debugfs_lookup(master_names[i], llcc_miss_dir));
|
||||||
|
debugfs_remove_recursive(llcc_miss_dir);
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init qcom_llcc_miss_init(void)
|
||||||
|
{
|
||||||
|
int ret, i, j;
|
||||||
|
|
||||||
|
llcc_miss = kzalloc(sizeof(*llcc_miss), GFP_KERNEL);
|
||||||
|
if (!llcc_miss)
|
||||||
|
return -ENOMEM;
|
||||||
|
llcc_miss->data = kzalloc(sizeof(*llcc_miss->data), GFP_KERNEL);
|
||||||
|
if (!llcc_miss->data) {
|
||||||
|
kfree(llcc_miss);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
for (i = 0; i < MAX_MASTER; i++)
|
||||||
|
llcc_miss->available_masters |= BIT(i);
|
||||||
|
ret = llcc_miss_create_fs_entries();
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* to get no of hex char in a line multiplying size of struct miss_sample by 2
|
||||||
|
* and adding 1 for tab and 1 for newline.
|
||||||
|
* output format is qtime followed by miss data in hexa,example -> 32c7bd2 a
|
||||||
|
*/
|
||||||
|
llcc_miss->size_of_line = sizeof(struct miss_sample) * 2 + 2;
|
||||||
|
llcc_miss->max_samples = PAGE_SIZE / llcc_miss->size_of_line;
|
||||||
|
for (i = 0; i < MAX_MASTER; i++) {
|
||||||
|
mdata[i].miss_data = kcalloc(llcc_miss->max_samples,
|
||||||
|
sizeof(struct miss_sample), GFP_KERNEL);
|
||||||
|
if (!mdata[i].miss_data) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto debugfs_file_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_init(&llcc_miss->lock);
|
||||||
|
hrtimer_init(&llcc_miss->hrtimer, CLOCK_MONOTONIC,
|
||||||
|
HRTIMER_MODE_REL);
|
||||||
|
llcc_miss->hrtimer.function = hrtimer_handler;
|
||||||
|
llcc_miss->wq = create_freezable_workqueue("llcc_miss_wq");
|
||||||
|
if (!llcc_miss->wq) {
|
||||||
|
pr_err("Couldn't create llcc_miss workqueue.\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto debugfs_file_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT_WORK(&llcc_miss->work, &llcc_miss_update_work);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
debugfs_file_err:
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
kfree(mdata[j].miss_data);
|
||||||
|
debugfs_remove_recursive(llcc_miss_dir);
|
||||||
|
err:
|
||||||
|
kfree(llcc_miss->data);
|
||||||
|
kfree(llcc_miss);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(qcom_llcc_miss_init);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("QCOM LLCC_MISS driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
11
drivers/soc/qcom/dcvs/trace-bus-prof.c
Normal file
11
drivers/soc/qcom/dcvs/trace-bus-prof.c
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CREATE_TRACE_POINTS
|
||||||
|
#include "trace-bus-prof.h"
|
||||||
|
|
||||||
|
|
||||||
|
EXPORT_TRACEPOINT_SYMBOL(memory_miss_last_sample);
|
||||||
|
MODULE_LICENSE("GPL");
|
51
drivers/soc/qcom/dcvs/trace-bus-prof.h
Normal file
51
drivers/soc/qcom/dcvs/trace-bus-prof.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef TRACE_SYSTEM
|
||||||
|
#define TRACE_SYSTEM bus_prof
|
||||||
|
|
||||||
|
#if !defined(_TRACE_BUS_PROF_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||||
|
#define _TRACE_BUS_PROF_H
|
||||||
|
#include "bus_prof.h"
|
||||||
|
#include <linux/tracepoint.h>
|
||||||
|
|
||||||
|
TRACE_EVENT(memory_miss_last_sample,
|
||||||
|
|
||||||
|
TP_PROTO(u64 qtime, struct llcc_miss_buf *master_buf0, struct llcc_miss_buf *master_buf1),
|
||||||
|
|
||||||
|
TP_ARGS(qtime, master_buf0, master_buf1),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__field(u64, qtime)
|
||||||
|
__field(u8, master1)
|
||||||
|
__field(u16, miss1)
|
||||||
|
__field(u8, master2)
|
||||||
|
__field(u16, miss2)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__entry->qtime = qtime;
|
||||||
|
__entry->master1 = master_buf0->master_id;
|
||||||
|
__entry->miss1 = master_buf0->miss_info;
|
||||||
|
__entry->master2 = master_buf1->master_id;
|
||||||
|
__entry->miss2 = master_buf1->miss_info;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("qtime=%llu master1=%u miss1=%u master2=%u miss2=%u",
|
||||||
|
__entry->qtime,
|
||||||
|
__entry->master1,
|
||||||
|
__entry->miss1,
|
||||||
|
__entry->master2,
|
||||||
|
__entry->miss2)
|
||||||
|
);
|
||||||
|
#endif /* _TRACE_BUS_PROF_H */
|
||||||
|
|
||||||
|
#undef TRACE_INCLUDE_PATH
|
||||||
|
#define TRACE_INCLUDE_PATH ../../drivers/soc/qcom/dcvs
|
||||||
|
|
||||||
|
#undef TRACE_INCLUDE_FILE
|
||||||
|
#define TRACE_INCLUDE_FILE trace-bus-prof
|
||||||
|
|
||||||
|
#include <trace/define_trace.h>
|
@ -2851,6 +2851,9 @@ static int smcinvoke_probe(struct platform_device *pdev)
|
|||||||
unsigned int count = 1;
|
unsigned int count = 1;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!qcom_scm_is_available())
|
||||||
|
return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "qcom_scm is not up!\n");
|
||||||
|
|
||||||
rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
|
rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
pr_err("dma_set_mask_and_coherent failed %d\n", rc);
|
pr_err("dma_set_mask_and_coherent failed %d\n", rc);
|
||||||
|
@ -119,6 +119,8 @@ extern int qcom_scm_pas_shutdown_retry(u32 peripheral);
|
|||||||
extern bool qcom_scm_pas_supported(u32 peripheral);
|
extern bool qcom_scm_pas_supported(u32 peripheral);
|
||||||
|
|
||||||
extern int qcom_scm_get_sec_dump_state(u32 *dump_state);
|
extern int qcom_scm_get_sec_dump_state(u32 *dump_state);
|
||||||
|
extern int qcom_scm_get_llcc_missrate(phys_addr_t in_buf, size_t in_buf_size,
|
||||||
|
phys_addr_t out_buf, size_t out_buf_size);
|
||||||
extern int qcom_scm_assign_dump_table_region(bool is_assign, phys_addr_t addr, size_t size);
|
extern int qcom_scm_assign_dump_table_region(bool is_assign, phys_addr_t addr, size_t size);
|
||||||
|
|
||||||
extern int qcom_scm_tz_blsp_modify_owner(int food, u64 subsystem, int *out);
|
extern int qcom_scm_tz_blsp_modify_owner(int food, u64 subsystem, int *out);
|
||||||
|
@ -54,6 +54,8 @@ msm_geni_serial.ko
|
|||||||
msm_rtb.ko
|
msm_rtb.ko
|
||||||
mem_buf.ko
|
mem_buf.ko
|
||||||
mem_buf_dev.ko
|
mem_buf_dev.ko
|
||||||
|
qseecom-mod.ko
|
||||||
|
smcinvoke_mod.ko
|
||||||
pinctrl-neo.ko
|
pinctrl-neo.ko
|
||||||
pinctrl-msm.ko
|
pinctrl-msm.ko
|
||||||
phy-generic.ko
|
phy-generic.ko
|
||||||
|
@ -59,6 +59,7 @@ nvmem_qcom-spmi-sdam.ko
|
|||||||
pinctrl-spmi-gpio.ko
|
pinctrl-spmi-gpio.ko
|
||||||
qcom-spmi-temp-alarm.ko
|
qcom-spmi-temp-alarm.ko
|
||||||
clk-spmi-pmic-div.ko
|
clk-spmi-pmic-div.ko
|
||||||
|
qcom_pm8008-regulator.ko
|
||||||
sdhci-msm.ko
|
sdhci-msm.ko
|
||||||
core_hang_detect.ko
|
core_hang_detect.ko
|
||||||
kryo_arm64_edac.ko
|
kryo_arm64_edac.ko
|
||||||
|
Loading…
Reference in New Issue
Block a user