[PATCH v3 015/105] drm/vc4: hvs: Boost the core clock during modeset

From: Maxime Ripard
Date: Wed May 27 2020 - 11:49:45 EST


In order to prevent timeouts and stalls in the pipeline, the core clock
needs to be maxed at 500MHz during a modeset on the BCM2711.

Signed-off-by: Maxime Ripard <maxime@xxxxxxxxxx>
---
drivers/gpu/drm/vc4/vc4_drv.h | 2 ++
drivers/gpu/drm/vc4/vc4_hvs.c | 9 +++++++++
drivers/gpu/drm/vc4/vc4_kms.c | 7 +++++++
3 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 1e226454c9a6..9b57ea2ba93f 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -323,6 +323,8 @@ struct vc4_hvs {
void __iomem *regs;
u32 __iomem *dlist;

+ struct clk *core_clk;
+
/* Memory manager for CRTCs to allocate space in the display
* list. Units are dwords.
*/
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 0fe4758de03a..f4942667355b 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -19,6 +19,7 @@
* each CRTC.
*/

+#include <linux/clk.h>
#include <linux/component.h>
#include <linux/platform_device.h>

@@ -241,6 +242,14 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
hvs->regset.regs = hvs_regs;
hvs->regset.nregs = ARRAY_SIZE(hvs_regs);

+ if (hvs->hvs5) {
+ hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(hvs->core_clk)) {
+ dev_err(&pdev->dev, "Couldn't get core clock\n");
+ return PTR_ERR(hvs->core_clk);
+ }
+ }
+
if (!hvs->hvs5)
hvs->dlist = hvs->regs + SCALER_DLIST_START;
else
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 9417e45d981f..29b75b60d858 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -11,6 +11,8 @@
* crtc, HDMI encoder).
*/

+#include <linux/clk.h>
+
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
@@ -149,6 +151,7 @@ vc4_atomic_complete_commit(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_hvs *hvs = vc4->hvs;
struct vc4_crtc *vc4_crtc;
int i;

@@ -160,6 +163,8 @@ vc4_atomic_complete_commit(struct drm_atomic_state *state)
vc4_hvs_mask_underrun(dev, vc4_crtc->channel);
}

+ clk_set_rate(hvs->core_clk, 500000000);
+
drm_atomic_helper_wait_for_fences(dev, state, false);

drm_atomic_helper_wait_for_dependencies(state);
@@ -182,6 +187,8 @@ vc4_atomic_complete_commit(struct drm_atomic_state *state)

drm_atomic_helper_commit_cleanup_done(state);

+ clk_set_rate(hvs->core_clk, 200000000);
+
drm_atomic_state_put(state);

up(&vc4->async_modeset);
--
git-series 0.9.1