aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-01-19 17:32:27 -0500
committerDave Airlie <airlied@redhat.com>2010-01-24 02:24:29 -0500
commit4eaeca33512b9774c25507b9a9bdcfe3791a5cc5 (patch)
treed171b1cf87604c4af8893a299cb872c950365aac /drivers
parentfc10332b8ac5ca32d11f898027d84c007543bd80 (diff)
drm/radeon/kms: clean up atombios pll code
- split pll adjust into a separate function - use a union for SetPixelClock params Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c196
1 files changed, 121 insertions, 75 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 7a8cdf2813dc..e619aca5423f 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -409,30 +409,22 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
409 } 409 }
410} 410}
411 411
412void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) 412union adjust_pixel_clock {
413 ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
414};
415
416static u32 atombios_adjust_pll(struct drm_crtc *crtc,
417 struct drm_display_mode *mode,
418 struct radeon_pll *pll)
413{ 419{
414 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
415 struct drm_device *dev = crtc->dev; 420 struct drm_device *dev = crtc->dev;
416 struct radeon_device *rdev = dev->dev_private; 421 struct radeon_device *rdev = dev->dev_private;
417 struct drm_encoder *encoder = NULL; 422 struct drm_encoder *encoder = NULL;
418 struct radeon_encoder *radeon_encoder = NULL; 423 struct radeon_encoder *radeon_encoder = NULL;
419 uint8_t frev, crev; 424 u32 adjusted_clock = mode->clock;
420 int index;
421 SET_PIXEL_CLOCK_PS_ALLOCATION args;
422 PIXEL_CLOCK_PARAMETERS *spc1_ptr;
423 PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
424 PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
425 uint32_t pll_clock = mode->clock;
426 uint32_t adjusted_clock;
427 uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
428 struct radeon_pll *pll;
429 425
430 if (radeon_crtc->crtc_id == 0) 426 /* reset the pll flags */
431 pll = &rdev->clock.p1pll; 427 pll->flags = 0;
432 else
433 pll = &rdev->clock.p2pll;
434
435 memset(&args, 0, sizeof(args));
436 428
437 if (ASIC_IS_AVIVO(rdev)) { 429 if (ASIC_IS_AVIVO(rdev)) {
438 if ((rdev->family == CHIP_RS600) || 430 if ((rdev->family == CHIP_RS600) ||
@@ -457,15 +449,17 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
457 449
458 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 450 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
459 if (encoder->crtc == crtc) { 451 if (encoder->crtc == crtc) {
460 if (!ASIC_IS_AVIVO(rdev)) { 452 radeon_encoder = to_radeon_encoder(encoder);
461 if (encoder->encoder_type != 453 if (ASIC_IS_AVIVO(rdev)) {
462 DRM_MODE_ENCODER_DAC) 454 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
455 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
456 adjusted_clock = mode->clock * 2;
457 } else {
458 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
463 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; 459 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
464 if (encoder->encoder_type == 460 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
465 DRM_MODE_ENCODER_LVDS)
466 pll->flags |= RADEON_PLL_USE_REF_DIV; 461 pll->flags |= RADEON_PLL_USE_REF_DIV;
467 } 462 }
468 radeon_encoder = to_radeon_encoder(encoder);
469 break; 463 break;
470 } 464 }
471 } 465 }
@@ -475,28 +469,88 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
475 * special hw requirements. 469 * special hw requirements.
476 */ 470 */
477 if (ASIC_IS_DCE3(rdev)) { 471 if (ASIC_IS_DCE3(rdev)) {
478 ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args; 472 union adjust_pixel_clock args;
479 473 struct radeon_encoder_atom_dig *dig;
480 if (!encoder) 474 u8 frev, crev;
481 return; 475 int index;
482 476
483 memset(&adjust_pll_args, 0, sizeof(adjust_pll_args)); 477 if (!radeon_encoder->enc_priv)
484 adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10); 478 return adjusted_clock;
485 adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id; 479 dig = radeon_encoder->enc_priv;
486 adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder);
487 480
488 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); 481 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
489 atom_execute_table(rdev->mode_info.atom_context, 482 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
490 index, (uint32_t *)&adjust_pll_args); 483 &crev);
491 adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10; 484
492 } else { 485 memset(&args, 0, sizeof(args));
493 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ 486
494 if (ASIC_IS_AVIVO(rdev) && 487 switch (frev) {
495 (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)) 488 case 1:
496 adjusted_clock = mode->clock * 2; 489 switch (crev) {
497 else 490 case 1:
498 adjusted_clock = mode->clock; 491 case 2:
492 args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
493 args.v1.ucTransmitterID = radeon_encoder->encoder_id;
494 args.v1.ucEncodeMode = atombios_get_encoder_mode(encoder);
495
496 atom_execute_table(rdev->mode_info.atom_context,
497 index, (uint32_t *)&args);
498 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
499 break;
500 default:
501 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
502 return adjusted_clock;
503 }
504 break;
505 default:
506 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
507 return adjusted_clock;
508 }
499 } 509 }
510 return adjusted_clock;
511}
512
513union set_pixel_clock {
514 SET_PIXEL_CLOCK_PS_ALLOCATION base;
515 PIXEL_CLOCK_PARAMETERS v1;
516 PIXEL_CLOCK_PARAMETERS_V2 v2;
517 PIXEL_CLOCK_PARAMETERS_V3 v3;
518};
519
520void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
521{
522 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
523 struct drm_device *dev = crtc->dev;
524 struct radeon_device *rdev = dev->dev_private;
525 struct drm_encoder *encoder = NULL;
526 struct radeon_encoder *radeon_encoder = NULL;
527 u8 frev, crev;
528 int index;
529 union set_pixel_clock args;
530 u32 pll_clock = mode->clock;
531 u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
532 struct radeon_pll *pll;
533 u32 adjusted_clock;
534
535 memset(&args, 0, sizeof(args));
536
537 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
538 if (encoder->crtc == crtc) {
539 radeon_encoder = to_radeon_encoder(encoder);
540 break;
541 }
542 }
543
544 if (!radeon_encoder)
545 return;
546
547 if (radeon_crtc->crtc_id == 0)
548 pll = &rdev->clock.p1pll;
549 else
550 pll = &rdev->clock.p2pll;
551
552 /* adjust pixel clock as needed */
553 adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
500 554
501 if (ASIC_IS_AVIVO(rdev)) { 555 if (ASIC_IS_AVIVO(rdev)) {
502 if (radeon_new_pll) 556 if (radeon_new_pll)
@@ -519,45 +573,38 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
519 case 1: 573 case 1:
520 switch (crev) { 574 switch (crev) {
521 case 1: 575 case 1:
522 spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; 576 args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
523 spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); 577 args.v1.usRefDiv = cpu_to_le16(ref_div);
524 spc1_ptr->usRefDiv = cpu_to_le16(ref_div); 578 args.v1.usFbDiv = cpu_to_le16(fb_div);
525 spc1_ptr->usFbDiv = cpu_to_le16(fb_div); 579 args.v1.ucFracFbDiv = frac_fb_div;
526 spc1_ptr->ucFracFbDiv = frac_fb_div; 580 args.v1.ucPostDiv = post_div;
527 spc1_ptr->ucPostDiv = post_div; 581 args.v1.ucPpll =
528 spc1_ptr->ucPpll =
529 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 582 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
530 spc1_ptr->ucCRTC = radeon_crtc->crtc_id; 583 args.v1.ucCRTC = radeon_crtc->crtc_id;
531 spc1_ptr->ucRefDivSrc = 1; 584 args.v1.ucRefDivSrc = 1;
532 break; 585 break;
533 case 2: 586 case 2:
534 spc2_ptr = 587 args.v2.usPixelClock = cpu_to_le16(mode->clock / 10);
535 (PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; 588 args.v2.usRefDiv = cpu_to_le16(ref_div);
536 spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); 589 args.v2.usFbDiv = cpu_to_le16(fb_div);
537 spc2_ptr->usRefDiv = cpu_to_le16(ref_div); 590 args.v2.ucFracFbDiv = frac_fb_div;
538 spc2_ptr->usFbDiv = cpu_to_le16(fb_div); 591 args.v2.ucPostDiv = post_div;
539 spc2_ptr->ucFracFbDiv = frac_fb_div; 592 args.v2.ucPpll =
540 spc2_ptr->ucPostDiv = post_div;
541 spc2_ptr->ucPpll =
542 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 593 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
543 spc2_ptr->ucCRTC = radeon_crtc->crtc_id; 594 args.v2.ucCRTC = radeon_crtc->crtc_id;
544 spc2_ptr->ucRefDivSrc = 1; 595 args.v2.ucRefDivSrc = 1;
545 break; 596 break;
546 case 3: 597 case 3:
547 if (!encoder) 598 args.v3.usPixelClock = cpu_to_le16(mode->clock / 10);
548 return; 599 args.v3.usRefDiv = cpu_to_le16(ref_div);
549 spc3_ptr = 600 args.v3.usFbDiv = cpu_to_le16(fb_div);
550 (PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; 601 args.v3.ucFracFbDiv = frac_fb_div;
551 spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); 602 args.v3.ucPostDiv = post_div;
552 spc3_ptr->usRefDiv = cpu_to_le16(ref_div); 603 args.v3.ucPpll =
553 spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
554 spc3_ptr->ucFracFbDiv = frac_fb_div;
555 spc3_ptr->ucPostDiv = post_div;
556 spc3_ptr->ucPpll =
557 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 604 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
558 spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2); 605 args.v3.ucMiscInfo = (radeon_crtc->crtc_id << 2);
559 spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id; 606 args.v3.ucTransmitterId = radeon_encoder->encoder_id;
560 spc3_ptr->ucEncoderMode = 607 args.v3.ucEncoderMode =
561 atombios_get_encoder_mode(encoder); 608 atombios_get_encoder_mode(encoder);
562 break; 609 break;
563 default: 610 default:
@@ -570,7 +617,6 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
570 return; 617 return;
571 } 618 }
572 619
573 printk("executing set pll\n");
574 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 620 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
575} 621}
576 622