root/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c

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

DEFINITIONS

This source file includes following definitions.
  1. fsl_dcu_drm_plane_index
  2. fsl_dcu_drm_plane_atomic_check
  3. fsl_dcu_drm_plane_atomic_disable
  4. fsl_dcu_drm_plane_atomic_update
  5. fsl_dcu_drm_plane_destroy
  6. fsl_dcu_drm_init_planes
  7. fsl_dcu_drm_primary_create_plane

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright 2015 Freescale Semiconductor, Inc.
   4  *
   5  * Freescale DCU drm device driver
   6  */
   7 
   8 #include <linux/regmap.h>
   9 
  10 #include <drm/drm_atomic_helper.h>
  11 #include <drm/drm_crtc.h>
  12 #include <drm/drm_fb_cma_helper.h>
  13 #include <drm/drm_fourcc.h>
  14 #include <drm/drm_gem_cma_helper.h>
  15 #include <drm/drm_plane_helper.h>
  16 #include <drm/drm_probe_helper.h>
  17 
  18 #include "fsl_dcu_drm_drv.h"
  19 #include "fsl_dcu_drm_plane.h"
  20 
  21 static int fsl_dcu_drm_plane_index(struct drm_plane *plane)
  22 {
  23         struct fsl_dcu_drm_device *fsl_dev = plane->dev->dev_private;
  24         unsigned int total_layer = fsl_dev->soc->total_layer;
  25         unsigned int index;
  26 
  27         index = drm_plane_index(plane);
  28         if (index < total_layer)
  29                 return total_layer - index - 1;
  30 
  31         dev_err(fsl_dev->dev, "No more layer left\n");
  32         return -EINVAL;
  33 }
  34 
  35 static int fsl_dcu_drm_plane_atomic_check(struct drm_plane *plane,
  36                                           struct drm_plane_state *state)
  37 {
  38         struct drm_framebuffer *fb = state->fb;
  39 
  40         if (!state->fb || !state->crtc)
  41                 return 0;
  42 
  43         switch (fb->format->format) {
  44         case DRM_FORMAT_RGB565:
  45         case DRM_FORMAT_RGB888:
  46         case DRM_FORMAT_XRGB8888:
  47         case DRM_FORMAT_ARGB8888:
  48         case DRM_FORMAT_XRGB4444:
  49         case DRM_FORMAT_ARGB4444:
  50         case DRM_FORMAT_XRGB1555:
  51         case DRM_FORMAT_ARGB1555:
  52         case DRM_FORMAT_YUV422:
  53                 return 0;
  54         default:
  55                 return -EINVAL;
  56         }
  57 }
  58 
  59 static void fsl_dcu_drm_plane_atomic_disable(struct drm_plane *plane,
  60                                              struct drm_plane_state *old_state)
  61 {
  62         struct fsl_dcu_drm_device *fsl_dev = plane->dev->dev_private;
  63         unsigned int value;
  64         int index;
  65 
  66         index = fsl_dcu_drm_plane_index(plane);
  67         if (index < 0)
  68                 return;
  69 
  70         regmap_read(fsl_dev->regmap, DCU_CTRLDESCLN(index, 4), &value);
  71         value &= ~DCU_LAYER_EN;
  72         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 4), value);
  73 }
  74 
  75 static void fsl_dcu_drm_plane_atomic_update(struct drm_plane *plane,
  76                                             struct drm_plane_state *old_state)
  77 
  78 {
  79         struct fsl_dcu_drm_device *fsl_dev = plane->dev->dev_private;
  80         struct drm_plane_state *state = plane->state;
  81         struct drm_framebuffer *fb = plane->state->fb;
  82         struct drm_gem_cma_object *gem;
  83         unsigned int alpha = DCU_LAYER_AB_NONE, bpp;
  84         int index;
  85 
  86         if (!fb)
  87                 return;
  88 
  89         index = fsl_dcu_drm_plane_index(plane);
  90         if (index < 0)
  91                 return;
  92 
  93         gem = drm_fb_cma_get_gem_obj(fb, 0);
  94 
  95         switch (fb->format->format) {
  96         case DRM_FORMAT_RGB565:
  97                 bpp = FSL_DCU_RGB565;
  98                 break;
  99         case DRM_FORMAT_RGB888:
 100                 bpp = FSL_DCU_RGB888;
 101                 break;
 102         case DRM_FORMAT_ARGB8888:
 103                 alpha = DCU_LAYER_AB_WHOLE_FRAME;
 104                 /* fall-through */
 105         case DRM_FORMAT_XRGB8888:
 106                 bpp = FSL_DCU_ARGB8888;
 107                 break;
 108         case DRM_FORMAT_ARGB4444:
 109                 alpha = DCU_LAYER_AB_WHOLE_FRAME;
 110                 /* fall-through */
 111         case DRM_FORMAT_XRGB4444:
 112                 bpp = FSL_DCU_ARGB4444;
 113                 break;
 114         case DRM_FORMAT_ARGB1555:
 115                 alpha = DCU_LAYER_AB_WHOLE_FRAME;
 116                 /* fall-through */
 117         case DRM_FORMAT_XRGB1555:
 118                 bpp = FSL_DCU_ARGB1555;
 119                 break;
 120         case DRM_FORMAT_YUV422:
 121                 bpp = FSL_DCU_YUV422;
 122                 break;
 123         default:
 124                 return;
 125         }
 126 
 127         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 1),
 128                      DCU_LAYER_HEIGHT(state->crtc_h) |
 129                      DCU_LAYER_WIDTH(state->crtc_w));
 130         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 2),
 131                      DCU_LAYER_POSY(state->crtc_y) |
 132                      DCU_LAYER_POSX(state->crtc_x));
 133         regmap_write(fsl_dev->regmap,
 134                      DCU_CTRLDESCLN(index, 3), gem->paddr);
 135         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 4),
 136                      DCU_LAYER_EN |
 137                      DCU_LAYER_TRANS(0xff) |
 138                      DCU_LAYER_BPP(bpp) |
 139                      alpha);
 140         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 5),
 141                      DCU_LAYER_CKMAX_R(0xFF) |
 142                      DCU_LAYER_CKMAX_G(0xFF) |
 143                      DCU_LAYER_CKMAX_B(0xFF));
 144         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 6),
 145                      DCU_LAYER_CKMIN_R(0) |
 146                      DCU_LAYER_CKMIN_G(0) |
 147                      DCU_LAYER_CKMIN_B(0));
 148         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 7), 0);
 149         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 8),
 150                      DCU_LAYER_FG_FCOLOR(0));
 151         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 9),
 152                      DCU_LAYER_BG_BCOLOR(0));
 153 
 154         if (!strcmp(fsl_dev->soc->name, "ls1021a")) {
 155                 regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(index, 10),
 156                              DCU_LAYER_POST_SKIP(0) |
 157                              DCU_LAYER_PRE_SKIP(0));
 158         }
 159 
 160         return;
 161 }
 162 
 163 static const struct drm_plane_helper_funcs fsl_dcu_drm_plane_helper_funcs = {
 164         .atomic_check = fsl_dcu_drm_plane_atomic_check,
 165         .atomic_disable = fsl_dcu_drm_plane_atomic_disable,
 166         .atomic_update = fsl_dcu_drm_plane_atomic_update,
 167 };
 168 
 169 static void fsl_dcu_drm_plane_destroy(struct drm_plane *plane)
 170 {
 171         drm_plane_cleanup(plane);
 172         kfree(plane);
 173 }
 174 
 175 static const struct drm_plane_funcs fsl_dcu_drm_plane_funcs = {
 176         .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 177         .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 178         .destroy = fsl_dcu_drm_plane_destroy,
 179         .disable_plane = drm_atomic_helper_disable_plane,
 180         .reset = drm_atomic_helper_plane_reset,
 181         .update_plane = drm_atomic_helper_update_plane,
 182 };
 183 
 184 static const u32 fsl_dcu_drm_plane_formats[] = {
 185         DRM_FORMAT_RGB565,
 186         DRM_FORMAT_RGB888,
 187         DRM_FORMAT_XRGB8888,
 188         DRM_FORMAT_ARGB8888,
 189         DRM_FORMAT_XRGB4444,
 190         DRM_FORMAT_ARGB4444,
 191         DRM_FORMAT_XRGB1555,
 192         DRM_FORMAT_ARGB1555,
 193         DRM_FORMAT_YUV422,
 194 };
 195 
 196 void fsl_dcu_drm_init_planes(struct drm_device *dev)
 197 {
 198         struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
 199         int i, j;
 200 
 201         for (i = 0; i < fsl_dev->soc->total_layer; i++) {
 202                 for (j = 1; j <= fsl_dev->soc->layer_regs; j++)
 203                         regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(i, j), 0);
 204         }
 205 }
 206 
 207 struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
 208 {
 209         struct drm_plane *primary;
 210         int ret;
 211 
 212         primary = kzalloc(sizeof(*primary), GFP_KERNEL);
 213         if (!primary) {
 214                 DRM_DEBUG_KMS("Failed to allocate primary plane\n");
 215                 return NULL;
 216         }
 217 
 218         /* possible_crtc's will be filled in later by crtc_init */
 219         ret = drm_universal_plane_init(dev, primary, 0,
 220                                        &fsl_dcu_drm_plane_funcs,
 221                                        fsl_dcu_drm_plane_formats,
 222                                        ARRAY_SIZE(fsl_dcu_drm_plane_formats),
 223                                        NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
 224         if (ret) {
 225                 kfree(primary);
 226                 primary = NULL;
 227         }
 228         drm_plane_helper_add(primary, &fsl_dcu_drm_plane_helper_funcs);
 229 
 230         return primary;
 231 }

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