diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_pm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 179 |
1 files changed, 75 insertions, 104 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index f87efec76236..aaa19dc418a0 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "drmP.h" | 23 | #include "drmP.h" |
24 | #include "radeon.h" | 24 | #include "radeon.h" |
25 | #include "avivod.h" | 25 | #include "avivod.h" |
26 | #include "atom.h" | ||
26 | #ifdef CONFIG_ACPI | 27 | #ifdef CONFIG_ACPI |
27 | #include <linux/acpi.h> | 28 | #include <linux/acpi.h> |
28 | #endif | 29 | #endif |
@@ -167,13 +168,13 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
167 | if (radeon_gui_idle(rdev)) { | 168 | if (radeon_gui_idle(rdev)) { |
168 | sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 169 | sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
169 | clock_info[rdev->pm.requested_clock_mode_index].sclk; | 170 | clock_info[rdev->pm.requested_clock_mode_index].sclk; |
170 | if (sclk > rdev->clock.default_sclk) | 171 | if (sclk > rdev->pm.default_sclk) |
171 | sclk = rdev->clock.default_sclk; | 172 | sclk = rdev->pm.default_sclk; |
172 | 173 | ||
173 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. | 174 | mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. |
174 | clock_info[rdev->pm.requested_clock_mode_index].mclk; | 175 | clock_info[rdev->pm.requested_clock_mode_index].mclk; |
175 | if (mclk > rdev->clock.default_mclk) | 176 | if (mclk > rdev->pm.default_mclk) |
176 | mclk = rdev->clock.default_mclk; | 177 | mclk = rdev->pm.default_mclk; |
177 | 178 | ||
178 | /* upvolt before raising clocks, downvolt after lowering clocks */ | 179 | /* upvolt before raising clocks, downvolt after lowering clocks */ |
179 | if (sclk < rdev->pm.current_sclk) | 180 | if (sclk < rdev->pm.current_sclk) |
@@ -365,12 +366,14 @@ static ssize_t radeon_set_pm_profile(struct device *dev, | |||
365 | else if (strncmp("high", buf, strlen("high")) == 0) | 366 | else if (strncmp("high", buf, strlen("high")) == 0) |
366 | rdev->pm.profile = PM_PROFILE_HIGH; | 367 | rdev->pm.profile = PM_PROFILE_HIGH; |
367 | else { | 368 | else { |
368 | DRM_ERROR("invalid power profile!\n"); | 369 | count = -EINVAL; |
369 | goto fail; | 370 | goto fail; |
370 | } | 371 | } |
371 | radeon_pm_update_profile(rdev); | 372 | radeon_pm_update_profile(rdev); |
372 | radeon_pm_set_clocks(rdev); | 373 | radeon_pm_set_clocks(rdev); |
373 | } | 374 | } else |
375 | count = -EINVAL; | ||
376 | |||
374 | fail: | 377 | fail: |
375 | mutex_unlock(&rdev->pm.mutex); | 378 | mutex_unlock(&rdev->pm.mutex); |
376 | 379 | ||
@@ -405,22 +408,15 @@ static ssize_t radeon_set_pm_method(struct device *dev, | |||
405 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; | 408 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; |
406 | mutex_unlock(&rdev->pm.mutex); | 409 | mutex_unlock(&rdev->pm.mutex); |
407 | } else if (strncmp("profile", buf, strlen("profile")) == 0) { | 410 | } else if (strncmp("profile", buf, strlen("profile")) == 0) { |
408 | bool flush_wq = false; | ||
409 | |||
410 | mutex_lock(&rdev->pm.mutex); | 411 | mutex_lock(&rdev->pm.mutex); |
411 | if (rdev->pm.pm_method == PM_METHOD_DYNPM) { | ||
412 | cancel_delayed_work(&rdev->pm.dynpm_idle_work); | ||
413 | flush_wq = true; | ||
414 | } | ||
415 | /* disable dynpm */ | 412 | /* disable dynpm */ |
416 | rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; | 413 | rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; |
417 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; | 414 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; |
418 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 415 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
419 | mutex_unlock(&rdev->pm.mutex); | 416 | mutex_unlock(&rdev->pm.mutex); |
420 | if (flush_wq) | 417 | cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); |
421 | flush_workqueue(rdev->wq); | ||
422 | } else { | 418 | } else { |
423 | DRM_ERROR("invalid power method!\n"); | 419 | count = -EINVAL; |
424 | goto fail; | 420 | goto fail; |
425 | } | 421 | } |
426 | radeon_pm_compute_clocks(rdev); | 422 | radeon_pm_compute_clocks(rdev); |
@@ -437,7 +433,7 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, | |||
437 | { | 433 | { |
438 | struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); | 434 | struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); |
439 | struct radeon_device *rdev = ddev->dev_private; | 435 | struct radeon_device *rdev = ddev->dev_private; |
440 | u32 temp; | 436 | int temp; |
441 | 437 | ||
442 | switch (rdev->pm.int_thermal_type) { | 438 | switch (rdev->pm.int_thermal_type) { |
443 | case THERMAL_TYPE_RV6XX: | 439 | case THERMAL_TYPE_RV6XX: |
@@ -447,8 +443,12 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, | |||
447 | temp = rv770_get_temp(rdev); | 443 | temp = rv770_get_temp(rdev); |
448 | break; | 444 | break; |
449 | case THERMAL_TYPE_EVERGREEN: | 445 | case THERMAL_TYPE_EVERGREEN: |
446 | case THERMAL_TYPE_NI: | ||
450 | temp = evergreen_get_temp(rdev); | 447 | temp = evergreen_get_temp(rdev); |
451 | break; | 448 | break; |
449 | case THERMAL_TYPE_SUMO: | ||
450 | temp = sumo_get_temp(rdev); | ||
451 | break; | ||
452 | default: | 452 | default: |
453 | temp = 0; | 453 | temp = 0; |
454 | break; | 454 | break; |
@@ -487,6 +487,8 @@ static int radeon_hwmon_init(struct radeon_device *rdev) | |||
487 | case THERMAL_TYPE_RV6XX: | 487 | case THERMAL_TYPE_RV6XX: |
488 | case THERMAL_TYPE_RV770: | 488 | case THERMAL_TYPE_RV770: |
489 | case THERMAL_TYPE_EVERGREEN: | 489 | case THERMAL_TYPE_EVERGREEN: |
490 | case THERMAL_TYPE_NI: | ||
491 | case THERMAL_TYPE_SUMO: | ||
490 | rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); | 492 | rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); |
491 | if (IS_ERR(rdev->pm.int_hwmon_dev)) { | 493 | if (IS_ERR(rdev->pm.int_hwmon_dev)) { |
492 | err = PTR_ERR(rdev->pm.int_hwmon_dev); | 494 | err = PTR_ERR(rdev->pm.int_hwmon_dev); |
@@ -520,34 +522,44 @@ static void radeon_hwmon_fini(struct radeon_device *rdev) | |||
520 | 522 | ||
521 | void radeon_pm_suspend(struct radeon_device *rdev) | 523 | void radeon_pm_suspend(struct radeon_device *rdev) |
522 | { | 524 | { |
523 | bool flush_wq = false; | ||
524 | |||
525 | mutex_lock(&rdev->pm.mutex); | 525 | mutex_lock(&rdev->pm.mutex); |
526 | if (rdev->pm.pm_method == PM_METHOD_DYNPM) { | 526 | if (rdev->pm.pm_method == PM_METHOD_DYNPM) { |
527 | cancel_delayed_work(&rdev->pm.dynpm_idle_work); | ||
528 | if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) | 527 | if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) |
529 | rdev->pm.dynpm_state = DYNPM_STATE_SUSPENDED; | 528 | rdev->pm.dynpm_state = DYNPM_STATE_SUSPENDED; |
530 | flush_wq = true; | ||
531 | } | 529 | } |
532 | mutex_unlock(&rdev->pm.mutex); | 530 | mutex_unlock(&rdev->pm.mutex); |
533 | if (flush_wq) | 531 | |
534 | flush_workqueue(rdev->wq); | 532 | cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); |
535 | } | 533 | } |
536 | 534 | ||
537 | void radeon_pm_resume(struct radeon_device *rdev) | 535 | void radeon_pm_resume(struct radeon_device *rdev) |
538 | { | 536 | { |
537 | /* set up the default clocks if the MC ucode is loaded */ | ||
538 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { | ||
539 | if (rdev->pm.default_vddc) | ||
540 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, | ||
541 | SET_VOLTAGE_TYPE_ASIC_VDDC); | ||
542 | if (rdev->pm.default_vddci) | ||
543 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, | ||
544 | SET_VOLTAGE_TYPE_ASIC_VDDCI); | ||
545 | if (rdev->pm.default_sclk) | ||
546 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); | ||
547 | if (rdev->pm.default_mclk) | ||
548 | radeon_set_memory_clock(rdev, rdev->pm.default_mclk); | ||
549 | } | ||
539 | /* asic init will reset the default power state */ | 550 | /* asic init will reset the default power state */ |
540 | mutex_lock(&rdev->pm.mutex); | 551 | mutex_lock(&rdev->pm.mutex); |
541 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; | 552 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; |
542 | rdev->pm.current_clock_mode_index = 0; | 553 | rdev->pm.current_clock_mode_index = 0; |
543 | rdev->pm.current_sclk = rdev->clock.default_sclk; | 554 | rdev->pm.current_sclk = rdev->pm.default_sclk; |
544 | rdev->pm.current_mclk = rdev->clock.default_mclk; | 555 | rdev->pm.current_mclk = rdev->pm.default_mclk; |
545 | rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; | 556 | rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; |
557 | rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci; | ||
546 | if (rdev->pm.pm_method == PM_METHOD_DYNPM | 558 | if (rdev->pm.pm_method == PM_METHOD_DYNPM |
547 | && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { | 559 | && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { |
548 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; | 560 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; |
549 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, | 561 | schedule_delayed_work(&rdev->pm.dynpm_idle_work, |
550 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | 562 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); |
551 | } | 563 | } |
552 | mutex_unlock(&rdev->pm.mutex); | 564 | mutex_unlock(&rdev->pm.mutex); |
553 | radeon_pm_compute_clocks(rdev); | 565 | radeon_pm_compute_clocks(rdev); |
@@ -564,6 +576,8 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
564 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; | 576 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; |
565 | rdev->pm.dynpm_can_upclock = true; | 577 | rdev->pm.dynpm_can_upclock = true; |
566 | rdev->pm.dynpm_can_downclock = true; | 578 | rdev->pm.dynpm_can_downclock = true; |
579 | rdev->pm.default_sclk = rdev->clock.default_sclk; | ||
580 | rdev->pm.default_mclk = rdev->clock.default_mclk; | ||
567 | rdev->pm.current_sclk = rdev->clock.default_sclk; | 581 | rdev->pm.current_sclk = rdev->clock.default_sclk; |
568 | rdev->pm.current_mclk = rdev->clock.default_mclk; | 582 | rdev->pm.current_mclk = rdev->clock.default_mclk; |
569 | rdev->pm.int_thermal_type = THERMAL_TYPE_NONE; | 583 | rdev->pm.int_thermal_type = THERMAL_TYPE_NONE; |
@@ -575,12 +589,25 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
575 | radeon_combios_get_power_modes(rdev); | 589 | radeon_combios_get_power_modes(rdev); |
576 | radeon_pm_print_states(rdev); | 590 | radeon_pm_print_states(rdev); |
577 | radeon_pm_init_profile(rdev); | 591 | radeon_pm_init_profile(rdev); |
592 | /* set up the default clocks if the MC ucode is loaded */ | ||
593 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { | ||
594 | if (rdev->pm.default_vddc) | ||
595 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, | ||
596 | SET_VOLTAGE_TYPE_ASIC_VDDC); | ||
597 | if (rdev->pm.default_sclk) | ||
598 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); | ||
599 | if (rdev->pm.default_mclk) | ||
600 | radeon_set_memory_clock(rdev, rdev->pm.default_mclk); | ||
601 | } | ||
578 | } | 602 | } |
579 | 603 | ||
580 | /* set up the internal thermal sensor if applicable */ | 604 | /* set up the internal thermal sensor if applicable */ |
581 | ret = radeon_hwmon_init(rdev); | 605 | ret = radeon_hwmon_init(rdev); |
582 | if (ret) | 606 | if (ret) |
583 | return ret; | 607 | return ret; |
608 | |||
609 | INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler); | ||
610 | |||
584 | if (rdev->pm.num_power_states > 1) { | 611 | if (rdev->pm.num_power_states > 1) { |
585 | /* where's the best place to put these? */ | 612 | /* where's the best place to put these? */ |
586 | ret = device_create_file(rdev->dev, &dev_attr_power_profile); | 613 | ret = device_create_file(rdev->dev, &dev_attr_power_profile); |
@@ -594,8 +621,6 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
594 | rdev->acpi_nb.notifier_call = radeon_acpi_event; | 621 | rdev->acpi_nb.notifier_call = radeon_acpi_event; |
595 | register_acpi_notifier(&rdev->acpi_nb); | 622 | register_acpi_notifier(&rdev->acpi_nb); |
596 | #endif | 623 | #endif |
597 | INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler); | ||
598 | |||
599 | if (radeon_debugfs_pm_init(rdev)) { | 624 | if (radeon_debugfs_pm_init(rdev)) { |
600 | DRM_ERROR("Failed to register debugfs file for PM!\n"); | 625 | DRM_ERROR("Failed to register debugfs file for PM!\n"); |
601 | } | 626 | } |
@@ -609,25 +634,20 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
609 | void radeon_pm_fini(struct radeon_device *rdev) | 634 | void radeon_pm_fini(struct radeon_device *rdev) |
610 | { | 635 | { |
611 | if (rdev->pm.num_power_states > 1) { | 636 | if (rdev->pm.num_power_states > 1) { |
612 | bool flush_wq = false; | ||
613 | |||
614 | mutex_lock(&rdev->pm.mutex); | 637 | mutex_lock(&rdev->pm.mutex); |
615 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { | 638 | if (rdev->pm.pm_method == PM_METHOD_PROFILE) { |
616 | rdev->pm.profile = PM_PROFILE_DEFAULT; | 639 | rdev->pm.profile = PM_PROFILE_DEFAULT; |
617 | radeon_pm_update_profile(rdev); | 640 | radeon_pm_update_profile(rdev); |
618 | radeon_pm_set_clocks(rdev); | 641 | radeon_pm_set_clocks(rdev); |
619 | } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { | 642 | } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { |
620 | /* cancel work */ | ||
621 | cancel_delayed_work(&rdev->pm.dynpm_idle_work); | ||
622 | flush_wq = true; | ||
623 | /* reset default clocks */ | 643 | /* reset default clocks */ |
624 | rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; | 644 | rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; |
625 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; | 645 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; |
626 | radeon_pm_set_clocks(rdev); | 646 | radeon_pm_set_clocks(rdev); |
627 | } | 647 | } |
628 | mutex_unlock(&rdev->pm.mutex); | 648 | mutex_unlock(&rdev->pm.mutex); |
629 | if (flush_wq) | 649 | |
630 | flush_workqueue(rdev->wq); | 650 | cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); |
631 | 651 | ||
632 | device_remove_file(rdev->dev, &dev_attr_power_profile); | 652 | device_remove_file(rdev->dev, &dev_attr_power_profile); |
633 | device_remove_file(rdev->dev, &dev_attr_power_method); | 653 | device_remove_file(rdev->dev, &dev_attr_power_method); |
@@ -636,6 +656,9 @@ void radeon_pm_fini(struct radeon_device *rdev) | |||
636 | #endif | 656 | #endif |
637 | } | 657 | } |
638 | 658 | ||
659 | if (rdev->pm.power_state) | ||
660 | kfree(rdev->pm.power_state); | ||
661 | |||
639 | radeon_hwmon_fini(rdev); | 662 | radeon_hwmon_fini(rdev); |
640 | } | 663 | } |
641 | 664 | ||
@@ -686,12 +709,12 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) | |||
686 | radeon_pm_get_dynpm_state(rdev); | 709 | radeon_pm_get_dynpm_state(rdev); |
687 | radeon_pm_set_clocks(rdev); | 710 | radeon_pm_set_clocks(rdev); |
688 | 711 | ||
689 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, | 712 | schedule_delayed_work(&rdev->pm.dynpm_idle_work, |
690 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | 713 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); |
691 | } else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) { | 714 | } else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) { |
692 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; | 715 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; |
693 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, | 716 | schedule_delayed_work(&rdev->pm.dynpm_idle_work, |
694 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | 717 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); |
695 | DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n"); | 718 | DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n"); |
696 | } | 719 | } |
697 | } else { /* count == 0 */ | 720 | } else { /* count == 0 */ |
@@ -712,73 +735,21 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) | |||
712 | 735 | ||
713 | static bool radeon_pm_in_vbl(struct radeon_device *rdev) | 736 | static bool radeon_pm_in_vbl(struct radeon_device *rdev) |
714 | { | 737 | { |
715 | u32 stat_crtc = 0, vbl = 0, position = 0; | 738 | int crtc, vpos, hpos, vbl_status; |
716 | bool in_vbl = true; | 739 | bool in_vbl = true; |
717 | 740 | ||
718 | if (ASIC_IS_DCE4(rdev)) { | 741 | /* Iterate over all active crtc's. All crtc's must be in vblank, |
719 | if (rdev->pm.active_crtcs & (1 << 0)) { | 742 | * otherwise return in_vbl == false. |
720 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 743 | */ |
721 | EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; | 744 | for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { |
722 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 745 | if (rdev->pm.active_crtcs & (1 << crtc)) { |
723 | EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; | 746 | vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos); |
724 | } | 747 | if ((vbl_status & DRM_SCANOUTPOS_VALID) && |
725 | if (rdev->pm.active_crtcs & (1 << 1)) { | 748 | !(vbl_status & DRM_SCANOUTPOS_INVBL)) |
726 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | ||
727 | EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; | ||
728 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | ||
729 | EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; | ||
730 | } | ||
731 | if (rdev->pm.active_crtcs & (1 << 2)) { | ||
732 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | ||
733 | EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; | ||
734 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | ||
735 | EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; | ||
736 | } | ||
737 | if (rdev->pm.active_crtcs & (1 << 3)) { | ||
738 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | ||
739 | EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; | ||
740 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | ||
741 | EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; | ||
742 | } | ||
743 | if (rdev->pm.active_crtcs & (1 << 4)) { | ||
744 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | ||
745 | EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; | ||
746 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | ||
747 | EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; | ||
748 | } | ||
749 | if (rdev->pm.active_crtcs & (1 << 5)) { | ||
750 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | ||
751 | EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; | ||
752 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | ||
753 | EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; | ||
754 | } | ||
755 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
756 | if (rdev->pm.active_crtcs & (1 << 0)) { | ||
757 | vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END) & 0xfff; | ||
758 | position = RREG32(AVIVO_D1CRTC_STATUS_POSITION) & 0xfff; | ||
759 | } | ||
760 | if (rdev->pm.active_crtcs & (1 << 1)) { | ||
761 | vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END) & 0xfff; | ||
762 | position = RREG32(AVIVO_D2CRTC_STATUS_POSITION) & 0xfff; | ||
763 | } | ||
764 | if (position < vbl && position > 1) | ||
765 | in_vbl = false; | ||
766 | } else { | ||
767 | if (rdev->pm.active_crtcs & (1 << 0)) { | ||
768 | stat_crtc = RREG32(RADEON_CRTC_STATUS); | ||
769 | if (!(stat_crtc & 1)) | ||
770 | in_vbl = false; | ||
771 | } | ||
772 | if (rdev->pm.active_crtcs & (1 << 1)) { | ||
773 | stat_crtc = RREG32(RADEON_CRTC2_STATUS); | ||
774 | if (!(stat_crtc & 1)) | ||
775 | in_vbl = false; | 749 | in_vbl = false; |
776 | } | 750 | } |
777 | } | 751 | } |
778 | 752 | ||
779 | if (position < vbl && position > 1) | ||
780 | in_vbl = false; | ||
781 | |||
782 | return in_vbl; | 753 | return in_vbl; |
783 | } | 754 | } |
784 | 755 | ||
@@ -848,8 +819,8 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) | |||
848 | radeon_pm_set_clocks(rdev); | 819 | radeon_pm_set_clocks(rdev); |
849 | } | 820 | } |
850 | 821 | ||
851 | queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, | 822 | schedule_delayed_work(&rdev->pm.dynpm_idle_work, |
852 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); | 823 | msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); |
853 | } | 824 | } |
854 | mutex_unlock(&rdev->pm.mutex); | 825 | mutex_unlock(&rdev->pm.mutex); |
855 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | 826 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); |
@@ -866,9 +837,9 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) | |||
866 | struct drm_device *dev = node->minor->dev; | 837 | struct drm_device *dev = node->minor->dev; |
867 | struct radeon_device *rdev = dev->dev_private; | 838 | struct radeon_device *rdev = dev->dev_private; |
868 | 839 | ||
869 | seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk); | 840 | seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk); |
870 | seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); | 841 | seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); |
871 | seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk); | 842 | seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk); |
872 | if (rdev->asic->get_memory_clock) | 843 | if (rdev->asic->get_memory_clock) |
873 | seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); | 844 | seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); |
874 | if (rdev->pm.current_vddc) | 845 | if (rdev->pm.current_vddc) |