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

Side by Side Diff: drivers/media/video/samsung/tv20/vmixer_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
OLDNEW
(Empty)
1 /* linux/drivers/media/video/samsung/tv20/vmixer_s5pv210.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - Mixer 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/interrupt.h>
18 #include <linux/platform_device.h>
19 #include <linux/clk.h>
20
21 #include <plat/clock.h>
22
23 #include <linux/io.h>
24
25
26 #include "tv_out_s5pv210.h"
27
28 #include <mach/regs-vmx.h>
29
30 #include <linux/irq.h>
31 #include <linux/delay.h>
32
33 #ifdef CONFIG_TVOUT_RAW_DBG
34 #define S5P_MXR_DEBUG 1
35 #endif
36
37 #ifdef S5P_MXR_DEBUG
38 #define VMPRINTK(fmt, args...) \
39 printk(KERN_INFO "\t\t[VM] %s: " fmt, __func__ , ## args)
40 #else
41 #define VMPRINTK(fmt, args...)
42 #endif
43
44 static struct resource *mixer_mem;
45 void __iomem *mixer_base;
46
47 /*
48 *set - set functions are only called under running vmixer
49 */
50 enum s5p_tv_vmx_err tv_vm_set_layer_show(enum s5p_tv_vmx_layer layer, bool show)
51 {
52 u32 mxr_config;
53
54 VMPRINTK("%d,%d\n\r", layer, show);
55
56 switch (layer) {
57
58 case VM_VIDEO_LAYER:
59 mxr_config = (show) ?
60 (readl(mixer_base + S5P_MXR_CFG) |
61 S5P_MXR_VIDEO_LAYER_SHOW) :
62 (readl(mixer_base + S5P_MXR_CFG) &
63 ~S5P_MXR_VIDEO_LAYER_SHOW);
64 break;
65
66 case VM_GPR0_LAYER:
67 mxr_config = (show) ?
68 (readl(mixer_base + S5P_MXR_CFG) |
69 S5P_MXR_GRAPHIC0_LAYER_SHOW) :
70 (readl(mixer_base + S5P_MXR_CFG) &
71 ~S5P_MXR_GRAPHIC0_LAYER_SHOW);
72 break;
73
74 case VM_GPR1_LAYER:
75 mxr_config = (show) ?
76 (readl(mixer_base + S5P_MXR_CFG) |
77 S5P_MXR_GRAPHIC1_LAYER_SHOW) :
78 (readl(mixer_base + S5P_MXR_CFG) &
79 ~S5P_MXR_GRAPHIC1_LAYER_SHOW);
80 break;
81
82 default:
83 VMPRINTK(" invalid layer parameter = %d\n\r", layer);
84 return S5P_TV_VMX_ERR_INVALID_PARAM;
85 }
86
87 writel(mxr_config, mixer_base + S5P_MXR_CFG);
88
89 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_CFG));
90
91 return VMIXER_NO_ERROR;
92 }
93
94 enum s5p_tv_vmx_err tv_vm_set_layer_priority(enum s5p_tv_vmx_layer layer,
95 u32 priority)
96 {
97 u32 layer_cfg;
98
99 VMPRINTK("%d,%d\n\r", layer, priority);
100
101 switch (layer) {
102
103 case VM_VIDEO_LAYER:
104 layer_cfg = S5P_MXR_VP_LAYER_PRIORITY_CLEAR(readl(
105 mixer_base + S5P_MXR_LAYER_CFG)) |
106 S5P_MXR_VP_LAYER_PRIORITY(priority);
107 break;
108
109 case VM_GPR0_LAYER:
110 layer_cfg = S5P_MXR_GRP0_LAYER_PRIORITY_CLEAR(
111 readl(mixer_base + S5P_MXR_LAYER_CFG)) |
112 S5P_MXR_GRP0_LAYER_PRIORITY(priority);
113 break;
114
115 case VM_GPR1_LAYER:
116 layer_cfg = S5P_MXR_GRP1_LAYER_PRIORITY_CLEAR(
117 readl(mixer_base + S5P_MXR_LAYER_CFG)) |
118 S5P_MXR_GRP1_LAYER_PRIORITY(priority);
119 break;
120
121 default:
122 VMPRINTK(" invalid layer parameter = %d\n\r", layer);
123 return S5P_TV_VMX_ERR_INVALID_PARAM;
124 }
125
126 writel(layer_cfg, mixer_base + S5P_MXR_LAYER_CFG);
127
128 return VMIXER_NO_ERROR;
129 }
130
131 enum s5p_tv_vmx_err tv_vm_set_win_blend(enum s5p_tv_vmx_layer layer,
132 bool enable)
133 {
134 u32 temp_reg;
135 VMPRINTK("%d,%d\n\r", layer, enable);
136
137 switch (layer) {
138
139 case VM_VIDEO_LAYER:
140 temp_reg = readl(mixer_base + S5P_MXR_VIDEO_CFG)
141 & (~S5P_MXR_VP_BLEND_ENABLE) ;
142
143 if (enable)
144 temp_reg |= S5P_MXR_VP_BLEND_ENABLE;
145 else
146 temp_reg |= S5P_MXR_VP_BLEND_DISABLE;
147
148 writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG);
149
150 break;
151
152 case VM_GPR0_LAYER:
153 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)
154 & (~S5P_MXR_WIN_BLEND_ENABLE) ;
155
156 if (enable)
157 temp_reg |= S5P_MXR_WIN_BLEND_ENABLE;
158 else
159 temp_reg |= S5P_MXR_WIN_BLEND_DISABLE;
160
161 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG);
162
163 break;
164
165 case VM_GPR1_LAYER:
166 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)
167 & (~S5P_MXR_WIN_BLEND_ENABLE) ;
168
169 if (enable)
170 temp_reg |= S5P_MXR_WIN_BLEND_ENABLE;
171 else
172 temp_reg |= S5P_MXR_WIN_BLEND_DISABLE;
173
174 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG);
175
176 break;
177
178 default:
179 VMPRINTK(" invalid layer parameter = %d\n\r", layer);
180 return S5P_TV_VMX_ERR_INVALID_PARAM;
181 }
182
183 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_VIDEO_CFG));
184 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG));
185 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG));
186
187 return VMIXER_NO_ERROR;
188 }
189
190
191 enum s5p_tv_vmx_err tv_vm_set_layer_alpha(enum s5p_tv_vmx_layer layer,
192 u32 alpha)
193 {
194 u32 temp_reg;
195 VMPRINTK("%d,%d\n\r", layer, alpha);
196
197 switch (layer) {
198
199 case VM_VIDEO_LAYER:
200 temp_reg = readl(mixer_base + S5P_MXR_VIDEO_CFG)
201 & (~S5P_MXR_ALPHA) ;
202 temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha);
203 writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG);
204 break;
205
206 case VM_GPR0_LAYER:
207 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG)
208 & (~S5P_MXR_ALPHA) ;
209 temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha);
210 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG);
211 break;
212
213 case VM_GPR1_LAYER:
214 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_CFG)
215 & (~S5P_MXR_ALPHA) ;
216 temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha);
217 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG);
218 break;
219
220 default:
221 VMPRINTK(" invalid layer parameter = %d\n\r", layer);
222 return S5P_TV_VMX_ERR_INVALID_PARAM;
223 }
224
225 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_VIDEO_CFG));
226 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_CFG));
227 VMPRINTK("0x08%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_CFG));
228
229 return VMIXER_NO_ERROR;
230 }
231
232
233 enum s5p_tv_vmx_err tv_vm_set_grp_base_address(
234 enum s5p_tv_vmx_layer layer, u32 base_addr)
235 {
236 VMPRINTK("%d,0x%x\n\r", layer, base_addr);
237
238 if (S5P_MXR_GRP_ADDR_ILLEGAL(base_addr)) {
239 VMPRINTK(" address is not word align = %d\n\r", base_addr);
240 return S5P_TV_VMX_ERR_BASE_ADDRESS_MUST_WORD_ALIGN;
241 }
242
243 switch (layer) {
244
245 case VM_GPR0_LAYER:
246 writel(S5P_MXR_GPR_BASE(base_addr),
247 mixer_base + S5P_MXR_GRAPHIC0_BASE);
248 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_BASE));
249 break;
250
251 case VM_GPR1_LAYER:
252 writel(S5P_MXR_GPR_BASE(base_addr),
253 mixer_base + S5P_MXR_GRAPHIC1_BASE);
254 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_BASE));
255 break;
256
257 default:
258 VMPRINTK(" invalid layer parameter = %d\n\r", layer);
259 return S5P_TV_VMX_ERR_INVALID_PARAM;
260 }
261
262 return VMIXER_NO_ERROR;
263 }
264
265 enum s5p_tv_vmx_err tv_vm_set_grp_layer_position(enum s5p_tv_vmx_layer layer,
266 u32 dst_offs_x, u32 dst_offs_y)
267 {
268 VMPRINTK("%d,%d,%d)\n\r", layer, dst_offs_x, dst_offs_y);
269
270 switch (layer) {
271
272 case VM_GPR0_LAYER:
273 writel(S5P_MXR_GRP_DESTX(dst_offs_x) |
274 S5P_MXR_GRP_DESTY(dst_offs_y),
275 mixer_base + S5P_MXR_GRAPHIC0_DXY);
276 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC0_DXY));
277 break;
278
279 case VM_GPR1_LAYER:
280 writel(S5P_MXR_GRP_DESTX(dst_offs_x) |
281 S5P_MXR_GRP_DESTY(dst_offs_y),
282 mixer_base + S5P_MXR_GRAPHIC1_DXY);
283 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_GRAPHIC1_DXY));
284 break;
285
286 default:
287 VMPRINTK("invalid layer parameter = %d\n\r", layer);
288 return S5P_TV_VMX_ERR_INVALID_PARAM;
289 }
290
291 return VMIXER_NO_ERROR;
292 }
293
294 enum s5p_tv_vmx_err tv_vm_set_grp_layer_size(enum s5p_tv_vmx_layer layer,
295 u32 span,
296 u32 width,
297 u32 height,
298 u32 src_offs_x,
299 u32 src_offs_y)
300 {
301 VMPRINTK("%d,%d,%d,%d,%d,%d)\n\r", layer, span, width, height,
302 src_offs_x, src_offs_y);
303
304 switch (layer) {
305
306 case VM_GPR0_LAYER:
307 writel(S5P_MXR_GRP_SPAN(span),
308 mixer_base + S5P_MXR_GRAPHIC0_SPAN);
309 writel(S5P_MXR_GRP_WIDTH(width) | S5P_MXR_GRP_HEIGHT(height),
310 mixer_base + S5P_MXR_GRAPHIC0_WH);
311 writel(S5P_MXR_GRP_STARTX(src_offs_x) |
312 S5P_MXR_GRP_STARTY(src_offs_y),
313 mixer_base + S5P_MXR_GRAPHIC0_SXY);
314 VMPRINTK("0x%x,0x%x,0x%x\n\r",
315 readl(mixer_base + S5P_MXR_GRAPHIC0_SPAN),
316 readl(mixer_base + S5P_MXR_GRAPHIC0_WH),
317 readl(mixer_base + S5P_MXR_GRAPHIC0_SXY));
318 break;
319
320 case VM_GPR1_LAYER:
321 writel(S5P_MXR_GRP_SPAN(span),
322 mixer_base + S5P_MXR_GRAPHIC1_SPAN);
323 writel(S5P_MXR_GRP_WIDTH(width) | S5P_MXR_GRP_HEIGHT(height),
324 mixer_base + S5P_MXR_GRAPHIC1_WH);
325 writel(S5P_MXR_GRP_STARTX(src_offs_x) |
326 S5P_MXR_GRP_STARTY(src_offs_y),
327 mixer_base + S5P_MXR_GRAPHIC1_SXY);
328 VMPRINTK("0x%x,0x%x,0x%x\n\r",
329 readl(mixer_base + S5P_MXR_GRAPHIC1_SPAN),
330 readl(mixer_base + S5P_MXR_GRAPHIC1_WH),
331 readl(mixer_base + S5P_MXR_GRAPHIC1_SXY));
332 break;
333
334 default:
335 VMPRINTK(" invalid layer parameter = %d\n\r", layer);
336 return S5P_TV_VMX_ERR_INVALID_PARAM;
337 }
338
339 return VMIXER_NO_ERROR;
340 }
341
342 enum s5p_tv_vmx_err tv_vm_set_bg_color(enum s5p_tv_vmx_bg_color_num colornum,
343 u32 color_y,
344 u32 color_cb,
345 u32 color_cr)
346 {
347 u32 reg_value;
348 VMPRINTK("%d,%d,%d,%d)\n\r", colornum, color_y, color_cb, color_cr);
349
350 reg_value = S5P_MXR_BG_COLOR_Y(color_y) |
351 S5P_MXR_BG_COLOR_CB(color_cb) | S5P_MXR_BG_COLOR_CR(color_cr);
352
353 switch (colornum) {
354
355 case VMIXER_BG_COLOR_0:
356 writel(reg_value, mixer_base + S5P_MXR_BG_COLOR0);
357 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR0));
358 break;
359
360 case VMIXER_BG_COLOR_1:
361 writel(reg_value, mixer_base + S5P_MXR_BG_COLOR1);
362 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR1));
363 break;
364
365 case VMIXER_BG_COLOR_2:
366 writel(reg_value, mixer_base + S5P_MXR_BG_COLOR2);
367 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_BG_COLOR2));
368 break;
369
370 default:
371 VMPRINTK(" invalid uiColorNum parameter = %d\n\r", colornum);
372 return S5P_TV_VMX_ERR_INVALID_PARAM;
373 }
374
375 return VMIXER_NO_ERROR;
376 }
377
378 /*
379 * initialization - iniization functions are only called under stopping vmixer
380 */
381 enum s5p_tv_vmx_err tv_vm_init_status_reg(
382 enum s5p_vmx_burst_mode burst, enum s5p_endian_type endian)
383 {
384 u32 temp_reg = 0;
385
386 VMPRINTK("++(%d,%d)\n\r", burst, endian);
387
388 temp_reg = S5P_MXR_MIXER_RESERVED | S5P_MXR_CMU_CANNOT_STOP_CLOCK;
389
390 switch (burst) {
391
392 case VM_BURST_8:
393 temp_reg |= S5P_MXR_BURST8_MODE;
394 break;
395
396 case VM_BURST_16:
397 temp_reg |= S5P_MXR_BURST16_MODE;
398 break;
399
400 default:
401 VMPRINTK("[ERR] : invalid burst parameter = %d\n\r", burst);
402 return S5P_TV_VMX_ERR_INVALID_PARAM;
403 }
404
405 switch (endian) {
406
407 case TVOUT_BIG_ENDIAN_MODE:
408 temp_reg |= S5P_MXR_BIG_ENDIAN_SOURCE_FORMAT;
409 break;
410
411 case TVOUT_LITTLE_ENDIAN_MODE:
412 temp_reg |= S5P_MXR_LITTLE_ENDIAN_SOURCE_FORMAT;
413 break;
414
415 default:
416 VMPRINTK("[ERR] : invalid endian parameter = %d\n\r", endian);
417 return S5P_TV_VMX_ERR_INVALID_PARAM;
418 }
419
420 writel(temp_reg, mixer_base + S5P_MXR_STATUS);
421
422 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_STATUS));
423
424 return VMIXER_NO_ERROR;
425 }
426
427 enum s5p_tv_vmx_err tv_vm_init_display_mode(
428 enum s5p_tv_disp_mode mode, enum s5p_tv_o_mode output_mode)
429 {
430 u32 temp_reg = readl(mixer_base + S5P_MXR_CFG);
431
432 VMPRINTK("%d,%d)\n\r", mode, output_mode);
433
434 switch (mode) {
435
436 case TVOUT_NTSC_M:
437 case TVOUT_NTSC_443:
438 temp_reg &= ~S5P_MXR_HD;
439 temp_reg &= ~S5P_MXR_PAL;
440 temp_reg &= S5P_MXR_INTERLACE_MODE;
441 break;
442
443 case TVOUT_PAL_BDGHI:
444 case TVOUT_PAL_M:
445 case TVOUT_PAL_N:
446 case TVOUT_PAL_NC:
447 case TVOUT_PAL_60:
448 temp_reg &= ~S5P_MXR_HD;
449 temp_reg |= S5P_MXR_PAL;
450 temp_reg &= S5P_MXR_INTERLACE_MODE;
451 break;
452
453 case TVOUT_480P_60_16_9:
454 case TVOUT_480P_60_4_3:
455 case TVOUT_480P_59:
456 temp_reg &= ~S5P_MXR_HD;
457 temp_reg &= ~S5P_MXR_PAL;
458 temp_reg |= S5P_MXR_PROGRESSVE_MODE;
459 break;
460
461 case TVOUT_576P_50_16_9:
462 case TVOUT_576P_50_4_3:
463 temp_reg &= ~S5P_MXR_HD;
464 temp_reg |= S5P_MXR_PAL;
465 temp_reg |= S5P_MXR_PROGRESSVE_MODE;
466 break;
467
468 case TVOUT_720P_50:
469 case TVOUT_720P_59:
470 case TVOUT_720P_60:
471 temp_reg |= S5P_MXR_HD;
472 temp_reg &= ~S5P_MXR_HD_1080I_MODE;
473 temp_reg |= S5P_MXR_PROGRESSVE_MODE;
474 break;
475
476 case TVOUT_1080I_50:
477 case TVOUT_1080I_59:
478 case TVOUT_1080I_60:
479 temp_reg |= S5P_MXR_HD;
480 temp_reg |= S5P_MXR_HD_1080I_MODE;
481 temp_reg &= S5P_MXR_INTERLACE_MODE;
482 break;
483
484 case TVOUT_1080P_50:
485 case TVOUT_1080P_59:
486 case TVOUT_1080P_60:
487 case TVOUT_1080P_30:
488 temp_reg |= S5P_MXR_HD;
489 temp_reg |= S5P_MXR_HD_1080P_MODE;
490 temp_reg |= S5P_MXR_PROGRESSVE_MODE;
491 break;
492
493 default:
494 VMPRINTK(" invalid mode parameter = %d\n\r", mode);
495 return S5P_TV_VMX_ERR_INVALID_PARAM;
496 }
497
498 switch (output_mode) {
499
500 case TVOUT_OUTPUT_COMPOSITE:
501 case TVOUT_OUTPUT_SVIDEO:
502 case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:
503 case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:
504 case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
505 temp_reg &= S5P_MXR_DST_SEL_ANALOG;
506 break;
507
508 case TVOUT_OUTPUT_HDMI_RGB:
509 case TVOUT_OUTPUT_DVI:
510 temp_reg |= S5P_MXR_DST_SEL_HDMI;
511 temp_reg &= ~(0x7<<8);
512 temp_reg |= RGB709_16_235<<9 | MX_RGB888<<8;
513 break;
514
515 case TVOUT_OUTPUT_HDMI:
516 temp_reg |= S5P_MXR_DST_SEL_HDMI;
517 temp_reg &= ~(0x7<<8);
518 temp_reg |= RGB601_16_235<<9 | MX_YUV444<<8;
519 break;
520
521 default:
522 VMPRINTK(" invalid mode parameter = %d\n\r", mode);
523 return S5P_TV_VMX_ERR_INVALID_PARAM;
524 }
525
526 writel(temp_reg, mixer_base + S5P_MXR_CFG);
527
528 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CFG));
529
530 return VMIXER_NO_ERROR;
531 }
532
533 u32 grp_scaling_factor(u32 src, u32 dst, u32 h_v)
534 {
535 u32 factor; /* for scaling factor */
536
537 /* check scale or not */
538 if (src == dst)
539 factor = 0;
540
541 if (dst % src) {
542 factor = 0;
543
544 VMPRINTK(" can't %s scaling src(%d) into dst(%d)\n"
545 , h_v ? "horizontal" : "vertical"
546 , src_w, dst_w);
547 VMPRINTK(" scaling vector must be 2/4/8x\n");
548 }
549
550 factor = dst / src;
551
552 switch (factor) {
553 case 2:
554 factor = 1;
555 break;
556
557 case 4:
558 factor = 2;
559 break;
560
561 case 8:
562 factor = 3;
563 break;
564
565 default:
566 VMPRINTK(" scaling vector must be 2/4/8x\n");
567 factor = 0;
568 break;
569 }
570
571 return factor;
572 }
573
574 void tv_vm_set_ctrl(enum s5p_tv_vmx_layer layer,
575 bool premul,
576 bool pixel_blending,
577 bool blank_change,
578 bool win_blending,
579 enum s5p_tv_vmx_color_fmt color,
580 u32 alpha, u32 blank_color)
581 {
582 u32 reg = readl(mixer_base + S5P_MXR_GRAPHIC0_CFG);
583
584 if (blank_change)
585 reg &= ~S5P_MXR_BLANK_CHANGE_NEW_PIXEL;
586 else
587 reg |= S5P_MXR_BLANK_CHANGE_NEW_PIXEL;
588
589
590 if (premul)
591 reg |= S5P_MXR_PRE_MUL_MODE;
592 else
593 reg &= ~S5P_MXR_PRE_MUL_MODE;
594
595 if (win_blending)
596 reg |= S5P_MXR_WIN_BLEND_ENABLE;
597 else
598 reg &= ~S5P_MXR_WIN_BLEND_ENABLE;
599
600 reg &= ~S5P_MXR_EG_COLOR_FORMAT(VM_DIRECT_RGB8888);
601 reg |= S5P_MXR_EG_COLOR_FORMAT(color);
602
603 reg &= ~S5P_MXR_GRP_ALPHA_VALUE(0xff);
604 reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha);
605
606 writel(reg, mixer_base + S5P_MXR_GRAPHIC0_CFG);
607 writel(S5P_MXR_GPR_BLANK_COLOR(blank_color),
608 mixer_base + S5P_MXR_GRAPHIC0_BLANK);
609
610 }
611
612 enum s5p_tv_vmx_err tv_vm_init_layer(enum s5p_tv_disp_mode mode,
613 enum s5p_tv_vmx_layer layer,
614 bool show,
615 bool win_blending,
616 u32 alpha,
617 u32 priority,
618 enum s5p_tv_vmx_color_fmt color,
619 bool blank_change,
620 bool pixel_blending,
621 bool premul,
622 u32 blank_color,
623 u32 base_addr,
624 u32 span,
625 u32 width,
626 u32 height,
627 u32 src_offs_x,
628 u32 src_offs_y,
629 u32 dst_offs_x,
630 u32 dst_offs_y,
631 u32 dst_width,
632 u32 dst_height)
633 {
634 u32 temp_reg = 0;
635 u32 h_factor = 0, v_factor = 0;
636
637 VMPRINTK("%d,%d,%d,%d,%d,%d,%d,%d,%d,0x%x,0x%x,%d,%d, \
638 %d,%d,%d,%d,%d)\n\r",
639 layer, show, win_blending, alpha, priority, color,
640 blank_change, pixel_blending, premul, blank_color,
641 base_addr, span, width, height, src_offs_x, src_offs_y,
642 dst_offs_x, dst_offs_y);
643
644 switch (layer) {
645
646 case VM_VIDEO_LAYER:
647 temp_reg = (win_blending) ?
648 S5P_MXR_VP_BLEND_ENABLE : S5P_MXR_VP_BLEND_DISABLE;
649 temp_reg |= S5P_MXR_VP_ALPHA_VALUE(alpha);
650 /* temp yuv pxl limiter setting*/
651 temp_reg &= ~(1<<17);
652 writel(temp_reg, mixer_base + S5P_MXR_VIDEO_CFG);
653 break;
654
655 case VM_GPR0_LAYER:
656 temp_reg = (blank_change) ? S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL :
657 S5P_MXR_BLANK_CHANGE_NEW_PIXEL;
658 temp_reg |= (premul) ? S5P_MXR_PRE_MUL_MODE :
659 S5P_MXR_NORMAL_MODE;
660 temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE :
661 S5P_MXR_WIN_BLEND_DISABLE;
662 temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE :
663 S5P_MXR_PIXEL_BLEND_DISABLE;
664 temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color);
665 temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha);
666 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC0_CFG);
667 writel(S5P_MXR_GPR_BLANK_COLOR(blank_color),
668 mixer_base + S5P_MXR_GRAPHIC0_BLANK);
669
670 VMPRINTK("--(0x%x)\n\r",
671 readl(mixer_base + S5P_MXR_GRAPHIC0_CFG));
672 VMPRINTK("--(0x%x)\n\r",
673 readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK));
674
675 tv_vm_set_grp_layer_size(layer, span, width, height,
676 src_offs_x, src_offs_y);
677
678 tv_vm_set_grp_base_address(layer, base_addr);
679 tv_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y);
680
681 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC0_WH);
682 h_factor = grp_scaling_factor(width, dst_width, 1);
683 v_factor = grp_scaling_factor(height, dst_height, 0);
684
685 temp_reg &= ~((0x3<<28)|(0x3<<12));
686
687 if (v_factor) {
688
689 u32 reg = readl(mixer_base + S5P_MXR_CFG);
690
691 /* In interlaced mode, vertical scaling must be
692 * replaced by PROGRESSIVE_MODE - pixel duplication
693 */
694 if (mode == TVOUT_1080I_50 ||
695 mode == TVOUT_1080I_59 ||
696 mode == TVOUT_1080I_60) {
697 /* scaled up by progressive setting */
698 reg |= S5P_MXR_PROGRESSVE_MODE;
699 writel(reg, mixer_base + S5P_MXR_CFG);
700 } else
701 /* scaled up by scale factor */
702 temp_reg |= v_factor << 12;
703 } else {
704 u32 reg = readl(mixer_base + S5P_MXR_CFG);
705
706 /*
707 * if v_factor is 0, recover the original mode
708 */
709 if (mode == TVOUT_1080I_50 ||
710 mode == TVOUT_1080I_59 ||
711 mode == TVOUT_1080I_60) {
712 reg &= S5P_MXR_INTERLACE_MODE;
713 writel(reg, mixer_base + S5P_MXR_CFG);
714 }
715 }
716 temp_reg |= h_factor << 28;
717 writel(temp_reg , mixer_base + S5P_MXR_GRAPHIC0_WH);
718 break;
719
720 case VM_GPR1_LAYER:
721 temp_reg = (blank_change) ?
722 S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL :
723 S5P_MXR_BLANK_CHANGE_NEW_PIXEL;
724 temp_reg |= (premul) ?
725 S5P_MXR_PRE_MUL_MODE : S5P_MXR_NORMAL_MODE;
726 temp_reg |= (win_blending) ? S5P_MXR_WIN_BLEND_ENABLE :
727 S5P_MXR_WIN_BLEND_DISABLE;
728 temp_reg |= (pixel_blending) ? S5P_MXR_PIXEL_BLEND_ENABLE :
729 S5P_MXR_PIXEL_BLEND_DISABLE;
730 temp_reg |= S5P_MXR_EG_COLOR_FORMAT(color);
731 temp_reg |= S5P_MXR_GRP_ALPHA_VALUE(alpha);
732
733 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_CFG);
734 writel(S5P_MXR_GPR_BLANK_COLOR(blank_color),
735 mixer_base + S5P_MXR_GRAPHIC1_BLANK);
736
737 VMPRINTK("--(0x%x)\n\r",
738 readl(mixer_base + S5P_MXR_GRAPHIC1_CFG));
739 VMPRINTK("--(0x%x)\n\r",
740 readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK));
741
742 tv_vm_set_grp_layer_size(layer, span, width, height,
743 src_offs_x, src_offs_y);
744
745 tv_vm_set_grp_base_address(layer, base_addr);
746 tv_vm_set_grp_layer_position(layer, dst_offs_x, dst_offs_y);
747
748 temp_reg = readl(mixer_base + S5P_MXR_GRAPHIC1_WH);
749 h_factor = grp_scaling_factor(width, dst_width, 1);
750 v_factor = grp_scaling_factor(height, dst_height, 0);
751
752 temp_reg &= ~((0x3<<28)|(0x3<<12));
753
754 if (v_factor) {
755
756 u32 reg = readl(mixer_base + S5P_MXR_CFG);
757
758 /* In interlaced mode, vertical scaling must be
759 * replaced by PROGRESSIVE_MODE - pixel duplication
760 */
761 if (mode == TVOUT_1080I_50 ||
762 mode == TVOUT_1080I_59 ||
763 mode == TVOUT_1080I_60) {
764 /* scaled up by progressive setting */
765 reg |= S5P_MXR_PROGRESSVE_MODE;
766 writel(reg, mixer_base + S5P_MXR_CFG);
767 } else
768 /* scaled up by scale factor */
769 temp_reg |= v_factor << 12;
770 } else {
771 u32 reg = readl(mixer_base + S5P_MXR_CFG);
772
773 /*
774 * if v_factor is 0, recover the original mode
775 */
776 if (mode == TVOUT_1080I_50 ||
777 mode == TVOUT_1080I_59 ||
778 mode == TVOUT_1080I_60) {
779 reg &= S5P_MXR_INTERLACE_MODE;
780 writel(reg, mixer_base + S5P_MXR_CFG);
781 }
782 }
783
784 temp_reg |= h_factor << 28;
785
786 writel(temp_reg, mixer_base + S5P_MXR_GRAPHIC1_WH);
787 break;
788
789 default:
790 VMPRINTK("invalid layer parameter = %d\n\r", layer);
791 return S5P_TV_VMX_ERR_INVALID_PARAM;
792 }
793
794 tv_vm_set_layer_priority(layer, priority);
795
796 tv_vm_set_layer_show(layer, show);
797
798 return VMIXER_NO_ERROR;
799 }
800
801 void tv_vm_init_bg_dither_enable(bool cr_dither_enable,
802 bool cb_dither_enable,
803 bool y_dither_enable)
804 {
805 u32 temp_reg = 0;
806
807 VMPRINTK("%d,%d,%d\n\r",
808 cr_dither_enable, cb_dither_enable, y_dither_enable);
809
810 temp_reg = (cr_dither_enable) ?
811 (temp_reg | S5P_MXR_BG_CR_DIHER_EN) :
812 (temp_reg & ~S5P_MXR_BG_CR_DIHER_EN);
813 temp_reg = (cb_dither_enable) ?
814 (temp_reg | S5P_MXR_BG_CB_DIHER_EN) :
815 (temp_reg & ~S5P_MXR_BG_CB_DIHER_EN);
816 temp_reg = (y_dither_enable) ?
817 (temp_reg | S5P_MXR_BG_Y_DIHER_EN) :
818 (temp_reg & ~S5P_MXR_BG_Y_DIHER_EN);
819
820 writel(temp_reg, mixer_base + S5P_MXR_BG_CFG);
821 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_BG_CFG));
822
823 }
824
825
826 enum s5p_tv_vmx_err tv_vm_init_bg_color(enum s5p_tv_vmx_bg_color_num color_num,
827 u32 color_y,
828 u32 color_cb,
829 u32 color_cr)
830 {
831 return tv_vm_set_bg_color(color_num, color_y, color_cb, color_cr);
832 }
833
834 enum s5p_tv_vmx_err tv_vm_init_csc_coef(enum s5p_yuv_fmt_component component,
835 enum s5p_tv_coef_y_mode mode,
836 u32 coeff0,
837 u32 coeff1,
838 u32 coeff2)
839 {
840 u32 mxr_cm;
841
842 VMPRINTK("%d,%d,%d,%d,%d\n\r", component, mode, coeff0, coeff1, coeff2);
843
844 switch (component) {
845
846 case TVOUT_YUV_Y:
847 mxr_cm = (mode == VMIXER_COEF_Y_WIDE) ?
848 S5P_MXR_BG_COLOR_WIDE : S5P_MXR_BG_COLOR_NARROW;
849 mxr_cm |= S5P_MXR_BG_COEFF_0(coeff0) |
850 S5P_MXR_BG_COEFF_1(coeff1) |
851 S5P_MXR_BG_COEFF_2(coeff2);
852 writel(mxr_cm, mixer_base + S5P_MXR_CM_COEFF_Y);
853 VMPRINTK("--(0x%x)\n\r",
854 readl(mixer_base + S5P_MXR_CM_COEFF_Y));
855 break;
856
857 case TVOUT_YUV_CB:
858 mxr_cm = S5P_MXR_BG_COEFF_0(coeff0) |
859 S5P_MXR_BG_COEFF_1(coeff1) |
860 S5P_MXR_BG_COEFF_2(coeff2);
861 writel(mxr_cm, mixer_base + S5P_MXR_CM_COEFF_CB);
862 VMPRINTK("--(0x%x)\n\r",
863 readl(mixer_base + S5P_MXR_CM_COEFF_CB));
864 break;
865
866 case TVOUT_YUV_CR:
867 mxr_cm = S5P_MXR_BG_COEFF_0(coeff0) |
868 S5P_MXR_BG_COEFF_1(coeff1) |
869 S5P_MXR_BG_COEFF_2(coeff2);
870 writel(mxr_cm, S5P_MXR_CM_COEFF_CR);
871 VMPRINTK("--(0x%x)\n\r",
872 readl(mixer_base + S5P_MXR_CM_COEFF_CR));
873 break;
874
875 default:
876 VMPRINTK("invalid component parameter = %d\n\r", component);
877 return S5P_TV_VMX_ERR_INVALID_PARAM;
878 }
879
880 return VMIXER_NO_ERROR;
881 }
882
883 void tv_vm_init_csc_coef_default(enum s5p_tv_vmx_csc_type csc_type)
884 {
885 VMPRINTK("%d\n\r", csc_type);
886
887 switch (csc_type) {
888
889 case VMIXER_CSC_RGB_TO_YUV601_LR:
890 writel((0 << 30) | (153 << 20) | (300 << 10) | (58 << 0),
891 mixer_base + S5P_MXR_CM_COEFF_Y);
892 writel((936 << 20) | (851 << 10) | (262 << 0),
893 mixer_base + S5P_MXR_CM_COEFF_CB);
894 writel((262 << 20) | (805 << 10) | (982 << 0),
895 mixer_base + S5P_MXR_CM_COEFF_CR);
896 break;
897
898 case VMIXER_CSC_RGB_TO_YUV601_FR:
899 writel((1 << 30) | (132 << 20) | (258 << 10) | (50 << 0),
900 mixer_base + S5P_MXR_CM_COEFF_Y);
901 writel((948 << 20) | (875 << 10) | (225 << 0),
902 mixer_base + S5P_MXR_CM_COEFF_CB);
903 writel((225 << 20) | (836 << 10) | (988 << 0),
904 mixer_base + S5P_MXR_CM_COEFF_CR);
905 break;
906
907 case VMIXER_CSC_RGB_TO_YUV709_LR:
908 writel((0 << 30) | (109 << 20) | (366 << 10) | (36 << 0),
909 mixer_base + S5P_MXR_CM_COEFF_Y);
910 writel((964 << 20) | (822 << 10) | (216 << 0),
911 mixer_base + S5P_MXR_CM_COEFF_CB);
912 writel((262 << 20) | (787 << 10) | (1000 << 0),
913 mixer_base + S5P_MXR_CM_COEFF_CR);
914 break;
915
916 case VMIXER_CSC_RGB_TO_YUV709_FR:
917 writel((1 << 30) | (94 << 20) | (314 << 10) | (32 << 0),
918 mixer_base + S5P_MXR_CM_COEFF_Y);
919 writel((972 << 20) | (851 << 10) | (225 << 0),
920 mixer_base + S5P_MXR_CM_COEFF_CB);
921 writel((225 << 20) | (820 << 10) | (1004 << 0),
922 mixer_base + S5P_MXR_CM_COEFF_CR);
923 break;
924
925 default:
926 VMPRINTK(" invalid csc_type parameter = %d\n\r", csc_type);
927 break;
928 }
929
930 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_Y));
931
932 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_CB));
933 VMPRINTK("--(0x%x)\n\r", readl(mixer_base + S5P_MXR_CM_COEFF_CR));
934 }
935
936 enum s5p_tv_vmx_err tv_vm_get_layer_info(enum s5p_tv_vmx_layer layer,
937 bool *show,
938 u32 *priority)
939 {
940 VMPRINTK("%d\n\r", layer);
941
942 switch (layer) {
943
944 case VM_VIDEO_LAYER:
945 *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) &
946 S5P_MXR_VIDEO_LAYER_SHOW) ? 1 : 0;
947 *priority = S5P_MXR_VP_LAYER_PRIORITY_INFO(
948 readl(mixer_base + S5P_MXR_LAYER_CFG));
949 break;
950
951 case VM_GPR0_LAYER:
952 *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) &
953 S5P_MXR_GRAPHIC0_LAYER_SHOW) ? 1 : 0;
954 *priority = S5P_MXR_GRP0_LAYER_PRIORITY_INFO(
955 readl(mixer_base + S5P_MXR_LAYER_CFG));
956 break;
957
958 case VM_GPR1_LAYER:
959 *show = (readl(mixer_base + S5P_MXR_LAYER_CFG) &
960 S5P_MXR_GRAPHIC1_LAYER_SHOW) ? 1 : 0;
961 *priority = S5P_MXR_GRP1_LAYER_PRIORITY_INFO(
962 readl(mixer_base + S5P_MXR_LAYER_CFG));
963 break;
964
965 default:
966 VMPRINTK("invalid layer parameter = %d\n\r", layer);
967 return S5P_TV_VMX_ERR_INVALID_PARAM;
968 }
969
970 VMPRINTK("%d,%d\n\r", *show, *priority);
971
972 return VMIXER_NO_ERROR;
973 }
974
975 /*
976 * start - start functions are only called under stopping vmixer
977 */
978
979 void tv_vm_start(void)
980 {
981 VMPRINTK("()\n\r");
982 writel((readl(mixer_base + S5P_MXR_STATUS) | S5P_MXR_MIXER_START),
983 mixer_base + S5P_MXR_STATUS);
984 VMPRINTK("0x%x\n\r", readl(mixer_base + S5P_MXR_STATUS));
985
986
987 VMPRINTK("S5P_MXR_STATUS \t\t 0x%08x\n ",
988 readl(mixer_base + S5P_MXR_STATUS));
989 VMPRINTK("S5P_MXR_INT_EN \t\t 0x%08x\n ",
990 readl(mixer_base + S5P_MXR_INT_EN));
991 VMPRINTK("S5P_MXR_BG_CFG \t\t 0x%08x\n ",
992 readl(mixer_base + S5P_MXR_BG_CFG));
993 VMPRINTK("S5P_MXR_BG_COLOR0 \t\t 0x%08x\n ",
994 readl(mixer_base + S5P_MXR_BG_COLOR0));
995 VMPRINTK("S5P_MXR_BG_COLOR1 \t\t 0x%08x\n ",
996 readl(mixer_base + S5P_MXR_BG_COLOR1));
997 VMPRINTK("S5P_MXR_BG_COLOR2 \t\t 0x%08x\n ",
998 readl(mixer_base + S5P_MXR_BG_COLOR2));
999 VMPRINTK("S5P_MXR_CM_COEFF_Y \t\t 0x%08x\n ",
1000 readl(mixer_base + S5P_MXR_CM_COEFF_Y));
1001 VMPRINTK("S5P_MXR_CM_COEFF_CB \t\t 0x%08x\n ",
1002 readl(mixer_base + S5P_MXR_CM_COEFF_CB));
1003 VMPRINTK("S5P_MXR_CM_COEFF_CR \t\t 0x%08x\n ",
1004 readl(mixer_base + S5P_MXR_CM_COEFF_CR));
1005 VMPRINTK("S5P_MXR_CM_COEFF_Y \t\t 0x%08x\n ",
1006 readl(mixer_base + S5P_MXR_CM_COEFF_Y));
1007 VMPRINTK("S5P_MXR_CM_COEFF_CB \t\t 0x%08x\n ",
1008 readl(mixer_base + S5P_MXR_CM_COEFF_CB));
1009 VMPRINTK("S5P_MXR_CM_COEFF_CR \t\t 0x%08x\n ",
1010 readl(mixer_base + S5P_MXR_CM_COEFF_CR));
1011 VMPRINTK("S5P_MXR_GRAPHIC0_CFG \t\t 0x%08x\n ",
1012 readl(mixer_base + S5P_MXR_GRAPHIC0_CFG));
1013 VMPRINTK("S5P_MXR_GRAPHIC0_BASE \t\t 0x%08x\n ",
1014 readl(mixer_base + S5P_MXR_GRAPHIC0_BASE));
1015 VMPRINTK("S5P_MXR_GRAPHIC0_SPAN \t\t 0x%08x\n ",
1016 readl(mixer_base + S5P_MXR_GRAPHIC0_SPAN));
1017 VMPRINTK("S5P_MXR_GRAPHIC0_WH \t\t 0x%08x\n ",
1018 readl(mixer_base + S5P_MXR_GRAPHIC0_WH));
1019 VMPRINTK("S5P_MXR_GRAPHIC0_SXY \t\t 0x%08x\n ",
1020 readl(mixer_base + S5P_MXR_GRAPHIC0_SXY));
1021 VMPRINTK("S5P_MXR_GRAPHIC0_DXY \t\t 0x%08x\n ",
1022 readl(mixer_base + S5P_MXR_GRAPHIC0_DXY));
1023 VMPRINTK("S5P_MXR_GRAPHIC0_BLANK \t\t 0x%08x\n ",
1024 readl(mixer_base + S5P_MXR_GRAPHIC0_BLANK));
1025 VMPRINTK("S5P_MXR_GRAPHIC1_BASE \t\t 0x%08x\n ",
1026 readl(mixer_base + S5P_MXR_GRAPHIC1_BASE));
1027 VMPRINTK("S5P_MXR_GRAPHIC1_SPAN \t\t 0x%08x\n ",
1028 readl(mixer_base + S5P_MXR_GRAPHIC1_SPAN));
1029 VMPRINTK("S5P_MXR_GRAPHIC1_WH \t\t 0x%08x\n ",
1030 readl(mixer_base + S5P_MXR_GRAPHIC1_WH));
1031 VMPRINTK("S5P_MXR_GRAPHIC1_SXY \t\t 0x%08x\n ",
1032 readl(mixer_base + S5P_MXR_GRAPHIC1_SXY));
1033 VMPRINTK("S5P_MXR_GRAPHIC1_DXY \t\t 0x%08x\n ",
1034 readl(mixer_base + S5P_MXR_GRAPHIC1_DXY));
1035 VMPRINTK("S5P_MXR_GRAPHIC1_BLANK \t\t 0x%08x\n ",
1036 readl(mixer_base + S5P_MXR_GRAPHIC1_BLANK));
1037 VMPRINTK("S5P_MXR_CFG \t\t 0x%08x\n ", readl(mixer_base + S5P_MXR_CFG));
1038 VMPRINTK("S5P_MXR_LAYER_CFG \t\t 0x%08x\n ",
1039 readl(mixer_base + S5P_MXR_LAYER_CFG));
1040
1041 }
1042
1043 /*
1044 * stop - stop functions are only called under running vmixer
1045 */
1046 void tv_vm_stop(void)
1047 {
1048 u32 reg = readl(mixer_base + S5P_MXR_STATUS);
1049
1050 reg &= ~S5P_MXR_MIXER_START;
1051
1052 writel(reg, mixer_base + S5P_MXR_STATUS);
1053
1054 do {
1055 reg = readl(mixer_base + S5P_MXR_STATUS);
1056 } while (reg & S5P_MXR_MIXER_START);
1057 }
1058
1059 /*
1060 * interrupt - for debug
1061 */
1062 enum s5p_tv_vmx_err tv_vm_set_underflow_interrupt_enable(
1063 enum s5p_tv_vmx_layer layer, bool en)
1064 {
1065 u32 enablemaks;
1066
1067 VMPRINTK("%d,%d\n\r", layer, en);
1068
1069 switch (layer) {
1070
1071 case VM_VIDEO_LAYER:
1072 enablemaks = S5P_MXR_VP_INT_ENABLE;
1073 break;
1074
1075 case VM_GPR0_LAYER:
1076 enablemaks = S5P_MXR_GRP0_INT_ENABLE;
1077 break;
1078
1079 case VM_GPR1_LAYER:
1080 enablemaks = S5P_MXR_GRP1_INT_ENABLE;
1081 break;
1082
1083 default:
1084 VMPRINTK("invalid layer parameter = %d\n\r", layer);
1085 return S5P_TV_VMX_ERR_INVALID_PARAM;
1086 }
1087
1088 if (en) {
1089 writel((readl(mixer_base + S5P_MXR_INT_EN) | enablemaks),
1090 mixer_base + S5P_MXR_INT_EN);
1091 } else {
1092 writel((readl(mixer_base + S5P_MXR_INT_EN) & ~enablemaks),
1093 mixer_base + S5P_MXR_INT_EN);
1094 }
1095
1096 VMPRINTK("0x%x)\n\r", readl(mixer_base + S5P_MXR_INT_EN));
1097
1098 return VMIXER_NO_ERROR;
1099 }
1100
1101
1102 enum s5p_tv_vmx_err tv_vm_set_vsync_interrupt(bool en)
1103 {
1104 if (en) {
1105 writel(S5P_MXR_VSYNC_INT_CLEARED, mixer_base +
1106 S5P_MXR_INT_STATUS);
1107 writel((readl(mixer_base + S5P_MXR_INT_EN) |
1108 S5P_MXR_VSYNC_INT_ENABLE),
1109 mixer_base + S5P_MXR_INT_EN);
1110 } else {
1111 writel((readl(mixer_base + S5P_MXR_INT_EN) &
1112 ~S5P_MXR_VSYNC_INT_ENABLE),
1113 mixer_base + S5P_MXR_INT_EN);
1114 }
1115
1116 VMPRINTK("0x%x)\n\r", readl(mixer_base + S5P_MXR_INT_EN));
1117
1118 return VMIXER_NO_ERROR;
1119 }
1120
1121 void tv_vm_clear_pend_all(void)
1122 {
1123 writel(S5P_MXR_INT_FIRED | S5P_MXR_VP_INT_FIRED |
1124 S5P_MXR_GRP0_INT_FIRED | S5P_MXR_GRP1_INT_FIRED,
1125 mixer_base + S5P_MXR_INT_EN);
1126 }
1127
1128 irqreturn_t tv_mixer_irq(int irq, void *dev_id)
1129 {
1130 bool v_i_f;
1131 bool g0_i_f;
1132 bool g1_i_f;
1133 bool mxr_i_f;
1134 u32 temp_reg = 0;
1135
1136 v_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS)
1137 & S5P_MXR_VP_INT_FIRED) ? true : false;
1138 g0_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS)
1139 & S5P_MXR_GRP0_INT_FIRED) ? true : false;
1140 g1_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS)
1141 & S5P_MXR_GRP1_INT_FIRED) ? true : false;
1142 mxr_i_f = (readl(mixer_base + S5P_MXR_INT_STATUS)
1143 & S5P_MXR_INT_FIRED) ? true : false;
1144
1145 if (mxr_i_f) {
1146 temp_reg |= S5P_MXR_INT_FIRED;
1147
1148 if (v_i_f) {
1149 temp_reg |= S5P_MXR_VP_INT_FIRED;
1150 printk(KERN_ERR "VP fifo under run!!\n\r");
1151 }
1152
1153 if (g0_i_f) {
1154 temp_reg |= S5P_MXR_GRP0_INT_FIRED;
1155 printk(KERN_ERR "GRP0 fifo under run!!\n\r");
1156 }
1157
1158 if (g1_i_f) {
1159 temp_reg |= S5P_MXR_GRP1_INT_FIRED;
1160 printk(KERN_ERR "GRP1 fifo under run!!\n\r");
1161 }
1162
1163 if (!v_i_f && !g0_i_f && !g1_i_f) {
1164 writel(S5P_MXR_VSYNC_INT_CLEARED,
1165 mixer_base + S5P_MXR_INT_STATUS);
1166 wake_up(&s5ptv_wq);
1167 } else
1168 writel(temp_reg, mixer_base + S5P_MXR_INT_STATUS);
1169
1170 }
1171 return IRQ_HANDLED;
1172 }
1173
1174 int __init tv_mixer_probe(struct platform_device *pdev, u32 res_num)
1175 {
1176 struct resource *res;
1177 size_t size;
1178
1179 res = platform_get_resource(pdev, IORESOURCE_MEM, res_num);
1180
1181 if (res == NULL) {
1182 dev_err(&pdev->dev,
1183 "failed to get memory region resource\n");
1184 goto error;
1185
1186 }
1187
1188 size = (res->end - res->start) + 1;
1189
1190 mixer_mem = request_mem_region(res->start, size, pdev->name);
1191
1192 if (mixer_mem == NULL) {
1193 dev_err(&pdev->dev,
1194 "failed to get memory region\n");
1195 goto error;
1196
1197 }
1198
1199 mixer_base = ioremap(res->start, size);
1200
1201 if (mixer_base == NULL) {
1202 dev_err(&pdev->dev,
1203 "failed to ioremap address region\n");
1204 goto error;
1205
1206
1207 }
1208
1209 /* Initializing wait queue for mixer vsync interrupt */
1210 init_waitqueue_head(&s5ptv_wq);
1211 return 0;
1212 error:
1213 return -ENOENT;
1214
1215 }
1216
1217 int __init tv_mixer_release(struct platform_device *pdev)
1218 {
1219 iounmap(mixer_base);
1220
1221 /* remove memory region */
1222 if (mixer_mem != NULL) {
1223 if (release_resource(mixer_mem))
1224 dev_err(&pdev->dev,
1225 "Can't remove tvout drv !!\n");
1226
1227 kfree(mixer_mem);
1228
1229 mixer_mem = NULL;
1230 }
1231
1232 return 0;
1233 }
OLDNEW
« no previous file with comments | « drivers/media/video/samsung/tv20/tv_power_s5pv210.c ('k') | drivers/media/video/samsung/tv20/vp_coeff_s5pv210.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698