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

Commit bb8ad281 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'drm-intel-next' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel: (22 commits)
  drm/i915: Fix for LVDS VBT change on IGDNG
  drm/i915: Zap the GTT mapping when transitioning from untiled to tiled.
  drm/i915: Refactor calls to unmap_mapping_range
  drm/i915: Avoid saving/restore the modesetting registers twice in KMS mode
  drm: Disable the unused connectors explicitly when resuming with KMS.
  drm/i915: Restore the KMS modeset for every activated CRTC
  drm/i915: Fix harmless warning from patch merged after i2c rework.
  drm/i915: Disable GEM when a broken video BIOS takes up the whole aperture.
  drm/i915: Check the LID device to decide whether the LVDS should be initialized
  drm/i915: Move lock to more reasonable location
  drm/i915: Add gtt_offset to gem object list debugfs output
  drm/i915: Remove gtt_bound from drm_i915_gem_object
  drm/i915: Disable VGA output when doing DRM_MODE_DPMS_OFF.
  drm/i915: crt fetch EDID by DVI-I converter on G4x platform
  drm/i915: Don't update display FIFO watermark on IGDNG
  drm/i915: Adjust DisplayPort clocks to use 96MHz reference
  drm/i915: Make driver less chatty
  drm/i915: fix up a raw 64bit divide
  drm/i915: enable sdvo lvds scaling function.
  drm/i915: Set SSC frequency for 8xx chips correctly
  ...
parents c368b492 5019914c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1090,6 +1090,8 @@ int drm_helper_resume_force_mode(struct drm_device *dev)
		if (ret == false)
			DRM_ERROR("failed to set mode on crtc %p\n", crtc);
	}
	/* disable the unused connectors while restoring the modesetting */
	drm_helper_disable_unused_functions(dev);
	return 0;
}
EXPORT_SYMBOL(drm_helper_resume_force_mode);
+62 −10
Original line number Diff line number Diff line
@@ -846,7 +846,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
		return 0;
	}

	printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr);
	DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr);

	dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);

@@ -885,8 +885,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 * some RAM for the framebuffer at early boot.  This code figures out
 * how much was set aside so we can use it for our own purposes.
 */
static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
			  unsigned long *preallocated_size)
static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
			  uint32_t *preallocated_size)
{
	struct pci_dev *bridge_dev;
	u16 tmp = 0;
@@ -984,10 +984,11 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
	return 0;
}

static int i915_load_modeset_init(struct drm_device *dev)
static int i915_load_modeset_init(struct drm_device *dev,
				  unsigned long prealloc_size,
				  unsigned long agp_size)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	unsigned long agp_size, prealloc_size;
	int fb_bar = IS_I9XX(dev) ? 2 : 0;
	int ret = 0;

@@ -1002,10 +1003,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
	if (IS_I965G(dev) || IS_G33(dev))
		dev_priv->cursor_needs_physical = false;

	ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
	if (ret)
		goto out;

	/* Basic memrange allocator for stolen space (aka vram) */
	drm_mm_init(&dev_priv->vram, 0, prealloc_size);

@@ -1082,6 +1079,44 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
	master->driver_priv = NULL;
}

static void i915_get_mem_freq(struct drm_device *dev)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	u32 tmp;

	if (!IS_IGD(dev))
		return;

	tmp = I915_READ(CLKCFG);

	switch (tmp & CLKCFG_FSB_MASK) {
	case CLKCFG_FSB_533:
		dev_priv->fsb_freq = 533; /* 133*4 */
		break;
	case CLKCFG_FSB_800:
		dev_priv->fsb_freq = 800; /* 200*4 */
		break;
	case CLKCFG_FSB_667:
		dev_priv->fsb_freq =  667; /* 167*4 */
		break;
	case CLKCFG_FSB_400:
		dev_priv->fsb_freq = 400; /* 100*4 */
		break;
	}

	switch (tmp & CLKCFG_MEM_MASK) {
	case CLKCFG_MEM_533:
		dev_priv->mem_freq = 533;
		break;
	case CLKCFG_MEM_667:
		dev_priv->mem_freq = 667;
		break;
	case CLKCFG_MEM_800:
		dev_priv->mem_freq = 800;
		break;
	}
}

