Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67dcabd0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (30 commits)
  vgaarb: fix incorrect dereference of userspace pointer.
  drm/radeon/kms: retry auxch on 0x20 timeout value.
  drm/radeon: Skip dma copy test in benchmark if card doesn't have dma engine.
  drm/vmwgfx: Fix a circular locking dependency bug.
  drm/vmwgfx: Drop scanout flag compat and add execbuf ioctl parameter members. Bumps major.
  drm/vmwgfx: Report propper framebuffer_{max|min}_{width|height}
  drm/vmwgfx: Update the user-space interface.
  drm/radeon/kms: fix screen clearing before fbcon.
  nouveau: fix state detection with switchable graphics
  drm/nouveau: move dereferences after null checks
  drm/nv50: make the pgraph irq handler loop like the pre-nv50 version
  drm/nv50: delete ramfc object after disabling fifo, not before
  drm/nv50: avoid unloading pgraph context when ctxprog is running
  drm/nv50: align size of buffer object to the right boundaries.
  drm/nv50: disregard dac outputs in nv50_sor_dpms()
  drm/nv50: prevent multiple init tables being parsed at the same time
  drm/nouveau: make dp auxch xfer len check for reads only
  drm/nv40: make INIT_COMPUTE_MEM a NOP, just like nv50
  drm/nouveau: Add proper vgaarb support.
  drm/nouveau: Fix fbcon on mixed pre-NV50 + NV50 multicard.
  ...
parents 09e65ed2 77c1ff39
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -90,21 +90,21 @@ int nouveau_hybrid_setup(struct drm_device *dev)
{
{
	int result;
	int result;


	if (nouveau_dsm(dev, NOUVEAU_DSM_ACTIVE, NOUVEAU_DSM_ACTIVE_QUERY,
	if (nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STATE,
								&result))
								&result))
		return -ENODEV;
		return -ENODEV;


	NV_INFO(dev, "_DSM hardware status gave 0x%x\n", result);
	NV_INFO(dev, "_DSM hardware status gave 0x%x\n", result);


	if (result & 0x1) {	/* Stamina mode - disable the external GPU */
	if (result) { /* Ensure that the external GPU is enabled */
		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL);
		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED,
									NULL);
	} else { /* Stamina mode - disable the external GPU */
		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA,
		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA,
									NULL);
									NULL);
		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA,
		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA,
									NULL);
									NULL);
	} else {		/* Ensure that the external GPU is enabled */
		nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL);
		nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED,
									NULL);
	}
	}


	return 0;
	return 0;
+10 −9
Original line number Original line Diff line number Diff line
@@ -1865,7 +1865,7 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)


	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;


	if (dev_priv->card_type >= NV_50)
	if (dev_priv->card_type >= NV_40)
		return 1;
		return 1;


	/*
	/*
@@ -3765,7 +3765,6 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
	 */
	 */


	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct init_exec iexec = {true, false};
	struct nvbios *bios = &dev_priv->VBIOS;
	struct nvbios *bios = &dev_priv->VBIOS;
	uint8_t *table = &bios->data[bios->display.script_table_ptr];
	uint8_t *table = &bios->data[bios->display.script_table_ptr];
	uint8_t *otable = NULL;
	uint8_t *otable = NULL;
@@ -3845,8 +3844,6 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
		}
		}
	}
	}


	bios->display.output = dcbent;

	if (pxclk == 0) {
	if (pxclk == 0) {
		script = ROM16(otable[6]);
		script = ROM16(otable[6]);
		if (!script) {
		if (!script) {
@@ -3855,7 +3852,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
		}
		}


		NV_TRACE(dev, "0x%04X: parsing output script 0\n", script);
		NV_TRACE(dev, "0x%04X: parsing output script 0\n", script);
		parse_init_table(bios, script, &iexec);
		nouveau_bios_run_init_table(dev, script, dcbent);
	} else
	} else
	if (pxclk == -1) {
	if (pxclk == -1) {
		script = ROM16(otable[8]);
		script = ROM16(otable[8]);
@@ -3865,7 +3862,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
		}
		}


		NV_TRACE(dev, "0x%04X: parsing output script 1\n", script);
		NV_TRACE(dev, "0x%04X: parsing output script 1\n", script);
		parse_init_table(bios, script, &iexec);
		nouveau_bios_run_init_table(dev, script, dcbent);
	} else
	} else
	if (pxclk == -2) {
	if (pxclk == -2) {
		if (table[4] >= 12)
		if (table[4] >= 12)
@@ -3878,7 +3875,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
		}
		}


		NV_TRACE(dev, "0x%04X: parsing output script 2\n", script);
		NV_TRACE(dev, "0x%04X: parsing output script 2\n", script);
		parse_init_table(bios, script, &iexec);
		nouveau_bios_run_init_table(dev, script, dcbent);
	} else
	} else
	if (pxclk > 0) {
	if (pxclk > 0) {
		script = ROM16(otable[table[4] + i*6 + 2]);
		script = ROM16(otable[table[4] + i*6 + 2]);
@@ -3890,7 +3887,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
		}
		}


		NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script);
		NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script);
		parse_init_table(bios, script, &iexec);
		nouveau_bios_run_init_table(dev, script, dcbent);
	} else
	} else
	if (pxclk < 0) {
	if (pxclk < 0) {
		script = ROM16(otable[table[4] + i*6 + 4]);
		script = ROM16(otable[table[4] + i*6 + 4]);
@@ -3902,7 +3899,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent,
		}
		}


		NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script);
		NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script);
		parse_init_table(bios, script, &iexec);
		nouveau_bios_run_init_table(dev, script, dcbent);
	}
	}


	return 0;
	return 0;
