* [PATCH v2 0/4] Add Novatek NT37705 panel driver for Fairphone (Gen. 6)
@ 2026-09-18 14:40 Luca Weiss
2026-09-18 14:40 ` [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 Luca Weiss
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Luca Weiss @ 2026-09-18 14:40 UTC (permalink / raw)
To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree,
linux-kernel, linux-arm-msm, Luca Weiss, Krzysztof Kozlowski,
Dmitry Baryshkov, Konrad Dybcio
Add bindings and a panel driver for the NT37705, and then enable display
on the Fairphone (Gen. 6).
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
Changes in v2:
- Fix kconfig dependencies of panel driver
- Pick up tags
- Link to v1: https://patch.msgid.link/20260501-fp6-panel-v1-0-e09cb05651cc@fairphone.com
---
Luca Weiss (4):
dt-bindings: display: panel: Add Novatek NT37705
drm/panel: Add driver for Novatek NT37705 panel
arm64: defconfig: Enable Novatek NT37705 panel
arm64: dts: qcom: milos-fairphone-fp6: Enable display
.../bindings/display/panel/novatek,nt37705.yaml | 72 ++++
arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts | 64 ++++
arch/arm64/configs/defconfig | 1 +
drivers/gpu/drm/panel/Kconfig | 12 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-novatek-nt37705.c | 413 +++++++++++++++++++++
6 files changed, 563 insertions(+)
---
base-commit: c2cd463d6ee7d55a3ec0719d93c49ff99022d58f
change-id: 20260501-fp6-panel-3d35c999d894
Best regards,
--
Luca Weiss <luca.weiss@fairphone.com>
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 2026-09-18 14:40 [PATCH v2 0/4] Add Novatek NT37705 panel driver for Fairphone (Gen. 6) Luca Weiss @ 2026-09-18 14:40 ` Luca Weiss 2026-09-18 14:51 ` sashiko-bot 2026-09-18 21:35 ` Rob Herring 2026-09-18 14:40 ` [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel Luca Weiss ` (2 subsequent siblings) 3 siblings, 2 replies; 12+ messages in thread From: Luca Weiss @ 2026-09-18 14:40 UTC (permalink / raw) To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio Cc: ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree, linux-kernel, linux-arm-msm, Luca Weiss, Krzysztof Kozlowski Novatek NT37705 is a display driver IC used to drive AMOLED DSI panels. Describe it and the panel in the Fairphone (Gen. 6) (BJ631JHM-T71-D900 from BOE) using it. Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Link: https://lore.kernel.org/r/81a3c207-4d8f-490f-8e2a-6f3f4c2acd35@kernel.org/ Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> --- .../bindings/display/panel/novatek,nt37705.yaml | 72 ++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml new file mode 100644 index 000000000000..1c796599f6fc --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/novatek,nt37705.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT37705-based DSI display panels + +maintainers: + - Luca Weiss <luca.weiss@fairphone.com> + +description: + The Novatek NT37705 is a generic DSI Panel IC used to control AMOLED panels. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: + contains: + const: boe,bj631jhm-t71-d900 + + reg: + maxItems: 1 + + vddio-supply: + description: I/O voltage rail + + dvdd-supply: + description: Digital voltage rail + + vci-supply: + description: Analog voltage rail + +required: + - compatible + - reg + - reset-gpios + - vddio-supply + - dvdd-supply + - vci-supply + - port + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + dsi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "boe,bj631jhm-t71-d900"; + reg = <0>; + + reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>; + + vci-supply = <&vreg_l19b>; + vddio-supply = <&vreg_l9b>; + dvdd-supply = <&vreg_oled_dvdd_1p2>; + + port { + panel_in_0: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + }; + }; + +... -- 2.55.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 2026-09-18 14:40 ` [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 Luca Weiss @ 2026-09-18 14:51 ` sashiko-bot 2026-09-18 21:35 ` Rob Herring 1 sibling, 0 replies; 12+ messages in thread From: sashiko-bot @ 2026-09-18 14:51 UTC (permalink / raw) To: Luca Weiss; +Cc: devicetree, conor+dt, robh, dri-devel Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] dt-bindings: loose compatible schema allows undocumented strings and omits IC fallback -- commit df95ba2aa44d396fccc370e5b084b78edf5052e8 Author: Luca Weiss <luca.weiss@fairphone.com> dt-bindings: display: panel: Add Novatek NT37705 This commit adds a new device tree binding for the Novatek NT37705, a display driver IC for AMOLED DSI panels. It also describes the BOE BJ631JHM-T71-D900 panel used in the Fairphone Gen. 6. Link: https://lore.kernel.org/r/81a3c207-4d8f-490f-8e2a-6f3f4c2acd35@kernel.org/ > diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml > new file mode 100644 > index 0000000000000..1c796599f6fce > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml > @@ -0,0 +1,72 @@ > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/panel/novatek,nt37705.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Novatek NT37705-based DSI display panels > + > +maintainers: > + - Luca Weiss <luca.weiss@fairphone.com> > + > +description: > + The Novatek NT37705 is a generic DSI Panel IC used to control AMOLED panels. > + > +allOf: > + - $ref: panel-common.yaml# > + > +properties: > + compatible: > + contains: > + const: boe,bj631jhm-t71-d900 [Severity: Medium] Will this loose containment check in properties.compatible allow undocumented strings to silently pass validation? In dt-schema, the contains keyword only verifies that at least one item matches the constraint, without restricting the presence, length, or content of additional items in the array. Consequently, a poorly crafted device tree node with compatible = "undocumented-garbage", "boe,bj631jhm-t71-d900"; will silently pass validation, defeating strict schema checking. Specific panel strings should be constrained with an exact match (e.g., const or enum), or an items array if fallbacks are used. Additionally, standard practice for generic panel ICs is to include a generic fallback string. Should the novatek,nt37705 fallback be included here? For example: items: [ enum: [ boe,bj631jhm-t71-d900 ], const: novatek,nt37705 ] The generic string novatek,nt37705 mentioned in the schema description is completely missing from the schema definition and the example. [ ... ] -- Sashiko AI review · https://sashiko.dev/#/patchset/20260918-fp6-panel-v2-0-6695c4008920@fairphone.com?part=1 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 2026-09-18 14:40 ` [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 Luca Weiss 2026-09-18 14:51 ` sashiko-bot @ 2026-09-18 21:35 ` Rob Herring 2026-10-02 14:00 ` Luca Weiss 1 sibling, 1 reply; 12+ messages in thread From: Rob Herring @ 2026-09-18 21:35 UTC (permalink / raw) To: Luca Weiss Cc: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio, ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree, linux-kernel, linux-arm-msm, Krzysztof Kozlowski On Fri, Sep 18, 2026 at 04:40:04PM +0200, Luca Weiss wrote: > Novatek NT37705 is a display driver IC used to drive AMOLED DSI panels. > > Describe it and the panel in the Fairphone (Gen. 6) (BJ631JHM-T71-D900 > from BOE) using it. > > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> > Link: https://lore.kernel.org/r/81a3c207-4d8f-490f-8e2a-6f3f4c2acd35@kernel.org/ > Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> > --- > .../bindings/display/panel/novatek,nt37705.yaml | 72 ++++++++++++++++++++++ > 1 file changed, 72 insertions(+) > > diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml > new file mode 100644 > index 000000000000..1c796599f6fc > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml Did novatek,nt37705 get dropped as a compatible, but the filename remains? > @@ -0,0 +1,72 @@ > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/panel/novatek,nt37705.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Novatek NT37705-based DSI display panels > + > +maintainers: > + - Luca Weiss <luca.weiss@fairphone.com> > + > +description: > + The Novatek NT37705 is a generic DSI Panel IC used to control AMOLED panels. > + > +allOf: > + - $ref: panel-common.yaml# > + > +properties: > + compatible: > + contains: As sashiko reports, "contains" is too loose. > + const: boe,bj631jhm-t71-d900 > + > + reg: > + maxItems: 1 > + > + vddio-supply: > + description: I/O voltage rail > + > + dvdd-supply: > + description: Digital voltage rail > + > + vci-supply: > + description: Analog voltage rail > + > +required: > + - compatible > + - reg > + - reset-gpios > + - vddio-supply > + - dvdd-supply > + - vci-supply > + - port > + > +unevaluatedProperties: false > + > +examples: > + - | > + #include <dt-bindings/gpio/gpio.h> > + > + dsi { > + #address-cells = <1>; > + #size-cells = <0>; > + > + panel@0 { > + compatible = "boe,bj631jhm-t71-d900"; > + reg = <0>; > + > + reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>; > + > + vci-supply = <&vreg_l19b>; > + vddio-supply = <&vreg_l9b>; > + dvdd-supply = <&vreg_oled_dvdd_1p2>; > + > + port { > + panel_in_0: endpoint { > + remote-endpoint = <&dsi0_out>; > + }; > + }; > + }; > + }; > + > +... > > -- > 2.55.0 > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 2026-09-18 21:35 ` Rob Herring @ 2026-10-02 14:00 ` Luca Weiss 2026-10-02 14:16 ` Rob Herring 0 siblings, 1 reply; 12+ messages in thread From: Luca Weiss @ 2026-10-02 14:00 UTC (permalink / raw) To: Rob Herring, Luca Weiss Cc: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio, ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree, linux-kernel, linux-arm-msm, Krzysztof Kozlowski Hi Rob, On Fri Sep 18, 2026 at 11:35 PM CEST, Rob Herring wrote: > On Fri, Sep 18, 2026 at 04:40:04PM +0200, Luca Weiss wrote: >> Novatek NT37705 is a display driver IC used to drive AMOLED DSI panels. >> >> Describe it and the panel in the Fairphone (Gen. 6) (BJ631JHM-T71-D900 >> from BOE) using it. >> >> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> >> Link: https://lore.kernel.org/r/81a3c207-4d8f-490f-8e2a-6f3f4c2acd35@kernel.org/ >> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> >> --- >> .../bindings/display/panel/novatek,nt37705.yaml | 72 ++++++++++++++++++++++ >> 1 file changed, 72 insertions(+) >> >> diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml >> new file mode 100644 >> index 000000000000..1c796599f6fc >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml > > Did novatek,nt37705 get dropped as a compatible, but the filename > remains? That's how himax,hx83112a.yaml and himax,hx83112b.yaml are as well, which I have upstreamed before. I *really* don't have strong opinions either way, but as in the email referred to in "Link:" the versions I have upstreamed before have been accepted without issue, and even discussion pointing in the way I have done things here. > >> @@ -0,0 +1,72 @@ >> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause >> +%YAML 1.2 >> +--- >> +$id: http://devicetree.org/schemas/display/panel/novatek,nt37705.yaml# >> +$schema: http://devicetree.org/meta-schemas/core.yaml# >> + >> +title: Novatek NT37705-based DSI display panels >> + >> +maintainers: >> + - Luca Weiss <luca.weiss@fairphone.com> >> + >> +description: >> + The Novatek NT37705 is a generic DSI Panel IC used to control AMOLED panels. >> + >> +allOf: >> + - $ref: panel-common.yaml# >> + >> +properties: >> + compatible: >> + contains: > > As sashiko reports, "contains" is too loose. Will fix, seems to also be an issue in the hx83112a/b yamls. > >> + const: boe,bj631jhm-t71-d900 >> + >> + reg: >> + maxItems: 1 >> + >> + vddio-supply: >> + description: I/O voltage rail >> + >> + dvdd-supply: >> + description: Digital voltage rail >> + >> + vci-supply: >> + description: Analog voltage rail >> + >> +required: >> + - compatible >> + - reg >> + - reset-gpios >> + - vddio-supply >> + - dvdd-supply >> + - vci-supply >> + - port >> + >> +unevaluatedProperties: false >> + >> +examples: >> + - | >> + #include <dt-bindings/gpio/gpio.h> >> + >> + dsi { >> + #address-cells = <1>; >> + #size-cells = <0>; >> + >> + panel@0 { >> + compatible = "boe,bj631jhm-t71-d900"; >> + reg = <0>; >> + >> + reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>; >> + >> + vci-supply = <&vreg_l19b>; >> + vddio-supply = <&vreg_l9b>; >> + dvdd-supply = <&vreg_oled_dvdd_1p2>; >> + >> + port { >> + panel_in_0: endpoint { >> + remote-endpoint = <&dsi0_out>; >> + }; >> + }; >> + }; >> + }; >> + >> +... >> >> -- >> 2.55.0 >> ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 2026-10-02 14:00 ` Luca Weiss @ 2026-10-02 14:16 ` Rob Herring 0 siblings, 0 replies; 12+ messages in thread From: Rob Herring @ 2026-10-02 14:16 UTC (permalink / raw) To: Luca Weiss Cc: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio, ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree, linux-kernel, linux-arm-msm, Krzysztof Kozlowski On Fri, Oct 02, 2026 at 04:00:49PM +0200, Luca Weiss wrote: > Hi Rob, > > On Fri Sep 18, 2026 at 11:35 PM CEST, Rob Herring wrote: > > On Fri, Sep 18, 2026 at 04:40:04PM +0200, Luca Weiss wrote: > >> Novatek NT37705 is a display driver IC used to drive AMOLED DSI panels. > >> > >> Describe it and the panel in the Fairphone (Gen. 6) (BJ631JHM-T71-D900 > >> from BOE) using it. > >> > >> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> > >> Link: https://lore.kernel.org/r/81a3c207-4d8f-490f-8e2a-6f3f4c2acd35@kernel.org/ > >> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> > >> --- > >> .../bindings/display/panel/novatek,nt37705.yaml | 72 ++++++++++++++++++++++ > >> 1 file changed, 72 insertions(+) > >> > >> diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml > >> new file mode 100644 > >> index 000000000000..1c796599f6fc > >> --- /dev/null > >> +++ b/Documentation/devicetree/bindings/display/panel/novatek,nt37705.yaml > > > > Did novatek,nt37705 get dropped as a compatible, but the filename > > remains? > > That's how himax,hx83112a.yaml and himax,hx83112b.yaml are as well, > which I have upstreamed before. I *really* don't have strong opinions > either way, but as in the email referred to in "Link:" the versions I > have upstreamed before have been accepted without issue, and even > discussion pointing in the way I have done things here. Okay. I guess just naming after the first panel would be odd for everyone else. Rob ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel 2026-09-18 14:40 [PATCH v2 0/4] Add Novatek NT37705 panel driver for Fairphone (Gen. 6) Luca Weiss 2026-09-18 14:40 ` [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 Luca Weiss @ 2026-09-18 14:40 ` Luca Weiss 2026-09-18 14:58 ` sashiko-bot ` (2 more replies) 2026-09-18 14:40 ` [PATCH v2 3/4] arm64: defconfig: Enable " Luca Weiss 2026-09-18 14:40 ` [PATCH v2 4/4] arm64: dts: qcom: milos-fairphone-fp6: Enable display Luca Weiss 3 siblings, 3 replies; 12+ messages in thread From: Luca Weiss @ 2026-09-18 14:40 UTC (permalink / raw) To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio Cc: ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree, linux-kernel, linux-arm-msm, Luca Weiss Add support for the 2484x1116 AMOLED panel from BOE (BJ631JHM-T71-D900) bundled with a NT37705 driver IC, as found on the Fairphone (Gen. 6) smartphone. The panel can also be configured in 10-bit (RGB101010) mode, however currently it's configured in 8-bit (RGB888) since there's some issues in the Qualcomm DPU driver when driving this panel in 10-bit. Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> --- drivers/gpu/drm/panel/Kconfig | 12 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-novatek-nt37705.c | 413 ++++++++++++++++++++++++++ 3 files changed, 426 insertions(+) diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index cbdf7b8f7f7a..be2f812bef76 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -706,6 +706,18 @@ config DRM_PANEL_NOVATEK_NT37700F Say Y here if you want to enable support for Novatek NT37700F DSI panel module. The panel has a resolution of 1080x2160. +config DRM_PANEL_NOVATEK_NT37705 + tristate "Novatek NT37705-based DSI panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select DRM_DISPLAY_DSC_HELPER + select DRM_DISPLAY_HELPER + help + Say Y here if you want to enable support for Novatek NT37705-based + display panels, such as the one found in the Fairphone (Gen. 6) + smartphone. + config DRM_PANEL_NOVATEK_NT37801 tristate "Novatek NT37801/NT37810 AMOLED DSI panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 3b523cf37833..e1366b5e25fc 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36536) += panel-novatek-nt36536.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672E) += panel-novatek-nt36672e.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT37700F) += panel-novatek-nt37700f.o +obj-$(CONFIG_DRM_PANEL_NOVATEK_NT37705) += panel-novatek-nt37705.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT37801) += panel-novatek-nt37801.o obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o diff --git a/drivers/gpu/drm/panel/panel-novatek-nt37705.c b/drivers/gpu/drm/panel/panel-novatek-nt37705.c new file mode 100644 index 000000000000..27bd8072ccd1 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-novatek-nt37705.c @@ -0,0 +1,413 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree. + * Copyright (c) 2026 Luca Weiss <luca.weiss@fairphone.com> + */ + +#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/display/drm_dsc.h> +#include <drm/display/drm_dsc_helper.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/drm_probe_helper.h> + +struct nt37705_panel { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct drm_dsc_config dsc; + struct regulator_bulk_data *supplies; + struct gpio_desc *reset_gpio; +}; + +static const struct regulator_bulk_data nt37705_supplies[] = { + { .supply = "vddio" }, + { .supply = "dvdd" }, + { .supply = "vci" }, +}; + +static inline struct nt37705_panel *to_nt37705_panel(struct drm_panel *panel) +{ + return container_of_const(panel, struct nt37705_panel, panel); +} + +static void nt37705_reset(struct nt37705_panel *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(5000, 6000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 11000); +} + +static int nt37705_on(struct nt37705_panel *ctx) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + ctx->dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, + 0x55, 0xaa, 0x52, 0x08, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x1b); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, 0x18); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x1c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x2c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x00, 0x01, 0x01, 0x01, 0x00, 0x05, 0x05, + 0x05, 0x00, 0x05, 0x05, 0x05, 0x00, 0x00, + 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x3c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x0b, + 0x0b, 0x00, 0x00, 0x0b, 0x0b, 0x00, 0x00, + 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x4c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, + 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x5c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x6c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0b, + 0x77, 0x77, 0x00, 0x00, 0x0b, 0x00, 0x1d, + 0x00, 0x1d); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x7c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0b, + 0x77, 0x77, 0x00, 0x00, 0x0b, 0x00, 0x1d, + 0x00, 0x1d); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x8c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x9c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x11, 0x11, 0x20, 0x02, 0x00, 0x03, 0x00, + 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0xa4); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, 0x00, 0xc0, 0x40, 0x08); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0xa8); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0xb0); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xba, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, + 0x55, 0xaa, 0x52, 0x08, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x05); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xc5, 0x15, 0x15, 0x15, 0xdd); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, + 0x55, 0xaa, 0x52, 0x08, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x0e); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb5, 0x32); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, + 0x55, 0xaa, 0x52, 0x00, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x80); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x19); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf2, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x1a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf4, 0x55); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x11); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf8, 0x01, 0x7f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x2d); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf8, 0x01, 0x20); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x81); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x05); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x3c); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf9, 0x04); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x1e); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfb, 0x0f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x0f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf5, 0x20); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x0d); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfb, 0x80); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x83); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x12); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfe, 0x41); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x13); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfd, 0x21); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY, + 0x20); + mipi_dsi_dcs_set_column_address_multi(&dsi_ctx, 0x0000, 0x045b); + mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0x0000, 0x09b3); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_GAMMA_CURVE, 0x00); + mipi_dsi_dcs_set_display_brightness_multi(&dsi_ctx, 0xbb0d); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x04); + mipi_dsi_dcs_set_display_brightness_multi(&dsi_ctx, 0xfe0f); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x01, 0x19); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x90, 0x03, 0x03); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x91, + 0x89, 0x28, 0x00, 0x0c, 0xd2, 0x00, 0x02, + 0x2f, 0x01, 0x18, 0x00, 0x07, 0x09, 0x75, + 0x08, 0x34, 0x10, 0xf0); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x02); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x01); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x30); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x00); + mipi_dsi_msleep(&dsi_ctx, 120); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x00); + mipi_dsi_msleep(&dsi_ctx, 22); + + return dsi_ctx.accum_err; +} + +static int nt37705_off(struct nt37705_panel *ctx) +{ + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + + ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x00); + mipi_dsi_msleep(&dsi_ctx, 20); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x00); + mipi_dsi_msleep(&dsi_ctx, 120); + + return dsi_ctx.accum_err; +} + +static int nt37705_prepare(struct drm_panel *panel) +{ + struct nt37705_panel *ctx = to_nt37705_panel(panel); + struct device *dev = &ctx->dsi->dev; + struct drm_dsc_picture_parameter_set pps; + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(nt37705_supplies), ctx->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + + nt37705_reset(ctx); + + ret = nt37705_on(ctx); + if (ret < 0) { + dev_err(dev, "Failed to initialize panel: %d\n", ret); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(nt37705_supplies), ctx->supplies); + return ret; + } + + drm_dsc_pps_payload_pack(&pps, &ctx->dsc); + + ret = mipi_dsi_picture_parameter_set(ctx->dsi, &pps); + if (ret < 0) { + dev_err(panel->dev, "failed to transmit PPS: %d\n", ret); + return ret; + } + + ret = mipi_dsi_compression_mode(ctx->dsi, true); + if (ret < 0) { + dev_err(dev, "failed to enable compression mode: %d\n", ret); + return ret; + } + + msleep(28); /* TODO: Is this panel-dependent? */ + + return 0; +} + +static int nt37705_unprepare(struct drm_panel *panel) +{ + struct nt37705_panel *ctx = to_nt37705_panel(panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + ret = nt37705_off(ctx); + if (ret < 0) + dev_err(dev, "Failed to un-initialize panel: %d\n", ret); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(nt37705_supplies), ctx->supplies); + + return 0; +} + +static const struct drm_display_mode nt37705_mode = { + .clock = (1116 + 100 + 30 + 100) * (2484 + 70 + 48 + 70) * 120 / 1000, + .hdisplay = 1116, + .hsync_start = 1116 + 100, + .hsync_end = 1116 + 100 + 30, + .htotal = 1116 + 100 + 30 + 100, + .vdisplay = 2484, + .vsync_start = 2484 + 70, + .vsync_end = 2484 + 70 + 48, + .vtotal = 2484 + 70 + 48 + 70, + .width_mm = 66, + .height_mm = 146, + .type = DRM_MODE_TYPE_DRIVER, +}; + +static int nt37705_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + return drm_connector_helper_get_modes_fixed(connector, &nt37705_mode); +} + +static const struct drm_panel_funcs nt37705_panel_funcs = { + .prepare = nt37705_prepare, + .unprepare = nt37705_unprepare, + .get_modes = nt37705_get_modes, +}; + +static int nt37705_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return 0; +} + +static const struct backlight_ops nt37705_bl_ops = { + .update_status = nt37705_bl_update_status, +}; + +static struct backlight_device * +nt37705_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .scale = BACKLIGHT_SCALE_NON_LINEAR, + .brightness = 4095, + .max_brightness = 4095, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &nt37705_bl_ops, &props); +} + +static int nt37705_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct nt37705_panel *ctx; + int ret; + + ctx = devm_drm_panel_alloc(dev, struct nt37705_panel, panel, + &nt37705_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + ret = devm_regulator_bulk_get_const(dev, + ARRAY_SIZE(nt37705_supplies), + nt37705_supplies, + &ctx->supplies); + if (ret < 0) + return ret; + + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "Failed to get reset-gpios\n"); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET | + MIPI_DSI_CLOCK_NON_CONTINUOUS; + + ctx->panel.prepare_prev_first = true; + + ctx->panel.backlight = nt37705_create_backlight(dsi); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "Failed to create backlight\n"); + + drm_panel_add(&ctx->panel); + + /* This panel only supports DSC; unconditionally enable it */ + dsi->dsc = &ctx->dsc; + + ctx->dsc.dsc_version_major = 1; + ctx->dsc.dsc_version_minor = 1; + + /* TODO: Pass slice_per_pkt = 2 */ + ctx->dsc.slice_height = 12; + ctx->dsc.slice_width = 558; + /* + * TODO: hdisplay should be read from the selected mode once + * it is passed back to drm_panel (in prepare?) + */ + WARN_ON(1116 % ctx->dsc.slice_width); + ctx->dsc.slice_count = 1116 / ctx->dsc.slice_width; + ctx->dsc.bits_per_component = 8; + ctx->dsc.bits_per_pixel = 8 << 4; /* 4 fractional bits */ + ctx->dsc.block_pred_enable = true; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + drm_panel_remove(&ctx->panel); + return dev_err_probe(dev, ret, "Failed to attach to DSI host\n"); + } + + return 0; +} + +static void nt37705_remove(struct mipi_dsi_device *dsi) +{ + struct nt37705_panel *ctx = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id nt37705_of_match[] = { + { .compatible = "boe,bj631jhm-t71-d900" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, nt37705_of_match); + +static struct mipi_dsi_driver nt37705_driver = { + .probe = nt37705_probe, + .remove = nt37705_remove, + .driver = { + .name = "panel-novatek-nt37705", + .of_match_table = nt37705_of_match, + }, +}; +module_mipi_dsi_driver(nt37705_driver); + +MODULE_DESCRIPTION("DRM driver for NT37705-equipped DSI panels"); +MODULE_LICENSE("GPL"); -- 2.55.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel 2026-09-18 14:40 ` [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel Luca Weiss @ 2026-09-18 14:58 ` sashiko-bot 2026-09-18 15:58 ` Uwe Kleine-König 2026-10-05 6:55 ` Dmitry Baryshkov 2 siblings, 0 replies; 12+ messages in thread From: sashiko-bot @ 2026-09-18 14:58 UTC (permalink / raw) To: Luca Weiss; +Cc: robh, dri-devel, conor+dt, devicetree Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider: - [High] drm/panel: resource leak on DSI command failure in prepare - [High] drm/panel: Use-After-Free of dangling dsi->dsc pointer - [Medium] drm/panel: unpowered device access in backlight update - [Medium] drm/panel: state corruption of mode_flags on error path - [Medium] drm/panel: protocol violation via malformed DCS commands -- commit 8f6434d0603fb1133d406bd15a56e3de3bcce821 Author: Luca Weiss <luca.weiss@fairphone.com> drm/panel: Add driver for Novatek NT37705 panel Add support for the 2484x1116 AMOLED panel from BOE (BJ631JHM-T71-D900) bundled with a NT37705 driver IC, as found on the Fairphone (Gen. 6) smartphone. > diff --git a/drivers/gpu/drm/panel/panel-novatek-nt37705.c b/drivers/gpu/drm/panel/panel-novatek-nt37705.c > index 0000000000000..27bd8072ccd1b > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-novatek-nt37705.c > @@ -0,0 +1,413 @@ [ ... ] > +static int nt37705_on(struct nt37705_panel *ctx) > +{ [ ... ] > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x00); > + mipi_dsi_msleep(&dsi_ctx, 120); > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x00); [Severity: Medium] Are these standard zero-parameter DCS commands (Exit Sleep Mode 0x11, Display On 0x29) intended to be transmitted with an extra 0x00 padding byte? This creates a 1-parameter short write instead of a 0-parameter short write, which violates the MIPI DCS specification and could cause panel controller misbehavior. > + mipi_dsi_msleep(&dsi_ctx, 22); > + > + return dsi_ctx.accum_err; > +} > + > +static int nt37705_off(struct nt37705_panel *ctx) > +{ > + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; > + > + ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; > + > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x00); > + mipi_dsi_msleep(&dsi_ctx, 20); > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x00); [Severity: Medium] Similarly, do these zero-parameter DCS commands (Display Off 0x28, Enter Sleep Mode 0x10) need the extra 0x00 padding byte? > + mipi_dsi_msleep(&dsi_ctx, 120); > + > + return dsi_ctx.accum_err; > +} > + > +static int nt37705_prepare(struct drm_panel *panel) > +{ [ ... ] > + ret = mipi_dsi_picture_parameter_set(ctx->dsi, &pps); > + if (ret < 0) { > + dev_err(panel->dev, "failed to transmit PPS: %d\n", ret); > + return ret; [Severity: High] Does this early return leak resources? If mipi_dsi_picture_parameter_set() fails, the function returns directly instead of jumping to a cleanup block to disable the regulators and assert the reset GPIO, preventing subsequent recovery or clean shutdown of the panel. > + } > + > + ret = mipi_dsi_compression_mode(ctx->dsi, true); > + if (ret < 0) { > + dev_err(dev, "failed to enable compression mode: %d\n", ret); > + return ret; [Severity: High] Similarly, does this early return also bypass resource cleanup? > + } > + > + msleep(28); /* TODO: Is this panel-dependent? */ > + > + return 0; > +} [ ... ] > +static int nt37705_bl_update_status(struct backlight_device *bl) > +{ > + struct mipi_dsi_device *dsi = bl_get_data(bl); > + u16 brightness = backlight_get_brightness(bl); > + int ret; > + > + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; > + > + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); [Severity: Medium] What happens if userspace modifies the sysfs brightness attribute when the display is suspended or turned off? This function appears to unconditionally initiate DSI transactions without checking the panel's power state, which could lead to DSI bus timeouts and potential system sluggishness depending on the DSI host implementation. > + if (ret < 0) > + return ret; [Severity: Medium] If mipi_dsi_dcs_set_display_brightness_large() fails, we take this early return path. Does this permanently disable the MIPI_DSI_MODE_LPM flag for the DSI device? If so, subsequent commands might be transmitted in the wrong mode, potentially breaking display functionality. > + > + dsi->mode_flags |= MIPI_DSI_MODE_LPM; > + > + return 0; > +} [ ... ] > +static int nt37705_probe(struct mipi_dsi_device *dsi) > +{ [ ... ] > + /* This panel only supports DSC; unconditionally enable it */ > + dsi->dsc = &ctx->dsc; [Severity: High] Will this lead to a Use-After-Free on driver unbind? Here we assign a pointer into the devres-managed ctx allocation to the longer-lived mipi_dsi_device struct. [ ... ] > +static void nt37705_remove(struct mipi_dsi_device *dsi) > +{ > + struct nt37705_panel *ctx = mipi_dsi_get_drvdata(dsi); > + int ret; > + > + ret = mipi_dsi_detach(dsi); > + if (ret < 0) > + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); > + > + drm_panel_remove(&ctx->panel); > +} [Severity: High] When nt37705_remove() completes, ctx is freed by devres, leaving dsi->dsc as a dangling pointer. If the DSI host accesses dsi->dsc afterwards, this could cause a UAF. Should dsi->dsc be set to NULL here? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260918-fp6-panel-v2-0-6695c4008920@fairphone.com?part=2 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel 2026-09-18 14:40 ` [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel Luca Weiss 2026-09-18 14:58 ` sashiko-bot @ 2026-09-18 15:58 ` Uwe Kleine-König 2026-10-05 6:55 ` Dmitry Baryshkov 2 siblings, 0 replies; 12+ messages in thread From: Uwe Kleine-König @ 2026-09-18 15:58 UTC (permalink / raw) To: Luca Weiss Cc: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio, ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree, linux-kernel, linux-arm-msm [-- Attachment #1: Type: text/plain, Size: 500 bytes --] On Fri, Sep 18, 2026 at 04:40:05PM +0200, Luca Weiss wrote: > +#include <linux/mod_devicetable.h> Please don't include that file. of_device_id is also provided by <drm/drm_mipi_dsi.h> (transitively via <linux/device.h> -> <linux/device/driver.h> -> <linux/device-id/of.h>) and you can rely on that. If you want to go full iwyu, please use <linux/device-id/of.h> instead of <linux/mod_devicetable.h>. <linux/mod_devicetable.h> is a dependency hog and will hopefully go away soon. Best regards Uwe [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel 2026-09-18 14:40 ` [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel Luca Weiss 2026-09-18 14:58 ` sashiko-bot 2026-09-18 15:58 ` Uwe Kleine-König @ 2026-10-05 6:55 ` Dmitry Baryshkov 2 siblings, 0 replies; 12+ messages in thread From: Dmitry Baryshkov @ 2026-10-05 6:55 UTC (permalink / raw) To: Luca Weiss Cc: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio, ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree, linux-kernel, linux-arm-msm On Fri, Sep 18, 2026 at 04:40:05PM +0200, Luca Weiss wrote: > Add support for the 2484x1116 AMOLED panel from BOE (BJ631JHM-T71-D900) > bundled with a NT37705 driver IC, as found on the Fairphone (Gen. 6) > smartphone. > > The panel can also be configured in 10-bit (RGB101010) mode, however > currently it's configured in 8-bit (RGB888) since there's some issues in > the Qualcomm DPU driver when driving this panel in 10-bit. > > Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> > --- > drivers/gpu/drm/panel/Kconfig | 12 + > drivers/gpu/drm/panel/Makefile | 1 + > drivers/gpu/drm/panel/panel-novatek-nt37705.c | 413 ++++++++++++++++++++++++++ > 3 files changed, 426 insertions(+) > > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x02); > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x01); > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x30); > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x00); > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x00); MIPI_DCS_EXIT_SLEEP_MODE > + mipi_dsi_msleep(&dsi_ctx, 120); > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x00); MIPI_DCS_SET_DISPLAY_ON > + mipi_dsi_msleep(&dsi_ctx, 22); > + > + return dsi_ctx.accum_err; > +} > + > +static int nt37705_off(struct nt37705_panel *ctx) > +{ > + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; > + > + ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; > + > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x00); MIPI_DCS_SET_DISPLAY_OFF > + mipi_dsi_msleep(&dsi_ctx, 20); > + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x00); MIPI_DCS_ENTER_SLEEP_MODE > + mipi_dsi_msleep(&dsi_ctx, 120); > + > + return dsi_ctx.accum_err; > +} > + -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 3/4] arm64: defconfig: Enable Novatek NT37705 panel 2026-09-18 14:40 [PATCH v2 0/4] Add Novatek NT37705 panel driver for Fairphone (Gen. 6) Luca Weiss 2026-09-18 14:40 ` [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 Luca Weiss 2026-09-18 14:40 ` [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel Luca Weiss @ 2026-09-18 14:40 ` Luca Weiss 2026-09-18 14:40 ` [PATCH v2 4/4] arm64: dts: qcom: milos-fairphone-fp6: Enable display Luca Weiss 3 siblings, 0 replies; 12+ messages in thread From: Luca Weiss @ 2026-09-18 14:40 UTC (permalink / raw) To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio Cc: ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree, linux-kernel, linux-arm-msm, Luca Weiss, Dmitry Baryshkov Enable the NT37705 panel driver which is used on Fairphone (Gen. 6). Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 6ec8d3a69c98..1d4afc733c8a 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1023,6 +1023,7 @@ CONFIG_DRM_PANEL_KHADAS_TS050=m CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m CONFIG_DRM_PANEL_NOVATEK_NT36672A=m CONFIG_DRM_PANEL_NOVATEK_NT36672E=m +CONFIG_DRM_PANEL_NOVATEK_NT37705=m CONFIG_DRM_PANEL_NOVATEK_NT37801=m CONFIG_DRM_PANEL_RAYDIUM_RM67191=m CONFIG_DRM_PANEL_RAYDIUM_RM692E5=m -- 2.55.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 4/4] arm64: dts: qcom: milos-fairphone-fp6: Enable display 2026-09-18 14:40 [PATCH v2 0/4] Add Novatek NT37705 panel driver for Fairphone (Gen. 6) Luca Weiss ` (2 preceding siblings ...) 2026-09-18 14:40 ` [PATCH v2 3/4] arm64: defconfig: Enable " Luca Weiss @ 2026-09-18 14:40 ` Luca Weiss 3 siblings, 0 replies; 12+ messages in thread From: Luca Weiss @ 2026-09-18 14:40 UTC (permalink / raw) To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio Cc: ~postmarketos/upstreaming, phone-devel, dri-devel, devicetree, linux-kernel, linux-arm-msm, Luca Weiss, Dmitry Baryshkov, Konrad Dybcio Configure the MDSS nodes for the phone and add the panel node. Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> --- arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts | 64 ++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts index 4e8777162b53..11015c3fa331 100644 --- a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts +++ b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts @@ -709,6 +709,49 @@ &ipa { status = "okay"; }; +&mdss { + status = "okay"; +}; + +&mdss_dsi0 { + vdda-supply = <&vreg_l4b>; + + status = "okay"; + + panel@0 { + compatible = "boe,bj631jhm-t71-d900"; + reg = <0>; + + reset-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>; + + vci-supply = <&vreg_l19b>; + vddio-supply = <&vreg_l9b>; + dvdd-supply = <&vreg_oled_dvdd_1p2>; + + pinctrl-0 = <&disp_reset_n_active>, <&mdp_vsync>; + pinctrl-1 = <&disp_reset_n_suspend>, <&mdp_vsync>; + pinctrl-names = "default", + "sleep"; + + port { + panel_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + }; +}; + +&mdss_dsi0_out { + data-lanes = <0 1 2 3>; + remote-endpoint = <&panel_in>; +}; + +&mdss_dsi0_phy { + vdds-supply = <&vreg_l2b>; + + status = "okay"; +}; + &pm8550vs_c { status = "okay"; }; @@ -872,6 +915,20 @@ &tlmm { <13 1>, /* NC */ <63 2>; /* WLAN UART */ + disp_reset_n_active: disp-reset-n-active-state { + pins = "gpio12"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + disp_reset_n_suspend: disp-reset-n-suspend-state { + pins = "gpio12"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + sdc2_card_det_n: sdc2-card-det-state { pins = "gpio65"; function = "gpio"; @@ -906,6 +963,13 @@ pm8008_int_default: pm8008-int-default-state { drive-strength = <2>; bias-disable; }; + + mdp_vsync: mdp-vsync-state { + pins = "gpio129"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; }; &uart5 { -- 2.55.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-10-05 6:55 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-18 14:40 [PATCH v2 0/4] Add Novatek NT37705 panel driver for Fairphone (Gen. 6) Luca Weiss 2026-09-18 14:40 ` [PATCH v2 1/4] dt-bindings: display: panel: Add Novatek NT37705 Luca Weiss 2026-09-18 14:51 ` sashiko-bot 2026-09-18 21:35 ` Rob Herring 2026-10-02 14:00 ` Luca Weiss 2026-10-02 14:16 ` Rob Herring 2026-09-18 14:40 ` [PATCH v2 2/4] drm/panel: Add driver for Novatek NT37705 panel Luca Weiss 2026-09-18 14:58 ` sashiko-bot 2026-09-18 15:58 ` Uwe Kleine-König 2026-10-05 6:55 ` Dmitry Baryshkov 2026-09-18 14:40 ` [PATCH v2 3/4] arm64: defconfig: Enable " Luca Weiss 2026-09-18 14:40 ` [PATCH v2 4/4] arm64: dts: qcom: milos-fairphone-fp6: Enable display Luca Weiss
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox