diff options
author | Ilija Hadzic <ihadzic@research.bell-labs.com> | 2013-01-02 18:27:46 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-01-31 16:24:45 -0500 |
commit | e97169930941c4326dd563578369590a52aec707 (patch) | |
tree | 072a99f88189e80155e17a20f20677205e1a00ca /drivers/gpu/drm/radeon/radeon_cs.c | |
parent | c3ad63afcdb931159690aa7ba2906079c3b38a13 (diff) |
drm/radeon: pull out common next_reloc function
next_reloc function does the same thing in all ASICs with
the exception of R600 which has a special case in legacy mode.
Pull out the common function in preparation for refactoring.
Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com>
Reviewed-by: Marek Olšák <maraeo@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cs.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cs.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 7f48d46a757d..1d214b66650f 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -737,3 +737,57 @@ void radeon_cs_dump_packet(struct radeon_cs_parser *p, | |||
737 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); | 737 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); |
738 | } | 738 | } |
739 | 739 | ||
740 | /** | ||
741 | * radeon_cs_packet_next_reloc() - parse next (should be reloc) packet | ||
742 | * @parser: parser structure holding parsing context. | ||
743 | * @data: pointer to relocation data | ||
744 | * @offset_start: starting offset | ||
745 | * @offset_mask: offset mask (to align start offset on) | ||
746 | * @reloc: reloc informations | ||
747 | * | ||
748 | * Check if next packet is relocation packet3, do bo validation and compute | ||
749 | * GPU offset using the provided start. | ||
750 | **/ | ||
751 | int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, | ||
752 | struct radeon_cs_reloc **cs_reloc, | ||
753 | int nomm) | ||
754 | { | ||
755 | struct radeon_cs_chunk *relocs_chunk; | ||
756 | struct radeon_cs_packet p3reloc; | ||
757 | unsigned idx; | ||
758 | int r; | ||
759 | |||
760 | if (p->chunk_relocs_idx == -1) { | ||
761 | DRM_ERROR("No relocation chunk !\n"); | ||
762 | return -EINVAL; | ||
763 | } | ||
764 | *cs_reloc = NULL; | ||
765 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | ||
766 | r = radeon_cs_packet_parse(p, &p3reloc, p->idx); | ||
767 | if (r) | ||
768 | return r; | ||
769 | p->idx += p3reloc.count + 2; | ||
770 | if (p3reloc.type != RADEON_PACKET_TYPE3 || | ||
771 | p3reloc.opcode != RADEON_PACKET3_NOP) { | ||
772 | DRM_ERROR("No packet3 for relocation for packet at %d.\n", | ||
773 | p3reloc.idx); | ||
774 | radeon_cs_dump_packet(p, &p3reloc); | ||
775 | return -EINVAL; | ||
776 | } | ||
777 | idx = radeon_get_ib_value(p, p3reloc.idx + 1); | ||
778 | if (idx >= relocs_chunk->length_dw) { | ||
779 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", | ||
780 | idx, relocs_chunk->length_dw); | ||
781 | radeon_cs_dump_packet(p, &p3reloc); | ||
782 | return -EINVAL; | ||
783 | } | ||
784 | /* FIXME: we assume reloc size is 4 dwords */ | ||
785 | if (nomm) { | ||
786 | *cs_reloc = p->relocs; | ||
787 | (*cs_reloc)->lobj.gpu_offset = | ||
788 | (u64)relocs_chunk->kdata[idx + 3] << 32; | ||
789 | (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0]; | ||
790 | } else | ||
791 | *cs_reloc = p->relocs_ptr[(idx / 4)]; | ||
792 | return 0; | ||
793 | } | ||