diff options
| -rw-r--r-- | linux-core/drm_crtc.c | 56 | ||||
| -rw-r--r-- | linux-core/drm_crtc.h | 4 | ||||
| -rw-r--r-- | linux-core/drm_crtc_helper.h | 9 | ||||
| -rw-r--r-- | linux-core/drm_drv.c | 1 | 
4 files changed, 67 insertions, 3 deletions
| diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index f7e7bfa8..5d5448c5 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -784,6 +784,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)  {  	struct drm_output *output, *ot;  	struct drm_crtc *crtc, *ct; +	struct drm_encoder *encoder, *enct;  	struct drm_framebuffer *fb, *fbt;  	struct drm_property *property, *pt; @@ -804,6 +805,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)  			dev->driver->fb_remove(dev, fb);  	} +	list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list, head) { +		encoder->funcs->destroy(encoder); +	} +  	list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {  		crtc->funcs->destroy(crtc);  	} @@ -911,14 +916,17 @@ int drm_mode_getresources(struct drm_device *dev,  	struct drm_framebuffer *fb;  	struct drm_output *output;  	struct drm_crtc *crtc; +	struct drm_encoder *encoder;  	int ret = 0;  	int output_count = 0;  	int crtc_count = 0;  	int fb_count = 0; +	int encoder_count = 0;  	int copied = 0;  	uint32_t __user *fb_id;  	uint32_t __user *crtc_id;  	uint32_t __user *output_id; +	uint32_t __user *encoder_id;  	mutex_lock(&dev->mode_config.mutex); @@ -931,6 +939,9 @@ int drm_mode_getresources(struct drm_device *dev,  	list_for_each(lh, &dev->mode_config.output_list)  		output_count++; +	list_for_each(lh, &dev->mode_config.encoder_list) +		encoder_count++; +  	card_res->max_height = dev->mode_config.max_height;  	card_res->min_height = dev->mode_config.min_height;  	card_res->max_width = dev->mode_config.max_width; @@ -982,9 +993,25 @@ int drm_mode_getresources(struct drm_device *dev,  		}  	}  	card_res->count_outputs = output_count; + +	/* Encoders */ +	if (card_res->count_encoders >= encoder_count) { +		copied = 0; +		encoder_id = (uint32_t *)(unsigned long)card_res->encoder_id_ptr; +		list_for_each_entry(encoder, &dev->mode_config.encoder_list, +				    head) { + 			DRM_DEBUG("ENCODER ID is %d\n", encoder->id); +			if (put_user(encoder->id, encoder_id + copied)) { +				ret = -EFAULT; +				goto out; +			} +			copied++; +		} +	} +	card_res->count_encoders = encoder_count; -	DRM_DEBUG("Counted %d %d\n", card_res->count_crtcs, -		  card_res->count_outputs); +	DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs, +		  card_res->count_outputs, card_res->count_encoders);  out:	  	mutex_unlock(&dev->mode_config.mutex); @@ -1165,6 +1192,31 @@ out:  	return ret;  } +int drm_mode_getencoder(struct drm_device *dev, +			void *data, struct drm_file *file_priv) +{ +	struct drm_mode_get_encoder *enc_resp = data; +	struct drm_encoder *encoder; +	int ret = 0; +	 +	mutex_lock(&dev->mode_config.mutex); +	encoder = idr_find(&dev->mode_config.crtc_idr, enc_resp->encoder_id); +	if (!encoder || (encoder->id != enc_resp->encoder_id)) { +		DRM_DEBUG("Unknown encoder ID %d\n", enc_resp->encoder_id); +		ret = -EINVAL; +		goto out; +	} + +	enc_resp->encoder_type = encoder->encoder_type; +	enc_resp->encoder_id = encoder->id; +	enc_resp->crtcs = encoder->possible_crtcs; +	enc_resp->clones = encoder->possible_clones; +	 +out: +	mutex_unlock(&dev->mode_config.mutex); +	return ret; +} +  /**   * drm_mode_setcrtc - set CRTC configuration   * @inode: inode from the ioctl diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 7bb779ef..adaa49bd 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -366,7 +366,6 @@ struct drm_crtc {  /**   * drm_output_funcs - control outputs on a given device - * @init: setup this output   * @dpms: set power state (see drm_crtc_funcs above)   * @save: save output state   * @restore: restore output state @@ -417,6 +416,7 @@ struct drm_encoder {  	uint32_t possible_clones;  	const struct drm_encoder_funcs *funcs; +	void *helper_private;  };  /** @@ -663,5 +663,7 @@ extern int drm_mode_hotplug_ioctl(struct drm_device *dev,  				  void *data, struct drm_file *file_priv);  extern int drm_mode_replacefb(struct drm_device *dev,  			      void *data, struct drm_file *file_priv); +int drm_mode_getencoder(struct drm_device *dev, +			void *data, struct drm_file *file_priv);  #endif /* __DRM_CRTC_H__ */ diff --git a/linux-core/drm_crtc_helper.h b/linux-core/drm_crtc_helper.h index f56b97c6..9e16861d 100644 --- a/linux-core/drm_crtc_helper.h +++ b/linux-core/drm_crtc_helper.h @@ -47,6 +47,15 @@ struct drm_output_helper_funcs {  			 struct drm_display_mode *adjusted_mode);  }; +struct drm_encoder_helper_funcs { +	void (*prepare)(struct drm_output *output); +	void (*commit)(struct drm_output *output); +	void (*mode_set)(struct drm_output *output, +			 struct drm_display_mode *mode, +			 struct drm_display_mode *adjusted_mode); +}; +	 +  extern int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_output *output,  					bool connected);  extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow); diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index d96b14b6..6111c850 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -142,6 +142,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {  	DRM_IOCTL_DEF(DRM_IOCTL_WAIT_HOTPLUG, drm_wait_hotplug, 0),  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_REPLACEFB, drm_mode_replacefb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), +	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),  	DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,  		      DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 
