[PATCH 2/6] drm: add tile_group support.

David Herrmann dh.herrmann at gmail.com
Mon Oct 20 02:11:09 PDT 2014


Hi

On Mon, Oct 20, 2014 at 8:37 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> A tile group is an identifier shared by a single monitor,
> DisplayID topology has 8 bytes we can use for this, just
> use those for now until something else comes up in the
> future. We assign these to an idr and use the idr to
> tell userspace what connectors are in the same tile group.
>
> DisplayID v1.3 says the serial number must be unique for
> displays from the same manufacturer.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  drivers/gpu/drm/drm_crtc.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_crtc.h     | 16 ++++++++++++
>  2 files changed, 77 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 90e7730..dfccc34 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -5037,6 +5037,7 @@ void drm_mode_config_init(struct drm_device *dev)
>         INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
>         INIT_LIST_HEAD(&dev->mode_config.plane_list);
>         idr_init(&dev->mode_config.crtc_idr);
> +       idr_init(&dev->mode_config.tile_idr);

You are missing a call to idr_destroy() in drm_mode_config_cleanup().
The IDR caches are not cleaned up automatically when it drops to size
0...

Thanks
David

>
>         drm_modeset_lock_all(dev);
>         drm_mode_create_standard_connector_properties(dev);
> @@ -5146,3 +5147,63 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
>                                            supported_rotations);
>  }
>  EXPORT_SYMBOL(drm_mode_create_rotation_property);
> +
> +static void drm_tile_group_free(struct kref *kref)
> +{
> +       struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);
> +       struct drm_device *dev = tg->dev;
> +       mutex_lock(&dev->mode_config.idr_mutex);
> +       idr_remove(&dev->mode_config.tile_idr, tg->id);
> +       mutex_lock(&dev->mode_config.idr_mutex);
> +       kfree(tg);
> +}
> +
> +void drm_mode_put_tile_group(struct drm_device *dev,
> +                            struct drm_tile_group *tg)
> +{
> +       kref_put(&tg->refcount, drm_tile_group_free);
> +}
> +
> +struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
> +                                              char topology[8])
> +{
> +       struct drm_tile_group *tg;
> +       int id;
> +       mutex_lock(&dev->mode_config.idr_mutex);
> +       idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
> +               if (!memcmp(tg->group_data, topology, 8)) {
> +                       kref_get(&tg->refcount);
> +                       mutex_unlock(&dev->mode_config.idr_mutex);
> +                       return tg;
> +               }
> +       }
> +       mutex_unlock(&dev->mode_config.idr_mutex);
> +       return NULL;
> +}
> +
> +struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
> +                                                 char topology[8])
> +{
> +       struct drm_tile_group *tg;
> +       int ret;
> +
> +       tg = kzalloc(sizeof(*tg), GFP_KERNEL);
> +       if (!tg)
> +               return ERR_PTR(-ENOMEM);
> +
> +       kref_init(&tg->refcount);
> +       memcpy(tg->group_data, topology, 8);
> +       tg->dev = dev;
> +
> +       mutex_lock(&dev->mode_config.idr_mutex);
> +       ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);
> +       if (ret >= 0) {
> +               tg->id = ret;
> +       } else {
> +               kfree(tg);
> +               tg = NULL;
> +       }
> +
> +       mutex_unlock(&dev->mode_config.idr_mutex);
> +       return tg;
> +}
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index f1105d0..afaec4b 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -136,6 +136,14 @@ struct drm_display_info {
>         u8 cea_rev;
>  };
>
> +/* data corresponds to displayid vend/prod/serial */
> +struct drm_tile_group {
> +       struct kref refcount;
> +       struct drm_device *dev;
> +       int id;
> +       u8 group_data[8];
> +};
> +
>  struct drm_framebuffer_funcs {
>         /* note: use drm_framebuffer_remove() */
>         void (*destroy)(struct drm_framebuffer *framebuffer);
> @@ -770,6 +778,7 @@ struct drm_mode_config {
>         struct drm_modeset_acquire_ctx *acquire_ctx; /* for legacy _lock_all() / _unlock_all() */
>         struct mutex idr_mutex; /* for IDR management */
>         struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */
> +       struct idr tile_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */
>         /* this is limited to one for now */
>
>
> @@ -1106,6 +1115,13 @@ extern void drm_set_preferred_mode(struct drm_connector *connector,
>  extern int drm_edid_header_is_valid(const u8 *raw_edid);
>  extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid);
>  extern bool drm_edid_is_valid(struct edid *edid);
> +
> +extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
> +                                                        char topology[8]);
> +extern struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
> +                                              char topology[8]);
> +extern void drm_mode_put_tile_group(struct drm_device *dev,
> +                                  struct drm_tile_group *tg);
>  struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
>                                            int hsize, int vsize, int fresh,
>                                            bool rb);
> --
> 2.1.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list