/**
 * i915_driver_load - setup chip and create an initial config
 * @dev: DRM device
@@ -1098,6 +1133,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	struct drm_i915_private *dev_priv = dev->dev_private;
	resource_size_t base, size;
	int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
	uint32_t agp_size, prealloc_size;

	/* i915 has 4 more counters */
	dev->counters += 4;
@@ -1146,9 +1182,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
			 "performance may suffer.\n");
	}

	ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
	if (ret)
		goto out_iomapfree;

	/* enable GEM by default */
	dev_priv->has_gem = 1;

	if (prealloc_size > agp_size * 3 / 4) {
		DRM_ERROR("Detected broken video BIOS with %d/%dkB of video "
			  "memory stolen.\n",
			  prealloc_size / 1024, agp_size / 1024);
		DRM_ERROR("Disabling GEM. (try reducing stolen memory or "
			  "updating the BIOS to fix).\n");
		dev_priv->has_gem = 0;
	}

	dev->driver->get_vblank_counter = i915_get_vblank_counter;
	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
	if (IS_G4X(dev) || IS_IGDNG(dev)) {
@@ -1165,6 +1214,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
			goto out_iomapfree;
	}

	i915_get_mem_freq(dev);

	/* On the 945G/GM, the chipset reports the MSI capability on the
	 * integrated graphics even though the support isn't actually there
	 * according to the published specs.  It doesn't appear to function
@@ -1180,6 +1231,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
		pci_enable_msi(dev->pdev);

	spin_lock_init(&dev_priv->user_irq_lock);
	spin_lock_init(&dev_priv->error_lock);
	dev_priv->user_irq_refcount = 0;

	ret = drm_vblank_init(dev, I915_NUM_PIPE);
@@ -1190,7 +1242,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	}

	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
		ret = i915_load_modeset_init(dev);
		ret = i915_load_modeset_init(dev, prealloc_size, agp_size);
		if (ret < 0) {
			DRM_ERROR("failed to init modeset\n");
			goto out_rmmap;
+7 −2
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@

#include "drm_pciids.h"
#include <linux/console.h>
#include "drm_crtc_helper.h"

static unsigned int i915_modeset = -1;
module_param_named(modeset, i915_modeset, int, 0400);
@@ -57,8 +58,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
	struct drm_i915_private *dev_priv = dev->dev_private;

	if (!dev || !dev_priv) {
		printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv);
		printk(KERN_ERR "DRM not initialized, aborting suspend.\n");
		DRM_ERROR("dev: %p, dev_priv: %p\n", dev, dev_priv);
		DRM_ERROR("DRM not initialized, aborting suspend.\n");
		return -ENODEV;
	}

@@ -115,6 +116,10 @@ static int i915_resume(struct drm_device *dev)

		drm_irq_install(dev);
	}
	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
		/* Resume the modeset for every activated CRTC */
		drm_helper_resume_force_mode(dev);
	}

	return ret;
}
+24 −3
Original line number Diff line number Diff line
@@ -133,6 +133,22 @@ struct sdvo_device_mapping {
	u8 initialized;
};

struct drm_i915_error_state {
	u32 eir;
	u32 pgtbl_er;
	u32 pipeastat;
	u32 pipebstat;
	u32 ipeir;
	u32 ipehr;
	u32 instdone;
	u32 acthd;
	u32 instpm;
	u32 instps;
	u32 instdone1;
	u32 seqno;
	struct timeval time;
};

