|
@@ -16,6 +16,7 @@
|
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
|
|
|
|
+#include "linux/clk.h"
|
|
|
#include "linux/component.h"
|
|
|
#include "linux/pm_runtime.h"
|
|
|
#include "vc4_drv.h"
|
|
@@ -305,6 +306,8 @@ static int vc4_v3d_runtime_suspend(struct device *dev)
|
|
|
drm_gem_object_put_unlocked(&vc4->bin_bo->base.base);
|
|
|
vc4->bin_bo = NULL;
|
|
|
|
|
|
+ clk_disable_unprepare(v3d->clk);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -318,6 +321,10 @@ static int vc4_v3d_runtime_resume(struct device *dev)
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
+ ret = clk_prepare_enable(v3d->clk);
|
|
|
+ if (ret != 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
vc4_v3d_init_hw(vc4->dev);
|
|
|
vc4_irq_postinstall(vc4->dev);
|
|
|
|
|
@@ -348,15 +355,37 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
|
|
|
vc4->v3d = v3d;
|
|
|
v3d->vc4 = vc4;
|
|
|
|
|
|
+ v3d->clk = devm_clk_get(dev, NULL);
|
|
|
+ if (IS_ERR(v3d->clk)) {
|
|
|
+ int ret = PTR_ERR(v3d->clk);
|
|
|
+
|
|
|
+ if (ret == -ENOENT) {
|
|
|
+ /* bcm2835 didn't have a clock reference in the DT. */
|
|
|
+ ret = 0;
|
|
|
+ v3d->clk = NULL;
|
|
|
+ } else {
|
|
|
+ if (ret != -EPROBE_DEFER)
|
|
|
+ dev_err(dev, "Failed to get V3D clock: %d\n",
|
|
|
+ ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (V3D_READ(V3D_IDENT0) != V3D_EXPECTED_IDENT0) {
|
|
|
DRM_ERROR("V3D_IDENT0 read 0x%08x instead of 0x%08x\n",
|
|
|
V3D_READ(V3D_IDENT0), V3D_EXPECTED_IDENT0);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ ret = clk_prepare_enable(v3d->clk);
|
|
|
+ if (ret != 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
ret = vc4_allocate_bin_bo(drm);
|
|
|
- if (ret)
|
|
|
+ if (ret) {
|
|
|
+ clk_disable_unprepare(v3d->clk);
|
|
|
return ret;
|
|
|
+ }
|
|
|
|
|
|
/* Reset the binner overflow address/size at setup, to be sure
|
|
|
* we don't reuse an old one.
|