import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / dispsys / mt8127 / ddp_rdma.c
CommitLineData
6fa3eb70
S
1#include <linux/kernel.h>
2#include <linux/mm.h>
3#include <linux/mm_types.h>
4#include <linux/module.h>
5#include <generated/autoconf.h>
6#include <linux/init.h>
7#include <linux/types.h>
8#include <linux/cdev.h>
9#include <linux/kdev_t.h>
10#include <linux/delay.h>
11#include <linux/ioport.h>
12#include <linux/platform_device.h>
13#include <linux/dma-mapping.h>
14#include <linux/device.h>
15#include <linux/fs.h>
16#include <linux/interrupt.h>
17#include <linux/wait.h>
18#include <linux/spinlock.h>
19#include <linux/param.h>
20#include <linux/uaccess.h>
21#include <linux/sched.h>
22#include <linux/slab.h>
23#include <linux/aee.h>
24
25#include <linux/xlog.h>
26
27#include <asm/io.h>
28#include <mach/mt_typedefs.h>
29#include "ddp_matrix_para.h"
30
31#include "ddp_reg.h"
32#include "ddp_rdma.h"
33#include "ddp_hal.h"
34#include "ddp_debug.h"
35#include "ddp_drv.h"
36#ifdef CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT
37#include <tz_cross/trustzone.h>
38#include <tz_cross/tz_ddp.h>
39#include <mach/m4u_port.h>
40#include <tz_cross/ta_mem.h>
41#include "trustzone/kree/system.h"
42#include "trustzone/kree/mem.h"
43
44// these 2 APIs are used for accessing ddp_session / ddp_mem_session with TEE
45extern KREE_SESSION_HANDLE ddp_session_handle(void);
46extern KREE_SESSION_HANDLE ddp_mem_session_handle(void);
47#endif
48
49#ifndef ASSERT
50//#define ASSERT(expr) do {printk("ASSERT error func=%s, line=%d\n", __FUNC__, __LINE__);} while (!(expr))
51#define ASSERT(expr) do {printk("ASSERT error \n");} while (!(expr))
52#endif
53
54#define DISP_INDEX_OFFSET 0xa000
55
56extern BOOL DISP_IsDecoupleMode(void);
57
58int RDMAStart(unsigned idx) {
59 ASSERT(idx <= 2);
60
61 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_INT_ENABLE, 0x3F);
62 DISP_REG_SET_FIELD(GLOBAL_CON_FLD_ENGINE_EN, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, 1);
63
64 return 0;
65}
66
67int RDMAStop(unsigned idx) {
68 ASSERT(idx <= 2);
69
70 DISP_REG_SET_FIELD(GLOBAL_CON_FLD_ENGINE_EN, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, 0);
71 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_INT_ENABLE, 0);
72 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_INT_STATUS, 0);
73 return 0;
74}
75
76int RDMAReset(unsigned idx) {
77 unsigned int delay_cnt=0;
78 //static unsigned int cnt=0;
79
80 // printk("[DDP] RDMAReset called %d \n", cnt++);
81
82 ASSERT(idx <= 2);
83
84 DISP_REG_SET_FIELD(GLOBAL_CON_FLD_SOFT_RESET, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, 1);
85 while((DISP_REG_GET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON)&0x700)==0x100)
86 {
87 delay_cnt++;
88 if(delay_cnt>10000)
89 {
90 printk("[DDP] error, RDMAReset(%d) timeout, stage 1! DISP_REG_RDMA_GLOBAL_CON=0x%x \n", idx, DISP_REG_GET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON));
91 break;
92 }
93 }
94 DISP_REG_SET_FIELD(GLOBAL_CON_FLD_SOFT_RESET, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, 0);
95 // printk("[DDP] start reset! \n");
96 while((DISP_REG_GET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON)&0x700)!=0x100)
97 {
98 delay_cnt++;
99 if(delay_cnt>10000)
100 {
101 printk("[DDP] error, RDMAReset(%d) timeout, stage 2! DISP_REG_RDMA_GLOBAL_CON=0x%x \n", idx, DISP_REG_GET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON));
102 ddp_dump_info(DISP_MODULE_CONFIG);
103 ddp_dump_info(DISP_MODULE_MUTEX);
104 ddp_dump_info(DISP_MODULE_OVL);
105 ddp_dump_info(DISP_MODULE_RDMA0);
106 break;
107 }
108 }
109 // printk("[DDP] end reset! \n");
110
111#if 0
112 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON , 0x00);
113 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0 , 0x00);
114 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_1 , 0x00);
115 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_CON , 0x00);
116 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_START_ADDR , 0x00);
117 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_SRC_PITCH , 0x00);
118 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_GMC_SETTING_1 , 0x20); ///TODO: need check
119 //DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_FIFO_CON , 0x80f00008); ///TODO: need check
120#endif
121
122 return 0;
123}
124
125extern unsigned int gUltraLevel;
126extern unsigned int gEnableUltra;
127#ifdef CONFIG_MTK_SEC_VIDEO_PATH_SUPPORT
128int RDMAConfig(unsigned idx,
129 enum RDMA_MODE mode,
130 DpColorFormat inFormat,
131 unsigned address,
132 enum RDMA_OUTPUT_FORMAT outputFormat,
133 unsigned pitch,
134 unsigned width,
135 unsigned height,
136 bool isByteSwap, // input setting
137 bool isRGBSwap) // ourput setting
138{
139 RDMAConfig_(idx, mode,inFormat, address, outputFormat, pitch, width, height, isByteSwap, isRGBSwap, 0);
140 return 0;
141}
142
143int RDMAConfig_(unsigned idx,
144 enum RDMA_MODE mode,
145 DpColorFormat inFormat,
146 unsigned address,
147 enum RDMA_OUTPUT_FORMAT outputFormat,
148 unsigned pitch,
149 unsigned width,
150 unsigned height,
151 bool isByteSwap, // input setting
152 bool isRGBSwap, // ourput setting
153 unsigned int RDMASecurity)
154{
155 unsigned int bpp = 2;
156 unsigned int rgb_swap = 0;
157 unsigned int input_is_yuv = 0;
158 unsigned int output_is_yuv = 0;
159 // Calculate fifo settings
160 unsigned int fifo_pseudo_length = 256; //HW fifo SRAM: 240(89), 256(71/72/82/92), 512
161 unsigned int fifo_threashold;
162 // Calculate ultra settings
163 unsigned int fps = 60;
164 unsigned int blank_overhead = 115; // it is 1.15, need to divide 100 later
165 unsigned int rdma_fifo_width = 16; // in unit of byte
166 unsigned int ultra_low_time = 6; // in unit of us
167 unsigned int pre_ultra_low_time = 8; // in unit of us
168 unsigned int pre_ultra_high_time = 9; // in unit of us
169 unsigned int consume_levels_per_usec;
170 unsigned int ultra_low_level;
171 unsigned int pre_ultra_low_level;
172 unsigned int pre_ultra_high_level;
173 unsigned int ultra_high_ofs;
174 unsigned int pre_ultra_low_ofs;
175 unsigned int pre_ultra_high_ofs;
176 enum RDMA_INPUT_FORMAT inputFormat = rdma_fmt_convert(inFormat);
177
178 if ((DISP_IsDecoupleMode()==0) || (gEnableUltra==1)) {
179 if(gUltraLevel==0)
180 {
181 ultra_low_time = 4; // in unit of us
182 pre_ultra_low_time = 6; // in unit of us
183 pre_ultra_high_time = 7; // in unit of us
184 }
185 else if(gUltraLevel==1)
186 {
187 ultra_low_time = 5; // in unit of us
188 pre_ultra_low_time = 7; // in unit of us
189 pre_ultra_high_time = 8; // in unit of us
190 }
191 else if(gUltraLevel==2)
192 {
193 ultra_low_time = 6; // in unit of us
194 pre_ultra_low_time = 8; // in unit of us
195 pre_ultra_high_time = 9; // in unit of us
196 }
197 }
198
199 ASSERT(idx <= 2);
200 if((width > RDMA_MAX_WIDTH) || (height > RDMA_MAX_HEIGHT))
201 {
202 printk("DDP error, RDMA input overflow, w=%d, h=%d, max_w=%d, max_h=%d\n", width, height, RDMA_MAX_WIDTH, RDMA_MAX_HEIGHT);
203 }
204
205 if(width==0 || height==0)
206 {
207 printk("DDP error, RDMA input error, w=%d, h=%d, pitch=%d\n", width, height, pitch);
208 ASSERT( width > 0);
209 ASSERT( height > 0);
210 }
211 if( mode == RDMA_MODE_MEMORY )
212 {
213 ASSERT( pitch > 0);
214 ASSERT( address > 0);
215 }
216
217 switch(inputFormat) {
218 case RDMA_INPUT_FORMAT_YUYV:
219 case RDMA_INPUT_FORMAT_UYVY:
220 case RDMA_INPUT_FORMAT_YVYU:
221 case RDMA_INPUT_FORMAT_VYUY:
222 case RDMA_INPUT_FORMAT_RGB565:
223 bpp = 2;
224 break;
225 case RDMA_INPUT_FORMAT_RGB888:
226 bpp = 3;
227 break;
228 case RDMA_INPUT_FORMAT_ARGB:
229 bpp = 4;
230 break;
231 // More color format support
232 case RDMA_INPUT_FORMAT_BGR565:
233 inputFormat -= RDMA_COLOR_BASE;
234 bpp = 2;
235 rgb_swap = 1;
236 break;
237 case RDMA_INPUT_FORMAT_BGR888:
238 inputFormat -= RDMA_COLOR_BASE;
239 bpp = 3;
240 rgb_swap = 1;
241 break;
242 case RDMA_INPUT_FORMAT_ABGR:
243 inputFormat -= RDMA_COLOR_BASE;
244 bpp = 4;
245 rgb_swap = 1;
246 break;
247
248 default:
249 printk("DDP error, unknown RDMA input format = %d\n", inputFormat);
250 ASSERT(0);
251 }
252 // OUTPUT_VALID_FIFO_THREASHOLD = min{(DISP_WIDTH+120)*bpp/16, FIFO_PSEUDO_LENGTH}
253 fifo_threashold = (width + 120) * bpp / 16;
254 fifo_threashold = fifo_threashold > fifo_pseudo_length ? fifo_pseudo_length : fifo_threashold;
255 //printk("RDMA: w=%d, h=%d, addr=%x, pitch=%d, mode=%d\n", width, height, address, width*bpp, mode);
256 //--------------------------------------------------------
257 // calculate ultra/pre-ultra setting
258 // to start to issue ultra from fifo having 4us data
259 // to stop to issue ultra until fifo having 6us data
260 // to start to issue pre-ultra from fifo having 6us data
261 // to stop to issue pre-ultra until fifo having 7us data
262 // the sequence is ultra_low < pre_ultra_low < ultra_high < pre_ultra_high
263 // 4us 6us 6us+1level 7us
264 //--------------------------------------------------------
265 consume_levels_per_usec = (width*height*fps*bpp/rdma_fifo_width/100)*blank_overhead;
266
267 // /1000000 for ultra_low_time in unit of us
268 ultra_low_level = ultra_low_time * consume_levels_per_usec / 1000000;
269 pre_ultra_low_level = pre_ultra_low_time * consume_levels_per_usec / 1000000;
270 pre_ultra_high_level = pre_ultra_high_time * consume_levels_per_usec / 1000000;
271 pre_ultra_low_ofs = pre_ultra_low_level - ultra_low_level;
272 ultra_high_ofs = 1;
273 pre_ultra_high_ofs = pre_ultra_high_level - pre_ultra_low_level - 1;
274 //printk("RDMA%d: fifo_pseudo_length=%d, fifo_threashold=%d, ultra_low_level=%x, pre_ultra_low_level=%d, pre_ultra_high_level=%d, ultra_high_ofs=%d, pre_ultra_low_ofs=%d, pre_ultra_high_ofs=%d\n",
275 // idx, fifo_pseudo_length, fifo_threashold, ultra_low_level, pre_ultra_low_level, pre_ultra_high_level, ultra_high_ofs, pre_ultra_low_ofs, pre_ultra_high_ofs);
276 if ((DISP_IsDecoupleMode()==0) || (gEnableUltra==1)) {
277 if(gUltraLevel==4) // always ultra
278 {
279 ultra_low_level = 0x6b;
280 pre_ultra_low_ofs = 0xa0;
281 ultra_high_ofs = 1;
282 pre_ultra_high_ofs = 1;
283 }
284 else if(gUltraLevel==3) // always pre-ultra
285 {
286 ultra_low_level = 0x6b;
287 pre_ultra_low_ofs = 0x36;
288 ultra_high_ofs = 0x50;
289 pre_ultra_high_ofs = 0x14;
290 }
291 }
292
293 switch(inputFormat) {
294 case RDMA_INPUT_FORMAT_YUYV:
295 case RDMA_INPUT_FORMAT_UYVY:
296 case RDMA_INPUT_FORMAT_YVYU:
297 case RDMA_INPUT_FORMAT_VYUY:
298 input_is_yuv = 1;
299 break;
300
301 case RDMA_INPUT_FORMAT_RGB565:
302 case RDMA_INPUT_FORMAT_RGB888:
303 case RDMA_INPUT_FORMAT_ARGB:
304 input_is_yuv = 0;
305 break;
306
307 default:
308 printk("DDP error, unknow input format is %d\n", inputFormat);
309 ASSERT(0);
310 }
311
312 if(outputFormat==RDMA_OUTPUT_FORMAT_ARGB)
313 {
314 output_is_yuv = 0;
315 }
316 else
317 {
318 output_is_yuv = 1;
319 }
320
321 if(input_is_yuv==1 && output_is_yuv==0)
322 {
323 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1);
324 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0x6);
325 // set color conversion matrix
326 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_00, coef_rdma_601_y2r[0][0] );
327 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_01, coef_rdma_601_y2r[0][1] );
328 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_02, coef_rdma_601_y2r[0][2] );
329 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_10, coef_rdma_601_y2r[1][0] );
330 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_11, coef_rdma_601_y2r[1][1] );
331 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_12, coef_rdma_601_y2r[1][2] );
332 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_20, coef_rdma_601_y2r[2][0] );
333 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_21, coef_rdma_601_y2r[2][1] );
334 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_22, coef_rdma_601_y2r[2][2] );
335
336 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD0, coef_rdma_601_y2r[3][0]);
337 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD1, coef_rdma_601_y2r[3][1]);
338 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD2, coef_rdma_601_y2r[3][2]);
339 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD0, coef_rdma_601_y2r[4][0]);
340 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD1, coef_rdma_601_y2r[4][1]);
341 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD2, coef_rdma_601_y2r[4][2]);
342 }
343 else if(input_is_yuv==0 && output_is_yuv==1)
344 {
345 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1);
346 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0x2);
347 // set color conversion matrix
348 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_00, coef_rdma_601_r2y[0][0] );
349 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_01, coef_rdma_601_r2y[0][1] );
350 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_02, coef_rdma_601_r2y[0][2] );
351 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_10, coef_rdma_601_r2y[1][0] );
352 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_11, coef_rdma_601_r2y[1][1] );
353 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_12, coef_rdma_601_r2y[1][2] );
354 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_20, coef_rdma_601_r2y[2][0] );
355 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_21, coef_rdma_601_r2y[2][1] );
356 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_22, coef_rdma_601_r2y[2][2] );
357
358 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD0, coef_rdma_601_r2y[3][0]);
359 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD1, coef_rdma_601_r2y[3][1]);
360 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD2, coef_rdma_601_r2y[3][2]);
361 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD0, coef_rdma_601_r2y[4][0]);
362 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD1, coef_rdma_601_r2y[4][1]);
363 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD2, coef_rdma_601_r2y[4][2]);
364 } else {
365 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0);
366 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0);
367 }
368
369 DISP_REG_SET_FIELD(GLOBAL_CON_FLD_MODE_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, mode);
370 DISP_REG_SET_FIELD(MEM_CON_FLD_MEM_MODE_INPUT_FORMAT, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_CON, inputFormat);
371
372 if(RDMASecurity)
373 {
374 MTEEC_PARAM param[4];
375 unsigned int paramTypes;
376 TZ_RESULT ret;
377
378 param[0].value.a = (uint32_t) address;
379 param[1].value.a = RDMASecurity;
380 param[2].value.a = pitch*height;
381 paramTypes = TZ_ParamTypes3(TZPT_VALUE_INPUT, TZPT_VALUE_INPUT, TZPT_VALUE_INPUT);
382 //DISP_OVL_ENGINE_DBG("[02420] Rdma config handle=0x%x \n", param[0].value.a);
383 ret = KREE_TeeServiceCall(ddp_session_handle(), TZCMD_DDP_RDMA_ADDR_CONFIG, paramTypes, param);
384 if(ret!= TZ_RESULT_SUCCESS)
385 {
386 pr_err("TZCMD_DDP_RDMA_ADDR_CONFIG fail, ret=%d \n", ret);
387 }
388 }
389 else
390 {
391 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_START_ADDR, address);
392 }
393 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_SRC_PITCH, pitch);
394 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_INT_ENABLE, 0x3F);
395
396 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_INPUT_BYTE_SWAP, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, isByteSwap);
397 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_OUTPUT_FORMAT, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, outputFormat);
398 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, width);
399 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_OUTPUT_RGB_SWAP, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, isRGBSwap||rgb_swap);
400 DISP_REG_SET_FIELD(SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_1, height);
401
402
403 // RDMA fifo config
404 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_FIFO_CON , (1<<31)|(fifo_pseudo_length<<16)|fifo_threashold);
405 // disp_rdma ultra high setting
406 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_GMC_SETTING_0, (pre_ultra_high_ofs<<24)|(ultra_high_ofs<<16)|(pre_ultra_low_ofs<<8)|ultra_low_level);
407
408 return 0;
409}
410#else
411int RDMAConfig(unsigned idx,
412 enum RDMA_MODE mode,
413 DpColorFormat inFormat,
414 unsigned address,
415 enum RDMA_OUTPUT_FORMAT outputFormat,
416 unsigned pitch,
417 unsigned width,
418 unsigned height,
419 bool isByteSwap, // input setting
420 bool isRGBSwap) // ourput setting
421{
422 unsigned int bpp = 2;
423 unsigned int rgb_swap = 0;
424 unsigned int input_is_yuv = 0;
425 unsigned int output_is_yuv = 0;
426 // Calculate fifo settings
427 unsigned int fifo_pseudo_length = 256; //HW fifo SRAM: 240(89), 256(71/72/82/92), 512
428 unsigned int fifo_threashold;
429 // Calculate ultra settings
430 unsigned int fps = 60;
431 unsigned int blank_overhead = 115; // it is 1.15, need to divide 100 later
432 unsigned int rdma_fifo_width = 16; // in unit of byte
433 unsigned int ultra_low_time = 6; // in unit of us
434 unsigned int pre_ultra_low_time = 8; // in unit of us
435 unsigned int pre_ultra_high_time = 9; // in unit of us
436 unsigned int consume_levels_per_usec;
437 unsigned int ultra_low_level;
438 unsigned int pre_ultra_low_level;
439 unsigned int pre_ultra_high_level;
440 unsigned int ultra_high_ofs;
441 unsigned int pre_ultra_low_ofs;
442 unsigned int pre_ultra_high_ofs;
443 enum RDMA_INPUT_FORMAT inputFormat = rdma_fmt_convert(inFormat);
444
445 if ((DISP_IsDecoupleMode()==0) || (gEnableUltra==1)) {
446 if(gUltraLevel==0)
447 {
448 ultra_low_time = 4; // in unit of us
449 pre_ultra_low_time = 6; // in unit of us
450 pre_ultra_high_time = 7; // in unit of us
451 }
452 else if(gUltraLevel==1)
453 {
454 ultra_low_time = 5; // in unit of us
455 pre_ultra_low_time = 7; // in unit of us
456 pre_ultra_high_time = 8; // in unit of us
457 }
458 else if(gUltraLevel==2)
459 {
460 ultra_low_time = 6; // in unit of us
461 pre_ultra_low_time = 8; // in unit of us
462 pre_ultra_high_time = 9; // in unit of us
463 }
464 }
465
466 ASSERT(idx <= 2);
467 if((width > RDMA_MAX_WIDTH) || (height > RDMA_MAX_HEIGHT))
468 {
469 printk("DDP error, RDMA input overflow, w=%d, h=%d, max_w=%d, max_h=%d\n", width, height, RDMA_MAX_WIDTH, RDMA_MAX_HEIGHT);
470 }
471
472 if(width==0 || height==0)
473 {
474 printk("DDP error, RDMA input error, w=%d, h=%d, pitch=%d\n", width, height, pitch);
475 ASSERT( width > 0);
476 ASSERT( height > 0);
477 }
478 if( mode == RDMA_MODE_MEMORY )
479 {
480 ASSERT( pitch > 0);
481 ASSERT( address > 0);
482 }
483
484 switch(inputFormat) {
485 case RDMA_INPUT_FORMAT_YUYV:
486 case RDMA_INPUT_FORMAT_UYVY:
487 case RDMA_INPUT_FORMAT_YVYU:
488 case RDMA_INPUT_FORMAT_VYUY:
489 case RDMA_INPUT_FORMAT_RGB565:
490 bpp = 2;
491 break;
492 case RDMA_INPUT_FORMAT_RGB888:
493 bpp = 3;
494 break;
495 case RDMA_INPUT_FORMAT_ARGB:
496 bpp = 4;
497 break;
498 // More color format support
499 case RDMA_INPUT_FORMAT_BGR565:
500 inputFormat -= RDMA_COLOR_BASE;
501 bpp = 2;
502 rgb_swap = 1;
503 break;
504 case RDMA_INPUT_FORMAT_BGR888:
505 inputFormat -= RDMA_COLOR_BASE;
506 bpp = 3;
507 rgb_swap = 1;
508 break;
509 case RDMA_INPUT_FORMAT_ABGR:
510 inputFormat -= RDMA_COLOR_BASE;
511 bpp = 4;
512 rgb_swap = 1;
513 break;
514
515 default:
516 printk("DDP error, unknown RDMA input format = %d\n", inputFormat);
517 ASSERT(0);
518 }
519 // OUTPUT_VALID_FIFO_THREASHOLD = min{(DISP_WIDTH+120)*bpp/16, FIFO_PSEUDO_LENGTH}
520 fifo_threashold = (width + 120) * bpp / 16;
521 fifo_threashold = fifo_threashold > fifo_pseudo_length ? fifo_pseudo_length : fifo_threashold;
522 //printk("RDMA: w=%d, h=%d, addr=%x, pitch=%d, mode=%d\n", width, height, address, width*bpp, mode);
523 //--------------------------------------------------------
524 // calculate ultra/pre-ultra setting
525 // to start to issue ultra from fifo having 4us data
526 // to stop to issue ultra until fifo having 6us data
527 // to start to issue pre-ultra from fifo having 6us data
528 // to stop to issue pre-ultra until fifo having 7us data
529 // the sequence is ultra_low < pre_ultra_low < ultra_high < pre_ultra_high
530 // 4us 6us 6us+1level 7us
531 //--------------------------------------------------------
532 consume_levels_per_usec = (width*height*fps*bpp/rdma_fifo_width/100)*blank_overhead;
533
534 // /1000000 for ultra_low_time in unit of us
535 ultra_low_level = ultra_low_time * consume_levels_per_usec / 1000000;
536 pre_ultra_low_level = pre_ultra_low_time * consume_levels_per_usec / 1000000;
537 pre_ultra_high_level = pre_ultra_high_time * consume_levels_per_usec / 1000000;
538 pre_ultra_low_ofs = pre_ultra_low_level - ultra_low_level;
539 ultra_high_ofs = 1;
540 pre_ultra_high_ofs = pre_ultra_high_level - pre_ultra_low_level - 1;
541 //printk("RDMA%d: fifo_pseudo_length=%d, fifo_threashold=%d, ultra_low_level=%x, pre_ultra_low_level=%d, pre_ultra_high_level=%d, ultra_high_ofs=%d, pre_ultra_low_ofs=%d, pre_ultra_high_ofs=%d\n",
542 // idx, fifo_pseudo_length, fifo_threashold, ultra_low_level, pre_ultra_low_level, pre_ultra_high_level, ultra_high_ofs, pre_ultra_low_ofs, pre_ultra_high_ofs);
543 if ((DISP_IsDecoupleMode()==0) || (gEnableUltra==1)) {
544 if(gUltraLevel==4) // always ultra
545 {
546 ultra_low_level = 0x6b;
547 pre_ultra_low_ofs = 0xa0;
548 ultra_high_ofs = 1;
549 pre_ultra_high_ofs = 1;
550 }
551 else if(gUltraLevel==3) // always pre-ultra
552 {
553 ultra_low_level = 0x6b;
554 pre_ultra_low_ofs = 0x36;
555 ultra_high_ofs = 0x50;
556 pre_ultra_high_ofs = 0x14;
557 }
558 }
559
560 switch(inputFormat) {
561 case RDMA_INPUT_FORMAT_YUYV:
562 case RDMA_INPUT_FORMAT_UYVY:
563 case RDMA_INPUT_FORMAT_YVYU:
564 case RDMA_INPUT_FORMAT_VYUY:
565 input_is_yuv = 1;
566 break;
567
568 case RDMA_INPUT_FORMAT_RGB565:
569 case RDMA_INPUT_FORMAT_RGB888:
570 case RDMA_INPUT_FORMAT_ARGB:
571 input_is_yuv = 0;
572 break;
573
574 default:
575 printk("DDP error, unknow input format is %d\n", inputFormat);
576 ASSERT(0);
577 }
578
579 if(outputFormat==RDMA_OUTPUT_FORMAT_ARGB)
580 {
581 output_is_yuv = 0;
582 }
583 else
584 {
585 output_is_yuv = 1;
586 }
587
588 if(input_is_yuv==1 && output_is_yuv==0)
589 {
590 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1);
591 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0x6);
592 // set color conversion matrix
593 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_00, coef_rdma_601_y2r[0][0] );
594 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_01, coef_rdma_601_y2r[0][1] );
595 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_02, coef_rdma_601_y2r[0][2] );
596 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_10, coef_rdma_601_y2r[1][0] );
597 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_11, coef_rdma_601_y2r[1][1] );
598 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_12, coef_rdma_601_y2r[1][2] );
599 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_20, coef_rdma_601_y2r[2][0] );
600 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_21, coef_rdma_601_y2r[2][1] );
601 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_22, coef_rdma_601_y2r[2][2] );
602
603 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD0, coef_rdma_601_y2r[3][0]);
604 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD1, coef_rdma_601_y2r[3][1]);
605 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD2, coef_rdma_601_y2r[3][2]);
606 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD0, coef_rdma_601_y2r[4][0]);
607 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD1, coef_rdma_601_y2r[4][1]);
608 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD2, coef_rdma_601_y2r[4][2]);
609 }
610 else if(input_is_yuv==0 && output_is_yuv==1)
611 {
612 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 1);
613 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0x2);
614 // set color conversion matrix
615 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_00, coef_rdma_601_r2y[0][0] );
616 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_01, coef_rdma_601_r2y[0][1] );
617 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_02, coef_rdma_601_r2y[0][2] );
618 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_10, coef_rdma_601_r2y[1][0] );
619 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_11, coef_rdma_601_r2y[1][1] );
620 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_12, coef_rdma_601_r2y[1][2] );
621 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_20, coef_rdma_601_r2y[2][0] );
622 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_21, coef_rdma_601_r2y[2][1] );
623 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_22, coef_rdma_601_r2y[2][2] );
624
625 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD0, coef_rdma_601_r2y[3][0]);
626 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD1, coef_rdma_601_r2y[3][1]);
627 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_PRE_ADD2, coef_rdma_601_r2y[3][2]);
628 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD0, coef_rdma_601_r2y[4][0]);
629 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD1, coef_rdma_601_r2y[4][1]);
630 DISP_REG_SET(idx*DISP_INDEX_OFFSET+DISP_REG_RDMA_CF_POST_ADD2, coef_rdma_601_r2y[4][2]);
631 } else {
632 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_ENABLE, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0);
633 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, 0);
634 }
635
636 DISP_REG_SET_FIELD(GLOBAL_CON_FLD_MODE_SEL, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, mode);
637 DISP_REG_SET_FIELD(MEM_CON_FLD_MEM_MODE_INPUT_FORMAT, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_CON, inputFormat);
638
639 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_START_ADDR, address);
640 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_SRC_PITCH, pitch);
641 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_INT_ENABLE, 0x3F);
642
643 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_INPUT_BYTE_SWAP, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, isByteSwap);
644 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_OUTPUT_FORMAT, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, outputFormat);
645 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, width);
646 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_OUTPUT_RGB_SWAP, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, isRGBSwap||rgb_swap);
647 DISP_REG_SET_FIELD(SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_1, height);
648
649
650 // RDMA fifo config
651 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_FIFO_CON , (1<<31)|(fifo_pseudo_length<<16)|fifo_threashold);
652 // disp_rdma ultra high setting
653 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_GMC_SETTING_0, (pre_ultra_high_ofs<<24)|(ultra_high_ofs<<16)|(pre_ultra_low_ofs<<8)|ultra_low_level);
654
655 return 0;
656}
657#endif
658void RDMAWait(unsigned idx)
659{
660 // polling interrupt status
661 unsigned int delay_cnt = 0;
662 while((DISP_REG_GET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_INT_STATUS) & 0x1) != 0x1)
663 {
664
665 delay_cnt++;
666 msleep(1);
667 if(delay_cnt>100)
668 {
669 printk("[DDP] error:RDMA%dWait timeout \n", idx);
670 break;
671 }
672 }
673 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_INT_STATUS , 0x0);
674}
675
676void RDMASetTargetLine(unsigned int idx, unsigned int line)
677{
678 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_TARGET_LINE, line);
679}
680
681void RDMASetOutputFrameSize(unsigned int idx, unsigned int width,unsigned int height)
682{
683 DISP_REG_SET_FIELD(SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_0, width);
684 DISP_REG_SET_FIELD(SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT, idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_SIZE_CON_1, height);
685
686}
687
688void RDMASetAddress(unsigned int idx, unsigned int address)
689{
690 DISP_REG_SET(idx * DISP_INDEX_OFFSET + DISP_REG_RDMA_MEM_START_ADDR, address);
691}
692
693enum RDMA_INPUT_FORMAT rdma_fmt_convert(DpColorFormat fmt)
694{
695 enum RDMA_INPUT_FORMAT rdma_fmt = RDMA_INPUT_FORMAT_RGB565;
696 switch(fmt)
697 {
698 case eRGB565:
699 rdma_fmt = RDMA_INPUT_FORMAT_RGB565;
700 break;
701 case eRGB888:
702 rdma_fmt = RDMA_INPUT_FORMAT_RGB888;
703 break;
704 case eBGR565:
705 rdma_fmt = RDMA_INPUT_FORMAT_BGR565;
706 break;
707 case eBGR888:
708 rdma_fmt = RDMA_INPUT_FORMAT_BGR888;
709 break;
710
711 case eARGB8888:
712 case ePARGB8888:
713 case eXARGB8888:
714 rdma_fmt = RDMA_INPUT_FORMAT_ARGB;
715 break;
716 case eABGR8888:
717 case ePABGR8888:
718 case eXABGR8888:
719 rdma_fmt = RDMA_INPUT_FORMAT_ABGR;
720 break;
721
722 case eYUY2:
723 rdma_fmt = RDMA_INPUT_FORMAT_YUYV;
724 break;
725 case eUYVY:
726 rdma_fmt = RDMA_INPUT_FORMAT_UYVY;
727 break;
728 case eYVYU:
729 rdma_fmt = RDMA_INPUT_FORMAT_YVYU;
730 break;
731 case eVYUY:
732 rdma_fmt = RDMA_INPUT_FORMAT_VYUY;
733 break;
734 default:
735 printk("error: rdma_fmt_convert fmt=%d, rdma_fmt=%d \n", fmt, rdma_fmt);
736 }
737 return rdma_fmt;
738}
739
740enum RDMA_OUTPUT_FORMAT rdma_output_fmt_convert(DpColorFormat fmt)
741{
742 enum RDMA_OUTPUT_FORMAT rdma_fmt = RDMA_OUTPUT_FORMAT_ARGB;
743 switch(fmt)
744 {
745 case eRGB565 :
746 rdma_fmt = RDMA_OUTPUT_FORMAT_ARGB ; break;
747 //case eYUV_444_1P :
748 // rdma_fmt = RDMA_OUTPUT_FORMAT_YUV444 ; break;
749 default:
750 printk("error: rdma_fmt_convert fmt=%d, rdma_fmt=%d \n", fmt, rdma_fmt);
751 }
752
753 return rdma_fmt;
754}
755