static inline void etna_set_state_from_bo(struct etna_cmd_stream *stream, uint32_t address, struct etna_bo *bo) { etna_cmd_stream_reserve(stream, 2); etna_emit_load_state(stream, address >> 2, 1); etna_cmd_stream_reloc(stream, &(struct etna_reloc){ .bo = bo, .flags = ETNA_RELOC_READ, .offset = 0, });
void etna_stall(struct etna_cmd_stream *stream, uint32_t from, uint32_t to) { etna_cmd_stream_reserve(stream, 4); etna_emit_load_state(stream, VIVS_GL_SEMAPHORE_TOKEN >> 2, 1, 0); etna_cmd_stream_emit(stream, VIVS_GL_SEMAPHORE_TOKEN_FROM(from) | VIVS_GL_SEMAPHORE_TOKEN_TO(to)); if (from == SYNC_RECIPIENT_FE) { /* if the frontend is to be stalled, queue a STALL frontend command */ CMD_STALL(stream, from, to); } else { /* otherwise, load the STALL token state */ etna_emit_load_state(stream, VIVS_GL_STALL_TOKEN >> 2, 1, 0); etna_cmd_stream_emit(stream, VIVS_GL_STALL_TOKEN_FROM(from) | VIVS_GL_STALL_TOKEN_TO(to)); } }
/* submit RS state, without any processing and no dependence on context * except TS if this is a source-to-destination blit. */ static void etna_submit_rs_state(struct etna_context *ctx, const struct compiled_rs_state *cs) { struct etna_screen *screen = etna_screen(ctx->base.screen); struct etna_cmd_stream *stream = ctx->stream; struct etna_coalesce coalesce; if (cs->RS_KICKER_INPLACE && !cs->source_ts_valid) /* Inplace resolve is no-op if TS is not configured */ return; ctx->stats.rs_operations++; if (cs->RS_KICKER_INPLACE) { etna_cmd_stream_reserve(stream, 6); etna_coalesce_start(stream, &coalesce); /* 0/1 */ EMIT_STATE(RS_EXTRA_CONFIG, cs->RS_EXTRA_CONFIG); /* 2/3 */ EMIT_STATE(RS_SOURCE_STRIDE, cs->RS_SOURCE_STRIDE); /* 4/5 */ EMIT_STATE(RS_KICKER_INPLACE, cs->RS_KICKER_INPLACE); etna_coalesce_end(stream, &coalesce); } else if (screen->specs.pixel_pipes == 1) { etna_cmd_stream_reserve(stream, 22); etna_coalesce_start(stream, &coalesce); /* 0/1 */ EMIT_STATE(RS_CONFIG, cs->RS_CONFIG); /* 2 */ EMIT_STATE_RELOC(RS_SOURCE_ADDR, &cs->source[0]); /* 3 */ EMIT_STATE(RS_SOURCE_STRIDE, cs->RS_SOURCE_STRIDE); /* 4 */ EMIT_STATE_RELOC(RS_DEST_ADDR, &cs->dest[0]); /* 5 */ EMIT_STATE(RS_DEST_STRIDE, cs->RS_DEST_STRIDE); /* 6/7 */ EMIT_STATE(RS_WINDOW_SIZE, cs->RS_WINDOW_SIZE); /* 8/9 */ EMIT_STATE(RS_DITHER(0), cs->RS_DITHER[0]); /*10 */ EMIT_STATE(RS_DITHER(1), cs->RS_DITHER[1]); /*11 - pad */ /*12/13*/ EMIT_STATE(RS_CLEAR_CONTROL, cs->RS_CLEAR_CONTROL); /*14 */ EMIT_STATE(RS_FILL_VALUE(0), cs->RS_FILL_VALUE[0]); /*15 */ EMIT_STATE(RS_FILL_VALUE(1), cs->RS_FILL_VALUE[1]); /*16 */ EMIT_STATE(RS_FILL_VALUE(2), cs->RS_FILL_VALUE[2]); /*17 */ EMIT_STATE(RS_FILL_VALUE(3), cs->RS_FILL_VALUE[3]); /*18/19*/ EMIT_STATE(RS_EXTRA_CONFIG, cs->RS_EXTRA_CONFIG); /*20/21*/ EMIT_STATE(RS_KICKER, 0xbeebbeeb); etna_coalesce_end(stream, &coalesce); } else if (screen->specs.pixel_pipes == 2) { etna_cmd_stream_reserve(stream, 34); /* worst case - both pipes multi=1 */ etna_coalesce_start(stream, &coalesce); /* 0/1 */ EMIT_STATE(RS_CONFIG, cs->RS_CONFIG); /* 2/3 */ EMIT_STATE(RS_SOURCE_STRIDE, cs->RS_SOURCE_STRIDE); /* 4/5 */ EMIT_STATE(RS_DEST_STRIDE, cs->RS_DEST_STRIDE); /* 6/7 */ EMIT_STATE_RELOC(RS_PIPE_SOURCE_ADDR(0), &cs->source[0]); if (cs->RS_SOURCE_STRIDE & VIVS_RS_SOURCE_STRIDE_MULTI) { /*8 */ EMIT_STATE_RELOC(RS_PIPE_SOURCE_ADDR(1), &cs->source[1]); /*9 - pad */ } /*10/11*/ EMIT_STATE_RELOC(RS_PIPE_DEST_ADDR(0), &cs->dest[0]); if (cs->RS_DEST_STRIDE & VIVS_RS_DEST_STRIDE_MULTI) { /*12*/ EMIT_STATE_RELOC(RS_PIPE_DEST_ADDR(1), &cs->dest[1]); /*13 - pad */ } /*14/15*/ EMIT_STATE(RS_PIPE_OFFSET(0), cs->RS_PIPE_OFFSET[0]); /*16 */ EMIT_STATE(RS_PIPE_OFFSET(1), cs->RS_PIPE_OFFSET[1]); /*17 - pad */ /*18/19*/ EMIT_STATE(RS_WINDOW_SIZE, cs->RS_WINDOW_SIZE); /*20/21*/ EMIT_STATE(RS_DITHER(0), cs->RS_DITHER[0]); /*22 */ EMIT_STATE(RS_DITHER(1), cs->RS_DITHER[1]); /*23 - pad */ /*24/25*/ EMIT_STATE(RS_CLEAR_CONTROL, cs->RS_CLEAR_CONTROL); /*26 */ EMIT_STATE(RS_FILL_VALUE(0), cs->RS_FILL_VALUE[0]); /*27 */ EMIT_STATE(RS_FILL_VALUE(1), cs->RS_FILL_VALUE[1]); /*28 */ EMIT_STATE(RS_FILL_VALUE(2), cs->RS_FILL_VALUE[2]); /*29 */ EMIT_STATE(RS_FILL_VALUE(3), cs->RS_FILL_VALUE[3]); /*30/31*/ EMIT_STATE(RS_EXTRA_CONFIG, cs->RS_EXTRA_CONFIG); /*32/33*/ EMIT_STATE(RS_KICKER, 0xbeebbeeb); etna_coalesce_end(stream, &coalesce); } else { abort(); } }
static inline void etna_set_state(struct etna_cmd_stream *stream, uint32_t address, uint32_t value) { etna_cmd_stream_reserve(stream, 2); etna_emit_load_state(stream, address >> 2, 1); etna_cmd_stream_emit(stream, value); }