Commit 8cf6f361 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-fixes-4.20' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

- 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
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181121163647.2847-1-alexander.deucher@amd.com
parents 1d74f133 a5d0f456
...@@ -501,8 +501,11 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle) ...@@ -501,8 +501,11 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
amdgpu_dpm_switch_power_profile(adev, if (adev->powerplay.pp_funcs &&
PP_SMC_POWER_PROFILE_COMPUTE, !idle); adev->powerplay.pp_funcs->switch_power_profile)
amdgpu_dpm_switch_power_profile(adev,
PP_SMC_POWER_PROFILE_COMPUTE,
!idle);
} }
bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid) 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) ...@@ -626,6 +626,13 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
"dither", "dither",
amdgpu_dither_enum_list, sz); amdgpu_dither_enum_list, sz);
if (amdgpu_device_has_dc_support(adev)) {
adev->mode_info.max_bpc_property =
drm_property_create_range(adev->ddev, 0, "max bpc", 8, 16);
if (!adev->mode_info.max_bpc_property)
return -ENOMEM;
}
return 0; return 0;
} }
......
...@@ -339,6 +339,8 @@ struct amdgpu_mode_info { ...@@ -339,6 +339,8 @@ struct amdgpu_mode_info {
struct drm_property *audio_property; struct drm_property *audio_property;
/* FMT dithering */ /* FMT dithering */
struct drm_property *dither_property; struct drm_property *dither_property;
/* maximum number of bits per channel for monitor color */
struct drm_property *max_bpc_property;
/* hardcoded DFP edid from BIOS */ /* hardcoded DFP edid from BIOS */
struct edid *bios_hardcoded_edid; struct edid *bios_hardcoded_edid;
int bios_hardcoded_edid_size; int bios_hardcoded_edid_size;
......
...@@ -46,6 +46,7 @@ MODULE_FIRMWARE("amdgpu/tahiti_mc.bin"); ...@@ -46,6 +46,7 @@ MODULE_FIRMWARE("amdgpu/tahiti_mc.bin");
MODULE_FIRMWARE("amdgpu/pitcairn_mc.bin"); MODULE_FIRMWARE("amdgpu/pitcairn_mc.bin");
MODULE_FIRMWARE("amdgpu/verde_mc.bin"); MODULE_FIRMWARE("amdgpu/verde_mc.bin");
MODULE_FIRMWARE("amdgpu/oland_mc.bin"); MODULE_FIRMWARE("amdgpu/oland_mc.bin");
MODULE_FIRMWARE("amdgpu/hainan_mc.bin");
MODULE_FIRMWARE("amdgpu/si58_mc.bin"); MODULE_FIRMWARE("amdgpu/si58_mc.bin");
#define MC_SEQ_MISC0__MT__MASK 0xf0000000 #define MC_SEQ_MISC0__MT__MASK 0xf0000000
......
...@@ -65,6 +65,13 @@ ...@@ -65,6 +65,13 @@
#define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba #define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba
#define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX 0 #define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX 0
/* for Vega20 register name change */
#define mmHDP_MEM_POWER_CTRL 0x00d4
#define HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK 0x00000001L
#define HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK 0x00000002L
#define HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK 0x00010000L
#define HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK 0x00020000L
#define mmHDP_MEM_POWER_CTRL_BASE_IDX 0
/* /*
* Indirect registers accessor * Indirect registers accessor
*/ */
...@@ -870,15 +877,33 @@ static void soc15_update_hdp_light_sleep(struct amdgpu_device *adev, bool enable ...@@ -870,15 +877,33 @@ static void soc15_update_hdp_light_sleep(struct amdgpu_device *adev, bool enable
{ {
uint32_t def, data; uint32_t def, data;
def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS)); if (adev->asic_type == CHIP_VEGA20) {
def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL));
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS)) if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS))
data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK; data |= HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK |
else HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK |
data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK; HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK |
HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK;
else
data &= ~(HDP_MEM_POWER_CTRL__IPH_MEM_POWER_CTRL_EN_MASK |
HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK |
HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK |
HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK);
if (def != data) if (def != data)
WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS), data); WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_CTRL), data);
} else {
def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS));
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS))
data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK;
else
data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK;
if (def != data)
WREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS), data);
}
} }
static void soc15_update_drm_clock_gating(struct amdgpu_device *adev, bool enable) 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, ...@@ -2358,8 +2358,15 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode,
static enum dc_color_depth static enum dc_color_depth
convert_color_depth_from_display_info(const struct drm_connector *connector) convert_color_depth_from_display_info(const struct drm_connector *connector)
{ {
struct dm_connector_state *dm_conn_state =
to_dm_connector_state(connector->state);
uint32_t bpc = connector->display_info.bpc; uint32_t bpc = connector->display_info.bpc;
/* TODO: Remove this when there's support for max_bpc in drm */
if (dm_conn_state && bpc > dm_conn_state->max_bpc)
/* Round down to nearest even number. */
bpc = dm_conn_state->max_bpc - (dm_conn_state->max_bpc & 1);
switch (bpc) { switch (bpc) {
case 0: case 0:
/* /*
...@@ -2943,6 +2950,9 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector, ...@@ -2943,6 +2950,9 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) { } else if (property == adev->mode_info.underscan_property) {
dm_new_state->underscan_enable = val; dm_new_state->underscan_enable = val;
ret = 0; ret = 0;
} else if (property == adev->mode_info.max_bpc_property) {
dm_new_state->max_bpc = val;
ret = 0;
} }
return ret; return ret;
...@@ -2985,6 +2995,9 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector, ...@@ -2985,6 +2995,9 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector,
} else if (property == adev->mode_info.underscan_property) { } else if (property == adev->mode_info.underscan_property) {
*val = dm_state->underscan_enable; *val = dm_state->underscan_enable;
ret = 0; ret = 0;
} else if (property == adev->mode_info.max_bpc_property) {
*val = dm_state->max_bpc;
ret = 0;
} }
return ret; return ret;
} }
...@@ -3795,6 +3808,9 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, ...@@ -3795,6 +3808,9 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
drm_object_attach_property(&aconnector->base.base, drm_object_attach_property(&aconnector->base.base,
adev->mode_info.underscan_vborder_property, adev->mode_info.underscan_vborder_property,
0); 0);
drm_object_attach_property(&aconnector->base.base,
adev->mode_info.max_bpc_property,
0);
} }
......
...@@ -204,6 +204,7 @@ struct dm_connector_state { ...@@ -204,6 +204,7 @@ struct dm_connector_state {
enum amdgpu_rmx_type scaling; enum amdgpu_rmx_type scaling;
uint8_t underscan_vborder; uint8_t underscan_vborder;
uint8_t underscan_hborder; uint8_t underscan_hborder;
uint8_t max_bpc;
bool underscan_enable; bool underscan_enable;
bool freesync_enable; bool freesync_enable;
bool freesync_capable; bool freesync_capable;
......
...@@ -4525,12 +4525,12 @@ static int smu7_get_sclk_od(struct pp_hwmgr *hwmgr) ...@@ -4525,12 +4525,12 @@ static int smu7_get_sclk_od(struct pp_hwmgr *hwmgr)
struct smu7_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); struct smu7_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table);
struct smu7_single_dpm_table *golden_sclk_table = struct smu7_single_dpm_table *golden_sclk_table =
&(data->golden_dpm_table.sclk_table); &(data->golden_dpm_table.sclk_table);
int value; int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
int golden_value = golden_sclk_table->dpm_levels
[golden_sclk_table->count - 1].value;
value = (sclk_table->dpm_levels[sclk_table->count - 1].value - value -= golden_value;
golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * value = DIV_ROUND_UP(value * 100, golden_value);
100 /
golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
return value; return value;
} }
...@@ -4567,12 +4567,12 @@ static int smu7_get_mclk_od(struct pp_hwmgr *hwmgr) ...@@ -4567,12 +4567,12 @@ static int smu7_get_mclk_od(struct pp_hwmgr *hwmgr)
struct smu7_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); struct smu7_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table);
struct smu7_single_dpm_table *golden_mclk_table = struct smu7_single_dpm_table *golden_mclk_table =
&(data->golden_dpm_table.mclk_table); &(data->golden_dpm_table.mclk_table);
int value; int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
int golden_value = golden_mclk_table->dpm_levels
[golden_mclk_table->count - 1].value;
value = (mclk_table->dpm_levels[mclk_table->count - 1].value - value -= golden_value;
golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * value = DIV_ROUND_UP(value * 100, golden_value);
100 /
golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value;
return value; return value;
} }
......
...@@ -4522,15 +4522,13 @@ static int vega10_get_sclk_od(struct pp_hwmgr *hwmgr) ...@@ -4522,15 +4522,13 @@ static int vega10_get_sclk_od(struct pp_hwmgr *hwmgr)
struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
struct vega10_single_dpm_table *golden_sclk_table = struct vega10_single_dpm_table *golden_sclk_table =
&(data->golden_dpm_table.gfx_table); &(data->golden_dpm_table.gfx_table);
int value; int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
int golden_value = golden_sclk_table->dpm_levels
value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
golden_sclk_table->dpm_levels
[golden_sclk_table->count - 1].value) *
100 /
golden_sclk_table->dpm_levels
[golden_sclk_table->count - 1].value; [golden_sclk_table->count - 1].value;
value -= golden_value;
value = DIV_ROUND_UP(value * 100, golden_value);
return value; return value;
} }
...@@ -4575,16 +4573,13 @@ static int vega10_get_mclk_od(struct pp_hwmgr *hwmgr) ...@@ -4575,16 +4573,13 @@ static int vega10_get_mclk_od(struct pp_hwmgr *hwmgr)
struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
struct vega10_single_dpm_table *golden_mclk_table = struct vega10_single_dpm_table *golden_mclk_table =
&(data->golden_dpm_table.mem_table); &(data->golden_dpm_table.mem_table);
int value; int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
int golden_value = golden_mclk_table->dpm_levels
value = (mclk_table->dpm_levels
[mclk_table->count - 1].value -
golden_mclk_table->dpm_levels
[golden_mclk_table->count - 1].value) *
100 /
golden_mclk_table->dpm_levels
[golden_mclk_table->count - 1].value; [golden_mclk_table->count - 1].value;
value -= golden_value;
value = DIV_ROUND_UP(value * 100, golden_value);
return value; return value;
} }
......
...@@ -2243,12 +2243,12 @@ static int vega12_get_sclk_od(struct pp_hwmgr *hwmgr) ...@@ -2243,12 +2243,12 @@ static int vega12_get_sclk_od(struct pp_hwmgr *hwmgr)
struct vega12_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); struct vega12_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
struct vega12_single_dpm_table *golden_sclk_table = struct vega12_single_dpm_table *golden_sclk_table =
&(data->golden_dpm_table.gfx_table); &(data->golden_dpm_table.gfx_table);
int value; int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
int golden_value = golden_sclk_table->dpm_levels
[golden_sclk_table->count - 1].value;
value = (sclk_table->dpm_levels[sclk_table->count - 1].value - value -= golden_value;
golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * value = DIV_ROUND_UP(value * 100, golden_value);
100 /
golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
return value; return value;
} }
...@@ -2264,16 +2264,13 @@ static int vega12_get_mclk_od(struct pp_hwmgr *hwmgr) ...@@ -2264,16 +2264,13 @@ static int vega12_get_mclk_od(struct pp_hwmgr *hwmgr)
struct vega12_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); struct vega12_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
struct vega12_single_dpm_table *golden_mclk_table = struct vega12_single_dpm_table *golden_mclk_table =
&(data->golden_dpm_table.mem_table); &(data->golden_dpm_table.mem_table);
int value; int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
int golden_value = golden_mclk_table->dpm_levels
value = (mclk_table->dpm_levels
[mclk_table->count - 1].value -
golden_mclk_table->dpm_levels
[golden_mclk_table->count - 1].value) *
100 /
golden_mclk_table->dpm_levels
[golden_mclk_table->count - 1].value; [golden_mclk_table->count - 1].value;
value -= golden_value;
value = DIV_ROUND_UP(value * 100, golden_value);
return value; return value;
} }
......
...@@ -75,7 +75,17 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) ...@@ -75,7 +75,17 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr)
data->phy_clk_quad_eqn_b = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT; data->phy_clk_quad_eqn_b = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT;
data->phy_clk_quad_eqn_c = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT; data->phy_clk_quad_eqn_c = PPREGKEY_VEGA20QUADRATICEQUATION_DFLT;
data->registry_data.disallowed_features = 0x0; /*
* Disable the following features for now:
* GFXCLK DS
* SOCLK DS
* LCLK DS
* DCEFCLK DS
* FCLK DS
* MP1CLK DS
* MP0CLK DS
*/
data->registry_data.disallowed_features = 0xE0041C00;
data->registry_data.od_state_in_dc_support = 0; data->registry_data.od_state_in_dc_support = 0;
data->registry_data.thermal_support = 1; data->registry_data.thermal_support = 1;
data->registry_data.skip_baco_hardware = 0; data->registry_data.skip_baco_hardware = 0;
...@@ -1313,12 +1323,13 @@ static int vega20_get_sclk_od( ...@@ -1313,12 +1323,13 @@ static int vega20_get_sclk_od(
&(data->dpm_table.gfx_table); &(data->dpm_table.gfx_table);
struct vega20_single_dpm_table *golden_sclk_table = struct vega20_single_dpm_table *golden_sclk_table =
&(data->golden_dpm_table.gfx_table); &(data->golden_dpm_table.gfx_table);
int value; int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
int golden_value = golden_sclk_table->dpm_levels
[golden_sclk_table->count - 1].value;
/* od percentage */ /* od percentage */
value = DIV_ROUND_UP((sclk_table->dpm_levels[sclk_table->count - 1].value - value -= golden_value;
golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * 100, value = DIV_ROUND_UP(value * 100, golden_value);
golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value);
return value; return value;
} }
...@@ -1358,12 +1369,13 @@ static int vega20_get_mclk_od( ...@@ -1358,12 +1369,13 @@ static int vega20_get_mclk_od(
&(data->dpm_table.mem_table); &(data->dpm_table.mem_table);
struct vega20_single_dpm_table *golden_mclk_table = struct vega20_single_dpm_table *golden_mclk_table =
&(data->golden_dpm_table.mem_table); &(data->golden_dpm_table.mem_table);
int value; int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
int golden_value = golden_mclk_table->dpm_levels
[golden_mclk_table->count - 1].value;
/* od percentage */ /* od percentage */
value = DIV_ROUND_UP((mclk_table->dpm_levels[mclk_table->count - 1].value - value -= golden_value;
golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * 100, value = DIV_ROUND_UP(value * 100, golden_value);
golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value);
return value; return value;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment