diff options
Diffstat (limited to 'linux-core/drm_crtc.c')
-rw-r--r-- | linux-core/drm_crtc.c | 67 |
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); } } |