aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2018-03-07 16:58:19 -0500
committerLinus Walleij <linus.walleij@linaro.org>2018-03-07 17:14:24 -0500
commitdf99dd9202216f54eaf672e07808e9198d868af6 (patch)
treeee75d257bc640dec1ff405deca483e83b63216e2 /drivers
parent2e7a66a8b5ebf1b04a866e5d7c981640f7f62934 (diff)
drm/pl111: Use max memory bandwidth for resolution
We were previously selecting 1024x768 and 32BPP as the default set-up for the PL111 consumers. This does not work on elder systems: the device tree bindings support a property "max-memory-bandwidth" in bytes/second that states that if you exceed this the memory bus will saturate. The result is flickering and unstable images. Parse the "max-memory-bandwidth" and respect it when intializing the driver. On the RealView PB11MP, Versatile and Integrator/CP we get a nice console as default with this code. Reviewed-by: Eric Anholt <eric@anholt.net> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20180307215819.15814-1-linus.walleij@linaro.org
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/pl111/pl111_display.c36
-rw-r--r--drivers/gpu/drm/pl111/pl111_drm.h1
-rw-r--r--drivers/gpu/drm/pl111/pl111_drv.c6
3 files changed, 43 insertions, 0 deletions
diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c
index 5b8368c76734..310646427907 100644
--- a/drivers/gpu/drm/pl111/pl111_display.c
+++ b/drivers/gpu/drm/pl111/pl111_display.c
@@ -50,6 +50,41 @@ irqreturn_t pl111_irq(int irq, void *data)
50 return status; 50 return status;
51} 51}
52 52
53static enum drm_mode_status
54pl111_mode_valid(struct drm_crtc *crtc,
55 const struct drm_display_mode *mode)
56{
57 struct drm_device *drm = crtc->dev;
58 struct pl111_drm_dev_private *priv = drm->dev_private;
59 u32 cpp = priv->variant->fb_bpp / 8;
60 u64 bw;
61
62 /*
63 * We use the pixelclock to also account for interlaced modes, the
64 * resulting bandwidth is in bytes per second.
65 */
66 bw = mode->clock * 1000; /* In Hz */
67 bw = bw * mode->hdisplay * mode->vdisplay * cpp;
68 bw = div_u64(bw, mode->htotal * mode->vtotal);
69
70 /*
71 * If no bandwidth constraints, anything goes, else
72 * check if we are too fast.
73 */
74 if (priv->memory_bw && (bw > priv->memory_bw)) {
75 DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu too fast\n",
76 mode->hdisplay, mode->vdisplay,
77 mode->clock * 1000, cpp, bw);
78
79 return MODE_BAD;
80 }
81 DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu bytes/s OK\n",
82 mode->hdisplay, mode->vdisplay,
83 mode->clock * 1000, cpp, bw);
84
85 return MODE_OK;
86}
87
53static int pl111_display_check(struct drm_simple_display_pipe *pipe, 88static int pl111_display_check(struct drm_simple_display_pipe *pipe,
54 struct drm_plane_state *pstate, 89 struct drm_plane_state *pstate,
55 struct drm_crtc_state *cstate) 90 struct drm_crtc_state *cstate)
@@ -348,6 +383,7 @@ static int pl111_display_prepare_fb(struct drm_simple_display_pipe *pipe,
348} 383}
349 384
350static struct drm_simple_display_pipe_funcs pl111_display_funcs = { 385static struct drm_simple_display_pipe_funcs pl111_display_funcs = {
386 .mode_valid = pl111_mode_valid,
351 .check = pl111_display_check, 387 .check = pl111_display_check,
352 .enable = pl111_display_enable, 388 .enable = pl111_display_enable,
353 .disable = pl111_display_disable, 389 .disable = pl111_display_disable,
diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h
index 2a93e0134061..8639b2d4ddf7 100644
--- a/drivers/gpu/drm/pl111/pl111_drm.h
+++ b/drivers/gpu/drm/pl111/pl111_drm.h
@@ -65,6 +65,7 @@ struct pl111_drm_dev_private {
65 struct drm_simple_display_pipe pipe; 65 struct drm_simple_display_pipe pipe;
66 66
67 void *regs; 67 void *regs;
68 u32 memory_bw;
68 u32 ienb; 69 u32 ienb;
69 u32 ctrl; 70 u32 ctrl;
70 /* The pixel clock (a reference to our clock divider off of CLCDCLK). */ 71 /* The pixel clock (a reference to our clock divider off of CLCDCLK). */
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index e92a406c9ea9..4621259d5387 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -257,6 +257,12 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
257 drm->dev_private = priv; 257 drm->dev_private = priv;
258 priv->variant = variant; 258 priv->variant = variant;
259 259
260 if (of_property_read_u32(dev->of_node, "max-memory-bandwidth",
261 &priv->memory_bw)) {
262 dev_info(dev, "no max memory bandwidth specified, assume unlimited\n");
263 priv->memory_bw = 0;
264 }
265
260 /* The two variants swap this register */ 266 /* The two variants swap this register */
261 if (variant->is_pl110) { 267 if (variant->is_pl110) {
262 priv->ienb = CLCD_PL110_IENB; 268 priv->ienb = CLCD_PL110_IENB;