aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_cs.c
diff options
context:
space:
mode:
authorIlija Hadzic <ihadzic@research.bell-labs.com>2013-01-02 18:27:46 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-01-31 16:24:45 -0500
commite97169930941c4326dd563578369590a52aec707 (patch)
tree072a99f88189e80155e17a20f20677205e1a00ca /drivers/gpu/drm/radeon/radeon_cs.c
parentc3ad63afcdb931159690aa7ba2906079c3b38a13 (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.c54
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 **/
751int 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}