Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (189 commits) drm/radeon/kms: fix warning about cur_placement being uninitialised. drm/ttm: Print debug information on memory manager when eviction fails drm: Add memory manager debug function drm/radeon/kms: restore surface registers on resume. drm/radeon/kms/r600/r700: fallback gracefully on ucode failure drm/ttm: Initialize eviction placement in case the driver callback doesn't drm/radeon/kms: cleanup structure and module if initialization fails drm/radeon/kms: actualy set the eviction placements we choose drm/radeon/kms: Fix NULL ptr dereference drm/radeon/kms/avivo: add support for new pll selection algo drm/radeon/kms/avivo: fix some bugs in the display bandwidth setup drm/radeon/kms: fix return value from fence function. drm/radeon: Remove tests for -ERESTART from the TTM code. drm/ttm: Have the TTM code return -ERESTARTSYS instead of -ERESTART. drm/radeon/kms: Convert radeon to new TTM validation API (V2) drm/ttm: Rework validation & memory space allocation (V3) drm: Add search/get functions to get a block in a specific range drm/radeon/kms: fix avivo tiling regression since radeon object rework drm/i915: Remove a debugging printk from hangcheck drm/radeon/kms: make sure i2c id matches ...
Šī revīzija ir iekļauta:
@@ -125,6 +125,15 @@ static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
|
||||
DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
|
||||
drm_tv_subconnector_enum_list)
|
||||
|
||||
static struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
|
||||
{ DRM_MODE_DIRTY_OFF, "Off" },
|
||||
{ DRM_MODE_DIRTY_ON, "On" },
|
||||
{ DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
|
||||
};
|
||||
|
||||
DRM_ENUM_NAME_FN(drm_get_dirty_info_name,
|
||||
drm_dirty_info_enum_list)
|
||||
|
||||
struct drm_conn_prop_enum_list {
|
||||
int type;
|
||||
char *name;
|
||||
@@ -247,7 +256,8 @@ static void drm_mode_object_put(struct drm_device *dev,
|
||||
mutex_unlock(&dev->mode_config.idr_mutex);
|
||||
}
|
||||
|
||||
void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
|
||||
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
|
||||
uint32_t id, uint32_t type)
|
||||
{
|
||||
struct drm_mode_object *obj = NULL;
|
||||
|
||||
@@ -801,6 +811,36 @@ int drm_mode_create_dithering_property(struct drm_device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_create_dithering_property);
|
||||
|
||||
/**
|
||||
* drm_mode_create_dirty_property - create dirty property
|
||||
* @dev: DRM device
|
||||
*
|
||||
* Called by a driver the first time it's needed, must be attached to desired
|
||||
* connectors.
|
||||
*/
|
||||
int drm_mode_create_dirty_info_property(struct drm_device *dev)
|
||||
{
|
||||
struct drm_property *dirty_info;
|
||||
int i;
|
||||
|
||||
if (dev->mode_config.dirty_info_property)
|
||||
return 0;
|
||||
|
||||
dirty_info =
|
||||
drm_property_create(dev, DRM_MODE_PROP_ENUM |
|
||||
DRM_MODE_PROP_IMMUTABLE,
|
||||
"dirty",
|
||||
ARRAY_SIZE(drm_dirty_info_enum_list));
|
||||
for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++)
|
||||
drm_property_add_enum(dirty_info, i,
|
||||
drm_dirty_info_enum_list[i].type,
|
||||
drm_dirty_info_enum_list[i].name);
|
||||
dev->mode_config.dirty_info_property = dirty_info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
|
||||
|
||||
/**
|
||||
* drm_mode_config_init - initialize DRM mode_configuration structure
|
||||
* @dev: DRM device
|
||||
@@ -1753,6 +1793,71 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_clip_rect __user *clips_ptr;
|
||||
struct drm_clip_rect *clips = NULL;
|
||||
struct drm_mode_fb_dirty_cmd *r = data;
|
||||
struct drm_mode_object *obj;
|
||||
struct drm_framebuffer *fb;
|
||||
unsigned flags;
|
||||
int num_clips;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
|
||||
if (!obj) {
|
||||
DRM_ERROR("invalid framebuffer id\n");
|
||||
ret = -EINVAL;
|
||||
goto out_err1;
|
||||
}
|
||||
fb = obj_to_fb(obj);
|
||||
|
||||
num_clips = r->num_clips;
|
||||
clips_ptr = (struct drm_clip_rect *)(unsigned long)r->clips_ptr;
|
||||
|
||||
if (!num_clips != !clips_ptr) {
|
||||
ret = -EINVAL;
|
||||
goto out_err1;
|
||||
}
|
||||
|
||||
flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags;
|
||||
|
||||
/* If userspace annotates copy, clips must come in pairs */
|
||||
if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) {
|
||||
ret = -EINVAL;
|
||||
goto out_err1;
|
||||
}
|
||||
|
||||
if (num_clips && clips_ptr) {
|
||||
clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
|
||||
if (!clips) {
|
||||
ret = -ENOMEM;
|
||||
goto out_err1;
|
||||
}
|
||||
|
||||
ret = copy_from_user(clips, clips_ptr,
|
||||
num_clips * sizeof(*clips));
|
||||
if (ret)
|
||||
goto out_err2;
|
||||
}
|
||||
|
||||
if (fb->funcs->dirty) {
|
||||
ret = fb->funcs->dirty(fb, flags, r->color, clips, num_clips);
|
||||
} else {
|
||||
ret = -ENOSYS;
|
||||
goto out_err2;
|
||||
}
|
||||
|
||||
out_err2:
|
||||
kfree(clips);
|
||||
out_err1:
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* drm_fb_release - remove and free the FBs on this file
|
||||
* @filp: file * from the ioctl
|
||||
@@ -2478,3 +2583,72 @@ out:
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int drm_mode_page_flip_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_mode_crtc_page_flip *page_flip = data;
|
||||
struct drm_mode_object *obj;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_framebuffer *fb;
|
||||
struct drm_pending_vblank_event *e = NULL;
|
||||
unsigned long flags;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
|
||||
page_flip->reserved != 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC);
|
||||
if (!obj)
|
||||
goto out;
|
||||
crtc = obj_to_crtc(obj);
|
||||
|
||||
if (crtc->funcs->page_flip == NULL)
|
||||
goto out;
|
||||
|
||||
obj = drm_mode_object_find(dev, page_flip->fb_id, DRM_MODE_OBJECT_FB);
|
||||
if (!obj)
|
||||
goto out;
|
||||
fb = obj_to_fb(obj);
|
||||
|
||||
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
|
||||
ret = -ENOMEM;
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
if (file_priv->event_space < sizeof e->event) {
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
goto out;
|
||||
}
|
||||
file_priv->event_space -= sizeof e->event;
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
|
||||
e = kzalloc(sizeof *e, GFP_KERNEL);
|
||||
if (e == NULL) {
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
file_priv->event_space += sizeof e->event;
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
goto out;
|
||||
}
|
||||
|
||||
e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
|
||||
e->event.base.length = sizeof e->event;
|
||||
e->event.user_data = page_flip->user_data;
|
||||
e->base.event = &e->event.base;
|
||||
e->base.file_priv = file_priv;
|
||||
e->base.destroy =
|
||||
(void (*) (struct drm_pending_event *)) kfree;
|
||||
}
|
||||
|
||||
ret = crtc->funcs->page_flip(crtc, fb, e);
|
||||
if (ret) {
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
file_priv->event_space += sizeof e->event;
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
kfree(e);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
return ret;
|
||||
}
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user