drm/radeon: Add support for programming the FMT blocks
The FMT blocks control how data is sent from the backend of the display pipe to to monitor. Proper set up of the FMT blocks are required for 30bpp formats. Additionally, dithering can be enabled on for better display with 18 and 24bpp displays. The exception is LVDS/eDP which atom takes care of in the SelectCRTC_Source table. For now just enable truncation until we test dithering more. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -153,6 +153,67 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
|
||||
return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING;
|
||||
}
|
||||
|
||||
void avivo_program_fmt(struct drm_encoder *encoder)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
|
||||
int bpc = 0;
|
||||
u32 tmp = 0;
|
||||
bool dither = false;
|
||||
|
||||
if (connector)
|
||||
bpc = radeon_get_monitor_bpc(connector);
|
||||
|
||||
/* LVDS FMT is set up by atom */
|
||||
if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
|
||||
return;
|
||||
|
||||
if (bpc == 0)
|
||||
return;
|
||||
|
||||
switch (bpc) {
|
||||
case 6:
|
||||
if (dither)
|
||||
/* 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)
|
||||
/* XXX sort out optimal dither settings */
|
||||
tmp |= (AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN |
|
||||
AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH);
|
||||
else
|
||||
tmp |= (AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_EN |
|
||||
AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_DEPTH);
|
||||
break;
|
||||
case 10:
|
||||
default:
|
||||
/* not needed */
|
||||
break;
|
||||
}
|
||||
|
||||
switch (radeon_encoder->encoder_id) {
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
||||
WREG32(AVIVO_TMDSA_BIT_DEPTH_CONTROL, tmp);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
||||
WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, tmp);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||
WREG32(AVIVO_DVOA_BIT_DEPTH_CONTROL, tmp);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_DDI:
|
||||
WREG32(AVIVO_DDIA_BIT_DEPTH_CONTROL, tmp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rs600_pm_misc(struct radeon_device *rdev)
|
||||
{
|
||||
int requested_index = rdev->pm.requested_power_state_index;
|
||||
|
Reference in New Issue
Block a user