diff options
-rw-r--r-- | drivers/video/omap2/dss/apply.c | 2 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 562 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.h | 33 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 25 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 57 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.h | 1 | ||||
-rw-r--r-- | include/video/omapdss.h | 15 |
7 files changed, 510 insertions, 185 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 2b1fa851a8b9..19d66f471b4b 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c | |||
@@ -584,7 +584,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) | |||
584 | 584 | ||
585 | replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode); | 585 | replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode); |
586 | 586 | ||
587 | r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings); | 587 | r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false); |
588 | if (r) { | 588 | if (r) { |
589 | /* | 589 | /* |
590 | * We can't do much here, as this function can be called from | 590 | * We can't do much here, as this function can be called from |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 811fe381aaea..a173a9481a23 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -86,14 +86,15 @@ struct dispc_features { | |||
86 | u16 sw_max; | 86 | u16 sw_max; |
87 | u16 vp_max; | 87 | u16 vp_max; |
88 | u16 hp_max; | 88 | u16 hp_max; |
89 | int (*calc_scaling) (enum omap_channel channel, | 89 | int (*calc_scaling) (enum omap_plane plane, |
90 | const struct omap_video_timings *mgr_timings, | 90 | const struct omap_video_timings *mgr_timings, |
91 | u16 width, u16 height, u16 out_width, u16 out_height, | 91 | u16 width, u16 height, u16 out_width, u16 out_height, |
92 | enum omap_color_mode color_mode, bool *five_taps, | 92 | enum omap_color_mode color_mode, bool *five_taps, |
93 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | 93 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, |
94 | u16 pos_x, unsigned long *core_clk); | 94 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem); |
95 | unsigned long (*calc_core_clk) (enum omap_channel channel, | 95 | unsigned long (*calc_core_clk) (enum omap_plane plane, |
96 | u16 width, u16 height, u16 out_width, u16 out_height); | 96 | u16 width, u16 height, u16 out_width, u16 out_height, |
97 | bool mem_to_mem); | ||
97 | u8 num_fifos; | 98 | u8 num_fifos; |
98 | 99 | ||
99 | /* swap GFX & WB fifos */ | 100 | /* swap GFX & WB fifos */ |
@@ -235,7 +236,14 @@ static const struct { | |||
235 | }, | 236 | }, |
236 | }; | 237 | }; |
237 | 238 | ||
239 | struct color_conv_coef { | ||
240 | int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb; | ||
241 | int full_range; | ||
242 | }; | ||
243 | |||
238 | static void _omap_dispc_set_irqs(void); | 244 | static void _omap_dispc_set_irqs(void); |
245 | static unsigned long dispc_plane_pclk_rate(enum omap_plane plane); | ||
246 | static unsigned long dispc_plane_lclk_rate(enum omap_plane plane); | ||
239 | 247 | ||
240 | static inline void dispc_write_reg(const u16 idx, u32 val) | 248 | static inline void dispc_write_reg(const u16 idx, u32 val) |
241 | { | 249 | { |
@@ -533,6 +541,11 @@ u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) | |||
533 | return mgr_desc[channel].framedone_irq; | 541 | return mgr_desc[channel].framedone_irq; |
534 | } | 542 | } |
535 | 543 | ||
544 | u32 dispc_wb_get_framedone_irq(void) | ||
545 | { | ||
546 | return DISPC_IRQ_FRAMEDONEWB; | ||
547 | } | ||
548 | |||
536 | bool dispc_mgr_go_busy(enum omap_channel channel) | 549 | bool dispc_mgr_go_busy(enum omap_channel channel) |
537 | { | 550 | { |
538 | return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; | 551 | return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; |
@@ -560,6 +573,30 @@ void dispc_mgr_go(enum omap_channel channel) | |||
560 | mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); | 573 | mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); |
561 | } | 574 | } |
562 | 575 | ||
576 | bool dispc_wb_go_busy(void) | ||
577 | { | ||
578 | return REG_GET(DISPC_CONTROL2, 6, 6) == 1; | ||
579 | } | ||
580 | |||
581 | void dispc_wb_go(void) | ||
582 | { | ||
583 | enum omap_plane plane = OMAP_DSS_WB; | ||
584 | bool enable, go; | ||
585 | |||
586 | enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1; | ||
587 | |||
588 | if (!enable) | ||
589 | return; | ||
590 | |||
591 | go = REG_GET(DISPC_CONTROL2, 6, 6) == 1; | ||
592 | if (go) { | ||
593 | DSSERR("GO bit not down for WB\n"); | ||
594 | return; | ||
595 | } | ||
596 | |||
597 | REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6); | ||
598 | } | ||
599 | |||
563 | static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) | 600 | static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) |
564 | { | 601 | { |
565 | dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value); | 602 | dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value); |
@@ -642,41 +679,41 @@ static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc, | |||
642 | } | 679 | } |
643 | } | 680 | } |
644 | 681 | ||
645 | static void _dispc_setup_color_conv_coef(void) | ||
646 | { | ||
647 | int i; | ||
648 | const struct color_conv_coef { | ||
649 | int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb; | ||
650 | int full_range; | ||
651 | } ctbl_bt601_5 = { | ||
652 | 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, | ||
653 | }; | ||
654 | |||
655 | const struct color_conv_coef *ct; | ||
656 | 682 | ||
683 | static void dispc_ovl_write_color_conv_coef(enum omap_plane plane, | ||
684 | const struct color_conv_coef *ct) | ||
685 | { | ||
657 | #define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0)) | 686 | #define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0)) |
658 | 687 | ||
659 | ct = &ctbl_bt601_5; | 688 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 0), CVAL(ct->rcr, ct->ry)); |
689 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 1), CVAL(ct->gy, ct->rcb)); | ||
690 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 2), CVAL(ct->gcb, ct->gcr)); | ||
691 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 3), CVAL(ct->bcr, ct->by)); | ||
692 | dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 4), CVAL(0, ct->bcb)); | ||
660 | 693 | ||
661 | for (i = 1; i < dss_feat_get_num_ovls(); i++) { | 694 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), ct->full_range, 11, 11); |
662 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 0), | ||
663 | CVAL(ct->rcr, ct->ry)); | ||
664 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 1), | ||
665 | CVAL(ct->gy, ct->rcb)); | ||
666 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 2), | ||
667 | CVAL(ct->gcb, ct->gcr)); | ||
668 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 3), | ||
669 | CVAL(ct->bcr, ct->by)); | ||
670 | dispc_write_reg(DISPC_OVL_CONV_COEF(i, 4), | ||
671 | CVAL(0, ct->bcb)); | ||
672 | |||
673 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), ct->full_range, | ||
674 | 11, 11); | ||
675 | } | ||
676 | 695 | ||
677 | #undef CVAL | 696 | #undef CVAL |
678 | } | 697 | } |
679 | 698 | ||
699 | static void dispc_setup_color_conv_coef(void) | ||
700 | { | ||
701 | int i; | ||
702 | int num_ovl = dss_feat_get_num_ovls(); | ||
703 | int num_wb = dss_feat_get_num_wbs(); | ||
704 | const struct color_conv_coef ctbl_bt601_5_ovl = { | ||
705 | 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, | ||
706 | }; | ||
707 | const struct color_conv_coef ctbl_bt601_5_wb = { | ||
708 | 66, 112, -38, 129, -94, -74, 25, -18, 112, 0, | ||
709 | }; | ||
710 | |||
711 | for (i = 1; i < num_ovl; i++) | ||
712 | dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_ovl); | ||
713 | |||
714 | for (; i < num_wb; i++) | ||
715 | dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_wb); | ||
716 | } | ||
680 | 717 | ||
681 | static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr) | 718 | static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr) |
682 | { | 719 | { |
@@ -698,24 +735,32 @@ static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr) | |||
698 | dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr); | 735 | dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr); |
699 | } | 736 | } |
700 | 737 | ||
701 | static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y) | 738 | static void dispc_ovl_set_pos(enum omap_plane plane, |
739 | enum omap_overlay_caps caps, int x, int y) | ||
702 | { | 740 | { |
703 | u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); | 741 | u32 val; |
742 | |||
743 | if ((caps & OMAP_DSS_OVL_CAP_POS) == 0) | ||
744 | return; | ||
745 | |||
746 | val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); | ||
704 | 747 | ||
705 | dispc_write_reg(DISPC_OVL_POSITION(plane), val); | 748 | dispc_write_reg(DISPC_OVL_POSITION(plane), val); |
706 | } | 749 | } |
707 | 750 | ||
708 | static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height) | 751 | static void dispc_ovl_set_input_size(enum omap_plane plane, int width, |
752 | int height) | ||
709 | { | 753 | { |
710 | u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); | 754 | u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); |
711 | 755 | ||
712 | if (plane == OMAP_DSS_GFX) | 756 | if (plane == OMAP_DSS_GFX || plane == OMAP_DSS_WB) |
713 | dispc_write_reg(DISPC_OVL_SIZE(plane), val); | 757 | dispc_write_reg(DISPC_OVL_SIZE(plane), val); |
714 | else | 758 | else |
715 | dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); | 759 | dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); |
716 | } | 760 | } |
717 | 761 | ||
718 | static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height) | 762 | static void dispc_ovl_set_output_size(enum omap_plane plane, int width, |
763 | int height) | ||
719 | { | 764 | { |
720 | u32 val; | 765 | u32 val; |
721 | 766 | ||
@@ -723,14 +768,16 @@ static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height) | |||
723 | 768 | ||
724 | val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); | 769 | val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); |
725 | 770 | ||
726 | dispc_write_reg(DISPC_OVL_SIZE(plane), val); | 771 | if (plane == OMAP_DSS_WB) |
772 | dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); | ||
773 | else | ||
774 | dispc_write_reg(DISPC_OVL_SIZE(plane), val); | ||
727 | } | 775 | } |
728 | 776 | ||
729 | static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder) | 777 | static void dispc_ovl_set_zorder(enum omap_plane plane, |
778 | enum omap_overlay_caps caps, u8 zorder) | ||
730 | { | 779 | { |
731 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | 780 | if ((caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) |
732 | |||
733 | if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) | ||
734 | return; | 781 | return; |
735 | 782 | ||
736 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26); | 783 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26); |
@@ -747,23 +794,22 @@ static void dispc_ovl_enable_zorder_planes(void) | |||
747 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); | 794 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); |
748 | } | 795 | } |
749 | 796 | ||
750 | static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable) | 797 | static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, |
798 | enum omap_overlay_caps caps, bool enable) | ||
751 | { | 799 | { |
752 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | 800 | if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) |
753 | |||
754 | if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) | ||
755 | return; | 801 | return; |
756 | 802 | ||
757 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28); | 803 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28); |
758 | } | 804 | } |
759 | 805 | ||
760 | static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha) | 806 | static void dispc_ovl_setup_global_alpha(enum omap_plane plane, |
807 | enum omap_overlay_caps caps, u8 global_alpha) | ||
761 | { | 808 | { |
762 | static const unsigned shifts[] = { 0, 8, 16, 24, }; | 809 | static const unsigned shifts[] = { 0, 8, 16, 24, }; |
763 | int shift; | 810 | int shift; |
764 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | ||
765 | 811 | ||
766 | if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) | 812 | if ((caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) |
767 | return; | 813 | return; |
768 | 814 | ||
769 | shift = shifts[plane]; | 815 | shift = shifts[plane]; |
@@ -971,10 +1017,17 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) | |||
971 | return channel; | 1017 | return channel; |
972 | } | 1018 | } |
973 | 1019 | ||
1020 | void dispc_wb_set_channel_in(enum dss_writeback_channel channel) | ||
1021 | { | ||
1022 | enum omap_plane plane = OMAP_DSS_WB; | ||
1023 | |||
1024 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16); | ||
1025 | } | ||
1026 | |||
974 | static void dispc_ovl_set_burst_size(enum omap_plane plane, | 1027 | static void dispc_ovl_set_burst_size(enum omap_plane plane, |
975 | enum omap_burst_size burst_size) | 1028 | enum omap_burst_size burst_size) |
976 | { | 1029 | { |
977 | static const unsigned shifts[] = { 6, 14, 14, 14, }; | 1030 | static const unsigned shifts[] = { 6, 14, 14, 14, 14, }; |
978 | int shift; | 1031 | int shift; |
979 | 1032 | ||
980 | shift = shifts[plane]; | 1033 | shift = shifts[plane]; |
@@ -1051,11 +1104,15 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable) | |||
1051 | dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); | 1104 | dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); |
1052 | } | 1105 | } |
1053 | 1106 | ||
1054 | static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable) | 1107 | static void dispc_ovl_enable_replication(enum omap_plane plane, |
1108 | enum omap_overlay_caps caps, bool enable) | ||
1055 | { | 1109 | { |
1056 | static const unsigned shifts[] = { 5, 10, 10, 10 }; | 1110 | static const unsigned shifts[] = { 5, 10, 10, 10 }; |
1057 | int shift; | 1111 | int shift; |
1058 | 1112 | ||
1113 | if ((caps & OMAP_DSS_OVL_CAP_REPLICATION) == 0) | ||
1114 | return; | ||
1115 | |||
1059 | shift = shifts[plane]; | 1116 | shift = shifts[plane]; |
1060 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift); | 1117 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift); |
1061 | } | 1118 | } |
@@ -1202,6 +1259,14 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | |||
1202 | if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { | 1259 | if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { |
1203 | *fifo_low = ovl_fifo_size - burst_size * 2; | 1260 | *fifo_low = ovl_fifo_size - burst_size * 2; |
1204 | *fifo_high = total_fifo_size - burst_size; | 1261 | *fifo_high = total_fifo_size - burst_size; |
1262 | } else if (plane == OMAP_DSS_WB) { | ||
1263 | /* | ||
1264 | * Most optimal configuration for writeback is to push out data | ||
1265 | * to the interconnect the moment writeback pushes enough pixels | ||
1266 | * in the FIFO to form a burst | ||
1267 | */ | ||
1268 | *fifo_low = 0; | ||
1269 | *fifo_high = burst_size; | ||
1205 | } else { | 1270 | } else { |
1206 | *fifo_low = ovl_fifo_size - burst_size; | 1271 | *fifo_low = ovl_fifo_size - burst_size; |
1207 | *fifo_high = total_fifo_size - buf_unit; | 1272 | *fifo_high = total_fifo_size - buf_unit; |
@@ -1444,6 +1509,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
1444 | { | 1509 | { |
1445 | int scale_x = out_width != orig_width; | 1510 | int scale_x = out_width != orig_width; |
1446 | int scale_y = out_height != orig_height; | 1511 | int scale_y = out_height != orig_height; |
1512 | bool chroma_upscale = plane != OMAP_DSS_WB ? true : false; | ||
1447 | 1513 | ||
1448 | if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) | 1514 | if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) |
1449 | return; | 1515 | return; |
@@ -1451,7 +1517,8 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
1451 | color_mode != OMAP_DSS_COLOR_UYVY && | 1517 | color_mode != OMAP_DSS_COLOR_UYVY && |
1452 | color_mode != OMAP_DSS_COLOR_NV12)) { | 1518 | color_mode != OMAP_DSS_COLOR_NV12)) { |
1453 | /* reset chroma resampling for RGB formats */ | 1519 | /* reset chroma resampling for RGB formats */ |
1454 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); | 1520 | if (plane != OMAP_DSS_WB) |
1521 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); | ||
1455 | return; | 1522 | return; |
1456 | } | 1523 | } |
1457 | 1524 | ||
@@ -1460,23 +1527,34 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
1460 | 1527 | ||
1461 | switch (color_mode) { | 1528 | switch (color_mode) { |
1462 | case OMAP_DSS_COLOR_NV12: | 1529 | case OMAP_DSS_COLOR_NV12: |
1463 | /* UV is subsampled by 2 vertically*/ | 1530 | if (chroma_upscale) { |
1464 | orig_height >>= 1; | 1531 | /* UV is subsampled by 2 horizontally and vertically */ |
1465 | /* UV is subsampled by 2 horz.*/ | 1532 | orig_height >>= 1; |
1466 | orig_width >>= 1; | 1533 | orig_width >>= 1; |
1534 | } else { | ||
1535 | /* UV is downsampled by 2 horizontally and vertically */ | ||
1536 | orig_height <<= 1; | ||
1537 | orig_width <<= 1; | ||
1538 | } | ||
1539 | |||
1467 | break; | 1540 | break; |
1468 | case OMAP_DSS_COLOR_YUV2: | 1541 | case OMAP_DSS_COLOR_YUV2: |
1469 | case OMAP_DSS_COLOR_UYVY: | 1542 | case OMAP_DSS_COLOR_UYVY: |
1470 | /*For YUV422 with 90/270 rotation, | 1543 | /* For YUV422 with 90/270 rotation, we don't upsample chroma */ |
1471 | *we don't upsample chroma | ||
1472 | */ | ||
1473 | if (rotation == OMAP_DSS_ROT_0 || | 1544 | if (rotation == OMAP_DSS_ROT_0 || |
1474 | rotation == OMAP_DSS_ROT_180) | 1545 | rotation == OMAP_DSS_ROT_180) { |
1475 | /* UV is subsampled by 2 hrz*/ | 1546 | if (chroma_upscale) |
1476 | orig_width >>= 1; | 1547 | /* UV is subsampled by 2 horizontally */ |
1548 | orig_width >>= 1; | ||
1549 | else | ||
1550 | /* UV is downsampled by 2 horizontally */ | ||
1551 | orig_width <<= 1; | ||
1552 | } | ||
1553 | |||
1477 | /* must use FIR for YUV422 if rotated */ | 1554 | /* must use FIR for YUV422 if rotated */ |
1478 | if (rotation != OMAP_DSS_ROT_0) | 1555 | if (rotation != OMAP_DSS_ROT_0) |
1479 | scale_x = scale_y = true; | 1556 | scale_x = scale_y = true; |
1557 | |||
1480 | break; | 1558 | break; |
1481 | default: | 1559 | default: |
1482 | BUG(); | 1560 | BUG(); |
@@ -1492,8 +1570,10 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, | |||
1492 | out_width, out_height, five_taps, | 1570 | out_width, out_height, five_taps, |
1493 | rotation, DISPC_COLOR_COMPONENT_UV); | 1571 | rotation, DISPC_COLOR_COMPONENT_UV); |
1494 | 1572 | ||
1495 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), | 1573 | if (plane != OMAP_DSS_WB) |
1496 | (scale_x || scale_y) ? 1 : 0, 8, 8); | 1574 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), |
1575 | (scale_x || scale_y) ? 1 : 0, 8, 8); | ||
1576 | |||
1497 | /* set H scaling */ | 1577 | /* set H scaling */ |
1498 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5); | 1578 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5); |
1499 | /* set V scaling */ | 1579 | /* set V scaling */ |
@@ -1909,22 +1989,19 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width, | |||
1909 | * This function is used to avoid synclosts in OMAP3, because of some | 1989 | * This function is used to avoid synclosts in OMAP3, because of some |
1910 | * undocumented horizontal position and timing related limitations. | 1990 | * undocumented horizontal position and timing related limitations. |
1911 | */ | 1991 | */ |
1912 | static int check_horiz_timing_omap3(enum omap_channel channel, | 1992 | static int check_horiz_timing_omap3(enum omap_plane plane, |
1913 | const struct omap_video_timings *t, u16 pos_x, | 1993 | const struct omap_video_timings *t, u16 pos_x, |
1914 | u16 width, u16 height, u16 out_width, u16 out_height) | 1994 | u16 width, u16 height, u16 out_width, u16 out_height) |
1915 | { | 1995 | { |
1916 | int DS = DIV_ROUND_UP(height, out_height); | 1996 | int DS = DIV_ROUND_UP(height, out_height); |
1917 | unsigned long nonactive, lclk, pclk; | 1997 | unsigned long nonactive; |
1918 | static const u8 limits[3] = { 8, 10, 20 }; | 1998 | static const u8 limits[3] = { 8, 10, 20 }; |
1919 | u64 val, blank; | 1999 | u64 val, blank; |
2000 | unsigned long pclk = dispc_plane_pclk_rate(plane); | ||
2001 | unsigned long lclk = dispc_plane_lclk_rate(plane); | ||
1920 | int i; | 2002 | int i; |
1921 | 2003 | ||
1922 | nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; | 2004 | nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; |
1923 | pclk = dispc_mgr_pclk_rate(channel); | ||
1924 | if (dss_mgr_is_lcd(channel)) | ||
1925 | lclk = dispc_mgr_lclk_rate(channel); | ||
1926 | else | ||
1927 | lclk = dispc_fclk_rate(); | ||
1928 | 2005 | ||
1929 | i = 0; | 2006 | i = 0; |
1930 | if (out_height < height) | 2007 | if (out_height < height) |
@@ -1961,13 +2038,14 @@ static int check_horiz_timing_omap3(enum omap_channel channel, | |||
1961 | return 0; | 2038 | return 0; |
1962 | } | 2039 | } |
1963 | 2040 | ||
1964 | static unsigned long calc_core_clk_five_taps(enum omap_channel channel, | 2041 | static unsigned long calc_core_clk_five_taps(enum omap_plane plane, |
1965 | const struct omap_video_timings *mgr_timings, u16 width, | 2042 | const struct omap_video_timings *mgr_timings, u16 width, |
1966 | u16 height, u16 out_width, u16 out_height, | 2043 | u16 height, u16 out_width, u16 out_height, |
1967 | enum omap_color_mode color_mode) | 2044 | enum omap_color_mode color_mode) |
1968 | { | 2045 | { |
1969 | u32 core_clk = 0; | 2046 | u32 core_clk = 0; |
1970 | u64 tmp, pclk = dispc_mgr_pclk_rate(channel); | 2047 | u64 tmp; |
2048 | unsigned long pclk = dispc_plane_pclk_rate(plane); | ||
1971 | 2049 | ||
1972 | if (height <= out_height && width <= out_width) | 2050 | if (height <= out_height && width <= out_width) |
1973 | return (unsigned long) pclk; | 2051 | return (unsigned long) pclk; |
@@ -2001,10 +2079,10 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel, | |||
2001 | return core_clk; | 2079 | return core_clk; |
2002 | } | 2080 | } |
2003 | 2081 | ||
2004 | static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width, | 2082 | static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, |
2005 | u16 height, u16 out_width, u16 out_height) | 2083 | u16 height, u16 out_width, u16 out_height, bool mem_to_mem) |
2006 | { | 2084 | { |
2007 | unsigned long pclk = dispc_mgr_pclk_rate(channel); | 2085 | unsigned long pclk = dispc_plane_pclk_rate(plane); |
2008 | 2086 | ||
2009 | if (height > out_height && width > out_width) | 2087 | if (height > out_height && width > out_width) |
2010 | return pclk * 4; | 2088 | return pclk * 4; |
@@ -2012,11 +2090,11 @@ static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width, | |||
2012 | return pclk * 2; | 2090 | return pclk * 2; |
2013 | } | 2091 | } |
2014 | 2092 | ||
2015 | static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width, | 2093 | static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, |
2016 | u16 height, u16 out_width, u16 out_height) | 2094 | u16 height, u16 out_width, u16 out_height, bool mem_to_mem) |
2017 | { | 2095 | { |
2018 | unsigned int hf, vf; | 2096 | unsigned int hf, vf; |
2019 | unsigned long pclk = dispc_mgr_pclk_rate(channel); | 2097 | unsigned long pclk = dispc_plane_pclk_rate(plane); |
2020 | 2098 | ||
2021 | /* | 2099 | /* |
2022 | * FIXME how to determine the 'A' factor | 2100 | * FIXME how to determine the 'A' factor |
@@ -2039,10 +2117,21 @@ static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width, | |||
2039 | return pclk * vf * hf; | 2117 | return pclk * vf * hf; |
2040 | } | 2118 | } |
2041 | 2119 | ||
2042 | static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width, | 2120 | static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width, |
2043 | u16 height, u16 out_width, u16 out_height) | 2121 | u16 height, u16 out_width, u16 out_height, bool mem_to_mem) |
2044 | { | 2122 | { |
2045 | unsigned long pclk = dispc_mgr_pclk_rate(channel); | 2123 | unsigned long pclk; |
2124 | |||
2125 | /* | ||
2126 | * If the overlay/writeback is in mem to mem mode, there are no | ||
2127 | * downscaling limitations with respect to pixel clock, return 1 as | ||
2128 | * required core clock to represent that we have sufficient enough | ||
2129 | * core clock to do maximum downscaling | ||
2130 | */ | ||
2131 | if (mem_to_mem) | ||
2132 | return 1; | ||
2133 | |||
2134 | pclk = dispc_plane_pclk_rate(plane); | ||
2046 | 2135 | ||
2047 | if (width > out_width) | 2136 | if (width > out_width) |
2048 | return DIV_ROUND_UP(pclk, out_width) * width; | 2137 | return DIV_ROUND_UP(pclk, out_width) * width; |
@@ -2050,25 +2139,26 @@ static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width, | |||
2050 | return pclk; | 2139 | return pclk; |
2051 | } | 2140 | } |
2052 | 2141 | ||
2053 | static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel, | 2142 | static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane, |
2054 | const struct omap_video_timings *mgr_timings, | 2143 | const struct omap_video_timings *mgr_timings, |
2055 | u16 width, u16 height, u16 out_width, u16 out_height, | 2144 | u16 width, u16 height, u16 out_width, u16 out_height, |
2056 | enum omap_color_mode color_mode, bool *five_taps, | 2145 | enum omap_color_mode color_mode, bool *five_taps, |
2057 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | 2146 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, |
2058 | u16 pos_x, unsigned long *core_clk) | 2147 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem) |
2059 | { | 2148 | { |
2060 | int error; | 2149 | int error; |
2061 | u16 in_width, in_height; | 2150 | u16 in_width, in_height; |
2062 | int min_factor = min(*decim_x, *decim_y); | 2151 | int min_factor = min(*decim_x, *decim_y); |
2063 | const int maxsinglelinewidth = | 2152 | const int maxsinglelinewidth = |
2064 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); | 2153 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); |
2154 | |||
2065 | *five_taps = false; | 2155 | *five_taps = false; |
2066 | 2156 | ||
2067 | do { | 2157 | do { |
2068 | in_height = DIV_ROUND_UP(height, *decim_y); | 2158 | in_height = DIV_ROUND_UP(height, *decim_y); |
2069 | in_width = DIV_ROUND_UP(width, *decim_x); | 2159 | in_width = DIV_ROUND_UP(width, *decim_x); |
2070 | *core_clk = dispc.feat->calc_core_clk(channel, in_width, | 2160 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, |
2071 | in_height, out_width, out_height); | 2161 | in_height, out_width, out_height, mem_to_mem); |
2072 | error = (in_width > maxsinglelinewidth || !*core_clk || | 2162 | error = (in_width > maxsinglelinewidth || !*core_clk || |
2073 | *core_clk > dispc_core_clk_rate()); | 2163 | *core_clk > dispc_core_clk_rate()); |
2074 | if (error) { | 2164 | if (error) { |
@@ -2090,12 +2180,12 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel, | |||
2090 | return 0; | 2180 | return 0; |
2091 | } | 2181 | } |
2092 | 2182 | ||
2093 | static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel, | 2183 | static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane, |
2094 | const struct omap_video_timings *mgr_timings, | 2184 | const struct omap_video_timings *mgr_timings, |
2095 | u16 width, u16 height, u16 out_width, u16 out_height, | 2185 | u16 width, u16 height, u16 out_width, u16 out_height, |
2096 | enum omap_color_mode color_mode, bool *five_taps, | 2186 | enum omap_color_mode color_mode, bool *five_taps, |
2097 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | 2187 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, |
2098 | u16 pos_x, unsigned long *core_clk) | 2188 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem) |
2099 | { | 2189 | { |
2100 | int error; | 2190 | int error; |
2101 | u16 in_width, in_height; | 2191 | u16 in_width, in_height; |
@@ -2106,19 +2196,21 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel, | |||
2106 | do { | 2196 | do { |
2107 | in_height = DIV_ROUND_UP(height, *decim_y); | 2197 | in_height = DIV_ROUND_UP(height, *decim_y); |
2108 | in_width = DIV_ROUND_UP(width, *decim_x); | 2198 | in_width = DIV_ROUND_UP(width, *decim_x); |
2109 | *core_clk = calc_core_clk_five_taps(channel, mgr_timings, | 2199 | *core_clk = calc_core_clk_five_taps(plane, mgr_timings, |
2110 | in_width, in_height, out_width, out_height, color_mode); | 2200 | in_width, in_height, out_width, out_height, color_mode); |
2111 | 2201 | ||
2112 | error = check_horiz_timing_omap3(channel, mgr_timings, pos_x, | 2202 | error = check_horiz_timing_omap3(plane, mgr_timings, |
2113 | in_width, in_height, out_width, out_height); | 2203 | pos_x, in_width, in_height, out_width, |
2204 | out_height); | ||
2114 | 2205 | ||
2115 | if (in_width > maxsinglelinewidth) | 2206 | if (in_width > maxsinglelinewidth) |
2116 | if (in_height > out_height && | 2207 | if (in_height > out_height && |
2117 | in_height < out_height * 2) | 2208 | in_height < out_height * 2) |
2118 | *five_taps = false; | 2209 | *five_taps = false; |
2119 | if (!*five_taps) | 2210 | if (!*five_taps) |
2120 | *core_clk = dispc.feat->calc_core_clk(channel, in_width, | 2211 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, |
2121 | in_height, out_width, out_height); | 2212 | in_height, out_width, out_height, |
2213 | mem_to_mem); | ||
2122 | 2214 | ||
2123 | error = (error || in_width > maxsinglelinewidth * 2 || | 2215 | error = (error || in_width > maxsinglelinewidth * 2 || |
2124 | (in_width > maxsinglelinewidth && *five_taps) || | 2216 | (in_width > maxsinglelinewidth && *five_taps) || |
@@ -2135,7 +2227,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel, | |||
2135 | } | 2227 | } |
2136 | } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); | 2228 | } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); |
2137 | 2229 | ||
2138 | if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height, | 2230 | if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height, |
2139 | out_width, out_height)){ | 2231 | out_width, out_height)){ |
2140 | DSSERR("horizontal timing too tight\n"); | 2232 | DSSERR("horizontal timing too tight\n"); |
2141 | return -EINVAL; | 2233 | return -EINVAL; |
@@ -2154,21 +2246,27 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel, | |||
2154 | return 0; | 2246 | return 0; |
2155 | } | 2247 | } |
2156 | 2248 | ||
2157 | static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel, | 2249 | static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, |
2158 | const struct omap_video_timings *mgr_timings, | 2250 | const struct omap_video_timings *mgr_timings, |
2159 | u16 width, u16 height, u16 out_width, u16 out_height, | 2251 | u16 width, u16 height, u16 out_width, u16 out_height, |
2160 | enum omap_color_mode color_mode, bool *five_taps, | 2252 | enum omap_color_mode color_mode, bool *five_taps, |
2161 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, | 2253 | int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, |
2162 | u16 pos_x, unsigned long *core_clk) | 2254 | u16 pos_x, unsigned long *core_clk, bool mem_to_mem) |
2163 | { | 2255 | { |
2164 | u16 in_width, in_width_max; | 2256 | u16 in_width, in_width_max; |
2165 | int decim_x_min = *decim_x; | 2257 | int decim_x_min = *decim_x; |
2166 | u16 in_height = DIV_ROUND_UP(height, *decim_y); | 2258 | u16 in_height = DIV_ROUND_UP(height, *decim_y); |
2167 | const int maxsinglelinewidth = | 2259 | const int maxsinglelinewidth = |
2168 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); | 2260 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); |
2261 | unsigned long pclk = dispc_plane_pclk_rate(plane); | ||
2262 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | ||
2263 | |||
2264 | if (mem_to_mem) | ||
2265 | in_width_max = DIV_ROUND_UP(out_width, maxdownscale); | ||
2266 | else | ||
2267 | in_width_max = dispc_core_clk_rate() / | ||
2268 | DIV_ROUND_UP(pclk, out_width); | ||
2169 | 2269 | ||
2170 | in_width_max = dispc_core_clk_rate() / | ||
2171 | DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width); | ||
2172 | *decim_x = DIV_ROUND_UP(width, in_width_max); | 2270 | *decim_x = DIV_ROUND_UP(width, in_width_max); |
2173 | 2271 | ||
2174 | *decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min; | 2272 | *decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min; |
@@ -2185,20 +2283,19 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel, | |||
2185 | return -EINVAL; | 2283 | return -EINVAL; |
2186 | } | 2284 | } |
2187 | 2285 | ||
2188 | *core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height, | 2286 | *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height, |
2189 | out_width, out_height); | 2287 | out_width, out_height, mem_to_mem); |
2190 | return 0; | 2288 | return 0; |
2191 | } | 2289 | } |
2192 | 2290 | ||
2193 | static int dispc_ovl_calc_scaling(enum omap_plane plane, | 2291 | static int dispc_ovl_calc_scaling(enum omap_plane plane, |
2194 | enum omap_channel channel, | 2292 | enum omap_overlay_caps caps, |
2195 | const struct omap_video_timings *mgr_timings, | 2293 | const struct omap_video_timings *mgr_timings, |
2196 | u16 width, u16 height, u16 out_width, u16 out_height, | 2294 | u16 width, u16 height, u16 out_width, u16 out_height, |
2197 | enum omap_color_mode color_mode, bool *five_taps, | 2295 | enum omap_color_mode color_mode, bool *five_taps, |
2198 | int *x_predecim, int *y_predecim, u16 pos_x, | 2296 | int *x_predecim, int *y_predecim, u16 pos_x, |
2199 | enum omap_dss_rotation_type rotation_type) | 2297 | enum omap_dss_rotation_type rotation_type, bool mem_to_mem) |
2200 | { | 2298 | { |
2201 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | ||
2202 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | 2299 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); |
2203 | const int max_decim_limit = 16; | 2300 | const int max_decim_limit = 16; |
2204 | unsigned long core_clk = 0; | 2301 | unsigned long core_clk = 0; |
@@ -2207,7 +2304,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
2207 | if (width == out_width && height == out_height) | 2304 | if (width == out_width && height == out_height) |
2208 | return 0; | 2305 | return 0; |
2209 | 2306 | ||
2210 | if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) | 2307 | if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0) |
2211 | return -EINVAL; | 2308 | return -EINVAL; |
2212 | 2309 | ||
2213 | *x_predecim = max_decim_limit; | 2310 | *x_predecim = max_decim_limit; |
@@ -2233,9 +2330,10 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
2233 | if (decim_y > *y_predecim || out_height > height * 8) | 2330 | if (decim_y > *y_predecim || out_height > height * 8) |
2234 | return -EINVAL; | 2331 | return -EINVAL; |
2235 | 2332 | ||
2236 | ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height, | 2333 | ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height, |
2237 | out_width, out_height, color_mode, five_taps, x_predecim, | 2334 | out_width, out_height, color_mode, five_taps, |
2238 | y_predecim, &decim_x, &decim_y, pos_x, &core_clk); | 2335 | x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk, |
2336 | mem_to_mem); | ||
2239 | if (ret) | 2337 | if (ret) |
2240 | return ret; | 2338 | return ret; |
2241 | 2339 | ||
@@ -2255,70 +2353,64 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
2255 | return 0; | 2353 | return 0; |
2256 | } | 2354 | } |
2257 | 2355 | ||
2258 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 2356 | static int dispc_ovl_setup_common(enum omap_plane plane, |
2259 | bool replication, const struct omap_video_timings *mgr_timings) | 2357 | enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr, |
2358 | u16 screen_width, int pos_x, int pos_y, u16 width, u16 height, | ||
2359 | u16 out_width, u16 out_height, enum omap_color_mode color_mode, | ||
2360 | u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha, | ||
2361 | u8 global_alpha, enum omap_dss_rotation_type rotation_type, | ||
2362 | bool replication, const struct omap_video_timings *mgr_timings, | ||
2363 | bool mem_to_mem) | ||
2260 | { | 2364 | { |
2261 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | ||
2262 | bool five_taps = true; | 2365 | bool five_taps = true; |
2263 | bool fieldmode = 0; | 2366 | bool fieldmode = 0; |
2264 | int r, cconv = 0; | 2367 | int r, cconv = 0; |
2265 | unsigned offset0, offset1; | 2368 | unsigned offset0, offset1; |
2266 | s32 row_inc; | 2369 | s32 row_inc; |
2267 | s32 pix_inc; | 2370 | s32 pix_inc; |
2268 | u16 frame_height = oi->height; | 2371 | u16 frame_height = height; |
2269 | unsigned int field_offset = 0; | 2372 | unsigned int field_offset = 0; |
2270 | u16 in_height = oi->height; | 2373 | u16 in_height = height; |
2271 | u16 in_width = oi->width; | 2374 | u16 in_width = width; |
2272 | u16 out_width, out_height; | ||
2273 | enum omap_channel channel; | ||
2274 | int x_predecim = 1, y_predecim = 1; | 2375 | int x_predecim = 1, y_predecim = 1; |
2275 | bool ilace = mgr_timings->interlace; | 2376 | bool ilace = mgr_timings->interlace; |
2276 | 2377 | ||
2277 | channel = dispc_ovl_get_channel_out(plane); | 2378 | if (paddr == 0) |
2278 | |||
2279 | DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " | ||
2280 | "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n", | ||
2281 | plane, oi->paddr, oi->p_uv_addr, | ||
2282 | oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, | ||
2283 | oi->out_width, oi->out_height, oi->color_mode, oi->rotation, | ||
2284 | oi->mirror, ilace, channel, replication); | ||
2285 | |||
2286 | if (oi->paddr == 0) | ||
2287 | return -EINVAL; | 2379 | return -EINVAL; |
2288 | 2380 | ||
2289 | out_width = oi->out_width == 0 ? oi->width : oi->out_width; | 2381 | out_width = out_width == 0 ? width : out_width; |
2290 | out_height = oi->out_height == 0 ? oi->height : oi->out_height; | 2382 | out_height = out_height == 0 ? height : out_height; |
2291 | 2383 | ||
2292 | if (ilace && oi->height == out_height) | 2384 | if (ilace && height == out_height) |
2293 | fieldmode = 1; | 2385 | fieldmode = 1; |
2294 | 2386 | ||
2295 | if (ilace) { | 2387 | if (ilace) { |
2296 | if (fieldmode) | 2388 | if (fieldmode) |
2297 | in_height /= 2; | 2389 | in_height /= 2; |
2298 | oi->pos_y /= 2; | 2390 | pos_y /= 2; |
2299 | out_height /= 2; | 2391 | out_height /= 2; |
2300 | 2392 | ||
2301 | DSSDBG("adjusting for ilace: height %d, pos_y %d, " | 2393 | DSSDBG("adjusting for ilace: height %d, pos_y %d, " |
2302 | "out_height %d\n", | 2394 | "out_height %d\n", in_height, pos_y, |
2303 | in_height, oi->pos_y, out_height); | 2395 | out_height); |
2304 | } | 2396 | } |
2305 | 2397 | ||
2306 | if (!dss_feat_color_mode_supported(plane, oi->color_mode)) | 2398 | if (!dss_feat_color_mode_supported(plane, color_mode)) |
2307 | return -EINVAL; | 2399 | return -EINVAL; |
2308 | 2400 | ||
2309 | r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width, | 2401 | r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width, |
2310 | in_height, out_width, out_height, oi->color_mode, | 2402 | in_height, out_width, out_height, color_mode, |
2311 | &five_taps, &x_predecim, &y_predecim, oi->pos_x, | 2403 | &five_taps, &x_predecim, &y_predecim, pos_x, |
2312 | oi->rotation_type); | 2404 | rotation_type, mem_to_mem); |
2313 | if (r) | 2405 | if (r) |
2314 | return r; | 2406 | return r; |
2315 | 2407 | ||
2316 | in_width = DIV_ROUND_UP(in_width, x_predecim); | 2408 | in_width = DIV_ROUND_UP(in_width, x_predecim); |
2317 | in_height = DIV_ROUND_UP(in_height, y_predecim); | 2409 | in_height = DIV_ROUND_UP(in_height, y_predecim); |
2318 | 2410 | ||
2319 | if (oi->color_mode == OMAP_DSS_COLOR_YUV2 || | 2411 | if (color_mode == OMAP_DSS_COLOR_YUV2 || |
2320 | oi->color_mode == OMAP_DSS_COLOR_UYVY || | 2412 | color_mode == OMAP_DSS_COLOR_UYVY || |
2321 | oi->color_mode == OMAP_DSS_COLOR_NV12) | 2413 | color_mode == OMAP_DSS_COLOR_NV12) |
2322 | cconv = 1; | 2414 | cconv = 1; |
2323 | 2415 | ||
2324 | if (ilace && !fieldmode) { | 2416 | if (ilace && !fieldmode) { |
@@ -2344,70 +2436,144 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | |||
2344 | row_inc = 0; | 2436 | row_inc = 0; |
2345 | pix_inc = 0; | 2437 | pix_inc = 0; |
2346 | 2438 | ||
2347 | if (oi->rotation_type == OMAP_DSS_ROT_TILER) | 2439 | if (rotation_type == OMAP_DSS_ROT_TILER) |
2348 | calc_tiler_rotation_offset(oi->screen_width, in_width, | 2440 | calc_tiler_rotation_offset(screen_width, in_width, |
2349 | oi->color_mode, fieldmode, field_offset, | 2441 | color_mode, fieldmode, field_offset, |
2350 | &offset0, &offset1, &row_inc, &pix_inc, | 2442 | &offset0, &offset1, &row_inc, &pix_inc, |
2351 | x_predecim, y_predecim); | 2443 | x_predecim, y_predecim); |
2352 | else if (oi->rotation_type == OMAP_DSS_ROT_DMA) | 2444 | else if (rotation_type == OMAP_DSS_ROT_DMA) |
2353 | calc_dma_rotation_offset(oi->rotation, oi->mirror, | 2445 | calc_dma_rotation_offset(rotation, mirror, |
2354 | oi->screen_width, in_width, frame_height, | 2446 | screen_width, in_width, frame_height, |
2355 | oi->color_mode, fieldmode, field_offset, | 2447 | color_mode, fieldmode, field_offset, |
2356 | &offset0, &offset1, &row_inc, &pix_inc, | 2448 | &offset0, &offset1, &row_inc, &pix_inc, |
2357 | x_predecim, y_predecim); | 2449 | x_predecim, y_predecim); |
2358 | else | 2450 | else |
2359 | calc_vrfb_rotation_offset(oi->rotation, oi->mirror, | 2451 | calc_vrfb_rotation_offset(rotation, mirror, |
2360 | oi->screen_width, in_width, frame_height, | 2452 | screen_width, in_width, frame_height, |
2361 | oi->color_mode, fieldmode, field_offset, | 2453 | color_mode, fieldmode, field_offset, |
2362 | &offset0, &offset1, &row_inc, &pix_inc, | 2454 | &offset0, &offset1, &row_inc, &pix_inc, |
2363 | x_predecim, y_predecim); | 2455 | x_predecim, y_predecim); |
2364 | 2456 | ||
2365 | DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", | 2457 | DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", |
2366 | offset0, offset1, row_inc, pix_inc); | 2458 | offset0, offset1, row_inc, pix_inc); |
2367 | 2459 | ||
2368 | dispc_ovl_set_color_mode(plane, oi->color_mode); | 2460 | dispc_ovl_set_color_mode(plane, color_mode); |
2369 | 2461 | ||
2370 | dispc_ovl_configure_burst_type(plane, oi->rotation_type); | 2462 | dispc_ovl_configure_burst_type(plane, rotation_type); |
2371 | 2463 | ||
2372 | dispc_ovl_set_ba0(plane, oi->paddr + offset0); | 2464 | dispc_ovl_set_ba0(plane, paddr + offset0); |
2373 | dispc_ovl_set_ba1(plane, oi->paddr + offset1); | 2465 | dispc_ovl_set_ba1(plane, paddr + offset1); |
2374 | 2466 | ||
2375 | if (OMAP_DSS_COLOR_NV12 == oi->color_mode) { | 2467 | if (OMAP_DSS_COLOR_NV12 == color_mode) { |
2376 | dispc_ovl_set_ba0_uv(plane, oi->p_uv_addr + offset0); | 2468 | dispc_ovl_set_ba0_uv(plane, p_uv_addr + offset0); |
2377 | dispc_ovl_set_ba1_uv(plane, oi->p_uv_addr + offset1); | 2469 | dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1); |
2378 | } | 2470 | } |
2379 | 2471 | ||
2380 | |||
2381 | dispc_ovl_set_row_inc(plane, row_inc); | 2472 | dispc_ovl_set_row_inc(plane, row_inc); |
2382 | dispc_ovl_set_pix_inc(plane, pix_inc); | 2473 | dispc_ovl_set_pix_inc(plane, pix_inc); |
2383 | 2474 | ||
2384 | DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width, | 2475 | DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, in_width, |
2385 | in_height, out_width, out_height); | 2476 | in_height, out_width, out_height); |
2386 | 2477 | ||
2387 | dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y); | 2478 | dispc_ovl_set_pos(plane, caps, pos_x, pos_y); |
2388 | 2479 | ||
2389 | dispc_ovl_set_pic_size(plane, in_width, in_height); | 2480 | dispc_ovl_set_input_size(plane, in_width, in_height); |
2390 | 2481 | ||
2391 | if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) { | 2482 | if (caps & OMAP_DSS_OVL_CAP_SCALE) { |
2392 | dispc_ovl_set_scaling(plane, in_width, in_height, out_width, | 2483 | dispc_ovl_set_scaling(plane, in_width, in_height, out_width, |
2393 | out_height, ilace, five_taps, fieldmode, | 2484 | out_height, ilace, five_taps, fieldmode, |
2394 | oi->color_mode, oi->rotation); | 2485 | color_mode, rotation); |
2395 | dispc_ovl_set_vid_size(plane, out_width, out_height); | 2486 | dispc_ovl_set_output_size(plane, out_width, out_height); |
2396 | dispc_ovl_set_vid_color_conv(plane, cconv); | 2487 | dispc_ovl_set_vid_color_conv(plane, cconv); |
2397 | } | 2488 | } |
2398 | 2489 | ||
2399 | dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror, | 2490 | dispc_ovl_set_rotation_attrs(plane, rotation, mirror, color_mode); |
2400 | oi->color_mode); | ||
2401 | 2491 | ||
2402 | dispc_ovl_set_zorder(plane, oi->zorder); | 2492 | dispc_ovl_set_zorder(plane, caps, zorder); |
2403 | dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha); | 2493 | dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha); |
2404 | dispc_ovl_setup_global_alpha(plane, oi->global_alpha); | 2494 | dispc_ovl_setup_global_alpha(plane, caps, global_alpha); |
2405 | 2495 | ||
2406 | dispc_ovl_enable_replication(plane, replication); | 2496 | dispc_ovl_enable_replication(plane, caps, replication); |
2407 | 2497 | ||
2408 | return 0; | 2498 | return 0; |
2409 | } | 2499 | } |
2410 | 2500 | ||
2501 | int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, | ||
2502 | bool replication, const struct omap_video_timings *mgr_timings, | ||
2503 | bool mem_to_mem) | ||
2504 | { | ||
2505 | int r; | ||
2506 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | ||
2507 | enum omap_channel channel; | ||
2508 | |||
2509 | channel = dispc_ovl_get_channel_out(plane); | ||
2510 | |||
2511 | DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " | ||
2512 | "%dx%d, cmode %x, rot %d, mir %d, chan %d repl %d\n", | ||
2513 | plane, oi->paddr, oi->p_uv_addr, oi->screen_width, oi->pos_x, | ||
2514 | oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height, | ||
2515 | oi->color_mode, oi->rotation, oi->mirror, channel, replication); | ||
2516 | |||
2517 | r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr, | ||
2518 | oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, | ||
2519 | oi->out_width, oi->out_height, oi->color_mode, oi->rotation, | ||
2520 | oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha, | ||
2521 | oi->rotation_type, replication, mgr_timings, mem_to_mem); | ||
2522 | |||
2523 | return r; | ||
2524 | } | ||
2525 | |||
2526 | int dispc_wb_setup(const struct omap_dss_writeback_info *wi, | ||
2527 | bool mem_to_mem, const struct omap_video_timings *mgr_timings) | ||
2528 | { | ||
2529 | int r; | ||
2530 | u32 l; | ||
2531 | enum omap_plane plane = OMAP_DSS_WB; | ||
2532 | const int pos_x = 0, pos_y = 0; | ||
2533 | const u8 zorder = 0, global_alpha = 0; | ||
2534 | const bool replication = false; | ||
2535 | bool truncation; | ||
2536 | int in_width = mgr_timings->x_res; | ||
2537 | int in_height = mgr_timings->y_res; | ||
2538 | enum omap_overlay_caps caps = | ||
2539 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA; | ||
2540 | |||
2541 | DSSDBG("dispc_wb_setup, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, " | ||
2542 | "rot %d, mir %d\n", wi->paddr, wi->p_uv_addr, in_width, | ||
2543 | in_height, wi->width, wi->height, wi->color_mode, wi->rotation, | ||
2544 | wi->mirror); | ||
2545 | |||
2546 | r = dispc_ovl_setup_common(plane, caps, wi->paddr, wi->p_uv_addr, | ||
2547 | wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width, | ||
2548 | wi->height, wi->color_mode, wi->rotation, wi->mirror, zorder, | ||
2549 | wi->pre_mult_alpha, global_alpha, wi->rotation_type, | ||
2550 | replication, mgr_timings, mem_to_mem); | ||
2551 | |||
2552 | switch (wi->color_mode) { | ||
2553 | case OMAP_DSS_COLOR_RGB16: | ||
2554 | case OMAP_DSS_COLOR_RGB24P: | ||
2555 | case OMAP_DSS_COLOR_ARGB16: | ||
2556 | case OMAP_DSS_COLOR_RGBA16: | ||
2557 | case OMAP_DSS_COLOR_RGB12U: | ||
2558 | case OMAP_DSS_COLOR_ARGB16_1555: | ||
2559 | case OMAP_DSS_COLOR_XRGB16_1555: | ||
2560 | case OMAP_DSS_COLOR_RGBX16: | ||
2561 | truncation = true; | ||
2562 | break; | ||
2563 | default: | ||
2564 | truncation = false; | ||
2565 | break; | ||
2566 | } | ||
2567 | |||
2568 | /* setup extra DISPC_WB_ATTRIBUTES */ | ||
2569 | l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); | ||
2570 | l = FLD_MOD(l, truncation, 10, 10); /* TRUNCATIONENABLE */ | ||
2571 | l = FLD_MOD(l, mem_to_mem, 19, 19); /* WRITEBACKMODE */ | ||
2572 | dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l); | ||
2573 | |||
2574 | return r; | ||
2575 | } | ||
2576 | |||
2411 | int dispc_ovl_enable(enum omap_plane plane, bool enable) | 2577 | int dispc_ovl_enable(enum omap_plane plane, bool enable) |
2412 | { | 2578 | { |
2413 | DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); | 2579 | DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); |
@@ -2560,6 +2726,47 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable) | |||
2560 | BUG(); | 2726 | BUG(); |
2561 | } | 2727 | } |
2562 | 2728 | ||
2729 | void dispc_wb_enable(bool enable) | ||
2730 | { | ||
2731 | enum omap_plane plane = OMAP_DSS_WB; | ||
2732 | struct completion frame_done_completion; | ||
2733 | bool is_on; | ||
2734 | int r; | ||
2735 | u32 irq; | ||
2736 | |||
2737 | is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); | ||
2738 | irq = DISPC_IRQ_FRAMEDONEWB; | ||
2739 | |||
2740 | if (!enable && is_on) { | ||
2741 | init_completion(&frame_done_completion); | ||
2742 | |||
2743 | r = omap_dispc_register_isr(dispc_disable_isr, | ||
2744 | &frame_done_completion, irq); | ||
2745 | if (r) | ||
2746 | DSSERR("failed to register FRAMEDONEWB isr\n"); | ||
2747 | } | ||
2748 | |||
2749 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0); | ||
2750 | |||
2751 | if (!enable && is_on) { | ||
2752 | if (!wait_for_completion_timeout(&frame_done_completion, | ||
2753 | msecs_to_jiffies(100))) | ||
2754 | DSSERR("timeout waiting for FRAMEDONEWB\n"); | ||
2755 | |||
2756 | r = omap_dispc_unregister_isr(dispc_disable_isr, | ||
2757 | &frame_done_completion, irq); | ||
2758 | if (r) | ||
2759 | DSSERR("failed to unregister FRAMEDONEWB isr\n"); | ||
2760 | } | ||
2761 | } | ||
2762 | |||
2763 | bool dispc_wb_is_enabled(void) | ||
2764 | { | ||
2765 | enum omap_plane plane = OMAP_DSS_WB; | ||
2766 | |||
2767 | return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); | ||
2768 | } | ||
2769 | |||
2563 | void dispc_lcd_enable_signal_polarity(bool act_high) | 2770 | void dispc_lcd_enable_signal_polarity(bool act_high) |
2564 | { | 2771 | { |
2565 | if (!dss_has_feature(FEAT_LCDENABLEPOL)) | 2772 | if (!dss_has_feature(FEAT_LCDENABLEPOL)) |
@@ -2963,6 +3170,23 @@ unsigned long dispc_core_clk_rate(void) | |||
2963 | return fclk / lcd; | 3170 | return fclk / lcd; |
2964 | } | 3171 | } |
2965 | 3172 | ||
3173 | static unsigned long dispc_plane_pclk_rate(enum omap_plane plane) | ||
3174 | { | ||
3175 | enum omap_channel channel = dispc_ovl_get_channel_out(plane); | ||
3176 | |||
3177 | return dispc_mgr_pclk_rate(channel); | ||
3178 | } | ||
3179 | |||
3180 | static unsigned long dispc_plane_lclk_rate(enum omap_plane plane) | ||
3181 | { | ||
3182 | enum omap_channel channel = dispc_ovl_get_channel_out(plane); | ||
3183 | |||
3184 | if (dss_mgr_is_lcd(channel)) | ||
3185 | return dispc_mgr_lclk_rate(channel); | ||
3186 | else | ||
3187 | return dispc_fclk_rate(); | ||
3188 | |||
3189 | } | ||
2966 | static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) | 3190 | static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) |
2967 | { | 3191 | { |
2968 | int lcd, pcd; | 3192 | int lcd, pcd; |
@@ -3756,7 +3980,7 @@ static void _omap_dispc_initial_config(void) | |||
3756 | if (dss_has_feature(FEAT_FUNCGATED)) | 3980 | if (dss_has_feature(FEAT_FUNCGATED)) |
3757 | REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); | 3981 | REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); |
3758 | 3982 | ||
3759 | _dispc_setup_color_conv_coef(); | 3983 | dispc_setup_color_conv_coef(); |
3760 | 3984 | ||
3761 | dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY); | 3985 | dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY); |
3762 | 3986 | ||
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h index 42e56cc7cdbc..222363c6e623 100644 --- a/drivers/video/omap2/dss/dispc.h +++ b/drivers/video/omap2/dss/dispc.h | |||
@@ -373,6 +373,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane) | |||
373 | case OMAP_DSS_VIDEO2: | 373 | case OMAP_DSS_VIDEO2: |
374 | return 0x0000; | 374 | return 0x0000; |
375 | case OMAP_DSS_VIDEO3: | 375 | case OMAP_DSS_VIDEO3: |
376 | case OMAP_DSS_WB: | ||
376 | return 0x0008; | 377 | return 0x0008; |
377 | default: | 378 | default: |
378 | BUG(); | 379 | BUG(); |
@@ -388,6 +389,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane) | |||
388 | case OMAP_DSS_VIDEO2: | 389 | case OMAP_DSS_VIDEO2: |
389 | return 0x0004; | 390 | return 0x0004; |
390 | case OMAP_DSS_VIDEO3: | 391 | case OMAP_DSS_VIDEO3: |
392 | case OMAP_DSS_WB: | ||
391 | return 0x000C; | 393 | return 0x000C; |
392 | default: | 394 | default: |
393 | BUG(); | 395 | BUG(); |
@@ -407,6 +409,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane) | |||
407 | return 0x04BC; | 409 | return 0x04BC; |
408 | case OMAP_DSS_VIDEO3: | 410 | case OMAP_DSS_VIDEO3: |
409 | return 0x0310; | 411 | return 0x0310; |
412 | case OMAP_DSS_WB: | ||
413 | return 0x0118; | ||
410 | default: | 414 | default: |
411 | BUG(); | 415 | BUG(); |
412 | return 0; | 416 | return 0; |
@@ -425,6 +429,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane) | |||
425 | return 0x04C0; | 429 | return 0x04C0; |
426 | case OMAP_DSS_VIDEO3: | 430 | case OMAP_DSS_VIDEO3: |
427 | return 0x0314; | 431 | return 0x0314; |
432 | case OMAP_DSS_WB: | ||
433 | return 0x011C; | ||
428 | default: | 434 | default: |
429 | BUG(); | 435 | BUG(); |
430 | return 0; | 436 | return 0; |
@@ -454,6 +460,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane) | |||
454 | case OMAP_DSS_VIDEO2: | 460 | case OMAP_DSS_VIDEO2: |
455 | return 0x000C; | 461 | return 0x000C; |
456 | case OMAP_DSS_VIDEO3: | 462 | case OMAP_DSS_VIDEO3: |
463 | case OMAP_DSS_WB: | ||
457 | return 0x00A8; | 464 | return 0x00A8; |
458 | default: | 465 | default: |
459 | BUG(); | 466 | BUG(); |
@@ -470,6 +477,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane) | |||
470 | case OMAP_DSS_VIDEO2: | 477 | case OMAP_DSS_VIDEO2: |
471 | return 0x0010; | 478 | return 0x0010; |
472 | case OMAP_DSS_VIDEO3: | 479 | case OMAP_DSS_VIDEO3: |
480 | case OMAP_DSS_WB: | ||
473 | return 0x0070; | 481 | return 0x0070; |
474 | default: | 482 | default: |
475 | BUG(); | 483 | BUG(); |
@@ -489,6 +497,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane) | |||
489 | return 0x04DC; | 497 | return 0x04DC; |
490 | case OMAP_DSS_VIDEO3: | 498 | case OMAP_DSS_VIDEO3: |
491 | return 0x032C; | 499 | return 0x032C; |
500 | case OMAP_DSS_WB: | ||
501 | return 0x0310; | ||
492 | default: | 502 | default: |
493 | BUG(); | 503 | BUG(); |
494 | return 0; | 504 | return 0; |
@@ -504,6 +514,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane) | |||
504 | case OMAP_DSS_VIDEO2: | 514 | case OMAP_DSS_VIDEO2: |
505 | return 0x0014; | 515 | return 0x0014; |
506 | case OMAP_DSS_VIDEO3: | 516 | case OMAP_DSS_VIDEO3: |
517 | case OMAP_DSS_WB: | ||
507 | return 0x008C; | 518 | return 0x008C; |
508 | default: | 519 | default: |
509 | BUG(); | 520 | BUG(); |
@@ -537,6 +548,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane) | |||
537 | case OMAP_DSS_VIDEO2: | 548 | case OMAP_DSS_VIDEO2: |
538 | return 0x001C; | 549 | return 0x001C; |
539 | case OMAP_DSS_VIDEO3: | 550 | case OMAP_DSS_VIDEO3: |
551 | case OMAP_DSS_WB: | ||
540 | return 0x00A4; | 552 | return 0x00A4; |
541 | default: | 553 | default: |
542 | BUG(); | 554 | BUG(); |
@@ -553,6 +565,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane) | |||
553 | case OMAP_DSS_VIDEO2: | 565 | case OMAP_DSS_VIDEO2: |
554 | return 0x0020; | 566 | return 0x0020; |
555 | case OMAP_DSS_VIDEO3: | 567 | case OMAP_DSS_VIDEO3: |
568 | case OMAP_DSS_WB: | ||
556 | return 0x0098; | 569 | return 0x0098; |
557 | default: | 570 | default: |
558 | BUG(); | 571 | BUG(); |
@@ -602,6 +615,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane) | |||
602 | case OMAP_DSS_VIDEO2: | 615 | case OMAP_DSS_VIDEO2: |
603 | return 0x0024; | 616 | return 0x0024; |
604 | case OMAP_DSS_VIDEO3: | 617 | case OMAP_DSS_VIDEO3: |
618 | case OMAP_DSS_WB: | ||
605 | return 0x0090; | 619 | return 0x0090; |
606 | default: | 620 | default: |
607 | BUG(); | 621 | BUG(); |
@@ -621,6 +635,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane) | |||
621 | return 0x055C; | 635 | return 0x055C; |
622 | case OMAP_DSS_VIDEO3: | 636 | case OMAP_DSS_VIDEO3: |
623 | return 0x0424; | 637 | return 0x0424; |
638 | case OMAP_DSS_WB: | ||
639 | return 0x290; | ||
624 | default: | 640 | default: |
625 | BUG(); | 641 | BUG(); |
626 | return 0; | 642 | return 0; |
@@ -637,6 +653,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane) | |||
637 | case OMAP_DSS_VIDEO2: | 653 | case OMAP_DSS_VIDEO2: |
638 | return 0x0028; | 654 | return 0x0028; |
639 | case OMAP_DSS_VIDEO3: | 655 | case OMAP_DSS_VIDEO3: |
656 | case OMAP_DSS_WB: | ||
640 | return 0x0094; | 657 | return 0x0094; |
641 | default: | 658 | default: |
642 | BUG(); | 659 | BUG(); |
@@ -655,6 +672,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane) | |||
655 | case OMAP_DSS_VIDEO2: | 672 | case OMAP_DSS_VIDEO2: |
656 | return 0x002C; | 673 | return 0x002C; |
657 | case OMAP_DSS_VIDEO3: | 674 | case OMAP_DSS_VIDEO3: |
675 | case OMAP_DSS_WB: | ||
658 | return 0x0000; | 676 | return 0x0000; |
659 | default: | 677 | default: |
660 | BUG(); | 678 | BUG(); |
@@ -674,6 +692,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane) | |||
674 | return 0x0560; | 692 | return 0x0560; |
675 | case OMAP_DSS_VIDEO3: | 693 | case OMAP_DSS_VIDEO3: |
676 | return 0x0428; | 694 | return 0x0428; |
695 | case OMAP_DSS_WB: | ||
696 | return 0x0294; | ||
677 | default: | 697 | default: |
678 | BUG(); | 698 | BUG(); |
679 | return 0; | 699 | return 0; |
@@ -690,6 +710,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane) | |||
690 | case OMAP_DSS_VIDEO2: | 710 | case OMAP_DSS_VIDEO2: |
691 | return 0x0030; | 711 | return 0x0030; |
692 | case OMAP_DSS_VIDEO3: | 712 | case OMAP_DSS_VIDEO3: |
713 | case OMAP_DSS_WB: | ||
693 | return 0x0004; | 714 | return 0x0004; |
694 | default: | 715 | default: |
695 | BUG(); | 716 | BUG(); |
@@ -709,6 +730,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane) | |||
709 | return 0x0564; | 730 | return 0x0564; |
710 | case OMAP_DSS_VIDEO3: | 731 | case OMAP_DSS_VIDEO3: |
711 | return 0x042C; | 732 | return 0x042C; |
733 | case OMAP_DSS_WB: | ||
734 | return 0x0298; | ||
712 | default: | 735 | default: |
713 | BUG(); | 736 | BUG(); |
714 | return 0; | 737 | return 0; |
@@ -726,6 +749,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i) | |||
726 | case OMAP_DSS_VIDEO2: | 749 | case OMAP_DSS_VIDEO2: |
727 | return 0x0034 + i * 0x8; | 750 | return 0x0034 + i * 0x8; |
728 | case OMAP_DSS_VIDEO3: | 751 | case OMAP_DSS_VIDEO3: |
752 | case OMAP_DSS_WB: | ||
729 | return 0x0010 + i * 0x8; | 753 | return 0x0010 + i * 0x8; |
730 | default: | 754 | default: |
731 | BUG(); | 755 | BUG(); |
@@ -746,6 +770,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i) | |||
746 | return 0x0568 + i * 0x8; | 770 | return 0x0568 + i * 0x8; |
747 | case OMAP_DSS_VIDEO3: | 771 | case OMAP_DSS_VIDEO3: |
748 | return 0x0430 + i * 0x8; | 772 | return 0x0430 + i * 0x8; |
773 | case OMAP_DSS_WB: | ||
774 | return 0x02A0 + i * 0x8; | ||
749 | default: | 775 | default: |
750 | BUG(); | 776 | BUG(); |
751 | return 0; | 777 | return 0; |
@@ -763,6 +789,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i) | |||
763 | case OMAP_DSS_VIDEO2: | 789 | case OMAP_DSS_VIDEO2: |
764 | return 0x0038 + i * 0x8; | 790 | return 0x0038 + i * 0x8; |
765 | case OMAP_DSS_VIDEO3: | 791 | case OMAP_DSS_VIDEO3: |
792 | case OMAP_DSS_WB: | ||
766 | return 0x0014 + i * 0x8; | 793 | return 0x0014 + i * 0x8; |
767 | default: | 794 | default: |
768 | BUG(); | 795 | BUG(); |
@@ -783,6 +810,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i) | |||
783 | return 0x056C + i * 0x8; | 810 | return 0x056C + i * 0x8; |
784 | case OMAP_DSS_VIDEO3: | 811 | case OMAP_DSS_VIDEO3: |
785 | return 0x0434 + i * 0x8; | 812 | return 0x0434 + i * 0x8; |
813 | case OMAP_DSS_WB: | ||
814 | return 0x02A4 + i * 0x8; | ||
786 | default: | 815 | default: |
787 | BUG(); | 816 | BUG(); |
788 | return 0; | 817 | return 0; |
@@ -799,6 +828,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i) | |||
799 | case OMAP_DSS_VIDEO1: | 828 | case OMAP_DSS_VIDEO1: |
800 | case OMAP_DSS_VIDEO2: | 829 | case OMAP_DSS_VIDEO2: |
801 | case OMAP_DSS_VIDEO3: | 830 | case OMAP_DSS_VIDEO3: |
831 | case OMAP_DSS_WB: | ||
802 | return 0x0074 + i * 0x4; | 832 | return 0x0074 + i * 0x4; |
803 | default: | 833 | default: |
804 | BUG(); | 834 | BUG(); |
@@ -818,6 +848,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i) | |||
818 | case OMAP_DSS_VIDEO2: | 848 | case OMAP_DSS_VIDEO2: |
819 | return 0x00B4 + i * 0x4; | 849 | return 0x00B4 + i * 0x4; |
820 | case OMAP_DSS_VIDEO3: | 850 | case OMAP_DSS_VIDEO3: |
851 | case OMAP_DSS_WB: | ||
821 | return 0x0050 + i * 0x4; | 852 | return 0x0050 + i * 0x4; |
822 | default: | 853 | default: |
823 | BUG(); | 854 | BUG(); |
@@ -838,6 +869,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i) | |||
838 | return 0x05A8 + i * 0x4; | 869 | return 0x05A8 + i * 0x4; |
839 | case OMAP_DSS_VIDEO3: | 870 | case OMAP_DSS_VIDEO3: |
840 | return 0x0470 + i * 0x4; | 871 | return 0x0470 + i * 0x4; |
872 | case OMAP_DSS_WB: | ||
873 | return 0x02E0 + i * 0x4; | ||
841 | default: | 874 | default: |
842 | BUG(); | 875 | BUG(); |
843 | return 0; | 876 | return 0; |
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index a14528bcfeab..6728892f9dad 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
@@ -113,6 +113,17 @@ enum dss_dsi_content_type { | |||
113 | DSS_DSI_CONTENT_GENERIC, | 113 | DSS_DSI_CONTENT_GENERIC, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | enum dss_writeback_channel { | ||
117 | DSS_WB_LCD1_MGR = 0, | ||
118 | DSS_WB_LCD2_MGR = 1, | ||
119 | DSS_WB_TV_MGR = 2, | ||
120 | DSS_WB_OVL0 = 3, | ||
121 | DSS_WB_OVL1 = 4, | ||
122 | DSS_WB_OVL2 = 5, | ||
123 | DSS_WB_OVL3 = 6, | ||
124 | DSS_WB_LCD3_MGR = 7, | ||
125 | }; | ||
126 | |||
116 | struct dss_clock_info { | 127 | struct dss_clock_info { |
117 | /* rates that we get with dividers below */ | 128 | /* rates that we get with dividers below */ |
118 | unsigned long fck; | 129 | unsigned long fck; |
@@ -444,8 +455,9 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); | |||
444 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | 455 | void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, |
445 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, | 456 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, |
446 | bool manual_update); | 457 | bool manual_update); |
447 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 458 | int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, |
448 | bool replication, const struct omap_video_timings *mgr_timings); | 459 | bool replication, const struct omap_video_timings *mgr_timings, |
460 | bool mem_to_mem); | ||
449 | int dispc_ovl_enable(enum omap_plane plane, bool enable); | 461 | int dispc_ovl_enable(enum omap_plane plane, bool enable); |
450 | void dispc_ovl_set_channel_out(enum omap_plane plane, | 462 | void dispc_ovl_set_channel_out(enum omap_plane plane, |
451 | enum omap_channel channel); | 463 | enum omap_channel channel); |
@@ -474,6 +486,15 @@ int dispc_mgr_get_clock_div(enum omap_channel channel, | |||
474 | void dispc_mgr_setup(enum omap_channel channel, | 486 | void dispc_mgr_setup(enum omap_channel channel, |
475 | struct omap_overlay_manager_info *info); | 487 | struct omap_overlay_manager_info *info); |
476 | 488 | ||
489 | u32 dispc_wb_get_framedone_irq(void); | ||
490 | bool dispc_wb_go_busy(void); | ||
491 | void dispc_wb_go(void); | ||
492 | void dispc_wb_enable(bool enable); | ||
493 | bool dispc_wb_is_enabled(void); | ||
494 | void dispc_wb_set_channel_in(enum dss_writeback_channel channel); | ||
495 | int dispc_wb_setup(const struct omap_dss_writeback_info *wi, | ||
496 | bool mem_to_mem, const struct omap_video_timings *timings); | ||
497 | |||
477 | /* VENC */ | 498 | /* VENC */ |
478 | #ifdef CONFIG_OMAP2_DSS_VENC | 499 | #ifdef CONFIG_OMAP2_DSS_VENC |
479 | int venc_init_platform_driver(void) __init; | 500 | int venc_init_platform_driver(void) __init; |
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index bfe7fc7b8593..acbc1e1efba3 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c | |||
@@ -46,6 +46,7 @@ struct omap_dss_features { | |||
46 | 46 | ||
47 | const int num_mgrs; | 47 | const int num_mgrs; |
48 | const int num_ovls; | 48 | const int num_ovls; |
49 | const int num_wbs; | ||
49 | const enum omap_display_type *supported_displays; | 50 | const enum omap_display_type *supported_displays; |
50 | const enum omap_dss_output_id *supported_outputs; | 51 | const enum omap_dss_output_id *supported_outputs; |
51 | const enum omap_color_mode *supported_color_modes; | 52 | const enum omap_color_mode *supported_color_modes; |
@@ -310,58 +311,80 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = { | |||
310 | OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | | 311 | OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | |
311 | OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | | 312 | OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | |
312 | OMAP_DSS_COLOR_RGBX32, | 313 | OMAP_DSS_COLOR_RGBX32, |
314 | |||
315 | /* OMAP_DSS_WB */ | ||
316 | OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U | | ||
317 | OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 | | ||
318 | OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 | | ||
319 | OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U | | ||
320 | OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY | | ||
321 | OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | | ||
322 | OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | | ||
323 | OMAP_DSS_COLOR_RGBX32, | ||
313 | }; | 324 | }; |
314 | 325 | ||
315 | static const enum omap_overlay_caps omap2_dss_overlay_caps[] = { | 326 | static const enum omap_overlay_caps omap2_dss_overlay_caps[] = { |
316 | /* OMAP_DSS_GFX */ | 327 | /* OMAP_DSS_GFX */ |
317 | 0, | 328 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, |
318 | 329 | ||
319 | /* OMAP_DSS_VIDEO1 */ | 330 | /* OMAP_DSS_VIDEO1 */ |
320 | OMAP_DSS_OVL_CAP_SCALE, | 331 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | |
332 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
321 | 333 | ||
322 | /* OMAP_DSS_VIDEO2 */ | 334 | /* OMAP_DSS_VIDEO2 */ |
323 | OMAP_DSS_OVL_CAP_SCALE, | 335 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | |
336 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
324 | }; | 337 | }; |
325 | 338 | ||
326 | static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = { | 339 | static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = { |
327 | /* OMAP_DSS_GFX */ | 340 | /* OMAP_DSS_GFX */ |
328 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA, | 341 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS | |
342 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
329 | 343 | ||
330 | /* OMAP_DSS_VIDEO1 */ | 344 | /* OMAP_DSS_VIDEO1 */ |
331 | OMAP_DSS_OVL_CAP_SCALE, | 345 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | |
346 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
332 | 347 | ||
333 | /* OMAP_DSS_VIDEO2 */ | 348 | /* OMAP_DSS_VIDEO2 */ |
334 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA, | 349 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
350 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
335 | }; | 351 | }; |
336 | 352 | ||
337 | static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = { | 353 | static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = { |
338 | /* OMAP_DSS_GFX */ | 354 | /* OMAP_DSS_GFX */ |
339 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA, | 355 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | |
356 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
340 | 357 | ||
341 | /* OMAP_DSS_VIDEO1 */ | 358 | /* OMAP_DSS_VIDEO1 */ |
342 | OMAP_DSS_OVL_CAP_SCALE, | 359 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | |
360 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
343 | 361 | ||
344 | /* OMAP_DSS_VIDEO2 */ | 362 | /* OMAP_DSS_VIDEO2 */ |
345 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | | 363 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
346 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA, | 364 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS | |
365 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
347 | }; | 366 | }; |
348 | 367 | ||
349 | static const enum omap_overlay_caps omap4_dss_overlay_caps[] = { | 368 | static const enum omap_overlay_caps omap4_dss_overlay_caps[] = { |
350 | /* OMAP_DSS_GFX */ | 369 | /* OMAP_DSS_GFX */ |
351 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | | 370 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | |
352 | OMAP_DSS_OVL_CAP_ZORDER, | 371 | OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS | |
372 | OMAP_DSS_OVL_CAP_REPLICATION, | ||
353 | 373 | ||
354 | /* OMAP_DSS_VIDEO1 */ | 374 | /* OMAP_DSS_VIDEO1 */ |
355 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | | 375 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
356 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER, | 376 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | |
377 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
357 | 378 | ||
358 | /* OMAP_DSS_VIDEO2 */ | 379 | /* OMAP_DSS_VIDEO2 */ |
359 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | | 380 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
360 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER, | 381 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | |
382 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
361 | 383 | ||
362 | /* OMAP_DSS_VIDEO3 */ | 384 | /* OMAP_DSS_VIDEO3 */ |
363 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | | 385 | OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | |
364 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER, | 386 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | |
387 | OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, | ||
365 | }; | 388 | }; |
366 | 389 | ||
367 | static const char * const omap2_dss_clk_source_names[] = { | 390 | static const char * const omap2_dss_clk_source_names[] = { |
@@ -698,6 +721,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { | |||
698 | 721 | ||
699 | .num_mgrs = 3, | 722 | .num_mgrs = 3, |
700 | .num_ovls = 4, | 723 | .num_ovls = 4, |
724 | .num_wbs = 1, | ||
701 | .supported_displays = omap4_dss_supported_displays, | 725 | .supported_displays = omap4_dss_supported_displays, |
702 | .supported_outputs = omap4_dss_supported_outputs, | 726 | .supported_outputs = omap4_dss_supported_outputs, |
703 | .supported_color_modes = omap4_dss_supported_color_modes, | 727 | .supported_color_modes = omap4_dss_supported_color_modes, |
@@ -719,6 +743,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = { | |||
719 | 743 | ||
720 | .num_mgrs = 3, | 744 | .num_mgrs = 3, |
721 | .num_ovls = 4, | 745 | .num_ovls = 4, |
746 | .num_wbs = 1, | ||
722 | .supported_displays = omap4_dss_supported_displays, | 747 | .supported_displays = omap4_dss_supported_displays, |
723 | .supported_outputs = omap4_dss_supported_outputs, | 748 | .supported_outputs = omap4_dss_supported_outputs, |
724 | .supported_color_modes = omap4_dss_supported_color_modes, | 749 | .supported_color_modes = omap4_dss_supported_color_modes, |
@@ -740,6 +765,7 @@ static const struct omap_dss_features omap4_dss_features = { | |||
740 | 765 | ||
741 | .num_mgrs = 3, | 766 | .num_mgrs = 3, |
742 | .num_ovls = 4, | 767 | .num_ovls = 4, |
768 | .num_wbs = 1, | ||
743 | .supported_displays = omap4_dss_supported_displays, | 769 | .supported_displays = omap4_dss_supported_displays, |
744 | .supported_outputs = omap4_dss_supported_outputs, | 770 | .supported_outputs = omap4_dss_supported_outputs, |
745 | .supported_color_modes = omap4_dss_supported_color_modes, | 771 | .supported_color_modes = omap4_dss_supported_color_modes, |
@@ -817,6 +843,11 @@ int dss_feat_get_num_ovls(void) | |||
817 | return omap_current_dss_features->num_ovls; | 843 | return omap_current_dss_features->num_ovls; |
818 | } | 844 | } |
819 | 845 | ||
846 | int dss_feat_get_num_wbs(void) | ||
847 | { | ||
848 | return omap_current_dss_features->num_wbs; | ||
849 | } | ||
850 | |||
820 | unsigned long dss_feat_get_param_min(enum dss_range_param param) | 851 | unsigned long dss_feat_get_param_min(enum dss_range_param param) |
821 | { | 852 | { |
822 | return omap_current_dss_features->dss_params[param].min; | 853 | return omap_current_dss_features->dss_params[param].min; |
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 89df2aa860d4..9218113b5e88 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h | |||
@@ -105,6 +105,7 @@ enum dss_range_param { | |||
105 | /* DSS Feature Functions */ | 105 | /* DSS Feature Functions */ |
106 | int dss_feat_get_num_mgrs(void); | 106 | int dss_feat_get_num_mgrs(void); |
107 | int dss_feat_get_num_ovls(void); | 107 | int dss_feat_get_num_ovls(void); |
108 | int dss_feat_get_num_wbs(void); | ||
108 | unsigned long dss_feat_get_param_min(enum dss_range_param param); | 109 | unsigned long dss_feat_get_param_min(enum dss_range_param param); |
109 | unsigned long dss_feat_get_param_max(enum dss_range_param param); | 110 | unsigned long dss_feat_get_param_max(enum dss_range_param param); |
110 | enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); | 111 | enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); |
diff --git a/include/video/omapdss.h b/include/video/omapdss.h index e65e2e9e16eb..3729173b7fbc 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h | |||
@@ -187,6 +187,8 @@ enum omap_overlay_caps { | |||
187 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1, | 187 | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1, |
188 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2, | 188 | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2, |
189 | OMAP_DSS_OVL_CAP_ZORDER = 1 << 3, | 189 | OMAP_DSS_OVL_CAP_ZORDER = 1 << 3, |
190 | OMAP_DSS_OVL_CAP_POS = 1 << 4, | ||
191 | OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5, | ||
190 | }; | 192 | }; |
191 | 193 | ||
192 | enum omap_overlay_manager_caps { | 194 | enum omap_overlay_manager_caps { |
@@ -508,6 +510,19 @@ struct omap_dsi_pin_config { | |||
508 | int pins[OMAP_DSS_MAX_DSI_PINS]; | 510 | int pins[OMAP_DSS_MAX_DSI_PINS]; |
509 | }; | 511 | }; |
510 | 512 | ||
513 | struct omap_dss_writeback_info { | ||
514 | u32 paddr; | ||
515 | u32 p_uv_addr; | ||
516 | u16 buf_width; | ||
517 | u16 width; | ||
518 | u16 height; | ||
519 | enum omap_color_mode color_mode; | ||
520 | u8 rotation; | ||
521 | enum omap_dss_rotation_type rotation_type; | ||
522 | bool mirror; | ||
523 | u8 pre_mult_alpha; | ||
524 | }; | ||
525 | |||
511 | struct omap_dss_output { | 526 | struct omap_dss_output { |
512 | struct list_head list; | 527 | struct list_head list; |
513 | 528 | ||