1 /* Copyright 2022 Advanced Micro Devices, Inc. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a 4 * copy of this software and associated documentation files (the "Software"), 5 * to deal in the Software without restriction, including without limitation 6 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 * and/or sell copies of the Software, and to permit persons to whom the 8 * Software is furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 17 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 19 * OTHER DEALINGS IN THE SOFTWARE. 20 * 21 * Authors: AMD 22 * 23 */ 24 25 #pragma once 26 27 #include "vpe_types.h" 28 #include "hw_shared.h" 29 30 #if defined(LITTLEENDIAN_CPU) 31 #elif defined(BIGENDIAN_CPU) 32 #else 33 #error "BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined" 34 #endif 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 enum config_type { 41 CONFIG_TYPE_UNKNOWN, 42 CONFIG_TYPE_DIRECT, 43 CONFIG_TYPE_INDIRECT 44 }; 45 46 typedef void (*config_callback_t)( 47 void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size, uint32_t pipe_idx); 48 49 #define MAX_CONFIG_PACKET_DATA_SIZE_DWORD 0x01000 50 51 struct vpep_direct_config_packet { 52 union { 53 struct { 54 #if defined(LITTLEENDIAN_CPU) 55 uint32_t INC : 1; 56 uint32_t : 1; 57 uint32_t VPEP_CONFIG_REGISTER_OFFSET : 18; 58 uint32_t VPEP_CONFIG_DATA_SIZE : 12; 59 #elif defined(BIGENDIAN_CPU) 60 uint32_t VPEP_CONFIG_DATA_SIZE : 12; 61 uint32_t VPEP_CONFIG_REGISTER_OFFSET : 18; 62 uint32_t : 1; 63 uint32_t INC : 1; 64 #endif 65 } bitfields, bits; 66 uint32_t u32all; 67 }; 68 uint32_t data[1]; 69 }; 70 71 /* config writer only help initialize the 1st DWORD, 72 * and 'close' the config (i.e. finalize the size) once it is completed. 73 * it doesn't help generate the content, which shall be prepared by the caller 74 * and then call config_writer_fill() 75 */ 76 struct config_writer { 77 struct vpe_buf *buf; /**< store the current buf pointer */ 78 79 /* store the base addr of the current config 80 * i.e. config header 81 * it is always constructed in emb_buf 82 */ 83 uint64_t base_gpu_va; 84 uint64_t base_cpu_va; 85 uint16_t gpu_addr_alignment; 86 uint32_t pipe_idx; 87 88 enum config_type type; 89 bool completed; 90 91 void *callback_ctx; 92 config_callback_t callback; 93 enum vpe_status status; 94 }; 95 96 /** initialize the config writer. 97 * Calls right before building any VPEP configs 98 * 99 * /param writer writer instance 100 * /param emb_buf points to the current cmd_buf, 101 * each config_writer_fill will update the address 102 */ 103 void config_writer_init(struct config_writer *writer, struct vpe_buf *emb_buf); 104 105 /** set the callback function (can be null) for notifying any config completion 106 * In the callback, caller can: 107 * 1. save the config for later reuse 108 * 2. write it to vpe descriptor 109 */ 110 void config_writer_set_callback( 111 struct config_writer *writer, void *callback_ctx, config_callback_t callback); 112 113 /** set the config type before config_writer_fill() 114 * if the config_type has changed, it will finalize the current one, 115 * 1) direct config 116 * VPEP_DIRECT_CONFIG_ARRAY_SIZE is finalized (in DW0) automatically. 117 * 2) indirect config 118 * NUM_DST is finalized (in DW0) automatically. 119 * and run callback (if set) to notify the completion. 120 * A new config desc header DW0 will be generated. 121 * 122 * /param writer writer instance 123 * /param type config type 124 */ 125 void config_writer_set_type(struct config_writer *writer, enum config_type type, uint32_t pipe_idx); 126 127 /** force create new config with specific type 128 * if the config is empty, only type will be changed, otherwise create new one 129 * 1) direct config 130 * VPEP_DIRECT_CONFIG_ARRAY_SIZE is finalized (in DW0) automatically. 131 * 2) indirect config 132 * NUM_DST is finalized (in DW0) automatically. 133 * and run callback (if set) to notify the completion. 134 * A new config desc header DW0 will be generated. 135 * 136 * /param writer writer instance 137 * /param type config type 138 * /param pipe_idx pipe instance 139 */ 140 void config_writer_force_new_with_type(struct config_writer *writer, enum config_type type); 141 142 /** fill the value to the buffer. 143 * If the dword exceeds the config packet size limit, 144 * callback will be called and a new config desc is created. 145 * 146 * /param writer writer instance 147 * /param value fill the DW to the config desc body 148 */ 149 void config_writer_fill(struct config_writer *writer, uint32_t value); 150 151 /** fill the header value to the buffer. 152 * If the current size + number of dwords in the array 153 * exceeds the config packet size limit, 154 * callback will be called and a new config desc is created. 155 * 156 * /param writer writer instance 157 * /param packet config packet with header filled properly 158 */ 159 void config_writer_fill_direct_config_packet_header( 160 struct config_writer *writer, struct vpep_direct_config_packet *packet); 161 162 /** fill the header and data value to the buffer. 163 * For single DATA element ONLY. 164 * If the current size + number of dwords in the array 165 * exceeds the config packet size limit, 166 * callback will be called and a new config desc is created. 167 * 168 * /param writer writer instance 169 * /param packet config packet with valid header and data 170 */ 171 void config_writer_fill_direct_config_packet( 172 struct config_writer *writer, struct vpep_direct_config_packet *packet); 173 174 void config_writer_fill_indirect_data_array( 175 struct config_writer *writer, const uint64_t data_gpuva, uint32_t size); 176 177 void config_writer_fill_indirect_destination(struct config_writer *writer, 178 const uint32_t offset_index, const uint32_t start_index, const uint32_t offset_data); 179 180 /** explicitly complete the config */ 181 void config_writer_complete(struct config_writer *writer); 182 183 #ifdef __cplusplus 184 } 185 #endif 186