i915: 3.12.9

git-svn-id: svn://kolibrios.org@4539 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2014-01-27 20:10:22 +00:00
parent 0c4f98c413
commit da432de99f
19 changed files with 338 additions and 93 deletions

View File

@ -103,7 +103,7 @@ EXPORT_SYMBOL(drm_clflush_pages);
void void
drm_clflush_sg(struct sg_table *st) drm_clflush_sg(struct sg_table *st)
{ {
struct sg_page_iter sg_iter; struct sg_page_iter sg_iter;
struct page *page; struct page *page;
uint8_t *pva; uint8_t *pva;
@ -112,8 +112,8 @@ drm_clflush_sg(struct sg_table *st)
pva = AllocKernelSpace(4096); pva = AllocKernelSpace(4096);
if( pva != NULL) if( pva != NULL)
{ {
mb(); mb();
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) for_each_sg_page(st->sgl, &sg_iter, st->nents, 0)
{ {
page = sg_page_iter_page(&sg_iter); page = sg_page_iter_page(&sg_iter);

View File

@ -68,6 +68,8 @@
#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
/* Force reduced-blanking timings for detailed modes */ /* Force reduced-blanking timings for detailed modes */
#define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7)
/* Force 8bpc */
#define EDID_QUIRK_FORCE_8BPC (1 << 8)
struct detailed_mode_closure { struct detailed_mode_closure {
struct drm_connector *connector; struct drm_connector *connector;
@ -128,6 +130,9 @@ static struct edid_quirk {
/* Medion MD 30217 PG */ /* Medion MD 30217 PG */
{ "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 },
/* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
{ "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC },
}; };
/* /*
@ -1009,12 +1014,12 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
if (block == 0) { if (block == 0) {
int score = drm_edid_header_is_valid(raw_edid); int score = drm_edid_header_is_valid(raw_edid);
if (score == 8) ; if (score == 8) ;
else if (score >= edid_fixup) { else if (score >= edid_fixup) {
DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
memcpy(raw_edid, edid_header, sizeof(edid_header)); memcpy(raw_edid, edid_header, sizeof(edid_header));
} else { } else {
goto bad; goto bad;
} }
} }
@ -1163,7 +1168,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
/* base block fetch */ /* base block fetch */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH)) if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH))
goto out; goto out;
if (drm_edid_block_valid(block, 0, print_bad_edid)) if (drm_edid_block_valid(block, 0, print_bad_edid))
break; break;
if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) { if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
@ -2258,7 +2263,7 @@ do_cvt_mode(struct detailed_timing *timing, void *c)
static int static int
add_cvt_modes(struct drm_connector *connector, struct edid *edid) add_cvt_modes(struct drm_connector *connector, struct edid *edid)
{ {
struct detailed_mode_closure closure = { struct detailed_mode_closure closure = {
connector, edid, 0, 0, 0 connector, edid, 0, 0, 0
}; };
@ -2683,7 +2688,7 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
dbl = cea_db_payload_len(db); dbl = cea_db_payload_len(db);
if (cea_db_tag(db) == VIDEO_BLOCK) if (cea_db_tag(db) == VIDEO_BLOCK)
modes += do_cea_modes (connector, db+1, dbl); modes += do_cea_modes(connector, db + 1, dbl);
else if (cea_db_is_hdmi_vsdb(db)) else if (cea_db_is_hdmi_vsdb(db))
modes += do_hdmi_vsdb_modes(connector, db, dbl); modes += do_hdmi_vsdb_modes(connector, db, dbl);
} }
@ -2795,7 +2800,7 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
for_each_cea_db(cea, i, start, end) { for_each_cea_db(cea, i, start, end) {
db = &cea[i]; db = &cea[i];
dbl = cea_db_payload_len(db); dbl = cea_db_payload_len(db);
switch (cea_db_tag(db)) { switch (cea_db_tag(db)) {
case AUDIO_BLOCK: case AUDIO_BLOCK:
/* Audio Data Block, contains SADs */ /* Audio Data Block, contains SADs */
@ -3236,6 +3241,9 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
drm_add_display_info(edid, &connector->display_info); drm_add_display_info(edid, &connector->display_info);
if (quirks & EDID_QUIRK_FORCE_8BPC)
connector->display_info.bpc = 8;
return num_modes; return num_modes;
} }
EXPORT_SYMBOL(drm_add_edid_modes); EXPORT_SYMBOL(drm_add_edid_modes);

View File

@ -689,7 +689,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
if (desired_mode->vdisplay > sizes.surface_height) if (desired_mode->vdisplay > sizes.surface_height)
sizes.surface_height = desired_mode->vdisplay; sizes.surface_height = desired_mode->vdisplay;
crtc_count++; crtc_count++;
} }
} }
if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) { if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {

View File

@ -254,9 +254,6 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
* we may want to use ida for number allocation and a hash table * we may want to use ida for number allocation and a hash table
* for the pointers, anyway. * for the pointers, anyway.
*/ */
if(handle == -2)
printf("%s handle %d\n", __FUNCTION__, handle);
spin_lock(&filp->table_lock); spin_lock(&filp->table_lock);
/* Check if we currently have a reference on the object */ /* Check if we currently have a reference on the object */
@ -267,8 +264,6 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
} }
dev = obj->dev; dev = obj->dev;
// printf("%s handle %d obj %p\n", __FUNCTION__, handle, obj);
/* Release reference and decrement refcount. */ /* Release reference and decrement refcount. */
idr_remove(&filp->object_idr, handle); idr_remove(&filp->object_idr, handle);
spin_unlock(&filp->table_lock); spin_unlock(&filp->table_lock);
@ -286,6 +281,12 @@ EXPORT_SYMBOL(drm_gem_handle_delete);
* Create a handle for this object. This adds a handle reference * Create a handle for this object. This adds a handle reference
* to the object, which includes a regular reference count. Callers * to the object, which includes a regular reference count. Callers
* will likely want to dereference the object afterwards. * will likely want to dereference the object afterwards.
/**
* drm_gem_handle_create_tail - internal functions to create a handle
*
* This expects the dev->object_name_lock to be held already and will drop it
* before returning. Used to avoid races in establishing new handles when
* importing an object from either an flink name or a dma-buf.
*/ */
int int
drm_gem_handle_create_tail(struct drm_file *file_priv, drm_gem_handle_create_tail(struct drm_file *file_priv,
@ -436,9 +437,6 @@ drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
{ {
struct drm_gem_object *obj; struct drm_gem_object *obj;
if(handle == -2)
printf("%s handle %d\n", __FUNCTION__, handle);
spin_lock(&filp->table_lock); spin_lock(&filp->table_lock);
/* Check if we currently have a reference on the object */ /* Check if we currently have a reference on the object */
@ -539,9 +537,6 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
if (!(dev->driver->driver_features & DRIVER_GEM)) if (!(dev->driver->driver_features & DRIVER_GEM))
return -ENODEV; return -ENODEV;
if(handle == -2)
printf("%s handle %d\n", __FUNCTION__, handle);
mutex_lock(&dev->object_name_lock); mutex_lock(&dev->object_name_lock);
obj = idr_find(&dev->object_name_idr, (int) args->name); obj = idr_find(&dev->object_name_idr, (int) args->name);
if (obj) { if (obj) {

View File

@ -119,7 +119,7 @@ int drm_irq_install(struct drm_device *dev)
if (ret < 0) { if (ret < 0) {
dev->irq_enabled = 0; dev->irq_enabled = 0;
DRM_ERROR(__FUNCTION__); DRM_ERROR(__FUNCTION__);
} }
u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4); u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4);

View File

@ -1360,6 +1360,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
aperture_size = dev_priv->gtt.mappable_end; aperture_size = dev_priv->gtt.mappable_end;
dev_priv->gtt.mappable = AllocKernelSpace(8192);
if (dev_priv->gtt.mappable == NULL) {
ret = -EIO;
goto out_rmmap;
}
/* The i915 workqueue is primarily used for batched retirement of /* The i915 workqueue is primarily used for batched retirement of
* requests (and thus managing bo) once the task has been completed * requests (and thus managing bo) once the task has been completed

View File

@ -534,7 +534,7 @@ struct i915_gtt {
size_t stolen_size; /* Total size of stolen memory */ size_t stolen_size; /* Total size of stolen memory */
unsigned long mappable_end; /* End offset that we can CPU map */ unsigned long mappable_end; /* End offset that we can CPU map */
struct io_mapping *mappable; /* Mapping to our CPU mappable region */ void *mappable; /* Mapping to our CPU mappable region */
phys_addr_t mappable_base; /* PA of our GMADR */ phys_addr_t mappable_base; /* PA of our GMADR */
/** "Graphics Stolen Memory" holds the global PTEs */ /** "Graphics Stolen Memory" holds the global PTEs */
@ -620,7 +620,7 @@ struct i915_fbc {
int interval; int interval;
} *fbc_work; } *fbc_work;
enum no_fbc_reason { enum no_fbc_reason {
FBC_OK, /* FBC is enabled */ FBC_OK, /* FBC is enabled */
FBC_UNSUPPORTED, /* FBC is not supported by this chipset */ FBC_UNSUPPORTED, /* FBC is not supported by this chipset */
FBC_NO_OUTPUT, /* no outputs enabled to compress */ FBC_NO_OUTPUT, /* no outputs enabled to compress */

View File

@ -633,7 +633,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
loff_t offset, page_base; loff_t offset, page_base;
char __user *user_data; char __user *user_data;
int page_offset, page_length, ret; int page_offset, page_length, ret;
char *vaddr;
ret = i915_gem_obj_ggtt_pin(obj, 0, true, true); ret = i915_gem_obj_ggtt_pin(obj, 0, true, true);
if (ret) if (ret)
@ -647,14 +646,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
if (ret) if (ret)
goto out_unpin; goto out_unpin;
vaddr = AllocKernelSpace(4096); user_data = to_user_ptr(args->data_ptr);
if(vaddr == NULL)
{
ret = -ENOSPC;
goto out_unpin;
};
user_data = (char __user *) (uintptr_t) args->data_ptr;
remain = args->size; remain = args->size;
offset = i915_gem_obj_ggtt_offset(obj) + args->offset; offset = i915_gem_obj_ggtt_offset(obj) + args->offset;
@ -672,17 +664,15 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
if ((page_offset + remain) > PAGE_SIZE) if ((page_offset + remain) > PAGE_SIZE)
page_length = PAGE_SIZE - page_offset; page_length = PAGE_SIZE - page_offset;
MapPage(vaddr, dev_priv->gtt.mappable_base+page_base, PG_SW|PG_NOCACHE); MapPage(dev_priv->gtt.mappable, dev_priv->gtt.mappable_base+page_base, PG_SW);
memcpy(vaddr+page_offset, user_data, page_length); memcpy(dev_priv->gtt.mappable+page_offset, user_data, page_length);
remain -= page_length; remain -= page_length;
user_data += page_length; user_data += page_length;
offset += page_length; offset += page_length;
} }
FreeKernelSpace(vaddr);
out_unpin: out_unpin:
i915_gem_object_unpin(obj); i915_gem_object_unpin(obj);
out: out:
@ -706,7 +696,7 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length,
if (unlikely(page_do_bit17_swizzling)) if (unlikely(page_do_bit17_swizzling))
return -EINVAL; return -EINVAL;
vaddr = (char *)MapIoMem((addr_t)page, 4096, PG_SW|PG_NOCACHE); vaddr = (char *)MapIoMem((addr_t)page, 4096, PG_SW);
if (needs_clflush_before) if (needs_clflush_before)
drm_clflush_virt_range(vaddr + shmem_page_offset, drm_clflush_virt_range(vaddr + shmem_page_offset,
page_length); page_length);
@ -2082,15 +2072,24 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request)
kfree(request); kfree(request);
} }
static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv,
struct intel_ring_buffer *ring) struct intel_ring_buffer *ring)
{ {
u32 completed_seqno; u32 completed_seqno = ring->get_seqno(ring, false);
u32 acthd; u32 acthd = intel_ring_get_active_head(ring);
struct drm_i915_gem_request *request;
acthd = intel_ring_get_active_head(ring); list_for_each_entry(request, &ring->request_list, list) {
completed_seqno = ring->get_seqno(ring, false); if (i915_seqno_passed(completed_seqno, request->seqno))
continue;
i915_set_reset_status(ring, request, acthd);
}
}
static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv,
struct intel_ring_buffer *ring)
{
while (!list_empty(&ring->request_list)) { while (!list_empty(&ring->request_list)) {
struct drm_i915_gem_request *request; struct drm_i915_gem_request *request;
@ -2098,9 +2097,6 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
struct drm_i915_gem_request, struct drm_i915_gem_request,
list); list);
if (request->seqno > completed_seqno)
i915_set_reset_status(ring, request, acthd);
i915_gem_free_request(request); i915_gem_free_request(request);
} }
@ -2142,8 +2138,16 @@ void i915_gem_reset(struct drm_device *dev)
struct intel_ring_buffer *ring; struct intel_ring_buffer *ring;
int i; int i;
/*
* Before we free the objects from the requests, we need to inspect
* them for finding the guilty party. As the requests only borrow
* their reference to the objects, the inspection must be done first.
*/
for_each_ring(ring, dev_priv, i) for_each_ring(ring, dev_priv, i)
i915_gem_reset_ring_lists(dev_priv, ring); i915_gem_reset_ring_status(dev_priv, ring);
for_each_ring(ring, dev_priv, i)
i915_gem_reset_ring_cleanup(dev_priv, ring);
i915_gem_restore_fences(dev); i915_gem_restore_fences(dev);
} }

