diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-23 21:13:34 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-23 21:13:34 -0500 |
| commit | 34e3f91b4e66e52b3e189b2f778bd37d68963ca8 (patch) | |
| tree | 83e7a0a2d1865ad413ac76a7a0883d4ed3d52dc8 | |
| parent | 9f3a6284880ceea452903e2043c88d7226736318 (diff) | |
| parent | 4e4ddd47774313accc86b233d6ca2c6a9037a671 (diff) | |
Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
drm/vmwgfx: Fix queries if no dma buffer thrashing is occuring.
drm/nv50: fix vram ptes on IGPs to point at stolen system memory
drm/nv50: fix instmem binding on IGPs to point at stolen system memory
drm/nv50: improve vram page table construction
drm/nv50: more efficient clearing of gpu page table entries
drm/nv50: make nv50_mem_vm_{bind,unbind} operate only on vram
drm/nouveau: Fix up pre-nv17 analog load detection.
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_mem.c | 113 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv04_dac.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_instmem.c | 58 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 108 |
5 files changed, 210 insertions, 76 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 5445cefdd03e..1c15ef37b71c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
| @@ -583,6 +583,7 @@ struct drm_nouveau_private { | |||
| 583 | uint64_t vm_end; | 583 | uint64_t vm_end; |
| 584 | struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; | 584 | struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; |
| 585 | int vm_vram_pt_nr; | 585 | int vm_vram_pt_nr; |
| 586 | uint64_t vram_sys_base; | ||
| 586 | 587 | ||
| 587 | /* the mtrr covering the FB */ | 588 | /* the mtrr covering the FB */ |
| 588 | int fb_mtrr; | 589 | int fb_mtrr; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 8f3a12f614ed..2dc09dbd817d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
| @@ -285,53 +285,50 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, | |||
| 285 | uint32_t flags, uint64_t phys) | 285 | uint32_t flags, uint64_t phys) |
| 286 | { | 286 | { |
| 287 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 287 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 288 | struct nouveau_gpuobj **pgt; | 288 | struct nouveau_gpuobj *pgt; |
| 289 | unsigned psz, pfl, pages; | 289 | unsigned block; |
| 290 | 290 | int i; | |
| 291 | if (virt >= dev_priv->vm_gart_base && | ||
| 292 | (virt + size) < (dev_priv->vm_gart_base + dev_priv->vm_gart_size)) { | ||
| 293 | psz = 12; | ||
| 294 | pgt = &dev_priv->gart_info.sg_ctxdma; | ||
| 295 | pfl = 0x21; | ||
| 296 | virt -= dev_priv->vm_gart_base; | ||
| 297 | } else | ||
| 298 | if (virt >= dev_priv->vm_vram_base && | ||
| 299 | (virt + size) < (dev_priv->vm_vram_base + dev_priv->vm_vram_size)) { | ||
| 300 | psz = 16; | ||
| 301 | pgt = dev_priv->vm_vram_pt; | ||
| 302 | pfl = 0x01; | ||
| 303 | virt -= dev_priv->vm_vram_base; | ||
| 304 | } else { | ||
| 305 | NV_ERROR(dev, "Invalid address: 0x%16llx-0x%16llx\n", | ||
| 306 | virt, virt + size - 1); | ||
| 307 | return -EINVAL; | ||
| 308 | } | ||
| 309 | 291 | ||
| 310 | pages = size >> psz; | 292 | virt = ((virt - dev_priv->vm_vram_base) >> 16) << 1; |
| 293 | size = (size >> 16) << 1; | ||
| 294 | |||
| 295 | phys |= ((uint64_t)flags << 32); | ||
| 296 | phys |= 1; | ||
| 297 | if (dev_priv->vram_sys_base) { | ||
| 298 | phys += dev_priv->vram_sys_base; | ||
| 299 | phys |= 0x30; | ||
| 300 | } | ||
| 311 | 301 | ||
| 312 | dev_priv->engine.instmem.prepare_access(dev, true); | 302 | dev_priv->engine.instmem.prepare_access(dev, true); |
| 313 | if (flags & 0x80000000) { | 303 | while (size) { |
| 314 | while (pages--) { | 304 | unsigned offset_h = upper_32_bits(phys); |
| 315 | struct nouveau_gpuobj *pt = pgt[virt >> 29]; | 305 | unsigned offset_l = lower_32_bits(phys); |
| 316 | unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; | 306 | unsigned pte, end; |
| 307 | |||
| 308 | for (i = 7; i >= 0; i--) { | ||
| 309 | block = 1 << (i + 1); | ||
| 310 | if (size >= block && !(virt & (block - 1))) | ||
| 311 | break; | ||
| 312 | } | ||
| 313 | offset_l |= (i << 7); | ||
| 317 | 314 | ||
| 318 | nv_wo32(dev, pt, pte++, 0x00000000); | 315 | phys += block << 15; |
| 319 | nv_wo32(dev, pt, pte++, 0x00000000); | 316 | size -= block; |
| 320 | 317 | ||
| 321 | virt += (1 << psz); | 318 | while (block) { |
| 322 | } | 319 | pgt = dev_priv->vm_vram_pt[virt >> 14]; |
| 323 | } else { | 320 | pte = virt & 0x3ffe; |
| 324 | while (pages--) { | ||
| 325 | struct nouveau_gpuobj *pt = pgt[virt >> 29]; | ||
| 326 | unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; | ||
| 327 | unsigned offset_h = upper_32_bits(phys) & 0xff; | ||
| 328 | unsigned offset_l = lower_32_bits(phys); | ||
| 329 | 321 | ||
| 330 | nv_wo32(dev, pt, pte++, offset_l | pfl); | 322 | end = pte + block; |
| 331 | nv_wo32(dev, pt, pte++, offset_h | flags); | 323 | if (end > 16384) |
| 324 | end = 16384; | ||
| 325 | block -= (end - pte); | ||
| 326 | virt += (end - pte); | ||
| 332 | 327 | ||
| 333 | phys += (1 << psz); | 328 | while (pte < end) { |
| 334 | virt += (1 << psz); | 329 | nv_wo32(dev, pgt, pte++, offset_l); |
| 330 | nv_wo32(dev, pgt, pte++, offset_h); | ||
| 331 | } | ||
| 335 | } | 332 | } |
| 336 | } | 333 | } |
| 337 | dev_priv->engine.instmem.finish_access(dev); | 334 | dev_priv->engine.instmem.finish_access(dev); |
| @@ -356,7 +353,41 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, | |||
| 356 | void | 353 | void |
| 357 | nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) | 354 | nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) |
| 358 | { | 355 | { |
| 359 | nv50_mem_vm_bind_linear(dev, virt, size, 0x80000000, 0); | 356 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 357 | struct nouveau_gpuobj *pgt; | ||
| 358 | unsigned pages, pte, end; | ||
| 359 | |||
| 360 | virt -= dev_priv->vm_vram_base; | ||
| 361 | pages = (size >> 16) << 1; | ||
| 362 | |||
| 363 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
| 364 | while (pages) { | ||
| 365 | pgt = dev_priv->vm_vram_pt[virt >> 29]; | ||
| 366 | pte = (virt & 0x1ffe0000ULL) >> 15; | ||
| 367 | |||
| 368 | end = pte + pages; | ||
| 369 | if (end > 16384) | ||
| 370 | end = 16384; | ||
| 371 | pages -= (end - pte); | ||
| 372 | virt += (end - pte) << 15; | ||
| 373 | |||
| 374 | while (pte < end) | ||
| 375 | nv_wo32(dev, pgt, pte++, 0); | ||
| 376 | } | ||
| 377 | dev_priv->engine.instmem.finish_access(dev); | ||
| 378 | |||
| 379 | nv_wr32(dev, 0x100c80, 0x00050001); | ||
| 380 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
| 381 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
| 382 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
| 383 | return; | ||
| 384 | } | ||
| 385 | |||
| 386 | nv_wr32(dev, 0x100c80, 0x00000001); | ||
| 387 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
| 388 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
| 389 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
| 390 | } | ||
| 360 | } | 391 | } |
| 361 | 392 | ||
| 362 | /* | 393 | /* |
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index d0e038d28948..1d73b15d70da 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
| @@ -119,7 +119,7 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, | |||
| 119 | struct drm_connector *connector) | 119 | struct drm_connector *connector) |
| 120 | { | 120 | { |
| 121 | struct drm_device *dev = encoder->dev; | 121 | struct drm_device *dev = encoder->dev; |
| 122 | uint8_t saved_seq1, saved_pi, saved_rpc1; | 122 | uint8_t saved_seq1, saved_pi, saved_rpc1, saved_cr_mode; |
| 123 | uint8_t saved_palette0[3], saved_palette_mask; | 123 | uint8_t saved_palette0[3], saved_palette_mask; |
| 124 | uint32_t saved_rtest_ctrl, saved_rgen_ctrl; | 124 | uint32_t saved_rtest_ctrl, saved_rgen_ctrl; |
| 125 | int i; | 125 | int i; |
| @@ -135,6 +135,9 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, | |||
| 135 | /* only implemented for head A for now */ | 135 | /* only implemented for head A for now */ |
| 136 | NVSetOwner(dev, 0); | 136 | NVSetOwner(dev, 0); |
| 137 | 137 | ||
| 138 | saved_cr_mode = NVReadVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX); | ||
| 139 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode | 0x80); | ||
| 140 | |||
| 138 | saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX); | ||
