mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 20:23:57 +08:00
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm radeon and nouveau fixes from Dave Airlie: "Fixes for the other big two. The radeon VCE one is large but it fixes some userspace triggerable issues, otherwise its blackscreens and oopses. Nouveau fixes a bleeding laptop panel issue when displayport is used sometimes" * 'drm-fixes' of git://people.freedesktop.org/~airlied/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 drm/gf119-/disp: fix nasty bug which can clobber SOR0's clock setup drm/nvd9/therm: handle another kind of PWM fan
This commit is contained in:
commit
2b2d323a31
@ -1009,7 +1009,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id,
|
||||
}
|
||||
|
||||
if (outp == 8)
|
||||
return false;
|
||||
return conf;
|
||||
|
||||
data = exec_lookup(priv, head, outp, ctrl, dcb, &ver, &hdr, &cnt, &len, &info1);
|
||||
if (data == 0x0000)
|
||||
|
@ -40,6 +40,7 @@ pwm_info(struct nouveau_therm *therm, int line)
|
||||
case 0x00: return 2;
|
||||
case 0x19: return 1;
|
||||
case 0x1c: return 0;
|
||||
case 0x1e: return 2;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1642,6 +1642,7 @@ struct radeon_vce {
|
||||
unsigned fb_version;
|
||||
atomic_t handles[RADEON_MAX_VCE_HANDLES];
|
||||
struct drm_file *filp[RADEON_MAX_VCE_HANDLES];
|
||||
unsigned img_size[RADEON_MAX_VCE_HANDLES];
|
||||
struct delayed_work idle_work;
|
||||
};
|
||||
|
||||
@ -1655,7 +1656,7 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
|
||||
uint32_t handle, struct radeon_fence **fence);
|
||||
void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp);
|
||||
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);
|
||||
bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
|
||||
struct radeon_ring *ring,
|
||||
@ -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_DCE81(rdev) ((rdev->family == CHIP_KAVERI))
|
||||
#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) || \
|
||||
(rdev->ddev->pdev->device == 0x6850) || \
|
||||
|
@ -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)
|
||||
return false;
|
||||
|
||||
|
@ -999,7 +999,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
|
||||
|
||||
/* avoid high jitter with small fractional dividers */
|
||||
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) {
|
||||
unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div);
|
||||
fb_div *= tmp;
|
||||
|
@ -577,28 +577,29 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
|
||||
if (r) {
|
||||
radeon_vm_fini(rdev, &fpriv->vm);
|
||||
kfree(fpriv);
|
||||
return r;
|
||||
if (rdev->accel_working) {
|
||||
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
|
||||
if (r) {
|
||||
radeon_vm_fini(rdev, &fpriv->vm);
|
||||
kfree(fpriv);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* map the ib pool buffer read only into
|
||||
* virtual address space */
|
||||
bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
|
||||
rdev->ring_tmp_bo.bo);
|
||||
r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
|
||||
RADEON_VM_PAGE_READABLE |
|
||||
RADEON_VM_PAGE_SNOOPED);
|
||||
|
||||
radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
|
||||
if (r) {
|
||||
radeon_vm_fini(rdev, &fpriv->vm);
|
||||
kfree(fpriv);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* map the ib pool buffer read only into
|
||||
* virtual address space */
|
||||
bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
|
||||
rdev->ring_tmp_bo.bo);
|
||||
r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
|
||||
RADEON_VM_PAGE_READABLE |
|
||||
RADEON_VM_PAGE_SNOOPED);
|
||||
|
||||
radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
|
||||
if (r) {
|
||||
radeon_vm_fini(rdev, &fpriv->vm);
|
||||
kfree(fpriv);
|
||||
return r;
|
||||
}
|
||||
|
||||
file_priv->driver_priv = fpriv;
|
||||
}
|
||||
|
||||
@ -626,13 +627,15 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
|
||||
struct radeon_bo_va *bo_va;
|
||||
int r;
|
||||
|
||||
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
|
||||
if (!r) {
|
||||
bo_va = radeon_vm_bo_find(&fpriv->vm,
|
||||
rdev->ring_tmp_bo.bo);
|
||||
if (bo_va)
|
||||
radeon_vm_bo_rmv(rdev, bo_va);
|
||||
radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
|
||||
if (rdev->accel_working) {
|
||||
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
|
||||
if (!r) {
|
||||
bo_va = radeon_vm_bo_find(&fpriv->vm,
|
||||
rdev->ring_tmp_bo.bo);
|
||||
if (bo_va)
|
||||
radeon_vm_bo_rmv(rdev, bo_va);
|
||||
radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
|
||||
}
|
||||
}
|
||||
|
||||
radeon_vm_fini(rdev, &fpriv->vm);
|
||||
|
@ -458,7 +458,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
|
||||
* into account. We don't want to disallow buffer moves
|
||||
* completely.
|
||||
*/
|
||||
if (current_domain != RADEON_GEM_DOMAIN_CPU &&
|
||||
if ((lobj->alt_domain & current_domain) != 0 &&
|
||||
(domain & current_domain) == 0 && /* will be moved */
|
||||
bytes_moved > bytes_moved_threshold) {
|
||||
/* don't move it */
|
||||
@ -699,22 +699,30 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
|
||||
rbo = container_of(bo, struct radeon_bo, tbo);
|
||||
radeon_bo_check_tiling(rbo, 0, 0);
|
||||
rdev = rbo->rdev;
|
||||
if (bo->mem.mem_type == TTM_PL_VRAM) {
|
||||
size = bo->mem.num_pages << PAGE_SHIFT;
|
||||
offset = bo->mem.start << PAGE_SHIFT;
|
||||
if ((offset + size) > rdev->mc.visible_vram_size) {
|
||||
/* hurrah the memory is not visible ! */
|
||||
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM);
|
||||
rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT;
|
||||
r = ttm_bo_validate(bo, &rbo->placement, false, false);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
offset = bo->mem.start << PAGE_SHIFT;
|
||||
/* this should not happen */
|
||||
if ((offset + size) > rdev->mc.visible_vram_size)
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bo->mem.mem_type != TTM_PL_VRAM)
|
||||
return 0;
|
||||
|
||||
size = bo->mem.num_pages << PAGE_SHIFT;
|
||||
offset = bo->mem.start << PAGE_SHIFT;
|
||||
if ((offset + size) <= rdev->mc.visible_vram_size)
|
||||
return 0;
|
||||
|
||||
/* hurrah the memory is not visible ! */
|
||||
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM);
|
||||
rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT;
|
||||
r = ttm_bo_validate(bo, &rbo->placement, false, false);
|
||||
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;
|
||||
}
|
||||
|
||||
offset = bo->mem.start << PAGE_SHIFT;
|
||||
/* this should never happen */
|
||||
if ((offset + size) > rdev->mc.visible_vram_size)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -361,6 +361,11 @@ static ssize_t radeon_set_pm_profile(struct device *dev,
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
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);
|
||||
if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
|
||||
if (strncmp("default", buf, strlen("default")) == 0)
|
||||
@ -409,6 +414,13 @@ static ssize_t radeon_set_pm_method(struct device *dev,
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
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 */
|
||||
if (rdev->pm.pm_method == PM_METHOD_DPM) {
|
||||
count = -EINVAL;
|
||||
@ -446,6 +458,10 @@ static ssize_t radeon_get_dpm_state(struct device *dev,
|
||||
struct radeon_device *rdev = ddev->dev_private;
|
||||
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",
|
||||
(pm == POWER_STATE_TYPE_BATTERY) ? "battery" :
|
||||
(pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance");
|
||||
@ -459,6 +475,11 @@ static ssize_t radeon_set_dpm_state(struct device *dev,
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
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);
|
||||
if (strncmp("battery", buf, strlen("battery")) == 0)
|
||||
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,
|
||||
struct radeon_device *rdev = ddev->dev_private;
|
||||
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",
|
||||
(level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" :
|
||||
(level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
|
||||
@ -500,6 +525,11 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev,
|
||||
enum radeon_dpm_forced_level level;
|
||||
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);
|
||||
if (strncmp("low", buf, strlen("low")) == 0) {
|
||||
level = RADEON_DPM_FORCED_LEVEL_LOW;
|
||||
@ -538,8 +568,14 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev,
|
||||
char *buf)
|
||||
{
|
||||
struct radeon_device *rdev = dev_get_drvdata(dev);
|
||||
struct drm_device *ddev = rdev->ddev;
|
||||
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)
|
||||
temp = radeon_get_temperature(rdev);
|
||||
else
|
||||
@ -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_device *dev = node->minor->dev;
|
||||
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);
|
||||
if (rdev->asic->dpm.debugfs_print_current_performance_level)
|
||||
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,
|
||||
* @p: parser context
|
||||
* @lo: address of lower dword
|
||||
* @hi: address of higher dword
|
||||
* @size: size of checker for relocation buffer
|
||||
*
|
||||
* 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;
|
||||
uint64_t offset;
|
||||
struct radeon_cs_reloc *reloc;
|
||||
uint64_t start, end, offset;
|
||||
unsigned 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)
|
||||
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[hi] = offset >> 32;
|
||||
p->ib.ptr[lo] = start & 0xFFFFFFFF;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
@ -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)
|
||||
{
|
||||
uint32_t handle = 0;
|
||||
bool destroy = false;
|
||||
int session_idx = -1;
|
||||
bool destroyed = false;
|
||||
uint32_t tmp, handle = 0;
|
||||
uint32_t *size = &tmp;
|
||||
int i, r;
|
||||
|
||||
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)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (destroyed) {
|
||||
DRM_ERROR("No other command allowed after destroy!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case 0x00000001: // session
|
||||
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;
|
||||
|
||||
case 0x00000002: // task info
|
||||
break;
|
||||
|
||||
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 0x04000002: // pic control
|
||||
case 0x04000005: // rate control
|
||||
@ -506,23 +572,39 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p)
|
||||
break;
|
||||
|
||||
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)
|
||||
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)
|
||||
return r;
|
||||
break;
|
||||
|
||||
case 0x02000001: // destroy
|
||||
destroy = true;
|
||||
destroyed = true;
|
||||
break;
|
||||
|
||||
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
|
||||
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
|
||||
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)
|
||||
return r;
|
||||
break;
|
||||
@ -532,33 +614,21 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (session_idx == -1) {
|
||||
DRM_ERROR("no session command at start of IB\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
p->idx += len / 4;
|
||||
}
|
||||
|
||||
if (destroy) {
|
||||
if (destroyed) {
|
||||
/* IB contains a destroy msg, free the handle */
|
||||
for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i)
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -595,7 +595,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
|
||||
ndw = 64;
|
||||
|
||||
/* assume the worst case */
|
||||
ndw += vm->max_pde_used * 12;
|
||||
ndw += vm->max_pde_used * 16;
|
||||
|
||||
/* update too big for an IB */
|
||||
if (ndw > 0xfffff)
|
||||
|
@ -107,8 +107,8 @@
|
||||
#define SPLL_CHG_STATUS (1 << 1)
|
||||
#define SPLL_CNTL_MODE 0x618
|
||||
#define SPLL_SW_DIR_CONTROL (1 << 0)
|
||||
# define SPLL_REFCLK_SEL(x) ((x) << 8)
|
||||
# define SPLL_REFCLK_SEL_MASK 0xFF00
|
||||
# define SPLL_REFCLK_SEL(x) ((x) << 26)
|
||||
# define SPLL_REFCLK_SEL_MASK (3 << 26)
|
||||
|
||||
#define CG_SPLL_SPREAD_SPECTRUM 0x620
|
||||
#define SSEN (1 << 0)
|
||||
|
Loading…
Reference in New Issue
Block a user