struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
int bpc = 0;
u32 tmp = 0;
- bool dither = false;
+ enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
- if (connector)
+ if (connector) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
bpc = radeon_get_monitor_bpc(connector);
+ dither = radeon_connector->dither;
+ }
/* LVDS/eDP FMT is set up by atom */
if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
switch (bpc) {
case 6:
- if (dither)
+ if (dither == RADEON_FMT_DITHER_ENABLE)
/* XXX sort out optimal dither settings */
tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(0));
tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(0));
break;
case 8:
- if (dither)
+ if (dither == RADEON_FMT_DITHER_ENABLE)
/* XXX sort out optimal dither settings */
tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
FMT_RGB_RANDOM_ENABLE |
tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(1));
break;
case 10:
- if (dither)
+ if (dither == RADEON_FMT_DITHER_ENABLE)
/* XXX sort out optimal dither settings */
tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
FMT_RGB_RANDOM_ENABLE |
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
int bpc = 0;
u32 tmp = 0;
- bool dither = false;
+ enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
- if (connector)
+ if (connector) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
bpc = radeon_get_monitor_bpc(connector);
+ dither = radeon_connector->dither;
+ }
/* LVDS/eDP FMT is set up by atom */
if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
switch (bpc) {
case 6:
- if (dither)
+ if (dither == RADEON_FMT_DITHER_ENABLE)
/* XXX sort out optimal dither settings */
tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
FMT_SPATIAL_DITHER_EN);
tmp |= FMT_TRUNCATE_EN;
break;
case 8:
- if (dither)
+ if (dither == RADEON_FMT_DITHER_ENABLE)
/* XXX sort out optimal dither settings */
tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
FMT_RGB_RANDOM_ENABLE |
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
int bpc = 0;
u32 tmp = 0;
- bool dither = false;
+ enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
- if (connector)
+ if (connector) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
bpc = radeon_get_monitor_bpc(connector);
+ dither = radeon_connector->dither;
+ }
/* LVDS FMT is set up by atom */
if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
switch (bpc) {
case 6:
- if (dither)
+ if (dither == RADEON_FMT_DITHER_ENABLE)
/* XXX sort out optimal dither settings */
tmp |= FMT_SPATIAL_DITHER_EN;
else
tmp |= FMT_TRUNCATE_EN;
break;
case 8:
- if (dither)
+ if (dither == RADEON_FMT_DITHER_ENABLE)
/* XXX sort out optimal dither settings */
tmp |= (FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH);
else
}
}
+ if (property == rdev->mode_info.dither_property) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ /* need to find digital encoder on connector */
+ encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
+ if (!encoder)
+ return 0;
+
+ radeon_encoder = to_radeon_encoder(encoder);
+
+ if (radeon_connector->dither != val) {
+ radeon_connector->dither = val;
+ radeon_property_change_mode(&radeon_encoder->base);
+ }
+ }
+
if (property == rdev->mode_info.underscan_property) {
/* need to find digital encoder on connector */
encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE);
+ drm_object_attach_property(&radeon_connector->base.base,
+ rdev->mode_info.dither_property,
+ RADEON_FMT_DITHER_DISABLE);
subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true;
if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE);
}
+ if (ASIC_IS_AVIVO(rdev)) {
+ drm_object_attach_property(&radeon_connector->base.base,
+ rdev->mode_info.dither_property,
+ RADEON_FMT_DITHER_DISABLE);
+ }
if (connector_type == DRM_MODE_CONNECTOR_DVII) {
radeon_connector->dac_load_detect = true;
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE);
}
+ if (ASIC_IS_AVIVO(rdev)) {
+ drm_object_attach_property(&radeon_connector->base.base,
+ rdev->mode_info.dither_property,
+ RADEON_FMT_DITHER_DISABLE);
+ }
subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true;
if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE);
}
+ if (ASIC_IS_AVIVO(rdev)) {
+ drm_object_attach_property(&radeon_connector->base.base,
+ rdev->mode_info.dither_property,
+ RADEON_FMT_DITHER_DISABLE);
+ }
connector->interlace_allowed = true;
/* in theory with a DP to VGA converter... */
connector->doublescan_allowed = false;
{ RADEON_AUDIO_AUTO, "auto" },
};
+/* XXX support different dither options? spatial, temporal, both, etc. */
+static struct drm_prop_enum_list radeon_dither_enum_list[] =
+{ { RADEON_FMT_DITHER_DISABLE, "off" },
+ { RADEON_FMT_DITHER_ENABLE, "on" },
+};
+
static int radeon_modeset_create_props(struct radeon_device *rdev)
{
int sz;
"audio",
radeon_audio_enum_list, sz);
+ sz = ARRAY_SIZE(radeon_dither_enum_list);
+ rdev->mode_info.dither_property =
+ drm_property_create_enum(rdev->ddev, 0,
+ "dither",
+ radeon_dither_enum_list, sz);
+
return 0;
}
struct drm_property *underscan_vborder_property;
/* audio */
struct drm_property *audio_property;
+ /* FMT dithering */
+ struct drm_property *dither_property;
/* hardcoded DFP edid from BIOS */
struct edid *bios_hardcoded_edid;
int bios_hardcoded_edid_size;
RADEON_AUDIO_AUTO = 2
};
+enum radeon_connector_dither {
+ RADEON_FMT_DITHER_DISABLE = 0,
+ RADEON_FMT_DITHER_ENABLE = 1,
+};
+
struct radeon_connector {
struct drm_connector base;
uint32_t connector_id;
struct radeon_router router;
struct radeon_i2c_chan *router_bus;
enum radeon_connector_audio audio;
+ enum radeon_connector_dither dither;
};
struct radeon_framebuffer {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
int bpc = 0;
u32 tmp = 0;
- bool dither = false;
+ enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
- if (connector)
+ if (connector) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
bpc = radeon_get_monitor_bpc(connector);
+ dither = radeon_connector->dither;
+ }
/* LVDS FMT is set up by atom */
if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
switch (bpc) {
case 6:
- if (dither)
+ if (dither == RADEON_FMT_DITHER_ENABLE)
/* XXX sort out optimal dither settings */
tmp |= AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN;
else
tmp |= AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_EN;
break;
case 8:
- if (dither)
+ if (dither == RADEON_FMT_DITHER_ENABLE)
/* XXX sort out optimal dither settings */
tmp |= (AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN |
AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH);