On 2024-08-27 15:53, sunpeng.li@xxxxxxx wrote: > From: Leo Li <sunpeng.li@xxxxxxx> > > [Why] > > DCN IPS interoperates with other system idle power features, such as > Zstates. > > On DCN35, there is a known issue where system Z8 + DCN IPS2 causes a > hard hang. We observe this on systems where the SBIOS allows Z8. > > Though there is a SBIOS fix, there's no guarantee that users will get it > any time soon, or even install it. A workaround is needed to prevent > this from rearing its head in the wild. > > [How] > > For DCN35, check the pmfw version to determine whether the SBIOS has the > fix. If not, set IPS1+RCG as the deepest possible state in all cases > except for s0ix and display off (DPMS). Otherwise, enable all IPS > > Signed-off-by: Leo Li <sunpeng.li@xxxxxxx> Reviewed-by: Harry Wentland <harry.wentland@xxxxxxx> Harry > --- > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 26 ++++++++++++++++++- > 1 file changed, 25 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index a18ecf8607232..a2e4973a4f6e3 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -1754,6 +1754,30 @@ static struct dml2_soc_bb *dm_dmub_get_vbios_bounding_box(struct amdgpu_device * > return bb; > } > > +static enum dmub_ips_disable_type dm_get_default_ips_mode( > + struct amdgpu_device *adev) > +{ > + /* > + * On DCN35 systems with Z8 enabled, it's possible for IPS2 + Z8 to > + * cause a hard hang. A fix exists for newer PMFW. > + * > + * As a workaround, for non-fixed PMFW, force IPS1+RCG as the deepest > + * IPS state in all cases, except for s0ix and all displays off (DPMS), > + * where IPS2 is allowed. > + * > + * When checking pmfw version, use the major and minor only. > + */ > + if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(3, 5, 0) && > + (adev->pm.fw_version & 0x00FFFF00) < 0x005D6300) > + return DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF; > + > + if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 5, 0)) > + return DMUB_IPS_ENABLE; > + > + /* ASICs older than DCN35 do not have IPSs */ > + return DMUB_IPS_DISABLE_ALL; > +} > + > static int amdgpu_dm_init(struct amdgpu_device *adev) > { > struct dc_init_data init_data; > @@ -1871,7 +1895,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) > else if (amdgpu_dc_debug_mask & DC_FORCE_IPS_ENABLE) > init_data.flags.disable_ips = DMUB_IPS_ENABLE; > else > - init_data.flags.disable_ips = DMUB_IPS_ENABLE; > + init_data.flags.disable_ips = dm_get_default_ips_mode(adev); > > init_data.flags.disable_ips_in_vpb = 0; >