diff options
| author | Alex Deucher <alexdeucher@gmail.com> | 2009-11-05 11:57:07 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2009-11-05 20:35:42 -0500 |
| commit | a3fa6320ce964f799388b152a1b0f6e2c3b32a7f (patch) | |
| tree | 0925ed2b6375ce557bb081fc9311fe5305652bcf | |
| parent | f95a9f0b05d22cffc46fbd2d065b260f8405e43f (diff) | |
drm/radeon/kms: initial mode validation support
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index fb4d9184704a..fce4c4087fda 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -397,6 +397,30 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) | |||
| 397 | static int radeon_lvds_mode_valid(struct drm_connector *connector, | 397 | static int radeon_lvds_mode_valid(struct drm_connector *connector, |
| 398 | struct drm_display_mode *mode) | 398 | struct drm_display_mode *mode) |
| 399 | { | 399 | { |
| 400 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | ||
| 401 | |||
| 402 | if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) | ||
| 403 | return MODE_PANEL; | ||
| 404 | |||
| 405 | if (encoder) { | ||
| 406 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 407 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | ||
| 408 | |||
| 409 | /* AVIVO hardware supports downscaling modes larger than the panel | ||
| 410 | * to the panel size, but I'm not sure this is desirable. | ||
| 411 | */ | ||
| 412 | if ((mode->hdisplay > native_mode->hdisplay) || | ||
| 413 | (mode->vdisplay > native_mode->vdisplay)) | ||
| 414 | return MODE_PANEL; | ||
| 415 | |||
| 416 | /* if scaling is disabled, block non-native modes */ | ||
| 417 | if (radeon_encoder->rmx_type == RMX_OFF) { | ||
| 418 | if ((mode->hdisplay != native_mode->hdisplay) || | ||
| 419 | (mode->vdisplay != native_mode->vdisplay)) | ||
| 420 | return MODE_PANEL; | ||
| 421 | } | ||
| 422 | } | ||
| 423 | |||
| 400 | return MODE_OK; | 424 | return MODE_OK; |
| 401 | } | 425 | } |
| 402 | 426 | ||
| @@ -512,6 +536,8 @@ static int radeon_vga_get_modes(struct drm_connector *connector) | |||
| 512 | static int radeon_vga_mode_valid(struct drm_connector *connector, | 536 | static int radeon_vga_mode_valid(struct drm_connector *connector, |
| 513 | struct drm_display_mode *mode) | 537 | struct drm_display_mode *mode) |
| 514 | { | 538 | { |
| 539 | /* XXX check mode bandwidth */ | ||
| 540 | /* XXX verify against max DAC output frequency */ | ||
| 515 | return MODE_OK; | 541 | return MODE_OK; |
| 516 | } | 542 | } |
| 517 | 543 | ||
| @@ -609,6 +635,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector) | |||
| 609 | static int radeon_tv_mode_valid(struct drm_connector *connector, | 635 | static int radeon_tv_mode_valid(struct drm_connector *connector, |
| 610 | struct drm_display_mode *mode) | 636 | struct drm_display_mode *mode) |
| 611 | { | 637 | { |
| 638 | if ((mode->hdisplay > 1024) || (mode->vdisplay > 768)) | ||
| 639 | return MODE_CLOCK_RANGE; | ||
| 612 | return MODE_OK; | 640 | return MODE_OK; |
| 613 | } | 641 | } |
| 614 | 642 | ||
| @@ -801,9 +829,27 @@ static void radeon_dvi_force(struct drm_connector *connector) | |||
| 801 | radeon_connector->use_digital = true; | 829 | radeon_connector->use_digital = true; |
| 802 | } | 830 | } |
| 803 | 831 | ||
| 832 | static int radeon_dvi_mode_valid(struct drm_connector *connector, | ||
| 833 | struct drm_display_mode *mode) | ||
| 834 | { | ||
| 835 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 836 | |||
| 837 | /* XXX check mode bandwidth */ | ||
| 838 | |||
| 839 | if (radeon_connector->use_digital && (mode->clock > 165000)) { | ||
| 840 | if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || | ||
| 841 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || | ||
| 842 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) | ||
| 843 | return MODE_OK; | ||
| 844 | else | ||
| 845 | return MODE_CLOCK_HIGH; | ||
| 846 | } | ||
| 847 | return MODE_OK; | ||
| 848 | } | ||
| 849 | |||
| 804 | struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { | 850 | struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { |
| 805 | .get_modes = radeon_dvi_get_modes, | 851 | .get_modes = radeon_dvi_get_modes, |
| 806 | .mode_valid = radeon_vga_mode_valid, | 852 | .mode_valid = radeon_dvi_mode_valid, |
| 807 | .best_encoder = radeon_dvi_encoder, | 853 | .best_encoder = radeon_dvi_encoder, |
| 808 | }; | 854 | }; |
| 809 | 855 | ||
