drm/tegra: Atomic conversion, phase 1
authorThierry Reding <treding@nvidia.com>
Mon, 24 Nov 2014 15:27:13 +0000 (16:27 +0100)
committerThierry Reding <treding@nvidia.com>
Tue, 27 Jan 2015 09:14:50 +0000 (10:14 +0100)
Implement initial atomic state handling. Hook up the CRTCs, planes' and
connectors' ->atomic_destroy_state() callback to ensure that the atomic
state objects don't leak.

Furthermore the CRTC now implements the ->mode_set_nofb() callback that
is used by new helpers to implement ->mode_set() and ->mode_set_base().
These new helpers also make use of the new plane helper functions which
the driver now provides.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/drm/tegra/dc.c
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/tegra/dsi.c
drivers/gpu/drm/tegra/hdmi.c
drivers/gpu/drm/tegra/output.c
drivers/gpu/drm/tegra/rgb.c
drivers/gpu/drm/tegra/sor.c

index 03c9ccf..f7254ab 100644 (file)
@@ -18,6 +18,7 @@
 #include "drm.h"
 #include "gem.h"
 
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
 
 struct tegra_dc_soc_info {
@@ -200,8 +201,8 @@ static inline u32 compute_initial_dda(unsigned int in)
        return dfixed_frac(inf);
 }
 
-static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
-                                const struct tegra_dc_window *window)
+static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
+                                 const struct tegra_dc_window *window)
 {
        unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
        unsigned long value, flags;
@@ -310,9 +311,11 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
                        break;
 
                case TEGRA_BO_TILING_MODE_BLOCK:
-                       DRM_ERROR("hardware doesn't support block linear mode\n");
-                       spin_unlock_irqrestore(&dc->lock, flags);
-                       return -EINVAL;
+                       /*
+                        * No need to handle this here because ->atomic_check
+                        * will already have filtered it out.
+                        */
+                       break;
                }
 
                tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
@@ -371,34 +374,6 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
        tegra_dc_window_commit(dc, index);
 
        spin_unlock_irqrestore(&dc->lock, flags);
-
-       return 0;
-}
-
-static int tegra_window_plane_disable(struct drm_plane *plane)
-{
-       struct tegra_dc *dc = to_tegra_dc(plane->crtc);
-       struct tegra_plane *p = to_tegra_plane(plane);
-       unsigned long flags;
-       u32 value;
-
-       if (!plane->crtc)
-               return 0;
-
-       spin_lock_irqsave(&dc->lock, flags);
-
-       value = WINDOW_A_SELECT << p->index;
-       tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
-
-       value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
-       value &= ~WIN_ENABLE;
-       tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
-
-       tegra_dc_window_commit(dc, p->index);
-
-       spin_unlock_irqrestore(&dc->lock, flags);
-
-       return 0;
 }
 
 static void tegra_plane_destroy(struct drm_plane *plane)
@@ -415,57 +390,139 @@ static const u32 tegra_primary_plane_formats[] = {
        DRM_FORMAT_RGB565,
 };
 
