soc: qcom: add kryo_e76 debugfs node
To disable and enable Kryo hardware errata 76 workaround at runtime, expose a debugfs interface. Wrote codes using e74/e76 API and data as a starting point. /sys/kernel/debug/scm_errata/kryo_e76 This allows Kryo errata 76 workaround to be toggled off or on (on affected devices) by echoing 0 or 1 to the file. Change-Id: I3d682021aa98eef5421ac2e7578da02f2ea98081 Signed-off-by: Se Wang (Patrick) Oh <sewango@codeaurora.org>
This commit is contained in:
parent
32b29d83ff
commit
051df5bd9b
1 changed files with 51 additions and 3 deletions
|
@ -17,12 +17,15 @@
|
|||
#include <linux/cpu.h>
|
||||
#include <soc/qcom/scm.h>
|
||||
|
||||
#define KRYO_ERRATA_74_75_ID 0x12
|
||||
#define SCM_KRYO_ERRATA_ID 0x12
|
||||
#define ERRATA_WA_DISABLE 0
|
||||
#define ERRATA_WA_ENABLE 1
|
||||
#define ERRATA_74_75_ID_BIT 0x000
|
||||
#define ERRATA_76_ID_BIT 0x100
|
||||
|
||||
static struct dentry *debugfs_base;
|
||||
static bool kryo_e74_e75_wa = true;
|
||||
static bool kryo_e76_wa;
|
||||
|
||||
static void kryo_e74_e75_scm(void *enable)
|
||||
{
|
||||
|
@ -34,8 +37,9 @@ static void kryo_e74_e75_scm(void *enable)
|
|||
|
||||
desc.arginfo = SCM_ARGS(1);
|
||||
desc.args[0] = enable ? ERRATA_WA_ENABLE : ERRATA_WA_DISABLE;
|
||||
desc.args[0] |= ERRATA_74_75_ID_BIT;
|
||||
|
||||
ret = scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_BOOT, KRYO_ERRATA_74_75_ID),
|
||||
ret = scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_BOOT, SCM_KRYO_ERRATA_ID),
|
||||
&desc);
|
||||
if (ret)
|
||||
pr_err("Failed to %s ERRATA_74_75 workaround\n",
|
||||
|
@ -62,8 +66,49 @@ static int kryo_e74_e75_get(void *data, u64 *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void kryo_e76_scm(void *enable)
|
||||
{
|
||||
int ret;
|
||||
struct scm_desc desc = {0};
|
||||
|
||||
if (!is_scm_armv8())
|
||||
return;
|
||||
|
||||
desc.arginfo = SCM_ARGS(1);
|
||||
desc.args[0] = enable ? ERRATA_WA_ENABLE : ERRATA_WA_DISABLE;
|
||||
desc.args[0] |= ERRATA_76_ID_BIT;
|
||||
|
||||
ret = scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_BOOT, SCM_KRYO_ERRATA_ID),
|
||||
&desc);
|
||||
if (ret)
|
||||
pr_err("Failed to %s ERRATA_76 workaround\n",
|
||||
enable ? "enable" : "disable");
|
||||
}
|
||||
|
||||
static int kryo_e76_set(void *data, u64 val)
|
||||
{
|
||||
if ((val && kryo_e76_wa) || (!val && !kryo_e76_wa))
|
||||
return 0;
|
||||
|
||||
kryo_e76_wa = !!val;
|
||||
|
||||
get_cpu();
|
||||
on_each_cpu(kryo_e76_scm, (void *)kryo_e76_wa, 1);
|
||||
put_cpu();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kryo_e76_get(void *data, u64 *val)
|
||||
{
|
||||
*val = kryo_e76_wa;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(kryo_e74_e75_fops, kryo_e74_e75_get,
|
||||
kryo_e74_e75_set, "%llu\n");
|
||||
DEFINE_SIMPLE_ATTRIBUTE(kryo_e76_fops, kryo_e76_get,
|
||||
kryo_e76_set, "%llu\n");
|
||||
|
||||
static int scm_errata_notifier_callback(struct notifier_block *nfb,
|
||||
unsigned long action, void *hcpu)
|
||||
|
@ -71,6 +116,7 @@ static int scm_errata_notifier_callback(struct notifier_block *nfb,
|
|||
switch (action & ~CPU_TASKS_FROZEN) {
|
||||
case CPU_STARTING:
|
||||
kryo_e74_e75_scm((void *)kryo_e74_e75_wa);
|
||||
kryo_e76_scm((void *)kryo_e76_wa);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -91,7 +137,9 @@ static int __init scm_errata_init(void)
|
|||
if (!debugfs_create_file("kryo_e74_e75", S_IRUGO | S_IWUSR,
|
||||
debugfs_base, NULL, &kryo_e74_e75_fops))
|
||||
goto err;
|
||||
|
||||
if (!debugfs_create_file("kryo_e76", S_IRUGO | S_IWUSR,
|
||||
debugfs_base, NULL, &kryo_e76_fops))
|
||||
goto err;
|
||||
ret = register_hotcpu_notifier(&scm_errata_notifier);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
|
Loading…
Add table
Reference in a new issue