diff options
| author | Alex Deucher <alexdeucher@gmail.com> | 2010-01-19 17:32:27 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2010-01-24 02:24:29 -0500 |
| commit | 4eaeca33512b9774c25507b9a9bdcfe3791a5cc5 (patch) | |
| tree | d171b1cf87604c4af8893a299cb872c950365aac | |
| parent | fc10332b8ac5ca32d11f898027d84c007543bd80 (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>
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 196 |
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 | ||
| 412 | void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | 412 | union adjust_pixel_clock { |
| 413 | ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; | ||
| 414 | }; | ||
| 415 | |||
| 416 | static 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 | |||
| 513 | union 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 | |||
| 520 | void 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 | ||
