summaryrefslogtreecommitdiff
path: root/shared-core/i915_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core/i915_init.c')
-rw-r--r--shared-core/i915_init.c303
1 files changed, 154 insertions, 149 deletions
diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c
index f2c07fc6..3a652e8d 100644
--- a/shared-core/i915_init.c
+++ b/shared-core/i915_init.c
@@ -100,62 +100,11 @@ 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_init_hwstatus(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long agp_size, prealloc_size;
- int size, 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;
-
- /* 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));
-
- /* Allow hardware batchbuffers unless told otherwise.
- */
- dev_priv->allow_batchbuffer = 1;
- dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS;
- mutex_init(&dev_priv->cmdbuf_mutex);
+ struct drm_memrange_node *free_space;
+ int ret = 0;
/* Program Hardware Status Page */
if (!IS_G33(dev)) {
@@ -165,52 +114,105 @@ int i915_load_modeset_init(struct drm_device *dev)
if (!dev_priv->status_page_dmah) {
DRM_ERROR("Can not allocate hardware status page\n");
ret = -ENOMEM;
- goto destroy_ringbuffer;
+ goto out;
}
- dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
+ dev_priv->hws_vaddr = 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) {
+ free_space = drm_memrange_search_free(&dev_priv->vram,
+ PAGE_SIZE,
+ PAGE_SIZE, 0);
+ if (!free_space) {
+ DRM_ERROR("No free vram available, aborting\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ dev_priv->hws = drm_memrange_get_block(free_space, PAGE_SIZE,
+ PAGE_SIZE);
+ if (!dev_priv->hws) {
DRM_ERROR("Unable to allocate or pin hw status page\n");
ret = -EINVAL;
- goto destroy_ringbuffer;
+ goto out;
}
- dev_priv->status_gfx_addr =
- dev_priv->hws_bo->offset & (0x1ffff << 12);
+ dev_priv->hws_agpoffset = dev_priv->hws->start;
dev_priv->hws_map.offset = dev->agp->base +
- dev_priv->hws_bo->offset;
- dev_priv->hws_map.size = size;
+ dev_priv->hws->start;
+ dev_priv->hws_map.size = PAGE_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;
+ dev_priv->hws_agpoffset = 0;
DRM_ERROR("can not ioremap virtual addr for"
"G33 hw status page\n");
ret = -ENOMEM;
- goto destroy_hws;
+ goto out_free;
}
- 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);
+ dev_priv->hws_vaddr = dev_priv->hws_map.handle;
+ I915_WRITE(HWS_PGA, dev_priv->hws_agpoffset);
}
+
+ memset(dev_priv->hws_vaddr, 0, PAGE_SIZE);
+
DRM_DEBUG("Enabled hardware status page\n");
+ return 0;
+
+out_free:
+ /* free hws */
+out:
+ return ret;
+}
+
+static void i915_cleanup_hwstatus(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ 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)
+ drm_memrange_put_block(dev_priv->hws);
+ }
+ I915_WRITE(HWS_PGA, 0x1ffff000);
+}
+
+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 ret = 0;
+
+ i915_probe_agp(dev->pdev, &agp_size, &prealloc_size);
+
+ /* Basic memrange allocator for stolen space (aka vram) */
+ drm_memrange_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);
+
+ ret = i915_gem_init_ringbuffer(dev);
+ if (ret)
+ goto out;
+
+ ret = i915_init_hwstatus(dev);
+ if (ret)
+ goto destroy_ringbuffer;
+
+ /* Allow hardware batchbuffers unless told otherwise.
+ */
+ dev_priv->allow_batchbuffer = 1;
+ dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS;
+ mutex_init(&dev_priv->cmdbuf_mutex);
+
dev_priv->wq = create_singlethread_workqueue("i915");
if (dev_priv->wq == 0) {
DRM_DEBUG("Error\n");
@@ -228,9 +230,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;
@@ -249,25 +248,10 @@ modeset_cleanup:
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);
+ i915_cleanup_hwstatus(dev);
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;
}
@@ -293,7 +277,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 +294,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,6 +323,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto free_priv;
}
+ INIT_LIST_HEAD(&dev_priv->mm.active_list);
+ INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
+ INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
+ INIT_LIST_HEAD(&dev_priv->mm.request_list);
+ INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
+ i915_gem_retire_work_handler);
+ dev_priv->mm.next_gem_seqno = 1;
+
#ifdef __linux__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
intel_init_chipset_flush_compat(dev);
@@ -348,26 +338,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
#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;
- }
-
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:
@@ -392,6 +370,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,44 +384,17 @@ 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
+ i915_cleanup_hwstatus(dev);
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_memrange_takedown(&dev_priv->vram);
+ i915_gem_lastclose(dev);
}
- drm_bo_driver_finish(dev);
-
#ifdef __linux__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
intel_init_chipset_flush_compat(dev);
@@ -497,10 +450,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 +490,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 +525,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;
}