summaryrefslogtreecommitdiff
path: root/linux-core/drm_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core/drm_crtc.c')
-rw-r--r--linux-core/drm_crtc.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index 13a01fee..ab8b4688 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -87,6 +87,31 @@ void drm_idr_put(struct drm_device *dev, int id)
}
/**
+ * drm_crtc_from_fb - find the CRTC structure associated with an fb
+ * @dev: DRM device
+ * @fb: framebuffer in question
+ *
+ * LOCKING:
+ * Caller must hold mode_config lock.
+ *
+ * Find CRTC in the mode_config structure that matches @fb.
+ *
+ * RETURNS:
+ * Pointer to the CRTC or NULL if it wasn't found.
+ */
+struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev,
+ struct drm_framebuffer *fb)
+{
+ struct drm_crtc *crtc;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc->fb == fb)
+ return crtc;
+ }
+ return NULL;
+}
+
+/**
* drm_framebuffer_create - create a new framebuffer object
* @dev: DRM device
*
@@ -465,6 +490,7 @@ done:
return ret;
}
+EXPORT_SYMBOL(drm_crtc_set_mode);
/**
* drm_disable_unused_functions - disable unused objects
@@ -670,6 +696,7 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev)
nmode->mode_id = drm_idr_get(dev, nmode);
return nmode;
}
+EXPORT_SYMBOL(drm_mode_create);
/**
* drm_mode_destroy - remove a mode
@@ -687,6 +714,7 @@ void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
kfree(mode);
}
+EXPORT_SYMBOL(drm_mode_destroy);
/**
* drm_mode_config_init - initialize DRM mode_configuration structure
@@ -865,6 +893,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow)
struct drm_framebuffer *fb;
drm_buffer_object_t *fbo;
unsigned long size, bytes_per_pixel;
+ int ret;
drm_crtc_probe_output_modes(dev, 2048, 2048);
@@ -884,29 +913,35 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow)
output->crtc->fb = fb;
des_mode = output->crtc->desired_mode;
- if (des_mode->hdisplay > fb->width) {
+ if (des_mode->hdisplay > fb->width)
fb->width = des_mode->hdisplay;
- fb->pitch = fb->width;
- }
if (des_mode->vdisplay > fb->height)
fb->height = des_mode->vdisplay;
/* FIXME: multiple depths */
bytes_per_pixel = 4;
fb->bits_per_pixel = 32;
+ fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8);
fb->depth = 24;
- size = fb->pitch * fb->height * bytes_per_pixel;
+ size = fb->width * fb->height * bytes_per_pixel;
/* FIXME - what about resizeable objects ??? */
- drm_buffer_object_create(dev, size, drm_bo_type_kernel,
- DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
- DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE,
- 0, 0, 0,
- &fbo);
- printk("allocated %dx%d fb: 0x%08lx, bo %p\n", fb->width,
- fb->height, fbo->offset, fbo);
+ ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel,
+ DRM_BO_FLAG_READ |
+ DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_MEM_PRIV0 |
+ DRM_BO_FLAG_NO_MOVE,
+ 0, 0, 0,
+ &fbo);
+ if (ret) {
+ printk(KERN_ERR "failed to allocate framebuffer\n");
+ drm_framebuffer_destroy(fb);
+ continue;
+ }
fb->offset = fbo->offset;
fb->bo = fbo;
- drmfb_probe(dev, output->crtc);
+ printk("allocated %dx%d fb: 0x%08lx, bo %p\n", fb->width,
+ fb->height, fbo->offset, fbo);
+ dev->driver->fb_probe(dev, output->crtc);
}
drm_disable_unused_functions(dev);
@@ -945,7 +980,7 @@ void drm_mode_config_cleanup(drm_device_t *dev)
}
list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
- drmfb_remove(dev, fb);
+ dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
/* If this FB was the kernel one, free it */
if (fb->bo->type == drm_bo_type_kernel) {
mutex_lock(&dev->struct_mutex);
@@ -1567,7 +1602,7 @@ int drm_mode_addfb(struct inode *inode, struct file *filp,
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
crtc->fb = fb;
- drmfb_probe(dev, crtc);
+ dev->driver->fb_probe(dev, crtc);
}
}
@@ -1606,7 +1641,7 @@ int drm_mode_rmfb(struct inode *inode, struct file *filp,
return -EINVAL;
}
- drmfb_remove(dev, fb);
+ dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
/* TODO check if we own the buffer */
/* TODO release all crtc connected to the framebuffer */
@@ -1688,7 +1723,7 @@ void drm_fb_release(struct file *filp)
list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
list_del(&fb->filp_head);
- drmfb_remove(dev, fb);
+ dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
drm_framebuffer_destroy(fb);
}
}