nouveau_display.c revision 80bc340b3dd720c5b7818e21a9a1ee36e1d7ef30
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 30fdb751ef2bbc78314d1e01d3425cfacfb19b9f86Ben Skeggs#include <nvif/class.h> 31fdb751ef2bbc78314d1e01d3425cfacfb19b9f86Ben Skeggs 326ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#include "nouveau_fbcon.h" 331a6463425552a8b9960e5a19b25421895846925cBen Skeggs#include "dispnv04/hw.h" 34332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez#include "nouveau_crtc.h" 35332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez#include "nouveau_dma.h" 3677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs#include "nouveau_gem.h" 37de69185573586302ada2e59ba41835df36986277Ben Skeggs#include "nouveau_connector.h" 3845c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs#include "nv50_display.h" 396ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 40ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs#include "nouveau_fence.h" 41ebb945a94bba2ce8dff7b0942ff2b3f2a52a0a69Ben Skeggs 4279ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs#include <nvif/event.h> 431d7c71a3e2f77336df536855b0efd2dc5bdeb41bBen Skeggs 4451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsstatic int 4580bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggsnouveau_display_vblank_handler(struct nvif_notify *notify) 4651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 4779ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs struct nouveau_crtc *nv_crtc = 4879ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs container_of(notify, typeof(*nv_crtc), vblank); 49b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs drm_handle_vblank(nv_crtc->base.dev, nv_crtc->index); 5080bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggs return NVIF_NOTIFY_KEEP; 5151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 5251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 5351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsint 5451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_enable(struct drm_device *dev, int head) 5551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 56b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct drm_crtc *crtc; 57b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 58b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 59b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs if (nv_crtc->index == head) { 6080bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggs nvif_notify_get(&nv_crtc->vblank); 61b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs return 0; 62b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs } 6351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 64b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs return -EINVAL; 6551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 6651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 6751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsvoid 6851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_disable(struct drm_device *dev, int head) 6951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 70b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct drm_crtc *crtc; 71b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 72b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 73b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs if (nv_crtc->index == head) { 7480bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggs nvif_notify_put(&nv_crtc->vblank); 75b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs return; 76b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs } 77b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs } 7851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 7951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 80d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsstatic inline int 81d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggscalc(int blanks, int blanke, int total, int line) 82d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 83d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (blanke >= blanks) { 84d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (line >= blanks) 85d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs line -= total; 86d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } else { 87d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (line >= blanks) 88d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs line -= total; 89d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs line -= blanke + 1; 90d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 91d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return line; 92d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 93d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 94d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsint 95d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsnouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, 96d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ktime_t *stime, ktime_t *etime) 97d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 984952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs struct { 994952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs struct nv04_disp_mthd_v0 base; 1004952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs struct nv04_disp_scanoutpos_v0 scan; 1014952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs } args = { 1024952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs .base.method = NV04_DISP_SCANOUTPOS, 1034952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs .base.head = nouveau_crtc(crtc)->index, 1044952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs }; 105d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct nouveau_display *disp = nouveau_display(crtc->dev); 106d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs int ret, retry = 1; 107d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 108d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs do { 1094952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); 110d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (ret != 0) 111d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return 0; 112d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 1134952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs if (args.scan.vline) { 114d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret |= DRM_SCANOUTPOS_ACCURATE; 115d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret |= DRM_SCANOUTPOS_VALID; 116d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs break; 117d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 118d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 119d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (retry) ndelay(crtc->linedur_ns); 120d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } while (retry--); 121d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 1224952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs *hpos = args.scan.hline; 1234952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs *vpos = calc(args.scan.vblanks, args.scan.vblanke, 1244952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs args.scan.vtotal, args.scan.vline); 1254952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs if (stime) *stime = ns_to_ktime(args.scan.time[0]); 1264952b4d339033c2019bbd00f28f422b6fc340408Ben Skeggs if (etime) *etime = ns_to_ktime(args.scan.time[1]); 127d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 128d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (*vpos < 0) 129d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs ret |= DRM_SCANOUTPOS_INVBL; 130d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return ret; 131d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 132d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 133d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsint 134d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsnouveau_display_scanoutpos(struct drm_device *dev, int head, unsigned int flags, 135d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) 136d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 137d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct drm_crtc *crtc; 138d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 139d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 140d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (nouveau_crtc(crtc)->index == head) { 141d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return nouveau_display_scanoutpos_head(crtc, vpos, hpos, 142d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs stime, etime); 143d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 144d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 145d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 146d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return 0; 147d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 148d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 149d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsint 150d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggsnouveau_display_vblstamp(struct drm_device *dev, int head, int *max_error, 151d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct timeval *time, unsigned flags) 152d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs{ 153d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs struct drm_crtc *crtc; 154d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 155d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 156d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs if (nouveau_crtc(crtc)->index == head) { 157d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return drm_calc_vbltimestamp_from_scanoutpos(dev, 158d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs head, max_error, time, flags, crtc, 159d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs &crtc->hwmode); 160d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 161d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs } 162d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 163d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs return -EINVAL; 164d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs} 165d83ef85395c9c1fae7636dca59f95c64963b307dBen Skeggs 16651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsstatic void 16751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_fini(struct drm_device *dev) 16851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 169b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct drm_crtc *crtc; 17051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 1711139ffb96b3f4e8be9006552d2dd4d302d62c2eeBen Skeggs drm_vblank_cleanup(dev); 1721139ffb96b3f4e8be9006552d2dd4d302d62c2eeBen Skeggs 173b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 174b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 17580bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggs nvif_notify_fini(&nv_crtc->vblank); 17651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 17751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 17851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 17951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsstatic int 18051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggsnouveau_display_vblank_init(struct drm_device *dev) 18151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs{ 18280bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 183b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct drm_crtc *crtc; 184b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs int ret; 18551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 186b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 187b12f0ae9e8dfee55c7757f9c4be3b1154c366754Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 18880bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggs ret = nvif_notify_init(&disp->disp, NULL, 18979ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs nouveau_display_vblank_handler, false, 19080bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggs NV04_DISP_NTFY_VBLANK, 19179ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs &(struct nvif_notify_head_req_v0) { 19279ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs .head = nv_crtc->index, 19379ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs }, 19479ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs sizeof(struct nvif_notify_head_req_v0), 19579ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs sizeof(struct nvif_notify_head_rep_v0), 19679ca27706a034b683196c85f5c6901b78e5ab8f0Ben Skeggs &nv_crtc->vblank); 19751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (ret) { 19851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_fini(dev); 19951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return ret; 20051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 20151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 20251cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 20351cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs ret = drm_vblank_init(dev, dev->mode_config.num_crtc); 20451cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs if (ret) { 20551cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_fini(dev); 20651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return ret; 20751cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs } 20851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 20951cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs return 0; 21051cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs} 21151cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs 2126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic void 2136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) 2146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 216ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs struct nouveau_display *disp = nouveau_display(drm_fb->dev); 217ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs 218ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs if (disp->fb_dtor) 219ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs disp->fb_dtor(drm_fb); 2206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 221bc9025bdc4e2b591734cca17697093845007b63dLuca Barbieri if (fb->nvbo) 22255fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann drm_gem_object_unreference_unlocked(&fb->nvbo->gem); 2236ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs drm_framebuffer_cleanup(drm_fb); 2256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs kfree(fb); 2266ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2276ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2286ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic int 2296ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, 2306ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_file *file_priv, 2316ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs unsigned int *handle) 2326ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 2336ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 2346ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 23555fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann return drm_gem_handle_create(file_priv, &fb->nvbo->gem, handle); 2366ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2376ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2386ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { 2396ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .destroy = nouveau_user_framebuffer_destroy, 2406ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .create_handle = nouveau_user_framebuffer_create_handle, 2416ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}; 2426ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 243386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlieint 24445c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggsnouveau_framebuffer_init(struct drm_device *dev, 24545c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs struct nouveau_framebuffer *nv_fb, 246308e5bcbdb10452e8aba31aa21432fb67ee46d72Jesse Barnes struct drm_mode_fb_cmd2 *mode_cmd, 24745c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs struct nouveau_bo *nvbo) 2486ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 249ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 25045c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs struct drm_framebuffer *fb = &nv_fb->base; 2516ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int ret; 2526ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 25345c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs drm_helper_mode_fill_fb_struct(fb, mode_cmd); 25445c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs nv_fb->nvbo = nvbo; 25545c4e0aae96c6354bf5131a282a74fe38d032de3Ben Skeggs 256c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); 257ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs if (ret) 258c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter return ret; 259ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs 260ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs if (disp->fb_ctor) { 261ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs ret = disp->fb_ctor(fb); 262ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs if (ret) 263ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs disp->fb_dtor(fb); 264c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter } 265c7d73f6a8ad71f9d9f58c86981322c6e48093a4fDaniel Vetter 266ab0af559d34b6817768c1720859aef7d7009ee57Ben Skeggs return ret; 2676ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2686ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 2696ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic struct drm_framebuffer * 2706ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create(struct drm_device *dev, 2716ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_file *file_priv, 272308e5bcbdb10452e8aba31aa21432fb67ee46d72Jesse Barnes struct drm_mode_fb_cmd2 *mode_cmd) 2736ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 274386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie struct nouveau_framebuffer *nouveau_fb; 2756ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_gem_object *gem; 276fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst int ret = -ENOMEM; 2776ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 278308e5bcbdb10452e8aba31aa21432fb67ee46d72Jesse Barnes gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); 2796ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (!gem) 280cce13ff7596985903ad924504562190a2c163a63Chris Wilson return ERR_PTR(-ENOENT); 2816ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 282386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); 283386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie if (!nouveau_fb) 284fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst goto err_unref; 285386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie 286386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem)); 287fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst if (ret) 288fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst goto err; 2896ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 290386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie return &nouveau_fb->base; 291fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst 292fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorsterr: 293fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst kfree(nouveau_fb); 294fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorsterr_unref: 295fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst drm_gem_object_unreference(gem); 296fdfb8332651db7a280851dfccfc4f0cff4bcd052Maarten Lankhorst return ERR_PTR(ret); 2976ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 2986ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 29927d5030a235d89842ed70e18d924f017b34a496dBen Skeggsstatic const struct drm_mode_config_funcs nouveau_mode_config_funcs = { 3006ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .fb_create = nouveau_user_framebuffer_create, 301eb1f8e4f3be898df808e2dfc131099f5831d491dDave Airlie .output_poll_changed = nouveau_fbcon_output_poll_changed, 3026ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}; 3036ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 304b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 3054a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstruct nouveau_drm_prop_enum_list { 306de69185573586302ada2e59ba41835df36986277Ben Skeggs u8 gen_mask; 307b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs int type; 308b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs char *name; 309b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs}; 310b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 3114a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstatic struct nouveau_drm_prop_enum_list underscan[] = { 3129285462273cbccb27187d5308ed95f94a9ceb1deBen Skeggs { 6, UNDERSCAN_AUTO, "auto" }, 3139285462273cbccb27187d5308ed95f94a9ceb1deBen Skeggs { 6, UNDERSCAN_OFF, "off" }, 3149285462273cbccb27187d5308ed95f94a9ceb1deBen Skeggs { 6, UNDERSCAN_ON, "on" }, 315de69185573586302ada2e59ba41835df36986277Ben Skeggs {} 316b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs}; 317b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 3184a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstatic struct nouveau_drm_prop_enum_list dither_mode[] = { 319de69185573586302ada2e59ba41835df36986277Ben Skeggs { 7, DITHERING_MODE_AUTO, "auto" }, 320de69185573586302ada2e59ba41835df36986277Ben Skeggs { 7, DITHERING_MODE_OFF, "off" }, 321de69185573586302ada2e59ba41835df36986277Ben Skeggs { 1, DITHERING_MODE_ON, "on" }, 322de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_MODE_STATIC2X2, "static 2x2" }, 323de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_MODE_DYNAMIC2X2, "dynamic 2x2" }, 324de69185573586302ada2e59ba41835df36986277Ben Skeggs { 4, DITHERING_MODE_TEMPORAL, "temporal" }, 325de69185573586302ada2e59ba41835df36986277Ben Skeggs {} 326de69185573586302ada2e59ba41835df36986277Ben Skeggs}; 327de69185573586302ada2e59ba41835df36986277Ben Skeggs 3284a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauerstatic struct nouveau_drm_prop_enum_list dither_depth[] = { 329de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_DEPTH_AUTO, "auto" }, 330de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, 331de69185573586302ada2e59ba41835df36986277Ben Skeggs { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, 332de69185573586302ada2e59ba41835df36986277Ben Skeggs {} 333de69185573586302ada2e59ba41835df36986277Ben Skeggs}; 334de69185573586302ada2e59ba41835df36986277Ben Skeggs 335de69185573586302ada2e59ba41835df36986277Ben Skeggs#define PROP_ENUM(p,gen,n,list) do { \ 3364a67d39190315558631d944b1cea4466ed4c86d8Sascha Hauer struct nouveau_drm_prop_enum_list *l = (list); \ 337de69185573586302ada2e59ba41835df36986277Ben Skeggs int c = 0; \ 338de69185573586302ada2e59ba41835df36986277Ben Skeggs while (l->gen_mask) { \ 339de69185573586302ada2e59ba41835df36986277Ben Skeggs if (l->gen_mask & (1 << (gen))) \ 340de69185573586302ada2e59ba41835df36986277Ben Skeggs c++; \ 341de69185573586302ada2e59ba41835df36986277Ben Skeggs l++; \ 342de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 343de69185573586302ada2e59ba41835df36986277Ben Skeggs if (c) { \ 344de69185573586302ada2e59ba41835df36986277Ben Skeggs p = drm_property_create(dev, DRM_MODE_PROP_ENUM, n, c); \ 345de69185573586302ada2e59ba41835df36986277Ben Skeggs l = (list); \ 346de69185573586302ada2e59ba41835df36986277Ben Skeggs c = 0; \ 347de69185573586302ada2e59ba41835df36986277Ben Skeggs while (p && l->gen_mask) { \ 348de69185573586302ada2e59ba41835df36986277Ben Skeggs if (l->gen_mask & (1 << (gen))) { \ 349de69185573586302ada2e59ba41835df36986277Ben Skeggs drm_property_add_enum(p, c, l->type, l->name); \ 350de69185573586302ada2e59ba41835df36986277Ben Skeggs c++; \ 351de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 352de69185573586302ada2e59ba41835df36986277Ben Skeggs l++; \ 353de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 354de69185573586302ada2e59ba41835df36986277Ben Skeggs } \ 355de69185573586302ada2e59ba41835df36986277Ben Skeggs} while(0) 356de69185573586302ada2e59ba41835df36986277Ben Skeggs 357042206c0cd4924879c4292c5ffa2bf1e8023ae5aFrancisco Jerezint 358f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsnouveau_display_init(struct drm_device *dev) 359f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs{ 36077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 36152c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct drm_connector *connector; 362f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs int ret; 363f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 364f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs ret = disp->init(dev); 36552c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs if (ret) 36652c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs return ret; 36752c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs 3687df898b1a70b13c3a8892625f4ead929d9554293Ben Skeggs /* enable polling for external displays */ 36952c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs drm_kms_helper_poll_enable(dev); 37052c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs 37152c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs /* enable hotplug interrupts */ 37252c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 37352c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct nouveau_connector *conn = nouveau_connector(connector); 37480bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggs nvif_notify_get(&conn->hpd); 375f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs } 376f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 377f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs return ret; 378f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs} 379f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 380f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsvoid 381f62b27db6b5479efe376b408802a081a834ef50eBen Skeggsnouveau_display_fini(struct drm_device *dev) 382f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs{ 38377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 38452c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct drm_connector *connector; 3859cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner int head; 3869cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner 3879cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner /* Make sure that drm and hw vblank irqs get properly disabled. */ 3889cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner for (head = 0; head < dev->mode_config.num_crtc; head++) 3899cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner drm_vblank_off(dev, head); 39052c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs 39152c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs /* disable hotplug interrupts */ 39252c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 39352c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs struct nouveau_connector *conn = nouveau_connector(connector); 39480bc340b3dd720c5b7818e21a9a1ee36e1d7ef30Ben Skeggs nvif_notify_put(&conn->hpd); 39552c4d767437b40b0cbc02d6a4480abb45ace64bbBen Skeggs } 396f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 397f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs drm_kms_helper_poll_disable(dev); 398f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs disp->fini(dev); 399f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs} 400f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 4019c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggsstatic void 4029c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggsnouveau_display_create_properties(struct drm_device *dev) 40327d5030a235d89842ed70e18d924f017b34a496dBen Skeggs{ 4049c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs struct nouveau_display *disp = nouveau_display(dev); 4059c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs int gen; 406de69185573586302ada2e59ba41835df36986277Ben Skeggs 407648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs if (disp->disp.oclass < NV50_DISP) 408de69185573586302ada2e59ba41835df36986277Ben Skeggs gen = 0; 409de69185573586302ada2e59ba41835df36986277Ben Skeggs else 410648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs if (disp->disp.oclass < GF110_DISP) 411de69185573586302ada2e59ba41835df36986277Ben Skeggs gen = 1; 412de69185573586302ada2e59ba41835df36986277Ben Skeggs else 413de69185573586302ada2e59ba41835df36986277Ben Skeggs gen = 2; 414de69185573586302ada2e59ba41835df36986277Ben Skeggs 415de69185573586302ada2e59ba41835df36986277Ben Skeggs PROP_ENUM(disp->dithering_mode, gen, "dithering mode", dither_mode); 416de69185573586302ada2e59ba41835df36986277Ben Skeggs PROP_ENUM(disp->dithering_depth, gen, "dithering depth", dither_depth); 417de69185573586302ada2e59ba41835df36986277Ben Skeggs PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); 418b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 419b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs disp->underscan_hborder_property = 420d9bc3c02e36d844c2d980e65ddda5c7699e073f8Sascha Hauer drm_property_create_range(dev, 0, "underscan hborder", 0, 128); 421b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 422b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs disp->underscan_vborder_property = 423d9bc3c02e36d844c2d980e65ddda5c7699e073f8Sascha Hauer drm_property_create_range(dev, 0, "underscan vborder", 0, 128); 424b29caa5885e85bbda7c84ea55721b9e79718583aBen Skeggs 4259c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs if (gen < 1) 4269c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs return; 427df26bc9c320602539b1b5b3d85786e4c8de7bf43Christoph Bumiller 4289c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs /* -90..+90 */ 4299c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs disp->vibrant_hue_property = 4309c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_property_create_range(dev, 0, "vibrant hue", 0, 180); 4319c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs 4329c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs /* -100..+100 */ 4339c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs disp->color_vibrance_property = 4349c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_property_create_range(dev, 0, "color vibrance", 0, 200); 4359c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs} 4369c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs 4379c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggsint 4389c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggsnouveau_display_create(struct drm_device *dev) 4399c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs{ 4409c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 4419c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs struct nouveau_display *disp; 4429c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs int ret; 4439c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs 4449c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); 4459c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs if (!disp) 4469c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs return -ENOMEM; 4479c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs 4489c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_mode_config_init(dev); 4499c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_mode_create_scaling_mode_property(dev); 4509c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs drm_mode_create_dvi_i_properties(dev); 451df26bc9c320602539b1b5b3d85786e4c8de7bf43Christoph Bumiller 452e6ecefaadfcdb03db8ac9e739b4ba7a93a8811b3Laurent Pinchart dev->mode_config.funcs = &nouveau_mode_config_funcs; 453967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs dev->mode_config.fb_base = nv_device_resource_start(nvkm_device(&drm->device), 1); 45427d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 45527d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.min_width = 0; 45627d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.min_height = 0; 457967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family < NV_DEVICE_INFO_V0_CELSIUS) { 45827d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_width = 2048; 45927d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_height = 2048; 46027d5030a235d89842ed70e18d924f017b34a496dBen Skeggs } else 461967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 46227d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_width = 4096; 46327d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_height = 4096; 46427d5030a235d89842ed70e18d924f017b34a496dBen Skeggs } else { 46527d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_width = 8192; 46627d5030a235d89842ed70e18d924f017b34a496dBen Skeggs dev->mode_config.max_height = 8192; 46727d5030a235d89842ed70e18d924f017b34a496dBen Skeggs } 46827d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 469f1377998eede7a8caa124fcf6a589b02c9e2bac7Dave Airlie dev->mode_config.preferred_depth = 24; 470f1377998eede7a8caa124fcf6a589b02c9e2bac7Dave Airlie dev->mode_config.prefer_shadow = 1; 471f1377998eede7a8caa124fcf6a589b02c9e2bac7Dave Airlie 472967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.chipset < 0x11) 473b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs dev->mode_config.async_page_flip = false; 474b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs else 475b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs dev->mode_config.async_page_flip = true; 476b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 477f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs drm_kms_helper_poll_init(dev); 478f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs drm_kms_helper_poll_disable(dev); 479f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 480fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (drm->vbios.dcb.entries) { 4812332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs static const u16 oclass[] = { 482648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs GM107_DISP, 483648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs GK110_DISP, 484648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs GK104_DISP, 485648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs GF110_DISP, 486648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs GT214_DISP, 487648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs GT206_DISP, 488648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs GT200_DISP, 489648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs G82_DISP, 490648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs NV50_DISP, 491648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs NV04_DISP, 4922332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs }; 4932332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs int i; 4942332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs 4952332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { 4960ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs ret = nvif_object_init(nvif_object(&drm->device), NULL, 4970ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs NVDRM_DISPLAY, oclass[i], 4980ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs NULL, 0, &disp->disp); 4992332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs } 5002332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs 5012332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs if (ret == 0) { 5029c210f378f7cee5f1a5eabe5a78c5ec98251cb5bBen Skeggs nouveau_display_create_properties(dev); 503648d4dfde721885737b33a06f2b73ee125acf271Ben Skeggs if (disp->disp.oclass < NV50_DISP) 5042332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs ret = nv04_display_create(dev); 5052332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs else 5062332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs ret = nv50_display_create(dev); 5072332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs } 508fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs } else { 509fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs ret = 0; 510fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs } 5119430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs 512fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (ret) 513fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs goto disp_create_err; 5149430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs 515fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (dev->mode_config.num_crtc) { 51651cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs ret = nouveau_display_vblank_init(dev); 517fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs if (ret) 518fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs goto vblank_err; 519f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs } 520f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 521fc1620883af8cbc10bfb1a4ef2eb4e8113243012Ben Skeggs nouveau_backlight_init(dev); 5225ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz return 0; 5235ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz 5245ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarzvblank_err: 52577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs disp->dtor(dev); 5265ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarzdisp_create_err: 5275ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz drm_kms_helper_poll_fini(dev); 5285ace2c9d6f5bc4600ca43fe188a33efc4c2dba79Marcin Slusarz drm_mode_config_cleanup(dev); 5292a44e4997c5fee8e1da1589ff57e0bd1c53f03ceBen Skeggs return ret; 53027d5030a235d89842ed70e18d924f017b34a496dBen Skeggs} 53127d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 53227d5030a235d89842ed70e18d924f017b34a496dBen Skeggsvoid 53327d5030a235d89842ed70e18d924f017b34a496dBen Skeggsnouveau_display_destroy(struct drm_device *dev) 53427d5030a235d89842ed70e18d924f017b34a496dBen Skeggs{ 53577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_display *disp = nouveau_display(dev); 53627d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 53777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_backlight_exit(dev); 53851cb4b392a307a8293b4f1f300ab803d7ad3b036Ben Skeggs nouveau_display_vblank_fini(dev); 539f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 540d6bf2f370703c0cab60bf1f5bf871a3f00eb8872Ben Skeggs drm_kms_helper_poll_fini(dev); 541d6bf2f370703c0cab60bf1f5bf871a3f00eb8872Ben Skeggs drm_mode_config_cleanup(dev); 542d6bf2f370703c0cab60bf1f5bf871a3f00eb8872Ben Skeggs 5439430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs if (disp->dtor) 5449430738d80223a1cd791a2baa74fa170d3df1262Ben Skeggs disp->dtor(dev); 545f62b27db6b5479efe376b408802a081a834ef50eBen Skeggs 5460ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs nvif_object_fini(&disp->disp); 5472332b31116d5500d05173b2a7aaa95ba15d7983aBen Skeggs 54877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_drm(dev)->display = NULL; 54977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs kfree(disp); 55077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs} 55177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 55277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggsint 55377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggsnouveau_display_suspend(struct drm_device *dev) 55477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs{ 55577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 55677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_crtc *crtc; 55777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 55877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_display_fini(dev); 55977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 560c52f4fa61d7504bacd94fd54f43fd0b5bdf74bbcBen Skeggs NV_INFO(drm, "unpinning framebuffer(s)...\n"); 56177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 56277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_framebuffer *nouveau_fb; 56377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 564f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 56577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!nouveau_fb || !nouveau_fb->nvbo) 56677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs continue; 56777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 56877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_unpin(nouveau_fb->nvbo); 56977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 57077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 57177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 57277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 57377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 57477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_unmap(nv_crtc->cursor.nvbo); 57577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_unpin(nv_crtc->cursor.nvbo); 57677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 57777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 57877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs return 0; 57977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs} 58077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 58177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggsvoid 5825addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlienouveau_display_repin(struct drm_device *dev) 58377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs{ 58477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 58577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_crtc *crtc; 58677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs int ret; 58777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 58877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 58977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_framebuffer *nouveau_fb; 59077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 591f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 59277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!nouveau_fb || !nouveau_fb->nvbo) 59377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs continue; 59477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 59577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); 59677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 59777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 59877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 59977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 60077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 60177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); 60277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (!ret) 60377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs ret = nouveau_bo_map(nv_crtc->cursor.nvbo); 60477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs if (ret) 60577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs NV_ERROR(drm, "Could not pin/map cursor.\n"); 60677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 6075addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlie} 60877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 6095addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlievoid 6105addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlienouveau_display_resume(struct drm_device *dev) 6115addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlie{ 6125addcf0a5f0fadceba6bd562d0616a1c5d4c1a4dDave Airlie struct drm_crtc *crtc; 6139cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner int head; 6149cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner 61577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nouveau_display_init(dev); 61677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 61777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs /* Force CLUT to get re-loaded during modeset */ 61877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 61977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 62077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 62177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->lut.depth = 0; 62277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 62377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 6249cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner /* Make sure that drm and hw vblank irqs get resumed if needed. */ 6259cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner for (head = 0; head < dev->mode_config.num_crtc; head++) 6269cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner drm_vblank_on(dev, head); 6279cba5efab5a8145ae6c52ea273553f069c294482Mario Kleiner 62877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs drm_helper_resume_force_mode(dev); 62977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 63077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 63177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 63277145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs u32 offset = nv_crtc->cursor.nvbo->bo.offset; 63377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs 63477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->cursor.set_offset(nv_crtc, offset); 63577145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, 63677145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_crtc->cursor_saved_y); 63777145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs } 63827d5030a235d89842ed70e18d924f017b34a496dBen Skeggs} 63927d5030a235d89842ed70e18d924f017b34a496dBen Skeggs 640332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezstatic int 641332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jereznouveau_page_flip_emit(struct nouveau_channel *chan, 642332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_bo *old_bo, 643332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_bo *new_bo, 644332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *s, 645332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_fence **pfence) 646332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez{ 647f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_fence_chan *fctx = chan->fence; 64877145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = chan->drm; 64977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_device *dev = drm->dev; 650332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez unsigned long flags; 651332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez int ret; 652332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 653332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Queue it to the pending list */ 654332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_lock_irqsave(&dev->event_lock, flags); 655f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs list_add_tail(&s->head, &fctx->flip); 656332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 657332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 658332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Synchronize with the old framebuffer */ 659332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez ret = nouveau_fence_sync(old_bo->bo.sync_obj, chan); 660332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 661332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail; 662332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 663332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Emit the pageflip */ 6641e303c03af1e631de37ec77cc2513210910a812cBen Skeggs ret = RING_SPACE(chan, 2); 665332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 666332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail; 667332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 668967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) 6696d597027755b2eed4298b85ebe3cb5c93b29d1a9Ben Skeggs BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); 6701e303c03af1e631de37ec77cc2513210910a812cBen Skeggs else 6711e303c03af1e631de37ec77cc2513210910a812cBen Skeggs BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1); 6721e303c03af1e631de37ec77cc2513210910a812cBen Skeggs OUT_RING (chan, 0x00000000); 673bd2f2037a42d4657ead3be2918db22e63626cd35Ben Skeggs FIRE_RING (chan); 674332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 675264ce192b3e7f45d0adb37bfbab2b01a3fbe6c30Ben Skeggs ret = nouveau_fence_new(chan, false, pfence); 676332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 677332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail; 678332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 679332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return 0; 680332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezfail: 681332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_lock_irqsave(&dev->event_lock, flags); 682332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez list_del(&s->head); 683332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 684332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return ret; 685332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez} 686332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 687332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezint 688332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jereznouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 689b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs struct drm_pending_vblank_event *event, u32 flags) 690332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez{ 691b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; 692332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct drm_device *dev = crtc->dev; 69377145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = nouveau_drm(dev); 694f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; 695332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; 696332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *s; 6970ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs struct nouveau_channel *chan; 6980ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs struct nouveau_cli *cli; 699332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_fence *fence; 700332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez int ret; 701332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 7020ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs chan = drm->channel; 7030ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs if (!chan) 704332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return -ENODEV; 7050ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs cli = (void *)nvif_client(&chan->device->base); 706332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 707332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez s = kzalloc(sizeof(*s), GFP_KERNEL); 708332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (!s) 709332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return -ENOMEM; 710332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 711d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst if (new_bo != old_bo) { 712d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); 713d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst if (ret) 714d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst goto fail_free; 715d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst } 716d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst 7170ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs mutex_lock(&cli->mutex); 718d5c1e84b3a130f0743b218b33ff7d9cb493ab5b4Maarten Lankhorst 719eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs /* synchronise rendering channel with the kernel's channel */ 720eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs spin_lock(&new_bo->bo.bdev->fence_lock); 721eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs fence = nouveau_fence_ref(new_bo->bo.sync_obj); 722eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs spin_unlock(&new_bo->bo.bdev->fence_lock); 723eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs ret = nouveau_fence_sync(fence, chan); 7242fd04c81dc652689b104ab16eba26146dde5c43fBen Skeggs nouveau_fence_unref(&fence); 725eae389f9b1e08a6e6e8da68937706d89517b1796Ben Skeggs if (ret) 72609c3de135063f93d7137ad112f551f293b1204cfMaarten Lankhorst goto fail_unpin; 727b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst 72807ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs ret = ttm_bo_reserve(&old_bo->bo, true, false, false, NULL); 729060810d7abaabcab282e062c595871d661561400Ben Skeggs if (ret) 730060810d7abaabcab282e062c595871d661561400Ben Skeggs goto fail_unpin; 731b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst 732b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst /* Initialize a page flip struct */ 733b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst *s = (struct nouveau_page_flip_state) 734b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst { { }, event, nouveau_crtc(crtc)->index, 735b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y, 736b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst new_bo->bo.offset }; 737b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst 738ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner /* Keep vblanks on during flip, for the target crtc of this flip */ 739ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner drm_vblank_get(dev, nouveau_crtc(crtc)->index); 740ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner 741332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Emit a page flip */ 742967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { 743b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); 744060810d7abaabcab282e062c595871d661561400Ben Skeggs if (ret) 745d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs goto fail_unreserve; 74678ae0ad403daf11cf63da86923d2b5dbeda3af8fBen Skeggs } else { 74778ae0ad403daf11cf63da86923d2b5dbeda3af8fBen Skeggs struct nv04_display *dispnv04 = nv04_display(dev); 748b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs int head = nouveau_crtc(crtc)->index; 749b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 750b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs if (swap_interval) { 751b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs ret = RING_SPACE(chan, 8); 752b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs if (ret) 753b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs goto fail_unreserve; 754b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 755b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); 756b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, 0); 757b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); 758b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, head); 759b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1); 760b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, 0); 761b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1); 762b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs OUT_RING (chan, 0); 763b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs } 764b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs 765b9d9dcdaae4a9284ba3484c528f44a9db18faabfBen Skeggs nouveau_bo_ref(new_bo, &dispnv04->image[head]); 766d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs } 767d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs 768332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); 769332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez if (ret) 770332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez goto fail_unreserve; 7710ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs mutex_unlock(&cli->mutex); 772332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 773332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez /* Update the crtc struct and cleanup */ 774f4510a2752b75ad5847b7935b68c233cab497f97Matt Roper crtc->primary->fb = fb; 775332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 77607ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs nouveau_bo_fence(old_bo, fence); 77707ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs ttm_bo_unreserve(&old_bo->bo); 778060810d7abaabcab282e062c595871d661561400Ben Skeggs if (old_bo != new_bo) 779b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst nouveau_bo_unpin(old_bo); 780332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez nouveau_fence_unref(&fence); 781332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return 0; 782332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 783332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezfail_unreserve: 784ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner drm_vblank_put(dev, nouveau_crtc(crtc)->index); 78507ad6ca0d391758ae3bffa95554abbae6c84e641Ben Skeggs ttm_bo_unreserve(&old_bo->bo); 786060810d7abaabcab282e062c595871d661561400Ben Skeggsfail_unpin: 7870ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs mutex_unlock(&cli->mutex); 788060810d7abaabcab282e062c595871d661561400Ben Skeggs if (old_bo != new_bo) 789b580c9e2b7ba5030a795aa2fb73b796523d65a78Maarten Lankhorst nouveau_bo_unpin(new_bo); 790332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezfail_free: 791332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez kfree(s); 792332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return ret; 793332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez} 794332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 795332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerezint 796332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jereznouveau_finish_page_flip(struct nouveau_channel *chan, 797332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *ps) 798332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez{ 799f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_fence_chan *fctx = chan->fence; 80077145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = chan->drm; 80177145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct drm_device *dev = drm->dev; 802332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez struct nouveau_page_flip_state *s; 803332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez unsigned long flags; 804af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner int crtcid = -1; 805332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 806332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_lock_irqsave(&dev->event_lock, flags); 807332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 808f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs if (list_empty(&fctx->flip)) { 80977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs NV_ERROR(drm, "unexpected pageflip\n"); 810332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 811332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return -EINVAL; 812332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez } 813332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 814f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); 815af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner if (s->event) { 816af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner /* Vblank timestamps/counts are only correct on >= NV-50 */ 817967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) 818af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner crtcid = s->crtc; 819af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner 820af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner drm_send_vblank_event(dev, crtcid, s->event); 821af4870e406126b7ac0ae7c7ce5751f25ebe60f28Mario Kleiner } 822332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 823ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner /* Give up ownership of vblank for page-flipped crtc */ 824ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner drm_vblank_put(dev, s->crtc); 825ba124a41058b300a5464206d2d33803cc3dc82ecMario Kleiner 826332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez list_del(&s->head); 827d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs if (ps) 828d7117e0d4e21034202833088e51fc21f8c8271f9Ben Skeggs *ps = *s; 829332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez kfree(s); 830332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez 831332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez spin_unlock_irqrestore(&dev->event_lock, flags); 832332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez return 0; 833332b242f47786d1a43bd7a19a0513dd5d493db8eFrancisco Jerez} 83433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 83533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsint 836f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggsnouveau_flip_complete(void *data) 837f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs{ 838f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_channel *chan = data; 83977145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs struct nouveau_drm *drm = chan->drm; 840f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs struct nouveau_page_flip_state state; 841f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 842f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs if (!nouveau_finish_page_flip(chan, &state)) { 843967e7bde8739fe3b215f7537e8f1f39c044902afBen Skeggs if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 84477145f1cbdf8d28b46ff8070ca749bad821e0774Ben Skeggs nv_set_crtc_base(drm->dev, state.crtc, state.offset + 845f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs state.y * state.pitch + 846f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs state.x * state.bpp / 8); 847f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs } 848f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs } 849f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 850f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs return 0; 851f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs} 852f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggs 853f589be88caf32501a734e531180d5df5d6089ef3Ben Skeggsint 85433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsnouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, 85533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct drm_mode_create_dumb *args) 85633dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs{ 85733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct nouveau_bo *bo; 85833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs int ret; 85933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 86033dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs args->pitch = roundup(args->width * (args->bpp / 8), 256); 86133dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs args->size = args->pitch * args->height; 86233dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs args->size = roundup(args->size, PAGE_SIZE); 86333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 864610bd7da160f76f1644ecb4cd7f39511b49a22ccDave Airlie ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo); 86533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs if (ret) 86633dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return ret; 86733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 86855fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); 86955fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann drm_gem_object_unreference_unlocked(&bo->gem); 87033dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return ret; 87133dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs} 87233dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 87333dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsint 87433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggsnouveau_display_dumb_map_offset(struct drm_file *file_priv, 87533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct drm_device *dev, 87633dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs uint32_t handle, uint64_t *poffset) 87733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs{ 87833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs struct drm_gem_object *gem; 87933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 88033dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs gem = drm_gem_object_lookup(dev, file_priv, handle); 88133dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs if (gem) { 88255fb74adc628b99424360b0123f47ea4484c56fdDavid Herrmann struct nouveau_bo *bo = nouveau_gem_object(gem); 88372525b3f333de54fa0c42ef87f27861e41478f1eDavid Herrmann *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); 88433dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs drm_gem_object_unreference_unlocked(gem); 88533dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return 0; 88633dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs } 88733dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs 88833dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs return -ENOENT; 88933dbc27f1ab3a37d04a8d226327fb3d384870e43Ben Skeggs} 890