From f07f04a51d92165e0ad711f1be1cc5bbbfcb4766 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Tue, 8 Feb 2022 00:29:23 +0300 Subject: [PATCH 1/8] drm/tegra: Use dev_err_probe() Replace dev_printk() with a generic dev_err_probe() helper which silences noisy error messages about deferred probe and makes easy to debug failing deferred probe by printing notification about the failure to KMSG in the end of kernel booting process and by adding failing device and the reason of deferred probe to devices_deferred of debugfs. This was proven to be useful in the case of eDP driver regression by immediately showing why display driver was failing when user asked for help, otherwise it would've been much more difficult to debug such problems on a third party device that doesn't have developer setup. Signed-off-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 13 +++---------- drivers/gpu/drm/tegra/hdmi.c | 34 +++++++++------------------------- 2 files changed, 12 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index eb70eee8992aa..9435c867c8653 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -3211,16 +3211,9 @@ static int tegra_dc_probe(struct platform_device *pdev) return -ENXIO; err = tegra_dc_rgb_probe(dc); - if (err < 0 && err != -ENODEV) { - const char *level = KERN_ERR; - - if (err == -EPROBE_DEFER) - level = KERN_DEBUG; - - dev_printk(level, dc->dev, "failed to probe RGB output: %d\n", - err); - return err; - } + if (err < 0 && err != -ENODEV) + return dev_err_probe(&pdev->dev, err, + "failed to probe RGB output\n"); platform_set_drvdata(pdev, dc); pm_runtime_enable(&pdev->dev); diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 8845af5d325f1..bf240767dad9f 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -1775,7 +1775,6 @@ static irqreturn_t tegra_hdmi_irq(int irq, void *data) static int tegra_hdmi_probe(struct platform_device *pdev) { - const char *level = KERN_ERR; struct tegra_hdmi *hdmi; struct resource *regs; int err; @@ -1817,36 +1816,21 @@ static int tegra_hdmi_probe(struct platform_device *pdev) hdmi->hdmi = devm_regulator_get(&pdev->dev, "hdmi"); err = PTR_ERR_OR_ZERO(hdmi->hdmi); - if (err) { - if (err == -EPROBE_DEFER) - level = KERN_DEBUG; - - dev_printk(level, &pdev->dev, - "failed to get HDMI regulator: %d\n", err); - return err; - } + if (err) + return dev_err_probe(&pdev->dev, err, + "failed to get HDMI regulator\n"); hdmi->pll = devm_regulator_get(&pdev->dev, "pll"); err = PTR_ERR_OR_ZERO(hdmi->pll); - if (err) { - if (err == -EPROBE_DEFER) - level = KERN_DEBUG; - - dev_printk(level, &pdev->dev, - "failed to get PLL regulator: %d\n", err); - return err; - } + if (err) + return dev_err_probe(&pdev->dev, err, + "failed to get PLL regulator\n"); hdmi->vdd = devm_regulator_get(&pdev->dev, "vdd"); err = PTR_ERR_OR_ZERO(hdmi->vdd); - if (err) { - if (err == -EPROBE_DEFER) - level = KERN_DEBUG; - - dev_printk(level, &pdev->dev, - "failed to get VDD regulator: %d\n", err); - return err; - } + if (err) + return dev_err_probe(&pdev->dev, err, + "failed to get VDD regulator\n"); hdmi->output.dev = &pdev->dev; From 221e3638feb8bc42143833c9a704fa89b6c366bb Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 10 Jan 2022 06:53:16 +0000 Subject: [PATCH 2/8] drm/tegra: Fix reference leak in tegra_dsi_ganged_probe The reference taken by 'of_find_device_by_node()' must be released when not needed anymore. Add put_device() call to fix this. Fixes: e94236cde4d5 ("drm/tegra: dsi: Add ganged mode support") Signed-off-by: Miaoqian Lin Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index f46d377f0c304..de1333dc0d867 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -1538,8 +1538,10 @@ static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi) dsi->slave = platform_get_drvdata(gangster); of_node_put(np); - if (!dsi->slave) + if (!dsi->slave) { + put_device(&gangster->dev); return -EPROBE_DEFER; + } dsi->slave->master = dsi; } From cea418863e968e086cf68b052da86b0707690ebc Mon Sep 17 00:00:00 2001 From: chiminghao Date: Fri, 12 Nov 2021 03:21:02 +0000 Subject: [PATCH 3/8] drm/tegra: dpaux: Remove unneeded variable Fix the following coccicheck REVIEW: ./drivers/gpu/drm/tegra/dpaux.c:282:13-16 REVIEW Unneeded variable Reported-by: Zeal Robot Signed-off-by: chiminghao Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dpaux.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index d7a731d287d23..ac3a18635ab1f 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -280,7 +280,6 @@ static void tegra_dpaux_hotplug(struct work_struct *work) static irqreturn_t tegra_dpaux_irq(int irq, void *data) { struct tegra_dpaux *dpaux = data; - irqreturn_t ret = IRQ_HANDLED; u32 value; /* clear interrupts */ @@ -297,7 +296,7 @@ static irqreturn_t tegra_dpaux_irq(int irq, void *data) if (value & DPAUX_INTR_AUX_DONE) complete(&dpaux->complete); - return ret; + return IRQ_HANDLED; } enum tegra_dpaux_functions { From e5d5db1a79a5929b9ced99472f9a748a243d6a69 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 7 Nov 2021 22:16:25 +0100 Subject: [PATCH 4/8] gpu: host1x: Fix an error handling path in 'host1x_probe()' Add the missing 'host1x_bo_cache_destroy()' call in the error handling path of the probe, as already done in the remove function. In order to simplify the error handling, move the 'host1x_bo_cache_init()' call after all the devm_ function. Fixes: 1f39b1dfa53c ("drm/tegra: Implement buffer object cache") Signed-off-by: Christophe JAILLET Signed-off-by: Thierry Reding --- drivers/gpu/host1x/dev.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 6994f8c0e02ea..9605495f001ad 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -447,7 +447,6 @@ static int host1x_probe(struct platform_device *pdev) if (syncpt_irq < 0) return syncpt_irq; - host1x_bo_cache_init(&host->cache); mutex_init(&host->devices_lock); INIT_LIST_HEAD(&host->devices); INIT_LIST_HEAD(&host->list); @@ -489,10 +488,12 @@ static int host1x_probe(struct platform_device *pdev) if (err) return err; + host1x_bo_cache_init(&host->cache); + err = host1x_iommu_init(host); if (err < 0) { dev_err(&pdev->dev, "failed to setup IOMMU: %d\n", err); - return err; + goto destroy_cache; } err = host1x_channel_list_init(&host->channel_list, @@ -553,6 +554,8 @@ static int host1x_probe(struct platform_device *pdev) host1x_channel_list_free(&host->channel_list); iommu_exit: host1x_iommu_exit(host); +destroy_cache: + host1x_bo_cache_destroy(&host->cache); return err; } From 025c6643a81564f066d8381b9e2f4603e0f8438f Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 7 Nov 2021 22:16:36 +0100 Subject: [PATCH 5/8] gpu: host1x: Fix a memory leak in 'host1x_remove()' Add a missing 'host1x_channel_list_free()' call in the remove function, as already done in the error handling path of the probe function. Fixes: 8474b02531c4 ("gpu: host1x: Refactor channel allocation code") Signed-off-by: Christophe JAILLET Signed-off-by: Thierry Reding --- drivers/gpu/host1x/dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 9605495f001ad..80c685ab3e30d 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -571,6 +571,7 @@ static int host1x_remove(struct platform_device *pdev) host1x_intr_deinit(host); host1x_syncpt_deinit(host); + host1x_channel_list_free(&host->channel_list); host1x_iommu_exit(host); host1x_bo_cache_destroy(&host->cache); From 28aa30b08de6f4b346f25f7c8bb5ba3739c1879c Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 12 Jan 2022 09:40:34 +0100 Subject: [PATCH 6/8] drm/tegra: Fix planar formats on Tegra186 and later Use the correct pitch when programming the DC_WIN_PLANAR_STORAGE_UV register's PITCH_U field to ensure the correct value is used in all cases. This isn't currently causing any problems because the pitch for both U and V planes is always the same. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index b910155f80c47..fc9813e6b2c92 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -673,7 +673,7 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V); tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V); - value = PITCH_U(fb->pitches[2]) | PITCH_V(fb->pitches[2]); + value = PITCH_U(fb->pitches[1]) | PITCH_V(fb->pitches[2]); tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE_UV); } else { tegra_plane_writel(p, 0, DC_WINBUF_START_ADDR_U); From a649b133c3154f3d1d297cf85711957e61c0f070 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 12 Jan 2022 09:36:29 +0100 Subject: [PATCH 7/8] drm/tegra: Support semi-planar formats on Tegra114+ The NV12, NV21, NV16, NV61, NV24 and NV42 formats are supported by Tegra114 and later display hardware. Add the necessary programming to allow them to be used. Note that this does not work for Tegra186 and later yet because those generations have a different display architecture that doesn't support the same formats. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 30 ++++++++++++++++---- drivers/gpu/drm/tegra/dc.h | 6 ++++ drivers/gpu/drm/tegra/hub.c | 24 ++++++++++------ drivers/gpu/drm/tegra/plane.c | 52 ++++++++++++++++++++++++++++++----- drivers/gpu/drm/tegra/plane.h | 2 +- 5 files changed, 91 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 9435c867c8653..9442d7ee84a06 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -345,18 +345,19 @@ static void tegra_dc_setup_window(struct tegra_plane *plane, { unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp; struct tegra_dc *dc = plane->dc; - bool yuv, planar; + unsigned int planes; u32 value; + bool yuv; /* * For YUV planar modes, the number of bytes per pixel takes into * account only the luma component and therefore is 1. */ - yuv = tegra_plane_format_is_yuv(window->format, &planar, NULL); + yuv = tegra_plane_format_is_yuv(window->format, &planes, NULL); if (!yuv) bpp = window->bits_per_pixel / 8; else - bpp = planar ? 1 : 2; + bpp = (planes > 1) ? 1 : 2; tegra_plane_writel(plane, window->format, DC_WIN_COLOR_DEPTH); tegra_plane_writel(plane, window->swap, DC_WIN_BYTE_SWAP); @@ -385,7 +386,7 @@ static void tegra_dc_setup_window(struct tegra_plane *plane, * For DDA computations the number of bytes per pixel for YUV planar * modes needs to take into account all Y, U and V components. */ - if (yuv && planar) + if (yuv && planes > 1) bpp = 2; h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp); @@ -405,9 +406,12 @@ static void tegra_dc_setup_window(struct tegra_plane *plane, tegra_plane_writel(plane, window->base[0], DC_WINBUF_START_ADDR); - if (yuv && planar) { + if (yuv && planes > 1) { tegra_plane_writel(plane, window->base[1], DC_WINBUF_START_ADDR_U); - tegra_plane_writel(plane, window->base[2], DC_WINBUF_START_ADDR_V); + + if (planes > 2) + tegra_plane_writel(plane, window->base[2], DC_WINBUF_START_ADDR_V); + value = window->stride[1] << 16 | window->stride[0]; tegra_plane_writel(plane, value, DC_WIN_LINE_STRIDE); } else { @@ -1193,6 +1197,13 @@ static const u32 tegra114_overlay_formats[] = { DRM_FORMAT_YUYV, DRM_FORMAT_YUV420, DRM_FORMAT_YUV422, + /* semi-planar formats */ + DRM_FORMAT_NV12, + DRM_FORMAT_NV21, + DRM_FORMAT_NV16, + DRM_FORMAT_NV61, + DRM_FORMAT_NV24, + DRM_FORMAT_NV42, }; static const u32 tegra124_overlay_formats[] = { @@ -1223,6 +1234,13 @@ static const u32 tegra124_overlay_formats[] = { DRM_FORMAT_YUYV, DRM_FORMAT_YUV420, DRM_FORMAT_YUV422, + /* semi-planar formats */ + DRM_FORMAT_NV12, + DRM_FORMAT_NV21, + DRM_FORMAT_NV16, + DRM_FORMAT_NV61, + DRM_FORMAT_NV24, + DRM_FORMAT_NV42, }; static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h index 3f91a10ea6c7d..67c4c5baa3cf2 100644 --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -637,6 +637,12 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc); #define WIN_COLOR_DEPTH_A8B8G8R8 36 #define WIN_COLOR_DEPTH_B8G8R8X8 37 #define WIN_COLOR_DEPTH_R8G8B8X8 38 +#define WIN_COLOR_DEPTH_YCrCb420SP 42 +#define WIN_COLOR_DEPTH_YCbCr420SP 43 +#define WIN_COLOR_DEPTH_YCrCb422SP 44 +#define WIN_COLOR_DEPTH_YCbCr422SP 45 +#define WIN_COLOR_DEPTH_YCrCb444SP 48 +#define WIN_COLOR_DEPTH_YCbCr444SP 49 #define WIN_COLOR_DEPTH_X8B8G8R8 65 #define WIN_COLOR_DEPTH_X8R8G8B8 66 diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index fc9813e6b2c92..b8d3174c04c91 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -540,8 +540,8 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, struct tegra_plane *p = to_tegra_plane(plane); u32 value, min_width, bypass = 0; dma_addr_t base, addr_flag = 0; - unsigned int bpc; - bool yuv, planar; + unsigned int bpc, planes; + bool yuv; int err; /* rien ne va plus */ @@ -559,7 +559,7 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, return; } - yuv = tegra_plane_format_is_yuv(tegra_plane_state->format, &planar, &bpc); + yuv = tegra_plane_format_is_yuv(tegra_plane_state->format, &planes, &bpc); tegra_dc_assign_shared_plane(dc, p); @@ -660,20 +660,26 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, value = PITCH(fb->pitches[0]); tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE); - if (yuv && planar) { + if (yuv && planes > 1) { base = tegra_plane_state->iova[1] + fb->offsets[1]; base |= addr_flag; tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_U); tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_U); - base = tegra_plane_state->iova[2] + fb->offsets[2]; - base |= addr_flag; + if (planes > 2) { + base = tegra_plane_state->iova[2] + fb->offsets[2]; + base |= addr_flag; + + tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V); + tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V); + } + + value = PITCH_U(fb->pitches[1]); - tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V); - tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V); + if (planes > 2) + value |= PITCH_V(fb->pitches[2]); - value = PITCH_U(fb->pitches[1]) | PITCH_V(fb->pitches[2]); tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE_UV); } else { tegra_plane_writel(p, 0, DC_WINBUF_START_ADDR_U); diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 321cb1f13da63..5136a37c02399 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -421,6 +421,30 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap) *format = WIN_COLOR_DEPTH_YCbCr422P; break; + case DRM_FORMAT_NV12: + *format = WIN_COLOR_DEPTH_YCbCr420SP; + break; + + case DRM_FORMAT_NV21: + *format = WIN_COLOR_DEPTH_YCrCb420SP; + break; + + case DRM_FORMAT_NV16: + *format = WIN_COLOR_DEPTH_YCbCr422SP; + break; + + case DRM_FORMAT_NV61: + *format = WIN_COLOR_DEPTH_YCrCb422SP; + break; + + case DRM_FORMAT_NV24: + *format = WIN_COLOR_DEPTH_YCbCr444SP; + break; + + case DRM_FORMAT_NV42: + *format = WIN_COLOR_DEPTH_YCrCb444SP; + break; + default: return -EINVAL; } @@ -441,13 +465,13 @@ bool tegra_plane_format_is_indexed(unsigned int format) return false; } -bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *bpc) +bool tegra_plane_format_is_yuv(unsigned int format, unsigned int *planes, unsigned int *bpc) { switch (format) { case WIN_COLOR_DEPTH_YCbCr422: case WIN_COLOR_DEPTH_YUV422: - if (planar) - *planar = false; + if (planes) + *planes = 1; if (bpc) *bpc = 8; @@ -462,8 +486,22 @@ bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int * case WIN_COLOR_DEPTH_YUV422R: case WIN_COLOR_DEPTH_YCbCr422RA: case WIN_COLOR_DEPTH_YUV422RA: - if (planar) - *planar = true; + if (planes) + *planes = 3; + + if (bpc) + *bpc = 8; + + return true; + + case WIN_COLOR_DEPTH_YCrCb420SP: + case WIN_COLOR_DEPTH_YCbCr420SP: + case WIN_COLOR_DEPTH_YCrCb422SP: + case WIN_COLOR_DEPTH_YCbCr422SP: + case WIN_COLOR_DEPTH_YCrCb444SP: + case WIN_COLOR_DEPTH_YCbCr444SP: + if (planes) + *planes = 2; if (bpc) *bpc = 8; @@ -471,8 +509,8 @@ bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int * return true; } - if (planar) - *planar = false; + if (planes) + *planes = 1; return false; } diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h index dfb20712fbd77..e33a581e6490e 100644 --- a/drivers/gpu/drm/tegra/plane.h +++ b/drivers/gpu/drm/tegra/plane.h @@ -90,7 +90,7 @@ int tegra_plane_state_add(struct tegra_plane *plane, int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap); bool tegra_plane_format_is_indexed(unsigned int format); -bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *bpc); +bool tegra_plane_format_is_yuv(unsigned int format, unsigned int *planes, unsigned int *bpc); int tegra_plane_setup_legacy_state(struct tegra_plane *tegra, struct tegra_plane_state *state); int tegra_plane_interconnect_init(struct tegra_plane *plane); From cf5086d35d8c7c2b9cb1ca34590097a5f2f8b588 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 24 Feb 2022 19:39:51 +0100 Subject: [PATCH 8/8] drm/tegra: Support YVYU, VYUY and YU24 formats Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 7 +++++-- drivers/gpu/drm/tegra/dc.h | 1 + drivers/gpu/drm/tegra/plane.c | 21 +++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 9442d7ee84a06..c6951cf5d2ca7 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1232,8 +1232,11 @@ static const u32 tegra124_overlay_formats[] = { /* planar formats */ DRM_FORMAT_UYVY, DRM_FORMAT_YUYV, - DRM_FORMAT_YUV420, - DRM_FORMAT_YUV422, + DRM_FORMAT_YVYU, + DRM_FORMAT_VYUY, + DRM_FORMAT_YUV420, /* YU12 */ + DRM_FORMAT_YUV422, /* YU16 */ + DRM_FORMAT_YUV444, /* YU24 */ /* semi-planar formats */ DRM_FORMAT_NV12, DRM_FORMAT_NV21, diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h index 67c4c5baa3cf2..f902794d42ccb 100644 --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -637,6 +637,7 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc); #define WIN_COLOR_DEPTH_A8B8G8R8 36 #define WIN_COLOR_DEPTH_B8G8R8X8 37 #define WIN_COLOR_DEPTH_R8G8B8X8 38 +#define WIN_COLOR_DEPTH_YCbCr444P 41 #define WIN_COLOR_DEPTH_YCrCb420SP 42 #define WIN_COLOR_DEPTH_YCbCr420SP 43 #define WIN_COLOR_DEPTH_YCrCb422SP 44 diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 5136a37c02399..e0e6938c62003 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -413,6 +413,22 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap) *swap = BYTE_SWAP_SWAP2; break; + case DRM_FORMAT_YVYU: + if (!swap) + return -EINVAL; + + *format = WIN_COLOR_DEPTH_YCbCr422; + *swap = BYTE_SWAP_SWAP4; + break; + + case DRM_FORMAT_VYUY: + if (!swap) + return -EINVAL; + + *format = WIN_COLOR_DEPTH_YCbCr422; + *swap = BYTE_SWAP_SWAP4HW; + break; + case DRM_FORMAT_YUV420: *format = WIN_COLOR_DEPTH_YCbCr420P; break; @@ -421,6 +437,10 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap) *format = WIN_COLOR_DEPTH_YCbCr422P; break; + case DRM_FORMAT_YUV444: + *format = WIN_COLOR_DEPTH_YCbCr444P; + break; + case DRM_FORMAT_NV12: *format = WIN_COLOR_DEPTH_YCbCr420SP; break; @@ -486,6 +506,7 @@ bool tegra_plane_format_is_yuv(unsigned int format, unsigned int *planes, unsign case WIN_COLOR_DEPTH_YUV422R: case WIN_COLOR_DEPTH_YCbCr422RA: case WIN_COLOR_DEPTH_YUV422RA: + case WIN_COLOR_DEPTH_YCbCr444P: if (planes) *planes = 3;