aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-10-20 02:17:17 -0400
committerDave Airlie <airlied@redhat.com>2014-12-08 18:56:46 -0500
commit138f9ebb9755a8cf09fd6a9ff8d011aaf5fb478f (patch)
tree167bcb1d1c10d7ea77ac084399698c7ad7c616ac /drivers/gpu
parentb49b55bd4fba6aa9bb25459e0ac3991c60c4aba4 (diff)
drm: add tile_group support. (v3)
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. v2: destroy idr (dvdhrm) add docbook (danvet) airlied:- not sure how to make docbook add fns to tile group section. v3: fix missing unlock. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/drm_crtc.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index de79283eaea7..0d1eaa9966e9 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -5152,6 +5152,7 @@ void drm_mode_config_init(struct drm_device *dev)
5152 INIT_LIST_HEAD(&dev->mode_config.property_blob_list); 5152 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
5153 INIT_LIST_HEAD(&dev->mode_config.plane_list); 5153 INIT_LIST_HEAD(&dev->mode_config.plane_list);
5154 idr_init(&dev->mode_config.crtc_idr); 5154 idr_init(&dev->mode_config.crtc_idr);
5155 idr_init(&dev->mode_config.tile_idr);
5155 5156
5156 drm_modeset_lock_all(dev); 5157 drm_modeset_lock_all(dev);
5157 drm_mode_create_standard_connector_properties(dev); 5158 drm_mode_create_standard_connector_properties(dev);
@@ -5239,6 +5240,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
5239 crtc->funcs->destroy(crtc); 5240 crtc->funcs->destroy(crtc);
5240 } 5241 }
5241 5242
5243 idr_destroy(&dev->mode_config.tile_idr);
5242 idr_destroy(&dev->mode_config.crtc_idr); 5244 idr_destroy(&dev->mode_config.crtc_idr);
5243 drm_modeset_lock_fini(&dev->mode_config.connection_mutex); 5245 drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
5244} 5246}
@@ -5261,3 +5263,100 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
5261 supported_rotations); 5263 supported_rotations);
5262} 5264}
5263EXPORT_SYMBOL(drm_mode_create_rotation_property); 5265EXPORT_SYMBOL(drm_mode_create_rotation_property);
5266
5267/**
5268 * DOC: Tile group
5269 *
5270 * Tile groups are used to represent tiled monitors with a unique
5271 * integer identifier. Tiled monitors using DisplayID v1.3 have
5272 * a unique 8-byte handle, we store this in a tile group, so we
5273 * have a common identifier for all tiles in a monitor group.
5274 */
5275static void drm_tile_group_free(struct kref *kref)
5276{
5277 struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);
5278 struct drm_device *dev = tg->dev;
5279 mutex_lock(&dev->mode_config.idr_mutex);
5280 idr_remove(&dev->mode_config.tile_idr, tg->id);
5281 mutex_unlock(&dev->mode_config.idr_mutex);
5282 kfree(tg);
5283}
5284
5285/**
5286 * drm_mode_put_tile_group - drop a reference to a tile group.
5287 * @dev: DRM device
5288 * @tg: tile group to drop reference to.
5289 *
5290 * drop reference to tile group and free if 0.
5291 */
5292void drm_mode_put_tile_group(struct drm_device *dev,
5293 struct drm_tile_group *tg)
5294{
5295 kref_put(&tg->refcount, drm_tile_group_free);
5296}
5297
5298/**
5299 * drm_mode_get_tile_group - get a reference to an existing tile group
5300 * @dev: DRM device
5301 * @topology: 8-bytes unique per monitor.
5302 *
5303 * Use the unique bytes to get a reference to an existing tile group.
5304 *
5305 * RETURNS:
5306 * tile group or NULL if not found.
5307 */
5308struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
5309 char topology[8])
5310{
5311 struct drm_tile_group *tg;
5312 int id;
5313 mutex_lock(&dev->mode_config.idr_mutex);
5314 idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
5315 if (!memcmp(tg->group_data, topology, 8)) {
5316 if (!kref_get_unless_zero(&tg->refcount))
5317 tg = NULL;
5318 mutex_unlock(&dev->mode_config.idr_mutex);
5319 return tg;
5320 }
5321 }
5322 mutex_unlock(&dev->mode_config.idr_mutex);
5323 return NULL;
5324}
5325
5326/**
5327 * drm_mode_create_tile_group - create a tile group from a displayid description
5328 * @dev: DRM device
5329 * @topology: 8-bytes unique per monitor.
5330 *
5331 * Create a tile group for the unique monitor, and get a unique
5332 * identifier for the tile group.
5333 *
5334 * RETURNS:
5335 * new tile group or error.
5336 */
5337struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
5338 char topology[8])
5339{
5340 struct drm_tile_group *tg;
5341 int ret;
5342
5343 tg = kzalloc(sizeof(*tg), GFP_KERNEL);
5344 if (!tg)
5345 return ERR_PTR(-ENOMEM);
5346
5347 kref_init(&tg->refcount);
5348 memcpy(tg->group_data, topology, 8);
5349 tg->dev = dev;
5350
5351 mutex_lock(&dev->mode_config.idr_mutex);
5352 ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);
5353 if (ret >= 0) {
5354 tg->id = ret;
5355 } else {
5356 kfree(tg);
5357 tg = ERR_PTR(ret);
5358 }
5359
5360 mutex_unlock(&dev->mode_config.idr_mutex);
5361 return tg;
5362}