From 328b7bf4c412c001823eed1411f6b0eea42f046c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 28 Apr 2017 15:42:21 -0700 Subject: [PATCH] drm/vc4: Turn the V3D clock on at runtime. For the Raspberry Pi's bindings, the power domain also implicitly turns on the clock and deasserts reset, but for the new Cygnus port we start representing the clock in the devicetree. v2: Document the clock-names property, check for -ENOENT for no clock in DT. v3: Drop NULL checks around clk calls which embed NULL checks. v4: Drop clk-names (feedback by Rob Herring) Signed-off-by: Eric Anholt Acked-by: Rob Herring Link: http://patchwork.freedesktop.org/patch/msgid/20170428224223.21904-1-eric@anholt.net --- .../bindings/display/brcm,bcm-vc4.txt | 3 ++ drivers/gpu/drm/vc4/vc4_drv.h | 1 + drivers/gpu/drm/vc4/vc4_v3d.c | 31 ++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt index ca02d3e4db917..bc1756f4f7918 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt +++ b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt @@ -59,6 +59,9 @@ Required properties for V3D: - interrupts: The interrupt number See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt +Optional properties for V3D: +- clocks: The clock the unit runs on + Required properties for DSI: - compatible: Should be "brcm,bcm2835-dsi0" or "brcm,bcm2835-dsi1" - reg: Physical base address and length of the DSI block's registers diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index b0967e2f7e882..92eb7d811bf21 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -200,6 +200,7 @@ struct vc4_v3d { struct vc4_dev *vc4; struct platform_device *pdev; void __iomem *regs; + struct clk *clk; }; struct vc4_hvs { diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c index a88078d7c9d14..7500820e5cd51 100644 --- a/drivers/gpu/drm/vc4/vc4_v3d.c +++ b/drivers/gpu/drm/vc4/vc4_v3d.c @@ -16,6 +16,7 @@ * this program. If not, see . */ +#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. -- 2.39.5