-static int tegra_primary_plane_update(struct drm_plane *plane,
-                                     struct drm_crtc *crtc,
-                                     struct drm_framebuffer *fb, int crtc_x,
-                                     int crtc_y, unsigned int crtc_w,
-                                     unsigned int crtc_h, uint32_t src_x,
-                                     uint32_t src_y, uint32_t src_w,
-                                     uint32_t src_h)
+static void tegra_primary_plane_destroy(struct drm_plane *plane)
 {
-       struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
+       tegra_plane_destroy(plane);
+}
+
+static const struct drm_plane_funcs tegra_primary_plane_funcs = {
+       .update_plane = drm_plane_helper_update,
+       .disable_plane = drm_plane_helper_disable,
+       .destroy = tegra_primary_plane_destroy,
+       .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+static int tegra_plane_prepare_fb(struct drm_plane *plane,
+                                 struct drm_framebuffer *fb)
+{
+       return 0;
+}
+
+static void tegra_plane_cleanup_fb(struct drm_plane *plane,
+                                  struct drm_framebuffer *fb)
+{
+}
+
+static int tegra_plane_atomic_check(struct drm_plane *plane,
+                                   struct drm_plane_state *state)
+{
+       struct tegra_dc *dc = to_tegra_dc(state->crtc);
+       struct tegra_bo_tiling tiling;
+       int err;
+
+       /* no need for further checks if the plane is being disabled */
+       if (!state->crtc)
+               return 0;
+
+       err = tegra_fb_get_tiling(state->fb, &tiling);
+       if (err < 0)
+               return err;
+
+       if (tiling.mode == TEGRA_BO_TILING_MODE_BLOCK &&
+           !dc->soc->supports_block_linear) {
+               DRM_ERROR("hardware doesn't support block linear mode\n");
+               return -EINVAL;
+       }
+
+       /*
+        * Tegra doesn't support different strides for U and V planes so we
+        * error out if the user tries to display a framebuffer with such a
+        * configuration.
+        */
+       if (drm_format_num_planes(state->fb->pixel_format) > 2) {
+               if (state->fb->pitches[2] != state->fb->pitches[1]) {
+                       DRM_ERROR("unsupported UV-plane configuration\n");
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static void tegra_plane_atomic_update(struct drm_plane *plane,
+                                     struct drm_plane_state *old_state)
+{
+       struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
+       struct drm_framebuffer *fb = plane->state->fb;
        struct tegra_plane *p = to_tegra_plane(plane);
-       struct tegra_dc *dc = to_tegra_dc(crtc);
        struct tegra_dc_window window;
+       unsigned int i;
        int err;
 
+       /* rien ne va plus */
+       if (!plane->state->crtc || !plane->state->fb)
+               return;
+
        memset(&window, 0, sizeof(window));
-       window.src.x = src_x >> 16;
-       window.src.y = src_y >> 16;
-       window.src.w = src_w >> 16;
-       window.src.h = src_h >> 16;
-       window.dst.x = crtc_x;
-       window.dst.y = crtc_y;
-       window.dst.w = crtc_w;
-       window.dst.h = crtc_h;
+       window.src.x = plane->state->src_x >> 16;
+       window.src.y = plane->state->src_y >> 16;
+       window.src.w = plane->state->src_w >> 16;
+       window.src.h = plane->state->src_h >> 16;
+       window.dst.x = plane->state->crtc_x;
+       window.dst.y = plane->state->crtc_y;
+       window.dst.w = plane->state->crtc_w;
+       window.dst.h = plane->state->crtc_h;
        window.format = tegra_dc_format(fb->pixel_format, &window.swap);
        window.bits_per_pixel = fb->bits_per_pixel;
        window.bottom_up = tegra_fb_is_bottom_up(fb);
 
        err = tegra_fb_get_tiling(fb, &window.tiling);
-       if (err < 0)
-               return err;
+       WARN_ON(err < 0);
 
-       window.base[0] = bo->paddr + fb->offsets[0];
-       window.stride[0] = fb->pitches[0];
+       for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
+               struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
 
-       err = tegra_dc_setup_window(dc, p->index, &window);
-       if (err < 0)
-               return err;
+               window.base[i] = bo->paddr + fb->offsets[i];
+               window.stride[i] = fb->pitches[i];
+       }
 
-       return 0;
+       tegra_dc_setup_window(dc, p->index, &window);
 }
 
-static void tegra_primary_plane_destroy(struct drm_plane *plane)
+static void tegra_plane_atomic_disable(struct drm_plane *plane,
+                                      struct drm_plane_state *old_state)
 {
-       tegra_window_plane_disable(plane);
-       tegra_plane_destroy(plane);
+       struct tegra_plane *p = to_tegra_plane(plane);
+       struct tegra_dc *dc;
+       unsigned long flags;
+       u32 value;
+
+       /* rien ne va plus */
+       if (!old_state || !old_state->crtc)
+               return;
+
+       dc = to_tegra_dc(old_state->crtc);
+
+       spin_lock_irqsave(&dc->lock, flags);
+
+       value = WINDOW_A_SELECT << p->index;
+       tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
+
+       value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
+       value &= ~WIN_ENABLE;
+       tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
+
+       tegra_dc_window_commit(dc, p->index);
+
+       spin_unlock_irqrestore(&dc->lock, flags);
 }
 
-static const struct drm_plane_funcs tegra_primary_plane_funcs = {
-       .update_plane = tegra_primary_plane_update,
-       .disable_plane = tegra_window_plane_disable,
-       .destroy = tegra_primary_plane_destroy,
+static const struct drm_plane_helper_funcs tegra_primary_plane_helper_funcs = {
+       .prepare_fb = tegra_plane_prepare_fb,
+       .cleanup_fb = tegra_plane_cleanup_fb,
+       .atomic_check = tegra_plane_atomic_check,
+       .atomic_update = tegra_plane_atomic_update,
+       .atomic_disable = tegra_plane_atomic_disable,
 };
 
 static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
@@ -504,6 +561,8 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
                return ERR_PTR(err);
        }
 
+       drm_plane_helper_add(&plane->base, &tegra_primary_plane_helper_funcs);
+
        return &plane->base;
 }
 
@@ -511,27 +570,42 @@ static const u32 tegra_cursor_plane_formats[] = {
        DRM_FORMAT_RGBA8888,
 };
 
-static int tegra_cursor_plane_update(struct drm_plane *plane,
-                                    struct drm_crtc *crtc,
-                                    struct drm_framebuffer *fb, int crtc_x,
-                                    int crtc_y, unsigned int crtc_w,
-                                    unsigned int crtc_h, uint32_t src_x,
-                                    uint32_t src_y, uint32_t src_w,
-                                    uint32_t src_h)
+static int tegra_cursor_atomic_check(struct drm_plane *plane,
+                                    struct drm_plane_state *state)
 {
-       struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
-       struct tegra_dc *dc = to_tegra_dc(crtc);
-       u32 value = CURSOR_CLIP_DISPLAY;
+       /* no need for further checks if the plane is being disabled */
+       if (!state->crtc)
+               return 0;
 
        /* scaling not supported for cursor */
-       if ((src_w >> 16 != crtc_w) || (src_h >> 16 != crtc_h))
+       if ((state->src_w >> 16 != state->crtc_w) ||
+           (state->src_h >> 16 != state->crtc_h))
                return -EINVAL;
 
        /* only square cursors supported */
-       if (src_w != src_h)
+       if (state->src_w != state->src_h)
+               return -EINVAL;
+
+       if (state->crtc_w != 32 && state->crtc_w != 64 &&
+           state->crtc_w != 128 && state->crtc_w != 256)
                return -EINVAL;
 
-       switch (crtc_w) {
+       return 0;
+}
+
+static void tegra_cursor_atomic_update(struct drm_plane *plane,
+                                      struct drm_plane_state *old_state)
+{
+       struct tegra_bo *bo = tegra_fb_get_plane(plane->state->fb, 0);
+       struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
+       struct drm_plane_state *state = plane->state;
+       u32 value = CURSOR_CLIP_DISPLAY;
+
+       /* rien ne va plus */
+       if (!plane->state->crtc || !plane->state->fb)
+               return;
+
+       switch (state->crtc_w) {
        case 32:
                value |= CURSOR_SIZE_32x32;
                break;
@@ -549,7 +623,9 @@ static int tegra_cursor_plane_update(struct drm_plane *plane,
                break;
 
        default:
-               return -EINVAL;
+               WARN(1, "cursor size %ux%u not supported\n", state->crtc_w,
+                    state->crtc_h);
+               return;
        }
 
        value |= (bo->paddr >> 10) & 0x3fffff;
@@ -575,23 +651,25 @@ static int tegra_cursor_plane_update(struct drm_plane *plane,
        tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL);
 
        /* position the cursor */
-       value = (crtc_y & 0x3fff) << 16 | (crtc_x & 0x3fff);
+       value = (state->crtc_y & 0x3fff) << 16 | (state->crtc_x & 0x3fff);
        tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION);
 
        /* apply changes */
        tegra_dc_cursor_commit(dc);
        tegra_dc_commit(dc);
-
-       return 0;
 }
 
-static int tegra_cursor_plane_disable(struct drm_plane *plane)
+static void tegra_cursor_atomic_disable(struct drm_plane *plane,
+                                       struct drm_plane_state *old_state)
 {
-       struct tegra_dc *dc = to_tegra_dc(plane->crtc);
+       struct tegra_dc *dc;
        u32 value;
 
-       if (!plane->crtc)
-               return 0;
+       /* rien ne va plus */
+       if (!old_state || !old_state->crtc)
+               return;
+
+       dc = to_tegra_dc(old_state->crtc);
 
        value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
        value &= ~CURSOR_ENABLE;
@@ -599,14 +677,21 @@ static int tegra_cursor_plane_disable(struct drm_plane *plane)
 
        tegra_dc_cursor_commit(dc);
        tegra_dc_commit(dc);
-
-       return 0;
 }
 
 static const struct drm_plane_funcs tegra_cursor_plane_funcs = {
-       .update_plane = tegra_cursor_plane_update,
-       .disable_plane = tegra_cursor_plane_disable,
+       .update_plane = drm_plane_helper_update,
+       .disable_plane = drm_plane_helper_disable,
        .destroy = tegra_plane_destroy,
+       .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+static const struct drm_plane_helper_funcs tegra_cursor_plane_helper_funcs = {
+       .prepare_fb = tegra_plane_prepare_fb,
+       .cleanup_fb = tegra_plane_cleanup_fb,
+       .atomic_check = tegra_cursor_atomic_check,
+       .atomic_update = tegra_cursor_atomic_update,
+       .atomic_disable = tegra_cursor_atomic_disable,
 };
 
 static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
@@ -632,71 +717,21 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
                return ERR_PTR(err);
        }
 
-       return &plane->base;
-}
-
-static int tegra_overlay_plane_update(struct drm_plane *plane,
-                                     struct drm_crtc *crtc,
-                                     struct drm_framebuffer *fb, int crtc_x,
-                                     int crtc_y, unsigned int crtc_w,
-                                     unsigned int crtc_h, uint32_t src_x,
-                                     uint32_t src_y, uint32_t src_w,
-                                     uint32_t src_h)
-{
-       struct tegra_plane *p = to_tegra_plane(plane);
-       struct tegra_dc *dc = to_tegra_dc(crtc);
-       struct tegra_dc_window window;
-       unsigned int i;
-       int err;
-
-       memset(&window, 0, sizeof(window));
-       window.src.x = src_x >> 16;
-       window.src.y = src_y >> 16;
-       window.src.w = src_w >> 16;
-       window.src.h = src_h >> 16;
-       window.dst.x = crtc_x;
-       window.dst.y = crtc_y;
-       window.dst.w = crtc_w;
-       window.dst.h = crtc_h;
-       window.format = tegra_dc_format(fb->pixel_format, &window.swap);
-       window.bits_per_pixel = fb->bits_per_pixel;
-       window.bottom_up = tegra_fb_is_bottom_up(fb);
-
-       err = tegra_fb_get_tiling(fb, &window.tiling);
-       if (err < 0)
-               return err;
+       drm_plane_helper_add(&plane->base, &tegra_cursor_plane_helper_funcs);
 
-       for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
-               struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
-
-               window.base[i] = bo->paddr + fb->offsets[i];
-
-               /*
-                * Tegra doesn't support different strides for U and V planes
-                * so we display a warning if the user tries to display a
-                * framebuffer with such a configuration.
-                */
-               if (i >= 2) {
-                       if (fb->pitches[i] != window.stride[1])
-                               DRM_ERROR("unsupported UV-plane configuration\n");
-               } else {
-                       window.stride[i] = fb->pitches[i];
-               }
-       }
-
-       return tegra_dc_setup_window(dc, p->index, &window);
+       return &plane->base;
 }
 
 static void tegra_overlay_plane_destroy(struct drm_plane *plane)
 {
-       tegra_window_plane_disable(plane);
        tegra_plane_destroy(plane);
 }
 
 static const struct drm_plane_funcs tegra_overlay_plane_funcs = {
-       .update_plane = tegra_overlay_plane_update,
-       .disable_plane = tegra_window_plane_disable,
+       .update_plane = drm_plane_helper_update,
+       .disable_plane = drm_plane_helper_disable,
        .destroy = tegra_overlay_plane_destroy,
+       .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
 
 static const uint32_t tegra_overlay_plane_formats[] = {
@@ -709,6 +744,14 @@ static const uint32_t tegra_overlay_plane_formats[] = {
        DRM_FORMAT_YUV422,
 };
 
+static const struct drm_plane_helper_funcs tegra_overlay_plane_helper_funcs = {
+       .prepare_fb = tegra_plane_prepare_fb,
+       .cleanup_fb = tegra_plane_cleanup_fb,
+       .atomic_check = tegra_plane_atomic_check,
+       .atomic_update = tegra_plane_atomic_update,
+       .atomic_disable = tegra_plane_atomic_disable,
+};
+
 static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
                                                       struct tegra_dc *dc,
                                                       unsigned int index)
@@ -735,6 +778,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
                return ERR_PTR(err);
        }
 
+       drm_plane_helper_add(&plane->base, &tegra_overlay_plane_helper_funcs);
+
        return &plane->base;
 }
 
