diff options
Diffstat (limited to 'drivers/gpu/drm/tegra/hub.c')
| -rw-r--r-- | drivers/gpu/drm/tegra/hub.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index b910155f80c4..c924ffba4094 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -5,18 +5,22 @@ #include <linux/clk.h> #include <linux/delay.h> +#include <linux/dma-mapping.h> #include <linux/host1x.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_graph.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_blend.h> #include <drm/drm_fourcc.h> +#include <drm/drm_framebuffer.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include "drm.h" @@ -518,12 +522,11 @@ static void tegra_shared_plane_atomic_disable(struct drm_plane *plane, static inline u32 compute_phase_incr(fixed20_12 in, unsigned int out) { - u64 tmp, tmp1, tmp2; + u64 tmp, tmp1; tmp = (u64)dfixed_trunc(in); - tmp2 = (u64)out; - tmp1 = (tmp << NFB) + (tmp2 >> 1); - do_div(tmp1, tmp2); + tmp1 = (tmp << NFB) + ((u64)out >> 1); + do_div(tmp1, out); return lower_32_bits(tmp1); } @@ -540,8 +543,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 +562,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 +663,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); + } - 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]); + + if (planes > 2) + value |= PITCH_V(fb->pitches[2]); - value = PITCH_U(fb->pitches[2]) | 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); @@ -747,9 +756,9 @@ static const struct drm_plane_helper_funcs tegra_shared_plane_helper_funcs = { struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, struct tegra_dc *dc, unsigned int wgrp, - unsigned int index) + unsigned int index, + enum drm_plane_type type) { - enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY; struct tegra_drm *tegra = drm->dev_private; struct tegra_display_hub *hub = tegra->hub; struct tegra_shared_plane *plane; @@ -1092,7 +1101,7 @@ static int tegra_display_hub_probe(struct platform_device *pdev) for (i = 0; i < hub->soc->num_wgrps; i++) { struct tegra_windowgroup *wgrp = &hub->wgrps[i]; - char id[8]; + char id[16]; snprintf(id, sizeof(id), "wgrp%u", i); mutex_init(&wgrp->lock); @@ -1165,17 +1174,12 @@ unregister: return err; } -static int tegra_display_hub_remove(struct platform_device *pdev) +static void tegra_display_hub_remove(struct platform_device *pdev) { struct tegra_display_hub *hub = platform_get_drvdata(pdev); unsigned int i; - int err; - err = host1x_client_unregister(&hub->client); - if (err < 0) { - dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", - err); - } + host1x_client_unregister(&hub->client); for (i = 0; i < hub->soc->num_wgrps; i++) { struct tegra_windowgroup *wgrp = &hub->wgrps[i]; @@ -1184,8 +1188,6 @@ static int tegra_display_hub_remove(struct platform_device *pdev) } pm_runtime_disable(&pdev->dev); - - return err; } static const struct tegra_display_hub_soc tegra186_display_hub = { |
