Commit 896066ee authored by Linus Torvalds's avatar Linus Torvalds

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

Pull drm fixes from Dave Airlie:
 "Last fixes from me: one amdgpu/radeon suspend resume and one leak fix,
  along with one vmware fix for some issues when command submission
  fails"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/amdgpu: don't try to recreate sysfs entries on resume
  drm/radeon: don't try to recreate sysfs entries on resume
  drm/amdgpu: stop leaking page flip fence
  drm/vmwgfx: Stabilize the command buffer submission code
parents 85051e29 22ca7ca5
...@@ -1654,6 +1654,7 @@ struct amdgpu_pm { ...@@ -1654,6 +1654,7 @@ struct amdgpu_pm {
u8 fan_max_rpm; u8 fan_max_rpm;
/* dpm */ /* dpm */
bool dpm_enabled; bool dpm_enabled;
bool sysfs_initialized;
struct amdgpu_dpm dpm; struct amdgpu_dpm dpm;
const struct firmware *fw; /* SMC firmware */ const struct firmware *fw; /* SMC firmware */
uint32_t fw_version; uint32_t fw_version;
......
...@@ -184,10 +184,6 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc, ...@@ -184,10 +184,6 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
goto cleanup; goto cleanup;
} }
fence_get(work->excl);
for (i = 0; i < work->shared_count; ++i)
fence_get(work->shared[i]);
amdgpu_bo_get_tiling_flags(new_rbo, &tiling_flags); amdgpu_bo_get_tiling_flags(new_rbo, &tiling_flags);
amdgpu_bo_unreserve(new_rbo); amdgpu_bo_unreserve(new_rbo);
......
...@@ -695,6 +695,9 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) ...@@ -695,6 +695,9 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
{ {
int ret; int ret;
if (adev->pm.sysfs_initialized)
return 0;
if (adev->pm.funcs->get_temperature == NULL) if (adev->pm.funcs->get_temperature == NULL)
return 0; return 0;
adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev, adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev,
...@@ -723,6 +726,8 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) ...@@ -723,6 +726,8 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
return ret; return ret;
} }
adev->pm.sysfs_initialized = true;
return 0; return 0;
} }
......
...@@ -1658,6 +1658,7 @@ struct radeon_pm { ...@@ -1658,6 +1658,7 @@ struct radeon_pm {
u8 fan_max_rpm; u8 fan_max_rpm;
/* dpm */ /* dpm */
bool dpm_enabled; bool dpm_enabled;
bool sysfs_initialized;
struct radeon_dpm dpm; struct radeon_dpm dpm;
}; };
......
...@@ -1528,19 +1528,23 @@ int radeon_pm_late_init(struct radeon_device *rdev) ...@@ -1528,19 +1528,23 @@ int radeon_pm_late_init(struct radeon_device *rdev)
if (rdev->pm.pm_method == PM_METHOD_DPM) { if (rdev->pm.pm_method == PM_METHOD_DPM) {
if (rdev->pm.dpm_enabled) { if (rdev->pm.dpm_enabled) {
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state); if (!rdev->pm.sysfs_initialized) {
if (ret) ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
DRM_ERROR("failed to create device file for dpm state\n"); if (ret)
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level); DRM_ERROR("failed to create device file for dpm state\n");
if (ret) ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
DRM_ERROR("failed to create device file for dpm state\n"); if (ret)
/* XXX: these are noops for dpm but are here for backwards compat */ DRM_ERROR("failed to create device file for dpm state\n");
ret = device_create_file(rdev->dev, &dev_attr_power_profile); /* XXX: these are noops for dpm but are here for backwards compat */
if (ret) ret = device_create_file(rdev->dev, &dev_attr_power_profile);
DRM_ERROR("failed to create device file for power profile\n"); if (ret)
ret = device_create_file(rdev->dev, &dev_attr_power_method); DRM_ERROR("failed to create device file for power profile\n");
if (ret) ret = device_create_file(rdev->dev, &dev_attr_power_method);
DRM_ERROR("failed to create device file for power method\n"); if (ret)
DRM_ERROR("failed to create device file for power method\n");
if (!ret)
rdev->pm.sysfs_initialized = true;
}
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
ret = radeon_dpm_late_enable(rdev); ret = radeon_dpm_late_enable(rdev);
...@@ -1556,7 +1560,8 @@ int radeon_pm_late_init(struct radeon_device *rdev) ...@@ -1556,7 +1560,8 @@ int radeon_pm_late_init(struct radeon_device *rdev)
} }
} }
} else { } else {
if (rdev->pm.num_power_states > 1) { if ((rdev->pm.num_power_states > 1) &&
(!rdev->pm.sysfs_initialized)) {
/* where's the best place to put these? */ /* where's the best place to put these? */
ret = device_create_file(rdev->dev, &dev_attr_power_profile); ret = device_create_file(rdev->dev, &dev_attr_power_profile);
if (ret) if (ret)
...@@ -1564,6 +1569,8 @@ int radeon_pm_late_init(struct radeon_device *rdev) ...@@ -1564,6 +1569,8 @@ int radeon_pm_late_init(struct radeon_device *rdev)
ret = device_create_file(rdev->dev, &dev_attr_power_method); ret = device_create_file(rdev->dev, &dev_attr_power_method);
if (ret) if (ret)
DRM_ERROR("failed to create device file for power method\n"); DRM_ERROR("failed to create device file for power method\n");
if (!ret)
rdev->pm.sysfs_initialized = true;
} }
} }
return ret; return ret;
......
...@@ -415,16 +415,16 @@ static void vmw_cmdbuf_ctx_process(struct vmw_cmdbuf_man *man, ...@@ -415,16 +415,16 @@ static void vmw_cmdbuf_ctx_process(struct vmw_cmdbuf_man *man,
* *
* Calls vmw_cmdbuf_ctx_process() on all contexts. If any context has * Calls vmw_cmdbuf_ctx_process() on all contexts. If any context has
* command buffers left that are not submitted to hardware, Make sure * command buffers left that are not submitted to hardware, Make sure
* IRQ handling is turned on. Otherwise, make sure it's turned off. This * IRQ handling is turned on. Otherwise, make sure it's turned off.
* function may return -EAGAIN to indicate it should be rerun due to
* possibly missed IRQs if IRQs has just been turned on.
*/ */
static int vmw_cmdbuf_man_process(struct vmw_cmdbuf_man *man) static void vmw_cmdbuf_man_process(struct vmw_cmdbuf_man *man)
{ {
int notempty = 0; int notempty;
struct vmw_cmdbuf_context *ctx; struct vmw_cmdbuf_context *ctx;
int i; int i;
retry:
notempty = 0;
for_each_cmdbuf_ctx(man, i, ctx) for_each_cmdbuf_ctx(man, i, ctx)
vmw_cmdbuf_ctx_process(man, ctx, &notempty); vmw_cmdbuf_ctx_process(man, ctx, &notempty);
...@@ -440,10 +440,8 @@ static int vmw_cmdbuf_man_process(struct vmw_cmdbuf_man *man) ...@@ -440,10 +440,8 @@ static int vmw_cmdbuf_man_process(struct vmw_cmdbuf_man *man)
man->irq_on = true; man->irq_on = true;
/* Rerun in case we just missed an irq. */ /* Rerun in case we just missed an irq. */
return -EAGAIN; goto retry;
} }
return 0;
} }
/** /**
...@@ -468,8 +466,7 @@ static void vmw_cmdbuf_ctx_add(struct vmw_cmdbuf_man *man, ...@@ -468,8 +466,7 @@ static void vmw_cmdbuf_ctx_add(struct vmw_cmdbuf_man *man,
header->cb_context = cb_context; header->cb_context = cb_context;
list_add_tail(&header->list, &man->ctx[cb_context].submitted); list_add_tail(&header->list, &man->ctx[cb_context].submitted);
if (vmw_cmdbuf_man_process(man) == -EAGAIN) vmw_cmdbuf_man_process(man);
vmw_cmdbuf_man_process(man);
} }
/** /**
...@@ -488,8 +485,7 @@ static void vmw_cmdbuf_man_tasklet(unsigned long data) ...@@ -488,8 +485,7 @@ static void vmw_cmdbuf_man_tasklet(unsigned long data)
struct vmw_cmdbuf_man *man = (struct vmw_cmdbuf_man *) data; struct vmw_cmdbuf_man *man = (struct vmw_cmdbuf_man *) data;
spin_lock(&man->lock); spin_lock(&man->lock);
if (vmw_cmdbuf_man_process(man) == -EAGAIN) vmw_cmdbuf_man_process(man);
(void) vmw_cmdbuf_man_process(man);
spin_unlock(&man->lock); spin_unlock(&man->lock);
} }
...@@ -507,6 +503,7 @@ static void vmw_cmdbuf_work_func(struct work_struct *work) ...@@ -507,6 +503,7 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
struct vmw_cmdbuf_man *man = struct vmw_cmdbuf_man *man =
container_of(work, struct vmw_cmdbuf_man, work); container_of(work, struct vmw_cmdbuf_man, work);
struct vmw_cmdbuf_header *entry, *next; struct vmw_cmdbuf_header *entry, *next;
uint32_t dummy;
bool restart = false; bool restart = false;
spin_lock_bh(&man->lock); spin_lock_bh(&man->lock);
...@@ -523,6 +520,8 @@ static void vmw_cmdbuf_work_func(struct work_struct *work) ...@@ -523,6 +520,8 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
if (restart && vmw_cmdbuf_startstop(man, true)) if (restart && vmw_cmdbuf_startstop(man, true))
DRM_ERROR("Failed restarting command buffer context 0.\n"); DRM_ERROR("Failed restarting command buffer context 0.\n");
/* Send a new fence in case one was removed */
vmw_fifo_send_fence(man->dev_priv, &dummy);
} }
/** /**
...@@ -682,7 +681,7 @@ static bool vmw_cmdbuf_try_alloc(struct vmw_cmdbuf_man *man, ...@@ -682,7 +681,7 @@ static bool vmw_cmdbuf_try_alloc(struct vmw_cmdbuf_man *man,
DRM_MM_SEARCH_DEFAULT, DRM_MM_SEARCH_DEFAULT,
DRM_MM_CREATE_DEFAULT); DRM_MM_CREATE_DEFAULT);
if (ret) { if (ret) {
(void) vmw_cmdbuf_man_process(man); vmw_cmdbuf_man_process(man);
ret = drm_mm_insert_node_generic(&man->mm, info->node, ret = drm_mm_insert_node_generic(&man->mm, info->node,
info->page_size, 0, 0, info->page_size, 0, 0,
DRM_MM_SEARCH_DEFAULT, DRM_MM_SEARCH_DEFAULT,
...@@ -1168,7 +1167,14 @@ int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man, ...@@ -1168,7 +1167,14 @@ int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man,
drm_mm_init(&man->mm, 0, size >> PAGE_SHIFT); drm_mm_init(&man->mm, 0, size >> PAGE_SHIFT);
man->has_pool = true; man->has_pool = true;
man->default_size = default_size;
/*
* For now, set the default size to VMW_CMDBUF_INLINE_SIZE to
* prevent deadlocks from happening when vmw_cmdbuf_space_pool()
* needs to wait for space and we block on further command
* submissions to be able to free up space.
*/
man->default_size = VMW_CMDBUF_INLINE_SIZE;
DRM_INFO("Using command buffers with %s pool.\n", DRM_INFO("Using command buffers with %s pool.\n",
(man->using_mob) ? "MOB" : "DMA"); (man->using_mob) ? "MOB" : "DMA");
......
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