PageRenderTime 66ms CodeModel.GetById 17ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/gpu/drm/nouveau/nouveau_state.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 1140 lines | 974 code | 108 blank | 58 comment | 99 complexity | 2954adb33297fa9c51c9c2156b30974f MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
   1/*
   2 * Copyright 2005 Stephane Marchesin
   3 * Copyright 2008 Stuart Bennett
   4 * All Rights Reserved.
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a
   7 * copy of this software and associated documentation files (the "Software"),
   8 * to deal in the Software without restriction, including without limitation
   9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10 * and/or sell copies of the Software, and to permit persons to whom the
  11 * Software is furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice (including the next
  14 * paragraph) shall be included in all copies or substantial portions of the
  15 * Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23 * DEALINGS IN THE SOFTWARE.
  24 */
  25
  26#include <linux/swab.h>
  27#include <linux/slab.h>
  28#include "drmP.h"
  29#include "drm.h"
  30#include "drm_sarea.h"
  31#include "drm_crtc_helper.h"
  32#include <linux/vgaarb.h>
  33#include <linux/vga_switcheroo.h>
  34
  35#include "nouveau_drv.h"
  36#include "nouveau_drm.h"
  37#include "nouveau_fbcon.h"
  38#include "nouveau_ramht.h"
  39#include "nouveau_pm.h"
  40#include "nv50_display.h"
  41
  42static void nouveau_stub_takedown(struct drm_device *dev) {}
  43static int nouveau_stub_init(struct drm_device *dev) { return 0; }
  44
  45static int nouveau_init_engine_ptrs(struct drm_device *dev)
  46{
  47	struct drm_nouveau_private *dev_priv = dev->dev_private;
  48	struct nouveau_engine *engine = &dev_priv->engine;
  49
  50	switch (dev_priv->chipset & 0xf0) {
  51	case 0x00:
  52		engine->instmem.init		= nv04_instmem_init;
  53		engine->instmem.takedown	= nv04_instmem_takedown;
  54		engine->instmem.suspend		= nv04_instmem_suspend;
  55		engine->instmem.resume		= nv04_instmem_resume;
  56		engine->instmem.get		= nv04_instmem_get;
  57		engine->instmem.put		= nv04_instmem_put;
  58		engine->instmem.map		= nv04_instmem_map;
  59		engine->instmem.unmap		= nv04_instmem_unmap;
  60		engine->instmem.flush		= nv04_instmem_flush;
  61		engine->mc.init			= nv04_mc_init;
  62		engine->mc.takedown		= nv04_mc_takedown;
  63		engine->timer.init		= nv04_timer_init;
  64		engine->timer.read		= nv04_timer_read;
  65		engine->timer.takedown		= nv04_timer_takedown;
  66		engine->fb.init			= nv04_fb_init;
  67		engine->fb.takedown		= nv04_fb_takedown;
  68		engine->fifo.channels		= 16;
  69		engine->fifo.init		= nv04_fifo_init;
  70		engine->fifo.takedown		= nv04_fifo_fini;
  71		engine->fifo.disable		= nv04_fifo_disable;
  72		engine->fifo.enable		= nv04_fifo_enable;
  73		engine->fifo.reassign		= nv04_fifo_reassign;
  74		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
  75		engine->fifo.channel_id		= nv04_fifo_channel_id;
  76		engine->fifo.create_context	= nv04_fifo_create_context;
  77		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
  78		engine->fifo.load_context	= nv04_fifo_load_context;
  79		engine->fifo.unload_context	= nv04_fifo_unload_context;
  80		engine->display.early_init	= nv04_display_early_init;
  81		engine->display.late_takedown	= nv04_display_late_takedown;
  82		engine->display.create		= nv04_display_create;
  83		engine->display.init		= nv04_display_init;
  84		engine->display.destroy		= nv04_display_destroy;
  85		engine->gpio.init		= nouveau_stub_init;
  86		engine->gpio.takedown		= nouveau_stub_takedown;
  87		engine->gpio.get		= NULL;
  88		engine->gpio.set		= NULL;
  89		engine->gpio.irq_enable		= NULL;
  90		engine->pm.clock_get		= nv04_pm_clock_get;
  91		engine->pm.clock_pre		= nv04_pm_clock_pre;
  92		engine->pm.clock_set		= nv04_pm_clock_set;
  93		engine->vram.init		= nouveau_mem_detect;
  94		engine->vram.flags_valid	= nouveau_mem_flags_valid;
  95		break;
  96	case 0x10:
  97		engine->instmem.init		= nv04_instmem_init;
  98		engine->instmem.takedown	= nv04_instmem_takedown;
  99		engine->instmem.suspend		= nv04_instmem_suspend;
 100		engine->instmem.resume		= nv04_instmem_resume;
 101		engine->instmem.get		= nv04_instmem_get;
 102		engine->instmem.put		= nv04_instmem_put;
 103		engine->instmem.map		= nv04_instmem_map;
 104		engine->instmem.unmap		= nv04_instmem_unmap;
 105		engine->instmem.flush		= nv04_instmem_flush;
 106		engine->mc.init			= nv04_mc_init;
 107		engine->mc.takedown		= nv04_mc_takedown;
 108		engine->timer.init		= nv04_timer_init;
 109		engine->timer.read		= nv04_timer_read;
 110		engine->timer.takedown		= nv04_timer_takedown;
 111		engine->fb.init			= nv10_fb_init;
 112		engine->fb.takedown		= nv10_fb_takedown;
 113		engine->fb.init_tile_region	= nv10_fb_init_tile_region;
 114		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
 115		engine->fb.free_tile_region	= nv10_fb_free_tile_region;
 116		engine->fifo.channels		= 32;
 117		engine->fifo.init		= nv10_fifo_init;
 118		engine->fifo.takedown		= nv04_fifo_fini;
 119		engine->fifo.disable		= nv04_fifo_disable;
 120		engine->fifo.enable		= nv04_fifo_enable;
 121		engine->fifo.reassign		= nv04_fifo_reassign;
 122		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
 123		engine->fifo.channel_id		= nv10_fifo_channel_id;
 124		engine->fifo.create_context	= nv10_fifo_create_context;
 125		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
 126		engine->fifo.load_context	= nv10_fifo_load_context;
 127		engine->fifo.unload_context	= nv10_fifo_unload_context;
 128		engine->display.early_init	= nv04_display_early_init;
 129		engine->display.late_takedown	= nv04_display_late_takedown;
 130		engine->display.create		= nv04_display_create;
 131		engine->display.init		= nv04_display_init;
 132		engine->display.destroy		= nv04_display_destroy;
 133		engine->gpio.init		= nouveau_stub_init;
 134		engine->gpio.takedown		= nouveau_stub_takedown;
 135		engine->gpio.get		= nv10_gpio_get;
 136		engine->gpio.set		= nv10_gpio_set;
 137		engine->gpio.irq_enable		= NULL;
 138		engine->pm.clock_get		= nv04_pm_clock_get;
 139		engine->pm.clock_pre		= nv04_pm_clock_pre;
 140		engine->pm.clock_set		= nv04_pm_clock_set;
 141		engine->vram.init		= nouveau_mem_detect;
 142		engine->vram.flags_valid	= nouveau_mem_flags_valid;
 143		break;
 144	case 0x20:
 145		engine->instmem.init		= nv04_instmem_init;
 146		engine->instmem.takedown	= nv04_instmem_takedown;
 147		engine->instmem.suspend		= nv04_instmem_suspend;
 148		engine->instmem.resume		= nv04_instmem_resume;
 149		engine->instmem.get		= nv04_instmem_get;
 150		engine->instmem.put		= nv04_instmem_put;
 151		engine->instmem.map		= nv04_instmem_map;
 152		engine->instmem.unmap		= nv04_instmem_unmap;
 153		engine->instmem.flush		= nv04_instmem_flush;
 154		engine->mc.init			= nv04_mc_init;
 155		engine->mc.takedown		= nv04_mc_takedown;
 156		engine->timer.init		= nv04_timer_init;
 157		engine->timer.read		= nv04_timer_read;
 158		engine->timer.takedown		= nv04_timer_takedown;
 159		engine->fb.init			= nv10_fb_init;
 160		engine->fb.takedown		= nv10_fb_takedown;
 161		engine->fb.init_tile_region	= nv10_fb_init_tile_region;
 162		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
 163		engine->fb.free_tile_region	= nv10_fb_free_tile_region;
 164		engine->fifo.channels		= 32;
 165		engine->fifo.init		= nv10_fifo_init;
 166		engine->fifo.takedown		= nv04_fifo_fini;
 167		engine->fifo.disable		= nv04_fifo_disable;
 168		engine->fifo.enable		= nv04_fifo_enable;
 169		engine->fifo.reassign		= nv04_fifo_reassign;
 170		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
 171		engine->fifo.channel_id		= nv10_fifo_channel_id;
 172		engine->fifo.create_context	= nv10_fifo_create_context;
 173		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
 174		engine->fifo.load_context	= nv10_fifo_load_context;
 175		engine->fifo.unload_context	= nv10_fifo_unload_context;
 176		engine->display.early_init	= nv04_display_early_init;
 177		engine->display.late_takedown	= nv04_display_late_takedown;
 178		engine->display.create		= nv04_display_create;
 179		engine->display.init		= nv04_display_init;
 180		engine->display.destroy		= nv04_display_destroy;
 181		engine->gpio.init		= nouveau_stub_init;
 182		engine->gpio.takedown		= nouveau_stub_takedown;
 183		engine->gpio.get		= nv10_gpio_get;
 184		engine->gpio.set		= nv10_gpio_set;
 185		engine->gpio.irq_enable		= NULL;
 186		engine->pm.clock_get		= nv04_pm_clock_get;
 187		engine->pm.clock_pre		= nv04_pm_clock_pre;
 188		engine->pm.clock_set		= nv04_pm_clock_set;
 189		engine->vram.init		= nouveau_mem_detect;
 190		engine->vram.flags_valid	= nouveau_mem_flags_valid;
 191		break;
 192	case 0x30:
 193		engine->instmem.init		= nv04_instmem_init;
 194		engine->instmem.takedown	= nv04_instmem_takedown;
 195		engine->instmem.suspend		= nv04_instmem_suspend;
 196		engine->instmem.resume		= nv04_instmem_resume;
 197		engine->instmem.get		= nv04_instmem_get;
 198		engine->instmem.put		= nv04_instmem_put;
 199		engine->instmem.map		= nv04_instmem_map;
 200		engine->instmem.unmap		= nv04_instmem_unmap;
 201		engine->instmem.flush		= nv04_instmem_flush;
 202		engine->mc.init			= nv04_mc_init;
 203		engine->mc.takedown		= nv04_mc_takedown;
 204		engine->timer.init		= nv04_timer_init;
 205		engine->timer.read		= nv04_timer_read;
 206		engine->timer.takedown		= nv04_timer_takedown;
 207		engine->fb.init			= nv30_fb_init;
 208		engine->fb.takedown		= nv30_fb_takedown;
 209		engine->fb.init_tile_region	= nv30_fb_init_tile_region;
 210		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
 211		engine->fb.free_tile_region	= nv30_fb_free_tile_region;
 212		engine->fifo.channels		= 32;
 213		engine->fifo.init		= nv10_fifo_init;
 214		engine->fifo.takedown		= nv04_fifo_fini;
 215		engine->fifo.disable		= nv04_fifo_disable;
 216		engine->fifo.enable		= nv04_fifo_enable;
 217		engine->fifo.reassign		= nv04_fifo_reassign;
 218		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
 219		engine->fifo.channel_id		= nv10_fifo_channel_id;
 220		engine->fifo.create_context	= nv10_fifo_create_context;
 221		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
 222		engine->fifo.load_context	= nv10_fifo_load_context;
 223		engine->fifo.unload_context	= nv10_fifo_unload_context;
 224		engine->display.early_init	= nv04_display_early_init;
 225		engine->display.late_takedown	= nv04_display_late_takedown;
 226		engine->display.create		= nv04_display_create;
 227		engine->display.init		= nv04_display_init;
 228		engine->display.destroy		= nv04_display_destroy;
 229		engine->gpio.init		= nouveau_stub_init;
 230		engine->gpio.takedown		= nouveau_stub_takedown;
 231		engine->gpio.get		= nv10_gpio_get;
 232		engine->gpio.set		= nv10_gpio_set;
 233		engine->gpio.irq_enable		= NULL;
 234		engine->pm.clock_get		= nv04_pm_clock_get;
 235		engine->pm.clock_pre		= nv04_pm_clock_pre;
 236		engine->pm.clock_set		= nv04_pm_clock_set;
 237		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
 238		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
 239		engine->vram.init		= nouveau_mem_detect;
 240		engine->vram.flags_valid	= nouveau_mem_flags_valid;
 241		break;
 242	case 0x40:
 243	case 0x60:
 244		engine->instmem.init		= nv04_instmem_init;
 245		engine->instmem.takedown	= nv04_instmem_takedown;
 246		engine->instmem.suspend		= nv04_instmem_suspend;
 247		engine->instmem.resume		= nv04_instmem_resume;
 248		engine->instmem.get		= nv04_instmem_get;
 249		engine->instmem.put		= nv04_instmem_put;
 250		engine->instmem.map		= nv04_instmem_map;
 251		engine->instmem.unmap		= nv04_instmem_unmap;
 252		engine->instmem.flush		= nv04_instmem_flush;
 253		engine->mc.init			= nv40_mc_init;
 254		engine->mc.takedown		= nv40_mc_takedown;
 255		engine->timer.init		= nv04_timer_init;
 256		engine->timer.read		= nv04_timer_read;
 257		engine->timer.takedown		= nv04_timer_takedown;
 258		engine->fb.init			= nv40_fb_init;
 259		engine->fb.takedown		= nv40_fb_takedown;
 260		engine->fb.init_tile_region	= nv30_fb_init_tile_region;
 261		engine->fb.set_tile_region	= nv40_fb_set_tile_region;
 262		engine->fb.free_tile_region	= nv30_fb_free_tile_region;
 263		engine->fifo.channels		= 32;
 264		engine->fifo.init		= nv40_fifo_init;
 265		engine->fifo.takedown		= nv04_fifo_fini;
 266		engine->fifo.disable		= nv04_fifo_disable;
 267		engine->fifo.enable		= nv04_fifo_enable;
 268		engine->fifo.reassign		= nv04_fifo_reassign;
 269		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
 270		engine->fifo.channel_id		= nv10_fifo_channel_id;
 271		engine->fifo.create_context	= nv40_fifo_create_context;
 272		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
 273		engine->fifo.load_context	= nv40_fifo_load_context;
 274		engine->fifo.unload_context	= nv40_fifo_unload_context;
 275		engine->display.early_init	= nv04_display_early_init;
 276		engine->display.late_takedown	= nv04_display_late_takedown;
 277		engine->display.create		= nv04_display_create;
 278		engine->display.init		= nv04_display_init;
 279		engine->display.destroy		= nv04_display_destroy;
 280		engine->gpio.init		= nouveau_stub_init;
 281		engine->gpio.takedown		= nouveau_stub_takedown;
 282		engine->gpio.get		= nv10_gpio_get;
 283		engine->gpio.set		= nv10_gpio_set;
 284		engine->gpio.irq_enable		= NULL;
 285		engine->pm.clock_get		= nv04_pm_clock_get;
 286		engine->pm.clock_pre		= nv04_pm_clock_pre;
 287		engine->pm.clock_set		= nv04_pm_clock_set;
 288		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
 289		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
 290		engine->pm.temp_get		= nv40_temp_get;
 291		engine->vram.init		= nouveau_mem_detect;
 292		engine->vram.flags_valid	= nouveau_mem_flags_valid;
 293		break;
 294	case 0x50:
 295	case 0x80: /* gotta love NVIDIA's consistency.. */
 296	case 0x90:
 297	case 0xA0:
 298		engine->instmem.init		= nv50_instmem_init;
 299		engine->instmem.takedown	= nv50_instmem_takedown;
 300		engine->instmem.suspend		= nv50_instmem_suspend;
 301		engine->instmem.resume		= nv50_instmem_resume;
 302		engine->instmem.get		= nv50_instmem_get;
 303		engine->instmem.put		= nv50_instmem_put;
 304		engine->instmem.map		= nv50_instmem_map;
 305		engine->instmem.unmap		= nv50_instmem_unmap;
 306		if (dev_priv->chipset == 0x50)
 307			engine->instmem.flush	= nv50_instmem_flush;
 308		else
 309			engine->instmem.flush	= nv84_instmem_flush;
 310		engine->mc.init			= nv50_mc_init;
 311		engine->mc.takedown		= nv50_mc_takedown;
 312		engine->timer.init		= nv04_timer_init;
 313		engine->timer.read		= nv04_timer_read;
 314		engine->timer.takedown		= nv04_timer_takedown;
 315		engine->fb.init			= nv50_fb_init;
 316		engine->fb.takedown		= nv50_fb_takedown;
 317		engine->fifo.channels		= 128;
 318		engine->fifo.init		= nv50_fifo_init;
 319		engine->fifo.takedown		= nv50_fifo_takedown;
 320		engine->fifo.disable		= nv04_fifo_disable;
 321		engine->fifo.enable		= nv04_fifo_enable;
 322		engine->fifo.reassign		= nv04_fifo_reassign;
 323		engine->fifo.channel_id		= nv50_fifo_channel_id;
 324		engine->fifo.create_context	= nv50_fifo_create_context;
 325		engine->fifo.destroy_context	= nv50_fifo_destroy_context;
 326		engine->fifo.load_context	= nv50_fifo_load_context;
 327		engine->fifo.unload_context	= nv50_fifo_unload_context;
 328		engine->fifo.tlb_flush		= nv50_fifo_tlb_flush;
 329		engine->display.early_init	= nv50_display_early_init;
 330		engine->display.late_takedown	= nv50_display_late_takedown;
 331		engine->display.create		= nv50_display_create;
 332		engine->display.init		= nv50_display_init;
 333		engine->display.destroy		= nv50_display_destroy;
 334		engine->gpio.init		= nv50_gpio_init;
 335		engine->gpio.takedown		= nv50_gpio_fini;
 336		engine->gpio.get		= nv50_gpio_get;
 337		engine->gpio.set		= nv50_gpio_set;
 338		engine->gpio.irq_register	= nv50_gpio_irq_register;
 339		engine->gpio.irq_unregister	= nv50_gpio_irq_unregister;
 340		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
 341		switch (dev_priv->chipset) {
 342		case 0x84:
 343		case 0x86:
 344		case 0x92:
 345		case 0x94:
 346		case 0x96:
 347		case 0x98:
 348		case 0xa0:
 349		case 0xaa:
 350		case 0xac:
 351		case 0x50:
 352			engine->pm.clock_get	= nv50_pm_clock_get;
 353			engine->pm.clock_pre	= nv50_pm_clock_pre;
 354			engine->pm.clock_set	= nv50_pm_clock_set;
 355			break;
 356		default:
 357			engine->pm.clock_get	= nva3_pm_clock_get;
 358			engine->pm.clock_pre	= nva3_pm_clock_pre;
 359			engine->pm.clock_set	= nva3_pm_clock_set;
 360			break;
 361		}
 362		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
 363		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
 364		if (dev_priv->chipset >= 0x84)
 365			engine->pm.temp_get	= nv84_temp_get;
 366		else
 367			engine->pm.temp_get	= nv40_temp_get;
 368		engine->vram.init		= nv50_vram_init;
 369		engine->vram.get		= nv50_vram_new;
 370		engine->vram.put		= nv50_vram_del;
 371		engine->vram.flags_valid	= nv50_vram_flags_valid;
 372		break;
 373	case 0xC0:
 374		engine->instmem.init		= nvc0_instmem_init;
 375		engine->instmem.takedown	= nvc0_instmem_takedown;
 376		engine->instmem.suspend		= nvc0_instmem_suspend;
 377		engine->instmem.resume		= nvc0_instmem_resume;
 378		engine->instmem.get		= nv50_instmem_get;
 379		engine->instmem.put		= nv50_instmem_put;
 380		engine->instmem.map		= nv50_instmem_map;
 381		engine->instmem.unmap		= nv50_instmem_unmap;
 382		engine->instmem.flush		= nv84_instmem_flush;
 383		engine->mc.init			= nv50_mc_init;
 384		engine->mc.takedown		= nv50_mc_takedown;
 385		engine->timer.init		= nv04_timer_init;
 386		engine->timer.read		= nv04_timer_read;
 387		engine->timer.takedown		= nv04_timer_takedown;
 388		engine->fb.init			= nvc0_fb_init;
 389		engine->fb.takedown		= nvc0_fb_takedown;
 390		engine->fifo.channels		= 128;
 391		engine->fifo.init		= nvc0_fifo_init;
 392		engine->fifo.takedown		= nvc0_fifo_takedown;
 393		engine->fifo.disable		= nvc0_fifo_disable;
 394		engine->fifo.enable		= nvc0_fifo_enable;
 395		engine->fifo.reassign		= nvc0_fifo_reassign;
 396		engine->fifo.channel_id		= nvc0_fifo_channel_id;
 397		engine->fifo.create_context	= nvc0_fifo_create_context;
 398		engine->fifo.destroy_context	= nvc0_fifo_destroy_context;
 399		engine->fifo.load_context	= nvc0_fifo_load_context;
 400		engine->fifo.unload_context	= nvc0_fifo_unload_context;
 401		engine->display.early_init	= nv50_display_early_init;
 402		engine->display.late_takedown	= nv50_display_late_takedown;
 403		engine->display.create		= nv50_display_create;
 404		engine->display.init		= nv50_display_init;
 405		engine->display.destroy		= nv50_display_destroy;
 406		engine->gpio.init		= nv50_gpio_init;
 407		engine->gpio.takedown		= nouveau_stub_takedown;
 408		engine->gpio.get		= nv50_gpio_get;
 409		engine->gpio.set		= nv50_gpio_set;
 410		engine->gpio.irq_register	= nv50_gpio_irq_register;
 411		engine->gpio.irq_unregister	= nv50_gpio_irq_unregister;
 412		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
 413		engine->vram.init		= nvc0_vram_init;
 414		engine->vram.get		= nvc0_vram_new;
 415		engine->vram.put		= nv50_vram_del;
 416		engine->vram.flags_valid	= nvc0_vram_flags_valid;
 417		break;
 418	default:
 419		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
 420		return 1;
 421	}
 422
 423	return 0;
 424}
 425
 426static unsigned int
 427nouveau_vga_set_decode(void *priv, bool state)
 428{
 429	struct drm_device *dev = priv;
 430	struct drm_nouveau_private *dev_priv = dev->dev_private;
 431
 432	if (dev_priv->chipset >= 0x40)
 433		nv_wr32(dev, 0x88054, state);
 434	else
 435		nv_wr32(dev, 0x1854, state);
 436
 437	if (state)
 438		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
 439		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 440	else
 441		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 442}
 443
 444static int
 445nouveau_card_init_channel(struct drm_device *dev)
 446{
 447	struct drm_nouveau_private *dev_priv = dev->dev_private;
 448	int ret;
 449
 450	ret = nouveau_channel_alloc(dev, &dev_priv->channel,
 451				    (struct drm_file *)-2, NvDmaFB, NvDmaTT);
 452	if (ret)
 453		return ret;
 454
 455	mutex_unlock(&dev_priv->channel->mutex);
 456	return 0;
 457}
 458
 459static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
 460					 enum vga_switcheroo_state state)
 461{
 462	struct drm_device *dev = pci_get_drvdata(pdev);
 463	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
 464	if (state == VGA_SWITCHEROO_ON) {
 465		printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
 466		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
 467		nouveau_pci_resume(pdev);
 468		drm_kms_helper_poll_enable(dev);
 469		dev->switch_power_state = DRM_SWITCH_POWER_ON;
 470	} else {
 471		printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
 472		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
 473		drm_kms_helper_poll_disable(dev);
 474		nouveau_pci_suspend(pdev, pmm);
 475		dev->switch_power_state = DRM_SWITCH_POWER_OFF;
 476	}
 477}
 478
 479static void nouveau_switcheroo_reprobe(struct pci_dev *pdev)
 480{
 481	struct drm_device *dev = pci_get_drvdata(pdev);
 482	nouveau_fbcon_output_poll_changed(dev);
 483}
 484
 485static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev)
 486{
 487	struct drm_device *dev = pci_get_drvdata(pdev);
 488	bool can_switch;
 489
 490	spin_lock(&dev->count_lock);
 491	can_switch = (dev->open_count == 0);
 492	spin_unlock(&dev->count_lock);
 493	return can_switch;
 494}
 495
 496int
 497nouveau_card_init(struct drm_device *dev)
 498{
 499	struct drm_nouveau_private *dev_priv = dev->dev_private;
 500	struct nouveau_engine *engine;
 501	int ret, e = 0;
 502
 503	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
 504	vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
 505				       nouveau_switcheroo_reprobe,
 506				       nouveau_switcheroo_can_switch);
 507
 508	/* Initialise internal driver API hooks */
 509	ret = nouveau_init_engine_ptrs(dev);
 510	if (ret)
 511		goto out;
 512	engine = &dev_priv->engine;
 513	spin_lock_init(&dev_priv->channels.lock);
 514	spin_lock_init(&dev_priv->tile.lock);
 515	spin_lock_init(&dev_priv->context_switch_lock);
 516	spin_lock_init(&dev_priv->vm_lock);
 517
 518	/* Make the CRTCs and I2C buses accessible */
 519	ret = engine->display.early_init(dev);
 520	if (ret)
 521		goto out;
 522
 523	/* Parse BIOS tables / Run init tables if card not POSTed */
 524	ret = nouveau_bios_init(dev);
 525	if (ret)
 526		goto out_display_early;
 527
 528	nouveau_pm_init(dev);
 529
 530	ret = nouveau_mem_vram_init(dev);
 531	if (ret)
 532		goto out_bios;
 533
 534	ret = nouveau_gpuobj_init(dev);
 535	if (ret)
 536		goto out_vram;
 537
 538	ret = engine->instmem.init(dev);
 539	if (ret)
 540		goto out_gpuobj;
 541
 542	ret = nouveau_mem_gart_init(dev);
 543	if (ret)
 544		goto out_instmem;
 545
 546	/* PMC */
 547	ret = engine->mc.init(dev);
 548	if (ret)
 549		goto out_gart;
 550
 551	/* PGPIO */
 552	ret = engine->gpio.init(dev);
 553	if (ret)
 554		goto out_mc;
 555
 556	/* PTIMER */
 557	ret = engine->timer.init(dev);
 558	if (ret)
 559		goto out_gpio;
 560
 561	/* PFB */
 562	ret = engine->fb.init(dev);
 563	if (ret)
 564		goto out_timer;
 565
 566	if (!nouveau_noaccel) {
 567		switch (dev_priv->card_type) {
 568		case NV_04:
 569			nv04_graph_create(dev);
 570			break;
 571		case NV_10:
 572			nv10_graph_create(dev);
 573			break;
 574		case NV_20:
 575		case NV_30:
 576			nv20_graph_create(dev);
 577			break;
 578		case NV_40:
 579			nv40_graph_create(dev);
 580			break;
 581		case NV_50:
 582			nv50_graph_create(dev);
 583			break;
 584		case NV_C0:
 585			nvc0_graph_create(dev);
 586			break;
 587		default:
 588			break;
 589		}
 590
 591		switch (dev_priv->chipset) {
 592		case 0x84:
 593		case 0x86:
 594		case 0x92:
 595		case 0x94:
 596		case 0x96:
 597		case 0xa0:
 598			nv84_crypt_create(dev);
 599			break;
 600		}
 601
 602		switch (dev_priv->card_type) {
 603		case NV_50:
 604			switch (dev_priv->chipset) {
 605			case 0xa3:
 606			case 0xa5:
 607			case 0xa8:
 608			case 0xaf:
 609				nva3_copy_create(dev);
 610				break;
 611			}
 612			break;
 613		case NV_C0:
 614			nvc0_copy_create(dev, 0);
 615			nvc0_copy_create(dev, 1);
 616			break;
 617		default:
 618			break;
 619		}
 620
 621		if (dev_priv->card_type == NV_40)
 622			nv40_mpeg_create(dev);
 623		else
 624		if (dev_priv->card_type == NV_50 &&
 625		    (dev_priv->chipset < 0x98 || dev_priv->chipset == 0xa0))
 626			nv50_mpeg_create(dev);
 627
 628		for (e = 0; e < NVOBJ_ENGINE_NR; e++) {
 629			if (dev_priv->eng[e]) {
 630				ret = dev_priv->eng[e]->init(dev, e);
 631				if (ret)
 632					goto out_engine;
 633			}
 634		}
 635
 636		/* PFIFO */
 637		ret = engine->fifo.init(dev);
 638		if (ret)
 639			goto out_engine;
 640	}
 641
 642	ret = engine->display.create(dev);
 643	if (ret)
 644		goto out_fifo;
 645
 646	ret = drm_vblank_init(dev, nv_two_heads(dev) ? 2 : 1);
 647	if (ret)
 648		goto out_vblank;
 649
 650	ret = nouveau_irq_init(dev);
 651	if (ret)
 652		goto out_vblank;
 653
 654	/* what about PVIDEO/PCRTC/PRAMDAC etc? */
 655
 656	if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
 657		ret = nouveau_fence_init(dev);
 658		if (ret)
 659			goto out_irq;
 660
 661		ret = nouveau_card_init_channel(dev);
 662		if (ret)
 663			goto out_fence;
 664	}
 665
 666	nouveau_fbcon_init(dev);
 667	drm_kms_helper_poll_init(dev);
 668	return 0;
 669
 670out_fence:
 671	nouveau_fence_fini(dev);
 672out_irq:
 673	nouveau_irq_fini(dev);
 674out_vblank:
 675	drm_vblank_cleanup(dev);
 676	engine->display.destroy(dev);
 677out_fifo:
 678	if (!nouveau_noaccel)
 679		engine->fifo.takedown(dev);
 680out_engine:
 681	if (!nouveau_noaccel) {
 682		for (e = e - 1; e >= 0; e--) {
 683			if (!dev_priv->eng[e])
 684				continue;
 685			dev_priv->eng[e]->fini(dev, e);
 686			dev_priv->eng[e]->destroy(dev,e );
 687		}
 688	}
 689
 690	engine->fb.takedown(dev);
 691out_timer:
 692	engine->timer.takedown(dev);
 693out_gpio:
 694	engine->gpio.takedown(dev);
 695out_mc:
 696	engine->mc.takedown(dev);
 697out_gart:
 698	nouveau_mem_gart_fini(dev);
 699out_instmem:
 700	engine->instmem.takedown(dev);
 701out_gpuobj:
 702	nouveau_gpuobj_takedown(dev);
 703out_vram:
 704	nouveau_mem_vram_fini(dev);
 705out_bios:
 706	nouveau_pm_fini(dev);
 707	nouveau_bios_takedown(dev);
 708out_display_early:
 709	engine->display.late_takedown(dev);
 710out:
 711	vga_client_register(dev->pdev, NULL, NULL, NULL);
 712	return ret;
 713}
 714
 715static void nouveau_card_takedown(struct drm_device *dev)
 716{
 717	struct drm_nouveau_private *dev_priv = dev->dev_private;
 718	struct nouveau_engine *engine = &dev_priv->engine;
 719	int e;
 720
 721	if (dev_priv->channel) {
 722		nouveau_fence_fini(dev);
 723		nouveau_channel_put_unlocked(&dev_priv->channel);
 724	}
 725
 726	if (!nouveau_noaccel) {
 727		engine->fifo.takedown(dev);
 728		for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
 729			if (dev_priv->eng[e]) {
 730				dev_priv->eng[e]->fini(dev, e);
 731				dev_priv->eng[e]->destroy(dev,e );
 732			}
 733		}
 734	}
 735	engine->fb.takedown(dev);
 736	engine->timer.takedown(dev);
 737	engine->gpio.takedown(dev);
 738	engine->mc.takedown(dev);
 739	engine->display.late_takedown(dev);
 740
 741	if (dev_priv->vga_ram) {
 742		nouveau_bo_unpin(dev_priv->vga_ram);
 743		nouveau_bo_ref(NULL, &dev_priv->vga_ram);
 744	}
 745
 746	mutex_lock(&dev->struct_mutex);
 747	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
 748	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
 749	mutex_unlock(&dev->struct_mutex);
 750	nouveau_mem_gart_fini(dev);
 751
 752	engine->instmem.takedown(dev);
 753	nouveau_gpuobj_takedown(dev);
 754	nouveau_mem_vram_fini(dev);
 755
 756	nouveau_irq_fini(dev);
 757	drm_vblank_cleanup(dev);
 758
 759	nouveau_pm_fini(dev);
 760	nouveau_bios_takedown(dev);
 761
 762	vga_client_register(dev->pdev, NULL, NULL, NULL);
 763}
 764
 765/* here a client dies, release the stuff that was allocated for its
 766 * file_priv */
 767void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
 768{
 769	nouveau_channel_cleanup(dev, file_priv);
 770}
 771
 772/* first module load, setup the mmio/fb mapping */
 773/* KMS: we need mmio at load time, not when the first drm client opens. */
 774int nouveau_firstopen(struct drm_device *dev)
 775{
 776	return 0;
 777}
 778
 779/* if we have an OF card, copy vbios to RAMIN */
 780static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
 781{
 782#if defined(__powerpc__)
 783	int size, i;
 784	const uint32_t *bios;
 785	struct device_node *dn = pci_device_to_OF_node(dev->pdev);
 786	if (!dn) {
 787		NV_INFO(dev, "Unable to get the OF node\n");
 788		return;
 789	}
 790
 791	bios = of_get_property(dn, "NVDA,BMP", &size);
 792	if (bios) {
 793		for (i = 0; i < size; i += 4)
 794			nv_wi32(dev, i, bios[i/4]);
 795		NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size);
 796	} else {
 797		NV_INFO(dev, "Unable to get the OF bios\n");
 798	}
 799#endif
 800}
 801
 802static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev)
 803{
 804	struct pci_dev *pdev = dev->pdev;
 805	struct apertures_struct *aper = alloc_apertures(3);
 806	if (!aper)
 807		return NULL;
 808
 809	aper->ranges[0].base = pci_resource_start(pdev, 1);
 810	aper->ranges[0].size = pci_resource_len(pdev, 1);
 811	aper->count = 1;
 812
 813	if (pci_resource_len(pdev, 2)) {
 814		aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
 815		aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
 816		aper->count++;
 817	}
 818
 819	if (pci_resource_len(pdev, 3)) {
 820		aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
 821		aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
 822		aper->count++;
 823	}
 824
 825	return aper;
 826}
 827
 828static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
 829{
 830	struct drm_nouveau_private *dev_priv = dev->dev_private;
 831	bool primary = false;
 832	dev_priv->apertures = nouveau_get_apertures(dev);
 833	if (!dev_priv->apertures)
 834		return -ENOMEM;
 835
 836#ifdef CONFIG_X86
 837	primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
 838#endif
 839
 840	remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
 841	return 0;
 842}
 843
 844int nouveau_load(struct drm_device *dev, unsigned long flags)
 845{
 846	struct drm_nouveau_private *dev_priv;
 847	uint32_t reg0;
 848	resource_size_t mmio_start_offs;
 849	int ret;
 850
 851	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
 852	if (!dev_priv) {
 853		ret = -ENOMEM;
 854		goto err_out;
 855	}
 856	dev->dev_private = dev_priv;
 857	dev_priv->dev = dev;
 858
 859	dev_priv->flags = flags & NOUVEAU_FLAGS;
 860
 861	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
 862		 dev->pci_vendor, dev->pci_device, dev->pdev->class);
 863
 864	/* resource 0 is mmio regs */
 865	/* resource 1 is linear FB */
 866	/* resource 2 is RAMIN (mmio regs + 0x1000000) */
 867	/* resource 6 is bios */
 868
 869	/* map the mmio regs */
 870	mmio_start_offs = pci_resource_start(dev->pdev, 0);
 871	dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000);
 872	if (!dev_priv->mmio) {
 873		NV_ERROR(dev, "Unable to initialize the mmio mapping. "
 874			 "Please report your setup to " DRIVER_EMAIL "\n");
 875		ret = -EINVAL;
 876		goto err_priv;
 877	}
 878	NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
 879					(unsigned long long)mmio_start_offs);
 880
 881#ifdef __BIG_ENDIAN
 882	/* Put the card in BE mode if it's not */
 883	if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001)
 884		nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001);
 885
 886	DRM_MEMORYBARRIER();
 887#endif
 888
 889	/* Time to determine the card architecture */
 890	reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
 891	dev_priv->stepping = 0; /* XXX: add stepping for pre-NV10? */
 892
 893	/* We're dealing with >=NV10 */
 894	if ((reg0 & 0x0f000000) > 0) {
 895		/* Bit 27-20 contain the architecture in hex */
 896		dev_priv->chipset = (reg0 & 0xff00000) >> 20;
 897		dev_priv->stepping = (reg0 & 0xff);
 898	/* NV04 or NV05 */
 899	} else if ((reg0 & 0xff00fff0) == 0x20004000) {
 900		if (reg0 & 0x00f00000)
 901			dev_priv->chipset = 0x05;
 902		else
 903			dev_priv->chipset = 0x04;
 904	} else
 905		dev_priv->chipset = 0xff;
 906
 907	switch (dev_priv->chipset & 0xf0) {
 908	case 0x00:
 909	case 0x10:
 910	case 0x20:
 911	case 0x30:
 912		dev_priv->card_type = dev_priv->chipset & 0xf0;
 913		break;
 914	case 0x40:
 915	case 0x60:
 916		dev_priv->card_type = NV_40;
 917		break;
 918	case 0x50:
 919	case 0x80:
 920	case 0x90:
 921	case 0xa0:
 922		dev_priv->card_type = NV_50;
 923		break;
 924	case 0xc0:
 925		dev_priv->card_type = NV_C0;
 926		break;
 927	default:
 928		NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0);
 929		ret = -EINVAL;
 930		goto err_mmio;
 931	}
 932
 933	NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
 934		dev_priv->card_type, reg0);
 935
 936	ret = nouveau_remove_conflicting_drivers(dev);
 937	if (ret)
 938		goto err_mmio;
 939
 940	/* Map PRAMIN BAR, or on older cards, the aperture within BAR0 */
 941	if (dev_priv->card_type >= NV_40) {
 942		int ramin_bar = 2;
 943		if (pci_resource_len(dev->pdev, ramin_bar) == 0)
 944			ramin_bar = 3;
 945
 946		dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar);
 947		dev_priv->ramin =
 948			ioremap(pci_resource_start(dev->pdev, ramin_bar),
 949				dev_priv->ramin_size);
 950		if (!dev_priv->ramin) {
 951			NV_ERROR(dev, "Failed to PRAMIN BAR");
 952			ret = -ENOMEM;
 953			goto err_mmio;
 954		}
 955	} else {
 956		dev_priv->ramin_size = 1 * 1024 * 1024;
 957		dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN,
 958					  dev_priv->ramin_size);
 959		if (!dev_priv->ramin) {
 960			NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n");
 961			ret = -ENOMEM;
 962			goto err_mmio;
 963		}
 964	}
 965
 966	nouveau_OF_copy_vbios_to_ramin(dev);
 967
 968	/* Special flags */
 969	if (dev->pci_device == 0x01a0)
 970		dev_priv->flags |= NV_NFORCE;
 971	else if (dev->pci_device == 0x01f0)
 972		dev_priv->flags |= NV_NFORCE2;
 973
 974	/* For kernel modesetting, init card now and bring up fbcon */
 975	ret = nouveau_card_init(dev);
 976	if (ret)
 977		goto err_ramin;
 978
 979	return 0;
 980
 981err_ramin:
 982	iounmap(dev_priv->ramin);
 983err_mmio:
 984	iounmap(dev_priv->mmio);
 985err_priv:
 986	kfree(dev_priv);
 987	dev->dev_private = NULL;
 988err_out:
 989	return ret;
 990}
 991
 992void nouveau_lastclose(struct drm_device *dev)
 993{
 994	vga_switcheroo_process_delayed_switch();
 995}
 996
 997int nouveau_unload(struct drm_device *dev)
 998{
 999	struct drm_nouveau_private *dev_priv = dev->dev_private;
1000	struct nouveau_engine *engine = &dev_priv->engine;
1001
1002	drm_kms_helper_poll_fini(dev);
1003	nouveau_fbcon_fini(dev);
1004	engine->display.destroy(dev);
1005	nouveau_card_takedown(dev);
1006
1007	iounmap(dev_priv->mmio);
1008	iounmap(dev_priv->ramin);
1009
1010	kfree(dev_priv);
1011	dev->dev_private = NULL;
1012	return 0;
1013}
1014
1015int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
1016						struct drm_file *file_priv)
1017{
1018	struct drm_nouveau_private *dev_priv = dev->dev_private;
1019	struct drm_nouveau_getparam *getparam = data;
1020
1021	switch (getparam->param) {
1022	case NOUVEAU_GETPARAM_CHIPSET_ID:
1023		getparam->value = dev_priv->chipset;
1024		break;
1025	case NOUVEAU_GETPARAM_PCI_VENDOR:
1026		getparam->value = dev->pci_vendor;
1027		break;
1028	case NOUVEAU_GETPARAM_PCI_DEVICE:
1029		getparam->value = dev->pci_device;
1030		break;
1031	case NOUVEAU_GETPARAM_BUS_TYPE:
1032		if (drm_pci_device_is_agp(dev))
1033			getparam->value = NV_AGP;
1034		else if (drm_pci_device_is_pcie(dev))
1035			getparam->value = NV_PCIE;
1036		else
1037			getparam->value = NV_PCI;
1038		break;
1039	case NOUVEAU_GETPARAM_FB_SIZE:
1040		getparam->value = dev_priv->fb_available_size;
1041		break;
1042	case NOUVEAU_GETPARAM_AGP_SIZE:
1043		getparam->value = dev_priv->gart_info.aper_size;
1044		break;
1045	case NOUVEAU_GETPARAM_VM_VRAM_BASE:
1046		getparam->value = 0; /* deprecated */
1047		break;
1048	case NOUVEAU_GETPARAM_PTIMER_TIME:
1049		getparam->value = dev_priv->engine.timer.read(dev);
1050		break;
1051	case NOUVEAU_GETPARAM_HAS_BO_USAGE:
1052		getparam->value = 1;
1053		break;
1054	case NOUVEAU_GETPARAM_HAS_PAGEFLIP:
1055		getparam->value = 1;
1056		break;
1057	case NOUVEAU_GETPARAM_GRAPH_UNITS:
1058		/* NV40 and NV50 versions are quite different, but register
1059		 * address is the same. User is supposed to know the card
1060		 * family anyway... */
1061		if (dev_priv->chipset >= 0x40) {
1062			getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS);
1063			break;
1064		}
1065		/* FALLTHRU */
1066	default:
1067		NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param);
1068		return -EINVAL;
1069	}
1070
1071	return 0;
1072}
1073
1074int
1075nouveau_ioctl_setparam(struct drm_device *dev, void *data,
1076		       struct drm_file *file_priv)
1077{
1078	struct drm_nouveau_setparam *setparam = data;
1079
1080	switch (setparam->param) {
1081	default:
1082		NV_DEBUG(dev, "unknown parameter %lld\n", setparam->param);
1083		return -EINVAL;
1084	}
1085
1086	return 0;
1087}
1088
1089/* Wait until (value(reg) & mask) == val, up until timeout has hit */
1090bool
1091nouveau_wait_eq(struct drm_device *dev, uint64_t timeout,
1092		uint32_t reg, uint32_t mask, uint32_t val)
1093{
1094	struct drm_nouveau_private *dev_priv = dev->dev_private;
1095	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
1096	uint64_t start = ptimer->read(dev);
1097
1098	do {
1099		if ((nv_rd32(dev, reg) & mask) == val)
1100			return true;
1101	} while (ptimer->read(dev) - start < timeout);
1102
1103	return false;
1104}
1105
1106/* Wait until (value(reg) & mask) != val, up until timeout has hit */
1107bool
1108nouveau_wait_ne(struct drm_device *dev, uint64_t timeout,
1109		uint32_t reg, uint32_t mask, uint32_t val)
1110{
1111	struct drm_nouveau_private *dev_priv = dev->dev_private;
1112	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
1113	uint64_t start = ptimer->read(dev);
1114
1115	do {
1116		if ((nv_rd32(dev, reg) & mask) != val)
1117			return true;
1118	} while (ptimer->read(dev) - start < timeout);
1119
1120	return false;
1121}
1122
1123/* Waits for PGRAPH to go completely idle */
1124bool nouveau_wait_for_idle(struct drm_device *dev)
1125{
1126	struct drm_nouveau_private *dev_priv = dev->dev_private;
1127	uint32_t mask = ~0;
1128
1129	if (dev_priv->card_type == NV_40)
1130		mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL;
1131
1132	if (!nv_wait(dev, NV04_PGRAPH_STATUS, mask, 0)) {
1133		NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n",
1134			 nv_rd32(dev, NV04_PGRAPH_STATUS));
1135		return false;
1136	}
1137
1138	return true;
1139}
1140