drm/amdgpu: clean up non-DC suspend/resume handling
Move the non-DC specific code into the DCE IP blocks similar to how we handle DC. This cleans up the common suspend and resume pathes. Reviewed-by: Evan Quan <evan.quan@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Родитель
e13d002bbf
Коммит
ca8ee26d61
|
@ -3672,14 +3672,9 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
|
|||
*/
|
||||
int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
int r;
|
||||
|
||||
adev = drm_to_adev(dev);
|
||||
|
||||
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
|
||||
return 0;
|
||||
|
||||
|
@ -3691,45 +3686,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
|||
|
||||
cancel_delayed_work_sync(&adev->delayed_init_work);
|
||||
|
||||
if (!amdgpu_device_has_dc_support(adev)) {
|
||||
/* turn off display hw */
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
drm_helper_connector_dpms(connector,
|
||||
DRM_MODE_DPMS_OFF);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
drm_modeset_unlock_all(dev);
|
||||
/* unpin the front buffers and cursors */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_framebuffer *fb = crtc->primary->fb;
|
||||
struct amdgpu_bo *robj;
|
||||
|
||||
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
|
||||
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
|
||||
r = amdgpu_bo_reserve(aobj, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(aobj);
|
||||
amdgpu_bo_unreserve(aobj);
|
||||
}
|
||||
}
|
||||
|
||||
if (fb == NULL || fb->obj[0] == NULL) {
|
||||
continue;
|
||||
}
|
||||
robj = gem_to_amdgpu_bo(fb->obj[0]);
|
||||
/* don't unpin kernel fb objects */
|
||||
if (!amdgpu_fbdev_robj_is_fb(adev, robj)) {
|
||||
r = amdgpu_bo_reserve(robj, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(robj);
|
||||
amdgpu_bo_unreserve(robj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_ras_suspend(adev);
|
||||
|
||||
r = amdgpu_device_ip_suspend_phase1(adev);
|
||||
|
@ -3766,10 +3722,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
|||
*/
|
||||
int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct drm_crtc *crtc;
|
||||
int r = 0;
|
||||
|
||||
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
|
||||
|
@ -3800,24 +3753,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
|||
queue_delayed_work(system_wq, &adev->delayed_init_work,
|
||||
msecs_to_jiffies(AMDGPU_RESUME_MS));
|
||||
|
||||
if (!amdgpu_device_has_dc_support(adev)) {
|
||||
/* pin cursors */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
|
||||
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
|
||||
r = amdgpu_bo_reserve(aobj, true);
|
||||
if (r == 0) {
|
||||
r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM);
|
||||
if (r != 0)
|
||||
dev_err(adev->dev, "Failed to pin cursor BO (%d)\n", r);
|
||||
amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj);
|
||||
amdgpu_bo_unreserve(aobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -3825,25 +3760,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
|||
/* Make sure IB tests flushed */
|
||||
flush_delayed_work(&adev->delayed_init_work);
|
||||
|
||||
/* blat the mode back in */
|
||||
if (fbcon) {
|
||||
if (!amdgpu_device_has_dc_support(adev)) {
|
||||
/* pre DCE11 */
|
||||
drm_helper_resume_force_mode(dev);
|
||||
|
||||
/* turn on display hw */
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
drm_helper_connector_dpms(connector,
|
||||
DRM_MODE_DPMS_ON);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
}
|
||||
if (fbcon)
|
||||
amdgpu_fbdev_set_suspend(adev, 0);
|
||||
}
|
||||
|
||||
drm_kms_helper_poll_enable(dev);
|
||||
|
||||
|
|
|
@ -1310,3 +1310,92 @@ bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc,
|
|||
return amdgpu_display_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos,
|
||||
stime, etime, mode);
|
||||
}
|
||||
|
||||
int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
|
||||
{
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
int r;
|
||||
|
||||
/* turn off display hw */
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
drm_helper_connector_dpms(connector,
|
||||
DRM_MODE_DPMS_OFF);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
drm_modeset_unlock_all(dev);
|
||||
/* unpin the front buffers and cursors */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_framebuffer *fb = crtc->primary->fb;
|
||||
struct amdgpu_bo *robj;
|
||||
|
||||
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
|
||||
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
|
||||
r = amdgpu_bo_reserve(aobj, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(aobj);
|
||||
amdgpu_bo_unreserve(aobj);
|
||||
}
|
||||
}
|
||||
|
||||
if (fb == NULL || fb->obj[0] == NULL) {
|
||||
continue;
|
||||
}
|
||||
robj = gem_to_amdgpu_bo(fb->obj[0]);
|
||||
/* don't unpin kernel fb objects */
|
||||
if (!amdgpu_fbdev_robj_is_fb(adev, robj)) {
|
||||
r = amdgpu_bo_reserve(robj, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(robj);
|
||||
amdgpu_bo_unreserve(robj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_display_resume_helper(struct amdgpu_device *adev)
|
||||
{
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
struct drm_crtc *crtc;
|
||||
int r;
|
||||
|
||||
/* pin cursors */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
|
||||
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
|
||||
r = amdgpu_bo_reserve(aobj, true);
|
||||
if (r == 0) {
|
||||
r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM);
|
||||
if (r != 0)
|
||||
dev_err(adev->dev, "Failed to pin cursor BO (%d)\n", r);
|
||||
amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj);
|
||||
amdgpu_bo_unreserve(aobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drm_helper_resume_force_mode(dev);
|
||||
|
||||
/* turn on display hw */
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
drm_helper_connector_dpms(connector,
|
||||
DRM_MODE_DPMS_ON);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,4 +47,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
|
|||
const struct drm_format_info *
|
||||
amdgpu_lookup_format_info(u32 format, uint64_t modifier);
|
||||
|
||||
int amdgpu_display_suspend_helper(struct amdgpu_device *adev);
|
||||
int amdgpu_display_resume_helper(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2897,6 +2897,11 @@ static int dce_v10_0_hw_fini(void *handle)
|
|||
static int dce_v10_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
@ -2921,8 +2926,10 @@ static int dce_v10_0_resume(void *handle)
|
|||
amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder,
|
||||
bl_level);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_v10_0_is_idle(void *handle)
|
||||
|
|
|
@ -3027,6 +3027,11 @@ static int dce_v11_0_hw_fini(void *handle)
|
|||
static int dce_v11_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
@ -3051,8 +3056,10 @@ static int dce_v11_0_resume(void *handle)
|
|||
amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder,
|
||||
bl_level);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_v11_0_is_idle(void *handle)
|
||||
|
|
|
@ -2770,7 +2770,11 @@ static int dce_v6_0_hw_fini(void *handle)
|
|||
static int dce_v6_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
||||
|
@ -2794,8 +2798,10 @@ static int dce_v6_0_resume(void *handle)
|
|||
amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder,
|
||||
bl_level);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_v6_0_is_idle(void *handle)
|
||||
|
|
|
@ -2796,6 +2796,11 @@ static int dce_v8_0_hw_fini(void *handle)
|
|||
static int dce_v8_0_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->mode_info.bl_level =
|
||||
amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
|
||||
|
@ -2820,8 +2825,10 @@ static int dce_v8_0_resume(void *handle)
|
|||
amdgpu_display_backlight_set_level(adev, adev->mode_info.bl_encoder,
|
||||
bl_level);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_v8_0_is_idle(void *handle)
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "dce_v11_0.h"
|
||||
#include "dce_virtual.h"
|
||||
#include "ivsrcid/ivsrcid_vislands30.h"
|
||||
#include "amdgpu_display.h"
|
||||
|
||||
#define DCE_VIRTUAL_VBLANK_PERIOD 16666666
|
||||
|
||||
|
@ -491,12 +492,24 @@ static int dce_virtual_hw_fini(void *handle)
|
|||
|
||||
static int dce_virtual_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
return dce_virtual_hw_fini(handle);
|
||||
}
|
||||
|
||||
static int dce_virtual_resume(void *handle)
|
||||
{
|
||||
return dce_virtual_hw_init(handle);
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = dce_virtual_hw_init(handle);
|
||||
if (r)
|
||||
return r;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_virtual_is_idle(void *handle)
|
||||
|
|
Загрузка…
Ссылка в новой задаче