From 01d73a6967f12fe6c4bbde1834a9fe662264a2eb Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 27 May 2010 13:40:24 -0600 Subject: drm: Remove drm_resource wrappers Remove the drm_resource wrappers and directly use the actual PCI and/or platform functions in their place. [airlied: fixup nouveau properly to build] Signed-off-by: Jordan Crouse Reviewed-by: Matt Turner Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index f7ba82e..7783035 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -39,19 +39,6 @@ #include #include "drmP.h" -resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource) -{ - return pci_resource_start(dev->pdev, resource); -} -EXPORT_SYMBOL(drm_get_resource_start); - -resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource) -{ - return pci_resource_len(dev->pdev, resource); -} - -EXPORT_SYMBOL(drm_get_resource_len); - static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, struct drm_local_map *map) { diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2a6b5de..9fe2d08 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1429,7 +1429,7 @@ static int i915_load_modeset_init(struct drm_device *dev, int fb_bar = IS_I9XX(dev) ? 2 : 0; int ret = 0; - dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & + dev->mode_config.fb_base = pci_resource_start(dev->pdev, fb_bar) & 0xff000000; /* Basic memrange allocator for stolen space (aka vram) */ @@ -1612,8 +1612,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) /* Add register map (needed for suspend/resume) */ mmio_bar = IS_I9XX(dev) ? 0 : 1; - base = drm_get_resource_start(dev, mmio_bar); - size = drm_get_resource_len(dev, mmio_bar); + base = pci_resource_start(dev->pdev, mmio_bar); + size = pci_resource_len(dev->pdev, mmio_bar); if (i915_get_bridge_dev(dev)) { ret = -EIO; diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c index 3c917fb..ccc129c 100644 --- a/drivers/gpu/drm/mga/mga_dma.c +++ b/drivers/gpu/drm/mga/mga_dma.c @@ -405,8 +405,8 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags) dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; dev_priv->chipset = flags; - dev_priv->mmio_base = drm_get_resource_start(dev, 1); - dev_priv->mmio_size = drm_get_resource_len(dev, 1); + dev_priv->mmio_base = pci_resource_start(dev->pdev, 1); + dev_priv->mmio_size = pci_resource_len(dev->pdev, 1); dev->counters += 3; dev->types[6] = _DRM_STAT_IRQ; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 6f3c195..9f5ab46 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -783,7 +783,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) break; case TTM_PL_VRAM: mem->bus.offset = mem->mm_node->start << PAGE_SHIFT; - mem->bus.base = drm_get_resource_start(dev, 1); + mem->bus.base = pci_resource_start(dev->pdev, 1); mem->bus.is_iomem = true; break; default: diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 1fc57ef..06555c7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -62,7 +62,8 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) * VRAM. */ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - drm_get_resource_start(dev, 1), + pci_resource_start(dev->pdev, + 1), dev_priv->fb_available_size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI, &pushbuf); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 775a701..37c7bf8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -471,8 +471,9 @@ void nouveau_mem_close(struct drm_device *dev) } if (dev_priv->fb_mtrr) { - drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1), - drm_get_resource_len(dev, 1), DRM_MTRR_WC); + drm_mtrr_del(dev_priv->fb_mtrr, + pci_resource_start(dev->pdev, 1), + pci_resource_len(dev->pdev, 1), DRM_MTRR_WC); dev_priv->fb_mtrr = 0; } } @@ -632,7 +633,7 @@ nouveau_mem_init(struct drm_device *dev) struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; int ret, dma_bits = 32; - dev_priv->fb_phys = drm_get_resource_start(dev, 1); + dev_priv->fb_phys = pci_resource_start(dev->pdev, 1); dev_priv->gart_info.type = NOUVEAU_GART_NONE; if (dev_priv->card_type >= NV_50 && @@ -664,8 +665,9 @@ nouveau_mem_init(struct drm_device *dev) dev_priv->fb_available_size = dev_priv->vram_size; dev_priv->fb_mappable_pages = dev_priv->fb_available_size; - if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1)) - dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1); + if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1)) + dev_priv->fb_mappable_pages = + pci_resource_len(dev->pdev, 1); dev_priv->fb_mappable_pages >>= PAGE_SHIFT; /* remove reserved space at end of vram from available amount */ @@ -717,8 +719,8 @@ nouveau_mem_init(struct drm_device *dev) return ret; } - dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1), - drm_get_resource_len(dev, 1), + dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1), + pci_resource_len(dev->pdev, 1), DRM_MTRR_WC); return 0; diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index d6fc0a8..fe2349b 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -616,7 +616,7 @@ nv20_graph_init(struct drm_device *dev) nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp); /* begin RAM config */ - vramsz = drm_get_resource_len(dev, 0) - 1; + vramsz = pci_resource_len(dev->pdev, 0) - 1; nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); @@ -717,7 +717,7 @@ nv30_graph_init(struct drm_device *dev) nv_wr32(dev, 0x0040075c , 0x00000001); /* begin RAM config */ - /* vramsz = drm_get_resource_len(dev, 0) - 1; */ + /* vramsz = pci_resource_len(dev->pdev, 0) - 1; */ nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); if (dev_priv->chipset != 0x34) { diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 704a25d..65b13b5 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -367,7 +367,7 @@ nv40_graph_init(struct drm_device *dev) nv40_graph_set_region_tiling(dev, i, 0, 0, 0); /* begin RAM config */ - vramsz = drm_get_resource_len(dev, 0) - 1; + vramsz = pci_resource_len(dev->pdev, 0) - 1; switch (dev_priv->chipset) { case 0x40: nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 5f21df3..71c01b6 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -241,7 +241,7 @@ nv50_instmem_init(struct drm_device *dev) return ret; BAR0_WI32(priv->fb_bar->gpuobj, 0x00, 0x7fc00000); BAR0_WI32(priv->fb_bar->gpuobj, 0x04, 0x40000000 + - drm_get_resource_len(dev, 1) - 1); + pci_resource_len(dev->pdev, 1) - 1); BAR0_WI32(priv->fb_bar->gpuobj, 0x08, 0x40000000); BAR0_WI32(priv->fb_bar->gpuobj, 0x0c, 0x00000000); BAR0_WI32(priv->fb_bar->gpuobj, 0x10, 0x00000000); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 8c8e4d3..a4745e4 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1300,8 +1300,8 @@ int evergreen_mc_init(struct radeon_device *rdev) } rdev->mc.vram_width = numchan * chansize; /* Could aper size report 0 ? */ - rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); - rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); + rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); + rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); /* Setup GPU memory space */ /* size in MB on evergreen */ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index cc004b0..c485c2c 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2284,8 +2284,8 @@ void r100_vram_init_sizes(struct radeon_device *rdev) u64 config_aper_size; /* work out accessible VRAM */ - rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); - rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); + rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); + rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev); /* FIXME we don't use the second aperture yet when we could use it */ if (rdev->mc.visible_vram_size > rdev->mc.aper_size) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 44e96a2..4959619 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1118,8 +1118,8 @@ int r600_mc_init(struct radeon_device *rdev) } rdev->mc.vram_width = numchan * chansize; /* Could aper size report 0 ? */ - rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); - rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); + rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); + rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); /* Setup GPU memory space */ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index fbba938..91f5b5a 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -49,7 +49,7 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev) resource_size_t size = 256 * 1024; /* ??? */ rdev->bios = NULL; - vram_base = drm_get_resource_start(rdev->ddev, 0); + vram_base = pci_resource_start(rdev->pdev, 0); bios = ioremap(vram_base, size); if (!bios) { return false; diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 2f042a3..eb6b9ee 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c @@ -2120,8 +2120,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) else dev_priv->flags |= RADEON_IS_PCI; - ret = drm_addmap(dev, drm_get_resource_start(dev, 2), - drm_get_resource_len(dev, 2), _DRM_REGISTERS, + ret = drm_addmap(dev, pci_resource_start(dev->pdev, 2), + pci_resource_len(dev->pdev, 2), _DRM_REGISTERS, _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); if (ret != 0) return ret; @@ -2194,9 +2194,9 @@ int radeon_driver_firstopen(struct drm_device *dev) dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); + dev_priv->fb_aper_offset = pci_resource_start(dev->pdev, 0); ret = drm_addmap(dev, dev_priv->fb_aper_offset, - drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, + pci_resource_len(dev->pdev, 0), _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING, &map); if (ret != 0) return ret; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index fdc3fdf..2a897a7 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -648,8 +648,8 @@ int radeon_device_init(struct radeon_device *rdev, /* Registers mapping */ /* TODO: block userspace mapping of io register */ - rdev->rmmio_base = drm_get_resource_start(rdev->ddev, 2); - rdev->rmmio_size = drm_get_resource_len(rdev->ddev, 2); + rdev->rmmio_base = pci_resource_start(rdev->pdev, 2); + rdev->rmmio_size = pci_resource_len(rdev->pdev, 2); rdev->rmmio = ioremap(rdev->rmmio_base, rdev->rmmio_size); if (rdev->rmmio == NULL) { return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 79887ca..340c761 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -685,8 +685,8 @@ void rs600_mc_init(struct radeon_device *rdev) { u64 base; - rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); - rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); + rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); + rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); rdev->mc.vram_is_ddr = true; rdev->mc.vram_width = 128; rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index bcc3319..a18ba98 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -151,8 +151,8 @@ void rs690_mc_init(struct radeon_device *rdev) rdev->mc.vram_width = 128; rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); rdev->mc.mc_vram_size = rdev->mc.real_vram_size; - rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); - rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); + rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); + rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); rdev->mc.visible_vram_size = rdev->mc.aper_size; base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); base = G_000100_MC_FB_START(base) << 16; diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 253f24a..5c7f0b9 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -908,8 +908,8 @@ int rv770_mc_init(struct radeon_device *rdev) } rdev->mc.vram_width = numchan * chansize; /* Could aper size report 0 ? */ - rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); - rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); + rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); + rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); /* Setup GPU memory space */ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index 2d0c9ca..f576232 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c @@ -573,13 +573,13 @@ int savage_driver_firstopen(struct drm_device *dev) dev_priv->mtrr[2].handle = -1; if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { fb_rsrc = 0; - fb_base = drm_get_resource_start(dev, 0); + fb_base = pci_resource_start(dev->pdev, 0); fb_size = SAVAGE_FB_SIZE_S3; mmio_base = fb_base + SAVAGE_FB_SIZE_S3; aper_rsrc = 0; aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; /* this should always be true */ - if (drm_get_resource_len(dev, 0) == 0x08000000) { + if (pci_resource_len(dev->pdev, 0) == 0x08000000) { /* Don't make MMIO write-cobining! We need 3 * MTRRs. */ dev_priv->mtrr[0].base = fb_base; @@ -599,18 +599,19 @@ int savage_driver_firstopen(struct drm_device *dev) dev_priv->mtrr[2].size, DRM_MTRR_WC); } else { DRM_ERROR("strange pci_resource_len %08llx\n", - (unsigned long long)drm_get_resource_len(dev, 0)); + (unsigned long long) + pci_resource_len(dev->pdev, 0)); } } else if (dev_priv->chipset != S3_SUPERSAVAGE && dev_priv->chipset != S3_SAVAGE2000) { - mmio_base = drm_get_resource_start(dev, 0); + mmio_base = pci_resource_start(dev->pdev, 0); fb_rsrc = 1; - fb_base = drm_get_resource_start(dev, 1); + fb_base = pci_resource_start(dev->pdev, 1); fb_size = SAVAGE_FB_SIZE_S4; aper_rsrc = 1; aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; /* this should always be true */ - if (drm_get_resource_len(dev, 1) == 0x08000000) { + if (pci_resource_len(dev->pdev, 1) == 0x08000000) { /* Can use one MTRR to cover both fb and * aperture. */ dev_priv->mtrr[0].base = fb_base; @@ -620,15 +621,16 @@ int savage_driver_firstopen(struct drm_device *dev) dev_priv->mtrr[0].size, DRM_MTRR_WC); } else { DRM_ERROR("strange pci_resource_len %08llx\n", - (unsigned long long)drm_get_resource_len(dev, 1)); + (unsigned long long) + pci_resource_len(dev->pdev, 1)); } } else { - mmio_base = drm_get_resource_start(dev, 0); + mmio_base = pci_resource_start(dev->pdev, 0); fb_rsrc = 1; - fb_base = drm_get_resource_start(dev, 1); - fb_size = drm_get_resource_len(dev, 1); + fb_base = pci_resource_start(dev->pdev, 1); + fb_size = pci_resource_len(dev->pdev, 1); aper_rsrc = 2; - aperture_base = drm_get_resource_start(dev, 2); + aperture_base = pci_resource_start(dev->pdev, 2); /* Automatic MTRR setup will do the right thing. */ } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c1b9871..8f7f5cb 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1273,10 +1273,6 @@ extern int drm_freebufs(struct drm_device *dev, void *data, extern int drm_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_order(unsigned long size); -extern resource_size_t drm_get_resource_start(struct drm_device *dev, - unsigned int resource); -extern resource_size_t drm_get_resource_len(struct drm_device *dev, - unsigned int resource); /* DMA support (drm_dma.h) */ extern int drm_dma_setup(struct drm_device *dev); -- cgit v0.10.2 From dcdb167402cbdca1d021bdfa5f63995ee0a79317 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 27 May 2010 13:40:25 -0600 Subject: drm: Add support for platform devices to register as DRM devices Allow platform devices without PCI resources to be DRM devices. [airlied: fixup warnings with dev pointers] Signed-off-by: Jordan Crouse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 88910e5..520ab23 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -6,7 +6,7 @@ # menuconfig DRM tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" - depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU + depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU select I2C select I2C_ALGOBIT select SLOW_WORK @@ -17,7 +17,7 @@ menuconfig DRM These modules provide support for synchronization, security, and DMA transfers. Please see for more details. You should also select and configure AGP - (/dev/agpgart) support. + (/dev/agpgart) support if it is available for your platform. config DRM_KMS_HELPER tristate diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index abe3f44..b4b2b48 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -9,7 +9,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ - drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ + drm_platform.o drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ drm_crtc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 4a66201..510bc87 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -243,47 +243,20 @@ int drm_lastclose(struct drm_device * dev) * * Initializes an array of drm_device structures, and attempts to * initialize all available devices, using consecutive minors, registering the - * stubs and initializing the AGP device. + * stubs and initializing the device. * * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and * after the initialization for driver customization. */ int drm_init(struct drm_driver *driver) { - struct pci_dev *pdev = NULL; - const struct pci_device_id *pid; - int i; - DRM_DEBUG("\n"); - INIT_LIST_HEAD(&driver->device_list); - if (driver->driver_features & DRIVER_MODESET) - return pci_register_driver(&driver->pci_driver); - - /* If not using KMS, fall back to stealth mode manual scanning. */ - for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { - pid = &driver->pci_driver.id_table[i]; - - /* Loop around setting up a DRM device for each PCI device - * matching our ID and device class. If we had the internal - * function that pci_get_subsys and pci_get_class used, we'd - * be able to just pass pid in instead of doing a two-stage - * thing. - */ - pdev = NULL; - while ((pdev = - pci_get_subsys(pid->vendor, pid->device, pid->subvendor, - pid->subdevice, pdev)) != NULL) { - if ((pdev->class & pid->class_mask) != pid->class) - continue; - - /* stealth mode requires a manual probe */ - pci_dev_get(pdev); - drm_get_dev(pdev, pid, driver); - } - } - return 0; + if (driver->driver_features & DRIVER_USE_PLATFORM_DEVICE) + return drm_platform_init(driver); + else + return drm_pci_init(driver); } EXPORT_SYMBOL(drm_init); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c198186..83d8072 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -282,7 +282,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) return block; carp: - dev_warn(&connector->dev->pdev->dev, "%s: EDID block %d invalid.\n", + dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n", drm_get_connector_name(connector), j); out: @@ -1626,7 +1626,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) return 0; } if (!drm_edid_is_valid(edid)) { - dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n", + dev_warn(connector->dev->dev, "%s: EDID invalid.\n", drm_get_connector_name(connector)); return 0; } diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index f0f6c6b..2ef2c78 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c @@ -51,13 +51,24 @@ int drm_name_info(struct seq_file *m, void *data) if (!master) return 0; - if (master->unique) { - seq_printf(m, "%s %s %s\n", - dev->driver->pci_driver.name, - pci_name(dev->pdev), master->unique); + if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) { + if (master->unique) { + seq_printf(m, "%s %s %s\n", + dev->driver->platform_device->name, + dev_name(dev->dev), master->unique); + } else { + seq_printf(m, "%s\n", + dev->driver->platform_device->name); + } } else { - seq_printf(m, "%s %s\n", dev->driver->pci_driver.name, - pci_name(dev->pdev)); + if (master->unique) { + seq_printf(m, "%s %s %s\n", + dev->driver->pci_driver.name, + dev_name(dev->dev), master->unique); + } else { + seq_printf(m, "%s %s\n", dev->driver->pci_driver.name, + dev_name(dev->dev)); + } } return 0; diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 9b9ff46..76d3d18 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -132,32 +132,57 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) struct drm_master *master = file_priv->master; int len; - if (master->unique != NULL) - return -EBUSY; - - master->unique_len = 40; - master->unique_size = master->unique_len; - master->unique = kmalloc(master->unique_size, GFP_KERNEL); - if (master->unique == NULL) - return -ENOMEM; + if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) { + master->unique_len = 10 + strlen(dev->platformdev->name); + master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL); + + if (master->unique == NULL) + return -ENOMEM; + + len = snprintf(master->unique, master->unique_len, + "platform:%s", dev->platformdev->name); + + if (len > master->unique_len) + DRM_ERROR("Unique buffer overflowed\n"); + + dev->devname = + kmalloc(strlen(dev->platformdev->name) + + master->unique_len + 2, GFP_KERNEL); + + if (dev->devname == NULL) + return -ENOMEM; + + sprintf(dev->devname, "%s@%s", dev->platformdev->name, + master->unique); + + } else { + master->unique_len = 40; + master->unique_size = master->unique_len; + master->unique = kmalloc(master->unique_size, GFP_KERNEL); + if (master->unique == NULL) + return -ENOMEM; + + len = snprintf(master->unique, master->unique_len, + "pci:%04x:%02x:%02x.%d", + drm_get_pci_domain(dev), + dev->pdev->bus->number, + PCI_SLOT(dev->pdev->devfn), + PCI_FUNC(dev->pdev->devfn)); + if (len >= master->unique_len) + DRM_ERROR("buffer overflow"); + else + master->unique_len = len; - len = snprintf(master->unique, master->unique_len, "pci:%04x:%02x:%02x.%d", - drm_get_pci_domain(dev), - dev->pdev->bus->number, - PCI_SLOT(dev->pdev->devfn), - PCI_FUNC(dev->pdev->devfn)); - if (len >= master->unique_len) - DRM_ERROR("buffer overflow"); - else - master->unique_len = len; + dev->devname = + kmalloc(strlen(dev->driver->pci_driver.name) + + master->unique_len + 2, GFP_KERNEL); - dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) + - master->unique_len + 2, GFP_KERNEL); - if (dev->devname == NULL) - return -ENOMEM; + if (dev->devname == NULL) + return -ENOMEM; - sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, - master->unique); + sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, + master->unique); + } return 0; } diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index a263b70..6353b62 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -57,6 +57,9 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, { struct drm_irq_busid *p = data; + if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) + return -EINVAL; + if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return -EINVAL; @@ -211,7 +214,7 @@ int drm_irq_install(struct drm_device *dev) if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return -EINVAL; - if (dev->pdev->irq == 0) + if (drm_dev_to_irq(dev) == 0) return -EINVAL; mutex_lock(&dev->struct_mutex); @@ -229,7 +232,7 @@ int drm_irq_install(struct drm_device *dev) dev->irq_enabled = 1; mutex_unlock(&dev->struct_mutex); - DRM_DEBUG("irq=%d\n", dev->pdev->irq); + DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); /* Before installing handler */ dev->driver->irq_preinstall(dev); @@ -302,14 +305,14 @@ int drm_irq_uninstall(struct drm_device * dev) if (!irq_enabled) return -EINVAL; - DRM_DEBUG("irq=%d\n", dev->pdev->irq); + DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); if (!drm_core_check_feature(dev, DRIVER_MODESET)) vga_client_register(dev->pdev, NULL, NULL, NULL); dev->driver->irq_uninstall(dev); - free_irq(dev->pdev->irq, dev); + free_irq(drm_dev_to_irq(dev), dev); return 0; } @@ -341,7 +344,7 @@ int drm_control(struct drm_device *dev, void *data, if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0; if (dev->if_version < DRM_IF_VERSION(1, 2) && - ctl->irq != dev->pdev->irq) + ctl->irq != drm_dev_to_irq(dev)) return -EINVAL; return drm_irq_install(dev); case DRM_UNINST_HANDLER: @@ -651,7 +654,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, int ret = 0; unsigned int flags, seq, crtc; - if ((!dev->pdev->irq) || (!dev->irq_enabled)) + if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled)) return -EINVAL; if (vblwait->request.type & _DRM_VBLANK_SIGNAL) diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 2ea9ad4..e20f78b 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -124,4 +124,147 @@ void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah) EXPORT_SYMBOL(drm_pci_free); +#ifdef CONFIG_PCI +/** + * Register. + * + * \param pdev - PCI device structure + * \param ent entry from the PCI ID table with device type flags + * \return zero on success or a negative number on failure. + * + * Attempt to gets inter module "drm" information. If we are first + * then register the character device and inter module information. + * Try and register, if we fail to register, backout previous work. + */ +int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, + struct drm_driver *driver) +{ + struct drm_device *dev; + int ret; + + DRM_DEBUG("\n"); + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + ret = pci_enable_device(pdev); + if (ret) + goto err_g1; + + pci_set_master(pdev); + + dev->pdev = pdev; + dev->dev = &pdev->dev; + + dev->pci_device = pdev->device; + dev->pci_vendor = pdev->vendor; + +#ifdef __alpha__ + dev->hose = pdev->sysdata; +#endif + + if ((ret = drm_fill_in_dev(dev, ent, driver))) { + printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); + goto err_g2; + } + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + pci_set_drvdata(pdev, dev); + ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); + if (ret) + goto err_g2; + } + + if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) + goto err_g3; + + if (dev->driver->load) { + ret = dev->driver->load(dev, ent->driver_data); + if (ret) + goto err_g4; + } + + /* setup the grouping for the legacy output */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_mode_group_init_legacy_group(dev, + &dev->primary->mode_group); + if (ret) + goto err_g4; + } + + list_add_tail(&dev->driver_item, &driver->device_list); + + DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", + driver->name, driver->major, driver->minor, driver->patchlevel, + driver->date, pci_name(pdev), dev->primary->index); + + return 0; + +err_g4: + drm_put_minor(&dev->primary); +err_g3: + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_put_minor(&dev->control); +err_g2: + pci_disable_device(pdev); +err_g1: + kfree(dev); + return ret; +} +EXPORT_SYMBOL(drm_get_pci_dev); + +/** + * PCI device initialization. Called via drm_init at module load time, + * + * \return zero on success or a negative number on failure. + * + * Initializes a drm_device structures,registering the + * stubs and initializing the AGP device. + * + * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and + * after the initialization for driver customization. + */ +int drm_pci_init(struct drm_driver *driver) +{ + struct pci_dev *pdev = NULL; + const struct pci_device_id *pid; + int i; + + if (driver->driver_features & DRIVER_MODESET) + return pci_register_driver(&driver->pci_driver); + + /* If not using KMS, fall back to stealth mode manual scanning. */ + for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { + pid = &driver->pci_driver.id_table[i]; + + /* Loop around setting up a DRM device for each PCI device + * matching our ID and device class. If we had the internal + * function that pci_get_subsys and pci_get_class used, we'd + * be able to just pass pid in instead of doing a two-stage + * thing. + */ + pdev = NULL; + while ((pdev = + pci_get_subsys(pid->vendor, pid->device, pid->subvendor, + pid->subdevice, pdev)) != NULL) { + if ((pdev->class & pid->class_mask) != pid->class) + continue; + + /* stealth mode requires a manual probe */ + pci_dev_get(pdev); + drm_get_pci_dev(pdev, pid, driver); + } + } + return 0; +} + +#else + +int drm_pci_init(struct drm_driver *driver) +{ + return -1; +} + +#endif /*@}*/ diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c new file mode 100644 index 0000000..460e9a3 --- /dev/null +++ b/drivers/gpu/drm/drm_platform.c @@ -0,0 +1,122 @@ +/* + * Derived from drm_pci.c + * + * Copyright 2003 José Fonseca. + * Copyright 2003 Leif Delgass. + * Copyright (c) 2009, Code Aurora Forum. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "drmP.h" + +/** + * Register. + * + * \param platdev - Platform device struture + * \return zero on success or a negative number on failure. + * + * Attempt to gets inter module "drm" information. If we are first + * then register the character device and inter module information. + * Try and register, if we fail to register, backout previous work. + */ + +int drm_get_platform_dev(struct platform_device *platdev, + struct drm_driver *driver) +{ + struct drm_device *dev; + int ret; + + DRM_DEBUG("\n"); + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->platformdev = platdev; + dev->dev = &platdev->dev; + + ret = drm_fill_in_dev(dev, NULL, driver); + + if (ret) { + printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); + goto err_g1; + } + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + dev_set_drvdata(&platdev->dev, dev); + ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); + if (ret) + goto err_g1; + } + + ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); + if (ret) + goto err_g2; + + if (dev->driver->load) { + ret = dev->driver->load(dev, 0); + if (ret) + goto err_g3; + } + + /* setup the grouping for the legacy output */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_mode_group_init_legacy_group(dev, + &dev->primary->mode_group); + if (ret) + goto err_g3; + } + + list_add_tail(&dev->driver_item, &driver->device_list); + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", + driver->name, driver->major, driver->minor, driver->patchlevel, + driver->date, dev->primary->index); + + return 0; + +err_g3: + drm_put_minor(&dev->primary); +err_g2: + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_put_minor(&dev->control); +err_g1: + kfree(dev); + return ret; +} +EXPORT_SYMBOL(drm_get_platform_dev); + +/** + * Platform device initialization. Called via drm_init at module load time, + * + * \return zero on success or a negative number on failure. + * + * Initializes a drm_device structures,registering the + * stubs + * + * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and + * after the initialization for driver customization. + */ + +int drm_platform_init(struct drm_driver *driver) +{ + return drm_get_platform_dev(driver->platform_device, driver); +} diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index a0c365f..63575e2 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -224,7 +224,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, return 0; } -static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, +int drm_fill_in_dev(struct drm_device *dev, const struct pci_device_id *ent, struct drm_driver *driver) { @@ -245,14 +245,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, idr_init(&dev->drw_idr); - dev->pdev = pdev; - dev->pci_device = pdev->device; - dev->pci_vendor = pdev->vendor; - -#ifdef __alpha__ - dev->hose = pdev->sysdata; -#endif - if (drm_ht_create(&dev->map_hash, 12)) { return -ENOMEM; } @@ -321,7 +313,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, * create the proc init entry via proc_init(). This routines assigns * minor numbers to secondary heads of multi-headed cards */ -static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) +int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) { struct drm_minor *new_minor; int ret; @@ -388,83 +380,6 @@ err_idr: } /** - * Register. - * - * \param pdev - PCI device structure - * \param ent entry from the PCI ID table with device type flags - * \return zero on success or a negative number on failure. - * - * Attempt to gets inter module "drm" information. If we are first - * then register the character device and inter module information. - * Try and register, if we fail to register, backout previous work. - */ -int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, - struct drm_driver *driver) -{ - struct drm_device *dev; - int ret; - - DRM_DEBUG("\n"); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - ret = pci_enable_device(pdev); - if (ret) - goto err_g1; - - pci_set_master(pdev); - if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { - printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); - goto err_g2; - } - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - pci_set_drvdata(pdev, dev); - ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); - if (ret) - goto err_g2; - } - - if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) - goto err_g3; - - if (dev->driver->load) { - ret = dev->driver->load(dev, ent->driver_data); - if (ret) - goto err_g4; - } - - /* setup the grouping for the legacy output */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group); - if (ret) - goto err_g4; - } - - list_add_tail(&dev->driver_item, &driver->device_list); - - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, pci_name(pdev), dev->primary->index); - - return 0; - -err_g4: - drm_put_minor(&dev->primary); -err_g3: - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(&dev->control); -err_g2: - pci_disable_device(pdev); -err_g1: - kfree(dev); - return ret; -} -EXPORT_SYMBOL(drm_get_dev); - -/** * Put a secondary minor number. * * \param sec_minor - structure to be released diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 3a3a451..14d9d82 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -488,7 +488,8 @@ int drm_sysfs_device_add(struct drm_minor *minor) int err; char *minor_str; - minor->kdev.parent = &minor->dev->pdev->dev; + minor->kdev.parent = minor->dev->dev; + minor->kdev.class = drm_class; minor->kdev.release = drm_sysfs_device_release; minor->kdev.devt = minor->device; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9fe2d08..9bed561 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -34,6 +34,7 @@ #include "i915_drm.h" #include "i915_drv.h" #include "i915_trace.h" +#include #include #include #include diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5c51e45..b7aecf5 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -435,7 +435,7 @@ int i965_reset(struct drm_device *dev, u8 flags) static int __devinit i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - return drm_get_dev(pdev, ent, &driver); + return drm_get_pci_dev(pdev, ent, &driver); } static void diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index c6079e3..f60a2b2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -132,7 +132,7 @@ static struct drm_driver driver; static int __devinit nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - return drm_get_dev(pdev, ent, &driver); + return drm_get_pci_dev(pdev, ent, &driver); } static void diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4afba1e..683e281 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -236,7 +236,7 @@ static struct drm_driver kms_driver; static int __devinit radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - return drm_get_dev(pdev, ent, &kms_driver); + return drm_get_pci_dev(pdev, ent, &kms_driver); } static void diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 0c9c081..f7f248d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -758,7 +758,7 @@ static struct drm_driver driver = { static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - return drm_get_dev(pdev, ent, &driver); + return drm_get_pci_dev(pdev, ent, &driver); } static int __init vmwgfx_init(void) diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 8f7f5cb..6235169 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -9,6 +9,7 @@ /* * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * Copyright (c) 2009-2010, Code Aurora Forum. * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -48,6 +49,7 @@ #include #include #include +#include #include #include #include /* For (un)lock_kernel */ @@ -144,6 +146,7 @@ extern void drm_ut_debug_printk(unsigned int request_level, #define DRIVER_IRQ_VBL2 0x800 #define DRIVER_GEM 0x1000 #define DRIVER_MODESET 0x2000 +#define DRIVER_USE_PLATFORM_DEVICE 0x4000 /***********************************************************************/ /** \name Begin the DRM... */ @@ -823,6 +826,7 @@ struct drm_driver { int num_ioctls; struct file_operations fops; struct pci_driver pci_driver; + struct platform_device *platform_device; /* List of devices hanging off this driver */ struct list_head device_list; }; @@ -1015,12 +1019,16 @@ struct drm_device { struct drm_agp_head *agp; /**< AGP data */ + struct device *dev; /**< Device structure */ struct pci_dev *pdev; /**< PCI device structure */ int pci_vendor; /**< PCI vendor id */ int pci_device; /**< PCI device id */ #ifdef __alpha__ struct pci_controller *hose; #endif + + struct platform_device *platformdev; /**< Platform device struture */ + struct drm_sg_mem *sg; /**< Scatter gather memory */ int num_crtcs; /**< Number of CRTCs on this device */ void *dev_private; /**< device private data */ @@ -1060,17 +1068,21 @@ struct drm_device { }; -static inline int drm_dev_to_irq(struct drm_device *dev) -{ - return dev->pdev->irq; -} - static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature) { return ((dev->driver->driver_features & feature) ? 1 : 0); } + +static inline int drm_dev_to_irq(struct drm_device *dev) +{ + if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) + return platform_get_irq(dev->platformdev, 0); + else + return dev->pdev->irq; +} + #ifdef __alpha__ #define drm_get_pci_domain(dev) dev->hose->index #else @@ -1347,8 +1359,11 @@ extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data, struct drm_master *drm_master_create(struct drm_minor *minor); extern struct drm_master *drm_master_get(struct drm_master *master); extern void drm_master_put(struct drm_master **master); -extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, - struct drm_driver *driver); +extern int drm_get_pci_dev(struct pci_dev *pdev, + const struct pci_device_id *ent, + struct drm_driver *driver); +extern int drm_get_platform_dev(struct platform_device *pdev, + struct drm_driver *driver); extern void drm_put_dev(struct drm_device *dev); extern int drm_put_minor(struct drm_minor **minor); extern unsigned int drm_debug; @@ -1525,6 +1540,9 @@ static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev, static __inline__ int drm_device_is_agp(struct drm_device *dev) { + if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) + return 0; + if (dev->driver->device_is_agp != NULL) { int err = (*dev->driver->device_is_agp) (dev); @@ -1538,7 +1556,10 @@ static __inline__ int drm_device_is_agp(struct drm_device *dev) static __inline__ int drm_device_is_pcie(struct drm_device *dev) { - return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); + if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) + return 0; + else + return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); } static __inline__ void drm_core_dropmap(struct drm_local_map *map) @@ -1546,6 +1567,21 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map) } #include "drm_mem_util.h" + +static inline void *drm_get_device(struct drm_device *dev) +{ + if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) + return dev->platformdev; + else + return dev->pdev; +} + +extern int drm_platform_init(struct drm_driver *driver); +extern int drm_pci_init(struct drm_driver *driver); +extern int drm_fill_in_dev(struct drm_device *dev, + const struct pci_device_id *ent, + struct drm_driver *driver); +int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type); /*@}*/ #endif /* __KERNEL__ */ -- cgit v0.10.2 From 4b7fb9b5746554d460e7bc986341d4b2db01e0b6 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 27 May 2010 13:40:26 -0600 Subject: drm: Add __arm defines to DRM Add __arm defines to specify behavior specific for an ARM processor. Signed-off-by: Jordan Crouse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 7783035..4fcbc44 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -176,7 +176,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, switch (map->type) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: -#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) +#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__) if (map->offset + (map->size-1) < map->offset || map->offset < virt_to_phys(high_memory)) { kfree(map); diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index c3b13fb..3778360 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -61,7 +61,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) tmp = pgprot_writecombine(tmp); else tmp = pgprot_noncached(tmp); -#elif defined(__sparc__) +#elif defined(__sparc__) || defined(__arm__) tmp = pgprot_noncached(tmp); #endif return tmp; @@ -601,6 +601,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) } switch (map->type) { +#if !defined(__arm__) case _DRM_AGP: if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) { /* @@ -615,20 +616,31 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) break; } /* fall through to _DRM_FRAME_BUFFER... */ +#endif case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: offset = dev->driver->get_reg_ofs(dev); vma->vm_flags |= VM_IO; /* not in core dump */ vma->vm_page_prot = drm_io_prot(map->type, vma); +#if !defined(__arm__) if (io_remap_pfn_range(vma, vma->vm_start, (map->offset + offset) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; +#else + if (remap_pfn_range(vma, vma->vm_start, + (map->offset + offset) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) + return -EAGAIN; +#endif + DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," " offset = 0x%llx\n", map->type, vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset)); + vma->vm_ops = &drm_vm_ops; break; case _DRM_CONSISTENT: -- cgit v0.10.2 From 05269a3a5a78bb074413de495105d7a2686c4529 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 27 May 2010 13:40:27 -0600 Subject: drm: Make sure the DRM offset matches the CPU The pgoff option in mmap() is defined as an unsigned long so the offset generated by DRM needs to fit into BITS_PER_LONG for the CPU in question. Signed-off-by: Jordan Crouse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 33dad3f..8601b72 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -68,8 +68,18 @@ * We make up offsets for buffer objects so we can recognize them at * mmap time. */ + +/* pgoff in mmap is an unsigned long, so we need to make sure that + * the faked up offset will fit + */ + +#if BITS_PER_LONG == 64 #define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1) #define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16) +#else +#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFUL >> PAGE_SHIFT) + 1) +#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFUL >> PAGE_SHIFT) * 16) +#endif /** * Initialize the GEM device fields -- cgit v0.10.2 From ac2874b980e05ed7a4ea8fed7b0a92428b51ce58 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 1 Jul 2010 16:47:31 -0700 Subject: drm: add vblank event trace point Emit a trace point for vblank events. This can be helpful for mapping drawing activity against the vblank frequency and period. Signed-off-by: Jesse Barnes Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index abe3f44..3b02e04 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -11,7 +11,8 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ drm_crtc.o drm_modes.o drm_edid.o \ - drm_info.o drm_debugfs.o drm_encoder_slave.o + drm_info.o drm_debugfs.o drm_encoder_slave.o \ + drm_trace_points.o drm-$(CONFIG_COMPAT) += drm_ioc32.o @@ -19,6 +20,8 @@ drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o +CFLAGS_drm_trace_points.o := -I$(src) + obj-$(CONFIG_DRM) += drm.o obj-$(CONFIG_DRM_TTM) += ttm/ obj-$(CONFIG_DRM_TDFX) += tdfx/ diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index a263b70..6d201a8 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -34,6 +34,7 @@ */ #include "drmP.h" +#include "drm_trace.h" #include /* For task queue support */ #include @@ -754,6 +755,8 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc) } spin_unlock_irqrestore(&dev->event_lock, flags); + + trace_drm_vblank_event(crtc, seq); } /** diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h new file mode 100644 index 0000000..8a92683 --- /dev/null +++ b/drivers/gpu/drm/drm_trace.h @@ -0,0 +1,37 @@ +#if !defined(_DRM_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _DRM_TRACE_H_ + +#include +#include +#include + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM drm +#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) +#define TRACE_INCLUDE_FILE drm_trace + +TRACE_EVENT(drm_vblank_event, + + TP_PROTO(int crtc, unsigned int seq), + + TP_ARGS(crtc, seq), + + TP_STRUCT__entry( + __field(int, crtc) + __field(unsigned int, seq) + ), + + TP_fast_assign( + __entry->crtc = crtc; + __entry->seq = seq; + ), + + TP_printk("crtc=%d, seq=%d", __entry->crtc, __entry->seq) +); + +#endif /* _DRM_TRACE_H_ */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#include diff --git a/drivers/gpu/drm/drm_trace_points.c b/drivers/gpu/drm/drm_trace_points.c new file mode 100644 index 0000000..0d0eb90 --- /dev/null +++ b/drivers/gpu/drm/drm_trace_points.c @@ -0,0 +1,4 @@ +#include "drmP.h" + +#define CREATE_TRACE_POINTS +#include "drm_trace.h" -- cgit v0.10.2 From b9c2c9ae882f058084e13e339925dbf8d2d20271 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 1 Jul 2010 16:48:09 -0700 Subject: drm: add per-event vblank event trace points Allows us to track each process that requests and completes events. Signed-off-by: Jesse Barnes Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 6d201a8..c2ecb3e 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -588,6 +588,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, return -ENOMEM; e->pipe = pipe; + e->base.pid = current->pid; e->event.base.type = DRM_EVENT_VBLANK; e->event.base.length = sizeof e->event; e->event.user_data = vblwait->request.signal; @@ -615,6 +616,9 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", vblwait->request.sequence, seq, pipe); + trace_drm_vblank_event_queued(current->pid, pipe, + vblwait->request.sequence); + e->event.sequence = vblwait->request.sequence; if ((seq - vblwait->request.sequence) <= (1 << 23)) { e->event.tv_sec = now.tv_sec; @@ -622,6 +626,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, drm_vblank_put(dev, e->pipe); list_add_tail(&e->base.link, &e->base.file_priv->event_list); wake_up_interruptible(&e->base.file_priv->event_wait); + trace_drm_vblank_event_delivered(current->pid, pipe, + vblwait->request.sequence); } else { list_add_tail(&e->base.link, &dev->vblank_event_list); } @@ -752,6 +758,8 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc) drm_vblank_put(dev, e->pipe); list_move_tail(&e->base.link, &e->base.file_priv->event_list); wake_up_interruptible(&e->base.file_priv->event_wait); + trace_drm_vblank_event_delivered(e->base.pid, e->pipe, + e->event.sequence); } spin_unlock_irqrestore(&dev->event_lock, flags); diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h index 8a92683..03ea964 100644 --- a/drivers/gpu/drm/drm_trace.h +++ b/drivers/gpu/drm/drm_trace.h @@ -11,22 +11,51 @@ #define TRACE_INCLUDE_FILE drm_trace TRACE_EVENT(drm_vblank_event, + TP_PROTO(int crtc, unsigned int seq), + TP_ARGS(crtc, seq), + TP_STRUCT__entry( + __field(int, crtc) + __field(unsigned int, seq) + ), + TP_fast_assign( + __entry->crtc = crtc; + __entry->seq = seq; + ), + TP_printk("crtc=%d, seq=%d", __entry->crtc, __entry->seq) +); - TP_PROTO(int crtc, unsigned int seq), - - TP_ARGS(crtc, seq), - - TP_STRUCT__entry( - __field(int, crtc) - __field(unsigned int, seq) - ), - - TP_fast_assign( - __entry->crtc = crtc; - __entry->seq = seq; - ), +TRACE_EVENT(drm_vblank_event_queued, + TP_PROTO(pid_t pid, int crtc, unsigned int seq), + TP_ARGS(pid, crtc, seq), + TP_STRUCT__entry( + __field(pid_t, pid) + __field(int, crtc) + __field(unsigned int, seq) + ), + TP_fast_assign( + __entry->pid = pid; + __entry->crtc = crtc; + __entry->seq = seq; + ), + TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \ + __entry->seq) +); - TP_printk("crtc=%d, seq=%d", __entry->crtc, __entry->seq) +TRACE_EVENT(drm_vblank_event_delivered, + TP_PROTO(pid_t pid, int crtc, unsigned int seq), + TP_ARGS(pid, crtc, seq), + TP_STRUCT__entry( + __field(pid_t, pid) + __field(int, crtc) + __field(unsigned int, seq) + ), + TP_fast_assign( + __entry->pid = pid; + __entry->crtc = crtc; + __entry->seq = seq; + ), + TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \ + __entry->seq) ); #endif /* _DRM_TRACE_H_ */ diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c1b9871..8364a70 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -403,6 +403,8 @@ struct drm_pending_event { struct drm_event *event; struct list_head link; struct drm_file *file_priv; + pid_t pid; /* pid of requester, no guarantee it's valid by the time + we deliver the event, for tracing only */ void (*destroy)(struct drm_pending_event *event); }; -- cgit v0.10.2 From e5510fac98a706c424034950f55bb5e819c46f51 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 1 Jul 2010 16:48:37 -0700 Subject: drm/i915: add tracepoints for flip requests & completions Signed-off-by: Jesse Barnes Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index fab2176..fea97a2 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -262,6 +262,42 @@ DEFINE_EVENT(i915_ring, i915_ring_wait_end, TP_ARGS(dev) ); +TRACE_EVENT(i915_flip_request, + TP_PROTO(int plane, struct drm_gem_object *obj), + + TP_ARGS(plane, obj), + + TP_STRUCT__entry( + __field(int, plane) + __field(struct drm_gem_object *, obj) + ), + + TP_fast_assign( + __entry->plane = plane; + __entry->obj = obj; + ), + + TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) +); + +TRACE_EVENT(i915_flip_complete, + TP_PROTO(int plane, struct drm_gem_object *obj), + + TP_ARGS(plane, obj), + + TP_STRUCT__entry( + __field(int, plane) + __field(struct drm_gem_object *, obj) + ), + + TP_fast_assign( + __entry->plane = plane; + __entry->obj = obj; + ), + + TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) +); + #endif /* _I915_TRACE_H_ */ /* This part must be outside protection */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 68dcf36..f879589 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -33,6 +33,7 @@ #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" +#include "i915_trace.h" #include "drm_dp_helper.h" #include "drm_crtc_helper.h" @@ -4650,6 +4651,8 @@ static void do_intel_finish_page_flip(struct drm_device *dev, atomic_dec_and_test(&obj_priv->pending_flip)) DRM_WAKEUP(&dev_priv->pending_flip_queue); schedule_work(&work->work); + + trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); } void intel_finish_page_flip(struct drm_device *dev, int pipe) @@ -4781,6 +4784,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, mutex_unlock(&dev->struct_mutex); + trace_i915_flip_request(intel_crtc->plane, obj); + return 0; } -- cgit v0.10.2 From 26f3751eb47c757c656333e74bdceccd8d286d76 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 2 Jul 2010 15:02:11 +0100 Subject: drm: use list_for_each_entry in drm_mm.c Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson Acked-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 2ac074c8..b75eb55 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -332,7 +332,6 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, unsigned alignment, int best_match) { - struct list_head *list; const struct list_head *free_stack = &mm->fl_entry; struct drm_mm_node *entry; struct drm_mm_node *best; @@ -342,8 +341,7 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, best = NULL; best_size = ~0UL; - list_for_each(list, free_stack) { - entry = list_entry(list, struct drm_mm_node, fl_entry); + list_for_each_entry(entry, free_stack, fl_entry) { wasted = 0; if (entry->size < size) @@ -376,7 +374,6 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, unsigned long end, int best_match) { - struct list_head *list; const struct list_head *free_stack = &mm->fl_entry; struct drm_mm_node *entry; struct drm_mm_node *best; @@ -386,8 +383,7 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, best = NULL; best_size = ~0UL; - list_for_each(list, free_stack) { - entry = list_entry(list, struct drm_mm_node, fl_entry); + list_for_each_entry(entry, free_stack, fl_entry) { wasted = 0; if (entry->size < size) -- cgit v0.10.2 From db3307a9f7b8078c654021e3b35354a2b09a8e67 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 2 Jul 2010 15:02:12 +0100 Subject: drm: kill drm_mm_node->private Only ever assigned, never used. Signed-off-by: Daniel Vetter [glisse: I will re-add if needed for range-restricted allocations] Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0743858..75061b3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2633,10 +2633,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) if (free_space != NULL) { obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, alignment); - if (obj_priv->gtt_space != NULL) { - obj_priv->gtt_space->private = obj; + if (obj_priv->gtt_space != NULL) obj_priv->gtt_offset = obj_priv->gtt_space->start; - } } if (obj_priv->gtt_space == NULL) { /* If the gtt is empty and we're still having trouble diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 555ebb1..9763288 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -476,7 +476,6 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) ++put_count; } if (bo->mem.mm_node) { - bo->mem.mm_node->private = NULL; drm_mm_put_block(bo->mem.mm_node); bo->mem.mm_node = NULL; } @@ -670,7 +669,6 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, printk(KERN_ERR TTM_PFX "Buffer eviction failed\n"); spin_lock(&glob->lru_lock); if (evict_mem.mm_node) { - evict_mem.mm_node->private = NULL; drm_mm_put_block(evict_mem.mm_node); evict_mem.mm_node = NULL; } @@ -929,8 +927,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, mem->mm_node = node; mem->mem_type = mem_type; mem->placement = cur_flags; - if (node) - node->private = bo; return 0; } @@ -973,7 +969,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, interruptible, no_wait_reserve, no_wait_gpu); if (ret == 0 && mem->mm_node) { mem->placement = cur_flags; - mem->mm_node->private = bo; return 0; } if (ret == -ERESTARTSYS) @@ -1029,7 +1024,6 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, out_unlock: if (ret && mem.mm_node) { spin_lock(&glob->lru_lock); - mem.mm_node->private = NULL; drm_mm_put_block(mem.mm_node); spin_unlock(&glob->lru_lock); } diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 13012a1..7cffb3e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -353,8 +353,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, fbo->vm_node = NULL; fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); - if (fbo->mem.mm_node) - fbo->mem.mm_node->private = (void *)fbo; kref_init(&fbo->list_kref); kref_init(&fbo->kref); fbo->destroy = &ttm_transfered_destroy; diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 4c10be3..da94071 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -48,7 +48,6 @@ struct drm_mm_node { unsigned long start; unsigned long size; struct drm_mm *mm; - void *private; }; struct drm_mm { -- cgit v0.10.2 From ca31efa89ae16c66966b8d5a5df3ae5cbffa61de Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 2 Jul 2010 15:02:13 +0100 Subject: drm: kill dead code in drm_mm.c Signed-off-by: Daniel Vetter Acked-by: Thomas Hellstrom Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index b75eb55..a5a7a16 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -48,36 +48,6 @@ #define MM_UNUSED_TARGET 4 -unsigned long drm_mm_tail_space(struct drm_mm *mm) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry->free) - return 0; - - return entry->size; -} - -int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry->free) - return -ENOMEM; - - if (entry->size <= size) - return -ENOMEM; - - entry->size -= size; - return 0; -} - static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) { struct drm_mm_node *child; @@ -152,21 +122,6 @@ static int drm_mm_create_tail_node(struct drm_mm *mm, return 0; } -int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size, int atomic) -{ - struct list_head *tail_node; - struct drm_mm_node *entry; - - tail_node = mm->ml_entry.prev; - entry = list_entry(tail_node, struct drm_mm_node, ml_entry); - if (!entry->free) { - return drm_mm_create_tail_node(mm, entry->start + entry->size, - size, atomic); - } - entry->size += size; - return 0; -} - static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, unsigned long size, int atomic) -- cgit v0.10.2 From d1024ce91ff4c2c4ccbf692d204c71cbf215157a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 2 Jul 2010 15:02:14 +0100 Subject: drm: sane naming for drm_mm.c Yeah, I've kinda noticed that fl_entry is the free stack. Still give it (and the memory node list ml_entry) decent names. Signed-off-by: Daniel Vetter Acked-by: Thomas Hellstrom Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index a5a7a16..d2267ff 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -64,8 +64,8 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) else { child = list_entry(mm->unused_nodes.next, - struct drm_mm_node, fl_entry); - list_del(&child->fl_entry); + struct drm_mm_node, free_stack); + list_del(&child->free_stack); --mm->num_unused; } spin_unlock(&mm->unused_lock); @@ -94,7 +94,7 @@ int drm_mm_pre_get(struct drm_mm *mm) return ret; } ++mm->num_unused; - list_add_tail(&node->fl_entry, &mm->unused_nodes); + list_add_tail(&node->free_stack, &mm->unused_nodes); } spin_unlock(&mm->unused_lock); return 0; @@ -116,8 +116,8 @@ static int drm_mm_create_tail_node(struct drm_mm *mm, child->start = start; child->mm = mm; - list_add_tail(&child->ml_entry, &mm->ml_entry); - list_add_tail(&child->fl_entry, &mm->fl_entry); + list_add_tail(&child->node_list, &mm->node_list); + list_add_tail(&child->free_stack, &mm->free_stack); return 0; } @@ -132,15 +132,15 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, if (unlikely(child == NULL)) return NULL; - INIT_LIST_HEAD(&child->fl_entry); + INIT_LIST_HEAD(&child->free_stack); child->free = 0; child->size = size; child->start = parent->start; child->mm = parent->mm; - list_add_tail(&child->ml_entry, &parent->ml_entry); - INIT_LIST_HEAD(&child->fl_entry); + list_add_tail(&child->node_list, &parent->node_list); + INIT_LIST_HEAD(&child->free_stack); parent->size -= size; parent->start += size; @@ -168,7 +168,7 @@ struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, } if (node->size == size) { - list_del_init(&node->fl_entry); + list_del_init(&node->free_stack); node->free = 0; } else { node = drm_mm_split_at_start(node, size, atomic); @@ -206,7 +206,7 @@ struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *node, } if (node->size == size) { - list_del_init(&node->fl_entry); + list_del_init(&node->free_stack); node->free = 0; } else { node = drm_mm_split_at_start(node, size, atomic); @@ -228,8 +228,8 @@ void drm_mm_put_block(struct drm_mm_node *cur) { struct drm_mm *mm = cur->mm; - struct list_head *cur_head = &cur->ml_entry; - struct list_head *root_head = &mm->ml_entry; + struct list_head *cur_head = &cur->node_list; + struct list_head *root_head = &mm->node_list; struct drm_mm_node *prev_node = NULL; struct drm_mm_node *next_node; @@ -237,7 +237,7 @@ void drm_mm_put_block(struct drm_mm_node *cur) if (cur_head->prev != root_head) { prev_node = - list_entry(cur_head->prev, struct drm_mm_node, ml_entry); + list_entry(cur_head->prev, struct drm_mm_node, node_list); if (prev_node->free) { prev_node->size += cur->size; merged = 1; @@ -245,15 +245,15 @@ void drm_mm_put_block(struct drm_mm_node *cur) } if (cur_head->next != root_head) { next_node = - list_entry(cur_head->next, struct drm_mm_node, ml_entry); + list_entry(cur_head->next, struct drm_mm_node, node_list); if (next_node->free) { if (merged) { prev_node->size += next_node->size; - list_del(&next_node->ml_entry); - list_del(&next_node->fl_entry); + list_del(&next_node->node_list); + list_del(&next_node->free_stack); spin_lock(&mm->unused_lock); if (mm->num_unused < MM_UNUSED_TARGET) { - list_add(&next_node->fl_entry, + list_add(&next_node->free_stack, &mm->unused_nodes); ++mm->num_unused; } else @@ -268,12 +268,12 @@ void drm_mm_put_block(struct drm_mm_node *cur) } if (!merged) { cur->free = 1; - list_add(&cur->fl_entry, &mm->fl_entry); + list_add(&cur->free_stack, &mm->free_stack); } else { - list_del(&cur->ml_entry); + list_del(&cur->node_list); spin_lock(&mm->unused_lock); if (mm->num_unused < MM_UNUSED_TARGET) { - list_add(&cur->fl_entry, &mm->unused_nodes); + list_add(&cur->free_stack, &mm->unused_nodes); ++mm->num_unused; } else kfree(cur); @@ -287,7 +287,6 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, unsigned alignment, int best_match) { - const struct list_head *free_stack = &mm->fl_entry; struct drm_mm_node *entry; struct drm_mm_node *best; unsigned long best_size; @@ -296,7 +295,7 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, best = NULL; best_size = ~0UL; - list_for_each_entry(entry, free_stack, fl_entry) { + list_for_each_entry(entry, &mm->free_stack, free_stack) { wasted = 0; if (entry->size < size) @@ -329,7 +328,6 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, unsigned long end, int best_match) { - const struct list_head *free_stack = &mm->fl_entry; struct drm_mm_node *entry; struct drm_mm_node *best; unsigned long best_size; @@ -338,7 +336,7 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, best = NULL; best_size = ~0UL; - list_for_each_entry(entry, free_stack, fl_entry) { + list_for_each_entry(entry, &mm->free_stack, free_stack) { wasted = 0; if (entry->size < size) @@ -373,7 +371,7 @@ EXPORT_SYMBOL(drm_mm_search_free_in_range); int drm_mm_clean(struct drm_mm * mm) { - struct list_head *head = &mm->ml_entry; + struct list_head *head = &mm->node_list; return (head->next->next == head); } @@ -381,8 +379,8 @@ EXPORT_SYMBOL(drm_mm_clean); int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) { - INIT_LIST_HEAD(&mm->ml_entry); - INIT_LIST_HEAD(&mm->fl_entry); + INIT_LIST_HEAD(&mm->node_list); + INIT_LIST_HEAD(&mm->free_stack); INIT_LIST_HEAD(&mm->unused_nodes); mm->num_unused = 0; spin_lock_init(&mm->unused_lock); @@ -393,25 +391,25 @@ EXPORT_SYMBOL(drm_mm_init); void drm_mm_takedown(struct drm_mm * mm) { - struct list_head *bnode = mm->fl_entry.next; + struct list_head *bnode = mm->free_stack.next; struct drm_mm_node *entry; struct drm_mm_node *next; - entry = list_entry(bnode, struct drm_mm_node, fl_entry); + entry = list_entry(bnode, struct drm_mm_node, free_stack); - if (entry->ml_entry.next != &mm->ml_entry || - entry->fl_entry.next != &mm->fl_entry) { + if (entry->node_list.next != &mm->node_list || + entry->free_stack.next != &mm->free_stack) { DRM_ERROR("Memory manager not clean. Delaying takedown\n"); return; } - list_del(&entry->fl_entry); - list_del(&entry->ml_entry); + list_del(&entry->free_stack); + list_del(&entry->node_list); kfree(entry); spin_lock(&mm->unused_lock); - list_for_each_entry_safe(entry, next, &mm->unused_nodes, fl_entry) { - list_del(&entry->fl_entry); + list_for_each_entry_safe(entry, next, &mm->unused_nodes, free_stack) { + list_del(&entry->free_stack); kfree(entry); --mm->num_unused; } @@ -426,7 +424,7 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) struct drm_mm_node *entry; int total_used = 0, total_free = 0, total = 0; - list_for_each_entry(entry, &mm->ml_entry, ml_entry) { + list_for_each_entry(entry, &mm->node_list, node_list) { printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8ld: %s\n", prefix, entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used"); @@ -447,7 +445,7 @@ int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) struct drm_mm_node *entry; int total_used = 0, total_free = 0, total = 0; - list_for_each_entry(entry, &mm->ml_entry, ml_entry) { + list_for_each_entry(entry, &mm->node_list, node_list) { seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: %s\n", entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used"); total += entry->size; if (entry->free) diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index da94071..e8740cc 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -42,8 +42,8 @@ #endif struct drm_mm_node { - struct list_head fl_entry; - struct list_head ml_entry; + struct list_head free_stack; + struct list_head node_list; int free; unsigned long start; unsigned long size; @@ -51,8 +51,11 @@ struct drm_mm_node { }; struct drm_mm { - struct list_head fl_entry; - struct list_head ml_entry; + /* List of free memory blocks, most recently freed ordered. */ + struct list_head free_stack; + /* List of all memory nodes, ordered according to the (increasing) start + * address of the memory node. */ + struct list_head node_list; struct list_head unused_nodes; int num_unused; spinlock_t unused_lock; -- cgit v0.10.2 From 7a6b2896f261894dde287d3faefa4b432cddca53 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 2 Jul 2010 15:02:15 +0100 Subject: drm_mm: extract check_free_mm_node There are already two copies of this logic. And the new scanning stuff will add some more. So extract it into a small helper function. Signed-off-by: Daniel Vetter Acked-by: Thomas Hellstrom Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index d2267ff..fd86a6c 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -283,6 +283,27 @@ void drm_mm_put_block(struct drm_mm_node *cur) EXPORT_SYMBOL(drm_mm_put_block); +static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size, + unsigned alignment) +{ + unsigned wasted = 0; + + if (entry->size < size) + return 0; + + if (alignment) { + register unsigned tmp = entry->start % alignment; + if (tmp) + wasted = alignment - tmp; + } + + if (entry->size >= size + wasted) { + return 1; + } + + return 0; +} + struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, unsigned alignment, int best_match) @@ -290,30 +311,20 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, struct drm_mm_node *entry; struct drm_mm_node *best; unsigned long best_size; - unsigned wasted; best = NULL; best_size = ~0UL; list_for_each_entry(entry, &mm->free_stack, free_stack) { - wasted = 0; - - if (entry->size < size) + if (!check_free_mm_node(entry, size, alignment)) continue; - if (alignment) { - register unsigned tmp = entry->start % alignment; - if (tmp) - wasted += alignment - tmp; - } + if (!best_match) + return entry; - if (entry->size >= size + wasted) { - if (!best_match) - return entry; - if (entry->size < best_size) { - best = entry; - best_size = entry->size; - } + if (entry->size < best_size) { + best = entry; + best_size = entry->size; } } @@ -331,37 +342,23 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, struct drm_mm_node *entry; struct drm_mm_node *best; unsigned long best_size; - unsigned wasted; best = NULL; best_size = ~0UL; list_for_each_entry(entry, &mm->free_stack, free_stack) { - wasted = 0; - - if (entry->size < size) + if (entry->start > end || (entry->start+entry->size) < start) continue; - if (entry->start > end || (entry->start+entry->size) < start) + if (!check_free_mm_node(entry, size, alignment)) continue; - if (entry->start < start) - wasted += start - entry->start; + if (!best_match) + return entry; - if (alignment) { - register unsigned tmp = (entry->start + wasted) % alignment; - if (tmp) - wasted += alignment - tmp; - } - - if (entry->size >= size + wasted && - (entry->start + wasted + size) <= end) { - if (!best_match) - return entry; - if (entry->size < best_size) { - best = entry; - best_size = entry->size; - } + if (entry->size < best_size) { + best = entry; + best_size = entry->size; } } -- cgit v0.10.2 From 709ea97145c125b3811ff70429e90ebdb0e832e5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 2 Jul 2010 15:02:16 +0100 Subject: drm: implement helper functions for scanning lru list These helper functions can be used to efficiently scan lru list for eviction. Eviction becomes a three stage process: 1. Scanning through the lru list until a suitable hole has been found. 2. Scan backwards to restore drm_mm consistency and find out which objects fall into the hole. 3. Evict the objects that fall into the hole. These helper functions don't allocate any memory (at the price of not allowing any other concurrent operations). Hence this can also be used for ttm (which does lru scanning under a spinlock). Evicting objects in this fashion should be more fair than the current approach by i915 (scan the lru for a object large enough to contain the new object). It's also more efficient than the current approach used by ttm (uncoditionally evict objects from the lru until there's enough free space). Signed-Off-by: Daniel Vetter Acked-by: Thomas Hellstrom Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index fd86a6c..da99edc 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -53,9 +53,9 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) struct drm_mm_node *child; if (atomic) - child = kmalloc(sizeof(*child), GFP_ATOMIC); + child = kzalloc(sizeof(*child), GFP_ATOMIC); else - child = kmalloc(sizeof(*child), GFP_KERNEL); + child = kzalloc(sizeof(*child), GFP_KERNEL); if (unlikely(child == NULL)) { spin_lock(&mm->unused_lock); @@ -85,7 +85,7 @@ int drm_mm_pre_get(struct drm_mm *mm) spin_lock(&mm->unused_lock); while (mm->num_unused < MM_UNUSED_TARGET) { spin_unlock(&mm->unused_lock); - node = kmalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc(sizeof(*node), GFP_KERNEL); spin_lock(&mm->unused_lock); if (unlikely(node == NULL)) { @@ -134,7 +134,6 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, INIT_LIST_HEAD(&child->free_stack); - child->free = 0; child->size = size; child->start = parent->start; child->mm = parent->mm; @@ -235,6 +234,9 @@ void drm_mm_put_block(struct drm_mm_node *cur) int merged = 0; + BUG_ON(cur->scanned_block || cur->scanned_prev_free + || cur->scanned_next_free); + if (cur_head->prev != root_head) { prev_node = list_entry(cur_head->prev, struct drm_mm_node, node_list); @@ -312,6 +314,8 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, struct drm_mm_node *best; unsigned long best_size; + BUG_ON(mm->scanned_blocks); + best = NULL; best_size = ~0UL; @@ -343,6 +347,8 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, struct drm_mm_node *best; unsigned long best_size; + BUG_ON(mm->scanned_blocks); + best = NULL; best_size = ~0UL; @@ -366,6 +372,158 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, } EXPORT_SYMBOL(drm_mm_search_free_in_range); +/** + * Initializa lru scanning. + * + * This simply sets up the scanning routines with the parameters for the desired + * hole. + * + * Warning: As long as the scan list is non-empty, no other operations than + * adding/removing nodes to/from the scan list are allowed. + */ +void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, + unsigned alignment) +{ + mm->scan_alignment = alignment; + mm->scan_size = size; + mm->scanned_blocks = 0; + mm->scan_hit_start = 0; + mm->scan_hit_size = 0; +} +EXPORT_SYMBOL(drm_mm_init_scan); + +/** + * Add a node to the scan list that might be freed to make space for the desired + * hole. + * + * Returns non-zero, if a hole has been found, zero otherwise. + */ +int drm_mm_scan_add_block(struct drm_mm_node *node) +{ + struct drm_mm *mm = node->mm; + struct list_head *prev_free, *next_free; + struct drm_mm_node *prev_node, *next_node; + + mm->scanned_blocks++; + + prev_free = next_free = NULL; + + BUG_ON(node->free); + node->scanned_block = 1; + node->free = 1; + + if (node->node_list.prev != &mm->node_list) { + prev_node = list_entry(node->node_list.prev, struct drm_mm_node, + node_list); + + if (prev_node->free) { + list_del(&prev_node->node_list); + + node->start = prev_node->start; + node->size += prev_node->size; + + prev_node->scanned_prev_free = 1; + + prev_free = &prev_node->free_stack; + } + } + + if (node->node_list.next != &mm->node_list) { + next_node = list_entry(node->node_list.next, struct drm_mm_node, + node_list); + + if (next_node->free) { + list_del(&next_node->node_list); + + node->size += next_node->size; + + next_node->scanned_next_free = 1; + + next_free = &next_node->free_stack; + } + } + + /* The free_stack list is not used for allocated objects, so these two + * pointers can be abused (as long as no allocations in this memory + * manager happens). */ + node->free_stack.prev = prev_free; + node->free_stack.next = next_free; + + if (check_free_mm_node(node, mm->scan_size, mm->scan_alignment)) { + mm->scan_hit_start = node->start; + mm->scan_hit_size = node->size; + + return 1; + } + + return 0; +} +EXPORT_SYMBOL(drm_mm_scan_add_block); + +/** + * Remove a node from the scan list. + * + * Nodes _must_ be removed in the exact same order from the scan list as they + * have been added, otherwise the internal state of the memory manager will be + * corrupted. + * + * When the scan list is empty, the selected memory nodes can be freed. An + * immediatly following drm_mm_search_free with best_match = 0 will then return + * the just freed block (because its at the top of the free_stack list). + * + * Returns one if this block should be evicted, zero otherwise. Will always + * return zero when no hole has been found. + */ +int drm_mm_scan_remove_block(struct drm_mm_node *node) +{ + struct drm_mm *mm = node->mm; + struct drm_mm_node *prev_node, *next_node; + + mm->scanned_blocks--; + + BUG_ON(!node->scanned_block); + node->scanned_block = 0; + node->free = 0; + + prev_node = list_entry(node->free_stack.prev, struct drm_mm_node, + free_stack); + next_node = list_entry(node->free_stack.next, struct drm_mm_node, + free_stack); + + if (prev_node) { + BUG_ON(!prev_node->scanned_prev_free); + prev_node->scanned_prev_free = 0; + + list_add_tail(&prev_node->node_list, &node->node_list); + + node->start = prev_node->start + prev_node->size; + node->size -= prev_node->size; + } + + if (next_node) { + BUG_ON(!next_node->scanned_next_free); + next_node->scanned_next_free = 0; + + list_add(&next_node->node_list, &node->node_list); + + node->size -= next_node->size; + } + + INIT_LIST_HEAD(&node->free_stack); + + /* Only need to check for containement because start&size for the + * complete resulting free block (not just the desired part) is + * stored. */ + if (node->start >= mm->scan_hit_start && + node->start + node->size + <= mm->scan_hit_start + mm->scan_hit_size) { + return 1; + } + + return 0; +} +EXPORT_SYMBOL(drm_mm_scan_remove_block); + int drm_mm_clean(struct drm_mm * mm) { struct list_head *head = &mm->node_list; @@ -380,6 +538,7 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) INIT_LIST_HEAD(&mm->free_stack); INIT_LIST_HEAD(&mm->unused_nodes); mm->num_unused = 0; + mm->scanned_blocks = 0; spin_lock_init(&mm->unused_lock); return drm_mm_create_tail_node(mm, start, size, 0); diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index e8740cc..bf01531 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -44,7 +44,10 @@ struct drm_mm_node { struct list_head free_stack; struct list_head node_list; - int free; + unsigned free : 1; + unsigned scanned_block : 1; + unsigned scanned_prev_free : 1; + unsigned scanned_next_free : 1; unsigned long start; unsigned long size; struct drm_mm *mm; @@ -59,6 +62,11 @@ struct drm_mm { struct list_head unused_nodes; int num_unused; spinlock_t unused_lock; + unsigned scan_alignment; + unsigned long scan_size; + unsigned long scan_hit_start; + unsigned scan_hit_size; + unsigned scanned_blocks; }; /* @@ -135,6 +143,11 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block) return block->mm; } +void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, + unsigned alignment); +int drm_mm_scan_add_block(struct drm_mm_node *node); +int drm_mm_scan_remove_block(struct drm_mm_node *node); + extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix); #ifdef CONFIG_DEBUG_FS int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm); -- cgit v0.10.2 From 5c8d7171cc4984351af802a525675d50ae555a7b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 11 Jun 2010 17:04:35 -0400 Subject: drm/kms: add crtc disable function More explicit than dpms. Same as the encoder disable function. Need this to explicity disconnect plls from crtcs for reuse when you plls:crtcs ratio isn't 1:1. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 9b2a541..fa1323f 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -241,7 +241,10 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; crtc->enabled = drm_helper_crtc_in_use(crtc); if (!crtc->enabled) { - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); + if (crtc_funcs->disable) + (*crtc_funcs->disable)(crtc); + else + (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF); crtc->fb = NULL; } } diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 1121f77..7e3c976 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -63,6 +63,9 @@ struct drm_crtc_helper_funcs { /* reload the current crtc LUT */ void (*load_lut)(struct drm_crtc *crtc); + + /* disable crtc when not in use - more explicit than dpms off */ + void (*disable)(struct drm_crtc *crtc); }; struct drm_encoder_helper_funcs { -- cgit v0.10.2 From f5f05c8a578395a22c190b11eea8e858965abbf7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 9 Jul 2010 07:43:27 +1000 Subject: drm: add PCI requirements to low-level drivers. Now that highlevel DRM no longer requires PCI, we can move the requirement into the lowlevel drivers. Reported-by: Randy Dunlap Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 520ab23..5b7a1a4 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -130,7 +130,7 @@ endchoice config DRM_MGA tristate "Matrox g200/g400" - depends on DRM + depends on DRM && PCI select FW_LOADER help Choose this option if you have a Matrox G200, G400 or G450 graphics @@ -148,14 +148,14 @@ config DRM_SIS config DRM_VIA tristate "Via unichrome video cards" - depends on DRM + depends on DRM && PCI help Choose this option if you have a Via unichrome or compatible video chipset. If M is selected the module will be called via. config DRM_SAVAGE tristate "Savage video cards" - depends on DRM + depends on DRM && PCI help Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister chipset. If M is selected the module will be called savage. diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 1175429..b6f5239 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -1,6 +1,6 @@ config DRM_NOUVEAU tristate "Nouveau (nVidia) cards" - depends on DRM + depends on DRM && PCI select FW_LOADER select DRM_KMS_HELPER select DRM_TTM -- cgit v0.10.2 From 86a1b9d1f175e9e9d022c7674d6ba1ede48ee15f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 1 Jul 2010 16:49:57 +1000 Subject: drm: disable encoder rather than dpms off in drm_crtc_prepare_encoders() Original behaviour will be preserved for drivers that don't implement disable() hooks for an encoder. Signed-off-by: Ben Skeggs Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index fa1323f..774d21e 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -201,6 +201,17 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) } EXPORT_SYMBOL(drm_helper_crtc_in_use); +static void +drm_encoder_disable(struct drm_encoder *encoder) +{ + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; + + if (encoder_funcs->disable) + (*encoder_funcs->disable)(encoder); + else + (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); +} + /** * drm_helper_disable_unused_functions - disable unused objects * @dev: DRM device @@ -215,7 +226,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) { struct drm_encoder *encoder; struct drm_connector *connector; - struct drm_encoder_helper_funcs *encoder_funcs; struct drm_crtc *crtc; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { @@ -226,12 +236,8 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) } list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - encoder_funcs = encoder->helper_private; if (!drm_helper_encoder_in_use(encoder)) { - if (encoder_funcs->disable) - (*encoder_funcs->disable)(encoder); - else - (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); + drm_encoder_disable(encoder); /* disconnector encoder from any connector */ encoder->crtc = NULL; } @@ -295,11 +301,11 @@ drm_crtc_prepare_encoders(struct drm_device *dev) encoder_funcs = encoder->helper_private; /* Disable unused encoders */ if (encoder->crtc == NULL) - (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); + drm_encoder_disable(encoder); /* Disable encoders whose CRTC is about to change */ if (encoder_funcs->get_crtc && encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) - (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); + drm_encoder_disable(encoder); } } -- cgit v0.10.2 From 2dfe36b1b6cb51ddfd2358774fd8f097528cfdd0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Jun 2010 09:47:43 +1000 Subject: drm/nouveau: place notifiers in system memory by default Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 0fd8e10..2dd7d19 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -56,7 +56,7 @@ int nouveau_vram_pushbuf; module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM"); -int nouveau_vram_notify = 1; +int nouveau_vram_notify = 0; module_param_named(vram_notify, nouveau_vram_notify, int, 0400); MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); -- cgit v0.10.2 From d17f395cdcec39033a481f96d75e8b3d3c41d43a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Jun 2010 13:32:42 +1000 Subject: drm/nouveau: move LVDS detection back to connector detect() time Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 149ed22..a8c44c9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -236,20 +236,6 @@ nouveau_connector_detect(struct drm_connector *connector) struct nouveau_i2c_chan *i2c; int type, flags; - if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS) - nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); - if (nv_encoder && nv_connector->native_mode) { - unsigned status = connector_status_connected; - -#if defined(CONFIG_ACPI_BUTTON) || \ - (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) - if (!nouveau_ignorelid && !acpi_lid_open()) - status = connector_status_unknown; -#endif - nouveau_connector_set_encoder(connector, nv_encoder); - return status; - } - /* Cleanup the previous EDID block. */ if (nv_connector->edid) { drm_mode_connector_update_edid_property(connector, NULL); @@ -321,6 +307,67 @@ detect_analog: return connector_status_disconnected; } +static enum drm_connector_status +nouveau_connector_detect_lvds(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct nouveau_encoder *nv_encoder = NULL; + enum drm_connector_status status = connector_status_disconnected; + + /* Cleanup the previous EDID block. */ + if (nv_connector->edid) { + drm_mode_connector_update_edid_property(connector, NULL); + kfree(nv_connector->edid); + nv_connector->edid = NULL; + } + + nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); + if (!nv_encoder) + return connector_status_disconnected; + + if (!dev_priv->vbios.fp_no_ddc) { + status = nouveau_connector_detect(connector); + if (status == connector_status_connected) + goto out; + } + + /* If no EDID found above, and the VBIOS indicates a hardcoded + * modeline is avalilable for the panel, set it as the panel's + * native mode and exit. + */ + if (nouveau_bios_fp_mode(dev, NULL) && (dev_priv->vbios.fp_no_ddc || + nv_encoder->dcb->lvdsconf.use_straps_for_mode)) { + status = connector_status_connected; + goto out; + } + + /* Still nothing, some VBIOS images have a hardcoded EDID block + * stored for the panel stored in them. + */ + if (!dev_priv->vbios.fp_no_ddc) { + struct edid *edid = + (struct edid *)nouveau_bios_embedded_edid(dev); + if (edid) { + nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + *(nv_connector->edid) = *edid; + status = connector_status_connected; + } + } + +out: +#if defined(CONFIG_ACPI_BUTTON) || \ + (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) + if (status == connector_status_connected && + !nouveau_ignorelid && !acpi_lid_open()) + status = connector_status_unknown; +#endif + + drm_mode_connector_update_edid_property(connector, nv_connector->edid); + return status; +} + static void nouveau_connector_force(struct drm_connector *connector) { @@ -534,21 +581,28 @@ static int nouveau_connector_get_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; + struct drm_display_mode mode; int ret = 0; - /* If we're not LVDS, destroy the previous native mode, the attached - * monitor could have changed. + /* destroy the native mode, the attached monitor could have changed. */ - if (nv_connector->dcb->type != DCB_CONNECTOR_LVDS && - nv_connector->native_mode) { + if (nv_connector->native_mode) { drm_mode_destroy(dev, nv_connector->native_mode); nv_connector->native_mode = NULL; } if (nv_connector->edid) ret = drm_add_edid_modes(connector, nv_connector->edid); + else + if (nv_encoder->dcb->type == OUTPUT_LVDS && + (nv_encoder->dcb->lvdsconf.use_straps_for_mode || + dev_priv->vbios.fp_no_ddc) && + nouveau_bios_fp_mode(dev, &mode)) { + nv_connector->native_mode = drm_mode_duplicate(dev, &mode); + } /* Find the native mode if this is a digital panel, if we didn't * find any modes through DDC previously add the native mode to @@ -662,99 +716,28 @@ nouveau_connector_funcs = { .force = nouveau_connector_force }; -static int -nouveau_connector_create_lvds(struct drm_device *dev, - struct drm_connector *connector) -{ - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_i2c_chan *i2c = NULL; - struct nouveau_encoder *nv_encoder; - struct drm_display_mode native, *mode, *temp; - bool dummy, if_is_24bit = false; - int ret, flags; - - nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); - if (!nv_encoder) - return -ENODEV; - - ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit); - if (ret) { - NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n"); - return ret; - } - nv_connector->use_dithering = !if_is_24bit; - - /* Firstly try getting EDID over DDC, if allowed and I2C channel - * is available. - */ - if (!dev_priv->vbios.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf) - i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); - - if (i2c) { - nouveau_connector_ddc_prepare(connector, &flags); - nv_connector->edid = drm_get_edid(connector, &i2c->adapter); - nouveau_connector_ddc_finish(connector, flags); - } - - /* If no EDID found above, and the VBIOS indicates a hardcoded - * modeline is avalilable for the panel, set it as the panel's - * native mode and exit. - */ - if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) && - (nv_encoder->dcb->lvdsconf.use_straps_for_mode || - dev_priv->vbios.fp_no_ddc)) { - nv_connector->native_mode = drm_mode_duplicate(dev, &native); - goto out; - } - - /* Still nothing, some VBIOS images have a hardcoded EDID block - * stored for the panel stored in them. - */ - if (!nv_connector->edid && !nv_connector->native_mode && - !dev_priv->vbios.fp_no_ddc) { - struct edid *edid = - (struct edid *)nouveau_bios_embedded_edid(dev); - if (edid) { - nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL); - *(nv_connector->edid) = *edid; - } - } - - if (!nv_connector->edid) - goto out; - - /* We didn't find/use a panel mode from the VBIOS, so parse the EDID - * block and look for the preferred mode there. - */ - ret = drm_add_edid_modes(connector, nv_connector->edid); - if (ret == 0) - goto out; - nv_connector->detected_encoder = nv_encoder; - nv_connector->native_mode = nouveau_connector_native_mode(connector); - list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) - drm_mode_remove(connector, mode); - -out: - if (!nv_connector->native_mode) { - NV_ERROR(dev, "LVDS present in DCB table, but couldn't " - "determine its native mode. Disabling.\n"); - return -ENODEV; - } - - drm_mode_connector_update_edid_property(connector, nv_connector->edid); - return 0; -} +static const struct drm_connector_funcs +nouveau_connector_funcs_lvds = { + .dpms = drm_helper_connector_dpms, + .save = NULL, + .restore = NULL, + .detect = nouveau_connector_detect_lvds, + .destroy = nouveau_connector_destroy, + .fill_modes = drm_helper_probe_single_connector_modes, + .set_property = nouveau_connector_set_property, + .force = nouveau_connector_force +}; int nouveau_connector_create(struct drm_device *dev, struct dcb_connector_table_entry *dcb) { + const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_connector *nv_connector = NULL; struct drm_connector *connector; struct drm_encoder *encoder; - int ret, type; + int type; NV_DEBUG_KMS(dev, "\n"); @@ -787,6 +770,7 @@ nouveau_connector_create(struct drm_device *dev, case DCB_CONNECTOR_LVDS: NV_INFO(dev, "Detected a LVDS connector\n"); type = DRM_MODE_CONNECTOR_LVDS; + funcs = &nouveau_connector_funcs_lvds; break; case DCB_CONNECTOR_DP: NV_INFO(dev, "Detected a DisplayPort connector\n"); @@ -811,7 +795,7 @@ nouveau_connector_create(struct drm_device *dev, connector->interlace_allowed = false; connector->doublescan_allowed = false; - drm_connector_init(dev, connector, &nouveau_connector_funcs, type); + drm_connector_init(dev, connector, funcs, type); drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); /* attach encoders */ @@ -841,9 +825,6 @@ nouveau_connector_create(struct drm_device *dev, drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0); } - if (dcb->type != DCB_CONNECTOR_LVDS) - nv_connector->use_dithering = false; - switch (dcb->type) { case DCB_CONNECTOR_VGA: connector->polled = DRM_CONNECTOR_POLL_CONNECT; @@ -883,14 +864,5 @@ nouveau_connector_create(struct drm_device *dev, } drm_sysfs_connector_add(connector); - - if (dcb->type == DCB_CONNECTOR_LVDS) { - ret = nouveau_connector_create_lvds(dev, connector); - if (ret) { - connector->funcs->destroy(connector); - return ret; - } - } - return 0; } -- cgit v0.10.2 From b833ac26f1f1c8e8d9149d83dbdd91432f2807d5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Jun 2010 15:32:24 +1000 Subject: drm/nouveau: use drm_mm in preference to custom code doing the same thing Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index c697191..20c5488 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -123,14 +123,6 @@ nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo) return ioptr; } -struct mem_block { - struct mem_block *next; - struct mem_block *prev; - uint64_t start; - uint64_t size; - struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ -}; - enum nouveau_flags { NV_NFORCE = 0x10000000, NV_NFORCE2 = 0x20000000 @@ -149,7 +141,7 @@ struct nouveau_gpuobj { struct list_head list; struct nouveau_channel *im_channel; - struct mem_block *im_pramin; + struct drm_mm_node *im_pramin; struct nouveau_bo *im_backing; uint32_t im_backing_start; uint32_t *im_backing_suspend; @@ -206,7 +198,7 @@ struct nouveau_channel { /* Notifier memory */ struct nouveau_bo *notifier_bo; - struct mem_block *notifier_heap; + struct drm_mm notifier_heap; /* PFIFO context */ struct nouveau_gpuobj_ref *ramfc; @@ -224,7 +216,7 @@ struct nouveau_channel { /* Objects */ struct nouveau_gpuobj_ref *ramin; /* Private instmem */ - struct mem_block *ramin_heap; /* Private PRAMIN heap */ + struct drm_mm ramin_heap; /* Private PRAMIN heap */ struct nouveau_gpuobj_ref *ramht; /* Hash table */ struct list_head ramht_refs; /* Objects referenced by RAMHT */ @@ -595,7 +587,7 @@ struct drm_nouveau_private { struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; int vm_vram_pt_nr; - struct mem_block *ramin_heap; + struct drm_mm ramin_heap; /* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */ uint32_t ctx_table_size; @@ -707,15 +699,7 @@ extern bool nouveau_wait_for_idle(struct drm_device *); extern int nouveau_card_init(struct drm_device *); /* nouveau_mem.c */ -extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, - uint64_t size); -extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, - uint64_t size, int align2, - struct drm_file *, int tail); -extern void nouveau_mem_takedown(struct mem_block **heap); -extern void nouveau_mem_free_block(struct mem_block *); extern int nouveau_mem_detect(struct drm_device *dev); -extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); extern int nouveau_mem_init(struct drm_device *); extern int nouveau_mem_init_agp(struct drm_device *); extern void nouveau_mem_close(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index fb6b791..4274281 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -35,162 +35,6 @@ #include "drm_sarea.h" #include "nouveau_drv.h" -static struct mem_block * -split_block(struct mem_block *p, uint64_t start, uint64_t size, - struct drm_file *file_priv) -{ - /* Maybe cut off the start of an existing block */ - if (start > p->start) { - struct mem_block *newblock = - kmalloc(sizeof(*newblock), GFP_KERNEL); - if (!newblock) - goto out; - newblock->start = start; - newblock->size = p->size - (start - p->start); - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size -= newblock->size; - p = newblock; - } - - /* Maybe cut off the end of an existing block */ - if (size < p->size) { - struct mem_block *newblock = - kmalloc(sizeof(*newblock), GFP_KERNEL); - if (!newblock) - goto out; - newblock->start = start + size; - newblock->size = p->size - size; - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size = size; - } - -out: - /* Our block is in the middle */ - p->file_priv = file_priv; - return p; -} - -struct mem_block * -nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, - int align2, struct drm_file *file_priv, int tail) -{ - struct mem_block *p; - uint64_t mask = (1 << align2) - 1; - - if (!heap) - return NULL; - - if (tail) { - list_for_each_prev(p, heap) { - uint64_t start = ((p->start + p->size) - size) & ~mask; - - if (p->file_priv == NULL && start >= p->start && - start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); - } - } else { - list_for_each(p, heap) { - uint64_t start = (p->start + mask) & ~mask; - - if (p->file_priv == NULL && - start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); - } - } - - return NULL; -} - -void nouveau_mem_free_block(struct mem_block *p) -{ - p->file_priv = NULL; - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - if (p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - kfree(q); - } - - if (p->prev->file_priv == NULL) { - struct mem_block *q = p->prev; - q->size += p->size; - q->next = p->next; - q->next->prev = q; - kfree(p); - } -} - -/* Initialize. How to check for an uninitialized heap? - */ -int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start, - uint64_t size) -{ - struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); - - if (!blocks) - return -ENOMEM; - - *heap = kmalloc(sizeof(**heap), GFP_KERNEL); - if (!*heap) { - kfree(blocks); - return -ENOMEM; - } - - blocks->start = start; - blocks->size = size; - blocks->file_priv = NULL; - blocks->next = blocks->prev = *heap; - - memset(*heap, 0, sizeof(**heap)); - (*heap)->file_priv = (struct drm_file *) -1; - (*heap)->next = (*heap)->prev = blocks; - return 0; -} - -/* - * Free all blocks associated with the releasing file_priv - */ -void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap || !heap->next) - return; - - list_for_each(p, heap) { - if (p->file_priv == file_priv) - p->file_priv = NULL; - } - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - list_for_each(p, heap) { - while ((p->file_priv == NULL) && - (p->next->file_priv == NULL) && - (p->next != heap)) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - kfree(q); - } - } -} - /* * NV10-NV40 tiling helpers */ @@ -421,24 +265,8 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) /* * Cleanup everything */ -void nouveau_mem_takedown(struct mem_block **heap) -{ - struct mem_block *p; - - if (!*heap) - return; - - for (p = (*heap)->next; p != *heap;) { - struct mem_block *q = p; - p = p->next; - kfree(q); - } - - kfree(*heap); - *heap = NULL; -} - -void nouveau_mem_close(struct drm_device *dev) +void +nouveau_mem_close(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 9537f3e..32f7fbd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c @@ -55,7 +55,7 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) if (ret) goto out_err; - ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size); + ret = drm_mm_init(&chan->notifier_heap, 0, ntfy->bo.mem.size); if (ret) goto out_err; @@ -80,7 +80,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan) nouveau_bo_unpin(chan->notifier_bo); mutex_unlock(&dev->struct_mutex); drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); - nouveau_mem_takedown(&chan->notifier_heap); + drm_mm_takedown(&chan->notifier_heap); } static void @@ -90,7 +90,7 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev, NV_DEBUG(dev, "\n"); if (gpuobj->priv) - nouveau_mem_free_block(gpuobj->priv); + drm_mm_put_block(gpuobj->priv); } int @@ -100,18 +100,13 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *nobj = NULL; - struct mem_block *mem; + struct drm_mm_node *mem; uint32_t offset; int target, ret; - if (!chan->notifier_heap) { - NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n", - chan->id); - return -EINVAL; - } - - mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0, - (struct drm_file *)-2, 0); + mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0); + if (mem) + mem = drm_mm_get_block(mem, size, 0); if (!mem) { NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); return -ENOMEM; @@ -144,17 +139,17 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, mem->size, NV_DMA_ACCESS_RW, target, &nobj); if (ret) { - nouveau_mem_free_block(mem); + drm_mm_put_block(mem); NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret); return ret; } - nobj->dtor = nouveau_notifier_gpuobj_dtor; - nobj->priv = mem; + nobj->dtor = nouveau_notifier_gpuobj_dtor; + nobj->priv = mem; ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL); if (ret) { nouveau_gpuobj_del(dev, &nobj); - nouveau_mem_free_block(mem); + drm_mm_put_block(mem); NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret); return ret; } @@ -170,7 +165,7 @@ nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset) return -EINVAL; if (poffset) { - struct mem_block *mem = nobj->priv; + struct drm_mm_node *mem = nobj->priv; if (*poffset >= mem->size) return false; diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index e7c100b..d436c3c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -209,7 +209,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->engine; struct nouveau_gpuobj *gpuobj; - struct mem_block *pramin = NULL; + struct drm_mm *pramin = NULL; int ret; NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n", @@ -233,17 +233,17 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, * available. */ if (chan) { - if (chan->ramin_heap) { + if (chan->ramin_heap.ml_entry.next) { NV_DEBUG(dev, "private heap\n"); - pramin = chan->ramin_heap; + pramin = &chan->ramin_heap; } else if (dev_priv->card_type < NV_50) { NV_DEBUG(dev, "global heap fallback\n"); - pramin = dev_priv->ramin_heap; + pramin = &dev_priv->ramin_heap; } } else { NV_DEBUG(dev, "global heap\n"); - pramin = dev_priv->ramin_heap; + pramin = &dev_priv->ramin_heap; } if (!pramin) { @@ -260,9 +260,10 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, } /* Allocate a chunk of the PRAMIN aperture */ - gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, - drm_order(align), - (struct drm_file *)-2, 0); + gpuobj->im_pramin = drm_mm_search_free(pramin, size, align, 0); + if (gpuobj->im_pramin) + gpuobj->im_pramin = drm_mm_get_block(gpuobj->im_pramin, size, align); + if (!gpuobj->im_pramin) { nouveau_gpuobj_del(dev, &gpuobj); return -ENOMEM; @@ -386,7 +387,7 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) if (gpuobj->flags & NVOBJ_FLAG_FAKE) kfree(gpuobj->im_pramin); else - nouveau_mem_free_block(gpuobj->im_pramin); + drm_mm_put_block(gpuobj->im_pramin); } list_del(&gpuobj->list); @@ -589,7 +590,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset, list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); if (p_offset != ~0) { - gpuobj->im_pramin = kzalloc(sizeof(struct mem_block), + gpuobj->im_pramin = kzalloc(sizeof(struct drm_mm_node), GFP_KERNEL); if (!gpuobj->im_pramin) { nouveau_gpuobj_del(dev, &gpuobj); @@ -944,8 +945,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) } pramin = chan->ramin->gpuobj; - ret = nouveau_mem_init_heap(&chan->ramin_heap, - pramin->im_pramin->start + base, size); + ret = drm_mm_init(&chan->ramin_heap, pramin->im_pramin->start + base, size); if (ret) { NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); nouveau_gpuobj_ref_del(dev, &chan->ramin); @@ -1130,8 +1130,8 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]); - if (chan->ramin_heap) - nouveau_mem_takedown(&chan->ramin_heap); + if (chan->ramin_heap.free_stack.next) + drm_mm_takedown(&chan->ramin_heap); if (chan->ramin) nouveau_gpuobj_ref_del(dev, &chan->ramin); diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c index a3b9563..17af702 100644 --- a/drivers/gpu/drm/nouveau/nv04_instmem.c +++ b/drivers/gpu/drm/nouveau/nv04_instmem.c @@ -106,7 +106,7 @@ int nv04_instmem_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t offset; - int ret = 0; + int ret; nv04_instmem_determine_amount(dev); nv04_instmem_configure_fixed_tables(dev); @@ -129,14 +129,14 @@ int nv04_instmem_init(struct drm_device *dev) offset = 0x40000; } - ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, - offset, dev_priv->ramin_rsvd_vram - offset); + ret = drm_mm_init(&dev_priv->ramin_heap, offset, + dev_priv->ramin_rsvd_vram - offset); if (ret) { - dev_priv->ramin_heap = NULL; - NV_ERROR(dev, "Failed to init RAMIN heap\n"); + NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret); + return ret; } - return ret; + return 0; } void diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 580a5d1..515edde 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -110,8 +110,8 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) return ret; } - ret = nouveau_mem_init_heap(&chan->ramin_heap, chan->ramin->gpuobj-> - im_pramin->start, 32768); + ret = drm_mm_init(&chan->ramin_heap, + chan->ramin->gpuobj->im_pramin->start, 32768); if (ret) { NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); nv50_evo_channel_del(pchan); diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 71c01b6..a361d16 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -147,7 +147,7 @@ nv50_instmem_init(struct drm_device *dev) if (ret) return ret; - if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base)) + if (drm_mm_init(&chan->ramin_heap, c_base, c_size - c_base)) return -ENOMEM; /* RAMFC + zero channel's PRAMIN up to start of VM pagedir */ @@ -276,9 +276,7 @@ nv50_instmem_init(struct drm_device *dev) nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700); /* Global PRAMIN heap */ - if (nouveau_mem_init_heap(&dev_priv->ramin_heap, - c_size, dev_priv->ramin_size - c_size)) { - dev_priv->ramin_heap = NULL; + if (drm_mm_init(&dev_priv->ramin_heap, c_size, dev_priv->ramin_size - c_size)) { NV_ERROR(dev, "Failed to init RAMIN heap\n"); } @@ -321,7 +319,7 @@ nv50_instmem_takedown(struct drm_device *dev) nouveau_gpuobj_del(dev, &chan->vm_pd); nouveau_gpuobj_ref_del(dev, &chan->ramfc); nouveau_gpuobj_ref_del(dev, &chan->ramin); - nouveau_mem_takedown(&chan->ramin_heap); + drm_mm_takedown(&chan->ramin_heap); dev_priv->fifos[0] = dev_priv->fifos[127] = NULL; kfree(chan); @@ -436,14 +434,14 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) return -EINVAL; - NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n", + NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n", gpuobj->im_pramin->start, gpuobj->im_pramin->size); pte = (gpuobj->im_pramin->start >> 12) << 1; pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; vram = gpuobj->im_backing_start; - NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n", + NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n", gpuobj->im_pramin->start, pte, pte_end); NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start); -- cgit v0.10.2 From cd0b072f95b3dbee5d7b97f52edc40f00d5d28e1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Jun 2010 15:56:22 +1000 Subject: drm/nouveau: remove left-over !DRIVER_MODESET paths It's far preferable to have the driver do nothing at all for "nomodeset". Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 65c441a..2e3c6ca 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -92,11 +92,9 @@ nouveau_dma_init(struct nouveau_channel *chan) return ret; /* Map M2MF notifier object - fbcon. */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = nouveau_bo_map(chan->notifier_bo); - if (ret) - return ret; - } + ret = nouveau_bo_map(chan->notifier_bo); + if (ret) + return ret; /* Insert NOPS for NOUVEAU_DMA_SKIPS */ ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 2dd7d19..6edfc23 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -155,9 +155,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) struct drm_crtc *crtc; int ret, i; - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - if (pm_state.event == PM_EVENT_PRETHAW) return 0; @@ -257,9 +254,6 @@ nouveau_pci_resume(struct pci_dev *pdev) struct drm_crtc *crtc; int ret, i; - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -ENODEV; - nouveau_fbcon_save_disable_accel(dev); NV_INFO(dev, "We're back, enabling device...\n"); @@ -371,7 +365,8 @@ nouveau_pci_resume(struct pci_dev *pdev) static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM, + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | + DRIVER_MODESET, .load = nouveau_load, .firstopen = nouveau_firstopen, .lastclose = nouveau_lastclose, @@ -438,16 +433,18 @@ static int __init nouveau_init(void) nouveau_modeset = 1; } - if (nouveau_modeset == 1) { - driver.driver_features |= DRIVER_MODESET; - nouveau_register_dsm_handler(); - } + if (!nouveau_modeset) + return 0; + nouveau_register_dsm_handler(); return drm_init(&driver); } static void __exit nouveau_exit(void) { + if (!nouveau_modeset) + return; + drm_exit(&driver); nouveau_unregister_dsm_handler(); } diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 4274281..bcf7ed3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -277,8 +277,7 @@ nouveau_mem_close(struct drm_device *dev) nouveau_ttm_global_release(dev_priv); - if (drm_core_has_AGP(dev) && dev->agp && - drm_core_check_feature(dev, DRIVER_MODESET)) { + if (drm_core_has_AGP(dev) && dev->agp) { struct drm_agp_mem *entry, *tempe; /* Remove AGP resources, but leave dev->agp diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index b02a231..3e241e4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -425,11 +425,9 @@ nouveau_card_init(struct drm_device *dev) spin_lock_init(&dev_priv->context_switch_lock); /* Parse BIOS tables / Run init tables if card not POSTed */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = nouveau_bios_init(dev); - if (ret) - goto out; - } + ret = nouveau_bios_init(dev); + if (ret) + goto out; ret = nouveau_mem_detect(dev); if (ret) @@ -504,14 +502,12 @@ nouveau_card_init(struct drm_device *dev) goto out_irq; } - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - if (dev_priv->card_type >= NV_50) - ret = nv50_display_create(dev); - else - ret = nv04_display_create(dev); - if (ret) - goto out_channel; - } + if (dev_priv->card_type >= NV_50) + ret = nv50_display_create(dev); + else + ret = nv04_display_create(dev); + if (ret) + goto out_channel; ret = nouveau_backlight_init(dev); if (ret) @@ -519,11 +515,8 @@ nouveau_card_init(struct drm_device *dev) dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - nouveau_fbcon_init(dev); - drm_kms_helper_poll_init(dev); - } - + nouveau_fbcon_init(dev); + drm_kms_helper_poll_init(dev); return 0; out_channel: @@ -595,8 +588,7 @@ static void nouveau_card_takedown(struct drm_device *dev) nouveau_mem_close(dev); engine->instmem.takedown(dev); - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_irq_uninstall(dev); + drm_irq_uninstall(dev); nouveau_gpuobj_late_takedown(dev); nouveau_bios_takedown(dev); @@ -691,6 +683,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) struct drm_nouveau_private *dev_priv; uint32_t reg0; resource_size_t mmio_start_offs; + int ret; dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (!dev_priv) @@ -773,11 +766,9 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", dev_priv->card_type, reg0); - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - int ret = nouveau_remove_conflicting_drivers(dev); - if (ret) - return ret; - } + ret = nouveau_remove_conflicting_drivers(dev); + if (ret) + return ret; /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */ if (dev_priv->card_type >= NV_40) { @@ -812,46 +803,28 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) dev_priv->flags |= NV_NFORCE2; /* For kernel modesetting, init card now and bring up fbcon */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - int ret = nouveau_card_init(dev); - if (ret) - return ret; - } + ret = nouveau_card_init(dev); + if (ret) + return ret; return 0; } -static void nouveau_close(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* In the case of an error dev_priv may not be allocated yet */ - if (dev_priv) - nouveau_card_takedown(dev); -} - -/* KMS: we need mmio at load time, not when the first drm client opens. */ void nouveau_lastclose(struct drm_device *dev) { - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - nouveau_close(dev); } int nouveau_unload(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - drm_kms_helper_poll_fini(dev); - nouveau_fbcon_fini(dev); - if (dev_priv->card_type >= NV_50) - nv50_display_destroy(dev); - else - nv04_display_destroy(dev); - nouveau_close(dev); - } + drm_kms_helper_poll_fini(dev); + nouveau_fbcon_fini(dev); + if (dev_priv->card_type >= NV_50) + nv50_display_destroy(dev); + else + nv04_display_destroy(dev); + nouveau_card_takedown(dev); iounmap(dev_priv->mmio); iounmap(dev_priv->ramin); -- cgit v0.10.2 From fb4f56214dd632d90b8ac64d7781faeb4dd744c7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 2 Jun 2010 08:38:19 +1000 Subject: drm/nouveau: missed some braces Luckily this had absolutely no effect whatsoever :) Reported-by: Marcin Slusarz Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index bcf7ed3..206bd16 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -367,9 +367,10 @@ nouveau_mem_detect(struct drm_device *dev) } else { dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; - if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) + if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) { dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); dev_priv->vram_sys_base <<= 12; + } } NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); -- cgit v0.10.2 From 7a2e4e03b77b929b10f3007395128a9870090653 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 2 Jun 2010 10:12:00 +1000 Subject: drm/nv50: fix memory detection for cards with >=4GiB VRAM Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 206bd16..2853ba0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -364,9 +364,14 @@ nouveau_mem_detect(struct drm_device *dev) } else if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { dev_priv->vram_size = nouveau_mem_detect_nforce(dev); - } else { + } else + if (dev_priv->card_type < NV_50) { dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; + } else { + dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); + dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; + dev_priv->vram_size &= 0xffffffff00; if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) { dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); dev_priv->vram_sys_base <<= 12; -- cgit v0.10.2 From 2fa67f12e71d7f8adade7c4e6bb839156dea2365 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 16 Jun 2010 15:52:44 +0200 Subject: drm/nouveau: Put the dithering check back in nouveau_connector_create. a7b9f9e5adef dropped it by accident. Signed-off-by: Francisco Jerez Tested-by: Thibaut Girka Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index a8c44c9..7919020 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -737,7 +737,7 @@ nouveau_connector_create(struct drm_device *dev, struct nouveau_connector *nv_connector = NULL; struct drm_connector *connector; struct drm_encoder *encoder; - int type; + int type, ret = 0; NV_DEBUG_KMS(dev, "\n"); @@ -813,9 +813,21 @@ nouveau_connector_create(struct drm_device *dev, if (!connector->encoder_ids[0]) { NV_WARN(dev, " no encoders, ignoring\n"); - drm_connector_cleanup(connector); - kfree(connector); - return 0; + goto fail; + } + + /* Check if we need dithering enabled */ + if (dcb->type == DCB_CONNECTOR_LVDS) { + bool dummy, is_24bit = false; + + ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit); + if (ret) { + NV_ERROR(dev, "Error parsing LVDS table, disabling " + "LVDS\n"); + goto fail; + } + + nv_connector->use_dithering = !is_24bit; } /* Init DVI-I specific properties */ @@ -865,4 +877,10 @@ nouveau_connector_create(struct drm_device *dev, drm_sysfs_connector_add(connector); return 0; + +fail: + drm_connector_cleanup(connector); + kfree(connector); + return ret; + } -- cgit v0.10.2 From 190a43783f2c43186180c827444d4eac901b4bcf Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 17 Jun 2010 12:42:14 +0200 Subject: drm/nouveau: Don't clear AGPCMD completely on INIT_RESET. We just need to clear the SBA and ENABLE bits to reset the AGP controller: If the AGP bridge was configured to use "fast writes", clearing the FW bit would break the subsequent MMIO writes and eventually end with a lockup. Note that all the BIOSes I've seen do the same as we did (it works for them because they don't use MMIO), OTOH the blob leaves FW untouched. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index fc924b6..9ab0c83 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -2146,7 +2146,8 @@ init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) /* no iexec->execute check by design */ pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19); - bios_wr32(bios, NV_PBUS_PCI_NV_19, 0); + bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19 & ~0xf00); + bios_wr32(bios, reg, value1); udelay(10); -- cgit v0.10.2 From 3af76454a70cd09d8e3ede94ee50a35c772ba439 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 19 Jun 2010 13:54:48 +0200 Subject: drm/nouveau: Ignore broken legacy I2C entries. The nv05 card in the bug report [1] doesn't have usable I2C port register offsets (they're all filled with zeros). Ignore them and use the defaults. [1] http://bugs.launchpad.net/bugs/569505 Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 9ab0c83..ed0f530 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5167,10 +5167,14 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset]; bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1]; bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2]; - bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; - bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; - bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; - bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7]; + if (bios->data[legacy_i2c_offset + 4]) + bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; + if (bios->data[legacy_i2c_offset + 5]) + bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; + if (bios->data[legacy_i2c_offset + 6]) + bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; + if (bios->data[legacy_i2c_offset + 7]) + bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7]; if (bmplength > 74) { bios->fmaxvco = ROM32(bmp[67]); -- cgit v0.10.2 From 3195c5f9784aa8ec27a7bb19a6840dc67e9e90f1 Mon Sep 17 00:00:00 2001 From: Albert Damen Date: Sun, 20 Jun 2010 16:57:57 +0200 Subject: drm/nouveau: set encoder for lvds fixes oops in nouveau_connector_get_modes with nv_encoder is NULL Signed-off-by: Albert Damen Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 7919020..53700f8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -365,6 +365,7 @@ out: #endif drm_mode_connector_update_edid_property(connector, nv_connector->edid); + nouveau_connector_set_encoder(connector, nv_encoder); return status; } -- cgit v0.10.2 From 8f1a60868f4594bc5576cca8952635f475e8bec6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 28 Jun 2010 14:35:50 +1000 Subject: drm/nouveau: tidy connector/encoder creation a little Create connectors before encoders to avoid having to do another loop across encoder list whenever we create a new connector. This allows us to pass the connector to the encoder creation functions, and avoid using a create_resources() callback since we can now call it directly. This can also potentially modify the connector ordering on nv50. On cards where the DCB connector and encoder tables are in the same order, things will be unchanged. However, there's some cards where the ordering between the tables differ, and in one case, leads us to naming the connectors "wrongly". Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index adf4ec2..bd33a54 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -81,6 +81,7 @@ struct dcb_connector_table_entry { enum dcb_connector_type type; uint8_t index2; uint8_t gpio_tag; + void *drm; }; struct dcb_connector_table { diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 53700f8..13f2e1e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -729,66 +729,62 @@ nouveau_connector_funcs_lvds = { .force = nouveau_connector_force }; -int -nouveau_connector_create(struct drm_device *dev, - struct dcb_connector_table_entry *dcb) +struct drm_connector * +nouveau_connector_create(struct drm_device *dev, int index) { const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_connector *nv_connector = NULL; + struct dcb_connector_table_entry *dcb = NULL; struct drm_connector *connector; - struct drm_encoder *encoder; int type, ret = 0; NV_DEBUG_KMS(dev, "\n"); + if (index >= dev_priv->vbios.dcb.connector.entries) + return ERR_PTR(-EINVAL); + + dcb = &dev_priv->vbios.dcb.connector.entry[index]; + if (dcb->drm) + return dcb->drm; + switch (dcb->type) { - case DCB_CONNECTOR_NONE: - return 0; case DCB_CONNECTOR_VGA: - NV_INFO(dev, "Detected a VGA connector\n"); type = DRM_MODE_CONNECTOR_VGA; break; case DCB_CONNECTOR_TV_0: case DCB_CONNECTOR_TV_1: case DCB_CONNECTOR_TV_3: - NV_INFO(dev, "Detected a TV connector\n"); type = DRM_MODE_CONNECTOR_TV; break; case DCB_CONNECTOR_DVI_I: - NV_INFO(dev, "Detected a DVI-I connector\n"); type = DRM_MODE_CONNECTOR_DVII; break; case DCB_CONNECTOR_DVI_D: - NV_INFO(dev, "Detected a DVI-D connector\n"); type = DRM_MODE_CONNECTOR_DVID; break; case DCB_CONNECTOR_HDMI_0: case DCB_CONNECTOR_HDMI_1: - NV_INFO(dev, "Detected a HDMI connector\n"); type = DRM_MODE_CONNECTOR_HDMIA; break; case DCB_CONNECTOR_LVDS: - NV_INFO(dev, "Detected a LVDS connector\n"); type = DRM_MODE_CONNECTOR_LVDS; funcs = &nouveau_connector_funcs_lvds; break; case DCB_CONNECTOR_DP: - NV_INFO(dev, "Detected a DisplayPort connector\n"); type = DRM_MODE_CONNECTOR_DisplayPort; break; case DCB_CONNECTOR_eDP: - NV_INFO(dev, "Detected an eDP connector\n"); type = DRM_MODE_CONNECTOR_eDP; break; default: NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type); - return -EINVAL; + return ERR_PTR(-EINVAL); } nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); if (!nv_connector) - return -ENOMEM; + return ERR_PTR(-ENOMEM); nv_connector->dcb = dcb; connector = &nv_connector->base; @@ -799,24 +795,6 @@ nouveau_connector_create(struct drm_device *dev, drm_connector_init(dev, connector, funcs, type); drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); - /* attach encoders */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (nv_encoder->dcb->connector != dcb->index) - continue; - - if (get_slave_funcs(nv_encoder)) - get_slave_funcs(nv_encoder)->create_resources(encoder, connector); - - drm_mode_connector_attach_encoder(connector, encoder); - } - - if (!connector->encoder_ids[0]) { - NV_WARN(dev, " no encoders, ignoring\n"); - goto fail; - } - /* Check if we need dithering enabled */ if (dcb->type == DCB_CONNECTOR_LVDS) { bool dummy, is_24bit = false; @@ -877,11 +855,12 @@ nouveau_connector_create(struct drm_device *dev, } drm_sysfs_connector_add(connector); - return 0; + dcb->drm = connector; + return dcb->drm; fail: drm_connector_cleanup(connector); kfree(connector); - return ret; + return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index 4ef38ab..1ce3d91 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -49,7 +49,7 @@ static inline struct nouveau_connector *nouveau_connector( return container_of(con, struct nouveau_connector, base); } -int nouveau_connector_create(struct drm_device *, - struct dcb_connector_table_entry *); +struct drm_connector * +nouveau_connector_create(struct drm_device *, int index); #endif /* __NOUVEAU_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 20c5488..e3c8bd4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1072,13 +1072,13 @@ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); /* nv04_dac.c */ -extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry); +extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *); extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); extern int nv04_dac_output_offset(struct drm_encoder *encoder); extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); /* nv04_dfp.c */ -extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry); +extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *); extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent); extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent, int head, bool dl); @@ -1087,10 +1087,10 @@ extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode); /* nv04_tv.c */ extern int nv04_tv_identify(struct drm_device *dev, int i2c_index); -extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry); +extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *); /* nv17_tv.c */ -extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry); +extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *); /* nv04_display.c */ extern int nv04_display_create(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index e1df820..e4442e2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -71,8 +71,8 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc) struct nouveau_connector * nouveau_encoder_connector_get(struct nouveau_encoder *encoder); -int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry); -int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry); +int nv50_sor_create(struct drm_connector *, struct dcb_entry *); +int nv50_dac_create(struct drm_connector *, struct dcb_entry *); struct bit_displayport_encoder_table { uint32_t match; diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 1cb19e3..8066c56 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -501,11 +501,13 @@ static const struct drm_encoder_funcs nv04_dac_funcs = { .destroy = nv04_dac_destroy, }; -int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) +int +nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry) { const struct drm_encoder_helper_funcs *helper; - struct drm_encoder *encoder; struct nouveau_encoder *nv_encoder = NULL; + struct drm_device *dev = connector->dev; + struct drm_encoder *encoder; nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); if (!nv_encoder) @@ -527,5 +529,6 @@ int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) encoder->possible_crtcs = entry->heads; encoder->possible_clones = 0; + drm_mode_connector_attach_encoder(connector, encoder); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index 41634d4..3559d89 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -584,11 +584,12 @@ static const struct drm_encoder_funcs nv04_dfp_funcs = { .destroy = nv04_dfp_destroy, }; -int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) +int +nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry) { const struct drm_encoder_helper_funcs *helper; - struct drm_encoder *encoder; struct nouveau_encoder *nv_encoder = NULL; + struct drm_encoder *encoder; int type; switch (entry->type) { @@ -613,11 +614,12 @@ int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) nv_encoder->dcb = entry; nv_encoder->or = ffs(entry->or) - 1; - drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type); + drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type); drm_encoder_helper_add(encoder, helper); encoder->possible_crtcs = entry->heads; encoder->possible_clones = 0; + drm_mode_connector_attach_encoder(connector, encoder); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index c7898b4..b35b7ed 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -94,6 +94,7 @@ nv04_display_create(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct dcb_table *dcb = &dev_priv->vbios.dcb; + struct drm_connector *connector, *ct; struct drm_encoder *encoder; struct drm_crtc *crtc; int i, ret; @@ -132,19 +133,23 @@ nv04_display_create(struct drm_device *dev) for (i = 0; i < dcb->entries; i++) { struct dcb_entry *dcbent = &dcb->entry[i]; + connector = nouveau_connector_create(dev, dcbent->connector); + if (IS_ERR(connector)) + continue; + switch (dcbent->type) { case OUTPUT_ANALOG: - ret = nv04_dac_create(dev, dcbent); + ret = nv04_dac_create(connector, dcbent); break; case OUTPUT_LVDS: case OUTPUT_TMDS: - ret = nv04_dfp_create(dev, dcbent); + ret = nv04_dfp_create(connector, dcbent); break; case OUTPUT_TV: if (dcbent->location == DCB_LOC_ON_CHIP) - ret = nv17_tv_create(dev, dcbent); + ret = nv17_tv_create(connector, dcbent); else - ret = nv04_tv_create(dev, dcbent); + ret = nv04_tv_create(connector, dcbent); break; default: NV_WARN(dev, "DCB type %d not known\n", dcbent->type); @@ -155,8 +160,14 @@ nv04_display_create(struct drm_device *dev) continue; } - for (i = 0; i < dcb->connector.entries; i++) - nouveau_connector_create(dev, &dcb->connector.entry[i]); + list_for_each_entry_safe(connector, ct, + &dev->mode_config.connector_list, head) { + if (!connector->encoder_ids[0]) { + NV_WARN(dev, "%s has no encoders, removing\n", + drm_get_connector_name(connector)); + connector->funcs->destroy(connector); + } + } /* Save previous state */ NVLockVgaCrtcs(dev, false); diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index c4e3404..84b5954 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c @@ -223,10 +223,12 @@ static void nv04_tv_destroy(struct drm_encoder *encoder) kfree(nv_encoder); } -int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) +int +nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) { struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; + struct drm_device *dev = connector->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct i2c_adapter *adap; struct drm_encoder_funcs *funcs = NULL; @@ -266,7 +268,7 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) was_locked = NVLockVgaCrtcs(dev, false); - ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap, + ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), adap, &nv04_tv_encoder_info[type].board_info); NVLockVgaCrtcs(dev, was_locked); @@ -294,7 +296,9 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) /* Set the slave encoder configuration */ sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params); + sfuncs->create_resources(encoder, connector); + drm_mode_connector_attach_encoder(connector, encoder); return 0; fail: diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 74c8803..44437ff 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -744,8 +744,10 @@ static struct drm_encoder_funcs nv17_tv_funcs = { .destroy = nv17_tv_destroy, }; -int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry) +int +nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry) { + struct drm_device *dev = connector->dev; struct drm_encoder *encoder; struct nv17_tv_encoder *tv_enc = NULL; @@ -774,5 +776,7 @@ int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry) encoder->possible_crtcs = entry->heads; encoder->possible_clones = 0; + nv17_tv_create_resources(encoder, connector); + drm_mode_connector_attach_encoder(connector, encoder); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index 1fd9537..e114f81 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c @@ -275,14 +275,11 @@ static const struct drm_encoder_funcs nv50_dac_encoder_funcs = { }; int -nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) +nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry) { struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; - NV_DEBUG_KMS(dev, "\n"); - NV_INFO(dev, "Detected a DAC output\n"); - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); if (!nv_encoder) return -ENOMEM; @@ -293,12 +290,14 @@ nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) nv_encoder->disconnect = nv50_dac_disconnect; - drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs, + drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs, DRM_MODE_ENCODER_DAC); drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); encoder->possible_crtcs = entry->heads; encoder->possible_clones = 0; + + drm_mode_connector_attach_encoder(connector, encoder); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 515edde..e031904 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -465,6 +465,7 @@ int nv50_display_create(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct dcb_table *dcb = &dev_priv->vbios.dcb; + struct drm_connector *connector, *ct; int ret, i; NV_DEBUG_KMS(dev, "\n"); @@ -507,14 +508,18 @@ int nv50_display_create(struct drm_device *dev) continue; } + connector = nouveau_connector_create(dev, entry->connector); + if (IS_ERR(connector)) + continue; + switch (entry->type) { case OUTPUT_TMDS: case OUTPUT_LVDS: case OUTPUT_DP: - nv50_sor_create(dev, entry); + nv50_sor_create(connector, entry); break; case OUTPUT_ANALOG: - nv50_dac_create(dev, entry); + nv50_dac_create(connector, entry); break; default: NV_WARN(dev, "DCB encoder %d unknown\n", entry->type); @@ -522,11 +527,13 @@ int nv50_display_create(struct drm_device *dev) } } - for (i = 0 ; i < dcb->connector.entries; i++) { - if (i != 0 && dcb->connector.entry[i].index2 == - dcb->connector.entry[i - 1].index2) - continue; - nouveau_connector_create(dev, &dcb->connector.entry[i]); + list_for_each_entry_safe(connector, ct, + &dev->mode_config.connector_list, head) { + if (!connector->encoder_ids[0]) { + NV_WARN(dev, "%s has no encoders, removing\n", + drm_get_connector_name(connector)); + connector->funcs->destroy(connector); + } } ret = nv50_display_init(dev); diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 812778d..4832bba 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -272,32 +272,22 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { }; int -nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) +nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry) { struct nouveau_encoder *nv_encoder = NULL; + struct drm_device *dev = connector->dev; struct drm_encoder *encoder; - bool dum; int type; NV_DEBUG_KMS(dev, "\n"); switch (entry->type) { case OUTPUT_TMDS: - NV_INFO(dev, "Detected a TMDS output\n"); + case OUTPUT_DP: type = DRM_MODE_ENCODER_TMDS; break; case OUTPUT_LVDS: - NV_INFO(dev, "Detected a LVDS output\n"); type = DRM_MODE_ENCODER_LVDS; - - if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) { - NV_ERROR(dev, "Failed parsing LVDS table\n"); - return -EINVAL; - } - break; - case OUTPUT_DP: - NV_INFO(dev, "Detected a DP output\n"); - type = DRM_MODE_ENCODER_TMDS; break; default: return -EINVAL; @@ -342,5 +332,6 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) nv_encoder->dp.mc_unknown = 5; } + drm_mode_connector_attach_encoder(connector, encoder); return 0; } -- cgit v0.10.2 From 309b8c89c8ddf9dd8e5f253c185d6af1d0358a79 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 29 Jun 2010 16:09:24 +1000 Subject: drm/nouveau: downgrade severity of most init table parser errors As long as we know the length of the opcode, we're probably better off trying to parse the remainder of an init table rather than aborting in the middle of it. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index ed0f530..2e8cdd7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -935,7 +935,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, NV_ERROR(bios->dev, "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", offset, config, count); - return -EINVAL; + return len; } configval = ROM32(bios->data[offset + 11 + config * 4]); @@ -1037,7 +1037,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, NV_ERROR(bios->dev, "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", offset, config, count); - return -EINVAL; + return len; } freq = ROM16(bios->data[offset + 12 + config * 2]); @@ -1209,7 +1209,7 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) dpe = nouveau_bios_dp_table(dev, dcb, &dummy); if (!dpe) { NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset); - return -EINVAL; + return 3; } switch (cond) { @@ -1233,12 +1233,16 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) int ret; auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index); - if (!auxch) - return -ENODEV; + if (!auxch) { + NV_ERROR(dev, "0x%04X: couldn't get auxch\n", offset); + return 3; + } ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1); - if (ret) - return ret; + if (ret) { + NV_ERROR(dev, "0x%04X: auxch rd fail: %d\n", offset, ret); + return 3; + } if (cond & 1) iexec->execute = false; @@ -1407,7 +1411,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, NV_ERROR(bios->dev, "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", offset, config, count); - return -EINVAL; + return len; } freq = ROM32(bios->data[offset + 11 + config * 4]); @@ -1467,6 +1471,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * "mask n" and OR it with "data n" before writing it back to the device */ + struct drm_device *dev = bios->dev; uint8_t i2c_index = bios->data[offset + 1]; uint8_t i2c_address = bios->data[offset + 2] >> 1; uint8_t count = bios->data[offset + 3]; @@ -1481,9 +1486,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) "Count: 0x%02X\n", offset, i2c_index, i2c_address, count); - chan = init_i2c_device_find(bios->dev, i2c_index); - if (!chan) - return -ENODEV; + chan = init_i2c_device_find(dev, i2c_index); + if (!chan) { + NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); + return len; + } for (i = 0; i < count; i++) { uint8_t reg = bios->data[offset + 4 + i * 3]; @@ -1494,8 +1501,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, &val); - if (ret < 0) - return ret; + if (ret < 0) { + NV_ERROR(dev, "0x%04X: i2c rd fail: %d\n", offset, ret); + return len; + } BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " "Mask: 0x%02X, Data: 0x%02X\n", @@ -1509,8 +1518,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &val); - if (ret < 0) - return ret; + if (ret < 0) { + NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); + return len; + } } return len; @@ -1535,6 +1546,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * "DCB I2C table entry index", set the register to "data n" */ + struct drm_device *dev = bios->dev; uint8_t i2c_index = bios->data[offset + 1]; uint8_t i2c_address = bios->data[offset + 2] >> 1; uint8_t count = bios->data[offset + 3]; @@ -1549,9 +1561,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) "Count: 0x%02X\n", offset, i2c_index, i2c_address, count); - chan = init_i2c_device_find(bios->dev, i2c_index); - if (!chan) - return -ENODEV; + chan = init_i2c_device_find(dev, i2c_index); + if (!chan) { + NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); + return len; + } for (i = 0; i < count; i++) { uint8_t reg = bios->data[offset + 4 + i * 2]; @@ -1568,8 +1582,10 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &val); - if (ret < 0) - return ret; + if (ret < 0) { + NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); + return len; + } } return len; @@ -1592,6 +1608,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * address" on the I2C bus given by "DCB I2C table entry index" */ + struct drm_device *dev = bios->dev; uint8_t i2c_index = bios->data[offset + 1]; uint8_t i2c_address = bios->data[offset + 2] >> 1; uint8_t count = bios->data[offset + 3]; @@ -1599,7 +1616,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) struct nouveau_i2c_chan *chan; struct i2c_msg msg; uint8_t data[256]; - int i; + int ret, i; if (!iexec->execute) return len; @@ -1608,9 +1625,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) "Count: 0x%02X\n", offset, i2c_index, i2c_address, count); - chan = init_i2c_device_find(bios->dev, i2c_index); - if (!chan) - return -ENODEV; + chan = init_i2c_device_find(dev, i2c_index); + if (!chan) { + NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); + return len; + } for (i = 0; i < count; i++) { data[i] = bios->data[offset + 4 + i]; @@ -1623,8 +1642,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) msg.flags = 0; msg.len = count; msg.buf = data; - if (i2c_transfer(&chan->adapter, &msg, 1) != 1) - return -EIO; + ret = i2c_transfer(&chan->adapter, &msg, 1); + if (ret != 1) { + NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); + return len; + } } return len; @@ -1648,6 +1670,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * used -- see get_tmds_index_reg() */ + struct drm_device *dev = bios->dev; uint8_t mlv = bios->data[offset + 1]; uint32_t tmdsaddr = bios->data[offset + 2]; uint8_t mask = bios->data[offset + 3]; @@ -1662,8 +1685,10 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) offset, mlv, tmdsaddr, mask, data); reg = get_tmds_index_reg(bios->dev, mlv); - if (!reg) - return -EINVAL; + if (!reg) { + NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset); + return 5; + } bios_wr32(bios, reg, tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); @@ -1693,6 +1718,7 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, * register is used -- see get_tmds_index_reg() */ + struct drm_device *dev = bios->dev; uint8_t mlv = bios->data[offset + 1]; uint8_t count = bios->data[offset + 2]; int len = 3 + count * 2; @@ -1706,8 +1732,10 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, offset, mlv, count); reg = get_tmds_index_reg(bios->dev, mlv); - if (!reg) - return -EINVAL; + if (!reg) { + NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset); + return len; + } for (i = 0; i < count; i++) { uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; @@ -2816,7 +2844,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) if (dev_priv->card_type != NV_50) { NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n"); - return -ENODEV; + return 1; } if (!iexec->execute) @@ -2888,10 +2916,7 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, uint8_t index; int i; - - if (!iexec->execute) - return len; - + /* critical! to know the length of the opcode */; if (!blocklen) { NV_ERROR(bios->dev, "0x%04X: Zero block length - has the M table " @@ -2899,6 +2924,9 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, return -EINVAL; } + if (!iexec->execute) + return len; + strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg]; @@ -3080,14 +3108,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) if (!bios->display.output) { NV_ERROR(dev, "INIT_AUXCH: no active output\n"); - return -EINVAL; + return len; } auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); if (!auxch) { NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", bios->display.output->i2c_index); - return -ENODEV; + return len; } if (!iexec->execute) @@ -3100,7 +3128,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); if (ret) { NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); - return ret; + return len; } data &= bios->data[offset + 0]; @@ -3109,7 +3137,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); if (ret) { NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); - return ret; + return len; } } @@ -3139,14 +3167,14 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) if (!bios->display.output) { NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); - return -EINVAL; + return len; } auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); if (!auxch) { NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", bios->display.output->i2c_index); - return -ENODEV; + return len; } if (!iexec->execute) @@ -3157,7 +3185,7 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); if (ret) { NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); - return ret; + return len; } } -- cgit v0.10.2 From 7149eee87a020cb81c52e9653a44c5f9e7c2a0d9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 30 Jun 2010 15:25:57 +1000 Subject: drm/nv50: fix DP->DVI if output has been programmed for native DP previously Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index 6ca80a3..b6391a1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -814,6 +814,7 @@ #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff #define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) +#define NV50_SOR_DP_CTRL_ENABLED 0x00000001 #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 #define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000 #define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000 diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index e031904..0c76204 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -821,6 +821,36 @@ nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb) } } +/* If programming a TMDS output on a SOR that can also be configured for + * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. + * + * It looks like the VBIOS TMDS scripts make an attempt at this, however, + * the VBIOS scripts on at least one board I have only switch it off on + * link 0, causing a blank display if the output has previously been + * programmed for DisplayPort. + */ +static void +nv50_display_unk20_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) +{ + int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1); + struct drm_encoder *encoder; + u32 tmp; + + if (dcb->type != OUTPUT_TMDS) + return; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + + if (nv_encoder->dcb->type == OUTPUT_DP) { + tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)); + tmp &= ~NV50_SOR_DP_CTRL_ENABLED; + nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp); + break; + } + } +} + static void nv50_display_unk20_handler(struct drm_device *dev) { @@ -845,6 +875,7 @@ nv50_display_unk20_handler(struct drm_device *dev) nouveau_bios_run_display_table(dev, dcbent, script, pclk); nv50_display_unk20_dp_hack(dev, dcbent); + nv50_display_unk20_dp_set_tmds(dev, dcbent); tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head)); tmp &= ~0x000000f; -- cgit v0.10.2 From df4cf1b72d726d788388858673fa61e42fdb9ad8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 1 Jul 2010 11:31:45 +1000 Subject: drm/nv50: DCB quirk for Dell M6300 Uncertain if this is a weirdo configuration, or a BIOS bug. If it's not a BIOS bug, we still don't know how to make it work anyway so ignore a "conflicting" DCB entry to prevent a display hang. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 2e8cdd7..3e274d5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5841,6 +5841,31 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb) dcb->entries = newentries; } +static bool +apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) +{ + /* Dell Precision M6300 + * DCB entry 2: 02025312 00000010 + * DCB entry 3: 02026312 00000020 + * + * Identical, except apparently a different connector on a + * different SOR link. Not a clue how we're supposed to know + * which one is in use if it even shares an i2c line... + * + * Ignore the connector on the second SOR link to prevent + * nasty problems until this is sorted (assuming it's not a + * VBIOS bug). + */ + if ((dev->pdev->device == 0x040d) && + (dev->pdev->subsystem_vendor == 0x1028) && + (dev->pdev->subsystem_device == 0x019b)) { + if (*conn == 0x02026312 && *conf == 0x00000020) + return false; + } + + return true; +} + static int parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) { @@ -5974,6 +5999,9 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) if ((connection & 0x0000000f) == 0x0000000f) continue; + if (!apply_dcb_encoder_quirks(dev, i, &connection, &config)) + continue; + NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n", dcb->entries, connection, config); -- cgit v0.10.2 From ec7fc4a1a7b322380d053fb04bfc4537be3cdfe5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 1 Jul 2010 15:33:45 +1000 Subject: drm/nv50: supply encoder disable() hook for SOR outputs Allows us to remove a driver hack that used to be necessary to disable encoders in certain situations before setting up a mode. The DRM has better knowledge of when this is needed than the driver does. This fixes a number of display switching issues. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index e4442e2..a1a0d48 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -38,13 +38,15 @@ struct nouveau_encoder { struct dcb_entry *dcb; int or; + /* different to drm_encoder.crtc, this reflects what's + * actually programmed on the hw, not the proposed crtc */ + struct drm_crtc *crtc; + struct drm_display_mode mode; int last_dpms; struct nv04_output_reg restore; - void (*disconnect)(struct nouveau_encoder *encoder); - union { struct { int mc_unknown; diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index b4e4a3b..fb3ed5d 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -440,40 +440,9 @@ nv50_crtc_prepare(struct drm_crtc *crtc) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct drm_device *dev = crtc->dev; - struct drm_encoder *encoder; - uint32_t dac = 0, sor = 0; NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); - /* Disconnect all unused encoders. */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (!drm_helper_encoder_in_use(encoder)) - continue; - - if (nv_encoder->dcb->type == OUTPUT_ANALOG || - nv_encoder->dcb->type == OUTPUT_TV) - dac |= (1 << nv_encoder->or); - else - sor |= (1 << nv_encoder->or); - } - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (nv_encoder->dcb->type == OUTPUT_ANALOG || - nv_encoder->dcb->type == OUTPUT_TV) { - if (dac & (1 << nv_encoder->or)) - continue; - } else { - if (sor & (1 << nv_encoder->or)) - continue; - } - - nv_encoder->disconnect(nv_encoder); - } - nv50_crtc_blank(nv_crtc, true); } diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index e114f81..f5fd35a 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c @@ -37,13 +37,17 @@ #include "nv50_display.h" static void -nv50_dac_disconnect(struct nouveau_encoder *nv_encoder) +nv50_dac_disconnect(struct drm_encoder *encoder) { - struct drm_device *dev = to_drm_encoder(nv_encoder)->dev; + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *evo = dev_priv->evo; int ret; + if (!nv_encoder->crtc) + return; + NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); ret = RING_SPACE(evo, 2); @@ -53,6 +57,8 @@ nv50_dac_disconnect(struct nouveau_encoder *nv_encoder) } BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); OUT_RING(evo, 0); + + nv_encoder->crtc = NULL; } static enum drm_connector_status @@ -243,6 +249,8 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2); OUT_RING(evo, mode_ctl); OUT_RING(evo, mode_ctl2); + + nv_encoder->crtc = encoder->crtc; } static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { @@ -253,7 +261,8 @@ static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { .prepare = nv50_dac_prepare, .commit = nv50_dac_commit, .mode_set = nv50_dac_mode_set, - .detect = nv50_dac_detect + .detect = nv50_dac_detect, + .disable = nv50_dac_disconnect }; static void @@ -288,8 +297,6 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry) nv_encoder->dcb = entry; nv_encoder->or = ffs(entry->or) - 1; - nv_encoder->disconnect = nv50_dac_disconnect; - drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs, DRM_MODE_ENCODER_DAC); drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 4832bba..b259d63 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -37,13 +37,17 @@ #include "nv50_display.h" static void -nv50_sor_disconnect(struct nouveau_encoder *nv_encoder) +nv50_sor_disconnect(struct drm_encoder *encoder) { - struct drm_device *dev = to_drm_encoder(nv_encoder)->dev; + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *evo = dev_priv->evo; int ret; + if (!nv_encoder->crtc) + return; + NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); ret = RING_SPACE(evo, 2); @@ -53,6 +57,9 @@ nv50_sor_disconnect(struct nouveau_encoder *nv_encoder) } BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); OUT_RING(evo, 0); + + nv_encoder->crtc = NULL; + nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; } static void @@ -94,14 +101,16 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) uint32_t val; int or = nv_encoder->or; - NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); + NV_DEBUG_KMS(dev, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode); nv_encoder->last_dpms = mode; list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { struct nouveau_encoder *nvenc = nouveau_encoder(enc); if (nvenc == nv_encoder || - nvenc->disconnect != nv50_sor_disconnect || + (nvenc->dcb->type != OUTPUT_TMDS && + nvenc->dcb->type != OUTPUT_LVDS && + nvenc->dcb->type != OUTPUT_DP) || nvenc->dcb->or != nv_encoder->dcb->or) continue; @@ -239,6 +248,14 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, } BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); OUT_RING(evo, mode_ctl); + + nv_encoder->crtc = encoder->crtc; +} + +static struct drm_crtc * +nv50_sor_crtc_get(struct drm_encoder *encoder) +{ + return nouveau_encoder(encoder)->crtc; } static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { @@ -249,7 +266,9 @@ static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { .prepare = nv50_sor_prepare, .commit = nv50_sor_commit, .mode_set = nv50_sor_mode_set, - .detect = NULL + .get_crtc = nv50_sor_crtc_get, + .detect = NULL, + .disable = nv50_sor_disconnect }; static void @@ -300,8 +319,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry) nv_encoder->dcb = entry; nv_encoder->or = ffs(entry->or) - 1; - - nv_encoder->disconnect = nv50_sor_disconnect; + nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type); drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs); -- cgit v0.10.2 From 044129212eca1c00707f35fc46392d76ced61a94 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 2 Jul 2010 13:47:38 +1000 Subject: drm/nv50: when debugging on, log which crtc we connect an encoder to Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index f5fd35a..98d3126 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c @@ -219,7 +219,8 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, uint32_t mode_ctl = 0, mode_ctl2 = 0; int ret; - NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); + NV_DEBUG_KMS(dev, "or %d type %d crtc %d\n", + nv_encoder->or, nv_encoder->dcb->type, crtc->index); nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index b259d63..03cb021 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -205,7 +205,8 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, uint32_t mode_ctl = 0; int ret; - NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); + NV_DEBUG_KMS(dev, "or %d type %d -> crtc %d\n", + nv_encoder->or, nv_encoder->dcb->type, crtc->index); nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); -- cgit v0.10.2 From be8860ac0c99c4cd67dfc364c6f57d299f8d7e9d Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 3 Jul 2010 12:47:14 +0200 Subject: drm/nv17-nv40: Avoid using active CRTCs for load detection. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 8066c56..bcc8090 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -261,12 +261,11 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); head = (saved_routput & 0x100) >> 8; -#if 0 - /* if there's a spare crtc, using it will minimise flicker for the case - * where the in-use crtc is in use by an off-chip tmds encoder */ - if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled) + + /* if there's a spare crtc, using it will minimise flicker */ + if (!(NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX) & 0xC0)) head ^= 1; -#endif + /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ routput = (saved_routput & 0xfffffece) | head << 8; -- cgit v0.10.2 From 8ccfe9e098d5975ef65d17de477f6b7dc0c446db Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 4 Jul 2010 16:14:42 +0200 Subject: drm/nv04-nv40: Prevent invalid DAC/TVDAC combinations. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e3c8bd4..565981d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1076,6 +1076,7 @@ extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *); extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); extern int nv04_dac_output_offset(struct drm_encoder *encoder); extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); +extern bool nv04_dac_in_use(struct drm_encoder *encoder); /* nv04_dfp.c */ extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *); diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index bcc8090..2d0fee5 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -314,9 +314,12 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct drm_device *dev = encoder->dev; struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - uint32_t sample = nv17_dac_sample_load(encoder); - if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { + if (nv04_dac_in_use(encoder)) + return connector_status_disconnected; + + if (nv17_dac_sample_load(encoder) & + NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { NV_INFO(dev, "Load detected on output %c\n", '@' + ffs(dcb->or)); return connector_status_connected; @@ -329,6 +332,9 @@ static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { + if (nv04_dac_in_use(encoder)) + return false; + return true; } @@ -427,6 +433,17 @@ void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) } } +/* Check if the DAC corresponding to 'encoder' is being used by + * someone else. */ +bool nv04_dac_in_use(struct drm_encoder *encoder) +{ + struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; + struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; + + return nv_gf4_disp_arch(encoder->dev) && + (dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index)); +} + static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 44437ff..864867e 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -125,6 +125,9 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); struct dcb_entry *dcb = tv_enc->base.dcb; + if (nv04_dac_in_use(encoder)) + return connector_status_disconnected; + if (dev_priv->chipset == 0x42 || dev_priv->chipset == 0x43) tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe; @@ -296,6 +299,9 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, { struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); + if (nv04_dac_in_use(encoder)) + return false; + if (tv_norm->kind == CTV_ENC_MODE) adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock; else -- cgit v0.10.2 From 2ed06b7d974a750ccb90ff88f5b7a870b89db966 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 3 Jul 2010 15:52:03 +0200 Subject: drm/nv04-nv40: Disable connector polling when there're no spare CRTCs left. Load detection needs the connector wired to a CRTC, when there are no inactive CRTCs left that means we need to cut some other head off for a while, causing intermittent flickering. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 13f2e1e..c2524ca 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -698,6 +698,44 @@ nouveau_connector_best_encoder(struct drm_connector *connector) return NULL; } +void +nouveau_connector_set_polling(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + bool spare_crtc = false; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + spare_crtc |= !crtc->enabled; + + connector->polled = 0; + + switch (connector->connector_type) { + case DRM_MODE_CONNECTOR_VGA: + case DRM_MODE_CONNECTOR_TV: + if (dev_priv->card_type >= NV_50 || + (nv_gf4_disp_arch(dev) && spare_crtc)) + connector->polled = DRM_CONNECTOR_POLL_CONNECT; + break; + + case DRM_MODE_CONNECTOR_DVII: + case DRM_MODE_CONNECTOR_DVID: + case DRM_MODE_CONNECTOR_HDMIA: + case DRM_MODE_CONNECTOR_DisplayPort: + case DRM_MODE_CONNECTOR_eDP: + if (dev_priv->card_type >= NV_50) + connector->polled = DRM_CONNECTOR_POLL_HPD; + else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID || + spare_crtc) + connector->polled = DRM_CONNECTOR_POLL_CONNECT; + break; + + default: + break; + } +} + static const struct drm_connector_helper_funcs nouveau_connector_helper_funcs = { .get_modes = nouveau_connector_get_modes, @@ -818,7 +856,6 @@ nouveau_connector_create(struct drm_device *dev, int index) switch (dcb->type) { case DCB_CONNECTOR_VGA: - connector->polled = DRM_CONNECTOR_POLL_CONNECT; if (dev_priv->card_type >= NV_50) { drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, @@ -830,17 +867,6 @@ nouveau_connector_create(struct drm_device *dev, int index) case DCB_CONNECTOR_TV_3: nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; break; - case DCB_CONNECTOR_DP: - case DCB_CONNECTOR_eDP: - case DCB_CONNECTOR_HDMI_0: - case DCB_CONNECTOR_HDMI_1: - case DCB_CONNECTOR_DVI_I: - case DCB_CONNECTOR_DVI_D: - if (dev_priv->card_type >= NV_50) - connector->polled = DRM_CONNECTOR_POLL_HPD; - else - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - /* fall-through */ default: nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; @@ -854,6 +880,8 @@ nouveau_connector_create(struct drm_device *dev, int index) break; } + nouveau_connector_set_polling(connector); + drm_sysfs_connector_add(connector); dcb->drm = connector; return dcb->drm; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index 1ce3d91..0d2e668 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -52,4 +52,7 @@ static inline struct nouveau_connector *nouveau_connector( struct drm_connector * nouveau_connector_create(struct drm_device *, int index); +void +nouveau_connector_set_polling(struct drm_connector *); + #endif /* __NOUVEAU_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index eba687f1..1c20c08 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -157,6 +157,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct drm_device *dev = crtc->dev; + struct drm_connector *connector; unsigned char seq1 = 0, crtc17 = 0; unsigned char crtc1A; @@ -211,6 +212,10 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) NVVgaSeqReset(dev, nv_crtc->index, false); NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); + + /* Update connector polling modes */ + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + nouveau_connector_set_polling(connector); } static bool -- cgit v0.10.2 From 6e86e0419471d11ed3d4d46039ee90e8cb85806c Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 3 Jul 2010 18:36:39 +0200 Subject: drm/nouveau: Fix a couple of sparse warnings. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index d4bcca8..381d385 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -42,7 +42,7 @@ static const char nouveau_dsm_muid[] = { 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, }; -static int nouveau_dsm(acpi_handle handle, int func, int arg, int *result) +static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) { struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_object_list input; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index c2524ca..464b3dc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -585,7 +585,6 @@ nouveau_connector_get_modes(struct drm_connector *connector) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; - struct drm_display_mode mode; int ret = 0; /* destroy the native mode, the attached monitor could have changed. @@ -600,9 +599,9 @@ nouveau_connector_get_modes(struct drm_connector *connector) else if (nv_encoder->dcb->type == OUTPUT_LVDS && (nv_encoder->dcb->lvdsconf.use_straps_for_mode || - dev_priv->vbios.fp_no_ddc) && - nouveau_bios_fp_mode(dev, &mode)) { - nv_connector->native_mode = drm_mode_duplicate(dev, &mode); + dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { + nv_connector->native_mode = drm_mode_create(dev); + nouveau_bios_fp_mode(dev, nv_connector->native_mode); } /* Find the native mode if this is a digital panel, if we didn't diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 6edfc23..2171dc8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -317,7 +317,6 @@ nouveau_pci_resume(struct pci_dev *pdev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - int ret; ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); if (!ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index c9a4a0d..728f555 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -333,7 +333,7 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev) drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper); } -int +static int nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev) { struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 69c76cf..791531b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -577,7 +577,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, struct drm_nouveau_gem_pushbuf_bo *bo; struct nouveau_channel *chan; struct validate_op op; - struct nouveau_fence *fence = 0; + struct nouveau_fence *fence = NULL; int i, j, ret = 0, do_reloc = 0; NOUVEAU_CHECK_INITIALISED_WITH_RETURN; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 2853ba0..4b42bf2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -371,7 +371,7 @@ nouveau_mem_detect(struct drm_device *dev) } else { dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; - dev_priv->vram_size &= 0xffffffff00; + dev_priv->vram_size &= 0xffffffff00ll; if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) { dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); dev_priv->vram_sys_base <<= 12; diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index 66fe559..611c83e 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c @@ -112,6 +112,12 @@ nv04_fifo_channel_id(struct drm_device *dev) NV03_PFIFO_CACHE1_PUSH1_CHID_MASK; } +#ifdef __BIG_ENDIAN +#define DMA_FETCH_ENDIANNESS NV_PFIFO_CACHE1_BIG_ENDIAN +#else +#define DMA_FETCH_ENDIANNESS 0 +#endif + int nv04_fifo_create_context(struct nouveau_channel *chan) { @@ -138,10 +144,7 @@ nv04_fifo_create_context(struct nouveau_channel *chan) RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0)); + DMA_FETCH_ENDIANNESS)); dev_priv->engine.instmem.finish_access(dev); /* enable the fifo dma operation */ diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 618355e..dd09679 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -342,7 +342,7 @@ static uint32_t nv04_graph_ctx_regs[] = { }; struct graph_state { - int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; + uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; }; struct nouveau_channel * diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index b203d06..b04e7c8 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -212,7 +212,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; - struct nouveau_gpuobj *ctx; + struct nouveau_gpuobj *obj; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; int hdr, ret; @@ -223,7 +223,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); if (ret) return ret; - ctx = chan->ramin_grctx->gpuobj; + obj = chan->ramin_grctx->gpuobj; hdr = IS_G80 ? 0x200 : 0x20; dev_priv->engine.instmem.prepare_access(dev, true); @@ -241,12 +241,12 @@ nv50_graph_create_context(struct nouveau_channel *chan) struct nouveau_grctx ctx = {}; ctx.dev = chan->dev; ctx.mode = NOUVEAU_GRCTX_VALS; - ctx.data = chan->ramin_grctx->gpuobj; + ctx.data = obj; nv50_grctx_init(&ctx); } else { - nouveau_grctx_vals_load(dev, ctx); + nouveau_grctx_vals_load(dev, obj); } - nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); + nv_wo32(dev, obj, 0x00000/4, chan->ramin->instance >> 12); dev_priv->engine.instmem.finish_access(dev); return 0; -- cgit v0.10.2 From ae55321c50434a57fca62aa9b243d575f0de8e6b Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 3 Jul 2010 20:47:44 +0200 Subject: drm/nouveau: INIT_CONFIGURE_PREINIT/CLK/MEM on newer BIOSes is not an error. No need to spam the logs when they're found, they're equivalent to INIT_DONE. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 3e274d5..e05f129 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -2211,7 +2211,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, uint32_t reg, data; if (bios->major_version > 2) - return -ENODEV; + return 0; bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); @@ -2266,7 +2266,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset, int clock; if (bios->major_version > 2) - return -ENODEV; + return 0; clock = ROM16(bios->data[meminitoffs + 4]) * 10; setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); @@ -2299,7 +2299,7 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset, uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); if (bios->major_version > 2) - return -ENODEV; + return 0; bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX, cr3c); -- cgit v0.10.2 From d3f12da1c5effa7853bdde31f0ea02f6c604dd04 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 4 Jul 2010 04:03:48 +0200 Subject: drm/nv04-nv40: Drop redundant logging. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index 3559d89..3311f3a 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -413,10 +413,6 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) struct dcb_entry *dcbe = nv_encoder->dcb; int head = nouveau_crtc(encoder->crtc)->index; - NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), - nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); - if (dcbe->type == OUTPUT_TMDS) run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); else if (dcbe->type == OUTPUT_LVDS) -- cgit v0.10.2 From 311ab6943fad769a1435bb375d3c821f3b41cdde Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 4 Jul 2010 12:54:23 +0200 Subject: drm/nouveau: Move the fence wait before migration resource clean-up. Avoids an oops in the fence wait failure path (bug 26521). Signed-off-by: Francisco Jerez Tested-by: Marcin Slusarz Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 9f5ab46..1371c77 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -461,9 +461,9 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, return ret; ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, - evict, no_wait_reserve, no_wait_gpu, new_mem); - if (nvbo->channel && nvbo->channel != chan) - ret = nouveau_fence_wait(fence, NULL, false, false); + evict || (nvbo->channel && + nvbo->channel != chan), + no_wait_reserve, no_wait_gpu, new_mem); nouveau_fence_unref((void *)&fence); return ret; } -- cgit v0.10.2 From 4664c67b5d054012562a74414ed3f8619912b3d1 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 4 Jul 2010 16:46:01 +0200 Subject: drm/nouveau: Workaround broken TV load detection on a "Zotac FX5200". The blob seems to have the same problem so it's probably a hardware issue (bug 28810). Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 864867e..359506e 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -116,6 +116,20 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) return sample; } +static bool +get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) +{ + /* Zotac FX5200 */ + if ((dev->pdev->device == 0x0322) && + (dev->pdev->subsystem_vendor == 0x19da) && + (dev->pdev->subsystem_device == 0x2035)) { + *pin_mask = 0xc; + return false; + } + + return true; +} + static enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) { @@ -124,15 +138,20 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) struct drm_mode_config *conf = &dev->mode_config; struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); struct dcb_entry *dcb = tv_enc->base.dcb; + bool reliable = get_tv_detect_quirks(dev, &tv_enc->pin_mask); if (nv04_dac_in_use(encoder)) return connector_status_disconnected; - if (dev_priv->chipset == 0x42 || - dev_priv->chipset == 0x43) - tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe; - else - tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe; + if (reliable) { + if (dev_priv->chipset == 0x42 || + dev_priv->chipset == 0x43) + tv_enc->pin_mask = + nv42_tv_sample_load(encoder) >> 28 & 0xe; + else + tv_enc->pin_mask = + nv17_dac_sample_load(encoder) >> 28 & 0xe; + } switch (tv_enc->pin_mask) { case 0x2: @@ -157,7 +176,9 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) conf->tv_subconnector_property, tv_enc->subconnector); - if (tv_enc->subconnector) { + if (!reliable) { + return connector_status_unknown; + } else if (tv_enc->subconnector) { NV_INFO(dev, "Load detected on output %c\n", '@' + ffs(dcb->or)); return connector_status_connected; -- cgit v0.10.2 From 835aadbef3b762bc43eceddfec90c9a5a312d3c1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 5 Jul 2010 15:19:16 +1000 Subject: drm/nv50: send evo "update" command after each disconnect It turns out that the display engine signals an interrupt for disconnects too. In order to make it easier to process the display interrupts correctly, we want to ensure we only get one operation per interrupt sequence - this is what this commit achieves. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index fb3ed5d..5d11ea1 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -449,7 +449,6 @@ nv50_crtc_prepare(struct drm_crtc *crtc) static void nv50_crtc_commit(struct drm_crtc *crtc) { - struct drm_crtc *crtc2; struct drm_device *dev = crtc->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *evo = dev_priv->evo; @@ -460,20 +459,14 @@ nv50_crtc_commit(struct drm_crtc *crtc) nv50_crtc_blank(nv_crtc, false); - /* Explicitly blank all unused crtc's. */ - list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) { - if (!drm_helper_crtc_in_use(crtc2)) - nv50_crtc_blank(nouveau_crtc(crtc2), true); - } - ret = RING_SPACE(evo, 2); if (ret) { NV_ERROR(dev, "no space while committing crtc\n"); return; } BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); - OUT_RING(evo, 0); - FIRE_RING(evo); + OUT_RING (evo, 0); + FIRE_RING (evo); } static bool diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index 98d3126..71e0d5f 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c @@ -47,16 +47,19 @@ nv50_dac_disconnect(struct drm_encoder *encoder) if (!nv_encoder->crtc) return; + nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); - ret = RING_SPACE(evo, 2); + ret = RING_SPACE(evo, 4); if (ret) { NV_ERROR(dev, "no space while disconnecting DAC\n"); return; } BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); - OUT_RING(evo, 0); + OUT_RING (evo, 0); + BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); + OUT_RING (evo, 0); nv_encoder->crtc = NULL; } diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 03cb021..6461eae 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -47,16 +47,19 @@ nv50_sor_disconnect(struct drm_encoder *encoder) if (!nv_encoder->crtc) return; + nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); - ret = RING_SPACE(evo, 2); + ret = RING_SPACE(evo, 4); if (ret) { NV_ERROR(dev, "no space while disconnecting SOR\n"); return; } BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); - OUT_RING(evo, 0); + OUT_RING (evo, 0); + BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); + OUT_RING (evo, 0); nv_encoder->crtc = NULL; nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; -- cgit v0.10.2 From 87c0e0e5133e252a6d3d561dd0caeec0244ea9a5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Jul 2010 08:54:34 +1000 Subject: drm/nv50: rewrite display irq handler The previous handler basically worked correctly for a full-blown mode change. However, it did nothing at all when a partial (encoder only) reconfiguation was necessary, leading to the display hanging on certain types of mode switch. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 565981d..4de342f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -610,6 +610,11 @@ struct drm_nouveau_private { struct backlight_device *backlight; struct nouveau_channel *evo; + struct { + struct dcb_entry *dcb; + u16 script; + u32 pclk; + } evo_irq; struct { struct dentry *channel_root; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 0c76204..711128c 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -559,131 +559,28 @@ int nv50_display_destroy(struct drm_device *dev) return 0; } -static inline uint32_t -nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t mc; - - if (sor) { - if (dev_priv->chipset < 0x90 || - dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) - mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or)); - else - mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or)); - } else { - mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or)); - } - - return mc; -} - -static int -nv50_display_irq_head(struct drm_device *dev, int *phead, - struct dcb_entry **pdcbent) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL); - uint32_t dac = 0, sor = 0; - int head, i, or = 0, type = OUTPUT_ANY; - - /* We're assuming that head 0 *or* head 1 will be active here, - * and not both. I'm not sure if the hw will even signal both - * ever, but it definitely shouldn't for us as we commit each - * CRTC separately, and submission will be blocked by the GPU - * until we handle each in turn. - */ - NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); - head = ffs((unk30 >> 9) & 3) - 1; - if (head < 0) - return -EINVAL; - - /* This assumes CRTCs are never bound to multiple encoders, which - * should be the case. - */ - for (i = 0; i < 3 && type == OUTPUT_ANY; i++) { - uint32_t mc = nv50_display_mode_ctrl(dev, false, i); - if (!(mc & (1 << head))) - continue; - - switch ((mc >> 8) & 0xf) { - case 0: type = OUTPUT_ANALOG; break; - case 1: type = OUTPUT_TV; break; - default: - NV_ERROR(dev, "unknown dac mode_ctrl: 0x%08x\n", dac); - return -1; - } - - or = i; - } - - for (i = 0; i < 4 && type == OUTPUT_ANY; i++) { - uint32_t mc = nv50_display_mode_ctrl(dev, true, i); - if (!(mc & (1 << head))) - continue; - - switch ((mc >> 8) & 0xf) { - case 0: type = OUTPUT_LVDS; break; - case 1: type = OUTPUT_TMDS; break; - case 2: type = OUTPUT_TMDS; break; - case 5: type = OUTPUT_TMDS; break; - case 8: type = OUTPUT_DP; break; - case 9: type = OUTPUT_DP; break; - default: - NV_ERROR(dev, "unknown sor mode_ctrl: 0x%08x\n", sor); - return -1; - } - - or = i; - } - - NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or); - if (type == OUTPUT_ANY) { - NV_ERROR(dev, "unknown encoder!!\n"); - return -1; - } - - for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { - struct dcb_entry *dcbent = &dev_priv->vbios.dcb.entry[i]; - - if (dcbent->type != type) - continue; - - if (!(dcbent->or & (1 << or))) - continue; - - *phead = head; - *pdcbent = dcbent; - return 0; - } - - NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or); - return 0; -} - -static uint32_t -nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, - int pxclk) +static u16 +nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb, + u32 mc, int pxclk) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_connector *nv_connector = NULL; struct drm_encoder *encoder; struct nvbios *bios = &dev_priv->vbios; - uint32_t mc, script = 0, or; + u32 script = 0, or; list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - if (nv_encoder->dcb != dcbent) + if (nv_encoder->dcb != dcb) continue; nv_connector = nouveau_encoder_connector_get(nv_encoder); break; } - or = ffs(dcbent->or) - 1; - mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or); - switch (dcbent->type) { + or = ffs(dcb->or) - 1; + switch (dcb->type) { case OUTPUT_LVDS: script = (mc >> 8) & 0xf; if (bios->fp_no_ddc) { @@ -774,17 +671,88 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr) static void nv50_display_unk10_handler(struct drm_device *dev) { - struct dcb_entry *dcbent; - int head, ret; + struct drm_nouveau_private *dev_priv = dev->dev_private; + u32 unk30 = nv_rd32(dev, 0x610030), mc; + int i, crtc, or, type = OUTPUT_ANY; - ret = nv50_display_irq_head(dev, &head, &dcbent); - if (ret) - goto ack; + NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); + dev_priv->evo_irq.dcb = NULL; nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); - nouveau_bios_run_display_table(dev, dcbent, 0, -1); + /* Determine which CRTC we're dealing with, only 1 ever will be + * signalled at the same time with the current nouveau code. + */ + crtc = ffs((unk30 & 0x00000060) >> 5) - 1; + if (crtc < 0) + goto ack; + + /* Nothing needs to be done for the encoder */ + crtc = ffs((unk30 & 0x00000180) >> 7) - 1; + if (crtc < 0) + goto ack; + /* Find which encoder was connected to the CRTC */ + for (i = 0; type == OUTPUT_ANY && i < 3; i++) { + mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i)); + NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); + if (!(mc & (1 << crtc))) + continue; + + switch ((mc & 0x00000f00) >> 8) { + case 0: type = OUTPUT_ANALOG; break; + case 1: type = OUTPUT_TV; break; + default: + NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); + goto ack; + } + + or = i; + } + + for (i = 0; type == OUTPUT_ANY && i < 4; i++) { + if (dev_priv->chipset < 0x90 || + dev_priv->chipset == 0x92 || + dev_priv->chipset == 0xa0) + mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i)); + else + mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i)); + + NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); + if (!(mc & (1 << crtc))) + continue; + + switch ((mc & 0x00000f00) >> 8) { + case 0: type = OUTPUT_LVDS; break; + case 1: type = OUTPUT_TMDS; break; + case 2: type = OUTPUT_TMDS; break; + case 5: type = OUTPUT_TMDS; break; + case 8: type = OUTPUT_DP; break; + case 9: type = OUTPUT_DP; break; + default: + NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); + goto ack; + } + + or = i; + } + + /* There was no encoder to disable */ + if (type == OUTPUT_ANY) + goto ack; + + /* Disable the encoder */ + for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { + struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i]; + + if (dcb->type == type && (dcb->or & (1 << or))) { + nouveau_bios_run_display_table(dev, dcb, 0, -1); + dev_priv->evo_irq.dcb = dcb; + goto ack; + } + } + + NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); ack: nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10); nv_wr32(dev, 0x610030, 0x80000000); @@ -854,34 +822,104 @@ nv50_display_unk20_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) static void nv50_display_unk20_handler(struct drm_device *dev) { - struct dcb_entry *dcbent; - uint32_t tmp, pclk, script; - int head, or, ret; + struct drm_nouveau_private *dev_priv = dev->dev_private; + u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc; + struct dcb_entry *dcb; + int i, crtc, or, type = OUTPUT_ANY; - ret = nv50_display_irq_head(dev, &head, &dcbent); - if (ret) + NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); + dcb = dev_priv->evo_irq.dcb; + if (dcb) { + nouveau_bios_run_display_table(dev, dcb, 0, -2); + dev_priv->evo_irq.dcb = NULL; + } + + /* CRTC clock change requested? */ + crtc = ffs((unk30 & 0x00000600) >> 9) - 1; + if (crtc >= 0) { + pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)); + pclk &= 0x003fffff; + + nv50_crtc_set_clock(dev, crtc, pclk); + + tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc)); + tmp &= ~0x000000f; + nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc), tmp); + } + + /* Nothing needs to be done for the encoder */ + crtc = ffs((unk30 & 0x00000180) >> 7) - 1; + if (crtc < 0) goto ack; - or = ffs(dcbent->or) - 1; - pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; - script = nv50_display_script_select(dev, dcbent, pclk); + pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)) & 0x003fffff; - NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk); + /* Find which encoder is connected to the CRTC */ + for (i = 0; type == OUTPUT_ANY && i < 3; i++) { + mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(i)); + NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); + if (!(mc & (1 << crtc))) + continue; - if (dcbent->type != OUTPUT_DP) - nouveau_bios_run_display_table(dev, dcbent, 0, -2); + switch ((mc & 0x00000f00) >> 8) { + case 0: type = OUTPUT_ANALOG; break; + case 1: type = OUTPUT_TV; break; + default: + NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); + goto ack; + } + + or = i; + } + + for (i = 0; type == OUTPUT_ANY && i < 4; i++) { + if (dev_priv->chipset < 0x90 || + dev_priv->chipset == 0x92 || + dev_priv->chipset == 0xa0) + mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(i)); + else + mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(i)); + + NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); + if (!(mc & (1 << crtc))) + continue; + + switch ((mc & 0x00000f00) >> 8) { + case 0: type = OUTPUT_LVDS; break; + case 1: type = OUTPUT_TMDS; break; + case 2: type = OUTPUT_TMDS; break; + case 5: type = OUTPUT_TMDS; break; + case 8: type = OUTPUT_DP; break; + case 9: type = OUTPUT_DP; break; + default: + NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); + goto ack; + } - nv50_crtc_set_clock(dev, head, pclk); + or = i; + } - nouveau_bios_run_display_table(dev, dcbent, script, pclk); + if (type == OUTPUT_ANY) + goto ack; - nv50_display_unk20_dp_hack(dev, dcbent); - nv50_display_unk20_dp_set_tmds(dev, dcbent); + /* Enable the encoder */ + for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { + dcb = &dev_priv->vbios.dcb.entry[i]; + if (dcb->type == type && (dcb->or & (1 << or))) + break; + } - tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head)); - tmp &= ~0x000000f; - nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp); + if (i == dev_priv->vbios.dcb.entries) { + NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); + goto ack; + } + + script = nv50_display_script_select(dev, dcb, mc, pclk); + nouveau_bios_run_display_table(dev, dcb, script, pclk); - if (dcbent->type != OUTPUT_ANALOG) { + nv50_display_unk20_dp_hack(dev, dcb); + nv50_display_unk20_dp_set_tmds(dev, dcb); + + if (dcb->type != OUTPUT_ANALOG) { tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); tmp &= ~0x00000f0f; if (script & 0x0100) @@ -891,6 +929,10 @@ nv50_display_unk20_handler(struct drm_device *dev) nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0); } + dev_priv->evo_irq.dcb = dcb; + dev_priv->evo_irq.pclk = pclk; + dev_priv->evo_irq.script = script; + ack: nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); nv_wr32(dev, 0x610030, 0x80000000); @@ -899,17 +941,17 @@ ack: static void nv50_display_unk40_handler(struct drm_device *dev) { - struct dcb_entry *dcbent; - int head, pclk, script, ret; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct dcb_entry *dcb = dev_priv->evo_irq.dcb; + u16 script = dev_priv->evo_irq.script; + u32 unk30 = nv_rd32(dev, 0x610030), pclk = dev_priv->evo_irq.pclk; - ret = nv50_display_irq_head(dev, &head, &dcbent); - if (ret) + NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); + dev_priv->evo_irq.dcb = NULL; + if (!dcb) goto ack; - pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; - script = nv50_display_script_select(dev, dcbent, pclk); - - nouveau_bios_run_display_table(dev, dcbent, script, -pclk); + nouveau_bios_run_display_table(dev, dcb, script, -pclk); ack: nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); nv_wr32(dev, 0x610030, 0x80000000); -- cgit v0.10.2 From ea4718d1dc52c4faef92065ce62fcba6113540bf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Jul 2010 11:00:42 +1000 Subject: drm/nouveau: move DP script invocation to nouveau_dp.c Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index deeb21c..184bc95 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -271,12 +271,26 @@ nouveau_dp_link_train(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - uint8_t config[4]; - uint8_t status[3]; + struct bit_displayport_encoder_table *dpe; + int dpe_headerlen; + uint8_t config[4], status[3]; bool cr_done, cr_max_vs, eq_done; int ret = 0, i, tries, voltage; NV_DEBUG_KMS(dev, "link training!!\n"); + + dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); + if (!dpe) { + NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or); + return false; + } + + if (dpe->script0) { + NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); + nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), + nv_encoder->dcb); + } + train: cr_done = eq_done = false; @@ -403,6 +417,12 @@ stop: } } + if (dpe->script1) { + NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); + nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), + nv_encoder->dcb); + } + return eq_done; } diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 6461eae..45a617d 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -66,36 +66,6 @@ nv50_sor_disconnect(struct drm_encoder *encoder) } static void -nv50_sor_dp_link_train(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct bit_displayport_encoder_table *dpe; - int dpe_headerlen; - - dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); - if (!dpe) { - NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or); - return; - } - - if (dpe->script0) { - NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); - nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), - nv_encoder->dcb); - } - - if (!nouveau_dp_link_train(encoder)) - NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or); - - if (dpe->script1) { - NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); - nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), - nv_encoder->dcb); - } -} - -static void nv50_sor_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; @@ -146,7 +116,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) } if (nv_encoder->dcb->type == OUTPUT_DP && mode == DRM_MODE_DPMS_ON) - nv50_sor_dp_link_train(encoder); + nouveau_dp_link_train(encoder); } static void -- cgit v0.10.2 From 1f403d9cca359531e16bc685ed5d619c77762004 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Jul 2010 11:20:17 +1000 Subject: drm/nv50: set DP display power state during DPMS Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 45a617d..bcd4cf8 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -115,8 +115,22 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or))); } - if (nv_encoder->dcb->type == OUTPUT_DP && mode == DRM_MODE_DPMS_ON) - nouveau_dp_link_train(encoder); + if (nv_encoder->dcb->type == OUTPUT_DP) { + struct nouveau_i2c_chan *auxch; + + auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); + if (!auxch) + return; + + if (mode == DRM_MODE_DPMS_ON) { + u8 status = DP_SET_POWER_D0; + nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1); + nouveau_dp_link_train(encoder); + } else { + u8 status = DP_SET_POWER_D3; + nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1); + } + } } static void -- cgit v0.10.2 From 646bef2d20accc6ed696a98e38d5f2515b0ff35d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Jul 2010 11:27:52 +1000 Subject: drm/nouveau: add scaler-only modes for eDP too Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 464b3dc..c2fb153 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -623,7 +623,8 @@ nouveau_connector_get_modes(struct drm_connector *connector) ret = get_slave_funcs(nv_encoder)-> get_modes(to_drm_encoder(nv_encoder), connector); - if (nv_encoder->dcb->type == OUTPUT_LVDS) + if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS || + nv_connector->dcb->type == DCB_CONNECTOR_eDP) ret += nouveau_connector_scaler_modes_add(connector); return ret; -- cgit v0.10.2 From b6d3d8717855c72e541bace5edd0460f2eed6dde Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Jun 2010 15:38:27 +1000 Subject: drm/nouveau: remove dev_priv->init_state and friends Nouveau will no longer load at all if card initialisation fails, so all these checks are unnecessary. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 1371c77..3ca8343 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -711,8 +711,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, return ret; /* Software copy if the card isn't up and running yet. */ - if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || - !dev_priv->channel) { + if (!dev_priv->channel) { ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); goto out; } diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 06555c7..53daeba 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -369,8 +369,6 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct nouveau_channel *chan; int ret; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; - if (dev_priv->engine.graph.accel_blocked) return -ENODEV; @@ -419,7 +417,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, struct drm_nouveau_channel_free *cfree = data; struct nouveau_channel *chan; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); nouveau_channel_free(chan); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 4de342f..afebd32 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -492,11 +492,6 @@ enum nouveau_card_type { struct drm_nouveau_private { struct drm_device *dev; - enum { - NOUVEAU_CARD_INIT_DOWN, - NOUVEAU_CARD_INIT_DONE, - NOUVEAU_CARD_INIT_FAILED - } init_state; /* the card type, takes NV_* as values */ enum nouveau_card_type card_type; @@ -649,14 +644,6 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo) return 0; } -#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \ - struct drm_nouveau_private *nv = dev->dev_private; \ - if (nv->init_state != NOUVEAU_CARD_INIT_DONE) { \ - NV_ERROR(dev, "called without init\n"); \ - return -EINVAL; \ - } \ -} while (0) - #define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do { \ struct drm_nouveau_private *nv = dev->dev_private; \ if (!nouveau_channel_owner(dev, (cl), (id))) { \ diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 791531b..547f2c2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -137,8 +137,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, uint32_t flags = 0; int ret = 0; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; - if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; @@ -580,7 +578,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, struct nouveau_fence *fence = NULL; int i, j, ret = 0, do_reloc = 0; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); req->vram_available = dev_priv->fb_aper_free; @@ -760,8 +757,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT); int ret = -EINVAL; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; - gem = drm_gem_object_lookup(dev, file_priv, req->handle); if (!gem) return ret; @@ -800,8 +795,6 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, struct nouveau_bo *nvbo; int ret = -EINVAL; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; - gem = drm_gem_object_lookup(dev, file_priv, req->handle); if (!gem) return ret; @@ -827,8 +820,6 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data, struct drm_gem_object *gem; int ret; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; - gem = drm_gem_object_lookup(dev, file_priv, req->handle); if (!gem) return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 32f7fbd..3ec181f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c @@ -184,7 +184,6 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, struct nouveau_channel *chan; int ret; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index d436c3c..5624f37e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -1232,7 +1232,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct nouveau_channel *chan; int ret; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan); if (init->handle == ~0) @@ -1283,7 +1282,6 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, struct nouveau_channel *chan; int ret; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan); ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 3e241e4..6fd99f1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -407,11 +407,6 @@ nouveau_card_init(struct drm_device *dev) struct nouveau_engine *engine; int ret; - NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); - - if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE) - return 0; - vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, nouveau_switcheroo_can_switch); @@ -421,7 +416,6 @@ nouveau_card_init(struct drm_device *dev) if (ret) goto out; engine = &dev_priv->engine; - dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; spin_lock_init(&dev_priv->context_switch_lock); /* Parse BIOS tables / Run init tables if card not POSTed */ @@ -513,8 +507,6 @@ nouveau_card_init(struct drm_device *dev) if (ret) NV_ERROR(dev, "Error %d registering backlight\n", ret); - dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; - nouveau_fbcon_init(dev); drm_kms_helper_poll_init(dev); return 0; @@ -559,44 +551,37 @@ static void nouveau_card_takedown(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->engine; - NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); - - if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) { + nouveau_backlight_exit(dev); - nouveau_backlight_exit(dev); - - if (dev_priv->channel) { - nouveau_channel_free(dev_priv->channel); - dev_priv->channel = NULL; - } - - if (!nouveau_noaccel) { - engine->fifo.takedown(dev); - engine->graph.takedown(dev); - } - engine->fb.takedown(dev); - engine->timer.takedown(dev); - engine->mc.takedown(dev); + if (dev_priv->channel) { + nouveau_channel_free(dev_priv->channel); + dev_priv->channel = NULL; + } - mutex_lock(&dev->struct_mutex); - ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); - ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); - mutex_unlock(&dev->struct_mutex); - nouveau_sgdma_takedown(dev); + if (!nouveau_noaccel) { + engine->fifo.takedown(dev); + engine->graph.takedown(dev); + } + engine->fb.takedown(dev); + engine->timer.takedown(dev); + engine->mc.takedown(dev); - nouveau_gpuobj_takedown(dev); - nouveau_mem_close(dev); - engine->instmem.takedown(dev); + mutex_lock(&dev->struct_mutex); + ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); + ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); + mutex_unlock(&dev->struct_mutex); + nouveau_sgdma_takedown(dev); - drm_irq_uninstall(dev); + nouveau_gpuobj_takedown(dev); + nouveau_mem_close(dev); + engine->instmem.takedown(dev); - nouveau_gpuobj_late_takedown(dev); - nouveau_bios_takedown(dev); + drm_irq_uninstall(dev); - vga_client_register(dev->pdev, NULL, NULL, NULL); + nouveau_gpuobj_late_takedown(dev); + nouveau_bios_takedown(dev); - dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; - } + vga_client_register(dev->pdev, NULL, NULL, NULL); } /* here a client dies, release the stuff that was allocated for its @@ -692,7 +677,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) dev_priv->dev = dev; dev_priv->flags = flags & NOUVEAU_FLAGS; - dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", dev->pci_vendor, dev->pci_device, dev->pdev->class); @@ -840,8 +824,6 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_getparam *getparam = data; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; - switch (getparam->param) { case NOUVEAU_GETPARAM_CHIPSET_ID: getparam->value = dev_priv->chipset; @@ -910,8 +892,6 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data, { struct drm_nouveau_setparam *setparam = data; - NOUVEAU_CHECK_INITIALISED_WITH_RETURN; - switch (setparam->param) { default: NV_ERROR(dev, "unknown parameter %lld\n", setparam->param); -- cgit v0.10.2 From 2107cce3056dccf37ae5cbfc95df348959b2c717 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 7 Jul 2010 11:05:48 +1000 Subject: drm/nv50: implement DAC disconnect fix missed in earlier commit Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index 71e0d5f..1bc0859 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c @@ -257,6 +257,12 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, nv_encoder->crtc = encoder->crtc; } +static struct drm_crtc * +nv50_dac_crtc_get(struct drm_encoder *encoder) +{ + return nouveau_encoder(encoder)->crtc; +} + static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { .dpms = nv50_dac_dpms, .save = nv50_dac_save, @@ -265,6 +271,7 @@ static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { .prepare = nv50_dac_prepare, .commit = nv50_dac_commit, .mode_set = nv50_dac_mode_set, + .get_crtc = nv50_dac_crtc_get, .detect = nv50_dac_detect, .disable = nv50_dac_disconnect }; -- cgit v0.10.2 From f56cb86f9abd229418f894a8ffedfb9ff465c181 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 8 Jul 2010 11:29:10 +1000 Subject: drm/nouveau: add instmem flush() hook This removes the previous prepare_access() and finish_access() hooks, and replaces it with a much simpler flush() hook. All the chipset-specific code before nv50 has its use removed completely, as it's not required there at all. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index afebd32..e21eacc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -269,8 +269,7 @@ struct nouveau_instmem_engine { void (*clear)(struct drm_device *, struct nouveau_gpuobj *); int (*bind)(struct drm_device *, struct nouveau_gpuobj *); int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); - void (*prepare_access)(struct drm_device *, bool write); - void (*finish_access)(struct drm_device *); + void (*flush)(struct drm_device *); }; struct nouveau_mc_engine { @@ -1027,8 +1026,7 @@ extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); -extern void nv04_instmem_prepare_access(struct drm_device *, bool write); -extern void nv04_instmem_finish_access(struct drm_device *); +extern void nv04_instmem_flush(struct drm_device *); /* nv50_instmem.c */ extern int nv50_instmem_init(struct drm_device *); @@ -1040,8 +1038,7 @@ extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); -extern void nv50_instmem_prepare_access(struct drm_device *, bool write); -extern void nv50_instmem_finish_access(struct drm_device *); +extern void nv50_instmem_flush(struct drm_device *); /* nv04_mc.c */ extern int nv04_mc_init(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 4b42bf2..5152c0a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -143,7 +143,6 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, phys |= 0x30; } - dev_priv->engine.instmem.prepare_access(dev, true); while (size) { unsigned offset_h = upper_32_bits(phys); unsigned offset_l = lower_32_bits(phys); @@ -175,7 +174,7 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, } } } - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); nv_wr32(dev, 0x100c80, 0x00050001); if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { @@ -218,7 +217,6 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) virt -= dev_priv->vm_vram_base; pages = (size >> 16) << 1; - dev_priv->engine.instmem.prepare_access(dev, true); while (pages) { pgt = dev_priv->vm_vram_pt[virt >> 29]; pte = (virt & 0x1ffe0000ULL) >> 15; @@ -232,7 +230,7 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) while (pte < end) nv_wo32(dev, pgt, pte++, 0); } - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); nv_wr32(dev, 0x100c80, 0x00050001); if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 5624f37e..7d86e05 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -132,7 +132,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) } } - instmem->prepare_access(dev, true); co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); do { if (!nouveau_ramht_entry_valid(dev, ramht, co)) { @@ -143,7 +142,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) nv_wo32(dev, ramht, (co + 4)/4, ctx); list_add_tail(&ref->list, &chan->ramht_refs); - instmem->finish_access(dev); + instmem->flush(dev); return 0; } NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n", @@ -153,7 +152,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) if (co >= dev_priv->ramht_size) co = 0; } while (co != ho); - instmem->finish_access(dev); NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id); return -ENOMEM; @@ -173,7 +171,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) return; } - instmem->prepare_access(dev, true); co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); do { if (nouveau_ramht_entry_valid(dev, ramht, co) && @@ -186,7 +183,7 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) nv_wo32(dev, ramht, (co + 4)/4, 0x00000000); list_del(&ref->list); - instmem->finish_access(dev); + instmem->flush(dev); return; } @@ -195,7 +192,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) co = 0; } while (co != ho); list_del(&ref->list); - instmem->finish_access(dev); NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", chan->id, ref->handle); @@ -280,10 +276,9 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { int i; - engine->instmem.prepare_access(dev, true); for (i = 0; i < gpuobj->im_pramin->size; i += 4) nv_wo32(dev, gpuobj, i/4, 0); - engine->instmem.finish_access(dev); + engine->instmem.flush(dev); } *gpuobj_ret = gpuobj; @@ -371,10 +366,9 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) } if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) { - engine->instmem.prepare_access(dev, true); for (i = 0; i < gpuobj->im_pramin->size; i += 4) nv_wo32(dev, gpuobj, i/4, 0); - engine->instmem.finish_access(dev); + engine->instmem.flush(dev); } if (gpuobj->dtor) @@ -606,10 +600,9 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset, } if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { - dev_priv->engine.instmem.prepare_access(dev, true); for (i = 0; i < gpuobj->im_pramin->size; i += 4) nv_wo32(dev, gpuobj, i/4, 0); - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); } if (pref) { @@ -697,8 +690,6 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, return ret; } - instmem->prepare_access(dev, true); - if (dev_priv->card_type < NV_50) { uint32_t frame, adjust, pte_flags = 0; @@ -735,7 +726,7 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, nv_wo32(dev, *gpuobj, 5, flags5); } - instmem->finish_access(dev); + instmem->flush(dev); (*gpuobj)->engine = NVOBJ_ENGINE_SW; (*gpuobj)->class = class; @@ -850,7 +841,6 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, return ret; } - dev_priv->engine.instmem.prepare_access(dev, true); if (dev_priv->card_type >= NV_50) { nv_wo32(dev, *gpuobj, 0, class); nv_wo32(dev, *gpuobj, 5, 0x00010000); @@ -875,7 +865,7 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, } } } - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); (*gpuobj)->engine = NVOBJ_ENGINE_GR; (*gpuobj)->class = class; @@ -988,17 +978,13 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, if (dev_priv->card_type >= NV_50) { uint32_t vm_offset, pde; - instmem->prepare_access(dev, true); - vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200; vm_offset += chan->ramin->gpuobj->im_pramin->start; ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000, 0, &chan->vm_pd, NULL); - if (ret) { - instmem->finish_access(dev); + if (ret) return ret; - } for (i = 0; i < 0x4000; i += 8) { nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000); nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe); @@ -1008,10 +994,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->gart_info.sg_ctxdma, &chan->vm_gart_pt); - if (ret) { - instmem->finish_access(dev); + if (ret) return ret; - } nv_wo32(dev, chan->vm_pd, pde++, chan->vm_gart_pt->instance | 0x03); nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); @@ -1021,17 +1005,15 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->vm_vram_pt[i], &chan->vm_vram_pt[i]); - if (ret) { - instmem->finish_access(dev); + if (ret) return ret; - } nv_wo32(dev, chan->vm_pd, pde++, chan->vm_vram_pt[i]->instance | 0x61); nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); } - instmem->finish_access(dev); + instmem->flush(dev); } /* RAMHT */ @@ -1164,10 +1146,8 @@ nouveau_gpuobj_suspend(struct drm_device *dev) return -ENOMEM; } - dev_priv->engine.instmem.prepare_access(dev, false); for (i = 0; i < gpuobj->im_pramin->size / 4; i++) gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i); - dev_priv->engine.instmem.finish_access(dev); } return 0; @@ -1212,10 +1192,9 @@ nouveau_gpuobj_resume(struct drm_device *dev) if (!gpuobj->im_backing_suspend) continue; - dev_priv->engine.instmem.prepare_access(dev, true); for (i = 0; i < gpuobj->im_pramin->size / 4; i++) nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]); - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); } nouveau_gpuobj_suspend_cleanup(dev); diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 1d6ee8b..1b2ab5a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -97,7 +97,6 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start); - dev_priv->engine.instmem.prepare_access(nvbe->dev, true); pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT); nvbe->pte_start = pte; for (i = 0; i < nvbe->nr_pages; i++) { @@ -116,7 +115,7 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) dma_offset += NV_CTXDMA_PAGE_SIZE; } } - dev_priv->engine.instmem.finish_access(nvbe->dev); + dev_priv->engine.instmem.flush(nvbe->dev); if (dev_priv->card_type == NV_50) { nv_wr32(dev, 0x100c80, 0x00050001); @@ -154,7 +153,6 @@ nouveau_sgdma_unbind(struct ttm_backend *be) if (!nvbe->bound) return 0; - dev_priv->engine.instmem.prepare_access(nvbe->dev, true); pte = nvbe->pte_start; for (i = 0; i < nvbe->nr_pages; i++) { dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus; @@ -170,7 +168,7 @@ nouveau_sgdma_unbind(struct ttm_backend *be) dma_offset += NV_CTXDMA_PAGE_SIZE; } } - dev_priv->engine.instmem.finish_access(nvbe->dev); + dev_priv->engine.instmem.flush(nvbe->dev); if (dev_priv->card_type == NV_50) { nv_wr32(dev, 0x100c80, 0x00050001); @@ -272,7 +270,6 @@ nouveau_sgdma_init(struct drm_device *dev) pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - dev_priv->engine.instmem.prepare_access(dev, true); if (dev_priv->card_type < NV_50) { /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE @@ -294,7 +291,7 @@ nouveau_sgdma_init(struct drm_device *dev) nv_wo32(dev, gpuobj, (i+4)/4, 0); } } - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); dev_priv->gart_info.type = NOUVEAU_GART_SGDMA; dev_priv->gart_info.aper_base = 0; @@ -325,14 +322,11 @@ nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; - struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; int pte; pte = (offset >> NV_CTXDMA_PAGE_SHIFT); if (dev_priv->card_type < NV_50) { - instmem->prepare_access(dev, false); *page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK; - instmem->finish_access(dev); return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 6fd99f1..67ee32f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -54,8 +54,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.clear = nv04_instmem_clear; engine->instmem.bind = nv04_instmem_bind; engine->instmem.unbind = nv04_instmem_unbind; - engine->instmem.prepare_access = nv04_instmem_prepare_access; - engine->instmem.finish_access = nv04_instmem_finish_access; + engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv04_mc_init; engine->mc.takedown = nv04_mc_takedown; engine->timer.init = nv04_timer_init; @@ -95,8 +94,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.clear = nv04_instmem_clear; engine->instmem.bind = nv04_instmem_bind; engine->instmem.unbind = nv04_instmem_unbind; - engine->instmem.prepare_access = nv04_instmem_prepare_access; - engine->instmem.finish_access = nv04_instmem_finish_access; + engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv04_mc_init; engine->mc.takedown = nv04_mc_takedown; engine->timer.init = nv04_timer_init; @@ -138,8 +136,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.clear = nv04_instmem_clear; engine->instmem.bind = nv04_instmem_bind; engine->instmem.unbind = nv04_instmem_unbind; - engine->instmem.prepare_access = nv04_instmem_prepare_access; - engine->instmem.finish_access = nv04_instmem_finish_access; + engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv04_mc_init; engine->mc.takedown = nv04_mc_takedown; engine->timer.init = nv04_timer_init; @@ -181,8 +178,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.clear = nv04_instmem_clear; engine->instmem.bind = nv04_instmem_bind; engine->instmem.unbind = nv04_instmem_unbind; - engine->instmem.prepare_access = nv04_instmem_prepare_access; - engine->instmem.finish_access = nv04_instmem_finish_access; + engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv04_mc_init; engine->mc.takedown = nv04_mc_takedown; engine->timer.init = nv04_timer_init; @@ -225,8 +221,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.clear = nv04_instmem_clear; engine->instmem.bind = nv04_instmem_bind; engine->instmem.unbind = nv04_instmem_unbind; - engine->instmem.prepare_access = nv04_instmem_prepare_access; - engine->instmem.finish_access = nv04_instmem_finish_access; + engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv40_mc_init; engine->mc.takedown = nv40_mc_takedown; engine->timer.init = nv04_timer_init; @@ -271,8 +266,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.clear = nv50_instmem_clear; engine->instmem.bind = nv50_instmem_bind; engine->instmem.unbind = nv50_instmem_unbind; - engine->instmem.prepare_access = nv50_instmem_prepare_access; - engine->instmem.finish_access = nv50_instmem_finish_access; + engine->instmem.flush = nv50_instmem_flush; engine->mc.init = nv50_mc_init; engine->mc.takedown = nv50_mc_takedown; engine->timer.init = nv04_timer_init; diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index 611c83e..b2c01fe 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c @@ -137,7 +137,6 @@ nv04_fifo_create_context(struct nouveau_channel *chan) spin_lock_irqsave(&dev_priv->context_switch_lock, flags); /* Setup initial state */ - dev_priv->engine.instmem.prepare_access(dev, true); RAMFC_WR(DMA_PUT, chan->pushbuf_base); RAMFC_WR(DMA_GET, chan->pushbuf_base); RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4); @@ -145,7 +144,6 @@ nv04_fifo_create_context(struct nouveau_channel *chan) NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | DMA_FETCH_ENDIANNESS)); - dev_priv->engine.instmem.finish_access(dev); /* enable the fifo dma operation */ nv_wr32(dev, NV04_PFIFO_MODE, @@ -172,8 +170,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid) struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t fc = NV04_RAMFC(chid), tmp; - dev_priv->engine.instmem.prepare_access(dev, false); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); tmp = nv_ri32(dev, fc + 8); @@ -184,8 +180,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid) nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20)); nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24)); - dev_priv->engine.instmem.finish_access(dev); - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); } @@ -226,7 +220,6 @@ nv04_fifo_unload_context(struct drm_device *dev) return -EINVAL; } - dev_priv->engine.instmem.prepare_access(dev, true); RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; @@ -236,7 +229,6 @@ nv04_fifo_unload_context(struct drm_device *dev) RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); - dev_priv->engine.instmem.finish_access(dev); nv04_fifo_do_load_context(dev, pfifo->channels - 1); nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c index 17af702..4408232 100644 --- a/drivers/gpu/drm/nouveau/nv04_instmem.c +++ b/drivers/gpu/drm/nouveau/nv04_instmem.c @@ -49,10 +49,8 @@ nv04_instmem_determine_amount(struct drm_device *dev) NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10); /* Clear all of it, except the BIOS image that's in the first 64KiB */ - dev_priv->engine.instmem.prepare_access(dev, true); for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4) nv_wi32(dev, i, 0x00000000); - dev_priv->engine.instmem.finish_access(dev); } static void @@ -186,12 +184,7 @@ nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) } void -nv04_instmem_prepare_access(struct drm_device *dev, bool write) -{ -} - -void -nv04_instmem_finish_access(struct drm_device *dev) +nv04_instmem_flush(struct drm_device *dev) { } diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c index 7aeabf2..7a4069c 100644 --- a/drivers/gpu/drm/nouveau/nv10_fifo.c +++ b/drivers/gpu/drm/nouveau/nv10_fifo.c @@ -55,7 +55,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan) /* Fill entries that are seen filled in dumps of nvidia driver just * after channel's is put into DMA mode */ - dev_priv->engine.instmem.prepare_access(dev, true); nv_wi32(dev, fc + 0, chan->pushbuf_base); nv_wi32(dev, fc + 4, chan->pushbuf_base); nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); @@ -66,7 +65,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan) NV_PFIFO_CACHE1_BIG_ENDIAN | #endif 0); - dev_priv->engine.instmem.finish_access(dev); /* enable the fifo dma operation */ nv_wr32(dev, NV04_PFIFO_MODE, @@ -91,8 +89,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid) struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t fc = NV10_RAMFC(chid), tmp; - dev_priv->engine.instmem.prepare_access(dev, false); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); @@ -117,8 +113,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid) nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48)); out: - dev_priv->engine.instmem.finish_access(dev); - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); } @@ -155,8 +149,6 @@ nv10_fifo_unload_context(struct drm_device *dev) return 0; fc = NV10_RAMFC(chid); - dev_priv->engine.instmem.prepare_access(dev, true); - nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); @@ -179,8 +171,6 @@ nv10_fifo_unload_context(struct drm_device *dev) nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); out: - dev_priv->engine.instmem.finish_access(dev); - nv10_fifo_do_load_context(dev, pfifo->channels - 1); nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); return 0; diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index fe2349b..f3e6dd70 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -421,7 +421,6 @@ nv20_graph_create_context(struct nouveau_channel *chan) return ret; /* Initialise default context values */ - dev_priv->engine.instmem.prepare_access(dev, true); ctx_init(dev, chan->ramin_grctx->gpuobj); /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ @@ -430,8 +429,6 @@ nv20_graph_create_context(struct nouveau_channel *chan) nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, chan->ramin_grctx->instance >> 4); - - dev_priv->engine.instmem.finish_access(dev); return 0; } @@ -444,9 +441,7 @@ nv20_graph_destroy_context(struct nouveau_channel *chan) if (chan->ramin_grctx) nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); - dev_priv->engine.instmem.prepare_access(dev, true); nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, 0); - dev_priv->engine.instmem.finish_access(dev); } int diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c index 500ccfd..2b67f18 100644 --- a/drivers/gpu/drm/nouveau/nv40_fifo.c +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c @@ -48,7 +48,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan) spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - dev_priv->engine.instmem.prepare_access(dev, true); nv_wi32(dev, fc + 0, chan->pushbuf_base); nv_wi32(dev, fc + 4, chan->pushbuf_base); nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); @@ -61,7 +60,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan) 0x30000000 /* no idea.. */); nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4); nv_wi32(dev, fc + 60, 0x0001FFFF); - dev_priv->engine.instmem.finish_access(dev); /* enable the fifo dma operation */ nv_wr32(dev, NV04_PFIFO_MODE, @@ -89,8 +87,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid) struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t fc = NV40_RAMFC(chid), tmp, tmp2; - dev_priv->engine.instmem.prepare_access(dev, false); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); @@ -127,8 +123,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid) nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76)); nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80)); - dev_priv->engine.instmem.finish_access(dev); - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); } @@ -166,7 +160,6 @@ nv40_fifo_unload_context(struct drm_device *dev) return 0; fc = NV40_RAMFC(chid); - dev_priv->engine.instmem.prepare_access(dev, true); nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); @@ -200,7 +193,6 @@ nv40_fifo_unload_context(struct drm_device *dev) tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16); nv_wi32(dev, fc + 72, tmp); #endif - dev_priv->engine.instmem.finish_access(dev); nv40_fifo_do_load_context(dev, pfifo->channels - 1); nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 65b13b5..2608c34 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -67,7 +67,6 @@ nv40_graph_create_context(struct nouveau_channel *chan) return ret; /* Initialise default context values */ - dev_priv->engine.instmem.prepare_access(dev, true); if (!pgraph->ctxprog) { struct nouveau_grctx ctx = {}; @@ -80,7 +79,6 @@ nv40_graph_create_context(struct nouveau_channel *chan) } nv_wo32(dev, chan->ramin_grctx->gpuobj, 0, chan->ramin_grctx->gpuobj->im_pramin->start); - dev_priv->engine.instmem.finish_access(dev); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 711128c..6a293c8 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -71,14 +71,13 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name, return ret; } - dev_priv->engine.instmem.prepare_access(dev, true); nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class); nv_wo32(dev, obj, 1, limit); nv_wo32(dev, obj, 2, offset); nv_wo32(dev, obj, 3, 0x00000000); nv_wo32(dev, obj, 4, 0x00000000); nv_wo32(dev, obj, 5, 0x00010000); - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index e20c0e2..d2d4fd0 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -49,12 +49,11 @@ nv50_fifo_init_thingo(struct drm_device *dev) priv->cur_thingo = !priv->cur_thingo; /* We never schedule channel 0 or 127 */ - dev_priv->engine.instmem.prepare_access(dev, true); for (i = 1, nr = 0; i < 127; i++) { if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc) nv_wo32(dev, cur->gpuobj, nr++, i); } - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); nv_wr32(dev, 0x32f4, cur->instance >> 12); nv_wr32(dev, 0x32ec, nr); @@ -281,8 +280,6 @@ nv50_fifo_create_context(struct nouveau_channel *chan) spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - dev_priv->engine.instmem.prepare_access(dev, true); - nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4); nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4)); nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff); @@ -304,7 +301,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan) nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12); } - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); ret = nv50_fifo_channel_enable(dev, chan->id, false); if (ret) { @@ -349,8 +346,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan) NV_DEBUG(dev, "ch%d\n", chan->id); - dev_priv->engine.instmem.prepare_access(dev, false); - nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4)); nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4)); nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4)); @@ -404,8 +399,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan) nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4)); } - dev_priv->engine.instmem.finish_access(dev); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); return 0; } @@ -434,8 +427,6 @@ nv50_fifo_unload_context(struct drm_device *dev) ramfc = chan->ramfc->gpuobj; cache = chan->cache->gpuobj; - dev_priv->engine.instmem.prepare_access(dev, true); - nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330)); nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334)); nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240)); @@ -491,7 +482,7 @@ nv50_fifo_unload_context(struct drm_device *dev) nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410)); } - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); /*XXX: probably reload ch127 (NULL) state back too */ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127); diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index b04e7c8..5dc3be5 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -226,7 +226,6 @@ nv50_graph_create_context(struct nouveau_channel *chan) obj = chan->ramin_grctx->gpuobj; hdr = IS_G80 ? 0x200 : 0x20; - dev_priv->engine.instmem.prepare_access(dev, true); nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + pgraph->grctx_size - 1); @@ -234,9 +233,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000); - dev_priv->engine.instmem.finish_access(dev); - dev_priv->engine.instmem.prepare_access(dev, true); if (!pgraph->ctxprog) { struct nouveau_grctx ctx = {}; ctx.dev = chan->dev; @@ -247,8 +244,8 @@ nv50_graph_create_context(struct nouveau_channel *chan) nouveau_grctx_vals_load(dev, obj); } nv_wo32(dev, obj, 0x00000/4, chan->ramin->instance >> 12); - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); return 0; } @@ -264,10 +261,9 @@ nv50_graph_destroy_context(struct nouveau_channel *chan) if (!chan->ramin || !chan->ramin->gpuobj) return; - dev_priv->engine.instmem.prepare_access(dev, true); for (i = hdr; i < hdr + 24; i += 4) nv_wo32(dev, chan->ramin->gpuobj, i/4, 0); - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); } diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index a361d16..d9feee3 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -35,8 +35,6 @@ struct nv50_instmem_priv { struct nouveau_gpuobj_ref *pramin_pt; struct nouveau_gpuobj_ref *pramin_bar; struct nouveau_gpuobj_ref *fb_bar; - - bool last_access_wr; }; #define NV50_INSTMEM_PAGE_SHIFT 12 @@ -262,16 +260,13 @@ nv50_instmem_init(struct drm_device *dev) /* Assume that praying isn't enough, check that we can re-read the * entire fake channel back from the PRAMIN BAR */ - dev_priv->engine.instmem.prepare_access(dev, false); for (i = 0; i < c_size; i += 4) { if (nv_rd32(dev, NV_RAMIN + i) != nv_ri32(dev, i)) { NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n", i); - dev_priv->engine.instmem.finish_access(dev); return -EINVAL; } } - dev_priv->engine.instmem.finish_access(dev); nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700); @@ -451,13 +446,12 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) vram |= 0x30; } - dev_priv->engine.instmem.prepare_access(dev, true); while (pte < pte_end) { nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram)); nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram)); vram += NV50_INSTMEM_PAGE_SIZE; } - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); nv_wr32(dev, 0x100c80, 0x00040001); if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { @@ -490,36 +484,21 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) pte = (gpuobj->im_pramin->start >> 12) << 1; pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; - dev_priv->engine.instmem.prepare_access(dev, true); while (pte < pte_end) { nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); } - dev_priv->engine.instmem.finish_access(dev); + dev_priv->engine.instmem.flush(dev); gpuobj->im_bound = 0; return 0; } void -nv50_instmem_prepare_access(struct drm_device *dev, bool write) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; - - priv->last_access_wr = write; -} - -void -nv50_instmem_finish_access(struct drm_device *dev) +nv50_instmem_flush(struct drm_device *dev) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; - - if (priv->last_access_wr) { - nv_wr32(dev, 0x070000, 0x00000001); - if (!nv_wait(0x070000, 0x00000001, 0x00000000)) - NV_ERROR(dev, "PRAMIN flush timeout\n"); - } + nv_wr32(dev, 0x070000, 0x00000001); + if (!nv_wait(0x070000, 0x00000001, 0x00000000)) + NV_ERROR(dev, "PRAMIN flush timeout\n"); } -- cgit v0.10.2 From 631872155f35b907ae3950016d9e72a308449d69 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 8 Jul 2010 11:39:18 +1000 Subject: drm/nv50: move tlb flushing to a helper function Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e21eacc..6a6873d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1039,6 +1039,7 @@ extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); extern void nv50_instmem_flush(struct drm_device *); +extern void nv50_vm_flush(struct drm_device *, int engine); /* nv04_mc.c */ extern int nv04_mc_init(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 5152c0a..5f8f95d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -176,34 +176,10 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, } dev_priv->engine.instmem.flush(dev); - nv_wr32(dev, 0x100c80, 0x00050001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - return -EBUSY; - } - - nv_wr32(dev, 0x100c80, 0x00000001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - return -EBUSY; - } - - nv_wr32(dev, 0x100c80, 0x00040001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - return -EBUSY; - } - - nv_wr32(dev, 0x100c80, 0x00060001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - return -EBUSY; - } - + nv50_vm_flush(dev, 5); + nv50_vm_flush(dev, 0); + nv50_vm_flush(dev, 4); + nv50_vm_flush(dev, 6); return 0; } @@ -232,32 +208,10 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) } dev_priv->engine.instmem.flush(dev); - nv_wr32(dev, 0x100c80, 0x00050001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - return; - } - - nv_wr32(dev, 0x100c80, 0x00000001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - return; - } - - nv_wr32(dev, 0x100c80, 0x00040001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - return; - } - - nv_wr32(dev, 0x100c80, 0x00060001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - } + nv50_vm_flush(dev, 5); + nv50_vm_flush(dev, 0); + nv50_vm_flush(dev, 4); + nv50_vm_flush(dev, 6); } /* diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 1b2ab5a..491767f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -118,21 +118,8 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) dev_priv->engine.instmem.flush(nvbe->dev); if (dev_priv->card_type == NV_50) { - nv_wr32(dev, 0x100c80, 0x00050001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", - nv_rd32(dev, 0x100c80)); - return -EBUSY; - } - - nv_wr32(dev, 0x100c80, 0x00000001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", - nv_rd32(dev, 0x100c80)); - return -EBUSY; - } + nv50_vm_flush(dev, 5); /* PGRAPH */ + nv50_vm_flush(dev, 0); /* PFIFO */ } nvbe->bound = true; @@ -171,21 +158,8 @@ nouveau_sgdma_unbind(struct ttm_backend *be) dev_priv->engine.instmem.flush(nvbe->dev); if (dev_priv->card_type == NV_50) { - nv_wr32(dev, 0x100c80, 0x00050001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", - nv_rd32(dev, 0x100c80)); - return -EBUSY; - } - - nv_wr32(dev, 0x100c80, 0x00000001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", - nv_rd32(dev, 0x100c80)); - return -EBUSY; - } + nv50_vm_flush(dev, 5); + nv50_vm_flush(dev, 0); } nvbe->bound = false; diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index d9feee3..2a5ec88 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -453,19 +453,8 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) } dev_priv->engine.instmem.flush(dev); - nv_wr32(dev, 0x100c80, 0x00040001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (1)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - return -EBUSY; - } - - nv_wr32(dev, 0x100c80, 0x00060001); - if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); - NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); - return -EBUSY; - } + nv50_vm_flush(dev, 4); + nv50_vm_flush(dev, 6); gpuobj->im_bound = 1; return 0; @@ -502,3 +491,11 @@ nv50_instmem_flush(struct drm_device *dev) NV_ERROR(dev, "PRAMIN flush timeout\n"); } +void +nv50_vm_flush(struct drm_device *dev, int engine) +{ + nv_wr32(dev, 0x100c80, (engine << 16) | 1); + if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) + NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); +} + -- cgit v0.10.2 From ec91db269e6a3c7f45b96169ccf5dbd1fde8fce8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 8 Jul 2010 11:53:19 +1000 Subject: drm/nouveau: remove ability to use external firmware This was always really a developer option, and if it's really necessary we can hack this in ourselves. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index acd31ed..4a1db73 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -9,7 +9,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ - nouveau_dp.o nouveau_grctx.o \ + nouveau_dp.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o nv50_mc.o \ nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 2171dc8..6c8cd38 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -35,10 +35,6 @@ #include "drm_pciids.h" -MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)"); -int nouveau_ctxfw = 0; -module_param_named(ctxfw, nouveau_ctxfw, int, 0400); - MODULE_PARM_DESC(noagp, "Disable AGP"); int nouveau_noagp; module_param_named(noagp, nouveau_noagp, int, 0400); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 6a6873d..64a080e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -330,8 +330,6 @@ struct nouveau_pgraph_object_class { struct nouveau_pgraph_engine { struct nouveau_pgraph_object_class *grclass; bool accel_blocked; - void *ctxprog; - void *ctxvals; int grctx_size; int (*init)(struct drm_device *); @@ -665,7 +663,6 @@ extern int nouveau_tv_disable; extern char *nouveau_tv_norm; extern int nouveau_reg_debug; extern char *nouveau_vbios; -extern int nouveau_ctxfw; extern int nouveau_ignorelid; extern int nouveau_nofbaccel; extern int nouveau_noaccel; @@ -1010,12 +1007,6 @@ extern int nv50_graph_unload_context(struct drm_device *); extern void nv50_graph_context_switch(struct drm_device *); extern int nv50_grctx_init(struct nouveau_grctx *); -/* nouveau_grctx.c */ -extern int nouveau_grctx_prog_load(struct drm_device *); -extern void nouveau_grctx_vals_load(struct drm_device *, - struct nouveau_gpuobj *); -extern void nouveau_grctx_fini(struct drm_device *); - /* nv04_instmem.c */ extern int nv04_instmem_init(struct drm_device *); extern void nv04_instmem_takedown(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c deleted file mode 100644 index f731c5f..0000000 --- a/drivers/gpu/drm/nouveau/nouveau_grctx.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include -#include - -#include "drmP.h" -#include "nouveau_drv.h" - -struct nouveau_ctxprog { - uint32_t signature; - uint8_t version; - uint16_t length; - uint32_t data[]; -} __attribute__ ((packed)); - -struct nouveau_ctxvals { - uint32_t signature; - uint8_t version; - uint32_t length; - struct { - uint32_t offset; - uint32_t value; - } data[]; -} __attribute__ ((packed)); - -int -nouveau_grctx_prog_load(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - const int chipset = dev_priv->chipset; - const struct firmware *fw; - const struct nouveau_ctxprog *cp; - const struct nouveau_ctxvals *cv; - char name[32]; - int ret, i; - - if (pgraph->accel_blocked) - return -ENODEV; - - if (!pgraph->ctxprog) { - sprintf(name, "nouveau/nv%02x.ctxprog", chipset); - ret = request_firmware(&fw, name, &dev->pdev->dev); - if (ret) { - NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset); - return ret; - } - - pgraph->ctxprog = kmemdup(fw->data, fw->size, GFP_KERNEL); - if (!pgraph->ctxprog) { - NV_ERROR(dev, "OOM copying ctxprog\n"); - release_firmware(fw); - return -ENOMEM; - } - - cp = pgraph->ctxprog; - if (le32_to_cpu(cp->signature) != 0x5043564e || - cp->version != 0 || - le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) { - NV_ERROR(dev, "ctxprog invalid\n"); - release_firmware(fw); - nouveau_grctx_fini(dev); - return -EINVAL; - } - release_firmware(fw); - } - - if (!pgraph->ctxvals) { - sprintf(name, "nouveau/nv%02x.ctxvals", chipset); - ret = request_firmware(&fw, name, &dev->pdev->dev); - if (ret) { - NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset); - nouveau_grctx_fini(dev); - return ret; - } - - pgraph->ctxvals = kmemdup(fw->data, fw->size, GFP_KERNEL); - if (!pgraph->ctxvals) { - NV_ERROR(dev, "OOM copying ctxvals\n"); - release_firmware(fw); - nouveau_grctx_fini(dev); - return -ENOMEM; - } - - cv = (void *)pgraph->ctxvals; - if (le32_to_cpu(cv->signature) != 0x5643564e || - cv->version != 0 || - le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) { - NV_ERROR(dev, "ctxvals invalid\n"); - release_firmware(fw); - nouveau_grctx_fini(dev); - return -EINVAL; - } - release_firmware(fw); - } - - cp = pgraph->ctxprog; - - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); - for (i = 0; i < le16_to_cpu(cp->length); i++) - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, - le32_to_cpu(cp->data[i])); - - return 0; -} - -void -nouveau_grctx_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - - if (pgraph->ctxprog) { - kfree(pgraph->ctxprog); - pgraph->ctxprog = NULL; - } - - if (pgraph->ctxvals) { - kfree(pgraph->ctxprog); - pgraph->ctxvals = NULL; - } -} - -void -nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - struct nouveau_ctxvals *cv = pgraph->ctxvals; - int i; - - if (!cv) - return; - - for (i = 0; i < le32_to_cpu(cv->length); i++) - nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset), - le32_to_cpu(cv->data[i].value)); -} diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 2608c34..fd7d2b5 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -58,6 +58,7 @@ nv40_graph_create_context(struct nouveau_channel *chan) struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nouveau_grctx ctx = {}; int ret; ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, @@ -67,16 +68,11 @@ nv40_graph_create_context(struct nouveau_channel *chan) return ret; /* Initialise default context values */ - if (!pgraph->ctxprog) { - struct nouveau_grctx ctx = {}; + ctx.dev = chan->dev; + ctx.mode = NOUVEAU_GRCTX_VALS; + ctx.data = chan->ramin_grctx->gpuobj; + nv40_grctx_init(&ctx); - ctx.dev = chan->dev; - ctx.mode = NOUVEAU_GRCTX_VALS; - ctx.data = chan->ramin_grctx->gpuobj; - nv40_grctx_init(&ctx); - } else { - nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj); - } nv_wo32(dev, chan->ramin_grctx->gpuobj, 0, chan->ramin_grctx->gpuobj->im_pramin->start); return 0; @@ -236,7 +232,8 @@ nv40_graph_init(struct drm_device *dev) struct drm_nouveau_private *dev_priv = (struct drm_nouveau_private *)dev->dev_private; struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - uint32_t vramsz; + struct nouveau_grctx ctx = {}; + uint32_t vramsz, *cp; int i, j; nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & @@ -244,32 +241,22 @@ nv40_graph_init(struct drm_device *dev) nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); - if (nouveau_ctxfw) { - nouveau_grctx_prog_load(dev); - dev_priv->engine.graph.grctx_size = 175 * 1024; - } - - if (!dev_priv->engine.graph.ctxprog) { - struct nouveau_grctx ctx = {}; - uint32_t *cp; - - cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL); - if (!cp) - return -ENOMEM; + cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL); + if (!cp) + return -ENOMEM; - ctx.dev = dev; - ctx.mode = NOUVEAU_GRCTX_PROG; - ctx.data = cp; - ctx.ctxprog_max = 256; - nv40_grctx_init(&ctx); - dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; + ctx.dev = dev; + ctx.mode = NOUVEAU_GRCTX_PROG; + ctx.data = cp; + ctx.ctxprog_max = 256; + nv40_grctx_init(&ctx); + dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); - for (i = 0; i < ctx.ctxprog_len; i++) - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); + nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); + for (i = 0; i < ctx.ctxprog_len; i++) + nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); - kfree(cp); - } + kfree(cp); /* No context present currently */ nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); @@ -405,7 +392,6 @@ nv40_graph_init(struct drm_device *dev) void nv40_graph_takedown(struct drm_device *dev) { - nouveau_grctx_fini(dev); } struct nouveau_pgraph_object_class nv40_graph_grclass[] = { diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 5dc3be5..395857a 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -103,37 +103,33 @@ static int nv50_graph_init_ctxctl(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_grctx ctx = {}; + uint32_t *cp; + int i; NV_DEBUG(dev, "\n"); - if (nouveau_ctxfw) { - nouveau_grctx_prog_load(dev); - dev_priv->engine.graph.grctx_size = 0x70000; + cp = kmalloc(512 * 4, GFP_KERNEL); + if (!cp) { + NV_ERROR(dev, "failed to allocate ctxprog\n"); + dev_priv->engine.graph.accel_blocked = true; + return 0; } - if (!dev_priv->engine.graph.ctxprog) { - struct nouveau_grctx ctx = {}; - uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL); - int i; - if (!cp) { - NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n"); - dev_priv->engine.graph.accel_blocked = true; - return 0; - } - ctx.dev = dev; - ctx.mode = NOUVEAU_GRCTX_PROG; - ctx.data = cp; - ctx.ctxprog_max = 512; - if (!nv50_grctx_init(&ctx)) { - dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; - - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); - for (i = 0; i < ctx.ctxprog_len; i++) - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); - } else { - dev_priv->engine.graph.accel_blocked = true; - } - kfree(cp); + + ctx.dev = dev; + ctx.mode = NOUVEAU_GRCTX_PROG; + ctx.data = cp; + ctx.ctxprog_max = 512; + if (!nv50_grctx_init(&ctx)) { + dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; + + nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); + for (i = 0; i < ctx.ctxprog_len; i++) + nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); + } else { + dev_priv->engine.graph.accel_blocked = true; } + kfree(cp); nv_wr32(dev, 0x400320, 4); nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); @@ -164,7 +160,6 @@ void nv50_graph_takedown(struct drm_device *dev) { NV_DEBUG(dev, "\n"); - nouveau_grctx_fini(dev); } void @@ -214,6 +209,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; struct nouveau_gpuobj *obj; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nouveau_grctx ctx = {}; int hdr, ret; NV_DEBUG(dev, "ch%d\n", chan->id); @@ -234,15 +230,11 @@ nv50_graph_create_context(struct nouveau_channel *chan) nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000); - if (!pgraph->ctxprog) { - struct nouveau_grctx ctx = {}; - ctx.dev = chan->dev; - ctx.mode = NOUVEAU_GRCTX_VALS; - ctx.data = obj; - nv50_grctx_init(&ctx); - } else { - nouveau_grctx_vals_load(dev, obj); - } + ctx.dev = chan->dev; + ctx.mode = NOUVEAU_GRCTX_VALS; + ctx.data = obj; + nv50_grctx_init(&ctx); + nv_wo32(dev, obj, 0x00000/4, chan->ramin->instance >> 12); dev_priv->engine.instmem.flush(dev); -- cgit v0.10.2 From 816544b21b020bdb9dcb9a5003fe3e1f109e8698 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 8 Jul 2010 13:15:05 +1000 Subject: drm/nouveau: allocate fixed amount of PRAMIN per channel on all chipsets Previously only done on nv50+ This commit also switches unknown NV2x/NV3x chipsets to noaccel mode. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 7d86e05..b6bcb25 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -229,25 +229,12 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, * available. */ if (chan) { - if (chan->ramin_heap.ml_entry.next) { - NV_DEBUG(dev, "private heap\n"); - pramin = &chan->ramin_heap; - } else - if (dev_priv->card_type < NV_50) { - NV_DEBUG(dev, "global heap fallback\n"); - pramin = &dev_priv->ramin_heap; - } + NV_DEBUG(dev, "channel heap\n"); + pramin = &chan->ramin_heap; } else { NV_DEBUG(dev, "global heap\n"); pramin = &dev_priv->ramin_heap; - } - - if (!pramin) { - NV_ERROR(dev, "No PRAMIN heap!\n"); - return -EINVAL; - } - if (!chan) { ret = engine->instmem.populate(dev, gpuobj, &size); if (ret) { nouveau_gpuobj_del(dev, &gpuobj); @@ -911,6 +898,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) base = 0; /* PGRAPH context */ + size += dev_priv->engine.graph.grctx_size; if (dev_priv->card_type == NV_50) { /* Various fixed table thingos */ @@ -921,12 +909,8 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) size += 0x8000; /* RAMFC */ size += 0x1000; - /* PGRAPH context */ - size += 0x70000; } - NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n", - chan->id, size, base); ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0, &chan->ramin); if (ret) { @@ -959,15 +943,11 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); - /* Reserve a block of PRAMIN for the channel - *XXX: maybe on card_type == NV_50) { - ret = nouveau_gpuobj_channel_init_pramin(chan); - if (ret) { - NV_ERROR(dev, "init pramin\n"); - return ret; - } + /* Allocate a chunk of memory for per-channel object storage */ + ret = nouveau_gpuobj_channel_init_pramin(chan); + if (ret) { + NV_ERROR(dev, "init pramin\n"); + return ret; } /* NV50 VM diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index f3e6dd70..0c776ee 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -370,53 +370,42 @@ nv20_graph_create_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); - unsigned int ctx_size; unsigned int idoffs = 0x28/4; int ret; switch (dev_priv->chipset) { case 0x20: - ctx_size = NV20_GRCTX_SIZE; ctx_init = nv20_graph_context_init; idoffs = 0; break; case 0x25: case 0x28: - ctx_size = NV25_GRCTX_SIZE; ctx_init = nv25_graph_context_init; break; case 0x2a: - ctx_size = NV2A_GRCTX_SIZE; ctx_init = nv2a_graph_context_init; idoffs = 0; break; case 0x30: case 0x31: - ctx_size = NV30_31_GRCTX_SIZE; ctx_init = nv30_31_graph_context_init; break; case 0x34: - ctx_size = NV34_GRCTX_SIZE; ctx_init = nv34_graph_context_init; break; case 0x35: case 0x36: - ctx_size = NV35_36_GRCTX_SIZE; ctx_init = nv35_36_graph_context_init; break; default: - ctx_size = 0; - ctx_init = nv35_36_graph_context_init; - NV_ERROR(dev, "Please contact the devs if you want your NV%x" - " card to work\n", dev_priv->chipset); - return -ENOSYS; - break; + BUG_ON(1); } - ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16, - NVOBJ_FLAG_ZERO_ALLOC, - &chan->ramin_grctx); + ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, + 16, NVOBJ_FLAG_ZERO_ALLOC, + &chan->ramin_grctx); if (ret) return ret; @@ -535,9 +524,27 @@ nv20_graph_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = (struct drm_nouveau_private *)dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; uint32_t tmp, vramsz; int ret, i; + switch (dev_priv->chipset) { + case 0x20: + pgraph->grctx_size = NV20_GRCTX_SIZE; + break; + case 0x25: + case 0x28: + pgraph->grctx_size = NV25_GRCTX_SIZE; + break; + case 0x2a: + pgraph->grctx_size = NV2A_GRCTX_SIZE; + break; + default: + NV_ERROR(dev, "unknown chipset, disabling acceleration\n"); + pgraph->accel_blocked = true; + return 0; + } + nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); nv_wr32(dev, NV03_PMC_ENABLE, @@ -647,8 +654,27 @@ int nv30_graph_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; int ret, i; + switch (dev_priv->chipset) { + case 0x30: + case 0x31: + pgraph->grctx_size = NV30_31_GRCTX_SIZE; + break; + case 0x34: + pgraph->grctx_size = NV34_GRCTX_SIZE; + break; + case 0x35: + case 0x36: + pgraph->grctx_size = NV35_36_GRCTX_SIZE; + break; + default: + NV_ERROR(dev, "unknown chipset, disabling acceleration\n"); + pgraph->accel_blocked = true; + return 0; + } + nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); nv_wr32(dev, NV03_PMC_ENABLE, -- cgit v0.10.2 From 3b569e0f2b8f48cd7f9ea37ef7597d1219b87477 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 8 Jul 2010 14:57:18 +1000 Subject: drm/nouveau: remove unused fbdev_info Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 64a080e..df55a11 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -517,8 +517,6 @@ struct drm_nouveau_private { atomic_t validate_sequence; } ttm; - struct fb_info *fbdev_info; - int fifo_alloc_count; struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; -- cgit v0.10.2 From ac94a343c74fe0504663583a7590e89257214f0d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 8 Jul 2010 15:28:48 +1000 Subject: drm/nv50: cleanup nv50_fifo.c Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index df55a11..f3dbce2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -294,10 +294,11 @@ struct nouveau_fb_engine { }; struct nouveau_fifo_engine { - void *priv; - int channels; + struct nouveau_gpuobj_ref *playlist[2]; + int cur_playlist; + int (*init)(struct drm_device *); void (*takedown)(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index d2d4fd0..c4467b0 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -28,25 +28,18 @@ #include "drm.h" #include "nouveau_drv.h" -struct nv50_fifo_priv { - struct nouveau_gpuobj_ref *thingo[2]; - int cur_thingo; -}; - -#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) - static void -nv50_fifo_init_thingo(struct drm_device *dev) +nv50_fifo_playlist_update(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; struct nouveau_gpuobj_ref *cur; int i, nr; NV_DEBUG(dev, "\n"); - cur = priv->thingo[priv->cur_thingo]; - priv->cur_thingo = !priv->cur_thingo; + cur = pfifo->playlist[pfifo->cur_playlist]; + pfifo->cur_playlist = !pfifo->cur_playlist; /* We never schedule channel 0 or 127 */ for (i = 1, nr = 0; i < 127; i++) { @@ -60,8 +53,8 @@ nv50_fifo_init_thingo(struct drm_device *dev) nv_wr32(dev, 0x2500, 0x101); } -static int -nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt) +static void +nv50_fifo_channel_enable(struct drm_device *dev, int channel) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->fifos[channel]; @@ -69,37 +62,28 @@ nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt) NV_DEBUG(dev, "ch%d\n", channel); - if (!chan->ramfc) - return -EINVAL; - - if (IS_G80) + if (dev_priv->chipset == 0x50) inst = chan->ramfc->instance >> 12; else inst = chan->ramfc->instance >> 8; - nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), - inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); - if (!nt) - nv50_fifo_init_thingo(dev); - return 0; + nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst | + NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); } static void -nv50_fifo_channel_disable(struct drm_device *dev, int channel, bool nt) +nv50_fifo_channel_disable(struct drm_device *dev, int channel) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t inst; - NV_DEBUG(dev, "ch%d, nt=%d\n", channel, nt); + NV_DEBUG(dev, "ch%d\n", channel); - if (IS_G80) + if (dev_priv->chipset == 0x50) inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; else inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst); - - if (!nt) - nv50_fifo_init_thingo(dev); } static void @@ -132,12 +116,12 @@ nv50_fifo_init_context_table(struct drm_device *dev) for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) { if (dev_priv->fifos[i]) - nv50_fifo_channel_enable(dev, i, true); + nv50_fifo_channel_enable(dev, i); else - nv50_fifo_channel_disable(dev, i, true); + nv50_fifo_channel_disable(dev, i); } - nv50_fifo_init_thingo(dev); + nv50_fifo_playlist_update(dev); } static void @@ -161,41 +145,38 @@ nv50_fifo_init_regs(struct drm_device *dev) nv_wr32(dev, 0x3270, 0); /* Enable dummy channels setup by nv50_instmem.c */ - nv50_fifo_channel_enable(dev, 0, true); - nv50_fifo_channel_enable(dev, 127, true); + nv50_fifo_channel_enable(dev, 0); + nv50_fifo_channel_enable(dev, 127); } int nv50_fifo_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_fifo_priv *priv; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; int ret; NV_DEBUG(dev, "\n"); - priv = dev_priv->engine.fifo.priv; - if (priv) { - priv->cur_thingo = !priv->cur_thingo; + if (pfifo->playlist[0]) { + pfifo->cur_playlist = !pfifo->cur_playlist; goto just_reset; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - dev_priv->engine.fifo.priv = priv; - ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, - NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]); + NVOBJ_FLAG_ZERO_ALLOC, + &pfifo->playlist[0]); if (ret) { - NV_ERROR(dev, "error creating thingo0: %d\n", ret); + NV_ERROR(dev, "error creating playlist 0: %d\n", ret); return ret; } ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, - NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]); + NVOBJ_FLAG_ZERO_ALLOC, + &pfifo->playlist[1]); if (ret) { - NV_ERROR(dev, "error creating thingo1: %d\n", ret); + nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]); + NV_ERROR(dev, "error creating playlist 1: %d\n", ret); return ret; } @@ -215,18 +196,15 @@ void nv50_fifo_takedown(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; NV_DEBUG(dev, "\n"); - if (!priv) + if (!pfifo->playlist[0]) return; - nouveau_gpuobj_ref_del(dev, &priv->thingo[0]); - nouveau_gpuobj_ref_del(dev, &priv->thingo[1]); - - dev_priv->engine.fifo.priv = NULL; - kfree(priv); + nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]); + nouveau_gpuobj_ref_del(dev, &pfifo->playlist[1]); } int @@ -247,7 +225,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan) NV_DEBUG(dev, "ch%d\n", chan->id); - if (IS_G80) { + if (dev_priv->chipset == 0x50) { uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start; uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start; @@ -292,7 +270,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan) chan->dma.ib_base * 4); nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16); - if (!IS_G80) { + if (dev_priv->chipset != 0x50) { nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id); nv_wo32(dev, chan->ramin->gpuobj, 1, chan->ramfc->instance >> 8); @@ -303,14 +281,8 @@ nv50_fifo_create_context(struct nouveau_channel *chan) dev_priv->engine.instmem.flush(dev); - ret = nv50_fifo_channel_enable(dev, chan->id, false); - if (ret) { - NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - nouveau_gpuobj_ref_del(dev, &chan->ramfc); - return ret; - } - + nv50_fifo_channel_enable(dev, chan->id); + nv50_fifo_playlist_update(dev); spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); return 0; } @@ -325,11 +297,12 @@ nv50_fifo_destroy_context(struct nouveau_channel *chan) /* This will ensure the channel is seen as disabled. */ chan->ramfc = NULL; - nv50_fifo_channel_disable(dev, chan->id, false); + nv50_fifo_channel_disable(dev, chan->id); /* Dummy channel, also used on ch 127 */ if (chan->id == 0) - nv50_fifo_channel_disable(dev, 127, false); + nv50_fifo_channel_disable(dev, 127); + nv50_fifo_playlist_update(dev); nouveau_gpuobj_ref_del(dev, &ramfc); nouveau_gpuobj_ref_del(dev, &chan->cache); @@ -391,7 +364,7 @@ nv50_fifo_load_context(struct nouveau_channel *chan) nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); /* guessing that all the 0x34xx regs aren't on NV50 */ - if (!IS_G80) { + if (dev_priv->chipset != 0x50) { nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4)); nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4)); nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4)); @@ -473,7 +446,7 @@ nv50_fifo_unload_context(struct drm_device *dev) } /* guessing that all the 0x34xx regs aren't on NV50 */ - if (!IS_G80) { + if (dev_priv->chipset != 0x50) { nv_wo32(dev, ramfc, 0x84/4, ptr >> 1); nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c)); nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400)); diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 395857a..1413028 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -30,8 +30,6 @@ #include "nouveau_grctx.h" -#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) - static void nv50_graph_init_reset(struct drm_device *dev) { @@ -221,7 +219,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) return ret; obj = chan->ramin_grctx->gpuobj; - hdr = IS_G80 ? 0x200 : 0x20; + hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + pgraph->grctx_size - 1); @@ -246,7 +244,7 @@ nv50_graph_destroy_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - int i, hdr = IS_G80 ? 0x200 : 0x20; + int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; NV_DEBUG(dev, "ch%d\n", chan->id); -- cgit v0.10.2 From c50a5681e7d0ce1dd6de06fd70a7eff56ebfb9e9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 8 Jul 2010 15:40:18 +1000 Subject: drm/nv20-nv30: move context table object out of dev_priv Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index f3dbce2..47fa28d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -333,6 +333,9 @@ struct nouveau_pgraph_engine { bool accel_blocked; int grctx_size; + /* NV2x/NV3x context table (0x400780) */ + struct nouveau_gpuobj_ref *ctx_table; + int (*init)(struct drm_device *); void (*takedown)(struct drm_device *); @@ -580,10 +583,6 @@ struct drm_nouveau_private { struct drm_mm ramin_heap; - /* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */ - uint32_t ctx_table_size; - struct nouveau_gpuobj_ref *ctx_table; - struct list_head gpuobj_list; struct nvbios vbios; diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index 0c776ee..17f309b 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -416,8 +416,8 @@ nv20_graph_create_context(struct nouveau_channel *chan) nv_wo32(dev, chan->ramin_grctx->gpuobj, idoffs, (chan->id << 24) | 0x1); /* CTX_USER */ - nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, - chan->ramin_grctx->instance >> 4); + nv_wo32(dev, pgraph->ctx_table->gpuobj, chan->id, + chan->ramin_grctx->instance >> 4); return 0; } @@ -426,11 +426,12 @@ nv20_graph_destroy_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; if (chan->ramin_grctx) nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); - nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, 0); + nv_wo32(dev, pgraph->ctx_table->gpuobj, chan->id, 0); } int @@ -522,8 +523,7 @@ nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, int nv20_graph_init(struct drm_device *dev) { - struct drm_nouveau_private *dev_priv = - (struct drm_nouveau_private *)dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; uint32_t tmp, vramsz; int ret, i; @@ -550,19 +550,17 @@ nv20_graph_init(struct drm_device *dev) nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); - if (!dev_priv->ctx_table) { + if (!pgraph->ctx_table) { /* Create Context Pointer Table */ - dev_priv->ctx_table_size = 32 * 4; - ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, - dev_priv->ctx_table_size, 16, + ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC, - &dev_priv->ctx_table); + &pgraph->ctx_table); if (ret) return ret; } nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, - dev_priv->ctx_table->instance >> 4); + pgraph->ctx_table->instance >> 4); nv20_graph_rdi(dev); @@ -646,8 +644,9 @@ void nv20_graph_takedown(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table); + nouveau_gpuobj_ref_del(dev, &pgraph->ctx_table); } int @@ -680,19 +679,17 @@ nv30_graph_init(struct drm_device *dev) nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); - if (!dev_priv->ctx_table) { + if (!pgraph->ctx_table) { /* Create Context Pointer Table */ - dev_priv->ctx_table_size = 32 * 4; - ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, - dev_priv->ctx_table_size, 16, + ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC, - &dev_priv->ctx_table); + &pgraph->ctx_table); if (ret) return ret; } nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, - dev_priv->ctx_table->instance >> 4); + pgraph->ctx_table->instance >> 4); nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); -- cgit v0.10.2 From 946cbc825adfa8189a035346d5f7ff31c32b549d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 9 Jul 2010 08:40:49 +1000 Subject: drm/nv50: fix dp_set_tmds to work on the right OR Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 6a293c8..ec1ccf6 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -809,7 +809,8 @@ nv50_display_unk20_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - if (nv_encoder->dcb->type == OUTPUT_DP) { + if (nv_encoder->dcb->type == OUTPUT_DP && + nv_encoder->dcb->or & (1 << or)) { tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)); tmp &= ~NV50_SOR_DP_CTRL_ENABLED; nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp); -- cgit v0.10.2 From baf8035edb5d8285cbf0bf2d1895b0a787501f8f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 9 Jul 2010 08:45:57 +1000 Subject: drm/nouveau: fix mtrr cleanup path Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 5f8f95d..5c48b1e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -253,7 +253,7 @@ nouveau_mem_close(struct drm_device *dev) drm_mtrr_del(dev_priv->fb_mtrr, pci_resource_start(dev->pdev, 1), pci_resource_len(dev->pdev, 1), DRM_MTRR_WC); - dev_priv->fb_mtrr = 0; + dev_priv->fb_mtrr = -1; } } -- cgit v0.10.2 From 271f29e7b55278bc2e4bab53448eef9b35778664 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 9 Jul 2010 10:37:42 +1000 Subject: drm/nv50: move dp_set_tmds() function to happen in the last display irq It seems on some chipsets that doing this from the 0x20 handler causes the display engine to not ever signal the final 0x40 stage. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index ec1ccf6..c19ed8c 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -788,37 +788,6 @@ nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb) } } -/* If programming a TMDS output on a SOR that can also be configured for - * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. - * - * It looks like the VBIOS TMDS scripts make an attempt at this, however, - * the VBIOS scripts on at least one board I have only switch it off on - * link 0, causing a blank display if the output has previously been - * programmed for DisplayPort. - */ -static void -nv50_display_unk20_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) -{ - int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1); - struct drm_encoder *encoder; - u32 tmp; - - if (dcb->type != OUTPUT_TMDS) - return; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (nv_encoder->dcb->type == OUTPUT_DP && - nv_encoder->dcb->or & (1 << or)) { - tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)); - tmp &= ~NV50_SOR_DP_CTRL_ENABLED; - nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp); - break; - } - } -} - static void nv50_display_unk20_handler(struct drm_device *dev) { @@ -917,7 +886,6 @@ nv50_display_unk20_handler(struct drm_device *dev) nouveau_bios_run_display_table(dev, dcb, script, pclk); nv50_display_unk20_dp_hack(dev, dcb); - nv50_display_unk20_dp_set_tmds(dev, dcb); if (dcb->type != OUTPUT_ANALOG) { tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); @@ -938,6 +906,37 @@ ack: nv_wr32(dev, 0x610030, 0x80000000); } +/* If programming a TMDS output on a SOR that can also be configured for + * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. + * + * It looks like the VBIOS TMDS scripts make an attempt at this, however, + * the VBIOS scripts on at least one board I have only switch it off on + * link 0, causing a blank display if the output has previously been + * programmed for DisplayPort. + */ +static void +nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) +{ + int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1); + struct drm_encoder *encoder; + u32 tmp; + + if (dcb->type != OUTPUT_TMDS) + return; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + + if (nv_encoder->dcb->type == OUTPUT_DP && + nv_encoder->dcb->or & (1 << or)) { + tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)); + tmp &= ~NV50_SOR_DP_CTRL_ENABLED; + nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp); + break; + } + } +} + static void nv50_display_unk40_handler(struct drm_device *dev) { @@ -952,6 +951,8 @@ nv50_display_unk40_handler(struct drm_device *dev) goto ack; nouveau_bios_run_display_table(dev, dcb, script, -pclk); + nv50_display_unk40_dp_set_tmds(dev, dcb); + ack: nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); nv_wr32(dev, 0x610030, 0x80000000); -- cgit v0.10.2 From e88efe056d308d0a3b6b645d0eec7236b2d8c902 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 9 Jul 2010 10:56:08 +1000 Subject: drm/nouveau: initialise display before enabling interrupts In some situations it's possible we can receive a spurious hotplug IRQ before we're ready to handle it, leading to an oops. Calling the display init before enabling interrupts should clear any pending IRQs on the GPU and prevent this from happening. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 67ee32f..c58ff9c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -471,12 +471,19 @@ nouveau_card_init(struct drm_device *dev) goto out_graph; } + if (dev_priv->card_type >= NV_50) + ret = nv50_display_create(dev); + else + ret = nv04_display_create(dev); + if (ret) + goto out_fifo; + /* this call irq_preinstall, register irq handler and * call irq_postinstall */ ret = drm_irq_install(dev); if (ret) - goto out_fifo; + goto out_display; ret = drm_vblank_init(dev, 0); if (ret) @@ -490,13 +497,6 @@ nouveau_card_init(struct drm_device *dev) goto out_irq; } - if (dev_priv->card_type >= NV_50) - ret = nv50_display_create(dev); - else - ret = nv04_display_create(dev); - if (ret) - goto out_channel; - ret = nouveau_backlight_init(dev); if (ret) NV_ERROR(dev, "Error %d registering backlight\n", ret); @@ -505,13 +505,13 @@ nouveau_card_init(struct drm_device *dev) drm_kms_helper_poll_init(dev); return 0; -out_channel: - if (dev_priv->channel) { - nouveau_channel_free(dev_priv->channel); - dev_priv->channel = NULL; - } out_irq: drm_irq_uninstall(dev); +out_display: + if (dev_priv->card_type >= NV_50) + nv50_display_destroy(dev); + else + nv04_display_destroy(dev); out_fifo: if (!nouveau_noaccel) engine->fifo.takedown(dev); -- cgit v0.10.2 From 77144554de9af353795698161af26e36f7cdbbef Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 10 Jul 2010 17:37:00 +0200 Subject: drm/nouveau: Fix crashes during fbcon init on single head cards. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 728f555..2fb2444 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -387,7 +387,8 @@ int nouveau_fbcon_init(struct drm_device *dev) dev_priv->nfbdev = nfbdev; nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; - ret = drm_fb_helper_init(dev, &nfbdev->helper, 2, 4); + ret = drm_fb_helper_init(dev, &nfbdev->helper, + nv_two_heads(dev) ? 2 : 1, 4); if (ret) { kfree(nfbdev); return ret; -- cgit v0.10.2 From 112d20ad5ca06a9ec7237602ee33bef6fa881daa Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 10 Jul 2010 18:10:59 +0200 Subject: drm/nouveau: Disable PROM access on init. On older cards ( Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_mc.c b/drivers/gpu/drm/nouveau/nv04_mc.c index 617ed1e..2af43a1 100644 --- a/drivers/gpu/drm/nouveau/nv04_mc.c +++ b/drivers/gpu/drm/nouveau/nv04_mc.c @@ -11,6 +11,10 @@ nv04_mc_init(struct drm_device *dev) */ nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); + + /* Disable PROM access. */ + nv_wr32(dev, NV_PBUS_PCI_NV_20, NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED); + return 0; } -- cgit v0.10.2 From dad9acff504257d37058d3452c978a4129944d99 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 11 Jul 2010 17:19:15 +0200 Subject: drm/nv04: Enable context switching on PFIFO init. Fixes a lockup when coming back from suspend. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index b2c01fe..06cedd9 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c @@ -292,6 +292,7 @@ nv04_fifo_init(struct drm_device *dev) nv04_fifo_init_intr(dev); pfifo->enable(dev); + pfifo->reassign(dev, true); for (i = 0; i < dev_priv->engine.fifo.channels; i++) { if (dev_priv->fifos[i]) { -- cgit v0.10.2 From 41090eb4243bef2e90159b2a6acdc671ad0f825b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 12 Jul 2010 13:15:44 +1000 Subject: drm/nouveau: fix pcirom vbios shadow breakage from acpi rom patch On nv50 it became impossible to attempt a PCI ROM shadow of the VBIOS, which will break some setups. This patch also removes the different ordering of shadow methods for pre-nv50 chipsets. The reason for the different ordering was paranoia, but it should hopefully be OK to try shadowing PRAMIN first. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index e05f129..5437c89 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -203,36 +203,26 @@ struct methods { const bool rw; }; -static struct methods nv04_methods[] = { - { "PROM", load_vbios_prom, false }, - { "PRAMIN", load_vbios_pramin, true }, - { "PCIROM", load_vbios_pci, true }, -}; - -static struct methods nv50_methods[] = { - { "ACPI", load_vbios_acpi, true }, +static struct methods shadow_methods[] = { { "PRAMIN", load_vbios_pramin, true }, { "PROM", load_vbios_prom, false }, { "PCIROM", load_vbios_pci, true }, + { "ACPI", load_vbios_acpi, true }, }; -#define METHODCNT 3 - static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct methods *methods; - int i; + const int nr_methods = ARRAY_SIZE(shadow_methods); + struct methods *methods = shadow_methods; int testscore = 3; - int scores[METHODCNT]; + int scores[nr_methods], i; if (nouveau_vbios) { - methods = nv04_methods; - for (i = 0; i < METHODCNT; i++) + for (i = 0; i < nr_methods; i++) if (!strcasecmp(nouveau_vbios, methods[i].desc)) break; - if (i < METHODCNT) { + if (i < nr_methods) { NV_INFO(dev, "Attempting to use BIOS image from %s\n", methods[i].desc); @@ -244,12 +234,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios); } - if (dev_priv->card_type < NV_50) - methods = nv04_methods; - else - methods = nv50_methods; - - for (i = 0; i < METHODCNT; i++) { + for (i = 0; i < nr_methods; i++) { NV_TRACE(dev, "Attempting to load BIOS image from %s\n", methods[i].desc); data[0] = data[1] = 0; /* avoid reuse of previous image */ @@ -260,7 +245,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) } while (--testscore > 0) { - for (i = 0; i < METHODCNT; i++) { + for (i = 0; i < nr_methods; i++) { if (scores[i] == testscore) { NV_TRACE(dev, "Using BIOS image from %s\n", methods[i].desc); -- cgit v0.10.2 From ca6adb8a217fc2a6f20a50b400ba676481a90945 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 12 Jul 2010 13:45:51 +1000 Subject: drm/nv50: fix RAMHT size Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index c4467b0..fb0281a 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -259,7 +259,9 @@ nv50_fifo_create_context(struct nouveau_channel *chan) spin_lock_irqsave(&dev_priv->context_switch_lock, flags); nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4); - nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4)); + nv_wo32(dev, ramfc, 0x80/4, (0 << 27) /* 4KiB */ | + (4 << 24) /* SEARCH_FULL */ | + (chan->ramht->instance >> 4)); nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff); nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff); nv_wo32(dev, ramfc, 0x40/4, 0x00000000); -- cgit v0.10.2 From 047d1d3cae2c4fc5be4fa20a97c8f5ba4fea1c56 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 May 2010 12:00:43 +1000 Subject: drm/nouveau: reduce usage of fence spinlock to when absolutely necessary Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 53daeba..90fdcda 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -258,9 +258,7 @@ nouveau_channel_free(struct nouveau_channel *chan) nouveau_debugfs_channel_fini(chan); /* Give outstanding push buffers a chance to complete */ - spin_lock_irqsave(&chan->fence.lock, flags); nouveau_fence_update(chan); - spin_unlock_irqrestore(&chan->fence.lock, flags); if (chan->fence.sequence != chan->fence.sequence_ack) { struct nouveau_fence *fence = NULL; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 47fa28d..587a0ab 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -188,7 +188,7 @@ struct nouveau_channel { struct list_head pending; uint32_t sequence; uint32_t sequence_ack; - uint32_t last_sequence_irq; + atomic_t last_sequence_irq; } fence; /* DMA push buffer */ @@ -1111,7 +1111,6 @@ extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr); extern int nouveau_fence_flush(void *obj, void *arg); extern void nouveau_fence_unref(void **obj); extern void *nouveau_fence_ref(void *obj); -extern void nouveau_fence_handler(struct drm_device *dev, int channel); /* nouveau_gem.c */ extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index faddf53..813d853 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -67,12 +67,13 @@ nouveau_fence_update(struct nouveau_channel *chan) if (USE_REFCNT) sequence = nvchan_rd32(chan, 0x48); else - sequence = chan->fence.last_sequence_irq; + sequence = atomic_read(&chan->fence.last_sequence_irq); if (chan->fence.sequence_ack == sequence) return; chan->fence.sequence_ack = sequence; + spin_lock(&chan->fence.lock); list_for_each_safe(entry, tmp, &chan->fence.pending) { fence = list_entry(entry, struct nouveau_fence, entry); @@ -84,6 +85,7 @@ nouveau_fence_update(struct nouveau_channel *chan) if (sequence == chan->fence.sequence_ack) break; } + spin_unlock(&chan->fence.lock); } int @@ -119,7 +121,6 @@ nouveau_fence_emit(struct nouveau_fence *fence) { struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private; struct nouveau_channel *chan = fence->channel; - unsigned long flags; int ret; ret = RING_SPACE(chan, 2); @@ -127,9 +128,7 @@ nouveau_fence_emit(struct nouveau_fence *fence) return ret; if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) { - spin_lock_irqsave(&chan->fence.lock, flags); nouveau_fence_update(chan); - spin_unlock_irqrestore(&chan->fence.lock, flags); BUG_ON(chan->fence.sequence == chan->fence.sequence_ack - 1); @@ -138,9 +137,9 @@ nouveau_fence_emit(struct nouveau_fence *fence) fence->sequence = ++chan->fence.sequence; kref_get(&fence->refcount); - spin_lock_irqsave(&chan->fence.lock, flags); + spin_lock(&chan->fence.lock); list_add_tail(&fence->entry, &chan->fence.pending); - spin_unlock_irqrestore(&chan->fence.lock, flags); + spin_unlock(&chan->fence.lock); BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1); OUT_RING(chan, fence->sequence); @@ -173,14 +172,11 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg) { struct nouveau_fence *fence = nouveau_fence(sync_obj); struct nouveau_channel *chan = fence->channel; - unsigned long flags; if (fence->signalled) return true; - spin_lock_irqsave(&chan->fence.lock, flags); nouveau_fence_update(chan); - spin_unlock_irqrestore(&chan->fence.lock, flags); return fence->signalled; } @@ -221,27 +217,12 @@ nouveau_fence_flush(void *sync_obj, void *sync_arg) return 0; } -void -nouveau_fence_handler(struct drm_device *dev, int channel) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = NULL; - - if (channel >= 0 && channel < dev_priv->engine.fifo.channels) - chan = dev_priv->fifos[channel]; - - if (chan) { - spin_lock_irq(&chan->fence.lock); - nouveau_fence_update(chan); - spin_unlock_irq(&chan->fence.lock); - } -} - int nouveau_fence_init(struct nouveau_channel *chan) { INIT_LIST_HEAD(&chan->fence.pending); spin_lock_init(&chan->fence.lock); + atomic_set(&chan->fence.last_sequence_irq, 0); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index dd09679..c897342 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -527,8 +527,7 @@ static int nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass, int mthd, uint32_t data) { - chan->fence.last_sequence_irq = data; - nouveau_fence_handler(chan->dev, chan->id); + atomic_set(&chan->fence.last_sequence_irq, data); return 0; } -- cgit v0.10.2 From 0edeb0c024f3af7d4dd8dde44ad1082b265ebc9a Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 10 Jul 2010 22:34:13 +0200 Subject: drm/i2c/ch7006: Fix up suspend/resume. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index 81681a0..3e2c9da 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c @@ -428,6 +428,22 @@ static int ch7006_remove(struct i2c_client *client) return 0; } +static int ch7006_suspend(struct i2c_client *client, pm_message_t mesg) +{ + ch7006_dbg(client, "\n"); + + return 0; +} + +static int ch7006_resume(struct i2c_client *client) +{ + ch7006_dbg(client, "\n"); + + ch7006_write(client, 0x3d, 0x0); + + return 0; +} + static int ch7006_encoder_init(struct i2c_client *client, struct drm_device *dev, struct drm_encoder_slave *encoder) @@ -487,6 +503,8 @@ static struct drm_i2c_encoder_driver ch7006_driver = { .i2c_driver = { .probe = ch7006_probe, .remove = ch7006_remove, + .suspend = ch7006_suspend, + .resume = ch7006_resume, .driver = { .name = "ch7006", -- cgit v0.10.2 From 9440106b460ddfb7c0ff98beb6a6741f1f67b92b Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 15 Jul 2010 15:43:25 -0400 Subject: drm: unify crtc,connector,encoder,fb debug printing Unify debug printing so it easier to track what's happening while debugging. Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 57cea01..b5802cf 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1126,7 +1126,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id); + DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); if (put_user(crtc->base.id, crtc_id + copied)) { ret = -EFAULT; goto out; @@ -1154,8 +1154,8 @@ int drm_mode_getresources(struct drm_device *dev, void *data, list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - DRM_DEBUG_KMS("ENCODER ID is %d\n", - encoder->base.id); + DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id, + drm_get_encoder_name(encoder)); if (put_user(encoder->base.id, encoder_id + copied)) { ret = -EFAULT; @@ -1185,8 +1185,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data, list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - DRM_DEBUG_KMS("CONNECTOR ID is %d\n", - connector->base.id); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, + drm_get_connector_name(connector)); if (put_user(connector->base.id, connector_id + copied)) { ret = -EFAULT; @@ -1209,7 +1210,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, } card_res->count_connectors = connector_count; - DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs, + DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs, card_res->count_connectors, card_res->count_encoders); out: @@ -1312,7 +1313,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); - DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id); + DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id); mutex_lock(&dev->mode_config.mutex); @@ -1493,6 +1494,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, goto out; } crtc = obj_to_crtc(obj); + DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); if (crtc_req->mode_valid) { /* If we have a mode we need a framebuffer. */ @@ -1569,6 +1571,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, goto out; } connector = obj_to_connector(obj); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, + drm_get_connector_name(connector)); connector_set[i] = connector; } @@ -1684,6 +1689,7 @@ int drm_mode_addfb(struct drm_device *dev, r->fb_id = fb->base.id; list_add(&fb->filp_head, &file_priv->fbs); + DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); out: mutex_unlock(&dev->mode_config.mutex); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 774d21e..11fe9c8 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -86,7 +86,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, int count = 0; int mode_flags = 0; - DRM_DEBUG_KMS("%s\n", drm_get_connector_name(connector)); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, + drm_get_connector_name(connector)); /* set all modes to the unverified state */ list_for_each_entry_safe(mode, t, &connector->modes, head) mode->status = MODE_UNVERIFIED; @@ -102,8 +103,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, connector->status = connector->funcs->detect(connector); if (connector->status == connector_status_disconnected) { - DRM_DEBUG_KMS("%s is disconnected\n", - drm_get_connector_name(connector)); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", + connector->base.id, drm_get_connector_name(connector)); drm_mode_connector_update_edid_property(connector, NULL); goto prune; } @@ -141,8 +142,8 @@ prune: drm_mode_sort(&connector->modes); - DRM_DEBUG_KMS("Probed modes for %s\n", - drm_get_connector_name(connector)); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id, + drm_get_connector_name(connector)); list_for_each_entry_safe(mode, t, &connector->modes, head) { mode->vrefresh = drm_mode_vrefresh(mode); @@ -374,6 +375,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) { goto done; } + DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); /* Prepare the encoders and CRTCs before setting the mode. */ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { @@ -401,8 +403,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, if (encoder->crtc != crtc) continue; - DRM_DEBUG("%s: set mode %s %x\n", drm_get_encoder_name(encoder), - mode->name, mode->base.id); + DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n", + encoder->base.id, drm_get_encoder_name(encoder), + mode->base.id, mode->name); encoder_funcs = encoder->helper_private; encoder_funcs->mode_set(encoder, mode, adjusted_mode); } @@ -478,10 +481,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) crtc_funcs = set->crtc->helper_private; - DRM_DEBUG_KMS("crtc: %p %d fb: %p connectors: %p num_connectors:" - " %d (x, y) (%i, %i)\n", - set->crtc, set->crtc->base.id, set->fb, set->connectors, - (int)set->num_connectors, set->x, set->y); + if (set->fb) { + DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", + set->crtc->base.id, set->fb->base.id, + (int)set->num_connectors, set->x, set->y); + } else { + DRM_DEBUG_KMS("[CRTC:%d] [NOFB] #connectors=%d (x y) (%i %i)\n", + set->crtc->base.id, (int)set->num_connectors, + set->x, set->y); + } dev = set->crtc->dev; @@ -610,8 +618,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) mode_changed = true; connector->encoder->crtc = new_crtc; } - DRM_DEBUG_KMS("setting connector %d crtc to %p\n", - connector->base.id, new_crtc); + if (new_crtc) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n", + connector->base.id, drm_get_connector_name(connector), + new_crtc->base.id); + } else { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n", + connector->base.id, drm_get_connector_name(connector)); + } } /* mode_set_base is not a required function */ @@ -629,8 +643,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) if (!drm_crtc_helper_set_mode(set->crtc, set->mode, set->x, set->y, old_fb)) { - DRM_ERROR("failed to set mode on crtc %p\n", - set->crtc); + DRM_ERROR("failed to set mode on [CRTC:%d]\n", + set->crtc->base.id); ret = -EINVAL; goto fail; } -- cgit v0.10.2 From 92897b5c669f5e819ff2596fe6228ca2e4904981 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 16 Jul 2010 15:09:17 +1000 Subject: drm: add "auto" dithering method There's no convenient/reliable way for drivers to both obey the dithering mode property, and to be able to attempt to provide a good default in all cases. This commit adds an "auto" method to the property which drivers can default to if they wish, whilst still allowing the user to override the choice as they do now. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index b5802cf..d8d65f4 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -80,6 +80,7 @@ static struct drm_prop_enum_list drm_dithering_mode_enum_list[] = { { DRM_MODE_DITHERING_OFF, "Off" }, { DRM_MODE_DITHERING_ON, "On" }, + { DRM_MODE_DITHERING_AUTO, "Automatic" }, }; /* diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index c5ba163..0fc7397 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -74,6 +74,7 @@ /* Dithering mode options */ #define DRM_MODE_DITHERING_OFF 0 #define DRM_MODE_DITHERING_ON 1 +#define DRM_MODE_DITHERING_AUTO 2 /* Dirty info options */ #define DRM_MODE_DIRTY_OFF 0 -- cgit v0.10.2 From 90c1efdd121c84ee73e9960667229a662f2315a3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 17 Jul 2010 20:23:26 +0100 Subject: drm: Return EBUSY if the framebuffer is unbound when flipping. It looks like there is a race condition between unbinding a framebuffer on a hotplug event and user space trying to flip: BUG: unable to handle kernel NULL pointer dereference at 0000000000000058 IP: [] intel_crtc_page_flip+0xc9/0x39c [i915] PGD 114724067 PUD 1145bd067 PMD 0 Oops: 0000 [#1] SMP Pid: 10954, comm: X Not tainted 2.6.35-rc5_stable_20100714+ #1 P5Q-EM/P5Q-EM RIP: 0010:[] [] intel_crtc_page_flip+0xc9/0x39c [i915] RSP: 0018:ffff880114927cc8 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff88012df48320 RCX: ffff88010c945600 RDX: ffff880001a109c8 RSI: ffff88010c945840 RDI: ffff88012df48320 RBP: ffff880114927d18 R08: ffff88012df48280 R09: ffff88012df48320 R10: 0000000003c2e0b0 R11: 0000000000003246 R12: ffff88010c945840 R13: ffff88012df48000 R14: 0000000000000060 R15: ffff88012dbb8000 FS: 00007f9e6078e830(0000) GS:ffff880001a00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000058 CR3: 00000001177a8000 CR4: 00000000000406f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process X (pid: 10954, threadinfo ffff880114926000, task ffff88012a4a1690) Stack: ffff88010c945600 ffff880115b176c0 ffff88012db10000 0000000000000246 <0> fffffff40006101c ffff88010c945600 00000000ffffffea ffff88010c945600 <0> ffff88012df48320 ffff88011b4b6780 ffff880114927d78 ffffffffa003bd0e Call Trace: [] drm_mode_page_flip_ioctl+0x1bc/0x214 [drm] [] drm_ioctl+0x25e/0x35e [drm] [] ? drm_mode_page_flip_ioctl+0x0/0x214 [drm] [] vfs_ioctl+0x2a/0x9e [] do_vfs_ioctl+0x531/0x565 [] sys_ioctl+0x55/0x77 [] ? sys_read+0x47/0x6f [] system_call_fastpath+0x16/0x1b Code: 45 d4 f4 ff ff ff 0f 84 e0 02 00 00 48 8b 4d b0 49 8d 9d 20 03 00 00 48 89 df 49 89 4c 24 38 49 8b 07 49 89 44 24 20 49 8b 47 20 <48> 8b 40 58 49 c7 04 24 00 00 00 00 49 c7 44 24 18 a9 a5 08 a0 RIP [] intel_crtc_page_flip+0xc9/0x39c [i915] RSP CR2: 0000000000000058 References: Bug 28811 - [page-flipping] GPU hang when modeset after unplugging another monitor (under compiz) https://bugs.freedesktop.org/show_bug.cgi?id=28811 Signed-off-by: Chris Wilson Reviewed-by: Jesse Barnes Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d8d65f4..4c68f76 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2617,6 +2617,15 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, goto out; crtc = obj_to_crtc(obj); + if (crtc->fb == NULL) { + /* The framebuffer is currently unbound, presumably + * due to a hotplug event, that userspace has not + * yet discovered. + */ + ret = -EBUSY; + goto out; + } + if (crtc->funcs->page_flip == NULL) goto out; -- cgit v0.10.2 From 37f9003bd355d9109769fff66f7f228aab42155b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 11 Jun 2010 17:58:38 -0400 Subject: drm/radeon/kms/atom: add crtc disable function Disables the crts as per dpms and also disables the ppll associated with the crtc. This should save additional power. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 8c2d647..a22d5a3 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -669,56 +669,25 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc) atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } -static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) +static void atombios_crtc_program_pll(struct drm_crtc *crtc, + int crtc_id, + int pll_id, + u32 encoder_mode, + u32 encoder_id, + u32 clock, + u32 ref_div, + u32 fb_div, + u32 frac_fb_div, + u32 post_div) { - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder = NULL; - struct radeon_encoder *radeon_encoder = NULL; u8 frev, crev; - int index; + int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); union set_pixel_clock args; - u32 pll_clock = mode->clock; - u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; - struct radeon_pll *pll; - u32 adjusted_clock; - int encoder_mode = 0; memset(&args, 0, sizeof(args)); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - radeon_encoder = to_radeon_encoder(encoder); - encoder_mode = atombios_get_encoder_mode(encoder); - break; - } - } - - if (!radeon_encoder) - return; - - switch (radeon_crtc->pll_id) { - case ATOM_PPLL1: - pll = &rdev->clock.p1pll; - break; - case ATOM_PPLL2: - pll = &rdev->clock.p2pll; - break; - case ATOM_DCPLL: - case ATOM_PPLL_INVALID: - default: - pll = &rdev->clock.dcpll; - break; - } - - /* adjust pixel clock as needed */ - adjusted_clock = atombios_adjust_pll(crtc, mode, pll); - - radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, - &ref_div, &post_div); - - index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) return; @@ -727,47 +696,49 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode case 1: switch (crev) { case 1: - args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); + if (clock == ATOM_DISABLE) + return; + args.v1.usPixelClock = cpu_to_le16(clock / 10); args.v1.usRefDiv = cpu_to_le16(ref_div); args.v1.usFbDiv = cpu_to_le16(fb_div); args.v1.ucFracFbDiv = frac_fb_div; args.v1.ucPostDiv = post_div; - args.v1.ucPpll = radeon_crtc->pll_id; - args.v1.ucCRTC = radeon_crtc->crtc_id; + args.v1.ucPpll = pll_id; + args.v1.ucCRTC = crtc_id; args.v1.ucRefDivSrc = 1; break; case 2: - args.v2.usPixelClock = cpu_to_le16(mode->clock / 10); + args.v2.usPixelClock = cpu_to_le16(clock / 10); args.v2.usRefDiv = cpu_to_le16(ref_div); args.v2.usFbDiv = cpu_to_le16(fb_div); args.v2.ucFracFbDiv = frac_fb_div; args.v2.ucPostDiv = post_div; - args.v2.ucPpll = radeon_crtc->pll_id; - args.v2.ucCRTC = radeon_crtc->crtc_id; + args.v2.ucPpll = pll_id; + args.v2.ucCRTC = crtc_id; args.v2.ucRefDivSrc = 1; break; case 3: - args.v3.usPixelClock = cpu_to_le16(mode->clock / 10); + args.v3.usPixelClock = cpu_to_le16(clock / 10); args.v3.usRefDiv = cpu_to_le16(ref_div); args.v3.usFbDiv = cpu_to_le16(fb_div); args.v3.ucFracFbDiv = frac_fb_div; args.v3.ucPostDiv = post_div; - args.v3.ucPpll = radeon_crtc->pll_id; - args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2); - args.v3.ucTransmitterId = radeon_encoder->encoder_id; + args.v3.ucPpll = pll_id; + args.v3.ucMiscInfo = (pll_id << 2); + args.v3.ucTransmitterId = encoder_id; args.v3.ucEncoderMode = encoder_mode; break; case 5: - args.v5.ucCRTC = radeon_crtc->crtc_id; - args.v5.usPixelClock = cpu_to_le16(mode->clock / 10); + args.v5.ucCRTC = crtc_id; + args.v5.usPixelClock = cpu_to_le16(clock / 10); args.v5.ucRefDiv = ref_div; args.v5.usFbDiv = cpu_to_le16(fb_div); args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); args.v5.ucPostDiv = post_div; args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ - args.v5.ucTransmitterID = radeon_encoder->encoder_id; + args.v5.ucTransmitterID = encoder_id; args.v5.ucEncoderMode = encoder_mode; - args.v5.ucPpll = radeon_crtc->pll_id; + args.v5.ucPpll = pll_id; break; default: DRM_ERROR("Unknown table version %d %d\n", frev, crev); @@ -782,6 +753,56 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) +{ + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; + struct drm_encoder *encoder = NULL; + struct radeon_encoder *radeon_encoder = NULL; + u32 pll_clock = mode->clock; + u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; + struct radeon_pll *pll; + u32 adjusted_clock; + int encoder_mode = 0; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + if (encoder->crtc == crtc) { + radeon_encoder = to_radeon_encoder(encoder); + encoder_mode = atombios_get_encoder_mode(encoder); + break; + } + } + + if (!radeon_encoder) + return; + + switch (radeon_crtc->pll_id) { + case ATOM_PPLL1: + pll = &rdev->clock.p1pll; + break; + case ATOM_PPLL2: + pll = &rdev->clock.p2pll; + break; + case ATOM_DCPLL: + case ATOM_PPLL_INVALID: + default: + pll = &rdev->clock.dcpll; + break; + } + + /* adjust pixel clock as needed */ + adjusted_clock = atombios_adjust_pll(crtc, mode, pll); + + radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, + &ref_div, &post_div); + + atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, + encoder_mode, radeon_encoder->encoder_id, mode->clock, + ref_div, fb_div, frac_fb_div, post_div); + +} + static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { @@ -1191,6 +1212,24 @@ static void atombios_crtc_commit(struct drm_crtc *crtc) atombios_lock_crtc(crtc, ATOM_DISABLE); } +static void atombios_crtc_disable(struct drm_crtc *crtc) +{ + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); + + switch (radeon_crtc->pll_id) { + case ATOM_PPLL1: + case ATOM_PPLL2: + /* disable the ppll */ + atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, + 0, 0, ATOM_DISABLE, 0, 0, 0, 0); + break; + default: + break; + } + radeon_crtc->pll_id = -1; +} + static const struct drm_crtc_helper_funcs atombios_helper_funcs = { .dpms = atombios_crtc_dpms, .mode_fixup = atombios_crtc_mode_fixup, @@ -1199,6 +1238,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { .prepare = atombios_crtc_prepare, .commit = atombios_crtc_commit, .load_lut = radeon_crtc_load_lut, + .disable = atombios_crtc_disable, }; void radeon_atombios_init_crtc(struct drm_device *dev, -- cgit v0.10.2 From 734ee8357ac2685a306acd598826d5eb8a3fca30 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 15 Jul 2010 11:02:54 +1000 Subject: drm/nv50: use correct PRAMIN flush register on original nv50 Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 587a0ab..16856e0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1028,6 +1028,7 @@ extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); extern void nv50_instmem_flush(struct drm_device *); +extern void nv84_instmem_flush(struct drm_device *); extern void nv50_vm_flush(struct drm_device *, int engine); /* nv04_mc.c */ diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index c58ff9c..0bf79bf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -266,7 +266,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.clear = nv50_instmem_clear; engine->instmem.bind = nv50_instmem_bind; engine->instmem.unbind = nv50_instmem_unbind; - engine->instmem.flush = nv50_instmem_flush; + if (dev_priv->chipset == 0x50) + engine->instmem.flush = nv50_instmem_flush; + else + engine->instmem.flush = nv84_instmem_flush; engine->mc.init = nv50_mc_init; engine->mc.takedown = nv50_mc_takedown; engine->timer.init = nv04_timer_init; diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 2a5ec88..2ed893c 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -486,6 +486,14 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) void nv50_instmem_flush(struct drm_device *dev) { + nv_wr32(dev, 0x00330c, 0x00000001); + if (!nv_wait(0x00330c, 0x00000001, 0x00000000)) + NV_ERROR(dev, "PRAMIN flush timeout\n"); +} + +void +nv84_instmem_flush(struct drm_device *dev) +{ nv_wr32(dev, 0x070000, 0x00000001); if (!nv_wait(0x070000, 0x00000001, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); -- cgit v0.10.2 From 03639b50385810c2153624c0c8cb85de93d31356 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 15 Jul 2010 11:25:55 +1000 Subject: drm/nouveau: remove quirk to fabricate DVI-A output on DCB 1.5 boards There's a report of this quirk breaking modesetting on at least one board. After discussion with Francisco Jerez, we've decided to remove it: it's not worth limiting the quirk to just where we know it can work? i'm happy either way really :) hmm, don't think so, most if not all DCB15 cards have just one DAC and with that quirk there's no way to tell if the load comes from the VGA or DVI port Signed-off-by: Ben Skeggs Acked-by: Francisco Jerez diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 5437c89..2297bbc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5739,13 +5739,6 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, case OUTPUT_TV: entry->tvconf.has_component_output = false; break; - case OUTPUT_TMDS: - /* - * Invent a DVI-A output, by copying the fields of the DVI-D - * output; reported to work by math_b on an NV20(!). - */ - fabricate_vga_output(dcb, entry->i2c_index, entry->heads); - break; case OUTPUT_LVDS: if ((conn & 0x00003f00) != 0x10) entry->lvdsconf.use_straps_for_mode = true; -- cgit v0.10.2 From a6ed76d7ffc62ffa474b41d31b011b6853c5de32 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 12 Jul 2010 15:33:07 +1000 Subject: drm/nouveau: support fetching LVDS EDID from ACPI Based on a patch from Matthew Garrett. Signed-off-by: Ben Skeggs Acked-by: Matthew Garrett diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 381d385..c17a055 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "drmP.h" #include "drm.h" @@ -11,6 +12,7 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" #include "nv50_display.h" +#include "nouveau_connector.h" #include @@ -259,3 +261,37 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); } + +int +nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) +{ + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct acpi_device *acpidev; + acpi_handle handle; + int type, ret; + void *edid; + + switch (connector->connector_type) { + case DRM_MODE_CONNECTOR_LVDS: + case DRM_MODE_CONNECTOR_eDP: + type = ACPI_VIDEO_DISPLAY_LCD; + break; + default: + return -EINVAL; + } + + handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); + if (!handle) + return -ENODEV; + + ret = acpi_bus_get_device(handle, &acpidev); + if (ret) + return -ENODEV; + + ret = acpi_video_get_edid(acpidev, type, -1, &edid); + if (ret < 0) + return ret; + + nv_connector->edid = edid; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 2297bbc..256c6ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5622,7 +5622,9 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, if (conf & 0x4 || conf & 0x8) entry->lvdsconf.use_power_scripts = true; } else { - mask = ~0x5; + mask = ~0x7; + if (conf & 0x2) + entry->lvdsconf.use_acpi_for_edid = true; if (conf & 0x4) entry->lvdsconf.use_power_scripts = true; } diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index bd33a54..cc52aec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -118,6 +118,7 @@ struct dcb_entry { struct { struct sor_conf sor; bool use_straps_for_mode; + bool use_acpi_for_edid; bool use_power_scripts; } lvdsconf; struct { diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index c2fb153..5070428 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -327,12 +327,29 @@ nouveau_connector_detect_lvds(struct drm_connector *connector) if (!nv_encoder) return connector_status_disconnected; + /* Try retrieving EDID via DDC */ if (!dev_priv->vbios.fp_no_ddc) { status = nouveau_connector_detect(connector); if (status == connector_status_connected) goto out; } + /* On some laptops (Sony, i'm looking at you) there appears to + * be no direct way of accessing the panel's EDID. The only + * option available to us appears to be to ask ACPI for help.. + * + * It's important this check's before trying straps, one of the + * said manufacturer's laptops are configured in such a way + * the nouveau decides an entry in the VBIOS FP mode table is + * valid - it's not (rh#613284) + */ + if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { + if (!nouveau_acpi_edid(dev, connector)) { + status = connector_status_connected; + goto out; + } + } + /* If no EDID found above, and the VBIOS indicates a hardcoded * modeline is avalilable for the panel, set it as the panel's * native mode and exit. diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 16856e0..20ca5b8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -827,11 +827,13 @@ void nouveau_register_dsm_handler(void); void nouveau_unregister_dsm_handler(void); int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); bool nouveau_acpi_rom_supported(struct pci_dev *pdev); +int nouveau_acpi_edid(struct drm_device *, struct drm_connector *); #else static inline void nouveau_register_dsm_handler(void) {} static inline void nouveau_unregister_dsm_handler(void) {} static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } +static inline int nouveau_acpi_edid(struct drm_device *, struct drm_connector *) { return -EINVAL; } #endif /* nouveau_backlight.c */ -- cgit v0.10.2 From c58754703c7d448c94aebf5e500d4278f6fc0678 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 16 Jul 2010 16:17:27 +1000 Subject: drm/nv50: fix regression that break LVDS in some places A previous commit started additionally using the SOR link when trying to match the correct output script. However, we never fill in this field for LVDS so we can never match a script at all. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 256c6ed..0eb1b5a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5627,6 +5627,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, entry->lvdsconf.use_acpi_for_edid = true; if (conf & 0x4) entry->lvdsconf.use_power_scripts = true; + entry->lvdsconf.sor.link = (conf & 0x00000030) >> 4; } if (conf & mask) { /* -- cgit v0.10.2 From eae6192a9d0d31f657b50873789175794767bf38 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 13 Jul 2010 16:16:26 +0200 Subject: drm/nouveau: Fix a sparse warning. It doesn't like variable length arrays. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 0eb1b5a..31183a4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -209,20 +209,20 @@ static struct methods shadow_methods[] = { { "PCIROM", load_vbios_pci, true }, { "ACPI", load_vbios_acpi, true }, }; +#define NUM_SHADOW_METHODS ARRAY_SIZE(shadow_methods) static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) { - const int nr_methods = ARRAY_SIZE(shadow_methods); struct methods *methods = shadow_methods; int testscore = 3; - int scores[nr_methods], i; + int scores[NUM_SHADOW_METHODS], i; if (nouveau_vbios) { - for (i = 0; i < nr_methods; i++) + for (i = 0; i < NUM_SHADOW_METHODS; i++) if (!strcasecmp(nouveau_vbios, methods[i].desc)) break; - if (i < nr_methods) { + if (i < NUM_SHADOW_METHODS) { NV_INFO(dev, "Attempting to use BIOS image from %s\n", methods[i].desc); @@ -234,7 +234,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios); } - for (i = 0; i < nr_methods; i++) { + for (i = 0; i < NUM_SHADOW_METHODS; i++) { NV_TRACE(dev, "Attempting to load BIOS image from %s\n", methods[i].desc); data[0] = data[1] = 0; /* avoid reuse of previous image */ @@ -245,7 +245,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) } while (--testscore > 0) { - for (i = 0; i < nr_methods; i++) { + for (i = 0; i < NUM_SHADOW_METHODS; i++) { if (scores[i] == testscore) { NV_TRACE(dev, "Using BIOS image from %s\n", methods[i].desc); -- cgit v0.10.2 From a5afb7758fcf558d6a8cd2546bc18aeedfc6192a Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 18 Jul 2010 16:19:16 +0200 Subject: drm/nouveau: Don't pick an interlaced mode as the panel native mode. Rescaling interlaced modes isn't going to work correctly, and even if it did, come on, interlaced flat panels? are you pulling my leg? Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 5070428..7f749d2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -506,7 +506,8 @@ nouveau_connector_native_mode(struct drm_connector *connector) int high_w = 0, high_h = 0, high_v = 0; list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { - if (helper->mode_valid(connector, mode) != MODE_OK) + if (helper->mode_valid(connector, mode) != MODE_OK || + (mode->flags & DRM_MODE_FLAG_INTERLACE)) continue; /* Use preferred mode if there is one.. */ -- cgit v0.10.2 From 20b240059297d1748f6120f432d0db0db9115c32 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 18 Jul 2010 17:07:16 +0200 Subject: drm/nouveau: Add another Zotac FX5200 TV-out quirk. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 359506e..bb3a284 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -120,9 +120,10 @@ static bool get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) { /* Zotac FX5200 */ - if ((dev->pdev->device == 0x0322) && - (dev->pdev->subsystem_vendor == 0x19da) && - (dev->pdev->subsystem_device == 0x2035)) { + if (dev->pdev->device == 0x0322 && + dev->pdev->subsystem_vendor == 0x19da && + (dev->pdev->subsystem_device == 0x1035 || + dev->pdev->subsystem_device == 0x2035)) { *pin_mask = 0xc; return false; } -- cgit v0.10.2 From 3c7066bca990a440b512663f89680bd1c1cae6c1 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 13 Jul 2010 15:50:23 +0200 Subject: drm/nouveau: Add some PFB register defines. Also collect all the PFB registers in a single place and remove some duplicated definitions. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 31183a4..382977c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -2129,10 +2129,10 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * This also has probably been done in the scripts, but an mmio trace of * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write) */ - bios_wr32(bios, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1); + bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); /* write back the saved configuration value */ - bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); + bios_wr32(bios, NV04_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); return 1; } @@ -2209,14 +2209,14 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, reg = ROM32(bios->data[seqtbloffs += 4])) { switch (reg) { - case NV_PFB_PRE: - data = NV_PFB_PRE_CMD_PRECHARGE; + case NV04_PFB_PRE: + data = NV04_PFB_PRE_CMD_PRECHARGE; break; - case NV_PFB_PAD: - data = NV_PFB_PAD_CKE_NORMAL; + case NV04_PFB_PAD: + data = NV04_PFB_PAD_CKE_NORMAL; break; - case NV_PFB_REF: - data = NV_PFB_REF_CMD_REFRESH; + case NV04_PFB_REF: + data = NV04_PFB_REF_CMD_REFRESH; break; default: data = ROM32(bios->data[meminitdata]); @@ -2418,7 +2418,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, * offset + 1 (8 bit): mask * offset + 2 (8 bit): cmpval * - * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval". + * Test if (NV04_PFB_BOOT_0 & "mask") equals "cmpval". * If condition not met skip subsequent opcodes until condition is * inverted (INIT_NOT), or we hit INIT_RESUME */ @@ -2430,7 +2430,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, if (!iexec->execute) return 3; - data = bios_rd32(bios, NV_PFB_BOOT_0) & mask; + data = bios_rd32(bios, NV04_PFB_BOOT_0) & mask; BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n", offset, data, cmpval); @@ -6343,7 +6343,7 @@ nouveau_bios_init(struct drm_device *dev) /* these will need remembering across a suspend */ saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0); - bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV_PFB_CFG0); + bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV04_PFB_CFG0); /* init script execution disabled */ bios->execute = false; diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c index 88f9bc0..ca85da7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_calc.c +++ b/drivers/gpu/drm/nouveau/nouveau_calc.c @@ -200,7 +200,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, struct nv_sim_state sim_data; int MClk = nouveau_hw_get_clock(dev, MPLL); int NVClk = nouveau_hw_get_clock(dev, NVPLL); - uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1); + uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1); sim_data.pclk_khz = VClk; sim_data.mclk_khz = MClk; @@ -218,7 +218,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, sim_data.mem_latency = 3; sim_data.mem_page_miss = 10; } else { - sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1; + sim_data.memory_type = nvReadFB(dev, NV04_PFB_CFG0) & 0x1; sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; sim_data.mem_latency = cfg1 & 0xf; sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 5c48b1e..568bcc2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -260,19 +260,19 @@ nouveau_mem_close(struct drm_device *dev) static uint32_t nouveau_mem_detect_nv04(struct drm_device *dev) { - uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0); + uint32_t boot0 = nv_rd32(dev, NV04_PFB_BOOT_0); if (boot0 & 0x00000100) return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; - switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) { - case NV04_BOOT_0_RAM_AMOUNT_32MB: + switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) { + case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB: return 32 * 1024 * 1024; - case NV04_BOOT_0_RAM_AMOUNT_16MB: + case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB: return 16 * 1024 * 1024; - case NV04_BOOT_0_RAM_AMOUNT_8MB: + case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB: return 8 * 1024 * 1024; - case NV04_BOOT_0_RAM_AMOUNT_4MB: + case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB: return 4 * 1024 * 1024; } @@ -318,10 +318,10 @@ nouveau_mem_detect(struct drm_device *dev) dev_priv->vram_size = nouveau_mem_detect_nforce(dev); } else if (dev_priv->card_type < NV_50) { - dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); - dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; + dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); + dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; } else { - dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); + dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; dev_priv->vram_size &= 0xffffffff00ll; if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) { diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index b6391a1..9c1056c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -1,19 +1,64 @@ +#define NV04_PFB_BOOT_0 0x00100000 +# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003 +# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000 +# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001 +# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002 +# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003 +# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004 +# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028 +# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000 +# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008 +# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010 +# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018 +# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020 +# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028 +# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100 +# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000 +#define NV04_PFB_DEBUG_0 0x00100080 +# define NV04_PFB_DEBUG_0_PAGE_MODE 0x00000001 +# define NV04_PFB_DEBUG_0_REFRESH_OFF 0x00000010 +# define NV04_PFB_DEBUG_0_REFRESH_COUNTX64 0x00003f00 +# define NV04_PFB_DEBUG_0_REFRESH_SLOW_CLK 0x00004000 +# define NV04_PFB_DEBUG_0_SAFE_MODE 0x00008000 +# define NV04_PFB_DEBUG_0_ALOM_ENABLE 0x00010000 +# define NV04_PFB_DEBUG_0_CASOE 0x00100000 +# define NV04_PFB_DEBUG_0_CKE_INVERT 0x10000000 +# define NV04_PFB_DEBUG_0_REFINC 0x20000000 +# define NV04_PFB_DEBUG_0_SAVE_POWER_OFF 0x40000000 +#define NV04_PFB_CFG0 0x00100200 +# define NV04_PFB_CFG0_SCRAMBLE 0x20000000 +#define NV04_PFB_CFG1 0x00100204 +#define NV04_PFB_FIFO_DATA 0x0010020c +# define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 +# define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 +#define NV10_PFB_REFCTRL 0x00100210 +# define NV10_PFB_REFCTRL_VALID_1 (1 << 31) +#define NV04_PFB_PAD 0x0010021c +# define NV04_PFB_PAD_CKE_NORMAL (1 << 0) +#define NV10_PFB_TILE(i) (0x00100240 + (i*16)) +#define NV10_PFB_TILE__SIZE 8 +#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) +#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) +#define NV10_PFB_TSTATUS(i) (0x0010024c + (i*16)) +#define NV04_PFB_REF 0x001002d0 +# define NV04_PFB_REF_CMD_REFRESH (1 << 0) +#define NV04_PFB_PRE 0x001002d4 +# define NV04_PFB_PRE_CMD_PRECHARGE (1 << 0) +#define NV10_PFB_CLOSE_PAGE2 0x0010033c +#define NV04_PFB_SCRAMBLE(i) (0x00100400 + 4 * (i)) +#define NV40_PFB_TILE(i) (0x00100600 + (i*16)) +#define NV40_PFB_TILE__SIZE_0 12 +#define NV40_PFB_TILE__SIZE_1 15 +#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) +#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) +#define NV40_PFB_TSTATUS(i) (0x0010060c + (i*16)) +#define NV40_PFB_UNK_800 0x00100800 -#define NV03_BOOT_0 0x00100000 -# define NV03_BOOT_0_RAM_AMOUNT 0x00000003 -# define NV03_BOOT_0_RAM_AMOUNT_8MB 0x00000000 -# define NV03_BOOT_0_RAM_AMOUNT_2MB 0x00000001 -# define NV03_BOOT_0_RAM_AMOUNT_4MB 0x00000002 -# define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM 0x00000003 -# define NV04_BOOT_0_RAM_AMOUNT_32MB 0x00000000 -# define NV04_BOOT_0_RAM_AMOUNT_4MB 0x00000001 -# define NV04_BOOT_0_RAM_AMOUNT_8MB 0x00000002 -# define NV04_BOOT_0_RAM_AMOUNT_16MB 0x00000003 - -#define NV04_FIFO_DATA 0x0010020c -# define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 -# define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 +#define NV_PEXTDEV_BOOT_0 0x00101000 +#define NV_PEXTDEV_BOOT_0_RAMCFG 0x0000003c +# define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12) +#define NV_PEXTDEV_BOOT_3 0x0010100c #define NV_RAMIN 0x00700000 @@ -131,23 +176,6 @@ #define NV04_PTIMER_TIME_1 0x00009410 #define NV04_PTIMER_ALARM_0 0x00009420 -#define NV04_PFB_CFG0 0x00100200 -#define NV04_PFB_CFG1 0x00100204 -#define NV40_PFB_020C 0x0010020C -#define NV10_PFB_TILE(i) (0x00100240 + (i*16)) -#define NV10_PFB_TILE__SIZE 8 -#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) -#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) -#define NV10_PFB_TSTATUS(i) (0x0010024C + (i*16)) -#define NV10_PFB_CLOSE_PAGE2 0x0010033C -#define NV40_PFB_TILE(i) (0x00100600 + (i*16)) -#define NV40_PFB_TILE__SIZE_0 12 -#define NV40_PFB_TILE__SIZE_1 15 -#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) -#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) -#define NV40_PFB_TSTATUS(i) (0x0010060C + (i*16)) -#define NV40_PFB_UNK_800 0x00100800 - #define NV04_PGRAPH_DEBUG_0 0x00400080 #define NV04_PGRAPH_DEBUG_1 0x00400084 #define NV04_PGRAPH_DEBUG_2 0x00400088 diff --git a/drivers/gpu/drm/nouveau/nv40_mc.c b/drivers/gpu/drm/nouveau/nv40_mc.c index 2a3495e..e4e72c1 100644 --- a/drivers/gpu/drm/nouveau/nv40_mc.c +++ b/drivers/gpu/drm/nouveau/nv40_mc.c @@ -19,7 +19,7 @@ nv40_mc_init(struct drm_device *dev) case 0x46: /* G72 */ case 0x4e: case 0x4c: /* C51_G7X */ - tmp = nv_rd32(dev, NV40_PFB_020C); + tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA); nv_wr32(dev, NV40_PMC_1700, tmp); nv_wr32(dev, NV40_PMC_1704, 0); nv_wr32(dev, NV40_PMC_1708, 0); diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h index 5998c35..ad64673 100644 --- a/drivers/gpu/drm/nouveau/nvreg.h +++ b/drivers/gpu/drm/nouveau/nvreg.h @@ -147,28 +147,6 @@ # define NV_VIO_GX_DONT_CARE_INDEX 0x07 # define NV_VIO_GX_BIT_MASK_INDEX 0x08 -#define NV_PFB_BOOT_0 0x00100000 -#define NV_PFB_CFG0 0x00100200 -#define NV_PFB_CFG1 0x00100204 -#define NV_PFB_CSTATUS 0x0010020C -#define NV_PFB_REFCTRL 0x00100210 -# define NV_PFB_REFCTRL_VALID_1 (1 << 31) -#define NV_PFB_PAD 0x0010021C -# define NV_PFB_PAD_CKE_NORMAL (1 << 0) -#define NV_PFB_TILE_NV10 0x00100240 -#define NV_PFB_TILE_SIZE_NV10 0x00100244 -#define NV_PFB_REF 0x001002D0 -# define NV_PFB_REF_CMD_REFRESH (1 << 0) -#define NV_PFB_PRE 0x001002D4 -# define NV_PFB_PRE_CMD_PRECHARGE (1 << 0) -#define NV_PFB_CLOSE_PAGE2 0x0010033C -#define NV_PFB_TILE_NV40 0x00100600 -#define NV_PFB_TILE_SIZE_NV40 0x00100604 - -#define NV_PEXTDEV_BOOT_0 0x00101000 -# define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12) -#define NV_PEXTDEV_BOOT_3 0x0010100c - #define NV_PCRTC_INTR_0 0x00600100 # define NV_PCRTC_INTR_0_VBLANK (1 << 0) #define NV_PCRTC_INTR_EN_0 0x00600140 -- cgit v0.10.2 From 67eda20e6b7a757ed45f6b5a8a4d30c2a0d47c7a Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 13 Jul 2010 15:59:50 +0200 Subject: drm/nv04-nv3x: Implement init-compute-mem. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Init-compute-mem was the last piece missing for nv0x-nv3x card cold-booting. This implementation is somewhat lacking but it's been reported to work on most chipsets it was tested in. Let me know if it breaks suspend to RAM for you. Signed-off-by: Francisco Jerez Tested-by: Patrice Mandin Tested-by: Ben Skeggs Tested-by: Xavier Chantry Tested-by: Marcin Kościelnicki Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 382977c..665f0d6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -28,6 +28,8 @@ #include "nouveau_hw.h" #include "nouveau_encoder.h" +#include + /* these defines are made up */ #define NV_CIO_CRE_44_HEADA 0x0 #define NV_CIO_CRE_44_HEADB 0x3 @@ -2067,6 +2069,323 @@ init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) return 5; } +static inline void +bios_md32(struct nvbios *bios, uint32_t reg, + uint32_t mask, uint32_t val) +{ + bios_wr32(bios, reg, (bios_rd32(bios, reg) & ~mask) | val); +} + +static uint32_t +peek_fb(struct drm_device *dev, struct io_mapping *fb, + uint32_t off) +{ + uint32_t val = 0; + + if (off < pci_resource_len(dev->pdev, 1)) { + uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off); + + val = ioread32(p); + + io_mapping_unmap_atomic(p); + } + + return val; +} + +static void +poke_fb(struct drm_device *dev, struct io_mapping *fb, + uint32_t off, uint32_t val) +{ + if (off < pci_resource_len(dev->pdev, 1)) { + uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off); + + iowrite32(val, p); + wmb(); + + io_mapping_unmap_atomic(p); + } +} + +static inline bool +read_back_fb(struct drm_device *dev, struct io_mapping *fb, + uint32_t off, uint32_t val) +{ + poke_fb(dev, fb, off, val); + return val == peek_fb(dev, fb, off); +} + +static int +nv04_init_compute_mem(struct nvbios *bios) +{ + struct drm_device *dev = bios->dev; + uint32_t patt = 0xdeadbeef; + struct io_mapping *fb; + int i; + + /* Map the framebuffer aperture */ + fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), + pci_resource_len(dev->pdev, 1)); + if (!fb) + return -ENOMEM; + + /* Sequencer and refresh off */ + NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); + bios_md32(bios, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF); + + bios_md32(bios, NV04_PFB_BOOT_0, ~0, + NV04_PFB_BOOT_0_RAM_AMOUNT_16MB | + NV04_PFB_BOOT_0_RAM_WIDTH_128 | + NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT); + + for (i = 0; i < 4; i++) + poke_fb(dev, fb, 4 * i, patt); + + poke_fb(dev, fb, 0x400000, patt + 1); + + if (peek_fb(dev, fb, 0) == patt + 1) { + bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, + NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT); + bios_md32(bios, NV04_PFB_DEBUG_0, + NV04_PFB_DEBUG_0_REFRESH_OFF, 0); + + for (i = 0; i < 4; i++) + poke_fb(dev, fb, 4 * i, patt); + + if ((peek_fb(dev, fb, 0xc) & 0xffff) != (patt & 0xffff)) + bios_md32(bios, NV04_PFB_BOOT_0, + NV04_PFB_BOOT_0_RAM_WIDTH_128 | + NV04_PFB_BOOT_0_RAM_AMOUNT, + NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); + + } else if ((peek_fb(dev, fb, 0xc) & 0xffff0000) != + (patt & 0xffff0000)) { + bios_md32(bios, NV04_PFB_BOOT_0, + NV04_PFB_BOOT_0_RAM_WIDTH_128 | + NV04_PFB_BOOT_0_RAM_AMOUNT, + NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); + + } else if (peek_fb(dev, fb, 0) == patt) { + if (read_back_fb(dev, fb, 0x800000, patt)) + bios_md32(bios, NV04_PFB_BOOT_0, + NV04_PFB_BOOT_0_RAM_AMOUNT, + NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); + else + bios_md32(bios, NV04_PFB_BOOT_0, + NV04_PFB_BOOT_0_RAM_AMOUNT, + NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); + + bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, + NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT); + + } else if (!read_back_fb(dev, fb, 0x800000, patt)) { + bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, + NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); + + } + + /* Refresh on, sequencer on */ + bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); + NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); + + io_mapping_free(fb); + return 0; +} + +static const uint8_t * +nv05_memory_config(struct nvbios *bios) +{ + /* Defaults for BIOSes lacking a memory config table */ + static const uint8_t default_config_tab[][2] = { + { 0x24, 0x00 }, + { 0x28, 0x00 }, + { 0x24, 0x01 }, + { 0x1f, 0x00 }, + { 0x0f, 0x00 }, + { 0x17, 0x00 }, + { 0x06, 0x00 }, + { 0x00, 0x00 } + }; + int i = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & + NV_PEXTDEV_BOOT_0_RAMCFG) >> 2; + + if (bios->legacy.mem_init_tbl_ptr) + return &bios->data[bios->legacy.mem_init_tbl_ptr + 2 * i]; + else + return default_config_tab[i]; +} + +static int +nv05_init_compute_mem(struct nvbios *bios) +{ + struct drm_device *dev = bios->dev; + const uint8_t *ramcfg = nv05_memory_config(bios); + uint32_t patt = 0xdeadbeef; + struct io_mapping *fb; + int i, v; + + /* Map the framebuffer aperture */ + fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), + pci_resource_len(dev->pdev, 1)); + if (!fb) + return -ENOMEM; + + /* Sequencer off */ + NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); + + if (bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE) + goto out; + + bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); + + /* If present load the hardcoded scrambling table */ + if (bios->legacy.mem_init_tbl_ptr) { + uint32_t *scramble_tab = (uint32_t *)&bios->data[ + bios->legacy.mem_init_tbl_ptr + 0x10]; + + for (i = 0; i < 8; i++) + bios_wr32(bios, NV04_PFB_SCRAMBLE(i), + ROM32(scramble_tab[i])); + } + + /* Set memory type/width/length defaults depending on the straps */ + bios_md32(bios, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]); + + if (ramcfg[1] & 0x80) + bios_md32(bios, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE); + + bios_md32(bios, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20); + bios_md32(bios, NV04_PFB_CFG1, 0, 1); + + /* Probe memory bus width */ + for (i = 0; i < 4; i++) + poke_fb(dev, fb, 4 * i, patt); + + if (peek_fb(dev, fb, 0xc) != patt) + bios_md32(bios, NV04_PFB_BOOT_0, + NV04_PFB_BOOT_0_RAM_WIDTH_128, 0); + + /* Probe memory length */ + v = bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT; + + if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB && + (!read_back_fb(dev, fb, 0x1000000, ++patt) || + !read_back_fb(dev, fb, 0, ++patt))) + bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, + NV04_PFB_BOOT_0_RAM_AMOUNT_16MB); + + if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB && + !read_back_fb(dev, fb, 0x800000, ++patt)) + bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, + NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); + + if (!read_back_fb(dev, fb, 0x400000, ++patt)) + bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, + NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); + +out: + /* Sequencer on */ + NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); + + io_mapping_free(fb); + return 0; +} + +static int +nv10_init_compute_mem(struct nvbios *bios) +{ + struct drm_device *dev = bios->dev; + struct drm_nouveau_private *dev_priv = bios->dev->dev_private; + const int mem_width[] = { 0x10, 0x00, 0x20 }; + const int mem_width_count = (dev_priv->chipset >= 0x17 ? 3 : 2); + uint32_t patt = 0xdeadbeef; + struct io_mapping *fb; + int i, j, k; + + /* Map the framebuffer aperture */ + fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), + pci_resource_len(dev->pdev, 1)); + if (!fb) + return -ENOMEM; + + bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); + + /* Probe memory bus width */ + for (i = 0; i < mem_width_count; i++) { + bios_md32(bios, NV04_PFB_CFG0, 0x30, mem_width[i]); + + for (j = 0; j < 4; j++) { + for (k = 0; k < 4; k++) + poke_fb(dev, fb, 0x1c, 0); + + poke_fb(dev, fb, 0x1c, patt); + poke_fb(dev, fb, 0x3c, 0); + + if (peek_fb(dev, fb, 0x1c) == patt) + goto mem_width_found; + } + } + +mem_width_found: + patt <<= 1; + + /* Probe amount of installed memory */ + for (i = 0; i < 4; i++) { + int off = bios_rd32(bios, NV04_PFB_FIFO_DATA) - 0x100000; + + poke_fb(dev, fb, off, patt); + poke_fb(dev, fb, 0, 0); + + peek_fb(dev, fb, 0); + peek_fb(dev, fb, 0); + peek_fb(dev, fb, 0); + peek_fb(dev, fb, 0); + + if (peek_fb(dev, fb, off) == patt) + goto amount_found; + } + + /* IC missing - disable the upper half memory space. */ + bios_md32(bios, NV04_PFB_CFG0, 0x1000, 0); + +amount_found: + io_mapping_free(fb); + return 0; +} + +static int +nv20_init_compute_mem(struct nvbios *bios) +{ + struct drm_device *dev = bios->dev; + struct drm_nouveau_private *dev_priv = bios->dev->dev_private; + uint32_t mask = (dev_priv->chipset >= 0x25 ? 0x300 : 0x900); + uint32_t amount, off; + struct io_mapping *fb; + + /* Map the framebuffer aperture */ + fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), + pci_resource_len(dev->pdev, 1)); + if (!fb) + return -ENOMEM; + + bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); + + /* Allow full addressing */ + bios_md32(bios, NV04_PFB_CFG0, 0, mask); + + amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); + for (off = amount; off > 0x2000000; off -= 0x2000000) + poke_fb(dev, fb, off - 4, off); + + amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); + if (amount != peek_fb(dev, fb, amount - 4)) + /* IC missing - disable the upper half memory space. */ + bios_md32(bios, NV04_PFB_CFG0, mask, 0); + + io_mapping_free(fb); + return 0; +} + static int init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) { @@ -2075,64 +2394,57 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) * * offset (8 bit): opcode * - * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so - * that the hardware can correctly calculate how much VRAM it has - * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C)) + * This opcode is meant to set the PFB memory config registers + * appropriately so that we can correctly calculate how much VRAM it + * has (on nv10 and better chipsets the amount of installed VRAM is + * subsequently reported in NV_PFB_CSTATUS (0x10020C)). * - * The implementation of this opcode in general consists of two parts: - * 1) determination of the memory bus width - * 2) determination of how many of the card's RAM pads have ICs attached + * The implementation of this opcode in general consists of several + * parts: * - * 1) is done by a cunning combination of writes to offsets 0x1c and - * 0x3c in the framebuffer, and seeing whether the written values are - * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0 + * 1) Determination of memory type and density. Only necessary for + * really old chipsets, the memory type reported by the strap bits + * (0x101000) is assumed to be accurate on nv05 and newer. * - * 2) is done by a cunning combination of writes to an offset slightly - * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing - * if the test pattern can be read back. This then affects bits 12-15 of - * NV_PFB_CFG0 + * 2) Determination of the memory bus width. Usually done by a cunning + * combination of writes to offsets 0x1c and 0x3c in the fb, and + * seeing whether the written values are read back correctly. * - * In this context a "cunning combination" may include multiple reads - * and writes to varying locations, often alternating the test pattern - * and 0, doubtless to make sure buffers are filled, residual charges - * on tracks are removed etc. + * Only necessary on nv0x-nv1x and nv34, on the other cards we can + * trust the straps. * - * Unfortunately, the "cunning combination"s mentioned above, and the - * changes to the bits in NV_PFB_CFG0 differ with nearly every bios - * trace I have. + * 3) Determination of how many of the card's RAM pads have ICs + * attached, usually done by a cunning combination of writes to an + * offset slightly less than the maximum memory reported by + * NV_PFB_CSTATUS, then seeing if the test pattern can be read back. * - * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which - * we started was correct, and use that instead + * This appears to be a NOP on IGPs and NV4x or newer chipsets, both io + * logs of the VBIOS and kmmio traces of the binary driver POSTing the + * card show nothing being done for this opcode. Why is it still listed + * in the table?! */ /* no iexec->execute check by design */ - /* - * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS - * and kmmio traces of the binary driver POSTing the card show nothing - * being done for this opcode. why is it still listed in the table?! - */ - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; + int ret; - if (dev_priv->card_type >= NV_40) - return 1; - - /* - * On every card I've seen, this step gets done for us earlier in - * the init scripts - uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01); - bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20); - */ - - /* - * This also has probably been done in the scripts, but an mmio trace of - * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write) - */ - bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); + if (dev_priv->chipset >= 0x40 || + dev_priv->chipset == 0x1a || + dev_priv->chipset == 0x1f) + ret = 0; + else if (dev_priv->chipset >= 0x20 && + dev_priv->chipset != 0x34) + ret = nv20_init_compute_mem(bios); + else if (dev_priv->chipset >= 0x10) + ret = nv10_init_compute_mem(bios); + else if (dev_priv->chipset >= 0x5) + ret = nv05_init_compute_mem(bios); + else + ret = nv04_init_compute_mem(bios); - /* write back the saved configuration value */ - bios_wr32(bios, NV04_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); + if (ret) + return ret; return 1; } @@ -6320,7 +6632,6 @@ nouveau_bios_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvbios *bios = &dev_priv->vbios; - uint32_t saved_nv_pextdev_boot_0; bool was_locked; int ret; @@ -6341,27 +6652,16 @@ nouveau_bios_init(struct drm_device *dev) if (!bios->major_version) /* we don't run version 0 bios */ return 0; - /* these will need remembering across a suspend */ - saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0); - bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV04_PFB_CFG0); - /* init script execution disabled */ bios->execute = false; /* ... unless card isn't POSTed already */ if (!nouveau_bios_posted(dev)) { - NV_INFO(dev, "Adaptor not initialised\n"); - if (dev_priv->card_type < NV_40) { - NV_ERROR(dev, "Unable to POST this chipset\n"); - return -ENODEV; - } - - NV_INFO(dev, "Running VBIOS init tables\n"); + NV_INFO(dev, "Adaptor not initialised, " + "running VBIOS init tables.\n"); bios->execute = true; } - bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0); - ret = nouveau_run_vbios_init(dev); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index cc52aec..024458a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -251,8 +251,6 @@ struct nvbios { struct { int crtchead; - /* these need remembering across suspend */ - uint32_t saved_nv_pfb_cfg0; } state; struct { -- cgit v0.10.2 From 6d6a413aa23c8bc7a5787596e06f3d6d8d4f11c7 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 19 Jul 2010 15:28:41 +0200 Subject: drm/i2c/ch7006: Don't assume that the specified config points to static memory. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index 3e2c9da..833b35f 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c @@ -33,7 +33,7 @@ static void ch7006_encoder_set_config(struct drm_encoder *encoder, { struct ch7006_priv *priv = to_ch7006_priv(encoder); - priv->params = params; + priv->params = *(struct ch7006_encoder_params *)params; } static void ch7006_encoder_destroy(struct drm_encoder *encoder) @@ -114,7 +114,7 @@ static void ch7006_encoder_mode_set(struct drm_encoder *encoder, { struct i2c_client *client = drm_i2c_encoder_get_client(encoder); struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct ch7006_encoder_params *params = priv->params; + struct ch7006_encoder_params *params = &priv->params; struct ch7006_state *state = &priv->state; uint8_t *regs = state->regs; struct ch7006_mode *mode = priv->mode; diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h index b06d3d9..1c6d2e3 100644 --- a/drivers/gpu/drm/i2c/ch7006_priv.h +++ b/drivers/gpu/drm/i2c/ch7006_priv.h @@ -77,7 +77,7 @@ struct ch7006_state { }; struct ch7006_priv { - struct ch7006_encoder_params *params; + struct ch7006_encoder_params params; struct ch7006_mode *mode; struct ch7006_state state; -- cgit v0.10.2 From 6d416d80f720f71e2dfe903d672bcca071822538 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 19 Jul 2010 15:55:08 +0200 Subject: drm/nouveau: Add some generic I2C gadget detection code. Clean up and move the external TV encoder detection code to nouveau_i2c.c, it's also going to be useful for external TMDS and DDC detection. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 7f749d2..27df006 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -139,26 +139,10 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, struct nouveau_encoder **pnv_encoder) { struct drm_device *dev = connector->dev; - uint8_t out_buf[] = { 0x0, 0x0}, buf[2]; int ret, flags, i; - struct i2c_msg msgs[] = { - { - .addr = 0x50, - .flags = 0, - .len = 1, - .buf = out_buf, - }, - { - .addr = 0x50, - .flags = I2C_M_RD, - .len = 1, - .buf = buf, - } - }; - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - struct nouveau_i2c_chan *i2c = NULL; + struct nouveau_i2c_chan *i2c; struct nouveau_encoder *nv_encoder; struct drm_mode_object *obj; int id; @@ -178,10 +162,10 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, continue; nouveau_connector_ddc_prepare(connector, &flags); - ret = i2c_transfer(&i2c->adapter, msgs, 2); + ret = nouveau_probe_i2c_addr(i2c, 0x50); nouveau_connector_ddc_finish(connector, flags); - if (ret == 2) { + if (ret) { *pnv_encoder = nv_encoder; return i2c; } diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 316a3c7..97ba89e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c @@ -278,3 +278,37 @@ nouveau_i2c_find(struct drm_device *dev, int index) return i2c->chan; } +bool +nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr) +{ + struct i2c_msg msg = { + .addr = addr, + .len = 0, + }; + + return i2c_transfer(&i2c->adapter, &msg, 1) == 1; +} + +int +nouveau_i2c_identify(struct drm_device *dev, const char *what, + struct i2c_board_info *info, int index) +{ + struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index); + int was_locked, i; + + was_locked = NVLockVgaCrtcs(dev, false); + NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); + + for (i = 0; info[i].addr; i++) { + if (nouveau_probe_i2c_addr(i2c, info[i].addr)) { + NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); + goto out; + } + } + + NV_DEBUG(dev, "No devices found.\n"); +out: + NVLockVgaCrtcs(dev, was_locked); + + return info[i].addr ? i : -ENODEV; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h index c8eaf7a..6dd2f87 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.h +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h @@ -45,6 +45,9 @@ struct nouveau_i2c_chan { int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index); void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *); struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index); +bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr); +int nouveau_i2c_identify(struct drm_device *dev, const char *what, + struct i2c_board_info *info, int index); int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte, uint8_t *read_byte); diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index 84b5954..8de1eef 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c @@ -34,69 +34,26 @@ #include "i2c/ch7006.h" -static struct { - struct i2c_board_info board_info; - struct drm_encoder_funcs funcs; - struct drm_encoder_helper_funcs hfuncs; - void *params; - -} nv04_tv_encoder_info[] = { +static struct i2c_board_info nv04_tv_encoder_info[] = { { - .board_info = { I2C_BOARD_INFO("ch7006", 0x75) }, - .params = &(struct ch7006_encoder_params) { + I2C_BOARD_INFO("ch7006", 0x75), + .platform_data = &(struct ch7006_encoder_params) { CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER, 0, 0, 0, CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED, CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC - }, + } }, + { } }; -static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr) -{ - struct i2c_msg msg = { - .addr = addr, - .len = 0, - }; - - return i2c_transfer(adapter, &msg, 1) == 1; -} - int nv04_tv_identify(struct drm_device *dev, int i2c_index) { - struct nouveau_i2c_chan *i2c; - bool was_locked; - int i, ret; - - NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index); - - i2c = nouveau_i2c_find(dev, i2c_index); - if (!i2c) - return -ENODEV; - - was_locked = NVLockVgaCrtcs(dev, false); - - for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) { - if (probe_i2c_addr(&i2c->adapter, - nv04_tv_encoder_info[i].board_info.addr)) { - ret = i; - break; - } - } - - if (i < ARRAY_SIZE(nv04_tv_encoder_info)) { - NV_TRACE(dev, "Detected TV encoder: %s\n", - nv04_tv_encoder_info[i].board_info.type); - - } else { - NV_TRACE(dev, "No TV encoders found.\n"); - i = -ENODEV; - } - - NVLockVgaCrtcs(dev, was_locked); - return i; + return nouveau_i2c_identify(dev, "TV encoder", + nv04_tv_encoder_info, i2c_index); } + #define PLLSEL_TV_CRTC1_MASK \ (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \ | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1) @@ -214,32 +171,33 @@ static void nv04_tv_commit(struct drm_encoder *encoder) static void nv04_tv_destroy(struct drm_encoder *encoder) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - to_encoder_slave(encoder)->slave_funcs->destroy(encoder); drm_encoder_cleanup(encoder); - kfree(nv_encoder); + kfree(encoder->helper_private); + kfree(nouveau_encoder(encoder)); } +static const struct drm_encoder_funcs nv04_tv_funcs = { + .destroy = nv04_tv_destroy, +}; + int nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) { struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; struct drm_device *dev = connector->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct i2c_adapter *adap; - struct drm_encoder_funcs *funcs = NULL; - struct drm_encoder_helper_funcs *hfuncs = NULL; - struct drm_encoder_slave_funcs *sfuncs = NULL; - int i2c_index = entry->i2c_index; + struct drm_encoder_helper_funcs *hfuncs; + struct drm_encoder_slave_funcs *sfuncs; + struct nouveau_i2c_chan *i2c = + nouveau_i2c_find(dev, entry->i2c_index); int type, ret; bool was_locked; /* Ensure that we can talk to this encoder */ - type = nv04_tv_identify(dev, i2c_index); + type = nv04_tv_identify(dev, entry->i2c_index); if (type < 0) return type; @@ -248,41 +206,37 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) if (!nv_encoder) return -ENOMEM; + hfuncs = kzalloc(sizeof(*hfuncs), GFP_KERNEL); + if (!hfuncs) { + ret = -ENOMEM; + goto fail_free; + } + /* Initialize the common members */ encoder = to_drm_encoder(nv_encoder); - funcs = &nv04_tv_encoder_info[type].funcs; - hfuncs = &nv04_tv_encoder_info[type].hfuncs; - - drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC); + drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC); drm_encoder_helper_add(encoder, hfuncs); encoder->possible_crtcs = entry->heads; encoder->possible_clones = 0; - nv_encoder->dcb = entry; nv_encoder->or = ffs(entry->or) - 1; /* Run the slave-specific initialization */ - adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter; - was_locked = NVLockVgaCrtcs(dev, false); - ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), adap, - &nv04_tv_encoder_info[type].board_info); + ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), + &i2c->adapter, &nv04_tv_encoder_info[type]); NVLockVgaCrtcs(dev, was_locked); if (ret < 0) - goto fail; + goto fail_cleanup; /* Fill the function pointers */ sfuncs = to_encoder_slave(encoder)->slave_funcs; - *funcs = (struct drm_encoder_funcs) { - .destroy = nv04_tv_destroy, - }; - *hfuncs = (struct drm_encoder_helper_funcs) { .dpms = nv04_tv_dpms, .save = sfuncs->save, @@ -294,16 +248,17 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) .detect = sfuncs->detect, }; - /* Set the slave encoder configuration */ - sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params); + /* Attach it to the specified connector. */ + sfuncs->set_config(encoder, nv04_tv_encoder_info[type].platform_data); sfuncs->create_resources(encoder, connector); - drm_mode_connector_attach_encoder(connector, encoder); + return 0; -fail: +fail_cleanup: drm_encoder_cleanup(encoder); - + kfree(hfuncs); +fail_free: kfree(nv_encoder); return ret; } -- cgit v0.10.2 From d06ab841d14f3747823e88e5172047367e051a32 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 20 Jul 2010 02:33:16 +0200 Subject: drm/nouveau: Remove useless CRTC_OWNER logging. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index b35b7ed..93200da 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -81,8 +81,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) } ownerknown: - NV_INFO(dev, "Initial CRTC_OWNER is %d\n", dev_priv->crtc_owner); - /* we need to ensure the heads are not tied henceforth, or reading any * 8 bit reg on head B will fail * setting a single arbitrary head solves that */ @@ -244,11 +242,8 @@ nv04_display_restore(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) crtc->funcs->restore(crtc); - if (nv_two_heads(dev)) { - NV_INFO(dev, "Restoring CRTC_OWNER to %d.\n", - dev_priv->crtc_owner); + if (nv_two_heads(dev)) NVSetOwner(dev, dev_priv->crtc_owner); - } NVLockVgaCrtcs(dev, true); } -- cgit v0.10.2 From 03cd06ca9046190e8418749c2c8f636e2625556c Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 20 Jul 2010 03:08:25 +0200 Subject: drm/nouveau: No need to lock/unlock the VGA CRTC regs all the time. Locking only makes sense in the VBIOS parsing code as it's executed before CRTC init. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 665f0d6..3b5523e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6607,7 +6607,6 @@ static bool nouveau_bios_posted(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - bool was_locked; unsigned htotal; if (dev_priv->chipset >= NV_50) { @@ -6617,13 +6616,14 @@ nouveau_bios_posted(struct drm_device *dev) return true; } - was_locked = NVLockVgaCrtcs(dev, false); + NVLockVgaCrtcs(dev, false); htotal = NVReadVgaCrtc(dev, 0, 0x06); htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; - NVLockVgaCrtcs(dev, was_locked); + NVLockVgaCrtcs(dev, true); + return (htotal != 0); } @@ -6632,7 +6632,6 @@ nouveau_bios_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvbios *bios = &dev_priv->vbios; - bool was_locked; int ret; if (!NVInitVBIOS(dev)) @@ -6667,14 +6666,14 @@ nouveau_bios_init(struct drm_device *dev) return ret; /* feature_byte on BMP is poor, but init always sets CR4B */ - was_locked = NVLockVgaCrtcs(dev, false); + NVLockVgaCrtcs(dev, false); if (bios->major_version < 5) bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40; /* all BIT systems need p_f_m_t for digital_min_front_porch */ if (bios->is_mobile || bios->major_version >= 5) ret = parse_fp_mode_table(dev, bios); - NVLockVgaCrtcs(dev, was_locked); + NVLockVgaCrtcs(dev, true); /* allow subsequent scripts to execute */ bios->execute = true; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 27df006..734e926 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -102,44 +102,12 @@ nouveau_connector_destroy(struct drm_connector *drm_connector) kfree(drm_connector); } -static void -nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags) -{ - struct drm_nouveau_private *dev_priv = connector->dev->dev_private; - - if (dev_priv->card_type >= NV_50) - return; - - *flags = 0; - if (NVLockVgaCrtcs(dev_priv->dev, false)) - *flags |= 1; - if (nv_heads_tied(dev_priv->dev)) - *flags |= 2; - - if (*flags & 2) - NVSetOwner(dev_priv->dev, 0); /* necessary? */ -} - -static void -nouveau_connector_ddc_finish(struct drm_connector *connector, int flags) -{ - struct drm_nouveau_private *dev_priv = connector->dev->dev_private; - - if (dev_priv->card_type >= NV_50) - return; - - if (flags & 2) - NVSetOwner(dev_priv->dev, 4); - if (flags & 1) - NVLockVgaCrtcs(dev_priv->dev, true); -} - static struct nouveau_i2c_chan * nouveau_connector_ddc_detect(struct drm_connector *connector, struct nouveau_encoder **pnv_encoder) { struct drm_device *dev = connector->dev; - int ret, flags, i; + int i; for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { struct nouveau_i2c_chan *i2c; @@ -155,17 +123,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, if (!obj) continue; nv_encoder = nouveau_encoder(obj_to_encoder(obj)); + i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); - if (nv_encoder->dcb->i2c_index < 0xf) - i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); - if (!i2c) - continue; - - nouveau_connector_ddc_prepare(connector, &flags); - ret = nouveau_probe_i2c_addr(i2c, 0x50); - nouveau_connector_ddc_finish(connector, flags); - - if (ret) { + if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { *pnv_encoder = nv_encoder; return i2c; } @@ -218,7 +178,7 @@ nouveau_connector_detect(struct drm_connector *connector) struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_encoder *nv_encoder = NULL; struct nouveau_i2c_chan *i2c; - int type, flags; + int type; /* Cleanup the previous EDID block. */ if (nv_connector->edid) { @@ -229,9 +189,7 @@ nouveau_connector_detect(struct drm_connector *connector) i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); if (i2c) { - nouveau_connector_ddc_prepare(connector, &flags); nv_connector->edid = drm_get_edid(connector, &i2c->adapter); - nouveau_connector_ddc_finish(connector, flags); drm_mode_connector_update_edid_property(connector, nv_connector->edid); if (!nv_connector->edid) { diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 6c8cd38..e93fbcc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -321,10 +321,9 @@ nouveau_pci_resume(struct pci_dev *pdev) NV_ERROR(dev, "Could not pin/map cursor.\n"); } - if (dev_priv->card_type < NV_50) { + if (dev_priv->card_type < NV_50) nv04_display_restore(dev); - NVLockVgaCrtcs(dev, false); - } else + else nv50_display_init(dev); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index 93200da..c6df391 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -32,8 +32,6 @@ #include "nouveau_encoder.h" #include "nouveau_connector.h" -#define MULTIPLE_ENCODERS(e) (e & (e - 1)) - static void nv04_display_store_initial_head_owner(struct drm_device *dev) { @@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) if (dev_priv->chipset != 0x11) { dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44); - goto ownerknown; + return; } /* reading CR44 is broken on nv11, so we attempt to infer it */ @@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) bool tvA = false; bool tvB = false; - NVLockVgaCrtcs(dev, false); - slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) & 0x80; if (slaved_on_B) @@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) & MASK(NV_CIO_CRE_LCD_LCD_SELECT)); - NVLockVgaCrtcs(dev, true); - if (slaved_on_A && !tvA) dev_priv->crtc_owner = 0x0; else if (slaved_on_B && !tvB) @@ -79,12 +73,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) else dev_priv->crtc_owner = 0x0; } - -ownerknown: - /* we need to ensure the heads are not tied henceforth, or reading any - * 8 bit reg on head B will fail - * setting a single arbitrary head solves that */ - NVSetOwner(dev, 0); } int @@ -99,8 +87,13 @@ nv04_display_create(struct drm_device *dev) NV_DEBUG_KMS(dev, "\n"); - if (nv_two_heads(dev)) + NVLockVgaCrtcs(dev, false); + + if (nv_two_heads(dev)) { nv04_display_store_initial_head_owner(dev); + NVSetOwner(dev, 0); + } + nouveau_hw_save_vga_fonts(dev, 1); drm_mode_config_init(dev); @@ -168,8 +161,6 @@ nv04_display_create(struct drm_device *dev) } /* Save previous state */ - NVLockVgaCrtcs(dev, false); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) crtc->funcs->save(crtc); @@ -185,6 +176,7 @@ nv04_display_create(struct drm_device *dev) void nv04_display_destroy(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_encoder *encoder; struct drm_crtc *crtc; @@ -200,8 +192,6 @@ nv04_display_destroy(struct drm_device *dev) } /* Restore state */ - NVLockVgaCrtcs(dev, false); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { struct drm_encoder_helper_funcs *func = encoder->helper_private; @@ -214,12 +204,15 @@ nv04_display_destroy(struct drm_device *dev) drm_mode_config_cleanup(dev); nouveau_hw_save_vga_fonts(dev, 0); + + if (nv_two_heads(dev)) + NVSetOwner(dev, dev_priv->crtc_owner); + NVLockVgaCrtcs(dev, true); } void nv04_display_restore(struct drm_device *dev) { - struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_encoder *encoder; struct drm_crtc *crtc; @@ -241,10 +234,5 @@ nv04_display_restore(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) crtc->funcs->restore(crtc); - - if (nv_two_heads(dev)) - NVSetOwner(dev, dev_priv->crtc_owner); - - NVLockVgaCrtcs(dev, true); } diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index 8de1eef..94e299c 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c @@ -194,7 +194,6 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, entry->i2c_index); int type, ret; - bool was_locked; /* Ensure that we can talk to this encoder */ type = nv04_tv_identify(dev, entry->i2c_index); @@ -224,13 +223,8 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) nv_encoder->or = ffs(entry->or) - 1; /* Run the slave-specific initialization */ - was_locked = NVLockVgaCrtcs(dev, false); - ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), &i2c->adapter, &nv04_tv_encoder_info[type]); - - NVLockVgaCrtcs(dev, was_locked); - if (ret < 0) goto fail_cleanup; -- cgit v0.10.2 From 45d60d1bfcbaa660a510e3b4be5d857ca8d81088 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 20 Jul 2010 14:17:23 +0200 Subject: drm/nouveau: Reset CRTC owner to 0 before BIOS init. Fixes suspend+multihead on some boards that also use BIOS scripts for modesetting. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 3b5523e..aae29cc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6551,8 +6551,10 @@ nouveau_run_vbios_init(struct drm_device *dev) int i, ret = 0; NVLockVgaCrtcs(dev, false); - if (nv_two_heads(dev)) - NVSetOwner(dev, bios->state.crtchead); + if (nv_two_heads(dev)) { + bios->state.crtchead = 0; + NVSetOwner(dev, 0); + } if (bios->major_version < 5) /* BMP only */ load_nv17_hw_sequencer_ucode(dev, bios); -- cgit v0.10.2 From 5620ba4680db0ba25b89952bdda41a9c8fd11f50 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 23 Jul 2010 10:00:12 +1000 Subject: drm/nouveau: fix build without CONFIG_ACPI Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 20ca5b8..11c0778 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -833,7 +833,7 @@ static inline void nouveau_register_dsm_handler(void) {} static inline void nouveau_unregister_dsm_handler(void) {} static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } -static inline int nouveau_acpi_edid(struct drm_device *, struct drm_connector *) { return -EINVAL; } +static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; } #endif /* nouveau_backlight.c */ -- cgit v0.10.2 From 49eed80ad0cfa5d5d02992e8088463cbf1a5ff85 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 23 Jul 2010 11:17:57 +1000 Subject: drm/nouveau: add nv_mask register accessor Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 11c0778..9d53f3d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1186,6 +1186,14 @@ static inline void nv_wr32(struct drm_device *dev, unsigned reg, u32 val) iowrite32_native(val, dev_priv->mmio + reg); } +static inline void nv_mask(struct drm_device *dev, u32 reg, u32 mask, u32 val) +{ + u32 tmp = nv_rd32(dev, reg); + tmp &= ~mask; + tmp |= val; + nv_wr32(dev, reg, tmp); +} + static inline u8 nv_rd08(struct drm_device *dev, unsigned reg) { struct drm_nouveau_private *dev_priv = dev->dev_private; -- cgit v0.10.2 From d0875edd9374296af8702d850254809e34a809cd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 23 Jul 2010 11:31:08 +1000 Subject: drm/nv50: add function to control GPIO IRQ reporting Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9d53f3d..6b24186 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1140,6 +1140,7 @@ int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); /* nv50_gpio.c */ int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); +void nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on); /* nv50_calc. */ int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk, diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index c19ed8c..fbd91c2 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -184,7 +184,7 @@ nv50_display_init(struct drm_device *dev) struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; struct nouveau_channel *evo = dev_priv->evo; struct drm_connector *connector; - uint32_t val, ram_amount, hpd_en[2]; + uint32_t val, ram_amount; uint64_t start; int ret, i; @@ -365,26 +365,10 @@ nv50_display_init(struct drm_device *dev) NV50_PDISPLAY_INTR_EN_CLK_UNK40)); /* enable hotplug interrupts */ - hpd_en[0] = hpd_en[1] = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct nouveau_connector *conn = nouveau_connector(connector); - struct dcb_gpio_entry *gpio; - - if (conn->dcb->gpio_tag == 0xff) - continue; - - gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag); - if (!gpio) - continue; - hpd_en[gpio->line >> 4] |= (0x00010001 << (gpio->line & 0xf)); - } - - nv_wr32(dev, 0xe054, 0xffffffff); - nv_wr32(dev, 0xe050, hpd_en[0]); - if (dev_priv->chipset >= 0x90) { - nv_wr32(dev, 0xe074, 0xffffffff); - nv_wr32(dev, 0xe070, hpd_en[1]); + nv50_gpio_irq_enable(dev, conn->dcb->gpio_tag, true); } return 0; diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index bb47ad7..88715c5 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -74,3 +74,22 @@ nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) nv_wr32(dev, r, v); return 0; } + +void +nv50_gpio_irq_enable(struct drm_device *dev, enum dcb_gpio_tag tag, bool on) +{ + struct dcb_gpio_entry *gpio; + u32 reg, mask; + + gpio = nouveau_bios_gpio_entry(dev, tag); + if (!gpio) { + NV_ERROR(dev, "gpio tag 0x%02x not found\n", tag); + return; + } + + reg = gpio->line < 16 ? 0xe050 : 0xe070; + mask = 0x00010001 << (gpio->line & 0xf); + + nv_wr32(dev, reg + 4, mask); + nv_mask(dev, reg + 0, mask, on ? mask : 0); +} diff --git a/drivers/gpu/drm/nouveau/nv50_mc.c b/drivers/gpu/drm/nouveau/nv50_mc.c index e0a9c3f..f680e8e 100644 --- a/drivers/gpu/drm/nouveau/nv50_mc.c +++ b/drivers/gpu/drm/nouveau/nv50_mc.c @@ -31,7 +31,20 @@ int nv50_mc_init(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); + + /* disable, and ack any pending gpio interrupts + * XXX doesn't technically belong here, but it'll do for the moment + */ + nv_wr32(dev, 0xe050, 0x00000000); + nv_wr32(dev, 0xe054, 0xffffffff); + if (dev_priv->chipset >= 0x90) { + nv_wr32(dev, 0xe070, 0x00000000); + nv_wr32(dev, 0xe074, 0xffffffff); + } + return 0; } -- cgit v0.10.2 From b01f06085e62c36659a5b6bde359ed1d98da91d7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 23 Jul 2010 11:39:03 +1000 Subject: drm/nouveau: disable hotplug detect around DP link training Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 184bc95..64b4395 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -23,8 +23,10 @@ */ #include "drmP.h" + #include "nouveau_drv.h" #include "nouveau_i2c.h" +#include "nouveau_connector.h" #include "nouveau_encoder.h" static int @@ -271,6 +273,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct nouveau_connector *nv_connector; struct bit_displayport_encoder_table *dpe; int dpe_headerlen; uint8_t config[4], status[3]; @@ -279,12 +282,21 @@ nouveau_dp_link_train(struct drm_encoder *encoder) NV_DEBUG_KMS(dev, "link training!!\n"); + nv_connector = nouveau_encoder_connector_get(nv_encoder); + if (!nv_connector) + return false; + dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); if (!dpe) { NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or); return false; } + /* disable hotplug detect, this flips around on some panels during + * link training. + */ + nv50_gpio_irq_enable(dev, nv_connector->dcb->gpio_tag, false); + if (dpe->script0) { NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), @@ -423,6 +435,9 @@ stop: nv_encoder->dcb); } + /* re-enable hotplug detect */ + nv50_gpio_irq_enable(dev, nv_connector->dcb->gpio_tag, true); + return eq_done; } -- cgit v0.10.2 From 8bded189552800cae6c333475a54dabe048a74aa Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 21 Jul 2010 21:08:11 +0200 Subject: drm/nv30: Init the PFB+0x3xx memory timing regs. Fixes the randomly flashing vertical lines seen on some nv3x after a cold-boot. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 4a1db73..b6ed605 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -12,7 +12,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nouveau_dp.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o nv50_mc.o \ - nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \ + nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o \ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o \ nv40_graph.o nv50_graph.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 6b24186..9f4b8f2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -896,6 +896,10 @@ extern void nv10_fb_takedown(struct drm_device *); extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t, uint32_t, uint32_t); +/* nv30_fb.c */ +extern int nv30_fb_init(struct drm_device *); +extern void nv30_fb_takedown(struct drm_device *); + /* nv40_fb.c */ extern int nv40_fb_init(struct drm_device *); extern void nv40_fb_takedown(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 0bf79bf..8d59c90 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -184,8 +184,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.init = nv04_timer_init; engine->timer.read = nv04_timer_read; engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv10_fb_init; - engine->fb.takedown = nv10_fb_takedown; + engine->fb.init = nv30_fb_init; + engine->fb.takedown = nv30_fb_takedown; engine->fb.set_region_tiling = nv10_fb_set_region_tiling; engine->graph.grclass = nv30_graph_grclass; engine->graph.init = nv30_graph_init; diff --git a/drivers/gpu/drm/nouveau/nv30_fb.c b/drivers/gpu/drm/nouveau/nv30_fb.c new file mode 100644 index 0000000..9d35c8b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv30_fb.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2010 Francisco Jerez. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +static int +calc_ref(int b, int l, int i) +{ + int j, x = 0; + + for (j = 0; j < 4; j++) { + int n = (b >> (8 * j) & 0xf); + int m = (l >> (8 * i) & 0xff) + 2 * (n & 0x8 ? n - 0x10 : n); + + x |= (0x80 | (m & 0x1f)) << (8 * j); + } + + return x; +} + +int +nv30_fb_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; + int i, j; + + pfb->num_tiles = NV10_PFB_TILE__SIZE; + + /* Turn all the tiling regions off. */ + for (i = 0; i < pfb->num_tiles; i++) + pfb->set_region_tiling(dev, i, 0, 0, 0); + + /* Init the memory timing regs at 0x10037c/0x1003ac */ + if (dev_priv->chipset == 0x30 || + dev_priv->chipset == 0x31 || + dev_priv->chipset == 0x35) { + /* Related to ROP count */ + int n = (dev_priv->chipset == 0x31 ? 2 : 4); + int b = (dev_priv->chipset > 0x30 ? + nv_rd32(dev, 0x122c) & 0xf : 0); + int l = nv_rd32(dev, 0x1003d0); + + for (i = 0; i < n; i++) { + for (j = 0; j < 3; j++) + nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j, + calc_ref(b, l, j)); + + for (j = 0; j < 2; j++) + nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j, + calc_ref(b, l, j)); + } + } + + return 0; +} + +void +nv30_fb_takedown(struct drm_device *dev) +{ +} -- cgit v0.10.2 From e04d8e829d7807e132d8c82c3554b164a803c617 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 23 Jul 2010 20:29:13 +0200 Subject: 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 Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index e93fbcc..eeaf1f1 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) 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) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9f4b8f2..8590032d 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 *); 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, diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 568bcc2..a9f36ab 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) 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); @@ -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) { @@ -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) { @@ -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); -- cgit v0.10.2 From f1feda70b5dfdbe6a1069efffec099b430467331 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 23 Jul 2010 23:17:57 +0200 Subject: drm/nouveau: Put back the old 2-messages I2C slave test. I was hoping we could detect I2C devices at a given address without actually writing data into them, but apparently some DDC slaves get confused with 0-bytes transactions. Put the good old test back. Reported-by: Ben Skeggs Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 97ba89e..5588e66 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c @@ -281,12 +281,23 @@ nouveau_i2c_find(struct drm_device *dev, int index) bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr) { - struct i2c_msg msg = { - .addr = addr, - .len = 0, + uint8_t buf[] = { 0 }; + struct i2c_msg msgs[] = { + { + .addr = addr, + .flags = 0, + .len = 1, + .buf = buf, + }, + { + .addr = addr, + .flags = I2C_M_RD, + .len = 1, + .buf = buf, + } }; - return i2c_transfer(&i2c->adapter, &msg, 1) == 1; + return i2c_transfer(&i2c->adapter, msgs, 2) == 2; } int -- cgit v0.10.2 From c88c2e0631b03ffb1485f8790a5b659beb1ac0be Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 24 Jul 2010 17:37:33 +0200 Subject: drm/nouveau: Move display init to a new nouveau_engine. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index eeaf1f1..1de5eb5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -263,6 +263,9 @@ nouveau_pci_resume(struct pci_dev *pdev) if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) nouveau_mem_reset_agp(dev); + /* Make the CRTCs accessible */ + engine->display.early_init(dev); + NV_INFO(dev, "POSTing device...\n"); ret = nouveau_run_vbios_init(dev); if (ret) @@ -325,10 +328,7 @@ nouveau_pci_resume(struct pci_dev *pdev) NV_ERROR(dev, "Could not pin/map cursor.\n"); } - if (dev_priv->card_type < NV_50) - nv04_display_restore(dev); - else - nv50_display_init(dev); + engine->display.init(dev); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 8590032d..0687e6a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -351,6 +351,14 @@ struct nouveau_pgraph_engine { uint32_t size, uint32_t pitch); }; +struct nouveau_display_engine { + int (*early_init)(struct drm_device *); + void (*late_takedown)(struct drm_device *); + int (*create)(struct drm_device *); + int (*init)(struct drm_device *); + void (*destroy)(struct drm_device *); +}; + struct nouveau_engine { struct nouveau_instmem_engine instmem; struct nouveau_mc_engine mc; @@ -358,6 +366,7 @@ struct nouveau_engine { struct nouveau_fb_engine fb; struct nouveau_pgraph_engine graph; struct nouveau_fifo_engine fifo; + struct nouveau_display_engine display; }; struct nouveau_pll_vals { @@ -1081,9 +1090,11 @@ extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *); extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *); /* nv04_display.c */ +extern int nv04_display_early_init(struct drm_device *); +extern void nv04_display_late_takedown(struct drm_device *); extern int nv04_display_create(struct drm_device *); +extern int nv04_display_init(struct drm_device *); extern void nv04_display_destroy(struct drm_device *); -extern void nv04_display_restore(struct drm_device *); /* nv04_crtc.c */ extern int nv04_crtc_create(struct drm_device *, int index); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 8d59c90..17176ad 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -84,6 +84,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.destroy_context = nv04_fifo_destroy_context; engine->fifo.load_context = nv04_fifo_load_context; engine->fifo.unload_context = nv04_fifo_unload_context; + engine->display.early_init = nv04_display_early_init; + engine->display.late_takedown = nv04_display_late_takedown; + engine->display.create = nv04_display_create; + engine->display.init = nv04_display_init; + engine->display.destroy = nv04_display_destroy; break; case 0x10: engine->instmem.init = nv04_instmem_init; @@ -126,6 +131,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.destroy_context = nv10_fifo_destroy_context; engine->fifo.load_context = nv10_fifo_load_context; engine->fifo.unload_context = nv10_fifo_unload_context; + engine->display.early_init = nv04_display_early_init; + engine->display.late_takedown = nv04_display_late_takedown; + engine->display.create = nv04_display_create; + engine->display.init = nv04_display_init; + engine->display.destroy = nv04_display_destroy; break; case 0x20: engine->instmem.init = nv04_instmem_init; @@ -168,6 +178,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.destroy_context = nv10_fifo_destroy_context; engine->fifo.load_context = nv10_fifo_load_context; engine->fifo.unload_context = nv10_fifo_unload_context; + engine->display.early_init = nv04_display_early_init; + engine->display.late_takedown = nv04_display_late_takedown; + engine->display.create = nv04_display_create; + engine->display.init = nv04_display_init; + engine->display.destroy = nv04_display_destroy; break; case 0x30: engine->instmem.init = nv04_instmem_init; @@ -210,6 +225,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.destroy_context = nv10_fifo_destroy_context; engine->fifo.load_context = nv10_fifo_load_context; engine->fifo.unload_context = nv10_fifo_unload_context; + engine->display.early_init = nv04_display_early_init; + engine->display.late_takedown = nv04_display_late_takedown; + engine->display.create = nv04_display_create; + engine->display.init = nv04_display_init; + engine->display.destroy = nv04_display_destroy; break; case 0x40: case 0x60: @@ -253,6 +273,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.destroy_context = nv40_fifo_destroy_context; engine->fifo.load_context = nv40_fifo_load_context; engine->fifo.unload_context = nv40_fifo_unload_context; + engine->display.early_init = nv04_display_early_init; + engine->display.late_takedown = nv04_display_late_takedown; + engine->display.create = nv04_display_create; + engine->display.init = nv04_display_init; + engine->display.destroy = nv04_display_destroy; break; case 0x50: case 0x80: /* gotta love NVIDIA's consistency.. */ @@ -297,6 +322,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.destroy_context = nv50_fifo_destroy_context; engine->fifo.load_context = nv50_fifo_load_context; engine->fifo.unload_context = nv50_fifo_unload_context; + engine->display.early_init = nv50_display_early_init; + engine->display.late_takedown = nv50_display_late_takedown; + engine->display.create = nv50_display_create; + engine->display.init = nv50_display_init; + engine->display.destroy = nv50_display_destroy; break; default: NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); @@ -415,10 +445,15 @@ nouveau_card_init(struct drm_device *dev) engine = &dev_priv->engine; spin_lock_init(&dev_priv->context_switch_lock); + /* Make the CRTCs and I2C buses accessible */ + ret = engine->display.early_init(dev); + if (ret) + goto out; + /* Parse BIOS tables / Run init tables if card not POSTed */ ret = nouveau_bios_init(dev); if (ret) - goto out; + goto out_display_early; ret = nouveau_mem_detect(dev); if (ret) @@ -474,10 +509,7 @@ nouveau_card_init(struct drm_device *dev) goto out_graph; } - if (dev_priv->card_type >= NV_50) - ret = nv50_display_create(dev); - else - ret = nv04_display_create(dev); + ret = engine->display.create(dev); if (ret) goto out_fifo; @@ -511,10 +543,7 @@ nouveau_card_init(struct drm_device *dev) out_irq: drm_irq_uninstall(dev); out_display: - if (dev_priv->card_type >= NV_50) - nv50_display_destroy(dev); - else - nv04_display_destroy(dev); + engine->display.destroy(dev); out_fifo: if (!nouveau_noaccel) engine->fifo.takedown(dev); @@ -538,6 +567,8 @@ out_gpuobj_early: nouveau_gpuobj_late_takedown(dev); out_bios: nouveau_bios_takedown(dev); +out_display_early: + engine->display.late_takedown(dev); out: vga_client_register(dev->pdev, NULL, NULL, NULL); return ret; @@ -562,6 +593,7 @@ static void nouveau_card_takedown(struct drm_device *dev) engine->fb.takedown(dev); engine->timer.takedown(dev); engine->mc.takedown(dev); + engine->display.late_takedown(dev); mutex_lock(&dev->struct_mutex); ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); @@ -798,13 +830,11 @@ void nouveau_lastclose(struct drm_device *dev) int nouveau_unload(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->engine; drm_kms_helper_poll_fini(dev); nouveau_fbcon_fini(dev); - if (dev_priv->card_type >= NV_50) - nv50_display_destroy(dev); - else - nv04_display_destroy(dev); + engine->display.destroy(dev); nouveau_card_takedown(dev); iounmap(dev_priv->mmio); diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index c6df391..cd70bd8 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -76,6 +76,32 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) } int +nv04_display_early_init(struct drm_device *dev) +{ + /* Unlock the VGA CRTCs. */ + NVLockVgaCrtcs(dev, false); + + /* Make sure the CRTCs aren't in slaved mode. */ + if (nv_two_heads(dev)) { + nv04_display_store_initial_head_owner(dev); + NVSetOwner(dev, 0); + } + + return 0; +} + +void +nv04_display_late_takedown(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (nv_two_heads(dev)) + NVSetOwner(dev, dev_priv->crtc_owner); + + NVLockVgaCrtcs(dev, true); +} + +int nv04_display_create(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -87,13 +113,6 @@ nv04_display_create(struct drm_device *dev) NV_DEBUG_KMS(dev, "\n"); - NVLockVgaCrtcs(dev, false); - - if (nv_two_heads(dev)) { - nv04_display_store_initial_head_owner(dev); - NVSetOwner(dev, 0); - } - nouveau_hw_save_vga_fonts(dev, 1); drm_mode_config_init(dev); @@ -176,7 +195,6 @@ nv04_display_create(struct drm_device *dev) void nv04_display_destroy(struct drm_device *dev) { - struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_encoder *encoder; struct drm_crtc *crtc; @@ -204,20 +222,14 @@ nv04_display_destroy(struct drm_device *dev) drm_mode_config_cleanup(dev); nouveau_hw_save_vga_fonts(dev, 0); - - if (nv_two_heads(dev)) - NVSetOwner(dev, dev_priv->crtc_owner); - NVLockVgaCrtcs(dev, true); } -void -nv04_display_restore(struct drm_device *dev) +int +nv04_display_init(struct drm_device *dev) { struct drm_encoder *encoder; struct drm_crtc *crtc; - NVLockVgaCrtcs(dev, false); - /* meh.. modeset apparently doesn't setup all the regs and depends * on pre-existing state, for now load the state of the card *before* * nouveau was loaded, and then do a modeset. @@ -234,5 +246,7 @@ nv04_display_restore(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) crtc->funcs->restore(crtc); + + return 0; } diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index fbd91c2..13a4489 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -178,6 +178,17 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) } int +nv50_display_early_init(struct drm_device *dev) +{ + return 0; +} + +void +nv50_display_late_takedown(struct drm_device *dev) +{ +} + +int nv50_display_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -528,7 +539,8 @@ int nv50_display_create(struct drm_device *dev) return 0; } -int nv50_display_destroy(struct drm_device *dev) +void +nv50_display_destroy(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -538,8 +550,6 @@ int nv50_display_destroy(struct drm_device *dev) nv50_display_disable(dev); nv50_evo_channel_del(&dev_priv->evo); - - return 0; } static u16 diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index 581d405..c551f0b 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h @@ -38,9 +38,11 @@ void nv50_display_irq_handler(struct drm_device *dev); void nv50_display_irq_handler_bh(struct work_struct *work); void nv50_display_irq_hotplug_bh(struct work_struct *work); -int nv50_display_init(struct drm_device *dev); +int nv50_display_early_init(struct drm_device *dev); +void nv50_display_late_takedown(struct drm_device *dev); int nv50_display_create(struct drm_device *dev); -int nv50_display_destroy(struct drm_device *dev); +int nv50_display_init(struct drm_device *dev); +void nv50_display_destroy(struct drm_device *dev); int nv50_crtc_blank(struct nouveau_crtc *, bool blank); int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); -- cgit v0.10.2 From 946fd35f88ae7ef910229e7995ab0c32d52517b4 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 24 Jul 2010 17:41:48 +0200 Subject: drm/nouveau: Get rid of the remaining VGA CRTC locking. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index aae29cc..40231ce 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6550,11 +6550,8 @@ nouveau_run_vbios_init(struct drm_device *dev) struct nvbios *bios = &dev_priv->vbios; int i, ret = 0; - NVLockVgaCrtcs(dev, false); - if (nv_two_heads(dev)) { - bios->state.crtchead = 0; - NVSetOwner(dev, 0); - } + /* Reset the BIOS head to 0. */ + bios->state.crtchead = 0; if (bios->major_version < 5) /* BMP only */ load_nv17_hw_sequencer_ucode(dev, bios); @@ -6587,8 +6584,6 @@ nouveau_run_vbios_init(struct drm_device *dev) } } - NVLockVgaCrtcs(dev, true); - return ret; } @@ -6618,13 +6613,11 @@ nouveau_bios_posted(struct drm_device *dev) return true; } - NVLockVgaCrtcs(dev, false); htotal = NVReadVgaCrtc(dev, 0, 0x06); htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; - NVLockVgaCrtcs(dev, true); return (htotal != 0); } @@ -6668,14 +6661,12 @@ nouveau_bios_init(struct drm_device *dev) return ret; /* feature_byte on BMP is poor, but init always sets CR4B */ - NVLockVgaCrtcs(dev, false); if (bios->major_version < 5) bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40; /* all BIT systems need p_f_m_t for digital_min_front_porch */ if (bios->is_mobile || bios->major_version >= 5) ret = parse_fp_mode_table(dev, bios); - NVLockVgaCrtcs(dev, true); /* allow subsequent scripts to execute */ bios->execute = true; diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 5588e66..cb0cb34 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c @@ -305,21 +305,18 @@ nouveau_i2c_identify(struct drm_device *dev, const char *what, struct i2c_board_info *info, int index) { struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index); - int was_locked, i; + int i; - was_locked = NVLockVgaCrtcs(dev, false); NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); for (i = 0; info[i].addr; i++) { if (nouveau_probe_i2c_addr(i2c, info[i].addr)) { NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); - goto out; + return i; } } NV_DEBUG(dev, "No devices found.\n"); -out: - NVLockVgaCrtcs(dev, was_locked); - return info[i].addr ? i : -ENODEV; + return -ENODEV; } -- cgit v0.10.2 From c04c5b1da18ec73eaabc7b8a8757545865426fc2 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 24 Jul 2010 17:42:20 +0200 Subject: drm/nouveau: Fix TV-out detection on unposted cards lacking a usable DCB table. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index cd70bd8..9e28cf7 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -78,6 +78,14 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) int nv04_display_early_init(struct drm_device *dev) { + /* Make the I2C buses accessible. */ + if (!nv_gf4_disp_arch(dev)) { + uint32_t pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); + + if (!(pmc_enable & 1)) + nv_wr32(dev, NV03_PMC_ENABLE, pmc_enable | 1); + } + /* Unlock the VGA CRTCs. */ NVLockVgaCrtcs(dev, false); -- cgit v0.10.2 From bf563a6b7c7efb283dd4ddf12cc90c2898195c16 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 26 Jul 2010 09:11:04 +1000 Subject: drm/nv50: correct wait condition for instmem flush MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Marcin Kościelnicki Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 2ed893c..37c7b48 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -487,7 +487,7 @@ void nv50_instmem_flush(struct drm_device *dev) { nv_wr32(dev, 0x00330c, 0x00000001); - if (!nv_wait(0x00330c, 0x00000001, 0x00000000)) + if (!nv_wait(0x00330c, 0x00000002, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); } @@ -495,7 +495,7 @@ void nv84_instmem_flush(struct drm_device *dev) { nv_wr32(dev, 0x070000, 0x00000001); - if (!nv_wait(0x070000, 0x00000001, 0x00000000)) + if (!nv_wait(0x070000, 0x00000002, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); } -- cgit v0.10.2 From ee2e013131dcf6427334663662dbe760ccdba735 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 26 Jul 2010 09:28:25 +1000 Subject: drm/nouveau: introduce gpio engine Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index b6ed605..2405d5e 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv50_cursor.o nv50_display.o nv50_fbcon.o \ nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ - nv17_gpio.o nv50_gpio.o \ + nv10_gpio.o nv50_gpio.o \ nv50_calc.o nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 40231ce..b59f348 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -3136,6 +3136,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) */ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; int i; @@ -3156,7 +3157,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", offset, gpio->tag, gpio->state_default); if (bios->execute) - nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); + pgpio->set(bios->dev, gpio->tag, gpio->state_default); /* The NVIDIA binary driver doesn't appear to actually do * any of this, my VBIOS does however. diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 64b4395..33742b1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -272,6 +272,8 @@ bool nouveau_dp_link_train(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_connector *nv_connector; struct bit_displayport_encoder_table *dpe; @@ -295,7 +297,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder) /* disable hotplug detect, this flips around on some panels during * link training. */ - nv50_gpio_irq_enable(dev, nv_connector->dcb->gpio_tag, false); + pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false); if (dpe->script0) { NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); @@ -436,7 +438,7 @@ stop: } /* re-enable hotplug detect */ - nv50_gpio_irq_enable(dev, nv_connector->dcb->gpio_tag, true); + pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true); return eq_done; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 0687e6a..d0a35d9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -359,6 +359,16 @@ struct nouveau_display_engine { void (*destroy)(struct drm_device *); }; +struct nouveau_gpio_engine { + int (*init)(struct drm_device *); + void (*takedown)(struct drm_device *); + + int (*get)(struct drm_device *, enum dcb_gpio_tag); + int (*set)(struct drm_device *, enum dcb_gpio_tag, int state); + + void (*irq_enable)(struct drm_device *, enum dcb_gpio_tag, bool on); +}; + struct nouveau_engine { struct nouveau_instmem_engine instmem; struct nouveau_mc_engine mc; @@ -367,6 +377,7 @@ struct nouveau_engine { struct nouveau_pgraph_engine graph; struct nouveau_fifo_engine fifo; struct nouveau_display_engine display; + struct nouveau_gpio_engine gpio; }; struct nouveau_pll_vals { @@ -1149,11 +1160,12 @@ extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *, extern int nouveau_gem_ioctl_info(struct drm_device *, void *, struct drm_file *); -/* nv17_gpio.c */ -int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); -int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); +/* nv10_gpio.c */ +int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); +int nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); /* nv50_gpio.c */ +int nv50_gpio_init(struct drm_device *dev); int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); void nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 17176ad..ee3729e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -38,6 +38,7 @@ #include "nv50_display.h" static void nouveau_stub_takedown(struct drm_device *dev) {} +static int nouveau_stub_init(struct drm_device *dev) { return 0; } static int nouveau_init_engine_ptrs(struct drm_device *dev) { @@ -89,6 +90,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->display.create = nv04_display_create; engine->display.init = nv04_display_init; engine->display.destroy = nv04_display_destroy; + engine->gpio.init = nouveau_stub_init; + engine->gpio.takedown = nouveau_stub_takedown; + engine->gpio.get = NULL; + engine->gpio.set = NULL; + engine->gpio.irq_enable = NULL; break; case 0x10: engine->instmem.init = nv04_instmem_init; @@ -136,6 +142,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->display.create = nv04_display_create; engine->display.init = nv04_display_init; engine->display.destroy = nv04_display_destroy; + engine->gpio.init = nouveau_stub_init; + engine->gpio.takedown = nouveau_stub_takedown; + engine->gpio.get = nv10_gpio_get; + engine->gpio.set = nv10_gpio_set; + engine->gpio.irq_enable = NULL; break; case 0x20: engine->instmem.init = nv04_instmem_init; @@ -183,6 +194,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->display.create = nv04_display_create; engine->display.init = nv04_display_init; engine->display.destroy = nv04_display_destroy; + engine->gpio.init = nouveau_stub_init; + engine->gpio.takedown = nouveau_stub_takedown; + engine->gpio.get = nv10_gpio_get; + engine->gpio.set = nv10_gpio_set; + engine->gpio.irq_enable = NULL; break; case 0x30: engine->instmem.init = nv04_instmem_init; @@ -230,6 +246,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->display.create = nv04_display_create; engine->display.init = nv04_display_init; engine->display.destroy = nv04_display_destroy; + engine->gpio.init = nouveau_stub_init; + engine->gpio.takedown = nouveau_stub_takedown; + engine->gpio.get = nv10_gpio_get; + engine->gpio.set = nv10_gpio_set; + engine->gpio.irq_enable = NULL; break; case 0x40: case 0x60: @@ -278,6 +299,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->display.create = nv04_display_create; engine->display.init = nv04_display_init; engine->display.destroy = nv04_display_destroy; + engine->gpio.init = nouveau_stub_init; + engine->gpio.takedown = nouveau_stub_takedown; + engine->gpio.get = nv10_gpio_get; + engine->gpio.set = nv10_gpio_set; + engine->gpio.irq_enable = NULL; break; case 0x50: case 0x80: /* gotta love NVIDIA's consistency.. */ @@ -327,6 +353,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->display.create = nv50_display_create; engine->display.init = nv50_display_init; engine->display.destroy = nv50_display_destroy; + engine->gpio.init = nv50_gpio_init; + engine->gpio.takedown = nouveau_stub_takedown; + engine->gpio.get = nv50_gpio_get; + engine->gpio.set = nv50_gpio_set; + engine->gpio.irq_enable = nv50_gpio_irq_enable; break; default: NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); @@ -485,10 +516,15 @@ nouveau_card_init(struct drm_device *dev) if (ret) goto out_gpuobj; + /* PGPIO */ + ret = engine->gpio.init(dev); + if (ret) + goto out_mc; + /* PTIMER */ ret = engine->timer.init(dev); if (ret) - goto out_mc; + goto out_gpio; /* PFB */ ret = engine->fb.init(dev); @@ -554,6 +590,8 @@ out_fb: engine->fb.takedown(dev); out_timer: engine->timer.takedown(dev); +out_gpio: + engine->gpio.takedown(dev); out_mc: engine->mc.takedown(dev); out_gpuobj: @@ -592,6 +630,7 @@ static void nouveau_card_takedown(struct drm_device *dev) } engine->fb.takedown(dev); engine->timer.takedown(dev); + engine->gpio.takedown(dev); engine->mc.takedown(dev); engine->display.late_takedown(dev); diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 2d0fee5..ea36270 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -220,6 +220,7 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio; struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, @@ -251,11 +252,11 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf); } - saved_gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); - saved_gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); + saved_gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1); + saved_gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0); - nv17_gpio_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV); - nv17_gpio_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV); + gpio->set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV); + gpio->set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV); msleep(4); @@ -303,8 +304,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4); nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2); - nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); - nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); + gpio->set(dev, DCB_GPIO_TVDAC1, saved_gpio1); + gpio->set(dev, DCB_GPIO_TVDAC0, saved_gpio0); return sample; } diff --git a/drivers/gpu/drm/nouveau/nv10_gpio.c b/drivers/gpu/drm/nouveau/nv10_gpio.c new file mode 100644 index 0000000..007fc29 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv10_gpio.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_hw.h" + +static bool +get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift, + uint32_t *mask) +{ + if (ent->line < 2) { + *reg = NV_PCRTC_GPIO; + *shift = ent->line * 16; + *mask = 0x11; + + } else if (ent->line < 10) { + *reg = NV_PCRTC_GPIO_EXT; + *shift = (ent->line - 2) * 4; + *mask = 0x3; + + } else if (ent->line < 14) { + *reg = NV_PCRTC_850; + *shift = (ent->line - 10) * 4; + *mask = 0x3; + + } else { + return false; + } + + return true; +} + +int +nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) +{ + struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); + uint32_t reg, shift, mask, value; + + if (!ent) + return -ENODEV; + + if (!get_gpio_location(ent, ®, &shift, &mask)) + return -ENODEV; + + value = NVReadCRTC(dev, 0, reg) >> shift; + + return (ent->invert ? 1 : 0) ^ (value & 1); +} + +int +nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) +{ + struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); + uint32_t reg, shift, mask, value; + + if (!ent) + return -ENODEV; + + if (!get_gpio_location(ent, ®, &shift, &mask)) + return -ENODEV; + + value = ((ent->invert ? 1 : 0) ^ (state ? 1 : 0)) << shift; + mask = ~(mask << shift); + + NVWriteCRTC(dev, 0, reg, value | (NVReadCRTC(dev, 0, reg) & mask)); + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nv17_gpio.c b/drivers/gpu/drm/nouveau/nv17_gpio.c deleted file mode 100644 index 2e58c33..0000000 --- a/drivers/gpu/drm/nouveau/nv17_gpio.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" - -static bool -get_gpio_location(struct dcb_gpio_entry *ent, uint32_t *reg, uint32_t *shift, - uint32_t *mask) -{ - if (ent->line < 2) { - *reg = NV_PCRTC_GPIO; - *shift = ent->line * 16; - *mask = 0x11; - - } else if (ent->line < 10) { - *reg = NV_PCRTC_GPIO_EXT; - *shift = (ent->line - 2) * 4; - *mask = 0x3; - - } else if (ent->line < 14) { - *reg = NV_PCRTC_850; - *shift = (ent->line - 10) * 4; - *mask = 0x3; - - } else { - return false; - } - - return true; -} - -int -nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) -{ - struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); - uint32_t reg, shift, mask, value; - - if (!ent) - return -ENODEV; - - if (!get_gpio_location(ent, ®, &shift, &mask)) - return -ENODEV; - - value = NVReadCRTC(dev, 0, reg) >> shift; - - return (ent->invert ? 1 : 0) ^ (value & 1); -} - -int -nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) -{ - struct dcb_gpio_entry *ent = nouveau_bios_gpio_entry(dev, tag); - uint32_t reg, shift, mask, value; - - if (!ent) - return -ENODEV; - - if (!get_gpio_location(ent, ®, &shift, &mask)) - return -ENODEV; - - value = ((ent->invert ? 1 : 0) ^ (state ? 1 : 0)) << shift; - mask = ~(mask << shift); - - NVWriteCRTC(dev, 0, reg, value | (NVReadCRTC(dev, 0, reg) & mask)); - - return 0; -} diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index bb3a284..44fefb0 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -37,6 +37,7 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio; uint32_t testval, regoffset = nv04_dac_output_offset(encoder); uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end, fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c; @@ -52,8 +53,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) head = (dacclk & 0x100) >> 8; /* Save the previous state. */ - gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); - gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); + gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1); + gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0); fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL); fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START); fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END); @@ -64,8 +65,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c); /* Prepare the DAC for load detection. */ - nv17_gpio_set(dev, DCB_GPIO_TVDAC1, true); - nv17_gpio_set(dev, DCB_GPIO_TVDAC0, true); + gpio->set(dev, DCB_GPIO_TVDAC1, true); + gpio->set(dev, DCB_GPIO_TVDAC0, true); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047); @@ -110,8 +111,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start); NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal); - nv17_gpio_set(dev, DCB_GPIO_TVDAC1, gpio1); - nv17_gpio_set(dev, DCB_GPIO_TVDAC0, gpio0); + gpio->set(dev, DCB_GPIO_TVDAC1, gpio1); + gpio->set(dev, DCB_GPIO_TVDAC0, gpio0); return sample; } @@ -335,6 +336,8 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio; struct nv17_tv_state *regs = &to_tv_enc(encoder)->state; struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); @@ -359,8 +362,8 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) nv_load_ptv(dev, regs, 200); - nv17_gpio_set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON); - nv17_gpio_set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON); + gpio->set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON); + gpio->set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON); nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); } diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 13a4489..0ab8687 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -193,6 +193,7 @@ nv50_display_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; struct nouveau_channel *evo = dev_priv->evo; struct drm_connector *connector; uint32_t val, ram_amount; @@ -379,7 +380,7 @@ nv50_display_init(struct drm_device *dev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct nouveau_connector *conn = nouveau_connector(connector); - nv50_gpio_irq_enable(dev, conn->dcb->gpio_tag, true); + pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); } return 0; diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index 88715c5..b2fab2b 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -93,3 +93,19 @@ nv50_gpio_irq_enable(struct drm_device *dev, enum dcb_gpio_tag tag, bool on) nv_wr32(dev, reg + 4, mask); nv_mask(dev, reg + 0, mask, on ? mask : 0); } + +int +nv50_gpio_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + /* disable, and ack any pending gpio interrupts */ + nv_wr32(dev, 0xe050, 0x00000000); + nv_wr32(dev, 0xe054, 0xffffffff); + if (dev_priv->chipset >= 0x90) { + nv_wr32(dev, 0xe070, 0x00000000); + nv_wr32(dev, 0xe074, 0xffffffff); + } + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nv50_mc.c b/drivers/gpu/drm/nouveau/nv50_mc.c index f680e8e..e0a9c3f 100644 --- a/drivers/gpu/drm/nouveau/nv50_mc.c +++ b/drivers/gpu/drm/nouveau/nv50_mc.c @@ -31,20 +31,7 @@ int nv50_mc_init(struct drm_device *dev) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); - - /* disable, and ack any pending gpio interrupts - * XXX doesn't technically belong here, but it'll do for the moment - */ - nv_wr32(dev, 0xe050, 0x00000000); - nv_wr32(dev, 0xe054, 0xffffffff); - if (dev_priv->chipset >= 0x90) { - nv_wr32(dev, 0xe070, 0x00000000); - nv_wr32(dev, 0xe074, 0xffffffff); - } - return 0; } -- cgit v0.10.2 From 0ccb3a75fe81ec3c4ceb7344c34d0497cbabb369 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 26 Jul 2010 11:35:37 +1000 Subject: drm/nv50: fix some not-error error messages Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 0ab8687..f13ad0d 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -380,6 +380,9 @@ nv50_display_init(struct drm_device *dev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct nouveau_connector *conn = nouveau_connector(connector); + if (conn->dcb->gpio_tag == 0xff) + continue; + pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); } -- cgit v0.10.2 From 4ce9198ecf73739104b274c7c6377ef3659b3ca5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 30 Jun 2010 12:13:55 -0400 Subject: drm/radeon/kms: minor driver cleanups - Make the logic in r100_pll_errata_after_index() match the other errata functions - Use rdev->family rather than rdev->flags & RADEON_FAMILY_MASK for kms - replace rn50 check using ids with ASIC_IS_RN50 convenience macro Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index ab37717..5aa2995 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2365,11 +2365,10 @@ void r100_mc_init(struct radeon_device *rdev) */ void r100_pll_errata_after_index(struct radeon_device *rdev) { - if (!(rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) { - return; + if (rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS) { + (void)RREG32(RADEON_CLOCK_CNTL_DATA); + (void)RREG32(RADEON_CRTC_GEN_CNTL); } - (void)RREG32(RADEON_CLOCK_CNTL_DATA); - (void)RREG32(RADEON_CRTC_GEN_CNTL); } static void r100_pll_errata_after_data(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index d1c1d8d..3426dd2 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2941,9 +2941,8 @@ static void combios_write_ram_size(struct drm_device *dev) if (rev < 3) { mem_cntl = RBIOS32(offset + 1); mem_size = RBIOS16(offset + 5); - if (((rdev->flags & RADEON_FAMILY_MASK) < CHIP_R200) && - ((dev->pdev->device != 0x515e) - && (dev->pdev->device != 0x5969))) + if ((rdev->family < CHIP_R200) && + !ASIC_IS_RN50(rdev)) WREG32(RADEON_MEM_CNTL, mem_cntl); } } @@ -2954,10 +2953,8 @@ static void combios_write_ram_size(struct drm_device *dev) if (offset) { rev = RBIOS8(offset - 1); if (rev < 1) { - if (((rdev->flags & RADEON_FAMILY_MASK) < - CHIP_R200) - && ((dev->pdev->device != 0x515e) - && (dev->pdev->device != 0x5969))) { + if ((rdev->family < CHIP_R200) + && !ASIC_IS_RN50(rdev)) { int ram = 0; int mem_addr_mapping = 0; -- cgit v0.10.2 From 9bd7ef5f5a5ab6088029ad95a435f03e1314275d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 30 Jun 2010 14:58:59 -0400 Subject: drm/radeon/kms/atom: bump atom loop timeout from 1 sec to 5 secs Some tables have delays that can cause the timeout to hit even when not intended. Should fix: https://bugs.freedesktop.org/show_bug.cgi?id=27744 and related bugs. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 1d56983..bded870 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -715,8 +715,8 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) cjiffies = jiffies; if (time_after(cjiffies, ctx->last_jump_jiffies)) { cjiffies -= ctx->last_jump_jiffies; - if ((jiffies_to_msecs(cjiffies) > 1000)) { - DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n"); + if ((jiffies_to_msecs(cjiffies) > 5000)) { + DRM_ERROR("atombios stuck in loop for more than 5secs aborting\n"); ctx->abort = true; } } else { -- cgit v0.10.2 From d7a2952f1adec32018a78ec0c2f504dd72f38e25 Mon Sep 17 00:00:00 2001 From: Alberto Milone Date: Tue, 6 Jul 2010 11:40:24 -0400 Subject: drm/radeon: Add support for the ATIF ACPI method to the radeon driver By calling the ATIF method in the radeon driver we can make sure that hotkeys such as the video switch key emit ACPI events when pressed. agd5f: fix warning Signed-off-by: Alberto Milone Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 84b1f27..aebe008 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -69,5 +69,6 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o +radeon-$(CONFIG_ACPI) += radeon_acpi.o obj-$(CONFIG_DRM_RADEON)+= radeon.o diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index ab61aaa..a5c1a3e9 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1414,6 +1414,13 @@ extern void r700_cp_fini(struct radeon_device *rdev); extern void evergreen_disable_interrupt_state(struct radeon_device *rdev); extern int evergreen_irq_set(struct radeon_device *rdev); +/* radeon_acpi.c */ +#if defined(CONFIG_ACPI) +extern int radeon_acpi_init(struct radeon_device *rdev); +#else +static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } +#endif + /* evergreen */ struct evergreen_mc_save { u32 vga_control[6]; diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c new file mode 100644 index 0000000..e366434 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_acpi.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include + +#include "drmP.h" +#include "drm.h" +#include "drm_sarea.h" +#include "drm_crtc_helper.h" +#include "radeon.h" + +#include + +/* Call the ATIF method + * + * Note: currently we discard the output + */ +static int radeon_atif_call(acpi_handle handle) +{ + acpi_status status; + union acpi_object atif_arg_elements[2]; + struct acpi_object_list atif_arg; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; + + atif_arg.count = 2; + atif_arg.pointer = &atif_arg_elements[0]; + + atif_arg_elements[0].type = ACPI_TYPE_INTEGER; + atif_arg_elements[0].integer.value = 0; + atif_arg_elements[1].type = ACPI_TYPE_INTEGER; + atif_arg_elements[1].integer.value = 0; + + status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); + + /* Fail only if calling the method fails and ATIF is supported */ + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + printk(KERN_INFO "failed to evaluate ATIF got %s\n", acpi_format_exception(status)); + kfree(buffer.pointer); + return 1; + } + + kfree(buffer.pointer); + return 0; +} + +/* Call all ACPI methods here */ +int radeon_acpi_init(struct radeon_device *rdev) +{ + acpi_handle handle; + int ret; + + /* No need to proceed if we're sure that ATIF is not supported */ + if (!ASIC_IS_AVIVO(rdev) || !rdev->bios) + return 0; + + /* Get the device handle */ + handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); + + /* Call the ATIF method */ + ret = radeon_atif_call(handle); + if (ret) + return ret; + + return 0; +} + diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 6a70c0d..70fda63 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -49,7 +49,7 @@ int radeon_driver_unload_kms(struct drm_device *dev) int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) { struct radeon_device *rdev; - int r; + int r, acpi_status; rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL); if (rdev == NULL) { @@ -77,6 +77,12 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) dev_err(&dev->pdev->dev, "Fatal error during GPU init\n"); goto out; } + + /* Call ACPI methods */ + acpi_status = radeon_acpi_init(rdev); + if (acpi_status) + dev_err(&dev->pdev->dev, "Error during ACPI methods call\n"); + /* Again modeset_init should fail only on fatal error * otherwise it should provide enough functionalities * for shadowfb to run -- cgit v0.10.2 From 21a8122ad38c60d73fe5dc51051414c3564d174a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 2 Jul 2010 12:58:16 -0400 Subject: drm/radeon/kms: add support for internal thermal sensors (v3) rv6xx/rv7xx/evergreen families supported; older asics did not have an internal thermal sensor. Note, not all oems use the internal thermal sensor, so it's only exposed in cases where it is used. Note also, that most laptops use an oem specific ACPI solution for GPU thermal information rather than using the internal thermal sensor directly. v2: export millidegrees celsius, use hwmon device properly. v3: fix Kconfig Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 5b7a1a4..4cab0c6 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -61,6 +61,7 @@ config DRM_RADEON select DRM_KMS_HELPER select DRM_TTM select POWER_SUPPLY + select HWMON help Choose this option if you have an ATI Radeon graphics card. There are both PCI and AGP versions. You don't need to choose this to diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 057192a..1b7da39 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -39,6 +39,23 @@ static void evergreen_gpu_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); +/* get temperature in millidegrees */ +u32 evergreen_get_temp(struct radeon_device *rdev) +{ + u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> + ASIC_T_SHIFT; + u32 actual_temp = 0; + + if ((temp >> 10) & 1) + actual_temp = 0; + else if ((temp >> 9) & 1) + actual_temp = 255; + else + actual_temp = (temp >> 1) & 0xff; + + return actual_temp * 1000; +} + void evergreen_pm_misc(struct radeon_device *rdev) { int req_ps_idx = rdev->pm.requested_power_state_index; diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index a1cd621..9b7532d 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -165,6 +165,11 @@ #define SE_DB_BUSY (1 << 30) #define SE_CB_BUSY (1 << 31) +#define CG_MULT_THERMAL_STATUS 0x740 +#define ASIC_T(x) ((x) << 16) +#define ASIC_T_MASK 0x7FF0000 +#define ASIC_T_SHIFT 16 + #define HDP_HOST_PATH_CNTL 0x2C00 #define HDP_NONSURFACE_BASE 0x2C04 #define HDP_NONSURFACE_INFO 0x2C08 diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a73a6e1..15fe6c2 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -92,6 +92,21 @@ void r600_gpu_init(struct radeon_device *rdev); void r600_fini(struct radeon_device *rdev); void r600_irq_disable(struct radeon_device *rdev); +/* get temperature in millidegrees */ +u32 rv6xx_get_temp(struct radeon_device *rdev) +{ + u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> + ASIC_T_SHIFT; + u32 actual_temp = 0; + + if ((temp >> 7) & 1) + actual_temp = 0; + else + actual_temp = (temp >> 1) & 0xff; + + return actual_temp * 1000; +} + void r600_pm_get_dynpm_state(struct radeon_device *rdev) { int i; diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 59c1f87..23205f0 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -239,6 +239,11 @@ #define GRBM_SOFT_RESET 0x8020 #define SOFT_RESET_CP (1<<0) +#define CG_THERMAL_STATUS 0x7F4 +#define ASIC_T(x) ((x) << 0) +#define ASIC_T_MASK 0x1FF +#define ASIC_T_SHIFT 0 + #define HDP_HOST_PATH_CNTL 0x2C00 #define HDP_NONSURFACE_BASE 0x2C04 #define HDP_NONSURFACE_INFO 0x2C08 diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a5c1a3e9..d4d776d 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -178,6 +178,9 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev); void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level); void rs690_pm_info(struct radeon_device *rdev); +extern u32 rv6xx_get_temp(struct radeon_device *rdev); +extern u32 rv770_get_temp(struct radeon_device *rdev); +extern u32 evergreen_get_temp(struct radeon_device *rdev); /* * Fences. @@ -670,6 +673,13 @@ struct radeon_pm_profile { int dpms_on_cm_idx; }; +enum radeon_int_thermal_type { + THERMAL_TYPE_NONE, + THERMAL_TYPE_RV6XX, + THERMAL_TYPE_RV770, + THERMAL_TYPE_EVERGREEN, +}; + struct radeon_voltage { enum radeon_voltage_type type; /* gpio voltage */ @@ -765,6 +775,9 @@ struct radeon_pm { enum radeon_pm_profile_type profile; int profile_index; struct radeon_pm_profile profiles[PM_PROFILE_MAX]; + /* internal thermal controller on rv6xx+ */ + enum radeon_int_thermal_type int_thermal_type; + struct device *int_hwmon_dev; }; diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 99bd8a9..5dd86b9 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1773,14 +1773,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) } /* add the i2c bus for thermal/fan chip */ - /* no support for internal controller yet */ if (controller->ucType > 0) { - if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || - (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) || - (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN)) { + if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { DRM_INFO("Internal thermal controller %s fan control\n", (controller->ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); + rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; + } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { + DRM_INFO("Internal thermal controller %s fan control\n", + (controller->ucFanParameters & + ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); + rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; + } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { + DRM_INFO("Internal thermal controller %s fan control\n", + (controller->ucFanParameters & + ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); + rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; } else if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || (controller->ucType == diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 115d26b..ed66062 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -27,6 +27,8 @@ #include #endif #include +#include +#include #define RADEON_IDLE_LOOP_MS 100 #define RADEON_RECLOCK_DELAY_MS 200 @@ -423,6 +425,82 @@ fail: static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile); static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method); +static ssize_t radeon_hwmon_show_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); + struct radeon_device *rdev = ddev->dev_private; + u32 temp; + + switch (rdev->pm.int_thermal_type) { + case THERMAL_TYPE_RV6XX: + temp = rv6xx_get_temp(rdev); + break; + case THERMAL_TYPE_RV770: + temp = rv770_get_temp(rdev); + break; + case THERMAL_TYPE_EVERGREEN: + temp = evergreen_get_temp(rdev); + break; + default: + temp = 0; + break; + } + + return snprintf(buf, PAGE_SIZE, "%d\n", temp); +} + +static ssize_t radeon_hwmon_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "radeon\n"); +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(name, S_IRUGO, radeon_hwmon_show_name, NULL, 0); + +static struct attribute *hwmon_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group hwmon_attrgroup = { + .attrs = hwmon_attributes, +}; + +static void radeon_hwmon_init(struct radeon_device *rdev) +{ + int err; + + rdev->pm.int_hwmon_dev = NULL; + + switch (rdev->pm.int_thermal_type) { + case THERMAL_TYPE_RV6XX: + case THERMAL_TYPE_RV770: + case THERMAL_TYPE_EVERGREEN: + rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); + dev_set_drvdata(rdev->pm.int_hwmon_dev, rdev->ddev); + err = sysfs_create_group(&rdev->pm.int_hwmon_dev->kobj, + &hwmon_attrgroup); + if (err) + DRM_ERROR("Unable to create hwmon sysfs file: %d\n", err); + break; + default: + break; + } +} + +static void radeon_hwmon_fini(struct radeon_device *rdev) +{ + if (rdev->pm.int_hwmon_dev) { + sysfs_remove_group(&rdev->pm.int_hwmon_dev->kobj, &hwmon_attrgroup); + hwmon_device_unregister(rdev->pm.int_hwmon_dev); + } +} + void radeon_pm_suspend(struct radeon_device *rdev) { bool flush_wq = false; @@ -470,6 +548,7 @@ int radeon_pm_init(struct radeon_device *rdev) rdev->pm.dynpm_can_downclock = true; rdev->pm.current_sclk = rdev->clock.default_sclk; rdev->pm.current_mclk = rdev->clock.default_mclk; + rdev->pm.int_thermal_type = THERMAL_TYPE_NONE; if (rdev->bios) { if (rdev->is_atom_bios) @@ -480,6 +559,8 @@ int radeon_pm_init(struct radeon_device *rdev) radeon_pm_init_profile(rdev); } + /* set up the internal thermal sensor if applicable */ + radeon_hwmon_init(rdev); if (rdev->pm.num_power_states > 1) { /* where's the best place to put these? */ ret = device_create_file(rdev->dev, &dev_attr_power_profile); @@ -535,6 +616,7 @@ void radeon_pm_fini(struct radeon_device *rdev) #endif } + radeon_hwmon_fini(rdev); if (rdev->pm.i2c_bus) radeon_i2c_destroy(rdev->pm.i2c_bus); } diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 6a7bf10..836c15a 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -42,6 +42,21 @@ static void rv770_gpu_init(struct radeon_device *rdev); void rv770_fini(struct radeon_device *rdev); +/* get temperature in millidegrees */ +u32 rv770_get_temp(struct radeon_device *rdev) +{ + u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> + ASIC_T_SHIFT; + u32 actual_temp = 0; + + if ((temp >> 9) & 1) + actual_temp = 0; + else + actual_temp = (temp >> 1) & 0xff; + + return actual_temp * 1000; +} + void rv770_pm_misc(struct radeon_device *rdev) { int req_ps_idx = rdev->pm.requested_power_state_index; diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 9506f8c..fd733f2 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -122,6 +122,11 @@ #define GUI_ACTIVE (1<<31) #define GRBM_STATUS2 0x8014 +#define CG_MULT_THERMAL_STATUS 0x740 +#define ASIC_T(x) ((x) << 16) +#define ASIC_T_MASK 0x3FF0000 +#define ASIC_T_SHIFT 16 + #define HDP_HOST_PATH_CNTL 0x2C00 #define HDP_NONSURFACE_BASE 0x2C04 #define HDP_NONSURFACE_INFO 0x2C08 -- cgit v0.10.2 From 40c4ac1c1931eb48ca0cf5e9ec464d13c5921994 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 20 May 2010 12:04:59 -0400 Subject: drm/radeon/kms: Add crtc tiling setup support for r6xx/r7xx Needed for scanning out of a tiled buffer. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a22d5a3..3b8f087 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1000,11 +1000,18 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, return -EINVAL; } - if (tiling_flags & RADEON_TILING_MACRO) - fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; + if (rdev->family >= CHIP_R600) { + if (tiling_flags & RADEON_TILING_MACRO) + fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1; + else if (tiling_flags & RADEON_TILING_MICRO) + fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1; + } else { + if (tiling_flags & RADEON_TILING_MACRO) + fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; - if (tiling_flags & RADEON_TILING_MICRO) - fb_format |= AVIVO_D1GRPH_TILED; + if (tiling_flags & RADEON_TILING_MICRO) + fb_format |= AVIVO_D1GRPH_TILED; + } if (radeon_crtc->crtc_id == 0) WREG32(AVIVO_D1VGA_CONTROL, 0); diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 93c9a2b..6ac1f60 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h @@ -386,6 +386,11 @@ # define AVIVO_D1GRPH_TILED (1 << 20) # define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) +# define R600_D1GRPH_ARRAY_MODE_LINEAR_GENERAL (0 << 20) +# define R600_D1GRPH_ARRAY_MODE_LINEAR_ALIGNED (1 << 20) +# define R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1 (2 << 20) +# define R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1 (4 << 20) + /* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2 * block and vice versa. This applies to GRPH, CUR, etc. */ -- cgit v0.10.2 From 97d663285322b3db05613d274b1eb3f9806f37ca Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 20 May 2010 12:12:48 -0400 Subject: drm/radeon/kms: Add crtc tiling setup support for evergreen Needed for scanning out of a tiled buffer. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 3b8f087..ec70234 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -862,6 +862,11 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, return -EINVAL; } + if (tiling_flags & RADEON_TILING_MACRO) + fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); + else if (tiling_flags & RADEON_TILING_MICRO) + fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); + switch (radeon_crtc->crtc_id) { case 0: WREG32(AVIVO_D1VGA_CONTROL, 0); diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index e028c1c..2330f3a 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h @@ -61,6 +61,11 @@ # define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5 # define EVERGREEN_GRPH_FORMAT_RGB111110 6 # define EVERGREEN_GRPH_FORMAT_BGR101111 7 +# define EVERGREEN_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) +# define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL 0 +# define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1 +# define EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1 2 +# define EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1 4 #define EVERGREEN_GRPH_SWAP_CONTROL 0x680c # define EVERGREEN_GRPH_ENDIAN_SWAP(x) (((x) & 0x3) << 0) # define EVERGREEN_GRPH_ENDIAN_NONE 0 -- cgit v0.10.2 From 7f813377203a60be01a3354664edc5d3c746100d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 20 May 2010 12:43:52 -0400 Subject: drm/radeon/kms: add tiling support to the cs checker for r6xx/r7xx Check for relocs for DB_DEPTH_INFO, CB_COLOR*_INFO, and texture resources. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index c39c1bc..5cab1b4 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -725,7 +725,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx track->db_depth_control = radeon_get_ib_value(p, idx); break; case R_028010_DB_DEPTH_INFO: - track->db_depth_info = radeon_get_ib_value(p, idx); + if (r600_cs_packet_next_is_pkt3_nop(p)) { + r = r600_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + track->db_depth_info = radeon_get_ib_value(p, idx); + ib[idx] &= C_028010_ARRAY_MODE; + track->db_depth_info &= C_028010_ARRAY_MODE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { + ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); + track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); + } else { + ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); + track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); + } + } else + track->db_depth_info = radeon_get_ib_value(p, idx); break; case R_028004_DB_DEPTH_VIEW: track->db_depth_view = radeon_get_ib_value(p, idx); @@ -758,8 +776,25 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx case R_0280B4_CB_COLOR5_INFO: case R_0280B8_CB_COLOR6_INFO: case R_0280BC_CB_COLOR7_INFO: - tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; - track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); + if (r600_cs_packet_next_is_pkt3_nop(p)) { + r = r600_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); + return -EINVAL; + } + tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; + track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { + ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); + track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); + } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { + ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); + track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); + } + } else { + tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; + track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); + } break; case R_028060_CB_COLOR0_SIZE: case R_028064_CB_COLOR1_SIZE: @@ -986,8 +1021,9 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels * the texture and mipmap bo object are big enough to cover this resource. */ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, - struct radeon_bo *texture, - struct radeon_bo *mipmap) + struct radeon_bo *texture, + struct radeon_bo *mipmap, + u32 tiling_flags) { u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0; u32 word0, word1, l0_size, mipmap_size; @@ -995,7 +1031,12 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i /* on legacy kernel we don't perform advanced check */ if (p->rdev == NULL) return 0; + word0 = radeon_get_ib_value(p, idx + 0); + if (tiling_flags & RADEON_TILING_MACRO) + word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); + else if (tiling_flags & RADEON_TILING_MICRO) + word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); word1 = radeon_get_ib_value(p, idx + 1); w0 = G_038000_TEX_WIDTH(word0) + 1; h0 = G_038004_TEX_HEIGHT(word1) + 1; @@ -1240,6 +1281,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); texture = reloc->robj; /* tex mip base */ r = r600_cs_packet_next_reloc(p, &reloc); @@ -1250,7 +1295,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); mipmap = reloc->robj; r = r600_check_texture_resource(p, idx+(i*7)+1, - texture, mipmap); + texture, mipmap, reloc->lobj.tiling_flags); if (r) return r; break; diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 23205f0..b7318ac 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -1159,6 +1159,10 @@ #define S_038000_TILE_MODE(x) (((x) & 0xF) << 3) #define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF) #define C_038000_TILE_MODE 0xFFFFFF87 +#define V_038000_ARRAY_LINEAR_GENERAL 0x00000000 +#define V_038000_ARRAY_LINEAR_ALIGNED 0x00000001 +#define V_038000_ARRAY_1D_TILED_THIN1 0x00000002 +#define V_038000_ARRAY_2D_TILED_THIN1 0x00000004 #define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7) #define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1) #define C_038000_TILE_TYPE 0xFFFFFF7F @@ -1362,6 +1366,8 @@ #define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15) #define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF) #define C_028010_ARRAY_MODE 0xFFF87FFF +#define V_028010_ARRAY_1D_TILED_THIN1 0x00000002 +#define V_028010_ARRAY_2D_TILED_THIN1 0x00000004 #define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25) #define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1) #define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF -- cgit v0.10.2 From 40e2a5c15d09e02a71711735564151c789f95032 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 4 Jun 2010 18:41:42 -0400 Subject: drm/radeon/kms: fix CS alignment checking for tiling (v2) Covers depth, cb, and textures. Hopefully I got this right. v2: - fix bugs: https://bugs.freedesktop.org/show_bug.cgi?id=28327 https://bugs.freedesktop.org/show_bug.cgi?id=28381 - use ALIGNED(), IS_ALIGNED() macros Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 5cab1b4..39bac5c 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -25,6 +25,7 @@ * Alex Deucher * Jerome Glisse */ +#include #include "drmP.h" #include "radeon.h" #include "r600d.h" @@ -166,7 +167,7 @@ static void r600_cs_track_init(struct r600_cs_track *track) static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) { struct r600_cs_track *track = p->track; - u32 bpe = 0, pitch, slice_tile_max, size, tmp, height; + u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align; volatile u32 *ib = p->ib->ptr; if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { @@ -180,56 +181,57 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) i, track->cb_color_info[i]); return -EINVAL; } - pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) << 3; + /* pitch is the number of 8x8 tiles per row */ + pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1; slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; - if (!pitch) { - dev_warn(p->dev, "%s:%d cb pitch (%d) for %d invalid (0x%08X)\n", - __func__, __LINE__, pitch, i, track->cb_color_size[i]); - return -EINVAL; - } - height = size / (pitch * bpe); + height = size / (pitch * 8 * bpe); if (height > 8192) height = 8192; + if (height > 7) + height &= ~0x7; switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) { case V_0280A0_ARRAY_LINEAR_GENERAL: + /* technically height & 0x7 */ + break; case V_0280A0_ARRAY_LINEAR_ALIGNED: - if (pitch & 0x3f) { - dev_warn(p->dev, "%s:%d cb pitch (%d x %d = %d) invalid\n", - __func__, __LINE__, pitch, bpe, pitch * bpe); + pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", + __func__, __LINE__, pitch); return -EINVAL; } - if ((pitch * bpe) & (track->group_size - 1)) { - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); + if (!IS_ALIGNED(height, 8)) { + dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", + __func__, __LINE__, height); return -EINVAL; } break; case V_0280A0_ARRAY_1D_TILED_THIN1: - if ((pitch * 8 * bpe * track->nsamples) & (track->group_size - 1)) { + pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8; + if (!IS_ALIGNED(pitch, pitch_align)) { dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); + __func__, __LINE__, pitch); + return -EINVAL; + } + if (!IS_ALIGNED(height, 8)) { + dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", + __func__, __LINE__, height); return -EINVAL; } - height &= ~0x7; - if (!height) - height = 8; break; case V_0280A0_ARRAY_2D_TILED_THIN1: - if (pitch & ((8 * track->nbanks) - 1)) { + pitch_align = max((u32)track->nbanks, + (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)); + if (!IS_ALIGNED(pitch, pitch_align)) { dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", __func__, __LINE__, pitch); return -EINVAL; } - tmp = pitch * 8 * bpe * track->nsamples; - tmp = tmp / track->nbanks; - if (tmp & (track->group_size - 1)) { - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); + if (!IS_ALIGNED((height / 8), track->nbanks)) { + dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", + __func__, __LINE__, height); return -EINVAL; } - height &= ~((16 * track->npipes) - 1); - if (!height) - height = 16 * track->npipes; break; default: dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, @@ -238,16 +240,20 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) return -EINVAL; } /* check offset */ - tmp = height * pitch; + tmp = height * pitch * 8 * bpe; if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { - dev_warn(p->dev, "%s offset[%d] %d to big\n", __func__, i, track->cb_color_bo_offset[i]); + dev_warn(p->dev, "%s offset[%d] %d too big\n", __func__, i, track->cb_color_bo_offset[i]); + return -EINVAL; + } + if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) { + dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]); return -EINVAL; } /* limit max tile */ - tmp = (height * pitch) >> 6; + tmp = (height * pitch * 8) >> 6; if (tmp < slice_tile_max) slice_tile_max = tmp; - tmp = S_028060_PITCH_TILE_MAX((pitch >> 3) - 1) | + tmp = S_028060_PITCH_TILE_MAX(pitch - 1) | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); ib[track->cb_color_size_idx[i]] = tmp; return 0; @@ -289,7 +295,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) /* Check depth buffer */ if (G_028800_STENCIL_ENABLE(track->db_depth_control) || G_028800_Z_ENABLE(track->db_depth_control)) { - u32 nviews, bpe, ntiles; + u32 nviews, bpe, ntiles, pitch, pitch_align, height, size; if (track->db_bo == NULL) { dev_warn(p->dev, "z/stencil with no depth buffer\n"); return -EINVAL; @@ -332,6 +338,51 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) } ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); } else { + size = radeon_bo_size(track->db_bo); + pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1; + height = size / (pitch * 8 * bpe); + height &= ~0x7; + if (!height) + height = 8; + + switch (G_028010_ARRAY_MODE(track->db_depth_info)) { + case V_028010_ARRAY_1D_TILED_THIN1: + pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8); + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + if (!IS_ALIGNED(height, 8)) { + dev_warn(p->dev, "%s:%d db height (%d) invalid\n", + __func__, __LINE__, height); + return -EINVAL; + } + break; + case V_028010_ARRAY_2D_TILED_THIN1: + pitch_align = max((u32)track->nbanks, + (u32)(((track->group_size / 8) / bpe) * track->nbanks)); + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + if ((height / 8) & (track->nbanks - 1)) { + dev_warn(p->dev, "%s:%d db height (%d) invalid\n", + __func__, __LINE__, height); + return -EINVAL; + } + break; + default: + dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, + G_028010_ARRAY_MODE(track->db_depth_info), + track->db_depth_info); + return -EINVAL; + } + if (!IS_ALIGNED(track->db_offset, track->group_size)) { + dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset); + return -EINVAL; + } ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; tmp = ntiles * bpe * 64 * nviews; @@ -982,8 +1033,9 @@ static inline unsigned minify(unsigned size, unsigned levels) } static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels, - unsigned w0, unsigned h0, unsigned d0, unsigned bpe, - unsigned *l0_size, unsigned *mipmap_size) + unsigned w0, unsigned h0, unsigned d0, unsigned bpe, + unsigned pitch_align, + unsigned *l0_size, unsigned *mipmap_size) { unsigned offset, i, level, face; unsigned width, height, depth, rowstride, size; @@ -996,13 +1048,13 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels height = minify(h0, i); depth = minify(d0, i); for(face = 0; face < nfaces; face++) { - rowstride = ((width * bpe) + 255) & ~255; + rowstride = ALIGN((width * bpe), pitch_align); size = height * rowstride * depth; offset += size; offset = (offset + 0x1f) & ~0x1f; } } - *l0_size = (((w0 * bpe) + 255) & ~255) * h0 * d0; + *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0; *mipmap_size = offset; if (!blevel) *mipmap_size -= *l0_size; @@ -1025,8 +1077,9 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i struct radeon_bo *mipmap, u32 tiling_flags) { + struct r600_cs_track *track = p->track; u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0; - u32 word0, word1, l0_size, mipmap_size; + u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align; /* on legacy kernel we don't perform advanced check */ if (p->rdev == NULL) @@ -1063,11 +1116,55 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i __func__, __LINE__, G_038004_DATA_FORMAT(word1)); return -EINVAL; } + + pitch = G_038000_PITCH(word0) + 1; + switch (G_038000_TILE_MODE(word0)) { + case V_038000_ARRAY_LINEAR_GENERAL: + pitch_align = 1; + /* XXX check height align */ + break; + case V_038000_ARRAY_LINEAR_ALIGNED: + pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + /* XXX check height align */ + break; + case V_038000_ARRAY_1D_TILED_THIN1: + pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8; + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + /* XXX check height align */ + break; + case V_038000_ARRAY_2D_TILED_THIN1: + pitch_align = max((u32)track->nbanks, + (u32)(((track->group_size / 8) / bpe) * track->nbanks)); + if (!IS_ALIGNED(pitch, pitch_align)) { + dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", + __func__, __LINE__, pitch); + return -EINVAL; + } + /* XXX check height align */ + break; + default: + dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, + G_038000_TILE_MODE(word0), word0); + return -EINVAL; + } + /* XXX check offset align */ + word0 = radeon_get_ib_value(p, idx + 4); word1 = radeon_get_ib_value(p, idx + 5); blevel = G_038010_BASE_LEVEL(word0); nlevels = G_038014_LAST_LEVEL(word1); - r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, &l0_size, &mipmap_size); + r600_texture_size(nfaces, blevel, nlevels, w0, h0, d0, bpe, + (pitch_align * bpe), + &l0_size, &mipmap_size); /* using get ib will give us the offset into the texture bo */ word0 = radeon_get_ib_value(p, idx + 2); if ((l0_size + word0) > radeon_bo_size(texture)) { -- cgit v0.10.2 From e7aeeba6a8fb86ac52bcffa0b72942f784f2b37f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 4 Jun 2010 13:10:12 -0400 Subject: drm/radeon/kms/r6xx+: add query for tile config (v2) Userspace needs this information to access tiled buffers via the CPU. v2: rebased on evergreen accel changes Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 1b7da39..957d506 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1132,6 +1132,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.max_backends) & EVERGREEN_MAX_BACKENDS_MASK)); + rdev->config.evergreen.tile_config = gb_addr_config; WREG32(GB_BACKEND_MAP, gb_backend_map); WREG32(GB_ADDR_CONFIG, gb_addr_config); WREG32(DMIF_ADDR_CONFIG, gb_addr_config); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 15fe6c2..aa36ef6 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1623,7 +1623,7 @@ void r600_gpu_init(struct radeon_device *rdev) r600_count_pipe_bits((cc_rb_backend_disable & R6XX_MAX_BACKENDS_MASK) >> 16)), (cc_rb_backend_disable >> 16)); - + rdev->config.r600.tile_config = tiling_config; tiling_config |= BACKEND_MAP(backend_map); WREG32(GB_TILING_CONFIG, tiling_config); WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index d4d776d..be8420e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -914,6 +914,7 @@ struct r600_asic { unsigned tiling_nbanks; unsigned tiling_npipes; unsigned tiling_group_size; + unsigned tile_config; struct r100_gpu_lockup lockup; }; @@ -938,6 +939,7 @@ struct rv770_asic { unsigned tiling_nbanks; unsigned tiling_npipes; unsigned tiling_group_size; + unsigned tile_config; struct r100_gpu_lockup lockup; }; @@ -963,6 +965,7 @@ struct evergreen_asic { unsigned tiling_nbanks; unsigned tiling_npipes; unsigned tiling_group_size; + unsigned tile_config; }; union radeon_asic_config { diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index ed0ceb3..6f8a2e5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -46,9 +46,10 @@ * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs * - 2.4.0 - add crtc id query * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen + * - 2.6.0 - add tiling config query (r6xx+) */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 5 +#define KMS_DRIVER_MINOR 6 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 70fda63..9012e6f 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -147,6 +147,18 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) case RADEON_INFO_ACCEL_WORKING2: value = rdev->accel_working; break; + case RADEON_INFO_TILING_CONFIG: + if (rdev->family >= CHIP_CEDAR) + value = rdev->config.evergreen.tile_config; + else if (rdev->family >= CHIP_RV770) + value = rdev->config.rv770.tile_config; + else if (rdev->family >= CHIP_R600) + value = rdev->config.r600.tile_config; + else { + DRM_DEBUG("tiling config is r6xx+ only!\n"); + return -EINVAL; + } + break; default: DRM_DEBUG("Invalid request %d\n", info->request); return -EINVAL; diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 836c15a..236fe66 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -674,8 +674,9 @@ static void rv770_gpu_init(struct radeon_device *rdev) r600_count_pipe_bits((cc_rb_backend_disable & R7XX_MAX_BACKENDS_MASK) >> 16)), (cc_rb_backend_disable >> 16)); - gb_tiling_config |= BACKEND_MAP(backend_map); + rdev->config.rv770.tile_config = gb_tiling_config; + gb_tiling_config |= BACKEND_MAP(backend_map); WREG32(GB_TILING_CONFIG, gb_tiling_config); WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 5347063..ac5f040 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -904,6 +904,7 @@ struct drm_radeon_cs { #define RADEON_INFO_ACCEL_WORKING 0x03 #define RADEON_INFO_CRTC_FROM_ID 0x04 #define RADEON_INFO_ACCEL_WORKING2 0x05 +#define RADEON_INFO_TILING_CONFIG 0x06 struct drm_radeon_info { uint32_t request; -- cgit v0.10.2 From 7eea7e9eea106a9c49cddf780f590dd8161481fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 19 Jun 2010 12:24:56 +0200 Subject: drm/radeon/kms: track audio engine state, do not use not setup timer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed to enable audio support on devices using polling. In case user decides to disable audio (module parameter) we still will try to use timer in r600_audio_enable_polling. This would lead to BUG in kernel/timer.c. Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 2b26553..631e1ed 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -160,6 +160,7 @@ static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) { DRM_INFO("%s audio support", enable ? "Enabling" : "Disabling"); WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000); + rdev->audio_enabled = enable; } /* @@ -200,7 +201,8 @@ void r600_audio_enable_polling(struct drm_encoder *encoder) return; radeon_encoder->audio_polling_active = 1; - mod_timer(&rdev->audio_timer, jiffies + 1); + if (rdev->audio_enabled) + mod_timer(&rdev->audio_timer, jiffies + 1); } /* @@ -266,7 +268,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) */ void r600_audio_fini(struct radeon_device *rdev) { - if (!radeon_audio || !r600_audio_chipset_supported(rdev)) + if (!rdev->audio_enabled) return; del_timer(&rdev->audio_timer); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index be8420e..0314175 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1084,6 +1084,7 @@ struct radeon_device { struct mutex vram_mutex; /* audio stuff */ + bool audio_enabled; struct timer_list audio_timer; int audio_channels; int audio_rate; -- cgit v0.10.2 From fe50ac78a6ec20db267b32e27a1d191128eaaa46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 19 Jun 2010 12:24:57 +0200 Subject: drm/radeon/kms: enable HDMI audio on RS600/RS690/RS740 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need method of selecting encoder that should receive HDMI block. For now we assign HDMI block to first enabled encoder. Hopefully there are not many RS6x0 chips with two digital encoders. [airlied: add RS740 checks as per Alex suggestion.] Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 26b4bc9..e6a58ed 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -435,7 +435,8 @@ static int r600_hdmi_find_free_block(struct drm_device *dev) } } - if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) { + if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || + rdev->family == CHIP_RS740) { return free_blocks[0] ? R600_HDMI_BLOCK1 : 0; } else if (rdev->family >= CHIP_R600) { if (free_blocks[0]) @@ -466,7 +467,8 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder) if (ASIC_IS_DCE32(rdev)) radeon_encoder->hdmi_config_offset = dig->dig_encoder ? R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; - } else if (rdev->family >= CHIP_R600) { + } else if (rdev->family >= CHIP_R600 || rdev->family == CHIP_RS600 || + rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev); } } diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 5ce3ccc..27d2e70 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -812,6 +812,13 @@ static int rs600_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failled initializing IB (%d).\n", r); return r; } + + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing audio\n"); + return r; + } + return 0; } @@ -838,6 +845,7 @@ int rs600_resume(struct radeon_device *rdev) int rs600_suspend(struct radeon_device *rdev) { + r600_audio_fini(rdev); r100_cp_disable(rdev); r100_wb_disable(rdev); rs600_irq_disable(rdev); @@ -847,6 +855,7 @@ int rs600_suspend(struct radeon_device *rdev) void rs600_fini(struct radeon_device *rdev) { + r600_audio_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 5fea094..23676b6 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -640,6 +640,13 @@ static int rs690_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failled initializing IB (%d).\n", r); return r; } + + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing audio\n"); + return r; + } + return 0; } @@ -666,6 +673,7 @@ int rs690_resume(struct radeon_device *rdev) int rs690_suspend(struct radeon_device *rdev) { + r600_audio_fini(rdev); r100_cp_disable(rdev); r100_wb_disable(rdev); rs600_irq_disable(rdev); @@ -675,6 +683,7 @@ int rs690_suspend(struct radeon_device *rdev) void rs690_fini(struct radeon_device *rdev) { + r600_audio_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); -- cgit v0.10.2 From 351a52a2414d2b104269755c86b476863c248034 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 30 Jun 2010 11:52:50 -0400 Subject: drm/radeon/kms: add ioport register access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required for the NB_MISC regs on rs780/rs880 which means HDMI/DVI/DP ports using PCIEPHY won't work without it. It might also help with s/r (asic init) issues on other atombios cards. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=28774 and similar issues reported by Alberto Milone. [airlied: Squash io fix patch] Signed-off-by: Alex Deucher Tested-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index bded870..8e421f6 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -108,12 +108,11 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, base++; break; case ATOM_IIO_READ: - temp = ctx->card->reg_read(ctx->card, CU16(base + 1)); + temp = ctx->card->ioreg_read(ctx->card, CU16(base + 1)); base += 3; break; case ATOM_IIO_WRITE: - (void)ctx->card->reg_read(ctx->card, CU16(base + 1)); - ctx->card->reg_write(ctx->card, CU16(base + 1), temp); + ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp); base += 3; break; case ATOM_IIO_CLEAR: diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index cd1b64a..a589a55 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h @@ -113,6 +113,8 @@ struct card_info { struct drm_device *dev; void (* reg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ uint32_t (* reg_read)(struct card_info *, uint32_t); /* filled by driver */ + void (* ioreg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ + uint32_t (* ioreg_read)(struct card_info *, uint32_t); /* filled by driver */ void (* mc_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ uint32_t (* mc_read)(struct card_info *, uint32_t); /* filled by driver */ void (* pll_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 0314175..966ba07 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1048,6 +1048,9 @@ struct radeon_device { uint32_t pcie_reg_mask; radeon_rreg_t pciep_rreg; radeon_wreg_t pciep_wreg; + /* io port */ + void __iomem *rio_mem; + resource_size_t rio_mem_size; struct radeon_clock clock; struct radeon_mc mc; struct radeon_gart gart; @@ -1130,6 +1133,26 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 } } +static inline u32 r100_io_rreg(struct radeon_device *rdev, u32 reg) +{ + if (reg < rdev->rio_mem_size) + return ioread32(rdev->rio_mem + reg); + else { + iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); + return ioread32(rdev->rio_mem + RADEON_MM_DATA); + } +} + +static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) +{ + if (reg < rdev->rio_mem_size) + iowrite32(v, rdev->rio_mem + reg); + else { + iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); + iowrite32(v, rdev->rio_mem + RADEON_MM_DATA); + } +} + /* * Cast helper */ @@ -1168,6 +1191,8 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 WREG32_PLL(reg, tmp_); \ } while (0) #define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg))) +#define RREG32_IO(reg) r100_io_rreg(rdev, (reg)) +#define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v)) /* * Indirect registers accessor diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 37533be..fefeb0f 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -415,6 +415,22 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) return r; } +static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val) +{ + struct radeon_device *rdev = info->dev->dev_private; + + WREG32_IO(reg*4, val); +} + +static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) +{ + struct radeon_device *rdev = info->dev->dev_private; + uint32_t r; + + r = RREG32_IO(reg*4); + return r; +} + int radeon_atombios_init(struct radeon_device *rdev) { struct card_info *atom_card_info = @@ -427,6 +443,15 @@ int radeon_atombios_init(struct radeon_device *rdev) atom_card_info->dev = rdev->ddev; atom_card_info->reg_read = cail_reg_read; atom_card_info->reg_write = cail_reg_write; + /* needed for iio ops */ + if (rdev->rio_mem) { + atom_card_info->ioreg_read = cail_ioreg_read; + atom_card_info->ioreg_write = cail_ioreg_write; + } else { + DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n"); + atom_card_info->ioreg_read = cail_reg_read; + atom_card_info->ioreg_write = cail_reg_write; + } atom_card_info->mc_read = cail_mc_read; atom_card_info->mc_write = cail_mc_write; atom_card_info->pll_read = cail_pll_read; @@ -573,7 +598,7 @@ int radeon_device_init(struct radeon_device *rdev, struct pci_dev *pdev, uint32_t flags) { - int r; + int r, i; int dma_bits; rdev->shutdown = false; @@ -659,6 +684,17 @@ int radeon_device_init(struct radeon_device *rdev, DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); + /* io port mapping */ + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (pci_resource_flags(rdev->pdev, i) & IORESOURCE_IO) { + rdev->rio_mem_size = pci_resource_len(rdev->pdev, i); + rdev->rio_mem = pci_iomap(rdev->pdev, i, rdev->rio_mem_size); + break; + } + } + if (rdev->rio_mem == NULL) + DRM_ERROR("Unable to find PCI I/O BAR\n"); + /* if we have > 1 VGA cards, then disable the radeon VGA resources */ /* this will fail for cards that aren't VGA class devices, just * ignore it */ @@ -701,6 +737,8 @@ void radeon_device_fini(struct radeon_device *rdev) destroy_workqueue(rdev->wq); vga_switcheroo_unregister_client(rdev->pdev); vga_client_register(rdev->pdev, NULL, NULL, NULL); + pci_iounmap(rdev->pdev, rdev->rio_mem); + rdev->rio_mem = NULL; iounmap(rdev->rmmio); rdev->rmmio = NULL; } -- cgit v0.10.2 From e376573f7267390f4e1bdc552564b6fb913bce76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 8 Jul 2010 12:43:28 +1000 Subject: drm/radeon: fall back to GTT if bo creation/validation in VRAM fails. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a problem where on low VRAM cards we'd run out of space for validation. [airlied: Tested on my M7, Thinkpad T42, compiz works with no problems.] Signed-off-by: Michel Dänzer Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index d5b9373..0afd1e6 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -110,6 +110,7 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, bo->surface_reg = -1; INIT_LIST_HEAD(&bo->list); +retry: radeon_ttm_placement_from_domain(bo, domain); /* Kernel allocation are uninterruptible */ mutex_lock(&rdev->vram_mutex); @@ -118,10 +119,15 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, &radeon_ttm_bo_destroy); mutex_unlock(&rdev->vram_mutex); if (unlikely(r != 0)) { - if (r != -ERESTARTSYS) + if (r != -ERESTARTSYS) { + if (domain == RADEON_GEM_DOMAIN_VRAM) { + domain |= RADEON_GEM_DOMAIN_GTT; + goto retry; + } dev_err(rdev->dev, "object_init failed for (%lu, 0x%08X)\n", size, domain); + } return r; } *bo_ptr = bo; @@ -321,6 +327,7 @@ int radeon_bo_list_validate(struct list_head *head) { struct radeon_bo_list *lobj; struct radeon_bo *bo; + u32 domain; int r; list_for_each_entry(lobj, head, list) { @@ -333,17 +340,19 @@ int radeon_bo_list_validate(struct list_head *head) list_for_each_entry(lobj, head, list) { bo = lobj->bo; if (!bo->pin_count) { - if (lobj->wdomain) { - radeon_ttm_placement_from_domain(bo, - lobj->wdomain); - } else { - radeon_ttm_placement_from_domain(bo, - lobj->rdomain); - } + domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; + + retry: + radeon_ttm_placement_from_domain(bo, domain); r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false, false); - if (unlikely(r)) + if (unlikely(r)) { + if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) { + domain |= RADEON_GEM_DOMAIN_GTT; + goto retry; + } return r; + } } lobj->gpu_offset = radeon_bo_gpu_offset(bo); lobj->tiling_flags = bo->tiling_flags; -- cgit v0.10.2 From 4c712e6c7ef19e7e8e1f38b27bb65290def39b40 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 15 Jul 2010 12:13:50 +1000 Subject: drm/radeon/kms: check/restore sanity before doing anything else with GPU. On systems using kexec, the new kernel is booted straight from the old kernel, without any warning to the graphics driver. So the GPU is basically left as-is in a running state, however the CPU side is completly reset. Without stating the saneness of anyone using kexec on live systems, we should at least try not to crash the GPU. This patch resets 3 registers to 0 that could cause bad things to happen to the running system. This allows kexec to work on a Power6/RN50 system. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 5aa2995..5d14732 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3809,6 +3809,31 @@ void r100_fini(struct radeon_device *rdev) rdev->bios = NULL; } +/* + * Due to how kexec works, it can leave the hw fully initialised when it + * boots the new kernel. However doing our init sequence with the CP and + * WB stuff setup causes GPU hangs on the RN50 at least. So at startup + * do some quick sanity checks and restore sane values to avoid this + * problem. + */ +void r100_restore_sanity(struct radeon_device *rdev) +{ + u32 tmp; + + tmp = RREG32(RADEON_CP_CSQ_CNTL); + if (tmp) { + WREG32(RADEON_CP_CSQ_CNTL, 0); + } + tmp = RREG32(RADEON_CP_RB_CNTL); + if (tmp) { + WREG32(RADEON_CP_RB_CNTL, 0); + } + tmp = RREG32(RADEON_SCRATCH_UMSK); + if (tmp) { + WREG32(RADEON_SCRATCH_UMSK, 0); + } +} + int r100_init(struct radeon_device *rdev) { int r; @@ -3821,6 +3846,8 @@ int r100_init(struct radeon_device *rdev) radeon_scratch_init(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + /* sanity check some register to avoid hangs like after kexec */ + r100_restore_sanity(rdev); /* TODO: disable VGA need to use VGA request */ /* BIOS*/ if (!radeon_get_bios(rdev)) { diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 7e81db5..3c34da0 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1377,6 +1377,8 @@ int r300_init(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev); /* TODO: disable VGA need to use VGA request */ + /* restore some register to sane defaults */ + r100_restore_sanity(rdev); /* BIOS*/ if (!radeon_get_bios(rdev)) { if (ASIC_IS_AVIVO(rdev)) diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index e6c8914..59f7bcc 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -343,6 +343,8 @@ int r420_init(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev); /* TODO: disable VGA need to use VGA request */ + /* restore some register to sane defaults */ + r100_restore_sanity(rdev); /* BIOS*/ if (!radeon_get_bios(rdev)) { if (ASIC_IS_AVIVO(rdev)) diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 34330df..213e2e0 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -230,6 +230,8 @@ int r520_init(struct radeon_device *rdev) radeon_scratch_init(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + /* restore some register to sane defaults */ + r100_restore_sanity(rdev); /* TODO: disable VGA need to use VGA request */ /* BIOS*/ if (!radeon_get_bios(rdev)) { diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index c0bbaa6..a5aff75 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -113,6 +113,7 @@ void r100_wb_fini(struct radeon_device *rdev); int r100_wb_init(struct radeon_device *rdev); int r100_cp_reset(struct radeon_device *rdev); void r100_vga_render_disable(struct radeon_device *rdev); +void r100_restore_sanity(struct radeon_device *rdev); int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, struct radeon_bo *robj); diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 9e4240b..c178481 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -480,6 +480,8 @@ int rs400_init(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev); /* TODO: disable VGA need to use VGA request */ + /* restore some register to sane defaults */ + r100_restore_sanity(rdev); /* BIOS*/ if (!radeon_get_bios(rdev)) { if (ASIC_IS_AVIVO(rdev)) diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 27d2e70..c576092 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -879,6 +879,8 @@ int rs600_init(struct radeon_device *rdev) radeon_scratch_init(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + /* restore some register to sane defaults */ + r100_restore_sanity(rdev); /* BIOS */ if (!radeon_get_bios(rdev)) { if (ASIC_IS_AVIVO(rdev)) diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 23676b6..3dde54d 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -707,6 +707,8 @@ int rs690_init(struct radeon_device *rdev) radeon_scratch_init(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + /* restore some register to sane defaults */ + r100_restore_sanity(rdev); /* TODO: disable VGA need to use VGA request */ /* BIOS*/ if (!radeon_get_bios(rdev)) { diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 7d9a7b0..3f04f73 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -468,6 +468,8 @@ int rv515_init(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev); /* TODO: disable VGA need to use VGA request */ + /* restore some register to sane defaults */ + r100_restore_sanity(rdev); /* BIOS*/ if (!radeon_get_bios(rdev)) { if (ASIC_IS_AVIVO(rdev)) -- cgit v0.10.2 From 167ffc44caaee68ea60dadf6931a4d195a4ed1f0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 17 Jul 2010 12:28:02 +0200 Subject: drm: radeon: fix sign bug The "error" variable is unsigned so it's never less than zero. I changed it to check if (freq < current_freq) directly. "best_error" is also unsigned so "best_error - 100" could be a large number instead of a negative. Since "error" is unsigned it is never less than a negative and so the cases where "best_error" is less than or equal to 100 are false. Signed-off-by: Dan Carpenter Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8154cdf..a68728d 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -558,15 +558,17 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll, current_freq = radeon_div(tmp, ref_div * post_div); if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) { - error = freq - current_freq; - error = error < 0 ? 0xffffffff : error; + if (freq < current_freq) + error = 0xffffffff; + else + error = freq - current_freq; } else error = abs(current_freq - freq); vco_diff = abs(vco - best_vco); if ((best_vco == 0 && error < best_error) || (best_vco != 0 && - (error < best_error - 100 || + ((best_error > 100 && error < best_error - 100) || (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) { best_post_div = post_div; best_ref_div = ref_div; -- cgit v0.10.2 From 833ee5c4ab36937a99e63935d7f06bc2c1f9343b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 16 Jul 2010 10:39:16 -0400 Subject: drm/radeon/kms: remove rs4xx gart limit We used to limit the rs4xx gart aperture to 32 MB, but I suspect that was due to not meeting the alignment requirements of the aperture. This patch should only be applied after: "drm/radeon/kms: fix gtt MC base alignment on rs4xx/rs690/rs740 asics" has been applied. This patch should probably soak for a bit in d-r-t. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 037b93a..ae2b76b 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -55,14 +55,6 @@ void rs400_gart_adjust_size(struct radeon_device *rdev) rdev->mc.gtt_size = 32 * 1024 * 1024; return; } - if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) { - /* FIXME: RS400 & RS480 seems to have issue with GART size - * if 4G of system memory (needs more testing) - */ - /* XXX is this still an issue with proper alignment? */ - rdev->mc.gtt_size = 32 * 1024 * 1024; - DRM_ERROR("Forcing to 32M GART size (because of ASIC bug ?)\n"); - } } void rs400_gart_tlb_flush(struct radeon_device *rdev) -- cgit v0.10.2 From 812d046915f48236657f02c06d7dc47140e9ceda Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 26 Jul 2010 18:51:53 -0400 Subject: drm/radeon/kms/r7xx: add workaround for hw issue with HDP flush Use of HDP_*_COHERENCY_FLUSH_CNTL can cause a hang in certain situations. Add workaround. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index e1e59e1..28e39bc 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -884,7 +884,17 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) u32 tmp; /* flush hdp cache so updates hit vram */ - WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); + if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { + void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; + u32 tmp; + + /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read + * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL + */ + WREG32(HDP_DEBUG1, 0); + tmp = readl((void __iomem *)ptr); + } else + WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); @@ -3527,5 +3537,15 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) */ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) { - WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); + /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read + * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL + */ + if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { + void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; + u32 tmp; + + WREG32(HDP_DEBUG1, 0); + tmp = readl((void __iomem *)ptr); + } else + WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); } diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index b7318ac..858a192 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -250,6 +250,7 @@ #define HDP_NONSURFACE_SIZE 0x2C0C #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 #define HDP_TILING_CONFIG 0x2F3C +#define HDP_DEBUG1 0x2F34 #define MC_VM_AGP_TOP 0x2184 #define MC_VM_AGP_BOT 0x2188 diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 236fe66..f1c79681 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -204,7 +204,10 @@ static void rv770_mc_program(struct radeon_device *rdev) WREG32((0x2c20 + j), 0x00000000); WREG32((0x2c24 + j), 0x00000000); } - WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); + /* r7xx hw bug. Read from HDP_DEBUG1 rather + * than writing to HDP_REG_COHERENCY_FLUSH_CNTL + */ + tmp = RREG32(HDP_DEBUG1); rv515_mc_stop(rdev, &save); if (r600_mc_wait_for_idle(rdev)) { diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index fd733f2..b7a5a20 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -133,6 +133,7 @@ #define HDP_NONSURFACE_SIZE 0x2C0C #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 #define HDP_TILING_CONFIG 0x2F3C +#define HDP_DEBUG1 0x2F34 #define MC_SHARED_CHMAP 0x2004 #define NOOFCHAN_SHIFT 12 -- cgit v0.10.2 From 8c119e9c3b85cb61c1b2bfd616061662367e9240 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 26 Jul 2010 12:39:00 -0400 Subject: drm/radeon: add comments to r6xx/r7xx blit state Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 0271b53..a8f8bbc 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -39,37 +39,48 @@ const u32 r6xx_default_state[] = { - 0xc0002400, + 0xc0002400, /* START_3D_CMDBUF */ 0x00000000, - 0xc0012800, + + 0xc0012800, /* CONTEXT_CONTROL */ 0x80000000, 0x80000000, + 0xc0016800, 0x00000010, - 0x00008000, + 0x00008000, /* WAIT_UNTIL */ + 0xc0016800, 0x00000542, - 0x07000003, + 0x07000003, /* TA_CNTL_AUX */ + 0xc0016800, 0x000005c5, - 0x00000000, + 0x00000000, /* VC_ENHANCE */ + 0xc0016800, 0x00000363, - 0x00000000, + 0x00000000, /* SQ_DYN_GPR_CNTL_PS_FLUSH_REQ */ + 0xc0016800, 0x0000060c, - 0x82000000, + 0x82000000, /* DB_DEBUG */ + 0xc0016800, 0x0000060e, - 0x01020204, + 0x01020204, /* DB_WATERMARKS */ + 0xc0016f00, 0x00000000, - 0x00000000, + 0x00000000, /* SQ_VTX_BASE_VTX_LOC */ + 0xc0016f00, 0x00000001, - 0x00000000, + 0x00000000, /* SQ_VTX_START_INST_LOC */ + 0xc0096900, 0x0000022a, + 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ 0x00000000, 0x00000000, 0x00000000, @@ -78,515 +89,670 @@ const u32 r6xx_default_state[] = 0x00000000, 0x00000000, 0x00000000, - 0x00000000, + 0xc0016900, 0x00000004, - 0x00000000, + 0x00000000, /* DB_DEPTH_INFO */ + 0xc0016900, 0x0000000a, - 0x00000000, + 0x00000000, /* DB_STENCIL_CLEAR */ + 0xc0016900, 0x0000000b, - 0x00000000, + 0x00000000, /* DB_DEPTH_CLEAR */ + 0xc0016900, 0x0000010c, - 0x00000000, + 0x00000000, /* DB_STENCILREFMASK */ + 0xc0016900, 0x0000010d, - 0x00000000, + 0x00000000, /* DB_STENCILREFMASK_BF */ + 0xc0016900, 0x00000200, - 0x00000000, + 0x00000000, /* DB_DEPTH_CONTROL */ + 0xc0016900, 0x00000343, - 0x00000060, + 0x00000060, /* DB_RENDER_CONTROL */ + 0xc0016900, 0x00000344, - 0x00000040, + 0x00000040, /* DB_RENDER_OVERRIDE */ + 0xc0016900, 0x00000351, - 0x0000aa00, + 0x0000aa00, /* DB_ALPHA_TO_MASK */ + 0xc0016900, 0x00000104, - 0x00000000, + 0x00000000, /* SX_ALPHA_TEST_CONTROL */ + 0xc0016900, 0x0000010e, - 0x00000000, + 0x00000000, /* SX_ALPHA_REF */ + 0xc0046900, 0x00000105, + 0x00000000, /* CB_BLEND_RED */ 0x00000000, 0x00000000, 0x00000000, - 0x00000000, + 0xc0036900, 0x00000109, + 0x00000000, /* CB_FOG_RED */ 0x00000000, 0x00000000, - 0x00000000, + 0xc0046900, 0x0000030c, - 0x01000000, + 0x01000000, /* CB_CLRCMP_CNTL */ 0x00000000, 0x00000000, 0x00000000, + 0xc0046900, 0x00000048, - 0x3f800000, + 0x3f800000, /* CB_CLEAR_RED */ 0x00000000, 0x3f800000, 0x3f800000, + 0xc0016900, 0x0000008e, - 0x0000000f, + 0x0000000f, /* CB_TARGET_MASK */ + 0xc0016900, 0x00000080, - 0x00000000, + 0x00000000, /* PA_SC_WINDOW_OFFSET */ + 0xc0016900, 0x00000083, - 0x0000ffff, + 0x0000ffff, /* PA_SC_CLIP_RECT_RULE */ + 0xc0016900, 0x00000084, - 0x00000000, + 0x00000000, /* PA_SC_WINDOW_SCISSOR_TL */ + 0xc0016900, 0x00000085, 0x20002000, + 0xc0016900, 0x00000086, 0x00000000, + 0xc0016900, 0x00000087, 0x20002000, + 0xc0016900, 0x00000088, 0x00000000, + 0xc0016900, 0x00000089, 0x20002000, + 0xc0016900, 0x0000008a, 0x00000000, + 0xc0016900, 0x0000008b, 0x20002000, + 0xc0016900, 0x0000008c, - 0x00000000, + 0x00000000, /* PA_SC_EDGERULE */ + 0xc0016900, 0x00000094, - 0x80000000, + 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ + 0xc0016900, 0x00000095, - 0x20002000, + 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ + 0xc0026900, 0x000000b4, - 0x00000000, + 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ 0x3f800000, + 0xc0016900, 0x00000096, - 0x80000000, + 0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */ + 0xc0016900, 0x00000097, 0x20002000, + 0xc0026900, 0x000000b6, 0x00000000, 0x3f800000, + 0xc0016900, 0x00000098, 0x80000000, + 0xc0016900, 0x00000099, 0x20002000, + 0xc0026900, 0x000000b8, 0x00000000, 0x3f800000, + 0xc0016900, 0x0000009a, 0x80000000, + 0xc0016900, 0x0000009b, 0x20002000, + 0xc0026900, 0x000000ba, 0x00000000, 0x3f800000, + 0xc0016900, 0x0000009c, 0x80000000, + 0xc0016900, 0x0000009d, 0x20002000, + 0xc0026900, 0x000000bc, 0x00000000, 0x3f800000, + 0xc0016900, 0x0000009e, 0x80000000, + 0xc0016900, 0x0000009f, 0x20002000, + 0xc0026900, 0x000000be, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a0, 0x80000000, + 0xc0016900, 0x000000a1, 0x20002000, + 0xc0026900, 0x000000c0, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a2, 0x80000000, + 0xc0016900, 0x000000a3, 0x20002000, + 0xc0026900, 0x000000c2, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a4, 0x80000000, + 0xc0016900, 0x000000a5, 0x20002000, + 0xc0026900, 0x000000c4, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a6, 0x80000000, + 0xc0016900, 0x000000a7, 0x20002000, + 0xc0026900, 0x000000c6, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a8, 0x80000000, + 0xc0016900, 0x000000a9, 0x20002000, + 0xc0026900, 0x000000c8, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000aa, 0x80000000, + 0xc0016900, 0x000000ab, 0x20002000, + 0xc0026900, 0x000000ca, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000ac, 0x80000000, + 0xc0016900, 0x000000ad, 0x20002000, + 0xc0026900, 0x000000cc, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000ae, 0x80000000, + 0xc0016900, 0x000000af, 0x20002000, + 0xc0026900, 0x000000ce, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000b0, 0x80000000, + 0xc0016900, 0x000000b1, 0x20002000, + 0xc0026900, 0x000000d0, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000b2, 0x80000000, + 0xc0016900, 0x000000b3, 0x20002000, + 0xc0026900, 0x000000d2, 0x00000000, 0x3f800000, + 0xc0016900, 0x00000293, - 0x00004010, + 0x00004010, /* PA_SC_MODE_CNTL */ + 0xc0016900, 0x00000300, - 0x00000000, + 0x00000000, /* PA_SC_LINE_CNTL */ + 0xc0016900, 0x00000301, - 0x00000000, + 0x00000000, /* PA_SC_AA_CONFIG */ + 0xc0016900, 0x00000312, - 0xffffffff, + 0xffffffff, /* PA_SC_AA_MASK */ + 0xc0016900, 0x00000307, - 0x00000000, + 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ + 0xc0016900, 0x00000308, 0x00000000, + 0xc0016900, 0x00000283, - 0x00000000, + 0x00000000, /* PA_SC_LINE_STIPPLE */ + 0xc0016900, 0x00000292, - 0x00000000, + 0x00000000, /* PA_SC_MPASS_PS_CNTL */ + 0xc0066900, 0x0000010f, + 0x00000000, /* PA_CL_VPORT_0_XSCALE */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, + 0xc0016900, - 0x00000206, + 0x00000206, /* PA_CL_VTE_CNTL */ 0x00000000, + 0xc0016900, 0x00000207, - 0x00000000, + 0x00000000, /* PA_CL_VS_OUT_CNTL */ + 0xc0016900, 0x00000208, - 0x00000000, + 0x00000000, /* PA_CL_NANINF_CNTL */ + 0xc0046900, 0x00000303, + 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ 0x3f800000, 0x3f800000, 0x3f800000, - 0x3f800000, + 0xc0016900, 0x00000205, - 0x00000004, + 0x00000004, /* PA_SU_SC_MODE_CNTL */ + 0xc0016900, 0x00000280, - 0x00000000, + 0x00000000, /* PA_SU_POINT_SIZE */ + 0xc0016900, 0x00000281, - 0x00000000, + 0x00000000, /* PA_SU_POINT_MINMAX */ + 0xc0016900, 0x0000037e, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ + 0xc0016900, 0x00000382, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ + 0xc0016900, 0x00000380, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ + 0xc0016900, 0x00000383, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ + 0xc0016900, 0x00000381, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ + 0xc0016900, 0x00000282, - 0x00000008, + 0x00000008, /* PA_SU_LINE_CNTL */ + 0xc0016900, 0x00000302, - 0x0000002d, + 0x0000002d, /* PA_SU_VTX_CNTL */ + 0xc0016900, 0x0000037f, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ + 0xc0016900, 0x000001b2, - 0x00000000, + 0x00000000, /* SPI_THREAD_GROUPING */ + 0xc0016900, 0x000001b6, - 0x00000000, + 0x00000000, /* SPI_INPUT_Z */ + 0xc0016900, 0x000001b7, - 0x00000000, + 0x00000000, /* SPI_FOG_CNTL */ + 0xc0016900, 0x000001b8, - 0x00000000, + 0x00000000, /* SPI_FOG_FUNC_SCALE */ + 0xc0016900, 0x000001b9, - 0x00000000, + 0x00000000, /* SPI_FOG_FUNC_BIAS */ + 0xc0016900, 0x00000225, - 0x00000000, + 0x00000000, /* SQ_PGM_START_FS */ + 0xc0016900, 0x00000229, - 0x00000000, + 0x00000000, /* SQ_PGM_RESOURCES_FS */ + 0xc0016900, 0x00000237, - 0x00000000, + 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ + 0xc0016900, 0x00000100, - 0x00000800, + 0x00000800, /* VGT_MAX_VTX_INDX */ + 0xc0016900, 0x00000101, - 0x00000000, + 0x00000000, /* VGT_MIN_VTX_INDX */ + 0xc0016900, 0x00000102, - 0x00000000, + 0x00000000, /* VGT_INDX_OFFSET */ + 0xc0016900, 0x000002a8, - 0x00000000, + 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ + 0xc0016900, 0x000002a9, - 0x00000000, + 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ + 0xc0016900, 0x00000103, - 0x00000000, + 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ + 0xc0016900, 0x00000284, - 0x00000000, + 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ + 0xc0016900, 0x00000290, - 0x00000000, + 0x00000000, /* VGT_GS_MODE */ + 0xc0016900, 0x00000285, - 0x00000000, + 0x00000000, /* VGT_HOS_CNTL */ + 0xc0016900, 0x00000286, - 0x00000000, + 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ + 0xc0016900, 0x00000287, - 0x00000000, + 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ + 0xc0016900, 0x00000288, - 0x00000000, + 0x00000000, /* VGT_HOS_REUSE_DEPTH */ + 0xc0016900, 0x00000289, - 0x00000000, + 0x00000000, /* VGT_GROUP_PRIM_TYPE */ + 0xc0016900, 0x0000028a, - 0x00000000, + 0x00000000, /* VGT_GROUP_FIRST_DECR */ + 0xc0016900, 0x0000028b, - 0x00000000, + 0x00000000, /* VGT_GROUP_DECR */ + 0xc0016900, 0x0000028c, - 0x00000000, + 0x00000000, /* VGT_GROUP_VECT_0_CNTL */ + 0xc0016900, 0x0000028d, - 0x00000000, + 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ + 0xc0016900, 0x0000028e, - 0x00000000, + 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ + 0xc0016900, 0x0000028f, - 0x00000000, + 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ + 0xc0016900, 0x000002a1, - 0x00000000, + 0x00000000, /* VGT_PRIMITIVEID_EN */ + 0xc0016900, 0x000002a5, - 0x00000000, + 0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */ + 0xc0016900, 0x000002ac, - 0x00000000, + 0x00000000, /* VGT_STRMOUT_EN */ + 0xc0016900, 0x000002ad, - 0x00000000, + 0x00000000, /* VGT_REUSE_OFF */ + 0xc0016900, 0x000002ae, - 0x00000000, + 0x00000000, /* VGT_VTX_CNT_EN */ + 0xc0016900, 0x000002c8, - 0x00000000, + 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ + 0xc0016900, 0x00000206, - 0x00000100, + 0x00000100, /* PA_CL_VTE_CNTL */ + 0xc0016900, 0x00000204, - 0x00010000, - 0xc0036e00, + 0x00010000, /* PA_CL_CLIP_CNTL */ + + 0xc0036e00, /* SET_SAMPLER */ 0x00000000, 0x00000012, 0x00000000, 0x00000000, + 0xc0016900, 0x0000008f, - 0x0000000f, + 0x0000000f, /* CB_SHADER_MASK */ + 0xc0016900, 0x000001e8, - 0x00000001, + 0x00000001, /* CB_SHADER_CONTROL */ + 0xc0016900, 0x00000202, - 0x00cc0000, + 0x00cc0000, /* CB_COLOR_CONTROL */ + 0xc0016900, 0x00000205, - 0x00000244, + 0x00000244, /* PA_SU_SC_MODE_CNTL */ + 0xc0016900, 0x00000203, - 0x00000210, + 0x00000210, /* DB_SHADER_CNTL */ + 0xc0016900, 0x000001b1, - 0x00000000, + 0x00000000, /* SPI_VS_OUT_CONFIG */ + 0xc0016900, 0x00000185, - 0x00000000, + 0x00000000, /* SPI_VS_OUT_ID_0 */ + 0xc0016900, 0x000001b3, - 0x00000001, + 0x00000001, /* SPI_PS_IN_CONTROL_0 */ + 0xc0016900, 0x000001b4, - 0x00000000, + 0x00000000, /* SPI_PS_IN_CONTROL_1 */ + 0xc0016900, 0x00000191, - 0x00000b00, + 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ + 0xc0016900, 0x000001b5, - 0x00000000, + 0x00000000, /* SPI_INTERP_CONTROL_0 */ }; const u32 r7xx_default_state[] = { - 0xc0012800, + 0xc0012800, /* CONTEXT_CONTROL */ 0x80000000, 0x80000000, + 0xc0016800, 0x00000010, - 0x00008000, + 0x00008000, /* WAIT_UNTIL */ + 0xc0016800, 0x00000542, - 0x07000002, + 0x07000002, /* TA_CNTL_AUX */ + 0xc0016800, 0x000005c5, - 0x00000000, + 0x00000000, /* VC_ENHANCE */ + 0xc0016800, 0x00000363, - 0x00004000, + 0x00004000, /* SQ_DYN_GPR_CNTL_PS_FLUSH_REQ */ + 0xc0016800, 0x0000060c, - 0x00000000, + 0x00000000, /* DB_DEBUG */ + 0xc0016800, 0x0000060e, - 0x00420204, + 0x00420204, /* DB_WATERMARKS */ + 0xc0016f00, 0x00000000, - 0x00000000, + 0x00000000, /* SQ_VTX_BASE_VTX_LOC */ + 0xc0016f00, 0x00000001, - 0x00000000, + 0x00000000, /* SQ_VTX_START_INST_LOC */ + 0xc0096900, 0x0000022a, + 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ 0x00000000, 0x00000000, 0x00000000, @@ -595,471 +761,614 @@ const u32 r7xx_default_state[] = 0x00000000, 0x00000000, 0x00000000, - 0x00000000, + 0xc0016900, 0x00000004, - 0x00000000, + 0x00000000, /* DB_DEPTH_INFO */ + 0xc0016900, 0x0000000a, - 0x00000000, + 0x00000000, /* DB_STENCIL_CLEAR */ + 0xc0016900, 0x0000000b, - 0x00000000, + 0x00000000, /* DB_DEPTH_CLEAR */ + 0xc0016900, 0x0000010c, - 0x00000000, + 0x00000000, /* DB_STENCILREFMASK */ + 0xc0016900, 0x0000010d, - 0x00000000, + 0x00000000, /* DB_STENCILREFMASK_BF */ + 0xc0016900, 0x00000200, - 0x00000000, + 0x00000000, /* DB_DEPTH_CONTROL */ + 0xc0016900, 0x00000343, - 0x00000060, + 0x00000060, /* DB_RENDER_CONTROL */ + 0xc0016900, 0x00000344, - 0x00000000, + 0x00000000, /* DB_RENDER_OVERRIDE */ + 0xc0016900, 0x00000351, - 0x0000aa00, + 0x0000aa00, /* DB_ALPHA_TO_MASK */ + 0xc0016900, 0x00000104, - 0x00000000, + 0x00000000, /* SX_ALPHA_TEST_CONTROL */ + 0xc0016900, 0x0000010e, - 0x00000000, + 0x00000000, /* SX_ALPHA_REF */ + 0xc0046900, 0x00000105, + 0x00000000, /* CB_BLEND_RED */ 0x00000000, 0x00000000, 0x00000000, - 0x00000000, + 0xc0046900, - 0x0000030c, + 0x0000030c, /* CB_CLRCMP_CNTL */ 0x01000000, 0x00000000, 0x00000000, 0x00000000, + 0xc0016900, 0x0000008e, - 0x0000000f, + 0x0000000f, /* CB_TARGET_MASK */ + 0xc0016900, 0x00000080, - 0x00000000, + 0x00000000, /* PA_SC_WINDOW_OFFSET */ + 0xc0016900, 0x00000083, - 0x0000ffff, + 0x0000ffff, /* PA_SC_CLIP_RECT_RULE */ + 0xc0016900, 0x00000084, - 0x00000000, + 0x00000000, /* PA_SC_WINDOW_SCISSOR_TL */ + 0xc0016900, 0x00000085, 0x20002000, + 0xc0016900, 0x00000086, 0x00000000, + 0xc0016900, 0x00000087, 0x20002000, + 0xc0016900, 0x00000088, 0x00000000, + 0xc0016900, 0x00000089, 0x20002000, + 0xc0016900, 0x0000008a, 0x00000000, + 0xc0016900, 0x0000008b, 0x20002000, + 0xc0016900, 0x0000008c, - 0xaaaaaaaa, + 0xaaaaaaaa, /* PA_SC_EDGERULE */ + 0xc0016900, 0x00000094, - 0x80000000, + 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ + 0xc0016900, 0x00000095, - 0x20002000, + 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ + 0xc0026900, 0x000000b4, - 0x00000000, + 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ 0x3f800000, + 0xc0016900, 0x00000096, 0x80000000, + 0xc0016900, 0x00000097, 0x20002000, + 0xc0026900, 0x000000b6, 0x00000000, 0x3f800000, + 0xc0016900, 0x00000098, 0x80000000, + 0xc0016900, 0x00000099, 0x20002000, + 0xc0026900, 0x000000b8, 0x00000000, 0x3f800000, + 0xc0016900, 0x0000009a, 0x80000000, + 0xc0016900, 0x0000009b, 0x20002000, + 0xc0026900, 0x000000ba, 0x00000000, 0x3f800000, + 0xc0016900, 0x0000009c, 0x80000000, + 0xc0016900, 0x0000009d, 0x20002000, + 0xc0026900, 0x000000bc, 0x00000000, 0x3f800000, + 0xc0016900, 0x0000009e, 0x80000000, + 0xc0016900, 0x0000009f, 0x20002000, + 0xc0026900, 0x000000be, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a0, 0x80000000, + 0xc0016900, 0x000000a1, 0x20002000, + 0xc0026900, 0x000000c0, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a2, 0x80000000, + 0xc0016900, 0x000000a3, 0x20002000, + 0xc0026900, 0x000000c2, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a4, 0x80000000, + 0xc0016900, 0x000000a5, 0x20002000, + 0xc0026900, 0x000000c4, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a6, 0x80000000, + 0xc0016900, 0x000000a7, 0x20002000, + 0xc0026900, 0x000000c6, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000a8, 0x80000000, + 0xc0016900, 0x000000a9, 0x20002000, + 0xc0026900, 0x000000c8, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000aa, 0x80000000, + 0xc0016900, 0x000000ab, 0x20002000, + 0xc0026900, 0x000000ca, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000ac, 0x80000000, + 0xc0016900, 0x000000ad, 0x20002000, + 0xc0026900, 0x000000cc, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000ae, 0x80000000, + 0xc0016900, 0x000000af, 0x20002000, + 0xc0026900, 0x000000ce, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000b0, 0x80000000, + 0xc0016900, 0x000000b1, 0x20002000, + 0xc0026900, 0x000000d0, 0x00000000, 0x3f800000, + 0xc0016900, 0x000000b2, 0x80000000, + 0xc0016900, 0x000000b3, 0x20002000, + 0xc0026900, 0x000000d2, 0x00000000, 0x3f800000, + 0xc0016900, 0x00000293, - 0x00514000, + 0x00514000, /* PA_SC_MODE_CNTL */ + 0xc0016900, 0x00000300, - 0x00000000, + 0x00000000, /* PA_SC_LINE_CNTL */ + 0xc0016900, 0x00000301, - 0x00000000, + 0x00000000, /* PA_SC_AA_CONFIG */ + 0xc0016900, 0x00000312, - 0xffffffff, + 0xffffffff, /* PA_SC_AA_MASK */ + 0xc0016900, 0x00000307, - 0x00000000, + 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ + 0xc0016900, 0x00000308, 0x00000000, + 0xc0016900, 0x00000283, - 0x00000000, + 0x00000000, /* PA_SC_LINE_STIPPLE */ + 0xc0016900, 0x00000292, - 0x00000000, + 0x00000000, /* PA_SC_MPASS_PS_CNTL */ + 0xc0066900, 0x0000010f, + 0x00000000, /* PA_CL_VPORT_0_XSCALE */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, + 0xc0016900, 0x00000206, - 0x00000000, + 0x00000000, /* PA_CL_VTE_CNTL */ + 0xc0016900, 0x00000207, - 0x00000000, + 0x00000000, /* PA_CL_VS_OUT_CNTL */ + 0xc0016900, 0x00000208, - 0x00000000, + 0x00000000, /* PA_CL_NANINF_CNTL */ + 0xc0046900, 0x00000303, + 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ 0x3f800000, 0x3f800000, 0x3f800000, - 0x3f800000, + 0xc0016900, 0x00000205, - 0x00000004, + 0x00000004, /* PA_SU_SC_MODE_CNTL */ + 0xc0016900, 0x00000280, - 0x00000000, + 0x00000000, /* PA_SU_POINT_SIZE */ + 0xc0016900, 0x00000281, - 0x00000000, + 0x00000000, /* PA_SU_POINT_MINMAX */ + 0xc0016900, 0x0000037e, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ + 0xc0016900, 0x00000382, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ + 0xc0016900, 0x00000380, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ + 0xc0016900, 0x00000383, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ + 0xc0016900, 0x00000381, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ + 0xc0016900, 0x00000282, - 0x00000008, + 0x00000008, /* PA_SU_LINE_CNTL */ + 0xc0016900, 0x00000302, - 0x0000002d, + 0x0000002d, /* PA_SU_VTX_CNTL */ + 0xc0016900, 0x0000037f, - 0x00000000, + 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ + 0xc0016900, 0x000001b2, - 0x00000001, + 0x00000001, /* SPI_THREAD_GROUPING */ + 0xc0016900, 0x000001b6, - 0x00000000, + 0x00000000, /* SPI_INPUT_Z */ + 0xc0016900, 0x000001b7, - 0x00000000, + 0x00000000, /* SPI_FOG_CNTL */ + 0xc0016900, 0x000001b8, - 0x00000000, + 0x00000000, /* SPI_FOG_FUNC_SCALE */ + 0xc0016900, 0x000001b9, - 0x00000000, + 0x00000000, /* SPI_FOG_FUNC_BIAS */ + 0xc0016900, 0x00000225, - 0x00000000, + 0x00000000, /* SQ_PGM_START_FS */ + 0xc0016900, 0x00000229, - 0x00000000, + 0x00000000, /* SQ_PGM_RESOURCES_FS */ + 0xc0016900, 0x00000237, - 0x00000000, + 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ + 0xc0016900, 0x00000100, - 0x00000800, + 0x00000800, /* VGT_MAX_VTX_INDX */ + 0xc0016900, 0x00000101, - 0x00000000, + 0x00000000, /* VGT_MIN_VTX_INDX */ + 0xc0016900, 0x00000102, - 0x00000000, + 0x00000000, /* VGT_INDX_OFFSET */ + 0xc0016900, 0x000002a8, - 0x00000000, + 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ + 0xc0016900, 0x000002a9, - 0x00000000, + 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ + 0xc0016900, 0x00000103, - 0x00000000, + 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ + 0xc0016900, 0x00000284, - 0x00000000, + 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ + 0xc0016900, 0x00000290, - 0x00000000, + 0x00000000, /* VGT_GS_MODE */ + 0xc0016900, 0x00000285, - 0x00000000, + 0x00000000, /* VGT_HOS_CNTL */ + 0xc0016900, 0x00000286, - 0x00000000, + 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ + 0xc0016900, 0x00000287, - 0x00000000, + 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ + 0xc0016900, 0x00000288, - 0x00000000, + 0x00000000, /* VGT_HOS_REUSE_DEPTH */ + 0xc0016900, 0x00000289, - 0x00000000, + 0x00000000, /* VGT_GROUP_PRIM_TYPE */ + 0xc0016900, 0x0000028a, - 0x00000000, + 0x00000000, /* VGT_GROUP_FIRST_DECR */ + 0xc0016900, 0x0000028b, - 0x00000000, + 0x00000000, /* VGT_GROUP_DECR */ + 0xc0016900, 0x0000028c, - 0x00000000, + 0x00000000, /* VGT_GROUP_VECT_0_CNTL */ + 0xc0016900, 0x0000028d, - 0x00000000, + 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ + 0xc0016900, 0x0000028e, - 0x00000000, + 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ + 0xc0016900, 0x0000028f, - 0x00000000, + 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ + 0xc0016900, 0x000002a1, - 0x00000000, + 0x00000000, /* VGT_PRIMITIVEID_EN */ + 0xc0016900, 0x000002a5, - 0x00000000, + 0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */ + 0xc0016900, 0x000002ac, - 0x00000000, + 0x00000000, /* VGT_STRMOUT_EN */ + 0xc0016900, 0x000002ad, - 0x00000000, + 0x00000000, /* VGT_REUSE_OFF */ + 0xc0016900, 0x000002ae, - 0x00000000, + 0x00000000, /* VGT_VTX_CNT_EN */ + 0xc0016900, 0x000002c8, - 0x00000000, + 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ + 0xc0016900, 0x00000206, - 0x00000100, + 0x00000100, /* PA_CL_VTE_CNTL */ + 0xc0016900, 0x00000204, - 0x00010000, - 0xc0036e00, + 0x00010000, /* PA_CL_CLIP_CNTL */ + + 0xc0036e00, /* SET_SAMPLER */ 0x00000000, 0x00000012, 0x00000000, 0x00000000, + 0xc0016900, 0x0000008f, - 0x0000000f, + 0x0000000f, /* CB_SHADER_MASK */ + 0xc0016900, 0x000001e8, - 0x00000001, + 0x00000001, /* CB_SHADER_CONTROL */ + 0xc0016900, 0x00000202, - 0x00cc0000, + 0x00cc0000, /* CB_COLOR_CONTROL */ + 0xc0016900, 0x00000205, - 0x00000244, + 0x00000244, /* PA_SU_SC_MODE_CNTL */ + 0xc0016900, 0x00000203, - 0x00000210, + 0x00000210, /* DB_SHADER_CNTL */ + 0xc0016900, 0x000001b1, - 0x00000000, + 0x00000000, /* SPI_VS_OUT_CONFIG */ + 0xc0016900, 0x00000185, - 0x00000000, + 0x00000000, /* SPI_VS_OUT_ID_0 */ + 0xc0016900, 0x000001b3, - 0x00000001, + 0x00000001, /* SPI_PS_IN_CONTROL_0 */ + 0xc0016900, 0x000001b4, - 0x00000000, + 0x00000000, /* SPI_PS_IN_CONTROL_1 */ + 0xc0016900, 0x00000191, - 0x00000b00, + 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ + 0xc0016900, 0x000001b5, - 0x00000000, + 0x00000000, /* SPI_INTERP_CONTROL_0 */ }; /* same for r6xx/r7xx */ -- cgit v0.10.2 From 7fc8878c3398a71c39e23ae1d9d56ba1f9e8c97d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 27 Jul 2010 11:11:19 -0400 Subject: drm/radeon: remove duplicate state emit in r6xx/r7xx blit Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index a8f8bbc..3bcbb93 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -459,10 +459,6 @@ const u32 r6xx_default_state[] = 0x00000000, 0xc0016900, - 0x00000206, /* PA_CL_VTE_CNTL */ - 0x00000000, - - 0xc0016900, 0x00000207, 0x00000000, /* PA_CL_VS_OUT_CNTL */ @@ -478,10 +474,6 @@ const u32 r6xx_default_state[] = 0x3f800000, 0xc0016900, - 0x00000205, - 0x00000004, /* PA_SU_SC_MODE_CNTL */ - - 0xc0016900, 0x00000280, 0x00000000, /* PA_SU_POINT_SIZE */ @@ -1118,10 +1110,6 @@ const u32 r7xx_default_state[] = 0x00000000, 0xc0016900, - 0x00000206, - 0x00000000, /* PA_CL_VTE_CNTL */ - - 0xc0016900, 0x00000207, 0x00000000, /* PA_CL_VS_OUT_CNTL */ @@ -1137,10 +1125,6 @@ const u32 r7xx_default_state[] = 0x3f800000, 0xc0016900, - 0x00000205, - 0x00000004, /* PA_SU_SC_MODE_CNTL */ - - 0xc0016900, 0x00000280, 0x00000000, /* PA_SU_POINT_SIZE */ -- cgit v0.10.2 From eb544433c368ad95615af168bfb2fedfc5e9ddb1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 27 Jul 2010 18:57:06 -0400 Subject: drm/radeon: group r6xx/r7xx sequential blit state group state that is emitted sequentially into fewer packets. This saves a number of dwords. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 3bcbb93..3a775c1 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -70,12 +70,9 @@ const u32 r6xx_default_state[] = 0x0000060e, 0x01020204, /* DB_WATERMARKS */ - 0xc0016f00, + 0xc0026f00, 0x00000000, 0x00000000, /* SQ_VTX_BASE_VTX_LOC */ - - 0xc0016f00, - 0x00000001, 0x00000000, /* SQ_VTX_START_INST_LOC */ 0xc0096900, @@ -94,32 +91,23 @@ const u32 r6xx_default_state[] = 0x00000004, 0x00000000, /* DB_DEPTH_INFO */ - 0xc0016900, + 0xc0026900, 0x0000000a, 0x00000000, /* DB_STENCIL_CLEAR */ - - 0xc0016900, - 0x0000000b, 0x00000000, /* DB_DEPTH_CLEAR */ - 0xc0016900, + 0xc0026900, 0x0000010c, 0x00000000, /* DB_STENCILREFMASK */ - - 0xc0016900, - 0x0000010d, 0x00000000, /* DB_STENCILREFMASK_BF */ 0xc0016900, 0x00000200, 0x00000000, /* DB_DEPTH_CONTROL */ - 0xc0016900, + 0xc0026900, 0x00000343, 0x00000060, /* DB_RENDER_CONTROL */ - - 0xc0016900, - 0x00000344, 0x00000040, /* DB_RENDER_OVERRIDE */ 0xc0016900, @@ -134,15 +122,12 @@ const u32 r6xx_default_state[] = 0x0000010e, 0x00000000, /* SX_ALPHA_REF */ - 0xc0046900, + 0xc0076900, 0x00000105, 0x00000000, /* CB_BLEND_RED */ 0x00000000, 0x00000000, 0x00000000, - - 0xc0036900, - 0x00000109, 0x00000000, /* CB_FOG_RED */ 0x00000000, 0x00000000, @@ -169,52 +154,22 @@ const u32 r6xx_default_state[] = 0x00000080, 0x00000000, /* PA_SC_WINDOW_OFFSET */ - 0xc0016900, + 0xc00a6900, 0x00000083, 0x0000ffff, /* PA_SC_CLIP_RECT_RULE */ - - 0xc0016900, - 0x00000084, - 0x00000000, /* PA_SC_WINDOW_SCISSOR_TL */ - - 0xc0016900, - 0x00000085, + 0x00000000, /* PA_SC_CLIPRECT_0_TL */ 0x20002000, - - 0xc0016900, - 0x00000086, 0x00000000, - - 0xc0016900, - 0x00000087, 0x20002000, - - 0xc0016900, - 0x00000088, 0x00000000, - - 0xc0016900, - 0x00000089, 0x20002000, - - 0xc0016900, - 0x0000008a, 0x00000000, - - 0xc0016900, - 0x0000008b, 0x20002000, - - 0xc0016900, - 0x0000008c, 0x00000000, /* PA_SC_EDGERULE */ - 0xc0016900, + 0xc0026900, 0x00000094, 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ - - 0xc0016900, - 0x00000095, 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ 0xc0026900, @@ -222,12 +177,9 @@ const u32 r6xx_default_state[] = 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ 0x3f800000, - 0xc0016900, + 0xc0026900, 0x00000096, 0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */ - - 0xc0016900, - 0x00000097, 0x20002000, 0xc0026900, @@ -235,12 +187,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x00000098, 0x80000000, - - 0xc0016900, - 0x00000099, 0x20002000, 0xc0026900, @@ -248,12 +197,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x0000009a, 0x80000000, - - 0xc0016900, - 0x0000009b, 0x20002000, 0xc0026900, @@ -261,12 +207,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x0000009c, 0x80000000, - - 0xc0016900, - 0x0000009d, 0x20002000, 0xc0026900, @@ -274,12 +217,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x0000009e, 0x80000000, - - 0xc0016900, - 0x0000009f, 0x20002000, 0xc0026900, @@ -287,12 +227,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a0, 0x80000000, - - 0xc0016900, - 0x000000a1, 0x20002000, 0xc0026900, @@ -300,12 +237,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a2, 0x80000000, - - 0xc0016900, - 0x000000a3, 0x20002000, 0xc0026900, @@ -313,12 +247,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a4, 0x80000000, - - 0xc0016900, - 0x000000a5, 0x20002000, 0xc0026900, @@ -326,12 +257,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a6, 0x80000000, - - 0xc0016900, - 0x000000a7, 0x20002000, 0xc0026900, @@ -339,12 +267,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a8, 0x80000000, - - 0xc0016900, - 0x000000a9, 0x20002000, 0xc0026900, @@ -352,12 +277,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000aa, 0x80000000, - - 0xc0016900, - 0x000000ab, 0x20002000, 0xc0026900, @@ -365,12 +287,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000ac, 0x80000000, - - 0xc0016900, - 0x000000ad, 0x20002000, 0xc0026900, @@ -378,12 +297,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000ae, 0x80000000, - - 0xc0016900, - 0x000000af, 0x20002000, 0xc0026900, @@ -391,12 +307,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000b0, 0x80000000, - - 0xc0016900, - 0x000000b1, 0x20002000, 0xc0026900, @@ -404,12 +317,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000b2, 0x80000000, - - 0xc0016900, - 0x000000b3, 0x20002000, 0xc0026900, @@ -421,24 +331,18 @@ const u32 r6xx_default_state[] = 0x00000293, 0x00004010, /* PA_SC_MODE_CNTL */ - 0xc0016900, + 0xc0026900, 0x00000300, 0x00000000, /* PA_SC_LINE_CNTL */ - - 0xc0016900, - 0x00000301, 0x00000000, /* PA_SC_AA_CONFIG */ 0xc0016900, 0x00000312, 0xffffffff, /* PA_SC_AA_MASK */ - 0xc0016900, + 0xc0026900, 0x00000307, 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ - - 0xc0016900, - 0x00000308, 0x00000000, 0xc0016900, @@ -458,12 +362,9 @@ const u32 r6xx_default_state[] = 0x00000000, 0x00000000, - 0xc0016900, + 0xc0026900, 0x00000207, 0x00000000, /* PA_CL_VS_OUT_CNTL */ - - 0xc0016900, - 0x00000208, 0x00000000, /* PA_CL_NANINF_CNTL */ 0xc0046900, @@ -473,12 +374,9 @@ const u32 r6xx_default_state[] = 0x3f800000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x00000280, 0x00000000, /* PA_SU_POINT_SIZE */ - - 0xc0016900, - 0x00000281, 0x00000000, /* PA_SU_POINT_MINMAX */ 0xc0016900, @@ -517,20 +415,11 @@ const u32 r6xx_default_state[] = 0x000001b2, 0x00000000, /* SPI_THREAD_GROUPING */ - 0xc0016900, + 0xc0046900, 0x000001b6, 0x00000000, /* SPI_INPUT_Z */ - - 0xc0016900, - 0x000001b7, 0x00000000, /* SPI_FOG_CNTL */ - - 0xc0016900, - 0x000001b8, 0x00000000, /* SPI_FOG_FUNC_SCALE */ - - 0xc0016900, - 0x000001b9, 0x00000000, /* SPI_FOG_FUNC_BIAS */ 0xc0016900, @@ -545,24 +434,15 @@ const u32 r6xx_default_state[] = 0x00000237, 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ - 0xc0016900, + 0xc0036900, 0x00000100, 0x00000800, /* VGT_MAX_VTX_INDX */ - - 0xc0016900, - 0x00000101, 0x00000000, /* VGT_MIN_VTX_INDX */ - - 0xc0016900, - 0x00000102, 0x00000000, /* VGT_INDX_OFFSET */ - 0xc0016900, + 0xc0026900, 0x000002a8, 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ - - 0xc0016900, - 0x000002a9, 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ 0xc0016900, @@ -581,44 +461,17 @@ const u32 r6xx_default_state[] = 0x00000285, 0x00000000, /* VGT_HOS_CNTL */ - 0xc0016900, + 0xc00a6900, 0x00000286, 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ - - 0xc0016900, - 0x00000287, 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ - - 0xc0016900, - 0x00000288, 0x00000000, /* VGT_HOS_REUSE_DEPTH */ - - 0xc0016900, - 0x00000289, 0x00000000, /* VGT_GROUP_PRIM_TYPE */ - - 0xc0016900, - 0x0000028a, 0x00000000, /* VGT_GROUP_FIRST_DECR */ - - 0xc0016900, - 0x0000028b, 0x00000000, /* VGT_GROUP_DECR */ - - 0xc0016900, - 0x0000028c, 0x00000000, /* VGT_GROUP_VECT_0_CNTL */ - - 0xc0016900, - 0x0000028d, 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ - - 0xc0016900, - 0x0000028e, 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ - - 0xc0016900, - 0x0000028f, 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ 0xc0016900, @@ -629,16 +482,10 @@ const u32 r6xx_default_state[] = 0x000002a5, 0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */ - 0xc0016900, + 0xc0036900, 0x000002ac, 0x00000000, /* VGT_STRMOUT_EN */ - - 0xc0016900, - 0x000002ad, 0x00000000, /* VGT_REUSE_OFF */ - - 0xc0016900, - 0x000002ae, 0x00000000, /* VGT_VTX_CNT_EN */ 0xc0016900, @@ -687,12 +534,9 @@ const u32 r6xx_default_state[] = 0x00000185, 0x00000000, /* SPI_VS_OUT_ID_0 */ - 0xc0016900, + 0xc0026900, 0x000001b3, 0x00000001, /* SPI_PS_IN_CONTROL_0 */ - - 0xc0016900, - 0x000001b4, 0x00000000, /* SPI_PS_IN_CONTROL_1 */ 0xc0016900, @@ -734,12 +578,9 @@ const u32 r7xx_default_state[] = 0x0000060e, 0x00420204, /* DB_WATERMARKS */ - 0xc0016f00, + 0xc0026f00, 0x00000000, 0x00000000, /* SQ_VTX_BASE_VTX_LOC */ - - 0xc0016f00, - 0x00000001, 0x00000000, /* SQ_VTX_START_INST_LOC */ 0xc0096900, @@ -758,32 +599,23 @@ const u32 r7xx_default_state[] = 0x00000004, 0x00000000, /* DB_DEPTH_INFO */ - 0xc0016900, + 0xc0026900, 0x0000000a, 0x00000000, /* DB_STENCIL_CLEAR */ - - 0xc0016900, - 0x0000000b, 0x00000000, /* DB_DEPTH_CLEAR */ - 0xc0016900, + 0xc0026900, 0x0000010c, 0x00000000, /* DB_STENCILREFMASK */ - - 0xc0016900, - 0x0000010d, 0x00000000, /* DB_STENCILREFMASK_BF */ 0xc0016900, 0x00000200, 0x00000000, /* DB_DEPTH_CONTROL */ - 0xc0016900, + 0xc0026900, 0x00000343, 0x00000060, /* DB_RENDER_CONTROL */ - - 0xc0016900, - 0x00000344, 0x00000000, /* DB_RENDER_OVERRIDE */ 0xc0016900, @@ -820,52 +652,22 @@ const u32 r7xx_default_state[] = 0x00000080, 0x00000000, /* PA_SC_WINDOW_OFFSET */ - 0xc0016900, + 0xc00a6900, 0x00000083, 0x0000ffff, /* PA_SC_CLIP_RECT_RULE */ - - 0xc0016900, - 0x00000084, - 0x00000000, /* PA_SC_WINDOW_SCISSOR_TL */ - - 0xc0016900, - 0x00000085, + 0x00000000, /* PA_SC_CLIPRECT_0_TL */ 0x20002000, - - 0xc0016900, - 0x00000086, 0x00000000, - - 0xc0016900, - 0x00000087, 0x20002000, - - 0xc0016900, - 0x00000088, 0x00000000, - - 0xc0016900, - 0x00000089, 0x20002000, - - 0xc0016900, - 0x0000008a, 0x00000000, - - 0xc0016900, - 0x0000008b, 0x20002000, - - 0xc0016900, - 0x0000008c, 0xaaaaaaaa, /* PA_SC_EDGERULE */ - 0xc0016900, + 0xc0026900, 0x00000094, 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ - - 0xc0016900, - 0x00000095, 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ 0xc0026900, @@ -873,12 +675,9 @@ const u32 r7xx_default_state[] = 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ 0x3f800000, - 0xc0016900, + 0xc0026900, 0x00000096, 0x80000000, - - 0xc0016900, - 0x00000097, 0x20002000, 0xc0026900, @@ -886,12 +685,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x00000098, 0x80000000, - - 0xc0016900, - 0x00000099, 0x20002000, 0xc0026900, @@ -902,9 +698,6 @@ const u32 r7xx_default_state[] = 0xc0016900, 0x0000009a, 0x80000000, - - 0xc0016900, - 0x0000009b, 0x20002000, 0xc0026900, @@ -912,12 +705,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x0000009c, 0x80000000, - - 0xc0016900, - 0x0000009d, 0x20002000, 0xc0026900, @@ -925,12 +715,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x0000009e, 0x80000000, - - 0xc0016900, - 0x0000009f, 0x20002000, 0xc0026900, @@ -938,12 +725,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a0, 0x80000000, - - 0xc0016900, - 0x000000a1, 0x20002000, 0xc0026900, @@ -951,12 +735,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a2, 0x80000000, - - 0xc0016900, - 0x000000a3, 0x20002000, 0xc0026900, @@ -964,12 +745,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a4, 0x80000000, - - 0xc0016900, - 0x000000a5, 0x20002000, 0xc0026900, @@ -977,12 +755,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a6, 0x80000000, - - 0xc0016900, - 0x000000a7, 0x20002000, 0xc0026900, @@ -990,12 +765,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000a8, 0x80000000, - - 0xc0016900, - 0x000000a9, 0x20002000, 0xc0026900, @@ -1003,12 +775,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000aa, 0x80000000, - - 0xc0016900, - 0x000000ab, 0x20002000, 0xc0026900, @@ -1016,12 +785,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000ac, 0x80000000, - - 0xc0016900, - 0x000000ad, 0x20002000, 0xc0026900, @@ -1029,12 +795,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000ae, 0x80000000, - - 0xc0016900, - 0x000000af, 0x20002000, 0xc0026900, @@ -1042,12 +805,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000b0, 0x80000000, - - 0xc0016900, - 0x000000b1, 0x20002000, 0xc0026900, @@ -1055,12 +815,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x000000b2, 0x80000000, - - 0xc0016900, - 0x000000b3, 0x20002000, 0xc0026900, @@ -1072,24 +829,18 @@ const u32 r7xx_default_state[] = 0x00000293, 0x00514000, /* PA_SC_MODE_CNTL */ - 0xc0016900, + 0xc0026900, 0x00000300, 0x00000000, /* PA_SC_LINE_CNTL */ - - 0xc0016900, - 0x00000301, 0x00000000, /* PA_SC_AA_CONFIG */ 0xc0016900, 0x00000312, 0xffffffff, /* PA_SC_AA_MASK */ - 0xc0016900, + 0xc0026900, 0x00000307, 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ - - 0xc0016900, - 0x00000308, 0x00000000, 0xc0016900, @@ -1109,12 +860,9 @@ const u32 r7xx_default_state[] = 0x00000000, 0x00000000, - 0xc0016900, + 0xc0026900, 0x00000207, 0x00000000, /* PA_CL_VS_OUT_CNTL */ - - 0xc0016900, - 0x00000208, 0x00000000, /* PA_CL_NANINF_CNTL */ 0xc0046900, @@ -1124,12 +872,9 @@ const u32 r7xx_default_state[] = 0x3f800000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x00000280, 0x00000000, /* PA_SU_POINT_SIZE */ - - 0xc0016900, - 0x00000281, 0x00000000, /* PA_SU_POINT_MINMAX */ 0xc0016900, @@ -1168,20 +913,11 @@ const u32 r7xx_default_state[] = 0x000001b2, 0x00000001, /* SPI_THREAD_GROUPING */ - 0xc0016900, + 0xc0046900, 0x000001b6, 0x00000000, /* SPI_INPUT_Z */ - - 0xc0016900, - 0x000001b7, 0x00000000, /* SPI_FOG_CNTL */ - - 0xc0016900, - 0x000001b8, 0x00000000, /* SPI_FOG_FUNC_SCALE */ - - 0xc0016900, - 0x000001b9, 0x00000000, /* SPI_FOG_FUNC_BIAS */ 0xc0016900, @@ -1196,24 +932,15 @@ const u32 r7xx_default_state[] = 0x00000237, 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ - 0xc0016900, + 0xc0036900, 0x00000100, 0x00000800, /* VGT_MAX_VTX_INDX */ - - 0xc0016900, - 0x00000101, 0x00000000, /* VGT_MIN_VTX_INDX */ - - 0xc0016900, - 0x00000102, 0x00000000, /* VGT_INDX_OFFSET */ - 0xc0016900, + 0xc0026900, 0x000002a8, 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ - - 0xc0016900, - 0x000002a9, 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ 0xc0016900, @@ -1228,48 +955,18 @@ const u32 r7xx_default_state[] = 0x00000290, 0x00000000, /* VGT_GS_MODE */ - 0xc0016900, + 0xc00b6900, 0x00000285, 0x00000000, /* VGT_HOS_CNTL */ - - 0xc0016900, - 0x00000286, 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ - - 0xc0016900, - 0x00000287, 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ - - 0xc0016900, - 0x00000288, 0x00000000, /* VGT_HOS_REUSE_DEPTH */ - - 0xc0016900, - 0x00000289, 0x00000000, /* VGT_GROUP_PRIM_TYPE */ - - 0xc0016900, - 0x0000028a, 0x00000000, /* VGT_GROUP_FIRST_DECR */ - - 0xc0016900, - 0x0000028b, 0x00000000, /* VGT_GROUP_DECR */ - - 0xc0016900, - 0x0000028c, 0x00000000, /* VGT_GROUP_VECT_0_CNTL */ - - 0xc0016900, - 0x0000028d, 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ - - 0xc0016900, - 0x0000028e, 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ - - 0xc0016900, - 0x0000028f, 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ 0xc0016900, @@ -1280,16 +977,10 @@ const u32 r7xx_default_state[] = 0x000002a5, 0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */ - 0xc0016900, + 0xc0036900, 0x000002ac, 0x00000000, /* VGT_STRMOUT_EN */ - - 0xc0016900, - 0x000002ad, 0x00000000, /* VGT_REUSE_OFF */ - - 0xc0016900, - 0x000002ae, 0x00000000, /* VGT_VTX_CNT_EN */ 0xc0016900, @@ -1338,12 +1029,9 @@ const u32 r7xx_default_state[] = 0x00000185, 0x00000000, /* SPI_VS_OUT_ID_0 */ - 0xc0016900, + 0xc0026900, 0x000001b3, 0x00000001, /* SPI_PS_IN_CONTROL_0 */ - - 0xc0016900, - 0x000001b4, 0x00000000, /* SPI_PS_IN_CONTROL_1 */ 0xc0016900, -- cgit v0.10.2 From 363c6a16e30464fddcb8f82b7e8f44109729cc95 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 26 Jul 2010 13:47:54 -0400 Subject: drm/radeon: r6xx/r7xx move vport clipping to a single packet Saves lots of dwords in blit emit Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 3a775c1..9a0553c 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -167,163 +167,70 @@ const u32 r6xx_default_state[] = 0x20002000, 0x00000000, /* PA_SC_EDGERULE */ - 0xc0026900, + 0xc0406900, 0x00000094, 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ - - 0xc0026900, - 0x000000b4, - 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ - 0x3f800000, - - 0xc0026900, - 0x00000096, 0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */ 0x20002000, - - 0xc0026900, - 0x000000b6, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x00000098, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000b8, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x0000009a, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000ba, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x0000009c, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000bc, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x0000009e, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000be, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a0, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c0, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a2, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c2, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a4, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c4, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a6, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c6, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a8, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c8, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000aa, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000ca, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000ac, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000cc, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000ae, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000ce, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000b0, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000d0, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000b2, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000d2, + 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, 0x00000000, 0x3f800000, @@ -665,163 +572,70 @@ const u32 r7xx_default_state[] = 0x20002000, 0xaaaaaaaa, /* PA_SC_EDGERULE */ - 0xc0026900, + 0xc0406900, 0x00000094, 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ - - 0xc0026900, - 0x000000b4, - 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ - 0x3f800000, - - 0xc0026900, - 0x00000096, + 0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */ + 0x20002000, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000b6, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x00000098, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000b8, - 0x00000000, - 0x3f800000, - - 0xc0016900, - 0x0000009a, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000ba, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x0000009c, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000bc, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x0000009e, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000be, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a0, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c0, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a2, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c2, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a4, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c4, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a6, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c6, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000a8, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000c8, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000aa, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000ca, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000ac, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000cc, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000ae, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000ce, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x000000b0, 0x80000000, 0x20002000, - - 0xc0026900, - 0x000000d0, + 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x00000000, + 0x3f800000, 0x00000000, 0x3f800000, - - 0xc0026900, - 0x000000b2, - 0x80000000, - 0x20002000, - - 0xc0026900, - 0x000000d2, 0x00000000, 0x3f800000, -- cgit v0.10.2 From d0623a3e74610aff0b984d68bbc027a7e511e686 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 27 Jul 2010 11:17:44 -0400 Subject: drm/radeon: reorder r6xx/r7xx blit state emit to make more regs sequential Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 9a0553c..9a0c947 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -96,11 +96,6 @@ const u32 r6xx_default_state[] = 0x00000000, /* DB_STENCIL_CLEAR */ 0x00000000, /* DB_DEPTH_CLEAR */ - 0xc0026900, - 0x0000010c, - 0x00000000, /* DB_STENCILREFMASK */ - 0x00000000, /* DB_STENCILREFMASK_BF */ - 0xc0016900, 0x00000200, 0x00000000, /* DB_DEPTH_CONTROL */ @@ -114,13 +109,19 @@ const u32 r6xx_default_state[] = 0x00000351, 0x0000aa00, /* DB_ALPHA_TO_MASK */ + 0xc0036900, + 0x00000100, + 0x00000800, /* VGT_MAX_VTX_INDX */ + 0x00000000, /* VGT_MIN_VTX_INDX */ + 0x00000000, /* VGT_INDX_OFFSET */ + 0xc0016900, - 0x00000104, - 0x00000000, /* SX_ALPHA_TEST_CONTROL */ + 0x00000103, + 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ 0xc0016900, - 0x0000010e, - 0x00000000, /* SX_ALPHA_REF */ + 0x00000104, + 0x00000000, /* SX_ALPHA_TEST_CONTROL */ 0xc0076900, 0x00000105, @@ -132,6 +133,15 @@ const u32 r6xx_default_state[] = 0x00000000, 0x00000000, + 0xc0026900, + 0x0000010c, + 0x00000000, /* DB_STENCILREFMASK */ + 0x00000000, /* DB_STENCILREFMASK_BF */ + + 0xc0016900, + 0x0000010e, + 0x00000000, /* SX_ALPHA_REF */ + 0xc0046900, 0x0000030c, 0x01000000, /* CB_CLRCMP_CNTL */ @@ -147,10 +157,6 @@ const u32 r6xx_default_state[] = 0x3f800000, 0xc0016900, - 0x0000008e, - 0x0000000f, /* CB_TARGET_MASK */ - - 0xc0016900, 0x00000080, 0x00000000, /* PA_SC_WINDOW_OFFSET */ @@ -235,31 +241,13 @@ const u32 r6xx_default_state[] = 0x3f800000, 0xc0016900, - 0x00000293, - 0x00004010, /* PA_SC_MODE_CNTL */ - - 0xc0026900, - 0x00000300, - 0x00000000, /* PA_SC_LINE_CNTL */ - 0x00000000, /* PA_SC_AA_CONFIG */ - - 0xc0016900, - 0x00000312, - 0xffffffff, /* PA_SC_AA_MASK */ - - 0xc0026900, - 0x00000307, - 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ - 0x00000000, - - 0xc0016900, - 0x00000283, - 0x00000000, /* PA_SC_LINE_STIPPLE */ - - 0xc0016900, 0x00000292, 0x00000000, /* PA_SC_MPASS_PS_CNTL */ + 0xc0016900, + 0x00000293, + 0x00004010, /* PA_SC_MODE_CNTL */ + 0xc0066900, 0x0000010f, 0x00000000, /* PA_CL_VPORT_0_XSCALE */ @@ -270,9 +258,13 @@ const u32 r6xx_default_state[] = 0x00000000, 0xc0026900, - 0x00000207, - 0x00000000, /* PA_CL_VS_OUT_CNTL */ - 0x00000000, /* PA_CL_NANINF_CNTL */ + 0x00000300, + 0x00000000, /* PA_SC_LINE_CNTL */ + 0x00000000, /* PA_SC_AA_CONFIG */ + + 0xc0016900, + 0x00000302, + 0x0000002d, /* PA_SU_VTX_CNTL */ 0xc0046900, 0x00000303, @@ -282,45 +274,37 @@ const u32 r6xx_default_state[] = 0x3f800000, 0xc0026900, - 0x00000280, - 0x00000000, /* PA_SU_POINT_SIZE */ - 0x00000000, /* PA_SU_POINT_MINMAX */ + 0x00000307, + 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ + 0x00000000, + + 0xc0016900, + 0x00000312, + 0xffffffff, /* PA_SC_AA_MASK */ 0xc0016900, 0x0000037e, 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ 0xc0016900, - 0x00000382, - 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ + 0x0000037f, + 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ 0xc0016900, 0x00000380, 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ 0xc0016900, - 0x00000383, - 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ - - 0xc0016900, 0x00000381, 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ 0xc0016900, - 0x00000282, - 0x00000008, /* PA_SU_LINE_CNTL */ - - 0xc0016900, - 0x00000302, - 0x0000002d, /* PA_SU_VTX_CNTL */ - - 0xc0016900, - 0x0000037f, - 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ + 0x00000382, + 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ 0xc0016900, - 0x000001b2, - 0x00000000, /* SPI_THREAD_GROUPING */ + 0x00000383, + 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ 0xc0046900, 0x000001b6, @@ -341,28 +325,27 @@ const u32 r6xx_default_state[] = 0x00000237, 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ - 0xc0036900, - 0x00000100, - 0x00000800, /* VGT_MAX_VTX_INDX */ - 0x00000000, /* VGT_MIN_VTX_INDX */ - 0x00000000, /* VGT_INDX_OFFSET */ - 0xc0026900, 0x000002a8, 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ + 0xc0026900, + 0x00000280, + 0x00000000, /* PA_SU_POINT_SIZE */ + 0x00000000, /* PA_SU_POINT_MINMAX */ + 0xc0016900, - 0x00000103, - 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ + 0x00000282, + 0x00000008, /* PA_SU_LINE_CNTL */ 0xc0016900, - 0x00000284, - 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ + 0x00000283, + 0x00000000, /* PA_SC_LINE_STIPPLE */ 0xc0016900, - 0x00000290, - 0x00000000, /* VGT_GS_MODE */ + 0x00000284, + 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ 0xc0016900, 0x00000285, @@ -382,6 +365,10 @@ const u32 r6xx_default_state[] = 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ 0xc0016900, + 0x00000290, + 0x00000000, /* VGT_GS_MODE */ + + 0xc0016900, 0x000002a1, 0x00000000, /* VGT_PRIMITIVEID_EN */ @@ -400,18 +387,33 @@ const u32 r6xx_default_state[] = 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ 0xc0016900, - 0x00000206, - 0x00000100, /* PA_CL_VTE_CNTL */ + 0x00000202, + 0x00cc0000, /* CB_COLOR_CONTROL */ + + 0xc0016900, + 0x00000203, + 0x00000210, /* DB_SHADER_CNTL */ 0xc0016900, 0x00000204, 0x00010000, /* PA_CL_CLIP_CNTL */ - 0xc0036e00, /* SET_SAMPLER */ - 0x00000000, - 0x00000012, - 0x00000000, - 0x00000000, + 0xc0016900, + 0x00000205, + 0x00000244, /* PA_SU_SC_MODE_CNTL */ + + 0xc0016900, + 0x00000206, + 0x00000100, /* PA_CL_VTE_CNTL */ + + 0xc0026900, + 0x00000207, + 0x00000000, /* PA_CL_VS_OUT_CNTL */ + 0x00000000, /* PA_CL_NANINF_CNTL */ + + 0xc0016900, + 0x0000008e, + 0x0000000f, /* CB_TARGET_MASK */ 0xc0016900, 0x0000008f, @@ -422,24 +424,20 @@ const u32 r6xx_default_state[] = 0x00000001, /* CB_SHADER_CONTROL */ 0xc0016900, - 0x00000202, - 0x00cc0000, /* CB_COLOR_CONTROL */ - - 0xc0016900, - 0x00000205, - 0x00000244, /* PA_SU_SC_MODE_CNTL */ + 0x00000185, + 0x00000000, /* SPI_VS_OUT_ID_0 */ 0xc0016900, - 0x00000203, - 0x00000210, /* DB_SHADER_CNTL */ + 0x00000191, + 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ 0xc0016900, 0x000001b1, 0x00000000, /* SPI_VS_OUT_CONFIG */ 0xc0016900, - 0x00000185, - 0x00000000, /* SPI_VS_OUT_ID_0 */ + 0x000001b2, + 0x00000000, /* SPI_THREAD_GROUPING */ 0xc0026900, 0x000001b3, @@ -447,12 +445,14 @@ const u32 r6xx_default_state[] = 0x00000000, /* SPI_PS_IN_CONTROL_1 */ 0xc0016900, - 0x00000191, - 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ - - 0xc0016900, 0x000001b5, 0x00000000, /* SPI_INTERP_CONTROL_0 */ + + 0xc0036e00, /* SET_SAMPLER */ + 0x00000000, + 0x00000012, + 0x00000000, + 0x00000000, }; const u32 r7xx_default_state[] = @@ -511,11 +511,6 @@ const u32 r7xx_default_state[] = 0x00000000, /* DB_STENCIL_CLEAR */ 0x00000000, /* DB_DEPTH_CLEAR */ - 0xc0026900, - 0x0000010c, - 0x00000000, /* DB_STENCILREFMASK */ - 0x00000000, /* DB_STENCILREFMASK_BF */ - 0xc0016900, 0x00000200, 0x00000000, /* DB_DEPTH_CONTROL */ @@ -529,13 +524,19 @@ const u32 r7xx_default_state[] = 0x00000351, 0x0000aa00, /* DB_ALPHA_TO_MASK */ + 0xc0036900, + 0x00000100, + 0x00000800, /* VGT_MAX_VTX_INDX */ + 0x00000000, /* VGT_MIN_VTX_INDX */ + 0x00000000, /* VGT_INDX_OFFSET */ + 0xc0016900, - 0x00000104, - 0x00000000, /* SX_ALPHA_TEST_CONTROL */ + 0x00000103, + 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ 0xc0016900, - 0x0000010e, - 0x00000000, /* SX_ALPHA_REF */ + 0x00000104, + 0x00000000, /* SX_ALPHA_TEST_CONTROL */ 0xc0046900, 0x00000105, @@ -544,6 +545,15 @@ const u32 r7xx_default_state[] = 0x00000000, 0x00000000, + 0xc0026900, + 0x0000010c, + 0x00000000, /* DB_STENCILREFMASK */ + 0x00000000, /* DB_STENCILREFMASK_BF */ + + 0xc0016900, + 0x0000010e, + 0x00000000, /* SX_ALPHA_REF */ + 0xc0046900, 0x0000030c, /* CB_CLRCMP_CNTL */ 0x01000000, @@ -552,10 +562,6 @@ const u32 r7xx_default_state[] = 0x00000000, 0xc0016900, - 0x0000008e, - 0x0000000f, /* CB_TARGET_MASK */ - - 0xc0016900, 0x00000080, 0x00000000, /* PA_SC_WINDOW_OFFSET */ @@ -640,31 +646,13 @@ const u32 r7xx_default_state[] = 0x3f800000, 0xc0016900, - 0x00000293, - 0x00514000, /* PA_SC_MODE_CNTL */ - - 0xc0026900, - 0x00000300, - 0x00000000, /* PA_SC_LINE_CNTL */ - 0x00000000, /* PA_SC_AA_CONFIG */ - - 0xc0016900, - 0x00000312, - 0xffffffff, /* PA_SC_AA_MASK */ - - 0xc0026900, - 0x00000307, - 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ - 0x00000000, - - 0xc0016900, - 0x00000283, - 0x00000000, /* PA_SC_LINE_STIPPLE */ - - 0xc0016900, 0x00000292, 0x00000000, /* PA_SC_MPASS_PS_CNTL */ + 0xc0016900, + 0x00000293, + 0x00514000, /* PA_SC_MODE_CNTL */ + 0xc0066900, 0x0000010f, 0x00000000, /* PA_CL_VPORT_0_XSCALE */ @@ -675,9 +663,13 @@ const u32 r7xx_default_state[] = 0x00000000, 0xc0026900, - 0x00000207, - 0x00000000, /* PA_CL_VS_OUT_CNTL */ - 0x00000000, /* PA_CL_NANINF_CNTL */ + 0x00000300, + 0x00000000, /* PA_SC_LINE_CNTL */ + 0x00000000, /* PA_SC_AA_CONFIG */ + + 0xc0016900, + 0x00000302, + 0x0000002d, /* PA_SU_VTX_CNTL */ 0xc0046900, 0x00000303, @@ -687,45 +679,37 @@ const u32 r7xx_default_state[] = 0x3f800000, 0xc0026900, - 0x00000280, - 0x00000000, /* PA_SU_POINT_SIZE */ - 0x00000000, /* PA_SU_POINT_MINMAX */ + 0x00000307, + 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ + 0x00000000, + + 0xc0016900, + 0x00000312, + 0xffffffff, /* PA_SC_AA_MASK */ 0xc0016900, 0x0000037e, 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ 0xc0016900, - 0x00000382, - 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ + 0x0000037f, + 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ 0xc0016900, 0x00000380, 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ 0xc0016900, - 0x00000383, - 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ - - 0xc0016900, 0x00000381, 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ 0xc0016900, - 0x00000282, - 0x00000008, /* PA_SU_LINE_CNTL */ - - 0xc0016900, - 0x00000302, - 0x0000002d, /* PA_SU_VTX_CNTL */ - - 0xc0016900, - 0x0000037f, - 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ + 0x00000382, + 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ 0xc0016900, - 0x000001b2, - 0x00000001, /* SPI_THREAD_GROUPING */ + 0x00000383, + 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ 0xc0046900, 0x000001b6, @@ -746,28 +730,27 @@ const u32 r7xx_default_state[] = 0x00000237, 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ - 0xc0036900, - 0x00000100, - 0x00000800, /* VGT_MAX_VTX_INDX */ - 0x00000000, /* VGT_MIN_VTX_INDX */ - 0x00000000, /* VGT_INDX_OFFSET */ - 0xc0026900, 0x000002a8, 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ + 0xc0026900, + 0x00000280, + 0x00000000, /* PA_SU_POINT_SIZE */ + 0x00000000, /* PA_SU_POINT_MINMAX */ + 0xc0016900, - 0x00000103, - 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ + 0x00000282, + 0x00000008, /* PA_SU_LINE_CNTL */ 0xc0016900, - 0x00000284, - 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ + 0x00000283, + 0x00000000, /* PA_SC_LINE_STIPPLE */ 0xc0016900, - 0x00000290, - 0x00000000, /* VGT_GS_MODE */ + 0x00000284, + 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ 0xc00b6900, 0x00000285, @@ -784,6 +767,10 @@ const u32 r7xx_default_state[] = 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ 0xc0016900, + 0x00000290, + 0x00000000, /* VGT_GS_MODE */ + + 0xc0016900, 0x000002a1, 0x00000000, /* VGT_PRIMITIVEID_EN */ @@ -802,18 +789,33 @@ const u32 r7xx_default_state[] = 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ 0xc0016900, - 0x00000206, - 0x00000100, /* PA_CL_VTE_CNTL */ + 0x00000202, + 0x00cc0000, /* CB_COLOR_CONTROL */ + + 0xc0016900, + 0x00000203, + 0x00000210, /* DB_SHADER_CNTL */ 0xc0016900, 0x00000204, 0x00010000, /* PA_CL_CLIP_CNTL */ - 0xc0036e00, /* SET_SAMPLER */ - 0x00000000, - 0x00000012, - 0x00000000, - 0x00000000, + 0xc0016900, + 0x00000205, + 0x00000244, /* PA_SU_SC_MODE_CNTL */ + + 0xc0016900, + 0x00000206, + 0x00000100, /* PA_CL_VTE_CNTL */ + + 0xc0026900, + 0x00000207, + 0x00000000, /* PA_CL_VS_OUT_CNTL */ + 0x00000000, /* PA_CL_NANINF_CNTL */ + + 0xc0016900, + 0x0000008e, + 0x0000000f, /* CB_TARGET_MASK */ 0xc0016900, 0x0000008f, @@ -824,24 +826,20 @@ const u32 r7xx_default_state[] = 0x00000001, /* CB_SHADER_CONTROL */ 0xc0016900, - 0x00000202, - 0x00cc0000, /* CB_COLOR_CONTROL */ - - 0xc0016900, - 0x00000205, - 0x00000244, /* PA_SU_SC_MODE_CNTL */ + 0x00000185, + 0x00000000, /* SPI_VS_OUT_ID_0 */ 0xc0016900, - 0x00000203, - 0x00000210, /* DB_SHADER_CNTL */ + 0x00000191, + 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ 0xc0016900, 0x000001b1, 0x00000000, /* SPI_VS_OUT_CONFIG */ 0xc0016900, - 0x00000185, - 0x00000000, /* SPI_VS_OUT_ID_0 */ + 0x000001b2, + 0x00000001, /* SPI_THREAD_GROUPING */ 0xc0026900, 0x000001b3, @@ -849,12 +847,14 @@ const u32 r7xx_default_state[] = 0x00000000, /* SPI_PS_IN_CONTROL_1 */ 0xc0016900, - 0x00000191, - 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ - - 0xc0016900, 0x000001b5, 0x00000000, /* SPI_INTERP_CONTROL_0 */ + + 0xc0036e00, /* SET_SAMPLER */ + 0x00000000, + 0x00000012, + 0x00000000, + 0x00000000, }; /* same for r6xx/r7xx */ -- cgit v0.10.2 From 43a7d2d104f26700c0cc070e5a317a51cd1b46c1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 27 Jul 2010 11:20:54 -0400 Subject: drm/radeon: group r6xx/r7xx newly sequential blit state group state that is emitted sequentially into fewer packets. This saves a number of dwords. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 9a0c947..762b81c 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -109,22 +109,13 @@ const u32 r6xx_default_state[] = 0x00000351, 0x0000aa00, /* DB_ALPHA_TO_MASK */ - 0xc0036900, + 0xc00f6900, 0x00000100, 0x00000800, /* VGT_MAX_VTX_INDX */ 0x00000000, /* VGT_MIN_VTX_INDX */ 0x00000000, /* VGT_INDX_OFFSET */ - - 0xc0016900, - 0x00000103, 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ - - 0xc0016900, - 0x00000104, 0x00000000, /* SX_ALPHA_TEST_CONTROL */ - - 0xc0076900, - 0x00000105, 0x00000000, /* CB_BLEND_RED */ 0x00000000, 0x00000000, @@ -132,16 +123,19 @@ const u32 r6xx_default_state[] = 0x00000000, /* CB_FOG_RED */ 0x00000000, 0x00000000, - - 0xc0026900, - 0x0000010c, 0x00000000, /* DB_STENCILREFMASK */ 0x00000000, /* DB_STENCILREFMASK_BF */ - - 0xc0016900, - 0x0000010e, 0x00000000, /* SX_ALPHA_REF */ + 0xc0066900, + 0x0000010f, + 0x00000000, /* PA_CL_VPORT_XSCALE */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0046900, 0x0000030c, 0x01000000, /* CB_CLRCMP_CNTL */ @@ -240,41 +234,20 @@ const u32 r6xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x00000292, 0x00000000, /* PA_SC_MPASS_PS_CNTL */ - - 0xc0016900, - 0x00000293, 0x00004010, /* PA_SC_MODE_CNTL */ - 0xc0066900, - 0x0000010f, - 0x00000000, /* PA_CL_VPORT_0_XSCALE */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0026900, + 0xc0096900, 0x00000300, 0x00000000, /* PA_SC_LINE_CNTL */ 0x00000000, /* PA_SC_AA_CONFIG */ - - 0xc0016900, - 0x00000302, 0x0000002d, /* PA_SU_VTX_CNTL */ - - 0xc0046900, - 0x00000303, 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ 0x3f800000, 0x3f800000, 0x3f800000, - - 0xc0026900, - 0x00000307, 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ 0x00000000, @@ -282,28 +255,13 @@ const u32 r6xx_default_state[] = 0x00000312, 0xffffffff, /* PA_SC_AA_MASK */ - 0xc0016900, + 0xc0066900, 0x0000037e, 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ - - 0xc0016900, - 0x0000037f, 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ - - 0xc0016900, - 0x00000380, 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ - - 0xc0016900, - 0x00000381, 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ - - 0xc0016900, - 0x00000382, 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ - - 0xc0016900, - 0x00000383, 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ 0xc0046900, @@ -330,29 +288,14 @@ const u32 r6xx_default_state[] = 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ - 0xc0026900, + 0xc0116900, 0x00000280, 0x00000000, /* PA_SU_POINT_SIZE */ 0x00000000, /* PA_SU_POINT_MINMAX */ - - 0xc0016900, - 0x00000282, 0x00000008, /* PA_SU_LINE_CNTL */ - - 0xc0016900, - 0x00000283, 0x00000000, /* PA_SC_LINE_STIPPLE */ - - 0xc0016900, - 0x00000284, 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ - - 0xc0016900, - 0x00000285, 0x00000000, /* VGT_HOS_CNTL */ - - 0xc00a6900, - 0x00000286, 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ 0x00000000, /* VGT_HOS_REUSE_DEPTH */ @@ -363,9 +306,6 @@ const u32 r6xx_default_state[] = 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ - - 0xc0016900, - 0x00000290, 0x00000000, /* VGT_GS_MODE */ 0xc0016900, @@ -386,37 +326,19 @@ const u32 r6xx_default_state[] = 0x000002c8, 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ - 0xc0016900, + 0xc0076900, 0x00000202, 0x00cc0000, /* CB_COLOR_CONTROL */ - - 0xc0016900, - 0x00000203, 0x00000210, /* DB_SHADER_CNTL */ - - 0xc0016900, - 0x00000204, 0x00010000, /* PA_CL_CLIP_CNTL */ - - 0xc0016900, - 0x00000205, 0x00000244, /* PA_SU_SC_MODE_CNTL */ - - 0xc0016900, - 0x00000206, 0x00000100, /* PA_CL_VTE_CNTL */ - - 0xc0026900, - 0x00000207, 0x00000000, /* PA_CL_VS_OUT_CNTL */ 0x00000000, /* PA_CL_NANINF_CNTL */ - 0xc0016900, + 0xc0026900, 0x0000008e, 0x0000000f, /* CB_TARGET_MASK */ - - 0xc0016900, - 0x0000008f, 0x0000000f, /* CB_SHADER_MASK */ 0xc0016900, @@ -431,21 +353,12 @@ const u32 r6xx_default_state[] = 0x00000191, 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ - 0xc0016900, + 0xc0056900, 0x000001b1, 0x00000000, /* SPI_VS_OUT_CONFIG */ - - 0xc0016900, - 0x000001b2, 0x00000000, /* SPI_THREAD_GROUPING */ - - 0xc0026900, - 0x000001b3, 0x00000001, /* SPI_PS_IN_CONTROL_0 */ 0x00000000, /* SPI_PS_IN_CONTROL_1 */ - - 0xc0016900, - 0x000001b5, 0x00000000, /* SPI_INTERP_CONTROL_0 */ 0xc0036e00, /* SET_SAMPLER */ @@ -524,36 +437,33 @@ const u32 r7xx_default_state[] = 0x00000351, 0x0000aa00, /* DB_ALPHA_TO_MASK */ - 0xc0036900, + 0xc0096900, 0x00000100, 0x00000800, /* VGT_MAX_VTX_INDX */ 0x00000000, /* VGT_MIN_VTX_INDX */ 0x00000000, /* VGT_INDX_OFFSET */ - - 0xc0016900, - 0x00000103, 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ - - 0xc0016900, - 0x00000104, 0x00000000, /* SX_ALPHA_TEST_CONTROL */ - - 0xc0046900, - 0x00000105, 0x00000000, /* CB_BLEND_RED */ 0x00000000, 0x00000000, 0x00000000, - 0xc0026900, + 0xc0036900, 0x0000010c, 0x00000000, /* DB_STENCILREFMASK */ 0x00000000, /* DB_STENCILREFMASK_BF */ - - 0xc0016900, - 0x0000010e, 0x00000000, /* SX_ALPHA_REF */ + 0xc0066900, + 0x0000010f, + 0x00000000, /* PA_CL_VPORT_XSCALE */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0046900, 0x0000030c, /* CB_CLRCMP_CNTL */ 0x01000000, @@ -645,41 +555,20 @@ const u32 r7xx_default_state[] = 0x00000000, 0x3f800000, - 0xc0016900, + 0xc0026900, 0x00000292, 0x00000000, /* PA_SC_MPASS_PS_CNTL */ - - 0xc0016900, - 0x00000293, 0x00514000, /* PA_SC_MODE_CNTL */ - 0xc0066900, - 0x0000010f, - 0x00000000, /* PA_CL_VPORT_0_XSCALE */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0026900, + 0xc0096900, 0x00000300, 0x00000000, /* PA_SC_LINE_CNTL */ 0x00000000, /* PA_SC_AA_CONFIG */ - - 0xc0016900, - 0x00000302, 0x0000002d, /* PA_SU_VTX_CNTL */ - - 0xc0046900, - 0x00000303, 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ 0x3f800000, 0x3f800000, 0x3f800000, - - 0xc0026900, - 0x00000307, 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ 0x00000000, @@ -687,28 +576,13 @@ const u32 r7xx_default_state[] = 0x00000312, 0xffffffff, /* PA_SC_AA_MASK */ - 0xc0016900, + 0xc0066900, 0x0000037e, 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ - - 0xc0016900, - 0x0000037f, 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ - - 0xc0016900, - 0x00000380, 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ - - 0xc0016900, - 0x00000381, 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ - - 0xc0016900, - 0x00000382, 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ - - 0xc0016900, - 0x00000383, 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ 0xc0046900, @@ -735,25 +609,13 @@ const u32 r7xx_default_state[] = 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ - 0xc0026900, + 0xc0116900, 0x00000280, 0x00000000, /* PA_SU_POINT_SIZE */ 0x00000000, /* PA_SU_POINT_MINMAX */ - - 0xc0016900, - 0x00000282, 0x00000008, /* PA_SU_LINE_CNTL */ - - 0xc0016900, - 0x00000283, 0x00000000, /* PA_SC_LINE_STIPPLE */ - - 0xc0016900, - 0x00000284, 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ - - 0xc00b6900, - 0x00000285, 0x00000000, /* VGT_HOS_CNTL */ 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ @@ -765,9 +627,6 @@ const u32 r7xx_default_state[] = 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ - - 0xc0016900, - 0x00000290, 0x00000000, /* VGT_GS_MODE */ 0xc0016900, @@ -788,37 +647,19 @@ const u32 r7xx_default_state[] = 0x000002c8, 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ - 0xc0016900, + 0xc0076900, 0x00000202, 0x00cc0000, /* CB_COLOR_CONTROL */ - - 0xc0016900, - 0x00000203, 0x00000210, /* DB_SHADER_CNTL */ - - 0xc0016900, - 0x00000204, 0x00010000, /* PA_CL_CLIP_CNTL */ - - 0xc0016900, - 0x00000205, 0x00000244, /* PA_SU_SC_MODE_CNTL */ - - 0xc0016900, - 0x00000206, 0x00000100, /* PA_CL_VTE_CNTL */ - - 0xc0026900, - 0x00000207, 0x00000000, /* PA_CL_VS_OUT_CNTL */ 0x00000000, /* PA_CL_NANINF_CNTL */ - 0xc0016900, + 0xc0026900, 0x0000008e, 0x0000000f, /* CB_TARGET_MASK */ - - 0xc0016900, - 0x0000008f, 0x0000000f, /* CB_SHADER_MASK */ 0xc0016900, @@ -833,21 +674,12 @@ const u32 r7xx_default_state[] = 0x00000191, 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ - 0xc0016900, + 0xc0056900, 0x000001b1, 0x00000000, /* SPI_VS_OUT_CONFIG */ - - 0xc0016900, - 0x000001b2, 0x00000001, /* SPI_THREAD_GROUPING */ - - 0xc0026900, - 0x000001b3, 0x00000001, /* SPI_PS_IN_CONTROL_0 */ 0x00000000, /* SPI_PS_IN_CONTROL_1 */ - - 0xc0016900, - 0x000001b5, 0x00000000, /* SPI_INTERP_CONTROL_0 */ 0xc0036e00, /* SET_SAMPLER */ -- cgit v0.10.2 From b417cc117a104ea457be18cfde9df9d69c21fa62 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 27 Jul 2010 11:01:15 -0400 Subject: drm/radeon: remove viewport transform from r6xx/r7xx blit emit We aren't using it, so no need. Save additional dwords. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 762b81c..e8151c1 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -127,15 +127,6 @@ const u32 r6xx_default_state[] = 0x00000000, /* DB_STENCILREFMASK_BF */ 0x00000000, /* SX_ALPHA_REF */ - 0xc0066900, - 0x0000010f, - 0x00000000, /* PA_CL_VPORT_XSCALE */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xc0046900, 0x0000030c, 0x01000000, /* CB_CLRCMP_CNTL */ @@ -455,15 +446,6 @@ const u32 r7xx_default_state[] = 0x00000000, /* DB_STENCILREFMASK_BF */ 0x00000000, /* SX_ALPHA_REF */ - 0xc0066900, - 0x0000010f, - 0x00000000, /* PA_CL_VPORT_XSCALE */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xc0046900, 0x0000030c, /* CB_CLRCMP_CNTL */ 0x01000000, -- cgit v0.10.2 From c39721c775f7ac20af5ff1cbbd11f80aeec91baa Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 24 Jul 2010 17:15:11 +0100 Subject: =?UTF-8?q?drm/vmgfx:=20operation=20on=20=E2=80=98par->dirty.y1?= =?UTF-8?q?=E2=80=99=20may=20be=20undefined?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trivial fix to set y1 = y2 = 0. Signed-off-by: Chris Wilson Cc: Jakob Bornecrantz Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index b0866f0..870967a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -528,7 +528,7 @@ int vmw_fb_init(struct vmw_private *vmw_priv) * Dirty & Deferred IO */ par->dirty.x1 = par->dirty.x2 = 0; - par->dirty.y1 = par->dirty.y1 = 0; + par->dirty.y1 = par->dirty.y2 = 0; par->dirty.active = true; spin_lock_init(&par->dirty.lock); info->fbdefio = &vmw_defio; -- cgit v0.10.2 From 05991110cf94117dd488f6d64dabdea56ff35107 Mon Sep 17 00:00:00 2001 From: Kulikov Vasiliy Date: Mon, 26 Jul 2010 12:23:54 +0400 Subject: drm/nouveau: set TASK_(UN)INTERRUPTIBLE before schedule_timeout() set_current_state() is called only once before the first iteration. After return from schedule_timeout() current state is TASK_RUNNING. If we are going to wait again, set_current_state() must be called. Signed-off-by: Kulikov Vasiliy Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 813d853..6b208ff 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -186,8 +186,6 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) unsigned long timeout = jiffies + (3 * DRM_HZ); int ret = 0; - __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); - while (1) { if (nouveau_fence_signalled(sync_obj, sync_arg)) break; @@ -197,6 +195,8 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) break; } + __set_current_state(intr ? TASK_INTERRUPTIBLE + : TASK_UNINTERRUPTIBLE); if (lazy) schedule_timeout(1); -- cgit v0.10.2 From ddd3d069c08bb1ba83aa4d522fc1360ce4afc270 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 24 Jul 2010 22:28:25 +0100 Subject: drm: Free the idr layers before calling idr_destroy() /* A typical clean-up sequence for objects stored in an idr tree, will * use idr_for_each() to free all objects, if necessary, then * idr_remove_all() to remove all ids, and idr_destroy() to free * up the cached idr_layers. */ We were missing the vital idr_rmove_all() step and so were leaking the used layers for every dri client: unreferenced object 0xf32133c0 (size 148): comm "plymouthd", pid 131, jiffies 4294678490 (age 2308.030s) hex dump (first 32 bytes): 04 00 00 00 00 00 00 00 00 00 00 00 00 40 19 f3 .............@.. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] create_object+0x124/0x1f1 [] kmemleak_alloc+0x4c/0x90 [] kmem_cache_alloc+0xee/0x13c [] idr_pre_get+0x24/0x61 [] drm_gem_handle_create+0x27/0x7f [drm] [] i915_gem_create_ioctl+0x4f/0x71 [i915] [] drm_ioctl+0x272/0x356 [drm] [] vfs_ioctl+0x33/0x91 [] do_vfs_ioctl+0x46b/0x496 [] sys_ioctl+0x46/0x66 [] sysenter_do_call+0x12/0x38 [] 0xffffffff Fixes https://bugzilla.kernel.org/show_bug.cgi?id=15803 Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 510bc87..b5a5168 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -335,6 +335,7 @@ static void __exit drm_core_exit(void) unregister_chrdev(DRM_MAJOR, "drm"); + idr_remove_all(&drm_minors_idr); idr_destroy(&drm_minors_idr); } diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 8601b72..4f1b867 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -429,6 +429,7 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private) idr_for_each(&file_private->object_idr, &drm_gem_object_release_handle, NULL); + idr_remove_all(&file_private->object_idr); idr_destroy(&file_private->object_idr); } -- cgit v0.10.2 From 6e35023ffad0ee74689710f0e81ee80c1019f93b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 24 Jul 2010 18:29:36 +0100 Subject: drm: Free devname along with master->unique The device name is tightly coupled and created at the same time as the master->unique address, so we need to free it with the master. Currently we overwrite it each time we create a new master: unreferenced object 0xe32c54b0 (size 32): comm "Xorg", pid 1455, jiffies 4294721798 (age 3196.879s) hex dump (first 32 bytes): 69 39 31 35 40 70 63 69 3a 30 30 30 30 3a 30 30 i915@pci:0000:00 3a 30 32 2e 30 00 6b 6b 6b 6b 6b 6b 6b 6b 6b a5 :02.0.kkkkkkkkk. backtrace: [] create_object+0x124/0x1f1 [] kmemleak_alloc+0x4c/0x90 [] __kmalloc+0x155/0x175 [] drm_setversion+0x11d/0x1b1 [drm] [] drm_ioctl+0x29a/0x356 [drm] [] vfs_ioctl+0x33/0x91 [] do_vfs_ioctl+0x46b/0x496 [] sys_ioctl+0x46/0x66 [] sysenter_do_call+0x12/0x38 [] 0xffffffff Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 63575e2..d1ad574 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -156,6 +156,9 @@ static void drm_master_destroy(struct kref *kref) master->unique_len = 0; } + kfree(dev->devname); + dev->devname = NULL; + list_for_each_entry_safe(pt, next, &master->magicfree, head) { list_del(&pt->head); drm_ht_remove_item(&master->magiclist, &pt->hash_item); -- cgit v0.10.2 From aca791c28a0fb884a020f75c8e4361af58f068ae Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Wed, 14 Jul 2010 21:54:13 +0200 Subject: drm/i810: fixed coding style issues Fixed brace, macro and spacing coding style issues, and a C99 comment. Signed-off-by: Nicolas Kaiser Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 997d917..09c86ed 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -60,9 +60,8 @@ static struct drm_buf *i810_freelist_get(struct drm_device * dev) /* In use is already a pointer */ used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, I810_BUF_CLIENT); - if (used == I810_BUF_FREE) { + if (used == I810_BUF_FREE) return buf; - } } return NULL; } @@ -71,7 +70,7 @@ static struct drm_buf *i810_freelist_get(struct drm_device * dev) * yet, the hardware updates in use for us once its on the ring buffer. */ -static int i810_freelist_put(struct drm_device * dev, struct drm_buf * buf) +static int i810_freelist_put(struct drm_device *dev, struct drm_buf *buf) { drm_i810_buf_priv_t *buf_priv = buf->dev_private; int used; @@ -121,7 +120,7 @@ static const struct file_operations i810_buffer_fops = { .fasync = drm_fasync, }; -static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) +static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) { struct drm_device *dev = file_priv->minor->dev; drm_i810_buf_priv_t *buf_priv = buf->dev_private; @@ -152,7 +151,7 @@ static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) return retcode; } -static int i810_unmap_buffer(struct drm_buf * buf) +static int i810_unmap_buffer(struct drm_buf *buf) { drm_i810_buf_priv_t *buf_priv = buf->dev_private; int retcode = 0; @@ -172,7 +171,7 @@ static int i810_unmap_buffer(struct drm_buf * buf) return retcode; } -static int i810_dma_get_buffer(struct drm_device * dev, drm_i810_dma_t * d, +static int i810_dma_get_buffer(struct drm_device *dev, drm_i810_dma_t *d, struct drm_file *file_priv) { struct drm_buf *buf; @@ -202,7 +201,7 @@ static int i810_dma_get_buffer(struct drm_device * dev, drm_i810_dma_t * d, return retcode; } -static int i810_dma_cleanup(struct drm_device * dev) +static int i810_dma_cleanup(struct drm_device *dev) { struct drm_device_dma *dma = dev->dma; @@ -218,9 +217,8 @@ static int i810_dma_cleanup(struct drm_device * dev) drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - if (dev_priv->ring.virtual_start) { + if (dev_priv->ring.virtual_start) drm_core_ioremapfree(&dev_priv->ring.map, dev); - } if (dev_priv->hw_status_page) { pci_free_consistent(dev->pdev, PAGE_SIZE, dev_priv->hw_status_page, @@ -242,7 +240,7 @@ static int i810_dma_cleanup(struct drm_device * dev) return 0; } -static int i810_wait_ring(struct drm_device * dev, int n) +static int i810_wait_ring(struct drm_device *dev, int n) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_ring_buffer_t *ring = &(dev_priv->ring); @@ -271,11 +269,11 @@ static int i810_wait_ring(struct drm_device * dev, int n) udelay(1); } - out_wait_ring: +out_wait_ring: return iters; } -static void i810_kernel_lost_context(struct drm_device * dev) +static void i810_kernel_lost_context(struct drm_device *dev) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_ring_buffer_t *ring = &(dev_priv->ring); @@ -287,7 +285,7 @@ static void i810_kernel_lost_context(struct drm_device * dev) ring->space += ring->Size; } -static int i810_freelist_init(struct drm_device * dev, drm_i810_private_t * dev_priv) +static int i810_freelist_init(struct drm_device *dev, drm_i810_private_t *dev_priv) { struct drm_device_dma *dma = dev->dma; int my_idx = 24; @@ -322,9 +320,9 @@ static int i810_freelist_init(struct drm_device * dev, drm_i810_private_t * dev_ return 0; } -static int i810_dma_initialize(struct drm_device * dev, - drm_i810_private_t * dev_priv, - drm_i810_init_t * init) +static int i810_dma_initialize(struct drm_device *dev, + drm_i810_private_t *dev_priv, + drm_i810_init_t *init) { struct drm_map_list *r_list; memset(dev_priv, 0, sizeof(drm_i810_private_t)); @@ -462,7 +460,7 @@ static int i810_dma_init(struct drm_device *dev, void *data, * Use 'volatile' & local var tmp to force the emitted values to be * identical to the verified ones. */ -static void i810EmitContextVerified(struct drm_device * dev, +static void i810EmitContextVerified(struct drm_device *dev, volatile unsigned int *code) { drm_i810_private_t *dev_priv = dev->dev_private; @@ -495,7 +493,7 @@ static void i810EmitContextVerified(struct drm_device * dev, ADVANCE_LP_RING(); } -static void i810EmitTexVerified(struct drm_device * dev, volatile unsigned int *code) +static void i810EmitTexVerified(struct drm_device *dev, volatile unsigned int *code) { drm_i810_private_t *dev_priv = dev->dev_private; int i, j = 0; @@ -528,7 +526,7 @@ static void i810EmitTexVerified(struct drm_device * dev, volatile unsigned int * /* Need to do some additional checking when setting the dest buffer. */ -static void i810EmitDestVerified(struct drm_device * dev, +static void i810EmitDestVerified(struct drm_device *dev, volatile unsigned int *code) { drm_i810_private_t *dev_priv = dev->dev_private; @@ -563,7 +561,7 @@ static void i810EmitDestVerified(struct drm_device * dev, ADVANCE_LP_RING(); } -static void i810EmitState(struct drm_device * dev) +static void i810EmitState(struct drm_device *dev) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -594,7 +592,7 @@ static void i810EmitState(struct drm_device * dev) /* need to verify */ -static void i810_dma_dispatch_clear(struct drm_device * dev, int flags, +static void i810_dma_dispatch_clear(struct drm_device *dev, int flags, unsigned int clear_color, unsigned int clear_zval) { @@ -669,7 +667,7 @@ static void i810_dma_dispatch_clear(struct drm_device * dev, int flags, } } -static void i810_dma_dispatch_swap(struct drm_device * dev) +static void i810_dma_dispatch_swap(struct drm_device *dev) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -715,8 +713,8 @@ static void i810_dma_dispatch_swap(struct drm_device * dev) } } -static void i810_dma_dispatch_vertex(struct drm_device * dev, - struct drm_buf * buf, int discard, int used) +static void i810_dma_dispatch_vertex(struct drm_device *dev, + struct drm_buf *buf, int discard, int used) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_buf_priv_t *buf_priv = buf->dev_private; @@ -795,7 +793,7 @@ static void i810_dma_dispatch_vertex(struct drm_device * dev, } } -static void i810_dma_dispatch_flip(struct drm_device * dev) +static void i810_dma_dispatch_flip(struct drm_device *dev) { drm_i810_private_t *dev_priv = dev->dev_private; int pitch = dev_priv->pitch; @@ -841,7 +839,7 @@ static void i810_dma_dispatch_flip(struct drm_device * dev) } -static void i810_dma_quiescent(struct drm_device * dev) +static void i810_dma_quiescent(struct drm_device *dev) { drm_i810_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -858,7 +856,7 @@ static void i810_dma_quiescent(struct drm_device * dev) i810_wait_ring(dev, dev_priv->ring.Size - 8); } -static int i810_flush_queue(struct drm_device * dev) +static int i810_flush_queue(struct drm_device *dev) { drm_i810_private_t *dev_priv = dev->dev_private; struct drm_device_dma *dma = dev->dma; @@ -891,7 +889,7 @@ static int i810_flush_queue(struct drm_device * dev) } /* Must be called with the lock held */ -static void i810_reclaim_buffers(struct drm_device * dev, +static void i810_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) { struct drm_device_dma *dma = dev->dma; @@ -969,9 +967,8 @@ static int i810_clear_bufs(struct drm_device *dev, void *data, LOCK_TEST_WITH_RETURN(dev, file_priv); /* GH: Someone's doing nasty things... */ - if (!dev->dev_private) { + if (!dev->dev_private) return -EINVAL; - } i810_dma_dispatch_clear(dev, clear->flags, clear->clear_color, clear->clear_depth); @@ -1039,7 +1036,7 @@ static int i810_docopy(struct drm_device *dev, void *data, return 0; } -static void i810_dma_dispatch_mc(struct drm_device * dev, struct drm_buf * buf, int used, +static void i810_dma_dispatch_mc(struct drm_device *dev, struct drm_buf *buf, int used, unsigned int last_render) { drm_i810_private_t *dev_priv = dev->dev_private; @@ -1053,9 +1050,8 @@ static void i810_dma_dispatch_mc(struct drm_device * dev, struct drm_buf * buf, i810_kernel_lost_context(dev); u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE); - if (u != I810_BUF_CLIENT) { + if (u != I810_BUF_CLIENT) DRM_DEBUG("MC found buffer that isn't mine!\n"); - } if (used > 4 * 1024) used = 0; @@ -1160,7 +1156,7 @@ static int i810_ov0_flip(struct drm_device *dev, void *data, LOCK_TEST_WITH_RETURN(dev, file_priv); - //Tell the overlay to update + /* Tell the overlay to update */ I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000); return 0; @@ -1168,7 +1164,7 @@ static int i810_ov0_flip(struct drm_device *dev, void *data, /* Not sure why this isn't set all the time: */ -static void i810_do_init_pageflip(struct drm_device * dev) +static void i810_do_init_pageflip(struct drm_device *dev) { drm_i810_private_t *dev_priv = dev->dev_private; @@ -1178,7 +1174,7 @@ static void i810_do_init_pageflip(struct drm_device * dev) dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; } -static int i810_do_cleanup_pageflip(struct drm_device * dev) +static int i810_do_cleanup_pageflip(struct drm_device *dev) { drm_i810_private_t *dev_priv = dev->dev_private; @@ -1218,28 +1214,27 @@ int i810_driver_load(struct drm_device *dev, unsigned long flags) return 0; } -void i810_driver_lastclose(struct drm_device * dev) +void i810_driver_lastclose(struct drm_device *dev) { i810_dma_cleanup(dev); } -void i810_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) +void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) { if (dev->dev_private) { drm_i810_private_t *dev_priv = dev->dev_private; - if (dev_priv->page_flipping) { + if (dev_priv->page_flipping) i810_do_cleanup_pageflip(dev); - } } } -void i810_driver_reclaim_buffers_locked(struct drm_device * dev, +void i810_driver_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv) { i810_reclaim_buffers(dev, file_priv); } -int i810_driver_dma_quiescent(struct drm_device * dev) +int i810_driver_dma_quiescent(struct drm_device *dev) { i810_dma_quiescent(dev); return 0; @@ -1276,7 +1271,7 @@ int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); * \returns * A value of 1 is always retured to indictate every i810 is AGP. */ -int i810_driver_device_is_agp(struct drm_device * dev) +int i810_driver_device_is_agp(struct drm_device *dev) { return 1; } diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h index 21e2691..0743fe9 100644 --- a/drivers/gpu/drm/i810/i810_drv.h +++ b/drivers/gpu/drm/i810/i810_drv.h @@ -115,16 +115,16 @@ typedef struct drm_i810_private { } drm_i810_private_t; /* i810_dma.c */ -extern int i810_driver_dma_quiescent(struct drm_device * dev); -extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev, +extern int i810_driver_dma_quiescent(struct drm_device *dev); +extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv); extern int i810_driver_load(struct drm_device *, unsigned long flags); -extern void i810_driver_lastclose(struct drm_device * dev); -extern void i810_driver_preclose(struct drm_device * dev, +extern void i810_driver_lastclose(struct drm_device *dev); +extern void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); -extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev, +extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv); -extern int i810_driver_device_is_agp(struct drm_device * dev); +extern int i810_driver_device_is_agp(struct drm_device *dev); extern struct drm_ioctl_desc i810_ioctls[]; extern int i810_max_ioctl; @@ -132,39 +132,41 @@ extern int i810_max_ioctl; #define I810_BASE(reg) ((unsigned long) \ dev_priv->mmio_map->handle) #define I810_ADDR(reg) (I810_BASE(reg) + reg) -#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg) +#define I810_DEREF(reg) (*(__volatile__ int *)I810_ADDR(reg)) #define I810_READ(reg) I810_DEREF(reg) -#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0) -#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg) +#define I810_WRITE(reg, val) do { I810_DEREF(reg) = val; } while (0) +#define I810_DEREF16(reg) (*(__volatile__ u16 *)I810_ADDR(reg)) #define I810_READ16(reg) I810_DEREF16(reg) -#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) +#define I810_WRITE16(reg, val) do { I810_DEREF16(reg) = val; } while (0) #define I810_VERBOSE 0 #define RING_LOCALS unsigned int outring, ringmask; \ - volatile char *virt; - -#define BEGIN_LP_RING(n) do { \ - if (I810_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d)\n", n); \ - if (dev_priv->ring.space < n*4) \ - i810_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ + volatile char *virt; + +#define BEGIN_LP_RING(n) do { \ + if (I810_VERBOSE) \ + DRM_DEBUG("BEGIN_LP_RING(%d)\n", n); \ + if (dev_priv->ring.space < n*4) \ + i810_wait_ring(dev, n*4); \ + dev_priv->ring.space -= n*4; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ } while (0) -#define ADVANCE_LP_RING() do { \ - if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ +#define ADVANCE_LP_RING() do { \ + if (I810_VERBOSE) \ + DRM_DEBUG("ADVANCE_LP_RING\n"); \ dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) - -#define OUT_RING(n) do { \ - if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ + I810_WRITE(LP_RING + RING_TAIL, outring); \ +} while (0) + +#define OUT_RING(n) do { \ + if (I810_VERBOSE) \ + DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ } while (0) #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) -- cgit v0.10.2 From 5649911316c89b6cf7963b521ec5e9287f8667a7 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Thu, 15 Jul 2010 00:14:43 +0200 Subject: drm/i830: fixed brace and spacing coding style issues Fixed brace and spacing coding style issues. Signed-off-by: Nicolas Kaiser Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 65759a9..7ee85ea 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c @@ -62,9 +62,8 @@ static struct drm_buf *i830_freelist_get(struct drm_device * dev) /* In use is already a pointer */ used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, I830_BUF_CLIENT); - if (used == I830_BUF_FREE) { + if (used == I830_BUF_FREE) return buf; - } } return NULL; } @@ -73,7 +72,7 @@ static struct drm_buf *i830_freelist_get(struct drm_device * dev) * yet, the hardware updates in use for us once its on the ring buffer. */ -static int i830_freelist_put(struct drm_device * dev, struct drm_buf * buf) +static int i830_freelist_put(struct drm_device *dev, struct drm_buf *buf) { drm_i830_buf_priv_t *buf_priv = buf->dev_private; int used; @@ -123,7 +122,7 @@ static const struct file_operations i830_buffer_fops = { .fasync = drm_fasync, }; -static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) +static int i830_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) { struct drm_device *dev = file_priv->minor->dev; drm_i830_buf_priv_t *buf_priv = buf->dev_private; @@ -156,7 +155,7 @@ static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) return retcode; } -static int i830_unmap_buffer(struct drm_buf * buf) +static int i830_unmap_buffer(struct drm_buf *buf) { drm_i830_buf_priv_t *buf_priv = buf->dev_private; int retcode = 0; @@ -176,7 +175,7 @@ static int i830_unmap_buffer(struct drm_buf * buf) return retcode; } -static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d, +static int i830_dma_get_buffer(struct drm_device *dev, drm_i830_dma_t *d, struct drm_file *file_priv) { struct drm_buf *buf; @@ -206,7 +205,7 @@ static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d, return retcode; } -static int i830_dma_cleanup(struct drm_device * dev) +static int i830_dma_cleanup(struct drm_device *dev) { struct drm_device_dma *dma = dev->dma; @@ -222,9 +221,8 @@ static int i830_dma_cleanup(struct drm_device * dev) drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - if (dev_priv->ring.virtual_start) { + if (dev_priv->ring.virtual_start) drm_core_ioremapfree(&dev_priv->ring.map, dev); - } if (dev_priv->hw_status_page) { pci_free_consistent(dev->pdev, PAGE_SIZE, dev_priv->hw_status_page, @@ -246,7 +244,7 @@ static int i830_dma_cleanup(struct drm_device * dev) return 0; } -int i830_wait_ring(struct drm_device * dev, int n, const char *caller) +int i830_wait_ring(struct drm_device *dev, int n, const char *caller) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_ring_buffer_t *ring = &(dev_priv->ring); @@ -276,11 +274,11 @@ int i830_wait_ring(struct drm_device * dev, int n, const char *caller) dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; } - out_wait_ring: +out_wait_ring: return iters; } -static void i830_kernel_lost_context(struct drm_device * dev) +static void i830_kernel_lost_context(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_ring_buffer_t *ring = &(dev_priv->ring); @@ -295,7 +293,7 @@ static void i830_kernel_lost_context(struct drm_device * dev) dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; } -static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_priv) +static int i830_freelist_init(struct drm_device *dev, drm_i830_private_t *dev_priv) { struct drm_device_dma *dma = dev->dma; int my_idx = 36; @@ -329,9 +327,9 @@ static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_ return 0; } -static int i830_dma_initialize(struct drm_device * dev, - drm_i830_private_t * dev_priv, - drm_i830_init_t * init) +static int i830_dma_initialize(struct drm_device *dev, + drm_i830_private_t *dev_priv, + drm_i830_init_t *init) { struct drm_map_list *r_list; @@ -482,7 +480,7 @@ static int i830_dma_init(struct drm_device *dev, void *data, /* Most efficient way to verify state for the i830 is as it is * emitted. Non-conformant state is silently dropped. */ -static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code) +static void i830EmitContextVerified(struct drm_device *dev, unsigned int *code) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; @@ -527,7 +525,7 @@ static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code) ADVANCE_LP_RING(); } -static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code) +static void i830EmitTexVerified(struct drm_device *dev, unsigned int *code) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; @@ -561,7 +559,7 @@ static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code) printk("rejected packet %x\n", code[0]); } -static void i830EmitTexBlendVerified(struct drm_device * dev, +static void i830EmitTexBlendVerified(struct drm_device *dev, unsigned int *code, unsigned int num) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -586,7 +584,7 @@ static void i830EmitTexBlendVerified(struct drm_device * dev, ADVANCE_LP_RING(); } -static void i830EmitTexPalette(struct drm_device * dev, +static void i830EmitTexPalette(struct drm_device *dev, unsigned int *palette, int number, int is_shared) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -603,9 +601,8 @@ static void i830EmitTexPalette(struct drm_device * dev, } else { OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number)); } - for (i = 0; i < 256; i++) { + for (i = 0; i < 256; i++) OUT_RING(palette[i]); - } OUT_RING(0); /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! */ @@ -613,7 +610,7 @@ static void i830EmitTexPalette(struct drm_device * dev, /* Need to do some additional checking when setting the dest buffer. */ -static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code) +static void i830EmitDestVerified(struct drm_device *dev, unsigned int *code) { drm_i830_private_t *dev_priv = dev->dev_private; unsigned int tmp; @@ -674,7 +671,7 @@ static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code) ADVANCE_LP_RING(); } -static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code) +static void i830EmitStippleVerified(struct drm_device *dev, unsigned int *code) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -685,7 +682,7 @@ static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code) ADVANCE_LP_RING(); } -static void i830EmitState(struct drm_device * dev) +static void i830EmitState(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -788,7 +785,7 @@ static void i830EmitState(struct drm_device * dev) * Performance monitoring functions */ -static void i830_fill_box(struct drm_device * dev, +static void i830_fill_box(struct drm_device *dev, int x, int y, int w, int h, int r, int g, int b) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -816,17 +813,16 @@ static void i830_fill_box(struct drm_device * dev, OUT_RING((y << 16) | x); OUT_RING(((y + h) << 16) | (x + w)); - if (dev_priv->current_page == 1) { + if (dev_priv->current_page == 1) OUT_RING(dev_priv->front_offset); - } else { + else OUT_RING(dev_priv->back_offset); - } OUT_RING(color); ADVANCE_LP_RING(); } -static void i830_cp_performance_boxes(struct drm_device * dev) +static void i830_cp_performance_boxes(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -871,7 +867,7 @@ static void i830_cp_performance_boxes(struct drm_device * dev) dev_priv->sarea_priv->perf_boxes = 0; } -static void i830_dma_dispatch_clear(struct drm_device * dev, int flags, +static void i830_dma_dispatch_clear(struct drm_device *dev, int flags, unsigned int clear_color, unsigned int clear_zval, unsigned int clear_depthmask) @@ -966,7 +962,7 @@ static void i830_dma_dispatch_clear(struct drm_device * dev, int flags, } } -static void i830_dma_dispatch_swap(struct drm_device * dev) +static void i830_dma_dispatch_swap(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -1036,7 +1032,7 @@ static void i830_dma_dispatch_swap(struct drm_device * dev) } } -static void i830_dma_dispatch_flip(struct drm_device * dev) +static void i830_dma_dispatch_flip(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -1079,8 +1075,8 @@ static void i830_dma_dispatch_flip(struct drm_device * dev) dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; } -static void i830_dma_dispatch_vertex(struct drm_device * dev, - struct drm_buf * buf, int discard, int used) +static void i830_dma_dispatch_vertex(struct drm_device *dev, + struct drm_buf *buf, int discard, int used) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_buf_priv_t *buf_priv = buf->dev_private; @@ -1100,9 +1096,8 @@ static void i830_dma_dispatch_vertex(struct drm_device * dev, if (discard) { u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_HARDWARE); - if (u != I830_BUF_CLIENT) { + if (u != I830_BUF_CLIENT) DRM_DEBUG("xxxx 2\n"); - } } if (used > 4 * 1023) @@ -1191,7 +1186,7 @@ static void i830_dma_dispatch_vertex(struct drm_device * dev, } } -static void i830_dma_quiescent(struct drm_device * dev) +static void i830_dma_quiescent(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -1208,7 +1203,7 @@ static void i830_dma_quiescent(struct drm_device * dev) i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__); } -static int i830_flush_queue(struct drm_device * dev) +static int i830_flush_queue(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; struct drm_device_dma *dma = dev->dma; @@ -1241,7 +1236,7 @@ static int i830_flush_queue(struct drm_device * dev) } /* Must be called with the lock held */ -static void i830_reclaim_buffers(struct drm_device * dev, struct drm_file *file_priv) +static void i830_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) { struct drm_device_dma *dma = dev->dma; int i; @@ -1316,9 +1311,8 @@ static int i830_clear_bufs(struct drm_device *dev, void *data, LOCK_TEST_WITH_RETURN(dev, file_priv); /* GH: Someone's doing nasty things... */ - if (!dev->dev_private) { + if (!dev->dev_private) return -EINVAL; - } i830_dma_dispatch_clear(dev, clear->flags, clear->clear_color, @@ -1339,7 +1333,7 @@ static int i830_swap_bufs(struct drm_device *dev, void *data, /* Not sure why this isn't set all the time: */ -static void i830_do_init_pageflip(struct drm_device * dev) +static void i830_do_init_pageflip(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -1349,7 +1343,7 @@ static void i830_do_init_pageflip(struct drm_device * dev) dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; } -static int i830_do_cleanup_pageflip(struct drm_device * dev) +static int i830_do_cleanup_pageflip(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -1490,27 +1484,26 @@ int i830_driver_load(struct drm_device *dev, unsigned long flags) return 0; } -void i830_driver_lastclose(struct drm_device * dev) +void i830_driver_lastclose(struct drm_device *dev) { i830_dma_cleanup(dev); } -void i830_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) +void i830_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) { if (dev->dev_private) { drm_i830_private_t *dev_priv = dev->dev_private; - if (dev_priv->page_flipping) { + if (dev_priv->page_flipping) i830_do_cleanup_pageflip(dev); - } } } -void i830_driver_reclaim_buffers_locked(struct drm_device * dev, struct drm_file *file_priv) +void i830_driver_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv) { i830_reclaim_buffers(dev, file_priv); } -int i830_driver_dma_quiescent(struct drm_device * dev) +int i830_driver_dma_quiescent(struct drm_device *dev) { i830_dma_quiescent(dev); return 0; @@ -1546,7 +1539,7 @@ int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); * \returns * A value of 1 is always retured to indictate every i8xx is AGP. */ -int i830_driver_device_is_agp(struct drm_device * dev) +int i830_driver_device_is_agp(struct drm_device *dev) { return 1; } diff --git a/drivers/gpu/drm/i830/i830_drv.h b/drivers/gpu/drm/i830/i830_drv.h index da82afe..ecfd25a 100644 --- a/drivers/gpu/drm/i830/i830_drv.h +++ b/drivers/gpu/drm/i830/i830_drv.h @@ -132,33 +132,33 @@ extern int i830_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS); -extern void i830_driver_irq_preinstall(struct drm_device * dev); -extern void i830_driver_irq_postinstall(struct drm_device * dev); -extern void i830_driver_irq_uninstall(struct drm_device * dev); +extern void i830_driver_irq_preinstall(struct drm_device *dev); +extern void i830_driver_irq_postinstall(struct drm_device *dev); +extern void i830_driver_irq_uninstall(struct drm_device *dev); extern int i830_driver_load(struct drm_device *, unsigned long flags); -extern void i830_driver_preclose(struct drm_device * dev, +extern void i830_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); -extern void i830_driver_lastclose(struct drm_device * dev); -extern void i830_driver_reclaim_buffers_locked(struct drm_device * dev, +extern void i830_driver_lastclose(struct drm_device *dev); +extern void i830_driver_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv); -extern int i830_driver_dma_quiescent(struct drm_device * dev); -extern int i830_driver_device_is_agp(struct drm_device * dev); +extern int i830_driver_dma_quiescent(struct drm_device *dev); +extern int i830_driver_device_is_agp(struct drm_device *dev); -#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) -#define I830_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val) -#define I830_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg) -#define I830_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val) +#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg) +#define I830_WRITE(reg, val) DRM_WRITE32(dev_priv->mmio_map, reg, val) +#define I830_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg) +#define I830_WRITE16(reg, val) DRM_WRITE16(dev_priv->mmio_map, reg, val) #define I830_VERBOSE 0 #define RING_LOCALS unsigned int outring, ringmask, outcount; \ - volatile char *virt; + volatile char *virt; #define BEGIN_LP_RING(n) do { \ if (I830_VERBOSE) \ printk("BEGIN_LP_RING(%d)\n", (n)); \ if (dev_priv->ring.space < n*4) \ - i830_wait_ring(dev, n*4, __func__); \ + i830_wait_ring(dev, n*4, __func__); \ outcount = 0; \ outring = dev_priv->ring.tail; \ ringmask = dev_priv->ring.tail_mask; \ @@ -166,21 +166,23 @@ extern int i830_driver_device_is_agp(struct drm_device * dev); } while (0) #define OUT_RING(n) do { \ - if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \ + if (I830_VERBOSE) \ + printk(" OUT_RING %x\n", (int)(n)); \ *(volatile unsigned int *)(virt + outring) = n; \ - outcount++; \ + outcount++; \ outring += 4; \ outring &= ringmask; \ } while (0) -#define ADVANCE_LP_RING() do { \ - if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \ - dev_priv->ring.tail = outring; \ - dev_priv->ring.space -= outcount * 4; \ - I830_WRITE(LP_RING + RING_TAIL, outring); \ -} while(0) +#define ADVANCE_LP_RING() do { \ + if (I830_VERBOSE) \ + printk("ADVANCE_LP_RING %x\n", outring); \ + dev_priv->ring.tail = outring; \ + dev_priv->ring.space -= outcount * 4; \ + I830_WRITE(LP_RING + RING_TAIL, outring); \ +} while (0) -extern int i830_wait_ring(struct drm_device * dev, int n, const char *caller); +extern int i830_wait_ring(struct drm_device *dev, int n, const char *caller); #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) diff --git a/drivers/gpu/drm/i830/i830_irq.c b/drivers/gpu/drm/i830/i830_irq.c index 91ec2bb..d1a6b95 100644 --- a/drivers/gpu/drm/i830/i830_irq.c +++ b/drivers/gpu/drm/i830/i830_irq.c @@ -53,7 +53,7 @@ irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_HANDLED; } -static int i830_emit_irq(struct drm_device * dev) +static int i830_emit_irq(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -70,7 +70,7 @@ static int i830_emit_irq(struct drm_device * dev) return atomic_read(&dev_priv->irq_emitted); } -static int i830_wait_irq(struct drm_device * dev, int irq_nr) +static int i830_wait_irq(struct drm_device *dev, int irq_nr) { drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; DECLARE_WAITQUEUE(entry, current); @@ -156,7 +156,7 @@ int i830_irq_wait(struct drm_device *dev, void *data, /* drm_dma.h hooks */ -void i830_driver_irq_preinstall(struct drm_device * dev) +void i830_driver_irq_preinstall(struct drm_device *dev) { drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; @@ -168,14 +168,14 @@ void i830_driver_irq_preinstall(struct drm_device * dev) init_waitqueue_head(&dev_priv->irq_queue); } -void i830_driver_irq_postinstall(struct drm_device * dev) +void i830_driver_irq_postinstall(struct drm_device *dev) { drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; I830_WRITE16(I830REG_INT_ENABLE_R, 0x2); } -void i830_driver_irq_uninstall(struct drm_device * dev) +void i830_driver_irq_uninstall(struct drm_device *dev) { drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; if (!dev_priv) -- cgit v0.10.2 From 219de62a1627247fca10789f28902f66cb0b408f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 25 Jun 2010 21:24:20 +0200 Subject: drm/radeon/kms: trivial code style fixes for audio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 631e1ed..b5443fe 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -63,7 +63,8 @@ int r600_audio_bits_per_sample(struct radeon_device *rdev) case 0x4: return 32; } - DRM_ERROR("Unknown bits per sample 0x%x using 16 instead.\n", (int)value); + dev_err(rdev->dev, "Unknown bits per sample 0x%x using 16 instead\n", + (int)value); return 16; } @@ -150,7 +151,8 @@ static void r600_audio_update_hdmi(unsigned long param) r600_hdmi_update_audio_settings(encoder); } - if(still_going) r600_audio_schedule_polling(rdev); + if (still_going) + r600_audio_schedule_polling(rdev); } /* @@ -158,7 +160,7 @@ static void r600_audio_update_hdmi(unsigned long param) */ static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) { - DRM_INFO("%s audio support", enable ? "Enabling" : "Disabling"); + DRM_INFO("%s audio support\n", enable ? "Enabling" : "Disabling"); WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000); rdev->audio_enabled = enable; } @@ -196,7 +198,8 @@ void r600_audio_enable_polling(struct drm_encoder *encoder) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - DRM_DEBUG("r600_audio_enable_polling: %d", radeon_encoder->audio_polling_active); + DRM_DEBUG("r600_audio_enable_polling: %d\n", + radeon_encoder->audio_polling_active); if (radeon_encoder->audio_polling_active) return; @@ -211,7 +214,8 @@ void r600_audio_enable_polling(struct drm_encoder *encoder) void r600_audio_disable_polling(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - DRM_DEBUG("r600_audio_disable_polling: %d", radeon_encoder->audio_polling_active); + DRM_DEBUG("r600_audio_disable_polling: %d\n", + radeon_encoder->audio_polling_active); radeon_encoder->audio_polling_active = 0; } @@ -238,7 +242,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301); break; default: - DRM_ERROR("Unsupported encoder type 0x%02X\n", + dev_err(rdev->dev, "Unsupported encoder type 0x%02X\n", radeon_encoder->encoder_id); return; } -- cgit v0.10.2 From 58c1e85af3645ac8df021dbf14acd215b5687f54 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Sun, 11 Jul 2010 15:32:42 +0200 Subject: drm/via: fixed coding style issues, simplified return Fixed brace, macro and spacing coding style issues. Simplified -if (ret) return ret; -return 0; +return ret; Signed-off-by: Nicolas Kaiser Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c index bfb92d2..68dda74 100644 --- a/drivers/gpu/drm/via/via_dma.c +++ b/drivers/gpu/drm/via/via_dma.c @@ -58,28 +58,29 @@ *((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \ *((uint32_t *)(vb) + 1) = (nData); \ vb = ((uint32_t *)vb) + 2; \ - dev_priv->dma_low +=8; \ + dev_priv->dma_low += 8; \ } #define via_flush_write_combine() DRM_MEMORYBARRIER() -#define VIA_OUT_RING_QW(w1,w2) \ +#define VIA_OUT_RING_QW(w1, w2) do { \ *vb++ = (w1); \ *vb++ = (w2); \ - dev_priv->dma_low += 8; + dev_priv->dma_low += 8; \ +} while (0) -static void via_cmdbuf_start(drm_via_private_t * dev_priv); -static void via_cmdbuf_pause(drm_via_private_t * dev_priv); -static void via_cmdbuf_reset(drm_via_private_t * dev_priv); -static void via_cmdbuf_rewind(drm_via_private_t * dev_priv); -static int via_wait_idle(drm_via_private_t * dev_priv); -static void via_pad_cache(drm_via_private_t * dev_priv, int qwords); +static void via_cmdbuf_start(drm_via_private_t *dev_priv); +static void via_cmdbuf_pause(drm_via_private_t *dev_priv); +static void via_cmdbuf_reset(drm_via_private_t *dev_priv); +static void via_cmdbuf_rewind(drm_via_private_t *dev_priv); +static int via_wait_idle(drm_via_private_t *dev_priv); +static void via_pad_cache(drm_via_private_t *dev_priv, int qwords); /* * Free space in command buffer. */ -static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv) +static uint32_t via_cmdbuf_space(drm_via_private_t *dev_priv) { uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; @@ -93,7 +94,7 @@ static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv) * How much does the command regulator lag behind? */ -static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv) +static uint32_t via_cmdbuf_lag(drm_via_private_t *dev_priv) { uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base; @@ -108,7 +109,7 @@ static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv) */ static inline int -via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size) +via_cmdbuf_wait(drm_via_private_t *dev_priv, unsigned int size) { uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; uint32_t cur_addr, hw_addr, next_addr; @@ -146,14 +147,13 @@ static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv, dev_priv->dma_high) { via_cmdbuf_rewind(dev_priv); } - if (via_cmdbuf_wait(dev_priv, size) != 0) { + if (via_cmdbuf_wait(dev_priv, size) != 0) return NULL; - } return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low); } -int via_dma_cleanup(struct drm_device * dev) +int via_dma_cleanup(struct drm_device *dev) { if (dev->dev_private) { drm_via_private_t *dev_priv = @@ -171,9 +171,9 @@ int via_dma_cleanup(struct drm_device * dev) return 0; } -static int via_initialize(struct drm_device * dev, - drm_via_private_t * dev_priv, - drm_via_dma_init_t * init) +static int via_initialize(struct drm_device *dev, + drm_via_private_t *dev_priv, + drm_via_dma_init_t *init) { if (!dev_priv || !dev_priv->mmio) { DRM_ERROR("via_dma_init called before via_map_init\n"); @@ -258,7 +258,7 @@ static int via_dma_init(struct drm_device *dev, void *data, struct drm_file *fil return retcode; } -static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * cmd) +static int via_dispatch_cmdbuffer(struct drm_device *dev, drm_via_cmdbuffer_t *cmd) { drm_via_private_t *dev_priv; uint32_t *vb; @@ -271,9 +271,8 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * return -EFAULT; } - if (cmd->size > VIA_PCI_BUF_SIZE) { + if (cmd->size > VIA_PCI_BUF_SIZE) return -ENOMEM; - } if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) return -EFAULT; @@ -291,9 +290,8 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * } vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size); - if (vb == NULL) { + if (vb == NULL) return -EAGAIN; - } memcpy(vb, dev_priv->pci_buf, cmd->size); @@ -311,13 +309,12 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * return 0; } -int via_driver_dma_quiescent(struct drm_device * dev) +int via_driver_dma_quiescent(struct drm_device *dev) { drm_via_private_t *dev_priv = dev->dev_private; - if (!via_wait_idle(dev_priv)) { + if (!via_wait_idle(dev_priv)) return -EBUSY; - } return 0; } @@ -339,22 +336,17 @@ static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *fi DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size); ret = via_dispatch_cmdbuffer(dev, cmdbuf); - if (ret) { - return ret; - } - - return 0; + return ret; } -static int via_dispatch_pci_cmdbuffer(struct drm_device * dev, - drm_via_cmdbuffer_t * cmd) +static int via_dispatch_pci_cmdbuffer(struct drm_device *dev, + drm_via_cmdbuffer_t *cmd) { drm_via_private_t *dev_priv = dev->dev_private; int ret; - if (cmd->size > VIA_PCI_BUF_SIZE) { + if (cmd->size > VIA_PCI_BUF_SIZE) return -ENOMEM; - } if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) return -EFAULT; @@ -380,19 +372,14 @@ static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size); ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf); - if (ret) { - return ret; - } - - return 0; + return ret; } -static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv, +static inline uint32_t *via_align_buffer(drm_via_private_t *dev_priv, uint32_t * vb, int qw_count) { - for (; qw_count > 0; --qw_count) { + for (; qw_count > 0; --qw_count) VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY); - } return vb; } @@ -401,7 +388,7 @@ static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv, * * Returns virtual pointer to ring buffer. */ -static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv) +static inline uint32_t *via_get_dma(drm_via_private_t *dev_priv) { return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low); } @@ -411,18 +398,18 @@ static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv) * modifying the pause address stored in the buffer itself. If * the regulator has already paused, restart it. */ -static int via_hook_segment(drm_via_private_t * dev_priv, +static int via_hook_segment(drm_via_private_t *dev_priv, uint32_t pause_addr_hi, uint32_t pause_addr_lo, int no_pci_fire) { int paused, count; volatile uint32_t *paused_at = dev_priv->last_pause_ptr; - uint32_t reader,ptr; + uint32_t reader, ptr; uint32_t diff; paused = 0; via_flush_write_combine(); - (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1); + (void) *(volatile uint32_t *)(via_get_dma(dev_priv) - 1); *paused_at = pause_addr_lo; via_flush_write_combine(); @@ -435,7 +422,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv, dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; /* - * If there is a possibility that the command reader will + * If there is a possibility that the command reader will * miss the new pause address and pause on the old one, * In that case we need to program the new start address * using PCI. @@ -443,9 +430,9 @@ static int via_hook_segment(drm_via_private_t * dev_priv, diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; count = 10000000; - while(diff == 0 && count--) { + while (diff == 0 && count--) { paused = (VIA_READ(0x41c) & 0x80000000); - if (paused) + if (paused) break; reader = *(dev_priv->hw_addr_ptr); diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff; @@ -477,7 +464,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv, return paused; } -static int via_wait_idle(drm_via_private_t * dev_priv) +static int via_wait_idle(drm_via_private_t *dev_priv) { int count = 10000000; @@ -491,9 +478,9 @@ static int via_wait_idle(drm_via_private_t * dev_priv) return count; } -static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type, - uint32_t addr, uint32_t * cmd_addr_hi, - uint32_t * cmd_addr_lo, int skip_wait) +static uint32_t *via_align_cmd(drm_via_private_t *dev_priv, uint32_t cmd_type, + uint32_t addr, uint32_t *cmd_addr_hi, + uint32_t *cmd_addr_lo, int skip_wait) { uint32_t agp_base; uint32_t cmd_addr, addr_lo, addr_hi; @@ -521,7 +508,7 @@ static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type, return vb; } -static void via_cmdbuf_start(drm_via_private_t * dev_priv) +static void via_cmdbuf_start(drm_via_private_t *dev_priv) { uint32_t pause_addr_lo, pause_addr_hi; uint32_t start_addr, start_addr_lo; @@ -580,7 +567,7 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) dev_priv->dma_diff = ptr - reader; } -static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) +static void via_pad_cache(drm_via_private_t *dev_priv, int qwords) { uint32_t *vb; @@ -590,7 +577,7 @@ static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) via_align_buffer(dev_priv, vb, qwords); } -static inline void via_dummy_bitblt(drm_via_private_t * dev_priv) +static inline void via_dummy_bitblt(drm_via_private_t *dev_priv) { uint32_t *vb = via_get_dma(dev_priv); SetReg2DAGP(0x0C, (0 | (0 << 16))); @@ -598,7 +585,7 @@ static inline void via_dummy_bitblt(drm_via_private_t * dev_priv) SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000); } -static void via_cmdbuf_jump(drm_via_private_t * dev_priv) +static void via_cmdbuf_jump(drm_via_private_t *dev_priv) { uint32_t agp_base; uint32_t pause_addr_lo, pause_addr_hi; @@ -617,9 +604,8 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) */ dev_priv->dma_low = 0; - if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) { + if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) DRM_ERROR("via_cmdbuf_jump failed\n"); - } via_dummy_bitblt(dev_priv); via_dummy_bitblt(dev_priv); @@ -657,12 +643,12 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) } -static void via_cmdbuf_rewind(drm_via_private_t * dev_priv) +static void via_cmdbuf_rewind(drm_via_private_t *dev_priv) { via_cmdbuf_jump(dev_priv); } -static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type) +static void via_cmdbuf_flush(drm_via_private_t *dev_priv, uint32_t cmd_type) { uint32_t pause_addr_lo, pause_addr_hi; @@ -670,12 +656,12 @@ static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type) via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); } -static void via_cmdbuf_pause(drm_via_private_t * dev_priv) +static void via_cmdbuf_pause(drm_via_private_t *dev_priv) { via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE); } -static void via_cmdbuf_reset(drm_via_private_t * dev_priv) +static void via_cmdbuf_reset(drm_via_private_t *dev_priv) { via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP); via_wait_idle(dev_priv); @@ -708,9 +694,8 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * case VIA_CMDBUF_SPACE: while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size) && --count) { - if (!d_siz->wait) { + if (!d_siz->wait) break; - } } if (!count) { DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n"); @@ -720,9 +705,8 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * case VIA_CMDBUF_LAG: while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size) && --count) { - if (!d_siz->wait) { + if (!d_siz->wait) break; - } } if (!count) { DRM_ERROR("VIA_CMDBUF_LAG timed out.\n"); diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c index 4c54f04..9b5b4d9 100644 --- a/drivers/gpu/drm/via/via_dmablit.c +++ b/drivers/gpu/drm/via/via_dmablit.c @@ -70,7 +70,7 @@ via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg) descriptor_this_page; dma_addr_t next = vsg->chain_start; - while(num_desc--) { + while (num_desc--) { if (descriptor_this_page-- == 0) { cur_descriptor_page--; descriptor_this_page = vsg->descriptors_per_page - 1; @@ -174,19 +174,19 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) struct page *page; int i; - switch(vsg->state) { + switch (vsg->state) { case dr_via_device_mapped: via_unmap_blit_from_device(pdev, vsg); case dr_via_desc_pages_alloc: - for (i=0; inum_desc_pages; ++i) { + for (i = 0; i < vsg->num_desc_pages; ++i) { if (vsg->desc_pages[i] != NULL) - free_page((unsigned long)vsg->desc_pages[i]); + free_page((unsigned long)vsg->desc_pages[i]); } kfree(vsg->desc_pages); case dr_via_pages_locked: - for (i=0; inum_pages; ++i) { - if ( NULL != (page = vsg->pages[i])) { - if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) + for (i = 0; i < vsg->num_pages; ++i) { + if (NULL != (page = vsg->pages[i])) { + if (!PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) SetPageDirty(page); page_cache_release(page); } @@ -232,7 +232,7 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) { int ret; unsigned long first_pfn = VIA_PFN(xfer->mem_addr); - vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride -1)) - + vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) - first_pfn + 1; if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages))) @@ -268,7 +268,7 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg) { int i; - vsg->descriptors_per_page = PAGE_SIZE / sizeof( drm_via_descriptor_t); + vsg->descriptors_per_page = PAGE_SIZE / sizeof(drm_via_descriptor_t); vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) / vsg->descriptors_per_page; @@ -276,7 +276,7 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg) return -ENOMEM; vsg->state = dr_via_desc_pages_alloc; - for (i=0; inum_desc_pages; ++i) { + for (i = 0; i < vsg->num_desc_pages; ++i) { if (NULL == (vsg->desc_pages[i] = (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL))) return -ENOMEM; @@ -318,21 +318,20 @@ via_dmablit_handler(struct drm_device *dev, int engine, int from_irq) drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; int cur; int done_transfer; - unsigned long irqsave=0; + unsigned long irqsave = 0; uint32_t status = 0; DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n", engine, from_irq, (unsigned long) blitq); - if (from_irq) { + if (from_irq) spin_lock(&blitq->blit_lock); - } else { + else spin_lock_irqsave(&blitq->blit_lock, irqsave); - } done_transfer = blitq->is_active && - (( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD); - done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE)); + ((status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD); + done_transfer = done_transfer || (blitq->aborting && !(status & VIA_DMA_CSR_DE)); cur = blitq->cur; if (done_transfer) { @@ -377,18 +376,16 @@ via_dmablit_handler(struct drm_device *dev, int engine, int from_irq) if (!timer_pending(&blitq->poll_timer)) mod_timer(&blitq->poll_timer, jiffies + 1); } else { - if (timer_pending(&blitq->poll_timer)) { + if (timer_pending(&blitq->poll_timer)) del_timer(&blitq->poll_timer); - } via_dmablit_engine_off(dev, engine); } } - if (from_irq) { + if (from_irq) spin_unlock(&blitq->blit_lock); - } else { + else spin_unlock_irqrestore(&blitq->blit_lock, irqsave); - } } @@ -414,10 +411,9 @@ via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_que ((blitq->cur_blit_handle - handle) <= (1 << 23)); if (queue && active) { - slot = handle - blitq->done_blit_handle + blitq->cur -1; - if (slot >= VIA_NUM_BLIT_SLOTS) { + slot = handle - blitq->done_blit_handle + blitq->cur - 1; + if (slot >= VIA_NUM_BLIT_SLOTS) slot -= VIA_NUM_BLIT_SLOTS; - } *queue = blitq->blit_queue + slot; } @@ -506,12 +502,12 @@ via_dmablit_workqueue(struct work_struct *work) int cur_released; - DRM_DEBUG("Workqueue task called for blit engine %ld\n",(unsigned long) + DRM_DEBUG("Workqueue task called for blit engine %ld\n", (unsigned long) (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues)); spin_lock_irqsave(&blitq->blit_lock, irqsave); - while(blitq->serviced != blitq->cur) { + while (blitq->serviced != blitq->cur) { cur_released = blitq->serviced++; @@ -545,13 +541,13 @@ via_dmablit_workqueue(struct work_struct *work) void via_init_dmablit(struct drm_device *dev) { - int i,j; + int i, j; drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; drm_via_blitq_t *blitq; pci_set_master(dev->pdev); - for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) { + for (i = 0; i < VIA_NUM_BLIT_ENGINES; ++i) { blitq = dev_priv->blit_queues + i; blitq->dev = dev; blitq->cur_blit_handle = 0; @@ -564,9 +560,8 @@ via_init_dmablit(struct drm_device *dev) blitq->is_active = 0; blitq->aborting = 0; spin_lock_init(&blitq->blit_lock); - for (j=0; jblit_queue + j); - } DRM_INIT_WAITQUEUE(&blitq->busy_queue); INIT_WORK(&blitq->wq, via_dmablit_workqueue); setup_timer(&blitq->poll_timer, via_dmablit_timer, @@ -685,18 +680,17 @@ via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg, drm_via_dmabli static int via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine) { - int ret=0; + int ret = 0; unsigned long irqsave; DRM_DEBUG("Num free is %d\n", blitq->num_free); spin_lock_irqsave(&blitq->blit_lock, irqsave); - while(blitq->num_free == 0) { + while (blitq->num_free == 0) { spin_unlock_irqrestore(&blitq->blit_lock, irqsave); DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0); - if (ret) { + if (ret) return (-EINTR == ret) ? -EAGAIN : ret; - } spin_lock_irqsave(&blitq->blit_lock, irqsave); } @@ -719,7 +713,7 @@ via_dmablit_release_slot(drm_via_blitq_t *blitq) spin_lock_irqsave(&blitq->blit_lock, irqsave); blitq->num_free++; spin_unlock_irqrestore(&blitq->blit_lock, irqsave); - DRM_WAKEUP( &blitq->busy_queue ); + DRM_WAKEUP(&blitq->busy_queue); } /* @@ -744,9 +738,8 @@ via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer) engine = (xfer->to_fb) ? 0 : 1; blitq = dev_priv->blit_queues + engine; - if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) { + if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) return ret; - } if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) { via_dmablit_release_slot(blitq); return -ENOMEM; @@ -780,7 +773,7 @@ via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer) */ int -via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv ) +via_dma_blit_sync(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_via_blitsync_t *sync = data; int err; @@ -804,7 +797,7 @@ via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_pri */ int -via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv ) +via_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_via_dmablit_t *xfer = data; int err; diff --git a/drivers/gpu/drm/via/via_dmablit.h b/drivers/gpu/drm/via/via_dmablit.h index 7408a54..9b662a3 100644 --- a/drivers/gpu/drm/via/via_dmablit.h +++ b/drivers/gpu/drm/via/via_dmablit.h @@ -45,12 +45,12 @@ typedef struct _drm_via_sg_info { int num_desc; enum dma_data_direction direction; unsigned char *bounce_buffer; - dma_addr_t chain_start; + dma_addr_t chain_start; uint32_t free_on_sequence; - unsigned int descriptors_per_page; + unsigned int descriptors_per_page; int aborted; enum { - dr_via_device_mapped, + dr_via_device_mapped, dr_via_desc_pages_alloc, dr_via_pages_locked, dr_via_pages_alloc, @@ -68,7 +68,7 @@ typedef struct _drm_via_blitq { unsigned num_free; unsigned num_outstanding; unsigned long end; - int aborting; + int aborting; int is_active; drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS]; spinlock_t blit_lock; diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h index cafcb84..9cf87d9 100644 --- a/drivers/gpu/drm/via/via_drv.h +++ b/drivers/gpu/drm/via/via_drv.h @@ -107,9 +107,9 @@ enum via_family { #define VIA_BASE ((dev_priv->mmio)) #define VIA_READ(reg) DRM_READ32(VIA_BASE, reg) -#define VIA_WRITE(reg,val) DRM_WRITE32(VIA_BASE, reg, val) +#define VIA_WRITE(reg, val) DRM_WRITE32(VIA_BASE, reg, val) #define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) -#define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val) +#define VIA_WRITE8(reg, val) DRM_WRITE8(VIA_BASE, reg, val) extern struct drm_ioctl_desc via_ioctls[]; extern int via_max_ioctl; @@ -121,28 +121,28 @@ extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *fil extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv ); -extern int via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv ); +extern int via_dma_blit_sync(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int via_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int via_driver_load(struct drm_device *dev, unsigned long chipset); extern int via_driver_unload(struct drm_device *dev); -extern int via_init_context(struct drm_device * dev, int context); -extern int via_final_context(struct drm_device * dev, int context); +extern int via_init_context(struct drm_device *dev, int context); +extern int via_final_context(struct drm_device *dev, int context); -extern int via_do_cleanup_map(struct drm_device * dev); +extern int via_do_cleanup_map(struct drm_device *dev); extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); extern int via_enable_vblank(struct drm_device *dev, int crtc); extern void via_disable_vblank(struct drm_device *dev, int crtc); extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); -extern void via_driver_irq_preinstall(struct drm_device * dev); +extern void via_driver_irq_preinstall(struct drm_device *dev); extern int via_driver_irq_postinstall(struct drm_device *dev); -extern void via_driver_irq_uninstall(struct drm_device * dev); +extern void via_driver_irq_uninstall(struct drm_device *dev); -extern int via_dma_cleanup(struct drm_device * dev); +extern int via_dma_cleanup(struct drm_device *dev); extern void via_init_command_verifier(void); -extern int via_driver_dma_quiescent(struct drm_device * dev); +extern int via_driver_dma_quiescent(struct drm_device *dev); extern void via_init_futex(drm_via_private_t *dev_priv); extern void via_cleanup_futex(drm_via_private_t *dev_priv); extern void via_release_futex(drm_via_private_t *dev_priv, int context); diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index 34079f2..d391f48 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c @@ -141,11 +141,10 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) atomic_inc(&cur_irq->irq_received); DRM_WAKEUP(&cur_irq->irq_queue); handled = 1; - if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) { + if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) via_dmablit_handler(dev, 0, 1); - } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) { + else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) via_dmablit_handler(dev, 1, 1); - } } cur_irq++; } @@ -160,7 +159,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_NONE; } -static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) +static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t *dev_priv) { u32 status; @@ -207,7 +206,7 @@ void via_disable_vblank(struct drm_device *dev, int crtc) } static int -via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequence, +via_driver_irq_wait(struct drm_device *dev, unsigned int irq, int force_sequence, unsigned int *sequence) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; @@ -260,7 +259,7 @@ via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequenc * drm_dma.h hooks */ -void via_driver_irq_preinstall(struct drm_device * dev) +void via_driver_irq_preinstall(struct drm_device *dev) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; @@ -329,7 +328,7 @@ int via_driver_irq_postinstall(struct drm_device *dev) return 0; } -void via_driver_irq_uninstall(struct drm_device * dev) +void via_driver_irq_uninstall(struct drm_device *dev) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index 6e6f915..6cca9a7 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c @@ -25,7 +25,7 @@ #include "via_drm.h" #include "via_drv.h" -static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init) +static int via_do_init_map(struct drm_device *dev, drm_via_init_t *init) { drm_via_private_t *dev_priv = dev->dev_private; @@ -68,7 +68,7 @@ static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init) return 0; } -int via_do_cleanup_map(struct drm_device * dev) +int via_do_cleanup_map(struct drm_device *dev) { via_dma_cleanup(dev); diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c index f694cb5..6cc2dad 100644 --- a/drivers/gpu/drm/via/via_mm.c +++ b/drivers/gpu/drm/via/via_mm.c @@ -31,7 +31,7 @@ #include "drm_sman.h" #define VIA_MM_ALIGN_SHIFT 4 -#define VIA_MM_ALIGN_MASK ( (1 << VIA_MM_ALIGN_SHIFT) - 1) +#define VIA_MM_ALIGN_MASK ((1 << VIA_MM_ALIGN_SHIFT) - 1) int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -172,7 +172,7 @@ int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) } -void via_reclaim_buffers_locked(struct drm_device * dev, +void via_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv) { drm_via_private_t *dev_priv = dev->dev_private; @@ -183,9 +183,8 @@ void via_reclaim_buffers_locked(struct drm_device * dev, return; } - if (dev->driver->dma_quiescent) { + if (dev->driver->dma_quiescent) dev->driver->dma_quiescent(dev); - } drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/via/via_verifier.c b/drivers/gpu/drm/via/via_verifier.c index 46a5791..48957b8 100644 --- a/drivers/gpu/drm/via/via_verifier.c +++ b/drivers/gpu/drm/via/via_verifier.c @@ -235,7 +235,7 @@ static hazard_t table2[256]; static hazard_t table3[256]; static __inline__ int -eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) +eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words) { if ((buf_end - *buf) >= num_words) { *buf += num_words; @@ -252,7 +252,7 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq, unsigned long offset, unsigned long size, - struct drm_device * dev) + struct drm_device *dev) { struct drm_map_list *r_list; drm_local_map_t *map = seq->map_cache; @@ -344,7 +344,7 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq) } static __inline__ int -investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq) +investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq) { register uint32_t tmp, *tmp_addr; @@ -518,7 +518,7 @@ investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq) static __inline__ int via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end, - drm_via_state_t * cur_seq) + drm_via_state_t *cur_seq) { drm_via_private_t *dev_priv = (drm_via_private_t *) cur_seq->dev->dev_private; @@ -621,8 +621,8 @@ via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end, } static __inline__ verifier_state_t -via_check_header2(uint32_t const **buffer, const uint32_t * buf_end, - drm_via_state_t * hc_state) +via_check_header2(uint32_t const **buffer, const uint32_t *buf_end, + drm_via_state_t *hc_state) { uint32_t cmd; int hz_mode; @@ -706,16 +706,15 @@ via_check_header2(uint32_t const **buffer, const uint32_t * buf_end, return state_error; } } - if (hc_state->unfinished && finish_current_sequence(hc_state)) { + if (hc_state->unfinished && finish_current_sequence(hc_state)) return state_error; - } *buffer = buf; return state_command; } static __inline__ verifier_state_t -via_parse_header2(drm_via_private_t * dev_priv, uint32_t const **buffer, - const uint32_t * buf_end, int *fire_count) +via_parse_header2(drm_via_private_t *dev_priv, uint32_t const **buffer, + const uint32_t *buf_end, int *fire_count) { uint32_t cmd; const uint32_t *buf = *buffer; @@ -833,8 +832,8 @@ via_check_header1(uint32_t const **buffer, const uint32_t * buf_end) } static __inline__ verifier_state_t -via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer, - const uint32_t * buf_end) +via_parse_header1(drm_via_private_t *dev_priv, uint32_t const **buffer, + const uint32_t *buf_end) { register uint32_t cmd; const uint32_t *buf = *buffer; @@ -851,7 +850,7 @@ via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer, } static __inline__ verifier_state_t -via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end) +via_check_vheader5(uint32_t const **buffer, const uint32_t *buf_end) { uint32_t data; const uint32_t *buf = *buffer; @@ -884,8 +883,8 @@ via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end) } static __inline__ verifier_state_t -via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer, - const uint32_t * buf_end) +via_parse_vheader5(drm_via_private_t *dev_priv, uint32_t const **buffer, + const uint32_t *buf_end) { uint32_t addr, count, i; const uint32_t *buf = *buffer; @@ -893,9 +892,8 @@ via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer, addr = *buf++ & ~VIA_VIDEOMASK; i = count = *buf; buf += 3; - while (i--) { + while (i--) VIA_WRITE(addr, *buf++); - } if (count & 3) buf += 4 - (count & 3); *buffer = buf; @@ -940,8 +938,8 @@ via_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end) } static __inline__ verifier_state_t -via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer, - const uint32_t * buf_end) +via_parse_vheader6(drm_via_private_t *dev_priv, uint32_t const **buffer, + const uint32_t *buf_end) { uint32_t addr, count, i; @@ -1037,7 +1035,7 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, } int -via_parse_command_stream(struct drm_device * dev, const uint32_t * buf, +via_parse_command_stream(struct drm_device *dev, const uint32_t *buf, unsigned int size) { @@ -1085,9 +1083,8 @@ via_parse_command_stream(struct drm_device * dev, const uint32_t * buf, return -EINVAL; } } - if (state == state_error) { + if (state == state_error) return -EINVAL; - } return 0; } @@ -1096,13 +1093,11 @@ setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size) { int i; - for (i = 0; i < 256; ++i) { + for (i = 0; i < 256; ++i) table[i] = forbidden_command; - } - for (i = 0; i < size; ++i) { + for (i = 0; i < size; ++i) table[init_table[i].code] = init_table[i].hz; - } } void via_init_command_verifier(void) diff --git a/drivers/gpu/drm/via/via_verifier.h b/drivers/gpu/drm/via/via_verifier.h index d6f8214..26b6d36 100644 --- a/drivers/gpu/drm/via/via_verifier.h +++ b/drivers/gpu/drm/via/via_verifier.h @@ -54,8 +54,8 @@ typedef struct { const uint32_t *buf_start; } drm_via_state_t; -extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, - struct drm_device * dev, int agp); +extern int via_verify_command_stream(const uint32_t *buf, unsigned int size, + struct drm_device *dev, int agp); extern int via_parse_command_stream(struct drm_device *dev, const uint32_t *buf, unsigned int size); diff --git a/drivers/gpu/drm/via/via_video.c b/drivers/gpu/drm/via/via_video.c index 6efac81..675d311 100644 --- a/drivers/gpu/drm/via/via_video.c +++ b/drivers/gpu/drm/via/via_video.c @@ -29,7 +29,7 @@ #include "via_drm.h" #include "via_drv.h" -void via_init_futex(drm_via_private_t * dev_priv) +void via_init_futex(drm_via_private_t *dev_priv) { unsigned int i; @@ -41,11 +41,11 @@ void via_init_futex(drm_via_private_t * dev_priv) } } -void via_cleanup_futex(drm_via_private_t * dev_priv) +void via_cleanup_futex(drm_via_private_t *dev_priv) { } -void via_release_futex(drm_via_private_t * dev_priv, int context) +void via_release_futex(drm_via_private_t *dev_priv, int context) { unsigned int i; volatile int *lock; -- cgit v0.10.2 From f2b2cb790ee873b6853ec99478d68dd9cd083132 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Mon, 12 Jul 2010 01:46:57 +0200 Subject: drm/mga: fixed brace, macro and spacing coding style issues Fixed brace, macro and spacing coding style issues. Signed-off-by: Nicolas Kaiser Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c index ccc129c..08868ac 100644 --- a/drivers/gpu/drm/mga/mga_dma.c +++ b/drivers/gpu/drm/mga/mga_dma.c @@ -52,7 +52,7 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup); * Engine control */ -int mga_do_wait_for_idle(drm_mga_private_t * dev_priv) +int mga_do_wait_for_idle(drm_mga_private_t *dev_priv) { u32 status = 0; int i; @@ -74,7 +74,7 @@ int mga_do_wait_for_idle(drm_mga_private_t * dev_priv) return -EBUSY; } -static int mga_do_dma_reset(drm_mga_private_t * dev_priv) +static int mga_do_dma_reset(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_primary_buffer_t *primary = &dev_priv->prim; @@ -102,7 +102,7 @@ static int mga_do_dma_reset(drm_mga_private_t * dev_priv) * Primary DMA stream */ -void mga_do_dma_flush(drm_mga_private_t * dev_priv) +void mga_do_dma_flush(drm_mga_private_t *dev_priv) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; @@ -142,11 +142,10 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv) head = MGA_READ(MGA_PRIMADDRESS); - if (head <= tail) { + if (head <= tail) primary->space = primary->size - primary->tail; - } else { + else primary->space = head - tail; - } DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); DRM_DEBUG(" tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset)); @@ -158,7 +157,7 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv) DRM_DEBUG("done.\n"); } -void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) +void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; @@ -181,11 +180,10 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) head = MGA_READ(MGA_PRIMADDRESS); - if (head == dev_priv->primary->offset) { + if (head == dev_priv->primary->offset) primary->space = primary->size; - } else { + else primary->space = head - dev_priv->primary->offset; - } DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); DRM_DEBUG(" tail = 0x%06x\n", primary->tail); @@ -199,7 +197,7 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv) DRM_DEBUG("done.\n"); } -void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv) +void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -220,11 +218,11 @@ void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv) * Freelist management */ -#define MGA_BUFFER_USED ~0 +#define MGA_BUFFER_USED (~0) #define MGA_BUFFER_FREE 0 #if MGA_FREELIST_DEBUG -static void mga_freelist_print(struct drm_device * dev) +static void mga_freelist_print(struct drm_device *dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; @@ -245,7 +243,7 @@ static void mga_freelist_print(struct drm_device * dev) } #endif -static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_priv) +static int mga_freelist_init(struct drm_device *dev, drm_mga_private_t *dev_priv) { struct drm_device_dma *dma = dev->dma; struct drm_buf *buf; @@ -288,7 +286,7 @@ static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_pr return 0; } -static void mga_freelist_cleanup(struct drm_device * dev) +static void mga_freelist_cleanup(struct drm_device *dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; @@ -308,7 +306,7 @@ static void mga_freelist_cleanup(struct drm_device * dev) #if 0 /* FIXME: Still needed? */ -static void mga_freelist_reset(struct drm_device * dev) +static void mga_freelist_reset(struct drm_device *dev) { struct drm_device_dma *dma = dev->dma; struct drm_buf *buf; @@ -356,7 +354,7 @@ static struct drm_buf *mga_freelist_get(struct drm_device * dev) return NULL; } -int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf) +int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; @@ -391,7 +389,7 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf) * DMA initialization, cleanup */ -int mga_driver_load(struct drm_device * dev, unsigned long flags) +int mga_driver_load(struct drm_device *dev, unsigned long flags) { drm_mga_private_t *dev_priv; int ret; @@ -439,8 +437,8 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags) * * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap */ -static int mga_do_agp_dma_bootstrap(struct drm_device * dev, - drm_mga_dma_bootstrap_t * dma_bs) +static int mga_do_agp_dma_bootstrap(struct drm_device *dev, + drm_mga_dma_bootstrap_t *dma_bs) { drm_mga_private_t *const dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -481,11 +479,10 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev, */ if (dev_priv->chipset == MGA_CARD_TYPE_G200) { - if (mode.mode & 0x02) { + if (mode.mode & 0x02) MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE); - } else { + else MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE); - } } /* Allocate and bind AGP memory. */ @@ -593,8 +590,8 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev, return 0; } #else -static int mga_do_agp_dma_bootstrap(struct drm_device * dev, - drm_mga_dma_bootstrap_t * dma_bs) +static int mga_do_agp_dma_bootstrap(struct drm_device *dev, + drm_mga_dma_bootstrap_t *dma_bs) { return -EINVAL; } @@ -614,8 +611,8 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev, * * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap */ -static int mga_do_pci_dma_bootstrap(struct drm_device * dev, - drm_mga_dma_bootstrap_t * dma_bs) +static int mga_do_pci_dma_bootstrap(struct drm_device *dev, + drm_mga_dma_bootstrap_t *dma_bs) { drm_mga_private_t *const dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -678,9 +675,8 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev, req.size = dma_bs->secondary_bin_size; err = drm_addbufs_pci(dev, &req); - if (!err) { + if (!err) break; - } } if (bin_count == 0) { @@ -704,8 +700,8 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev, return 0; } -static int mga_do_dma_bootstrap(struct drm_device * dev, - drm_mga_dma_bootstrap_t * dma_bs) +static int mga_do_dma_bootstrap(struct drm_device *dev, + drm_mga_dma_bootstrap_t *dma_bs) { const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev); int err; @@ -737,17 +733,15 @@ static int mga_do_dma_bootstrap(struct drm_device * dev, * carve off portions of it for internal uses. The remaining memory * is returned to user-mode to be used for AGP textures. */ - if (is_agp) { + if (is_agp) err = mga_do_agp_dma_bootstrap(dev, dma_bs); - } /* If we attempted to initialize the card for AGP DMA but failed, * clean-up any mess that may have been created. */ - if (err) { + if (err) mga_do_cleanup_dma(dev, MINIMAL_CLEANUP); - } /* Not only do we want to try and initialized PCI cards for PCI DMA, * but we also try to initialized AGP cards that could not be @@ -757,9 +751,8 @@ static int mga_do_dma_bootstrap(struct drm_device * dev, * AGP memory, etc. */ - if (!is_agp || err) { + if (!is_agp || err) err = mga_do_pci_dma_bootstrap(dev, dma_bs); - } return err; } @@ -792,7 +785,7 @@ int mga_dma_bootstrap(struct drm_device *dev, void *data, return err; } -static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init) +static int mga_do_init_dma(struct drm_device *dev, drm_mga_init_t *init) { drm_mga_private_t *dev_priv; int ret; @@ -800,11 +793,10 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init) dev_priv = dev->dev_private; - if (init->sgram) { + if (init->sgram) dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; - } else { + else dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; - } dev_priv->maccess = init->maccess; dev_priv->fb_cpp = init->fb_cpp; @@ -975,9 +967,8 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup) dev_priv->agp_handle = 0; } - if ((dev->agp != NULL) && dev->agp->acquired) { + if ((dev->agp != NULL) && dev->agp->acquired) err = drm_agp_release(dev); - } #endif } @@ -998,9 +989,8 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup) memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); - if (dev_priv->head != NULL) { + if (dev_priv->head != NULL) mga_freelist_cleanup(dev); - } } return err; @@ -1017,9 +1007,8 @@ int mga_dma_init(struct drm_device *dev, void *data, switch (init->func) { case MGA_INIT_DMA: err = mga_do_init_dma(dev, init); - if (err) { + if (err) (void)mga_do_cleanup_dma(dev, FULL_CLEANUP); - } return err; case MGA_CLEANUP_DMA: return mga_do_cleanup_dma(dev, FULL_CLEANUP); @@ -1047,9 +1036,8 @@ int mga_dma_flush(struct drm_device *dev, void *data, WRAP_WAIT_WITH_RETURN(dev_priv); - if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) { + if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) mga_do_dma_flush(dev_priv); - } if (lock->flags & _DRM_LOCK_QUIESCENT) { #if MGA_DMA_DEBUG @@ -1079,8 +1067,8 @@ int mga_dma_reset(struct drm_device *dev, void *data, * DMA buffer management */ -static int mga_dma_get_buffers(struct drm_device * dev, - struct drm_file *file_priv, struct drm_dma * d) +static int mga_dma_get_buffers(struct drm_device *dev, + struct drm_file *file_priv, struct drm_dma *d) { struct drm_buf *buf; int i; @@ -1134,9 +1122,8 @@ int mga_dma_buffers(struct drm_device *dev, void *data, d->granted_count = 0; - if (d->request_count) { + if (d->request_count) ret = mga_dma_get_buffers(dev, file_priv, d); - } return ret; } @@ -1144,7 +1131,7 @@ int mga_dma_buffers(struct drm_device *dev, void *data, /** * Called just before the module is unloaded. */ -int mga_driver_unload(struct drm_device * dev) +int mga_driver_unload(struct drm_device *dev) { kfree(dev->dev_private); dev->dev_private = NULL; @@ -1155,12 +1142,12 @@ int mga_driver_unload(struct drm_device * dev) /** * Called when the last opener of the device is closed. */ -void mga_driver_lastclose(struct drm_device * dev) +void mga_driver_lastclose(struct drm_device *dev) { mga_do_cleanup_dma(dev, FULL_CLEANUP); } -int mga_driver_dma_quiescent(struct drm_device * dev) +int mga_driver_dma_quiescent(struct drm_device *dev) { drm_mga_private_t *dev_priv = dev->dev_private; return mga_do_wait_for_idle(dev_priv); diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c index ddfe161..26d0d8c 100644 --- a/drivers/gpu/drm/mga/mga_drv.c +++ b/drivers/gpu/drm/mga/mga_drv.c @@ -36,7 +36,7 @@ #include "drm_pciids.h" -static int mga_driver_device_is_agp(struct drm_device * dev); +static int mga_driver_device_is_agp(struct drm_device *dev); static struct pci_device_id pciidlist[] = { mga_PCI_IDS @@ -119,7 +119,7 @@ MODULE_LICENSE("GPL and additional rights"); * \returns * If the device is a PCI G450, zero is returned. Otherwise 2 is returned. */ -static int mga_driver_device_is_agp(struct drm_device * dev) +static int mga_driver_device_is_agp(struct drm_device *dev) { const struct pci_dev *const pdev = dev->pdev; diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h index be6c6b9..1084fa4 100644 --- a/drivers/gpu/drm/mga/mga_drv.h +++ b/drivers/gpu/drm/mga/mga_drv.h @@ -164,59 +164,59 @@ extern int mga_dma_reset(struct drm_device *dev, void *data, extern int mga_dma_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int mga_driver_load(struct drm_device *dev, unsigned long flags); -extern int mga_driver_unload(struct drm_device * dev); -extern void mga_driver_lastclose(struct drm_device * dev); -extern int mga_driver_dma_quiescent(struct drm_device * dev); +extern int mga_driver_unload(struct drm_device *dev); +extern void mga_driver_lastclose(struct drm_device *dev); +extern int mga_driver_dma_quiescent(struct drm_device *dev); -extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); +extern int mga_do_wait_for_idle(drm_mga_private_t *dev_priv); -extern void mga_do_dma_flush(drm_mga_private_t * dev_priv); -extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv); -extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv); +extern void mga_do_dma_flush(drm_mga_private_t *dev_priv); +extern void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv); +extern void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv); -extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf); +extern int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf); /* mga_warp.c */ -extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); -extern int mga_warp_init(drm_mga_private_t * dev_priv); +extern int mga_warp_install_microcode(drm_mga_private_t *dev_priv); +extern int mga_warp_init(drm_mga_private_t *dev_priv); /* mga_irq.c */ extern int mga_enable_vblank(struct drm_device *dev, int crtc); extern void mga_disable_vblank(struct drm_device *dev, int crtc); extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); -extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); -extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); +extern int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence); +extern int mga_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence); extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); -extern void mga_driver_irq_preinstall(struct drm_device * dev); +extern void mga_driver_irq_preinstall(struct drm_device *dev); extern int mga_driver_irq_postinstall(struct drm_device *dev); -extern void mga_driver_irq_uninstall(struct drm_device * dev); +extern void mga_driver_irq_uninstall(struct drm_device *dev); extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); #define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() #if defined(__linux__) && defined(__alpha__) -#define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle)) -#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg) +#define MGA_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) +#define MGA_ADDR(reg) (MGA_BASE(reg) + reg) -#define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg ) -#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg ) +#define MGA_DEREF(reg) (*(volatile u32 *)MGA_ADDR(reg)) +#define MGA_DEREF8(reg) (*(volatile u8 *)MGA_ADDR(reg)) -#define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg))) -#define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg))) -#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0) -#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0) +#define MGA_READ(reg) (_MGA_READ((u32 *)MGA_ADDR(reg))) +#define MGA_READ8(reg) (_MGA_READ((u8 *)MGA_ADDR(reg))) +#define MGA_WRITE(reg, val) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF(reg) = val; } while (0) +#define MGA_WRITE8(reg, val) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8(reg) = val; } while (0) -static inline u32 _MGA_READ(u32 * addr) +static inline u32 _MGA_READ(u32 *addr) { DRM_MEMORYBARRIER(); return *(volatile u32 *)addr; } #else -#define MGA_READ8( reg ) DRM_READ8(dev_priv->mmio, (reg)) -#define MGA_READ( reg ) DRM_READ32(dev_priv->mmio, (reg)) -#define MGA_WRITE8( reg, val ) DRM_WRITE8(dev_priv->mmio, (reg), (val)) -#define MGA_WRITE( reg, val ) DRM_WRITE32(dev_priv->mmio, (reg), (val)) +#define MGA_READ8(reg) DRM_READ8(dev_priv->mmio, (reg)) +#define MGA_READ(reg) DRM_READ32(dev_priv->mmio, (reg)) +#define MGA_WRITE8(reg, val) DRM_WRITE8(dev_priv->mmio, (reg), (val)) +#define MGA_WRITE(reg, val) DRM_WRITE32(dev_priv->mmio, (reg), (val)) #endif #define DWGREG0 0x1c00 @@ -233,40 +233,39 @@ static inline u32 _MGA_READ(u32 * addr) * Helper macross... */ -#define MGA_EMIT_STATE( dev_priv, dirty ) \ +#define MGA_EMIT_STATE(dev_priv, dirty) \ do { \ - if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) { \ - if ( dev_priv->chipset >= MGA_CARD_TYPE_G400 ) { \ - mga_g400_emit_state( dev_priv ); \ - } else { \ - mga_g200_emit_state( dev_priv ); \ - } \ + if ((dirty) & ~MGA_UPLOAD_CLIPRECTS) { \ + if (dev_priv->chipset >= MGA_CARD_TYPE_G400) \ + mga_g400_emit_state(dev_priv); \ + else \ + mga_g200_emit_state(dev_priv); \ } \ } while (0) -#define WRAP_TEST_WITH_RETURN( dev_priv ) \ +#define WRAP_TEST_WITH_RETURN(dev_priv) \ do { \ - if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ - if ( mga_is_idle( dev_priv ) ) { \ - mga_do_dma_wrap_end( dev_priv ); \ - } else if ( dev_priv->prim.space < \ - dev_priv->prim.high_mark ) { \ - if ( MGA_DMA_DEBUG ) \ - DRM_INFO( "wrap...\n"); \ - return -EBUSY; \ + if (test_bit(0, &dev_priv->prim.wrapped)) { \ + if (mga_is_idle(dev_priv)) { \ + mga_do_dma_wrap_end(dev_priv); \ + } else if (dev_priv->prim.space < \ + dev_priv->prim.high_mark) { \ + if (MGA_DMA_DEBUG) \ + DRM_INFO("wrap...\n"); \ + return -EBUSY; \ } \ } \ } while (0) -#define WRAP_WAIT_WITH_RETURN( dev_priv ) \ +#define WRAP_WAIT_WITH_RETURN(dev_priv) \ do { \ - if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \ - if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \ - if ( MGA_DMA_DEBUG ) \ - DRM_INFO( "wrap...\n"); \ - return -EBUSY; \ + if (test_bit(0, &dev_priv->prim.wrapped)) { \ + if (mga_do_wait_for_idle(dev_priv) < 0) { \ + if (MGA_DMA_DEBUG) \ + DRM_INFO("wrap...\n"); \ + return -EBUSY; \ } \ - mga_do_dma_wrap_end( dev_priv ); \ + mga_do_dma_wrap_end(dev_priv); \ } \ } while (0) @@ -280,12 +279,12 @@ do { \ #define DMA_BLOCK_SIZE (5 * sizeof(u32)) -#define BEGIN_DMA( n ) \ +#define BEGIN_DMA(n) \ do { \ - if ( MGA_VERBOSE ) { \ - DRM_INFO( "BEGIN_DMA( %d )\n", (n) ); \ - DRM_INFO( " space=0x%x req=0x%Zx\n", \ - dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \ + if (MGA_VERBOSE) { \ + DRM_INFO("BEGIN_DMA(%d)\n", (n)); \ + DRM_INFO(" space=0x%x req=0x%Zx\n", \ + dev_priv->prim.space, (n) * DMA_BLOCK_SIZE); \ } \ prim = dev_priv->prim.start; \ write = dev_priv->prim.tail; \ @@ -293,9 +292,9 @@ do { \ #define BEGIN_DMA_WRAP() \ do { \ - if ( MGA_VERBOSE ) { \ - DRM_INFO( "BEGIN_DMA()\n" ); \ - DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \ + if (MGA_VERBOSE) { \ + DRM_INFO("BEGIN_DMA()\n"); \ + DRM_INFO(" space=0x%x\n", dev_priv->prim.space); \ } \ prim = dev_priv->prim.start; \ write = dev_priv->prim.tail; \ @@ -304,72 +303,68 @@ do { \ #define ADVANCE_DMA() \ do { \ dev_priv->prim.tail = write; \ - if ( MGA_VERBOSE ) { \ - DRM_INFO( "ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \ - write, dev_priv->prim.space ); \ - } \ + if (MGA_VERBOSE) \ + DRM_INFO("ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \ + write, dev_priv->prim.space); \ } while (0) #define FLUSH_DMA() \ do { \ - if ( 0 ) { \ - DRM_INFO( "\n" ); \ - DRM_INFO( " tail=0x%06x head=0x%06lx\n", \ - dev_priv->prim.tail, \ - (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \ - dev_priv->primary->offset)); \ + if (0) { \ + DRM_INFO("\n"); \ + DRM_INFO(" tail=0x%06x head=0x%06lx\n", \ + dev_priv->prim.tail, \ + (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \ + dev_priv->primary->offset)); \ } \ - if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) { \ - if ( dev_priv->prim.space < \ - dev_priv->prim.high_mark ) { \ - mga_do_dma_wrap_start( dev_priv ); \ - } else { \ - mga_do_dma_flush( dev_priv ); \ - } \ + if (!test_bit(0, &dev_priv->prim.wrapped)) { \ + if (dev_priv->prim.space < dev_priv->prim.high_mark) \ + mga_do_dma_wrap_start(dev_priv); \ + else \ + mga_do_dma_flush(dev_priv); \ } \ } while (0) /* Never use this, always use DMA_BLOCK(...) for primary DMA output. */ -#define DMA_WRITE( offset, val ) \ +#define DMA_WRITE(offset, val) \ do { \ - if ( MGA_VERBOSE ) { \ - DRM_INFO( " DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \ - (u32)(val), write + (offset) * sizeof(u32) ); \ - } \ + if (MGA_VERBOSE) \ + DRM_INFO(" DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \ + (u32)(val), write + (offset) * sizeof(u32)); \ *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \ } while (0) -#define DMA_BLOCK( reg0, val0, reg1, val1, reg2, val2, reg3, val3 ) \ +#define DMA_BLOCK(reg0, val0, reg1, val1, reg2, val2, reg3, val3) \ do { \ - DMA_WRITE( 0, ((DMAREG( reg0 ) << 0) | \ - (DMAREG( reg1 ) << 8) | \ - (DMAREG( reg2 ) << 16) | \ - (DMAREG( reg3 ) << 24)) ); \ - DMA_WRITE( 1, val0 ); \ - DMA_WRITE( 2, val1 ); \ - DMA_WRITE( 3, val2 ); \ - DMA_WRITE( 4, val3 ); \ + DMA_WRITE(0, ((DMAREG(reg0) << 0) | \ + (DMAREG(reg1) << 8) | \ + (DMAREG(reg2) << 16) | \ + (DMAREG(reg3) << 24))); \ + DMA_WRITE(1, val0); \ + DMA_WRITE(2, val1); \ + DMA_WRITE(3, val2); \ + DMA_WRITE(4, val3); \ write += DMA_BLOCK_SIZE; \ } while (0) /* Buffer aging via primary DMA stream head pointer. */ -#define SET_AGE( age, h, w ) \ +#define SET_AGE(age, h, w) \ do { \ (age)->head = h; \ (age)->wrap = w; \ } while (0) -#define TEST_AGE( age, h, w ) ( (age)->wrap < w || \ - ( (age)->wrap == w && \ - (age)->head < h ) ) +#define TEST_AGE(age, h, w) ((age)->wrap < w || \ + ((age)->wrap == w && \ + (age)->head < h)) -#define AGE_BUFFER( buf_priv ) \ +#define AGE_BUFFER(buf_priv) \ do { \ drm_mga_freelist_t *entry = (buf_priv)->list_entry; \ - if ( (buf_priv)->dispatched ) { \ + if ((buf_priv)->dispatched) { \ entry->age.head = (dev_priv->prim.tail + \ dev_priv->primary->offset); \ entry->age.wrap = dev_priv->sarea_priv->last_wrap; \ @@ -681,7 +676,7 @@ do { \ /* Simple idle test. */ -static __inline__ int mga_is_idle(drm_mga_private_t * dev_priv) +static __inline__ int mga_is_idle(drm_mga_private_t *dev_priv) { u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; return (status == MGA_ENDPRDMASTS); diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c index daa6041..2581202 100644 --- a/drivers/gpu/drm/mga/mga_irq.c +++ b/drivers/gpu/drm/mga/mga_irq.c @@ -76,9 +76,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) /* In addition to clearing the interrupt-pending bit, we * have to write to MGA_PRIMEND to re-start the DMA operation. */ - if ((prim_start & ~0x03) != (prim_end & ~0x03)) { + if ((prim_start & ~0x03) != (prim_end & ~0x03)) MGA_WRITE(MGA_PRIMEND, prim_end); - } atomic_inc(&dev_priv->last_fence_retired); DRM_WAKEUP(&dev_priv->fence_queue); @@ -120,7 +119,7 @@ void mga_disable_vblank(struct drm_device *dev, int crtc) /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ } -int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) +int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; unsigned int cur_fence; @@ -139,7 +138,7 @@ int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) return ret; } -void mga_driver_irq_preinstall(struct drm_device * dev) +void mga_driver_irq_preinstall(struct drm_device *dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -162,7 +161,7 @@ int mga_driver_irq_postinstall(struct drm_device *dev) return 0; } -void mga_driver_irq_uninstall(struct drm_device * dev) +void mga_driver_irq_uninstall(struct drm_device *dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; if (!dev_priv) diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c index a53b848..fff8204 100644 --- a/drivers/gpu/drm/mga/mga_state.c +++ b/drivers/gpu/drm/mga/mga_state.c @@ -41,8 +41,8 @@ * DMA hardware state programming functions */ -static void mga_emit_clip_rect(drm_mga_private_t * dev_priv, - struct drm_clip_rect * box) +static void mga_emit_clip_rect(drm_mga_private_t *dev_priv, + struct drm_clip_rect *box) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; @@ -66,7 +66,7 @@ static void mga_emit_clip_rect(drm_mga_private_t * dev_priv, ADVANCE_DMA(); } -static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv) +static __inline__ void mga_g200_emit_context(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; @@ -89,7 +89,7 @@ static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv) ADVANCE_DMA(); } -static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv) +static __inline__ void mga_g400_emit_context(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; @@ -116,7 +116,7 @@ static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv) ADVANCE_DMA(); } -static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv) +static __inline__ void mga_g200_emit_tex0(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; @@ -144,7 +144,7 @@ static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv) ADVANCE_DMA(); } -static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv) +static __inline__ void mga_g400_emit_tex0(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; @@ -184,7 +184,7 @@ static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv) ADVANCE_DMA(); } -static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv) +static __inline__ void mga_g400_emit_tex1(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; @@ -223,7 +223,7 @@ static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv) ADVANCE_DMA(); } -static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv) +static __inline__ void mga_g200_emit_pipe(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int pipe = sarea_priv->warp_pipe; @@ -250,7 +250,7 @@ static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv) ADVANCE_DMA(); } -static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv) +static __inline__ void mga_g400_emit_pipe(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int pipe = sarea_priv->warp_pipe; @@ -327,7 +327,7 @@ static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv) ADVANCE_DMA(); } -static void mga_g200_emit_state(drm_mga_private_t * dev_priv) +static void mga_g200_emit_state(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; @@ -348,7 +348,7 @@ static void mga_g200_emit_state(drm_mga_private_t * dev_priv) } } -static void mga_g400_emit_state(drm_mga_private_t * dev_priv) +static void mga_g400_emit_state(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; @@ -381,7 +381,7 @@ static void mga_g400_emit_state(drm_mga_private_t * dev_priv) /* Disallow all write destinations except the front and backbuffer. */ -static int mga_verify_context(drm_mga_private_t * dev_priv) +static int mga_verify_context(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; @@ -400,7 +400,7 @@ static int mga_verify_context(drm_mga_private_t * dev_priv) /* Disallow texture reads from PCI space. */ -static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit) +static int mga_verify_tex(drm_mga_private_t *dev_priv, int unit) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit]; @@ -417,7 +417,7 @@ static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit) return 0; } -static int mga_verify_state(drm_mga_private_t * dev_priv) +static int mga_verify_state(drm_mga_private_t *dev_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; @@ -446,7 +446,7 @@ static int mga_verify_state(drm_mga_private_t * dev_priv) return (ret == 0); } -static int mga_verify_iload(drm_mga_private_t * dev_priv, +static int mga_verify_iload(drm_mga_private_t *dev_priv, unsigned int dstorg, unsigned int length) { if (dstorg < dev_priv->texture_offset || @@ -465,7 +465,7 @@ static int mga_verify_iload(drm_mga_private_t * dev_priv, return 0; } -static int mga_verify_blit(drm_mga_private_t * dev_priv, +static int mga_verify_blit(drm_mga_private_t *dev_priv, unsigned int srcorg, unsigned int dstorg) { if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || @@ -480,7 +480,7 @@ static int mga_verify_blit(drm_mga_private_t * dev_priv, * */ -static void mga_dma_dispatch_clear(struct drm_device * dev, drm_mga_clear_t * clear) +static void mga_dma_dispatch_clear(struct drm_device *dev, drm_mga_clear_t *clear) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -568,7 +568,7 @@ static void mga_dma_dispatch_clear(struct drm_device * dev, drm_mga_clear_t * cl FLUSH_DMA(); } -static void mga_dma_dispatch_swap(struct drm_device * dev) +static void mga_dma_dispatch_swap(struct drm_device *dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -622,7 +622,7 @@ static void mga_dma_dispatch_swap(struct drm_device * dev) DRM_DEBUG("... done.\n"); } -static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf) +static void mga_dma_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; @@ -669,7 +669,7 @@ static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * bu FLUSH_DMA(); } -static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * buf, +static void mga_dma_dispatch_indices(struct drm_device *dev, struct drm_buf *buf, unsigned int start, unsigned int end) { drm_mga_private_t *dev_priv = dev->dev_private; @@ -718,7 +718,7 @@ static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * b /* This copies a 64 byte aligned agp region to the frambuffer with a * standard blit, the ioctl needs to do checking. */ -static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf, +static void mga_dma_dispatch_iload(struct drm_device *dev, struct drm_buf *buf, unsigned int dstorg, unsigned int length) { drm_mga_private_t *dev_priv = dev->dev_private; @@ -766,7 +766,7 @@ static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf FLUSH_DMA(); } -static void mga_dma_dispatch_blit(struct drm_device * dev, drm_mga_blit_t * blit) +static void mga_dma_dispatch_blit(struct drm_device *dev, drm_mga_blit_t *blit) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -801,9 +801,8 @@ static void mga_dma_dispatch_blit(struct drm_device * dev, drm_mga_blit_t * blit int w = pbox[i].x2 - pbox[i].x1 - 1; int start; - if (blit->ydir == -1) { + if (blit->ydir == -1) srcy = blit->height - srcy - 1; - } start = srcy * blit->src_pitch + srcx; diff --git a/drivers/gpu/drm/mga/mga_warp.c b/drivers/gpu/drm/mga/mga_warp.c index 9aad484..f172bd5 100644 --- a/drivers/gpu/drm/mga/mga_warp.c +++ b/drivers/gpu/drm/mga/mga_warp.c @@ -46,7 +46,7 @@ MODULE_FIRMWARE(FIRMWARE_G400); #define WARP_UCODE_SIZE(size) ALIGN(size, MGA_WARP_CODE_ALIGN) -int mga_warp_install_microcode(drm_mga_private_t * dev_priv) +int mga_warp_install_microcode(drm_mga_private_t *dev_priv) { unsigned char *vcbase = dev_priv->warp->handle; unsigned long pcbase = dev_priv->warp->offset; @@ -133,7 +133,7 @@ out: #define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) -int mga_warp_init(drm_mga_private_t * dev_priv) +int mga_warp_init(drm_mga_private_t *dev_priv) { u32 wmisc; -- cgit v0.10.2 From bc5e9d6a22f49fb4a7a5ec385062d1eb473bfec4 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Mon, 12 Jul 2010 13:44:23 +0200 Subject: drm/r128: fixed brace and spacing coding style issues Fixed brace and spacing coding style issues. Signed-off-by: Nicolas Kaiser Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c index e671d0e..570e190 100644 --- a/drivers/gpu/drm/r128/r128_cce.c +++ b/drivers/gpu/drm/r128/r128_cce.c @@ -44,7 +44,7 @@ MODULE_FIRMWARE(FIRMWARE_NAME); -static int R128_READ_PLL(struct drm_device * dev, int addr) +static int R128_READ_PLL(struct drm_device *dev, int addr) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -53,7 +53,7 @@ static int R128_READ_PLL(struct drm_device * dev, int addr) } #if R128_FIFO_DEBUG -static void r128_status(drm_r128_private_t * dev_priv) +static void r128_status(drm_r128_private_t *dev_priv) { printk("GUI_STAT = 0x%08x\n", (unsigned int)R128_READ(R128_GUI_STAT)); @@ -74,7 +74,7 @@ static void r128_status(drm_r128_private_t * dev_priv) * Engine, FIFO control */ -static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv) +static int r128_do_pixcache_flush(drm_r128_private_t *dev_priv) { u32 tmp; int i; @@ -83,9 +83,8 @@ static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv) R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp); for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) { + if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) return 0; - } DRM_UDELAY(1); } @@ -95,7 +94,7 @@ static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv) return -EBUSY; } -static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries) +static int r128_do_wait_for_fifo(drm_r128_private_t *dev_priv, int entries) { int i; @@ -112,7 +111,7 @@ static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries) return -EBUSY; } -static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv) +static int r128_do_wait_for_idle(drm_r128_private_t *dev_priv) { int i, ret; @@ -189,7 +188,7 @@ out_release: * prior to a wait for idle, as it informs the engine that the command * stream is ending. */ -static void r128_do_cce_flush(drm_r128_private_t * dev_priv) +static void r128_do_cce_flush(drm_r128_private_t *dev_priv) { u32 tmp; @@ -199,7 +198,7 @@ static void r128_do_cce_flush(drm_r128_private_t * dev_priv) /* Wait for the CCE to go idle. */ -int r128_do_cce_idle(drm_r128_private_t * dev_priv) +int r128_do_cce_idle(drm_r128_private_t *dev_priv) { int i; @@ -225,7 +224,7 @@ int r128_do_cce_idle(drm_r128_private_t * dev_priv) /* Start the Concurrent Command Engine. */ -static void r128_do_cce_start(drm_r128_private_t * dev_priv) +static void r128_do_cce_start(drm_r128_private_t *dev_priv) { r128_do_wait_for_idle(dev_priv); @@ -242,7 +241,7 @@ static void r128_do_cce_start(drm_r128_private_t * dev_priv) * commands, so you must wait for the CCE command stream to complete * before calling this routine. */ -static void r128_do_cce_reset(drm_r128_private_t * dev_priv) +static void r128_do_cce_reset(drm_r128_private_t *dev_priv) { R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); @@ -253,7 +252,7 @@ static void r128_do_cce_reset(drm_r128_private_t * dev_priv) * commands, so you must flush the command stream and wait for the CCE * to go idle before calling this routine. */ -static void r128_do_cce_stop(drm_r128_private_t * dev_priv) +static void r128_do_cce_stop(drm_r128_private_t *dev_priv) { R128_WRITE(R128_PM4_MICRO_CNTL, 0); R128_WRITE(R128_PM4_BUFFER_CNTL, @@ -264,7 +263,7 @@ static void r128_do_cce_stop(drm_r128_private_t * dev_priv) /* Reset the engine. This will stop the CCE if it is running. */ -static int r128_do_engine_reset(struct drm_device * dev) +static int r128_do_engine_reset(struct drm_device *dev) { drm_r128_private_t *dev_priv = dev->dev_private; u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; @@ -301,8 +300,8 @@ static int r128_do_engine_reset(struct drm_device * dev) return 0; } -static void r128_cce_init_ring_buffer(struct drm_device * dev, - drm_r128_private_t * dev_priv) +static void r128_cce_init_ring_buffer(struct drm_device *dev, + drm_r128_private_t *dev_priv) { u32 ring_start; u32 tmp; @@ -340,7 +339,7 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev, R128_WRITE(R128_BUS_CNTL, tmp); } -static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) +static int r128_do_init_cce(struct drm_device *dev, drm_r128_init_t *init) { drm_r128_private_t *dev_priv; int rc; @@ -588,7 +587,7 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) return rc; } -int r128_do_cleanup_cce(struct drm_device * dev) +int r128_do_cleanup_cce(struct drm_device *dev) { /* Make sure interrupts are disabled here because the uninstall ioctl @@ -682,9 +681,8 @@ int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv /* Flush any pending CCE commands. This ensures any outstanding * commands are exectuted by the engine before we turn it off. */ - if (stop->flush) { + if (stop->flush) r128_do_cce_flush(dev_priv); - } /* If we fail to make the engine go idle, we return an error * code so that the DRM ioctl wrapper can try again. @@ -735,9 +733,8 @@ int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv DEV_INIT_TEST_WITH_RETURN(dev_priv); - if (dev_priv->cce_running) { + if (dev_priv->cce_running) r128_do_cce_flush(dev_priv); - } return r128_do_cce_idle(dev_priv); } @@ -765,7 +762,7 @@ int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_pr #define R128_BUFFER_FREE 0 #if 0 -static int r128_freelist_init(struct drm_device * dev) +static int r128_freelist_init(struct drm_device *dev) { struct drm_device_dma *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; @@ -848,7 +845,7 @@ static struct drm_buf *r128_freelist_get(struct drm_device * dev) return NULL; } -void r128_freelist_reset(struct drm_device * dev) +void r128_freelist_reset(struct drm_device *dev) { struct drm_device_dma *dma = dev->dma; int i; @@ -864,7 +861,7 @@ void r128_freelist_reset(struct drm_device * dev) * CCE command submission */ -int r128_wait_ring(drm_r128_private_t * dev_priv, int n) +int r128_wait_ring(drm_r128_private_t *dev_priv, int n) { drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; @@ -881,9 +878,9 @@ int r128_wait_ring(drm_r128_private_t * dev_priv, int n) return -EBUSY; } -static int r128_cce_get_buffers(struct drm_device * dev, +static int r128_cce_get_buffers(struct drm_device *dev, struct drm_file *file_priv, - struct drm_dma * d) + struct drm_dma *d) { int i; struct drm_buf *buf; @@ -933,9 +930,8 @@ int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_p d->granted_count = 0; - if (d->request_count) { + if (d->request_count) ret = r128_cce_get_buffers(dev, file_priv, d); - } return ret; } diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index b806fdc..1e2971f 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c @@ -85,7 +85,7 @@ static struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, }; -int r128_driver_load(struct drm_device * dev, unsigned long flags) +int r128_driver_load(struct drm_device *dev, unsigned long flags) { return drm_vblank_init(dev, 1); } diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h index 3c60829..930c71b 100644 --- a/drivers/gpu/drm/r128/r128_drv.h +++ b/drivers/gpu/drm/r128/r128_drv.h @@ -53,7 +53,7 @@ #define DRIVER_MINOR 5 #define DRIVER_PATCHLEVEL 0 -#define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR ) +#define GET_RING_HEAD(dev_priv) R128_READ(R128_PM4_BUFFER_DL_RPTR) typedef struct drm_r128_freelist { unsigned int age; @@ -144,23 +144,23 @@ extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void r128_freelist_reset(struct drm_device * dev); +extern void r128_freelist_reset(struct drm_device *dev); -extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); +extern int r128_wait_ring(drm_r128_private_t *dev_priv, int n); -extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); -extern int r128_do_cleanup_cce(struct drm_device * dev); +extern int r128_do_cce_idle(drm_r128_private_t *dev_priv); +extern int r128_do_cleanup_cce(struct drm_device *dev); extern int r128_enable_vblank(struct drm_device *dev, int crtc); extern void r128_disable_vblank(struct drm_device *dev, int crtc); extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); -extern void r128_driver_irq_preinstall(struct drm_device * dev); +extern void r128_driver_irq_preinstall(struct drm_device *dev); extern int r128_driver_irq_postinstall(struct drm_device *dev); -extern void r128_driver_irq_uninstall(struct drm_device * dev); -extern void r128_driver_lastclose(struct drm_device * dev); -extern int r128_driver_load(struct drm_device * dev, unsigned long flags); -extern void r128_driver_preclose(struct drm_device * dev, +extern void r128_driver_irq_uninstall(struct drm_device *dev); +extern void r128_driver_lastclose(struct drm_device *dev); +extern int r128_driver_load(struct drm_device *dev, unsigned long flags); +extern void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, @@ -390,27 +390,27 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, #define R128_PCIGART_TABLE_SIZE 32768 -#define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) -#define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) -#define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) -#define R128_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) +#define R128_READ(reg) DRM_READ32(dev_priv->mmio, (reg)) +#define R128_WRITE(reg, val) DRM_WRITE32(dev_priv->mmio, (reg), (val)) +#define R128_READ8(reg) DRM_READ8(dev_priv->mmio, (reg)) +#define R128_WRITE8(reg, val) DRM_WRITE8(dev_priv->mmio, (reg), (val)) -#define R128_WRITE_PLL(addr,val) \ +#define R128_WRITE_PLL(addr, val) \ do { \ R128_WRITE8(R128_CLOCK_CNTL_INDEX, \ ((addr) & 0x1f) | R128_PLL_WR_EN); \ R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \ } while (0) -#define CCE_PACKET0( reg, n ) (R128_CCE_PACKET0 | \ +#define CCE_PACKET0(reg, n) (R128_CCE_PACKET0 | \ ((n) << 16) | ((reg) >> 2)) -#define CCE_PACKET1( reg0, reg1 ) (R128_CCE_PACKET1 | \ +#define CCE_PACKET1(reg0, reg1) (R128_CCE_PACKET1 | \ (((reg1) >> 2) << 11) | ((reg0) >> 2)) #define CCE_PACKET2() (R128_CCE_PACKET2) -#define CCE_PACKET3( pkt, n ) (R128_CCE_PACKET3 | \ +#define CCE_PACKET3(pkt, n) (R128_CCE_PACKET3 | \ (pkt) | ((n) << 16)) -static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv) +static __inline__ void r128_update_ring_snapshot(drm_r128_private_t *dev_priv) { drm_r128_ring_buffer_t *ring = &dev_priv->ring; ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32); @@ -430,37 +430,38 @@ do { \ } \ } while (0) -#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ +#define RING_SPACE_TEST_WITH_RETURN(dev_priv) \ do { \ drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ - if ( ring->space < ring->high_mark ) { \ - for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ - r128_update_ring_snapshot( dev_priv ); \ - if ( ring->space >= ring->high_mark ) \ + if (ring->space < ring->high_mark) { \ + for (i = 0 ; i < dev_priv->usec_timeout ; i++) { \ + r128_update_ring_snapshot(dev_priv); \ + if (ring->space >= ring->high_mark) \ goto __ring_space_done; \ - DRM_UDELAY(1); \ + DRM_UDELAY(1); \ } \ - DRM_ERROR( "ring space check failed!\n" ); \ - return -EBUSY; \ + DRM_ERROR("ring space check failed!\n"); \ + return -EBUSY; \ } \ __ring_space_done: \ ; \ } while (0) -#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ +#define VB_AGE_TEST_WITH_RETURN(dev_priv) \ do { \ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \ - if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) { \ - int __ret = r128_do_cce_idle( dev_priv ); \ - if ( __ret ) return __ret; \ + if (sarea_priv->last_dispatch >= R128_MAX_VB_AGE) { \ + int __ret = r128_do_cce_idle(dev_priv); \ + if (__ret) \ + return __ret; \ sarea_priv->last_dispatch = 0; \ - r128_freelist_reset( dev ); \ + r128_freelist_reset(dev); \ } \ } while (0) #define R128_WAIT_UNTIL_PAGE_FLIPPED() do { \ - OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) ); \ - OUT_RING( R128_EVENT_CRTC_OFFSET ); \ + OUT_RING(CCE_PACKET0(R128_WAIT_UNTIL, 0)); \ + OUT_RING(R128_EVENT_CRTC_OFFSET); \ } while (0) /* ================================================================ @@ -472,13 +473,12 @@ do { \ #define RING_LOCALS \ int write, _nr; unsigned int tail_mask; volatile u32 *ring; -#define BEGIN_RING( n ) do { \ - if ( R128_VERBOSE ) { \ - DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ - } \ - if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ +#define BEGIN_RING(n) do { \ + if (R128_VERBOSE) \ + DRM_INFO("BEGIN_RING(%d)\n", (n)); \ + if (dev_priv->ring.space <= (n) * sizeof(u32)) { \ COMMIT_RING(); \ - r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \ + r128_wait_ring(dev_priv, (n) * sizeof(u32)); \ } \ _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ @@ -494,40 +494,36 @@ do { \ #define R128_BROKEN_CCE 1 #define ADVANCE_RING() do { \ - if ( R128_VERBOSE ) { \ - DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ - write, dev_priv->ring.tail ); \ - } \ - if ( R128_BROKEN_CCE && write < 32 ) { \ - memcpy( dev_priv->ring.end, \ - dev_priv->ring.start, \ - write * sizeof(u32) ); \ - } \ - if (((dev_priv->ring.tail + _nr) & tail_mask) != write) { \ + if (R128_VERBOSE) \ + DRM_INFO("ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ + write, dev_priv->ring.tail); \ + if (R128_BROKEN_CCE && write < 32) \ + memcpy(dev_priv->ring.end, \ + dev_priv->ring.start, \ + write * sizeof(u32)); \ + if (((dev_priv->ring.tail + _nr) & tail_mask) != write) \ DRM_ERROR( \ "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ ((dev_priv->ring.tail + _nr) & tail_mask), \ write, __LINE__); \ - } else \ + else \ dev_priv->ring.tail = write; \ } while (0) #define COMMIT_RING() do { \ - if ( R128_VERBOSE ) { \ - DRM_INFO( "COMMIT_RING() tail=0x%06x\n", \ - dev_priv->ring.tail ); \ - } \ + if (R128_VERBOSE) \ + DRM_INFO("COMMIT_RING() tail=0x%06x\n", \ + dev_priv->ring.tail); \ DRM_MEMORYBARRIER(); \ - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail ); \ - R128_READ( R128_PM4_BUFFER_DL_WPTR ); \ + R128_WRITE(R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail); \ + R128_READ(R128_PM4_BUFFER_DL_WPTR); \ } while (0) -#define OUT_RING( x ) do { \ - if ( R128_VERBOSE ) { \ - DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ - (unsigned int)(x), write ); \ - } \ - ring[write++] = cpu_to_le32( x ); \ +#define OUT_RING(x) do { \ + if (R128_VERBOSE) \ + DRM_INFO(" OUT_RING( 0x%08x ) at 0x%x\n", \ + (unsigned int)(x), write); \ + ring[write++] = cpu_to_le32(x); \ write &= tail_mask; \ } while (0) diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c index 69810fb..429d5a0 100644 --- a/drivers/gpu/drm/r128/r128_irq.c +++ b/drivers/gpu/drm/r128/r128_irq.c @@ -90,7 +90,7 @@ void r128_disable_vblank(struct drm_device *dev, int crtc) */ } -void r128_driver_irq_preinstall(struct drm_device * dev) +void r128_driver_irq_preinstall(struct drm_device *dev) { drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; @@ -105,7 +105,7 @@ int r128_driver_irq_postinstall(struct drm_device *dev) return 0; } -void r128_driver_irq_uninstall(struct drm_device * dev) +void r128_driver_irq_uninstall(struct drm_device *dev) { drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; if (!dev_priv) diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c index af2665c..077af1f 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c @@ -37,8 +37,8 @@ * CCE hardware state programming functions */ -static void r128_emit_clip_rects(drm_r128_private_t * dev_priv, - struct drm_clip_rect * boxes, int count) +static void r128_emit_clip_rects(drm_r128_private_t *dev_priv, + struct drm_clip_rect *boxes, int count) { u32 aux_sc_cntl = 0x00000000; RING_LOCALS; @@ -80,7 +80,7 @@ static void r128_emit_clip_rects(drm_r128_private_t * dev_priv, ADVANCE_RING(); } -static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv) +static __inline__ void r128_emit_core(drm_r128_private_t *dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; @@ -95,7 +95,7 @@ static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv) ADVANCE_RING(); } -static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv) +static __inline__ void r128_emit_context(drm_r128_private_t *dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; @@ -121,7 +121,7 @@ static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv) ADVANCE_RING(); } -static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv) +static __inline__ void r128_emit_setup(drm_r128_private_t *dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; @@ -137,7 +137,7 @@ static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv) ADVANCE_RING(); } -static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv) +static __inline__ void r128_emit_masks(drm_r128_private_t *dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; @@ -156,7 +156,7 @@ static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv) ADVANCE_RING(); } -static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv) +static __inline__ void r128_emit_window(drm_r128_private_t *dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; @@ -171,7 +171,7 @@ static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv) ADVANCE_RING(); } -static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv) +static __inline__ void r128_emit_tex0(drm_r128_private_t *dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_context_regs_t *ctx = &sarea_priv->context_state; @@ -187,9 +187,8 @@ static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv) OUT_RING(tex->tex_cntl); OUT_RING(tex->tex_combine_cntl); OUT_RING(ctx->tex_size_pitch_c); - for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { + for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) OUT_RING(tex->tex_offset[i]); - } OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1)); OUT_RING(ctx->constant_color_c); @@ -198,7 +197,7 @@ static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv) ADVANCE_RING(); } -static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv) +static __inline__ void r128_emit_tex1(drm_r128_private_t *dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; @@ -211,9 +210,8 @@ static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv) OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS)); OUT_RING(tex->tex_cntl); OUT_RING(tex->tex_combine_cntl); - for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) { + for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) OUT_RING(tex->tex_offset[i]); - } OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0)); OUT_RING(tex->tex_border_color); @@ -221,7 +219,7 @@ static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv) ADVANCE_RING(); } -static void r128_emit_state(drm_r128_private_t * dev_priv) +static void r128_emit_state(drm_r128_private_t *dev_priv) { drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; @@ -274,7 +272,7 @@ static void r128_emit_state(drm_r128_private_t * dev_priv) * Performance monitoring functions */ -static void r128_clear_box(drm_r128_private_t * dev_priv, +static void r128_clear_box(drm_r128_private_t *dev_priv, int x, int y, int w, int h, int r, int g, int b) { u32 pitch, offset; @@ -321,13 +319,12 @@ static void r128_clear_box(drm_r128_private_t * dev_priv, ADVANCE_RING(); } -static void r128_cce_performance_boxes(drm_r128_private_t * dev_priv) +static void r128_cce_performance_boxes(drm_r128_private_t *dev_priv) { - if (atomic_read(&dev_priv->idle_count) == 0) { + if (atomic_read(&dev_priv->idle_count) == 0) r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); - } else { + else atomic_set(&dev_priv->idle_count, 0); - } } #endif @@ -352,8 +349,8 @@ static void r128_print_dirty(const char *msg, unsigned int flags) (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : ""); } -static void r128_cce_dispatch_clear(struct drm_device * dev, - drm_r128_clear_t * clear) +static void r128_cce_dispatch_clear(struct drm_device *dev, + drm_r128_clear_t *clear) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -458,7 +455,7 @@ static void r128_cce_dispatch_clear(struct drm_device * dev, } } -static void r128_cce_dispatch_swap(struct drm_device * dev) +static void r128_cce_dispatch_swap(struct drm_device *dev) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -524,7 +521,7 @@ static void r128_cce_dispatch_swap(struct drm_device * dev) ADVANCE_RING(); } -static void r128_cce_dispatch_flip(struct drm_device * dev) +static void r128_cce_dispatch_flip(struct drm_device *dev) { drm_r128_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -542,11 +539,10 @@ static void r128_cce_dispatch_flip(struct drm_device * dev) R128_WAIT_UNTIL_PAGE_FLIPPED(); OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0)); - if (dev_priv->current_page == 0) { + if (dev_priv->current_page == 0) OUT_RING(dev_priv->back_offset); - } else { + else OUT_RING(dev_priv->front_offset); - } ADVANCE_RING(); @@ -566,7 +562,7 @@ static void r128_cce_dispatch_flip(struct drm_device * dev) ADVANCE_RING(); } -static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf) +static void r128_cce_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private; @@ -585,9 +581,8 @@ static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * b if (buf->used) { buf_priv->dispatched = 1; - if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) { + if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) r128_emit_state(dev_priv); - } do { /* Emit the next set of up to three cliprects */ @@ -636,8 +631,8 @@ static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * b sarea_priv->nbox = 0; } -static void r128_cce_dispatch_indirect(struct drm_device * dev, - struct drm_buf * buf, int start, int end) +static void r128_cce_dispatch_indirect(struct drm_device *dev, + struct drm_buf *buf, int start, int end) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private; @@ -691,8 +686,8 @@ static void r128_cce_dispatch_indirect(struct drm_device * dev, dev_priv->sarea_priv->last_dispatch++; } -static void r128_cce_dispatch_indices(struct drm_device * dev, - struct drm_buf * buf, +static void r128_cce_dispatch_indices(struct drm_device *dev, + struct drm_buf *buf, int start, int end, int count) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -713,9 +708,8 @@ static void r128_cce_dispatch_indices(struct drm_device * dev, if (start != end) { buf_priv->dispatched = 1; - if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) { + if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) r128_emit_state(dev_priv); - } dwords = (end - start + 3) / sizeof(u32); @@ -775,9 +769,9 @@ static void r128_cce_dispatch_indices(struct drm_device * dev, sarea_priv->nbox = 0; } -static int r128_cce_dispatch_blit(struct drm_device * dev, +static int r128_cce_dispatch_blit(struct drm_device *dev, struct drm_file *file_priv, - drm_r128_blit_t * blit) + drm_r128_blit_t *blit) { drm_r128_private_t *dev_priv = dev->dev_private; struct drm_device_dma *dma = dev->dma; @@ -887,8 +881,8 @@ static int r128_cce_dispatch_blit(struct drm_device * dev, * have hardware stencil support. */ -static int r128_cce_dispatch_write_span(struct drm_device * dev, - drm_r128_depth_t * depth) +static int r128_cce_dispatch_write_span(struct drm_device *dev, + drm_r128_depth_t *depth) { drm_r128_private_t *dev_priv = dev->dev_private; int count, x, y; @@ -902,12 +896,10 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, if (count > 4096 || count <= 0) return -EMSGSIZE; - if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { + if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) return -EFAULT; - } - if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { + if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) return -EFAULT; - } buffer_size = depth->n * sizeof(u32); buffer = kmalloc(buffer_size, GFP_KERNEL); @@ -983,8 +975,8 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, return 0; } -static int r128_cce_dispatch_write_pixels(struct drm_device * dev, - drm_r128_depth_t * depth) +static int r128_cce_dispatch_write_pixels(struct drm_device *dev, + drm_r128_depth_t *depth) { drm_r128_private_t *dev_priv = dev->dev_private; int count, *x, *y; @@ -1001,9 +993,8 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, xbuf_size = count * sizeof(*x); ybuf_size = count * sizeof(*y); x = kmalloc(xbuf_size, GFP_KERNEL); - if (x == NULL) { + if (x == NULL) return -ENOMEM; - } y = kmalloc(ybuf_size, GFP_KERNEL); if (y == NULL) { kfree(x); @@ -1105,8 +1096,8 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, return 0; } -static int r128_cce_dispatch_read_span(struct drm_device * dev, - drm_r128_depth_t * depth) +static int r128_cce_dispatch_read_span(struct drm_device *dev, + drm_r128_depth_t *depth) { drm_r128_private_t *dev_priv = dev->dev_private; int count, x, y; @@ -1117,12 +1108,10 @@ static int r128_cce_dispatch_read_span(struct drm_device * dev, if (count > 4096 || count <= 0) return -EMSGSIZE; - if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { + if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) return -EFAULT; - } - if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { + if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) return -EFAULT; - } BEGIN_RING(7); @@ -1148,8 +1137,8 @@ static int r128_cce_dispatch_read_span(struct drm_device * dev, return 0; } -static int r128_cce_dispatch_read_pixels(struct drm_device * dev, - drm_r128_depth_t * depth) +static int r128_cce_dispatch_read_pixels(struct drm_device *dev, + drm_r128_depth_t *depth) { drm_r128_private_t *dev_priv = dev->dev_private; int count, *x, *y; @@ -1161,16 +1150,14 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev, if (count > 4096 || count <= 0) return -EMSGSIZE; - if (count > dev_priv->depth_pitch) { + if (count > dev_priv->depth_pitch) count = dev_priv->depth_pitch; - } xbuf_size = count * sizeof(*x); ybuf_size = count * sizeof(*y); x = kmalloc(xbuf_size, GFP_KERNEL); - if (x == NULL) { + if (x == NULL) return -ENOMEM; - } y = kmalloc(ybuf_size, GFP_KERNEL); if (y == NULL) { kfree(x); @@ -1220,7 +1207,7 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev, * Polygon stipple */ -static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple) +static void r128_cce_dispatch_stipple(struct drm_device *dev, u32 *stipple) { drm_r128_private_t *dev_priv = dev->dev_private; int i; @@ -1230,9 +1217,8 @@ static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple) BEGIN_RING(33); OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31)); - for (i = 0; i < 32; i++) { + for (i = 0; i < 32; i++) OUT_RING(stipple[i]); - } ADVANCE_RING(); } @@ -1269,7 +1255,7 @@ static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *f return 0; } -static int r128_do_init_pageflip(struct drm_device * dev) +static int r128_do_init_pageflip(struct drm_device *dev) { drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); @@ -1288,7 +1274,7 @@ static int r128_do_init_pageflip(struct drm_device * dev) return 0; } -static int r128_do_cleanup_pageflip(struct drm_device * dev) +static int r128_do_cleanup_pageflip(struct drm_device *dev) { drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); @@ -1645,17 +1631,16 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi return 0; } -void r128_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) +void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) { if (dev->dev_private) { drm_r128_private_t *dev_priv = dev->dev_private; - if (dev_priv->page_flipping) { + if (dev_priv->page_flipping) r128_do_cleanup_pageflip(dev); - } } } -void r128_driver_lastclose(struct drm_device * dev) +void r128_driver_lastclose(struct drm_device *dev) { r128_do_cleanup_cce(dev); } -- cgit v0.10.2 From a7b98b6748efdddd832b39662801c9f828df1813 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Fri, 9 Jul 2010 16:47:28 +0200 Subject: drm/sis: fixed brace and spacing coding style issues Fixed brace and spacing coding style issues. Signed-off-by: Nicolas Kaiser Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 4fd1f06..776bf9e 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -47,9 +47,8 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) dev->dev_private = (void *)dev_priv; dev_priv->chipset = chipset; ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); - if (ret) { + if (ret) kfree(dev_priv); - } return ret; } diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index af22111..07d0f29 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c @@ -78,7 +78,7 @@ static unsigned long sis_sman_mm_offset(void *private, void *ref) #else /* CONFIG_FB_SIS[_MODULE] */ #define SIS_MM_ALIGN_SHIFT 4 -#define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1) +#define SIS_MM_ALIGN_MASK ((1 << SIS_MM_ALIGN_SHIFT) - 1) #endif /* CONFIG_FB_SIS[_MODULE] */ @@ -225,9 +225,8 @@ static drm_local_map_t *sis_reg_init(struct drm_device *dev) map = entry->map; if (!map) continue; - if (map->type == _DRM_REGISTERS) { + if (map->type == _DRM_REGISTERS) return map; - } } return NULL; } @@ -264,10 +263,10 @@ int sis_idle(struct drm_device *dev) end = jiffies + (DRM_HZ * 3); - for (i=0; i<4; ++i) { + for (i = 0; i < 4; ++i) { do { idle_reg = SIS_READ(0x85cc); - } while ( !time_after_eq(jiffies, end) && + } while (!time_after_eq(jiffies, end) && ((idle_reg & 0x80000000) != 0x80000000)); } @@ -301,7 +300,7 @@ void sis_lastclose(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); } -void sis_reclaim_buffers_locked(struct drm_device * dev, +void sis_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv) { drm_sis_private_t *dev_priv = dev->dev_private; @@ -312,9 +311,8 @@ void sis_reclaim_buffers_locked(struct drm_device * dev, return; } - if (dev->driver->dma_quiescent) { + if (dev->driver->dma_quiescent) dev->driver->dma_quiescent(dev); - } drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv); mutex_unlock(&dev->struct_mutex); -- cgit v0.10.2 From e190bfe56841551b1ad5abb42ebd0c4798cc8c01 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 22 Jul 2010 17:06:18 +0200 Subject: drm: Import driver for the sil164 I2C TMDS transmitter. sil164 transmitters are used for DVI outputs on Intel/nvidia and ATI setups. So far only nouveau can use this driver. Signed-off-by: Francisco Jerez Tested-by: Patrice Mandin Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile index 6d2abaf..9286256 100644 --- a/drivers/gpu/drm/i2c/Makefile +++ b/drivers/gpu/drm/i2c/Makefile @@ -2,3 +2,6 @@ ccflags-y := -Iinclude/drm ch7006-y := ch7006_drv.o ch7006_mode.o obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o + +sil164-y := sil164_drv.o +obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c new file mode 100644 index 0000000..0b67732 --- /dev/null +++ b/drivers/gpu/drm/i2c/sil164_drv.c @@ -0,0 +1,462 @@ +/* + * Copyright (C) 2010 Francisco Jerez. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm_crtc_helper.h" +#include "drm_encoder_slave.h" +#include "i2c/sil164.h" + +struct sil164_priv { + struct sil164_encoder_params config; + struct i2c_client *duallink_slave; + + uint8_t saved_state[0x10]; + uint8_t saved_slave_state[0x10]; +}; + +#define to_sil164_priv(x) \ + ((struct sil164_priv *)to_encoder_slave(x)->slave_priv) + +#define sil164_dbg(client, format, ...) do { \ + if (drm_debug & DRM_UT_KMS) \ + dev_printk(KERN_DEBUG, &client->dev, \ + "%s: " format, __func__, ## __VA_ARGS__); \ + } while (0) +#define sil164_info(client, format, ...) \ + dev_info(&client->dev, format, __VA_ARGS__) +#define sil164_err(client, format, ...) \ + dev_err(&client->dev, format, __VA_ARGS__) + +#define SIL164_I2C_ADDR_MASTER 0x38 +#define SIL164_I2C_ADDR_SLAVE 0x39 + +/* HW register definitions */ + +#define SIL164_VENDOR_LO 0x0 +#define SIL164_VENDOR_HI 0x1 +#define SIL164_DEVICE_LO 0x2 +#define SIL164_DEVICE_HI 0x3 +#define SIL164_REVISION 0x4 +#define SIL164_FREQ_MIN 0x6 +#define SIL164_FREQ_MAX 0x7 +#define SIL164_CONTROL0 0x8 +# define SIL164_CONTROL0_POWER_ON 0x01 +# define SIL164_CONTROL0_EDGE_RISING 0x02 +# define SIL164_CONTROL0_INPUT_24BIT 0x04 +# define SIL164_CONTROL0_DUAL_EDGE 0x08 +# define SIL164_CONTROL0_HSYNC_ON 0x10 +# define SIL164_CONTROL0_VSYNC_ON 0x20 +#define SIL164_DETECT 0x9 +# define SIL164_DETECT_INTR_STAT 0x01 +# define SIL164_DETECT_HOTPLUG_STAT 0x02 +# define SIL164_DETECT_RECEIVER_STAT 0x04 +# define SIL164_DETECT_INTR_MODE_RECEIVER 0x00 +# define SIL164_DETECT_INTR_MODE_HOTPLUG 0x08 +# define SIL164_DETECT_OUT_MODE_HIGH 0x00 +# define SIL164_DETECT_OUT_MODE_INTR 0x10 +# define SIL164_DETECT_OUT_MODE_RECEIVER 0x20 +# define SIL164_DETECT_OUT_MODE_HOTPLUG 0x30 +# define SIL164_DETECT_VSWING_STAT 0x80 +#define SIL164_CONTROL1 0xa +# define SIL164_CONTROL1_DESKEW_ENABLE 0x10 +# define SIL164_CONTROL1_DESKEW_INCR_SHIFT 5 +#define SIL164_GPIO 0xb +#define SIL164_CONTROL2 0xc +# define SIL164_CONTROL2_FILTER_ENABLE 0x01 +# define SIL164_CONTROL2_FILTER_SETTING_SHIFT 1 +# define SIL164_CONTROL2_DUALLINK_MASTER 0x40 +# define SIL164_CONTROL2_SYNC_CONT 0x80 +#define SIL164_DUALLINK 0xd +# define SIL164_DUALLINK_ENABLE 0x10 +# define SIL164_DUALLINK_SKEW_SHIFT 5 +#define SIL164_PLLZONE 0xe +# define SIL164_PLLZONE_STAT 0x08 +# define SIL164_PLLZONE_FORCE_ON 0x10 +# define SIL164_PLLZONE_FORCE_HIGH 0x20 + +/* HW access functions */ + +static void +sil164_write(struct i2c_client *client, uint8_t addr, uint8_t val) +{ + uint8_t buf[] = {addr, val}; + int ret; + + ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); + if (ret < 0) + sil164_err(client, "Error %d writing to subaddress 0x%x\n", + ret, addr); +} + +static uint8_t +sil164_read(struct i2c_client *client, uint8_t addr) +{ + uint8_t val; + int ret; + + ret = i2c_master_send(client, &addr, sizeof(addr)); + if (ret < 0) + goto fail; + + ret = i2c_master_recv(client, &val, sizeof(val)); + if (ret < 0) + goto fail; + + return val; + +fail: + sil164_err(client, "Error %d reading from subaddress 0x%x\n", + ret, addr); + return 0; +} + +static void +sil164_save_state(struct i2c_client *client, uint8_t *state) +{ + int i; + + for (i = 0x8; i <= 0xe; i++) + state[i] = sil164_read(client, i); +} + +static void +sil164_restore_state(struct i2c_client *client, uint8_t *state) +{ + int i; + + for (i = 0x8; i <= 0xe; i++) + sil164_write(client, i, state[i]); +} + +static void +sil164_set_power_state(struct i2c_client *client, bool on) +{ + uint8_t control0 = sil164_read(client, SIL164_CONTROL0); + + if (on) + control0 |= SIL164_CONTROL0_POWER_ON; + else + control0 &= ~SIL164_CONTROL0_POWER_ON; + + sil164_write(client, SIL164_CONTROL0, control0); +} + +static void +sil164_init_state(struct i2c_client *client, + struct sil164_encoder_params *config, + bool duallink) +{ + sil164_write(client, SIL164_CONTROL0, + SIL164_CONTROL0_HSYNC_ON | + SIL164_CONTROL0_VSYNC_ON | + (config->input_edge ? SIL164_CONTROL0_EDGE_RISING : 0) | + (config->input_width ? SIL164_CONTROL0_INPUT_24BIT : 0) | + (config->input_dual ? SIL164_CONTROL0_DUAL_EDGE : 0)); + + sil164_write(client, SIL164_DETECT, + SIL164_DETECT_INTR_STAT | + SIL164_DETECT_OUT_MODE_RECEIVER); + + sil164_write(client, SIL164_CONTROL1, + (config->input_skew ? SIL164_CONTROL1_DESKEW_ENABLE : 0) | + (((config->input_skew + 4) & 0x7) + << SIL164_CONTROL1_DESKEW_INCR_SHIFT)); + + sil164_write(client, SIL164_CONTROL2, + SIL164_CONTROL2_SYNC_CONT | + (config->pll_filter ? 0 : SIL164_CONTROL2_FILTER_ENABLE) | + (4 << SIL164_CONTROL2_FILTER_SETTING_SHIFT)); + + sil164_write(client, SIL164_PLLZONE, 0); + + if (duallink) + sil164_write(client, SIL164_DUALLINK, + SIL164_DUALLINK_ENABLE | + (((config->duallink_skew + 4) & 0x7) + << SIL164_DUALLINK_SKEW_SHIFT)); + else + sil164_write(client, SIL164_DUALLINK, 0); +} + +/* DRM encoder functions */ + +static void +sil164_encoder_set_config(struct drm_encoder *encoder, void *params) +{ + struct sil164_priv *priv = to_sil164_priv(encoder); + + priv->config = *(struct sil164_encoder_params *)params; +} + +static void +sil164_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct sil164_priv *priv = to_sil164_priv(encoder); + bool on = (mode == DRM_MODE_DPMS_ON); + bool duallink = (on && encoder->crtc->mode.clock > 165000); + + sil164_set_power_state(drm_i2c_encoder_get_client(encoder), on); + + if (priv->duallink_slave) + sil164_set_power_state(priv->duallink_slave, duallink); +} + +static void +sil164_encoder_save(struct drm_encoder *encoder) +{ + struct sil164_priv *priv = to_sil164_priv(encoder); + + sil164_save_state(drm_i2c_encoder_get_client(encoder), + priv->saved_state); + + if (priv->duallink_slave) + sil164_save_state(priv->duallink_slave, + priv->saved_slave_state); +} + +static void +sil164_encoder_restore(struct drm_encoder *encoder) +{ + struct sil164_priv *priv = to_sil164_priv(encoder); + + sil164_restore_state(drm_i2c_encoder_get_client(encoder), + priv->saved_state); + + if (priv->duallink_slave) + sil164_restore_state(priv->duallink_slave, + priv->saved_slave_state); +} + +static bool +sil164_encoder_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static int +sil164_encoder_mode_valid(struct drm_encoder *encoder, + struct drm_display_mode *mode) +{ + struct sil164_priv *priv = to_sil164_priv(encoder); + + if (mode->clock < 32000) + return MODE_CLOCK_LOW; + + if (mode->clock > 330000 || + (mode->clock > 165000 && !priv->duallink_slave)) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + +static void +sil164_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct sil164_priv *priv = to_sil164_priv(encoder); + bool duallink = adjusted_mode->clock > 165000; + + sil164_init_state(drm_i2c_encoder_get_client(encoder), + &priv->config, duallink); + + if (priv->duallink_slave) + sil164_init_state(priv->duallink_slave, + &priv->config, duallink); + + sil164_encoder_dpms(encoder, DRM_MODE_DPMS_ON); +} + +static enum drm_connector_status +sil164_encoder_detect(struct drm_encoder *encoder, + struct drm_connector *connector) +{ + struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + + if (sil164_read(client, SIL164_DETECT) & SIL164_DETECT_HOTPLUG_STAT) + return connector_status_connected; + else + return connector_status_disconnected; +} + +static int +sil164_encoder_get_modes(struct drm_encoder *encoder, + struct drm_connector *connector) +{ + return 0; +} + +static int +sil164_encoder_create_resources(struct drm_encoder *encoder, + struct drm_connector *connector) +{ + return 0; +} + +static int +sil164_encoder_set_property(struct drm_encoder *encoder, + struct drm_connector *connector, + struct drm_property *property, + uint64_t val) +{ + return 0; +} + +static void +sil164_encoder_destroy(struct drm_encoder *encoder) +{ + struct sil164_priv *priv = to_sil164_priv(encoder); + + if (priv->duallink_slave) + i2c_unregister_device(priv->duallink_slave); + + kfree(priv); + drm_i2c_encoder_destroy(encoder); +} + +static struct drm_encoder_slave_funcs sil164_encoder_funcs = { + .set_config = sil164_encoder_set_config, + .destroy = sil164_encoder_destroy, + .dpms = sil164_encoder_dpms, + .save = sil164_encoder_save, + .restore = sil164_encoder_restore, + .mode_fixup = sil164_encoder_mode_fixup, + .mode_valid = sil164_encoder_mode_valid, + .mode_set = sil164_encoder_mode_set, + .detect = sil164_encoder_detect, + .get_modes = sil164_encoder_get_modes, + .create_resources = sil164_encoder_create_resources, + .set_property = sil164_encoder_set_property, +}; + +/* I2C driver functions */ + +static int +sil164_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int vendor = sil164_read(client, SIL164_VENDOR_HI) << 8 | + sil164_read(client, SIL164_VENDOR_LO); + int device = sil164_read(client, SIL164_DEVICE_HI) << 8 | + sil164_read(client, SIL164_DEVICE_LO); + int rev = sil164_read(client, SIL164_REVISION); + + if (vendor != 0x1 || device != 0x6) { + sil164_dbg(client, "Unknown device %x:%x.%x\n", + vendor, device, rev); + return -ENODEV; + } + + sil164_info(client, "Detected device %x:%x.%x\n", + vendor, device, rev); + + return 0; +} + +static int +sil164_remove(struct i2c_client *client) +{ + return 0; +} + +static struct i2c_client * +sil164_detect_slave(struct i2c_client *client) +{ + struct i2c_adapter *adap = client->adapter; + struct i2c_msg msg = { + .addr = SIL164_I2C_ADDR_SLAVE, + .len = 0, + }; + const struct i2c_board_info info = { + I2C_BOARD_INFO("sil164", SIL164_I2C_ADDR_SLAVE) + }; + + if (i2c_transfer(adap, &msg, 1) != 1) { + sil164_dbg(adap, "No dual-link slave found."); + return NULL; + } + + return i2c_new_device(adap, &info); +} + +static int +sil164_encoder_init(struct i2c_client *client, + struct drm_device *dev, + struct drm_encoder_slave *encoder) +{ + struct sil164_priv *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + encoder->slave_priv = priv; + encoder->slave_funcs = &sil164_encoder_funcs; + + priv->duallink_slave = sil164_detect_slave(client); + + return 0; +} + +static struct i2c_device_id sil164_ids[] = { + { "sil164", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sil164_ids); + +static struct drm_i2c_encoder_driver sil164_driver = { + .i2c_driver = { + .probe = sil164_probe, + .remove = sil164_remove, + .driver = { + .name = "sil164", + }, + .id_table = sil164_ids, + }, + .encoder_init = sil164_encoder_init, +}; + +/* Module initialization */ + +static int __init +sil164_init(void) +{ + return drm_i2c_encoder_register(THIS_MODULE, &sil164_driver); +} + +static void __exit +sil164_exit(void) +{ + drm_i2c_encoder_unregister(&sil164_driver); +} + +MODULE_AUTHOR("Francisco Jerez "); +MODULE_DESCRIPTION("Silicon Image sil164 TMDS transmitter driver"); +MODULE_LICENSE("GPL and additional rights"); + +module_init(sil164_init); +module_exit(sil164_exit); diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index b6f5239..d2d2804 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -41,4 +41,13 @@ config DRM_I2C_CH7006 This driver is currently only useful if you're also using the nouveau driver. + +config DRM_I2C_SIL164 + tristate "Silicon Image sil164 TMDS transmitter" + default m if DRM_NOUVEAU + help + Support for sil164 and similar single-link (or dual-link + when used in pairs) TMDS transmitters, used in some nVidia + video cards. + endmenu diff --git a/include/drm/i2c/sil164.h b/include/drm/i2c/sil164.h new file mode 100644 index 0000000..205e273 --- /dev/null +++ b/include/drm/i2c/sil164.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2010 Francisco Jerez. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __DRM_I2C_SIL164_H__ +#define __DRM_I2C_SIL164_H__ + +/** + * struct sil164_encoder_params + * + * Describes how the sil164 is connected to the GPU. It should be used + * as the @params parameter of its @set_config method. + * + * See "http://www.siliconimage.com/docs/SiI-DS-0021-E-164.pdf". + */ +struct sil164_encoder_params { + enum { + SIL164_INPUT_EDGE_FALLING = 0, + SIL164_INPUT_EDGE_RISING + } input_edge; + + enum { + SIL164_INPUT_WIDTH_12BIT = 0, + SIL164_INPUT_WIDTH_24BIT + } input_width; + + enum { + SIL164_INPUT_SINGLE_EDGE = 0, + SIL164_INPUT_DUAL_EDGE + } input_dual; + + enum { + SIL164_PLL_FILTER_ON = 0, + SIL164_PLL_FILTER_OFF, + } pll_filter; + + int input_skew; /** < Allowed range [-4, 3], use 0 for no de-skew. */ + int duallink_skew; /** < Allowed range [-4, 3]. */ +}; + +#endif -- cgit v0.10.2 From d9fdaafbe912a34ef06ed569c6606fe2811f325b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Aug 2010 10:42:55 +1000 Subject: drm/radeon/kms: move a bunch of modesetting debug to correct debug usage. This migrates a bunch of DRM_DEBUG->DRM_DEBUG_KMS so we can get more modesetting related info without all the other ioctl handling easily. Also the PM code moves to DRM_DEBUG_DRIVER mostly. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index ec70234..a2e65d9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -818,7 +818,7 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, /* no fb bound */ if (!crtc->fb) { - DRM_DEBUG("No FB bound\n"); + DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -957,7 +957,7 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, /* no fb bound */ if (!crtc->fb) { - DRM_DEBUG("No FB bound\n"); + DRM_DEBUG_KMS("No FB bound\n"); return 0; } diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index abffb14..36e0d4b 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -296,7 +296,7 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], u8 this_v = dp_get_adjust_request_voltage(link_status, lane); u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane); - DRM_DEBUG("requested signal parameters: lane %d voltage %s pre_emph %s\n", + DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n", lane, voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT], pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); @@ -313,7 +313,7 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], if (p >= dp_pre_emphasis_max(v)) p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; - DRM_DEBUG("using signal parameters: voltage %s pre_emph %s\n", + DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n", voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT], pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); @@ -358,7 +358,7 @@ retry: if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) { if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10) goto retry; - DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n", + DRM_DEBUG_KMS("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n", req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], chan->rec.i2c_id, args.v1.ucReplyStatus, retry_count); return false; @@ -461,10 +461,10 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) memcpy(dig_connector->dpcd, msg, 8); { int i; - DRM_DEBUG("DPCD: "); + DRM_DEBUG_KMS("DPCD: "); for (i = 0; i < 8; i++) - DRM_DEBUG("%02x ", msg[i]); - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("%02x ", msg[i]); + DRM_DEBUG_KMS("\n"); } return true; } @@ -512,7 +512,7 @@ static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector, return false; } - DRM_DEBUG("link status %02x %02x %02x %02x %02x %02x\n", + DRM_DEBUG_KMS("link status %02x %02x %02x %02x %02x %02x\n", link_status[0], link_status[1], link_status[2], link_status[3], link_status[4], link_status[5]); return true; @@ -695,7 +695,7 @@ void dp_link_train(struct drm_encoder *encoder, if (!clock_recovery) DRM_ERROR("clock recovery failed\n"); else - DRM_DEBUG("clock recovery at voltage %d pre-emphasis %d\n", + DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n", train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT); @@ -739,7 +739,7 @@ void dp_link_train(struct drm_encoder *encoder, if (!channel_eq) DRM_ERROR("channel eq failed\n"); else - DRM_DEBUG("channel eq at voltage %d pre-emphasis %d\n", + DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n", train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e115583..4c48df4 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -141,7 +141,7 @@ void r100_pm_get_dynpm_state(struct radeon_device *rdev) /* only one clock mode per power state */ rdev->pm.requested_clock_mode_index = 0; - DRM_DEBUG("Requested: e: %d m: %d p: %d\n", + DRM_DEBUG_DRIVER("Requested: e: %d m: %d p: %d\n", rdev->pm.power_state[rdev->pm.requested_power_state_index]. clock_info[rdev->pm.requested_clock_mode_index].sclk, rdev->pm.power_state[rdev->pm.requested_power_state_index]. @@ -276,7 +276,7 @@ void r100_pm_misc(struct radeon_device *rdev) rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) { radeon_set_pcie_lanes(rdev, ps->pcie_lanes); - DRM_DEBUG("Setting: p: %d\n", ps->pcie_lanes); + DRM_DEBUG_DRIVER("Setting: p: %d\n", ps->pcie_lanes); } } @@ -849,7 +849,7 @@ static int r100_cp_init_microcode(struct radeon_device *rdev) const char *fw_name = NULL; int err; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); err = IS_ERR(pdev); @@ -2642,7 +2642,7 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg, flags |= pitch / 8; - DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); + DRM_DEBUG_KMS("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); WREG32(RADEON_SURFACE0_INFO + surf_index, flags); WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1); @@ -3038,7 +3038,7 @@ void r100_bandwidth_update(struct radeon_device *rdev) } #endif - DRM_DEBUG("GRPH_BUFFER_CNTL from to %x\n", + DRM_DEBUG_KMS("GRPH_BUFFER_CNTL from to %x\n", /* (unsigned int)info->SavedReg->grph_buffer_cntl, */ (unsigned int)RREG32(RADEON_GRPH_BUFFER_CNTL)); } @@ -3134,7 +3134,7 @@ void r100_bandwidth_update(struct radeon_device *rdev) WREG32(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC); } - DRM_DEBUG("GRPH2_BUFFER_CNTL from to %x\n", + DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n", (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); } } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 28e39bc..d0ebae9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -271,7 +271,7 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev) } } - DRM_DEBUG("Requested: e: %d m: %d p: %d\n", + DRM_DEBUG_DRIVER("Requested: e: %d m: %d p: %d\n", rdev->pm.power_state[rdev->pm.requested_power_state_index]. clock_info[rdev->pm.requested_clock_mode_index].sclk, rdev->pm.power_state[rdev->pm.requested_power_state_index]. @@ -586,7 +586,7 @@ void r600_pm_misc(struct radeon_device *rdev) if (voltage->voltage != rdev->pm.current_vddc) { radeon_atom_set_voltage(rdev, voltage->voltage); rdev->pm.current_vddc = voltage->voltage; - DRM_DEBUG("Setting: v: %d\n", voltage->voltage); + DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage); } } } diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 0a97aeb..6df7bd5 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -723,7 +723,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct } if (i == ATOM_DEVICE_CV_INDEX) { - DRM_DEBUG("Skipping Component Video\n"); + DRM_DEBUG_KMS("Skipping Component Video\n"); continue; } @@ -1095,7 +1095,7 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, (tmds_info->asMiscInfo[i]. ucPLL_VoltageSwing & 0xf) << 16; - DRM_DEBUG("TMDS PLL From ATOMBIOS %u %x\n", + DRM_DEBUG_KMS("TMDS PLL From ATOMBIOS %u %x\n", tmds->tmds_pll[i].freq, tmds->tmds_pll[i].value); @@ -2187,11 +2187,11 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { if (connected) { - DRM_DEBUG("TV1 connected\n"); + DRM_DEBUG_KMS("TV1 connected\n"); bios_3_scratch |= ATOM_S3_TV1_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_TV1; } else { - DRM_DEBUG("TV1 disconnected\n"); + DRM_DEBUG_KMS("TV1 disconnected\n"); bios_0_scratch &= ~ATOM_S0_TV1_MASK; bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_TV1; @@ -2200,11 +2200,11 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT)) { if (connected) { - DRM_DEBUG("CV connected\n"); + DRM_DEBUG_KMS("CV connected\n"); bios_3_scratch |= ATOM_S3_CV_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_CV; } else { - DRM_DEBUG("CV disconnected\n"); + DRM_DEBUG_KMS("CV disconnected\n"); bios_0_scratch &= ~ATOM_S0_CV_MASK; bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_CV; @@ -2213,12 +2213,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { if (connected) { - DRM_DEBUG("LCD1 connected\n"); + DRM_DEBUG_KMS("LCD1 connected\n"); bios_0_scratch |= ATOM_S0_LCD1; bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1; } else { - DRM_DEBUG("LCD1 disconnected\n"); + DRM_DEBUG_KMS("LCD1 disconnected\n"); bios_0_scratch &= ~ATOM_S0_LCD1; bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1; @@ -2227,12 +2227,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { if (connected) { - DRM_DEBUG("CRT1 connected\n"); + DRM_DEBUG_KMS("CRT1 connected\n"); bios_0_scratch |= ATOM_S0_CRT1_COLOR; bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1; } else { - DRM_DEBUG("CRT1 disconnected\n"); + DRM_DEBUG_KMS("CRT1 disconnected\n"); bios_0_scratch &= ~ATOM_S0_CRT1_MASK; bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1; @@ -2241,12 +2241,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { if (connected) { - DRM_DEBUG("CRT2 connected\n"); + DRM_DEBUG_KMS("CRT2 connected\n"); bios_0_scratch |= ATOM_S0_CRT2_COLOR; bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2; } else { - DRM_DEBUG("CRT2 disconnected\n"); + DRM_DEBUG_KMS("CRT2 disconnected\n"); bios_0_scratch &= ~ATOM_S0_CRT2_MASK; bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2; @@ -2255,12 +2255,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { if (connected) { - DRM_DEBUG("DFP1 connected\n"); + DRM_DEBUG_KMS("DFP1 connected\n"); bios_0_scratch |= ATOM_S0_DFP1; bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1; } else { - DRM_DEBUG("DFP1 disconnected\n"); + DRM_DEBUG_KMS("DFP1 disconnected\n"); bios_0_scratch &= ~ATOM_S0_DFP1; bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1; @@ -2269,12 +2269,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { if (connected) { - DRM_DEBUG("DFP2 connected\n"); + DRM_DEBUG_KMS("DFP2 connected\n"); bios_0_scratch |= ATOM_S0_DFP2; bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2; } else { - DRM_DEBUG("DFP2 disconnected\n"); + DRM_DEBUG_KMS("DFP2 disconnected\n"); bios_0_scratch &= ~ATOM_S0_DFP2; bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2; @@ -2283,12 +2283,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) { if (connected) { - DRM_DEBUG("DFP3 connected\n"); + DRM_DEBUG_KMS("DFP3 connected\n"); bios_0_scratch |= ATOM_S0_DFP3; bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3; } else { - DRM_DEBUG("DFP3 disconnected\n"); + DRM_DEBUG_KMS("DFP3 disconnected\n"); bios_0_scratch &= ~ATOM_S0_DFP3; bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3; @@ -2297,12 +2297,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) { if (connected) { - DRM_DEBUG("DFP4 connected\n"); + DRM_DEBUG_KMS("DFP4 connected\n"); bios_0_scratch |= ATOM_S0_DFP4; bios_3_scratch |= ATOM_S3_DFP4_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4; } else { - DRM_DEBUG("DFP4 disconnected\n"); + DRM_DEBUG_KMS("DFP4 disconnected\n"); bios_0_scratch &= ~ATOM_S0_DFP4; bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4; @@ -2311,12 +2311,12 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) { if (connected) { - DRM_DEBUG("DFP5 connected\n"); + DRM_DEBUG_KMS("DFP5 connected\n"); bios_0_scratch |= ATOM_S0_DFP5; bios_3_scratch |= ATOM_S3_DFP5_ACTIVE; bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5; } else { - DRM_DEBUG("DFP5 disconnected\n"); + DRM_DEBUG_KMS("DFP5 disconnected\n"); bios_0_scratch &= ~ATOM_S0_DFP5; bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE; bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 5e45cb2..cd2a6c25 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -1205,7 +1205,7 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, RBIOS32(tmds_info + i * 10 + 0x08); tmds->tmds_pll[i].freq = RBIOS16(tmds_info + i * 10 + 0x10); - DRM_DEBUG("TMDS PLL From COMBIOS %u %x\n", + DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n", tmds->tmds_pll[i].freq, tmds->tmds_pll[i].value); } @@ -1223,7 +1223,7 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, stride += 10; else stride += 6; - DRM_DEBUG("TMDS PLL From COMBIOS %u %x\n", + DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n", tmds->tmds_pll[i].freq, tmds->tmds_pll[i].value); } @@ -2208,7 +2208,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) uint16_t tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); if (tmds_info) { - DRM_DEBUG("Found DFP table, assuming DVI connector\n"); + DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -2234,7 +2234,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) } else { uint16_t crt_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); - DRM_DEBUG("Found CRT table, assuming VGA connector\n"); + DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); if (crt_info) { radeon_add_legacy_encoder(dev, radeon_get_encoder_id(dev, @@ -2251,7 +2251,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) CONNECTOR_OBJECT_ID_VGA, &hpd); } else { - DRM_DEBUG("No connector info found\n"); + DRM_DEBUG_KMS("No connector info found\n"); return false; } } @@ -2340,7 +2340,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) ddc_i2c.valid = false; break; } - DRM_DEBUG("LCD DDC Info Table found!\n"); + DRM_DEBUG_KMS("LCD DDC Info Table found!\n"); } else ddc_i2c.valid = false; @@ -3118,14 +3118,14 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { if (connected) { - DRM_DEBUG("TV1 connected\n"); + DRM_DEBUG_KMS("TV1 connected\n"); /* fix me */ bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; /*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */ bios_5_scratch |= RADEON_TV1_ON; bios_5_scratch |= RADEON_ACC_REQ_TV1; } else { - DRM_DEBUG("TV1 disconnected\n"); + DRM_DEBUG_KMS("TV1 disconnected\n"); bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK; bios_5_scratch &= ~RADEON_TV1_ON; bios_5_scratch &= ~RADEON_ACC_REQ_TV1; @@ -3134,12 +3134,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { if (connected) { - DRM_DEBUG("LCD1 connected\n"); + DRM_DEBUG_KMS("LCD1 connected\n"); bios_4_scratch |= RADEON_LCD1_ATTACHED; bios_5_scratch |= RADEON_LCD1_ON; bios_5_scratch |= RADEON_ACC_REQ_LCD1; } else { - DRM_DEBUG("LCD1 disconnected\n"); + DRM_DEBUG_KMS("LCD1 disconnected\n"); bios_4_scratch &= ~RADEON_LCD1_ATTACHED; bios_5_scratch &= ~RADEON_LCD1_ON; bios_5_scratch &= ~RADEON_ACC_REQ_LCD1; @@ -3148,12 +3148,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { if (connected) { - DRM_DEBUG("CRT1 connected\n"); + DRM_DEBUG_KMS("CRT1 connected\n"); bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; bios_5_scratch |= RADEON_CRT1_ON; bios_5_scratch |= RADEON_ACC_REQ_CRT1; } else { - DRM_DEBUG("CRT1 disconnected\n"); + DRM_DEBUG_KMS("CRT1 disconnected\n"); bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; bios_5_scratch &= ~RADEON_CRT1_ON; bios_5_scratch &= ~RADEON_ACC_REQ_CRT1; @@ -3162,12 +3162,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { if (connected) { - DRM_DEBUG("CRT2 connected\n"); + DRM_DEBUG_KMS("CRT2 connected\n"); bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; bios_5_scratch |= RADEON_CRT2_ON; bios_5_scratch |= RADEON_ACC_REQ_CRT2; } else { - DRM_DEBUG("CRT2 disconnected\n"); + DRM_DEBUG_KMS("CRT2 disconnected\n"); bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; bios_5_scratch &= ~RADEON_CRT2_ON; bios_5_scratch &= ~RADEON_ACC_REQ_CRT2; @@ -3176,12 +3176,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { if (connected) { - DRM_DEBUG("DFP1 connected\n"); + DRM_DEBUG_KMS("DFP1 connected\n"); bios_4_scratch |= RADEON_DFP1_ATTACHED; bios_5_scratch |= RADEON_DFP1_ON; bios_5_scratch |= RADEON_ACC_REQ_DFP1; } else { - DRM_DEBUG("DFP1 disconnected\n"); + DRM_DEBUG_KMS("DFP1 disconnected\n"); bios_4_scratch &= ~RADEON_DFP1_ATTACHED; bios_5_scratch &= ~RADEON_DFP1_ON; bios_5_scratch &= ~RADEON_ACC_REQ_DFP1; @@ -3190,12 +3190,12 @@ radeon_combios_connected_scratch_regs(struct drm_connector *connector, if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { if (connected) { - DRM_DEBUG("DFP2 connected\n"); + DRM_DEBUG_KMS("DFP2 connected\n"); bios_4_scratch |= RADEON_DFP2_ATTACHED; bios_5_scratch |= RADEON_DFP2_ON; bios_5_scratch |= RADEON_ACC_REQ_DFP2; } else { - DRM_DEBUG("DFP2 disconnected\n"); + DRM_DEBUG_KMS("DFP2 disconnected\n"); bios_4_scratch &= ~RADEON_DFP2_ATTACHED; bios_5_scratch &= ~RADEON_DFP2_ON; bios_5_scratch &= ~RADEON_ACC_REQ_DFP2; diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index adccbc2..41286c9 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -214,7 +214,7 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; drm_mode_set_name(mode); - DRM_DEBUG("Adding native panel mode %s\n", mode->name); + DRM_DEBUG_KMS("Adding native panel mode %s\n", mode->name); } else if (native_mode->hdisplay != 0 && native_mode->vdisplay != 0) { /* mac laptops without an edid */ @@ -226,7 +226,7 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode */ mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; - DRM_DEBUG("Adding cvt approximation of native panel mode %s\n", mode->name); + DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name); } return mode; } @@ -522,7 +522,7 @@ static int radeon_lvds_set_property(struct drm_connector *connector, struct radeon_encoder *radeon_encoder; enum radeon_rmx_type rmx_type; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); if (property != dev->mode_config.scaling_mode_property) return 0; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index a68728d..283beed 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -42,7 +42,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc) struct radeon_device *rdev = dev->dev_private; int i; - DRM_DEBUG("%d\n", radeon_crtc->crtc_id); + DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0); WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); @@ -75,7 +75,7 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc) struct radeon_device *rdev = dev->dev_private; int i; - DRM_DEBUG("%d\n", radeon_crtc->crtc_id); + DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); @@ -469,7 +469,7 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll, uint32_t post_div; u32 pll_out_min, pll_out_max; - DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); + DRM_DEBUG_KMS("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); freq = freq * 1000; if (pll->flags & RADEON_PLL_IS_LCD) { @@ -805,7 +805,7 @@ done: *ref_div_p = ref_div; *post_div_p = post_div; - DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p); + DRM_DEBUG_KMS("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p); } void radeon_compute_pll(struct radeon_pll *pll, diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index e0b30b2..5e7a053 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -205,7 +205,7 @@ void radeon_encoder_set_active_device(struct drm_encoder *encoder) if (connector->encoder == encoder) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices; - DRM_DEBUG("setting active device to %08x from %08x %08x for encoder %d\n", + DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n", radeon_encoder->active_device, radeon_encoder->devices, radeon_connector->devices, encoder->encoder_type); } @@ -1021,7 +1021,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) memset(&args, 0, sizeof(args)); - DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", + DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", radeon_encoder->encoder_id, mode, radeon_encoder->devices, radeon_encoder->active_device); switch (radeon_encoder->encoder_id) { @@ -1484,7 +1484,7 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec uint32_t bios_0_scratch; if (!atombios_dac_load_detect(encoder, connector)) { - DRM_DEBUG("detect returned false \n"); + DRM_DEBUG_KMS("detect returned false \n"); return connector_status_unknown; } @@ -1493,7 +1493,7 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec else bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); - DRM_DEBUG("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); + DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { if (bios_0_scratch & ATOM_S0_CRT1_MASK) return connector_status_connected; diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 8931c8e..dd0a78e9 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -141,7 +141,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } } if (!found) { - DRM_DEBUG("unknown crtc id %d\n", value); + DRM_DEBUG_KMS("unknown crtc id %d\n", value); return -EINVAL; } break; @@ -156,12 +156,12 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) else if (rdev->family >= CHIP_R600) value = rdev->config.r600.tile_config; else { - DRM_DEBUG("tiling config is r6xx+ only!\n"); + DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); return -EINVAL; } break; default: - DRM_DEBUG("Invalid request %d\n", info->request); + DRM_DEBUG_KMS("Invalid request %d\n", info->request); return -EINVAL; } if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index e1e5255..989df51 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -362,10 +362,10 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, uint32_t gen_cntl_reg, gen_cntl_val; int r; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); /* no fb bound */ if (!crtc->fb) { - DRM_DEBUG("No FB bound\n"); + DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -528,7 +528,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod uint32_t crtc_v_sync_strt_wid; bool is_tv = false; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->crtc == crtc) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -757,7 +757,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) } } - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); if (!use_bios_divs) { radeon_compute_pll(pll, mode->clock, @@ -772,7 +772,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) if (!post_div->divider) post_div = &post_divs[0]; - DRM_DEBUG("dc=%u, fd=%d, rd=%d, pd=%d\n", + DRM_DEBUG_KMS("dc=%u, fd=%d, rd=%d, pd=%d\n", (unsigned)freq, feedback_div, reference_div, @@ -841,12 +841,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | RADEON_P2PLL_SLEEP | RADEON_P2PLL_ATOMIC_UPDATE_EN)); - DRM_DEBUG("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n", + DRM_DEBUG_KMS("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n", (unsigned)pll_ref_div, (unsigned)pll_fb_post_div, (unsigned)htotal_cntl, RREG32_PLL(RADEON_P2PLL_CNTL)); - DRM_DEBUG("Wrote2: rd=%u, fd=%u, pd=%u\n", + DRM_DEBUG_KMS("Wrote2: rd=%u, fd=%u, pd=%u\n", (unsigned)pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, (unsigned)pll_fb_post_div & RADEON_P2PLL_FB0_DIV_MASK, (unsigned)((pll_fb_post_div & @@ -947,12 +947,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | RADEON_PPLL_ATOMIC_UPDATE_EN | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); - DRM_DEBUG("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", + DRM_DEBUG_KMS("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", pll_ref_div, pll_fb_post_div, (unsigned)htotal_cntl, RREG32_PLL(RADEON_PPLL_CNTL)); - DRM_DEBUG("Wrote: rd=%d, fd=%d, pd=%d\n", + DRM_DEBUG_KMS("Wrote: rd=%d, fd=%d, pd=%d\n", pll_ref_div & RADEON_PPLL_REF_DIV_MASK, pll_fb_post_div & RADEON_PPLL_FB3_DIV_MASK, (pll_fb_post_div & RADEON_PPLL_POST3_DIV_MASK) >> 16); diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 5688a0c..b8149cb 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -47,7 +47,7 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; int panel_pwr_delay = 2000; bool is_mac = false; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); if (radeon_encoder->enc_priv) { if (rdev->is_atom_bios) { @@ -151,7 +151,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; @@ -167,7 +167,7 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, } else { struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; if (lvds) { - DRM_DEBUG("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); + DRM_DEBUG_KMS("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); lvds_gen_cntl = lvds->lvds_gen_cntl; lvds_ss_gen_cntl &= ~((0xf << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) | (0xf << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); @@ -250,7 +250,7 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode uint32_t dac_cntl = RREG32(RADEON_DAC_CNTL); uint32_t dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL); - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); switch (mode) { case DRM_MODE_DPMS_ON: @@ -315,7 +315,7 @@ static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); if (radeon_crtc->crtc_id == 0) { if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) { @@ -446,7 +446,7 @@ static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; uint32_t fp_gen_cntl = RREG32(RADEON_FP_GEN_CNTL); - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); switch (mode) { case DRM_MODE_DPMS_ON: @@ -502,7 +502,7 @@ static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl; int i; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); tmp = tmds_pll_cntl = RREG32(RADEON_TMDS_PLL_CNTL); tmp &= 0xfffff; @@ -610,7 +610,7 @@ static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; uint32_t fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); switch (mode) { case DRM_MODE_DPMS_ON: @@ -666,7 +666,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); uint32_t fp2_gen_cntl; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); if (rdev->is_atom_bios) { radeon_encoder->pixel_clock = adjusted_mode->clock; @@ -760,7 +760,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; uint32_t tv_master_cntl = 0; bool is_tv; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; @@ -878,7 +878,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0; bool is_tv = false; - DRM_DEBUG("\n"); + DRM_DEBUG_KMS("\n"); is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; @@ -1075,10 +1075,10 @@ static bool r300_legacy_tv_detect(struct drm_encoder *encoder, tmp = RREG32(RADEON_TV_DAC_CNTL); if ((tmp & RADEON_TV_DAC_GDACDET) != 0) { found = true; - DRM_DEBUG("S-video TV connection detected\n"); + DRM_DEBUG_KMS("S-video TV connection detected\n"); } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { found = true; - DRM_DEBUG("Composite TV connection detected\n"); + DRM_DEBUG_KMS("Composite TV connection detected\n"); } WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); @@ -1141,10 +1141,10 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, tmp = RREG32(RADEON_TV_DAC_CNTL); if (tmp & RADEON_TV_DAC_GDACDET) { found = true; - DRM_DEBUG("S-video TV connection detected\n"); + DRM_DEBUG_KMS("S-video TV connection detected\n"); } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { found = true; - DRM_DEBUG("Composite TV connection detected\n"); + DRM_DEBUG_KMS("Composite TV connection detected\n"); } WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl); diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c index 0320403..c7b6cb4 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_tv.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c @@ -496,7 +496,7 @@ static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder) restart -= v_offset + h_offset; - DRM_DEBUG("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n", + DRM_DEBUG_KMS("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n", const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart); tv_dac->tv.hrestart = restart % h_total; @@ -505,7 +505,7 @@ static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder) restart /= v_total; tv_dac->tv.frestart = restart % f_total; - DRM_DEBUG("compute_restart: F/H/V=%u,%u,%u\n", + DRM_DEBUG_KMS("compute_restart: F/H/V=%u,%u,%u\n", (unsigned)tv_dac->tv.frestart, (unsigned)tv_dac->tv.vrestart, (unsigned)tv_dac->tv.hrestart); @@ -523,7 +523,7 @@ static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder) tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) | ((u32)h_inc << RADEON_H_INC_SHIFT); - DRM_DEBUG("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc); + DRM_DEBUG_KMS("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc); return h_changed; } diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index ed66062..a3d25f419 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -62,9 +62,9 @@ static int radeon_acpi_event(struct notifier_block *nb, if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { if (power_supply_is_system_supplied() > 0) - DRM_DEBUG("pm: AC\n"); + DRM_DEBUG_DRIVER("pm: AC\n"); else - DRM_DEBUG("pm: DC\n"); + DRM_DEBUG_DRIVER("pm: DC\n"); if (rdev->pm.pm_method == PM_METHOD_PROFILE) { if (rdev->pm.profile == PM_PROFILE_AUTO) { @@ -198,7 +198,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) radeon_set_engine_clock(rdev, sclk); radeon_pm_debug_check_in_vbl(rdev, true); rdev->pm.current_sclk = sclk; - DRM_DEBUG("Setting: e: %d\n", sclk); + DRM_DEBUG_DRIVER("Setting: e: %d\n", sclk); } /* set memory clock */ @@ -207,7 +207,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) radeon_set_memory_clock(rdev, mclk); radeon_pm_debug_check_in_vbl(rdev, true); rdev->pm.current_mclk = mclk; - DRM_DEBUG("Setting: m: %d\n", mclk); + DRM_DEBUG_DRIVER("Setting: m: %d\n", mclk); } if (misc_after) @@ -219,7 +219,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; } else - DRM_DEBUG("pm: GUI not idle!!!\n"); + DRM_DEBUG_DRIVER("pm: GUI not idle!!!\n"); } static void radeon_pm_set_clocks(struct radeon_device *rdev) @@ -294,27 +294,27 @@ static void radeon_pm_print_states(struct radeon_device *rdev) struct radeon_power_state *power_state; struct radeon_pm_clock_info *clock_info; - DRM_DEBUG("%d Power State(s)\n", rdev->pm.num_power_states); + DRM_DEBUG_DRIVER("%d Power State(s)\n", rdev->pm.num_power_states); for (i = 0; i < rdev->pm.num_power_states; i++) { power_state = &rdev->pm.power_state[i]; - DRM_DEBUG("State %d: %s\n", i, + DRM_DEBUG_DRIVER("State %d: %s\n", i, radeon_pm_state_type_name[power_state->type]); if (i == rdev->pm.default_power_state_index) - DRM_DEBUG("\tDefault"); + DRM_DEBUG_DRIVER("\tDefault"); if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP)) - DRM_DEBUG("\t%d PCIE Lanes\n", power_state->pcie_lanes); + DRM_DEBUG_DRIVER("\t%d PCIE Lanes\n", power_state->pcie_lanes); if (power_state->flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - DRM_DEBUG("\tSingle display only\n"); - DRM_DEBUG("\t%d Clock Mode(s)\n", power_state->num_clock_modes); + DRM_DEBUG_DRIVER("\tSingle display only\n"); + DRM_DEBUG_DRIVER("\t%d Clock Mode(s)\n", power_state->num_clock_modes); for (j = 0; j < power_state->num_clock_modes; j++) { clock_info = &(power_state->clock_info[j]); if (rdev->flags & RADEON_IS_IGP) - DRM_DEBUG("\t\t%d e: %d%s\n", + DRM_DEBUG_DRIVER("\t\t%d e: %d%s\n", j, clock_info->sclk * 10, clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : ""); else - DRM_DEBUG("\t\t%d e: %d\tm: %d\tv: %d%s\n", + DRM_DEBUG_DRIVER("\t\t%d e: %d\tm: %d\tv: %d%s\n", j, clock_info->sclk * 10, clock_info->mclk * 10, @@ -657,7 +657,7 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) radeon_pm_get_dynpm_state(rdev); radeon_pm_set_clocks(rdev); - DRM_DEBUG("radeon: dynamic power management deactivated\n"); + DRM_DEBUG_DRIVER("radeon: dynamic power management deactivated\n"); } } else if (rdev->pm.active_crtc_count == 1) { /* TODO: Increase clocks if needed for current mode */ @@ -674,7 +674,7 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); - DRM_DEBUG("radeon: dynamic power management activated\n"); + DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n"); } } else { /* count == 0 */ if (rdev->pm.dynpm_state != DYNPM_STATE_MINIMUM) { @@ -770,7 +770,7 @@ static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish bool in_vbl = radeon_pm_in_vbl(rdev); if (in_vbl == false) - DRM_DEBUG("not in vbl for pm change %08x at %s\n", stat_crtc, + DRM_DEBUG_DRIVER("not in vbl for pm change %08x at %s\n", stat_crtc, finish ? "exit" : "entry"); return in_vbl; } -- cgit v0.10.2 From ab9e1f5966591dc3e811418e96ba04f284c52458 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 13 Jul 2010 11:11:11 +1000 Subject: drm/radeon: add basic zmask/hiz support (v4) This interface allows userspace to request hyperz support, it probably needs more locking, and really reporting that you can have hyperz is racy since someone else might get it before you do. v2: modify so we pass 0 valued packets to let DDX/r300c keep working. also fixed incorrect 0x4f1c reference. v3: fixup zb_bw_cntl so older drivers keep working v4: add locking, fixup SC_HYPERZ_EN - patch stream to disable hiz Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 4c48df4..e817a0b 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1803,6 +1803,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p, return r; break; /* triggers drawing using indices to vertex buffer */ + case PACKET3_3D_CLEAR_HIZ: + case PACKET3_3D_CLEAR_ZMASK: + if (p->rdev->hyperz_filp != p->filp) + return -EINVAL; + break; case PACKET3_NOP: break; default: diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h index d016b16..b121b6c 100644 --- a/drivers/gpu/drm/radeon/r100d.h +++ b/drivers/gpu/drm/radeon/r100d.h @@ -48,10 +48,12 @@ #define PACKET3_3D_DRAW_IMMD 0x29 #define PACKET3_3D_DRAW_INDX 0x2A #define PACKET3_3D_LOAD_VBPNTR 0x2F +#define PACKET3_3D_CLEAR_ZMASK 0x32 #define PACKET3_INDX_BUFFER 0x33 #define PACKET3_3D_DRAW_VBUF_2 0x34 #define PACKET3_3D_DRAW_IMMD_2 0x35 #define PACKET3_3D_DRAW_INDX_2 0x36 +#define PACKET3_3D_CLEAR_HIZ 0x37 #define PACKET3_BITBLT_MULTI 0x9B #define PACKET0(reg, n) (CP_PACKET0 | \ diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 58eab5d..c827738 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1048,14 +1048,47 @@ static int r300_packet0_check(struct radeon_cs_parser *p, /* RB3D_COLOR_CHANNEL_MASK */ track->color_channel_mask = idx_value; break; - case 0x4d1c: + case 0x43a4: + /* SC_HYPERZ_EN */ + /* r300c emits this register - we need to disable hyperz for it + * without complaining */ + if (p->rdev->hyperz_filp != p->filp) { + if (idx_value & 0x1) + ib[idx] = idx_value & ~1; + } + break; + case 0x4f1c: /* ZB_BW_CNTL */ track->zb_cb_clear = !!(idx_value & (1 << 5)); + if (p->rdev->hyperz_filp != p->filp) { + if (idx_value & (R300_HIZ_ENABLE | + R300_RD_COMP_ENABLE | + R300_WR_COMP_ENABLE | + R300_FAST_FILL_ENABLE)) + goto fail; + } break; case 0x4e04: /* RB3D_BLENDCNTL */ track->blend_read_enable = !!(idx_value & (1 << 2)); break; + case 0x4f28: /* ZB_DEPTHCLEARVALUE */ + break; + case 0x4f30: /* ZB_MASK_OFFSET */ + case 0x4f34: /* ZB_ZMASK_PITCH */ + case 0x4f44: /* ZB_HIZ_OFFSET */ + case 0x4f54: /* ZB_HIZ_PITCH */ + if (idx_value && (p->rdev->hyperz_filp != p->filp)) + goto fail; + break; + case 0x4028: + if (idx_value && (p->rdev->hyperz_filp != p->filp)) + goto fail; + /* GB_Z_PEQ_CONFIG */ + if (p->rdev->family >= CHIP_RV350) + break; + goto fail; + break; case 0x4be8: /* valid register only on RV530 */ if (p->rdev->family == CHIP_RV530) @@ -1066,8 +1099,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, } return 0; fail: - printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", - reg, idx); + printk(KERN_ERR "Forbidden register 0x%04X in cs at %d (val=%08x)\n", + reg, idx, idx_value); return -EINVAL; } @@ -1161,6 +1194,11 @@ static int r300_packet3_check(struct radeon_cs_parser *p, return r; } break; + case PACKET3_3D_CLEAR_HIZ: + case PACKET3_3D_CLEAR_ZMASK: + if (p->rdev->hyperz_filp != p->filp) + return -EINVAL; + break; case PACKET3_NOP: break; default: diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h index 968a333..0c036c6 100644 --- a/drivers/gpu/drm/radeon/r300d.h +++ b/drivers/gpu/drm/radeon/r300d.h @@ -48,10 +48,12 @@ #define PACKET3_3D_DRAW_IMMD 0x29 #define PACKET3_3D_DRAW_INDX 0x2A #define PACKET3_3D_LOAD_VBPNTR 0x2F +#define PACKET3_3D_CLEAR_ZMASK 0x32 #define PACKET3_INDX_BUFFER 0x33 #define PACKET3_3D_DRAW_VBUF_2 0x34 #define PACKET3_3D_DRAW_IMMD_2 0x35 #define PACKET3_3D_DRAW_INDX_2 0x36 +#define PACKET3_3D_CLEAR_HIZ 0x37 #define PACKET3_BITBLT_MULTI 0x9B #define PACKET0(reg, n) (CP_PACKET0 | \ diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index c84f9a3..368fecf0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1098,6 +1098,8 @@ struct radeon_device { bool powered_down; struct notifier_block acpi_nb; + /* only one userspace can use Hyperz features at a time */ + struct drm_file *hyperz_filp; }; int radeon_device_init(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 6f8a2e5..795403b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -46,7 +46,7 @@ * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs * - 2.4.0 - add crtc id query * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen - * - 2.6.0 - add tiling config query (r6xx+) + * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) */ #define KMS_DRIVER_MAJOR 2 #define KMS_DRIVER_MINOR 6 diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index dd0a78e9..e5b7054 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -159,6 +159,15 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); return -EINVAL; } + case RADEON_INFO_WANT_HYPERZ: + mutex_lock(&dev->struct_mutex); + if (rdev->hyperz_filp) + value = 0; + else { + rdev->hyperz_filp = filp; + value = 1; + } + mutex_unlock(&dev->struct_mutex); break; default: DRM_DEBUG_KMS("Invalid request %d\n", info->request); @@ -199,9 +208,11 @@ void radeon_driver_postclose_kms(struct drm_device *dev, void radeon_driver_preclose_kms(struct drm_device *dev, struct drm_file *file_priv) { + struct radeon_device *rdev = dev->dev_private; + if (rdev->hyperz_filp == file_priv) + rdev->hyperz_filp = NULL; } - /* * VBlank related functions. */ diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 index 1e97b2d..b506ec1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 @@ -187,7 +187,6 @@ r300 0x4f60 0x4364 RS_INST_13 0x4368 RS_INST_14 0x436C RS_INST_15 -0x43A4 SC_HYPERZ_EN 0x43A8 SC_EDGERULE 0x43B0 SC_CLIP_0_A 0x43B4 SC_CLIP_0_B @@ -716,16 +715,4 @@ r300 0x4f60 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT -0x4F1C ZB_BW_CNTL -0x4F28 ZB_DEPTHCLEARVALUE -0x4F30 ZB_ZMASK_OFFSET -0x4F34 ZB_ZMASK_PITCH -0x4F38 ZB_ZMASK_WRINDEX -0x4F3C ZB_ZMASK_DWORD -0x4F40 ZB_ZMASK_RDINDEX -0x4F44 ZB_HIZ_OFFSET -0x4F48 ZB_HIZ_WRINDEX -0x4F4C ZB_HIZ_DWORD -0x4F50 ZB_HIZ_RDINDEX -0x4F54 ZB_HIZ_PITCH 0x4F58 ZB_ZPASS_DATA diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 index e958980..8c1214c 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 @@ -130,6 +130,7 @@ r420 0x4f60 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE +0x4028 GB_Z_PEQ_CONFIG 0x4100 TX_INVALTAGS 0x4200 GA_POINT_S0 0x4204 GA_POINT_T0 @@ -187,7 +188,6 @@ r420 0x4f60 0x4364 RS_INST_13 0x4368 RS_INST_14 0x436C RS_INST_15 -0x43A4 SC_HYPERZ_EN 0x43A8 SC_EDGERULE 0x43B0 SC_CLIP_0_A 0x43B4 SC_CLIP_0_B @@ -782,16 +782,4 @@ r420 0x4f60 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT -0x4F1C ZB_BW_CNTL -0x4F28 ZB_DEPTHCLEARVALUE -0x4F30 ZB_ZMASK_OFFSET -0x4F34 ZB_ZMASK_PITCH -0x4F38 ZB_ZMASK_WRINDEX -0x4F3C ZB_ZMASK_DWORD -0x4F40 ZB_ZMASK_RDINDEX -0x4F44 ZB_HIZ_OFFSET -0x4F48 ZB_HIZ_WRINDEX -0x4F4C ZB_HIZ_DWORD -0x4F50 ZB_HIZ_RDINDEX -0x4F54 ZB_HIZ_PITCH 0x4F58 ZB_ZPASS_DATA diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 83e8bc0..0828d80 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 @@ -187,7 +187,6 @@ rs600 0x6d40 0x4364 RS_INST_13 0x4368 RS_INST_14 0x436C RS_INST_15 -0x43A4 SC_HYPERZ_EN 0x43A8 SC_EDGERULE 0x43B0 SC_CLIP_0_A 0x43B4 SC_CLIP_0_B @@ -782,16 +781,4 @@ rs600 0x6d40 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT -0x4F1C ZB_BW_CNTL -0x4F28 ZB_DEPTHCLEARVALUE -0x4F30 ZB_ZMASK_OFFSET -0x4F34 ZB_ZMASK_PITCH -0x4F38 ZB_ZMASK_WRINDEX -0x4F3C ZB_ZMASK_DWORD -0x4F40 ZB_ZMASK_RDINDEX -0x4F44 ZB_HIZ_OFFSET -0x4F48 ZB_HIZ_WRINDEX -0x4F4C ZB_HIZ_DWORD -0x4F50 ZB_HIZ_RDINDEX -0x4F54 ZB_HIZ_PITCH 0x4F58 ZB_ZPASS_DATA diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 1e46233..8293855 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -235,7 +235,6 @@ rv515 0x6d40 0x4354 RS_INST_13 0x4358 RS_INST_14 0x435C RS_INST_15 -0x43A4 SC_HYPERZ_EN 0x43A8 SC_EDGERULE 0x43B0 SC_CLIP_0_A 0x43B4 SC_CLIP_0_B @@ -479,17 +478,5 @@ rv515 0x6d40 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT -0x4F1C ZB_BW_CNTL -0x4F28 ZB_DEPTHCLEARVALUE -0x4F30 ZB_ZMASK_OFFSET -0x4F34 ZB_ZMASK_PITCH -0x4F38 ZB_ZMASK_WRINDEX -0x4F3C ZB_ZMASK_DWORD -0x4F40 ZB_ZMASK_RDINDEX -0x4F44 ZB_HIZ_OFFSET -0x4F48 ZB_HIZ_WRINDEX -0x4F4C ZB_HIZ_DWORD -0x4F50 ZB_HIZ_RDINDEX -0x4F54 ZB_HIZ_PITCH 0x4F58 ZB_ZPASS_DATA 0x4FD4 ZB_STENCILREFMASK_BF diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index ac5f040..0acaf8f 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -905,6 +905,7 @@ struct drm_radeon_cs { #define RADEON_INFO_CRTC_FROM_ID 0x04 #define RADEON_INFO_ACCEL_WORKING2 0x05 #define RADEON_INFO_TILING_CONFIG 0x06 +#define RADEON_INFO_WANT_HYPERZ 0x07 struct drm_radeon_info { uint32_t request; -- cgit v0.10.2 From 0544edfdc3b8f172944c26b9961ca120feb04798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=A4chler?= Date: Fri, 2 Jul 2010 10:44:23 +0200 Subject: gpu/drm/i915: Add a blacklist to omit modeset on LID open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On some machines (currently only the Toshiba Tecra A11 is known), the GPU locks up when modeset is forced on LID open. This patch adds a new DMI blacklist and omits modesetting for all matches. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=15550 Signed-off-by: Thomas Bächler Reviewed-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 31df55f..0eab8df 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -599,6 +599,26 @@ static int intel_lvds_get_modes(struct drm_connector *connector) return 0; } +static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id) +{ + DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident); + return 1; +} + +/* The GPU hangs up on these systems if modeset is performed on LID open */ +static const struct dmi_system_id intel_no_modeset_on_lid[] = { + { + .callback = intel_no_modeset_on_lid_dmi_callback, + .ident = "Toshiba Tecra A11", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"), + }, + }, + + { } /* terminating entry */ +}; + /* * Lid events. Note the use of 'modeset_on_lid': * - we set it on lid close, and reset it on open @@ -622,6 +642,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, */ if (connector) connector->status = connector->funcs->detect(connector); + /* Don't force modeset on machines where it causes a GPU lockup */ + if (dmi_check_system(intel_no_modeset_on_lid)) + return NOTIFY_OK; if (!acpi_lid_open()) { dev_priv->modeset_on_lid = 1; return NOTIFY_OK; -- cgit v0.10.2 From 43b27f40ebc40758a4acad03ea9fa717ba65d76e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 2 Jul 2010 08:57:15 +0100 Subject: drm/i915: Explosion following OOM in do_execbuffer. Oops, when merging the extra details following an OOM, I missed that driver_private is now NULL and the correct way to convert from the drm_gem_object into the drm_i915_gem_object is to use to_intel_bo(). BUG: unable to handle kernel NULL pointer dereference at 00000069 IP: [] i915_gem_do_execbuffer+0x71f/0xbb6 *pde = 00000000 Oops: 0000 [#1] SMP last sysfs file: /sys/devices/virtual/vc/vcsa3/uevent Pid: 10993, comm: X Not tainted 2.6.35-rc2+ #67 / EIP: 0060:[] EFLAGS: 00213202 CPU: 0 EIP is at i915_gem_do_execbuffer+0x71f/0xbb6 EAX: f647e8a8 EBX: 00000000 ECX: 00000003 EDX: 00000000 ESI: 00424000 EDI: 00000000 EBP: f6508e48 ESP: f6508dd4 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Process X (pid: 10993, ti=f6508000 task=f6432880 task.ti=f6508000) Stack: f6508de0 f7130000 00000001 00000000 00000000 f647e8a8 00000000 f64f8480 <0> f7974414 00000000 00000006 00000000 00000000 f6578000 00000008 00000006 <0> f6797880 00400000 00000000 ffffffe4 f7974400 000000d0 000000d0 000001c0 Call Trace: [] ? i915_gem_execbuffer2+0xa1/0xe7 [] ? drm_ioctl+0x22c/0x2fa [] ? i915_gem_execbuffer2+0x0/0xe7 [] ? do_sync_read+0x8f/0xca [] ? vfs_ioctl+0x2c/0x96 [] ? drm_ioctl+0x0/0x2fa [] ? do_vfs_ioctl+0x429/0x45a [] ? fsnotify_access+0x54/0x5f [] ? vfs_read+0x9a/0xae [] ? sys_ioctl+0x33/0x4d [] ? sysenter_do_call+0x12/0x26 Code: d0 89 4d c4 31 c9 89 45 d8 eb 44 8b 45 cc 8b 14 88 8b 42 50 89 45 bc 8b 45 a0 8b 52 38 89 55 d0 31 d2 f6 40 20 01 74 0d 8b 55 bc 42 69 30 0f 95 c2 0f b6 d2 8b 45 d0 c7 45 d4 00 00 00 00 89 EIP: [] i915_gem_do_execbuffer+0x71f/0xbb6 SS:ESP 0068:f6508dd4 CR2: 0000000000000069 ---[ end trace 3f1d514b34d39381 ]--- Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 15d2d93..8004dc9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3645,6 +3645,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev, return ret; } + int i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv, @@ -3792,7 +3793,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, unsigned long long total_size = 0; int num_fences = 0; for (i = 0; i < args->buffer_count; i++) { - obj_priv = object_list[i]->driver_private; + obj_priv = to_intel_bo(object_list[i]); total_size += object_list[i]->size; num_fences += -- cgit v0.10.2 From 8699be3ef1d71d1c5e11eee239f53573d72515a3 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Wed, 16 Jun 2010 10:13:52 +0200 Subject: intel_agp: Don't oops with zero stolen memory When "onboard video memory" is set do "disabled" in BIOS on Asus P4P800-VM board (i865G), kernel oopses with memory corruption: https://bugs.freedesktop.org/show_bug.cgi?id=28430 Fix that by cleanly aborting the initialization. Signed-off-by: Ondrej Zary Signed-off-by: Eric Anholt diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9344216..f97122a 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -797,6 +797,10 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge) /* we have to call this as early as possible after the MMIO base address is known */ intel_i830_init_gtt_entries(); + if (intel_private.gtt_entries == 0) { + iounmap(intel_private.registers); + return -ENOMEM; + } agp_bridge->gatt_table = NULL; @@ -1279,6 +1283,11 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) /* we have to call this as early as possible after the MMIO base address is known */ intel_i830_init_gtt_entries(); + if (intel_private.gtt_entries == 0) { + iounmap(intel_private.gtt); + iounmap(intel_private.registers); + return -ENOMEM; + } agp_bridge->gatt_table = NULL; @@ -1387,6 +1396,11 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) /* we have to call this as early as possible after the MMIO base address is known */ intel_i830_init_gtt_entries(); + if (intel_private.gtt_entries == 0) { + iounmap(intel_private.gtt); + iounmap(intel_private.registers); + return -ENOMEM; + } agp_bridge->gatt_table = NULL; -- cgit v0.10.2 From e25e6601099d6d8e5a2221e47cdd142814616b08 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 30 Jun 2010 13:15:19 -0700 Subject: drm/i915: remove unused vblank_enable var from i915_driver_irq_handler Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index dba53d4..390d111 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -842,7 +842,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) u32 iir, new_iir; u32 pipea_stats, pipeb_stats; u32 vblank_status; - u32 vblank_enable; int vblank = 0; unsigned long irqflags; int irq_received; @@ -856,13 +855,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) iir = I915_READ(IIR); - if (IS_I965G(dev)) { + if (IS_I965G(dev)) vblank_status = I915_START_VBLANK_INTERRUPT_STATUS; - vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE; - } else { + else vblank_status = I915_VBLANK_INTERRUPT_STATUS; - vblank_enable = I915_VBLANK_INTERRUPT_ENABLE; - } for (;;) { irq_received = iir != 0; -- cgit v0.10.2 From d874bcff793d6167c8aa3dd0c2fd00ca40ab12a2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 30 Jun 2010 13:16:00 -0700 Subject: drm/i915: remove duplicate PIPE*STAT bit definitions Having two sets has made me think I caught a bug more than once now. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 390d111..fb6b462 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -171,10 +171,10 @@ void intel_enable_asle (struct drm_device *dev) ironlake_enable_display_irq(dev_priv, DE_GSE); else { i915_enable_pipestat(dev_priv, 1, - I915_LEGACY_BLC_EVENT_ENABLE); + PIPE_LEGACY_BLC_EVENT_ENABLE); if (IS_I965G(dev)) i915_enable_pipestat(dev_priv, 0, - I915_LEGACY_BLC_EVENT_ENABLE); + PIPE_LEGACY_BLC_EVENT_ENABLE); } } @@ -856,9 +856,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) iir = I915_READ(IIR); if (IS_I965G(dev)) - vblank_status = I915_START_VBLANK_INTERRUPT_STATUS; + vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS; else - vblank_status = I915_VBLANK_INTERRUPT_STATUS; + vblank_status = PIPE_VBLANK_INTERRUPT_STATUS; for (;;) { irq_received = iir != 0; @@ -962,8 +962,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) intel_finish_page_flip(dev, 1); } - if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) || - (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) || + if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || + (pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || (iir & I915_ASLE_INTERRUPT)) opregion_asle_intr(dev); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6d9b028..dc7c6f8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -595,32 +595,6 @@ #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ -#define I915_FIFO_UNDERRUN_STATUS (1UL<<31) -#define I915_CRC_ERROR_ENABLE (1UL<<29) -#define I915_CRC_DONE_ENABLE (1UL<<28) -#define I915_GMBUS_EVENT_ENABLE (1UL<<27) -#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25) -#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) -#define I915_DPST_EVENT_ENABLE (1UL<<23) -#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22) -#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) -#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) -#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ -#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16) -#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) -#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12) -#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11) -#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9) -#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) -#define I915_DPST_EVENT_STATUS (1UL<<7) -#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6) -#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) -#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) -#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ -#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1) -#define I915_OVERLAY_UPDATED_STATUS (1UL<<0) - #define SRX_INDEX 0x3c4 #define SRX_DATA 0x3c5 #define SR01 1 -- cgit v0.10.2 From 36e83a187ca7517e9bdce7148b1c2c27661ef38f Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Sat, 12 Jun 2010 14:32:21 +0800 Subject: drm/i915: Add the support of eDP on DP-D for Ibex/CPT This one adds support for eDP that connected on PCH DP-D port instead of CPU DP-A port, and only DP-D port could be used for eDP. https://bugs.freedesktop.org/show_bug.cgi?id=27220 Signed-off-by: Zhao Yakui Tested-by: Jan-Hendrik Zab Tested-by: Templar Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f879589..926470d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3452,7 +3452,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, temp |= PIPE_8BPC; else temp |= PIPE_6BPC; - } else if (is_edp) { + } else if (is_edp || (is_dp && intel_pch_has_edp(crtc))) { switch (dev_priv->edp_bpp/3) { case 8: temp |= PIPE_8BPC; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1aac59e..b4f0282 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -43,6 +43,7 @@ #define DP_LINK_CONFIGURATION_SIZE 9 #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) +#define IS_PCH_eDP(dp_priv) ((dp_priv)->has_edp) struct intel_dp_priv { uint32_t output_reg; @@ -56,6 +57,7 @@ struct intel_dp_priv { struct intel_encoder *intel_encoder; struct i2c_adapter adapter; struct i2c_algo_dp_aux_data algo; + bool has_edp; }; static void @@ -128,8 +130,9 @@ intel_dp_link_required(struct drm_device *dev, struct intel_encoder *intel_encoder, int pixel_clock) { struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; - if (IS_eDP(intel_encoder)) + if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) return (pixel_clock * dev_priv->edp_bpp) / 8; else return pixel_clock * 3; @@ -563,14 +566,14 @@ intel_reduce_ratio(uint32_t *num, uint32_t *den) } static void -intel_dp_compute_m_n(int bytes_per_pixel, +intel_dp_compute_m_n(int bpp, int nlanes, int pixel_clock, int link_clock, struct intel_dp_m_n *m_n) { m_n->tu = 64; - m_n->gmch_m = pixel_clock * bytes_per_pixel; + m_n->gmch_m = (pixel_clock * bpp) >> 3; m_n->gmch_n = link_clock * nlanes; intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); m_n->link_m = pixel_clock; @@ -578,6 +581,28 @@ intel_dp_compute_m_n(int bytes_per_pixel, intel_reduce_ratio(&m_n->link_m, &m_n->link_n); } +bool intel_pch_has_edp(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_encoder *encoder; + + list_for_each_entry(encoder, &mode_config->encoder_list, head) { + struct intel_encoder *intel_encoder; + struct intel_dp_priv *dp_priv; + + if (!encoder || encoder->crtc != crtc) + continue; + + intel_encoder = enc_to_intel_encoder(encoder); + dp_priv = intel_encoder->dev_priv; + + if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) + return dp_priv->has_edp; + } + return false; +} + void intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -587,7 +612,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_encoder *encoder; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int lane_count = 4; + int lane_count = 4, bpp = 24; struct intel_dp_m_n m_n; /* @@ -605,6 +630,8 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { lane_count = dp_priv->lane_count; + if (IS_PCH_eDP(dp_priv)) + bpp = dev_priv->edp_bpp; break; } } @@ -614,7 +641,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, * the number of bytes_per_pixel post-LUT, which we always * set up for 8-bits of R/G/B, or 3 bytes total. */ - intel_dp_compute_m_n(3, lane_count, + intel_dp_compute_m_n(bpp, lane_count, mode->clock, adjusted_mode->clock, &m_n); if (HAS_PCH_SPLIT(dev)) { @@ -751,13 +778,13 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) if (mode != DRM_MODE_DPMS_ON) { if (dp_reg & DP_PORT_EN) { intel_dp_link_down(intel_encoder, dp_priv->DP); - if (IS_eDP(intel_encoder)) + if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) ironlake_edp_backlight_off(dev); } } else { if (!(dp_reg & DP_PORT_EN)) { intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); - if (IS_eDP(intel_encoder)) + if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) ironlake_edp_backlight_on(dev); } } @@ -1291,6 +1318,7 @@ static int intel_dp_get_modes(struct drm_connector *connector) struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); struct drm_device *dev = intel_encoder->enc.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; int ret; /* We should parse the EDID data and find out if it has an audio sink @@ -1301,7 +1329,7 @@ static int intel_dp_get_modes(struct drm_connector *connector) return ret; /* if eDP has no EDID, try to use fixed panel mode from VBT */ - if (IS_eDP(intel_encoder)) { + if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { if (dev_priv->panel_fixed_mode != NULL) { struct drm_display_mode *mode; mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); @@ -1386,6 +1414,26 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) return -1; } +/* check the VBT to see whether the eDP is on DP-D port */ +static bool intel_dpd_is_edp(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct child_device_config *p_child; + int i; + + if (!dev_priv->child_dev_num) + return false; + + for (i = 0; i < dev_priv->child_dev_num; i++) { + p_child = dev_priv->child_dev + i; + + if (p_child->dvo_port == PORT_IDPD && + p_child->device_type == DEVICE_TYPE_eDP) + return true; + } + return false; +} + void intel_dp_init(struct drm_device *dev, int output_reg) { @@ -1431,6 +1479,11 @@ intel_dp_init(struct drm_device *dev, int output_reg) if (IS_eDP(intel_encoder)) intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); + if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) { + if (intel_dpd_is_edp(dev)) + dp_priv->has_edp = true; + } + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = true; connector->doublescan_allowed = 0; @@ -1479,7 +1532,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) intel_encoder->ddc_bus = &dp_priv->adapter; intel_encoder->hot_plug = intel_dp_hot_plug; - if (output_reg == DP_A) { + if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { /* initialize panel mode from VBT if available for eDP */ if (dev_priv->lfp_lvds_vbt_mode) { dev_priv->panel_fixed_mode = diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 72206f3..3fbedd8 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -179,6 +179,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg); void intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); +extern bool intel_pch_has_edp(struct drm_crtc *crtc); extern void intel_edp_link_config (struct intel_encoder *, int *, int *); -- cgit v0.10.2 From fa143215b11056b878875f87edac78a1cfb9d1c0 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Sat, 12 Jun 2010 14:32:23 +0800 Subject: drm/i915: Fix watermark calculation in self-refresh mode For self-refresh mode WM calculation's "line time" should use mode's htotal instead of hdisplay. "surface width" is the hdisplay for display plane and 64 for cursor plane. Signed-off-by: Zhao Yakui Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d147ab2..7fba852 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -176,7 +176,8 @@ struct drm_i915_display_funcs { int (*get_display_clock_speed)(struct drm_device *dev); int (*get_fifo_size)(struct drm_device *dev, int plane); void (*update_wm)(struct drm_device *dev, int planea_clock, - int planeb_clock, int sr_hdisplay, int pixel_size); + int planeb_clock, int sr_hdisplay, int sr_htotal, + int pixel_size); /* clock updates for mode set */ /* cursor updates */ /* render clock increase/decrease */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 926470d..274d78d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2809,7 +2809,8 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) } static void pineview_update_wm(struct drm_device *dev, int planea_clock, - int planeb_clock, int sr_hdisplay, int pixel_size) + int planeb_clock, int sr_hdisplay, int unused, + int pixel_size) { struct drm_i915_private *dev_priv = dev->dev_private; u32 reg; @@ -2874,7 +2875,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, } static void g4x_update_wm(struct drm_device *dev, int planea_clock, - int planeb_clock, int sr_hdisplay, int pixel_size) + int planeb_clock, int sr_hdisplay, int sr_htotal, + int pixel_size) { struct drm_i915_private *dev_priv = dev->dev_private; int total_size, cacheline_size; @@ -2917,11 +2919,11 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, static const int sr_latency_ns = 12000; sr_clock = planea_clock ? planea_clock : planeb_clock; - line_time_us = ((sr_hdisplay * 1000) / sr_clock); + line_time_us = ((sr_htotal * 1000) / sr_clock); /* Use ns/us then divide to preserve precision */ - sr_entries = (((sr_latency_ns / line_time_us) + 1) * - pixel_size * sr_hdisplay) / 1000; + sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * + pixel_size * sr_hdisplay; sr_entries = roundup(sr_entries / cacheline_size, 1); DRM_DEBUG("self-refresh entries: %d\n", sr_entries); I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); @@ -2948,7 +2950,8 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, } static void i965_update_wm(struct drm_device *dev, int planea_clock, - int planeb_clock, int sr_hdisplay, int pixel_size) + int planeb_clock, int sr_hdisplay, int sr_htotal, + int pixel_size) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long line_time_us; @@ -2960,11 +2963,11 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, static const int sr_latency_ns = 12000; sr_clock = planea_clock ? planea_clock : planeb_clock; - line_time_us = ((sr_hdisplay * 1000) / sr_clock); + line_time_us = ((sr_htotal * 1000) / sr_clock); /* Use ns/us then divide to preserve precision */ - sr_entries = (((sr_latency_ns / line_time_us) + 1) * - pixel_size * sr_hdisplay) / 1000; + sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * + pixel_size * sr_hdisplay; sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1); DRM_DEBUG("self-refresh entries: %d\n", sr_entries); srwm = I945_FIFO_SIZE - sr_entries; @@ -2990,7 +2993,8 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, } static void i9xx_update_wm(struct drm_device *dev, int planea_clock, - int planeb_clock, int sr_hdisplay, int pixel_size) + int planeb_clock, int sr_hdisplay, int sr_htotal, + int pixel_size) { struct drm_i915_private *dev_priv = dev->dev_private; uint32_t fwater_lo; @@ -3035,11 +3039,11 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, static const int sr_latency_ns = 6000; sr_clock = planea_clock ? planea_clock : planeb_clock; - line_time_us = ((sr_hdisplay * 1000) / sr_clock); + line_time_us = ((sr_htotal * 1000) / sr_clock); /* Use ns/us then divide to preserve precision */ - sr_entries = (((sr_latency_ns / line_time_us) + 1) * - pixel_size * sr_hdisplay) / 1000; + sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * + pixel_size * sr_hdisplay; sr_entries = roundup(sr_entries / cacheline_size, 1); DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries); srwm = total_size - sr_entries; @@ -3078,7 +3082,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, } static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, - int unused2, int pixel_size) + int unused2, int unused3, int pixel_size) { struct drm_i915_private *dev_priv = dev->dev_private; uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; @@ -3098,7 +3102,8 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, #define ILK_LP0_PLANE_LATENCY 700 static void ironlake_update_wm(struct drm_device *dev, int planea_clock, - int planeb_clock, int sr_hdisplay, int pixel_size) + int planeb_clock, int sr_hdisplay, int sr_htotal, + int pixel_size) { struct drm_i915_private *dev_priv = dev->dev_private; int planea_wm, planeb_wm, cursora_wm, cursorb_wm; @@ -3160,7 +3165,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, int ilk_sr_latency = I915_READ(MLTR_ILK) & ILK_SRLT_MASK; sr_clock = planea_clock ? planea_clock : planeb_clock; - line_time_us = ((sr_hdisplay * 1000) / sr_clock); + line_time_us = ((sr_htotal * 1000) / sr_clock); /* Use ns/us then divide to preserve precision */ line_count = ((ilk_sr_latency * 500) / line_time_us + 1000) @@ -3220,6 +3225,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, * bytes per pixel * where * line time = htotal / dotclock + * surface width = hdisplay for normal plane and 64 for cursor * and latency is assumed to be high, as above. * * The final value programmed to the register should always be rounded up, @@ -3236,6 +3242,7 @@ static void intel_update_watermarks(struct drm_device *dev) int sr_hdisplay = 0; unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; int enabled = 0, pixel_size = 0; + int sr_htotal = 0; if (!dev_priv->display.update_wm) return; @@ -3256,6 +3263,7 @@ static void intel_update_watermarks(struct drm_device *dev) } sr_hdisplay = crtc->mode.hdisplay; sr_clock = crtc->mode.clock; + sr_htotal = crtc->mode.htotal; if (crtc->fb) pixel_size = crtc->fb->bits_per_pixel / 8; else @@ -3267,7 +3275,7 @@ static void intel_update_watermarks(struct drm_device *dev) return; dev_priv->display.update_wm(dev, planea_clock, planeb_clock, - sr_hdisplay, pixel_size); + sr_hdisplay, sr_htotal, pixel_size); } static int intel_crtc_mode_set(struct drm_crtc *crtc, -- cgit v0.10.2 From 1b07e04e9cd443fc333f4036d129ba7c08d340c4 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Sat, 12 Jun 2010 14:32:24 +0800 Subject: drm/i915: Fix fifo size for self-refresh watermark on 965G The total self-refresh fifo entry size for display plane is 512 instead of 128 for 965G. Also fix WM value mask for 965G. About 1.0W power can be saved on one T61 laptop after the self-refresh watermark is configured correctly. Signed-off-by: Zhao Yakui Signed-off-by: Zhenyu wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index dc7c6f8..b637fbf 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2140,7 +2140,8 @@ #define I830_FIFO_LINE_SIZE 32 #define G4X_FIFO_SIZE 127 -#define I945_FIFO_SIZE 127 /* 945 & 965 */ +#define I965_FIFO_SIZE 512 +#define I945_FIFO_SIZE 127 #define I915_FIFO_SIZE 95 #define I855GM_FIFO_SIZE 127 /* In cachelines */ #define I830_FIFO_SIZE 95 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 274d78d..09e3f02 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2970,10 +2970,10 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, pixel_size * sr_hdisplay; sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1); DRM_DEBUG("self-refresh entries: %d\n", sr_entries); - srwm = I945_FIFO_SIZE - sr_entries; + srwm = I965_FIFO_SIZE - sr_entries; if (srwm < 0) srwm = 1; - srwm &= 0x3f; + srwm &= 0x1ff; if (IS_I965GM(dev)) I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); } else { -- cgit v0.10.2 From 4fe5e61180d8ea2268d6e64972d90efbe2bab4aa Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Sat, 12 Jun 2010 14:32:25 +0800 Subject: drm/i915: Apply self-refresh watermark calculation for cursor plane In SR mode cursor plane watermark calculation uses same formula like display plane. This one fixes the case for 965G and G45. Signed-off-by: Zhao Yakui Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b637fbf..1f741a6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2160,6 +2160,9 @@ #define PINEVIEW_CURSOR_DFT_WM 0 #define PINEVIEW_CURSOR_GUARD_WM 5 +#define I965_CURSOR_FIFO 64 +#define I965_CURSOR_MAX_WM 32 +#define I965_CURSOR_DFT_WM 8 /* define the Watermark register on Ironlake */ #define WM0_PIPEA_ILK 0x45100 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 09e3f02..b580cd8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2539,6 +2539,20 @@ static struct intel_watermark_params g4x_wm_info = { 2, G4X_FIFO_LINE_SIZE, }; +static struct intel_watermark_params g4x_cursor_wm_info = { + I965_CURSOR_FIFO, + I965_CURSOR_MAX_WM, + I965_CURSOR_DFT_WM, + 2, + G4X_FIFO_LINE_SIZE, +}; +static struct intel_watermark_params i965_cursor_wm_info = { + I965_CURSOR_FIFO, + I965_CURSOR_MAX_WM, + I965_CURSOR_DFT_WM, + 2, + I915_FIFO_LINE_SIZE, +}; static struct intel_watermark_params i945_wm_info = { I945_FIFO_SIZE, I915_MAX_WM, @@ -2925,7 +2939,18 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * pixel_size * sr_hdisplay; sr_entries = roundup(sr_entries / cacheline_size, 1); - DRM_DEBUG("self-refresh entries: %d\n", sr_entries); + + entries_required = (((sr_latency_ns / line_time_us) + + 1000) / 1000) * pixel_size * 64; + entries_required = roundup(entries_required / + g4x_cursor_wm_info.cacheline_size, 1); + cursor_sr = entries_required + g4x_cursor_wm_info.guard_size; + + if (cursor_sr > g4x_cursor_wm_info.max_wm) + cursor_sr = g4x_cursor_wm_info.max_wm; + DRM_DEBUG_KMS("self-refresh watermark: display plane %d " + "cursor %d\n", sr_entries, cursor_sr); + I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); } else { /* Turn off self refresh if both pipes are enabled */ @@ -2956,6 +2981,7 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, struct drm_i915_private *dev_priv = dev->dev_private; unsigned long line_time_us; int sr_clock, sr_entries, srwm = 1; + int cursor_sr = 16; /* Calc sr entries for one plane configs */ if (sr_hdisplay && (!planea_clock || !planeb_clock)) { @@ -2974,6 +3000,20 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, if (srwm < 0) srwm = 1; srwm &= 0x1ff; + + sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * + pixel_size * 64; + sr_entries = roundup(sr_entries / + i965_cursor_wm_info.cacheline_size, 1); + cursor_sr = i965_cursor_wm_info.fifo_size - + (sr_entries + i965_cursor_wm_info.guard_size); + + if (cursor_sr > i965_cursor_wm_info.max_wm) + cursor_sr = i965_cursor_wm_info.max_wm; + + DRM_DEBUG_KMS("self-refresh watermark: display plane %d " + "cursor %d\n", srwm, cursor_sr); + if (IS_I965GM(dev)) I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); } else { @@ -2990,6 +3030,8 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | (8 << 16) | (8 << 8) | (8 << 0)); I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); + /* update cursor SR watermark */ + I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); } static void i9xx_update_wm(struct drm_device *dev, int planea_clock, -- cgit v0.10.2 From c936f44d1b2daea2fd1d52300cab792abe01e28c Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Sat, 12 Jun 2010 14:32:26 +0800 Subject: drm/i915: Calculate cursor watermark under non-SR state for Ironlake The hardware team suggest that the "large buffer" method should be used to calculate the cursor watermark under non-SR state as well, which is to avoid the flicker when FBC is enabled on Ironlake. Signed-off-by: Zhao Yakui Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1f741a6..d0ccfa0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2190,6 +2190,9 @@ #define ILK_DISPLAY_FIFO 128 #define ILK_DISPLAY_MAXWM 64 #define ILK_DISPLAY_DFTWM 8 +#define ILK_CURSOR_FIFO 32 +#define ILK_CURSOR_MAXWM 16 +#define ILK_CURSOR_DFTWM 8 #define ILK_DISPLAY_SR_FIFO 512 #define ILK_DISPLAY_MAX_SRWM 0x1ff diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b580cd8..cca6ce8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2590,6 +2590,14 @@ static struct intel_watermark_params ironlake_display_wm_info = { ILK_FIFO_LINE_SIZE }; +static struct intel_watermark_params ironlake_cursor_wm_info = { + ILK_CURSOR_FIFO, + ILK_CURSOR_MAXWM, + ILK_CURSOR_DFTWM, + 2, + ILK_FIFO_LINE_SIZE +}; + static struct intel_watermark_params ironlake_display_srwm_info = { ILK_DISPLAY_SR_FIFO, ILK_DISPLAY_MAX_SRWM, @@ -3142,6 +3150,7 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, } #define ILK_LP0_PLANE_LATENCY 700 +#define ILK_LP0_CURSOR_LATENCY 1300 static void ironlake_update_wm(struct drm_device *dev, int planea_clock, int planeb_clock, int sr_hdisplay, int sr_htotal, @@ -3153,6 +3162,21 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, unsigned long line_time_us; int sr_clock, entries_required; u32 reg_value; + int line_count; + int planea_htotal = 0, planeb_htotal = 0; + struct drm_crtc *crtc; + struct intel_crtc *intel_crtc; + + /* Need htotal for all active display plane */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + intel_crtc = to_intel_crtc(crtc); + if (crtc->enabled) { + if (intel_crtc->plane == 0) + planea_htotal = crtc->mode.htotal; + else + planeb_htotal = crtc->mode.htotal; + } + } /* Calculate and update the watermark for plane A */ if (planea_clock) { @@ -3166,7 +3190,20 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, if (planea_wm > (int)ironlake_display_wm_info.max_wm) planea_wm = ironlake_display_wm_info.max_wm; - cursora_wm = 16; + /* Use the large buffer method to calculate cursor watermark */ + line_time_us = (planea_htotal * 1000) / planea_clock; + + /* Use ns/us then divide to preserve precision */ + line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; + + /* calculate the cursor watermark for cursor A */ + entries_required = line_count * 64 * pixel_size; + entries_required = DIV_ROUND_UP(entries_required, + ironlake_cursor_wm_info.cacheline_size); + cursora_wm = entries_required + ironlake_cursor_wm_info.guard_size; + if (cursora_wm > ironlake_cursor_wm_info.max_wm) + cursora_wm = ironlake_cursor_wm_info.max_wm; + reg_value = I915_READ(WM0_PIPEA_ILK); reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); reg_value |= (planea_wm << WM0_PIPE_PLANE_SHIFT) | @@ -3187,7 +3224,20 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, if (planeb_wm > (int)ironlake_display_wm_info.max_wm) planeb_wm = ironlake_display_wm_info.max_wm; - cursorb_wm = 16; + /* Use the large buffer method to calculate cursor watermark */ + line_time_us = (planeb_htotal * 1000) / planeb_clock; + + /* Use ns/us then divide to preserve precision */ + line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; + + /* calculate the cursor watermark for cursor B */ + entries_required = line_count * 64 * pixel_size; + entries_required = DIV_ROUND_UP(entries_required, + ironlake_cursor_wm_info.cacheline_size); + cursorb_wm = entries_required + ironlake_cursor_wm_info.guard_size; + if (cursorb_wm > ironlake_cursor_wm_info.max_wm) + cursorb_wm = ironlake_cursor_wm_info.max_wm; + reg_value = I915_READ(WM0_PIPEB_ILK); reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); reg_value |= (planeb_wm << WM0_PIPE_PLANE_SHIFT) | @@ -3202,7 +3252,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, * display plane is used. */ if (!planea_clock || !planeb_clock) { - int line_count; + /* Read the self-refresh latency. The unit is 0.5us */ int ilk_sr_latency = I915_READ(MLTR_ILK) & ILK_SRLT_MASK; -- cgit v0.10.2 From b52eb4dcab23fe0c52a437276258e0afcf913ef5 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Sat, 12 Jun 2010 14:32:27 +0800 Subject: drm/i915: Add frame buffer compression support on Ironlake mobile About 0.2W power can be saved on one HP laptop. Signed-off-by: Zhao Yakui Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9289803..9ddb7b5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1257,7 +1257,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) drm_mm_put_block(compressed_fb); } - if (!IS_GM45(dev)) { + if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096, 4096, 0); if (!compressed_llb) { @@ -1283,8 +1283,9 @@ static void i915_setup_compression(struct drm_device *dev, int size) intel_disable_fbc(dev); dev_priv->compressed_fb = compressed_fb; - - if (IS_GM45(dev)) { + if (IS_IRONLAKE_M(dev)) + I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); + else if (IS_GM45(dev)) { I915_WRITE(DPFC_CB_BASE, compressed_fb->start); } else { I915_WRITE(FBC_CFB_BASE, cfb_base); @@ -1292,7 +1293,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) dev_priv->compressed_llb = compressed_llb; } - DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, + DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, ll_base, size >> 20); } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 65d3f3e..b5694d2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -134,7 +134,7 @@ static const struct intel_device_info intel_ironlake_d_info = { static const struct intel_device_info intel_ironlake_m_info = { .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, - .need_gfx_hws = 1, .has_rc6 = 1, + .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, }; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7fba852..f5636d8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1042,6 +1042,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev); extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); extern void i8xx_disable_fbc(struct drm_device *dev); extern void g4x_disable_fbc(struct drm_device *dev); +extern void ironlake_disable_fbc(struct drm_device *dev); extern void intel_disable_fbc(struct drm_device *dev); extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); extern bool intel_fbc_enabled(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d0ccfa0..e2a6f68 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -530,6 +530,21 @@ #define DPFC_CHICKEN 0x3224 #define DPFC_HT_MODIFY (1<<31) +/* Framebuffer compression for Ironlake */ +#define ILK_DPFC_CB_BASE 0x43200 +#define ILK_DPFC_CONTROL 0x43208 +/* The bit 28-8 is reserved */ +#define DPFC_RESERVED (0x1FFFFF00) +#define ILK_DPFC_RECOMP_CTL 0x4320c +#define ILK_DPFC_STATUS 0x43210 +#define ILK_DPFC_FENCE_YOFF 0x43218 +#define ILK_DPFC_CHICKEN 0x43224 +#define ILK_FBC_RT_BASE 0x2128 +#define ILK_FBC_RT_VALID (1<<0) + +#define ILK_DISPLAY_CHICKEN1 0x42000 +#define ILK_FBCQ_DIS (1<<22) + /* * GPIO regs */ @@ -2491,6 +2506,10 @@ #define ILK_VSDPFD_FULL (1<<21) #define ILK_DSPCLK_GATE 0x42020 #define ILK_DPARB_CLK_GATE (1<<5) +/* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ +#define ILK_CLK_FBC (1<<7) +#define ILK_DPFC_DIS1 (1<<8) +#define ILK_DPFC_DIS2 (1<<9) #define DISP_ARB_CTL 0x45000 #define DISP_TILE_SURFACE_SWIZZLING (1<<13) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 60a5800..6e20252 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -602,7 +602,9 @@ void i915_save_display(struct drm_device *dev) /* Only save FBC state on the platform that supports FBC */ if (I915_HAS_FBC(dev)) { - if (IS_GM45(dev)) { + if (IS_IRONLAKE_M(dev)) { + dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); + } else if (IS_GM45(dev)) { dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); } else { dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); @@ -706,7 +708,10 @@ void i915_restore_display(struct drm_device *dev) /* only restore FBC info on the platform that supports FBC*/ if (I915_HAS_FBC(dev)) { - if (IS_GM45(dev)) { + if (IS_IRONLAKE_M(dev)) { + ironlake_disable_fbc(dev); + I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); + } else if (IS_GM45(dev)) { g4x_disable_fbc(dev); I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); } else { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cca6ce8..f2f812e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1123,6 +1123,67 @@ static bool g4x_fbc_enabled(struct drm_device *dev) return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; } +static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_framebuffer *fb = crtc->fb; + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int plane = (intel_crtc->plane == 0) ? DPFC_CTL_PLANEA : + DPFC_CTL_PLANEB; + unsigned long stall_watermark = 200; + u32 dpfc_ctl; + + dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; + dev_priv->cfb_fence = obj_priv->fence_reg; + dev_priv->cfb_plane = intel_crtc->plane; + + dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); + dpfc_ctl &= DPFC_RESERVED; + dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); + if (obj_priv->tiling_mode != I915_TILING_NONE) { + dpfc_ctl |= (DPFC_CTL_FENCE_EN | dev_priv->cfb_fence); + I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); + } else { + I915_WRITE(ILK_DPFC_CHICKEN, ~DPFC_HT_MODIFY); + } + + I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); + I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | + (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | + (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); + I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); + I915_WRITE(ILK_FBC_RT_BASE, obj_priv->gtt_offset | ILK_FBC_RT_VALID); + /* enable it... */ + I915_WRITE(ILK_DPFC_CONTROL, I915_READ(ILK_DPFC_CONTROL) | + DPFC_CTL_EN); + + DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); +} + +void ironlake_disable_fbc(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 dpfc_ctl; + + /* Disable compression */ + dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); + dpfc_ctl &= ~DPFC_CTL_EN; + I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); + intel_wait_for_vblank(dev); + + DRM_DEBUG_KMS("disabled FBC\n"); +} + +static bool ironlake_fbc_enabled(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; +} + bool intel_fbc_enabled(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -1966,6 +2027,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) intel_crtc_load_lut(crtc); + intel_update_fbc(crtc, &crtc->mode); + break; case DRM_MODE_DPMS_OFF: DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); @@ -1980,6 +2043,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) I915_READ(dspbase_reg); } + if (dev_priv->cfb_plane == plane && + dev_priv->display.disable_fbc) + dev_priv->display.disable_fbc(dev); + i915_disable_vga(dev); /* disable cpu pipe, disable after all planes disabled */ @@ -5452,6 +5519,26 @@ void intel_init_clock_gating(struct drm_device *dev) (I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS)); } + /* + * Based on the document from hardware guys the following bits + * should be set unconditionally in order to enable FBC. + * The bit 22 of 0x42000 + * The bit 22 of 0x42004 + * The bit 7,8,9 of 0x42020. + */ + if (IS_IRONLAKE_M(dev)) { + I915_WRITE(ILK_DISPLAY_CHICKEN1, + I915_READ(ILK_DISPLAY_CHICKEN1) | + ILK_FBCQ_DIS); + I915_WRITE(ILK_DISPLAY_CHICKEN2, + I915_READ(ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE); + I915_WRITE(ILK_DSPCLK_GATE, + I915_READ(ILK_DSPCLK_GATE) | + ILK_DPFC_DIS1 | + ILK_DPFC_DIS2 | + ILK_CLK_FBC); + } return; } else if (IS_G4X(dev)) { uint32_t dspclk_gate; @@ -5530,7 +5617,11 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.dpms = i9xx_crtc_dpms; if (I915_HAS_FBC(dev)) { - if (IS_GM45(dev)) { + if (IS_IRONLAKE_M(dev)) { + dev_priv->display.fbc_enabled = ironlake_fbc_enabled; + dev_priv->display.enable_fbc = ironlake_enable_fbc; + dev_priv->display.disable_fbc = ironlake_disable_fbc; + } else if (IS_GM45(dev)) { dev_priv->display.fbc_enabled = g4x_fbc_enabled; dev_priv->display.enable_fbc = g4x_enable_fbc; dev_priv->display.disable_fbc = g4x_disable_fbc; -- cgit v0.10.2 From 7aa69d2ee7e1ecff104fc068585f21af45582982 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Tue, 8 Jun 2010 21:18:06 +0200 Subject: drm/i915: Typo in #define checkpatch complains about this define: WARNING: space prohibited between function name and open parenthesis '(' +#define GEN6_RENDER TIMEOUT_COUNTER_EXPIRED (1 << 6) Signed-off-by: Nicolas Kaiser Acked-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e2a6f68..849ab8a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -442,7 +442,7 @@ #define GEN6_RENDER_IMR 0x20a8 #define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8) #define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7) -#define GEN6_RENDER TIMEOUT_COUNTER_EXPIRED (1 << 6) +#define GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED (1 << 6) #define GEN6_RENDER_L3_PARITY_ERROR (1 << 5) #define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4) #define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3) -- cgit v0.10.2 From 5f35308bab7efd8c03e4bb4feea07f9b94138c3c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 7 Jun 2010 14:03:03 +0100 Subject: drm/i915: Propagate error from drm_install_irq() during EnterVT Simple fix for error propagation along the old UMS path. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8004dc9..0bf4bcd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4687,9 +4687,19 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list)); mutex_unlock(&dev->struct_mutex); - drm_irq_install(dev); + ret = drm_irq_install(dev); + if (ret) + goto cleanup_ringbuffer; return 0; + +cleanup_ringbuffer: + mutex_lock(&dev->struct_mutex); + i915_gem_cleanup_ringbuffer(dev); + dev_priv->mm.suspended = 1; + mutex_unlock(&dev->struct_mutex); + + return ret; } int -- cgit v0.10.2 From 96b099fd6d64389e619dbf7ca9059bf16e441f6b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 7 Jun 2010 14:03:04 +0100 Subject: drm/i915: Propagate error from drm_vblank_get() during page-flipping. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f2f812e..bf486b1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4897,19 +4897,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, mutex_lock(&dev->struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, obj); - if (ret != 0) { - mutex_unlock(&dev->struct_mutex); - - spin_lock_irqsave(&dev->event_lock, flags); - intel_crtc->unpin_work = NULL; - spin_unlock_irqrestore(&dev->event_lock, flags); - - kfree(work); - - DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", - to_intel_bo(obj)); - return ret; - } + if (ret) + goto cleanup_work; /* Reference the objects for the scheduled work. */ drm_gem_object_reference(work->old_fb_obj); @@ -4917,7 +4906,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, crtc->fb = fb; i915_gem_object_flush_write_domain(obj); - drm_vblank_get(dev, intel_crtc->pipe); + + ret = drm_vblank_get(dev, intel_crtc->pipe); + if (ret) + goto cleanup_objs; + obj_priv = to_intel_bo(obj); atomic_inc(&obj_priv->pending_flip); work->pending_flip_obj = obj; @@ -4954,6 +4947,20 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, trace_i915_flip_request(intel_crtc->plane, obj); return 0; + +cleanup_objs: + drm_gem_object_unreference(work->old_fb_obj); + drm_gem_object_unreference(obj); +cleanup_work: + mutex_unlock(&dev->struct_mutex); + + spin_lock_irqsave(&dev->event_lock, flags); + intel_crtc->unpin_work = NULL; + spin_unlock_irqrestore(&dev->event_lock, flags); + + kfree(work); + + return ret; } static const struct drm_crtc_helper_funcs intel_helper_funcs = { -- cgit v0.10.2 From 2dafb1e082c541d4bc0f275a6ffa9c39da690f01 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 7 Jun 2010 14:03:05 +0100 Subject: drm/i915: Propagate error from i915_gem_object_flush_gpu_write_domain() Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f5636d8..f8f315d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -982,7 +982,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev); int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); void i915_gem_object_put_pages(struct drm_gem_object *obj); void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); -void i915_gem_object_flush_write_domain(struct drm_gem_object *obj); +int i915_gem_object_flush_write_domain(struct drm_gem_object *obj); void i915_gem_shrinker_init(void); void i915_gem_shrinker_exit(void); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0bf4bcd..b1069dc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -35,7 +35,7 @@ #include #include -static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); +static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, @@ -2583,7 +2583,10 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj) if (!IS_I965G(dev)) { int ret; - i915_gem_object_flush_gpu_write_domain(obj); + ret = i915_gem_object_flush_gpu_write_domain(obj); + if (ret != 0) + return ret; + ret = i915_gem_object_wait_rendering(obj); if (ret != 0) return ret; @@ -2731,7 +2734,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj) } /** Flushes any GPU write domain for the object if it's dirty. */ -static void +static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; @@ -2739,17 +2742,18 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) - return; + return 0; /* Queue the GPU write cache flushing we need. */ old_write_domain = obj->write_domain; i915_gem_flush(dev, 0, obj->write_domain); - (void) i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring); - BUG_ON(obj->write_domain); + if (i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring) == 0) + return -ENOMEM; trace_i915_gem_object_change_domain(obj, obj->read_domains, old_write_domain); + return 0; } /** Flushes the GTT write domain for the object if it's dirty. */ @@ -2793,9 +2797,11 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) old_write_domain); } -void +int i915_gem_object_flush_write_domain(struct drm_gem_object *obj) { + int ret = 0; + switch (obj->write_domain) { case I915_GEM_DOMAIN_GTT: i915_gem_object_flush_gtt_write_domain(obj); @@ -2804,9 +2810,11 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj) i915_gem_object_flush_cpu_write_domain(obj); break; default: - i915_gem_object_flush_gpu_write_domain(obj); + ret = i915_gem_object_flush_gpu_write_domain(obj); break; } + + return ret; } /** @@ -2826,7 +2834,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) if (obj_priv->gtt_space == NULL) return -EINVAL; - i915_gem_object_flush_gpu_write_domain(obj); + ret = i915_gem_object_flush_gpu_write_domain(obj); + if (ret != 0) + return ret; + /* Wait on any GPU rendering and flushing to occur. */ ret = i915_gem_object_wait_rendering(obj); if (ret != 0) @@ -2876,7 +2887,9 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) if (obj_priv->gtt_space == NULL) return -EINVAL; - i915_gem_object_flush_gpu_write_domain(obj); + ret = i915_gem_object_flush_gpu_write_domain(obj); + if (ret) + return ret; /* Wait on any GPU rendering and flushing to occur. */ if (obj_priv->active) { @@ -2924,7 +2937,10 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) uint32_t old_write_domain, old_read_domains; int ret; - i915_gem_object_flush_gpu_write_domain(obj); + ret = i915_gem_object_flush_gpu_write_domain(obj); + if (ret) + return ret; + /* Wait on any GPU rendering and flushing to occur. */ ret = i915_gem_object_wait_rendering(obj); if (ret != 0) @@ -3214,7 +3230,10 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, if (offset == 0 && size == obj->size) return i915_gem_object_set_to_cpu_domain(obj, 0); - i915_gem_object_flush_gpu_write_domain(obj); + ret = i915_gem_object_flush_gpu_write_domain(obj); + if (ret) + return ret; + /* Wait on any GPU rendering and flushing to occur. */ ret = i915_gem_object_wait_rendering(obj); if (ret != 0) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bf486b1..81179fb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4905,7 +4905,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, drm_gem_object_reference(obj); crtc->fb = fb; - i915_gem_object_flush_write_domain(obj); + ret = i915_gem_object_flush_write_domain(obj); + if (ret) + goto cleanup_objs; ret = drm_vblank_get(dev, intel_crtc->pipe); if (ret) -- cgit v0.10.2 From 11824e8c4e8a1279ee209173da777b2295b72e82 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Jun 2010 15:40:18 +0100 Subject: drm/i915: Silence sparse complaints over insufficient bitfield int types. drivers/gpu/drm/i915/i915_drv.h|676 col 19| warning: dubious bitfield without explicit `signed' or `unsigned' drivers/gpu/drm/i915/i915_drv.h|712 col 19| warning: dubious bitfield without explicit `signed' or `unsigned' Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f8f315d..e40dcf2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -673,7 +673,7 @@ struct drm_i915_gem_object { * * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) */ - int fence_reg : 5; + signed int fence_reg : 5; /** * Used for checking the object doesn't appear more than once @@ -709,7 +709,7 @@ struct drm_i915_gem_object { * * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3 * bits with absolutely no headroom. So use 4 bits. */ - int pin_count : 4; + unsigned int pin_count : 4; #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf /** AGP memory structure for our GTT binding. */ -- cgit v0.10.2 From 2d3fa0de689e1a53fdfc3db50732b62e58d0ca6b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Jun 2010 15:40:19 +0100 Subject: drm/i915: Silence sparse over duplicate members in static initializer drivers/gpu/drm/i915/i915_drv.c|100 col 18| warning: Initializer entry defined twice drivers/gpu/drm/i915/i915_drv.c|101 col 3| also defined here drivers/gpu/drm/i915/i915_drv.c|117 col 18| warning: Initializer entry defined twice drivers/gpu/drm/i915/i915_drv.c|118 col 3| also defined here Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b5694d2..39eaa37 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -97,7 +97,7 @@ static const struct intel_device_info intel_i965g_info = { }; static const struct intel_device_info intel_i965gm_info = { - .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1, + .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, }; @@ -114,7 +114,7 @@ static const struct intel_device_info intel_g45_info = { }; static const struct intel_device_info intel_gm45_info = { - .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1, + .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, -- cgit v0.10.2 From b4b78d12d7c5108b9a71752b59dcc51b11cd9ea6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Jun 2010 15:40:20 +0100 Subject: drm/i915: Silence sparse over non-static local structure. drivers/gpu/drm/i915/i915_drv.c|485 col 25| warning: symbol 'i915_pm_ops' was not declared. Should it be static? Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 39eaa37..04d9d1f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -482,7 +482,7 @@ static int i915_pm_poweroff(struct device *dev) return i915_drm_freeze(drm_dev); } -const struct dev_pm_ops i915_pm_ops = { +static const struct dev_pm_ops i915_pm_ops = { .suspend = i915_pm_suspend, .resume = i915_pm_resume, .freeze = i915_pm_freeze, -- cgit v0.10.2 From d312ec251769dc2ad6c9bd9856a756c6097ab63c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Jun 2010 15:40:22 +0100 Subject: drm/i915: Sparse warns about the incorrect sign for storing bit17 Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e40dcf2..21a4af9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -739,7 +739,7 @@ struct drm_i915_gem_object { uint32_t stride; /** Record of address bit 17 of each page at last unbind. */ - long *bit_17; + unsigned long *bit_17; /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */ uint32_t agp_type; -- cgit v0.10.2 From 3ca87e82831f040986f27aef44fc61c8ddf6ee79 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Jun 2010 15:40:23 +0100 Subject: drm/i915: Sparse warning about invalid value for burst_ena in tv_modes drivers/gpu/drm/i915/intel_tv.c|479 col 16| warning: cast truncates bits from constant value (8 becomes 0) Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 6d553c2..de2b961 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -476,7 +476,7 @@ static const struct tv_mode tv_modes[] = { .vi_end_f1 = 20, .vi_end_f2 = 21, .nbr_end = 240, - .burst_ena = 8, + .burst_ena = true, .hburst_start = 72, .hburst_len = 34, .vburst_start_f1 = 9, .vburst_end_f1 = 240, .vburst_start_f2 = 10, .vburst_end_f2 = 240, -- cgit v0.10.2 From 2377b741abec485449d145e5065dd2b7dd64226f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 7 Jul 2010 14:06:43 -0700 Subject: drm/i915: fix FDI frequency check Since mode->clock is in kHz we should be checking against 2700000 instead of just 27000. This patch gets my x201s working again (well working as well as it ever was anyway). When looking for this I also noticed we set link_bw to 270000, but the calculation is different. Does it also need to use kHz or we using 10kHz internally? Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 81179fb..7e57eab 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -323,6 +323,9 @@ struct intel_limit { #define IRONLAKE_DP_P1_MIN 1 #define IRONLAKE_DP_P1_MAX 2 +/* FDI */ +#define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */ + static bool intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); @@ -2421,8 +2424,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; if (HAS_PCH_SPLIT(dev)) { /* FDI link clock is fixed at 2.7G */ - if (mode->clock * 3 > 27000 * 4) - return MODE_CLOCK_HIGH; + if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) + return false; } drm_mode_set_crtcinfo(adjusted_mode, 0); -- cgit v0.10.2 From 0b3400040d189b129e9770b7ea2e38729e3d75c4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Jun 2010 13:21:26 +0100 Subject: drm/i915: Remove the WARN when failing to set tiling. We generally issue an error message at the point of failure, and so this warning with a fairly pointless stacktrace is superfluous and ugly. Needless to say, the common trigger for this WARN happens to be EIO where this is pure noise. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 4b7c49d..155719e 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -333,8 +333,6 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, i915_gem_release_mmap(obj); if (ret != 0) { - WARN(ret != -ERESTARTSYS, - "failed to reset object for tiling switch"); args->tiling_mode = obj_priv->tiling_mode; args->stride = obj_priv->stride; goto err; -- cgit v0.10.2 From cbb465e72ae2cf37d252284c28a0d89ddfaaa240 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Jun 2010 12:16:24 +0100 Subject: drm/i915: Include instdone[1] in hangcheck References: Bug 26691 - Spurious hangcheck whilst executing a long shader over a large vertex buffer https://bugs.freedesktop.org/show_bug.cgi?id=26691 Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 21a4af9..70e2527 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -286,6 +286,8 @@ typedef struct drm_i915_private { struct timer_list hangcheck_timer; int hangcheck_count; uint32_t last_acthd; + uint32_t last_instdone; + uint32_t last_instdone1; struct drm_mm vram; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index fb6b462..85785a8 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1229,16 +1229,21 @@ void i915_hangcheck_elapsed(unsigned long data) { struct drm_device *dev = (struct drm_device *)data; drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t acthd; + uint32_t acthd, instdone, instdone1; /* No reset support on this chip yet. */ if (IS_GEN6(dev)) return; - if (!IS_I965G(dev)) + if (!IS_I965G(dev)) { acthd = I915_READ(ACTHD); - else + instdone = I915_READ(INSTDONE); + instdone1 = 0; + } else { acthd = I915_READ(ACTHD_I965); + instdone = I915_READ(INSTDONE_I965); + instdone1 = I915_READ(INSTDONE1); + } /* If all work is done then ACTHD clearly hasn't advanced. */ if (list_empty(&dev_priv->render_ring.request_list) || @@ -1249,21 +1254,24 @@ void i915_hangcheck_elapsed(unsigned long data) return; } - if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) { - DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); - i915_handle_error(dev, true); - return; - } + if (dev_priv->last_acthd == acthd && + dev_priv->last_instdone == instdone && + dev_priv->last_instdone1 == instdone1) { + if (dev_priv->hangcheck_count++ > 1) { + DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); + i915_handle_error(dev, true); + return; + } + } else { + dev_priv->hangcheck_count = 0; + + dev_priv->last_acthd = acthd; + dev_priv->last_instdone = instdone; + dev_priv->last_instdone1 = instdone1; + } /* Reset timer case chip hangs without another request being added */ mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); - - if (acthd != dev_priv->last_acthd) - dev_priv->hangcheck_count = 0; - else - dev_priv->hangcheck_count++; - - dev_priv->last_acthd = acthd; } /* drm_dma.h hooks -- cgit v0.10.2 From 2991196fbc19f68206eb81694e9ef338366ebc53 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Jun 2010 19:29:54 +0200 Subject: drm/i915: cleanup: use ARRAY_SIZE() NUM_TV_MODES is the same as ARRAY_SIZE(tv_modes). In the end, I decided it was cleaner to remove NUM_TV_MODES and just use ARRAY_SIZE(tv_modes) through out. Signed-off-by: Dan Carpenter Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index de2b961..d61ffbc 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -896,8 +896,6 @@ static const struct tv_mode tv_modes[] = { }, }; -#define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0]) - static void intel_tv_dpms(struct drm_encoder *encoder, int mode) { @@ -1512,7 +1510,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop tv_priv->margin[TV_MARGIN_BOTTOM] = val; changed = true; } else if (property == dev->mode_config.tv_mode_property) { - if (val >= NUM_TV_MODES) { + if (val >= ARRAY_SIZE(tv_modes)) { ret = -EINVAL; goto out; } @@ -1693,13 +1691,13 @@ intel_tv_init(struct drm_device *dev) connector->doublescan_allowed = false; /* Create TV properties then attach current values */ - tv_format_names = kmalloc(sizeof(char *) * NUM_TV_MODES, + tv_format_names = kmalloc(sizeof(char *) * ARRAY_SIZE(tv_modes), GFP_KERNEL); if (!tv_format_names) goto out; - for (i = 0; i < NUM_TV_MODES; i++) + for (i = 0; i < ARRAY_SIZE(tv_modes); i++) tv_format_names[i] = tv_modes[i].name; - drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names); + drm_mode_create_tv_properties(dev, ARRAY_SIZE(tv_modes), tv_format_names); drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, initial_mode); -- cgit v0.10.2 From e1a4474349997d722e4ae64e40a68feb25307109 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 25 Jun 2010 15:32:14 -0400 Subject: drm/i915/pch: Cosmetic fix to FDI link training Unmask the bits for link training reporting before starting link training. If stage 1 training finished before we unmask them, then we'd spin around in a loop a few times until smashing on through. Which is harmless, since training _did_ succeed, it just looks ugly in dmesg. Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7e57eab..f67c74a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1604,6 +1604,15 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; u32 temp, tries = 0; + /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit + for train result */ + temp = I915_READ(fdi_rx_imr_reg); + temp &= ~FDI_RX_SYMBOL_LOCK; + temp &= ~FDI_RX_BIT_LOCK; + I915_WRITE(fdi_rx_imr_reg, temp); + I915_READ(fdi_rx_imr_reg); + udelay(150); + /* enable CPU FDI TX and PCH FDI RX */ temp = I915_READ(fdi_tx_reg); temp |= FDI_TX_ENABLE; @@ -1621,16 +1630,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) I915_READ(fdi_rx_reg); udelay(150); - /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit - for train result */ - temp = I915_READ(fdi_rx_imr_reg); - temp &= ~FDI_RX_SYMBOL_LOCK; - temp &= ~FDI_RX_BIT_LOCK; - I915_WRITE(fdi_rx_imr_reg, temp); - I915_READ(fdi_rx_imr_reg); - udelay(150); - - for (;;) { + for (tries = 0; tries < 5; tries++) { temp = I915_READ(fdi_rx_iir_reg); DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); @@ -1640,14 +1640,9 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) temp | FDI_RX_BIT_LOCK); break; } - - tries++; - - if (tries > 5) { - DRM_DEBUG_KMS("FDI train 1 fail!\n"); - break; - } } + if (tries == 5) + DRM_DEBUG_KMS("FDI train 1 fail!\n"); /* Train 2 */ temp = I915_READ(fdi_tx_reg); @@ -1663,7 +1658,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) tries = 0; - for (;;) { + for (tries = 0; tries < 5; tries++) { temp = I915_READ(fdi_rx_iir_reg); DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); @@ -1673,14 +1668,9 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) DRM_DEBUG_KMS("FDI train 2 done.\n"); break; } - - tries++; - - if (tries > 5) { - DRM_DEBUG_KMS("FDI train 2 fail!\n"); - break; - } } + if (tries == 5) + DRM_DEBUG_KMS("FDI train 2 fail!\n"); DRM_DEBUG_KMS("FDI train done\n"); } @@ -1705,6 +1695,15 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; u32 temp, i; + /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit + for train result */ + temp = I915_READ(fdi_rx_imr_reg); + temp &= ~FDI_RX_SYMBOL_LOCK; + temp &= ~FDI_RX_BIT_LOCK; + I915_WRITE(fdi_rx_imr_reg, temp); + I915_READ(fdi_rx_imr_reg); + udelay(150); + /* enable CPU FDI TX and PCH FDI RX */ temp = I915_READ(fdi_tx_reg); temp |= FDI_TX_ENABLE; @@ -1730,15 +1729,6 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) I915_READ(fdi_rx_reg); udelay(150); - /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit - for train result */ - temp = I915_READ(fdi_rx_imr_reg); - temp &= ~FDI_RX_SYMBOL_LOCK; - temp &= ~FDI_RX_BIT_LOCK; - I915_WRITE(fdi_rx_imr_reg, temp); - I915_READ(fdi_rx_imr_reg); - udelay(150); - for (i = 0; i < 4; i++ ) { temp = I915_READ(fdi_tx_reg); temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; -- cgit v0.10.2 From 534843dabf79da40561148764916e1b2e6bbcebe Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 5 Jul 2010 18:01:46 +0100 Subject: drm/i915: Use 128k alignment for untiled display surface on i965 (v2) The original i965, including the revised G35 and Q35, requires an alignment of 128K for the display surface with linear memory, so increase the requirement from 64k for these chipsets. For the later chipsets in the i965 family, only a 4k alignment is required. (So long as we do not start performing asynchronous flips.) Note the impact of this should be slight as on i965 we should be using a tiled frontbuffer for anything up to a 4096x4096 display. v2: compilation fixes and note that the docs do not exclude the G35 from the extra alignment. Signed-off-by: Chris Wilson Reviewed-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 04d9d1f..ca740d9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -93,11 +93,11 @@ static const struct intel_device_info intel_i945gm_info = { }; static const struct intel_device_info intel_i965g_info = { - .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, + .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, }; static const struct intel_device_info intel_i965gm_info = { - .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, + .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, }; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 70e2527..5a0100e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -201,6 +201,8 @@ struct intel_device_info { u8 need_gfx_hws : 1; u8 is_g4x : 1; u8 is_pineview : 1; + u8 is_broadwater : 1; + u8 is_crestline : 1; u8 is_ironlake : 1; u8 is_gen6 : 1; u8 has_fbc : 1; @@ -1134,6 +1136,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); #define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) #define IS_I965G(dev) (INTEL_INFO(dev)->is_i965g) #define IS_I965GM(dev) (INTEL_INFO(dev)->is_i965gm) +#define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater) +#define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline) #define IS_GM45(dev) ((dev)->pci_device == 0x2A42) #define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) #define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f67c74a..8359c50 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1329,7 +1329,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) switch (obj_priv->tiling_mode) { case I915_TILING_NONE: - alignment = 64 * 1024; + if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) + alignment = 128 * 1024; + else if (IS_I965G(dev)) + alignment = 4 * 1024; + else + alignment = 64 * 1024; break; case I915_TILING_X: /* pin() will align the object as required by fence */ -- cgit v0.10.2 From 6103da0d03d5f185070be50a0cb8813f6bf30dc1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 5 Jul 2010 18:01:47 +0100 Subject: drm/i915: Include any alternate names by which the device is known. When trying to keep track of features between the kernel, the 2D driver, mesa and the specs, it helps to list any other name by which the device is referred to. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ca740d9..119692f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -148,33 +148,33 @@ static const struct intel_device_info intel_sandybridge_m_info = { .has_hotplug = 1, .is_gen6 = 1, }; -static const struct pci_device_id pciidlist[] = { - INTEL_VGA_DEVICE(0x3577, &intel_i830_info), - INTEL_VGA_DEVICE(0x2562, &intel_845g_info), - INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), +static const struct pci_device_id pciidlist[] = { /* aka */ + INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */ + INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */ + INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), /* I855_GM */ INTEL_VGA_DEVICE(0x358e, &intel_i85x_info), - INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), - INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), - INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), - INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), - INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), - INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), - INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), - INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), - INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), - INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), - INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), - INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), - INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), - INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), - INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), - INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), - INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), - INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), - INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), - INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), - INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), - INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), + INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), /* I865_G */ + INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), /* I915_G */ + INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), /* E7221_G */ + INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), /* I915_GM */ + INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), /* I945_G */ + INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), /* I945_GM */ + INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), /* I945_GME */ + INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), /* I946_GZ */ + INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), /* G35_G */ + INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), /* I965_Q */ + INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), /* I965_G */ + INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), /* Q35_G */ + INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), /* G33_G */ + INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), /* Q33_G */ + INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), /* I965_GM */ + INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), /* I965_GME */ + INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), /* GM45_G */ + INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), /* IGD_E_G */ + INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), /* Q45_G */ + INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ + INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ + INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), -- cgit v0.10.2 From 3869d4a8afd3ce97770e66d6a96672af93984cc2 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 9 Jul 2010 10:40:58 -0700 Subject: agp/intel: Support the extended physical addressing bits on Sandybridge. Signed-off-by: Zhenyu Wang [anholt: Split this patch out of a larger patch for Sandybridge fixes] Signed-off-by: Eric Anholt diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index d836a71..5bbc7be 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -816,9 +816,9 @@ static const struct intel_driver_description { { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, "HD Graphics", NULL, &intel_i965_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG, - "Sandybridge", NULL, &intel_i965_driver }, + "Sandybridge", NULL, &intel_gen6_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG, - "Sandybridge", NULL, &intel_i965_driver }, + "Sandybridge", NULL, &intel_gen6_driver }, { 0, 0, NULL, NULL, NULL } }; diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index f97122a..2b1a0e9 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1315,6 +1315,16 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, return addr | bridge->driver->masks[type].mask; } +static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge, + dma_addr_t addr, int type) +{ + /* Shift high bits down */ + addr |= (addr >> 28) & 0xff; + + /* Type checking must be done elsewhere */ + return addr | bridge->driver->masks[type].mask; +} + static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) { u16 snb_gmch_ctl; @@ -1528,6 +1538,39 @@ static const struct agp_bridge_driver intel_i965_driver = { #endif }; +static const struct agp_bridge_driver intel_gen6_driver = { + .owner = THIS_MODULE, + .aperture_sizes = intel_i830_sizes, + .size_type = FIXED_APER_SIZE, + .num_aperture_sizes = 4, + .needs_scratch_page = true, + .configure = intel_i9xx_configure, + .fetch_size = intel_i9xx_fetch_size, + .cleanup = intel_i915_cleanup, + .mask_memory = intel_gen6_mask_memory, + .masks = intel_i810_masks, + .agp_enable = intel_i810_agp_enable, + .cache_flush = global_cache_flush, + .create_gatt_table = intel_i965_create_gatt_table, + .free_gatt_table = intel_i830_free_gatt_table, + .insert_memory = intel_i915_insert_entries, + .remove_memory = intel_i915_remove_entries, + .alloc_by_type = intel_i830_alloc_by_type, + .free_by_type = intel_i810_free_by_type, + .agp_alloc_page = agp_generic_alloc_page, + .agp_alloc_pages = agp_generic_alloc_pages, + .agp_destroy_page = agp_generic_destroy_page, + .agp_destroy_pages = agp_generic_destroy_pages, + .agp_type_to_mask_type = intel_i830_type_to_mask_type, + .chipset_flush = intel_i915_chipset_flush, +#ifdef USE_PCI_DMA_API + .agp_map_page = intel_agp_map_page, + .agp_unmap_page = intel_agp_unmap_page, + .agp_map_memory = intel_agp_map_memory, + .agp_unmap_memory = intel_agp_unmap_memory, +#endif +}; + static const struct agp_bridge_driver intel_g33_driver = { .owner = THIS_MODULE, .aperture_sizes = intel_i830_sizes, -- cgit v0.10.2 From a2757b6fab6dee3dbf43bdb7d7226d03747fbdb1 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 9 Jul 2010 10:45:17 -0700 Subject: agp/intel: Add actual definitions of the Sandybridge PTE caching bits. diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 2547465..c05e3e5 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h @@ -60,6 +60,12 @@ #define I810_PTE_LOCAL 0x00000002 #define I810_PTE_VALID 0x00000001 #define I830_PTE_SYSTEM_CACHED 0x00000006 +/* GT PTE cache control fields */ +#define GEN6_PTE_UNCACHED 0x00000002 +#define GEN6_PTE_LLC 0x00000004 +#define GEN6_PTE_LLC_MLC 0x00000006 +#define GEN6_PTE_GFDT 0x00000008 + #define I810_SMRAM_MISCC 0x70 #define I810_GFX_MEM_WIN_SIZE 0x00010000 #define I810_GFX_MEM_WIN_32M 0x00010000 diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 2b1a0e9..ccd4b1e 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -176,7 +176,7 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem, if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) { - cache_bits = I830_PTE_SYSTEM_CACHED; + cache_bits = GEN6_PTE_LLC_MLC; } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { -- cgit v0.10.2 From 831cd4453598b2c8e193f077023910c6b0c39558 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 24 Jul 2010 18:29:37 +0100 Subject: agp/intel: Destroy the scatterlist on allocation failure A side-effect of being able to use custom page allocations with the sg_table is that it cannot reap the partially constructed scatterlist if fails to allocate a page. So we need to call sg_free_table() ourselves if sg_alloc_table() fails. Signed-off-by: Chris Wilson Cc Dave Airlie Signed-off-by: Eric Anholt diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 0c6d0fe..f804325 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -104,7 +104,7 @@ static int intel_agp_map_memory(struct agp_memory *mem) DBG("try mapping %lu pages\n", (unsigned long)mem->page_count); if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL)) - return -ENOMEM; + goto err; mem->sg_list = sg = st.sgl; @@ -113,11 +113,14 @@ static int intel_agp_map_memory(struct agp_memory *mem) mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list, mem->page_count, PCI_DMA_BIDIRECTIONAL); - if (unlikely(!mem->num_sg)) { - intel_agp_free_sglist(mem); - return -ENOMEM; - } + if (unlikely(!mem->num_sg)) + goto err; + return 0; + +err: + sg_free_table(&st); + return -ENOMEM; } static void intel_agp_unmap_memory(struct agp_memory *mem) -- cgit v0.10.2 From 4f444071702bf0b76cfb381150cf0fc8cacdc931 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 21 Jul 2010 13:57:47 -0700 Subject: drm/i915: apply DP bandwidth workaround for PCH eDP as well Fixes https://bugs.freedesktop.org/show_bug.cgi?id=29141 though the workaround itself is still a bit of a mystery. Tested-by: Adam Hill Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c612981e..5a11a2b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -534,7 +534,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, } } - if (IS_eDP(intel_encoder)) { + if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { /* okay we failed just pick the highest */ dp_priv->lane_count = max_lane_count; dp_priv->link_bw = bws[max_clock]; -- cgit v0.10.2 From 71677043350874c55f60dce06a03ab61e3af6e93 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 17 Jul 2010 13:38:43 +0100 Subject: drm/i915: Remove the redundant check for a fixed_panel_mode We already checked just a couple of lines above that we have found a fixed_panel_mode for the LVDS, so remove the surplus check. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 0eab8df..6ef9388 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -200,27 +200,25 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, if (dev_priv->panel_fixed_mode == NULL) return true; /* - * If we have timings from the BIOS for the panel, put them in + * We have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, * with the panel scaling set up to source from the H/VDisplay * of the original mode. */ - if (dev_priv->panel_fixed_mode != NULL) { - adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; - adjusted_mode->hsync_start = - dev_priv->panel_fixed_mode->hsync_start; - adjusted_mode->hsync_end = - dev_priv->panel_fixed_mode->hsync_end; - adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; - adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; - adjusted_mode->vsync_start = - dev_priv->panel_fixed_mode->vsync_start; - adjusted_mode->vsync_end = - dev_priv->panel_fixed_mode->vsync_end; - adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; - adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); - } + adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; + adjusted_mode->hsync_start = + dev_priv->panel_fixed_mode->hsync_start; + adjusted_mode->hsync_end = + dev_priv->panel_fixed_mode->hsync_end; + adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; + adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; + adjusted_mode->vsync_start = + dev_priv->panel_fixed_mode->vsync_start; + adjusted_mode->vsync_end = + dev_priv->panel_fixed_mode->vsync_end; + adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; + adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; + drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); /* Make sure pre-965s set dither correctly */ if (!IS_I965G(dev)) { -- cgit v0.10.2 From 49be663f9952d0fc50bb0a4a75c3fd201e40ec59 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 18 Jul 2010 12:05:54 +0100 Subject: drm/i915: Refactor panel fitting on the LVDS. (v2) Move the common routines into separate functions to not only increase readability, but also throwaway surplus code. In doing so, we review the calculation of the aspect preserving scaling and avoid the use of fixed-point until we need to calculate the accurate scale factor. v2: Improve comments as suggested by Jesse. 1 files changed, 105 insertions(+), 194 deletions(-) Signed-off-by: Chris Wilson Reviewed-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6ef9388..0a2e600 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -156,31 +156,73 @@ static int intel_lvds_mode_valid(struct drm_connector *connector, return MODE_OK; } +static void +centre_horizontally(struct drm_display_mode *mode, + int width) +{ + u32 border, sync_pos, blank_width, sync_width; + + /* keep the hsync and hblank widths constant */ + sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start; + blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start; + sync_pos = (blank_width - sync_width + 1) / 2; + + border = (mode->hdisplay - width + 1) / 2; + border += border & 1; /* make the border even */ + + mode->crtc_hdisplay = width; + mode->crtc_hblank_start = width + border; + mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; + + mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; + mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; +} + +static void +centre_vertically(struct drm_display_mode *mode, + int height) +{ + u32 border, sync_pos, blank_width, sync_width; + + /* keep the vsync and vblank widths constant */ + sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start; + blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start; + sync_pos = (blank_width - sync_width + 1) / 2; + + border = (mode->vdisplay - height + 1) / 2; + + mode->crtc_vdisplay = height; + mode->crtc_vblank_start = height + border; + mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; + + mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; + mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; +} + +static inline u32 panel_fitter_scaling(u32 source, u32 target) +{ + /* + * Floating point operation is not supported. So the FACTOR + * is defined, which can avoid the floating point computation + * when calculating the panel ratio. + */ +#define ACCURACY 12 +#define FACTOR (1 << ACCURACY) + u32 ratio = source * FACTOR / target; + return (FACTOR * ratio + FACTOR/2) / FACTOR; +} + static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - /* - * float point operation is not supported . So the PANEL_RATIO_FACTOR - * is defined, which can avoid the float point computation when - * calculating the panel ratio. - */ -#define PANEL_RATIO_FACTOR 8192 struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct drm_encoder *tmp_encoder; struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; - u32 pfit_control = 0, pfit_pgm_ratios = 0; - int left_border = 0, right_border = 0, top_border = 0; - int bottom_border = 0; - bool border = 0; - int panel_ratio, desired_ratio, vert_scale, horiz_scale; - int horiz_ratio, vert_ratio; - u32 hsync_width, vsync_width; - u32 hblank_width, vblank_width; - u32 hsync_pos, vsync_pos; + u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; /* Should never happen!! */ if (!IS_I965G(dev) && intel_crtc->pipe == 0) { @@ -228,11 +270,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, /* Native modes don't need fitting */ if (adjusted_mode->hdisplay == mode->hdisplay && - adjusted_mode->vdisplay == mode->vdisplay) { - pfit_pgm_ratios = 0; - border = 0; + adjusted_mode->vdisplay == mode->vdisplay) goto out; - } /* full screen scale for now */ if (HAS_PCH_SPLIT(dev)) @@ -240,25 +279,9 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, /* 965+ wants fuzzy fitting */ if (IS_I965G(dev)) - pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | - PFIT_FILTER_FUZZY; - - hsync_width = adjusted_mode->crtc_hsync_end - - adjusted_mode->crtc_hsync_start; - vsync_width = adjusted_mode->crtc_vsync_end - - adjusted_mode->crtc_vsync_start; - hblank_width = adjusted_mode->crtc_hblank_end - - adjusted_mode->crtc_hblank_start; - vblank_width = adjusted_mode->crtc_vblank_end - - adjusted_mode->crtc_vblank_start; - /* - * Deal with panel fitting options. Figure out how to stretch the - * image based on its aspect ratio & the current panel fitting mode. - */ - panel_ratio = adjusted_mode->hdisplay * PANEL_RATIO_FACTOR / - adjusted_mode->vdisplay; - desired_ratio = mode->hdisplay * PANEL_RATIO_FACTOR / - mode->vdisplay; + pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | + PFIT_FILTER_FUZZY); + /* * Enable automatic panel scaling for non-native modes so that they fill * the screen. Should be enabled before the pipe is enabled, according @@ -276,170 +299,63 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, * For centered modes, we have to calculate border widths & * heights and modify the values programmed into the CRTC. */ - left_border = (adjusted_mode->hdisplay - mode->hdisplay) / 2; - right_border = left_border; - if (mode->hdisplay & 1) - right_border++; - top_border = (adjusted_mode->vdisplay - mode->vdisplay) / 2; - bottom_border = top_border; - if (mode->vdisplay & 1) - bottom_border++; - /* Set active & border values */ - adjusted_mode->crtc_hdisplay = mode->hdisplay; - /* Keep the boder be even */ - if (right_border & 1) - right_border++; - /* use the border directly instead of border minuse one */ - adjusted_mode->crtc_hblank_start = mode->hdisplay + - right_border; - /* keep the blank width constant */ - adjusted_mode->crtc_hblank_end = - adjusted_mode->crtc_hblank_start + hblank_width; - /* get the hsync pos relative to hblank start */ - hsync_pos = (hblank_width - hsync_width) / 2; - /* keep the hsync pos be even */ - if (hsync_pos & 1) - hsync_pos++; - adjusted_mode->crtc_hsync_start = - adjusted_mode->crtc_hblank_start + hsync_pos; - /* keep the hsync width constant */ - adjusted_mode->crtc_hsync_end = - adjusted_mode->crtc_hsync_start + hsync_width; - adjusted_mode->crtc_vdisplay = mode->vdisplay; - /* use the border instead of border minus one */ - adjusted_mode->crtc_vblank_start = mode->vdisplay + - bottom_border; - /* keep the vblank width constant */ - adjusted_mode->crtc_vblank_end = - adjusted_mode->crtc_vblank_start + vblank_width; - /* get the vsync start postion relative to vblank start */ - vsync_pos = (vblank_width - vsync_width) / 2; - adjusted_mode->crtc_vsync_start = - adjusted_mode->crtc_vblank_start + vsync_pos; - /* keep the vsync width constant */ - adjusted_mode->crtc_vsync_end = - adjusted_mode->crtc_vsync_start + vsync_width; - border = 1; + centre_horizontally(adjusted_mode, mode->hdisplay); + centre_vertically(adjusted_mode, mode->vdisplay); + border = LVDS_BORDER_ENABLE; break; + case DRM_MODE_SCALE_ASPECT: - /* Scale but preserve the spect ratio */ - pfit_control |= PFIT_ENABLE; + /* Scale but preserve the aspect ratio */ if (IS_I965G(dev)) { + u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; + u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; + + pfit_control |= PFIT_ENABLE; /* 965+ is easy, it does everything in hw */ - if (panel_ratio > desired_ratio) + if (scaled_width > scaled_height) pfit_control |= PFIT_SCALING_PILLAR; - else if (panel_ratio < desired_ratio) + else if (scaled_width < scaled_height) pfit_control |= PFIT_SCALING_LETTER; else pfit_control |= PFIT_SCALING_AUTO; } else { + u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; + u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; /* * For earlier chips we have to calculate the scaling * ratio by hand and program it into the * PFIT_PGM_RATIO register */ - u32 horiz_bits, vert_bits, bits = 12; - horiz_ratio = mode->hdisplay * PANEL_RATIO_FACTOR/ - adjusted_mode->hdisplay; - vert_ratio = mode->vdisplay * PANEL_RATIO_FACTOR/ - adjusted_mode->vdisplay; - horiz_scale = adjusted_mode->hdisplay * - PANEL_RATIO_FACTOR / mode->hdisplay; - vert_scale = adjusted_mode->vdisplay * - PANEL_RATIO_FACTOR / mode->vdisplay; - - /* retain aspect ratio */ - if (panel_ratio > desired_ratio) { /* Pillar */ - u32 scaled_width; - scaled_width = mode->hdisplay * vert_scale / - PANEL_RATIO_FACTOR; - horiz_ratio = vert_ratio; - pfit_control |= (VERT_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - /* Pillar will have left/right borders */ - left_border = (adjusted_mode->hdisplay - - scaled_width) / 2; - right_border = left_border; - if (mode->hdisplay & 1) /* odd resolutions */ - right_border++; - /* keep the border be even */ - if (right_border & 1) - right_border++; - adjusted_mode->crtc_hdisplay = scaled_width; - /* use border instead of border minus one */ - adjusted_mode->crtc_hblank_start = - scaled_width + right_border; - /* keep the hblank width constant */ - adjusted_mode->crtc_hblank_end = - adjusted_mode->crtc_hblank_start + - hblank_width; - /* - * get the hsync start pos relative to - * hblank start - */ - hsync_pos = (hblank_width - hsync_width) / 2; - /* keep the hsync_pos be even */ - if (hsync_pos & 1) - hsync_pos++; - adjusted_mode->crtc_hsync_start = - adjusted_mode->crtc_hblank_start + - hsync_pos; - /* keept hsync width constant */ - adjusted_mode->crtc_hsync_end = - adjusted_mode->crtc_hsync_start + - hsync_width; - border = 1; - } else if (panel_ratio < desired_ratio) { /* letter */ - u32 scaled_height = mode->vdisplay * - horiz_scale / PANEL_RATIO_FACTOR; - vert_ratio = horiz_ratio; - pfit_control |= (HORIZ_AUTO_SCALE | + if (scaled_width > scaled_height) { /* pillar */ + centre_horizontally(adjusted_mode, scaled_height / mode->vdisplay); + + border = LVDS_BORDER_ENABLE; + if (mode->vdisplay != adjusted_mode->vdisplay) { + u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay); + pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | + bits << PFIT_VERT_SCALE_SHIFT); + pfit_control |= (PFIT_ENABLE | + VERT_INTERP_BILINEAR | + HORIZ_INTERP_BILINEAR); + } + } else if (scaled_width < scaled_height) { /* letter */ + centre_vertically(adjusted_mode, scaled_width / mode->hdisplay); + + border = LVDS_BORDER_ENABLE; + if (mode->hdisplay != adjusted_mode->hdisplay) { + u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay); + pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | + bits << PFIT_VERT_SCALE_SHIFT); + pfit_control |= (PFIT_ENABLE | + VERT_INTERP_BILINEAR | + HORIZ_INTERP_BILINEAR); + } + } else + /* Aspects match, Let hw scale both directions */ + pfit_control |= (PFIT_ENABLE | + VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR); - /* Letterbox will have top/bottom border */ - top_border = (adjusted_mode->vdisplay - - scaled_height) / 2; - bottom_border = top_border; - if (mode->vdisplay & 1) - bottom_border++; - adjusted_mode->crtc_vdisplay = scaled_height; - /* use border instead of border minus one */ - adjusted_mode->crtc_vblank_start = - scaled_height + bottom_border; - /* keep the vblank width constant */ - adjusted_mode->crtc_vblank_end = - adjusted_mode->crtc_vblank_start + - vblank_width; - /* - * get the vsync start pos relative to - * vblank start - */ - vsync_pos = (vblank_width - vsync_width) / 2; - adjusted_mode->crtc_vsync_start = - adjusted_mode->crtc_vblank_start + - vsync_pos; - /* keep the vsync width constant */ - adjusted_mode->crtc_vsync_end = - adjusted_mode->crtc_vsync_start + - vsync_width; - border = 1; - } else { - /* Aspects match, Let hw scale both directions */ - pfit_control |= (VERT_AUTO_SCALE | - HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - } - horiz_bits = (1 << bits) * horiz_ratio / - PANEL_RATIO_FACTOR; - vert_bits = (1 << bits) * vert_ratio / - PANEL_RATIO_FACTOR; - pfit_pgm_ratios = - ((vert_bits << PFIT_VERT_SCALE_SHIFT) & - PFIT_VERT_SCALE_MASK) | - ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) & - PFIT_HORIZ_SCALE_MASK); } break; @@ -456,6 +372,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR); break; + default: break; } @@ -463,14 +380,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, out: lvds_priv->pfit_control = pfit_control; lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; - /* - * When there exists the border, it means that the LVDS_BORDR - * should be enabled. - */ - if (border) - dev_priv->lvds_border_bits |= LVDS_BORDER_ENABLE; - else - dev_priv->lvds_border_bits &= ~(LVDS_BORDER_ENABLE); + dev_priv->lvds_border_bits = border; + /* * XXX: It would be nice to support lower refresh rates on the * panels to reduce power consumption, and perhaps match the -- cgit v0.10.2 From f091737978251811e34e7813ba4bfae5cae0b810 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 16 Jul 2010 14:46:27 -0400 Subject: drm/i915/dp: Rename has_edp to is_pch_edp to reflect its real meaning Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5a11a2b..a06d186 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -43,7 +43,7 @@ #define DP_LINK_CONFIGURATION_SIZE 9 #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) -#define IS_PCH_eDP(dp_priv) ((dp_priv)->has_edp) +#define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp) struct intel_dp_priv { uint32_t output_reg; @@ -57,7 +57,7 @@ struct intel_dp_priv { struct intel_encoder *intel_encoder; struct i2c_adapter adapter; struct i2c_algo_dp_aux_data algo; - bool has_edp; + bool is_pch_edp; }; static void @@ -598,7 +598,7 @@ bool intel_pch_has_edp(struct drm_crtc *crtc) dp_priv = intel_encoder->dev_priv; if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) - return dp_priv->has_edp; + return dp_priv->is_pch_edp; } return false; } @@ -1530,7 +1530,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) { if (intel_dpd_is_edp(dev)) - dp_priv->has_edp = true; + dp_priv->is_pch_edp = true; } intel_encoder->crtc_mask = (1 << 0) | (1 << 1); -- cgit v0.10.2 From b329530ca7cdf6bf014f2124efd983e01265d623 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 16 Jul 2010 14:46:28 -0400 Subject: drm/i915/dp: Correctly report eDP in the core connector type Do this for both real eDP and for PCH_DP_D when used as the eDP connection. Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a06d186..016a923 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1492,6 +1492,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) struct intel_connector *intel_connector; struct intel_dp_priv *dp_priv; const char *name = NULL; + int type; intel_encoder = kcalloc(sizeof(struct intel_encoder) + sizeof(struct intel_dp_priv), 1, GFP_KERNEL); @@ -1506,18 +1507,24 @@ intel_dp_init(struct drm_device *dev, int output_reg) dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); + if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) + if (intel_dpd_is_edp(dev)) + dp_priv->is_pch_edp = true; + + if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { + type = DRM_MODE_CONNECTOR_eDP; + intel_encoder->type = INTEL_OUTPUT_EDP; + } else { + type = DRM_MODE_CONNECTOR_DisplayPort; + intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + } + connector = &intel_connector->base; - drm_connector_init(dev, connector, &intel_dp_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); + drm_connector_init(dev, connector, &intel_dp_connector_funcs, type); drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); connector->polled = DRM_CONNECTOR_POLL_HPD; - if (output_reg == DP_A) - intel_encoder->type = INTEL_OUTPUT_EDP; - else - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; - if (output_reg == DP_B || output_reg == PCH_DP_B) intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); else if (output_reg == DP_C || output_reg == PCH_DP_C) @@ -1528,11 +1535,6 @@ intel_dp_init(struct drm_device *dev, int output_reg) if (IS_eDP(intel_encoder)) intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); - if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) { - if (intel_dpd_is_edp(dev)) - dp_priv->is_pch_edp = true; - } - intel_encoder->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = true; connector->doublescan_allowed = 0; -- cgit v0.10.2 From cb0953d734348e8862d6d7edc666cfb3bf6d8fae Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 16 Jul 2010 14:46:29 -0400 Subject: drm/i915: Initialize LVDS and eDP outputs before anything else This makes them sort to the front in X, which makes them likely to be the primary outputs if you haven't specified a preference in your DE, which is likely to be what you want. Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 30d8911..82d1b91 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5111,19 +5111,26 @@ static void intel_setup_outputs(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_encoder *encoder; + bool dpd_is_edp = false; - intel_crt_init(dev); - - /* Set up integrated LVDS */ if (IS_MOBILE(dev) && !IS_I830(dev)) intel_lvds_init(dev); if (HAS_PCH_SPLIT(dev)) { - int found; + dpd_is_edp = intel_dpd_is_edp(dev); if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) intel_dp_init(dev, DP_A); + if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) + intel_dp_init(dev, PCH_DP_D); + } + + intel_crt_init(dev); + + if (HAS_PCH_SPLIT(dev)) { + int found; + if (I915_READ(HDMIB) & PORT_DETECTED) { /* PCH SDVOB multiplex with HDMIB */ found = intel_sdvo_init(dev, PCH_SDVOB); @@ -5142,7 +5149,7 @@ static void intel_setup_outputs(struct drm_device *dev) if (I915_READ(PCH_DP_C) & DP_DETECTED) intel_dp_init(dev, PCH_DP_C); - if (I915_READ(PCH_DP_D) & DP_DETECTED) + if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) intel_dp_init(dev, PCH_DP_D); } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 016a923..f7410cf 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1464,7 +1464,7 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) } /* check the VBT to see whether the eDP is on DP-D port */ -static bool intel_dpd_is_edp(struct drm_device *dev) +bool intel_dpd_is_edp(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct child_device_config *p_child; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8c941da..296933a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -180,6 +180,7 @@ void intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); extern bool intel_pch_has_edp(struct drm_crtc *crtc); +extern bool intel_dpd_is_edp(struct drm_device *dev); extern void intel_edp_link_config (struct intel_encoder *, int *, int *); -- cgit v0.10.2 From d6d952689a48375afb97f619f77d548f16d45a92 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 16 Jul 2010 14:46:30 -0400 Subject: drm/i915/pch: Set transcoder sync polarity for DP based on actual mode Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 82d1b91..9a95a27 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1998,9 +1998,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) reg = I915_READ(trans_dp_ctl); reg &= ~TRANS_DP_PORT_SEL_MASK; reg = TRANS_DP_OUTPUT_ENABLE | - TRANS_DP_ENH_FRAMING | - TRANS_DP_VSYNC_ACTIVE_HIGH | - TRANS_DP_HSYNC_ACTIVE_HIGH; + TRANS_DP_ENH_FRAMING; + + if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) + reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; + if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) + reg |= TRANS_DP_VSYNC_ACTIVE_HIGH; switch (intel_trans_dp_port_sel(crtc)) { case PCH_DP_B: -- cgit v0.10.2 From b599c0bca1e08a89a7fc4305bc84f4be30ada368 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 16 Jul 2010 14:46:31 -0400 Subject: drm/i915/hdmi: Set sync polarity based on actual mode Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 83bd764..197887e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -54,10 +54,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; u32 sdvox; - sdvox = SDVO_ENCODING_HDMI | - SDVO_BORDER_ENABLE | - SDVO_VSYNC_ACTIVE_HIGH | - SDVO_HSYNC_ACTIVE_HIGH; + sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + sdvox |= SDVO_VSYNC_ACTIVE_HIGH; + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + sdvox |= SDVO_HSYNC_ACTIVE_HIGH; if (hdmi_priv->has_hdmi_sink) { sdvox |= SDVO_AUDIO_ENABLE; -- cgit v0.10.2 From 81a14b46846fea0741902e8d8dfcc6c6c78154c8 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 16 Jul 2010 14:46:32 -0400 Subject: drm/i915/sdvo: Set sync polarity based on actual mode Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 76993ac..8b2bfc0 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1237,9 +1237,11 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, /* Set the SDVO control regs. */ if (IS_I965G(dev)) { - sdvox |= SDVO_BORDER_ENABLE | - SDVO_VSYNC_ACTIVE_HIGH | - SDVO_HSYNC_ACTIVE_HIGH; + sdvox |= SDVO_BORDER_ENABLE; + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + sdvox |= SDVO_VSYNC_ACTIVE_HIGH; + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + sdvox |= SDVO_HSYNC_ACTIVE_HIGH; } else { sdvox |= I915_READ(sdvo_priv->sdvo_reg); switch (sdvo_priv->sdvo_reg) { -- cgit v0.10.2 From b9efc4804b1e61ee01a0d824c5d27bfdb518fffe Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 19 Jul 2010 09:43:11 +0100 Subject: drm/i915: Add fixed panel mode parsed from EDID for eDP without fixed mode in VBT Signed-off-by: Zhao Yakui Reviewed-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f7410cf..2b99ab2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1374,8 +1374,22 @@ static int intel_dp_get_modes(struct drm_connector *connector) */ ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); - if (ret) + if (ret) { + if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && + !dev_priv->panel_fixed_mode) { + struct drm_display_mode *newmode; + list_for_each_entry(newmode, &connector->probed_modes, + head) { + if (newmode->type & DRM_MODE_TYPE_PREFERRED) { + dev_priv->panel_fixed_mode = + drm_mode_duplicate(dev, newmode); + break; + } + } + } + return ret; + } /* if eDP has no EDID, try to use fixed panel mode from VBT */ if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { -- cgit v0.10.2 From 1fc7947898e3c407a20e130458e30cc45aa3335c Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 19 Jul 2010 09:43:12 +0100 Subject: drm/i915: Enable panel fitting for eDP When trying to set other display mode besides the fixed panel mode, the panel fitting should be enabled. This is similar to LVDS. Signed-off-by: Zhao Yakui Reviewed-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9a95a27..ce96c3a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1903,7 +1903,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) } /* Enable panel fitting for LVDS */ - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) + || HAS_eDP || intel_pch_has_edp(crtc)) { temp = I915_READ(pf_ctl_reg); I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); -- cgit v0.10.2 From 0d3a1beecfa54b938edf3ed046902f072e1e180a Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 19 Jul 2010 09:43:13 +0100 Subject: drm/i915: Always use the fixed panel timing for eDP Signed-off-by: Zhao Yakui Reviewed-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2b99ab2..233e6fd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -511,11 +511,37 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, { struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; int lane_count, clock; int max_lane_count = intel_dp_max_lane_count(intel_encoder); int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; + if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && + dev_priv->panel_fixed_mode) { + struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; + + adjusted_mode->hdisplay = fixed_mode->hdisplay; + adjusted_mode->hsync_start = fixed_mode->hsync_start; + adjusted_mode->hsync_end = fixed_mode->hsync_end; + adjusted_mode->htotal = fixed_mode->htotal; + + adjusted_mode->vdisplay = fixed_mode->vdisplay; + adjusted_mode->vsync_start = fixed_mode->vsync_start; + adjusted_mode->vsync_end = fixed_mode->vsync_end; + adjusted_mode->vtotal = fixed_mode->vtotal; + + adjusted_mode->clock = fixed_mode->clock; + drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); + + /* + * the mode->clock is used to calculate the Data&Link M/N + * of the pipe. For the eDP the fixed clock should be used. + */ + mode->clock = dev_priv->panel_fixed_mode->clock; + } + for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) { int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); -- cgit v0.10.2 From 7de56f43e06ec6e17f548dfb359d395adbfbb87d Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Mon, 19 Jul 2010 09:43:14 +0100 Subject: drm/i915: Validate the mode for eDP by using fixed panel size Signed-off-by: Zhao Yakui Reviewed-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 233e6fd..40be1fa 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -150,9 +150,21 @@ intel_dp_mode_valid(struct drm_connector *connector, { struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; + struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = dev->dev_private; int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); int max_lanes = intel_dp_max_lane_count(intel_encoder); + if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && + dev_priv->panel_fixed_mode) { + if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) + return MODE_PANEL; + + if (mode->vdisplay > dev_priv->panel_fixed_mode->vdisplay) + return MODE_PANEL; + } + /* only refuse the mode on non eDP since we have seen some wierd eDP panels which are outside spec tolerances but somehow work by magic */ if (!IS_eDP(intel_encoder) && -- cgit v0.10.2 From a1efd14a99483a4fb9308902397ed86b69454c99 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 12 Jul 2010 19:35:38 +0100 Subject: drm/i915: Check overlay stride errata for i830 and i845 Apparently i830 and i845 cannot handle any stride that is not a multiple of 256, unlike their brethren which do support 64 byte aligned strides. Signed-off-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d7ad513..fe05ba2 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -958,7 +958,7 @@ static int check_overlay_src(struct drm_device *dev, || rec->src_width < N_HORIZ_Y_TAPS*4) return -EINVAL; - /* check alingment constrains */ + /* check alignment constraints */ switch (rec->flags & I915_OVERLAY_TYPE_MASK) { case I915_OVERLAY_RGB: /* not implemented */ @@ -990,7 +990,10 @@ static int check_overlay_src(struct drm_device *dev, return -EINVAL; /* stride checking */ - stride_mask = 63; + if (IS_I830(dev) || IS_845G(dev)) + stride_mask = 255; + else + stride_mask = 63; if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) return -EINVAL; -- cgit v0.10.2 From d79613643b4512962b2be5262a09b6694dd96101 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 13 Jul 2010 13:52:17 +0100 Subject: drm/i915: Typo in (unused) register mask for overlay. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index fe05ba2..f26ec2f 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -65,7 +65,7 @@ #define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */ #define OCMD_TVSYNCFLIP_PARITY (0x1<<9) #define OCMD_TVSYNCFLIP_ENABLE (0x1<<7) -#define OCMD_BUF_TYPE_MASK (Ox1<<5) +#define OCMD_BUF_TYPE_MASK (0x1<<5) #define OCMD_BUF_TYPE_FRAME (0x0<<5) #define OCMD_BUF_TYPE_FIELD (0x1<<5) #define OCMD_TEST_MODE (0x1<<4) -- cgit v0.10.2 From 8de9b311bcd117a97998574705829bd48bfa2971 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 19 Jul 2010 19:59:52 +0100 Subject: drm/i915: Round up the watermark entries (v3) Even though "we have enough padding that it should be ok", round up the watermark entries to the next unit to be on the safe side... v2: Use the DIV_ROUND_UP macro v3: Spotted a few more missing round-ups. Signed-off-by: Chris Wilson Cc: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ce96c3a..baaaeaa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2734,7 +2734,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, */ entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / 1000; - entries_required /= wm->cacheline_size; + entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size); DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required); @@ -2855,11 +2855,9 @@ static int i9xx_get_fifo_size(struct drm_device *dev, int plane) uint32_t dsparb = I915_READ(DSPARB); int size; - if (plane == 0) - size = dsparb & 0x7f; - else - size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - - (dsparb & 0x7f); + size = dsparb & 0x7f; + if (plane) + size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", size); @@ -2873,11 +2871,9 @@ static int i85x_get_fifo_size(struct drm_device *dev, int plane) uint32_t dsparb = I915_READ(DSPARB); int size; - if (plane == 0) - size = dsparb & 0x1ff; - else - size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - - (dsparb & 0x1ff); + size = dsparb & 0x1ff; + if (plane) + size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size; size >>= 1; /* Convert to cachelines */ DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, @@ -3009,12 +3005,12 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, */ entries_required = ((planea_clock / 1000) * pixel_size * latency_ns) / 1000; - entries_required /= G4X_FIFO_LINE_SIZE; + entries_required = DIV_ROUND_UP(entries_required, G4X_FIFO_LINE_SIZE); planea_wm = entries_required + planea_params.guard_size; entries_required = ((planeb_clock / 1000) * pixel_size * latency_ns) / 1000; - entries_required /= G4X_FIFO_LINE_SIZE; + entries_required = DIV_ROUND_UP(entries_required, G4X_FIFO_LINE_SIZE); planeb_wm = entries_required + planeb_params.guard_size; cursora_wm = cursorb_wm = 16; @@ -3033,12 +3029,12 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, /* Use ns/us then divide to preserve precision */ sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * pixel_size * sr_hdisplay; - sr_entries = roundup(sr_entries / cacheline_size, 1); + sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size); entries_required = (((sr_latency_ns / line_time_us) + 1000) / 1000) * pixel_size * 64; - entries_required = roundup(entries_required / - g4x_cursor_wm_info.cacheline_size, 1); + entries_required = DIV_ROUND_UP(entries_required, + g4x_cursor_wm_info.cacheline_size); cursor_sr = entries_required + g4x_cursor_wm_info.guard_size; if (cursor_sr > g4x_cursor_wm_info.max_wm) @@ -3089,7 +3085,7 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, /* Use ns/us then divide to preserve precision */ sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * pixel_size * sr_hdisplay; - sr_entries = roundup(sr_entries / I915_FIFO_LINE_SIZE, 1); + sr_entries = DIV_ROUND_UP(sr_entries, I915_FIFO_LINE_SIZE); DRM_DEBUG("self-refresh entries: %d\n", sr_entries); srwm = I965_FIFO_SIZE - sr_entries; if (srwm < 0) @@ -3098,8 +3094,8 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * pixel_size * 64; - sr_entries = roundup(sr_entries / - i965_cursor_wm_info.cacheline_size, 1); + sr_entries = DIV_ROUND_UP(sr_entries, + i965_cursor_wm_info.cacheline_size); cursor_sr = i965_cursor_wm_info.fifo_size - (sr_entries + i965_cursor_wm_info.guard_size); @@ -3181,7 +3177,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, /* Use ns/us then divide to preserve precision */ sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * pixel_size * sr_hdisplay; - sr_entries = roundup(sr_entries / cacheline_size, 1); + sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size); DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries); srwm = total_size - sr_entries; if (srwm < 0) @@ -3270,7 +3266,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, entries_required = ((planea_clock / 1000) * pixel_size * ILK_LP0_PLANE_LATENCY) / 1000; entries_required = DIV_ROUND_UP(entries_required, - ironlake_display_wm_info.cacheline_size); + ironlake_display_wm_info.cacheline_size); planea_wm = entries_required + ironlake_display_wm_info.guard_size; @@ -3304,7 +3300,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, entries_required = ((planeb_clock / 1000) * pixel_size * ILK_LP0_PLANE_LATENCY) / 1000; entries_required = DIV_ROUND_UP(entries_required, - ironlake_display_wm_info.cacheline_size); + ironlake_display_wm_info.cacheline_size); planeb_wm = entries_required + ironlake_display_wm_info.guard_size; @@ -3353,14 +3349,14 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, /* calculate the self-refresh watermark for display plane */ entries_required = line_count * sr_hdisplay * pixel_size; entries_required = DIV_ROUND_UP(entries_required, - ironlake_display_srwm_info.cacheline_size); + ironlake_display_srwm_info.cacheline_size); sr_wm = entries_required + ironlake_display_srwm_info.guard_size; /* calculate the self-refresh watermark for display cursor */ entries_required = line_count * pixel_size * 64; entries_required = DIV_ROUND_UP(entries_required, - ironlake_cursor_srwm_info.cacheline_size); + ironlake_cursor_srwm_info.cacheline_size); cursor_wm = entries_required + ironlake_cursor_srwm_info.guard_size; -- cgit v0.10.2 From b9421ae8f30958deea98d71477b4a77a066856b4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 19 Jul 2010 21:46:08 +0100 Subject: drm/i915: Warn if we run out of FIFO space for a mode Signed-off-by: Chris Wilson Cc: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index baaaeaa..132314e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2745,8 +2745,14 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, /* Don't promote wm_size to unsigned... */ if (wm_size > (long)wm->max_wm) wm_size = wm->max_wm; - if (wm_size <= 0) + if (wm_size <= 0) { wm_size = wm->default_wm; + DRM_ERROR("Insufficient FIFO for plane, expect flickering:" + " entries required = %ld, available = %lu.\n", + entries_required + wm->guard_size, + wm->fifo_size); + } + return wm_size; } -- cgit v0.10.2 From b09a1feca65764311f8a3e14befb52b98d705f0a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 23 Jul 2010 23:18:49 +0100 Subject: drm/i915: Refactor i915_gem_retire_requests() Combine the iteration over active render rings into a common function. This is in preparation for reusing the idle function to also retire deferred free requests. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 119692f..5044f65 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags) /* * Clear request list */ - i915_gem_retire_requests(dev, &dev_priv->render_ring); + i915_gem_retire_requests(dev); if (need_display) i915_save_display(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 46a544a..a27780b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -960,8 +960,7 @@ uint32_t i915_get_gem_seqno(struct drm_device *dev, bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); -void i915_gem_retire_requests(struct drm_device *dev, - struct intel_ring_buffer *ring); +void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_retire_work_handler(struct work_struct *work); void i915_gem_clflush_object(struct drm_gem_object *obj); int i915_gem_object_set_domain(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b1069dc..138ca6e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1709,9 +1709,9 @@ i915_get_gem_seqno(struct drm_device *dev, /** * This function clears the request list as sequence numbers are passed. */ -void -i915_gem_retire_requests(struct drm_device *dev, - struct intel_ring_buffer *ring) +static void +i915_gem_retire_requests_ring(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; uint32_t seqno; @@ -1751,6 +1751,16 @@ i915_gem_retire_requests(struct drm_device *dev, } void +i915_gem_retire_requests(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + i915_gem_retire_requests_ring(dev, &dev_priv->render_ring); + if (HAS_BSD(dev)) + i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring); +} + +void i915_gem_retire_work_handler(struct work_struct *work) { drm_i915_private_t *dev_priv; @@ -1761,10 +1771,7 @@ i915_gem_retire_work_handler(struct work_struct *work) dev = dev_priv->dev; mutex_lock(&dev->struct_mutex); - i915_gem_retire_requests(dev, &dev_priv->render_ring); - - if (HAS_BSD(dev)) - i915_gem_retire_requests(dev, &dev_priv->bsd_ring); + i915_gem_retire_requests(dev); if (!dev_priv->mm.suspended && (!list_empty(&dev_priv->render_ring.request_list) || @@ -1832,7 +1839,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, * a separate wait queue to handle that. */ if (ret == 0) - i915_gem_retire_requests(dev, ring); + i915_gem_retire_requests_ring(dev, ring); return ret; } @@ -2107,10 +2114,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) struct intel_ring_buffer *render_ring = &dev_priv->render_ring; struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; for (;;) { - i915_gem_retire_requests(dev, render_ring); - - if (HAS_BSD(dev)) - i915_gem_retire_requests(dev, bsd_ring); + i915_gem_retire_requests(dev); /* If there's an inactive buffer available now, grab it * and be done. @@ -4330,7 +4334,6 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_busy *args = data; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; - drm_i915_private_t *dev_priv = dev->dev_private; obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) { @@ -4345,10 +4348,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, * actually unmasked, and our working set ends up being larger than * required. */ - i915_gem_retire_requests(dev, &dev_priv->render_ring); - - if (HAS_BSD(dev)) - i915_gem_retire_requests(dev, &dev_priv->bsd_ring); + i915_gem_retire_requests(dev); obj_priv = to_intel_bo(obj); /* Don't count being on the flushing list against the object being @@ -5054,10 +5054,7 @@ rescan: continue; spin_unlock(&shrink_list_lock); - i915_gem_retire_requests(dev, &dev_priv->render_ring); - - if (HAS_BSD(dev)) - i915_gem_retire_requests(dev, &dev_priv->bsd_ring); + i915_gem_retire_requests(dev); list_for_each_entry_safe(obj_priv, next_obj, &dev_priv->mm.inactive_list, -- cgit v0.10.2 From be72615bcf4d5b7b314d836c5e1b4baa4b65dad1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 23 Jul 2010 23:18:50 +0100 Subject: drm/i915: Repeat unbinding during free if interrupted (v6) If during the freeing of an object the unbind is interrupted by a system call, which is quite possible if we have outstanding GPU writes that must be flushed, the unbind is silently aborted. This still leaves the AGP region and backing pages allocated, and perhaps more importantly, the object remains upon the various lists exposing us to memory corruption. I think this is the cause behind the use-after-free, such as Bug 15664 - Graphics hang and kernel backtrace when starting Azureus with Compiz enabled https://bugzilla.kernel.org/show_bug.cgi?id=15664 v2: Daniel Vetter reminded me that kernel space programming is never easy. We cannot simply spin to clear the pending signal and so must deferred the freeing of the object until later. v3: Run from the top level retire requests. v4: Tested with P(return -ERESTARTSYS)=.5 from i915_gem_do_wait_request() v5: Rebase against Eric's for-linus tree. v6: Refactor, split and add a comment about avoiding unbounded recursion. Signed-off-by: Chris Wilson Cc: Daniel Vetter Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a27780b..906663b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -552,6 +552,14 @@ typedef struct drm_i915_private { struct list_head fence_list; /** + * List of objects currently pending being freed. + * + * These objects are no longer in use, but due to a signal + * we were prevented from freeing them at the appointed time. + */ + struct list_head deferred_free_list; + + /** * We leave the user IRQ off as much as possible, * but this means that requests will finish and never * be retired once the system goes idle. Set a timer to diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 138ca6e..f45f385 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -53,6 +53,7 @@ static int i915_gem_evict_from_inactive_list(struct drm_device *dev); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv); +static void i915_gem_free_object_tail(struct drm_gem_object *obj); static LIST_HEAD(shrink_list); static DEFINE_SPINLOCK(shrink_list_lock); @@ -1755,6 +1756,20 @@ i915_gem_retire_requests(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + if (!list_empty(&dev_priv->mm.deferred_free_list)) { + struct drm_i915_gem_object *obj_priv, *tmp; + + /* We must be careful that during unbind() we do not + * accidentally infinitely recurse into retire requests. + * Currently: + * retire -> free -> unbind -> wait -> retire_ring + */ + list_for_each_entry_safe(obj_priv, tmp, + &dev_priv->mm.deferred_free_list, + list) + i915_gem_free_object_tail(&obj_priv->base); + } + i915_gem_retire_requests_ring(dev, &dev_priv->render_ring); if (HAS_BSD(dev)) i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring); @@ -4458,20 +4473,19 @@ int i915_gem_init_object(struct drm_gem_object *obj) return 0; } -void i915_gem_free_object(struct drm_gem_object *obj) +static void i915_gem_free_object_tail(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; + drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + int ret; - trace_i915_gem_object_destroy(obj); - - while (obj_priv->pin_count > 0) - i915_gem_object_unpin(obj); - - if (obj_priv->phys_obj) - i915_gem_detach_phys_object(dev, obj); - - i915_gem_object_unbind(obj); + ret = i915_gem_object_unbind(obj); + if (ret == -ERESTARTSYS) { + list_move(&obj_priv->list, + &dev_priv->mm.deferred_free_list); + return; + } if (obj_priv->mmap_offset) i915_gem_free_mmap_offset(obj); @@ -4483,6 +4497,22 @@ void i915_gem_free_object(struct drm_gem_object *obj) kfree(obj_priv); } +void i915_gem_free_object(struct drm_gem_object *obj) +{ + struct drm_device *dev = obj->dev; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + + trace_i915_gem_object_destroy(obj); + + while (obj_priv->pin_count > 0) + i915_gem_object_unpin(obj); + + if (obj_priv->phys_obj) + i915_gem_detach_phys_object(dev, obj); + + i915_gem_free_object_tail(obj); +} + /** Unbinds all inactive objects. */ static int i915_gem_evict_from_inactive_list(struct drm_device *dev) @@ -4756,6 +4786,7 @@ i915_gem_load(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); INIT_LIST_HEAD(&dev_priv->mm.inactive_list); INIT_LIST_HEAD(&dev_priv->mm.fence_list); + INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list); INIT_LIST_HEAD(&dev_priv->render_ring.active_list); INIT_LIST_HEAD(&dev_priv->render_ring.request_list); if (HAS_BSD(dev)) { -- cgit v0.10.2 From 8dc1775dce10d5e47d2805665804fddf39ea3a90 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 23 Jul 2010 23:18:51 +0100 Subject: drm/i915: Attempt to uncouple object after catastrophic failure in unbind If we fail to flush outstanding GPU writes but return the memory to the system, we risk corrupting memory should the GPU recovery and complete those writes. On the other hand, if we bail early and free the object then we have a definite use-after-free and real memory corruption. Choose the lesser of two evils, since in order to recover from the hung GPU we need to completely reset it, those pending writes should never happen. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f45f385..eeb7688 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1967,11 +1967,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) * before we unbind. */ ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) { - if (ret != -ERESTARTSYS) - DRM_ERROR("set_domain failed: %d\n", ret); + if (ret == -ERESTARTSYS) return ret; - } + /* Continue on if we fail due to EIO, the GPU is hung so we + * should be safe and we need to cleanup or else we might + * cause memory corruption through use-after-free. + */ BUG_ON(obj_priv->active); @@ -2007,7 +2008,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) trace_i915_gem_object_unbind(obj); - return 0; + return ret; } static struct drm_gem_object * -- cgit v0.10.2 From 86f100b136626e91f4f66f3776303475e2e58998 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 24 Jul 2010 21:03:49 +0100 Subject: drm/i915: Unreference object not handle on creation When creating an object, we create the handle by which it is known to the process and which own the reference to the object. That reference to the new handle is what we want to transfer to the process, not the lost reference to the object; so free the local object reference *not* the process's handle reference. This brings i915_gem_object_create_ioctl() into line with drm_gem_open_ioctl() Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index eeb7688..4efd4fd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -128,8 +128,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, return -ENOMEM; ret = drm_gem_handle_create(file_priv, obj, &handle); - drm_gem_object_handle_unreference_unlocked(obj); - + drm_gem_object_unreference_unlocked(obj); if (ret) return ret; -- cgit v0.10.2 From cda4b7d3a5b1dcbc0d8e7bad52134347798e9047 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 9 Jul 2010 08:45:04 +0100 Subject: drm/i915: Unset cursor if out-of-bounds upon mode change (v4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The docs warn that to position the cursor such that no part of it is visible on the pipe is an undefined operation. Avoid such circumstances upon changing the mode, or at any other time, by unsetting the cursor if it moves out of bounds. "For normal high resolution display modes, the cursor must have at least a single pixel positioned over the active screen.” (p143, p148 of the hardware registers docs). Fixes: Bug 24748 - [965G] Graphics crashes when resolution is changed with KMS enabled https://bugs.freedesktop.org/show_bug.cgi?id=24748 v2: Only update the cursor registers if they change. v3: Fix the unsigned comparision of x,y against width,height. v4: Always set CUR.BASE or else the cursor may become corrupt. Signed-off-by: Chris Wilson Reported-by: Christian Eggers Cc: Christopher James Halse Rogers Cc: stable@kernel.org Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 132314e..ca3b8a8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -43,6 +43,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type); static void intel_update_watermarks(struct drm_device *dev); static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule); +static void intel_crtc_update_cursor(struct drm_crtc *crtc); typedef struct { /* given values */ @@ -3575,6 +3576,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, return -EINVAL; } + /* Ensure that the cursor is valid for the new mode before changing... */ + intel_crtc_update_cursor(crtc); + if (is_lvds && dev_priv->lvds_downclock_avail) { has_reduced_clock = limit->find_pll(limit, crtc, dev_priv->lvds_downclock, @@ -4111,6 +4115,85 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) } } +/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ +static void intel_crtc_update_cursor(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + int x = intel_crtc->cursor_x; + int y = intel_crtc->cursor_y; + uint32_t base, pos; + bool visible; + + pos = 0; + + if (crtc->fb) { + base = intel_crtc->cursor_addr; + if (x > (int) crtc->fb->width) + base = 0; + + if (y > (int) crtc->fb->height) + base = 0; + } else + base = 0; + + if (x < 0) { + if (x + intel_crtc->cursor_width < 0) + base = 0; + + pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; + x = -x; + } + pos |= x << CURSOR_X_SHIFT; + + if (y < 0) { + if (y + intel_crtc->cursor_height < 0) + base = 0; + + pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; + y = -y; + } + pos |= y << CURSOR_Y_SHIFT; + + visible = base != 0; + if (!visible && !intel_crtc->cursor_visble) + return; + + I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); + if (intel_crtc->cursor_visble != visible) { + uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); + if (base) { + /* Hooray for CUR*CNTR differences */ + if (IS_MOBILE(dev) || IS_I9XX(dev)) { + cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); + cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + cntl |= pipe << 28; /* Connect to correct pipe */ + } else { + cntl &= ~(CURSOR_FORMAT_MASK); + cntl |= CURSOR_ENABLE; + cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; + } + } else { + if (IS_MOBILE(dev) || IS_I9XX(dev)) { + cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); + cntl |= CURSOR_MODE_DISABLE; + } else { + cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); + } + } + I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); + + intel_crtc->cursor_visble = visible; + } + /* and commit changes on next vblank */ + I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); + + if (visible) + intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); +} + static int intel_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, @@ -4121,11 +4204,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_gem_object *bo; struct drm_i915_gem_object *obj_priv; - int pipe = intel_crtc->pipe; - uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; - uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; - uint32_t temp = I915_READ(control); - size_t addr; + uint32_t addr; int ret; DRM_DEBUG_KMS("\n"); @@ -4133,12 +4212,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, /* if we want to turn off the cursor ignore width and height */ if (!handle) { DRM_DEBUG_KMS("cursor off\n"); - if (IS_MOBILE(dev) || IS_I9XX(dev)) { - temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); - temp |= CURSOR_MODE_DISABLE; - } else { - temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); - } addr = 0; bo = NULL; mutex_lock(&dev->struct_mutex); @@ -4180,7 +4253,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, addr = obj_priv->gtt_offset; } else { - ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); + ret = i915_gem_attach_phys_object(dev, bo, + (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); if (ret) { DRM_ERROR("failed to attach phys object\n"); goto fail_locked; @@ -4191,21 +4265,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, if (!IS_I9XX(dev)) I915_WRITE(CURSIZE, (height << 12) | width); - /* Hooray for CUR*CNTR differences */ - if (IS_MOBILE(dev) || IS_I9XX(dev)) { - temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); - temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - temp |= (pipe << 28); /* Connect to correct pipe */ - } else { - temp &= ~(CURSOR_FORMAT_MASK); - temp |= CURSOR_ENABLE; - temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; - } - finish: - I915_WRITE(control, temp); - I915_WRITE(base, addr); - if (intel_crtc->cursor_bo) { if (dev_priv->info->cursor_needs_physical) { if (intel_crtc->cursor_bo != bo) @@ -4219,6 +4279,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, intel_crtc->cursor_addr = addr; intel_crtc->cursor_bo = bo; + intel_crtc->cursor_width = width; + intel_crtc->cursor_height = height; + + intel_crtc_update_cursor(crtc); return 0; fail_unpin: @@ -4232,34 +4296,12 @@ fail: static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_framebuffer *intel_fb; - int pipe = intel_crtc->pipe; - uint32_t temp = 0; - uint32_t adder; - - if (crtc->fb) { - intel_fb = to_intel_framebuffer(crtc->fb); - intel_mark_busy(dev, intel_fb->obj); - } - - if (x < 0) { - temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; - x = -x; - } - if (y < 0) { - temp |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; - y = -y; - } - temp |= x << CURSOR_X_SHIFT; - temp |= y << CURSOR_Y_SHIFT; + intel_crtc->cursor_x = x; + intel_crtc->cursor_y = y; - adder = intel_crtc->cursor_addr; - I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); - I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder); + intel_crtc_update_cursor(crtc); return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 296933a..b219014 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -143,8 +143,6 @@ struct intel_crtc { struct drm_crtc base; enum pipe pipe; enum plane plane; - struct drm_gem_object *cursor_bo; - uint32_t cursor_addr; u8 lut_r[256], lut_g[256], lut_b[256]; int dpms_mode; bool busy; /* is scanout buffer being updated frequently? */ @@ -153,6 +151,12 @@ struct intel_crtc { struct intel_overlay *overlay; struct intel_unpin_work *unpin_work; int fdi_lanes; + + struct drm_gem_object *cursor_bo; + uint32_t cursor_addr; + int16_t cursor_x, cursor_y; + int16_t cursor_width, cursor_height; + bool cursor_visble; }; #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) -- cgit v0.10.2 From d1d6ca73ef548748e141747e7260798327d6a2c1 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 8 Jul 2010 09:22:46 -0700 Subject: drm/agp/i915: trim stolen space to 32M Some BIOSes will claim a large chunk of stolen space. Unless we reclaim it, our aperture for remapping buffer objects will be constrained. So clamp the stolen space to 32M and ignore the rest. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=15469 among others. Adding the ignored stolen memory back into the general pool using the memory hotplug code is left as an exercise for the reader. Signed-off-by: Jesse Barnes Reviewed-by: Simon Farnsworth Tested-by: Artem S. Tashkinov Signed-off-by: Eric Anholt diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index f804325..d22ffb8 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -25,6 +25,10 @@ #define USE_PCI_DMA_API 1 #endif +/* Max amount of stolen space, anything above will be returned to Linux */ +int intel_max_stolen = 32 * 1024 * 1024; +EXPORT_SYMBOL(intel_max_stolen); + static const struct aper_size_info_fixed intel_i810_sizes[] = { {64, 16384, 4}, @@ -713,7 +717,12 @@ static void intel_i830_init_gtt_entries(void) break; } } - if (gtt_entries > 0) { + if (!local && gtt_entries > intel_max_stolen) { + dev_info(&agp_bridge->dev->dev, + "detected %dK stolen memory, trimming to %dK\n", + gtt_entries / KB(1), intel_max_stolen / KB(1)); + gtt_entries = intel_max_stolen / KB(4); + } else if (gtt_entries > 0) { dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n", gtt_entries / KB(1), local ? "local" : "stolen"); gtt_entries /= KB(4); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 14054c0..f19ffe8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -41,6 +41,8 @@ #include #include +extern int intel_max_stolen; /* from AGP driver */ + /** * Sets up the hardware status page for devices that need a physical address * in the register. @@ -2106,6 +2108,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (ret) goto out_iomapfree; + if (prealloc_size > intel_max_stolen) { + DRM_INFO("detected %dM stolen memory, trimming to %dM\n", + prealloc_size >> 20, intel_max_stolen >> 20); + prealloc_size = intel_max_stolen; + } + dev_priv->wq = create_singlethread_workqueue("i915"); if (dev_priv->wq == NULL) { DRM_ERROR("Failed to create our workqueue.\n"); -- cgit v0.10.2 From e0a2ca737597de5068634df2706f4cf1c1e32d84 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 8 Jul 2010 12:24:52 -0400 Subject: drm/radeon/kms: make sure rio_mem is valid before unmapping it If we were not able to map the io bar in device init, don't attempt to unmap it in device fini. All radeons should have a io bar, so I doubt this would ever trigger, but just to be on the safe side... Pointed out by: Alberto Milone Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 0fea894..a64811a 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -737,7 +737,8 @@ void radeon_device_fini(struct radeon_device *rdev) destroy_workqueue(rdev->wq); vga_switcheroo_unregister_client(rdev->pdev); vga_client_register(rdev->pdev, NULL, NULL, NULL); - pci_iounmap(rdev->pdev, rdev->rio_mem); + if (rdev->rio_mem) + pci_iounmap(rdev->pdev, rdev->rio_mem); rdev->rio_mem = NULL; iounmap(rdev->rmmio); rdev->rmmio = NULL; -- cgit v0.10.2 From 2581afccadd347bf97c3a5620ba72c99aca8c355 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 20 Jul 2010 03:24:11 -0400 Subject: drm/radeon/kms: make sure HPD is set to NONE on analog-only connectors HPD is digital only. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 41286c9..6b9aac7 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1082,6 +1082,8 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.load_detect_property, 1); + /* no HPD on analog connectors */ + radeon_connector->hpd.hpd = RADEON_HPD_NONE; connector->polled = DRM_CONNECTOR_POLL_CONNECT; break; case DRM_MODE_CONNECTOR_DVIA: @@ -1096,6 +1098,8 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.load_detect_property, 1); + /* no HPD on analog connectors */ + radeon_connector->hpd.hpd = RADEON_HPD_NONE; break; case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVID: @@ -1186,6 +1190,8 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.tv_std_property, radeon_atombios_get_tv_info(rdev)); + /* no HPD on analog connectors */ + radeon_connector->hpd.hpd = RADEON_HPD_NONE; } break; case DRM_MODE_CONNECTOR_LVDS: @@ -1209,7 +1215,7 @@ radeon_add_atom_connector(struct drm_device *dev, break; } - if (hpd->hpd == RADEON_HPD_NONE) { + if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { if (i2c_bus->valid) connector->polled = DRM_CONNECTOR_POLL_CONNECT; } else @@ -1276,6 +1282,8 @@ radeon_add_legacy_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.load_detect_property, 1); + /* no HPD on analog connectors */ + radeon_connector->hpd.hpd = RADEON_HPD_NONE; connector->polled = DRM_CONNECTOR_POLL_CONNECT; break; case DRM_MODE_CONNECTOR_DVIA: @@ -1290,6 +1298,8 @@ radeon_add_legacy_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.load_detect_property, 1); + /* no HPD on analog connectors */ + radeon_connector->hpd.hpd = RADEON_HPD_NONE; break; case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVID: @@ -1328,6 +1338,8 @@ radeon_add_legacy_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.tv_std_property, radeon_combios_get_tv_info(rdev)); + /* no HPD on analog connectors */ + radeon_connector->hpd.hpd = RADEON_HPD_NONE; } break; case DRM_MODE_CONNECTOR_LVDS: @@ -1345,7 +1357,7 @@ radeon_add_legacy_connector(struct drm_device *dev, break; } - if (hpd->hpd == RADEON_HPD_NONE) { + if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { if (i2c_bus->valid) connector->polled = DRM_CONNECTOR_POLL_CONNECT; } else -- cgit v0.10.2 From 7b824ec2e5d7d086264ecae51e30e3c5e00cdecc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 26 Jul 2010 14:49:07 -0700 Subject: drm/i915: Clear the Ironlake dithering flags when the pipe doesn't want it. My fine DisplayPort output was getting ST dithering forever after having had the LVDS enabled at one point. Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ca3b8a8..ae17185 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3888,6 +3888,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, udelay(150); } + if (HAS_PCH_SPLIT(dev)) { + pipeconf &= ~PIPE_ENABLE_DITHER; + pipeconf &= ~PIPE_DITHER_TYPE_MASK; + } + /* The LVDS pin pair needs to be on before the DPLLs are enabled. * This is an exception to the general rule that mode_set doesn't turn * things on. @@ -3930,16 +3935,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, if (dev_priv->lvds_dither) { if (HAS_PCH_SPLIT(dev)) { pipeconf |= PIPE_ENABLE_DITHER; - pipeconf &= ~PIPE_DITHER_TYPE_MASK; pipeconf |= PIPE_DITHER_TYPE_ST01; } else lvds |= LVDS_ENABLE_DITHER; } else { - if (HAS_PCH_SPLIT(dev)) { - pipeconf &= ~PIPE_ENABLE_DITHER; - pipeconf &= ~PIPE_DITHER_TYPE_MASK; - } else + if (!HAS_PCH_SPLIT(dev)) { lvds &= ~LVDS_ENABLE_DITHER; + } } } I915_WRITE(lvds_reg, lvds); -- cgit v0.10.2 From ba4420c224c2808f2661cf8428f43ceef7a73a4a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 9 Mar 2010 10:56:52 +1000 Subject: drm: move ttm global code to core drm I wrote this for the prime sharing work, but I also noticed other external non-upstream drivers from a large company carrying a similiar patch, so I may as well ship it in master. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index df8f923..f3a23a3 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -12,7 +12,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_platform.o drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ drm_crtc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \ - drm_trace_points.o + drm_trace_points.o drm_global.o drm-$(CONFIG_COMPAT) += drm_ioc32.o diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index b5a5168..d5b349d 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -288,6 +288,7 @@ static int __init drm_core_init(void) { int ret = -ENOMEM; + drm_global_init(); idr_init(&drm_minors_idr); if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) diff --git a/drivers/gpu/drm/drm_global.c b/drivers/gpu/drm/drm_global.c new file mode 100644 index 0000000..c87dc96 --- /dev/null +++ b/drivers/gpu/drm/drm_global.c @@ -0,0 +1,112 @@ +/************************************************************************** + * + * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include +#include +#include "drm_global.h" + +struct drm_global_item { + struct mutex mutex; + void *object; + int refcount; +}; + +static struct drm_global_item glob[DRM_GLOBAL_NUM]; + +void drm_global_init(void) +{ + int i; + + for (i = 0; i < DRM_GLOBAL_NUM; ++i) { + struct drm_global_item *item = &glob[i]; + mutex_init(&item->mutex); + item->object = NULL; + item->refcount = 0; + } +} + +void drm_global_release(void) +{ + int i; + for (i = 0; i < DRM_GLOBAL_NUM; ++i) { + struct drm_global_item *item = &glob[i]; + BUG_ON(item->object != NULL); + BUG_ON(item->refcount != 0); + } +} + +int drm_global_item_ref(struct drm_global_reference *ref) +{ + int ret; + struct drm_global_item *item = &glob[ref->global_type]; + void *object; + + mutex_lock(&item->mutex); + if (item->refcount == 0) { + item->object = kzalloc(ref->size, GFP_KERNEL); + if (unlikely(item->object == NULL)) { + ret = -ENOMEM; + goto out_err; + } + + ref->object = item->object; + ret = ref->init(ref); + if (unlikely(ret != 0)) + goto out_err; + + } + ++item->refcount; + ref->object = item->object; + object = item->object; + mutex_unlock(&item->mutex); + return 0; +out_err: + mutex_unlock(&item->mutex); + item->object = NULL; + return ret; +} +EXPORT_SYMBOL(drm_global_item_ref); + +void drm_global_item_unref(struct drm_global_reference *ref) +{ + struct drm_global_item *item = &glob[ref->global_type]; + + mutex_lock(&item->mutex); + BUG_ON(item->refcount == 0); + BUG_ON(ref->object != item->object); + if (--item->refcount == 0) { + ref->release(ref); + item->object = NULL; + } + mutex_unlock(&item->mutex); +} +EXPORT_SYMBOL(drm_global_item_unref); + diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index d0a35d9..e15db15 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -533,7 +533,7 @@ struct drm_nouveau_private { struct list_head vbl_waiting; struct { - struct ttm_global_reference mem_global_ref; + struct drm_global_reference mem_global_ref; struct ttm_bo_global_ref bo_global_ref; struct ttm_bo_device bdev; spinlock_t bo_list_lock; diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index c385d50..bd35f93 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -42,13 +42,13 @@ nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) } static int -nouveau_ttm_mem_global_init(struct ttm_global_reference *ref) +nouveau_ttm_mem_global_init(struct drm_global_reference *ref) { return ttm_mem_global_init(ref->object); } static void -nouveau_ttm_mem_global_release(struct ttm_global_reference *ref) +nouveau_ttm_mem_global_release(struct drm_global_reference *ref) { ttm_mem_global_release(ref->object); } @@ -56,16 +56,16 @@ nouveau_ttm_mem_global_release(struct ttm_global_reference *ref) int nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv) { - struct ttm_global_reference *global_ref; + struct drm_global_reference *global_ref; int ret; global_ref = &dev_priv->ttm.mem_global_ref; - global_ref->global_type = TTM_GLOBAL_TTM_MEM; + global_ref->global_type = DRM_GLOBAL_TTM_MEM; global_ref->size = sizeof(struct ttm_mem_global); global_ref->init = &nouveau_ttm_mem_global_init; global_ref->release = &nouveau_ttm_mem_global_release; - ret = ttm_global_item_ref(global_ref); + ret = drm_global_item_ref(global_ref); if (unlikely(ret != 0)) { DRM_ERROR("Failed setting up TTM memory accounting\n"); dev_priv->ttm.mem_global_ref.release = NULL; @@ -74,15 +74,15 @@ nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv) dev_priv->ttm.bo_global_ref.mem_glob = global_ref->object; global_ref = &dev_priv->ttm.bo_global_ref.ref; - global_ref->global_type = TTM_GLOBAL_TTM_BO; + global_ref->global_type = DRM_GLOBAL_TTM_BO; global_ref->size = sizeof(struct ttm_bo_global); global_ref->init = &ttm_bo_global_init; global_ref->release = &ttm_bo_global_release; - ret = ttm_global_item_ref(global_ref); + ret = drm_global_item_ref(global_ref); if (unlikely(ret != 0)) { DRM_ERROR("Failed setting up TTM BO subsystem\n"); - ttm_global_item_unref(&dev_priv->ttm.mem_global_ref); + drm_global_item_unref(&dev_priv->ttm.mem_global_ref); dev_priv->ttm.mem_global_ref.release = NULL; return ret; } @@ -96,8 +96,8 @@ nouveau_ttm_global_release(struct drm_nouveau_private *dev_priv) if (dev_priv->ttm.mem_global_ref.release == NULL) return; - ttm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref); - ttm_global_item_unref(&dev_priv->ttm.mem_global_ref); + drm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref); + drm_global_item_unref(&dev_priv->ttm.mem_global_ref); dev_priv->ttm.mem_global_ref.release = NULL; } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 368fecf0..3cd1c47 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -235,7 +235,7 @@ struct radeon_surface_reg { */ struct radeon_mman { struct ttm_bo_global_ref bo_global_ref; - struct ttm_global_reference mem_global_ref; + struct drm_global_reference mem_global_ref; struct ttm_bo_device bdev; bool mem_global_referenced; bool initialized; diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index e9918d8..84c53e4 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -59,28 +59,28 @@ static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) /* * Global memory. */ -static int radeon_ttm_mem_global_init(struct ttm_global_reference *ref) +static int radeon_ttm_mem_global_init(struct drm_global_reference *ref) { return ttm_mem_global_init(ref->object); } -static void radeon_ttm_mem_global_release(struct ttm_global_reference *ref) +static void radeon_ttm_mem_global_release(struct drm_global_reference *ref) { ttm_mem_global_release(ref->object); } static int radeon_ttm_global_init(struct radeon_device *rdev) { - struct ttm_global_reference *global_ref; + struct drm_global_reference *global_ref; int r; rdev->mman.mem_global_referenced = false; global_ref = &rdev->mman.mem_global_ref; - global_ref->global_type = TTM_GLOBAL_TTM_MEM; + global_ref->global_type = DRM_GLOBAL_TTM_MEM; global_ref->size = sizeof(struct ttm_mem_global); global_ref->init = &radeon_ttm_mem_global_init; global_ref->release = &radeon_ttm_mem_global_release; - r = ttm_global_item_ref(global_ref); + r = drm_global_item_ref(global_ref); if (r != 0) { DRM_ERROR("Failed setting up TTM memory accounting " "subsystem.\n"); @@ -90,14 +90,14 @@ static int radeon_ttm_global_init(struct radeon_device *rdev) rdev->mman.bo_global_ref.mem_glob = rdev->mman.mem_global_ref.object; global_ref = &rdev->mman.bo_global_ref.ref; - global_ref->global_type = TTM_GLOBAL_TTM_BO; + global_ref->global_type = DRM_GLOBAL_TTM_BO; global_ref->size = sizeof(struct ttm_bo_global); global_ref->init = &ttm_bo_global_init; global_ref->release = &ttm_bo_global_release; - r = ttm_global_item_ref(global_ref); + r = drm_global_item_ref(global_ref); if (r != 0) { DRM_ERROR("Failed setting up TTM BO subsystem.\n"); - ttm_global_item_unref(&rdev->mman.mem_global_ref); + drm_global_item_unref(&rdev->mman.mem_global_ref); return r; } @@ -108,8 +108,8 @@ static int radeon_ttm_global_init(struct radeon_device *rdev) static void radeon_ttm_global_fini(struct radeon_device *rdev) { if (rdev->mman.mem_global_referenced) { - ttm_global_item_unref(&rdev->mman.bo_global_ref.ref); - ttm_global_item_unref(&rdev->mman.mem_global_ref); + drm_global_item_unref(&rdev->mman.bo_global_ref.ref); + drm_global_item_unref(&rdev->mman.mem_global_ref); rdev->mman.mem_global_referenced = false; } } diff --git a/drivers/gpu/drm/ttm/Makefile b/drivers/gpu/drm/ttm/Makefile index 4256e20..b256d4a 100644 --- a/drivers/gpu/drm/ttm/Makefile +++ b/drivers/gpu/drm/ttm/Makefile @@ -3,7 +3,7 @@ ccflags-y := -Iinclude/drm ttm-y := ttm_agp_backend.o ttm_memory.o ttm_tt.o ttm_bo.o \ - ttm_bo_util.o ttm_bo_vm.o ttm_module.o ttm_global.o \ + ttm_bo_util.o ttm_bo_vm.o ttm_module.o \ ttm_object.o ttm_lock.o ttm_execbuf_util.o ttm_page_alloc.o obj-$(CONFIG_DRM_TTM) += ttm.o diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 9763288..cb4cf7e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1395,7 +1395,7 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj) kfree(glob); } -void ttm_bo_global_release(struct ttm_global_reference *ref) +void ttm_bo_global_release(struct drm_global_reference *ref) { struct ttm_bo_global *glob = ref->object; @@ -1404,7 +1404,7 @@ void ttm_bo_global_release(struct ttm_global_reference *ref) } EXPORT_SYMBOL(ttm_bo_global_release); -int ttm_bo_global_init(struct ttm_global_reference *ref) +int ttm_bo_global_init(struct drm_global_reference *ref) { struct ttm_bo_global_ref *bo_ref = container_of(ref, struct ttm_bo_global_ref, ref); diff --git a/drivers/gpu/drm/ttm/ttm_global.c b/drivers/gpu/drm/ttm/ttm_global.c deleted file mode 100644 index b170071..0000000 --- a/drivers/gpu/drm/ttm/ttm_global.c +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************** - * - * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include "ttm/ttm_module.h" -#include -#include -#include - -struct ttm_global_item { - struct mutex mutex; - void *object; - int refcount; -}; - -static struct ttm_global_item glob[TTM_GLOBAL_NUM]; - -void ttm_global_init(void) -{ - int i; - - for (i = 0; i < TTM_GLOBAL_NUM; ++i) { - struct ttm_global_item *item = &glob[i]; - mutex_init(&item->mutex); - item->object = NULL; - item->refcount = 0; - } -} - -void ttm_global_release(void) -{ - int i; - for (i = 0; i < TTM_GLOBAL_NUM; ++i) { - struct ttm_global_item *item = &glob[i]; - BUG_ON(item->object != NULL); - BUG_ON(item->refcount != 0); - } -} - -int ttm_global_item_ref(struct ttm_global_reference *ref) -{ - int ret; - struct ttm_global_item *item = &glob[ref->global_type]; - void *object; - - mutex_lock(&item->mutex); - if (item->refcount == 0) { - item->object = kzalloc(ref->size, GFP_KERNEL); - if (unlikely(item->object == NULL)) { - ret = -ENOMEM; - goto out_err; - } - - ref->object = item->object; - ret = ref->init(ref); - if (unlikely(ret != 0)) - goto out_err; - - } - ++item->refcount; - ref->object = item->object; - object = item->object; - mutex_unlock(&item->mutex); - return 0; -out_err: - mutex_unlock(&item->mutex); - item->object = NULL; - return ret; -} -EXPORT_SYMBOL(ttm_global_item_ref); - -void ttm_global_item_unref(struct ttm_global_reference *ref) -{ - struct ttm_global_item *item = &glob[ref->global_type]; - - mutex_lock(&item->mutex); - BUG_ON(item->refcount == 0); - BUG_ON(ref->object != item->object); - if (--item->refcount == 0) { - ref->release(ref); - item->object = NULL; - } - mutex_unlock(&item->mutex); -} -EXPORT_SYMBOL(ttm_global_item_unref); - diff --git a/drivers/gpu/drm/ttm/ttm_module.c b/drivers/gpu/drm/ttm/ttm_module.c index 9a6edbf..902d7cf 100644 --- a/drivers/gpu/drm/ttm/ttm_module.c +++ b/drivers/gpu/drm/ttm/ttm_module.c @@ -70,8 +70,6 @@ static int __init ttm_init(void) if (unlikely(ret != 0)) return ret; - ttm_global_init(); - atomic_set(&device_released, 0); ret = drm_class_device_register(&ttm_drm_class_device); if (unlikely(ret != 0)) @@ -81,7 +79,6 @@ static int __init ttm_init(void) out_no_dev_reg: atomic_set(&device_released, 1); wake_up_all(&exit_q); - ttm_global_release(); return ret; } @@ -95,7 +92,6 @@ static void __exit ttm_exit(void) */ wait_event(exit_q, atomic_read(&device_released) == 1); - ttm_global_release(); } module_init(ttm_init); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index eaad520..429f917 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -164,7 +164,7 @@ struct vmw_vga_topology_state { struct vmw_private { struct ttm_bo_device bdev; struct ttm_bo_global_ref bo_global_ref; - struct ttm_global_reference mem_global_ref; + struct drm_global_reference mem_global_ref; struct vmw_fifo_state fifo; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c index e3df4ad..8312328 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c @@ -44,29 +44,29 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma) return ttm_bo_mmap(filp, vma, &dev_priv->bdev); } -static int vmw_ttm_mem_global_init(struct ttm_global_reference *ref) +static int vmw_ttm_mem_global_init(struct drm_global_reference *ref) { DRM_INFO("global init.\n"); return ttm_mem_global_init(ref->object); } -static void vmw_ttm_mem_global_release(struct ttm_global_reference *ref) +static void vmw_ttm_mem_global_release(struct drm_global_reference *ref) { ttm_mem_global_release(ref->object); } int vmw_ttm_global_init(struct vmw_private *dev_priv) { - struct ttm_global_reference *global_ref; + struct drm_global_reference *global_ref; int ret; global_ref = &dev_priv->mem_global_ref; - global_ref->global_type = TTM_GLOBAL_TTM_MEM; + global_ref->global_type = DRM_GLOBAL_TTM_MEM; global_ref->size = sizeof(struct ttm_mem_global); global_ref->init = &vmw_ttm_mem_global_init; global_ref->release = &vmw_ttm_mem_global_release; - ret = ttm_global_item_ref(global_ref); + ret = drm_global_item_ref(global_ref); if (unlikely(ret != 0)) { DRM_ERROR("Failed setting up TTM memory accounting.\n"); return ret; @@ -75,11 +75,11 @@ int vmw_ttm_global_init(struct vmw_private *dev_priv) dev_priv->bo_global_ref.mem_glob = dev_priv->mem_global_ref.object; global_ref = &dev_priv->bo_global_ref.ref; - global_ref->global_type = TTM_GLOBAL_TTM_BO; + global_ref->global_type = DRM_GLOBAL_TTM_BO; global_ref->size = sizeof(struct ttm_bo_global); global_ref->init = &ttm_bo_global_init; global_ref->release = &ttm_bo_global_release; - ret = ttm_global_item_ref(global_ref); + ret = drm_global_item_ref(global_ref); if (unlikely(ret != 0)) { DRM_ERROR("Failed setting up TTM buffer objects.\n"); @@ -88,12 +88,12 @@ int vmw_ttm_global_init(struct vmw_private *dev_priv) return 0; out_no_bo: - ttm_global_item_unref(&dev_priv->mem_global_ref); + drm_global_item_unref(&dev_priv->mem_global_ref); return ret; } void vmw_ttm_global_release(struct vmw_private *dev_priv) { - ttm_global_item_unref(&dev_priv->bo_global_ref.ref); - ttm_global_item_unref(&dev_priv->mem_global_ref); + drm_global_item_unref(&dev_priv->bo_global_ref.ref); + drm_global_item_unref(&dev_priv->mem_global_ref); } diff --git a/include/drm/drm.h b/include/drm/drm.h index e3f46e0..e5f7061 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -663,6 +663,8 @@ struct drm_gem_open { #define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) #define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) +#define DRM_IOCTL_GEM_PRIME_OPEN DRM_IOWR(0x2e, struct drm_gem_open) + #define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) #define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) #define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode) diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 04b564b..53017ba 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1453,6 +1453,8 @@ void drm_gem_vm_open(struct vm_area_struct *vma); void drm_gem_vm_close(struct vm_area_struct *vma); int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); +#include "drm_global.h" + static inline void drm_gem_object_reference(struct drm_gem_object *obj) { diff --git a/include/drm/drm_global.h b/include/drm/drm_global.h new file mode 100644 index 0000000..a06805e --- /dev/null +++ b/include/drm/drm_global.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#ifndef _DRM_GLOBAL_H_ +#define _DRM_GLOBAL_H_ +enum drm_global_types { + DRM_GLOBAL_TTM_MEM = 0, + DRM_GLOBAL_TTM_BO, + DRM_GLOBAL_TTM_OBJECT, + DRM_GLOBAL_NUM +}; + +struct drm_global_reference { + enum drm_global_types global_type; + size_t size; + void *object; + int (*init) (struct drm_global_reference *); + void (*release) (struct drm_global_reference *); +}; + +extern void drm_global_init(void); +extern void drm_global_release(void); +extern int drm_global_item_ref(struct drm_global_reference *ref); +extern void drm_global_item_unref(struct drm_global_reference *ref); + +#endif diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 0ea602d..b875042 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -34,6 +34,7 @@ #include "ttm/ttm_memory.h" #include "ttm/ttm_module.h" #include "drm_mm.h" +#include "drm_global.h" #include "linux/workqueue.h" #include "linux/fs.h" #include "linux/spinlock.h" @@ -362,7 +363,7 @@ struct ttm_bo_driver { */ struct ttm_bo_global_ref { - struct ttm_global_reference ref; + struct drm_global_reference ref; struct ttm_mem_global *mem_glob; }; @@ -687,8 +688,8 @@ extern int ttm_mem_io_reserve(struct ttm_bo_device *bdev, extern void ttm_mem_io_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem); -extern void ttm_bo_global_release(struct ttm_global_reference *ref); -extern int ttm_bo_global_init(struct ttm_global_reference *ref); +extern void ttm_bo_global_release(struct drm_global_reference *ref); +extern int ttm_bo_global_init(struct drm_global_reference *ref); extern int ttm_bo_device_release(struct ttm_bo_device *bdev); diff --git a/include/drm/ttm/ttm_module.h b/include/drm/ttm/ttm_module.h index cf416ae..45fa318 100644 --- a/include/drm/ttm/ttm_module.h +++ b/include/drm/ttm/ttm_module.h @@ -35,26 +35,6 @@ struct kobject; #define TTM_PFX "[TTM] " - -enum ttm_global_types { - TTM_GLOBAL_TTM_MEM = 0, - TTM_GLOBAL_TTM_BO, - TTM_GLOBAL_TTM_OBJECT, - TTM_GLOBAL_NUM -}; - -struct ttm_global_reference { - enum ttm_global_types global_type; - size_t size; - void *object; - int (*init) (struct ttm_global_reference *); - void (*release) (struct ttm_global_reference *); -}; - -extern void ttm_global_init(void); -extern void ttm_global_release(void); -extern int ttm_global_item_ref(struct ttm_global_reference *ref); -extern void ttm_global_item_unref(struct ttm_global_reference *ref); extern struct kobject *ttm_get_kobj(void); #endif /* _TTM_MODULE_H_ */ -- cgit v0.10.2 From e06b14ee91a2ddefc9a67443a6cd8ee0fa800115 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 2 Aug 2010 12:13:46 -0400 Subject: drm/radeon/kms: handle the case of no active displays properly in the bandwidth code Logic was: if (mode0 && mode1) else if (mode0) else Should be: if (mode0 && mode1) else if (mode0) else if (mode1) Otherwise we may end up calculating the priority regs with unitialized values. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=16492 Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index f3a8c93..6fbb874 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -398,7 +398,9 @@ void rs690_bandwidth_update(struct radeon_device *rdev) struct drm_display_mode *mode1 = NULL; struct rs690_watermark wm0; struct rs690_watermark wm1; - u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt; + u32 tmp; + u32 d1mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1); + u32 d2mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1); fixed20_12 priority_mark02, priority_mark12, fill_rate; fixed20_12 a, b; @@ -495,10 +497,6 @@ void rs690_bandwidth_update(struct radeon_device *rdev) d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); } - WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); - WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); - WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); - WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); } else if (mode0) { if (dfixed_trunc(wm0.dbpp) > 64) a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair); @@ -528,13 +526,7 @@ void rs690_bandwidth_update(struct radeon_device *rdev) d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); if (rdev->disp_priority == 2) d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); - WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); - WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); - WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, - S_006D48_D2MODE_PRIORITY_A_OFF(1)); - WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, - S_006D4C_D2MODE_PRIORITY_B_OFF(1)); - } else { + } else if (mode1) { if (dfixed_trunc(wm1.dbpp) > 64) a.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair); else @@ -563,13 +555,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev) d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); if (rdev->disp_priority == 2) d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); - WREG32(R_006548_D1MODE_PRIORITY_A_CNT, - S_006548_D1MODE_PRIORITY_A_OFF(1)); - WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, - S_00654C_D1MODE_PRIORITY_B_OFF(1)); - WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); - WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); } + + WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); + WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); + WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); + WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); } uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg) diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index b951b87..4d6e860 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -927,7 +927,9 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) struct drm_display_mode *mode1 = NULL; struct rv515_watermark wm0; struct rv515_watermark wm1; - u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt; + u32 tmp; + u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF; + u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF; fixed20_12 priority_mark02, priority_mark12, fill_rate; fixed20_12 a, b; @@ -1001,10 +1003,6 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; } - WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); - WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); - WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); - WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); } else if (mode0) { if (dfixed_trunc(wm0.dbpp) > 64) a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); @@ -1034,11 +1032,7 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); if (rdev->disp_priority == 2) d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; - WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); - WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); - WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); - WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); - } else { + } else if (mode1) { if (dfixed_trunc(wm1.dbpp) > 64) a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); else @@ -1067,11 +1061,12 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev) d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); if (rdev->disp_priority == 2) d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; - WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); - WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); - WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); - WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); } + + WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); + WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); + WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); + WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); } void rv515_bandwidth_update(struct radeon_device *rdev) -- cgit v0.10.2 From 4c70b2eae371ebe83019ac47de6088b78124ab36 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 2 Aug 2010 19:39:15 -0400 Subject: drm/radeon/kms/igp: sideport is AMD only Intel variants don't support it. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 6df7bd5..3bc2bcd 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1032,21 +1032,18 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) u8 frev, crev; u16 data_offset; + /* sideport is AMD only */ + if (rdev->family == CHIP_RS600) + return false; + if (atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset)) { igp_info = (union igp_info *)(mode_info->atom_context->bios + data_offset); switch (crev) { case 1: - /* AMD IGPS */ - if ((rdev->family == CHIP_RS690) || - (rdev->family == CHIP_RS740)) { - if (igp_info->info.ulBootUpMemoryClock) - return true; - } else { - if (igp_info->info.ucMemoryType & 0xf0) - return true; - } + if (igp_info->info.ulBootUpMemoryClock) + return true; break; case 2: if (igp_info->info_2.ucMemoryType & 0x0f) diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index cd2a6c25..5e1474c 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -693,6 +693,10 @@ bool radeon_combios_sideport_present(struct radeon_device *rdev) struct drm_device *dev = rdev->ddev; u16 igp_info; + /* sideport is AMD only */ + if (rdev->family == CHIP_RS400) + return false; + igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE); if (igp_info) { diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 85cd911..cc05b23 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -696,7 +696,6 @@ void rs600_mc_init(struct radeon_device *rdev) rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); base = RREG32_MC(R_000004_MC_FB_LOCATION); base = G_000004_MC_FB_START(base) << 16; - rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); radeon_vram_location(rdev, &rdev->mc, base); rdev->mc.gtt_base_align = 0; radeon_gtt_location(rdev, &rdev->mc); diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 6fbb874..3e3f757 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -159,8 +159,8 @@ void rs690_mc_init(struct radeon_device *rdev) rdev->mc.visible_vram_size = rdev->mc.aper_size; base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); base = G_000100_MC_FB_START(base) << 16; - rs690_pm_info(rdev); rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); + rs690_pm_info(rdev); radeon_vram_location(rdev, &rdev->mc, base); rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; radeon_gtt_location(rdev, &rdev->mc); -- cgit v0.10.2 From d65d65b175a29bd7ea2bb69c046419329c4a5db7 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 3 Aug 2010 19:58:49 -0400 Subject: drm/radeon/kms: fix calculation of h/v scaling factors Prior to this patch the code was dividing the src_v by the dst_h and vice versa, rather than src_v/dst_v and src_h/dst_h. This could lead to problems in the calculation of the display watermarks. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 283beed..12a5414 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1073,11 +1073,13 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_encoder *radeon_encoder; bool first = true; + u32 src_v = 1, dst_v = 1; + u32 src_h = 1, dst_h = 1; list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - radeon_encoder = to_radeon_encoder(encoder); if (encoder->crtc != crtc) continue; + radeon_encoder = to_radeon_encoder(encoder); if (first) { /* set scaling */ if (radeon_encoder->rmx_type == RMX_OFF) @@ -1087,6 +1089,10 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, radeon_crtc->rmx_type = radeon_encoder->rmx_type; else radeon_crtc->rmx_type = RMX_OFF; + src_v = crtc->mode.vdisplay; + dst_v = radeon_crtc->native_mode.vdisplay; + src_h = crtc->mode.hdisplay; + dst_h = radeon_crtc->native_mode.vdisplay; /* copy native mode */ memcpy(&radeon_crtc->native_mode, &radeon_encoder->native_mode, @@ -1096,22 +1102,22 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { /* WARNING: Right now this can't happen but * in the future we need to check that scaling - * are consistent accross different encoder + * are consistent across different encoder * (ie all encoder can work with the same * scaling). */ - DRM_ERROR("Scaling not consistent accross encoder.\n"); + DRM_ERROR("Scaling not consistent across encoder.\n"); return false; } } } if (radeon_crtc->rmx_type != RMX_OFF) { fixed20_12 a, b; - a.full = dfixed_const(crtc->mode.vdisplay); - b.full = dfixed_const(radeon_crtc->native_mode.hdisplay); + a.full = dfixed_const(src_v); + b.full = dfixed_const(dst_v); radeon_crtc->vsc.full = dfixed_div(a, b); - a.full = dfixed_const(crtc->mode.hdisplay); - b.full = dfixed_const(radeon_crtc->native_mode.vdisplay); + a.full = dfixed_const(src_h); + b.full = dfixed_const(dst_h); radeon_crtc->hsc.full = dfixed_div(a, b); } else { radeon_crtc->vsc.full = dfixed_const(1); -- cgit v0.10.2 From 5b1714d386a2f0c0d270e3abe1ac39ad1b0ba010 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 3 Aug 2010 19:59:20 -0400 Subject: drm/radeon/kms: enable underscan option for digital connectors This connector attribute allows you to enable or disable underscan on a digital output to compensate for panels that automatically overscan (e.g., many HDMI TVs). Valid values for the attribute are: off - forces underscan off on - forces underscan on auto - enables underscan if an HDMI TV is connected, off otherwise default value is auto. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a2e65d9..12ad512 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -44,10 +44,6 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, memset(&args, 0, sizeof(args)); - args.usOverscanRight = 0; - args.usOverscanLeft = 0; - args.usOverscanBottom = 0; - args.usOverscanTop = 0; args.ucCRTC = radeon_crtc->crtc_id; switch (radeon_crtc->rmx_type) { @@ -56,7 +52,6 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); break; case RMX_ASPECT: a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; @@ -69,17 +64,16 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; } - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); break; case RMX_FULL: default: - args.usOverscanRight = 0; - args.usOverscanLeft = 0; - args.usOverscanBottom = 0; - args.usOverscanTop = 0; - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + args.usOverscanRight = radeon_crtc->h_border; + args.usOverscanLeft = radeon_crtc->h_border; + args.usOverscanBottom = radeon_crtc->v_border; + args.usOverscanTop = radeon_crtc->v_border; break; } + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } static void atombios_scaler_setup(struct drm_crtc *crtc) @@ -282,22 +276,22 @@ atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, u16 misc = 0; memset(&args, 0, sizeof(args)); - args.usH_Size = cpu_to_le16(mode->crtc_hdisplay); + args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (radeon_crtc->h_border * 2)); args.usH_Blanking_Time = - cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay); - args.usV_Size = cpu_to_le16(mode->crtc_vdisplay); + cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (radeon_crtc->h_border * 2)); + args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (radeon_crtc->v_border * 2)); args.usV_Blanking_Time = - cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay); + cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (radeon_crtc->v_border * 2)); args.usH_SyncOffset = - cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay); + cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + radeon_crtc->h_border); args.usH_SyncWidth = cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); args.usV_SyncOffset = - cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay); + cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + radeon_crtc->v_border); args.usV_SyncWidth = cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); - /*args.ucH_Border = mode->hborder;*/ - /*args.ucV_Border = mode->vborder;*/ + args.ucH_Border = radeon_crtc->h_border; + args.ucV_Border = radeon_crtc->v_border; if (mode->flags & DRM_MODE_FLAG_NVSYNC) misc |= ATOM_VSYNC_POLARITY; @@ -1176,10 +1170,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, atombios_crtc_set_pll(crtc, adjusted_mode); atombios_enable_ss(crtc); - if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_AVIVO(rdev)) atombios_set_crtc_dtd_timing(crtc, adjusted_mode); - else if (ASIC_IS_AVIVO(rdev)) - atombios_crtc_set_timing(crtc, adjusted_mode); else { atombios_crtc_set_timing(crtc, adjusted_mode); if (radeon_crtc->crtc_id == 0) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 6b9aac7..609eda6 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -312,6 +312,20 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr } } + if (property == rdev->mode_info.underscan_property) { + /* need to find digital encoder on connector */ + encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); + if (!encoder) + return 0; + + radeon_encoder = to_radeon_encoder(encoder); + + if (radeon_encoder->underscan_type != val) { + radeon_encoder->underscan_type = val; + radeon_property_change_mode(&radeon_encoder->base); + } + } + if (property == rdev->mode_info.tv_std_property) { encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC); if (!encoder) { @@ -1120,6 +1134,9 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.coherent_mode_property, 1); + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.underscan_property, + UNDERSCAN_AUTO); if (connector_type == DRM_MODE_CONNECTOR_DVII) { radeon_connector->dac_load_detect = true; drm_connector_attach_property(&radeon_connector->base, @@ -1145,6 +1162,9 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.coherent_mode_property, 1); + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.underscan_property, + UNDERSCAN_AUTO); subpixel_order = SubPixelHorizontalRGB; break; case DRM_MODE_CONNECTOR_DisplayPort: @@ -1176,6 +1196,9 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.coherent_mode_property, 1); + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.underscan_property, + UNDERSCAN_AUTO); break; case DRM_MODE_CONNECTOR_SVIDEO: case DRM_MODE_CONNECTOR_Composite: diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 12a5414..74dac96 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -921,6 +921,12 @@ static struct drm_prop_enum_list radeon_tv_std_enum_list[] = { TV_STD_SECAM, "secam" }, }; +static struct drm_prop_enum_list radeon_underscan_enum_list[] = +{ { UNDERSCAN_OFF, "off" }, + { UNDERSCAN_ON, "on" }, + { UNDERSCAN_AUTO, "auto" }, +}; + static int radeon_modeset_create_props(struct radeon_device *rdev) { int i, sz; @@ -974,6 +980,18 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) radeon_tv_std_enum_list[i].name); } + sz = ARRAY_SIZE(radeon_underscan_enum_list); + rdev->mode_info.underscan_property = + drm_property_create(rdev->ddev, + DRM_MODE_PROP_ENUM, + "underscan", sz); + for (i = 0; i < sz; i++) { + drm_property_add_enum(rdev->mode_info.underscan_property, + i, + radeon_underscan_enum_list[i].type, + radeon_underscan_enum_list[i].name); + } + return 0; } @@ -1069,17 +1087,26 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *adjusted_mode) { struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; struct drm_encoder *encoder; struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_encoder *radeon_encoder; + struct drm_connector *connector; + struct radeon_connector *radeon_connector; bool first = true; u32 src_v = 1, dst_v = 1; u32 src_h = 1, dst_h = 1; + radeon_crtc->h_border = 0; + radeon_crtc->v_border = 0; + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->crtc != crtc) continue; radeon_encoder = to_radeon_encoder(encoder); + connector = radeon_get_connector_for_encoder(encoder); + radeon_connector = to_radeon_connector(connector); + if (first) { /* set scaling */ if (radeon_encoder->rmx_type == RMX_OFF) @@ -1097,6 +1124,20 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, memcpy(&radeon_crtc->native_mode, &radeon_encoder->native_mode, sizeof(struct drm_display_mode)); + + /* fix up for overscan on hdmi */ + if (ASIC_IS_AVIVO(rdev) && + ((radeon_encoder->underscan_type == UNDERSCAN_ON) || + ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && + drm_detect_hdmi_monitor(radeon_connector->edid)))) { + radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; + radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; + radeon_crtc->rmx_type = RMX_FULL; + src_v = crtc->mode.vdisplay; + dst_v = crtc->mode.vdisplay - (radeon_crtc->v_border * 2); + src_h = crtc->mode.hdisplay; + dst_h = crtc->mode.hdisplay - (radeon_crtc->h_border * 2); + } first = false; } else { if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 5e7a053..4a4ff98 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -212,7 +212,7 @@ void radeon_encoder_set_active_device(struct drm_encoder *encoder) } } -static struct drm_connector * +struct drm_connector * radeon_get_connector_for_encoder(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; @@ -1694,6 +1694,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su radeon_encoder->encoder_id = encoder_id; radeon_encoder->devices = supported_device; radeon_encoder->rmx_type = RMX_OFF; + radeon_encoder->underscan_type = UNDERSCAN_OFF; switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_LVDS: @@ -1707,6 +1708,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su } else { drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); + radeon_encoder->underscan_type = UNDERSCAN_AUTO; } drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); break; @@ -1736,6 +1738,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su } else { drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); + radeon_encoder->underscan_type = UNDERSCAN_AUTO; } drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); break; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 95696aa..71aea40 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -66,6 +66,12 @@ enum radeon_tv_std { TV_STD_PAL_N, }; +enum radeon_underscan_type { + UNDERSCAN_OFF, + UNDERSCAN_ON, + UNDERSCAN_AUTO, +}; + enum radeon_hpd_id { RADEON_HPD_1 = 0, RADEON_HPD_2, @@ -226,10 +232,12 @@ struct radeon_mode_info { struct drm_property *coherent_mode_property; /* DAC enable load detect */ struct drm_property *load_detect_property; - /* TV standard load detect */ + /* TV standard */ struct drm_property *tv_std_property; /* legacy TMDS PLL detect */ struct drm_property *tmds_pll_property; + /* underscan */ + struct drm_property *underscan_property; /* hardcoded DFP edid from BIOS */ struct edid *bios_hardcoded_edid; @@ -266,6 +274,8 @@ struct radeon_crtc { uint32_t legacy_display_base_addr; uint32_t legacy_cursor_offset; enum radeon_rmx_type rmx_type; + u8 h_border; + u8 v_border; fixed20_12 vsc; fixed20_12 hsc; struct drm_display_mode native_mode; @@ -354,6 +364,7 @@ struct radeon_encoder { uint32_t flags; uint32_t pixel_clock; enum radeon_rmx_type rmx_type; + enum radeon_underscan_type underscan_type; struct drm_display_mode native_mode; void *enc_priv; int audio_polling_active; @@ -392,7 +403,7 @@ struct radeon_connector { uint32_t connector_id; uint32_t devices; struct radeon_i2c_chan *ddc_bus; - /* some systems have a an hdmi and vga port with a shared ddc line */ + /* some systems have an hdmi and vga port with a shared ddc line */ bool shared_ddc; bool use_digital; /* we need to mind the EDID between detect @@ -414,6 +425,9 @@ radeon_combios_get_tv_info(struct radeon_device *rdev); extern enum radeon_tv_std radeon_atombios_get_tv_info(struct radeon_device *rdev); +extern struct drm_connector * +radeon_get_connector_for_encoder(struct drm_encoder *encoder); + extern void radeon_connector_hotplug(struct drm_connector *connector); extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, -- cgit v0.10.2 From dc77de12dde95c8da39e4c417eb70c7d445cf84b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 4 Aug 2010 11:16:56 +1000 Subject: drm/radeon: tone down overchatty acpi debug messages. On non laptop systems we'll see these the whole time, so make them less important. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index e366434..3f6636b 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c @@ -35,7 +35,7 @@ static int radeon_atif_call(acpi_handle handle) /* Fail only if calling the method fails and ATIF is supported */ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - printk(KERN_INFO "failed to evaluate ATIF got %s\n", acpi_format_exception(status)); + printk(KERN_DEBUG "failed to evaluate ATIF got %s\n", acpi_format_exception(status)); kfree(buffer.pointer); return 1; } diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index e5b7054..ddcd3b1 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -81,7 +81,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) /* Call ACPI methods */ acpi_status = radeon_acpi_init(rdev); if (acpi_status) - dev_err(&dev->pdev->dev, "Error during ACPI methods call\n"); + dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n"); /* Again modeset_init should fail only on fatal error * otherwise it should provide enough functionalities -- cgit v0.10.2 From 3fb688fdc1890f9e8e97597f690c145ab888aec0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Aug 2010 11:09:42 +0100 Subject: drm: Cleanup after failing to create master->unique and dev->name v2: Userspace (notably xf86-video-{intel,ati}) became confused when drmSetInterfaceVersion() started returning -EBUSY as they used a second call (the first done in drmOpen()) to check their master credentials. Since userspace wants to be able to repeatedly call drmSetInterfaceVersion() allow them to do so. v3: Rebase to drm-core-next. Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 76d3d18..7b03b19 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -64,6 +64,19 @@ int drm_getunique(struct drm_device *dev, void *data, return 0; } +static void +drm_unset_busid(struct drm_device *dev, + struct drm_master *master) +{ + kfree(dev->devname); + dev->devname = NULL; + + kfree(master->unique); + master->unique = NULL; + master->unique_len = 0; + master->unique_size = 0; +} + /** * Set the bus id. * @@ -94,17 +107,24 @@ int drm_setunique(struct drm_device *dev, void *data, master->unique_len = u->unique_len; master->unique_size = u->unique_len + 1; master->unique = kmalloc(master->unique_size, GFP_KERNEL); - if (!master->unique) - return -ENOMEM; - if (copy_from_user(master->unique, u->unique, master->unique_len)) - return -EFAULT; + if (!master->unique) { + ret = -ENOMEM; + goto err; + } + + if (copy_from_user(master->unique, u->unique, master->unique_len)) { + ret = -EFAULT; + goto err; + } master->unique[master->unique_len] = '\0'; dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) + strlen(master->unique) + 2, GFP_KERNEL); - if (!dev->devname) - return -ENOMEM; + if (!dev->devname) { + ret = -ENOMEM; + goto err; + } sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, master->unique); @@ -113,24 +133,36 @@ int drm_setunique(struct drm_device *dev, void *data, * busid. */ ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func); - if (ret != 3) - return -EINVAL; + if (ret != 3) { + ret = -EINVAL; + goto err; + } + domain = bus >> 8; bus &= 0xff; if ((domain != drm_get_pci_domain(dev)) || (bus != dev->pdev->bus->number) || (slot != PCI_SLOT(dev->pdev->devfn)) || - (func != PCI_FUNC(dev->pdev->devfn))) - return -EINVAL; + (func != PCI_FUNC(dev->pdev->devfn))) { + ret = -EINVAL; + goto err; + } return 0; + +err: + drm_unset_busid(dev, master); + return ret; } static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) { struct drm_master *master = file_priv->master; - int len; + int len, ret; + + if (master->unique != NULL) + drm_unset_busid(dev, master); if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) { master->unique_len = 10 + strlen(dev->platformdev->name); @@ -142,15 +174,20 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) len = snprintf(master->unique, master->unique_len, "platform:%s", dev->platformdev->name); - if (len > master->unique_len) + if (len > master->unique_len) { DRM_ERROR("Unique buffer overflowed\n"); + ret = -EINVAL; + goto err; + } dev->devname = kmalloc(strlen(dev->platformdev->name) + master->unique_len + 2, GFP_KERNEL); - if (dev->devname == NULL) - return -ENOMEM; + if (dev->devname == NULL) { + ret = -ENOMEM; + goto err; + } sprintf(dev->devname, "%s@%s", dev->platformdev->name, master->unique); @@ -168,23 +205,31 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) dev->pdev->bus->number, PCI_SLOT(dev->pdev->devfn), PCI_FUNC(dev->pdev->devfn)); - if (len >= master->unique_len) + if (len >= master->unique_len) { DRM_ERROR("buffer overflow"); - else + ret = -EINVAL; + goto err; + } else master->unique_len = len; dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) + master->unique_len + 2, GFP_KERNEL); - if (dev->devname == NULL) - return -ENOMEM; + if (dev->devname == NULL) { + ret = -ENOMEM; + goto err; + } sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, master->unique); } return 0; + +err: + drm_unset_busid(dev, master); + return ret; } /** @@ -348,7 +393,9 @@ int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_pri /* * Version 1.1 includes tying of DRM to specific device */ - drm_set_busid(dev, file_priv); + retcode = drm_set_busid(dev, file_priv); + if (retcode) + goto done; } } -- cgit v0.10.2 From 1297c05a8dfb568c689f057d51a65eebe5ddc86f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 4 Aug 2010 11:40:00 -0400 Subject: drm/radeon: add new pci ids New evergreen and r7xx ids. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 2d428b0..3a9940e 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -146,6 +146,8 @@ {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x688A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x688C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x688D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6898, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6899, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x689c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HEMLOCK|RADEON_NEW_MEMMAP}, \ @@ -161,6 +163,7 @@ {0x1002, 0x68be, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68c7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ @@ -174,6 +177,7 @@ {0x1002, 0x68e8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68e9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68f1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68f8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68f9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68fe, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ @@ -314,6 +318,7 @@ {0x1002, 0x9456, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ {0x1002, 0x945A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x945B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x945E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ {0x1002, 0x946A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ @@ -324,6 +329,7 @@ {0x1002, 0x9487, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9488, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9489, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x948A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x948F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9490, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9491, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ @@ -366,6 +372,7 @@ {0x1002, 0x9553, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9555, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9557, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x955f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9581, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x9583, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ -- cgit v0.10.2 From 430f70d59da643f1aa7c9cf3493423a76550b110 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 4 Aug 2010 03:45:04 -0400 Subject: drm/radeon/kms: only expose underscan on avivo chips R4xx also uses the atom add connector function, but underscan is only supported on avivo chips. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 609eda6..2395c86 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1134,9 +1134,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.coherent_mode_property, 1); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_property, - UNDERSCAN_AUTO); + if (ASIC_IS_AVIVO(rdev)) + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.underscan_property, + UNDERSCAN_AUTO); if (connector_type == DRM_MODE_CONNECTOR_DVII) { radeon_connector->dac_load_detect = true; drm_connector_attach_property(&radeon_connector->base, @@ -1162,9 +1163,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.coherent_mode_property, 1); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_property, - UNDERSCAN_AUTO); + if (ASIC_IS_AVIVO(rdev)) + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.underscan_property, + UNDERSCAN_AUTO); subpixel_order = SubPixelHorizontalRGB; break; case DRM_MODE_CONNECTOR_DisplayPort: @@ -1196,9 +1198,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_attach_property(&radeon_connector->base, rdev->mode_info.coherent_mode_property, 1); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_property, - UNDERSCAN_AUTO); + if (ASIC_IS_AVIVO(rdev)) + drm_connector_attach_property(&radeon_connector->base, + rdev->mode_info.underscan_property, + UNDERSCAN_AUTO); break; case DRM_MODE_CONNECTOR_SVIDEO: case DRM_MODE_CONNECTOR_Composite: diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 4a4ff98..263c809 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1708,7 +1708,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su } else { drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); - radeon_encoder->underscan_type = UNDERSCAN_AUTO; + if (ASIC_IS_AVIVO(rdev)) + radeon_encoder->underscan_type = UNDERSCAN_AUTO; } drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); break; @@ -1738,7 +1739,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su } else { drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); - radeon_encoder->underscan_type = UNDERSCAN_AUTO; + if (ASIC_IS_AVIVO(rdev)) + radeon_encoder->underscan_type = UNDERSCAN_AUTO; } drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); break; -- cgit v0.10.2 From fca3ec01e0b40cab82cac7745e154b01969e6219 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Aug 2010 14:34:24 +0100 Subject: drm,io-mapping: Specify slot to use for atomic mappings This is required should we ever attempt to use an io-mapping where KM_USER0 is verboten, such as inside an IRQ context. Signed-off-by: Chris Wilson Cc: Eric Anholt Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4efd4fd..2a4ed7c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -496,10 +496,10 @@ fast_user_write(struct io_mapping *mapping, char *vaddr_atomic; unsigned long unwritten; - vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base); + vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base, KM_USER0); unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset, user_data, length); - io_mapping_unmap_atomic(vaddr_atomic); + io_mapping_unmap_atomic(vaddr_atomic, KM_USER0); if (unwritten) return -EFAULT; return 0; @@ -3487,7 +3487,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, reloc_offset = obj_priv->gtt_offset + reloc->offset; reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, (reloc_offset & - ~(PAGE_SIZE - 1))); + ~(PAGE_SIZE - 1)), + KM_USER0); reloc_entry = (uint32_t __iomem *)(reloc_page + (reloc_offset & (PAGE_SIZE - 1))); reloc_val = target_obj_priv->gtt_offset + reloc->delta; @@ -3498,7 +3499,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, readl(reloc_entry), reloc_val); #endif writel(reloc_val, reloc_entry); - io_mapping_unmap_atomic(reloc_page); + io_mapping_unmap_atomic(reloc_page, KM_USER0); /* The updated presumed offset for this entry will be * copied back out to the user. diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index f26ec2f..d39aea2 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -185,7 +185,8 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over if (OVERLAY_NONPHYSICAL(overlay->dev)) { regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, - overlay->reg_bo->gtt_offset); + overlay->reg_bo->gtt_offset, + KM_USER0); if (!regs) { DRM_ERROR("failed to map overlay regs in GTT\n"); @@ -200,7 +201,7 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) { if (OVERLAY_NONPHYSICAL(overlay->dev)) - io_mapping_unmap_atomic(overlay->virt_addr); + io_mapping_unmap_atomic(overlay->virt_addr, KM_USER0); overlay->virt_addr = NULL; diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index b59f348..7369b5e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -2083,11 +2083,11 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb, uint32_t val = 0; if (off < pci_resource_len(dev->pdev, 1)) { - uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off); + uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0); val = ioread32(p); - io_mapping_unmap_atomic(p); + io_mapping_unmap_atomic(p, KM_USER0); } return val; @@ -2098,12 +2098,12 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb, uint32_t off, uint32_t val) { if (off < pci_resource_len(dev->pdev, 1)) { - uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off); + uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off, KM_USER0); iowrite32(val, p); wmb(); - io_mapping_unmap_atomic(p); + io_mapping_unmap_atomic(p, KM_USER0); } } diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index 25085dd..e0ea40f 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -79,7 +79,9 @@ io_mapping_free(struct io_mapping *mapping) /* Atomic map/unmap */ static inline void * -io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) +io_mapping_map_atomic_wc(struct io_mapping *mapping, + unsigned long offset, + int slot) { resource_size_t phys_addr; unsigned long pfn; @@ -87,13 +89,13 @@ io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) BUG_ON(offset >= mapping->size); phys_addr = mapping->base + offset; pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); - return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot); + return iomap_atomic_prot_pfn(pfn, slot, mapping->prot); } static inline void -io_mapping_unmap_atomic(void *vaddr) +io_mapping_unmap_atomic(void *vaddr, int slot) { - iounmap_atomic(vaddr, KM_USER0); + iounmap_atomic(vaddr, slot); } static inline void * @@ -133,13 +135,15 @@ io_mapping_free(struct io_mapping *mapping) /* Atomic map/unmap */ static inline void * -io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) +io_mapping_map_atomic_wc(struct io_mapping *mapping, + unsigned long offset, + int slot) { return ((char *) mapping) + offset; } static inline void -io_mapping_unmap_atomic(void *vaddr) +io_mapping_unmap_atomic(void *vaddr, int slot) { } -- cgit v0.10.2 From a1e09b62592eb57e25f8d076ffa5b7bef18be812 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 22 Jul 2010 17:07:38 +0200 Subject: drm/kms: Simplify setup of the initial I2C encoder config. In most use cases the driver will be using the same static config all the time: interpreting i2c_board_info::platform_data as the default config we can can save the GPU driver a redundant set_config() call. Signed-off-by: Francisco Jerez Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c index f018469..d62c064 100644 --- a/drivers/gpu/drm/drm_encoder_slave.c +++ b/drivers/gpu/drm/drm_encoder_slave.c @@ -41,6 +41,9 @@ * &drm_encoder_slave. The @slave_funcs field will be initialized with * the hooks provided by the slave driver. * + * If @info->platform_data is non-NULL it will be used as the initial + * slave config. + * * Returns 0 on success or a negative errno on failure, in particular, * -ENODEV is returned when no matching driver is found. */ @@ -85,6 +88,10 @@ int drm_i2c_encoder_init(struct drm_device *dev, if (err) goto fail_unregister; + if (info->platform_data) + encoder->slave_funcs->set_config(&encoder->base, + info->platform_data); + return 0; fail_unregister: -- cgit v0.10.2 From 58374713c9dfb4d231f8c56cac089f6fbdedc2ec Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 10 Jul 2010 23:51:39 +0200 Subject: drm: kill BKL from common code This restricts the use of the big kernel lock to the i830 and i810 device drivers. The three remaining users in common code (open, ioctl and release) get converted to a new mutex, the drm_global_mutex, making the locking stricter than the big kernel lock. This may have a performance impact, but only in those cases that currently don't use DRM_UNLOCKED flag in the ioctl list and would benefit from that anyway. The reason why i810 and i830 cannot use drm_global_mutex in their mmap functions is a lock-order inversion problem between the current use of the BKL and mmap_sem in these drivers. Since the BKL has release-on-sleep semantics, it's harmless but it would cause trouble if we replace the BKL with a mutex. Instead, these drivers get their own ioctl wrappers that take the BKL around every ioctl call and then set their own handlers as DRM_UNLOCKED. Signed-off-by: Arnd Bergmann Cc: David Airlie Cc: dri-devel@lists.freedesktop.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index d5b349d..90288ec 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -481,9 +481,9 @@ long drm_ioctl(struct file *filp, if (ioctl->flags & DRM_UNLOCKED) retcode = func(dev, kdata, file_priv); else { - lock_kernel(); + mutex_lock(&drm_global_mutex); retcode = func(dev, kdata, file_priv); - unlock_kernel(); + mutex_unlock(&drm_global_mutex); } if (cmd & IOC_OUT) { diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index e7aace2..2ca8df8 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -39,6 +39,9 @@ #include #include +/* from BKL pushdown: note that nothing else serializes idr_find() */ +DEFINE_MUTEX(drm_global_mutex); + static int drm_open_helper(struct inode *inode, struct file *filp, struct drm_device * dev); @@ -175,8 +178,7 @@ int drm_stub_open(struct inode *inode, struct file *filp) DRM_DEBUG("\n"); - /* BKL pushdown: note that nothing else serializes idr_find() */ - lock_kernel(); + mutex_lock(&drm_global_mutex); minor = idr_find(&drm_minors_idr, minor_id); if (!minor) goto out; @@ -197,7 +199,7 @@ int drm_stub_open(struct inode *inode, struct file *filp) fops_put(old_fops); out: - unlock_kernel(); + mutex_unlock(&drm_global_mutex); return err; } @@ -472,7 +474,7 @@ int drm_release(struct inode *inode, struct file *filp) struct drm_device *dev = file_priv->minor->dev; int retcode = 0; - lock_kernel(); + mutex_lock(&drm_global_mutex); DRM_DEBUG("open_count = %d\n", dev->open_count); @@ -573,17 +575,14 @@ int drm_release(struct inode *inode, struct file *filp) if (atomic_read(&dev->ioctl_count)) { DRM_ERROR("Device busy: %d\n", atomic_read(&dev->ioctl_count)); - spin_unlock(&dev->count_lock); - unlock_kernel(); - return -EBUSY; + retcode = -EBUSY; + goto out; } - spin_unlock(&dev->count_lock); - unlock_kernel(); - return drm_lastclose(dev); + retcode = drm_lastclose(dev); } +out: spin_unlock(&dev->count_lock); - - unlock_kernel(); + mutex_unlock(&drm_global_mutex); return retcode; } diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 09c86ed..0e6c131 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -37,6 +37,7 @@ #include /* For task queue support */ #include #include +#include #include #define I810_BUF_FREE 2 @@ -1240,22 +1241,35 @@ int i810_driver_dma_quiescent(struct drm_device *dev) return 0; } +/* + * call the drm_ioctl under the big kernel lock because + * to lock against the i810_mmap_buffers function. + */ +long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + lock_kernel(); + ret = drm_ioctl(file, cmd, arg); + unlock_kernel(); + return ret; +} + struct drm_ioctl_desc i810_ioctls[] = { - DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH) + DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), }; int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index c1e0275..b4250b2 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c @@ -59,7 +59,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .unlocked_ioctl = drm_ioctl, + .unlocked_ioctl = i810_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h index 0743fe9..c9339f4 100644 --- a/drivers/gpu/drm/i810/i810_drv.h +++ b/drivers/gpu/drm/i810/i810_drv.h @@ -126,6 +126,7 @@ extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv); extern int i810_driver_device_is_agp(struct drm_device *dev); +extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); extern struct drm_ioctl_desc i810_ioctls[]; extern int i810_max_ioctl; diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 7ee85ea..5168862 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c @@ -36,6 +36,7 @@ #include "i830_drm.h" #include "i830_drv.h" #include /* For task queue support */ +#include #include #include #include @@ -1509,21 +1510,34 @@ int i830_driver_dma_quiescent(struct drm_device *dev) return 0; } +/* + * call the drm_ioctl under the big kernel lock because + * to lock against the i830_mmap_buffers function. + */ +long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + lock_kernel(); + ret = drm_ioctl(file, cmd, arg); + unlock_kernel(); + return ret; +} + struct drm_ioctl_desc i830_ioctls[] = { - DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH) + DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), }; int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); diff --git a/drivers/gpu/drm/i830/i830_drv.c b/drivers/gpu/drm/i830/i830_drv.c index 44f990b..a5c66aa 100644 --- a/drivers/gpu/drm/i830/i830_drv.c +++ b/drivers/gpu/drm/i830/i830_drv.c @@ -70,7 +70,7 @@ static struct drm_driver driver = { .owner = THIS_MODULE, .open = drm_open, .release = drm_release, - .unlocked_ioctl = drm_ioctl, + .unlocked_ioctl = i830_ioctl, .mmap = drm_mmap, .poll = drm_poll, .fasync = drm_fasync, diff --git a/drivers/gpu/drm/i830/i830_drv.h b/drivers/gpu/drm/i830/i830_drv.h index ecfd25a..0df1c72 100644 --- a/drivers/gpu/drm/i830/i830_drv.h +++ b/drivers/gpu/drm/i830/i830_drv.h @@ -122,6 +122,7 @@ typedef struct drm_i830_private { } drm_i830_private_t; +long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg); extern struct drm_ioctl_desc i830_ioctls[]; extern int i830_max_ioctl; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 53017ba..e2a4da7 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -52,7 +52,6 @@ #include #include #include -#include /* For (un)lock_kernel */ #include #include #include @@ -1152,6 +1151,7 @@ extern long drm_compat_ioctl(struct file *filp, extern int drm_lastclose(struct drm_device *dev); /* Device support (drm_fops.h) */ +extern struct mutex drm_global_mutex; extern int drm_open(struct inode *inode, struct file *filp); extern int drm_stub_open(struct inode *inode, struct file *filp); extern int drm_fasync(int fd, struct file *filp, int on); -- cgit v0.10.2 From 46cfc58a77de5fc8385ad87077f4dc14633e57a7 Mon Sep 17 00:00:00 2001 From: Kulikov Vasiliy Date: Tue, 3 Aug 2010 19:42:30 +0400 Subject: agp: efficeon-agp: do not use PCI resources before pci_enable_device() IRQ and resource[] may not have correct values until after PCI hotplug setup occurs at pci_enable_device() time. The semantic match that finds this problem is as follows: // @@ identifier x; identifier request ~= "pci_request.*|pci_resource.*"; @@ ( * x->irq | * x->resource | * request(x, ...) ) ... *pci_enable_device(x) // Signed-off-by: Kulikov Vasiliy Signed-off-by: Dave Airlie diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index aa109cb..d607f53 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -372,6 +372,17 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, bridge->capndx = cap_ptr; /* + * If the device has not been properly setup, the following will catch + * the problem and should stop the system from crashing. + * 20030610 - hamish@zot.org + */ + if (pci_enable_device(pdev)) { + printk(KERN_ERR PFX "Unable to Enable PCI device\n"); + agp_put_bridge(bridge); + return -ENODEV; + } + + /* * The following fixes the case where the BIOS has "forgotten" to * provide an address range for the GART. * 20030610 - hamish@zot.org @@ -385,17 +396,6 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, } } - /* - * If the device has not been properly setup, the following will catch - * the problem and should stop the system from crashing. - * 20030610 - hamish@zot.org - */ - if (pci_enable_device(pdev)) { - printk(KERN_ERR PFX "Unable to Enable PCI device\n"); - agp_put_bridge(bridge); - return -ENODEV; - } - /* Fill in the mode register */ if (cap_ptr) { pci_read_config_dword(pdev, -- cgit v0.10.2 From 96576a9e1a0cdb8a43d3af5846be0948f52b4460 Mon Sep 17 00:00:00 2001 From: Kulikov Vasiliy Date: Tue, 3 Aug 2010 19:42:34 +0400 Subject: agp: intel-agp: do not use PCI resources before pci_enable_device() IRQ and resource[] may not have correct values until after PCI hotplug setup occurs at pci_enable_device() time. The semantic match that finds this problem is as follows: // @@ identifier x; identifier request ~= "pci_request.*|pci_resource.*"; @@ ( * x->irq | * x->resource | * request(x, ...) ) ... *pci_enable_device(x) // Signed-off-by: Kulikov Vasiliy Signed-off-by: Dave Airlie diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 5bbc7be..ddf5def 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -908,6 +908,17 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); /* + * If the device has not been properly setup, the following will catch + * the problem and should stop the system from crashing. + * 20030610 - hamish@zot.org + */ + if (pci_enable_device(pdev)) { + dev_err(&pdev->dev, "can't enable PCI device\n"); + agp_put_bridge(bridge); + return -ENODEV; + } + + /* * The following fixes the case where the BIOS has "forgotten" to * provide an address range for the GART. * 20030610 - hamish@zot.org @@ -921,17 +932,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, } } - /* - * If the device has not been properly setup, the following will catch - * the problem and should stop the system from crashing. - * 20030610 - hamish@zot.org - */ - if (pci_enable_device(pdev)) { - dev_err(&pdev->dev, "can't enable PCI device\n"); - agp_put_bridge(bridge); - return -ENODEV; - } - /* Fill in the mode register */ if (cap_ptr) { pci_read_config_dword(pdev, -- cgit v0.10.2