提交 7b98040a 编写于 作者: D Dave Airlie

Merge branch 'linux-4.3' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-fixes

Nothing too crazy here, a couple of regression fixes + runpm/fbcon
race fix.

* 'linux-4.3' of git://anongit.freedesktop.org/git/nouveau/linux-2.6:
  drm/nouveau/bios: fix OF loading
  drm/nouveau/fbcon: take runpm reference when userspace has an open fd
  drm/nouveau/nouveau: Disable AGP for SiS 761
  drm/nouveau/display: allow up to 16k width/height for fermi+
  drm/nouveau/bios: translate devinit pri/sec i2c bus to internal identifiers
......@@ -469,9 +469,13 @@ nouveau_display_create(struct drm_device *dev)
if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
dev->mode_config.max_width = 4096;
dev->mode_config.max_height = 4096;
} else {
} else
if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) {
dev->mode_config.max_width = 8192;
dev->mode_config.max_height = 8192;
} else {
dev->mode_config.max_width = 16384;
dev->mode_config.max_height = 16384;
}
dev->mode_config.preferred_depth = 24;
......
......@@ -178,8 +178,30 @@ nouveau_fbcon_sync(struct fb_info *info)
return 0;
}
static int
nouveau_fbcon_open(struct fb_info *info, int user)
{
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
int ret = pm_runtime_get_sync(drm->dev->dev);
if (ret < 0 && ret != -EACCES)
return ret;
return 0;
}
static int
nouveau_fbcon_release(struct fb_info *info, int user)
{
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
pm_runtime_put(drm->dev->dev);
return 0;
}
static struct fb_ops nouveau_fbcon_ops = {
.owner = THIS_MODULE,
.fb_open = nouveau_fbcon_open,
.fb_release = nouveau_fbcon_release,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_fillrect = nouveau_fbcon_fillrect,
......@@ -195,6 +217,8 @@ static struct fb_ops nouveau_fbcon_ops = {
static struct fb_ops nouveau_fbcon_sw_ops = {
.owner = THIS_MODULE,
.fb_open = nouveau_fbcon_open,
.fb_release = nouveau_fbcon_release,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_fillrect = drm_fb_helper_cfb_fillrect,
......
......@@ -267,6 +267,12 @@ init_i2c(struct nvbios_init *init, int index)
index = NVKM_I2C_BUS_PRI;
if (init->outp && init->outp->i2c_upper_default)
index = NVKM_I2C_BUS_SEC;
} else
if (index == 0x80) {
index = NVKM_I2C_BUS_PRI;
} else
if (index == 0x81) {
index = NVKM_I2C_BUS_SEC;
}
bus = nvkm_i2c_bus_find(i2c, index);
......
......@@ -8,7 +8,10 @@ struct nvbios_source {
void *(*init)(struct nvkm_bios *, const char *);
void (*fini)(void *);
u32 (*read)(void *, u32 offset, u32 length, struct nvkm_bios *);
u32 (*size)(void *);
bool rw;
bool ignore_checksum;
bool no_pcir;
};
int nvbios_extend(struct nvkm_bios *, u32 length);
......
......@@ -45,7 +45,7 @@ shadow_fetch(struct nvkm_bios *bios, struct shadow *mthd, u32 upto)
u32 read = mthd->func->read(data, start, limit - start, bios);
bios->size = start + read;
}
return bios->size >= limit;
return bios->size >= upto;
}
static int
......@@ -55,14 +55,22 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
struct nvbios_image image;
int score = 1;
if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
nvkm_debug(subdev, "%08x: header fetch failed\n", offset);
return 0;
}
if (mthd->func->no_pcir) {
image.base = 0;
image.type = 0;
image.size = mthd->func->size(mthd->data);
image.last = 1;
} else {
if (!shadow_fetch(bios, mthd, offset + 0x1000)) {
nvkm_debug(subdev, "%08x: header fetch failed\n",
offset);
return 0;
}
if (!nvbios_image(bios, idx, &image)) {
nvkm_debug(subdev, "image %d invalid\n", idx);
return 0;
if (!nvbios_image(bios, idx, &image)) {
nvkm_debug(subdev, "image %d invalid\n", idx);
return 0;
}
}
nvkm_debug(subdev, "%08x: type %02x, %d bytes\n",
image.base, image.type, image.size);
......@@ -74,7 +82,8 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
switch (image.type) {
case 0x00:
if (nvbios_checksum(&bios->data[image.base], image.size)) {
if (!mthd->func->ignore_checksum &&
nvbios_checksum(&bios->data[image.base], image.size)) {
nvkm_debug(subdev, "%08x: checksum failed\n",
image.base);
if (mthd->func->rw)
......
......@@ -21,6 +21,7 @@
*
*/
#include "priv.h"
#include <core/pci.h>
#if defined(__powerpc__)
......@@ -33,17 +34,26 @@ static u32
of_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
{
struct priv *priv = data;
if (offset + length <= priv->size) {
if (offset < priv->size) {
length = min_t(u32, length, priv->size - offset);
memcpy_fromio(bios->data + offset, priv->data + offset, length);
return length;
}
return 0;
}
static u32
of_size(void *data)
{
struct priv *priv = data;
return priv->size;
}
static void *
of_init(struct nvkm_bios *bios, const char *name)
{
struct pci_dev *pdev = bios->subdev.device->func->pci(bios->subdev.device)->pdev;
struct nvkm_device *device = bios->subdev.device;
struct pci_dev *pdev = device->func->pci(device)->pdev;
struct device_node *dn;
struct priv *priv;
if (!(dn = pci_device_to_OF_node(pdev)))
......@@ -62,7 +72,10 @@ nvbios_of = {
.init = of_init,
.fini = (void(*)(void *))kfree,
.read = of_read,
.size = of_size,
.rw = false,
.ignore_checksum = true,
.no_pcir = true,
};
#else
const struct nvbios_source
......
......@@ -35,6 +35,8 @@ static const struct nvkm_device_agp_quirk
nvkm_device_agp_quirks[] = {
/* VIA Apollo PRO133x / GeForce FX 5600 Ultra - fdo#20341 */
{ PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_NVIDIA, 0x0311, 2 },
/* SiS 761 does not support AGP cards, use PCI mode */
{ PCI_VENDOR_ID_SI, 0x0761, PCI_ANY_ID, PCI_ANY_ID, 0 },
{},
};
......@@ -137,8 +139,10 @@ nvkm_agp_ctor(struct nvkm_pci *pci)
while (quirk->hostbridge_vendor) {
if (info.device->vendor == quirk->hostbridge_vendor &&
info.device->device == quirk->hostbridge_device &&
pci->pdev->vendor == quirk->chip_vendor &&
pci->pdev->device == quirk->chip_device) {
(quirk->chip_vendor == (u16)PCI_ANY_ID ||
pci->pdev->vendor == quirk->chip_vendor) &&
(quirk->chip_device == (u16)PCI_ANY_ID ||
pci->pdev->device == quirk->chip_device)) {
nvkm_info(subdev, "forcing default agp mode to %dX, "
"use NvAGP=<mode> to override\n",
quirk->mode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册