summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2013-08-14 16:47:37 -0400
committerDave Airlie <airlied@redhat.com>2013-09-02 10:23:26 +1000
commit3b336ec4c5460833ad7573d0b6e22793f6a389ab (patch)
treed82b0a12cc700203203d1236197a25b2c12967be /drivers/gpu/drm/drm_crtc.c
parent2254f637dbd18f6432da526552d19a616ffbf8d6 (diff)
drm: Add drm_bridge
This patch adds the notion of a drm_bridge. A bridge is a chained device which hangs off an encoder. The drm driver using the bridge should provide the association between encoder and bridge. Once a bridge is associated with an encoder, it will participate in mode set, and dpms (via the enable/disable hooks). Signed-off-by: Sean Paul <seanpaul@chromium.org> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 452591b6799..5ebc972c0b6 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -799,6 +799,41 @@ void drm_connector_unplug_all(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_connector_unplug_all);
+int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge,
+ const struct drm_bridge_funcs *funcs)
+{
+ int ret;
+
+ drm_modeset_lock_all(dev);
+
+ ret = drm_mode_object_get(dev, &bridge->base, DRM_MODE_OBJECT_BRIDGE);
+ if (ret)
+ goto out;
+
+ bridge->dev = dev;
+ bridge->funcs = funcs;
+
+ list_add_tail(&bridge->head, &dev->mode_config.bridge_list);
+ dev->mode_config.num_bridge++;
+
+ out:
+ drm_modeset_unlock_all(dev);
+ return ret;
+}
+EXPORT_SYMBOL(drm_bridge_init);
+
+void drm_bridge_cleanup(struct drm_bridge *bridge)
+{
+ struct drm_device *dev = bridge->dev;
+
+ drm_modeset_lock_all(dev);
+ drm_mode_object_put(dev, &bridge->base);
+ list_del(&bridge->head);
+ dev->mode_config.num_bridge--;
+ drm_modeset_unlock_all(dev);
+}
+EXPORT_SYMBOL(drm_bridge_cleanup);
+
int drm_encoder_init(struct drm_device *dev,
struct drm_encoder *encoder,
const struct drm_encoder_funcs *funcs,
@@ -1184,6 +1219,7 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
total_objects += dev->mode_config.num_crtc;
total_objects += dev->mode_config.num_connector;
total_objects += dev->mode_config.num_encoder;
+ total_objects += dev->mode_config.num_bridge;
group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
if (!group->id_list)
@@ -1192,6 +1228,7 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
group->num_crtcs = 0;
group->num_connectors = 0;
group->num_encoders = 0;
+ group->num_bridges = 0;
return 0;
}
@@ -1201,6 +1238,7 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
struct drm_crtc *crtc;
struct drm_encoder *encoder;
struct drm_connector *connector;
+ struct drm_bridge *bridge;
int ret;
if ((ret = drm_mode_group_init(dev, group)))
@@ -1217,6 +1255,11 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
group->id_list[group->num_crtcs + group->num_encoders +
group->num_connectors++] = connector->base.id;
+ list_for_each_entry(bridge, &dev->mode_config.bridge_list, head)
+ group->id_list[group->num_crtcs + group->num_encoders +
+ group->num_connectors + group->num_bridges++] =
+ bridge->base.id;
+
return 0;
}
EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
@@ -3902,6 +3945,7 @@ void drm_mode_config_init(struct drm_device *dev)
INIT_LIST_HEAD(&dev->mode_config.fb_list);
INIT_LIST_HEAD(&dev->mode_config.crtc_list);
INIT_LIST_HEAD(&dev->mode_config.connector_list);
+ INIT_LIST_HEAD(&dev->mode_config.bridge_list);
INIT_LIST_HEAD(&dev->mode_config.encoder_list);
INIT_LIST_HEAD(&dev->mode_config.property_list);
INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
@@ -3938,6 +3982,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_connector *connector, *ot;
struct drm_crtc *crtc, *ct;
struct drm_encoder *encoder, *enct;
+ struct drm_bridge *bridge, *brt;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
struct drm_property_blob *blob, *bt;
@@ -3948,6 +3993,11 @@ void drm_mode_config_cleanup(struct drm_device *dev)
encoder->funcs->destroy(encoder);
}
+ list_for_each_entry_safe(bridge, brt,
+ &dev->mode_config.bridge_list, head) {
+ bridge->funcs->destroy(bridge);
+ }
+
list_for_each_entry_safe(connector, ot,
&dev->mode_config.connector_list, head) {
connector->funcs->destroy(connector);