diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index 67375dccc1d..0d22c629d90 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -155,7 +155,7 @@ static struct radeon_winsys_cs * radeon_drm_cs_create(struct radeon_winsys *rws, enum ring_type ring_type, void (*flush)(void *ctx, unsigned flags, - struct pipe_fence_handle **fence), + struct pipe_fence_handle **fence), void *flush_ctx, struct radeon_winsys_cs_handle *trace_buf) { @@ -196,10 +196,10 @@ radeon_drm_cs_create(struct radeon_winsys *rws, #define OUT_CS(cs, value) (cs)->buf[(cs)->cdw++] = (value) static INLINE void update_reloc(struct drm_radeon_cs_reloc *reloc, - enum radeon_bo_domain rd, - enum radeon_bo_domain wd, - unsigned priority, - enum radeon_bo_domain *added_domains) + enum radeon_bo_domain rd, + enum radeon_bo_domain wd, + unsigned priority, + enum radeon_bo_domain *added_domains) { *added_domains = (rd | wd) & ~(reloc->read_domains | reloc->write_domain); @@ -434,33 +434,37 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, switch (cs->base.ring_type) { case RING_DMA: - /* pad DMA ring to 8 DWs */ - if (cs->ws->info.chip_class <= SI) { - while (rcs->cdw & 7) - OUT_CS(&cs->base, 0xf0000000); /* NOP packet */ - } else { - while (rcs->cdw & 7) - OUT_CS(&cs->base, 0x00000000); /* NOP packet */ - } - break; + /* pad DMA ring to 8 DWs */ + if (cs->ws->info.chip_class <= SI) { + while (rcs->cdw & 7) + OUT_CS(&cs->base, 0xf0000000); /* NOP packet */ + } else { + while (rcs->cdw & 7) + OUT_CS(&cs->base, 0x00000000); /* NOP packet */ + } + break; case RING_GFX: - /* pad DMA ring to 8 DWs to meet CP fetch alignment requirements - * r6xx, requires at least 4 dw alignment to avoid a hw bug. - */ - if (cs->ws->info.chip_class <= SI) { - while (rcs->cdw & 7) - OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */ - } else { - while (rcs->cdw & 7) - OUT_CS(&cs->base, 0xffff1000); /* type3 nop packet */ - } - break; + /* pad DMA ring to 8 DWs to meet CP fetch alignment requirements + * r6xx, requires at least 4 dw alignment to avoid a hw bug. + * hawaii with old firmware needs type2 nop packet. + * accel_working2 with value 3 indicates the new firmware. + */ + if (cs->ws->info.chip_class <= SI || + (cs->ws->info.family == CHIP_HAWAII && + cs->ws->accel_working2 < 3)) { + while (rcs->cdw & 7) + OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */ + } else { + while (rcs->cdw & 7) + OUT_CS(&cs->base, 0xffff1000); /* type3 nop packet */ + } + break; case RING_UVD: - while (rcs->cdw & 15) - OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */ - break; + while (rcs->cdw & 15) + OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */ + break; default: - break; + break; } if (rcs->cdw > RADEON_MAX_CMDBUF_DWORDS) { diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c index e54e79e38f8..703375871eb 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -382,6 +382,16 @@ static boolean do_winsys_init(struct radeon_drm_winsys *ws) radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_PIPES, NULL, &ws->info.r600_max_pipes); + radeon_get_drm_value(ws->fd, RADEON_INFO_ACCEL_WORKING2, NULL, + &ws->accel_working2); + if (ws->info.family == CHIP_HAWAII && ws->accel_working2 < 2) { + fprintf(stderr, "radeon: GPU acceleration for Hawaii disabled, " + "returned accel_working2 value %u is smaller than 2. " + "Please install a newer kernel.\n", + ws->accel_working2); + return FALSE; + } + if (radeon_get_drm_value(ws->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, NULL, ws->info.si_tile_mode_array)) { ws->info.si_tile_mode_array_valid = TRUE; diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h index 18fe0aeab10..1e0c632be99 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h @@ -55,6 +55,7 @@ struct radeon_drm_winsys { enum radeon_generation gen; struct radeon_info info; uint32_t va_start; + uint32_t accel_working2; struct pb_manager *kman; struct pb_manager *cman;