> 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@xxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel