root/drivers/gpu/drm/tilcdc/tilcdc_plane.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tilcdc_plane_atomic_check
  2. tilcdc_plane_atomic_update
  3. tilcdc_plane_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2015 Texas Instruments
   4  * Author: Jyri Sarha <jsarha@ti.com>
   5  */
   6 
   7 #include <drm/drm_atomic.h>
   8 #include <drm/drm_plane_helper.h>
   9 #include <drm/drm_atomic_helper.h>
  10 #include <drm/drm_fourcc.h>
  11 
  12 #include "tilcdc_drv.h"
  13 
  14 static struct drm_plane_funcs tilcdc_plane_funcs = {
  15         .update_plane   = drm_atomic_helper_update_plane,
  16         .disable_plane  = drm_atomic_helper_disable_plane,
  17         .destroy        = drm_plane_cleanup,
  18         .reset          = drm_atomic_helper_plane_reset,
  19         .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
  20         .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
  21 };
  22 
  23 static int tilcdc_plane_atomic_check(struct drm_plane *plane,
  24                                      struct drm_plane_state *state)
  25 {
  26         struct drm_crtc_state *crtc_state;
  27         struct drm_plane_state *old_state = plane->state;
  28         unsigned int pitch;
  29 
  30         if (!state->crtc)
  31                 return 0;
  32 
  33         if (WARN_ON(!state->fb))
  34                 return -EINVAL;
  35 
  36         if (state->crtc_x || state->crtc_y) {
  37                 dev_err(plane->dev->dev, "%s: crtc position must be zero.",
  38                         __func__);
  39                 return -EINVAL;
  40         }
  41 
  42         crtc_state = drm_atomic_get_existing_crtc_state(state->state,
  43                                                         state->crtc);
  44         /* we should have a crtc state if the plane is attached to a crtc */
  45         if (WARN_ON(!crtc_state))
  46                 return 0;
  47 
  48         if (crtc_state->mode.hdisplay != state->crtc_w ||
  49             crtc_state->mode.vdisplay != state->crtc_h) {
  50                 dev_err(plane->dev->dev,
  51                         "%s: Size must match mode (%dx%d == %dx%d)", __func__,
  52                         crtc_state->mode.hdisplay, crtc_state->mode.vdisplay,
  53                         state->crtc_w, state->crtc_h);
  54                 return -EINVAL;
  55         }
  56 
  57         pitch = crtc_state->mode.hdisplay *
  58                 state->fb->format->cpp[0];
  59         if (state->fb->pitches[0] != pitch) {
  60                 dev_err(plane->dev->dev,
  61                         "Invalid pitch: fb and crtc widths must be the same");
  62                 return -EINVAL;
  63         }
  64 
  65         if (state->fb && old_state->fb &&
  66             state->fb->format != old_state->fb->format) {
  67                 dev_dbg(plane->dev->dev,
  68                         "%s(): pixel format change requires mode_change\n",
  69                         __func__);
  70                 crtc_state->mode_changed = true;
  71         }
  72 
  73         return 0;
  74 }
  75 
  76 static void tilcdc_plane_atomic_update(struct drm_plane *plane,
  77                                        struct drm_plane_state *old_state)
  78 {
  79         struct drm_plane_state *state = plane->state;
  80 
  81         if (!state->crtc)
  82                 return;
  83 
  84         if (WARN_ON(!state->fb || !state->crtc->state))
  85                 return;
  86 
  87         tilcdc_crtc_update_fb(state->crtc,
  88                               state->fb,
  89                               state->crtc->state->event);
  90 }
  91 
  92 static const struct drm_plane_helper_funcs plane_helper_funcs = {
  93         .atomic_check = tilcdc_plane_atomic_check,
  94         .atomic_update = tilcdc_plane_atomic_update,
  95 };
  96 
  97 int tilcdc_plane_init(struct drm_device *dev,
  98                       struct drm_plane *plane)
  99 {
 100         struct tilcdc_drm_private *priv = dev->dev_private;
 101         int ret;
 102 
 103         ret = drm_plane_init(dev, plane, 1,
 104                              &tilcdc_plane_funcs,
 105                              priv->pixelformats,
 106                              priv->num_pixelformats,
 107                              true);
 108         if (ret) {
 109                 dev_err(dev->dev, "Failed to initialize plane: %d\n", ret);
 110                 return ret;
 111         }
 112 
 113         drm_plane_helper_add(plane, &plane_helper_funcs);
 114 
 115         return 0;
 116 }

/* [<][>][^][v][top][bottom][index][help] */