linux/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2015 MediaTek Inc.
   4 */
   5
   6#include <asm/barrier.h>
   7#include <drm/drmP.h>
   8#include <drm/drm_atomic_helper.h>
   9#include <drm/drm_plane_helper.h>
  10#include <drm/drm_probe_helper.h>
  11#include <linux/clk.h>
  12#include <linux/pm_runtime.h>
  13#include <soc/mediatek/smi.h>
  14
  15#include "mtk_drm_drv.h"
  16#include "mtk_drm_crtc.h"
  17#include "mtk_drm_ddp.h"
  18#include "mtk_drm_ddp_comp.h"
  19#include "mtk_drm_gem.h"
  20#include "mtk_drm_plane.h"
  21
  22/**
  23 * struct mtk_drm_crtc - MediaTek specific crtc structure.
  24 * @base: crtc object.
  25 * @enabled: records whether crtc_enable succeeded
  26 * @planes: array of 4 drm_plane structures, one for each overlay plane
  27 * @pending_planes: whether any plane has pending changes to be applied
  28 * @config_regs: memory mapped mmsys configuration register space
  29 * @mutex: handle to one of the ten disp_mutex streams
  30 * @ddp_comp_nr: number of components in ddp_comp
  31 * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
  32 */
  33struct mtk_drm_crtc {
  34        struct drm_crtc                 base;
  35        bool                            enabled;
  36
  37        bool                            pending_needs_vblank;
  38        struct drm_pending_vblank_event *event;
  39
  40        struct drm_plane                *planes;
  41        unsigned int                    layer_nr;
  42        bool                            pending_planes;
  43
  44        void __iomem                    *config_regs;
  45        struct mtk_disp_mutex           *mutex;
  46        unsigned int                    ddp_comp_nr;
  47        struct mtk_ddp_comp             **ddp_comp;
  48};
  49
  50struct mtk_crtc_state {
  51        struct drm_crtc_state           base;
  52
  53        bool                            pending_config;
  54        unsigned int                    pending_width;
  55        unsigned int                    pending_height;
  56        unsigned int                    pending_vrefresh;
  57};
  58
  59static inline struct mtk_drm_crtc *to_mtk_crtc(struct drm_crtc *c)
  60{
  61        return container_of(c, struct mtk_drm_crtc, base);
  62}
  63
  64static inline struct mtk_crtc_state *to_mtk_crtc_state(struct drm_crtc_state *s)
  65{
  66        return container_of(s, struct mtk_crtc_state, base);
  67}
  68
  69static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
  70{
  71        struct drm_crtc *crtc = &mtk_crtc->base;
  72        unsigned long flags;
  73
  74        spin_lock_irqsave(&crtc->dev->event_lock, flags);
  75        drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
  76        drm_crtc_vblank_put(crtc);
  77        mtk_crtc->event = NULL;
  78        spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
  79}
  80
  81static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
  82{
  83        drm_crtc_handle_vblank(&mtk_crtc->base);
  84        if (mtk_crtc->pending_needs_vblank) {
  85                mtk_drm_crtc_finish_page_flip(mtk_crtc);
  86                mtk_crtc->pending_needs_vblank = false;
  87        }
  88}
  89
  90static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
  91{
  92        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
  93
  94        mtk_disp_mutex_put(mtk_crtc->mutex);
  95
  96        drm_crtc_cleanup(crtc);
  97}
  98
  99static void mtk_drm_crtc_reset(struct drm_crtc *crtc)
 100{
 101        struct mtk_crtc_state *state;
 102
 103        if (crtc->state) {
 104                __drm_atomic_helper_crtc_destroy_state(crtc->state);
 105
 106                state = to_mtk_crtc_state(crtc->state);
 107                memset(state, 0, sizeof(*state));
 108        } else {
 109                state = kzalloc(sizeof(*state), GFP_KERNEL);
 110                if (!state)
 111                        return;
 112                crtc->state = &state->base;
 113        }
 114
 115        state->base.crtc = crtc;
 116}
 117
 118static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc)
 119{
 120        struct mtk_crtc_state *state;
 121
 122        state = kzalloc(sizeof(*state), GFP_KERNEL);
 123        if (!state)
 124                return NULL;
 125
 126        __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
 127
 128        WARN_ON(state->base.crtc != crtc);
 129        state->base.crtc = crtc;
 130
 131        return &state->base;
 132}
 133
 134static void mtk_drm_crtc_destroy_state(struct drm_crtc *crtc,
 135                                       struct drm_crtc_state *state)
 136{
 137        __drm_atomic_helper_crtc_destroy_state(state);
 138        kfree(to_mtk_crtc_state(state));
 139}
 140
 141static bool mtk_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 142                                    const struct drm_display_mode *mode,
 143                                    struct drm_display_mode *adjusted_mode)
 144{
 145        /* Nothing to do here, but this callback is mandatory. */
 146        return true;
 147}
 148
 149static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 150{
 151        struct mtk_crtc_state *state = to_mtk_crtc_state(crtc->state);
 152
 153        state->pending_width = crtc->mode.hdisplay;
 154        state->pending_height = crtc->mode.vdisplay;
 155        state->pending_vrefresh = crtc->mode.vrefresh;
 156        wmb();  /* Make sure the above parameters are set before update */
 157        state->pending_config = true;
 158}
 159
 160static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 161{
 162        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 163        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 164
 165        mtk_ddp_comp_enable_vblank(comp, &mtk_crtc->base);
 166
 167        return 0;
 168}
 169
 170static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)
 171{
 172        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 173        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 174
 175        mtk_ddp_comp_disable_vblank(comp);
 176}
 177
 178static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
 179{
 180        int ret;
 181        int i;
 182
 183        DRM_DEBUG_DRIVER("%s\n", __func__);
 184        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 185                ret = clk_prepare_enable(mtk_crtc->ddp_comp[i]->clk);
 186                if (ret) {
 187                        DRM_ERROR("Failed to enable clock %d: %d\n", i, ret);
 188                        goto err;
 189                }
 190        }
 191
 192        return 0;
 193err:
 194        while (--i >= 0)
 195                clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
 196        return ret;
 197}
 198
 199static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
 200{
 201        int i;
 202
 203        DRM_DEBUG_DRIVER("%s\n", __func__);
 204        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
 205                clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
 206}
 207
 208static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 209{
 210        struct drm_crtc *crtc = &mtk_crtc->base;
 211        struct drm_connector *connector;
 212        struct drm_encoder *encoder;
 213        struct drm_connector_list_iter conn_iter;
 214        unsigned int width, height, vrefresh, bpc = MTK_MAX_BPC;
 215        int ret;
 216        int i;
 217
 218        DRM_DEBUG_DRIVER("%s\n", __func__);
 219        if (WARN_ON(!crtc->state))
 220                return -EINVAL;
 221
 222        width = crtc->state->adjusted_mode.hdisplay;
 223        height = crtc->state->adjusted_mode.vdisplay;
 224        vrefresh = crtc->state->adjusted_mode.vrefresh;
 225
 226        drm_for_each_encoder(encoder, crtc->dev) {
 227                if (encoder->crtc != crtc)
 228                        continue;
 229
 230                drm_connector_list_iter_begin(crtc->dev, &conn_iter);
 231                drm_for_each_connector_iter(connector, &conn_iter) {
 232                        if (connector->encoder != encoder)
 233                                continue;
 234                        if (connector->display_info.bpc != 0 &&
 235                            bpc > connector->display_info.bpc)
 236                                bpc = connector->display_info.bpc;
 237                }
 238                drm_connector_list_iter_end(&conn_iter);
 239        }
 240
 241        ret = pm_runtime_get_sync(crtc->dev->dev);
 242        if (ret < 0) {
 243                DRM_ERROR("Failed to enable power domain: %d\n", ret);
 244                return ret;
 245        }
 246
 247        ret = mtk_disp_mutex_prepare(mtk_crtc->mutex);
 248        if (ret < 0) {
 249                DRM_ERROR("Failed to enable mutex clock: %d\n", ret);
 250                goto err_pm_runtime_put;
 251        }
 252
 253        ret = mtk_crtc_ddp_clk_enable(mtk_crtc);
 254        if (ret < 0) {
 255                DRM_ERROR("Failed to enable component clocks: %d\n", ret);
 256                goto err_mutex_unprepare;
 257        }
 258
 259        DRM_DEBUG_DRIVER("mediatek_ddp_ddp_path_setup\n");
 260        for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
 261                mtk_ddp_add_comp_to_path(mtk_crtc->config_regs,
 262                                         mtk_crtc->ddp_comp[i]->id,
 263                                         mtk_crtc->ddp_comp[i + 1]->id);
 264                mtk_disp_mutex_add_comp(mtk_crtc->mutex,
 265                                        mtk_crtc->ddp_comp[i]->id);
 266        }
 267        mtk_disp_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
 268        mtk_disp_mutex_enable(mtk_crtc->mutex);
 269
 270        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 271                struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
 272
 273                mtk_ddp_comp_config(comp, width, height, vrefresh, bpc);
 274                mtk_ddp_comp_start(comp);
 275        }
 276
 277        /* Initially configure all planes */
 278        for (i = 0; i < mtk_crtc->layer_nr; i++) {
 279                struct drm_plane *plane = &mtk_crtc->planes[i];
 280                struct mtk_plane_state *plane_state;
 281
 282                plane_state = to_mtk_plane_state(plane->state);
 283                mtk_ddp_comp_layer_config(mtk_crtc->ddp_comp[0], i,
 284                                          plane_state);
 285        }
 286
 287        return 0;
 288
 289err_mutex_unprepare:
 290        mtk_disp_mutex_unprepare(mtk_crtc->mutex);
 291err_pm_runtime_put:
 292        pm_runtime_put(crtc->dev->dev);
 293        return ret;
 294}
 295
 296static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
 297{
 298        struct drm_device *drm = mtk_crtc->base.dev;
 299        int i;
 300
 301        DRM_DEBUG_DRIVER("%s\n", __func__);
 302        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
 303                mtk_ddp_comp_stop(mtk_crtc->ddp_comp[i]);
 304        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
 305                mtk_disp_mutex_remove_comp(mtk_crtc->mutex,
 306                                           mtk_crtc->ddp_comp[i]->id);
 307        mtk_disp_mutex_disable(mtk_crtc->mutex);
 308        for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
 309                mtk_ddp_remove_comp_from_path(mtk_crtc->config_regs,
 310                                              mtk_crtc->ddp_comp[i]->id,
 311                                              mtk_crtc->ddp_comp[i + 1]->id);
 312                mtk_disp_mutex_remove_comp(mtk_crtc->mutex,
 313                                           mtk_crtc->ddp_comp[i]->id);
 314        }
 315        mtk_disp_mutex_remove_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
 316        mtk_crtc_ddp_clk_disable(mtk_crtc);
 317        mtk_disp_mutex_unprepare(mtk_crtc->mutex);
 318
 319        pm_runtime_put(drm->dev);
 320}
 321
 322static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
 323{
 324        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 325        struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
 326        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 327        unsigned int i;
 328
 329        /*
 330         * TODO: instead of updating the registers here, we should prepare
 331         * working registers in atomic_commit and let the hardware command
 332         * queue update module registers on vblank.
 333         */
 334        if (state->pending_config) {
 335                mtk_ddp_comp_config(comp, state->pending_width,
 336                                    state->pending_height,
 337                                    state->pending_vrefresh, 0);
 338
 339                state->pending_config = false;
 340        }
 341
 342        if (mtk_crtc->pending_planes) {
 343                for (i = 0; i < mtk_crtc->layer_nr; i++) {
 344                        struct drm_plane *plane = &mtk_crtc->planes[i];
 345                        struct mtk_plane_state *plane_state;
 346
 347                        plane_state = to_mtk_plane_state(plane->state);
 348
 349                        if (plane_state->pending.config) {
 350                                mtk_ddp_comp_layer_config(comp, i, plane_state);
 351                                plane_state->pending.config = false;
 352                        }
 353                }
 354                mtk_crtc->pending_planes = false;
 355        }
 356}
 357
 358static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 359                                       struct drm_crtc_state *old_state)
 360{
 361        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 362        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 363        int ret;
 364
 365        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 366
 367        ret = mtk_smi_larb_get(comp->larb_dev);
 368        if (ret) {
 369                DRM_ERROR("Failed to get larb: %d\n", ret);
 370                return;
 371        }
 372
 373        ret = mtk_crtc_ddp_hw_init(mtk_crtc);
 374        if (ret) {
 375                mtk_smi_larb_put(comp->larb_dev);
 376                return;
 377        }
 378
 379        drm_crtc_vblank_on(crtc);
 380        mtk_crtc->enabled = true;
 381}
 382
 383static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 384                                        struct drm_crtc_state *old_state)
 385{
 386        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 387        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 388        int i;
 389
 390        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 391        if (!mtk_crtc->enabled)
 392                return;
 393
 394        /* Set all pending plane state to disabled */
 395        for (i = 0; i < mtk_crtc->layer_nr; i++) {
 396                struct drm_plane *plane = &mtk_crtc->planes[i];
 397                struct mtk_plane_state *plane_state;
 398
 399                plane_state = to_mtk_plane_state(plane->state);
 400                plane_state->pending.enable = false;
 401                plane_state->pending.config = true;
 402        }
 403        mtk_crtc->pending_planes = true;
 404
 405        /* Wait for planes to be disabled */
 406        drm_crtc_wait_one_vblank(crtc);
 407
 408        drm_crtc_vblank_off(crtc);
 409        mtk_crtc_ddp_hw_fini(mtk_crtc);
 410        mtk_smi_larb_put(comp->larb_dev);
 411
 412        mtk_crtc->enabled = false;
 413}
 414
 415static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
 416                                      struct drm_crtc_state *old_crtc_state)
 417{
 418        struct mtk_crtc_state *state = to_mtk_crtc_state(crtc->state);
 419        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 420
 421        if (mtk_crtc->event && state->base.event)
 422                DRM_ERROR("new event while there is still a pending event\n");
 423
 424        if (state->base.event) {
 425                state->base.event->pipe = drm_crtc_index(crtc);
 426                WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 427                mtk_crtc->event = state->base.event;
 428                state->base.event = NULL;
 429        }
 430}
 431
 432static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 433                                      struct drm_crtc_state *old_crtc_state)
 434{
 435        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 436        struct mtk_drm_private *priv = crtc->dev->dev_private;
 437        unsigned int pending_planes = 0;
 438        int i;
 439
 440        if (mtk_crtc->event)
 441                mtk_crtc->pending_needs_vblank = true;
 442        for (i = 0; i < mtk_crtc->layer_nr; i++) {
 443                struct drm_plane *plane = &mtk_crtc->planes[i];
 444                struct mtk_plane_state *plane_state;
 445
 446                plane_state = to_mtk_plane_state(plane->state);
 447                if (plane_state->pending.dirty) {
 448                        plane_state->pending.config = true;
 449                        plane_state->pending.dirty = false;
 450                        pending_planes |= BIT(i);
 451                }
 452        }
 453        if (pending_planes)
 454                mtk_crtc->pending_planes = true;
 455        if (crtc->state->color_mgmt_changed)
 456                for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
 457                        mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
 458
 459        if (priv->data->shadow_register) {
 460                mtk_disp_mutex_acquire(mtk_crtc->mutex);
 461                mtk_crtc_ddp_config(crtc);
 462                mtk_disp_mutex_release(mtk_crtc->mutex);
 463        }
 464}
 465
 466static const struct drm_crtc_funcs mtk_crtc_funcs = {
 467        .set_config             = drm_atomic_helper_set_config,
 468        .page_flip              = drm_atomic_helper_page_flip,
 469        .destroy                = mtk_drm_crtc_destroy,
 470        .reset                  = mtk_drm_crtc_reset,
 471        .atomic_duplicate_state = mtk_drm_crtc_duplicate_state,
 472        .atomic_destroy_state   = mtk_drm_crtc_destroy_state,
 473        .gamma_set              = drm_atomic_helper_legacy_gamma_set,
 474        .enable_vblank          = mtk_drm_crtc_enable_vblank,
 475        .disable_vblank         = mtk_drm_crtc_disable_vblank,
 476};
 477
 478static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
 479        .mode_fixup     = mtk_drm_crtc_mode_fixup,
 480        .mode_set_nofb  = mtk_drm_crtc_mode_set_nofb,
 481        .atomic_begin   = mtk_drm_crtc_atomic_begin,
 482        .atomic_flush   = mtk_drm_crtc_atomic_flush,
 483        .atomic_enable  = mtk_drm_crtc_atomic_enable,
 484        .atomic_disable = mtk_drm_crtc_atomic_disable,
 485};
 486
 487static int mtk_drm_crtc_init(struct drm_device *drm,
 488                             struct mtk_drm_crtc *mtk_crtc,
 489                             struct drm_plane *primary,
 490                             struct drm_plane *cursor, unsigned int pipe)
 491{
 492        int ret;
 493
 494        ret = drm_crtc_init_with_planes(drm, &mtk_crtc->base, primary, cursor,
 495                                        &mtk_crtc_funcs, NULL);
 496        if (ret)
 497                goto err_cleanup_crtc;
 498
 499        drm_crtc_helper_add(&mtk_crtc->base, &mtk_crtc_helper_funcs);
 500
 501        return 0;
 502
 503err_cleanup_crtc:
 504        drm_crtc_cleanup(&mtk_crtc->base);
 505        return ret;
 506}
 507
 508void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp)
 509{
 510        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 511        struct mtk_drm_private *priv = crtc->dev->dev_private;
 512
 513        if (!priv->data->shadow_register)
 514                mtk_crtc_ddp_config(crtc);
 515
 516        mtk_drm_finish_page_flip(mtk_crtc);
 517}
 518
 519int mtk_drm_crtc_create(struct drm_device *drm_dev,
 520                        const enum mtk_ddp_comp_id *path, unsigned int path_len)
 521{
 522        struct mtk_drm_private *priv = drm_dev->dev_private;
 523        struct device *dev = drm_dev->dev;
 524        struct mtk_drm_crtc *mtk_crtc;
 525        enum drm_plane_type type;
 526        unsigned int zpos;
 527        int pipe = priv->num_pipes;
 528        int ret;
 529        int i;
 530
 531        if (!path)
 532                return 0;
 533
 534        for (i = 0; i < path_len; i++) {
 535                enum mtk_ddp_comp_id comp_id = path[i];
 536                struct device_node *node;
 537
 538                node = priv->comp_node[comp_id];
 539                if (!node) {
 540                        dev_info(dev,
 541                                 "Not creating crtc %d because component %d is disabled or missing\n",
 542                                 pipe, comp_id);
 543                        return 0;
 544                }
 545        }
 546
 547        mtk_crtc = devm_kzalloc(dev, sizeof(*mtk_crtc), GFP_KERNEL);
 548        if (!mtk_crtc)
 549                return -ENOMEM;
 550
 551        mtk_crtc->config_regs = priv->config_regs;
 552        mtk_crtc->ddp_comp_nr = path_len;
 553        mtk_crtc->ddp_comp = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr,
 554                                                sizeof(*mtk_crtc->ddp_comp),
 555                                                GFP_KERNEL);
 556        if (!mtk_crtc->ddp_comp)
 557                return -ENOMEM;
 558
 559        mtk_crtc->mutex = mtk_disp_mutex_get(priv->mutex_dev, pipe);
 560        if (IS_ERR(mtk_crtc->mutex)) {
 561                ret = PTR_ERR(mtk_crtc->mutex);
 562                dev_err(dev, "Failed to get mutex: %d\n", ret);
 563                return ret;
 564        }
 565
 566        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 567                enum mtk_ddp_comp_id comp_id = path[i];
 568                struct mtk_ddp_comp *comp;
 569                struct device_node *node;
 570
 571                node = priv->comp_node[comp_id];
 572                comp = priv->ddp_comp[comp_id];
 573                if (!comp) {
 574                        dev_err(dev, "Component %pOF not initialized\n", node);
 575                        ret = -ENODEV;
 576                        return ret;
 577                }
 578
 579                mtk_crtc->ddp_comp[i] = comp;
 580        }
 581
 582        mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]);
 583        mtk_crtc->planes = devm_kcalloc(dev, mtk_crtc->layer_nr,
 584                                        sizeof(struct drm_plane),
 585                                        GFP_KERNEL);
 586
 587        for (zpos = 0; zpos < mtk_crtc->layer_nr; zpos++) {
 588                type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY :
 589                                (zpos == 1) ? DRM_PLANE_TYPE_CURSOR :
 590                                                DRM_PLANE_TYPE_OVERLAY;
 591                ret = mtk_plane_init(drm_dev, &mtk_crtc->planes[zpos],
 592                                     BIT(pipe), type);
 593                if (ret)
 594                        return ret;
 595        }
 596
 597        ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, &mtk_crtc->planes[0],
 598                                mtk_crtc->layer_nr > 1 ? &mtk_crtc->planes[1] :
 599                                NULL, pipe);
 600        if (ret < 0)
 601                return ret;
 602        drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE);
 603        drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, MTK_LUT_SIZE);
 604        priv->num_pipes++;
 605
 606        return 0;
 607}
 608