The following set of patches refactor the CS-parser logic in an effort to consolidate the code that is repeated across ASIC-specific files. All patches except #8 are function-neutral, that is they preserve the existing functionality of the driver. Patch #8 adds one extra check for WAIT_REG_MEM packet that I believe should be there.
I have been running with these patches for about a month on several machines with Evergreen and NI GPUs without noticing any regressions. I also ran quick tests on all Radeon GPUs that I had around, which range from R300 through NI cards.
The patches have been rebased to the current state of Dave's drm-next branch.
regards,
Ilija
length_dw field was assigned twice. While at it, move user_ptr assignment together with all other assignments to p->chunks[i] structure to make the code more readable.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/radeon_cs.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 396baba0..4be64e0 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -203,7 +203,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) p->chunks[i].length_dw = user_chunk.length_dw; p->chunks[i].kdata = NULL; p->chunks[i].chunk_id = user_chunk.chunk_id; - + p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) { p->chunk_relocs_idx = i; } @@ -226,9 +226,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) return -EINVAL; }
- p->chunks[i].length_dw = user_chunk.length_dw; - p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; - cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data; if ((p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) || (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS)) {
For the series:
Reviewed-by: Marek Olšák maraeo@gmail.com
Marek
On Thu, Jan 3, 2013 at 12:27 AM, Ilija Hadzic ihadzic@research.bell-labs.com wrote:
length_dw field was assigned twice. While at it, move user_ptr assignment together with all other assignments to p->chunks[i] structure to make the code more readable.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com
drivers/gpu/drm/radeon/radeon_cs.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 396baba0..4be64e0 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -203,7 +203,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) p->chunks[i].length_dw = user_chunk.length_dw; p->chunks[i].kdata = NULL; p->chunks[i].chunk_id = user_chunk.chunk_id;
p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) { p->chunk_relocs_idx = i; }
@@ -226,9 +226,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) return -EINVAL; }
p->chunks[i].length_dw = user_chunk.length_dw;
p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data;
cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data; if ((p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) || (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS)) {
-- 1.7.12
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/radeon_cs.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 4be64e0..8b03f1c 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -29,9 +29,6 @@ #include "radeon_reg.h" #include "radeon.h"
-void r100_cs_dump_packet(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt); - static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) { struct drm_device *ddev = p->rdev->ddev;
Preparatory patch: patches to follow will touch a piece of code that had broken indentication, so fix it before touching it.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/r100.c | 45 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 8ff7cac..40c0318 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2106,31 +2106,30 @@ int r100_cs_parse(struct radeon_cs_parser *p) } p->idx += pkt.count + 2; switch (pkt.type) { - case PACKET_TYPE0: - if (p->rdev->family >= CHIP_R200) - r = r100_cs_parse_packet0(p, &pkt, - p->rdev->config.r100.reg_safe_bm, - p->rdev->config.r100.reg_safe_bm_size, - &r200_packet0_check); - else - r = r100_cs_parse_packet0(p, &pkt, - p->rdev->config.r100.reg_safe_bm, - p->rdev->config.r100.reg_safe_bm_size, - &r100_packet0_check); - break; - case PACKET_TYPE2: - break; - case PACKET_TYPE3: - r = r100_packet3_check(p, &pkt); - break; - default: - DRM_ERROR("Unknown packet type %d !\n", - pkt.type); - return -EINVAL; + case PACKET_TYPE0: + if (p->rdev->family >= CHIP_R200) + r = r100_cs_parse_packet0(p, &pkt, + p->rdev->config.r100.reg_safe_bm, + p->rdev->config.r100.reg_safe_bm_size, + &r200_packet0_check); + else + r = r100_cs_parse_packet0(p, &pkt, + p->rdev->config.r100.reg_safe_bm, + p->rdev->config.r100.reg_safe_bm_size, + &r100_packet0_check); + break; + case PACKET_TYPE2: + break; + case PACKET_TYPE3: + r = r100_packet3_check(p, &pkt); + break; + default: + DRM_ERROR("Unknown packet type %d !\n", + pkt.type); + return -EINVAL; } - if (r) { + if (r) return r; - } } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); return 0; }
CS packet parse functions have a lot of in common across all ASICs. Implement a common function and take care of small differences between families inside the function.
This patch is a prep for major refactoring and consolidation of CS parsing code.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/radeon_cs.c | 53 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_reg.h | 11 ++++++++ 2 files changed, 64 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 8b03f1c..95eb673 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -639,3 +639,56 @@ u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) idx_value = ibc->kpage[new_page][pg_offset/4]; return idx_value; } + +/** + * radeon_cs_packet_parse() - parse cp packet and point ib index to next packet + * @parser: parser structure holding parsing context. + * @pkt: where to store packet information + * + * Assume that chunk_ib_index is properly set. Will return -EINVAL + * if packet is bigger than remaining ib size. or if packets is unknown. + **/ +int radeon_cs_packet_parse(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt, + unsigned idx) +{ + struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; + struct radeon_device *rdev = p->rdev; + uint32_t header; + + if (idx >= ib_chunk->length_dw) { + DRM_ERROR("Can not parse packet at %d after CS end %d !\n", + idx, ib_chunk->length_dw); + return -EINVAL; + } + header = radeon_get_ib_value(p, idx); + pkt->idx = idx; + pkt->type = RADEON_CP_PACKET_GET_TYPE(header); + pkt->count = RADEON_CP_PACKET_GET_COUNT(header); + pkt->one_reg_wr = 0; + switch (pkt->type) { + case RADEON_PACKET_TYPE0: + if (rdev->family < CHIP_R600) { + pkt->reg = R100_CP_PACKET0_GET_REG(header); + pkt->one_reg_wr = + RADEON_CP_PACKET0_GET_ONE_REG_WR(header); + } else + pkt->reg = R600_CP_PACKET0_GET_REG(header); + break; + case RADEON_PACKET_TYPE3: + pkt->opcode = RADEON_CP_PACKET3_GET_OPCODE(header); + break; + case RADEON_PACKET_TYPE2: + pkt->count = -1; + break; + default: + DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); + return -EINVAL; + } + if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { + DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", + pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); + return -EINVAL; + } + return 0; +} diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 5d8f735..d9e4204 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h @@ -3706,4 +3706,15 @@
#define RV530_GB_PIPE_SELECT2 0x4124
+#define RADEON_CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) +#define RADEON_CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) +#define RADEON_CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) +#define RADEON_CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) +#define R100_CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) +#define R600_CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) +#define RADEON_PACKET_TYPE0 0 +#define RADEON_PACKET_TYPE1 1 +#define RADEON_PACKET_TYPE2 2 +#define RADEON_PACKET_TYPE3 3 + #endif
We now have a common radeon_cs_packet_parse function that is good for all ASICs. Hook it up and eliminate ASIC-specific versions.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/evergreen_cs.c | 57 +++------------------------------ drivers/gpu/drm/radeon/r100.c | 55 +++----------------------------- drivers/gpu/drm/radeon/r300.c | 2 +- drivers/gpu/drm/radeon/r600_cs.c | 59 ++++------------------------------- drivers/gpu/drm/radeon/radeon.h | 4 +++ 5 files changed, 20 insertions(+), 157 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 7a44566..1ba4ca3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -1009,53 +1009,6 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) }
/** - * evergreen_cs_packet_parse() - parse cp packet and point ib index to next packet - * @parser: parser structure holding parsing context. - * @pkt: where to store packet informations - * - * Assume that chunk_ib_index is properly set. Will return -EINVAL - * if packet is bigger than remaining ib size. or if packets is unknown. - **/ -static int evergreen_cs_packet_parse(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx) -{ - struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - uint32_t header; - - if (idx >= ib_chunk->length_dw) { - DRM_ERROR("Can not parse packet at %d after CS end %d !\n", - idx, ib_chunk->length_dw); - return -EINVAL; - } - header = radeon_get_ib_value(p, idx); - pkt->idx = idx; - pkt->type = CP_PACKET_GET_TYPE(header); - pkt->count = CP_PACKET_GET_COUNT(header); - pkt->one_reg_wr = 0; - switch (pkt->type) { - case PACKET_TYPE0: - pkt->reg = CP_PACKET0_GET_REG(header); - break; - case PACKET_TYPE3: - pkt->opcode = CP_PACKET3_GET_OPCODE(header); - break; - case PACKET_TYPE2: - pkt->count = -1; - break; - default: - DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); - return -EINVAL; - } - if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { - DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", - pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); - return -EINVAL; - } - return 0; -} - -/** * evergreen_cs_packet_next_reloc() - parse next packet which should be reloc packet3 * @parser: parser structure holding parsing context. * @data: pointer to relocation data @@ -1080,7 +1033,7 @@ static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, } *cs_reloc = NULL; relocs_chunk = &p->chunks[p->chunk_relocs_idx]; - r = evergreen_cs_packet_parse(p, &p3reloc, p->idx); + r = radeon_cs_packet_parse(p, &p3reloc, p->idx); if (r) { return r; } @@ -1112,7 +1065,7 @@ static bool evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) struct radeon_cs_packet p3reloc; int r;
- r = evergreen_cs_packet_parse(p, &p3reloc, p->idx); + r = radeon_cs_packet_parse(p, &p3reloc, p->idx); if (r) { return false; } @@ -1150,7 +1103,7 @@ static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p) ib = p->ib.ptr;
/* parse the WAIT_REG_MEM */ - r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->idx); + r = radeon_cs_packet_parse(p, &wait_reg_mem, p->idx); if (r) return r;
@@ -1183,7 +1136,7 @@ static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p) }
/* jump over the NOP */ - r = evergreen_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); + r = radeon_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); if (r) return r;
@@ -2819,7 +2772,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) p->track = track; } do { - r = evergreen_cs_packet_parse(p, &pkt, p->idx); + r = radeon_cs_packet_parse(p, &pkt, p->idx); if (r) { kfree(p->track); p->track = NULL; diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 40c0318..7842447 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1370,53 +1370,6 @@ void r100_cs_dump_packet(struct radeon_cs_parser *p, }
/** - * r100_cs_packet_parse() - parse cp packet and point ib index to next packet - * @parser: parser structure holding parsing context. - * @pkt: where to store packet informations - * - * Assume that chunk_ib_index is properly set. Will return -EINVAL - * if packet is bigger than remaining ib size. or if packets is unknown. - **/ -int r100_cs_packet_parse(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx) -{ - struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - uint32_t header; - - if (idx >= ib_chunk->length_dw) { - DRM_ERROR("Can not parse packet at %d after CS end %d !\n", - idx, ib_chunk->length_dw); - return -EINVAL; - } - header = radeon_get_ib_value(p, idx); - pkt->idx = idx; - pkt->type = CP_PACKET_GET_TYPE(header); - pkt->count = CP_PACKET_GET_COUNT(header); - switch (pkt->type) { - case PACKET_TYPE0: - pkt->reg = CP_PACKET0_GET_REG(header); - pkt->one_reg_wr = CP_PACKET0_GET_ONE_REG_WR(header); - break; - case PACKET_TYPE3: - pkt->opcode = CP_PACKET3_GET_OPCODE(header); - break; - case PACKET_TYPE2: - pkt->count = -1; - break; - default: - DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); - return -EINVAL; - } - if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { - DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", - pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); - return -EINVAL; - } - return 0; -} - -/** * r100_cs_packet_next_vline() - parse userspace VLINE packet * @parser: parser structure holding parsing context. * @@ -1444,7 +1397,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) ib = p->ib.ptr;
/* parse the wait until */ - r = r100_cs_packet_parse(p, &waitreloc, p->idx); + r = radeon_cs_packet_parse(p, &waitreloc, p->idx); if (r) return r;
@@ -1461,7 +1414,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) }
/* jump over the NOP */ - r = r100_cs_packet_parse(p, &p3reloc, p->idx + waitreloc.count + 2); + r = radeon_cs_packet_parse(p, &p3reloc, p->idx + waitreloc.count + 2); if (r) return r;
@@ -1531,7 +1484,7 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, } *cs_reloc = NULL; relocs_chunk = &p->chunks[p->chunk_relocs_idx]; - r = r100_cs_packet_parse(p, &p3reloc, p->idx); + r = radeon_cs_packet_parse(p, &p3reloc, p->idx); if (r) { return r; } @@ -2100,7 +2053,7 @@ int r100_cs_parse(struct radeon_cs_parser *p) r100_cs_track_clear(p->rdev, track); p->track = track; do { - r = r100_cs_packet_parse(p, &pkt, p->idx); + r = radeon_cs_packet_parse(p, &pkt, p->idx); if (r) { return r; } diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index d0ba602..34ca46e 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1257,7 +1257,7 @@ int r300_cs_parse(struct radeon_cs_parser *p) r100_cs_track_clear(p->rdev, track); p->track = track; do { - r = r100_cs_packet_parse(p, &pkt, p->idx); + r = radeon_cs_packet_parse(p, &pkt, p->idx); if (r) { return r; } diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 9ea13d0..1717fec 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -784,53 +784,6 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) }
/** - * r600_cs_packet_parse() - parse cp packet and point ib index to next packet - * @parser: parser structure holding parsing context. - * @pkt: where to store packet informations - * - * Assume that chunk_ib_index is properly set. Will return -EINVAL - * if packet is bigger than remaining ib size. or if packets is unknown. - **/ -static int r600_cs_packet_parse(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx) -{ - struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - uint32_t header; - - if (idx >= ib_chunk->length_dw) { - DRM_ERROR("Can not parse packet at %d after CS end %d !\n", - idx, ib_chunk->length_dw); - return -EINVAL; - } - header = radeon_get_ib_value(p, idx); - pkt->idx = idx; - pkt->type = CP_PACKET_GET_TYPE(header); - pkt->count = CP_PACKET_GET_COUNT(header); - pkt->one_reg_wr = 0; - switch (pkt->type) { - case PACKET_TYPE0: - pkt->reg = CP_PACKET0_GET_REG(header); - break; - case PACKET_TYPE3: - pkt->opcode = CP_PACKET3_GET_OPCODE(header); - break; - case PACKET_TYPE2: - pkt->count = -1; - break; - default: - DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); - return -EINVAL; - } - if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { - DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", - pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); - return -EINVAL; - } - return 0; -} - -/** * r600_cs_packet_next_reloc_mm() - parse next packet which should be reloc packet3 * @parser: parser structure holding parsing context. * @data: pointer to relocation data @@ -855,7 +808,7 @@ static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, } *cs_reloc = NULL; relocs_chunk = &p->chunks[p->chunk_relocs_idx]; - r = r600_cs_packet_parse(p, &p3reloc, p->idx); + r = radeon_cs_packet_parse(p, &p3reloc, p->idx); if (r) { return r; } @@ -901,7 +854,7 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, } *cs_reloc = NULL; relocs_chunk = &p->chunks[p->chunk_relocs_idx]; - r = r600_cs_packet_parse(p, &p3reloc, p->idx); + r = radeon_cs_packet_parse(p, &p3reloc, p->idx); if (r) { return r; } @@ -935,7 +888,7 @@ static int r600_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) struct radeon_cs_packet p3reloc; int r;
- r = r600_cs_packet_parse(p, &p3reloc, p->idx); + r = radeon_cs_packet_parse(p, &p3reloc, p->idx); if (r) { return 0; } @@ -973,7 +926,7 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) ib = p->ib.ptr;
/* parse the WAIT_REG_MEM */ - r = r600_cs_packet_parse(p, &wait_reg_mem, p->idx); + r = radeon_cs_packet_parse(p, &wait_reg_mem, p->idx); if (r) return r;
@@ -1006,7 +959,7 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) }
/* jump over the NOP */ - r = r600_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); + r = radeon_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); if (r) return r;
@@ -2410,7 +2363,7 @@ int r600_cs_parse(struct radeon_cs_parser *p) p->track = track; } do { - r = r600_cs_packet_parse(p, &pkt, p->idx); + r = radeon_cs_packet_parse(p, &pkt, p->idx); if (r) { kfree(p->track); p->track = NULL; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 9b9422c..a2f1f67 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1966,6 +1966,10 @@ static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } static inline void radeon_acpi_fini(struct radeon_device *rdev) { } #endif
+int radeon_cs_packet_parse(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt, + unsigned idx); + #include "radeon_object.h"
#endif
Once we factored out radeon_cs_packet_parse function, evergreen_cs_next_is_pkt3_nop and r600_cs_next_is_pkt3_nop functions became identical, so they can be factored out into a common function.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/evergreen_cs.c | 23 +---------------------- drivers/gpu/drm/radeon/r600_cs.c | 30 ++++-------------------------- drivers/gpu/drm/radeon/radeon.h | 2 ++ drivers/gpu/drm/radeon/radeon_cs.c | 21 +++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_reg.h | 2 ++ 5 files changed, 30 insertions(+), 48 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 1ba4ca3..883b9f7 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -1055,27 +1055,6 @@ static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, }
/** - * evergreen_cs_packet_next_is_pkt3_nop() - test if the next packet is NOP - * @p: structure holding the parser context. - * - * Check if the next packet is a relocation packet3. - **/ -static bool evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) -{ - struct radeon_cs_packet p3reloc; - int r; - - r = radeon_cs_packet_parse(p, &p3reloc, p->idx); - if (r) { - return false; - } - if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - return false; - } - return true; -} - -/** * evergreen_cs_packet_next_vline() - parse userspace VLINE packet * @parser: parser structure holding parsing context. * @@ -2464,7 +2443,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
if ((tex_dim == SQ_TEX_DIM_2D_MSAA || tex_dim == SQ_TEX_DIM_2D_ARRAY_MSAA) && !mip_address && - !evergreen_cs_packet_next_is_pkt3_nop(p)) { + !radeon_cs_packet_next_is_pkt3_nop(p)) { /* MIP_ADDRESS should point to FMASK for an MSAA texture. * It should be 0 if FMASK is disabled. */ moffset = 0; diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 1717fec..e2fb76a 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -877,28 +877,6 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, }
/** - * r600_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc - * @parser: parser structure holding parsing context. - * - * Check next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -static int r600_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) -{ - struct radeon_cs_packet p3reloc; - int r; - - r = radeon_cs_packet_parse(p, &p3reloc, p->idx); - if (r) { - return 0; - } - if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - return 0; - } - return 1; -} - -/** * r600_cs_packet_next_vline() - parse userspace VLINE packet * @parser: parser structure holding parsing context. * @@ -1108,7 +1086,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) break; case R_028010_DB_DEPTH_INFO: if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && - r600_cs_packet_next_is_pkt3_nop(p)) { + radeon_cs_packet_next_is_pkt3_nop(p)) { r = r600_cs_packet_next_reloc(p, &reloc); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " @@ -1209,7 +1187,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case R_0280B8_CB_COLOR6_INFO: case R_0280BC_CB_COLOR7_INFO: if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && - r600_cs_packet_next_is_pkt3_nop(p)) { + radeon_cs_packet_next_is_pkt3_nop(p)) { r = r600_cs_packet_next_reloc(p, &reloc); if (r) { dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); @@ -1273,7 +1251,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case R_0280F8_CB_COLOR6_FRAG: case R_0280FC_CB_COLOR7_FRAG: tmp = (reg - R_0280E0_CB_COLOR0_FRAG) / 4; - if (!r600_cs_packet_next_is_pkt3_nop(p)) { + if (!radeon_cs_packet_next_is_pkt3_nop(p)) { if (!track->cb_color_base_last[tmp]) { dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); return -EINVAL; @@ -1304,7 +1282,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case R_0280D8_CB_COLOR6_TILE: case R_0280DC_CB_COLOR7_TILE: tmp = (reg - R_0280C0_CB_COLOR0_TILE) / 4; - if (!r600_cs_packet_next_is_pkt3_nop(p)) { + if (!radeon_cs_packet_next_is_pkt3_nop(p)) { if (!track->cb_color_base_last[tmp]) { dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); return -EINVAL; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a2f1f67..a5066ab 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1969,6 +1969,8 @@ static inline void radeon_acpi_fini(struct radeon_device *rdev) { } int radeon_cs_packet_parse(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx); +bool radeon_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p); +
#include "radeon_object.h"
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 95eb673..b308087 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -692,3 +692,24 @@ int radeon_cs_packet_parse(struct radeon_cs_parser *p, } return 0; } + +/** + * radeon_cs_packet_next_is_pkt3_nop() - test if the next packet is P3 NOP + * @p: structure holding the parser context. + * + * Check if the next packet is NOP relocation packet3. + **/ +bool radeon_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) +{ + struct radeon_cs_packet p3reloc; + int r; + + r = radeon_cs_packet_parse(p, &p3reloc, p->idx); + if (r) + return false; + if (p3reloc.type != RADEON_PACKET_TYPE3) + return false; + if (p3reloc.opcode != RADEON_PACKET3_NOP) + return false; + return true; +} diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index d9e4204..ce7e9f2 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h @@ -3717,4 +3717,6 @@ #define RADEON_PACKET_TYPE2 2 #define RADEON_PACKET_TYPE3 3
+#define RADEON_PACKET3_NOP 0x10 + #endif
vline packet parsing function for R600 and Evergreen+ are the same, except that they use different registers. Factor out the algorithm into a common function that uses register table passed from ASIC-specific caller.
This reduces ASIC-specific function to (trivial) setup of register table and call into the common function.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/evergreen_cs.c | 120 +++++++--------------------------- drivers/gpu/drm/radeon/r600_cs.c | 61 +++++++++++------ drivers/gpu/drm/radeon/radeon.h | 4 +- drivers/gpu/drm/radeon/radeon_reg.h | 2 + 4 files changed, 70 insertions(+), 117 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 883b9f7..2690532 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -1055,109 +1055,35 @@ static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, }
/** - * evergreen_cs_packet_next_vline() - parse userspace VLINE packet + * evergreen_cs_packet_parse_vline() - parse userspace VLINE packet * @parser: parser structure holding parsing context. * - * Userspace sends a special sequence for VLINE waits. - * PACKET0 - VLINE_START_END + value - * PACKET3 - WAIT_REG_MEM poll vline status reg - * RELOC (P3) - crtc_id in reloc. - * - * This function parses this and relocates the VLINE START END - * and WAIT_REG_MEM packets to the correct crtc. - * It also detects a switched off crtc and nulls out the - * wait in that case. + * This is an Evergreen(+)-specific function for parsing VLINE packets. + * Real work is done by r600_cs_common_vline_parse function. + * Here we just set up ASIC-specific register table and call + * the common implementation function. */ static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p) { - struct drm_mode_object *obj; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - struct radeon_cs_packet p3reloc, wait_reg_mem; - int crtc_id; - int r; - uint32_t header, h_idx, reg, wait_reg_mem_info; - volatile uint32_t *ib; - - ib = p->ib.ptr; - - /* parse the WAIT_REG_MEM */ - r = radeon_cs_packet_parse(p, &wait_reg_mem, p->idx); - if (r) - return r; - - /* check its a WAIT_REG_MEM */ - if (wait_reg_mem.type != PACKET_TYPE3 || - wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) { - DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n"); - return -EINVAL; - } - - wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1); - /* bit 4 is reg (0) or mem (1) */ - if (wait_reg_mem_info & 0x10) { - DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n"); - return -EINVAL; - } - /* waiting for value to be equal */ - if ((wait_reg_mem_info & 0x7) != 0x3) { - DRM_ERROR("vline WAIT_REG_MEM function not equal\n"); - return -EINVAL; - } - if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != EVERGREEN_VLINE_STATUS) { - DRM_ERROR("vline WAIT_REG_MEM bad reg\n"); - return -EINVAL; - }
- if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != EVERGREEN_VLINE_STAT) { - DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n"); - return -EINVAL; - } - - /* jump over the NOP */ - r = radeon_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); - if (r) - return r; - - h_idx = p->idx - 2; - p->idx += wait_reg_mem.count + 2; - p->idx += p3reloc.count + 2; - - header = radeon_get_ib_value(p, h_idx); - crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); - reg = CP_PACKET0_GET_REG(header); - obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); - if (!obj) { - DRM_ERROR("cannot find crtc %d\n", crtc_id); - return -EINVAL; - } - crtc = obj_to_crtc(obj); - radeon_crtc = to_radeon_crtc(crtc); - crtc_id = radeon_crtc->crtc_id; - - if (!crtc->enabled) { - /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */ - ib[h_idx + 2] = PACKET2(0); - ib[h_idx + 3] = PACKET2(0); - ib[h_idx + 4] = PACKET2(0); - ib[h_idx + 5] = PACKET2(0); - ib[h_idx + 6] = PACKET2(0); - ib[h_idx + 7] = PACKET2(0); - ib[h_idx + 8] = PACKET2(0); - } else { - switch (reg) { - case EVERGREEN_VLINE_START_END: - header &= ~R600_CP_PACKET0_REG_MASK; - header |= (EVERGREEN_VLINE_START_END + radeon_crtc->crtc_offset) >> 2; - ib[h_idx] = header; - ib[h_idx + 4] = (EVERGREEN_VLINE_STATUS + radeon_crtc->crtc_offset) >> 2; - break; - default: - DRM_ERROR("unknown crtc reloc\n"); - return -EINVAL; - } - } - return 0; + static uint32_t vline_start_end[6] = { + EVERGREEN_VLINE_START_END + EVERGREEN_CRTC0_REGISTER_OFFSET, + EVERGREEN_VLINE_START_END + EVERGREEN_CRTC1_REGISTER_OFFSET, + EVERGREEN_VLINE_START_END + EVERGREEN_CRTC2_REGISTER_OFFSET, + EVERGREEN_VLINE_START_END + EVERGREEN_CRTC3_REGISTER_OFFSET, + EVERGREEN_VLINE_START_END + EVERGREEN_CRTC4_REGISTER_OFFSET, + EVERGREEN_VLINE_START_END + EVERGREEN_CRTC5_REGISTER_OFFSET + }; + static uint32_t vline_status[6] = { + EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, + EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, + EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, + EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, + EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, + EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET + }; + + return r600_cs_common_vline_parse(p, vline_start_end, vline_status); }
static int evergreen_packet0_check(struct radeon_cs_parser *p, diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index e2fb76a..5d59275 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -877,9 +877,30 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, }
/** - * r600_cs_packet_next_vline() - parse userspace VLINE packet + * r600_cs_packet_parse_vline() - parse userspace VLINE packet * @parser: parser structure holding parsing context. * + * This is an R600-specific function for parsing VLINE packets. + * Real work is done by r600_cs_common_vline_parse function. + * Here we just set up ASIC-specific register table and call + * the common implementation function. + */ +static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) +{ + static uint32_t vline_start_end[2] = {AVIVO_D1MODE_VLINE_START_END, + AVIVO_D2MODE_VLINE_START_END}; + static uint32_t vline_status[2] = {AVIVO_D1MODE_VLINE_STATUS, + AVIVO_D2MODE_VLINE_STATUS}; + + return r600_cs_common_vline_parse(p, vline_start_end, vline_status); +} + +/** + * r600_cs_common_vline_parse() - common vline parser + * @parser: parser structure holding parsing context. + * @vline_start_end: table of vline_start_end registers + * @vline_status: table of vline_status registers + * * Userspace sends a special sequence for VLINE waits. * PACKET0 - VLINE_START_END + value * PACKET3 - WAIT_REG_MEM poll vline status reg @@ -888,9 +909,16 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, * This function parses this and relocates the VLINE START END * and WAIT_REG_MEM packets to the correct crtc. * It also detects a switched off crtc and nulls out the - * wait in that case. + * wait in that case. This function is common for all ASICs that + * are R600 and newer. The parsing algorithm is the same, and only + * differs in which registers are used. + * + * Caller is the ASIC-specific function which passes the parser + * context and ASIC-specific register table */ -static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) +int r600_cs_common_vline_parse(struct radeon_cs_parser *p, + uint32_t *vline_start_end, + uint32_t *vline_status) { struct drm_mode_object *obj; struct drm_crtc *crtc; @@ -918,7 +946,7 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1); /* bit 4 is reg (0) or mem (1) */ if (wait_reg_mem_info & 0x10) { - DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n"); + DRM_ERROR("vline WAIT_REG_MEM waiting on MEM instead of REG\n"); return -EINVAL; } /* waiting for value to be equal */ @@ -926,12 +954,12 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) DRM_ERROR("vline WAIT_REG_MEM function not equal\n"); return -EINVAL; } - if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != AVIVO_D1MODE_VLINE_STATUS) { + if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != vline_status[0]) { DRM_ERROR("vline WAIT_REG_MEM bad reg\n"); return -EINVAL; }
- if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != AVIVO_D1MODE_VLINE_STAT) { + if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != RADEON_VLINE_STAT) { DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n"); return -EINVAL; } @@ -959,7 +987,7 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) crtc_id = radeon_crtc->crtc_id;
if (!crtc->enabled) { - /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */ + /* CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */ ib[h_idx + 2] = PACKET2(0); ib[h_idx + 3] = PACKET2(0); ib[h_idx + 4] = PACKET2(0); @@ -967,20 +995,15 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) ib[h_idx + 6] = PACKET2(0); ib[h_idx + 7] = PACKET2(0); ib[h_idx + 8] = PACKET2(0); - } else if (crtc_id == 1) { - switch (reg) { - case AVIVO_D1MODE_VLINE_START_END: - header &= ~R600_CP_PACKET0_REG_MASK; - header |= AVIVO_D2MODE_VLINE_START_END >> 2; - break; - default: - DRM_ERROR("unknown crtc reloc\n"); - return -EINVAL; - } + } else if (reg == vline_start_end[0]) { + header &= ~R600_CP_PACKET0_REG_MASK; + header |= vline_start_end[crtc_id] >> 2; ib[h_idx] = header; - ib[h_idx + 4] = AVIVO_D2MODE_VLINE_STATUS >> 2; + ib[h_idx + 4] = vline_status[crtc_id] >> 2; + } else { + DRM_ERROR("unknown crtc reloc\n"); + return -EINVAL; } - return 0; }
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a5066ab..669c723 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1970,7 +1970,9 @@ int radeon_cs_packet_parse(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx); bool radeon_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p); - +int r600_cs_common_vline_parse(struct radeon_cs_parser *p, + uint32_t *vline_start_end, + uint32_t *vline_status);
#include "radeon_object.h"
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index ce7e9f2..7e2c2b7 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h @@ -3719,4 +3719,6 @@
#define RADEON_PACKET3_NOP 0x10
+#define RADEON_VLINE_STAT (1 << 12) + #endif
WAIT_REG_MEM on register does not allow the use of PFP. Enforce this restriction when checking packets sent from userland.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/evergreen_cs.c | 3 +++ drivers/gpu/drm/radeon/r600_cs.c | 8 ++++++++ 2 files changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 2690532..02aeb7f 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -2101,6 +2101,9 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffffc); ib[idx+2] = upper_32_bits(offset) & 0xff; + } else if (idx_value & 0x100) { + DRM_ERROR("cannot use PFP on REG wait\n"); + return -EINVAL; } break; case PACKET3_CP_DMA: diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 5d59275..d64432b 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -949,6 +949,11 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p, DRM_ERROR("vline WAIT_REG_MEM waiting on MEM instead of REG\n"); return -EINVAL; } + /* bit 8 is me (0) or pfp (1) */ + if (wait_reg_mem_info & 0x100) { + DRM_ERROR("vline WAIT_REG_MEM waiting on PFP instead of ME\n"); + return -EINVAL; + } /* waiting for value to be equal */ if ((wait_reg_mem_info & 0x7) != 0x3) { DRM_ERROR("vline WAIT_REG_MEM function not equal\n"); @@ -1847,6 +1852,9 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffff0); ib[idx+2] = upper_32_bits(offset) & 0xff; + } else if (idx_value & 0x100) { + DRM_ERROR("cannot use PFP on REG wait\n"); + return -EINVAL; } break; case PACKET3_CP_DMA:
This function is not limited to r100, but it can dump a (raw) packet for any ASIC. Rename it accordingly and move its declaration to radeon.h
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/r100.c | 52 ++++++++++++++----------------------- drivers/gpu/drm/radeon/r100_track.h | 2 -- drivers/gpu/drm/radeon/r200.c | 14 +++++----- drivers/gpu/drm/radeon/r300.c | 18 ++++++------- drivers/gpu/drm/radeon/radeon.h | 2 ++ drivers/gpu/drm/radeon/radeon_cs.c | 21 +++++++++++++++ 6 files changed, 58 insertions(+), 51 deletions(-)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 7842447..cf7e359 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1219,7 +1219,7 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; }
@@ -1233,7 +1233,7 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { if (reg == RADEON_SRC_PITCH_OFFSET) { DRM_ERROR("Cannot src blit from microtiled surface\n"); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return -EINVAL; } tile_flags |= RADEON_DST_TILE_MICRO; @@ -1263,7 +1263,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, if (c > 16) { DRM_ERROR("Only 16 vertex buffers are allowed %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return -EINVAL; } track->num_arrays = c; @@ -1272,7 +1272,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } idx_value = radeon_get_ib_value(p, idx); @@ -1285,7 +1285,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } ib[idx+2] = radeon_get_ib_value(p, idx + 2) + ((u32)reloc->lobj.gpu_offset); @@ -1298,7 +1298,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } idx_value = radeon_get_ib_value(p, idx); @@ -1355,20 +1355,6 @@ int r100_cs_parse_packet0(struct radeon_cs_parser *p, return 0; }
-void r100_cs_dump_packet(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt) -{ - volatile uint32_t *ib; - unsigned i; - unsigned idx; - - ib = p->ib.ptr; - idx = pkt->idx; - for (i = 0; i <= (pkt->count + 1); i++, idx++) { - DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); - } -} - /** * r100_cs_packet_next_vline() - parse userspace VLINE packet * @parser: parser structure holding parsing context. @@ -1492,14 +1478,14 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { DRM_ERROR("No packet3 for relocation for packet at %d.\n", p3reloc.idx); - r100_cs_dump_packet(p, &p3reloc); + 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); - r100_cs_dump_packet(p, &p3reloc); + radeon_cs_dump_packet(p, &p3reloc); return -EINVAL; } /* FIXME: we assume reloc size is 4 dwords */ @@ -1584,7 +1570,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } break; @@ -1601,7 +1587,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->zb.robj = reloc->robj; @@ -1614,7 +1600,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->cb[0].robj = reloc->robj; @@ -1630,7 +1616,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { @@ -1657,7 +1643,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->textures[0].cube_info[i].offset = idx_value; @@ -1675,7 +1661,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->textures[1].cube_info[i].offset = idx_value; @@ -1693,7 +1679,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->textures[2].cube_info[i].offset = idx_value; @@ -1711,7 +1697,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { @@ -1782,7 +1768,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); @@ -1942,7 +1928,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p, r = r100_cs_packet_next_reloc(p, &reloc); if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } ib[idx+1] = radeon_get_ib_value(p, idx+1) + ((u32)reloc->lobj.gpu_offset); @@ -1956,7 +1942,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p, r = r100_cs_packet_next_reloc(p, &reloc); if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } ib[idx] = radeon_get_ib_value(p, idx) + ((u32)reloc->lobj.gpu_offset); diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index 6a603b3..c81b174 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h @@ -83,8 +83,6 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track); int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, struct radeon_cs_reloc **cs_reloc); -void r100_cs_dump_packet(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt);
int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 98143a5..07ea6f4 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -162,7 +162,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } break; @@ -179,7 +179,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->zb.robj = reloc->robj; @@ -192,7 +192,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->cb[0].robj = reloc->robj; @@ -211,7 +211,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { @@ -264,7 +264,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->textures[i].cube_info[face - 1].offset = idx_value; @@ -282,7 +282,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; }
@@ -359,7 +359,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 34ca46e..47bfca1 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -615,7 +615,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } break; @@ -634,7 +634,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->cb[i].robj = reloc->robj; @@ -647,7 +647,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->zb.robj = reloc->robj; @@ -676,7 +676,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; }
@@ -749,7 +749,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; }
@@ -834,7 +834,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; }
@@ -1049,7 +1049,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); @@ -1091,7 +1091,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } track->aa.robj = reloc->robj; @@ -1159,7 +1159,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p, r = r100_cs_packet_next_reloc(p, &reloc); if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); + radeon_cs_dump_packet(p, pkt); return r; } ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 669c723..a0e28dc 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1970,6 +1970,8 @@ int radeon_cs_packet_parse(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx); 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 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 b308087..2ef7e81 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -713,3 +713,24 @@ bool radeon_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) return false; return true; } + +/** + * radeon_cs_dump_packet() - dump raw packet context + * @p: structure holding the parser context. + * @pkt: structure holding the packet. + * + * Used mostly for debugging and error reporting. + **/ +void radeon_cs_dump_packet(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt) +{ + volatile uint32_t *ib; + unsigned i; + unsigned idx; + + ib = p->ib.ptr; + idx = pkt->idx; + for (i = 0; i <= (pkt->count + 1); i++, idx++) + DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); +} +
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 --- drivers/gpu/drm/radeon/radeon.h | 3 +++ drivers/gpu/drm/radeon/radeon_cs.c | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a0e28dc..dd8feab 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1972,6 +1972,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 2ef7e81..5c3d773 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -734,3 +734,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; +}
This patch eliminates ASIC-specific ***_cs_packet_next_reloc functions and hooks up the new common function.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/evergreen_cs.c | 129 +++++++++------------------ drivers/gpu/drm/radeon/r100.c | 76 +++------------- drivers/gpu/drm/radeon/r100_track.h | 2 - drivers/gpu/drm/radeon/r200.c | 12 +-- drivers/gpu/drm/radeon/r300.c | 16 ++-- drivers/gpu/drm/radeon/r600_cs.c | 158 +++++++--------------------------- 6 files changed, 98 insertions(+), 295 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 02aeb7f..211b509 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -36,9 +36,6 @@
int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, struct radeon_cs_reloc **cs_reloc); -static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); - struct evergreen_cs_track { u32 group_size; u32 nbanks; @@ -1009,52 +1006,6 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) }
/** - * evergreen_cs_packet_next_reloc() - parse next packet which should be reloc packet3 - * @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 next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) -{ - 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 != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - DRM_ERROR("No packet3 for relocation for packet at %d.\n", - p3reloc.idx); - 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); - return -EINVAL; - } - /* FIXME: we assume reloc size is 4 dwords */ - *cs_reloc = p->relocs_ptr[(idx / 4)]; - return 0; -} - -/** * evergreen_cs_packet_parse_vline() - parse userspace VLINE packet * @parser: parser structure holding parsing context. * @@ -1205,7 +1156,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case SQ_LSTMP_RING_BASE: case SQ_PSTMP_RING_BASE: case SQ_VSTMP_RING_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1234,7 +1185,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case DB_Z_INFO: track->db_z_info = radeon_get_ib_value(p, idx); if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1276,7 +1227,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->db_dirty = true; break; case DB_Z_READ_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1288,7 +1239,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->db_dirty = true; break; case DB_Z_WRITE_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1300,7 +1251,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->db_dirty = true; break; case DB_STENCIL_READ_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1312,7 +1263,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->db_dirty = true; break; case DB_STENCIL_WRITE_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1335,7 +1286,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case VGT_STRMOUT_BUFFER_BASE_1: case VGT_STRMOUT_BUFFER_BASE_2: case VGT_STRMOUT_BUFFER_BASE_3: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1357,7 +1308,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->streamout_dirty = true; break; case CP_COHER_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "missing reloc for CP_COHER_BASE " "0x%04X\n", reg); @@ -1421,7 +1372,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) tmp = (reg - CB_COLOR0_INFO) / 0x3c; track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1439,7 +1390,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1500,7 +1451,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR5_ATTRIB: case CB_COLOR6_ATTRIB: case CB_COLOR7_ATTRIB: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1528,7 +1479,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR9_ATTRIB: case CB_COLOR10_ATTRIB: case CB_COLOR11_ATTRIB: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1561,7 +1512,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR6_FMASK: case CB_COLOR7_FMASK: tmp = (reg - CB_COLOR0_FMASK) / 0x3c; - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); return -EINVAL; @@ -1578,7 +1529,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR6_CMASK: case CB_COLOR7_CMASK: tmp = (reg - CB_COLOR0_CMASK) / 0x3c; - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); return -EINVAL; @@ -1616,7 +1567,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR5_BASE: case CB_COLOR6_BASE: case CB_COLOR7_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1632,7 +1583,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR9_BASE: case CB_COLOR10_BASE: case CB_COLOR11_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1645,7 +1596,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->cb_dirty = true; break; case DB_HTILE_DATA_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1763,7 +1714,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case SQ_ALU_CONST_CACHE_LS_13: case SQ_ALU_CONST_CACHE_LS_14: case SQ_ALU_CONST_CACHE_LS_15: - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1777,7 +1728,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) "0x%04X\n", reg); return -EINVAL; } - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONFIG_REG " "0x%04X\n", reg); @@ -1791,7 +1742,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) "0x%04X\n", reg); return -EINVAL; } - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1876,7 +1827,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, return -EINVAL; }
- r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad SET PREDICATION\n"); return -EINVAL; @@ -1922,7 +1873,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad INDEX_BASE\n"); return -EINVAL; } - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad INDEX_BASE\n"); return -EINVAL; @@ -1949,7 +1900,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad DRAW_INDEX\n"); return -EINVAL; } - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad DRAW_INDEX\n"); return -EINVAL; @@ -1977,7 +1928,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad DRAW_INDEX_2\n"); return -EINVAL; } - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad DRAW_INDEX_2\n"); return -EINVAL; @@ -2068,7 +2019,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad DISPATCH_INDIRECT\n"); return -EINVAL; } - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad DISPATCH_INDIRECT\n"); return -EINVAL; @@ -2089,7 +2040,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, if (idx_value & 0x10) { uint64_t offset;
- r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad WAIT_REG_MEM\n"); return -EINVAL; @@ -2143,7 +2094,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, } /* src address space is memory */ if (((info & 0x60000000) >> 29) == 0) { - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad CP DMA SRC\n"); return -EINVAL; @@ -2181,7 +2132,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } if (((info & 0x00300000) >> 20) == 0) { - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad CP DMA DST\n"); return -EINVAL; @@ -2215,7 +2166,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, /* 0xffffffff/0x0 is flush all cache flag */ if (radeon_get_ib_value(p, idx + 1) != 0xffffffff || radeon_get_ib_value(p, idx + 2) != 0) { - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad SURFACE_SYNC\n"); return -EINVAL; @@ -2231,7 +2182,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, if (pkt->count) { uint64_t offset;
- r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad EVENT_WRITE\n"); return -EINVAL; @@ -2252,7 +2203,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad EVENT_WRITE_EOP\n"); return -EINVAL; } - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad EVENT_WRITE_EOP\n"); return -EINVAL; @@ -2274,7 +2225,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad EVENT_WRITE_EOS\n"); return -EINVAL; } - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad EVENT_WRITE_EOS\n"); return -EINVAL; @@ -2341,7 +2292,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { case SQ_TEX_VTX_VALID_TEXTURE: /* tex base */ - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad SET_RESOURCE (tex)\n"); return -EINVAL; @@ -2378,7 +2329,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, moffset = 0; mipmap = NULL; } else { - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad SET_RESOURCE (tex)\n"); return -EINVAL; @@ -2397,7 +2348,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, { uint64_t offset64; /* vtx base */ - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad SET_RESOURCE (vtx)\n"); return -EINVAL; @@ -2479,7 +2430,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, /* Updating memory at DST_ADDRESS. */ if (idx_value & 0x1) { u64 offset; - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n"); return -EINVAL; @@ -2498,7 +2449,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, /* Reading data from SRC_ADDRESS. */ if (((idx_value >> 1) & 0x3) == 2) { u64 offset; - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n"); return -EINVAL; @@ -2523,7 +2474,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad MEM_WRITE (invalid count)\n"); return -EINVAL; } - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad MEM_WRITE (missing reloc)\n"); return -EINVAL; @@ -2552,7 +2503,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, if (idx_value & 0x1) { u64 offset; /* SRC is memory. */ - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad COPY_DW (missing src reloc)\n"); return -EINVAL; @@ -2576,7 +2527,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, if (idx_value & 0x2) { u64 offset; /* DST is memory. */ - r = evergreen_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("bad COPY_DW (missing dst reloc)\n"); return -EINVAL; diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index cf7e359..8469607 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1215,7 +1215,7 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, struct radeon_cs_reloc *reloc; u32 value;
- r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1268,7 +1268,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, } track->num_arrays = c; for (i = 0; i < (c - 1); i+=2, idx+=3) { - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); @@ -1281,7 +1281,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, track->arrays[i + 0].esize = idx_value >> 8; track->arrays[i + 0].robj = reloc->robj; track->arrays[i + 0].esize &= 0x7F; - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); @@ -1294,7 +1294,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, track->arrays[i + 1].esize &= 0x7F; } if (c & 1) { - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); @@ -1445,54 +1445,6 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) return 0; }
-/** - * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3 - * @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 next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) -{ - 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 != PACKET_TYPE3 || p3reloc.opcode != 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 */ - *cs_reloc = p->relocs_ptr[(idx / 4)]; - return 0; -} - static int r100_get_vtx_size(uint32_t vtx_fmt) { int vtx_size; @@ -1583,7 +1535,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, return r; break; case RADEON_RB3D_DEPTHOFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1596,7 +1548,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case RADEON_RB3D_COLOROFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1612,7 +1564,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, case RADEON_PP_TXOFFSET_1: case RADEON_PP_TXOFFSET_2: i = (reg - RADEON_PP_TXOFFSET_0) / 24; - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1639,7 +1591,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, case RADEON_PP_CUBIC_OFFSET_T0_3: case RADEON_PP_CUBIC_OFFSET_T0_4: i = (reg - RADEON_PP_CUBIC_OFFSET_T0_0) / 4; - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1657,7 +1609,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, case RADEON_PP_CUBIC_OFFSET_T1_3: case RADEON_PP_CUBIC_OFFSET_T1_4: i = (reg - RADEON_PP_CUBIC_OFFSET_T1_0) / 4; - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1675,7 +1627,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, case RADEON_PP_CUBIC_OFFSET_T2_3: case RADEON_PP_CUBIC_OFFSET_T2_4: i = (reg - RADEON_PP_CUBIC_OFFSET_T2_0) / 4; - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1693,7 +1645,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->zb_dirty = true; break; case RADEON_RB3D_COLORPITCH: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1764,7 +1716,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->zb_dirty = true; break; case RADEON_RB3D_ZPASS_ADDR: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1925,7 +1877,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p, return r; break; case PACKET3_INDX_BUFFER: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); radeon_cs_dump_packet(p, pkt); @@ -1939,7 +1891,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p, break; case 0x23: /* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */ - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); radeon_cs_dump_packet(p, pkt); diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index c81b174..eb40888 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h @@ -81,8 +81,6 @@ struct r100_cs_track {
int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track); -int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc);
int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 07ea6f4..b3807ed 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -175,7 +175,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, return r; break; case RADEON_RB3D_DEPTHOFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -188,7 +188,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case RADEON_RB3D_COLOROFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -207,7 +207,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, case R200_PP_TXOFFSET_4: case R200_PP_TXOFFSET_5: i = (reg - R200_PP_TXOFFSET_0) / 24; - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -260,7 +260,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, case R200_PP_CUBIC_OFFSET_F5_5: i = (reg - R200_PP_TXOFFSET_0) / 24; face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4; - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -278,7 +278,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, track->zb_dirty = true; break; case RADEON_RB3D_COLORPITCH: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -355,7 +355,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, track->zb_dirty = true; break; case RADEON_RB3D_ZPASS_ADDR: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 47bfca1..98f723c 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -630,7 +630,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case R300_RB3D_COLOROFFSET2: case R300_RB3D_COLOROFFSET3: i = (reg - R300_RB3D_COLOROFFSET0) >> 2; - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -643,7 +643,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case R300_ZB_DEPTHOFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -672,7 +672,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case R300_TX_OFFSET_0+56: case R300_TX_OFFSET_0+60: i = (reg - R300_TX_OFFSET_0) >> 2; - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -745,7 +745,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, /* RB3D_COLORPITCH2 */ /* RB3D_COLORPITCH3 */ if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -830,7 +830,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case 0x4F24: /* ZB_DEPTHPITCH */ if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1045,7 +1045,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->tex_dirty = true; break; case R300_ZB_ZPASS_ADDR: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1087,7 +1087,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->cb_dirty = true; break; case R300_RB3D_AARESOLVE_OFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", idx, reg); @@ -1156,7 +1156,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p, return r; break; case PACKET3_INDX_BUFFER: - r = r100_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, 0); if (r) { DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); radeon_cs_dump_packet(p, pkt); diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index d64432b..6f80dbf 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -31,12 +31,7 @@ #include "r600d.h" #include "r600_reg_safe.h"
-static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); -static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); -typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**); -static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm; +static int r600_nomm; extern void r600_cs_legacy_get_tiling_conf(struct drm_device *dev, u32 *npipes, u32 *nbanks, u32 *group_size);
@@ -784,99 +779,6 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) }
/** - * r600_cs_packet_next_reloc_mm() - parse next packet which should be reloc packet3 - * @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 next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) -{ - 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 != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - DRM_ERROR("No packet3 for relocation for packet at %d.\n", - p3reloc.idx); - 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); - return -EINVAL; - } - /* FIXME: we assume reloc size is 4 dwords */ - *cs_reloc = p->relocs_ptr[(idx / 4)]; - return 0; -} - -/** - * r600_cs_packet_next_reloc_nomm() - parse next packet which should be reloc packet3 - * @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 next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) -{ - 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 != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - DRM_ERROR("No packet3 for relocation for packet at %d.\n", - p3reloc.idx); - 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); - return -EINVAL; - } - *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]; - return 0; -} - -/** * r600_cs_packet_parse_vline() - parse userspace VLINE packet * @parser: parser structure holding parsing context. * @@ -1115,7 +1017,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case R_028010_DB_DEPTH_INFO: if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && radeon_cs_packet_next_is_pkt3_nop(p)) { - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1157,7 +1059,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case VGT_STRMOUT_BUFFER_BASE_1: case VGT_STRMOUT_BUFFER_BASE_2: case VGT_STRMOUT_BUFFER_BASE_3: - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1180,7 +1082,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->streamout_dirty = true; break; case CP_COHER_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_warn(p->dev, "missing reloc for CP_COHER_BASE " "0x%04X\n", reg); @@ -1216,7 +1118,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case R_0280BC_CB_COLOR7_INFO: if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && radeon_cs_packet_next_is_pkt3_nop(p)) { - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); return -EINVAL; @@ -1288,7 +1190,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp]; ib[idx] = track->cb_color_base_last[tmp]; } else { - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); return -EINVAL; @@ -1319,7 +1221,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp]; ib[idx] = track->cb_color_base_last[tmp]; } else { - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); return -EINVAL; @@ -1354,7 +1256,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR5_BASE: case CB_COLOR6_BASE: case CB_COLOR7_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1369,7 +1271,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->cb_dirty = true; break; case DB_DEPTH_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1382,7 +1284,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->db_dirty = true; break; case DB_HTILE_DATA_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1452,7 +1354,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case SQ_ALU_CONST_CACHE_VS_13: case SQ_ALU_CONST_CACHE_VS_14: case SQ_ALU_CONST_CACHE_VS_15: - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " "0x%04X\n", reg); @@ -1461,7 +1363,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); break; case SX_MEMORY_EXPORT_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { dev_warn(p->dev, "bad SET_CONFIG_REG " "0x%04X\n", reg); @@ -1747,7 +1649,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; }
- r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad SET PREDICATION\n"); return -EINVAL; @@ -1788,7 +1690,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad DRAW_INDEX\n"); return -EINVAL; } - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad DRAW_INDEX\n"); return -EINVAL; @@ -1840,7 +1742,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, if (idx_value & 0x10) { uint64_t offset;
- r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad WAIT_REG_MEM\n"); return -EINVAL; @@ -1877,7 +1779,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } /* src address space is memory */ - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad CP DMA SRC\n"); return -EINVAL; @@ -1907,7 +1809,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("CP DMA DAIC only supported for registers\n"); return -EINVAL; } - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad CP DMA DST\n"); return -EINVAL; @@ -1937,7 +1839,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, /* 0xffffffff/0x0 is flush all cache flag */ if (radeon_get_ib_value(p, idx + 1) != 0xffffffff || radeon_get_ib_value(p, idx + 2) != 0) { - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad SURFACE_SYNC\n"); return -EINVAL; @@ -1953,7 +1855,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, if (pkt->count) { uint64_t offset;
- r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad EVENT_WRITE\n"); return -EINVAL; @@ -1974,7 +1876,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad EVENT_WRITE_EOP\n"); return -EINVAL; } - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad EVENT_WRITE\n"); return -EINVAL; @@ -2040,7 +1942,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) { case SQ_TEX_VTX_VALID_TEXTURE: /* tex base */ - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad SET_RESOURCE\n"); return -EINVAL; @@ -2054,7 +1956,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, } texture = reloc->robj; /* tex mip base */ - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad SET_RESOURCE\n"); return -EINVAL; @@ -2075,7 +1977,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, { uint64_t offset64; /* vtx base */ - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad SET_RESOURCE\n"); return -EINVAL; @@ -2176,7 +2078,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, { u64 offset;
- r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad STRMOUT_BASE_UPDATE reloc\n"); return -EINVAL; @@ -2220,7 +2122,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, /* Updating memory at DST_ADDRESS. */ if (idx_value & 0x1) { u64 offset; - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n"); return -EINVAL; @@ -2239,7 +2141,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, /* Reading data from SRC_ADDRESS. */ if (((idx_value >> 1) & 0x3) == 2) { u64 offset; - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n"); return -EINVAL; @@ -2264,7 +2166,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, DRM_ERROR("bad MEM_WRITE (invalid count)\n"); return -EINVAL; } - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad MEM_WRITE (missing reloc)\n"); return -EINVAL; @@ -2293,7 +2195,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, if (idx_value & 0x1) { u64 offset; /* SRC is memory. */ - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad COPY_DW (missing src reloc)\n"); return -EINVAL; @@ -2317,7 +2219,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, if (idx_value & 0x2) { u64 offset; /* DST is memory. */ - r = r600_cs_packet_next_reloc(p, &reloc); + r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); if (r) { DRM_ERROR("bad COPY_DW (missing dst reloc)\n"); return -EINVAL; @@ -2503,7 +2405,7 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
void r600_cs_legacy_init(void) { - r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_nomm; + r600_nomm = 1; }
/*
After refactoring the _cs logic, we ended up with many macros and constants that #define the same thing. Clean'em up.
Signed-off-by: Ilija Hadzic ihadzic@research.bell-labs.com --- drivers/gpu/drm/radeon/evergreen_cs.c | 18 +++++++++--------- drivers/gpu/drm/radeon/evergreend.h | 13 ++----------- drivers/gpu/drm/radeon/nid.h | 13 ++----------- drivers/gpu/drm/radeon/r100.c | 8 ++++---- drivers/gpu/drm/radeon/r100d.h | 11 ----------- drivers/gpu/drm/radeon/r300.c | 6 +++--- drivers/gpu/drm/radeon/r300d.h | 11 ----------- drivers/gpu/drm/radeon/r600_cs.c | 10 +++++----- drivers/gpu/drm/radeon/r600d.h | 13 ++----------- drivers/gpu/drm/radeon/rv515d.h | 11 ----------- drivers/gpu/drm/radeon/si.c | 12 ++++++------ drivers/gpu/drm/radeon/sid.h | 13 ++----------- 12 files changed, 35 insertions(+), 104 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 211b509..4a9760a 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -2639,12 +2639,12 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) } p->idx += pkt.count + 2; switch (pkt.type) { - case PACKET_TYPE0: + case RADEON_PACKET_TYPE0: r = evergreen_cs_parse_packet0(p, &pkt); break; - case PACKET_TYPE2: + case RADEON_PACKET_TYPE2: break; - case PACKET_TYPE3: + case RADEON_PACKET_TYPE3: r = evergreen_packet3_check(p, &pkt); break; default: @@ -3395,19 +3395,19 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
do { pkt.idx = idx; - pkt.type = CP_PACKET_GET_TYPE(ib->ptr[idx]); - pkt.count = CP_PACKET_GET_COUNT(ib->ptr[idx]); + pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]); + pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]); pkt.one_reg_wr = 0; switch (pkt.type) { - case PACKET_TYPE0: + case RADEON_PACKET_TYPE0: dev_err(rdev->dev, "Packet0 not allowed!\n"); ret = -EINVAL; break; - case PACKET_TYPE2: + case RADEON_PACKET_TYPE2: idx += 1; break; - case PACKET_TYPE3: - pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]); + case RADEON_PACKET_TYPE3: + pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]); ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt); idx += pkt.count + 2; break; diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index cb9baaa..5ce08cf 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -979,16 +979,7 @@ /* * PM4 */ -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ +#define PACKET0(reg, n) ((RADEON_PACKET_TYPE0 << 30) | \ (((reg) >> 2) & 0xFFFF) | \ ((n) & 0x3FFF) << 16) #define CP_PACKET2 0x80000000 @@ -997,7 +988,7 @@
#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
-#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ +#define PACKET3(op, n) ((RADEON_PACKET_TYPE3 << 30) | \ (((op) & 0xFF) << 8) | \ ((n) & 0x3FFF) << 16)
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index b93186b..a3a3212 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h @@ -474,16 +474,7 @@ /* * PM4 */ -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ +#define PACKET0(reg, n) ((RADEON_PACKET_TYPE0 << 30) | \ (((reg) >> 2) & 0xFFFF) | \ ((n) & 0x3FFF) << 16) #define CP_PACKET2 0x80000000 @@ -492,7 +483,7 @@
#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
-#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ +#define PACKET3(op, n) ((RADEON_PACKET_TYPE3 << 30) | \ (((op) & 0xFF) << 8) | \ ((n) & 0x3FFF) << 16)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 8469607..9db5853 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1410,7 +1410,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
header = radeon_get_ib_value(p, h_idx); crtc_id = radeon_get_ib_value(p, h_idx + 5); - reg = CP_PACKET0_GET_REG(header); + reg = R100_CP_PACKET0_GET_REG(header); obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); if (!obj) { DRM_ERROR("cannot find crtc %d\n", crtc_id); @@ -1997,7 +1997,7 @@ int r100_cs_parse(struct radeon_cs_parser *p) } p->idx += pkt.count + 2; switch (pkt.type) { - case PACKET_TYPE0: + case RADEON_PACKET_TYPE0: if (p->rdev->family >= CHIP_R200) r = r100_cs_parse_packet0(p, &pkt, p->rdev->config.r100.reg_safe_bm, @@ -2009,9 +2009,9 @@ int r100_cs_parse(struct radeon_cs_parser *p) p->rdev->config.r100.reg_safe_bm_size, &r100_packet0_check); break; - case PACKET_TYPE2: + case RADEON_PACKET_TYPE2: break; - case PACKET_TYPE3: + case RADEON_PACKET_TYPE3: r = r100_packet3_check(p, &pkt); break; default: diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h index eab9176..f0f8ee6 100644 --- a/drivers/gpu/drm/radeon/r100d.h +++ b/drivers/gpu/drm/radeon/r100d.h @@ -64,17 +64,6 @@ REG_SET(PACKET3_IT_OPCODE, (op)) | \ REG_SET(PACKET3_COUNT, (n)))
-#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) -#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) - /* Registers */ #define R_0000F0_RBBM_SOFT_RESET 0x0000F0 #define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 98f723c..c60350e 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1263,15 +1263,15 @@ int r300_cs_parse(struct radeon_cs_parser *p) } p->idx += pkt.count + 2; switch (pkt.type) { - case PACKET_TYPE0: + case RADEON_PACKET_TYPE0: r = r100_cs_parse_packet0(p, &pkt, p->rdev->config.r300.reg_safe_bm, p->rdev->config.r300.reg_safe_bm_size, &r300_packet0_check); break; - case PACKET_TYPE2: + case RADEON_PACKET_TYPE2: break; - case PACKET_TYPE3: + case RADEON_PACKET_TYPE3: r = r300_packet3_check(p, &pkt); break; default: diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h index 1f519a5..ff229a0 100644 --- a/drivers/gpu/drm/radeon/r300d.h +++ b/drivers/gpu/drm/radeon/r300d.h @@ -65,17 +65,6 @@ REG_SET(PACKET3_IT_OPCODE, (op)) | \ REG_SET(PACKET3_COUNT, (n)))
-#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) -#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) - /* Registers */ #define R_000148_MC_FB_LOCATION 0x000148 #define S_000148_MC_FB_START(x) (((x) & 0xFFFF) << 0) diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 6f80dbf..652a4a7 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -839,7 +839,7 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p, return r;
/* check its a WAIT_REG_MEM */ - if (wait_reg_mem.type != PACKET_TYPE3 || + if (wait_reg_mem.type != RADEON_PACKET_TYPE3 || wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) { DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n"); return -EINVAL; @@ -882,7 +882,7 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
header = radeon_get_ib_value(p, h_idx); crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); - reg = CP_PACKET0_GET_REG(header); + reg = R600_CP_PACKET0_GET_REG(header);
obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); if (!obj) { @@ -2282,12 +2282,12 @@ int r600_cs_parse(struct radeon_cs_parser *p) } p->idx += pkt.count + 2; switch (pkt.type) { - case PACKET_TYPE0: + case RADEON_PACKET_TYPE0: r = r600_cs_parse_packet0(p, &pkt); break; - case PACKET_TYPE2: + case RADEON_PACKET_TYPE2: break; - case PACKET_TYPE3: + case RADEON_PACKET_TYPE3: r = r600_packet3_check(p, &pkt); break; default: diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 4a53402..62423b0 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -1143,19 +1143,10 @@ /* * PM4 */ -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ +#define PACKET0(reg, n) ((RADEON_PACKET_TYPE0 << 30) | \ (((reg) >> 2) & 0xFFFF) | \ ((n) & 0x3FFF) << 16) -#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ +#define PACKET3(op, n) ((RADEON_PACKET_TYPE3 << 30) | \ (((op) & 0xFF) << 8) | \ ((n) & 0x3FFF) << 16)
diff --git a/drivers/gpu/drm/radeon/rv515d.h b/drivers/gpu/drm/radeon/rv515d.h index 590309a..6927a20 100644 --- a/drivers/gpu/drm/radeon/rv515d.h +++ b/drivers/gpu/drm/radeon/rv515d.h @@ -205,17 +205,6 @@ REG_SET(PACKET3_IT_OPCODE, (op)) | \ REG_SET(PACKET3_COUNT, (n)))
-#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) -#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) - /* Registers */ #define R_0000F0_RBBM_SOFT_RESET 0x0000F0 #define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index ef68365..34d2440 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -2793,19 +2793,19 @@ int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
do { pkt.idx = idx; - pkt.type = CP_PACKET_GET_TYPE(ib->ptr[idx]); - pkt.count = CP_PACKET_GET_COUNT(ib->ptr[idx]); + pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]); + pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]); pkt.one_reg_wr = 0; switch (pkt.type) { - case PACKET_TYPE0: + case RADEON_PACKET_TYPE0: dev_err(rdev->dev, "Packet0 not allowed!\n"); ret = -EINVAL; break; - case PACKET_TYPE2: + case RADEON_PACKET_TYPE2: idx += 1; break; - case PACKET_TYPE3: - pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]); + case RADEON_PACKET_TYPE3: + pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]); if (ib->is_const_ib) ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt); else { diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 62b4621..1cc0ea4 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h @@ -767,16 +767,7 @@ /* * PM4 */ -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ +#define PACKET0(reg, n) ((RADEON_PACKET_TYPE0 << 30) | \ (((reg) >> 2) & 0xFFFF) | \ ((n) & 0x3FFF) << 16) #define CP_PACKET2 0x80000000 @@ -785,7 +776,7 @@
#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
-#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ +#define PACKET3(op, n) ((RADEON_PACKET_TYPE3 << 30) | \ (((op) & 0xFF) << 8) | \ ((n) & 0x3FFF) << 16)
The following set of patches refactor the CS-parser logic in an effort to consolidate the code that is repeated across ASIC-specific files. All patches except #8 are function-neutral, that is they preserve the existing functionality of the driver. Patch #8 adds one extra check for WAIT_REG_MEM packet that I believe should be there.
I have been running with these patches for about a month on several machines with Evergreen and NI GPUs without noticing any regressions. I also ran quick tests on all Radeon GPUs that I had around, which range from R300 through NI cards.
Did you run these with pre-kms userspace etc to make sure it doesn't cause regressions there?
Dave.
On Fri, 4 Jan 2013, Dave Airlie wrote:
Did you run these with pre-kms userspace etc to make sure it doesn't cause regressions there?
No, I didn't, but I can give it a quick whirl. I think I still have one or two machines with 6.14.x DDX that I can put in UMS mode and see what happens.
Haven't used UMS for at least 2-3 years. My bet is that it is more likely that I will hit a few unrelated UMS problems that are there even without my patches, but I'll let you know the result when I have it.
-- Ilija
On Fri, 4 Jan 2013, Dave Airlie wrote:
Did you run these with pre-kms userspace etc to make sure it doesn't cause regressions there?
I did some tests with UMS and shuffled a number of cards. As I feared, I ran into a number of unrelated problems, but in each case I have seen identical beahvior between the kernel with my patches and without. So as far as I can tell, my patches do not introduce regressions in legacy modes, althugh I am not sure about the coverage.
Also, in one test, I think I have hit a genuine bug in ATI DDX (explained below).
Below I describe what I saw with each card family. Maybe for some test cases I am missing some "magic" option in xorg.conf or maybe what I am seeing (mostly reduced feature set) is expected in UMS.
* With an NI card (TURKS, HD6570 card), Xorg just plain tells me that the card is supported in KMS only mode. So, I guess, that's it for that card.
* A test with Evergreen (CEDAR) card works in UMS mode, but I can't get 3D acceleration. I see these messages in Xorg log file:
[ 37.024] (II) RADEON(0): No DRI yet on Evergreen ..... ..... [ 37.364] (II) AIGLX: Screen 0 is not DRI2 capable [ 37.364] (II) AIGLX: Screen 0 is not DRI capable [ 37.664] (II) AIGLX: Loaded and initialized swrast [ 37.664] (II) GLX: Initialized DRISWRAST GL provider for screen 0
Sounds like just a "property" of UMS to me, but I am not sure. Nevertheless, the behavior with and without my kernel patches is identical. Still, 2D copying should still be exercising the CS parser, so there is some test coverage here.
* A test with an R7xx card (RV730, E4690 card) results in a segfault in DDX. Again, this is irrespective of my kernel patches, so I believe that the bug has been there for a while and that it's in userland. The crash occurs in r600_set_render_target() function and what causes it is corrupted cb_conf->surface pointer. When the crash occurs it has a value of 0x1, which doesn't look like something that would live in .bss, .data or come from the heap. I didn't try other R6xx cards, but I suspect that they may have the same problem because they share the code in DDX. I don't know if UMS DDX will be maintained going forward, so I don't know if it makes sense to open a bug for this. BTW, DDX I am testing this with is 6.14.6
* A test with R300 card (Radeon X300 card) works (again identically with and without my patches), but again without 3D acceleration. So it's similar result and comment as with the Evergreen test, though relevant messages in Xorg log file are slightly different:
[ 35.630] (EE) AIGLX error: r300 does not export required DRI extension [ 35.630] (EE) AIGLX: reverting to software rendering [ 35.915] (II) AIGLX: Loaded and initialized swrast [ 35.915] (II) GLX: Initialized DRISWRAST GL provider for screen 0
Again, I don't know if this is just the way things are in UMS mode or if there is some configuration magic I need to do.
So at this point I'd say that I have not seen anything that would indicate a regression in legacy mode, although the limitations I have hit make the tests more limited that I thought they would be (and KMS I tested quite a bit, so I am confident there).
thanks,
Ilija
On Fri, Jan 4, 2013 at 5:57 PM, Ilija Hadzic ihadzic@research.bell-labs.com wrote:
On Fri, 4 Jan 2013, Dave Airlie wrote:
Did you run these with pre-kms userspace etc to make sure it doesn't cause regressions there?
I did some tests with UMS and shuffled a number of cards. As I feared, I ran into a number of unrelated problems, but in each case I have seen identical beahvior between the kernel with my patches and without. So as far as I can tell, my patches do not introduce regressions in legacy modes, althugh I am not sure about the coverage.
Also, in one test, I think I have hit a genuine bug in ATI DDX (explained below).
Below I describe what I saw with each card family. Maybe for some test cases I am missing some "magic" option in xorg.conf or maybe what I am seeing (mostly reduced feature set) is expected in UMS.
- With an NI card (TURKS, HD6570 card), Xorg just plain tells me that the card is supported in KMS only mode. So, I guess, that's it for that card.
Evergreen was the last set of hardware supported by UMS.
- A test with Evergreen (CEDAR) card works in UMS mode, but I can't get 3D acceleration. I see these messages in Xorg log file:
[ 37.024] (II) RADEON(0): No DRI yet on Evergreen
UMS support for evergreen is modesetting only. No accel.
..... ..... [ 37.364] (II) AIGLX: Screen 0 is not DRI2 capable [ 37.364] (II) AIGLX: Screen 0 is not DRI capable [ 37.664] (II) AIGLX: Loaded and initialized swrast [ 37.664] (II) GLX: Initialized DRISWRAST GL provider for screen 0
Sounds like just a "property" of UMS to me, but I am not sure. Nevertheless, the behavior with and without my kernel patches is identical. Still, 2D copying should still be exercising the CS parser, so there is some test coverage here.
- A test with an R7xx card (RV730, E4690 card) results in a segfault in DDX. Again, this is irrespective of my kernel patches, so I believe that the bug has been there for a while and that it's in userland. The crash occurs in r600_set_render_target() function and what causes it is corrupted cb_conf->surface pointer. When the crash occurs it has a value of 0x1, which doesn't look like something that would live in .bss, .data or come from the heap. I didn't try other R6xx cards, but I suspect that they may have the same problem because they share the code in DDX. I don't know if UMS DDX will be maintained going forward, so I don't know if it makes sense to open a bug for this. BTW, DDX I am testing this with is 6.14.6
R6xx and r7xx are really all you need to worry about in this case. R1xx-r5xx UMS uses a different kernel interface for command submission and evergreen and later don't have UMS drm support. UMS r6xx/r7xx support used the same kernel interface for command submission but the kernel side was much simpler. Additionally, UMS requires the old non-gallium 3D drivers. It sounds like some other change in the ddx broke UMS support for r6xx/r7xx. UMS support was dropped for xf86-video-ati 7.0.0, so we mostly want to try and avoid breaking things for users with ancient userspace stacks and a new kernel. That said, I'm not sure there are that many UMS users left.
Alex
- A test with R300 card (Radeon X300 card) works (again identically with and without my patches), but again without 3D acceleration. So it's similar result and comment as with the Evergreen test, though relevant messages in Xorg log file are slightly different:
[ 35.630] (EE) AIGLX error: r300 does not export required DRI extension [ 35.630] (EE) AIGLX: reverting to software rendering [ 35.915] (II) AIGLX: Loaded and initialized swrast [ 35.915] (II) GLX: Initialized DRISWRAST GL provider for screen 0
Again, I don't know if this is just the way things are in UMS mode or if there is some configuration magic I need to do.
So at this point I'd say that I have not seen anything that would indicate a regression in legacy mode, although the limitations I have hit make the tests more limited that I thought they would be (and KMS I tested quite a bit, so I am confident there).
thanks,
Ilija
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[SNIP]
On 05.01.2013 00:42, Alex Deucher wrote:
R6xx and r7xx are really all you need to worry about in this case. R1xx-r5xx UMS uses a different kernel interface for command submission and evergreen and later don't have UMS drm support. UMS r6xx/r7xx support used the same kernel interface for command submission but the kernel side was much simpler. Additionally, UMS requires the old non-gallium 3D drivers. It sounds like some other change in the ddx broke UMS support for r6xx/r7xx. UMS support was dropped for xf86-video-ati 7.0.0, so we mostly want to try and avoid breaking things for users with ancient userspace stacks and a new kernel. That said, I'm not sure there are that many UMS users left.
Alex
Wouldn't it be a good idea to finally get ride of the old UMS stuff inside the kernel driver?
Maybe making it a config option with default N as first step and then wait for a year or two and see if anybody starts complaining?
Christian.
On Sat, Jan 05, 2013 at 03:21:27PM +0100, Christian König wrote:
[SNIP]
On 05.01.2013 00:42, Alex Deucher wrote:
R6xx and r7xx are really all you need to worry about in this case. R1xx-r5xx UMS uses a different kernel interface for command submission and evergreen and later don't have UMS drm support. UMS r6xx/r7xx support used the same kernel interface for command submission but the kernel side was much simpler. Additionally, UMS requires the old non-gallium 3D drivers. It sounds like some other change in the ddx broke UMS support for r6xx/r7xx. UMS support was dropped for xf86-video-ati 7.0.0, so we mostly want to try and avoid breaking things for users with ancient userspace stacks and a new kernel. That said, I'm not sure there are that many UMS users left.
Alex
Wouldn't it be a good idea to finally get ride of the old UMS stuff inside the kernel driver?
Maybe making it a config option with default N as first step and then wait for a year or two and see if anybody starts complaining?
Multiply that waiting time by 10 and you're there ;-) At least that's my understanding of the "thou shalt not break existing userspace" rule. And afaik we still get the oddball ums/non-gem/dri1 regression report for the intel driver every few months. We tried very hard though over the past few releases to separate out the old code to reduce those though ... -Daniel
On Fri, 4 Jan 2013, Alex Deucher wrote:
R6xx and r7xx are really all you need to worry about in this case. R1xx-r5xx UMS uses a different kernel interface for command submission and evergreen and later don't have UMS drm support. UMS r6xx/r7xx support used the same kernel interface for command submission but the kernel side was much simpler.
OK, I have found an old machine with RV730 GPU and a known-working UMS: 2.6.35 kernel, 6.13.2 DDX, 7.8.2 mesa (classic), 1.9 Xorg). I changed the kernel to the latest drm-next and ran tests with and without my CS-refactoring patches. Here are the results:
* It appears that drm-next in its current state is broken with regard to UMS (nothing to do with my patches, it was pre-broken to begin with). UMS provokes the kernel into a NULL-pointer dereference oops. Good news is that I have tracked down the crash and I will be sending the patches with the fix shortly.
* There are multiple patches that contributed to the breakage of UMS. I didn't bother pin-pointing them all, but one that I looked (6a7068b4) dates back to April 2012 so there are kernels out in distros that crash on UMS. That probably tells us how many UMS users are left out there :-). BTW, the reason UMS crashes is because parser->rdev is NULL in UMS mode so every patch that tries to dereference it (and shares the code path with UMS) will cause an oops (it will become clear when you see the patches).
* So, having fixed the above incidental finding, I got my machine with ancient UMS-userspace and a shiny latest drm-next kernel (plus my CS-refactoring patches plus my yet-to-be-sent UMS fixes) to work. My test consists of bringing up Gnome (it's Gnome 2 on that machine), running glxgears, sphereworld (an example code from OpenGL Superbible book), and OpenArena. Everything seems to work.
* Going back to KMS and retesting there, things still look good.
So this (with tests I did on Friday) should cover all the cases.
Additionally, UMS requires the old non-gallium 3D drivers. It sounds like some other change in the ddx broke UMS support for r6xx/r7xx.
The DDX segfault I reported on Friday was provoked by trying to run Gallium 3D driver on the top of UMS. Once I switched back to classic, the crash went away. So I guess the userspace crash was provoked by some obscure path that was never intended to be exercised. I don't think it's worth investigating further.
-- Ilija
On Tue, Jan 8, 2013 at 12:09 AM, Ilija Hadzic ihadzic@research.bell-labs.com wrote:
On Fri, 4 Jan 2013, Alex Deucher wrote:
R6xx and r7xx are really all you need to worry about in this case. R1xx-r5xx UMS uses a different kernel interface for command submission and evergreen and later don't have UMS drm support. UMS r6xx/r7xx support used the same kernel interface for command submission but the kernel side was much simpler.
OK, I have found an old machine with RV730 GPU and a known-working UMS: 2.6.35 kernel, 6.13.2 DDX, 7.8.2 mesa (classic), 1.9 Xorg). I changed the kernel to the latest drm-next and ran tests with and without my CS-refactoring patches. Here are the results:
It appears that drm-next in its current state is broken with regard to UMS (nothing to do with my patches, it was pre-broken to begin with). UMS provokes the kernel into a NULL-pointer dereference oops. Good news is that I have tracked down the crash and I will be sending the patches with the fix shortly.
There are multiple patches that contributed to the breakage of UMS. I didn't bother pin-pointing them all, but one that I looked (6a7068b4) dates back to April 2012 so there are kernels out in distros that crash on UMS. That probably tells us how many UMS users are left out there :-). BTW, the reason UMS crashes is because parser->rdev is NULL in UMS mode so every patch that tries to dereference it (and shares the code path with UMS) will cause an oops (it will become clear when you see the patches).
So, having fixed the above incidental finding, I got my machine with ancient UMS-userspace and a shiny latest drm-next kernel (plus my CS-refactoring patches plus my yet-to-be-sent UMS fixes) to work. My test consists of bringing up Gnome (it's Gnome 2 on that machine), running glxgears, sphereworld (an example code from OpenGL Superbible book), and OpenArena. Everything seems to work.
Going back to KMS and retesting there, things still look good.
So this (with tests I did on Friday) should cover all the cases.
Additionally, UMS requires the old non-gallium 3D drivers. It sounds like some other change in the ddx broke UMS support for r6xx/r7xx.
The DDX segfault I reported on Friday was provoked by trying to run Gallium 3D driver on the top of UMS. Once I switched back to classic, the crash went away. So I guess the userspace crash was provoked by some obscure path that was never intended to be exercised. I don't think it's worth investigating further.
IIRC, the radeon gallium drivers call abort() if they encounter an unsupported DRM version (that is UMS).
Marek
On Mon, Jan 7, 2013 at 7:21 PM, Marek Olšák maraeo@gmail.com wrote:
IIRC, the radeon gallium drivers call abort() if they encounter an unsupported DRM version (that is UMS).
I am not familiar enough to comment, but my observation was that as soon as I backed out to classic, the segfault went away. So I assumed that the mismatch between the UMS and Gallium was the cause.
Anyway, it's a secondary issue for this thread.
-- Ilija
On 08.01.2013 00:09, Ilija Hadzic wrote:
- There are multiple patches that contributed to the breakage of UMS. I didn't bother pin-pointing them all, but one that I looked (6a7068b4) dates back to April 2012 so there are kernels out in distros that crash on UMS. That probably tells us how many UMS users are left out there :-). BTW, the reason UMS crashes is because parser->rdev is NULL in UMS mode so every patch that tries to dereference it (and shares the code path with UMS) will cause an oops (it will become clear when you see the patches).
Well, that are some very valuable informations. Thx allot for testing and preparing patches to fix those bugs.
It confirms my suspicion that nobody is testing the UMS code paths any more and so in reality the code is completely unmaintained.
Christian.
On Wed, Jan 2, 2013 at 6:27 PM, Ilija Hadzic ihadzic@research.bell-labs.com wrote:
The following set of patches refactor the CS-parser logic in an effort to consolidate the code that is repeated across ASIC-specific files. All patches except #8 are function-neutral, that is they preserve the existing functionality of the driver. Patch #8 adds one extra check for WAIT_REG_MEM packet that I believe should be there.
I have been running with these patches for about a month on several machines with Evergreen and NI GPUs without noticing any regressions. I also ran quick tests on all Radeon GPUs that I had around, which range from R300 through NI cards.
The patches have been rebased to the current state of Dave's drm-next branch.
Looks good to me. Nice clean up. As long as there are no regressions with UMS, consider them applied.
Thanks!
Alex
dri-devel@lists.freedesktop.org