Commit 9d5715f9 authored by Dave Airlie's avatar Dave Airlie

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

radeon and amdgpu fixes for 4.2.  All over the place:
- fix cursor corruption on resume and re-enable no VT switch on suspend
- vblank fixes
- fix gpuvm error messages
- misc other fixes

* 'drm-fixes-4.2' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: disable vce init on cayman (v2)
  drm/amdgpu: fix timeout calculation
  drm/radeon: check if BO_VA is set before adding it to the invalidation list
  drm/radeon: allways add the VM clear duplicate
  Revert "Revert "drm/radeon: dont switch vt on suspend""
  drm/radeon: Fold radeon_set_cursor() into radeon_show_cursor()
  drm/radeon: unpin cursor BOs on suspend and pin them again on resume (v2)
  drm/radeon: Clean up reference counting and pinning of the cursor BOs
  drm/radeon: fix underflow in r600_cp_dispatch_texture()
  drm/radeon: default to 2048 MB GART size on SI+
  drm/radeon: fix HDP flushing
  drm/radeon: use RCU query for GEM_BUSY syscall
  drm/amdgpu: Handle irqs only based on irq ring, not irq status regs.
  drm/radeon: Handle irqs only based on irq ring, not irq status regs.
parents c4b5fd3f 355c8228
...@@ -352,7 +352,7 @@ unsigned long amdgpu_gem_timeout(uint64_t timeout_ns) ...@@ -352,7 +352,7 @@ unsigned long amdgpu_gem_timeout(uint64_t timeout_ns)
if (((int64_t)timeout_ns) < 0) if (((int64_t)timeout_ns) < 0)
return MAX_SCHEDULE_TIMEOUT; return MAX_SCHEDULE_TIMEOUT;
timeout = ktime_sub_ns(ktime_get(), timeout_ns); timeout = ktime_sub(ns_to_ktime(timeout_ns), ktime_get());
if (ktime_to_ns(timeout) < 0) if (ktime_to_ns(timeout) < 0)
return 0; return 0;
......
...@@ -3403,19 +3403,25 @@ static int dce_v10_0_crtc_irq(struct amdgpu_device *adev, ...@@ -3403,19 +3403,25 @@ static int dce_v10_0_crtc_irq(struct amdgpu_device *adev,
switch (entry->src_data) { switch (entry->src_data) {
case 0: /* vblank */ case 0: /* vblank */
if (disp_int & interrupt_status_offsets[crtc].vblank) { if (disp_int & interrupt_status_offsets[crtc].vblank)
dce_v10_0_crtc_vblank_int_ack(adev, crtc); dce_v10_0_crtc_vblank_int_ack(adev, crtc);
if (amdgpu_irq_enabled(adev, source, irq_type)) { else
drm_handle_vblank(adev->ddev, crtc); DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
}
DRM_DEBUG("IH: D%d vblank\n", crtc + 1); if (amdgpu_irq_enabled(adev, source, irq_type)) {
drm_handle_vblank(adev->ddev, crtc);
} }
DRM_DEBUG("IH: D%d vblank\n", crtc + 1);
break; break;
case 1: /* vline */ case 1: /* vline */
if (disp_int & interrupt_status_offsets[crtc].vline) { if (disp_int & interrupt_status_offsets[crtc].vline)
dce_v10_0_crtc_vline_int_ack(adev, crtc); dce_v10_0_crtc_vline_int_ack(adev, crtc);
DRM_DEBUG("IH: D%d vline\n", crtc + 1); else
} DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
DRM_DEBUG("IH: D%d vline\n", crtc + 1);
break; break;
default: default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", entry->src_id, entry->src_data); DRM_DEBUG("Unhandled interrupt: %d %d\n", entry->src_id, entry->src_data);
......
...@@ -3402,19 +3402,25 @@ static int dce_v11_0_crtc_irq(struct amdgpu_device *adev, ...@@ -3402,19 +3402,25 @@ static int dce_v11_0_crtc_irq(struct amdgpu_device *adev,
switch (entry->src_data) { switch (entry->src_data) {
case 0: /* vblank */ case 0: /* vblank */
if (disp_int & interrupt_status_offsets[crtc].vblank) { if (disp_int & interrupt_status_offsets[crtc].vblank)
dce_v11_0_crtc_vblank_int_ack(adev, crtc); dce_v11_0_crtc_vblank_int_ack(adev, crtc);
if (amdgpu_irq_enabled(adev, source, irq_type)) { else
drm_handle_vblank(adev->ddev, crtc); DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
}
DRM_DEBUG("IH: D%d vblank\n", crtc + 1); if (amdgpu_irq_enabled(adev, source, irq_type)) {
drm_handle_vblank(adev->ddev, crtc);
} }
DRM_DEBUG("IH: D%d vblank\n", crtc + 1);
break; break;
case 1: /* vline */ case 1: /* vline */
if (disp_int & interrupt_status_offsets[crtc].vline) { if (disp_int & interrupt_status_offsets[crtc].vline)
dce_v11_0_crtc_vline_int_ack(adev, crtc); dce_v11_0_crtc_vline_int_ack(adev, crtc);
DRM_DEBUG("IH: D%d vline\n", crtc + 1); else
} DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
DRM_DEBUG("IH: D%d vline\n", crtc + 1);
break; break;
default: default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", entry->src_id, entry->src_data); DRM_DEBUG("Unhandled interrupt: %d %d\n", entry->src_id, entry->src_data);
......
...@@ -3237,19 +3237,25 @@ static int dce_v8_0_crtc_irq(struct amdgpu_device *adev, ...@@ -3237,19 +3237,25 @@ static int dce_v8_0_crtc_irq(struct amdgpu_device *adev,
switch (entry->src_data) { switch (entry->src_data) {
case 0: /* vblank */ case 0: /* vblank */
if (disp_int & interrupt_status_offsets[crtc].vblank) { if (disp_int & interrupt_status_offsets[crtc].vblank)
WREG32(mmLB_VBLANK_STATUS + crtc_offsets[crtc], LB_VBLANK_STATUS__VBLANK_ACK_MASK); WREG32(mmLB_VBLANK_STATUS + crtc_offsets[crtc], LB_VBLANK_STATUS__VBLANK_ACK_MASK);
if (amdgpu_irq_enabled(adev, source, irq_type)) { else
drm_handle_vblank(adev->ddev, crtc); DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
}
DRM_DEBUG("IH: D%d vblank\n", crtc + 1); if (amdgpu_irq_enabled(adev, source, irq_type)) {
drm_handle_vblank(adev->ddev, crtc);
} }
DRM_DEBUG("IH: D%d vblank\n", crtc + 1);
break; break;
case 1: /* vline */ case 1: /* vline */
if (disp_int & interrupt_status_offsets[crtc].vline) { if (disp_int & interrupt_status_offsets[crtc].vline)
WREG32(mmLB_VLINE_STATUS + crtc_offsets[crtc], LB_VLINE_STATUS__VLINE_ACK_MASK); WREG32(mmLB_VLINE_STATUS + crtc_offsets[crtc], LB_VLINE_STATUS__VLINE_ACK_MASK);
DRM_DEBUG("IH: D%d vline\n", crtc + 1); else
} DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
DRM_DEBUG("IH: D%d vline\n", crtc + 1);
break; break;
default: default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", entry->src_id, entry->src_data); DRM_DEBUG("Unhandled interrupt: %d %d\n", entry->src_id, entry->src_data);
......
This diff is collapsed.
This diff is collapsed.
...@@ -2162,18 +2162,20 @@ static int cayman_startup(struct radeon_device *rdev) ...@@ -2162,18 +2162,20 @@ static int cayman_startup(struct radeon_device *rdev)
DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
} }
ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; if (rdev->family == CHIP_ARUBA) {
if (ring->ring_size) ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); if (ring->ring_size)
r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
if (ring->ring_size) if (ring->ring_size)
r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
if (!r) if (!r)
r = vce_v1_0_init(rdev); r = vce_v1_0_init(rdev);
else if (r != -ENOENT) if (r)
DRM_ERROR("radeon: failed initializing VCE (%d).\n", r); DRM_ERROR("radeon: failed initializing VCE (%d).\n", r);
}
r = radeon_ib_pool_init(rdev); r = radeon_ib_pool_init(rdev);
if (r) { if (r) {
...@@ -2396,7 +2398,8 @@ void cayman_fini(struct radeon_device *rdev) ...@@ -2396,7 +2398,8 @@ void cayman_fini(struct radeon_device *rdev)
radeon_irq_kms_fini(rdev); radeon_irq_kms_fini(rdev);
uvd_v1_0_fini(rdev); uvd_v1_0_fini(rdev);
radeon_uvd_fini(rdev); radeon_uvd_fini(rdev);
radeon_vce_fini(rdev); if (rdev->family == CHIP_ARUBA)
radeon_vce_fini(rdev);
cayman_pcie_gart_fini(rdev); cayman_pcie_gart_fini(rdev);
r600_vram_scratch_fini(rdev); r600_vram_scratch_fini(rdev);
radeon_gem_fini(rdev); radeon_gem_fini(rdev);
......
...@@ -4086,23 +4086,27 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -4086,23 +4086,27 @@ int r600_irq_process(struct radeon_device *rdev)
case 1: /* D1 vblank/vline */ case 1: /* D1 vblank/vline */
switch (src_data) { switch (src_data) {
case 0: /* D1 vblank */ case 0: /* D1 vblank */
if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT))
if (rdev->irq.crtc_vblank_int[0]) { DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n");
drm_handle_vblank(rdev->ddev, 0);
rdev->pm.vblank_sync = true; if (rdev->irq.crtc_vblank_int[0]) {
wake_up(&rdev->irq.vblank_queue); drm_handle_vblank(rdev->ddev, 0);
} rdev->pm.vblank_sync = true;
if (atomic_read(&rdev->irq.pflip[0])) wake_up(&rdev->irq.vblank_queue);
radeon_crtc_handle_vblank(rdev, 0);
rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
DRM_DEBUG("IH: D1 vblank\n");
} }
if (atomic_read(&rdev->irq.pflip[0]))
radeon_crtc_handle_vblank(rdev, 0);
rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
DRM_DEBUG("IH: D1 vblank\n");
break; break;
case 1: /* D1 vline */ case 1: /* D1 vline */
if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT))
rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; DRM_DEBUG("IH: D1 vline - IH event w/o asserted irq bit?\n");
DRM_DEBUG("IH: D1 vline\n");
} rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT;
DRM_DEBUG("IH: D1 vline\n");
break; break;
default: default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
...@@ -4112,23 +4116,27 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -4112,23 +4116,27 @@ int r600_irq_process(struct radeon_device *rdev)
case 5: /* D2 vblank/vline */ case 5: /* D2 vblank/vline */
switch (src_data) { switch (src_data) {
case 0: /* D2 vblank */ case 0: /* D2 vblank */
if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT))
if (rdev->irq.crtc_vblank_int[1]) { DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n");
drm_handle_vblank(rdev->ddev, 1);
rdev->pm.vblank_sync = true; if (rdev->irq.crtc_vblank_int[1]) {
wake_up(&rdev->irq.vblank_queue); drm_handle_vblank(rdev->ddev, 1);
} rdev->pm.vblank_sync = true;
if (atomic_read(&rdev->irq.pflip[1])) wake_up(&rdev->irq.vblank_queue);
radeon_crtc_handle_vblank(rdev, 1);
rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
DRM_DEBUG("IH: D2 vblank\n");
} }
if (atomic_read(&rdev->irq.pflip[1]))
radeon_crtc_handle_vblank(rdev, 1);
rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
DRM_DEBUG("IH: D2 vblank\n");
break; break;
case 1: /* D1 vline */ case 1: /* D1 vline */
if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT))
rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; DRM_DEBUG("IH: D2 vline - IH event w/o asserted irq bit?\n");
DRM_DEBUG("IH: D2 vline\n");
} rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT;
DRM_DEBUG("IH: D2 vline\n");
break; break;
default: default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
...@@ -4148,46 +4156,53 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -4148,46 +4156,53 @@ int r600_irq_process(struct radeon_device *rdev)
case 19: /* HPD/DAC hotplug */ case 19: /* HPD/DAC hotplug */
switch (src_data) { switch (src_data) {
case 0: case 0:
if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT))
rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; DRM_DEBUG("IH: HPD1 - IH event w/o asserted irq bit?\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD1\n"); rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT;
} queue_hotplug = true;
DRM_DEBUG("IH: HPD1\n");
break; break;
case 1: case 1:
if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT))
rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; DRM_DEBUG("IH: HPD2 - IH event w/o asserted irq bit?\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD2\n"); rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT;
} queue_hotplug = true;
DRM_DEBUG("IH: HPD2\n");
break; break;
case 4: case 4:
if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT))
rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; DRM_DEBUG("IH: HPD3 - IH event w/o asserted irq bit?\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD3\n"); rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT;
} queue_hotplug = true;
DRM_DEBUG("IH: HPD3\n");
break; break;
case 5: case 5:
if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT))
rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; DRM_DEBUG("IH: HPD4 - IH event w/o asserted irq bit?\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD4\n"); rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT;
} queue_hotplug = true;
DRM_DEBUG("IH: HPD4\n");
break; break;
case 10: case 10:
if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT))
rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; DRM_DEBUG("IH: HPD5 - IH event w/o asserted irq bit?\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD5\n"); rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
} queue_hotplug = true;
DRM_DEBUG("IH: HPD5\n");
break; break;
case 12: case 12:
if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT))
rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; DRM_DEBUG("IH: HPD6 - IH event w/o asserted irq bit?\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD6\n"); rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
} queue_hotplug = true;
DRM_DEBUG("IH: HPD6\n");
break; break;
default: default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
...@@ -4197,18 +4212,22 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -4197,18 +4212,22 @@ int r600_irq_process(struct radeon_device *rdev)
case 21: /* hdmi */ case 21: /* hdmi */
switch (src_data) { switch (src_data) {
case 4: case 4:
if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) { if (!(rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG))
rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG; DRM_DEBUG("IH: HDMI0 - IH event w/o asserted irq bit?\n");
queue_hdmi = true;
DRM_DEBUG("IH: HDMI0\n"); rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG;
} queue_hdmi = true;
DRM_DEBUG("IH: HDMI0\n");
break; break;
case 5: case 5:
if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) { if (!(rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG))
rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG; DRM_DEBUG("IH: HDMI1 - IH event w/o asserted irq bit?\n");
queue_hdmi = true;
DRM_DEBUG("IH: HDMI1\n"); rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG;
} queue_hdmi = true;
DRM_DEBUG("IH: HDMI1\n");
break; break;
default: default:
DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
......
...@@ -2483,7 +2483,7 @@ int r600_cp_dispatch_texture(struct drm_device *dev, ...@@ -2483,7 +2483,7 @@ int r600_cp_dispatch_texture(struct drm_device *dev,
struct drm_buf *buf; struct drm_buf *buf;
u32 *buffer; u32 *buffer;
const u8 __user *data; const u8 __user *data;
int size, pass_size; unsigned int size, pass_size;
u64 src_offset, dst_offset; u64 src_offset, dst_offset;
if (!radeon_check_offset(dev_priv, tex->offset)) { if (!radeon_check_offset(dev_priv, tex->offset)) {
......
...@@ -91,15 +91,34 @@ static void radeon_show_cursor(struct drm_crtc *crtc) ...@@ -91,15 +91,34 @@ static void radeon_show_cursor(struct drm_crtc *crtc)
struct radeon_device *rdev = crtc->dev->dev_private; struct radeon_device *rdev = crtc->dev->dev_private;
if (ASIC_IS_DCE4(rdev)) { if (ASIC_IS_DCE4(rdev)) {
WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
upper_32_bits(radeon_crtc->cursor_addr));
WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
lower_32_bits(radeon_crtc->cursor_addr));
WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN |
EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) |
EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2));
} else if (ASIC_IS_AVIVO(rdev)) { } else if (ASIC_IS_AVIVO(rdev)) {
if (rdev->family >= CHIP_RV770) {
if (radeon_crtc->crtc_id)
WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH,
upper_32_bits(radeon_crtc->cursor_addr));
else
WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH,
upper_32_bits(radeon_crtc->cursor_addr));
}
WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
lower_32_bits(radeon_crtc->cursor_addr));
WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
(AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
} else { } else {
/* offset is from DISP(2)_BASE_ADDRESS */
WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset,
radeon_crtc->cursor_addr - radeon_crtc->legacy_display_base_addr);
switch (radeon_crtc->crtc_id) { switch (radeon_crtc->crtc_id) {
case 0: case 0:
WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL); WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
...@@ -205,8 +224,9 @@ static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y) ...@@ -205,8 +224,9 @@ static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y)
| (x << 16) | (x << 16)
| y)); | y));
/* offset is from DISP(2)_BASE_ADDRESS */ /* offset is from DISP(2)_BASE_ADDRESS */
WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset,
(yorigin * 256))); radeon_crtc->cursor_addr - radeon_crtc->legacy_display_base_addr +
yorigin * 256);
} }
radeon_crtc->cursor_x = x; radeon_crtc->cursor_x = x;
...@@ -227,53 +247,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, ...@@ -227,53 +247,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,
return ret; return ret;
} }
static int radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct radeon_device *rdev = crtc->dev->dev_private;
struct radeon_bo *robj = gem_to_radeon_bo(obj);
uint64_t gpu_addr;
int ret;
ret = radeon_bo_reserve(robj, false);
if (unlikely(ret != 0))
goto fail;
/* Only 27 bit offset for legacy cursor */
ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM,
ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27,
&gpu_addr);
radeon_bo_unreserve(robj);
if (ret)
goto fail;
if (ASIC_IS_DCE4(rdev)) {
WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
upper_32_bits(gpu_addr));
WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
gpu_addr & 0xffffffff);
} else if (ASIC_IS_AVIVO(rdev)) {
if (rdev->family >= CHIP_RV770) {
if (radeon_crtc->crtc_id)
WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr));
else
WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr));
}
WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
gpu_addr & 0xffffffff);
} else {
radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr;
/* offset is from DISP(2)_BASE_ADDRESS */
WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
}
return 0;
fail:
drm_gem_object_unreference_unlocked(obj);
return ret;
}
int radeon_crtc_cursor_set2(struct drm_crtc *crtc, int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
struct drm_file *file_priv, struct drm_file *file_priv,
uint32_t handle, uint32_t handle,
...@@ -283,7 +256,9 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, ...@@ -283,7 +256,9 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
int32_t hot_y) int32_t hot_y)
{ {
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct radeon_device *rdev = crtc->dev->dev_private;
struct drm_gem_object *obj; struct drm_gem_object *obj;
struct radeon_bo *robj;
int ret; int ret;
if (!handle) { if (!handle) {
...@@ -305,6 +280,23 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, ...@@ -305,6 +280,23 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
return -ENOENT; return -ENOENT;
} }
robj = gem_to_radeon_bo(obj);
ret = radeon_bo_reserve(robj, false);
if (ret != 0) {
drm_gem_object_unreference_unlocked(obj);
return ret;
}
/* Only 27 bit offset for legacy cursor */
ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM,
ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27,
&radeon_crtc->cursor_addr);
radeon_bo_unreserve(robj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
drm_gem_object_unreference_unlocked(obj);
return ret;
}
radeon_crtc->cursor_width = width; radeon_crtc->cursor_width = width;
radeon_crtc->cursor_height = height; radeon_crtc->cursor_height = height;
...@@ -323,13 +315,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, ...@@ -323,13 +315,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
radeon_crtc->cursor_hot_y = hot_y; radeon_crtc->cursor_hot_y = hot_y;
} }
ret = radeon_set_cursor(crtc, obj); radeon_show_cursor(crtc);
if (ret)
DRM_ERROR("radeon_set_cursor returned %d, not changing cursor\n",
ret);
else
radeon_show_cursor(crtc);
radeon_lock_cursor(crtc, false); radeon_lock_cursor(crtc, false);
...@@ -341,8 +327,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, ...@@ -341,8 +327,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
radeon_bo_unpin(robj); radeon_bo_unpin(robj);
radeon_bo_unreserve(robj); radeon_bo_unreserve(robj);
} }
if (radeon_crtc->cursor_bo != obj) drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo);
drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo);
} }
radeon_crtc->cursor_bo = obj; radeon_crtc->cursor_bo = obj;
...@@ -360,7 +345,6 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, ...@@ -360,7 +345,6 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
void radeon_cursor_reset(struct drm_crtc *crtc) void radeon_cursor_reset(struct drm_crtc *crtc)
{ {
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
int ret;
if (radeon_crtc->cursor_bo) { if (radeon_crtc->cursor_bo) {
radeon_lock_cursor(crtc, true); radeon_lock_cursor(crtc, true);
...@@ -368,12 +352,7 @@ void radeon_cursor_reset(struct drm_crtc *crtc) ...@@ -368,12 +352,7 @@ void radeon_cursor_reset(struct drm_crtc *crtc)
radeon_cursor_move_locked(crtc, radeon_crtc->cursor_x, radeon_cursor_move_locked(crtc, radeon_crtc->cursor_x,
radeon_crtc->cursor_y); radeon_crtc->cursor_y);
ret = radeon_set_cursor(crtc, radeon_crtc->cursor_bo); radeon_show_cursor(crtc);
if (ret)
DRM_ERROR("radeon_set_cursor returned %d, not showing "
"cursor\n", ret);
else
radeon_show_cursor(crtc);
radeon_lock_cursor(crtc, false); radeon_lock_cursor(crtc, false);
} }
......
...@@ -1079,6 +1079,22 @@ static bool radeon_check_pot_argument(int arg) ...@@ -1079,6 +1079,22 @@ static bool radeon_check_pot_argument(int arg)
return (arg & (arg - 1)) == 0; return (arg & (arg - 1)) == 0;
} }
/**
* Determine a sensible default GART size according to ASIC family.
*
* @family ASIC family name
*/
static int radeon_gart_size_auto(enum radeon_family family)
{
/* default to a larger gart size on newer asics */
if (family >= CHIP_TAHITI)
return 2048;
else if (family >= CHIP_RV770)
return 1024;
else
return 512;
}
/** /**
* radeon_check_arguments - validate module params * radeon_check_arguments - validate module params
* *
...@@ -1097,27 +1113,17 @@ static void radeon_check_arguments(struct radeon_device *rdev) ...@@ -1097,27 +1113,17 @@ static void radeon_check_arguments(struct radeon_device *rdev)
} }
if (radeon_gart_size == -1) { if (radeon_gart_size == -1) {
/* default to a larger gart size on newer asics */ radeon_gart_size = radeon_gart_size_auto(rdev->family);
if (rdev->family >= CHIP_RV770)
radeon_gart_size = 1024;
else
radeon_gart_size = 512;
} }
/* gtt size must be power of two and greater or equal to 32M */ /* gtt size must be power of two and greater or equal to 32M */
if (radeon_gart_size < 32) { if (radeon_gart_size < 32) {
dev_warn(rdev->dev, "gart size (%d) too small\n", dev_warn(rdev->dev, "gart size (%d) too small\n",
radeon_gart_size); radeon_gart_size);
if (rdev->family >= CHIP_RV770) radeon_gart_size = radeon_gart_size_auto(rdev->family);
radeon_gart_size = 1024;
else
radeon_gart_size = 512;
} else if (!radeon_check_pot_argument(radeon_gart_size)) { } else if (!radeon_check_pot_argument(radeon_gart_size)) {
dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n",
radeon_gart_size); radeon_gart_size);
if (rdev->family >= CHIP_RV770) radeon_gart_size = radeon_gart_size_auto(rdev->family);
radeon_gart_size = 1024;
else
radeon_gart_size = 512;
} }
rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20; rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20;
...@@ -1572,11 +1578,21 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) ...@@ -1572,11 +1578,21 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
} }
/* unpin the front buffers */ /* unpin the front buffers and cursors */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->primary->fb); struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->primary->fb);
struct radeon_bo *robj; struct radeon_bo *robj;
if (radeon_crtc->cursor_bo) {
struct radeon_bo *robj = gem_to_radeon_bo(radeon_crtc->cursor_bo);
r = radeon_bo_reserve(robj, false);
if (r == 0) {
radeon_bo_unpin(robj);
radeon_bo_unreserve(robj);
}
}
if (rfb == NULL || rfb->obj == NULL) { if (rfb == NULL || rfb->obj == NULL) {
continue; continue;
} }
...@@ -1639,6 +1655,7 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) ...@@ -1639,6 +1655,7 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
{ {
struct drm_connector *connector; struct drm_connector *connector;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct drm_crtc *crtc;
int r; int r;
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
...@@ -1678,6 +1695,27 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) ...@@ -1678,6 +1695,27 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
radeon_restore_bios_scratch_regs(rdev); radeon_restore_bios_scratch_regs(rdev);
/* pin cursors */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
if (radeon_crtc->cursor_bo) {
struct radeon_bo *robj = gem_to_radeon_bo(radeon_crtc->cursor_bo);
r = radeon_bo_reserve(robj, false);
if (r == 0) {
/* Only 27 bit offset for legacy cursor */
r = radeon_bo_pin_restricted(robj,
RADEON_GEM_DOMAIN_VRAM,
ASIC_IS_AVIVO(rdev) ?
0 : 1 << 27,
&radeon_crtc->cursor_addr);
if (r != 0)
DRM_ERROR("Failed to pin cursor BO (%d)\n", r);
radeon_bo_unreserve(robj);
}
}
}
/* init dig PHYs, disp eng pll */ /* init dig PHYs, disp eng pll */
if (rdev->is_atom_bios) { if (rdev->is_atom_bios) {
radeon_atom_encoder_init(rdev); radeon_atom_encoder_init(rdev);
......
...@@ -257,6 +257,7 @@ static int radeonfb_create(struct drm_fb_helper *helper, ...@@ -257,6 +257,7 @@ static int radeonfb_create(struct drm_fb_helper *helper,
} }
info->par = rfbdev; info->par = rfbdev;
info->skip_vt_switch = true;
ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
if (ret) { if (ret) {
......
...@@ -428,7 +428,6 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, ...@@ -428,7 +428,6 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp) struct drm_file *filp)
{ {
struct radeon_device *rdev = dev->dev_private;
struct drm_radeon_gem_busy *args = data; struct drm_radeon_gem_busy *args = data;
struct drm_gem_object *gobj; struct drm_gem_object *gobj;
struct radeon_bo *robj; struct radeon_bo *robj;
...@@ -440,10 +439,16 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, ...@@ -440,10 +439,16 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
return -ENOENT; return -ENOENT;
} }
robj = gem_to_radeon_bo(gobj); robj = gem_to_radeon_bo(gobj);
r = radeon_bo_wait(robj, &cur_placement, true);
r = reservation_object_test_signaled_rcu(robj->tbo.resv, true);
if (r == 0)
r = -EBUSY;
else
r = 0;
cur_placement = ACCESS_ONCE(robj->tbo.mem.mem_type);
args->domain = radeon_mem_type_to_domain(cur_placement); args->domain = radeon_mem_type_to_domain(cur_placement);
drm_gem_object_unreference_unlocked(gobj); drm_gem_object_unreference_unlocked(gobj);
r = radeon_gem_handle_lockup(rdev, r);
return r; return r;
} }
...@@ -471,6 +476,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, ...@@ -471,6 +476,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
r = ret; r = ret;
/* Flush HDP cache via MMIO if necessary */ /* Flush HDP cache via MMIO if necessary */
cur_placement = ACCESS_ONCE(robj->tbo.mem.mem_type);
if (rdev->asic->mmio_hdp_flush && if (rdev->asic->mmio_hdp_flush &&
radeon_mem_type_to_domain(cur_placement) == RADEON_GEM_DOMAIN_VRAM) radeon_mem_type_to_domain(cur_placement) == RADEON_GEM_DOMAIN_VRAM)
robj->rdev->asic->mmio_hdp_flush(rdev); robj->rdev->asic->mmio_hdp_flush(rdev);
......
...@@ -343,7 +343,6 @@ struct radeon_crtc { ...@@ -343,7 +343,6 @@ struct radeon_crtc {
int max_cursor_width; int max_cursor_width;
int max_cursor_height; int max_cursor_height;
uint32_t legacy_display_base_addr; uint32_t legacy_display_base_addr;
uint32_t legacy_cursor_offset;
enum radeon_rmx_type rmx_type; enum radeon_rmx_type rmx_type;
u8 h_border; u8 h_border;
u8 v_border; u8 v_border;
......
...@@ -493,38 +493,35 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, ...@@ -493,38 +493,35 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
} }
if (bo_va->it.start || bo_va->it.last) { if (bo_va->it.start || bo_va->it.last) {
spin_lock(&vm->status_lock); /* add a clone of the bo_va to clear the old address */
if (list_empty(&bo_va->vm_status)) { struct radeon_bo_va *tmp;
/* add a clone of the bo_va to clear the old address */ tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL);
struct radeon_bo_va *tmp; if (!tmp) {
spin_unlock(&vm->status_lock); mutex_unlock(&vm->mutex);
tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); r = -ENOMEM;
if (!tmp) { goto error_unreserve;
mutex_unlock(&vm->mutex);
r = -ENOMEM;
goto error_unreserve;
}
tmp->it.start = bo_va->it.start;
tmp->it.last = bo_va->it.last;
tmp->vm = vm;
tmp->bo = radeon_bo_ref(bo_va->bo);
spin_lock(&vm->status_lock);
list_add(&tmp->vm_status, &vm->freed);
} }
spin_unlock(&vm->status_lock); tmp->it.start = bo_va->it.start;
tmp->it.last = bo_va->it.last;
tmp->vm = vm;
tmp->bo = radeon_bo_ref(bo_va->bo);
interval_tree_remove(&bo_va->it, &vm->va); interval_tree_remove(&bo_va->it, &vm->va);
spin_lock(&vm->status_lock);
bo_va->it.start = 0; bo_va->it.start = 0;
bo_va->it.last = 0; bo_va->it.last = 0;
list_del_init(&bo_va->vm_status);
list_add(&tmp->vm_status, &vm->freed);
spin_unlock(&vm->status_lock);
} }
if (soffset || eoffset) { if (soffset || eoffset) {
spin_lock(&vm->status_lock);
bo_va->it.start = soffset; bo_va->it.start = soffset;
bo_va->it.last = eoffset - 1; bo_va->it.last = eoffset - 1;
interval_tree_insert(&bo_va->it, &vm->va);
spin_lock(&vm->status_lock);
list_add(&bo_va->vm_status, &vm->cleared); list_add(&bo_va->vm_status, &vm->cleared);
spin_unlock(&vm->status_lock); spin_unlock(&vm->status_lock);
interval_tree_insert(&bo_va->it, &vm->va);
} }
bo_va->flags = flags; bo_va->flags = flags;
...@@ -1158,7 +1155,8 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev, ...@@ -1158,7 +1155,8 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev,
list_for_each_entry(bo_va, &bo->va, bo_list) { list_for_each_entry(bo_va, &bo->va, bo_list) {
spin_lock(&bo_va->vm->status_lock); spin_lock(&bo_va->vm->status_lock);
if (list_empty(&bo_va->vm_status)) if (list_empty(&bo_va->vm_status) &&
(bo_va->it.start || bo_va->it.last))
list_add(&bo_va->vm_status, &bo_va->vm->invalidated); list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
spin_unlock(&bo_va->vm->status_lock); spin_unlock(&bo_va->vm->status_lock);
} }
......
This diff is collapsed.
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