- OD fixes for powerplay - Vega20 fixes - KFD fix for Kaveri - add missing firmware declaration for hainan (SI chip) - Fix DC user experience regressions related to panels that support >8 bpc
Unified · Split
| @@ -501,8 +501,11 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle) · 500 unmodified lines | ||
| 501 | 501 | { |
| 502 | 502 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
| 503 | 503 | |
| 504 | − amdgpu_dpm_switch_power_profile(adev, | |
| 505 | − PP_SMC_POWER_PROFILE_COMPUTE, !idle); | |
| 504 | + if (adev->powerplay.pp_funcs && | |
| 505 | + adev->powerplay.pp_funcs->switch_power_profile) | |
| 506 | + amdgpu_dpm_switch_power_profile(adev, | |
| 507 | + PP_SMC_POWER_PROFILE_COMPUTE, | |
| 508 | + !idle); | |
| 506 | 509 | } |
| 507 | 510 | |
| 508 | 511 | bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid) |
| @@ -626,6 +626,13 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev) · 625 unmodified lines | ||
| 626 | 626 | "dither", |
| 627 | 627 | amdgpu_dither_enum_list, sz); |
| 628 | 628 | |
| 629 | + if (amdgpu_device_has_dc_support(adev)) { | |
| 630 | + adev->mode_info.max_bpc_property = | |
| 631 | + drm_property_create_range(adev->ddev, 0, "max bpc", 8, 16); | |
| 632 | + if (!adev->mode_info.max_bpc_property) | |
| 633 | + return -ENOMEM; | |
| 634 | + } | |
| 635 | + | |
| 629 | 636 | return 0; |
| 630 | 637 | } |
| 631 | 638 | |
| @@ -339,6 +339,8 @@ struct amdgpu_mode_info { · 338 unmodified lines | ||
| 339 | 339 | struct drm_property *audio_property; |
| 340 | 340 | /* FMT dithering */ |
| 341 | 341 | struct drm_property *dither_property; |
| 342 | + /* maximum number of bits per channel for monitor color */ | |
| 343 | + struct drm_property *max_bpc_property; | |
| 342 | 344 | /* hardcoded DFP edid from BIOS */ |
| 343 | 345 | struct edid *bios_hardcoded_edid; |
| 344 | 346 | int bios_hardcoded_edid_size; |
| @@ -46,6 +46,7 @@ MODULE_FIRMWARE("amdgpu/tahiti_mc.bin"); · 45 unmodified lines | ||
| 46 | 46 | MODULE_FIRMWARE("amdgpu/pitcairn_mc.bin"); |
| 47 | 47 | MODULE_FIRMWARE("amdgpu/verde_mc.bin"); |
| 48 | 48 | MODULE_FIRMWARE("amdgpu/oland_mc.bin"); |
| 49 | +MODULE_FIRMWARE("amdgpu/hainan_mc.bin"); | |
| 49 | 50 | MODULE_FIRMWARE("amdgpu/si58_mc.bin"); |
| 50 | 51 | |
| 51 | 52 | #define MC_SEQ_MISC0__MT__MASK 0xf0000000 |
| @@ -65,6 +65,13 @@ · 64 unmodified lines | ||
| 65 | 65 | #define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba |
| 66 | 66 | #define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX 0 |
| 67 | 67 | |
| 68 | +/* for Vega20 register name change */ | |
| 69 | +#define mmHDP_MEM_POWER_CTRL 0x00d4 | |
| 70 | +#define HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK 0x00000001L | |
| 71 | +#define HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK 0x00000002L | |
| 72 | +#define HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK 0x00010000L | |
| 73 | +#define HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK 0x00020000L | |
| 74 | +#define mmHDP_MEM_POWER_CTRL_BASE_IDX 0 | |
| 68 | 75 | /* |
| 69 | 76 | * Indirect registers accessor |
| 70 | 77 | */ |
| @@ -870,15 +877,33 @@ static void soc15_update_hdp_light_sleep(struct amdgpu_device *adev, bool enable · 799 unmodified lines | ||
| 870 | 877 | { |
| 871 | 878 | uint32_t def, data; |
| 872 | 879 | |
| 873 | − def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS)); | |
| 880 | + if (adev->asic_type == CHIP_VEGA20) { | |
| 881 | + def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL)); | |
| 874 | 882 | |
| 875 | − if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS)) | |
| 876 | − data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK; | |
| 877 | − else | |
| 878 | − data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK; | |
| 883 | + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS)) | |
| 884 | + data |= HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK | | |
| 885 | + HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK | | |
| 886 | + HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK | | |
| 887 | + HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK; | |
| 888 | + else | |
| 889 | + data &= ~(HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK | | |
| 890 | + HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK | | |
| 891 | + HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK | | |
| 892 | + HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK); | |
| 879 | 893 | |
| 880 | − if (def != data) | |
| 881 | − WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS), data); | |
| 894 | + if (def != data) | |
| 895 | + WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL), data); | |
| 896 | + } else { | |
| 897 | + def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS)); | |
| 898 | + | |
| 899 | + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS)) | |
| 900 | + data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK; | |
| 901 | + else | |
| 902 | + data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK; | |
| 903 | + | |
| 904 | + if (def != data) | |
| 905 | + WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS), data); | |
| 906 | + } | |
| 882 | 907 | } |
| 883 | 908 | |
| 884 | 909 | static void soc15_update_drm_clock_gating(struct amdgpu_device *adev, bool enable) |
| @@ -2358,8 +2358,15 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode, · 2357 unmodified lines | ||
| 2358 | 2358 | static enum dc_color_depth |
| 2359 | 2359 | convert_color_depth_from_display_info(const struct drm_connector *connector) |
| 2360 | 2360 | { |
| 2361 | + struct dm_connector_state *dm_conn_state = | |
| 2362 | + to_dm_connector_state(connector->state); | |
| 2361 | 2363 | uint32_t bpc = connector->display_info.bpc; |
| 2362 | 2364 | |
| 2365 | + /* TODO: Remove this when there's support for max_bpc in drm */ | |
| 2366 | + if (dm_conn_state && bpc > dm_conn_state->max_bpc) | |
| 2367 | + /* Round down to nearest even number. */ | |
| 2368 | + bpc = dm_conn_state->max_bpc - (dm_conn_state->max_bpc & 1); | |
| 2369 | + | |
| 2363 | 2370 | switch (bpc) { |
| 2364 | 2371 | case 0: |
| 2365 | 2372 | /* |
| @@ -2943,6 +2950,9 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector, · 577 unmodified lines | ||
| 2943 | 2950 | } else if (property == adev->mode_info.underscan_property) { |
| 2944 | 2951 | dm_new_state->underscan_enable = val; |
| 2945 | 2952 | ret = 0; |
| 2953 | + } else if (property == adev->mode_info.max_bpc_property) { | |
| 2954 | + dm_new_state->max_bpc = val; | |
| 2955 | + ret = 0; | |
| 2946 | 2956 | } |
| 2947 | 2957 | |
| 2948 | 2958 | return ret; |
| @@ -2985,6 +2995,9 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector, · 36 unmodified lines | ||
| 2985 | 2995 | } else if (property == adev->mode_info.underscan_property) { |
| 2986 | 2996 | *val = dm_state->underscan_enable; |
| 2987 | 2997 | ret = 0; |
| 2998 | + } else if (property == adev->mode_info.max_bpc_property) { | |
| 2999 | + *val = dm_state->max_bpc; | |
| 3000 | + ret = 0; | |
| 2988 | 3001 | } |
| 2989 | 3002 | return ret; |
| 2990 | 3003 | } |
| @@ -3795,6 +3808,9 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, · 804 unmodified lines | ||
| 3795 | 3808 | drm_object_attach_property(&aconnector->base.base, |
| 3796 | 3809 | adev->mode_info.underscan_vborder_property, |
| 3797 | 3810 | 0); |
| 3811 | + drm_object_attach_property(&aconnector->base.base, | |
| 3812 | + adev->mode_info.max_bpc_property, | |
| 3813 | + 0); | |
| 3798 | 3814 | |
| 3799 | 3815 | } |
| 3800 | 3816 | |
| @@ -204,6 +204,7 @@ struct dm_connector_state { · 203 unmodified lines | ||
| 204 | 204 | enum amdgpu_rmx_type scaling; |
| 205 | 205 | uint8_t underscan_vborder; |
| 206 | 206 | uint8_t underscan_hborder; |
| 207 | + uint8_t max_bpc; | |
| 207 | 208 | bool underscan_enable; |
| 208 | 209 | bool freesync_enable; |
| 209 | 210 | bool freesync_capable; |
| @@ -4525,12 +4525,12 @@ static int smu7_get_sclk_od(struct pp_hwmgr *hwmgr) · 4524 unmodified lines | ||
| 4525 | 4525 | struct smu7_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); |
| 4526 | 4526 | struct smu7_single_dpm_table *golden_sclk_table = |
| 4527 | 4527 | &(data->golden_dpm_table.sclk_table); |
| 4528 | − int value; | |
| 4528 | + int value = sclk_table->dpm_levels[sclk_table->count - 1].value; | |
| 4529 | + int golden_value = golden_sclk_table->dpm_levels | |
| 4530 | + [golden_sclk_table->count - 1].value; | |
| 4529 | 4531 | |
| 4530 | − value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | |
| 4531 | − golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * | |
| 4532 | − 100 / | |
| 4533 | − golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | |
| 4532 | + value -= golden_value; | |
| 4533 | + value = DIV_ROUND_UP(value * 100, golden_value); | |
| 4534 | 4534 | |
| 4535 | 4535 | return value; |
| 4536 | 4536 | } |
| @@ -4567,12 +4567,12 @@ static int smu7_get_mclk_od(struct pp_hwmgr *hwmgr) · 30 unmodified lines | ||
| 4567 | 4567 | struct smu7_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); |
| 4568 | 4568 | struct smu7_single_dpm_table *golden_mclk_table = |
| 4569 | 4569 | &(data->golden_dpm_table.mclk_table); |
| 4570 | − int value; | |
| 4570 | + int value = mclk_table->dpm_levels[mclk_table->count - 1].value; | |
| 4571 | + int golden_value = golden_mclk_table->dpm_levels | |
| 4572 | + [golden_mclk_table->count - 1].value; | |
| 4571 | 4573 | |
| 4572 | − value = (mclk_table->dpm_levels[mclk_table->count - 1].value - | |
| 4573 | − golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * | |
| 4574 | − 100 / | |
| 4575 | − golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; | |
| 4574 | + value -= golden_value; | |
| 4575 | + value = DIV_ROUND_UP(value * 100, golden_value); | |
| 4576 | 4576 | |
| 4577 | 4577 | return value; |
| 4578 | 4578 | } |
| @@ -4522,15 +4522,13 @@ static int vega10_get_sclk_od(struct pp_hwmgr *hwmgr) · 4521 unmodified lines | ||
| 4522 | 4522 | struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); |
| 4523 | 4523 | struct vega10_single_dpm_table *golden_sclk_table = |
| 4524 | 4524 | &(data->golden_dpm_table.gfx_table); |
| 4525 | − int value; | |
| 4526 | − | |
| 4527 | − value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | |
| 4528 | − golden_sclk_table->dpm_levels | |
| 4529 | − [golden_sclk_table->count - 1].value) * | |
| 4530 | − 100 / | |
| 4531 | − golden_sclk_table->dpm_levels | |
| 4525 | + int value = sclk_table->dpm_levels[sclk_table->count - 1].value; | |
| 4526 | + int golden_value = golden_sclk_table->dpm_levels | |
| 4532 | 4527 | [golden_sclk_table->count - 1].value; |
| 4533 | 4528 | |
| 4529 | + value -= golden_value; | |
| 4530 | + value = DIV_ROUND_UP(value * 100, golden_value); | |
| 4531 | + | |
| 4534 | 4532 | return value; |
| 4535 | 4533 | } |
| 4536 | 4534 | |
| @@ -4575,16 +4573,13 @@ static int vega10_get_mclk_od(struct pp_hwmgr *hwmgr) · 38 unmodified lines | ||
| 4575 | 4573 | struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); |
| 4576 | 4574 | struct vega10_single_dpm_table *golden_mclk_table = |
| 4577 | 4575 | &(data->golden_dpm_table.mem_table); |
| 4578 | − int value; | |
| 4579 | − | |
| 4580 | − value = (mclk_table->dpm_levels | |
| 4581 | − [mclk_table->count - 1].value - | |
| 4582 | − golden_mclk_table->dpm_levels | |
| 4583 | − [golden_mclk_table->count - 1].value) * | |
| 4584 | − 100 / | |
| 4585 | − golden_mclk_table->dpm_levels | |
| 4576 | + int value = mclk_table->dpm_levels[mclk_table->count - 1].value; | |
| 4577 | + int golden_value = golden_mclk_table->dpm_levels | |
| 4586 | 4578 | [golden_mclk_table->count - 1].value; |
| 4587 | 4579 | |
| 4580 | + value -= golden_value; | |
| 4581 | + value = DIV_ROUND_UP(value * 100, golden_value); | |
| 4582 | + | |
| 4588 | 4583 | return value; |
| 4589 | 4584 | } |
| 4590 | 4585 | |
| @@ -2243,12 +2243,12 @@ static int vega12_get_sclk_od(struct pp_hwmgr *hwmgr) · 2242 unmodified lines | ||
| 2243 | 2243 | struct vega12_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); |
| 2244 | 2244 | struct vega12_single_dpm_table *golden_sclk_table = |
| 2245 | 2245 | &(data->golden_dpm_table.gfx_table); |
| 2246 | − int value; | |
| 2246 | + int value = sclk_table->dpm_levels[sclk_table->count - 1].value; | |
| 2247 | + int golden_value = golden_sclk_table->dpm_levels | |
| 2248 | + [golden_sclk_table->count - 1].value; | |
| 2247 | 2249 | |
| 2248 | − value = (sclk_table->dpm_levels[sclk_table->count - 1].value - | |
| 2249 | − golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * | |
| 2250 | − 100 / | |
| 2251 | − golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | |
| 2250 | + value -= golden_value; | |
| 2251 | + value = DIV_ROUND_UP(value * 100, golden_value); | |
| 2252 | 2252 | |
| 2253 | 2253 | return value; |
| 2254 | 2254 | } |
| @@ -2264,16 +2264,13 @@ static int vega12_get_mclk_od(struct pp_hwmgr *hwmgr) · 9 unmodified lines | ||
| 2264 | 2264 | struct vega12_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); |
| 2265 | 2265 | struct vega12_single_dpm_table *golden_mclk_table = |
| 2266 | 2266 | &(data->golden_dpm_table.mem_table); |
| 2267 | − int value; | |
| 2268 | − | |
| 2269 | − value = (mclk_table->dpm_levels | |
| 2270 | − [mclk_table->count - 1].value - | |
| 2271 | − golden_mclk_table->dpm_levels | |
| 2272 | − [golden_mclk_table->count - 1].value) * | |
| 2273 | − 100 / | |
| 2274 | − golden_mclk_table->dpm_levels | |
| 2267 | + int value = mclk_table->dpm_levels[mclk_table->count - 1].value; | |
| 2268 | + int golden_value = golden_mclk_table->dpm_levels | |
| 2275 | 2269 | [golden_mclk_table->count - 1].value; |
| 2276 | 2270 | |
| 2271 | + value -= golden_value; | |
| 2272 | + value = DIV_ROUND_UP(value * 100, golden_value); | |
| 2273 | + | |
| 2277 | 2274 | return value; |
| 2278 | 2275 | } |
| 2279 | 2276 | |
| @@ -75,7 +75,17 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) · 74 unmodified lines | ||
| 75 | 75 | data->phy_clk_quad_eqn_b = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT; |
| 76 | 76 | data->phy_clk_quad_eqn_c = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT; |
| 77 | 77 | |
| 78 | − data->registry_data.disallowed_features = 0x0; | |
| 78 | + /* | |
| 79 | + * Disable the following features for now: | |
| 80 | + * GFXCLK DS | |
| 81 | + * SOCLK DS | |
| 82 | + * LCLK DS | |
| 83 | + * DCEFCLK DS | |
| 84 | + * FCLK DS | |
| 85 | + * MP1CLK DS | |
| 86 | + * MP0CLK DS | |
| 87 | + */ | |
| 88 | + data->registry_data.disallowed_features = 0xE0041C00; | |
| 79 | 89 | data->registry_data.od_state_in_dc_support = 0; |
| 80 | 90 | data->registry_data.thermal_support = 1; |
| 81 | 91 | data->registry_data.skip_baco_hardware = 0; |
| @@ -1313,12 +1323,13 @@ static int vega20_get_sclk_od( · 1231 unmodified lines | ||
| 1313 | 1323 | &(data->dpm_table.gfx_table); |
| 1314 | 1324 | struct vega20_single_dpm_table *golden_sclk_table = |
| 1315 | 1325 | &(data->golden_dpm_table.gfx_table); |
| 1316 | − int value; | |
| 1326 | + int value = sclk_table->dpm_levels[sclk_table->count - 1].value; | |
| 1327 | + int golden_value = golden_sclk_table->dpm_levels | |
| 1328 | + [golden_sclk_table->count - 1].value; | |
| 1317 | 1329 | |
| 1318 | 1330 | /* od percentage */ |
| 1319 | − value = DIV_ROUND_UP((sclk_table->dpm_levels[sclk_table->count - 1].value - | |
| 1320 | − golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * 100, | |
| 1321 | − golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value); | |
| 1331 | + value -= golden_value; | |
| 1332 | + value = DIV_ROUND_UP(value * 100, golden_value); | |
| 1322 | 1333 | |
| 1323 | 1334 | return value; |
| 1324 | 1335 | } |
| @@ -1358,12 +1369,13 @@ static int vega20_get_mclk_od( · 33 unmodified lines | ||
| 1358 | 1369 | &(data->dpm_table.mem_table); |
| 1359 | 1370 | struct vega20_single_dpm_table *golden_mclk_table = |
| 1360 | 1371 | &(data->golden_dpm_table.mem_table); |
| 1361 | − int value; | |
| 1372 | + int value = mclk_table->dpm_levels[mclk_table->count - 1].value; | |
| 1373 | + int golden_value = golden_mclk_table->dpm_levels | |
| 1374 | + [golden_mclk_table->count - 1].value; | |
| 1362 | 1375 | |
| 1363 | 1376 | /* od percentage */ |
| 1364 | − value = DIV_ROUND_UP((mclk_table->dpm_levels[mclk_table->count - 1].value - | |
| 1365 | − golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * 100, | |
| 1366 | − golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value); | |
| 1377 | + value -= golden_value; | |
| 1378 | + value = DIV_ROUND_UP(value * 100, golden_value); | |
| 1367 | 1379 | |
| 1368 | 1380 | return value; |
| 1369 | 1381 | } |