From dafa1f1f2e9a6c1f10e9fface6a6162adeb46c44 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sat, 17 Nov 2012 06:19:51 +0000 Subject: [PATCH] i915: new irq handling code git-svn-id: svn://kolibrios.org@3051 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/video/drm/drm_crtc_helper.c | 4 - drivers/video/drm/i915/bitmap.c | 66 +++++++++----- drivers/video/drm/i915/i915_irq.c | 136 +++++++++------------------- 3 files changed, 90 insertions(+), 116 deletions(-) diff --git a/drivers/video/drm/drm_crtc_helper.c b/drivers/video/drm/drm_crtc_helper.c index 7144c2088c..a53f96da8e 100644 --- a/drivers/video/drm/drm_crtc_helper.c +++ b/drivers/video/drm/drm_crtc_helper.c @@ -353,8 +353,6 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_encoder *encoder; bool ret = true; - ENTER(); - crtc->enabled = drm_helper_crtc_in_use(crtc); if (!crtc->enabled) return true; @@ -469,8 +467,6 @@ done: crtc->y = saved_y; } - LEAVE(); - return ret; } EXPORT_SYMBOL(drm_crtc_helper_set_mode); diff --git a/drivers/video/drm/i915/bitmap.c b/drivers/video/drm/i915/bitmap.c index 308751d1c0..4a709e6ca2 100644 --- a/drivers/video/drm/i915/bitmap.c +++ b/drivers/video/drm/i915/bitmap.c @@ -27,7 +27,6 @@ void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap) bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU; mutex_lock(&main_device->struct_mutex); - drm_gem_object_unreference(&bitmap->obj->base); 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 }; + for(;i < max_count; i++, vaddr+= PAGE_SIZE) + { + MapPage(vaddr, 0, 0); //map as shared page + }; + bitmap->page_count = page_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", width, height, pitch, size); - if( page_count == bitmap->page_count ) - { - bitmap->width = width; - bitmap->height = height; - bitmap->pitch = pitch; - } - else if(page_count > bitmap->page_count) + if(page_count > 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__, page_count - bitmap->page_count); -// mutex_lock(&main_device->struct_mutex); - i915_gem_object_unpin(bitmap->obj); i915_gem_object_unbind(bitmap->obj); 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); if (ret) goto err4; -// mutex_unlock(&main_device->struct_mutex); bitmap->page_count = page_count; - bitmap->width = width; - bitmap->height = height; - bitmap->pitch = pitch; + bitmap->gaddr = bitmap->obj->gtt_offset; + } + 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; }; - if(ret != 0 ) - { - pbitmap->data = NULL; - pbitmap->pitch = 0; + bitmap->width = width; + bitmap->height = height; + bitmap->pitch = pitch; - dbgprintf("%s fail\n", __FUNCTION__); - return ret; - }; pbitmap->data = bitmap->uaddr; pbitmap->pitch = bitmap->pitch; @@ -403,6 +424,7 @@ err4: while (i-- > bitmap->page_count) FreePage(pages[i]); +err3: return -1; }; @@ -447,6 +469,8 @@ void __attribute__((regparm(1))) destroy_context(struct context *context) context_map[context->slot] = NULL; + FreeKernelSpace(context->cmd_buffer); + mutex_lock(&main_device->struct_mutex); drm_gem_object_unreference(&context->obj->base); mutex_unlock(&main_device->struct_mutex); diff --git a/drivers/video/drm/i915/i915_irq.c b/drivers/video/drm/i915/i915_irq.c index 626e566ed5..961e8acf01 100644 --- a/drivers/video/drm/i915/i915_irq.c +++ b/drivers/video/drm/i915/i915_irq.c @@ -42,6 +42,14 @@ #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_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue ) @@ -2134,8 +2142,8 @@ static irqreturn_t i915_irq_handler(DRM_IRQ_ARGS) int plane = pipe; if (IS_MOBILE(dev)) plane = !plane; - if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS && - drm_handle_vblank(dev, pipe)) { + if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS /* && + drm_handle_vblank(dev, pipe) */) { if (iir & flip[plane]) { // intel_prepare_page_flip(dev, plane); // 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); for_each_pipe(pipe) { - if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS && - drm_handle_vblank(dev, pipe)) { +// if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS && +// drm_handle_vblank(dev, pipe)) { // i915_pageflip_stall_check(dev, pipe); // intel_finish_page_flip(dev, pipe); - } +// } if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) blc_event = true; @@ -2441,91 +2449,48 @@ static void i965_irq_uninstall(struct drm_device * dev) void intel_irq_init(struct drm_device *dev) { 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)) { - 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; + driver->irq_handler = valleyview_irq_handler; + driver->irq_preinstall = valleyview_irq_preinstall; + driver->irq_postinstall = valleyview_irq_postinstall; } else if (IS_IVYBRIDGE(dev)) { /* Share pre & uninstall handlers with ILK/SNB */ - dev->driver->irq_handler = ivybridge_irq_handler; - dev->driver->irq_preinstall = ironlake_irq_preinstall; - dev->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; + driver->irq_handler = ivybridge_irq_handler; + driver->irq_preinstall = ironlake_irq_preinstall; + driver->irq_postinstall = ivybridge_irq_postinstall; } else if (IS_HASWELL(dev)) { /* Share interrupts handling with IVB */ - dev->driver->irq_handler = ivybridge_irq_handler; - dev->driver->irq_preinstall = ironlake_irq_preinstall; - dev->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; + driver->irq_handler = ivybridge_irq_handler; + driver->irq_preinstall = ironlake_irq_preinstall; + driver->irq_postinstall = ivybridge_irq_postinstall; } 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; + driver->irq_handler = ironlake_irq_handler; + driver->irq_preinstall = ironlake_irq_preinstall; + driver->irq_postinstall = ironlake_irq_postinstall; } else { 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) { - 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; + driver->irq_handler = i915_irq_handler; + driver->irq_preinstall = i915_irq_preinstall; + driver->irq_postinstall = i915_irq_postinstall; } 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; + driver->irq_handler = i965_irq_handler; + driver->irq_preinstall = i965_irq_preinstall; + driver->irq_postinstall = i965_irq_postinstall; } - 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) { + unsigned long sh_flags = 0; int irq_line; int ret = 0; + char *irqname; + mutex_lock(&dev->struct_mutex); /* Driver must have been initialized */ @@ -2541,39 +2506,28 @@ int drm_irq_install(struct drm_device *dev) dev->irq_enabled = 1; mutex_unlock(&dev->struct_mutex); - irq_device = dev; irq_line = 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); - if (ret == 0) { - mutex_lock(&dev->struct_mutex); - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - return ret; + ret = AttachIntHandler(irq_line, driver->irq_handler, (u32)dev); + + /* After installing handler */ + if (driver->irq_postinstall) + ret = driver->irq_postinstall(dev); + + 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); - cmd&= ~(1<<10); - PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd); - DRM_DEBUG("i915: irq initialized.\n"); return ret; } - -