Merge branch 'drm-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (33 commits) drm/radeon/kms: fix typo in radeon_compute_pll_gain drm/radeon/kms: try to detect tv vs monitor for underscan drm/radeon/kms: fix sideport detection on newer rs880 boards drm/radeon: fix passing wrong type to gem object create. drm/radeon/kms: set encoder type to DVI for HDMI on evergreen drm/radeon/kms: add back missing break in info ioctl drm/radeon/kms: don't enable MSIs on AGP boards drm/radeon/kms: fix agp mode setup on cards that use pcie bridges drm: move dereference below check drm: fix end of loop test drm/radeon/kms: rework radeon_dp_detect() logic drm/radeon/kms: add missing asic callback assignment for evergreen drm/radeon/kms/DCE3+: switch pads to ddc mode when going i2c drm/radeon/kms/pm: bail early if nothing's changing drm/radeon/kms/atom: clean up dig atom handling drm/radeon/kms: DCE3/4 transmitter fixes drm/radeon/kms: rework encoder handling drm/radeon/kms: DCE3/4 AdjustPixelPll updates drm/radeon: Fix stack data leak drm/radeon/kms: fix GTT/VRAM overlapping test ...
This commit is contained in:
@@ -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)
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -426,18 +426,18 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
|
||||
***********************************/
|
||||
|
||||
struct drm_ioctl_desc nouveau_ioctls[] = {
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH),
|
||||
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH),
|
||||
};
|
||||
|
||||
int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user