diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 99 |
1 files changed, 85 insertions, 14 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 12ad512bd3d..464a81a1990 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -332,6 +332,11 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, | |||
332 | args.usV_SyncWidth = | 332 | args.usV_SyncWidth = |
333 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); | 333 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
334 | 334 | ||
335 | args.ucOverscanRight = radeon_crtc->h_border; | ||
336 | args.ucOverscanLeft = radeon_crtc->h_border; | ||
337 | args.ucOverscanBottom = radeon_crtc->v_border; | ||
338 | args.ucOverscanTop = radeon_crtc->v_border; | ||
339 | |||
335 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | 340 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
336 | misc |= ATOM_VSYNC_POLARITY; | 341 | misc |= ATOM_VSYNC_POLARITY; |
337 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | 342 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
@@ -471,6 +476,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
471 | struct radeon_encoder *radeon_encoder = NULL; | 476 | struct radeon_encoder *radeon_encoder = NULL; |
472 | u32 adjusted_clock = mode->clock; | 477 | u32 adjusted_clock = mode->clock; |
473 | int encoder_mode = 0; | 478 | int encoder_mode = 0; |
479 | u32 dp_clock = mode->clock; | ||
480 | int bpc = 8; | ||
474 | 481 | ||
475 | /* reset the pll flags */ | 482 | /* reset the pll flags */ |
476 | pll->flags = 0; | 483 | pll->flags = 0; |
@@ -513,6 +520,17 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
513 | if (encoder->crtc == crtc) { | 520 | if (encoder->crtc == crtc) { |
514 | radeon_encoder = to_radeon_encoder(encoder); | 521 | radeon_encoder = to_radeon_encoder(encoder); |
515 | encoder_mode = atombios_get_encoder_mode(encoder); | 522 | encoder_mode = atombios_get_encoder_mode(encoder); |
523 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { | ||
524 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
525 | if (connector) { | ||
526 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
527 | struct radeon_connector_atom_dig *dig_connector = | ||
528 | radeon_connector->con_priv; | ||
529 | |||
530 | dp_clock = dig_connector->dp_clock; | ||
531 | } | ||
532 | } | ||
533 | |||
516 | if (ASIC_IS_AVIVO(rdev)) { | 534 | if (ASIC_IS_AVIVO(rdev)) { |
517 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 535 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
518 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 536 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
@@ -521,6 +539,20 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
521 | pll->algo = PLL_ALGO_LEGACY; | 539 | pll->algo = PLL_ALGO_LEGACY; |
522 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; | 540 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; |
523 | } | 541 | } |
542 | /* There is some evidence (often anecdotal) that RV515 LVDS | ||
543 | * (on some boards at least) prefers the legacy algo. I'm not | ||
544 | * sure whether this should handled generically or on a | ||
545 | * case-by-case quirk basis. Both algos should work fine in the | ||
546 | * majority of cases. | ||
547 | */ | ||
548 | if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) && | ||
549 | (rdev->family == CHIP_RV515)) { | ||
550 | /* allow the user to overrride just in case */ | ||
551 | if (radeon_new_pll == 1) | ||
552 | pll->algo = PLL_ALGO_NEW; | ||
553 | else | ||
554 | pll->algo = PLL_ALGO_LEGACY; | ||
555 | } | ||
524 | } else { | 556 | } else { |
525 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 557 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
526 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; | 558 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; |
@@ -555,6 +587,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
555 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 587 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
556 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; | 588 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
557 | args.v1.ucEncodeMode = encoder_mode; | 589 | args.v1.ucEncodeMode = encoder_mode; |
590 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { | ||
591 | /* may want to enable SS on DP eventually */ | ||
592 | /* args.v1.ucConfig |= | ||
593 | ADJUST_DISPLAY_CONFIG_SS_ENABLE;*/ | ||
594 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
595 | args.v1.ucConfig |= | ||
596 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; | ||
597 | } | ||
558 | 598 | ||
559 | atom_execute_table(rdev->mode_info.atom_context, | 599 | atom_execute_table(rdev->mode_info.atom_context, |
560 | index, (uint32_t *)&args); | 600 | index, (uint32_t *)&args); |
@@ -568,10 +608,20 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
568 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 608 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
569 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 609 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
570 | 610 | ||
571 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 611 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
612 | /* may want to enable SS on DP/eDP eventually */ | ||
613 | /*args.v3.sInput.ucDispPllConfig |= | ||
614 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
572 | args.v3.sInput.ucDispPllConfig |= | 615 | args.v3.sInput.ucDispPllConfig |= |
573 | DISPPLL_CONFIG_COHERENT_MODE; | 616 | DISPPLL_CONFIG_COHERENT_MODE; |
574 | else { | 617 | /* 16200 or 27000 */ |
618 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
619 | } else { | ||
620 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) { | ||
621 | /* deep color support */ | ||
622 | args.v3.sInput.usPixelClock = | ||
623 | cpu_to_le16((mode->clock * bpc / 8) / 10); | ||
624 | } | ||
575 | if (dig->coherent_mode) | 625 | if (dig->coherent_mode) |
576 | args.v3.sInput.ucDispPllConfig |= | 626 | args.v3.sInput.ucDispPllConfig |= |
577 | DISPPLL_CONFIG_COHERENT_MODE; | 627 | DISPPLL_CONFIG_COHERENT_MODE; |
@@ -580,13 +630,19 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
580 | DISPPLL_CONFIG_DUAL_LINK; | 630 | DISPPLL_CONFIG_DUAL_LINK; |
581 | } | 631 | } |
582 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 632 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
583 | /* may want to enable SS on DP/eDP eventually */ | 633 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
584 | /*args.v3.sInput.ucDispPllConfig |= | 634 | /* may want to enable SS on DP/eDP eventually */ |
585 | DISPPLL_CONFIG_SS_ENABLE;*/ | 635 | /*args.v3.sInput.ucDispPllConfig |= |
586 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 636 | DISPPLL_CONFIG_SS_ENABLE;*/ |
587 | args.v3.sInput.ucDispPllConfig |= | 637 | args.v3.sInput.ucDispPllConfig |= |
588 | DISPPLL_CONFIG_COHERENT_MODE; | 638 | DISPPLL_CONFIG_COHERENT_MODE; |
589 | else { | 639 | /* 16200 or 27000 */ |
640 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
641 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
642 | /* want to enable SS on LVDS eventually */ | ||
643 | /*args.v3.sInput.ucDispPllConfig |= | ||
644 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
645 | } else { | ||
590 | if (mode->clock > 165000) | 646 | if (mode->clock > 165000) |
591 | args.v3.sInput.ucDispPllConfig |= | 647 | args.v3.sInput.ucDispPllConfig |= |
592 | DISPPLL_CONFIG_DUAL_LINK; | 648 | DISPPLL_CONFIG_DUAL_LINK; |
@@ -1019,11 +1075,11 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1019 | 1075 | ||
1020 | if (rdev->family >= CHIP_RV770) { | 1076 | if (rdev->family >= CHIP_RV770) { |
1021 | if (radeon_crtc->crtc_id) { | 1077 | if (radeon_crtc->crtc_id) { |
1022 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | 1078 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1023 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | 1079 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1024 | } else { | 1080 | } else { |
1025 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | 1081 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1026 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | 1082 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1027 | } | 1083 | } |
1028 | } | 1084 | } |
1029 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | 1085 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
@@ -1160,8 +1216,18 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1160 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1216 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1161 | struct drm_device *dev = crtc->dev; | 1217 | struct drm_device *dev = crtc->dev; |
1162 | struct radeon_device *rdev = dev->dev_private; | 1218 | struct radeon_device *rdev = dev->dev_private; |
1219 | struct drm_encoder *encoder; | ||
1220 | bool is_tvcv = false; | ||
1163 | 1221 | ||
1164 | /* TODO color tiling */ | 1222 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1223 | /* find tv std */ | ||
1224 | if (encoder->crtc == crtc) { | ||
1225 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1226 | if (radeon_encoder->active_device & | ||
1227 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
1228 | is_tvcv = true; | ||
1229 | } | ||
1230 | } | ||
1165 | 1231 | ||
1166 | atombios_disable_ss(crtc); | 1232 | atombios_disable_ss(crtc); |
1167 | /* always set DCPLL */ | 1233 | /* always set DCPLL */ |
@@ -1170,9 +1236,14 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1170 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1236 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1171 | atombios_enable_ss(crtc); | 1237 | atombios_enable_ss(crtc); |
1172 | 1238 | ||
1173 | if (ASIC_IS_AVIVO(rdev)) | 1239 | if (ASIC_IS_DCE4(rdev)) |
1174 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1240 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
1175 | else { | 1241 | else if (ASIC_IS_AVIVO(rdev)) { |
1242 | if (is_tvcv) | ||
1243 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
1244 | else | ||
1245 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | ||
1246 | } else { | ||
1176 | atombios_crtc_set_timing(crtc, adjusted_mode); | 1247 | atombios_crtc_set_timing(crtc, adjusted_mode); |
1177 | if (radeon_crtc->crtc_id == 0) | 1248 | if (radeon_crtc->crtc_id == 0) |
1178 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1249 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |