diff options
Diffstat (limited to 'drivers/media/video/davinci/vpbe_osd.c')
-rw-r--r-- | drivers/media/video/davinci/vpbe_osd.c | 491 |
1 files changed, 433 insertions, 58 deletions
diff --git a/drivers/media/video/davinci/vpbe_osd.c b/drivers/media/video/davinci/vpbe_osd.c index ceccf4302518..d6488b79ae3b 100644 --- a/drivers/media/video/davinci/vpbe_osd.c +++ b/drivers/media/video/davinci/vpbe_osd.c | |||
@@ -248,11 +248,29 @@ static void _osd_set_rec601_attenuation(struct osd_state *sd, | |||
248 | osd_modify(sd, OSD_OSDWIN0MD_ATN0E, | 248 | osd_modify(sd, OSD_OSDWIN0MD_ATN0E, |
249 | enable ? OSD_OSDWIN0MD_ATN0E : 0, | 249 | enable ? OSD_OSDWIN0MD_ATN0E : 0, |
250 | OSD_OSDWIN0MD); | 250 | OSD_OSDWIN0MD); |
251 | if (sd->vpbe_type == VPBE_VERSION_1) | ||
252 | osd_modify(sd, OSD_OSDWIN0MD_ATN0E, | ||
253 | enable ? OSD_OSDWIN0MD_ATN0E : 0, | ||
254 | OSD_OSDWIN0MD); | ||
255 | else if ((sd->vpbe_type == VPBE_VERSION_3) || | ||
256 | (sd->vpbe_type == VPBE_VERSION_2)) | ||
257 | osd_modify(sd, OSD_EXTMODE_ATNOSD0EN, | ||
258 | enable ? OSD_EXTMODE_ATNOSD0EN : 0, | ||
259 | OSD_EXTMODE); | ||
251 | break; | 260 | break; |
252 | case OSDWIN_OSD1: | 261 | case OSDWIN_OSD1: |
253 | osd_modify(sd, OSD_OSDWIN1MD_ATN1E, | 262 | osd_modify(sd, OSD_OSDWIN1MD_ATN1E, |
254 | enable ? OSD_OSDWIN1MD_ATN1E : 0, | 263 | enable ? OSD_OSDWIN1MD_ATN1E : 0, |
255 | OSD_OSDWIN1MD); | 264 | OSD_OSDWIN1MD); |
265 | if (sd->vpbe_type == VPBE_VERSION_1) | ||
266 | osd_modify(sd, OSD_OSDWIN1MD_ATN1E, | ||
267 | enable ? OSD_OSDWIN1MD_ATN1E : 0, | ||
268 | OSD_OSDWIN1MD); | ||
269 | else if ((sd->vpbe_type == VPBE_VERSION_3) || | ||
270 | (sd->vpbe_type == VPBE_VERSION_2)) | ||
271 | osd_modify(sd, OSD_EXTMODE_ATNOSD1EN, | ||
272 | enable ? OSD_EXTMODE_ATNOSD1EN : 0, | ||
273 | OSD_EXTMODE); | ||
256 | break; | 274 | break; |
257 | } | 275 | } |
258 | } | 276 | } |
@@ -273,15 +291,71 @@ static void _osd_set_blending_factor(struct osd_state *sd, | |||
273 | } | 291 | } |
274 | } | 292 | } |
275 | 293 | ||
294 | static void _osd_enable_rgb888_pixblend(struct osd_state *sd, | ||
295 | enum osd_win_layer osdwin) | ||
296 | { | ||
297 | |||
298 | osd_modify(sd, OSD_MISCCTL_BLDSEL, 0, OSD_MISCCTL); | ||
299 | switch (osdwin) { | ||
300 | case OSDWIN_OSD0: | ||
301 | osd_modify(sd, OSD_EXTMODE_OSD0BLDCHR, | ||
302 | OSD_EXTMODE_OSD0BLDCHR, OSD_EXTMODE); | ||
303 | break; | ||
304 | case OSDWIN_OSD1: | ||
305 | osd_modify(sd, OSD_EXTMODE_OSD1BLDCHR, | ||
306 | OSD_EXTMODE_OSD1BLDCHR, OSD_EXTMODE); | ||
307 | break; | ||
308 | } | ||
309 | } | ||
310 | |||
276 | static void _osd_enable_color_key(struct osd_state *sd, | 311 | static void _osd_enable_color_key(struct osd_state *sd, |
277 | enum osd_win_layer osdwin, | 312 | enum osd_win_layer osdwin, |
278 | unsigned colorkey, | 313 | unsigned colorkey, |
279 | enum osd_pix_format pixfmt) | 314 | enum osd_pix_format pixfmt) |
280 | { | 315 | { |
281 | switch (pixfmt) { | 316 | switch (pixfmt) { |
317 | case PIXFMT_1BPP: | ||
318 | case PIXFMT_2BPP: | ||
319 | case PIXFMT_4BPP: | ||
320 | case PIXFMT_8BPP: | ||
321 | if (sd->vpbe_type == VPBE_VERSION_3) { | ||
322 | switch (osdwin) { | ||
323 | case OSDWIN_OSD0: | ||
324 | osd_modify(sd, OSD_TRANSPBMPIDX_BMP0, | ||
325 | colorkey << | ||
326 | OSD_TRANSPBMPIDX_BMP0_SHIFT, | ||
327 | OSD_TRANSPBMPIDX); | ||
328 | break; | ||
329 | case OSDWIN_OSD1: | ||
330 | osd_modify(sd, OSD_TRANSPBMPIDX_BMP1, | ||
331 | colorkey << | ||
332 | OSD_TRANSPBMPIDX_BMP1_SHIFT, | ||
333 | OSD_TRANSPBMPIDX); | ||
334 | break; | ||
335 | } | ||
336 | } | ||
337 | break; | ||
282 | case PIXFMT_RGB565: | 338 | case PIXFMT_RGB565: |
283 | osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS, | 339 | if (sd->vpbe_type == VPBE_VERSION_1) |
284 | OSD_TRANSPVAL); | 340 | osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS, |
341 | OSD_TRANSPVAL); | ||
342 | else if (sd->vpbe_type == VPBE_VERSION_3) | ||
343 | osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL, | ||
344 | OSD_TRANSPVALL); | ||
345 | break; | ||
346 | case PIXFMT_YCbCrI: | ||
347 | case PIXFMT_YCrCbI: | ||
348 | if (sd->vpbe_type == VPBE_VERSION_3) | ||
349 | osd_modify(sd, OSD_TRANSPVALU_Y, colorkey, | ||
350 | OSD_TRANSPVALU); | ||
351 | break; | ||
352 | case PIXFMT_RGB888: | ||
353 | if (sd->vpbe_type == VPBE_VERSION_3) { | ||
354 | osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL, | ||
355 | OSD_TRANSPVALL); | ||
356 | osd_modify(sd, OSD_TRANSPVALU_RGBU, colorkey >> 16, | ||
357 | OSD_TRANSPVALU); | ||
358 | } | ||
285 | break; | 359 | break; |
286 | default: | 360 | default: |
287 | break; | 361 | break; |
@@ -470,23 +544,188 @@ static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer, | |||
470 | return 0; | 544 | return 0; |
471 | } | 545 | } |
472 | 546 | ||
547 | #define OSD_SRC_ADDR_HIGH4 0x7800000 | ||
548 | #define OSD_SRC_ADDR_HIGH7 0x7F0000 | ||
549 | #define OSD_SRCADD_OFSET_SFT 23 | ||
550 | #define OSD_SRCADD_ADD_SFT 16 | ||
551 | #define OSD_WINADL_MASK 0xFFFF | ||
552 | #define OSD_WINOFST_MASK 0x1000 | ||
553 | #define VPBE_REG_BASE 0x80000000 | ||
554 | |||
473 | static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer, | 555 | static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer, |
474 | unsigned long fb_base_phys, | 556 | unsigned long fb_base_phys, |
475 | unsigned long cbcr_ofst) | 557 | unsigned long cbcr_ofst) |
476 | { | 558 | { |
477 | switch (layer) { | 559 | |
478 | case WIN_OSD0: | 560 | if (sd->vpbe_type == VPBE_VERSION_1) { |
479 | osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR); | 561 | switch (layer) { |
480 | break; | 562 | case WIN_OSD0: |
481 | case WIN_VID0: | 563 | osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR); |
482 | osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); | 564 | break; |
483 | break; | 565 | case WIN_VID0: |
484 | case WIN_OSD1: | 566 | osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); |
485 | osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR); | 567 | break; |
486 | break; | 568 | case WIN_OSD1: |
487 | case WIN_VID1: | 569 | osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR); |
488 | osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR); | 570 | break; |
489 | break; | 571 | case WIN_VID1: |
572 | osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR); | ||
573 | break; | ||
574 | } | ||
575 | } else if (sd->vpbe_type == VPBE_VERSION_3) { | ||
576 | unsigned long fb_offset_32 = | ||
577 | (fb_base_phys - VPBE_REG_BASE) >> 5; | ||
578 | |||
579 | switch (layer) { | ||
580 | case WIN_OSD0: | ||
581 | osd_modify(sd, OSD_OSDWINADH_O0AH, | ||
582 | fb_offset_32 >> (OSD_SRCADD_ADD_SFT - | ||
583 | OSD_OSDWINADH_O0AH_SHIFT), | ||
584 | OSD_OSDWINADH); | ||
585 | osd_write(sd, fb_offset_32 & OSD_OSDWIN0ADL_O0AL, | ||
586 | OSD_OSDWIN0ADL); | ||
587 | break; | ||
588 | case WIN_VID0: | ||
589 | osd_modify(sd, OSD_VIDWINADH_V0AH, | ||
590 | fb_offset_32 >> (OSD_SRCADD_ADD_SFT - | ||
591 | OSD_VIDWINADH_V0AH_SHIFT), | ||
592 | OSD_VIDWINADH); | ||
593 | osd_write(sd, fb_offset_32 & OSD_VIDWIN0ADL_V0AL, | ||
594 | OSD_VIDWIN0ADL); | ||
595 | break; | ||
596 | case WIN_OSD1: | ||
597 | osd_modify(sd, OSD_OSDWINADH_O1AH, | ||
598 | fb_offset_32 >> (OSD_SRCADD_ADD_SFT - | ||
599 | OSD_OSDWINADH_O1AH_SHIFT), | ||
600 | OSD_OSDWINADH); | ||
601 | osd_write(sd, fb_offset_32 & OSD_OSDWIN1ADL_O1AL, | ||
602 | OSD_OSDWIN1ADL); | ||
603 | break; | ||
604 | case WIN_VID1: | ||
605 | osd_modify(sd, OSD_VIDWINADH_V1AH, | ||
606 | fb_offset_32 >> (OSD_SRCADD_ADD_SFT - | ||
607 | OSD_VIDWINADH_V1AH_SHIFT), | ||
608 | OSD_VIDWINADH); | ||
609 | osd_write(sd, fb_offset_32 & OSD_VIDWIN1ADL_V1AL, | ||
610 | OSD_VIDWIN1ADL); | ||
611 | break; | ||
612 | } | ||
613 | } else if (sd->vpbe_type == VPBE_VERSION_2) { | ||
614 | struct osd_window_state *win = &sd->win[layer]; | ||
615 | unsigned long fb_offset_32, cbcr_offset_32; | ||
616 | |||
617 | fb_offset_32 = fb_base_phys - VPBE_REG_BASE; | ||
618 | if (cbcr_ofst) | ||
619 | cbcr_offset_32 = cbcr_ofst; | ||
620 | else | ||
621 | cbcr_offset_32 = win->lconfig.line_length * | ||
622 | win->lconfig.ysize; | ||
623 | cbcr_offset_32 += fb_offset_32; | ||
624 | fb_offset_32 = fb_offset_32 >> 5; | ||
625 | cbcr_offset_32 = cbcr_offset_32 >> 5; | ||
626 | /* | ||
627 | * DM365: start address is 27-bit long address b26 - b23 are | ||
628 | * in offset register b12 - b9, and * bit 26 has to be '1' | ||
629 | */ | ||
630 | if (win->lconfig.pixfmt == PIXFMT_NV12) { | ||
631 | switch (layer) { | ||
632 | case WIN_VID0: | ||
633 | case WIN_VID1: | ||
634 | /* Y is in VID0 */ | ||
635 | osd_modify(sd, OSD_VIDWIN0OFST_V0AH, | ||
636 | ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> | ||
637 | (OSD_SRCADD_OFSET_SFT - | ||
638 | OSD_WINOFST_AH_SHIFT)) | | ||
639 | OSD_WINOFST_MASK, OSD_VIDWIN0OFST); | ||
640 | osd_modify(sd, OSD_VIDWINADH_V0AH, | ||
641 | (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> | ||
642 | (OSD_SRCADD_ADD_SFT - | ||
643 | OSD_VIDWINADH_V0AH_SHIFT), | ||
644 | OSD_VIDWINADH); | ||
645 | osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, | ||
646 | OSD_VIDWIN0ADL); | ||
647 | /* CbCr is in VID1 */ | ||
648 | osd_modify(sd, OSD_VIDWIN1OFST_V1AH, | ||
649 | ((cbcr_offset_32 & | ||
650 | OSD_SRC_ADDR_HIGH4) >> | ||
651 | (OSD_SRCADD_OFSET_SFT - | ||
652 | OSD_WINOFST_AH_SHIFT)) | | ||
653 | OSD_WINOFST_MASK, OSD_VIDWIN1OFST); | ||
654 | osd_modify(sd, OSD_VIDWINADH_V1AH, | ||
655 | (cbcr_offset_32 & | ||
656 | OSD_SRC_ADDR_HIGH7) >> | ||
657 | (OSD_SRCADD_ADD_SFT - | ||
658 | OSD_VIDWINADH_V1AH_SHIFT), | ||
659 | OSD_VIDWINADH); | ||
660 | osd_write(sd, cbcr_offset_32 & OSD_WINADL_MASK, | ||
661 | OSD_VIDWIN1ADL); | ||
662 | break; | ||
663 | default: | ||
664 | break; | ||
665 | } | ||
666 | } | ||
667 | |||
668 | switch (layer) { | ||
669 | case WIN_OSD0: | ||
670 | osd_modify(sd, OSD_OSDWIN0OFST_O0AH, | ||
671 | ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> | ||
672 | (OSD_SRCADD_OFSET_SFT - | ||
673 | OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK, | ||
674 | OSD_OSDWIN0OFST); | ||
675 | osd_modify(sd, OSD_OSDWINADH_O0AH, | ||
676 | (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> | ||
677 | (OSD_SRCADD_ADD_SFT - | ||
678 | OSD_OSDWINADH_O0AH_SHIFT), OSD_OSDWINADH); | ||
679 | osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, | ||
680 | OSD_OSDWIN0ADL); | ||
681 | break; | ||
682 | case WIN_VID0: | ||
683 | if (win->lconfig.pixfmt != PIXFMT_NV12) { | ||
684 | osd_modify(sd, OSD_VIDWIN0OFST_V0AH, | ||
685 | ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> | ||
686 | (OSD_SRCADD_OFSET_SFT - | ||
687 | OSD_WINOFST_AH_SHIFT)) | | ||
688 | OSD_WINOFST_MASK, OSD_VIDWIN0OFST); | ||
689 | osd_modify(sd, OSD_VIDWINADH_V0AH, | ||
690 | (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> | ||
691 | (OSD_SRCADD_ADD_SFT - | ||
692 | OSD_VIDWINADH_V0AH_SHIFT), | ||
693 | OSD_VIDWINADH); | ||
694 | osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, | ||
695 | OSD_VIDWIN0ADL); | ||
696 | } | ||
697 | break; | ||
698 | case WIN_OSD1: | ||
699 | osd_modify(sd, OSD_OSDWIN1OFST_O1AH, | ||
700 | ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> | ||
701 | (OSD_SRCADD_OFSET_SFT - | ||
702 | OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK, | ||
703 | OSD_OSDWIN1OFST); | ||
704 | osd_modify(sd, OSD_OSDWINADH_O1AH, | ||
705 | (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> | ||
706 | (OSD_SRCADD_ADD_SFT - | ||
707 | OSD_OSDWINADH_O1AH_SHIFT), | ||
708 | OSD_OSDWINADH); | ||
709 | osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, | ||
710 | OSD_OSDWIN1ADL); | ||
711 | break; | ||
712 | case WIN_VID1: | ||
713 | if (win->lconfig.pixfmt != PIXFMT_NV12) { | ||
714 | osd_modify(sd, OSD_VIDWIN1OFST_V1AH, | ||
715 | ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> | ||
716 | (OSD_SRCADD_OFSET_SFT - | ||
717 | OSD_WINOFST_AH_SHIFT)) | | ||
718 | OSD_WINOFST_MASK, OSD_VIDWIN1OFST); | ||
719 | osd_modify(sd, OSD_VIDWINADH_V1AH, | ||
720 | (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> | ||
721 | (OSD_SRCADD_ADD_SFT - | ||
722 | OSD_VIDWINADH_V1AH_SHIFT), | ||
723 | OSD_VIDWINADH); | ||
724 | osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, | ||
725 | OSD_VIDWIN1ADL); | ||
726 | } | ||
727 | break; | ||
728 | } | ||
490 | } | 729 | } |
491 | } | 730 | } |
492 | 731 | ||
@@ -545,7 +784,7 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, | |||
545 | { | 784 | { |
546 | struct osd_state *osd = sd; | 785 | struct osd_state *osd = sd; |
547 | struct osd_window_state *win = &osd->win[layer]; | 786 | struct osd_window_state *win = &osd->win[layer]; |
548 | int bad_config; | 787 | int bad_config = 0; |
549 | 788 | ||
550 | /* verify that the pixel format is compatible with the layer */ | 789 | /* verify that the pixel format is compatible with the layer */ |
551 | switch (lconfig->pixfmt) { | 790 | switch (lconfig->pixfmt) { |
@@ -554,17 +793,25 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, | |||
554 | case PIXFMT_4BPP: | 793 | case PIXFMT_4BPP: |
555 | case PIXFMT_8BPP: | 794 | case PIXFMT_8BPP: |
556 | case PIXFMT_RGB565: | 795 | case PIXFMT_RGB565: |
557 | bad_config = !is_osd_win(layer); | 796 | if (osd->vpbe_type == VPBE_VERSION_1) |
797 | bad_config = !is_vid_win(layer); | ||
558 | break; | 798 | break; |
559 | case PIXFMT_YCbCrI: | 799 | case PIXFMT_YCbCrI: |
560 | case PIXFMT_YCrCbI: | 800 | case PIXFMT_YCrCbI: |
561 | bad_config = !is_vid_win(layer); | 801 | bad_config = !is_vid_win(layer); |
562 | break; | 802 | break; |
563 | case PIXFMT_RGB888: | 803 | case PIXFMT_RGB888: |
564 | bad_config = !is_vid_win(layer); | 804 | if (osd->vpbe_type == VPBE_VERSION_1) |
805 | bad_config = !is_vid_win(layer); | ||
806 | else if ((osd->vpbe_type == VPBE_VERSION_3) || | ||
807 | (osd->vpbe_type == VPBE_VERSION_2)) | ||
808 | bad_config = !is_osd_win(layer); | ||
565 | break; | 809 | break; |
566 | case PIXFMT_NV12: | 810 | case PIXFMT_NV12: |
567 | bad_config = 1; | 811 | if (osd->vpbe_type != VPBE_VERSION_2) |
812 | bad_config = 1; | ||
813 | else | ||
814 | bad_config = is_osd_win(layer); | ||
568 | break; | 815 | break; |
569 | case PIXFMT_OSD_ATTR: | 816 | case PIXFMT_OSD_ATTR: |
570 | bad_config = (layer != WIN_OSD1); | 817 | bad_config = (layer != WIN_OSD1); |
@@ -584,7 +831,8 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, | |||
584 | 831 | ||
585 | /* DM6446: */ | 832 | /* DM6446: */ |
586 | /* only one OSD window at a time can use RGB pixel formats */ | 833 | /* only one OSD window at a time can use RGB pixel formats */ |
587 | if (is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) { | 834 | if ((osd->vpbe_type == VPBE_VERSION_1) && |
835 | is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) { | ||
588 | enum osd_pix_format pixfmt; | 836 | enum osd_pix_format pixfmt; |
589 | if (layer == WIN_OSD0) | 837 | if (layer == WIN_OSD0) |
590 | pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt; | 838 | pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt; |
@@ -602,7 +850,8 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, | |||
602 | } | 850 | } |
603 | 851 | ||
604 | /* DM6446: only one video window at a time can use RGB888 */ | 852 | /* DM6446: only one video window at a time can use RGB888 */ |
605 | if (is_vid_win(layer) && lconfig->pixfmt == PIXFMT_RGB888) { | 853 | if ((osd->vpbe_type == VPBE_VERSION_1) && is_vid_win(layer) && |
854 | lconfig->pixfmt == PIXFMT_RGB888) { | ||
606 | enum osd_pix_format pixfmt; | 855 | enum osd_pix_format pixfmt; |
607 | 856 | ||
608 | if (layer == WIN_VID0) | 857 | if (layer == WIN_VID0) |
@@ -652,7 +901,8 @@ static void _osd_disable_vid_rgb888(struct osd_state *sd) | |||
652 | * The caller must ensure that neither video window is currently | 901 | * The caller must ensure that neither video window is currently |
653 | * configured for RGB888 pixel format. | 902 | * configured for RGB888 pixel format. |
654 | */ | 903 | */ |
655 | osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL); | 904 | if (sd->vpbe_type == VPBE_VERSION_1) |
905 | osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL); | ||
656 | } | 906 | } |
657 | 907 | ||
658 | static void _osd_enable_vid_rgb888(struct osd_state *sd, | 908 | static void _osd_enable_vid_rgb888(struct osd_state *sd, |
@@ -665,13 +915,14 @@ static void _osd_enable_vid_rgb888(struct osd_state *sd, | |||
665 | * currently configured for RGB888 pixel format, as this routine will | 915 | * currently configured for RGB888 pixel format, as this routine will |
666 | * disable RGB888 pixel format for the other window. | 916 | * disable RGB888 pixel format for the other window. |
667 | */ | 917 | */ |
668 | if (layer == WIN_VID0) { | 918 | if (sd->vpbe_type == VPBE_VERSION_1) { |
669 | osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, | 919 | if (layer == WIN_VID0) |
670 | OSD_MISCCTL_RGBEN, OSD_MISCCTL); | 920 | osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, |
671 | } else if (layer == WIN_VID1) { | 921 | OSD_MISCCTL_RGBEN, OSD_MISCCTL); |
672 | osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, | 922 | else if (layer == WIN_VID1) |
673 | OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, | 923 | osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, |
674 | OSD_MISCCTL); | 924 | OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, |
925 | OSD_MISCCTL); | ||
675 | } | 926 | } |
676 | } | 927 | } |
677 | 928 | ||
@@ -697,9 +948,30 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, | |||
697 | 948 | ||
698 | switch (layer) { | 949 | switch (layer) { |
699 | case WIN_OSD0: | 950 | case WIN_OSD0: |
700 | winmd_mask |= OSD_OSDWIN0MD_RGB0E; | 951 | if (sd->vpbe_type == VPBE_VERSION_1) { |
701 | if (lconfig->pixfmt == PIXFMT_RGB565) | 952 | winmd_mask |= OSD_OSDWIN0MD_RGB0E; |
702 | winmd |= OSD_OSDWIN0MD_RGB0E; | 953 | if (lconfig->pixfmt == PIXFMT_RGB565) |
954 | winmd |= OSD_OSDWIN0MD_RGB0E; | ||
955 | } else if ((sd->vpbe_type == VPBE_VERSION_3) || | ||
956 | (sd->vpbe_type == VPBE_VERSION_2)) { | ||
957 | winmd_mask |= OSD_OSDWIN0MD_BMP0MD; | ||
958 | switch (lconfig->pixfmt) { | ||
959 | case PIXFMT_RGB565: | ||
960 | winmd |= (1 << | ||
961 | OSD_OSDWIN0MD_BMP0MD_SHIFT); | ||
962 | break; | ||
963 | case PIXFMT_RGB888: | ||
964 | winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT); | ||
965 | _osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0); | ||
966 | break; | ||
967 | case PIXFMT_YCbCrI: | ||
968 | case PIXFMT_YCrCbI: | ||
969 | winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT); | ||
970 | break; | ||
971 | default: | ||
972 | break; | ||
973 | } | ||
974 | } | ||
703 | 975 | ||
704 | winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0; | 976 | winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0; |
705 | 977 | ||
@@ -749,12 +1021,59 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, | |||
749 | * For YUV420P format the register contents are | 1021 | * For YUV420P format the register contents are |
750 | * duplicated in both VID registers | 1022 | * duplicated in both VID registers |
751 | */ | 1023 | */ |
1024 | if ((sd->vpbe_type == VPBE_VERSION_2) && | ||
1025 | (lconfig->pixfmt == PIXFMT_NV12)) { | ||
1026 | /* other window also */ | ||
1027 | if (lconfig->interlaced) { | ||
1028 | winmd_mask |= OSD_VIDWINMD_VFF1; | ||
1029 | winmd |= OSD_VIDWINMD_VFF1; | ||
1030 | osd_modify(sd, winmd_mask, winmd, | ||
1031 | OSD_VIDWINMD); | ||
1032 | } | ||
1033 | |||
1034 | osd_modify(sd, OSD_MISCCTL_S420D, | ||
1035 | OSD_MISCCTL_S420D, OSD_MISCCTL); | ||
1036 | osd_write(sd, lconfig->line_length >> 5, | ||
1037 | OSD_VIDWIN1OFST); | ||
1038 | osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP); | ||
1039 | osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL); | ||
1040 | /* | ||
1041 | * if NV21 pixfmt and line length not 32B | ||
1042 | * aligned (e.g. NTSC), Need to set window | ||
1043 | * X pixel size to be 32B aligned as well | ||
1044 | */ | ||
1045 | if (lconfig->xsize % 32) { | ||
1046 | osd_write(sd, | ||
1047 | ((lconfig->xsize + 31) & ~31), | ||
1048 | OSD_VIDWIN1XL); | ||
1049 | osd_write(sd, | ||
1050 | ((lconfig->xsize + 31) & ~31), | ||
1051 | OSD_VIDWIN0XL); | ||
1052 | } | ||
1053 | } else if ((sd->vpbe_type == VPBE_VERSION_2) && | ||
1054 | (lconfig->pixfmt != PIXFMT_NV12)) { | ||
1055 | osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D, | ||
1056 | OSD_MISCCTL); | ||
1057 | } | ||
1058 | |||
752 | if (lconfig->interlaced) { | 1059 | if (lconfig->interlaced) { |
753 | osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP); | 1060 | osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP); |
754 | osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL); | 1061 | osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL); |
1062 | if ((sd->vpbe_type == VPBE_VERSION_2) && | ||
1063 | lconfig->pixfmt == PIXFMT_NV12) { | ||
1064 | osd_write(sd, lconfig->ypos >> 1, | ||
1065 | OSD_VIDWIN1YP); | ||
1066 | osd_write(sd, lconfig->ysize >> 1, | ||
1067 | OSD_VIDWIN1YL); | ||
1068 | } | ||
755 | } else { | 1069 | } else { |
756 | osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP); | 1070 | osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP); |
757 | osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL); | 1071 | osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL); |
1072 | if ((sd->vpbe_type == VPBE_VERSION_2) && | ||
1073 | lconfig->pixfmt == PIXFMT_NV12) { | ||
1074 | osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP); | ||
1075 | osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL); | ||
1076 | } | ||
758 | } | 1077 | } |
759 | break; | 1078 | break; |
760 | case WIN_OSD1: | 1079 | case WIN_OSD1: |
@@ -764,14 +1083,43 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, | |||
764 | * attribute mode to a normal mode. | 1083 | * attribute mode to a normal mode. |
765 | */ | 1084 | */ |
766 | if (lconfig->pixfmt == PIXFMT_OSD_ATTR) { | 1085 | if (lconfig->pixfmt == PIXFMT_OSD_ATTR) { |
767 | winmd_mask |= | 1086 | if (sd->vpbe_type == VPBE_VERSION_1) { |
768 | OSD_OSDWIN1MD_ATN1E | OSD_OSDWIN1MD_RGB1E | | 1087 | winmd_mask |= OSD_OSDWIN1MD_ATN1E | |
769 | OSD_OSDWIN1MD_CLUTS1 | | 1088 | OSD_OSDWIN1MD_RGB1E | OSD_OSDWIN1MD_CLUTS1 | |
770 | OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1; | 1089 | OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1; |
1090 | } else { | ||
1091 | winmd_mask |= OSD_OSDWIN1MD_BMP1MD | | ||
1092 | OSD_OSDWIN1MD_CLUTS1 | OSD_OSDWIN1MD_BLND1 | | ||
1093 | OSD_OSDWIN1MD_TE1; | ||
1094 | } | ||
771 | } else { | 1095 | } else { |
772 | winmd_mask |= OSD_OSDWIN1MD_RGB1E; | 1096 | if (sd->vpbe_type == VPBE_VERSION_1) { |
773 | if (lconfig->pixfmt == PIXFMT_RGB565) | 1097 | winmd_mask |= OSD_OSDWIN1MD_RGB1E; |
774 | winmd |= OSD_OSDWIN1MD_RGB1E; | 1098 | if (lconfig->pixfmt == PIXFMT_RGB565) |
1099 | winmd |= OSD_OSDWIN1MD_RGB1E; | ||
1100 | } else if ((sd->vpbe_type == VPBE_VERSION_3) | ||
1101 | || (sd->vpbe_type == VPBE_VERSION_2)) { | ||
1102 | winmd_mask |= OSD_OSDWIN1MD_BMP1MD; | ||
1103 | switch (lconfig->pixfmt) { | ||
1104 | case PIXFMT_RGB565: | ||
1105 | winmd |= | ||
1106 | (1 << OSD_OSDWIN1MD_BMP1MD_SHIFT); | ||
1107 | break; | ||
1108 | case PIXFMT_RGB888: | ||
1109 | winmd |= | ||
1110 | (2 << OSD_OSDWIN1MD_BMP1MD_SHIFT); | ||
1111 | _osd_enable_rgb888_pixblend(sd, | ||
1112 | OSDWIN_OSD1); | ||
1113 | break; | ||
1114 | case PIXFMT_YCbCrI: | ||
1115 | case PIXFMT_YCrCbI: | ||
1116 | winmd |= | ||
1117 | (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT); | ||
1118 | break; | ||
1119 | default: | ||
1120 | break; | ||
1121 | } | ||
1122 | } | ||
775 | 1123 | ||
776 | winmd_mask |= OSD_OSDWIN1MD_BMW1; | 1124 | winmd_mask |= OSD_OSDWIN1MD_BMW1; |
777 | switch (lconfig->pixfmt) { | 1125 | switch (lconfig->pixfmt) { |
@@ -822,15 +1170,45 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, | |||
822 | * For YUV420P format the register contents are | 1170 | * For YUV420P format the register contents are |
823 | * duplicated in both VID registers | 1171 | * duplicated in both VID registers |
824 | */ | 1172 | */ |
825 | osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D, | 1173 | if (sd->vpbe_type == VPBE_VERSION_2) { |
826 | OSD_MISCCTL); | 1174 | if (lconfig->pixfmt == PIXFMT_NV12) { |
1175 | /* other window also */ | ||
1176 | if (lconfig->interlaced) { | ||
1177 | winmd_mask |= OSD_VIDWINMD_VFF0; | ||
1178 | winmd |= OSD_VIDWINMD_VFF0; | ||
1179 | osd_modify(sd, winmd_mask, winmd, | ||
1180 | OSD_VIDWINMD); | ||
1181 | } | ||
1182 | osd_modify(sd, OSD_MISCCTL_S420D, | ||
1183 | OSD_MISCCTL_S420D, OSD_MISCCTL); | ||
1184 | osd_write(sd, lconfig->line_length >> 5, | ||
1185 | OSD_VIDWIN0OFST); | ||
1186 | osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP); | ||
1187 | osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL); | ||
1188 | } else { | ||
1189 | osd_modify(sd, OSD_MISCCTL_S420D, | ||
1190 | ~OSD_MISCCTL_S420D, OSD_MISCCTL); | ||
1191 | } | ||
1192 | } | ||
827 | 1193 | ||
828 | if (lconfig->interlaced) { | 1194 | if (lconfig->interlaced) { |
829 | osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP); | 1195 | osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP); |
830 | osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL); | 1196 | osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL); |
1197 | if ((sd->vpbe_type == VPBE_VERSION_2) && | ||
1198 | lconfig->pixfmt == PIXFMT_NV12) { | ||
1199 | osd_write(sd, lconfig->ypos >> 1, | ||
1200 | OSD_VIDWIN0YP); | ||
1201 | osd_write(sd, lconfig->ysize >> 1, | ||
1202 | OSD_VIDWIN0YL); | ||
1203 | } | ||
831 | } else { | 1204 | } else { |
832 | osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP); | 1205 | osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP); |
833 | osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL); | 1206 | osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL); |
1207 | if ((sd->vpbe_type == VPBE_VERSION_2) && | ||
1208 | lconfig->pixfmt == PIXFMT_NV12) { | ||
1209 | osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP); | ||
1210 | osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL); | ||
1211 | } | ||
834 | } | 1212 | } |
835 | break; | 1213 | break; |
836 | } | 1214 | } |
@@ -1089,6 +1467,11 @@ static void _osd_init(struct osd_state *sd) | |||
1089 | osd_write(sd, 0, OSD_OSDWIN1MD); | 1467 | osd_write(sd, 0, OSD_OSDWIN1MD); |
1090 | osd_write(sd, 0, OSD_RECTCUR); | 1468 | osd_write(sd, 0, OSD_RECTCUR); |
1091 | osd_write(sd, 0, OSD_MISCCTL); | 1469 | osd_write(sd, 0, OSD_MISCCTL); |
1470 | if (sd->vpbe_type == VPBE_VERSION_3) { | ||
1471 | osd_write(sd, 0, OSD_VBNDRY); | ||
1472 | osd_write(sd, 0, OSD_EXTMODE); | ||
1473 | osd_write(sd, OSD_MISCCTL_DMANG, OSD_MISCCTL); | ||
1474 | } | ||
1092 | } | 1475 | } |
1093 | 1476 | ||
1094 | static void osd_set_left_margin(struct osd_state *sd, u32 val) | 1477 | static void osd_set_left_margin(struct osd_state *sd, u32 val) |
@@ -1110,6 +1493,14 @@ static int osd_initialize(struct osd_state *osd) | |||
1110 | /* set default Cb/Cr order */ | 1493 | /* set default Cb/Cr order */ |
1111 | osd->yc_pixfmt = PIXFMT_YCbCrI; | 1494 | osd->yc_pixfmt = PIXFMT_YCbCrI; |
1112 | 1495 | ||
1496 | if (osd->vpbe_type == VPBE_VERSION_3) { | ||
1497 | /* | ||
1498 | * ROM CLUT1 on the DM355 is similar (identical?) to ROM CLUT0 | ||
1499 | * on the DM6446, so make ROM_CLUT1 the default on the DM355. | ||
1500 | */ | ||
1501 | osd->rom_clut = ROM_CLUT1; | ||
1502 | } | ||
1503 | |||
1113 | _osd_set_field_inversion(osd, osd->field_inversion); | 1504 | _osd_set_field_inversion(osd, osd->field_inversion); |
1114 | _osd_set_rom_clut(osd, osd->rom_clut); | 1505 | _osd_set_rom_clut(osd, osd->rom_clut); |
1115 | 1506 | ||
@@ -1208,23 +1599,7 @@ static struct platform_driver osd_driver = { | |||
1208 | }, | 1599 | }, |
1209 | }; | 1600 | }; |
1210 | 1601 | ||
1211 | static int osd_init(void) | 1602 | module_platform_driver(osd_driver); |
1212 | { | ||
1213 | if (platform_driver_register(&osd_driver)) { | ||
1214 | printk(KERN_ERR "Unable to register davinci osd driver\n"); | ||
1215 | return -ENODEV; | ||
1216 | } | ||
1217 | |||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1221 | static void osd_exit(void) | ||
1222 | { | ||
1223 | platform_driver_unregister(&osd_driver); | ||
1224 | } | ||
1225 | |||
1226 | module_init(osd_init); | ||
1227 | module_exit(osd_exit); | ||
1228 | 1603 | ||
1229 | MODULE_LICENSE("GPL"); | 1604 | MODULE_LICENSE("GPL"); |
1230 | MODULE_DESCRIPTION("DaVinci OSD Manager Driver"); | 1605 | MODULE_DESCRIPTION("DaVinci OSD Manager Driver"); |