Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(564)

Side by Side Diff: drivers/media/video/samsung/tv20/vprocessor_s5pv210.c

Issue 2036011: V4L/DVB : Add S5PV210 TV out driver support (Closed) Base URL: swsolcc@12.23.106.100:kernel-samsung.git
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « drivers/media/video/samsung/tv20/vp_coeff_s5pv210.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* linux/drivers/media/video/samsung/tv20/vprocessor_s5pv210.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - Video Processor raw ftn file for Samsung TVOut driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
16 #include <linux/string.h>
17 #include <linux/delay.h>
18 #include <linux/platform_device.h>
19 #include <linux/clk.h>
20
21 #include <plat/clock.h>
22 #include <linux/io.h>
23
24 #include "tv_out_s5pv210.h"
25
26 #include <mach/regs-vprocessor.h>
27 #include "vp_coeff_s5pv210.h"
28
29 #ifdef CONFIG_TVOUT_RAW_DBG
30 #define S5P_VP_DEBUG 1
31 #endif
32
33 #ifdef S5P_VP_DEBUG
34 #define VPPRINTK(fmt, args...) \
35 printk(KERN_INFO "\t\t[VP] %s: " fmt, __func__ , ## args)
36 #else
37 #define VPPRINTK(fmt, args...)
38 #endif
39
40 static struct resource *vp_mem;
41 void __iomem *vp_base;
42
43 /*
44 * set
45 * - set functions are only called under running video processor
46 * - after running set functions,
47 * it is need to run tv_vp_update() function
48 * for update shadow registers
49 */
50 void tv_vp_set_field_id(enum s5p_vp_field mode)
51 {
52 VPPRINTK("%d\n\r", mode);
53
54 writel((mode == VPROC_TOP_FIELD) ?
55 vp_base + S5P_VP_FIELD_ID_TOP :
56 vp_base + S5P_VP_FIELD_ID_BOTTOM,
57 vp_base + S5P_VP_FIELD_ID);
58
59 VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_VP_FIELD_ID));
60 }
61
62 enum s5p_tv_vp_err tv_vp_set_top_field_address(u32 top_y_addr, u32 top_c_addr)
63 {
64 VPPRINTK("0x%x,0x%x\n\r", top_y_addr, top_c_addr);
65
66 if (VP_PTR_ILLEGAL(top_y_addr) || VP_PTR_ILLEGAL(top_c_addr)) {
67 VPPRINTK(" address is not double word align = 0x%x,0x%x\n\r",
68 top_y_addr, top_c_addr);
69 return S5P_TV_VP_ERR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN;
70 }
71
72 writel(top_y_addr, vp_base + S5P_VP_TOP_Y_PTR);
73
74 writel(top_c_addr, vp_base + S5P_VP_TOP_C_PTR);
75
76 VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_TOP_Y_PTR),
77 readl(vp_base + S5P_VP_TOP_C_PTR));
78
79 return VPROC_NO_ERROR;
80 }
81
82 enum s5p_tv_vp_err tv_vp_set_bottom_field_address(
83 u32 bottom_y_addr, u32 bottom_c_addr)
84 {
85 VPPRINTK("0x%x,0x%x\n\r", bottom_y_addr, bottom_c_addr);
86
87 if (VP_PTR_ILLEGAL(bottom_y_addr) || VP_PTR_ILLEGAL(bottom_c_addr)) {
88 VPPRINTK(" address is not double word align = 0x%x,0x%x\n\r",
89 bottom_y_addr, bottom_c_addr);
90 return S5P_TV_VP_ERR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN;
91 }
92
93 writel(bottom_y_addr, vp_base + S5P_VP_BOT_Y_PTR);
94
95 writel(bottom_c_addr, vp_base + S5P_VP_BOT_C_PTR);
96
97 VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_BOT_Y_PTR),
98 readl(vp_base + S5P_VP_BOT_C_PTR));
99
100 return VPROC_NO_ERROR;
101 }
102
103 /* TO-DO :: VP_TILE_SIZE_Y, vp_base+S5P_VP_IMG_SIZE_Y --> what is diff.? */
104 enum s5p_tv_vp_err tv_vp_set_img_size(u32 img_width, u32 img_height)
105 {
106 VPPRINTK("%d,%d\n\r", img_width, img_height);
107
108 if (VP_IMG_SIZE_ILLEGAL(img_width) ||
109 VP_IMG_SIZE_ILLEGAL(img_height)) {
110 VPPRINTK("image full size is not double word align = %d,%d\n\r",
111 img_width, img_height);
112 return S5P_TV_VP_ERR_BASE_ADDRESS_MUST_DOUBLE_WORD_ALIGN;
113 }
114
115 writel(VP_IMG_HSIZE(img_width) | VP_IMG_VSIZE(img_height),
116 vp_base + S5P_VP_IMG_SIZE_Y);
117
118 writel(VP_IMG_HSIZE(img_width) | VP_IMG_VSIZE(img_height / 2),
119 vp_base + S5P_VP_IMG_SIZE_C);
120
121 VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_IMG_SIZE_Y),
122 readl(vp_base + S5P_VP_IMG_SIZE_C));
123
124 return VPROC_NO_ERROR;
125 }
126
127 void tv_vp_set_src_position(u32 src_off_x,
128 u32 src_x_fract_step,
129 u32 src_off_y)
130 {
131 VPPRINTK("%d,%d,%d)\n\r", src_off_x, src_x_fract_step, src_off_y);
132
133 writel(VP_SRC_H_POSITION(src_off_x) |
134 VP_SRC_X_FRACT_STEP(src_x_fract_step),
135 vp_base + S5P_VP_SRC_H_POSITION);
136 writel(VP_SRC_V_POSITION(src_off_y), vp_base + S5P_VP_SRC_V_POSITION);
137
138 VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_SRC_H_POSITION),
139 readl(vp_base + S5P_VP_SRC_V_POSITION));
140 }
141
142 void tv_vp_set_dest_position(u32 dst_off_x,
143 u32 dst_off_y)
144 {
145 VPPRINTK("%d,%d)\n\r", dst_off_x, dst_off_y);
146
147
148 writel(VP_DST_H_POSITION(dst_off_x), vp_base + S5P_VP_DST_H_POSITION);
149 writel(VP_DST_V_POSITION(dst_off_y), vp_base + S5P_VP_DST_V_POSITION);
150
151 VPPRINTK("0x%x,0x%x\n\r", readl(vp_base + S5P_VP_DST_H_POSITION),
152 readl(vp_base + S5P_VP_DST_V_POSITION));
153 }
154
155 void tv_vp_set_src_dest_size(u32 src_width,
156 u32 src_height,
157 u32 dst_width,
158 u32 dst_height,
159 bool ipc_2d)
160 {
161 u32 h_ratio = (src_width << 16) / dst_width;
162 u32 v_ratio = (ipc_2d) ?
163 ((src_height << 17) / dst_height) :
164 ((src_height << 16) / dst_height);
165
166 VPPRINTK("(%d,%d,%d,%d)++\n\r", src_width, src_height,
167 dst_width, dst_height);
168
169 writel(VP_SRC_WIDTH(src_width), vp_base + S5P_VP_SRC_WIDTH);
170 writel(VP_SRC_HEIGHT(src_height), vp_base + S5P_VP_SRC_HEIGHT);
171 writel(VP_DST_WIDTH(dst_width), vp_base + S5P_VP_DST_WIDTH);
172 writel(VP_DST_HEIGHT(dst_height), vp_base + S5P_VP_DST_HEIGHT) ;
173 writel(VP_H_RATIO(h_ratio), vp_base + S5P_VP_H_RATIO);
174 writel(VP_V_RATIO(v_ratio), vp_base + S5P_VP_V_RATIO);
175
176 writel((ipc_2d) ? (readl(vp_base + S5P_VP_MODE) | VP_2D_IPC_ON) :
177 (readl(vp_base + S5P_VP_MODE) & ~VP_2D_IPC_ON),
178 vp_base + S5P_VP_MODE);
179
180 VPPRINTK("%d,%d,%d,%d,0x%x,0x%x\n\r", readl(vp_base + S5P_VP_SRC_WIDTH),
181 readl(vp_base + S5P_VP_SRC_HEIGHT),
182 readl(vp_base + S5P_VP_DST_WIDTH),
183 readl(vp_base + S5P_VP_DST_HEIGHT),
184 readl(vp_base + S5P_VP_H_RATIO),
185 readl(vp_base + S5P_VP_V_RATIO));
186 }
187
188 enum s5p_tv_vp_err tv_vp_set_poly_filter_coef(enum s5p_vp_poly_coeff poly_coeff,
189 signed char ch0,
190 signed char ch1,
191 signed char ch2,
192 signed char ch3)
193 {
194 VPPRINTK("%d,%d,%d,%d,%d)\n\r", poly_coeff, ch0, ch1, ch2, ch3);
195
196 if (poly_coeff > VPROC_POLY4_C1_HH || poly_coeff < VPROC_POLY8_Y0_LL ||
197 (poly_coeff > VPROC_POLY8_Y3_HH &&
198 poly_coeff < VPROC_POLY4_Y0_LL)) {
199
200 VPPRINTK("invaild poly_coeff parameter \n\r");
201 return S5P_TV_VP_ERR_INVALID_PARAM;
202 }
203
204 writel((((0xff&ch0) << 24) | ((0xff&ch1) << 16) |
205 ((0xff&ch2) << 8) | (0xff&ch3)),
206 vp_base + S5P_VP_POLY8_Y0_LL + poly_coeff*4);
207
208 VPPRINTK("0x%08x, 0x%08x\n\r",
209 readl(vp_base + S5P_VP_POLY8_Y0_LL + poly_coeff*4),
210 vp_base + S5P_VP_POLY8_Y0_LL + poly_coeff*4);
211
212 return VPROC_NO_ERROR;
213 }
214
215 void tv_vp_set_poly_filter_coef_default(u32 h_ratio, u32 v_ratio)
216 {
217 enum s5p_tv_vp_filter_h_pp e_h_filter;
218 enum s5p_tv_vp_filter_v_pp e_v_filter;
219 u8 *poly_flt_coeff;
220 int i, j;
221
222 VPPRINTK("%d,%d\n\r", h_ratio, v_ratio);
223
224 /*
225 * For the real interlace mode,
226 * the vertical ratio should be used after divided by 2.
227 * Because in the interlace mode,
228 * all the VP output is used for SDOUT display
229 * and it should be the same as one field of the progressive mode.
230 * Therefore the same filter coefficients should be used
231 * for the same the final output video.
232 * When half of the interlace V_RATIO is
233 * same as the progressive V_RATIO,
234 * the final output video scale is same. (20051104,ishan)
235 */
236
237 /*Horizontal Y 8tap */
238 /*Horizontal C 4tap */
239 /* if (h_ratio <= 0x200) */ /* 720->720 or zoom in */
240
241 if (h_ratio <= (0x1 << 16)) { /* 720->720 or zoom in */
242 e_h_filter = VPROC_PP_H_NORMAL;
243 }
244
245 /* else if (h_ratio <= 0x240) */ /* 720->640 */ /* ?? */
246 else if (h_ratio <= (0x9 << 13)) /* 720->640 */ /* ?? */
247 e_h_filter = VPROC_PP_H_8_9 ;
248
249 /* else if(h_ratio <= 0x400) */ /* 2->1 */ /* 2 */
250 else if (h_ratio <= (0x1 << 17)) /* 2->1 */ /* 2 */
251 e_h_filter = VPROC_PP_H_1_2;
252
253 /* else if (h_ratio <= 0x600) */ /* 3->1 */ /* 3 */
254 else if (h_ratio <= (0x3 << 16)) /* 2->1 */ /* 2 */
255 e_h_filter = VPROC_PP_H_1_3;
256 else /* 0x800 */
257 e_h_filter = VPROC_PP_H_1_4; /* 4->1 */ /* 4 */
258
259 /* Vertical Y 4tap */
260 /* if (v_ratio <= 0x100) */ /* 720->720 or zoom in*/
261 if (v_ratio <= (0x1 << 16)) /* 720->720 or zoom in*/
262 e_v_filter = VPROC_PP_V_NORMAL;
263 else if (v_ratio <= (0x5 << 14)) /* 4->3*/
264 e_v_filter = VPROC_PP_V_3_4;
265 else if (v_ratio <= (0x3 << 15)) /*6->5*/
266 e_v_filter = VPROC_PP_V_5_6;
267 else if (v_ratio <= (0x1 << 17)) /* 2->1*/
268 e_v_filter = VPROC_PP_V_1_2;
269 else if (v_ratio <= (0x3 << 16)) /* 3->1*/
270 e_v_filter = VPROC_PP_V_1_3;
271 else /* 0x400 */ /* 4->1*/
272 e_v_filter = VPROC_PP_V_1_4;
273
274 poly_flt_coeff = (u8 *)(g_s_vp8tap_coef_y_h + e_h_filter * 16 * 8);
275
276 for (i = 0; i < 4; i++) {
277 for (j = 0; j < 4; j++) {
278 tv_vp_set_poly_filter_coef(
279 VPROC_POLY8_Y0_LL + (i*4) + j,
280 *(poly_flt_coeff + 4*j*8 + (7 - i)),
281 *(poly_flt_coeff + (4*j + 1)*8 + (7 - i)),
282 *(poly_flt_coeff + (4*j + 2)*8 + (7 - i)),
283 *(poly_flt_coeff + (4*j + 3)*8 + (7 - i)));
284 }
285 }
286
287 poly_flt_coeff = (u8 *)(g_s_vp4tap_coef_c_h + e_h_filter * 16 * 4);
288
289 for (i = 0; i < 2; i++) {
290 for (j = 0; j < 4; j++) {
291 tv_vp_set_poly_filter_coef(
292 VPROC_POLY4_C0_LL + (i*4) + j,
293 *(poly_flt_coeff + 4*j*4 + (3 - i)),
294 *(poly_flt_coeff + (4*j + 1)*4 + (3 - i)),
295 *(poly_flt_coeff + (4*j + 2)*4 + (3 - i)),
296 *(poly_flt_coeff + (4*j + 3)*4 + (3 - i)));
297 }
298 }
299
300 poly_flt_coeff = (u8 *)(g_s_vp4tap_coef_y_v + e_v_filter * 16 * 4);
301
302 for (i = 0; i < 4; i++) {
303 for (j = 0; j < 4; j++) {
304 tv_vp_set_poly_filter_coef(
305 VPROC_POLY4_Y0_LL + (i*4) + j,
306 *(poly_flt_coeff + 4*j*4 + (3 - i)),
307 *(poly_flt_coeff + (4*j + 1)*4 + (3 - i)),
308 *(poly_flt_coeff + (4*j + 2)*4 + (3 - i)),
309 *(poly_flt_coeff + (4*j + 3)*4 + (3 - i)));
310 }
311 }
312
313 VPPRINTK("%d,%d\n\r", e_h_filter, e_v_filter);
314 }
315
316 void tv_vp_set_src_dest_size_with_default_poly_filter_coef(u32 src_width,
317 u32 src_height,
318 u32 dst_width,
319 u32 dst_height,
320 bool ipc_2d)
321 {
322 u32 h_ratio = (src_width << 16) / dst_width;
323 u32 v_ratio = (ipc_2d) ? ((src_height << 17) / dst_height) :
324 ((src_height << 16) / dst_height);
325
326 tv_vp_set_src_dest_size(src_width, src_height,
327 dst_width, dst_height, ipc_2d);
328 tv_vp_set_poly_filter_coef_default(h_ratio, v_ratio);
329 }
330
331 enum s5p_tv_vp_err tv_vp_set_brightness_contrast_control(
332 enum s5p_vp_line_eq eq_num,
333 u32 intc,
334 u32 slope)
335 {
336 VPPRINTK("%d,%d,%d\n\r", eq_num, intc, slope);
337
338 if (eq_num > VProc_LINE_EQ_7 || eq_num < VProc_LINE_EQ_0) {
339 VPPRINTK("invaild eq_num parameter \n\r");
340 return S5P_TV_VP_ERR_INVALID_PARAM;
341 }
342
343 writel(VP_LINE_INTC(intc) | VP_LINE_SLOPE(slope),
344
345 vp_base + S5P_PP_LINE_EQ0 + eq_num*4);
346
347 VPPRINTK("0x%08x, 0x%08x\n\r",
348 readl(vp_base + S5P_PP_LINE_EQ0 + eq_num*4),
349 vp_base + S5P_PP_LINE_EQ0 + eq_num*4);
350
351 return VPROC_NO_ERROR;
352 }
353
354 void tv_vp_set_brightness(bool brightness)
355 {
356 unsigned short i;
357
358 VPPRINTK("%d\n\r", brightness);
359
360 g_vp_contrast_brightness =
361 VP_LINE_INTC_CLEAR(g_vp_contrast_brightness) |
362 VP_LINE_INTC(brightness);
363
364 for (i = 0; i < 8; i++) {
365 writel(g_vp_contrast_brightness,
366 vp_base + S5P_PP_LINE_EQ0 + i*4);
367 }
368
369 VPPRINTK("%d\n\r", g_vp_contrast_brightness);
370 }
371
372 void tv_vp_set_contrast(u8 contrast)
373 {
374 unsigned short i;
375
376 VPPRINTK("%d\n\r", contrast);
377
378 g_vp_contrast_brightness =
379 VP_LINE_SLOPE_CLEAR(g_vp_contrast_brightness) |
380 VP_LINE_SLOPE(contrast);
381
382 for (i = 0; i < 8; i++) {
383 writel(g_vp_contrast_brightness,
384 vp_base + S5P_PP_LINE_EQ0 + i*4);
385 }
386
387 VPPRINTK("%d\n\r", g_vp_contrast_brightness);
388 }
389
390 enum s5p_tv_vp_err tv_vp_update(void)
391 {
392 VPPRINTK("()\n\r");
393
394 writel(readl(vp_base + S5P_VP_SHADOW_UPDATE) |
395 S5P_VP_SHADOW_UPDATE_ENABLE,
396 vp_base + S5P_VP_SHADOW_UPDATE);
397
398 VPPRINTK("()\n\r");
399
400 return VPROC_NO_ERROR;
401 }
402
403 enum s5p_vp_field tv_vp_get_field_id(void)
404 {
405 VPPRINTK("()\n\r");
406 return ((readl(vp_base + S5P_VP_FIELD_ID) == S5P_VP_FIELD_ID_BOTTOM) ?
407 VPROC_BOTTOM_FIELD : VPROC_TOP_FIELD);
408 }
409
410 unsigned short tv_vp_get_update_status(void)
411 {
412 VPPRINTK("()\n\r");
413 return readl(vp_base + S5P_VP_SHADOW_UPDATE) &
414 S5P_VP_SHADOW_UPDATE_ENABLE;
415 }
416
417 /*
418 * initialization - iniization functions are
419 only called under stopping video processor
420 */
421 void tv_vp_init_field_id(enum s5p_vp_field mode)
422 {
423 tv_vp_set_field_id(mode);
424 }
425
426 void tv_vp_init_op_mode(bool line_skip,
427 enum s5p_vp_mem_mode mem_mode,
428 enum s5p_vp_chroma_expansion chroma_exp,
429 enum s5p_vp_filed_id_toggle toggle_id)
430 {
431 u32 temp_reg;
432 VPPRINTK("%d,%d,%d,%d\n\r", line_skip, mem_mode, chroma_exp, toggle_id);
433
434 temp_reg = (line_skip) ? VP_LINE_SKIP_ON : VP_LINE_SKIP_OFF;
435 temp_reg |= (mem_mode == VPROC_2D_TILE_MODE) ?
436 VP_MEM_2D_MODE : VP_MEM_LINEAR_MODE;
437 temp_reg |= (chroma_exp == VPROC_USING_C_TOP_BOTTOM) ?
438 VP_CHROMA_USE_TOP_BOTTOM : VP_CHROMA_USE_TOP;
439 temp_reg |= (toggle_id == S5P_TV_VP_FILED_ID_TOGGLE_VSYNC) ?
440 VP_FIELD_ID_TOGGLE_VSYNC : VP_FIELD_ID_TOGGLE_USER;
441
442 writel(temp_reg, vp_base + S5P_VP_MODE);
443 VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_VP_MODE));
444 }
445
446 void tv_vp_init_pixel_rate_control(enum s5p_vp_pxl_rate rate)
447 {
448 VPPRINTK("%d\n\r", rate);
449
450 writel(VP_PEL_RATE_CTRL(rate), vp_base + S5P_VP_PER_RATE_CTRL);
451
452 VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_VP_PER_RATE_CTRL));
453 }
454
455 enum s5p_tv_vp_err tv_vp_init_layer(u32 top_y_addr,
456 u32 top_c_addr,
457 u32 bottom_y_addr,
458 u32 bottom_c_addr,
459 enum s5p_endian_type src_img_endian,
460 u32 img_width,
461 u32 img_height,
462 u32 src_off_x,
463 u32 src_x_fract_step,
464 u32 src_off_y,
465 u32 src_width,
466 u32 src_height,
467 u32 dst_off_x,
468 u32 dst_off_y,
469 u32 dst_width,
470 u32 dst_height,
471 bool ipc_2d)
472 {
473 enum s5p_tv_vp_err error = VPROC_NO_ERROR;
474
475 VPPRINTK("%d\n\r", src_img_endian);
476
477 writel(1, vp_base + S5P_VP_ENDIAN_MODE);
478
479 error = tv_vp_set_top_field_address(top_y_addr, top_c_addr);
480
481 if (error != VPROC_NO_ERROR)
482 return error;
483
484 error = tv_vp_set_bottom_field_address(bottom_y_addr, bottom_c_addr);
485
486 if (error != VPROC_NO_ERROR)
487 return error;
488
489 error = tv_vp_set_img_size(img_width, img_height);
490
491 if (error != VPROC_NO_ERROR)
492 return error;
493
494 tv_vp_set_src_position(src_off_x, src_x_fract_step, src_off_y);
495
496 tv_vp_set_dest_position(dst_off_x, dst_off_y);
497
498 tv_vp_set_src_dest_size(
499 src_width, src_height, dst_width, dst_height, ipc_2d);
500
501 VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_VP_ENDIAN_MODE));
502
503 return error;
504
505 }
506
507 enum s5p_tv_vp_err tv_vp_init_layer_def_poly_filter_coef(
508 u32 top_y_addr,
509 u32 top_c_addr,
510 u32 bottom_y_addr,
511 u32 bottom_c_addr,
512 enum s5p_endian_type src_img_endian,
513 u32 img_width,
514 u32 img_height,
515 u32 src_off_x,
516 u32 src_x_fract_step,
517 u32 src_off_y,
518 u32 src_width,
519 u32 src_height,
520 u32 dst_off_x,
521 u32 dst_off_y,
522 u32 dst_width,
523 u32 dst_height,
524 bool ipc_2d)
525 {
526 enum s5p_tv_vp_err error = VPROC_NO_ERROR;
527
528 u32 h_ratio = (src_width << 16) / dst_width;
529 u32 v_ratio = (ipc_2d) ? ((src_height << 17) / dst_height) :
530 ((src_height << 16) / dst_height);
531
532 tv_vp_set_poly_filter_coef_default(h_ratio, v_ratio);
533 error = tv_vp_init_layer(top_y_addr, top_c_addr,
534 bottom_y_addr, bottom_c_addr,
535 src_img_endian,
536 img_width, img_height,
537 src_off_x, src_x_fract_step, src_off_y,
538 src_width, src_height,
539 dst_off_x, dst_off_y,
540 dst_width, dst_height,
541 ipc_2d);
542 return error;
543 }
544
545 enum s5p_tv_vp_err tv_vp_init_poly_filter_coef(
546 enum s5p_vp_poly_coeff poly_coeff,
547 signed char ch0,
548 signed char ch1,
549 signed char ch2,
550 signed char ch3)
551 {
552 return tv_vp_set_poly_filter_coef(poly_coeff, ch0, ch1, ch2, ch3);
553 }
554
555 void tv_vp_init_bypass_post_process(bool bypass)
556 {
557 VPPRINTK("%d\n\r", bypass);
558
559 writel((bypass) ? VP_BY_PASS_ENABLE : VP_BY_PASS_DISABLE,
560 vp_base + S5P_PP_BYPASS);
561
562 VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_BYPASS));
563 }
564
565 enum s5p_tv_vp_err tv_vp_init_csc_coef(
566 enum s5p_vp_csc_coeff csc_coeff, u32 coeff)
567 {
568 VPPRINTK("%d,%d\n\r", csc_coeff, coeff);
569
570 if (csc_coeff > VPROC_CSC_CR2CR_COEF ||
571 csc_coeff < VPROC_CSC_Y2Y_COEF) {
572 VPPRINTK("invaild csc_coeff parameter \n\r");
573 return S5P_TV_VP_ERR_INVALID_PARAM;
574 }
575
576 writel(VP_CSC_COEF(coeff),
577 vp_base + S5P_PP_CSC_Y2Y_COEF + csc_coeff*4);
578
579 VPPRINTK("0x%08x\n\r",
580 readl(vp_base + S5P_PP_CSC_Y2Y_COEF + csc_coeff*4));
581
582 return VPROC_NO_ERROR;
583 }
584
585 void tv_vp_init_saturation(u32 sat)
586 {
587 VPPRINTK("%d\n\r", sat);
588
589 writel(VP_SATURATION(sat), vp_base + S5P_PP_SATURATION);
590
591 VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_SATURATION));
592 }
593
594 void tv_vp_init_sharpness(u32 th_h_noise,
595 enum s5p_vp_sharpness_control sharpness)
596 {
597 VPPRINTK("%d,%d\n\r", th_h_noise, sharpness);
598
599 writel(VP_TH_HNOISE(th_h_noise) | VP_SHARPNESS(sharpness),
600 vp_base + S5P_PP_SHARPNESS);
601
602 VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_SHARPNESS));
603 }
604
605 enum s5p_tv_vp_err tv_vp_init_brightness_contrast_control(
606 enum s5p_vp_line_eq eq_num,
607 u32 intc,
608 u32 slope)
609 {
610 return tv_vp_set_brightness_contrast_control(eq_num, intc, slope);
611 }
612
613 void tv_vp_init_brightness(bool brightness)
614 {
615 tv_vp_set_brightness(brightness);
616 }
617
618
619 void tv_vp_init_contrast(u8 contrast)
620 {
621 tv_vp_set_contrast(contrast);
622 }
623
624 void tv_vp_init_brightness_offset(u32 offset)
625 {
626 VPPRINTK("%d\n\r", offset);
627
628 writel(VP_BRIGHT_OFFSET(offset), vp_base + S5P_PP_BRIGHT_OFFSET);
629
630 VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_BRIGHT_OFFSET));
631 }
632
633 void tv_vp_init_csc_control(bool sub_y_offset_en, bool csc_en)
634 {
635 u32 temp_reg;
636 VPPRINTK("%d,%d\n\r", sub_y_offset_en, csc_en);
637
638 temp_reg = (sub_y_offset_en) ? VP_SUB_Y_OFFSET_ENABLE :
639 VP_SUB_Y_OFFSET_DISABLE;
640 temp_reg |= (csc_en) ? VP_CSC_ENABLE : VP_CSC_DISABLE;
641 writel(temp_reg, vp_base + S5P_PP_CSC_EN);
642
643 VPPRINTK("0x%08x\n\r", readl(vp_base + S5P_PP_CSC_EN));
644 }
645
646 enum s5p_tv_vp_err tv_vp_init_csc_coef_default(enum s5p_vp_csc_type csc_type)
647 {
648 VPPRINTK("%d\n\r", csc_type);
649
650 switch (csc_type) {
651
652 case VPROC_CSC_SD_HD:
653 writel(Y2Y_COEF_601_TO_709, vp_base + S5P_PP_CSC_Y2Y_COEF);
654 writel(CB2Y_COEF_601_TO_709, vp_base + S5P_PP_CSC_CB2Y_COEF);
655 writel(CR2Y_COEF_601_TO_709, vp_base + S5P_PP_CSC_CR2Y_COEF);
656 writel(Y2CB_COEF_601_TO_709, vp_base + S5P_PP_CSC_Y2CB_COEF);
657 writel(CB2CB_COEF_601_TO_709, vp_base + S5P_PP_CSC_CB2CB_COEF);
658 writel(CR2CB_COEF_601_TO_709, vp_base + S5P_PP_CSC_CR2CB_COEF);
659 writel(Y2CR_COEF_601_TO_709, vp_base + S5P_PP_CSC_Y2CR_COEF);
660 writel(CB2CR_COEF_601_TO_709, vp_base + S5P_PP_CSC_CB2CR_COEF);
661 writel(CR2CR_COEF_601_TO_709, vp_base + S5P_PP_CSC_CR2CR_COEF);
662 break;
663
664 case VPROC_CSC_HD_SD:
665 writel(Y2Y_COEF_709_TO_601, vp_base + S5P_PP_CSC_Y2Y_COEF);
666 writel(CB2Y_COEF_709_TO_601, vp_base + S5P_PP_CSC_CB2Y_COEF);
667 writel(CR2Y_COEF_709_TO_601, vp_base + S5P_PP_CSC_CR2Y_COEF);
668 writel(Y2CB_COEF_709_TO_601, vp_base + S5P_PP_CSC_Y2CB_COEF);
669 writel(CB2CB_COEF_709_TO_601, vp_base + S5P_PP_CSC_CB2CB_COEF);
670 writel(CR2CB_COEF_709_TO_601, vp_base + S5P_PP_CSC_CR2CB_COEF);
671 writel(Y2CR_COEF_709_TO_601, vp_base + S5P_PP_CSC_Y2CR_COEF);
672 writel(CB2CR_COEF_709_TO_601, vp_base + S5P_PP_CSC_CB2CR_COEF);
673 writel(CR2CR_COEF_709_TO_601, vp_base + S5P_PP_CSC_CR2CR_COEF);
674 break;
675
676 default:
677 VPPRINTK("invalid csc_type parameter = %d\n\r", csc_type);
678 return S5P_TV_VP_ERR_INVALID_PARAM;
679 }
680
681 VPPRINTK("0x%08x,0x%08x,0x%08x,0x%08x,0x%08x, \
682 0x%08x,0x%08x,0x%08x,0x%08x)\n\r",
683 readl(vp_base + S5P_PP_CSC_Y2Y_COEF),
684 readl(vp_base + S5P_PP_CSC_CB2Y_COEF),
685 readl(vp_base + S5P_PP_CSC_CR2Y_COEF),
686 readl(vp_base + S5P_PP_CSC_Y2CB_COEF),
687 readl(vp_base + S5P_PP_CSC_CB2CB_COEF),
688 readl(vp_base + S5P_PP_CSC_CR2CB_COEF),
689 readl(vp_base + S5P_PP_CSC_Y2CR_COEF),
690 readl(vp_base + S5P_PP_CSC_CB2CR_COEF),
691 readl(vp_base + S5P_PP_CSC_CR2CR_COEF));
692
693 return VPROC_NO_ERROR;
694 }
695
696 /*
697 * start - start functions are only called under stopping video processor
698 */
699 enum s5p_tv_vp_err tv_vp_start(void)
700 {
701 enum s5p_tv_vp_err error = VPROC_NO_ERROR;
702
703 VPPRINTK("()\n\r");
704
705 writel(VP_ON_ENABLE, vp_base + S5P_VP_ENABLE);
706
707 error = tv_vp_update();
708
709 VPPRINTK("()\n\r");
710 return error;
711 }
712
713 /*
714 * stop - stop functions are only called under running video processor
715 */
716 enum s5p_tv_vp_err tv_vp_stop(void)
717 {
718 enum s5p_tv_vp_err error = VPROC_NO_ERROR;
719
720 VPPRINTK("()\n\r");
721
722 writel((readl(vp_base + S5P_VP_ENABLE) & ~VP_ON_ENABLE),
723 vp_base + S5P_VP_ENABLE);
724
725 error = tv_vp_update();
726
727 while (!(readl(vp_base + S5P_VP_ENABLE) & VP_POWER_DOWN_RDY))
728 msleep(1);
729
730 return error;
731 }
732
733 void tv_vp_sw_reset(void)
734 {
735 VPPRINTK("()\n\r");
736
737 writel((readl(vp_base + S5P_VP_SRESET) | VP_SOFT_RESET),
738 vp_base + S5P_VP_SRESET);
739
740 while (readl(vp_base + S5P_VP_SRESET) & VP_SOFT_RESET)
741 msleep(10);
742
743 VPPRINTK("()\n\r");
744 }
745
746 int __init tv_vp_probe(struct platform_device *pdev, u32 res_num)
747 {
748 struct resource *res;
749 size_t size;
750
751 res = platform_get_resource(pdev, IORESOURCE_MEM, res_num);
752
753 if (res == NULL) {
754 dev_err(&pdev->dev,
755 "failed to get memory region resource\n");
756 goto error;
757
758 }
759
760 size = (res->end - res->start) + 1;
761
762 vp_mem = request_mem_region(res->start, size, pdev->name);
763
764 if (vp_mem == NULL) {
765 dev_err(&pdev->dev,
766 "failed to get memory region\n");
767 goto error;
768
769 }
770
771 vp_base = ioremap(res->start, size);
772
773 if (vp_base == NULL) {
774 dev_err(&pdev->dev,
775 "failed to ioremap address region\n");
776 goto error;
777
778
779 }
780
781 return 0;
782 error:
783 return -ENOENT;
784
785 }
786
787 int __init tv_vp_release(struct platform_device *pdev)
788 {
789 iounmap(vp_base);
790
791 /* remove memory region */
792 if (vp_mem != NULL) {
793 if (release_resource(vp_mem))
794 dev_err(&pdev->dev,
795 "Can't remove tvout drv !!\n");
796
797 kfree(vp_mem);
798
799 vp_mem = NULL;
800 }
801
802 return 0;
803 }
804
OLDNEW
« no previous file with comments | « drivers/media/video/samsung/tv20/vp_coeff_s5pv210.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698