Skip to content

Commit 19f416d

Browse files
Kwibooginkage
authored andcommitted
RFC: drm/panthor: Do not set clk rate when device is suspended
On Rockchip RK3588 trying to change the SCMI_CLK_GPU rate when the GPU device is PM runtime suspended may cause a kernel panic: $ echo 1000000000 > /sys/class/devfreq/fb000000.gpu/min_freq SError Interrupt on CPU4, code 0x00000000be000411 -- SError CPU: 4 UID: 0 PID: 241 Comm: sh Not tainted 6.15.0-rc3 #1 VOLUNTARY Hardware name: Radxa ROCK 5B (DT) pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : smc_send_message+0x140/0x148 lr : smc_send_message+0xd8/0x148 sp : ffff8000827138c0 x29: ffff8000827138c0 x28: ffff000008764000 x27: 0000000000000000 x26: 0000000000000000 x25: 00000000ffffffff x24: ffff800082713b28 x23: ffff00000696b010 x22: ffff000003db4da0 x21: ffff000003fdae80 x20: ffff0000053f22c0 x19: ffff000003db4d80 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 00000000245df550 x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 x11: 0000000000000040 x10: ffff000003fde138 x9 : ffff000003fde130 x8 : ffff000005e5c948 x7 : 0000000000000000 x6 : 0000000000000000 x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000 Kernel panic - not syncing: Asynchronous SError Interrupt CPU: 4 UID: 0 PID: 241 Comm: sh Not tainted 6.15.0-rc3 #1 VOLUNTARY Hardware name: Radxa ROCK 5B (DT) Call trace: show_stack+0x28/0x78 (C) dump_stack_lvl+0x58/0x74 dump_stack+0x14/0x1c panic+0x14c/0x328 add_taint+0x0/0xc0 arm64_serror_panic+0x60/0x6c do_serror+0x24/0x60 el1h_64_error_handler+0x2c/0x40 el1h_64_error+0x6c/0x70 smc_send_message+0x140/0x148 (P) do_xfer+0xb0/0x1f8 scmi_clock_rate_set+0xc0/0x220 scmi_clk_set_rate+0x24/0x38 clk_change_rate+0x164/0x288 clk_core_set_rate_nolock+0x1dc/0x314 clk_set_rate+0x34/0x144 _opp_config_clk_single+0x2c/0x90 _set_opp+0x104/0x564 dev_pm_opp_set_rate+0x110/0x260 panthor_devfreq_target+0x38/0x60 [panthor] devfreq_set_target+0x84/0x180 devfreq_update_target+0xb4/0xcc update_devfreq+0x10/0x18 set_freq_store+0x6c/0xb4 dev_attr_store+0x14/0x24 sysfs_kf_write+0x54/0x60 kernfs_fop_write_iter+0x118/0x1e0 vfs_write+0x224/0x390 ksys_write+0x68/0x100 __arm64_sys_write+0x18/0x20 invoke_syscall+0x44/0x100 el0_svc_common.constprop.0+0x3c/0xe0 do_el0_svc+0x18/0x20 el0_svc+0x2c/0xc0 el0t_64_sync_handler+0x104/0x130 el0t_64_sync+0x170/0x174 SMP: stopping secondary CPUs Kernel Offset: disabled CPU features: 0x0e00,000000e0,01202650,8201700b Memory Limit: 3838 MB ---[ end Kernel panic - not syncing: Asynchronous SError Interrupt ]--- This typically happen when CLK_GPU is disabled or when PD_GPU is down. Add a config_clks ops that will not set core clk rate when the device is PM runtime suspended. Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
1 parent 0e1ca87 commit 19f416d

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

drivers/gpu/drm/panthor/panthor_devfreq.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,42 @@ static struct devfreq_dev_profile panthor_devfreq_profile = {
122122
.get_dev_status = panthor_devfreq_get_dev_status,
123123
};
124124

125+
static int panthor_devfreq_config_clks(struct device *dev,
126+
struct opp_table *opp_table,
127+
struct dev_pm_opp *opp,
128+
void *data, bool scaling_down)
129+
{
130+
struct panthor_device *ptdev = dev_get_drvdata(dev);
131+
unsigned long *target = data;
132+
unsigned long freq;
133+
int ret = 0;
134+
135+
if (!pm_runtime_enabled(dev))
136+
return 0;
137+
138+
/* One of target and opp must be available */
139+
if (target) {
140+
freq = *target;
141+
} else if (opp) {
142+
freq = dev_pm_opp_get_freq(opp);
143+
} else {
144+
WARN_ON(1);
145+
return -EINVAL;
146+
}
147+
148+
pm_runtime_get_noresume(dev);
149+
150+
if (!pm_runtime_suspended(dev)) {
151+
ret = clk_set_rate(ptdev->clks.core, freq);
152+
if (ret)
153+
dev_err(dev, "failed to set clock rate: %lu\n", freq);
154+
}
155+
156+
pm_runtime_put_noidle(dev);
157+
158+
return ret;
159+
}
160+
125161
int panthor_devfreq_init(struct panthor_device *ptdev)
126162
{
127163
/* There's actually 2 regulators (mali and sram), but the OPP core only
@@ -131,6 +167,11 @@ int panthor_devfreq_init(struct panthor_device *ptdev)
131167
* the coupling logic deal with voltage updates.
132168
*/
133169
static const char * const reg_names[] = { "mali", NULL };
170+
static const char * const clk_names[] = { "core", NULL };
171+
struct dev_pm_opp_config config = {
172+
.clk_names = clk_names,
173+
.config_clks = panthor_devfreq_config_clks,
174+
};
134175
struct thermal_cooling_device *cooling;
135176
struct device *dev = ptdev->base.dev;
136177
struct panthor_devfreq *pdevfreq;
@@ -153,6 +194,10 @@ int panthor_devfreq_init(struct panthor_device *ptdev)
153194
return ret;
154195
}
155196

197+
ret = devm_pm_opp_set_config(dev, &config);
198+
if (ret)
199+
return ret;
200+
156201
ret = devm_pm_opp_of_add_table(dev);
157202
if (ret)
158203
return ret;

0 commit comments

Comments
 (0)