aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-05-23 12:41:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-05-23 12:41:33 -0400
commit2b2d323a31dc8b369a4c0e33705339399021fa83 (patch)
treec74f0b1fadf8d56672d5090489d5fa69e226b12a
parentfc3ac5c75bae55ca6a070eb72038a94d4f130d8d (diff)
parent77c01bef72a5ce5cb24adae6066ed81a52004d30 (diff)
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
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c55
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c40
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c42
-rw-r--r--drivers/gpu/drm/radeon/radeon_vce.c130
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c2
-rw-r--r--drivers/gpu/drm/radeon/sid.h4
11 files changed, 218 insertions, 80 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
index 7762665ad8fd..876de9ac3793 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
@@ -1009,7 +1009,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id,
1009 } 1009 }
1010 1010
1011 if (outp == 8) 1011 if (outp == 8)
1012 return false; 1012 return conf;
1013 1013
1014 data = exec_lookup(priv, head, outp, ctrl, dcb, &ver, &hdr, &cnt, &len, &info1); 1014 data = exec_lookup(priv, head, outp, ctrl, dcb, &ver, &hdr, &cnt, &len, &info1);
1015 if (data == 0x0000) 1015 if (data == 0x0000)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
index 43fec17ea540..bbf117be572f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
@@ -40,6 +40,7 @@ pwm_info(struct nouveau_therm *therm, int line)
40 case 0x00: return 2; 40 case 0x00: return 2;
41 case 0x19: return 1; 41 case 0x19: return 1;
42 case 0x1c: return 0; 42 case 0x1c: return 0;
43 case 0x1e: return 2;
43 default: 44 default:
44 break; 45 break;
45 } 46 }
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 68528619834a..8149e7cf4303 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1642,6 +1642,7 @@ struct radeon_vce {
1642 unsigned fb_version; 1642 unsigned fb_version;
1643 atomic_t handles[RADEON_MAX_VCE_HANDLES]; 1643 atomic_t handles[RADEON_MAX_VCE_HANDLES];
1644 struct drm_file *filp[RADEON_MAX_VCE_HANDLES]; 1644 struct drm_file *filp[RADEON_MAX_VCE_HANDLES];
1645 unsigned img_size[RADEON_MAX_VCE_HANDLES];
1645 struct delayed_work idle_work; 1646 struct delayed_work idle_work;
1646}; 1647};
1647 1648
@@ -1655,7 +1656,7 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
1655 uint32_t handle, struct radeon_fence **fence); 1656 uint32_t handle, struct radeon_fence **fence);
1656void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp); 1657void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp);
1657void radeon_vce_note_usage(struct radeon_device *rdev); 1658void radeon_vce_note_usage(struct radeon_device *rdev);
1658int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi); 1659int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi, unsigned size);
1659int radeon_vce_cs_parse(struct radeon_cs_parser *p); 1660int radeon_vce_cs_parse(struct radeon_cs_parser *p);
1660bool radeon_vce_semaphore_emit(struct radeon_device *rdev, 1661bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
1661 struct radeon_ring *ring, 1662 struct radeon_ring *ring,
@@ -2640,7 +2641,8 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
2640#define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE)) 2641#define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE))
2641#define ASIC_IS_DCE81(rdev) ((rdev->family == CHIP_KAVERI)) 2642#define ASIC_IS_DCE81(rdev) ((rdev->family == CHIP_KAVERI))
2642#define ASIC_IS_DCE82(rdev) ((rdev->family == CHIP_BONAIRE)) 2643#define ASIC_IS_DCE82(rdev) ((rdev->family == CHIP_BONAIRE))
2643#define ASIC_IS_DCE83(rdev) ((rdev->family == CHIP_KABINI)) 2644#define ASIC_IS_DCE83(rdev) ((rdev->family == CHIP_KABINI) || \
2645 (rdev->family == CHIP_MULLINS))
2644 2646
2645#define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \ 2647#define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \
2646 (rdev->ddev->pdev->device == 0x6850) || \ 2648 (rdev->ddev->pdev->device == 0x6850) || \
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index b3633d9a5317..9ab30976287d 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -196,6 +196,20 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
196 } 196 }
197 } 197 }
198 198
199 if (!found) {
200 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
201 dhandle = ACPI_HANDLE(&pdev->dev);
202 if (!dhandle)
203 continue;
204
205 status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
206 if (!ACPI_FAILURE(status)) {
207 found = true;
208 break;
209 }
210 }
211 }
212
199 if (!found) 213 if (!found)
200 return false; 214 return false;
201 215
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 408b6ac53f0b..f00dbbf4d806 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -999,7 +999,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
999 999
1000 /* avoid high jitter with small fractional dividers */ 1000 /* avoid high jitter with small fractional dividers */
1001 if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) { 1001 if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) {
1002 fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 60); 1002 fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 50);
1003 if (fb_div < fb_div_min) { 1003 if (fb_div < fb_div_min) {
1004 unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div); 1004 unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div);
1005 fb_div *= tmp; 1005 fb_div *= tmp;
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 0cc47f12d995..eaaedba04675 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -577,28 +577,29 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
577 return r; 577 return r;
578 } 578 }
579 579
580 r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); 580 if (rdev->accel_working) {
581 if (r) { 581 r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
582 radeon_vm_fini(rdev, &fpriv->vm); 582 if (r) {
583 kfree(fpriv); 583 radeon_vm_fini(rdev, &fpriv->vm);
584 return r; 584 kfree(fpriv);
585 } 585 return r;
586 }
586 587
587 /* map the ib pool buffer read only into 588 /* map the ib pool buffer read only into
588 * virtual address space */ 589 * virtual address space */
589 bo_va = radeon_vm_bo_add(rdev, &fpriv->vm, 590 bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
590 rdev->ring_tmp_bo.bo); 591 rdev->ring_tmp_bo.bo);
591 r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, 592 r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
592 RADEON_VM_PAGE_READABLE | 593 RADEON_VM_PAGE_READABLE |
593 RADEON_VM_PAGE_SNOOPED); 594 RADEON_VM_PAGE_SNOOPED);
594 595
595 radeon_bo_unreserve(rdev->ring_tmp_bo.bo); 596 radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
596 if (r) { 597 if (r) {
597 radeon_vm_fini(rdev, &fpriv->vm); 598 radeon_vm_fini(rdev, &fpriv->vm);
598 kfree(fpriv); 599 kfree(fpriv);
599 return r; 600 return r;
601 }
600 } 602 }
601
602 file_priv->driver_priv = fpriv; 603 file_priv->driver_priv = fpriv;
603 } 604 }
604 605
@@ -626,13 +627,15 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
626 struct radeon_bo_va *bo_va; 627 struct radeon_bo_va *bo_va;
627 int r; 628 int r;
628 629
629 r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); 630 if (rdev->accel_working) {
630 if (!r) { 631 r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
631 bo_va = radeon_vm_bo_find(&fpriv->vm, 632 if (!r) {
632 rdev->ring_tmp_bo.bo); 633 bo_va = radeon_vm_bo_find(&fpriv->vm,
633 if (bo_va) 634 rdev->ring_tmp_bo.bo);
634 radeon_vm_bo_rmv(rdev, bo_va); 635 if (bo_va)
635 radeon_bo_unreserve(rdev->ring_tmp_bo.bo); 636 radeon_vm_bo_rmv(rdev, bo_va);
637 radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
638 }
636 } 639 }
637 640
638 radeon_vm_fini(rdev, &fpriv->vm); 641 radeon_vm_fini(rdev, &fpriv->vm);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 19bec0dbfa38..4faa4d6f9bb4 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -458,7 +458,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
458 * into account. We don't want to disallow buffer moves 458 * into account. We don't want to disallow buffer moves
459 * completely. 459 * completely.
460 */ 460 */
461 if (current_domain != RADEON_GEM_DOMAIN_CPU && 461 if ((lobj->alt_domain & current_domain) != 0 &&
462 (domain & current_domain) == 0 && /* will be moved */ 462 (domain & current_domain) == 0 && /* will be moved */
463 bytes_moved > bytes_moved_threshold) { 463 bytes_moved > bytes_moved_threshold) {
464 /* don't move it */ 464 /* don't move it */
@@ -699,22 +699,30 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
699 rbo = container_of(bo, struct radeon_bo, tbo); 699 rbo = container_of(bo, struct radeon_bo, tbo);
700 radeon_bo_check_tiling(rbo, 0, 0); 700 radeon_bo_check_tiling(rbo, 0, 0);
701 rdev = rbo->rdev; 701 rdev = rbo->rdev;
702 if (bo->mem.mem_type == TTM_PL_VRAM) { 702 if (bo->mem.mem_type != TTM_PL_VRAM)
703 size = bo->mem.num_pages << PAGE_SHIFT; 703 return 0;
704 offset = bo->mem.start << PAGE_SHIFT; 704
705 if ((offset + size) > rdev->mc.visible_vram_size) { 705 size = bo->mem.num_pages << PAGE_SHIFT;
706 /* hurrah the memory is not visible ! */ 706 offset = bo->mem.start << PAGE_SHIFT;
707 radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM); 707 if ((offset + size) <= rdev->mc.visible_vram_size)
708 rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT; 708 return 0;
709 r = ttm_bo_validate(bo, &rbo->placement, false, false); 709
710 if (unlikely(r != 0)) 710 /* hurrah the memory is not visible ! */
711 return r; 711 radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM);
712 offset = bo->mem.start << PAGE_SHIFT; 712 rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT;
713 /* this should not happen */ 713 r = ttm_bo_validate(bo, &rbo->placement, false, false);
714 if ((offset + size) > rdev->mc.visible_vram_size) 714 if (unlikely(r == -ENOMEM)) {
715 return -EINVAL; 715 radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT);
716 } 716 return ttm_bo_validate(bo, &rbo->placement, false, false);
717 } else if (unlikely(r != 0)) {
718 return r;
717 } 719 }
720
721 offset = bo->mem.start << PAGE_SHIFT;
722 /* this should never happen */
723 if ((offset + size) > rdev->mc.visible_vram_size)
724 return -EINVAL;
725
718 return 0; 726 return 0;
719} 727}
720 728
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index f30b8426eee2..53d6e1bb48dc 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -361,6 +361,11 @@ static ssize_t radeon_set_pm_profile(struct device *dev,
361 struct drm_device *ddev = dev_get_drvdata(dev); 361 struct drm_device *ddev = dev_get_drvdata(dev);
362 struct radeon_device *rdev = ddev->dev_private; 362 struct radeon_device *rdev = ddev->dev_private;
363 363
364 /* Can't set profile when the card is off */
365 if ((rdev->flags & RADEON_IS_PX) &&
366 (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
367 return -EINVAL;
368
364 mutex_lock(&rdev->pm.mutex); 369 mutex_lock(&rdev->pm.mutex);
365 if (rdev->pm.pm_method == PM_METHOD_PROFILE) { 370 if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
366 if (strncmp("default", buf, strlen("default")) == 0) 371 if (strncmp("default", buf, strlen("default")) == 0)
@@ -409,6 +414,13 @@ static ssize_t radeon_set_pm_method(struct device *dev,
409 struct drm_device *ddev = dev_get_drvdata(dev); 414 struct drm_device *ddev = dev_get_drvdata(dev);
410 struct radeon_device *rdev = ddev->dev_private; 415 struct radeon_device *rdev = ddev->dev_private;
411 416
417 /* Can't set method when the card is off */
418 if ((rdev->flags & RADEON_IS_PX) &&
419 (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
420 count = -EINVAL;
421 goto fail;
422 }
423
412 /* we don't support the legacy modes with dpm */ 424 /* we don't support the legacy modes with dpm */
413 if (rdev->pm.pm_method == PM_METHOD_DPM) { 425 if (rdev->pm.pm_method == PM_METHOD_DPM) {
414 count = -EINVAL; 426 count = -EINVAL;
@@ -446,6 +458,10 @@ static ssize_t radeon_get_dpm_state(struct device *dev,
446 struct radeon_device *rdev = ddev->dev_private; 458 struct radeon_device *rdev = ddev->dev_private;
447 enum radeon_pm_state_type pm = rdev->pm.dpm.user_state; 459 enum radeon_pm_state_type pm = rdev->pm.dpm.user_state;
448 460
461 if ((rdev->flags & RADEON_IS_PX) &&
462 (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
463 return snprintf(buf, PAGE_SIZE, "off\n");
464
449 return snprintf(buf, PAGE_SIZE, "%s\n", 465 return snprintf(buf, PAGE_SIZE, "%s\n",
450 (pm == POWER_STATE_TYPE_BATTERY) ? "battery" : 466 (pm == POWER_STATE_TYPE_BATTERY) ? "battery" :
451 (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); 467 (pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance");
@@ -459,6 +475,11 @@ static ssize_t radeon_set_dpm_state(struct device *dev,
459 struct drm_device *ddev = dev_get_drvdata(dev); 475 struct drm_device *ddev = dev_get_drvdata(dev);
460 struct radeon_device *rdev = ddev->dev_private; 476 struct radeon_device *rdev = ddev->dev_private;
461 477
478 /* Can't set dpm state when the card is off */
479 if ((rdev->flags & RADEON_IS_PX) &&
480 (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
481 return -EINVAL;
482
462 mutex_lock(&rdev->pm.mutex); 483 mutex_lock(&rdev->pm.mutex);
463 if (strncmp("battery", buf, strlen("battery")) == 0) 484 if (strncmp("battery", buf, strlen("battery")) == 0)
464 rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY; 485 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 struct radeon_device *rdev = ddev->dev_private; 506 struct radeon_device *rdev = ddev->dev_private;
486 enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; 507 enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level;
487 508
509 if ((rdev->flags & RADEON_IS_PX) &&
510 (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
511 return snprintf(buf, PAGE_SIZE, "off\n");
512
488 return snprintf(buf, PAGE_SIZE, "%s\n", 513 return snprintf(buf, PAGE_SIZE, "%s\n",
489 (level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" : 514 (level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" :
490 (level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); 515 (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 enum radeon_dpm_forced_level level; 525 enum radeon_dpm_forced_level level;
501 int ret = 0; 526 int ret = 0;
502 527
528 /* Can't force performance level when the card is off */
529 if ((rdev->flags & RADEON_IS_PX) &&
530 (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
531 return -EINVAL;
532
503 mutex_lock(&rdev->pm.mutex); 533 mutex_lock(&rdev->pm.mutex);
504 if (strncmp("low", buf, strlen("low")) == 0) { 534 if (strncmp("low", buf, strlen("low")) == 0) {
505 level = RADEON_DPM_FORCED_LEVEL_LOW; 535 level = RADEON_DPM_FORCED_LEVEL_LOW;
@@ -538,8 +568,14 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev,
538 char *buf) 568 char *buf)
539{ 569{
540 struct radeon_device *rdev = dev_get_drvdata(dev); 570 struct radeon_device *rdev = dev_get_drvdata(dev);
571 struct drm_device *ddev = rdev->ddev;
541 int temp; 572 int temp;
542 573
574 /* Can't get temperature when the card is off */
575 if ((rdev->flags & RADEON_IS_PX) &&
576 (ddev->switch_power_state != DRM_SWITCH_POWER_ON))
577 return -EINVAL;
578
543 if (rdev->asic->pm.get_temperature) 579 if (rdev->asic->pm.get_temperature)
544 temp = radeon_get_temperature(rdev); 580 temp = radeon_get_temperature(rdev);
545 else 581 else
@@ -1614,8 +1650,12 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
1614 struct drm_info_node *node = (struct drm_info_node *) m->private; 1650 struct drm_info_node *node = (struct drm_info_node *) m->private;
1615 struct drm_device *dev = node->minor->dev; 1651 struct drm_device *dev = node->minor->dev;
1616 struct radeon_device *rdev = dev->dev_private; 1652 struct radeon_device *rdev = dev->dev_private;
1653 struct drm_device *ddev = rdev->ddev;
1617 1654
1618 if (rdev->pm.dpm_enabled) { 1655 if ((rdev->flags & RADEON_IS_PX) &&
1656 (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
1657 seq_printf(m, "PX asic powered off\n");
1658 } else if (rdev->pm.dpm_enabled) {
1619 mutex_lock(&rdev->pm.mutex); 1659 mutex_lock(&rdev->pm.mutex);
1620 if (rdev->asic->dpm.debugfs_print_current_performance_level) 1660 if (rdev->asic->dpm.debugfs_print_current_performance_level)
1621 radeon_dpm_debugfs_print_current_performance_level(rdev, m); 1661 radeon_dpm_debugfs_print_current_performance_level(rdev, m);
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c
index f73324c81491..3971d968af6c 100644
--- a/drivers/gpu/drm/radeon/radeon_vce.c
+++ b/drivers/gpu/drm/radeon/radeon_vce.c
@@ -443,13 +443,16 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
443 * @p: parser context 443 * @p: parser context
444 * @lo: address of lower dword 444 * @lo: address of lower dword
445 * @hi: address of higher dword 445 * @hi: address of higher dword
446 * @size: size of checker for relocation buffer
446 * 447 *
447 * Patch relocation inside command stream with real buffer address 448 * Patch relocation inside command stream with real buffer address
448 */ 449 */
449int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi) 450int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi,
451 unsigned size)
450{ 452{
451 struct radeon_cs_chunk *relocs_chunk; 453 struct radeon_cs_chunk *relocs_chunk;
452 uint64_t offset; 454 struct radeon_cs_reloc *reloc;
455 uint64_t start, end, offset;
453 unsigned idx; 456 unsigned idx;
454 457
455 relocs_chunk = &p->chunks[p->chunk_relocs_idx]; 458 relocs_chunk = &p->chunks[p->chunk_relocs_idx];
@@ -462,15 +465,60 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi)
462 return -EINVAL; 465 return -EINVAL;
463 } 466 }
464 467
465 offset += p->relocs_ptr[(idx / 4)]->gpu_offset; 468 reloc = p->relocs_ptr[(idx / 4)];
469 start = reloc->gpu_offset;
470 end = start + radeon_bo_size(reloc->robj);
471 start += offset;
466 472
467 p->ib.ptr[lo] = offset & 0xFFFFFFFF; 473 p->ib.ptr[lo] = start & 0xFFFFFFFF;
468 p->ib.ptr[hi] = offset >> 32; 474 p->ib.ptr[hi] = start >> 32;
475
476 if (end <= start) {
477 DRM_ERROR("invalid reloc offset %llX!\n", offset);
478 return -EINVAL;
479 }
480 if ((end - start) < size) {
481 DRM_ERROR("buffer to small (%d / %d)!\n",
482 (unsigned)(end - start), size);
483 return -EINVAL;
484 }
469 485
470 return 0; 486 return 0;
471} 487}
472 488
473/** 489/**
490 * radeon_vce_validate_handle - validate stream handle
491 *
492 * @p: parser context
493 * @handle: handle to validate
494 *
495 * Validates the handle and return the found session index or -EINVAL
496 * we we don't have another free session index.
497 */
498int radeon_vce_validate_handle(struct radeon_cs_parser *p, uint32_t handle)
499{
500 unsigned i;
501
502 /* validate the handle */
503 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
504 if (atomic_read(&p->rdev->vce.handles[i]) == handle)
505 return i;
506 }
507
508 /* handle not found try to alloc a new one */
509 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
510 if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) {
511 p->rdev->vce.filp[i] = p->filp;
512 p->rdev->vce.img_size[i] = 0;
513 return i;
514 }
515 }
516
517 DRM_ERROR("No more free VCE handles!\n");
518 return -EINVAL;
519}
520
521/**
474 * radeon_vce_cs_parse - parse and validate the command stream 522 * radeon_vce_cs_parse - parse and validate the command stream
475 * 523 *
476 * @p: parser context 524 * @p: parser context
@@ -478,8 +526,10 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi)
478 */ 526 */
479int radeon_vce_cs_parse(struct radeon_cs_parser *p) 527int radeon_vce_cs_parse(struct radeon_cs_parser *p)
480{ 528{
481 uint32_t handle = 0; 529 int session_idx = -1;
482 bool destroy = false; 530 bool destroyed = false;
531 uint32_t tmp, handle = 0;
532 uint32_t *size = &tmp;
483 int i, r; 533 int i, r;
484 534
485 while (p->idx < p->chunks[p->chunk_ib_idx].length_dw) { 535 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 return -EINVAL; 541 return -EINVAL;
492 } 542 }
493 543
544 if (destroyed) {
545 DRM_ERROR("No other command allowed after destroy!\n");
546 return -EINVAL;
547 }
548
494 switch (cmd) { 549 switch (cmd) {
495 case 0x00000001: // session 550 case 0x00000001: // session
496 handle = radeon_get_ib_value(p, p->idx + 2); 551 handle = radeon_get_ib_value(p, p->idx + 2);
552 session_idx = radeon_vce_validate_handle(p, handle);
553 if (session_idx < 0)
554 return session_idx;
555 size = &p->rdev->vce.img_size[session_idx];
497 break; 556 break;
498 557
499 case 0x00000002: // task info 558 case 0x00000002: // task info
559 break;
560
500 case 0x01000001: // create 561 case 0x01000001: // create
562 *size = radeon_get_ib_value(p, p->idx + 8) *
563 radeon_get_ib_value(p, p->idx + 10) *
564 8 * 3 / 2;
565 break;
566
501 case 0x04000001: // config extension 567 case 0x04000001: // config extension
502 case 0x04000002: // pic control 568 case 0x04000002: // pic control
503 case 0x04000005: // rate control 569 case 0x04000005: // rate control
@@ -506,23 +572,39 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p)
506 break; 572 break;
507 573
508 case 0x03000001: // encode 574 case 0x03000001: // encode
509 r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9); 575 r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9,
576 *size);
510 if (r) 577 if (r)
511 return r; 578 return r;
512 579
513 r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11); 580 r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11,
581 *size / 3);
514 if (r) 582 if (r)
515 return r; 583 return r;
516 break; 584 break;
517 585
518 case 0x02000001: // destroy 586 case 0x02000001: // destroy
519 destroy = true; 587 destroyed = true;
520 break; 588 break;
521 589
522 case 0x05000001: // context buffer 590 case 0x05000001: // context buffer
591 r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
592 *size * 2);
593 if (r)
594 return r;
595 break;
596
523 case 0x05000004: // video bitstream buffer 597 case 0x05000004: // video bitstream buffer
598 tmp = radeon_get_ib_value(p, p->idx + 4);
599 r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
600 tmp);
601 if (r)
602 return r;
603 break;
604
524 case 0x05000005: // feedback buffer 605 case 0x05000005: // feedback buffer
525 r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2); 606 r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2,
607 4096);
526 if (r) 608 if (r)
527 return r; 609 return r;
528 break; 610 break;
@@ -532,33 +614,21 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p)
532 return -EINVAL; 614 return -EINVAL;
533 } 615 }
534 616
617 if (session_idx == -1) {
618 DRM_ERROR("no session command at start of IB\n");
619 return -EINVAL;
620 }
621
535 p->idx += len / 4; 622 p->idx += len / 4;
536 } 623 }
537 624
538 if (destroy) { 625 if (destroyed) {
539 /* IB contains a destroy msg, free the handle */ 626 /* IB contains a destroy msg, free the handle */
540 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) 627 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i)
541 atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0); 628 atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0);
542
543 return 0;
544 }
545
546 /* create or encode, validate the handle */
547 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
548 if (atomic_read(&p->rdev->vce.handles[i]) == handle)
549 return 0;
550 } 629 }
551 630
552 /* handle not found try to alloc a new one */ 631 return 0;
553 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
554 if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) {
555 p->rdev->vce.filp[i] = p->filp;
556 return 0;
557 }
558 }
559
560 DRM_ERROR("No more free VCE handles!\n");
561 return -EINVAL;
562} 632}
563 633
564/** 634/**
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index 2aae6ce49d32..d9ab99f47612 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -595,7 +595,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
595 ndw = 64; 595 ndw = 64;
596 596
597 /* assume the worst case */ 597 /* assume the worst case */
598 ndw += vm->max_pde_used * 12; 598 ndw += vm->max_pde_used * 16;
599 599
600 /* update too big for an IB */ 600 /* update too big for an IB */
601 if (ndw > 0xfffff) 601 if (ndw > 0xfffff)
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index 683532f84931..7321283602ce 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -107,8 +107,8 @@
107#define SPLL_CHG_STATUS (1 << 1) 107#define SPLL_CHG_STATUS (1 << 1)
108#define SPLL_CNTL_MODE 0x618 108#define SPLL_CNTL_MODE 0x618
109#define SPLL_SW_DIR_CONTROL (1 << 0) 109#define SPLL_SW_DIR_CONTROL (1 << 0)
110# define SPLL_REFCLK_SEL(x) ((x) << 8) 110# define SPLL_REFCLK_SEL(x) ((x) << 26)
111# define SPLL_REFCLK_SEL_MASK 0xFF00 111# define SPLL_REFCLK_SEL_MASK (3 << 26)
112 112
113#define CG_SPLL_SPREAD_SPECTRUM 0x620 113#define CG_SPLL_SPREAD_SPECTRUM 0x620
114#define SSEN (1 << 0) 114#define SSEN (1 << 0)