diff options
Diffstat (limited to 'drivers/gpu')
| -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 || |
