aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Osipenko <digetx@gmail.com>2018-05-04 10:39:58 -0400
committerThierry Reding <treding@nvidia.com>2018-05-17 08:08:44 -0400
commitacc6a3a9afdd4e0537342012656cdb5c4a3127c5 (patch)
tree51c4a4280fdecd57d3ed457bd0eb4073bfadad56
parent0c407de5ed1a329468122cbf4f3e727e0c1e3f36 (diff)
drm/tegra: dc: Enable plane scaling filters
Currently resized plane produces a "pixelated" image which doesn't look nice, especially in a case of a video overlay. Enable scaling filters that significantly improve image quality of a scaled overlay. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/dc.c81
-rw-r--r--drivers/gpu/drm/tegra/dc.h7
2 files changed, 88 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 3e7ec3937346..a4dd866fc8be 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -224,6 +224,39 @@ static void tegra_plane_setup_blending(struct tegra_plane *plane,
224 tegra_plane_writel(plane, value, DC_WIN_BLEND_LAYER_CONTROL); 224 tegra_plane_writel(plane, value, DC_WIN_BLEND_LAYER_CONTROL);
225} 225}
226 226
227static bool
228tegra_plane_use_horizontal_filtering(struct tegra_plane *plane,
229 const struct tegra_dc_window *window)
230{
231 struct tegra_dc *dc = plane->dc;
232
233 if (window->src.w == window->dst.w)
234 return false;
235
236 if (plane->index == 0 && dc->soc->has_win_a_without_filters)
237 return false;
238
239 return true;
240}
241
242static bool
243tegra_plane_use_vertical_filtering(struct tegra_plane *plane,
244 const struct tegra_dc_window *window)
245{
246 struct tegra_dc *dc = plane->dc;
247
248 if (window->src.h == window->dst.h)
249 return false;
250
251 if (plane->index == 0 && dc->soc->has_win_a_without_filters)
252 return false;
253
254 if (plane->index == 2 && dc->soc->has_win_c_without_vert_filter)
255 return false;
256
257 return true;
258}
259
227static void tegra_dc_setup_window(struct tegra_plane *plane, 260static void tegra_dc_setup_window(struct tegra_plane *plane,
228 const struct tegra_dc_window *window) 261 const struct tegra_dc_window *window)
229{ 262{
@@ -361,6 +394,44 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
361 if (window->bottom_up) 394 if (window->bottom_up)
362 value |= V_DIRECTION; 395 value |= V_DIRECTION;
363 396
397 if (tegra_plane_use_horizontal_filtering(plane, window)) {
398 /*
399 * Enable horizontal 6-tap filter and set filtering
400 * coefficients to the default values defined in TRM.
401 */
402 tegra_plane_writel(plane, 0x00008000, DC_WIN_H_FILTER_P(0));
403 tegra_plane_writel(plane, 0x3e087ce1, DC_WIN_H_FILTER_P(1));
404 tegra_plane_writel(plane, 0x3b117ac1, DC_WIN_H_FILTER_P(2));
405 tegra_plane_writel(plane, 0x591b73aa, DC_WIN_H_FILTER_P(3));
406 tegra_plane_writel(plane, 0x57256d9a, DC_WIN_H_FILTER_P(4));
407 tegra_plane_writel(plane, 0x552f668b, DC_WIN_H_FILTER_P(5));
408 tegra_plane_writel(plane, 0x73385e8b, DC_WIN_H_FILTER_P(6));
409 tegra_plane_writel(plane, 0x72435583, DC_WIN_H_FILTER_P(7));
410 tegra_plane_writel(plane, 0x714c4c8b, DC_WIN_H_FILTER_P(8));
411 tegra_plane_writel(plane, 0x70554393, DC_WIN_H_FILTER_P(9));
412 tegra_plane_writel(plane, 0x715e389b, DC_WIN_H_FILTER_P(10));
413 tegra_plane_writel(plane, 0x71662faa, DC_WIN_H_FILTER_P(11));
414 tegra_plane_writel(plane, 0x536d25ba, DC_WIN_H_FILTER_P(12));
415 tegra_plane_writel(plane, 0x55731bca, DC_WIN_H_FILTER_P(13));
416 tegra_plane_writel(plane, 0x387a11d9, DC_WIN_H_FILTER_P(14));
417 tegra_plane_writel(plane, 0x3c7c08f1, DC_WIN_H_FILTER_P(15));
418
419 value |= H_FILTER;
420 }
421
422 if (tegra_plane_use_vertical_filtering(plane, window)) {
423 unsigned int i, k;
424
425 /*
426 * Enable vertical 2-tap filter and set filtering
427 * coefficients to the default values defined in TRM.
428 */
429 for (i = 0, k = 128; i < 16; i++, k -= 8)
430 tegra_plane_writel(plane, k, DC_WIN_V_FILTER_P(i));
431
432 value |= V_FILTER;
433 }
434
364 tegra_plane_writel(plane, value, DC_WIN_WIN_OPTIONS); 435 tegra_plane_writel(plane, value, DC_WIN_WIN_OPTIONS);
365 436
366 if (dc->soc->supports_blending) 437 if (dc->soc->supports_blending)
@@ -1951,6 +2022,8 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
1951 .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats), 2022 .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats),
1952 .overlay_formats = tegra20_overlay_formats, 2023 .overlay_formats = tegra20_overlay_formats,
1953 .modifiers = tegra20_modifiers, 2024 .modifiers = tegra20_modifiers,
2025 .has_win_a_without_filters = true,
2026 .has_win_c_without_vert_filter = true,
1954}; 2027};
1955 2028
1956static const struct tegra_dc_soc_info tegra30_dc_soc_info = { 2029static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
@@ -1968,6 +2041,8 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
1968 .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats), 2041 .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats),
1969 .overlay_formats = tegra20_overlay_formats, 2042 .overlay_formats = tegra20_overlay_formats,
1970 .modifiers = tegra20_modifiers, 2043 .modifiers = tegra20_modifiers,
2044 .has_win_a_without_filters = false,
2045 .has_win_c_without_vert_filter = false,
1971}; 2046};
1972 2047
1973static const struct tegra_dc_soc_info tegra114_dc_soc_info = { 2048static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
@@ -1985,6 +2060,8 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
1985 .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats), 2060 .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats),
1986 .overlay_formats = tegra114_overlay_formats, 2061 .overlay_formats = tegra114_overlay_formats,
1987 .modifiers = tegra20_modifiers, 2062 .modifiers = tegra20_modifiers,
2063 .has_win_a_without_filters = false,
2064 .has_win_c_without_vert_filter = false,
1988}; 2065};
1989 2066
1990static const struct tegra_dc_soc_info tegra124_dc_soc_info = { 2067static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
@@ -2002,6 +2079,8 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
2002 .num_overlay_formats = ARRAY_SIZE(tegra124_overlay_formats), 2079 .num_overlay_formats = ARRAY_SIZE(tegra124_overlay_formats),
2003 .overlay_formats = tegra124_overlay_formats, 2080 .overlay_formats = tegra124_overlay_formats,
2004 .modifiers = tegra124_modifiers, 2081 .modifiers = tegra124_modifiers,
2082 .has_win_a_without_filters = false,
2083 .has_win_c_without_vert_filter = false,
2005}; 2084};
2006 2085
2007static const struct tegra_dc_soc_info tegra210_dc_soc_info = { 2086static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
@@ -2019,6 +2098,8 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
2019 .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats), 2098 .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats),
2020 .overlay_formats = tegra114_overlay_formats, 2099 .overlay_formats = tegra114_overlay_formats,
2021 .modifiers = tegra124_modifiers, 2100 .modifiers = tegra124_modifiers,
2101 .has_win_a_without_filters = false,
2102 .has_win_c_without_vert_filter = false,
2022}; 2103};
2023 2104
2024static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = { 2105static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = {
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 7be786febb17..556321fde9d2 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -67,6 +67,8 @@ struct tegra_dc_soc_info {
67 const u32 *overlay_formats; 67 const u32 *overlay_formats;
68 unsigned int num_overlay_formats; 68 unsigned int num_overlay_formats;
69 const u64 *modifiers; 69 const u64 *modifiers;
70 bool has_win_a_without_filters;
71 bool has_win_c_without_vert_filter;
70}; 72};
71 73
72struct tegra_dc { 74struct tegra_dc {
@@ -553,6 +555,9 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
553#define THREAD_NUM(x) (((x) & 0x1f) << 1) 555#define THREAD_NUM(x) (((x) & 0x1f) << 1)
554#define THREAD_GROUP_ENABLE (1 << 0) 556#define THREAD_GROUP_ENABLE (1 << 0)
555 557
558#define DC_WIN_H_FILTER_P(p) (0x601 + (p))
559#define DC_WIN_V_FILTER_P(p) (0x619 + (p))
560
556#define DC_WIN_CSC_YOF 0x611 561#define DC_WIN_CSC_YOF 0x611
557#define DC_WIN_CSC_KYRGB 0x612 562#define DC_WIN_CSC_KYRGB 0x612
558#define DC_WIN_CSC_KUR 0x613 563#define DC_WIN_CSC_KUR 0x613
@@ -566,6 +571,8 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
566#define H_DIRECTION (1 << 0) 571#define H_DIRECTION (1 << 0)
567#define V_DIRECTION (1 << 2) 572#define V_DIRECTION (1 << 2)
568#define COLOR_EXPAND (1 << 6) 573#define COLOR_EXPAND (1 << 6)
574#define H_FILTER (1 << 8)
575#define V_FILTER (1 << 10)
569#define CSC_ENABLE (1 << 18) 576#define CSC_ENABLE (1 << 18)
570#define WIN_ENABLE (1 << 30) 577#define WIN_ENABLE (1 << 30)
571 578