Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
Pull drm fixes from Dave Airlie:
 "Daniel had some fixes queued up, that were delayed, the stolen memory
  ones and vga arbiter ones are quite useful, along with his usual bunch
  of stuff, nothing for HSW outputs yet.

  The one nouveau fix is for a regression I caused with the poweroff stuff"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (30 commits)
  drm/nouveau: fix oops on runtime suspend/resume
  drm/i915: Delay disabling of VGA memory until vgacon->fbcon handoff is done
  drm/i915: try not to lose backlight CBLV precision
  drm/i915: Confine page flips to BCS on Valleyview
  drm/i915: Skip stolen region initialisation if none is reserved
  drm/i915: fix gpu hang vs. flip stall deadlocks
  drm/i915: Hold an object reference whilst we shrink it
  drm/i915: fix i9xx_crtc_clock_get for multiplied pixels
  drm/i915: handle sdvo input pixel multiplier correctly again
  drm/i915: fix hpd work vs. flush_work in the pageflip code deadlock
  drm/i915: fix up the relocate_entry refactoring
  drm/i915: Fix pipe config warnings when dealing with LVDS fixed mode
  drm/i915: Don't call sg_free_table() if sg_alloc_table() fails
  i915: Update VGA arbiter support for newer devices
  vgaarb: Fix VGA decodes changes
  vgaarb: Don't disable resources that are not owned
  drm/i915: Pin pages whilst mapping the dma-buf
  drm/i915: enable trickle feed on Haswell
  x86: add early quirk for reserving Intel graphics stolen memory v5
  drm/i915: split PCI IDs out into i915_drm.h v4
  ...
  • Loading branch information
torvalds committed Sep 11, 2013
2 parents cf59676 + 0117277 commit fa1586a
Show file tree
Hide file tree
Showing 30 changed files with 780 additions and 337 deletions.
154 changes: 154 additions & 0 deletions arch/x86/kernel/early-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/pci_ids.h>
#include <drm/i915_drm.h>
#include <asm/pci-direct.h>
#include <asm/dma.h>
#include <asm/io_apic.h>
Expand Down Expand Up @@ -216,6 +217,157 @@ static void __init intel_remapping_check(int num, int slot, int func)

}

/*
* Systems with Intel graphics controllers set aside memory exclusively
* for gfx driver use. This memory is not marked in the E820 as reserved
* or as RAM, and so is subject to overlap from E820 manipulation later
* in the boot process. On some systems, MMIO space is allocated on top,
* despite the efforts of the "RAM buffer" approach, which simply rounds
* memory boundaries up to 64M to try to catch space that may decode
* as RAM and so is not suitable for MMIO.
*
* And yes, so far on current devices the base addr is always under 4G.
*/
static u32 __init intel_stolen_base(int num, int slot, int func)
{
u32 base;

/*
* For the PCI IDs in this quirk, the stolen base is always
* in 0x5c, aka the BDSM register (yes that's really what
* it's called).
*/
base = read_pci_config(num, slot, func, 0x5c);
base &= ~((1<<20) - 1);

return base;
}

#define KB(x) ((x) * 1024)
#define MB(x) (KB (KB (x)))
#define GB(x) (MB (KB (x)))

static size_t __init gen3_stolen_size(int num, int slot, int func)
{
size_t stolen_size;
u16 gmch_ctrl;

gmch_ctrl = read_pci_config_16(0, 0, 0, I830_GMCH_CTRL);

switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
case I855_GMCH_GMS_STOLEN_1M:
stolen_size = MB(1);
break;
case I855_GMCH_GMS_STOLEN_4M:
stolen_size = MB(4);
break;
case I855_GMCH_GMS_STOLEN_8M:
stolen_size = MB(8);
break;
case I855_GMCH_GMS_STOLEN_16M:
stolen_size = MB(16);
break;
case I855_GMCH_GMS_STOLEN_32M:
stolen_size = MB(32);
break;
case I915_GMCH_GMS_STOLEN_48M:
stolen_size = MB(48);
break;
case I915_GMCH_GMS_STOLEN_64M:
stolen_size = MB(64);
break;
case G33_GMCH_GMS_STOLEN_128M:
stolen_size = MB(128);
break;
case G33_GMCH_GMS_STOLEN_256M:
stolen_size = MB(256);
break;
case INTEL_GMCH_GMS_STOLEN_96M:
stolen_size = MB(96);
break;
case INTEL_GMCH_GMS_STOLEN_160M:
stolen_size = MB(160);
break;
case INTEL_GMCH_GMS_STOLEN_224M:
stolen_size = MB(224);
break;
case INTEL_GMCH_GMS_STOLEN_352M:
stolen_size = MB(352);
break;
default:
stolen_size = 0;
break;
}

return stolen_size;
}

static size_t __init gen6_stolen_size(int num, int slot, int func)
{
u16 gmch_ctrl;

gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL);
gmch_ctrl >>= SNB_GMCH_GMS_SHIFT;
gmch_ctrl &= SNB_GMCH_GMS_MASK;

return gmch_ctrl << 25; /* 32 MB units */
}

