diff options
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_main.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_mode.c | 70 |
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 | ||
1415 | static 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 | |||
1415 | static int mga_vga_mode_valid(struct drm_connector *connector, | 1441 | static 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 || |