aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_cs.c')
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 9ea13d07cc55..69ec24ab8d63 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -2476,8 +2476,10 @@ static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error)
2476 kfree(parser->relocs); 2476 kfree(parser->relocs);
2477 for (i = 0; i < parser->nchunks; i++) { 2477 for (i = 0; i < parser->nchunks; i++) {
2478 kfree(parser->chunks[i].kdata); 2478 kfree(parser->chunks[i].kdata);
2479 kfree(parser->chunks[i].kpage[0]); 2479 if (parser->rdev && (parser->rdev->flags & RADEON_IS_AGP)) {
2480 kfree(parser->chunks[i].kpage[1]); 2480 kfree(parser->chunks[i].kpage[0]);
2481 kfree(parser->chunks[i].kpage[1]);
2482 }
2481 } 2483 }
2482 kfree(parser->chunks); 2484 kfree(parser->chunks);
2483 kfree(parser->chunks_array); 2485 kfree(parser->chunks_array);
@@ -2561,16 +2563,16 @@ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p,
2561 struct radeon_cs_chunk *relocs_chunk; 2563 struct radeon_cs_chunk *relocs_chunk;
2562 unsigned idx; 2564 unsigned idx;
2563 2565
2566 *cs_reloc = NULL;
2564 if (p->chunk_relocs_idx == -1) { 2567 if (p->chunk_relocs_idx == -1) {
2565 DRM_ERROR("No relocation chunk !\n"); 2568 DRM_ERROR("No relocation chunk !\n");
2566 return -EINVAL; 2569 return -EINVAL;
2567 } 2570 }
2568 *cs_reloc = NULL;
2569 relocs_chunk = &p->chunks[p->chunk_relocs_idx]; 2571 relocs_chunk = &p->chunks[p->chunk_relocs_idx];
2570 idx = p->dma_reloc_idx; 2572 idx = p->dma_reloc_idx;
2571 if (idx >= relocs_chunk->length_dw) { 2573 if (idx >= p->nrelocs) {
2572 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", 2574 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
2573 idx, relocs_chunk->length_dw); 2575 idx, p->nrelocs);
2574 return -EINVAL; 2576 return -EINVAL;
2575 } 2577 }
2576 *cs_reloc = p->relocs_ptr[idx]; 2578 *cs_reloc = p->relocs_ptr[idx];
@@ -2677,16 +2679,29 @@ int r600_dma_cs_parse(struct radeon_cs_parser *p)
2677 } 2679 }
2678 p->idx += 7; 2680 p->idx += 7;
2679 } else { 2681 } else {
2680 src_offset = ib[idx+2]; 2682 if (p->family >= CHIP_RV770) {
2681 src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; 2683 src_offset = ib[idx+2];
2682 dst_offset = ib[idx+1]; 2684 src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32;
2683 dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; 2685 dst_offset = ib[idx+1];
2686 dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32;
2684 2687
2685 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); 2688 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
2686 ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); 2689 ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
2687 ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; 2690 ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
2688 ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; 2691 ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
2689 p->idx += 5; 2692 p->idx += 5;
2693 } else {
2694 src_offset = ib[idx+2];
2695 src_offset |= ((u64)(ib[idx+3] & 0xff)) << 32;
2696 dst_offset = ib[idx+1];
2697 dst_offset |= ((u64)(ib[idx+3] & 0xff0000)) << 16;
2698
2699 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
2700 ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
2701 ib[idx+3] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
2702 ib[idx+3] += (upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff) << 16;
2703 p->idx += 4;
2704 }
2690 } 2705 }
2691 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { 2706 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
2692 dev_warn(p->dev, "DMA copy src buffer too small (%llu %lu)\n", 2707 dev_warn(p->dev, "DMA copy src buffer too small (%llu %lu)\n",