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 | |
parent | c3ad63afcdb931159690aa7ba2906079c3b38a13 (diff) | |
download | linux-stable-e97169930941c4326dd563578369590a52aec707.tar.gz linux-stable-e97169930941c4326dd563578369590a52aec707.tar.bz2 linux-stable-e97169930941c4326dd563578369590a52aec707.zip |
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>
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cs.c | 54 |
2 files changed, 57 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5f964309ba68..fa17ce026aba 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1978,6 +1978,9 @@ int radeon_cs_packet_parse(struct radeon_cs_parser *p, bool radeon_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p); void radeon_cs_dump_packet(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt); +int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, + struct radeon_cs_reloc **cs_reloc, + int nomm); int r600_cs_common_vline_parse(struct radeon_cs_parser *p, uint32_t *vline_start_end, uint32_t *vline_status); 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, DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); } +/** + * radeon_cs_packet_next_reloc() - parse next (should be reloc) packet + * @parser: parser structure holding parsing context. + * @data: pointer to relocation data + * @offset_start: starting offset + * @offset_mask: offset mask (to align start offset on) + * @reloc: reloc informations + * + * Check if next packet is relocation packet3, do bo validation and compute + * GPU offset using the provided start. + **/ +int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, + struct radeon_cs_reloc **cs_reloc, + int nomm) +{ + struct radeon_cs_chunk *relocs_chunk; + struct radeon_cs_packet p3reloc; + unsigned idx; + int r; + + if (p->chunk_relocs_idx == -1) { + DRM_ERROR("No relocation chunk !\n"); + return -EINVAL; + } + *cs_reloc = NULL; + relocs_chunk = &p->chunks[p->chunk_relocs_idx]; + r = radeon_cs_packet_parse(p, &p3reloc, p->idx); + if (r) + return r; + p->idx += p3reloc.count + 2; + if (p3reloc.type != RADEON_PACKET_TYPE3 || + p3reloc.opcode != RADEON_PACKET3_NOP) { + DRM_ERROR("No packet3 for relocation for packet at %d.\n", + p3reloc.idx); + radeon_cs_dump_packet(p, &p3reloc); + return -EINVAL; + } + idx = radeon_get_ib_value(p, p3reloc.idx + 1); + if (idx >= relocs_chunk->length_dw) { + DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", + idx, relocs_chunk->length_dw); + radeon_cs_dump_packet(p, &p3reloc); + return -EINVAL; + } + /* FIXME: we assume reloc size is 4 dwords */ + if (nomm) { + *cs_reloc = p->relocs; + (*cs_reloc)->lobj.gpu_offset = + (u64)relocs_chunk->kdata[idx + 3] << 32; + (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0]; + } else + *cs_reloc = p->relocs_ptr[(idx / 4)]; + return 0; +} |