Ver Fonte

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
Dave Airlie há 9 anos atrás
pai
commit
7b98040a77

+ 5 - 1
drivers/gpu/drm/nouveau/nouveau_display.c

@@ -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;

+ 24 - 0
drivers/gpu/drm/nouveau/nouveau_fbcon.c

@@ -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,

+ 6 - 0
drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c

@@ -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);

+ 3 - 0
drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h

@@ -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);

+ 18 - 9
drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c

@@ -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)

+ 15 - 2
drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c

@@ -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

+ 6 - 2
drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c

@@ -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);