summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@jbarnes-t61.(none)>2008-06-11 15:59:01 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-06-11 15:59:01 -0700
commit4a2e29bf9982165deeeabb5c585fc0a8a659f380 (patch)
treed9aeb96a387bac3a8209292d9cc12f3b7c0c93bd /linux-core
parentf5412a944fa4666e25f4fa27b6ed85c21ccb65a0 (diff)
Use GEM in modesetting
Use GEM for ring buffer setup and framebuffer allocation. This means reworking the hardware status page stuff a bit (just use the basic range allocator for vram for now) and #ifdef'ing out the TTM & DRI2 code. Works well enough to load/unload several times and display fbcon on my T61 (though there's still some unexplained console corruption).
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/i915_drv.c10
-rw-r--r--linux-core/i915_gem.c52
-rw-r--r--linux-core/intel_display.c34
-rw-r--r--linux-core/intel_drv.h3
-rw-r--r--linux-core/intel_fb.c79
5 files changed, 102 insertions, 76 deletions
diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c
index 8718bd10..574282b2 100644
--- a/linux-core/i915_drv.c
+++ b/linux-core/i915_drv.c
@@ -48,11 +48,11 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
unsigned int i915_rightof = 1;
module_param_named(i915_rightof, i915_rightof, int, 0400);
-#ifdef I915_HAVE_FENCE
+#if defined(I915_HAVE_FENCE) && defined(I915_TTM)
extern struct drm_fence_driver i915_fence_driver;
#endif
-#ifdef I915_HAVE_BUFFER
+#if defined(I915_HAVE_BUFFER) && defined(I915_TTM)
static uint32_t i915_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL};
static uint32_t i915_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL};
@@ -71,7 +71,7 @@ static struct drm_bo_driver i915_bo_driver = {
.ttm_cache_flush = i915_flush_ttm,
.command_stream_barrier = NULL,
};
-#endif
+#endif /* ttm */
static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
{
@@ -619,10 +619,10 @@ static struct drm_driver driver = {
.probe = probe,
.remove = __devexit_p(drm_cleanup_pci),
},
-#ifdef I915_HAVE_FENCE
+#if defined(I915_HAVE_FENCE) && defined(I915_TTM)
.fence_driver = &i915_fence_driver,
#endif
-#ifdef I915_HAVE_BUFFER
+#if defined(I915_HAVE_BUFFER) && defined(I915_TTM)
.bo_driver = &i915_bo_driver,
#endif
.name = DRIVER_NAME,
diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c
index 961831c6..47745010 100644
--- a/linux-core/i915_gem.c
+++ b/linux-core/i915_gem.c
@@ -41,28 +41,35 @@ i915_gem_object_set_domain(struct drm_gem_object *obj,
uint32_t read_domains,
uint32_t write_domain);
-int
-i915_gem_init_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int i915_gem_do_init(struct drm_device *dev, unsigned long start,
+ unsigned long end)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_i915_gem_init *args = data;
-
- mutex_lock(&dev->struct_mutex);
- if (args->gtt_start >= args->gtt_end ||
- (args->gtt_start & (PAGE_SIZE - 1)) != 0 ||
- (args->gtt_end & (PAGE_SIZE - 1)) != 0) {
- mutex_unlock(&dev->struct_mutex);
+ if (start >= end ||
+ (start & (PAGE_SIZE - 1)) != 0 ||
+ (end & (PAGE_SIZE - 1)) != 0) {
return -EINVAL;
}
- drm_memrange_init(&dev_priv->mm.gtt_space, args->gtt_start,
- args->gtt_end - args->gtt_start);
+ drm_memrange_init(&dev_priv->mm.gtt_space, start,
+ end - start);
+
+ return 0;
+}
+
+int
+i915_gem_init_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_init *args = data;
+ int ret;
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_gem_do_init(dev, args->gtt_start, args->gtt_end);
mutex_unlock(&dev->struct_mutex);
- return 0;
+ return ret;
}
static void
@@ -1834,17 +1841,16 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
/* Stop the ring if it's running. */
- I915_WRITE(LP_RING + RING_LEN, 0);
- I915_WRITE(LP_RING + RING_HEAD, 0);
- I915_WRITE(LP_RING + RING_TAIL, 0);
- I915_WRITE(LP_RING + RING_START, 0);
+ I915_WRITE(PRB0_CTL, 0);
+ I915_WRITE(PRB0_HEAD, 0);
+ I915_WRITE(PRB0_TAIL, 0);
+ I915_WRITE(PRB0_START, 0);
/* Initialize the ring. */
- I915_WRITE(LP_RING + RING_START, obj_priv->gtt_offset);
- I915_WRITE(LP_RING + RING_LEN,
- ((obj->size - 4096) & RING_NR_PAGES) |
- RING_NO_REPORT |
- RING_VALID);
+ I915_WRITE(PRB0_START, obj_priv->gtt_offset);
+ I915_WRITE(PRB0_CTL, (((obj->size - 4096) & RING_NR_PAGES) |
+ RING_NO_REPORT |
+ RING_VALID));
/* Update our cache of the ring state */
i915_kernel_lost_context(dev);
@@ -1852,7 +1858,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
return 0;
}
-static void
+void
i915_gem_cleanup_ringbuffer(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c
index 0a2854a2..50ad1a27 100644
--- a/linux-core/intel_display.c
+++ b/linux-core/intel_display.c
@@ -369,6 +369,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y)
struct drm_i915_master_private *master_priv;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_framebuffer *intel_fb;
+ struct drm_i915_gem_object *obj_priv;
int pipe = intel_crtc->pipe;
unsigned long Start, Offset;
int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
@@ -385,7 +386,9 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y)
intel_fb = to_intel_framebuffer(crtc->fb);
- Start = intel_fb->bo->offset;
+ obj_priv = intel_fb->obj->driver_private;
+
+ Start = obj_priv->gtt_offset;
Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
I915_WRITE(dspstride, crtc->fb->pitch);
@@ -1493,7 +1496,7 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {
};
struct drm_framebuffer *intel_user_framebuffer_create(struct drm_device *dev,
- struct drm_file *file_priv,
+ struct drm_file *filp,
struct drm_mode_fb_cmd *mode_cmd)
{
struct intel_framebuffer *intel_fb;
@@ -1505,15 +1508,15 @@ struct drm_framebuffer *intel_user_framebuffer_create(struct drm_device *dev,
drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
- if (file_priv) {
- mutex_lock(&dev->struct_mutex);
- intel_fb->bo = drm_lookup_buffer_object(file_priv, intel_fb->base.mm_handle, 0);
- mutex_unlock(&dev->struct_mutex);
- if (!intel_fb->bo) {
+ if (filp) {
+ intel_fb->obj = drm_gem_object_lookup(dev, filp,
+ mode_cmd->handle);
+ if (!intel_fb->obj) {
kfree(intel_fb);
return NULL;
}
}
+ drm_gem_object_unreference(intel_fb->obj);
return &intel_fb->base;
}
@@ -1521,22 +1524,25 @@ static int intel_insert_new_fb(struct drm_device *dev, struct drm_file *file_pri
struct drm_framebuffer *fb, struct drm_mode_fb_cmd *mode_cmd)
{
struct intel_framebuffer *intel_fb;
- struct drm_buffer_object *bo;
+ struct drm_gem_object *obj;
struct drm_crtc *crtc;
intel_fb = to_intel_framebuffer(fb);
mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, mode_cmd->handle, 0);
- mutex_unlock(&dev->struct_mutex);
+ obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
- if (!bo)
+ if (!obj) {
+ mutex_unlock(&dev->struct_mutex);
return -EINVAL;
+ }
drm_helper_mode_fill_fb_struct(fb, mode_cmd);
-
- drm_bo_usage_deref_unlocked(&intel_fb->bo);
- intel_fb->bo = bo;
+ drm_gem_object_unreference(intel_fb->obj);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+
+ intel_fb->obj = obj;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (crtc->fb == fb) {
diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h
index 1008e271..bffbeef0 100644
--- a/linux-core/intel_drv.h
+++ b/linux-core/intel_drv.h
@@ -50,8 +50,7 @@ struct intel_i2c_chan {
struct intel_framebuffer {
struct drm_framebuffer base;
- struct drm_buffer_object *bo;
- struct drm_bo_kmap_obj kmap;
+ struct drm_gem_object *obj;
};
diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c
index 856ec868..d53b22ff 100644
--- a/linux-core/intel_fb.c
+++ b/linux-core/intel_fb.c
@@ -590,9 +590,10 @@ int intelfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_height
struct drm_framebuffer *fb;
struct intel_framebuffer *intel_fb;
struct drm_mode_fb_cmd mode_cmd;
- struct drm_buffer_object *fbo = NULL;
+ struct drm_gem_object *fbo = NULL;
+ struct drm_i915_gem_object *obj_priv;
struct device *device = &dev->pdev->dev;
- int ret;
+ int size, aligned_size, ret;
mode_cmd.width = surface_width;/* crtc->desired_mode->hdisplay; */
mode_cmd.height = surface_height;/* crtc->desired_mode->vdisplay; */
@@ -601,26 +602,28 @@ int intelfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_height
mode_cmd.pitch = mode_cmd.width * ((mode_cmd.bpp + 1) / 8);
mode_cmd.depth = 24;
- ret = drm_buffer_object_create(dev, mode_cmd.pitch * mode_cmd.height,
- drm_bo_type_kernel,
- DRM_BO_FLAG_READ |
- DRM_BO_FLAG_WRITE |
- DRM_BO_FLAG_MEM_TT |
- DRM_BO_FLAG_MEM_VRAM |
- DRM_BO_FLAG_NO_EVICT,
- DRM_BO_HINT_DONT_FENCE, 0, 0,
- &fbo);
- if (ret || !fbo) {
+ size = mode_cmd.pitch * mode_cmd.height;
+ aligned_size = ALIGN(size, PAGE_SIZE);
+ fbo = drm_gem_object_alloc(dev, aligned_size);
+ if (!fbo) {
printk(KERN_ERR "failed to allocate framebuffer\n");
- return -EINVAL;
+ ret = -ENOMEM;
+ goto out;
+ }
+ obj_priv = fbo->driver_private;
+
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_gem_object_pin(fbo, PAGE_SIZE);
+ if (ret) {
+ DRM_ERROR("failed to pin fb: %d\n", ret);
+ goto out_unref;
}
-
fb = intel_user_framebuffer_create(dev, NULL, &mode_cmd);
if (!fb) {
- drm_bo_usage_deref_unlocked(&fbo);
DRM_ERROR("failed to allocate fb.\n");
- return -EINVAL;
+ ret = -ENOMEM;
+ goto out_unref;
}
list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
@@ -628,11 +631,13 @@ int intelfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_height
intel_fb = to_intel_framebuffer(fb);
*intel_fb_p = intel_fb;
- intel_fb->bo = fbo;
+ intel_fb->obj = fbo;
info = framebuffer_alloc(sizeof(struct intelfb_par), device);
- if (!info)
- return -EINVAL;
+ if (!info) {
+ ret = -ENOMEM;
+ goto out_unref;
+ }
par = info->par;
@@ -651,19 +656,20 @@ int intelfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_height
info->fbops = &intelfb_ops;
info->fix.line_length = fb->pitch;
- info->fix.smem_start = intel_fb->bo->offset + dev->mode_config.fb_base;
- info->fix.smem_len = info->fix.line_length * fb->height;
+ info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset;
+ info->fix.smem_len = size;
info->flags = FBINFO_DEFAULT;
- ret = drm_bo_kmap(intel_fb->bo, 0, intel_fb->bo->num_pages, &intel_fb->kmap);
- if (ret)
- DRM_ERROR("error mapping fb: %d\n", ret);
-
- info->screen_base = intel_fb->kmap.virtual;
- info->screen_size = info->fix.smem_len; /* FIXME */
+ info->screen_base = ioremap(dev->agp->base + obj_priv->gtt_offset,
+ size);
+ if (!info->screen_base) {
+ ret = -ENOSPC;
+ goto out_unref;
+ }
+ info->screen_size = size;
- memset(intel_fb->kmap.virtual, 0, info->screen_size);
+ memset(info->screen_base, 0, size);
info->pseudo_palette = fb->pseudo_palette;
info->var.xres_virtual = fb->width;
@@ -754,10 +760,17 @@ int intelfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_height
par->dev = dev;
/* To allow resizeing without swapping buffers */
- printk("allocated %dx%d fb: 0x%08lx, bo %p\n", intel_fb->base.width,
- intel_fb->base.height, intel_fb->bo->offset, fbo);
+ printk("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width,
+ intel_fb->base.height, obj_priv->gtt_offset, fbo);
+ mutex_unlock(&dev->struct_mutex);
return 0;
+
+out_unref:
+ drm_gem_object_unreference(fbo);
+ mutex_unlock(&dev->struct_mutex);
+out:
+ return ret;
}
static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc *crtc)
@@ -1001,8 +1014,10 @@ int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
if (info) {
unregister_framebuffer(info);
- drm_bo_kunmap(&intel_fb->kmap);
- drm_bo_usage_deref_unlocked(&intel_fb->bo);
+ iounmap(info->screen_base);
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(intel_fb->obj);
+ mutex_unlock(&dev->struct_mutex);
framebuffer_release(info);
}
return 0;