/drivers/video/drm/drm_cache.c |
---|
29,6 → 29,7 |
*/ |
#include <linux/export.h> |
#include <linux/scatterlist.h> |
#include <drm/drmP.h> |
extern int x86_clflush_size; |
37,6 → 38,7 |
{ |
asm volatile("clflush %0" : "+m" (*(volatile char*)__p)); |
} |
#if 0 |
static void |
drm_clflush_page(struct page *page) |
75,12 → 77,12 |
void |
drm_clflush_pages(struct page *pages[], unsigned long num_pages) |
{ |
uint8_t *page_virtual; |
uint8_t *pva; |
unsigned int i, j; |
page_virtual = AllocKernelSpace(4096); |
pva = AllocKernelSpace(4096); |
if(page_virtual != NULL) |
if(pva != NULL) |
{ |
dma_addr_t *src, *dst; |
u32 count; |
88,44 → 90,45 |
for (i = 0; i < num_pages; i++) |
{ |
mb(); |
// asm volatile("mfence"); |
MapPage(page_virtual,*pages++, 0x001); |
MapPage(pva, page_to_phys(pages[i]), 0x001); |
for (j = 0; j < PAGE_SIZE; j += x86_clflush_size) |
clflush(page_virtual + j); |
mb(); |
clflush(pva + j); |
} |
FreeKernelSpace(page_virtual); |
FreeKernelSpace(pva); |
} |
mb(); |
} |
EXPORT_SYMBOL(drm_clflush_pages); |
#if 0 |
void |
drm_clflush_sg(struct sg_table *st) |
{ |
#if defined(CONFIG_X86) |
if (cpu_has_clflush) { |
struct sg_page_iter sg_iter; |
struct page *page; |
uint8_t *pva; |
unsigned int i; |
pva = AllocKernelSpace(4096); |
if( pva != NULL) |
{ |
mb(); |
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) |
drm_clflush_page(sg_page_iter_page(&sg_iter)); |
mb(); |
{ |
page = sg_page_iter_page(&sg_iter); |
return; |
} |
MapPage(pva,page_to_phys(page), 0x001); |
if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) |
printk(KERN_ERR "Timed out waiting for cache flush.\n"); |
#else |
printk(KERN_ERR "Architecture has no drm_cache.c support\n"); |
WARN_ON_ONCE(1); |
#endif |
for (i = 0; i < PAGE_SIZE; i += x86_clflush_size) |
clflush(pva + i); |
}; |
FreeKernelSpace(pva); |
}; |
mb(); |
} |
EXPORT_SYMBOL(drm_clflush_sg); |
#if 0 |
void |
drm_clflush_virt_range(char *addr, unsigned long length) |
{ |
/drivers/video/drm/drm_irq.c |
---|
84,6 → 84,8 |
unsigned long sh_flags = 0; |
char *irqname; |
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) |
return -EINVAL; |
if (drm_dev_to_irq(dev) == 0) |
return -EINVAL; |
202,8 → 204,99 |
crtc->base.id, (int) dotclock/1000, (int) framedur_ns, |
(int) linedur_ns, (int) pixeldur_ns); |
} |
EXPORT_SYMBOL(drm_calc_timestamping_constants); |
/** |
* drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms |
* drivers. Implements calculation of exact vblank timestamps from |
* given drm_display_mode timings and current video scanout position |
* of a crtc. This can be called from within get_vblank_timestamp() |
* implementation of a kms driver to implement the actual timestamping. |
* |
* Should return timestamps conforming to the OML_sync_control OpenML |
* extension specification. The timestamp corresponds to the end of |
* the vblank interval, aka start of scanout of topmost-leftmost display |
* pixel in the following video frame. |
* |
* Requires support for optional dev->driver->get_scanout_position() |
* in kms driver, plus a bit of setup code to provide a drm_display_mode |
* that corresponds to the true scanout timing. |
* |
* The current implementation only handles standard video modes. It |
* returns as no operation if a doublescan or interlaced video mode is |
* active. Higher level code is expected to handle this. |
* |
* @dev: DRM device. |
* @crtc: Which crtc's vblank timestamp to retrieve. |
* @max_error: Desired maximum allowable error in timestamps (nanosecs). |
* On return contains true maximum error of timestamp. |
* @vblank_time: Pointer to struct timeval which should receive the timestamp. |
* @flags: Flags to pass to driver: |
* 0 = Default. |
* DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. |
* @refcrtc: drm_crtc* of crtc which defines scanout timing. |
* |
* Returns negative value on error, failure or if not supported in current |
* video mode: |
* |
* -EINVAL - Invalid crtc. |
* -EAGAIN - Temporary unavailable, e.g., called before initial modeset. |
* -ENOTSUPP - Function not supported in current display mode. |
* -EIO - Failed, e.g., due to failed scanout position query. |
* |
* Returns or'ed positive status flags on success: |
* |
* DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. |
* DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. |
* |
*/ |
int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, |
int *max_error, |
struct timeval *vblank_time, |
unsigned flags, |
struct drm_crtc *refcrtc) |
{ |
// ktime_t stime, etime, mono_time_offset; |
struct timeval tv_etime; |
struct drm_display_mode *mode; |
int vbl_status, vtotal, vdisplay; |
int vpos, hpos, i; |
s64 framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; |
bool invbl; |
if (crtc < 0 || crtc >= dev->num_crtcs) { |
DRM_ERROR("Invalid crtc %d\n", crtc); |
return -EINVAL; |
} |
/* Scanout position query not supported? Should not happen. */ |
if (!dev->driver->get_scanout_position) { |
DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); |
return -EIO; |
} |
mode = &refcrtc->hwmode; |
vtotal = mode->crtc_vtotal; |
vdisplay = mode->crtc_vdisplay; |
/* Durations of frames, lines, pixels in nanoseconds. */ |
framedur_ns = refcrtc->framedur_ns; |
linedur_ns = refcrtc->linedur_ns; |
pixeldur_ns = refcrtc->pixeldur_ns; |
/* If mode timing undefined, just return as no-op: |
* Happens during initial modesetting of a crtc. |
*/ |
if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { |
DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); |
return -EAGAIN; |
} |
return -EIO; |
} |
EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); |
/** |
* drm_vblank_pre_modeset - account for vblanks across mode sets |
* @dev: DRM device |
/drivers/video/drm/i915/Makefile |
---|
81,6 → 81,7 |
../hdmi.c \ |
Gtt/intel-agp.c \ |
Gtt/intel-gtt.c \ |
../drm_cache.c \ |
../drm_global.c \ |
../drm_drv.c \ |
../drm_vma_manager.c \ |
/drivers/video/drm/i915/i915_dma.c |
---|
1215,6 → 1215,7 |
cleanup_gem: |
mutex_lock(&dev->struct_mutex); |
i915_gem_cleanup_ringbuffer(dev); |
i915_gem_context_fini(dev); |
mutex_unlock(&dev->struct_mutex); |
i915_gem_cleanup_aliasing_ppgtt(dev); |
cleanup_irq: |
1421,12 → 1422,19 |
if (HAS_POWER_WELL(dev)) |
i915_init_power_well(dev); |
if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
ret = i915_load_modeset_init(dev); |
if (ret < 0) { |
DRM_ERROR("failed to init modeset\n"); |
goto out_gem_unload; |
} |
} else { |
/* Start out suspended in ums mode. */ |
dev_priv->ums.mm_suspended = 1; |
} |
if (INTEL_INFO(dev)->num_pipes) { |
/* Must be done after probing outputs */ |
intel_opregion_init(dev); |
/drivers/video/drm/i915/i915_drv.c |
---|
637,7 → 637,8 |
mutex_lock(&dev->struct_mutex); |
i915_gem_restore_gtt_mappings(dev); |
mutex_unlock(&dev->struct_mutex); |
} |
} else if (drm_core_check_feature(dev, DRIVER_MODESET)) |
i915_check_and_clear_faults(dev); |
__i915_drm_thaw(dev); |
949,14 → 950,9 |
DRM_INFO("device %x:%x\n", device.pci_dev.vendor, |
device.pci_dev.device); |
/* |
if (intel_info->gen != 3) { |
} else if (init_agp() != 0) { |
DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); |
return -ENODEV; |
} |
*/ |
driver.driver_features |= DRIVER_MODESET; |
err = drm_get_pci_dev(&device.pci_dev, ent, &driver); |
return err; |
/drivers/video/drm/i915/i915_gem.c |
---|
1292,11 → 1292,43 |
return ret; |
} |
/** |
* Called when user space has done writes to this buffer |
*/ |
int |
i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, |
struct drm_file *file) |
{ |
struct drm_i915_gem_sw_finish *args = data; |
struct drm_i915_gem_object *obj; |
int ret = 0; |
if(args->handle == -2) |
{ |
printf("%s handle %d\n", __FUNCTION__, args->handle); |
return 0; |
} |
ret = i915_mutex_lock_interruptible(dev); |
if (ret) |
return ret; |
obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
if (&obj->base == NULL) { |
ret = -ENOENT; |
goto unlock; |
} |
/* Pinned buffers may be scanout, so flush the cache */ |
if (obj->pin_display) |
i915_gem_object_flush_cpu_write_domain(obj, true); |
drm_gem_object_unreference(&obj->base); |
unlock: |
mutex_unlock(&dev->struct_mutex); |
return ret; |
} |
/** |
* Maps the contents of an object, returning the address it is mapped |
* into. |
3115,55 → 3147,10 |
*/ |
if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) |
return false; |
#if 0 |
if(obj->mapped != NULL) |
{ |
uint8_t *page_virtual; |
unsigned int i; |
page_virtual = obj->mapped; |
asm volatile("mfence"); |
for (i = 0; i < obj->base.size; i += x86_clflush_size) |
clflush(page_virtual + i); |
asm volatile("mfence"); |
} |
else |
{ |
uint8_t *page_virtual; |
unsigned int i; |
page_virtual = AllocKernelSpace(obj->base.size); |
if(page_virtual != NULL) |
{ |
dma_addr_t *src, *dst; |
u32 count; |
trace_i915_gem_object_clflush(obj); |
drm_clflush_sg(obj->pages); |
#define page_tabs 0xFDC00000 /* really dirty hack */ |
src = obj->pages.page; |
dst = &((dma_addr_t*)page_tabs)[(u32_t)page_virtual >> 12]; |
count = obj->base.size/4096; |
while(count--) |
{ |
*dst++ = (0xFFFFF000 & *src++) | 0x001 ; |
}; |
asm volatile("mfence"); |
for (i = 0; i < obj->base.size; i += x86_clflush_size) |
clflush(page_virtual + i); |
asm volatile("mfence"); |
FreeKernelSpace(page_virtual); |
} |
else |
{ |
asm volatile ( |
"mfence \n" |
"wbinvd \n" /* this is really ugly */ |
"mfence"); |
} |
} |
#endif |
return true; |
} |
/drivers/video/drm/i915/i915_irq.c |
---|
2385,6 → 2385,8 |
if (!dev_priv) |
return; |
del_timer_sync(&dev_priv->hotplug_reenable_timer); |
for_each_pipe(pipe) |
I915_WRITE(PIPESTAT(pipe), 0xffff); |
2406,6 → 2408,8 |
if (!dev_priv) |
return; |
del_timer_sync(&dev_priv->hotplug_reenable_timer); |
I915_WRITE(HWSTAM, 0xffffffff); |
I915_WRITE(DEIMR, 0xffffffff); |
2788,6 → 2792,8 |
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
int pipe; |
del_timer_sync(&dev_priv->hotplug_reenable_timer); |
if (I915_HAS_HOTPLUG(dev)) { |
I915_WRITE(PORT_HOTPLUG_EN, 0); |
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
3036,6 → 3042,8 |
if (!dev_priv) |
return; |
del_timer_sync(&dev_priv->hotplug_reenable_timer); |
I915_WRITE(PORT_HOTPLUG_EN, 0); |
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
3098,18 → 3106,34 |
setup_timer(&dev_priv->hotplug_reenable_timer, i915_reenable_hotplug_timer_func, |
(unsigned long) dev_priv); |
dev->driver->get_vblank_counter = i915_get_vblank_counter; |
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { |
dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ |
dev->driver->get_vblank_counter = gm45_get_vblank_counter; |
} |
// dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
if (drm_core_check_feature(dev, DRIVER_MODESET)) |
dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; |
else |
dev->driver->get_vblank_timestamp = NULL; |
dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
if (IS_VALLEYVIEW(dev)) { |
dev->driver->irq_handler = valleyview_irq_handler; |
dev->driver->irq_preinstall = valleyview_irq_preinstall; |
dev->driver->irq_postinstall = valleyview_irq_postinstall; |
dev->driver->irq_uninstall = valleyview_irq_uninstall; |
dev->driver->enable_vblank = valleyview_enable_vblank; |
dev->driver->disable_vblank = valleyview_disable_vblank; |
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
} else if (HAS_PCH_SPLIT(dev)) { |
dev->driver->irq_handler = ironlake_irq_handler; |
dev->driver->irq_preinstall = ironlake_irq_preinstall; |
dev->driver->irq_postinstall = ironlake_irq_postinstall; |
dev->driver->irq_uninstall = ironlake_irq_uninstall; |
dev->driver->enable_vblank = ironlake_enable_vblank; |
dev->driver->disable_vblank = ironlake_disable_vblank; |
dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; |
} else { |
if (INTEL_INFO(dev)->gen == 2) { |
3116,14 → 3140,18 |
} else if (INTEL_INFO(dev)->gen == 3) { |
dev->driver->irq_preinstall = i915_irq_preinstall; |
dev->driver->irq_postinstall = i915_irq_postinstall; |
dev->driver->irq_uninstall = i915_irq_uninstall; |
dev->driver->irq_handler = i915_irq_handler; |
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
} else { |
dev->driver->irq_preinstall = i965_irq_preinstall; |
dev->driver->irq_postinstall = i965_irq_postinstall; |
dev->driver->irq_uninstall = i965_irq_uninstall; |
dev->driver->irq_handler = i965_irq_handler; |
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
} |
dev->driver->enable_vblank = i915_enable_vblank; |
dev->driver->disable_vblank = i915_disable_vblank; |
} |
} |
/drivers/video/drm/i915/i915_trace.h |
---|
3,9 → 3,7 |
//#include <linux/stringify.h> |
#include <linux/types.h> |
//#include <linux/tracepoint.h> |
//#define WARN_ON(x) |
#define trace_i915_gem_object_create(x) |
#define trace_i915_gem_object_destroy(x) |
27,5 → 25,7 |
#define trace_i915_gem_ring_dispatch(a, b, c) |
#define trace_i915_vma_bind(a, b) |
#define trace_i915_vma_unbind(a) |
#define trace_i915_gem_object_clflush(a) |
#define trace_i915_reg_rw(a, b, c, d, e) |
#endif |
/drivers/video/drm/i915/intel_display.c |
---|
6161,7 → 6161,7 |
if (dev_priv->pc8.disable_count != 1) |
return; |
// cancel_delayed_work_sync(&dev_priv->pc8.enable_work); |
cancel_delayed_work_sync(&dev_priv->pc8.enable_work); |
if (!dev_priv->pc8.enabled) |
return; |
7566,7 → 7566,7 |
spin_unlock_irqrestore(&dev->event_lock, flags); |
if (work) { |
// cancel_work_sync(&work->work); |
cancel_work_sync(&work->work); |
kfree(work); |
} |
/drivers/video/drm/i915/intel_dp.c |
---|
3053,7 → 3053,7 |
i2c_del_adapter(&intel_dp->adapter); |
drm_encoder_cleanup(encoder); |
if (is_edp(intel_dp)) { |
// cancel_delayed_work_sync(&intel_dp->panel_vdd_work); |
cancel_delayed_work_sync(&intel_dp->panel_vdd_work); |
mutex_lock(&dev->mode_config.mutex); |
ironlake_panel_vdd_off_sync(intel_dp); |
mutex_unlock(&dev->mode_config.mutex); |
3493,7 → 3493,7 |
if (!intel_edp_init_connector(intel_dp, intel_connector)) { |
i2c_del_adapter(&intel_dp->adapter); |
if (is_edp(intel_dp)) { |
// cancel_delayed_work_sync(&intel_dp->panel_vdd_work); |
cancel_delayed_work_sync(&intel_dp->panel_vdd_work); |
mutex_lock(&dev->mode_config.mutex); |
ironlake_panel_vdd_off_sync(intel_dp); |
mutex_unlock(&dev->mode_config.mutex); |
/drivers/video/drm/i915/intel_panel.c |
---|
490,6 → 490,17 |
struct drm_i915_private *dev_priv = dev->dev_private; |
unsigned long flags; |
/* |
* Do not disable backlight on the vgaswitcheroo path. When switching |
* away from i915, the other client may depend on i915 to handle the |
* backlight. This will leave the backlight on unnecessarily when |
* another client is not activated. |
*/ |
if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) { |
DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n"); |
return; |
} |
spin_lock_irqsave(&dev_priv->backlight.lock, flags); |
dev_priv->backlight.enabled = false; |
/drivers/video/drm/i915/intel_pm.c |
---|
363,9 → 363,9 |
* dev_priv->fbc.fbc_work, so we can perform the cancellation |
* entirely asynchronously. |
*/ |
// if (cancel_delayed_work(&dev_priv->fbc_work->work)) |
if (cancel_delayed_work(&dev_priv->fbc.fbc_work->work)) |
/* tasklet was killed before being run, clean up */ |
// kfree(dev_priv->fbc_work); |
kfree(dev_priv->fbc.fbc_work); |
/* Mark the work as no longer wanted so that if it does |
* wake-up (because the work was already running and waiting |
4608,8 → 4608,11 |
if (IS_IRONLAKE_M(dev)) { |
ironlake_disable_drps(dev); |
ironlake_disable_rc6(dev); |
} else if (INTEL_INFO(dev)->gen >= 6 && !IS_VALLEYVIEW(dev)) { |
// cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); |
} else if (INTEL_INFO(dev)->gen >= 6) { |
cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); |
cancel_work_sync(&dev_priv->rps.work); |
if (IS_VALLEYVIEW(dev)) |
cancel_delayed_work_sync(&dev_priv->rps.vlv_work); |
mutex_lock(&dev_priv->rps.hw_lock); |
if (IS_VALLEYVIEW(dev)) |
valleyview_disable_rps(dev); |
/drivers/video/drm/i915/intel_ringbuffer.c |
---|
1247,8 → 1247,8 |
} |
obj = NULL; |
if (!HAS_LLC(dev)) |
obj = i915_gem_object_create_stolen(dev, ring->size); |
// if (!HAS_LLC(dev)) |
// obj = i915_gem_object_create_stolen(dev, ring->size); |
if (obj == NULL) |
obj = i915_gem_alloc_object(dev, ring->size); |
if (obj == NULL) { |
/drivers/video/drm/i915/intel_uncore.c |
---|
364,6 → 364,7 |
val = __raw_i915_read##x(dev_priv, reg); \ |
} \ |
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ |
trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \ |
return val; \ |
} |
377,6 → 378,7 |
void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val, bool trace) { \ |
unsigned long irqflags; \ |
u32 __fifo_ret = 0; \ |
trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \ |
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \ |
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ |
/drivers/video/drm/i915/kms_display.c |
---|
197,7 → 197,6 |
{ |
os_display->width = fb->width; |
os_display->height = fb->height; |
os_display->pitch = fb->pitches[0]; |
os_display->vrefresh = drm_mode_vrefresh(mode); |
sysSetScreen(fb->width, fb->height, fb->pitches[0]); |
209,7 → 208,6 |
DRM_ERROR("failed to set mode %d_%d on crtc %p\n", |
fb->width, fb->height, crtc); |
return ret; |
} |
381,12 → 379,9 |
{ |
struct drm_display_mode *mode; |
// connector->funcs->fill_modes(connector, dev->mode_config.max_width, |
// dev->mode_config.max_height); |
list_for_each_entry(mode, &connector->modes, head) |
{ |
printf("check mode w:%d h:%d %dHz\n", |
dbgprintf("check mode w:%d h:%d %dHz\n", |
drm_mode_width(mode), drm_mode_height(mode), |
drm_mode_vrefresh(mode)); |
/drivers/video/drm/i915/main.c |
---|
184,15 → 184,10 |
if( cmdline && *cmdline ) |
parse_cmdline(cmdline, cmdtable, log, &usermode); |
if(!dbg_open(log)) |
if( *log && !dbg_open(log)) |
{ |
strcpy(log, "/tmp1/1/i915.log"); |
if(!dbg_open(log)) |
{ |
printf("Can't open %s\nExit\n", log); |
return 0; |
}; |
} |
cpu_detect(); |
622,7 → 617,9 |
while( (c = *p++) == ' '); |
p--; |
while( (c = *log++ = *p++) && (c != ' ')); |
while((c = *p++) && (c != ' ')) |
*log++ = c; |
*log = 0; |
return p; |
643,7 → 640,6 |
{ |
p1+= table->size; |
*table->val = my_atoi(&p1); |
// printf("%s %d\n", table->key, *table->val); |
} |
table++; |
} |
696,3 → 692,5 |
: "dx", "di"); |
return __res; |
} |