aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2010-07-23 14:29:13 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-07-25 21:43:25 -0400
commite04d8e829d7807e132d8c82c3554b164a803c617 (patch)
tree59a48dcafc2791869ec79b57616d2d83b71754f5 /drivers
parent8bded189552800cae6c333475a54dabe048a74aa (diff)
drm/nouveau: Reset AGP before running the init scripts.
BIOS scripts usually make an attempt to reset the AGP controller, however on some nv4x cards doing it properly involves switching FW off and on: if we do that without updating the AGP bridge settings accordingly (e.g. with the corresponding calls to agp_enable()) we will be locking ourselves out of the card MMIO space. Do it from nouveau_mem_reset_agp() before the init scripts are executed. Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c43
3 files changed, 34 insertions, 14 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index e93fbcc56da5..eeaf1f15a428 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -259,6 +259,10 @@ nouveau_pci_resume(struct pci_dev *pdev)
259 return -1; 259 return -1;
260 pci_set_master(dev->pdev); 260 pci_set_master(dev->pdev);
261 261
262 /* Make sure the AGP controller is in a consistent state */
263 if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
264 nouveau_mem_reset_agp(dev);
265
262 NV_INFO(dev, "POSTing device...\n"); 266 NV_INFO(dev, "POSTing device...\n");
263 ret = nouveau_run_vbios_init(dev); 267 ret = nouveau_run_vbios_init(dev);
264 if (ret) 268 if (ret)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 9f4b8f2e2ec8..8590032d36ad 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -688,6 +688,7 @@ extern int nouveau_card_init(struct drm_device *);
688extern int nouveau_mem_detect(struct drm_device *dev); 688extern int nouveau_mem_detect(struct drm_device *dev);
689extern int nouveau_mem_init(struct drm_device *); 689extern int nouveau_mem_init(struct drm_device *);
690extern int nouveau_mem_init_agp(struct drm_device *); 690extern int nouveau_mem_init_agp(struct drm_device *);
691extern int nouveau_mem_reset_agp(struct drm_device *);
691extern void nouveau_mem_close(struct drm_device *); 692extern void nouveau_mem_close(struct drm_device *);
692extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev, 693extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev,
693 uint32_t addr, 694 uint32_t addr,
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 568bcc21216f..a9f36ab256b7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -341,18 +341,36 @@ nouveau_mem_detect(struct drm_device *dev)
341 return -ENOMEM; 341 return -ENOMEM;
342} 342}
343 343
344#if __OS_HAS_AGP 344int
345static void nouveau_mem_reset_agp(struct drm_device *dev) 345nouveau_mem_reset_agp(struct drm_device *dev)
346{ 346{
347 uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable; 347#if __OS_HAS_AGP
348 uint32_t saved_pci_nv_1, pmc_enable;
349 int ret;
350
351 /* First of all, disable fast writes, otherwise if it's
352 * already enabled in the AGP bridge and we disable the card's
353 * AGP controller we might be locking ourselves out of it. */
354 if (dev->agp->acquired) {
355 struct drm_agp_info info;
356 struct drm_agp_mode mode;
357
358 ret = drm_agp_info(dev, &info);
359 if (ret)
360 return ret;
361
362 mode.mode = info.mode & ~0x10;
363 ret = drm_agp_enable(dev, mode);
364 if (ret)
365 return ret;
366 }
348 367
349 saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1); 368 saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1);
350 saved_pci_nv_19 = nv_rd32(dev, NV04_PBUS_PCI_NV_19);
351 369
352 /* clear busmaster bit */ 370 /* clear busmaster bit */
353 nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4); 371 nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4);
354 /* clear SBA and AGP bits */ 372 /* disable AGP */
355 nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff); 373 nv_wr32(dev, NV04_PBUS_PCI_NV_19, 0);
356 374
357 /* power cycle pgraph, if enabled */ 375 /* power cycle pgraph, if enabled */
358 pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); 376 pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE);
@@ -364,11 +382,12 @@ static void nouveau_mem_reset_agp(struct drm_device *dev)
364 } 382 }
365 383
366 /* and restore (gives effect of resetting AGP) */ 384 /* and restore (gives effect of resetting AGP) */
367 nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19);
368 nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1); 385 nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
369}
370#endif 386#endif
371 387
388 return 0;
389}
390
372int 391int
373nouveau_mem_init_agp(struct drm_device *dev) 392nouveau_mem_init_agp(struct drm_device *dev)
374{ 393{
@@ -378,11 +397,6 @@ nouveau_mem_init_agp(struct drm_device *dev)
378 struct drm_agp_mode mode; 397 struct drm_agp_mode mode;
379 int ret; 398 int ret;
380 399
381 if (nouveau_noagp)
382 return 0;
383
384 nouveau_mem_reset_agp(dev);
385
386 if (!dev->agp->acquired) { 400 if (!dev->agp->acquired) {
387 ret = drm_agp_acquire(dev); 401 ret = drm_agp_acquire(dev);
388 if (ret) { 402 if (ret) {
@@ -479,7 +493,8 @@ nouveau_mem_init(struct drm_device *dev)
479 493
480 /* GART */ 494 /* GART */
481#if !defined(__powerpc__) && !defined(__ia64__) 495#if !defined(__powerpc__) && !defined(__ia64__)
482 if (drm_device_is_agp(dev) && dev->agp) { 496 if (drm_device_is_agp(dev) && dev->agp && !nouveau_noagp) {
497 nouveau_mem_reset_agp(dev);
483 ret = nouveau_mem_init_agp(dev); 498 ret = nouveau_mem_init_agp(dev);
484 if (ret) 499 if (ret)
485 NV_ERROR(dev, "Error initialising AGP: %d\n", ret); 500 NV_ERROR(dev, "Error initialising AGP: %d\n", ret);