linux/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014 Traphandler
   3 * Copyright (C) 2014 Free Electrons
   4 * Copyright (C) 2014 Atmel
   5 *
   6 * Author: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
   7 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify it
  10 * under the terms of the GNU General Public License version 2 as published by
  11 * the Free Software Foundation.
  12 *
  13 * This program is distributed in the hope that it will be useful, but WITHOUT
  14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  16 * more details.
  17 *
  18 * You should have received a copy of the GNU General Public License along with
  19 * this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21
  22#ifndef DRM_ATMEL_HLCDC_H
  23#define DRM_ATMEL_HLCDC_H
  24
  25#include <linux/clk.h>
  26#include <linux/dmapool.h>
  27#include <linux/irqdomain.h>
  28#include <linux/mfd/atmel-hlcdc.h>
  29#include <linux/pwm.h>
  30
  31#include <drm/drm_atomic.h>
  32#include <drm/drm_atomic_helper.h>
  33#include <drm/drm_crtc.h>
  34#include <drm/drm_crtc_helper.h>
  35#include <drm/drm_fb_helper.h>
  36#include <drm/drm_fb_cma_helper.h>
  37#include <drm/drm_gem_cma_helper.h>
  38#include <drm/drm_gem_framebuffer_helper.h>
  39#include <drm/drm_panel.h>
  40#include <drm/drm_plane_helper.h>
  41#include <drm/drmP.h>
  42
  43#define ATMEL_HLCDC_LAYER_CHER                  0x0
  44#define ATMEL_HLCDC_LAYER_CHDR                  0x4
  45#define ATMEL_HLCDC_LAYER_CHSR                  0x8
  46#define ATMEL_HLCDC_LAYER_EN                    BIT(0)
  47#define ATMEL_HLCDC_LAYER_UPDATE                BIT(1)
  48#define ATMEL_HLCDC_LAYER_A2Q                   BIT(2)
  49#define ATMEL_HLCDC_LAYER_RST                   BIT(8)
  50
  51#define ATMEL_HLCDC_LAYER_IER                   0xc
  52#define ATMEL_HLCDC_LAYER_IDR                   0x10
  53#define ATMEL_HLCDC_LAYER_IMR                   0x14
  54#define ATMEL_HLCDC_LAYER_ISR                   0x18
  55#define ATMEL_HLCDC_LAYER_DFETCH                BIT(0)
  56#define ATMEL_HLCDC_LAYER_LFETCH                BIT(1)
  57#define ATMEL_HLCDC_LAYER_DMA_IRQ(p)            BIT(2 + (8 * (p)))
  58#define ATMEL_HLCDC_LAYER_DSCR_IRQ(p)           BIT(3 + (8 * (p)))
  59#define ATMEL_HLCDC_LAYER_ADD_IRQ(p)            BIT(4 + (8 * (p)))
  60#define ATMEL_HLCDC_LAYER_DONE_IRQ(p)           BIT(5 + (8 * (p)))
  61#define ATMEL_HLCDC_LAYER_OVR_IRQ(p)            BIT(6 + (8 * (p)))
  62
  63#define ATMEL_HLCDC_LAYER_PLANE_HEAD(p)         (((p) * 0x10) + 0x1c)
  64#define ATMEL_HLCDC_LAYER_PLANE_ADDR(p)         (((p) * 0x10) + 0x20)
  65#define ATMEL_HLCDC_LAYER_PLANE_CTRL(p)         (((p) * 0x10) + 0x24)
  66#define ATMEL_HLCDC_LAYER_PLANE_NEXT(p)         (((p) * 0x10) + 0x28)
  67
  68#define ATMEL_HLCDC_LAYER_DMA_CFG               0
  69#define ATMEL_HLCDC_LAYER_DMA_SIF               BIT(0)
  70#define ATMEL_HLCDC_LAYER_DMA_BLEN_MASK         GENMASK(5, 4)
  71#define ATMEL_HLCDC_LAYER_DMA_BLEN_SINGLE       (0 << 4)
  72#define ATMEL_HLCDC_LAYER_DMA_BLEN_INCR4        (1 << 4)
  73#define ATMEL_HLCDC_LAYER_DMA_BLEN_INCR8        (2 << 4)
  74#define ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16       (3 << 4)
  75#define ATMEL_HLCDC_LAYER_DMA_DLBO              BIT(8)
  76#define ATMEL_HLCDC_LAYER_DMA_ROTDIS            BIT(12)
  77#define ATMEL_HLCDC_LAYER_DMA_LOCKDIS           BIT(13)
  78
  79#define ATMEL_HLCDC_LAYER_FORMAT_CFG            1
  80#define ATMEL_HLCDC_LAYER_RGB                   (0 << 0)
  81#define ATMEL_HLCDC_LAYER_CLUT                  (1 << 0)
  82#define ATMEL_HLCDC_LAYER_YUV                   (2 << 0)
  83#define ATMEL_HLCDC_RGB_MODE(m)                 \
  84        (ATMEL_HLCDC_LAYER_RGB | (((m) & 0xf) << 4))
  85#define ATMEL_HLCDC_CLUT_MODE(m)                \
  86        (ATMEL_HLCDC_LAYER_CLUT | (((m) & 0x3) << 8))
  87#define ATMEL_HLCDC_YUV_MODE(m)                 \
  88        (ATMEL_HLCDC_LAYER_YUV | (((m) & 0xf) << 12))
  89#define ATMEL_HLCDC_YUV422ROT                   BIT(16)
  90#define ATMEL_HLCDC_YUV422SWP                   BIT(17)
  91#define ATMEL_HLCDC_DSCALEOPT                   BIT(20)
  92
  93#define ATMEL_HLCDC_C1_MODE                     ATMEL_HLCDC_CLUT_MODE(0)
  94#define ATMEL_HLCDC_C2_MODE                     ATMEL_HLCDC_CLUT_MODE(1)
  95#define ATMEL_HLCDC_C4_MODE                     ATMEL_HLCDC_CLUT_MODE(2)
  96#define ATMEL_HLCDC_C8_MODE                     ATMEL_HLCDC_CLUT_MODE(3)
  97
  98#define ATMEL_HLCDC_XRGB4444_MODE               ATMEL_HLCDC_RGB_MODE(0)
  99#define ATMEL_HLCDC_ARGB4444_MODE               ATMEL_HLCDC_RGB_MODE(1)
 100#define ATMEL_HLCDC_RGBA4444_MODE               ATMEL_HLCDC_RGB_MODE(2)
 101#define ATMEL_HLCDC_RGB565_MODE                 ATMEL_HLCDC_RGB_MODE(3)
 102#define ATMEL_HLCDC_ARGB1555_MODE               ATMEL_HLCDC_RGB_MODE(4)
 103#define ATMEL_HLCDC_XRGB8888_MODE               ATMEL_HLCDC_RGB_MODE(9)
 104#define ATMEL_HLCDC_RGB888_MODE                 ATMEL_HLCDC_RGB_MODE(10)
 105#define ATMEL_HLCDC_ARGB8888_MODE               ATMEL_HLCDC_RGB_MODE(12)
 106#define ATMEL_HLCDC_RGBA8888_MODE               ATMEL_HLCDC_RGB_MODE(13)
 107
 108#define ATMEL_HLCDC_AYUV_MODE                   ATMEL_HLCDC_YUV_MODE(0)
 109#define ATMEL_HLCDC_YUYV_MODE                   ATMEL_HLCDC_YUV_MODE(1)
 110#define ATMEL_HLCDC_UYVY_MODE                   ATMEL_HLCDC_YUV_MODE(2)
 111#define ATMEL_HLCDC_YVYU_MODE                   ATMEL_HLCDC_YUV_MODE(3)
 112#define ATMEL_HLCDC_VYUY_MODE                   ATMEL_HLCDC_YUV_MODE(4)
 113#define ATMEL_HLCDC_NV61_MODE                   ATMEL_HLCDC_YUV_MODE(5)
 114#define ATMEL_HLCDC_YUV422_MODE                 ATMEL_HLCDC_YUV_MODE(6)
 115#define ATMEL_HLCDC_NV21_MODE                   ATMEL_HLCDC_YUV_MODE(7)
 116#define ATMEL_HLCDC_YUV420_MODE                 ATMEL_HLCDC_YUV_MODE(8)
 117
 118#define ATMEL_HLCDC_LAYER_POS(x, y)             ((x) | ((y) << 16))
 119#define ATMEL_HLCDC_LAYER_SIZE(w, h)            (((w) - 1) | (((h) - 1) << 16))
 120
 121#define ATMEL_HLCDC_LAYER_CRKEY                 BIT(0)
 122#define ATMEL_HLCDC_LAYER_INV                   BIT(1)
 123#define ATMEL_HLCDC_LAYER_ITER2BL               BIT(2)
 124#define ATMEL_HLCDC_LAYER_ITER                  BIT(3)
 125#define ATMEL_HLCDC_LAYER_REVALPHA              BIT(4)
 126#define ATMEL_HLCDC_LAYER_GAEN                  BIT(5)
 127#define ATMEL_HLCDC_LAYER_LAEN                  BIT(6)
 128#define ATMEL_HLCDC_LAYER_OVR                   BIT(7)
 129#define ATMEL_HLCDC_LAYER_DMA                   BIT(8)
 130#define ATMEL_HLCDC_LAYER_REP                   BIT(9)
 131#define ATMEL_HLCDC_LAYER_DSTKEY                BIT(10)
 132#define ATMEL_HLCDC_LAYER_DISCEN                BIT(11)
 133#define ATMEL_HLCDC_LAYER_GA_SHIFT              16
 134#define ATMEL_HLCDC_LAYER_GA_MASK               \
 135        GENMASK(23, ATMEL_HLCDC_LAYER_GA_SHIFT)
 136#define ATMEL_HLCDC_LAYER_GA(x)                 \
 137        ((x) << ATMEL_HLCDC_LAYER_GA_SHIFT)
 138
 139#define ATMEL_HLCDC_LAYER_DISC_POS(x, y)        ((x) | ((y) << 16))
 140#define ATMEL_HLCDC_LAYER_DISC_SIZE(w, h)       (((w) - 1) | (((h) - 1) << 16))
 141
 142#define ATMEL_HLCDC_LAYER_SCALER_FACTORS(x, y)  ((x) | ((y) << 16))
 143#define ATMEL_HLCDC_LAYER_SCALER_ENABLE         BIT(31)
 144
 145#define ATMEL_HLCDC_LAYER_MAX_PLANES            3
 146
 147#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_RESERVED   BIT(0)
 148#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED     BIT(1)
 149#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE       BIT(2)
 150#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN    BIT(3)
 151
 152#define ATMEL_HLCDC_CLUT_SIZE                   256
 153
 154#define ATMEL_HLCDC_MAX_LAYERS                  6
 155
 156/**
 157 * Atmel HLCDC Layer registers layout structure
 158 *
 159 * Each HLCDC layer has its own register organization and a given register
 160 * can be placed differently on 2 different layers depending on its
 161 * capabilities.
 162 * This structure stores common registers layout for a given layer and is
 163 * used by HLCDC layer code to choose the appropriate register to write to
 164 * or to read from.
 165 *
 166 * For all fields, a value of zero means "unsupported".
 167 *
 168 * See Atmel's datasheet for a detailled description of these registers.
 169 *
 170 * @xstride: xstride registers
 171 * @pstride: pstride registers
 172 * @pos: position register
 173 * @size: displayed size register
 174 * @memsize: memory size register
 175 * @default_color: default color register
 176 * @chroma_key: chroma key register
 177 * @chroma_key_mask: chroma key mask register
 178 * @general_config: general layer config register
 179 * @sacler_config: scaler factors register
 180 * @phicoeffs: X/Y PHI coefficient registers
 181 * @disc_pos: discard area position register
 182 * @disc_size: discard area size register
 183 * @csc: color space conversion register
 184 */
 185struct atmel_hlcdc_layer_cfg_layout {
 186        int xstride[ATMEL_HLCDC_LAYER_MAX_PLANES];
 187        int pstride[ATMEL_HLCDC_LAYER_MAX_PLANES];
 188        int pos;
 189        int size;
 190        int memsize;
 191        int default_color;
 192        int chroma_key;
 193        int chroma_key_mask;
 194        int general_config;
 195        int scaler_config;
 196        struct {
 197                int x;
 198                int y;
 199        } phicoeffs;
 200        int disc_pos;
 201        int disc_size;
 202        int csc;
 203};
 204
 205/**
 206 * Atmel HLCDC DMA descriptor structure
 207 *
 208 * This structure is used by the HLCDC DMA engine to schedule a DMA transfer.
 209 *
 210 * The structure fields must remain in this specific order, because they're
 211 * used by the HLCDC DMA engine, which expect them in this order.
 212 * HLCDC DMA descriptors must be aligned on 64 bits.
 213 *
 214 * @addr: buffer DMA address
 215 * @ctrl: DMA transfer options
 216 * @next: next DMA descriptor to fetch
 217 * @self: descriptor DMA address
 218 */
 219struct atmel_hlcdc_dma_channel_dscr {
 220        dma_addr_t addr;
 221        u32 ctrl;
 222        dma_addr_t next;
 223        dma_addr_t self;
 224} __aligned(sizeof(u64));
 225
 226/**
 227 * Atmel HLCDC layer types
 228 */
 229enum atmel_hlcdc_layer_type {
 230        ATMEL_HLCDC_NO_LAYER,
 231        ATMEL_HLCDC_BASE_LAYER,
 232        ATMEL_HLCDC_OVERLAY_LAYER,
 233        ATMEL_HLCDC_CURSOR_LAYER,
 234        ATMEL_HLCDC_PP_LAYER,
 235};
 236
 237/**
 238 * Atmel HLCDC Supported formats structure
 239 *
 240 * This structure list all the formats supported by a given layer.
 241 *
 242 * @nformats: number of supported formats
 243 * @formats: supported formats
 244 */
 245struct atmel_hlcdc_formats {
 246        int nformats;
 247        u32 *formats;
 248};
 249
 250/**
 251 * Atmel HLCDC Layer description structure
 252 *
 253 * This structure describes the capabilities provided by a given layer.
 254 *
 255 * @name: layer name
 256 * @type: layer type
 257 * @id: layer id
 258 * @regs_offset: offset of the layer registers from the HLCDC registers base
 259 * @cfgs_offset: CFGX registers offset from the layer registers base
 260 * @formats: supported formats
 261 * @layout: config registers layout
 262 * @max_width: maximum width supported by this layer (0 means unlimited)
 263 * @max_height: maximum height supported by this layer (0 means unlimited)
 264 */
 265struct atmel_hlcdc_layer_desc {
 266        const char *name;
 267        enum atmel_hlcdc_layer_type type;
 268        int id;
 269        int regs_offset;
 270        int cfgs_offset;
 271        int clut_offset;
 272        struct atmel_hlcdc_formats *formats;
 273        struct atmel_hlcdc_layer_cfg_layout layout;
 274        int max_width;
 275        int max_height;
 276};
 277
 278/**
 279 * Atmel HLCDC Layer.
 280 *
 281 * A layer can be a DRM plane of a post processing layer used to render
 282 * HLCDC composition into memory.
 283 *
 284 * @desc: layer description
 285 * @regmap: pointer to the HLCDC regmap
 286 */
 287struct atmel_hlcdc_layer {
 288        const struct atmel_hlcdc_layer_desc *desc;
 289        struct regmap *regmap;
 290};
 291
 292/**
 293 * Atmel HLCDC Plane.
 294 *
 295 * @base: base DRM plane structure
 296 * @layer: HLCDC layer structure
 297 * @properties: pointer to the property definitions structure
 298 */
 299struct atmel_hlcdc_plane {
 300        struct drm_plane base;
 301        struct atmel_hlcdc_layer layer;
 302        struct atmel_hlcdc_plane_properties *properties;
 303};
 304
 305static inline struct atmel_hlcdc_plane *
 306drm_plane_to_atmel_hlcdc_plane(struct drm_plane *p)
 307{
 308        return container_of(p, struct atmel_hlcdc_plane, base);
 309}
 310
 311static inline struct atmel_hlcdc_plane *
 312atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
 313{
 314        return container_of(layer, struct atmel_hlcdc_plane, layer);
 315}
 316
 317/**
 318 * Atmel HLCDC Display Controller description structure.
 319 *
 320 * This structure describes the HLCDC IP capabilities and depends on the
 321 * HLCDC IP version (or Atmel SoC family).
 322 *
 323 * @min_width: minimum width supported by the Display Controller
 324 * @min_height: minimum height supported by the Display Controller
 325 * @max_width: maximum width supported by the Display Controller
 326 * @max_height: maximum height supported by the Display Controller
 327 * @max_spw: maximum vertical/horizontal pulse width
 328 * @max_vpw: maximum vertical back/front porch width
 329 * @max_hpw: maximum horizontal back/front porch width
 330 * @conflicting_output_formats: true if RGBXXX output formats conflict with
 331 *                              each other.
 332 * @layers: a layer description table describing available layers
 333 * @nlayers: layer description table size
 334 */
 335struct atmel_hlcdc_dc_desc {
 336        int min_width;
 337        int min_height;
 338        int max_width;
 339        int max_height;
 340        int max_spw;
 341        int max_vpw;
 342        int max_hpw;
 343        bool conflicting_output_formats;
 344        const struct atmel_hlcdc_layer_desc *layers;
 345        int nlayers;
 346};
 347
 348/**
 349 * Atmel HLCDC Plane properties.
 350 *
 351 * This structure stores plane property definitions.
 352 *
 353 * @alpha: alpha blending (or transparency) property
 354 * @rotation: rotation property
 355 */
 356struct atmel_hlcdc_plane_properties {
 357        struct drm_property *alpha;
 358};
 359
 360/**
 361 * Atmel HLCDC Display Controller.
 362 *
 363 * @desc: HLCDC Display Controller description
 364 * @dscrpool: DMA coherent pool used to allocate DMA descriptors
 365 * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
 366 * @fbdev: framebuffer device attached to the Display Controller
 367 * @crtc: CRTC provided by the display controller
 368 * @planes: instantiated planes
 369 * @layers: active HLCDC layers
 370 * @wq: display controller workqueue
 371 * @suspend: used to store the HLCDC state when entering suspend
 372 * @commit: used for async commit handling
 373 */
 374struct atmel_hlcdc_dc {
 375        const struct atmel_hlcdc_dc_desc *desc;
 376        struct dma_pool *dscrpool;
 377        struct atmel_hlcdc *hlcdc;
 378        struct drm_crtc *crtc;
 379        struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
 380        struct workqueue_struct *wq;
 381        struct {
 382                u32 imr;
 383                struct drm_atomic_state *state;
 384        } suspend;
 385        struct {
 386                wait_queue_head_t wait;
 387                bool pending;
 388        } commit;
 389};
 390
 391extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats;
 392extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats;
 393
 394static inline void atmel_hlcdc_layer_write_reg(struct atmel_hlcdc_layer *layer,
 395                                               unsigned int reg, u32 val)
 396{
 397        regmap_write(layer->regmap, layer->desc->regs_offset + reg, val);
 398}
 399
 400static inline u32 atmel_hlcdc_layer_read_reg(struct atmel_hlcdc_layer *layer,
 401                                             unsigned int reg)
 402{
 403        u32 val;
 404
 405        regmap_read(layer->regmap, layer->desc->regs_offset + reg, &val);
 406
 407        return val;
 408}
 409
 410static inline void atmel_hlcdc_layer_write_cfg(struct atmel_hlcdc_layer *layer,
 411                                               unsigned int cfgid, u32 val)
 412{
 413        atmel_hlcdc_layer_write_reg(layer,
 414                                    layer->desc->cfgs_offset +
 415                                    (cfgid * sizeof(u32)), val);
 416}
 417
 418static inline u32 atmel_hlcdc_layer_read_cfg(struct atmel_hlcdc_layer *layer,
 419                                             unsigned int cfgid)
 420{
 421        return atmel_hlcdc_layer_read_reg(layer,
 422                                          layer->desc->cfgs_offset +
 423                                          (cfgid * sizeof(u32)));
 424}
 425
 426static inline void atmel_hlcdc_layer_write_clut(struct atmel_hlcdc_layer *layer,
 427                                                unsigned int c, u32 val)
 428{
 429        regmap_write(layer->regmap,
 430                     layer->desc->clut_offset + c * sizeof(u32),
 431                     val);
 432}
 433
 434static inline void atmel_hlcdc_layer_init(struct atmel_hlcdc_layer *layer,
 435                                const struct atmel_hlcdc_layer_desc *desc,
 436                                struct regmap *regmap)
 437{
 438        layer->desc = desc;
 439        layer->regmap = regmap;
 440}
 441
 442enum drm_mode_status
 443atmel_hlcdc_dc_mode_valid(struct atmel_hlcdc_dc *dc,
 444                          const struct drm_display_mode *mode);
 445
 446int atmel_hlcdc_create_planes(struct drm_device *dev);
 447void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane);
 448
 449int atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state);
 450int atmel_hlcdc_plane_prepare_ahb_routing(struct drm_crtc_state *c_state);
 451
 452void atmel_hlcdc_crtc_irq(struct drm_crtc *c);
 453
 454int atmel_hlcdc_crtc_create(struct drm_device *dev);
 455
 456int atmel_hlcdc_create_outputs(struct drm_device *dev);
 457
 458#endif /* DRM_ATMEL_HLCDC_H */
 459