1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 3bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22bf215546Sopenharmony_ci * IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#ifndef RADV_CS_H 26bf215546Sopenharmony_ci#define RADV_CS_H 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include <assert.h> 29bf215546Sopenharmony_ci#include <stdint.h> 30bf215546Sopenharmony_ci#include <string.h> 31bf215546Sopenharmony_ci#include "radv_private.h" 32bf215546Sopenharmony_ci#include "sid.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_cistatic inline unsigned 35bf215546Sopenharmony_ciradeon_check_space(struct radeon_winsys *ws, struct radeon_cmdbuf *cs, unsigned needed) 36bf215546Sopenharmony_ci{ 37bf215546Sopenharmony_ci if (cs->max_dw - cs->cdw < needed) 38bf215546Sopenharmony_ci ws->cs_grow(cs, needed); 39bf215546Sopenharmony_ci return cs->cdw + needed; 40bf215546Sopenharmony_ci} 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cistatic inline void 43bf215546Sopenharmony_ciradeon_set_config_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num) 44bf215546Sopenharmony_ci{ 45bf215546Sopenharmony_ci assert(reg >= SI_CONFIG_REG_OFFSET && reg < SI_CONFIG_REG_END); 46bf215546Sopenharmony_ci assert(cs->cdw + 2 + num <= cs->max_dw); 47bf215546Sopenharmony_ci assert(num); 48bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_CONFIG_REG, num, 0)); 49bf215546Sopenharmony_ci radeon_emit(cs, (reg - SI_CONFIG_REG_OFFSET) >> 2); 50bf215546Sopenharmony_ci} 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_cistatic inline void 53bf215546Sopenharmony_ciradeon_set_config_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 54bf215546Sopenharmony_ci{ 55bf215546Sopenharmony_ci radeon_set_config_reg_seq(cs, reg, 1); 56bf215546Sopenharmony_ci radeon_emit(cs, value); 57bf215546Sopenharmony_ci} 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_cistatic inline void 60bf215546Sopenharmony_ciradeon_set_context_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num) 61bf215546Sopenharmony_ci{ 62bf215546Sopenharmony_ci assert(reg >= SI_CONTEXT_REG_OFFSET && reg < SI_CONTEXT_REG_END); 63bf215546Sopenharmony_ci assert(cs->cdw + 2 + num <= cs->max_dw); 64bf215546Sopenharmony_ci assert(num); 65bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, num, 0)); 66bf215546Sopenharmony_ci radeon_emit(cs, (reg - SI_CONTEXT_REG_OFFSET) >> 2); 67bf215546Sopenharmony_ci} 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_cistatic inline void 70bf215546Sopenharmony_ciradeon_set_context_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 71bf215546Sopenharmony_ci{ 72bf215546Sopenharmony_ci radeon_set_context_reg_seq(cs, reg, 1); 73bf215546Sopenharmony_ci radeon_emit(cs, value); 74bf215546Sopenharmony_ci} 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_cistatic inline void 77bf215546Sopenharmony_ciradeon_set_context_reg_idx(struct radeon_cmdbuf *cs, unsigned reg, unsigned idx, unsigned value) 78bf215546Sopenharmony_ci{ 79bf215546Sopenharmony_ci assert(reg >= SI_CONTEXT_REG_OFFSET && reg < SI_CONTEXT_REG_END); 80bf215546Sopenharmony_ci assert(cs->cdw + 3 <= cs->max_dw); 81bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, 1, 0)); 82bf215546Sopenharmony_ci radeon_emit(cs, (reg - SI_CONTEXT_REG_OFFSET) >> 2 | (idx << 28)); 83bf215546Sopenharmony_ci radeon_emit(cs, value); 84bf215546Sopenharmony_ci} 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_cistatic inline void 87bf215546Sopenharmony_ciradeon_set_context_reg_rmw(struct radeon_cmdbuf *cs, unsigned reg, unsigned value, unsigned mask) 88bf215546Sopenharmony_ci{ 89bf215546Sopenharmony_ci assert(reg >= SI_CONTEXT_REG_OFFSET && reg < SI_CONTEXT_REG_END); 90bf215546Sopenharmony_ci assert(cs->cdw + 4 <= cs->max_dw); 91bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_CONTEXT_REG_RMW, 2, 0)); 92bf215546Sopenharmony_ci radeon_emit(cs, (reg - SI_CONTEXT_REG_OFFSET) >> 2); 93bf215546Sopenharmony_ci radeon_emit(cs, mask); 94bf215546Sopenharmony_ci radeon_emit(cs, value); 95bf215546Sopenharmony_ci} 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_cistatic inline void 98bf215546Sopenharmony_ciradeon_set_sh_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num) 99bf215546Sopenharmony_ci{ 100bf215546Sopenharmony_ci assert(reg >= SI_SH_REG_OFFSET && reg < SI_SH_REG_END); 101bf215546Sopenharmony_ci assert(cs->cdw + 2 + num <= cs->max_dw); 102bf215546Sopenharmony_ci assert(num); 103bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_SH_REG, num, 0)); 104bf215546Sopenharmony_ci radeon_emit(cs, (reg - SI_SH_REG_OFFSET) >> 2); 105bf215546Sopenharmony_ci} 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_cistatic inline void 108bf215546Sopenharmony_ciradeon_set_sh_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 109bf215546Sopenharmony_ci{ 110bf215546Sopenharmony_ci radeon_set_sh_reg_seq(cs, reg, 1); 111bf215546Sopenharmony_ci radeon_emit(cs, value); 112bf215546Sopenharmony_ci} 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_cistatic inline void 115bf215546Sopenharmony_ciradeon_set_sh_reg_idx(const struct radv_physical_device *pdevice, struct radeon_cmdbuf *cs, 116bf215546Sopenharmony_ci unsigned reg, unsigned idx, unsigned value) 117bf215546Sopenharmony_ci{ 118bf215546Sopenharmony_ci assert(reg >= SI_SH_REG_OFFSET && reg < SI_SH_REG_END); 119bf215546Sopenharmony_ci assert(cs->cdw + 3 <= cs->max_dw); 120bf215546Sopenharmony_ci assert(idx); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci unsigned opcode = PKT3_SET_SH_REG_INDEX; 123bf215546Sopenharmony_ci if (pdevice->rad_info.gfx_level < GFX10) 124bf215546Sopenharmony_ci opcode = PKT3_SET_SH_REG; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci radeon_emit(cs, PKT3(opcode, 1, 0)); 127bf215546Sopenharmony_ci radeon_emit(cs, (reg - SI_SH_REG_OFFSET) >> 2 | (idx << 28)); 128bf215546Sopenharmony_ci radeon_emit(cs, value); 129bf215546Sopenharmony_ci} 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_cistatic inline void 132bf215546Sopenharmony_cigfx10_set_sh_reg_idx3(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 133bf215546Sopenharmony_ci{ 134bf215546Sopenharmony_ci assert(reg >= SI_SH_REG_OFFSET && reg < SI_SH_REG_END); 135bf215546Sopenharmony_ci assert(cs->cdw + 3 <= cs->max_dw); 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_SH_REG_INDEX, 1, 0)); 138bf215546Sopenharmony_ci radeon_emit(cs, (reg - SI_SH_REG_OFFSET) >> 2 | (3 << 28)); 139bf215546Sopenharmony_ci radeon_emit(cs, value); 140bf215546Sopenharmony_ci} 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_cistatic inline void 143bf215546Sopenharmony_ciradeon_set_uconfig_reg_seq(struct radeon_cmdbuf *cs, unsigned reg, unsigned num) 144bf215546Sopenharmony_ci{ 145bf215546Sopenharmony_ci assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END); 146bf215546Sopenharmony_ci assert(cs->cdw + 2 + num <= cs->max_dw); 147bf215546Sopenharmony_ci assert(num); 148bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, num, 0)); 149bf215546Sopenharmony_ci radeon_emit(cs, (reg - CIK_UCONFIG_REG_OFFSET) >> 2); 150bf215546Sopenharmony_ci} 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_cistatic inline void 153bf215546Sopenharmony_ciradeon_set_uconfig_reg_seq_perfctr(struct radeon_cmdbuf *cs, unsigned reg, unsigned num) 154bf215546Sopenharmony_ci{ 155bf215546Sopenharmony_ci assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END); 156bf215546Sopenharmony_ci assert(cs->cdw + 2 + num <= cs->max_dw); 157bf215546Sopenharmony_ci assert(num); 158bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, num, 1)); 159bf215546Sopenharmony_ci radeon_emit(cs, (reg - CIK_UCONFIG_REG_OFFSET) >> 2); 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_cistatic inline void 163bf215546Sopenharmony_ciradeon_set_uconfig_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 164bf215546Sopenharmony_ci{ 165bf215546Sopenharmony_ci radeon_set_uconfig_reg_seq(cs, reg, 1); 166bf215546Sopenharmony_ci radeon_emit(cs, value); 167bf215546Sopenharmony_ci} 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_cistatic inline void 170bf215546Sopenharmony_ciradeon_set_uconfig_reg_idx(const struct radv_physical_device *pdevice, struct radeon_cmdbuf *cs, 171bf215546Sopenharmony_ci unsigned reg, unsigned idx, unsigned value) 172bf215546Sopenharmony_ci{ 173bf215546Sopenharmony_ci assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END); 174bf215546Sopenharmony_ci assert(cs->cdw + 3 <= cs->max_dw); 175bf215546Sopenharmony_ci assert(idx); 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci unsigned opcode = PKT3_SET_UCONFIG_REG_INDEX; 178bf215546Sopenharmony_ci if (pdevice->rad_info.gfx_level < GFX9 || 179bf215546Sopenharmony_ci (pdevice->rad_info.gfx_level == GFX9 && pdevice->rad_info.me_fw_version < 26)) 180bf215546Sopenharmony_ci opcode = PKT3_SET_UCONFIG_REG; 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci radeon_emit(cs, PKT3(opcode, 1, 0)); 183bf215546Sopenharmony_ci radeon_emit(cs, (reg - CIK_UCONFIG_REG_OFFSET) >> 2 | (idx << 28)); 184bf215546Sopenharmony_ci radeon_emit(cs, value); 185bf215546Sopenharmony_ci} 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_cistatic inline void 188bf215546Sopenharmony_ciradeon_set_perfctr_reg(struct radv_cmd_buffer *cmd_buffer, unsigned reg, unsigned value) 189bf215546Sopenharmony_ci{ 190bf215546Sopenharmony_ci struct radeon_cmdbuf *cs = cmd_buffer->cs; 191bf215546Sopenharmony_ci assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END); 192bf215546Sopenharmony_ci assert(cs->cdw + 3 <= cs->max_dw); 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci /* 195bf215546Sopenharmony_ci * On GFX10, there is a bug with the ME implementation of its content addressable memory (CAM), 196bf215546Sopenharmony_ci * that means that it can skip register writes due to not taking correctly into account the 197bf215546Sopenharmony_ci * fields from the GRBM_GFX_INDEX. With this bit we can force the write. 198bf215546Sopenharmony_ci */ 199bf215546Sopenharmony_ci bool filter_cam_workaround = cmd_buffer->device->physical_device->rad_info.gfx_level >= GFX10 && 200bf215546Sopenharmony_ci cmd_buffer->qf == RADV_QUEUE_GENERAL; 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, 1, 0) | PKT3_RESET_FILTER_CAM(filter_cam_workaround)); 203bf215546Sopenharmony_ci radeon_emit(cs, (reg - CIK_UCONFIG_REG_OFFSET) >> 2); 204bf215546Sopenharmony_ci radeon_emit(cs, value); 205bf215546Sopenharmony_ci} 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_cistatic inline void 208bf215546Sopenharmony_ciradeon_set_privileged_config_reg(struct radeon_cmdbuf *cs, unsigned reg, unsigned value) 209bf215546Sopenharmony_ci{ 210bf215546Sopenharmony_ci assert(reg < CIK_UCONFIG_REG_OFFSET); 211bf215546Sopenharmony_ci assert(cs->cdw + 6 <= cs->max_dw); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0)); 214bf215546Sopenharmony_ci radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_IMM) | COPY_DATA_DST_SEL(COPY_DATA_PERF)); 215bf215546Sopenharmony_ci radeon_emit(cs, value); 216bf215546Sopenharmony_ci radeon_emit(cs, 0); /* unused */ 217bf215546Sopenharmony_ci radeon_emit(cs, reg >> 2); 218bf215546Sopenharmony_ci radeon_emit(cs, 0); /* unused */ 219bf215546Sopenharmony_ci} 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci#endif /* RADV_CS_H */ 222