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 "nv50_display.h" 39 40static void nouveau_stub_takedown(struct drm_device *dev) {} 41static int nouveau_stub_init(struct drm_device *dev) { return 0; } 42 43static int nouveau_init_engine_ptrs(struct drm_device *dev) 44{ 45 struct drm_nouveau_private *dev_priv = dev->dev_private; 46 struct nouveau_engine *engine = &dev_priv->engine; 47 48 switch (dev_priv->chipset & 0xf0) { 49 case 0x00: 50 engine->instmem.init = nv04_instmem_init; 51 engine->instmem.takedown = nv04_instmem_takedown; 52 engine->instmem.suspend = nv04_instmem_suspend; 53 engine->instmem.resume = nv04_instmem_resume; 54 engine->instmem.populate = nv04_instmem_populate; 55 engine->instmem.clear = nv04_instmem_clear; 56 engine->instmem.bind = nv04_instmem_bind; 57 engine->instmem.unbind = nv04_instmem_unbind; 58 engine->instmem.flush = nv04_instmem_flush; 59 engine->mc.init = nv04_mc_init; 60 engine->mc.takedown = nv04_mc_takedown; 61 engine->timer.init = nv04_timer_init; 62 engine->timer.read = nv04_timer_read; 63 engine->timer.takedown = nv04_timer_takedown; 64 engine->fb.init = nv04_fb_init; 65 engine->fb.takedown = nv04_fb_takedown; 66 engine->graph.grclass = nv04_graph_grclass; 67 engine->graph.init = nv04_graph_init; 68 engine->graph.takedown = nv04_graph_takedown; 69 engine->graph.fifo_access = nv04_graph_fifo_access; 70 engine->graph.channel = nv04_graph_channel; 71 engine->graph.create_context = nv04_graph_create_context; 72 engine->graph.destroy_context = nv04_graph_destroy_context; 73 engine->graph.load_context = nv04_graph_load_context; 74 engine->graph.unload_context = nv04_graph_unload_context; 75 engine->fifo.channels = 16; 76 engine->fifo.init = nv04_fifo_init; 77 engine->fifo.takedown = nouveau_stub_takedown; 78 engine->fifo.disable = nv04_fifo_disable; 79 engine->fifo.enable = nv04_fifo_enable; 80 engine->fifo.reassign = nv04_fifo_reassign; 81 engine->fifo.cache_flush = nv04_fifo_cache_flush; 82 engine->fifo.cache_pull = nv04_fifo_cache_pull; 83 engine->fifo.channel_id = nv04_fifo_channel_id; 84 engine->fifo.create_context = nv04_fifo_create_context; 85 engine->fifo.destroy_context = nv04_fifo_destroy_context; 86 engine->fifo.load_context = nv04_fifo_load_context; 87 engine->fifo.unload_context = nv04_fifo_unload_context; 88 engine->display.early_init = nv04_display_early_init; 89 engine->display.late_takedown = nv04_display_late_takedown; 90 engine->display.create = nv04_display_create; 91 engine->display.init = nv04_display_init; 92 engine->display.destroy = nv04_display_destroy; 93 engine->gpio.init = nouveau_stub_init; 94 engine->gpio.takedown = nouveau_stub_takedown; 95 engine->gpio.get = NULL; 96 engine->gpio.set = NULL; 97 engine->gpio.irq_enable = NULL; 98 break; 99 case 0x10: 100 engine->instmem.init = nv04_instmem_init; 101 engine->instmem.takedown = nv04_instmem_takedown; 102 engine->instmem.suspend = nv04_instmem_suspend; 103 engine->instmem.resume = nv04_instmem_resume; 104 engine->instmem.populate = nv04_instmem_populate; 105 engine->instmem.clear = nv04_instmem_clear; 106 engine->instmem.bind = nv04_instmem_bind; 107 engine->instmem.unbind = nv04_instmem_unbind; 108 engine->instmem.flush = nv04_instmem_flush; 109 engine->mc.init = nv04_mc_init; 110 engine->mc.takedown = nv04_mc_takedown; 111 engine->timer.init = nv04_timer_init; 112 engine->timer.read = nv04_timer_read; 113 engine->timer.takedown = nv04_timer_takedown; 114 engine->fb.init = nv10_fb_init; 115 engine->fb.takedown = nv10_fb_takedown; 116 engine->fb.set_region_tiling = nv10_fb_set_region_tiling; 117 engine->graph.grclass = nv10_graph_grclass; 118 engine->graph.init = nv10_graph_init; 119 engine->graph.takedown = nv10_graph_takedown; 120 engine->graph.channel = nv10_graph_channel; 121 engine->graph.create_context = nv10_graph_create_context; 122 engine->graph.destroy_context = nv10_graph_destroy_context; 123 engine->graph.fifo_access = nv04_graph_fifo_access; 124 engine->graph.load_context = nv10_graph_load_context; 125 engine->graph.unload_context = nv10_graph_unload_context; 126 engine->graph.set_region_tiling = nv10_graph_set_region_tiling; 127 engine->fifo.channels = 32; 128 engine->fifo.init = nv10_fifo_init; 129 engine->fifo.takedown = nouveau_stub_takedown; 130 engine->fifo.disable = nv04_fifo_disable; 131 engine->fifo.enable = nv04_fifo_enable; 132 engine->fifo.reassign = nv04_fifo_reassign; 133 engine->fifo.cache_flush = nv04_fifo_cache_flush; 134 engine->fifo.cache_pull = nv04_fifo_cache_pull; 135 engine->fifo.channel_id = nv10_fifo_channel_id; 136 engine->fifo.create_context = nv10_fifo_create_context; 137 engine->fifo.destroy_context = nv10_fifo_destroy_context; 138 engine->fifo.load_context = nv10_fifo_load_context; 139 engine->fifo.unload_context = nv10_fifo_unload_context; 140 engine->display.early_init = nv04_display_early_init; 141 engine->display.late_takedown = nv04_display_late_takedown; 142 engine->display.create = nv04_display_create; 143 engine->display.init = nv04_display_init; 144 engine->display.destroy = nv04_display_destroy; 145 engine->gpio.init = nouveau_stub_init; 146 engine->gpio.takedown = nouveau_stub_takedown; 147 engine->gpio.get = nv10_gpio_get; 148 engine->gpio.set = nv10_gpio_set; 149 engine->gpio.irq_enable = NULL; 150 break; 151 case 0x20: 152 engine->instmem.init = nv04_instmem_init; 153 engine->instmem.takedown = nv04_instmem_takedown; 154 engine->instmem.suspend = nv04_instmem_suspend; 155 engine->instmem.resume = nv04_instmem_resume; 156 engine->instmem.populate = nv04_instmem_populate; 157 engine->instmem.clear = nv04_instmem_clear; 158 engine->instmem.bind = nv04_instmem_bind; 159 engine->instmem.unbind = nv04_instmem_unbind; 160 engine->instmem.flush = nv04_instmem_flush; 161 engine->mc.init = nv04_mc_init; 162 engine->mc.takedown = nv04_mc_takedown; 163 engine->timer.init = nv04_timer_init; 164 engine->timer.read = nv04_timer_read; 165 engine->timer.takedown = nv04_timer_takedown; 166 engine->fb.init = nv10_fb_init; 167 engine->fb.takedown = nv10_fb_takedown; 168 engine->fb.set_region_tiling = nv10_fb_set_region_tiling; 169 engine->graph.grclass = nv20_graph_grclass; 170 engine->graph.init = nv20_graph_init; 171 engine->graph.takedown = nv20_graph_takedown; 172 engine->graph.channel = nv10_graph_channel; 173 engine->graph.create_context = nv20_graph_create_context; 174 engine->graph.destroy_context = nv20_graph_destroy_context; 175 engine->graph.fifo_access = nv04_graph_fifo_access; 176 engine->graph.load_context = nv20_graph_load_context; 177 engine->graph.unload_context = nv20_graph_unload_context; 178 engine->graph.set_region_tiling = nv20_graph_set_region_tiling; 179 engine->fifo.channels = 32; 180 engine->fifo.init = nv10_fifo_init; 181 engine->fifo.takedown = nouveau_stub_takedown; 182 engine->fifo.disable = nv04_fifo_disable; 183 engine->fifo.enable = nv04_fifo_enable; 184 engine->fifo.reassign = nv04_fifo_reassign; 185 engine->fifo.cache_flush = nv04_fifo_cache_flush; 186 engine->fifo.cache_pull = nv04_fifo_cache_pull; 187 engine->fifo.channel_id = nv10_fifo_channel_id; 188 engine->fifo.create_context = nv10_fifo_create_context; 189 engine->fifo.destroy_context = nv10_fifo_destroy_context; 190 engine->fifo.load_context = nv10_fifo_load_context; 191 engine->fifo.unload_context = nv10_fifo_unload_context; 192 engine->display.early_init = nv04_display_early_init; 193 engine->display.late_takedown = nv04_display_late_takedown; 194 engine->display.create = nv04_display_create; 195 engine->display.init = nv04_display_init; 196 engine->display.destroy = nv04_display_destroy; 197 engine->gpio.init = nouveau_stub_init; 198 engine->gpio.takedown = nouveau_stub_takedown; 199 engine->gpio.get = nv10_gpio_get; 200 engine->gpio.set = nv10_gpio_set; 201 engine->gpio.irq_enable = NULL; 202 break; 203 case 0x30: 204 engine->instmem.init = nv04_instmem_init; 205 engine->instmem.takedown = nv04_instmem_takedown; 206 engine->instmem.suspend = nv04_instmem_suspend; 207 engine->instmem.resume = nv04_instmem_resume; 208 engine->instmem.populate = nv04_instmem_populate; 209 engine->instmem.clear = nv04_instmem_clear; 210 engine->instmem.bind = nv04_instmem_bind; 211 engine->instmem.unbind = nv04_instmem_unbind; 212 engine->instmem.flush = nv04_instmem_flush; 213 engine->mc.init = nv04_mc_init; 214 engine->mc.takedown = nv04_mc_takedown; 215 engine->timer.init = nv04_timer_init; 216 engine->timer.read = nv04_timer_read; 217 engine->timer.takedown = nv04_timer_takedown; 218 engine->fb.init = nv30_fb_init; 219 engine->fb.takedown = nv30_fb_takedown; 220 engine->fb.set_region_tiling = nv10_fb_set_region_tiling; 221 engine->graph.grclass = nv30_graph_grclass; 222 engine->graph.init = nv30_graph_init; 223 engine->graph.takedown = nv20_graph_takedown; 224 engine->graph.fifo_access = nv04_graph_fifo_access; 225 engine->graph.channel = nv10_graph_channel; 226 engine->graph.create_context = nv20_graph_create_context; 227 engine->graph.destroy_context = nv20_graph_destroy_context; 228 engine->graph.load_context = nv20_graph_load_context; 229 engine->graph.unload_context = nv20_graph_unload_context; 230 engine->graph.set_region_tiling = nv20_graph_set_region_tiling; 231 engine->fifo.channels = 32; 232 engine->fifo.init = nv10_fifo_init; 233 engine->fifo.takedown = nouveau_stub_takedown; 234 engine->fifo.disable = nv04_fifo_disable; 235 engine->fifo.enable = nv04_fifo_enable; 236 engine->fifo.reassign = nv04_fifo_reassign; 237 engine->fifo.cache_flush = nv04_fifo_cache_flush; 238 engine->fifo.cache_pull = nv04_fifo_cache_pull; 239 engine->fifo.channel_id = nv10_fifo_channel_id; 240 engine->fifo.create_context = nv10_fifo_create_context; 241 engine->fifo.destroy_context = nv10_fifo_destroy_context; 242 engine->fifo.load_context = nv10_fifo_load_context; 243 engine->fifo.unload_context = nv10_fifo_unload_context; 244 engine->display.early_init = nv04_display_early_init; 245 engine->display.late_takedown = nv04_display_late_takedown; 246 engine->display.create = nv04_display_create; 247 engine->display.init = nv04_display_init; 248 engine->display.destroy = nv04_display_destroy; 249 engine->gpio.init = nouveau_stub_init; 250 engine->gpio.takedown = nouveau_stub_takedown; 251 engine->gpio.get = nv10_gpio_get; 252 engine->gpio.set = nv10_gpio_set; 253 engine->gpio.irq_enable = NULL; 254 break; 255 case 0x40: 256 case 0x60: 257 engine->instmem.init = nv04_instmem_init; 258 engine->instmem.takedown = nv04_instmem_takedown; 259 engine->instmem.suspend = nv04_instmem_suspend; 260 engine->instmem.resume = nv04_instmem_resume; 261 engine->instmem.populate = nv04_instmem_populate; 262 engine->instmem.clear = nv04_instmem_clear; 263 engine->instmem.bind = nv04_instmem_bind; 264 engine->instmem.unbind = nv04_instmem_unbind; 265 engine->instmem.flush = nv04_instmem_flush; 266 engine->mc.init = nv40_mc_init; 267 engine->mc.takedown = nv40_mc_takedown; 268 engine->timer.init = nv04_timer_init; 269 engine->timer.read = nv04_timer_read; 270 engine->timer.takedown = nv04_timer_takedown; 271 engine->fb.init = nv40_fb_init; 272 engine->fb.takedown = nv40_fb_takedown; 273 engine->fb.set_region_tiling = nv40_fb_set_region_tiling; 274 engine->graph.grclass = nv40_graph_grclass; 275 engine->graph.init = nv40_graph_init; 276 engine->graph.takedown = nv40_graph_takedown; 277 engine->graph.fifo_access = nv04_graph_fifo_access; 278 engine->graph.channel = nv40_graph_channel; 279 engine->graph.create_context = nv40_graph_create_context; 280 engine->graph.destroy_context = nv40_graph_destroy_context; 281 engine->graph.load_context = nv40_graph_load_context; 282 engine->graph.unload_context = nv40_graph_unload_context; 283 engine->graph.set_region_tiling = nv40_graph_set_region_tiling; 284 engine->fifo.channels = 32; 285 engine->fifo.init = nv40_fifo_init; 286 engine->fifo.takedown = nouveau_stub_takedown; 287 engine->fifo.disable = nv04_fifo_disable; 288 engine->fifo.enable = nv04_fifo_enable; 289 engine->fifo.reassign = nv04_fifo_reassign; 290 engine->fifo.cache_flush = nv04_fifo_cache_flush; 291 engine->fifo.cache_pull = nv04_fifo_cache_pull; 292 engine->fifo.channel_id = nv10_fifo_channel_id; 293 engine->fifo.create_context = nv40_fifo_create_context; 294 engine->fifo.destroy_context = nv40_fifo_destroy_context; 295 engine->fifo.load_context = nv40_fifo_load_context; 296 engine->fifo.unload_context = nv40_fifo_unload_context; 297 engine->display.early_init = nv04_display_early_init; 298 engine->display.late_takedown = nv04_display_late_takedown; 299 engine->display.create = nv04_display_create; 300 engine->display.init = nv04_display_init; 301 engine->display.destroy = nv04_display_destroy; 302 engine->gpio.init = nouveau_stub_init; 303 engine->gpio.takedown = nouveau_stub_takedown; 304 engine->gpio.get = nv10_gpio_get; 305 engine->gpio.set = nv10_gpio_set; 306 engine->gpio.irq_enable = NULL; 307 break; 308 case 0x50: 309 case 0x80: /* gotta love NVIDIA's consistency.. */ 310 case 0x90: 311 case 0xA0: 312 engine->instmem.init = nv50_instmem_init; 313 engine->instmem.takedown = nv50_instmem_takedown; 314 engine->instmem.suspend = nv50_instmem_suspend; 315 engine->instmem.resume = nv50_instmem_resume; 316 engine->instmem.populate = nv50_instmem_populate; 317 engine->instmem.clear = nv50_instmem_clear; 318 engine->instmem.bind = nv50_instmem_bind; 319 engine->instmem.unbind = nv50_instmem_unbind; 320 if (dev_priv->chipset == 0x50) 321 engine->instmem.flush = nv50_instmem_flush; 322 else 323 engine->instmem.flush = nv84_instmem_flush; 324 engine->mc.init = nv50_mc_init; 325 engine->mc.takedown = nv50_mc_takedown; 326 engine->timer.init = nv04_timer_init; 327 engine->timer.read = nv04_timer_read; 328 engine->timer.takedown = nv04_timer_takedown; 329 engine->fb.init = nv50_fb_init; 330 engine->fb.takedown = nv50_fb_takedown; 331 engine->graph.grclass = nv50_graph_grclass; 332 engine->graph.init = nv50_graph_init; 333 engine->graph.takedown = nv50_graph_takedown; 334 engine->graph.fifo_access = nv50_graph_fifo_access; 335 engine->graph.channel = nv50_graph_channel; 336 engine->graph.create_context = nv50_graph_create_context; 337 engine->graph.destroy_context = nv50_graph_destroy_context; 338 engine->graph.load_context = nv50_graph_load_context; 339 engine->graph.unload_context = nv50_graph_unload_context; 340 engine->fifo.channels = 128; 341 engine->fifo.init = nv50_fifo_init; 342 engine->fifo.takedown = nv50_fifo_takedown; 343 engine->fifo.disable = nv04_fifo_disable; 344 engine->fifo.enable = nv04_fifo_enable; 345 engine->fifo.reassign = nv04_fifo_reassign; 346 engine->fifo.channel_id = nv50_fifo_channel_id; 347 engine->fifo.create_context = nv50_fifo_create_context; 348 engine->fifo.destroy_context = nv50_fifo_destroy_context; 349 engine->fifo.load_context = nv50_fifo_load_context; 350 engine->fifo.unload_context = nv50_fifo_unload_context; 351 engine->display.early_init = nv50_display_early_init; 352 engine->display.late_takedown = nv50_display_late_takedown; 353 engine->display.create = nv50_display_create; 354 engine->display.init = nv50_display_init; 355 engine->display.destroy = nv50_display_destroy; 356 engine->gpio.init = nv50_gpio_init; 357 engine->gpio.takedown = nouveau_stub_takedown; 358 engine->gpio.get = nv50_gpio_get; 359 engine->gpio.set = nv50_gpio_set; 360 engine->gpio.irq_enable = nv50_gpio_irq_enable; 361 break; 362 case 0xC0: 363 engine->instmem.init = nvc0_instmem_init; 364 engine->instmem.takedown = nvc0_instmem_takedown; 365 engine->instmem.suspend = nvc0_instmem_suspend; 366 engine->instmem.resume = nvc0_instmem_resume; 367 engine->instmem.populate = nvc0_instmem_populate; 368 engine->instmem.clear = nvc0_instmem_clear; 369 engine->instmem.bind = nvc0_instmem_bind; 370 engine->instmem.unbind = nvc0_instmem_unbind; 371 engine->instmem.flush = nvc0_instmem_flush; 372 engine->mc.init = nv50_mc_init; 373 engine->mc.takedown = nv50_mc_takedown; 374 engine->timer.init = nv04_timer_init; 375 engine->timer.read = nv04_timer_read; 376 engine->timer.takedown = nv04_timer_takedown; 377 engine->fb.init = nvc0_fb_init; 378 engine->fb.takedown = nvc0_fb_takedown; 379 engine->graph.grclass = NULL; //nvc0_graph_grclass; 380 engine->graph.init = nvc0_graph_init; 381 engine->graph.takedown = nvc0_graph_takedown; 382 engine->graph.fifo_access = nvc0_graph_fifo_access; 383 engine->graph.channel = nvc0_graph_channel; 384 engine->graph.create_context = nvc0_graph_create_context; 385 engine->graph.destroy_context = nvc0_graph_destroy_context; 386 engine->graph.load_context = nvc0_graph_load_context; 387 engine->graph.unload_context = nvc0_graph_unload_context; 388 engine->fifo.channels = 128; 389 engine->fifo.init = nvc0_fifo_init; 390 engine->fifo.takedown = nvc0_fifo_takedown; 391 engine->fifo.disable = nvc0_fifo_disable; 392 engine->fifo.enable = nvc0_fifo_enable; 393 engine->fifo.reassign = nvc0_fifo_reassign; 394 engine->fifo.channel_id = nvc0_fifo_channel_id; 395 engine->fifo.create_context = nvc0_fifo_create_context; 396 engine->fifo.destroy_context = nvc0_fifo_destroy_context; 397 engine->fifo.load_context = nvc0_fifo_load_context; 398 engine->fifo.unload_context = nvc0_fifo_unload_context; 399 engine->display.early_init = nv50_display_early_init; 400 engine->display.late_takedown = nv50_display_late_takedown; 401 engine->display.create = nv50_display_create; 402 engine->display.init = nv50_display_init; 403 engine->display.destroy = nv50_display_destroy; 404 engine->gpio.init = nv50_gpio_init; 405 engine->gpio.takedown = nouveau_stub_takedown; 406 engine->gpio.get = nv50_gpio_get; 407 engine->gpio.set = nv50_gpio_set; 408 engine->gpio.irq_enable = nv50_gpio_irq_enable; 409 break; 410 default: 411 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); 412 return 1; 413 } 414 415 return 0; 416} 417 418static unsigned int 419nouveau_vga_set_decode(void *priv, bool state) 420{ 421 struct drm_device *dev = priv; 422 struct drm_nouveau_private *dev_priv = dev->dev_private; 423 424 if (dev_priv->chipset >= 0x40) 425 nv_wr32(dev, 0x88054, state); 426 else 427 nv_wr32(dev, 0x1854, state); 428 429 if (state) 430 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | 431 VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 432 else 433 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 434} 435 436static int 437nouveau_card_init_channel(struct drm_device *dev) 438{ 439 struct drm_nouveau_private *dev_priv = dev->dev_private; 440 struct nouveau_gpuobj *gpuobj; 441 int ret; 442 443 ret = nouveau_channel_alloc(dev, &dev_priv->channel, 444 (struct drm_file *)-2, 445 NvDmaFB, NvDmaTT); 446 if (ret) 447 return ret; 448 449 gpuobj = NULL; 450 ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, 451 0, dev_priv->vram_size, 452 NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, 453 &gpuobj); 454 if (ret) 455 goto out_err; 456 457 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, 458 gpuobj, NULL); 459 if (ret) 460 goto out_err; 461 462 gpuobj = NULL; 463 ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, 464 dev_priv->gart_info.aper_size, 465 NV_DMA_ACCESS_RW, &gpuobj, NULL); 466 if (ret) 467 goto out_err; 468 469 ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, 470 gpuobj, NULL); 471 if (ret) 472 goto out_err; 473 474 return 0; 475out_err: 476 nouveau_gpuobj_del(dev, &gpuobj); 477 nouveau_channel_free(dev_priv->channel); 478 dev_priv->channel = NULL; 479 return ret; 480} 481 482static void nouveau_switcheroo_set_state(struct pci_dev *pdev, 483 enum vga_switcheroo_state state) 484{ 485 struct drm_device *dev = pci_get_drvdata(pdev); 486 pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; 487 if (state == VGA_SWITCHEROO_ON) { 488 printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); 489 nouveau_pci_resume(pdev); 490 drm_kms_helper_poll_enable(dev); 491 } else { 492 printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); 493 drm_kms_helper_poll_disable(dev); 494 nouveau_pci_suspend(pdev, pmm); 495 } 496} 497 498static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev) 499{ 500 struct drm_device *dev = pci_get_drvdata(pdev); 501 bool can_switch; 502 503 spin_lock(&dev->count_lock); 504 can_switch = (dev->open_count == 0); 505 spin_unlock(&dev->count_lock); 506 return can_switch; 507} 508 509int 510nouveau_card_init(struct drm_device *dev) 511{ 512 struct drm_nouveau_private *dev_priv = dev->dev_private; 513 struct nouveau_engine *engine; 514 int ret; 515 516 vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); 517 vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, 518 nouveau_switcheroo_can_switch); 519 520 /* Initialise internal driver API hooks */ 521 ret = nouveau_init_engine_ptrs(dev); 522 if (ret) 523 goto out; 524 engine = &dev_priv->engine; 525 spin_lock_init(&dev_priv->context_switch_lock); 526 527 /* Make the CRTCs and I2C buses accessible */ 528 ret = engine->display.early_init(dev); 529 if (ret) 530 goto out; 531 532 /* Parse BIOS tables / Run init tables if card not POSTed */ 533 ret = nouveau_bios_init(dev); 534 if (ret) 535 goto out_display_early; 536 537 ret = nouveau_mem_detect(dev); 538 if (ret) 539 goto out_bios; 540 541 ret = nouveau_gpuobj_early_init(dev); 542 if (ret) 543 goto out_bios; 544 545 /* Initialise instance memory, must happen before mem_init so we 546 * know exactly how much VRAM we're able to use for "normal" 547 * purposes. 548 */ 549 ret = engine->instmem.init(dev); 550 if (ret) 551 goto out_gpuobj_early; 552 553 /* Setup the memory manager */ 554 ret = nouveau_mem_init(dev); 555 if (ret) 556 goto out_instmem; 557 558 ret = nouveau_gpuobj_init(dev); 559 if (ret) 560 goto out_mem; 561 562 /* PMC */ 563 ret = engine->mc.init(dev); 564 if (ret) 565 goto out_gpuobj; 566 567 /* PGPIO */ 568 ret = engine->gpio.init(dev); 569 if (ret) 570 goto out_mc; 571 572 /* PTIMER */ 573 ret = engine->timer.init(dev); 574 if (ret) 575 goto out_gpio; 576 577 /* PFB */ 578 ret = engine->fb.init(dev); 579 if (ret) 580 goto out_timer; 581 582 if (nouveau_noaccel) 583 engine->graph.accel_blocked = true; 584 else { 585 /* PGRAPH */ 586 ret = engine->graph.init(dev); 587 if (ret) 588 goto out_fb; 589 590 /* PFIFO */ 591 ret = engine->fifo.init(dev); 592 if (ret) 593 goto out_graph; 594 } 595 596 ret = engine->display.create(dev); 597 if (ret) 598 goto out_fifo; 599 600 /* this call irq_preinstall, register irq handler and 601 * call irq_postinstall 602 */ 603 ret = drm_irq_install(dev); 604 if (ret) 605 goto out_display; 606 607 ret = drm_vblank_init(dev, 0); 608 if (ret) 609 goto out_irq; 610 611 /* what about PVIDEO/PCRTC/PRAMDAC etc? */ 612 613 if (!engine->graph.accel_blocked) { 614 ret = nouveau_card_init_channel(dev); 615 if (ret) 616 goto out_irq; 617 } 618 619 ret = nouveau_backlight_init(dev); 620 if (ret) 621 NV_ERROR(dev, "Error %d registering backlight\n", ret); 622 623 nouveau_fbcon_init(dev); 624 drm_kms_helper_poll_init(dev); 625 return 0; 626 627out_irq: 628 drm_irq_uninstall(dev); 629out_display: 630 engine->display.destroy(dev); 631out_fifo: 632 if (!nouveau_noaccel) 633 engine->fifo.takedown(dev); 634out_graph: 635 if (!nouveau_noaccel) 636 engine->graph.takedown(dev); 637out_fb: 638 engine->fb.takedown(dev); 639out_timer: 640 engine->timer.takedown(dev); 641out_gpio: 642 engine->gpio.takedown(dev); 643out_mc: 644 engine->mc.takedown(dev); 645out_gpuobj: 646 nouveau_gpuobj_takedown(dev); 647out_mem: 648 nouveau_sgdma_takedown(dev); 649 nouveau_mem_close(dev); 650out_instmem: 651 engine->instmem.takedown(dev); 652out_gpuobj_early: 653 nouveau_gpuobj_late_takedown(dev); 654out_bios: 655 nouveau_bios_takedown(dev); 656out_display_early: 657 engine->display.late_takedown(dev); 658out: 659 vga_client_register(dev->pdev, NULL, NULL, NULL); 660 return ret; 661} 662 663static void nouveau_card_takedown(struct drm_device *dev) 664{ 665 struct drm_nouveau_private *dev_priv = dev->dev_private; 666 struct nouveau_engine *engine = &dev_priv->engine; 667 668 nouveau_backlight_exit(dev); 669 670 if (dev_priv->channel) { 671 nouveau_channel_free(dev_priv->channel); 672 dev_priv->channel = NULL; 673 } 674 675 if (!nouveau_noaccel) { 676 engine->fifo.takedown(dev); 677 engine->graph.takedown(dev); 678 } 679 engine->fb.takedown(dev); 680 engine->timer.takedown(dev); 681 engine->gpio.takedown(dev); 682 engine->mc.takedown(dev); 683 engine->display.late_takedown(dev); 684 685 mutex_lock(&dev->struct_mutex); 686 ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); 687 ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); 688 mutex_unlock(&dev->struct_mutex); 689 nouveau_sgdma_takedown(dev); 690 691 nouveau_gpuobj_takedown(dev); 692 nouveau_mem_close(dev); 693 engine->instmem.takedown(dev); 694 695 drm_irq_uninstall(dev); 696 697 nouveau_gpuobj_late_takedown(dev); 698 nouveau_bios_takedown(dev); 699 700 vga_client_register(dev->pdev, NULL, NULL, NULL); 701} 702 703/* here a client dies, release the stuff that was allocated for its 704 * file_priv */ 705void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv) 706{ 707 nouveau_channel_cleanup(dev, file_priv); 708} 709 710/* first module load, setup the mmio/fb mapping */ 711/* KMS: we need mmio at load time, not when the first drm client opens. */ 712int nouveau_firstopen(struct drm_device *dev) 713{ 714 return 0; 715} 716 717/* if we have an OF card, copy vbios to RAMIN */ 718static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev) 719{ 720#if defined(__powerpc__) 721 int size, i; 722 const uint32_t *bios; 723 struct device_node *dn = pci_device_to_OF_node(dev->pdev); 724 if (!dn) { 725 NV_INFO(dev, "Unable to get the OF node\n"); 726 return; 727 } 728 729 bios = of_get_property(dn, "NVDA,BMP", &size); 730 if (bios) { 731 for (i = 0; i < size; i += 4) 732 nv_wi32(dev, i, bios[i/4]); 733 NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size); 734 } else { 735 NV_INFO(dev, "Unable to get the OF bios\n"); 736 } 737#endif 738} 739 740static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev) 741{ 742 struct pci_dev *pdev = dev->pdev; 743 struct apertures_struct *aper = alloc_apertures(3); 744 if (!aper) 745 return NULL; 746 747 aper->ranges[0].base = pci_resource_start(pdev, 1); 748 aper->ranges[0].size = pci_resource_len(pdev, 1); 749 aper->count = 1; 750 751 if (pci_resource_len(pdev, 2)) { 752 aper->ranges[aper->count].base = pci_resource_start(pdev, 2); 753 aper->ranges[aper->count].size = pci_resource_len(pdev, 2); 754 aper->count++; 755 } 756 757 if (pci_resource_len(pdev, 3)) { 758 aper->ranges[aper->count].base = pci_resource_start(pdev, 3); 759 aper->ranges[aper->count].size = pci_resource_len(pdev, 3); 760 aper->count++; 761 } 762 763 return aper; 764} 765 766static int nouveau_remove_conflicting_drivers(struct drm_device *dev) 767{ 768 struct drm_nouveau_private *dev_priv = dev->dev_private; 769 bool primary = false; 770 dev_priv->apertures = nouveau_get_apertures(dev); 771 if (!dev_priv->apertures) 772 return -ENOMEM; 773 774#ifdef CONFIG_X86 775 primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; 776#endif 777 778 remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary); 779 return 0; 780} 781 782int nouveau_load(struct drm_device *dev, unsigned long flags) 783{ 784 struct drm_nouveau_private *dev_priv; 785 uint32_t reg0; 786 resource_size_t mmio_start_offs; 787 int ret; 788 789 dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); 790 if (!dev_priv) { 791 ret = -ENOMEM; 792 goto err_out; 793 } 794 dev->dev_private = dev_priv; 795 dev_priv->dev = dev; 796 797 dev_priv->flags = flags & NOUVEAU_FLAGS; 798 799 NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", 800 dev->pci_vendor, dev->pci_device, dev->pdev->class); 801 802 dev_priv->wq = create_workqueue("nouveau"); 803 if (!dev_priv->wq) { 804 ret = -EINVAL; 805 goto err_priv; 806 } 807 808 /* resource 0 is mmio regs */ 809 /* resource 1 is linear FB */ 810 /* resource 2 is RAMIN (mmio regs + 0x1000000) */ 811 /* resource 6 is bios */ 812 813 /* map the mmio regs */ 814 mmio_start_offs = pci_resource_start(dev->pdev, 0); 815 dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000); 816 if (!dev_priv->mmio) { 817 NV_ERROR(dev, "Unable to initialize the mmio mapping. " 818 "Please report your setup to " DRIVER_EMAIL "\n"); 819 ret = -EINVAL; 820 goto err_wq; 821 } 822 NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", 823 (unsigned long long)mmio_start_offs); 824 825#ifdef __BIG_ENDIAN 826 /* Put the card in BE mode if it's not */ 827 if (nv_rd32(dev, NV03_PMC_BOOT_1)) 828 nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001); 829 830 DRM_MEMORYBARRIER(); 831#endif 832 833 /* Time to determine the card architecture */ 834 reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); 835 836 /* We're dealing with >=NV10 */ 837 if ((reg0 & 0x0f000000) > 0) { 838 /* Bit 27-20 contain the architecture in hex */ 839 dev_priv->chipset = (reg0 & 0xff00000) >> 20; 840 /* NV04 or NV05 */ 841 } else if ((reg0 & 0xff00fff0) == 0x20004000) { 842 if (reg0 & 0x00f00000) 843 dev_priv->chipset = 0x05; 844 else 845 dev_priv->chipset = 0x04; 846 } else 847 dev_priv->chipset = 0xff; 848 849 switch (dev_priv->chipset & 0xf0) { 850 case 0x00: 851 case 0x10: 852 case 0x20: 853 case 0x30: 854 dev_priv->card_type = dev_priv->chipset & 0xf0; 855 break; 856 case 0x40: 857 case 0x60: 858 dev_priv->card_type = NV_40; 859 break; 860 case 0x50: 861 case 0x80: 862 case 0x90: 863 case 0xa0: 864 dev_priv->card_type = NV_50; 865 break; 866 case 0xc0: 867 dev_priv->card_type = NV_C0; 868 break; 869 default: 870 NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0); 871 ret = -EINVAL; 872 goto err_mmio; 873 } 874 875 NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", 876 dev_priv->card_type, reg0); 877 878 ret = nouveau_remove_conflicting_drivers(dev); 879 if (ret) 880 goto err_mmio; 881 882 /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ 883 if (dev_priv->card_type >= NV_40) { 884 int ramin_bar = 2; 885 if (pci_resource_len(dev->pdev, ramin_bar) == 0) 886 ramin_bar = 3; 887 888 dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar); 889 dev_priv->ramin = 890 ioremap(pci_resource_start(dev->pdev, ramin_bar), 891 dev_priv->ramin_size); 892 if (!dev_priv->ramin) { 893 NV_ERROR(dev, "Failed to PRAMIN BAR"); 894 ret = -ENOMEM; 895 goto err_mmio; 896 } 897 } else { 898 dev_priv->ramin_size = 1 * 1024 * 1024; 899 dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN, 900 dev_priv->ramin_size); 901 if (!dev_priv->ramin) { 902 NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n"); 903 ret = -ENOMEM; 904 goto err_mmio; 905 } 906 } 907 908 nouveau_OF_copy_vbios_to_ramin(dev); 909 910 /* Special flags */ 911 if (dev->pci_device == 0x01a0) 912 dev_priv->flags |= NV_NFORCE; 913 else if (dev->pci_device == 0x01f0) 914 dev_priv->flags |= NV_NFORCE2; 915 916 /* For kernel modesetting, init card now and bring up fbcon */ 917 ret = nouveau_card_init(dev); 918 if (ret) 919 goto err_ramin; 920 921 return 0; 922 923err_ramin: 924 iounmap(dev_priv->ramin); 925err_mmio: 926 iounmap(dev_priv->mmio); 927err_wq: 928 destroy_workqueue(dev_priv->wq); 929err_priv: 930 kfree(dev_priv); 931 dev->dev_private = NULL; 932err_out: 933 return ret; 934} 935 936void nouveau_lastclose(struct drm_device *dev) 937{ 938} 939 940int nouveau_unload(struct drm_device *dev) 941{ 942 struct drm_nouveau_private *dev_priv = dev->dev_private; 943 struct nouveau_engine *engine = &dev_priv->engine; 944 945 drm_kms_helper_poll_fini(dev); 946 nouveau_fbcon_fini(dev); 947 engine->display.destroy(dev); 948 nouveau_card_takedown(dev); 949 950 iounmap(dev_priv->mmio); 951 iounmap(dev_priv->ramin); 952 953 kfree(dev_priv); 954 dev->dev_private = NULL; 955 return 0; 956} 957 958int nouveau_ioctl_getparam(struct drm_device *dev, void *data, 959 struct drm_file *file_priv) 960{ 961 struct drm_nouveau_private *dev_priv = dev->dev_private; 962 struct drm_nouveau_getparam *getparam = data; 963 964 switch (getparam->param) { 965 case NOUVEAU_GETPARAM_CHIPSET_ID: 966 getparam->value = dev_priv->chipset; 967 break; 968 case NOUVEAU_GETPARAM_PCI_VENDOR: 969 getparam->value = dev->pci_vendor; 970 break; 971 case NOUVEAU_GETPARAM_PCI_DEVICE: 972 getparam->value = dev->pci_device; 973 break; 974 case NOUVEAU_GETPARAM_BUS_TYPE: 975 if (drm_device_is_agp(dev)) 976 getparam->value = NV_AGP; 977 else if (drm_device_is_pcie(dev)) 978 getparam->value = NV_PCIE; 979 else 980 getparam->value = NV_PCI; 981 break; 982 case NOUVEAU_GETPARAM_FB_PHYSICAL: 983 getparam->value = dev_priv->fb_phys; 984 break; 985 case NOUVEAU_GETPARAM_AGP_PHYSICAL: 986 getparam->value = dev_priv->gart_info.aper_base; 987 break; 988 case NOUVEAU_GETPARAM_PCI_PHYSICAL: 989 if (dev->sg) { 990 getparam->value = (unsigned long)dev->sg->virtual; 991 } else { 992 NV_ERROR(dev, "Requested PCIGART address, " 993 "while no PCIGART was created\n"); 994 return -EINVAL; 995 } 996 break; 997 case NOUVEAU_GETPARAM_FB_SIZE: 998 getparam->value = dev_priv->fb_available_size; 999 break; 1000 case NOUVEAU_GETPARAM_AGP_SIZE: 1001 getparam->value = dev_priv->gart_info.aper_size; 1002 break; 1003 case NOUVEAU_GETPARAM_VM_VRAM_BASE: 1004 getparam->value = dev_priv->vm_vram_base; 1005 break; 1006 case NOUVEAU_GETPARAM_PTIMER_TIME: 1007 getparam->value = dev_priv->engine.timer.read(dev); 1008 break; 1009 case NOUVEAU_GETPARAM_GRAPH_UNITS: 1010 /* NV40 and NV50 versions are quite different, but register 1011 * address is the same. User is supposed to know the card 1012 * family anyway... */ 1013 if (dev_priv->chipset >= 0x40) { 1014 getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS); 1015 break; 1016 } 1017 /* FALLTHRU */ 1018 default: 1019 NV_ERROR(dev, "unknown parameter %lld\n", getparam->param); 1020 return -EINVAL; 1021 } 1022 1023 return 0; 1024} 1025 1026int 1027nouveau_ioctl_setparam(struct drm_device *dev, void *data, 1028 struct drm_file *file_priv) 1029{ 1030 struct drm_nouveau_setparam *setparam = data; 1031 1032 switch (setparam->param) { 1033 default: 1034 NV_ERROR(dev, "unknown parameter %lld\n", setparam->param); 1035 return -EINVAL; 1036 } 1037 1038 return 0; 1039} 1040 1041/* Wait until (value(reg) & mask) == val, up until timeout has hit */ 1042bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, 1043 uint32_t reg, uint32_t mask, uint32_t val) 1044{ 1045 struct drm_nouveau_private *dev_priv = dev->dev_private; 1046 struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; 1047 uint64_t start = ptimer->read(dev); 1048 1049 do { 1050 if ((nv_rd32(dev, reg) & mask) == val) 1051 return true; 1052 } while (ptimer->read(dev) - start < timeout); 1053 1054 return false; 1055} 1056 1057/* Waits for PGRAPH to go completely idle */ 1058bool nouveau_wait_for_idle(struct drm_device *dev) 1059{ 1060 if (!nv_wait(NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) { 1061 NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n", 1062 nv_rd32(dev, NV04_PGRAPH_STATUS)); 1063 return false; 1064 } 1065 1066 return true; 1067} 1068