diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 2b29084..290b019 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -330,6 +330,9 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, /* get the native mode for LVDS */ if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) radeon_panel_mode_fixup(encoder, adjusted_mode); + else if ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT)) && + (radeon_encoder->rmx_type != RMX_OFF)) + radeon_panel_mode_fixup(encoder, adjusted_mode); /* get the native mode for TV */ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 4483119..b397d16 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -585,6 +585,31 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct radeon_property_change_mode(&radeon_encoder->base); } + if (property == dev->mode_config.scaling_mode_property) { + enum radeon_rmx_type rmx_type; + + if (connector->encoder) + radeon_encoder = to_radeon_encoder(connector->encoder); + else { + struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; + radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); + } + + switch (val) { + case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break; + case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break; + case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break; + default: + case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break; + } + if (radeon_encoder->rmx_type == rmx_type) + return 0; + + radeon_encoder->rmx_type = rmx_type; + + radeon_property_change_mode(&radeon_encoder->base); + } + return 0; } @@ -1001,10 +1026,24 @@ static const struct drm_connector_funcs radeon_tv_connector_funcs = { static int radeon_dvi_get_modes(struct drm_connector *connector) { + struct drm_device *dev = connector->dev; + struct radeon_device *rdev = dev->dev_private; struct radeon_connector *radeon_connector = to_radeon_connector(connector); int ret; ret = radeon_ddc_get_modes(radeon_connector); + + if (!ret && rdev->is_atom_bios) { + struct drm_encoder *encoder = radeon_best_single_encoder(connector); + struct drm_display_mode *preferred_mode = + list_first_entry(&connector->probed_modes, + struct drm_display_mode, head); + if (preferred_mode && encoder) { + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + radeon_encoder->native_mode = *preferred_mode; + } + } + return ret; } @@ -1326,6 +1365,8 @@ static const struct drm_connector_funcs radeon_dvi_connector_funcs = { static int radeon_dp_get_modes(struct drm_connector *connector) { + struct drm_device *dev = connector->dev; + struct radeon_device *rdev = dev->dev_private; struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; struct drm_encoder *encoder = radeon_best_single_encoder(connector); @@ -1384,6 +1425,17 @@ static int radeon_dp_get_modes(struct drm_connector *connector) radeon_atom_ext_encoder_setup_ddc(encoder); } ret = radeon_ddc_get_modes(radeon_connector); + + if (!ret && rdev->is_atom_bios) { + struct drm_encoder *encoder = radeon_best_single_encoder(connector); + struct drm_display_mode *preferred_mode = + list_first_entry(&connector->probed_modes, + struct drm_display_mode, head); + if (preferred_mode && encoder) { + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + radeon_encoder->native_mode = *preferred_mode; + } + } } return ret; @@ -1788,6 +1840,9 @@ radeon_add_atom_connector(struct drm_device *dev, rdev->mode_info.load_detect_property, 1); } + drm_object_attach_property(&radeon_connector->base.base, + dev->mode_config.scaling_mode_property, + DRM_MODE_SCALE_NONE); break; case DRM_MODE_CONNECTOR_LVDS: case DRM_MODE_CONNECTOR_eDP: @@ -1868,6 +1923,9 @@ radeon_add_atom_connector(struct drm_device *dev, drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.underscan_vborder_property, 0); + drm_object_attach_property(&radeon_connector->base.base, + dev->mode_config.scaling_mode_property, + DRM_MODE_SCALE_NONE); } if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) { drm_object_attach_property(&radeon_connector->base.base, @@ -1965,6 +2023,9 @@ radeon_add_atom_connector(struct drm_device *dev, drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.underscan_vborder_property, 0); + drm_object_attach_property(&radeon_connector->base.base, + dev->mode_config.scaling_mode_property, + DRM_MODE_SCALE_NONE); } if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) { drm_object_attach_property(&radeon_connector->base.base,