Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

+209 -75
+1
drivers/gpu/drm/nouveau/nouveau_drv.h
··· 583 583 uint64_t vm_end; 584 584 struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; 585 585 int vm_vram_pt_nr; 586 + uint64_t vram_sys_base; 586 587 587 588 /* the mtrr covering the FB */ 588 589 int fb_mtrr;
+71 -40
drivers/gpu/drm/nouveau/nouveau_mem.c
··· 285 285 uint32_t flags, uint64_t phys) 286 286 { 287 287 struct drm_nouveau_private *dev_priv = dev->dev_private; 288 - struct nouveau_gpuobj **pgt; 289 - unsigned psz, pfl, pages; 288 + struct nouveau_gpuobj *pgt; 289 + unsigned block; 290 + int i; 290 291 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; 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; 308 300 } 309 301 310 - pages = size >> psz; 311 - 312 302 dev_priv->engine.instmem.prepare_access(dev, true); 313 - if (flags & 0x80000000) { 314 - while (pages--) { 315 - struct nouveau_gpuobj *pt = pgt[virt >> 29]; 316 - unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; 303 + while (size) { 304 + unsigned offset_h = upper_32_bits(phys); 305 + unsigned offset_l = lower_32_bits(phys); 306 + unsigned pte, end; 317 307 318 - nv_wo32(dev, pt, pte++, 0x00000000); 319 - nv_wo32(dev, pt, pte++, 0x00000000); 320 - 321 - virt += (1 << psz); 308 + for (i = 7; i >= 0; i--) { 309 + block = 1 << (i + 1); 310 + if (size >= block && !(virt & (block - 1))) 311 + break; 322 312 } 323 - } else { 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); 313 + offset_l |= (i << 7); 329 314 330 - nv_wo32(dev, pt, pte++, offset_l | pfl); 331 - nv_wo32(dev, pt, pte++, offset_h | flags); 315 + phys += block << 15; 316 + size -= block; 332 317 333 - phys += (1 << psz); 334 - virt += (1 << psz); 318 + while (block) { 319 + pgt = dev_priv->vm_vram_pt[virt >> 14]; 320 + pte = virt & 0x3ffe; 321 + 322 + end = pte + block; 323 + if (end > 16384) 324 + end = 16384; 325 + block -= (end - pte); 326 + virt += (end - pte); 327 + 328 + while (pte < end) { 329 + nv_wo32(dev, pgt, pte++, offset_l); 330 + nv_wo32(dev, pgt, pte++, offset_h); 331 + } 335 332 } 336 333 } 337 334 dev_priv->engine.instmem.finish_access(dev); ··· 353 356 void 354 357 nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) 355 358 { 356 - nv50_mem_vm_bind_linear(dev, virt, size, 0x80000000, 0); 359 + struct drm_nouveau_private *dev_priv = dev->dev_private; 360 + struct nouveau_gpuobj *pgt; 361 + unsigned pages, pte, end; 362 + 363 + virt -= dev_priv->vm_vram_base; 364 + pages = (size >> 16) << 1; 365 + 366 + dev_priv->engine.instmem.prepare_access(dev, true); 367 + while (pages) { 368 + pgt = dev_priv->vm_vram_pt[virt >> 29]; 369 + pte = (virt & 0x1ffe0000ULL) >> 15; 370 + 371 + end = pte + pages; 372 + if (end > 16384) 373 + end = 16384; 374 + pages -= (end - pte); 375 + virt += (end - pte) << 15; 376 + 377 + while (pte < end) 378 + nv_wo32(dev, pgt, pte++, 0); 379 + } 380 + dev_priv->engine.instmem.finish_access(dev); 381 + 382 + nv_wr32(dev, 0x100c80, 0x00050001); 383 + if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { 384 + NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); 385 + NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); 386 + return; 387 + } 388 + 389 + nv_wr32(dev, 0x100c80, 0x00000001); 390 + if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { 391 + NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); 392 + NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); 393 + } 357 394 } 358 395 359 396 /*
+5 -1
drivers/gpu/drm/nouveau/nv04_dac.c
··· 119 119 struct drm_connector *connector) 120 120 { 121 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 123 uint8_t saved_palette0[3], saved_palette_mask; 124 124 uint32_t saved_rtest_ctrl, saved_rgen_ctrl; 125 125 int i; ··· 134 134 if (nv_two_heads(dev)) 135 135 /* only implemented for head A for now */ 136 136 NVSetOwner(dev, 0); 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); 137 140 138 141 saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX); 139 142 NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20); ··· 206 203 NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi); 207 204 NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1); 208 205 NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); 206 + NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); 209 207 210 208 if (blue == 0x18) { 211 209 NV_INFO(dev, "Load detected on head A\n");
+40 -18
drivers/gpu/drm/nouveau/nv50_instmem.c
··· 76 76 for (i = 0x1700; i <= 0x1710; i += 4) 77 77 priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); 78 78 79 + if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) 80 + dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; 81 + else 82 + dev_priv->vram_sys_base = 0; 83 + 79 84 /* Reserve the last MiB of VRAM, we should probably try to avoid 80 85 * setting up the below tables over the top of the VBIOS image at 81 86 * some point. ··· 177 172 * We map the entire fake channel into the start of the PRAMIN BAR 178 173 */ 179 174 ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000, 180 - 0, &priv->pramin_pt); 175 + 0, &priv->pramin_pt); 181 176 if (ret) 182 177 return ret; 183 178 184 - for (i = 0, v = c_offset; i < pt_size; i += 8, v += 0x1000) { 185 - if (v < (c_offset + c_size)) 186 - BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v | 1); 187 - else 188 - BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000009); 179 + v = c_offset | 1; 180 + if (dev_priv->vram_sys_base) { 181 + v += dev_priv->vram_sys_base; 182 + v |= 0x30; 183 + } 184 + 185 + i = 0; 186 + while (v < dev_priv->vram_sys_base + c_offset + c_size) { 187 + BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v); 189 188 BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); 189 + v += 0x1000; 190 + i += 8; 191 + } 192 + 193 + while (i < pt_size) { 194 + BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000000); 195 + BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); 196 + i += 8; 190 197 } 191 198 192 199 BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63); ··· 433 416 { 434 417 struct drm_nouveau_private *dev_priv = dev->dev_private; 435 418 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; 436 - uint32_t pte, pte_end, vram; 419 + struct nouveau_gpuobj *pramin_pt = priv->pramin_pt->gpuobj; 420 + uint32_t pte, pte_end; 421 + uint64_t vram; 437 422 438 423 if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) 439 424 return -EINVAL; ··· 443 424 NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n", 444 425 gpuobj->im_pramin->start, gpuobj->im_pramin->size); 445 426 446 - pte = (gpuobj->im_pramin->start >> 12) << 3; 447 - pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; 427 + pte = (gpuobj->im_pramin->start >> 12) << 1; 428 + pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; 448 429 vram = gpuobj->im_backing_start; 449 430 450 431 NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n", 451 432 gpuobj->im_pramin->start, pte, pte_end); 452 433 NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start); 453 434 435 + vram |= 1; 436 + if (dev_priv->vram_sys_base) { 437 + vram += dev_priv->vram_sys_base; 438 + vram |= 0x30; 439 + } 440 + 454 441 dev_priv->engine.instmem.prepare_access(dev, true); 455 442 while (pte < pte_end) { 456 - nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, vram | 1); 457 - nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); 458 - 459 - pte += 8; 443 + nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram)); 444 + nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram)); 460 445 vram += NV50_INSTMEM_PAGE_SIZE; 461 446 } 462 447 dev_priv->engine.instmem.finish_access(dev); ··· 493 470 if (gpuobj->im_bound == 0) 494 471 return -EINVAL; 495 472 496 - pte = (gpuobj->im_pramin->start >> 12) << 3; 497 - pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; 473 + pte = (gpuobj->im_pramin->start >> 12) << 1; 474 + pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; 498 475 499 476 dev_priv->engine.instmem.prepare_access(dev, true); 500 477 while (pte < pte_end) { 501 - nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, 0x00000009); 502 - nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); 503 - pte += 8; 478 + nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); 479 + nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); 504 480 } 505 481 dev_priv->engine.instmem.finish_access(dev); 506 482
+92 -16
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
··· 182 182 return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid); 183 183 } 184 184 185 - static int vmw_cmd_dma(struct vmw_private *dev_priv, 186 - struct vmw_sw_context *sw_context, 187 - SVGA3dCmdHeader *header) 185 + static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, 186 + struct vmw_sw_context *sw_context, 187 + SVGAGuestPtr *ptr, 188 + struct vmw_dma_buffer **vmw_bo_p) 188 189 { 189 - uint32_t handle; 190 190 struct vmw_dma_buffer *vmw_bo = NULL; 191 191 struct ttm_buffer_object *bo; 192 - struct vmw_surface *srf = NULL; 193 - struct vmw_dma_cmd { 194 - SVGA3dCmdHeader header; 195 - SVGA3dCmdSurfaceDMA dma; 196 - } *cmd; 192 + uint32_t handle = ptr->gmrId; 197 193 struct vmw_relocation *reloc; 198 - int ret; 199 194 uint32_t cur_validate_node; 200 195 struct ttm_validate_buffer *val_buf; 196 + int ret; 201 197 202 - cmd = container_of(header, struct vmw_dma_cmd, header); 203 - handle = cmd->dma.guest.ptr.gmrId; 204 198 ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); 205 199 if (unlikely(ret != 0)) { 206 200 DRM_ERROR("Could not find or use GMR region.\n"); ··· 203 209 bo = &vmw_bo->base; 204 210 205 211 if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) { 206 - DRM_ERROR("Max number of DMA commands per submission" 212 + DRM_ERROR("Max number relocations per submission" 207 213 " exceeded\n"); 208 214 ret = -EINVAL; 209 215 goto out_no_reloc; 210 216 } 211 217 212 218 reloc = &sw_context->relocs[sw_context->cur_reloc++]; 213 - reloc->location = &cmd->dma.guest.ptr; 219 + reloc->location = ptr; 214 220 215 221 cur_validate_node = vmw_dmabuf_validate_node(bo, sw_context->cur_val_buf); 216 222 if (unlikely(cur_validate_node >= VMWGFX_MAX_GMRS)) { ··· 228 234 list_add_tail(&val_buf->head, &sw_context->validate_nodes); 229 235 ++sw_context->cur_val_buf; 230 236 } 237 + *vmw_bo_p = vmw_bo; 238 + return 0; 231 239 240 + out_no_reloc: 241 + vmw_dmabuf_unreference(&vmw_bo); 242 + vmw_bo_p = NULL; 243 + return ret; 244 + } 245 + 246 + static int vmw_cmd_end_query(struct vmw_private *dev_priv, 247 + struct vmw_sw_context *sw_context, 248 + SVGA3dCmdHeader *header) 249 + { 250 + struct vmw_dma_buffer *vmw_bo; 251 + struct vmw_query_cmd { 252 + SVGA3dCmdHeader header; 253 + SVGA3dCmdEndQuery q; 254 + } *cmd; 255 + int ret; 256 + 257 + cmd = container_of(header, struct vmw_query_cmd, header); 258 + ret = vmw_cmd_cid_check(dev_priv, sw_context, header); 259 + if (unlikely(ret != 0)) 260 + return ret; 261 + 262 + ret = vmw_translate_guest_ptr(dev_priv, sw_context, 263 + &cmd->q.guestResult, 264 + &vmw_bo); 265 + if (unlikely(ret != 0)) 266 + return ret; 267 + 268 + vmw_dmabuf_unreference(&vmw_bo); 269 + return 0; 270 + } 271 + 272 + static int vmw_cmd_wait_query(struct vmw_private *dev_priv, 273 + struct vmw_sw_context *sw_context, 274 + SVGA3dCmdHeader *header) 275 + { 276 + struct vmw_dma_buffer *vmw_bo; 277 + struct vmw_query_cmd { 278 + SVGA3dCmdHeader header; 279 + SVGA3dCmdWaitForQuery q; 280 + } *cmd; 281 + int ret; 282 + 283 + cmd = container_of(header, struct vmw_query_cmd, header); 284 + ret = vmw_cmd_cid_check(dev_priv, sw_context, header); 285 + if (unlikely(ret != 0)) 286 + return ret; 287 + 288 + ret = vmw_translate_guest_ptr(dev_priv, sw_context, 289 + &cmd->q.guestResult, 290 + &vmw_bo); 291 + if (unlikely(ret != 0)) 292 + return ret; 293 + 294 + vmw_dmabuf_unreference(&vmw_bo); 295 + return 0; 296 + } 297 + 298 + 299 + static int vmw_cmd_dma(struct vmw_private *dev_priv, 300 + struct vmw_sw_context *sw_context, 301 + SVGA3dCmdHeader *header) 302 + { 303 + struct vmw_dma_buffer *vmw_bo = NULL; 304 + struct ttm_buffer_object *bo; 305 + struct vmw_surface *srf = NULL; 306 + struct vmw_dma_cmd { 307 + SVGA3dCmdHeader header; 308 + SVGA3dCmdSurfaceDMA dma; 309 + } *cmd; 310 + int ret; 311 + 312 + cmd = container_of(header, struct vmw_dma_cmd, header); 313 + ret = vmw_translate_guest_ptr(dev_priv, sw_context, 314 + &cmd->dma.guest.ptr, 315 + &vmw_bo); 316 + if (unlikely(ret != 0)) 317 + return ret; 318 + 319 + bo = &vmw_bo->base; 232 320 ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile, 233 321 cmd->dma.host.sid, &srf); 234 322 if (ret) { ··· 455 379 VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw), 456 380 VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check), 457 381 VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check), 458 - VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_cid_check), 459 - VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_cid_check), 382 + VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query), 383 + VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query), 460 384 VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok), 461 385 VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN, 462 386 &vmw_cmd_blt_surf_screen_check)