mirror of https://gitee.com/openkylin/linux.git
Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-next
So here's my promised pile of fixes for 3.9. I've dropped the core prep patches for vt-switchless suspend/resume as discussed on irc. Highlights: - Fix dmar on g4x. Not really gfx related, but I'm fed up with getting blamed for dmar crapouts. - Disable wc ptes updates on ilk when dmar is enabled (Chris). So again, dmar, but this time gfx related :( - Reduced range support for hsw, using the pipe CSC (Ville). - Fixup pll limits for gen3/4 (Patrick Jakobsson). The sdvo patch is already confirmed to fix 2 bug reports, so added cc: stable on that one. - Regression fix for 8bit fb console (Ville). - Preserve lane reversal bits on DDI/FDI ports (Damien). - Page flip vs. gpu hang fixes (Ville). Unfortuntely not quite all of them, need to decide what to do with the currently still in-flight ones. - Panel fitter regression fix from Mika Kuoppala (was accidentally left on on some pipes with the new modset code since 3.7). This also improves the modeset sequence and might help a few other unrelated issues with lvds. - Write backlight regs even harder ... another installement in our eternal fight against the BIOS and backlights. - Fixup lid notifier vs. suspend/resume races (Zhang Rui). Prep work for new ACPI stuff, but closing the race itself seems worthwile on its own. - A few other small fixes and tiny cleanups all over. Lots of the patches are cc: stable since I've stalled on a few not-so-important fixes for 3.8 due to the grumpy noise Linus made. * 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel: (33 commits) intel/iommu: force writebuffer-flush quirk on Gen 4 Chipsets drm/i915: Disable WC PTE updates to w/a buggy IOMMU on ILK drm/i915: Implement pipe CSC based limited range RGB output drm/i915: inverted brightness quirk for Acer Aspire 4736Z drm/i915: Print the hw context status is debugfs drm/i915: Use HAS_L3_GPU_CACHE in i915_gem_l3_remap drm/i915: Fix PIPE_CONTROL DW/QW write through global GTT on IVB+ drm/i915: Set i9xx sdvo clock limits according to specifications drm/i915: Set i9xx lvds clock limits according to specifications drm/i915: Preserve the DDI link reversal configuration drm/i915: Preserve the FDI line reversal override bit on CPT drm/i915: add missing \n to UTS_RELEASE in the error_state drm: Use C8 instead of RGB332 when determining the format from depth/bpp drm: Fill depth/bits_per_pixel for C8 format drm/i915: don't clflush gem objects in stolen memory drm/i915: Don't wait for page flips if there was GPU reset drm/i915: Kill obj->pending_flip drm/i915: Fix a typo in a intel_modeset_stage_output_state() comment drm/i915: remove bogus mutex_unlock from error-path drm/i915: Print the pipe control page GTT address ...
This commit is contained in:
commit
b81e059ec5
|
@ -572,6 +572,40 @@ static void intel_gtt_cleanup(void)
|
|||
intel_gtt_teardown_scratch_page();
|
||||
}
|
||||
|
||||
/* Certain Gen5 chipsets require require idling the GPU before
|
||||
* unmapping anything from the GTT when VT-d is enabled.
|
||||
*/
|
||||
static inline int needs_ilk_vtd_wa(void)
|
||||
{
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
const unsigned short gpu_devid = intel_private.pcidev->device;
|
||||
|
||||
/* Query intel_iommu to see if we need the workaround. Presumably that
|
||||
* was loaded first.
|
||||
*/
|
||||
if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB ||
|
||||
gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
|
||||
intel_iommu_gfx_mapped)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool intel_gtt_can_wc(void)
|
||||
{
|
||||
if (INTEL_GTT_GEN <= 2)
|
||||
return false;
|
||||
|
||||
if (INTEL_GTT_GEN >= 6)
|
||||
return false;
|
||||
|
||||
/* Reports of major corruption with ILK vt'd enabled */
|
||||
if (needs_ilk_vtd_wa())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int intel_gtt_init(void)
|
||||
{
|
||||
u32 gma_addr;
|
||||
|
@ -601,7 +635,7 @@ static int intel_gtt_init(void)
|
|||
gtt_map_size = intel_private.gtt_total_entries * 4;
|
||||
|
||||
intel_private.gtt = NULL;
|
||||
if (INTEL_GTT_GEN < 6 && INTEL_GTT_GEN > 2)
|
||||
if (intel_gtt_can_wc())
|
||||
intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr,
|
||||
gtt_map_size);
|
||||
if (intel_private.gtt == NULL)
|
||||
|
@ -1072,7 +1106,6 @@ static void i965_write_entry(dma_addr_t addr,
|
|||
writel(addr | pte_flags, intel_private.gtt + entry);
|
||||
}
|
||||
|
||||
|
||||
static int i9xx_setup(void)
|
||||
{
|
||||
u32 reg_addr, gtt_addr;
|
||||
|
@ -1371,10 +1404,13 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
|
|||
}
|
||||
EXPORT_SYMBOL(intel_gmch_probe);
|
||||
|
||||
void intel_gtt_get(size_t *gtt_total, size_t *stolen_size)
|
||||
void intel_gtt_get(size_t *gtt_total, size_t *stolen_size,
|
||||
phys_addr_t *mappable_base, unsigned long *mappable_end)
|
||||
{
|
||||
*gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT;
|
||||
*stolen_size = intel_private.stolen_size;
|
||||
*mappable_base = intel_private.gma_bus_addr;
|
||||
*mappable_end = intel_private.gtt_mappable_entries << PAGE_SHIFT;
|
||||
}
|
||||
EXPORT_SYMBOL(intel_gtt_get);
|
||||
|
||||
|
|
|
@ -2267,7 +2267,7 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
|
|||
|
||||
switch (bpp) {
|
||||
case 8:
|
||||
fmt = DRM_FORMAT_RGB332;
|
||||
fmt = DRM_FORMAT_C8;
|
||||
break;
|
||||
case 16:
|
||||
if (depth == 15)
|
||||
|
@ -3870,6 +3870,7 @@ void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
|
|||
int *bpp)
|
||||
{
|
||||
switch (format) {
|
||||
case DRM_FORMAT_C8:
|
||||
case DRM_FORMAT_RGB332:
|
||||
case DRM_FORMAT_BGR233:
|
||||
*depth = 8;
|
||||
|
|
|
@ -694,7 +694,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
|
|||
|
||||
seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
|
||||
error->time.tv_usec);
|
||||
seq_printf(m, "Kernel: " UTS_RELEASE);
|
||||
seq_printf(m, "Kernel: " UTS_RELEASE "\n");
|
||||
seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
|
||||
seq_printf(m, "EIR: 0x%08x\n", error->eir);
|
||||
seq_printf(m, "IER: 0x%08x\n", error->ier);
|
||||
|
@ -1484,7 +1484,8 @@ static int i915_context_status(struct seq_file *m, void *unused)
|
|||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
int ret;
|
||||
struct intel_ring_buffer *ring;
|
||||
int ret, i;
|
||||
|
||||
ret = mutex_lock_interruptible(&dev->mode_config.mutex);
|
||||
if (ret)
|
||||
|
@ -1502,6 +1503,14 @@ static int i915_context_status(struct seq_file *m, void *unused)
|
|||
seq_printf(m, "\n");
|
||||
}
|
||||
|
||||
for_each_ring(ring, dev_priv, i) {
|
||||
if (ring->default_context) {
|
||||
seq_printf(m, "HW default context %s ring ", ring->name);
|
||||
describe_obj(m, ring->default_context->obj);
|
||||
seq_printf(m, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1610,6 +1610,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
mutex_init(&dev_priv->dpio_lock);
|
||||
|
||||
mutex_init(&dev_priv->rps.hw_lock);
|
||||
mutex_init(&dev_priv->modeset_restore_lock);
|
||||
|
||||
if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
|
||||
dev_priv->num_pipe = 3;
|
||||
|
|
|
@ -470,6 +470,11 @@ static int i915_drm_freeze(struct drm_device *dev)
|
|||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
/* ignore lid events during suspend */
|
||||
mutex_lock(&dev_priv->modeset_restore_lock);
|
||||
dev_priv->modeset_restore = MODESET_SUSPENDED;
|
||||
mutex_unlock(&dev_priv->modeset_restore_lock);
|
||||
|
||||
intel_set_power_well(dev, true);
|
||||
|
||||
drm_kms_helper_poll_disable(dev);
|
||||
|
@ -496,9 +501,6 @@ static int i915_drm_freeze(struct drm_device *dev)
|
|||
|
||||
intel_opregion_fini(dev);
|
||||
|
||||
/* Modeset on resume, not lid events */
|
||||
dev_priv->modeset_on_lid = 0;
|
||||
|
||||
console_lock();
|
||||
intel_fbdev_set_suspend(dev, 1);
|
||||
console_unlock();
|
||||
|
@ -574,8 +576,6 @@ static int __i915_drm_thaw(struct drm_device *dev)
|
|||
|
||||
intel_opregion_init(dev);
|
||||
|
||||
dev_priv->modeset_on_lid = 0;
|
||||
|
||||
/*
|
||||
* The console lock can be pretty contented on resume due
|
||||
* to all the printk activity. Try to keep it out of the hot
|
||||
|
@ -588,6 +588,9 @@ static int __i915_drm_thaw(struct drm_device *dev)
|
|||
schedule_work(&dev_priv->console_resume_work);
|
||||
}
|
||||
|
||||
mutex_lock(&dev_priv->modeset_restore_lock);
|
||||
dev_priv->modeset_restore = MODESET_DONE;
|
||||
mutex_unlock(&dev_priv->modeset_restore_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -399,7 +399,8 @@ struct i915_gtt {
|
|||
|
||||
/* global gtt ops */
|
||||
int (*gtt_probe)(struct drm_device *dev, size_t *gtt_total,
|
||||
size_t *stolen);
|
||||
size_t *stolen, phys_addr_t *mappable_base,
|
||||
unsigned long *mappable_end);
|
||||
void (*gtt_remove)(struct drm_device *dev);
|
||||
void (*gtt_clear_range)(struct drm_device *dev,
|
||||
unsigned int first_entry,
|
||||
|
@ -846,6 +847,12 @@ struct i915_gpu_error {
|
|||
unsigned int stop_rings;
|
||||
};
|
||||
|
||||
enum modeset_restore {
|
||||
MODESET_ON_LID_OPEN,
|
||||
MODESET_DONE,
|
||||
MODESET_SUSPENDED,
|
||||
};
|
||||
|
||||
typedef struct drm_i915_private {
|
||||
struct drm_device *dev;
|
||||
struct kmem_cache *slab;
|
||||
|
@ -919,7 +926,7 @@ typedef struct drm_i915_private {
|
|||
|
||||
/* overlay */
|
||||
struct intel_overlay *overlay;
|
||||
bool sprite_scaling_enabled;
|
||||
unsigned int sprite_scaling_enabled;
|
||||
|
||||
/* LVDS info */
|
||||
int backlight_level; /* restore backlight to this value */
|
||||
|
@ -967,8 +974,8 @@ typedef struct drm_i915_private {
|
|||
|
||||
unsigned long quirks;
|
||||
|
||||
/* Register state */
|
||||
bool modeset_on_lid;
|
||||
enum modeset_restore modeset_restore;
|
||||
struct mutex modeset_restore_lock;
|
||||
|
||||
struct i915_gtt gtt;
|
||||
|
||||
|
@ -1033,7 +1040,7 @@ typedef struct drm_i915_private {
|
|||
bool hw_contexts_disabled;
|
||||
uint32_t hw_context_size;
|
||||
|
||||
bool fdi_rx_polarity_reversed;
|
||||
u32 fdi_rx_config;
|
||||
|
||||
struct i915_suspend_saved_registers regfile;
|
||||
|
||||
|
@ -1208,13 +1215,6 @@ struct drm_i915_gem_object {
|
|||
|
||||
/** for phy allocated objects */
|
||||
struct drm_i915_gem_phys_object *phys_obj;
|
||||
|
||||
/**
|
||||
* Number of crtcs where this object is currently the fb, but
|
||||
* will be page flipped away on the next vblank. When it
|
||||
* reaches 0, dev_priv->pending_flip_queue will be woken up.
|
||||
*/
|
||||
atomic_t pending_flip;
|
||||
};
|
||||
#define to_gem_object(obj) (&((struct drm_i915_gem_object *)(obj))->base)
|
||||
|
||||
|
|
|
@ -3021,6 +3021,13 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj)
|
|||
if (obj->pages == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Stolen memory is always coherent with the GPU as it is explicitly
|
||||
* marked as wc by the system, or the system is cache-coherent.
|
||||
*/
|
||||
if (obj->stolen)
|
||||
return;
|
||||
|
||||
/* If the GPU is snooping the contents of the CPU cache,
|
||||
* we do not need to manually clear the CPU cache lines. However,
|
||||
* the caches are only snooped when the render cache is
|
||||
|
@ -3865,7 +3872,7 @@ void i915_gem_l3_remap(struct drm_device *dev)
|
|||
u32 misccpctl;
|
||||
int i;
|
||||
|
||||
if (!IS_IVYBRIDGE(dev))
|
||||
if (!HAS_L3_GPU_CACHE(dev))
|
||||
return;
|
||||
|
||||
if (!dev_priv->l3_parity.remap_info)
|
||||
|
@ -3930,22 +3937,11 @@ intel_enable_blt(struct drm_device *dev)
|
|||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
i915_gem_init_hw(struct drm_device *dev)
|
||||
static int i915_gem_init_rings(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int ret;
|
||||
|
||||
if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
|
||||
return -EIO;
|
||||
|
||||
if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1))
|
||||
I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000);
|
||||
|
||||
i915_gem_l3_remap(dev);
|
||||
|
||||
i915_gem_init_swizzling(dev);
|
||||
|
||||
ret = intel_init_render_ring_buffer(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -3963,6 +3959,38 @@ i915_gem_init_hw(struct drm_device *dev)
|
|||
}
|
||||
|
||||
ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000));
|
||||
if (ret)
|
||||
goto cleanup_blt_ring;
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup_blt_ring:
|
||||
intel_cleanup_ring_buffer(&dev_priv->ring[BCS]);
|
||||
cleanup_bsd_ring:
|
||||
intel_cleanup_ring_buffer(&dev_priv->ring[VCS]);
|
||||
cleanup_render_ring:
|
||||
intel_cleanup_ring_buffer(&dev_priv->ring[RCS]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
i915_gem_init_hw(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
int ret;
|
||||
|
||||
if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
|
||||
return -EIO;
|
||||
|
||||
if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1))
|
||||
I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000);
|
||||
|
||||
i915_gem_l3_remap(dev);
|
||||
|
||||
i915_gem_init_swizzling(dev);
|
||||
|
||||
ret = i915_gem_init_rings(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -3974,12 +4002,6 @@ i915_gem_init_hw(struct drm_device *dev)
|
|||
i915_gem_init_ppgtt(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup_bsd_ring:
|
||||
intel_cleanup_ring_buffer(&dev_priv->ring[VCS]);
|
||||
cleanup_render_ring:
|
||||
intel_cleanup_ring_buffer(&dev_priv->ring[RCS]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int i915_gem_init(struct drm_device *dev)
|
||||
|
|
|
@ -126,13 +126,8 @@ static int get_context_size(struct drm_device *dev)
|
|||
|
||||
static void do_destroy(struct i915_hw_context *ctx)
|
||||
{
|
||||
struct drm_device *dev = ctx->obj->base.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (ctx->file_priv)
|
||||
idr_remove(&ctx->file_priv->context_idr, ctx->id);
|
||||
else
|
||||
BUG_ON(ctx != dev_priv->ring[RCS].default_context);
|
||||
|
||||
drm_gem_object_unreference(&ctx->obj->base);
|
||||
kfree(ctx);
|
||||
|
@ -242,7 +237,6 @@ static int create_default_context(struct drm_i915_private *dev_priv)
|
|||
void i915_gem_context_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
uint32_t ctx_size;
|
||||
|
||||
if (!HAS_HW_CONTEXTS(dev)) {
|
||||
dev_priv->hw_contexts_disabled = true;
|
||||
|
@ -254,11 +248,9 @@ void i915_gem_context_init(struct drm_device *dev)
|
|||
dev_priv->ring[RCS].default_context)
|
||||
return;
|
||||
|
||||
ctx_size = get_context_size(dev);
|
||||
dev_priv->hw_context_size = get_context_size(dev);
|
||||
dev_priv->hw_context_size = round_up(dev_priv->hw_context_size, 4096);
|
||||
dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
|
||||
|
||||
if (ctx_size <= 0 || ctx_size > (1<<20)) {
|
||||
if (dev_priv->hw_context_size > (1<<20)) {
|
||||
dev_priv->hw_contexts_disabled = true;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -725,7 +725,9 @@ static inline size_t gen7_get_stolen_size(u16 snb_gmch_ctl)
|
|||
|
||||
static int gen6_gmch_probe(struct drm_device *dev,
|
||||
size_t *gtt_total,
|
||||
size_t *stolen)
|
||||
size_t *stolen,
|
||||
phys_addr_t *mappable_base,
|
||||
unsigned long *mappable_end)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
phys_addr_t gtt_bus_addr;
|
||||
|
@ -733,11 +735,13 @@ static int gen6_gmch_probe(struct drm_device *dev,
|
|||
u16 snb_gmch_ctl;
|
||||
int ret;
|
||||
|
||||
*mappable_base = pci_resource_start(dev->pdev, 2);
|
||||
*mappable_end = pci_resource_len(dev->pdev, 2);
|
||||
|
||||
/* 64/512MB is the current min/max we actually know of, but this is just
|
||||
* a coarse sanity check.
|
||||
*/
|
||||
if ((dev_priv->gtt.mappable_end < (64<<20) ||
|
||||
(dev_priv->gtt.mappable_end > (512<<20)))) {
|
||||
if ((*mappable_end < (64<<20) || (*mappable_end > (512<<20)))) {
|
||||
DRM_ERROR("Unknown GMADR size (%lx)\n",
|
||||
dev_priv->gtt.mappable_end);
|
||||
return -ENXIO;
|
||||
|
@ -782,7 +786,9 @@ static void gen6_gmch_remove(struct drm_device *dev)
|
|||
|
||||
static int i915_gmch_probe(struct drm_device *dev,
|
||||
size_t *gtt_total,
|
||||
size_t *stolen)
|
||||
size_t *stolen,
|
||||
phys_addr_t *mappable_base,
|
||||
unsigned long *mappable_end)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int ret;
|
||||
|
@ -793,7 +799,7 @@ static int i915_gmch_probe(struct drm_device *dev,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
intel_gtt_get(gtt_total, stolen);
|
||||
intel_gtt_get(gtt_total, stolen, mappable_base, mappable_end);
|
||||
|
||||
dev_priv->gtt.do_idle_maps = needs_idle_maps(dev_priv->dev);
|
||||
dev_priv->gtt.gtt_clear_range = i915_ggtt_clear_range;
|
||||
|
@ -814,9 +820,6 @@ int i915_gem_gtt_init(struct drm_device *dev)
|
|||
unsigned long gtt_size;
|
||||
int ret;
|
||||
|
||||
gtt->mappable_base = pci_resource_start(dev->pdev, 2);
|
||||
gtt->mappable_end = pci_resource_len(dev->pdev, 2);
|
||||
|
||||
if (INTEL_INFO(dev)->gen <= 5) {
|
||||
dev_priv->gtt.gtt_probe = i915_gmch_probe;
|
||||
dev_priv->gtt.gtt_remove = i915_gmch_remove;
|
||||
|
@ -826,7 +829,9 @@ int i915_gem_gtt_init(struct drm_device *dev)
|
|||
}
|
||||
|
||||
ret = dev_priv->gtt.gtt_probe(dev, &dev_priv->gtt.total,
|
||||
&dev_priv->gtt.stolen_size);
|
||||
&dev_priv->gtt.stolen_size,
|
||||
>t->mappable_base,
|
||||
>t->mappable_end);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -1924,7 +1924,7 @@ static void valleyview_irq_preinstall(struct drm_device *dev)
|
|||
* This register is the same on all known PCH chips.
|
||||
*/
|
||||
|
||||
static void ironlake_enable_pch_hotplug(struct drm_device *dev)
|
||||
static void ibx_enable_hotplug(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
u32 hotplug;
|
||||
|
@ -1937,6 +1937,28 @@ static void ironlake_enable_pch_hotplug(struct drm_device *dev)
|
|||
I915_WRITE(PCH_PORT_HOTPLUG, hotplug);
|
||||
}
|
||||
|
||||
static void ibx_irq_postinstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
u32 mask;
|
||||
|
||||
if (HAS_PCH_IBX(dev))
|
||||
mask = SDE_HOTPLUG_MASK |
|
||||
SDE_GMBUS |
|
||||
SDE_AUX_MASK;
|
||||
else
|
||||
mask = SDE_HOTPLUG_MASK_CPT |
|
||||
SDE_GMBUS_CPT |
|
||||
SDE_AUX_MASK_CPT;
|
||||
|
||||
I915_WRITE(SDEIIR, I915_READ(SDEIIR));
|
||||
I915_WRITE(SDEIMR, ~mask);
|
||||
I915_WRITE(SDEIER, mask);
|
||||
POSTING_READ(SDEIER);
|
||||
|
||||
ibx_enable_hotplug(dev);
|
||||
}
|
||||
|
||||
static int ironlake_irq_postinstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
|
@ -1945,8 +1967,6 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
|
|||
DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
|
||||
DE_AUX_CHANNEL_A;
|
||||
u32 render_irqs;
|
||||
u32 hotplug_mask;
|
||||
u32 pch_irq_mask;
|
||||
|
||||
dev_priv->irq_mask = ~display_mask;
|
||||
|
||||
|
@ -1974,30 +1994,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
|
|||
I915_WRITE(GTIER, render_irqs);
|
||||
POSTING_READ(GTIER);
|
||||
|
||||
if (HAS_PCH_CPT(dev)) {
|
||||
hotplug_mask = (SDE_CRT_HOTPLUG_CPT |
|
||||
SDE_PORTB_HOTPLUG_CPT |
|
||||
SDE_PORTC_HOTPLUG_CPT |
|
||||
SDE_PORTD_HOTPLUG_CPT |
|
||||
SDE_GMBUS_CPT |
|
||||
SDE_AUX_MASK_CPT);
|
||||
} else {
|
||||
hotplug_mask = (SDE_CRT_HOTPLUG |
|
||||
SDE_PORTB_HOTPLUG |
|
||||
SDE_PORTC_HOTPLUG |
|
||||
SDE_PORTD_HOTPLUG |
|
||||
SDE_GMBUS |
|
||||
SDE_AUX_MASK);
|
||||
}
|
||||
|
||||
pch_irq_mask = ~hotplug_mask;
|
||||
|
||||
I915_WRITE(SDEIIR, I915_READ(SDEIIR));
|
||||
I915_WRITE(SDEIMR, pch_irq_mask);
|
||||
I915_WRITE(SDEIER, hotplug_mask);
|
||||
POSTING_READ(SDEIER);
|
||||
|
||||
ironlake_enable_pch_hotplug(dev);
|
||||
ibx_irq_postinstall(dev);
|
||||
|
||||
if (IS_IRONLAKE_M(dev)) {
|
||||
/* Clear & enable PCU event interrupts */
|
||||
|
@ -2020,8 +2017,6 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
|
|||
DE_PLANEA_FLIP_DONE_IVB |
|
||||
DE_AUX_CHANNEL_A_IVB;
|
||||
u32 render_irqs;
|
||||
u32 hotplug_mask;
|
||||
u32 pch_irq_mask;
|
||||
|
||||
dev_priv->irq_mask = ~display_mask;
|
||||
|
||||
|
@ -2045,20 +2040,7 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
|
|||
I915_WRITE(GTIER, render_irqs);
|
||||
POSTING_READ(GTIER);
|
||||
|
||||
hotplug_mask = (SDE_CRT_HOTPLUG_CPT |
|
||||
SDE_PORTB_HOTPLUG_CPT |
|
||||
SDE_PORTC_HOTPLUG_CPT |
|
||||
SDE_PORTD_HOTPLUG_CPT |
|
||||
SDE_GMBUS_CPT |
|
||||
SDE_AUX_MASK_CPT);
|
||||
pch_irq_mask = ~hotplug_mask;
|
||||
|
||||
I915_WRITE(SDEIIR, I915_READ(SDEIIR));
|
||||
I915_WRITE(SDEIMR, pch_irq_mask);
|
||||
I915_WRITE(SDEIER, hotplug_mask);
|
||||
POSTING_READ(SDEIER);
|
||||
|
||||
ironlake_enable_pch_hotplug(dev);
|
||||
ibx_irq_postinstall(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2137,12 +2119,12 @@ static void valleyview_hpd_irq_setup(struct drm_device *dev)
|
|||
u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
|
||||
|
||||
/* Note HDMI and DP share bits */
|
||||
if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= HDMIB_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= HDMIC_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= HDMID_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= PORTB_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= PORTC_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= PORTD_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915)
|
||||
hotplug_en |= SDVOC_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915)
|
||||
|
@ -2408,12 +2390,12 @@ static void i915_hpd_irq_setup(struct drm_device *dev)
|
|||
if (I915_HAS_HOTPLUG(dev)) {
|
||||
hotplug_en = I915_READ(PORT_HOTPLUG_EN);
|
||||
|
||||
if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= HDMIB_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= HDMIC_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= HDMID_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= PORTB_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= PORTC_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= PORTD_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_I915)
|
||||
hotplug_en |= SDVOC_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS_I915)
|
||||
|
@ -2642,12 +2624,12 @@ static void i965_hpd_irq_setup(struct drm_device *dev)
|
|||
|
||||
/* Note HDMI and DP share hotplug bits */
|
||||
hotplug_en = 0;
|
||||
if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= HDMIB_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= HDMIC_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= HDMID_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & PORTB_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= PORTB_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & PORTC_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= PORTC_HOTPLUG_INT_EN;
|
||||
if (dev_priv->hotplug_supported_mask & PORTD_HOTPLUG_INT_STATUS)
|
||||
hotplug_en |= PORTD_HOTPLUG_INT_EN;
|
||||
if (IS_G4X(dev)) {
|
||||
if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS_G4X)
|
||||
hotplug_en |= SDVOC_HOTPLUG_INT_EN;
|
||||
|
|
|
@ -308,6 +308,7 @@
|
|||
#define DISPLAY_PLANE_A (0<<20)
|
||||
#define DISPLAY_PLANE_B (1<<20)
|
||||
#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2))
|
||||
#define PIPE_CONTROL_GLOBAL_GTT_IVB (1<<24) /* gen7+ */
|
||||
#define PIPE_CONTROL_CS_STALL (1<<20)
|
||||
#define PIPE_CONTROL_TLB_INVALIDATE (1<<18)
|
||||
#define PIPE_CONTROL_QW_WRITE (1<<14)
|
||||
|
@ -1235,6 +1236,10 @@
|
|||
#define MAD_DIMM_A_SIZE_SHIFT 0
|
||||
#define MAD_DIMM_A_SIZE_MASK (0xff << MAD_DIMM_A_SIZE_SHIFT)
|
||||
|
||||
/** snb MCH registers for priority tuning */
|
||||
#define MCH_SSKPD (MCHBAR_MIRROR_BASE_SNB + 0x5d10)
|
||||
#define MCH_SSKPD_WM0_MASK 0x3f
|
||||
#define MCH_SSKPD_WM0_VAL 0xc
|
||||
|
||||
/* Clocking configuration register */
|
||||
#define CLKCFG 0x10c00
|
||||
|
@ -1625,12 +1630,9 @@
|
|||
|
||||
/* Hotplug control (945+ only) */
|
||||
#define PORT_HOTPLUG_EN (dev_priv->info->display_mmio_offset + 0x61110)
|
||||
#define HDMIB_HOTPLUG_INT_EN (1 << 29)
|
||||
#define DPB_HOTPLUG_INT_EN (1 << 29)
|
||||
#define HDMIC_HOTPLUG_INT_EN (1 << 28)
|
||||
#define DPC_HOTPLUG_INT_EN (1 << 28)
|
||||
#define HDMID_HOTPLUG_INT_EN (1 << 27)
|
||||
#define DPD_HOTPLUG_INT_EN (1 << 27)
|
||||
#define PORTB_HOTPLUG_INT_EN (1 << 29)
|
||||
#define PORTC_HOTPLUG_INT_EN (1 << 28)
|
||||
#define PORTD_HOTPLUG_INT_EN (1 << 27)
|
||||
#define SDVOB_HOTPLUG_INT_EN (1 << 26)
|
||||
#define SDVOC_HOTPLUG_INT_EN (1 << 25)
|
||||
#define TV_HOTPLUG_INT_EN (1 << 18)
|
||||
|
@ -1653,19 +1655,12 @@
|
|||
|
||||
#define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114)
|
||||
/* HDMI/DP bits are gen4+ */
|
||||
#define DPB_HOTPLUG_LIVE_STATUS (1 << 29)
|
||||
#define DPC_HOTPLUG_LIVE_STATUS (1 << 28)
|
||||
#define DPD_HOTPLUG_LIVE_STATUS (1 << 27)
|
||||
#define DPD_HOTPLUG_INT_STATUS (3 << 21)
|
||||
#define DPC_HOTPLUG_INT_STATUS (3 << 19)
|
||||
#define DPB_HOTPLUG_INT_STATUS (3 << 17)
|
||||
/* HDMI bits are shared with the DP bits */
|
||||
#define HDMIB_HOTPLUG_LIVE_STATUS (1 << 29)
|
||||
#define HDMIC_HOTPLUG_LIVE_STATUS (1 << 28)
|
||||
#define HDMID_HOTPLUG_LIVE_STATUS (1 << 27)
|
||||
#define HDMID_HOTPLUG_INT_STATUS (3 << 21)
|
||||
#define HDMIC_HOTPLUG_INT_STATUS (3 << 19)
|
||||
#define HDMIB_HOTPLUG_INT_STATUS (3 << 17)
|
||||
#define PORTB_HOTPLUG_LIVE_STATUS (1 << 29)
|
||||
#define PORTC_HOTPLUG_LIVE_STATUS (1 << 28)
|
||||
#define PORTD_HOTPLUG_LIVE_STATUS (1 << 27)
|
||||
#define PORTD_HOTPLUG_INT_STATUS (3 << 21)
|
||||
#define PORTC_HOTPLUG_INT_STATUS (3 << 19)
|
||||
#define PORTB_HOTPLUG_INT_STATUS (3 << 17)
|
||||
/* CRT/TV common between gen3+ */
|
||||
#define CRT_HOTPLUG_INT_STATUS (1 << 11)
|
||||
#define TV_HOTPLUG_INT_STATUS (1 << 10)
|
||||
|
@ -2954,6 +2949,7 @@
|
|||
#define CURSOR_ENABLE 0x80000000
|
||||
#define CURSOR_GAMMA_ENABLE 0x40000000
|
||||
#define CURSOR_STRIDE_MASK 0x30000000
|
||||
#define CURSOR_PIPE_CSC_ENABLE (1<<24)
|
||||
#define CURSOR_FORMAT_SHIFT 24
|
||||
#define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT)
|
||||
#define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT)
|
||||
|
@ -3015,6 +3011,7 @@
|
|||
#define DISPPLANE_RGBA888 (0xf<<26)
|
||||
#define DISPPLANE_STEREO_ENABLE (1<<25)
|
||||
#define DISPPLANE_STEREO_DISABLE 0
|
||||
#define DISPPLANE_PIPE_CSC_ENABLE (1<<24)
|
||||
#define DISPPLANE_SEL_PIPE_SHIFT 24
|
||||
#define DISPPLANE_SEL_PIPE_MASK (3<<DISPPLANE_SEL_PIPE_SHIFT)
|
||||
#define DISPPLANE_SEL_PIPE_A 0
|
||||
|
@ -3103,6 +3100,7 @@
|
|||
#define DVS_FORMAT_RGBX101010 (1<<25)
|
||||
#define DVS_FORMAT_RGBX888 (2<<25)
|
||||
#define DVS_FORMAT_RGBX161616 (3<<25)
|
||||
#define DVS_PIPE_CSC_ENABLE (1<<24)
|
||||
#define DVS_SOURCE_KEY (1<<22)
|
||||
#define DVS_RGB_ORDER_XBGR (1<<20)
|
||||
#define DVS_YUV_BYTE_ORDER_MASK (3<<16)
|
||||
|
@ -3170,7 +3168,7 @@
|
|||
#define SPRITE_FORMAT_RGBX161616 (3<<25)
|
||||
#define SPRITE_FORMAT_YUV444 (4<<25)
|
||||
#define SPRITE_FORMAT_XR_BGR101010 (5<<25) /* Extended range */
|
||||
#define SPRITE_CSC_ENABLE (1<<24)
|
||||
#define SPRITE_PIPE_CSC_ENABLE (1<<24)
|
||||
#define SPRITE_SOURCE_KEY (1<<22)
|
||||
#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */
|
||||
#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19)
|
||||
|
@ -3917,7 +3915,7 @@
|
|||
#define FDI_10BPC (1<<16)
|
||||
#define FDI_6BPC (2<<16)
|
||||
#define FDI_12BPC (3<<16)
|
||||
#define FDI_LINK_REVERSE_OVERWRITE (1<<15)
|
||||
#define FDI_RX_LINK_REVERSAL_OVERRIDE (1<<15)
|
||||
#define FDI_DMI_LINK_REVERSE_MASK (1<<14)
|
||||
#define FDI_RX_PLL_ENABLE (1<<13)
|
||||
#define FDI_FS_ERR_CORRECT_ENABLE (1<<11)
|
||||
|
@ -4272,8 +4270,8 @@
|
|||
#define GEN6_PCODE_READ_MIN_FREQ_TABLE 0x9
|
||||
#define GEN6_PCODE_WRITE_RC6VIDS 0x4
|
||||
#define GEN6_PCODE_READ_RC6VIDS 0x5
|
||||
#define GEN6_ENCODE_RC6_VID(mv) (((mv) / 5) - 245) < 0 ?: 0
|
||||
#define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) > 0 ? ((vids) * 5) + 245 : 0)
|
||||
#define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5)
|
||||
#define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245)
|
||||
#define GEN6_PCODE_DATA 0x138128
|
||||
#define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8
|
||||
|
||||
|
@ -4516,6 +4514,7 @@
|
|||
#define DDI_BUF_EMP_800MV_0DB_HSW (7<<24) /* Sel7 */
|
||||
#define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */
|
||||
#define DDI_BUF_EMP_MASK (0xf<<24)
|
||||
#define DDI_BUF_PORT_REVERSAL (1<<16)
|
||||
#define DDI_BUF_IS_IDLE (1<<7)
|
||||
#define DDI_A_4_LANES (1<<4)
|
||||
#define DDI_PORT_WIDTH_X1 (0<<1)
|
||||
|
@ -4649,4 +4648,51 @@
|
|||
#define WM_DBG_DISALLOW_MAXFIFO (1<<1)
|
||||
#define WM_DBG_DISALLOW_SPRITE (1<<2)
|
||||
|
||||
/* pipe CSC */
|
||||
#define _PIPE_A_CSC_COEFF_RY_GY 0x49010
|
||||
#define _PIPE_A_CSC_COEFF_BY 0x49014
|
||||
#define _PIPE_A_CSC_COEFF_RU_GU 0x49018
|
||||
#define _PIPE_A_CSC_COEFF_BU 0x4901c
|
||||
#define _PIPE_A_CSC_COEFF_RV_GV 0x49020
|
||||
#define _PIPE_A_CSC_COEFF_BV 0x49024
|
||||
#define _PIPE_A_CSC_MODE 0x49028
|
||||
#define _PIPE_A_CSC_PREOFF_HI 0x49030
|
||||
#define _PIPE_A_CSC_PREOFF_ME 0x49034
|
||||
#define _PIPE_A_CSC_PREOFF_LO 0x49038
|
||||
#define _PIPE_A_CSC_POSTOFF_HI 0x49040
|
||||
#define _PIPE_A_CSC_POSTOFF_ME 0x49044
|
||||
#define _PIPE_A_CSC_POSTOFF_LO 0x49048
|
||||
|
||||
#define _PIPE_B_CSC_COEFF_RY_GY 0x49110
|
||||
#define _PIPE_B_CSC_COEFF_BY 0x49114
|
||||
#define _PIPE_B_CSC_COEFF_RU_GU 0x49118
|
||||
#define _PIPE_B_CSC_COEFF_BU 0x4911c
|
||||
#define _PIPE_B_CSC_COEFF_RV_GV 0x49120
|
||||
#define _PIPE_B_CSC_COEFF_BV 0x49124
|
||||
#define _PIPE_B_CSC_MODE 0x49128
|
||||
#define _PIPE_B_CSC_PREOFF_HI 0x49130
|
||||
#define _PIPE_B_CSC_PREOFF_ME 0x49134
|
||||
#define _PIPE_B_CSC_PREOFF_LO 0x49138
|
||||
#define _PIPE_B_CSC_POSTOFF_HI 0x49140
|
||||
#define _PIPE_B_CSC_POSTOFF_ME 0x49144
|
||||
#define _PIPE_B_CSC_POSTOFF_LO 0x49148
|
||||
|
||||
#define CSC_BLACK_SCREEN_OFFSET (1 << 2)
|
||||
#define CSC_POSITION_BEFORE_GAMMA (1 << 1)
|
||||
#define CSC_MODE_YUV_TO_RGB (1 << 0)
|
||||
|
||||
#define PIPE_CSC_COEFF_RY_GY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RY_GY, _PIPE_B_CSC_COEFF_RY_GY)
|
||||
#define PIPE_CSC_COEFF_BY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BY, _PIPE_B_CSC_COEFF_BY)
|
||||
#define PIPE_CSC_COEFF_RU_GU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RU_GU, _PIPE_B_CSC_COEFF_RU_GU)
|
||||
#define PIPE_CSC_COEFF_BU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BU, _PIPE_B_CSC_COEFF_BU)
|
||||
#define PIPE_CSC_COEFF_RV_GV(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RV_GV, _PIPE_B_CSC_COEFF_RV_GV)
|
||||
#define PIPE_CSC_COEFF_BV(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BV, _PIPE_B_CSC_COEFF_BV)
|
||||
#define PIPE_CSC_MODE(pipe) _PIPE(pipe, _PIPE_A_CSC_MODE, _PIPE_B_CSC_MODE)
|
||||
#define PIPE_CSC_PREOFF_HI(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_HI, _PIPE_B_CSC_PREOFF_HI)
|
||||
#define PIPE_CSC_PREOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_ME, _PIPE_B_CSC_PREOFF_ME)
|
||||
#define PIPE_CSC_PREOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_PREOFF_LO, _PIPE_B_CSC_PREOFF_LO)
|
||||
#define PIPE_CSC_POSTOFF_HI(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_HI, _PIPE_B_CSC_POSTOFF_HI)
|
||||
#define PIPE_CSC_POSTOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME)
|
||||
#define PIPE_CSC_POSTOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO)
|
||||
|
||||
#endif /* _I915_REG_H_ */
|
||||
|
|
|
@ -800,10 +800,14 @@ void intel_crt_init(struct drm_device *dev)
|
|||
dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
|
||||
|
||||
/*
|
||||
* TODO: find a proper way to discover whether we need to set the
|
||||
* polarity reversal bit or not, instead of relying on the BIOS.
|
||||
* TODO: find a proper way to discover whether we need to set the the
|
||||
* polarity and link reversal bits or not, instead of relying on the
|
||||
* BIOS.
|
||||
*/
|
||||
if (HAS_PCH_LPT(dev))
|
||||
dev_priv->fdi_rx_polarity_reversed =
|
||||
!!(I915_READ(_FDI_RXA_CTL) & FDI_RX_POLARITY_REVERSED_LPT);
|
||||
if (HAS_PCH_LPT(dev)) {
|
||||
u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT |
|
||||
FDI_RX_LINK_REVERSAL_OVERRIDE;
|
||||
|
||||
dev_priv->fdi_rx_config = I915_READ(_FDI_RXA_CTL) & fdi_config;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,10 +180,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
|
|||
FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
|
||||
|
||||
/* Enable the PCH Receiver FDI PLL */
|
||||
rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE |
|
||||
((intel_crtc->fdi_lanes - 1) << 19);
|
||||
if (dev_priv->fdi_rx_polarity_reversed)
|
||||
rx_ctl_val |= FDI_RX_POLARITY_REVERSED_LPT;
|
||||
rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
|
||||
FDI_RX_PLL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 19);
|
||||
I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
|
||||
POSTING_READ(_FDI_RXA_CTL);
|
||||
udelay(220);
|
||||
|
@ -205,7 +203,10 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
|
|||
DP_TP_CTL_LINK_TRAIN_PAT1 |
|
||||
DP_TP_CTL_ENABLE);
|
||||
|
||||
/* Configure and enable DDI_BUF_CTL for DDI E with next voltage */
|
||||
/* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
|
||||
* DDI E does not support port reversal, the functionality is
|
||||
* achieved on the PCH side in FDI_RX_CTL, so no need to set the
|
||||
* port reversal bit */
|
||||
I915_WRITE(DDI_BUF_CTL(PORT_E),
|
||||
DDI_BUF_CTL_ENABLE |
|
||||
((intel_crtc->fdi_lanes - 1) << 1) |
|
||||
|
@ -680,8 +681,11 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder,
|
|||
intel_crtc->eld_vld = false;
|
||||
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
struct intel_digital_port *intel_dig_port =
|
||||
enc_to_dig_port(encoder);
|
||||
|
||||
intel_dp->DP = DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
|
||||
intel_dp->DP = intel_dig_port->port_reversal |
|
||||
DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
|
||||
switch (intel_dp->lane_count) {
|
||||
case 1:
|
||||
intel_dp->DP |= DDI_PORT_WIDTH_X1;
|
||||
|
@ -1304,11 +1308,15 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
|
|||
uint32_t tmp;
|
||||
|
||||
if (type == INTEL_OUTPUT_HDMI) {
|
||||
struct intel_digital_port *intel_dig_port =
|
||||
enc_to_dig_port(encoder);
|
||||
|
||||
/* In HDMI/DVI mode, the port width, and swing/emphasis values
|
||||
* are ignored so nothing special needs to be done besides
|
||||
* enabling the port.
|
||||
*/
|
||||
I915_WRITE(DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE);
|
||||
I915_WRITE(DDI_BUF_CTL(port),
|
||||
intel_dig_port->port_reversal | DDI_BUF_CTL_ENABLE);
|
||||
} else if (type == INTEL_OUTPUT_EDP) {
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
|
||||
|
@ -1485,6 +1493,7 @@ static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = {
|
|||
|
||||
void intel_ddi_init(struct drm_device *dev, enum port port)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_digital_port *intel_dig_port;
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct drm_encoder *encoder;
|
||||
|
@ -1525,6 +1534,8 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
|
|||
intel_encoder->get_hw_state = intel_ddi_get_hw_state;
|
||||
|
||||
intel_dig_port->port = port;
|
||||
intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) &
|
||||
DDI_BUF_PORT_REVERSAL;
|
||||
if (hdmi_connector)
|
||||
intel_dig_port->hdmi.sdvox_reg = DDI_BUF_CTL(port);
|
||||
else
|
||||
|
|
|
@ -154,8 +154,8 @@ static const intel_limit_t intel_limits_i9xx_sdvo = {
|
|||
.vco = { .min = 1400000, .max = 2800000 },
|
||||
.n = { .min = 1, .max = 6 },
|
||||
.m = { .min = 70, .max = 120 },
|
||||
.m1 = { .min = 10, .max = 22 },
|
||||
.m2 = { .min = 5, .max = 9 },
|
||||
.m1 = { .min = 8, .max = 18 },
|
||||
.m2 = { .min = 3, .max = 7 },
|
||||
.p = { .min = 5, .max = 80 },
|
||||
.p1 = { .min = 1, .max = 8 },
|
||||
.p2 = { .dot_limit = 200000,
|
||||
|
@ -168,8 +168,8 @@ static const intel_limit_t intel_limits_i9xx_lvds = {
|
|||
.vco = { .min = 1400000, .max = 2800000 },
|
||||
.n = { .min = 1, .max = 6 },
|
||||
.m = { .min = 70, .max = 120 },
|
||||
.m1 = { .min = 10, .max = 22 },
|
||||
.m2 = { .min = 5, .max = 9 },
|
||||
.m1 = { .min = 8, .max = 18 },
|
||||
.m2 = { .min = 3, .max = 7 },
|
||||
.p = { .min = 7, .max = 98 },
|
||||
.p1 = { .min = 1, .max = 8 },
|
||||
.p2 = { .dot_limit = 112000,
|
||||
|
@ -2226,12 +2226,6 @@ intel_finish_fb(struct drm_framebuffer *old_fb)
|
|||
bool was_interruptible = dev_priv->mm.interruptible;
|
||||
int ret;
|
||||
|
||||
WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue));
|
||||
|
||||
wait_event(dev_priv->pending_flip_queue,
|
||||
i915_reset_in_progress(&dev_priv->gpu_error) ||
|
||||
atomic_read(&obj->pending_flip) == 0);
|
||||
|
||||
/* Big Hammer, we also need to ensure that any pending
|
||||
* MI_WAIT_FOR_EVENT inside a user batch buffer on the
|
||||
* current scanout is retired before unpinning the old
|
||||
|
@ -2874,10 +2868,12 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
|
|||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
unsigned long flags;
|
||||
bool pending;
|
||||
|
||||
if (i915_reset_in_progress(&dev_priv->gpu_error))
|
||||
if (i915_reset_in_progress(&dev_priv->gpu_error) ||
|
||||
intel_crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter))
|
||||
return false;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
|
@ -3615,6 +3611,11 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
|
|||
intel_update_watermarks(dev);
|
||||
|
||||
intel_enable_pll(dev_priv, pipe);
|
||||
|
||||
for_each_encoder_on_crtc(dev, crtc, encoder)
|
||||
if (encoder->pre_enable)
|
||||
encoder->pre_enable(encoder);
|
||||
|
||||
intel_enable_pipe(dev_priv, pipe, false);
|
||||
intel_enable_plane(dev_priv, plane, pipe);
|
||||
|
||||
|
@ -3637,6 +3638,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
|
|||
struct intel_encoder *encoder;
|
||||
int pipe = intel_crtc->pipe;
|
||||
int plane = intel_crtc->plane;
|
||||
u32 pctl;
|
||||
|
||||
|
||||
if (!intel_crtc->active)
|
||||
|
@ -3656,6 +3658,13 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
|
|||
|
||||
intel_disable_plane(dev_priv, plane, pipe);
|
||||
intel_disable_pipe(dev_priv, pipe);
|
||||
|
||||
/* Disable pannel fitter if it is on this pipe. */
|
||||
pctl = I915_READ(PFIT_CONTROL);
|
||||
if ((pctl & PFIT_ENABLE) &&
|
||||
((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe)
|
||||
I915_WRITE(PFIT_CONTROL, 0);
|
||||
|
||||
intel_disable_pll(dev_priv, pipe);
|
||||
|
||||
intel_crtc->active = false;
|
||||
|
@ -5109,6 +5118,71 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
|
|||
POSTING_READ(PIPECONF(pipe));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the pipe CSC unit.
|
||||
*
|
||||
* Currently only full range RGB to limited range RGB conversion
|
||||
* is supported, but eventually this should handle various
|
||||
* RGB<->YCbCr scenarios as well.
|
||||
*/
|
||||
static void intel_set_pipe_csc(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
int pipe = intel_crtc->pipe;
|
||||
uint16_t coeff = 0x7800; /* 1.0 */
|
||||
|
||||
/*
|
||||
* TODO: Check what kind of values actually come out of the pipe
|
||||
* with these coeff/postoff values and adjust to get the best
|
||||
* accuracy. Perhaps we even need to take the bpc value into
|
||||
* consideration.
|
||||
*/
|
||||
|
||||
if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
|
||||
coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */
|
||||
|
||||
/*
|
||||
* GY/GU and RY/RU should be the other way around according
|
||||
* to BSpec, but reality doesn't agree. Just set them up in
|
||||
* a way that results in the correct picture.
|
||||
*/
|
||||
I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff << 16);
|
||||
I915_WRITE(PIPE_CSC_COEFF_BY(pipe), 0);
|
||||
|
||||
I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff);
|
||||
I915_WRITE(PIPE_CSC_COEFF_BU(pipe), 0);
|
||||
|
||||
I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), 0);
|
||||
I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff << 16);
|
||||
|
||||
I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0);
|
||||
I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0);
|
||||
I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0);
|
||||
|
||||
if (INTEL_INFO(dev)->gen > 6) {
|
||||
uint16_t postoff = 0;
|
||||
|
||||
if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
|
||||
postoff = (16 * (1 << 13) / 255) & 0x1fff;
|
||||
|
||||
I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
|
||||
I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff);
|
||||
I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff);
|
||||
|
||||
I915_WRITE(PIPE_CSC_MODE(pipe), 0);
|
||||
} else {
|
||||
uint32_t mode = CSC_MODE_YUV_TO_RGB;
|
||||
|
||||
if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
|
||||
mode |= CSC_BLACK_SCREEN_OFFSET;
|
||||
|
||||
I915_WRITE(PIPE_CSC_MODE(pipe), mode);
|
||||
}
|
||||
}
|
||||
|
||||
static void haswell_set_pipeconf(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *adjusted_mode,
|
||||
bool dither)
|
||||
|
@ -5697,8 +5771,10 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
|
|||
|
||||
haswell_set_pipeconf(crtc, adjusted_mode, dither);
|
||||
|
||||
intel_set_pipe_csc(crtc, adjusted_mode);
|
||||
|
||||
/* Set up the display plane register */
|
||||
I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE);
|
||||
I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE | DISPPLANE_PIPE_CSC_ENABLE);
|
||||
POSTING_READ(DSPCNTR(plane));
|
||||
|
||||
ret = intel_pipe_set_base(crtc, x, y, fb);
|
||||
|
@ -6103,6 +6179,8 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
|
|||
cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
|
||||
cntl |= CURSOR_MODE_DISABLE;
|
||||
}
|
||||
if (IS_HASWELL(dev))
|
||||
cntl |= CURSOR_PIPE_CSC_ENABLE;
|
||||
I915_WRITE(CURCNTR_IVB(pipe), cntl);
|
||||
|
||||
intel_crtc->cursor_visible = visible;
|
||||
|
@ -7235,6 +7313,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
|
|||
work->enable_stall_check = true;
|
||||
|
||||
atomic_inc(&intel_crtc->unpin_work_count);
|
||||
intel_crtc->reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
|
||||
|
||||
ret = dev_priv->display.queue_flip(dev, crtc, fb, obj);
|
||||
if (ret)
|
||||
|
@ -7876,7 +7955,7 @@ intel_modeset_stage_output_state(struct drm_device *dev,
|
|||
struct intel_encoder *encoder;
|
||||
int count, ro;
|
||||
|
||||
/* The upper layers ensure that we either disabl a crtc or have a list
|
||||
/* The upper layers ensure that we either disable a crtc or have a list
|
||||
* of connectors. For paranoia, double-check this. */
|
||||
WARN_ON(!set->fb && (set->num_connectors != 0));
|
||||
WARN_ON(set->fb && (set->num_connectors == 0));
|
||||
|
@ -8655,6 +8734,9 @@ static struct intel_quirk intel_quirks[] = {
|
|||
|
||||
/* Acer/Packard Bell NCL20 */
|
||||
{ 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
|
||||
|
||||
/* Acer Aspire 4736Z */
|
||||
{ 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
|
||||
};
|
||||
|
||||
static void intel_init_quirks(struct drm_device *dev)
|
||||
|
|
|
@ -2302,13 +2302,13 @@ g4x_dp_detect(struct intel_dp *intel_dp)
|
|||
|
||||
switch (intel_dig_port->port) {
|
||||
case PORT_B:
|
||||
bit = DPB_HOTPLUG_LIVE_STATUS;
|
||||
bit = PORTB_HOTPLUG_LIVE_STATUS;
|
||||
break;
|
||||
case PORT_C:
|
||||
bit = DPC_HOTPLUG_LIVE_STATUS;
|
||||
bit = PORTC_HOTPLUG_LIVE_STATUS;
|
||||
break;
|
||||
case PORT_D:
|
||||
bit = DPD_HOTPLUG_LIVE_STATUS;
|
||||
bit = PORTD_HOTPLUG_LIVE_STATUS;
|
||||
break;
|
||||
default:
|
||||
return connector_status_unknown;
|
||||
|
@ -2837,15 +2837,15 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
|
|||
name = "DPDDC-A";
|
||||
break;
|
||||
case PORT_B:
|
||||
dev_priv->hotplug_supported_mask |= DPB_HOTPLUG_INT_STATUS;
|
||||
dev_priv->hotplug_supported_mask |= PORTB_HOTPLUG_INT_STATUS;
|
||||
name = "DPDDC-B";
|
||||
break;
|
||||
case PORT_C:
|
||||
dev_priv->hotplug_supported_mask |= DPC_HOTPLUG_INT_STATUS;
|
||||
dev_priv->hotplug_supported_mask |= PORTC_HOTPLUG_INT_STATUS;
|
||||
name = "DPDDC-C";
|
||||
break;
|
||||
case PORT_D:
|
||||
dev_priv->hotplug_supported_mask |= DPD_HOTPLUG_INT_STATUS;
|
||||
dev_priv->hotplug_supported_mask |= PORTD_HOTPLUG_INT_STATUS;
|
||||
name = "DPDDC-D";
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -235,6 +235,9 @@ struct intel_crtc {
|
|||
/* We can share PLLs across outputs if the timings match */
|
||||
struct intel_pch_pll *pch_pll;
|
||||
uint32_t ddi_pll_sel;
|
||||
|
||||
/* reset counter value when the last flip was submitted */
|
||||
unsigned int reset_counter;
|
||||
};
|
||||
|
||||
struct intel_plane {
|
||||
|
@ -390,6 +393,7 @@ struct intel_dp {
|
|||
struct intel_digital_port {
|
||||
struct intel_encoder base;
|
||||
enum port port;
|
||||
u32 port_reversal;
|
||||
struct intel_dp dp;
|
||||
struct intel_hdmi hdmi;
|
||||
};
|
||||
|
|
|
@ -802,10 +802,10 @@ static bool g4x_hdmi_connected(struct intel_hdmi *intel_hdmi)
|
|||
|
||||
switch (intel_dig_port->port) {
|
||||
case PORT_B:
|
||||
bit = HDMIB_HOTPLUG_LIVE_STATUS;
|
||||
bit = PORTB_HOTPLUG_LIVE_STATUS;
|
||||
break;
|
||||
case PORT_C:
|
||||
bit = HDMIC_HOTPLUG_LIVE_STATUS;
|
||||
bit = PORTC_HOTPLUG_LIVE_STATUS;
|
||||
break;
|
||||
default:
|
||||
bit = 0;
|
||||
|
@ -1021,15 +1021,15 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
|
|||
switch (port) {
|
||||
case PORT_B:
|
||||
intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
|
||||
dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
|
||||
dev_priv->hotplug_supported_mask |= PORTB_HOTPLUG_INT_STATUS;
|
||||
break;
|
||||
case PORT_C:
|
||||
intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
|
||||
dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
|
||||
dev_priv->hotplug_supported_mask |= PORTC_HOTPLUG_INT_STATUS;
|
||||
break;
|
||||
case PORT_D:
|
||||
intel_hdmi->ddc_bus = GMBUS_PORT_DPD;
|
||||
dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
|
||||
dev_priv->hotplug_supported_mask |= PORTD_HOTPLUG_INT_STATUS;
|
||||
break;
|
||||
case PORT_A:
|
||||
/* Internal port only for eDP. */
|
||||
|
|
|
@ -51,7 +51,6 @@ struct intel_lvds_encoder {
|
|||
|
||||
u32 pfit_control;
|
||||
u32 pfit_pgm_ratios;
|
||||
bool pfit_dirty;
|
||||
bool is_dual_link;
|
||||
u32 reg;
|
||||
|
||||
|
@ -151,6 +150,29 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder)
|
|||
I915_WRITE(lvds_encoder->reg, temp);
|
||||
}
|
||||
|
||||
static void intel_pre_enable_lvds(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct intel_lvds_encoder *enc = to_lvds_encoder(&encoder->base);
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (HAS_PCH_SPLIT(dev) || !enc->pfit_control)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Enable automatic panel scaling so that non-native modes
|
||||
* fill the screen. The panel fitter should only be
|
||||
* adjusted whilst the pipe is disabled, according to
|
||||
* register description and PRM.
|
||||
*/
|
||||
DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
|
||||
enc->pfit_control,
|
||||
enc->pfit_pgm_ratios);
|
||||
|
||||
I915_WRITE(PFIT_PGM_RATIOS, enc->pfit_pgm_ratios);
|
||||
I915_WRITE(PFIT_CONTROL, enc->pfit_control);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the power state for the panel.
|
||||
*/
|
||||
|
@ -172,22 +194,6 @@ static void intel_enable_lvds(struct intel_encoder *encoder)
|
|||
|
||||
I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) | LVDS_PORT_EN);
|
||||
|
||||
if (lvds_encoder->pfit_dirty) {
|
||||
/*
|
||||
* Enable automatic panel scaling so that non-native modes
|
||||
* fill the screen. The panel fitter should only be
|
||||
* adjusted whilst the pipe is disabled, according to
|
||||
* register description and PRM.
|
||||
*/
|
||||
DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
|
||||
lvds_encoder->pfit_control,
|
||||
lvds_encoder->pfit_pgm_ratios);
|
||||
|
||||
I915_WRITE(PFIT_PGM_RATIOS, lvds_encoder->pfit_pgm_ratios);
|
||||
I915_WRITE(PFIT_CONTROL, lvds_encoder->pfit_control);
|
||||
lvds_encoder->pfit_dirty = false;
|
||||
}
|
||||
|
||||
I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
|
||||
POSTING_READ(lvds_encoder->reg);
|
||||
if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
|
||||
|
@ -217,11 +223,6 @@ static void intel_disable_lvds(struct intel_encoder *encoder)
|
|||
if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
|
||||
DRM_ERROR("timed out waiting for panel to power off\n");
|
||||
|
||||
if (lvds_encoder->pfit_control) {
|
||||
I915_WRITE(PFIT_CONTROL, 0);
|
||||
lvds_encoder->pfit_dirty = true;
|
||||
}
|
||||
|
||||
I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN);
|
||||
POSTING_READ(lvds_encoder->reg);
|
||||
}
|
||||
|
@ -461,7 +462,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
|||
pfit_pgm_ratios != lvds_encoder->pfit_pgm_ratios) {
|
||||
lvds_encoder->pfit_control = pfit_control;
|
||||
lvds_encoder->pfit_pgm_ratios = pfit_pgm_ratios;
|
||||
lvds_encoder->pfit_dirty = true;
|
||||
}
|
||||
dev_priv->lvds_border_bits = border;
|
||||
|
||||
|
@ -547,13 +547,14 @@ static const struct dmi_system_id intel_no_modeset_on_lid[] = {
|
|||
};
|
||||
|
||||
/*
|
||||
* Lid events. Note the use of 'modeset_on_lid':
|
||||
* - we set it on lid close, and reset it on open
|
||||
* Lid events. Note the use of 'modeset':
|
||||
* - we set it to MODESET_ON_LID_OPEN on lid close,
|
||||
* and set it to MODESET_DONE on open
|
||||
* - we use it as a "only once" bit (ie we ignore
|
||||
* duplicate events where it was already properly
|
||||
* set/reset)
|
||||
* - the suspend/resume paths will also set it to
|
||||
* zero, since they restore the mode ("lid open").
|
||||
* duplicate events where it was already properly set)
|
||||
* - the suspend/resume paths will set it to
|
||||
* MODESET_SUSPENDED and ignore the lid open event,
|
||||
* because they restore the mode ("lid open").
|
||||
*/
|
||||
static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
||||
void *unused)
|
||||
|
@ -567,6 +568,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
|||
if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
|
||||
return NOTIFY_OK;
|
||||
|
||||
mutex_lock(&dev_priv->modeset_restore_lock);
|
||||
if (dev_priv->modeset_restore == MODESET_SUSPENDED)
|
||||
goto exit;
|
||||
/*
|
||||
* check and update the status of LVDS connector after receiving
|
||||
* the LID nofication event.
|
||||
|
@ -575,21 +579,24 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
|||
|
||||
/* Don't force modeset on machines where it causes a GPU lockup */
|
||||
if (dmi_check_system(intel_no_modeset_on_lid))
|
||||
return NOTIFY_OK;
|
||||
goto exit;
|
||||
if (!acpi_lid_open()) {
|
||||
dev_priv->modeset_on_lid = 1;
|
||||
return NOTIFY_OK;
|
||||
/* do modeset on next lid open event */
|
||||
dev_priv->modeset_restore = MODESET_ON_LID_OPEN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!dev_priv->modeset_on_lid)
|
||||
return NOTIFY_OK;
|
||||
|
||||
dev_priv->modeset_on_lid = 0;
|
||||
if (dev_priv->modeset_restore == MODESET_DONE)
|
||||
goto exit;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
intel_modeset_setup_hw_state(dev, true);
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
dev_priv->modeset_restore = MODESET_DONE;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&dev_priv->modeset_restore_lock);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
|
@ -1093,6 +1100,7 @@ bool intel_lvds_init(struct drm_device *dev)
|
|||
DRM_MODE_ENCODER_LVDS);
|
||||
|
||||
intel_encoder->enable = intel_enable_lvds;
|
||||
intel_encoder->pre_enable = intel_pre_enable_lvds;
|
||||
intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
|
||||
intel_encoder->disable = intel_disable_lvds;
|
||||
intel_encoder->get_hw_state = intel_lvds_get_hw_state;
|
||||
|
|
|
@ -321,6 +321,9 @@ void intel_panel_enable_backlight(struct drm_device *dev,
|
|||
if (dev_priv->backlight_level == 0)
|
||||
dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
|
||||
|
||||
dev_priv->backlight_enabled = true;
|
||||
intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 4) {
|
||||
uint32_t reg, tmp;
|
||||
|
||||
|
@ -356,12 +359,12 @@ void intel_panel_enable_backlight(struct drm_device *dev,
|
|||
}
|
||||
|
||||
set_level:
|
||||
/* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
|
||||
* BLC_PWM_CPU_CTL may be cleared to zero automatically when these
|
||||
* registers are set.
|
||||
/* Check the current backlight level and try to set again if it's zero.
|
||||
* On some machines, BLC_PWM_CPU_CTL is cleared to zero automatically
|
||||
* when BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1 are written.
|
||||
*/
|
||||
dev_priv->backlight_enabled = true;
|
||||
intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
|
||||
if (!intel_panel_get_backlight(dev))
|
||||
intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
|
||||
}
|
||||
|
||||
static void intel_panel_init_backlight(struct drm_device *dev)
|
||||
|
|
|
@ -2289,7 +2289,6 @@ intel_alloc_context_page(struct drm_device *dev)
|
|||
i915_gem_object_unpin(ctx);
|
||||
err_unref:
|
||||
drm_gem_object_unreference(&ctx->base);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3584,6 +3583,19 @@ static void cpt_init_clock_gating(struct drm_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void gen6_check_mch_setup(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = I915_READ(MCH_SSKPD);
|
||||
if ((tmp & MCH_SSKPD_WM0_MASK) != MCH_SSKPD_WM0_VAL) {
|
||||
DRM_INFO("Wrong MCH_SSKPD value: 0x%08x\n", tmp);
|
||||
DRM_INFO("This can cause pipe underruns and display issues.\n");
|
||||
DRM_INFO("Please upgrade your BIOS to fix this.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void gen6_init_clock_gating(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
@ -3676,6 +3688,8 @@ static void gen6_init_clock_gating(struct drm_device *dev)
|
|||
I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI));
|
||||
|
||||
cpt_init_clock_gating(dev);
|
||||
|
||||
gen6_check_mch_setup(dev);
|
||||
}
|
||||
|
||||
static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
|
||||
|
@ -3861,6 +3875,8 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
|
|||
I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);
|
||||
|
||||
cpt_init_clock_gating(dev);
|
||||
|
||||
gen6_check_mch_setup(dev);
|
||||
}
|
||||
|
||||
static void valleyview_init_clock_gating(struct drm_device *dev)
|
||||
|
|
|
@ -318,6 +318,7 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring,
|
|||
* TLB invalidate requires a post-sync write.
|
||||
*/
|
||||
flags |= PIPE_CONTROL_QW_WRITE;
|
||||
flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
|
||||
|
||||
/* Workaround: we must issue a pipe_control with CS-stall bit
|
||||
* set before a pipe_control command that has the state cache
|
||||
|
@ -331,7 +332,7 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring,
|
|||
|
||||
intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4));
|
||||
intel_ring_emit(ring, flags);
|
||||
intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT);
|
||||
intel_ring_emit(ring, scratch_addr);
|
||||
intel_ring_emit(ring, 0);
|
||||
intel_ring_advance(ring);
|
||||
|
||||
|
@ -467,6 +468,9 @@ init_pipe_control(struct intel_ring_buffer *ring)
|
|||
if (pc->cpu_page == NULL)
|
||||
goto err_unpin;
|
||||
|
||||
DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n",
|
||||
ring->name, pc->gtt_offset);
|
||||
|
||||
pc->obj = obj;
|
||||
ring->private = pc;
|
||||
return 0;
|
||||
|
|
|
@ -50,6 +50,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
|
|||
u32 sprctl, sprscale = 0;
|
||||
unsigned long sprsurf_offset, linear_offset;
|
||||
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
|
||||
bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
|
||||
|
||||
sprctl = I915_READ(SPRCTL(pipe));
|
||||
|
||||
|
@ -89,6 +90,9 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
|
|||
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
|
||||
sprctl |= SPRITE_ENABLE;
|
||||
|
||||
if (IS_HASWELL(dev))
|
||||
sprctl |= SPRITE_PIPE_CSC_ENABLE;
|
||||
|
||||
/* Sizes are 0 based */
|
||||
src_w--;
|
||||
src_h--;
|
||||
|
@ -103,19 +107,15 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
|
|||
* when scaling is disabled.
|
||||
*/
|
||||
if (crtc_w != src_w || crtc_h != src_h) {
|
||||
if (!dev_priv->sprite_scaling_enabled) {
|
||||
dev_priv->sprite_scaling_enabled = true;
|
||||
dev_priv->sprite_scaling_enabled |= 1 << pipe;
|
||||
|
||||
if (!scaling_was_enabled) {
|
||||
intel_update_watermarks(dev);
|
||||
intel_wait_for_vblank(dev, pipe);
|
||||
}
|
||||
sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
|
||||
} else {
|
||||
if (dev_priv->sprite_scaling_enabled) {
|
||||
dev_priv->sprite_scaling_enabled = false;
|
||||
/* potentially re-enable LP watermarks */
|
||||
intel_update_watermarks(dev);
|
||||
}
|
||||
}
|
||||
} else
|
||||
dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
|
||||
|
||||
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
|
||||
I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
|
||||
|
@ -141,6 +141,10 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
|
|||
I915_WRITE(SPRCTL(pipe), sprctl);
|
||||
I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset);
|
||||
POSTING_READ(SPRSURF(pipe));
|
||||
|
||||
/* potentially re-enable LP watermarks */
|
||||
if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
|
||||
intel_update_watermarks(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -150,6 +154,7 @@ ivb_disable_plane(struct drm_plane *plane)
|
|||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
int pipe = intel_plane->pipe;
|
||||
bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
|
||||
|
||||
I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
|
||||
/* Can't leave the scaler enabled... */
|
||||
|
@ -159,8 +164,11 @@ ivb_disable_plane(struct drm_plane *plane)
|
|||
I915_MODIFY_DISPBASE(SPRSURF(pipe), 0);
|
||||
POSTING_READ(SPRSURF(pipe));
|
||||
|
||||
dev_priv->sprite_scaling_enabled = false;
|
||||
intel_update_watermarks(dev);
|
||||
dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
|
||||
|
||||
/* potentially re-enable LP watermarks */
|
||||
if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
|
||||
intel_update_watermarks(dev);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -4253,13 +4253,19 @@ static void quirk_iommu_rwbf(struct pci_dev *dev)
|
|||
{
|
||||
/*
|
||||
* Mobile 4 Series Chipset neglects to set RWBF capability,
|
||||
* but needs it:
|
||||
* but needs it. Same seems to hold for the desktop versions.
|
||||
*/
|
||||
printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n");
|
||||
rwbf_quirk = 1;
|
||||
}
|
||||
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
|
||||
|
||||
#define GGC 0x52
|
||||
#define GGC_MEMORY_SIZE_MASK (0xf << 8)
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
#ifndef _DRM_INTEL_GTT_H
|
||||
#define _DRM_INTEL_GTT_H
|
||||
|
||||
void intel_gtt_get(size_t *gtt_total, size_t *stolen_size);
|
||||
void intel_gtt_get(size_t *gtt_total, size_t *stolen_size,
|
||||
phys_addr_t *mappable_base, unsigned long *mappable_end);
|
||||
|
||||
int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
|
||||
struct agp_bridge_data *bridge);
|
||||
|
|
Loading…
Reference in New Issue