typedef size_t (*stolen_size_fn)(int num, int slot, int func);

static struct pci_device_id intel_stolen_ids[] __initdata = {
INTEL_I915G_IDS(gen3_stolen_size),
INTEL_I915GM_IDS(gen3_stolen_size),
INTEL_I945G_IDS(gen3_stolen_size),
INTEL_I945GM_IDS(gen3_stolen_size),
INTEL_VLV_M_IDS(gen3_stolen_size),
INTEL_VLV_D_IDS(gen3_stolen_size),
INTEL_PINEVIEW_IDS(gen3_stolen_size),
INTEL_I965G_IDS(gen3_stolen_size),
INTEL_G33_IDS(gen3_stolen_size),
INTEL_I965GM_IDS(gen3_stolen_size),
INTEL_GM45_IDS(gen3_stolen_size),
INTEL_G45_IDS(gen3_stolen_size),
INTEL_IRONLAKE_D_IDS(gen3_stolen_size),
INTEL_IRONLAKE_M_IDS(gen3_stolen_size),
INTEL_SNB_D_IDS(gen6_stolen_size),
INTEL_SNB_M_IDS(gen6_stolen_size),
INTEL_IVB_M_IDS(gen6_stolen_size),
INTEL_IVB_D_IDS(gen6_stolen_size),
INTEL_HSW_D_IDS(gen6_stolen_size),
INTEL_HSW_M_IDS(gen6_stolen_size),
};

static void __init intel_graphics_stolen(int num, int slot, int func)
{
size_t size;
int i;
u32 start;
u16 device, subvendor, subdevice;

device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID);
subvendor = read_pci_config_16(num, slot, func,
PCI_SUBSYSTEM_VENDOR_ID);
subdevice = read_pci_config_16(num, slot, func, PCI_SUBSYSTEM_ID);

for (i = 0; i < ARRAY_SIZE(intel_stolen_ids); i++) {
if (intel_stolen_ids[i].device == device) {
stolen_size_fn stolen_size =
(stolen_size_fn)intel_stolen_ids[i].driver_data;
size = stolen_size(num, slot, func);
start = intel_stolen_base(num, slot, func);
if (size && start) {
/* Mark this space as reserved */
e820_add_region(start, size, E820_RESERVED);
sanitize_e820_map(e820.map,
ARRAY_SIZE(e820.map),
&e820.nr_map);
}
return;
}
}
}

#define QFLAG_APPLY_ONCE 0x1
#define QFLAG_APPLIED 0x2
#define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
Expand Down Expand Up @@ -251,6 +403,8 @@ static struct chipset early_qrk[] __initdata = {
PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
{ PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST,
PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID,
QFLAG_APPLY_ONCE, intel_graphics_stolen },
{}
};

Expand Down
11 changes: 10 additions & 1 deletion drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS);
u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
u32 rpstat, cagf;
u32 rpstat, cagf, reqf;
u32 rpupei, rpcurup, rpprevup;
u32 rpdownei, rpcurdown, rpprevdown;
int max_freq;
Expand All @@ -869,6 +869,14 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)

gen6_gt_force_wake_get(dev_priv);

reqf = I915_READ(GEN6_RPNSWREQ);
reqf &= ~GEN6_TURBO_DISABLE;
if (IS_HASWELL(dev))
reqf >>= 24;
else
reqf >>= 25;
reqf *= GT_FREQUENCY_MULTIPLIER;

rpstat = I915_READ(GEN6_RPSTAT1);
rpupei = I915_READ(GEN6_RP_CUR_UP_EI);
rpcurup = I915_READ(GEN6_RP_CUR_UP);
Expand All @@ -893,6 +901,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused)
gt_perf_status & 0xff);
seq_printf(m, "Render p-state limit: %d\n",
rp_state_limits & 0xff);
seq_printf(m, "RPNSWREQ: %dMHz\n", reqf);
seq_printf(m, "CAGF: %dMHz\n", cagf);
seq_printf(m, "RP CUR UP EI: %dus\n", rpupei &
GEN6_CURICONT_MASK);
Expand Down
15 changes: 12 additions & 3 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1290,9 +1290,12 @@ static int i915_load_modeset_init(struct drm_device *dev)
* then we do not take part in VGA arbitration and the
* vga_client_register() fails with -ENODEV.
*/
ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
if (ret && ret != -ENODEV)
goto out;
if (!HAS_PCH_SPLIT(dev)) {
ret = vga_client_register(dev->pdev, dev, NULL,
i915_vga_set_decode);
if (ret && ret != -ENODEV)
goto out;
}

intel_register_dsm_handler();

Expand Down Expand Up @@ -1348,6 +1351,12 @@ static int i915_load_modeset_init(struct drm_device *dev)
*/
intel_fbdev_initial_config(dev);

/*
* Must do this after fbcon init so that
* vgacon_save_screen() works during the handover.
*/
i915_disable_vga_mem(dev);

/* Only enable hotplug handling once the fbdev is fully set up. */
dev_priv->enable_hotplug_processing = true;

Expand Down
Loading

0 comments on commit fa1586a

Please sign in to comment.