View File

@ -328,10 +328,8 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
{ {
struct drm_i915_file_private *file_priv = file->driver_priv; struct drm_i915_file_private *file_priv = file->driver_priv;
mutex_lock(&dev->struct_mutex);
idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
idr_destroy(&file_priv->context_idr); idr_destroy(&file_priv->context_idr);
mutex_unlock(&dev->struct_mutex);
} }
static struct i915_hw_context * static struct i915_hw_context *
@ -404,11 +402,21 @@ static int do_switch(struct i915_hw_context *to)
if (ret) if (ret)
return ret; return ret;
/* Clear this page out of any CPU caches for coherent swap-in/out. Note /*
* Pin can switch back to the default context if we end up calling into
* evict_everything - as a last ditch gtt defrag effort that also
* switches to the default context. Hence we need to reload from here.
*/
from = ring->last_context;
/*
* Clear this page out of any CPU caches for coherent swap-in/out. Note
* that thanks to write = false in this call and us not setting any gpu * that thanks to write = false in this call and us not setting any gpu
* write domains when putting a context object onto the active list * write domains when putting a context object onto the active list
* (when switching away from it), this won't block. * (when switching away from it), this won't block.
* XXX: We need a real interface to do this instead of trickery. */ *
* XXX: We need a real interface to do this instead of trickery.
*/
ret = i915_gem_object_set_to_gtt_domain(to->obj, false); ret = i915_gem_object_set_to_gtt_domain(to->obj, false);
if (ret) { if (ret) {
i915_gem_object_unpin(to->obj); i915_gem_object_unpin(to->obj);

View File

@ -190,6 +190,8 @@ static int
relocate_entry_cpu(struct drm_i915_gem_object *obj, relocate_entry_cpu(struct drm_i915_gem_object *obj,
struct drm_i915_gem_relocation_entry *reloc) struct drm_i915_gem_relocation_entry *reloc)
{ {
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t page_offset = offset_in_page(reloc->offset); uint32_t page_offset = offset_in_page(reloc->offset);
char *vaddr; char *vaddr;
int ret = -EINVAL; int ret = -EINVAL;
@ -198,10 +200,9 @@ relocate_entry_cpu(struct drm_i915_gem_object *obj,
if (ret) if (ret)
return ret; return ret;
vaddr = (char *)MapIoMem((addr_t)i915_gem_object_get_page(obj, vaddr = dev_priv->gtt.mappable+4096;
reloc->offset >> PAGE_SHIFT), 4096, 3); MapPage(vaddr,(addr_t)i915_gem_object_get_page(obj,reloc->offset >> PAGE_SHIFT), PG_SW);
*(uint32_t *)(vaddr + page_offset) = reloc->delta; *(uint32_t *)(vaddr + page_offset) = reloc->delta;
FreeKernelSpace(vaddr);
return 0; return 0;
} }
@ -226,12 +227,12 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
/* Map the page containing the relocation we're going to perform. */ /* Map the page containing the relocation we're going to perform. */
reloc->offset += i915_gem_obj_ggtt_offset(obj); reloc->offset += i915_gem_obj_ggtt_offset(obj);
reloc_page = (void*)MapIoMem(dev_priv->gtt.mappable_base + MapPage(dev_priv->gtt.mappable,dev_priv->gtt.mappable_base +
(reloc->offset & PAGE_MASK), 4096, 0x18|3); (reloc->offset & PAGE_MASK), PG_SW);
reloc_page = dev_priv->gtt.mappable;
reloc_entry = (uint32_t __iomem *) reloc_entry = (uint32_t __iomem *)
(reloc_page + offset_in_page(reloc->offset)); (reloc_page + offset_in_page(reloc->offset));
iowrite32(reloc->delta, reloc_entry); iowrite32(reloc->delta, reloc_entry);
FreeKernelSpace(reloc_page);
return 0; return 0;
} }
@ -343,7 +344,7 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj,
struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
int remain, ret; int remain, ret;
user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; user_relocs = to_user_ptr(entry->relocs_ptr);
remain = entry->relocation_count; remain = entry->relocation_count;
while (remain) { while (remain) {
@ -667,7 +668,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
u64 invalid_offset = (u64)-1; u64 invalid_offset = (u64)-1;
int j; int j;
user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr; user_relocs = to_user_ptr(exec[i].relocs_ptr);
if (copy_from_user(reloc+total, user_relocs, if (copy_from_user(reloc+total, user_relocs,
exec[i].relocation_count * sizeof(*reloc))) { exec[i].relocation_count * sizeof(*reloc))) {
@ -1260,8 +1261,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
return -ENOMEM; return -ENOMEM;
} }
ret = copy_from_user(exec2_list, ret = copy_from_user(exec2_list,
(struct drm_i915_relocation_entry __user *) to_user_ptr(args->buffers_ptr),
(uintptr_t) args->buffers_ptr,
sizeof(*exec2_list) * args->buffer_count); sizeof(*exec2_list) * args->buffer_count);
if (ret != 0) { if (ret != 0) {
DRM_DEBUG("copy %d exec entries failed %d\n", DRM_DEBUG("copy %d exec entries failed %d\n",
@ -1275,7 +1275,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
&dev_priv->gtt.base); &dev_priv->gtt.base);
if (!ret) { if (!ret) {
/* Copy the new buffer offsets back to the user's exec list. */ /* Copy the new buffer offsets back to the user's exec list. */
ret = copy_to_user((void __user *)(uintptr_t)args->buffers_ptr, ret = copy_to_user(to_user_ptr(args->buffers_ptr),
exec2_list, exec2_list,
sizeof(*exec2_list) * args->buffer_count); sizeof(*exec2_list) * args->buffer_count);
if (ret) { if (ret) {

View File

@ -831,7 +831,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
DRM_ERROR("Aliased PPGTT setup failed %d\n", ret); DRM_ERROR("Aliased PPGTT setup failed %d\n", ret);
drm_mm_takedown(&dev_priv->gtt.base.mm); drm_mm_takedown(&dev_priv->gtt.base.mm);
gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE; gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE;
} }
i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size);
} }

View File

@ -279,7 +279,7 @@ static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev,
DRM_DEBUG_KMS("uncleared fifo underrun on pipe %c\n", DRM_DEBUG_KMS("uncleared fifo underrun on pipe %c\n",
pipe_name(pipe)); pipe_name(pipe));
} }
} }
} }
/** /**
@ -1294,7 +1294,7 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
if (pch_iir & SDE_ERROR_CPT) if (pch_iir & SDE_ERROR_CPT)
cpt_serr_int_handler(dev); cpt_serr_int_handler(dev);
} }
static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir) static void ilk_display_irq_handler(struct drm_device *dev, u32 de_iir)
{ {
@ -1385,7 +1385,7 @@ static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir)
/* clear PCH hotplug event before clear CPU irq */ /* clear PCH hotplug event before clear CPU irq */
I915_WRITE(SDEIIR, pch_iir); I915_WRITE(SDEIIR, pch_iir);
} }
} }
static irqreturn_t ironlake_irq_handler(int irq, void *arg) static irqreturn_t ironlake_irq_handler(int irq, void *arg)
@ -1427,7 +1427,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
if (err_int_reenable) if (err_int_reenable)
ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
spin_unlock(&dev_priv->irq_lock); spin_unlock(&dev_priv->irq_lock);
} }
gt_iir = I915_READ(GTIIR); gt_iir = I915_READ(GTIIR);
if (gt_iir) { if (gt_iir) {
@ -1437,7 +1437,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
ilk_gt_irq_handler(dev, dev_priv, gt_iir); ilk_gt_irq_handler(dev, dev_priv, gt_iir);
I915_WRITE(GTIIR, gt_iir); I915_WRITE(GTIIR, gt_iir);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
} }
de_iir = I915_READ(DEIIR); de_iir = I915_READ(DEIIR);
if (de_iir) { if (de_iir) {
@ -1456,7 +1456,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
I915_WRITE(GEN6_PMIIR, pm_iir); I915_WRITE(GEN6_PMIIR, pm_iir);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
} }
} }
if (err_int_reenable) { if (err_int_reenable) {
spin_lock(&dev_priv->irq_lock); spin_lock(&dev_priv->irq_lock);
@ -2122,7 +2122,7 @@ static void gen5_gt_irq_preinstall(struct drm_device *dev)
I915_WRITE(GEN6_PMIMR, 0xffffffff); I915_WRITE(GEN6_PMIMR, 0xffffffff);
I915_WRITE(GEN6_PMIER, 0x0); I915_WRITE(GEN6_PMIER, 0x0);
POSTING_READ(GEN6_PMIER); POSTING_READ(GEN6_PMIER);
} }
} }
/* drm_dma.h hooks /* drm_dma.h hooks

View File

@ -961,12 +961,18 @@ void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
enum pipe pipe; enum pipe pipe;
struct intel_crtc *intel_crtc; struct intel_crtc *intel_crtc;
dev_priv->ddi_plls.spll_refcount = 0;
dev_priv->ddi_plls.wrpll1_refcount = 0;
dev_priv->ddi_plls.wrpll2_refcount = 0;
for_each_pipe(pipe) { for_each_pipe(pipe) {
intel_crtc = intel_crtc =
to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
if (!intel_crtc->active) if (!intel_crtc->active) {
intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE;
continue; continue;
}
intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv, intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv,
pipe); pipe);

View File

@ -1432,6 +1432,20 @@ static void i9xx_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
POSTING_READ(DPLL(pipe)); POSTING_READ(DPLL(pipe));
} }
static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
{
u32 val = 0;
/* Make sure the pipe isn't still relying on us */
assert_pipe_disabled(dev_priv, pipe);
/* Leave integrated clock source enabled */
if (pipe == PIPE_B)
val = DPLL_INTEGRATED_CRI_CLK_VLV;
I915_WRITE(DPLL(pipe), val);
POSTING_READ(DPLL(pipe));
}
void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port) void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port)
{ {
u32 port_mask; u32 port_mask;
@ -5281,7 +5295,7 @@ static void lpt_reset_fdi_mphy(struct drm_i915_private *dev_priv)
if (wait_for_atomic_us((I915_READ(SOUTH_CHICKEN2) & if (wait_for_atomic_us((I915_READ(SOUTH_CHICKEN2) &
FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100))
DRM_ERROR("FDI mPHY reset de-assert timeout\n"); DRM_ERROR("FDI mPHY reset de-assert timeout\n");
} }
/* WaMPhyProgramming:hsw */ /* WaMPhyProgramming:hsw */
static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv) static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv)
@ -5356,7 +5370,7 @@ static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv)
tmp &= ~(0xF << 28); tmp &= ~(0xF << 28);
tmp |= (4 << 28); tmp |= (4 << 28);
intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY);
} }
/* Implements 3 different sequences from BSpec chapter "Display iCLK /* Implements 3 different sequences from BSpec chapter "Display iCLK
* Programming" based on the parameters passed: * Programming" based on the parameters passed:
@ -5999,7 +6013,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
uint32_t val; uint32_t val;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head)
WARN(crtc->base.enabled, "CRTC for pipe %c enabled\n", WARN(crtc->active, "CRTC for pipe %c enabled\n",
pipe_name(crtc->pipe)); pipe_name(crtc->pipe));
WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n"); WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
@ -10515,7 +10529,9 @@ void intel_modeset_gem_init(struct drm_device *dev)
// intel_setup_overlay(dev); // intel_setup_overlay(dev);
mutex_lock(&dev->mode_config.mutex);
intel_modeset_setup_hw_state(dev, false); intel_modeset_setup_hw_state(dev, false);
mutex_unlock(&dev->mode_config.mutex);
} }
void intel_modeset_cleanup(struct drm_device *dev) void intel_modeset_cleanup(struct drm_device *dev)
@ -10589,14 +10605,15 @@ void intel_connector_attach_encoder(struct intel_connector *connector,
int intel_modeset_vga_set_state(struct drm_device *dev, bool state) int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL;
u16 gmch_ctrl; u16 gmch_ctrl;
pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl); pci_read_config_word(dev_priv->bridge_dev, reg, &gmch_ctrl);
if (state) if (state)
gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE; gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
else else
gmch_ctrl |= INTEL_GMCH_VGA_DISABLE; gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); pci_write_config_word(dev_priv->bridge_dev, reg, gmch_ctrl);
return 0; return 0;
} }

View File

@ -1767,7 +1767,7 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
intel_enable_dp(encoder); intel_enable_dp(encoder);
vlv_wait_port_ready(dev_priv, port); vlv_wait_port_ready(dev_priv, port);
} }
static void intel_dp_pre_pll_enable(struct intel_encoder *encoder) static void intel_dp_pre_pll_enable(struct intel_encoder *encoder)
{ {

View File

@ -2355,7 +2355,7 @@ static unsigned int ilk_cursor_wm_max(const struct drm_device *dev,
return level == 0 ? 63 : 255; return level == 0 ? 63 : 255;
else else
return level == 0 ? 31 : 63; return level == 0 ? 31 : 63;
} }
/* Calculate the maximum FBC watermark */ /* Calculate the maximum FBC watermark */
static unsigned int ilk_fbc_wm_max(void) static unsigned int ilk_fbc_wm_max(void)
@ -2374,7 +2374,7 @@ static void ilk_wm_max(struct drm_device *dev,
max->spr = ilk_plane_wm_max(dev, level, config, ddb_partitioning, true); max->spr = ilk_plane_wm_max(dev, level, config, ddb_partitioning, true);
max->cur = ilk_cursor_wm_max(dev, level, config); max->cur = ilk_cursor_wm_max(dev, level, config);
max->fbc = ilk_fbc_wm_max(); max->fbc = ilk_fbc_wm_max();
} }
static bool ilk_check_wm(int level, static bool ilk_check_wm(int level,
const struct hsw_wm_maximums *max, const struct hsw_wm_maximums *max,
@ -4629,8 +4629,6 @@ static void intel_gen6_powersave_work(struct work_struct *work)
rps.delayed_resume_work.work); rps.delayed_resume_work.work);
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
ENTER();
mutex_lock(&dev_priv->rps.hw_lock); mutex_lock(&dev_priv->rps.hw_lock);
if (IS_VALLEYVIEW(dev)) { if (IS_VALLEYVIEW(dev)) {
@ -4640,8 +4638,6 @@ static void intel_gen6_powersave_work(struct work_struct *work)
gen6_update_ring_freq(dev); gen6_update_ring_freq(dev);
} }
mutex_unlock(&dev_priv->rps.hw_lock); mutex_unlock(&dev_priv->rps.hw_lock);
LEAVE();
} }
void intel_enable_gt_powersave(struct drm_device *dev) void intel_enable_gt_powersave(struct drm_device *dev)

