diff options
Diffstat (limited to 'shared-core/i915_init.c')
-rw-r--r-- | shared-core/i915_init.c | 320 |
1 files changed, 144 insertions, 176 deletions
diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index f2c07fc6..4f2d3a4f 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -100,56 +100,22 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, return 0; } -int i915_load_modeset_init(struct drm_device *dev) +static int i915_load_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; unsigned long agp_size, prealloc_size; - int size, ret = 0; + int ret = 0; i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); - printk("setting up %ld bytes of VRAM space\n", prealloc_size); - printk("setting up %ld bytes of TT space\n", (agp_size - prealloc_size)); - - drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT, 1); - drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, - (agp_size - prealloc_size) >> PAGE_SHIFT, 1); - I915_WRITE(PRB0_CTL, 0); - I915_WRITE(PRB0_HEAD, 0); - I915_WRITE(PRB0_TAIL, 0); - - size = PRIMARY_RINGBUFFER_SIZE; - ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_NO_EVICT, - DRM_BO_HINT_DONT_FENCE, 0x1, 0, - &dev_priv->ring_buffer); - if (ret < 0) { - DRM_ERROR("Unable to allocate or pin ring buffer\n"); - goto clean_mm; - } - /* remap the buffer object properly */ - dev_priv->ring.Start = dev_priv->ring_buffer->offset; - dev_priv->ring.End = dev_priv->ring.Start + size; - dev_priv->ring.Size = size; - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + /* Basic memrange allocator for stolen space (aka vram) */ + drm_mm_init(&dev_priv->vram, 0, prealloc_size); + /* Let GEM Manage from end of prealloc space to end of aperture */ + i915_gem_do_init(dev, prealloc_size, agp_size); - /* FIXME: need wrapper with PCI mem checks */ - ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem, - (void **) &dev_priv->ring.virtual_start); - if (ret) { - DRM_ERROR("error mapping ring buffer: %d\n", ret); - goto destroy_ringbuffer; - } - - DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start, - dev_priv->ring.virtual_start, dev_priv->ring.Size); - - memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size); - I915_WRITE(PRB0_START, dev_priv->ring.Start); - I915_WRITE(PRB0_CTL, ((dev_priv->ring.Size - 4096) & RING_NR_PAGES) | - (RING_NO_REPORT | RING_VALID)); + ret = i915_gem_init_ringbuffer(dev); + if (ret) + goto out; /* Allow hardware batchbuffers unless told otherwise. */ @@ -157,65 +123,11 @@ int i915_load_modeset_init(struct drm_device *dev) dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; mutex_init(&dev_priv->cmdbuf_mutex); - /* Program Hardware Status Page */ - if (!IS_G33(dev)) { - dev_priv->status_page_dmah = - drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); - - if (!dev_priv->status_page_dmah) { - DRM_ERROR("Can not allocate hardware status page\n"); - ret = -ENOMEM; - goto destroy_ringbuffer; - } - dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; - dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; - - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - - I915_WRITE(HWS_PGA, dev_priv->dma_status_page); - } else { - size = 4 * 1024; - ret = drm_buffer_object_create(dev, size, - drm_bo_type_kernel, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_NO_EVICT, - DRM_BO_HINT_DONT_FENCE, 0x1, 0, - &dev_priv->hws_bo); - if (ret < 0) { - DRM_ERROR("Unable to allocate or pin hw status page\n"); - ret = -EINVAL; - goto destroy_ringbuffer; - } - - dev_priv->status_gfx_addr = - dev_priv->hws_bo->offset & (0x1ffff << 12); - dev_priv->hws_map.offset = dev->agp->base + - dev_priv->hws_bo->offset; - dev_priv->hws_map.size = size; - dev_priv->hws_map.type= 0; - dev_priv->hws_map.flags= 0; - dev_priv->hws_map.mtrr = 0; - - drm_core_ioremap(&dev_priv->hws_map, dev); - if (dev_priv->hws_map.handle == NULL) { - dev_priv->status_gfx_addr = 0; - DRM_ERROR("can not ioremap virtual addr for" - "G33 hw status page\n"); - ret = -ENOMEM; - goto destroy_hws; - } - dev_priv->hw_status_page = dev_priv->hws_map.handle; - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); - } - DRM_DEBUG("Enabled hardware status page\n"); - dev_priv->wq = create_singlethread_workqueue("i915"); if (dev_priv->wq == 0) { DRM_DEBUG("Error\n"); ret = -EINVAL; - goto destroy_hws; + goto destroy_ringbuffer; } ret = intel_init_bios(dev); @@ -228,9 +140,6 @@ int i915_load_modeset_init(struct drm_device *dev) intel_modeset_init(dev); drm_helper_initial_config(dev, false); - drm_mm_print(&dev->bm.man[DRM_BO_MEM_VRAM].manager, "VRAM"); - drm_mm_print(&dev->bm.man[DRM_BO_MEM_TT].manager, "TT"); - dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); if (!dev->devname) { ret = -ENOMEM; @@ -248,26 +157,9 @@ modeset_cleanup: intel_modeset_cleanup(dev); destroy_wq: destroy_workqueue(dev_priv->wq); -destroy_hws: - if (!IS_G33(dev)) { - if (dev_priv->status_page_dmah) - drm_pci_free(dev, dev_priv->status_page_dmah); - } else { - if (dev_priv->hws_map.handle) - drm_core_ioremapfree(&dev_priv->hws_map, dev); - if (dev_priv->hws_bo) - drm_bo_usage_deref_unlocked(&dev_priv->hws_bo); - } - I915_WRITE(HWS_PGA, 0x1ffff000); destroy_ringbuffer: - if (dev_priv->ring.virtual_start) - drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, - dev_priv->ring.virtual_start); - if (dev_priv->ring_buffer) - drm_bo_usage_deref_unlocked(&dev_priv->ring_buffer); -clean_mm: - drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1); - drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1); + i915_gem_cleanup_ringbuffer(dev); +out: return ret; } @@ -285,7 +177,8 @@ clean_mm: int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv; - int ret = 0; + int ret = 0, num_pipes = 2; + u32 tmp; dev_priv = drm_alloc(sizeof(struct drm_i915_private), DRM_MEM_DRIVER); if (dev_priv == NULL) @@ -293,7 +186,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) memset(dev_priv, 0, sizeof(struct drm_i915_private)); dev->dev_private = (void *)dev_priv; -// dev_priv->flags = flags; + dev_priv->dev = dev; /* i915 has 4 more counters */ dev->counters += 4; @@ -310,10 +203,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (IS_I965G(dev) || IS_G33(dev)) dev_priv->cursor_needs_physical = false; - if (IS_I9XX(dev)) { + if (IS_I9XX(dev)) pci_read_config_dword(dev->pdev, 0x5C, &dev_priv->stolen_base); - DRM_DEBUG("stolen base %p\n", (void*)dev_priv->stolen_base); - } if (IS_I9XX(dev)) { dev_priv->mmiobase = drm_get_resource_start(dev, 0); @@ -341,33 +232,65 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto free_priv; } + i915_gem_load(dev); + #ifdef __linux__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) - intel_init_chipset_flush_compat(dev); + intel_init_chipset_flush_compat(dev); +#endif +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) + intel_opregion_init(dev); #endif #endif - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - /* - * Initialize the memory manager for local and AGP space - */ - ret = drm_bo_driver_init(dev); - if (ret) { - DRM_ERROR("fail to init memory manager for " - "local & AGP space\n"); - goto out_rmmap; - } + tmp = I915_READ(PIPEASTAT); + I915_WRITE(PIPEASTAT, tmp); + tmp = I915_READ(PIPEBSTAT); + I915_WRITE(PIPEBSTAT, tmp); + + atomic_set(&dev_priv->irq_received, 0); + I915_WRITE(HWSTAM, 0xeffe); + I915_WRITE(IMR, 0x0); + I915_WRITE(IER, 0x0); + + DRM_SPININIT(&dev_priv->swaps_lock, "swap"); + INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); + dev_priv->swaps_pending = 0; + + DRM_SPININIT(&dev_priv->user_irq_lock, "userirq"); + dev_priv->user_irq_refcount = 0; + dev_priv->irq_mask_reg = ~0; + + ret = drm_vblank_init(dev, num_pipes); + if (ret) + goto out_rmmap; + + ret = drm_hotplug_init(dev); + if (ret) + goto out_rmmap; + + dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ + i915_enable_interrupt(dev); + DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); + + /* + * Initialize the hardware status page IRQ location. + */ + + I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); + + 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 driver_fini; + goto out_rmmap; } } + return 0; -driver_fini: - drm_bo_driver_finish(dev); out_rmmap: drm_rmmap(dev, dev_priv->mmio_map); free_priv: @@ -379,6 +302,23 @@ int i915_driver_unload(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + u32 temp; + + dev_priv->vblank_pipe = 0; + + dev_priv->irq_enabled = 0; + + I915_WRITE(HWSTAM, 0xffffffff); + I915_WRITE(IMR, 0xffffffff); + I915_WRITE(IER, 0x0); + + temp = I915_READ(PIPEASTAT); + I915_WRITE(PIPEASTAT, temp); + temp = I915_READ(PIPEBSTAT); + I915_WRITE(PIPEBSTAT, temp); + temp = I915_READ(IIR); + I915_WRITE(IIR, temp); + I915_WRITE(PRB0_CTL, 0); if (drm_core_check_feature(dev, DRIVER_MODESET)) { @@ -392,6 +332,8 @@ int i915_driver_unload(struct drm_device *dev) drm_core_ioremapfree(&dev_priv->ring.map, dev); } #endif + +#ifdef DRI2 if (dev_priv->sarea_kmap.virtual) { drm_bo_kunmap(&dev_priv->sarea_kmap); dev_priv->sarea_kmap.virtual = NULL; @@ -404,53 +346,27 @@ int i915_driver_unload(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); dev_priv->sarea_bo = NULL; } - - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - dev_priv->status_page_dmah = NULL; - dev_priv->hw_status_page = NULL; - dev_priv->dma_status_page = 0; - /* Need to rewrite hardware status page */ - I915_WRITE(HWS_PGA, 0x1ffff000); - } - - if (dev_priv->status_gfx_addr) { - dev_priv->status_gfx_addr = 0; - drm_core_ioremapfree(&dev_priv->hws_map, dev); - drm_bo_usage_deref_unlocked(&dev_priv->hws_bo); - I915_WRITE(HWS_PGA, 0x1ffff000); - } +#endif if (drm_core_check_feature(dev, DRIVER_MODESET)) { - drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, - dev_priv->ring.virtual_start); - - DRM_DEBUG("usage is %d\n", atomic_read(&dev_priv->ring_buffer->usage)); mutex_lock(&dev->struct_mutex); - drm_bo_usage_deref_locked(&dev_priv->ring_buffer); - - if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1)) { - DRM_ERROR("Memory manager type 3 not clean. " - "Delaying takedown\n"); - } - if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) { - DRM_ERROR("Memory manager type 3 not clean. " - "Delaying takedown\n"); - } + i915_gem_cleanup_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); + drm_mm_takedown(&dev_priv->vram); + i915_gem_lastclose(dev); } - drm_bo_driver_finish(dev); + drm_rmmap(dev, dev_priv->mmio_map); #ifdef __linux__ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) + intel_opregion_free(dev); +#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) - intel_init_chipset_flush_compat(dev); + intel_fini_chipset_flush_compat(dev); #endif #endif - DRM_DEBUG("%p\n", dev_priv->mmio_map); - drm_rmmap(dev, dev_priv->mmio_map); - drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -497,10 +413,36 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) master->driver_priv = NULL; } +int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) +{ + struct drm_i915_file_private *i915_file_priv; + + DRM_DEBUG("\n"); + i915_file_priv = (struct drm_i915_file_private *) + drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES); + + if (!i915_file_priv) + return -ENOMEM; + + file_priv->driver_priv = i915_file_priv; + + i915_file_priv->mm.last_gem_seqno = 0; + i915_file_priv->mm.last_gem_throttle_seqno = 0; + + return 0; +} + +void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) +{ + struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; + + drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES); +} + void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { struct drm_i915_private *dev_priv = dev->dev_private; - if (drm_core_check_feature(dev, DRIVER_MODESET)) + if (!drm_core_check_feature(dev, DRIVER_MODESET)) i915_mem_release(dev, file_priv, dev_priv->agp_heap); } @@ -511,8 +453,33 @@ void i915_driver_lastclose(struct drm_device * dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) return; +#ifdef I915_HAVE_BUFFER + if (dev_priv->val_bufs) { + vfree(dev_priv->val_bufs); + dev_priv->val_bufs = NULL; + } +#endif + + i915_gem_lastclose(dev); + if (dev_priv->agp_heap) i915_mem_takedown(&(dev_priv->agp_heap)); + +#if defined(DRI2) + if (dev_priv->sarea_kmap.virtual) { + drm_bo_kunmap(&dev_priv->sarea_kmap); + dev_priv->sarea_kmap.virtual = NULL; + dev->control->master->lock.hw_lock = NULL; + dev->sigdata.lock = NULL; + } + + if (dev_priv->sarea_bo) { + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&dev_priv->sarea_bo); + mutex_unlock(&dev->struct_mutex); + dev_priv->sarea_bo = NULL; + } +#endif i915_dma_cleanup(dev); } @@ -521,7 +488,8 @@ int i915_driver_firstopen(struct drm_device *dev) { if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0; - +#if defined(I915_HAVE_BUFFER) && defined(I915_TTM) drm_bo_driver_init(dev); +#endif return 0; } |