[PATCH v2 1/2] drm: Add drm_bridge
On Wed, Aug 14, 2013 at 4:47 PM, Sean Paul wrote: > 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 Ok, I've had a chance to rebase my msm drm-bridge patch on top of this latest version (which I'll be sending in a couple of minutes) Reviewed-by: Rob Clark > --- > drivers/gpu/drm/drm_crtc.c| 50 ++ > drivers/gpu/drm/drm_crtc_helper.c | 89 > ++- > include/drm/drm_crtc.h| 55 > 3 files changed, 175 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index fc83bb9..0311e2b 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -781,6 +781,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, >base, DRM_MODE_OBJECT_BRIDGE); > + if (ret) > + goto out; > + > + bridge->dev = dev; > + bridge->funcs = funcs; > + > + list_add_tail(>head, >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, >base); > + list_del(>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, > @@ -1190,6 +1225,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) > @@ -1198,6 +1234,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; > } > > @@ -1207,6 +1244,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))) > @@ -1223,6 +1261,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, >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); > @@ -3905,6 +3948,7 @@ void drm_mode_config_init(struct drm_device *dev) > INIT_LIST_HEAD(>mode_config.fb_list); > INIT_LIST_HEAD(>mode_config.crtc_list); > INIT_LIST_HEAD(>mode_config.connector_list); > + INIT_LIST_HEAD(>mode_config.bridge_list); > INIT_LIST_HEAD(>mode_config.encoder_list); > INIT_LIST_HEAD(>mode_config.property_list); > INIT_LIST_HEAD(>mode_config.property_blob_list); > @@ -3941,6 +3985,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; > @@ -3951,6 +3996,11 @@ void drm_mode_config_cleanup(struct drm_device *dev) > encoder->funcs->destroy(encoder); > } > > + list_for_each_entry_safe(bridge, brt, > +>mode_config.bridge_list,
Re: [PATCH v2 1/2] drm: Add drm_bridge
On Wed, Aug 14, 2013 at 4:47 PM, Sean Paul seanp...@chromium.org wrote: 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 seanp...@chromium.org Ok, I've had a chance to rebase my msm drm-bridge patch on top of this latest version (which I'll be sending in a couple of minutes) Reviewed-by: Rob Clark robdcl...@gmail.com --- drivers/gpu/drm/drm_crtc.c| 50 ++ drivers/gpu/drm/drm_crtc_helper.c | 89 ++- include/drm/drm_crtc.h| 55 3 files changed, 175 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fc83bb9..0311e2b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -781,6 +781,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, @@ -1190,6 +1225,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) @@ -1198,6 +1234,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; } @@ -1207,6 +1244,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))) @@ -1223,6 +1261,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); @@ -3905,6 +3948,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); @@ -3941,6 +3985,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; @@ -3951,6 +3996,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) { +
[PATCH v2 1/2] drm: Add drm_bridge
On Thu, Aug 29, 2013 at 12:13:16PM -0400, Rob Clark wrote: > On Thu, Aug 29, 2013 at 11:59 AM, Sean Paul wrote: > > On Wed, Aug 14, 2013 at 4:47 PM, Sean Paul wrote: > >> 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). > >> > > > > Friendly ping. Any feedback? > > It looks good to me, although unfortunately I've not had a chance to > rebase on this version. I'll try to make some time to do that in the > next few days. Looks good to me, no more bikesheds from my side. I kinda wanted to port over some of the stuff we have in drm/i915, but I guess that won't happen anytime soon. Imo this can go in as soon as we have an in-tree user ready. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
[PATCH v2 1/2] drm: Add drm_bridge
On Thu, Aug 29, 2013 at 11:59 AM, Sean Paul wrote: > On Wed, Aug 14, 2013 at 4:47 PM, Sean Paul wrote: >> 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). >> > > Friendly ping. Any feedback? It looks good to me, although unfortunately I've not had a chance to rebase on this version. I'll try to make some time to do that in the next few days. BR, -R > Sean > > >> Signed-off-by: Sean Paul >> --- >> drivers/gpu/drm/drm_crtc.c| 50 ++ >> drivers/gpu/drm/drm_crtc_helper.c | 89 >> ++- >> include/drm/drm_crtc.h| 55 >> 3 files changed, 175 insertions(+), 19 deletions(-) >> >> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c >> index fc83bb9..0311e2b 100644 >> --- a/drivers/gpu/drm/drm_crtc.c >> +++ b/drivers/gpu/drm/drm_crtc.c >> @@ -781,6 +781,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, >base, >> DRM_MODE_OBJECT_BRIDGE); >> + if (ret) >> + goto out; >> + >> + bridge->dev = dev; >> + bridge->funcs = funcs; >> + >> + list_add_tail(>head, >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, >base); >> + list_del(>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, >> @@ -1190,6 +1225,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) >> @@ -1198,6 +1234,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; >> } >> >> @@ -1207,6 +1244,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))) >> @@ -1223,6 +1261,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, >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); >> @@ -3905,6 +3948,7 @@ void drm_mode_config_init(struct drm_device *dev) >> INIT_LIST_HEAD(>mode_config.fb_list); >> INIT_LIST_HEAD(>mode_config.crtc_list); >> INIT_LIST_HEAD(>mode_config.connector_list); >> + INIT_LIST_HEAD(>mode_config.bridge_list); >> INIT_LIST_HEAD(>mode_config.encoder_list); >> INIT_LIST_HEAD(>mode_config.property_list); >> INIT_LIST_HEAD(>mode_config.property_blob_list); >> @@ -3941,6 +3985,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; >> @@ -3951,6 +3996,11 @@
[PATCH v2 1/2] drm: Add drm_bridge
On Wed, Aug 14, 2013 at 4:47 PM, Sean Paul wrote: > 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). > Friendly ping. Any feedback? Sean > Signed-off-by: Sean Paul > --- > drivers/gpu/drm/drm_crtc.c| 50 ++ > drivers/gpu/drm/drm_crtc_helper.c | 89 > ++- > include/drm/drm_crtc.h| 55 > 3 files changed, 175 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index fc83bb9..0311e2b 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -781,6 +781,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, >base, DRM_MODE_OBJECT_BRIDGE); > + if (ret) > + goto out; > + > + bridge->dev = dev; > + bridge->funcs = funcs; > + > + list_add_tail(>head, >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, >base); > + list_del(>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, > @@ -1190,6 +1225,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) > @@ -1198,6 +1234,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; > } > > @@ -1207,6 +1244,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))) > @@ -1223,6 +1261,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, >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); > @@ -3905,6 +3948,7 @@ void drm_mode_config_init(struct drm_device *dev) > INIT_LIST_HEAD(>mode_config.fb_list); > INIT_LIST_HEAD(>mode_config.crtc_list); > INIT_LIST_HEAD(>mode_config.connector_list); > + INIT_LIST_HEAD(>mode_config.bridge_list); > INIT_LIST_HEAD(>mode_config.encoder_list); > INIT_LIST_HEAD(>mode_config.property_list); > INIT_LIST_HEAD(>mode_config.property_blob_list); > @@ -3941,6 +3985,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; > @@ -3951,6 +3996,11 @@ void drm_mode_config_cleanup(struct drm_device *dev) > encoder->funcs->destroy(encoder); > } > > + list_for_each_entry_safe(bridge, brt, > +>mode_config.bridge_list, head) { > + bridge->funcs->destroy(bridge); > + } > + > list_for_each_entry_safe(connector, ot,
Re: [PATCH v2 1/2] drm: Add drm_bridge
On Wed, Aug 14, 2013 at 4:47 PM, Sean Paul seanp...@chromium.org wrote: 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). Friendly ping. Any feedback? Sean Signed-off-by: Sean Paul seanp...@chromium.org --- drivers/gpu/drm/drm_crtc.c| 50 ++ drivers/gpu/drm/drm_crtc_helper.c | 89 ++- include/drm/drm_crtc.h| 55 3 files changed, 175 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fc83bb9..0311e2b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -781,6 +781,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, @@ -1190,6 +1225,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) @@ -1198,6 +1234,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; } @@ -1207,6 +1244,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))) @@ -1223,6 +1261,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); @@ -3905,6 +3948,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); @@ -3941,6 +3985,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; @@ -3951,6 +3996,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,
Re: [PATCH v2 1/2] drm: Add drm_bridge
On Thu, Aug 29, 2013 at 11:59 AM, Sean Paul seanp...@chromium.org wrote: On Wed, Aug 14, 2013 at 4:47 PM, Sean Paul seanp...@chromium.org wrote: 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). Friendly ping. Any feedback? It looks good to me, although unfortunately I've not had a chance to rebase on this version. I'll try to make some time to do that in the next few days. BR, -R Sean Signed-off-by: Sean Paul seanp...@chromium.org --- drivers/gpu/drm/drm_crtc.c| 50 ++ drivers/gpu/drm/drm_crtc_helper.c | 89 ++- include/drm/drm_crtc.h| 55 3 files changed, 175 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fc83bb9..0311e2b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -781,6 +781,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, @@ -1190,6 +1225,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) @@ -1198,6 +1234,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; } @@ -1207,6 +1244,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))) @@ -1223,6 +1261,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); @@ -3905,6 +3948,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); @@ -3941,6 +3985,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; @@ -3951,6 +3996,11 @@ void drm_mode_config_cleanup(struct drm_device *dev) encoder-funcs-destroy(encoder); } + list_for_each_entry_safe(bridge, brt,
Re: [PATCH v2 1/2] drm: Add drm_bridge
On Thu, Aug 29, 2013 at 12:13:16PM -0400, Rob Clark wrote: On Thu, Aug 29, 2013 at 11:59 AM, Sean Paul seanp...@chromium.org wrote: On Wed, Aug 14, 2013 at 4:47 PM, Sean Paul seanp...@chromium.org wrote: 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). Friendly ping. Any feedback? It looks good to me, although unfortunately I've not had a chance to rebase on this version. I'll try to make some time to do that in the next few days. Looks good to me, no more bikesheds from my side. I kinda wanted to port over some of the stuff we have in drm/i915, but I guess that won't happen anytime soon. Imo this can go in as soon as we have an in-tree user ready. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 1/2] 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 --- drivers/gpu/drm/drm_crtc.c| 50 ++ drivers/gpu/drm/drm_crtc_helper.c | 89 ++- include/drm/drm_crtc.h| 55 3 files changed, 175 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fc83bb9..0311e2b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -781,6 +781,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, >base, DRM_MODE_OBJECT_BRIDGE); + if (ret) + goto out; + + bridge->dev = dev; + bridge->funcs = funcs; + + list_add_tail(>head, >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, >base); + list_del(>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, @@ -1190,6 +1225,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) @@ -1198,6 +1234,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; } @@ -1207,6 +1244,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))) @@ -1223,6 +1261,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, >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); @@ -3905,6 +3948,7 @@ void drm_mode_config_init(struct drm_device *dev) INIT_LIST_HEAD(>mode_config.fb_list); INIT_LIST_HEAD(>mode_config.crtc_list); INIT_LIST_HEAD(>mode_config.connector_list); + INIT_LIST_HEAD(>mode_config.bridge_list); INIT_LIST_HEAD(>mode_config.encoder_list); INIT_LIST_HEAD(>mode_config.property_list); INIT_LIST_HEAD(>mode_config.property_blob_list); @@ -3941,6 +3985,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; @@ -3951,6 +3996,11 @@ void drm_mode_config_cleanup(struct drm_device *dev) encoder->funcs->destroy(encoder); } + list_for_each_entry_safe(bridge, brt, +>mode_config.bridge_list, head) { + bridge->funcs->destroy(bridge); + } + list_for_each_entry_safe(connector, ot, >mode_config.connector_list, head) { connector->funcs->destroy(connector); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 6a64749..c722c3b 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -257,10 +257,16
[PATCH v2 1/2] 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 seanp...@chromium.org --- drivers/gpu/drm/drm_crtc.c| 50 ++ drivers/gpu/drm/drm_crtc_helper.c | 89 ++- include/drm/drm_crtc.h| 55 3 files changed, 175 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fc83bb9..0311e2b 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -781,6 +781,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, @@ -1190,6 +1225,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) @@ -1198,6 +1234,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; } @@ -1207,6 +1244,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))) @@ -1223,6 +1261,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); @@ -3905,6 +3948,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); @@ -3941,6 +3985,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; @@ -3951,6 +3996,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); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 6a64749..c722c3b 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++