Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ilija Hadzic and committed by
Alex Deucher
e9716993 c3ad63af

+57
+3
drivers/gpu/drm/radeon/radeon.h
··· 1978 1978 bool radeon_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p); 1979 1979 void radeon_cs_dump_packet(struct radeon_cs_parser *p, 1980 1980 struct radeon_cs_packet *pkt); 1981 + int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, 1982 + struct radeon_cs_reloc **cs_reloc, 1983 + int nomm); 1981 1984 int r600_cs_common_vline_parse(struct radeon_cs_parser *p, 1982 1985 uint32_t *vline_start_end, 1983 1986 uint32_t *vline_status);
+54
drivers/gpu/drm/radeon/radeon_cs.c
··· 737 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 + }