Home | History | Annotate | Download | only in mrst
      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 (at) 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
    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
    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
    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
    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
    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
    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 
    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 
    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