aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c37
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c5
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h3
3 files changed, 45 insertions, 0 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index cc85c16cbc2a..ae2e16ed3874 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -23,6 +23,7 @@
23#include <drm/drm_crtc_helper.h> 23#include <drm/drm_crtc_helper.h>
24#include <drm/drm_mode.h> 24#include <drm/drm_mode.h>
25#include <drm/drm_plane_helper.h> 25#include <drm/drm_plane_helper.h>
26#include <linux/math64.h>
26 27
27#include "omap_drv.h" 28#include "omap_drv.h"
28 29
@@ -400,6 +401,41 @@ static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
400 drm_crtc_vblank_off(crtc); 401 drm_crtc_vblank_off(crtc);
401} 402}
402 403
404static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
405 const struct drm_display_mode *mode)
406{
407 struct omap_drm_private *priv = crtc->dev->dev_private;
408
409 /* Check for bandwidth limit */
410 if (priv->max_bandwidth) {
411 /*
412 * Estimation for the bandwidth need of a given mode with one
413 * full screen plane:
414 * bandwidth = resolution * 32bpp * (pclk / (vtotal * htotal))
415 * ^^ Refresh rate ^^
416 *
417 * The interlaced mode is taken into account by using the
418 * pixelclock in the calculation.
419 *
420 * The equation is rearranged for 64bit arithmetic.
421 */
422 uint64_t bandwidth = mode->clock * 1000;
423 unsigned int bpp = 4;
424
425 bandwidth = bandwidth * mode->hdisplay * mode->vdisplay * bpp;
426 bandwidth = div_u64(bandwidth, mode->htotal * mode->vtotal);
427
428 /*
429 * Reject modes which would need more bandwidth if used with one
430 * full resolution plane (most common use case).
431 */
432 if (priv->max_bandwidth < bandwidth)
433 return MODE_BAD;
434 }
435
436 return MODE_OK;
437}
438
403static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) 439static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
404{ 440{
405 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 441 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -621,6 +657,7 @@ static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
621 .atomic_flush = omap_crtc_atomic_flush, 657 .atomic_flush = omap_crtc_atomic_flush,
622 .atomic_enable = omap_crtc_atomic_enable, 658 .atomic_enable = omap_crtc_atomic_enable,
623 .atomic_disable = omap_crtc_atomic_disable, 659 .atomic_disable = omap_crtc_atomic_disable,
660 .mode_valid = omap_crtc_mode_valid,
624}; 661};
625 662
626/* ----------------------------------------------------------------------------- 663/* -----------------------------------------------------------------------------
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 96857c508ee0..c4bb261dfcd9 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -563,6 +563,11 @@ static int pdev_probe(struct platform_device *pdev)
563 ddev->dev_private = priv; 563 ddev->dev_private = priv;
564 platform_set_drvdata(pdev, ddev); 564 platform_set_drvdata(pdev, ddev);
565 565
566 /* Get memory bandwidth limits */
567 if (priv->dispc_ops->get_memory_bandwidth_limit)
568 priv->max_bandwidth =
569 priv->dispc_ops->get_memory_bandwidth_limit();
570
566 omap_gem_init(ddev); 571 omap_gem_init(ddev);
567 572
568 ret = omap_modeset_init(ddev); 573 ret = omap_modeset_init(ddev);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 4bd1e9070b31..d404e8c56b61 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -83,6 +83,9 @@ struct omap_drm_private {
83 spinlock_t wait_lock; /* protects the wait_list */ 83 spinlock_t wait_lock; /* protects the wait_list */
84 struct list_head wait_list; /* list of omap_irq_wait */ 84 struct list_head wait_list; /* list of omap_irq_wait */
85 uint32_t irq_mask; /* enabled irqs in addition to wait_list */ 85 uint32_t irq_mask; /* enabled irqs in addition to wait_list */
86
87 /* memory bandwidth limit if it is needed on the platform */
88 unsigned int max_bandwidth;
86}; 89};
87 90
88 91