Explorar el Código

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "Mainly nouveau fixes, one for a regressions in -rc1, fixes for booting
  on a ppc G5, and a Kconfig fix.  Two radeon fixes, one oops, one s/r
  fix.  One udl mmap fix.  And one core drm fix to stop bad fbdev apps
  overwriting bits of ram."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm: Validate requested virtual size against allocated fb size
  drm/radeon: Don't dereference possibly-NULL pointer.
  mm, drm/udl: fixup vma flags on mmap
  drm/radeon/kms: fix fans after resume
  nouveau/bios: Fix tracking of BIOS image data
  nouveau: Fix crash when pci_ram_rom() returns a size of 0
  drm/nouveau: select POWER_SUPPLY
  drm/nouveau: inform userspace of relaxed kernel subchannel requirements
  Revert "drm/nouveau: inform userspace of new kernel subchannel requirements"
  drm/nouveau: oops, create m2mf for nvd9 too
Linus Torvalds hace 13 años
padre
commit
e1a7eb08ee

+ 6 - 2
drivers/gpu/drm/drm_fb_helper.c

@@ -559,9 +559,13 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 		return -EINVAL;
 
 	/* Need to resize the fb object !!! */
-	if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height) {
+	if (var->bits_per_pixel > fb->bits_per_pixel ||
+	    var->xres > fb->width || var->yres > fb->height ||
+	    var->xres_virtual > fb->width || var->yres_virtual > fb->height) {
 		DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb "
-			  "object %dx%d-%d > %dx%d-%d\n", var->xres, var->yres, var->bits_per_pixel,
+			  "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n",
+			  var->xres, var->yres, var->bits_per_pixel,
+			  var->xres_virtual, var->yres_virtual,
 			  fb->width, fb->height, fb->bits_per_pixel);
 		return -EINVAL;
 	}

+ 1 - 0
drivers/gpu/drm/nouveau/Kconfig

@@ -13,6 +13,7 @@ config DRM_NOUVEAU
 	select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT
 	select ACPI_WMI if ACPI
 	select MXM_WMI if ACPI
+	select POWER_SUPPLY
 	help
 	  Choose this option for open-source nVidia support.
 

+ 6 - 3
drivers/gpu/drm/nouveau/nouveau_bios.c

@@ -177,14 +177,15 @@ bios_shadow_pci(struct nvbios *bios)
 
 	if (!pci_enable_rom(pdev)) {
 		void __iomem *rom = pci_map_rom(pdev, &length);
-		if (rom) {
+		if (rom && length) {
 			bios->data = kmalloc(length, GFP_KERNEL);
 			if (bios->data) {
 				memcpy_fromio(bios->data, rom, length);
 				bios->length = length;
 			}
-			pci_unmap_rom(pdev, rom);
 		}
+		if (rom)
+			pci_unmap_rom(pdev, rom);
 
 		pci_disable_rom(pdev);
 	}
@@ -272,6 +273,7 @@ bios_shadow(struct drm_device *dev)
 		mthd->score = score_vbios(bios, mthd->rw);
 		mthd->size = bios->length;
 		mthd->data = bios->data;
+		bios->data = NULL;
 	} while (mthd->score != 3 && (++mthd)->shadow);
 
 	mthd = shadow_methods;
@@ -280,7 +282,8 @@ bios_shadow(struct drm_device *dev)
 		if (mthd->score > best->score) {
 			kfree(best->data);
 			best = mthd;
-		}
+		} else
+			kfree(mthd->data);
 	} while ((++mthd)->shadow);
 
 	if (best->score) {

+ 5 - 5
drivers/gpu/drm/nouveau/nouveau_channel.c

@@ -436,11 +436,11 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
 	}
 
 	if (dev_priv->card_type < NV_C0) {
-		init->subchan[0].handle = NvSw;
-		init->subchan[0].grclass = NV_SW;
-		init->nr_subchan = 1;
-	} else {
-		init->nr_subchan = 0;
+		init->subchan[0].handle = 0x00000000;
+		init->subchan[0].grclass = 0x0000;
+		init->subchan[1].handle = NvSw;
+		init->subchan[1].grclass = NV_SW;
+		init->nr_subchan = 2;
 	}
 
 	/* Named memory object area */

+ 2 - 2
drivers/gpu/drm/nouveau/nouveau_dma.h

