MALI: bifrost: enable regulator when suspend

When system resume, all power domains will power on in
dpm_noirq_resume_devices(), if vdd gpu is disabled before system
suspend, the pd gpu will failed to power on when system resume,
the detail as follows:

rockchip-pm-domain fd8d8000.power-management:power-controller: failed to get ack on domain 'gpu', target_idle = 0, target_ack = 0, val=0x8080f
Kernel panic - not syncing: panic_on_set_idle set ...
CPU: 0 PID: 1947 Comm: Binder:352_2 Not tainted 5.10.66 #960
Hardware name: Rockchip RK3588 EVB1 LP4 V10 Board (DT)
Call trace:
 dump_backtrace+0x0/0x1c8
 show_stack+0x1c/0x2c
 dump_stack_lvl+0xdc/0x12c
 dump_stack+0x1c/0x64
 panic+0x150/0x3a4
 rockchip_pmu_set_idle_request+0x1f8/0x1fc
 rockchip_pd_power+0x11c/0x1e0
 rockchip_pd_power_on+0x28/0x38
 genpd_sync_power_on+0xf4/0x134
 genpd_resume_noirq+0x70/0xd0
 device_resume_noirq+0x1a8/0x410
 dpm_noirq_resume_devices+0x100/0x55c
 dpm_resume_noirq+0x18/0x34
 suspend_enter+0x33c/0x52c
 suspend_devices_and_enter+0xec/0x338
 enter_state+0x12c/0x3f8
 pm_suspend+0x60/0xcc
 state_store+0x108/0x148
 kobj_attr_store+0x1c/0x34
 sysfs_kf_write+0x40/0x58
 kernfs_fop_write_iter+0xf0/0x194
 vfs_write+0x328/0x390
 ksys_write+0x78/0xe8
 __arm64_sys_write+0x20/0x30
 el0_svc_common+0xc0/0x23c
 do_el0_svc+0x28/0x88
 el0_svc+0x14/0x24
 el0_sync_handler+0x88/0xec
 el0_sync+0x1a8/0x1c0
SMP: stopping secondary CPUs

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Change-Id: I89f80d37ab2cc61c715bce3f8a25c26552918922
This commit is contained in:
Finley Xiao
2022-04-10 23:31:53 +08:00
committed by Tao Huang
parent d1ae8597d2
commit fe111758d6
5 changed files with 41 additions and 6 deletions

View File

@@ -25,7 +25,6 @@
int kbase_devfreq_init(struct kbase_device *kbdev);
void kbase_devfreq_term(struct kbase_device *kbdev);
int kbase_platform_rk_init_opp_table(struct kbase_device *kbdev);
int kbase_devfreq_opp_helper(struct dev_pm_set_opp_data *data);
/**

View File

@@ -5391,10 +5391,17 @@ static int kbase_device_suspend(struct device *dev)
flush_workqueue(kbdev->devfreq_queue.workq);
}
#endif
#ifdef CONFIG_ARCH_ROCKCHIP
kbase_platform_rk_enable_regulator(kbdev);
#endif
#ifdef KBASE_PM_RUNTIME
if (kbdev->is_runtime_resumed) {
if (kbdev->pm.backend.callback_power_runtime_off)
kbdev->pm.backend.callback_power_runtime_off(kbdev);
}
#endif /* KBASE_PM_RUNTIME */
return 0;
}
@@ -5415,10 +5422,12 @@ static int kbase_device_resume(struct device *dev)
if (!kbdev)
return -ENODEV;
#ifdef KBASE_PM_RUNTIME
if (kbdev->is_runtime_resumed) {
if (kbdev->pm.backend.callback_power_runtime_on)
kbdev->pm.backend.callback_power_runtime_on(kbdev);
}
#endif /* KBASE_PM_RUNTIME */
kbase_pm_resume(kbdev);

View File

@@ -88,3 +88,6 @@ extern struct kbase_platform_funcs_conf platform_funcs;
#define CLK_RATE_TRACE_OPS (&clk_rate_trace_ops)
extern struct kbase_clk_rate_trace_op_conf clk_rate_trace_ops;
int kbase_platform_rk_init_opp_table(struct kbase_device *kbdev);
int kbase_platform_rk_enable_regulator(struct kbase_device *kbdev);

View File

@@ -34,6 +34,7 @@
#include <soc/rockchip/rockchip_opp_select.h>
#include <soc/rockchip/rockchip_system_monitor.h>
#include "mali_kbase_config_platform.h"
#include "mali_kbase_rk.h"
#define POWER_DOWN_FREQ 200000000
@@ -105,6 +106,7 @@ static void rk_pm_power_off_delay_work(struct work_struct *work)
rk_pm_disable_clk(kbdev);
rk_pm_disable_regulator(kbdev);
platform->is_regulator_on = false;
platform->is_powered = false;
wake_unlock(&platform->wake_lock);
@@ -243,11 +245,14 @@ static int rk_pm_callback_power_on(struct kbase_device *kbdev)
}
/* we must enable vdd_gpu before pd_gpu_in_chip. */
err = rk_pm_enable_regulator(kbdev);
if (err) {
E("fail to enable regulator, err : %d.", err);
ret = err;
goto out;
if (!platform->is_regulator_on) {
err = rk_pm_enable_regulator(kbdev);
if (err) {
E("fail to enable regulator, err : %d.", err);
ret = err;
goto out;
}
platform->is_regulator_on = true;
}
err = rk_pm_enable_clk(kbdev);
@@ -554,6 +559,23 @@ int kbase_platform_rk_init_opp_table(struct kbase_device *kbdev)
"gpu_leakage", "mali");
}
int kbase_platform_rk_enable_regulator(struct kbase_device *kbdev)
{
struct rk_context *platform = get_rk_context(kbdev);
int err = 0;
if (!platform->is_regulator_on) {
err = rk_pm_enable_regulator(kbdev);
if (err) {
E("fail to enable regulator, err : %d.", err);
return err;
}
platform->is_regulator_on = true;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static void *enumerate_gpu_clk(struct kbase_device *kbdev,

View File

@@ -33,6 +33,8 @@ struct rk_context {
*/
bool is_powered;
bool is_regulator_on;
struct kbase_device *kbdev;
struct workqueue_struct *power_off_wq;