freedreno: add a20x
authorJonathan Marek <jonathan@marek.ca>
Thu, 21 Jun 2018 21:06:27 +0000 (17:06 -0400)
committerRob Clark <robdclark@gmail.com>
Fri, 22 Jun 2018 12:23:10 +0000 (08:23 -0400)
this patch adds support for a20x, which has some differences with a220:
-no VGT_MAX_VTX_INDX register
-no CLEAR_COLOR register
-set RB_BC_CONTROL in restore (hangs without)
-different CP_DRAW_INDX format

tested with kmscube and glmark2 scenes, on par with a220

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a2xx/fd2_draw.c
src/gallium/drivers/freedreno/a2xx/fd2_emit.c
src/gallium/drivers/freedreno/a2xx/fd2_gmem.c
src/gallium/drivers/freedreno/freedreno_draw.h
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_screen.h
src/gallium/drivers/freedreno/freedreno_util.h

index 8df1793a35f95792ec8f442ebb9296b50e352d19..ca634d794ad89f85083238eb9d9bf4a6857c184c 100644 (file)
@@ -101,12 +101,14 @@ fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
        OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
        OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
 
-       OUT_WFI (ring);
+       if (!is_a20x(ctx->screen)) {
+               OUT_WFI (ring);
 
-       OUT_PKT3(ring, CP_SET_CONSTANT, 3);
-       OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
-       OUT_RING(ring, info->max_index);        /* VGT_MAX_VTX_INDX */
-       OUT_RING(ring, info->min_index);        /* VGT_MIN_VTX_INDX */
+               OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+               OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+               OUT_RING(ring, info->max_index);        /* VGT_MAX_VTX_INDX */
+               OUT_RING(ring, info->min_index);        /* VGT_MIN_VTX_INDX */
+       }
 
        fd_draw_emit(ctx->batch, ring, ctx->primtypes[info->mode],
                                 IGNORE_VISIBILITY, info, index_offset);
@@ -157,9 +159,18 @@ fd2_clear(struct fd_context *ctx, unsigned buffers,
        OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1);
        OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE);
 
-       OUT_PKT3(ring, CP_SET_CONSTANT, 2);
-       OUT_RING(ring, CP_REG(REG_A2XX_CLEAR_COLOR));
-       OUT_RING(ring, colr);
+       if (is_a20x(ctx->screen)) {
+               OUT_PKT3(ring, CP_SET_CONSTANT, 5);
+               OUT_RING(ring, 0x00000480);
+               OUT_RING(ring, color->ui[0]);
+               OUT_RING(ring, color->ui[1]);
+               OUT_RING(ring, color->ui[2]);
+               OUT_RING(ring, color->ui[3]);
+       } else {
+               OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+               OUT_RING(ring, CP_REG(REG_A2XX_CLEAR_COLOR));
+               OUT_RING(ring, colr);
+       }
 
        OUT_PKT3(ring, CP_SET_CONSTANT, 2);
        OUT_RING(ring, CP_REG(REG_A2XX_A220_RB_LRZ_VSC_CONTROL));
@@ -264,10 +275,12 @@ fd2_clear(struct fd_context *ctx, unsigned buffers,
                OUT_RING(ring, 0x0);
        }
 
-       OUT_PKT3(ring, CP_SET_CONSTANT, 3);
-       OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
-       OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
-       OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+       if (!is_a20x(ctx->screen)) {
+               OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+               OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+               OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
+               OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+       }
 
        fd_draw(ctx->batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
                        DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL);
index d749eb0324a9c2fc178dc9680d7c7080dd4385c9..4bf41b2c678007e04b38b101bd87ace66841f5dd 100644 (file)
@@ -332,6 +332,16 @@ fd2_emit_state(struct fd_context *ctx, const enum fd_dirty_3d_state dirty)
 void
 fd2_emit_restore(struct fd_context *ctx, struct fd_ringbuffer *ring)
 {
+       if (is_a20x(ctx->screen)) {
+               OUT_PKT0(ring, REG_A2XX_RB_BC_CONTROL, 1);
+               OUT_RING(ring,
+                       A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT(3) |
+                       A2XX_RB_BC_CONTROL_DISABLE_LZ_NULL_ZCMD_DROP |
+                       A2XX_RB_BC_CONTROL_ENABLE_CRC_UPDATE |
+                       A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT(8) |
+                       A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT(3));
+       }
+
        OUT_PKT0(ring, REG_A2XX_TP0_CHICKEN, 1);
        OUT_RING(ring, 0x00000002);
 
index 46a7d18ef090ef1963a1cb2fbc82426e9a5ef1f6..62382995c09c8e5179659e45b145be1ee4d001ea 100644 (file)
@@ -89,12 +89,14 @@ emit_gmem2mem_surf(struct fd_batch *batch, uint32_t base,
                        A2XX_RB_COPY_DEST_INFO_WRITE_BLUE |
                        A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA);
 
-       OUT_WFI (ring);
+       if (!is_a20x(batch->ctx->screen)) {
+               OUT_WFI (ring);
 
-       OUT_PKT3(ring, CP_SET_CONSTANT, 3);
-       OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
-       OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
-       OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+               OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+               OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+               OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
+               OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+       }
 
        fd_draw(batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
                        DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL);
@@ -214,10 +216,12 @@ emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base,
        OUT_RING(ring, 0x00000000);
        OUT_RING(ring, 0x00000200);
 
-       OUT_PKT3(ring, CP_SET_CONSTANT, 3);
-       OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
-       OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
-       OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+       if (!is_a20x(batch->ctx->screen)) {
+               OUT_PKT3(ring, CP_SET_CONSTANT, 3);
+               OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX));
+               OUT_RING(ring, 3);                 /* VGT_MAX_VTX_INDX */
+               OUT_RING(ring, 0);                 /* VGT_MIN_VTX_INDX */
+       }
 
        fd_draw(batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY,
                        DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL);
