Skip to content

Commit

Permalink
drm/nouveau: Reset AGP before running the init scripts.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Francisco Jerez authored and Ben Skeggs committed Jul 26, 2010
1 parent 8bded18 commit e04d8e8
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ nouveau_pci_resume(struct pci_dev *pdev)
return -1;
pci_set_master(dev->pdev);

/* Make sure the AGP controller is in a consistent state */
if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
nouveau_mem_reset_agp(dev);

NV_INFO(dev, "POSTing device...\n");
ret = nouveau_run_vbios_init(dev);
if (ret)
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ extern int nouveau_card_init(struct drm_device *);
extern int nouveau_mem_detect(struct drm_device *dev);
extern int nouveau_mem_init(struct drm_device *);
extern int nouveau_mem_init_agp(struct drm_device *);
extern int nouveau_mem_reset_agp(struct drm_device *);
extern void nouveau_mem_close(struct drm_device *);
extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev,
uint32_t addr,
Expand Down
43 changes: 29 additions & 14 deletions drivers/gpu/drm/nouveau/nouveau_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,18 +341,36 @@ nouveau_mem_detect(struct drm_device *dev)
return -ENOMEM;
}

#if __OS_HAS_AGP
static void nouveau_mem_reset_agp(struct drm_device *dev)
int
nouveau_mem_reset_agp(struct drm_device *dev)
{
uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable;
#if __OS_HAS_AGP
uint32_t saved_pci_nv_1, pmc_enable;
int ret;

/* First of all, disable fast writes, otherwise if it's
* already enabled in the AGP bridge and we disable the card's
* AGP controller we might be locking ourselves out of it. */
if (dev->agp->acquired) {
struct drm_agp_info info;
struct drm_agp_mode mode;

ret = drm_agp_info(dev, &info);
if (ret)
return ret;

mode.mode = info.mode & ~0x10;
ret = drm_agp_enable(dev, mode);
if (ret)
return ret;
}

saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1);
saved_pci_nv_19 = nv_rd32(dev, NV04_PBUS_PCI_NV_19);

/* clear busmaster bit */
nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4);
/* clear SBA and AGP bits */
nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff);
/* disable AGP */
nv_wr32(dev, NV04_PBUS_PCI_NV_19, 0);

/* power cycle pgraph, if enabled */
pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE);
Expand All @@ -364,11 +382,12 @@ static void nouveau_mem_reset_agp(struct drm_device *dev)
}

/* and restore (gives effect of resetting AGP) */
nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19);
nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
}
#endif

return 0;
}

int
nouveau_mem_init_agp(struct drm_device *dev)
{
Expand All @@ -378,11 +397,6 @@ nouveau_mem_init_agp(struct drm_device *dev)
struct drm_agp_mode mode;
int ret;

if (nouveau_noagp)
return 0;

nouveau_mem_reset_agp(dev);

if (!dev->agp->acquired) {
ret = drm_agp_acquire(dev);
if (ret) {
Expand Down Expand Up @@ -479,7 +493,8 @@ nouveau_mem_init(struct drm_device *dev)

/* GART */
#if !defined(__powerpc__) && !defined(__ia64__)
if (drm_device_is_agp(dev) && dev->agp) {
if (drm_device_is_agp(dev) && dev->agp && !nouveau_noagp) {
nouveau_mem_reset_agp(dev);
ret = nouveau_mem_init_agp(dev);
if (ret)
NV_ERROR(dev, "Error initialising AGP: %d\n", ret);
Expand Down

0 comments on commit e04d8e8

Please sign in to comment.