Commit 3fa8f89d authored by Sathishkumar S's avatar Sathishkumar S Committed by Alex Deucher
Browse files

drm/amdgpu: enable smart shift on dGPU (v5)



enable smart shift on dGPU if it is part of HG system and
the platform supports ATCS method to handle power shift.

V2: avoid psc updates in baco enter and exit (Lijo)
    fix alignment (Shashank)
V3: rebased on unified ATCS handling. (Alex)
V4: check for return value and warn on failed update (Shashank)
    return 0 if device does not support smart shift.  (Lizo)
V5: rebased on ATPX/ATCS structures global (Alex)

Signed-off-by: default avatarSathishkumar S <sathishkumar.sundararaju@amd.com>
Reviewed-by: default avatarLijo Lazar <lijo.lazar@amd.com>
Reviewed-by: default avatarShashank Sharma <shashank.sharma@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 19a1d935
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -130,6 +130,13 @@ struct amdgpu_mgpu_info
	bool				pending_reset;
};

enum amdgpu_ss {
	AMDGPU_SS_DRV_LOAD,
	AMDGPU_SS_DEV_D0,
	AMDGPU_SS_DEV_D3,
	AMDGPU_SS_DRV_UNLOAD
};

struct amdgpu_watchdog_timer
{
	bool timeout_fatal_disable;
@@ -1264,6 +1271,7 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev);
bool amdgpu_device_supports_atpx(struct drm_device *dev);
bool amdgpu_device_supports_px(struct drm_device *dev);
bool amdgpu_device_supports_boco(struct drm_device *dev);
bool amdgpu_device_supports_smart_shift(struct drm_device *dev);
bool amdgpu_device_supports_baco(struct drm_device *dev);
bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
				      struct amdgpu_device *peer_adev);
@@ -1336,6 +1344,13 @@ struct amdgpu_afmt_acr {
struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock);

/* amdgpu_acpi.c */

/* ATCS Device/Driver State */
#define AMDGPU_ATCS_PSC_DEV_STATE_D0		0
#define AMDGPU_ATCS_PSC_DEV_STATE_D3_HOT	3
#define AMDGPU_ATCS_PSC_DRV_STATE_OPR		0
#define AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR	1

#if defined(CONFIG_ACPI)
int amdgpu_acpi_init(struct amdgpu_device *adev);
void amdgpu_acpi_fini(struct amdgpu_device *adev);
@@ -1345,6 +1360,7 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
						u8 perf_req, bool advertise);
int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
				    u8 dev_state, bool drv_state);
int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_state);
int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);

void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps);
@@ -1358,6 +1374,8 @@ static inline void amdgpu_acpi_detect(void) { }
static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; }
static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
						  u8 dev_state, bool drv_state) { return 0; }
static inline int amdgpu_acpi_smart_shift_update(struct drm_device *dev,
						 enum amdgpu_ss ss_state) { return 0; }
#endif

int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
+49 −0
Original line number Diff line number Diff line
@@ -754,6 +754,55 @@ int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
	return 0;
}

/**
 * amdgpu_acpi_smart_shift_update - update dGPU device state to SBIOS
 *
 * @dev: drm_device pointer
 * @ss_state: current smart shift event
 *
 * returns 0 on success,
 * otherwise return error number.
 */
int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_state)
{
	struct amdgpu_device *adev = drm_to_adev(dev);
	int r;

	if (!amdgpu_device_supports_smart_shift(dev))
		return 0;

	switch (ss_state) {
	/* SBIOS trigger “stop”, “enable” and “start” at D0, Driver Operational.
	 * SBIOS trigger “stop” at D3, Driver Not Operational.
	 * SBIOS trigger “stop” and “disable” at D0, Driver NOT operational.
	 */
	case AMDGPU_SS_DRV_LOAD:
		r = amdgpu_acpi_power_shift_control(adev,
						    AMDGPU_ATCS_PSC_DEV_STATE_D0,
						    AMDGPU_ATCS_PSC_DRV_STATE_OPR);
		break;
	case AMDGPU_SS_DEV_D0:
		r = amdgpu_acpi_power_shift_control(adev,
						    AMDGPU_ATCS_PSC_DEV_STATE_D0,
						    AMDGPU_ATCS_PSC_DRV_STATE_OPR);
		break;
	case AMDGPU_SS_DEV_D3:
		r = amdgpu_acpi_power_shift_control(adev,
						    AMDGPU_ATCS_PSC_DEV_STATE_D3_HOT,
						    AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR);
		break;
	case AMDGPU_SS_DRV_UNLOAD:
		r = amdgpu_acpi_power_shift_control(adev,
						    AMDGPU_ATCS_PSC_DEV_STATE_D0,
						    AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR);
		break;
	default:
		return -EINVAL;
	}

	return r;
}

/**
 * amdgpu_acpi_event - handle notify events
 *
+24 −0
Original line number Diff line number Diff line
@@ -263,6 +263,21 @@ bool amdgpu_device_supports_baco(struct drm_device *dev)
	return amdgpu_asic_supports_baco(adev);
}

/**
 * amdgpu_device_supports_smart_shift - Is the device dGPU with
 * smart shift support
 *
 * @dev: drm_device pointer
 *
 * Returns true if the device is a dGPU with Smart Shift support,
 * otherwise returns false.
 */
bool amdgpu_device_supports_smart_shift(struct drm_device *dev)
{
	return (amdgpu_device_supports_boco(dev) &&
		amdgpu_acpi_is_power_shift_control_supported());
}

/*
 * VRAM access helper functions
 */
@@ -3750,6 +3765,10 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
		return 0;

	adev->in_suspend = true;

	if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D3))
		DRM_WARN("smart shift update failed\n");

	drm_kms_helper_poll_disable(dev);

	if (fbcon)
@@ -3859,6 +3878,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
#endif
	adev->in_suspend = false;

	if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D0))
		DRM_WARN("smart shift update failed\n");

	return 0;
}

@@ -4938,6 +4960,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
			amdgpu_vf_error_put(tmp_adev, AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r);
		} else {
			dev_info(tmp_adev->dev, "GPU reset(%d) succeeded!\n", atomic_read(&tmp_adev->gpu_reset_counter));
			if (amdgpu_acpi_smart_shift_update(adev_to_drm(tmp_adev), AMDGPU_SS_DEV_D0))
				DRM_WARN("smart shift update failed\n");
		}
	}

+6 −0
Original line number Diff line number Diff line
@@ -91,6 +91,9 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
		pm_runtime_forbid(dev->dev);
	}

	if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_UNLOAD))
		DRM_WARN("smart shift update failed\n");

	amdgpu_acpi_fini(adev);
	amdgpu_device_fini(adev);
}
@@ -214,6 +217,9 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
		pm_runtime_put_autosuspend(dev->dev);
	}

	if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_LOAD))
		DRM_WARN("smart shift update failed\n");

out:
	if (r) {
		/* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */