Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-next-5.5-2019-11-15' of git://people.freedesktop.org/~agd5f/linux into drm-next

drm-next-5.5-2019-11-15:

amdgpu:
- Fix AVFS handling on SMU7 parts with custom power tables
- Enable Overdrive sysfs interface for Navi parts
- Fix power limit handling on smu11 parts
- Fix pcie link sysfs output for Navi
- Probably cancel MM worker threads on shutdown

radeon:
- Cleanup for ppc change

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191115163516.3714-1-alexander.deucher@amd.com

+493 -39
+3
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 3110 3110 3111 3111 DRM_INFO("amdgpu: finishing device.\n"); 3112 3112 adev->shutdown = true; 3113 + 3114 + flush_delayed_work(&adev->delayed_init_work); 3115 + 3113 3116 /* disable all interrupts */ 3114 3117 amdgpu_irq_disable_all(adev); 3115 3118 if (adev->mode_info.mode_config_initialized){
+21 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 567 567 struct ta_xgmi_shared_memory *xgmi_cmd; 568 568 int ret; 569 569 570 - if (!psp->adev->psp.ta_fw) 570 + if (!psp->adev->psp.ta_fw || 571 + !psp->adev->psp.ta_xgmi_ucode_size || 572 + !psp->adev->psp.ta_xgmi_start_addr) 571 573 return -ENOENT; 572 574 573 575 if (!psp->xgmi_context.initialized) { ··· 779 777 { 780 778 int ret; 781 779 780 + if (!psp->adev->psp.ta_ras_ucode_size || 781 + !psp->adev->psp.ta_ras_start_addr) { 782 + dev_warn(psp->adev->dev, "RAS: ras ta ucode is not available\n"); 783 + return 0; 784 + } 785 + 782 786 if (!psp->ras.ras_initialized) { 783 787 ret = psp_ras_init_shared_buf(psp); 784 788 if (ret) ··· 873 865 static int psp_hdcp_initialize(struct psp_context *psp) 874 866 { 875 867 int ret; 868 + 869 + if (!psp->adev->psp.ta_hdcp_ucode_size || 870 + !psp->adev->psp.ta_hdcp_start_addr) { 871 + dev_warn(psp->adev->dev, "HDCP: hdcp ta ucode is not available\n"); 872 + return 0; 873 + } 876 874 877 875 if (!psp->hdcp_context.hdcp_initialized) { 878 876 ret = psp_hdcp_init_shared_buf(psp); ··· 1052 1038 static int psp_dtm_initialize(struct psp_context *psp) 1053 1039 { 1054 1040 int ret; 1041 + 1042 + if (!psp->adev->psp.ta_dtm_ucode_size || 1043 + !psp->adev->psp.ta_dtm_start_addr) { 1044 + dev_warn(psp->adev->dev, "DTM: dtm ta ucode is not available\n"); 1045 + return 0; 1046 + } 1055 1047 1056 1048 if (!psp->dtm_context.dtm_initialized) { 1057 1049 ret = psp_dtm_init_shared_buf(psp);
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
··· 299 299 { 300 300 int i, j; 301 301 302 + cancel_delayed_work_sync(&adev->uvd.idle_work); 302 303 drm_sched_entity_destroy(&adev->uvd.entity); 303 304 304 305 for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
··· 216 216 if (adev->vce.vcpu_bo == NULL) 217 217 return 0; 218 218 219 + cancel_delayed_work_sync(&adev->vce.idle_work); 219 220 drm_sched_entity_destroy(&adev->vce.entity); 220 221 221 222 amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr,
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
··· 193 193 { 194 194 int i, j; 195 195 196 + cancel_delayed_work_sync(&adev->vcn.idle_work); 197 + 196 198 if (adev->vcn.indirect_sram) { 197 199 amdgpu_bo_free_kernel(&adev->vcn.dpg_sram_bo, 198 200 &adev->vcn.dpg_sram_gpu_addr,
+17 -5
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
··· 1068 1068 return ret; 1069 1069 1070 1070 if (adev->asic_type != CHIP_ARCTURUS) { 1071 - ret = smu_override_pcie_parameters(smu); 1072 - if (ret) 1073 - return ret; 1074 - 1075 1071 ret = smu_notify_display_change(smu); 1076 1072 if (ret) 1077 1073 return ret; ··· 1096 1100 return ret; 1097 1101 } 1098 1102 1103 + if (adev->asic_type != CHIP_ARCTURUS) { 1104 + ret = smu_override_pcie_parameters(smu); 1105 + if (ret) 1106 + return ret; 1107 + } 1108 + 1099 1109 ret = smu_set_default_od_settings(smu, initialize); 1100 1110 if (ret) 1101 1111 return ret; ··· 1111 1109 if (ret) 1112 1110 return ret; 1113 1111 1114 - ret = smu_get_power_limit(smu, &smu->default_power_limit, true, false); 1112 + ret = smu_get_power_limit(smu, &smu->default_power_limit, false, false); 1115 1113 if (ret) 1116 1114 return ret; 1117 1115 } ··· 2510 2508 ret = smu->ppt_funcs->get_dpm_clock_table(smu, clock_table); 2511 2509 2512 2510 mutex_unlock(&smu->mutex); 2511 + 2512 + return ret; 2513 + } 2514 + 2515 + uint32_t smu_get_pptable_power_limit(struct smu_context *smu) 2516 + { 2517 + uint32_t ret = 0; 2518 + 2519 + if (smu->ppt_funcs->get_pptable_power_limit) 2520 + ret = smu->ppt_funcs->get_pptable_power_limit(smu); 2513 2521 2514 2522 return ret; 2515 2523 }
+12 -11
drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
··· 1261 1261 1262 1262 static int arcturus_get_power_limit(struct smu_context *smu, 1263 1263 uint32_t *limit, 1264 - bool asic_default) 1264 + bool cap) 1265 1265 { 1266 1266 PPTable_t *pptable = smu->smu_table.driver_pptable; 1267 1267 uint32_t asic_default_power_limit = 0; 1268 1268 int ret = 0; 1269 1269 int power_src; 1270 1270 1271 - if (!smu->default_power_limit || 1272 - !smu->power_limit) { 1271 + if (!smu->power_limit) { 1273 1272 if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { 1274 1273 power_src = smu_power_get_index(smu, SMU_POWER_SOURCE_AC); 1275 1274 if (power_src < 0) ··· 1291 1292 pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; 1292 1293 } 1293 1294 1294 - if (smu->od_enabled) { 1295 - asic_default_power_limit *= (100 + smu->smu_table.TDPODLimit); 1296 - asic_default_power_limit /= 100; 1297 - } 1298 - 1299 - smu->default_power_limit = asic_default_power_limit; 1300 1295 smu->power_limit = asic_default_power_limit; 1301 1296 } 1302 1297 1303 - if (asic_default) 1304 - *limit = smu->default_power_limit; 1298 + if (cap) 1299 + *limit = smu_v11_0_get_max_power_limit(smu); 1305 1300 else 1306 1301 *limit = smu->power_limit; 1307 1302 ··· 2063 2070 i2c_del_adapter(control); 2064 2071 } 2065 2072 2073 + static uint32_t arcturus_get_pptable_power_limit(struct smu_context *smu) 2074 + { 2075 + PPTable_t *pptable = smu->smu_table.driver_pptable; 2076 + 2077 + return pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; 2078 + } 2079 + 2066 2080 static const struct pptable_funcs arcturus_ppt_funcs = { 2067 2081 /* translate smu index into arcturus specific index */ 2068 2082 .get_smu_msg_index = arcturus_get_smu_msg_index, ··· 2160 2160 .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, 2161 2161 .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, 2162 2162 .override_pcie_parameters = smu_v11_0_override_pcie_parameters, 2163 + .get_pptable_power_limit = arcturus_get_pptable_power_limit, 2163 2164 }; 2164 2165 2165 2166 void arcturus_set_ppt_funcs(struct smu_context *smu)
+7
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
··· 3969 3969 "Failed to populate and upload SCLK MCLK DPM levels!", 3970 3970 result = tmp_result); 3971 3971 3972 + /* 3973 + * If a custom pp table is loaded, set DPMTABLE_OD_UPDATE_VDDC flag. 3974 + * That effectively disables AVFS feature. 3975 + */ 3976 + if (hwmgr->hardcode_pp_table != NULL) 3977 + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC; 3978 + 3972 3979 tmp_result = smu7_update_avfs(hwmgr); 3973 3980 PP_ASSERT_WITH_CODE((0 == tmp_result), 3974 3981 "Failed to update avfs voltages!",
+3 -1
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
··· 261 261 struct smu_table *tables; 262 262 struct smu_table memory_pool; 263 263 uint8_t thermal_controller_type; 264 - uint16_t TDPODLimit; 265 264 266 265 void *overdrive_table; 267 266 }; ··· 547 548 int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max); 548 549 int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max); 549 550 int (*override_pcie_parameters)(struct smu_context *smu); 551 + uint32_t (*get_pptable_power_limit)(struct smu_context *smu); 550 552 }; 551 553 552 554 int smu_load_microcode(struct smu_context *smu); ··· 716 716 717 717 int smu_get_dpm_clock_table(struct smu_context *smu, 718 718 struct dpm_clocks *clock_table); 719 + 720 + uint32_t smu_get_pptable_power_limit(struct smu_context *smu); 719 721 720 722 #endif
+12
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
··· 48 48 49 49 #define SMU11_TOOL_SIZE 0x19000 50 50 51 + #define MAX_PCIE_CONF 2 52 + 51 53 #define CLK_MAP(clk, index) \ 52 54 [SMU_##clk] = {1, (index)} 53 55 ··· 90 88 uint32_t max; /* MHz */ 91 89 }; 92 90 91 + struct smu_11_0_pcie_table { 92 + uint8_t pcie_gen[MAX_PCIE_CONF]; 93 + uint8_t pcie_lane[MAX_PCIE_CONF]; 94 + }; 95 + 93 96 struct smu_11_0_dpm_tables { 94 97 struct smu_11_0_dpm_table soc_table; 95 98 struct smu_11_0_dpm_table gfx_table; ··· 107 100 struct smu_11_0_dpm_table display_table; 108 101 struct smu_11_0_dpm_table phy_table; 109 102 struct smu_11_0_dpm_table fclk_table; 103 + struct smu_11_0_pcie_table pcie_table; 110 104 }; 111 105 112 106 struct smu_11_0_dpm_context { ··· 257 249 uint32_t min, uint32_t max); 258 250 259 251 int smu_v11_0_override_pcie_parameters(struct smu_context *smu); 252 + 253 + int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size); 254 + 255 + uint32_t smu_v11_0_get_max_power_limit(struct smu_context *smu); 260 256 261 257 #endif
+2
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0_pptable.h
··· 141 141 struct smu_11_0_power_saving_clock_table power_saving_clock; 142 142 struct smu_11_0_overdrive_table overdrive_table; 143 143 144 + #ifndef SMU_11_0_PARTIAL_PPTABLE 144 145 PPTable_t smc_pptable; //PPTable_t in smu11_driver_if.h 146 + #endif 145 147 } __attribute__((packed)); 146 148 147 149 #endif
+340 -11
drivers/gpu/drm/amd/powerplay/navi10_ppt.c
··· 36 36 #include "navi10_ppt.h" 37 37 #include "smu_v11_0_pptable.h" 38 38 #include "smu_v11_0_ppsmc.h" 39 + #include "nbio/nbio_7_4_sh_mask.h" 39 40 40 41 #include "asic_reg/mp/mp_11_0_sh_mask.h" 41 42 ··· 600 599 struct smu_table_context *table_context = &smu->smu_table; 601 600 struct smu_11_0_dpm_context *dpm_context = smu_dpm->dpm_context; 602 601 PPTable_t *driver_ppt = NULL; 602 + int i; 603 603 604 604 driver_ppt = table_context->driver_pptable; 605 605 ··· 630 628 631 629 dpm_context->dpm_tables.phy_table.min = driver_ppt->FreqTablePhyclk[0]; 632 630 dpm_context->dpm_tables.phy_table.max = driver_ppt->FreqTablePhyclk[NUM_PHYCLK_DPM_LEVELS - 1]; 631 + 632 + for (i = 0; i < MAX_PCIE_CONF; i++) { 633 + dpm_context->dpm_tables.pcie_table.pcie_gen[i] = driver_ppt->PcieGenSpeed[i]; 634 + dpm_context->dpm_tables.pcie_table.pcie_lane[i] = driver_ppt->PcieLaneCount[i]; 635 + } 633 636 634 637 return 0; 635 638 } ··· 698 691 return dpm_desc->SnapToDiscrete == 0 ? true : false; 699 692 } 700 693 694 + static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_ID feature) 695 + { 696 + return od_table->cap[feature]; 697 + } 698 + 699 + 701 700 static int navi10_print_clk_levels(struct smu_context *smu, 702 701 enum smu_clk_type clk_type, char *buf) 703 702 { 703 + uint16_t *curve_settings; 704 704 int i, size = 0, ret = 0; 705 705 uint32_t cur_value = 0, value = 0, count = 0; 706 706 uint32_t freq_values[3] = {0}; 707 707 uint32_t mark_index = 0; 708 + struct smu_table_context *table_context = &smu->smu_table; 709 + uint32_t gen_speed, lane_width; 710 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 711 + struct smu_11_0_dpm_context *dpm_context = smu_dpm->dpm_context; 712 + struct amdgpu_device *adev = smu->adev; 713 + PPTable_t *pptable = (PPTable_t *)table_context->driver_pptable; 714 + OverDriveTable_t *od_table = 715 + (OverDriveTable_t *)table_context->overdrive_table; 716 + struct smu_11_0_overdrive_table *od_settings = smu->od_settings; 708 717 709 718 switch (clk_type) { 710 719 case SMU_GFXCLK: ··· 769 746 i == mark_index ? "*" : ""); 770 747 } 771 748 749 + } 750 + break; 751 + case SMU_PCIE: 752 + gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & 753 + PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) 754 + >> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; 755 + lane_width = (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & 756 + PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK) 757 + >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; 758 + for (i = 0; i < NUM_LINK_LEVELS; i++) 759 + size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, 760 + (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 0) ? "2.5GT/s," : 761 + (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 1) ? "5.0GT/s," : 762 + (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 2) ? "8.0GT/s," : 763 + (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 3) ? "16.0GT/s," : "", 764 + (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 1) ? "x1" : 765 + (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 2) ? "x2" : 766 + (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 3) ? "x4" : 767 + (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 4) ? "x8" : 768 + (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 5) ? "x12" : 769 + (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 6) ? "x16" : "", 770 + pptable->LclkFreq[i], 771 + (gen_speed == dpm_context->dpm_tables.pcie_table.pcie_gen[i]) && 772 + (lane_width == dpm_context->dpm_tables.pcie_table.pcie_lane[i]) ? 773 + "*" : ""); 774 + break; 775 + case SMU_OD_SCLK: 776 + if (!smu->od_enabled || !od_table || !od_settings) 777 + break; 778 + if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS)) 779 + break; 780 + size += sprintf(buf + size, "OD_SCLK:\n"); 781 + size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax); 782 + break; 783 + case SMU_OD_MCLK: 784 + if (!smu->od_enabled || !od_table || !od_settings) 785 + break; 786 + if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX)) 787 + break; 788 + size += sprintf(buf + size, "OD_MCLK:\n"); 789 + size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax); 790 + break; 791 + case SMU_OD_VDDC_CURVE: 792 + if (!smu->od_enabled || !od_table || !od_settings) 793 + break; 794 + if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE)) 795 + break; 796 + size += sprintf(buf + size, "OD_VDDC_CURVE:\n"); 797 + for (i = 0; i < 3; i++) { 798 + switch (i) { 799 + case 0: 800 + curve_settings = &od_table->GfxclkFreq1; 801 + break; 802 + case 1: 803 + curve_settings = &od_table->GfxclkFreq2; 804 + break; 805 + case 2: 806 + curve_settings = &od_table->GfxclkFreq3; 807 + break; 808 + default: 809 + break; 810 + } 811 + size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE); 772 812 } 773 813 break; 774 814 default: ··· 1668 1582 return ret; 1669 1583 } 1670 1584 1585 + static uint32_t navi10_get_pptable_power_limit(struct smu_context *smu) 1586 + { 1587 + PPTable_t *pptable = smu->smu_table.driver_pptable; 1588 + return pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; 1589 + } 1590 + 1671 1591 static int navi10_get_power_limit(struct smu_context *smu, 1672 1592 uint32_t *limit, 1673 - bool asic_default) 1593 + bool cap) 1674 1594 { 1675 1595 PPTable_t *pptable = smu->smu_table.driver_pptable; 1676 1596 uint32_t asic_default_power_limit = 0; 1677 1597 int ret = 0; 1678 1598 int power_src; 1679 1599 1680 - if (!smu->default_power_limit || 1681 - !smu->power_limit) { 1600 + if (!smu->power_limit) { 1682 1601 if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { 1683 1602 power_src = smu_power_get_index(smu, SMU_POWER_SOURCE_AC); 1684 1603 if (power_src < 0) ··· 1706 1615 pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; 1707 1616 } 1708 1617 1709 - if (smu->od_enabled) { 1710 - asic_default_power_limit *= (100 + smu->smu_table.TDPODLimit); 1711 - asic_default_power_limit /= 100; 1712 - } 1713 - 1714 - smu->default_power_limit = asic_default_power_limit; 1715 1618 smu->power_limit = asic_default_power_limit; 1716 1619 } 1717 1620 1718 - if (asic_default) 1719 - *limit = smu->default_power_limit; 1621 + if (cap) 1622 + *limit = smu_v11_0_get_max_power_limit(smu); 1720 1623 else 1721 1624 *limit = smu->power_limit; 1722 1625 ··· 1725 1640 int ret, i; 1726 1641 uint32_t smu_pcie_arg; 1727 1642 1643 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 1644 + struct smu_11_0_dpm_context *dpm_context = smu_dpm->dpm_context; 1645 + 1728 1646 for (i = 0; i < NUM_LINK_LEVELS; i++) { 1729 1647 smu_pcie_arg = (i << 16) | 1730 1648 ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) : ··· 1736 1648 ret = smu_send_smc_msg_with_param(smu, 1737 1649 SMU_MSG_OverridePcieParameters, 1738 1650 smu_pcie_arg); 1651 + 1652 + if (ret) 1653 + return ret; 1654 + 1655 + if (pptable->PcieGenSpeed[i] > pcie_gen_cap) 1656 + dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pcie_gen_cap; 1657 + if (pptable->PcieLaneCount[i] > pcie_width_cap) 1658 + dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pcie_width_cap; 1659 + } 1660 + 1661 + return 0; 1662 + } 1663 + 1664 + static inline void navi10_dump_od_table(OverDriveTable_t *od_table) { 1665 + pr_debug("OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table->GfxclkFmax); 1666 + pr_debug("OD: Gfx1: (%d, %d)\n", od_table->GfxclkFreq1, od_table->GfxclkVolt1); 1667 + pr_debug("OD: Gfx2: (%d, %d)\n", od_table->GfxclkFreq2, od_table->GfxclkVolt2); 1668 + pr_debug("OD: Gfx3: (%d, %d)\n", od_table->GfxclkFreq3, od_table->GfxclkVolt3); 1669 + pr_debug("OD: UclkFmax: %d\n", od_table->UclkFmax); 1670 + pr_debug("OD: OverDrivePct: %d\n", od_table->OverDrivePct); 1671 + } 1672 + 1673 + static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODSETTING_ID setting, uint32_t value) 1674 + { 1675 + if (value < od_table->min[setting]) { 1676 + pr_warn("OD setting (%d, %d) is less than the minimum allowed (%d)\n", setting, value, od_table->min[setting]); 1677 + return -EINVAL; 1678 + } 1679 + if (value > od_table->max[setting]) { 1680 + pr_warn("OD setting (%d, %d) is greater than the maximum allowed (%d)\n", setting, value, od_table->max[setting]); 1681 + return -EINVAL; 1682 + } 1683 + return 0; 1684 + } 1685 + 1686 + static int navi10_setup_od_limits(struct smu_context *smu) { 1687 + struct smu_11_0_overdrive_table *overdrive_table = NULL; 1688 + struct smu_11_0_powerplay_table *powerplay_table = NULL; 1689 + 1690 + if (!smu->smu_table.power_play_table) { 1691 + pr_err("powerplay table uninitialized!\n"); 1692 + return -ENOENT; 1693 + } 1694 + powerplay_table = (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table; 1695 + overdrive_table = &powerplay_table->overdrive_table; 1696 + if (!smu->od_settings) { 1697 + smu->od_settings = kmemdup(overdrive_table, sizeof(struct smu_11_0_overdrive_table), GFP_KERNEL); 1698 + } else { 1699 + memcpy(smu->od_settings, overdrive_table, sizeof(struct smu_11_0_overdrive_table)); 1700 + } 1701 + return 0; 1702 + } 1703 + 1704 + static int navi10_set_default_od_settings(struct smu_context *smu, bool initialize) { 1705 + OverDriveTable_t *od_table; 1706 + int ret = 0; 1707 + 1708 + ret = smu_v11_0_set_default_od_settings(smu, initialize, sizeof(OverDriveTable_t)); 1709 + if (ret) 1710 + return ret; 1711 + 1712 + if (initialize) { 1713 + ret = navi10_setup_od_limits(smu); 1714 + if (ret) { 1715 + pr_err("Failed to retrieve board OD limits\n"); 1716 + return ret; 1717 + } 1718 + 1719 + } 1720 + 1721 + od_table = (OverDriveTable_t *)smu->smu_table.overdrive_table; 1722 + if (od_table) { 1723 + navi10_dump_od_table(od_table); 1739 1724 } 1740 1725 1741 1726 return ret; 1742 1727 } 1743 1728 1729 + static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) { 1730 + int i; 1731 + int ret = 0; 1732 + struct smu_table_context *table_context = &smu->smu_table; 1733 + OverDriveTable_t *od_table; 1734 + struct smu_11_0_overdrive_table *od_settings; 1735 + enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting; 1736 + uint16_t *freq_ptr, *voltage_ptr; 1737 + od_table = (OverDriveTable_t *)table_context->overdrive_table; 1738 + 1739 + if (!smu->od_enabled) { 1740 + pr_warn("OverDrive is not enabled!\n"); 1741 + return -EINVAL; 1742 + } 1743 + 1744 + if (!smu->od_settings) { 1745 + pr_err("OD board limits are not set!\n"); 1746 + return -ENOENT; 1747 + } 1748 + 1749 + od_settings = smu->od_settings; 1750 + 1751 + switch (type) { 1752 + case PP_OD_EDIT_SCLK_VDDC_TABLE: 1753 + if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS)) { 1754 + pr_warn("GFXCLK_LIMITS not supported!\n"); 1755 + return -ENOTSUPP; 1756 + } 1757 + if (!table_context->overdrive_table) { 1758 + pr_err("Overdrive is not initialized\n"); 1759 + return -EINVAL; 1760 + } 1761 + for (i = 0; i < size; i += 2) { 1762 + if (i + 2 > size) { 1763 + pr_info("invalid number of input parameters %d\n", size); 1764 + return -EINVAL; 1765 + } 1766 + switch (input[i]) { 1767 + case 0: 1768 + freq_setting = SMU_11_0_ODSETTING_GFXCLKFMIN; 1769 + freq_ptr = &od_table->GfxclkFmin; 1770 + if (input[i + 1] > od_table->GfxclkFmax) { 1771 + pr_info("GfxclkFmin (%ld) must be <= GfxclkFmax (%u)!\n", 1772 + input[i + 1], 1773 + od_table->GfxclkFmin); 1774 + return -EINVAL; 1775 + } 1776 + break; 1777 + case 1: 1778 + freq_setting = SMU_11_0_ODSETTING_GFXCLKFMAX; 1779 + freq_ptr = &od_table->GfxclkFmax; 1780 + if (input[i + 1] < od_table->GfxclkFmin) { 1781 + pr_info("GfxclkFmax (%ld) must be >= GfxclkFmin (%u)!\n", 1782 + input[i + 1], 1783 + od_table->GfxclkFmax); 1784 + return -EINVAL; 1785 + } 1786 + break; 1787 + default: 1788 + pr_info("Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]); 1789 + pr_info("Supported indices: [0:min,1:max]\n"); 1790 + return -EINVAL; 1791 + } 1792 + ret = navi10_od_setting_check_range(od_settings, freq_setting, input[i + 1]); 1793 + if (ret) 1794 + return ret; 1795 + *freq_ptr = input[i + 1]; 1796 + } 1797 + break; 1798 + case PP_OD_EDIT_MCLK_VDDC_TABLE: 1799 + if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX)) { 1800 + pr_warn("UCLK_MAX not supported!\n"); 1801 + return -ENOTSUPP; 1802 + } 1803 + if (size < 2) { 1804 + pr_info("invalid number of parameters: %d\n", size); 1805 + return -EINVAL; 1806 + } 1807 + if (input[0] != 1) { 1808 + pr_info("Invalid MCLK_VDDC_TABLE index: %ld\n", input[0]); 1809 + pr_info("Supported indices: [1:max]\n"); 1810 + return -EINVAL; 1811 + } 1812 + ret = navi10_od_setting_check_range(od_settings, SMU_11_0_ODSETTING_UCLKFMAX, input[1]); 1813 + if (ret) 1814 + return ret; 1815 + od_table->UclkFmax = input[1]; 1816 + break; 1817 + case PP_OD_COMMIT_DPM_TABLE: 1818 + navi10_dump_od_table(od_table); 1819 + ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, true); 1820 + if (ret) { 1821 + pr_err("Failed to import overdrive table!\n"); 1822 + return ret; 1823 + } 1824 + // no lock needed because smu_od_edit_dpm_table has it 1825 + ret = smu_handle_task(smu, smu->smu_dpm.dpm_level, 1826 + AMD_PP_TASK_READJUST_POWER_STATE, 1827 + false); 1828 + if (ret) { 1829 + return ret; 1830 + } 1831 + break; 1832 + case PP_OD_EDIT_VDDC_CURVE: 1833 + if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE)) { 1834 + pr_warn("GFXCLK_CURVE not supported!\n"); 1835 + return -ENOTSUPP; 1836 + } 1837 + if (size < 3) { 1838 + pr_info("invalid number of parameters: %d\n", size); 1839 + return -EINVAL; 1840 + } 1841 + if (!od_table) { 1842 + pr_info("Overdrive is not initialized\n"); 1843 + return -EINVAL; 1844 + } 1845 + 1846 + switch (input[0]) { 1847 + case 0: 1848 + freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1; 1849 + voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1; 1850 + freq_ptr = &od_table->GfxclkFreq1; 1851 + voltage_ptr = &od_table->GfxclkVolt1; 1852 + break; 1853 + case 1: 1854 + freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2; 1855 + voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2; 1856 + freq_ptr = &od_table->GfxclkFreq2; 1857 + voltage_ptr = &od_table->GfxclkVolt2; 1858 + break; 1859 + case 2: 1860 + freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3; 1861 + voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3; 1862 + freq_ptr = &od_table->GfxclkFreq3; 1863 + voltage_ptr = &od_table->GfxclkVolt3; 1864 + break; 1865 + default: 1866 + pr_info("Invalid VDDC_CURVE index: %ld\n", input[0]); 1867 + pr_info("Supported indices: [0, 1, 2]\n"); 1868 + return -EINVAL; 1869 + } 1870 + ret = navi10_od_setting_check_range(od_settings, freq_setting, input[1]); 1871 + if (ret) 1872 + return ret; 1873 + // Allow setting zero to disable the OverDrive VDDC curve 1874 + if (input[2] != 0) { 1875 + ret = navi10_od_setting_check_range(od_settings, voltage_setting, input[2]); 1876 + if (ret) 1877 + return ret; 1878 + *freq_ptr = input[1]; 1879 + *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE; 1880 + pr_debug("OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr, *voltage_ptr); 1881 + } else { 1882 + // If setting 0, disable all voltage curve settings 1883 + od_table->GfxclkVolt1 = 0; 1884 + od_table->GfxclkVolt2 = 0; 1885 + od_table->GfxclkVolt3 = 0; 1886 + } 1887 + navi10_dump_od_table(od_table); 1888 + break; 1889 + default: 1890 + return -ENOSYS; 1891 + } 1892 + return ret; 1893 + } 1744 1894 1745 1895 static const struct pptable_funcs navi10_ppt_funcs = { 1746 1896 .tables_init = navi10_tables_init, ··· 2068 1742 .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, 2069 1743 .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, 2070 1744 .override_pcie_parameters = smu_v11_0_override_pcie_parameters, 1745 + .set_default_od_settings = navi10_set_default_od_settings, 1746 + .od_edit_dpm_table = navi10_od_edit_dpm_table, 1747 + .get_pptable_power_limit = navi10_get_pptable_power_limit, 2071 1748 }; 2072 1749 2073 1750 void navi10_set_ppt_funcs(struct smu_context *smu)
+5
drivers/gpu/drm/amd/powerplay/navi10_ppt.h
··· 33 33 #define NAVI14_UMD_PSTATE_PEAK_XTX_GFXCLK (1717) 34 34 #define NAVI14_UMD_PSTATE_PEAK_XL_GFXCLK (1448) 35 35 36 + #define NAVI10_VOLTAGE_SCALE (4) 37 + 38 + #define smnPCIE_LC_SPEED_CNTL 0x11140290 39 + #define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288 40 + 36 41 extern void navi10_set_ppt_funcs(struct smu_context *smu); 37 42 38 43 #endif
+64 -3
drivers/gpu/drm/amd/powerplay/smu_v11_0.c
··· 24 24 #include <linux/module.h> 25 25 #include <linux/pci.h> 26 26 27 + #define SMU_11_0_PARTIAL_PPTABLE 28 + 27 29 #include "pp_debug.h" 28 30 #include "amdgpu.h" 29 31 #include "amdgpu_smu.h" ··· 33 31 #include "atomfirmware.h" 34 32 #include "amdgpu_atomfirmware.h" 35 33 #include "smu_v11_0.h" 34 + #include "smu_v11_0_pptable.h" 36 35 #include "soc15_common.h" 37 36 #include "atom.h" 38 37 #include "amd_pcie.h" ··· 1048 1045 return 0; 1049 1046 } 1050 1047 1048 + uint32_t smu_v11_0_get_max_power_limit(struct smu_context *smu) { 1049 + uint32_t od_limit, max_power_limit; 1050 + struct smu_11_0_powerplay_table *powerplay_table = NULL; 1051 + struct smu_table_context *table_context = &smu->smu_table; 1052 + powerplay_table = table_context->power_play_table; 1053 + 1054 + max_power_limit = smu_get_pptable_power_limit(smu); 1055 + 1056 + if (!max_power_limit) { 1057 + // If we couldn't get the table limit, fall back on first-read value 1058 + if (!smu->default_power_limit) 1059 + smu->default_power_limit = smu->power_limit; 1060 + max_power_limit = smu->default_power_limit; 1061 + } 1062 + 1063 + if (smu->od_enabled) { 1064 + od_limit = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); 1065 + 1066 + pr_debug("ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_limit, smu->default_power_limit); 1067 + 1068 + max_power_limit *= (100 + od_limit); 1069 + max_power_limit /= 100; 1070 + } 1071 + 1072 + return max_power_limit; 1073 + } 1074 + 1051 1075 int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n) 1052 1076 { 1053 1077 int ret = 0; 1078 + uint32_t max_power_limit; 1054 1079 1055 - if (n > smu->default_power_limit) { 1056 - pr_err("New power limit is over the max allowed %d\n", 1057 - smu->default_power_limit); 1080 + max_power_limit = smu_v11_0_get_max_power_limit(smu); 1081 + 1082 + if (n > max_power_limit) { 1083 + pr_err("New power limit (%d) is over the max allowed %d\n", 1084 + n, 1085 + max_power_limit); 1058 1086 return -EINVAL; 1059 1087 } 1060 1088 ··· 1812 1778 1813 1779 return ret; 1814 1780 1781 + } 1782 + 1783 + int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size) 1784 + { 1785 + struct smu_table_context *table_context = &smu->smu_table; 1786 + int ret = 0; 1787 + 1788 + if (initialize) { 1789 + if (table_context->overdrive_table) { 1790 + return -EINVAL; 1791 + } 1792 + table_context->overdrive_table = kzalloc(overdrive_table_size, GFP_KERNEL); 1793 + if (!table_context->overdrive_table) { 1794 + return -ENOMEM; 1795 + } 1796 + ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, false); 1797 + if (ret) { 1798 + pr_err("Failed to export overdrive table!\n"); 1799 + return ret; 1800 + } 1801 + } 1802 + ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, true); 1803 + if (ret) { 1804 + pr_err("Failed to import overdrive table!\n"); 1805 + return ret; 1806 + } 1807 + return ret; 1815 1808 }
-1
drivers/gpu/drm/amd/powerplay/vega20_ppt.c
··· 466 466 sizeof(PPTable_t)); 467 467 468 468 table_context->thermal_controller_type = powerplay_table->ucThermalControllerType; 469 - table_context->TDPODLimit = le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE]); 470 469 471 470 return 0; 472 471 }
+3 -6
drivers/gpu/drm/radeon/radeon_drv.c
··· 379 379 static void 380 380 radeon_pci_shutdown(struct pci_dev *pdev) 381 381 { 382 - #ifdef CONFIG_PPC64 383 - struct drm_device *ddev = pci_get_drvdata(pdev); 384 - #endif 385 - 386 382 /* if we are running in a VM, make sure the device 387 383 * torn down properly on reboot/shutdown 388 384 */ ··· 386 390 radeon_pci_remove(pdev); 387 391 388 392 #ifdef CONFIG_PPC64 389 - /* Some adapters need to be suspended before a 393 + /* 394 + * Some adapters need to be suspended before a 390 395 * shutdown occurs in order to prevent an error 391 396 * during kexec. 392 397 * Make this power specific becauase it breaks 393 398 * some non-power boards. 394 399 */ 395 - radeon_suspend_kms(ddev, true, true, false); 400 + radeon_suspend_kms(pci_get_drvdata(pdev), true, true, false); 396 401 #endif 397 402 } 398 403