diff options
author | Robert Morell <rmorell@nvidia.com> | 2011-03-17 21:02:00 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:01:34 -0400 |
commit | 3ec39250c2a7ee16ff4083ce60cd4cb08894bfe7 (patch) | |
tree | 364696a4d77129ec6ea7042d02dbbff888edb410 /drivers/video/tegra/dc/dc.c | |
parent | 3e18f8c77dad3d763206a265ccc55484a8f4a7af (diff) |
video: tegra: Only attempt filtering when supported
The Tegra display windows are not entirely symmetric; only some of them
support filtering in either direction. This change makes the kernel
only enable filtering when it's supported by the hardware.
bug 818525
Original-Change-Id: I0f85f52fcc5c6785c75003c54c8aee12fcd0a220
Signed-off-by: Robert Morell <rmorell@nvidia.com>
Reviewed-on: http://git-master/r/40524
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Rebase-Id: R7306a484983f91d501bcb122d5fc3cf25c5006d7
Diffstat (limited to 'drivers/video/tegra/dc/dc.c')
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index dacb37511..6fb4f7e1c 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c | |||
@@ -69,6 +69,28 @@ struct tegra_dc *tegra_dcs[TEGRA_MAX_DC]; | |||
69 | DEFINE_MUTEX(tegra_dc_lock); | 69 | DEFINE_MUTEX(tegra_dc_lock); |
70 | DEFINE_MUTEX(shared_lock); | 70 | DEFINE_MUTEX(shared_lock); |
71 | 71 | ||
72 | static const struct { | ||
73 | bool h; | ||
74 | bool v; | ||
75 | } can_filter[] = { | ||
76 | /* Window A has no filtering */ | ||
77 | { false, false }, | ||
78 | /* Window B has both H and V filtering */ | ||
79 | { true, true }, | ||
80 | /* Window C has only H filtering */ | ||
81 | { false, true }, | ||
82 | }; | ||
83 | static inline bool win_use_v_filter(const struct tegra_dc_win *win) | ||
84 | { | ||
85 | return can_filter[win->idx].v && | ||
86 | win->h != win->out_h; | ||
87 | } | ||
88 | static inline bool win_use_h_filter(const struct tegra_dc_win *win) | ||
89 | { | ||
90 | return can_filter[win->idx].h && | ||
91 | win->w != win->out_w; | ||
92 | } | ||
93 | |||
72 | static inline int tegra_dc_fmt_bpp(int fmt) | 94 | static inline int tegra_dc_fmt_bpp(int fmt) |
73 | { | 95 | { |
74 | switch (fmt) { | 96 | switch (fmt) { |
@@ -655,7 +677,7 @@ static void tegra_dc_set_latency_allowance(struct tegra_dc *dc, | |||
655 | 677 | ||
656 | /* tegra_dc_get_bandwidth() treats V filter windows as double | 678 | /* tegra_dc_get_bandwidth() treats V filter windows as double |
657 | * bandwidth, but LA has a seperate client for V filter */ | 679 | * bandwidth, but LA has a seperate client for V filter */ |
658 | if (w->idx == 1 && WIN_USE_V_FILTER(w)) | 680 | if (w->idx == 1 && win_use_v_filter(w)) |
659 | bw /= 2; | 681 | bw /= 2; |
660 | 682 | ||
661 | tegra_set_latency_allowance(la_id_tab[dc->ndev->id][w->idx], bw); | 683 | tegra_set_latency_allowance(la_id_tab[dc->ndev->id][w->idx], bw); |
@@ -769,7 +791,7 @@ static unsigned long tegra_dc_calc_win_bandwidth(struct tegra_dc *dc, | |||
769 | * to prevent overflow of long. */ | 791 | * to prevent overflow of long. */ |
770 | ret = (unsigned long)(dc->pixel_clk >> 16) * | 792 | ret = (unsigned long)(dc->pixel_clk >> 16) * |
771 | bpp / 8 * | 793 | bpp / 8 * |
772 | (WIN_USE_V_FILTER(w) ? 2 : 1) * w->w / w->out_w * | 794 | (win_use_v_filter(w) ? 2 : 1) * w->w / w->out_w * |
773 | (WIN_IS_TILED(w) ? tiled_windows_bw_multiplier : 1); | 795 | (WIN_IS_TILED(w) ? tiled_windows_bw_multiplier : 1); |
774 | 796 | ||
775 | /* | 797 | /* |
@@ -874,6 +896,8 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n) | |||
874 | bool invert_h = (win->flags & TEGRA_WIN_FLAG_INVERT_H) != 0; | 896 | bool invert_h = (win->flags & TEGRA_WIN_FLAG_INVERT_H) != 0; |
875 | bool invert_v = (win->flags & TEGRA_WIN_FLAG_INVERT_V) != 0; | 897 | bool invert_v = (win->flags & TEGRA_WIN_FLAG_INVERT_V) != 0; |
876 | bool yuvp = tegra_dc_is_yuv_planar(win->fmt); | 898 | bool yuvp = tegra_dc_is_yuv_planar(win->fmt); |
899 | const bool filter_h = win_use_h_filter(win); | ||
900 | const bool filter_v = win_use_v_filter(win); | ||
877 | 901 | ||
878 | if (win->z != dc->blend.z[win->idx]) { | 902 | if (win->z != dc->blend.z[win->idx]) { |
879 | dc->blend.z[win->idx] = win->z; | 903 | dc->blend.z[win->idx] = win->z; |
@@ -973,16 +997,9 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n) | |||
973 | else if (tegra_dc_fmt_bpp(win->fmt) < 24) | 997 | else if (tegra_dc_fmt_bpp(win->fmt) < 24) |
974 | val |= COLOR_EXPAND; | 998 | val |= COLOR_EXPAND; |
975 | 999 | ||
976 | /* only B and C have H filer, force it on if scaling */ | 1000 | if (filter_h) |
977 | if (win->idx != 0 && win->w != win->out_w) | ||
978 | win->flags |= TEGRA_WIN_FLAG_H_FILTER; | ||
979 | /* only B has V filter, set it if scaling */ | ||
980 | if (win->idx == 1 && win->h != win->out_h) | ||
981 | win->flags |= TEGRA_WIN_FLAG_V_FILTER; | ||
982 | |||
983 | if (WIN_USE_H_FILTER(win)) | ||
984 | val |= H_FILTER_ENABLE; | 1001 | val |= H_FILTER_ENABLE; |
985 | if (WIN_USE_V_FILTER(win)) | 1002 | if (filter_v) |
986 | val |= V_FILTER_ENABLE; | 1003 | val |= V_FILTER_ENABLE; |
987 | 1004 | ||
988 | if (invert_h) | 1005 | if (invert_h) |