aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/davinci/vpbe_osd.c473
1 files changed, 432 insertions, 41 deletions
diff --git a/drivers/media/video/davinci/vpbe_osd.c b/drivers/media/video/davinci/vpbe_osd.c
index ceccf430251..feeec2256c4 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
294static 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
276static void _osd_enable_color_key(struct osd_state *sd, 311static 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
473static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer, 555static 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
658static void _osd_enable_vid_rgb888(struct osd_state *sd, 908static 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
1094static void osd_set_left_margin(struct osd_state *sd, u32 val) 1477static 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