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 * Zeng Li <zeng.li@intel.com>
27 *
28 */
29
30 #include "psb_cmdbuf.h"
31
32 #include <unistd.h>
33 #include <stdio.h>
34
35 #include "hwdefs/mem_io.h"
36 #include "hwdefs/msvdx_offsets.h"
37 #include "hwdefs/reg_io2.h"
38 #include "hwdefs/msvdx_vec_reg_io2.h"
39 #include "hwdefs/msvdx_vdmc_reg_io2.h"
40 #include "hwdefs/msvdx_mtx_reg_io2.h"
41 #include "hwdefs/msvdx_dmac_linked_list.h"
42 #include "hwdefs/msvdx_rendec_mtx_slice_cntrl_reg_io2.h"
43 #include "hwdefs/msvdx_core_regs_io2.h"
44 #include "hwdefs/h264_macroblock_mem_io.h"
45 #include "hwdefs/dxva_cmdseq_msg.h"
46 #include "hwdefs/dxva_fw_ctrl.h"
47 #include "hwdefs/fwrk_msg_mem_io.h"
48 #include "hwdefs/dxva_msg.h"
49 #include "hwdefs/msvdx_cmds_io2.h"
50 #include <stdlib.h>
51 #include <errno.h>
52 #include <string.h>
53
54 #include "psb_def.h"
55 #include "psb_drv_debug.h"
56
57 #define H264_MACROBLOCK_DATA_SIZE 0x80
58
59 #define MSVDX_CMDS_BASE 0x1000
60 #define MSVDX_CORE_BASE 0x600
61 #define MSVDX_VEC_BASE 0x800
62
63 #define MSVDX_DEBLOCK_REG_SET 0x10000000
64 #define MSVDX_DEBLOCK_REG_GET 0x20000000
65 #define MSVDX_DEBLOCK_REG_POLLn 0x30000000
66 #define MSVDX_DEBLOCK_REG_POLLx 0x40000000
67
68 static int reg_set_count = 0;
69 static int reg_get_count = 0;
70 static int reg_poll_x = 0;
71 static int reg_poll_n = 0;
72
73 #define psb_deblock_reg_set(group, reg, value) \
74 *cmdbuf->regio_idx++ = (group##_##reg##_##OFFSET + group##_##BASE) | MSVDX_DEBLOCK_REG_SET; \
75 *cmdbuf->regio_idx++ = value; reg_set_count++;
76
77 #define psb_deblock_reg_set_RELOC( group, reg, buffer, buffer_offset, dst) \
78 *cmdbuf->regio_idx++ = (group##_##reg##_##OFFSET + group##_##BASE) | MSVDX_DEBLOCK_REG_SET; \
79 RELOC_REGIO(*cmdbuf->regio_idx++, buffer_offset, buffer, dst); reg_set_count++;
80
81 #define psb_deblock_reg_table_set(group, reg, index, value) \
82 *cmdbuf->regio_idx++ = ( (group##_##reg##_OFFSET + group##_##BASE + index*group##_##reg##_STRIDE) | MSVDX_DEBLOCK_REG_SET); \
83 *cmdbuf->regio_idx++ = value; reg_set_count++;
84
85 #define psb_deblock_reg_get(group, reg) \
86 *cmdbuf->regio_idx++ = (group##_##reg##_##OFFSET + group##_##BASE) | MSVDX_DEBLOCK_REG_GET; reg_get_count++;
87
88 #if 1
89 #define h264_pollForSpaceForNCommands(NumCommands)\
90 *cmdbuf->regio_idx++ = (MSVDX_CORE_CR_MSVDX_COMMAND_SPACE_OFFSET + MSVDX_CORE_BASE) | MSVDX_DEBLOCK_REG_POLLn; \
91 *cmdbuf->regio_idx++ = NumCommands; reg_poll_n++;
92 #else
93 #define h264_pollForSpaceForNCommands(NumCommands) /* Seems not needed, so just define it null */
94 #endif
95
96 #define PollForSpaceForXCommands \
97 *cmdbuf->regio_idx++ = (MSVDX_CORE_CR_MSVDX_COMMAND_SPACE_OFFSET + MSVDX_CORE_BASE) | MSVDX_DEBLOCK_REG_POLLx; reg_poll_x++;
98
99 typedef enum {
100 H264_BLOCKSIZE_16X16 = 0, /* 1 block */
101 H264_BLOCKSIZE_16X8 = 1, /* 2 blocks */
102 H264_BLOCKSIZE_8X16 = 2,
103 H264_BLOCKSIZE_8X8 = 3, /* 4 blocks */
104 H264_BLOCKSIZE_8X4 = 4,
105 H264_BLOCKSIZE_4X8 = 5,
106 H264_BLOCKSIZE_4X4 = 6
107
108 } h264_eBlockSize;
109
110 static uint32_t BlockDownsizeMap[] = {
111 1, 1, 3, 3, 3, 5, 5
112 };
113
114 static uint32_t BlocksToSendMap[] = {
115 1, 2, 2, 4, 4, 4, 4
116 };
117
118 static uint32_t BlockAddressMap[7][4] = {
119 { 0 }, /* 16x16 */
120 { 0, 2 }, /* 16x8 */
121 { 0, 1 }, /* 8x16 */
122 { 0, 1, 2, 3 }, /* 8x8 */
123 { 0, 1, 2, 3 }, /* 8x4 */
124 { 0, 1, 2, 3 }, /* 4x8 */
125 { 0, 1, 2, 3 } /* 4x4 */
126 };
127
128 static uint32_t VectorsToSendMap[] = {
129 1, 1, 1, 1, 2, 2, 4
130 };
131
132 static uint32_t VectorOffsetMap[7][4] = {
133 { 0 }, /* 16x16 */
134 { 0 }, /* 16x8 */
135 { 0 }, /* 8x16 */
136 { 0 }, /* 8x8 */
137 { 0, 2 }, /* 8x4 */
138 { 0, 1 }, /* 4x8 */
139 { 0, 1, 2, 3 } /* 4x4 */
140 };
141
142
143 static uint32_t Above1AboveTileMap[] = {
144 /* 9, 12, 8, 13 */
145 13, 12, 9, 8
146 };
147
148 static uint32_t CurrentAboveTileMap[] = {
149 /* 11, 14, 10, 15 */
150 15, 14, 11, 10
151 };
152
153 static uint32_t CurrentColTileMap[] = {
154 10, 15, 0, 5, 8, 13, 2, 7, 1, 4, 3, 6, 9, 12
155 };
156
157
158 static uint32_t ColBlockMap[] = {
159 2, 3, 0, 1
160 };
161
162 void
h264_above1InterBlockSequence(psb_cmdbuf_p cmdbuf,uint8_t * MbData)163 h264_above1InterBlockSequence(psb_cmdbuf_p cmdbuf, uint8_t* MbData)
164 {
165 uint32_t i, BlockNum, Mv, MvAddr, Value;
166 uint32_t Block8x8, blockType;
167 uint32_t InterBlockCmd;
168 uint32_t MotionVecCmd[16];
169 uint32_t BlockType[4] = {0};
170 uint32_t DpbIdx[4];
171
172 /* set MV vars to 0 */
173 for (i = 0; i < 16; i++) {
174 MotionVecCmd[i] = 0;
175 }
176
177 /* Read the size of blocks 2 and 3 and resize them so they are all ?x8 */
178 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK2_PREDICTION_SIZE);
179 if (Value > (sizeof(BlockDownsizeMap) / sizeof(uint32_t) - 1))
180 Value = sizeof(BlockDownsizeMap) / sizeof(uint32_t) - 1;
181 BlockType[2] = BlockDownsizeMap[Value];
182 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK3_PREDICTION_SIZE);
183 if (Value > (sizeof(BlockDownsizeMap) / sizeof(uint32_t) - 1))
184 Value = sizeof(BlockDownsizeMap) / sizeof(uint32_t) - 1;
185 BlockType[3] = BlockDownsizeMap[Value];
186
187 /* read motion vectors for the bottom row, but store them in the correct locn. for ?x8 blocks */
188 for (i = 0; i < 4; i++) {
189 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_X_ABOVE, i);
190 REGIO_WRITE_FIELD(MotionVecCmd[Above1AboveTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_X, Value);
191 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_Y_ABOVE, i);
192 REGIO_WRITE_FIELD(MotionVecCmd[Above1AboveTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_Y, Value);
193 }
194
195 /* read DPB index for blocks 2 and 3 */
196 for (i = 0; i < 2; i++) {
197 DpbIdx[ColBlockMap[i]] = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_DPB_IDX_COL, i);
198 }
199
200 /* Send commands required blocks */
201 for (BlockNum = BlocksToSendMap[BlockType[2]] / 2;
202 BlockNum < BlocksToSendMap[BlockType[2]];
203 BlockNum++) {
204 /* block address */
205 Block8x8 = BlockAddressMap[BlockType[2]][BlockNum];
206 /* block type */
207 blockType = BlockType[Block8x8];
208
209 InterBlockCmd = 0;
210 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, INTER_PRED_BLOCK_SIZE, blockType);
211 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, REF_INDEX_A_VALID, 1);
212 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, REF_INDEX_A, DpbIdx[Block8x8]);
213
214 /* send commands */
215 h264_pollForSpaceForNCommands(1 + VectorsToSendMap[blockType]);
216 psb_deblock_reg_table_set(MSVDX_CMDS, INTER_BLOCK_PREDICTION_ABOVE1, Block8x8, InterBlockCmd);
217
218 for (i = 0; i < VectorsToSendMap[blockType]; i++) {
219 /* only send forward MVs in baseline */
220 MvAddr = (2 * 4 * Block8x8) + VectorOffsetMap[blockType][i];
221 Mv = (4 * Block8x8) + VectorOffsetMap[blockType][i];
222 psb_deblock_reg_table_set(MSVDX_CMDS, MOTION_VECTOR_ABOVE1, MvAddr, MotionVecCmd[Mv]);
223 }
224 }
225 }
226
227 void
h264_currentInterBlockSequence(psb_cmdbuf_p cmdbuf,uint8_t * MbData)228 h264_currentInterBlockSequence(psb_cmdbuf_p cmdbuf, uint8_t * MbData)
229 {
230 uint32_t i, BlockNum, Mv, MvAddr, Value;
231 uint32_t Block8x8, blockType;
232 uint32_t InterBlockCmd;
233 uint32_t MotionVecCmd[16];
234 uint32_t BlockType[4];
235 uint32_t DpbIdx[4];
236
237 /* set MV vars to 0 */
238 for (i = 0; i < 16; i++) {
239 MotionVecCmd[i] = 0;
240 }
241
242 /* read block size */
243 BlockType[0] = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK0_PREDICTION_SIZE);
244 BlockType[1] = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK1_PREDICTION_SIZE);
245 BlockType[2] = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK2_PREDICTION_SIZE);
246 BlockType[3] = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_BLOCK3_PREDICTION_SIZE);
247
248 /* read motion vectors in all 16 4x4 sub-blocks*/
249 for (i = 1; i < 3; i++) { /* get blocks 11 and 14 */
250 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_X_ABOVE, i);
251 REGIO_WRITE_FIELD(MotionVecCmd[CurrentAboveTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_X, Value);
252 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_Y_ABOVE, i);
253 REGIO_WRITE_FIELD(MotionVecCmd[CurrentAboveTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_Y, Value);
254 }
255 for (i = 0; i < 14; i++) {
256 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_X_COL, i);
257 REGIO_WRITE_FIELD(MotionVecCmd[CurrentColTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_X, Value);
258 Value = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COMP_Y_COL, i);
259 REGIO_WRITE_FIELD(MotionVecCmd[CurrentColTileMap[i]], MSVDX_CMDS, MOTION_VECTOR, MV_Y, Value);
260 }
261
262 /* read DPB index for all 4 blocks */
263 for (i = 0; i < 4; i++) {
264 DpbIdx[ColBlockMap[i]] = MEMIO_READ_TABLE_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_DPB_IDX_COL, i);
265 }
266
267 /* Send commands required blocks */
268 for (BlockNum = 0;
269 BlockNum < BlocksToSendMap[BlockType[0]];
270 BlockNum++) {
271 /* block address */
272 Block8x8 = BlockAddressMap[BlockType[0]][BlockNum];
273 /* block type */
274 blockType = BlockType[Block8x8];
275
276 InterBlockCmd = 0;
277 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, INTER_PRED_BLOCK_SIZE, blockType);
278 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, REF_INDEX_A_VALID, 1);
279 REGIO_WRITE_FIELD(InterBlockCmd, MSVDX_CMDS, INTER_BLOCK_PREDICTION, REF_INDEX_A, DpbIdx[Block8x8]);
280
281 /* send commands */
282 h264_pollForSpaceForNCommands(1 + VectorsToSendMap[blockType]);
283 psb_deblock_reg_table_set(MSVDX_CMDS, INTER_BLOCK_PREDICTION, Block8x8, InterBlockCmd);
284
285 for (i = 0; i < VectorsToSendMap[blockType]; i++) {
286 /* only send forward MVs in baseline */
287 MvAddr = (2 * 4 * Block8x8) + VectorOffsetMap[blockType][i];
288 Mv = (4 * Block8x8) + VectorOffsetMap[blockType][i];
289 psb_deblock_reg_table_set(MSVDX_CMDS, MOTION_VECTOR, MvAddr, MotionVecCmd[Mv]);
290 }
291 }
292 }
293
294 void
h264_currentIntraBlockPrediction(psb_cmdbuf_p cmdbuf,uint8_t * MbData,int bMbIsIPCM)295 h264_currentIntraBlockPrediction(psb_cmdbuf_p cmdbuf, uint8_t * MbData, int bMbIsIPCM)
296 {
297 uint32_t BlockSizeY, BlockSizeC;
298 uint32_t IntraCmdY, IntraCmdC;
299
300 /* select block size I_PCM or I_16x16 */
301 BlockSizeY = (1 == bMbIsIPCM) ? 3 : 0;
302 /* select block size I_PCM or I_8x8 */
303 BlockSizeC = (1 == bMbIsIPCM) ? 3 : 1;
304
305 IntraCmdY = IntraCmdC = 0;
306
307 REGIO_WRITE_FIELD(
308 IntraCmdY,
309 MSVDX_CMDS, INTRA_BLOCK_PREDICTION,
310 INTRA_PRED_BLOCK_SIZE,
311 BlockSizeY);
312 REGIO_WRITE_FIELD(
313 IntraCmdC,
314 MSVDX_CMDS, INTRA_BLOCK_PREDICTION,
315 INTRA_PRED_BLOCK_SIZE,
316 BlockSizeC);
317
318 h264_pollForSpaceForNCommands(2);
319 psb_deblock_reg_table_set(MSVDX_CMDS, INTRA_BLOCK_PREDICTION, 0, IntraCmdY);
320 psb_deblock_reg_table_set(MSVDX_CMDS, INTRA_BLOCK_PREDICTION, 4, IntraCmdC);
321 }
322
323 void
h264_above1IntraBlockPrediction(psb_cmdbuf_p cmdbuf,uint8_t * MbData,int bMbIsIPCM)324 h264_above1IntraBlockPrediction(psb_cmdbuf_p cmdbuf, uint8_t * MbData, int bMbIsIPCM)
325 {
326 uint32_t BlockSizeY;
327 uint32_t IntraCmdY;
328
329 /* select block size I_PCM or I_16x16 */
330 BlockSizeY = (1 == bMbIsIPCM) ? 3 : 0;
331 IntraCmdY = 0;
332
333 REGIO_WRITE_FIELD(
334 IntraCmdY,
335 MSVDX_CMDS, INTRA_BLOCK_PREDICTION_ABOVE1,
336 INTRA_PRED_BLOCK_SIZE_ABOVE1,
337 BlockSizeY);
338
339 h264_pollForSpaceForNCommands(1);
340 psb_deblock_reg_table_set(MSVDX_CMDS, INTRA_BLOCK_PREDICTION_ABOVE1, 0, IntraCmdY);
341 }
342
343 void
h264_macroblockCmdSequence(psb_cmdbuf_p cmdbuf,uint8_t * MbData,uint32_t X,uint32_t Y,int bCurrent)344 h264_macroblockCmdSequence(psb_cmdbuf_p cmdbuf, uint8_t * MbData, uint32_t X, uint32_t Y, int bCurrent)
345 {
346 int bMbIsIPCM;
347 uint32_t MbType;
348 uint32_t Value;
349 uint32_t MbNumberCmd, MbQuantCmd, MbTransZeroCmd;
350
351 /* Macroblock Type */
352 MbType = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_MBTYPE);
353
354 /* Macroblock Number */
355 /* no need for MB_ERROR_FLAG as error info is not stored */
356 /* no need for MB_FIELD_CODE as basline is always frame based */
357 MbNumberCmd = 0;
358
359 Value = (3 == MbType) ? 0 : MbType;
360 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_CODE_TYPE, Value);
361
362 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_NO_Y, Y);
363 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_NO_X, X);
364
365 /* H264 Quant */
366 /* TRANSFORM_SIZE_8X8 always false in basline */
367 MbQuantCmd = 0;
368
369 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_QP_CR);
370 REGIO_WRITE_FIELD(MbQuantCmd, MSVDX_CMDS, MACROBLOCK_H264_QUANT, MB_QUANT_CHROMA_CR, Value);
371
372 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_QP_CB);
373 REGIO_WRITE_FIELD(MbQuantCmd, MSVDX_CMDS, MACROBLOCK_H264_QUANT, MB_QUANT_CHROMA_CB, Value);
374
375 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_QP);
376 REGIO_WRITE_FIELD(MbQuantCmd, MSVDX_CMDS, MACROBLOCK_H264_QUANT, MB_QUANT_LUMA, Value);
377
378 /* send 2 commands */
379 h264_pollForSpaceForNCommands(2);
380 if (1 == bCurrent) {
381 /* Top and Left available flags are only sent for current MB */
382 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_MB_AVAILABLE_TOP_FLAG);
383 Value = (1 == Value) ? 0 : 1;
384 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_SLICE_TOP, Value);
385
386 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_MB_AVAILABLE_LEFT_FLAG);
387 Value = (1 == Value) ? 0 : 1;
388 REGIO_WRITE_FIELD(MbNumberCmd, MSVDX_CMDS, MACROBLOCK_NUMBER, MB_SLICE_LHS, Value);
389
390 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_NUMBER, MbNumberCmd);
391 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_H264_QUANT, MbQuantCmd);
392 } else {
393 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_NUMBER_ABOVE1, MbNumberCmd);
394 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_H264_QUANT_ABOVE1, MbQuantCmd);
395 }
396
397 /* Prediction Block Sequence */
398 bMbIsIPCM = 0;
399 switch (MbType) {
400 case 3: /* IPCM */
401 bMbIsIPCM = 1;
402 /* deliberate drop through */
403 case 0: /* I */
404 if (1 == bCurrent) {
405 h264_currentIntraBlockPrediction(cmdbuf, MbData, bMbIsIPCM);
406 } else {
407 h264_above1IntraBlockPrediction(cmdbuf, MbData, bMbIsIPCM);
408 }
409 break;
410 case 1: /* P */
411 if (1 == bCurrent) {
412 h264_currentInterBlockSequence(cmdbuf, MbData);
413 } else {
414 h264_above1InterBlockSequence(cmdbuf, MbData);
415 }
416 break;
417 case 2: /* B */
418 default:
419 /* invalid MB type */
420 //IMG_ASSERT( 0 );
421 break;
422 }
423
424 /* Trasform Zero */
425 MbTransZeroCmd = 0;
426 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_ASO_MB_TRANSFORM_ZERO);
427 REGIO_WRITE_FIELD(MbTransZeroCmd, MSVDX_CMDS, MACROBLOCK_BLOCK_TRANSFORM_ZERO, MB_BLOCK_TRANSFORM_ZERO, Value);
428
429 /* write last command */
430 h264_pollForSpaceForNCommands(1);
431 if (1 == bCurrent) {
432 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_BLOCK_TRANSFORM_ZERO, MbTransZeroCmd);
433 } else {
434 MbTransZeroCmd &= 0x0000CC00; /* only send for sub-blocks 10,11,14 and 15 */
435 psb_deblock_reg_set(MSVDX_CMDS, MACROBLOCK_BLOCK_TRANSFORM_ZERO_ABOVE1, MbTransZeroCmd);
436 }
437 }
438
439 uint32_t
h264_getCurrentSliceCmd(uint8_t * MbData)440 h264_getCurrentSliceCmd(uint8_t* MbData)
441 {
442 uint32_t Value, Cmd;
443
444 Cmd = 0;
445
446 /* unpack data from stored MB + repack in command */
447 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_DISABLE_DEBLOCK_FILTER_IDC);
448 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, DISABLE_DEBLOCK_FILTER_IDC, Value);
449
450 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_H264_BE_SLICE0_ALPHA_CO_OFFSET_DIV2);
451 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_ALPHA_CO_OFFSET_DIV2, Value);
452
453 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_H264_BE_SLICE0_BETA_OFFSET_DIV2);
454 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_BETA_OFFSET_DIV2, Value);
455
456 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_H264_BE_SLICE0_FIELD_TYPE);
457 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_FIELD_TYPE, Value);
458
459 Value = MEMIO_READ_FIELD(MbData, MSVDX_VEC_ENTDEC_VLRIF_H264_MB_UNIT_COPY_H264_BE_SLICE0_CODE_TYPE);
460 REGIO_WRITE_FIELD(Cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE, Value);
461
462 return Cmd;
463 }
464
h264_secondPass(psb_cmdbuf_p cmdbuf,uint8_t * MbData,uint32_t OperatingModeCmd,uint32_t Width,uint32_t Height)465 int h264_secondPass(
466 psb_cmdbuf_p cmdbuf,
467 uint8_t * MbData,
468 uint32_t OperatingModeCmd,
469 uint32_t Width,
470 uint32_t Height
471 )
472 {
473 uint32_t i, PicSize;
474 uint32_t EndOfPictureCmd;
475 uint32_t EndOfSliceCmd;
476 uint32_t SliceCmd, OldSliceCmd;
477 uint32_t EnableReg;
478 uint8_t * CurrMb;
479 uint8_t * Above1Mb;
480 int bRetCode = 0;
481
482 PicSize = Width * Height;
483
484 /* End of Slice command */
485 EndOfSliceCmd = 0;
486 REGIO_WRITE_FIELD(EndOfSliceCmd, MSVDX_CMDS, END_SLICE_PICTURE, PICTURE_END, 0);
487
488
489 /* put vdeb into second pass mode */
490 /* send operating mode command for VDEB only */
491 REGIO_WRITE_FIELD(OperatingModeCmd, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 2); /* VDEB only */
492 h264_pollForSpaceForNCommands(1);
493 psb_deblock_reg_get(MSVDX_CORE, CR_MSVDX_COMMAND_SPACE);
494 psb_deblock_reg_set(MSVDX_CMDS, OPERATING_MODE, OperatingModeCmd);
495
496 PollForSpaceForXCommands;
497
498 /* Send Slice Command */
499 SliceCmd = h264_getCurrentSliceCmd(MbData);
500 h264_pollForSpaceForNCommands(2);
501 psb_deblock_reg_set(MSVDX_CMDS, SLICE_PARAMS, SliceCmd);
502 psb_deblock_reg_set(MSVDX_CMDS, SLICE_PARAMS_ABOVE1, SliceCmd);
503 /* process top row */
504 for (i = 0, CurrMb = MbData;
505 i < Width;
506 i++, CurrMb += H264_MACROBLOCK_DATA_SIZE) {
507 OldSliceCmd = SliceCmd;
508 SliceCmd = h264_getCurrentSliceCmd(CurrMb);
509 if (OldSliceCmd != SliceCmd) {
510 h264_pollForSpaceForNCommands(2);
511 psb_deblock_reg_set(MSVDX_CMDS, END_SLICE_PICTURE, EndOfSliceCmd);
512 psb_deblock_reg_set(MSVDX_CMDS, SLICE_PARAMS, SliceCmd);
513 }
514
515 h264_macroblockCmdSequence(cmdbuf, CurrMb, i, 0, 1);
516 }
517
518 /* process rest of picture */
519 for (Above1Mb = MbData;
520 i < PicSize;
521 i++, CurrMb += H264_MACROBLOCK_DATA_SIZE, Above1Mb += H264_MACROBLOCK_DATA_SIZE) {
522 OldSliceCmd = SliceCmd;
523 SliceCmd = h264_getCurrentSliceCmd(CurrMb);
524 if (OldSliceCmd != SliceCmd) {
525 h264_pollForSpaceForNCommands(2);
526 psb_deblock_reg_set(MSVDX_CMDS, END_SLICE_PICTURE, EndOfSliceCmd);
527 psb_deblock_reg_set(MSVDX_CMDS, SLICE_PARAMS, SliceCmd);
528 }
529
530 h264_macroblockCmdSequence(cmdbuf, Above1Mb, (i % Width), (i / Width) - 1, 0);
531 h264_macroblockCmdSequence(cmdbuf, CurrMb, (i % Width), (i / Width), 1);
532 }
533
534 /* send end of pic + restart back end */
535 EndOfPictureCmd = 0;
536 EnableReg = 0;
537 REGIO_WRITE_FIELD(EndOfPictureCmd, MSVDX_CMDS, END_SLICE_PICTURE, PICTURE_END, 1);
538 REGIO_WRITE_FIELD(EnableReg, MSVDX_VEC, CR_VEC_CONTROL, ENTDEC_ENABLE_BE, 1);
539
540 h264_pollForSpaceForNCommands(2);
541 psb_deblock_reg_set(MSVDX_CMDS, END_SLICE_PICTURE, EndOfSliceCmd);
542 psb_deblock_reg_set(MSVDX_CMDS, END_SLICE_PICTURE, EndOfPictureCmd);
543 //psb_deblock_reg_set( MSVDX_VEC, CR_VEC_CONTROL, EnableReg); /* this is not a command */
544 return bRetCode;
545 }
546
psb_cmdbuf_second_pass(object_context_p obj_context,uint32_t OperatingModeCmd,unsigned char * pvParamBase,uint32_t PicWidthInMbs,uint32_t FrameHeightInMbs,psb_buffer_p target_buffer,uint32_t chroma_offset)547 int psb_cmdbuf_second_pass(object_context_p obj_context,
548 uint32_t OperatingModeCmd,
549 unsigned char * pvParamBase,
550 uint32_t PicWidthInMbs,
551 uint32_t FrameHeightInMbs,
552 psb_buffer_p target_buffer,
553 uint32_t chroma_offset
554 )
555 {
556 int bRetVal = 1;
557 uint32_t Cmd, item_loc;
558 uint32_t *cmd_size;
559 psb_cmdbuf_p cmdbuf = obj_context->cmdbuf;
560
561 if (psb_buffer_map(&cmdbuf->regio_buf, &cmdbuf->regio_base)) {
562 //printf("map cmdbuf->regio_buf error\n");
563 return bRetVal;
564 }
565
566 item_loc = psb_cmdbuf_buffer_ref(cmdbuf, &cmdbuf->regio_buf);
567
568 cmdbuf->regio_idx = (uint32_t *)cmdbuf->regio_base;
569 cmd_size = cmdbuf->regio_idx++;
570
571 h264_pollForSpaceForNCommands(4);
572
573 psb_deblock_reg_set_RELOC(MSVDX_CMDS, LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES, target_buffer, target_buffer->buffer_ofs, item_loc);
574 psb_deblock_reg_set_RELOC(MSVDX_CMDS, CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES, target_buffer, target_buffer->buffer_ofs + chroma_offset, item_loc);
575
576 Cmd = 0;
577 REGIO_WRITE_FIELD_LITE(Cmd, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, (FrameHeightInMbs * 16) - 1);
578 REGIO_WRITE_FIELD_LITE(Cmd, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, (PicWidthInMbs * 16) - 1);
579 psb_deblock_reg_set(MSVDX_CMDS, DISPLAY_PICTURE_SIZE, Cmd);
580
581
582 Cmd = 0;
583 REGIO_WRITE_FIELD_LITE(Cmd, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_HEIGHT, (FrameHeightInMbs * 16) - 1);
584 REGIO_WRITE_FIELD_LITE(Cmd, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_WIDTH, (PicWidthInMbs * 16) - 1);
585 psb_deblock_reg_set(MSVDX_CMDS, CODED_PICTURE_SIZE, Cmd);
586
587 /* BRN25312 */
588 psb_deblock_reg_set(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS, 0);
589 psb_deblock_reg_set(MSVDX_CMDS, VC1_CHROMA_RANGE_MAPPING_BASE_ADDRESS, 0);
590 psb_deblock_reg_set(MSVDX_CMDS, VC1_RANGE_MAPPING_FLAGS, 0);
591
592 /* process second pass */
593 bRetVal = h264_secondPass(cmdbuf,
594 (uint8_t*)pvParamBase,
595 OperatingModeCmd,
596 PicWidthInMbs,
597 FrameHeightInMbs);
598
599 *cmd_size = (cmdbuf->regio_idx - (uint32_t *)cmdbuf->regio_base - 1);
600
601 drv_debug_msg(VIDEO_DEBUG_GENERAL, "DEBLOCK: REGIO size is %d\n", (uint32_t)(cmdbuf->regio_idx - (uint32_t *)cmdbuf->regio_base) - 1);
602 //printf("DEBLOCK: REGIO size is %d\n", (uint32_t)(cmdbuf->regio_idx - (uint32_t *)cmdbuf->regio_base) - 1);
603 psb_buffer_unmap(&cmdbuf->regio_buf);
604 return bRetVal;
605 }
606