aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h3
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_main.c2
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c70
3 files changed, 70 insertions, 5 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 364a05a15eb1..d9737ef2d9a2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -214,7 +214,8 @@ struct mga_device {
214 struct ttm_bo_device bdev; 214 struct ttm_bo_device bdev;
215 } ttm; 215 } ttm;
216 216
217 u32 reg_1e24; /* SE model number */ 217 /* SE model number stored in reg 0x1e24 */
218 u32 unique_rev_id;
218}; 219};
219 220
220 221
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index 6d6b598ff791..9fa5685baee0 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,
176 176
177 /* stash G200 SE model number for later use */ 177 /* stash G200 SE model number for later use */
178 if (IS_G200_SE(mdev)) 178 if (IS_G200_SE(mdev))
179 mdev->reg_1e24 = RREG32(0x1e24); 179 mdev->unique_rev_id = RREG32(0x1e24);
180 180
181 ret = mga_vram_init(mdev); 181 ret = mga_vram_init(mdev);
182 if (ret) 182 if (ret)
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 5b1a9e73fe58..251784aa2225 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,
1008 1008
1009 1009
1010 if (IS_G200_SE(mdev)) { 1010 if (IS_G200_SE(mdev)) {
1011 if (mdev->reg_1e24 >= 0x02) { 1011 if (mdev->unique_rev_id >= 0x02) {
1012 u8 hi_pri_lvl; 1012 u8 hi_pri_lvl;
1013 u32 bpp; 1013 u32 bpp;
1014 u32 mb; 1014 u32 mb;
@@ -1038,7 +1038,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
1038 WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl); 1038 WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl);
1039 } else { 1039 } else {
1040 WREG8(MGAREG_CRTCEXT_INDEX, 0x06); 1040 WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1041 if (mdev->reg_1e24 >= 0x01) 1041 if (mdev->unique_rev_id >= 0x01)
1042 WREG8(MGAREG_CRTCEXT_DATA, 0x03); 1042 WREG8(MGAREG_CRTCEXT_DATA, 0x03);
1043 else 1043 else
1044 WREG8(MGAREG_CRTCEXT_DATA, 0x04); 1044 WREG8(MGAREG_CRTCEXT_DATA, 0x04);
@@ -1412,6 +1412,32 @@ static int mga_vga_get_modes(struct drm_connector *connector)
1412 return ret; 1412 return ret;
1413} 1413}
1414 1414
1415static uint32_t mga_vga_calculate_mode_bandwidth(struct drm_display_mode *mode,
1416 int bits_per_pixel)
1417{
1418 uint32_t total_area, divisor;
1419 int64_t active_area, pixels_per_second, bandwidth;
1420 uint64_t bytes_per_pixel = (bits_per_pixel + 7) / 8;
1421
1422 divisor = 1024;
1423
1424 if (!mode->htotal || !mode->vtotal || !mode->clock)
1425 return 0;
1426
1427 active_area = mode->hdisplay * mode->vdisplay;
1428 total_area = mode->htotal * mode->vtotal;
1429
1430 pixels_per_second = active_area * mode->clock * 1000;
1431 do_div(pixels_per_second, total_area);
1432
1433 bandwidth = pixels_per_second * bytes_per_pixel * 100;
1434 do_div(bandwidth, divisor);
1435
1436 return (uint32_t)(bandwidth);
1437}
1438
1439#define MODE_BANDWIDTH MODE_BAD
1440
1415static int mga_vga_mode_valid(struct drm_connector *connector, 1441static int mga_vga_mode_valid(struct drm_connector *connector,
1416 struct drm_display_mode *mode) 1442 struct drm_display_mode *mode)
1417{ 1443{
@@ -1423,7 +1449,45 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
1423 int bpp = 32; 1449 int bpp = 32;
1424 int i = 0; 1450 int i = 0;
1425 1451
1426 /* FIXME: Add bandwidth and g200se limitations */ 1452 if (IS_G200_SE(mdev)) {
1453 if (mdev->unique_rev_id == 0x01) {
1454 if (mode->hdisplay > 1600)
1455 return MODE_VIRTUAL_X;
1456 if (mode->vdisplay > 1200)
1457 return MODE_VIRTUAL_Y;
1458 if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1459 > (24400 * 1024))
1460 return MODE_BANDWIDTH;
1461 } else if (mdev->unique_rev_id >= 0x02) {
1462 if (mode->hdisplay > 1920)
1463 return MODE_VIRTUAL_X;
1464 if (mode->vdisplay > 1200)
1465 return MODE_VIRTUAL_Y;
1466 if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1467 > (30100 * 1024))
1468 return MODE_BANDWIDTH;
1469 }
1470 } else if (mdev->type == G200_WB) {
1471 if (mode->hdisplay > 1280)
1472 return MODE_VIRTUAL_X;
1473 if (mode->vdisplay > 1024)
1474 return MODE_VIRTUAL_Y;
1475 if (mga_vga_calculate_mode_bandwidth(mode,
1476 bpp > (31877 * 1024)))
1477 return MODE_BANDWIDTH;
1478 } else if (mdev->type == G200_EV &&
1479 (mga_vga_calculate_mode_bandwidth(mode, bpp)
1480 > (32700 * 1024))) {
1481 return MODE_BANDWIDTH;
1482 } else if (mode->type == G200_EH &&
1483 (mga_vga_calculate_mode_bandwidth(mode, bpp)
1484 > (37500 * 1024))) {
1485 return MODE_BANDWIDTH;
1486 } else if (mode->type == G200_ER &&
1487 (mga_vga_calculate_mode_bandwidth(mode,
1488 bpp) > (55000 * 1024))) {
1489 return MODE_BANDWIDTH;
1490 }
1427 1491
1428 if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 || 1492 if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
1429 mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 || 1493 mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||