add addfb/rmfb ioctls

Originally from Jakob, cleaned up by airlied.
This commit is contained in:
Jakob Bornecrantz 2007-04-10 18:44:47 +10:00 committed by Dave Airlie
parent 7e2b1a6cf5
commit b50bda002b
7 changed files with 135 additions and 29 deletions

View file

@ -192,6 +192,28 @@ err_allocs:
return 0;
}
uint32_t drmModeAddFB(int fd, uint32_t width, uint32_t height,
uint8_t bpp, uint32_t pitch, drmBO *bo)
{
struct drm_mode_fb_cmd f;
f.width = width;
f.height = height;
f.pitch = pitch;
f.bpp = bpp;
f.handle = bo->handle;
if (ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f))
return 0;
return f.buffer_id;
}
int drmModeRmFB(int fd, uint32_t bufferId)
{
return ioctl(fd, DRM_IOCTL_MODE_RMFB, bufferId);
}
#if 0
int drmModeForceProbe(int fd, uint32_t outputId)
{

View file

@ -77,8 +77,10 @@ typedef struct _drmModeRes {
typedef struct _drmModeFrameBuffer {
uint32_t minWidth, maxWidth;
uint32_t minHeight, maxHeight;
uint32_t width;
uint32_t height;
uint32_t pitch;
uint8_t bpp;
} drmModeFrameBuffer, *drmModeFrameBufferPtr;

View file

@ -465,18 +465,19 @@ void drm_crtc_config_init(drm_device_t *dev)
}
EXPORT_SYMBOL(drm_crtc_config_init);
void drm_framebuffer_set_object(drm_device_t *dev, unsigned long handle)
static int drm_get_buffer_object(drm_device_t *dev, struct drm_buffer_object **bo, unsigned long handle)
{
struct drm_framebuffer *fb;
drm_user_object_t *uo;
drm_hash_item_t *hash;
drm_buffer_object_t *bo;
int ret;
*bo = NULL;
mutex_lock(&dev->struct_mutex);
ret = drm_ht_find_item(&dev->object_hash, handle, &hash);
if (ret) {
DRM_ERROR("Couldn't find handle.\n");
ret = -EINVAL;
goto out_err;
}
@ -485,20 +486,13 @@ void drm_framebuffer_set_object(drm_device_t *dev, unsigned long handle)
ret = -EINVAL;
goto out_err;
}
bo = drm_user_object_entry(uo, drm_buffer_object_t, base);
/* get the first fb */
list_for_each_entry(fb, &dev->crtc_config.fb_list, head) {
fb->offset = bo->offset;
break;
}
*bo = drm_user_object_entry(uo, drm_buffer_object_t, base);
ret = 0;
out_err:
mutex_unlock(&dev->struct_mutex);
return;
return ret;
}
EXPORT_SYMBOL(drm_framebuffer_set_object);
bool drm_initial_config(drm_device_t *dev, bool can_grow)
{
@ -923,3 +917,78 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,
retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set);
return retcode;
}
/* Add framebuffer ioctl */
int drm_mode_addfb(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->head->dev;
struct drm_mode_fb_cmd __user *argp = (void __user *)arg;
struct drm_mode_fb_cmd r;
struct drm_crtc_config *config = &dev->crtc_config;
struct drm_framebuffer *fb;
struct drm_buffer_object *bo;
int ret;
if (!copy_from_user(&r, argp, sizeof(r)))
return -EFAULT;
if (config->min_width > r.width || r.width > config->max_width) {
DRM_ERROR("mode new framebuffer width not within limits");
return -EINVAL;
}
if (config->min_height > r.height || r.height > config->min_height) {
DRM_ERROR("mode new framebuffer height not within limits");
return -EINVAL;
}
/* TODO check limits are okay */
ret = drm_get_buffer_object(dev, &bo, r.handle);
if (ret || !bo)
return -EINVAL;
/* TODO check buffer is sufficently large */
/* TODO setup destructor callback */
fb = drm_framebuffer_create(dev);
if(!fb)
return -EINVAL;;
fb->width = r.width;
fb->height = r.height;
fb->pitch = r.pitch;
fb->bits_per_pixel = r.bpp;
fb->offset = bo->offset;
fb->bo = bo;
r.buffer_id = fb->id;
if (!copy_to_user(argp, &r, sizeof(r)))
return -EFAULT;
return 0;
}
int drm_mode_rmfb(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
struct drm_framebuffer *fb = 0;
uint32_t id = arg;
fb = idr_find(&dev->crtc_config.crtc_idr, id);
/* TODO check that we realy get a framebuffer back. */
if (!fb || (id != fb->id)) {
DRM_ERROR("mode invalid framebuffer id\n");
return -EINVAL;
}
/* TODO check if we own the buffer */
/* TODO release all crtc connected to the framebuffer */
/* TODO unhock the destructor from the buffer object */
drm_framebuffer_destroy(fb);
return 0;
}

View file

@ -178,6 +178,7 @@ struct drm_framebuffer {
unsigned int depth;
int bits_per_pixel;
int flags;
struct drm_buffer_object *bo;
};
struct drm_crtc;
struct drm_output;
@ -432,17 +433,6 @@ extern void drm_disable_unused_functions(struct drm_device *dev);
extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
extern void drm_crtc_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
/* IOCTLs */
extern int drm_mode_getresources(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_mode_getcrtc(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_mode_getoutput(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_mode_setcrtc(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern void drm_mode_list_concat(struct list_head *head,
struct list_head *new);
extern void drm_mode_validate_size(struct drm_device *dev,
@ -454,7 +444,20 @@ extern void drm_mode_sort(struct list_head *mode_list);
extern int drm_mode_vrefresh(struct drm_display_mode *mode);
extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
int adjust_flags);
extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
/* IOCTLs */
extern int drm_mode_getresources(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_mode_getcrtc(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_mode_getoutput(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_mode_setcrtc(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_mode_addfb(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_mode_rmfb(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
#endif /* __DRM_CRTC_H__ */

View file

@ -127,6 +127,8 @@ static drm_ioctl_desc_t drm_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_MODE_GETCRTC)] = {drm_mode_getcrtc, DRM_MASTER|DRM_ROOT_ONLY},
[DRM_IOCTL_NR(DRM_IOCTL_MODE_GETOUTPUT)] = {drm_mode_getoutput, DRM_MASTER|DRM_ROOT_ONLY},
[DRM_IOCTL_NR(DRM_IOCTL_MODE_SETCRTC)] = {drm_mode_setcrtc, DRM_MASTER|DRM_ROOT_ONLY},
[DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB)] = {drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY},
[DRM_IOCTL_NR(DRM_IOCTL_MODE_RMFB)] = {drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY},
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )

View file

@ -962,6 +962,14 @@ struct drm_mode_get_output {
};
struct drm_mode_fb_cmd {
unsigned int buffer_id;
unsigned int width, height;
unsigned int pitch;
unsigned int bpp;
unsigned int handle;
};
/**
* \name Ioctls Definitions
*/
@ -1037,6 +1045,8 @@ struct drm_mode_get_output {
#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
#define DRM_IOCTL_MODE_GETOUTPUT DRM_IOWR(0xA2, struct drm_mode_get_output)
#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA3, struct drm_mode_crtc)
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xA4, struct drm_mode_fb_cmd)
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xA5, unsigned int)
/*@}*/
/**

View file

@ -171,8 +171,6 @@ static int i915_initialize(drm_device_t * dev,
I915_WRITE(0x02080, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
/* this probably doesn't belong here - TODO */
drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle);
drm_set_desired_modes(dev);
return 0;