typedef struct drm_i915_private {
	struct drm_device *dev;

@@ -209,6 +225,11 @@ typedef struct drm_i915_private {
	int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
	int num_fence_regs; /* 8 on pre-965, 16 otherwise */

	unsigned int fsb_freq, mem_freq;

	spinlock_t error_lock;
	struct drm_i915_error_state *first_error;

	/* Register state */
	u8 saveLBB;
	u32 saveDSPACNTR;
@@ -468,9 +489,6 @@ struct drm_i915_gem_object {
	 */
	int fence_reg;

	/** Boolean whether this object has a valid gtt offset. */
	int gtt_bound;

	/** How many users have pinned this object in GTT space */
	int pin_count;

@@ -655,6 +673,7 @@ void i915_gem_free_object(struct drm_gem_object *obj);
int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
void i915_gem_object_unpin(struct drm_gem_object *obj);
int i915_gem_object_unbind(struct drm_gem_object *obj);
void i915_gem_release_mmap(struct drm_gem_object *obj);
void i915_gem_lastclose(struct drm_device *dev);
uint32_t i915_get_gem_seqno(struct drm_device *dev);
int i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
@@ -870,6 +889,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define SUPPORTS_INTEGRATED_HDMI(dev)	(IS_G4X(dev) || IS_IGDNG(dev))
#define SUPPORTS_INTEGRATED_DP(dev)	(IS_G4X(dev) || IS_IGDNG(dev))
#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
/* dsparb controlled by hw only */
#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))

#define PRIMARY_RINGBUFFER_SIZE         (128*1024)

+27 −9
Original line number Diff line number Diff line
@@ -1252,6 +1252,31 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
	return ret;
}

/**
 * i915_gem_release_mmap - remove physical page mappings
 * @obj: obj in question
 *
 * Preserve the reservation of the mmaping with the DRM core code, but
 * relinquish ownership of the pages back to the system.
 *
 * It is vital that we remove the page mapping if we have mapped a tiled
 * object through the GTT and then lose the fence register due to
 * resource pressure. Similarly if the object has been moved out of the
 * aperture, than pages mapped into userspace must be revoked. Removing the
 * mapping will then trigger a page fault on the next user access, allowing
 * fixup by i915_gem_fault().
 */
void
i915_gem_release_mmap(struct drm_gem_object *obj)
{
	struct drm_device *dev = obj->dev;
	struct drm_i915_gem_object *obj_priv = obj->driver_private;

	if (dev->dev_mapping)
		unmap_mapping_range(dev->dev_mapping,
				    obj_priv->mmap_offset, obj->size, 1);
}

static void
i915_gem_free_mmap_offset(struct drm_gem_object *obj)
{
@@ -1861,7 +1886,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
{
	struct drm_device *dev = obj->dev;
	struct drm_i915_gem_object *obj_priv = obj->driver_private;
	loff_t offset;
	int ret = 0;

#if WATCH_BUF
@@ -1898,9 +1922,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
	BUG_ON(obj_priv->active);

	/* blow away mappings if mapped through GTT */
	offset = ((loff_t) obj->map_list.hash.key) << PAGE_SHIFT;
	if (dev->dev_mapping)
		unmap_mapping_range(dev->dev_mapping, offset, obj->size, 1);
	i915_gem_release_mmap(obj);

	if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
		i915_gem_clear_fence_reg(obj);
@@ -2222,7 +2244,6 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
	/* None available, try to steal one or wait for a user to finish */
	if (i == dev_priv->num_fence_regs) {
		uint32_t seqno = dev_priv->mm.next_gem_seqno;
		loff_t offset;

		if (avail == 0)
			return -ENOSPC;
@@ -2274,10 +2295,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
		 * Zap this virtual mapping so we can set up a fence again
		 * for this object next time we need it.
		 */
		offset = ((loff_t) reg->obj->map_list.hash.key) << PAGE_SHIFT;
		if (dev->dev_mapping)
			unmap_mapping_range(dev->dev_mapping, offset,
					    reg->obj->size, 1);
		i915_gem_release_mmap(reg->obj);
		old_obj_priv->fence_reg = I915_FENCE_REG_NONE;
	}

Loading