forked from KolibriOS/kolibrios
i915: 3.12.9
git-svn-id: svn://kolibrios.org@4539 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
0c4f98c413
commit
da432de99f
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user