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, ®.reg28);
757 ReadRegMFE(0x29, ®.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, ®.reg42);
762 ReadRegMFE(0x43, ®.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