All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/1] drm/mgag200: Added resolution and bandwidth limits for various G200e products.
@ 2013-06-26 18:38 Julia Lemire
  2013-06-26 18:38 ` [PATCH v2 1/1] " Julia Lemire
  0 siblings, 1 reply; 3+ messages in thread
From: Julia Lemire @ 2013-06-26 18:38 UTC (permalink / raw)
  To: dri-devel; +Cc: Mathieu Larouche

I am resubmitting this patch because I ran into a build error when trying to 
build it on a 32-bit system.  I had to fix how the 64-bit division was done in 
mga_vga_calculate_mode_bandwidth.  I used the do_div macro instead of doing the
straight division.


Julia Lemire (1):
  drm/mgag200: Added resolution and bandwidth limits for various G200e
    products.

 drivers/gpu/drm/mgag200/mgag200_drv.h  |    3 +-
 drivers/gpu/drm/mgag200/mgag200_main.c |    2 +-
 drivers/gpu/drm/mgag200/mgag200_mode.c |   64 ++++++++++++++++++++++++++++++--
 3 files changed, 64 insertions(+), 5 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v2 1/1] drm/mgag200: Added resolution and bandwidth limits for various G200e products.
  2013-06-26 18:38 [PATCH v2 0/1] drm/mgag200: Added resolution and bandwidth limits for various G200e products Julia Lemire
@ 2013-06-26 18:38 ` Julia Lemire
  2013-06-27 11:08   ` Dave Airlie
  0 siblings, 1 reply; 3+ messages in thread
From: Julia Lemire @ 2013-06-26 18:38 UTC (permalink / raw)
  To: dri-devel; +Cc: Mathieu Larouche

At the larger resolutions, the g200e series sometimes struggles with
maintaining a proper output.  Problems like flickering or black bands appearing
on screen can occur.  In order to avoid this, limitations regarding resolutions
and bandwidth have been added for the different variations of the g200e series.
This code was ported from the old xorg mga driver.


Signed-off-by: Julia Lemire <jlemire@matrox.com>
---
 drivers/gpu/drm/mgag200/mgag200_drv.h  |    3 +-
 drivers/gpu/drm/mgag200/mgag200_main.c |    2 +-
 drivers/gpu/drm/mgag200/mgag200_mode.c |   64 ++++++++++++++++++++++++++++++--
 3 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index bf29b2f..988911a 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -198,7 +198,8 @@ struct mga_device {
 		struct ttm_bo_device bdev;
 	} ttm;
 
-	u32 reg_1e24; /* SE model number */
+	/* SE model number stored in reg 0x1e24 */
+	u32 unique_rev_id;
 };
 
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index 9905923..dafe049 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -176,7 +176,7 @@ static int mgag200_device_init(struct drm_device *dev,
 
 	/* stash G200 SE model number for later use */
 	if (IS_G200_SE(mdev))
-		mdev->reg_1e24 = RREG32(0x1e24);
+		mdev->unique_rev_id = RREG32(0x1e24);
 
 	ret = mga_vram_init(mdev);
 	if (ret)
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index ee66bad..098bc3b 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1008,7 +1008,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
 
 
 	if (IS_G200_SE(mdev)) {
-		if (mdev->reg_1e24 >= 0x02) {
+		if (mdev->unique_rev_id >= 0x02) {
 			u8 hi_pri_lvl;
 			u32 bpp;
 			u32 mb;
@@ -1038,7 +1038,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
 			WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl);
 		} else {
 			WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
-			if (mdev->reg_1e24 >= 0x01)
+			if (mdev->unique_rev_id >= 0x01)
 				WREG8(MGAREG_CRTCEXT_DATA, 0x03);
 			else
 				WREG8(MGAREG_CRTCEXT_DATA, 0x04);
@@ -1410,6 +1410,32 @@ static int mga_vga_get_modes(struct drm_connector *connector)
 	return ret;
 }
 
+static uint32_t mga_vga_calculate_mode_bandwidth(struct drm_display_mode * mode,
+                                                       int bits_per_pixel)
+{
+       uint32_t total_area, divisor;
+       uint64_t active_area, pixels_per_second, bandwidth;
+       uint64_t bytes_per_pixel = (bits_per_pixel + 7) / 8;
+
+       divisor = 1024;
+
+       if(!mode->htotal || !mode->vtotal || !mode->clock)
+               return 0;
+
+       active_area = mode->hdisplay * mode->vdisplay;
+       total_area = mode->htotal * mode->vtotal;
+
+       pixels_per_second = active_area * mode->clock * 1000;
+       do_div(pixels_per_second, total_area);
+       
+       bandwidth = pixels_per_second * bytes_per_pixel * 100;
+       do_div(bandwidth, divisor);
+       
+       return (uint32_t)(bandwidth);
+}
+
+#define MODE_BANDWIDTH	MODE_BAD
+
 static int mga_vga_mode_valid(struct drm_connector *connector,
 				 struct drm_display_mode *mode)
 {
@@ -1421,7 +1447,39 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
 	int bpp = 32;
 	int i = 0;
 
-	/* FIXME: Add bandwidth and g200se limitations */
+	if (IS_G200_SE(mdev)) {
+		if (mdev->unique_rev_id == 0x01) {
+			if (mode->hdisplay > 1600)
+				return MODE_VIRTUAL_X;
+			if (mode->vdisplay > 1200)
+				return MODE_VIRTUAL_Y;
+			if (mga_vga_calculate_mode_bandwidth(mode, bpp) > (24400 * 1024))
+				return MODE_BANDWIDTH;
+		} else if (mdev->unique_rev_id >= 0x02) {
+			if (mode->hdisplay > 1920)
+				return MODE_VIRTUAL_X;
+			if (mode->vdisplay > 1200)
+				return MODE_VIRTUAL_Y;
+			if (mga_vga_calculate_mode_bandwidth(mode, bpp) > (30100 * 1024))
+				return MODE_BANDWIDTH;
+		}
+	} else if (mdev->type == G200_WB) {
+		if (mode->hdisplay > 1280)
+			return MODE_VIRTUAL_X;
+		if (mode->vdisplay > 1024)
+			return MODE_VIRTUAL_Y;
+		if (mga_vga_calculate_mode_bandwidth(mode, bpp > (31877 * 1024)))
+			return MODE_BANDWIDTH;
+	} else if (mdev->type == G200_EV && 
+		(mga_vga_calculate_mode_bandwidth(mode, bpp) > (32700 * 1024))) {
+		return MODE_BANDWIDTH;
+	} else if (mode->type == G200_EH && 
+		(mga_vga_calculate_mode_bandwidth(mode, bpp) > (37500 * 1024))) {
+	 	return MODE_BANDWIDTH;
+	} else if (mode->type == G200_ER && 
+		(mga_vga_calculate_mode_bandwidth(mode, bpp) > (55000 * 1024))) {
+		return MODE_BANDWIDTH;
+	}
 
 	if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
 	    mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2 1/1] drm/mgag200: Added resolution and bandwidth limits for various G200e products.
  2013-06-26 18:38 ` [PATCH v2 1/1] " Julia Lemire
