From 836aadff09e0bd271f09c65f0cb7a301c2fee337 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Mon, 24 May 2021 15:14:20 +0100 Subject: [PATCH] drm/tegra: Update Tegra DRM to add support for v5.13 There are several updates in the Linux DRM framework for Linux v5.13 and so make the necessary changes to the out-of-tree Tegra DRM driver so we can compile it with Linux v5.13 and earlier. Bug 3308967 Change-Id: Ie7a5e0a3978b2d6d16f769c2efda8b1685e28709 Signed-off-by: Jon Hunter Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2534002 Reviewed-by: Mikko Perttunen Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- drivers/gpu/drm/tegra/dc.c | 135 +++++++++++++++++++++++----------- drivers/gpu/drm/tegra/hub.c | 76 +++++++++++++------ drivers/gpu/drm/tegra/plane.c | 9 +++ 3 files changed, 153 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index cb3a4cdf..168a583d 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -605,23 +605,31 @@ static const u64 tegra124_modifiers[] = { }; static int tegra_plane_atomic_check(struct drm_plane *plane, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_atomic_state *state) +{ + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, + plane); +#else struct drm_plane_state *state) { - struct tegra_plane_state *plane_state = to_tegra_plane_state(state); + struct drm_plane_state *new_plane_state = state; +#endif + struct tegra_plane_state *plane_state = to_tegra_plane_state(new_plane_state); unsigned int supported_rotation = DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y; - unsigned int rotation = state->rotation; + unsigned int rotation = new_plane_state->rotation; struct tegra_bo_tiling *tiling = &plane_state->tiling; struct tegra_plane *tegra = to_tegra_plane(plane); - struct tegra_dc *dc = to_tegra_dc(state->crtc); + struct tegra_dc *dc = to_tegra_dc(new_plane_state->crtc); int err; /* no need for further checks if the plane is being disabled */ - if (!state->crtc) + if (!new_plane_state->crtc) return 0; - err = tegra_plane_format(state->fb->format->format, + err = tegra_plane_format(new_plane_state->fb->format->format, &plane_state->format, &plane_state->swap); if (err < 0) @@ -639,7 +647,7 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, return err; } - err = tegra_fb_get_tiling(state->fb, tiling); + err = tegra_fb_get_tiling(new_plane_state->fb, tiling); if (err < 0) return err; @@ -655,7 +663,7 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, * property in order to achieve the same result. The legacy BO flag * duplicates the DRM rotation property when both are set. */ - if (tegra_fb_is_bottom_up(state->fb)) + if (tegra_fb_is_bottom_up(new_plane_state->fb)) rotation |= DRM_MODE_REFLECT_Y; rotation = drm_rotation_simplify(rotation, supported_rotation); @@ -675,14 +683,14 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, * error out if the user tries to display a framebuffer with such a * configuration. */ - if (state->fb->format->num_planes > 2) { - if (state->fb->pitches[2] != state->fb->pitches[1]) { + if (new_plane_state->fb->format->num_planes > 2) { + if (new_plane_state->fb->pitches[2] != new_plane_state->fb->pitches[1]) { DRM_ERROR("unsupported UV-plane configuration\n"); return -EINVAL; } } - err = tegra_plane_state_add(tegra, state); + err = tegra_plane_state_add(tegra, new_plane_state); if (err < 0) return err; @@ -690,8 +698,15 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, } static void tegra_plane_atomic_disable(struct drm_plane *plane, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_atomic_state *state) +{ + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, + plane); +#else struct drm_plane_state *old_state) { +#endif struct tegra_plane *p = to_tegra_plane(plane); u32 value; @@ -705,42 +720,54 @@ static void tegra_plane_atomic_disable(struct drm_plane *plane, } static void tegra_plane_atomic_update(struct drm_plane *plane, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_atomic_state *state) +{ + struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, + plane); +#else struct drm_plane_state *old_state) { - struct tegra_plane_state *state = to_tegra_plane_state(plane->state); - struct drm_framebuffer *fb = plane->state->fb; + struct drm_plane_state *new_state = plane->state; +#endif + struct tegra_plane_state *tegra_plane_state = to_tegra_plane_state(new_state); + struct drm_framebuffer *fb = new_state->fb; struct tegra_plane *p = to_tegra_plane(plane); struct tegra_dc_window window; unsigned int i; /* rien ne va plus */ - if (!plane->state->crtc || !plane->state->fb) + if (!new_state->crtc || !new_state->fb) return; - if (!plane->state->visible) + if (!new_state->visible) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + return tegra_plane_atomic_disable(plane, state); +#else return tegra_plane_atomic_disable(plane, old_state); +#endif memset(&window, 0, sizeof(window)); - window.src.x = plane->state->src.x1 >> 16; - window.src.y = plane->state->src.y1 >> 16; - window.src.w = drm_rect_width(&plane->state->src) >> 16; - window.src.h = drm_rect_height(&plane->state->src) >> 16; - window.dst.x = plane->state->dst.x1; - window.dst.y = plane->state->dst.y1; - window.dst.w = drm_rect_width(&plane->state->dst); - window.dst.h = drm_rect_height(&plane->state->dst); + window.src.x = new_state->src.x1 >> 16; + window.src.y = new_state->src.y1 >> 16; + window.src.w = drm_rect_width(&new_state->src) >> 16; + window.src.h = drm_rect_height(&new_state->src) >> 16; + window.dst.x = new_state->dst.x1; + window.dst.y = new_state->dst.y1; + window.dst.w = drm_rect_width(&new_state->dst); + window.dst.h = drm_rect_height(&new_state->dst); window.bits_per_pixel = fb->format->cpp[0] * 8; - window.reflect_x = state->reflect_x; - window.reflect_y = state->reflect_y; + window.reflect_x = tegra_plane_state->reflect_x; + window.reflect_y = tegra_plane_state->reflect_y; /* copy from state */ - window.zpos = plane->state->normalized_zpos; - window.tiling = state->tiling; - window.format = state->format; - window.swap = state->swap; + window.zpos = new_state->normalized_zpos; + window.tiling = tegra_plane_state->tiling; + window.format = tegra_plane_state->format; + window.swap = tegra_plane_state->swap; for (i = 0; i < fb->format->num_planes; i++) { - window.base[i] = state->iova[i] + fb->offsets[i]; + window.base[i] = tegra_plane_state->iova[i] + fb->offsets[i]; /* * Tegra uses a shared stride for UV planes. Framebuffers are @@ -832,29 +859,36 @@ static const u32 tegra_cursor_plane_formats[] = { }; static int tegra_cursor_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_atomic_state *state) { + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, + plane); +#else + struct drm_plane_state *new_plane_state) +{ +#endif struct tegra_plane *tegra = to_tegra_plane(plane); int err; /* no need for further checks if the plane is being disabled */ - if (!state->crtc) + if (!new_plane_state->crtc) return 0; /* scaling not supported for cursor */ - if ((state->src_w >> 16 != state->crtc_w) || - (state->src_h >> 16 != state->crtc_h)) + if ((new_plane_state->src_w >> 16 != new_plane_state->crtc_w) || + (new_plane_state->src_h >> 16 != new_plane_state->crtc_h)) return -EINVAL; /* only square cursors supported */ - if (state->src_w != state->src_h) + if (new_plane_state->src_w != new_plane_state->src_h) return -EINVAL; - if (state->crtc_w != 32 && state->crtc_w != 64 && - state->crtc_w != 128 && state->crtc_w != 256) + if (new_plane_state->crtc_w != 32 && new_plane_state->crtc_w != 64 && + new_plane_state->crtc_w != 128 && new_plane_state->crtc_w != 256) return -EINVAL; - err = tegra_plane_state_add(tegra, state); + err = tegra_plane_state_add(tegra, new_plane_state); if (err < 0) return err; @@ -862,17 +896,25 @@ static int tegra_cursor_atomic_check(struct drm_plane *plane, } static void tegra_cursor_atomic_update(struct drm_plane *plane, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_atomic_state *state) +{ + struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, + plane); +#else struct drm_plane_state *old_state) { - struct tegra_plane_state *state = to_tegra_plane_state(plane->state); + struct drm_plane_state *new_state = plane->state; +#endif + struct tegra_plane_state *tegra_plane_state = to_tegra_plane_state(new_state); struct tegra_dc *dc = to_tegra_dc(plane->state->crtc); u32 value = CURSOR_CLIP_DISPLAY; /* rien ne va plus */ - if (!plane->state->crtc || !plane->state->fb) + if (!new_state->crtc || !new_state->fb) return; - switch (plane->state->crtc_w) { + switch (new_state->crtc_w) { case 32: value |= CURSOR_SIZE_32x32; break; @@ -891,15 +933,15 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane, default: WARN(1, "cursor size %ux%u not supported\n", - plane->state->crtc_w, plane->state->crtc_h); + new_state->crtc_w, new_state->crtc_h); return; } - value |= (state->iova[0] >> 10) & 0x3fffff; + value |= (tegra_plane_state->iova[0] >> 10) & 0x3fffff; tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR); #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT - value = (state->iova[0] >> 32) & 0x3; + value = (tegra_plane_state->iova[0] >> 32) & 0x3; tegra_dc_writel(dc, value, DC_DISP_CURSOR_START_ADDR_HI); #endif @@ -924,8 +966,15 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane, } static void tegra_cursor_atomic_disable(struct drm_plane *plane, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_atomic_state *state) +{ + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, + plane); +#else struct drm_plane_state *old_state) { +#endif struct tegra_dc *dc; u32 value; diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index 6f64dc65..df2f34b0 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -336,25 +337,33 @@ static void tegra_dc_remove_shared_plane(struct tegra_dc *dc, } static int tegra_shared_plane_atomic_check(struct drm_plane *plane, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_atomic_state *state) +{ + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, + plane); +#else struct drm_plane_state *state) { - struct tegra_plane_state *plane_state = to_tegra_plane_state(state); + struct drm_plane_state *new_plane_state = state; +#endif + struct tegra_plane_state *plane_state = to_tegra_plane_state(new_plane_state); struct tegra_shared_plane *tegra = to_tegra_shared_plane(plane); struct tegra_bo_tiling *tiling = &plane_state->tiling; - struct tegra_dc *dc = to_tegra_dc(state->crtc); + struct tegra_dc *dc = to_tegra_dc(new_plane_state->crtc); int err; /* no need for further checks if the plane is being disabled */ - if (!state->crtc || !state->fb) + if (!new_plane_state->crtc || !new_plane_state->fb) return 0; - err = tegra_plane_format(state->fb->format->format, + err = tegra_plane_format(new_plane_state->fb->format->format, &plane_state->format, &plane_state->swap); if (err < 0) return err; - err = tegra_fb_get_tiling(state->fb, tiling); + err = tegra_fb_get_tiling(new_plane_state->fb, tiling); if (err < 0) return err; @@ -369,8 +378,8 @@ static int tegra_shared_plane_atomic_check(struct drm_plane *plane, * error out if the user tries to display a framebuffer with such a * configuration. */ - if (state->fb->format->num_planes > 2) { - if (state->fb->pitches[2] != state->fb->pitches[1]) { + if (new_plane_state->fb->format->num_planes > 2) { + if (new_plane_state->fb->pitches[2] != new_plane_state->fb->pitches[1]) { DRM_ERROR("unsupported UV-plane configuration\n"); return -EINVAL; } @@ -378,7 +387,7 @@ static int tegra_shared_plane_atomic_check(struct drm_plane *plane, /* XXX scaling is not yet supported, add a check here */ - err = tegra_plane_state_add(&tegra->base, state); + err = tegra_plane_state_add(&tegra->base, new_plane_state); if (err < 0) return err; @@ -386,8 +395,15 @@ static int tegra_shared_plane_atomic_check(struct drm_plane *plane, } static void tegra_shared_plane_atomic_disable(struct drm_plane *plane, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_atomic_state *state) +{ + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, + plane); +#else struct drm_plane_state *old_state) { +#endif struct tegra_plane *p = to_tegra_plane(plane); struct tegra_dc *dc; u32 value; @@ -423,23 +439,35 @@ static void tegra_shared_plane_atomic_disable(struct drm_plane *plane, } static void tegra_shared_plane_atomic_update(struct drm_plane *plane, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + struct drm_atomic_state *state) +{ + struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, + plane); +#else struct drm_plane_state *old_state) { - struct tegra_plane_state *state = to_tegra_plane_state(plane->state); - struct tegra_dc *dc = to_tegra_dc(plane->state->crtc); - unsigned int zpos = plane->state->normalized_zpos; - struct drm_framebuffer *fb = plane->state->fb; + struct drm_plane_state *new_state = plane->state; +#endif + struct tegra_plane_state *tegra_plane_state = to_tegra_plane_state(new_state); + struct tegra_dc *dc = to_tegra_dc(new_state->crtc); + unsigned int zpos = new_state->normalized_zpos; + struct drm_framebuffer *fb = new_state->fb; struct tegra_plane *p = to_tegra_plane(plane); dma_addr_t base; u32 value; int err; /* rien ne va plus */ - if (!plane->state->crtc || !plane->state->fb) + if (!new_state->crtc || !new_state->fb) return; - if (!plane->state->visible) { + if (!new_state->visible) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + tegra_shared_plane_atomic_disable(plane, state); +#else tegra_shared_plane_atomic_disable(plane, old_state); +#endif return; } @@ -477,22 +505,22 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, /* disable compression */ tegra_plane_writel(p, 0, DC_WINBUF_CDE_CONTROL); - base = state->iova[0] + fb->offsets[0]; + base = tegra_plane_state->iova[0] + fb->offsets[0]; - tegra_plane_writel(p, state->format, DC_WIN_COLOR_DEPTH); + tegra_plane_writel(p, tegra_plane_state->format, DC_WIN_COLOR_DEPTH); tegra_plane_writel(p, 0, DC_WIN_PRECOMP_WGRP_PARAMS); - value = V_POSITION(plane->state->crtc_y) | - H_POSITION(plane->state->crtc_x); + value = V_POSITION(new_state->crtc_y) | + H_POSITION(new_state->crtc_x); tegra_plane_writel(p, value, DC_WIN_POSITION); - value = V_SIZE(plane->state->crtc_h) | H_SIZE(plane->state->crtc_w); + value = V_SIZE(new_state->crtc_h) | H_SIZE(new_state->crtc_w); tegra_plane_writel(p, value, DC_WIN_SIZE); value = WIN_ENABLE | COLOR_EXPAND; tegra_plane_writel(p, value, DC_WIN_WIN_OPTIONS); - value = V_SIZE(plane->state->crtc_h) | H_SIZE(plane->state->crtc_w); + value = V_SIZE(new_state->crtc_h) | H_SIZE(new_state->crtc_w); tegra_plane_writel(p, value, DC_WIN_CROPPED_SIZE); tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI); @@ -504,15 +532,15 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, value = CLAMP_BEFORE_BLEND | DEGAMMA_SRGB | INPUT_RANGE_FULL; tegra_plane_writel(p, value, DC_WIN_SET_PARAMS); - value = OFFSET_X(plane->state->src_y >> 16) | - OFFSET_Y(plane->state->src_x >> 16); + value = OFFSET_X(new_state->src_y >> 16) | + OFFSET_Y(new_state->src_x >> 16); tegra_plane_writel(p, value, DC_WINBUF_CROPPED_POINT); if (dc->soc->supports_block_linear) { - unsigned long height = state->tiling.value; + unsigned long height = tegra_plane_state->tiling.value; /* XXX */ - switch (state->tiling.mode) { + switch (tegra_plane_state->tiling.mode) { case TEGRA_BO_TILING_MODE_PITCH: value = DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(0) | DC_WINBUF_SURFACE_KIND_PITCH; diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 539d1493..50f42d1e 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -4,11 +4,16 @@ */ #include +#include #include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) +#include +#else #include +#endif #include #include "dc.h" @@ -198,7 +203,11 @@ int tegra_plane_prepare_fb(struct drm_plane *plane, if (!state->fb) return 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) + drm_gem_plane_helper_prepare_fb(plane, state); +#else drm_gem_fb_prepare_fb(plane, state); +#endif return tegra_dc_pin(dc, to_tegra_plane_state(state)); }