nouveau_display.c revision 0ad72863ea426d46b2786cba9430e122a40aad0b
16ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs/* 26ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * Copyright (C) 2008 Maarten Maathuis. 36ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * All Rights Reserved. 46ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 56ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * Permission is hereby granted, free of charge, to any person obtaining 66ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * a copy of this software and associated documentation files (the 76ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * "Software"), to deal in the Software without restriction, including 86ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * without limitation the rights to use, copy, modify, merge, publish, 96ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * distribute, sublicense, and/or sell copies of the Software, and to 106ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * permit persons to whom the Software is furnished to do so, subject to 116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * the following conditions: 126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * The above copyright notice and this permission notice (including the 146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * next paragraph) shall be included in all copies or substantial 156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * portions of the Software. 166ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 176ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 186ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 196ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 216ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 226ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 236ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs */ 266ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 27760285e7e7ab282c25b5e90816f7c47000557f4fDavid Howells#include <drm/drmP.h> 28760285e7e7ab282c25b5e90816f7c47000557f4fDavid Howells#include <drm/drm_crtc_helper.h> 2977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 306ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#include "nouveau_fbcon.h" 311a6463425552a8b9960e5a19b25421895846925cBen Skeggs#include "dispnv04/hw.h" 32332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez#include "nouveau_crtc.h" 33332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez#include "nouveau_dma.h" 3477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs#include "nouveau_gem.h" 35de69185573586302ada2e59ba41835df36986277Ben Skeggs#include "nouveau_connector.h" 3645c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs#include "nv50_display.h" 376ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 38ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs#include "nouveau_fence.h" 39ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs 401d7c71a3e2f77336df536855b0efd2dc5bdeb41bBen Skeggs#include <core/class.h> 4179ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs#include <nvif/event.h> 421d7c71a3e2f77336df536855b0efd2dc5bdeb41bBen Skeggs 4351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsstatic int 4479ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggsnouveau_display_vblank_handler(struct nvkm_notify *notify) 4551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 4679ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs struct nouveau_crtc *nv_crtc = 4779ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs container_of(notify, typeof(*nv_crtc), vblank); 48b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs drm_handle_vblank(nv_crtc->base.dev, nv_crtc->index); 4979ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs return NVKM_NOTIFY_KEEP; 5051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 5151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 5251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsint 5351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_enable(struct drm_device *dev, int head) 5451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 55b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct drm_crtc *crtc; 56b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 57b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 58b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs if (nv_crtc->index == head) { 5979ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs nvkm_notify_get(&nv_crtc->vblank); 60b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs return 0; 61b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs } 6251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 63b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs return -EINVAL; 6451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 6551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 6651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsvoid 6751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_disable(struct drm_device *dev, int head) 6851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 69b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct drm_crtc *crtc; 70b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 71b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 72b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs if (nv_crtc->index == head) { 7379ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs nvkm_notify_put(&nv_crtc->vblank); 74b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs return; 75b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs } 76b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs } 7751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 7851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 79d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsstatic inline int 80d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggscalc(int blanks, int blanke, int total, int line) 81d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 82d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (blanke >= blanks) { 83d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (line >= blanks) 84d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs line -= total; 85d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } else { 86d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (line >= blanks) 87d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs line -= total; 88d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs line -= blanke + 1; 89d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 90d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return line; 91d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 92d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 93d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsint 94d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsnouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, 95d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ktime_t *stime, ktime_t *etime) 96d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 97d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs const u32 mthd = NV04_DISP_SCANOUTPOS + nouveau_crtc(crtc)->index; 98d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct nouveau_display *disp = nouveau_display(crtc->dev); 99d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct nv04_display_scanoutpos args; 100d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs int ret, retry = 1; 101d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 102d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs do { 1030ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs ret = nvif_exec(&disp->disp, mthd, &args, sizeof(args)); 104d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (ret != 0) 105d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return 0; 106d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 107d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (args.vline) { 108d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret |= DRM_SCANOUTPOS_ACCURATE; 109d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret |= DRM_SCANOUTPOS_VALID; 110d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs break; 111d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 112d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 113d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (retry) ndelay(crtc->linedur_ns); 114d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } while (retry--); 115d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 1166c3252bc83155ae69d78fefdc7458aa64d8a87dbMario Kleiner *hpos = args.hline; 117d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs *vpos = calc(args.vblanks, args.vblanke, args.vtotal, args.vline); 118d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (stime) *stime = ns_to_ktime(args.time[0]); 119d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (etime) *etime = ns_to_ktime(args.time[1]); 120d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 121d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (*vpos < 0) 122d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret |= DRM_SCANOUTPOS_INVBL; 123d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return ret; 124d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 125d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 126d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsint 127d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsnouveau_display_scanoutpos(struct drm_device *dev, int head, unsigned int flags, 128d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) 129d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 130d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct drm_crtc *crtc; 131d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 132d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 133d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (nouveau_crtc(crtc)->index == head) { 134d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return nouveau_display_scanoutpos_head(crtc, vpos, hpos, 135d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs stime, etime); 136d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 137d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 138d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 139d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return 0; 140d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 141d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 142d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsint 143d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsnouveau_display_vblstamp(struct drm_device *dev, int head, int *max_error, 144d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct timeval *time, unsigned flags) 145d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 146d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct drm_crtc *crtc; 147d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 148d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 149d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (nouveau_crtc(crtc)->index == head) { 150d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return drm_calc_vbltimestamp_from_scanoutpos(dev, 151d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs head, max_error, time, flags, crtc, 152d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs &crtc->hwmode); 153d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 154d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 155d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 156d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return -EINVAL; 157d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 158d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 15951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsstatic void 16051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_fini(struct drm_device *dev) 16151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 162b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct drm_crtc *crtc; 16351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 1641139ffb96b3f4e8be9006552d2dd4d302d62c2eeBen Skeggs drm_vblank_cleanup(dev); 1651139ffb96b3f4e8be9006552d2dd4d302d62c2eeBen Skeggs 166b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 167b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 16879ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs nvkm_notify_fini(&nv_crtc->vblank); 16951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 17051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 17151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 17251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsstatic int 17351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_init(struct drm_device *dev) 17451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 17551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 176967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs struct nouveau_disp *pdisp = nvkm_disp(&drm->device); 177b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct drm_crtc *crtc; 178b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs int ret; 17951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 180b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 181b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 18279ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs ret = nvkm_notify_init(&pdisp->vblank, 18379ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs nouveau_display_vblank_handler, false, 18479ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs &(struct nvif_notify_head_req_v0) { 18579ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs .head = nv_crtc->index, 18679ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs }, 18779ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs sizeof(struct nvif_notify_head_req_v0), 18879ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs sizeof(struct nvif_notify_head_rep_v0), 18979ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs &nv_crtc->vblank); 19051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (ret) { 19151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_fini(dev); 19251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return ret; 19351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 19451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 19551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 19651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs ret = drm_vblank_init(dev, dev->mode_config.num_crtc); 19751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (ret) { 19851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_fini(dev); 19951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return ret; 20051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 20151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 20251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return 0; 20351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 20451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 2056ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic void 2066ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) 2076ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2086ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 209ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs struct nouveau_display *disp = nouveau_display(drm_fb->dev); 210ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs 211ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs if (disp->fb_dtor) 212ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs disp->fb_dtor(drm_fb); 2136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 214bc9025bdc4e2b591734cca17697093845007b63dLuca Barbieri if (fb->nvbo) 21555fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann drm_gem_object_unreference_unlocked(&fb->nvbo->gem); 2166ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2176ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs drm_framebuffer_cleanup(drm_fb); 2186ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs kfree(fb); 2196ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2216ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic int 2226ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, 2236ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_file *file_priv, 2246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs unsigned int *handle) 2256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2266ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 2276ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 22855fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann return drm_gem_handle_create(file_priv, &fb->nvbo->gem, handle); 2296ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2306ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2316ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { 2326ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .destroy = nouveau_user_framebuffer_destroy, 2336ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .create_handle = nouveau_user_framebuffer_create_handle, 2346ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}; 2356ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 236386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlieint 23745c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggsnouveau_framebuffer_init(struct drm_device *dev, 23845c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs struct nouveau_framebuffer *nv_fb, 239308e5bcbdb10452e8aba31aa21432fb67ee46d72Jesse Barnes struct drm_mode_fb_cmd2 *mode_cmd, 24045c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs struct nouveau_bo *nvbo) 2416ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 242ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 24345c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs struct drm_framebuffer *fb = &nv_fb->base; 2446ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int ret; 2456ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 24645c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs drm_helper_mode_fill_fb_struct(fb, mode_cmd); 24745c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs nv_fb->nvbo = nvbo; 24845c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs 249c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); 250ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs if (ret) 251c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter return ret; 252ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs 253ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs if (disp->fb_ctor) { 254ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs ret = disp->fb_ctor(fb); 255ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs if (ret) 256ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs disp->fb_dtor(fb); 257c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter } 258c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter 259ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs return ret; 2606ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2616ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2626ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic struct drm_framebuffer * 2636ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create(struct drm_device *dev, 2646ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_file *file_priv, 265308e5bcbdb10452e8aba31aa21432fb67ee46d72Jesse Barnes struct drm_mode_fb_cmd2 *mode_cmd) 2666ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 267386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie struct nouveau_framebuffer *nouveau_fb; 2686ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_gem_object *gem; 269fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst int ret = -ENOMEM; 2706ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 271308e5bcbdb10452e8aba31aa21432fb67ee46d72Jesse Barnes gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); 2726ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (!gem) 273cce13ff7596985903ad924504562190a2c163a63Chris Wilson return ERR_PTR(-ENOENT); 2746ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 275386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); 276386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie if (!nouveau_fb) 277fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst goto err_unref; 278386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie 279386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem)); 280fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst if (ret) 281fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst goto err; 2826ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 283386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie return &nouveau_fb->base; 284fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst 285fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorsterr: 286fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst kfree(nouveau_fb); 287fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorsterr_unref: 288fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst drm_gem_object_unreference(gem); 289fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst return ERR_PTR(ret); 2906ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2916ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 29227d5030a235d89842ed70e18d924f017b34a496dBen Skeggsstatic const struct drm_mode_config_funcs nouveau_mode_config_funcs = { 2936ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .fb_create = nouveau_user_framebuffer_create, 294eb1f8e4f3be898df808e2dfc131099f5831d491dDave Airlie .output_poll_changed = nouveau_fbcon_output_poll_changed, 2956ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}; 2966ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 297b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 2984a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstruct nouveau_drm_prop_enum_list { 299de69185573586302ada2e59ba41835df36986277Ben Skeggs u8 gen_mask; 300b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs int type; 301b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs char *name; 302b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs}; 303b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 3044a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstatic struct nouveau_drm_prop_enum_list underscan[] = { 3059285462273cbccb27187d5308ed95f94a9ceb1deBen Skeggs { 6, UNDERSCAN_AUTO, "auto" }, 3069285462273cbccb27187d5308ed95f94a9ceb1deBen Skeggs { 6, UNDERSCAN_OFF, "off" }, 3079285462273cbccb27187d5308ed95f94a9ceb1deBen Skeggs { 6, UNDERSCAN_ON, "on" }, 308de69185573586302ada2e59ba41835df36986277Ben Skeggs {} 309b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs}; 310b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 3114a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstatic struct nouveau_drm_prop_enum_list dither_mode[] = { 312de69185573586302ada2e59ba41835df36986277Ben Skeggs { 7, DITHERING_MODE_AUTO, "auto" }, 313de69185573586302ada2e59ba41835df36986277Ben Skeggs { 7, DITHERING_MODE_OFF, "off" }, 314de69185573586302ada2e59ba41835df36986277Ben Skeggs { 1, DITHERING_MODE_ON, "on" }, 315de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_MODE_STATIC2X2, "static 2x2" }, 316de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_MODE_DYNAMIC2X2, "dynamic 2x2" }, 317de69185573586302ada2e59ba41835df36986277Ben Skeggs { 4, DITHERING_MODE_TEMPORAL, "temporal" }, 318de69185573586302ada2e59ba41835df36986277Ben Skeggs {} 319de69185573586302ada2e59ba41835df36986277Ben Skeggs}; 320de69185573586302ada2e59ba41835df36986277Ben Skeggs 3214a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstatic struct nouveau_drm_prop_enum_list dither_depth[] = { 322de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_DEPTH_AUTO, "auto" }, 323de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, 324de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, 325de69185573586302ada2e59ba41835df36986277Ben Skeggs {} 326de69185573586302ada2e59ba41835df36986277Ben Skeggs}; 327de69185573586302ada2e59ba41835df36986277Ben Skeggs 328de69185573586302ada2e59ba41835df36986277Ben Skeggs#define PROP_ENUM(p,gen,n,list) do { \ 3294a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauer struct nouveau_drm_prop_enum_list *l = (list); \ 330de69185573586302ada2e59ba41835df36986277Ben Skeggs int c = 0; \ 331de69185573586302ada2e59ba41835df36986277Ben Skeggs while (l->gen_mask) { \ 332de69185573586302ada2e59ba41835df36986277Ben Skeggs if (l->gen_mask & (1 << (gen))) \ 333de69185573586302ada2e59ba41835df36986277Ben Skeggs c++; \ 334de69185573586302ada2e59ba41835df36986277Ben Skeggs l++; \ 335de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 336de69185573586302ada2e59ba41835df36986277Ben Skeggs if (c) { \ 337de69185573586302ada2e59ba41835df36986277Ben Skeggs p = drm_property_create(dev, DRM_MODE_PROP_ENUM, n, c); \ 338de69185573586302ada2e59ba41835df36986277Ben Skeggs l = (list); \ 339de69185573586302ada2e59ba41835df36986277Ben Skeggs c = 0; \ 340de69185573586302ada2e59ba41835df36986277Ben Skeggs while (p && l->gen_mask) { \ 341de69185573586302ada2e59ba41835df36986277Ben Skeggs if (l->gen_mask & (1 << (gen))) { \ 342de69185573586302ada2e59ba41835df36986277Ben Skeggs drm_property_add_enum(p, c, l->type, l->name); \ 343de69185573586302ada2e59ba41835df36986277Ben Skeggs c++; \ 344de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 345de69185573586302ada2e59ba41835df36986277Ben Skeggs l++; \ 346de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 347de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 348de69185573586302ada2e59ba41835df36986277Ben Skeggs} while(0) 349de69185573586302ada2e59ba41835df36986277Ben Skeggs 350042206c0cd4924879c4292c5ffa2bf1e8023ae5aFrancisco Jerezint 351f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsnouveau_display_init(struct drm_device *dev) 352f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs{ 35377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 35452c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct drm_connector *connector; 355f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs int ret; 356f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 357f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs ret = disp->init(dev); 35852c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs if (ret) 35952c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs return ret; 36052c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs 3617df898b1a70b13c3a8892625f4ead929d9554293Ben Skeggs /* enable polling for external displays */ 36252c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs drm_kms_helper_poll_enable(dev); 36352c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs 36452c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs /* enable hotplug interrupts */ 36552c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 36652c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct nouveau_connector *conn = nouveau_connector(connector); 36779ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs nvkm_notify_get(&conn->hpd); 368f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs } 369f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 370f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs return ret; 371f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs} 372f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 373f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsvoid 374f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsnouveau_display_fini(struct drm_device *dev) 375f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs{ 37677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 37752c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct drm_connector *connector; 3789cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner int head; 3799cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner 3809cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner /* Make sure that drm and hw vblank irqs get properly disabled. */ 3819cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner for (head = 0; head < dev->mode_config.num_crtc; head++) 3829cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner drm_vblank_off(dev, head); 38352c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs 38452c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs /* disable hotplug interrupts */ 38552c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 38652c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct nouveau_connector *conn = nouveau_connector(connector); 38779ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs nvkm_notify_put(&conn->hpd); 38852c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs } 389f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 390f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs drm_kms_helper_poll_disable(dev); 391f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs disp->fini(dev); 392f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs} 393f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 3949c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggsstatic void 3959c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggsnouveau_display_create_properties(struct drm_device *dev) 39627d5030a235d89842ed70e18d924f017b34a496dBen Skeggs{ 3979c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs struct nouveau_display *disp = nouveau_display(dev); 3989c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs int gen; 399de69185573586302ada2e59ba41835df36986277Ben Skeggs 4000ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs if (disp->disp.oclass < NV50_DISP_CLASS) 401de69185573586302ada2e59ba41835df36986277Ben Skeggs gen = 0; 402de69185573586302ada2e59ba41835df36986277Ben Skeggs else 4030ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs if (disp->disp.oclass < NVD0_DISP_CLASS) 404de69185573586302ada2e59ba41835df36986277Ben Skeggs gen = 1; 405de69185573586302ada2e59ba41835df36986277Ben Skeggs else 406de69185573586302ada2e59ba41835df36986277Ben Skeggs gen = 2; 407de69185573586302ada2e59ba41835df36986277Ben Skeggs 408de69185573586302ada2e59ba41835df36986277Ben Skeggs PROP_ENUM(disp->dithering_mode, gen, "dithering mode", dither_mode); 409de69185573586302ada2e59ba41835df36986277Ben Skeggs PROP_ENUM(disp->dithering_depth, gen, "dithering depth", dither_depth); 410de69185573586302ada2e59ba41835df36986277Ben Skeggs PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); 411b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 412b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs disp->underscan_hborder_property = 413d9bc3c02e36d844c2d980e65ddda5c7699e073f8Sascha Hauer drm_property_create_range(dev, 0, "underscan hborder", 0, 128); 414b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 415b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs disp->underscan_vborder_property = 416d9bc3c02e36d844c2d980e65ddda5c7699e073f8Sascha Hauer drm_property_create_range(dev, 0, "underscan vborder", 0, 128); 417b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 4189c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs if (gen < 1) 4199c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs return; 420df26bc9c320602539b1b5b3d85786e4c8de7bf43Christoph Bumiller 4219c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs /* -90..+90 */ 4229c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs disp->vibrant_hue_property = 4239c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_property_create_range(dev, 0, "vibrant hue", 0, 180); 4249c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs 4259c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs /* -100..+100 */ 4269c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs disp->color_vibrance_property = 4279c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_property_create_range(dev, 0, "color vibrance", 0, 200); 4289c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs} 4299c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs 4309c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggsint 4319c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggsnouveau_display_create(struct drm_device *dev) 4329c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs{ 4339c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 4349c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs struct nouveau_display *disp; 4359c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs int ret; 4369c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs 4379c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); 4389c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs if (!disp) 4399c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs return -ENOMEM; 4409c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs 4419c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_mode_config_init(dev); 4429c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_mode_create_scaling_mode_property(dev); 4439c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_mode_create_dvi_i_properties(dev); 444df26bc9c320602539b1b5b3d85786e4c8de7bf43Christoph Bumiller 445e6ecefaadfcdb03db8ac9e739b4ba7a93a8811b3Laurent Pinchart dev->mode_config.funcs = &nouveau_mode_config_funcs; 446967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs dev->mode_config.fb_base = nv_device_resource_start(nvkm_device(&drm->device), 1); 44727d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 44827d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.min_width = 0; 44927d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.min_height = 0; 450967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family < NV_DEVICE_INFO_V0_CELSIUS) { 45127d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_width = 2048; 45227d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_height = 2048; 45327d5030a235d89842ed70e18d924f017b34a496dBen Skeggs } else 454967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 45527d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_width = 4096; 45627d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_height = 4096; 45727d5030a235d89842ed70e18d924f017b34a496dBen Skeggs } else { 45827d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_width = 8192; 45927d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_height = 8192; 46027d5030a235d89842ed70e18d924f017b34a496dBen Skeggs } 46127d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 462f1377998eede7a8caa124fcf6a589b02c9e2bac7Dave Airlie dev->mode_config.preferred_depth = 24; 463f1377998eede7a8caa124fcf6a589b02c9e2bac7Dave Airlie dev->mode_config.prefer_shadow = 1; 464f1377998eede7a8caa124fcf6a589b02c9e2bac7Dave Airlie 465967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.chipset < 0x11) 466b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs dev->mode_config.async_page_flip = false; 467b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs else 468b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs dev->mode_config.async_page_flip = true; 469b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 470f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs drm_kms_helper_poll_init(dev); 471f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs drm_kms_helper_poll_disable(dev); 472f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 473fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (drm->vbios.dcb.entries) { 4742332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs static const u16 oclass[] = { 4750b681687fe9eaa552059030a90897a78fea8f86aBen Skeggs GM107_DISP_CLASS, 4762332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVF0_DISP_CLASS, 4772332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVE0_DISP_CLASS, 4782332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVD0_DISP_CLASS, 4792332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVA3_DISP_CLASS, 4802332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NV94_DISP_CLASS, 4812332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVA0_DISP_CLASS, 4822332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NV84_DISP_CLASS, 4832332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NV50_DISP_CLASS, 4842332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NV04_DISP_CLASS, 4852332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs }; 4862332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs int i; 4872332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs 4882332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { 4890ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs ret = nvif_object_init(nvif_object(&drm->device), NULL, 4900ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs NVDRM_DISPLAY, oclass[i], 4910ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs NULL, 0, &disp->disp); 4922332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs } 4932332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs 4942332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs if (ret == 0) { 4959c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs nouveau_display_create_properties(dev); 4960ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs if (disp->disp.oclass < NV50_DISP_CLASS) 4972332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs ret = nv04_display_create(dev); 4982332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs else 4992332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs ret = nv50_display_create(dev); 5002332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs } 501fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs } else { 502fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs ret = 0; 503fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs } 5049430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs 505fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (ret) 506fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs goto disp_create_err; 5079430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs 508fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (dev->mode_config.num_crtc) { 50951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs ret = nouveau_display_vblank_init(dev); 510fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (ret) 511fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs goto vblank_err; 512f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs } 513f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 514fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs nouveau_backlight_init(dev); 5155ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz return 0; 5165ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz 5175ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarzvblank_err: 51877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs disp->dtor(dev); 5195ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarzdisp_create_err: 5205ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz drm_kms_helper_poll_fini(dev); 5215ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz drm_mode_config_cleanup(dev); 5222a44e4997c5fee8e1da1589ff57e0bd1c53f03ceBen Skeggs return ret; 52327d5030a235d89842ed70e18d924f017b34a496dBen Skeggs} 52427d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 52527d5030a235d89842ed70e18d924f017b34a496dBen Skeggsvoid 52627d5030a235d89842ed70e18d924f017b34a496dBen Skeggsnouveau_display_destroy(struct drm_device *dev) 52727d5030a235d89842ed70e18d924f017b34a496dBen Skeggs{ 52877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 52927d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 53077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_backlight_exit(dev); 53151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_fini(dev); 532f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 533d6bf2f370703c0cab60bf1f5bf871a3f00eb8872Ben Skeggs drm_kms_helper_poll_fini(dev); 534d6bf2f370703c0cab60bf1f5bf871a3f00eb8872Ben Skeggs drm_mode_config_cleanup(dev); 535d6bf2f370703c0cab60bf1f5bf871a3f00eb8872Ben Skeggs 5369430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs if (disp->dtor) 5379430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs disp->dtor(dev); 538f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 5390ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs nvif_object_fini(&disp->disp); 5402332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs 54177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_drm(dev)->display = NULL; 54277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs kfree(disp); 54377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs} 54477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 54577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggsint 54677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggsnouveau_display_suspend(struct drm_device *dev) 54777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs{ 54877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 54977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_crtc *crtc; 55077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 55177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_display_fini(dev); 55277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 553c52f4fa61d7504bacd94fd54f43fd0b5bdf74bbcBen Skeggs NV_INFO(drm, "unpinning framebuffer(s)...\n"); 55477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 55577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_framebuffer *nouveau_fb; 55677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 557f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 55877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!nouveau_fb || !nouveau_fb->nvbo) 55977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs continue; 56077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 56177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_unpin(nouveau_fb->nvbo); 56277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 56377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 56477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 56577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 56677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 56777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_unmap(nv_crtc->cursor.nvbo); 56877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_unpin(nv_crtc->cursor.nvbo); 56977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 57077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 57177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs return 0; 57277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs} 57377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 57477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggsvoid 5755addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlienouveau_display_repin(struct drm_device *dev) 57677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs{ 57777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 57877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_crtc *crtc; 57977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs int ret; 58077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 58177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 58277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_framebuffer *nouveau_fb; 58377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 584f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 58577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!nouveau_fb || !nouveau_fb->nvbo) 58677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs continue; 58777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 58877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); 58977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 59077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 59177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 59277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 59377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 59477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); 59577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!ret) 59677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs ret = nouveau_bo_map(nv_crtc->cursor.nvbo); 59777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (ret) 59877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs NV_ERROR(drm, "Could not pin/map cursor.\n"); 59977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 6005addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlie} 60177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 6025addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlievoid 6035addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlienouveau_display_resume(struct drm_device *dev) 6045addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlie{ 6055addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlie struct drm_crtc *crtc; 6069cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner int head; 6079cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner 60877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_display_init(dev); 60977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 61077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs /* Force CLUT to get re-loaded during modeset */ 61177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 61277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 61377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 61477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->lut.depth = 0; 61577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 61677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 6179cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner /* Make sure that drm and hw vblank irqs get resumed if needed. */ 6189cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner for (head = 0; head < dev->mode_config.num_crtc; head++) 6199cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner drm_vblank_on(dev, head); 6209cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner 62177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs drm_helper_resume_force_mode(dev); 62277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 62377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 62477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 62577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs u32 offset = nv_crtc->cursor.nvbo->bo.offset; 62677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 62777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->cursor.set_offset(nv_crtc, offset); 62877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, 62977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->cursor_saved_y); 63077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 63127d5030a235d89842ed70e18d924f017b34a496dBen Skeggs} 63227d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 633332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezstatic int 634332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jereznouveau_page_flip_emit(struct nouveau_channel *chan, 635332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_bo *old_bo, 636332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_bo *new_bo, 637332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *s, 638332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_fence **pfence) 639332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez{ 640f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_fence_chan *fctx = chan->fence; 64177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = chan->drm; 64277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_device *dev = drm->dev; 643332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez unsigned long flags; 644332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez int ret; 645332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 646332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Queue it to the pending list */ 647332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_lock_irqsave(&dev->event_lock, flags); 648f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs list_add_tail(&s->head, &fctx->flip); 649332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 650332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 651332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Synchronize with the old framebuffer */ 652332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez ret = nouveau_fence_sync(old_bo->bo.sync_obj, chan); 653332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 654332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail; 655332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 656332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Emit the pageflip */ 6571e303c03af1e631de37ec77cc2513210910a812cBen Skeggs ret = RING_SPACE(chan, 2); 658332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 659332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail; 660332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 661967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) 6626d597027755b2eed4298b85ebe3cb5c93b29d1a9Ben Skeggs BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); 6631e303c03af1e631de37ec77cc2513210910a812cBen Skeggs else 6641e303c03af1e631de37ec77cc2513210910a812cBen Skeggs BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1); 6651e303c03af1e631de37ec77cc2513210910a812cBen Skeggs OUT_RING (chan, 0x00000000); 666bd2f2037a42d4657ead3be2918db22e63626cd35Ben Skeggs FIRE_RING (chan); 667332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 668264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs ret = nouveau_fence_new(chan, false, pfence); 669332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 670332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail; 671332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 672332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return 0; 673332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezfail: 674332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_lock_irqsave(&dev->event_lock, flags); 675332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez list_del(&s->head); 676332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 677332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return ret; 678332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez} 679332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 680332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezint 681332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jereznouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 682b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs struct drm_pending_vblank_event *event, u32 flags) 683332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez{ 684b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; 685332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct drm_device *dev = crtc->dev; 68677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 687f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; 688332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; 689332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *s; 6900ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs struct nouveau_channel *chan; 6910ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs struct nouveau_cli *cli; 692332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_fence *fence; 693332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez int ret; 694332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 6950ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs chan = drm->channel; 6960ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs if (!chan) 697332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return -ENODEV; 6980ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs cli = (void *)nvif_client(&chan->device->base); 699332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 700332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez s = kzalloc(sizeof(*s), GFP_KERNEL); 701332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (!s) 702332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return -ENOMEM; 703332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 704d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst if (new_bo != old_bo) { 705d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); 706d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst if (ret) 707d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst goto fail_free; 708d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst } 709d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst 7100ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs mutex_lock(&cli->mutex); 711d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst 712eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs /* synchronise rendering channel with the kernel's channel */ 713eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs spin_lock(&new_bo->bo.bdev->fence_lock); 714eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs fence = nouveau_fence_ref(new_bo->bo.sync_obj); 715eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs spin_unlock(&new_bo->bo.bdev->fence_lock); 716eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs ret = nouveau_fence_sync(fence, chan); 7172fd04c81dc652689b104ab16eba26146dde5c43fBen Skeggs nouveau_fence_unref(&fence); 718eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs if (ret) 71909c3de135063f93d7137ad112f551f293b1204cfMaarten Lankhorst goto fail_unpin; 720b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst 72107ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs ret = ttm_bo_reserve(&old_bo->bo, true, false, false, NULL); 722060810d7abaabcab282e062c595871d661561400Ben Skeggs if (ret) 723060810d7abaabcab282e062c595871d661561400Ben Skeggs goto fail_unpin; 724b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst 725b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst /* Initialize a page flip struct */ 726b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst *s = (struct nouveau_page_flip_state) 727b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst { { }, event, nouveau_crtc(crtc)->index, 728b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y, 729b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst new_bo->bo.offset }; 730b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst 731ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner /* Keep vblanks on during flip, for the target crtc of this flip */ 732ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner drm_vblank_get(dev, nouveau_crtc(crtc)->index); 733ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner 734332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Emit a page flip */ 735967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { 736b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); 737060810d7abaabcab282e062c595871d661561400Ben Skeggs if (ret) 738d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs goto fail_unreserve; 73978ae0ad403daf11cf63da86923d2b5dbeda3af8fBen Skeggs } else { 74078ae0ad403daf11cf63da86923d2b5dbeda3af8fBen Skeggs struct nv04_display *dispnv04 = nv04_display(dev); 741b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs int head = nouveau_crtc(crtc)->index; 742b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 743b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs if (swap_interval) { 744b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs ret = RING_SPACE(chan, 8); 745b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs if (ret) 746b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs goto fail_unreserve; 747b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 748b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); 749b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, 0); 750b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); 751b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, head); 752b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1); 753b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, 0); 754b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1); 755b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, 0); 756b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs } 757b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 758b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs nouveau_bo_ref(new_bo, &dispnv04->image[head]); 759d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs } 760d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs 761332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); 762332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 763332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail_unreserve; 7640ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs mutex_unlock(&cli->mutex); 765332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 766332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Update the crtc struct and cleanup */ 767f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper crtc->primary->fb = fb; 768332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 76907ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs nouveau_bo_fence(old_bo, fence); 77007ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs ttm_bo_unreserve(&old_bo->bo); 771060810d7abaabcab282e062c595871d661561400Ben Skeggs if (old_bo != new_bo) 772b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst nouveau_bo_unpin(old_bo); 773332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez nouveau_fence_unref(&fence); 774332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return 0; 775332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 776332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezfail_unreserve: 777ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner drm_vblank_put(dev, nouveau_crtc(crtc)->index); 77807ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs ttm_bo_unreserve(&old_bo->bo); 779060810d7abaabcab282e062c595871d661561400Ben Skeggsfail_unpin: 7800ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs mutex_unlock(&cli->mutex); 781060810d7abaabcab282e062c595871d661561400Ben Skeggs if (old_bo != new_bo) 782b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst nouveau_bo_unpin(new_bo); 783332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezfail_free: 784332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez kfree(s); 785332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return ret; 786332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez} 787332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 788332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezint 789332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jereznouveau_finish_page_flip(struct nouveau_channel *chan, 790332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *ps) 791332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez{ 792f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_fence_chan *fctx = chan->fence; 79377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = chan->drm; 79477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_device *dev = drm->dev; 795332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *s; 796332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez unsigned long flags; 797af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner int crtcid = -1; 798332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 799332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_lock_irqsave(&dev->event_lock, flags); 800332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 801f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs if (list_empty(&fctx->flip)) { 80277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs NV_ERROR(drm, "unexpected pageflip\n"); 803332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 804332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return -EINVAL; 805332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez } 806332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 807f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); 808af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner if (s->event) { 809af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner /* Vblank timestamps/counts are only correct on >= NV-50 */ 810967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) 811af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner crtcid = s->crtc; 812af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner 813af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner drm_send_vblank_event(dev, crtcid, s->event); 814af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner } 815332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 816ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner /* Give up ownership of vblank for page-flipped crtc */ 817ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner drm_vblank_put(dev, s->crtc); 818ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner 819332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez list_del(&s->head); 820d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs if (ps) 821d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs *ps = *s; 822332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez kfree(s); 823332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 824332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 825332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return 0; 826332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez} 82733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 82833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsint 829f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggsnouveau_flip_complete(void *data) 830f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs{ 831f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_channel *chan = data; 83277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = chan->drm; 833f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_page_flip_state state; 834f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 835f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs if (!nouveau_finish_page_flip(chan, &state)) { 836967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 83777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_set_crtc_base(drm->dev, state.crtc, state.offset + 838f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs state.y * state.pitch + 839f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs state.x * state.bpp / 8); 840f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs } 841f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs } 842f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 843f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs return 0; 844f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs} 845f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 846f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggsint 84733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsnouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, 84833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct drm_mode_create_dumb *args) 84933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs{ 85033dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct nouveau_bo *bo; 85133dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs int ret; 85233dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 85333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs args->pitch = roundup(args->width * (args->bpp / 8), 256); 85433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs args->size = args->pitch * args->height; 85533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs args->size = roundup(args->size, PAGE_SIZE); 85633dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 857610bd7da160f76f1644ecb4cd7f39511b49a22ccDave Airlie ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo); 85833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs if (ret) 85933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return ret; 86033dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 86155fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); 86255fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann drm_gem_object_unreference_unlocked(&bo->gem); 86333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return ret; 86433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs} 86533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 86633dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsint 86733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsnouveau_display_dumb_map_offset(struct drm_file *file_priv, 86833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct drm_device *dev, 86933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs uint32_t handle, uint64_t *poffset) 87033dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs{ 87133dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct drm_gem_object *gem; 87233dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 87333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs gem = drm_gem_object_lookup(dev, file_priv, handle); 87433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs if (gem) { 87555fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann struct nouveau_bo *bo = nouveau_gem_object(gem); 87672525b3f333de54fa0c42ef87f27861e41478f1eDavid Herrmann *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); 87733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs drm_gem_object_unreference_unlocked(gem); 87833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return 0; 87933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs } 88033dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 88133dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return -ENOENT; 88233dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs} 883