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