diff options
author | Kenneth Feng <kenneth.feng@amd.com> | 2018-03-20 02:02:07 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-03-21 15:36:58 -0400 |
commit | 7436854ebd4166a7c4b023031f62f24f1174d2d2 (patch) | |
tree | 00985c96f9e56046a70bdabfd439263410d22116 | |
parent | 7f3f106e4431429c27d7cb5f1925d6709b51982e (diff) |
drm/amd/powerplay: Return per DPM level clock
Add change to return per DPM level clock in DAL interface
Signed-off-by: Kenneth Feng <kenneth.feng@amd.com>
Reviewed-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 370 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h | 2 |
2 files changed, 276 insertions, 96 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 7121870ff48c..f0bcac4be104 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | |||
@@ -483,6 +483,56 @@ static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state) | |||
483 | dpm_state->hard_max_level = 0xff; | 483 | dpm_state->hard_max_level = 0xff; |
484 | } | 484 | } |
485 | 485 | ||
486 | static int vega12_get_number_dpm_level(struct pp_hwmgr *hwmgr, | ||
487 | PPCLK_e clkID, uint32_t *num_dpm_level) | ||
488 | { | ||
489 | int result; | ||
490 | /* | ||
491 | * SMU expects the Clock ID to be in the top 16 bits. | ||
492 | * Lower 16 bits specify the level however 0xFF is a | ||
493 | * special argument the returns the total number of levels | ||
494 | */ | ||
495 | PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr, | ||
496 | PPSMC_MSG_GetDpmFreqByIndex, (clkID << 16 | 0xFF)) == 0, | ||
497 | "[GetNumberDpmLevel] Failed to get DPM levels from SMU for CLKID!", | ||
498 | return -EINVAL); | ||
499 | |||
500 | result = vega12_read_arg_from_smc(hwmgr, num_dpm_level); | ||
501 | |||
502 | PP_ASSERT_WITH_CODE(*num_dpm_level < MAX_REGULAR_DPM_NUMBER, | ||
503 | "[GetNumberDPMLevel] Number of DPM levels is greater than limit", | ||
504 | return -EINVAL); | ||
505 | |||
506 | PP_ASSERT_WITH_CODE(*num_dpm_level != 0, | ||
507 | "[GetNumberDPMLevel] Number of CLK Levels is zero!", | ||
508 | return -EINVAL); | ||
509 | |||
510 | return result; | ||
511 | } | ||
512 | |||
513 | static int vega12_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr, | ||
514 | PPCLK_e clkID, uint32_t index, uint32_t *clock) | ||
515 | { | ||
516 | int result; | ||
517 | |||
518 | /* | ||
519 | *SMU expects the Clock ID to be in the top 16 bits. | ||
520 | *Lower 16 bits specify the level | ||
521 | */ | ||
522 | PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr, | ||
523 | PPSMC_MSG_GetDpmFreqByIndex, (clkID << 16 | index)) == 0, | ||
524 | "[GetDpmFrequencyByIndex] Failed to get dpm frequency from SMU!", | ||
525 | return -EINVAL); | ||
526 | |||
527 | result = vega12_read_arg_from_smc(hwmgr, clock); | ||
528 | |||
529 | PP_ASSERT_WITH_CODE(*clock != 0, | ||
530 | "[GetDPMFrequencyByIndex] Failed to get dpm frequency by index.!", | ||
531 | return -EINVAL); | ||
532 | |||
533 | return result; | ||
534 | } | ||
535 | |||
486 | /* | 536 | /* |
487 | * This function is to initialize all DPM state tables | 537 | * This function is to initialize all DPM state tables |
488 | * for SMU based on the dependency table. | 538 | * for SMU based on the dependency table. |
@@ -493,43 +543,214 @@ static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state) | |||
493 | */ | 543 | */ |
494 | static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) | 544 | static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) |
495 | { | 545 | { |
546 | uint32_t num_levels, i, clock; | ||
547 | |||
496 | struct vega12_hwmgr *data = | 548 | struct vega12_hwmgr *data = |
497 | (struct vega12_hwmgr *)(hwmgr->backend); | 549 | (struct vega12_hwmgr *)(hwmgr->backend); |
550 | |||
498 | struct vega12_single_dpm_table *dpm_table; | 551 | struct vega12_single_dpm_table *dpm_table; |
499 | 552 | ||
500 | memset(&data->dpm_table, 0, sizeof(data->dpm_table)); | 553 | memset(&data->dpm_table, 0, sizeof(data->dpm_table)); |
501 | 554 | ||
502 | /* Initialize Sclk DPM table based on allow Sclk values */ | 555 | /* Initialize Sclk DPM and SOC DPM table based on allow Sclk values */ |
503 | dpm_table = &(data->dpm_table.soc_table); | 556 | dpm_table = &(data->dpm_table.soc_table); |
557 | |||
558 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_SOCCLK, | ||
559 | &num_levels) == 0, | ||
560 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for SOCCLK!", | ||
561 | return -EINVAL); | ||
562 | |||
563 | dpm_table->count = num_levels; | ||
564 | |||
565 | for (i = 0; i < num_levels; i++) { | ||
566 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
567 | PPCLK_SOCCLK, i, &clock) == 0, | ||
568 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for SOCCLK!", | ||
569 | return -EINVAL); | ||
570 | |||
571 | dpm_table->dpm_levels[i].value = clock; | ||
572 | } | ||
573 | |||
504 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 574 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
505 | 575 | ||
506 | dpm_table = &(data->dpm_table.gfx_table); | 576 | dpm_table = &(data->dpm_table.gfx_table); |
507 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | ||
508 | 577 | ||
509 | /* Initialize Mclk DPM table based on allow Mclk values */ | 578 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_GFXCLK, |
579 | &num_levels) == 0, | ||
580 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for GFXCLK!", | ||
581 | return -EINVAL); | ||
582 | |||
583 | dpm_table->count = num_levels; | ||
584 | for (i = 0; i < num_levels; i++) { | ||
585 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
586 | PPCLK_GFXCLK, i, &clock) == 0, | ||
587 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for GFXCLK!", | ||
588 | return -EINVAL); | ||
589 | |||
590 | dpm_table->dpm_levels[i].value = clock; | ||
591 | } | ||
592 | |||
593 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | ||
594 | /* Initialize Mclk DPM table based on allow Mclk values */ | ||
510 | dpm_table = &(data->dpm_table.mem_table); | 595 | dpm_table = &(data->dpm_table.mem_table); |
596 | |||
597 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_UCLK, | ||
598 | &num_levels) == 0, | ||
599 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for UCLK!", | ||
600 | return -EINVAL); | ||
601 | |||
602 | dpm_table->count = num_levels; | ||
603 | |||
604 | for (i = 0; i < num_levels; i++) { | ||
605 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
606 | PPCLK_UCLK, i, &clock) == 0, | ||
607 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for UCLK!", | ||
608 | return -EINVAL); | ||
609 | |||
610 | dpm_table->dpm_levels[i].value = clock; | ||
611 | } | ||
612 | |||
511 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 613 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
512 | 614 | ||
513 | dpm_table = &(data->dpm_table.eclk_table); | 615 | dpm_table = &(data->dpm_table.eclk_table); |
616 | |||
617 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_ECLK, | ||
618 | &num_levels) == 0, | ||
619 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for ECLK!", | ||
620 | return -EINVAL); | ||
621 | |||
622 | dpm_table->count = num_levels; | ||
623 | |||
624 | for (i = 0; i < num_levels; i++) { | ||
625 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
626 | PPCLK_ECLK, i, &clock) == 0, | ||
627 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for ECLK!", | ||
628 | return -EINVAL); | ||
629 | |||
630 | dpm_table->dpm_levels[i].value = clock; | ||
631 | } | ||
632 | |||
514 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 633 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
515 | 634 | ||
516 | dpm_table = &(data->dpm_table.vclk_table); | 635 | dpm_table = &(data->dpm_table.vclk_table); |
636 | |||
637 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_VCLK, | ||
638 | &num_levels) == 0, | ||
639 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for VCLK!", | ||
640 | return -EINVAL); | ||
641 | |||
642 | dpm_table->count = num_levels; | ||
643 | |||
644 | for (i = 0; i < num_levels; i++) { | ||
645 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
646 | PPCLK_VCLK, i, &clock) == 0, | ||
647 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for VCLK!", | ||
648 | return -EINVAL); | ||
649 | |||
650 | dpm_table->dpm_levels[i].value = clock; | ||
651 | } | ||
652 | |||
517 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 653 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
518 | 654 | ||
519 | dpm_table = &(data->dpm_table.dclk_table); | 655 | dpm_table = &(data->dpm_table.dclk_table); |
656 | |||
657 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_DCLK, | ||
658 | &num_levels) == 0, | ||
659 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCLK!", | ||
660 | return -EINVAL); | ||
661 | |||
662 | dpm_table->count = num_levels; | ||
663 | |||
664 | for (i = 0; i < num_levels; i++) { | ||
665 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
666 | PPCLK_DCLK, i, &clock) == 0, | ||
667 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCLK!", | ||
668 | return -EINVAL); | ||
669 | |||
670 | dpm_table->dpm_levels[i].value = clock; | ||
671 | } | ||
672 | |||
520 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 673 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
521 | 674 | ||
522 | /* Assume there is no headless Vega12 for now */ | 675 | /* Assume there is no headless Vega12 for now */ |
523 | dpm_table = &(data->dpm_table.dcef_table); | 676 | dpm_table = &(data->dpm_table.dcef_table); |
677 | |||
678 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, | ||
679 | PPCLK_DCEFCLK, &num_levels) == 0, | ||
680 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCEFCLK!", | ||
681 | return -EINVAL); | ||
682 | |||
683 | dpm_table->count = num_levels; | ||
684 | |||
685 | for (i = 0; i < num_levels; i++) { | ||
686 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
687 | PPCLK_DCEFCLK, i, &clock) == 0, | ||
688 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCEFCLK!", | ||
689 | return -EINVAL); | ||
690 | |||
691 | dpm_table->dpm_levels[i].value = clock; | ||
692 | } | ||
693 | |||
524 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 694 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
525 | 695 | ||
526 | dpm_table = &(data->dpm_table.pixel_table); | 696 | dpm_table = &(data->dpm_table.pixel_table); |
697 | |||
698 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, | ||
699 | PPCLK_PIXCLK, &num_levels) == 0, | ||
700 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PIXCLK!", | ||
701 | return -EINVAL); | ||
702 | |||
703 | dpm_table->count = num_levels; | ||
704 | |||
705 | for (i = 0; i < num_levels; i++) { | ||
706 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
707 | PPCLK_PIXCLK, i, &clock) == 0, | ||
708 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PIXCLK!", | ||
709 | return -EINVAL); | ||
710 | |||
711 | dpm_table->dpm_levels[i].value = clock; | ||
712 | } | ||
713 | |||
527 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 714 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
528 | 715 | ||
529 | dpm_table = &(data->dpm_table.display_table); | 716 | dpm_table = &(data->dpm_table.display_table); |
717 | |||
718 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, | ||
719 | PPCLK_DISPCLK, &num_levels) == 0, | ||
720 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DISPCLK!", | ||
721 | return -EINVAL); | ||
722 | |||
723 | dpm_table->count = num_levels; | ||
724 | |||
725 | for (i = 0; i < num_levels; i++) { | ||
726 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
727 | PPCLK_DISPCLK, i, &clock) == 0, | ||
728 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DISPCLK!", | ||
729 | return -EINVAL); | ||
730 | |||
731 | dpm_table->dpm_levels[i].value = clock; | ||
732 | } | ||
733 | |||
530 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 734 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
531 | 735 | ||
532 | dpm_table = &(data->dpm_table.phy_table); | 736 | dpm_table = &(data->dpm_table.phy_table); |
737 | |||
738 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, | ||
739 | PPCLK_PHYCLK, &num_levels) == 0, | ||
740 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PHYCLK!", | ||
741 | return -EINVAL); | ||
742 | |||
743 | dpm_table->count = num_levels; | ||
744 | |||
745 | for (i = 0; i < num_levels; i++) { | ||
746 | PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, | ||
747 | PPCLK_PHYCLK, i, &clock) == 0, | ||
748 | "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PHYCLK!", | ||
749 | return -EINVAL); | ||
750 | |||
751 | dpm_table->dpm_levels[i].value = clock; | ||
752 | } | ||
753 | |||
533 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 754 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
534 | 755 | ||
535 | /* save a copy of the default DPM table */ | 756 | /* save a copy of the default DPM table */ |
@@ -586,11 +807,6 @@ static int vega12_init_smc_table(struct pp_hwmgr *hwmgr) | |||
586 | struct phm_ppt_v3_information *pptable_information = | 807 | struct phm_ppt_v3_information *pptable_information = |
587 | (struct phm_ppt_v3_information *)hwmgr->pptable; | 808 | (struct phm_ppt_v3_information *)hwmgr->pptable; |
588 | 809 | ||
589 | result = vega12_setup_default_dpm_tables(hwmgr); | ||
590 | PP_ASSERT_WITH_CODE(!result, | ||
591 | "Failed to setup default DPM tables!", | ||
592 | return result); | ||
593 | |||
594 | result = pp_atomfwctrl_get_vbios_bootup_values(hwmgr, &boot_up_values); | 810 | result = pp_atomfwctrl_get_vbios_bootup_values(hwmgr, &boot_up_values); |
595 | if (!result) { | 811 | if (!result) { |
596 | data->vbios_boot_state.vddc = boot_up_values.usVddc; | 812 | data->vbios_boot_state.vddc = boot_up_values.usVddc; |
@@ -731,6 +947,10 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | |||
731 | "Failed to power control set level!", | 947 | "Failed to power control set level!", |
732 | return result); | 948 | return result); |
733 | 949 | ||
950 | result = vega12_setup_default_dpm_tables(hwmgr); | ||
951 | PP_ASSERT_WITH_CODE(!result, | ||
952 | "Failed to setup default DPM tables!", | ||
953 | return result); | ||
734 | return result; | 954 | return result; |
735 | } | 955 | } |
736 | 956 | ||
@@ -1633,33 +1853,25 @@ static int vega12_get_sclks(struct pp_hwmgr *hwmgr, | |||
1633 | struct pp_clock_levels_with_latency *clocks) | 1853 | struct pp_clock_levels_with_latency *clocks) |
1634 | { | 1854 | { |
1635 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | 1855 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); |
1856 | uint32_t ucount; | ||
1636 | int i; | 1857 | int i; |
1637 | uint32_t min, max, increments; | 1858 | struct vega12_single_dpm_table *dpm_table; |
1638 | 1859 | ||
1639 | if (!data->smu_features[GNLD_DPM_GFXCLK].enabled) | 1860 | if (!data->smu_features[GNLD_DPM_GFXCLK].enabled) |
1640 | return -1; | 1861 | return -1; |
1641 | 1862 | ||
1642 | PP_ASSERT_WITH_CODE( | 1863 | dpm_table = &(data->dpm_table.gfx_table); |
1643 | vega12_get_clock_ranges(hwmgr, &min, PPCLK_GFXCLK, false) == 0, | 1864 | ucount = (dpm_table->count > VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS) ? |
1644 | "[GetSclks]: fail to get min PPCLK_GFXCLK\n", | 1865 | VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS : dpm_table->count; |
1645 | return -1); | ||
1646 | PP_ASSERT_WITH_CODE( | ||
1647 | vega12_get_clock_ranges(hwmgr, &max, PPCLK_GFXCLK, true) == 0, | ||
1648 | "[GetSclks]: fail to get max PPCLK_GFXCLK\n", | ||
1649 | return -1); | ||
1650 | 1866 | ||
1651 | clocks->data[0].clocks_in_khz = min * 100; | 1867 | for (i = 0; i < ucount; i++) { |
1652 | increments = (max - min) / (VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS - 1); | 1868 | clocks->data[i].clocks_in_khz = |
1869 | dpm_table->dpm_levels[i].value * 100; | ||
1653 | 1870 | ||
1654 | for (i = 1; i < (VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS - 1); i++) { | 1871 | clocks->data[i].latency_in_us = 0; |
1655 | if ((min + (increments * i)) != 0) { | ||
1656 | clocks->data[i].clocks_in_khz = | ||
1657 | (min + increments * i) * 100; | ||
1658 | clocks->data[i].latency_in_us = 0; | ||
1659 | } | ||
1660 | } | 1872 | } |
1661 | clocks->data[i].clocks_in_khz = max * 100; | 1873 | |
1662 | clocks->num_levels = i + 1; | 1874 | clocks->num_levels = ucount; |
1663 | 1875 | ||
1664 | return 0; | 1876 | return 0; |
1665 | } | 1877 | } |
@@ -1674,44 +1886,26 @@ static int vega12_get_memclocks(struct pp_hwmgr *hwmgr, | |||
1674 | struct pp_clock_levels_with_latency *clocks) | 1886 | struct pp_clock_levels_with_latency *clocks) |
1675 | { | 1887 | { |
1676 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | 1888 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); |
1677 | uint32_t min, max, increments; | 1889 | uint32_t ucount; |
1678 | int i; | 1890 | int i; |
1679 | 1891 | struct vega12_single_dpm_table *dpm_table; | |
1680 | if (!data->smu_features[GNLD_DPM_UCLK].enabled) | 1892 | if (!data->smu_features[GNLD_DPM_UCLK].enabled) |
1681 | return -1; | 1893 | return -1; |
1682 | 1894 | ||
1683 | PP_ASSERT_WITH_CODE( | 1895 | dpm_table = &(data->dpm_table.mem_table); |
1684 | vega12_get_clock_ranges(hwmgr, &min, PPCLK_UCLK, false) == 0, | 1896 | ucount = (dpm_table->count > VG12_PSUEDO_NUM_UCLK_DPM_LEVELS) ? |
1685 | "[GetMclks]: fail to get min PPCLK_UCLK\n", | 1897 | VG12_PSUEDO_NUM_UCLK_DPM_LEVELS : dpm_table->count; |
1686 | return -1); | ||
1687 | PP_ASSERT_WITH_CODE( | ||
1688 | vega12_get_clock_ranges(hwmgr, &max, PPCLK_UCLK, true) == 0, | ||
1689 | "[GetMclks]: fail to get max PPCLK_UCLK\n", | ||
1690 | return -1); | ||
1691 | |||
1692 | clocks->data[0].clocks_in_khz = min * 100; | ||
1693 | clocks->data[0].latency_in_us = | ||
1694 | data->mclk_latency_table.entries[0].latency = | ||
1695 | vega12_get_mem_latency(hwmgr, min); | ||
1696 | 1898 | ||
1697 | increments = (max - min) / (VG12_PSUEDO_NUM_UCLK_DPM_LEVELS - 1); | 1899 | for (i = 0; i < ucount; i++) { |
1900 | clocks->data[i].clocks_in_khz = | ||
1901 | dpm_table->dpm_levels[i].value * 100; | ||
1698 | 1902 | ||
1699 | for (i = 1; i < (VG12_PSUEDO_NUM_UCLK_DPM_LEVELS - 1); i++) { | 1903 | clocks->data[i].latency_in_us = |
1700 | if ((min + (increments * i)) != 0) { | 1904 | data->mclk_latency_table.entries[i].latency = |
1701 | clocks->data[i].clocks_in_khz = | 1905 | vega12_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value); |
1702 | (min + (increments * i)) * 100; | ||
1703 | clocks->data[i].latency_in_us = | ||
1704 | data->mclk_latency_table.entries[i].latency = | ||
1705 | vega12_get_mem_latency(hwmgr, min + increments * i); | ||
1706 | } | ||
1707 | } | 1906 | } |
1708 | 1907 | ||
1709 | clocks->data[i].clocks_in_khz = max * 100; | 1908 | clocks->num_levels = data->mclk_latency_table.count = ucount; |
1710 | clocks->data[i].latency_in_us = | ||
1711 | data->mclk_latency_table.entries[i].latency = | ||
1712 | vega12_get_mem_latency(hwmgr, max); | ||
1713 | |||
1714 | clocks->num_levels = data->mclk_latency_table.count = i + 1; | ||
1715 | 1909 | ||
1716 | return 0; | 1910 | return 0; |
1717 | } | 1911 | } |
@@ -1720,33 +1914,26 @@ static int vega12_get_dcefclocks(struct pp_hwmgr *hwmgr, | |||
1720 | struct pp_clock_levels_with_latency *clocks) | 1914 | struct pp_clock_levels_with_latency *clocks) |
1721 | { | 1915 | { |
1722 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | 1916 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); |
1917 | uint32_t ucount; | ||
1723 | int i; | 1918 | int i; |
1724 | uint32_t min, max, increments; | 1919 | struct vega12_single_dpm_table *dpm_table; |
1725 | 1920 | ||
1726 | if (!data->smu_features[GNLD_DPM_DCEFCLK].enabled) | 1921 | if (!data->smu_features[GNLD_DPM_DCEFCLK].enabled) |
1727 | return -1; | 1922 | return -1; |
1728 | 1923 | ||
1729 | PP_ASSERT_WITH_CODE( | ||
1730 | vega12_get_clock_ranges(hwmgr, &min, PPCLK_DCEFCLK, false) == 0, | ||
1731 | "[GetDcfclocks]: fail to get min PPCLK_DCEFCLK\n", | ||
1732 | return -1); | ||
1733 | PP_ASSERT_WITH_CODE( | ||
1734 | vega12_get_clock_ranges(hwmgr, &max, PPCLK_DCEFCLK, true) == 0, | ||
1735 | "[GetDcfclocks]: fail to get max PPCLK_DCEFCLK\n", | ||
1736 | return -1); | ||
1737 | 1924 | ||
1738 | clocks->data[0].clocks_in_khz = min * 100; | 1925 | dpm_table = &(data->dpm_table.dcef_table); |
1739 | increments = (max - min) / (VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS - 1); | 1926 | ucount = (dpm_table->count > VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS) ? |
1927 | VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS : dpm_table->count; | ||
1928 | |||
1929 | for (i = 0; i < ucount; i++) { | ||
1930 | clocks->data[i].clocks_in_khz = | ||
1931 | dpm_table->dpm_levels[i].value * 100; | ||
1740 | 1932 | ||
1741 | for (i = 1; i < (VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS - 1); i++) { | 1933 | clocks->data[i].latency_in_us = 0; |
1742 | if ((min + (increments * i)) != 0) { | ||
1743 | clocks->data[i].clocks_in_khz = | ||
1744 | (min + increments * i) * 100; | ||
1745 | clocks->data[i].latency_in_us = 0; | ||
1746 | } | ||
1747 | } | 1934 | } |
1748 | clocks->data[i].clocks_in_khz = max * 100; | 1935 | |
1749 | clocks->num_levels = i + 1; | 1936 | clocks->num_levels = ucount; |
1750 | 1937 | ||
1751 | return 0; | 1938 | return 0; |
1752 | } | 1939 | } |
@@ -1755,34 +1942,26 @@ static int vega12_get_socclocks(struct pp_hwmgr *hwmgr, | |||
1755 | struct pp_clock_levels_with_latency *clocks) | 1942 | struct pp_clock_levels_with_latency *clocks) |
1756 | { | 1943 | { |
1757 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | 1944 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); |
1945 | uint32_t ucount; | ||
1758 | int i; | 1946 | int i; |
1759 | uint32_t min, max, increments; | 1947 | struct vega12_single_dpm_table *dpm_table; |
1760 | 1948 | ||
1761 | if (!data->smu_features[GNLD_DPM_SOCCLK].enabled) | 1949 | if (!data->smu_features[GNLD_DPM_SOCCLK].enabled) |
1762 | return -1; | 1950 | return -1; |
1763 | 1951 | ||
1764 | PP_ASSERT_WITH_CODE( | ||
1765 | vega12_get_clock_ranges(hwmgr, &min, PPCLK_SOCCLK, false) == 0, | ||
1766 | "[GetSocclks]: fail to get min PPCLK_SOCCLK\n", | ||
1767 | return -1); | ||
1768 | PP_ASSERT_WITH_CODE( | ||
1769 | vega12_get_clock_ranges(hwmgr, &max, PPCLK_SOCCLK, true) == 0, | ||
1770 | "[GetSocclks]: fail to get max PPCLK_SOCCLK\n", | ||
1771 | return -1); | ||
1772 | 1952 | ||
1773 | clocks->data[0].clocks_in_khz = min * 100; | 1953 | dpm_table = &(data->dpm_table.soc_table); |
1774 | increments = (max - min) / (VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS - 1); | 1954 | ucount = (dpm_table->count > VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS) ? |
1955 | VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS : dpm_table->count; | ||
1775 | 1956 | ||
1776 | for (i = 1; i < (VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS - 1); i++) { | 1957 | for (i = 0; i < ucount; i++) { |
1777 | if ((min + (increments * i)) != 0) { | 1958 | clocks->data[i].clocks_in_khz = |
1778 | clocks->data[i].clocks_in_khz = | 1959 | dpm_table->dpm_levels[i].value * 100; |
1779 | (min + increments * i) * 100; | 1960 | |
1780 | clocks->data[i].latency_in_us = 0; | 1961 | clocks->data[i].latency_in_us = 0; |
1781 | } | ||
1782 | } | 1962 | } |
1783 | 1963 | ||
1784 | clocks->data[i].clocks_in_khz = max * 100; | 1964 | clocks->num_levels = ucount; |
1785 | clocks->num_levels = i + 1; | ||
1786 | 1965 | ||
1787 | return 0; | 1966 | return 0; |
1788 | 1967 | ||
@@ -2374,6 +2553,7 @@ static int vega12_register_thermal_interrupt(struct pp_hwmgr *hwmgr, | |||
2374 | return 0; | 2553 | return 0; |
2375 | } | 2554 | } |
2376 | 2555 | ||
2556 | |||
2377 | static const struct pp_hwmgr_func vega12_hwmgr_funcs = { | 2557 | static const struct pp_hwmgr_func vega12_hwmgr_funcs = { |
2378 | .backend_init = vega12_hwmgr_backend_init, | 2558 | .backend_init = vega12_hwmgr_backend_init, |
2379 | .backend_fini = vega12_hwmgr_backend_fini, | 2559 | .backend_fini = vega12_hwmgr_backend_fini, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h index 80791d6e433c..644c7f0b7648 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h | |||
@@ -124,7 +124,7 @@ struct vega12_dpm_level { | |||
124 | }; | 124 | }; |
125 | 125 | ||
126 | #define VEGA12_MAX_DEEPSLEEP_DIVIDER_ID 5 | 126 | #define VEGA12_MAX_DEEPSLEEP_DIVIDER_ID 5 |
127 | #define MAX_REGULAR_DPM_NUMBER 8 | 127 | #define MAX_REGULAR_DPM_NUMBER 16 |
128 | #define MAX_PCIE_CONF 2 | 128 | #define MAX_PCIE_CONF 2 |
129 | #define VEGA12_MINIMUM_ENGINE_CLOCK 2500 | 129 | #define VEGA12_MINIMUM_ENGINE_CLOCK 2500 |
130 | 130 | ||