soc: rockchip: opp_select: dump current opp state when panic for cpu/ddr

panic log:
cpu cpu6: cur_freq: 1008000000 Hz, volt_vdd: 675000 uV, volt_mem: 675000 uV
cpu cpu4: cur_freq: 408000000 Hz, volt_vdd: 675000 uV, volt_mem: 675000 uV
cpu cpu0: cur_freq: 816000000 Hz, volt_vdd: 675000 uV, volt_mem: 675000 uV
rockchip-dmc dmc: cur_freq: 528000000 Hz, volt_vdd: 675000 uV, volt_mem: 700000 uV

Change-Id: I29ea94cc9deaba0e1d285390312256567708d6ef
Signed-off-by: Liang Chen <cl@rock-chips.com>
This commit is contained in:
Liang Chen
2022-10-08 20:13:59 +08:00
committed by Tao Huang
parent fda1cfae99
commit bc2d913a39
4 changed files with 87 additions and 0 deletions

View File

@@ -899,6 +899,22 @@ static struct notifier_block rockchip_cpufreq_transition_notifier_block = {
.notifier_call = rockchip_cpufreq_transition_notifier,
};
static int rockchip_cpufreq_panic_notifier(struct notifier_block *nb,
unsigned long v, void *p)
{
struct cluster_info *ci;
list_for_each_entry(ci, &cluster_info_list, list_head) {
rockchip_opp_dump_cur_state(ci->opp_info.dev);
}
return 0;
}
static struct notifier_block rockchip_cpufreq_panic_notifier_block = {
.notifier_call = rockchip_cpufreq_panic_notifier,
};
static int __init rockchip_cpufreq_driver_init(void)
{
struct cluster_info *cluster, *pos;
@@ -948,6 +964,11 @@ static int __init rockchip_cpufreq_driver_init(void)
#endif
}
ret = atomic_notifier_chain_register(&panic_notifier_list,
&rockchip_cpufreq_panic_notifier_block);
if (ret)
pr_err("failed to register cpufreq panic notifier\n");
return PTR_ERR_OR_ZERO(platform_device_register_data(NULL, "cpufreq-dt",
-1, (void *)&pdata,
sizeof(struct cpufreq_dt_platform_data)));

View File

@@ -118,6 +118,7 @@ struct rockchip_dmcfreq {
struct regulator *vdd_center;
struct regulator *mem_reg;
struct notifier_block status_nb;
struct notifier_block panic_nb;
struct list_head video_info_list;
struct freq_map_table *cpu_bw_tbl;
struct work_struct boost_work;
@@ -2576,6 +2577,17 @@ next:
return NOTIFY_OK;
}
static int rockchip_dmcfreq_panic_notifier(struct notifier_block *nb,
unsigned long v, void *p)
{
struct rockchip_dmcfreq *dmcfreq =
container_of(nb, struct rockchip_dmcfreq, panic_nb);
rockchip_opp_dump_cur_state(dmcfreq->dev);
return 0;
}
static ssize_t rockchip_dmcfreq_status_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -3129,6 +3141,12 @@ static void rockchip_dmcfreq_register_notifier(struct rockchip_dmcfreq *dmcfreq)
if (ret)
dev_err(dmcfreq->dev, "failed to register system_status nb\n");
dmcfreq->panic_nb.notifier_call = rockchip_dmcfreq_panic_notifier;
ret = atomic_notifier_chain_register(&panic_notifier_list,
&dmcfreq->panic_nb);
if (ret)
dev_err(dmcfreq->dev, "failed to register panic nb\n");
dmc_mdevp.data = dmcfreq->info.devfreq;
dmcfreq->mdev_info = rockchip_system_monitor_register(dmcfreq->dev,
&dmc_mdevp);

View File

@@ -1728,6 +1728,48 @@ out:
}
EXPORT_SYMBOL(rockchip_init_opp_table);
int rockchip_opp_dump_cur_state(struct device *dev)
{
struct clk *clk;
struct opp_table *opp_table;
int volt_vdd, volt_mem;
if (!dev)
return -ENODEV;
opp_table = dev_pm_opp_get_opp_table(dev);
if (IS_ERR(opp_table)) {
dev_err(dev, "%s: device opp doesn't exist\n", __func__);
return PTR_ERR(opp_table);
}
clk = opp_table->clk;
if (IS_ERR(clk)) {
dev_err(dev, "%s: No clock available for the device\n",
__func__);
dev_pm_opp_put_opp_table(opp_table);
return PTR_ERR(clk);
}
if (opp_table->regulator_count == 1) {
volt_vdd = regulator_get_voltage(opp_table->regulators[0]);
dev_info(dev, "cur_freq: %lu Hz, volt: %d uV\n",
clk_get_rate(clk), volt_vdd);
}
if (opp_table->regulator_count == 2) {
volt_vdd = regulator_get_voltage(opp_table->regulators[0]);
volt_mem = regulator_get_voltage(opp_table->regulators[1]);
dev_info(dev, "cur_freq: %lu Hz, volt_vdd: %d uV, volt_mem: %d uV\n",
clk_get_rate(clk), volt_vdd, volt_mem);
}
dev_pm_opp_put_opp_table(opp_table);
return 0;
}
EXPORT_SYMBOL(rockchip_opp_dump_cur_state);
MODULE_DESCRIPTION("ROCKCHIP OPP Select");
MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>, Liang Chen <cl@rock-chips.com>");
MODULE_LICENSE("GPL");

View File

@@ -107,6 +107,7 @@ int rockchip_set_intermediate_rate(struct device *dev,
int rockchip_init_opp_table(struct device *dev,
struct rockchip_opp_info *info,
char *lkg_name, char *reg_name);
int rockchip_opp_dump_cur_state(struct device *dev);
#else
static inline int rockchip_of_get_leakage(struct device *dev, char *lkg_name,
int *leakage)
@@ -226,6 +227,11 @@ static inline int rockchip_init_opp_table(struct device *dev,
return -EOPNOTSUPP;
}
static inline int rockchip_opp_dump_cur_state(struct device *dev)
{
return -EOPNOTSUPP;
}
#endif /* CONFIG_ROCKCHIP_OPP */
#endif