@@ -48,8 +48,8 @@ void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
 
 /* Hardcoded object assignments to subchannels (subchannel id). */
 enum {
-	NvSubSw		= 0,
-	NvSubM2MF	= 1,
+	NvSubM2MF	= 0,
+	NvSubSw		= 1,
 	NvSub2D		= 2,
 	NvSubCtxSurf2D  = 2,
 	NvSubGdiRect    = 3,

+ 1 - 1
drivers/gpu/drm/nouveau/nouveau_state.c

@@ -642,7 +642,7 @@ nouveau_card_channel_init(struct drm_device *dev)
 		OUT_RING  (chan, chan->vram_handle);
 		OUT_RING  (chan, chan->gart_handle);
 	} else
-	if (dev_priv->card_type <= NV_C0) {
+	if (dev_priv->card_type <= NV_D0) {
 		ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039);
 		if (ret)
 			goto error;

+ 14 - 1
drivers/gpu/drm/radeon/atom.c

@@ -1306,8 +1306,11 @@ struct atom_context *atom_parse(struct card_info *card, void *bios)
 
 int atom_asic_init(struct atom_context *ctx)
 {
+	struct radeon_device *rdev = ctx->card->dev->dev_private;
 	int hwi = CU16(ctx->data_table + ATOM_DATA_FWI_PTR);
 	uint32_t ps[16];
+	int ret;
+
 	memset(ps, 0, 64);
 
 	ps[0] = cpu_to_le32(CU32(hwi + ATOM_FWI_DEFSCLK_PTR));
@@ -1317,7 +1320,17 @@ int atom_asic_init(struct atom_context *ctx)
 
 	if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT))
 		return 1;
-	return atom_execute_table(ctx, ATOM_CMD_INIT, ps);
+	ret = atom_execute_table(ctx, ATOM_CMD_INIT, ps);
+	if (ret)
+		return ret;
+
+	memset(ps, 0, 64);
+
+	if (rdev->family < CHIP_R600) {
+		if (CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_SPDFANCNTL))
+			atom_execute_table(ctx, ATOM_CMD_SPDFANCNTL, ps);
+	}
+	return ret;
 }
 
 void atom_destroy(struct atom_context *ctx)

+ 1 - 0
drivers/gpu/drm/radeon/atom.h

@@ -44,6 +44,7 @@
 #define ATOM_CMD_SETSCLK	0x0A
 #define ATOM_CMD_SETMCLK	0x0B
 #define ATOM_CMD_SETPCLK	0x0C
+#define ATOM_CMD_SPDFANCNTL	0x39
 
 #define ATOM_DATA_FWI_PTR	0xC
 #define ATOM_DATA_IIO_PTR	0x32

+ 2 - 1
drivers/gpu/drm/radeon/radeon_object.c

@@ -241,7 +241,8 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
 				domain_start = bo->rdev->mc.vram_start;
 			else
 				domain_start = bo->rdev->mc.gtt_start;
-			WARN_ON_ONCE((*gpu_addr - domain_start) > max_offset);
+			WARN_ON_ONCE(max_offset <
+				     (radeon_bo_gpu_offset(bo) - domain_start));
 		}
 
 		return 0;

+ 1 - 1
drivers/gpu/drm/udl/udl_drv.c

@@ -47,7 +47,7 @@ static struct vm_operations_struct udl_gem_vm_ops = {
 static const struct file_operations udl_driver_fops = {
 	.owner = THIS_MODULE,
 	.open = drm_open,
-	.mmap = drm_gem_mmap,
+	.mmap = udl_drm_gem_mmap,
 	.poll = drm_poll,
 	.read = drm_read,
 	.unlocked_ioctl	= drm_ioctl,

+ 1 - 0
drivers/gpu/drm/udl/udl_drv.h

@@ -121,6 +121,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev,
 
 int udl_gem_vmap(struct udl_gem_object *obj);
 void udl_gem_vunmap(struct udl_gem_object *obj);
+int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 
 int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,

+ 14 - 0
drivers/gpu/drm/udl/udl_gem.c

@@ -71,6 +71,20 @@ int udl_dumb_destroy(struct drm_file *file, struct drm_device *dev,
 	return drm_gem_handle_delete(file, handle);
 }
 
+int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	int ret;
+
+	ret = drm_gem_mmap(filp, vma);
+	if (ret)
+		return ret;
+
+	vma->vm_flags &= ~VM_PFNMAP;
+	vma->vm_flags |= VM_MIXEDMAP;
+
+	return ret;
+}
+
 int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
 	struct udl_gem_object *obj = to_udl_bo(vma->vm_private_data);