xref: /utopia/UTPA2-700.0.x/modules/mfe/drv/mfe_ex/cModel/mfe_reg_jpge.c_ (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1
2
3
4#include "MFE_chip.h"
5#include "mfe_common.h"
6#include "mfe_type.h"
7#include "ms_dprintf.h"
8#ifdef __MOBILE_CASE__
9#include <stdio.h>
10#include <string.h>
11#endif
12#if defined(WIN32)
13	#include "sigdump/sigdump_api.h"
14#endif
15#include "Exif.h"
16#include "jcmarker.h"
17#if (DEBUG_LEVEL & DRV_L6)
18extern int mfe_starttime;
19//int endtime=0;
20#endif
21/*
22typedef struct _JpgInfo
23{
24	int nFrameMode;
25	int nUseMST422;
26	int nUseYVYU;
27	int nWidth, nHeight;
28	int nLastZZ;
29	int QTable[2][64];
30	int nQFactor;
31} JpgInfo;
32*/
33
34static void OutputSwCfg1_Jpg(MFE_U32 nFrmNum, MFE_CONFIG* pConfig);
35
36
37static void jpeg_add_quant_table (JpgInfo* cinfo, int which_tbl,
38		      const unsigned int *basic_table,
39		      int scale_factor, MFE_BOOL force_baseline)
40{
41
42    long temp;
43    int i;
44    for (i = 0; i < DCTSIZE2; i++) {
45        temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
46        /* limit the values to the valid range */
47        if (temp <= 0L) temp = 1L;
48        if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
49        if (force_baseline && temp > 255L)
50          temp = 255L;		/* limit to baseline range if requested */
51        cinfo->QTable[which_tbl][i] = (MFE_U16) temp;
52    }
53
54}
55
56static void jpeg_set_linear_quality (JpgInfo* cinfo, int scale_factor, MFE_BOOL force_baseline)
57{
58  jpeg_add_quant_table(cinfo, 0, QTable_default_0,
59		       scale_factor, force_baseline);
60  jpeg_add_quant_table(cinfo, 1, QTable_default_1,
61		       scale_factor, force_baseline);
62}
63
64static int jpeg_quality_scaling (int quality)
65{
66  if (quality <= 0) quality = 1;
67  if (quality > 100) quality = 100;
68
69  if (quality < 50)
70    quality = 5000 / quality;
71  else
72    quality = 200 - quality*2;
73
74  return quality;
75}
76
77void mfeJPE_Set_QTABLE(MFE_CONFIG *pConfig)
78{
79	int quality;
80	JpgInfo* pInfo = &pConfig->ctxJpgInfo;
81	quality = jpeg_quality_scaling(pConfig->m_quality);
82	jpeg_set_linear_quality(pInfo, quality, TRUE);
83}
84
85void mfeJPE_Init(MFE_CONFIG *pConfig)
86{
87	int i;
88	JpgInfo* pInfo = &pConfig->ctxJpgInfo;
89	int quality;
90	memset(pInfo, 0, sizeof(JpgInfo));
91
92	pInfo->nFrameMode = pConfig->m_bFrameMode;
93	pInfo->nUseMST422 = 1;
94	pInfo->nUseYVYU = 0;
95	pInfo->nQFactor = 3;
96	pInfo->nLastZZ = 63;
97	pInfo->nWidth = pConfig->nBufWidth;
98	pInfo->nHeight = pConfig->nBufHeight;
99	pInfo->fdc_mode = pConfig->m_bFDC_mode;
100
101	quality = jpeg_quality_scaling(pConfig->m_quality);
102	jpeg_set_linear_quality(pInfo, quality, TRUE);
103
104    //print Q table
105        ms_dprintk(DRV_L1, "table 0");
106    for(i=0;i<64;i+=8){
107        ms_dprintk(DRV_L1, "%d,%d,%d,%d,%d,%d,%d,%d",pInfo->QTable[0][i+0],pInfo->QTable[0][i+1],
108            pInfo->QTable[0][i+2],pInfo->QTable[0][i+3],
109            pInfo->QTable[0][i+4],pInfo->QTable[0][i+5],
110            pInfo->QTable[0][i+6],pInfo->QTable[0][i+7]);
111    }
112
113        ms_dprintk(DRV_L1, "table 1");
114    for(i=0;i<64;i+=8){
115        ms_dprintk(DRV_L1, "%d,%d,%d,%d,%d,%d,%d,%d\n",pInfo->QTable[1][i+0],pInfo->QTable[1][i+1],
116            pInfo->QTable[1][i+2],pInfo->QTable[1][i+3],
117            pInfo->QTable[1][i+4],pInfo->QTable[1][i+5],
118            pInfo->QTable[1][i+6],pInfo->QTable[1][i+7]);
119    }
120
121}
122
123void mfeJPE_EncodeFrame(MFE_CONFIG *pConfig, GOPINFO* pGopInfo)
124{
125
126#if (DEBUG_LEVEL & DRV_L6)
127        mfe_starttime = MsOS_GetSystemTime();
128#endif
129    OutputSwCfg1_Jpg(0 , pConfig);
130
131}
132
133void OutputSwCfg1_Jpg(MFE_U32 nFrmNum, MFE_CONFIG* pConfig)
134{
135
136    int nTarWriteCount;
137    int nRegWriteCount;
138    int nTarFDCCount;
139    int nRegFDCCount;
140
141    void* pContext;
142    JpgInfo*  pJpgInfo = &pConfig->ctxJpgInfo;
143    BitsInfo* pBitsInfo = &pConfig->ctxBitsInfo;
144    BufInfo*  pBufInfo = &pConfig->ctxBufInfo;
145
146    pContext = (void*)pBitsInfo;
147
148	//////////////////////////////////////////////////////////////////////////
149	// Sequence-wide settings
150
151	if (nFrmNum==0) {
152		memset(mfe_reg, 0, sizeof(MFE_REG));	// Initial
153		mfe_reg->reg_mfe_g_enc_mode = REG_ENC_MODE_JPEG;
154		mfe_reg->reg_mfe_g_pic_width = (pJpgInfo->nWidth+15)&~15;
155		mfe_reg->reg_mfe_g_pic_height = (pJpgInfo->nHeight+7)&~7;
156
157		mfe_reg->reg_mfe_g_qmode = 1;	// Always with quant-tables
158		mfe_reg->reg_mfe_g_jpe_enc_mode = 1;	// current version supports 422 only
159		mfe_reg->reg_mfe_g_jpe_buffer_mode = pJpgInfo->nFrameMode;
160		if (pJpgInfo->nFrameMode==0)
161			mfe_reg->reg_mfe_g_jpe_multibuf_mode = 0;
162
163		mfe_reg->reg_mfe_g_jpe_qfactor = pJpgInfo->nQFactor;		// 3 means no altering qtable
164		mfe_reg->reg_mfe_g_packed_mode = pJpgInfo->nUseYVYU ? 0 : 1;
165#ifdef _MFE_M1_
166		mfe_reg->reg_mfe_g_jpe_mst422_mode = pJpgInfo->nUseMST422 ? 1 : 0;
167
168#ifdef _SW_BUF_MODE_
169        mfe_reg->reg_mfe_g_sw_buffer_mode = 1;
170#else
171        mfe_reg->reg_mfe_g_sw_buffer_mode = 0;
172        if (pJpgInfo->nFrameMode==0) { //hw row mode
173            // disable fs fail irq for hw handshake
174            mfe_reg->reg_mfe_g_irq_mask = IRQ_FS_FAIL;
175        }
176#endif
177#endif
178	}
179	else {
180		mfe_reg->reg_mfe_g_frame_start_sw = 0;
181	}
182
183	//////////////////////////////////////////////////////////////////////////
184	// Frame-wide settings
185#ifdef CLOCK_GATING
186    mfe_reg->reg16 = 0xffff;	// clock gating
187#endif
188	// Input buffer address: Must be 256-byte aligned.
189	MFE_ASSERT((pBufInfo->m_nCurYAddr.miuAddress&0xFF)==0);
190	MFE_ASSERT((pBufInfo->m_nCurCAddr.miuAddress&0xFF)==0);
191
192    if(pConfig->m_bFrameMode==0) {
193//	MFE_ASSERT((pBufInfo->m_nRefYAddr[0].miuAddress&0xFF)==0);
194	MFE_ASSERT((pBufInfo->m_nRefYAddr[1].miuAddress&0xFF)==0);
195//	MFE_ASSERT((pBufInfo->m_nRefCAddr[0].miuAddress&0xFF)==0);
196	MFE_ASSERT((pBufInfo->m_nRefCAddr[1].miuAddress&0xFF)==0);
197    }
198	MFE_ASSERT((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress&0x7)==0);
199
200	mfe_reg->reg_mfe_g_cur_y_adr_low  = (MFE_U16)((pBufInfo->m_nCurYAddr.miuAddress>>8)&0xFFFF);
201	mfe_reg->reg_mfe_g_cur_y_adr_high = (MFE_U16)(pBufInfo->m_nCurYAddr.miuAddress>>(8+16));
202	mfe_reg->reg_mfe_g_cur_c_adr_low  = (MFE_U16)((pBufInfo->m_nCurCAddr.miuAddress>>8)&0xFFFF);
203	mfe_reg->reg_mfe_g_cur_c_adr_high = (MFE_U16)(pBufInfo->m_nCurCAddr.miuAddress>>(8+16));
204
205       //if (mfe_reg->reg_mfe_g_enc_mode!=REG_ENC_MODE_JPEG)
206	{
207	//	mfe_reg->reg_mfe_g_ref_y_adr0_low  = (MFE_U16)((pBufInfo->m_nRefYAddr[0].miuAddress>>8)&0xFFFF);
208	//	mfe_reg->reg_mfe_g_ref_y_adr0_high = (MFE_U16)(pBufInfo->m_nRefYAddr[0].miuAddress>>(8+16));
209        if(pConfig->m_bFrameMode==0) {
210             mfe_reg->reg_mfe_g_ref_y_adr1_low  = (MFE_U16)((pBufInfo->m_nRefYAddr[1].miuAddress>>8)&0xFFFF);
211		mfe_reg->reg_mfe_g_ref_y_adr1_high = (MFE_U16)(pBufInfo->m_nRefYAddr[1].miuAddress>>(8+16));
212
213	//	mfe_reg->reg_mfe_g_ref_c_adr0_low  = (MFE_U16)((pBufInfo->m_nRefCAddr[0].miuAddress>>8)&0xFFFF);
214	//	mfe_reg->reg_mfe_g_ref_c_adr0_high = (MFE_U16)(pBufInfo->m_nRefCAddr[0].miuAddress>>(8+16));
215		mfe_reg->reg_mfe_g_ref_c_adr1_low  = (MFE_U16)((pBufInfo->m_nRefCAddr[1].miuAddress>>8)&0xFFFF);
216		mfe_reg->reg_mfe_g_ref_c_adr1_high = (MFE_U16)(pBufInfo->m_nRefCAddr[1].miuAddress>>(8+16));
217        }
218	//	mfe_reg->reg_mfe_g_rec_y_adr_low  = (MFE_U16)((pBufInfo->m_nRecYAddr.miuAddress>>8)&0xFFFF);
219	//	mfe_reg->reg_mfe_g_rec_y_adr_high = (MFE_U16)(pBufInfo->m_nRecYAddr.miuAddress>>(8+16));
220	//	mfe_reg->reg_mfe_g_rec_c_adr_low  = (MFE_U16)((pBufInfo->m_nRecCAddr.miuAddress>>8)&0xFFFF);
221	//	mfe_reg->reg_mfe_g_rec_c_adr_high = (MFE_U16)(pBufInfo->m_nRecCAddr.miuAddress>>(8+16));
222	}
223
224	// Output buffers: Must be 8-byte aligned.
225#ifdef _MFE_T8_
226	mfe_reg->reg_mfe_s_bspobuf_sadr_low  = (MFE_U16)((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress>>3)&0xFFFF);
227	mfe_reg->reg_mfe_s_bspobuf_sadr_high = (MFE_U16)(pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress>>(3+16));
228	mfe_reg->reg_mfe_s_bspobuf_eadr_low  = (MFE_U16)(((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress+pBufInfo->m_OutBufferSize-8)>>3)&0xFFFF);
229	mfe_reg->reg_mfe_s_bspobuf_eadr_high = (MFE_U16)((pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress+pBufInfo->m_OutBufferSize-8)>>(3+16));
230#elif defined(_MFE_M1_)
231	mfe_reg->reg_mfe_s_bspobuf_hw_en = 0;
232#if defined(USE_HW_DBL_OBUF)
233	mfe_reg->reg_mfe_s_bspobuf_hw_en = 1;
234#endif
235#endif
236
237	mfe_reg->reg_mfe_s_txip_irfsh_en = 0;
238
239	mfe_reg->reg_mfe_g_frame_type = 0;	// JPEG: always I-frame
240	mfe_reg->reg_mfe_s_quan_idx_last = pJpgInfo->nLastZZ;
241	if (mfe_reg->reg_mfe_s_quan_idx_last<63)
242		mfe_reg->reg_mfe_s_quan_idx_swlast = 1;
243	else
244		mfe_reg->reg_mfe_s_quan_idx_swlast = 0;
245#if defined(_MFE_M1_)
246    //enable eco item.
247    mfe_reg->reg_mfe_s_txip_eco0 = 1;
248#endif
249	//////////////////////////////////////////////////////////////////////////
250	// swcfg1 output
251	nTarWriteCount = 0;
252	nRegWriteCount = 0;
253	nTarFDCCount = 0;
254	nRegFDCCount = 0;
255	if (nFrmNum==0) {
256		MFE_ASSERT(mfe_reg->reg_mfe_g_qmode==1);
257		WriteQTable(pJpgInfo->QTable[0], pJpgInfo->QTable[1]);
258	}
259
260	nTarWriteCount = 40 +1; //add eco item.
261
262    if(pJpgInfo->fdc_mode) {
263	nTarFDCCount = PutFDC(pContext, 1);
264	nTarWriteCount += nTarFDCCount*3+1;
265    }
266#ifdef TEST_IMGBUF_FULL
267    nTarWriteCount += 2;
268#endif
269    if(pJpgInfo->fdc_mode) {
270	nTarFDCCount *= 3;
271	nTarFDCCount++;	// reg to set fdc round
272    }
273	// SW reset
274	mfe_reg->reg_mfe_g_viu_soft_rstz=1;
275
276	mfe_reg->reg_mfe_g_soft_rstz = 0;
277	WriteRegMFE(0x0, mfe_reg->reg00, "[%d] reg00", nRegWriteCount++, "SW reset 0");
278	mfe_reg->reg_mfe_g_soft_rstz = 1;
279	WriteRegMFE(0x0, mfe_reg->reg00, "[%d] reg00", nRegWriteCount++, "SW reset 1");
280
281	WriteRegMFE(0x1, mfe_reg->reg01, "[%d] reg01", nRegWriteCount++, "picture width");
282	WriteRegMFE(0x2, mfe_reg->reg02, "[%d] reg02", nRegWriteCount++, "picture height");
283	WriteRegMFE(0x3, mfe_reg->reg03, "[%d] reg03", nRegWriteCount++, "value");
284
285       WriteRegMFE(0x16, mfe_reg->reg16, "[%d] reg16", nRegWriteCount++, "Clock gating");
286
287	// Input buffers
288	WriteRegMFE(0x06, mfe_reg->reg06, "[%d] reg06", nRegWriteCount++, "current luma base address");
289	WriteRegMFE(0x07, mfe_reg->reg07, "[%d] reg07", nRegWriteCount++, "current luma base address high");
290	WriteRegMFE(0x08, mfe_reg->reg08, "[%d] reg08", nRegWriteCount++, "current chroma base address");
291	WriteRegMFE(0x09, mfe_reg->reg09, "[%d] reg09", nRegWriteCount++, "current chroma base address high");
292	WriteRegMFE(0x0a, mfe_reg->reg0a, "[%d] reg0a", nRegWriteCount++, "reference luma base address0");
293	WriteRegMFE(0x0b, mfe_reg->reg0b, "[%d] reg0b", nRegWriteCount++, "reference luma base address0 high");
294	WriteRegMFE(0x0c, mfe_reg->reg0c, "[%d] reg0c", nRegWriteCount++, "reference luma base address1");
295	WriteRegMFE(0x0d, mfe_reg->reg0d, "[%d] reg0d", nRegWriteCount++, "reference luma base address1 high");
296	WriteRegMFE(0x0e, mfe_reg->reg0e, "[%d] reg0e", nRegWriteCount++, "reference chroma base address0");
297	WriteRegMFE(0x0f, mfe_reg->reg0f, "[%d] reg0f", nRegWriteCount++, "reference chroma base address0 high");
298	WriteRegMFE(0x10, mfe_reg->reg10, "[%d] reg10", nRegWriteCount++, "reference chroma base address1");
299	WriteRegMFE(0x11, mfe_reg->reg11, "[%d] reg11", nRegWriteCount++, "reference chroma base address1 high");
300	WriteRegMFE(0x12, mfe_reg->reg12, "[%d] reg12", nRegWriteCount++, "reconstructed luma base address:");
301	WriteRegMFE(0x13, mfe_reg->reg13, "[%d] reg13", nRegWriteCount++, "reconstructed luma base address high");
302	WriteRegMFE(0x14, mfe_reg->reg14, "[%d] reg14", nRegWriteCount++, "reconstructed chroma base address:");
303	WriteRegMFE(0x15, mfe_reg->reg15, "[%d] reg15", nRegWriteCount++, "reconstructed chroma base address: high");
304
305	// Output buffer
306#ifdef _MFE_M1_
307	mfe_reg->reg_mfe_s_bspobuf_fifo_th = 1;
308	mfe_reg->reg_mfe_s_mvobuf_set_adr = 0;
309	mfe_reg->reg_mfe_s_mvobuf_fifo_th = 0;
310	mfe_reg->reg_mfe_s_bsp_fdc_skip = !pJpgInfo->fdc_mode;
311#else
312	WriteRegMFE(0x3c, mfe_reg->reg3c, "[%d] reg3c", nRegWriteCount++, "bsp obuf start address: ");
313	WriteRegMFE(0x3d, mfe_reg->reg3d, "[%d] reg3d", nRegWriteCount++, "bsp obuf start address high");
314	WriteRegMFE(0x3e, mfe_reg->reg3e, "[%d] reg3e", nRegWriteCount++, "bsp obuf end address: ");
315	WriteRegMFE(0x3f, mfe_reg->reg3f, "[%d] reg3f", nRegWriteCount++, "bsp obuf end address high");
316	//
317	mfe_reg->reg_mfe_s_bspobuf_set_adr = 1;
318	mfe_reg->reg_mfe_s_bspobuf_fifo_th = 1;
319	mfe_reg->reg_mfe_s_mvobuf_set_adr = 0;
320	mfe_reg->reg_mfe_s_mvobuf_fifo_th = 0;
321	mfe_reg->reg_mfe_s_bsp_fdc_skip = 1;
322#endif
323
324#ifdef _MFE_M1_
325    // Enable set-obuf
326    mfe_reg->reg_mfe_s_bspobuf_update_adr = 1;
327    WriteRegMFE(0x3f, mfe_reg->reg3f, "[%d] reg3f", nRegWriteCount++, "reg_mfe_s_bspobuf_update_adr");
328    mfe_reg->reg_mfe_s_bspobuf_update_adr = 0;  // write-one-clear
329#if defined(USE_HW_DBL_OBUF)
330    nRegWriteCount += SetObufAddr((MFE_U32)pBufInfo->m_nOutBufAddr, pBufInfo->m_OutBufferSize, 0, 0);
331    nRegWriteCount += SetObufAddr((MFE_U32)pBufInfo->m_nOutBufAddr+pBufInfo->m_OutBufferSize, pBufInfo->m_OutBufferSize, 1, 1);
332#else
333    nRegWriteCount += SetObufAddr((MFE_U32)pBufInfo->m_nOutBufAddr[pConfig->nOBufIndex].miuAddress, pBufInfo->m_OutBufferSize, 0, 1);
334#endif
335
336#else
337	WriteRegMFE(0x3b, mfe_reg->reg3b, "[%d] reg3b", nRegWriteCount++, "set bsp obuf");
338    mfe_reg->reg_mfe_s_bspobuf_set_adr = 0;	// HW is write-one-clear
339#endif
340
341    // Cannot use mode 3.
342    if (pJpgInfo->nFrameMode==0) {
343        mfe_reg->reg_mfe_g_jpe_fsvs_mode=2;
344    }
345    else
346        mfe_reg->reg_mfe_g_jpe_fsvs_mode=0;  // When frame mode: Don't care
347
348    WriteRegMFE(0x18, mfe_reg->reg18, "[%d] reg18", nRegWriteCount++, "JPE encode mode");
349
350    // Cross-format wrong reg setting prevention
351    WriteRegMFE(0x1b, mfe_reg->reg1b, "[%d] reg1b", nRegWriteCount++, "MPEG4 FieldDCT");
352
353#ifdef _MFE_M1_
354    if(pConfig->MfeAdvInfo.input_imi_en) {
355        mfe_reg->reg_mfe_s_marb_eimi_block = 0x1;
356        WriteRegMFE(0x68, mfe_reg->reg68, "[%d] reg68", nRegWriteCount, "IMI enable");
357    }
358    else
359        mfe_reg->reg_mfe_s_marb_eimi_block = 0x0;
360#endif
361    mfe_reg->reg_mfe_g_crc_mode = 0xC;
362    mfe_reg->reg_mfe_g_debug_tcycle_chk_en = 0x1;
363    mfe_reg->reg_mfe_g_debug_tcycle_chk_sel = 0x0;
364    mfe_reg->reg_mfe_g_debug_en = 0; // TEST
365    WriteRegMFE(0x73, mfe_reg->reg73, "[%d] reg73", nRegWriteCount++, "crc mode");
366
367    WriteRegMFE(0x2c, mfe_reg->reg2c, "[%d] reg2c", nRegWriteCount++, "Last zigzag");
368
369    // Reset any StopAndGo or StopAndDrop setting.
370    mfe_reg->reg_mfe_s_txip_sng_mb = 0;
371    WriteRegMFE(0x2d, mfe_reg->reg2d, "[%d] reg2d", nRegWriteCount++, "reg_mfe_s_txip_sng_mb=0");
372
373#ifdef _MFE_M1_
374    //enable eco item
375    WriteRegMFE(0x7d, mfe_reg->reg7d, "[%d] reg7d", nRegWriteCount++, "reg_mfe_s_txip_eco0=1");
376#endif
377
378    DumpAllReg();
379
380    // Enable HW
381    mfe_reg->reg_mfe_g_frame_start_sw = 1;
382    WriteRegMFE(0x00, mfe_reg->reg00, "[%d] reg00", nRegWriteCount++, "frame start");
383    mfe_reg->reg_mfe_g_frame_start_sw = 0;	// HW is write-one-clear
384
385    // FDC
386    if(pJpgInfo->fdc_mode) {
387    	nRegFDCCount = PutFDC(pContext, 0);
388    	nRegWriteCount += nRegFDCCount;
389    }
390
391    if(nRegFDCCount != nTarFDCCount) {
392        ms_dprintk(DRV_L4,"nRegFDCCount = %d,nTarFDCCount = %d \n",nRegFDCCount,nTarFDCCount);
393    }
394    if(nRegWriteCount != nTarWriteCount) {
395        ms_dprintk(DRV_L4,"nRegWriteCount = %d,nTarWriteCount = %d \n",nRegWriteCount,nTarWriteCount);
396    }
397    // Only for debug
398    //MFE_ASSERT(nRegWriteCount==nTarWriteCount);
399    //MFE_ASSERT(nRegFDCCount==nTarFDCCount);
400
401}
402
403