diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_cs.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_cs.c | 43 |
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", |