Merge remote branch 'nouveau/for-airlied' of /ssd/git/drm-nouveau-next into drm-core-next

* 'nouveau/for-airlied' of /ssd/git/drm-nouveau-next:
  drm/nouveau: fix earlier mistake when fixing merge conflict
  drm/nvc0: fix thinko in instmem suspend/resume
  drm/nouveau: Workaround missing GPIO tables on an Apple iMac G4 NV18.
  drm/nouveau: Add TV-out quirk for an MSI nForce2 IGP.
  drm/nv50-nvc0: ramht_size is meant to be in bytes, not entries
  drm/nouveau: punt some more log messages to debug level
  drm/nouveau: remove warning about unknown tmds table revisions
  drm/nouveau: check for error when allocating/mapping dummy page
  drm/nouveau: fix race condition when under memory pressure
  drm/nv50: fix minor thinko from nvc0 changes
  drm/nouveau: Don't try DDC on the dummy I2C channel.
This commit is contained in:
Dave Airlie 2010-08-23 08:34:59 +10:00
commit d03330383c
10 changed files with 103 additions and 34 deletions

View File

@ -2166,7 +2166,7 @@ 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 =
uint8_t __iomem *p =
io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0);
val = ioread32(p + (off & ~PAGE_MASK));
@ -2182,7 +2182,7 @@ 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 =
uint8_t __iomem *p =
io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0);
iowrite32(val, p + (off & ~PAGE_MASK));
@ -4587,7 +4587,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
NV_TRACE(dev, "0x%04X: parsing output script 0\n", script);
NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
} else
if (pxclk == -1) {
@ -4597,7 +4597,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
NV_TRACE(dev, "0x%04X: parsing output script 1\n", script);
NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
} else
if (pxclk == -2) {
@ -4610,7 +4610,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
NV_TRACE(dev, "0x%04X: parsing output script 2\n", script);
NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
} else
if (pxclk > 0) {
@ -4622,7 +4622,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script);
NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
} else
if (pxclk < 0) {
@ -4634,7 +4634,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
return 1;
}
NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script);
NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script);
nouveau_bios_run_init_table(dev, script, dcbent);
}
@ -5357,19 +5357,17 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios,
}
tmdstableptr = ROM16(bios->data[bitentry->offset]);
if (tmdstableptr == 0x0) {
if (!tmdstableptr) {
NV_ERROR(dev, "Pointer to TMDS table invalid\n");
return -EINVAL;
}
NV_INFO(dev, "TMDS table version %d.%d\n",
bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf);
/* nv50+ has v2.0, but we don't parse it atm */
if (bios->data[tmdstableptr] != 0x11) {
NV_WARN(dev,
"TMDS table revision %d.%d not currently supported\n",
bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf);
if (bios->data[tmdstableptr] != 0x11)
return -ENOSYS;
}
/*
* These two scripts are odd: they don't seem to get run even when
@ -5809,6 +5807,22 @@ parse_dcb_gpio_table(struct nvbios *bios)
gpio->line = tvdac_gpio[1] >> 4;
gpio->invert = tvdac_gpio[0] & 2;
}
} else {
/*
* No systematic way to store GPIO info on pre-v2.2
* DCBs, try to match the PCI device IDs.
*/
/* Apple iMac G4 NV18 */
if (dev->pdev->device == 0x0189 &&
dev->pdev->subsystem_vendor == 0x10de &&
dev->pdev->subsystem_device == 0x0010) {
struct dcb_gpio_entry *gpio = new_gpio_entry(bios);
gpio->tag = DCB_GPIO_TVDAC0;
gpio->line = 4;
}
}
if (!gpio_table_ptr)

View File

@ -36,6 +36,21 @@
#include <linux/log2.h>
#include <linux/slab.h>
int
nouveau_bo_sync_gpu(struct nouveau_bo *nvbo, struct nouveau_channel *chan)
{
struct nouveau_fence *prev_fence = nvbo->bo.sync_obj;
int ret;
if (!prev_fence || nouveau_fence_channel(prev_fence) == chan)
return 0;
spin_lock(&nvbo->bo.lock);
ret = ttm_bo_wait(&nvbo->bo, false, false, false);
spin_unlock(&nvbo->bo.lock);
return ret;
}
static void
nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
{

View File

@ -104,7 +104,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
int i;
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
struct nouveau_i2c_chan *i2c;
struct nouveau_i2c_chan *i2c = NULL;
struct nouveau_encoder *nv_encoder;
struct drm_mode_object *obj;
int id;
@ -117,7 +117,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 && nouveau_probe_i2c_addr(i2c, 0x50)) {
*pnv_encoder = nv_encoder;

View File

@ -1165,6 +1165,7 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val);
extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *);
/* nouveau_fence.c */
struct nouveau_fence;

View File

