Skip to content

Commit 71be60f

Browse files
committed
drm/vc4: v3d: Rework the runtime_pm setup
At bind time, vc4_v3d_bind() will read a register to retrieve the v3d version and make sure it's a version we're compatible with. However, the v3d has an optional clock that is enabled only after the register read-out and a power domain that wasn't enabled at all in the bind implementation. This was working fine at boot because both were enabled, but resulted in the version check failing if we were unbinding and rebinding the driver because the unbinding would have turned them off. The fix isn't as easy as calling pm_runtime_resume_and_get() prior to the register access to power up the power domain though. Indeed, the runtime_resume implementation will enable the clock mentioned above, call vc4_v3d_init_hw() and then vc4_irq_enable(). Prior to the previous patch, vc4_irq_enable() needed to occur after our call to platform_get_irq() and vc4_irq_install(), since vc4_irq_enable() used to call enable_irq() and vc4_irq_install() will call request_irq(). vc4_irq_install() will also do some register access, so needs the power domain to be on. So we ended up in a situation where vc4_v3d_runtime_resume() needed vc4_irq_install() to have been called before, and vc4_irq_install() needed vc4_v3d_runtime_resume(). The previous patch removed the enable_irq() call in vc4_irq_enable() and thus removed the dependency of vc4_v3d_runtime_resume() on vc4_irq_install(). Thus, we can now rework our bind implementation to call pm_runtime_resume_and_get() before our register access to make sure the power domain is on. vc4_v3d_runtime_resume() also takes care of turning the clock on and calling vc4_v3d_init_hw() so we can remove them from bind. Acked-by: Thomas Zimmermann <[email protected]> Signed-off-by: Maxime Ripard <[email protected]>
1 parent 412d276 commit 71be60f

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

drivers/gpu/drm/vc4/vc4_v3d.c

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -463,41 +463,48 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
463463
}
464464
}
465465

466+
ret = platform_get_irq(pdev, 0);
467+
if (ret < 0)
468+
return ret;
469+
vc4->irq = ret;
470+
471+
pm_runtime_enable(dev);
472+
473+
ret = pm_runtime_resume_and_get(dev);
474+
if (ret)
475+
goto err_disable_runtime_pm;
476+
466477
if (V3D_READ(V3D_IDENT0) != V3D_EXPECTED_IDENT0) {
467478
DRM_ERROR("V3D_IDENT0 read 0x%08x instead of 0x%08x\n",
468479
V3D_READ(V3D_IDENT0), V3D_EXPECTED_IDENT0);
469-
return -EINVAL;
480+
ret = -EINVAL;
481+
goto err_put_runtime_pm;
470482
}
471483

472-
ret = clk_prepare_enable(v3d->clk);
473-
if (ret != 0)
474-
return ret;
475-
476484
/* Reset the binner overflow address/size at setup, to be sure
477485
* we don't reuse an old one.
478486
*/
479487
V3D_WRITE(V3D_BPOA, 0);
480488
V3D_WRITE(V3D_BPOS, 0);
481489

482-
vc4_v3d_init_hw(drm);
483-
484-
ret = platform_get_irq(pdev, 0);
485-
if (ret < 0)
486-
return ret;
487-
vc4->irq = ret;
488-
489490
ret = vc4_irq_install(drm, vc4->irq);
490491
if (ret) {
491492
DRM_ERROR("Failed to install IRQ handler\n");
492-
return ret;
493+
goto err_put_runtime_pm;
493494
}
494495

495-
pm_runtime_set_active(dev);
496496
pm_runtime_use_autosuspend(dev);
497497
pm_runtime_set_autosuspend_delay(dev, 40); /* a little over 2 frames. */
498-
pm_runtime_enable(dev);
499498

500499
return 0;
500+
501+
err_put_runtime_pm:
502+
pm_runtime_put(dev);
503+
504+
err_disable_runtime_pm:
505+
pm_runtime_disable(dev);
506+
507+
return ret;
501508
}
502509

503510
static void vc4_v3d_unbind(struct device *dev, struct device *master,

0 commit comments

Comments
 (0)