Commit 52fa904e authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-msm-fixes-2022-01-25' of https://gitlab.freedesktop.org/drm/msm into drm-fixes

A few msm fixes.
- parameter checks
- put_device balancing
- idle/suspend fixes
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGvAfsgtr==VM4wixAC_hSTuV=eNWXxX=BhZqQrbxHjKgg@mail.gmail.com
parents 2fd0e5fb 6aa89ae1
......@@ -1560,6 +1560,8 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)
for (i = 0; i < gpu->nr_rings; i++)
a6xx_gpu->shadow[i] = 0;
gpu->suspend_count++;
return 0;
}
......
......@@ -608,9 +608,27 @@ static int adreno_resume(struct device *dev)
return gpu->funcs->pm_resume(gpu);
}
static int active_submits(struct msm_gpu *gpu)
{
int active_submits;
mutex_lock(&gpu->active_lock);
active_submits = gpu->active_submits;
mutex_unlock(&gpu->active_lock);
return active_submits;
}
static int adreno_suspend(struct device *dev)
{
struct msm_gpu *gpu = dev_to_gpu(dev);
int remaining;
remaining = wait_event_timeout(gpu->retire_event,
active_submits(gpu) == 0,
msecs_to_jiffies(1000));
if (remaining == 0) {
dev_err(dev, "Timeout waiting for GPU to suspend\n");
return -EBUSY;
}
return gpu->funcs->pm_suspend(gpu);
}
......
......@@ -26,9 +26,16 @@ static void dpu_setup_dspp_pcc(struct dpu_hw_dspp *ctx,
struct dpu_hw_pcc_cfg *cfg)
{
u32 base = ctx->cap->sblk->pcc.base;
u32 base;
if (!ctx || !base) {
if (!ctx) {
DRM_ERROR("invalid ctx %pK\n", ctx);
return;
}
base = ctx->cap->sblk->pcc.base;
if (!base) {
DRM_ERROR("invalid ctx %pK pcc base 0x%x\n", ctx, base);
return;
}
......
......@@ -40,7 +40,12 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi)
of_node_put(phy_node);
if (!phy_pdev || !msm_dsi->phy) {
if (!phy_pdev) {
DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__);
return -EPROBE_DEFER;
}
if (!msm_dsi->phy) {
put_device(&phy_pdev->dev);
DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__);
return -EPROBE_DEFER;
}
......
......@@ -808,12 +808,14 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy,
struct msm_dsi_phy_clk_request *clk_req,
struct msm_dsi_phy_shared_timings *shared_timings)
{
struct device *dev = &phy->pdev->dev;
struct device *dev;
int ret;
if (!phy || !phy->cfg->ops.enable)
return -EINVAL;
dev = &phy->pdev->dev;
ret = dsi_phy_enable_resource(phy);
if (ret) {
DRM_DEV_ERROR(dev, "%s: resource enable failed, %d\n",
......
......@@ -97,10 +97,15 @@ static int msm_hdmi_get_phy(struct hdmi *hdmi)
of_node_put(phy_node);
if (!phy_pdev || !hdmi->phy) {
if (!phy_pdev) {
DRM_DEV_ERROR(&pdev->dev, "phy driver is not ready\n");
return -EPROBE_DEFER;
}
if (!hdmi->phy) {
DRM_DEV_ERROR(&pdev->dev, "phy driver is not ready\n");
put_device(&phy_pdev->dev);
return -EPROBE_DEFER;
}
hdmi->phy_dev = get_device(&phy_pdev->dev);
......
......@@ -461,7 +461,7 @@ static int msm_init_vram(struct drm_device *dev)
of_node_put(node);
if (ret)
return ret;
size = r.end - r.start;
size = r.end - r.start + 1;
DRM_INFO("using VRAM carveout: %lx@%pa\n", size, &r.start);
/* if we have no IOMMU, then we need to use carveout allocator.
......@@ -510,7 +510,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
struct msm_drm_private *priv = dev_get_drvdata(dev);
struct drm_device *ddev;
struct msm_kms *kms;
struct msm_mdss *mdss;
int ret, i;
ddev = drm_dev_alloc(drv, dev);
......@@ -521,8 +520,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
ddev->dev_private = priv;
priv->dev = ddev;
mdss = priv->mdss;
priv->wq = alloc_ordered_workqueue("msm", 0);
priv->hangcheck_period = DRM_MSM_HANGCHECK_DEFAULT_PERIOD;
......
......@@ -703,6 +703,8 @@ static void retire_submits(struct msm_gpu *gpu)
}
}
}
wake_up_all(&gpu->retire_event);
}
static void retire_worker(struct kthread_work *work)
......@@ -848,6 +850,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
INIT_LIST_HEAD(&gpu->active_list);
mutex_init(&gpu->active_lock);
mutex_init(&gpu->lock);
init_waitqueue_head(&gpu->retire_event);
kthread_init_work(&gpu->retire_work, retire_worker);
kthread_init_work(&gpu->recover_work, recover_worker);
kthread_init_work(&gpu->fault_work, fault_worker);
......
......@@ -230,6 +230,9 @@ struct msm_gpu {
/* work for handling GPU recovery: */
struct kthread_work recover_work;
/** retire_event: notified when submits are retired: */
wait_queue_head_t retire_event;
/* work for handling active-list retiring: */
struct kthread_work retire_work;
......
......@@ -133,6 +133,18 @@ void msm_devfreq_init(struct msm_gpu *gpu)
CLOCK_MONOTONIC, HRTIMER_MODE_REL);
}
static void cancel_idle_work(struct msm_gpu_devfreq *df)
{
hrtimer_cancel(&df->idle_work.timer);
kthread_cancel_work_sync(&df->idle_work.work);
}
static void cancel_boost_work(struct msm_gpu_devfreq *df)
{
hrtimer_cancel(&df->boost_work.timer);
kthread_cancel_work_sync(&df->boost_work.work);
}
void msm_devfreq_cleanup(struct msm_gpu *gpu)
{
struct msm_gpu_devfreq *df = &gpu->devfreq;
......@@ -152,7 +164,12 @@ void msm_devfreq_resume(struct msm_gpu *gpu)
void msm_devfreq_suspend(struct msm_gpu *gpu)
{
devfreq_suspend_device(gpu->devfreq.devfreq);
struct msm_gpu_devfreq *df = &gpu->devfreq;
devfreq_suspend_device(df->devfreq);
cancel_idle_work(df);
cancel_boost_work(df);
}
static void msm_devfreq_boost_work(struct kthread_work *work)
......@@ -196,7 +213,7 @@ void msm_devfreq_active(struct msm_gpu *gpu)
/*
* Cancel any pending transition to idle frequency:
*/
hrtimer_cancel(&df->idle_work.timer);
cancel_idle_work(df);
idle_time = ktime_to_ms(ktime_sub(ktime_get(), df->idle_time));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment