drm: add encoder / get encoder to the modesetting resources interface
authorDave Airlie <airlied@redhat.com>
Fri, 30 May 2008 02:03:36 +0000 (12:03 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 30 May 2008 02:03:36 +0000 (12:03 +1000)
linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/drm_crtc_helper.h
linux-core/drm_drv.c

index f7e7bfa..5d5448c 100644 (file)
@@ -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
index 7bb779e..adaa49b 100644 (file)
@@ -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__ */
 
index f56b97c..9e16861 100644 (file)
@@ -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);
index d96b14b..6111c85 100644 (file)
@@ -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),