drm/bridge: lt9211: Add drive-strength-microamp DT property
Subsystems (4)
cover drm/bridge: lt9211: Add drive-strength-microamp DT property
The LT9211 LVDS TX output driver current is currently hardcoded to 0x8 (~25 uA). Some board layouts require a different drive strength to meet signal integrity requirements.
This series adds support for the standard 'drive-strength-microamp' DT property, allowing board DTs to select one of sixteen discrete current levels between 12 uA and 36 uA. The default preserves the existing behaviour.
Boerge Struempfel (2):
dt-bindings: display/bridge: lt9211: Add drive-strength-microamp
property
drm/bridge: lt9211: Add drive-strength-microamp DT property
.../display/bridge/lontium,lt9211.yaml | 7 +++++ drivers/gpu/drm/bridge/lontium-lt9211.c | 28 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-)
Signature · 1 line
2.54.0
PATCH 1/2 dt-bindings: display/bridge: lt9211: Add drive-strength-microamp property
Add the 'drive-strength-microamp' property to allow board DTs to configure the LT9211 LVDS TX output driver current. Sixteen discrete levels are supported, ranging from 12 uA to 36 uA. Defaults to 25 uA.
--- .../devicetree/bindings/display/bridge/lontium,lt9211.yaml | 7 +++++++ 1 file changed, 7 insertions(+)
Documentation/devicetree/bindings/display/bridge/lontium,lt9211.yaml +7 -0
@@ -31,6 +31,13 @@ properties: vccio-supply: description: Regulator for 1.8V IO power. + drive-strength-microamp: + description: + LVDS TX output driver current. Sixteen discrete levels are supported, + corresponding to the following nominal values in microamps. + enum: [12, 14, 16, 17, 19, 20, 22, 23, 25, 27, 28, 30, 31, 33, 34, 36] + default: 25 + ports: $ref: /schemas/graph.yaml#/properties/ports
Signature · 1 line
2.54.0
Re: [PATCH 1/2] dt-bindings: display/bridge: lt9211: Add drive-strength-microamp property
Quoted 5 lines · Boerge Struempfel
Add the 'drive-strength-microamp' property to allow board DTs to configure the LT9211 LVDS TX output driver current. Sixteen discrete levels are supported, ranging from 12 uA to 36 uA. Defaults to 25 uA.
Signed-off-by Boerge Struempfel <[email protected]>
pw-bot: not-applicable
[email protected]
AI reviewRe: [PATCH 1/2] dt-bindings: display/bridge: lt9211: Add drive-strength-microamp property
In reply to Boerge StruempfelThank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] The values proposed for `drive-strength-microamp` are incorrect by two orders of magnitude…
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The values proposed for drive-strength-microamp are incorrect by two orders of magnitude, exposing an internal reference current rather than the actual pad output current and violating standard DT unit semantics. --
commit 97454d8731d851d94cc1fb58faf0cb4d4b8ca94c
Author: Boerge Struempfel <[email protected]>
dt-bindings: display/bridge: lt9211: Add drive-strength-microamp property
This commit adds the drive-strength-microamp property to allow configuring the LT9211 LVDS TX output driver current. It supports 16 discrete levels ranging from 12 to 36 microamps, and sets a default of 25 microamps.
Quoted 3 lines
Documentation/devicetree/bindings/display/bridge/lontium,lt9211.yaml +0
-0
[ ... ]
Documentation/devicetree/bindings/display/bridge/lontium,lt9211.yaml properties: · line 38
Quoted 9 lines
Documentation/devicetree/bindings/display/bridge/lontium,lt9211.yaml +5
-0@@ -31,6 +31,13 @@ properties: vccio-supply: description: Regulator for 1.8V IO power. + drive-strength-microamp: + description: + LVDS TX output driver current. Sixteen discrete levels are supported, + corresponding to the following nominal values in microamps. + enum: [12, 14, 16, 17, 19, 20, 22, 23, 25, 27, 28, 30, 31, 33, 34, 36]
Are these values exposing an internal reference current rather than the actual pad output current?
A subsequent commit in the series mentions that the hardware supports discrete current levels starting at 12.5 microamps with a step of 1.5625 microamps.
However, standard LVDS signaling typically requires a drive current of around 3.5 mA (3500 microamps) to produce the required 350 mV voltage swing across a standard 100-ohm termination. A 25 microamp drive current would only produce a 2.5 mV swing, which appears too small for an LVDS link.
Since drive-strength-microamp is a standard property, using it to expose an internal reference scale might permanently hardcode incorrect physical units into the device tree ABI.
Should the enum instead reflect the actual multiplied pad output current, which might be closer to the range of 1250 to 3600 microamps?
Quoted 4 lines
Documentation/devicetree/bindings/display/bridge/lontium,lt9211.yaml +2
-0+ default: 25 + ports: $ref: /schemas/graph.yaml#/properties/ports
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
PATCH 2/2 drm/bridge: lt9211: Add drive-strength-microamp DT property
In reply to Boerge StruempfelThe LT9211 LVDS TX output driver current (RG_MLTX_HSDRV_ISEL) was previously hardcoded to 0x8 (~25 uA), which may not be optimal for all board layouts.
The hardware supports 16 discrete current levels starting at 12.5 uA with a step of 1.5625 uA. These are exposed as rounded integer microamp values in the lookup table.
Add support for the 'drive-strength-microamp' DT property. A lookup table maps the sixteen supported microamp values (12..36 uA) to the corresponding register field. Defaults to 25 uA when the property is absent, preserving the existing behaviour.
--- drivers/gpu/drm/bridge/lontium-lt9211.c | 28 ++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
drivers/gpu/drm/bridge/lontium-lt9211.c +27 -1
@@ -40,6 +40,11 @@/* DSI lane count - 0 means 4 lanes ; 1, 2, 3 means 1, 2, 3 lanes. */ #define REG_DSI_LANE_COUNT (n) ((n) & 3) +/* Maps register value (index) to drive-strength-microamp DT property value */ +static const u32 lt9211_hsdrv_microamp[] = { +12 ,14 ,16 ,17 ,19 ,20 ,22 ,23 ,25 ,27 ,28 ,30 ,31 ,33 ,34 ,36 +}; +struct lt9211 {struct drm_bridge bridge;struct device *dev;
@@ -50,6 +55,7 @@ struct lt9211 {struct regulator *vccio;bool lvds_dual_link;bool lvds_dual_link_even_odd_swap; +u8 lvds_hsdrv_isel; };static const struct regmap_range lt9211_rw_ranges[] = {
@@ -374,7 +380,8 @@ static int lt9211_configure_tx(struct lt9211 *ctx, bool jeida,/* BIT(7) is LVDS dual-port */ { 0x823b, 0x38 | (ctx->lvds_dual_link ? BIT(7) : 0) }, { 0x823e, 0x92 }, - { 0x823f, 0x48 }, +/* bits 3:0: RG_MLTX_HSDRV_ISEL, LVDS TX driver current */ + { 0x823f, 0x40 | ctx->lvds_hsdrv_isel }, { 0x8240, 0x31 }, { 0x8243, 0x80 }, { 0x8244, 0x00 },
@@ -629,7 +636,9 @@ static int lt9211_parse_dt(struct lt9211 *ctx)struct device *dev = ctx->dev;struct drm_panel *panel;int dual_link; +u32 microamp;int ret; +int i; ctx->vccio =devm_regulator_get (dev,"vccio" );if (IS_ERR (ctx->vccio))
@@ -666,6 +675,23 @@ static int lt9211_parse_dt(struct lt9211 *ctx) ctx->panel_bridge = panel_bridge; + ctx->lvds_hsdrv_isel =8 ;/* default: 25 uA */ + ret =of_property_read_u32 (dev->of_node,"drive-strength-microamp" , + µamp); +if (!ret) { +for (i =0 ; i <ARRAY_SIZE (lt9211_hsdrv_microamp); i++) { +if (lt9211_hsdrv_microamp[i] == microamp) { + ctx->lvds_hsdrv_isel = i; +break ; + } + } +if (i ==ARRAY_SIZE (lt9211_hsdrv_microamp)) { +dev_err (dev,"Invalid drive-strength-microamp value %u\n" , + microamp); +return -EINVAL ; + } + } +return 0 ; }
Signature · 1 line
2.54.0
drivers/gpu/drm/bridge/lontium-lt9211.c line 44
Quoted 2 lines · Boerge Struempfel
drivers/gpu/drm/bridge/lontium-lt9211.c +2
-0+/* Maps register value (index) to drive-strength-microamp DT property value */ +static const u32 lt9211_hsdrv_microamp[] = {
This can be u8 .
Quoted 35 lines
drivers/gpu/drm/bridge/lontium-lt9211.c +8
-1+12 ,14 ,16 ,17 ,19 ,20 ,22 ,23 ,25 ,27 ,28 ,30 ,31 ,33 ,34 ,36 +}; +struct lt9211 {struct drm_bridge bridge;struct device *dev;@@ -50,6 +55,7 @@ struct lt9211 {struct regulator *vccio;bool lvds_dual_link;bool lvds_dual_link_even_odd_swap; +u8 lvds_hsdrv_isel; };static const struct regmap_range lt9211_rw_ranges[] = {@@ -374,7 +380,8 @@ static int lt9211_configure_tx(struct lt9211 *ctx, bool jeida,/* BIT(7) is LVDS dual-port */ { 0x823b, 0x38 | (ctx->lvds_dual_link ? BIT(7) : 0) }, { 0x823e, 0x92 }, - { 0x823f, 0x48 }, +/* bits 3:0: RG_MLTX_HSDRV_ISEL, LVDS TX driver current */ + { 0x823f, 0x40 | ctx->lvds_hsdrv_isel }, { 0x8240, 0x31 }, { 0x8243, 0x80 }, { 0x8244, 0x00 },@@ -629,7 +636,9 @@ static int lt9211_parse_dt(struct lt9211 *ctx)struct device *dev = ctx->dev;struct drm_panel *panel;int dual_link; +u32 microamp;int ret; +int i; ctx->vccio =devm_regulator_get (dev,"vccio" );if (IS_ERR (ctx->vccio))
drivers/gpu/drm/bridge/lontium-lt9211.c static int lt9211_parse_dt(struct lt9211 *ctx) · line 680
Quoted 6 lines
drivers/gpu/drm/bridge/lontium-lt9211.c +3
-0@@ -666,6 +675,23 @@ static int lt9211_parse_dt(struct lt9211 *ctx) ctx->panel_bridge = panel_bridge; + ctx->lvds_hsdrv_isel =8 ;/* default: 25 uA */ + ret =of_property_read_u32 (dev->of_node,"drive-strength-microamp" , + µamp);
if ret != 0 , then what happens here ?
Quoted 15 lines
drivers/gpu/drm/bridge/lontium-lt9211.c +14
-0+if (!ret) { +for (i =0 ; i <ARRAY_SIZE (lt9211_hsdrv_microamp); i++) { +if (lt9211_hsdrv_microamp[i] == microamp) { + ctx->lvds_hsdrv_isel = i; +break ; + } + } +if (i ==ARRAY_SIZE (lt9211_hsdrv_microamp)) { +dev_err (dev,"Invalid drive-strength-microamp value %u\n" , + microamp); +return -EINVAL ; + } + } +return 0 ;
[...]
Hello Marek,
Thank you for your feedback,
Quoted 7 lines · Marek Vasut
drivers/gpu/drm/bridge/lontium-lt9211.c line 44
Quoted 2 lines · Boerge Struempfel
drivers/gpu/drm/bridge/lontium-lt9211.c +2
-0+/* Maps register value (index) to drive-strength-microamp DT property value */ +static const u32 lt9211_hsdrv_microamp[] = {This can be u8 .
you are right, I'll change that in the v2.
Quoted 36 lines
Quoted 36 lines
drivers/gpu/drm/bridge/lontium-lt9211.c +8
-1+12 ,14 ,16 ,17 ,19 ,20 ,22 ,23 ,25 ,27 ,28 ,30 ,31 ,33 ,34 ,36 +}; +struct lt9211 {struct drm_bridge bridge;struct device *dev;@@ -50,6 +55,7 @@ struct lt9211 {struct regulator *vccio;bool lvds_dual_link;bool lvds_dual_link_even_odd_swap; +u8 lvds_hsdrv_isel; };static const struct regmap_range lt9211_rw_ranges[] = {@@ -374,7 +380,8 @@ static int lt9211_configure_tx(struct lt9211 *ctx, bool jeida,/* BIT(7) is LVDS dual-port */ { 0x823b, 0x38 | (ctx->lvds_dual_link ? BIT(7) : 0) }, { 0x823e, 0x92 }, - { 0x823f, 0x48 }, +/* bits 3:0: RG_MLTX_HSDRV_ISEL, LVDS TX driver current */ + { 0x823f, 0x40 | ctx->lvds_hsdrv_isel }, { 0x8240, 0x31 }, { 0x8243, 0x80 }, { 0x8244, 0x00 },@@ -629,7 +636,9 @@ static int lt9211_parse_dt(struct lt9211 *ctx)struct device *dev = ctx->dev;struct drm_panel *panel;int dual_link; +u32 microamp;int ret; +int i; ctx->vccio =devm_regulator_get (dev,"vccio" );if (IS_ERR (ctx->vccio))@@ -666,6 +675,23 @@ static int lt9211_parse_dt(struct lt9211 *ctx)
Quoted 8 lines
drivers/gpu/drm/bridge/lontium-lt9211.c static int lt9211_parse_dt(struct lt9211 *ctx) · line 680
Quoted 5 lines
drivers/gpu/drm/bridge/lontium-lt9211.c +3
-0ctx->panel_bridge = panel_bridge; + ctx->lvds_hsdrv_isel =8 ;/* default: 25 uA */ + ret =of_property_read_u32 (dev->of_node,"drive-strength-microamp" , + µamp);if ret != 0 , then what happens here ?
if ret != 0, we will keep the default value of 8 (corresponding to 25 uA as written above), which is the behavior that the driver had previously.
According to the documentation, of_property_read_u32() will return 0 on success, -EINVAL if the property does not exist, -ENODATA if property does not have a value, and -EOVERFLOW if the property data isn't large enough. I think we only would need to give a warning or similar if the -ENODATA or -EOVERFLOW cases. However, I personally do not think that is necessary, as the usage is specified unambiguously in the devicetree bindings.
If you feel like we should add a warning in those cases, I can add them however.
Quoted 17 lines
Quoted 15 lines
drivers/gpu/drm/bridge/lontium-lt9211.c +14
-0+if (!ret) { +for (i =0 ; i <ARRAY_SIZE (lt9211_hsdrv_microamp); i++) { +if (lt9211_hsdrv_microamp[i] == microamp) { + ctx->lvds_hsdrv_isel = i; +break ; + } + } +if (i ==ARRAY_SIZE (lt9211_hsdrv_microamp)) { +dev_err (dev,"Invalid drive-strength-microamp value %u\n" , + microamp); +return -EINVAL ; + } + } +return 0 ;[...]
Signature · 6 lines
Best regards, Börge Strümpfel DATA MODUL AG Landsberger Str. 322 80687 München
On 5/13/26 11:02 AM, Börge Strümpfel wrote:
[...]
Quoted 10 lines
Quoted 6 lines
drivers/gpu/drm/bridge/lontium-lt9211.c static int lt9211_parse_dt(struct lt9211 *ctx) · line 680
Quoted 3 lines
drivers/gpu/drm/bridge/lontium-lt9211.c +3
-0+ ctx->lvds_hsdrv_isel =8 ;/* default: 25 uA */ + ret =of_property_read_u32 (dev->of_node,"drive-strength-microamp" , + µamp);if ret != 0 , then what happens here ?
if ret != 0, we will keep the default value of 8 (corresponding to 25 uA as written above), which is the behavior that the driver had previously.
Quoted 7 lines
According to the documentation,
of_property_read_u32()will return 0 on success,-EINVALif the property does not exist,-ENODATAif property does not have a value, and-EOVERFLOWif the property data isn't large enough. I think we only would need to give a warning or similar if the-ENODATAor-EOVERFLOWcases. However, I personally do not think that is necessary, as the usage is specified unambiguously in the devicetree bindings.
Users can pass in malformed DT, so a warning is a good idea. Thanks.