aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/atombios_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c456
1 files changed, 390 insertions, 66 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index af464e351fbd..dd9fdf560611 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -245,21 +245,25 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
245 245
246 switch (mode) { 246 switch (mode) {
247 case DRM_MODE_DPMS_ON: 247 case DRM_MODE_DPMS_ON:
248 atombios_enable_crtc(crtc, 1); 248 atombios_enable_crtc(crtc, ATOM_ENABLE);
249 if (ASIC_IS_DCE3(rdev)) 249 if (ASIC_IS_DCE3(rdev))
250 atombios_enable_crtc_memreq(crtc, 1); 250 atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
251 atombios_blank_crtc(crtc, 0); 251 atombios_blank_crtc(crtc, ATOM_DISABLE);
252 drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); 252 /* XXX re-enable when interrupt support is added */
253 if (!ASIC_IS_DCE4(rdev))
254 drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
253 radeon_crtc_load_lut(crtc); 255 radeon_crtc_load_lut(crtc);
254 break; 256 break;
255 case DRM_MODE_DPMS_STANDBY: 257 case DRM_MODE_DPMS_STANDBY:
256 case DRM_MODE_DPMS_SUSPEND: 258 case DRM_MODE_DPMS_SUSPEND:
257 case DRM_MODE_DPMS_OFF: 259 case DRM_MODE_DPMS_OFF:
258 drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); 260 /* XXX re-enable when interrupt support is added */
259 atombios_blank_crtc(crtc, 1); 261 if (!ASIC_IS_DCE4(rdev))
262 drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
263 atombios_blank_crtc(crtc, ATOM_ENABLE);
260 if (ASIC_IS_DCE3(rdev)) 264 if (ASIC_IS_DCE3(rdev))
261 atombios_enable_crtc_memreq(crtc, 0); 265 atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
262 atombios_enable_crtc(crtc, 0); 266 atombios_enable_crtc(crtc, ATOM_DISABLE);
263 break; 267 break;
264 } 268 }
265} 269}
@@ -349,6 +353,11 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
349 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 353 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
350} 354}
351 355
356union atom_enable_ss {
357 ENABLE_LVDS_SS_PARAMETERS legacy;
358 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
359};
360
352static void atombios_set_ss(struct drm_crtc *crtc, int enable) 361static void atombios_set_ss(struct drm_crtc *crtc, int enable)
353{ 362{
354 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 363 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
@@ -358,11 +367,14 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
358 struct radeon_encoder *radeon_encoder = NULL; 367 struct radeon_encoder *radeon_encoder = NULL;
359 struct radeon_encoder_atom_dig *dig = NULL; 368 struct radeon_encoder_atom_dig *dig = NULL;
360 int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); 369 int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
361 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION args; 370 union atom_enable_ss args;
362 ENABLE_LVDS_SS_PARAMETERS legacy_args;
363 uint16_t percentage = 0; 371 uint16_t percentage = 0;
364 uint8_t type = 0, step = 0, delay = 0, range = 0; 372 uint8_t type = 0, step = 0, delay = 0, range = 0;
365 373
374 /* XXX add ss support for DCE4 */
375 if (ASIC_IS_DCE4(rdev))
376 return;
377
366 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 378 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
367 if (encoder->crtc == crtc) { 379 if (encoder->crtc == crtc) {
368 radeon_encoder = to_radeon_encoder(encoder); 380 radeon_encoder = to_radeon_encoder(encoder);
@@ -386,29 +398,28 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
386 if (!radeon_encoder) 398 if (!radeon_encoder)
387 return; 399 return;
388 400
401 memset(&args, 0, sizeof(args));
389 if (ASIC_IS_AVIVO(rdev)) { 402 if (ASIC_IS_AVIVO(rdev)) {
390 memset(&args, 0, sizeof(args)); 403 args.v1.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
391 args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); 404 args.v1.ucSpreadSpectrumType = type;
392 args.ucSpreadSpectrumType = type; 405 args.v1.ucSpreadSpectrumStep = step;
393 args.ucSpreadSpectrumStep = step; 406 args.v1.ucSpreadSpectrumDelay = delay;
394 args.ucSpreadSpectrumDelay = delay; 407 args.v1.ucSpreadSpectrumRange = range;
395 args.ucSpreadSpectrumRange = range; 408 args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
396 args.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 409 args.v1.ucEnable = enable;
397 args.ucEnable = enable;
398 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
399 } else { 410 } else {
400 memset(&legacy_args, 0, sizeof(legacy_args)); 411 args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
401 legacy_args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); 412 args.legacy.ucSpreadSpectrumType = type;
402 legacy_args.ucSpreadSpectrumType = type; 413 args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
403 legacy_args.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; 414 args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
404 legacy_args.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; 415 args.legacy.ucEnable = enable;
405 legacy_args.ucEnable = enable;
406 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&legacy_args);
407 } 416 }
417 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
408} 418}
409 419
410union adjust_pixel_clock { 420union adjust_pixel_clock {
411 ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; 421 ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
422 ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
412}; 423};
413 424
414static u32 atombios_adjust_pll(struct drm_crtc *crtc, 425static u32 atombios_adjust_pll(struct drm_crtc *crtc,
@@ -420,10 +431,24 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
420 struct drm_encoder *encoder = NULL; 431 struct drm_encoder *encoder = NULL;
421 struct radeon_encoder *radeon_encoder = NULL; 432 struct radeon_encoder *radeon_encoder = NULL;
422 u32 adjusted_clock = mode->clock; 433 u32 adjusted_clock = mode->clock;
434 int encoder_mode = 0;
423 435
424 /* reset the pll flags */ 436 /* reset the pll flags */
425 pll->flags = 0; 437 pll->flags = 0;
426 438
439 /* select the PLL algo */
440 if (ASIC_IS_AVIVO(rdev)) {
441 if (radeon_new_pll == 0)
442 pll->algo = PLL_ALGO_LEGACY;
443 else
444 pll->algo = PLL_ALGO_NEW;
445 } else {
446 if (radeon_new_pll == 1)
447 pll->algo = PLL_ALGO_NEW;
448 else
449 pll->algo = PLL_ALGO_LEGACY;
450 }
451
427 if (ASIC_IS_AVIVO(rdev)) { 452 if (ASIC_IS_AVIVO(rdev)) {
428 if ((rdev->family == CHIP_RS600) || 453 if ((rdev->family == CHIP_RS600) ||
429 (rdev->family == CHIP_RS690) || 454 (rdev->family == CHIP_RS690) ||
@@ -448,10 +473,16 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
448 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 473 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
449 if (encoder->crtc == crtc) { 474 if (encoder->crtc == crtc) {
450 radeon_encoder = to_radeon_encoder(encoder); 475 radeon_encoder = to_radeon_encoder(encoder);
476 encoder_mode = atombios_get_encoder_mode(encoder);
451 if (ASIC_IS_AVIVO(rdev)) { 477 if (ASIC_IS_AVIVO(rdev)) {
452 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ 478 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
453 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) 479 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
454 adjusted_clock = mode->clock * 2; 480 adjusted_clock = mode->clock * 2;
481 /* LVDS PLL quirks */
482 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
483 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
484 pll->algo = dig->pll_algo;
485 }
455 } else { 486 } else {
456 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) 487 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
457 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; 488 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
@@ -468,14 +499,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
468 */ 499 */
469 if (ASIC_IS_DCE3(rdev)) { 500 if (ASIC_IS_DCE3(rdev)) {
470 union adjust_pixel_clock args; 501 union adjust_pixel_clock args;
471 struct radeon_encoder_atom_dig *dig;
472 u8 frev, crev; 502 u8 frev, crev;
473 int index; 503 int index;
474 504
475 if (!radeon_encoder->enc_priv)
476 return adjusted_clock;
477 dig = radeon_encoder->enc_priv;
478
479 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); 505 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
480 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 506 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
481 &crev); 507 &crev);
@@ -489,12 +515,51 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
489 case 2: 515 case 2:
490 args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); 516 args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
491 args.v1.ucTransmitterID = radeon_encoder->encoder_id; 517 args.v1.ucTransmitterID = radeon_encoder->encoder_id;
492 args.v1.ucEncodeMode = atombios_get_encoder_mode(encoder); 518 args.v1.ucEncodeMode = encoder_mode;
493 519
494 atom_execute_table(rdev->mode_info.atom_context, 520 atom_execute_table(rdev->mode_info.atom_context,
495 index, (uint32_t *)&args); 521 index, (uint32_t *)&args);
496 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10; 522 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
497 break; 523 break;
524 case 3:
525 args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10);
526 args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
527 args.v3.sInput.ucEncodeMode = encoder_mode;
528 args.v3.sInput.ucDispPllConfig = 0;
529 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
530 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
531
532 if (encoder_mode == ATOM_ENCODER_MODE_DP)
533 args.v3.sInput.ucDispPllConfig |=
534 DISPPLL_CONFIG_COHERENT_MODE;
535 else {
536 if (dig->coherent_mode)
537 args.v3.sInput.ucDispPllConfig |=
538 DISPPLL_CONFIG_COHERENT_MODE;
539 if (mode->clock > 165000)
540 args.v3.sInput.ucDispPllConfig |=
541 DISPPLL_CONFIG_DUAL_LINK;
542 }
543 } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
544 /* may want to enable SS on DP/eDP eventually */
545 args.v3.sInput.ucDispPllConfig |=
546 DISPPLL_CONFIG_SS_ENABLE;
547 if (mode->clock > 165000)
548 args.v3.sInput.ucDispPllConfig |=
549 DISPPLL_CONFIG_DUAL_LINK;
550 }
551 atom_execute_table(rdev->mode_info.atom_context,
552 index, (uint32_t *)&args);
553 adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
554 if (args.v3.sOutput.ucRefDiv) {
555 pll->flags |= RADEON_PLL_USE_REF_DIV;
556 pll->reference_div = args.v3.sOutput.ucRefDiv;
557 }
558 if (args.v3.sOutput.ucPostDiv) {
559 pll->flags |= RADEON_PLL_USE_POST_DIV;
560 pll->post_div = args.v3.sOutput.ucPostDiv;
561 }
562 break;
498 default: 563 default:
499 DRM_ERROR("Unknown table version %d %d\n", frev, crev); 564 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
500 return adjusted_clock; 565 return adjusted_clock;
@@ -513,9 +578,47 @@ union set_pixel_clock {
513 PIXEL_CLOCK_PARAMETERS v1; 578 PIXEL_CLOCK_PARAMETERS v1;
514 PIXEL_CLOCK_PARAMETERS_V2 v2; 579 PIXEL_CLOCK_PARAMETERS_V2 v2;
515 PIXEL_CLOCK_PARAMETERS_V3 v3; 580 PIXEL_CLOCK_PARAMETERS_V3 v3;
581 PIXEL_CLOCK_PARAMETERS_V5 v5;
516}; 582};
517 583
518void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) 584static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
585{
586 struct drm_device *dev = crtc->dev;
587 struct radeon_device *rdev = dev->dev_private;
588 u8 frev, crev;
589 int index;
590 union set_pixel_clock args;
591
592 memset(&args, 0, sizeof(args));
593
594 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
595 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
596 &crev);
597
598 switch (frev) {
599 case 1:
600 switch (crev) {
601 case 5:
602 /* if the default dcpll clock is specified,
603 * SetPixelClock provides the dividers
604 */
605 args.v5.ucCRTC = ATOM_CRTC_INVALID;
606 args.v5.usPixelClock = rdev->clock.default_dispclk;
607 args.v5.ucPpll = ATOM_DCPLL;
608 break;
609 default:
610 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
611 return;
612 }
613 break;
614 default:
615 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
616 return;
617 }
618 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
619}
620
621static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
519{ 622{
520 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 623 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
521 struct drm_device *dev = crtc->dev; 624 struct drm_device *dev = crtc->dev;
@@ -529,12 +632,14 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
529 u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; 632 u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
530 struct radeon_pll *pll; 633 struct radeon_pll *pll;
531 u32 adjusted_clock; 634 u32 adjusted_clock;
635 int encoder_mode = 0;
532 636
533 memset(&args, 0, sizeof(args)); 637 memset(&args, 0, sizeof(args));
534 638
535 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 639 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
536 if (encoder->crtc == crtc) { 640 if (encoder->crtc == crtc) {
537 radeon_encoder = to_radeon_encoder(encoder); 641 radeon_encoder = to_radeon_encoder(encoder);
642 encoder_mode = atombios_get_encoder_mode(encoder);
538 break; 643 break;
539 } 644 }
540 } 645 }
@@ -542,26 +647,24 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
542 if (!radeon_encoder) 647 if (!radeon_encoder)
543 return; 648 return;
544 649
545 if (radeon_crtc->crtc_id == 0) 650 switch (radeon_crtc->pll_id) {
651 case ATOM_PPLL1:
546 pll = &rdev->clock.p1pll; 652 pll = &rdev->clock.p1pll;
547 else 653 break;
654 case ATOM_PPLL2:
548 pll = &rdev->clock.p2pll; 655 pll = &rdev->clock.p2pll;
656 break;
657 case ATOM_DCPLL:
658 case ATOM_PPLL_INVALID:
659 pll = &rdev->clock.dcpll;
660 break;
661 }
549 662
550 /* adjust pixel clock as needed */ 663 /* adjust pixel clock as needed */
551 adjusted_clock = atombios_adjust_pll(crtc, mode, pll); 664 adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
552 665
553 if (ASIC_IS_AVIVO(rdev)) { 666 radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
554 if (radeon_new_pll) 667 &ref_div, &post_div);
555 radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
556 &fb_div, &frac_fb_div,
557 &ref_div, &post_div);
558 else
559 radeon_compute_pll(pll, adjusted_clock, &pll_clock,
560 &fb_div, &frac_fb_div,
561 &ref_div, &post_div);
562 } else
563 radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
564 &ref_div, &post_div);
565 668
566 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); 669 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
567 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 670 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
@@ -576,8 +679,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
576 args.v1.usFbDiv = cpu_to_le16(fb_div); 679 args.v1.usFbDiv = cpu_to_le16(fb_div);
577 args.v1.ucFracFbDiv = frac_fb_div; 680 args.v1.ucFracFbDiv = frac_fb_div;
578 args.v1.ucPostDiv = post_div; 681 args.v1.ucPostDiv = post_div;
579 args.v1.ucPpll = 682 args.v1.ucPpll = radeon_crtc->pll_id;
580 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
581 args.v1.ucCRTC = radeon_crtc->crtc_id; 683 args.v1.ucCRTC = radeon_crtc->crtc_id;
582 args.v1.ucRefDivSrc = 1; 684 args.v1.ucRefDivSrc = 1;
583 break; 685 break;
@@ -587,8 +689,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
587 args.v2.usFbDiv = cpu_to_le16(fb_div); 689 args.v2.usFbDiv = cpu_to_le16(fb_div);
588 args.v2.ucFracFbDiv = frac_fb_div; 690 args.v2.ucFracFbDiv = frac_fb_div;
589 args.v2.ucPostDiv = post_div; 691 args.v2.ucPostDiv = post_div;
590 args.v2.ucPpll = 692 args.v2.ucPpll = radeon_crtc->pll_id;
591 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
592 args.v2.ucCRTC = radeon_crtc->crtc_id; 693 args.v2.ucCRTC = radeon_crtc->crtc_id;
593 args.v2.ucRefDivSrc = 1; 694 args.v2.ucRefDivSrc = 1;
594 break; 695 break;
@@ -598,12 +699,22 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
598 args.v3.usFbDiv = cpu_to_le16(fb_div); 699 args.v3.usFbDiv = cpu_to_le16(fb_div);
599 args.v3.ucFracFbDiv = frac_fb_div; 700 args.v3.ucFracFbDiv = frac_fb_div;
600 args.v3.ucPostDiv = post_div; 701 args.v3.ucPostDiv = post_div;
601 args.v3.ucPpll = 702 args.v3.ucPpll = radeon_crtc->pll_id;
602 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 703 args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2);
603 args.v3.ucMiscInfo = (radeon_crtc->crtc_id << 2);
604 args.v3.ucTransmitterId = radeon_encoder->encoder_id; 704 args.v3.ucTransmitterId = radeon_encoder->encoder_id;
605 args.v3.ucEncoderMode = 705 args.v3.ucEncoderMode = encoder_mode;
606 atombios_get_encoder_mode(encoder); 706 break;
707 case 5:
708 args.v5.ucCRTC = radeon_crtc->crtc_id;
709 args.v5.usPixelClock = cpu_to_le16(mode->clock / 10);
710 args.v5.ucRefDiv = ref_div;
711 args.v5.usFbDiv = cpu_to_le16(fb_div);
712 args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
713 args.v5.ucPostDiv = post_div;
714 args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
715 args.v5.ucTransmitterID = radeon_encoder->encoder_id;
716 args.v5.ucEncoderMode = encoder_mode;
717 args.v5.ucPpll = radeon_crtc->pll_id;
607 break; 718 break;
608 default: 719 default:
609 DRM_ERROR("Unknown table version %d %d\n", frev, crev); 720 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
@@ -618,6 +729,140 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
618 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 729 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
619} 730}
620 731
732static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
733 struct drm_framebuffer *old_fb)
734{
735 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
736 struct drm_device *dev = crtc->dev;
737 struct radeon_device *rdev = dev->dev_private;
738 struct radeon_framebuffer *radeon_fb;
739 struct drm_gem_object *obj;
740 struct radeon_bo *rbo;
741 uint64_t fb_location;
742 uint32_t fb_format, fb_pitch_pixels, tiling_flags;
743 int r;
744
745 /* no fb bound */
746 if (!crtc->fb) {
747 DRM_DEBUG("No FB bound\n");
748 return 0;
749 }
750
751 radeon_fb = to_radeon_framebuffer(crtc->fb);
752
753 /* Pin framebuffer & get tilling informations */
754 obj = radeon_fb->obj;
755 rbo = obj->driver_private;
756 r = radeon_bo_reserve(rbo, false);
757 if (unlikely(r != 0))
758 return r;
759 r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
760 if (unlikely(r != 0)) {
761 radeon_bo_unreserve(rbo);
762 return -EINVAL;
763 }
764 radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
765 radeon_bo_unreserve(rbo);
766
767 switch (crtc->fb->bits_per_pixel) {
768 case 8:
769 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
770 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
771 break;
772 case 15:
773 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
774 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
775 break;
776 case 16:
777 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
778 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
779 break;
780 case 24:
781 case 32:
782 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
783 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
784 break;
785 default:
786 DRM_ERROR("Unsupported screen depth %d\n",
787 crtc->fb->bits_per_pixel);
788 return -EINVAL;
789 }
790
791 switch (radeon_crtc->crtc_id) {
792 case 0:
793 WREG32(AVIVO_D1VGA_CONTROL, 0);
794 break;
795 case 1:
796 WREG32(AVIVO_D2VGA_CONTROL, 0);
797 break;
798 case 2:
799 WREG32(EVERGREEN_D3VGA_CONTROL, 0);
800 break;
801 case 3:
802 WREG32(EVERGREEN_D4VGA_CONTROL, 0);
803 break;
804 case 4:
805 WREG32(EVERGREEN_D5VGA_CONTROL, 0);
806 break;
807 case 5:
808 WREG32(EVERGREEN_D6VGA_CONTROL, 0);
809 break;
810 default:
811 break;
812 }
813
814 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
815 upper_32_bits(fb_location));
816 WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
817 upper_32_bits(fb_location));
818 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
819 (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
820 WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
821 (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
822 WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
823
824 WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
825 WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
826 WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
827 WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
828 WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width);
829 WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height);
830
831 fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
832 WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
833 WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
834
835 WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
836 crtc->mode.vdisplay);
837 x &= ~3;
838 y &= ~1;
839 WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
840 (x << 16) | y);
841 WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
842 (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
843
844 if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
845 WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
846 EVERGREEN_INTERLEAVE_EN);
847 else
848 WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
849
850 if (old_fb && old_fb != crtc->fb) {
851 radeon_fb = to_radeon_framebuffer(old_fb);
852 rbo = radeon_fb->obj->driver_private;
853 r = radeon_bo_reserve(rbo, false);
854 if (unlikely(r != 0))
855 return r;
856 radeon_bo_unpin(rbo);
857 radeon_bo_unreserve(rbo);
858 }
859
860 /* Bytes per pixel may have changed */
861 radeon_bandwidth_update(rdev);
862
863 return 0;
864}
865
621static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, 866static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
622 struct drm_framebuffer *old_fb) 867 struct drm_framebuffer *old_fb)
623{ 868{
@@ -755,7 +1000,9 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
755 struct drm_device *dev = crtc->dev; 1000 struct drm_device *dev = crtc->dev;
756 struct radeon_device *rdev = dev->dev_private; 1001 struct radeon_device *rdev = dev->dev_private;
757 1002
758 if (ASIC_IS_AVIVO(rdev)) 1003 if (ASIC_IS_DCE4(rdev))
1004 return evergreen_crtc_set_base(crtc, x, y, old_fb);
1005 else if (ASIC_IS_AVIVO(rdev))
759 return avivo_crtc_set_base(crtc, x, y, old_fb); 1006 return avivo_crtc_set_base(crtc, x, y, old_fb);
760 else 1007 else
761 return radeon_crtc_set_base(crtc, x, y, old_fb); 1008 return radeon_crtc_set_base(crtc, x, y, old_fb);
@@ -785,6 +1032,46 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
785 } 1032 }
786} 1033}
787 1034
1035static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1036{
1037 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1038 struct drm_device *dev = crtc->dev;
1039 struct radeon_device *rdev = dev->dev_private;
1040 struct drm_encoder *test_encoder;
1041 struct drm_crtc *test_crtc;
1042 uint32_t pll_in_use = 0;
1043
1044 if (ASIC_IS_DCE4(rdev)) {
1045 /* if crtc is driving DP and we have an ext clock, use that */
1046 list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
1047 if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
1048 if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) {
1049 if (rdev->clock.dp_extclk)
1050 return ATOM_PPLL_INVALID;
1051 }
1052 }
1053 }
1054
1055 /* otherwise, pick one of the plls */
1056 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1057 struct radeon_crtc *radeon_test_crtc;
1058
1059 if (crtc == test_crtc)
1060 continue;
1061
1062 radeon_test_crtc = to_radeon_crtc(test_crtc);
1063 if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
1064 (radeon_test_crtc->pll_id <= ATOM_PPLL2))
1065 pll_in_use |= (1 << radeon_test_crtc->pll_id);
1066 }
1067 if (!(pll_in_use & 1))
1068 return ATOM_PPLL1;
1069 return ATOM_PPLL2;
1070 } else
1071 return radeon_crtc->crtc_id;
1072
1073}
1074
788int atombios_crtc_mode_set(struct drm_crtc *crtc, 1075int atombios_crtc_mode_set(struct drm_crtc *crtc,
789 struct drm_display_mode *mode, 1076 struct drm_display_mode *mode,
790 struct drm_display_mode *adjusted_mode, 1077 struct drm_display_mode *adjusted_mode,
@@ -796,19 +1083,27 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
796 1083
797 /* TODO color tiling */ 1084 /* TODO color tiling */
798 1085
1086 /* pick pll */
1087 radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
1088
799 atombios_set_ss(crtc, 0); 1089 atombios_set_ss(crtc, 0);
1090 /* always set DCPLL */
1091 if (ASIC_IS_DCE4(rdev))
1092 atombios_crtc_set_dcpll(crtc);
800 atombios_crtc_set_pll(crtc, adjusted_mode); 1093 atombios_crtc_set_pll(crtc, adjusted_mode);
801 atombios_set_ss(crtc, 1); 1094 atombios_set_ss(crtc, 1);
802 atombios_crtc_set_timing(crtc, adjusted_mode);
803 1095
804 if (ASIC_IS_AVIVO(rdev)) 1096 if (ASIC_IS_DCE4(rdev))
805 atombios_crtc_set_base(crtc, x, y, old_fb); 1097 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1098 else if (ASIC_IS_AVIVO(rdev))
1099 atombios_crtc_set_timing(crtc, adjusted_mode);
806 else { 1100 else {
1101 atombios_crtc_set_timing(crtc, adjusted_mode);
807 if (radeon_crtc->crtc_id == 0) 1102 if (radeon_crtc->crtc_id == 0)
808 atombios_set_crtc_dtd_timing(crtc, adjusted_mode); 1103 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
809 atombios_crtc_set_base(crtc, x, y, old_fb);
810 radeon_legacy_atom_fixup(crtc); 1104 radeon_legacy_atom_fixup(crtc);
811 } 1105 }
1106 atombios_crtc_set_base(crtc, x, y, old_fb);
812 atombios_overscan_setup(crtc, mode, adjusted_mode); 1107 atombios_overscan_setup(crtc, mode, adjusted_mode);
813 atombios_scaler_setup(crtc); 1108 atombios_scaler_setup(crtc);
814 return 0; 1109 return 0;
@@ -825,14 +1120,14 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
825 1120
826static void atombios_crtc_prepare(struct drm_crtc *crtc) 1121static void atombios_crtc_prepare(struct drm_crtc *crtc)
827{ 1122{
828 atombios_lock_crtc(crtc, 1); 1123 atombios_lock_crtc(crtc, ATOM_ENABLE);
829 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 1124 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
830} 1125}
831 1126
832static void atombios_crtc_commit(struct drm_crtc *crtc) 1127static void atombios_crtc_commit(struct drm_crtc *crtc)
833{ 1128{
834 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 1129 atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
835 atombios_lock_crtc(crtc, 0); 1130 atombios_lock_crtc(crtc, ATOM_DISABLE);
836} 1131}
837 1132
838static const struct drm_crtc_helper_funcs atombios_helper_funcs = { 1133static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
@@ -848,8 +1143,37 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
848void radeon_atombios_init_crtc(struct drm_device *dev, 1143void radeon_atombios_init_crtc(struct drm_device *dev,
849 struct radeon_crtc *radeon_crtc) 1144 struct radeon_crtc *radeon_crtc)
850{ 1145{
851 if (radeon_crtc->crtc_id == 1) 1146 struct radeon_device *rdev = dev->dev_private;
852 radeon_crtc->crtc_offset = 1147
853 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; 1148 if (ASIC_IS_DCE4(rdev)) {
1149 switch (radeon_crtc->crtc_id) {
1150 case 0:
1151 default:
1152 radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
1153 break;
1154 case 1:
1155 radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
1156 break;
1157 case 2:
1158 radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
1159 break;
1160 case 3:
1161 radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
1162 break;
1163 case 4:
1164 radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
1165 break;
1166 case 5:
1167 radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
1168 break;
1169 }
1170 } else {
1171 if (radeon_crtc->crtc_id == 1)
1172 radeon_crtc->crtc_offset =
1173 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
1174 else
1175 radeon_crtc->crtc_offset = 0;
1176 }
1177 radeon_crtc->pll_id = -1;
854 drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); 1178 drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
855} 1179}