index b293f73b82ed4f4f89f037df3d7f5d084d97db9b..4a922d9ca3b0f422e83fae28a5bdaf71b4648637 100644 (file)
@@ -74,18 +74,25 @@ fd_draw(struct fd_batch *batch, struct fd_ringbuffer *ring,
                OUT_RING(ring, 0);
        }
 
-       OUT_PKT3(ring, CP_DRAW_INDX, idx_buffer ? 5 : 3);
-       OUT_RING(ring, 0x00000000);        /* viz query info. */
-       if (vismode == USE_VISIBILITY) {
-               /* leave vis mode blank for now, it will be patched up when
-                * we know if we are binning or not
-                */
-               OUT_RINGP(ring, DRAW(primtype, src_sel, idx_type, 0, instances),
-                               &batch->draw_patches);
+       if (is_a20x(batch->ctx->screen)) {
+               OUT_PKT3(ring, CP_DRAW_INDX, idx_buffer ? 4 : 2);
+               OUT_RING(ring, 0x00000000);
+               OUT_RING(ring, DRAW_A20X(primtype, src_sel, idx_type, vismode, count));
        } else {
-               OUT_RING(ring, DRAW(primtype, src_sel, idx_type, vismode, instances));
+               OUT_PKT3(ring, CP_DRAW_INDX, idx_buffer ? 5 : 3);
+               OUT_RING(ring, 0x00000000);        /* viz query info. */
+               if (vismode == USE_VISIBILITY) {
+                       /* leave vis mode blank for now, it will be patched up when
+                        * we know if we are binning or not
+                        */
+                       OUT_RINGP(ring, DRAW(primtype, src_sel, idx_type, 0, instances),
+                                       &batch->draw_patches);
+               } else {
+                       OUT_RING(ring, DRAW(primtype, src_sel, idx_type, vismode, instances));
+               }
+               OUT_RING(ring, count);             /* NumIndices */
        }
-       OUT_RING(ring, count);             /* NumIndices */
+
        if (idx_buffer) {
                OUT_RELOC(ring, fd_resource(idx_buffer)->bo, idx_offset, 0, 0);
                OUT_RING (ring, idx_size);
index 2e842a8da7d1d5d5223d9aa7f0a710f5f178ef88..042e0384f1a692f9c97cb479a7da1072f5815489 100644 (file)
@@ -875,6 +875,7 @@ fd_screen_create(struct fd_device *dev)
         * send a patch ;-)
         */
        switch (screen->gpu_id) {
+       case 205:
        case 220:
                fd2_screen_init(pscreen);
                break;
index 6be739ae2876bcffe76c510927e973ecbbcd193b..013dba1a6d3468b835640f128a548d27c1edea8a 100644 (file)
@@ -106,6 +106,12 @@ struct fd_bo * fd_screen_bo_from_handle(struct pipe_screen *pscreen,
 
 struct pipe_screen * fd_screen_create(struct fd_device *dev);
 
+static inline boolean
+is_a20x(struct fd_screen *screen)
+{
+       return (screen->gpu_id >= 200) && (screen->gpu_id < 210);
+}
+
 /* is a3xx patch revision 0? */
 /* TODO a306.0 probably doesn't need this.. be more clever?? */
 static inline boolean
index 9645561e07105887ccf72af76a6982b43896edf2..cdac08be6e2583660313a15af2ffcdaa98c8ab10 100644 (file)
@@ -112,6 +112,19 @@ static inline uint32_t DRAW(enum pc_di_primtype prim_type,
                        (instances         << 24);
 }
 
+static inline uint32_t DRAW_A20X(enum pc_di_primtype prim_type,
+               enum pc_di_src_sel source_select, enum pc_di_index_size index_size,
+               enum pc_di_vis_cull_mode vis_cull_mode,
+               uint16_t count)
+{
+       return (prim_type         << 0) |
+                       (source_select     << 6) |
+                       ((index_size & 1)  << 11) |
+                       ((index_size >> 1) << 13) |
+                       (vis_cull_mode     << 9) |
+                       (count         << 16);
+}
+
 /* for tracking cmdstream positions that need to be patched: */
 struct fd_cs_patch {
        uint32_t *cs;