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)); } }
static inline void etna_emit_load_state(struct etna_cmd_stream *stream, const uint16_t offset, const uint16_t count) { uint32_t v; v = (VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE | VIV_FE_LOAD_STATE_HEADER_OFFSET(offset) | (VIV_FE_LOAD_STATE_HEADER_COUNT(count) & VIV_FE_LOAD_STATE_HEADER_COUNT__MASK)); etna_cmd_stream_emit(stream, v); }
void etna_cmd_stream_reloc(struct etna_cmd_stream *stream, const struct etna_reloc *r) { struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream); struct drm_etnaviv_gem_submit_reloc *reloc; uint32_t idx = APPEND(&priv->submit, relocs); uint32_t addr = 0; reloc = &priv->submit.relocs[idx]; reloc->reloc_idx = bo2idx(stream, r->bo, r->flags); reloc->reloc_offset = r->offset; reloc->submit_offset = stream->offset * 4; /* in bytes */ reloc->flags = 0; etna_cmd_stream_emit(stream, addr); }
static void etna_coalesce_end(struct etna_cmd_stream *stream, struct etna_coalesce *coalesce) { uint32_t end = etna_cmd_stream_offset(stream); uint32_t size = end - coalesce->start; if (size) { uint32_t offset = coalesce->start - 1; uint32_t value = etna_cmd_stream_get(stream, offset); value |= VIV_FE_LOAD_STATE_HEADER_COUNT(size); etna_cmd_stream_set(stream, offset, value); } /* append needed padding */ if (end % 2 == 1) etna_cmd_stream_emit(stream, 0xdeadbeef); }
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); }
/* Queue a STALL command (queues 2 words) */ static inline void CMD_STALL(struct etna_cmd_stream *stream, uint32_t from, uint32_t to) { etna_cmd_stream_emit(stream, VIV_FE_STALL_HEADER_OP_STALL); etna_cmd_stream_emit(stream, VIV_FE_STALL_TOKEN_FROM(from) | VIV_FE_STALL_TOKEN_TO(to)); }