@ -361,16 +361,11 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
list_for_each_entry(nvbo, list, entry) {
struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
struct nouveau_fence *prev_fence = nvbo->bo.sync_obj;
if (prev_fence && nouveau_fence_channel(prev_fence) != chan) {
spin_lock(&nvbo->bo.lock);
ret = ttm_bo_wait(&nvbo->bo, false, false, false);
spin_unlock(&nvbo->bo.lock);
if (unlikely(ret)) {
NV_ERROR(dev, "fail wait other chan\n");
return ret;
}
ret = nouveau_bo_sync_gpu(nvbo, chan);
if (unlikely(ret)) {
NV_ERROR(dev, "fail pre-validate sync\n");
return ret;
}
ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains,
@ -381,7 +376,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
return ret;
}
nvbo->channel = chan;
nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan;
ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement,
false, false, false);
nvbo->channel = NULL;
@ -390,6 +385,12 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
return ret;
}
ret = nouveau_bo_sync_gpu(nvbo, chan);
if (unlikely(ret)) {
NV_ERROR(dev, "fail post-validate sync\n");
return ret;
}
if (nvbo->bo.offset == b->presumed.offset &&
((nvbo->bo.mem.mem_type == TTM_PL_VRAM &&
b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) ||
@ -615,6 +616,21 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
mutex_lock(&dev->struct_mutex);
/* Mark push buffers as being used on PFIFO, the validation code
* will then make sure that if the pushbuf bo moves, that they
* happen on the kernel channel, which will in turn cause a sync
* to happen before we try and submit the push buffer.
*/
for (i = 0; i < req->nr_push; i++) {
if (push[i].bo_index >= req->nr_buffers) {
NV_ERROR(dev, "push %d buffer not in list\n", i);
ret = -EINVAL;
goto out;
}
bo[push[i].bo_index].read_domains |= (1 << 31);
}
/* Validate buffer list */
ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers,
req->nr_buffers, &op, &do_reloc);

View File

@ -163,7 +163,7 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
if (entry->chan)
return -EEXIST;
if (dev_priv->card_type == NV_C0 && entry->read >= NV50_I2C_PORTS) {
if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) {
NV_ERROR(dev, "unknown i2c port %d\n", entry->read);
return -EINVAL;
}

View File

@ -214,6 +214,7 @@ int
nouveau_sgdma_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct pci_dev *pdev = dev->pdev;
struct nouveau_gpuobj *gpuobj = NULL;
uint32_t aper_size, obj_size;
int i, ret;
@ -239,10 +240,19 @@ nouveau_sgdma_init(struct drm_device *dev)
dev_priv->gart_info.sg_dummy_page =
alloc_page(GFP_KERNEL|__GFP_DMA32);
if (!dev_priv->gart_info.sg_dummy_page) {
nouveau_gpuobj_del(dev, &gpuobj);
return -ENOMEM;
}
set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags);
dev_priv->gart_info.sg_dummy_bus =
pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0,
pci_map_page(pdev, dev_priv->gart_info.sg_dummy_page, 0,
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
if (pci_dma_mapping_error(pdev, dev_priv->gart_info.sg_dummy_bus)) {
nouveau_gpuobj_del(dev, &gpuobj);
return -EFAULT;
}
if (dev_priv->card_type < NV_50) {
/* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and

View File

@ -129,6 +129,14 @@ get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask)
return false;
}
/* MSI nForce2 IGP */
if (dev->pdev->device == 0x01f0 &&
dev->pdev->subsystem_vendor == 0x1462 &&
dev->pdev->subsystem_device == 0x5710) {
*pin_mask = 0xc;
return false;
}
return true;
}

View File

@ -278,7 +278,7 @@ nv50_instmem_init(struct drm_device *dev)
/*XXX: incorrect, but needed to make hash func "work" */
dev_priv->ramht_offset = 0x10000;
dev_priv->ramht_bits = 9;
dev_priv->ramht_size = (1 << dev_priv->ramht_bits);
dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8;
return 0;
}

View File

@ -142,14 +142,16 @@ int
nvc0_instmem_suspend(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
u32 *buf;
int i;
dev_priv->susres.ramin_copy = vmalloc(65536);
if (!dev_priv->susres.ramin_copy)
return -ENOMEM;
buf = dev_priv->susres.ramin_copy;
for (i = 0x700000; i < 0x710000; i += 4)
dev_priv->susres.ramin_copy[i/4] = nv_rd32(dev, i);
for (i = 0; i < 65536; i += 4)
buf[i/4] = nv_rd32(dev, NV04_PRAMIN + i);
return 0;
}
@ -157,14 +159,15 @@ void
nvc0_instmem_resume(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
u32 *buf = dev_priv->susres.ramin_copy;
u64 chan;
int i;
chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram;
nv_wr32(dev, 0x001700, chan >> 16);
for (i = 0x700000; i < 0x710000; i += 4)
nv_wr32(dev, i, dev_priv->susres.ramin_copy[i/4]);
for (i = 0; i < 65536; i += 4)
nv_wr32(dev, NV04_PRAMIN + i, buf[i/4]);
vfree(dev_priv->susres.ramin_copy);
dev_priv->susres.ramin_copy = NULL;
@ -221,7 +224,7 @@ nvc0_instmem_init(struct drm_device *dev)
/*XXX: incorrect, but needed to make hash func "work" */
dev_priv->ramht_offset = 0x10000;
dev_priv->ramht_bits = 9;
dev_priv->ramht_size = (1 << dev_priv->ramht_bits);
dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8;
return 0;
}