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:
Linus Torvalds
2009-12-10 21:56:47 -08:00
revīzija 3ef884b4c0
122 mainīti faili ar 12038 papildinājumiem un 2957 dzēšanām

Parādīt failu

@@ -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;
}