linux/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
<<
>>
Prefs
   1/*
   2 * rcar_du_crtc.c  --  R-Car Display Unit CRTCs
   3 *
   4 * Copyright (C) 2013-2015 Renesas Electronics Corporation
   5 *
   6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 */
  13
  14#include <linux/clk.h>
  15#include <linux/mutex.h>
  16#include <linux/sys_soc.h>
  17
  18#include <drm/drmP.h>
  19#include <drm/drm_atomic.h>
  20#include <drm/drm_atomic_helper.h>
  21#include <drm/drm_crtc.h>
  22#include <drm/drm_crtc_helper.h>
  23#include <drm/drm_fb_cma_helper.h>
  24#include <drm/drm_gem_cma_helper.h>
  25#include <drm/drm_plane_helper.h>
  26
  27#include "rcar_du_crtc.h"
  28#include "rcar_du_drv.h"
  29#include "rcar_du_kms.h"
  30#include "rcar_du_plane.h"
  31#include "rcar_du_regs.h"
  32#include "rcar_du_vsp.h"
  33
  34static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
  35{
  36        struct rcar_du_device *rcdu = rcrtc->group->dev;
  37
  38        return rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
  39}
  40
  41static void rcar_du_crtc_write(struct rcar_du_crtc *rcrtc, u32 reg, u32 data)
  42{
  43        struct rcar_du_device *rcdu = rcrtc->group->dev;
  44
  45        rcar_du_write(rcdu, rcrtc->mmio_offset + reg, data);
  46}
  47
  48static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr)
  49{
  50        struct rcar_du_device *rcdu = rcrtc->group->dev;
  51
  52        rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
  53                      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
  54}
  55
  56static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
  57{
  58        struct rcar_du_device *rcdu = rcrtc->group->dev;
  59
  60        rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
  61                      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
  62}
  63
  64static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
  65                                 u32 clr, u32 set)
  66{
  67        struct rcar_du_device *rcdu = rcrtc->group->dev;
  68        u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
  69
  70        rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
  71}
  72
  73static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
  74{
  75        int ret;
  76
  77        ret = clk_prepare_enable(rcrtc->clock);
  78        if (ret < 0)
  79                return ret;
  80
  81        ret = clk_prepare_enable(rcrtc->extclock);
  82        if (ret < 0)
  83                goto error_clock;
  84
  85        ret = rcar_du_group_get(rcrtc->group);
  86        if (ret < 0)
  87                goto error_group;
  88
  89        return 0;
  90
  91error_group:
  92        clk_disable_unprepare(rcrtc->extclock);
  93error_clock:
  94        clk_disable_unprepare(rcrtc->clock);
  95        return ret;
  96}
  97
  98static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
  99{
 100        rcar_du_group_put(rcrtc->group);
 101
 102        clk_disable_unprepare(rcrtc->extclock);
 103        clk_disable_unprepare(rcrtc->clock);
 104}
 105
 106/* -----------------------------------------------------------------------------
 107 * Hardware Setup
 108 */
 109
 110struct dpll_info {
 111        unsigned int output;
 112        unsigned int fdpll;
 113        unsigned int n;
 114        unsigned int m;
 115};
 116
 117static void rcar_du_dpll_divider(struct rcar_du_crtc *rcrtc,
 118                                 struct dpll_info *dpll,
 119                                 unsigned long input,
 120                                 unsigned long target)
 121{
 122        unsigned long best_diff = (unsigned long)-1;
 123        unsigned long diff;
 124        unsigned int fdpll;
 125        unsigned int m;
 126        unsigned int n;
 127
 128        /*
 129         *   fin                                 fvco        fout       fclkout
 130         * in --> [1/M] --> |PD| -> [LPF] -> [VCO] -> [1/P] -+-> [1/FDPLL] -> out
 131         *              +-> |  |                             |
 132         *              |                                    |
 133         *              +---------------- [1/N] <------------+
 134         *
 135         *      fclkout = fvco / P / FDPLL -- (1)
 136         *
 137         * fin/M = fvco/P/N
 138         *
 139         *      fvco = fin * P *  N / M -- (2)
 140         *
 141         * (1) + (2) indicates
 142         *
 143         *      fclkout = fin * N / M / FDPLL
 144         *
 145         * NOTES
 146         *      N       : (n + 1)
 147         *      M       : (m + 1)
 148         *      FDPLL   : (fdpll + 1)
 149         *      P       : 2
 150         *      2kHz < fvco < 4096MHz
 151         *
 152         * To minimize the jitter,
 153         * N : as large as possible
 154         * M : as small as possible
 155         */
 156        for (m = 0; m < 4; m++) {
 157                for (n = 119; n > 38; n--) {
 158                        /*
 159                         * This code only runs on 64-bit architectures, the
 160                         * unsigned long type can thus be used for 64-bit
 161                         * computation. It will still compile without any
 162                         * warning on 32-bit architectures.
 163                         *
 164                         * To optimize calculations, use fout instead of fvco
 165                         * to verify the VCO frequency constraint.
 166                         */
 167                        unsigned long fout = input * (n + 1) / (m + 1);
 168
 169                        if (fout < 1000 || fout > 2048 * 1000 * 1000U)
 170                                continue;
 171
 172                        for (fdpll = 1; fdpll < 32; fdpll++) {
 173                                unsigned long output;
 174
 175                                output = fout / (fdpll + 1);
 176                                if (output >= 400 * 1000 * 1000)
 177                                        continue;
 178
 179                                diff = abs((long)output - (long)target);
 180                                if (best_diff > diff) {
 181                                        best_diff = diff;
 182                                        dpll->n = n;
 183                                        dpll->m = m;
 184                                        dpll->fdpll = fdpll;
 185                                        dpll->output = output;
 186                                }
 187
 188                                if (diff == 0)
 189                                        goto done;
 190                        }
 191                }
 192        }
 193
 194done:
 195        dev_dbg(rcrtc->group->dev->dev,
 196                "output:%u, fdpll:%u, n:%u, m:%u, diff:%lu\n",
 197                 dpll->output, dpll->fdpll, dpll->n, dpll->m,
 198                 best_diff);
 199}
 200
 201static const struct soc_device_attribute rcar_du_r8a7795_es1[] = {
 202        { .soc_id = "r8a7795", .revision = "ES1.*" },
 203        { /* sentinel */ }
 204};
 205
 206static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
 207{
 208        const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
 209        struct rcar_du_device *rcdu = rcrtc->group->dev;
 210        unsigned long mode_clock = mode->clock * 1000;
 211        unsigned long clk;
 212        u32 value;
 213        u32 escr;
 214        u32 div;
 215
 216        /*
 217         * Compute the clock divisor and select the internal or external dot
 218         * clock based on the requested frequency.
 219         */
 220        clk = clk_get_rate(rcrtc->clock);
 221        div = DIV_ROUND_CLOSEST(clk, mode_clock);
 222        div = clamp(div, 1U, 64U) - 1;
 223        escr = div | ESCR_DCLKSEL_CLKS;
 224
 225        if (rcrtc->extclock) {
 226                struct dpll_info dpll = { 0 };
 227                unsigned long extclk;
 228                unsigned long extrate;
 229                unsigned long rate;
 230                u32 extdiv;
 231
 232                extclk = clk_get_rate(rcrtc->extclock);
 233                if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
 234                        unsigned long target = mode_clock;
 235
 236                        /*
 237                         * The H3 ES1.x exhibits dot clock duty cycle stability
 238                         * issues. We can work around them by configuring the
 239                         * DPLL to twice the desired frequency, coupled with a
 240                         * /2 post-divider. This isn't needed on other SoCs and
 241                         * breaks HDMI output on M3-W for a currently unknown
 242                         * reason, so restrict the workaround to H3 ES1.x.
 243                         */
 244                        if (soc_device_match(rcar_du_r8a7795_es1))
 245                                target *= 2;
 246
 247                        rcar_du_dpll_divider(rcrtc, &dpll, extclk, target);
 248                        extclk = dpll.output;
 249                }
 250
 251                extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock);
 252                extdiv = clamp(extdiv, 1U, 64U) - 1;
 253
 254                rate = clk / (div + 1);
 255                extrate = extclk / (extdiv + 1);
 256
 257                if (abs((long)extrate - (long)mode_clock) <
 258                    abs((long)rate - (long)mode_clock)) {
 259
 260                        if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
 261                                u32 dpllcr = DPLLCR_CODE | DPLLCR_CLKE
 262                                           | DPLLCR_FDPLL(dpll.fdpll)
 263                                           | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m)
 264                                           | DPLLCR_STBY;
 265
 266                                if (rcrtc->index == 1)
 267                                        dpllcr |= DPLLCR_PLCS1
 268                                               |  DPLLCR_INCS_DOTCLKIN1;
 269                                else
 270                                        dpllcr |= DPLLCR_PLCS0
 271                                               |  DPLLCR_INCS_DOTCLKIN0;
 272
 273                                rcar_du_group_write(rcrtc->group, DPLLCR,
 274                                                    dpllcr);
 275                        }
 276
 277                        escr = ESCR_DCLKSEL_DCLKIN | extdiv;
 278                }
 279
 280                dev_dbg(rcrtc->group->dev->dev,
 281                        "mode clock %lu extrate %lu rate %lu ESCR 0x%08x\n",
 282                        mode_clock, extrate, rate, escr);
 283        }
 284
 285        rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
 286                            escr);
 287        rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
 288
 289        /* Signal polarities */
 290        value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0)
 291              | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0)
 292              | DSMR_DIPM_DISP | DSMR_CSPM;
 293        rcar_du_crtc_write(rcrtc, DSMR, value);
 294
 295        /* Display timings */
 296        rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - 19);
 297        rcar_du_crtc_write(rcrtc, HDER, mode->htotal - mode->hsync_start +
 298                                        mode->hdisplay - 19);
 299        rcar_du_crtc_write(rcrtc, HSWR, mode->hsync_end -
 300                                        mode->hsync_start - 1);
 301        rcar_du_crtc_write(rcrtc, HCR,  mode->htotal - 1);
 302
 303        rcar_du_crtc_write(rcrtc, VDSR, mode->crtc_vtotal -
 304                                        mode->crtc_vsync_end - 2);
 305        rcar_du_crtc_write(rcrtc, VDER, mode->crtc_vtotal -
 306                                        mode->crtc_vsync_end +
 307                                        mode->crtc_vdisplay - 2);
 308        rcar_du_crtc_write(rcrtc, VSPR, mode->crtc_vtotal -
 309                                        mode->crtc_vsync_end +
 310                                        mode->crtc_vsync_start - 1);
 311        rcar_du_crtc_write(rcrtc, VCR,  mode->crtc_vtotal - 1);
 312
 313        rcar_du_crtc_write(rcrtc, DESR,  mode->htotal - mode->hsync_start - 1);
 314        rcar_du_crtc_write(rcrtc, DEWR,  mode->hdisplay);
 315}
 316
 317void rcar_du_crtc_route_output(struct drm_crtc *crtc,
 318                               enum rcar_du_output output)
 319{
 320        struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 321        struct rcar_du_device *rcdu = rcrtc->group->dev;
 322
 323        /*
 324         * Store the route from the CRTC output to the DU output. The DU will be
 325         * configured when starting the CRTC.
 326         */
 327        rcrtc->outputs |= BIT(output);
 328
 329        /*
 330         * Store RGB routing to DPAD0, the hardware will be configured when
 331         * starting the CRTC.
 332         */
 333        if (output == RCAR_DU_OUTPUT_DPAD0)
 334                rcdu->dpad0_source = rcrtc->index;
 335}
 336
 337static unsigned int plane_zpos(struct rcar_du_plane *plane)
 338{
 339        return plane->plane.state->normalized_zpos;
 340}
 341
 342static const struct rcar_du_format_info *
 343plane_format(struct rcar_du_plane *plane)
 344{
 345        return to_rcar_plane_state(plane->plane.state)->format;
 346}
 347
 348static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
 349{
 350        struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
 351        struct rcar_du_device *rcdu = rcrtc->group->dev;
 352        unsigned int num_planes = 0;
 353        unsigned int dptsr_planes;
 354        unsigned int hwplanes = 0;
 355        unsigned int prio = 0;
 356        unsigned int i;
 357        u32 dspr = 0;
 358
 359        for (i = 0; i < rcrtc->group->num_planes; ++i) {
 360                struct rcar_du_plane *plane = &rcrtc->group->planes[i];
 361                unsigned int j;
 362
 363                if (plane->plane.state->crtc != &rcrtc->crtc ||
 364                    !plane->plane.state->visible)
 365                        continue;
 366
 367                /* Insert the plane in the sorted planes array. */
 368                for (j = num_planes++; j > 0; --j) {
 369                        if (plane_zpos(planes[j-1]) <= plane_zpos(plane))
 370                                break;
 371                        planes[j] = planes[j-1];
 372                }
 373
 374                planes[j] = plane;
 375                prio += plane_format(plane)->planes * 4;
 376        }
 377
 378        for (i = 0; i < num_planes; ++i) {
 379                struct rcar_du_plane *plane = planes[i];
 380                struct drm_plane_state *state = plane->plane.state;
 381                unsigned int index = to_rcar_plane_state(state)->hwindex;
 382
 383                prio -= 4;
 384                dspr |= (index + 1) << prio;
 385                hwplanes |= 1 << index;
 386
 387                if (plane_format(plane)->planes == 2) {
 388                        index = (index + 1) % 8;
 389
 390                        prio -= 4;
 391                        dspr |= (index + 1) << prio;
 392                        hwplanes |= 1 << index;
 393                }
 394        }
 395
 396        /* If VSP+DU integration is enabled the plane assignment is fixed. */
 397        if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
 398                if (rcdu->info->gen < 3) {
 399                        dspr = (rcrtc->index % 2) + 1;
 400                        hwplanes = 1 << (rcrtc->index % 2);
 401                } else {
 402                        dspr = (rcrtc->index % 2) ? 3 : 1;
 403                        hwplanes = 1 << ((rcrtc->index % 2) ? 2 : 0);
 404                }
 405        }
 406
 407        /*
 408         * Update the planes to display timing and dot clock generator
 409         * associations.
 410         *
 411         * Updating the DPTSR register requires restarting the CRTC group,
 412         * resulting in visible flicker. To mitigate the issue only update the
 413         * association if needed by enabled planes. Planes being disabled will
 414         * keep their current association.
 415         */
 416        mutex_lock(&rcrtc->group->lock);
 417
 418        dptsr_planes = rcrtc->index % 2 ? rcrtc->group->dptsr_planes | hwplanes
 419                     : rcrtc->group->dptsr_planes & ~hwplanes;
 420
 421        if (dptsr_planes != rcrtc->group->dptsr_planes) {
 422                rcar_du_group_write(rcrtc->group, DPTSR,
 423                                    (dptsr_planes << 16) | dptsr_planes);
 424                rcrtc->group->dptsr_planes = dptsr_planes;
 425
 426                if (rcrtc->group->used_crtcs)
 427                        rcar_du_group_restart(rcrtc->group);
 428        }
 429
 430        /* Restart the group if plane sources have changed. */
 431        if (rcrtc->group->need_restart)
 432                rcar_du_group_restart(rcrtc->group);
 433
 434        mutex_unlock(&rcrtc->group->lock);
 435
 436        rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
 437                            dspr);
 438}
 439
 440/* -----------------------------------------------------------------------------
 441 * Page Flip
 442 */
 443
 444void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc)
 445{
 446        struct drm_pending_vblank_event *event;
 447        struct drm_device *dev = rcrtc->crtc.dev;
 448        unsigned long flags;
 449
 450        spin_lock_irqsave(&dev->event_lock, flags);
 451        event = rcrtc->event;
 452        rcrtc->event = NULL;
 453        spin_unlock_irqrestore(&dev->event_lock, flags);
 454
 455        if (event == NULL)
 456                return;
 457
 458        spin_lock_irqsave(&dev->event_lock, flags);
 459        drm_crtc_send_vblank_event(&rcrtc->crtc, event);
 460        wake_up(&rcrtc->flip_wait);
 461        spin_unlock_irqrestore(&dev->event_lock, flags);
 462
 463        drm_crtc_vblank_put(&rcrtc->crtc);
 464}
 465
 466static bool rcar_du_crtc_page_flip_pending(struct rcar_du_crtc *rcrtc)
 467{
 468        struct drm_device *dev = rcrtc->crtc.dev;
 469        unsigned long flags;
 470        bool pending;
 471
 472        spin_lock_irqsave(&dev->event_lock, flags);
 473        pending = rcrtc->event != NULL;
 474        spin_unlock_irqrestore(&dev->event_lock, flags);
 475
 476        return pending;
 477}
 478
 479static void rcar_du_crtc_wait_page_flip(struct rcar_du_crtc *rcrtc)
 480{
 481        struct rcar_du_device *rcdu = rcrtc->group->dev;
 482
 483        if (wait_event_timeout(rcrtc->flip_wait,
 484                               !rcar_du_crtc_page_flip_pending(rcrtc),
 485                               msecs_to_jiffies(50)))
 486                return;
 487
 488        dev_warn(rcdu->dev, "page flip timeout\n");
 489
 490        rcar_du_crtc_finish_page_flip(rcrtc);
 491}
 492
 493/* -----------------------------------------------------------------------------
 494 * Start/Stop and Suspend/Resume
 495 */
 496
 497static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
 498{
 499        /* Set display off and background to black */
 500        rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
 501        rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0));
 502
 503        /* Configure display timings and output routing */
 504        rcar_du_crtc_set_display_timing(rcrtc);
 505        rcar_du_group_set_routing(rcrtc->group);
 506
 507        /* Start with all planes disabled. */
 508        rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
 509
 510        /* Enable the VSP compositor. */
 511        if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
 512                rcar_du_vsp_enable(rcrtc);
 513
 514        /* Turn vertical blanking interrupt reporting on. */
 515        drm_crtc_vblank_on(&rcrtc->crtc);
 516}
 517
 518static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
 519{
 520        bool interlaced;
 521
 522        /*
 523         * Select master sync mode. This enables display operation in master
 524         * sync mode (with the HSYNC and VSYNC signals configured as outputs and
 525         * actively driven).
 526         */
 527        interlaced = rcrtc->crtc.mode.flags & DRM_MODE_FLAG_INTERLACE;
 528        rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
 529                             (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
 530                             DSYSR_TVM_MASTER);
 531
 532        rcar_du_group_start_stop(rcrtc->group, true);
 533}
 534
 535static void rcar_du_crtc_disable_planes(struct rcar_du_crtc *rcrtc)
 536{
 537        struct rcar_du_device *rcdu = rcrtc->group->dev;
 538        struct drm_crtc *crtc = &rcrtc->crtc;
 539        u32 status;
 540
 541        /* Make sure vblank interrupts are enabled. */
 542        drm_crtc_vblank_get(crtc);
 543
 544        /*
 545         * Disable planes and calculate how many vertical blanking interrupts we
 546         * have to wait for. If a vertical blanking interrupt has been triggered
 547         * but not processed yet, we don't know whether it occurred before or
 548         * after the planes got disabled. We thus have to wait for two vblank
 549         * interrupts in that case.
 550         */
 551        spin_lock_irq(&rcrtc->vblank_lock);
 552        rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
 553        status = rcar_du_crtc_read(rcrtc, DSSR);
 554        rcrtc->vblank_count = status & DSSR_VBK ? 2 : 1;
 555        spin_unlock_irq(&rcrtc->vblank_lock);
 556
 557        if (!wait_event_timeout(rcrtc->vblank_wait, rcrtc->vblank_count == 0,
 558                                msecs_to_jiffies(100)))
 559                dev_warn(rcdu->dev, "vertical blanking timeout\n");
 560
 561        drm_crtc_vblank_put(crtc);
 562}
 563
 564static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
 565{
 566        struct drm_crtc *crtc = &rcrtc->crtc;
 567
 568        /*
 569         * Disable all planes and wait for the change to take effect. This is
 570         * required as the plane enable registers are updated on vblank, and no
 571         * vblank will occur once the CRTC is stopped. Disabling planes when
 572         * starting the CRTC thus wouldn't be enough as it would start scanning
 573         * out immediately from old frame buffers until the next vblank.
 574         *
 575         * This increases the CRTC stop delay, especially when multiple CRTCs
 576         * are stopped in one operation as we now wait for one vblank per CRTC.
 577         * Whether this can be improved needs to be researched.
 578         */
 579        rcar_du_crtc_disable_planes(rcrtc);
 580
 581        /*
 582         * Disable vertical blanking interrupt reporting. We first need to wait
 583         * for page flip completion before stopping the CRTC as userspace
 584         * expects page flips to eventually complete.
 585         */
 586        rcar_du_crtc_wait_page_flip(rcrtc);
 587        drm_crtc_vblank_off(crtc);
 588
 589        /* Disable the VSP compositor. */
 590        if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
 591                rcar_du_vsp_disable(rcrtc);
 592
 593        /*
 594         * Select switch sync mode. This stops display operation and configures
 595         * the HSYNC and VSYNC signals as inputs.
 596         */
 597        rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
 598
 599        rcar_du_group_start_stop(rcrtc->group, false);
 600}
 601
 602/* -----------------------------------------------------------------------------
 603 * CRTC Functions
 604 */
 605
 606static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
 607                                       struct drm_crtc_state *old_state)
 608{
 609        struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 610
 611        /*
 612         * If the CRTC has already been setup by the .atomic_begin() handler we
 613         * can skip the setup stage.
 614         */
 615        if (!rcrtc->initialized) {
 616                rcar_du_crtc_get(rcrtc);
 617                rcar_du_crtc_setup(rcrtc);
 618                rcrtc->initialized = true;
 619        }
 620
 621        rcar_du_crtc_start(rcrtc);
 622}
 623
 624static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
 625                                        struct drm_crtc_state *old_state)
 626{
 627        struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 628
 629        rcar_du_crtc_stop(rcrtc);
 630        rcar_du_crtc_put(rcrtc);
 631
 632        spin_lock_irq(&crtc->dev->event_lock);
 633        if (crtc->state->event) {
 634                drm_crtc_send_vblank_event(crtc, crtc->state->event);
 635                crtc->state->event = NULL;
 636        }
 637        spin_unlock_irq(&crtc->dev->event_lock);
 638
 639        rcrtc->initialized = false;
 640        rcrtc->outputs = 0;
 641}
 642
 643static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
 644                                      struct drm_crtc_state *old_crtc_state)
 645{
 646        struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 647
 648        WARN_ON(!crtc->state->enable);
 649
 650        /*
 651         * If a mode set is in progress we can be called with the CRTC disabled.
 652         * We then need to first setup the CRTC in order to configure planes.
 653         * The .atomic_enable() handler will notice and skip the CRTC setup.
 654         */
 655        if (!rcrtc->initialized) {
 656                rcar_du_crtc_get(rcrtc);
 657                rcar_du_crtc_setup(rcrtc);
 658                rcrtc->initialized = true;
 659        }
 660
 661        if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
 662                rcar_du_vsp_atomic_begin(rcrtc);
 663}
 664
 665static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
 666                                      struct drm_crtc_state *old_crtc_state)
 667{
 668        struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 669        struct drm_device *dev = rcrtc->crtc.dev;
 670        unsigned long flags;
 671
 672        rcar_du_crtc_update_planes(rcrtc);
 673
 674        if (crtc->state->event) {
 675                WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 676
 677                spin_lock_irqsave(&dev->event_lock, flags);
 678                rcrtc->event = crtc->state->event;
 679                crtc->state->event = NULL;
 680                spin_unlock_irqrestore(&dev->event_lock, flags);
 681        }
 682
 683        if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
 684                rcar_du_vsp_atomic_flush(rcrtc);
 685}
 686
 687static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
 688        .atomic_begin = rcar_du_crtc_atomic_begin,
 689        .atomic_flush = rcar_du_crtc_atomic_flush,
 690        .atomic_enable = rcar_du_crtc_atomic_enable,
 691        .atomic_disable = rcar_du_crtc_atomic_disable,
 692};
 693
 694static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
 695{
 696        struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 697
 698        rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
 699        rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
 700        rcrtc->vblank_enable = true;
 701
 702        return 0;
 703}
 704
 705static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc)
 706{
 707        struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
 708
 709        rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE);
 710        rcrtc->vblank_enable = false;
 711}
 712
 713static const struct drm_crtc_funcs crtc_funcs = {
 714        .reset = drm_atomic_helper_crtc_reset,
 715        .destroy = drm_crtc_cleanup,
 716        .set_config = drm_atomic_helper_set_config,
 717        .page_flip = drm_atomic_helper_page_flip,
 718        .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 719        .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 720        .enable_vblank = rcar_du_crtc_enable_vblank,
 721        .disable_vblank = rcar_du_crtc_disable_vblank,
 722};
 723
 724/* -----------------------------------------------------------------------------
 725 * Interrupt Handling
 726 */
 727
 728static irqreturn_t rcar_du_crtc_irq(int irq, void *arg)
 729{
 730        struct rcar_du_crtc *rcrtc = arg;
 731        struct rcar_du_device *rcdu = rcrtc->group->dev;
 732        irqreturn_t ret = IRQ_NONE;
 733        u32 status;
 734
 735        spin_lock(&rcrtc->vblank_lock);
 736
 737        status = rcar_du_crtc_read(rcrtc, DSSR);
 738        rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
 739
 740        if (status & DSSR_VBK) {
 741                /*
 742                 * Wake up the vblank wait if the counter reaches 0. This must
 743                 * be protected by the vblank_lock to avoid races in
 744                 * rcar_du_crtc_disable_planes().
 745                 */
 746                if (rcrtc->vblank_count) {
 747                        if (--rcrtc->vblank_count == 0)
 748                                wake_up(&rcrtc->vblank_wait);
 749                }
 750        }
 751
 752        spin_unlock(&rcrtc->vblank_lock);
 753
 754        if (status & DSSR_VBK) {
 755                if (rcdu->info->gen < 3) {
 756                        drm_crtc_handle_vblank(&rcrtc->crtc);
 757                        rcar_du_crtc_finish_page_flip(rcrtc);
 758                }
 759
 760                ret = IRQ_HANDLED;
 761        }
 762
 763        return ret;
 764}
 765
 766/* -----------------------------------------------------------------------------
 767 * Initialization
 768 */
 769
 770int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
 771{
 772        static const unsigned int mmio_offsets[] = {
 773                DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET, DU3_REG_OFFSET
 774        };
 775
 776        struct rcar_du_device *rcdu = rgrp->dev;
 777        struct platform_device *pdev = to_platform_device(rcdu->dev);
 778        struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index];
 779        struct drm_crtc *crtc = &rcrtc->crtc;
 780        struct drm_plane *primary;
 781        unsigned int irqflags;
 782        struct clk *clk;
 783        char clk_name[9];
 784        char *name;
 785        int irq;
 786        int ret;
 787
 788        /* Get the CRTC clock and the optional external clock. */
 789        if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
 790                sprintf(clk_name, "du.%u", index);
 791                name = clk_name;
 792        } else {
 793                name = NULL;
 794        }
 795
 796        rcrtc->clock = devm_clk_get(rcdu->dev, name);
 797        if (IS_ERR(rcrtc->clock)) {
 798                dev_err(rcdu->dev, "no clock for CRTC %u\n", index);
 799                return PTR_ERR(rcrtc->clock);
 800        }
 801
 802        sprintf(clk_name, "dclkin.%u", index);
 803        clk = devm_clk_get(rcdu->dev, clk_name);
 804        if (!IS_ERR(clk)) {
 805                rcrtc->extclock = clk;
 806        } else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
 807                dev_info(rcdu->dev, "can't get external clock %u\n", index);
 808                return -EPROBE_DEFER;
 809        }
 810
 811        init_waitqueue_head(&rcrtc->flip_wait);
 812        init_waitqueue_head(&rcrtc->vblank_wait);
 813        spin_lock_init(&rcrtc->vblank_lock);
 814
 815        rcrtc->group = rgrp;
 816        rcrtc->mmio_offset = mmio_offsets[index];
 817        rcrtc->index = index;
 818
 819        if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
 820                primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
 821        else
 822                primary = &rgrp->planes[index % 2].plane;
 823
 824        ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary,
 825                                        NULL, &crtc_funcs, NULL);
 826        if (ret < 0)
 827                return ret;
 828
 829        drm_crtc_helper_add(crtc, &crtc_helper_funcs);
 830
 831        /* Start with vertical blanking interrupt reporting disabled. */
 832        drm_crtc_vblank_off(crtc);
 833
 834        /* Register the interrupt handler. */
 835        if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
 836                irq = platform_get_irq(pdev, index);
 837                irqflags = 0;
 838        } else {
 839                irq = platform_get_irq(pdev, 0);
 840                irqflags = IRQF_SHARED;
 841        }
 842
 843        if (irq < 0) {
 844                dev_err(rcdu->dev, "no IRQ for CRTC %u\n", index);
 845                return irq;
 846        }
 847
 848        ret = devm_request_irq(rcdu->dev, irq, rcar_du_crtc_irq, irqflags,
 849                               dev_name(rcdu->dev), rcrtc);
 850        if (ret < 0) {
 851                dev_err(rcdu->dev,
 852                        "failed to register IRQ for CRTC %u\n", index);
 853                return ret;
 854        }
 855
 856        return 0;
 857}
 858