root/drivers/gpu/drm/meson/meson_crtc.c

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

DEFINITIONS

This source file includes following definitions.
  1. meson_crtc_enable_vblank
  2. meson_crtc_disable_vblank
  3. meson_g12a_crtc_atomic_enable
  4. meson_crtc_atomic_enable
  5. meson_g12a_crtc_atomic_disable
  6. meson_crtc_atomic_disable
  7. meson_crtc_atomic_begin
  8. meson_crtc_atomic_flush
  9. meson_crtc_enable_osd1
  10. meson_g12a_crtc_enable_osd1
  11. meson_crtc_enable_vd1
  12. meson_g12a_crtc_enable_vd1
  13. meson_crtc_irq
  14. meson_crtc_create

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2016 BayLibre, SAS
   4  * Author: Neil Armstrong <narmstrong@baylibre.com>
   5  * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
   6  * Copyright (C) 2014 Endless Mobile
   7  *
   8  * Written by:
   9  *     Jasper St. Pierre <jstpierre@mecheye.net>
  10  */
  11 
  12 #include <linux/bitfield.h>
  13 #include <linux/soc/amlogic/meson-canvas.h>
  14 
  15 #include <drm/drm_atomic_helper.h>
  16 #include <drm/drm_device.h>
  17 #include <drm/drm_print.h>
  18 #include <drm/drm_probe_helper.h>
  19 #include <drm/drm_vblank.h>
  20 
  21 #include "meson_crtc.h"
  22 #include "meson_plane.h"
  23 #include "meson_registers.h"
  24 #include "meson_venc.h"
  25 #include "meson_viu.h"
  26 #include "meson_vpp.h"
  27 
  28 #define MESON_G12A_VIU_OFFSET   0x5ec0
  29 
  30 /* CRTC definition */
  31 
  32 struct meson_crtc {
  33         struct drm_crtc base;
  34         struct drm_pending_vblank_event *event;
  35         struct meson_drm *priv;
  36         void (*enable_osd1)(struct meson_drm *priv);
  37         void (*enable_vd1)(struct meson_drm *priv);
  38         unsigned int viu_offset;
  39 };
  40 #define to_meson_crtc(x) container_of(x, struct meson_crtc, base)
  41 
  42 /* CRTC */
  43 
  44 static int meson_crtc_enable_vblank(struct drm_crtc *crtc)
  45 {
  46         struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
  47         struct meson_drm *priv = meson_crtc->priv;
  48 
  49         meson_venc_enable_vsync(priv);
  50 
  51         return 0;
  52 }
  53 
  54 static void meson_crtc_disable_vblank(struct drm_crtc *crtc)
  55 {
  56         struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
  57         struct meson_drm *priv = meson_crtc->priv;
  58 
  59         meson_venc_disable_vsync(priv);
  60 }
  61 
  62 static const struct drm_crtc_funcs meson_crtc_funcs = {
  63         .atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
  64         .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
  65         .destroy                = drm_crtc_cleanup,
  66         .page_flip              = drm_atomic_helper_page_flip,
  67         .reset                  = drm_atomic_helper_crtc_reset,
  68         .set_config             = drm_atomic_helper_set_config,
  69         .enable_vblank          = meson_crtc_enable_vblank,
  70         .disable_vblank         = meson_crtc_disable_vblank,
  71 
  72 };
  73 
  74 static void meson_g12a_crtc_atomic_enable(struct drm_crtc *crtc,
  75                                           struct drm_crtc_state *old_state)
  76 {
  77         struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
  78         struct drm_crtc_state *crtc_state = crtc->state;
  79         struct meson_drm *priv = meson_crtc->priv;
  80 
  81         DRM_DEBUG_DRIVER("\n");
  82 
  83         if (!crtc_state) {
  84                 DRM_ERROR("Invalid crtc_state\n");
  85                 return;
  86         }
  87 
  88         /* VD1 Preblend vertical start/end */
  89         writel(FIELD_PREP(GENMASK(11, 0), 2303),
  90                priv->io_base + _REG(VPP_PREBLEND_VD1_V_START_END));
  91 
  92         /* Setup Blender */
  93         writel(crtc_state->mode.hdisplay |
  94                crtc_state->mode.vdisplay << 16,
  95                priv->io_base + _REG(VPP_POSTBLEND_H_SIZE));
  96 
  97         writel_relaxed(0 << 16 |
  98                         (crtc_state->mode.hdisplay - 1),
  99                         priv->io_base + _REG(VPP_OSD1_BLD_H_SCOPE));
 100         writel_relaxed(0 << 16 |
 101                         (crtc_state->mode.vdisplay - 1),
 102                         priv->io_base + _REG(VPP_OSD1_BLD_V_SCOPE));
 103         writel_relaxed(crtc_state->mode.hdisplay << 16 |
 104                         crtc_state->mode.vdisplay,
 105                         priv->io_base + _REG(VPP_OUT_H_V_SIZE));
 106 
 107         drm_crtc_vblank_on(crtc);
 108 }
 109 
 110 static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
 111                                      struct drm_crtc_state *old_state)
 112 {
 113         struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
 114         struct drm_crtc_state *crtc_state = crtc->state;
 115         struct meson_drm *priv = meson_crtc->priv;
 116 
 117         DRM_DEBUG_DRIVER("\n");
 118 
 119         if (!crtc_state) {
 120                 DRM_ERROR("Invalid crtc_state\n");
 121                 return;
 122         }
 123 
 124         /* Enable VPP Postblend */
 125         writel(crtc_state->mode.hdisplay,
 126                priv->io_base + _REG(VPP_POSTBLEND_H_SIZE));
 127 
 128         /* VD1 Preblend vertical start/end */
 129         writel(FIELD_PREP(GENMASK(11, 0), 2303),
 130                         priv->io_base + _REG(VPP_PREBLEND_VD1_V_START_END));
 131 
 132         writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE,
 133                             priv->io_base + _REG(VPP_MISC));
 134 
 135         drm_crtc_vblank_on(crtc);
 136 }
 137 
 138 static void meson_g12a_crtc_atomic_disable(struct drm_crtc *crtc,
 139                                            struct drm_crtc_state *old_state)
 140 {
 141         struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
 142         struct meson_drm *priv = meson_crtc->priv;
 143 
 144         DRM_DEBUG_DRIVER("\n");
 145 
 146         drm_crtc_vblank_off(crtc);
 147 
 148         priv->viu.osd1_enabled = false;
 149         priv->viu.osd1_commit = false;
 150 
 151         priv->viu.vd1_enabled = false;
 152         priv->viu.vd1_commit = false;
 153 
 154         if (crtc->state->event && !crtc->state->active) {
 155                 spin_lock_irq(&crtc->dev->event_lock);
 156                 drm_crtc_send_vblank_event(crtc, crtc->state->event);
 157                 spin_unlock_irq(&crtc->dev->event_lock);
 158 
 159                 crtc->state->event = NULL;
 160         }
 161 }
 162 
 163 static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
 164                                       struct drm_crtc_state *old_state)
 165 {
 166         struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
 167         struct meson_drm *priv = meson_crtc->priv;
 168 
 169         DRM_DEBUG_DRIVER("\n");
 170 
 171         drm_crtc_vblank_off(crtc);
 172 
 173         priv->viu.osd1_enabled = false;
 174         priv->viu.osd1_commit = false;
 175 
 176         priv->viu.vd1_enabled = false;
 177         priv->viu.vd1_commit = false;
 178 
 179         /* Disable VPP Postblend */
 180         writel_bits_relaxed(VPP_OSD1_POSTBLEND | VPP_VD1_POSTBLEND |
 181                             VPP_VD1_PREBLEND | VPP_POSTBLEND_ENABLE, 0,
 182                             priv->io_base + _REG(VPP_MISC));
 183 
 184         if (crtc->state->event && !crtc->state->active) {
 185                 spin_lock_irq(&crtc->dev->event_lock);
 186                 drm_crtc_send_vblank_event(crtc, crtc->state->event);
 187                 spin_unlock_irq(&crtc->dev->event_lock);
 188 
 189                 crtc->state->event = NULL;
 190         }
 191 }
 192 
 193 static void meson_crtc_atomic_begin(struct drm_crtc *crtc,
 194                                     struct drm_crtc_state *state)
 195 {
 196         struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
 197         unsigned long flags;
 198 
 199         if (crtc->state->event) {
 200                 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 201 
 202                 spin_lock_irqsave(&crtc->dev->event_lock, flags);
 203                 meson_crtc->event = crtc->state->event;
 204                 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 205                 crtc->state->event = NULL;
 206         }
 207 }
 208 
 209 static void meson_crtc_atomic_flush(struct drm_crtc *crtc,
 210                                     struct drm_crtc_state *old_crtc_state)
 211 {
 212         struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
 213         struct meson_drm *priv = meson_crtc->priv;
 214 
 215         priv->viu.osd1_commit = true;
 216         priv->viu.vd1_commit = true;
 217 }
 218 
 219 static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = {
 220         .atomic_begin   = meson_crtc_atomic_begin,
 221         .atomic_flush   = meson_crtc_atomic_flush,
 222         .atomic_enable  = meson_crtc_atomic_enable,
 223         .atomic_disable = meson_crtc_atomic_disable,
 224 };
 225 
 226 static const struct drm_crtc_helper_funcs meson_g12a_crtc_helper_funcs = {
 227         .atomic_begin   = meson_crtc_atomic_begin,
 228         .atomic_flush   = meson_crtc_atomic_flush,
 229         .atomic_enable  = meson_g12a_crtc_atomic_enable,
 230         .atomic_disable = meson_g12a_crtc_atomic_disable,
 231 };
 232 
 233 static void meson_crtc_enable_osd1(struct meson_drm *priv)
 234 {
 235         writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
 236                             priv->io_base + _REG(VPP_MISC));
 237 }
 238 
 239 static void meson_g12a_crtc_enable_osd1(struct meson_drm *priv)
 240 {
 241         writel_relaxed(priv->viu.osd_blend_din0_scope_h,
 242                        priv->io_base +
 243                        _REG(VIU_OSD_BLEND_DIN0_SCOPE_H));
 244         writel_relaxed(priv->viu.osd_blend_din0_scope_v,
 245                        priv->io_base +
 246                        _REG(VIU_OSD_BLEND_DIN0_SCOPE_V));
 247         writel_relaxed(priv->viu.osb_blend0_size,
 248                        priv->io_base +
 249                        _REG(VIU_OSD_BLEND_BLEND0_SIZE));
 250         writel_relaxed(priv->viu.osb_blend1_size,
 251                        priv->io_base +
 252                        _REG(VIU_OSD_BLEND_BLEND1_SIZE));
 253         writel_bits_relaxed(3 << 8, 3 << 8,
 254                             priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
 255 }
 256 
 257 static void meson_crtc_enable_vd1(struct meson_drm *priv)
 258 {
 259         writel_bits_relaxed(VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND |
 260                             VPP_COLOR_MNG_ENABLE,
 261                             VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND |
 262                             VPP_COLOR_MNG_ENABLE,
 263                             priv->io_base + _REG(VPP_MISC));
 264 }
 265 
 266 static void meson_g12a_crtc_enable_vd1(struct meson_drm *priv)
 267 {
 268         writel_relaxed(VD_BLEND_PREBLD_SRC_VD1 |
 269                        VD_BLEND_PREBLD_PREMULT_EN |
 270                        VD_BLEND_POSTBLD_SRC_VD1 |
 271                        VD_BLEND_POSTBLD_PREMULT_EN,
 272                        priv->io_base + _REG(VD1_BLEND_SRC_CTRL));
 273 }
 274 
 275 void meson_crtc_irq(struct meson_drm *priv)
 276 {
 277         struct meson_crtc *meson_crtc = to_meson_crtc(priv->crtc);
 278         unsigned long flags;
 279 
 280         /* Update the OSD registers */
 281         if (priv->viu.osd1_enabled && priv->viu.osd1_commit) {
 282                 writel_relaxed(priv->viu.osd1_ctrl_stat,
 283                                 priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
 284                 writel_relaxed(priv->viu.osd1_blk0_cfg[0],
 285                                 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W0));
 286                 writel_relaxed(priv->viu.osd1_blk0_cfg[1],
 287                                 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W1));
 288                 writel_relaxed(priv->viu.osd1_blk0_cfg[2],
 289                                 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W2));
 290                 writel_relaxed(priv->viu.osd1_blk0_cfg[3],
 291                                 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W3));
 292                 writel_relaxed(priv->viu.osd1_blk0_cfg[4],
 293                                 priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W4));
 294                 writel_relaxed(priv->viu.osd_sc_ctrl0,
 295                                 priv->io_base + _REG(VPP_OSD_SC_CTRL0));
 296                 writel_relaxed(priv->viu.osd_sc_i_wh_m1,
 297                                 priv->io_base + _REG(VPP_OSD_SCI_WH_M1));
 298                 writel_relaxed(priv->viu.osd_sc_o_h_start_end,
 299                                 priv->io_base + _REG(VPP_OSD_SCO_H_START_END));
 300                 writel_relaxed(priv->viu.osd_sc_o_v_start_end,
 301                                 priv->io_base + _REG(VPP_OSD_SCO_V_START_END));
 302                 writel_relaxed(priv->viu.osd_sc_v_ini_phase,
 303                                 priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));
 304                 writel_relaxed(priv->viu.osd_sc_v_phase_step,
 305                                 priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));
 306                 writel_relaxed(priv->viu.osd_sc_h_ini_phase,
 307                                 priv->io_base + _REG(VPP_OSD_HSC_INI_PHASE));
 308                 writel_relaxed(priv->viu.osd_sc_h_phase_step,
 309                                 priv->io_base + _REG(VPP_OSD_HSC_PHASE_STEP));
 310                 writel_relaxed(priv->viu.osd_sc_h_ctrl0,
 311                                 priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
 312                 writel_relaxed(priv->viu.osd_sc_v_ctrl0,
 313                                 priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
 314 
 315                 meson_canvas_config(priv->canvas, priv->canvas_id_osd1,
 316                                 priv->viu.osd1_addr, priv->viu.osd1_stride,
 317                                 priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
 318                                 MESON_CANVAS_BLKMODE_LINEAR, 0);
 319 
 320                 /* Enable OSD1 */
 321                 if (meson_crtc->enable_osd1)
 322                         meson_crtc->enable_osd1(priv);
 323 
 324                 priv->viu.osd1_commit = false;
 325         }
 326 
 327         /* Update the VD1 registers */
 328         if (priv->viu.vd1_enabled && priv->viu.vd1_commit) {
 329 
 330                 switch (priv->viu.vd1_planes) {
 331                 case 3:
 332                         meson_canvas_config(priv->canvas,
 333                                             priv->canvas_id_vd1_2,
 334                                             priv->viu.vd1_addr2,
 335                                             priv->viu.vd1_stride2,
 336                                             priv->viu.vd1_height2,
 337                                             MESON_CANVAS_WRAP_NONE,
 338                                             MESON_CANVAS_BLKMODE_LINEAR,
 339                                             MESON_CANVAS_ENDIAN_SWAP64);
 340                 /* fallthrough */
 341                 case 2:
 342                         meson_canvas_config(priv->canvas,
 343                                             priv->canvas_id_vd1_1,
 344                                             priv->viu.vd1_addr1,
 345                                             priv->viu.vd1_stride1,
 346                                             priv->viu.vd1_height1,
 347                                             MESON_CANVAS_WRAP_NONE,
 348                                             MESON_CANVAS_BLKMODE_LINEAR,
 349                                             MESON_CANVAS_ENDIAN_SWAP64);
 350                 /* fallthrough */
 351                 case 1:
 352                         meson_canvas_config(priv->canvas,
 353                                             priv->canvas_id_vd1_0,
 354                                             priv->viu.vd1_addr0,
 355                                             priv->viu.vd1_stride0,
 356                                             priv->viu.vd1_height0,
 357                                             MESON_CANVAS_WRAP_NONE,
 358                                             MESON_CANVAS_BLKMODE_LINEAR,
 359                                             MESON_CANVAS_ENDIAN_SWAP64);
 360                 };
 361 
 362                 writel_relaxed(priv->viu.vd1_if0_gen_reg,
 363                                 priv->io_base + meson_crtc->viu_offset +
 364                                 _REG(VD1_IF0_GEN_REG));
 365                 writel_relaxed(priv->viu.vd1_if0_gen_reg,
 366                                 priv->io_base + meson_crtc->viu_offset +
 367                                 _REG(VD2_IF0_GEN_REG));
 368                 writel_relaxed(priv->viu.vd1_if0_gen_reg2,
 369                                 priv->io_base + meson_crtc->viu_offset +
 370                                 _REG(VD1_IF0_GEN_REG2));
 371                 writel_relaxed(priv->viu.viu_vd1_fmt_ctrl,
 372                                 priv->io_base + meson_crtc->viu_offset +
 373                                 _REG(VIU_VD1_FMT_CTRL));
 374                 writel_relaxed(priv->viu.viu_vd1_fmt_ctrl,
 375                                 priv->io_base + meson_crtc->viu_offset +
 376                                 _REG(VIU_VD2_FMT_CTRL));
 377                 writel_relaxed(priv->viu.viu_vd1_fmt_w,
 378                                 priv->io_base + meson_crtc->viu_offset +
 379                                 _REG(VIU_VD1_FMT_W));
 380                 writel_relaxed(priv->viu.viu_vd1_fmt_w,
 381                                 priv->io_base + meson_crtc->viu_offset +
 382                                 _REG(VIU_VD2_FMT_W));
 383                 writel_relaxed(priv->viu.vd1_if0_canvas0,
 384                                 priv->io_base + meson_crtc->viu_offset +
 385                                 _REG(VD1_IF0_CANVAS0));
 386                 writel_relaxed(priv->viu.vd1_if0_canvas0,
 387                                 priv->io_base + meson_crtc->viu_offset +
 388                                 _REG(VD1_IF0_CANVAS1));
 389                 writel_relaxed(priv->viu.vd1_if0_canvas0,
 390                                 priv->io_base + meson_crtc->viu_offset +
 391                                 _REG(VD2_IF0_CANVAS0));
 392                 writel_relaxed(priv->viu.vd1_if0_canvas0,
 393                                 priv->io_base + meson_crtc->viu_offset +
 394                                 _REG(VD2_IF0_CANVAS1));
 395                 writel_relaxed(priv->viu.vd1_if0_luma_x0,
 396                                 priv->io_base + meson_crtc->viu_offset +
 397                                 _REG(VD1_IF0_LUMA_X0));
 398                 writel_relaxed(priv->viu.vd1_if0_luma_x0,
 399                                 priv->io_base + meson_crtc->viu_offset +
 400                                 _REG(VD1_IF0_LUMA_X1));
 401                 writel_relaxed(priv->viu.vd1_if0_luma_x0,
 402                                 priv->io_base + meson_crtc->viu_offset +
 403                                 _REG(VD2_IF0_LUMA_X0));
 404                 writel_relaxed(priv->viu.vd1_if0_luma_x0,
 405                                 priv->io_base + meson_crtc->viu_offset +
 406                                 _REG(VD2_IF0_LUMA_X1));
 407                 writel_relaxed(priv->viu.vd1_if0_luma_y0,
 408                                 priv->io_base + meson_crtc->viu_offset +
 409                                 _REG(VD1_IF0_LUMA_Y0));
 410                 writel_relaxed(priv->viu.vd1_if0_luma_y0,
 411                                 priv->io_base + meson_crtc->viu_offset +
 412                                 _REG(VD1_IF0_LUMA_Y1));
 413                 writel_relaxed(priv->viu.vd1_if0_luma_y0,
 414                                 priv->io_base + meson_crtc->viu_offset +
 415                                 _REG(VD2_IF0_LUMA_Y0));
 416                 writel_relaxed(priv->viu.vd1_if0_luma_y0,
 417                                 priv->io_base + meson_crtc->viu_offset +
 418                                 _REG(VD2_IF0_LUMA_Y1));
 419                 writel_relaxed(priv->viu.vd1_if0_chroma_x0,
 420                                 priv->io_base + meson_crtc->viu_offset +
 421                                 _REG(VD1_IF0_CHROMA_X0));
 422                 writel_relaxed(priv->viu.vd1_if0_chroma_x0,
 423                                 priv->io_base + meson_crtc->viu_offset +
 424                                 _REG(VD1_IF0_CHROMA_X1));
 425                 writel_relaxed(priv->viu.vd1_if0_chroma_x0,
 426                                 priv->io_base + meson_crtc->viu_offset +
 427                                 _REG(VD2_IF0_CHROMA_X0));
 428                 writel_relaxed(priv->viu.vd1_if0_chroma_x0,
 429                                 priv->io_base + meson_crtc->viu_offset +
 430                                 _REG(VD2_IF0_CHROMA_X1));
 431                 writel_relaxed(priv->viu.vd1_if0_chroma_y0,
 432                                 priv->io_base + meson_crtc->viu_offset +
 433                                 _REG(VD1_IF0_CHROMA_Y0));
 434                 writel_relaxed(priv->viu.vd1_if0_chroma_y0,
 435                                 priv->io_base + meson_crtc->viu_offset +
 436                                 _REG(VD1_IF0_CHROMA_Y1));
 437                 writel_relaxed(priv->viu.vd1_if0_chroma_y0,
 438                                 priv->io_base + meson_crtc->viu_offset +
 439                                 _REG(VD2_IF0_CHROMA_Y0));
 440                 writel_relaxed(priv->viu.vd1_if0_chroma_y0,
 441                                 priv->io_base + meson_crtc->viu_offset +
 442                                 _REG(VD2_IF0_CHROMA_Y1));
 443                 writel_relaxed(priv->viu.vd1_if0_repeat_loop,
 444                                 priv->io_base + meson_crtc->viu_offset +
 445                                 _REG(VD1_IF0_RPT_LOOP));
 446                 writel_relaxed(priv->viu.vd1_if0_repeat_loop,
 447                                 priv->io_base + meson_crtc->viu_offset +
 448                                 _REG(VD2_IF0_RPT_LOOP));
 449                 writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat,
 450                                 priv->io_base + meson_crtc->viu_offset +
 451                                 _REG(VD1_IF0_LUMA0_RPT_PAT));
 452                 writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat,
 453                                 priv->io_base + meson_crtc->viu_offset +
 454                                 _REG(VD2_IF0_LUMA0_RPT_PAT));
 455                 writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat,
 456                                 priv->io_base + meson_crtc->viu_offset +
 457                                 _REG(VD1_IF0_LUMA1_RPT_PAT));
 458                 writel_relaxed(priv->viu.vd1_if0_luma0_rpt_pat,
 459                                 priv->io_base + meson_crtc->viu_offset +
 460                                 _REG(VD2_IF0_LUMA1_RPT_PAT));
 461                 writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat,
 462                                 priv->io_base + meson_crtc->viu_offset +
 463                                 _REG(VD1_IF0_CHROMA0_RPT_PAT));
 464                 writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat,
 465                                 priv->io_base + meson_crtc->viu_offset +
 466                                 _REG(VD2_IF0_CHROMA0_RPT_PAT));
 467                 writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat,
 468                                 priv->io_base + meson_crtc->viu_offset +
 469                                 _REG(VD1_IF0_CHROMA1_RPT_PAT));
 470                 writel_relaxed(priv->viu.vd1_if0_chroma0_rpt_pat,
 471                                 priv->io_base + meson_crtc->viu_offset +
 472                                 _REG(VD2_IF0_CHROMA1_RPT_PAT));
 473                 writel_relaxed(0, priv->io_base + meson_crtc->viu_offset +
 474                                 _REG(VD1_IF0_LUMA_PSEL));
 475                 writel_relaxed(0, priv->io_base + meson_crtc->viu_offset +
 476                                 _REG(VD1_IF0_CHROMA_PSEL));
 477                 writel_relaxed(0, priv->io_base + meson_crtc->viu_offset +
 478                                 _REG(VD2_IF0_LUMA_PSEL));
 479                 writel_relaxed(0, priv->io_base + meson_crtc->viu_offset +
 480                                 _REG(VD2_IF0_CHROMA_PSEL));
 481                 writel_relaxed(priv->viu.vd1_range_map_y,
 482                                 priv->io_base + meson_crtc->viu_offset +
 483                                 _REG(VD1_IF0_RANGE_MAP_Y));
 484                 writel_relaxed(priv->viu.vd1_range_map_cb,
 485                                 priv->io_base + meson_crtc->viu_offset +
 486                                 _REG(VD1_IF0_RANGE_MAP_CB));
 487                 writel_relaxed(priv->viu.vd1_range_map_cr,
 488                                 priv->io_base + meson_crtc->viu_offset +
 489                                 _REG(VD1_IF0_RANGE_MAP_CR));
 490                 writel_relaxed(VPP_VSC_BANK_LENGTH(4) |
 491                                VPP_HSC_BANK_LENGTH(4) |
 492                                VPP_SC_VD_EN_ENABLE |
 493                                VPP_SC_TOP_EN_ENABLE |
 494                                VPP_SC_HSC_EN_ENABLE |
 495                                VPP_SC_VSC_EN_ENABLE,
 496                                 priv->io_base + _REG(VPP_SC_MISC));
 497                 writel_relaxed(priv->viu.vpp_pic_in_height,
 498                                 priv->io_base + _REG(VPP_PIC_IN_HEIGHT));
 499                 writel_relaxed(priv->viu.vpp_postblend_vd1_h_start_end,
 500                         priv->io_base + _REG(VPP_POSTBLEND_VD1_H_START_END));
 501                 writel_relaxed(priv->viu.vpp_blend_vd2_h_start_end,
 502                         priv->io_base + _REG(VPP_BLEND_VD2_H_START_END));
 503                 writel_relaxed(priv->viu.vpp_postblend_vd1_v_start_end,
 504                         priv->io_base + _REG(VPP_POSTBLEND_VD1_V_START_END));
 505                 writel_relaxed(priv->viu.vpp_blend_vd2_v_start_end,
 506                         priv->io_base + _REG(VPP_BLEND_VD2_V_START_END));
 507                 writel_relaxed(priv->viu.vpp_hsc_region12_startp,
 508                                 priv->io_base + _REG(VPP_HSC_REGION12_STARTP));
 509                 writel_relaxed(priv->viu.vpp_hsc_region34_startp,
 510                                 priv->io_base + _REG(VPP_HSC_REGION34_STARTP));
 511                 writel_relaxed(priv->viu.vpp_hsc_region4_endp,
 512                                 priv->io_base + _REG(VPP_HSC_REGION4_ENDP));
 513                 writel_relaxed(priv->viu.vpp_hsc_start_phase_step,
 514                                 priv->io_base + _REG(VPP_HSC_START_PHASE_STEP));
 515                 writel_relaxed(priv->viu.vpp_hsc_region1_phase_slope,
 516                         priv->io_base + _REG(VPP_HSC_REGION1_PHASE_SLOPE));
 517                 writel_relaxed(priv->viu.vpp_hsc_region3_phase_slope,
 518                         priv->io_base + _REG(VPP_HSC_REGION3_PHASE_SLOPE));
 519                 writel_relaxed(priv->viu.vpp_line_in_length,
 520                                 priv->io_base + _REG(VPP_LINE_IN_LENGTH));
 521                 writel_relaxed(priv->viu.vpp_preblend_h_size,
 522                                 priv->io_base + _REG(VPP_PREBLEND_H_SIZE));
 523                 writel_relaxed(priv->viu.vpp_vsc_region12_startp,
 524                                 priv->io_base + _REG(VPP_VSC_REGION12_STARTP));
 525                 writel_relaxed(priv->viu.vpp_vsc_region34_startp,
 526                                 priv->io_base + _REG(VPP_VSC_REGION34_STARTP));
 527                 writel_relaxed(priv->viu.vpp_vsc_region4_endp,
 528                                 priv->io_base + _REG(VPP_VSC_REGION4_ENDP));
 529                 writel_relaxed(priv->viu.vpp_vsc_start_phase_step,
 530                                 priv->io_base + _REG(VPP_VSC_START_PHASE_STEP));
 531                 writel_relaxed(priv->viu.vpp_vsc_ini_phase,
 532                                 priv->io_base + _REG(VPP_VSC_INI_PHASE));
 533                 writel_relaxed(priv->viu.vpp_vsc_phase_ctrl,
 534                                 priv->io_base + _REG(VPP_VSC_PHASE_CTRL));
 535                 writel_relaxed(priv->viu.vpp_hsc_phase_ctrl,
 536                                 priv->io_base + _REG(VPP_HSC_PHASE_CTRL));
 537                 writel_relaxed(0x42, priv->io_base + _REG(VPP_SCALE_COEF_IDX));
 538 
 539                 /* Enable VD1 */
 540                 if (meson_crtc->enable_vd1)
 541                         meson_crtc->enable_vd1(priv);
 542 
 543                 priv->viu.vd1_commit = false;
 544         }
 545 
 546         drm_crtc_handle_vblank(priv->crtc);
 547 
 548         spin_lock_irqsave(&priv->drm->event_lock, flags);
 549         if (meson_crtc->event) {
 550                 drm_crtc_send_vblank_event(priv->crtc, meson_crtc->event);
 551                 drm_crtc_vblank_put(priv->crtc);
 552                 meson_crtc->event = NULL;
 553         }
 554         spin_unlock_irqrestore(&priv->drm->event_lock, flags);
 555 }
 556 
 557 int meson_crtc_create(struct meson_drm *priv)
 558 {
 559         struct meson_crtc *meson_crtc;
 560         struct drm_crtc *crtc;
 561         int ret;
 562 
 563         meson_crtc = devm_kzalloc(priv->drm->dev, sizeof(*meson_crtc),
 564                                   GFP_KERNEL);
 565         if (!meson_crtc)
 566                 return -ENOMEM;
 567 
 568         meson_crtc->priv = priv;
 569         crtc = &meson_crtc->base;
 570         ret = drm_crtc_init_with_planes(priv->drm, crtc,
 571                                         priv->primary_plane, NULL,
 572                                         &meson_crtc_funcs, "meson_crtc");
 573         if (ret) {
 574                 dev_err(priv->drm->dev, "Failed to init CRTC\n");
 575                 return ret;
 576         }
 577 
 578         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
 579                 meson_crtc->enable_osd1 = meson_g12a_crtc_enable_osd1;
 580                 meson_crtc->enable_vd1 = meson_g12a_crtc_enable_vd1;
 581                 meson_crtc->viu_offset = MESON_G12A_VIU_OFFSET;
 582                 drm_crtc_helper_add(crtc, &meson_g12a_crtc_helper_funcs);
 583         } else {
 584                 meson_crtc->enable_osd1 = meson_crtc_enable_osd1;
 585                 meson_crtc->enable_vd1 = meson_crtc_enable_vd1;
 586                 drm_crtc_helper_add(crtc, &meson_crtc_helper_funcs);
 587         }
 588 
 589         priv->crtc = crtc;
 590 
 591         return 0;
 592 }

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