@@ -953,6 +998,7 @@ static const struct drm_crtc_funcs tegra_crtc_funcs = {
        .page_flip = tegra_dc_page_flip,
        .set_config = drm_crtc_helper_set_config,
        .destroy = tegra_dc_destroy,
+       .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
 static void tegra_dc_stop(struct tegra_dc *dc)
@@ -1090,16 +1136,11 @@ int tegra_dc_setup_clock(struct tegra_dc *dc, struct clk *parent,
        return 0;
 }
 
-static int tegra_crtc_mode_set(struct drm_crtc *crtc,
-                              struct drm_display_mode *mode,
-                              struct drm_display_mode *adjusted,
-                              int x, int y, struct drm_framebuffer *old_fb)
+static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
-       struct tegra_bo *bo = tegra_fb_get_plane(crtc->primary->fb, 0);
+       struct drm_display_mode *mode = &crtc->state->adjusted_mode;
        struct tegra_dc *dc = to_tegra_dc(crtc);
-       struct tegra_dc_window window;
        u32 value;
-       int err;
 
        /* program display mode */
        tegra_dc_set_timings(dc, mode);
@@ -1113,36 +1154,6 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
                value &= ~INTERLACE_ENABLE;
                tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL);
        }
-
-       /* setup window parameters */
-       memset(&window, 0, sizeof(window));
-       window.src.x = 0;
-       window.src.y = 0;
-       window.src.w = mode->hdisplay;
-       window.src.h = mode->vdisplay;
-       window.dst.x = 0;
-       window.dst.y = 0;
-       window.dst.w = mode->hdisplay;
-       window.dst.h = mode->vdisplay;
-       window.format = tegra_dc_format(crtc->primary->fb->pixel_format,
-                                       &window.swap);
-       window.bits_per_pixel = crtc->primary->fb->bits_per_pixel;
-       window.stride[0] = crtc->primary->fb->pitches[0];
-       window.base[0] = bo->paddr;
-
-       err = tegra_dc_setup_window(dc, 0, &window);
-       if (err < 0)
-               dev_err(dc->dev, "failed to enable root plane\n");
-
-       return 0;
-}
-
-static int tegra_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-                                   struct drm_framebuffer *old_fb)
-{
-       struct tegra_dc *dc = to_tegra_dc(crtc);
-
-       return tegra_dc_set_base(dc, x, y, crtc->primary->fb);
 }
 
 static void tegra_crtc_prepare(struct drm_crtc *crtc)
