diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
| -rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 140 | 
1 files changed, 111 insertions, 29 deletions
| diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index f6191215b2cb..e08f962288d9 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -430,9 +430,7 @@ EXPORT_SYMBOL(drm_framebuffer_init);  static void __drm_framebuffer_unregister(struct drm_device *dev,  					 struct drm_framebuffer *fb)  { -	mutex_lock(&dev->mode_config.idr_mutex); -	idr_remove(&dev->mode_config.crtc_idr, fb->base.id); -	mutex_unlock(&dev->mode_config.idr_mutex); +	drm_mode_object_put(dev, &fb->base);  	fb->base.id = 0;  } @@ -1150,6 +1148,29 @@ out_unlock:  EXPORT_SYMBOL(drm_encoder_init);  /** + * drm_encoder_index - find the index of a registered encoder + * @encoder: encoder to find index for + * + * Given a registered encoder, return the index of that encoder within a DRM + * device's list of encoders. + */ +unsigned int drm_encoder_index(struct drm_encoder *encoder) +{ +	unsigned int index = 0; +	struct drm_encoder *tmp; + +	drm_for_each_encoder(tmp, encoder->dev) { +		if (tmp == encoder) +			return index; + +		index++; +	} + +	BUG(); +} +EXPORT_SYMBOL(drm_encoder_index); + +/**   * drm_encoder_cleanup - cleans up an initialised encoder   * @encoder: encoder to cleanup   * @@ -1531,6 +1552,41 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)  		return -ENOMEM;  	dev->mode_config.prop_mode_id = prop; +	prop = drm_property_create(dev, +			DRM_MODE_PROP_BLOB, +			"DEGAMMA_LUT", 0); +	if (!prop) +		return -ENOMEM; +	dev->mode_config.degamma_lut_property = prop; + +	prop = drm_property_create_range(dev, +			DRM_MODE_PROP_IMMUTABLE, +			"DEGAMMA_LUT_SIZE", 0, UINT_MAX); +	if (!prop) +		return -ENOMEM; +	dev->mode_config.degamma_lut_size_property = prop; + +	prop = drm_property_create(dev, +			DRM_MODE_PROP_BLOB, +			"CTM", 0); +	if (!prop) +		return -ENOMEM; +	dev->mode_config.ctm_property = prop; + +	prop = drm_property_create(dev, +			DRM_MODE_PROP_BLOB, +			"GAMMA_LUT", 0); +	if (!prop) +		return -ENOMEM; +	dev->mode_config.gamma_lut_property = prop; + +	prop = drm_property_create_range(dev, +			DRM_MODE_PROP_IMMUTABLE, +			"GAMMA_LUT_SIZE", 0, UINT_MAX); +	if (!prop) +		return -ENOMEM; +	dev->mode_config.gamma_lut_size_property = prop; +  	return 0;  } @@ -5254,7 +5310,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,  	struct drm_crtc *crtc;  	struct drm_framebuffer *fb = NULL;  	struct drm_pending_vblank_event *e = NULL; -	unsigned long flags;  	int ret = -EINVAL;  	if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || @@ -5305,41 +5360,26 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,  	}  	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); +		e = kzalloc(sizeof *e, GFP_KERNEL); +		if (!e) { +			ret = -ENOMEM;  			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 = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); +		if (ret) { +			kfree(e); +			goto out; +		}  	}  	crtc->primary->old_fb = crtc->primary->fb;  	ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);  	if (ret) { -		if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { -			spin_lock_irqsave(&dev->event_lock, flags); -			file_priv->event_space += sizeof(e->event); -			spin_unlock_irqrestore(&dev->event_lock, flags); -			kfree(e); -		} +		if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) +			drm_event_cancel_free(dev, &e->base);  		/* Keep the old fb, don't unref it. */  		crtc->primary->old_fb = NULL;  	} else { @@ -5720,6 +5760,48 @@ int drm_format_vert_chroma_subsampling(uint32_t format)  EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);  /** + * drm_format_plane_width - width of the plane given the first plane + * @width: width of the first plane + * @format: pixel format + * @plane: plane index + * + * Returns: + * The width of @plane, given that the width of the first plane is @width. + */ +int drm_format_plane_width(int width, uint32_t format, int plane) +{ +	if (plane >= drm_format_num_planes(format)) +		return 0; + +	if (plane == 0) +		return width; + +	return width / drm_format_horz_chroma_subsampling(format); +} +EXPORT_SYMBOL(drm_format_plane_width); + +/** + * drm_format_plane_height - height of the plane given the first plane + * @height: height of the first plane + * @format: pixel format + * @plane: plane index + * + * Returns: + * The height of @plane, given that the height of the first plane is @height. + */ +int drm_format_plane_height(int height, uint32_t format, int plane) +{ +	if (plane >= drm_format_num_planes(format)) +		return 0; + +	if (plane == 0) +		return height; + +	return height / drm_format_vert_chroma_subsampling(format); +} +EXPORT_SYMBOL(drm_format_plane_height); + +/**   * drm_rotation_simplify() - Try to simplify the rotation   * @rotation: Rotation to be simplified   * @supported_rotations: Supported rotations | 
