From 4e02c92f043bd68b6746b2cf8d2291974593b453 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 20 Jan 2010 15:18:01 -0500 Subject: [PATCH] drm/radeon/kms/evergreen: add support for atom AdjustDisplayPll table Used to adjust the pixel clock and parameters before setting the pll. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_crtc.c | 34 +++++++++++++++++++++++++++++++- 1 files changed, 33 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 31cbbf8..1cb1c0a 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -415,6 +415,7 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) union adjust_pixel_clock { ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; + ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3; }; static u32 atombios_adjust_pll(struct drm_crtc *crtc, @@ -426,6 +427,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, struct drm_encoder *encoder = NULL; struct radeon_encoder *radeon_encoder = NULL; u32 adjusted_clock = mode->clock; + int encoder_mode = 0; /* reset the pll flags */ pll->flags = 0; @@ -463,6 +465,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->crtc == crtc) { radeon_encoder = to_radeon_encoder(encoder); + encoder_mode = atombios_get_encoder_mode(encoder); if (ASIC_IS_AVIVO(rdev)) { /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) @@ -509,12 +512,41 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, case 2: args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); args.v1.ucTransmitterID = radeon_encoder->encoder_id; - args.v1.ucEncodeMode = atombios_get_encoder_mode(encoder); + args.v1.ucEncodeMode = encoder_mode; atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10; break; + case 3: + args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10); + args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; + args.v3.sInput.ucEncodeMode = encoder_mode; + args.v3.sInput.ucDispPllConfig = 0; + if (encoder_mode == ATOM_ENCODER_MODE_DP) + args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_COHERENT_MODE; + else { + if (dig->coherent_mode) + args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_COHERENT_MODE; + if (mode->clock > 165000) + args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK; + } + /* may want to enable SS on DP/eDP eventually */ + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE; + + atom_execute_table(rdev->mode_info.atom_context, + index, (uint32_t *)&args); + adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; + if (args.v3.sOutput.ucRefDiv) { + pll->flags |= RADEON_PLL_USE_REF_DIV; + pll->reference_div = args.v3.sOutput.ucRefDiv; + } + if (args.v3.sOutput.ucPostDiv) { + pll->flags |= RADEON_PLL_USE_POST_DIV; + pll->post_div = args.v3.sOutput.ucPostDiv; + } + break; default: DRM_ERROR("Unknown table version %d %d\n", frev, crev); return adjusted_clock; -- 1.5.6.3