• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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