xref: /utopia/UTPA2-700.0.x/modules/mfe/drv/mfe_ex/cModel/mfe_common.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 
79 #include "MFE_chip.h"
80 #include "mfe_type.h"
81 #include "mfe_common.h"
82 #include "ms_dprintf.h"
83 #include "mdrv_mfe_math.h"
84 #include "mhal_mfe.h"
85 
86 #ifdef WIN32
87 #include "UDMAapi.h"
88 #endif
89 
90 #if defined(CHECK_FDC_DONE)&&defined(_MFE_UTOPIA_)
91 #include "MsCommon.h"
92 #include "MsVersion.h"
93 #include "MsOS.h"
94 #include "MsTypes.h"
95 #endif
96 #define CEILING_ALIGN(value, align) (((MS_U32)(value)+((align)-1UL)) & ~((align)-1UL))
97 #ifdef __MOBILE_CASE__
98 #include <stdio.h>
99 #include <string.h>
100 #include "MsOS.h"
101 #endif
102 #if (defined(_MFE_T8_)||defined(_MFE_M1_))&&defined(_MIPS_PLATFORM_)&&!defined(_KERNEL_MODE_)
103 extern MS_U32 u32MFERegOSBase;
104 #endif
WriteRegMFE(MS_U32 u32Address,MS_U16 val,MS_S8 * str1,MS_S32 num,MS_S8 * str3)105 void WriteRegMFE(MS_U32 u32Address, MS_U16 val, MS_S8 *str1, MS_S32 num, MS_S8 *str3)
106 {
107 
108 #if defined(__MFE_G2__)
109     //ms_dprintk(DRV_L5, (MS_S8*)("write: %02x=%04x\n"),u32Address,val);
110     __MFE_REG(u32Address) = (MS_U32) val;
111     //MsOS_DelayTask(1);
112 #elif defined(WIN32)
113     UDMA_RIUWrite16(REG_BANK_MFE+u32Address, val);
114 #else
115     __MFE_REG(u32Address) = val;
116 #endif
117 }
118 
119 // void WriteRegMFE_Bank1(U32 u32Address, U16 val, MS_S8 *str1, MS_S32 num, MS_S8 *str3)
120 // {
121 //     sd_output_reg(sd_sw_cfg3, u32Address, val, str1, num, str3);
122 //     UDMA_RIUWrite16(REG_BANK_MFE1+u32Address, val);
123 // }
124 #if defined(_MFE_MUJI_) || defined(_MFE_MONET_) || defined(_MFE_MESSI_) || defined(_MFE_MANHATTAN_) || defined(_MFE_MASERATI_) || defined(_MFE_MAXIM_) || defined(_MFE_KANO_) || defined(_MFE_K6_)
WriteRegMFE_BANK1(MS_U32 u32Address,MS_U16 val,MS_S8 * str1,MS_S32 num,MS_S8 * str3)125 void WriteRegMFE_BANK1(MS_U32 u32Address, MS_U16 val, MS_S8 *str1, MS_S32 num, MS_S8 *str3)
126 {
127 #if defined(WIN32)
128 	UDMA_RIUWrite16(REG_BANK_MFE1+u32Address, val);
129 #else
130     __MFE_REG1(u32Address) = val;
131 #endif
132 }
133 #endif
134 
ReadRegMFE(MS_U32 u32Address,MS_U16 * val)135 void ReadRegMFE(MS_U32 u32Address, MS_U16 *val)
136 {
137 
138 #if defined(__MFE_G2__)
139     *val = (MS_U16) __MFE_REG(u32Address);
140 #elif defined(WIN32)
141     UDMA_RIURead16(REG_BANK_MFE+u32Address, val);
142 #else
143     *val = __MFE_REG(u32Address);
144 #endif
145 }
146 #if defined(_MFE_MUJI_) || defined(_MFE_MONET_) || defined(_MFE_MESSI_) || defined(_MFE_MANHATTAN_) || defined(_MFE_MASERATI_) || defined(_MFE_MAXIM_) || defined(_MFE_KANO_) || defined(_MFE_K6_)
ReadRegMFE_BANK1(MS_U32 u32Address,MS_U16 * val)147 void ReadRegMFE_BANK1(MS_U32 u32Address, MS_U16 *val)
148 {
149 
150 #if defined(__MFE_G2__)
151     *val = (MS_U16) __MFE_REG1(u32Address);
152 #elif defined(WIN32)
153     UDMA_RIURead16(REG_BANK_MFE1+u32Address, val);
154 #else
155     *val = __MFE_REG1(u32Address);
156 #endif
157 }
158 #endif
DumpAllReg(MFE_REG * mfe_reg)159 void DumpAllReg(MFE_REG* mfe_reg)
160 {
161 #if (DRV_L5==0)
162     return;
163 #elif defined(__MOBILE_CASE__)
164     MS_S32 i,j;
165     MS_U16 tmp[8];
166     for (i = 0; i < 0x80; i+=8) {
167         for(j=0;j<8;j++)
168             ReadRegMFE(i+j, (tmp+j));
169 
170         ms_dprintk(DRV_L5,"%02X=%04X %02X=%04X %02X=%04X %02X=%04X %02X=%04X %02X=%04X %02X=%04X %02X=%04X\n"),
171             i, tmp[0],i+1, tmp[1],i+2, tmp[2],i+3, tmp[3],i+4, tmp[4],i+5, tmp[5],i+6, tmp[6],i+7, tmp[7]);
172     }
173 
174 #else
175     MS_S32 i;
176     MS_U16 tmp[8] = { 0 };
177     for (i = 0; i < 0x80; i += 0x8) {
178         ReadRegMFE(i    , &tmp[0]);
179         ReadRegMFE(i + 1, &tmp[1]);
180         ReadRegMFE(i + 2, &tmp[2]);
181         ReadRegMFE(i + 3, &tmp[3]);
182         ReadRegMFE(i + 4, &tmp[4]);
183         ReadRegMFE(i + 5, &tmp[5]);
184         ReadRegMFE(i + 6, &tmp[6]);
185         ReadRegMFE(i + 7, &tmp[7]);
186         ms_dprintk(DRV_L5, "0x%02X | 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n",
187             (unsigned int)i,
188             (unsigned int)tmp[0], (unsigned int)tmp[1], (unsigned int)tmp[2], (unsigned int)tmp[3],
189             (unsigned int)tmp[4], (unsigned int)tmp[5], (unsigned int)tmp[6], (unsigned int)tmp[7]);
190     }
191 #endif
192 }
193 
194 #if defined(_MFE_M1_)||defined(_MFE_AGATE_)
195 /*
196  * pAddr: The buffer address (can be s0 or s1)
197  * nBufSize: The size of the buffer
198  * nObufIdx: Must be 0 or 1 (means to set s0/e0 or s1/e1)
199  * bSetAdrFlag: if 1, set reg_jpe_s_bspobuf_set_adr. This is for (1) before-fs buffer setting, or (2) in-frame sw-multi-obuf switching.
200  *              Note for in-frame hw-double-buffer changing, this must be 0.
201  */
SetObufAddr(MFE_REG * mfe_reg,MS_U32 pAddr,MS_U32 nBufSize,MS_S32 nObufIdx,MS_S32 bSetAdrFlag)202 MS_S32 SetObufAddr(MFE_REG* mfe_reg, MS_U32 pAddr, MS_U32 nBufSize, MS_S32 nObufIdx, MS_S32 bSetAdrFlag)
203 {
204     MS_S32 nRegWriteCount = 0;
205     MS_U32 pOutBufAddr = pAddr;
206 
207     if (nObufIdx==0) {
208         // For safety
209         mfe_reg->reg_mfe_s_obuf_write_id_adr = 0;
210         MS_ASSERT(mfe_reg->reg3e==0x0);
211         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
212         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
213         //
214         mfe_reg->reg_mfe_s_bspobuf_low = (pOutBufAddr>>3)&0xFFFF;
215         mfe_reg->reg_mfe_s_bspobuf_high = pOutBufAddr>>(3+16);
216         mfe_reg->reg_mfe_s_obuf_id = 0;  // s0
217         WriteRegMFE(0x3c, mfe_reg->reg3c, (MS_S8*)("[%d] reg3c"), nRegWriteCount++, (MS_S8*)("bsp obuf address low"));
218         WriteRegMFE(0x3d, mfe_reg->reg3d, (MS_S8*)("[%d] reg3d"), nRegWriteCount++, (MS_S8*)("bsp obuf address high"));
219         mfe_reg->reg_mfe_s_obuf_write_id_adr = 1;
220         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
221 
222         // For safety
223         mfe_reg->reg_mfe_s_obuf_write_id_adr = 0;
224         MS_ASSERT(mfe_reg->reg3e==0x0);
225         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
226         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
227         //
228         mfe_reg->reg_mfe_s_bspobuf_low = ((pOutBufAddr+nBufSize-8)>>3)&0xFFFF;
229         mfe_reg->reg_mfe_s_bspobuf_high = (pOutBufAddr+nBufSize-8)>>(3+16);
230         mfe_reg->reg_mfe_s_obuf_id = 1;  // e0
231         WriteRegMFE(0x3c, mfe_reg->reg3c, (MS_S8*)("[%d] reg3c"), nRegWriteCount++, (MS_S8*)("bsp obuf address low"));
232         WriteRegMFE(0x3d, mfe_reg->reg3d, (MS_S8*)("[%d] reg3d"), nRegWriteCount++, (MS_S8*)("bsp obuf address high"));
233         mfe_reg->reg_mfe_s_obuf_write_id_adr = 1;
234         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
235     }
236 
237 #if defined(USE_HW_DBL_OBUF)
238     if (nObufIdx==1) {
239         MS_ASSERT(OBUF_NUM==2||OBUF_NUM==4);
240         MS_ASSERT((pOutBufAddr&0x7)==0);
241 
242         // For safety
243         mfe_reg->reg_mfe_s_obuf_write_id_adr = 0;
244         MS_ASSERT(mfe_reg->reg3e==0x0);
245         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
246         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
247         //
248         mfe_reg->reg_mfe_s_bspobuf_low = (pOutBufAddr>>3)&0xFFFF;
249         mfe_reg->reg_mfe_s_bspobuf_high = pOutBufAddr>>(3+16);
250         mfe_reg->reg_mfe_s_obuf_id = 2;  // s1
251         WriteRegMFE(0x3c, mfe_reg->reg3c, (MS_S8*)("[%d] reg3c"), nRegWriteCount++, (MS_S8*)("bsp obuf address low"));
252         WriteRegMFE(0x3d, mfe_reg->reg3d, (MS_S8*)("[%d] reg3d"), nRegWriteCount++, (MS_S8*)("bsp obuf address high"));
253         mfe_reg->reg_mfe_s_obuf_write_id_adr = 1;
254         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
255 
256         // For safety
257         mfe_reg->reg_mfe_s_obuf_write_id_adr = 0;
258         MS_ASSERT(mfe_reg->reg3e==0x0);
259         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
260         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
261         //
262         mfe_reg->reg_mfe_s_bspobuf_low = ((pOutBufAddr+nBufSize-8)>>3)&0xFFFF;
263         mfe_reg->reg_mfe_s_bspobuf_high = (pOutBufAddr+nBufSize-8)>>(3+16);
264         mfe_reg->reg_mfe_s_obuf_id = 3;  // e1
265         WriteRegMFE(0x3c, mfe_reg->reg3c, (MS_S8*)("[%d] reg3c"), nRegWriteCount++, (MS_S8*)("bsp obuf address low"));
266         WriteRegMFE(0x3d, mfe_reg->reg3d, (MS_S8*)("[%d] reg3d"), nRegWriteCount++, (MS_S8*)("bsp obuf address high"));
267         mfe_reg->reg_mfe_s_obuf_write_id_adr = 1;
268         WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)("[%d] reg3e"), nRegWriteCount++, (MS_S8*)("write_id_adr"));
269     }    // nObufIdx==1
270 #endif // USE_HW_DBL_OBUF
271 
272     if (bSetAdrFlag) {
273         mfe_reg->reg_mfe_s_bspobuf_set_adr = 1;
274         WriteRegMFE(0x3b, mfe_reg->reg3b, (MS_S8*)("[%d] reg3b"), nRegWriteCount++, (MS_S8*)("set bsp obuf"));
275         mfe_reg->reg_mfe_s_bspobuf_set_adr = 0;    // HW is write-one-clear
276     }
277 /*
278 #if defined(USE_HW_DBL_OBUF)
279     // DEBUG codes
280     {
281         MFE_REG tmp_reg;
282         tmp_reg.reg6a = 0;
283         UDMA_RIURead16(REG_BANK_MFE+0x6a, (MS_U16*)&tmp_reg.reg6a);
284         printf("[SetObufAddr]\n\treg_mfe_s_obuf0_status = %d\n\treg_mfe_s_obuf1_status = %d\n\treg_mfe_s_bspobuf_idx=%d\n\tobufadr_update_cnt=%d\n"),
285             tmp_reg.reg_mfe_s_obuf0_status,
286             tmp_reg.reg_mfe_s_obuf1_status,
287             tmp_reg.reg_mfe_s_bspobuf_idx,
288             tmp_reg.obufadr_update_cnt);
289       // Below is read back buffer address to check
290       //#define CHECK_OBUF_ADDRESS
291       #if defined(CHECK_OBUF_ADDRESS)
292         UDMA_RIURead16(REG_BANK_MFE+0x3f, (MS_U16*)&tmp_reg.reg3f);
293         tmp_reg.reg_mfe_s_bspobuf_adr_rchk_en = 1;
294         for (MS_S32 i=0; i<4; i++) {
295             tmp_reg.reg_mfe_s_bspobuf_adr_rchk_sel = i;
296             UDMA_RIUWrite16(REG_BANK_MFE+0x3f, tmp_reg.reg3f);
297             UDMA_RIURead16(REG_BANK_MFE+0x44, (MS_U16*)&tmp_reg.reg44);
298             UDMA_RIURead16(REG_BANK_MFE+0x45, (MS_U16*)&tmp_reg.reg45);
299             printf("\tObuf%d %d(s=0,e=1) = 0x%08x\n"),
300                 i>>1, i&1, ((tmp_reg.reg_mfe_s_bspobuf_wptr_high<<16)|tmp_reg.reg_mfe_s_bspobuf_wptr_low)<<3);
301         }
302         tmp_reg.reg_mfe_s_bspobuf_adr_rchk_en = 0;
303         UDMA_RIUWrite16(REG_BANK_MFE+0x3f, tmp_reg.reg3f);
304       #endif
305     }
306 #endif
307 */
308     return nRegWriteCount;
309 }
310 
311 #else
SetObufAddr(MFE_REG * mfe_reg,MS_U16 sadr_low,MS_U16 sadr_high,MS_U16 eadr_low,MS_U16 eadr_high)312 void SetObufAddr(MFE_REG* mfe_reg, MS_U16 sadr_low, MS_U16 sadr_high, MS_U16 eadr_low, MS_U16 eadr_high)
313 {
314     mfe_reg->reg_mfe_s_bspobuf_sadr_low = sadr_low;
315     mfe_reg->reg_mfe_s_bspobuf_sadr_high = sadr_high;
316     mfe_reg->reg_mfe_s_bspobuf_eadr_low = eadr_low;
317     mfe_reg->reg_mfe_s_bspobuf_eadr_high = eadr_high;
318 
319     WriteRegMFE(0x3c, mfe_reg->reg3c, (MS_S8*)(""), 0, (MS_S8*)(""));
320     WriteRegMFE(0x3d, mfe_reg->reg3d, (MS_S8*)(""), 0, (MS_S8*)(""));
321     WriteRegMFE(0x3e, mfe_reg->reg3e, (MS_S8*)(""), 0, (MS_S8*)(""));
322     WriteRegMFE(0x3f, mfe_reg->reg3f, (MS_S8*)(""), 0, (MS_S8*)(""));
323 
324     //printf("sadr_high = 0x%x, sadr_low = 0x%x, eadr_high = 0x%x, eadr_low = 0x%x\n"), sadr_high, sadr_low, eadr_high, eadr_low);
325     MS_ASSERT(mfe_reg->reg_mfe_s_mvobuf_set_adr==0);
326     mfe_reg->reg_mfe_s_bspobuf_set_adr = 1;
327     WriteRegMFE(0x3b, mfe_reg->reg3b, (MS_S8*)(""), 0, (MS_S8*)(""));
328     mfe_reg->reg_mfe_s_bspobuf_set_adr = 0;    // HW is write-one-clear
329 }
330 #endif
331 
ClearBsfFullIRQ(MFE_REG * mfe_reg)332 void ClearBsfFullIRQ(MFE_REG* mfe_reg)
333 {
334     mfe_reg->reg_mfe_g_irq_clr1 = 1;
335     WriteRegMFE(0x1d, mfe_reg->reg1d, (MS_S8*)(""), 0, (MS_S8*)(""));
336     mfe_reg->reg_mfe_g_irq_clr1 = 0;    // HW is write-one-clear
337 }
338 
ClearIRQ(MFE_REG * mfe_reg,MS_S32 number)339 void ClearIRQ(MFE_REG* mfe_reg,MS_S32 number)
340 {
341     ReadRegMFE(0x1d, &mfe_reg->reg1d);
342     switch (number) {
343         case 0: mfe_reg->reg_mfe_g_irq_clr0 = 1; break;
344         case 1: mfe_reg->reg_mfe_g_irq_clr1 = 1; break;
345         case 2: mfe_reg->reg_mfe_g_irq_clr2 = 1; break;
346         case 3: mfe_reg->reg_mfe_g_irq_clr3 = 1; break;
347         case 4: mfe_reg->reg_mfe_g_irq_clr4 = 1; break;
348         case 5: mfe_reg->reg_mfe_g_irq_clr5 = 1; break;
349         case 6: mfe_reg->reg_mfe_g_irq_clr6 = 1; break;
350         case 7: mfe_reg->reg_mfe_g_irq_clr7 = 1; break;
351     }
352     WriteRegMFE(0x1d, mfe_reg->reg1d, (MS_S8*)(""), 0, (MS_S8*)(""));
353     switch (number) {    // HW is write-one-clear
354     case 0: mfe_reg->reg_mfe_g_irq_clr0 = 0; break;
355     case 1: mfe_reg->reg_mfe_g_irq_clr1 = 0; break;
356     case 2: mfe_reg->reg_mfe_g_irq_clr2 = 0; break;
357     case 3: mfe_reg->reg_mfe_g_irq_clr3 = 0; break;
358     case 4: mfe_reg->reg_mfe_g_irq_clr4 = 0; break;
359     case 5: mfe_reg->reg_mfe_g_irq_clr5 = 0; break;
360     case 6: mfe_reg->reg_mfe_g_irq_clr6 = 0; break;
361     case 7: mfe_reg->reg_mfe_g_irq_clr7 = 0; break;
362     }
363 }
364 
365 
Enable_HW(MFE_REG * mfe_reg)366 void Enable_HW(MFE_REG* mfe_reg)
367 {
368     mfe_reg->reg_mfe_g_frame_start_sw = 1;
369     //WriteRegMFE(0x00, mfe_reg->reg00, (MS_S8*)("[%d] reg00"), nRegWriteCount++, (MS_S8*)("frame start"));
370     WriteRegMFE(0x00, mfe_reg->reg00, (MS_S8*)(""), 0, (MS_S8*)(""));
371     mfe_reg->reg_mfe_g_frame_start_sw = 0;    // HW is write-one-clear
372 }
373 
ResetAllRegs(MFE_REG * mfe_reg)374 void ResetAllRegs(MFE_REG* mfe_reg)
375 {
376     MS_S32 nRegWriteCount = 0;
377 
378     memset(mfe_reg, 0, sizeof(MFE_REG));    // Initial
379     mfe_reg->reg_mfe_g_soft_rstz = 1;
380     WriteRegMFE(0x0, mfe_reg->reg00, (MS_S8*)("[%d] reg00"), nRegWriteCount++, (MS_S8*)("SW reset 1"));
381 
382     WriteRegMFE(0x3, mfe_reg->reg03, (MS_S8*)("[%d] reg03"), nRegWriteCount++, (MS_S8*)("tbc_mode=0"));
383     WriteRegMFE(0x4, mfe_reg->reg04, (MS_S8*)("[%d] reg04"), nRegWriteCount++, (MS_S8*)("er_bs mode threshold"));
384     mfe_reg->reg_mfe_g_inter_pref = 0x200;
385     WriteRegMFE(0x5, mfe_reg->reg05, (MS_S8*)("[%d] reg05"), nRegWriteCount++, (MS_S8*)("inter prediction preference"));
386 
387     WriteRegMFE(0x16, mfe_reg->reg16, (MS_S8*)("[%d] reg16"), nRegWriteCount++, (MS_S8*)("clock gating=0"));
388 
389     // [JPEG]
390     mfe_reg->reg_mfe_g_jpe_qfactor = 0x3;
391     mfe_reg->reg_mfe_g_viu_soft_rstz = 1;
392     WriteRegMFE(0x18, mfe_reg->reg18, (MS_S8*)("[%d] reg18"), nRegWriteCount++, (MS_S8*)("JPE encode mode"));
393 
394     // [MPEG4/H263]
395     WriteRegMFE(0x19, mfe_reg->reg19, (MS_S8*)("[%d] reg19"), nRegWriteCount++, (MS_S8*)("value"));
396     WriteRegMFE(0x1a, mfe_reg->reg1a, (MS_S8*)("[%d] reg1a"), nRegWriteCount++, (MS_S8*)("value"));
397     WriteRegMFE(0x1b, mfe_reg->reg1b, (MS_S8*)("[%d] reg1b"), nRegWriteCount++, (MS_S8*)("value"));
398 
399     // ME setting
400     mfe_reg->reg_mfe_s_me_ref_en_mode = 0x3;
401     WriteRegMFE(0x20, mfe_reg->reg20, (MS_S8*)("[%d] reg20"), nRegWriteCount++, (MS_S8*)("ME partition setting"));
402 
403     // [IME PIPELINE]
404     WriteRegMFE(0x21, mfe_reg->reg21, (MS_S8*)("[%d] reg21"), nRegWriteCount++, (MS_S8*)("value"));
405     mfe_reg->reg_mfe_s_ime_mesr_max_addr = 0x5d;
406     WriteRegMFE(0x22, mfe_reg->reg22, (MS_S8*)("[%d] reg22"), nRegWriteCount++, (MS_S8*)("me search range max depth"));
407     mfe_reg->reg_mfe_s_ime_mvx_max = 0x3e;
408     WriteRegMFE(0x23, mfe_reg->reg23, (MS_S8*)("[%d] reg23"), nRegWriteCount++, (MS_S8*)("me mvx"));
409     mfe_reg->reg_mfe_s_ime_mvy_max = 0x1f;
410     WriteRegMFE(0x24, mfe_reg->reg24, (MS_S8*)("[%d] reg24"), nRegWriteCount++, (MS_S8*)("me mvy"));
411 
412     // [FME PIPELINE]
413     mfe_reg->reg_mfe_s_fme_pipeline_on = 0x0;    // This is hw default value
414     WriteRegMFE(0x25, mfe_reg->reg25, (MS_S8*)("[%d] reg25"), nRegWriteCount++, (MS_S8*)("FME"));
415 
416     // MBR
417     WriteRegMFE(0x26, mfe_reg->reg26, (MS_S8*)("[%d] reg26"), nRegWriteCount++, (MS_S8*)("MBR: mbbits"));
418     WriteRegMFE(0x27, mfe_reg->reg27, (MS_S8*)("[%d] reg27"), nRegWriteCount++, (MS_S8*)("MBR: frame qstep"));
419     WriteRegMFE(0x29, mfe_reg->reg29, (MS_S8*)("[%d] reg29"), nRegWriteCount++, (MS_S8*)("264 qp-offset"));
420     mfe_reg->reg_mfe_s_mbr_qp_min = 0x1;
421     mfe_reg->reg_mfe_s_mbr_qp_max = 0x1d;
422     WriteRegMFE(0x2a, mfe_reg->reg2a, (MS_S8*)("[%d] reg2a"), nRegWriteCount++, (MS_S8*)("QP min/max"));
423     mfe_reg->reg_mfe_s_mbr_qstep_min = 0x1f;
424     WriteRegMFE(0x6e, mfe_reg->reg6e, (MS_S8*)("[%d] reg6e"), nRegWriteCount++, (MS_S8*)("QStep min"));
425     mfe_reg->reg_mfe_s_mbr_qstep_max = 0x3a0;
426     WriteRegMFE(0x6f, mfe_reg->reg6f, (MS_S8*)("[%d] reg6f"), nRegWriteCount++, (MS_S8*)("QStep max"));
427 
428     // IEAP
429     mfe_reg->reg_mfe_s_ieap_last_mode = 8;
430     mfe_reg->reg_mfe_s_ieap_ccest_en = 1;
431     mfe_reg->reg_mfe_s_ieap_ccest_thr = 3;
432     WriteRegMFE(0x2b, mfe_reg->reg2b, (MS_S8*)("[%d] reg2b"), nRegWriteCount++, (MS_S8*)("ieap"));
433 
434     // QUAN
435     WriteRegMFE(0x2c, mfe_reg->reg2c, (MS_S8*)("[%d] reg2c"), nRegWriteCount++, (MS_S8*)("Last zigzag"));
436 
437     // TXIP control & debug
438     WriteRegMFE(0x2d, mfe_reg->reg2d, (MS_S8*)("[%d] reg2d"), nRegWriteCount, (MS_S8*)(""));
439     WriteRegMFE(0x2e, mfe_reg->reg2e, (MS_S8*)("[%d] reg2e"), nRegWriteCount, (MS_S8*)(""));
440     WriteRegMFE(0x2f, mfe_reg->reg2f, (MS_S8*)("[%d] reg2f"), nRegWriteCount, (MS_S8*)(""));
441     WriteRegMFE(0x30, mfe_reg->reg30, (MS_S8*)("[%d] reg30"), nRegWriteCount, (MS_S8*)(""));
442     WriteRegMFE(0x31, mfe_reg->reg31, (MS_S8*)("[%d] reg31"), nRegWriteCount, (MS_S8*)(""));
443     mfe_reg->reg_mfe_s_txip_wait_mode = 1;
444     WriteRegMFE(0x32, mfe_reg->reg32, (MS_S8*)("[%d] reg32"), nRegWriteCount, (MS_S8*)(""));
445     WriteRegMFE(0x33, mfe_reg->reg33, (MS_S8*)("[%d] reg33"), nRegWriteCount, (MS_S8*)(""));
446     WriteRegMFE(0x34, mfe_reg->reg34, (MS_S8*)("[%d] reg34"), nRegWriteCount, (MS_S8*)(""));
447 
448     // MDC
449     WriteRegMFE(0x37, mfe_reg->reg37, (MS_S8*)("[%d] reg37"), nRegWriteCount++, (MS_S8*)("MPEG4 MDC"));
450     WriteRegMFE(0x38, mfe_reg->reg38, (MS_S8*)("[%d] reg38"), nRegWriteCount++, (MS_S8*)("MPEG4: vop_time_increment"));
451     WriteRegMFE(0x39, mfe_reg->reg39, (MS_S8*)("[%d] reg39"), nRegWriteCount++, (MS_S8*)("value"));
452     mfe_reg->reg_mfe_s_mdc_h264_disable_dbf_idc = 2;
453     WriteRegMFE(0x3a, mfe_reg->reg3a, (MS_S8*)("[%d] reg3a"), nRegWriteCount++, (MS_S8*)("value"));
454 
455     // FDC
456     WriteRegMFE(0x46, mfe_reg->reg46, (MS_S8*)("[FDC %d] reg46"), nRegWriteCount++, (MS_S8*)("fdc bs"));
457     WriteRegMFE(0x47, mfe_reg->reg47, (MS_S8*)("[FDC %d] reg47"), nRegWriteCount++, (MS_S8*)("fdc len"));
458     WriteRegMFE(0x48, mfe_reg->reg48, (MS_S8*)("[FDC %d] reg48"), nRegWriteCount++, (MS_S8*)("fdc vld"));
459     // [Table Control]
460     WriteRegMFE(0x49, mfe_reg->reg49, (MS_S8*)("[Table %d] reg49"), nRegWriteCount++, (MS_S8*)("table address"));
461     WriteRegMFE(0x4a, mfe_reg->reg4a, (MS_S8*)("[Table %d] reg4a"), nRegWriteCount++, (MS_S8*)("table write data"));
462 
463     // [Debug]
464     WriteRegMFE(0x70, mfe_reg->reg70, (MS_S8*)("[%d] reg70"), nRegWriteCount++, (MS_S8*)(""));
465     WriteRegMFE(0x71, mfe_reg->reg71, (MS_S8*)("[%d] reg71"), nRegWriteCount++, (MS_S8*)(""));
466     WriteRegMFE(0x72, mfe_reg->reg72, (MS_S8*)("[%d] reg72"), nRegWriteCount++, (MS_S8*)(""));
467     WriteRegMFE(0x73, mfe_reg->reg73, (MS_S8*)("[%d] reg73"), nRegWriteCount++, (MS_S8*)(""));
468 }
469 
TestStopAtMb(MFE_REG * mfe_reg)470 void TestStopAtMb(MFE_REG* mfe_reg)
471 {
472     mfe_reg->reg_mfe_g_debug_trig_mbx = STOP_MBX;
473     WriteRegMFE(0x71, mfe_reg->reg71, (MS_S8*)("[%d] reg71"), 0, (MS_S8*)("reg_mfe_g_debug_trig_mbx"));
474     mfe_reg->reg_mfe_g_debug_trig_mby = STOP_MBY;
475     WriteRegMFE(0x72, mfe_reg->reg72, (MS_S8*)("[%d] reg72"), 0, (MS_S8*)("reg_mfe_g_debug_trig_mby"));
476     mfe_reg->reg_mfe_s_txip_sng_mb = 1;
477     WriteRegMFE(0x2d, mfe_reg->reg2d, (MS_S8*)("[%d] reg2d"), 0, (MS_S8*)("reg_mfe_s_txip_sng_mb=1"));
478     mfe_reg->reg_mfe_g_debug_trig_mode = 1;
479     mfe_reg->reg_mfe_g_debug_en = 1;
480     WriteRegMFE(0x73, mfe_reg->reg73, (MS_S8*)("[%d] reg73"), 0, (MS_S8*)("reg_mfe_g_debug_trig_mode=1"));
481     mfe_reg->reg_mfe_g_debug_trig_cycle = 0;
482     WriteRegMFE(0x70, mfe_reg->reg70, (MS_S8*)("[%d] reg70"), 0, (MS_S8*)("reg_mfe_g_debug_trig_cycle=0"));
483 }
484 
TestStop(MFE_REG * mfe_reg)485 void TestStop(MFE_REG* mfe_reg)
486 {
487     mfe_reg->reg_mfe_s_txip_sng_set = 1;
488     WriteRegMFE(0x2d, mfe_reg->reg2d, (MS_S8*)("[%d] reg2d"), 0, (MS_S8*)("reg_mfe_s_txip_sng_set=1"));
489 }
490 
491 
WriteQTable(MFE_REG * mfe_reg,MS_S32 * Table0,MS_S32 * Table1)492 void WriteQTable(MFE_REG* mfe_reg, MS_S32* Table0, MS_S32* Table1)
493 {
494     MS_S32 i, nTarWriteCount, nRegWriteCount=0;
495 
496     if (mfe_reg->reg_mfe_g_qmode==1) {    // Q table
497         nTarWriteCount = 2 + ((64>>1)*3)*2;
498 
499         // Switch to sw mode
500         mfe_reg->reg_mfe_g_tbc_mode = 0;
501         WriteRegMFE(0x3, mfe_reg->reg03, (MS_S8*)("[%d] reg3"), nRegWriteCount++, (MS_S8*)("tbc_mode=0"));
502 
503         mfe_reg->reg48 = 0;
504         for (i=0; i<64; i+=2) {
505             mfe_reg->reg_mfe_s_tbc_wdata =Table0[((i&0x7)<<3)|(i>>3)]
506                 | (Table0[(((i+1)&0x7)<<3)|((i+1)>>3)]<<8);
507 
508             WriteRegMFE(0x4a, mfe_reg->reg4a, (MS_S8*)("[%d] reg4a"), nRegWriteCount++, (MS_S8*)("table write data"));
509             mfe_reg->reg_mfe_s_tbc_rw = 1;
510             mfe_reg->reg_mfe_s_tbc_en = 1;
511             mfe_reg->reg_mfe_s_tbc_adr = i>>1;
512             WriteRegMFE(0x49, mfe_reg->reg49, (MS_S8*)("[%d] reg49"), nRegWriteCount++, (MS_S8*)("table address"));
513             WriteRegMFE(0x48, mfe_reg->reg48, (MS_S8*)("[%d] reg48"), nRegWriteCount++, (MS_S8*)("table write enable"));
514             mfe_reg->reg_mfe_s_tbc_en = 0;    // HW is write-one-clear
515 
516         }
517         for (i=0; i<64; i+=2) {
518             mfe_reg->reg_mfe_s_tbc_wdata = Table1[((i&0x7)<<3)|(i>>3)]
519                 | (Table1[(((i+1)&0x7)<<3)|((i+1)>>3)]<<8);
520 
521             WriteRegMFE(0x4a, mfe_reg->reg4a, (MS_S8*)("[%d] reg4a"), nRegWriteCount++, (MS_S8*)("table write data (inter)"));
522             mfe_reg->reg_mfe_s_tbc_rw = 1;
523             mfe_reg->reg_mfe_s_tbc_en = 1;
524             mfe_reg->reg_mfe_s_tbc_adr = (64+i)>>1;
525             WriteRegMFE(0x49, mfe_reg->reg49, (MS_S8*)("[%d] reg49"), nRegWriteCount++, (MS_S8*)("table address"));
526             WriteRegMFE(0x48, mfe_reg->reg48, (MS_S8*)("[%d] reg48"), nRegWriteCount++, (MS_S8*)("table write enable"));
527             mfe_reg->reg_mfe_s_tbc_en = 0;    // HW is write-one-clear
528 
529         }
530 
531         // Switch to hw mode
532         mfe_reg->reg_mfe_g_tbc_mode = 1;
533         WriteRegMFE(0x3, mfe_reg->reg03, (MS_S8*)("[%d] reg03"), nRegWriteCount++, (MS_S8*)("tbc_mode=1"));
534     } else
535     {
536         nTarWriteCount = 2;
537         // Switch to sw mode
538         mfe_reg->reg_mfe_g_tbc_mode = 0;
539         WriteRegMFE(0x3, mfe_reg->reg03, (MS_S8*)("[%d] reg03"), nRegWriteCount++, (MS_S8*)("tbc_mode=0"));
540         // Switch to hw mode
541         mfe_reg->reg_mfe_g_tbc_mode = 1;
542         WriteRegMFE(0x3, mfe_reg->reg03, (MS_S8*)("[%d] reg03"), nRegWriteCount++, (MS_S8*)("tbc_mode=1"));
543     }
544     MS_ASSERT(nRegWriteCount==nTarWriteCount);
545 
546 }
547 
548 // Mode 0: Actual FDC putting.
549 // Mode 1: Get number of FDC data round (each round is 16bit).
550 
PutFDC(MFE_REG * mfe_reg,void * pContext,MS_S32 mode)551 MS_S32 PutFDC(MFE_REG* mfe_reg, void* pContext, MS_S32 mode)
552 {
553     MS_S32 len, bit_len;
554     MS_U32 val=0;
555     MS_U8* ptr;
556     MS_U8 bits;
557     MS_S32 nRegWriteNum = 0;
558     MS_S32 nTotalRound = 0;
559 
560 
561     BitsInfo* pBitsInfo = (BitsInfo*)pContext;
562     ptr = pBitsInfo->ptr;
563     len = pBitsInfo->len;
564     bits = pBitsInfo->bits;
565     bit_len = pBitsInfo->bit_len;
566     bit_len += len*8;
567 
568     // Calculate total round.
569     if (bit_len==0)
570         nTotalRound = 1;
571     else
572         nTotalRound = (bit_len+15)>>4;
573     if (mode==1)
574         return nTotalRound;
575 
576     ms_dprintk(DRV_L3, "FDC: %d bits\n", (int)bit_len);
577     mfe_reg->reg46 = 0;
578     mfe_reg->reg47 = 0;
579     mfe_reg->reg48 = 0;
580     // Fill the total round reg
581     mfe_reg->reg_mfe_s_fdc_bs_count = nTotalRound-1;    // Count from 0
582     WriteRegMFE(0x47, mfe_reg->reg47, (MS_S8*)("[FDC %d] reg47"), nRegWriteNum++, (MS_S8*)("fdc round count"));
583 
584     while (bit_len>16) {
585         val = (ptr[0]<<8) | ptr[1];
586         ptr += 2;
587         bit_len -= 16;
588         len -= 2;
589 
590         mfe_reg->reg_mfe_s_fdc_bs = val;
591         mfe_reg->reg_mfe_s_fdc_bs_len = 15;
592         mfe_reg->reg_mfe_s_fdc_bs_vld = 1;
593         WriteRegMFE(0x46, mfe_reg->reg46, (MS_S8*)("[FDC %d] reg46"), nRegWriteNum++, (MS_S8*)("fdc bs"));
594         WriteRegMFE(0x47, mfe_reg->reg47, (MS_S8*)("[FDC %d] reg47"), nRegWriteNum++, (MS_S8*)("fdc len"));
595         WriteRegMFE(0x48, mfe_reg->reg48, (MS_S8*)("[FDC %d] reg48"), nRegWriteNum++, (MS_S8*)("fdc vld"));
596         mfe_reg->reg_mfe_s_fdc_bs_vld = 0;    // HW is write-one-clear
597     }
598     if (len==0) {
599         val = bits<<8;
600     } else if (len==1) {
601         val = (ptr[0]<<8) | bits;
602     } else if (len==2) {
603         val = (ptr[0]<<8) | ptr[1];
604     }
605 
606     mfe_reg->reg_mfe_s_fdc_bs = val;
607     mfe_reg->reg_mfe_s_fdc_bs_len = bit_len;
608     mfe_reg->reg_mfe_s_fdc_bs_vld = 1;
609     WriteRegMFE(0x46, mfe_reg->reg46, (MS_S8*)("[FDC %d] reg46"), nRegWriteNum++, (MS_S8*)("fdc bs"));
610     WriteRegMFE(0x47, mfe_reg->reg47, (MS_S8*)("[FDC %d] reg47"), nRegWriteNum++, (MS_S8*)("fdc len"));
611     WriteRegMFE(0x48, mfe_reg->reg48, (MS_S8*)("[FDC %d] reg48"), nRegWriteNum++, (MS_S8*)("fdc vld"));
612     mfe_reg->reg_mfe_s_fdc_bs_vld = 0;    // HW is write-one-clear
613 
614     return nRegWriteNum;
615 }
616 
617 //////////////////////////////////////////////////////////////////////////
618 // Intra Update
619 //        These are for settings and buffer allocation.
620 //        The actual algorithm is implemented in IntraUpdate.c
621 //////////////////////////////////////////////////////////////////////////
622 
IntraUpdateInit(MFE_CONFIG * pConfig)623 void IntraUpdateInit(MFE_CONFIG *pConfig)
624 {
625     IntraUpdateContext *ctx = &pConfig->m_IUContext;
626 
627     ctx->nWidth = pConfig->nBufWidth;
628     MS_ASSERT(ctx->nWidth%16==0);
629     ctx->nHeight = pConfig->nBufHeight;
630     MS_ASSERT(ctx->nHeight%16==0);
631     ctx->nTotalMb = (ctx->nWidth*ctx->nHeight)>>8;
632     ctx->pHwMbMap = MfeDrvMemMalloc(sizeof(HW_MB_MAP)*ctx->nTotalMb, (const MS_S8*)("pHwMbMap"));//pConfig->m_UIHwMap;
633     ctx->pSwMbMap = MfeDrvMemMalloc(sizeof(SW_MB_MAP)*ctx->nTotalMb, (const MS_S8*)("pSwMbMap"));//pConfig->m_UISwMap;
634 
635     if (pConfig->g_intraupdate_enable) {
636         ctx->bCIR = 1;
637         ctx->CIR_COUNT = (ctx->nTotalMb/pConfig->g_intraupdate_period)+1;
638     }
639     else {
640         ctx->bCIR = 0;
641     }
642 
643     ctx->bFIR = 0;
644     ctx->FIR_THR = 132;
645 
646     ctx->bAIR = 0;
647     ctx->AIR_COUNT = 10;
648     ctx->AIR_ROUND = 1;
649 
650     IntraUpdate_Init(ctx);
651 }
652 
IntraUpdateFrame(MFE_CONFIG * pConfig)653 void IntraUpdateFrame(MFE_CONFIG *pConfig)
654 {
655     IntraUpdate_Frame(&pConfig->m_IUContext);
656 }
657 
IntraUpdateClose(MFE_CONFIG * pConfig)658 void IntraUpdateClose(MFE_CONFIG *pConfig)
659 {
660     IntraUpdateContext *ctx = &pConfig->m_IUContext;
661 
662     if (ctx->pHwMbMap) {
663         MfeDrvMemFree((void**)&ctx->pHwMbMap, (const MS_S8*)("pHwMbMap"));
664     }
665     if (ctx->pSwMbMap) {
666         MfeDrvMemFree((void**)&ctx->pSwMbMap, (const MS_S8*)("pSwMbMap"));
667     }
668 }
669 
670 //////////////////////////////////////////////////////////////////////////
671 // Rate Control
672 //////////////////////////////////////////////////////////////////////////
673 
674 
_sw263v_ReinitRateCtrl(RateCtrl_t * rcctx,MFE_CONFIG * pConfig)675 static void _sw263v_ReinitRateCtrl(RateCtrl_t* rcctx,MFE_CONFIG* pConfig)
676 {
677     H263RCInfo rcInfo;
678     rcInfo.nWidth = pConfig->nBufWidth;
679     rcInfo.nHeight= pConfig->nBufHeight;
680     rcInfo.fTargetFrameRate = (MS_FLOAT) (pConfig->FrameRatex100 / 100);
681     rcInfo.fMinFrameRate = 5;
682     rcInfo.m_nBitrate = pConfig->nBitrate;
683     rcInfo.nPCount= pConfig->nPbetweenI;
684     rcInfo.rcGranularity = FRAMELEVELRC;
685     rcInfo.rcMethod = STRICT_CONST_BITRATE;
686     rc_Init(rcctx,&rcInfo);
687 
688 }
689 
MfeDrvRateControlInit(MFE_CONFIG * pConfig)690 void MfeDrvRateControlInit(MFE_CONFIG* pConfig)
691 {
692 
693     if(pConfig->VTMode){
694         rc_Create(&pConfig->VTRateCtrl);
695         _sw263v_ReinitRateCtrl(&pConfig->VTRateCtrl,pConfig);
696         return;
697     }
698 
699     pConfig->rcInfo.nCodecType = pConfig->nCodecType;
700     pConfig->rcInfo.nWidth = pConfig->nBufWidth;
701     pConfig->rcInfo.nHeight = pConfig->nBufHeight;
702 
703 //beacuse LG GP3 env no support float div
704 //this version only support 29.97fps and integer fps
705     if(pConfig->FrameRatex100==2997){
706         pConfig->rcInfo.fTargetFrameRate_is_float = 1;
707         pConfig->rcInfo.fTargetFrameRate = 29.97f;
708     }
709     else{
710         pConfig->rcInfo.fTargetFrameRate_is_float = 0;
711         pConfig->rcInfo.fTargetFrameRate = 0;
712         pConfig->rcInfo.int_fTargetFrameRate = pConfig->FrameRatex100/100;
713        //pConfig->rcInfo.fTargetFrameRate = (MS_FLOAT)(pConfig->FrameRatex100/100);
714     }
715 
716     pConfig->rcInfo.nBitrate = pConfig->nBitrate;
717     pConfig->rcInfo.nMaxBitrate = 0;   // Let RC decide
718     pConfig->rcInfo.nVPSize = pConfig->nVPSizeInBits > 0 ? pConfig->nVPSizeInBits : 0;    // 0 means not used.
719     pConfig->rcInfo.nVPMbRow = pConfig->nVPSizeInMbRow;    // 0 means not used.
720     pConfig->rcInfo.bFixedFrameRate = 1;
721     pConfig->rcInfo.nPCount = pConfig->nPbetweenI;    // Number of P-frames between I-frames
722     pConfig->rcInfo.nBCount = pConfig->nBbetweenP;    // Number of B-frames between P-frames
723     pConfig->rcInfo.rcMethod = CONSTRAINED_VARIABLE_BITRATE;
724     pConfig->rcInfo.rcGranularity = MBLEVELRC;//FRAMELEVELRC;
725     if (pConfig->rcInfo.nBitrate <=0) {
726         pConfig->rcInfo.rcGranularity = FRAMELEVELRC;
727         pConfig->rcInfo.rcMethod = CONST_QUALITY;
728         if (pConfig->rcInfo.nBitrate<0) {
729             pConfig->rcInfo.nConstQP = -pConfig->rcInfo.nBitrate;
730             if (pConfig->rcInfo.nConstQP>29)
731                 pConfig->rcInfo.nConstQP = 29;
732         }
733         else
734             pConfig->rcInfo.nConstQP = 8;
735     }
736     ms_dprintk(DRV_L1,"RC method: %d\n", pConfig->rcInfo.rcMethod);
737 #if 0 // Test const qp
738     pConfig->rcInfo.rcMethod = CONST_QUALITY;
739     pConfig->rcInfo.rcGranularity = FRAMELEVELRC;
740     pConfig->rcInfo.nConstQP = 12;
741 #endif
742     cvbr_InitRateControl(&pConfig->ctxRateControl, &pConfig->rcInfo);
743     pConfig->m_cvbrFrameSkip = 0;
744     pConfig->m_bGenSkipVopHeader = 1;
745 }
746 
MfeDrvRateControlUpdate(MFE_CONFIG * pConfig,MS_S8 nFieldType)747 void MfeDrvRateControlUpdate(MFE_CONFIG* pConfig, MS_S8 nFieldType)
748 {
749     MS_S32 nLastFrmAvgQStep, nLastFrmBits;
750     CVBRRateControl* pRC = &pConfig->ctxRateControl;
751     RateControl_REG reg;
752     // Rate control
753     // Read reg_mfe_s_mbr_last_frm_avg_qp and assign to rate control context.
754     reg.reg28 = 0;
755     reg.reg29 = 0;
756     ReadRegMFE(0x28, &reg.reg28);
757     ReadRegMFE(0x29, &reg.reg29);
758     nLastFrmAvgQStep = ((MS_S32)reg.reg_mfe_s_mbr_last_frm_avg_qp_high << 16) + reg.reg_mfe_s_mbr_last_frm_avg_qp_low;
759     reg.reg42 = 0;
760     reg.reg43 = 0;
761     ReadRegMFE(0x42, &reg.reg42);
762     ReadRegMFE(0x43, &reg.reg43);
763     nLastFrmBits = ((MS_S32)reg.reg_mfe_s_bsp_bit_cnt_high<<16) + reg.reg_mfe_s_bsp_bit_cnt_low;
764 
765     if(pConfig->VTMode){
766         if(rc_CheckSkippedFrame(&pConfig->VTRateCtrl))
767             rc_UpdateFrame(&pConfig->VTRateCtrl, 0,rcQstep2QP(pRC,nLastFrmAvgQStep/pConfig->VTRateCtrl.m_nNFrame),TRUE);
768         else
769             rc_UpdateFrame(&pConfig->VTRateCtrl, nLastFrmBits,rcQstep2QP(pRC,nLastFrmAvgQStep/pConfig->VTRateCtrl.m_nNFrame),FALSE);
770         return;
771     }
772     if (nFieldType==0 || nFieldType==1) {
773         pRC->m_nLastFrameAvgQStep[0] = nLastFrmAvgQStep;
774         pRC->m_nLastFrameAvgQStep[1] = 0;
775     }
776     else {    // nFieldType=2
777         pRC->m_nLastFrameAvgQStep[1] = nLastFrmAvgQStep;
778     }
779     // Read
780     if (pConfig->m_cvbrFrameSkip>0 && pConfig->vopPredType==P_VOP) {
781         nLastFrmBits = pConfig->m_OutStream.m_nByteCount*8;
782         cvbr_UpdateFrame(pRC, nLastFrmBits, 1, nFieldType);
783         pConfig->m_cvbrFrameSkip--;
784     }
785     else {
786         pConfig->m_cvbrFrameSkip = cvbr_UpdateFrame(pRC, nLastFrmBits, 0, nFieldType);
787     }
788 
789 }
790 
MfeDrvRateControlDeInit(MFE_CONFIG * pConfig)791 void MfeDrvRateControlDeInit(MFE_CONFIG* pConfig)
792 {
793     if(pConfig->VTMode){
794         rc_Finish(&pConfig->VTRateCtrl);
795         rc_Destroy(&pConfig->VTRateCtrl);
796     }
797     else {
798         cvbr_CloseRateControl(&pConfig->ctxRateControl);
799     }
800 }
801 
802 //report cabac_bit_count and bin count
MfeDrvCabacStuffingReport(MFE_CONFIG * pConfig)803 MS_S32 MfeDrvCabacStuffingReport(MFE_CONFIG* pConfig)
804 {
805 #if defined(_MFE_MUJI_) || defined(_MFE_MONET_) || defined(_MFE_MESSI_) || defined(_MFE_MANHATTAN_) || defined(_MFE_MASERATI_) || defined(_MFE_MAXIM_) || defined(_MFE_KANO_) || defined(_MFE_K6_)
806     MS_U16 tmp_low = 0;
807     MS_U16 tmp_high = 0;
808     MS_U32 bytes_in_picture;
809     MS_U32 bin_count,bit_count;
810 
811     MS_U32 min_num_bytes=0;
812     MS_S32 stuffing_bytes=0;
813     MS_S32 RawMbBits;
814     MS_S32 PicSizeInMbs = pConfig->nBufWidth*pConfig->nBufHeight/16/16;
815     //load reg_mfe_s_cabac_bin_count
816     ReadRegMFE_BANK1(0x30,&tmp_low);
817     ReadRegMFE_BANK1(0x31,&tmp_high);
818     bin_count = (((MS_U32)tmp_high)<<16) | ((MS_U32)tmp_low);
819 
820     //load reg_mfe_s_cabac_bit_count
821     ReadRegMFE_BANK1(0x32,&tmp_low);
822     ReadRegMFE_BANK1(0x33,&tmp_high);
823     bit_count = (((MS_U32)tmp_high)<<16) | ((MS_U32)tmp_low);
824 
825     bytes_in_picture = (CEILING_ALIGN(bit_count,0x8) / 8);
826 
827     RawMbBits = 256 * /*img->bitdepth_luma*/8 + 2 * /*MbWidthC[active_sps->chroma_format_idc]*/8 * /*MbHeightC[active_sps->chroma_format_idc]*/8 * /*img->bitdepth_chroma*/8;
828     min_num_bytes = ((96 * bin_count) - (RawMbBits * PicSizeInMbs *3) + 1023) / 1024;
829     if ((MS_U32)min_num_bytes > bytes_in_picture)
830     {
831         stuffing_bytes = min_num_bytes - bytes_in_picture;
832         stuffing_bytes = 3*((stuffing_bytes+2)/3);
833         ms_dprintk(DRV_L3, "CABAC stuffing bytes = %6d (according to Clause 7.4.2.10)\n", (int)stuffing_bytes);
834     }
835 
836     return stuffing_bytes;
837 #else
838     ms_dprintk(DRV_L4,"Not Support CABAC in this CHIP\n");
839     return 0;
840 #endif
841 }
842 
843 
MfeDrvMemMalloc(MS_SIZE size,const MS_S8 * msg)844 void* MfeDrvMemMalloc(MS_SIZE size,const MS_S8* msg)
845 {
846     void* ret_ptr = malloc(size);
847     ms_dprintk(DRV_L2, "[MFE MALLOC][%s] PTR: %p, SIZE: 0x%x\n", msg, ret_ptr, (unsigned int)size);
848     return ret_ptr;
849 }
850 
851 
MfeDrvMemFree(void ** mem_ptr,const MS_S8 * msg)852 void MfeDrvMemFree(void** mem_ptr, const MS_S8* msg)
853 {
854     if (mem_ptr && *mem_ptr)
855     {
856         ms_dprintk(DRV_L2,"[MFE FREE][%s] PTR: %p\n", msg, mem_ptr);
857         free(*mem_ptr);
858         *mem_ptr = NULL;
859     }
860 }
861