Commit f060e461 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'amd-drm-fixes-6.8-2024-02-29' of...

Merge tag 'amd-drm-fixes-6.8-2024-02-29' of https://gitlab.freedesktop.org/agd5f/linux

 into drm-fixes

amd-drm-fixes-6.8-2024-02-29:

amdgpu:
- Fix potential buffer overflow
- Fix power min cap
- Suspend/resume fix
- SI PM fix
- eDP fix

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240229152424.6646-1-alexander.deucher@amd.com
parents bba679c0 b7cdccc6
Loading
Loading
Loading
Loading
+25 −20
Original line number Diff line number Diff line
@@ -574,11 +574,34 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
		return AMD_RESET_METHOD_MODE1;
}

static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
{
	u32 sol_reg;

	sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);

	/* Will reset for the following suspend abort cases.
	 * 1) Only reset limit on APU side, dGPU hasn't checked yet.
	 * 2) S3 suspend abort and TOS already launched.
	 */
	if (adev->flags & AMD_IS_APU && adev->in_s3 &&
			!adev->suspend_complete &&
			sol_reg)
		return true;

	return false;
}

static int soc15_asic_reset(struct amdgpu_device *adev)
{
	/* original raven doesn't have full asic reset */
	if ((adev->apu_flags & AMD_APU_IS_RAVEN) ||
	    (adev->apu_flags & AMD_APU_IS_RAVEN2))
	/* On the latest Raven, the GPU reset can be performed
	 * successfully. So now, temporarily enable it for the
	 * S3 suspend abort case.
	 */
	if (((adev->apu_flags & AMD_APU_IS_RAVEN) ||
	    (adev->apu_flags & AMD_APU_IS_RAVEN2)) &&
		!soc15_need_reset_on_resume(adev))
		return 0;

	switch (soc15_asic_reset_method(adev)) {
@@ -1298,24 +1321,6 @@ static int soc15_common_suspend(void *handle)
	return soc15_common_hw_fini(adev);
}

static bool soc15_need_reset_on_resume(struct amdgpu_device *adev)
{
	u32 sol_reg;

	sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);

	/* Will reset for the following suspend abort cases.
	 * 1) Only reset limit on APU side, dGPU hasn't checked yet.
	 * 2) S3 suspend abort and TOS already launched.
	 */
	if (adev->flags & AMD_IS_APU && adev->in_s3 &&
			!adev->suspend_complete &&
			sol_reg)
		return true;

	return false;
}

static int soc15_common_resume(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+4 −2
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps)
	/* Workaround for some monitors that do not clear DPCD 0x317 if FreeSync is unsupported */
	case drm_edid_encode_panel_id('A', 'U', 'O', 0xA7AB):
	case drm_edid_encode_panel_id('A', 'U', 'O', 0xE69B):
	case drm_edid_encode_panel_id('B', 'O', 'E', 0x092A):
	case drm_edid_encode_panel_id('L', 'G', 'D', 0x06D1):
		DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id);
		edid_caps->panel_patch.remove_sink_ext_caps = true;
		break;
@@ -120,6 +122,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(

	edid_caps->edid_hdmi = connector->display_info.is_hdmi;

	apply_edid_quirks(edid_buf, edid_caps);

	sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
	if (sad_count <= 0)
		return result;
@@ -146,8 +150,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
	else
		edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;

	apply_edid_quirks(edid_buf, edid_caps);

	kfree(sads);
	kfree(sadb);

+5 −0
Original line number Diff line number Diff line
@@ -76,6 +76,11 @@ static void map_hw_resources(struct dml2_context *dml2,
			in_out_display_cfg->hw.DLGRefClkFreqMHz = 50;
		}
		for (j = 0; j < mode_support_info->DPPPerSurface[i]; j++) {
			if (i >= __DML2_WRAPPER_MAX_STREAMS_PLANES__) {
				dml_print("DML::%s: Index out of bounds: i=%d, __DML2_WRAPPER_MAX_STREAMS_PLANES__=%d\n",
					  __func__, i, __DML2_WRAPPER_MAX_STREAMS_PLANES__);
				break;
			}
			dml2->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id[num_pipes] = dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[i];
			dml2->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id_valid[num_pipes] = true;
			dml2->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_id[num_pipes] = dml2->v20.scratch.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[i];
+29 −0
Original line number Diff line number Diff line
@@ -6925,6 +6925,23 @@ static int si_dpm_enable(struct amdgpu_device *adev)
	return 0;
}

static int si_set_temperature_range(struct amdgpu_device *adev)
{
	int ret;

	ret = si_thermal_enable_alert(adev, false);
	if (ret)
		return ret;
	ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
	if (ret)
		return ret;
	ret = si_thermal_enable_alert(adev, true);
	if (ret)
		return ret;

	return ret;
}

static void si_dpm_disable(struct amdgpu_device *adev)
{
	struct rv7xx_power_info *pi = rv770_get_pi(adev);
@@ -7608,6 +7625,18 @@ static int si_dpm_process_interrupt(struct amdgpu_device *adev,

static int si_dpm_late_init(void *handle)
{
	int ret;
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	if (!adev->pm.dpm_enabled)
		return 0;

	ret = si_set_temperature_range(adev);
	if (ret)
		return ret;
#if 0 //TODO ?
	si_dpm_powergate_uvd(adev, true);
#endif
	return 0;
}

+4 −5
Original line number Diff line number Diff line
@@ -1303,13 +1303,12 @@ static int arcturus_get_power_limit(struct smu_context *smu,
	if (default_power_limit)
		*default_power_limit = power_limit;

	if (smu->od_enabled) {
	if (smu->od_enabled)
		od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
		od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
	} else {
	else
		od_percent_upper = 0;
		od_percent_lower = 100;
	}

	od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);

	dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
							od_percent_upper, od_percent_lower, power_limit);
Loading