@@ -5864,10 +5861,13 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table,
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nvbios *bios = &dev_priv->VBIOS;
	struct nvbios *bios = &dev_priv->VBIOS;
	struct init_exec iexec = { true, false };
	struct init_exec iexec = { true, false };
	unsigned long flags;


	spin_lock_irqsave(&bios->lock, flags);
	bios->display.output = dcbent;
	bios->display.output = dcbent;
	parse_init_table(bios, table, &iexec);
	parse_init_table(bios, table, &iexec);
	bios->display.output = NULL;
	bios->display.output = NULL;
	spin_unlock_irqrestore(&bios->lock, flags);
}
}


static bool NVInitVBIOS(struct drm_device *dev)
static bool NVInitVBIOS(struct drm_device *dev)
@@ -5876,6 +5876,7 @@ static bool NVInitVBIOS(struct drm_device *dev)
	struct nvbios *bios = &dev_priv->VBIOS;
	struct nvbios *bios = &dev_priv->VBIOS;


	memset(bios, 0, sizeof(struct nvbios));
	memset(bios, 0, sizeof(struct nvbios));
	spin_lock_init(&bios->lock);
	bios->dev = dev;
	bios->dev = dev;


	if (!NVShadowVBIOS(dev, bios->data))
	if (!NVShadowVBIOS(dev, bios->data))
+2 −0
Original line number Original line Diff line number Diff line
@@ -205,6 +205,8 @@ struct nvbios {
	struct drm_device *dev;
	struct drm_device *dev;
	struct nouveau_bios_info pub;
	struct nouveau_bios_info pub;


	spinlock_t lock;

	uint8_t data[NV_PROM_SIZE];
	uint8_t data[NV_PROM_SIZE];
	unsigned int length;
	unsigned int length;
	bool execute;
	bool execute;
+5 −5
Original line number Original line Diff line number Diff line
@@ -65,8 +65,10 @@ nouveau_bo_fixup_align(struct drm_device *dev,


	/*
	/*
	 * Some of the tile_flags have a periodic structure of N*4096 bytes,
	 * Some of the tile_flags have a periodic structure of N*4096 bytes,
	 * align to to that as well as the page size. Overallocate memory to
	 * align to to that as well as the page size. Align the size to the
	 * avoid corruption of other buffer objects.
	 * appropriate boundaries. This does imply that sizes are rounded up
	 * 3-7 pages, so be aware of this and do not waste memory by allocating
	 * many small buffers.
	 */
	 */
	if (dev_priv->card_type == NV_50) {
	if (dev_priv->card_type == NV_50) {
		uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15;
		uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15;
@@ -77,22 +79,20 @@ nouveau_bo_fixup_align(struct drm_device *dev,
		case 0x2800:
		case 0x2800:
		case 0x4800:
		case 0x4800:
		case 0x7a00:
		case 0x7a00:
			*size = roundup(*size, block_size);
			if (is_power_of_2(block_size)) {
			if (is_power_of_2(block_size)) {
				*size += 3 * block_size;
				for (i = 1; i < 10; i++) {
				for (i = 1; i < 10; i++) {
					*align = 12 * i * block_size;
					*align = 12 * i * block_size;
					if (!(*align % 65536))
					if (!(*align % 65536))
						break;
						break;
				}
				}
			} else {
			} else {
				*size += 6 * block_size;
				for (i = 1; i < 10; i++) {
				for (i = 1; i < 10; i++) {
					*align = 8 * i * block_size;
					*align = 8 * i * block_size;
					if (!(*align % 65536))
					if (!(*align % 65536))
						break;
						break;
				}
				}
			}
			}
			*size = roundup(*size, *align);
			break;
			break;
		default:
		default:
			break;
			break;
+3 −4
Original line number Original line Diff line number Diff line
@@ -278,12 +278,11 @@ nouveau_channel_free(struct nouveau_channel *chan)
	/* Ensure the channel is no longer active on the GPU */
	/* Ensure the channel is no longer active on the GPU */
	pfifo->reassign(dev, false);
	pfifo->reassign(dev, false);


	if (pgraph->channel(dev) == chan) {
	pgraph->fifo_access(dev, false);
	pgraph->fifo_access(dev, false);
	if (pgraph->channel(dev) == chan)
		pgraph->unload_context(dev);
		pgraph->unload_context(dev);
		pgraph->fifo_access(dev, true);
	}
	pgraph->destroy_context(chan);
	pgraph->destroy_context(chan);
	pgraph->fifo_access(dev, true);


	if (pfifo->channel_id(dev) == chan->id) {
	if (pfifo->channel_id(dev) == chan->id) {
		pfifo->disable(dev);
		pfifo->disable(dev);
Loading