linux/drivers/gpu/drm/nouveau/nv50_crtc.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2008 Maarten Maathuis.
   3 * All Rights Reserved.
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining
   6 * a copy of this software and associated documentation files (the
   7 * "Software"), to deal in the Software without restriction, including
   8 * without limitation the rights to use, copy, modify, merge, publish,
   9 * distribute, sublicense, and/or sell copies of the Software, and to
  10 * permit persons to whom the Software is furnished to do so, subject to
  11 * the following conditions:
  12 *
  13 * The above copyright notice and this permission notice (including the
  14 * next paragraph) shall be included in all copies or substantial
  15 * portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24 *
  25 */
  26
  27#include "drmP.h"
  28#include "drm_mode.h"
  29#include "drm_crtc_helper.h"
  30
  31#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
  32#include "nouveau_reg.h"
  33#include "nouveau_drv.h"
  34#include "nouveau_hw.h"
  35#include "nouveau_encoder.h"
  36#include "nouveau_crtc.h"
  37#include "nouveau_fb.h"
  38#include "nouveau_connector.h"
  39#include "nv50_display.h"
  40
  41static void
  42nv50_crtc_lut_load(struct drm_crtc *crtc)
  43{
  44        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
  45        void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
  46        int i;
  47
  48        NV_DEBUG_KMS(crtc->dev, "\n");
  49
  50        for (i = 0; i < 256; i++) {
  51                writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0);
  52                writew(nv_crtc->lut.g[i] >> 2, lut + 8*i + 2);
  53                writew(nv_crtc->lut.b[i] >> 2, lut + 8*i + 4);
  54        }
  55
  56        if (nv_crtc->lut.depth == 30) {
  57                writew(nv_crtc->lut.r[i - 1] >> 2, lut + 8*i + 0);
  58                writew(nv_crtc->lut.g[i - 1] >> 2, lut + 8*i + 2);
  59                writew(nv_crtc->lut.b[i - 1] >> 2, lut + 8*i + 4);
  60        }
  61}
  62
  63int
  64nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked)
  65{
  66        struct drm_device *dev = nv_crtc->base.dev;
  67        struct drm_nouveau_private *dev_priv = dev->dev_private;
  68        struct nouveau_channel *evo = nv50_display(dev)->master;
  69        int index = nv_crtc->index, ret;
  70
  71        NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
  72        NV_DEBUG_KMS(dev, "%s\n", blanked ? "blanked" : "unblanked");
  73
  74        if (blanked) {
  75                nv_crtc->cursor.hide(nv_crtc, false);
  76
  77                ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 7 : 5);
  78                if (ret) {
  79                        NV_ERROR(dev, "no space while blanking crtc\n");
  80                        return ret;
  81                }
  82                BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2);
  83                OUT_RING(evo, NV50_EVO_CRTC_CLUT_MODE_BLANK);
  84                OUT_RING(evo, 0);
  85                if (dev_priv->chipset != 0x50) {
  86                        BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1);
  87                        OUT_RING(evo, NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE);
  88                }
  89
  90                BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1);
  91                OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE);
  92        } else {
  93                if (nv_crtc->cursor.visible)
  94                        nv_crtc->cursor.show(nv_crtc, false);
  95                else
  96                        nv_crtc->cursor.hide(nv_crtc, false);
  97
  98                ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 10 : 8);
  99                if (ret) {
 100                        NV_ERROR(dev, "no space while unblanking crtc\n");
 101                        return ret;
 102                }
 103                BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2);
 104                OUT_RING(evo, nv_crtc->lut.depth == 8 ?
 105                                NV50_EVO_CRTC_CLUT_MODE_OFF :
 106                                NV50_EVO_CRTC_CLUT_MODE_ON);
 107                OUT_RING(evo, (nv_crtc->lut.nvbo->bo.mem.start << PAGE_SHIFT) >> 8);
 108                if (dev_priv->chipset != 0x50) {
 109                        BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1);
 110                        OUT_RING(evo, NvEvoVRAM);
 111                }
 112
 113                BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_OFFSET), 2);
 114                OUT_RING(evo, nv_crtc->fb.offset >> 8);
 115                OUT_RING(evo, 0);
 116                BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1);
 117                if (dev_priv->chipset != 0x50)
 118                        if (nv_crtc->fb.tile_flags == 0x7a00 ||
 119                            nv_crtc->fb.tile_flags == 0xfe00)
 120                                OUT_RING(evo, NvEvoFB32);
 121                        else
 122                        if (nv_crtc->fb.tile_flags == 0x7000)
 123                                OUT_RING(evo, NvEvoFB16);
 124                        else
 125                                OUT_RING(evo, NvEvoVRAM_LP);
 126                else
 127                        OUT_RING(evo, NvEvoVRAM_LP);
 128        }
 129
 130        nv_crtc->fb.blanked = blanked;
 131        return 0;
 132}
 133
 134static int
 135nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update)
 136{
 137        struct drm_device *dev = nv_crtc->base.dev;
 138        struct nouveau_channel *evo = nv50_display(dev)->master;
 139        int ret;
 140
 141        NV_DEBUG_KMS(dev, "\n");
 142
 143        ret = RING_SPACE(evo, 2 + (update ? 2 : 0));
 144        if (ret) {
 145                NV_ERROR(dev, "no space while setting dither\n");
 146                return ret;
 147        }
 148
 149        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DITHER_CTRL), 1);
 150        if (on)
 151                OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_ON);
 152        else
 153                OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_OFF);
 154
 155        if (update) {
 156                BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
 157                OUT_RING(evo, 0);
 158                FIRE_RING(evo);
 159        }
 160
 161        return 0;
 162}
 163
 164struct nouveau_connector *
 165nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
 166{
 167        struct drm_device *dev = nv_crtc->base.dev;
 168        struct drm_connector *connector;
 169        struct drm_crtc *crtc = to_drm_crtc(nv_crtc);
 170
 171        /* The safest approach is to find an encoder with the right crtc, that
 172         * is also linked to a connector. */
 173        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 174                if (connector->encoder)
 175                        if (connector->encoder->crtc == crtc)
 176                                return nouveau_connector(connector);
 177        }
 178
 179        return NULL;
 180}
 181
 182static int
 183nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update)
 184{
 185        struct nouveau_connector *nv_connector =
 186                nouveau_crtc_connector_get(nv_crtc);
 187        struct drm_device *dev = nv_crtc->base.dev;
 188        struct nouveau_channel *evo = nv50_display(dev)->master;
 189        struct drm_display_mode *native_mode = NULL;
 190        struct drm_display_mode *mode = &nv_crtc->base.mode;
 191        uint32_t outX, outY, horiz, vert;
 192        int ret;
 193
 194        NV_DEBUG_KMS(dev, "\n");
 195
 196        switch (scaling_mode) {
 197        case DRM_MODE_SCALE_NONE:
 198                break;
 199        default:
 200                if (!nv_connector || !nv_connector->native_mode) {
 201                        NV_ERROR(dev, "No native mode, forcing panel scaling\n");
 202                        scaling_mode = DRM_MODE_SCALE_NONE;
 203                } else {
 204                        native_mode = nv_connector->native_mode;
 205                }
 206                break;
 207        }
 208
 209        switch (scaling_mode) {
 210        case DRM_MODE_SCALE_ASPECT:
 211                horiz = (native_mode->hdisplay << 19) / mode->hdisplay;
 212                vert = (native_mode->vdisplay << 19) / mode->vdisplay;
 213
 214                if (vert > horiz) {
 215                        outX = (mode->hdisplay * horiz) >> 19;
 216                        outY = (mode->vdisplay * horiz) >> 19;
 217                } else {
 218                        outX = (mode->hdisplay * vert) >> 19;
 219                        outY = (mode->vdisplay * vert) >> 19;
 220                }
 221                break;
 222        case DRM_MODE_SCALE_FULLSCREEN:
 223                outX = native_mode->hdisplay;
 224                outY = native_mode->vdisplay;
 225                break;
 226        case DRM_MODE_SCALE_CENTER:
 227        case DRM_MODE_SCALE_NONE:
 228        default:
 229                outX = mode->hdisplay;
 230                outY = mode->vdisplay;
 231                break;
 232        }
 233
 234        ret = RING_SPACE(evo, update ? 7 : 5);
 235        if (ret)
 236                return ret;
 237
 238        /* Got a better name for SCALER_ACTIVE? */
 239        /* One day i've got to really figure out why this is needed. */
 240        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CTRL), 1);
 241        if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) ||
 242            (mode->flags & DRM_MODE_FLAG_INTERLACE) ||
 243            mode->hdisplay != outX || mode->vdisplay != outY) {
 244                OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_ACTIVE);
 245        } else {
 246                OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_INACTIVE);
 247        }
 248
 249        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_RES1), 2);
 250        OUT_RING(evo, outY << 16 | outX);
 251        OUT_RING(evo, outY << 16 | outX);
 252
 253        if (update) {
 254                BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
 255                OUT_RING(evo, 0);
 256                FIRE_RING(evo);
 257        }
 258
 259        return 0;
 260}
 261
 262int
 263nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
 264{
 265        struct drm_nouveau_private *dev_priv = dev->dev_private;
 266        struct pll_lims pll;
 267        uint32_t reg1, reg2;
 268        int ret, N1, M1, N2, M2, P;
 269
 270        ret = get_pll_limits(dev, PLL_VPLL0 + head, &pll);
 271        if (ret)
 272                return ret;
 273
 274        if (pll.vco2.maxfreq) {
 275                ret = nv50_calc_pll(dev, &pll, pclk, &N1, &M1, &N2, &M2, &P);
 276                if (ret <= 0)
 277                        return 0;
 278
 279                NV_DEBUG(dev, "pclk %d out %d NM1 %d %d NM2 %d %d P %d\n",
 280                         pclk, ret, N1, M1, N2, M2, P);
 281
 282                reg1 = nv_rd32(dev, pll.reg + 4) & 0xff00ff00;
 283                reg2 = nv_rd32(dev, pll.reg + 8) & 0x8000ff00;
 284                nv_wr32(dev, pll.reg + 0, 0x10000611);
 285                nv_wr32(dev, pll.reg + 4, reg1 | (M1 << 16) | N1);
 286                nv_wr32(dev, pll.reg + 8, reg2 | (P << 28) | (M2 << 16) | N2);
 287        } else
 288        if (dev_priv->chipset < NV_C0) {
 289                ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
 290                if (ret <= 0)
 291                        return 0;
 292
 293                NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
 294                         pclk, ret, N1, N2, M1, P);
 295
 296                reg1 = nv_rd32(dev, pll.reg + 4) & 0xffc00000;
 297                nv_wr32(dev, pll.reg + 0, 0x50000610);
 298                nv_wr32(dev, pll.reg + 4, reg1 | (P << 16) | (M1 << 8) | N1);
 299                nv_wr32(dev, pll.reg + 8, N2);
 300        } else {
 301                ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
 302                if (ret <= 0)
 303                        return 0;
 304
 305                NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
 306                         pclk, ret, N1, N2, M1, P);
 307
 308                nv_mask(dev, pll.reg + 0x0c, 0x00000000, 0x00000100);
 309                nv_wr32(dev, pll.reg + 0x04, (P << 16) | (N1 << 8) | M1);
 310                nv_wr32(dev, pll.reg + 0x10, N2 << 16);
 311        }
 312
 313        return 0;
 314}
 315
 316static void
 317nv50_crtc_destroy(struct drm_crtc *crtc)
 318{
 319        struct drm_device *dev;
 320        struct nouveau_crtc *nv_crtc;
 321
 322        if (!crtc)
 323                return;
 324
 325        dev = crtc->dev;
 326        nv_crtc = nouveau_crtc(crtc);
 327
 328        NV_DEBUG_KMS(dev, "\n");
 329
 330        drm_crtc_cleanup(&nv_crtc->base);
 331
 332        nv50_cursor_fini(nv_crtc);
 333
 334        nouveau_bo_unmap(nv_crtc->lut.nvbo);
 335        nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
 336        nouveau_bo_unmap(nv_crtc->cursor.nvbo);
 337        nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
 338        kfree(nv_crtc->mode);
 339        kfree(nv_crtc);
 340}
 341
 342int
 343nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
 344                     uint32_t buffer_handle, uint32_t width, uint32_t height)
 345{
 346        struct drm_device *dev = crtc->dev;
 347        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 348        struct nouveau_bo *cursor = NULL;
 349        struct drm_gem_object *gem;
 350        int ret = 0, i;
 351
 352        if (!buffer_handle) {
 353                nv_crtc->cursor.hide(nv_crtc, true);
 354                return 0;
 355        }
 356
 357        if (width != 64 || height != 64)
 358                return -EINVAL;
 359
 360        gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
 361        if (!gem)
 362                return -ENOENT;
 363        cursor = nouveau_gem_object(gem);
 364
 365        ret = nouveau_bo_map(cursor);
 366        if (ret)
 367                goto out;
 368
 369        /* The simple will do for now. */
 370        for (i = 0; i < 64 * 64; i++)
 371                nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, nouveau_bo_rd32(cursor, i));
 372
 373        nouveau_bo_unmap(cursor);
 374
 375        nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.mem.start << PAGE_SHIFT);
 376        nv_crtc->cursor.show(nv_crtc, true);
 377
 378out:
 379        drm_gem_object_unreference_unlocked(gem);
 380        return ret;
 381}
 382
 383int
 384nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 385{
 386        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 387
 388        nv_crtc->cursor.set_pos(nv_crtc, x, y);
 389        return 0;
 390}
 391
 392static void
 393nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
 394                    uint32_t start, uint32_t size)
 395{
 396        int end = (start + size > 256) ? 256 : start + size, i;
 397        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 398
 399        for (i = start; i < end; i++) {
 400                nv_crtc->lut.r[i] = r[i];
 401                nv_crtc->lut.g[i] = g[i];
 402                nv_crtc->lut.b[i] = b[i];
 403        }
 404
 405        /* We need to know the depth before we upload, but it's possible to
 406         * get called before a framebuffer is bound.  If this is the case,
 407         * mark the lut values as dirty by setting depth==0, and it'll be
 408         * uploaded on the first mode_set_base()
 409         */
 410        if (!nv_crtc->base.fb) {
 411                nv_crtc->lut.depth = 0;
 412                return;
 413        }
 414
 415        nv50_crtc_lut_load(crtc);
 416}
 417
 418static void
 419nv50_crtc_save(struct drm_crtc *crtc)
 420{
 421        NV_ERROR(crtc->dev, "!!\n");
 422}
 423
 424static void
 425nv50_crtc_restore(struct drm_crtc *crtc)
 426{
 427        NV_ERROR(crtc->dev, "!!\n");
 428}
 429
 430static const struct drm_crtc_funcs nv50_crtc_funcs = {
 431        .save = nv50_crtc_save,
 432        .restore = nv50_crtc_restore,
 433        .cursor_set = nv50_crtc_cursor_set,
 434        .cursor_move = nv50_crtc_cursor_move,
 435        .gamma_set = nv50_crtc_gamma_set,
 436        .set_config = drm_crtc_helper_set_config,
 437        .page_flip = nouveau_crtc_page_flip,
 438        .destroy = nv50_crtc_destroy,
 439};
 440
 441static void
 442nv50_crtc_dpms(struct drm_crtc *crtc, int mode)
 443{
 444}
 445
 446static int
 447nv50_crtc_wait_complete(struct drm_crtc *crtc)
 448{
 449        struct drm_device *dev = crtc->dev;
 450        struct drm_nouveau_private *dev_priv = dev->dev_private;
 451        struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
 452        struct nv50_display *disp = nv50_display(dev);
 453        struct nouveau_channel *evo = disp->master;
 454        u64 start;
 455        int ret;
 456
 457        ret = RING_SPACE(evo, 6);
 458        if (ret)
 459                return ret;
 460        BEGIN_RING(evo, 0, 0x0084, 1);
 461        OUT_RING  (evo, 0x80000000);
 462        BEGIN_RING(evo, 0, 0x0080, 1);
 463        OUT_RING  (evo, 0);
 464        BEGIN_RING(evo, 0, 0x0084, 1);
 465        OUT_RING  (evo, 0x00000000);
 466
 467        nv_wo32(disp->ntfy, 0x000, 0x00000000);
 468        FIRE_RING (evo);
 469
 470        start = ptimer->read(dev);
 471        do {
 472                if (nv_ro32(disp->ntfy, 0x000))
 473                        return 0;
 474        } while (ptimer->read(dev) - start < 2000000000ULL);
 475
 476        return -EBUSY;
 477}
 478
 479static void
 480nv50_crtc_prepare(struct drm_crtc *crtc)
 481{
 482        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 483        struct drm_device *dev = crtc->dev;
 484
 485        NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
 486
 487        nv50_display_flip_stop(crtc);
 488        drm_vblank_pre_modeset(dev, nv_crtc->index);
 489        nv50_crtc_blank(nv_crtc, true);
 490}
 491
 492static void
 493nv50_crtc_commit(struct drm_crtc *crtc)
 494{
 495        struct drm_device *dev = crtc->dev;
 496        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 497
 498        NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
 499
 500        nv50_crtc_blank(nv_crtc, false);
 501        drm_vblank_post_modeset(dev, nv_crtc->index);
 502        nv50_crtc_wait_complete(crtc);
 503        nv50_display_flip_next(crtc, crtc->fb, NULL);
 504}
 505
 506static bool
 507nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode,
 508                     struct drm_display_mode *adjusted_mode)
 509{
 510        return true;
 511}
 512
 513static int
 514nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
 515                           struct drm_framebuffer *passed_fb,
 516                           int x, int y, bool atomic)
 517{
 518        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 519        struct drm_device *dev = nv_crtc->base.dev;
 520        struct drm_nouveau_private *dev_priv = dev->dev_private;
 521        struct nouveau_channel *evo = nv50_display(dev)->master;
 522        struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
 523        struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
 524        int ret;
 525
 526        NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
 527
 528        /* If atomic, we want to switch to the fb we were passed, so
 529         * now we update pointers to do that.  (We don't pin; just
 530         * assume we're already pinned and update the base address.)
 531         */
 532        if (atomic) {
 533                drm_fb = passed_fb;
 534                fb = nouveau_framebuffer(passed_fb);
 535        } else {
 536                /* If not atomic, we can go ahead and pin, and unpin the
 537                 * old fb we were passed.
 538                 */
 539                ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
 540                if (ret)
 541                        return ret;
 542
 543                if (passed_fb) {
 544                        struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
 545                        nouveau_bo_unpin(ofb->nvbo);
 546                }
 547        }
 548
 549        nv_crtc->fb.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT;
 550        nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
 551        nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
 552        if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) {
 553                ret = RING_SPACE(evo, 2);
 554                if (ret)
 555                        return ret;
 556
 557                BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1);
 558                OUT_RING  (evo, fb->r_dma);
 559        }
 560
 561        ret = RING_SPACE(evo, 12);
 562        if (ret)
 563                return ret;
 564
 565        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5);
 566        OUT_RING  (evo, nv_crtc->fb.offset >> 8);
 567        OUT_RING  (evo, 0);
 568        OUT_RING  (evo, (drm_fb->height << 16) | drm_fb->width);
 569        OUT_RING  (evo, fb->r_pitch);
 570        OUT_RING  (evo, fb->r_format);
 571
 572        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1);
 573        OUT_RING  (evo, fb->base.depth == 8 ?
 574                   NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON);
 575
 576        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1);
 577        OUT_RING  (evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR);
 578        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1);
 579        OUT_RING  (evo, (y << 16) | x);
 580
 581        if (nv_crtc->lut.depth != fb->base.depth) {
 582                nv_crtc->lut.depth = fb->base.depth;
 583                nv50_crtc_lut_load(crtc);
 584        }
 585
 586        return 0;
 587}
 588
 589static int
 590nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
 591                   struct drm_display_mode *adjusted_mode, int x, int y,
 592                   struct drm_framebuffer *old_fb)
 593{
 594        struct drm_device *dev = crtc->dev;
 595        struct nouveau_channel *evo = nv50_display(dev)->master;
 596        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 597        struct nouveau_connector *nv_connector = NULL;
 598        uint32_t hsync_dur,  vsync_dur, hsync_start_to_end, vsync_start_to_end;
 599        uint32_t hunk1, vunk1, vunk2a, vunk2b;
 600        int ret;
 601
 602        /* Find the connector attached to this CRTC */
 603        nv_connector = nouveau_crtc_connector_get(nv_crtc);
 604
 605        *nv_crtc->mode = *adjusted_mode;
 606
 607        NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
 608
 609        hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
 610        vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
 611        hsync_start_to_end = adjusted_mode->htotal - adjusted_mode->hsync_start;
 612        vsync_start_to_end = adjusted_mode->vtotal - adjusted_mode->vsync_start;
 613        /* I can't give this a proper name, anyone else can? */
 614        hunk1 = adjusted_mode->htotal -
 615                adjusted_mode->hsync_start + adjusted_mode->hdisplay;
 616        vunk1 = adjusted_mode->vtotal -
 617                adjusted_mode->vsync_start + adjusted_mode->vdisplay;
 618        /* Another strange value, this time only for interlaced adjusted_modes. */
 619        vunk2a = 2 * adjusted_mode->vtotal -
 620                 adjusted_mode->vsync_start + adjusted_mode->vdisplay;
 621        vunk2b = adjusted_mode->vtotal -
 622                 adjusted_mode->vsync_start + adjusted_mode->vtotal;
 623
 624        if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
 625                vsync_dur /= 2;
 626                vsync_start_to_end  /= 2;
 627                vunk1 /= 2;
 628                vunk2a /= 2;
 629                vunk2b /= 2;
 630                /* magic */
 631                if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) {
 632                        vsync_start_to_end -= 1;
 633                        vunk1 -= 1;
 634                        vunk2a -= 1;
 635                        vunk2b -= 1;
 636                }
 637        }
 638
 639        ret = RING_SPACE(evo, 17);
 640        if (ret)
 641                return ret;
 642
 643        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLOCK), 2);
 644        OUT_RING(evo, adjusted_mode->clock | 0x800000);
 645        OUT_RING(evo, (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 0);
 646
 647        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DISPLAY_START), 5);
 648        OUT_RING(evo, 0);
 649        OUT_RING(evo, (adjusted_mode->vtotal << 16) | adjusted_mode->htotal);
 650        OUT_RING(evo, (vsync_dur - 1) << 16 | (hsync_dur - 1));
 651        OUT_RING(evo, (vsync_start_to_end - 1) << 16 |
 652                        (hsync_start_to_end - 1));
 653        OUT_RING(evo, (vunk1 - 1) << 16 | (hunk1 - 1));
 654
 655        if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
 656                BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK0824), 1);
 657                OUT_RING(evo, (vunk2b - 1) << 16 | (vunk2a - 1));
 658        } else {
 659                OUT_RING(evo, 0);
 660                OUT_RING(evo, 0);
 661        }
 662
 663        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK082C), 1);
 664        OUT_RING(evo, 0);
 665
 666        /* This is the actual resolution of the mode. */
 667        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, REAL_RES), 1);
 668        OUT_RING(evo, (mode->vdisplay << 16) | mode->hdisplay);
 669        BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CENTER_OFFSET), 1);
 670        OUT_RING(evo, NV50_EVO_CRTC_SCALE_CENTER_OFFSET_VAL(0, 0));
 671
 672        nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false);
 673        nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false);
 674
 675        return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
 676}
 677
 678static int
 679nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 680                        struct drm_framebuffer *old_fb)
 681{
 682        int ret;
 683
 684        nv50_display_flip_stop(crtc);
 685        ret = nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
 686        if (ret)
 687                return ret;
 688
 689        ret = nv50_crtc_wait_complete(crtc);
 690        if (ret)
 691                return ret;
 692
 693        return nv50_display_flip_next(crtc, crtc->fb, NULL);
 694}
 695
 696static int
 697nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
 698                               struct drm_framebuffer *fb,
 699                               int x, int y, enum mode_set_atomic state)
 700{
 701        int ret;
 702
 703        nv50_display_flip_stop(crtc);
 704        ret = nv50_crtc_do_mode_set_base(crtc, fb, x, y, true);
 705        if (ret)
 706                return ret;
 707
 708        return nv50_crtc_wait_complete(crtc);
 709}
 710
 711static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
 712        .dpms = nv50_crtc_dpms,
 713        .prepare = nv50_crtc_prepare,
 714        .commit = nv50_crtc_commit,
 715        .mode_fixup = nv50_crtc_mode_fixup,
 716        .mode_set = nv50_crtc_mode_set,
 717        .mode_set_base = nv50_crtc_mode_set_base,
 718        .mode_set_base_atomic = nv50_crtc_mode_set_base_atomic,
 719        .load_lut = nv50_crtc_lut_load,
 720};
 721
 722int
 723nv50_crtc_create(struct drm_device *dev, int index)
 724{
 725        struct nouveau_crtc *nv_crtc = NULL;
 726        int ret, i;
 727
 728        NV_DEBUG_KMS(dev, "\n");
 729
 730        nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
 731        if (!nv_crtc)
 732                return -ENOMEM;
 733
 734        nv_crtc->mode = kzalloc(sizeof(*nv_crtc->mode), GFP_KERNEL);
 735        if (!nv_crtc->mode) {
 736                kfree(nv_crtc);
 737                return -ENOMEM;
 738        }
 739
 740        /* Default CLUT parameters, will be activated on the hw upon
 741         * first mode set.
 742         */
 743        for (i = 0; i < 256; i++) {
 744                nv_crtc->lut.r[i] = i << 8;
 745                nv_crtc->lut.g[i] = i << 8;
 746                nv_crtc->lut.b[i] = i << 8;
 747        }
 748        nv_crtc->lut.depth = 0;
 749
 750        ret = nouveau_bo_new(dev, NULL, 4096, 0x100, TTM_PL_FLAG_VRAM,
 751                             0, 0x0000, &nv_crtc->lut.nvbo);
 752        if (!ret) {
 753                ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM);
 754                if (!ret)
 755                        ret = nouveau_bo_map(nv_crtc->lut.nvbo);
 756                if (ret)
 757                        nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
 758        }
 759
 760        if (ret) {
 761                kfree(nv_crtc->mode);
 762                kfree(nv_crtc);
 763                return ret;
 764        }
 765
 766        nv_crtc->index = index;
 767
 768        /* set function pointers */
 769        nv_crtc->set_dither = nv50_crtc_set_dither;
 770        nv_crtc->set_scale = nv50_crtc_set_scale;
 771
 772        drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs);
 773        drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs);
 774        drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
 775
 776        ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM,
 777                             0, 0x0000, &nv_crtc->cursor.nvbo);
 778        if (!ret) {
 779                ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
 780                if (!ret)
 781                        ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
 782                if (ret)
 783                        nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
 784        }
 785
 786        nv50_cursor_init(nv_crtc);
 787        return 0;
 788}
 789