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 29 #if defined(LITTLEENDIAN_CPU) 30 #elif defined(BIGENDIAN_CPU) 31 #else 32 #error "BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined" 33 #endif 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 enum config_type { 40 CONFIG_TYPE_UNKNOWN, 41 CONFIG_TYPE_DIRECT, 42 CONFIG_TYPE_INDIRECT 43 }; 44 45 typedef void (*config_callback_t)( 46 void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size); 47 48 #define MAX_CONFIG_PACKET_DATA_SIZE_DWORD 0x01000 49 50 struct vpep_direct_config_packet { 51 union { 52 struct { 53 #if defined(LITTLEENDIAN_CPU) 54 uint32_t INC : 1; 55 uint32_t : 1; 56 uint32_t VPEP_CONFIG_REGISTER_OFFSET : 18; 57 uint32_t VPEP_CONFIG_DATA_SIZE : 12; 58 #elif defined(BIGENDIAN_CPU) 59 uint32_t VPEP_CONFIG_DATA_SIZE : 12; 60 uint32_t VPEP_CONFIG_REGISTER_OFFSET : 18; 61 uint32_t : 1; 62 uint32_t INC : 1; 63 #endif 64 } bitfields, bits; 65 uint32_t u32all; 66 }; 67 uint32_t data[1]; 68 }; 69 70 /* config writer only help initialize the 1st DWORD, 71 * and 'close' the config (i.e. finalize the size) once it is completed. 72 * it doesn't help generate the content, which shall be prepared by the caller 73 * and then call config_writer_fill() 74 */ 75 struct config_writer { 76 struct vpe_buf *buf; /**< store the current buf pointer */ 77 78 /* store the base addr of the currnet config 79 * i.e. config header 80 * it is always constructed in emb_buf 81 */ 82 uint64_t base_gpu_va; 83 uint64_t base_cpu_va; 84 85 enum config_type type; 86 bool completed; 87 88 void *callback_ctx; 89 config_callback_t callback; 90 enum vpe_status status; 91 }; 92 93 /** initialize the config writer. 94 * Calls right before building any VPEP configs 95 * 96 * /param writer writer instance 97 * /param emb_buf points to the current cmd_buf, 98 * each config_writer_fill will update the address 99 */ 100 void config_writer_init(struct config_writer *writer, struct vpe_buf *emb_buf); 101 102 /** set the callback function (can be null) for notifying any config completion 103 * In the callback, caller can: 104 * 1. save the config for later reuse 105 * 2. write it to vpe descriptor 106 */ 107 void config_writer_set_callback( 108 struct config_writer *writer, void *callback_ctx, config_callback_t callback); 109 110 /** set the config type before config_writer_fill() 111 * if the config_type has changed, it will finalize the current one, 112 * 1) direct config 113 * VPEP_DIRECT_CONFIG_ARRAY_SIZE is finalized (in DW0) automatically. 114 * 2) indirect config 115 * NUM_DST is finalized (in DW0) automatically. 116 * and run callback (if set) to notify the completion. 117 * A new config desc header DW0 will be generated. 118 * 119 * /param writer writer instance 120 * /param type config type 121 */ 122 void config_writer_set_type(struct config_writer *writer, enum config_type type); 123 124 /** force create new config with specific type 125 * if the config is empty, only type will be changed, otherwise create new one 126 * 1) direct config 127 * VPEP_DIRECT_CONFIG_ARRAY_SIZE is finalized (in DW0) automatically. 128 * 2) indirect config 129 * NUM_DST is finalized (in DW0) automatically. 130 * and run callback (if set) to notify the completion. 131 * A new config desc header DW0 will be generated. 132 * 133 * /param writer writer instance 134 * /param type config type 135 */ 136 void config_writer_force_new_with_type(struct config_writer *writer, enum config_type type); 137 138 /** fill the value to the buffer. 139 * If the dword exceeds the config packet size limit, 140 * callback will be called and a new config desc is created. 141 * 142 * /param writer writer instance 143 * /param value fill the DW to the config desc body 144 */ 145 void config_writer_fill(struct config_writer *writer, uint32_t value); 146 147 /** fill the header value to the buffer. 148 * If the current size + number of dwords in the array 149 * exceeds the config packet size limit, 150 * callback will be called and a new config desc is created. 151 * 152 * /param writer writer instance 153 * /param packet config packet with header filled properly 154 */ 155 void config_writer_fill_direct_config_packet_header( 156 struct config_writer *writer, struct vpep_direct_config_packet *packet); 157 158 /** fill the header and data value to the buffer. 159 * For single DATA element ONLY. 160 * If the current size + number of dwords in the array 161 * exceeds the config packet size limit, 162 * callback will be called and a new config desc is created. 163 * 164 * /param writer writer instance 165 * /param packet config packet with valid header and data 166 */ 167 void config_writer_fill_direct_config_packet( 168 struct config_writer *writer, struct vpep_direct_config_packet *packet); 169 170 void config_writer_fill_indirect_data_array( 171 struct config_writer *writer, const uint64_t data_gpuva, uint32_t size); 172 173 void config_writer_fill_indirect_destination(struct config_writer *writer, 174 const uint32_t offset_index, const uint32_t start_index, const uint32_t offset_data); 175 176 /** explicitly complete the config */ 177 void config_writer_complete(struct config_writer *writer); 178 179 #ifdef __cplusplus 180 } 181 #endif 182