Kaynağa Gözat

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

A couple of bios parser fixes (one for ancient chips, another for new ones - important in Optimus configs).  Another to make sure KMS is enabled on certain Optimus configs, and a TTM failure path fix.

* 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6:
  drm/nouveau/ttm: prevent double-free in nouveau_sgdma_create_ttm() failure path
  drm/nouveau/bios/init: fix thinko in INIT_CONFIGURE_MEM
  drm/nouveau/kms: enable for non-vga pci classes
  drm/nouveau/bios/init: stub opcode 0xaa
Dave Airlie 11 yıl önce
ebeveyn
işleme
4f7d1bc973

+ 18 - 3
drivers/gpu/drm/nouveau/core/subdev/bios/init.c

@@ -579,8 +579,22 @@ static void
 init_reserved(struct nvbios_init *init)
 {
 	u8 opcode = nv_ro08(init->bios, init->offset);
-	trace("RESERVED\t0x%02x\n", opcode);
-	init->offset += 1;
+	u8 length, i;
+
+	switch (opcode) {
+	case 0xaa:
+		length = 4;
+		break;
+	default:
+		length = 1;
+		break;
+	}
+
+	trace("RESERVED 0x%02x\t", opcode);
+	for (i = 1; i < length; i++)
+		cont(" 0x%02x", nv_ro08(init->bios, init->offset + i));
+	cont("\n");
+	init->offset += length;
 }
 
 /**
@@ -1437,7 +1451,7 @@ init_configure_mem(struct nvbios_init *init)
 	data = init_rdvgai(init, 0x03c4, 0x01);
 	init_wrvgai(init, 0x03c4, 0x01, data | 0x20);
 
-	while ((addr = nv_ro32(bios, sdata)) != 0xffffffff) {
+	for (; (addr = nv_ro32(bios, sdata)) != 0xffffffff; sdata += 4) {
 		switch (addr) {
 		case 0x10021c: /* CKE_NORMAL */
 		case 0x1002d0: /* CMD_REFRESH */
@@ -2135,6 +2149,7 @@ static struct nvbios_init_opcode {
 	[0x99] = { init_zm_auxch },
 	[0x9a] = { init_i2c_long_if },
 	[0xa9] = { init_gpio_ne },
+	[0xaa] = { init_reserved },
 };
 
 #define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0]))

+ 15 - 20
drivers/gpu/drm/nouveau/nouveau_display.c

@@ -278,7 +278,6 @@ nouveau_display_create(struct drm_device *dev)
 {
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	struct nouveau_display *disp;
-	u32 pclass = dev->pdev->class >> 8;
 	int ret, gen;
 
 	disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL);
@@ -340,29 +339,25 @@ nouveau_display_create(struct drm_device *dev)
 	drm_kms_helper_poll_init(dev);
 	drm_kms_helper_poll_disable(dev);
 
-	if (nouveau_modeset == 1 ||
-	    (nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) {
-		if (drm->vbios.dcb.entries) {
-			if (nv_device(drm->device)->card_type < NV_50)
-				ret = nv04_display_create(dev);
-			else
-				ret = nv50_display_create(dev);
-		} else {
-			ret = 0;
-		}
-
-		if (ret)
-			goto disp_create_err;
+	if (drm->vbios.dcb.entries) {
+		if (nv_device(drm->device)->card_type < NV_50)
+			ret = nv04_display_create(dev);
+		else
+			ret = nv50_display_create(dev);
+	} else {
+		ret = 0;
+	}
 
-		if (dev->mode_config.num_crtc) {
-			ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
-			if (ret)
-				goto vblank_err;
-		}
+	if (ret)
+		goto disp_create_err;
 
-		nouveau_backlight_init(dev);
+	if (dev->mode_config.num_crtc) {
+		ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+		if (ret)
+			goto vblank_err;
 	}
 
+	nouveau_backlight_init(dev);
 	return 0;
 
 vblank_err:

+ 2 - 1
drivers/gpu/drm/nouveau/nouveau_fbcon.c

@@ -454,7 +454,8 @@ nouveau_fbcon_init(struct drm_device *dev)
 	int preferred_bpp;
 	int ret;
 
-	if (!dev->mode_config.num_crtc)
+	if (!dev->mode_config.num_crtc ||
+	    (dev->pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
 		return 0;
 
 	fbcon = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);

+ 1 - 3
drivers/gpu/drm/nouveau/nouveau_sgdma.c

@@ -104,9 +104,7 @@ nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
 	else
 		nvbe->ttm.ttm.func = &nv50_sgdma_backend;
 
-	if (ttm_dma_tt_init(&nvbe->ttm, bdev, size, page_flags, dummy_read_page)) {
-		kfree(nvbe);
+	if (ttm_dma_tt_init(&nvbe->ttm, bdev, size, page_flags, dummy_read_page))
 		return NULL;
-	}
 	return &nvbe->ttm.ttm;
 }