diff options
| author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-26 09:48:55 -0400 |
|---|---|---|
| committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-26 09:48:55 -0400 |
| commit | 69036f0ccd9d48b4e999be4e98fa459430ec93b4 (patch) | |
| tree | e09e075957c7e9b8299e57883d50eb3cff6ee3b2 | |
| parent | 866f0956cba7d28432f20f8a696e5c1a2b40b915 (diff) | |
| parent | 6e5264b0380593efda8157406ec40f00daac9f2d (diff) | |
Merge branch 'archit/wb-dispc-for-3.7'
Merge omapdss writeback work. These patches implement the low level writeback
features in the DISPC, but do not yet add a way to actually use the writeback
from the userspace.
* archit/wb-dispc-for-3.7:
OMAPDSS: DISPC: Configure color conversion coefficients for writeback
OMAPDSS: DISPC: Add manager like functions for writeback
OMAPDSS: DISPC: Configure writeback FIFOs
OMAPDSS: DISPC: Configure writeback specific parameters in dispc_wb_setup()
OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup
OMAPDSS: DISPC: Add function to set channel in for writeback
OMAPDSS: DISPC: Don't set chroma resampling bit for writeback
OMAPDSS: DISPC: Downscale chroma if plane is writeback
OMAPDSS: DISPC: Configure input and output sizes for writeback
OMAPDSS: DISPC: Add writeback register offsets and dss features structs
OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma
OMAPDSS: DIPSC: Relax scaling limitations when in memory to memory mode
OMAPDSS: DISPC: Don't pass channel out when configuring overlays
OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_ovl_setup_common
OMAPDSS: OVERLAY: Add position and replication as overlay caps
OMAPDSS: DISPC: Pass overlay caps as a parameter to dispc plane functions
OMAPDSS: DISPC: Simplify function names for setting pipeline input and output sizes
OMAPDSS: DISPC: Constify omap_overlay_info in dispc_ovl_setup()
| -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 | ||
