mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-25 00:10:11 +01:00
add addfb/rmfb ioctls
Originally from Jakob, cleaned up by airlied.
This commit is contained in:
parent
7e2b1a6cf5
commit
b50bda002b
7 changed files with 135 additions and 29 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue