From 643b1f5629a30f979e2da678ecf0b1855e074a8c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 23 Feb 2015 10:59:36 -0500 Subject: [PATCH] drm/radeon: implement output csc property for DCE5+ Implement the property for DCE5+ asics. Older asics require a slightly more complex process. bug: https://bugs.freedesktop.org/show_bug.cgi?id=83226 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_crtc.c | 6 +++ drivers/gpu/drm/radeon/radeon_connectors.c | 52 ++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_display.c | 2 +- drivers/gpu/drm/radeon/radeon_mode.h | 2 + 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 86807ee91bd1..2d0adb9619ce 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -2069,6 +2069,12 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, radeon_crtc->connector = NULL; return false; } + if (radeon_crtc->encoder) { + struct radeon_encoder *radeon_encoder = + to_radeon_encoder(radeon_crtc->encoder); + + radeon_crtc->output_csc = radeon_encoder->output_csc; + } if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) return false; if (!atombios_crtc_prepare_pll(crtc, adjusted_mode)) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 27def67cb6be..0a371a13da94 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -725,6 +725,30 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct radeon_property_change_mode(&radeon_encoder->base); } + if (property == rdev->mode_info.output_csc_property) { + 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)); + } + + if (radeon_encoder->output_csc == val) + return 0; + + radeon_encoder->output_csc = val; + + if (connector->encoder->crtc) { + struct drm_crtc *crtc = connector->encoder->crtc; + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + + radeon_crtc->output_csc = radeon_encoder->output_csc; + + (*crtc_funcs->load_lut)(crtc); + } + } + return 0; } @@ -1872,6 +1896,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_object_attach_property(&radeon_connector->base.base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_NONE); + if (ASIC_IS_DCE5(rdev)) + drm_object_attach_property(&radeon_connector->base.base, + rdev->mode_info.output_csc_property, + RADEON_OUTPUT_CSC_BYPASS); break; case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVID: @@ -1904,6 +1932,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, RADEON_AUDIO_AUTO); + if (ASIC_IS_DCE5(rdev)) + drm_object_attach_property(&radeon_connector->base.base, + rdev->mode_info.output_csc_property, + RADEON_OUTPUT_CSC_BYPASS); subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = true; @@ -1950,6 +1982,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_object_attach_property(&radeon_connector->base.base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_NONE); + if (ASIC_IS_DCE5(rdev)) + drm_object_attach_property(&radeon_connector->base.base, + rdev->mode_info.output_csc_property, + RADEON_OUTPUT_CSC_BYPASS); /* no HPD on analog connectors */ radeon_connector->hpd.hpd = RADEON_HPD_NONE; connector->polled = DRM_CONNECTOR_POLL_CONNECT; @@ -1972,6 +2008,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_object_attach_property(&radeon_connector->base.base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_NONE); + if (ASIC_IS_DCE5(rdev)) + drm_object_attach_property(&radeon_connector->base.base, + rdev->mode_info.output_csc_property, + RADEON_OUTPUT_CSC_BYPASS); /* no HPD on analog connectors */ radeon_connector->hpd.hpd = RADEON_HPD_NONE; connector->interlace_allowed = true; @@ -2023,6 +2063,10 @@ radeon_add_atom_connector(struct drm_device *dev, rdev->mode_info.load_detect_property, 1); } + if (ASIC_IS_DCE5(rdev)) + drm_object_attach_property(&radeon_connector->base.base, + rdev->mode_info.output_csc_property, + RADEON_OUTPUT_CSC_BYPASS); connector->interlace_allowed = true; if (connector_type == DRM_MODE_CONNECTOR_DVII) connector->doublescan_allowed = true; @@ -2068,6 +2112,10 @@ radeon_add_atom_connector(struct drm_device *dev, rdev->mode_info.audio_property, RADEON_AUDIO_AUTO); } + if (ASIC_IS_DCE5(rdev)) + drm_object_attach_property(&radeon_connector->base.base, + rdev->mode_info.output_csc_property, + RADEON_OUTPUT_CSC_BYPASS); subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = true; if (connector_type == DRM_MODE_CONNECTOR_HDMIB) @@ -2116,6 +2164,10 @@ radeon_add_atom_connector(struct drm_device *dev, rdev->mode_info.audio_property, RADEON_AUDIO_AUTO); } + if (ASIC_IS_DCE5(rdev)) + drm_object_attach_property(&radeon_connector->base.base, + rdev->mode_info.output_csc_property, + RADEON_OUTPUT_CSC_BYPASS); connector->interlace_allowed = true; /* in theory with a DP to VGA converter... */ connector->doublescan_allowed = false; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index d57dfb954257..d2e9e9efc159 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -154,7 +154,7 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc) (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) | NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS))); WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset, - (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) | + (NI_OUTPUT_CSC_GRPH_MODE(radeon_crtc->output_csc) | NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS))); /* XXX match this to the depth of the crtc fmt block, move to modeset? */ WREG32(0x6940 + radeon_crtc->crtc_offset, 0); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 67d4f776147d..664825c01aa6 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -366,6 +366,7 @@ struct radeon_crtc { u32 wm_low; u32 wm_high; struct drm_display_mode hw_mode; + enum radeon_output_csc output_csc; }; struct radeon_encoder_primary_dac { @@ -459,6 +460,7 @@ struct radeon_encoder { bool is_ext_encoder; u16 caps; struct radeon_audio_funcs *audio; + enum radeon_output_csc output_csc; }; struct radeon_connector_atom_dig {