Commit 77c01bef authored by Dave Airlie's avatar Dave Airlie

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

radeon fixes, VCE one is big but does fix a userspace crash.

* 'drm-fixes-3.15' of git://people.freedesktop.org/~deathsimple/linux:
  drm/radeon/pm: don't allow debugfs/sysfs access when PX card is off (v2)
  drm/radeon: avoid segfault on device open when accel is not working.
  drm/radeon: fix typo in finding PLL params
  drm/radeon: fix register typo on si
  drm/radeon: fix buffer placement under memory pressure v2
  drm/radeon: fix page directory update size estimation
  drm/radeon: handle non-VGA class pci devices with ATRM
  drm/radeon: fix DCE83 check for mullins
  drm/radeon: check VCE relocation buffer range v3
  drm/radeon: also try GART for CPU accessed buffers
parents 763b2573 4f2f2039
...@@ -1642,6 +1642,7 @@ struct radeon_vce { ...@@ -1642,6 +1642,7 @@ struct radeon_vce {
unsigned fb_version; unsigned fb_version;
atomic_t handles[RADEON_MAX_VCE_HANDLES]; atomic_t handles[RADEON_MAX_VCE_HANDLES];
struct drm_file *filp[RADEON_MAX_VCE_HANDLES]; struct drm_file *filp[RADEON_MAX_VCE_HANDLES];
unsigned img_size[RADEON_MAX_VCE_HANDLES];
struct delayed_work idle_work; struct delayed_work idle_work;
}; };
...@@ -1655,7 +1656,7 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring, ...@@ -1655,7 +1656,7 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
uint32_t handle, struct radeon_fence **fence); uint32_t handle, struct radeon_fence **fence);
void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp); void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp);
void radeon_vce_note_usage(struct radeon_device *rdev); void radeon_vce_note_usage(struct radeon_device *rdev);
int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi); int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi, unsigned size);
int radeon_vce_cs_parse(struct radeon_cs_parser *p); int radeon_vce_cs_parse(struct radeon_cs_parser *p);
bool radeon_vce_semaphore_emit(struct radeon_device *rdev, bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
struct radeon_ring *ring, struct radeon_ring *ring,
...@@ -2640,7 +2641,8 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); ...@@ -2640,7 +2641,8 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
#define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE)) #define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE))
#define ASIC_IS_DCE81(rdev) ((rdev->family == CHIP_KAVERI)) #define ASIC_IS_DCE81(rdev) ((rdev->family == CHIP_KAVERI))
#define ASIC_IS_DCE82(rdev) ((rdev->family == CHIP_BONAIRE)) #define ASIC_IS_DCE82(rdev) ((rdev->family == CHIP_BONAIRE))
#define ASIC_IS_DCE83(rdev) ((rdev->family == CHIP_KABINI)) #define ASIC_IS_DCE83(rdev) ((rdev->family == CHIP_KABINI) || \
(rdev->family == CHIP_MULLINS))
#define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \ #define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \
(rdev->ddev->pdev->device == 0x6850) || \ (rdev->ddev->pdev->device == 0x6850) || \
......
...@@ -196,6 +196,20 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) ...@@ -196,6 +196,20 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
} }
} }
if (!found) {
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
dhandle = ACPI_HANDLE(&pdev->dev);
if (!dhandle)
continue;
status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
if (!ACPI_FAILURE(status)) {
found = true;
break;
}
}
}
if (!found) if (!found)
return false; return false;
......
...@@ -999,7 +999,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, ...@@ -999,7 +999,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
/* avoid high jitter with small fractional dividers */ /* avoid high jitter with small fractional dividers */
if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) { if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) {
fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 60); fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 50);
if (fb_div < fb_div_min) { if (fb_div < fb_div_min) {
unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div); unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div);
fb_div *= tmp; fb_div *= tmp;
......
...@@ -577,6 +577,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) ...@@ -577,6 +577,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
return r; return r;
} }
if (rdev->accel_working) {
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
if (r) { if (r) {
radeon_vm_fini(rdev, &fpriv->vm); radeon_vm_fini(rdev, &fpriv->vm);
...@@ -598,7 +599,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) ...@@ -598,7 +599,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
kfree(fpriv); kfree(fpriv);
return r; return r;
} }
}
file_priv->driver_priv = fpriv; file_priv->driver_priv = fpriv;
} }
...@@ -626,6 +627,7 @@ void radeon_driver_postclose_kms(struct drm_device *dev, ...@@ -626,6 +627,7 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
struct radeon_bo_va *bo_va; struct radeon_bo_va *bo_va;
int r; int r;
if (rdev->accel_working) {
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
if (!r) { if (!r) {
bo_va = radeon_vm_bo_find(&fpriv->vm, bo_va = radeon_vm_bo_find(&fpriv->vm,
...@@ -634,6 +636,7 @@ void radeon_driver_postclose_kms(struct drm_device *dev, ...@@ -634,6 +636,7 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
radeon_vm_bo_rmv(rdev, bo_va); radeon_vm_bo_rmv(rdev, bo_va);
radeon_bo_unreserve(rdev->ring_tmp_bo.bo); radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
} }
}
radeon_vm_fini(rdev, &fpriv->vm); radeon_vm_fini(rdev, &fpriv->vm);
kfree(fpriv); kfree(fpriv);
......
...@@ -458,7 +458,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev, ...@@ -458,7 +458,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
* into account. We don't want to disallow buffer moves * into account. We don't want to disallow buffer moves
* completely. * completely.
*/ */
if (current_domain != RADEON_GEM_DOMAIN_CPU && if ((lobj->alt_domain & current_domain) != 0 &&
(domain & current_domain) == 0 && /* will be moved */ (domain & current_domain) == 0 && /* will be moved */
bytes_moved > bytes_moved_threshold) { bytes_moved > bytes_moved_threshold) {
/* don't move it */ /* don't move it */
...@@ -699,22 +699,30 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) ...@@ -699,22 +699,30 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
rbo = container_of(bo, struct radeon_bo, tbo); rbo = container_of(bo, struct radeon_bo, tbo);
radeon_bo_check_tiling(rbo, 0, 0); radeon_bo_check_tiling(rbo, 0, 0);
rdev = rbo->rdev; rdev = rbo->rdev;
if (bo->mem.mem_type == TTM_PL_VRAM) { if (bo->mem.mem_type != TTM_PL_VRAM)
return 0;
size = bo->mem.num_pages << PAGE_SHIFT; size = bo->mem.num_pages << PAGE_SHIFT;
offset = bo->mem.start << PAGE_SHIFT; offset = bo->mem.start << PAGE_SHIFT;
if ((offset + size) > rdev->mc.visible_vram_size) { if ((offset + size) <= rdev->mc.visible_vram_size)
return 0;
/* hurrah the memory is not visible ! */ /* hurrah the memory is not visible ! */
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM); radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM);
rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT; rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT;
r = ttm_bo_validate(bo, &rbo->placement, false, false); r = ttm_bo_validate(bo, &rbo->placement, false, false);
if (unlikely(r != 0)) if (unlikely(r == -ENOMEM)) {
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT);
return ttm_bo_validate(bo, &rbo->placement, false, false);
} else if (unlikely(r != 0)) {
return r; return r;
}
offset = bo->mem.start << PAGE_SHIFT; offset = bo->mem.start << PAGE_SHIFT;
/* this should not happen */ /* this should never happen */
if ((offset + size) > rdev->mc.visible_vram_size) if ((offset + size) > rdev->mc.visible_vram_size)
return -EINVAL; return -EINVAL;
}
}
return 0; return 0;
} }
......
...@@ -361,6 +361,11 @@ static ssize_t radeon_set_pm_profile(struct device *dev, ...@@ -361,6 +361,11 @@ static ssize_t radeon_set_pm_profile(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
/* Can't set profile when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (rdev->pm.pm_method == PM_METHOD_PROFILE) { if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
if (strncmp("default", buf, strlen("default")) == 0) if (strncmp("default", buf, strlen("default")) == 0)
...@@ -409,6 +414,13 @@ static ssize_t radeon_set_pm_method(struct device *dev, ...@@ -409,6 +414,13 @@ static ssize_t radeon_set_pm_method(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
/* Can't set method when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
count = -EINVAL;
goto fail;
}
/* we don't support the legacy modes with dpm */ /* we don't support the legacy modes with dpm */
if (rdev->pm.pm_method == PM_METHOD_DPM) { if (rdev->pm.pm_method == PM_METHOD_DPM) {
count = -EINVAL; count = -EINVAL;
...@@ -446,6 +458,10 @@ static ssize_t radeon_get_dpm_state(struct device *dev, ...@@ -446,6 +458,10 @@ static ssize_t radeon_get_dpm_state(struct device *dev,
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
enum radeon_pm_state_type pm = rdev->pm.dpm.user_state; enum radeon_pm_state_type pm = rdev->pm.dpm.user_state;
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return snprintf(buf, PAGE_SIZE, "off\n");
return snprintf(buf, PAGE_SIZE, "%s\n", return snprintf(buf, PAGE_SIZE, "%s\n",
(pm == POWER_STATE_TYPE_BATTERY) ? "battery" : (pm == POWER_STATE_TYPE_BATTERY) ? "battery" :
(pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance");
...@@ -459,6 +475,11 @@ static ssize_t radeon_set_dpm_state(struct device *dev, ...@@ -459,6 +475,11 @@ static ssize_t radeon_set_dpm_state(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
/* Can't set dpm state when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (strncmp("battery", buf, strlen("battery")) == 0) if (strncmp("battery", buf, strlen("battery")) == 0)
rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY; rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY;
...@@ -485,6 +506,10 @@ static ssize_t radeon_get_dpm_forced_performance_level(struct device *dev, ...@@ -485,6 +506,10 @@ static ssize_t radeon_get_dpm_forced_performance_level(struct device *dev,
struct radeon_device *rdev = ddev->dev_private; struct radeon_device *rdev = ddev->dev_private;
enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level;
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return snprintf(buf, PAGE_SIZE, "off\n");
return snprintf(buf, PAGE_SIZE, "%s\n", return snprintf(buf, PAGE_SIZE, "%s\n",
(level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" : (level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" :
(level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); (level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
...@@ -500,6 +525,11 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev, ...@@ -500,6 +525,11 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev,
enum radeon_dpm_forced_level level; enum radeon_dpm_forced_level level;
int ret = 0; int ret = 0;
/* Can't force performance level when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (strncmp("low", buf, strlen("low")) == 0) { if (strncmp("low", buf, strlen("low")) == 0) {
level = RADEON_DPM_FORCED_LEVEL_LOW; level = RADEON_DPM_FORCED_LEVEL_LOW;
...@@ -538,8 +568,14 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, ...@@ -538,8 +568,14 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev,
char *buf) char *buf)
{ {
struct radeon_device *rdev = dev_get_drvdata(dev); struct radeon_device *rdev = dev_get_drvdata(dev);
struct drm_device *ddev = rdev->ddev;
int temp; int temp;
/* Can't get temperature when the card is off */
if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON))
return -EINVAL;
if (rdev->asic->pm.get_temperature) if (rdev->asic->pm.get_temperature)
temp = radeon_get_temperature(rdev); temp = radeon_get_temperature(rdev);
else else
...@@ -1614,8 +1650,12 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) ...@@ -1614,8 +1650,12 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct drm_device *ddev = rdev->ddev;
if (rdev->pm.dpm_enabled) { if ((rdev->flags & RADEON_IS_PX) &&
(ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
seq_printf(m, "PX asic powered off\n");
} else if (rdev->pm.dpm_enabled) {
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (rdev->asic->dpm.debugfs_print_current_performance_level) if (rdev->asic->dpm.debugfs_print_current_performance_level)
radeon_dpm_debugfs_print_current_performance_level(rdev, m); radeon_dpm_debugfs_print_current_performance_level(rdev, m);
......
...@@ -443,13 +443,16 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring, ...@@ -443,13 +443,16 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
* @p: parser context * @p: parser context
* @lo: address of lower dword * @lo: address of lower dword
* @hi: address of higher dword * @hi: address of higher dword
* @size: size of checker for relocation buffer
* *
* Patch relocation inside command stream with real buffer address * Patch relocation inside command stream with real buffer address
*/ */
int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi) int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi,
unsigned size)
{ {
struct radeon_cs_chunk *relocs_chunk; struct radeon_cs_chunk *relocs_chunk;
uint64_t offset; struct radeon_cs_reloc *reloc;
uint64_t start, end, offset;
unsigned idx; unsigned idx;
relocs_chunk = &p->chunks[p->chunk_relocs_idx]; relocs_chunk = &p->chunks[p->chunk_relocs_idx];
...@@ -462,14 +465,59 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi) ...@@ -462,14 +465,59 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi)
return -EINVAL; return -EINVAL;
} }
offset += p->relocs_ptr[(idx / 4)]->gpu_offset; reloc = p->relocs_ptr[(idx / 4)];
start = reloc->gpu_offset;
end = start + radeon_bo_size(reloc->robj);
start += offset;
p->ib.ptr[lo] = offset & 0xFFFFFFFF; p->ib.ptr[lo] = start & 0xFFFFFFFF;
p->ib.ptr[hi] = offset >> 32; p->ib.ptr[hi] = start >> 32;
if (end <= start) {
DRM_ERROR("invalid reloc offset %llX!\n", offset);
return -EINVAL;
}
if ((end - start) < size) {
DRM_ERROR("buffer to small (%d / %d)!\n",
(unsigned)(end - start), size);
return -EINVAL;
}
return 0; return 0;
} }
/**
* radeon_vce_validate_handle - validate stream handle
*
* @p: parser context
* @handle: handle to validate
*
* Validates the handle and return the found session index or -EINVAL
* we we don't have another free session index.
*/
int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle)
{
unsigned i;
/* validate the handle */
for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
if (atomic_read(&p->rdev->vce.handles[i]) == handle)
return i;
}
/* handle not found try to alloc a new one */
for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) {
p->rdev->vce.filp[i] = p->filp;
p->rdev->vce.img_size[i] = 0;
return i;
}
}
DRM_ERROR("No more free VCE handles!\n");
return -EINVAL;
}
/** /**
* radeon_vce_cs_parse - parse and validate the command stream * radeon_vce_cs_parse - parse and validate the command stream
* *
...@@ -478,8 +526,10 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi) ...@@ -478,8 +526,10 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi)
*/ */
int radeon_vce_cs_parse(struct radeon_cs_parser *p) int radeon_vce_cs_parse(struct radeon_cs_parser *p)
{ {
uint32_t handle = 0; int session_idx = -1;
bool destroy = false; bool destroyed = false;
uint32_t tmp, handle = 0;
uint32_t *size = &tmp;
int i, r; int i, r;
while (p->idx < p->chunks[p->chunk_ib_idx].length_dw) { while (p->idx < p->chunks[p->chunk_ib_idx].length_dw) {
...@@ -491,13 +541,29 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) ...@@ -491,13 +541,29 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p)
return -EINVAL; return -EINVAL;
} }
if (destroyed) {
DRM_ERROR("No other command allowed after destroy!\n");
return -EINVAL;
}
switch (cmd) { switch (cmd) {
case 0x00000001: // session case 0x00000001: // session
handle = radeon_get_ib_value(p, p->idx + 2); handle = radeon_get_ib_value(p, p->idx + 2);
session_idx = radeon_vce_validate_handle(p, handle);
if (session_idx < 0)
return session_idx;
size = &p->rdev->vce.img_size[session_idx];
break; break;
case 0x00000002: // task info case 0x00000002: // task info
break;
case 0x01000001: // create case 0x01000001: // create
*size = radeon_get_ib_value(p, p->idx + 8) *
radeon_get_ib_value(p, p->idx + 10) *
8 * 3 / 2;
break;
case 0x04000001: // config extension case 0x04000001: // config extension
case 0x04000002: // pic control case 0x04000002: // pic control
case 0x04000005: // rate control case 0x04000005: // rate control
...@@ -506,23 +572,39 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) ...@@ -506,23 +572,39 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p)
break; break;
case 0x03000001: // encode case 0x03000001: // encode
r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9); r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9,
*size);
if (r) if (r)
return r; return r;
r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11); r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11,
*size / 3);
if (r) if (r)
return r; return r;
break; break;
case 0x02000001: // destroy case 0x02000001: // destroy
destroy = true; destroyed = true;
break; break;
case 0x05000001: // context buffer case 0x05000001: // context buffer
r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
*size * 2);
if (r)
return r;
break;
case 0x05000004: // video bitstream buffer case 0x05000004: // video bitstream buffer
tmp = radeon_get_ib_value(p, p->idx + 4);
r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
tmp);
if (r)
return r;
break;
case 0x05000005: // feedback buffer case 0x05000005: // feedback buffer
r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2); r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
4096);
if (r) if (r)
return r; return r;
break; break;
...@@ -532,33 +614,21 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) ...@@ -532,33 +614,21 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p)
return -EINVAL; return -EINVAL;
} }
if (session_idx == -1) {
DRM_ERROR("no session command at start of IB\n");
return -EINVAL;
}
p->idx += len / 4; p->idx += len / 4;
} }
if (destroy) { if (destroyed) {
/* IB contains a destroy msg, free the handle */ /* IB contains a destroy msg, free the handle */
for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i)
atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0); atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0);
return 0;
} }
/* create or encode, validate the handle */
for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
if (atomic_read(&p->rdev->vce.handles[i]) == handle)
return 0; return 0;
}
/* handle not found try to alloc a new one */
for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) {
p->rdev->vce.filp[i] = p->filp;
return 0;
}
}
DRM_ERROR("No more free VCE handles!\n");
return -EINVAL;
} }
/** /**
......
...@@ -595,7 +595,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, ...@@ -595,7 +595,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
ndw = 64; ndw = 64;
/* assume the worst case */ /* assume the worst case */
ndw += vm->max_pde_used * 12; ndw += vm->max_pde_used * 16;
/* update too big for an IB */ /* update too big for an IB */
if (ndw > 0xfffff) if (ndw > 0xfffff)
......
...@@ -107,8 +107,8 @@ ...@@ -107,8 +107,8 @@
#define SPLL_CHG_STATUS (1 << 1) #define SPLL_CHG_STATUS (1 << 1)
#define SPLL_CNTL_MODE 0x618 #define SPLL_CNTL_MODE 0x618
#define SPLL_SW_DIR_CONTROL (1 << 0) #define SPLL_SW_DIR_CONTROL (1 << 0)
# define SPLL_REFCLK_SEL(x) ((x) << 8) # define SPLL_REFCLK_SEL(x) ((x) << 26)
# define SPLL_REFCLK_SEL_MASK 0xFF00 # define SPLL_REFCLK_SEL_MASK (3 << 26)
#define CG_SPLL_SPREAD_SPECTRUM 0x620 #define CG_SPLL_SPREAD_SPECTRUM 0x620
#define SSEN (1 << 0) #define SSEN (1 << 0)
......
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