summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/imagination/pvr_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/imagination/pvr_device.c')
-rw-r--r--drivers/gpu/drm/imagination/pvr_device.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c
index 201ae780494f..e16282325178 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -5,6 +5,7 @@
#include "pvr_device_info.h"
#include "pvr_fw.h"
+#include "pvr_power.h"
#include "pvr_rogue_cr_defs.h"
#include "pvr_vm.h"
@@ -361,6 +362,8 @@ pvr_device_gpu_fini(struct pvr_device *pvr_dev)
int
pvr_device_init(struct pvr_device *pvr_dev)
{
+ struct drm_device *drm_dev = from_pvr_device(pvr_dev);
+ struct device *dev = drm_dev->dev;
int err;
/* Enable and initialize clocks required for the device to operate. */
@@ -368,13 +371,29 @@ pvr_device_init(struct pvr_device *pvr_dev)
if (err)
return err;
+ /* Explicitly power the GPU so we can access control registers before the FW is booted. */
+ err = pm_runtime_resume_and_get(dev);
+ if (err)
+ return err;
+
/* Map the control registers into memory. */
err = pvr_device_reg_init(pvr_dev);
if (err)
- return err;
+ goto err_pm_runtime_put;
/* Perform GPU-specific initialization steps. */
- return pvr_device_gpu_init(pvr_dev);
+ err = pvr_device_gpu_init(pvr_dev);
+ if (err)
+ goto err_pm_runtime_put;
+
+ pm_runtime_put(dev);
+
+ return 0;
+
+err_pm_runtime_put:
+ pm_runtime_put_sync_suspend(dev);
+
+ return err;
}
/**