Hi Tomi, Am Montag, 31. Juli 2023, 14:13:14 CEST schrieb Tomi Valkeinen: > DRM bridges are not visible to the userspace and it may not be > immediately clear if the chain is somehow constructed incorrectly. I > have had two separate instances of a bridge driver failing to do a > drm_bridge_attach() call, resulting in the bridge connector not being > part of the chain. In some situations this doesn't seem to cause issues, > but it will if DRM_BRIDGE_ATTACH_NO_CONNECTOR flag is used. > > Add a debugfs file to print the bridge chains. For me, on this TI AM62 > based platform, I get the following output: > > encoder[39] > bridge[0] type: 0, ops: 0x0 > bridge[1] type: 0, ops: 0x0, OF: > /bus@f0000/i2c@20000000/dsi@e:toshiba,tc358778 bridge[2] type: 0, ops: 0x3, > OF: /bus@f0000/i2c@20010000/hdmi@48:lontium,lt8912b bridge[3] type: 11, > ops: 0x7, OF: /hdmi-connector:hdmi-connector > > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@xxxxxxxxxxxxxxxx> Looks good: $ for dev in /sys/kernel/debug/dri/*; do cat $dev/bridge_chains; done cat: /sys/kernel/debug/dri/0/bridge_chains: No such file or directory encoder[36] bridge[0] type: 0, ops: 0x0, OF: /soc@0/bus@32c00000/display- bridge@32fc4000:fsl,imx8mp-hdmi-pvi bridge[1] type: 0, ops: 0x7, OF: /soc@0/bus@32c00000/ hdmi@32fd8000:fsl,imx8mp-hdmi cat: /sys/kernel/debug/dri/128/bridge_chains: No such file or directory encoder[36] bridge[0] type: 16, ops: 0x0, OF: /soc@0/bus@32c00000/ dsi@32e60000:fsl,imx8mp-mipi-dsim bridge[1] type: 10, ops: 0x3, OF: /soc@0/bus@30800000/i2c@30a30000/ bridge@f:toshiba,tc9595 Tested-by: Alexander Stein <alexander.stein@xxxxxxxxxxxxxxx> > --- > Changes in v3: > - Use drm_for_each_bridge_in_chain() > - Drop extra comment > - Fix whitespace issue > - Call drm_bridge_debugfs_init() only if the driver uses modeset > - Drop #ifdef for drm_bridge_debugfs_init() declaration > - Link to v2: > https://lore.kernel.org/r/20230721-drm-bridge-chain-debugfs-v2-1-76df943479 > 62@xxxxxxxxxxxxxxxx > > Changes in v2: > - Fixed compilation issue when !CONFIG_OF > - Link to v1: > https://lore.kernel.org/r/20230721-drm-bridge-chain-debugfs-v1-1-8614ff7e89 > 0d@xxxxxxxxxxxxxxxx --- > drivers/gpu/drm/drm_bridge.c | 46 > +++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_debugfs.c | > 3 +++ > include/drm/drm_bridge.h | 3 +++ > 3 files changed, 52 insertions(+) > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c > index c3d69af02e79..39e68e45bb12 100644 > --- a/drivers/gpu/drm/drm_bridge.c > +++ b/drivers/gpu/drm/drm_bridge.c > @@ -27,8 +27,10 @@ > #include <linux/mutex.h> > > #include <drm/drm_atomic_state_helper.h> > +#include <drm/drm_debugfs.h> > #include <drm/drm_bridge.h> > #include <drm/drm_encoder.h> > +#include <drm/drm_file.h> > #include <drm/drm_of.h> > #include <drm/drm_print.h> > > @@ -1345,6 +1347,50 @@ struct drm_bridge *of_drm_find_bridge(struct > device_node *np) EXPORT_SYMBOL(of_drm_find_bridge); > #endif > > +#ifdef CONFIG_DEBUG_FS > +static int drm_bridge_chains_info(struct seq_file *m, void *data) > +{ > + struct drm_debugfs_entry *entry = m->private; > + struct drm_device *dev = entry->dev; > + struct drm_printer p = drm_seq_file_printer(m); > + struct drm_mode_config *config = &dev->mode_config; > + struct drm_encoder *encoder; > + unsigned int bridge_idx = 0; > + > + list_for_each_entry(encoder, &config->encoder_list, head) { > + struct drm_bridge *bridge; > + > + drm_printf(&p, "encoder[%u]\n", encoder->base.id); > + > + drm_for_each_bridge_in_chain(encoder, bridge) { > + drm_printf(&p, "\tbridge[%u] type: %u, ops: %#x", > + bridge_idx, bridge->type, bridge- >ops); > + > +#ifdef CONFIG_OF > + if (bridge->of_node) > + drm_printf(&p, ", OF: %pOFfc", bridge- >of_node); > +#endif > + > + drm_printf(&p, "\n"); > + > + bridge_idx++; > + } > + } > + > + return 0; > +} > + > +static const struct drm_debugfs_info drm_bridge_debugfs_list[] = { > + { "bridge_chains", drm_bridge_chains_info, 0 }, > +}; > + > +void drm_bridge_debugfs_init(struct drm_minor *minor) > +{ > + drm_debugfs_add_files(minor->dev, drm_bridge_debugfs_list, > + ARRAY_SIZE(drm_bridge_debugfs_list)); > +} > +#endif > + > MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@xxxxxxxxxxx>"); > MODULE_DESCRIPTION("DRM bridge infrastructure"); > MODULE_LICENSE("GPL and additional rights"); > diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c > index a3a488205009..3b1de2c61c89 100644 > --- a/drivers/gpu/drm/drm_debugfs.c > +++ b/drivers/gpu/drm/drm_debugfs.c > @@ -31,6 +31,7 @@ > > #include <drm/drm_atomic.h> > #include <drm/drm_auth.h> > +#include <drm/drm_bridge.h> > #include <drm/drm_client.h> > #include <drm/drm_debugfs.h> > #include <drm/drm_device.h> > @@ -274,6 +275,8 @@ int drm_debugfs_init(struct drm_minor *minor, int > minor_id, > > if (drm_drv_uses_atomic_modeset(dev)) { > drm_atomic_debugfs_init(minor); > + > + drm_bridge_debugfs_init(minor); > } > > if (drm_core_check_feature(dev, DRIVER_MODESET)) { > diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h > index bf964cdfb330..cb10ee108538 100644 > --- a/include/drm/drm_bridge.h > +++ b/include/drm/drm_bridge.h > @@ -949,4 +949,7 @@ static inline struct drm_bridge > *drmm_of_get_bridge(struct drm_device *drm, } > #endif > > +struct drm_minor; > +void drm_bridge_debugfs_init(struct drm_minor *minor); > + > #endif > > --- > base-commit: a0c64d153d687756c8719b8d10e609d62e1cb6fd > change-id: 20230721-drm-bridge-chain-debugfs-0bbc1522f57a > > Best regards, -- TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany Amtsgericht München, HRB 105018 Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider http://www.tq-group.com/