linux/drivers/gpu/drm/rcar-du/rcar_du_kms.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * rcar_du_kms.c  --  R-Car Display Unit Mode Setting
   4 *
   5 * Copyright (C) 2013-2015 Renesas Electronics Corporation
   6 *
   7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
   8 */
   9
  10#include <drm/drm_atomic.h>
  11#include <drm/drm_atomic_helper.h>
  12#include <drm/drm_crtc.h>
  13#include <drm/drm_device.h>
  14#include <drm/drm_fb_cma_helper.h>
  15#include <drm/drm_gem_cma_helper.h>
  16#include <drm/drm_gem_framebuffer_helper.h>
  17#include <drm/drm_managed.h>
  18#include <drm/drm_probe_helper.h>
  19#include <drm/drm_vblank.h>
  20
  21#include <linux/device.h>
  22#include <linux/dma-buf.h>
  23#include <linux/of_graph.h>
  24#include <linux/of_platform.h>
  25#include <linux/wait.h>
  26
  27#include "rcar_du_crtc.h"
  28#include "rcar_du_drv.h"
  29#include "rcar_du_encoder.h"
  30#include "rcar_du_kms.h"
  31#include "rcar_du_regs.h"
  32#include "rcar_du_vsp.h"
  33#include "rcar_du_writeback.h"
  34
  35/* -----------------------------------------------------------------------------
  36 * Format helpers
  37 */
  38
  39static const struct rcar_du_format_info rcar_du_format_infos[] = {
  40        {
  41                .fourcc = DRM_FORMAT_RGB565,
  42                .v4l2 = V4L2_PIX_FMT_RGB565,
  43                .bpp = 16,
  44                .planes = 1,
  45                .hsub = 1,
  46                .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
  47                .edf = PnDDCR4_EDF_NONE,
  48        }, {
  49                .fourcc = DRM_FORMAT_ARGB1555,
  50                .v4l2 = V4L2_PIX_FMT_ARGB555,
  51                .bpp = 16,
  52                .planes = 1,
  53                .hsub = 1,
  54                .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB,
  55                .edf = PnDDCR4_EDF_NONE,
  56        }, {
  57                .fourcc = DRM_FORMAT_XRGB1555,
  58                .v4l2 = V4L2_PIX_FMT_XRGB555,
  59                .bpp = 16,
  60                .planes = 1,
  61                .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB,
  62                .edf = PnDDCR4_EDF_NONE,
  63        }, {
  64                .fourcc = DRM_FORMAT_XRGB8888,
  65                .v4l2 = V4L2_PIX_FMT_XBGR32,
  66                .bpp = 32,
  67                .planes = 1,
  68                .hsub = 1,
  69                .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
  70                .edf = PnDDCR4_EDF_RGB888,
  71        }, {
  72                .fourcc = DRM_FORMAT_ARGB8888,
  73                .v4l2 = V4L2_PIX_FMT_ABGR32,
  74                .bpp = 32,
  75                .planes = 1,
  76                .hsub = 1,
  77                .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_16BPP,
  78                .edf = PnDDCR4_EDF_ARGB8888,
  79        }, {
  80                .fourcc = DRM_FORMAT_UYVY,
  81                .v4l2 = V4L2_PIX_FMT_UYVY,
  82                .bpp = 16,
  83                .planes = 1,
  84                .hsub = 2,
  85                .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
  86                .edf = PnDDCR4_EDF_NONE,
  87        }, {
  88                .fourcc = DRM_FORMAT_YUYV,
  89                .v4l2 = V4L2_PIX_FMT_YUYV,
  90                .bpp = 16,
  91                .planes = 1,
  92                .hsub = 2,
  93                .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
  94                .edf = PnDDCR4_EDF_NONE,
  95        }, {
  96                .fourcc = DRM_FORMAT_NV12,
  97                .v4l2 = V4L2_PIX_FMT_NV12M,
  98                .bpp = 12,
  99                .planes = 2,
 100                .hsub = 2,
 101                .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
 102                .edf = PnDDCR4_EDF_NONE,
 103        }, {
 104                .fourcc = DRM_FORMAT_NV21,
 105                .v4l2 = V4L2_PIX_FMT_NV21M,
 106                .bpp = 12,
 107                .planes = 2,
 108                .hsub = 2,
 109                .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
 110                .edf = PnDDCR4_EDF_NONE,
 111        }, {
 112                .fourcc = DRM_FORMAT_NV16,
 113                .v4l2 = V4L2_PIX_FMT_NV16M,
 114                .bpp = 16,
 115                .planes = 2,
 116                .hsub = 2,
 117                .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
 118                .edf = PnDDCR4_EDF_NONE,
 119        },
 120        /*
 121         * The following formats are not supported on Gen2 and thus have no
 122         * associated .pnmr or .edf settings.
 123         */
 124        {
 125                .fourcc = DRM_FORMAT_RGB332,
 126                .v4l2 = V4L2_PIX_FMT_RGB332,
 127                .bpp = 8,
 128                .planes = 1,
 129                .hsub = 1,
 130        }, {
 131                .fourcc = DRM_FORMAT_ARGB4444,
 132                .v4l2 = V4L2_PIX_FMT_ARGB444,
 133                .bpp = 16,
 134                .planes = 1,
 135                .hsub = 1,
 136        }, {
 137                .fourcc = DRM_FORMAT_XRGB4444,
 138                .v4l2 = V4L2_PIX_FMT_XRGB444,
 139                .bpp = 16,
 140                .planes = 1,
 141                .hsub = 1,
 142        }, {
 143                .fourcc = DRM_FORMAT_RGBA4444,
 144                .v4l2 = V4L2_PIX_FMT_RGBA444,
 145                .bpp = 16,
 146                .planes = 1,
 147                .hsub = 1,
 148        }, {
 149                .fourcc = DRM_FORMAT_RGBX4444,
 150                .v4l2 = V4L2_PIX_FMT_RGBX444,
 151                .bpp = 16,
 152                .planes = 1,
 153                .hsub = 1,
 154        }, {
 155                .fourcc = DRM_FORMAT_ABGR4444,
 156                .v4l2 = V4L2_PIX_FMT_ABGR444,
 157                .bpp = 16,
 158                .planes = 1,
 159                .hsub = 1,
 160        }, {
 161                .fourcc = DRM_FORMAT_XBGR4444,
 162                .v4l2 = V4L2_PIX_FMT_XBGR444,
 163                .bpp = 16,
 164                .planes = 1,
 165                .hsub = 1,
 166        }, {
 167                .fourcc = DRM_FORMAT_BGRA4444,
 168                .v4l2 = V4L2_PIX_FMT_BGRA444,
 169                .bpp = 16,
 170                .planes = 1,
 171                .hsub = 1,
 172        }, {
 173                .fourcc = DRM_FORMAT_BGRX4444,
 174                .v4l2 = V4L2_PIX_FMT_BGRX444,
 175                .bpp = 16,
 176                .planes = 1,
 177                .hsub = 1,
 178        }, {
 179                .fourcc = DRM_FORMAT_RGBA5551,
 180                .v4l2 = V4L2_PIX_FMT_RGBA555,
 181                .bpp = 16,
 182                .planes = 1,
 183                .hsub = 1,
 184        }, {
 185                .fourcc = DRM_FORMAT_RGBX5551,
 186                .v4l2 = V4L2_PIX_FMT_RGBX555,
 187                .bpp = 16,
 188                .planes = 1,
 189                .hsub = 1,
 190        }, {
 191                .fourcc = DRM_FORMAT_ABGR1555,
 192                .v4l2 = V4L2_PIX_FMT_ABGR555,
 193                .bpp = 16,
 194                .planes = 1,
 195                .hsub = 1,
 196        }, {
 197                .fourcc = DRM_FORMAT_XBGR1555,
 198                .v4l2 = V4L2_PIX_FMT_XBGR555,
 199                .bpp = 16,
 200                .planes = 1,
 201                .hsub = 1,
 202        }, {
 203                .fourcc = DRM_FORMAT_BGRA5551,
 204                .v4l2 = V4L2_PIX_FMT_BGRA555,
 205                .bpp = 16,
 206                .planes = 1,
 207                .hsub = 1,
 208        }, {
 209                .fourcc = DRM_FORMAT_BGRX5551,
 210                .v4l2 = V4L2_PIX_FMT_BGRX555,
 211                .bpp = 16,
 212                .planes = 1,
 213                .hsub = 1,
 214        }, {
 215                .fourcc = DRM_FORMAT_BGR888,
 216                .v4l2 = V4L2_PIX_FMT_RGB24,
 217                .bpp = 24,
 218                .planes = 1,
 219                .hsub = 1,
 220        }, {
 221                .fourcc = DRM_FORMAT_RGB888,
 222                .v4l2 = V4L2_PIX_FMT_BGR24,
 223                .bpp = 24,
 224                .planes = 1,
 225                .hsub = 1,
 226        }, {
 227                .fourcc = DRM_FORMAT_RGBA8888,
 228                .v4l2 = V4L2_PIX_FMT_BGRA32,
 229                .bpp = 32,
 230                .planes = 1,
 231                .hsub = 1,
 232        }, {
 233                .fourcc = DRM_FORMAT_RGBX8888,
 234                .v4l2 = V4L2_PIX_FMT_BGRX32,
 235                .bpp = 32,
 236                .planes = 1,
 237                .hsub = 1,
 238        }, {
 239                .fourcc = DRM_FORMAT_ABGR8888,
 240                .v4l2 = V4L2_PIX_FMT_RGBA32,
 241                .bpp = 32,
 242                .planes = 1,
 243                .hsub = 1,
 244        }, {
 245                .fourcc = DRM_FORMAT_XBGR8888,
 246                .v4l2 = V4L2_PIX_FMT_RGBX32,
 247                .bpp = 32,
 248                .planes = 1,
 249                .hsub = 1,
 250        }, {
 251                .fourcc = DRM_FORMAT_BGRA8888,
 252                .v4l2 = V4L2_PIX_FMT_ARGB32,
 253                .bpp = 32,
 254                .planes = 1,
 255                .hsub = 1,
 256        }, {
 257                .fourcc = DRM_FORMAT_BGRX8888,
 258                .v4l2 = V4L2_PIX_FMT_XRGB32,
 259                .bpp = 32,
 260                .planes = 1,
 261                .hsub = 1,
 262        }, {
 263                .fourcc = DRM_FORMAT_YVYU,
 264                .v4l2 = V4L2_PIX_FMT_YVYU,
 265                .bpp = 16,
 266                .planes = 1,
 267                .hsub = 2,
 268        }, {
 269                .fourcc = DRM_FORMAT_NV61,
 270                .v4l2 = V4L2_PIX_FMT_NV61M,
 271                .bpp = 16,
 272                .planes = 2,
 273                .hsub = 2,
 274        }, {
 275                .fourcc = DRM_FORMAT_YUV420,
 276                .v4l2 = V4L2_PIX_FMT_YUV420M,
 277                .bpp = 12,
 278                .planes = 3,
 279                .hsub = 2,
 280        }, {
 281                .fourcc = DRM_FORMAT_YVU420,
 282                .v4l2 = V4L2_PIX_FMT_YVU420M,
 283                .bpp = 12,
 284                .planes = 3,
 285                .hsub = 2,
 286        }, {
 287                .fourcc = DRM_FORMAT_YUV422,
 288                .v4l2 = V4L2_PIX_FMT_YUV422M,
 289                .bpp = 16,
 290                .planes = 3,
 291                .hsub = 2,
 292        }, {
 293                .fourcc = DRM_FORMAT_YVU422,
 294                .v4l2 = V4L2_PIX_FMT_YVU422M,
 295                .bpp = 16,
 296                .planes = 3,
 297                .hsub = 2,
 298        }, {
 299                .fourcc = DRM_FORMAT_YUV444,
 300                .v4l2 = V4L2_PIX_FMT_YUV444M,
 301                .bpp = 24,
 302                .planes = 3,
 303                .hsub = 1,
 304        }, {
 305                .fourcc = DRM_FORMAT_YVU444,
 306                .v4l2 = V4L2_PIX_FMT_YVU444M,
 307                .bpp = 24,
 308                .planes = 3,
 309                .hsub = 1,
 310        },
 311};
 312
 313const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc)
 314{
 315        unsigned int i;
 316
 317        for (i = 0; i < ARRAY_SIZE(rcar_du_format_infos); ++i) {
 318                if (rcar_du_format_infos[i].fourcc == fourcc)
 319                        return &rcar_du_format_infos[i];
 320        }
 321
 322        return NULL;
 323}
 324
 325/* -----------------------------------------------------------------------------
 326 * Frame buffer
 327 */
 328
 329static const struct drm_gem_object_funcs rcar_du_gem_funcs = {
 330        .free = drm_gem_cma_free_object,
 331        .print_info = drm_gem_cma_print_info,
 332        .get_sg_table = drm_gem_cma_get_sg_table,
 333        .vmap = drm_gem_cma_vmap,
 334        .mmap = drm_gem_cma_mmap,
 335        .vm_ops = &drm_gem_cma_vm_ops,
 336};
 337
 338struct drm_gem_object *rcar_du_gem_prime_import_sg_table(struct drm_device *dev,
 339                                struct dma_buf_attachment *attach,
 340                                struct sg_table *sgt)
 341{
 342        struct rcar_du_device *rcdu = to_rcar_du_device(dev);
 343        struct drm_gem_cma_object *cma_obj;
 344        struct drm_gem_object *gem_obj;
 345        int ret;
 346
 347        if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
 348                return drm_gem_cma_prime_import_sg_table(dev, attach, sgt);
 349
 350        /* Create a CMA GEM buffer. */
 351        cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
 352        if (!cma_obj)
 353                return ERR_PTR(-ENOMEM);
 354
 355        gem_obj = &cma_obj->base;
 356        gem_obj->funcs = &rcar_du_gem_funcs;
 357
 358        drm_gem_private_object_init(dev, gem_obj, attach->dmabuf->size);
 359        cma_obj->map_noncoherent = false;
 360
 361        ret = drm_gem_create_mmap_offset(gem_obj);
 362        if (ret) {
 363                drm_gem_object_release(gem_obj);
 364                kfree(cma_obj);
 365                return ERR_PTR(ret);
 366        }
 367
 368        cma_obj->paddr = 0;
 369        cma_obj->sgt = sgt;
 370
 371        return gem_obj;
 372}
 373
 374int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
 375                        struct drm_mode_create_dumb *args)
 376{
 377        struct rcar_du_device *rcdu = to_rcar_du_device(dev);
 378        unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
 379        unsigned int align;
 380
 381        /*
 382         * The R8A7779 DU requires a 16 pixels pitch alignment as documented,
 383         * but the R8A7790 DU seems to require a 128 bytes pitch alignment.
 384         */
 385        if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
 386                align = 128;
 387        else
 388                align = 16 * args->bpp / 8;
 389
 390        args->pitch = roundup(min_pitch, align);
 391
 392        return drm_gem_cma_dumb_create_internal(file, dev, args);
 393}
 394
 395static struct drm_framebuffer *
 396rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 397                  const struct drm_mode_fb_cmd2 *mode_cmd)
 398{
 399        struct rcar_du_device *rcdu = to_rcar_du_device(dev);
 400        const struct rcar_du_format_info *format;
 401        unsigned int chroma_pitch;
 402        unsigned int max_pitch;
 403        unsigned int align;
 404        unsigned int i;
 405
 406        format = rcar_du_format_info(mode_cmd->pixel_format);
 407        if (format == NULL) {
 408                dev_dbg(dev->dev, "unsupported pixel format %08x\n",
 409                        mode_cmd->pixel_format);
 410                return ERR_PTR(-EINVAL);
 411        }
 412
 413        if (rcdu->info->gen < 3) {
 414                /*
 415                 * On Gen2 the DU limits the pitch to 4095 pixels and requires
 416                 * buffers to be aligned to a 16 pixels boundary (or 128 bytes
 417                 * on some platforms).
 418                 */
 419                unsigned int bpp = format->planes == 1 ? format->bpp / 8 : 1;
 420
 421                max_pitch = 4095 * bpp;
 422
 423                if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
 424                        align = 128;
 425                else
 426                        align = 16 * bpp;
 427        } else {
 428                /*
 429                 * On Gen3 the memory interface is handled by the VSP that
 430                 * limits the pitch to 65535 bytes and has no alignment
 431                 * constraint.
 432                 */
 433                max_pitch = 65535;
 434                align = 1;
 435        }
 436
 437        if (mode_cmd->pitches[0] & (align - 1) ||
 438            mode_cmd->pitches[0] > max_pitch) {
 439                dev_dbg(dev->dev, "invalid pitch value %u\n",
 440                        mode_cmd->pitches[0]);
 441                return ERR_PTR(-EINVAL);
 442        }
 443
 444        /*
 445         * Calculate the chroma plane(s) pitch using the horizontal subsampling
 446         * factor. For semi-planar formats, the U and V planes are combined, the
 447         * pitch must thus be doubled.
 448         */
 449        chroma_pitch = mode_cmd->pitches[0] / format->hsub;
 450        if (format->planes == 2)
 451                chroma_pitch *= 2;
 452
 453        for (i = 1; i < format->planes; ++i) {
 454                if (mode_cmd->pitches[i] != chroma_pitch) {
 455                        dev_dbg(dev->dev,
 456                                "luma and chroma pitches are not compatible\n");
 457                        return ERR_PTR(-EINVAL);
 458                }
 459        }
 460
 461        return drm_gem_fb_create(dev, file_priv, mode_cmd);
 462}
 463
 464/* -----------------------------------------------------------------------------
 465 * Atomic Check and Update
 466 */
 467
 468static int rcar_du_atomic_check(struct drm_device *dev,
 469                                struct drm_atomic_state *state)
 470{
 471        struct rcar_du_device *rcdu = to_rcar_du_device(dev);
 472        int ret;
 473
 474        ret = drm_atomic_helper_check(dev, state);
 475        if (ret)
 476                return ret;
 477
 478        if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
 479                return 0;
 480
 481        return rcar_du_atomic_check_planes(dev, state);
 482}
 483
 484static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
 485{
 486        struct drm_device *dev = old_state->dev;
 487        struct rcar_du_device *rcdu = to_rcar_du_device(dev);
 488        struct drm_crtc_state *crtc_state;
 489        struct drm_crtc *crtc;
 490        unsigned int i;
 491
 492        /*
 493         * Store RGB routing to DPAD0 and DPAD1, the hardware will be configured
 494         * when starting the CRTCs.
 495         */
 496        rcdu->dpad1_source = -1;
 497
 498        for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) {
 499                struct rcar_du_crtc_state *rcrtc_state =
 500                        to_rcar_crtc_state(crtc_state);
 501                struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 502
 503                if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD0))
 504                        rcdu->dpad0_source = rcrtc->index;
 505
 506                if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD1))
 507                        rcdu->dpad1_source = rcrtc->index;
 508        }
 509
 510        /* Apply the atomic update. */
 511        drm_atomic_helper_commit_modeset_disables(dev, old_state);
 512        drm_atomic_helper_commit_planes(dev, old_state,
 513                                        DRM_PLANE_COMMIT_ACTIVE_ONLY);
 514        drm_atomic_helper_commit_modeset_enables(dev, old_state);
 515
 516        drm_atomic_helper_commit_hw_done(old_state);
 517        drm_atomic_helper_wait_for_flip_done(dev, old_state);
 518
 519        drm_atomic_helper_cleanup_planes(dev, old_state);
 520}
 521
 522/* -----------------------------------------------------------------------------
 523 * Initialization
 524 */
 525
 526static const struct drm_mode_config_helper_funcs rcar_du_mode_config_helper = {
 527        .atomic_commit_tail = rcar_du_atomic_commit_tail,
 528};
 529
 530static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = {
 531        .fb_create = rcar_du_fb_create,
 532        .atomic_check = rcar_du_atomic_check,
 533        .atomic_commit = drm_atomic_helper_commit,
 534};
 535
 536static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
 537                                     enum rcar_du_output output,
 538                                     struct of_endpoint *ep)
 539{
 540        struct device_node *entity;
 541        int ret;
 542
 543        /* Locate the connected entity and initialize the encoder. */
 544        entity = of_graph_get_remote_port_parent(ep->local_node);
 545        if (!entity) {
 546                dev_dbg(rcdu->dev, "unconnected endpoint %pOF, skipping\n",
 547                        ep->local_node);
 548                return -ENODEV;
 549        }
 550
 551        if (!of_device_is_available(entity)) {
 552                dev_dbg(rcdu->dev,
 553                        "connected entity %pOF is disabled, skipping\n",
 554                        entity);
 555                of_node_put(entity);
 556                return -ENODEV;
 557        }
 558
 559        ret = rcar_du_encoder_init(rcdu, output, entity);
 560        if (ret && ret != -EPROBE_DEFER && ret != -ENOLINK)
 561                dev_warn(rcdu->dev,
 562                         "failed to initialize encoder %pOF on output %s (%d), skipping\n",
 563                         entity, rcar_du_output_name(output), ret);
 564
 565        of_node_put(entity);
 566
 567        return ret;
 568}
 569
 570static int rcar_du_encoders_init(struct rcar_du_device *rcdu)
 571{
 572        struct device_node *np = rcdu->dev->of_node;
 573        struct device_node *ep_node;
 574        unsigned int num_encoders = 0;
 575
 576        /*
 577         * Iterate over the endpoints and create one encoder for each output
 578         * pipeline.
 579         */
 580        for_each_endpoint_of_node(np, ep_node) {
 581                enum rcar_du_output output;
 582                struct of_endpoint ep;
 583                unsigned int i;
 584                int ret;
 585
 586                ret = of_graph_parse_endpoint(ep_node, &ep);
 587                if (ret < 0) {
 588                        of_node_put(ep_node);
 589                        return ret;
 590                }
 591
 592                /* Find the output route corresponding to the port number. */
 593                for (i = 0; i < RCAR_DU_OUTPUT_MAX; ++i) {
 594                        if (rcdu->info->routes[i].possible_crtcs &&
 595                            rcdu->info->routes[i].port == ep.port) {
 596                                output = i;
 597                                break;
 598                        }
 599                }
 600
 601                if (i == RCAR_DU_OUTPUT_MAX) {
 602                        dev_warn(rcdu->dev,
 603                                 "port %u references unexisting output, skipping\n",
 604                                 ep.port);
 605                        continue;
 606                }
 607
 608                /* Process the output pipeline. */
 609                ret = rcar_du_encoders_init_one(rcdu, output, &ep);
 610                if (ret < 0) {
 611                        if (ret == -EPROBE_DEFER) {
 612                                of_node_put(ep_node);
 613                                return ret;
 614                        }
 615
 616                        continue;
 617                }
 618
 619                num_encoders++;
 620        }
 621
 622        return num_encoders;
 623}
 624
 625static int rcar_du_properties_init(struct rcar_du_device *rcdu)
 626{
 627        /*
 628         * The color key is expressed as an RGB888 triplet stored in a 32-bit
 629         * integer in XRGB8888 format. Bit 24 is used as a flag to disable (0)
 630         * or enable source color keying (1).
 631         */
 632        rcdu->props.colorkey =
 633                drm_property_create_range(&rcdu->ddev, 0, "colorkey",
 634                                          0, 0x01ffffff);
 635        if (rcdu->props.colorkey == NULL)
 636                return -ENOMEM;
 637
 638        return 0;
 639}
 640
 641static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
 642{
 643        const struct device_node *np = rcdu->dev->of_node;
 644        const char *vsps_prop_name = "renesas,vsps";
 645        struct of_phandle_args args;
 646        struct {
 647                struct device_node *np;
 648                unsigned int crtcs_mask;
 649        } vsps[RCAR_DU_MAX_VSPS] = { { NULL, }, };
 650        unsigned int vsps_count = 0;
 651        unsigned int cells;
 652        unsigned int i;
 653        int ret;
 654
 655        /*
 656         * First parse the DT vsps property to populate the list of VSPs. Each
 657         * entry contains a pointer to the VSP DT node and a bitmask of the
 658         * connected DU CRTCs.
 659         */
 660        ret = of_property_count_u32_elems(np, vsps_prop_name);
 661        if (ret < 0) {
 662                /* Backward compatibility with old DTBs. */
 663                vsps_prop_name = "vsps";
 664                ret = of_property_count_u32_elems(np, vsps_prop_name);
 665        }
 666        cells = ret / rcdu->num_crtcs - 1;
 667        if (cells > 1)
 668                return -EINVAL;
 669
 670        for (i = 0; i < rcdu->num_crtcs; ++i) {
 671                unsigned int j;
 672
 673                ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name,
 674                                                       cells, i, &args);
 675                if (ret < 0)
 676                        goto error;
 677
 678                /*
 679                 * Add the VSP to the list or update the corresponding existing
 680                 * entry if the VSP has already been added.
 681                 */
 682                for (j = 0; j < vsps_count; ++j) {
 683                        if (vsps[j].np == args.np)
 684                                break;
 685                }
 686
 687                if (j < vsps_count)
 688                        of_node_put(args.np);
 689                else
 690                        vsps[vsps_count++].np = args.np;
 691
 692                vsps[j].crtcs_mask |= BIT(i);
 693
 694                /*
 695                 * Store the VSP pointer and pipe index in the CRTC. If the
 696                 * second cell of the 'renesas,vsps' specifier isn't present,
 697                 * default to 0 to remain compatible with older DT bindings.
 698                 */
 699                rcdu->crtcs[i].vsp = &rcdu->vsps[j];
 700                rcdu->crtcs[i].vsp_pipe = cells >= 1 ? args.args[0] : 0;
 701        }
 702
 703        /*
 704         * Then initialize all the VSPs from the node pointers and CRTCs bitmask
 705         * computed previously.
 706         */
 707        for (i = 0; i < vsps_count; ++i) {
 708                struct rcar_du_vsp *vsp = &rcdu->vsps[i];
 709
 710                vsp->index = i;
 711                vsp->dev = rcdu;
 712
 713                ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask);
 714                if (ret < 0)
 715                        goto error;
 716        }
 717
 718        return 0;
 719
 720error:
 721        for (i = 0; i < ARRAY_SIZE(vsps); ++i)
 722                of_node_put(vsps[i].np);
 723
 724        return ret;
 725}
 726
 727static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
 728{
 729        const struct device_node *np = rcdu->dev->of_node;
 730        unsigned int i;
 731        int cells;
 732
 733        cells = of_property_count_u32_elems(np, "renesas,cmms");
 734        if (cells == -EINVAL)
 735                return 0;
 736
 737        if (cells > rcdu->num_crtcs) {
 738                dev_err(rcdu->dev,
 739                        "Invalid number of entries in 'renesas,cmms'\n");
 740                return -EINVAL;
 741        }
 742
 743        for (i = 0; i < cells; ++i) {
 744                struct platform_device *pdev;
 745                struct device_link *link;
 746                struct device_node *cmm;
 747                int ret;
 748
 749                cmm = of_parse_phandle(np, "renesas,cmms", i);
 750                if (!cmm) {
 751                        dev_err(rcdu->dev,
 752                                "Failed to parse 'renesas,cmms' property\n");
 753                        return -EINVAL;
 754                }
 755
 756                if (!of_device_is_available(cmm)) {
 757                        /* It's fine to have a phandle to a non-enabled CMM. */
 758                        of_node_put(cmm);
 759                        continue;
 760                }
 761
 762                pdev = of_find_device_by_node(cmm);
 763                if (!pdev) {
 764                        dev_err(rcdu->dev, "No device found for CMM%u\n", i);
 765                        of_node_put(cmm);
 766                        return -EINVAL;
 767                }
 768
 769                of_node_put(cmm);
 770
 771                /*
 772                 * -ENODEV is used to report that the CMM config option is
 773                 * disabled: return 0 and let the DU continue probing.
 774                 */
 775                ret = rcar_cmm_init(pdev);
 776                if (ret) {
 777                        platform_device_put(pdev);
 778                        return ret == -ENODEV ? 0 : ret;
 779                }
 780
 781                rcdu->cmms[i] = pdev;
 782
 783                /*
 784                 * Enforce suspend/resume ordering by making the CMM a provider
 785                 * of the DU: CMM is suspended after and resumed before the DU.
 786                 */
 787                link = device_link_add(rcdu->dev, &pdev->dev, DL_FLAG_STATELESS);
 788                if (!link) {
 789                        dev_err(rcdu->dev,
 790                                "Failed to create device link to CMM%u\n", i);
 791                        return -EINVAL;
 792                }
 793        }
 794
 795        return 0;
 796}
 797
 798static void rcar_du_modeset_cleanup(struct drm_device *dev, void *res)
 799{
 800        struct rcar_du_device *rcdu = to_rcar_du_device(dev);
 801        unsigned int i;
 802
 803        for (i = 0; i < ARRAY_SIZE(rcdu->cmms); ++i)
 804                platform_device_put(rcdu->cmms[i]);
 805}
 806
 807int rcar_du_modeset_init(struct rcar_du_device *rcdu)
 808{
 809        static const unsigned int mmio_offsets[] = {
 810                DU0_REG_OFFSET, DU2_REG_OFFSET
 811        };
 812
 813        struct drm_device *dev = &rcdu->ddev;
 814        struct drm_encoder *encoder;
 815        unsigned int dpad0_sources;
 816        unsigned int num_encoders;
 817        unsigned int num_groups;
 818        unsigned int swindex;
 819        unsigned int hwindex;
 820        unsigned int i;
 821        int ret;
 822
 823        ret = drmm_mode_config_init(dev);
 824        if (ret)
 825                return ret;
 826
 827        ret = drmm_add_action(&rcdu->ddev, rcar_du_modeset_cleanup, NULL);
 828        if (ret)
 829                return ret;
 830
 831        dev->mode_config.min_width = 0;
 832        dev->mode_config.min_height = 0;
 833        dev->mode_config.normalize_zpos = true;
 834        dev->mode_config.funcs = &rcar_du_mode_config_funcs;
 835        dev->mode_config.helper_private = &rcar_du_mode_config_helper;
 836
 837        if (rcdu->info->gen < 3) {
 838                dev->mode_config.max_width = 4095;
 839                dev->mode_config.max_height = 2047;
 840        } else {
 841                /*
 842                 * The Gen3 DU uses the VSP1 for memory access, and is limited
 843                 * to frame sizes of 8190x8190.
 844                 */
 845                dev->mode_config.max_width = 8190;
 846                dev->mode_config.max_height = 8190;
 847        }
 848
 849        rcdu->num_crtcs = hweight8(rcdu->info->channels_mask);
 850
 851        ret = rcar_du_properties_init(rcdu);
 852        if (ret < 0)
 853                return ret;
 854
 855        /*
 856         * Initialize vertical blanking interrupts handling. Start with vblank
 857         * disabled for all CRTCs.
 858         */
 859        ret = drm_vblank_init(dev, rcdu->num_crtcs);
 860        if (ret < 0)
 861                return ret;
 862
 863        /* Initialize the groups. */
 864        num_groups = DIV_ROUND_UP(rcdu->num_crtcs, 2);
 865
 866        for (i = 0; i < num_groups; ++i) {
 867                struct rcar_du_group *rgrp = &rcdu->groups[i];
 868
 869                mutex_init(&rgrp->lock);
 870
 871                rgrp->dev = rcdu;
 872                rgrp->mmio_offset = mmio_offsets[i];
 873                rgrp->index = i;
 874                /* Extract the channel mask for this group only. */
 875                rgrp->channels_mask = (rcdu->info->channels_mask >> (2 * i))
 876                                   & GENMASK(1, 0);
 877                rgrp->num_crtcs = hweight8(rgrp->channels_mask);
 878
 879                /*
 880                 * If we have more than one CRTCs in this group pre-associate
 881                 * the low-order planes with CRTC 0 and the high-order planes
 882                 * with CRTC 1 to minimize flicker occurring when the
 883                 * association is changed.
 884                 */
 885                rgrp->dptsr_planes = rgrp->num_crtcs > 1
 886                                   ? (rcdu->info->gen >= 3 ? 0x04 : 0xf0)
 887                                   : 0;
 888
 889                if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
 890                        ret = rcar_du_planes_init(rgrp);
 891                        if (ret < 0)
 892                                return ret;
 893                }
 894        }
 895
 896        /* Initialize the compositors. */
 897        if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
 898                ret = rcar_du_vsps_init(rcdu);
 899                if (ret < 0)
 900                        return ret;
 901        }
 902
 903        /* Initialize the Color Management Modules. */
 904        ret = rcar_du_cmm_init(rcdu);
 905        if (ret)
 906                return ret;
 907
 908        /* Create the CRTCs. */
 909        for (swindex = 0, hwindex = 0; swindex < rcdu->num_crtcs; ++hwindex) {
 910                struct rcar_du_group *rgrp;
 911
 912                /* Skip unpopulated DU channels. */
 913                if (!(rcdu->info->channels_mask & BIT(hwindex)))
 914                        continue;
 915
 916                rgrp = &rcdu->groups[hwindex / 2];
 917
 918                ret = rcar_du_crtc_create(rgrp, swindex++, hwindex);
 919                if (ret < 0)
 920                        return ret;
 921        }
 922
 923        /* Initialize the encoders. */
 924        ret = rcar_du_encoders_init(rcdu);
 925        if (ret < 0)
 926                return ret;
 927
 928        if (ret == 0) {
 929                dev_err(rcdu->dev, "error: no encoder could be initialized\n");
 930                return -EINVAL;
 931        }
 932
 933        num_encoders = ret;
 934
 935        /*
 936         * Set the possible CRTCs and possible clones. There's always at least
 937         * one way for all encoders to clone each other, set all bits in the
 938         * possible clones field.
 939         */
 940        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 941                struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
 942                const struct rcar_du_output_routing *route =
 943                        &rcdu->info->routes[renc->output];
 944
 945                encoder->possible_crtcs = route->possible_crtcs;
 946                encoder->possible_clones = (1 << num_encoders) - 1;
 947        }
 948
 949        /* Create the writeback connectors. */
 950        if (rcdu->info->gen >= 3) {
 951                for (i = 0; i < rcdu->num_crtcs; ++i) {
 952                        struct rcar_du_crtc *rcrtc = &rcdu->crtcs[i];
 953
 954                        ret = rcar_du_writeback_init(rcdu, rcrtc);
 955                        if (ret < 0)
 956                                return ret;
 957                }
 958        }
 959
 960        /*
 961         * Initialize the default DPAD0 source to the index of the first DU
 962         * channel that can be connected to DPAD0. The exact value doesn't
 963         * matter as it should be overwritten by mode setting for the RGB
 964         * output, but it is nonetheless required to ensure a valid initial
 965         * hardware configuration on Gen3 where DU0 can't always be connected to
 966         * DPAD0.
 967         */
 968        dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
 969        rcdu->dpad0_source = ffs(dpad0_sources) - 1;
 970
 971        drm_mode_config_reset(dev);
 972
 973        drm_kms_helper_poll_init(dev);
 974
 975        return 0;
 976}
 977