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 <linux/clk.h>
   7#include <linux/dma-mapping.h>
   8#include <linux/mailbox_controller.h>
   9#include <linux/pm_runtime.h>
  10#include <linux/soc/mediatek/mtk-cmdq.h>
  11#include <linux/soc/mediatek/mtk-mmsys.h>
  12#include <linux/soc/mediatek/mtk-mutex.h>
  13
  14#include <asm/barrier.h>
  15
  16#include <drm/drm_atomic.h>
  17#include <drm/drm_atomic_helper.h>
  18#include <drm/drm_plane_helper.h>
  19#include <drm/drm_probe_helper.h>
  20#include <drm/drm_vblank.h>
  21
  22#include "mtk_drm_drv.h"
  23#include "mtk_drm_crtc.h"
  24#include "mtk_drm_ddp_comp.h"
  25#include "mtk_drm_gem.h"
  26#include "mtk_drm_plane.h"
  27
  28/*
  29 * struct mtk_drm_crtc - MediaTek specific crtc structure.
  30 * @base: crtc object.
  31 * @enabled: records whether crtc_enable succeeded
  32 * @planes: array of 4 drm_plane structures, one for each overlay plane
  33 * @pending_planes: whether any plane has pending changes to be applied
  34 * @mmsys_dev: pointer to the mmsys device for configuration registers
  35 * @mutex: handle to one of the ten disp_mutex streams
  36 * @ddp_comp_nr: number of components in ddp_comp
  37 * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
  38 *
  39 * TODO: Needs update: this header is missing a bunch of member descriptions.
  40 */
  41struct mtk_drm_crtc {
  42        struct drm_crtc                 base;
  43        bool                            enabled;
  44
  45        bool                            pending_needs_vblank;
  46        struct drm_pending_vblank_event *event;
  47
  48        struct drm_plane                *planes;
  49        unsigned int                    layer_nr;
  50        bool                            pending_planes;
  51        bool                            pending_async_planes;
  52
  53#if IS_REACHABLE(CONFIG_MTK_CMDQ)
  54        struct cmdq_client              cmdq_client;
  55        struct cmdq_pkt                 cmdq_handle;
  56        u32                             cmdq_event;
  57        u32                             cmdq_vblank_cnt;
  58        wait_queue_head_t               cb_blocking_queue;
  59#endif
  60
  61        struct device                   *mmsys_dev;
  62        struct mtk_mutex                *mutex;
  63        unsigned int                    ddp_comp_nr;
  64        struct mtk_ddp_comp             **ddp_comp;
  65
  66        /* lock for display hardware access */
  67        struct mutex                    hw_lock;
  68        bool                            config_updating;
  69};
  70
  71struct mtk_crtc_state {
  72        struct drm_crtc_state           base;
  73
  74        bool                            pending_config;
  75        unsigned int                    pending_width;
  76        unsigned int                    pending_height;
  77        unsigned int                    pending_vrefresh;
  78};
  79
  80static inline struct mtk_drm_crtc *to_mtk_crtc(struct drm_crtc *c)
  81{
  82        return container_of(c, struct mtk_drm_crtc, base);
  83}
  84
  85static inline struct mtk_crtc_state *to_mtk_crtc_state(struct drm_crtc_state *s)
  86{
  87        return container_of(s, struct mtk_crtc_state, base);
  88}
  89
  90static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
  91{
  92        struct drm_crtc *crtc = &mtk_crtc->base;
  93        unsigned long flags;
  94
  95        spin_lock_irqsave(&crtc->dev->event_lock, flags);
  96        drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
  97        drm_crtc_vblank_put(crtc);
  98        mtk_crtc->event = NULL;
  99        spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 100}
 101
 102static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
 103{
 104        drm_crtc_handle_vblank(&mtk_crtc->base);
 105        if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
 106                mtk_drm_crtc_finish_page_flip(mtk_crtc);
 107                mtk_crtc->pending_needs_vblank = false;
 108        }
 109}
 110
 111#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 112static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
 113                                   size_t size)
 114{
 115        struct device *dev;
 116        dma_addr_t dma_addr;
 117
 118        pkt->va_base = kzalloc(size, GFP_KERNEL);
 119        if (!pkt->va_base) {
 120                kfree(pkt);
 121                return -ENOMEM;
 122        }
 123        pkt->buf_size = size;
 124        pkt->cl = (void *)client;
 125
 126        dev = client->chan->mbox->dev;
 127        dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
 128                                  DMA_TO_DEVICE);
 129        if (dma_mapping_error(dev, dma_addr)) {
 130                dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
 131                kfree(pkt->va_base);
 132                kfree(pkt);
 133                return -ENOMEM;
 134        }
 135
 136        pkt->pa_base = dma_addr;
 137
 138        return 0;
 139}
 140
 141static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
 142{
 143        struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
 144
 145        dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
 146                         DMA_TO_DEVICE);
 147        kfree(pkt->va_base);
 148        kfree(pkt);
 149}
 150#endif
 151
 152static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
 153{
 154        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 155
 156        mtk_mutex_put(mtk_crtc->mutex);
 157#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 158        mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
 159
 160        if (mtk_crtc->cmdq_client.chan) {
 161                mbox_free_channel(mtk_crtc->cmdq_client.chan);
 162                mtk_crtc->cmdq_client.chan = NULL;
 163        }
 164#endif
 165        drm_crtc_cleanup(crtc);
 166}
 167
 168static void mtk_drm_crtc_reset(struct drm_crtc *crtc)
 169{
 170        struct mtk_crtc_state *state;
 171
 172        if (crtc->state)
 173                __drm_atomic_helper_crtc_destroy_state(crtc->state);
 174
 175        kfree(to_mtk_crtc_state(crtc->state));
 176        crtc->state = NULL;
 177
 178        state = kzalloc(sizeof(*state), GFP_KERNEL);
 179        if (state)
 180                __drm_atomic_helper_crtc_reset(crtc, &state->base);
 181}
 182
 183static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc)
 184{
 185        struct mtk_crtc_state *state;
 186
 187        state = kzalloc(sizeof(*state), GFP_KERNEL);
 188        if (!state)
 189                return NULL;
 190
 191        __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
 192
 193        WARN_ON(state->base.crtc != crtc);
 194        state->base.crtc = crtc;
 195
 196        return &state->base;
 197}
 198
 199static void mtk_drm_crtc_destroy_state(struct drm_crtc *crtc,
 200                                       struct drm_crtc_state *state)
 201{
 202        __drm_atomic_helper_crtc_destroy_state(state);
 203        kfree(to_mtk_crtc_state(state));
 204}
 205
 206static bool mtk_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 207                                    const struct drm_display_mode *mode,
 208                                    struct drm_display_mode *adjusted_mode)
 209{
 210        /* Nothing to do here, but this callback is mandatory. */
 211        return true;
 212}
 213
 214static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 215{
 216        struct mtk_crtc_state *state = to_mtk_crtc_state(crtc->state);
 217
 218        state->pending_width = crtc->mode.hdisplay;
 219        state->pending_height = crtc->mode.vdisplay;
 220        state->pending_vrefresh = drm_mode_vrefresh(&crtc->mode);
 221        wmb();  /* Make sure the above parameters are set before update */
 222        state->pending_config = true;
 223}
 224
 225static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
 226{
 227        int ret;
 228        int i;
 229
 230        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 231                ret = mtk_ddp_comp_clk_enable(mtk_crtc->ddp_comp[i]);
 232                if (ret) {
 233                        DRM_ERROR("Failed to enable clock %d: %d\n", i, ret);
 234                        goto err;
 235                }
 236        }
 237
 238        return 0;
 239err:
 240        while (--i >= 0)
 241                mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
 242        return ret;
 243}
 244
 245static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
 246{
 247        int i;
 248
 249        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
 250                mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
 251}
 252
 253static
 254struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
 255                                                struct drm_plane *plane,
 256                                                unsigned int *local_layer)
 257{
 258        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 259        struct mtk_ddp_comp *comp;
 260        int i, count = 0;
 261        unsigned int local_index = plane - mtk_crtc->planes;
 262
 263        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 264                comp = mtk_crtc->ddp_comp[i];
 265                if (local_index < (count + mtk_ddp_comp_layer_nr(comp))) {
 266                        *local_layer = local_index - count;
 267                        return comp;
 268                }
 269                count += mtk_ddp_comp_layer_nr(comp);
 270        }
 271
 272        WARN(1, "Failed to find component for plane %d\n", plane->index);
 273        return NULL;
 274}
 275
 276#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 277static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 278{
 279        struct cmdq_cb_data *data = mssg;
 280        struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, client);
 281        struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client);
 282        struct mtk_crtc_state *state;
 283        unsigned int i;
 284
 285        if (data->sta < 0)
 286                return;
 287
 288        state = to_mtk_crtc_state(mtk_crtc->base.state);
 289
 290        state->pending_config = false;
 291
 292        if (mtk_crtc->pending_planes) {
 293                for (i = 0; i < mtk_crtc->layer_nr; i++) {
 294                        struct drm_plane *plane = &mtk_crtc->planes[i];
 295                        struct mtk_plane_state *plane_state;
 296
 297                        plane_state = to_mtk_plane_state(plane->state);
 298
 299                        plane_state->pending.config = false;
 300                }
 301                mtk_crtc->pending_planes = false;
 302        }
 303
 304        if (mtk_crtc->pending_async_planes) {
 305                for (i = 0; i < mtk_crtc->layer_nr; i++) {
 306                        struct drm_plane *plane = &mtk_crtc->planes[i];
 307                        struct mtk_plane_state *plane_state;
 308
 309                        plane_state = to_mtk_plane_state(plane->state);
 310
 311                        plane_state->pending.async_config = false;
 312                }
 313                mtk_crtc->pending_async_planes = false;
 314        }
 315
 316        mtk_crtc->cmdq_vblank_cnt = 0;
 317        wake_up(&mtk_crtc->cb_blocking_queue);
 318}
 319#endif
 320
 321static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 322{
 323        struct drm_crtc *crtc = &mtk_crtc->base;
 324        struct drm_connector *connector;
 325        struct drm_encoder *encoder;
 326        struct drm_connector_list_iter conn_iter;
 327        unsigned int width, height, vrefresh, bpc = MTK_MAX_BPC;
 328        int ret;
 329        int i;
 330
 331        if (WARN_ON(!crtc->state))
 332                return -EINVAL;
 333
 334        width = crtc->state->adjusted_mode.hdisplay;
 335        height = crtc->state->adjusted_mode.vdisplay;
 336        vrefresh = drm_mode_vrefresh(&crtc->state->adjusted_mode);
 337
 338        drm_for_each_encoder(encoder, crtc->dev) {
 339                if (encoder->crtc != crtc)
 340                        continue;
 341
 342                drm_connector_list_iter_begin(crtc->dev, &conn_iter);
 343                drm_for_each_connector_iter(connector, &conn_iter) {
 344                        if (connector->encoder != encoder)
 345                                continue;
 346                        if (connector->display_info.bpc != 0 &&
 347                            bpc > connector->display_info.bpc)
 348                                bpc = connector->display_info.bpc;
 349                }
 350                drm_connector_list_iter_end(&conn_iter);
 351        }
 352
 353        ret = pm_runtime_resume_and_get(crtc->dev->dev);
 354        if (ret < 0) {
 355                DRM_ERROR("Failed to enable power domain: %d\n", ret);
 356                return ret;
 357        }
 358
 359        ret = mtk_mutex_prepare(mtk_crtc->mutex);
 360        if (ret < 0) {
 361                DRM_ERROR("Failed to enable mutex clock: %d\n", ret);
 362                goto err_pm_runtime_put;
 363        }
 364
 365        ret = mtk_crtc_ddp_clk_enable(mtk_crtc);
 366        if (ret < 0) {
 367                DRM_ERROR("Failed to enable component clocks: %d\n", ret);
 368                goto err_mutex_unprepare;
 369        }
 370
 371        for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
 372                mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,
 373                                      mtk_crtc->ddp_comp[i]->id,
 374                                      mtk_crtc->ddp_comp[i + 1]->id);
 375                mtk_mutex_add_comp(mtk_crtc->mutex,
 376                                        mtk_crtc->ddp_comp[i]->id);
 377        }
 378        mtk_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
 379        mtk_mutex_enable(mtk_crtc->mutex);
 380
 381        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 382                struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
 383
 384                if (i == 1)
 385                        mtk_ddp_comp_bgclr_in_on(comp);
 386
 387                mtk_ddp_comp_config(comp, width, height, vrefresh, bpc, NULL);
 388                mtk_ddp_comp_start(comp);
 389        }
 390
 391        /* Initially configure all planes */
 392        for (i = 0; i < mtk_crtc->layer_nr; i++) {
 393                struct drm_plane *plane = &mtk_crtc->planes[i];
 394                struct mtk_plane_state *plane_state;
 395                struct mtk_ddp_comp *comp;
 396                unsigned int local_layer;
 397
 398                plane_state = to_mtk_plane_state(plane->state);
 399                comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
 400                if (comp)
 401                        mtk_ddp_comp_layer_config(comp, local_layer,
 402                                                  plane_state, NULL);
 403        }
 404
 405        return 0;
 406
 407err_mutex_unprepare:
 408        mtk_mutex_unprepare(mtk_crtc->mutex);
 409err_pm_runtime_put:
 410        pm_runtime_put(crtc->dev->dev);
 411        return ret;
 412}
 413
 414static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
 415{
 416        struct drm_device *drm = mtk_crtc->base.dev;
 417        struct drm_crtc *crtc = &mtk_crtc->base;
 418        int i;
 419
 420        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 421                mtk_ddp_comp_stop(mtk_crtc->ddp_comp[i]);
 422                if (i == 1)
 423                        mtk_ddp_comp_bgclr_in_off(mtk_crtc->ddp_comp[i]);
 424        }
 425
 426        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
 427                mtk_mutex_remove_comp(mtk_crtc->mutex,
 428                                           mtk_crtc->ddp_comp[i]->id);
 429        mtk_mutex_disable(mtk_crtc->mutex);
 430        for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
 431                mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev,
 432                                         mtk_crtc->ddp_comp[i]->id,
 433                                         mtk_crtc->ddp_comp[i + 1]->id);
 434                mtk_mutex_remove_comp(mtk_crtc->mutex,
 435                                           mtk_crtc->ddp_comp[i]->id);
 436        }
 437        mtk_mutex_remove_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);
 438        mtk_crtc_ddp_clk_disable(mtk_crtc);
 439        mtk_mutex_unprepare(mtk_crtc->mutex);
 440
 441        pm_runtime_put(drm->dev);
 442
 443        if (crtc->state->event && !crtc->state->active) {
 444                spin_lock_irq(&crtc->dev->event_lock);
 445                drm_crtc_send_vblank_event(crtc, crtc->state->event);
 446                crtc->state->event = NULL;
 447                spin_unlock_irq(&crtc->dev->event_lock);
 448        }
 449}
 450
 451static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 452                                struct cmdq_pkt *cmdq_handle)
 453{
 454        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 455        struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
 456        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 457        unsigned int i;
 458        unsigned int local_layer;
 459
 460        /*
 461         * TODO: instead of updating the registers here, we should prepare
 462         * working registers in atomic_commit and let the hardware command
 463         * queue update module registers on vblank.
 464         */
 465        if (state->pending_config) {
 466                mtk_ddp_comp_config(comp, state->pending_width,
 467                                    state->pending_height,
 468                                    state->pending_vrefresh, 0,
 469                                    cmdq_handle);
 470
 471                if (!cmdq_handle)
 472                        state->pending_config = false;
 473        }
 474
 475        if (mtk_crtc->pending_planes) {
 476                for (i = 0; i < mtk_crtc->layer_nr; i++) {
 477                        struct drm_plane *plane = &mtk_crtc->planes[i];
 478                        struct mtk_plane_state *plane_state;
 479
 480                        plane_state = to_mtk_plane_state(plane->state);
 481
 482                        if (!plane_state->pending.config)
 483                                continue;
 484
 485                        comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
 486                                                          &local_layer);
 487
 488                        if (comp)
 489                                mtk_ddp_comp_layer_config(comp, local_layer,
 490                                                          plane_state,
 491                                                          cmdq_handle);
 492                        if (!cmdq_handle)
 493                                plane_state->pending.config = false;
 494                }
 495
 496                if (!cmdq_handle)
 497                        mtk_crtc->pending_planes = false;
 498        }
 499
 500        if (mtk_crtc->pending_async_planes) {
 501                for (i = 0; i < mtk_crtc->layer_nr; i++) {
 502                        struct drm_plane *plane = &mtk_crtc->planes[i];
 503                        struct mtk_plane_state *plane_state;
 504
 505                        plane_state = to_mtk_plane_state(plane->state);
 506
 507                        if (!plane_state->pending.async_config)
 508                                continue;
 509
 510                        comp = mtk_drm_ddp_comp_for_plane(crtc, plane,
 511                                                          &local_layer);
 512
 513                        if (comp)
 514                                mtk_ddp_comp_layer_config(comp, local_layer,
 515                                                          plane_state,
 516                                                          cmdq_handle);
 517                        if (!cmdq_handle)
 518                                plane_state->pending.async_config = false;
 519                }
 520
 521                if (!cmdq_handle)
 522                        mtk_crtc->pending_async_planes = false;
 523        }
 524}
 525
 526static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
 527                                       bool needs_vblank)
 528{
 529#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 530        struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle;
 531#endif
 532        struct drm_crtc *crtc = &mtk_crtc->base;
 533        struct mtk_drm_private *priv = crtc->dev->dev_private;
 534        unsigned int pending_planes = 0, pending_async_planes = 0;
 535        int i;
 536
 537        mutex_lock(&mtk_crtc->hw_lock);
 538        mtk_crtc->config_updating = true;
 539        if (needs_vblank)
 540                mtk_crtc->pending_needs_vblank = true;
 541
 542        for (i = 0; i < mtk_crtc->layer_nr; i++) {
 543                struct drm_plane *plane = &mtk_crtc->planes[i];
 544                struct mtk_plane_state *plane_state;
 545
 546                plane_state = to_mtk_plane_state(plane->state);
 547                if (plane_state->pending.dirty) {
 548                        plane_state->pending.config = true;
 549                        plane_state->pending.dirty = false;
 550                        pending_planes |= BIT(i);
 551                } else if (plane_state->pending.async_dirty) {
 552                        plane_state->pending.async_config = true;
 553                        plane_state->pending.async_dirty = false;
 554                        pending_async_planes |= BIT(i);
 555                }
 556        }
 557        if (pending_planes)
 558                mtk_crtc->pending_planes = true;
 559        if (pending_async_planes)
 560                mtk_crtc->pending_async_planes = true;
 561
 562        if (priv->data->shadow_register) {
 563                mtk_mutex_acquire(mtk_crtc->mutex);
 564                mtk_crtc_ddp_config(crtc, NULL);
 565                mtk_mutex_release(mtk_crtc->mutex);
 566        }
 567#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 568        if (mtk_crtc->cmdq_client.chan) {
 569                mbox_flush(mtk_crtc->cmdq_client.chan, 2000);
 570                cmdq_handle->cmd_buf_size = 0;
 571                cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
 572                cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
 573                mtk_crtc_ddp_config(crtc, cmdq_handle);
 574                cmdq_pkt_finalize(cmdq_handle);
 575                dma_sync_single_for_device(mtk_crtc->cmdq_client.chan->mbox->dev,
 576                                           cmdq_handle->pa_base,
 577                                           cmdq_handle->cmd_buf_size,
 578                                           DMA_TO_DEVICE);
 579                /*
 580                 * CMDQ command should execute in next 3 vblank.
 581                 * One vblank interrupt before send message (occasionally)
 582                 * and one vblank interrupt after cmdq done,
 583                 * so it's timeout after 3 vblank interrupt.
 584                 * If it fail to execute in next 3 vblank, timeout happen.
 585                 */
 586                mtk_crtc->cmdq_vblank_cnt = 3;
 587
 588                mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
 589                mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
 590        }
 591#endif
 592        mtk_crtc->config_updating = false;
 593        mutex_unlock(&mtk_crtc->hw_lock);
 594}
 595
 596static void mtk_crtc_ddp_irq(void *data)
 597{
 598        struct drm_crtc *crtc = data;
 599        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 600        struct mtk_drm_private *priv = crtc->dev->dev_private;
 601
 602#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 603        if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
 604                mtk_crtc_ddp_config(crtc, NULL);
 605        else if (mtk_crtc->cmdq_vblank_cnt > 0 && --mtk_crtc->cmdq_vblank_cnt == 0)
 606                DRM_ERROR("mtk_crtc %d CMDQ execute command timeout!\n",
 607                          drm_crtc_index(&mtk_crtc->base));
 608#else
 609        if (!priv->data->shadow_register)
 610                mtk_crtc_ddp_config(crtc, NULL);
 611#endif
 612        mtk_drm_finish_page_flip(mtk_crtc);
 613}
 614
 615static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 616{
 617        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 618        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 619
 620        mtk_ddp_comp_enable_vblank(comp, mtk_crtc_ddp_irq, &mtk_crtc->base);
 621
 622        return 0;
 623}
 624
 625static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)
 626{
 627        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 628        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 629
 630        mtk_ddp_comp_disable_vblank(comp);
 631}
 632
 633int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
 634                             struct mtk_plane_state *state)
 635{
 636        unsigned int local_layer;
 637        struct mtk_ddp_comp *comp;
 638
 639        comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
 640        if (comp)
 641                return mtk_ddp_comp_layer_check(comp, local_layer, state);
 642        return 0;
 643}
 644
 645void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
 646                               struct drm_atomic_state *state)
 647{
 648        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 649
 650        if (!mtk_crtc->enabled)
 651                return;
 652
 653        mtk_drm_crtc_update_config(mtk_crtc, false);
 654}
 655
 656static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 657                                       struct drm_atomic_state *state)
 658{
 659        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 660        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 661        int ret;
 662
 663        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 664
 665        ret = pm_runtime_resume_and_get(comp->dev);
 666        if (ret < 0) {
 667                DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);
 668                return;
 669        }
 670
 671        ret = mtk_crtc_ddp_hw_init(mtk_crtc);
 672        if (ret) {
 673                pm_runtime_put(comp->dev);
 674                return;
 675        }
 676
 677        drm_crtc_vblank_on(crtc);
 678        mtk_crtc->enabled = true;
 679}
 680
 681static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 682                                        struct drm_atomic_state *state)
 683{
 684        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 685        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 686        int i, ret;
 687
 688        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 689        if (!mtk_crtc->enabled)
 690                return;
 691
 692        /* Set all pending plane state to disabled */
 693        for (i = 0; i < mtk_crtc->layer_nr; i++) {
 694                struct drm_plane *plane = &mtk_crtc->planes[i];
 695                struct mtk_plane_state *plane_state;
 696
 697                plane_state = to_mtk_plane_state(plane->state);
 698                plane_state->pending.enable = false;
 699                plane_state->pending.config = true;
 700        }
 701        mtk_crtc->pending_planes = true;
 702
 703        mtk_drm_crtc_update_config(mtk_crtc, false);
 704#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 705        /* Wait for planes to be disabled by cmdq */
 706        if (mtk_crtc->cmdq_client.chan)
 707                wait_event_timeout(mtk_crtc->cb_blocking_queue,
 708                                   mtk_crtc->cmdq_vblank_cnt == 0,
 709                                   msecs_to_jiffies(500));
 710#endif
 711        /* Wait for planes to be disabled */
 712        drm_crtc_wait_one_vblank(crtc);
 713
 714        drm_crtc_vblank_off(crtc);
 715        mtk_crtc_ddp_hw_fini(mtk_crtc);
 716        ret = pm_runtime_put(comp->dev);
 717        if (ret < 0)
 718                DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", ret);
 719
 720        mtk_crtc->enabled = false;
 721}
 722
 723static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
 724                                      struct drm_atomic_state *state)
 725{
 726        struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
 727                                                                          crtc);
 728        struct mtk_crtc_state *mtk_crtc_state = to_mtk_crtc_state(crtc_state);
 729        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 730
 731        if (mtk_crtc->event && mtk_crtc_state->base.event)
 732                DRM_ERROR("new event while there is still a pending event\n");
 733
 734        if (mtk_crtc_state->base.event) {
 735                mtk_crtc_state->base.event->pipe = drm_crtc_index(crtc);
 736                WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 737                mtk_crtc->event = mtk_crtc_state->base.event;
 738                mtk_crtc_state->base.event = NULL;
 739        }
 740}
 741
 742static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 743                                      struct drm_atomic_state *state)
 744{
 745        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 746        int i;
 747
 748        if (crtc->state->color_mgmt_changed)
 749                for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 750                        mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
 751                        mtk_ddp_ctm_set(mtk_crtc->ddp_comp[i], crtc->state);
 752                }
 753        mtk_drm_crtc_update_config(mtk_crtc, !!mtk_crtc->event);
 754}
 755
 756static const struct drm_crtc_funcs mtk_crtc_funcs = {
 757        .set_config             = drm_atomic_helper_set_config,
 758        .page_flip              = drm_atomic_helper_page_flip,
 759        .destroy                = mtk_drm_crtc_destroy,
 760        .reset                  = mtk_drm_crtc_reset,
 761        .atomic_duplicate_state = mtk_drm_crtc_duplicate_state,
 762        .atomic_destroy_state   = mtk_drm_crtc_destroy_state,
 763        .enable_vblank          = mtk_drm_crtc_enable_vblank,
 764        .disable_vblank         = mtk_drm_crtc_disable_vblank,
 765};
 766
 767static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
 768        .mode_fixup     = mtk_drm_crtc_mode_fixup,
 769        .mode_set_nofb  = mtk_drm_crtc_mode_set_nofb,
 770        .atomic_begin   = mtk_drm_crtc_atomic_begin,
 771        .atomic_flush   = mtk_drm_crtc_atomic_flush,
 772        .atomic_enable  = mtk_drm_crtc_atomic_enable,
 773        .atomic_disable = mtk_drm_crtc_atomic_disable,
 774};
 775
 776static int mtk_drm_crtc_init(struct drm_device *drm,
 777                             struct mtk_drm_crtc *mtk_crtc,
 778                             unsigned int pipe)
 779{
 780        struct drm_plane *primary = NULL;
 781        struct drm_plane *cursor = NULL;
 782        int i, ret;
 783
 784        for (i = 0; i < mtk_crtc->layer_nr; i++) {
 785                if (mtk_crtc->planes[i].type == DRM_PLANE_TYPE_PRIMARY)
 786                        primary = &mtk_crtc->planes[i];
 787                else if (mtk_crtc->planes[i].type == DRM_PLANE_TYPE_CURSOR)
 788                        cursor = &mtk_crtc->planes[i];
 789        }
 790
 791        ret = drm_crtc_init_with_planes(drm, &mtk_crtc->base, primary, cursor,
 792                                        &mtk_crtc_funcs, NULL);
 793        if (ret)
 794                goto err_cleanup_crtc;
 795
 796        drm_crtc_helper_add(&mtk_crtc->base, &mtk_crtc_helper_funcs);
 797
 798        return 0;
 799
 800err_cleanup_crtc:
 801        drm_crtc_cleanup(&mtk_crtc->base);
 802        return ret;
 803}
 804
 805static int mtk_drm_crtc_num_comp_planes(struct mtk_drm_crtc *mtk_crtc,
 806                                        int comp_idx)
 807{
 808        struct mtk_ddp_comp *comp;
 809
 810        if (comp_idx > 1)
 811                return 0;
 812
 813        comp = mtk_crtc->ddp_comp[comp_idx];
 814        if (!comp->funcs)
 815                return 0;
 816
 817        if (comp_idx == 1 && !comp->funcs->bgclr_in_on)
 818                return 0;
 819
 820        return mtk_ddp_comp_layer_nr(comp);
 821}
 822
 823static inline
 824enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx,
 825                                            unsigned int num_planes)
 826{
 827        if (plane_idx == 0)
 828                return DRM_PLANE_TYPE_PRIMARY;
 829        else if (plane_idx == (num_planes - 1))
 830                return DRM_PLANE_TYPE_CURSOR;
 831        else
 832                return DRM_PLANE_TYPE_OVERLAY;
 833
 834}
 835
 836static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 837                                         struct mtk_drm_crtc *mtk_crtc,
 838                                         int comp_idx, int pipe)
 839{
 840        int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx);
 841        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx];
 842        int i, ret;
 843
 844        for (i = 0; i < num_planes; i++) {
 845                ret = mtk_plane_init(drm_dev,
 846                                &mtk_crtc->planes[mtk_crtc->layer_nr],
 847                                BIT(pipe),
 848                                mtk_drm_crtc_plane_type(mtk_crtc->layer_nr,
 849                                                        num_planes),
 850                                mtk_ddp_comp_supported_rotations(comp));
 851                if (ret)
 852                        return ret;
 853
 854                mtk_crtc->layer_nr++;
 855        }
 856        return 0;
 857}
 858
 859int mtk_drm_crtc_create(struct drm_device *drm_dev,
 860                        const enum mtk_ddp_comp_id *path, unsigned int path_len)
 861{
 862        struct mtk_drm_private *priv = drm_dev->dev_private;
 863        struct device *dev = drm_dev->dev;
 864        struct mtk_drm_crtc *mtk_crtc;
 865        unsigned int num_comp_planes = 0;
 866        int pipe = priv->num_pipes;
 867        int ret;
 868        int i;
 869        bool has_ctm = false;
 870        uint gamma_lut_size = 0;
 871
 872        if (!path)
 873                return 0;
 874
 875        for (i = 0; i < path_len; i++) {
 876                enum mtk_ddp_comp_id comp_id = path[i];
 877                struct device_node *node;
 878                struct mtk_ddp_comp *comp;
 879
 880                node = priv->comp_node[comp_id];
 881                comp = &priv->ddp_comp[comp_id];
 882
 883                if (!node) {
 884                        dev_info(dev,
 885                                 "Not creating crtc %d because component %d is disabled or missing\n",
 886                                 pipe, comp_id);
 887                        return 0;
 888                }
 889
 890                if (!comp->dev) {
 891                        dev_err(dev, "Component %pOF not initialized\n", node);
 892                        return -ENODEV;
 893                }
 894        }
 895
 896        mtk_crtc = devm_kzalloc(dev, sizeof(*mtk_crtc), GFP_KERNEL);
 897        if (!mtk_crtc)
 898                return -ENOMEM;
 899
 900        mtk_crtc->mmsys_dev = priv->mmsys_dev;
 901        mtk_crtc->ddp_comp_nr = path_len;
 902        mtk_crtc->ddp_comp = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr,
 903                                                sizeof(*mtk_crtc->ddp_comp),
 904                                                GFP_KERNEL);
 905        if (!mtk_crtc->ddp_comp)
 906                return -ENOMEM;
 907
 908        mtk_crtc->mutex = mtk_mutex_get(priv->mutex_dev);
 909        if (IS_ERR(mtk_crtc->mutex)) {
 910                ret = PTR_ERR(mtk_crtc->mutex);
 911                dev_err(dev, "Failed to get mutex: %d\n", ret);
 912                return ret;
 913        }
 914
 915        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 916                enum mtk_ddp_comp_id comp_id = path[i];
 917                struct mtk_ddp_comp *comp;
 918
 919                comp = &priv->ddp_comp[comp_id];
 920                mtk_crtc->ddp_comp[i] = comp;
 921
 922                if (comp->funcs) {
 923                        if (comp->funcs->gamma_set)
 924                                gamma_lut_size = MTK_LUT_SIZE;
 925
 926                        if (comp->funcs->ctm_set)
 927                                has_ctm = true;
 928                }
 929        }
 930
 931        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
 932                num_comp_planes += mtk_drm_crtc_num_comp_planes(mtk_crtc, i);
 933
 934        mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes,
 935                                        sizeof(struct drm_plane), GFP_KERNEL);
 936
 937        for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 938                ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
 939                                                    pipe);
 940                if (ret)
 941                        return ret;
 942        }
 943
 944        ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
 945        if (ret < 0)
 946                return ret;
 947
 948        if (gamma_lut_size)
 949                drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
 950        drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
 951        priv->num_pipes++;
 952        mutex_init(&mtk_crtc->hw_lock);
 953
 954#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 955        mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;
 956        mtk_crtc->cmdq_client.client.tx_block = false;
 957        mtk_crtc->cmdq_client.client.knows_txdone = true;
 958        mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;
 959        mtk_crtc->cmdq_client.chan =
 960                        mbox_request_channel(&mtk_crtc->cmdq_client.client,
 961                                             drm_crtc_index(&mtk_crtc->base));
 962        if (IS_ERR(mtk_crtc->cmdq_client.chan)) {
 963                dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
 964                        drm_crtc_index(&mtk_crtc->base));
 965                mtk_crtc->cmdq_client.chan = NULL;
 966        }
 967
 968        if (mtk_crtc->cmdq_client.chan) {
 969                ret = of_property_read_u32_index(priv->mutex_node,
 970                                                 "mediatek,gce-events",
 971                                                 drm_crtc_index(&mtk_crtc->base),
 972                                                 &mtk_crtc->cmdq_event);
 973                if (ret) {
 974                        dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
 975                                drm_crtc_index(&mtk_crtc->base));
 976                        mbox_free_channel(mtk_crtc->cmdq_client.chan);
 977                        mtk_crtc->cmdq_client.chan = NULL;
 978                } else {
 979                        ret = mtk_drm_cmdq_pkt_create(&mtk_crtc->cmdq_client,
 980                                                      &mtk_crtc->cmdq_handle,
 981                                                      PAGE_SIZE);
 982                        if (ret) {
 983                                dev_dbg(dev, "mtk_crtc %d failed to create cmdq packet\n",
 984                                        drm_crtc_index(&mtk_crtc->base));
 985                                mbox_free_channel(mtk_crtc->cmdq_client.chan);
 986                                mtk_crtc->cmdq_client.chan = NULL;
 987                        }
 988                }
 989
 990                /* for sending blocking cmd in crtc disable */
 991                init_waitqueue_head(&mtk_crtc->cb_blocking_queue);
 992        }
 993#endif
 994        return 0;
 995}
 996