@@ -1193,13 +1204,31 @@ static void tegra_crtc_commit(struct drm_crtc *crtc)
        tegra_dc_commit(dc);
 }
 
+static int tegra_crtc_atomic_check(struct drm_crtc *crtc,
+                                  struct drm_crtc_state *state)
+{
+       return 0;
+}
+
+static void tegra_crtc_atomic_begin(struct drm_crtc *crtc)
+{
+}
+
+static void tegra_crtc_atomic_flush(struct drm_crtc *crtc)
+{
+}
+
 static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
        .disable = tegra_crtc_disable,
        .mode_fixup = tegra_crtc_mode_fixup,
-       .mode_set = tegra_crtc_mode_set,
-       .mode_set_base = tegra_crtc_mode_set_base,
+       .mode_set = drm_helper_crtc_mode_set,
+       .mode_set_nofb = tegra_crtc_mode_set_nofb,
+       .mode_set_base = drm_helper_crtc_mode_set_base,
        .prepare = tegra_crtc_prepare,
        .commit = tegra_crtc_commit,
+       .atomic_check = tegra_crtc_atomic_check,
+       .atomic_begin = tegra_crtc_atomic_begin,
+       .atomic_flush = tegra_crtc_atomic_flush,
 };
 
 static irqreturn_t tegra_dc_irq(int irq, void *data)
