linux/drivers/gpu/drm/nouveau/nouveau_display.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 <acpi/video.h>
  28#include <drm/drmP.h>
  29#include <drm/drm_atomic.h>
  30#include <drm/drm_atomic_helper.h>
  31#include <drm/drm_crtc_helper.h>
  32
  33#include <nvif/class.h>
  34
  35#include "nouveau_fbcon.h"
  36#include "dispnv04/hw.h"
  37#include "nouveau_crtc.h"
  38#include "nouveau_dma.h"
  39#include "nouveau_gem.h"
  40#include "nouveau_connector.h"
  41#include "nv50_display.h"
  42
  43#include "nouveau_fence.h"
  44
  45#include <nvif/cl0046.h>
  46#include <nvif/event.h>
  47
  48static int
  49nouveau_display_vblank_handler(struct nvif_notify *notify)
  50{
  51        struct nouveau_crtc *nv_crtc =
  52                container_of(notify, typeof(*nv_crtc), vblank);
  53        drm_crtc_handle_vblank(&nv_crtc->base);
  54        return NVIF_NOTIFY_KEEP;
  55}
  56
  57int
  58nouveau_display_vblank_enable(struct drm_device *dev, unsigned int pipe)
  59{
  60        struct drm_crtc *crtc;
  61        struct nouveau_crtc *nv_crtc;
  62
  63        crtc = drm_crtc_from_index(dev, pipe);
  64        if (!crtc)
  65                return -EINVAL;
  66
  67        nv_crtc = nouveau_crtc(crtc);
  68        nvif_notify_get(&nv_crtc->vblank);
  69
  70        return 0;
  71}
  72
  73void
  74nouveau_display_vblank_disable(struct drm_device *dev, unsigned int pipe)
  75{
  76        struct drm_crtc *crtc;
  77        struct nouveau_crtc *nv_crtc;
  78
  79        crtc = drm_crtc_from_index(dev, pipe);
  80        if (!crtc)
  81                return;
  82
  83        nv_crtc = nouveau_crtc(crtc);
  84        nvif_notify_put(&nv_crtc->vblank);
  85}
  86
  87static inline int
  88calc(int blanks, int blanke, int total, int line)
  89{
  90        if (blanke >= blanks) {
  91                if (line >= blanks)
  92                        line -= total;
  93        } else {
  94                if (line >= blanks)
  95                        line -= total;
  96                line -= blanke + 1;
  97        }
  98        return line;
  99}
 100
 101static bool
 102nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
 103                                ktime_t *stime, ktime_t *etime)
 104{
 105        struct {
 106                struct nv04_disp_mthd_v0 base;
 107                struct nv04_disp_scanoutpos_v0 scan;
 108        } args = {
 109                .base.method = NV04_DISP_SCANOUTPOS,
 110                .base.head = nouveau_crtc(crtc)->index,
 111        };
 112        struct nouveau_display *disp = nouveau_display(crtc->dev);
 113        struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
 114        int retry = 20;
 115        bool ret = false;
 116
 117        do {
 118                ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args));
 119                if (ret != 0)
 120                        return false;
 121
 122                if (args.scan.vline) {
 123                        ret = true;
 124                        break;
 125                }
 126
 127                if (retry) ndelay(vblank->linedur_ns);
 128        } while (retry--);
 129
 130        *hpos = args.scan.hline;
 131        *vpos = calc(args.scan.vblanks, args.scan.vblanke,
 132                     args.scan.vtotal, args.scan.vline);
 133        if (stime) *stime = ns_to_ktime(args.scan.time[0]);
 134        if (etime) *etime = ns_to_ktime(args.scan.time[1]);
 135
 136        return ret;
 137}
 138
 139bool
 140nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe,
 141                           bool in_vblank_irq, int *vpos, int *hpos,
 142                           ktime_t *stime, ktime_t *etime,
 143                           const struct drm_display_mode *mode)
 144{
 145        struct drm_crtc *crtc;
 146
 147        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 148                if (nouveau_crtc(crtc)->index == pipe) {
 149                        return nouveau_display_scanoutpos_head(crtc, vpos, hpos,
 150                                                               stime, etime);
 151                }
 152        }
 153
 154        return false;
 155}
 156
 157static void
 158nouveau_display_vblank_fini(struct drm_device *dev)
 159{
 160        struct drm_crtc *crtc;
 161
 162        drm_vblank_cleanup(dev);
 163
 164        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 165                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 166                nvif_notify_fini(&nv_crtc->vblank);
 167        }
 168}
 169
 170static int
 171nouveau_display_vblank_init(struct drm_device *dev)
 172{
 173        struct nouveau_display *disp = nouveau_display(dev);
 174        struct drm_crtc *crtc;
 175        int ret;
 176
 177        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 178                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 179                ret = nvif_notify_init(&disp->disp,
 180                                       nouveau_display_vblank_handler, false,
 181                                       NV04_DISP_NTFY_VBLANK,
 182                                       &(struct nvif_notify_head_req_v0) {
 183                                        .head = nv_crtc->index,
 184                                       },
 185                                       sizeof(struct nvif_notify_head_req_v0),
 186                                       sizeof(struct nvif_notify_head_rep_v0),
 187                                       &nv_crtc->vblank);
 188                if (ret) {
 189                        nouveau_display_vblank_fini(dev);
 190                        return ret;
 191                }
 192        }
 193
 194        ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
 195        if (ret) {
 196                nouveau_display_vblank_fini(dev);
 197                return ret;
 198        }
 199
 200        return 0;
 201}
 202
 203static void
 204nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
 205{
 206        struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
 207
 208        if (fb->nvbo)
 209                drm_gem_object_unreference_unlocked(&fb->nvbo->gem);
 210
 211        drm_framebuffer_cleanup(drm_fb);
 212        kfree(fb);
 213}
 214
 215static int
 216nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb,
 217                                       struct drm_file *file_priv,
 218                                       unsigned int *handle)
 219{
 220        struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
 221
 222        return drm_gem_handle_create(file_priv, &fb->nvbo->gem, handle);
 223}
 224
 225static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
 226        .destroy = nouveau_user_framebuffer_destroy,
 227        .create_handle = nouveau_user_framebuffer_create_handle,
 228};
 229
 230int
 231nouveau_framebuffer_new(struct drm_device *dev,
 232                        const struct drm_mode_fb_cmd2 *mode_cmd,
 233                        struct nouveau_bo *nvbo,
 234                        struct nouveau_framebuffer **pfb)
 235{
 236        struct nouveau_framebuffer *fb;
 237        int ret;
 238
 239        if (!(fb = *pfb = kzalloc(sizeof(*fb), GFP_KERNEL)))
 240                return -ENOMEM;
 241
 242        drm_helper_mode_fill_fb_struct(dev, &fb->base, mode_cmd);
 243        fb->nvbo = nvbo;
 244
 245        ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs);
 246        if (ret)
 247                kfree(fb);
 248        return ret;
 249}
 250
 251struct drm_framebuffer *
 252nouveau_user_framebuffer_create(struct drm_device *dev,
 253                                struct drm_file *file_priv,
 254                                const struct drm_mode_fb_cmd2 *mode_cmd)
 255{
 256        struct nouveau_framebuffer *fb;
 257        struct nouveau_bo *nvbo;
 258        struct drm_gem_object *gem;
 259        int ret;
 260
 261        gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]);
 262        if (!gem)
 263                return ERR_PTR(-ENOENT);
 264        nvbo = nouveau_gem_object(gem);
 265
 266        ret = nouveau_framebuffer_new(dev, mode_cmd, nvbo, &fb);
 267        if (ret == 0)
 268                return &fb->base;
 269
 270        drm_gem_object_unreference_unlocked(gem);
 271        return ERR_PTR(ret);
 272}
 273
 274static const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
 275        .fb_create = nouveau_user_framebuffer_create,
 276        .output_poll_changed = nouveau_fbcon_output_poll_changed,
 277};
 278
 279
 280struct nouveau_drm_prop_enum_list {
 281        u8 gen_mask;
 282        int type;
 283        char *name;
 284};
 285
 286static struct nouveau_drm_prop_enum_list underscan[] = {
 287        { 6, UNDERSCAN_AUTO, "auto" },
 288        { 6, UNDERSCAN_OFF, "off" },
 289        { 6, UNDERSCAN_ON, "on" },
 290        {}
 291};
 292
 293static struct nouveau_drm_prop_enum_list dither_mode[] = {
 294        { 7, DITHERING_MODE_AUTO, "auto" },
 295        { 7, DITHERING_MODE_OFF, "off" },
 296        { 1, DITHERING_MODE_ON, "on" },
 297        { 6, DITHERING_MODE_STATIC2X2, "static 2x2" },
 298        { 6, DITHERING_MODE_DYNAMIC2X2, "dynamic 2x2" },
 299        { 4, DITHERING_MODE_TEMPORAL, "temporal" },
 300        {}
 301};
 302
 303static struct nouveau_drm_prop_enum_list dither_depth[] = {
 304        { 6, DITHERING_DEPTH_AUTO, "auto" },
 305        { 6, DITHERING_DEPTH_6BPC, "6 bpc" },
 306        { 6, DITHERING_DEPTH_8BPC, "8 bpc" },
 307        {}
 308};
 309
 310#define PROP_ENUM(p,gen,n,list) do {                                           \
 311        struct nouveau_drm_prop_enum_list *l = (list);                         \
 312        int c = 0;                                                             \
 313        while (l->gen_mask) {                                                  \
 314                if (l->gen_mask & (1 << (gen)))                                \
 315                        c++;                                                   \
 316                l++;                                                           \
 317        }                                                                      \
 318        if (c) {                                                               \
 319                p = drm_property_create(dev, DRM_MODE_PROP_ENUM, n, c);        \
 320                l = (list);                                                    \
 321                c = 0;                                                         \
 322                while (p && l->gen_mask) {                                     \
 323                        if (l->gen_mask & (1 << (gen))) {                      \
 324                                drm_property_add_enum(p, c, l->type, l->name); \
 325                                c++;                                           \
 326                        }                                                      \
 327                        l++;                                                   \
 328                }                                                              \
 329        }                                                                      \
 330} while(0)
 331
 332static void
 333nouveau_display_hpd_work(struct work_struct *work)
 334{
 335        struct nouveau_drm *drm = container_of(work, typeof(*drm), hpd_work);
 336
 337        pm_runtime_get_sync(drm->dev->dev);
 338
 339        drm_helper_hpd_irq_event(drm->dev);
 340        /* enable polling for external displays */
 341        drm_kms_helper_poll_enable(drm->dev);
 342
 343        pm_runtime_mark_last_busy(drm->dev->dev);
 344        pm_runtime_put_sync(drm->dev->dev);
 345}
 346
 347#ifdef CONFIG_ACPI
 348
 349/*
 350 * Hans de Goede: This define belongs in acpi/video.h, I've submitted a patch
 351 * to the acpi subsys to move it there from drivers/acpi/acpi_video.c .
 352 * This should be dropped once that is merged.
 353 */
 354#ifndef ACPI_VIDEO_NOTIFY_PROBE
 355#define ACPI_VIDEO_NOTIFY_PROBE                 0x81
 356#endif
 357
 358static int
 359nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val,
 360                          void *data)
 361{
 362        struct nouveau_drm *drm = container_of(nb, typeof(*drm), acpi_nb);
 363        struct acpi_bus_event *info = data;
 364
 365        if (!strcmp(info->device_class, ACPI_VIDEO_CLASS)) {
 366                if (info->type == ACPI_VIDEO_NOTIFY_PROBE) {
 367                        /*
 368                         * This may be the only indication we receive of a
 369                         * connector hotplug on a runtime suspended GPU,
 370                         * schedule hpd_work to check.
 371                         */
 372                        schedule_work(&drm->hpd_work);
 373
 374                        /* acpi-video should not generate keypresses for this */
 375                        return NOTIFY_BAD;
 376                }
 377        }
 378
 379        return NOTIFY_DONE;
 380}
 381#endif
 382
 383int
 384nouveau_display_init(struct drm_device *dev)
 385{
 386        struct nouveau_display *disp = nouveau_display(dev);
 387        struct nouveau_drm *drm = nouveau_drm(dev);
 388        struct drm_connector *connector;
 389        int ret;
 390
 391        ret = disp->init(dev);
 392        if (ret)
 393                return ret;
 394
 395        /* enable hotplug interrupts */
 396        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 397                struct nouveau_connector *conn = nouveau_connector(connector);
 398                nvif_notify_get(&conn->hpd);
 399        }
 400
 401        /* enable flip completion events */
 402        nvif_notify_get(&drm->flip);
 403        return ret;
 404}
 405
 406void
 407nouveau_display_fini(struct drm_device *dev, bool suspend)
 408{
 409        struct nouveau_display *disp = nouveau_display(dev);
 410        struct nouveau_drm *drm = nouveau_drm(dev);
 411        struct drm_connector *connector;
 412
 413        if (!suspend) {
 414                if (drm_drv_uses_atomic_modeset(dev))
 415                        drm_atomic_helper_shutdown(dev);
 416                else
 417                        drm_crtc_force_disable_all(dev);
 418        }
 419
 420        /* disable flip completion events */
 421        nvif_notify_put(&drm->flip);
 422
 423        /* disable hotplug interrupts */
 424        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 425                struct nouveau_connector *conn = nouveau_connector(connector);
 426                nvif_notify_put(&conn->hpd);
 427        }
 428
 429        drm_kms_helper_poll_disable(dev);
 430        disp->fini(dev);
 431}
 432
 433static void
 434nouveau_display_create_properties(struct drm_device *dev)
 435{
 436        struct nouveau_display *disp = nouveau_display(dev);
 437        int gen;
 438
 439        if (disp->disp.oclass < NV50_DISP)
 440                gen = 0;
 441        else
 442        if (disp->disp.oclass < GF110_DISP)
 443                gen = 1;
 444        else
 445                gen = 2;
 446
 447        PROP_ENUM(disp->dithering_mode, gen, "dithering mode", dither_mode);
 448        PROP_ENUM(disp->dithering_depth, gen, "dithering depth", dither_depth);
 449        PROP_ENUM(disp->underscan_property, gen, "underscan", underscan);
 450
 451        disp->underscan_hborder_property =
 452                drm_property_create_range(dev, 0, "underscan hborder", 0, 128);
 453
 454        disp->underscan_vborder_property =
 455                drm_property_create_range(dev, 0, "underscan vborder", 0, 128);
 456
 457        if (gen < 1)
 458                return;
 459
 460        /* -90..+90 */
 461        disp->vibrant_hue_property =
 462                drm_property_create_range(dev, 0, "vibrant hue", 0, 180);
 463
 464        /* -100..+100 */
 465        disp->color_vibrance_property =
 466                drm_property_create_range(dev, 0, "color vibrance", 0, 200);
 467}
 468
 469int
 470nouveau_display_create(struct drm_device *dev)
 471{
 472        struct nouveau_drm *drm = nouveau_drm(dev);
 473        struct nvkm_device *device = nvxx_device(&drm->client.device);
 474        struct nouveau_display *disp;
 475        int ret;
 476
 477        disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL);
 478        if (!disp)
 479                return -ENOMEM;
 480
 481        drm_mode_config_init(dev);
 482        drm_mode_create_scaling_mode_property(dev);
 483        drm_mode_create_dvi_i_properties(dev);
 484
 485        dev->mode_config.funcs = &nouveau_mode_config_funcs;
 486        dev->mode_config.fb_base = device->func->resource_addr(device, 1);
 487
 488        dev->mode_config.min_width = 0;
 489        dev->mode_config.min_height = 0;
 490        if (drm->client.device.info.family < NV_DEVICE_INFO_V0_CELSIUS) {
 491                dev->mode_config.max_width = 2048;
 492                dev->mode_config.max_height = 2048;
 493        } else
 494        if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA) {
 495                dev->mode_config.max_width = 4096;
 496                dev->mode_config.max_height = 4096;
 497        } else
 498        if (drm->client.device.info.family < NV_DEVICE_INFO_V0_FERMI) {
 499                dev->mode_config.max_width = 8192;
 500                dev->mode_config.max_height = 8192;
 501        } else {
 502                dev->mode_config.max_width = 16384;
 503                dev->mode_config.max_height = 16384;
 504        }
 505
 506        dev->mode_config.preferred_depth = 24;
 507        dev->mode_config.prefer_shadow = 1;
 508
 509        if (drm->client.device.info.chipset < 0x11)
 510                dev->mode_config.async_page_flip = false;
 511        else
 512                dev->mode_config.async_page_flip = true;
 513
 514        drm_kms_helper_poll_init(dev);
 515        drm_kms_helper_poll_disable(dev);
 516
 517        if (nouveau_modeset != 2 && drm->vbios.dcb.entries) {
 518                static const u16 oclass[] = {
 519                        GP102_DISP,
 520                        GP100_DISP,
 521                        GM200_DISP,
 522                        GM107_DISP,
 523                        GK110_DISP,
 524                        GK104_DISP,
 525                        GF110_DISP,
 526                        GT214_DISP,
 527                        GT206_DISP,
 528                        GT200_DISP,
 529                        G82_DISP,
 530                        NV50_DISP,
 531                        NV04_DISP,
 532                };
 533                int i;
 534
 535                for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) {
 536                        ret = nvif_object_init(&drm->client.device.object, 0,
 537                                               oclass[i], NULL, 0, &disp->disp);
 538                }
 539
 540                if (ret == 0) {
 541                        nouveau_display_create_properties(dev);
 542                        if (disp->disp.oclass < NV50_DISP)
 543                                ret = nv04_display_create(dev);
 544                        else
 545                                ret = nv50_display_create(dev);
 546                }
 547        } else {
 548                ret = 0;
 549        }
 550
 551        if (ret)
 552                goto disp_create_err;
 553
 554        drm_mode_config_reset(dev);
 555
 556        if (dev->mode_config.num_crtc) {
 557                ret = nouveau_display_vblank_init(dev);
 558                if (ret)
 559                        goto vblank_err;
 560        }
 561
 562        nouveau_backlight_init(dev);
 563        INIT_WORK(&drm->hpd_work, nouveau_display_hpd_work);
 564#ifdef CONFIG_ACPI
 565        drm->acpi_nb.notifier_call = nouveau_display_acpi_ntfy;
 566        register_acpi_notifier(&drm->acpi_nb);
 567#endif
 568
 569        return 0;
 570
 571vblank_err:
 572        disp->dtor(dev);
 573disp_create_err:
 574        drm_kms_helper_poll_fini(dev);
 575        drm_mode_config_cleanup(dev);
 576        return ret;
 577}
 578
 579void
 580nouveau_display_destroy(struct drm_device *dev)
 581{
 582        struct nouveau_display *disp = nouveau_display(dev);
 583
 584#ifdef CONFIG_ACPI
 585        unregister_acpi_notifier(&nouveau_drm(dev)->acpi_nb);
 586#endif
 587        nouveau_backlight_exit(dev);
 588        nouveau_display_vblank_fini(dev);
 589
 590        drm_kms_helper_poll_fini(dev);
 591        drm_mode_config_cleanup(dev);
 592
 593        if (disp->dtor)
 594                disp->dtor(dev);
 595
 596        nvif_object_fini(&disp->disp);
 597
 598        nouveau_drm(dev)->display = NULL;
 599        kfree(disp);
 600}
 601
 602int
 603nouveau_display_suspend(struct drm_device *dev, bool runtime)
 604{
 605        struct nouveau_display *disp = nouveau_display(dev);
 606        struct drm_crtc *crtc;
 607
 608        if (drm_drv_uses_atomic_modeset(dev)) {
 609                if (!runtime) {
 610                        disp->suspend = drm_atomic_helper_suspend(dev);
 611                        if (IS_ERR(disp->suspend)) {
 612                                int ret = PTR_ERR(disp->suspend);
 613                                disp->suspend = NULL;
 614                                return ret;
 615                        }
 616                }
 617
 618                nouveau_display_fini(dev, true);
 619                return 0;
 620        }
 621
 622        nouveau_display_fini(dev, true);
 623
 624        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 625                struct nouveau_framebuffer *nouveau_fb;
 626
 627                nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
 628                if (!nouveau_fb || !nouveau_fb->nvbo)
 629                        continue;
 630
 631                nouveau_bo_unpin(nouveau_fb->nvbo);
 632        }
 633
 634        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 635                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 636                if (nv_crtc->cursor.nvbo) {
 637                        if (nv_crtc->cursor.set_offset)
 638                                nouveau_bo_unmap(nv_crtc->cursor.nvbo);
 639                        nouveau_bo_unpin(nv_crtc->cursor.nvbo);
 640                }
 641        }
 642
 643        return 0;
 644}
 645
 646void
 647nouveau_display_resume(struct drm_device *dev, bool runtime)
 648{
 649        struct nouveau_display *disp = nouveau_display(dev);
 650        struct nouveau_drm *drm = nouveau_drm(dev);
 651        struct drm_crtc *crtc;
 652        int ret;
 653
 654        if (drm_drv_uses_atomic_modeset(dev)) {
 655                nouveau_display_init(dev);
 656                if (disp->suspend) {
 657                        drm_atomic_helper_resume(dev, disp->suspend);
 658                        disp->suspend = NULL;
 659                }
 660                return;
 661        }
 662
 663        /* re-pin fb/cursors */
 664        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 665                struct nouveau_framebuffer *nouveau_fb;
 666
 667                nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
 668                if (!nouveau_fb || !nouveau_fb->nvbo)
 669                        continue;
 670
 671                ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM, true);
 672                if (ret)
 673                        NV_ERROR(drm, "Could not pin framebuffer\n");
 674        }
 675
 676        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 677                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 678                if (!nv_crtc->cursor.nvbo)
 679                        continue;
 680
 681                ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true);
 682                if (!ret && nv_crtc->cursor.set_offset)
 683                        ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
 684                if (ret)
 685                        NV_ERROR(drm, "Could not pin/map cursor.\n");
 686        }
 687
 688        nouveau_display_init(dev);
 689
 690        /* Force CLUT to get re-loaded during modeset */
 691        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 692                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 693
 694                nv_crtc->lut.depth = 0;
 695        }
 696
 697        /* This should ensure we don't hit a locking problem when someone
 698         * wakes us up via a connector.  We should never go into suspend
 699         * while the display is on anyways.
 700         */
 701        if (runtime)
 702                return;
 703
 704        drm_helper_resume_force_mode(dev);
 705
 706        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 707                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 708
 709                if (!nv_crtc->cursor.nvbo)
 710                        continue;
 711
 712                if (nv_crtc->cursor.set_offset)
 713                        nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset);
 714                nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
 715                                                 nv_crtc->cursor_saved_y);
 716        }
 717}
 718
 719static int
 720nouveau_page_flip_emit(struct nouveau_channel *chan,
 721                       struct nouveau_bo *old_bo,
 722                       struct nouveau_bo *new_bo,
 723                       struct nouveau_page_flip_state *s,
 724                       struct nouveau_fence **pfence)
 725{
 726        struct nouveau_fence_chan *fctx = chan->fence;
 727        struct nouveau_drm *drm = chan->drm;
 728        struct drm_device *dev = drm->dev;
 729        unsigned long flags;
 730        int ret;
 731
 732        /* Queue it to the pending list */
 733        spin_lock_irqsave(&dev->event_lock, flags);
 734        list_add_tail(&s->head, &fctx->flip);
 735        spin_unlock_irqrestore(&dev->event_lock, flags);
 736
 737        /* Synchronize with the old framebuffer */
 738        ret = nouveau_fence_sync(old_bo, chan, false, false);
 739        if (ret)
 740                goto fail;
 741
 742        /* Emit the pageflip */
 743        ret = RING_SPACE(chan, 2);
 744        if (ret)
 745                goto fail;
 746
 747        BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
 748        OUT_RING  (chan, 0x00000000);
 749        FIRE_RING (chan);
 750
 751        ret = nouveau_fence_new(chan, false, pfence);
 752        if (ret)
 753                goto fail;
 754
 755        return 0;
 756fail:
 757        spin_lock_irqsave(&dev->event_lock, flags);
 758        list_del(&s->head);
 759        spin_unlock_irqrestore(&dev->event_lock, flags);
 760        return ret;
 761}
 762
 763int
 764nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 765                       struct drm_pending_vblank_event *event, u32 flags,
 766                       struct drm_modeset_acquire_ctx *ctx)
 767{
 768        const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1;
 769        struct drm_device *dev = crtc->dev;
 770        struct nouveau_drm *drm = nouveau_drm(dev);
 771        struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo;
 772        struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo;
 773        struct nouveau_page_flip_state *s;
 774        struct nouveau_channel *chan;
 775        struct nouveau_cli *cli;
 776        struct nouveau_fence *fence;
 777        struct nv04_display *dispnv04 = nv04_display(dev);
 778        int head = nouveau_crtc(crtc)->index;
 779        int ret;
 780
 781        chan = drm->channel;
 782        if (!chan)
 783                return -ENODEV;
 784        cli = (void *)chan->user.client;
 785
 786        s = kzalloc(sizeof(*s), GFP_KERNEL);
 787        if (!s)
 788                return -ENOMEM;
 789
 790        if (new_bo != old_bo) {
 791                ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM, true);
 792                if (ret)
 793                        goto fail_free;
 794        }
 795
 796        mutex_lock(&cli->mutex);
 797        ret = ttm_bo_reserve(&new_bo->bo, true, false, NULL);
 798        if (ret)
 799                goto fail_unpin;
 800
 801        /* synchronise rendering channel with the kernel's channel */
 802        ret = nouveau_fence_sync(new_bo, chan, false, true);
 803        if (ret) {
 804                ttm_bo_unreserve(&new_bo->bo);
 805                goto fail_unpin;
 806        }
 807
 808        if (new_bo != old_bo) {
 809                ttm_bo_unreserve(&new_bo->bo);
 810
 811                ret = ttm_bo_reserve(&old_bo->bo, true, false, NULL);
 812                if (ret)
 813                        goto fail_unpin;
 814        }
 815
 816        /* Initialize a page flip struct */
 817        *s = (struct nouveau_page_flip_state)
 818                { { }, event, crtc, fb->format->cpp[0] * 8, fb->pitches[0],
 819                  new_bo->bo.offset };
 820
 821        /* Keep vblanks on during flip, for the target crtc of this flip */
 822        drm_crtc_vblank_get(crtc);
 823
 824        /* Emit a page flip */
 825        if (swap_interval) {
 826                ret = RING_SPACE(chan, 8);
 827                if (ret)
 828                        goto fail_unreserve;
 829
 830                BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1);
 831                OUT_RING  (chan, 0);
 832                BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1);
 833                OUT_RING  (chan, head);
 834                BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1);
 835                OUT_RING  (chan, 0);
 836                BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1);
 837                OUT_RING  (chan, 0);
 838        }
 839
 840        nouveau_bo_ref(new_bo, &dispnv04->image[head]);
 841
 842        ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
 843        if (ret)
 844                goto fail_unreserve;
 845        mutex_unlock(&cli->mutex);
 846
 847        /* Update the crtc struct and cleanup */
 848        crtc->primary->fb = fb;
 849
 850        nouveau_bo_fence(old_bo, fence, false);
 851        ttm_bo_unreserve(&old_bo->bo);
 852        if (old_bo != new_bo)
 853                nouveau_bo_unpin(old_bo);
 854        nouveau_fence_unref(&fence);
 855        return 0;
 856
 857fail_unreserve:
 858        drm_crtc_vblank_put(crtc);
 859        ttm_bo_unreserve(&old_bo->bo);
 860fail_unpin:
 861        mutex_unlock(&cli->mutex);
 862        if (old_bo != new_bo)
 863                nouveau_bo_unpin(new_bo);
 864fail_free:
 865        kfree(s);
 866        return ret;
 867}
 868
 869int
 870nouveau_finish_page_flip(struct nouveau_channel *chan,
 871                         struct nouveau_page_flip_state *ps)
 872{
 873        struct nouveau_fence_chan *fctx = chan->fence;
 874        struct nouveau_drm *drm = chan->drm;
 875        struct drm_device *dev = drm->dev;
 876        struct nouveau_page_flip_state *s;
 877        unsigned long flags;
 878
 879        spin_lock_irqsave(&dev->event_lock, flags);
 880
 881        if (list_empty(&fctx->flip)) {
 882                NV_ERROR(drm, "unexpected pageflip\n");
 883                spin_unlock_irqrestore(&dev->event_lock, flags);
 884                return -EINVAL;
 885        }
 886
 887        s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
 888        if (s->event) {
 889                drm_crtc_arm_vblank_event(s->crtc, s->event);
 890        } else {
 891                /* Give up ownership of vblank for page-flipped crtc */
 892                drm_crtc_vblank_put(s->crtc);
 893        }
 894
 895        list_del(&s->head);
 896        if (ps)
 897                *ps = *s;
 898        kfree(s);
 899
 900        spin_unlock_irqrestore(&dev->event_lock, flags);
 901        return 0;
 902}
 903
 904int
 905nouveau_flip_complete(struct nvif_notify *notify)
 906{
 907        struct nouveau_drm *drm = container_of(notify, typeof(*drm), flip);
 908        struct nouveau_channel *chan = drm->channel;
 909        struct nouveau_page_flip_state state;
 910
 911        if (!nouveau_finish_page_flip(chan, &state)) {
 912                nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc),
 913                                 state.offset + state.crtc->y *
 914                                 state.pitch + state.crtc->x *
 915                                 state.bpp / 8);
 916        }
 917
 918        return NVIF_NOTIFY_KEEP;
 919}
 920
 921int
 922nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
 923                            struct drm_mode_create_dumb *args)
 924{
 925        struct nouveau_cli *cli = nouveau_cli(file_priv);
 926        struct nouveau_bo *bo;
 927        uint32_t domain;
 928        int ret;
 929
 930        args->pitch = roundup(args->width * (args->bpp / 8), 256);
 931        args->size = args->pitch * args->height;
 932        args->size = roundup(args->size, PAGE_SIZE);
 933
 934        /* Use VRAM if there is any ; otherwise fallback to system memory */
 935        if (nouveau_drm(dev)->client.device.info.ram_size != 0)
 936                domain = NOUVEAU_GEM_DOMAIN_VRAM;
 937        else
 938                domain = NOUVEAU_GEM_DOMAIN_GART;
 939
 940        ret = nouveau_gem_new(cli, args->size, 0, domain, 0, 0, &bo);
 941        if (ret)
 942                return ret;
 943
 944        ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle);
 945        drm_gem_object_unreference_unlocked(&bo->gem);
 946        return ret;
 947}
 948
 949int
 950nouveau_display_dumb_map_offset(struct drm_file *file_priv,
 951                                struct drm_device *dev,
 952                                uint32_t handle, uint64_t *poffset)
 953{
 954        struct drm_gem_object *gem;
 955
 956        gem = drm_gem_object_lookup(file_priv, handle);
 957        if (gem) {
 958                struct nouveau_bo *bo = nouveau_gem_object(gem);
 959                *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node);
 960                drm_gem_object_unreference_unlocked(gem);
 961                return 0;
 962        }
 963
 964        return -ENOENT;
 965}
 966