Skip to content

Commit

Permalink
drm/msm/gpu: fix clk lockup PM suspend/resume handler (v2)
Browse files Browse the repository at this point in the history
testing freq. transitions on MSM8916 Samsung J5 "a3xx":
locks up when gpu was on 310MHz:

resume handler was setting opp rate that will do clk_set_rate before
the clk was enabled.

devfreq can do this job if opp-suspend was defined in dt.

changed resume so clk gets enabled first and let devfreq setting it

changed suspend aswell

Signed-off-by: Christoph Rudorff <[email protected]>

drm/msm/gpu: PM suspend/resume handler hotfix resume

Signed-off-by: Christoph Rudorff <[email protected]>
  • Loading branch information
Christoph Rudorff committed Oct 16, 2023
1 parent 10a4487 commit c48aba5
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
25 changes: 19 additions & 6 deletions drivers/gpu/drm/msm/msm_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,31 +57,44 @@ static int disable_pwrrail(struct msm_gpu *gpu)

static int enable_clk(struct msm_gpu *gpu)
{
if (gpu->core_clk && gpu->fast_rate)
int ret;
ret = clk_bulk_prepare_enable(gpu->nr_clocks, gpu->grp_clks);
if (ret)
return ret;
/*
devfreq_resume_device() will do set_rate
if an "opp-suspend" exists
*/
if (gpu->core_clk && gpu->fast_rate &&
dev_pm_opp_get_suspend_opp_freq(&gpu->pdev->dev) == 0)
dev_pm_opp_set_rate(&gpu->pdev->dev, gpu->fast_rate);

/* Set the RBBM timer rate to 19.2Mhz */
if (gpu->rbbmtimer_clk)
clk_set_rate(gpu->rbbmtimer_clk, 19200000);

return clk_bulk_prepare_enable(gpu->nr_clocks, gpu->grp_clks);
return 0;
}

static int disable_clk(struct msm_gpu *gpu)
{
clk_bulk_disable_unprepare(gpu->nr_clocks, gpu->grp_clks);

/*
* Set the clock to a deliberately low rate. On older targets the clock
* speed had to be non zero to avoid problems. On newer targets this
* will be rounded down to zero anyway so it all works out.
* skip this if an "opp-suspend" exists:
* devfreq_suspend_device() has done this
*/
if (gpu->core_clk)
dev_pm_opp_set_rate(&gpu->pdev->dev, 27000000);
if (gpu->core_clk &&
dev_pm_opp_get_suspend_opp_freq(&gpu->pdev->dev) == 0)
dev_pm_opp_set_rate(&gpu->pdev->dev, 1);

if (gpu->rbbmtimer_clk)
clk_set_rate(gpu->rbbmtimer_clk, 0);

clk_bulk_disable_unprepare(gpu->nr_clocks, gpu->grp_clks);

return 0;
}

Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/msm/msm_gpu_devfreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ void msm_devfreq_resume(struct msm_gpu *gpu)
mutex_lock(&df->lock);
df->busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate);
df->time = ktime_get();
df->idle_freq = 0;
df->suspended = false;
mutex_unlock(&df->lock);

Expand All @@ -247,10 +248,10 @@ void msm_devfreq_suspend(struct msm_gpu *gpu)
df->suspended = true;
mutex_unlock(&df->lock);

devfreq_suspend_device(df->devfreq);

cancel_idle_work(df);
cancel_boost_work(df);

devfreq_suspend_device(df->devfreq);
}

static void msm_devfreq_boost_work(struct kthread_work *work)
Expand Down

0 comments on commit c48aba5

Please sign in to comment.