@ 2013-06-27 11:08   ` Dave Airlie
  0 siblings, 0 replies; 3+ messages in thread
From: Dave Airlie @ 2013-06-27 11:08 UTC (permalink / raw)
  To: Julia Lemire; +Cc: Mathieu Larouche, dri-devel

> At the larger resolutions, the g200e series sometimes struggles with
> maintaining a proper output.  Problems like flickering or black bands appearing
> on screen can occur.  In order to avoid this, limitations regarding resolutions
> and bandwidth have been added for the different variations of the g200e series.
> This code was ported from the old xorg mga driver.

Please run scripts/checkpatch.pl over patches before submitting them,
I'm seeing a few bad things in this.

Dave.

>
>
> Signed-off-by: Julia Lemire <jlemire@matrox.com>
> ---
>  drivers/gpu/drm/mgag200/mgag200_drv.h  |    3 +-
>  drivers/gpu/drm/mgag200/mgag200_main.c |    2 +-
>  drivers/gpu/drm/mgag200/mgag200_mode.c |   64 ++++++++++++++++++++++++++++++--
>  3 files changed, 64 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
> index bf29b2f..988911a 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_drv.h
> +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
> @@ -198,7 +198,8 @@ struct mga_device {
>                 struct ttm_bo_device bdev;
>         } ttm;
>
> -       u32 reg_1e24; /* SE model number */
> +       /* SE model number stored in reg 0x1e24 */
> +       u32 unique_rev_id;
>  };
>
>
> diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
> index 9905923..dafe049 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_main.c
> +++ b/drivers/gpu/drm/mgag200/mgag200_main.c
> @@ -176,7 +176,7 @@ static int mgag200_device_init(struct drm_device *dev,
>
>         /* stash G200 SE model number for later use */
>         if (IS_G200_SE(mdev))
> -               mdev->reg_1e24 = RREG32(0x1e24);
> +               mdev->unique_rev_id = RREG32(0x1e24);
>
>         ret = mga_vram_init(mdev);
>         if (ret)
> diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
> index ee66bad..098bc3b 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_mode.c
> +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
> @@ -1008,7 +1008,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
>
>
>         if (IS_G200_SE(mdev)) {
> -               if (mdev->reg_1e24 >= 0x02) {
> +               if (mdev->unique_rev_id >= 0x02) {
>                         u8 hi_pri_lvl;
>                         u32 bpp;
>                         u32 mb;
> @@ -1038,7 +1038,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
>                         WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl);
>                 } else {
>                         WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
> -                       if (mdev->reg_1e24 >= 0x01)
> +                       if (mdev->unique_rev_id >= 0x01)
>                                 WREG8(MGAREG_CRTCEXT_DATA, 0x03);
>                         else
>                                 WREG8(MGAREG_CRTCEXT_DATA, 0x04);
> @@ -1410,6 +1410,32 @@ static int mga_vga_get_modes(struct drm_connector *connector)
>         return ret;
>  }
>
> +static uint32_t mga_vga_calculate_mode_bandwidth(struct drm_display_mode * mode,
> +                                                       int bits_per_pixel)
> +{
> +       uint32_t total_area, divisor;
> +       uint64_t active_area, pixels_per_second, bandwidth;
> +       uint64_t bytes_per_pixel = (bits_per_pixel + 7) / 8;
> +
> +       divisor = 1024;
> +
> +       if(!mode->htotal || !mode->vtotal || !mode->clock)
> +               return 0;
> +
> +       active_area = mode->hdisplay * mode->vdisplay;
> +       total_area = mode->htotal * mode->vtotal;
> +
> +       pixels_per_second = active_area * mode->clock * 1000;
> +       do_div(pixels_per_second, total_area);
> +
> +       bandwidth = pixels_per_second * bytes_per_pixel * 100;
> +       do_div(bandwidth, divisor);
> +
> +       return (uint32_t)(bandwidth);
> +}
> +
> +#define MODE_BANDWIDTH MODE_BAD
> +
>  static int mga_vga_mode_valid(struct drm_connector *connector,
>                                  struct drm_display_mode *mode)
>  {
> @@ -1421,7 +1447,39 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
>         int bpp = 32;
>         int i = 0;
>
> -       /* FIXME: Add bandwidth and g200se limitations */
> +       if (IS_G200_SE(mdev)) {
> +               if (mdev->unique_rev_id == 0x01) {
> +                       if (mode->hdisplay > 1600)
> +                               return MODE_VIRTUAL_X;
> +                       if (mode->vdisplay > 1200)
> +                               return MODE_VIRTUAL_Y;
> +                       if (mga_vga_calculate_mode_bandwidth(mode, bpp) > (24400 * 1024))
> +                               return MODE_BANDWIDTH;
> +               } else if (mdev->unique_rev_id >= 0x02) {
> +                       if (mode->hdisplay > 1920)
> +                               return MODE_VIRTUAL_X;
> +                       if (mode->vdisplay > 1200)
> +                               return MODE_VIRTUAL_Y;
> +                       if (mga_vga_calculate_mode_bandwidth(mode, bpp) > (30100 * 1024))
> +                               return MODE_BANDWIDTH;
> +               }
> +       } else if (mdev->type == G200_WB) {
> +               if (mode->hdisplay > 1280)
> +                       return MODE_VIRTUAL_X;
> +               if (mode->vdisplay > 1024)
> +                       return MODE_VIRTUAL_Y;
> +               if (mga_vga_calculate_mode_bandwidth(mode, bpp > (31877 * 1024)))
> +                       return MODE_BANDWIDTH;
> +       } else if (mdev->type == G200_EV &&
> +               (mga_vga_calculate_mode_bandwidth(mode, bpp) > (32700 * 1024))) {
> +               return MODE_BANDWIDTH;
> +       } else if (mode->type == G200_EH &&
> +               (mga_vga_calculate_mode_bandwidth(mode, bpp) > (37500 * 1024))) {
> +               return MODE_BANDWIDTH;
> +       } else if (mode->type == G200_ER &&
> +               (mga_vga_calculate_mode_bandwidth(mode, bpp) > (55000 * 1024))) {
> +               return MODE_BANDWIDTH;
> +       }
>
>         if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
>             mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||
> --
> 1.7.10.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-06-27 11:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-26 18:38 [PATCH v2 0/1] drm/mgag200: Added resolution and bandwidth limits for various G200e products Julia Lemire
2013-06-26 18:38 ` [PATCH v2 1/1] " Julia Lemire
2013-06-27 11:08   ` Dave Airlie

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.