index e29d914..0e0da86 100644 (file)
@@ -121,8 +121,8 @@ static int tegra_drm_unload(struct drm_device *drm)
 
        drm_kms_helper_poll_fini(drm);
        tegra_drm_fb_exit(drm);
-       drm_vblank_cleanup(drm);
        drm_mode_config_cleanup(drm);
+       drm_vblank_cleanup(drm);
 
        err = host1x_device_exit(device);
        if (err < 0)
index 23f4b0f..234cd1c 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/regulator/consumer.h>
 
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_panel.h>
 
@@ -736,6 +737,7 @@ static const struct drm_connector_funcs tegra_dsi_connector_funcs = {
        .detect = tegra_output_connector_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .destroy = tegra_output_connector_destroy,
+       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static enum drm_mode_status
index d41530f..bf868d5 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 
@@ -781,6 +782,7 @@ static const struct drm_connector_funcs tegra_hdmi_connector_funcs = {
        .detect = tegra_output_connector_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .destroy = tegra_output_connector_destroy,
+       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static enum drm_mode_status
index 8bb6600..37db479 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/of_gpio.h>
 
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_panel.h>
 #include "drm.h"
 
index 0c932f9..23ba403 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/clk.h>
 
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_panel.h>
 
 #include "drm.h"
@@ -97,6 +98,7 @@ static const struct drm_connector_funcs tegra_rgb_connector_funcs = {
        .detect = tegra_output_connector_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .destroy = tegra_output_connector_destroy,
+       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static enum drm_mode_status
index 9e67838..e2f3993 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <soc/tegra/pmc.h>
 
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_panel.h>
 
@@ -737,6 +738,7 @@ static const struct drm_connector_funcs tegra_sor_connector_funcs = {
        .detect = tegra_sor_connector_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .destroy = tegra_output_connector_destroy,
+       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static int tegra_sor_connector_get_modes(struct drm_connector *connector)