View File

@ -483,7 +483,7 @@ init_pipe_control(struct intel_ring_buffer *ring)
goto err_unref; goto err_unref;
ring->scratch.gtt_offset = i915_gem_obj_ggtt_offset(ring->scratch.obj); ring->scratch.gtt_offset = i915_gem_obj_ggtt_offset(ring->scratch.obj);
ring->scratch.cpu_page = (void*)MapIoMem((addr_t)sg_page(ring->scratch.obj->pages->sgl),4096, PG_SW); ring->scratch.cpu_page = (void*)MapIoMem((addr_t)sg_page(ring->scratch.obj->pages->sgl),4096, PG_SW|0x100);
if (ring->scratch.cpu_page == NULL) { if (ring->scratch.cpu_page == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_unpin; goto err_unpin;
@ -1182,7 +1182,7 @@ static int init_status_page(struct intel_ring_buffer *ring)
} }
ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj); ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(obj);
ring->status_page.page_addr = (void*)MapIoMem((addr_t)sg_page(obj->pages->sgl),4096,PG_SW); ring->status_page.page_addr = (void*)MapIoMem((addr_t)sg_page(obj->pages->sgl),4096,PG_SW|0x100);
if (ring->status_page.page_addr == NULL) { if (ring->status_page.page_addr == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_unpin; goto err_unpin;

View File

@ -913,10 +913,6 @@ int i915_mask_update(struct drm_device *dev, void *data,
safe_sti(ifl); safe_sti(ifl);
ret = i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false); ret = i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false);
if(ret != 0 )
{
dbgprintf("%s: i915_gem_object_set_to_gtt_domain failed\n", __FUNCTION__);
};
} }
err2: err2:
@ -927,6 +923,212 @@ err1:
return ret; return ret;
} }
int i915_mask_update_ex(struct drm_device *dev, void *data,
struct drm_file *file)
{
struct drm_i915_mask_update *mask = data;
struct drm_gem_object *obj;
static unsigned int mask_seqno[256];
static warn_count;
rect_t win;
u32 winw,winh;
u32 ml,mt,mr,mb;
u32 slot;
int ret = 0;
slot = *((u8*)CURRENT_TASK);
if( mask_seqno[slot] == os_display->mask_seqno)
return 0;
GetWindowRect(&win);
win.right+= 1;
win.bottom+= 1;
winw = win.right - win.left;
winh = win.bottom - win.top;
if(mask->dx >= winw ||
mask->dy >= winh)
return 1;
ml = win.left + mask->dx;
mt = win.top + mask->dy;
mr = ml + mask->width;
mb = mt + mask->height;
if( ml >= win.right || mt >= win.bottom ||
mr < win.left || mb < win.top )
return 1;
if( mr > win.right )
mr = win.right;
if( mb > win.bottom )
mb = win.bottom;
mask->width = mr - ml;
mask->height = mb - mt;
if( mask->width == 0 ||
mask->height== 0 )
return 1;
obj = drm_gem_object_lookup(dev, file, mask->handle);
if (obj == NULL)
return -ENOENT;
if (!obj->filp) {
drm_gem_object_unreference_unlocked(obj);
return -EINVAL;
}
#if 1
if(warn_count < 1000)
{
printf("left %d top %d right %d bottom %d\n",
ml, mt, mr, mb);
warn_count++;
};
#endif
#if 1
{
u8* src_offset;
u8* dst_offset;
u32 ifl;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
goto err1;
i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
src_offset = (u8*)( mt*os_display->width + ml);
src_offset+= get_display_map();
dst_offset = (u8*)mask->bo_map;
u32_t tmp_h = mask->height;
ifl = safe_cli();
{
mask_seqno[slot] = os_display->mask_seqno;
slot|= (slot<<8)|(slot<<16)|(slot<<24);
__asm__ __volatile__ (
"movd %[slot], %%xmm6 \n"
"punpckldq %%xmm6, %%xmm6 \n"
"punpcklqdq %%xmm6, %%xmm6 \n"
:: [slot] "m" (slot)
:"xmm6");
while( tmp_h--)
{
int tmp_w = mask->width;
u8* tmp_src = src_offset;
u8* tmp_dst = dst_offset;
src_offset+= os_display->width;
dst_offset+= mask->bo_pitch;
while(tmp_w >= 64)
{
__asm__ __volatile__ (
"movdqu (%0), %%xmm0 \n"
"movdqu 16(%0), %%xmm1 \n"
"movdqu 32(%0), %%xmm2 \n"
"movdqu 48(%0), %%xmm3 \n"
"pcmpeqb %%xmm6, %%xmm0 \n"
"pcmpeqb %%xmm6, %%xmm1 \n"
"pcmpeqb %%xmm6, %%xmm2 \n"
"pcmpeqb %%xmm6, %%xmm3 \n"
"movdqa %%xmm0, (%%edi) \n"
"movdqa %%xmm1, 16(%%edi) \n"
"movdqa %%xmm2, 32(%%edi) \n"
"movdqa %%xmm3, 48(%%edi) \n"
:: "r" (tmp_src), "D" (tmp_dst)
:"xmm0","xmm1","xmm2","xmm3");
tmp_w -= 64;
tmp_src += 64;
tmp_dst += 64;
}
if( tmp_w >= 32 )
{
__asm__ __volatile__ (
"movdqu (%0), %%xmm0 \n"
"movdqu 16(%0), %%xmm1 \n"
"pcmpeqb %%xmm6, %%xmm0 \n"
"pcmpeqb %%xmm6, %%xmm1 \n"
"movdqa %%xmm0, (%%edi) \n"
"movdqa %%xmm1, 16(%%edi) \n"
:: "r" (tmp_src), "D" (tmp_dst)
:"xmm0","xmm1");
tmp_w -= 32;
tmp_src += 32;
tmp_dst += 32;
}
if( tmp_w >= 16 )
{
__asm__ __volatile__ (
"movdqu (%0), %%xmm0 \n"
"pcmpeqb %%xmm6, %%xmm0 \n"
"movdqa %%xmm0, (%%edi) \n"
:: "r" (tmp_src), "D" (tmp_dst)
:"xmm0");
tmp_w -= 16;
tmp_src += 16;
tmp_dst += 16;
}
if( tmp_w >= 8 )
{
__asm__ __volatile__ (
"movq (%0), %%xmm0 \n"
"pcmpeqb %%xmm6, %%xmm0 \n"
"movq %%xmm0, (%%edi) \n"
:: "r" (tmp_src), "D" (tmp_dst)
:"xmm0");
tmp_w -= 8;
tmp_src += 8;
tmp_dst += 8;
}
if( tmp_w >= 4 )
{
__asm__ __volatile__ (
"movd (%0), %%xmm0 \n"
"pcmpeqb %%xmm6, %%xmm0 \n"
"movd %%xmm0, (%%edi) \n"
:: "r" (tmp_src), "D" (tmp_dst)
:"xmm0");
tmp_w -= 4;
tmp_src += 4;
tmp_dst += 4;
}
while(tmp_w--)
*tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
};
};
safe_sti(ifl);
i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false);
}
#endif
err2:
mutex_unlock(&dev->struct_mutex);
err1:
drm_gem_object_unreference(obj);
return ret;
}

View File

@ -266,7 +266,7 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
#define SRV_FBINFO 43 #define SRV_FBINFO 43
#define SRV_MASK_UPDATE 44 #define SRV_MASK_UPDATE 44
#define SRV_MASK_UPDATE_EX 45
#define check_input(size) \ #define check_input(size) \
if( unlikely((inp==NULL)||(io->inp_size != (size))) ) \ if( unlikely((inp==NULL)||(io->inp_size != (size))) ) \
@ -443,6 +443,10 @@ int _stdcall display_handler(ioctl_t *io)
case SRV_MASK_UPDATE: case SRV_MASK_UPDATE:
retval = i915_mask_update(main_device, inp, file); retval = i915_mask_update(main_device, inp, file);
break; break;
case SRV_MASK_UPDATE_EX:
retval = i915_mask_update_ex(main_device, inp, file);
break;
}; };
return retval; return retval;