Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/bridge: Document the probe issue with MIPI-DSI bridges

Interactions between bridges, panels, MIPI-DSI host and the component
framework are not trivial and can lead to probing issues when
implementing a display driver. Let's document the various cases we need
too consider, and the solution to support all the cases.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210910101218.1632297-3-maxime@cerno.tech

+63
+6
Documentation/gpu/drm-kms-helpers.rst
··· 157 157 .. kernel-doc:: drivers/gpu/drm/drm_bridge.c 158 158 :doc: display driver integration 159 159 160 + Special Care with MIPI-DSI bridges 161 + ---------------------------------- 162 + 163 + .. kernel-doc:: drivers/gpu/drm/drm_bridge.c 164 + :doc: special care dsi 165 + 160 166 Bridge Operations 161 167 ----------------- 162 168
+57
drivers/gpu/drm/drm_bridge.c
··· 95 95 * documentation of bridge operations for more details). 96 96 */ 97 97 98 + /** 99 + * DOC: special care dsi 100 + * 101 + * The interaction between the bridges and other frameworks involved in 102 + * the probing of the upstream driver and the bridge driver can be 103 + * challenging. Indeed, there's multiple cases that needs to be 104 + * considered: 105 + * 106 + * - The upstream driver doesn't use the component framework and isn't a 107 + * MIPI-DSI host. In this case, the bridge driver will probe at some 108 + * point and the upstream driver should try to probe again by returning 109 + * EPROBE_DEFER as long as the bridge driver hasn't probed. 110 + * 111 + * - The upstream driver doesn't use the component framework, but is a 112 + * MIPI-DSI host. The bridge device uses the MIPI-DCS commands to be 113 + * controlled. In this case, the bridge device is a child of the 114 + * display device and when it will probe it's assured that the display 115 + * device (and MIPI-DSI host) is present. The upstream driver will be 116 + * assured that the bridge driver is connected between the 117 + * &mipi_dsi_host_ops.attach and &mipi_dsi_host_ops.detach operations. 118 + * Therefore, it must run mipi_dsi_host_register() in its probe 119 + * function, and then run drm_bridge_attach() in its 120 + * &mipi_dsi_host_ops.attach hook. 121 + * 122 + * - The upstream driver uses the component framework and is a MIPI-DSI 123 + * host. The bridge device uses the MIPI-DCS commands to be 124 + * controlled. This is the same situation than above, and can run 125 + * mipi_dsi_host_register() in either its probe or bind hooks. 126 + * 127 + * - The upstream driver uses the component framework and is a MIPI-DSI 128 + * host. The bridge device uses a separate bus (such as I2C) to be 129 + * controlled. In this case, there's no correlation between the probe 130 + * of the bridge and upstream drivers, so care must be taken to avoid 131 + * an endless EPROBE_DEFER loop, with each driver waiting for the 132 + * other to probe. 133 + * 134 + * The ideal pattern to cover the last item (and all the others in the 135 + * MIPI-DSI host driver case) is to split the operations like this: 136 + * 137 + * - The MIPI-DSI host driver must run mipi_dsi_host_register() in its 138 + * probe hook. It will make sure that the MIPI-DSI host sticks around, 139 + * and that the driver's bind can be called. 140 + * 141 + * - In its probe hook, the bridge driver must try to find its MIPI-DSI 142 + * host, register as a MIPI-DSI device and attach the MIPI-DSI device 143 + * to its host. The bridge driver is now functional. 144 + * 145 + * - In its &struct mipi_dsi_host_ops.attach hook, the MIPI-DSI host can 146 + * now add its component. Its bind hook will now be called and since 147 + * the bridge driver is attached and registered, we can now look for 148 + * and attach it. 149 + * 150 + * At this point, we're now certain that both the upstream driver and 151 + * the bridge driver are functional and we can't have a deadlock-like 152 + * situation when probing. 153 + */ 154 + 98 155 static DEFINE_MUTEX(bridge_lock); 99 156 static LIST_HEAD(bridge_list); 100 157