i915: new irq handling code

git-svn-id: svn://kolibrios.org@3051 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2012-11-17 06:19:51 +00:00
parent dd73e1caef
commit dafa1f1f2e
3 changed files with 90 additions and 116 deletions

View File

@ -353,8 +353,6 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
struct drm_encoder *encoder; struct drm_encoder *encoder;
bool ret = true; bool ret = true;
ENTER();
crtc->enabled = drm_helper_crtc_in_use(crtc); crtc->enabled = drm_helper_crtc_in_use(crtc);
if (!crtc->enabled) if (!crtc->enabled)
return true; return true;
@ -469,8 +467,6 @@ done:
crtc->y = saved_y; crtc->y = saved_y;
} }
LEAVE();
return ret; return ret;
} }
EXPORT_SYMBOL(drm_crtc_helper_set_mode); EXPORT_SYMBOL(drm_crtc_helper_set_mode);

View File

@ -27,7 +27,6 @@ void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap)
bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU; bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
mutex_lock(&main_device->struct_mutex); mutex_lock(&main_device->struct_mutex);
drm_gem_object_unreference(&bitmap->obj->base); drm_gem_object_unreference(&bitmap->obj->base);
mutex_unlock(&main_device->struct_mutex); mutex_unlock(&main_device->struct_mutex);
@ -210,6 +209,11 @@ int create_surface(struct drm_device *dev, struct io_call_10 *pbitmap)
MapPage(vaddr, page, 0x207); //map as shared page MapPage(vaddr, page, 0x207); //map as shared page
}; };
for(;i < max_count; i++, vaddr+= PAGE_SIZE)
{
MapPage(vaddr, 0, 0); //map as shared page
};
bitmap->page_count = page_count; bitmap->page_count = page_count;
bitmap->max_count = max_count; bitmap->max_count = max_count;
}; };
@ -339,13 +343,7 @@ int resize_surface(struct io_call_14 *pbitmap)
DRM_DEBUG("new width %d height %d pitch %d size %d\n", DRM_DEBUG("new width %d height %d pitch %d size %d\n",
width, height, pitch, size); width, height, pitch, size);
if( page_count == bitmap->page_count ) if(page_count > bitmap->page_count)
{
bitmap->width = width;
bitmap->height = height;
bitmap->pitch = pitch;
}
else if(page_count > bitmap->page_count)
{ {
char *vaddr = bitmap->uaddr + PAGE_SIZE * bitmap->page_count; char *vaddr = bitmap->uaddr + PAGE_SIZE * bitmap->page_count;
@ -366,8 +364,6 @@ int resize_surface(struct io_call_14 *pbitmap)
DRM_DEBUG("%s alloc %d pages\n", __FUNCTION__, DRM_DEBUG("%s alloc %d pages\n", __FUNCTION__,
page_count - bitmap->page_count); page_count - bitmap->page_count);
// mutex_lock(&main_device->struct_mutex);
i915_gem_object_unpin(bitmap->obj); i915_gem_object_unpin(bitmap->obj);
i915_gem_object_unbind(bitmap->obj); i915_gem_object_unbind(bitmap->obj);
bitmap->obj->base.size = size; bitmap->obj->base.size = size;
@ -376,23 +372,48 @@ int resize_surface(struct io_call_14 *pbitmap)
ret = i915_gem_object_pin(bitmap->obj, PAGE_SIZE, true,true); ret = i915_gem_object_pin(bitmap->obj, PAGE_SIZE, true,true);
if (ret) if (ret)
goto err4; goto err4;
// mutex_unlock(&main_device->struct_mutex);
bitmap->page_count = page_count; bitmap->page_count = page_count;
bitmap->width = width; bitmap->gaddr = bitmap->obj->gtt_offset;
bitmap->height = height; }
bitmap->pitch = pitch; else if(page_count < bitmap->page_count)
{
char *vaddr = bitmap->uaddr + PAGE_SIZE * page_count;
i915_gem_object_unpin(bitmap->obj);
i915_gem_object_unbind(bitmap->obj);
pages = bitmap->obj->allocated_pages;
DRM_DEBUG("old pages %d new_pages %d vaddr %x\n",
bitmap->page_count, page_count, vaddr);
for(i = page_count; i < bitmap->page_count; i++, vaddr+= PAGE_SIZE)
{
MapPage(vaddr, 0, 0); //unmap
FreePage(pages[i]);
pages[i] = 0;
};
DRM_DEBUG("%s release %d pages\n", __FUNCTION__,
bitmap->page_count - page_count);
bitmap->obj->base.size = size;
bitmap->obj->pages.nents = page_count;
ret = i915_gem_object_pin(bitmap->obj, PAGE_SIZE, true,true);
if (ret)
goto err3;
bitmap->page_count = page_count;
bitmap->gaddr = bitmap->obj->gtt_offset; bitmap->gaddr = bitmap->obj->gtt_offset;
}; };
if(ret != 0 ) bitmap->width = width;
{ bitmap->height = height;
pbitmap->data = NULL; bitmap->pitch = pitch;
pbitmap->pitch = 0;
dbgprintf("%s fail\n", __FUNCTION__);
return ret;
};
pbitmap->data = bitmap->uaddr; pbitmap->data = bitmap->uaddr;
pbitmap->pitch = bitmap->pitch; pbitmap->pitch = bitmap->pitch;
@ -403,6 +424,7 @@ err4:
while (i-- > bitmap->page_count) while (i-- > bitmap->page_count)
FreePage(pages[i]); FreePage(pages[i]);
err3:
return -1; return -1;
}; };
@ -447,6 +469,8 @@ void __attribute__((regparm(1))) destroy_context(struct context *context)
context_map[context->slot] = NULL; context_map[context->slot] = NULL;
FreeKernelSpace(context->cmd_buffer);
mutex_lock(&main_device->struct_mutex); mutex_lock(&main_device->struct_mutex);
drm_gem_object_unreference(&context->obj->base); drm_gem_object_unreference(&context->obj->base);
mutex_unlock(&main_device->struct_mutex); mutex_unlock(&main_device->struct_mutex);

View File

@ -42,6 +42,14 @@
#define DRM_IRQ_ARGS void *arg #define DRM_IRQ_ARGS void *arg
static struct drm_driver {
irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
void (*irq_preinstall) (struct drm_device *dev);
int (*irq_postinstall) (struct drm_device *dev);
}drm_driver;
static struct drm_driver *driver = &drm_driver;
#define DRM_WAKEUP( queue ) wake_up( queue ) #define DRM_WAKEUP( queue ) wake_up( queue )
#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue ) #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
@ -2134,8 +2142,8 @@ static irqreturn_t i915_irq_handler(DRM_IRQ_ARGS)
int plane = pipe; int plane = pipe;
if (IS_MOBILE(dev)) if (IS_MOBILE(dev))
plane = !plane; plane = !plane;
if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS && if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS /* &&
drm_handle_vblank(dev, pipe)) { drm_handle_vblank(dev, pipe) */) {
if (iir & flip[plane]) { if (iir & flip[plane]) {
// intel_prepare_page_flip(dev, plane); // intel_prepare_page_flip(dev, plane);
// intel_finish_page_flip(dev, pipe); // intel_finish_page_flip(dev, pipe);
@ -2378,11 +2386,11 @@ static irqreturn_t i965_irq_handler(DRM_IRQ_ARGS)
// intel_prepare_page_flip(dev, 1); // intel_prepare_page_flip(dev, 1);
for_each_pipe(pipe) { for_each_pipe(pipe) {
if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS && // if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
drm_handle_vblank(dev, pipe)) { // drm_handle_vblank(dev, pipe)) {
// i915_pageflip_stall_check(dev, pipe); // i915_pageflip_stall_check(dev, pipe);
// intel_finish_page_flip(dev, pipe); // intel_finish_page_flip(dev, pipe);
} // }
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true; blc_event = true;
@ -2441,91 +2449,48 @@ static void i965_irq_uninstall(struct drm_device * dev)
void intel_irq_init(struct drm_device *dev) void intel_irq_init(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
#if 0
// INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
// INIT_WORK(&dev_priv->error_work, i915_error_work_func);
// INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
// INIT_WORK(&dev_priv->parity_error_work, ivybridge_parity_work);
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;
}
// 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)) { if (IS_VALLEYVIEW(dev)) {
dev->driver->irq_handler = valleyview_irq_handler; driver->irq_handler = valleyview_irq_handler;
dev->driver->irq_preinstall = valleyview_irq_preinstall; driver->irq_preinstall = valleyview_irq_preinstall;
dev->driver->irq_postinstall = valleyview_irq_postinstall; 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;
} else if (IS_IVYBRIDGE(dev)) { } else if (IS_IVYBRIDGE(dev)) {
/* Share pre & uninstall handlers with ILK/SNB */ /* Share pre & uninstall handlers with ILK/SNB */
dev->driver->irq_handler = ivybridge_irq_handler; driver->irq_handler = ivybridge_irq_handler;
dev->driver->irq_preinstall = ironlake_irq_preinstall; driver->irq_preinstall = ironlake_irq_preinstall;
dev->driver->irq_postinstall = ivybridge_irq_postinstall; driver->irq_postinstall = ivybridge_irq_postinstall;
dev->driver->irq_uninstall = ironlake_irq_uninstall;
dev->driver->enable_vblank = ivybridge_enable_vblank;
dev->driver->disable_vblank = ivybridge_disable_vblank;
} else if (IS_HASWELL(dev)) { } else if (IS_HASWELL(dev)) {
/* Share interrupts handling with IVB */ /* Share interrupts handling with IVB */
dev->driver->irq_handler = ivybridge_irq_handler; driver->irq_handler = ivybridge_irq_handler;
dev->driver->irq_preinstall = ironlake_irq_preinstall; driver->irq_preinstall = ironlake_irq_preinstall;
dev->driver->irq_postinstall = ivybridge_irq_postinstall; driver->irq_postinstall = ivybridge_irq_postinstall;
dev->driver->irq_uninstall = ironlake_irq_uninstall;
dev->driver->enable_vblank = ivybridge_enable_vblank;
dev->driver->disable_vblank = ivybridge_disable_vblank;
} else if (HAS_PCH_SPLIT(dev)) { } else if (HAS_PCH_SPLIT(dev)) {
dev->driver->irq_handler = ironlake_irq_handler; driver->irq_handler = ironlake_irq_handler;
dev->driver->irq_preinstall = ironlake_irq_preinstall; driver->irq_preinstall = ironlake_irq_preinstall;
dev->driver->irq_postinstall = ironlake_irq_postinstall; 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;
} else { } else {
if (INTEL_INFO(dev)->gen == 2) { if (INTEL_INFO(dev)->gen == 2) {
dev->driver->irq_preinstall = i8xx_irq_preinstall;
dev->driver->irq_postinstall = i8xx_irq_postinstall;
dev->driver->irq_handler = i8xx_irq_handler;
dev->driver->irq_uninstall = i8xx_irq_uninstall;
} else if (INTEL_INFO(dev)->gen == 3) { } else if (INTEL_INFO(dev)->gen == 3) {
dev->driver->irq_preinstall = i915_irq_preinstall; driver->irq_handler = i915_irq_handler;
dev->driver->irq_postinstall = i915_irq_postinstall; driver->irq_preinstall = i915_irq_preinstall;
dev->driver->irq_uninstall = i915_irq_uninstall; driver->irq_postinstall = i915_irq_postinstall;
dev->driver->irq_handler = i915_irq_handler;
} else { } else {
dev->driver->irq_preinstall = i965_irq_preinstall; driver->irq_handler = i965_irq_handler;
dev->driver->irq_postinstall = i965_irq_postinstall; driver->irq_preinstall = i965_irq_preinstall;
dev->driver->irq_uninstall = i965_irq_uninstall; driver->irq_postinstall = i965_irq_postinstall;
dev->driver->irq_handler = i965_irq_handler;
} }
dev->driver->enable_vblank = i915_enable_vblank;
dev->driver->disable_vblank = i915_disable_vblank;
} }
#endif
} }
static struct drm_device *irq_device;
void irq_handler_kms()
{
ironlake_irq_handler(irq_device);
}
int drm_irq_install(struct drm_device *dev) int drm_irq_install(struct drm_device *dev)
{ {
unsigned long sh_flags = 0;
int irq_line; int irq_line;
int ret = 0; int ret = 0;
char *irqname;
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
/* Driver must have been initialized */ /* Driver must have been initialized */
@ -2541,39 +2506,28 @@ int drm_irq_install(struct drm_device *dev)
dev->irq_enabled = 1; dev->irq_enabled = 1;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
irq_device = dev;
irq_line = drm_dev_to_irq(dev); irq_line = drm_dev_to_irq(dev);
DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
ironlake_irq_preinstall(dev); /* Before installing handler */
if (driver->irq_preinstall)
driver->irq_preinstall(dev);
ret = AttachIntHandler(irq_line, irq_handler_kms, 2); ret = AttachIntHandler(irq_line, driver->irq_handler, (u32)dev);
if (ret == 0) {
mutex_lock(&dev->struct_mutex); /* After installing handler */
dev->irq_enabled = 0; if (driver->irq_postinstall)
mutex_unlock(&dev->struct_mutex); ret = driver->irq_postinstall(dev);
return ret;
if (ret < 0) {
DRM_ERROR(__FUNCTION__);
} }
ret = ironlake_irq_postinstall(dev);
// if (ret < 0) {
// mutex_lock(&dev->struct_mutex);
// dev->irq_enabled = 0;
// mutex_unlock(&dev->struct_mutex);
// free_irq(drm_dev_to_irq(dev), dev);
// }
u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4); u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4);
cmd&= ~(1<<10); cmd&= ~(1<<10);
PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd); PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd);
DRM_DEBUG("i915: irq initialized.\n");
return ret; return ret;
} }