[PATCH v2 1/1] drm/mgag200: Added resolution and bandwidth limits for various G200e products.
Dave Airlie
airlied at gmail.com
Thu Jun 27 04:08:06 PDT 2013
> 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 at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the dri-devel
mailing list