1 /*
2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3  * Copyright (c) Imagination Technologies Limited, UK
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Waldo Bastian <waldo.bastian@intel.com>
27  *
28  */
29 
30 #ifndef _PSB_CMDBUF_H_
31 #define _PSB_CMDBUF_H_
32 
33 #include "psb_drv_video.h"
34 #include "psb_buffer.h"
35 //#include "xf86mm.h"
36 #include "hwdefs/dxva_fw_ctrl.h"
37 #include "hwdefs/lldma_defs.h"
38 
39 #include <stdint.h>
40 
41 
42 #ifdef ANDROID
43 #define Bool int
44 #endif
45 
46 
47 typedef struct psb_cmdbuf_s *psb_cmdbuf_p;
48 
49 struct psb_cmdbuf_s {
50     struct psb_buffer_s buf;
51     unsigned int size;
52     struct psb_buffer_s reloc_buf;
53     unsigned int reloc_size;
54 
55     struct psb_buffer_s regio_buf;
56     unsigned int regio_size;
57     unsigned char * regio_base;
58     uint32_t *regio_idx;
59 
60     /* MTX msg */
61     unsigned char *MTX_msg;
62     /* Relocation records */
63     unsigned char *reloc_base;
64     struct drm_psb_reloc *reloc_idx;
65 
66     /* CMD stream data */
67     int cmd_count;
68     int deblock_count;
69 #ifdef SLICE_HEADER_PARSING
70     int parse_count;
71     int decode_flag;
72 #endif
73     int oold_count;
74     int host_be_opp_count;
75     int frame_info_count;
76     unsigned char *cmd_base;
77     unsigned char *cmd_start;
78     uint32_t *cmd_idx;
79     uint32_t *cmd_bitstream_size; /* Pointer to bitstream size field in last SR_SETUP */
80     /* LLDMA records */
81     unsigned char *lldma_base;
82     unsigned char *lldma_idx;
83     unsigned char *lldma_last; /* Pointer to last LLDMA record */
84 
85     /* Referenced buffers */
86     psb_buffer_p *buffer_refs;
87 
88     int buffer_refs_count;
89     int buffer_refs_allocated;
90     /* Pointer for Register commands */
91     uint32_t *reg_start;
92     uint32_t *reg_wt_p;
93     uint32_t reg_next;
94     uint32_t reg_flags;
95     /* Pointer for Rendec Block commands */
96     uint32_t *rendec_block_start;
97     uint32_t *rendec_chunk_start;
98     /* Pointer for Segment commands */
99     uint32_t *last_next_segment_cmd;
100     uint32_t first_segment_size;
101     /* Pointer for Skip block commands */
102     uint32_t *skip_block_start;
103     uint32_t skip_condition;
104 };
105 
106 /*
107  * Create command buffer
108  */
109 VAStatus psb_cmdbuf_create(
110     object_context_p obj_context,
111     psb_driver_data_p driver_data,
112     psb_cmdbuf_p cmdbuf);
113 
114 /*
115  * Destroy buffer
116  */
117 void psb_cmdbuf_destroy(psb_cmdbuf_p cmdbuf);
118 
119 /*
120  * Reset buffer & map
121  *
122  * Returns 0 on success
123  */
124 int psb_cmdbuf_reset(psb_cmdbuf_p cmdbuf);
125 
126 /*
127  * Unmap buffer
128  *
129  * Returns 0 on success
130  */
131 int psb_cmdbuf_unmap(psb_cmdbuf_p cmdbuf);
132 
133 /*
134  * Reference an addtional buffer "buf" in the command stream
135  * Returns a reference index that can be used to refer to "buf" in
136  * relocation records, on error -1 is returned.
137  */
138 int psb_cmdbuf_buffer_ref(psb_cmdbuf_p cmdbuf, psb_buffer_p buf);
139 
140 /* Creates a relocation record for a DWORD in the mapped "cmdbuf" at address
141  * "addr_in_cmdbuf"
142  * The relocation is based on the device virtual address of "ref_buffer"
143  * "buf_offset" is be added to the device virtual address, and the sum is then
144  * right shifted with "align_shift".
145  * "mask" determines which bits of the target DWORD will be updated with the so
146  * constructed address. The remaining bits will be filled with bits from "background".
147  */
148 void psb_cmdbuf_add_relocation(psb_cmdbuf_p cmdbuf,
149                                uint32_t *addr_in_cmdbuf,
150                                psb_buffer_p ref_buffer,
151                                uint32_t buf_offset,
152                                uint32_t mask,
153                                uint32_t background,
154                                uint32_t align_shift,
155                                uint32_t dst_buffer);
156 
157 #define RELOC(dest, offset, buf)        psb_cmdbuf_add_relocation(cmdbuf, (uint32_t*) &dest, buf, offset, 0XFFFFFFFF, 0, 0, 1)
158 #define RELOC_MSG(dest, offset, buf)    psb_cmdbuf_add_relocation(cmdbuf, (uint32_t*) &dest, buf, offset, 0XFFFFFFFF, 0, 0, 0)
159 #define RELOC_SHIFT4(dest, offset, background, buf)     psb_cmdbuf_add_relocation(cmdbuf, (uint32_t*) &dest, buf, offset, 0X0FFFFFFF, background, 4, 1)
160 #define RELOC_REGIO(dest, offset, buf, dst)     psb_cmdbuf_add_relocation(cmdbuf, (uint32_t*) &dest, buf, offset, 0XFFFFFFFF, 0, 0, dst)
161 
162 /*
163  * Advances "obj_context" to the next cmdbuf
164  *
165  * Returns 0 on success
166  */
167 int psb_context_get_next_cmdbuf(object_context_p obj_context);
168 
169 int psb_context_submit_deblock(object_context_p obj_context);
170 
171 int psb_context_submit_oold(object_context_p obj_context,
172                             psb_buffer_p src_buf,
173                             psb_buffer_p dst_buf,
174                             psb_buffer_p colocate_buffer,
175                             uint32_t picture_width_in_mb,
176                             uint32_t frame_height_in_mb,
177                             uint32_t field_type,
178                             uint32_t chroma_offset);
179 
180 int psb_context_submit_host_be_opp(object_context_p obj_context,
181                                   psb_buffer_p buf_a,
182                                   psb_buffer_p buf_b,
183                                   psb_buffer_p buf_c,
184                                   uint32_t picture_widht_mb,
185                                   uint32_t frame_height_mb,
186                                   uint32_t rotation_flags,
187                                   uint32_t field_type,
188                                   uint32_t ext_stride_a,
189                                   uint32_t chroma_offset_a,
190                                   uint32_t chroma_offset_b);
191 
192 int psb_context_submit_hw_deblock(object_context_p obj_context,
193                                   psb_buffer_p buf_a,
194                                   psb_buffer_p buf_b,
195                                   psb_buffer_p colocate_buffer,
196                                   uint32_t picture_widht_mb,
197                                   uint32_t frame_height_mb,
198                                   uint32_t rotation_flags,
199                                   uint32_t field_type,
200                                   uint32_t ext_stride_a,
201                                   uint32_t chroma_offset_a,
202                                   uint32_t chroma_offset_b,
203                                   uint32_t is_oold);
204 
205 int psb_context_submit_hw_deblock(object_context_p obj_context,
206                                   psb_buffer_p buf_a,
207                                   psb_buffer_p buf_b,
208                                   psb_buffer_p colocate_buffer,
209                                   uint32_t picture_widht_mb,
210                                   uint32_t frame_height_mb,
211                                   uint32_t rotation_flags,
212                                   uint32_t field_type,
213                                   uint32_t ext_stride_a,
214                                   uint32_t chroma_offset_a,
215                                   uint32_t chroma_offset_b,
216                                   uint32_t is_oold);
217 
218 /*
219  * Submits the current cmdbuf
220  *
221  * Returns 0 on success
222  */
223 int psb_context_submit_cmdbuf(object_context_p obj_context);
224 
225 /*
226  * Flushes the pending cmdbuf
227  *
228  * Return 0 on success
229  */
230 int psb_context_flush_cmdbuf(object_context_p obj_context);
231 void psb_cmdbuf_skip_start_block(psb_cmdbuf_p cmdbuf, uint32_t skip_condition);
232 
233 /*
234  * Write a SR_SETUP_CMD referencing a bitstream buffer to the command buffer
235  *
236  * The slice data runs from buffer_offset_in_bytes to buffer_offset_in_bytes + size_in_bytes
237  * The first bit to be processed is buffer_offset_in_bytes + offset_in_bits
238  *
239  * TODO: Return something
240  */
241 
242 void psb_cmdbuf_dma_write_bitstream(psb_cmdbuf_p cmdbuf,
243                                       psb_buffer_p bitstream_buf,
244                                       uint32_t buffer_offset,
245                                       uint32_t size_in_bytes,
246                                       uint32_t offset_in_bits,
247                                       uint32_t flags);
248 
249 void psb_cmdbuf_dma_write_cmdbuf(psb_cmdbuf_p cmdbuf,
250     psb_buffer_p bitstream_buf,
251     uint32_t buffer_offset,
252     uint32_t size,
253     uint32_t dest_offset,
254     DMA_TYPE type);
255 
256 #ifdef SLICE_HEADER_PARSING
257 void psb_cmdbuf_dma_write_key(psb_cmdbuf_p cmdbuf,
258                                       uint32_t flags,
259                                       uint32_t key);
260 #endif
261 /*
262  * Create a command to set registers
263  */
264 void psb_cmdbuf_reg_start_block(psb_cmdbuf_p cmdbuf, uint32_t flags);
265 
266 void psb_cmdbuf_reg_set(psb_cmdbuf_p cmdbuf, uint32_t reg, uint32_t val);
267 
268 #define psb_cmdbuf_reg_set_RELOC( cmdbuf, reg, buffer,buffer_offset)             \
269     do { *cmdbuf->cmd_idx++ = reg; RELOC(*cmdbuf->cmd_idx++, buffer_offset, buffer); } while (0)
270 
271 void psb_cmdbuf_reg_set_address(psb_cmdbuf_p cmdbuf,
272                                 uint32_t reg,
273                                 psb_buffer_p buffer,
274                                 uint32_t buffer_offset);
275 
276 /*
277  * Finish a command to set registers
278  */
279 void psb_cmdbuf_reg_end_block(psb_cmdbuf_p cmdbuf);
280 
281 /*
282  * Create a RENDEC command block
283  */
284 void psb_cmdbuf_rendec_start(psb_cmdbuf_p cmdbuf, uint32_t dest_address);
285 
286 #define psb_cmdbuf_rendec_write( cmdbuf, val ) \
287     do { *cmdbuf->cmd_idx++ = val; } while(0)
288 
289 void psb_cmdbuf_rendec_write_block(psb_cmdbuf_p cmdbuf,
290                                    unsigned char *block,
291                                    uint32_t size);
292 
293 void psb_cmdbuf_rendec_write_address(psb_cmdbuf_p cmdbuf,
294                                      psb_buffer_p buffer,
295                                      uint32_t buffer_offset);
296 
297 typedef enum {
298     SKIP_ON_CONTEXT_SWITCH = 1,
299 } E_SKIP_CONDITION;
300 
301 /*
302  * Create a conditional SKIP block
303  */
304 void psb_cmdbuf_skip_start_block(psb_cmdbuf_p cmdbuf, uint32_t skip_condition);
305 
306 /*
307  * Terminate a conditional SKIP block
308  */
309 void psb_cmdbuf_skip_end_block(psb_cmdbuf_p cmdbuf);
310 
311 /*
312  * Terminate a conditional SKIP block
313  */
314 void psb_cmdbuf_rendec_end(psb_cmdbuf_p cmdbuf);
315 /*
316  * Write RegIO record into buffer
317  */
318 int psb_cmdbuf_second_pass(object_context_p obj_context,
319                            uint32_t OperatingModeCmd,
320                            unsigned char * pvParamBase,
321                            uint32_t PicWidthInMbs,
322                            uint32_t FrameHeightInMbs,
323                            psb_buffer_p target_buffer,
324                            uint32_t chroma_offset
325                           );
326 
327 void *psb_cmdbuf_alloc_space(psb_cmdbuf_p cmdbuf, uint32_t byte_size);
328 
329 void psb_cmdbuf_dma_write_bitstream_chained(psb_cmdbuf_p cmdbuf,
330         psb_buffer_p bitstream_buf,
331         uint32_t size_in_bytes);
332 
333 #endif /* _PSB_CMDBUF_H_ */
334