1 /* TSI 2023.xmo */ 2 /******************************************************************************* 3 * Copyright (c) 2023 Think Silicon Single Member PC 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * of this header file and/or associated documentation files to use, copy, 7 * modify, merge, publish, distribute, sublicense, and/or sell copies of the 8 * Materials, and to permit persons to whom the Materials are furnished to do 9 * so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Materials. 13 * 14 * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS 15 * NEMAGFX API. THE UNMODIFIED, NORMATIVE VERSIONS OF THINK-SILICON NEMAGFX 16 * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT: 17 * https://think-silicon.com/products/software/nemagfx-api 18 * 19 * The software is provided 'as is', without warranty of any kind, express or 20 * implied, including but not limited to the warranties of merchantability, 21 * fitness for a particular purpose and noninfringement. In no event shall 22 * Think Silicon Single Member PC be liable for any claim, damages or other 23 * liability, whether in an action of contract, tort or otherwise, arising 24 * from, out of or in connection with the software or the use or other dealings 25 * in the software. 26 ******************************************************************************/ 27 28 29 #ifndef NEMA_CMDLIST_H__ 30 #define NEMA_CMDLIST_H__ 31 32 #include "nema_sys_defs.h" 33 #include "nema_hal.h" 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 #define CL_NOP 0x010000U 40 #define CL_PUSH 0x020000U 41 #define CL_RETURN 0x040000U 42 #define CL_ABORT 0x080000U 43 44 #define CL_BATCH_SHIFT 12 45 #define CL_BATCH_LOOP 0x8000 46 47 #define SUBMISSION_ID_MASK 0xffffff 48 49 #define CL_ALIGNMENT_MASK (0x00000007U) // CL buffer must be 8 byte aligned 50 51 //--------------------------------------------------------------------------- 52 typedef struct nema_cmdlist_t_ { 53 nema_buffer_t bo; 54 int size; /**< Number of entries in the command list */ 55 int offset; /**< Points to the next address to write */ 56 uint32_t flags; /**< Flags */ 57 int32_t submission_id; 58 struct nema_cmdlist_t_ *next; /**< Points to next command list */ 59 struct nema_cmdlist_t_ *root; /**< Points to the head of the list */ 60 } nema_cmdlist_t; 61 62 /** \brief Create a new Command List into a preallocated space 63 * 64 * \param addr_virt Command List's address (preallocated) 65 * \param size_bytes Command List's size in bytes 66 * \return The instance of the new Command List 67 * 68 */ 69 nema_cmdlist_t nema_cl_create_prealloc(nema_buffer_t *bo); 70 71 /** \brief Create a new, non expandable Command List of specific size 72 * 73 * \param size_bytes Command List's size in bytes 74 * \return The instance of the new Command List 75 * 76 */ 77 nema_cmdlist_t nema_cl_create_sized(int size_bytes); 78 79 /** \brief Create a new expandable Command List 80 * 81 * \return The instance of the new Command List 82 * 83 */ 84 nema_cmdlist_t nema_cl_create(void); 85 86 /** \brief Destroy/Free a Command List 87 * 88 * \param cl Pointer to the Command List 89 * 90 */ 91 void nema_cl_destroy(nema_cmdlist_t *cl); 92 93 /** \brief Reset position of next command to be written to the beginning. Doesn't clear the List's contents. 94 * 95 * \param cl Pointer to the Command List 96 * 97 */ 98 void nema_cl_rewind(nema_cmdlist_t *cl); 99 100 /** \brief Define in which Command List each subsequent commands are going to be inserted. 101 * 102 * \param cl Pointer to the Command List 103 * 104 */ 105 void nema_cl_bind(nema_cmdlist_t *cl); 106 107 /** \brief Define in which Command List each subsequent commands are going to be inserted. 108 * Bind this command list as Circular. It never gets full, it never expands, 109 * it may get implicitly submitted, it cannot be reused. No other CL should be submitted 110 * while a circular CL is bound 111 * 112 * \param cl Pointer to the Command List 113 * 114 */ 115 void nema_cl_bind_circular(nema_cmdlist_t *cl); 116 117 /** \brief Unbind current bound Command List, if any. 118 * 119 * 120 */ 121 void nema_cl_unbind(void); 122 123 124 /** \brief Get bound Command List 125 * 126 * \return Pointer to the bound Command List 127 * 128 */ 129 nema_cmdlist_t *nema_cl_get_bound(void); 130 131 /** \private */ 132 void nema_cl_submit_no_irq(nema_cmdlist_t *cl); 133 134 /** \brief Enqueue Command List to the Ring Buffer for execution 135 * 136 * \param cl Pointer to the Command List 137 * 138 */ 139 void nema_cl_submit(nema_cmdlist_t *cl); 140 141 /** \brief Wait for Command List to finish 142 * 143 * \param cl Pointer to the Command List 144 * \return 0 if no error has occurred 145 * 146 */ 147 int nema_cl_wait(nema_cmdlist_t *cl); 148 149 /** \brief Add a command to the bound Command List 150 * 151 * \param reg Hardware register to be written 152 * \param data Data to be written 153 * 154 */ 155 void nema_cl_add_cmd(uint32_t reg, uint32_t data); 156 157 /** \brief Add multiple commands to the bound Command List 158 * 159 * \param cmd_no Numbers of commands to add 160 * \param cmd Pointer to the commands to be added 161 * \return 0 if no error has occurred 162 * 163 */ 164 int nema_cl_add_multiple_cmds(int cmd_no, uint32_t *cmd); 165 166 /** private */ 167 uint32_t * nema_cl_get_space(int cmd_no); 168 169 /** \brief Branch from the bound Command List to a different one. Return is implied. 170 * 171 * \param cl Pointer to the Command List to branch to 172 * 173 */ 174 void nema_cl_branch(nema_cmdlist_t *cl); 175 176 /** \brief Jump from the bound Command List to a different one. No return is implied. 177 * 178 * \param cl Pointer to the Command List to jump to 179 * 180 */ 181 void nema_cl_jump(nema_cmdlist_t *cl); 182 183 /** \brief Add an explicit return command to the bound Command List 184 * 185 * 186 */ 187 void nema_cl_return(void); 188 189 /** \brief Returns positive number if the Command List is almost full, otherwise returns 0. 190 * 191 * \param cl Pointer to the Command List 192 * 193 */ 194 int nema_cl_almost_full(nema_cmdlist_t *cl); 195 196 /** \brief Check if there is enough space or expansion can be performed for 197 * required commands. 198 * 199 * \param cmd_no Numbers of commands to be checked if they fit 200 * \reurn zero is commands fit or expansion xan be performed else return negative 201 */ 202 int nema_cl_enough_space(int cmd_no); 203 204 #ifdef __cplusplus 205 } 206 #endif 207 208 #endif 209