xref: /aosp_15_r20/external/mesa3d/src/amd/vpelib/src/core/inc/config_writer.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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