drm/radeon: add a connector property for dither
Allows you to enable dither in the display hardware when the monitor supports lower a lower bpc than the current framebuffer format. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Родитель
134b480f4b
Коммит
6214bb7487
|
@ -7427,10 +7427,13 @@ void dce8_program_fmt(struct drm_encoder *encoder)
|
|||
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)
|
||||
|
@ -7446,7 +7449,7 @@ void dce8_program_fmt(struct drm_encoder *encoder)
|
|||
|
||||
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));
|
||||
|
@ -7454,7 +7457,7 @@ void dce8_program_fmt(struct drm_encoder *encoder)
|
|||
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 |
|
||||
|
@ -7463,7 +7466,7 @@ void dce8_program_fmt(struct drm_encoder *encoder)
|
|||
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 |
|
||||
|
|
|
@ -1202,10 +1202,13 @@ void dce4_program_fmt(struct drm_encoder *encoder)
|
|||
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)
|
||||
|
@ -1221,7 +1224,7 @@ void dce4_program_fmt(struct drm_encoder *encoder)
|
|||
|
||||
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);
|
||||
|
@ -1229,7 +1232,7 @@ void dce4_program_fmt(struct drm_encoder *encoder)
|
|||
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 |
|
||||
|
|
|
@ -133,10 +133,13 @@ void dce3_program_fmt(struct drm_encoder *encoder)
|
|||
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)
|
||||
|
@ -152,14 +155,14 @@ void dce3_program_fmt(struct drm_encoder *encoder)
|
|||
|
||||
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
|
||||
|
|
|
@ -411,6 +411,21 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -1661,6 +1676,9 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
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)
|
||||
|
@ -1759,6 +1777,11 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
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,
|
||||
|
@ -1804,6 +1827,11 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
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)
|
||||
|
@ -1848,6 +1876,11 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
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;
|
||||
|
|
|
@ -1178,6 +1178,12 @@ static struct drm_prop_enum_list radeon_audio_enum_list[] =
|
|||
{ 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;
|
||||
|
@ -1234,6 +1240,12 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)
|
|||
"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;
|
||||
}
|
||||
|
||||
|
|
|
@ -249,6 +249,8 @@ struct radeon_mode_info {
|
|||
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;
|
||||
|
@ -479,6 +481,11 @@ enum radeon_connector_audio {
|
|||
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;
|
||||
|
@ -498,6 +505,7 @@ struct radeon_connector {
|
|||
struct radeon_router router;
|
||||
struct radeon_i2c_chan *router_bus;
|
||||
enum radeon_connector_audio audio;
|
||||
enum radeon_connector_dither dither;
|
||||
};
|
||||
|
||||
struct radeon_framebuffer {
|
||||
|
|
|
@ -161,10 +161,13 @@ void avivo_program_fmt(struct drm_encoder *encoder)
|
|||
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)
|
||||
|
@ -175,14 +178,14 @@ void avivo_program_fmt(struct drm_encoder *encoder)
|
|||
|
||||
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче