nouveau_display.c revision f4510a2752b75ad5847b7935b68c233cab497f97
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 4077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs#include <engine/disp.h> 41e0996aea4c349ba302b63203b7d5cab6034dbdcaBen Skeggs 421d7c71a3e2f77336df536855b0efd2dc5bdeb41bBen Skeggs#include <core/class.h> 431d7c71a3e2f77336df536855b0efd2dc5bdeb41bBen Skeggs 4451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsstatic int 4551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_handler(void *data, int head) 4651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 4751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs struct nouveau_drm *drm = data; 4851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs drm_handle_vblank(drm->dev, head); 4951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return NVKM_EVENT_KEEP; 5051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 5151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 5251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsint 5351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_enable(struct drm_device *dev, int head) 5451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 5551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 5651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (disp) { 5751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_event_get(disp->vblank[head]); 5851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return 0; 5951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 6051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return -EIO; 6151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 6251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 6351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsvoid 6451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_disable(struct drm_device *dev, int head) 6551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 6651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 6751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (disp) 6851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_event_put(disp->vblank[head]); 6951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 7051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 71d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsstatic inline int 72d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggscalc(int blanks, int blanke, int total, int line) 73d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 74d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (blanke >= blanks) { 75d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (line >= blanks) 76d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs line -= total; 77d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } else { 78d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (line >= blanks) 79d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs line -= total; 80d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs line -= blanke + 1; 81d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 82d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return line; 83d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 84d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 85d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsint 86d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsnouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, 87d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ktime_t *stime, ktime_t *etime) 88d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 89d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs const u32 mthd = NV04_DISP_SCANOUTPOS + nouveau_crtc(crtc)->index; 90d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct nouveau_display *disp = nouveau_display(crtc->dev); 91d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct nv04_display_scanoutpos args; 92d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs int ret, retry = 1; 93d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 94d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs do { 95d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret = nv_exec(disp->core, mthd, &args, sizeof(args)); 96d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (ret != 0) 97d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return 0; 98d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 99d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (args.vline) { 100d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret |= DRM_SCANOUTPOS_ACCURATE; 101d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret |= DRM_SCANOUTPOS_VALID; 102d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs break; 103d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 104d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 105d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (retry) ndelay(crtc->linedur_ns); 106d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } while (retry--); 107d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 1086c3252bc83155ae69d78fefdc7458aa64d8a87dbMario Kleiner *hpos = args.hline; 109d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs *vpos = calc(args.vblanks, args.vblanke, args.vtotal, args.vline); 110d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (stime) *stime = ns_to_ktime(args.time[0]); 111d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (etime) *etime = ns_to_ktime(args.time[1]); 112d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 113d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (*vpos < 0) 114d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret |= DRM_SCANOUTPOS_INVBL; 115d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return ret; 116d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 117d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 118d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsint 119d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsnouveau_display_scanoutpos(struct drm_device *dev, int head, unsigned int flags, 120d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) 121d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 122d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct drm_crtc *crtc; 123d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 124d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 125d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (nouveau_crtc(crtc)->index == head) { 126d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return nouveau_display_scanoutpos_head(crtc, vpos, hpos, 127d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs stime, etime); 128d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 129d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 130d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 131d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return 0; 132d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 133d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 134d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsint 135d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsnouveau_display_vblstamp(struct drm_device *dev, int head, int *max_error, 136d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct timeval *time, unsigned flags) 137d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 138d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct drm_crtc *crtc; 139d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 140d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 141d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (nouveau_crtc(crtc)->index == head) { 142d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return drm_calc_vbltimestamp_from_scanoutpos(dev, 143d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs head, max_error, time, flags, crtc, 144d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs &crtc->hwmode); 145d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 146d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 147d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 148d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return -EINVAL; 149d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 150d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 15151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsstatic void 15251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_fini(struct drm_device *dev) 15351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 15451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 15551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs int i; 15651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 1571139ffb96b3f4e8be9006552d2dd4d302d62c2eeBen Skeggs drm_vblank_cleanup(dev); 1581139ffb96b3f4e8be9006552d2dd4d302d62c2eeBen Skeggs 15951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (disp->vblank) { 16051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs for (i = 0; i < dev->mode_config.num_crtc; i++) 16151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_event_ref(NULL, &disp->vblank[i]); 16251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs kfree(disp->vblank); 16351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs disp->vblank = NULL; 16451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 16551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 16651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 16751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsstatic int 16851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_init(struct drm_device *dev) 16951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 17051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 17151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 17251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs struct nouveau_disp *pdisp = nouveau_disp(drm->device); 17351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs int ret, i; 17451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 17551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs disp->vblank = kzalloc(dev->mode_config.num_crtc * 17651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs sizeof(*disp->vblank), GFP_KERNEL); 17751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (!disp->vblank) 17851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return -ENOMEM; 17951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 18051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs for (i = 0; i < dev->mode_config.num_crtc; i++) { 18151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs ret = nouveau_event_new(pdisp->vblank, i, 18251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_handler, 18351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs drm, &disp->vblank[i]); 18451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (ret) { 18551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_fini(dev); 18651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return ret; 18751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 18851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 18951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 19051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs ret = drm_vblank_init(dev, dev->mode_config.num_crtc); 19151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (ret) { 19251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_fini(dev); 19351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return ret; 19451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 19551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 19651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return 0; 19751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 19851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 1996ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic void 2006ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) 2016ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2026ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 2036ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 204bc9025bdc4e2b591734cca17697093845007b63dLuca Barbieri if (fb->nvbo) 20555fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann drm_gem_object_unreference_unlocked(&fb->nvbo->gem); 2066ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2076ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs drm_framebuffer_cleanup(drm_fb); 2086ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs kfree(fb); 2096ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2106ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic int 2126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, 2136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_file *file_priv, 2146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs unsigned int *handle) 2156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2166ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 2176ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 21855fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann return drm_gem_handle_create(file_priv, &fb->nvbo->gem, handle); 2196ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2216ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { 2226ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .destroy = nouveau_user_framebuffer_destroy, 2236ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .create_handle = nouveau_user_framebuffer_create_handle, 2246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}; 2256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 226386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlieint 22745c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggsnouveau_framebuffer_init(struct drm_device *dev, 22845c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs struct nouveau_framebuffer *nv_fb, 229308e5bcbdb10452e8aba31aa21432fb67ee46d72Jesse Barnes struct drm_mode_fb_cmd2 *mode_cmd, 23045c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs struct nouveau_bo *nvbo) 2316ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 23277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 23345c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs struct drm_framebuffer *fb = &nv_fb->base; 2346ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int ret; 2356ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 23645c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs drm_helper_mode_fill_fb_struct(fb, mode_cmd); 23745c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs nv_fb->nvbo = nvbo; 23845c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs 23977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->card_type >= NV_50) { 24045c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs u32 tile_flags = nouveau_bo_tile_layout(nvbo); 24145c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs if (tile_flags == 0x7a00 || 24245c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs tile_flags == 0xfe00) 24345c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs nv_fb->r_dma = NvEvoFB32; 24445c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs else 24545c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs if (tile_flags == 0x7000) 24645c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs nv_fb->r_dma = NvEvoFB16; 24745c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs else 24845c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs nv_fb->r_dma = NvEvoVRAM_LP; 24945c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs 25045c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs switch (fb->depth) { 2514f6029da58ba9204c98e33f4f3737fe085c87a6fBen Skeggs case 8: nv_fb->r_format = 0x1e00; break; 2524f6029da58ba9204c98e33f4f3737fe085c87a6fBen Skeggs case 15: nv_fb->r_format = 0xe900; break; 2534f6029da58ba9204c98e33f4f3737fe085c87a6fBen Skeggs case 16: nv_fb->r_format = 0xe800; break; 25445c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs case 24: 2554f6029da58ba9204c98e33f4f3737fe085c87a6fBen Skeggs case 32: nv_fb->r_format = 0xcf00; break; 2564f6029da58ba9204c98e33f4f3737fe085c87a6fBen Skeggs case 30: nv_fb->r_format = 0xd100; break; 25745c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs default: 25877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs NV_ERROR(drm, "unknown depth %d\n", fb->depth); 25945c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs return -EINVAL; 26045c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs } 26145c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs 262bd9c5a2016307164c419c5e24a46921c10e620a0Maarten Lankhorst if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) { 263bd9c5a2016307164c419c5e24a46921c10e620a0Maarten Lankhorst NV_ERROR(drm, "framebuffer requires contiguous bo\n"); 264bd9c5a2016307164c419c5e24a46921c10e620a0Maarten Lankhorst return -EINVAL; 265bd9c5a2016307164c419c5e24a46921c10e620a0Maarten Lankhorst } 266bd9c5a2016307164c419c5e24a46921c10e620a0Maarten Lankhorst 26777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->chipset == 0x50) 26845c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs nv_fb->r_format |= (tile_flags << 8); 26945c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs 2702fad3d5e2bc8776a2963399a936db13814107646Ben Skeggs if (!tile_flags) { 27177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->card_type < NV_D0) 27201f2c7730e188077026c5f766f85f329c7000c54Ville Syrjälä nv_fb->r_pitch = 0x00100000 | fb->pitches[0]; 2732fad3d5e2bc8776a2963399a936db13814107646Ben Skeggs else 27401f2c7730e188077026c5f766f85f329c7000c54Ville Syrjälä nv_fb->r_pitch = 0x01000000 | fb->pitches[0]; 2752fad3d5e2bc8776a2963399a936db13814107646Ben Skeggs } else { 27645c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs u32 mode = nvbo->tile_mode; 27777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->card_type >= NV_C0) 27845c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs mode >>= 4; 27901f2c7730e188077026c5f766f85f329c7000c54Ville Syrjälä nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode; 28045c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs } 28145c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs } 28245c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs 283c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); 284c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter if (ret) { 285c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter return ret; 286c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter } 287c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter 288386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie return 0; 2896ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2906ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2916ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic struct drm_framebuffer * 2926ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create(struct drm_device *dev, 2936ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_file *file_priv, 294308e5bcbdb10452e8aba31aa21432fb67ee46d72Jesse Barnes struct drm_mode_fb_cmd2 *mode_cmd) 2956ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 296386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie struct nouveau_framebuffer *nouveau_fb; 2976ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_gem_object *gem; 298fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst int ret = -ENOMEM; 2996ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 300308e5bcbdb10452e8aba31aa21432fb67ee46d72Jesse Barnes gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); 3016ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (!gem) 302cce13ff7596985903ad924504562190a2c163a63Chris Wilson return ERR_PTR(-ENOENT); 3036ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 304386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); 305386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie if (!nouveau_fb) 306fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst goto err_unref; 307386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie 308386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem)); 309fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst if (ret) 310fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst goto err; 3116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 312386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie return &nouveau_fb->base; 313fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst 314fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorsterr: 315fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst kfree(nouveau_fb); 316fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorsterr_unref: 317fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst drm_gem_object_unreference(gem); 318fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst return ERR_PTR(ret); 3196ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 3206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 32127d5030a235d89842ed70e18d924f017b34a496dBen Skeggsstatic const struct drm_mode_config_funcs nouveau_mode_config_funcs = { 3226ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .fb_create = nouveau_user_framebuffer_create, 323eb1f8e4f3be898df808e2dfc131099f5831d491dDave Airlie .output_poll_changed = nouveau_fbcon_output_poll_changed, 3246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}; 3256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 326b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 3274a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstruct nouveau_drm_prop_enum_list { 328de69185573586302ada2e59ba41835df36986277Ben Skeggs u8 gen_mask; 329b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs int type; 330b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs char *name; 331b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs}; 332b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 3334a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstatic struct nouveau_drm_prop_enum_list underscan[] = { 3349285462273cbccb27187d5308ed95f94a9ceb1deBen Skeggs { 6, UNDERSCAN_AUTO, "auto" }, 3359285462273cbccb27187d5308ed95f94a9ceb1deBen Skeggs { 6, UNDERSCAN_OFF, "off" }, 3369285462273cbccb27187d5308ed95f94a9ceb1deBen Skeggs { 6, UNDERSCAN_ON, "on" }, 337de69185573586302ada2e59ba41835df36986277Ben Skeggs {} 338b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs}; 339b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 3404a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstatic struct nouveau_drm_prop_enum_list dither_mode[] = { 341de69185573586302ada2e59ba41835df36986277Ben Skeggs { 7, DITHERING_MODE_AUTO, "auto" }, 342de69185573586302ada2e59ba41835df36986277Ben Skeggs { 7, DITHERING_MODE_OFF, "off" }, 343de69185573586302ada2e59ba41835df36986277Ben Skeggs { 1, DITHERING_MODE_ON, "on" }, 344de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_MODE_STATIC2X2, "static 2x2" }, 345de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_MODE_DYNAMIC2X2, "dynamic 2x2" }, 346de69185573586302ada2e59ba41835df36986277Ben Skeggs { 4, DITHERING_MODE_TEMPORAL, "temporal" }, 347de69185573586302ada2e59ba41835df36986277Ben Skeggs {} 348de69185573586302ada2e59ba41835df36986277Ben Skeggs}; 349de69185573586302ada2e59ba41835df36986277Ben Skeggs 3504a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstatic struct nouveau_drm_prop_enum_list dither_depth[] = { 351de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_DEPTH_AUTO, "auto" }, 352de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, 353de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, 354de69185573586302ada2e59ba41835df36986277Ben Skeggs {} 355de69185573586302ada2e59ba41835df36986277Ben Skeggs}; 356de69185573586302ada2e59ba41835df36986277Ben Skeggs 357de69185573586302ada2e59ba41835df36986277Ben Skeggs#define PROP_ENUM(p,gen,n,list) do { \ 3584a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauer struct nouveau_drm_prop_enum_list *l = (list); \ 359de69185573586302ada2e59ba41835df36986277Ben Skeggs int c = 0; \ 360de69185573586302ada2e59ba41835df36986277Ben Skeggs while (l->gen_mask) { \ 361de69185573586302ada2e59ba41835df36986277Ben Skeggs if (l->gen_mask & (1 << (gen))) \ 362de69185573586302ada2e59ba41835df36986277Ben Skeggs c++; \ 363de69185573586302ada2e59ba41835df36986277Ben Skeggs l++; \ 364de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 365de69185573586302ada2e59ba41835df36986277Ben Skeggs if (c) { \ 366de69185573586302ada2e59ba41835df36986277Ben Skeggs p = drm_property_create(dev, DRM_MODE_PROP_ENUM, n, c); \ 367de69185573586302ada2e59ba41835df36986277Ben Skeggs l = (list); \ 368de69185573586302ada2e59ba41835df36986277Ben Skeggs c = 0; \ 369de69185573586302ada2e59ba41835df36986277Ben Skeggs while (p && l->gen_mask) { \ 370de69185573586302ada2e59ba41835df36986277Ben Skeggs if (l->gen_mask & (1 << (gen))) { \ 371de69185573586302ada2e59ba41835df36986277Ben Skeggs drm_property_add_enum(p, c, l->type, l->name); \ 372de69185573586302ada2e59ba41835df36986277Ben Skeggs c++; \ 373de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 374de69185573586302ada2e59ba41835df36986277Ben Skeggs l++; \ 375de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 376de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 377de69185573586302ada2e59ba41835df36986277Ben Skeggs} while(0) 378de69185573586302ada2e59ba41835df36986277Ben Skeggs 379042206c0cd4924879c4292c5ffa2bf1e8023ae5aFrancisco Jerezint 380f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsnouveau_display_init(struct drm_device *dev) 381f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs{ 38277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 38352c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct drm_connector *connector; 384f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs int ret; 385f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 386f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs ret = disp->init(dev); 38752c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs if (ret) 38852c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs return ret; 38952c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs 3907df898b1a70b13c3a8892625f4ead929d9554293Ben Skeggs /* enable polling for external displays */ 39152c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs drm_kms_helper_poll_enable(dev); 39252c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs 39352c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs /* enable hotplug interrupts */ 39452c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 39552c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct nouveau_connector *conn = nouveau_connector(connector); 39651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (conn->hpd_func) nouveau_event_get(conn->hpd_func); 397f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs } 398f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 399f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs return ret; 400f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs} 401f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 402f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsvoid 403f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsnouveau_display_fini(struct drm_device *dev) 404f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs{ 40577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 40652c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct drm_connector *connector; 40752c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs 40852c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs /* disable hotplug interrupts */ 40952c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 41052c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct nouveau_connector *conn = nouveau_connector(connector); 41151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (conn->hpd_func) nouveau_event_put(conn->hpd_func); 41252c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs } 413f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 414f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs drm_kms_helper_poll_disable(dev); 415f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs disp->fini(dev); 416f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs} 417f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 418f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsint 41927d5030a235d89842ed70e18d924f017b34a496dBen Skeggsnouveau_display_create(struct drm_device *dev) 42027d5030a235d89842ed70e18d924f017b34a496dBen Skeggs{ 42177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 422420b94697722512a2c0732970dc1530197a49adbAlexandre Courbot struct nouveau_device *device = nouveau_dev(dev); 42377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp; 424de69185573586302ada2e59ba41835df36986277Ben Skeggs int ret, gen; 42527d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 42677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); 42777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!disp) 42877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs return -ENOMEM; 42977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 43027d5030a235d89842ed70e18d924f017b34a496dBen Skeggs drm_mode_config_init(dev); 43127d5030a235d89842ed70e18d924f017b34a496dBen Skeggs drm_mode_create_scaling_mode_property(dev); 4324ceca5f8649125645fc4e7f178a1dca1345ab9b4Ben Skeggs drm_mode_create_dvi_i_properties(dev); 433de69185573586302ada2e59ba41835df36986277Ben Skeggs 43477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->card_type < NV_50) 435de69185573586302ada2e59ba41835df36986277Ben Skeggs gen = 0; 436de69185573586302ada2e59ba41835df36986277Ben Skeggs else 43777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->card_type < NV_D0) 438de69185573586302ada2e59ba41835df36986277Ben Skeggs gen = 1; 439de69185573586302ada2e59ba41835df36986277Ben Skeggs else 440de69185573586302ada2e59ba41835df36986277Ben Skeggs gen = 2; 441de69185573586302ada2e59ba41835df36986277Ben Skeggs 442de69185573586302ada2e59ba41835df36986277Ben Skeggs PROP_ENUM(disp->dithering_mode, gen, "dithering mode", dither_mode); 443de69185573586302ada2e59ba41835df36986277Ben Skeggs PROP_ENUM(disp->dithering_depth, gen, "dithering depth", dither_depth); 444de69185573586302ada2e59ba41835df36986277Ben Skeggs PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); 445b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 446b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs disp->underscan_hborder_property = 447d9bc3c02e36d844c2d980e65ddda5c7699e073f8Sascha Hauer drm_property_create_range(dev, 0, "underscan hborder", 0, 128); 448b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 449b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs disp->underscan_vborder_property = 450d9bc3c02e36d844c2d980e65ddda5c7699e073f8Sascha Hauer drm_property_create_range(dev, 0, "underscan vborder", 0, 128); 451b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 452f9887d091149406de5c8b388f7e0bb6932dd621bBen Skeggs if (gen >= 1) { 45303e9a04050f5333c779ed37c027a6aae5644cf6cMarcin Slusarz /* -90..+90 */ 454df26bc9c320602539b1b5b3d85786e4c8de7bf43Christoph Bumiller disp->vibrant_hue_property = 45503e9a04050f5333c779ed37c027a6aae5644cf6cMarcin Slusarz drm_property_create_range(dev, 0, "vibrant hue", 0, 180); 456df26bc9c320602539b1b5b3d85786e4c8de7bf43Christoph Bumiller 45703e9a04050f5333c779ed37c027a6aae5644cf6cMarcin Slusarz /* -100..+100 */ 458df26bc9c320602539b1b5b3d85786e4c8de7bf43Christoph Bumiller disp->color_vibrance_property = 45903e9a04050f5333c779ed37c027a6aae5644cf6cMarcin Slusarz drm_property_create_range(dev, 0, "color vibrance", 0, 200); 460df26bc9c320602539b1b5b3d85786e4c8de7bf43Christoph Bumiller } 461df26bc9c320602539b1b5b3d85786e4c8de7bf43Christoph Bumiller 462e6ecefaadfcdb03db8ac9e739b4ba7a93a8811b3Laurent Pinchart dev->mode_config.funcs = &nouveau_mode_config_funcs; 463420b94697722512a2c0732970dc1530197a49adbAlexandre Courbot dev->mode_config.fb_base = nv_device_resource_start(device, 1); 46427d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 46527d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.min_width = 0; 46627d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.min_height = 0; 46777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->card_type < NV_10) { 46827d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_width = 2048; 46927d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_height = 2048; 47027d5030a235d89842ed70e18d924f017b34a496dBen Skeggs } else 47177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->card_type < NV_50) { 47227d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_width = 4096; 47327d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_height = 4096; 47427d5030a235d89842ed70e18d924f017b34a496dBen Skeggs } else { 47527d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_width = 8192; 47627d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_height = 8192; 47727d5030a235d89842ed70e18d924f017b34a496dBen Skeggs } 47827d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 479f1377998eede7a8caa124fcf6a589b02c9e2bac7Dave Airlie dev->mode_config.preferred_depth = 24; 480f1377998eede7a8caa124fcf6a589b02c9e2bac7Dave Airlie dev->mode_config.prefer_shadow = 1; 481f1377998eede7a8caa124fcf6a589b02c9e2bac7Dave Airlie 482b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs if (nv_device(drm->device)->chipset < 0x11) 483b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs dev->mode_config.async_page_flip = false; 484b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs else 485b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs dev->mode_config.async_page_flip = true; 486b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 487f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs drm_kms_helper_poll_init(dev); 488f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs drm_kms_helper_poll_disable(dev); 489f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 490fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (drm->vbios.dcb.entries) { 4912332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs static const u16 oclass[] = { 4920b681687fe9eaa552059030a90897a78fea8f86aBen Skeggs GM107_DISP_CLASS, 4932332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVF0_DISP_CLASS, 4942332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVE0_DISP_CLASS, 4952332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVD0_DISP_CLASS, 4962332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVA3_DISP_CLASS, 4972332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NV94_DISP_CLASS, 4982332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVA0_DISP_CLASS, 4992332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NV84_DISP_CLASS, 5002332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NV50_DISP_CLASS, 5012332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NV04_DISP_CLASS, 5022332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs }; 5032332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs int i; 5042332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs 5052332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { 5062332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, 5072332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NVDRM_DISPLAY, oclass[i], 5082332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs NULL, 0, &disp->core); 5092332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs } 5102332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs 5112332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs if (ret == 0) { 5122332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs if (nv_mclass(disp->core) < NV50_DISP_CLASS) 5132332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs ret = nv04_display_create(dev); 5142332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs else 5152332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs ret = nv50_display_create(dev); 5162332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs } 517fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs } else { 518fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs ret = 0; 519fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs } 5209430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs 521fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (ret) 522fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs goto disp_create_err; 5239430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs 524fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (dev->mode_config.num_crtc) { 52551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs ret = nouveau_display_vblank_init(dev); 526fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (ret) 527fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs goto vblank_err; 528f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs } 529f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 530fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs nouveau_backlight_init(dev); 5315ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz return 0; 5325ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz 5335ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarzvblank_err: 53477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs disp->dtor(dev); 5355ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarzdisp_create_err: 5365ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz drm_kms_helper_poll_fini(dev); 5375ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz drm_mode_config_cleanup(dev); 5382a44e4997c5fee8e1da1589ff57e0bd1c53f03ceBen Skeggs return ret; 53927d5030a235d89842ed70e18d924f017b34a496dBen Skeggs} 54027d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 54127d5030a235d89842ed70e18d924f017b34a496dBen Skeggsvoid 54227d5030a235d89842ed70e18d924f017b34a496dBen Skeggsnouveau_display_destroy(struct drm_device *dev) 54327d5030a235d89842ed70e18d924f017b34a496dBen Skeggs{ 54477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 5452332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 54627d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 54777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_backlight_exit(dev); 54851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_fini(dev); 549f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 550d6bf2f370703c0cab60bf1f5bf871a3f00eb8872Ben Skeggs drm_kms_helper_poll_fini(dev); 551d6bf2f370703c0cab60bf1f5bf871a3f00eb8872Ben Skeggs drm_mode_config_cleanup(dev); 552d6bf2f370703c0cab60bf1f5bf871a3f00eb8872Ben Skeggs 5539430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs if (disp->dtor) 5549430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs disp->dtor(dev); 555f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 5562332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_DISPLAY); 5572332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs 55877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_drm(dev)->display = NULL; 55977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs kfree(disp); 56077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs} 56177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 56277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggsint 56377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggsnouveau_display_suspend(struct drm_device *dev) 56477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs{ 56577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 56677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_crtc *crtc; 56777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 56877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_display_fini(dev); 56977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 570c52f4fa61d7504bacd94fd54f43fd0b5bdf74bbcBen Skeggs NV_INFO(drm, "unpinning framebuffer(s)...\n"); 57177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 57277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_framebuffer *nouveau_fb; 57377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 574f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 57577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!nouveau_fb || !nouveau_fb->nvbo) 57677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs continue; 57777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 57877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_unpin(nouveau_fb->nvbo); 57977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 58077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 58177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 58277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 58377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 58477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_unmap(nv_crtc->cursor.nvbo); 58577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_unpin(nv_crtc->cursor.nvbo); 58677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 58777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 58877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs return 0; 58977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs} 59077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 59177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggsvoid 5925addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlienouveau_display_repin(struct drm_device *dev) 59377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs{ 59477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 59577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_crtc *crtc; 59677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs int ret; 59777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 59877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 59977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_framebuffer *nouveau_fb; 60077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 601f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 60277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!nouveau_fb || !nouveau_fb->nvbo) 60377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs continue; 60477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 60577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); 60677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 60777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 60877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 60977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 61077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 61177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); 61277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!ret) 61377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs ret = nouveau_bo_map(nv_crtc->cursor.nvbo); 61477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (ret) 61577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs NV_ERROR(drm, "Could not pin/map cursor.\n"); 61677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 6175addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlie} 61877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 6195addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlievoid 6205addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlienouveau_display_resume(struct drm_device *dev) 6215addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlie{ 6225addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlie struct drm_crtc *crtc; 62377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_display_init(dev); 62477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 62577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs /* Force CLUT to get re-loaded during modeset */ 62677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 62777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 62877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 62977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->lut.depth = 0; 63077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 63177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 63277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs drm_helper_resume_force_mode(dev); 63377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 63477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 63577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 63677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs u32 offset = nv_crtc->cursor.nvbo->bo.offset; 63777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 63877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->cursor.set_offset(nv_crtc, offset); 63977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, 64077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->cursor_saved_y); 64177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 64227d5030a235d89842ed70e18d924f017b34a496dBen Skeggs} 64327d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 644332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezstatic int 645332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jereznouveau_page_flip_emit(struct nouveau_channel *chan, 646332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_bo *old_bo, 647332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_bo *new_bo, 648332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *s, 649332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_fence **pfence) 650332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez{ 651f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_fence_chan *fctx = chan->fence; 65277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = chan->drm; 65377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_device *dev = drm->dev; 654332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez unsigned long flags; 655332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez int ret; 656332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 657332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Queue it to the pending list */ 658332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_lock_irqsave(&dev->event_lock, flags); 659f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs list_add_tail(&s->head, &fctx->flip); 660332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 661332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 662332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Synchronize with the old framebuffer */ 663332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez ret = nouveau_fence_sync(old_bo->bo.sync_obj, chan); 664332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 665332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail; 666332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 667332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Emit the pageflip */ 6681e303c03af1e631de37ec77cc2513210910a812cBen Skeggs ret = RING_SPACE(chan, 2); 669332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 670332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail; 671332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 6721e303c03af1e631de37ec77cc2513210910a812cBen Skeggs if (nv_device(drm->device)->card_type < NV_C0) 6736d597027755b2eed4298b85ebe3cb5c93b29d1a9Ben Skeggs BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); 6741e303c03af1e631de37ec77cc2513210910a812cBen Skeggs else 6751e303c03af1e631de37ec77cc2513210910a812cBen Skeggs BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1); 6761e303c03af1e631de37ec77cc2513210910a812cBen Skeggs OUT_RING (chan, 0x00000000); 677bd2f2037a42d4657ead3be2918db22e63626cd35Ben Skeggs FIRE_RING (chan); 678332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 679264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs ret = nouveau_fence_new(chan, false, pfence); 680332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 681332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail; 682332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 683332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return 0; 684332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezfail: 685332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_lock_irqsave(&dev->event_lock, flags); 686332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez list_del(&s->head); 687332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 688332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return ret; 689332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez} 690332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 691332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezint 692332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jereznouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 693b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs struct drm_pending_vblank_event *event, u32 flags) 694332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez{ 695b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; 696332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct drm_device *dev = crtc->dev; 69777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 698f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; 699332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; 700332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *s; 701eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs struct nouveau_channel *chan = drm->channel; 702332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_fence *fence; 703332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez int ret; 704332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 70577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!drm->channel) 706332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return -ENODEV; 707332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 708332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez s = kzalloc(sizeof(*s), GFP_KERNEL); 709332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (!s) 710332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return -ENOMEM; 711332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 712d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst if (new_bo != old_bo) { 713d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); 714d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst if (ret) 715d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst goto fail_free; 716d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst } 717d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst 718d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst mutex_lock(&chan->cli->mutex); 719d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst 720eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs /* synchronise rendering channel with the kernel's channel */ 721eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs spin_lock(&new_bo->bo.bdev->fence_lock); 722eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs fence = nouveau_fence_ref(new_bo->bo.sync_obj); 723eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs spin_unlock(&new_bo->bo.bdev->fence_lock); 724eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs ret = nouveau_fence_sync(fence, chan); 7252fd04c81dc652689b104ab16eba26146dde5c43fBen Skeggs nouveau_fence_unref(&fence); 726eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs if (ret) 72709c3de135063f93d7137ad112f551f293b1204cfMaarten Lankhorst goto fail_unpin; 728b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst 72907ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs ret = ttm_bo_reserve(&old_bo->bo, true, false, false, NULL); 730060810d7abaabcab282e062c595871d661561400Ben Skeggs if (ret) 731060810d7abaabcab282e062c595871d661561400Ben Skeggs goto fail_unpin; 732b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst 733b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst /* Initialize a page flip struct */ 734b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst *s = (struct nouveau_page_flip_state) 735b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst { { }, event, nouveau_crtc(crtc)->index, 736b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y, 737b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst new_bo->bo.offset }; 738b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst 739332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Emit a page flip */ 74077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->card_type >= NV_50) { 741b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); 742060810d7abaabcab282e062c595871d661561400Ben Skeggs if (ret) 743d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs goto fail_unreserve; 74478ae0ad403daf11cf63da86923d2b5dbeda3af8fBen Skeggs } else { 74578ae0ad403daf11cf63da86923d2b5dbeda3af8fBen Skeggs struct nv04_display *dispnv04 = nv04_display(dev); 746b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs int head = nouveau_crtc(crtc)->index; 747b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 748b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs if (swap_interval) { 749b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs ret = RING_SPACE(chan, 8); 750b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs if (ret) 751b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs goto fail_unreserve; 752b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 753b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); 754b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, 0); 755b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); 756b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, head); 757b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1); 758b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, 0); 759b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1); 760b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, 0); 761b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs } 762b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 763b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs nouveau_bo_ref(new_bo, &dispnv04->image[head]); 764d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs } 765d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs 766332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); 76777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs mutex_unlock(&chan->cli->mutex); 768332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 769332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail_unreserve; 770332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 771332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Update the crtc struct and cleanup */ 772f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper crtc->primary->fb = fb; 773332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 77407ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs nouveau_bo_fence(old_bo, fence); 77507ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs ttm_bo_unreserve(&old_bo->bo); 776060810d7abaabcab282e062c595871d661561400Ben Skeggs if (old_bo != new_bo) 777b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst nouveau_bo_unpin(old_bo); 778332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez nouveau_fence_unref(&fence); 779332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return 0; 780332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 781332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezfail_unreserve: 78207ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs ttm_bo_unreserve(&old_bo->bo); 783060810d7abaabcab282e062c595871d661561400Ben Skeggsfail_unpin: 784060810d7abaabcab282e062c595871d661561400Ben Skeggs mutex_unlock(&chan->cli->mutex); 785060810d7abaabcab282e062c595871d661561400Ben Skeggs if (old_bo != new_bo) 786b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst nouveau_bo_unpin(new_bo); 787332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezfail_free: 788332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez kfree(s); 789332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return ret; 790332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez} 791332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 792332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezint 793332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jereznouveau_finish_page_flip(struct nouveau_channel *chan, 794332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *ps) 795332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez{ 796f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_fence_chan *fctx = chan->fence; 79777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = chan->drm; 79877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_device *dev = drm->dev; 799332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *s; 800332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez unsigned long flags; 801332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 802332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_lock_irqsave(&dev->event_lock, flags); 803332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 804f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs if (list_empty(&fctx->flip)) { 80577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs NV_ERROR(drm, "unexpected pageflip\n"); 806332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 807332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return -EINVAL; 808332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez } 809332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 810f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); 81195d38d144ab4520aea3f8fcfacc5fd62d3bf2697Rob Clark if (s->event) 812f074d733866628973eca0ddb0c534ef4561da9e0Maarten Lankhorst drm_send_vblank_event(dev, s->crtc, s->event); 813332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 814332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez list_del(&s->head); 815d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs if (ps) 816d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs *ps = *s; 817332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez kfree(s); 818332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 819332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 820332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return 0; 821332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez} 82233dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 82333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsint 824f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggsnouveau_flip_complete(void *data) 825f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs{ 826f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_channel *chan = data; 82777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = chan->drm; 828f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_page_flip_state state; 829f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 830f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs if (!nouveau_finish_page_flip(chan, &state)) { 83177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (nv_device(drm->device)->card_type < NV_50) { 83277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_set_crtc_base(drm->dev, state.crtc, state.offset + 833f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs state.y * state.pitch + 834f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs state.x * state.bpp / 8); 835f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs } 836f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs } 837f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 838f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs return 0; 839f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs} 840f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 841f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggsint 84233dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsnouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, 84333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct drm_mode_create_dumb *args) 84433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs{ 84533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct nouveau_bo *bo; 84633dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs int ret; 84733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 84833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs args->pitch = roundup(args->width * (args->bpp / 8), 256); 84933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs args->size = args->pitch * args->height; 85033dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs args->size = roundup(args->size, PAGE_SIZE); 85133dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 852610bd7da160f76f1644ecb4cd7f39511b49a22ccDave Airlie ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo); 85333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs if (ret) 85433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return ret; 85533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 85655fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); 85755fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann drm_gem_object_unreference_unlocked(&bo->gem); 85833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return ret; 85933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs} 86033dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 86133dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsint 86233dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsnouveau_display_dumb_map_offset(struct drm_file *file_priv, 86333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct drm_device *dev, 86433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs uint32_t handle, uint64_t *poffset) 86533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs{ 86633dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct drm_gem_object *gem; 86733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 86833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs gem = drm_gem_object_lookup(dev, file_priv, handle); 86933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs if (gem) { 87055fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann struct nouveau_bo *bo = nouveau_gem_object(gem); 87172525b3f333de54fa0c42ef87f27861e41478f1eDavid Herrmann *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); 87233dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs drm_gem_object_unreference_unlocked(gem); 87333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return 0; 87433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs } 87533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 87633dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return -ENOENT; 87733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs} 878