Add Lontium LT7911EXC eDP to MIPI DSI bridge
Subsystems (4)
v11 cover Add Lontium LT7911EXC eDP to MIPI DSI bridge
From: Sunyun Yang <[email protected]>
The LT7911EXC is an I2C-controlled bridge that receives eDP1.4 and output mipi dsi. This series introduces:
- A device tree binding YAML file describing the hardware
- A new DRM bridge driver implementing the basic functionality
---
Change in v11:
- dt-binding:
- drm/bridge:
1. Removed Reviewed-by, we would appreciate it if the maintainer could help review this.
2. Use devm_gpiod_get(,, GPIOD_OUT_HIGH) to fix the reset GPIO backpowering issue. [sashiko-bot]
3. Fixed Use-After-Free vulnerability due to dynamic DRM bridge removal in DSI detach callback.
4. Fixed Use-After-Free of regmap during DRM teardown because firmware upgrade worker defeats removal safeguard.
5. Fixed firmware upgrade performs a hardware reset, causing silent loss of DRM state and a blank screen.
6. Use of kmalloc for a 64KB software buffer is susceptible to memory fragmentation failures - Fix by using kvmalloc
7. Use the 'lt7911exc->ocm_lock' mutex and the 'lt7911exc->upgrade' flag to resolve the race condition between DRM atomic modeset and firmware upgrade.
8. Use the 'lt7911exc->upgrade_lock' mutex to prevent redundant upgrades.
9. Use the 'lt7911exc->removed' flag to prevent the driver from being triggered to upgrade during the unload process.
- Link to v10: https://lore.kernel.org/lkml/[email protected]/
Change in v10:
- dt-binding:
- drm/bridge:
1. Fixed the firmware upgrade error paths to always clear the upgrade
flag before returning, including firmware size validation failures
and allocation failures. [sashiko-bot]
2. Added proper locking in lt7911exc_atomic_pre_enable() and lt7911exc_atomic_post_disable() to serialize register accesses with the firmware upgrade flow and avoid concurrent I2C transactions.
3. Added an exclusivity check in lt7911exc_dsi_host_attach() to reject multiple downstream attachments and prevent repeated drm_bridge_add() calls and panel bridge leaks.
4. Reworked lt7911exc_firmware_store() to use mutex_trylock() so concurrent sysfs writers immediately return -EBUSY instead of blocking behind an active firmware upgrade.
5. Updated the remove path to prevent new firmware upgrade work from being queued after device removal by setting the upgrade state before cancelling the worker.
- Link to v9: https://lore.kernel.org/lkml/[email protected]/
Change in v9:
- dt-binding:
- drm/bridge:
1. DSI transfer callback returns success for reads without populating [sashiko-bot]
the receive buffer, leaking uninitialized memory. - fixed it by implementing a strict whitelist mechanism.
2. DSI transfer callback polls for eDP video readiness before the
upstream encoder is enabled, guaranteeing a timeout. - removed
3. The driver attempts I2C transfers while the hardware is held in
physical reset. - fixed
4. Missing DRM_MIPI_DSI Kconfig dependency causes linker errors. - fixed
5. request_firmware is called while holding the hardware lock and
halting the MCU, risking a system pipeline stall. - fixed
6. Sleeping functions are called from atomic context in the DRM bridge callbacks. - fixed
7. lt7911exc_dsi_host_transfer bypasses the required MCU hardware halt sequence. - fixed by internal firmware controls the panel initialization sequence and handles all MIPI DSI command transmission.
- Link to v8: https://lore.kernel.org/lkml/[email protected]/
Change in v8:
- dt-binding:
- drm/bridge:
1. Protect firmware upgrade and DRM bridge callback paths with ocm_lock. [sashiko-bot]
2. Remove the hardware reset from the remove callback, and ensure that all hardware reset operations are protected by ocm_lock.
3. crc reconstruction explicitly casts each byte to u32 before shifting
4. The display configuration is handled by the firmware, and the MIPI DSI host registration issue has been fixed.
5. The batch register read/write operations have already been updated to include return value checking.
6. The dev_err_probe() used outside of probe context has been fixed.
- Link to v7: https://lore.kernel.org/lkml/[email protected]/
Change in v7:
- dt-binding:
1. fix commit message typos(Receiver、signal) [sashiko-bot]
2. remove the ambiguity caused by "signal/dual".
- drm/bridge:
1. using devm_regulator_get_enable avoids power leaks. [sashiko-bot]
2. set reset gpio is low after cutting off power in lt7911exc_remove function, avoid backpowering.
3. synchronous request_firmware() call cause a permanent probe failure if the driver is built-in, probe executes before the root filesystem is mounted, which would cause this to fail with -ENOENT, we have removed this functionality. Use trigger to upgrade.
4. add depends on I2C and select REGMAP_I2C in Kconfig.
5. add return value of devm_drm_bridge_add() in probe().
6. add directly header files (linux/slab.h, linux/delay.h, linux/regulator/consumer.h)
- Link to v6: https://lore.kernel.org/lkml/[email protected]/
Change in v6:
- dt-binding:
- drm/bridge:
1. use #define FW_FILE "Lontium/lt7911exc_fw.bin" to match linux-firmware
- Link to v5: https://lore.kernel.org/lkml/[email protected]/
Change in v5:
- dt-binding:
- drm/bridge:
1. Change "mipi" to "mipi dsi" in the commit message. [Dmitry]
2. Change "eDP/MIPI" to "eDP/MIPI DSI" in Kconfig.
- Link to v4: https://lore.kernel.org/lkml/[email protected]/
Change in v4:
- dt-binding:
1. Fix the missing spaces on the "subject". [Krzysztof]
2. Fix the error descriptions for port@0 and port@1.
- drm/bridge:
- Link to v3: https://lore.kernel.org/lkml/[email protected]/
Change in v3:
- dt-binding:
- drm/bridge:
1. already submit lt7911exc_fw.bin to linux-firmware. [Dmitry]
2. remove lt7911exc_remove function.
3. drop the "lontium, " in lt7911exc_i2c_table.
- Link to v2: https://lore.kernel.org/lkml/[email protected]/
Change in v2:
- dt-binding:
1. reset pins use active low. [Dmitry]
- drm/bridge:
1. use atomic_* callbacks. [Quentin]
2. fix the incorrect formatting and spaces.
3. add the required header files. [Dmitry]
4. remove "enabled" flag.
5. remove *fw from the lt7911exc struct.
6. .max_register and .range_max use actual range.
7. regulator use bulk interface.
8. use dev_err_probe, devm_mutex_init and devm_drm_bridge_add.
9. Replace GPL v2 with GPL.
- Link to v1: https://lore.kernel.org/lkml/[email protected]/
---
Sunyun Yang (2):
dt-bindings: bridge: Add Lontium LT7911EXC eDP to MIPI DSI bridge drm/bridge: Add Lontium LT7911EXC eDP to MIPI DSI bridge
.../display/bridge/lontium,lt7911exc.yaml | 89 +++ drivers/gpu/drm/bridge/Kconfig | 16 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/lontium-lt7911exc.c | 698 ++++++++++++++++++ 4 files changed, 804 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/lontium,lt7911exc.yaml create mode 100644 drivers/gpu/drm/bridge/lontium-lt7911exc.c
Signature · 1 line
2.34.1
PATCH v11 1/2 dt-bindings: bridge: Add Lontium LT7911EXC eDP to MIPI DSI bridge
From: Sunyun Yang <[email protected]>
This commit adds the device tree binding schema for the Lontium LT7911EXC. This device is an I2C-controlled bridge that converts eDP 1.4 input to MIPI DSI output.
--- .../display/bridge/lontium,lt7911exc.yaml | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/lontium,lt7911exc.yaml
Documentation/devicetree/bindings/display/bridge/lontium,lt7911exc.yaml new file +89 -0
@@ -0,0 +1,89 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/lontium,lt7911exc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lontium LT7911EXC eDP to MIPI DSI Bridge + +maintainers: + - Sunyun Yang <[email protected]> + +properties: + compatible: + enum: + - lontium,lt7911exc + + reg: + maxItems: 1 + + reset-gpios: + maxItems: 1 + description: GPIO connected to RST_ pin. + + vdd-supply: + description: Regulator for 1.2V MIPI phy power. + + vcc-supply: + description: Regulator for 3.3V IO power. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Video port for eDP input. + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Video port for MIPI DSI output. + + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - reset-gpios + - vdd-supply + - vcc-supply + - ports + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + mipi-bridge@41 { + compatible = "lontium,lt7911exc"; + reg = <0x41>; + reset-gpios = <&gpy8 8 GPIO_ACTIVE_LOW>; + vdd-supply = <<7911exc_1v2>; + vcc-supply = <<7911exc_3v3>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + bridge_in: endpoint { + remote-endpoint = <&edp_out>; + }; + }; + + port@1 { + reg = <1>; + bridge_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; + }; + };
Signature · 1 line
2.34.1
PATCH v11 2/2 drm/bridge: Add Lontium LT7911EXC eDP to MIPI DSI bridge
In reply to [email protected]From: Sunyun Yang <[email protected]>
Add support for the Lontium LT7911EXC bridge chip, which converts eDP input to MIPI DSI output using an internal firmware-controlled pipeline.
The driver provides:
- DRM bridge integration for eDP-to-DSI routing
- MIPI DSI host interface for downstream panel attachment
- Firmware upgrade mechanism over I2C (erase/program/verify)
- GPIO-based reset and regulator management
Display timing and MIPI DCS packet generation are handled by the chip firmware and are not configured by the driver.
--- drivers/gpu/drm/bridge/Kconfig | 16 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/lontium-lt7911exc.c | 698 +++++++++++++++++++++ 3 files changed, 715 insertions(+) create mode 100644 drivers/gpu/drm/bridge/lontium-lt7911exc.c
drivers/gpu/drm/bridge/Kconfig +16 -0
@@ -132,6 +132,22 @@ config DRM_ITE_IT6505 help ITE IT6505 DisplayPort bridge chip driver. +config DRM_LONTIUM_LT7911EXC + tristate "Lontium eDP/MIPI DSI bridge" + depends on OF + depends on I2C + select CRC32 + select DRM_PANEL + select DRM_MIPI_DSI + select DRM_KMS_HELPER + select FW_LOADER + select REGMAP_I2C + help + DRM driver for the Lontium LT7911EXC bridge + chip.The LT7911EXC converts eDP input to MIPI + DSI output. + Please say Y if you have such hardware. + config DRM_LONTIUM_LT8912B tristate "Lontium LT8912B DSI/HDMI bridge" depends on OF
drivers/gpu/drm/bridge/Makefile +1 -0
@@ -13,6 +13,7 @@ obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o obj-$(CONFIG_DRM_INNO_HDMI) += inno-hdmi.o obj-$(CONFIG_DRM_ITE_IT6263) += ite-it6263.o obj-$(CONFIG_DRM_ITE_IT6505) += ite-it6505.o +obj-$(CONFIG_DRM_LONTIUM_LT7911EXC) += lontium-lt7911exc.o obj-$(CONFIG_DRM_LONTIUM_LT8912B) += lontium-lt8912b.o obj-$(CONFIG_DRM_LONTIUM_LT9211) += lontium-lt9211.o obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +698 -0
698 lines not on this page · raw message
Signature · 1 line
2.34.1
[email protected]
AI reviewRe: [PATCH v11 2/2] drm/bridge: Add Lontium LT7911EXC eDP to MIPI DSI bridge
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [High] Missing drm_panel_bridge_remove() in lt7911exc_dsi_host_detach() causes bridge list corruption and…
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Missing drm_panel_bridge_remove() in lt7911exc_dsi_host_detach() causes bridge list corruption and Use-After-Free.
- [Medium] The fast ocm_lock is held during a 420ms hardware reset sequence, causing severe latency stalls for concurrent DRM and DSI operations. --
commit 7a7cfdfb50c450205bc811aedab79e9db1683754
Author: Sunyun Yang <[email protected]>
drm/bridge: Add Lontium LT7911EXC eDP to MIPI DSI bridge
Add support for the Lontium LT7911EXC bridge chip, which converts eDP input to MIPI DSI output using an internal firmware-controlled pipeline.
Quoted 5 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +0
-0
[ ... ]
Quoted 4 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +4
-0+static void lt7911exc_firmware_upgrade_work (struct work_struct *work) +{ + struct lt7911exc *lt7911exc = container_of(work, struct lt7911exc, work); +struct device *dev = lt7911exc->dev;
[ ... ]
drivers/gpu/drm/bridge/lontium-lt7911exc.c line 347
Quoted 4 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +4
-0+mutex_lock (<7911exc->upgrade_lock); + +mutex_lock (<7911exc->ocm_lock); +lt7911exc_reset (lt7911exc);
[Severity: Medium]
Since lt7911exc_reset() sleeps for 420ms (due to msleep calls), does holding the fast ocm_lock here unnecessarily stall concurrent DRM and DSI operations?
It looks like the upgrade_lock already serializes firmware upgrades. Can the ocm_lock be acquired after the reset sequence?
Quoted 4 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +4
-0+lt7911exc_hw_mcu_halt (lt7911exc); +mutex_unlock (<7911exc->ocm_lock); + + ret =lt7911exc_block_erase (lt7911exc);
[ ... ]
drivers/gpu/drm/bridge/lontium-lt7911exc.c line 370
Quoted 8 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +8
-0+ ret =lt7911exc_write_crc (lt7911exc, crc32,FW_SIZE -4 ); +if (ret <0 ) { +dev_err (dev,"failed to write firmware crc\n" ); + goto out_unlock; + } + +mutex_lock (<7911exc->ocm_lock); +lt7911exc_reset (lt7911exc);
[Severity: Medium]
Similarly, does holding the ocm_lock during this second reset sequence cause severe latency stalls for other display operations?
Quoted 3 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +3
-0+mutex_unlock (<7911exc->ocm_lock); + + ret =lt7911exc_upgrade_result (lt7911exc, crc32);
[ ... ]
drivers/gpu/drm/bridge/lontium-lt7911exc.c line 477
Quoted 8 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +8
-0+static int lt7911exc_dsi_host_detach (struct mipi_dsi_host *host,struct mipi_dsi_device *dev) +{ +struct lt7911exc *lt7911exc =dsi_host_to_lt7911exc (host); + +if (!lt7911exc->output.dev) +return 0 ; + + lt7911exc->output.dev =NULL ;
[Severity: High]
Should drm_panel_bridge_remove() be called here?
When the panel is unbound, its device is destroyed and the devres cleanup frees the bridge memory. If the bridge isn't properly removed here, the freed bridge remains linked in the global DRM bridge_list, potentially causing a use-after-free on subsequent list traversals.
Quoted 3 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +3
-0+ +return 0 ; +}
[ ... ]
Quoted 3 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +3
-0+static void lt7911exc_remove (struct i2c_client *client) +{ +struct lt7911exc *lt7911exc =i2c_get_clientdata (client);
[ ... ]
drivers/gpu/drm/bridge/lontium-lt7911exc.c line 665
Quoted 5 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +5
-0+mipi_dsi_host_unregister (<7911exc->dsi_host); +drm_bridge_remove (<7911exc->bridge); + +if (lt7911exc->output.panel && lt7911exc->output.bridge) +drm_panel_bridge_remove (lt7911exc->output.bridge);
[Severity: High]
Can this dereference a freed pointer?
Since mipi_dsi_host_unregister() triggers panel detachment, and lt7911exc_dsi_host_detach() doesn't remove the panel bridge, the bridge memory could be freed during the detachment. Calling drm_panel_bridge_remove() here would then lead to a use-after-free.
Quoted 3 lines
drivers/gpu/drm/bridge/lontium-lt7911exc.c new file +3
-0+ +gpiod_set_value_cansleep (lt7911exc->reset_gpio,1 ); +}
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2