* [PATCH 01/39] dt-bindings: display: imx: Document i.MX95 Display Controller DomainBlend
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-15 13:24 ` Rob Herring
2025-10-11 16:51 ` [PATCH 02/39] drm/imx: Add " Marek Vasut
` (39 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
i.MX95 Display Controller display engine consists of all processing
units that operate in a display clock domain. Document DomainBlend
block which is specific to i.MX95 and required to get any display
output on that SoC.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
.../display/imx/fsl,imx95-dc-domainblend.yaml | 32 +++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
new file mode 100644
index 0000000000000..703f98e3321e8
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx95-dc-domainblend.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX95 Display Controller Domain Blend Unit
+
+description: Combines two input frames to a single output frame.
+
+maintainers:
+ - Marek Vasut <marek.vasut@mailbox.org>
+
+properties:
+ compatible:
+ const: fsl,imx95-dc-domainblend
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ domainblend@4b6a0000 {
+ compatible = "fsl,imx95-dc-domainblend";
+ reg = <0x4b6a0000 0x10>;
+ };
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 01/39] dt-bindings: display: imx: Document i.MX95 Display Controller DomainBlend
2025-10-11 16:51 ` [PATCH 01/39] dt-bindings: display: imx: Document i.MX95 Display Controller DomainBlend Marek Vasut
@ 2025-10-15 13:24 ` Rob Herring
2025-10-16 2:07 ` Liu Ying
0 siblings, 1 reply; 113+ messages in thread
From: Rob Herring @ 2025-10-15 13:24 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Shawn Guo, Thomas Zimmermann,
devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:16PM +0200, Marek Vasut wrote:
> i.MX95 Display Controller display engine consists of all processing
> units that operate in a display clock domain. Document DomainBlend
> block which is specific to i.MX95 and required to get any display
> output on that SoC.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../display/imx/fsl,imx95-dc-domainblend.yaml | 32 +++++++++++++++++++
> 1 file changed, 32 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
> new file mode 100644
> index 0000000000000..703f98e3321e8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
> @@ -0,0 +1,32 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/imx/fsl,imx95-dc-domainblend.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX95 Display Controller Domain Blend Unit
> +
> +description: Combines two input frames to a single output frame.
> +
> +maintainers:
> + - Marek Vasut <marek.vasut@mailbox.org>
> +
> +properties:
> + compatible:
> + const: fsl,imx95-dc-domainblend
> +
> + reg:
> + maxItems: 1
No clocks or other resources?
> +
> +required:
> + - compatible
> + - reg
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + domainblend@4b6a0000 {
> + compatible = "fsl,imx95-dc-domainblend";
> + reg = <0x4b6a0000 0x10>;
> + };
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 01/39] dt-bindings: display: imx: Document i.MX95 Display Controller DomainBlend
2025-10-15 13:24 ` Rob Herring
@ 2025-10-16 2:07 ` Liu Ying
2025-10-17 15:15 ` Marek Vasut
2025-10-21 6:52 ` Krzysztof Kozlowski
0 siblings, 2 replies; 113+ messages in thread
From: Liu Ying @ 2025-10-16 2:07 UTC (permalink / raw)
To: Rob Herring, Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Shawn Guo, Thomas Zimmermann, devicetree,
imx, linux-arm-kernel, linux-clk
On 10/15/2025, Rob Herring wrote:
> On Sat, Oct 11, 2025 at 06:51:16PM +0200, Marek Vasut wrote:
>> i.MX95 Display Controller display engine consists of all processing
>> units that operate in a display clock domain. Document DomainBlend
>> block which is specific to i.MX95 and required to get any display
>> output on that SoC.
>>
>> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
>> ---
>> Cc: Abel Vesa <abelvesa@kernel.org>
>> Cc: Conor Dooley <conor+dt@kernel.org>
>> Cc: Fabio Estevam <festevam@gmail.com>
>> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
>> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
>> Cc: Liu Ying <victor.liu@nxp.com>
>> Cc: Lucas Stach <l.stach@pengutronix.de>
>> Cc: Peng Fan <peng.fan@nxp.com>
>> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
>> Cc: Rob Herring <robh@kernel.org>
>> Cc: Shawn Guo <shawnguo@kernel.org>
>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
>> Cc: devicetree@vger.kernel.org
>> Cc: dri-devel@lists.freedesktop.org
>> Cc: imx@lists.linux.dev
>> Cc: linux-arm-kernel@lists.infradead.org
>> Cc: linux-clk@vger.kernel.org
>> ---
>> .../display/imx/fsl,imx95-dc-domainblend.yaml | 32 +++++++++++++++++++
>> 1 file changed, 32 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
>> new file mode 100644
>> index 0000000000000..703f98e3321e8
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
>> @@ -0,0 +1,32 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/display/imx/fsl,imx95-dc-domainblend.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Freescale i.MX95 Display Controller Domain Blend Unit
>> +
>> +description: Combines two input frames to a single output frame.
I'd like to comment on patches in split patch serieses(to be sent if needed).
But, since I provide the below interrupt information, anyway I take the chance
to comment more:
Add more description about the unit according to i.MX95 DC IP spec:
The unit operates in four modes:
- Primary mode: The primary input is used for output.
- Secondary mode: The secondary input is used for output.
- Blend mode: Primary and secondary inputs are blended, according to the
programmed blending functions.
- SidebySide mode: Primary and secondary streams are projected side by side,
i.e., primary video on the left side and secondary on the
right.
BTW, I confirm that two Domain Blend Units exist in i.MX95 DC while they don't
exist in i.MX8qxp/qm DCs. And, as you can see, this unit supports multiple
modes, this would impact how an OS implements a display driver a lot, especially
Blend mode and SidebySide mode.
>> +
>> +maintainers:
>> + - Marek Vasut <marek.vasut@mailbox.org>
>> +
>> +properties:
>> + compatible:
>> + const: fsl,imx95-dc-domainblend
>> +
>> + reg:
>> + maxItems: 1
>
> No clocks or other resources?
As patch 39 shows, there are 3 interrupts - domainblend{0,1}_shdload,
domainblend{0,1}_framecomplete and domainblend{0,1}_seqcomplete.
>
>> +
>> +required:
>> + - compatible
>> + - reg
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> + - |
>> + domainblend@4b6a0000 {
>> + compatible = "fsl,imx95-dc-domainblend";
>> + reg = <0x4b6a0000 0x10>;
>> + };
>> --
>> 2.51.0
>>
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 01/39] dt-bindings: display: imx: Document i.MX95 Display Controller DomainBlend
2025-10-16 2:07 ` Liu Ying
@ 2025-10-17 15:15 ` Marek Vasut
2025-10-18 6:09 ` Ying Liu
2025-10-21 6:52 ` Krzysztof Kozlowski
1 sibling, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:15 UTC (permalink / raw)
To: Liu Ying, Rob Herring
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Shawn Guo, Thomas Zimmermann, devicetree,
imx, linux-arm-kernel, linux-clk
On 10/16/25 4:07 AM, Liu Ying wrote:
Hello Liu,
>>> +$id: http://devicetree.org/schemas/display/imx/fsl,imx95-dc-domainblend.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Freescale i.MX95 Display Controller Domain Blend Unit
>>> +
>>> +description: Combines two input frames to a single output frame.
>
> I'd like to comment on patches in split patch serieses(to be sent if needed).
> But, since I provide the below interrupt information, anyway I take the chance
> to comment more:
>
> Add more description about the unit according to i.MX95 DC IP spec:
> The unit operates in four modes:
> - Primary mode: The primary input is used for output.
> - Secondary mode: The secondary input is used for output.
> - Blend mode: Primary and secondary inputs are blended, according to the
> programmed blending functions.
> - SidebySide mode: Primary and secondary streams are projected side by side,
> i.e., primary video on the left side and secondary on the
> right.
>
> BTW, I confirm that two Domain Blend Units exist in i.MX95 DC while they don't
> exist in i.MX8qxp/qm DCs. And, as you can see, this unit supports multiple
> modes, this would impact how an OS implements a display driver a lot, especially
> Blend mode and SidebySide mode.
There is one thing which specifically concerns me about the DB, it seems
to be capable of blending two inputs from different security domains, is
that correct ?
>>> +maintainers:
>>> + - Marek Vasut <marek.vasut@mailbox.org>
>>> +
>>> +properties:
>>> + compatible:
>>> + const: fsl,imx95-dc-domainblend
>>> +
>>> + reg:
>>> + maxItems: 1
>>
>> No clocks or other resources?
>
> As patch 39 shows, there are 3 interrupts - domainblend{0,1}_shdload,
> domainblend{0,1}_framecomplete and domainblend{0,1}_seqcomplete.
It seems we currently do not use either clock or interrupts on either
domainblend or layerblend IPs, but maybe DB and LB are different and LB
really has no clock/interrupts ?
^ permalink raw reply [flat|nested] 113+ messages in thread* RE: [PATCH 01/39] dt-bindings: display: imx: Document i.MX95 Display Controller DomainBlend
2025-10-17 15:15 ` Marek Vasut
@ 2025-10-18 6:09 ` Ying Liu
0 siblings, 0 replies; 113+ messages in thread
From: Ying Liu @ 2025-10-18 6:09 UTC (permalink / raw)
To: Marek Vasut, Rob Herring
Cc: dri-devel@lists.freedesktop.org, Abel Vesa, Conor Dooley,
Fabio Estevam, Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Shawn Guo, Thomas Zimmermann,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org
On 10/17/25, Marek Vasut <marek.vasut@mailbox.org> wrote:
> On 10/16/25 4:07 AM, Liu Ying wrote:
>
> Hello Liu,
Hello Marek,
>
> >>> +$id:
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicet
> ree.org%2Fschemas%2Fdisplay%2Fimx%2Ffsl%2Cimx95-dc-
> domainblend.yaml%23&data=05%7C02%7Cvictor.liu%40nxp.com%7Cc0eb44
> 78aced4ce6921d08de0d9d59dd%7C686ea1d3bc2b4c6fa92cd99c5c301635%7
> C0%7C0%7C638963166631090945%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0
> eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpb
> CIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=NEUOVd1LBTU%2FIymp1Ieb
> 22hbewujlOfQzZTflJ39Nuw%3D&reserved=0
> >>> +$schema:
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicet
> ree.org%2Fmeta-
> schemas%2Fcore.yaml%23&data=05%7C02%7Cvictor.liu%40nxp.com%7Cc0e
> b4478aced4ce6921d08de0d9d59dd%7C686ea1d3bc2b4c6fa92cd99c5c301635
> %7C0%7C0%7C638963166631115160%7CUnknown%7CTWFpbGZsb3d8eyJFb
> XB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTW
> FpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=JSP9XazHXO0HeirsaW3D
> lqKf5rXOJgGJ1M1hcsk7jS0%3D&reserved=0
> >>> +
> >>> +title: Freescale i.MX95 Display Controller Domain Blend Unit
> >>> +
> >>> +description: Combines two input frames to a single output frame.
> >
> > I'd like to comment on patches in split patch serieses(to be sent if needed).
> > But, since I provide the below interrupt information, anyway I take the
> chance
> > to comment more:
> >
> > Add more description about the unit according to i.MX95 DC IP spec:
> > The unit operates in four modes:
> > - Primary mode: The primary input is used for output.
> > - Secondary mode: The secondary input is used for output.
> > - Blend mode: Primary and secondary inputs are blended, according to the
> > programmed blending functions.
> > - SidebySide mode: Primary and secondary streams are projected side by
> side,
> > i.e., primary video on the left side and secondary on the
> > right.
> >
> > BTW, I confirm that two Domain Blend Units exist in i.MX95 DC while they
> don't
> > exist in i.MX8qxp/qm DCs. And, as you can see, this unit supports multiple
> > modes, this would impact how an OS implements a display driver a lot,
> especially
> > Blend mode and SidebySide mode.
>
> There is one thing which specifically concerns me about the DB, it seems
> to be capable of blending two inputs from different security domains, is
> that correct ?
For now, I know nothing more than the DT binding description here, i.e.,
two inputs are combined to one output in four modes. And, DB cannot be
bypassed IIUC.
>
> >>> +maintainers:
> >>> + - Marek Vasut <marek.vasut@mailbox.org>
> >>> +
> >>> +properties:
> >>> + compatible:
> >>> + const: fsl,imx95-dc-domainblend
> >>> +
> >>> + reg:
> >>> + maxItems: 1
> >>
> >> No clocks or other resources?
> >
> > As patch 39 shows, there are 3 interrupts - domainblend{0,1}_shdload,
> > domainblend{0,1}_framecomplete and domainblend{0,1}_seqcomplete.
> It seems we currently do not use either clock or interrupts on either
> domainblend or layerblend IPs, but maybe DB and LB are different and LB
> really has no clock/interrupts ?
If you take a look at NXP downstream kernel, it uses
domainblend{0,1}_shdload IRQs in CRTC driver and I believe that upstream
driver should use them too.
DB and LB are different. DB is in Display Engine, while LB is in Pixel Engine.
This pipeline sort of tells how LD and DB are connected: LB -> ED -> DB.
LB has no interrupts. And since it processes pixels in Pixel Engine with AXI
CLK and it can be configured via the AHB interface of DC with CFG CLK, I'd
say it kind of inherits AXI CLK and CFG CLK from Pixel Engine and DC
respectively. See the diagram in fsl,imx8qxp-dc.yaml, you'll find those
clocks.
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 01/39] dt-bindings: display: imx: Document i.MX95 Display Controller DomainBlend
2025-10-16 2:07 ` Liu Ying
2025-10-17 15:15 ` Marek Vasut
@ 2025-10-21 6:52 ` Krzysztof Kozlowski
1 sibling, 0 replies; 113+ messages in thread
From: Krzysztof Kozlowski @ 2025-10-21 6:52 UTC (permalink / raw)
To: Liu Ying
Cc: Rob Herring, Marek Vasut, dri-devel, Abel Vesa, Conor Dooley,
Fabio Estevam, Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Shawn Guo, Thomas Zimmermann,
devicetree, imx, linux-arm-kernel, linux-clk
On Thu, Oct 16, 2025 at 10:07:26AM +0800, Liu Ying wrote:
> On 10/15/2025, Rob Herring wrote:
> >> +properties:
> >> + compatible:
> >> + const: fsl,imx95-dc-domainblend
> >> +
> >> + reg:
> >> + maxItems: 1
> >
> > No clocks or other resources?
>
> As patch 39 shows, there are 3 interrupts - domainblend{0,1}_shdload,
> domainblend{0,1}_framecomplete and domainblend{0,1}_seqcomplete.
So they should be here. Just like all other resources, because bindings
should be complete (see writing-bindings doc).
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 02/39] drm/imx: Add i.MX95 Display Controller DomainBlend
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
2025-10-11 16:51 ` [PATCH 01/39] dt-bindings: display: imx: Document i.MX95 Display Controller DomainBlend Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 16:38 ` Frank Li
2025-10-11 16:51 ` [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units Marek Vasut
` (38 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
i.MX95 Display Controller display engine consists of all processing
units that operate in a display clock domain. Add DomainBlend driver
which is specific to i.MX95 and required to get any display output on
that SoC.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/Makefile | 2 +-
drivers/gpu/drm/imx/dc/dc-crtc.c | 2 +
drivers/gpu/drm/imx/dc/dc-db.c | 226 +++++++++++++++++++++++++++++++
drivers/gpu/drm/imx/dc/dc-de.c | 2 +
drivers/gpu/drm/imx/dc/dc-de.h | 11 ++
drivers/gpu/drm/imx/dc/dc-drv.c | 1 +
drivers/gpu/drm/imx/dc/dc-drv.h | 3 +
drivers/gpu/drm/imx/dc/dc-kms.h | 4 +
8 files changed, 250 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/imx/dc/dc-db.c
diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
index b9d33c074984a..20386e4082e56 100644
--- a/drivers/gpu/drm/imx/dc/Makefile
+++ b/drivers/gpu/drm/imx/dc/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
+imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-db.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
dc-plane.o dc-tc.o
diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
index 31d3a982deaf7..56991cb033945 100644
--- a/drivers/gpu/drm/imx/dc/dc-crtc.c
+++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
@@ -272,6 +272,7 @@ dc_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
dc_fg_enable_clock(dc_crtc->fg);
dc_ed_pec_sync_trigger(dc_crtc->ed_cont);
dc_ed_pec_sync_trigger(dc_crtc->ed_safe);
+ dc_db_shdtokgen(dc_crtc->db);
dc_fg_shdtokgen(dc_crtc->fg);
dc_fg_enable(dc_crtc->fg);
@@ -521,6 +522,7 @@ int dc_crtc_init(struct dc_drm_device *dc_drm, int crtc_index)
dc_crtc->ed_cont = pe->ed_cont[crtc_index];
dc_crtc->ed_safe = pe->ed_safe[crtc_index];
dc_crtc->fg = de->fg;
+ dc_crtc->db = de->db;
dc_crtc->irq_dec_framecomplete = de->irq_framecomplete;
dc_crtc->irq_dec_seqcomplete = de->irq_seqcomplete;
diff --git a/drivers/gpu/drm/imx/dc/dc-db.c b/drivers/gpu/drm/imx/dc/dc-db.c
new file mode 100644
index 0000000000000..789942d1c446d
--- /dev/null
+++ b/drivers/gpu/drm/imx/dc/dc-db.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2025 Marek Vasut <marek.vasut@mailbox.org>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/component.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_blend.h>
+
+#include "dc-drv.h"
+#include "dc-pe.h"
+
+#define PIXENGCFG_DYNAMIC 0x8
+#define PIXENGCFG_DYNAMIC_PRIM_SEL_MASK GENMASK(5, 0)
+#define PIXENGCFG_DYNAMIC_PRIM_SEL(x) \
+ FIELD_PREP(PIXENGCFG_DYNAMIC_PRIM_SEL_MASK, (x))
+#define PIXENGCFG_DYNAMIC_SEC_SEL_MASK GENMASK(13, 8)
+#define PIXENGCFG_DYNAMIC_SEC_SEL(x) \
+ FIELD_PREP(PIXENGCFG_DYNAMIC_SEC_SEL_MASK, (x))
+
+#define STATICCONTROL 0x8
+#define SHDTOKSEL_MASK GENMASK(6, 4)
+#define SHDTOKSEL(x) FIELD_PREP(SHDTOKSEL_MASK, (x))
+#define SHDLDSEL_MASK GENMASK(3, 1)
+#define SHDLDSEL(x) FIELD_PREP(SHDLDSEL_MASK, (x))
+
+#define CONTROL 0xc
+#define SHDTOKGEN BIT(0)
+
+#define MODECONTROL 0x10
+
+#define ALPHACONTROL 0x14
+#define ALPHAMASKENABLE BIT(0)
+
+#define BLENDCONTROL 0x18
+#define ALPHA_MASK GENMASK(23, 16)
+#define ALPHA(x) FIELD_PREP(ALPHA_MASK, (x))
+#define PRIM_C_BLD_FUNC_MASK GENMASK(2, 0)
+#define PRIM_C_BLD_FUNC(x) \
+ FIELD_PREP(PRIM_C_BLD_FUNC_MASK, (x))
+#define SEC_C_BLD_FUNC_MASK GENMASK(6, 4)
+#define SEC_C_BLD_FUNC(x) \
+ FIELD_PREP(SEC_C_BLD_FUNC_MASK, (x))
+#define PRIM_A_BLD_FUNC_MASK GENMASK(10, 8)
+#define PRIM_A_BLD_FUNC(x) \
+ FIELD_PREP(PRIM_A_BLD_FUNC_MASK, (x))
+#define SEC_A_BLD_FUNC_MASK GENMASK(14, 12)
+#define SEC_A_BLD_FUNC(x) \
+ FIELD_PREP(SEC_A_BLD_FUNC_MASK, (x))
+
+enum dc_db_blend_func {
+ DC_DOMAINBLEND_BLEND_ZERO,
+ DC_DOMAINBLEND_BLEND_ONE,
+ DC_DOMAINBLEND_BLEND_PRIM_ALPHA,
+ DC_DOMAINBLEND_BLEND_ONE_MINUS_PRIM_ALPHA,
+ DC_DOMAINBLEND_BLEND_SEC_ALPHA,
+ DC_DOMAINBLEND_BLEND_ONE_MINUS_SEC_ALPHA,
+ DC_DOMAINBLEND_BLEND_CONST_ALPHA,
+ DC_DOMAINBLEND_BLEND_ONE_MINUS_CONST_ALPHA,
+};
+
+enum dc_db_shadow_sel {
+ SW = 0x4,
+ SW_PRIM = 0x5,
+ SW_SEC = 0x6,
+};
+
+static const struct dc_subdev_info dc_db_info[] = {
+ { .reg_start = 0x4b6a0000, .id = 0, },
+ { .reg_start = 0x4b720000, .id = 1, },
+};
+
+static const struct regmap_range dc_db_regmap_ranges[] = {
+ regmap_reg_range(STATICCONTROL, BLENDCONTROL),
+};
+
+static const struct regmap_access_table dc_db_regmap_access_table = {
+ .yes_ranges = dc_db_regmap_ranges,
+ .n_yes_ranges = ARRAY_SIZE(dc_db_regmap_ranges),
+};
+
+static const struct regmap_config dc_db_cfg_regmap_config = {
+ .name = "cfg",
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .fast_io = true,
+ .wr_table = &dc_db_regmap_access_table,
+ .rd_table = &dc_db_regmap_access_table,
+ .max_register = BLENDCONTROL,
+};
+
+enum dc_db_mode {
+ DB_PRIMARY,
+ DB_SECONDARY,
+ DB_BLEND,
+ DB_SIDEBYSIDE,
+};
+
+static inline void dc_db_enable_shden(struct dc_db *db)
+{
+ regmap_write_bits(db->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
+}
+
+static inline void dc_db_shdtoksel(struct dc_db *db, enum dc_db_shadow_sel sel)
+{
+ regmap_write_bits(db->reg_cfg, STATICCONTROL, SHDTOKSEL_MASK,
+ SHDTOKSEL(sel));
+}
+
+static inline void dc_db_shdldsel(struct dc_db *db, enum dc_db_shadow_sel sel)
+{
+ regmap_write_bits(db->reg_cfg, STATICCONTROL, SHDLDSEL_MASK,
+ SHDLDSEL(sel));
+}
+
+void dc_db_shdtokgen(struct dc_db *db)
+{
+ regmap_write(db->reg_cfg, CONTROL, SHDTOKGEN);
+}
+
+static void dc_db_mode(struct dc_db *db, enum dc_db_mode mode)
+{
+ regmap_write(db->reg_cfg, MODECONTROL, mode);
+}
+
+static inline void dc_db_alphamaskmode_disable(struct dc_db *db)
+{
+ regmap_write_bits(db->reg_cfg, ALPHACONTROL, ALPHAMASKENABLE, 0);
+}
+
+static inline void dc_db_blendcontrol(struct dc_db *db)
+{
+ u32 val = PRIM_A_BLD_FUNC(DC_DOMAINBLEND_BLEND_ZERO) |
+ SEC_A_BLD_FUNC(DC_DOMAINBLEND_BLEND_ZERO) |
+ PRIM_C_BLD_FUNC(DC_DOMAINBLEND_BLEND_ZERO) |
+ SEC_C_BLD_FUNC(DC_DOMAINBLEND_BLEND_ONE);
+
+ regmap_write(db->reg_cfg, BLENDCONTROL, val);
+}
+
+void dc_db_init(struct dc_db *db)
+{
+ dc_db_enable_shden(db);
+ dc_db_shdtoksel(db, SW);
+ dc_db_shdldsel(db, SW);
+ dc_db_mode(db, DB_PRIMARY);
+ dc_db_alphamaskmode_disable(db);
+ dc_db_blendcontrol(db);
+}
+
+static int dc_db_bind(struct device *dev, struct device *master, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dc_drm_device *dc_drm = data;
+ struct resource *res_cfg;
+ void __iomem *base_cfg;
+ struct dc_db *db;
+
+ db = devm_kzalloc(dev, sizeof(*db), GFP_KERNEL);
+ if (!db)
+ return -ENOMEM;
+
+ base_cfg = devm_platform_get_and_ioremap_resource(pdev, 0, &res_cfg);
+ if (IS_ERR(base_cfg))
+ return PTR_ERR(base_cfg);
+
+ db->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
+ &dc_db_cfg_regmap_config);
+ if (IS_ERR(db->reg_cfg))
+ return PTR_ERR(db->reg_cfg);
+
+ db->id = dc_subdev_get_id(dc_db_info, ARRAY_SIZE(dc_db_info), res_cfg);
+ if (db->id < 0) {
+ dev_err(dev, "failed to get instance number: %d\n", db->id);
+ return db->id;
+ }
+
+ db->dev = dev;
+ dc_drm->db[db->id] = db;
+
+ return 0;
+}
+
+static const struct component_ops dc_db_ops = {
+ .bind = dc_db_bind,
+};
+
+static int dc_db_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = component_add(&pdev->dev, &dc_db_ops);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret,
+ "failed to add component\n");
+
+ return 0;
+}
+
+static void dc_db_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &dc_db_ops);
+}
+
+static const struct of_device_id dc_db_dt_ids[] = {
+ { .compatible = "fsl,imx95-dc-domainblend" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dc_db_dt_ids);
+
+struct platform_driver dc_db_driver = {
+ .probe = dc_db_probe,
+ .remove = dc_db_remove,
+ .driver = {
+ .name = "imx95-dc-domainblend",
+ .suppress_bind_attrs = true,
+ .of_match_table = dc_db_dt_ids,
+ },
+};
diff --git a/drivers/gpu/drm/imx/dc/dc-de.c b/drivers/gpu/drm/imx/dc/dc-de.c
index 5a3125596fdf4..23b0cea68d325 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.c
+++ b/drivers/gpu/drm/imx/dc/dc-de.c
@@ -114,6 +114,7 @@ void dc_de_post_bind(struct dc_drm_device *dc_drm)
for (i = 0; i < DC_DISPLAYS; i++) {
de = dc_drm->de[i];
+ de->db = dc_drm->db[i];
de->fg = dc_drm->fg[i];
de->tc = dc_drm->tc[i];
}
@@ -149,6 +150,7 @@ static int dc_de_runtime_resume(struct device *dev)
struct dc_de *de = dev_get_drvdata(dev);
dc_dec_init(de);
+ dc_db_init(de->db);
dc_fg_init(de->fg);
dc_tc_init(de->tc);
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
index 211f3fcc1a9ad..1ac70b4f6276f 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.h
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -16,6 +16,12 @@
#define DC_FRAMEGEN_MAX_FRAME_INDEX 0x3ffff
#define DC_FRAMEGEN_MAX_CLOCK_KHZ 300000
+struct dc_db {
+ struct device *dev;
+ struct regmap *reg_cfg;
+ int id;
+};
+
struct dc_fg {
struct device *dev;
struct regmap *reg;
@@ -30,6 +36,7 @@ struct dc_tc {
struct dc_de {
struct device *dev;
struct regmap *reg_top;
+ struct dc_db *db;
struct dc_fg *fg;
struct dc_tc *tc;
int irq_shdload;
@@ -37,6 +44,10 @@ struct dc_de {
int irq_seqcomplete;
};
+/* Domain Blend Unit */
+void dc_db_init(struct dc_db *db);
+void dc_db_shdtokgen(struct dc_db *db);
+
/* Frame Generator Unit */
void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m);
void dc_fg_enable(struct dc_fg *fg);
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index 04f021d2d6cfc..f108964bf89f4 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -263,6 +263,7 @@ static struct platform_driver dc_driver = {
static struct platform_driver * const dc_drivers[] = {
&dc_cf_driver,
+ &dc_db_driver,
&dc_de_driver,
&dc_ed_driver,
&dc_fg_driver,
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index eb61b8c762693..17ce2d748262b 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -40,6 +40,8 @@ struct dc_drm_device {
struct dc_ed *ed_safe[DC_DISPLAYS];
/** @ed_cont: extdst list(content stream) */
struct dc_ed *ed_cont[DC_DISPLAYS];
+ /** @lb: domainblend list */
+ struct dc_db *db[DC_DISPLAYS];
/** @fg: framegen list */
struct dc_fg *fg[DC_DISPLAYS];
/** @fu_disp: fetchunit list(used by display engine) */
@@ -71,6 +73,7 @@ void dc_kms_uninit(struct dc_drm_device *dc_drm);
int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
extern struct platform_driver dc_cf_driver;
+extern struct platform_driver dc_db_driver;
extern struct platform_driver dc_de_driver;
extern struct platform_driver dc_ed_driver;
extern struct platform_driver dc_fg_driver;
diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
index cd7860eff986a..3e61dbb87afe7 100644
--- a/drivers/gpu/drm/imx/dc/dc-kms.h
+++ b/drivers/gpu/drm/imx/dc/dc-kms.h
@@ -48,6 +48,8 @@ struct dc_crtc {
struct dc_ed *ed_cont;
/** @ed_safe: safety stream extdst */
struct dc_ed *ed_safe;
+ /** @db: domain blend */
+ struct dc_db *db;
/** @fg: framegen */
struct dc_fg *fg;
/**
@@ -122,6 +124,8 @@ struct dc_plane {
struct dc_fu *fu;
/** @cf: content stream constframe */
struct dc_cf *cf;
+ /** @db: domainblend */
+ struct dc_db *db;
/** @lb: layerblend */
struct dc_lb *lb;
/** @ed: content stream extdst */
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 02/39] drm/imx: Add i.MX95 Display Controller DomainBlend
2025-10-11 16:51 ` [PATCH 02/39] drm/imx: Add " Marek Vasut
@ 2025-10-13 16:38 ` Frank Li
2025-10-14 11:50 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 16:38 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:17PM +0200, Marek Vasut wrote:
> i.MX95 Display Controller display engine consists of all processing
> units that operate in a display clock domain. Add DomainBlend driver
> which is specific to i.MX95 and required to get any display output on
> that SoC.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/Makefile | 2 +-
> drivers/gpu/drm/imx/dc/dc-crtc.c | 2 +
> drivers/gpu/drm/imx/dc/dc-db.c | 226 +++++++++++++++++++++++++++++++
> drivers/gpu/drm/imx/dc/dc-de.c | 2 +
> drivers/gpu/drm/imx/dc/dc-de.h | 11 ++
> drivers/gpu/drm/imx/dc/dc-drv.c | 1 +
> drivers/gpu/drm/imx/dc/dc-drv.h | 3 +
> drivers/gpu/drm/imx/dc/dc-kms.h | 4 +
> 8 files changed, 250 insertions(+), 1 deletion(-)
> create mode 100644 drivers/gpu/drm/imx/dc/dc-db.c
>
> diff --git a/drivers/gpu/drm/imx/dc/Makefile b/drivers/gpu/drm/imx/dc/Makefile
> index b9d33c074984a..20386e4082e56 100644
> --- a/drivers/gpu/drm/imx/dc/Makefile
> +++ b/drivers/gpu/drm/imx/dc/Makefile
> @@ -1,6 +1,6 @@
> # SPDX-License-Identifier: GPL-2.0
>
> -imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
> +imx8-dc-drm-objs := dc-cf.o dc-crtc.o dc-db.o dc-de.o dc-drv.o dc-ed.o dc-fg.o dc-fl.o \
> dc-fu.o dc-fw.o dc-ic.o dc-kms.o dc-lb.o dc-pe.o \
> dc-plane.o dc-tc.o
>
...
> +
> +#include "dc-drv.h"
> +#include "dc-pe.h"
> +
> +#define PIXENGCFG_DYNAMIC 0x8
> +#define PIXENGCFG_DYNAMIC_PRIM_SEL_MASK GENMASK(5, 0)
> +#define PIXENGCFG_DYNAMIC_PRIM_SEL(x) \
> + FIELD_PREP(PIXENGCFG_DYNAMIC_PRIM_SEL_MASK, (x))
> +#define PIXENGCFG_DYNAMIC_SEC_SEL_MASK GENMASK(13, 8)
> +#define PIXENGCFG_DYNAMIC_SEC_SEL(x) \
> + FIELD_PREP(PIXENGCFG_DYNAMIC_SEC_SEL_MASK, (x))
> +
> +#define STATICCONTROL 0x8
> +#define SHDTOKSEL_MASK GENMASK(6, 4)
> +#define SHDTOKSEL(x) FIELD_PREP(SHDTOKSEL_MASK, (x))
> +#define SHDLDSEL_MASK GENMASK(3, 1)
> +#define SHDLDSEL(x) FIELD_PREP(SHDLDSEL_MASK, (x))
Can you keep bit fields as consistent order, from 31..0 or 0..31.
> +
> +#define CONTROL 0xc
> +#define SHDTOKGEN BIT(0)
> +
...
> +
> +enum dc_db_blend_func {
> + DC_DOMAINBLEND_BLEND_ZERO,
> + DC_DOMAINBLEND_BLEND_ONE,
> + DC_DOMAINBLEND_BLEND_PRIM_ALPHA,
> + DC_DOMAINBLEND_BLEND_ONE_MINUS_PRIM_ALPHA,
> + DC_DOMAINBLEND_BLEND_SEC_ALPHA,
> + DC_DOMAINBLEND_BLEND_ONE_MINUS_SEC_ALPHA,
> + DC_DOMAINBLEND_BLEND_CONST_ALPHA,
> + DC_DOMAINBLEND_BLEND_ONE_MINUS_CONST_ALPHA,
> +};
> +
> +enum dc_db_shadow_sel {
> + SW = 0x4,
> + SW_PRIM = 0x5,
> + SW_SEC = 0x6,
> +};
> +
> +static const struct dc_subdev_info dc_db_info[] = {
> + { .reg_start = 0x4b6a0000, .id = 0, },
> + { .reg_start = 0x4b720000, .id = 1, },
> +};
Not sure why need map register address to id? Does graphic link or use
dt cells pass it as argument.
I have find use .id at this driver.
> +
> +static const struct regmap_range dc_db_regmap_ranges[] = {
> + regmap_reg_range(STATICCONTROL, BLENDCONTROL),
> +};
> +
...
> +
> +static inline void dc_db_enable_shden(struct dc_db *db)
> +{
> + regmap_write_bits(db->reg_cfg, STATICCONTROL, SHDEN, SHDEN);
> +}
> +
> +static inline void dc_db_shdtoksel(struct dc_db *db, enum dc_db_shadow_sel sel)
> +{
> + regmap_write_bits(db->reg_cfg, STATICCONTROL, SHDTOKSEL_MASK,
> + SHDTOKSEL(sel));
> +}
> +
> +static inline void dc_db_shdldsel(struct dc_db *db, enum dc_db_shadow_sel sel)
> +{
> + regmap_write_bits(db->reg_cfg, STATICCONTROL, SHDLDSEL_MASK,
> + SHDLDSEL(sel));
> +}
> +
> +void dc_db_shdtokgen(struct dc_db *db)
> +{
> + regmap_write(db->reg_cfg, CONTROL, SHDTOKGEN);
> +}
> +
> +static void dc_db_mode(struct dc_db *db, enum dc_db_mode mode)
> +{
> + regmap_write(db->reg_cfg, MODECONTROL, mode);
> +}
> +
> +static inline void dc_db_alphamaskmode_disable(struct dc_db *db)
> +{
> + regmap_write_bits(db->reg_cfg, ALPHACONTROL, ALPHAMASKENABLE, 0);
> +}
This helper function just write value to one register, not helper much
at all.
> +
> +static inline void dc_db_blendcontrol(struct dc_db *db)
> +{
> + u32 val = PRIM_A_BLD_FUNC(DC_DOMAINBLEND_BLEND_ZERO) |
> + SEC_A_BLD_FUNC(DC_DOMAINBLEND_BLEND_ZERO) |
> + PRIM_C_BLD_FUNC(DC_DOMAINBLEND_BLEND_ZERO) |
> + SEC_C_BLD_FUNC(DC_DOMAINBLEND_BLEND_ONE);
> +
> + regmap_write(db->reg_cfg, BLENDCONTROL, val);
> +}
> +
> +void dc_db_init(struct dc_db *db)
> +{
> + dc_db_enable_shden(db);
> + dc_db_shdtoksel(db, SW);
> + dc_db_shdldsel(db, SW);
> + dc_db_mode(db, DB_PRIMARY);
> + dc_db_alphamaskmode_disable(db);
> + dc_db_blendcontrol(db);
> +}
> +
...
>
> +struct dc_db {
> + struct device *dev;
> + struct regmap *reg_cfg;
> + int id;
where actually use this id?
Frank
> +};
> +
> struct dc_fg {
> struct device *dev;
> struct regmap *reg;
> @@ -30,6 +36,7 @@ struct dc_tc {
> struct dc_de {
> struct device *dev;
> struct regmap *reg_top;
> + struct dc_db *db;
> struct dc_fg *fg;
> struct dc_tc *tc;
> int irq_shdload;
> @@ -37,6 +44,10 @@ struct dc_de {
> int irq_seqcomplete;
> };
>
> +/* Domain Blend Unit */
> +void dc_db_init(struct dc_db *db);
> +void dc_db_shdtokgen(struct dc_db *db);
> +
> /* Frame Generator Unit */
> void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m);
> void dc_fg_enable(struct dc_fg *fg);
> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
> index 04f021d2d6cfc..f108964bf89f4 100644
> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
> @@ -263,6 +263,7 @@ static struct platform_driver dc_driver = {
>
> static struct platform_driver * const dc_drivers[] = {
> &dc_cf_driver,
> + &dc_db_driver,
> &dc_de_driver,
> &dc_ed_driver,
> &dc_fg_driver,
> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
> index eb61b8c762693..17ce2d748262b 100644
> --- a/drivers/gpu/drm/imx/dc/dc-drv.h
> +++ b/drivers/gpu/drm/imx/dc/dc-drv.h
> @@ -40,6 +40,8 @@ struct dc_drm_device {
> struct dc_ed *ed_safe[DC_DISPLAYS];
> /** @ed_cont: extdst list(content stream) */
> struct dc_ed *ed_cont[DC_DISPLAYS];
> + /** @lb: domainblend list */
> + struct dc_db *db[DC_DISPLAYS];
> /** @fg: framegen list */
> struct dc_fg *fg[DC_DISPLAYS];
> /** @fu_disp: fetchunit list(used by display engine) */
> @@ -71,6 +73,7 @@ void dc_kms_uninit(struct dc_drm_device *dc_drm);
> int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane);
>
> extern struct platform_driver dc_cf_driver;
> +extern struct platform_driver dc_db_driver;
> extern struct platform_driver dc_de_driver;
> extern struct platform_driver dc_ed_driver;
> extern struct platform_driver dc_fg_driver;
> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
> index cd7860eff986a..3e61dbb87afe7 100644
> --- a/drivers/gpu/drm/imx/dc/dc-kms.h
> +++ b/drivers/gpu/drm/imx/dc/dc-kms.h
> @@ -48,6 +48,8 @@ struct dc_crtc {
> struct dc_ed *ed_cont;
> /** @ed_safe: safety stream extdst */
> struct dc_ed *ed_safe;
> + /** @db: domain blend */
> + struct dc_db *db;
> /** @fg: framegen */
> struct dc_fg *fg;
> /**
> @@ -122,6 +124,8 @@ struct dc_plane {
> struct dc_fu *fu;
> /** @cf: content stream constframe */
> struct dc_cf *cf;
> + /** @db: domainblend */
> + struct dc_db *db;
> /** @lb: layerblend */
> struct dc_lb *lb;
> /** @ed: content stream extdst */
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 02/39] drm/imx: Add i.MX95 Display Controller DomainBlend
2025-10-13 16:38 ` Frank Li
@ 2025-10-14 11:50 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-14 11:50 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 6:38 PM, Frank Li wrote:
Hello Frank,
>> +#define STATICCONTROL 0x8
>> +#define SHDTOKSEL_MASK GENMASK(6, 4)
>> +#define SHDTOKSEL(x) FIELD_PREP(SHDTOKSEL_MASK, (x))
>> +#define SHDLDSEL_MASK GENMASK(3, 1)
>> +#define SHDLDSEL(x) FIELD_PREP(SHDLDSEL_MASK, (x))
>
> Can you keep bit fields as consistent order, from 31..0 or 0..31.
I sent a separate fix for that, so it can go in before these patches:
[PATCH] drm/imx: dc: Sort bits and bitfields in descending order
[...]
>> +static const struct dc_subdev_info dc_db_info[] = {
>> + { .reg_start = 0x4b6a0000, .id = 0, },
>> + { .reg_start = 0x4b720000, .id = 1, },
>> +};
>
> Not sure why need map register address to id? Does graphic link or use
> dt cells pass it as argument.
The display engine component (de) does use it to figure out which
matching domainblend component (db) to access , since there are multiple
instances of each.
Is there anything I should change ?
>> +static inline void dc_db_alphamaskmode_disable(struct dc_db *db)
>> +{
>> + regmap_write_bits(db->reg_cfg, ALPHACONTROL, ALPHAMASKENABLE, 0);
>> +}
>
> This helper function just write value to one register, not helper much
> at all.
I agree, but it also makes dc_db_init() a bit more readable, so I don't
think inlining this is going to improve the driver much.
>> +static inline void dc_db_blendcontrol(struct dc_db *db)
>> +{
>> + u32 val = PRIM_A_BLD_FUNC(DC_DOMAINBLEND_BLEND_ZERO) |
>> + SEC_A_BLD_FUNC(DC_DOMAINBLEND_BLEND_ZERO) |
>> + PRIM_C_BLD_FUNC(DC_DOMAINBLEND_BLEND_ZERO) |
>> + SEC_C_BLD_FUNC(DC_DOMAINBLEND_BLEND_ONE);
>> +
>> + regmap_write(db->reg_cfg, BLENDCONTROL, val);
>> +}
>> +
>> +void dc_db_init(struct dc_db *db)
>> +{
>> + dc_db_enable_shden(db);
>> + dc_db_shdtoksel(db, SW);
>> + dc_db_shdldsel(db, SW);
>> + dc_db_mode(db, DB_PRIMARY);
>> + dc_db_alphamaskmode_disable(db);
>> + dc_db_blendcontrol(db);
>> +}
>> +
> ...
>>
>> +struct dc_db {
>> + struct device *dev;
>> + struct regmap *reg_cfg;
>> + int id;
>
> where actually use this id?
Please see dc_db_bind() .
I will be handling the rest of the feedback on this series piece by
piece, thank you for your input.
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
2025-10-11 16:51 ` [PATCH 01/39] dt-bindings: display: imx: Document i.MX95 Display Controller DomainBlend Marek Vasut
2025-10-11 16:51 ` [PATCH 02/39] drm/imx: Add " Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 16:49 ` Frank Li
2025-10-11 16:51 ` [PATCH 04/39] drm/imx: dc: Use bulk clock Marek Vasut
` (37 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Freescale i.MX95 Display Controller is implemented as construction set of
building blocks with unified concept and standardized interfaces. Document
all new processing units present in i.MX95.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
.../imx/fsl,imx8qxp-dc-constframe.yaml | 4 +-
.../imx/fsl,imx8qxp-dc-display-engine.yaml | 45 +++++++++++++---
.../display/imx/fsl,imx8qxp-dc-extdst.yaml | 4 +-
.../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 1 +
.../display/imx/fsl,imx8qxp-dc-framegen.yaml | 13 ++++-
.../imx/fsl,imx8qxp-dc-layerblend.yaml | 4 +-
.../imx/fsl,imx8qxp-dc-pixel-engine.yaml | 52 +++++++++++++++---
.../display/imx/fsl,imx8qxp-dc-tcon.yaml | 5 +-
.../bindings/display/imx/fsl,imx8qxp-dc.yaml | 53 ++++++++++++++++---
9 files changed, 153 insertions(+), 28 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
index 94f6785636085..3a585b3b9a789 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
@@ -18,7 +18,9 @@ maintainers:
properties:
compatible:
- const: fsl,imx8qxp-dc-constframe
+ enum:
+ - fsl,imx8qxp-dc-constframe
+ - fsl,imx95-dc-constframe
reg:
maxItems: 2
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml
index 91f3bb77d8d0d..aba818546028b 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-display-engine.yaml
@@ -16,7 +16,9 @@ maintainers:
properties:
compatible:
- const: fsl,imx8qxp-dc-display-engine
+ enum:
+ - fsl,imx8qxp-dc-display-engine
+ - fsl,imx95-dc-display-engine
reg:
maxItems: 2
@@ -42,10 +44,10 @@ properties:
maxItems: 1
"#address-cells":
- const: 1
+ enum: [1, 2]
"#size-cells":
- const: 1
+ enum: [1, 2]
ranges: true
@@ -58,13 +60,23 @@ patternProperties:
compatible:
const: fsl,imx8qxp-dc-dither
+ "^domainblend@[0-9a-f]+$":
+ type: object
+ additionalProperties: true
+
+ properties:
+ compatible:
+ const: fsl,imx95-dc-domainblend
+
"^framegen@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
- const: fsl,imx8qxp-dc-framegen
+ enum:
+ - fsl,imx8qxp-dc-framegen
+ - fsl,imx95-dc-framegen
"^gammacor@[0-9a-f]+$":
type: object
@@ -90,13 +102,15 @@ patternProperties:
compatible:
const: fsl,imx8qxp-dc-signature
- "^tcon@[0-9a-f]+$":
+ "^tcon(@[0-9a-f]+)?$":
type: object
additionalProperties: true
properties:
compatible:
- const: fsl,imx8qxp-dc-tcon
+ enum:
+ - fsl,imx8qxp-dc-tcon
+ - fsl,imx95-dc-tcon
required:
- compatible
@@ -109,6 +123,25 @@ required:
- "#size-cells"
- ranges
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,imx95-dc-display-engine
+ then:
+ properties:
+ "#address-cells":
+ const: 2
+ "#size-cells":
+ const: 2
+ else:
+ properties:
+ "#address-cells":
+ const: 1
+ "#size-cells":
+ const: 1
+
additionalProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
index dfc2d4f94f8eb..82a748b0024d4 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-extdst.yaml
@@ -32,7 +32,9 @@ maintainers:
properties:
compatible:
- const: fsl,imx8qxp-dc-extdst
+ enum:
+ - fsl,imx8qxp-dc-extdst
+ - fsl,imx95-dc-extdst
reg:
maxItems: 2
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
index 97fb6a4598d96..0e67322627a55 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-fetchunit.yaml
@@ -111,6 +111,7 @@ properties:
- fsl,imx8qxp-dc-fetcheco
- fsl,imx8qxp-dc-fetchlayer
- fsl,imx8qxp-dc-fetchwarp
+ - fsl,imx95-dc-fetchlayer
reg:
maxItems: 2
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
index 9d1dc3a9de90e..dd83ac669478b 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
@@ -16,18 +16,27 @@ maintainers:
properties:
compatible:
- const: fsl,imx8qxp-dc-framegen
+ enum:
+ - fsl,imx8qxp-dc-framegen
+ - fsl,imx95-dc-framegen
reg:
maxItems: 1
clocks:
- maxItems: 1
+ minItems: 1
+ maxItems: 6
+
+ clock-names:
+ minItems: 1
+ maxItems: 6
interrupts:
+ minItems: 6
maxItems: 8
interrupt-names:
+ minItems: 6
items:
- const: int0
- const: int1
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
index 2a6ab8a0ed7fc..6565b7acf47e4 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
@@ -13,7 +13,9 @@ maintainers:
properties:
compatible:
- const: fsl,imx8qxp-dc-layerblend
+ enum:
+ - fsl,imx8qxp-dc-layerblend
+ - fsl,imx95-dc-layerblend
reg:
maxItems: 2
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
index 633443a6cc380..2d0ee83e30b25 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
@@ -17,19 +17,28 @@ maintainers:
properties:
compatible:
- const: fsl,imx8qxp-dc-pixel-engine
+ oneOf:
+ - const: fsl,imx8qxp-dc-pixel-engine
+ - items:
+ - const: fsl,imx95-dc-pixel-engine
+ - const: fsl,imx8qxp-dc-pixel-engine
reg:
maxItems: 1
clocks:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
+
+ clock-names:
+ minItems: 1
+ maxItems: 2
"#address-cells":
- const: 1
+ enum: [1, 2]
"#size-cells":
- const: 1
+ enum: [1, 2]
ranges: true
@@ -48,7 +57,9 @@ patternProperties:
properties:
compatible:
- const: fsl,imx8qxp-dc-constframe
+ enum:
+ - fsl,imx8qxp-dc-constframe
+ - fsl,imx95-dc-constframe
"^extdst@[0-9a-f]+$":
type: object
@@ -56,7 +67,9 @@ patternProperties:
properties:
compatible:
- const: fsl,imx8qxp-dc-extdst
+ enum:
+ - fsl,imx8qxp-dc-extdst
+ - fsl,imx95-dc-extdst
"^fetchdecode@[0-9a-f]+$":
type: object
@@ -80,7 +93,9 @@ patternProperties:
properties:
compatible:
- const: fsl,imx8qxp-dc-fetchlayer
+ enum:
+ - fsl,imx8qxp-dc-fetchlayer
+ - fsl,imx95-dc-fetchlayer
"^fetchwarp@[0-9a-f]+$":
type: object
@@ -104,7 +119,9 @@ patternProperties:
properties:
compatible:
- const: fsl,imx8qxp-dc-layerblend
+ enum:
+ - fsl,imx8qxp-dc-layerblend
+ - fsl,imx95-dc-layerblend
"^matrix@[0-9a-f]+$":
type: object
@@ -138,6 +155,25 @@ required:
- "#size-cells"
- ranges
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,imx95-dc-pixel-engine
+ then:
+ properties:
+ "#address-cells":
+ const: 2
+ "#size-cells":
+ const: 2
+ else:
+ properties:
+ "#address-cells":
+ const: 1
+ "#size-cells":
+ const: 1
+
additionalProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
index 7a3b77ea92c73..1f935b342f461 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
@@ -15,7 +15,9 @@ maintainers:
properties:
compatible:
- const: fsl,imx8qxp-dc-tcon
+ enum:
+ - fsl,imx8qxp-dc-tcon
+ - fsl,imx95-dc-tcon
reg:
maxItems: 1
@@ -26,7 +28,6 @@ properties:
required:
- compatible
- - reg
- port
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
index 0a72f9f0b5fda..1e8f559acb4de 100644
--- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
@@ -48,13 +48,20 @@ maintainers:
properties:
compatible:
- const: fsl,imx8qxp-dc
+ enum:
+ - fsl,imx8qxp-dc
+ - fsl,imx95-dc
reg:
maxItems: 1
clocks:
- maxItems: 1
+ minItems: 1
+ maxItems: 6
+
+ clock-names:
+ minItems: 1
+ maxItems: 6
resets:
maxItems: 2
@@ -68,10 +75,15 @@ properties:
maxItems: 1
"#address-cells":
- const: 1
+ enum: [1, 2]
"#size-cells":
- const: 1
+ enum: [1, 2]
+
+ fsl,syscon:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: |
+ A phandle which points to Control and Status Registers (CSR) module.
ranges: true
@@ -90,7 +102,9 @@ patternProperties:
properties:
compatible:
- const: fsl,imx8qxp-dc-display-engine
+ enum:
+ - fsl,imx8qxp-dc-display-engine
+ - fsl,imx95-dc-display-engine
"^interrupt-controller@[0-9a-f]+$":
type: object
@@ -98,7 +112,9 @@ patternProperties:
properties:
compatible:
- const: fsl,imx8qxp-dc-intc
+ enum:
+ - fsl,imx8qxp-dc-intc
+ - fsl,imx95-dc-intc
"^pixel-engine@[0-9a-f]+$":
type: object
@@ -106,7 +122,11 @@ patternProperties:
properties:
compatible:
- const: fsl,imx8qxp-dc-pixel-engine
+ oneOf:
+ - const: fsl,imx8qxp-dc-pixel-engine
+ - items:
+ - const: fsl,imx95-dc-pixel-engine
+ - const: fsl,imx8qxp-dc-pixel-engine
"^pmu@[0-9a-f]+$":
type: object
@@ -125,6 +145,25 @@ required:
- "#size-cells"
- ranges
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,imx95-dc
+ then:
+ properties:
+ "#address-cells":
+ const: 2
+ "#size-cells":
+ const: 2
+ else:
+ properties:
+ "#address-cells":
+ const: 1
+ "#size-cells":
+ const: 1
+
additionalProperties: false
examples:
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units
2025-10-11 16:51 ` [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units Marek Vasut
@ 2025-10-13 16:49 ` Frank Li
2025-10-14 11:52 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 16:49 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:18PM +0200, Marek Vasut wrote:
> Freescale i.MX95 Display Controller is implemented as construction set of
> building blocks with unified concept and standardized interfaces. Document
> all new processing units present in i.MX95.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../imx/fsl,imx8qxp-dc-constframe.yaml | 4 +-
> .../imx/fsl,imx8qxp-dc-display-engine.yaml | 45 +++++++++++++---
> .../display/imx/fsl,imx8qxp-dc-extdst.yaml | 4 +-
> .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 1 +
> .../display/imx/fsl,imx8qxp-dc-framegen.yaml | 13 ++++-
> .../imx/fsl,imx8qxp-dc-layerblend.yaml | 4 +-
> .../imx/fsl,imx8qxp-dc-pixel-engine.yaml | 52 +++++++++++++++---
> .../display/imx/fsl,imx8qxp-dc-tcon.yaml | 5 +-
> .../bindings/display/imx/fsl,imx8qxp-dc.yaml | 53 ++++++++++++++++---
> 9 files changed, 153 insertions(+), 28 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
> index 94f6785636085..3a585b3b9a789 100644
> --- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-constframe.yaml
> @@ -18,7 +18,9 @@ maintainers:
>
...
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc-framegen
> + enum:
> + - fsl,imx8qxp-dc-framegen
> + - fsl,imx95-dc-framegen
>
> "^gammacor@[0-9a-f]+$":
> type: object
> @@ -90,13 +102,15 @@ patternProperties:
> compatible:
> const: fsl,imx8qxp-dc-signature
>
> - "^tcon@[0-9a-f]+$":
> + "^tcon(@[0-9a-f]+)?$":
why here allow no address unit tcon?
Frank
> type: object
> additionalProperties: true
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc-tcon
> + enum:
> + - fsl,imx8qxp-dc-tcon
> + - fsl,imx95-dc-tcon
>
...
> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
> index 9d1dc3a9de90e..dd83ac669478b 100644
> --- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-framegen.yaml
> @@ -16,18 +16,27 @@ maintainers:
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc-framegen
> + enum:
> + - fsl,imx8qxp-dc-framegen
> + - fsl,imx95-dc-framegen
>
> reg:
> maxItems: 1
>
> clocks:
> - maxItems: 1
> + minItems: 1
> + maxItems: 6
> +
> + clock-names:
> + minItems: 1
> + maxItems: 6
>
> interrupts:
> + minItems: 6
> maxItems: 8
>
> interrupt-names:
> + minItems: 6
Need if branch to keep the same restriction for exited compatible string
> items:
> - const: int0
> - const: int1
> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
> index 2a6ab8a0ed7fc..6565b7acf47e4 100644
> --- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-layerblend.yaml
> @@ -13,7 +13,9 @@ maintainers:
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc-layerblend
> + enum:
> + - fsl,imx8qxp-dc-layerblend
> + - fsl,imx95-dc-layerblend
>
> reg:
> maxItems: 2
...
> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
> index 633443a6cc380..2d0ee83e30b25 100644
> --- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-pixel-engine.yaml
> @@ -17,19 +17,28 @@ maintainers:
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc-pixel-engine
> + oneOf:
> + - const: fsl,imx8qxp-dc-pixel-engine
> + - items:
> + - const: fsl,imx95-dc-pixel-engine
> + - const: fsl,imx8qxp-dc-pixel-engine
>
> reg:
> maxItems: 1
>
> clocks:
> - maxItems: 1
> + minItems: 1
> + maxItems: 2
> +
> + clock-names:
> + minItems: 1
> + maxItems: 2
>
> "#address-cells":
> - const: 1
> + enum: [1, 2]
>
> "#size-cells":
> - const: 1
> + enum: [1, 2]
>
> ranges: true
>
...
>
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: fsl,imx95-dc-pixel-engine
> + then:
> + properties:
> + "#address-cells":
> + const: 2
> + "#size-cells":
> + const: 2
> + else:
> + properties:
> + "#address-cells":
> + const: 1
> + "#size-cells":
> + const: 1
Need keep the same restriction for clocks and clock-names.
> +
> additionalProperties: false
>
> examples:
> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
> index 7a3b77ea92c73..1f935b342f461 100644
> --- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc-tcon.yaml
> @@ -15,7 +15,9 @@ maintainers:
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc-tcon
> + enum:
> + - fsl,imx8qxp-dc-tcon
> + - fsl,imx95-dc-tcon
>
> reg:
> maxItems: 1
> @@ -26,7 +28,6 @@ properties:
>
> required:
> - compatible
> - - reg
> - port
>
> additionalProperties: false
> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
> index 0a72f9f0b5fda..1e8f559acb4de 100644
> --- a/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dc.yaml
> @@ -48,13 +48,20 @@ maintainers:
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc
> + enum:
> + - fsl,imx8qxp-dc
> + - fsl,imx95-dc
>
> reg:
> maxItems: 1
>
> clocks:
> - maxItems: 1
> + minItems: 1
> + maxItems: 6
> +
> + clock-names:
> + minItems: 1
> + maxItems: 6
>
> resets:
> maxItems: 2
> @@ -68,10 +75,15 @@ properties:
> maxItems: 1
>
> "#address-cells":
> - const: 1
> + enum: [1, 2]
>
> "#size-cells":
> - const: 1
> + enum: [1, 2]
> +
> + fsl,syscon:
> + $ref: /schemas/types.yaml#/definitions/phandle
> + description: |
> + A phandle which points to Control and Status Registers (CSR) module.
Why need this one? is it possible to abstract it to standard interface,
like phy, clock, reset ...
Frank
>
> ranges: true
>
> @@ -90,7 +102,9 @@ patternProperties:
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc-display-engine
> + enum:
> + - fsl,imx8qxp-dc-display-engine
> + - fsl,imx95-dc-display-engine
>
> "^interrupt-controller@[0-9a-f]+$":
> type: object
> @@ -98,7 +112,9 @@ patternProperties:
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc-intc
> + enum:
> + - fsl,imx8qxp-dc-intc
> + - fsl,imx95-dc-intc
>
> "^pixel-engine@[0-9a-f]+$":
> type: object
> @@ -106,7 +122,11 @@ patternProperties:
>
> properties:
> compatible:
> - const: fsl,imx8qxp-dc-pixel-engine
> + oneOf:
> + - const: fsl,imx8qxp-dc-pixel-engine
> + - items:
> + - const: fsl,imx95-dc-pixel-engine
> + - const: fsl,imx8qxp-dc-pixel-engine
>
> "^pmu@[0-9a-f]+$":
> type: object
> @@ -125,6 +145,25 @@ required:
> - "#size-cells"
> - ranges
>
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: fsl,imx95-dc
> + then:
> + properties:
> + "#address-cells":
> + const: 2
> + "#size-cells":
> + const: 2
> + else:
> + properties:
> + "#address-cells":
> + const: 1
> + "#size-cells":
> + const: 1
> +
> additionalProperties: false
>
> examples:
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units
2025-10-13 16:49 ` Frank Li
@ 2025-10-14 11:52 ` Marek Vasut
2025-10-15 8:59 ` Liu Ying
0 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-14 11:52 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 6:49 PM, Frank Li wrote:
Hello Frank,
>> @@ -90,13 +102,15 @@ patternProperties:
>> compatible:
>> const: fsl,imx8qxp-dc-signature
>>
>> - "^tcon@[0-9a-f]+$":
>> + "^tcon(@[0-9a-f]+)?$":
>
> why here allow no address unit tcon?
This might be something Liu can clarify too.
TCON on iMX95 DPU does not seem to exist at all, or at least has no
control registers. Hence no address.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units
2025-10-14 11:52 ` Marek Vasut
@ 2025-10-15 8:59 ` Liu Ying
2025-10-15 10:19 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Liu Ying @ 2025-10-15 8:59 UTC (permalink / raw)
To: Marek Vasut, Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/14/2025, Marek Vasut wrote:
> On 10/13/25 6:49 PM, Frank Li wrote:
>
> Hello Frank,
>
>>> @@ -90,13 +102,15 @@ patternProperties:
>>> compatible:
>>> const: fsl,imx8qxp-dc-signature
>>>
>>> - "^tcon@[0-9a-f]+$":
>>> + "^tcon(@[0-9a-f]+)?$":
>>
>> why here allow no address unit tcon?
> This might be something Liu can clarify too.
>
> TCON on iMX95 DPU does not seem to exist at all, or at least has no control registers. Hence no address.
i.MX95 DC hasn't got TCON so it should not be documented for i.MX95 DC.
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units
2025-10-15 8:59 ` Liu Ying
@ 2025-10-15 10:19 ` Marek Vasut
2025-10-16 2:28 ` Liu Ying
0 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-15 10:19 UTC (permalink / raw)
To: Liu Ying, Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/15/25 10:59 AM, Liu Ying wrote:
Hello Liu,
>>>> @@ -90,13 +102,15 @@ patternProperties:
>>>> compatible:
>>>> const: fsl,imx8qxp-dc-signature
>>>>
>>>> - "^tcon@[0-9a-f]+$":
>>>> + "^tcon(@[0-9a-f]+)?$":
>>>
>>> why here allow no address unit tcon?
>> This might be something Liu can clarify too.
>>
>> TCON on iMX95 DPU does not seem to exist at all, or at least has no control registers. Hence no address.
>
> i.MX95 DC hasn't got TCON so it should not be documented for i.MX95 DC.
What DT node do I attach the pixel-mapper/pixel-interleaver to then ?
--
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units
2025-10-15 10:19 ` Marek Vasut
@ 2025-10-16 2:28 ` Liu Ying
2025-10-16 2:58 ` Liu Ying
2025-10-17 15:18 ` Marek Vasut
0 siblings, 2 replies; 113+ messages in thread
From: Liu Ying @ 2025-10-16 2:28 UTC (permalink / raw)
To: Marek Vasut, Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/15/2025, Marek Vasut wrote:
> On 10/15/25 10:59 AM, Liu Ying wrote:
>
> Hello Liu,
Hello,
>
>>>>> @@ -90,13 +102,15 @@ patternProperties:
>>>>> compatible:
>>>>> const: fsl,imx8qxp-dc-signature
>>>>>
>>>>> - "^tcon@[0-9a-f]+$":
>>>>> + "^tcon(@[0-9a-f]+)?$":
>>>>
>>>> why here allow no address unit tcon?
>>> This might be something Liu can clarify too.
>>>
>>> TCON on iMX95 DPU does not seem to exist at all, or at least has no control registers. Hence no address.
>>
>> i.MX95 DC hasn't got TCON so it should not be documented for i.MX95 DC.
>
> What DT node do I attach the pixel-mapper/pixel-interleaver to then ?
It's Dither unit which sits in the last position of an i.MX95 DC display stream.
BTW, i.MX8qxp/qm DCs haven't got any Dither unit. The existing i.MX8qxp DC
DT bindings have already documented all units within i.MX8qxp DC(I hope I didn't
miss any unit). And TCON is the last one for i.MX8qxp/qm DC display stream.
Have you got i.MX95 DC IP spec? If no, then it would be difficult for you to
write DT bindings for all i.MX95 DC units. Note that this is something
necessary to do.
And, a bit more information about display pipelines in i.MX95 display domain:
Dither -> pixel interleaver -> pixel link loopback -> camera domain
-> pixel link -> MIPI DSI controller
-> pixel mapper(LDB)
Note that NXP downstream kernel wrongly adds pixel link between pixel
interleaver and pixel mapper due to ambiguous i.MX95 TRM.
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units
2025-10-16 2:28 ` Liu Ying
@ 2025-10-16 2:58 ` Liu Ying
2025-10-17 15:18 ` Marek Vasut
1 sibling, 0 replies; 113+ messages in thread
From: Liu Ying @ 2025-10-16 2:58 UTC (permalink / raw)
To: Marek Vasut, Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/16/2025, Liu Ying wrote:
> BTW, i.MX8qxp/qm DCs haven't got any Dither unit.
Hmm, sorry, I have to correct this - i.MX8qxp/qm DCs do have got Dither units,
and it's documented.
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units
2025-10-16 2:28 ` Liu Ying
2025-10-16 2:58 ` Liu Ying
@ 2025-10-17 15:18 ` Marek Vasut
2025-10-18 5:44 ` Ying Liu
1 sibling, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:18 UTC (permalink / raw)
To: Liu Ying, Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/16/25 4:28 AM, Liu Ying wrote:
Hello Liu,
> Have you got i.MX95 DC IP spec? If no, then it would be difficult for you to
> write DT bindings for all i.MX95 DC units. Note that this is something
> necessary to do.
Nope, still waiting for those.
> And, a bit more information about display pipelines in i.MX95 display domain:
>
> Dither -> pixel interleaver -> pixel link loopback -> camera domain
> -> pixel link -> MIPI DSI controller
> -> pixel mapper(LDB)
>
> Note that NXP downstream kernel wrongly adds pixel link between pixel
> interleaver and pixel mapper due to ambiguous i.MX95 TRM.
Is my understanding correct, that the Dither Unit ~= Display Engine ?
^ permalink raw reply [flat|nested] 113+ messages in thread
* RE: [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units
2025-10-17 15:18 ` Marek Vasut
@ 2025-10-18 5:44 ` Ying Liu
0 siblings, 0 replies; 113+ messages in thread
From: Ying Liu @ 2025-10-18 5:44 UTC (permalink / raw)
To: Marek Vasut, Frank Li
Cc: dri-devel@lists.freedesktop.org, Abel Vesa, Conor Dooley,
Fabio Estevam, Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-clk@vger.kernel.org
On 10/17/25, Marek Vasut <marek.vasut@mailbox.org> wrote:
> On 10/16/25 4:28 AM, Liu Ying wrote:
>
> Hello Liu,
Hello Marek,
>
> > Have you got i.MX95 DC IP spec? If no, then it would be difficult for you to
> > write DT bindings for all i.MX95 DC units. Note that this is something
> > necessary to do.
>
> Nope, still waiting for those.
>
> > And, a bit more information about display pipelines in i.MX95 display
> domain:
> >
> > Dither -> pixel interleaver -> pixel link loopback -> camera domain
> > -> pixel link -> MIPI DSI controller
> > -> pixel mapper(LDB)
> >
> > Note that NXP downstream kernel wrongly adds pixel link between pixel
> > interleaver and pixel mapper due to ambiguous i.MX95 TRM.
> Is my understanding correct, that the Dither Unit ~= Display Engine ?
Nope, Dither Unit is a component of Display Engine. You may take a look at
fsl,imx8qxp-dc-display-engine.yaml whose patternProperties lists all components
of i.MX8qxp DC Display Engine and Dither Unit is one of them.
i.MX95 DC Display Engine has below components:
Domain Blend Unit, Frame Generator, Color Matrix, LUT 3D, Dither Unit, from
the first input component to the last output component, and additionally,
Signature Unit and IDHash Unit which be configured to tap from some of the
above components.
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 04/39] drm/imx: dc: Use bulk clock
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (2 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 03/39] dt-bindings: display: imx: Document i.MX95 Display Controller processing units Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 16:54 ` Frank Li
2025-10-11 16:51 ` [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use Marek Vasut
` (36 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Switch to bulk clock operations, as many of the blocks present in DC
use multiple clock on i.MX95. The use of bulk clock operations allows
the driver to seamlessly handle one or multiple clock.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-drv.c | 14 ++++++++------
drivers/gpu/drm/imx/dc/dc-ic.c | 14 ++++++++------
drivers/gpu/drm/imx/dc/dc-pe.c | 12 ++++++------
drivers/gpu/drm/imx/dc/dc-pe.h | 3 ++-
4 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index f108964bf89f4..2717c92aba6c5 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -31,7 +31,8 @@
struct dc_priv {
struct drm_device *drm;
- struct clk *clk_cfg;
+ struct clk_bulk_data *clk_cfg;
+ int clk_cfg_count;
};
DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
@@ -163,10 +164,11 @@ static int dc_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
- priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(priv->clk_cfg))
- return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
+ ret = devm_clk_bulk_get_all(&pdev->dev, &priv->clk_cfg);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
"failed to get cfg clock\n");
+ priv->clk_cfg_count = ret;
dev_set_drvdata(&pdev->dev, priv);
@@ -201,7 +203,7 @@ static int dc_runtime_suspend(struct device *dev)
{
struct dc_priv *priv = dev_get_drvdata(dev);
- clk_disable_unprepare(priv->clk_cfg);
+ clk_bulk_disable_unprepare(priv->clk_cfg_count, priv->clk_cfg);
return 0;
}
@@ -211,7 +213,7 @@ static int dc_runtime_resume(struct device *dev)
struct dc_priv *priv = dev_get_drvdata(dev);
int ret;
- ret = clk_prepare_enable(priv->clk_cfg);
+ ret = clk_bulk_prepare_enable(priv->clk_cfg_count, priv->clk_cfg);
if (ret)
dev_err(dev, "failed to enable cfg clock: %d\n", ret);
diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
index a270ae4030cdc..67441b349a7d2 100644
--- a/drivers/gpu/drm/imx/dc/dc-ic.c
+++ b/drivers/gpu/drm/imx/dc/dc-ic.c
@@ -30,7 +30,8 @@
struct dc_ic_data {
struct regmap *regs;
- struct clk *clk_axi;
+ struct clk_bulk_data *clk_axi;
+ int clk_axi_count;
int irq[IRQ_COUNT];
struct irq_domain *domain;
};
@@ -136,10 +137,11 @@ static int dc_ic_probe(struct platform_device *pdev)
if (IS_ERR(data->regs))
return PTR_ERR(data->regs);
- data->clk_axi = devm_clk_get(dev, NULL);
- if (IS_ERR(data->clk_axi))
- return dev_err_probe(dev, PTR_ERR(data->clk_axi),
+ ret = devm_clk_bulk_get_all(dev, &data->clk_axi);
+ if (ret < 0)
+ return dev_err_probe(dev, ret,
"failed to get AXI clock\n");
+ data->clk_axi_count = ret;
for (i = 0; i < IRQ_COUNT; i++) {
/* skip the reserved IRQ */
@@ -242,7 +244,7 @@ static int dc_ic_runtime_suspend(struct device *dev)
{
struct dc_ic_data *data = dev_get_drvdata(dev);
- clk_disable_unprepare(data->clk_axi);
+ clk_bulk_disable_unprepare(data->clk_axi_count, data->clk_axi);
return 0;
}
@@ -252,7 +254,7 @@ static int dc_ic_runtime_resume(struct device *dev)
struct dc_ic_data *data = dev_get_drvdata(dev);
int ret;
- ret = clk_prepare_enable(data->clk_axi);
+ ret = clk_bulk_prepare_enable(data->clk_axi_count, data->clk_axi);
if (ret)
dev_err(dev, "failed to enable AXI clock: %d\n", ret);
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.c b/drivers/gpu/drm/imx/dc/dc-pe.c
index 6676c22f3f458..eb96a6206cc6d 100644
--- a/drivers/gpu/drm/imx/dc/dc-pe.c
+++ b/drivers/gpu/drm/imx/dc/dc-pe.c
@@ -27,10 +27,10 @@ static int dc_pe_bind(struct device *dev, struct device *master, void *data)
if (!pe)
return -ENOMEM;
- pe->clk_axi = devm_clk_get(dev, NULL);
- if (IS_ERR(pe->clk_axi))
- return dev_err_probe(dev, PTR_ERR(pe->clk_axi),
- "failed to get AXI clock\n");
+ ret = devm_clk_bulk_get_all(dev, &pe->clk_axi);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "failed to get AXI clock\n");
+ pe->clk_axi_count = ret;
pe->dev = dev;
@@ -99,7 +99,7 @@ static int dc_pe_runtime_suspend(struct device *dev)
{
struct dc_pe *pe = dev_get_drvdata(dev);
- clk_disable_unprepare(pe->clk_axi);
+ clk_bulk_disable_unprepare(pe->clk_axi_count, pe->clk_axi);
return 0;
}
@@ -109,7 +109,7 @@ static int dc_pe_runtime_resume(struct device *dev)
struct dc_pe *pe = dev_get_drvdata(dev);
int i, ret;
- ret = clk_prepare_enable(pe->clk_axi);
+ ret = clk_bulk_prepare_enable(pe->clk_axi_count, pe->clk_axi);
if (ret) {
dev_err(dev, "failed to enable AXI clock: %d\n", ret);
return ret;
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
index f5e01a6eb9e91..ffeb1c7af1c9f 100644
--- a/drivers/gpu/drm/imx/dc/dc-pe.h
+++ b/drivers/gpu/drm/imx/dc/dc-pe.h
@@ -67,7 +67,8 @@ struct dc_lb {
struct dc_pe {
struct device *dev;
- struct clk *clk_axi;
+ struct clk_bulk_data *clk_axi;
+ int clk_axi_count;
struct dc_cf *cf_safe[DC_DISPLAYS];
struct dc_cf *cf_cont[DC_DISPLAYS];
struct dc_ed *ed_safe[DC_DISPLAYS];
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 04/39] drm/imx: dc: Use bulk clock
2025-10-11 16:51 ` [PATCH 04/39] drm/imx: dc: Use bulk clock Marek Vasut
@ 2025-10-13 16:54 ` Frank Li
2025-10-14 12:02 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 16:54 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:19PM +0200, Marek Vasut wrote:
> Switch to bulk clock operations, as many of the blocks present in DC
s/operations/API
> use multiple clock on i.MX95. The use of bulk clock operations allows
> the driver to seamlessly handle one or multiple clock.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-drv.c | 14 ++++++++------
> drivers/gpu/drm/imx/dc/dc-ic.c | 14 ++++++++------
> drivers/gpu/drm/imx/dc/dc-pe.c | 12 ++++++------
> drivers/gpu/drm/imx/dc/dc-pe.h | 3 ++-
> 4 files changed, 24 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
> index f108964bf89f4..2717c92aba6c5 100644
> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
> @@ -31,7 +31,8 @@
>
> struct dc_priv {
> struct drm_device *drm;
> - struct clk *clk_cfg;
> + struct clk_bulk_data *clk_cfg;
> + int clk_cfg_count;
> };
>
> DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
> @@ -163,10 +164,11 @@ static int dc_probe(struct platform_device *pdev)
> if (!priv)
> return -ENOMEM;
>
> - priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
> - if (IS_ERR(priv->clk_cfg))
> - return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
> + ret = devm_clk_bulk_get_all(&pdev->dev, &priv->clk_cfg);
> + if (ret < 0)
> + return dev_err_probe(&pdev->dev, ret,
> "failed to get cfg clock\n");
> + priv->clk_cfg_count = ret;
>
> dev_set_drvdata(&pdev->dev, priv);
>
> @@ -201,7 +203,7 @@ static int dc_runtime_suspend(struct device *dev)
> {
> struct dc_priv *priv = dev_get_drvdata(dev);
>
> - clk_disable_unprepare(priv->clk_cfg);
> + clk_bulk_disable_unprepare(priv->clk_cfg_count, priv->clk_cfg);
>
> return 0;
> }
> @@ -211,7 +213,7 @@ static int dc_runtime_resume(struct device *dev)
> struct dc_priv *priv = dev_get_drvdata(dev);
> int ret;
>
> - ret = clk_prepare_enable(priv->clk_cfg);
> + ret = clk_bulk_prepare_enable(priv->clk_cfg_count, priv->clk_cfg);
> if (ret)
> dev_err(dev, "failed to enable cfg clock: %d\n", ret);
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
> index a270ae4030cdc..67441b349a7d2 100644
> --- a/drivers/gpu/drm/imx/dc/dc-ic.c
> +++ b/drivers/gpu/drm/imx/dc/dc-ic.c
> @@ -30,7 +30,8 @@
>
> struct dc_ic_data {
> struct regmap *regs;
> - struct clk *clk_axi;
> + struct clk_bulk_data *clk_axi;
I am not sure if "axi' is good name for bulk clks. Maybe use 'clks'. _axi
quite specific to special 'axi' clocks.
Frank
> + int clk_axi_count;
> int irq[IRQ_COUNT];
> struct irq_domain *domain;
> };
> @@ -136,10 +137,11 @@ static int dc_ic_probe(struct platform_device *pdev)
> if (IS_ERR(data->regs))
> return PTR_ERR(data->regs);
>
> - data->clk_axi = devm_clk_get(dev, NULL);
> - if (IS_ERR(data->clk_axi))
> - return dev_err_probe(dev, PTR_ERR(data->clk_axi),
> + ret = devm_clk_bulk_get_all(dev, &data->clk_axi);
> + if (ret < 0)
> + return dev_err_probe(dev, ret,
> "failed to get AXI clock\n");
> + data->clk_axi_count = ret;
>
> for (i = 0; i < IRQ_COUNT; i++) {
> /* skip the reserved IRQ */
> @@ -242,7 +244,7 @@ static int dc_ic_runtime_suspend(struct device *dev)
> {
> struct dc_ic_data *data = dev_get_drvdata(dev);
>
> - clk_disable_unprepare(data->clk_axi);
> + clk_bulk_disable_unprepare(data->clk_axi_count, data->clk_axi);
>
> return 0;
> }
> @@ -252,7 +254,7 @@ static int dc_ic_runtime_resume(struct device *dev)
> struct dc_ic_data *data = dev_get_drvdata(dev);
> int ret;
>
> - ret = clk_prepare_enable(data->clk_axi);
> + ret = clk_bulk_prepare_enable(data->clk_axi_count, data->clk_axi);
> if (ret)
> dev_err(dev, "failed to enable AXI clock: %d\n", ret);
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-pe.c b/drivers/gpu/drm/imx/dc/dc-pe.c
> index 6676c22f3f458..eb96a6206cc6d 100644
> --- a/drivers/gpu/drm/imx/dc/dc-pe.c
> +++ b/drivers/gpu/drm/imx/dc/dc-pe.c
> @@ -27,10 +27,10 @@ static int dc_pe_bind(struct device *dev, struct device *master, void *data)
> if (!pe)
> return -ENOMEM;
>
> - pe->clk_axi = devm_clk_get(dev, NULL);
> - if (IS_ERR(pe->clk_axi))
> - return dev_err_probe(dev, PTR_ERR(pe->clk_axi),
> - "failed to get AXI clock\n");
> + ret = devm_clk_bulk_get_all(dev, &pe->clk_axi);
> + if (ret < 0)
> + return dev_err_probe(dev, ret, "failed to get AXI clock\n");
> + pe->clk_axi_count = ret;
>
> pe->dev = dev;
>
> @@ -99,7 +99,7 @@ static int dc_pe_runtime_suspend(struct device *dev)
> {
> struct dc_pe *pe = dev_get_drvdata(dev);
>
> - clk_disable_unprepare(pe->clk_axi);
> + clk_bulk_disable_unprepare(pe->clk_axi_count, pe->clk_axi);
>
> return 0;
> }
> @@ -109,7 +109,7 @@ static int dc_pe_runtime_resume(struct device *dev)
> struct dc_pe *pe = dev_get_drvdata(dev);
> int i, ret;
>
> - ret = clk_prepare_enable(pe->clk_axi);
> + ret = clk_bulk_prepare_enable(pe->clk_axi_count, pe->clk_axi);
> if (ret) {
> dev_err(dev, "failed to enable AXI clock: %d\n", ret);
> return ret;
> diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
> index f5e01a6eb9e91..ffeb1c7af1c9f 100644
> --- a/drivers/gpu/drm/imx/dc/dc-pe.h
> +++ b/drivers/gpu/drm/imx/dc/dc-pe.h
> @@ -67,7 +67,8 @@ struct dc_lb {
>
> struct dc_pe {
> struct device *dev;
> - struct clk *clk_axi;
> + struct clk_bulk_data *clk_axi;
> + int clk_axi_count;
> struct dc_cf *cf_safe[DC_DISPLAYS];
> struct dc_cf *cf_cont[DC_DISPLAYS];
> struct dc_ed *ed_safe[DC_DISPLAYS];
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 04/39] drm/imx: dc: Use bulk clock
2025-10-13 16:54 ` Frank Li
@ 2025-10-14 12:02 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-14 12:02 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 6:54 PM, Frank Li wrote:
> On Sat, Oct 11, 2025 at 06:51:19PM +0200, Marek Vasut wrote:
>> Switch to bulk clock operations, as many of the blocks present in DC
>
> s/operations/API
>
>> use multiple clock on i.MX95. The use of bulk clock operations allows
>> the driver to seamlessly handle one or multiple clock.
>>
>> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
>> ---
>> Cc: Abel Vesa <abelvesa@kernel.org>
>> Cc: Conor Dooley <conor+dt@kernel.org>
>> Cc: Fabio Estevam <festevam@gmail.com>
>> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
>> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
>> Cc: Liu Ying <victor.liu@nxp.com>
>> Cc: Lucas Stach <l.stach@pengutronix.de>
>> Cc: Peng Fan <peng.fan@nxp.com>
>> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
>> Cc: Rob Herring <robh@kernel.org>
>> Cc: Shawn Guo <shawnguo@kernel.org>
>> Cc: Thomas Zimmermann <tzimmermann@suse.de>
>> Cc: devicetree@vger.kernel.org
>> Cc: dri-devel@lists.freedesktop.org
>> Cc: imx@lists.linux.dev
>> Cc: linux-arm-kernel@lists.infradead.org
>> Cc: linux-clk@vger.kernel.org
>> ---
>> drivers/gpu/drm/imx/dc/dc-drv.c | 14 ++++++++------
>> drivers/gpu/drm/imx/dc/dc-ic.c | 14 ++++++++------
>> drivers/gpu/drm/imx/dc/dc-pe.c | 12 ++++++------
>> drivers/gpu/drm/imx/dc/dc-pe.h | 3 ++-
>> 4 files changed, 24 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
>> index f108964bf89f4..2717c92aba6c5 100644
>> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
>> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
>> @@ -31,7 +31,8 @@
>>
>> struct dc_priv {
>> struct drm_device *drm;
>> - struct clk *clk_cfg;
>> + struct clk_bulk_data *clk_cfg;
>> + int clk_cfg_count;
>> };
>>
>> DEFINE_DRM_GEM_DMA_FOPS(dc_drm_driver_fops);
>> @@ -163,10 +164,11 @@ static int dc_probe(struct platform_device *pdev)
>> if (!priv)
>> return -ENOMEM;
>>
>> - priv->clk_cfg = devm_clk_get(&pdev->dev, NULL);
>> - if (IS_ERR(priv->clk_cfg))
>> - return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cfg),
>> + ret = devm_clk_bulk_get_all(&pdev->dev, &priv->clk_cfg);
>> + if (ret < 0)
>> + return dev_err_probe(&pdev->dev, ret,
>> "failed to get cfg clock\n");
>> + priv->clk_cfg_count = ret;
>>
>> dev_set_drvdata(&pdev->dev, priv);
>>
>> @@ -201,7 +203,7 @@ static int dc_runtime_suspend(struct device *dev)
>> {
>> struct dc_priv *priv = dev_get_drvdata(dev);
>>
>> - clk_disable_unprepare(priv->clk_cfg);
>> + clk_bulk_disable_unprepare(priv->clk_cfg_count, priv->clk_cfg);
>>
>> return 0;
>> }
>> @@ -211,7 +213,7 @@ static int dc_runtime_resume(struct device *dev)
>> struct dc_priv *priv = dev_get_drvdata(dev);
>> int ret;
>>
>> - ret = clk_prepare_enable(priv->clk_cfg);
>> + ret = clk_bulk_prepare_enable(priv->clk_cfg_count, priv->clk_cfg);
>> if (ret)
>> dev_err(dev, "failed to enable cfg clock: %d\n", ret);
>>
>> diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
>> index a270ae4030cdc..67441b349a7d2 100644
>> --- a/drivers/gpu/drm/imx/dc/dc-ic.c
>> +++ b/drivers/gpu/drm/imx/dc/dc-ic.c
>> @@ -30,7 +30,8 @@
>>
>> struct dc_ic_data {
>> struct regmap *regs;
>> - struct clk *clk_axi;
>> + struct clk_bulk_data *clk_axi;
>
> I am not sure if "axi' is good name for bulk clks. Maybe use 'clks'. _axi
> quite specific to special 'axi' clocks.
Fixed both, thanks.
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (3 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 04/39] drm/imx: dc: Use bulk clock Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 16:56 ` Frank Li
2025-10-11 16:51 ` [PATCH 06/39] drm/imx: dc: Rename i.MX8QXP specific Link IDs Marek Vasut
` (35 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Rework dc_subdev_get_id() to drop ARRAY_SIZE() use and use empty trailing
entry in each ID look up array instead. This allows passing of those arrays
around as OF match data, which will be useful when using this pipeline on
i.MX95, which has different address-to-ID mapping.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-cf.c | 3 ++-
drivers/gpu/drm/imx/dc/dc-db.c | 3 ++-
drivers/gpu/drm/imx/dc/dc-de.c | 3 ++-
drivers/gpu/drm/imx/dc/dc-drv.h | 8 +++++---
drivers/gpu/drm/imx/dc/dc-ed.c | 3 ++-
drivers/gpu/drm/imx/dc/dc-fg.c | 3 ++-
drivers/gpu/drm/imx/dc/dc-fl.c | 3 ++-
drivers/gpu/drm/imx/dc/dc-fw.c | 3 ++-
drivers/gpu/drm/imx/dc/dc-lb.c | 3 ++-
drivers/gpu/drm/imx/dc/dc-tc.c | 3 ++-
10 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
index 2f077161e9126..846705534546a 100644
--- a/drivers/gpu/drm/imx/dc/dc-cf.c
+++ b/drivers/gpu/drm/imx/dc/dc-cf.c
@@ -29,6 +29,7 @@ static const struct dc_subdev_info dc_cf_info[] = {
{ .reg_start = 0x561809e0, .id = 1, },
{ .reg_start = 0x561809a0, .id = 4, },
{ .reg_start = 0x56180a20, .id = 5, },
+ { /* sentinel */ },
};
static const struct regmap_range dc_cf_regmap_ranges[] = {
@@ -106,7 +107,7 @@ static int dc_cf_bind(struct device *dev, struct device *master, void *data)
if (IS_ERR(cf->reg_cfg))
return PTR_ERR(cf->reg_cfg);
- id = dc_subdev_get_id(dc_cf_info, ARRAY_SIZE(dc_cf_info), res_pec);
+ id = dc_subdev_get_id(dc_cf_info, res_pec);
if (id < 0) {
dev_err(dev, "failed to get instance number: %d\n", id);
return id;
diff --git a/drivers/gpu/drm/imx/dc/dc-db.c b/drivers/gpu/drm/imx/dc/dc-db.c
index 789942d1c446d..3958a2c4ec934 100644
--- a/drivers/gpu/drm/imx/dc/dc-db.c
+++ b/drivers/gpu/drm/imx/dc/dc-db.c
@@ -74,6 +74,7 @@ enum dc_db_shadow_sel {
static const struct dc_subdev_info dc_db_info[] = {
{ .reg_start = 0x4b6a0000, .id = 0, },
{ .reg_start = 0x4b720000, .id = 1, },
+ { /* sentinel */ },
};
static const struct regmap_range dc_db_regmap_ranges[] = {
@@ -176,7 +177,7 @@ static int dc_db_bind(struct device *dev, struct device *master, void *data)
if (IS_ERR(db->reg_cfg))
return PTR_ERR(db->reg_cfg);
- db->id = dc_subdev_get_id(dc_db_info, ARRAY_SIZE(dc_db_info), res_cfg);
+ db->id = dc_subdev_get_id(dc_db_info, res_cfg);
if (db->id < 0) {
dev_err(dev, "failed to get instance number: %d\n", db->id);
return db->id;
diff --git a/drivers/gpu/drm/imx/dc/dc-de.c b/drivers/gpu/drm/imx/dc/dc-de.c
index 23b0cea68d325..81334c0088219 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.c
+++ b/drivers/gpu/drm/imx/dc/dc-de.c
@@ -21,6 +21,7 @@
static const struct dc_subdev_info dc_de_info[] = {
{ .reg_start = 0x5618b400, .id = 0, },
{ .reg_start = 0x5618b420, .id = 1, },
+ { /* sentinel */ },
};
static const struct regmap_range dc_de_regmap_ranges[] = {
@@ -90,7 +91,7 @@ static int dc_de_bind(struct device *dev, struct device *master, void *data)
if (ret)
return ret;
- id = dc_subdev_get_id(dc_de_info, ARRAY_SIZE(dc_de_info), res_top);
+ id = dc_subdev_get_id(dc_de_info, res_top);
if (id < 0) {
dev_err(dev, "failed to get instance number: %d\n", id);
return id;
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
index 17ce2d748262b..a7ad17680a9b2 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.h
+++ b/drivers/gpu/drm/imx/dc/dc-drv.h
@@ -85,16 +85,18 @@ extern struct platform_driver dc_pe_driver;
extern struct platform_driver dc_tc_driver;
static inline int dc_subdev_get_id(const struct dc_subdev_info *info,
- int info_cnt, struct resource *res)
+ struct resource *res)
{
- int i;
+ int i = 0;
if (!res)
return -EINVAL;
- for (i = 0; i < info_cnt; i++)
+ while (info[i].reg_start) {
if (info[i].reg_start == res->start)
return info[i].id;
+ i++;
+ }
return -EINVAL;
}
diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
index 86ecc22d0a554..a63c387a4c023 100644
--- a/drivers/gpu/drm/imx/dc/dc-ed.c
+++ b/drivers/gpu/drm/imx/dc/dc-ed.c
@@ -40,6 +40,7 @@ static const struct dc_subdev_info dc_ed_info[] = {
{ .reg_start = 0x56180a00, .id = 1, },
{ .reg_start = 0x561809c0, .id = 4, },
{ .reg_start = 0x56180a40, .id = 5, },
+ { /* sentinel */ },
};
static const struct regmap_range dc_ed_pec_regmap_write_ranges[] = {
@@ -226,7 +227,7 @@ static int dc_ed_bind(struct device *dev, struct device *master, void *data)
ed->dev = dev;
- id = dc_subdev_get_id(dc_ed_info, ARRAY_SIZE(dc_ed_info), res_pec);
+ id = dc_subdev_get_id(dc_ed_info, res_pec);
if (id < 0) {
dev_err(dev, "failed to get instance number: %d\n", id);
return id;
diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
index 7f6c1852bf724..5fadd67aa911b 100644
--- a/drivers/gpu/drm/imx/dc/dc-fg.c
+++ b/drivers/gpu/drm/imx/dc/dc-fg.c
@@ -92,6 +92,7 @@ enum dc_fg_dm {
static const struct dc_subdev_info dc_fg_info[] = {
{ .reg_start = 0x5618b800, .id = 0, },
{ .reg_start = 0x5618d400, .id = 1, },
+ { /* sentinel */ },
};
static const struct regmap_range dc_fg_regmap_write_ranges[] = {
@@ -326,7 +327,7 @@ static int dc_fg_bind(struct device *dev, struct device *master, void *data)
return dev_err_probe(dev, PTR_ERR(fg->clk_disp),
"failed to get display clock\n");
- id = dc_subdev_get_id(dc_fg_info, ARRAY_SIZE(dc_fg_info), res);
+ id = dc_subdev_get_id(dc_fg_info, res);
if (id < 0) {
dev_err(dev, "failed to get instance number: %d\n", id);
return id;
diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
index 3ce24c72aa13e..d4e746f8c4297 100644
--- a/drivers/gpu/drm/imx/dc/dc-fl.c
+++ b/drivers/gpu/drm/imx/dc/dc-fl.c
@@ -33,6 +33,7 @@ struct dc_fl {
static const struct dc_subdev_info dc_fl_info[] = {
{ .reg_start = 0x56180ac0, .id = 0, },
+ { /* sentinel */ },
};
static const struct regmap_range dc_fl_regmap_ranges[] = {
@@ -120,7 +121,7 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
if (IS_ERR(fu->reg_cfg))
return PTR_ERR(fu->reg_cfg);
- id = dc_subdev_get_id(dc_fl_info, ARRAY_SIZE(dc_fl_info), res_pec);
+ id = dc_subdev_get_id(dc_fl_info, res_pec);
if (id < 0) {
dev_err(dev, "failed to get instance number: %d\n", id);
return id;
diff --git a/drivers/gpu/drm/imx/dc/dc-fw.c b/drivers/gpu/drm/imx/dc/dc-fw.c
index acb2d4d9e2ecd..c1131b7b17c2f 100644
--- a/drivers/gpu/drm/imx/dc/dc-fw.c
+++ b/drivers/gpu/drm/imx/dc/dc-fw.c
@@ -35,6 +35,7 @@ struct dc_fw {
static const struct dc_subdev_info dc_fw_info[] = {
{ .reg_start = 0x56180a60, .id = 2, },
+ { /* sentinel */ },
};
static const struct regmap_range dc_fw_pec_regmap_access_ranges[] = {
@@ -157,7 +158,7 @@ static int dc_fw_bind(struct device *dev, struct device *master, void *data)
if (IS_ERR(fu->reg_cfg))
return PTR_ERR(fu->reg_cfg);
- id = dc_subdev_get_id(dc_fw_info, ARRAY_SIZE(dc_fw_info), res_pec);
+ id = dc_subdev_get_id(dc_fw_info, res_pec);
if (id < 0) {
dev_err(dev, "failed to get instance number: %d\n", id);
return id;
diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
index 38f966625d382..34ea61c2de87d 100644
--- a/drivers/gpu/drm/imx/dc/dc-lb.c
+++ b/drivers/gpu/drm/imx/dc/dc-lb.c
@@ -76,6 +76,7 @@ static const struct dc_subdev_info dc_lb_info[] = {
{ .reg_start = 0x56180bc0, .id = 1, },
{ .reg_start = 0x56180be0, .id = 2, },
{ .reg_start = 0x56180c00, .id = 3, },
+ { /* sentinel */ },
};
static const struct regmap_range dc_lb_pec_regmap_access_ranges[] = {
@@ -273,7 +274,7 @@ static int dc_lb_bind(struct device *dev, struct device *master, void *data)
if (IS_ERR(lb->reg_cfg))
return PTR_ERR(lb->reg_cfg);
- lb->id = dc_subdev_get_id(dc_lb_info, ARRAY_SIZE(dc_lb_info), res_pec);
+ lb->id = dc_subdev_get_id(dc_lb_info, res_pec);
if (lb->id < 0) {
dev_err(dev, "failed to get instance number: %d\n", lb->id);
return lb->id;
diff --git a/drivers/gpu/drm/imx/dc/dc-tc.c b/drivers/gpu/drm/imx/dc/dc-tc.c
index 0bfd381b2cea1..f44b68c0a5e6d 100644
--- a/drivers/gpu/drm/imx/dc/dc-tc.c
+++ b/drivers/gpu/drm/imx/dc/dc-tc.c
@@ -28,6 +28,7 @@
static const struct dc_subdev_info dc_tc_info[] = {
{ .reg_start = 0x5618c800, .id = 0, },
{ .reg_start = 0x5618e400, .id = 1, },
+ { /* sentinel */ },
};
static const struct regmap_range dc_tc_regmap_ranges[] = {
@@ -91,7 +92,7 @@ static int dc_tc_bind(struct device *dev, struct device *master, void *data)
if (IS_ERR(tc->reg))
return PTR_ERR(tc->reg);
- id = dc_subdev_get_id(dc_tc_info, ARRAY_SIZE(dc_tc_info), res);
+ id = dc_subdev_get_id(dc_tc_info, res);
if (id < 0) {
dev_err(dev, "failed to get instance number: %d\n", id);
return id;
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
2025-10-11 16:51 ` [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use Marek Vasut
@ 2025-10-13 16:56 ` Frank Li
2025-10-14 14:03 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 16:56 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:20PM +0200, Marek Vasut wrote:
> Rework dc_subdev_get_id() to drop ARRAY_SIZE() use and use empty trailing
> entry in each ID look up array instead. This allows passing of those arrays
> around as OF match data, which will be useful when using this pipeline on
> i.MX95, which has different address-to-ID mapping.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
This change is okay. but my questions is why need map register to id.
Frank
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-cf.c | 3 ++-
> drivers/gpu/drm/imx/dc/dc-db.c | 3 ++-
> drivers/gpu/drm/imx/dc/dc-de.c | 3 ++-
> drivers/gpu/drm/imx/dc/dc-drv.h | 8 +++++---
> drivers/gpu/drm/imx/dc/dc-ed.c | 3 ++-
> drivers/gpu/drm/imx/dc/dc-fg.c | 3 ++-
> drivers/gpu/drm/imx/dc/dc-fl.c | 3 ++-
> drivers/gpu/drm/imx/dc/dc-fw.c | 3 ++-
> drivers/gpu/drm/imx/dc/dc-lb.c | 3 ++-
> drivers/gpu/drm/imx/dc/dc-tc.c | 3 ++-
> 10 files changed, 23 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
> index 2f077161e9126..846705534546a 100644
> --- a/drivers/gpu/drm/imx/dc/dc-cf.c
> +++ b/drivers/gpu/drm/imx/dc/dc-cf.c
> @@ -29,6 +29,7 @@ static const struct dc_subdev_info dc_cf_info[] = {
> { .reg_start = 0x561809e0, .id = 1, },
> { .reg_start = 0x561809a0, .id = 4, },
> { .reg_start = 0x56180a20, .id = 5, },
> + { /* sentinel */ },
> };
>
> static const struct regmap_range dc_cf_regmap_ranges[] = {
> @@ -106,7 +107,7 @@ static int dc_cf_bind(struct device *dev, struct device *master, void *data)
> if (IS_ERR(cf->reg_cfg))
> return PTR_ERR(cf->reg_cfg);
>
> - id = dc_subdev_get_id(dc_cf_info, ARRAY_SIZE(dc_cf_info), res_pec);
> + id = dc_subdev_get_id(dc_cf_info, res_pec);
> if (id < 0) {
> dev_err(dev, "failed to get instance number: %d\n", id);
> return id;
> diff --git a/drivers/gpu/drm/imx/dc/dc-db.c b/drivers/gpu/drm/imx/dc/dc-db.c
> index 789942d1c446d..3958a2c4ec934 100644
> --- a/drivers/gpu/drm/imx/dc/dc-db.c
> +++ b/drivers/gpu/drm/imx/dc/dc-db.c
> @@ -74,6 +74,7 @@ enum dc_db_shadow_sel {
> static const struct dc_subdev_info dc_db_info[] = {
> { .reg_start = 0x4b6a0000, .id = 0, },
> { .reg_start = 0x4b720000, .id = 1, },
> + { /* sentinel */ },
> };
>
> static const struct regmap_range dc_db_regmap_ranges[] = {
> @@ -176,7 +177,7 @@ static int dc_db_bind(struct device *dev, struct device *master, void *data)
> if (IS_ERR(db->reg_cfg))
> return PTR_ERR(db->reg_cfg);
>
> - db->id = dc_subdev_get_id(dc_db_info, ARRAY_SIZE(dc_db_info), res_cfg);
> + db->id = dc_subdev_get_id(dc_db_info, res_cfg);
> if (db->id < 0) {
> dev_err(dev, "failed to get instance number: %d\n", db->id);
> return db->id;
> diff --git a/drivers/gpu/drm/imx/dc/dc-de.c b/drivers/gpu/drm/imx/dc/dc-de.c
> index 23b0cea68d325..81334c0088219 100644
> --- a/drivers/gpu/drm/imx/dc/dc-de.c
> +++ b/drivers/gpu/drm/imx/dc/dc-de.c
> @@ -21,6 +21,7 @@
> static const struct dc_subdev_info dc_de_info[] = {
> { .reg_start = 0x5618b400, .id = 0, },
> { .reg_start = 0x5618b420, .id = 1, },
> + { /* sentinel */ },
> };
>
> static const struct regmap_range dc_de_regmap_ranges[] = {
> @@ -90,7 +91,7 @@ static int dc_de_bind(struct device *dev, struct device *master, void *data)
> if (ret)
> return ret;
>
> - id = dc_subdev_get_id(dc_de_info, ARRAY_SIZE(dc_de_info), res_top);
> + id = dc_subdev_get_id(dc_de_info, res_top);
> if (id < 0) {
> dev_err(dev, "failed to get instance number: %d\n", id);
> return id;
> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.h b/drivers/gpu/drm/imx/dc/dc-drv.h
> index 17ce2d748262b..a7ad17680a9b2 100644
> --- a/drivers/gpu/drm/imx/dc/dc-drv.h
> +++ b/drivers/gpu/drm/imx/dc/dc-drv.h
> @@ -85,16 +85,18 @@ extern struct platform_driver dc_pe_driver;
> extern struct platform_driver dc_tc_driver;
>
> static inline int dc_subdev_get_id(const struct dc_subdev_info *info,
> - int info_cnt, struct resource *res)
> + struct resource *res)
> {
> - int i;
> + int i = 0;
>
> if (!res)
> return -EINVAL;
>
> - for (i = 0; i < info_cnt; i++)
> + while (info[i].reg_start) {
> if (info[i].reg_start == res->start)
> return info[i].id;
> + i++;
> + }
>
> return -EINVAL;
> }
> diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
> index 86ecc22d0a554..a63c387a4c023 100644
> --- a/drivers/gpu/drm/imx/dc/dc-ed.c
> +++ b/drivers/gpu/drm/imx/dc/dc-ed.c
> @@ -40,6 +40,7 @@ static const struct dc_subdev_info dc_ed_info[] = {
> { .reg_start = 0x56180a00, .id = 1, },
> { .reg_start = 0x561809c0, .id = 4, },
> { .reg_start = 0x56180a40, .id = 5, },
> + { /* sentinel */ },
> };
>
> static const struct regmap_range dc_ed_pec_regmap_write_ranges[] = {
> @@ -226,7 +227,7 @@ static int dc_ed_bind(struct device *dev, struct device *master, void *data)
>
> ed->dev = dev;
>
> - id = dc_subdev_get_id(dc_ed_info, ARRAY_SIZE(dc_ed_info), res_pec);
> + id = dc_subdev_get_id(dc_ed_info, res_pec);
> if (id < 0) {
> dev_err(dev, "failed to get instance number: %d\n", id);
> return id;
> diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
> index 7f6c1852bf724..5fadd67aa911b 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fg.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fg.c
> @@ -92,6 +92,7 @@ enum dc_fg_dm {
> static const struct dc_subdev_info dc_fg_info[] = {
> { .reg_start = 0x5618b800, .id = 0, },
> { .reg_start = 0x5618d400, .id = 1, },
> + { /* sentinel */ },
> };
>
> static const struct regmap_range dc_fg_regmap_write_ranges[] = {
> @@ -326,7 +327,7 @@ static int dc_fg_bind(struct device *dev, struct device *master, void *data)
> return dev_err_probe(dev, PTR_ERR(fg->clk_disp),
> "failed to get display clock\n");
>
> - id = dc_subdev_get_id(dc_fg_info, ARRAY_SIZE(dc_fg_info), res);
> + id = dc_subdev_get_id(dc_fg_info, res);
> if (id < 0) {
> dev_err(dev, "failed to get instance number: %d\n", id);
> return id;
> diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
> index 3ce24c72aa13e..d4e746f8c4297 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fl.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fl.c
> @@ -33,6 +33,7 @@ struct dc_fl {
>
> static const struct dc_subdev_info dc_fl_info[] = {
> { .reg_start = 0x56180ac0, .id = 0, },
> + { /* sentinel */ },
> };
>
> static const struct regmap_range dc_fl_regmap_ranges[] = {
> @@ -120,7 +121,7 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
> if (IS_ERR(fu->reg_cfg))
> return PTR_ERR(fu->reg_cfg);
>
> - id = dc_subdev_get_id(dc_fl_info, ARRAY_SIZE(dc_fl_info), res_pec);
> + id = dc_subdev_get_id(dc_fl_info, res_pec);
> if (id < 0) {
> dev_err(dev, "failed to get instance number: %d\n", id);
> return id;
> diff --git a/drivers/gpu/drm/imx/dc/dc-fw.c b/drivers/gpu/drm/imx/dc/dc-fw.c
> index acb2d4d9e2ecd..c1131b7b17c2f 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fw.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fw.c
> @@ -35,6 +35,7 @@ struct dc_fw {
>
> static const struct dc_subdev_info dc_fw_info[] = {
> { .reg_start = 0x56180a60, .id = 2, },
> + { /* sentinel */ },
> };
>
> static const struct regmap_range dc_fw_pec_regmap_access_ranges[] = {
> @@ -157,7 +158,7 @@ static int dc_fw_bind(struct device *dev, struct device *master, void *data)
> if (IS_ERR(fu->reg_cfg))
> return PTR_ERR(fu->reg_cfg);
>
> - id = dc_subdev_get_id(dc_fw_info, ARRAY_SIZE(dc_fw_info), res_pec);
> + id = dc_subdev_get_id(dc_fw_info, res_pec);
> if (id < 0) {
> dev_err(dev, "failed to get instance number: %d\n", id);
> return id;
> diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
> index 38f966625d382..34ea61c2de87d 100644
> --- a/drivers/gpu/drm/imx/dc/dc-lb.c
> +++ b/drivers/gpu/drm/imx/dc/dc-lb.c
> @@ -76,6 +76,7 @@ static const struct dc_subdev_info dc_lb_info[] = {
> { .reg_start = 0x56180bc0, .id = 1, },
> { .reg_start = 0x56180be0, .id = 2, },
> { .reg_start = 0x56180c00, .id = 3, },
> + { /* sentinel */ },
> };
>
> static const struct regmap_range dc_lb_pec_regmap_access_ranges[] = {
> @@ -273,7 +274,7 @@ static int dc_lb_bind(struct device *dev, struct device *master, void *data)
> if (IS_ERR(lb->reg_cfg))
> return PTR_ERR(lb->reg_cfg);
>
> - lb->id = dc_subdev_get_id(dc_lb_info, ARRAY_SIZE(dc_lb_info), res_pec);
> + lb->id = dc_subdev_get_id(dc_lb_info, res_pec);
> if (lb->id < 0) {
> dev_err(dev, "failed to get instance number: %d\n", lb->id);
> return lb->id;
> diff --git a/drivers/gpu/drm/imx/dc/dc-tc.c b/drivers/gpu/drm/imx/dc/dc-tc.c
> index 0bfd381b2cea1..f44b68c0a5e6d 100644
> --- a/drivers/gpu/drm/imx/dc/dc-tc.c
> +++ b/drivers/gpu/drm/imx/dc/dc-tc.c
> @@ -28,6 +28,7 @@
> static const struct dc_subdev_info dc_tc_info[] = {
> { .reg_start = 0x5618c800, .id = 0, },
> { .reg_start = 0x5618e400, .id = 1, },
> + { /* sentinel */ },
> };
>
> static const struct regmap_range dc_tc_regmap_ranges[] = {
> @@ -91,7 +92,7 @@ static int dc_tc_bind(struct device *dev, struct device *master, void *data)
> if (IS_ERR(tc->reg))
> return PTR_ERR(tc->reg);
>
> - id = dc_subdev_get_id(dc_tc_info, ARRAY_SIZE(dc_tc_info), res);
> + id = dc_subdev_get_id(dc_tc_info, res);
> if (id < 0) {
> dev_err(dev, "failed to get instance number: %d\n", id);
> return id;
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
2025-10-13 16:56 ` Frank Li
@ 2025-10-14 14:03 ` Marek Vasut
2025-10-14 15:11 ` Frank Li
0 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-14 14:03 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 6:56 PM, Frank Li wrote:
> On Sat, Oct 11, 2025 at 06:51:20PM +0200, Marek Vasut wrote:
>> Rework dc_subdev_get_id() to drop ARRAY_SIZE() use and use empty trailing
>> entry in each ID look up array instead. This allows passing of those arrays
>> around as OF match data, which will be useful when using this pipeline on
>> i.MX95, which has different address-to-ID mapping.
>>
>> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
>
> This change is okay. but my questions is why need map register to id.
This seems to be a recurring pattern in the driver, where some
components need to find other components to link with them. The mapping
is fixed, and since the DT does not encode link IDs, the resolution of
the mapping has to happen by mapping the component base addresses to the
IDs first.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
2025-10-14 14:03 ` Marek Vasut
@ 2025-10-14 15:11 ` Frank Li
2025-10-14 21:11 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-14 15:11 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Tue, Oct 14, 2025 at 04:03:37PM +0200, Marek Vasut wrote:
> On 10/13/25 6:56 PM, Frank Li wrote:
> > On Sat, Oct 11, 2025 at 06:51:20PM +0200, Marek Vasut wrote:
> > > Rework dc_subdev_get_id() to drop ARRAY_SIZE() use and use empty trailing
> > > entry in each ID look up array instead. This allows passing of those arrays
> > > around as OF match data, which will be useful when using this pipeline on
> > > i.MX95, which has different address-to-ID mapping.
> > >
> > > Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> >
> > This change is okay. but my questions is why need map register to id.
>
> This seems to be a recurring pattern in the driver, where some components
> need to find other components to link with them. The mapping is fixed, and
> since the DT does not encode link IDs, the resolution of the mapping has to
> happen by mapping the component base addresses to the IDs first.
In graphic link, port@<n>, n should be id? why not use it?
Frank
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
2025-10-14 15:11 ` Frank Li
@ 2025-10-14 21:11 ` Marek Vasut
2025-10-15 9:14 ` Liu Ying
0 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-14 21:11 UTC (permalink / raw)
To: Frank Li, Liu Ying
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/14/25 5:11 PM, Frank Li wrote:
> On Tue, Oct 14, 2025 at 04:03:37PM +0200, Marek Vasut wrote:
>> On 10/13/25 6:56 PM, Frank Li wrote:
>>> On Sat, Oct 11, 2025 at 06:51:20PM +0200, Marek Vasut wrote:
>>>> Rework dc_subdev_get_id() to drop ARRAY_SIZE() use and use empty trailing
>>>> entry in each ID look up array instead. This allows passing of those arrays
>>>> around as OF match data, which will be useful when using this pipeline on
>>>> i.MX95, which has different address-to-ID mapping.
>>>>
>>>> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
>>>
>>> This change is okay. but my questions is why need map register to id.
>>
>> This seems to be a recurring pattern in the driver, where some components
>> need to find other components to link with them. The mapping is fixed, and
>> since the DT does not encode link IDs, the resolution of the mapping has to
>> happen by mapping the component base addresses to the IDs first.
>
> In graphic link, port@<n>, n should be id? why not use it?
I suspect you could model the relationships between the DC blocks using
OF graph, yes. I also suspect that description would be very complex in
DT, considering the amount of blocks and links this device contains. I
suspect this is why there is no such DT description using OF graph.
I think it might also be good to talk to Liu directly about the original
design decision and why this id mapping was done the way it was done,
they should know better than me.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
2025-10-14 21:11 ` Marek Vasut
@ 2025-10-15 9:14 ` Liu Ying
2025-10-15 14:31 ` Frank Li
0 siblings, 1 reply; 113+ messages in thread
From: Liu Ying @ 2025-10-15 9:14 UTC (permalink / raw)
To: Marek Vasut, Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/14/2025, Marek Vasut wrote:
> On 10/14/25 5:11 PM, Frank Li wrote:
>> On Tue, Oct 14, 2025 at 04:03:37PM +0200, Marek Vasut wrote:
>>> On 10/13/25 6:56 PM, Frank Li wrote:
>>>> On Sat, Oct 11, 2025 at 06:51:20PM +0200, Marek Vasut wrote:
>>>>> Rework dc_subdev_get_id() to drop ARRAY_SIZE() use and use empty trailing
>>>>> entry in each ID look up array instead. This allows passing of those arrays
>>>>> around as OF match data, which will be useful when using this pipeline on
>>>>> i.MX95, which has different address-to-ID mapping.
>>>>>
>>>>> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
>>>>
>>>> This change is okay. but my questions is why need map register to id.
>>>
>>> This seems to be a recurring pattern in the driver, where some components
>>> need to find other components to link with them. The mapping is fixed, and
>>> since the DT does not encode link IDs, the resolution of the mapping has to
>>> happen by mapping the component base addresses to the IDs first.
>>
>> In graphic link, port@<n>, n should be id? why not use it?
> I suspect you could model the relationships between the DC blocks using OF
> graph, yes. I also suspect that description would be very complex in
> DT, considering the amount of blocks and links this device contains. I
> suspect this is why there is no such DT description using OF graph.
Yes. The design decision was made to avoid using OF graph to describe
links between DC blocks due to the complexity.
>
> I think it might also be good to talk to Liu directly about the original design
> decision and why this id mapping was done the way it was done,
> they should know better than me.
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
2025-10-15 9:14 ` Liu Ying
@ 2025-10-15 14:31 ` Frank Li
2025-10-16 2:50 ` Liu Ying
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-15 14:31 UTC (permalink / raw)
To: Liu Ying
Cc: Marek Vasut, dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Wed, Oct 15, 2025 at 05:14:02PM +0800, Liu Ying wrote:
> On 10/14/2025, Marek Vasut wrote:
> > On 10/14/25 5:11 PM, Frank Li wrote:
> >> On Tue, Oct 14, 2025 at 04:03:37PM +0200, Marek Vasut wrote:
> >>> On 10/13/25 6:56 PM, Frank Li wrote:
> >>>> On Sat, Oct 11, 2025 at 06:51:20PM +0200, Marek Vasut wrote:
> >>>>> Rework dc_subdev_get_id() to drop ARRAY_SIZE() use and use empty trailing
> >>>>> entry in each ID look up array instead. This allows passing of those arrays
> >>>>> around as OF match data, which will be useful when using this pipeline on
> >>>>> i.MX95, which has different address-to-ID mapping.
> >>>>>
> >>>>> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> >>>>
> >>>> This change is okay. but my questions is why need map register to id.
> >>>
> >>> This seems to be a recurring pattern in the driver, where some components
> >>> need to find other components to link with them. The mapping is fixed, and
> >>> since the DT does not encode link IDs, the resolution of the mapping has to
> >>> happen by mapping the component base addresses to the IDs first.
> >>
> >> In graphic link, port@<n>, n should be id? why not use it?
> > I suspect you could model the relationships between the DC blocks using OF
> > graph, yes. I also suspect that description would be very complex in
> > DT, considering the amount of blocks and links this device contains. I
> > suspect this is why there is no such DT description using OF graph.
>
> Yes. The design decision was made to avoid using OF graph to describe
> links between DC blocks due to the complexity.
Any previous discuission? Using registers base address to determiate ID
is not solution.
Frank
>
> >
> > I think it might also be good to talk to Liu directly about the original design
> > decision and why this id mapping was done the way it was done,
> > they should know better than me.
>
>
> --
> Regards,
> Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
2025-10-15 14:31 ` Frank Li
@ 2025-10-16 2:50 ` Liu Ying
0 siblings, 0 replies; 113+ messages in thread
From: Liu Ying @ 2025-10-16 2:50 UTC (permalink / raw)
To: Frank Li
Cc: Marek Vasut, dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/15/2025, Frank Li wrote:
> On Wed, Oct 15, 2025 at 05:14:02PM +0800, Liu Ying wrote:
>> On 10/14/2025, Marek Vasut wrote:
>>> On 10/14/25 5:11 PM, Frank Li wrote:
>>>> On Tue, Oct 14, 2025 at 04:03:37PM +0200, Marek Vasut wrote:
>>>>> On 10/13/25 6:56 PM, Frank Li wrote:
>>>>>> On Sat, Oct 11, 2025 at 06:51:20PM +0200, Marek Vasut wrote:
>>>>>>> Rework dc_subdev_get_id() to drop ARRAY_SIZE() use and use empty trailing
>>>>>>> entry in each ID look up array instead. This allows passing of those arrays
>>>>>>> around as OF match data, which will be useful when using this pipeline on
>>>>>>> i.MX95, which has different address-to-ID mapping.
>>>>>>>
>>>>>>> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
>>>>>>
>>>>>> This change is okay. but my questions is why need map register to id.
>>>>>
>>>>> This seems to be a recurring pattern in the driver, where some components
>>>>> need to find other components to link with them. The mapping is fixed, and
>>>>> since the DT does not encode link IDs, the resolution of the mapping has to
>>>>> happen by mapping the component base addresses to the IDs first.
>>>>
>>>> In graphic link, port@<n>, n should be id? why not use it?
>>> I suspect you could model the relationships between the DC blocks using OF
>>> graph, yes. I also suspect that description would be very complex in
>>> DT, considering the amount of blocks and links this device contains. I
>>> suspect this is why there is no such DT description using OF graph.
>>
>> Yes. The design decision was made to avoid using OF graph to describe
>> links between DC blocks due to the complexity.
>
> Any previous discuission? Using registers base address to determiate ID
Yes, you may find the discussion in
https://patchwork.freedesktop.org/series/135786/
> is not solution.
Well it is, based on the discussion. And it's also used by MSM DPU,
see drivers/gpu/drm/msm/disp/dpu1/catalog/*.h, though IIRC someone said
it's not the best solution for MSM DPU.
>
> Frank
>
>>
>>>
>>> I think it might also be good to talk to Liu directly about the original design
>>> decision and why this id mapping was done the way it was done,
>>> they should know better than me.
>>
>>
>> --
>> Regards,
>> Liu Ying
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 06/39] drm/imx: dc: Rename i.MX8QXP specific Link IDs
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (4 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 05/39] drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 16:58 ` Frank Li
2025-10-11 16:51 ` [PATCH 07/39] drm/imx: dc: cf: Pass struct dc_subdev_info via OF match data Marek Vasut
` (34 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Add _IMX8QXP suffix to Link IDs which are specific to the i.MX8QXP SoC.
This is an i.MX95 support preparatory patch. No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-cf.c | 4 ++--
drivers/gpu/drm/imx/dc/dc-ed.c | 12 ++++++------
drivers/gpu/drm/imx/dc/dc-lb.c | 14 +++++++-------
drivers/gpu/drm/imx/dc/dc-pe.h | 22 +++++++++++-----------
4 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
index 846705534546a..6cb83182a3668 100644
--- a/drivers/gpu/drm/imx/dc/dc-cf.c
+++ b/drivers/gpu/drm/imx/dc/dc-cf.c
@@ -123,11 +123,11 @@ static int dc_cf_bind(struct device *dev, struct device *master, void *data)
dc_drm->cf_cont[1] = cf;
break;
case 4:
- cf->link = LINK_ID_CONSTFRAME4;
+ cf->link = LINK_ID_CONSTFRAME4_MX8QXP;
dc_drm->cf_safe[0] = cf;
break;
case 5:
- cf->link = LINK_ID_CONSTFRAME5;
+ cf->link = LINK_ID_CONSTFRAME5_MX8QXP;
dc_drm->cf_safe[1] = cf;
break;
}
diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
index a63c387a4c023..9a141c6aa0812 100644
--- a/drivers/gpu/drm/imx/dc/dc-ed.c
+++ b/drivers/gpu/drm/imx/dc/dc-ed.c
@@ -110,12 +110,12 @@ static const enum dc_link_id src_sels[] = {
LINK_ID_NONE,
LINK_ID_CONSTFRAME0,
LINK_ID_CONSTFRAME1,
- LINK_ID_CONSTFRAME4,
- LINK_ID_CONSTFRAME5,
- LINK_ID_LAYERBLEND3,
- LINK_ID_LAYERBLEND2,
- LINK_ID_LAYERBLEND1,
- LINK_ID_LAYERBLEND0,
+ LINK_ID_CONSTFRAME4_MX8QXP,
+ LINK_ID_CONSTFRAME5_MX8QXP,
+ LINK_ID_LAYERBLEND3_MX8QXP,
+ LINK_ID_LAYERBLEND2_MX8QXP,
+ LINK_ID_LAYERBLEND1_MX8QXP,
+ LINK_ID_LAYERBLEND0_MX8QXP,
};
static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
index 34ea61c2de87d..619353456743c 100644
--- a/drivers/gpu/drm/imx/dc/dc-lb.c
+++ b/drivers/gpu/drm/imx/dc/dc-lb.c
@@ -124,8 +124,8 @@ static const enum dc_link_id prim_sels[] = {
LINK_ID_NONE,
LINK_ID_CONSTFRAME0,
LINK_ID_CONSTFRAME1,
- LINK_ID_CONSTFRAME4,
- LINK_ID_CONSTFRAME5,
+ LINK_ID_CONSTFRAME4_MX8QXP,
+ LINK_ID_CONSTFRAME5_MX8QXP,
/*
* special options:
* layerblend(n) has n special options,
@@ -133,10 +133,10 @@ static const enum dc_link_id prim_sels[] = {
* layerblend3 has 3 special options -
* layerblend0/1/2.
*/
- LINK_ID_LAYERBLEND0,
- LINK_ID_LAYERBLEND1,
- LINK_ID_LAYERBLEND2,
- LINK_ID_LAYERBLEND3,
+ LINK_ID_LAYERBLEND0_MX8QXP,
+ LINK_ID_LAYERBLEND1_MX8QXP,
+ LINK_ID_LAYERBLEND2_MX8QXP,
+ LINK_ID_LAYERBLEND3_MX8QXP,
};
static const enum dc_link_id sec_sels[] = {
@@ -281,7 +281,7 @@ static int dc_lb_bind(struct device *dev, struct device *master, void *data)
}
lb->dev = dev;
- lb->link = LINK_ID_LAYERBLEND0 + lb->id;
+ lb->link = LINK_ID_LAYERBLEND0_MX8QXP + lb->id;
dc_drm->lb[lb->id] = lb;
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
index ffeb1c7af1c9f..866859403a79d 100644
--- a/drivers/gpu/drm/imx/dc/dc-pe.h
+++ b/drivers/gpu/drm/imx/dc/dc-pe.h
@@ -22,17 +22,17 @@
#define DC_LB_CNT 4
enum dc_link_id {
- LINK_ID_NONE = 0x00,
- LINK_ID_CONSTFRAME0 = 0x0c,
- LINK_ID_CONSTFRAME4 = 0x0e,
- LINK_ID_CONSTFRAME1 = 0x10,
- LINK_ID_CONSTFRAME5 = 0x12,
- LINK_ID_FETCHWARP2 = 0x14,
- LINK_ID_FETCHLAYER0 = 0x1a,
- LINK_ID_LAYERBLEND0 = 0x21,
- LINK_ID_LAYERBLEND1 = 0x22,
- LINK_ID_LAYERBLEND2 = 0x23,
- LINK_ID_LAYERBLEND3 = 0x24,
+ LINK_ID_NONE = 0x00,
+ LINK_ID_CONSTFRAME0 = 0x0c,
+ LINK_ID_CONSTFRAME4_MX8QXP = 0x0e,
+ LINK_ID_CONSTFRAME1 = 0x10,
+ LINK_ID_CONSTFRAME5_MX8QXP = 0x12,
+ LINK_ID_FETCHWARP2 = 0x14,
+ LINK_ID_FETCHLAYER0 = 0x1a,
+ LINK_ID_LAYERBLEND0_MX8QXP = 0x21,
+ LINK_ID_LAYERBLEND1_MX8QXP = 0x22,
+ LINK_ID_LAYERBLEND2_MX8QXP = 0x23,
+ LINK_ID_LAYERBLEND3_MX8QXP = 0x24,
};
enum dc_lb_mode {
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 06/39] drm/imx: dc: Rename i.MX8QXP specific Link IDs
2025-10-11 16:51 ` [PATCH 06/39] drm/imx: dc: Rename i.MX8QXP specific Link IDs Marek Vasut
@ 2025-10-13 16:58 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 16:58 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:21PM +0200, Marek Vasut wrote:
> Add _IMX8QXP suffix to Link IDs which are specific to the i.MX8QXP SoC.
> This is an i.MX95 support preparatory patch. No functional change.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-cf.c | 4 ++--
> drivers/gpu/drm/imx/dc/dc-ed.c | 12 ++++++------
> drivers/gpu/drm/imx/dc/dc-lb.c | 14 +++++++-------
> drivers/gpu/drm/imx/dc/dc-pe.h | 22 +++++++++++-----------
> 4 files changed, 26 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
> index 846705534546a..6cb83182a3668 100644
> --- a/drivers/gpu/drm/imx/dc/dc-cf.c
> +++ b/drivers/gpu/drm/imx/dc/dc-cf.c
> @@ -123,11 +123,11 @@ static int dc_cf_bind(struct device *dev, struct device *master, void *data)
> dc_drm->cf_cont[1] = cf;
> break;
> case 4:
> - cf->link = LINK_ID_CONSTFRAME4;
> + cf->link = LINK_ID_CONSTFRAME4_MX8QXP;
> dc_drm->cf_safe[0] = cf;
> break;
> case 5:
> - cf->link = LINK_ID_CONSTFRAME5;
> + cf->link = LINK_ID_CONSTFRAME5_MX8QXP;
> dc_drm->cf_safe[1] = cf;
> break;
> }
> diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
> index a63c387a4c023..9a141c6aa0812 100644
> --- a/drivers/gpu/drm/imx/dc/dc-ed.c
> +++ b/drivers/gpu/drm/imx/dc/dc-ed.c
> @@ -110,12 +110,12 @@ static const enum dc_link_id src_sels[] = {
> LINK_ID_NONE,
> LINK_ID_CONSTFRAME0,
> LINK_ID_CONSTFRAME1,
> - LINK_ID_CONSTFRAME4,
> - LINK_ID_CONSTFRAME5,
> - LINK_ID_LAYERBLEND3,
> - LINK_ID_LAYERBLEND2,
> - LINK_ID_LAYERBLEND1,
> - LINK_ID_LAYERBLEND0,
> + LINK_ID_CONSTFRAME4_MX8QXP,
> + LINK_ID_CONSTFRAME5_MX8QXP,
> + LINK_ID_LAYERBLEND3_MX8QXP,
> + LINK_ID_LAYERBLEND2_MX8QXP,
> + LINK_ID_LAYERBLEND1_MX8QXP,
> + LINK_ID_LAYERBLEND0_MX8QXP,
> };
>
> static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
> diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
> index 34ea61c2de87d..619353456743c 100644
> --- a/drivers/gpu/drm/imx/dc/dc-lb.c
> +++ b/drivers/gpu/drm/imx/dc/dc-lb.c
> @@ -124,8 +124,8 @@ static const enum dc_link_id prim_sels[] = {
> LINK_ID_NONE,
> LINK_ID_CONSTFRAME0,
> LINK_ID_CONSTFRAME1,
> - LINK_ID_CONSTFRAME4,
> - LINK_ID_CONSTFRAME5,
> + LINK_ID_CONSTFRAME4_MX8QXP,
> + LINK_ID_CONSTFRAME5_MX8QXP,
> /*
> * special options:
> * layerblend(n) has n special options,
> @@ -133,10 +133,10 @@ static const enum dc_link_id prim_sels[] = {
> * layerblend3 has 3 special options -
> * layerblend0/1/2.
> */
> - LINK_ID_LAYERBLEND0,
> - LINK_ID_LAYERBLEND1,
> - LINK_ID_LAYERBLEND2,
> - LINK_ID_LAYERBLEND3,
> + LINK_ID_LAYERBLEND0_MX8QXP,
> + LINK_ID_LAYERBLEND1_MX8QXP,
> + LINK_ID_LAYERBLEND2_MX8QXP,
> + LINK_ID_LAYERBLEND3_MX8QXP,
> };
>
> static const enum dc_link_id sec_sels[] = {
> @@ -281,7 +281,7 @@ static int dc_lb_bind(struct device *dev, struct device *master, void *data)
> }
>
> lb->dev = dev;
> - lb->link = LINK_ID_LAYERBLEND0 + lb->id;
> + lb->link = LINK_ID_LAYERBLEND0_MX8QXP + lb->id;
>
> dc_drm->lb[lb->id] = lb;
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
> index ffeb1c7af1c9f..866859403a79d 100644
> --- a/drivers/gpu/drm/imx/dc/dc-pe.h
> +++ b/drivers/gpu/drm/imx/dc/dc-pe.h
> @@ -22,17 +22,17 @@
> #define DC_LB_CNT 4
>
> enum dc_link_id {
> - LINK_ID_NONE = 0x00,
> - LINK_ID_CONSTFRAME0 = 0x0c,
> - LINK_ID_CONSTFRAME4 = 0x0e,
> - LINK_ID_CONSTFRAME1 = 0x10,
> - LINK_ID_CONSTFRAME5 = 0x12,
> - LINK_ID_FETCHWARP2 = 0x14,
> - LINK_ID_FETCHLAYER0 = 0x1a,
> - LINK_ID_LAYERBLEND0 = 0x21,
> - LINK_ID_LAYERBLEND1 = 0x22,
> - LINK_ID_LAYERBLEND2 = 0x23,
> - LINK_ID_LAYERBLEND3 = 0x24,
> + LINK_ID_NONE = 0x00,
> + LINK_ID_CONSTFRAME0 = 0x0c,
> + LINK_ID_CONSTFRAME4_MX8QXP = 0x0e,
> + LINK_ID_CONSTFRAME1 = 0x10,
> + LINK_ID_CONSTFRAME5_MX8QXP = 0x12,
> + LINK_ID_FETCHWARP2 = 0x14,
> + LINK_ID_FETCHLAYER0 = 0x1a,
> + LINK_ID_LAYERBLEND0_MX8QXP = 0x21,
> + LINK_ID_LAYERBLEND1_MX8QXP = 0x22,
> + LINK_ID_LAYERBLEND2_MX8QXP = 0x23,
> + LINK_ID_LAYERBLEND3_MX8QXP = 0x24,
> };
>
> enum dc_lb_mode {
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 07/39] drm/imx: dc: cf: Pass struct dc_subdev_info via OF match data
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (5 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 06/39] drm/imx: dc: Rename i.MX8QXP specific Link IDs Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 17:01 ` Frank Li
2025-10-11 16:51 ` [PATCH 08/39] drm/imx: dc: de: Pass struct dc_de_subdev_match_data " Marek Vasut
` (33 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Pass the struct dc_subdev_info as OF match data into the driver,
so the driver can use the match data to correct map addresses to
IDs. This is a preparatory patch for i.MX95 addition. No functional
change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-cf.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
index 6cb83182a3668..1d3602c5d4230 100644
--- a/drivers/gpu/drm/imx/dc/dc-cf.c
+++ b/drivers/gpu/drm/imx/dc/dc-cf.c
@@ -10,6 +10,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include "dc-drv.h"
@@ -24,7 +25,13 @@
#define CONSTANTCOLOR 0x10
#define BLUE(x) FIELD_PREP(GENMASK(15, 8), (x))
-static const struct dc_subdev_info dc_cf_info[] = {
+struct dc_cf_subdev_match_data {
+ enum dc_link_id link_cf4;
+ enum dc_link_id link_cf5;
+ const struct dc_subdev_info *info;
+};
+
+static const struct dc_subdev_info dc_cf_info_imx8qxp[] = {
{ .reg_start = 0x56180960, .id = 0, },
{ .reg_start = 0x561809e0, .id = 1, },
{ .reg_start = 0x561809a0, .id = 4, },
@@ -32,6 +39,12 @@ static const struct dc_subdev_info dc_cf_info[] = {
{ /* sentinel */ },
};
+static const struct dc_cf_subdev_match_data dc_cf_match_data_imx8qxp = {
+ .link_cf4 = LINK_ID_CONSTFRAME4_MX8QXP,
+ .link_cf5 = LINK_ID_CONSTFRAME5_MX8QXP,
+ .info = dc_cf_info_imx8qxp,
+};
+
static const struct regmap_range dc_cf_regmap_ranges[] = {
regmap_reg_range(STATICCONTROL, CONSTANTCOLOR),
};
@@ -85,6 +98,8 @@ void dc_cf_init(struct dc_cf *cf)
static int dc_cf_bind(struct device *dev, struct device *master, void *data)
{
+ const struct dc_cf_subdev_match_data *dc_cf_match_data = device_get_match_data(dev);
+ const struct dc_subdev_info *dc_cf_info = dc_cf_match_data->info;
struct platform_device *pdev = to_platform_device(dev);
struct dc_drm_device *dc_drm = data;
struct resource *res_pec;
@@ -123,11 +138,11 @@ static int dc_cf_bind(struct device *dev, struct device *master, void *data)
dc_drm->cf_cont[1] = cf;
break;
case 4:
- cf->link = LINK_ID_CONSTFRAME4_MX8QXP;
+ cf->link = dc_cf_match_data->link_cf4;
dc_drm->cf_safe[0] = cf;
break;
case 5:
- cf->link = LINK_ID_CONSTFRAME5_MX8QXP;
+ cf->link = dc_cf_match_data->link_cf5;
dc_drm->cf_safe[1] = cf;
break;
}
@@ -157,7 +172,7 @@ static void dc_cf_remove(struct platform_device *pdev)
}
static const struct of_device_id dc_cf_dt_ids[] = {
- { .compatible = "fsl,imx8qxp-dc-constframe" },
+ { .compatible = "fsl,imx8qxp-dc-constframe", .data = &dc_cf_match_data_imx8qxp },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_cf_dt_ids);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 07/39] drm/imx: dc: cf: Pass struct dc_subdev_info via OF match data
2025-10-11 16:51 ` [PATCH 07/39] drm/imx: dc: cf: Pass struct dc_subdev_info via OF match data Marek Vasut
@ 2025-10-13 17:01 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 17:01 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:22PM +0200, Marek Vasut wrote:
> Pass the struct dc_subdev_info as OF match data into the driver,
> so the driver can use the match data to correct map addresses to
> IDs. This is a preparatory patch for i.MX95 addition. No functional
> change.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-cf.c | 23 +++++++++++++++++++----
> 1 file changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
> index 6cb83182a3668..1d3602c5d4230 100644
> --- a/drivers/gpu/drm/imx/dc/dc-cf.c
> +++ b/drivers/gpu/drm/imx/dc/dc-cf.c
> @@ -10,6 +10,7 @@
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> +#include <linux/property.h>
> #include <linux/regmap.h>
>
> #include "dc-drv.h"
> @@ -24,7 +25,13 @@
> #define CONSTANTCOLOR 0x10
> #define BLUE(x) FIELD_PREP(GENMASK(15, 8), (x))
>
> -static const struct dc_subdev_info dc_cf_info[] = {
> +struct dc_cf_subdev_match_data {
> + enum dc_link_id link_cf4;
> + enum dc_link_id link_cf5;
> + const struct dc_subdev_info *info;
> +};
> +
> +static const struct dc_subdev_info dc_cf_info_imx8qxp[] = {
> { .reg_start = 0x56180960, .id = 0, },
> { .reg_start = 0x561809e0, .id = 1, },
> { .reg_start = 0x561809a0, .id = 4, },
> @@ -32,6 +39,12 @@ static const struct dc_subdev_info dc_cf_info[] = {
> { /* sentinel */ },
> };
>
> +static const struct dc_cf_subdev_match_data dc_cf_match_data_imx8qxp = {
> + .link_cf4 = LINK_ID_CONSTFRAME4_MX8QXP,
> + .link_cf5 = LINK_ID_CONSTFRAME5_MX8QXP,
> + .info = dc_cf_info_imx8qxp,
> +};
> +
> static const struct regmap_range dc_cf_regmap_ranges[] = {
> regmap_reg_range(STATICCONTROL, CONSTANTCOLOR),
> };
> @@ -85,6 +98,8 @@ void dc_cf_init(struct dc_cf *cf)
>
> static int dc_cf_bind(struct device *dev, struct device *master, void *data)
> {
> + const struct dc_cf_subdev_match_data *dc_cf_match_data = device_get_match_data(dev);
> + const struct dc_subdev_info *dc_cf_info = dc_cf_match_data->info;
> struct platform_device *pdev = to_platform_device(dev);
> struct dc_drm_device *dc_drm = data;
> struct resource *res_pec;
> @@ -123,11 +138,11 @@ static int dc_cf_bind(struct device *dev, struct device *master, void *data)
> dc_drm->cf_cont[1] = cf;
> break;
> case 4:
> - cf->link = LINK_ID_CONSTFRAME4_MX8QXP;
> + cf->link = dc_cf_match_data->link_cf4;
> dc_drm->cf_safe[0] = cf;
> break;
> case 5:
> - cf->link = LINK_ID_CONSTFRAME5_MX8QXP;
> + cf->link = dc_cf_match_data->link_cf5;
> dc_drm->cf_safe[1] = cf;
> break;
> }
> @@ -157,7 +172,7 @@ static void dc_cf_remove(struct platform_device *pdev)
> }
>
> static const struct of_device_id dc_cf_dt_ids[] = {
> - { .compatible = "fsl,imx8qxp-dc-constframe" },
> + { .compatible = "fsl,imx8qxp-dc-constframe", .data = &dc_cf_match_data_imx8qxp },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_cf_dt_ids);
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 08/39] drm/imx: dc: de: Pass struct dc_de_subdev_match_data via OF match data
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (6 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 07/39] drm/imx: dc: cf: Pass struct dc_subdev_info via OF match data Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 17:05 ` Frank Li
2025-10-11 16:51 ` [PATCH 09/39] drm/imx: dc: ed: Rework dc_ed_pec_src_sel() to drop ARRAY_SIZE() use Marek Vasut
` (32 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Introduce struct dc_de_subdev_match_data which describes the differences
between i.MX8QXP and i.MX95, which in this case is one register offset
and address space offsets, and pass it as OF match data into the driver,
so the driver can use the match data to correctly access Display Engine
polarity control register on each SoC. This is a preparatory patch for
i.MX95 addition. No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-de.c | 44 +++++++++++++++++++++++-----------
drivers/gpu/drm/imx/dc/dc-de.h | 1 +
2 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-de.c b/drivers/gpu/drm/imx/dc/dc-de.c
index 81334c0088219..6331b2f3b622c 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.c
+++ b/drivers/gpu/drm/imx/dc/dc-de.c
@@ -10,47 +10,62 @@
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include "dc-de.h"
#include "dc-drv.h"
-#define POLARITYCTRL 0xc
+#define POLARITYCTRL_IMX8QXP 0xc
#define POLEN_HIGH BIT(2)
-static const struct dc_subdev_info dc_de_info[] = {
+struct dc_de_subdev_match_data {
+ const struct regmap_config *regmap_config;
+ unsigned int reg_polarityctrl;
+ const struct dc_subdev_info *info;
+};
+
+static const struct dc_subdev_info dc_de_info_imx8qxp[] = {
{ .reg_start = 0x5618b400, .id = 0, },
{ .reg_start = 0x5618b420, .id = 1, },
{ /* sentinel */ },
};
-static const struct regmap_range dc_de_regmap_ranges[] = {
- regmap_reg_range(POLARITYCTRL, POLARITYCTRL),
+static const struct regmap_range dc_de_regmap_ranges_imx8qxp[] = {
+ regmap_reg_range(POLARITYCTRL_IMX8QXP, POLARITYCTRL_IMX8QXP),
};
-static const struct regmap_access_table dc_de_regmap_access_table = {
- .yes_ranges = dc_de_regmap_ranges,
- .n_yes_ranges = ARRAY_SIZE(dc_de_regmap_ranges),
+static const struct regmap_access_table dc_de_regmap_access_table_imx8qxp = {
+ .yes_ranges = dc_de_regmap_ranges_imx8qxp,
+ .n_yes_ranges = ARRAY_SIZE(dc_de_regmap_ranges_imx8qxp),
};
-static const struct regmap_config dc_de_top_regmap_config = {
+static const struct regmap_config dc_de_top_regmap_config_imx8qxp = {
.name = "top",
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.fast_io = true,
- .wr_table = &dc_de_regmap_access_table,
- .rd_table = &dc_de_regmap_access_table,
- .max_register = POLARITYCTRL,
+ .wr_table = &dc_de_regmap_access_table_imx8qxp,
+ .rd_table = &dc_de_regmap_access_table_imx8qxp,
+ .max_register = POLARITYCTRL_IMX8QXP,
+};
+
+static const struct dc_de_subdev_match_data dc_de_match_data_imx8qxp = {
+ .regmap_config = &dc_de_top_regmap_config_imx8qxp,
+ .reg_polarityctrl = POLARITYCTRL_IMX8QXP,
+ .info = dc_de_info_imx8qxp,
};
static inline void dc_dec_init(struct dc_de *de)
{
- regmap_write_bits(de->reg_top, POLARITYCTRL, POLARITYCTRL, POLEN_HIGH);
+ regmap_write_bits(de->reg_top, de->reg_polarityctrl, de->reg_polarityctrl, POLEN_HIGH);
}
static int dc_de_bind(struct device *dev, struct device *master, void *data)
{
+ const struct dc_de_subdev_match_data *dc_de_match_data = device_get_match_data(dev);
+ const struct dc_subdev_info *dc_de_info = dc_de_match_data->info;
struct platform_device *pdev = to_platform_device(dev);
struct dc_drm_device *dc_drm = data;
struct resource *res_top;
@@ -67,7 +82,7 @@ static int dc_de_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(base_top);
de->reg_top = devm_regmap_init_mmio(dev, base_top,
- &dc_de_top_regmap_config);
+ dc_de_match_data->regmap_config);
if (IS_ERR(de->reg_top))
return PTR_ERR(de->reg_top);
@@ -84,6 +99,7 @@ static int dc_de_bind(struct device *dev, struct device *master, void *data)
return de->irq_seqcomplete;
de->dev = dev;
+ de->reg_polarityctrl = dc_de_match_data->reg_polarityctrl;
dev_set_drvdata(dev, de);
@@ -163,7 +179,7 @@ static const struct dev_pm_ops dc_de_pm_ops = {
};
static const struct of_device_id dc_de_dt_ids[] = {
- { .compatible = "fsl,imx8qxp-dc-display-engine" },
+ { .compatible = "fsl,imx8qxp-dc-display-engine", .data = &dc_de_match_data_imx8qxp },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_de_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
index 1ac70b4f6276f..e054ad88190e1 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.h
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -42,6 +42,7 @@ struct dc_de {
int irq_shdload;
int irq_framecomplete;
int irq_seqcomplete;
+ unsigned int reg_polarityctrl;
};
/* Domain Blend Unit */
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 08/39] drm/imx: dc: de: Pass struct dc_de_subdev_match_data via OF match data
2025-10-11 16:51 ` [PATCH 08/39] drm/imx: dc: de: Pass struct dc_de_subdev_match_data " Marek Vasut
@ 2025-10-13 17:05 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 17:05 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:23PM +0200, Marek Vasut wrote:
> Introduce struct dc_de_subdev_match_data which describes the differences
> between i.MX8QXP and i.MX95, which in this case is one register offset
> and address space offsets, and pass it as OF match data into the driver,
> so the driver can use the match data to correctly access Display Engine
> polarity control register on each SoC. This is a preparatory patch for
> i.MX95 addition. No functional change.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-de.c | 44 +++++++++++++++++++++++-----------
> drivers/gpu/drm/imx/dc/dc-de.h | 1 +
> 2 files changed, 31 insertions(+), 14 deletions(-)
>
...
> diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
> index 1ac70b4f6276f..e054ad88190e1 100644
> --- a/drivers/gpu/drm/imx/dc/dc-de.h
> +++ b/drivers/gpu/drm/imx/dc/dc-de.h
> @@ -42,6 +42,7 @@ struct dc_de {
> int irq_shdload;
> int irq_framecomplete;
> int irq_seqcomplete;
> + unsigned int reg_polarityctrl;
suggest add pointer to dc_de_subdev_match_data, in case need more in future
and avoid copy data again.
Frank
> };
>
> /* Domain Blend Unit */
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 09/39] drm/imx: dc: ed: Rework dc_ed_pec_src_sel() to drop ARRAY_SIZE() use
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (7 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 08/39] drm/imx: dc: de: Pass struct dc_de_subdev_match_data " Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:24 ` Frank Li
2025-10-11 16:51 ` [PATCH 10/39] drm/imx: dc: ed: Pass struct dc_ed_subdev_match_data via OF match data Marek Vasut
` (31 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Rework dc_ed_pec_src_sel() to drop ARRAY_SIZE() use and use new sentinel
trailing entry LINK_ID_LAST to stop iterating over src_sels array instead.
This allows passing of this array around as OF match data, which will be
useful when using this pipeline on i.MX95, which has different src_sels
array.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-ed.c | 7 ++++---
drivers/gpu/drm/imx/dc/dc-pe.h | 1 +
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
index 9a141c6aa0812..2fdd22a903dec 100644
--- a/drivers/gpu/drm/imx/dc/dc-ed.c
+++ b/drivers/gpu/drm/imx/dc/dc-ed.c
@@ -116,6 +116,7 @@ static const enum dc_link_id src_sels[] = {
LINK_ID_LAYERBLEND2_MX8QXP,
LINK_ID_LAYERBLEND1_MX8QXP,
LINK_ID_LAYERBLEND0_MX8QXP,
+ LINK_ID_LAST /* sentinel */
};
static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
@@ -141,10 +142,10 @@ static inline void dc_ed_pec_div_reset(struct dc_ed *ed)
void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src)
{
- int i;
+ int i = 0;
- for (i = 0; i < ARRAY_SIZE(src_sels); i++) {
- if (src_sels[i] == src) {
+ while (src_sels[i] != LINK_ID_LAST) {
+ if (src_sels[i++] == src) {
regmap_write(ed->reg_pec, PIXENGCFG_DYNAMIC, src);
return;
}
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
index 866859403a79d..1e1e04cc39d4b 100644
--- a/drivers/gpu/drm/imx/dc/dc-pe.h
+++ b/drivers/gpu/drm/imx/dc/dc-pe.h
@@ -33,6 +33,7 @@ enum dc_link_id {
LINK_ID_LAYERBLEND1_MX8QXP = 0x22,
LINK_ID_LAYERBLEND2_MX8QXP = 0x23,
LINK_ID_LAYERBLEND3_MX8QXP = 0x24,
+ LINK_ID_LAST = 0xffffffff, /* sentinel */
};
enum dc_lb_mode {
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 09/39] drm/imx: dc: ed: Rework dc_ed_pec_src_sel() to drop ARRAY_SIZE() use
2025-10-11 16:51 ` [PATCH 09/39] drm/imx: dc: ed: Rework dc_ed_pec_src_sel() to drop ARRAY_SIZE() use Marek Vasut
@ 2025-10-13 18:24 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:24 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:24PM +0200, Marek Vasut wrote:
> Rework dc_ed_pec_src_sel() to drop ARRAY_SIZE() use and use new sentinel
> trailing entry LINK_ID_LAST to stop iterating over src_sels array instead.
> This allows passing of this array around as OF match data, which will be
> useful when using this pipeline on i.MX95, which has different src_sels
> array.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-ed.c | 7 ++++---
> drivers/gpu/drm/imx/dc/dc-pe.h | 1 +
> 2 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
> index 9a141c6aa0812..2fdd22a903dec 100644
> --- a/drivers/gpu/drm/imx/dc/dc-ed.c
> +++ b/drivers/gpu/drm/imx/dc/dc-ed.c
> @@ -116,6 +116,7 @@ static const enum dc_link_id src_sels[] = {
> LINK_ID_LAYERBLEND2_MX8QXP,
> LINK_ID_LAYERBLEND1_MX8QXP,
> LINK_ID_LAYERBLEND0_MX8QXP,
> + LINK_ID_LAST /* sentinel */
> };
>
> static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
> @@ -141,10 +142,10 @@ static inline void dc_ed_pec_div_reset(struct dc_ed *ed)
>
> void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src)
> {
> - int i;
> + int i = 0;
>
> - for (i = 0; i < ARRAY_SIZE(src_sels); i++) {
> - if (src_sels[i] == src) {
> + while (src_sels[i] != LINK_ID_LAST) {
> + if (src_sels[i++] == src) {
> regmap_write(ed->reg_pec, PIXENGCFG_DYNAMIC, src);
> return;
> }
> diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
> index 866859403a79d..1e1e04cc39d4b 100644
> --- a/drivers/gpu/drm/imx/dc/dc-pe.h
> +++ b/drivers/gpu/drm/imx/dc/dc-pe.h
> @@ -33,6 +33,7 @@ enum dc_link_id {
> LINK_ID_LAYERBLEND1_MX8QXP = 0x22,
> LINK_ID_LAYERBLEND2_MX8QXP = 0x23,
> LINK_ID_LAYERBLEND3_MX8QXP = 0x24,
> + LINK_ID_LAST = 0xffffffff, /* sentinel */
> };
>
> enum dc_lb_mode {
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 10/39] drm/imx: dc: ed: Pass struct dc_ed_subdev_match_data via OF match data
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (8 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 09/39] drm/imx: dc: ed: Rework dc_ed_pec_src_sel() to drop ARRAY_SIZE() use Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:26 ` Frank Li
2025-10-11 16:51 ` [PATCH 11/39] drm/imx: dc: fg: Parametrize register access Marek Vasut
` (30 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Introduce struct dc_ed_subdev_match_data which describes the differences
between i.MX8QXP and i.MX95, which in this case is src_sels mapping and
address space offsets, and pass it as OF match data into the driver, so
the driver can use the match data to apply correct src_sels value to the
IP registers on each SoC. This is a preparatory patch for i.MX95 addition.
No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-ed.c | 24 +++++++++++++++++++-----
drivers/gpu/drm/imx/dc/dc-pe.h | 1 +
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
index 2fdd22a903dec..63dcad30ecced 100644
--- a/drivers/gpu/drm/imx/dc/dc-ed.c
+++ b/drivers/gpu/drm/imx/dc/dc-ed.c
@@ -9,6 +9,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include "dc-drv.h"
@@ -35,7 +36,12 @@
#define CONTROL 0xc
#define GAMMAAPPLYENABLE BIT(0)
-static const struct dc_subdev_info dc_ed_info[] = {
+struct dc_ed_subdev_match_data {
+ const enum dc_link_id *src_sels;
+ const struct dc_subdev_info *info;
+};
+
+static const struct dc_subdev_info dc_ed_info_imx8qxp[] = {
{ .reg_start = 0x56180980, .id = 0, },
{ .reg_start = 0x56180a00, .id = 1, },
{ .reg_start = 0x561809c0, .id = 4, },
@@ -106,7 +112,7 @@ static const struct regmap_config dc_ed_cfg_regmap_config = {
.max_register = CONTROL,
};
-static const enum dc_link_id src_sels[] = {
+static const enum dc_link_id src_sels_imx8qxp[] = {
LINK_ID_NONE,
LINK_ID_CONSTFRAME0,
LINK_ID_CONSTFRAME1,
@@ -119,6 +125,11 @@ static const enum dc_link_id src_sels[] = {
LINK_ID_LAST /* sentinel */
};
+static const struct dc_ed_subdev_match_data dc_ed_match_data_imx8qxp = {
+ .src_sels = src_sels_imx8qxp,
+ .info = dc_ed_info_imx8qxp,
+};
+
static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
{
regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SHDEN, SHDEN);
@@ -144,8 +155,8 @@ void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src)
{
int i = 0;
- while (src_sels[i] != LINK_ID_LAST) {
- if (src_sels[i++] == src) {
+ while (ed->src_sels[i] != LINK_ID_LAST) {
+ if (ed->src_sels[i++] == src) {
regmap_write(ed->reg_pec, PIXENGCFG_DYNAMIC, src);
return;
}
@@ -192,6 +203,8 @@ void dc_ed_init(struct dc_ed *ed)
static int dc_ed_bind(struct device *dev, struct device *master, void *data)
{
+ const struct dc_ed_subdev_match_data *dc_ed_match_data = device_get_match_data(dev);
+ const struct dc_subdev_info *dc_ed_info = dc_ed_match_data->info;
struct platform_device *pdev = to_platform_device(dev);
struct dc_drm_device *dc_drm = data;
struct resource *res_pec;
@@ -227,6 +240,7 @@ static int dc_ed_bind(struct device *dev, struct device *master, void *data)
return ed->irq_shdload;
ed->dev = dev;
+ ed->src_sels = dc_ed_match_data->src_sels;
id = dc_subdev_get_id(dc_ed_info, res_pec);
if (id < 0) {
@@ -274,7 +288,7 @@ static void dc_ed_remove(struct platform_device *pdev)
}
static const struct of_device_id dc_ed_dt_ids[] = {
- { .compatible = "fsl,imx8qxp-dc-extdst" },
+ { .compatible = "fsl,imx8qxp-dc-extdst", .data = &dc_ed_match_data_imx8qxp },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_ed_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
index 1e1e04cc39d4b..7928f947b0cef 100644
--- a/drivers/gpu/drm/imx/dc/dc-pe.h
+++ b/drivers/gpu/drm/imx/dc/dc-pe.h
@@ -56,6 +56,7 @@ struct dc_ed {
struct regmap *reg_pec;
struct regmap *reg_cfg;
int irq_shdload;
+ const enum dc_link_id *src_sels;
};
struct dc_lb {
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 10/39] drm/imx: dc: ed: Pass struct dc_ed_subdev_match_data via OF match data
2025-10-11 16:51 ` [PATCH 10/39] drm/imx: dc: ed: Pass struct dc_ed_subdev_match_data via OF match data Marek Vasut
@ 2025-10-13 18:26 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:26 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:25PM +0200, Marek Vasut wrote:
> Introduce struct dc_ed_subdev_match_data which describes the differences
> between i.MX8QXP and i.MX95, which in this case is src_sels mapping and
> address space offsets, and pass it as OF match data into the driver, so
> the driver can use the match data to apply correct src_sels value to the
> IP registers on each SoC. This is a preparatory patch for i.MX95 addition.
> No functional change.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-ed.c | 24 +++++++++++++++++++-----
> drivers/gpu/drm/imx/dc/dc-pe.h | 1 +
> 2 files changed, 20 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
> index 2fdd22a903dec..63dcad30ecced 100644
> --- a/drivers/gpu/drm/imx/dc/dc-ed.c
> +++ b/drivers/gpu/drm/imx/dc/dc-ed.c
> @@ -9,6 +9,7 @@
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> +#include <linux/property.h>
> #include <linux/regmap.h>
>
> #include "dc-drv.h"
> @@ -35,7 +36,12 @@
> #define CONTROL 0xc
> #define GAMMAAPPLYENABLE BIT(0)
>
> -static const struct dc_subdev_info dc_ed_info[] = {
> +struct dc_ed_subdev_match_data {
> + const enum dc_link_id *src_sels;
> + const struct dc_subdev_info *info;
> +};
> +
> +static const struct dc_subdev_info dc_ed_info_imx8qxp[] = {
> { .reg_start = 0x56180980, .id = 0, },
> { .reg_start = 0x56180a00, .id = 1, },
> { .reg_start = 0x561809c0, .id = 4, },
> @@ -106,7 +112,7 @@ static const struct regmap_config dc_ed_cfg_regmap_config = {
> .max_register = CONTROL,
> };
>
> -static const enum dc_link_id src_sels[] = {
> +static const enum dc_link_id src_sels_imx8qxp[] = {
> LINK_ID_NONE,
> LINK_ID_CONSTFRAME0,
> LINK_ID_CONSTFRAME1,
> @@ -119,6 +125,11 @@ static const enum dc_link_id src_sels[] = {
> LINK_ID_LAST /* sentinel */
> };
>
> +static const struct dc_ed_subdev_match_data dc_ed_match_data_imx8qxp = {
> + .src_sels = src_sels_imx8qxp,
> + .info = dc_ed_info_imx8qxp,
> +};
> +
> static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
> {
> regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SHDEN, SHDEN);
> @@ -144,8 +155,8 @@ void dc_ed_pec_src_sel(struct dc_ed *ed, enum dc_link_id src)
> {
> int i = 0;
>
> - while (src_sels[i] != LINK_ID_LAST) {
> - if (src_sels[i++] == src) {
> + while (ed->src_sels[i] != LINK_ID_LAST) {
> + if (ed->src_sels[i++] == src) {
> regmap_write(ed->reg_pec, PIXENGCFG_DYNAMIC, src);
> return;
> }
> @@ -192,6 +203,8 @@ void dc_ed_init(struct dc_ed *ed)
>
> static int dc_ed_bind(struct device *dev, struct device *master, void *data)
> {
> + const struct dc_ed_subdev_match_data *dc_ed_match_data = device_get_match_data(dev);
> + const struct dc_subdev_info *dc_ed_info = dc_ed_match_data->info;
> struct platform_device *pdev = to_platform_device(dev);
> struct dc_drm_device *dc_drm = data;
> struct resource *res_pec;
> @@ -227,6 +240,7 @@ static int dc_ed_bind(struct device *dev, struct device *master, void *data)
> return ed->irq_shdload;
>
> ed->dev = dev;
> + ed->src_sels = dc_ed_match_data->src_sels;
>
> id = dc_subdev_get_id(dc_ed_info, res_pec);
> if (id < 0) {
> @@ -274,7 +288,7 @@ static void dc_ed_remove(struct platform_device *pdev)
> }
>
> static const struct of_device_id dc_ed_dt_ids[] = {
> - { .compatible = "fsl,imx8qxp-dc-extdst" },
> + { .compatible = "fsl,imx8qxp-dc-extdst", .data = &dc_ed_match_data_imx8qxp },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_ed_dt_ids);
> diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
> index 1e1e04cc39d4b..7928f947b0cef 100644
> --- a/drivers/gpu/drm/imx/dc/dc-pe.h
> +++ b/drivers/gpu/drm/imx/dc/dc-pe.h
> @@ -56,6 +56,7 @@ struct dc_ed {
> struct regmap *reg_pec;
> struct regmap *reg_cfg;
> int irq_shdload;
> + const enum dc_link_id *src_sels;
Pointer to dc_ed_subdev_match_data, in case need more data in future.
Frank
> };
>
> struct dc_lb {
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 11/39] drm/imx: dc: fg: Parametrize register access
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (9 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 10/39] drm/imx: dc: ed: Pass struct dc_ed_subdev_match_data via OF match data Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:29 ` Frank Li
2025-10-11 16:51 ` [PATCH 12/39] drm/imx: dc: ed: Pass struct dc_fg_subdev_match_data via OF match data Marek Vasut
` (29 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Pass register offset for the second half of the register area around.
This is done in preparation for i.MX95 support addition, which has the
registers at offset 0x24 instead of 0x00. No functional change so far.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-fg.c | 62 ++++++++++++++++++----------------
1 file changed, 32 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
index 5fadd67aa911b..05e635fdb4f9c 100644
--- a/drivers/gpu/drm/imx/dc/dc-fg.c
+++ b/drivers/gpu/drm/imx/dc/dc-fg.c
@@ -49,35 +49,37 @@
#define ROW(x) FIELD_PREP(GENMASK(29, 16), (x))
#define COL(x) FIELD_PREP(GENMASK(13, 0), (x))
-#define PACFG 0x54
-#define SACFG 0x58
+#define OFFSET_MX8QXP 0x00
+
+#define PACFG(o) (0x54 + (o))
+#define SACFG(o) (0x58 + (o))
#define STARTY(x) FIELD_PREP(GENMASK(29, 16), ((x) + 1))
#define STARTX(x) FIELD_PREP(GENMASK(13, 0), ((x) + 1))
-#define FGINCTRL 0x5c
-#define FGINCTRLPANIC 0x60
+#define FGINCTRL(o) (0x5c + (o))
+#define FGINCTRLPANIC(o) (0x60 + (o))
#define FGDM_MASK GENMASK(2, 0)
#define ENPRIMALPHA BIT(3)
#define ENSECALPHA BIT(4)
-#define FGCCR 0x64
+#define FGCCR(o) (0x64 + (o))
#define CCGREEN(x) FIELD_PREP(GENMASK(19, 10), (x))
-#define FGENABLE 0x68
+#define FGENABLE(o) (0x68 + (o))
#define FGEN BIT(0)
-#define FGSLR 0x6c
+#define FGSLR(o) (0x6c + (o))
#define SHDTOKGEN BIT(0)
-#define FGTIMESTAMP 0x74
+#define FGTIMESTAMP(o) (0x74 + (o))
#define FRAMEINDEX(x) FIELD_GET(GENMASK(31, 14), (x))
#define LINEINDEX(x) FIELD_GET(GENMASK(13, 0), (x))
-#define FGCHSTAT 0x78
+#define FGCHSTAT(o) (0x78 + (o))
#define SECSYNCSTAT BIT(24)
#define SFIFOEMPTY BIT(16)
-#define FGCHSTATCLR 0x7c
+#define FGCHSTATCLR(o) (0x7c + (o))
#define CLRSECSTAT BIT(16)
enum dc_fg_syncmode {
@@ -98,15 +100,15 @@ static const struct dc_subdev_info dc_fg_info[] = {
static const struct regmap_range dc_fg_regmap_write_ranges[] = {
regmap_reg_range(FGSTCTRL, VTCFG2),
regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
- regmap_reg_range(PACFG, FGSLR),
- regmap_reg_range(FGCHSTATCLR, FGCHSTATCLR),
+ regmap_reg_range(PACFG(OFFSET_MX8QXP), FGSLR(OFFSET_MX8QXP)),
+ regmap_reg_range(FGCHSTATCLR(OFFSET_MX8QXP), FGCHSTATCLR(OFFSET_MX8QXP)),
};
static const struct regmap_range dc_fg_regmap_read_ranges[] = {
regmap_reg_range(FGSTCTRL, VTCFG2),
regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
- regmap_reg_range(PACFG, FGENABLE),
- regmap_reg_range(FGTIMESTAMP, FGCHSTAT),
+ regmap_reg_range(PACFG(OFFSET_MX8QXP), FGENABLE(OFFSET_MX8QXP)),
+ regmap_reg_range(FGTIMESTAMP(OFFSET_MX8QXP), FGCHSTAT(OFFSET_MX8QXP)),
};
static const struct regmap_access_table dc_fg_regmap_write_table = {
@@ -126,7 +128,7 @@ static const struct regmap_config dc_fg_regmap_config = {
.fast_io = true,
.wr_table = &dc_fg_regmap_write_table,
.rd_table = &dc_fg_regmap_read_table,
- .max_register = FGCHSTATCLR,
+ .max_register = FGCHSTATCLR(OFFSET_MX8QXP),
};
static inline void dc_fg_enable_shden(struct dc_fg *fg)
@@ -172,15 +174,15 @@ void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
regmap_write(fg->reg, SKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
/* primary and secondary area position configuration */
- regmap_write(fg->reg, PACFG, STARTX(0) | STARTY(0));
- regmap_write(fg->reg, SACFG, STARTX(0) | STARTY(0));
+ regmap_write(fg->reg, PACFG(OFFSET_MX8QXP), STARTX(0) | STARTY(0));
+ regmap_write(fg->reg, SACFG(OFFSET_MX8QXP), STARTX(0) | STARTY(0));
/* alpha */
- regmap_write_bits(fg->reg, FGINCTRL, ENPRIMALPHA | ENSECALPHA, 0);
- regmap_write_bits(fg->reg, FGINCTRLPANIC, ENPRIMALPHA | ENSECALPHA, 0);
+ regmap_write_bits(fg->reg, FGINCTRL(OFFSET_MX8QXP), ENPRIMALPHA | ENSECALPHA, 0);
+ regmap_write_bits(fg->reg, FGINCTRLPANIC(OFFSET_MX8QXP), ENPRIMALPHA | ENSECALPHA, 0);
/* constant color is green(used in panic mode) */
- regmap_write(fg->reg, FGCCR, CCGREEN(0x3ff));
+ regmap_write(fg->reg, FGCCR(OFFSET_MX8QXP), CCGREEN(0x3ff));
ret = clk_set_rate(fg->clk_disp, m->clock * HZ_PER_KHZ);
if (ret < 0)
@@ -189,34 +191,34 @@ void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
static inline void dc_fg_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
{
- regmap_write_bits(fg->reg, FGINCTRL, FGDM_MASK, mode);
+ regmap_write_bits(fg->reg, FGINCTRL(OFFSET_MX8QXP), FGDM_MASK, mode);
}
static inline void dc_fg_panic_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
{
- regmap_write_bits(fg->reg, FGINCTRLPANIC, FGDM_MASK, mode);
+ regmap_write_bits(fg->reg, FGINCTRLPANIC(OFFSET_MX8QXP), FGDM_MASK, mode);
}
void dc_fg_enable(struct dc_fg *fg)
{
- regmap_write(fg->reg, FGENABLE, FGEN);
+ regmap_write(fg->reg, FGENABLE(OFFSET_MX8QXP), FGEN);
}
void dc_fg_disable(struct dc_fg *fg)
{
- regmap_write(fg->reg, FGENABLE, 0);
+ regmap_write(fg->reg, FGENABLE(OFFSET_MX8QXP), 0);
}
void dc_fg_shdtokgen(struct dc_fg *fg)
{
- regmap_write(fg->reg, FGSLR, SHDTOKGEN);
+ regmap_write(fg->reg, FGSLR(OFFSET_MX8QXP), SHDTOKGEN);
}
u32 dc_fg_get_frame_index(struct dc_fg *fg)
{
u32 val;
- regmap_read(fg->reg, FGTIMESTAMP, &val);
+ regmap_read(fg->reg, FGTIMESTAMP(OFFSET_MX8QXP), &val);
return FRAMEINDEX(val);
}
@@ -225,7 +227,7 @@ u32 dc_fg_get_line_index(struct dc_fg *fg)
{
u32 val;
- regmap_read(fg->reg, FGTIMESTAMP, &val);
+ regmap_read(fg->reg, FGTIMESTAMP(OFFSET_MX8QXP), &val);
return LINEINDEX(val);
}
@@ -249,21 +251,21 @@ bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg)
{
u32 val;
- regmap_read(fg->reg, FGCHSTAT, &val);
+ regmap_read(fg->reg, FGCHSTAT(OFFSET_MX8QXP), &val);
return !!(val & SFIFOEMPTY);
}
void dc_fg_secondary_clear_channel_status(struct dc_fg *fg)
{
- regmap_write(fg->reg, FGCHSTATCLR, CLRSECSTAT);
+ regmap_write(fg->reg, FGCHSTATCLR(OFFSET_MX8QXP), CLRSECSTAT);
}
int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg)
{
unsigned int val;
- return regmap_read_poll_timeout(fg->reg, FGCHSTAT, val,
+ return regmap_read_poll_timeout(fg->reg, FGCHSTAT(OFFSET_MX8QXP), val,
val & SECSYNCSTAT, 5, 100000);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 11/39] drm/imx: dc: fg: Parametrize register access
2025-10-11 16:51 ` [PATCH 11/39] drm/imx: dc: fg: Parametrize register access Marek Vasut
@ 2025-10-13 18:29 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:29 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:26PM +0200, Marek Vasut wrote:
> Pass register offset for the second half of the register area around.
> This is done in preparation for i.MX95 support addition, which has the
This is preparation for i.MX95 support addition...
> registers at offset 0x24 instead of 0x00. No functional change so far.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-fg.c | 62 ++++++++++++++++++----------------
> 1 file changed, 32 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
> index 5fadd67aa911b..05e635fdb4f9c 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fg.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fg.c
> @@ -49,35 +49,37 @@
> #define ROW(x) FIELD_PREP(GENMASK(29, 16), (x))
> #define COL(x) FIELD_PREP(GENMASK(13, 0), (x))
>
> -#define PACFG 0x54
> -#define SACFG 0x58
> +#define OFFSET_MX8QXP 0x00
> +
> +#define PACFG(o) (0x54 + (o))
> +#define SACFG(o) (0x58 + (o))
> #define STARTY(x) FIELD_PREP(GENMASK(29, 16), ((x) + 1))
> #define STARTX(x) FIELD_PREP(GENMASK(13, 0), ((x) + 1))
>
> -#define FGINCTRL 0x5c
> -#define FGINCTRLPANIC 0x60
> +#define FGINCTRL(o) (0x5c + (o))
> +#define FGINCTRLPANIC(o) (0x60 + (o))
I think off is better to read compared o
Frank
> #define FGDM_MASK GENMASK(2, 0)
> #define ENPRIMALPHA BIT(3)
> #define ENSECALPHA BIT(4)
>
> -#define FGCCR 0x64
> +#define FGCCR(o) (0x64 + (o))
> #define CCGREEN(x) FIELD_PREP(GENMASK(19, 10), (x))
>
> -#define FGENABLE 0x68
> +#define FGENABLE(o) (0x68 + (o))
> #define FGEN BIT(0)
>
> -#define FGSLR 0x6c
> +#define FGSLR(o) (0x6c + (o))
> #define SHDTOKGEN BIT(0)
>
> -#define FGTIMESTAMP 0x74
> +#define FGTIMESTAMP(o) (0x74 + (o))
> #define FRAMEINDEX(x) FIELD_GET(GENMASK(31, 14), (x))
> #define LINEINDEX(x) FIELD_GET(GENMASK(13, 0), (x))
>
> -#define FGCHSTAT 0x78
> +#define FGCHSTAT(o) (0x78 + (o))
> #define SECSYNCSTAT BIT(24)
> #define SFIFOEMPTY BIT(16)
>
> -#define FGCHSTATCLR 0x7c
> +#define FGCHSTATCLR(o) (0x7c + (o))
> #define CLRSECSTAT BIT(16)
>
> enum dc_fg_syncmode {
> @@ -98,15 +100,15 @@ static const struct dc_subdev_info dc_fg_info[] = {
> static const struct regmap_range dc_fg_regmap_write_ranges[] = {
> regmap_reg_range(FGSTCTRL, VTCFG2),
> regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
> - regmap_reg_range(PACFG, FGSLR),
> - regmap_reg_range(FGCHSTATCLR, FGCHSTATCLR),
> + regmap_reg_range(PACFG(OFFSET_MX8QXP), FGSLR(OFFSET_MX8QXP)),
> + regmap_reg_range(FGCHSTATCLR(OFFSET_MX8QXP), FGCHSTATCLR(OFFSET_MX8QXP)),
> };
>
> static const struct regmap_range dc_fg_regmap_read_ranges[] = {
> regmap_reg_range(FGSTCTRL, VTCFG2),
> regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
> - regmap_reg_range(PACFG, FGENABLE),
> - regmap_reg_range(FGTIMESTAMP, FGCHSTAT),
> + regmap_reg_range(PACFG(OFFSET_MX8QXP), FGENABLE(OFFSET_MX8QXP)),
> + regmap_reg_range(FGTIMESTAMP(OFFSET_MX8QXP), FGCHSTAT(OFFSET_MX8QXP)),
> };
>
> static const struct regmap_access_table dc_fg_regmap_write_table = {
> @@ -126,7 +128,7 @@ static const struct regmap_config dc_fg_regmap_config = {
> .fast_io = true,
> .wr_table = &dc_fg_regmap_write_table,
> .rd_table = &dc_fg_regmap_read_table,
> - .max_register = FGCHSTATCLR,
> + .max_register = FGCHSTATCLR(OFFSET_MX8QXP),
> };
>
> static inline void dc_fg_enable_shden(struct dc_fg *fg)
> @@ -172,15 +174,15 @@ void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
> regmap_write(fg->reg, SKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
>
> /* primary and secondary area position configuration */
> - regmap_write(fg->reg, PACFG, STARTX(0) | STARTY(0));
> - regmap_write(fg->reg, SACFG, STARTX(0) | STARTY(0));
> + regmap_write(fg->reg, PACFG(OFFSET_MX8QXP), STARTX(0) | STARTY(0));
> + regmap_write(fg->reg, SACFG(OFFSET_MX8QXP), STARTX(0) | STARTY(0));
>
> /* alpha */
> - regmap_write_bits(fg->reg, FGINCTRL, ENPRIMALPHA | ENSECALPHA, 0);
> - regmap_write_bits(fg->reg, FGINCTRLPANIC, ENPRIMALPHA | ENSECALPHA, 0);
> + regmap_write_bits(fg->reg, FGINCTRL(OFFSET_MX8QXP), ENPRIMALPHA | ENSECALPHA, 0);
> + regmap_write_bits(fg->reg, FGINCTRLPANIC(OFFSET_MX8QXP), ENPRIMALPHA | ENSECALPHA, 0);
>
> /* constant color is green(used in panic mode) */
> - regmap_write(fg->reg, FGCCR, CCGREEN(0x3ff));
> + regmap_write(fg->reg, FGCCR(OFFSET_MX8QXP), CCGREEN(0x3ff));
>
> ret = clk_set_rate(fg->clk_disp, m->clock * HZ_PER_KHZ);
> if (ret < 0)
> @@ -189,34 +191,34 @@ void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
>
> static inline void dc_fg_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
> {
> - regmap_write_bits(fg->reg, FGINCTRL, FGDM_MASK, mode);
> + regmap_write_bits(fg->reg, FGINCTRL(OFFSET_MX8QXP), FGDM_MASK, mode);
> }
>
> static inline void dc_fg_panic_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
> {
> - regmap_write_bits(fg->reg, FGINCTRLPANIC, FGDM_MASK, mode);
> + regmap_write_bits(fg->reg, FGINCTRLPANIC(OFFSET_MX8QXP), FGDM_MASK, mode);
> }
>
> void dc_fg_enable(struct dc_fg *fg)
> {
> - regmap_write(fg->reg, FGENABLE, FGEN);
> + regmap_write(fg->reg, FGENABLE(OFFSET_MX8QXP), FGEN);
> }
>
> void dc_fg_disable(struct dc_fg *fg)
> {
> - regmap_write(fg->reg, FGENABLE, 0);
> + regmap_write(fg->reg, FGENABLE(OFFSET_MX8QXP), 0);
> }
>
> void dc_fg_shdtokgen(struct dc_fg *fg)
> {
> - regmap_write(fg->reg, FGSLR, SHDTOKGEN);
> + regmap_write(fg->reg, FGSLR(OFFSET_MX8QXP), SHDTOKGEN);
> }
>
> u32 dc_fg_get_frame_index(struct dc_fg *fg)
> {
> u32 val;
>
> - regmap_read(fg->reg, FGTIMESTAMP, &val);
> + regmap_read(fg->reg, FGTIMESTAMP(OFFSET_MX8QXP), &val);
>
> return FRAMEINDEX(val);
> }
> @@ -225,7 +227,7 @@ u32 dc_fg_get_line_index(struct dc_fg *fg)
> {
> u32 val;
>
> - regmap_read(fg->reg, FGTIMESTAMP, &val);
> + regmap_read(fg->reg, FGTIMESTAMP(OFFSET_MX8QXP), &val);
>
> return LINEINDEX(val);
> }
> @@ -249,21 +251,21 @@ bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg)
> {
> u32 val;
>
> - regmap_read(fg->reg, FGCHSTAT, &val);
> + regmap_read(fg->reg, FGCHSTAT(OFFSET_MX8QXP), &val);
>
> return !!(val & SFIFOEMPTY);
> }
>
> void dc_fg_secondary_clear_channel_status(struct dc_fg *fg)
> {
> - regmap_write(fg->reg, FGCHSTATCLR, CLRSECSTAT);
> + regmap_write(fg->reg, FGCHSTATCLR(OFFSET_MX8QXP), CLRSECSTAT);
> }
>
> int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg)
> {
> unsigned int val;
>
> - return regmap_read_poll_timeout(fg->reg, FGCHSTAT, val,
> + return regmap_read_poll_timeout(fg->reg, FGCHSTAT(OFFSET_MX8QXP), val,
> val & SECSYNCSTAT, 5, 100000);
> }
>
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 12/39] drm/imx: dc: ed: Pass struct dc_fg_subdev_match_data via OF match data
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (10 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 11/39] drm/imx: dc: fg: Parametrize register access Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:31 ` Frank Li
2025-10-11 16:51 ` [PATCH 13/39] drm/imx: dc: fu: Describe remaining register offsets Marek Vasut
` (28 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Introduce struct dc_fg_subdev_match_data which describes the differences
between i.MX8QXP and i.MX95, which in this case is registers offset and
address space offsets, and pass it as OF match data into the driver, so
the driver can use the match data to apply correct offset to access the
IP registers on each SoC. This is a preparatory patch for i.MX95 addition.
No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-de.h | 1 +
drivers/gpu/drm/imx/dc/dc-fg.c | 74 +++++++++++++++++++++-------------
2 files changed, 46 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
index e054ad88190e1..797056a09ddb4 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.h
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -26,6 +26,7 @@ struct dc_fg {
struct device *dev;
struct regmap *reg;
struct clk *clk_disp;
+ unsigned int reg_offset;
};
struct dc_tc {
diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
index 05e635fdb4f9c..e13b057a92ffb 100644
--- a/drivers/gpu/drm/imx/dc/dc-fg.c
+++ b/drivers/gpu/drm/imx/dc/dc-fg.c
@@ -12,6 +12,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/units.h>
@@ -82,6 +83,12 @@
#define FGCHSTATCLR(o) (0x7c + (o))
#define CLRSECSTAT BIT(16)
+struct dc_fg_subdev_match_data {
+ const struct regmap_config *regmap_config;
+ unsigned int reg_offset;
+ const struct dc_subdev_info *info;
+};
+
enum dc_fg_syncmode {
FG_SYNCMODE_OFF, /* No side-by-side synchronization. */
};
@@ -91,46 +98,52 @@ enum dc_fg_dm {
FG_DM_SEC_ON_TOP = 0x5, /* Both inputs overlaid with secondary on top. */
};
-static const struct dc_subdev_info dc_fg_info[] = {
+static const struct dc_subdev_info dc_fg_info_imx8qxp[] = {
{ .reg_start = 0x5618b800, .id = 0, },
{ .reg_start = 0x5618d400, .id = 1, },
{ /* sentinel */ },
};
-static const struct regmap_range dc_fg_regmap_write_ranges[] = {
+static const struct regmap_range dc_fg_regmap_write_ranges_imx8qxp[] = {
regmap_reg_range(FGSTCTRL, VTCFG2),
regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
regmap_reg_range(PACFG(OFFSET_MX8QXP), FGSLR(OFFSET_MX8QXP)),
regmap_reg_range(FGCHSTATCLR(OFFSET_MX8QXP), FGCHSTATCLR(OFFSET_MX8QXP)),
};
-static const struct regmap_range dc_fg_regmap_read_ranges[] = {
+static const struct regmap_range dc_fg_regmap_read_ranges_imx8qxp[] = {
regmap_reg_range(FGSTCTRL, VTCFG2),
regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
regmap_reg_range(PACFG(OFFSET_MX8QXP), FGENABLE(OFFSET_MX8QXP)),
regmap_reg_range(FGTIMESTAMP(OFFSET_MX8QXP), FGCHSTAT(OFFSET_MX8QXP)),
};
-static const struct regmap_access_table dc_fg_regmap_write_table = {
- .yes_ranges = dc_fg_regmap_write_ranges,
- .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_write_ranges),
+static const struct regmap_access_table dc_fg_regmap_write_table_imx8qxp = {
+ .yes_ranges = dc_fg_regmap_write_ranges_imx8qxp,
+ .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_write_ranges_imx8qxp),
};
-static const struct regmap_access_table dc_fg_regmap_read_table = {
- .yes_ranges = dc_fg_regmap_read_ranges,
- .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_read_ranges),
+static const struct regmap_access_table dc_fg_regmap_read_table_imx8qxp = {
+ .yes_ranges = dc_fg_regmap_read_ranges_imx8qxp,
+ .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_read_ranges_imx8qxp),
};
-static const struct regmap_config dc_fg_regmap_config = {
+static const struct regmap_config dc_fg_regmap_config_imx8qxp = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.fast_io = true,
- .wr_table = &dc_fg_regmap_write_table,
- .rd_table = &dc_fg_regmap_read_table,
+ .wr_table = &dc_fg_regmap_write_table_imx8qxp,
+ .rd_table = &dc_fg_regmap_read_table_imx8qxp,
.max_register = FGCHSTATCLR(OFFSET_MX8QXP),
};
+static const struct dc_fg_subdev_match_data dc_fg_match_data_imx8qxp = {
+ .regmap_config = &dc_fg_regmap_config_imx8qxp,
+ .reg_offset = OFFSET_MX8QXP,
+ .info = dc_fg_info_imx8qxp,
+};
+
static inline void dc_fg_enable_shden(struct dc_fg *fg)
{
regmap_write_bits(fg->reg, FGSTCTRL, SHDEN, SHDEN);
@@ -174,15 +187,15 @@ void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
regmap_write(fg->reg, SKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
/* primary and secondary area position configuration */
- regmap_write(fg->reg, PACFG(OFFSET_MX8QXP), STARTX(0) | STARTY(0));
- regmap_write(fg->reg, SACFG(OFFSET_MX8QXP), STARTX(0) | STARTY(0));
+ regmap_write(fg->reg, PACFG(fg->reg_offset), STARTX(0) | STARTY(0));
+ regmap_write(fg->reg, SACFG(fg->reg_offset), STARTX(0) | STARTY(0));
/* alpha */
- regmap_write_bits(fg->reg, FGINCTRL(OFFSET_MX8QXP), ENPRIMALPHA | ENSECALPHA, 0);
- regmap_write_bits(fg->reg, FGINCTRLPANIC(OFFSET_MX8QXP), ENPRIMALPHA | ENSECALPHA, 0);
+ regmap_write_bits(fg->reg, FGINCTRL(fg->reg_offset), ENPRIMALPHA | ENSECALPHA, 0);
+ regmap_write_bits(fg->reg, FGINCTRLPANIC(fg->reg_offset), ENPRIMALPHA | ENSECALPHA, 0);
/* constant color is green(used in panic mode) */
- regmap_write(fg->reg, FGCCR(OFFSET_MX8QXP), CCGREEN(0x3ff));
+ regmap_write(fg->reg, FGCCR(fg->reg_offset), CCGREEN(0x3ff));
ret = clk_set_rate(fg->clk_disp, m->clock * HZ_PER_KHZ);
if (ret < 0)
@@ -191,34 +204,34 @@ void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
static inline void dc_fg_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
{
- regmap_write_bits(fg->reg, FGINCTRL(OFFSET_MX8QXP), FGDM_MASK, mode);
+ regmap_write_bits(fg->reg, FGINCTRL(fg->reg_offset), FGDM_MASK, mode);
}
static inline void dc_fg_panic_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
{
- regmap_write_bits(fg->reg, FGINCTRLPANIC(OFFSET_MX8QXP), FGDM_MASK, mode);
+ regmap_write_bits(fg->reg, FGINCTRLPANIC(fg->reg_offset), FGDM_MASK, mode);
}
void dc_fg_enable(struct dc_fg *fg)
{
- regmap_write(fg->reg, FGENABLE(OFFSET_MX8QXP), FGEN);
+ regmap_write(fg->reg, FGENABLE(fg->reg_offset), FGEN);
}
void dc_fg_disable(struct dc_fg *fg)
{
- regmap_write(fg->reg, FGENABLE(OFFSET_MX8QXP), 0);
+ regmap_write(fg->reg, FGENABLE(fg->reg_offset), 0);
}
void dc_fg_shdtokgen(struct dc_fg *fg)
{
- regmap_write(fg->reg, FGSLR(OFFSET_MX8QXP), SHDTOKGEN);
+ regmap_write(fg->reg, FGSLR(fg->reg_offset), SHDTOKGEN);
}
u32 dc_fg_get_frame_index(struct dc_fg *fg)
{
u32 val;
- regmap_read(fg->reg, FGTIMESTAMP(OFFSET_MX8QXP), &val);
+ regmap_read(fg->reg, FGTIMESTAMP(fg->reg_offset), &val);
return FRAMEINDEX(val);
}
@@ -227,7 +240,7 @@ u32 dc_fg_get_line_index(struct dc_fg *fg)
{
u32 val;
- regmap_read(fg->reg, FGTIMESTAMP(OFFSET_MX8QXP), &val);
+ regmap_read(fg->reg, FGTIMESTAMP(fg->reg_offset), &val);
return LINEINDEX(val);
}
@@ -251,21 +264,21 @@ bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg)
{
u32 val;
- regmap_read(fg->reg, FGCHSTAT(OFFSET_MX8QXP), &val);
+ regmap_read(fg->reg, FGCHSTAT(fg->reg_offset), &val);
return !!(val & SFIFOEMPTY);
}
void dc_fg_secondary_clear_channel_status(struct dc_fg *fg)
{
- regmap_write(fg->reg, FGCHSTATCLR(OFFSET_MX8QXP), CLRSECSTAT);
+ regmap_write(fg->reg, FGCHSTATCLR(fg->reg_offset), CLRSECSTAT);
}
int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg)
{
unsigned int val;
- return regmap_read_poll_timeout(fg->reg, FGCHSTAT(OFFSET_MX8QXP), val,
+ return regmap_read_poll_timeout(fg->reg, FGCHSTAT(fg->reg_offset), val,
val & SECSYNCSTAT, 5, 100000);
}
@@ -305,6 +318,8 @@ void dc_fg_init(struct dc_fg *fg)
static int dc_fg_bind(struct device *dev, struct device *master, void *data)
{
+ const struct dc_fg_subdev_match_data *dc_fg_match_data = device_get_match_data(dev);
+ const struct dc_subdev_info *dc_fg_info = dc_fg_match_data->info;
struct platform_device *pdev = to_platform_device(dev);
struct dc_drm_device *dc_drm = data;
struct resource *res;
@@ -320,7 +335,7 @@ static int dc_fg_bind(struct device *dev, struct device *master, void *data)
if (IS_ERR(base))
return PTR_ERR(base);
- fg->reg = devm_regmap_init_mmio(dev, base, &dc_fg_regmap_config);
+ fg->reg = devm_regmap_init_mmio(dev, base, dc_fg_match_data->regmap_config);
if (IS_ERR(fg->reg))
return PTR_ERR(fg->reg);
@@ -336,6 +351,7 @@ static int dc_fg_bind(struct device *dev, struct device *master, void *data)
}
fg->dev = dev;
+ fg->reg_offset = dc_fg_match_data->reg_offset;
dc_drm->fg[id] = fg;
return 0;
@@ -363,7 +379,7 @@ static void dc_fg_remove(struct platform_device *pdev)
}
static const struct of_device_id dc_fg_dt_ids[] = {
- { .compatible = "fsl,imx8qxp-dc-framegen" },
+ { .compatible = "fsl,imx8qxp-dc-framegen", .data = &dc_fg_match_data_imx8qxp },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_fg_dt_ids);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 12/39] drm/imx: dc: ed: Pass struct dc_fg_subdev_match_data via OF match data
2025-10-11 16:51 ` [PATCH 12/39] drm/imx: dc: ed: Pass struct dc_fg_subdev_match_data via OF match data Marek Vasut
@ 2025-10-13 18:31 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:31 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:27PM +0200, Marek Vasut wrote:
> Introduce struct dc_fg_subdev_match_data which describes the differences
> between i.MX8QXP and i.MX95, which in this case is registers offset and
> address space offsets, and pass it as OF match data into the driver, so
> the driver can use the match data to apply correct offset to access the
> IP registers on each SoC. This is a preparatory patch for i.MX95 addition.
> No functional change.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-de.h | 1 +
> drivers/gpu/drm/imx/dc/dc-fg.c | 74 +++++++++++++++++++++-------------
> 2 files changed, 46 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
> index e054ad88190e1..797056a09ddb4 100644
> --- a/drivers/gpu/drm/imx/dc/dc-de.h
> +++ b/drivers/gpu/drm/imx/dc/dc-de.h
> @@ -26,6 +26,7 @@ struct dc_fg {
> struct device *dev;
> struct regmap *reg;
> struct clk *clk_disp;
> + unsigned int reg_offset;
the same as other comments, pointer to dc_fg_subdev_match_data.
Frank
> };
>
> struct dc_tc {
> diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
> index 05e635fdb4f9c..e13b057a92ffb 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fg.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fg.c
> @@ -12,6 +12,7 @@
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> +#include <linux/property.h>
> #include <linux/regmap.h>
> #include <linux/units.h>
>
> @@ -82,6 +83,12 @@
> #define FGCHSTATCLR(o) (0x7c + (o))
> #define CLRSECSTAT BIT(16)
>
> +struct dc_fg_subdev_match_data {
> + const struct regmap_config *regmap_config;
> + unsigned int reg_offset;
> + const struct dc_subdev_info *info;
> +};
> +
> enum dc_fg_syncmode {
> FG_SYNCMODE_OFF, /* No side-by-side synchronization. */
> };
> @@ -91,46 +98,52 @@ enum dc_fg_dm {
> FG_DM_SEC_ON_TOP = 0x5, /* Both inputs overlaid with secondary on top. */
> };
>
> -static const struct dc_subdev_info dc_fg_info[] = {
> +static const struct dc_subdev_info dc_fg_info_imx8qxp[] = {
> { .reg_start = 0x5618b800, .id = 0, },
> { .reg_start = 0x5618d400, .id = 1, },
> { /* sentinel */ },
> };
>
> -static const struct regmap_range dc_fg_regmap_write_ranges[] = {
> +static const struct regmap_range dc_fg_regmap_write_ranges_imx8qxp[] = {
> regmap_reg_range(FGSTCTRL, VTCFG2),
> regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
> regmap_reg_range(PACFG(OFFSET_MX8QXP), FGSLR(OFFSET_MX8QXP)),
> regmap_reg_range(FGCHSTATCLR(OFFSET_MX8QXP), FGCHSTATCLR(OFFSET_MX8QXP)),
> };
>
> -static const struct regmap_range dc_fg_regmap_read_ranges[] = {
> +static const struct regmap_range dc_fg_regmap_read_ranges_imx8qxp[] = {
> regmap_reg_range(FGSTCTRL, VTCFG2),
> regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
> regmap_reg_range(PACFG(OFFSET_MX8QXP), FGENABLE(OFFSET_MX8QXP)),
> regmap_reg_range(FGTIMESTAMP(OFFSET_MX8QXP), FGCHSTAT(OFFSET_MX8QXP)),
> };
>
> -static const struct regmap_access_table dc_fg_regmap_write_table = {
> - .yes_ranges = dc_fg_regmap_write_ranges,
> - .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_write_ranges),
> +static const struct regmap_access_table dc_fg_regmap_write_table_imx8qxp = {
> + .yes_ranges = dc_fg_regmap_write_ranges_imx8qxp,
> + .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_write_ranges_imx8qxp),
> };
>
> -static const struct regmap_access_table dc_fg_regmap_read_table = {
> - .yes_ranges = dc_fg_regmap_read_ranges,
> - .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_read_ranges),
> +static const struct regmap_access_table dc_fg_regmap_read_table_imx8qxp = {
> + .yes_ranges = dc_fg_regmap_read_ranges_imx8qxp,
> + .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_read_ranges_imx8qxp),
> };
>
> -static const struct regmap_config dc_fg_regmap_config = {
> +static const struct regmap_config dc_fg_regmap_config_imx8qxp = {
> .reg_bits = 32,
> .reg_stride = 4,
> .val_bits = 32,
> .fast_io = true,
> - .wr_table = &dc_fg_regmap_write_table,
> - .rd_table = &dc_fg_regmap_read_table,
> + .wr_table = &dc_fg_regmap_write_table_imx8qxp,
> + .rd_table = &dc_fg_regmap_read_table_imx8qxp,
> .max_register = FGCHSTATCLR(OFFSET_MX8QXP),
> };
>
> +static const struct dc_fg_subdev_match_data dc_fg_match_data_imx8qxp = {
> + .regmap_config = &dc_fg_regmap_config_imx8qxp,
> + .reg_offset = OFFSET_MX8QXP,
> + .info = dc_fg_info_imx8qxp,
> +};
> +
> static inline void dc_fg_enable_shden(struct dc_fg *fg)
> {
> regmap_write_bits(fg->reg, FGSTCTRL, SHDEN, SHDEN);
> @@ -174,15 +187,15 @@ void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
> regmap_write(fg->reg, SKICKCONFIG, COL(kick_col) | ROW(kick_row) | EN);
>
> /* primary and secondary area position configuration */
> - regmap_write(fg->reg, PACFG(OFFSET_MX8QXP), STARTX(0) | STARTY(0));
> - regmap_write(fg->reg, SACFG(OFFSET_MX8QXP), STARTX(0) | STARTY(0));
> + regmap_write(fg->reg, PACFG(fg->reg_offset), STARTX(0) | STARTY(0));
> + regmap_write(fg->reg, SACFG(fg->reg_offset), STARTX(0) | STARTY(0));
>
> /* alpha */
> - regmap_write_bits(fg->reg, FGINCTRL(OFFSET_MX8QXP), ENPRIMALPHA | ENSECALPHA, 0);
> - regmap_write_bits(fg->reg, FGINCTRLPANIC(OFFSET_MX8QXP), ENPRIMALPHA | ENSECALPHA, 0);
> + regmap_write_bits(fg->reg, FGINCTRL(fg->reg_offset), ENPRIMALPHA | ENSECALPHA, 0);
> + regmap_write_bits(fg->reg, FGINCTRLPANIC(fg->reg_offset), ENPRIMALPHA | ENSECALPHA, 0);
>
> /* constant color is green(used in panic mode) */
> - regmap_write(fg->reg, FGCCR(OFFSET_MX8QXP), CCGREEN(0x3ff));
> + regmap_write(fg->reg, FGCCR(fg->reg_offset), CCGREEN(0x3ff));
>
> ret = clk_set_rate(fg->clk_disp, m->clock * HZ_PER_KHZ);
> if (ret < 0)
> @@ -191,34 +204,34 @@ void dc_fg_cfg_videomode(struct dc_fg *fg, struct drm_display_mode *m)
>
> static inline void dc_fg_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
> {
> - regmap_write_bits(fg->reg, FGINCTRL(OFFSET_MX8QXP), FGDM_MASK, mode);
> + regmap_write_bits(fg->reg, FGINCTRL(fg->reg_offset), FGDM_MASK, mode);
> }
>
> static inline void dc_fg_panic_displaymode(struct dc_fg *fg, enum dc_fg_dm mode)
> {
> - regmap_write_bits(fg->reg, FGINCTRLPANIC(OFFSET_MX8QXP), FGDM_MASK, mode);
> + regmap_write_bits(fg->reg, FGINCTRLPANIC(fg->reg_offset), FGDM_MASK, mode);
> }
>
> void dc_fg_enable(struct dc_fg *fg)
> {
> - regmap_write(fg->reg, FGENABLE(OFFSET_MX8QXP), FGEN);
> + regmap_write(fg->reg, FGENABLE(fg->reg_offset), FGEN);
> }
>
> void dc_fg_disable(struct dc_fg *fg)
> {
> - regmap_write(fg->reg, FGENABLE(OFFSET_MX8QXP), 0);
> + regmap_write(fg->reg, FGENABLE(fg->reg_offset), 0);
> }
>
> void dc_fg_shdtokgen(struct dc_fg *fg)
> {
> - regmap_write(fg->reg, FGSLR(OFFSET_MX8QXP), SHDTOKGEN);
> + regmap_write(fg->reg, FGSLR(fg->reg_offset), SHDTOKGEN);
> }
>
> u32 dc_fg_get_frame_index(struct dc_fg *fg)
> {
> u32 val;
>
> - regmap_read(fg->reg, FGTIMESTAMP(OFFSET_MX8QXP), &val);
> + regmap_read(fg->reg, FGTIMESTAMP(fg->reg_offset), &val);
>
> return FRAMEINDEX(val);
> }
> @@ -227,7 +240,7 @@ u32 dc_fg_get_line_index(struct dc_fg *fg)
> {
> u32 val;
>
> - regmap_read(fg->reg, FGTIMESTAMP(OFFSET_MX8QXP), &val);
> + regmap_read(fg->reg, FGTIMESTAMP(fg->reg_offset), &val);
>
> return LINEINDEX(val);
> }
> @@ -251,21 +264,21 @@ bool dc_fg_secondary_requests_to_read_empty_fifo(struct dc_fg *fg)
> {
> u32 val;
>
> - regmap_read(fg->reg, FGCHSTAT(OFFSET_MX8QXP), &val);
> + regmap_read(fg->reg, FGCHSTAT(fg->reg_offset), &val);
>
> return !!(val & SFIFOEMPTY);
> }
>
> void dc_fg_secondary_clear_channel_status(struct dc_fg *fg)
> {
> - regmap_write(fg->reg, FGCHSTATCLR(OFFSET_MX8QXP), CLRSECSTAT);
> + regmap_write(fg->reg, FGCHSTATCLR(fg->reg_offset), CLRSECSTAT);
> }
>
> int dc_fg_wait_for_secondary_syncup(struct dc_fg *fg)
> {
> unsigned int val;
>
> - return regmap_read_poll_timeout(fg->reg, FGCHSTAT(OFFSET_MX8QXP), val,
> + return regmap_read_poll_timeout(fg->reg, FGCHSTAT(fg->reg_offset), val,
> val & SECSYNCSTAT, 5, 100000);
> }
>
> @@ -305,6 +318,8 @@ void dc_fg_init(struct dc_fg *fg)
>
> static int dc_fg_bind(struct device *dev, struct device *master, void *data)
> {
> + const struct dc_fg_subdev_match_data *dc_fg_match_data = device_get_match_data(dev);
> + const struct dc_subdev_info *dc_fg_info = dc_fg_match_data->info;
> struct platform_device *pdev = to_platform_device(dev);
> struct dc_drm_device *dc_drm = data;
> struct resource *res;
> @@ -320,7 +335,7 @@ static int dc_fg_bind(struct device *dev, struct device *master, void *data)
> if (IS_ERR(base))
> return PTR_ERR(base);
>
> - fg->reg = devm_regmap_init_mmio(dev, base, &dc_fg_regmap_config);
> + fg->reg = devm_regmap_init_mmio(dev, base, dc_fg_match_data->regmap_config);
> if (IS_ERR(fg->reg))
> return PTR_ERR(fg->reg);
>
> @@ -336,6 +351,7 @@ static int dc_fg_bind(struct device *dev, struct device *master, void *data)
> }
>
> fg->dev = dev;
> + fg->reg_offset = dc_fg_match_data->reg_offset;
> dc_drm->fg[id] = fg;
>
> return 0;
> @@ -363,7 +379,7 @@ static void dc_fg_remove(struct platform_device *pdev)
> }
>
> static const struct of_device_id dc_fg_dt_ids[] = {
> - { .compatible = "fsl,imx8qxp-dc-framegen" },
> + { .compatible = "fsl,imx8qxp-dc-framegen", .data = &dc_fg_match_data_imx8qxp },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_fg_dt_ids);
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 13/39] drm/imx: dc: fu: Describe remaining register offsets
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (11 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 12/39] drm/imx: dc: ed: Pass struct dc_fg_subdev_match_data via OF match data Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:34 ` Frank Li
2025-10-11 16:51 ` [PATCH 14/39] drm/imx: dc: fu: Inline FRAC_OFFSET into FetchLayer and FetchWrap Marek Vasut
` (27 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Describe the rest of register offsets in struct dc_fu { } and
use them throughout the driver. This is a preparatory change
for i.MX95 addition. No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-fl.c | 12 ++++++++----
drivers/gpu/drm/imx/dc/dc-fu.c | 6 +++---
drivers/gpu/drm/imx/dc/dc-fu.h | 4 ++++
drivers/gpu/drm/imx/dc/dc-fw.c | 10 +++++++---
4 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
index d4e746f8c4297..8571871c6a683 100644
--- a/drivers/gpu/drm/imx/dc/dc-fl.c
+++ b/drivers/gpu/drm/imx/dc/dc-fl.c
@@ -63,20 +63,20 @@ static void dc_fl_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
dc_fu_set_src_bpp(fu, frac, format->cpp[0] * 8);
- regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
+ regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
YUVCONVERSIONMODE_MASK,
YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
dc_fu_get_pixel_format_bits(fu, format->format, &bits);
dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
- regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
- regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
+ regmap_write(fu->reg_cfg, fu->reg_colorcomponentbits[frac], bits);
+ regmap_write(fu->reg_cfg, fu->reg_colorcomponentshift[frac], shifts);
}
static void dc_fl_set_framedimensions(struct dc_fu *fu, int w, int h)
{
- regmap_write(fu->reg_cfg, FRAMEDIMENSIONS,
+ regmap_write(fu->reg_cfg, fu->reg_framedimensions,
FRAMEWIDTH(w) | FRAMEHEIGHT(h));
}
@@ -133,12 +133,16 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
fu->reg_baseaddr[i] = BASEADDRESS(i);
fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION(i);
+ fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS(i);
+ fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT(i);
fu->reg_layeroffset[i] = LAYEROFFSET(i);
fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET(i);
fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS(i);
fu->reg_constantcolor[i] = CONSTANTCOLOR(i);
fu->reg_layerproperty[i] = LAYERPROPERTY(i);
}
+ fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
+ fu->reg_framedimensions = FRAMEDIMENSIONS;
snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", id);
dc_fl_set_ops(fu);
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.c b/drivers/gpu/drm/imx/dc/dc-fu.c
index f94c591c81589..cc8b0d05891fd 100644
--- a/drivers/gpu/drm/imx/dc/dc-fu.c
+++ b/drivers/gpu/drm/imx/dc/dc-fu.c
@@ -113,13 +113,13 @@ void dc_fu_shdldreq_sticky(struct dc_fu *fu, u8 layer_mask)
static inline void dc_fu_set_linemode(struct dc_fu *fu, enum dc_linemode mode)
{
- regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT, LINEMODE_MASK,
+ regmap_write_bits(fu->reg_cfg, fu->reg_burstbuffermanagement, LINEMODE_MASK,
mode);
}
static inline void dc_fu_set_numbuffers(struct dc_fu *fu, unsigned int num)
{
- regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
+ regmap_write_bits(fu->reg_cfg, fu->reg_burstbuffermanagement,
SETNUMBUFFERS_MASK, SETNUMBUFFERS(num));
}
@@ -132,7 +132,7 @@ static void dc_fu_set_burstlength(struct dc_fu *fu, dma_addr_t baddr)
burst_size = min(burst_size, 128U);
burst_length = burst_size / 8;
- regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
+ regmap_write_bits(fu->reg_cfg, fu->reg_burstbuffermanagement,
SETBURSTLENGTH_MASK, SETBURSTLENGTH(burst_length));
}
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.h b/drivers/gpu/drm/imx/dc/dc-fu.h
index e016e1ea5b4e0..2a330c0abf6a1 100644
--- a/drivers/gpu/drm/imx/dc/dc-fu.h
+++ b/drivers/gpu/drm/imx/dc/dc-fu.h
@@ -105,11 +105,15 @@ struct dc_fu {
u32 reg_baseaddr[DC_FETCHUNIT_FRAC_NUM];
u32 reg_sourcebufferattributes[DC_FETCHUNIT_FRAC_NUM];
u32 reg_sourcebufferdimension[DC_FETCHUNIT_FRAC_NUM];
+ u32 reg_colorcomponentbits[DC_FETCHUNIT_FRAC_NUM];
+ u32 reg_colorcomponentshift[DC_FETCHUNIT_FRAC_NUM];
u32 reg_layeroffset[DC_FETCHUNIT_FRAC_NUM];
u32 reg_clipwindowoffset[DC_FETCHUNIT_FRAC_NUM];
u32 reg_clipwindowdimensions[DC_FETCHUNIT_FRAC_NUM];
u32 reg_constantcolor[DC_FETCHUNIT_FRAC_NUM];
u32 reg_layerproperty[DC_FETCHUNIT_FRAC_NUM];
+ u32 reg_burstbuffermanagement;
+ u32 reg_framedimensions;
unsigned int id;
enum dc_link_id link_id;
struct dc_fu_ops ops;
diff --git a/drivers/gpu/drm/imx/dc/dc-fw.c b/drivers/gpu/drm/imx/dc/dc-fw.c
index c1131b7b17c2f..dc036121f0d23 100644
--- a/drivers/gpu/drm/imx/dc/dc-fw.c
+++ b/drivers/gpu/drm/imx/dc/dc-fw.c
@@ -91,15 +91,15 @@ static void dc_fw_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
regmap_write_bits(fu->reg_cfg, CONTROL, RASTERMODE_MASK,
RASTERMODE(RASTERMODE_NORMAL));
- regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
+ regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
YUVCONVERSIONMODE_MASK,
YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
dc_fu_get_pixel_format_bits(fu, format->format, &bits);
dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
- regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
- regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
+ regmap_write(fu->reg_cfg, fu->reg_colorcomponentbits[frac], bits);
+ regmap_write(fu->reg_cfg, fu->reg_colorcomponentshift[frac], shifts);
}
static void dc_fw_set_framedimensions(struct dc_fu *fu, int w, int h)
@@ -170,12 +170,16 @@ static int dc_fw_bind(struct device *dev, struct device *master, void *data)
fu->reg_baseaddr[i] = BASEADDRESS(i);
fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION(i);
+ fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS(i);
+ fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT(i);
fu->reg_layeroffset[i] = LAYEROFFSET(i);
fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET(i);
fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS(i);
fu->reg_constantcolor[i] = CONSTANTCOLOR(i);
fu->reg_layerproperty[i] = LAYERPROPERTY(i);
}
+ fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
+ fu->reg_framedimensions = FRAMEDIMENSIONS;
snprintf(fu->name, sizeof(fu->name), "FetchWarp%d", id);
dc_fw_set_ops(fu);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 13/39] drm/imx: dc: fu: Describe remaining register offsets
2025-10-11 16:51 ` [PATCH 13/39] drm/imx: dc: fu: Describe remaining register offsets Marek Vasut
@ 2025-10-13 18:34 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:34 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:28PM +0200, Marek Vasut wrote:
> Describe the rest of register offsets in struct dc_fu { } and
> use them throughout the driver. This is a preparatory change
> for i.MX95 addition. No functional change.
Nit: wrap at 75 chars to try to use full line.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-fl.c | 12 ++++++++----
> drivers/gpu/drm/imx/dc/dc-fu.c | 6 +++---
> drivers/gpu/drm/imx/dc/dc-fu.h | 4 ++++
> drivers/gpu/drm/imx/dc/dc-fw.c | 10 +++++++---
> 4 files changed, 22 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
> index d4e746f8c4297..8571871c6a683 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fl.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fl.c
> @@ -63,20 +63,20 @@ static void dc_fl_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
>
> dc_fu_set_src_bpp(fu, frac, format->cpp[0] * 8);
>
> - regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
> + regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
> YUVCONVERSIONMODE_MASK,
> YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
>
> dc_fu_get_pixel_format_bits(fu, format->format, &bits);
> dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
>
> - regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
> - regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
> + regmap_write(fu->reg_cfg, fu->reg_colorcomponentbits[frac], bits);
> + regmap_write(fu->reg_cfg, fu->reg_colorcomponentshift[frac], shifts);
> }
>
> static void dc_fl_set_framedimensions(struct dc_fu *fu, int w, int h)
> {
> - regmap_write(fu->reg_cfg, FRAMEDIMENSIONS,
> + regmap_write(fu->reg_cfg, fu->reg_framedimensions,
> FRAMEWIDTH(w) | FRAMEHEIGHT(h));
> }
>
> @@ -133,12 +133,16 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
> fu->reg_baseaddr[i] = BASEADDRESS(i);
> fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
> fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION(i);
> + fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS(i);
> + fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT(i);
> fu->reg_layeroffset[i] = LAYEROFFSET(i);
> fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET(i);
> fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS(i);
> fu->reg_constantcolor[i] = CONSTANTCOLOR(i);
> fu->reg_layerproperty[i] = LAYERPROPERTY(i);
> }
> + fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
> + fu->reg_framedimensions = FRAMEDIMENSIONS;
> snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", id);
>
> dc_fl_set_ops(fu);
> diff --git a/drivers/gpu/drm/imx/dc/dc-fu.c b/drivers/gpu/drm/imx/dc/dc-fu.c
> index f94c591c81589..cc8b0d05891fd 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fu.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fu.c
> @@ -113,13 +113,13 @@ void dc_fu_shdldreq_sticky(struct dc_fu *fu, u8 layer_mask)
>
> static inline void dc_fu_set_linemode(struct dc_fu *fu, enum dc_linemode mode)
> {
> - regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT, LINEMODE_MASK,
> + regmap_write_bits(fu->reg_cfg, fu->reg_burstbuffermanagement, LINEMODE_MASK,
> mode);
> }
>
> static inline void dc_fu_set_numbuffers(struct dc_fu *fu, unsigned int num)
> {
> - regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
> + regmap_write_bits(fu->reg_cfg, fu->reg_burstbuffermanagement,
> SETNUMBUFFERS_MASK, SETNUMBUFFERS(num));
> }
>
> @@ -132,7 +132,7 @@ static void dc_fu_set_burstlength(struct dc_fu *fu, dma_addr_t baddr)
> burst_size = min(burst_size, 128U);
> burst_length = burst_size / 8;
>
> - regmap_write_bits(fu->reg_cfg, BURSTBUFFERMANAGEMENT,
> + regmap_write_bits(fu->reg_cfg, fu->reg_burstbuffermanagement,
> SETBURSTLENGTH_MASK, SETBURSTLENGTH(burst_length));
> }
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-fu.h b/drivers/gpu/drm/imx/dc/dc-fu.h
> index e016e1ea5b4e0..2a330c0abf6a1 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fu.h
> +++ b/drivers/gpu/drm/imx/dc/dc-fu.h
> @@ -105,11 +105,15 @@ struct dc_fu {
> u32 reg_baseaddr[DC_FETCHUNIT_FRAC_NUM];
> u32 reg_sourcebufferattributes[DC_FETCHUNIT_FRAC_NUM];
> u32 reg_sourcebufferdimension[DC_FETCHUNIT_FRAC_NUM];
> + u32 reg_colorcomponentbits[DC_FETCHUNIT_FRAC_NUM];
> + u32 reg_colorcomponentshift[DC_FETCHUNIT_FRAC_NUM];
> u32 reg_layeroffset[DC_FETCHUNIT_FRAC_NUM];
> u32 reg_clipwindowoffset[DC_FETCHUNIT_FRAC_NUM];
> u32 reg_clipwindowdimensions[DC_FETCHUNIT_FRAC_NUM];
> u32 reg_constantcolor[DC_FETCHUNIT_FRAC_NUM];
> u32 reg_layerproperty[DC_FETCHUNIT_FRAC_NUM];
> + u32 reg_burstbuffermanagement;
> + u32 reg_framedimensions;
> unsigned int id;
> enum dc_link_id link_id;
> struct dc_fu_ops ops;
> diff --git a/drivers/gpu/drm/imx/dc/dc-fw.c b/drivers/gpu/drm/imx/dc/dc-fw.c
> index c1131b7b17c2f..dc036121f0d23 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fw.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fw.c
> @@ -91,15 +91,15 @@ static void dc_fw_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
> regmap_write_bits(fu->reg_cfg, CONTROL, RASTERMODE_MASK,
> RASTERMODE(RASTERMODE_NORMAL));
>
> - regmap_write_bits(fu->reg_cfg, LAYERPROPERTY(frac),
> + regmap_write_bits(fu->reg_cfg, fu->reg_layerproperty[frac],
> YUVCONVERSIONMODE_MASK,
> YUVCONVERSIONMODE(YUVCONVERSIONMODE_OFF));
>
> dc_fu_get_pixel_format_bits(fu, format->format, &bits);
> dc_fu_get_pixel_format_shifts(fu, format->format, &shifts);
>
> - regmap_write(fu->reg_cfg, COLORCOMPONENTBITS(frac), bits);
> - regmap_write(fu->reg_cfg, COLORCOMPONENTSHIFT(frac), shifts);
> + regmap_write(fu->reg_cfg, fu->reg_colorcomponentbits[frac], bits);
> + regmap_write(fu->reg_cfg, fu->reg_colorcomponentshift[frac], shifts);
> }
>
> static void dc_fw_set_framedimensions(struct dc_fu *fu, int w, int h)
> @@ -170,12 +170,16 @@ static int dc_fw_bind(struct device *dev, struct device *master, void *data)
> fu->reg_baseaddr[i] = BASEADDRESS(i);
> fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
> fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION(i);
> + fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS(i);
> + fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT(i);
> fu->reg_layeroffset[i] = LAYEROFFSET(i);
> fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET(i);
> fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS(i);
> fu->reg_constantcolor[i] = CONSTANTCOLOR(i);
> fu->reg_layerproperty[i] = LAYERPROPERTY(i);
> }
> + fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
> + fu->reg_framedimensions = FRAMEDIMENSIONS;
> snprintf(fu->name, sizeof(fu->name), "FetchWarp%d", id);
>
> dc_fw_set_ops(fu);
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 14/39] drm/imx: dc: fu: Inline FRAC_OFFSET into FetchLayer and FetchWrap
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (12 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 13/39] drm/imx: dc: fu: Describe remaining register offsets Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:39 ` Frank Li
2025-10-11 16:51 ` [PATCH 15/39] drm/imx: dc: fu: Pass struct dc_fu_subdev_match_data via OF match data Marek Vasut
` (26 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Move FRAC_OFFSET into FetchLayer and FetchLayer drivers, because
FetchLayer is present on i.MX95 with different FRAC_OFFSET and
FetchWrap is not present. Prepare the register offset calculation
for i.MX95 addition. No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-fl.c | 46 +++++++++++++++++++---------------
drivers/gpu/drm/imx/dc/dc-fu.h | 3 ---
drivers/gpu/drm/imx/dc/dc-fw.c | 45 ++++++++++++++++++---------------
3 files changed, 51 insertions(+), 43 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
index 8571871c6a683..a76825dc75fe1 100644
--- a/drivers/gpu/drm/imx/dc/dc-fl.c
+++ b/drivers/gpu/drm/imx/dc/dc-fl.c
@@ -15,16 +15,19 @@
#include "dc-drv.h"
#include "dc-fu.h"
-#define BASEADDRESS(x) (0x10 + FRAC_OFFSET * (x))
-#define SOURCEBUFFERATTRIBUTES(x) (0x14 + FRAC_OFFSET * (x))
-#define SOURCEBUFFERDIMENSION(x) (0x18 + FRAC_OFFSET * (x))
-#define COLORCOMPONENTBITS(x) (0x1c + FRAC_OFFSET * (x))
-#define COLORCOMPONENTSHIFT(x) (0x20 + FRAC_OFFSET * (x))
-#define LAYEROFFSET(x) (0x24 + FRAC_OFFSET * (x))
-#define CLIPWINDOWOFFSET(x) (0x28 + FRAC_OFFSET * (x))
-#define CLIPWINDOWDIMENSIONS(x) (0x2c + FRAC_OFFSET * (x))
-#define CONSTANTCOLOR(x) (0x30 + FRAC_OFFSET * (x))
-#define LAYERPROPERTY(x) (0x34 + FRAC_OFFSET * (x))
+#define FRAC_OFFSET 0x28
+
+#define BURSTBUFFERMANAGEMENT 0xc
+#define BASEADDRESS 0x10
+#define SOURCEBUFFERATTRIBUTES 0x14
+#define SOURCEBUFFERDIMENSION 0x18
+#define COLORCOMPONENTBITS 0x1c
+#define COLORCOMPONENTSHIFT 0x20
+#define LAYEROFFSET 0x24
+#define CLIPWINDOWOFFSET 0x28
+#define CLIPWINDOWDIMENSIONS 0x2c
+#define CONSTANTCOLOR 0x30
+#define LAYERPROPERTY 0x34
#define FRAMEDIMENSIONS 0x150
struct dc_fl {
@@ -98,6 +101,7 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct dc_drm_device *dc_drm = data;
+ unsigned int off_base, off_regs;
struct resource *res_pec;
void __iomem *base_cfg;
struct dc_fl *fl;
@@ -130,16 +134,18 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
fu->link_id = LINK_ID_FETCHLAYER0;
fu->id = DC_FETCHUNIT_FL0;
for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
- fu->reg_baseaddr[i] = BASEADDRESS(i);
- fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
- fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION(i);
- fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS(i);
- fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT(i);
- fu->reg_layeroffset[i] = LAYEROFFSET(i);
- fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET(i);
- fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS(i);
- fu->reg_constantcolor[i] = CONSTANTCOLOR(i);
- fu->reg_layerproperty[i] = LAYERPROPERTY(i);
+ off_base = i * FRAC_OFFSET;
+ fu->reg_baseaddr[i] = BASEADDRESS + off_base;
+ off_regs = i * FRAC_OFFSET;
+ fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES + off_regs;
+ fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION + off_regs;
+ fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS + off_regs;
+ fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT + off_regs;
+ fu->reg_layeroffset[i] = LAYEROFFSET + off_regs;
+ fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET + off_regs;
+ fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS + off_regs;
+ fu->reg_constantcolor[i] = CONSTANTCOLOR + off_regs;
+ fu->reg_layerproperty[i] = LAYERPROPERTY + off_regs;
}
fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
fu->reg_framedimensions = FRAMEDIMENSIONS;
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.h b/drivers/gpu/drm/imx/dc/dc-fu.h
index 2a330c0abf6a1..3983ef23e40fb 100644
--- a/drivers/gpu/drm/imx/dc/dc-fu.h
+++ b/drivers/gpu/drm/imx/dc/dc-fu.h
@@ -15,10 +15,7 @@
#include "dc-pe.h"
-#define FRAC_OFFSET 0x28
-
#define STATICCONTROL 0x8
-#define BURSTBUFFERMANAGEMENT 0xc
/* COLORCOMPONENTBITS */
#define R_BITS(x) FIELD_PREP_CONST(GENMASK(27, 24), (x))
diff --git a/drivers/gpu/drm/imx/dc/dc-fw.c b/drivers/gpu/drm/imx/dc/dc-fw.c
index dc036121f0d23..7bbe06a840c93 100644
--- a/drivers/gpu/drm/imx/dc/dc-fw.c
+++ b/drivers/gpu/drm/imx/dc/dc-fw.c
@@ -16,16 +16,19 @@
#define PIXENGCFG_DYNAMIC 0x8
-#define BASEADDRESS(x) (0x10 + FRAC_OFFSET * (x))
-#define SOURCEBUFFERATTRIBUTES(x) (0x14 + FRAC_OFFSET * (x))
-#define SOURCEBUFFERDIMENSION(x) (0x18 + FRAC_OFFSET * (x))
-#define COLORCOMPONENTBITS(x) (0x1c + FRAC_OFFSET * (x))
-#define COLORCOMPONENTSHIFT(x) (0x20 + FRAC_OFFSET * (x))
-#define LAYEROFFSET(x) (0x24 + FRAC_OFFSET * (x))
-#define CLIPWINDOWOFFSET(x) (0x28 + FRAC_OFFSET * (x))
-#define CLIPWINDOWDIMENSIONS(x) (0x2c + FRAC_OFFSET * (x))
-#define CONSTANTCOLOR(x) (0x30 + FRAC_OFFSET * (x))
-#define LAYERPROPERTY(x) (0x34 + FRAC_OFFSET * (x))
+#define FRAC_OFFSET 0x28
+
+#define BURSTBUFFERMANAGEMENT 0xc
+#define BASEADDRESS 0x10
+#define SOURCEBUFFERATTRIBUTES 0x14
+#define SOURCEBUFFERDIMENSION 0x18
+#define COLORCOMPONENTBITS 0x1c
+#define COLORCOMPONENTSHIFT 0x20
+#define LAYEROFFSET 0x24
+#define CLIPWINDOWOFFSET 0x28
+#define CLIPWINDOWDIMENSIONS 0x2c
+#define CONSTANTCOLOR 0x30
+#define LAYERPROPERTY 0x34
#define FRAMEDIMENSIONS 0x150
#define CONTROL 0x170
@@ -130,6 +133,7 @@ static int dc_fw_bind(struct device *dev, struct device *master, void *data)
struct resource *res_pec;
void __iomem *base_pec;
void __iomem *base_cfg;
+ unsigned int off;
struct dc_fw *fw;
struct dc_fu *fu;
int i, id;
@@ -167,16 +171,17 @@ static int dc_fw_bind(struct device *dev, struct device *master, void *data)
fu->link_id = LINK_ID_FETCHWARP2;
fu->id = DC_FETCHUNIT_FW2;
for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
- fu->reg_baseaddr[i] = BASEADDRESS(i);
- fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
- fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION(i);
- fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS(i);
- fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT(i);
- fu->reg_layeroffset[i] = LAYEROFFSET(i);
- fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET(i);
- fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS(i);
- fu->reg_constantcolor[i] = CONSTANTCOLOR(i);
- fu->reg_layerproperty[i] = LAYERPROPERTY(i);
+ off = i * FRAC_OFFSET;
+ fu->reg_baseaddr[i] = BASEADDRESS + off;
+ fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES + off;
+ fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION + off;
+ fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS + off;
+ fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT + off;
+ fu->reg_layeroffset[i] = LAYEROFFSET + off;
+ fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET + off;
+ fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS + off;
+ fu->reg_constantcolor[i] = CONSTANTCOLOR + off;
+ fu->reg_layerproperty[i] = LAYERPROPERTY + off;
}
fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
fu->reg_framedimensions = FRAMEDIMENSIONS;
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 14/39] drm/imx: dc: fu: Inline FRAC_OFFSET into FetchLayer and FetchWrap
2025-10-11 16:51 ` [PATCH 14/39] drm/imx: dc: fu: Inline FRAC_OFFSET into FetchLayer and FetchWrap Marek Vasut
@ 2025-10-13 18:39 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:39 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:29PM +0200, Marek Vasut wrote:
> Move FRAC_OFFSET into FetchLayer and FetchLayer drivers, because
> FetchLayer is present on i.MX95 with different FRAC_OFFSET and
> FetchWrap is not present. Prepare the register offset calculation
> for i.MX95 addition. No functional change.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-fl.c | 46 +++++++++++++++++++---------------
> drivers/gpu/drm/imx/dc/dc-fu.h | 3 ---
> drivers/gpu/drm/imx/dc/dc-fw.c | 45 ++++++++++++++++++---------------
> 3 files changed, 51 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
> index 8571871c6a683..a76825dc75fe1 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fl.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fl.c
> @@ -15,16 +15,19 @@
> #include "dc-drv.h"
> #include "dc-fu.h"
>
> -#define BASEADDRESS(x) (0x10 + FRAC_OFFSET * (x))
> -#define SOURCEBUFFERATTRIBUTES(x) (0x14 + FRAC_OFFSET * (x))
> -#define SOURCEBUFFERDIMENSION(x) (0x18 + FRAC_OFFSET * (x))
> -#define COLORCOMPONENTBITS(x) (0x1c + FRAC_OFFSET * (x))
> -#define COLORCOMPONENTSHIFT(x) (0x20 + FRAC_OFFSET * (x))
> -#define LAYEROFFSET(x) (0x24 + FRAC_OFFSET * (x))
> -#define CLIPWINDOWOFFSET(x) (0x28 + FRAC_OFFSET * (x))
> -#define CLIPWINDOWDIMENSIONS(x) (0x2c + FRAC_OFFSET * (x))
> -#define CONSTANTCOLOR(x) (0x30 + FRAC_OFFSET * (x))
> -#define LAYERPROPERTY(x) (0x34 + FRAC_OFFSET * (x))
> +#define FRAC_OFFSET 0x28
> +
> +#define BURSTBUFFERMANAGEMENT 0xc
> +#define BASEADDRESS 0x10
> +#define SOURCEBUFFERATTRIBUTES 0x14
> +#define SOURCEBUFFERDIMENSION 0x18
> +#define COLORCOMPONENTBITS 0x1c
> +#define COLORCOMPONENTSHIFT 0x20
> +#define LAYEROFFSET 0x24
> +#define CLIPWINDOWOFFSET 0x28
> +#define CLIPWINDOWDIMENSIONS 0x2c
> +#define CONSTANTCOLOR 0x30
> +#define LAYERPROPERTY 0x34
> #define FRAMEDIMENSIONS 0x150
>
> struct dc_fl {
> @@ -98,6 +101,7 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct dc_drm_device *dc_drm = data;
> + unsigned int off_base, off_regs;
> struct resource *res_pec;
> void __iomem *base_cfg;
> struct dc_fl *fl;
> @@ -130,16 +134,18 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
> fu->link_id = LINK_ID_FETCHLAYER0;
> fu->id = DC_FETCHUNIT_FL0;
> for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
> - fu->reg_baseaddr[i] = BASEADDRESS(i);
> - fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
> - fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION(i);
> - fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS(i);
> - fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT(i);
> - fu->reg_layeroffset[i] = LAYEROFFSET(i);
> - fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET(i);
> - fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS(i);
> - fu->reg_constantcolor[i] = CONSTANTCOLOR(i);
> - fu->reg_layerproperty[i] = LAYERPROPERTY(i);
> + off_base = i * FRAC_OFFSET;
> + fu->reg_baseaddr[i] = BASEADDRESS + off_base;
> + off_regs = i * FRAC_OFFSET;
> + fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES + off_regs;
> + fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION + off_regs;
> + fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS + off_regs;
> + fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT + off_regs;
> + fu->reg_layeroffset[i] = LAYEROFFSET + off_regs;
> + fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET + off_regs;
> + fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS + off_regs;
> + fu->reg_constantcolor[i] = CONSTANTCOLOR + off_regs;
> + fu->reg_layerproperty[i] = LAYERPROPERTY + off_regs;
> }
> fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
> fu->reg_framedimensions = FRAMEDIMENSIONS;
> diff --git a/drivers/gpu/drm/imx/dc/dc-fu.h b/drivers/gpu/drm/imx/dc/dc-fu.h
> index 2a330c0abf6a1..3983ef23e40fb 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fu.h
> +++ b/drivers/gpu/drm/imx/dc/dc-fu.h
> @@ -15,10 +15,7 @@
>
> #include "dc-pe.h"
>
> -#define FRAC_OFFSET 0x28
> -
> #define STATICCONTROL 0x8
> -#define BURSTBUFFERMANAGEMENT 0xc
>
> /* COLORCOMPONENTBITS */
> #define R_BITS(x) FIELD_PREP_CONST(GENMASK(27, 24), (x))
> diff --git a/drivers/gpu/drm/imx/dc/dc-fw.c b/drivers/gpu/drm/imx/dc/dc-fw.c
> index dc036121f0d23..7bbe06a840c93 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fw.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fw.c
> @@ -16,16 +16,19 @@
>
> #define PIXENGCFG_DYNAMIC 0x8
>
> -#define BASEADDRESS(x) (0x10 + FRAC_OFFSET * (x))
> -#define SOURCEBUFFERATTRIBUTES(x) (0x14 + FRAC_OFFSET * (x))
> -#define SOURCEBUFFERDIMENSION(x) (0x18 + FRAC_OFFSET * (x))
> -#define COLORCOMPONENTBITS(x) (0x1c + FRAC_OFFSET * (x))
> -#define COLORCOMPONENTSHIFT(x) (0x20 + FRAC_OFFSET * (x))
> -#define LAYEROFFSET(x) (0x24 + FRAC_OFFSET * (x))
> -#define CLIPWINDOWOFFSET(x) (0x28 + FRAC_OFFSET * (x))
> -#define CLIPWINDOWDIMENSIONS(x) (0x2c + FRAC_OFFSET * (x))
> -#define CONSTANTCOLOR(x) (0x30 + FRAC_OFFSET * (x))
> -#define LAYERPROPERTY(x) (0x34 + FRAC_OFFSET * (x))
> +#define FRAC_OFFSET 0x28
> +
> +#define BURSTBUFFERMANAGEMENT 0xc
> +#define BASEADDRESS 0x10
> +#define SOURCEBUFFERATTRIBUTES 0x14
> +#define SOURCEBUFFERDIMENSION 0x18
> +#define COLORCOMPONENTBITS 0x1c
> +#define COLORCOMPONENTSHIFT 0x20
> +#define LAYEROFFSET 0x24
> +#define CLIPWINDOWOFFSET 0x28
> +#define CLIPWINDOWDIMENSIONS 0x2c
> +#define CONSTANTCOLOR 0x30
> +#define LAYERPROPERTY 0x34
> #define FRAMEDIMENSIONS 0x150
> #define CONTROL 0x170
>
> @@ -130,6 +133,7 @@ static int dc_fw_bind(struct device *dev, struct device *master, void *data)
> struct resource *res_pec;
> void __iomem *base_pec;
> void __iomem *base_cfg;
> + unsigned int off;
> struct dc_fw *fw;
> struct dc_fu *fu;
> int i, id;
> @@ -167,16 +171,17 @@ static int dc_fw_bind(struct device *dev, struct device *master, void *data)
> fu->link_id = LINK_ID_FETCHWARP2;
> fu->id = DC_FETCHUNIT_FW2;
> for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
> - fu->reg_baseaddr[i] = BASEADDRESS(i);
> - fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES(i);
> - fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION(i);
> - fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS(i);
> - fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT(i);
> - fu->reg_layeroffset[i] = LAYEROFFSET(i);
> - fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET(i);
> - fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS(i);
> - fu->reg_constantcolor[i] = CONSTANTCOLOR(i);
> - fu->reg_layerproperty[i] = LAYERPROPERTY(i);
> + off = i * FRAC_OFFSET;
> + fu->reg_baseaddr[i] = BASEADDRESS + off;
> + fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES + off;
> + fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION + off;
> + fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS + off;
> + fu->reg_colorcomponentshift[i] = COLORCOMPONENTSHIFT + off;
> + fu->reg_layeroffset[i] = LAYEROFFSET + off;
> + fu->reg_clipwindowoffset[i] = CLIPWINDOWOFFSET + off;
> + fu->reg_clipwindowdimensions[i] = CLIPWINDOWDIMENSIONS + off;
> + fu->reg_constantcolor[i] = CONSTANTCOLOR + off;
> + fu->reg_layerproperty[i] = LAYERPROPERTY + off;
> }
> fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
> fu->reg_framedimensions = FRAMEDIMENSIONS;
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 15/39] drm/imx: dc: fu: Pass struct dc_fu_subdev_match_data via OF match data
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (13 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 14/39] drm/imx: dc: fu: Inline FRAC_OFFSET into FetchLayer and FetchWrap Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:43 ` Frank Li
2025-10-11 16:51 ` [PATCH 16/39] drm/imx: dc: lb: Pass struct dc_lb_subdev_match_data " Marek Vasut
` (25 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Introduce struct dc_fu_subdev_match_data which describes the differences
between i.MX8QXP and i.MX95, which in this case register offsets as well
as address space offsets, and pass it as OF match data into the driver, so
the driver can use the match data to correctly access registers on each SoC.
This is a preparatory patch for i.MX95 addition. No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-fl.c | 61 +++++++++++++++++++++++-----------
1 file changed, 41 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
index a76825dc75fe1..53647e3a395b4 100644
--- a/drivers/gpu/drm/imx/dc/dc-fl.c
+++ b/drivers/gpu/drm/imx/dc/dc-fl.c
@@ -15,8 +15,6 @@
#include "dc-drv.h"
#include "dc-fu.h"
-#define FRAC_OFFSET 0x28
-
#define BURSTBUFFERMANAGEMENT 0xc
#define BASEADDRESS 0x10
#define SOURCEBUFFERATTRIBUTES 0x14
@@ -28,35 +26,55 @@
#define CLIPWINDOWDIMENSIONS 0x2c
#define CONSTANTCOLOR 0x30
#define LAYERPROPERTY 0x34
-#define FRAMEDIMENSIONS 0x150
+#define FRAMEDIMENSIONS_IMX8QXP 0x150
struct dc_fl {
struct dc_fu fu;
};
-static const struct dc_subdev_info dc_fl_info[] = {
+struct dc_fl_subdev_match_data {
+ const struct regmap_config *regmap_config;
+ unsigned int reg_offset_bbm;
+ unsigned int reg_offset_base;
+ unsigned int reg_offset_rest;
+ unsigned int reg_framedimensions;
+ unsigned int reg_frac_offset;
+ const struct dc_subdev_info *info;
+};
+
+static const struct dc_subdev_info dc_fl_info_imx8qxp[] = {
{ .reg_start = 0x56180ac0, .id = 0, },
{ /* sentinel */ },
};
-static const struct regmap_range dc_fl_regmap_ranges[] = {
- regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS),
+static const struct regmap_range dc_fl_regmap_ranges_imx8qxp[] = {
+ regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS_IMX8QXP),
};
-static const struct regmap_access_table dc_fl_regmap_access_table = {
- .yes_ranges = dc_fl_regmap_ranges,
- .n_yes_ranges = ARRAY_SIZE(dc_fl_regmap_ranges),
+static const struct regmap_access_table dc_fl_regmap_access_table_imx8qxp = {
+ .yes_ranges = dc_fl_regmap_ranges_imx8qxp,
+ .n_yes_ranges = ARRAY_SIZE(dc_fl_regmap_ranges_imx8qxp),
};
-static const struct regmap_config dc_fl_cfg_regmap_config = {
+static const struct regmap_config dc_fl_cfg_regmap_config_imx8qxp = {
.name = "cfg",
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.fast_io = true,
- .wr_table = &dc_fl_regmap_access_table,
- .rd_table = &dc_fl_regmap_access_table,
- .max_register = FRAMEDIMENSIONS,
+ .wr_table = &dc_fl_regmap_access_table_imx8qxp,
+ .rd_table = &dc_fl_regmap_access_table_imx8qxp,
+ .max_register = FRAMEDIMENSIONS_IMX8QXP,
+};
+
+static const struct dc_fl_subdev_match_data dc_fl_match_data_imx8qxp = {
+ .regmap_config = &dc_fl_cfg_regmap_config_imx8qxp,
+ .reg_offset_bbm = 0,
+ .reg_offset_base = 0,
+ .reg_offset_rest = 0,
+ .reg_framedimensions = FRAMEDIMENSIONS_IMX8QXP,
+ .reg_frac_offset = 0x28,
+ .info = dc_fl_info_imx8qxp,
};
static void dc_fl_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
@@ -99,9 +117,11 @@ static void dc_fl_set_ops(struct dc_fu *fu)
static int dc_fl_bind(struct device *dev, struct device *master, void *data)
{
+ const struct dc_fl_subdev_match_data *dc_fl_match_data = device_get_match_data(dev);
+ const struct dc_subdev_info *dc_fl_info = dc_fl_match_data->info;
struct platform_device *pdev = to_platform_device(dev);
struct dc_drm_device *dc_drm = data;
- unsigned int off_base, off_regs;
+ unsigned int off, off_base, off_regs;
struct resource *res_pec;
void __iomem *base_cfg;
struct dc_fl *fl;
@@ -121,7 +141,7 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(base_cfg);
fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
- &dc_fl_cfg_regmap_config);
+ dc_fl_match_data->regmap_config);
if (IS_ERR(fu->reg_cfg))
return PTR_ERR(fu->reg_cfg);
@@ -134,9 +154,10 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
fu->link_id = LINK_ID_FETCHLAYER0;
fu->id = DC_FETCHUNIT_FL0;
for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
- off_base = i * FRAC_OFFSET;
+ off = i * dc_fl_match_data->reg_frac_offset;
+ off_base = off + dc_fl_match_data->reg_offset_base;
fu->reg_baseaddr[i] = BASEADDRESS + off_base;
- off_regs = i * FRAC_OFFSET;
+ off_regs = off + dc_fl_match_data->reg_offset_rest;
fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES + off_regs;
fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION + off_regs;
fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS + off_regs;
@@ -147,8 +168,8 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
fu->reg_constantcolor[i] = CONSTANTCOLOR + off_regs;
fu->reg_layerproperty[i] = LAYERPROPERTY + off_regs;
}
- fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
- fu->reg_framedimensions = FRAMEDIMENSIONS;
+ fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT + dc_fl_match_data->reg_offset_bbm;
+ fu->reg_framedimensions = dc_fl_match_data->reg_framedimensions;
snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", id);
dc_fl_set_ops(fu);
@@ -180,7 +201,7 @@ static void dc_fl_remove(struct platform_device *pdev)
}
static const struct of_device_id dc_fl_dt_ids[] = {
- { .compatible = "fsl,imx8qxp-dc-fetchlayer" },
+ { .compatible = "fsl,imx8qxp-dc-fetchlayer", .data = &dc_fl_match_data_imx8qxp },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_fl_dt_ids);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 15/39] drm/imx: dc: fu: Pass struct dc_fu_subdev_match_data via OF match data
2025-10-11 16:51 ` [PATCH 15/39] drm/imx: dc: fu: Pass struct dc_fu_subdev_match_data via OF match data Marek Vasut
@ 2025-10-13 18:43 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:43 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:30PM +0200, Marek Vasut wrote:
> Introduce struct dc_fu_subdev_match_data which describes the differences
> between i.MX8QXP and i.MX95, which in this case register offsets as well
> as address space offsets, and pass it as OF match data into the driver, so
> the driver can use the match data to correctly access registers on each SoC.
> This is a preparatory patch for i.MX95 addition. No functional change.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-fl.c | 61 +++++++++++++++++++++++-----------
> 1 file changed, 41 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
> index a76825dc75fe1..53647e3a395b4 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fl.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fl.c
> @@ -15,8 +15,6 @@
> #include "dc-drv.h"
> #include "dc-fu.h"
>
> -#define FRAC_OFFSET 0x28
> -
> #define BURSTBUFFERMANAGEMENT 0xc
> #define BASEADDRESS 0x10
> #define SOURCEBUFFERATTRIBUTES 0x14
> @@ -28,35 +26,55 @@
> #define CLIPWINDOWDIMENSIONS 0x2c
> #define CONSTANTCOLOR 0x30
> #define LAYERPROPERTY 0x34
> -#define FRAMEDIMENSIONS 0x150
> +#define FRAMEDIMENSIONS_IMX8QXP 0x150
>
> struct dc_fl {
> struct dc_fu fu;
> };
>
> -static const struct dc_subdev_info dc_fl_info[] = {
> +struct dc_fl_subdev_match_data {
> + const struct regmap_config *regmap_config;
> + unsigned int reg_offset_bbm;
> + unsigned int reg_offset_base;
> + unsigned int reg_offset_rest;
> + unsigned int reg_framedimensions;
> + unsigned int reg_frac_offset;
> + const struct dc_subdev_info *info;
> +};
> +
> +static const struct dc_subdev_info dc_fl_info_imx8qxp[] = {
> { .reg_start = 0x56180ac0, .id = 0, },
> { /* sentinel */ },
> };
>
> -static const struct regmap_range dc_fl_regmap_ranges[] = {
> - regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS),
> +static const struct regmap_range dc_fl_regmap_ranges_imx8qxp[] = {
> + regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS_IMX8QXP),
> };
>
> -static const struct regmap_access_table dc_fl_regmap_access_table = {
> - .yes_ranges = dc_fl_regmap_ranges,
> - .n_yes_ranges = ARRAY_SIZE(dc_fl_regmap_ranges),
> +static const struct regmap_access_table dc_fl_regmap_access_table_imx8qxp = {
> + .yes_ranges = dc_fl_regmap_ranges_imx8qxp,
> + .n_yes_ranges = ARRAY_SIZE(dc_fl_regmap_ranges_imx8qxp),
> };
>
> -static const struct regmap_config dc_fl_cfg_regmap_config = {
> +static const struct regmap_config dc_fl_cfg_regmap_config_imx8qxp = {
> .name = "cfg",
> .reg_bits = 32,
> .reg_stride = 4,
> .val_bits = 32,
> .fast_io = true,
> - .wr_table = &dc_fl_regmap_access_table,
> - .rd_table = &dc_fl_regmap_access_table,
> - .max_register = FRAMEDIMENSIONS,
> + .wr_table = &dc_fl_regmap_access_table_imx8qxp,
> + .rd_table = &dc_fl_regmap_access_table_imx8qxp,
> + .max_register = FRAMEDIMENSIONS_IMX8QXP,
> +};
> +
> +static const struct dc_fl_subdev_match_data dc_fl_match_data_imx8qxp = {
> + .regmap_config = &dc_fl_cfg_regmap_config_imx8qxp,
> + .reg_offset_bbm = 0,
> + .reg_offset_base = 0,
> + .reg_offset_rest = 0,
> + .reg_framedimensions = FRAMEDIMENSIONS_IMX8QXP,
> + .reg_frac_offset = 0x28,
> + .info = dc_fl_info_imx8qxp,
> };
>
> static void dc_fl_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
> @@ -99,9 +117,11 @@ static void dc_fl_set_ops(struct dc_fu *fu)
>
> static int dc_fl_bind(struct device *dev, struct device *master, void *data)
> {
> + const struct dc_fl_subdev_match_data *dc_fl_match_data = device_get_match_data(dev);
> + const struct dc_subdev_info *dc_fl_info = dc_fl_match_data->info;
> struct platform_device *pdev = to_platform_device(dev);
> struct dc_drm_device *dc_drm = data;
> - unsigned int off_base, off_regs;
> + unsigned int off, off_base, off_regs;
> struct resource *res_pec;
> void __iomem *base_cfg;
> struct dc_fl *fl;
> @@ -121,7 +141,7 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
> return PTR_ERR(base_cfg);
>
> fu->reg_cfg = devm_regmap_init_mmio(dev, base_cfg,
> - &dc_fl_cfg_regmap_config);
> + dc_fl_match_data->regmap_config);
> if (IS_ERR(fu->reg_cfg))
> return PTR_ERR(fu->reg_cfg);
>
> @@ -134,9 +154,10 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
> fu->link_id = LINK_ID_FETCHLAYER0;
> fu->id = DC_FETCHUNIT_FL0;
> for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
> - off_base = i * FRAC_OFFSET;
> + off = i * dc_fl_match_data->reg_frac_offset;
> + off_base = off + dc_fl_match_data->reg_offset_base;
> fu->reg_baseaddr[i] = BASEADDRESS + off_base;
> - off_regs = i * FRAC_OFFSET;
> + off_regs = off + dc_fl_match_data->reg_offset_rest;
> fu->reg_sourcebufferattributes[i] = SOURCEBUFFERATTRIBUTES + off_regs;
> fu->reg_sourcebufferdimension[i] = SOURCEBUFFERDIMENSION + off_regs;
> fu->reg_colorcomponentbits[i] = COLORCOMPONENTBITS + off_regs;
> @@ -147,8 +168,8 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
> fu->reg_constantcolor[i] = CONSTANTCOLOR + off_regs;
> fu->reg_layerproperty[i] = LAYERPROPERTY + off_regs;
> }
> - fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT;
> - fu->reg_framedimensions = FRAMEDIMENSIONS;
> + fu->reg_burstbuffermanagement = BURSTBUFFERMANAGEMENT + dc_fl_match_data->reg_offset_bbm;
> + fu->reg_framedimensions = dc_fl_match_data->reg_framedimensions;
> snprintf(fu->name, sizeof(fu->name), "FetchLayer%d", id);
>
> dc_fl_set_ops(fu);
> @@ -180,7 +201,7 @@ static void dc_fl_remove(struct platform_device *pdev)
> }
>
> static const struct of_device_id dc_fl_dt_ids[] = {
> - { .compatible = "fsl,imx8qxp-dc-fetchlayer" },
> + { .compatible = "fsl,imx8qxp-dc-fetchlayer", .data = &dc_fl_match_data_imx8qxp },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_fl_dt_ids);
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 16/39] drm/imx: dc: lb: Pass struct dc_lb_subdev_match_data via OF match data
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (14 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 15/39] drm/imx: dc: fu: Pass struct dc_fu_subdev_match_data via OF match data Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:45 ` Frank Li
2025-10-11 16:51 ` [PATCH 17/39] drm/imx: dc: tc: Pass struct dc_tc_subdev_match_data " Marek Vasut
` (24 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Introduce struct dc_lb_subdev_match_data which describes the differences
between i.MX8QXP and i.MX95, which in this case link ID mapping as well
as address space offsets, and pass it as OF match data into the driver, so
the driver can use the match data to correctly select pixel data routing.
This is a preparatory patch for i.MX95 addition. No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-lb.c | 42 ++++++++++++++++++++++++++--------
drivers/gpu/drm/imx/dc/dc-pe.h | 3 +++
2 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
index 619353456743c..ba9183b244ab3 100644
--- a/drivers/gpu/drm/imx/dc/dc-lb.c
+++ b/drivers/gpu/drm/imx/dc/dc-lb.c
@@ -56,6 +56,14 @@
#define YPOS_MASK GENMASK(31, 16)
#define YPOS(x) FIELD_PREP(YPOS_MASK, (x))
+struct dc_lb_subdev_match_data {
+ const enum dc_link_id *pri_sels;
+ const enum dc_link_id *sec_sels;
+ const enum dc_link_id first_lb;
+ unsigned int last_cf;
+ const struct dc_subdev_info *info;
+};
+
enum dc_lb_blend_func {
DC_LAYERBLEND_BLEND_ZERO,
DC_LAYERBLEND_BLEND_ONE,
@@ -119,7 +127,7 @@ static const struct regmap_config dc_lb_cfg_regmap_config = {
.max_register = POSITION,
};
-static const enum dc_link_id prim_sels[] = {
+static const enum dc_link_id prim_sels_imx8qxp[] = {
/* common options */
LINK_ID_NONE,
LINK_ID_CONSTFRAME0,
@@ -137,12 +145,22 @@ static const enum dc_link_id prim_sels[] = {
LINK_ID_LAYERBLEND1_MX8QXP,
LINK_ID_LAYERBLEND2_MX8QXP,
LINK_ID_LAYERBLEND3_MX8QXP,
+ LINK_ID_LAST
};
-static const enum dc_link_id sec_sels[] = {
+static const enum dc_link_id sec_sels_imx8qxp[] = {
LINK_ID_NONE,
LINK_ID_FETCHWARP2,
LINK_ID_FETCHLAYER0,
+ LINK_ID_LAST
+};
+
+static const struct dc_lb_subdev_match_data dc_lb_match_data_imx8qxp = {
+ .pri_sels = prim_sels_imx8qxp,
+ .sec_sels = sec_sels_imx8qxp,
+ .first_lb = LINK_ID_LAYERBLEND0_MX8QXP,
+ .last_cf = 5,
+ .info = dc_lb_info_imx8qxp,
};
enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
@@ -152,11 +170,10 @@ enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim)
{
- int fixed_sels_num = ARRAY_SIZE(prim_sels) - 4;
int i;
- for (i = 0; i < fixed_sels_num + lb->id; i++) {
- if (prim_sels[i] == prim) {
+ for (i = 0; i < lb->last_cf + lb->id; i++) {
+ if (lb->pri_sels[i] == prim) {
regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
PIXENGCFG_DYNAMIC_PRIM_SEL_MASK,
PIXENGCFG_DYNAMIC_PRIM_SEL(prim));
@@ -169,10 +186,10 @@ void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim)
void dc_lb_pec_dynamic_sec_sel(struct dc_lb *lb, enum dc_link_id sec)
{
- int i;
+ int i = 0;
- for (i = 0; i < ARRAY_SIZE(sec_sels); i++) {
- if (sec_sels[i] == sec) {
+ while (lb->sec_sels[i] != LINK_ID_LAST) {
+ if (lb->sec_sels[i++] == sec) {
regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
PIXENGCFG_DYNAMIC_SEC_SEL_MASK,
PIXENGCFG_DYNAMIC_SEC_SEL(sec));
@@ -245,6 +262,8 @@ void dc_lb_init(struct dc_lb *lb)
static int dc_lb_bind(struct device *dev, struct device *master, void *data)
{
+ const struct dc_lb_subdev_match_data *dc_lb_match_data = device_get_match_data(dev);
+ const struct dc_subdev_info *dc_lb_info = dc_lb_match_data->info;
struct platform_device *pdev = to_platform_device(dev);
struct dc_drm_device *dc_drm = data;
struct resource *res_pec;
@@ -281,7 +300,10 @@ static int dc_lb_bind(struct device *dev, struct device *master, void *data)
}
lb->dev = dev;
- lb->link = LINK_ID_LAYERBLEND0_MX8QXP + lb->id;
+ lb->link = dc_lb_match_data->first_lb + lb->id;
+ lb->pri_sels = dc_lb_match_data->pri_sels;
+ lb->sec_sels = dc_lb_match_data->sec_sels;
+ lb->last_cf = dc_lb_match_data->last_cf;
dc_drm->lb[lb->id] = lb;
@@ -310,7 +332,7 @@ static void dc_lb_remove(struct platform_device *pdev)
}
static const struct of_device_id dc_lb_dt_ids[] = {
- { .compatible = "fsl,imx8qxp-dc-layerblend" },
+ { .compatible = "fsl,imx8qxp-dc-layerblend", .data = &dc_lb_match_data_imx8qxp },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_lb_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
index 7928f947b0cef..492d193127bc1 100644
--- a/drivers/gpu/drm/imx/dc/dc-pe.h
+++ b/drivers/gpu/drm/imx/dc/dc-pe.h
@@ -65,6 +65,9 @@ struct dc_lb {
struct regmap *reg_cfg;
int id;
enum dc_link_id link;
+ const enum dc_link_id *pri_sels;
+ const enum dc_link_id *sec_sels;
+ unsigned int last_cf;
};
struct dc_pe {
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 16/39] drm/imx: dc: lb: Pass struct dc_lb_subdev_match_data via OF match data
2025-10-11 16:51 ` [PATCH 16/39] drm/imx: dc: lb: Pass struct dc_lb_subdev_match_data " Marek Vasut
@ 2025-10-13 18:45 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:45 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:31PM +0200, Marek Vasut wrote:
> Introduce struct dc_lb_subdev_match_data which describes the differences
> between i.MX8QXP and i.MX95, which in this case link ID mapping as well
> as address space offsets, and pass it as OF match data into the driver, so
> the driver can use the match data to correctly select pixel data routing.
> This is a preparatory patch for i.MX95 addition. No functional change.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-lb.c | 42 ++++++++++++++++++++++++++--------
> drivers/gpu/drm/imx/dc/dc-pe.h | 3 +++
> 2 files changed, 35 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
> index 619353456743c..ba9183b244ab3 100644
> --- a/drivers/gpu/drm/imx/dc/dc-lb.c
> +++ b/drivers/gpu/drm/imx/dc/dc-lb.c
> @@ -56,6 +56,14 @@
> #define YPOS_MASK GENMASK(31, 16)
> #define YPOS(x) FIELD_PREP(YPOS_MASK, (x))
>
> +struct dc_lb_subdev_match_data {
> + const enum dc_link_id *pri_sels;
> + const enum dc_link_id *sec_sels;
> + const enum dc_link_id first_lb;
> + unsigned int last_cf;
> + const struct dc_subdev_info *info;
> +};
> +
> enum dc_lb_blend_func {
> DC_LAYERBLEND_BLEND_ZERO,
> DC_LAYERBLEND_BLEND_ONE,
> @@ -119,7 +127,7 @@ static const struct regmap_config dc_lb_cfg_regmap_config = {
> .max_register = POSITION,
> };
>
> -static const enum dc_link_id prim_sels[] = {
> +static const enum dc_link_id prim_sels_imx8qxp[] = {
> /* common options */
> LINK_ID_NONE,
> LINK_ID_CONSTFRAME0,
> @@ -137,12 +145,22 @@ static const enum dc_link_id prim_sels[] = {
> LINK_ID_LAYERBLEND1_MX8QXP,
> LINK_ID_LAYERBLEND2_MX8QXP,
> LINK_ID_LAYERBLEND3_MX8QXP,
> + LINK_ID_LAST
> };
>
> -static const enum dc_link_id sec_sels[] = {
> +static const enum dc_link_id sec_sels_imx8qxp[] = {
> LINK_ID_NONE,
> LINK_ID_FETCHWARP2,
> LINK_ID_FETCHLAYER0,
> + LINK_ID_LAST
> +};
> +
> +static const struct dc_lb_subdev_match_data dc_lb_match_data_imx8qxp = {
> + .pri_sels = prim_sels_imx8qxp,
> + .sec_sels = sec_sels_imx8qxp,
> + .first_lb = LINK_ID_LAYERBLEND0_MX8QXP,
> + .last_cf = 5,
> + .info = dc_lb_info_imx8qxp,
> };
>
> enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
> @@ -152,11 +170,10 @@ enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
>
> void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim)
> {
> - int fixed_sels_num = ARRAY_SIZE(prim_sels) - 4;
> int i;
>
> - for (i = 0; i < fixed_sels_num + lb->id; i++) {
> - if (prim_sels[i] == prim) {
> + for (i = 0; i < lb->last_cf + lb->id; i++) {
> + if (lb->pri_sels[i] == prim) {
> regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
> PIXENGCFG_DYNAMIC_PRIM_SEL_MASK,
> PIXENGCFG_DYNAMIC_PRIM_SEL(prim));
> @@ -169,10 +186,10 @@ void dc_lb_pec_dynamic_prim_sel(struct dc_lb *lb, enum dc_link_id prim)
>
> void dc_lb_pec_dynamic_sec_sel(struct dc_lb *lb, enum dc_link_id sec)
> {
> - int i;
> + int i = 0;
>
> - for (i = 0; i < ARRAY_SIZE(sec_sels); i++) {
> - if (sec_sels[i] == sec) {
> + while (lb->sec_sels[i] != LINK_ID_LAST) {
> + if (lb->sec_sels[i++] == sec) {
> regmap_write_bits(lb->reg_pec, PIXENGCFG_DYNAMIC,
> PIXENGCFG_DYNAMIC_SEC_SEL_MASK,
> PIXENGCFG_DYNAMIC_SEC_SEL(sec));
> @@ -245,6 +262,8 @@ void dc_lb_init(struct dc_lb *lb)
>
> static int dc_lb_bind(struct device *dev, struct device *master, void *data)
> {
> + const struct dc_lb_subdev_match_data *dc_lb_match_data = device_get_match_data(dev);
> + const struct dc_subdev_info *dc_lb_info = dc_lb_match_data->info;
> struct platform_device *pdev = to_platform_device(dev);
> struct dc_drm_device *dc_drm = data;
> struct resource *res_pec;
> @@ -281,7 +300,10 @@ static int dc_lb_bind(struct device *dev, struct device *master, void *data)
> }
>
> lb->dev = dev;
> - lb->link = LINK_ID_LAYERBLEND0_MX8QXP + lb->id;
> + lb->link = dc_lb_match_data->first_lb + lb->id;
> + lb->pri_sels = dc_lb_match_data->pri_sels;
> + lb->sec_sels = dc_lb_match_data->sec_sels;
> + lb->last_cf = dc_lb_match_data->last_cf;
>
> dc_drm->lb[lb->id] = lb;
>
> @@ -310,7 +332,7 @@ static void dc_lb_remove(struct platform_device *pdev)
> }
>
> static const struct of_device_id dc_lb_dt_ids[] = {
> - { .compatible = "fsl,imx8qxp-dc-layerblend" },
> + { .compatible = "fsl,imx8qxp-dc-layerblend", .data = &dc_lb_match_data_imx8qxp },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_lb_dt_ids);
> diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
> index 7928f947b0cef..492d193127bc1 100644
> --- a/drivers/gpu/drm/imx/dc/dc-pe.h
> +++ b/drivers/gpu/drm/imx/dc/dc-pe.h
> @@ -65,6 +65,9 @@ struct dc_lb {
> struct regmap *reg_cfg;
> int id;
> enum dc_link_id link;
> + const enum dc_link_id *pri_sels;
> + const enum dc_link_id *sec_sels;
> + unsigned int last_cf;
Direct use pointer to dc_lb_subdev_match_data to avoid copy data to here.
Frank
> };
>
> struct dc_pe {
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 17/39] drm/imx: dc: tc: Pass struct dc_tc_subdev_match_data via OF match data
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (15 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 16/39] drm/imx: dc: lb: Pass struct dc_lb_subdev_match_data " Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-11 16:51 ` [PATCH 18/39] drm/imx: dc: ic: Pass struct dc_ic_subdev_match_data " Marek Vasut
` (23 subsequent siblings)
40 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Introduce struct dc_tc_subdev_match_data which describes the differences
between i.MX8QXP and i.MX95, which in this case need for configuration
and address space offsets, and pass it as OF match data into the driver, so
the driver can use the match data to optionally configure the TCON.
This is a preparatory patch for i.MX95 addition. No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-de.h | 1 +
drivers/gpu/drm/imx/dc/dc-tc.c | 40 ++++++++++++++++++++++++++--------
2 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-de.h b/drivers/gpu/drm/imx/dc/dc-de.h
index 797056a09ddb4..e74368aacf553 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.h
+++ b/drivers/gpu/drm/imx/dc/dc-de.h
@@ -32,6 +32,7 @@ struct dc_fg {
struct dc_tc {
struct device *dev;
struct regmap *reg;
+ bool need_config;
};
struct dc_de {
diff --git a/drivers/gpu/drm/imx/dc/dc-tc.c b/drivers/gpu/drm/imx/dc/dc-tc.c
index f44b68c0a5e6d..1f287706e8706 100644
--- a/drivers/gpu/drm/imx/dc/dc-tc.c
+++ b/drivers/gpu/drm/imx/dc/dc-tc.c
@@ -7,6 +7,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include "dc-drv.h"
@@ -25,7 +26,12 @@
#define MAPBIT27_24 0x430
#define MAPBIT31_28 0x434
-static const struct dc_subdev_info dc_tc_info[] = {
+struct dc_tc_subdev_match_data {
+ bool need_config;
+ const struct dc_subdev_info *info;
+};
+
+static const struct dc_subdev_info dc_tc_info_imx8qxp[] = {
{ .reg_start = 0x5618c800, .id = 0, },
{ .reg_start = 0x5618e400, .id = 1, },
{ /* sentinel */ },
@@ -61,8 +67,16 @@ static const u32 dc_tc_mapbit[] = {
0x13121110, 0x03020100, 0x07060504, 0x00000908,
};
+static const struct dc_tc_subdev_match_data dc_tc_match_data_imx8qxp = {
+ .need_config = true,
+ .info = dc_tc_info_imx8qxp,
+};
+
void dc_tc_init(struct dc_tc *tc)
{
+ if (!tc->need_config)
+ return;
+
/* reset TCON_CTRL to POR default so that TCON works in bypass mode */
regmap_write(tc->reg, TCON_CTRL, CTRL_RST_VAL);
@@ -73,6 +87,8 @@ void dc_tc_init(struct dc_tc *tc)
static int dc_tc_bind(struct device *dev, struct device *master, void *data)
{
+ const struct dc_tc_subdev_match_data *dc_tc_match_data = device_get_match_data(dev);
+ const struct dc_subdev_info *dc_tc_info = dc_tc_match_data->info;
struct platform_device *pdev = to_platform_device(dev);
struct dc_drm_device *dc_drm = data;
struct resource *res;
@@ -84,13 +100,19 @@ static int dc_tc_bind(struct device *dev, struct device *master, void *data)
if (!tc)
return -ENOMEM;
- base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(base))
- return PTR_ERR(base);
-
- tc->reg = devm_regmap_init_mmio(dev, base, &dc_tc_regmap_config);
- if (IS_ERR(tc->reg))
- return PTR_ERR(tc->reg);
+ if (dc_tc_match_data->need_config) {
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ tc->reg = devm_regmap_init_mmio(dev, base, &dc_tc_regmap_config);
+ if (IS_ERR(tc->reg))
+ return PTR_ERR(tc->reg);
+ } else {
+ res = platform_get_resource(to_platform_device(pdev->dev.parent), IORESOURCE_MEM, 0);
+ if (IS_ERR(res))
+ return PTR_ERR(res);
+ }
id = dc_subdev_get_id(dc_tc_info, res);
if (id < 0) {
@@ -126,7 +148,7 @@ static void dc_tc_remove(struct platform_device *pdev)
}
static const struct of_device_id dc_tc_dt_ids[] = {
- { .compatible = "fsl,imx8qxp-dc-tcon" },
+ { .compatible = "fsl,imx8qxp-dc-tcon", .data = &dc_tc_match_data_imx8qxp },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_tc_dt_ids);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* [PATCH 18/39] drm/imx: dc: ic: Pass struct dc_ic_subdev_match_data via OF match data
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (16 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 17/39] drm/imx: dc: tc: Pass struct dc_tc_subdev_match_data " Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-11 16:51 ` [PATCH 19/39] drm/imx: dc: ic: Use DT node as interrupt controller name Marek Vasut
` (22 subsequent siblings)
40 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Introduce struct dc_ic_subdev_match_data which describes the differences
between i.MX8QXP and i.MX95, which in this case is register map difference
and presence of user registers, and pass it as OF match data into the driver,
so the driver can use the match data to correctly set up the IRQ controller.
This is a preparatory patch for i.MX95 addition. No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-ic.c | 118 +++++++++++++++++++++------------
1 file changed, 76 insertions(+), 42 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
index 67441b349a7d2..f327ef0918766 100644
--- a/drivers/gpu/drm/imx/dc/dc-ic.c
+++ b/drivers/gpu/drm/imx/dc/dc-ic.c
@@ -24,16 +24,17 @@
#define USERINTERRUPTCLEAR(n) (0x50 + 4 * (n))
#define USERINTERRUPTSTATUS(n) (0x58 + 4 * (n))
-#define IRQ_COUNT 49
-#define IRQ_RESERVED 35
-#define REG_NUM 2
+#define IRQ_COUNT_MAX 49
+#define REG_NUM_MAX 2
struct dc_ic_data {
struct regmap *regs;
struct clk_bulk_data *clk_axi;
int clk_axi_count;
- int irq[IRQ_COUNT];
+ int irq[IRQ_COUNT_MAX];
struct irq_domain *domain;
+ unsigned int reg_enable;
+ unsigned int reg_status;
};
struct dc_ic_entry {
@@ -41,60 +42,85 @@ struct dc_ic_entry {
int irq;
};
-static const struct regmap_range dc_ic_regmap_write_ranges[] = {
+struct dc_ic_subdev_match_data {
+ const struct regmap_config *regmap_config;
+ unsigned int reg_enable;
+ unsigned int reg_clear;
+ unsigned int reg_status;
+ unsigned int reg_count;
+ unsigned int irq_count;
+ unsigned long unused_irq[REG_NUM_MAX];
+ int reserved_irq;
+ bool user_irq;
+};
+
+static const struct regmap_range dc_ic_regmap_write_ranges_imx8qxp[] = {
regmap_reg_range(USERINTERRUPTMASK(0), INTERRUPTCLEAR(1)),
regmap_reg_range(USERINTERRUPTENABLE(0), USERINTERRUPTCLEAR(1)),
};
-static const struct regmap_access_table dc_ic_regmap_write_table = {
- .yes_ranges = dc_ic_regmap_write_ranges,
- .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_write_ranges),
+static const struct regmap_access_table dc_ic_regmap_write_table_imx8qxp = {
+ .yes_ranges = dc_ic_regmap_write_ranges_imx8qxp,
+ .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_write_ranges_imx8qxp),
};
-static const struct regmap_range dc_ic_regmap_read_ranges[] = {
+static const struct regmap_range dc_ic_regmap_read_ranges_imx8qxp[] = {
regmap_reg_range(USERINTERRUPTMASK(0), INTERRUPTENABLE(1)),
regmap_reg_range(INTERRUPTSTATUS(0), INTERRUPTSTATUS(1)),
regmap_reg_range(USERINTERRUPTENABLE(0), USERINTERRUPTENABLE(1)),
regmap_reg_range(USERINTERRUPTSTATUS(0), USERINTERRUPTSTATUS(1)),
};
-static const struct regmap_access_table dc_ic_regmap_read_table = {
- .yes_ranges = dc_ic_regmap_read_ranges,
- .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_read_ranges),
+static const struct regmap_access_table dc_ic_regmap_read_table_imx8qxp = {
+ .yes_ranges = dc_ic_regmap_read_ranges_imx8qxp,
+ .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_read_ranges_imx8qxp),
};
-static const struct regmap_range dc_ic_regmap_volatile_ranges[] = {
+static const struct regmap_range dc_ic_regmap_volatile_ranges_imx8qxp[] = {
regmap_reg_range(INTERRUPTPRESET(0), INTERRUPTCLEAR(1)),
regmap_reg_range(USERINTERRUPTPRESET(0), USERINTERRUPTCLEAR(1)),
};
-static const struct regmap_access_table dc_ic_regmap_volatile_table = {
- .yes_ranges = dc_ic_regmap_volatile_ranges,
- .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_volatile_ranges),
+static const struct regmap_access_table dc_ic_regmap_volatile_table_imx8qxp = {
+ .yes_ranges = dc_ic_regmap_volatile_ranges_imx8qxp,
+ .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_volatile_ranges_imx8qxp),
};
-static const struct regmap_config dc_ic_regmap_config = {
+static const struct regmap_config dc_ic_regmap_config_imx8qxp = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.fast_io = true,
- .wr_table = &dc_ic_regmap_write_table,
- .rd_table = &dc_ic_regmap_read_table,
- .volatile_table = &dc_ic_regmap_volatile_table,
+ .wr_table = &dc_ic_regmap_write_table_imx8qxp,
+ .rd_table = &dc_ic_regmap_read_table_imx8qxp,
+ .volatile_table = &dc_ic_regmap_volatile_table_imx8qxp,
.max_register = USERINTERRUPTSTATUS(1),
};
+static const struct dc_ic_subdev_match_data dc_ic_match_data_imx8qxp = {
+ .regmap_config = &dc_ic_regmap_config_imx8qxp,
+ .reg_enable = USERINTERRUPTENABLE(0),
+ .reg_clear = USERINTERRUPTCLEAR(0),
+ .reg_status = USERINTERRUPTSTATUS(0),
+ .reg_count = 2,
+ .irq_count = 49,
+ .user_irq = true,
+ .unused_irq = { 0x00000000, 0xfffe0008 },
+ .reserved_irq = 35,
+};
+
static void dc_ic_irq_handler(struct irq_desc *desc)
{
struct dc_ic_entry *entry = irq_desc_get_handler_data(desc);
struct dc_ic_data *data = entry->data;
- unsigned int status, enable;
+ unsigned int status, enable, offset;
unsigned int virq;
chained_irq_enter(irq_desc_get_chip(desc), desc);
- regmap_read(data->regs, USERINTERRUPTSTATUS(entry->irq / 32), &status);
- regmap_read(data->regs, USERINTERRUPTENABLE(entry->irq / 32), &enable);
+ offset = entry->irq / 32;
+ regmap_read(data->regs, data->reg_status + 4 * offset, &status);
+ regmap_read(data->regs, data->reg_enable + 4 * offset, &enable);
status &= enable;
@@ -107,11 +133,10 @@ static void dc_ic_irq_handler(struct irq_desc *desc)
chained_irq_exit(irq_desc_get_chip(desc), desc);
}
-static const unsigned long unused_irq[REG_NUM] = {0x00000000, 0xfffe0008};
-
static int dc_ic_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ const struct dc_ic_subdev_match_data *dc_ic_match_data = device_get_match_data(dev);
struct irq_chip_generic *gc;
struct dc_ic_entry *entry;
struct irq_chip_type *ct;
@@ -123,7 +148,7 @@ static int dc_ic_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
- entry = devm_kcalloc(dev, IRQ_COUNT, sizeof(*entry), GFP_KERNEL);
+ entry = devm_kcalloc(dev, dc_ic_match_data->irq_count, sizeof(*entry), GFP_KERNEL);
if (!entry)
return -ENOMEM;
@@ -133,7 +158,7 @@ static int dc_ic_probe(struct platform_device *pdev)
return PTR_ERR(base);
}
- data->regs = devm_regmap_init_mmio(dev, base, &dc_ic_regmap_config);
+ data->regs = devm_regmap_init_mmio(dev, base, dc_ic_match_data->regmap_config);
if (IS_ERR(data->regs))
return PTR_ERR(data->regs);
@@ -143,9 +168,12 @@ static int dc_ic_probe(struct platform_device *pdev)
"failed to get AXI clock\n");
data->clk_axi_count = ret;
- for (i = 0; i < IRQ_COUNT; i++) {
+ data->reg_enable = dc_ic_match_data->reg_enable;
+ data->reg_status = dc_ic_match_data->reg_status;
+
+ for (i = 0; i < dc_ic_match_data->irq_count; i++) {
/* skip the reserved IRQ */
- if (i == IRQ_RESERVED)
+ if (i == dc_ic_match_data->reserved_irq)
continue;
ret = platform_get_irq(pdev, i);
@@ -165,18 +193,22 @@ static int dc_ic_probe(struct platform_device *pdev)
return ret;
}
- for (i = 0; i < REG_NUM; i++) {
+ for (i = 0; i < dc_ic_match_data->reg_count; i++) {
/* mask and clear all interrupts */
+ regmap_write(data->regs, dc_ic_match_data->reg_enable + (4 * i), 0x0);
+ regmap_write(data->regs, dc_ic_match_data->reg_clear + (4 * i), 0xffffffff);
+
+ if (!dc_ic_match_data->user_irq)
+ continue;
+
regmap_write(data->regs, USERINTERRUPTENABLE(i), 0x0);
- regmap_write(data->regs, INTERRUPTENABLE(i), 0x0);
regmap_write(data->regs, USERINTERRUPTCLEAR(i), 0xffffffff);
- regmap_write(data->regs, INTERRUPTCLEAR(i), 0xffffffff);
/* set all interrupts to user mode */
regmap_write(data->regs, USERINTERRUPTMASK(i), 0xffffffff);
}
- data->domain = irq_domain_add_linear(dev->of_node, IRQ_COUNT,
+ data->domain = irq_domain_add_linear(dev->of_node, dc_ic_match_data->irq_count,
&irq_generic_chip_ops, data);
if (!data->domain) {
dev_err(dev, "failed to create IRQ domain\n");
@@ -194,21 +226,21 @@ static int dc_ic_probe(struct platform_device *pdev)
return ret;
}
- for (i = 0; i < IRQ_COUNT; i += 32) {
+ for (i = 0; i < dc_ic_match_data->irq_count; i += 32) {
gc = irq_get_domain_generic_chip(data->domain, i);
gc->reg_base = base;
- gc->unused = unused_irq[i / 32];
+ gc->unused = dc_ic_match_data->unused_irq[i / 32];
ct = gc->chip_types;
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_clr_bit;
ct->chip.irq_unmask = irq_gc_mask_set_bit;
- ct->regs.ack = USERINTERRUPTCLEAR(i / 32);
- ct->regs.mask = USERINTERRUPTENABLE(i / 32);
+ ct->regs.ack = dc_ic_match_data->reg_clear + (i / 8);
+ ct->regs.mask = dc_ic_match_data->reg_enable + (i / 8);
}
- for (i = 0; i < IRQ_COUNT; i++) {
+ for (i = 0; i < dc_ic_match_data->irq_count; i++) {
/* skip the reserved IRQ */
- if (i == IRQ_RESERVED)
+ if (i == dc_ic_match_data->reserved_irq)
continue;
data->irq[i] = irq_of_parse_and_map(dev->of_node, i);
@@ -225,11 +257,13 @@ static int dc_ic_probe(struct platform_device *pdev)
static void dc_ic_remove(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
+ const struct dc_ic_subdev_match_data *dc_ic_match_data = device_get_match_data(dev);
struct dc_ic_data *data = dev_get_drvdata(&pdev->dev);
int i;
- for (i = 0; i < IRQ_COUNT; i++) {
- if (i == IRQ_RESERVED)
+ for (i = 0; i < dc_ic_match_data->irq_count; i++) {
+ if (i == dc_ic_match_data->reserved_irq)
continue;
irq_set_chained_handler_and_data(data->irq[i], NULL, NULL);
@@ -268,7 +302,7 @@ static const struct dev_pm_ops dc_ic_pm_ops = {
};
static const struct of_device_id dc_ic_dt_ids[] = {
- { .compatible = "fsl,imx8qxp-dc-intc", },
+ { .compatible = "fsl,imx8qxp-dc-intc", .data = &dc_ic_match_data_imx8qxp },
{ /* sentinel */ }
};
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* [PATCH 19/39] drm/imx: dc: ic: Use DT node as interrupt controller name
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (17 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 18/39] drm/imx: dc: ic: Pass struct dc_ic_subdev_match_data " Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-11 16:51 ` [PATCH 20/39] drm/imx: dc: Configure display CSR clock feed select Marek Vasut
` (21 subsequent siblings)
40 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
The DC on i.MX95 contains multiple interrupt controllers,
use DT node name as interrupt controller name to tell them
apart.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-ic.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
index f327ef0918766..c3d7e5aa4ae23 100644
--- a/drivers/gpu/drm/imx/dc/dc-ic.c
+++ b/drivers/gpu/drm/imx/dc/dc-ic.c
@@ -217,7 +217,8 @@ static int dc_ic_probe(struct platform_device *pdev)
}
irq_domain_set_pm_device(data->domain, dev);
- ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, "DC",
+ ret = irq_alloc_domain_generic_chips(data->domain, 32, 1,
+ of_node_full_name(dev->of_node),
handle_level_irq, 0, 0, 0);
if (ret) {
dev_err(dev, "failed to alloc generic IRQ chips: %d\n", ret);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* [PATCH 20/39] drm/imx: dc: Configure display CSR clock feed select
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (18 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 19/39] drm/imx: dc: ic: Use DT node as interrupt controller name Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:48 ` Frank Li
2025-10-11 16:51 ` [PATCH 21/39] drm/imx: dc: crtc: Do not check disabled CRTCs Marek Vasut
` (20 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Configure DISPLAY_CSR clock feed selector on i.MX95 accordingly
for either DSI and LVDS serializers. This is especially important
to make LVDS displays operational, the default selector setting
of 0 only works for DSI serializer.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-drv.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index 2717c92aba6c5..dec8ad19bad42 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -7,6 +7,7 @@
#include <linux/component.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <linux/mfd/syscon.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -29,8 +30,15 @@
#include "dc-drv.h"
#include "dc-pe.h"
+#define DISPLAY_ENGINES_CLOCK_CONTROL 0x00
+#define DISP_CLK1_SEL GENMASK(3, 2)
+#define DISP_CLK0_SEL GENMASK(1, 0)
+#define DISP_CLK_SEL_CCM 0
+#define DISP_CLK_SEL_LVDS 2
+
struct dc_priv {
struct drm_device *drm;
+ struct regmap *regmap;
struct clk_bulk_data *clk_cfg;
int clk_cfg_count;
};
@@ -119,6 +127,17 @@ static int dc_drm_bind(struct device *dev)
if (ret)
return ret;
+ if (priv->regmap) {
+ regmap_write_bits(priv->regmap, DISPLAY_ENGINES_CLOCK_CONTROL,
+ DISP_CLK0_SEL | DISP_CLK1_SEL,
+ FIELD_PREP(DISP_CLK0_SEL,
+ ((dc_drm->encoder[0].encoder_type == DRM_MODE_ENCODER_DSI) ?
+ DISP_CLK_SEL_CCM : DISP_CLK_SEL_LVDS)) |
+ FIELD_PREP(DISP_CLK1_SEL,
+ ((dc_drm->encoder[1].encoder_type == DRM_MODE_ENCODER_DSI) ?
+ DISP_CLK_SEL_CCM : DISP_CLK_SEL_LVDS)));
+ }
+
ret = drm_dev_register(drm, 0);
if (ret) {
dev_err(dev, "failed to register drm device: %d\n", ret);
@@ -157,6 +176,7 @@ static const struct component_master_ops dc_drm_ops = {
static int dc_probe(struct platform_device *pdev)
{
struct component_match *match = NULL;
+ struct device_node *np = pdev->dev.of_node;
struct dc_priv *priv;
int ret;
@@ -170,6 +190,12 @@ static int dc_probe(struct platform_device *pdev)
"failed to get cfg clock\n");
priv->clk_cfg_count = ret;
+ if (of_device_is_compatible(np, "fsl,imx95-dc")) {
+ priv->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,syscon");
+ if (IS_ERR(priv->regmap))
+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->regmap), "failed to get regmap\n");
+ }
+
dev_set_drvdata(&pdev->dev, priv);
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 20/39] drm/imx: dc: Configure display CSR clock feed select
2025-10-11 16:51 ` [PATCH 20/39] drm/imx: dc: Configure display CSR clock feed select Marek Vasut
@ 2025-10-13 18:48 ` Frank Li
2025-10-17 15:20 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:48 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:35PM +0200, Marek Vasut wrote:
> Configure DISPLAY_CSR clock feed selector on i.MX95 accordingly
> for either DSI and LVDS serializers. This is especially important
> to make LVDS displays operational, the default selector setting
> of 0 only works for DSI serializer.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-drv.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
> index 2717c92aba6c5..dec8ad19bad42 100644
> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
> @@ -7,6 +7,7 @@
> #include <linux/component.h>
> #include <linux/device.h>
> #include <linux/dma-mapping.h>
> +#include <linux/mfd/syscon.h>
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> #include <linux/of.h>
> @@ -29,8 +30,15 @@
> #include "dc-drv.h"
> #include "dc-pe.h"
>
> +#define DISPLAY_ENGINES_CLOCK_CONTROL 0x00
> +#define DISP_CLK1_SEL GENMASK(3, 2)
> +#define DISP_CLK0_SEL GENMASK(1, 0)
> +#define DISP_CLK_SEL_CCM 0
> +#define DISP_CLK_SEL_LVDS 2
> +
> struct dc_priv {
> struct drm_device *drm;
> + struct regmap *regmap;
> struct clk_bulk_data *clk_cfg;
> int clk_cfg_count;
> };
> @@ -119,6 +127,17 @@ static int dc_drm_bind(struct device *dev)
> if (ret)
> return ret;
>
> + if (priv->regmap) {
> + regmap_write_bits(priv->regmap, DISPLAY_ENGINES_CLOCK_CONTROL,
> + DISP_CLK0_SEL | DISP_CLK1_SEL,
> + FIELD_PREP(DISP_CLK0_SEL,
> + ((dc_drm->encoder[0].encoder_type == DRM_MODE_ENCODER_DSI) ?
> + DISP_CLK_SEL_CCM : DISP_CLK_SEL_LVDS)) |
> + FIELD_PREP(DISP_CLK1_SEL,
> + ((dc_drm->encoder[1].encoder_type == DRM_MODE_ENCODER_DSI) ?
> + DISP_CLK_SEL_CCM : DISP_CLK_SEL_LVDS)));
> + }
> +
why not export as clock providor and use clk API to do that?
Frank
> ret = drm_dev_register(drm, 0);
> if (ret) {
> dev_err(dev, "failed to register drm device: %d\n", ret);
> @@ -157,6 +176,7 @@ static const struct component_master_ops dc_drm_ops = {
> static int dc_probe(struct platform_device *pdev)
> {
> struct component_match *match = NULL;
> + struct device_node *np = pdev->dev.of_node;
> struct dc_priv *priv;
> int ret;
>
> @@ -170,6 +190,12 @@ static int dc_probe(struct platform_device *pdev)
> "failed to get cfg clock\n");
> priv->clk_cfg_count = ret;
>
> + if (of_device_is_compatible(np, "fsl,imx95-dc")) {
> + priv->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,syscon");
> + if (IS_ERR(priv->regmap))
> + return dev_err_probe(&pdev->dev, PTR_ERR(priv->regmap), "failed to get regmap\n");
> + }
> +
> dev_set_drvdata(&pdev->dev, priv);
>
> ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 20/39] drm/imx: dc: Configure display CSR clock feed select
2025-10-13 18:48 ` Frank Li
@ 2025-10-17 15:20 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:20 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 8:48 PM, Frank Li wrote:
Hello Frank,
>> @@ -119,6 +127,17 @@ static int dc_drm_bind(struct device *dev)
>> if (ret)
>> return ret;
>>
>> + if (priv->regmap) {
>> + regmap_write_bits(priv->regmap, DISPLAY_ENGINES_CLOCK_CONTROL,
>> + DISP_CLK0_SEL | DISP_CLK1_SEL,
>> + FIELD_PREP(DISP_CLK0_SEL,
>> + ((dc_drm->encoder[0].encoder_type == DRM_MODE_ENCODER_DSI) ?
>> + DISP_CLK_SEL_CCM : DISP_CLK_SEL_LVDS)) |
>> + FIELD_PREP(DISP_CLK1_SEL,
>> + ((dc_drm->encoder[1].encoder_type == DRM_MODE_ENCODER_DSI) ?
>> + DISP_CLK_SEL_CCM : DISP_CLK_SEL_LVDS)));
>> + }
>> +
>
> why not export as clock providor and use clk API to do that?
I don't think there are any clock operations
(enable/disable/set_rate/...) besides controlling this selector/mux
(set_parent), so using the clock API would have massive overhead for
little gain.
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 21/39] drm/imx: dc: crtc: Do not check disabled CRTCs
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (19 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 20/39] drm/imx: dc: Configure display CSR clock feed select Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:50 ` Frank Li
2025-10-11 16:51 ` [PATCH 22/39] drm/imx: dc: Keep FU unit running on i.MX95 Marek Vasut
` (19 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
If the CRTC is disabled, do not check it, as the check will fail.
Skip over the disabled CRTC.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-crtc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
index 56991cb033945..4955f519db917 100644
--- a/drivers/gpu/drm/imx/dc/dc-crtc.c
+++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
@@ -156,6 +156,10 @@ dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
enum drm_mode_status status;
+ /* If we are not active we don't care */
+ if (!new_crtc_state->active)
+ return 0;
+
status = dc_crtc_check_clock(dc_crtc, adj->clock);
if (status != MODE_OK)
return -EINVAL;
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 21/39] drm/imx: dc: crtc: Do not check disabled CRTCs
2025-10-11 16:51 ` [PATCH 21/39] drm/imx: dc: crtc: Do not check disabled CRTCs Marek Vasut
@ 2025-10-13 18:50 ` Frank Li
2025-10-14 21:41 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:50 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:36PM +0200, Marek Vasut wrote:
> If the CRTC is disabled, do not check it, as the check will fail.
> Skip over the disabled CRTC.
sorry, I have not understand what means.
Frank
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-crtc.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-crtc.c b/drivers/gpu/drm/imx/dc/dc-crtc.c
> index 56991cb033945..4955f519db917 100644
> --- a/drivers/gpu/drm/imx/dc/dc-crtc.c
> +++ b/drivers/gpu/drm/imx/dc/dc-crtc.c
> @@ -156,6 +156,10 @@ dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
> struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
> enum drm_mode_status status;
>
> + /* If we are not active we don't care */
> + if (!new_crtc_state->active)
> + return 0;
> +
> status = dc_crtc_check_clock(dc_crtc, adj->clock);
> if (status != MODE_OK)
> return -EINVAL;
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 21/39] drm/imx: dc: crtc: Do not check disabled CRTCs
2025-10-13 18:50 ` Frank Li
@ 2025-10-14 21:41 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-14 21:41 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 8:50 PM, Frank Li wrote:
> On Sat, Oct 11, 2025 at 06:51:36PM +0200, Marek Vasut wrote:
>> If the CRTC is disabled, do not check it, as the check will fail.
>> Skip over the disabled CRTC.
>
> sorry, I have not understand what means.
It means that on inactive CRTC, the atomic check below will fail because
there is no valid mode, and the check itself makes no sense.
>> @@ -156,6 +156,10 @@ dc_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
>> struct dc_crtc *dc_crtc = to_dc_crtc(crtc);
>> enum drm_mode_status status;
>>
>> + /* If we are not active we don't care */
>> + if (!new_crtc_state->active)
>> + return 0;
>> +
>> status = dc_crtc_check_clock(dc_crtc, adj->clock);
>> if (status != MODE_OK)
>> return -EINVAL;
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 22/39] drm/imx: dc: Keep FU unit running on i.MX95
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (20 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 21/39] drm/imx: dc: crtc: Do not check disabled CRTCs Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:52 ` Frank Li
2025-10-11 16:51 ` [PATCH 23/39] drm/imx: dc: Add OF match data for i.MX95 Marek Vasut
` (18 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
The i.MX95 does not have CF inputs into ED, it must pull inputs from FU
otherwise the controller crashes into green screen panic mode. Keep the
FU running on i.MX95.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-kms.h | 2 ++
drivers/gpu/drm/imx/dc/dc-plane.c | 10 +++++++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
index 3e61dbb87afe7..af37523ae0be3 100644
--- a/drivers/gpu/drm/imx/dc/dc-kms.h
+++ b/drivers/gpu/drm/imx/dc/dc-kms.h
@@ -130,6 +130,8 @@ struct dc_plane {
struct dc_lb *lb;
/** @ed: content stream extdst */
struct dc_ed *ed;
+ /** @keep_fu: keep FU running on iMX95 */
+ bool keep_fu;
};
#endif /* __DC_KMS_H__ */
diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
index d8b946fb90de6..18010c2b0bd78 100644
--- a/drivers/gpu/drm/imx/dc/dc-plane.c
+++ b/drivers/gpu/drm/imx/dc/dc-plane.c
@@ -4,6 +4,7 @@
*/
#include <linux/container_of.h>
+#include <linux/of.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
@@ -185,9 +186,11 @@ static void dc_plane_atomic_disable(struct drm_plane *plane,
if (!drm_dev_enter(plane->dev, &idx))
return;
- /* disable fetchunit in shadow */
- fu_ops = dc_fu_get_ops(dplane->fu);
- fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
+ /* disable fetchunit in shadow on i.MX8QXP */
+ if (!dplane->keep_fu) {
+ fu_ops = dc_fu_get_ops(dplane->fu);
+ fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
+ }
/* set ExtDst's source to ConstFrame */
dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
@@ -219,6 +222,7 @@ int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
dc_plane->lb = dc_drm->pe->lb[plane->index];
dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
+ dc_plane->keep_fu = of_device_is_compatible(dc_drm->base.dev->of_node, "fsl,imx95-dc");
return 0;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 22/39] drm/imx: dc: Keep FU unit running on i.MX95
2025-10-11 16:51 ` [PATCH 22/39] drm/imx: dc: Keep FU unit running on i.MX95 Marek Vasut
@ 2025-10-13 18:52 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:52 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:37PM +0200, Marek Vasut wrote:
> The i.MX95 does not have CF inputs into ED, it must pull inputs from FU
> otherwise the controller crashes into green screen panic mode. Keep the
> FU running on i.MX95.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/dc-kms.h | 2 ++
> drivers/gpu/drm/imx/dc/dc-plane.c | 10 +++++++---
> 2 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-kms.h b/drivers/gpu/drm/imx/dc/dc-kms.h
> index 3e61dbb87afe7..af37523ae0be3 100644
> --- a/drivers/gpu/drm/imx/dc/dc-kms.h
> +++ b/drivers/gpu/drm/imx/dc/dc-kms.h
> @@ -130,6 +130,8 @@ struct dc_plane {
> struct dc_lb *lb;
> /** @ed: content stream extdst */
> struct dc_ed *ed;
> + /** @keep_fu: keep FU running on iMX95 */
> + bool keep_fu;
> };
>
> #endif /* __DC_KMS_H__ */
> diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
> index d8b946fb90de6..18010c2b0bd78 100644
> --- a/drivers/gpu/drm/imx/dc/dc-plane.c
> +++ b/drivers/gpu/drm/imx/dc/dc-plane.c
> @@ -4,6 +4,7 @@
> */
>
> #include <linux/container_of.h>
> +#include <linux/of.h>
>
> #include <drm/drm_atomic.h>
> #include <drm/drm_atomic_helper.h>
> @@ -185,9 +186,11 @@ static void dc_plane_atomic_disable(struct drm_plane *plane,
> if (!drm_dev_enter(plane->dev, &idx))
> return;
>
> - /* disable fetchunit in shadow */
> - fu_ops = dc_fu_get_ops(dplane->fu);
> - fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
> + /* disable fetchunit in shadow on i.MX8QXP */
> + if (!dplane->keep_fu) {
> + fu_ops = dc_fu_get_ops(dplane->fu);
> + fu_ops->disable_src_buf(dplane->fu, DC_FETCHUNIT_FRAC0);
> + }
>
> /* set ExtDst's source to ConstFrame */
> dc_ed_pec_src_sel(dplane->ed, dc_cf_get_link_id(dplane->cf));
> @@ -219,6 +222,7 @@ int dc_plane_init(struct dc_drm_device *dc_drm, struct dc_plane *dc_plane)
> dc_plane->cf = dc_drm->pe->cf_cont[plane->index];
> dc_plane->lb = dc_drm->pe->lb[plane->index];
> dc_plane->ed = dc_drm->pe->ed_cont[plane->index];
> + dc_plane->keep_fu = of_device_is_compatible(dc_drm->base.dev->of_node, "fsl,imx95-dc");
Put it into drv match data
Frank
>
> return 0;
> }
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 23/39] drm/imx: dc: Add OF match data for i.MX95
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (21 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 22/39] drm/imx: dc: Keep FU unit running on i.MX95 Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:54 ` Frank Li
2025-10-11 16:51 ` [PATCH 24/39] drm/imx: Add more RGB swizzling options Marek Vasut
` (17 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Fill in OF match data for i.MX95, so the drivers can bind on this SoC.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/Kconfig | 4 +--
drivers/gpu/drm/imx/dc/dc-cf.c | 15 ++++++++
drivers/gpu/drm/imx/dc/dc-de.c | 34 ++++++++++++++++++
drivers/gpu/drm/imx/dc/dc-drv.c | 4 ++-
drivers/gpu/drm/imx/dc/dc-ed.c | 25 ++++++++++++++
drivers/gpu/drm/imx/dc/dc-fg.c | 48 ++++++++++++++++++++++++++
drivers/gpu/drm/imx/dc/dc-fl.c | 41 +++++++++++++++++++++-
drivers/gpu/drm/imx/dc/dc-ic.c | 61 +++++++++++++++++++++++++++++++--
drivers/gpu/drm/imx/dc/dc-lb.c | 52 +++++++++++++++++++++++++++-
drivers/gpu/drm/imx/dc/dc-pe.h | 11 +++++-
drivers/gpu/drm/imx/dc/dc-tc.c | 12 +++++++
11 files changed, 299 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
index 415993207f2e3..95fddf38066b0 100644
--- a/drivers/gpu/drm/imx/dc/Kconfig
+++ b/drivers/gpu/drm/imx/dc/Kconfig
@@ -1,5 +1,5 @@
config DRM_IMX8_DC
- tristate "Freescale i.MX8 Display Controller Graphics"
+ tristate "Freescale i.MX8Q/i.MX95 Display Controller Graphics"
depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
select DRM_CLIENT_SELECTION
select DRM_GEM_DMA_HELPER
@@ -10,4 +10,4 @@ config DRM_IMX8_DC
select REGMAP
select REGMAP_MMIO
help
- enable Freescale i.MX8 Display Controller(DC) graphics support
+ enable Freescale i.MX8Q/i.MX95 Display Controller(DC) graphics support
diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
index 1d3602c5d4230..1d409146f8b99 100644
--- a/drivers/gpu/drm/imx/dc/dc-cf.c
+++ b/drivers/gpu/drm/imx/dc/dc-cf.c
@@ -39,12 +39,26 @@ static const struct dc_subdev_info dc_cf_info_imx8qxp[] = {
{ /* sentinel */ },
};
+static const struct dc_subdev_info dc_cf_info_imx95[] = {
+ { .reg_start = 0x4b4f1000, .id = 0, },
+ { .reg_start = 0x4b531000, .id = 1, },
+ { .reg_start = 0x4b501000, .id = 4, },
+ { .reg_start = 0x4b541000, .id = 5, },
+ { /* sentinel */ },
+};
+
static const struct dc_cf_subdev_match_data dc_cf_match_data_imx8qxp = {
.link_cf4 = LINK_ID_CONSTFRAME4_MX8QXP,
.link_cf5 = LINK_ID_CONSTFRAME5_MX8QXP,
.info = dc_cf_info_imx8qxp,
};
+static const struct dc_cf_subdev_match_data dc_cf_match_data_imx95 = {
+ .link_cf4 = LINK_ID_CONSTFRAME4_MX95,
+ .link_cf5 = LINK_ID_CONSTFRAME5_MX95,
+ .info = dc_cf_info_imx95,
+};
+
static const struct regmap_range dc_cf_regmap_ranges[] = {
regmap_reg_range(STATICCONTROL, CONSTANTCOLOR),
};
@@ -173,6 +187,7 @@ static void dc_cf_remove(struct platform_device *pdev)
static const struct of_device_id dc_cf_dt_ids[] = {
{ .compatible = "fsl,imx8qxp-dc-constframe", .data = &dc_cf_match_data_imx8qxp },
+ { .compatible = "fsl,imx95-dc-constframe", .data = &dc_cf_match_data_imx95 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_cf_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-de.c b/drivers/gpu/drm/imx/dc/dc-de.c
index 6331b2f3b622c..5ee54c65e23f6 100644
--- a/drivers/gpu/drm/imx/dc/dc-de.c
+++ b/drivers/gpu/drm/imx/dc/dc-de.c
@@ -16,6 +16,7 @@
#include "dc-de.h"
#include "dc-drv.h"
+#define POLARITYCTRL_IMX95 0x8
#define POLARITYCTRL_IMX8QXP 0xc
#define POLEN_HIGH BIT(2)
@@ -57,6 +58,38 @@ static const struct dc_de_subdev_match_data dc_de_match_data_imx8qxp = {
.info = dc_de_info_imx8qxp,
};
+static const struct dc_subdev_info dc_de_info_imx95[] = {
+ { .reg_start = 0x4b711000, .id = 0, },
+ { .reg_start = 0x4b771000, .id = 1, },
+ { /* sentinel */ },
+};
+
+static const struct regmap_range dc_de_regmap_ranges_imx95[] = {
+ regmap_reg_range(POLARITYCTRL_IMX95, POLARITYCTRL_IMX95),
+};
+
+static const struct regmap_access_table dc_de_regmap_access_table_imx95 = {
+ .yes_ranges = dc_de_regmap_ranges_imx95,
+ .n_yes_ranges = ARRAY_SIZE(dc_de_regmap_ranges_imx95),
+};
+
+static const struct regmap_config dc_de_top_regmap_config_imx95 = {
+ .name = "top",
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .fast_io = true,
+ .wr_table = &dc_de_regmap_access_table_imx95,
+ .rd_table = &dc_de_regmap_access_table_imx95,
+ .max_register = POLARITYCTRL_IMX95,
+};
+
+static const struct dc_de_subdev_match_data dc_de_match_data_imx95 = {
+ .regmap_config = &dc_de_top_regmap_config_imx95,
+ .reg_polarityctrl = POLARITYCTRL_IMX95,
+ .info = dc_de_info_imx95,
+};
+
static inline void dc_dec_init(struct dc_de *de)
{
regmap_write_bits(de->reg_top, de->reg_polarityctrl, de->reg_polarityctrl, POLEN_HIGH);
@@ -180,6 +213,7 @@ static const struct dev_pm_ops dc_de_pm_ops = {
static const struct of_device_id dc_de_dt_ids[] = {
{ .compatible = "fsl,imx8qxp-dc-display-engine", .data = &dc_de_match_data_imx8qxp },
+ { .compatible = "fsl,imx95-dc-display-engine", .data = &dc_de_match_data_imx95 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_de_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
index dec8ad19bad42..b09fd8d6a2c52 100644
--- a/drivers/gpu/drm/imx/dc/dc-drv.c
+++ b/drivers/gpu/drm/imx/dc/dc-drv.c
@@ -64,7 +64,8 @@ dc_add_components(struct device *dev, struct component_match **matchptr)
for_each_available_child_of_node(dev->of_node, child) {
/* The interrupt controller is not a component. */
- if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
+ if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc") ||
+ of_device_is_compatible(child, "fsl,imx95-dc-intc"))
continue;
drm_of_component_match_add(dev, matchptr, component_compare_of,
@@ -274,6 +275,7 @@ static const struct dev_pm_ops dc_pm_ops = {
static const struct of_device_id dc_dt_ids[] = {
{ .compatible = "fsl,imx8qxp-dc", },
+ { .compatible = "fsl,imx95-dc", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
index 63dcad30ecced..a2f89dabd2b58 100644
--- a/drivers/gpu/drm/imx/dc/dc-ed.c
+++ b/drivers/gpu/drm/imx/dc/dc-ed.c
@@ -49,6 +49,14 @@ static const struct dc_subdev_info dc_ed_info_imx8qxp[] = {
{ /* sentinel */ },
};
+static const struct dc_subdev_info dc_ed_info_imx95[] = {
+ { .reg_start = 0x4b511000, .id = 0, },
+ { .reg_start = 0x4b551000, .id = 1, },
+ { .reg_start = 0x4b521000, .id = 4, },
+ { .reg_start = 0x4b561000, .id = 5, },
+ { /* sentinel */ },
+};
+
static const struct regmap_range dc_ed_pec_regmap_write_ranges[] = {
regmap_reg_range(PIXENGCFG_STATIC, PIXENGCFG_STATIC),
regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
@@ -125,11 +133,27 @@ static const enum dc_link_id src_sels_imx8qxp[] = {
LINK_ID_LAST /* sentinel */
};
+static const enum dc_link_id src_sels_imx95[] = {
+ LINK_ID_NONE,
+ LINK_ID_LAYERBLEND5_MX95,
+ LINK_ID_LAYERBLEND4_MX95,
+ LINK_ID_LAYERBLEND3_MX95,
+ LINK_ID_LAYERBLEND2_MX95,
+ LINK_ID_LAYERBLEND1_MX95,
+ LINK_ID_LAYERBLEND0_MX95,
+ LINK_ID_LAST /* sentinel */
+};
+
static const struct dc_ed_subdev_match_data dc_ed_match_data_imx8qxp = {
.src_sels = src_sels_imx8qxp,
.info = dc_ed_info_imx8qxp,
};
+static const struct dc_ed_subdev_match_data dc_ed_match_data_imx95 = {
+ .src_sels = src_sels_imx95,
+ .info = dc_ed_info_imx95,
+};
+
static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
{
regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SHDEN, SHDEN);
@@ -289,6 +313,7 @@ static void dc_ed_remove(struct platform_device *pdev)
static const struct of_device_id dc_ed_dt_ids[] = {
{ .compatible = "fsl,imx8qxp-dc-extdst", .data = &dc_ed_match_data_imx8qxp },
+ { .compatible = "fsl,imx95-dc-extdst", .data = &dc_ed_match_data_imx95 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_ed_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
index e13b057a92ffb..b2477461faff5 100644
--- a/drivers/gpu/drm/imx/dc/dc-fg.c
+++ b/drivers/gpu/drm/imx/dc/dc-fg.c
@@ -51,6 +51,7 @@
#define COL(x) FIELD_PREP(GENMASK(13, 0), (x))
#define OFFSET_MX8QXP 0x00
+#define OFFSET_MX95 0x24
#define PACFG(o) (0x54 + (o))
#define SACFG(o) (0x58 + (o))
@@ -104,6 +105,12 @@ static const struct dc_subdev_info dc_fg_info_imx8qxp[] = {
{ /* sentinel */ },
};
+static const struct dc_subdev_info dc_fg_info_imx95[] = {
+ { .reg_start = 0x4b6b0000, .id = 0, },
+ { .reg_start = 0x4b730000, .id = 1, },
+ { /* sentinel */ },
+};
+
static const struct regmap_range dc_fg_regmap_write_ranges_imx8qxp[] = {
regmap_reg_range(FGSTCTRL, VTCFG2),
regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
@@ -144,6 +151,46 @@ static const struct dc_fg_subdev_match_data dc_fg_match_data_imx8qxp = {
.info = dc_fg_info_imx8qxp,
};
+static const struct regmap_range dc_fg_regmap_write_ranges_imx95[] = {
+ regmap_reg_range(FGSTCTRL, VTCFG2),
+ regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
+ regmap_reg_range(PACFG(OFFSET_MX95), FGSLR(OFFSET_MX95)),
+ regmap_reg_range(FGCHSTATCLR(OFFSET_MX95), FGCHSTATCLR(OFFSET_MX95)),
+};
+
+static const struct regmap_range dc_fg_regmap_read_ranges_imx95[] = {
+ regmap_reg_range(FGSTCTRL, VTCFG2),
+ regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
+ regmap_reg_range(PACFG(OFFSET_MX95), FGENABLE(OFFSET_MX95)),
+ regmap_reg_range(FGTIMESTAMP(OFFSET_MX95), FGCHSTAT(OFFSET_MX95)),
+};
+
+static const struct regmap_access_table dc_fg_regmap_write_table_imx95 = {
+ .yes_ranges = dc_fg_regmap_write_ranges_imx95,
+ .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_write_ranges_imx95),
+};
+
+static const struct regmap_access_table dc_fg_regmap_read_table_imx95 = {
+ .yes_ranges = dc_fg_regmap_read_ranges_imx95,
+ .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_read_ranges_imx95),
+};
+
+static const struct regmap_config dc_fg_regmap_config_imx95 = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .fast_io = true,
+ .wr_table = &dc_fg_regmap_write_table_imx95,
+ .rd_table = &dc_fg_regmap_read_table_imx95,
+ .max_register = FGCHSTATCLR(OFFSET_MX95),
+};
+
+static const struct dc_fg_subdev_match_data dc_fg_match_data_imx95 = {
+ .regmap_config = &dc_fg_regmap_config_imx95,
+ .reg_offset = OFFSET_MX95,
+ .info = dc_fg_info_imx95,
+};
+
static inline void dc_fg_enable_shden(struct dc_fg *fg)
{
regmap_write_bits(fg->reg, FGSTCTRL, SHDEN, SHDEN);
@@ -380,6 +427,7 @@ static void dc_fg_remove(struct platform_device *pdev)
static const struct of_device_id dc_fg_dt_ids[] = {
{ .compatible = "fsl,imx8qxp-dc-framegen", .data = &dc_fg_match_data_imx8qxp },
+ { .compatible = "fsl,imx95-dc-framegen", .data = &dc_fg_match_data_imx95 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_fg_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
index 53647e3a395b4..3aa437120b11d 100644
--- a/drivers/gpu/drm/imx/dc/dc-fl.c
+++ b/drivers/gpu/drm/imx/dc/dc-fl.c
@@ -8,6 +8,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <drm/drm_fourcc.h>
@@ -27,6 +28,7 @@
#define CONSTANTCOLOR 0x30
#define LAYERPROPERTY 0x34
#define FRAMEDIMENSIONS_IMX8QXP 0x150
+#define FRAMEDIMENSIONS_IMX95 0x1d8
struct dc_fl {
struct dc_fu fu;
@@ -47,6 +49,12 @@ static const struct dc_subdev_info dc_fl_info_imx8qxp[] = {
{ /* sentinel */ },
};
+static const struct dc_subdev_info dc_fl_info_imx95[] = {
+ { .reg_start = 0x4b5d1000, .id = 0, },
+ { .reg_start = 0x4b5e1000, .id = 1, },
+ { /* sentinel */ },
+};
+
static const struct regmap_range dc_fl_regmap_ranges_imx8qxp[] = {
regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS_IMX8QXP),
};
@@ -77,6 +85,36 @@ static const struct dc_fl_subdev_match_data dc_fl_match_data_imx8qxp = {
.info = dc_fl_info_imx8qxp,
};
+static const struct regmap_range dc_fl_regmap_ranges_imx95[] = {
+ regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS_IMX95),
+};
+
+static const struct regmap_access_table dc_fl_regmap_access_table_imx95 = {
+ .yes_ranges = dc_fl_regmap_ranges_imx95,
+ .n_yes_ranges = ARRAY_SIZE(dc_fl_regmap_ranges_imx95),
+};
+
+static const struct regmap_config dc_fl_cfg_regmap_config_imx95 = {
+ .name = "cfg",
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .fast_io = true,
+ .wr_table = &dc_fl_regmap_access_table_imx95,
+ .rd_table = &dc_fl_regmap_access_table_imx95,
+ .max_register = FRAMEDIMENSIONS_IMX95,
+};
+
+static const struct dc_fl_subdev_match_data dc_fl_match_data_imx95 = {
+ .regmap_config = &dc_fl_cfg_regmap_config_imx95,
+ .reg_offset_bbm = 0x4,
+ .reg_offset_base = 0x8,
+ .reg_offset_rest = 0x14,
+ .reg_framedimensions = FRAMEDIMENSIONS_IMX95,
+ .reg_frac_offset = 0x38,
+ .info = dc_fl_info_imx95,
+};
+
static void dc_fl_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
const struct drm_format_info *format)
{
@@ -152,7 +190,7 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
}
fu->link_id = LINK_ID_FETCHLAYER0;
- fu->id = DC_FETCHUNIT_FL0;
+ fu->id = DC_FETCHUNIT_FL0 + id;
for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
off = i * dc_fl_match_data->reg_frac_offset;
off_base = off + dc_fl_match_data->reg_offset_base;
@@ -202,6 +240,7 @@ static void dc_fl_remove(struct platform_device *pdev)
static const struct of_device_id dc_fl_dt_ids[] = {
{ .compatible = "fsl,imx8qxp-dc-fetchlayer", .data = &dc_fl_match_data_imx8qxp },
+ { .compatible = "fsl,imx95-dc-fetchlayer", .data = &dc_fl_match_data_imx95 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_fl_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
index c3d7e5aa4ae23..ac83642cbe4c8 100644
--- a/drivers/gpu/drm/imx/dc/dc-ic.c
+++ b/drivers/gpu/drm/imx/dc/dc-ic.c
@@ -24,8 +24,13 @@
#define USERINTERRUPTCLEAR(n) (0x50 + 4 * (n))
#define USERINTERRUPTSTATUS(n) (0x58 + 4 * (n))
-#define IRQ_COUNT_MAX 49
-#define REG_NUM_MAX 2
+#define INTERRUPTENABLE_MX95(n) (0x8 + 4 * (n))
+#define INTERRUPTPRESET_MX95(n) (0x14 + 4 * (n))
+#define INTERRUPTCLEAR_MX95(n) (0x20 + 4 * (n))
+#define INTERRUPTSTATUS_MX95(n) (0x2c + 4 * (n))
+
+#define IRQ_COUNT_MAX 86
+#define REG_NUM_MAX 3
struct dc_ic_data {
struct regmap *regs;
@@ -109,6 +114,57 @@ static const struct dc_ic_subdev_match_data dc_ic_match_data_imx8qxp = {
.reserved_irq = 35,
};
+static const struct regmap_range dc_ic_regmap_write_ranges_imx95[] = {
+ regmap_reg_range(INTERRUPTENABLE_MX95(0), INTERRUPTCLEAR_MX95(2)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_write_table_imx95 = {
+ .yes_ranges = dc_ic_regmap_write_ranges_imx95,
+ .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_write_ranges_imx95),
+};
+
+static const struct regmap_range dc_ic_regmap_read_ranges_imx95[] = {
+ regmap_reg_range(INTERRUPTENABLE_MX95(0), INTERRUPTENABLE_MX95(2)),
+ regmap_reg_range(INTERRUPTSTATUS_MX95(0), INTERRUPTSTATUS_MX95(2)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_read_table_imx95 = {
+ .yes_ranges = dc_ic_regmap_read_ranges_imx95,
+ .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_read_ranges_imx95),
+};
+
+static const struct regmap_range dc_ic_regmap_volatile_ranges_imx95[] = {
+ regmap_reg_range(INTERRUPTPRESET_MX95(0), INTERRUPTCLEAR_MX95(2)),
+};
+
+static const struct regmap_access_table dc_ic_regmap_volatile_table_imx95 = {
+ .yes_ranges = dc_ic_regmap_volatile_ranges_imx95,
+ .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_volatile_ranges_imx95),
+};
+
+static const struct regmap_config dc_ic_regmap_config_imx95 = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .fast_io = true,
+ .wr_table = &dc_ic_regmap_write_table_imx95,
+ .rd_table = &dc_ic_regmap_read_table_imx95,
+ .volatile_table = &dc_ic_regmap_volatile_table_imx95,
+ .max_register = INTERRUPTSTATUS_MX95(2),
+};
+
+static const struct dc_ic_subdev_match_data dc_ic_match_data_imx95 = {
+ .regmap_config = &dc_ic_regmap_config_imx95,
+ .reg_enable = INTERRUPTENABLE_MX95(0),
+ .reg_clear = INTERRUPTCLEAR_MX95(0),
+ .reg_status = INTERRUPTSTATUS_MX95(0),
+ .reg_count = 3,
+ .irq_count = 86,
+ .user_irq = false,
+ .unused_irq = { 0x00000000, 0x00000000, 0xffc00000 },
+ .reserved_irq = -1,
+};
+
static void dc_ic_irq_handler(struct irq_desc *desc)
{
struct dc_ic_entry *entry = irq_desc_get_handler_data(desc);
@@ -304,6 +360,7 @@ static const struct dev_pm_ops dc_ic_pm_ops = {
static const struct of_device_id dc_ic_dt_ids[] = {
{ .compatible = "fsl,imx8qxp-dc-intc", .data = &dc_ic_match_data_imx8qxp },
+ { .compatible = "fsl,imx95-dc-intc", .data = &dc_ic_match_data_imx95 },
{ /* sentinel */ }
};
diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
index ba9183b244ab3..f38f338e48c4c 100644
--- a/drivers/gpu/drm/imx/dc/dc-lb.c
+++ b/drivers/gpu/drm/imx/dc/dc-lb.c
@@ -9,6 +9,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <drm/drm_blend.h>
@@ -79,7 +80,7 @@ enum dc_lb_shadow_sel {
BOTH = 0x2,
};
-static const struct dc_subdev_info dc_lb_info[] = {
+static const struct dc_subdev_info dc_lb_info_imx8qxp[] = {
{ .reg_start = 0x56180ba0, .id = 0, },
{ .reg_start = 0x56180bc0, .id = 1, },
{ .reg_start = 0x56180be0, .id = 2, },
@@ -87,6 +88,16 @@ static const struct dc_subdev_info dc_lb_info[] = {
{ /* sentinel */ },
};
+static const struct dc_subdev_info dc_lb_info_imx95[] = {
+ { .reg_start = 0x4b571000, .id = 0, },
+ { .reg_start = 0x4b581000, .id = 1, },
+ { .reg_start = 0x4b591000, .id = 2, },
+ { .reg_start = 0x4b5a1000, .id = 3, },
+ { .reg_start = 0x4b5b1000, .id = 4, },
+ { .reg_start = 0x4b5c1000, .id = 5, },
+ { /* sentinel */ },
+};
+
static const struct regmap_range dc_lb_pec_regmap_access_ranges[] = {
regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
};
@@ -163,6 +174,44 @@ static const struct dc_lb_subdev_match_data dc_lb_match_data_imx8qxp = {
.info = dc_lb_info_imx8qxp,
};
+static const enum dc_link_id prim_sels_imx95[] = {
+ /* common options */
+ LINK_ID_NONE,
+ LINK_ID_CONSTFRAME0,
+ LINK_ID_CONSTFRAME1,
+ LINK_ID_CONSTFRAME4_MX95,
+ LINK_ID_CONSTFRAME5_MX95,
+ /*
+ * special options:
+ * layerblend(n) has n special options,
+ * from layerblend0 to layerblend(n - 1), e.g.,
+ * layerblend3 has 3 special options -
+ * layerblend0/1/2.
+ */
+ LINK_ID_LAYERBLEND0_MX95,
+ LINK_ID_LAYERBLEND1_MX95,
+ LINK_ID_LAYERBLEND2_MX95,
+ LINK_ID_LAYERBLEND3_MX95,
+ LINK_ID_LAYERBLEND4_MX95,
+ LINK_ID_LAYERBLEND5_MX95,
+ LINK_ID_LAST
+};
+
+static const enum dc_link_id sec_sels_imx95[] = {
+ LINK_ID_NONE,
+ LINK_ID_FETCHLAYER0,
+ LINK_ID_FETCHLAYER1_MX95,
+ LINK_ID_LAST
+};
+
+static const struct dc_lb_subdev_match_data dc_lb_match_data_imx95 = {
+ .pri_sels = prim_sels_imx95,
+ .sec_sels = sec_sels_imx95,
+ .first_lb = LINK_ID_LAYERBLEND0_MX95,
+ .last_cf = 7,
+ .info = dc_lb_info_imx95,
+};
+
enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
{
return lb->link;
@@ -333,6 +382,7 @@ static void dc_lb_remove(struct platform_device *pdev)
static const struct of_device_id dc_lb_dt_ids[] = {
{ .compatible = "fsl,imx8qxp-dc-layerblend", .data = &dc_lb_match_data_imx8qxp },
+ { .compatible = "fsl,imx95-dc-layerblend", .data = &dc_lb_match_data_imx95 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_lb_dt_ids);
diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
index 492d193127bc1..c7a50749db38f 100644
--- a/drivers/gpu/drm/imx/dc/dc-pe.h
+++ b/drivers/gpu/drm/imx/dc/dc-pe.h
@@ -19,16 +19,25 @@
#define CLKEN(n) ((n) << CLKEN_MASK_SHIFT)
#define DC_DISP_FU_CNT 2
-#define DC_LB_CNT 4
+#define DC_LB_CNT 6
enum dc_link_id {
LINK_ID_NONE = 0x00,
LINK_ID_CONSTFRAME0 = 0x0c,
+ LINK_ID_CONSTFRAME4_MX95 = 0x0d,
LINK_ID_CONSTFRAME4_MX8QXP = 0x0e,
LINK_ID_CONSTFRAME1 = 0x10,
+ LINK_ID_CONSTFRAME5_MX95 = 0x11,
LINK_ID_CONSTFRAME5_MX8QXP = 0x12,
+ LINK_ID_LAYERBLEND0_MX95 = 0x14,
+ LINK_ID_LAYERBLEND1_MX95 = 0x15,
+ LINK_ID_LAYERBLEND2_MX95 = 0x16,
+ LINK_ID_LAYERBLEND3_MX95 = 0x17,
+ LINK_ID_LAYERBLEND4_MX95 = 0x18,
+ LINK_ID_LAYERBLEND5_MX95 = 0x19,
LINK_ID_FETCHWARP2 = 0x14,
LINK_ID_FETCHLAYER0 = 0x1a,
+ LINK_ID_FETCHLAYER1_MX95 = 0x1b,
LINK_ID_LAYERBLEND0_MX8QXP = 0x21,
LINK_ID_LAYERBLEND1_MX8QXP = 0x22,
LINK_ID_LAYERBLEND2_MX8QXP = 0x23,
diff --git a/drivers/gpu/drm/imx/dc/dc-tc.c b/drivers/gpu/drm/imx/dc/dc-tc.c
index 1f287706e8706..9a08fcabc625a 100644
--- a/drivers/gpu/drm/imx/dc/dc-tc.c
+++ b/drivers/gpu/drm/imx/dc/dc-tc.c
@@ -37,6 +37,12 @@ static const struct dc_subdev_info dc_tc_info_imx8qxp[] = {
{ /* sentinel */ },
};
+static const struct dc_subdev_info dc_tc_info_imx95[] = {
+ { .reg_start = 0x4b711000, .id = 0, },
+ { .reg_start = 0x4b771000, .id = 1, },
+ { /* sentinel */ },
+};
+
static const struct regmap_range dc_tc_regmap_ranges[] = {
regmap_reg_range(TCON_CTRL, TCON_CTRL),
regmap_reg_range(MAPBIT3_0, MAPBIT31_28),
@@ -72,6 +78,11 @@ static const struct dc_tc_subdev_match_data dc_tc_match_data_imx8qxp = {
.info = dc_tc_info_imx8qxp,
};
+static const struct dc_tc_subdev_match_data dc_tc_match_data_imx95 = {
+ .need_config = false,
+ .info = dc_tc_info_imx95,
+};
+
void dc_tc_init(struct dc_tc *tc)
{
if (!tc->need_config)
@@ -149,6 +160,7 @@ static void dc_tc_remove(struct platform_device *pdev)
static const struct of_device_id dc_tc_dt_ids[] = {
{ .compatible = "fsl,imx8qxp-dc-tcon", .data = &dc_tc_match_data_imx8qxp },
+ { .compatible = "fsl,imx95-dc-tcon", .data = &dc_tc_match_data_imx95 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_tc_dt_ids);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 23/39] drm/imx: dc: Add OF match data for i.MX95
2025-10-11 16:51 ` [PATCH 23/39] drm/imx: dc: Add OF match data for i.MX95 Marek Vasut
@ 2025-10-13 18:54 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:54 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:38PM +0200, Marek Vasut wrote:
> Fill in OF match data for i.MX95, so the drivers can bind on this SoC.
Add i.MX95 support by filling OF match data.
Frank
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/imx/dc/Kconfig | 4 +--
> drivers/gpu/drm/imx/dc/dc-cf.c | 15 ++++++++
> drivers/gpu/drm/imx/dc/dc-de.c | 34 ++++++++++++++++++
> drivers/gpu/drm/imx/dc/dc-drv.c | 4 ++-
> drivers/gpu/drm/imx/dc/dc-ed.c | 25 ++++++++++++++
> drivers/gpu/drm/imx/dc/dc-fg.c | 48 ++++++++++++++++++++++++++
> drivers/gpu/drm/imx/dc/dc-fl.c | 41 +++++++++++++++++++++-
> drivers/gpu/drm/imx/dc/dc-ic.c | 61 +++++++++++++++++++++++++++++++--
> drivers/gpu/drm/imx/dc/dc-lb.c | 52 +++++++++++++++++++++++++++-
> drivers/gpu/drm/imx/dc/dc-pe.h | 11 +++++-
> drivers/gpu/drm/imx/dc/dc-tc.c | 12 +++++++
> 11 files changed, 299 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/dc/Kconfig b/drivers/gpu/drm/imx/dc/Kconfig
> index 415993207f2e3..95fddf38066b0 100644
> --- a/drivers/gpu/drm/imx/dc/Kconfig
> +++ b/drivers/gpu/drm/imx/dc/Kconfig
> @@ -1,5 +1,5 @@
> config DRM_IMX8_DC
> - tristate "Freescale i.MX8 Display Controller Graphics"
> + tristate "Freescale i.MX8Q/i.MX95 Display Controller Graphics"
> depends on DRM && COMMON_CLK && OF && (ARCH_MXC || COMPILE_TEST)
> select DRM_CLIENT_SELECTION
> select DRM_GEM_DMA_HELPER
> @@ -10,4 +10,4 @@ config DRM_IMX8_DC
> select REGMAP
> select REGMAP_MMIO
> help
> - enable Freescale i.MX8 Display Controller(DC) graphics support
> + enable Freescale i.MX8Q/i.MX95 Display Controller(DC) graphics support
> diff --git a/drivers/gpu/drm/imx/dc/dc-cf.c b/drivers/gpu/drm/imx/dc/dc-cf.c
> index 1d3602c5d4230..1d409146f8b99 100644
> --- a/drivers/gpu/drm/imx/dc/dc-cf.c
> +++ b/drivers/gpu/drm/imx/dc/dc-cf.c
> @@ -39,12 +39,26 @@ static const struct dc_subdev_info dc_cf_info_imx8qxp[] = {
> { /* sentinel */ },
> };
>
> +static const struct dc_subdev_info dc_cf_info_imx95[] = {
> + { .reg_start = 0x4b4f1000, .id = 0, },
> + { .reg_start = 0x4b531000, .id = 1, },
> + { .reg_start = 0x4b501000, .id = 4, },
> + { .reg_start = 0x4b541000, .id = 5, },
> + { /* sentinel */ },
> +};
> +
> static const struct dc_cf_subdev_match_data dc_cf_match_data_imx8qxp = {
> .link_cf4 = LINK_ID_CONSTFRAME4_MX8QXP,
> .link_cf5 = LINK_ID_CONSTFRAME5_MX8QXP,
> .info = dc_cf_info_imx8qxp,
> };
>
> +static const struct dc_cf_subdev_match_data dc_cf_match_data_imx95 = {
> + .link_cf4 = LINK_ID_CONSTFRAME4_MX95,
> + .link_cf5 = LINK_ID_CONSTFRAME5_MX95,
> + .info = dc_cf_info_imx95,
> +};
> +
> static const struct regmap_range dc_cf_regmap_ranges[] = {
> regmap_reg_range(STATICCONTROL, CONSTANTCOLOR),
> };
> @@ -173,6 +187,7 @@ static void dc_cf_remove(struct platform_device *pdev)
>
> static const struct of_device_id dc_cf_dt_ids[] = {
> { .compatible = "fsl,imx8qxp-dc-constframe", .data = &dc_cf_match_data_imx8qxp },
> + { .compatible = "fsl,imx95-dc-constframe", .data = &dc_cf_match_data_imx95 },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_cf_dt_ids);
> diff --git a/drivers/gpu/drm/imx/dc/dc-de.c b/drivers/gpu/drm/imx/dc/dc-de.c
> index 6331b2f3b622c..5ee54c65e23f6 100644
> --- a/drivers/gpu/drm/imx/dc/dc-de.c
> +++ b/drivers/gpu/drm/imx/dc/dc-de.c
> @@ -16,6 +16,7 @@
> #include "dc-de.h"
> #include "dc-drv.h"
>
> +#define POLARITYCTRL_IMX95 0x8
> #define POLARITYCTRL_IMX8QXP 0xc
> #define POLEN_HIGH BIT(2)
>
> @@ -57,6 +58,38 @@ static const struct dc_de_subdev_match_data dc_de_match_data_imx8qxp = {
> .info = dc_de_info_imx8qxp,
> };
>
> +static const struct dc_subdev_info dc_de_info_imx95[] = {
> + { .reg_start = 0x4b711000, .id = 0, },
> + { .reg_start = 0x4b771000, .id = 1, },
> + { /* sentinel */ },
> +};
> +
> +static const struct regmap_range dc_de_regmap_ranges_imx95[] = {
> + regmap_reg_range(POLARITYCTRL_IMX95, POLARITYCTRL_IMX95),
> +};
> +
> +static const struct regmap_access_table dc_de_regmap_access_table_imx95 = {
> + .yes_ranges = dc_de_regmap_ranges_imx95,
> + .n_yes_ranges = ARRAY_SIZE(dc_de_regmap_ranges_imx95),
> +};
> +
> +static const struct regmap_config dc_de_top_regmap_config_imx95 = {
> + .name = "top",
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .fast_io = true,
> + .wr_table = &dc_de_regmap_access_table_imx95,
> + .rd_table = &dc_de_regmap_access_table_imx95,
> + .max_register = POLARITYCTRL_IMX95,
> +};
> +
> +static const struct dc_de_subdev_match_data dc_de_match_data_imx95 = {
> + .regmap_config = &dc_de_top_regmap_config_imx95,
> + .reg_polarityctrl = POLARITYCTRL_IMX95,
> + .info = dc_de_info_imx95,
> +};
> +
> static inline void dc_dec_init(struct dc_de *de)
> {
> regmap_write_bits(de->reg_top, de->reg_polarityctrl, de->reg_polarityctrl, POLEN_HIGH);
> @@ -180,6 +213,7 @@ static const struct dev_pm_ops dc_de_pm_ops = {
>
> static const struct of_device_id dc_de_dt_ids[] = {
> { .compatible = "fsl,imx8qxp-dc-display-engine", .data = &dc_de_match_data_imx8qxp },
> + { .compatible = "fsl,imx95-dc-display-engine", .data = &dc_de_match_data_imx95 },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_de_dt_ids);
> diff --git a/drivers/gpu/drm/imx/dc/dc-drv.c b/drivers/gpu/drm/imx/dc/dc-drv.c
> index dec8ad19bad42..b09fd8d6a2c52 100644
> --- a/drivers/gpu/drm/imx/dc/dc-drv.c
> +++ b/drivers/gpu/drm/imx/dc/dc-drv.c
> @@ -64,7 +64,8 @@ dc_add_components(struct device *dev, struct component_match **matchptr)
>
> for_each_available_child_of_node(dev->of_node, child) {
> /* The interrupt controller is not a component. */
> - if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc"))
> + if (of_device_is_compatible(child, "fsl,imx8qxp-dc-intc") ||
> + of_device_is_compatible(child, "fsl,imx95-dc-intc"))
> continue;
>
> drm_of_component_match_add(dev, matchptr, component_compare_of,
> @@ -274,6 +275,7 @@ static const struct dev_pm_ops dc_pm_ops = {
>
> static const struct of_device_id dc_dt_ids[] = {
> { .compatible = "fsl,imx8qxp-dc", },
> + { .compatible = "fsl,imx95-dc", },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_dt_ids);
> diff --git a/drivers/gpu/drm/imx/dc/dc-ed.c b/drivers/gpu/drm/imx/dc/dc-ed.c
> index 63dcad30ecced..a2f89dabd2b58 100644
> --- a/drivers/gpu/drm/imx/dc/dc-ed.c
> +++ b/drivers/gpu/drm/imx/dc/dc-ed.c
> @@ -49,6 +49,14 @@ static const struct dc_subdev_info dc_ed_info_imx8qxp[] = {
> { /* sentinel */ },
> };
>
> +static const struct dc_subdev_info dc_ed_info_imx95[] = {
> + { .reg_start = 0x4b511000, .id = 0, },
> + { .reg_start = 0x4b551000, .id = 1, },
> + { .reg_start = 0x4b521000, .id = 4, },
> + { .reg_start = 0x4b561000, .id = 5, },
> + { /* sentinel */ },
> +};
> +
> static const struct regmap_range dc_ed_pec_regmap_write_ranges[] = {
> regmap_reg_range(PIXENGCFG_STATIC, PIXENGCFG_STATIC),
> regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
> @@ -125,11 +133,27 @@ static const enum dc_link_id src_sels_imx8qxp[] = {
> LINK_ID_LAST /* sentinel */
> };
>
> +static const enum dc_link_id src_sels_imx95[] = {
> + LINK_ID_NONE,
> + LINK_ID_LAYERBLEND5_MX95,
> + LINK_ID_LAYERBLEND4_MX95,
> + LINK_ID_LAYERBLEND3_MX95,
> + LINK_ID_LAYERBLEND2_MX95,
> + LINK_ID_LAYERBLEND1_MX95,
> + LINK_ID_LAYERBLEND0_MX95,
> + LINK_ID_LAST /* sentinel */
> +};
> +
> static const struct dc_ed_subdev_match_data dc_ed_match_data_imx8qxp = {
> .src_sels = src_sels_imx8qxp,
> .info = dc_ed_info_imx8qxp,
> };
>
> +static const struct dc_ed_subdev_match_data dc_ed_match_data_imx95 = {
> + .src_sels = src_sels_imx95,
> + .info = dc_ed_info_imx95,
> +};
> +
> static inline void dc_ed_pec_enable_shden(struct dc_ed *ed)
> {
> regmap_write_bits(ed->reg_pec, PIXENGCFG_STATIC, SHDEN, SHDEN);
> @@ -289,6 +313,7 @@ static void dc_ed_remove(struct platform_device *pdev)
>
> static const struct of_device_id dc_ed_dt_ids[] = {
> { .compatible = "fsl,imx8qxp-dc-extdst", .data = &dc_ed_match_data_imx8qxp },
> + { .compatible = "fsl,imx95-dc-extdst", .data = &dc_ed_match_data_imx95 },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_ed_dt_ids);
> diff --git a/drivers/gpu/drm/imx/dc/dc-fg.c b/drivers/gpu/drm/imx/dc/dc-fg.c
> index e13b057a92ffb..b2477461faff5 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fg.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fg.c
> @@ -51,6 +51,7 @@
> #define COL(x) FIELD_PREP(GENMASK(13, 0), (x))
>
> #define OFFSET_MX8QXP 0x00
> +#define OFFSET_MX95 0x24
>
> #define PACFG(o) (0x54 + (o))
> #define SACFG(o) (0x58 + (o))
> @@ -104,6 +105,12 @@ static const struct dc_subdev_info dc_fg_info_imx8qxp[] = {
> { /* sentinel */ },
> };
>
> +static const struct dc_subdev_info dc_fg_info_imx95[] = {
> + { .reg_start = 0x4b6b0000, .id = 0, },
> + { .reg_start = 0x4b730000, .id = 1, },
> + { /* sentinel */ },
> +};
> +
> static const struct regmap_range dc_fg_regmap_write_ranges_imx8qxp[] = {
> regmap_reg_range(FGSTCTRL, VTCFG2),
> regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
> @@ -144,6 +151,46 @@ static const struct dc_fg_subdev_match_data dc_fg_match_data_imx8qxp = {
> .info = dc_fg_info_imx8qxp,
> };
>
> +static const struct regmap_range dc_fg_regmap_write_ranges_imx95[] = {
> + regmap_reg_range(FGSTCTRL, VTCFG2),
> + regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
> + regmap_reg_range(PACFG(OFFSET_MX95), FGSLR(OFFSET_MX95)),
> + regmap_reg_range(FGCHSTATCLR(OFFSET_MX95), FGCHSTATCLR(OFFSET_MX95)),
> +};
> +
> +static const struct regmap_range dc_fg_regmap_read_ranges_imx95[] = {
> + regmap_reg_range(FGSTCTRL, VTCFG2),
> + regmap_reg_range(PKICKCONFIG, SKICKCONFIG),
> + regmap_reg_range(PACFG(OFFSET_MX95), FGENABLE(OFFSET_MX95)),
> + regmap_reg_range(FGTIMESTAMP(OFFSET_MX95), FGCHSTAT(OFFSET_MX95)),
> +};
> +
> +static const struct regmap_access_table dc_fg_regmap_write_table_imx95 = {
> + .yes_ranges = dc_fg_regmap_write_ranges_imx95,
> + .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_write_ranges_imx95),
> +};
> +
> +static const struct regmap_access_table dc_fg_regmap_read_table_imx95 = {
> + .yes_ranges = dc_fg_regmap_read_ranges_imx95,
> + .n_yes_ranges = ARRAY_SIZE(dc_fg_regmap_read_ranges_imx95),
> +};
> +
> +static const struct regmap_config dc_fg_regmap_config_imx95 = {
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .fast_io = true,
> + .wr_table = &dc_fg_regmap_write_table_imx95,
> + .rd_table = &dc_fg_regmap_read_table_imx95,
> + .max_register = FGCHSTATCLR(OFFSET_MX95),
> +};
> +
> +static const struct dc_fg_subdev_match_data dc_fg_match_data_imx95 = {
> + .regmap_config = &dc_fg_regmap_config_imx95,
> + .reg_offset = OFFSET_MX95,
> + .info = dc_fg_info_imx95,
> +};
> +
> static inline void dc_fg_enable_shden(struct dc_fg *fg)
> {
> regmap_write_bits(fg->reg, FGSTCTRL, SHDEN, SHDEN);
> @@ -380,6 +427,7 @@ static void dc_fg_remove(struct platform_device *pdev)
>
> static const struct of_device_id dc_fg_dt_ids[] = {
> { .compatible = "fsl,imx8qxp-dc-framegen", .data = &dc_fg_match_data_imx8qxp },
> + { .compatible = "fsl,imx95-dc-framegen", .data = &dc_fg_match_data_imx95 },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_fg_dt_ids);
> diff --git a/drivers/gpu/drm/imx/dc/dc-fl.c b/drivers/gpu/drm/imx/dc/dc-fl.c
> index 53647e3a395b4..3aa437120b11d 100644
> --- a/drivers/gpu/drm/imx/dc/dc-fl.c
> +++ b/drivers/gpu/drm/imx/dc/dc-fl.c
> @@ -8,6 +8,7 @@
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> +#include <linux/property.h>
> #include <linux/regmap.h>
>
> #include <drm/drm_fourcc.h>
> @@ -27,6 +28,7 @@
> #define CONSTANTCOLOR 0x30
> #define LAYERPROPERTY 0x34
> #define FRAMEDIMENSIONS_IMX8QXP 0x150
> +#define FRAMEDIMENSIONS_IMX95 0x1d8
>
> struct dc_fl {
> struct dc_fu fu;
> @@ -47,6 +49,12 @@ static const struct dc_subdev_info dc_fl_info_imx8qxp[] = {
> { /* sentinel */ },
> };
>
> +static const struct dc_subdev_info dc_fl_info_imx95[] = {
> + { .reg_start = 0x4b5d1000, .id = 0, },
> + { .reg_start = 0x4b5e1000, .id = 1, },
> + { /* sentinel */ },
> +};
> +
> static const struct regmap_range dc_fl_regmap_ranges_imx8qxp[] = {
> regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS_IMX8QXP),
> };
> @@ -77,6 +85,36 @@ static const struct dc_fl_subdev_match_data dc_fl_match_data_imx8qxp = {
> .info = dc_fl_info_imx8qxp,
> };
>
> +static const struct regmap_range dc_fl_regmap_ranges_imx95[] = {
> + regmap_reg_range(STATICCONTROL, FRAMEDIMENSIONS_IMX95),
> +};
> +
> +static const struct regmap_access_table dc_fl_regmap_access_table_imx95 = {
> + .yes_ranges = dc_fl_regmap_ranges_imx95,
> + .n_yes_ranges = ARRAY_SIZE(dc_fl_regmap_ranges_imx95),
> +};
> +
> +static const struct regmap_config dc_fl_cfg_regmap_config_imx95 = {
> + .name = "cfg",
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .fast_io = true,
> + .wr_table = &dc_fl_regmap_access_table_imx95,
> + .rd_table = &dc_fl_regmap_access_table_imx95,
> + .max_register = FRAMEDIMENSIONS_IMX95,
> +};
> +
> +static const struct dc_fl_subdev_match_data dc_fl_match_data_imx95 = {
> + .regmap_config = &dc_fl_cfg_regmap_config_imx95,
> + .reg_offset_bbm = 0x4,
> + .reg_offset_base = 0x8,
> + .reg_offset_rest = 0x14,
> + .reg_framedimensions = FRAMEDIMENSIONS_IMX95,
> + .reg_frac_offset = 0x38,
> + .info = dc_fl_info_imx95,
> +};
> +
> static void dc_fl_set_fmt(struct dc_fu *fu, enum dc_fu_frac frac,
> const struct drm_format_info *format)
> {
> @@ -152,7 +190,7 @@ static int dc_fl_bind(struct device *dev, struct device *master, void *data)
> }
>
> fu->link_id = LINK_ID_FETCHLAYER0;
> - fu->id = DC_FETCHUNIT_FL0;
> + fu->id = DC_FETCHUNIT_FL0 + id;
> for (i = 0; i < DC_FETCHUNIT_FRAC_NUM; i++) {
> off = i * dc_fl_match_data->reg_frac_offset;
> off_base = off + dc_fl_match_data->reg_offset_base;
> @@ -202,6 +240,7 @@ static void dc_fl_remove(struct platform_device *pdev)
>
> static const struct of_device_id dc_fl_dt_ids[] = {
> { .compatible = "fsl,imx8qxp-dc-fetchlayer", .data = &dc_fl_match_data_imx8qxp },
> + { .compatible = "fsl,imx95-dc-fetchlayer", .data = &dc_fl_match_data_imx95 },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_fl_dt_ids);
> diff --git a/drivers/gpu/drm/imx/dc/dc-ic.c b/drivers/gpu/drm/imx/dc/dc-ic.c
> index c3d7e5aa4ae23..ac83642cbe4c8 100644
> --- a/drivers/gpu/drm/imx/dc/dc-ic.c
> +++ b/drivers/gpu/drm/imx/dc/dc-ic.c
> @@ -24,8 +24,13 @@
> #define USERINTERRUPTCLEAR(n) (0x50 + 4 * (n))
> #define USERINTERRUPTSTATUS(n) (0x58 + 4 * (n))
>
> -#define IRQ_COUNT_MAX 49
> -#define REG_NUM_MAX 2
> +#define INTERRUPTENABLE_MX95(n) (0x8 + 4 * (n))
> +#define INTERRUPTPRESET_MX95(n) (0x14 + 4 * (n))
> +#define INTERRUPTCLEAR_MX95(n) (0x20 + 4 * (n))
> +#define INTERRUPTSTATUS_MX95(n) (0x2c + 4 * (n))
> +
> +#define IRQ_COUNT_MAX 86
> +#define REG_NUM_MAX 3
>
> struct dc_ic_data {
> struct regmap *regs;
> @@ -109,6 +114,57 @@ static const struct dc_ic_subdev_match_data dc_ic_match_data_imx8qxp = {
> .reserved_irq = 35,
> };
>
> +static const struct regmap_range dc_ic_regmap_write_ranges_imx95[] = {
> + regmap_reg_range(INTERRUPTENABLE_MX95(0), INTERRUPTCLEAR_MX95(2)),
> +};
> +
> +static const struct regmap_access_table dc_ic_regmap_write_table_imx95 = {
> + .yes_ranges = dc_ic_regmap_write_ranges_imx95,
> + .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_write_ranges_imx95),
> +};
> +
> +static const struct regmap_range dc_ic_regmap_read_ranges_imx95[] = {
> + regmap_reg_range(INTERRUPTENABLE_MX95(0), INTERRUPTENABLE_MX95(2)),
> + regmap_reg_range(INTERRUPTSTATUS_MX95(0), INTERRUPTSTATUS_MX95(2)),
> +};
> +
> +static const struct regmap_access_table dc_ic_regmap_read_table_imx95 = {
> + .yes_ranges = dc_ic_regmap_read_ranges_imx95,
> + .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_read_ranges_imx95),
> +};
> +
> +static const struct regmap_range dc_ic_regmap_volatile_ranges_imx95[] = {
> + regmap_reg_range(INTERRUPTPRESET_MX95(0), INTERRUPTCLEAR_MX95(2)),
> +};
> +
> +static const struct regmap_access_table dc_ic_regmap_volatile_table_imx95 = {
> + .yes_ranges = dc_ic_regmap_volatile_ranges_imx95,
> + .n_yes_ranges = ARRAY_SIZE(dc_ic_regmap_volatile_ranges_imx95),
> +};
> +
> +static const struct regmap_config dc_ic_regmap_config_imx95 = {
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .fast_io = true,
> + .wr_table = &dc_ic_regmap_write_table_imx95,
> + .rd_table = &dc_ic_regmap_read_table_imx95,
> + .volatile_table = &dc_ic_regmap_volatile_table_imx95,
> + .max_register = INTERRUPTSTATUS_MX95(2),
> +};
> +
> +static const struct dc_ic_subdev_match_data dc_ic_match_data_imx95 = {
> + .regmap_config = &dc_ic_regmap_config_imx95,
> + .reg_enable = INTERRUPTENABLE_MX95(0),
> + .reg_clear = INTERRUPTCLEAR_MX95(0),
> + .reg_status = INTERRUPTSTATUS_MX95(0),
> + .reg_count = 3,
> + .irq_count = 86,
> + .user_irq = false,
> + .unused_irq = { 0x00000000, 0x00000000, 0xffc00000 },
> + .reserved_irq = -1,
> +};
> +
> static void dc_ic_irq_handler(struct irq_desc *desc)
> {
> struct dc_ic_entry *entry = irq_desc_get_handler_data(desc);
> @@ -304,6 +360,7 @@ static const struct dev_pm_ops dc_ic_pm_ops = {
>
> static const struct of_device_id dc_ic_dt_ids[] = {
> { .compatible = "fsl,imx8qxp-dc-intc", .data = &dc_ic_match_data_imx8qxp },
> + { .compatible = "fsl,imx95-dc-intc", .data = &dc_ic_match_data_imx95 },
> { /* sentinel */ }
> };
>
> diff --git a/drivers/gpu/drm/imx/dc/dc-lb.c b/drivers/gpu/drm/imx/dc/dc-lb.c
> index ba9183b244ab3..f38f338e48c4c 100644
> --- a/drivers/gpu/drm/imx/dc/dc-lb.c
> +++ b/drivers/gpu/drm/imx/dc/dc-lb.c
> @@ -9,6 +9,7 @@
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> +#include <linux/property.h>
> #include <linux/regmap.h>
>
> #include <drm/drm_blend.h>
> @@ -79,7 +80,7 @@ enum dc_lb_shadow_sel {
> BOTH = 0x2,
> };
>
> -static const struct dc_subdev_info dc_lb_info[] = {
> +static const struct dc_subdev_info dc_lb_info_imx8qxp[] = {
> { .reg_start = 0x56180ba0, .id = 0, },
> { .reg_start = 0x56180bc0, .id = 1, },
> { .reg_start = 0x56180be0, .id = 2, },
> @@ -87,6 +88,16 @@ static const struct dc_subdev_info dc_lb_info[] = {
> { /* sentinel */ },
> };
>
> +static const struct dc_subdev_info dc_lb_info_imx95[] = {
> + { .reg_start = 0x4b571000, .id = 0, },
> + { .reg_start = 0x4b581000, .id = 1, },
> + { .reg_start = 0x4b591000, .id = 2, },
> + { .reg_start = 0x4b5a1000, .id = 3, },
> + { .reg_start = 0x4b5b1000, .id = 4, },
> + { .reg_start = 0x4b5c1000, .id = 5, },
> + { /* sentinel */ },
> +};
> +
> static const struct regmap_range dc_lb_pec_regmap_access_ranges[] = {
> regmap_reg_range(PIXENGCFG_DYNAMIC, PIXENGCFG_DYNAMIC),
> };
> @@ -163,6 +174,44 @@ static const struct dc_lb_subdev_match_data dc_lb_match_data_imx8qxp = {
> .info = dc_lb_info_imx8qxp,
> };
>
> +static const enum dc_link_id prim_sels_imx95[] = {
> + /* common options */
> + LINK_ID_NONE,
> + LINK_ID_CONSTFRAME0,
> + LINK_ID_CONSTFRAME1,
> + LINK_ID_CONSTFRAME4_MX95,
> + LINK_ID_CONSTFRAME5_MX95,
> + /*
> + * special options:
> + * layerblend(n) has n special options,
> + * from layerblend0 to layerblend(n - 1), e.g.,
> + * layerblend3 has 3 special options -
> + * layerblend0/1/2.
> + */
> + LINK_ID_LAYERBLEND0_MX95,
> + LINK_ID_LAYERBLEND1_MX95,
> + LINK_ID_LAYERBLEND2_MX95,
> + LINK_ID_LAYERBLEND3_MX95,
> + LINK_ID_LAYERBLEND4_MX95,
> + LINK_ID_LAYERBLEND5_MX95,
> + LINK_ID_LAST
> +};
> +
> +static const enum dc_link_id sec_sels_imx95[] = {
> + LINK_ID_NONE,
> + LINK_ID_FETCHLAYER0,
> + LINK_ID_FETCHLAYER1_MX95,
> + LINK_ID_LAST
> +};
> +
> +static const struct dc_lb_subdev_match_data dc_lb_match_data_imx95 = {
> + .pri_sels = prim_sels_imx95,
> + .sec_sels = sec_sels_imx95,
> + .first_lb = LINK_ID_LAYERBLEND0_MX95,
> + .last_cf = 7,
> + .info = dc_lb_info_imx95,
> +};
> +
> enum dc_link_id dc_lb_get_link_id(struct dc_lb *lb)
> {
> return lb->link;
> @@ -333,6 +382,7 @@ static void dc_lb_remove(struct platform_device *pdev)
>
> static const struct of_device_id dc_lb_dt_ids[] = {
> { .compatible = "fsl,imx8qxp-dc-layerblend", .data = &dc_lb_match_data_imx8qxp },
> + { .compatible = "fsl,imx95-dc-layerblend", .data = &dc_lb_match_data_imx95 },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_lb_dt_ids);
> diff --git a/drivers/gpu/drm/imx/dc/dc-pe.h b/drivers/gpu/drm/imx/dc/dc-pe.h
> index 492d193127bc1..c7a50749db38f 100644
> --- a/drivers/gpu/drm/imx/dc/dc-pe.h
> +++ b/drivers/gpu/drm/imx/dc/dc-pe.h
> @@ -19,16 +19,25 @@
> #define CLKEN(n) ((n) << CLKEN_MASK_SHIFT)
>
> #define DC_DISP_FU_CNT 2
> -#define DC_LB_CNT 4
> +#define DC_LB_CNT 6
>
> enum dc_link_id {
> LINK_ID_NONE = 0x00,
> LINK_ID_CONSTFRAME0 = 0x0c,
> + LINK_ID_CONSTFRAME4_MX95 = 0x0d,
> LINK_ID_CONSTFRAME4_MX8QXP = 0x0e,
> LINK_ID_CONSTFRAME1 = 0x10,
> + LINK_ID_CONSTFRAME5_MX95 = 0x11,
> LINK_ID_CONSTFRAME5_MX8QXP = 0x12,
> + LINK_ID_LAYERBLEND0_MX95 = 0x14,
> + LINK_ID_LAYERBLEND1_MX95 = 0x15,
> + LINK_ID_LAYERBLEND2_MX95 = 0x16,
> + LINK_ID_LAYERBLEND3_MX95 = 0x17,
> + LINK_ID_LAYERBLEND4_MX95 = 0x18,
> + LINK_ID_LAYERBLEND5_MX95 = 0x19,
> LINK_ID_FETCHWARP2 = 0x14,
> LINK_ID_FETCHLAYER0 = 0x1a,
> + LINK_ID_FETCHLAYER1_MX95 = 0x1b,
> LINK_ID_LAYERBLEND0_MX8QXP = 0x21,
> LINK_ID_LAYERBLEND1_MX8QXP = 0x22,
> LINK_ID_LAYERBLEND2_MX8QXP = 0x23,
> diff --git a/drivers/gpu/drm/imx/dc/dc-tc.c b/drivers/gpu/drm/imx/dc/dc-tc.c
> index 1f287706e8706..9a08fcabc625a 100644
> --- a/drivers/gpu/drm/imx/dc/dc-tc.c
> +++ b/drivers/gpu/drm/imx/dc/dc-tc.c
> @@ -37,6 +37,12 @@ static const struct dc_subdev_info dc_tc_info_imx8qxp[] = {
> { /* sentinel */ },
> };
>
> +static const struct dc_subdev_info dc_tc_info_imx95[] = {
> + { .reg_start = 0x4b711000, .id = 0, },
> + { .reg_start = 0x4b771000, .id = 1, },
> + { /* sentinel */ },
> +};
> +
> static const struct regmap_range dc_tc_regmap_ranges[] = {
> regmap_reg_range(TCON_CTRL, TCON_CTRL),
> regmap_reg_range(MAPBIT3_0, MAPBIT31_28),
> @@ -72,6 +78,11 @@ static const struct dc_tc_subdev_match_data dc_tc_match_data_imx8qxp = {
> .info = dc_tc_info_imx8qxp,
> };
>
> +static const struct dc_tc_subdev_match_data dc_tc_match_data_imx95 = {
> + .need_config = false,
> + .info = dc_tc_info_imx95,
> +};
> +
> void dc_tc_init(struct dc_tc *tc)
> {
> if (!tc->need_config)
> @@ -149,6 +160,7 @@ static void dc_tc_remove(struct platform_device *pdev)
>
> static const struct of_device_id dc_tc_dt_ids[] = {
> { .compatible = "fsl,imx8qxp-dc-tcon", .data = &dc_tc_match_data_imx8qxp },
> + { .compatible = "fsl,imx95-dc-tcon", .data = &dc_tc_match_data_imx95 },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, dc_tc_dt_ids);
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 24/39] drm/imx: Add more RGB swizzling options
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (22 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 23/39] drm/imx: dc: Add OF match data for i.MX95 Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-11 16:51 ` [PATCH 25/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel interleaver support Marek Vasut
` (16 subsequent siblings)
40 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Add additional buffer format swizzling options beyond XR24, the
hardware is capable of sampling other formats, fill them in.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/imx/dc/dc-fu.c | 40 +++++++++++++++++++++++++++++++
drivers/gpu/drm/imx/dc/dc-plane.c | 8 +++++++
2 files changed, 48 insertions(+)
diff --git a/drivers/gpu/drm/imx/dc/dc-fu.c b/drivers/gpu/drm/imx/dc/dc-fu.c
index cc8b0d05891fd..dd4a3d20fdbf4 100644
--- a/drivers/gpu/drm/imx/dc/dc-fu.c
+++ b/drivers/gpu/drm/imx/dc/dc-fu.c
@@ -65,6 +65,46 @@ static const struct dc_fu_pixel_format pixel_formats[] = {
DRM_FORMAT_XRGB8888,
R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
R_SHIFT(16) | G_SHIFT(8) | B_SHIFT(0) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_ARGB8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(8),
+ R_SHIFT(16) | G_SHIFT(8) | B_SHIFT(0) | A_SHIFT(24),
+ }, {
+ DRM_FORMAT_ABGR8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(8),
+ R_SHIFT(0) | G_SHIFT(8) | B_SHIFT(16) | A_SHIFT(24),
+ }, {
+ DRM_FORMAT_XBGR8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(0) | G_SHIFT(8) | B_SHIFT(16) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_RGBA8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(8),
+ R_SHIFT(24) | G_SHIFT(16) | B_SHIFT(8) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_RGBX8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(24) | G_SHIFT(16) | B_SHIFT(8) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_BGRA8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(8),
+ R_SHIFT(8) | G_SHIFT(16) | B_SHIFT(24) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_BGRX8888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(8) | G_SHIFT(16) | B_SHIFT(24) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_RGB888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(16) | G_SHIFT(8) | B_SHIFT(0) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_BGR888,
+ R_BITS(8) | G_BITS(8) | B_BITS(8) | A_BITS(0),
+ R_SHIFT(0) | G_SHIFT(8) | B_SHIFT(16) | A_SHIFT(0),
+ }, {
+ DRM_FORMAT_RGB565,
+ R_BITS(5) | G_BITS(6) | B_BITS(5) | A_BITS(0),
+ R_SHIFT(11) | G_SHIFT(5) | B_SHIFT(0) | A_SHIFT(0),
},
};
diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c
index 18010c2b0bd78..182dff15af679 100644
--- a/drivers/gpu/drm/imx/dc/dc-plane.c
+++ b/drivers/gpu/drm/imx/dc/dc-plane.c
@@ -34,6 +34,14 @@ do { \
static const uint32_t dc_plane_formats[] = {
DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_BGRX8888,
+ DRM_FORMAT_RGB565,
};
static const struct drm_plane_funcs dc_plane_funcs = {
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* [PATCH 25/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel interleaver support
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (23 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 24/39] drm/imx: Add more RGB swizzling options Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 18:57 ` Frank Li
2025-10-11 16:51 ` [PATCH 26/39] drm/bridge: imx: Add " Marek Vasut
` (15 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Document NXP i.MX95 pixel interleaver bridge support.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
.../bridge/fsl,imx95-pixel-interleaver.yaml | 85 +++++++++++++++++++
1 file changed, 85 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-interleaver.yaml
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-interleaver.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-interleaver.yaml
new file mode 100644
index 0000000000000..6a0647f060a02
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-interleaver.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/fsl,imx95-pixel-interleaver.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX95 Display Pixel Interleaver
+
+maintainers:
+ - Liu Ying <victor.liu@nxp.com>
+ - Marek Vasut <marek.vasut@mailbox.org>
+
+description: |
+ The Freescale i.MX95 Display Pixel Interleaver receives and processes
+ 2 input display streams from the display controller and routes those
+ to 3 pixel link output ports. The interleaver is capable of YUV444 to
+ YUV422 conversion and pixel interleaving.
+
+properties:
+ compatible:
+ const: fsl,imx95-pixel-interleaver
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ fsl,syscon:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: |
+ A phandle which points to Control and Status Registers (CSR) module.
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: The pixel link input port node from upstream video source.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: The pixel link output port node to downstream bridge.
+
+ required:
+ - port@0
+ - port@1
+
+required:
+ - compatible
+ - fsl,syscon
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ bridge@4b0d0000 {
+ compatible = "fsl,imx95-pixel-interleaver";
+ reg = <0x4b0d0000 0x50>;
+ clocks = <&scmi_clk 0>;
+ fsl,syscon = <&dispmix_csr>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pixel_interleaver_disp0_to_dpu_disp0: endpoint {
+ remote-endpoint = <&dpu_disp0_to_pixel_interleaver_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pixel_interleaver_disp0_to_display_pixel_link0: endpoint {
+ remote-endpoint = <&display_pixel_link0_to_pixel_interleaver_disp0>;
+ };
+ };
+ };
+ };
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 25/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel interleaver support
2025-10-11 16:51 ` [PATCH 25/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel interleaver support Marek Vasut
@ 2025-10-13 18:57 ` Frank Li
2025-10-17 14:55 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 18:57 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:40PM +0200, Marek Vasut wrote:
> Document NXP i.MX95 pixel interleaver bridge support.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../bridge/fsl,imx95-pixel-interleaver.yaml | 85 +++++++++++++++++++
> 1 file changed, 85 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-interleaver.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-interleaver.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-interleaver.yaml
> new file mode 100644
> index 0000000000000..6a0647f060a02
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-interleaver.yaml
> @@ -0,0 +1,85 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/fsl,imx95-pixel-interleaver.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX95 Display Pixel Interleaver
> +
> +maintainers:
> + - Liu Ying <victor.liu@nxp.com>
> + - Marek Vasut <marek.vasut@mailbox.org>
> +
> +description: |
Needn't |
> + The Freescale i.MX95 Display Pixel Interleaver receives and processes
> + 2 input display streams from the display controller and routes those
> + to 3 pixel link output ports. The interleaver is capable of YUV444 to
> + YUV422 conversion and pixel interleaving.
> +
> +properties:
> + compatible:
> + const: fsl,imx95-pixel-interleaver
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + fsl,syscon:
> + $ref: /schemas/types.yaml#/definitions/phandle
> + description: |
> + A phandle which points to Control and Status Registers (CSR) module.
Need justify why not standard interface such as clock, phy, reset ...
> +
> + ports:
> + $ref: /schemas/graph.yaml#/properties/ports
> +
> + properties:
> + port@0:
> + $ref: /schemas/graph.yaml#/properties/port
video-interfaces.yaml?
> + description: The pixel link input port node from upstream video source.
> +
> + port@1:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: The pixel link output port node to downstream bridge.
> +
> + required:
> + - port@0
> + - port@1
> +
> +required:
> + - compatible
> + - fsl,syscon
> + - ports
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + bridge@4b0d0000 {
> + compatible = "fsl,imx95-pixel-interleaver";
> + reg = <0x4b0d0000 0x50>;
> + clocks = <&scmi_clk 0>;
> + fsl,syscon = <&dispmix_csr>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> +
> + pixel_interleaver_disp0_to_dpu_disp0: endpoint {
example needn't label pixel_interleaver_disp0_to_dpu_disp0
Frank
> + remote-endpoint = <&dpu_disp0_to_pixel_interleaver_disp0>;
> + };
> + };
> +
> + port@1 {
> + reg = <1>;
> +
> + pixel_interleaver_disp0_to_display_pixel_link0: endpoint {
> + remote-endpoint = <&display_pixel_link0_to_pixel_interleaver_disp0>;
> + };
> + };
> + };
> + };
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 25/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel interleaver support
2025-10-13 18:57 ` Frank Li
@ 2025-10-17 14:55 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 14:55 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 8:57 PM, Frank Li wrote:
Hello Frank,
>> + fsl,syscon:
>> + $ref: /schemas/types.yaml#/definitions/phandle
>> + description: |
>> + A phandle which points to Control and Status Registers (CSR) module.
>
> Need justify why not standard interface such as clock, phy, reset ...
Because this is neither clock, nor reset nor anything else. This is
really only a remote register which controls the pixel interleaving.
Therefore, syscon.
>> +
>> + ports:
>> + $ref: /schemas/graph.yaml#/properties/ports
>> +
>> + properties:
>> + port@0:
>> + $ref: /schemas/graph.yaml#/properties/port
>
> video-interfaces.yaml?
No, because none of the properties in video-interfaces.yaml are
applicable to this port as far as I can tell.
The rest is fixed, thanks !
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 26/39] drm/bridge: imx: Add NXP i.MX95 pixel interleaver support
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (24 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 25/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel interleaver support Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:02 ` Frank Li
2025-10-11 16:51 ` [PATCH 27/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel link support Marek Vasut
` (14 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Liu Ying, Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
From: Liu Ying <victor.liu@nxp.com>
Add NXP i.MX95 pixel interleaver support.
Signed-off-by: Liu Ying <victor.liu@nxp.com>
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/bridge/imx/Kconfig | 9 +
drivers/gpu/drm/bridge/imx/Makefile | 1 +
.../drm/bridge/imx/imx95-pixel-interleaver.c | 217 ++++++++++++++++++
3 files changed, 227 insertions(+)
create mode 100644 drivers/gpu/drm/bridge/imx/imx95-pixel-interleaver.c
diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig
index 9a480c6abb856..3e1b1d825d7bf 100644
--- a/drivers/gpu/drm/bridge/imx/Kconfig
+++ b/drivers/gpu/drm/bridge/imx/Kconfig
@@ -88,4 +88,13 @@ config DRM_IMX93_MIPI_DSI
Choose this to enable MIPI DSI controller found in Freescale i.MX93
processor.
+config DRM_IMX95_PIXEL_INTERLEAVER
+ tristate "NXP i.MX95 pixel interleaver"
+ depends on OF && MFD_SYSCON && COMMON_CLK
+ select DRM_KMS_HELPER
+ select REGMAP_MMIO
+ help
+ Choose this to enable pixel interleaver found in NXP i.MX95
+ processors.
+
endif # ARCH_MXC || COMPILE_TEST
diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile
index dd5d485848066..583054c70f002 100644
--- a/drivers/gpu/drm/bridge/imx/Makefile
+++ b/drivers/gpu/drm/bridge/imx/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o
obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o
obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o
obj-$(CONFIG_DRM_IMX93_MIPI_DSI) += imx93-mipi-dsi.o
+obj-$(CONFIG_DRM_IMX95_PIXEL_INTERLEAVER) += imx95-pixel-interleaver.o
diff --git a/drivers/gpu/drm/bridge/imx/imx95-pixel-interleaver.c b/drivers/gpu/drm/bridge/imx/imx95-pixel-interleaver.c
new file mode 100644
index 0000000000000..e6d96e68db895
--- /dev/null
+++ b/drivers/gpu/drm/bridge/imx/imx95-pixel-interleaver.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright 2023 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/media-bus-format.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_bridge.h>
+
+#define PIXEL_INTERLEAVER_CTRL 0x4
+#define DISP_IN_SEL BIT(1)
+#define MODE BIT(0)
+
+#define CTRL 0x0
+#define VSYNC_POLARITY BIT(10)
+#define HSYNC_POLARITY BIT(9)
+
+#define SWRST 0x20
+#define SW_RST BIT(1)
+
+#define IE 0x30
+
+#define DRIVER_NAME "imx95-pixel-interleaver"
+
+struct imx95_pixel_interleaver_bridge {
+ struct drm_bridge bridge;
+ struct drm_bridge *next_bridge;
+ struct device *dev;
+ void __iomem *regs;
+ struct regmap *regmap;
+ struct clk *clk_bus;
+};
+
+static void
+imx95_pixel_interleaver_bridge_sw_reset(struct imx95_pixel_interleaver_bridge *pi)
+{
+ clk_prepare_enable(pi->clk_bus);
+
+ writel(SW_RST, pi->regs + SWRST);
+ usleep_range(10, 20);
+ writel(0, pi->regs + SWRST);
+
+ clk_disable_unprepare(pi->clk_bus);
+}
+
+static int
+imx95_pixel_interleaver_bridge_attach(struct drm_bridge *bridge,
+ struct drm_encoder *encoder,
+ enum drm_bridge_attach_flags flags)
+{
+ struct imx95_pixel_interleaver_bridge *pi = bridge->driver_private;
+
+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+ dev_err(pi->dev, "do not support creating a drm_connector\n");
+ return -EINVAL;
+ }
+
+ return drm_bridge_attach(encoder, pi->next_bridge, bridge,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+}
+
+static void
+imx95_pixel_interleaver_bridge_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adjusted_mode)
+{
+ struct imx95_pixel_interleaver_bridge *pi = bridge->driver_private;
+
+ imx95_pixel_interleaver_bridge_sw_reset(pi);
+
+ clk_prepare_enable(pi->clk_bus);
+
+ /* HSYNC and VSYNC are active low. Data Enable is active high */
+ writel(HSYNC_POLARITY | VSYNC_POLARITY, pi->regs + CTRL);
+
+ /* Disable interrupts */
+ writel(0, pi->regs + IE);
+
+ clk_disable_unprepare(pi->clk_bus);
+}
+
+static void
+imx95_pixel_interleaver_bridge_enable(struct drm_bridge *bridge)
+{
+ struct imx95_pixel_interleaver_bridge *pi = bridge->driver_private;
+
+ regmap_write(pi->regmap, PIXEL_INTERLEAVER_CTRL, 0);
+}
+
+static u32 *
+imx95_pixel_interleaver_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state,
+ u32 output_fmt,
+ unsigned int *num_input_fmts)
+{
+ u32 *input_fmts;
+
+ if (output_fmt != MEDIA_BUS_FMT_RGB888_1X24)
+ return NULL;
+
+ *num_input_fmts = 1;
+
+ input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
+ if (!input_fmts)
+ return NULL;
+
+ input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
+
+ return input_fmts;
+}
+
+static const struct drm_bridge_funcs imx95_pixel_interleaver_bridge_funcs = {
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .atomic_reset = drm_atomic_helper_bridge_reset,
+ .attach = imx95_pixel_interleaver_bridge_attach,
+ .mode_set = imx95_pixel_interleaver_bridge_mode_set,
+ .enable = imx95_pixel_interleaver_bridge_enable,
+ .atomic_get_input_bus_fmts =
+ imx95_pixel_interleaver_bridge_atomic_get_input_bus_fmts,
+};
+
+static int imx95_pixel_interleaver_bridge_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *remote, *remote_port, *np = dev->of_node;
+ struct imx95_pixel_interleaver_bridge *pi;
+
+ pi = devm_drm_bridge_alloc(dev, struct imx95_pixel_interleaver_bridge, bridge,
+ &imx95_pixel_interleaver_bridge_funcs);
+ if (IS_ERR(pi))
+ return PTR_ERR(pi);
+
+ pi->dev = dev;
+ platform_set_drvdata(pdev, pi);
+
+ pi->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(pi->regs))
+ return PTR_ERR(pi->regs);
+
+ pi->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,syscon");
+ if (IS_ERR(pi->regmap))
+ return dev_err_probe(dev, PTR_ERR(pi->regmap), "failed to get regmap\n");
+
+ pi->clk_bus = devm_clk_get(dev, NULL);
+ if (IS_ERR(pi->clk_bus))
+ return dev_err_probe(dev, PTR_ERR(pi->clk_bus), "failed to get clock\n");
+
+ pi->bridge.driver_private = pi;
+ pi->bridge.of_node = np;
+
+ remote = of_graph_get_remote_node(np, 1, 0);
+ if (!remote)
+ return dev_err_probe(dev, -EINVAL, "no remote node for port@1 endpoint\n");
+
+ remote_port = of_graph_get_port_by_id(remote, 0);
+ of_node_put(remote);
+ if (!remote_port)
+ return dev_err_probe(dev, -EINVAL, "no remote port\n");
+
+ pi->next_bridge = of_drm_find_bridge(remote_port);
+ of_node_put(remote_port);
+ if (!pi->next_bridge) {
+ dev_err(dev, "failed to find next bridge for port@1 endpoint\n");
+ return -EPROBE_DEFER;
+ }
+
+ imx95_pixel_interleaver_bridge_sw_reset(pi);
+
+ drm_bridge_add(&pi->bridge);
+
+ return 0;
+}
+
+static void imx95_pixel_interleaver_bridge_remove(struct platform_device *pdev)
+{
+ struct imx95_pixel_interleaver_bridge *pi = platform_get_drvdata(pdev);
+
+ drm_bridge_remove(&pi->bridge);
+}
+
+static const struct of_device_id imx95_pixel_interleaver_bridge_dt_ids[] = {
+ { .compatible = "fsl,imx95-pixel-interleaver", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx95_pixel_interleaver_bridge_dt_ids);
+
+static struct platform_driver imx95_pixel_interleaver_bridge_driver = {
+ .probe = imx95_pixel_interleaver_bridge_probe,
+ .remove = imx95_pixel_interleaver_bridge_remove,
+ .driver = {
+ .of_match_table = imx95_pixel_interleaver_bridge_dt_ids,
+ .name = DRIVER_NAME,
+ },
+};
+
+module_platform_driver(imx95_pixel_interleaver_bridge_driver);
+
+MODULE_DESCRIPTION("i.MX95 display pixel interleaver bridge driver");
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 26/39] drm/bridge: imx: Add NXP i.MX95 pixel interleaver support
2025-10-11 16:51 ` [PATCH 26/39] drm/bridge: imx: Add " Marek Vasut
@ 2025-10-13 19:02 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:02 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Liu Ying, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach, Peng Fan,
Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:41PM +0200, Marek Vasut wrote:
> From: Liu Ying <victor.liu@nxp.com>
>
> Add NXP i.MX95 pixel interleaver support.
>
> Signed-off-by: Liu Ying <victor.liu@nxp.com>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/bridge/imx/Kconfig | 9 +
> drivers/gpu/drm/bridge/imx/Makefile | 1 +
> .../drm/bridge/imx/imx95-pixel-interleaver.c | 217 ++++++++++++++++++
> 3 files changed, 227 insertions(+)
> create mode 100644 drivers/gpu/drm/bridge/imx/imx95-pixel-interleaver.c
>
> diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig
> index 9a480c6abb856..3e1b1d825d7bf 100644
> --- a/drivers/gpu/drm/bridge/imx/Kconfig
> +++ b/drivers/gpu/drm/bridge/imx/Kconfig
> @@ -88,4 +88,13 @@ config DRM_IMX93_MIPI_DSI
> Choose this to enable MIPI DSI controller found in Freescale i.MX93
> processor.
>
> +config DRM_IMX95_PIXEL_INTERLEAVER
> + tristate "NXP i.MX95 pixel interleaver"
> + depends on OF && MFD_SYSCON && COMMON_CLK
> + select DRM_KMS_HELPER
> + select REGMAP_MMIO
> + help
> + Choose this to enable pixel interleaver found in NXP i.MX95
> + processors.
> +
> endif # ARCH_MXC || COMPILE_TEST
> diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile
> index dd5d485848066..583054c70f002 100644
> --- a/drivers/gpu/drm/bridge/imx/Makefile
> +++ b/drivers/gpu/drm/bridge/imx/Makefile
> @@ -8,3 +8,4 @@ obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o
> obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o
> obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o
> obj-$(CONFIG_DRM_IMX93_MIPI_DSI) += imx93-mipi-dsi.o
> +obj-$(CONFIG_DRM_IMX95_PIXEL_INTERLEAVER) += imx95-pixel-interleaver.o
> diff --git a/drivers/gpu/drm/bridge/imx/imx95-pixel-interleaver.c b/drivers/gpu/drm/bridge/imx/imx95-pixel-interleaver.c
> new file mode 100644
> index 0000000000000..e6d96e68db895
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/imx/imx95-pixel-interleaver.c
> @@ -0,0 +1,217 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * Copyright 2023 NXP
2025?
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/media-bus-format.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <drm/drm_atomic_state_helper.h>
> +#include <drm/drm_bridge.h>
> +
> +#define PIXEL_INTERLEAVER_CTRL 0x4
> +#define DISP_IN_SEL BIT(1)
> +#define MODE BIT(0)
> +
> +#define CTRL 0x0
> +#define VSYNC_POLARITY BIT(10)
> +#define HSYNC_POLARITY BIT(9)
> +
> +#define SWRST 0x20
> +#define SW_RST BIT(1)
> +
> +#define IE 0x30
Register name is too short. add prefix for it.
> +
> +#define DRIVER_NAME "imx95-pixel-interleaver"
Only use once, needn't it.
> +
> +struct imx95_pixel_interleaver_bridge {
> + struct drm_bridge bridge;
> + struct drm_bridge *next_bridge;
> + struct device *dev;
> + void __iomem *regs;
> + struct regmap *regmap;
> + struct clk *clk_bus;
> +};
> +
> +static void
> +imx95_pixel_interleaver_bridge_sw_reset(struct imx95_pixel_interleaver_bridge *pi)
> +{
> + clk_prepare_enable(pi->clk_bus);
need check ret value.
> +
> + writel(SW_RST, pi->regs + SWRST);
> + usleep_range(10, 20);
> + writel(0, pi->regs + SWRST);
> +
> + clk_disable_unprepare(pi->clk_bus);
> +}
> +
> +static int
> +imx95_pixel_interleaver_bridge_attach(struct drm_bridge *bridge,
> + struct drm_encoder *encoder,
> + enum drm_bridge_attach_flags flags)
> +{
> + struct imx95_pixel_interleaver_bridge *pi = bridge->driver_private;
> +
> + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
> + dev_err(pi->dev, "do not support creating a drm_connector\n");
> + return -EINVAL;
> + }
> +
> + return drm_bridge_attach(encoder, pi->next_bridge, bridge,
> + DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +}
> +
> +static void
> +imx95_pixel_interleaver_bridge_mode_set(struct drm_bridge *bridge,
> + const struct drm_display_mode *mode,
> + const struct drm_display_mode *adjusted_mode)
> +{
> + struct imx95_pixel_interleaver_bridge *pi = bridge->driver_private;
> +
> + imx95_pixel_interleaver_bridge_sw_reset(pi);
> +
> + clk_prepare_enable(pi->clk_bus);
> +
> + /* HSYNC and VSYNC are active low. Data Enable is active high */
> + writel(HSYNC_POLARITY | VSYNC_POLARITY, pi->regs + CTRL);
> +
> + /* Disable interrupts */
> + writel(0, pi->regs + IE);
> +
> + clk_disable_unprepare(pi->clk_bus);
> +}
> +
> +static void
> +imx95_pixel_interleaver_bridge_enable(struct drm_bridge *bridge)
> +{
> + struct imx95_pixel_interleaver_bridge *pi = bridge->driver_private;
> +
> + regmap_write(pi->regmap, PIXEL_INTERLEAVER_CTRL, 0);
Look like it can use standard reset interface
Frank
> +}
> +
> +static u32 *
> +imx95_pixel_interleaver_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
> + struct drm_bridge_state *bridge_state,
> + struct drm_crtc_state *crtc_state,
> + struct drm_connector_state *conn_state,
> + u32 output_fmt,
> + unsigned int *num_input_fmts)
> +{
> + u32 *input_fmts;
> +
> + if (output_fmt != MEDIA_BUS_FMT_RGB888_1X24)
> + return NULL;
> +
> + *num_input_fmts = 1;
> +
> + input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
> + if (!input_fmts)
> + return NULL;
> +
> + input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
> +
> + return input_fmts;
> +}
> +
> +static const struct drm_bridge_funcs imx95_pixel_interleaver_bridge_funcs = {
> + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> + .atomic_reset = drm_atomic_helper_bridge_reset,
> + .attach = imx95_pixel_interleaver_bridge_attach,
> + .mode_set = imx95_pixel_interleaver_bridge_mode_set,
> + .enable = imx95_pixel_interleaver_bridge_enable,
> + .atomic_get_input_bus_fmts =
> + imx95_pixel_interleaver_bridge_atomic_get_input_bus_fmts,
> +};
> +
> +static int imx95_pixel_interleaver_bridge_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *remote, *remote_port, *np = dev->of_node;
> + struct imx95_pixel_interleaver_bridge *pi;
> +
> + pi = devm_drm_bridge_alloc(dev, struct imx95_pixel_interleaver_bridge, bridge,
> + &imx95_pixel_interleaver_bridge_funcs);
> + if (IS_ERR(pi))
> + return PTR_ERR(pi);
> +
> + pi->dev = dev;
> + platform_set_drvdata(pdev, pi);
> +
> + pi->regs = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(pi->regs))
> + return PTR_ERR(pi->regs);
> +
> + pi->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,syscon");
> + if (IS_ERR(pi->regmap))
> + return dev_err_probe(dev, PTR_ERR(pi->regmap), "failed to get regmap\n");
> +
> + pi->clk_bus = devm_clk_get(dev, NULL);
> + if (IS_ERR(pi->clk_bus))
> + return dev_err_probe(dev, PTR_ERR(pi->clk_bus), "failed to get clock\n");
> +
> + pi->bridge.driver_private = pi;
> + pi->bridge.of_node = np;
> +
> + remote = of_graph_get_remote_node(np, 1, 0);
> + if (!remote)
> + return dev_err_probe(dev, -EINVAL, "no remote node for port@1 endpoint\n");
> +
> + remote_port = of_graph_get_port_by_id(remote, 0);
> + of_node_put(remote);
> + if (!remote_port)
> + return dev_err_probe(dev, -EINVAL, "no remote port\n");
> +
> + pi->next_bridge = of_drm_find_bridge(remote_port);
> + of_node_put(remote_port);
> + if (!pi->next_bridge) {
> + dev_err(dev, "failed to find next bridge for port@1 endpoint\n");
> + return -EPROBE_DEFER;
> + }
> +
> + imx95_pixel_interleaver_bridge_sw_reset(pi);
> +
> + drm_bridge_add(&pi->bridge);
> +
> + return 0;
> +}
> +
> +static void imx95_pixel_interleaver_bridge_remove(struct platform_device *pdev)
> +{
> + struct imx95_pixel_interleaver_bridge *pi = platform_get_drvdata(pdev);
> +
> + drm_bridge_remove(&pi->bridge);
> +}
> +
> +static const struct of_device_id imx95_pixel_interleaver_bridge_dt_ids[] = {
> + { .compatible = "fsl,imx95-pixel-interleaver", },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, imx95_pixel_interleaver_bridge_dt_ids);
> +
> +static struct platform_driver imx95_pixel_interleaver_bridge_driver = {
> + .probe = imx95_pixel_interleaver_bridge_probe,
> + .remove = imx95_pixel_interleaver_bridge_remove,
> + .driver = {
> + .of_match_table = imx95_pixel_interleaver_bridge_dt_ids,
> + .name = DRIVER_NAME,
> + },
> +};
> +
> +module_platform_driver(imx95_pixel_interleaver_bridge_driver);
> +
> +MODULE_DESCRIPTION("i.MX95 display pixel interleaver bridge driver");
> +MODULE_AUTHOR("NXP Semiconductor");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:" DRIVER_NAME);
Drop it, see
https://lore.kernel.org/imx/daf6fb72-5849-49f7-b17a-818944eb9f1e@kernel.org/
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 27/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel link support
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (25 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 26/39] drm/bridge: imx: Add " Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:08 ` Frank Li
2025-10-11 16:51 ` [PATCH 28/39] drm/bridge: imx: Add " Marek Vasut
` (13 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Document NXP i.MX95 pixel link bridge support.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
.../display/bridge/fsl,imx95-pixel-link.yaml | 101 ++++++++++++++++++
1 file changed, 101 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-link.yaml
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-link.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-link.yaml
new file mode 100644
index 0000000000000..b37888adfa45e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-link.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/fsl,imx95-pixel-link.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX95 Display Pixel Link
+
+maintainers:
+ - Liu Ying <victor.liu@nxp.com>
+ - Marek Vasut <marek.vasut@mailbox.org>
+
+description: |
+ The Freescale i.MX95 Display Pixel Link (DPL) forms a standard
+ asynchronous linkage between pixel sources (display controller
+ or camera module) and pixel consumers(imaging or displays).
+ It consists of two distinct functions, a pixel transfer function
+ and a control interface. Multiple pixel channels can exist per one
+ control channel. This binding documentation is only for pixel links
+ whose pixel sources are display controllers.
+
+ The i.MX95 Display Pixel Link is accessed via syscon.
+
+properties:
+ compatible:
+ const: fsl,imx95-dc-pixel-link
+
+ fsl,dc-stream-id:
+ $ref: /schemas/types.yaml#/definitions/uint8
+ description: |
+ u8 value representing the display controller stream index that the pixel
+ link connects to.
+ enum: [0, 1]
+
+ fsl,syscon:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: |
+ A phandle which points to Control and Status Registers (CSR) module.
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: The pixel link input port node from upstream video source.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: The pixel link output port node to downstream bridge.
+
+ required:
+ - port@0
+ - port@1
+
+required:
+ - compatible
+ - fsl,dc-stream-id
+ - fsl,syscon
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ dc0-pixel-link0 {
+ compatible = "fsl,imx95-dc-pixel-link";
+ fsl,dc-stream-id = /bits/ 8 <0>;
+ fsl,syscon = <&dispmix_csr>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* from DC 0 pixel interleaver channel0 */
+ port@0 {
+ reg = <0>;
+
+ dc0_pixel_link0_dc0_pixel_interleaver_ch0: endpoint {
+ remote-endpoint = <&dc0_pixel_interleaver_ch0_dc0_pixel_link0>;
+ };
+ };
+
+ /* to MIPI/LVDS combo subsystems */
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&mipi_lvds_0_pxl2dpi_dc0_pixel_link0>;
+ };
+
+ dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&mipi_lvds_1_pxl2dpi_dc0_pixel_link0>;
+ };
+ };
+ };
+ };
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 27/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel link support
2025-10-11 16:51 ` [PATCH 27/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel link support Marek Vasut
@ 2025-10-13 19:08 ` Frank Li
2025-10-17 15:01 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:08 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:42PM +0200, Marek Vasut wrote:
> Document NXP i.MX95 pixel link bridge support.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../display/bridge/fsl,imx95-pixel-link.yaml | 101 ++++++++++++++++++
> 1 file changed, 101 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-link.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-link.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-link.yaml
> new file mode 100644
> index 0000000000000..b37888adfa45e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-link.yaml
> @@ -0,0 +1,101 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/fsl,imx95-pixel-link.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX95 Display Pixel Link
> +
> +maintainers:
> + - Liu Ying <victor.liu@nxp.com>
> + - Marek Vasut <marek.vasut@mailbox.org>
> +
> +description: |
use >
> + The Freescale i.MX95 Display Pixel Link (DPL) forms a standard
> + asynchronous linkage between pixel sources (display controller
> + or camera module) and pixel consumers(imaging or displays).
> + It consists of two distinct functions, a pixel transfer function
> + and a control interface. Multiple pixel channels can exist per one
> + control channel. This binding documentation is only for pixel links
> + whose pixel sources are display controllers.
> +
> + The i.MX95 Display Pixel Link is accessed via syscon.
> +
> +properties:
> + compatible:
> + const: fsl,imx95-dc-pixel-link
> +
> + fsl,dc-stream-id:
> + $ref: /schemas/types.yaml#/definitions/uint8
> + description: |
Needn't |
why need this id
> + u8 value representing the display controller stream index that the pixel
> + link connects to.
> + enum: [0, 1]
> +
> + fsl,syscon:
> + $ref: /schemas/types.yaml#/definitions/phandle
> + description: |
> + A phandle which points to Control and Status Registers (CSR) module.
Why not use stardard interface, like reset, clock, phy ...
> +
> + ports:
> + $ref: /schemas/graph.yaml#/properties/ports
> +
> + properties:
> + port@0:
> + $ref: /schemas/graph.yaml#/properties/port
video-interfaces.yaml?
> + description: The pixel link input port node from upstream video source.
> +
> + port@1:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: The pixel link output port node to downstream bridge.
> +
> + required:
> + - port@0
> + - port@1
> +
> +required:
> + - compatible
> + - fsl,dc-stream-id
> + - fsl,syscon
> + - ports
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + dc0-pixel-link0 {
> + compatible = "fsl,imx95-dc-pixel-link";
> + fsl,dc-stream-id = /bits/ 8 <0>;
> + fsl,syscon = <&dispmix_csr>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + /* from DC 0 pixel interleaver channel0 */
> + port@0 {
> + reg = <0>;
> +
> + dc0_pixel_link0_dc0_pixel_interleaver_ch0: endpoint {
> + remote-endpoint = <&dc0_pixel_interleaver_ch0_dc0_pixel_link0>;
> + };
> + };
> +
> + /* to MIPI/LVDS combo subsystems */
> + port@1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>;
> +
> + dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint@0 {
Needn't label dc0_pixel_link0_mipi_lvds_0_pxl2dpi
> + reg = <0>;
> + remote-endpoint = <&mipi_lvds_0_pxl2dpi_dc0_pixel_link0>;
> + };
> +
> + dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint@1 {
> + reg = <1>;
> + remote-endpoint = <&mipi_lvds_1_pxl2dpi_dc0_pixel_link0>;
> + };
> + };
> + };
> + };
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 27/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel link support
2025-10-13 19:08 ` Frank Li
@ 2025-10-17 15:01 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:01 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 9:08 PM, Frank Li wrote:
Hello Frank,
>> +
>> +description: |
>
> use >
Why not drop the trailing | altogether ?
>> + The Freescale i.MX95 Display Pixel Link (DPL) forms a standard
>> + asynchronous linkage between pixel sources (display controller
>> + or camera module) and pixel consumers(imaging or displays).
>> + It consists of two distinct functions, a pixel transfer function
>> + and a control interface. Multiple pixel channels can exist per one
>> + control channel. This binding documentation is only for pixel links
>> + whose pixel sources are display controllers.
>> +
>> + The i.MX95 Display Pixel Link is accessed via syscon.
>> +
>> +properties:
>> + compatible:
>> + const: fsl,imx95-dc-pixel-link
>> +
>> + fsl,dc-stream-id:
>> + $ref: /schemas/types.yaml#/definitions/uint8
>> + description: |
>
> Needn't |
>
> why need this id
Because the IP is generic and can be attached to either output of the
DC. We need to figure which one this is attached to, to configure the
correct bitfields in syscon registers.
>> + u8 value representing the display controller stream index that the pixel
>> + link connects to.
>> + enum: [0, 1]
>> +
>> + fsl,syscon:
>> + $ref: /schemas/types.yaml#/definitions/phandle
>> + description: |
>> + A phandle which points to Control and Status Registers (CSR) module.
>
> Why not use stardard interface, like reset, clock, phy ...
No standard interface fits, this is really a special remote register.
>> + ports:
>> + $ref: /schemas/graph.yaml#/properties/ports
>> +
>> + properties:
>> + port@0:
>> + $ref: /schemas/graph.yaml#/properties/port
>
> video-interfaces.yaml?
None of the properties in video-interfaces.yaml fit , so it makes no
sense to pull it in here.
The other issues are fixed, thanks !
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 28/39] drm/bridge: imx: Add NXP i.MX95 pixel link support
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (26 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 27/39] dt-bindings: display: bridge: Document NXP i.MX95 pixel link support Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:10 ` Frank Li
2025-10-11 16:51 ` [PATCH 29/39] dt-bindings: display: bridge: Document Freescale i.MX95 MIPI DSI Marek Vasut
` (12 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Liu Ying, Marek Vasut, Sandor Yu, Abel Vesa, Conor Dooley,
Fabio Estevam, Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
From: Liu Ying <victor.liu@nxp.com>
Add NXP i.MX95 pixel link bridge support.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
Signed-off-by: Liu Ying <victor.liu@nxp.com>
Reviewed-by: Sandor Yu <Sandor.yu@nxp.com>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/bridge/imx/Kconfig | 9 +
drivers/gpu/drm/bridge/imx/Makefile | 1 +
drivers/gpu/drm/bridge/imx/imx95-pixel-link.c | 184 ++++++++++++++++++
3 files changed, 194 insertions(+)
create mode 100644 drivers/gpu/drm/bridge/imx/imx95-pixel-link.c
diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig
index 3e1b1d825d7bf..8baa335deac49 100644
--- a/drivers/gpu/drm/bridge/imx/Kconfig
+++ b/drivers/gpu/drm/bridge/imx/Kconfig
@@ -97,4 +97,13 @@ config DRM_IMX95_PIXEL_INTERLEAVER
Choose this to enable pixel interleaver found in NXP i.MX95
processors.
+config DRM_IMX95_PIXEL_LINK
+ tristate "NXP i.MX95 display pixel link"
+ depends on OF && MFD_SYSCON
+ select DRM_KMS_HELPER
+ select REGMAP_MMIO
+ help
+ Choose this to enable display pixel link found in NXP i.MX95
+ processors.
+
endif # ARCH_MXC || COMPILE_TEST
diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile
index 583054c70f002..b6b2e1bc8d4bd 100644
--- a/drivers/gpu/drm/bridge/imx/Makefile
+++ b/drivers/gpu/drm/bridge/imx/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o
obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o
obj-$(CONFIG_DRM_IMX93_MIPI_DSI) += imx93-mipi-dsi.o
obj-$(CONFIG_DRM_IMX95_PIXEL_INTERLEAVER) += imx95-pixel-interleaver.o
+obj-$(CONFIG_DRM_IMX95_PIXEL_LINK) += imx95-pixel-link.o
diff --git a/drivers/gpu/drm/bridge/imx/imx95-pixel-link.c b/drivers/gpu/drm/bridge/imx/imx95-pixel-link.c
new file mode 100644
index 0000000000000..747d2d77b59ef
--- /dev/null
+++ b/drivers/gpu/drm/bridge/imx/imx95-pixel-link.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright 2023 NXP
+ */
+
+#include <linux/bits.h>
+#include <linux/media-bus-format.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_bridge.h>
+
+#define CTRL 0x8
+#define PL_VALID(n) BIT(1 + 4 * (n))
+#define PL_ENABLE(n) BIT(4 * (n))
+
+#define OUT_ENDPOINTS 2
+
+#define DRIVER_NAME "imx95-pixel-link"
+
+struct imx95_pixel_link_bridge {
+ struct drm_bridge bridge;
+ struct drm_bridge *next_bridge;
+ struct device *dev;
+ struct regmap *regmap;
+ u8 stream_id;
+};
+
+static int imx95_pixel_link_bridge_attach(struct drm_bridge *bridge,
+ struct drm_encoder *encoder,
+ enum drm_bridge_attach_flags flags)
+{
+ struct imx95_pixel_link_bridge *pl = bridge->driver_private;
+
+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+ dev_err(pl->dev, "do not support creating a drm_connector\n");
+ return -EINVAL;
+ }
+
+ return drm_bridge_attach(encoder, pl->next_bridge, bridge,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+}
+
+static void imx95_pixel_link_bridge_disable(struct drm_bridge *bridge)
+{
+ struct imx95_pixel_link_bridge *pl = bridge->driver_private;
+ unsigned int id = pl->stream_id;
+
+ regmap_update_bits(pl->regmap, CTRL, PL_ENABLE(id), 0);
+ regmap_update_bits(pl->regmap, CTRL, PL_VALID(id), 0);
+}
+
+static void imx95_pixel_link_bridge_enable(struct drm_bridge *bridge)
+{
+ struct imx95_pixel_link_bridge *pl = bridge->driver_private;
+ unsigned int id = pl->stream_id;
+
+ regmap_update_bits(pl->regmap, CTRL, PL_VALID(id), PL_VALID(id));
+ regmap_update_bits(pl->regmap, CTRL, PL_ENABLE(id), PL_ENABLE(id));
+}
+
+static u32 *
+imx95_pixel_link_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state,
+ u32 output_fmt,
+ unsigned int *num_input_fmts)
+{
+ u32 *input_fmts;
+
+ if (output_fmt != MEDIA_BUS_FMT_RGB888_1X36_CPADLO &&
+ output_fmt != MEDIA_BUS_FMT_FIXED)
+ return NULL;
+
+ *num_input_fmts = 1;
+
+ input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
+ if (!input_fmts)
+ return NULL;
+
+ input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
+
+ return input_fmts;
+}
+
+static const struct drm_bridge_funcs imx95_pixel_link_bridge_funcs = {
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .atomic_reset = drm_atomic_helper_bridge_reset,
+ .attach = imx95_pixel_link_bridge_attach,
+ .disable = imx95_pixel_link_bridge_disable,
+ .enable = imx95_pixel_link_bridge_enable,
+ .atomic_get_input_bus_fmts =
+ imx95_pixel_link_bridge_atomic_get_input_bus_fmts,
+};
+
+static int imx95_pixel_link_bridge_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *remote, *np = dev->of_node;
+ struct imx95_pixel_link_bridge *pl;
+ int i, ret;
+
+ pl = devm_drm_bridge_alloc(dev, struct imx95_pixel_link_bridge, bridge,
+ &imx95_pixel_link_bridge_funcs);
+ if (IS_ERR(pl))
+ return PTR_ERR(pl);
+
+ pl->dev = dev;
+ platform_set_drvdata(pdev, pl);
+
+ pl->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,syscon");
+ if (IS_ERR(pl->regmap))
+ return dev_err_probe(dev, PTR_ERR(pl->regmap), "failed to get regmap\n");
+
+ ret = of_property_read_u8(np, "fsl,dc-stream-id", &pl->stream_id);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get stream index\n");
+
+ pl->bridge.driver_private = pl;
+ pl->bridge.of_node = of_graph_get_port_by_id(np, 0);
+ if (!pl->bridge.of_node)
+ return dev_err_probe(dev, -ENODEV, "failed to get port@0\n");
+ of_node_put(pl->bridge.of_node);
+
+ for (i = 0; i < OUT_ENDPOINTS; i++) {
+ remote = of_graph_get_remote_node(np, 1, i);
+ if (!remote) {
+ dev_dbg(dev, "no remote node for port@1 ep%u\n", i);
+ continue;
+ }
+
+ pl->next_bridge = of_drm_find_bridge(remote);
+ if (!pl->next_bridge) {
+ dev_dbg(dev, "failed to find next bridge for port@1 ep%u\n", i);
+ of_node_put(remote);
+ return -EPROBE_DEFER;
+ }
+
+ of_node_put(remote);
+
+ drm_bridge_add(&pl->bridge);
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static void imx95_pixel_link_bridge_remove(struct platform_device *pdev)
+{
+ struct imx95_pixel_link_bridge *pl = platform_get_drvdata(pdev);
+
+ drm_bridge_remove(&pl->bridge);
+}
+
+static const struct of_device_id imx95_pixel_link_bridge_dt_ids[] = {
+ { .compatible = "fsl,imx95-dc-pixel-link", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx95_pixel_link_bridge_dt_ids);
+
+static struct platform_driver imx95_pixel_link_bridge_driver = {
+ .probe = imx95_pixel_link_bridge_probe,
+ .remove = imx95_pixel_link_bridge_remove,
+ .driver = {
+ .of_match_table = imx95_pixel_link_bridge_dt_ids,
+ .name = DRIVER_NAME,
+ },
+};
+
+module_platform_driver(imx95_pixel_link_bridge_driver);
+
+MODULE_DESCRIPTION("i.MX95 display pixel link bridge driver");
+MODULE_AUTHOR("NXP Semiconductor");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 28/39] drm/bridge: imx: Add NXP i.MX95 pixel link support
2025-10-11 16:51 ` [PATCH 28/39] drm/bridge: imx: Add " Marek Vasut
@ 2025-10-13 19:10 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:10 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Liu Ying, Sandor Yu, Abel Vesa, Conor Dooley,
Fabio Estevam, Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:43PM +0200, Marek Vasut wrote:
> From: Liu Ying <victor.liu@nxp.com>
>
> Add NXP i.MX95 pixel link bridge support.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> Signed-off-by: Liu Ying <victor.liu@nxp.com>
> Reviewed-by: Sandor Yu <Sandor.yu@nxp.com>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/bridge/imx/Kconfig | 9 +
> drivers/gpu/drm/bridge/imx/Makefile | 1 +
> drivers/gpu/drm/bridge/imx/imx95-pixel-link.c | 184 ++++++++++++++++++
> 3 files changed, 194 insertions(+)
> create mode 100644 drivers/gpu/drm/bridge/imx/imx95-pixel-link.c
>
> diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig
> index 3e1b1d825d7bf..8baa335deac49 100644
> --- a/drivers/gpu/drm/bridge/imx/Kconfig
> +++ b/drivers/gpu/drm/bridge/imx/Kconfig
> @@ -97,4 +97,13 @@ config DRM_IMX95_PIXEL_INTERLEAVER
> Choose this to enable pixel interleaver found in NXP i.MX95
> processors.
>
> +config DRM_IMX95_PIXEL_LINK
> + tristate "NXP i.MX95 display pixel link"
> + depends on OF && MFD_SYSCON
> + select DRM_KMS_HELPER
> + select REGMAP_MMIO
> + help
> + Choose this to enable display pixel link found in NXP i.MX95
> + processors.
> +
> endif # ARCH_MXC || COMPILE_TEST
> diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile
> index 583054c70f002..b6b2e1bc8d4bd 100644
> --- a/drivers/gpu/drm/bridge/imx/Makefile
> +++ b/drivers/gpu/drm/bridge/imx/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o
> obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o
> obj-$(CONFIG_DRM_IMX93_MIPI_DSI) += imx93-mipi-dsi.o
> obj-$(CONFIG_DRM_IMX95_PIXEL_INTERLEAVER) += imx95-pixel-interleaver.o
> +obj-$(CONFIG_DRM_IMX95_PIXEL_LINK) += imx95-pixel-link.o
> diff --git a/drivers/gpu/drm/bridge/imx/imx95-pixel-link.c b/drivers/gpu/drm/bridge/imx/imx95-pixel-link.c
> new file mode 100644
> index 0000000000000..747d2d77b59ef
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/imx/imx95-pixel-link.c
> @@ -0,0 +1,184 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * Copyright 2023 NXP
> + */
> +
> +#include <linux/bits.h>
> +#include <linux/media-bus-format.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <drm/drm_atomic_state_helper.h>
> +#include <drm/drm_bridge.h>
> +
> +#define CTRL 0x8
register name too short
> +#define PL_VALID(n) BIT(1 + 4 * (n))
> +#define PL_ENABLE(n) BIT(4 * (n))
> +
> +#define OUT_ENDPOINTS 2
> +
> +#define DRIVER_NAME "imx95-pixel-link"
> +
> +struct imx95_pixel_link_bridge {
> + struct drm_bridge bridge;
> + struct drm_bridge *next_bridge;
> + struct device *dev;
> + struct regmap *regmap;
> + u8 stream_id;
> +};
> +
> +static int imx95_pixel_link_bridge_attach(struct drm_bridge *bridge,
> + struct drm_encoder *encoder,
> + enum drm_bridge_attach_flags flags)
> +{
> + struct imx95_pixel_link_bridge *pl = bridge->driver_private;
> +
> + if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
> + dev_err(pl->dev, "do not support creating a drm_connector\n");
> + return -EINVAL;
> + }
> +
> + return drm_bridge_attach(encoder, pl->next_bridge, bridge,
> + DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +}
> +
> +static void imx95_pixel_link_bridge_disable(struct drm_bridge *bridge)
> +{
> + struct imx95_pixel_link_bridge *pl = bridge->driver_private;
> + unsigned int id = pl->stream_id;
> +
> + regmap_update_bits(pl->regmap, CTRL, PL_ENABLE(id), 0);
> + regmap_update_bits(pl->regmap, CTRL, PL_VALID(id), 0);
> +}
> +
> +static void imx95_pixel_link_bridge_enable(struct drm_bridge *bridge)
> +{
> + struct imx95_pixel_link_bridge *pl = bridge->driver_private;
> + unsigned int id = pl->stream_id;
> +
> + regmap_update_bits(pl->regmap, CTRL, PL_VALID(id), PL_VALID(id));
> + regmap_update_bits(pl->regmap, CTRL, PL_ENABLE(id), PL_ENABLE(id));
> +}
> +
> +static u32 *
> +imx95_pixel_link_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
> + struct drm_bridge_state *bridge_state,
> + struct drm_crtc_state *crtc_state,
> + struct drm_connector_state *conn_state,
> + u32 output_fmt,
> + unsigned int *num_input_fmts)
> +{
> + u32 *input_fmts;
> +
> + if (output_fmt != MEDIA_BUS_FMT_RGB888_1X36_CPADLO &&
> + output_fmt != MEDIA_BUS_FMT_FIXED)
> + return NULL;
> +
> + *num_input_fmts = 1;
> +
> + input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
> + if (!input_fmts)
> + return NULL;
> +
> + input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
> +
> + return input_fmts;
> +}
> +
> +static const struct drm_bridge_funcs imx95_pixel_link_bridge_funcs = {
> + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> + .atomic_reset = drm_atomic_helper_bridge_reset,
> + .attach = imx95_pixel_link_bridge_attach,
> + .disable = imx95_pixel_link_bridge_disable,
> + .enable = imx95_pixel_link_bridge_enable,
> + .atomic_get_input_bus_fmts =
> + imx95_pixel_link_bridge_atomic_get_input_bus_fmts,
> +};
> +
> +static int imx95_pixel_link_bridge_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *remote, *np = dev->of_node;
> + struct imx95_pixel_link_bridge *pl;
> + int i, ret;
> +
> + pl = devm_drm_bridge_alloc(dev, struct imx95_pixel_link_bridge, bridge,
> + &imx95_pixel_link_bridge_funcs);
> + if (IS_ERR(pl))
> + return PTR_ERR(pl);
> +
> + pl->dev = dev;
> + platform_set_drvdata(pdev, pl);
> +
> + pl->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,syscon");
> + if (IS_ERR(pl->regmap))
> + return dev_err_probe(dev, PTR_ERR(pl->regmap), "failed to get regmap\n");
> +
> + ret = of_property_read_u8(np, "fsl,dc-stream-id", &pl->stream_id);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to get stream index\n");
> +
> + pl->bridge.driver_private = pl;
> + pl->bridge.of_node = of_graph_get_port_by_id(np, 0);
> + if (!pl->bridge.of_node)
> + return dev_err_probe(dev, -ENODEV, "failed to get port@0\n");
> + of_node_put(pl->bridge.of_node);
this put should be in driver remove function.
> +
> + for (i = 0; i < OUT_ENDPOINTS; i++) {
> + remote = of_graph_get_remote_node(np, 1, i);
> + if (!remote) {
> + dev_dbg(dev, "no remote node for port@1 ep%u\n", i);
> + continue;
> + }
> +
> + pl->next_bridge = of_drm_find_bridge(remote);
> + if (!pl->next_bridge) {
> + dev_dbg(dev, "failed to find next bridge for port@1 ep%u\n", i);
> + of_node_put(remote);
> + return -EPROBE_DEFER;
> + }
> +
> + of_node_put(remote);
> +
> + drm_bridge_add(&pl->bridge);
> +
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static void imx95_pixel_link_bridge_remove(struct platform_device *pdev)
> +{
> + struct imx95_pixel_link_bridge *pl = platform_get_drvdata(pdev);
> +
> + drm_bridge_remove(&pl->bridge);
> +}
> +
> +static const struct of_device_id imx95_pixel_link_bridge_dt_ids[] = {
> + { .compatible = "fsl,imx95-dc-pixel-link", },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, imx95_pixel_link_bridge_dt_ids);
> +
> +static struct platform_driver imx95_pixel_link_bridge_driver = {
> + .probe = imx95_pixel_link_bridge_probe,
> + .remove = imx95_pixel_link_bridge_remove,
> + .driver = {
> + .of_match_table = imx95_pixel_link_bridge_dt_ids,
> + .name = DRIVER_NAME,
> + },
> +};
> +
> +module_platform_driver(imx95_pixel_link_bridge_driver);
> +
> +MODULE_DESCRIPTION("i.MX95 display pixel link bridge driver");
> +MODULE_AUTHOR("NXP Semiconductor");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:" DRIVER_NAME);
Drop
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 29/39] dt-bindings: display: bridge: Document Freescale i.MX95 MIPI DSI
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (27 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 28/39] drm/bridge: imx: Add " Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:13 ` Frank Li
2025-10-11 16:51 ` [PATCH 30/39] drm/bridge: imx93-mipi-dsi: Add i.MX95 PLL initialization Marek Vasut
` (11 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Freescale i.MX95 SoC embeds a Synopsys Designware MIPI DSI host
controller and a Synopsys Designware MIPI DPHY. Unlike the i.MX93
PHY, the i.MX95 PHY uses more syscon interfaces to configure the
PHY.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
.../display/bridge/fsl,imx93-mipi-dsi.yaml | 48 +++++++++++++++++--
1 file changed, 43 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml
index d6e51d0cf5464..388301c4f95c1 100644
--- a/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml
@@ -14,12 +14,11 @@ description: |
Designware MIPI DPHY embedded in Freescale i.MX93 SoC. Some configurations
and extensions to them are controlled by i.MX93 media blk-ctrl.
-allOf:
- - $ref: snps,dw-mipi-dsi.yaml#
-
properties:
compatible:
- const: fsl,imx93-mipi-dsi
+ enum:
+ - fsl,imx93-mipi-dsi
+ - fsl,imx95-mipi-dsi
clocks:
items:
@@ -46,13 +45,52 @@ properties:
controller and MIPI DPHY PLL related configurations through PLL SoC
interface.
+ fsl,disp-master-csr:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ i.MX95 Display Master CSR is a syscon which includes registers to
+ control DSI clock settings, clock gating, and pixel link select.
+
+ fsl,disp-stream-csr:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ i.MX95 Display Stream CSR is a syscon which includes configuration
+ and status registers for the DSI host.
+
+ fsl,mipi-combo-phy-csr:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ i.MX95 Display Stream CSR is a syscon which configuration and status
+ registers for the MIPI Tx DPHY module in the Camera domain.
+
power-domains:
maxItems: 1
+allOf:
+ - $ref: snps,dw-mipi-dsi.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,imx93-mipi-dsi
+ then:
+ required:
+ - fsl,media-blk-ctrl
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,imx95-mipi-dsi
+ then:
+ required:
+ - fsl,disp-master-csr
+ - fsl,disp-stream-csr
+ - fsl,mipi-combo-phy-csr
+
required:
- compatible
- interrupts
- - fsl,media-blk-ctrl
- power-domains
unevaluatedProperties: false
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 29/39] dt-bindings: display: bridge: Document Freescale i.MX95 MIPI DSI
2025-10-11 16:51 ` [PATCH 29/39] dt-bindings: display: bridge: Document Freescale i.MX95 MIPI DSI Marek Vasut
@ 2025-10-13 19:13 ` Frank Li
2025-10-17 15:37 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:13 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:44PM +0200, Marek Vasut wrote:
> Freescale i.MX95 SoC embeds a Synopsys Designware MIPI DSI host
> controller and a Synopsys Designware MIPI DPHY. Unlike the i.MX93
> PHY, the i.MX95 PHY uses more syscon interfaces to configure the
> PHY.
Any common driver for Synopsys Designware MIPI DSI, suppose many vendor
use this IP?
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../display/bridge/fsl,imx93-mipi-dsi.yaml | 48 +++++++++++++++++--
> 1 file changed, 43 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml
> index d6e51d0cf5464..388301c4f95c1 100644
> --- a/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml
> @@ -14,12 +14,11 @@ description: |
> Designware MIPI DPHY embedded in Freescale i.MX93 SoC. Some configurations
> and extensions to them are controlled by i.MX93 media blk-ctrl.
>
> -allOf:
> - - $ref: snps,dw-mipi-dsi.yaml#
> -
> properties:
> compatible:
> - const: fsl,imx93-mipi-dsi
> + enum:
> + - fsl,imx93-mipi-dsi
> + - fsl,imx95-mipi-dsi
>
> clocks:
> items:
> @@ -46,13 +45,52 @@ properties:
> controller and MIPI DPHY PLL related configurations through PLL SoC
> interface.
>
> + fsl,disp-master-csr:
> + $ref: /schemas/types.yaml#/definitions/phandle
> + description:
> + i.MX95 Display Master CSR is a syscon which includes registers to
> + control DSI clock settings, clock gating, and pixel link select.
why not go through standard phy interface?
> +
> + fsl,disp-stream-csr:
> + $ref: /schemas/types.yaml#/definitions/phandle
> + description:
> + i.MX95 Display Stream CSR is a syscon which includes configuration
> + and status registers for the DSI host.
why not go through standard phy interface?
Frank
> +
> + fsl,mipi-combo-phy-csr:
> + $ref: /schemas/types.yaml#/definitions/phandle
> + description:
> + i.MX95 Display Stream CSR is a syscon which configuration and status
> + registers for the MIPI Tx DPHY module in the Camera domain.
> +
> power-domains:
> maxItems: 1
>
> +allOf:
> + - $ref: snps,dw-mipi-dsi.yaml#
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: fsl,imx93-mipi-dsi
> + then:
> + required:
> + - fsl,media-blk-ctrl
> +
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: fsl,imx95-mipi-dsi
> + then:
> + required:
> + - fsl,disp-master-csr
> + - fsl,disp-stream-csr
> + - fsl,mipi-combo-phy-csr
> +
> required:
> - compatible
> - interrupts
> - - fsl,media-blk-ctrl
> - power-domains
>
> unevaluatedProperties: false
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 29/39] dt-bindings: display: bridge: Document Freescale i.MX95 MIPI DSI
2025-10-13 19:13 ` Frank Li
@ 2025-10-17 15:37 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:37 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 9:13 PM, Frank Li wrote:
> On Sat, Oct 11, 2025 at 06:51:44PM +0200, Marek Vasut wrote:
>> Freescale i.MX95 SoC embeds a Synopsys Designware MIPI DSI host
>> controller and a Synopsys Designware MIPI DPHY. Unlike the i.MX93
>> PHY, the i.MX95 PHY uses more syscon interfaces to configure the
>> PHY.
>
> Any common driver for Synopsys Designware MIPI DSI, suppose many vendor
> use this IP?
Sure, the IP is common, the "glue logic" is SoC-specific.
>> properties:
>> compatible:
>> - const: fsl,imx93-mipi-dsi
>> + enum:
>> + - fsl,imx93-mipi-dsi
>> + - fsl,imx95-mipi-dsi
>>
>> clocks:
>> items:
>> @@ -46,13 +45,52 @@ properties:
>> controller and MIPI DPHY PLL related configurations through PLL SoC
>> interface.
>>
>> + fsl,disp-master-csr:
>> + $ref: /schemas/types.yaml#/definitions/phandle
>> + description:
>> + i.MX95 Display Master CSR is a syscon which includes registers to
>> + control DSI clock settings, clock gating, and pixel link select.
>
> why not go through standard phy interface?
>
>> +
>> + fsl,disp-stream-csr:
>> + $ref: /schemas/types.yaml#/definitions/phandle
>> + description:
>> + i.MX95 Display Stream CSR is a syscon which includes configuration
>> + and status registers for the DSI host.
>
> why not go through standard phy interface?
These are aux control signals , these registers are not PHY .
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 30/39] drm/bridge: imx93-mipi-dsi: Add i.MX95 PLL initialization
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (28 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 29/39] dt-bindings: display: bridge: Document Freescale i.MX95 MIPI DSI Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-11 16:51 ` [PATCH 31/39] dt-bindings: clock: Split support for i.MX95 LVDS CSR Marek Vasut
` (10 subsequent siblings)
40 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Add PLL initialization for the i.MX95 SoC, which differs from the i.MX93.
Unlike the i.MX93 PHY, the i.MX95 PHY uses more syscon interfaces to configure
the PHY. Retain common code where possible, which are frequency table look ups
and matching tables.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 612 ++++++++++++++++++--
1 file changed, 575 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
index 8f7a0d46601a4..d0fda2fca2b43 100644
--- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
@@ -13,6 +13,7 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/phy/phy.h>
#include <linux/phy/phy-mipi-dphy.h>
#include <linux/platform_device.h>
@@ -23,7 +24,7 @@
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_modes.h>
-/* DPHY PLL configuration registers */
+/* i.MX93 DPHY PLL configuration registers */
#define DSI_REG 0x4c
#define CFGCLKFREQRANGE_MASK GENMASK(5, 0)
#define CFGCLKFREQRANGE(x) FIELD_PREP(CFGCLKFREQRANGE_MASK, (x))
@@ -70,6 +71,123 @@
#define RGB888_TO_RGB666 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 6)
#define RGB565_TO_RGB565 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 7)
+/* i.MX95 DPHY PLL configuration registers */
+#define DSI_DPI_CFG_POL 0x14
+#define COLORM_ACTIVE_LOW BIT(4)
+#define SHUTD_ACTIVE_LOW BIT(3)
+#define HSYNC_ACTIVE_LOW BIT(2)
+#define VSYNC_ACTIVE_LOW BIT(1)
+#define DATAEN_ACTIVE_LOW BIT(0)
+
+#define DSI_PHY_TST_CTRL0 0xb4
+#define PHY_TESTCLK BIT(1)
+#define PHY_UNTESTCLK 0
+#define PHY_TESTCLR BIT(0)
+#define PHY_UNTESTCLR 0
+
+#define DSI_PHY_TST_CTRL1 0xb8
+#define PHY_TESTEN BIT(16)
+#define PHY_UNTESTEN 0
+#define PHY_TESTDOUT_MASK GENMASK(15, 8)
+#define PHY_TESTDOUT(n) FIELD_PREP(PHY_TESTDOUT_MASK, (n))
+#define PHY_TESTDIN(n) FIELD_PREP(GENMASK(7, 0), (n))
+
+/* master CSR */
+#define DSI_CLOCK_GATING_CONTROL 0x0
+#define DISPLAY_ASYNC_FIFO(n) BIT(0 + (n))
+#define DPHY_PLL_CLKIN BIT(2)
+#define DPHY_PLL_CLKOUT BIT(3)
+#define DPHY_PLL_CLKEXT BIT(4)
+
+#define DSI_PIXEL_LINK_CONTROL 0x4
+#define PIXEL_LINK_SEL BIT(0)
+
+#define DSI_CLOCK_SETTING 0x8
+#define DPHY_REF_CLOCK_DIV(n) FIELD_PREP(GENMASK(3, 0), (n))
+#define DPHY_BYPASS_CLOCK BIT(6)
+#define DPHY_REF_CLOCK_SOURCE BIT(7)
+#define DPHY_PLL_DIV(n) FIELD_PREP(GENMASK(11, 8), (n))
+#define PL_SLV_DSI_INGRESS_CLK_SEL(n) BIT(16 + (n))
+
+/* stream CSR */
+#define DSI_HOST_CONFIGURATION 0x0
+#define PIXEL_LINK_FORMAT_MASK GENMASK(2, 0)
+#define SHUTDOWN BIT(4)
+#define COLORMODE BIT(5)
+
+#define DSI_PARITY_ERROR_STATUS 0x4
+#define DSI_PARITY_ERROR_THRESHOLD 0x8
+
+/* DPHY CSR */
+#define PHY_MODE_CONTROL 0x0
+#define PHY_ENABLE_EXT(n) FIELD_PREP(GENMASK(7, 4), (n))
+#define PLL_GP_CLK_EN BIT(3)
+#define PLL_CLKSEL_MASK GENMASK(2, 1)
+#define PLL_CLKSEL_STOP FIELD_PREP(PLL_CLKSEL_MASK, 0)
+#define PLL_CLKSEL_GEN FIELD_PREP(PLL_CLKSEL_MASK, 1)
+#define PLL_CLKSEL_EXT FIELD_PREP(PLL_CLKSEL_MASK, 2)
+#define TX_RXZ_DSI_MODE BIT(0)
+
+#define PHY_FREQ_CONTROL 0x4
+#define PHY_HSFREQRANGE(n) FIELD_PREP(GENMASK(22, 16), (n))
+#define PHY_CFGCLKFREQRANGE(n) FIELD_PREP(GENMASK(7, 0), (n))
+
+#define PHY_TEST_MODE_CONTROL 0x8
+#define EXT_SIGNAL_ALL GENMASK(19, 14)
+#define TURNDISABLE_0 BIT(13)
+#define ENABLECLK_EXT BIT(12)
+
+#define PHY_TEST_MODE_STATUS 0xc
+#define PHY_LOCK BIT(11)
+
+/* DPHY test control register */
+#define DIG_RDWR_TX_PLL_1 0x15e
+#define PLL_CPBIAS_CNTRL_RW_MASK GENMASK(6, 0)
+#define PLL_CPBIAS_CNTRL_RW(n) FIELD_PREP(PLL_CPBIAS_CNTRL_RW_MASK, (n))
+#define DIG_RDWR_TX_PLL_5 0x162
+#define PLL_INT_CNTRL_RW(n) FIELD_PREP(GENMASK(7, 2), (n))
+#define PLL_GMP_CNTRL_RW(n) FIELD_PREP(GENMASK(1, 0), (n))
+#define DIG_RDWR_TX_PLL_9 0x166
+#define PLL_LOCK_SEL_RW BIT(2)
+#define DIG_RDWR_TX_PLL_13 0x16a
+#define DIG_RDWR_TX_PLL_17 0x16e
+#define PLL_PWRON_OVR_RW BIT(7)
+#define PLL_PWRON_OVR_EN_RW BIT(6)
+#define PLL_PROP_CNTRL_RW_MASK GENMASK(5, 0)
+#define PLL_PROP_CNTRL_RW(n) FIELD_PREP(PLL_PROP_CNTRL_RW_MASK, (n))
+#define DIG_RDWR_TX_PLL_22 0x173
+#define DIG_RDWR_TX_PLL_23 0x174
+#define DIG_RDWR_TX_PLL_24 0x175
+#define PLL_TH2_RW(n) FIELD_PREP(GENMASK(7, 0), (n))
+#define DIG_RDWR_TX_PLL_25 0x176
+#define PLL_TH3_RW(n) FIELD_PREP(GENMASK(7, 0), (n))
+#define DIG_RDWR_TX_PLL_27 0x178
+#define PLL_N_OVR_EN_RW BIT(7)
+#define PLL_N_OVR_RW_MASK GENMASK(6, 3)
+#define PLL_N_OVR_RW(n) FIELD_PREP(PLL_N_OVR_RW_MASK, ((n) - 1))
+#define DIG_RDWR_TX_PLL_28 0x179
+#define PLL_M_LOW(n) (((n) - 2) & 0xff)
+#define DIG_RDWR_TX_PLL_29 0x17a
+#define PLL_M_HIGH(n) ((((n) - 2) >> 8) & 0xff)
+#define DIG_RDWR_TX_PLL_30 0x17b
+#define PLL_VCO_CNTRL_OVR_EN_RW BIT(7)
+#define PLL_VCO_CNTRL_OVR_RW_MASK GENMASK(6, 1)
+#define PLL_VCO_CNTRL_OVR_RW(n) FIELD_PREP(PLL_VCO_CNTRL_OVR_RW_MASK, (n))
+#define PLL_M_OVR_EN_RW BIT(0)
+#define DIG_RDWR_TX_PLL_31 0x17c
+#define PLL_CLKOUTEN_RIGHT_RW BIT(1)
+#define PLL_CLKOUTEN_LEFT_RW BIT(0)
+#define DIG_RDWR_TX_CB_0 0x1aa
+#define DIG_RDWR_TX_CB_1 0x1ab
+#define DIG_RDWR_TX_TX_SLEW_0 0x26b
+#define DIG_RDWR_TX_TX_SLEW_5 0x270
+#define DIG_RDWR_TX_TX_SLEW_6 0x271
+#define DIG_RDWR_TX_TX_SLEW_7 0x272
+#define DIG_RDWR_TX_CLK_TERMLOWCAP 0x402
+
+#define IMX95_DSI_ENDPOINT_PL0 0
+#define IMX95_DSI_ENDPOINT_PL1 1
+
#define MHZ(x) ((x) * 1000000UL)
#define REF_CLK_RATE_MAX MHZ(64)
@@ -89,9 +207,24 @@
#define N_MAX 16U
#define N_MIN 1U
+#define PIXEL_LINK_STREAMS 2
+
+enum dsi_pixel_link_format {
+ RGB_24BIT,
+ RGB_30BIT,
+ RGB_18BIT,
+ RGB_16BIT,
+ YCBCR_20BIT_422,
+ YCBCR_16BIT_422,
+};
+
struct imx93_dsi {
struct device *dev;
+ void __iomem *base;
struct regmap *regmap;
+ struct regmap *mst;
+ struct regmap *str;
+ struct regmap *phy;
struct clk *clk_pixel;
struct clk *clk_ref;
struct clk *clk_cfg;
@@ -99,6 +232,10 @@ struct imx93_dsi {
struct dw_mipi_dsi_plat_data pdata;
union phy_configure_opts phy_cfg;
unsigned long ref_clk_rate;
+ unsigned int lanes;
+ unsigned int lane_mbps;
+ bool use_pl0;
+ u32 fixed_format;
u32 format;
};
@@ -200,7 +337,7 @@ static const struct dphy_pll_hsfreqrange hsfreqrange_map[] = {
{ 2500, 0x49 },
};
-static void dphy_pll_write(struct imx93_dsi *dsi, unsigned int reg, u32 value)
+static void imx93_dsi_pll_write(struct imx93_dsi *dsi, unsigned int reg, u32 value)
{
int ret;
@@ -293,19 +430,19 @@ dphy_pll_get_configure_from_opts(struct imx93_dsi *dsi,
return 0;
}
-static void dphy_pll_clear_shadow(struct imx93_dsi *dsi)
+static void imx93_dsi_pll_clear_shadow(struct imx93_dsi *dsi)
{
/* Reference DPHY Databook Figure 3-3 Initialization Timing Diagram. */
/* Select clock generation first. */
- dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN);
+ imx93_dsi_pll_write(dsi, DSI_REG, CLKSEL_GEN);
/* Clear shadow after clock selection is done a while. */
fsleep(1);
- dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN | SHADOW_CLR);
+ imx93_dsi_pll_write(dsi, DSI_REG, CLKSEL_GEN | SHADOW_CLR);
/* A minimum pulse of 5ns on shadow_clear signal. */
fsleep(1);
- dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN);
+ imx93_dsi_pll_write(dsi, DSI_REG, CLKSEL_GEN);
}
static unsigned long dphy_pll_get_cfgclkrange(struct imx93_dsi *dsi)
@@ -354,7 +491,7 @@ static u8 dphy_pll_get_prop(struct phy_configure_opts_mipi_dphy *dphy_opts)
return 0;
}
-static int dphy_pll_update(struct imx93_dsi *dsi)
+static int imx93_dsi_pll_update(struct imx93_dsi *dsi)
{
int ret;
@@ -380,7 +517,7 @@ static int dphy_pll_update(struct imx93_dsi *dsi)
return 0;
}
-static int dphy_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *opts)
+static int imx93_dsi_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *opts)
{
struct dphy_pll_cfg cfg = { 0 };
u32 val;
@@ -392,22 +529,22 @@ static int dphy_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *o
return ret;
}
- dphy_pll_clear_shadow(dsi);
+ imx93_dsi_pll_clear_shadow(dsi);
/* DSI_REG */
val = CLKSEL_GEN |
CFGCLKFREQRANGE(dphy_pll_get_cfgclkrange(dsi)) |
HSFREQRANGE(dphy_pll_get_hsfreqrange(&opts->mipi_dphy));
- dphy_pll_write(dsi, DSI_REG, val);
+ imx93_dsi_pll_write(dsi, DSI_REG, val);
/* DSI_WRITE_REG0 */
val = M(cfg.m) | N(cfg.n) | INT_CTRL(0) |
VCO_CTRL(dphy_pll_get_vco(&opts->mipi_dphy)) |
PROP_CTRL(dphy_pll_get_prop(&opts->mipi_dphy));
- dphy_pll_write(dsi, DSI_WRITE_REG0, val);
+ imx93_dsi_pll_write(dsi, DSI_WRITE_REG0, val);
/* DSI_WRITE_REG1 */
- dphy_pll_write(dsi, DSI_WRITE_REG1, GMP_CTRL(1) | CPBIAS_CTRL(0x10));
+ imx93_dsi_pll_write(dsi, DSI_WRITE_REG1, GMP_CTRL(1) | CPBIAS_CTRL(0x10));
ret = clk_prepare_enable(dsi->clk_ref);
if (ret < 0) {
@@ -421,7 +558,7 @@ static int dphy_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *o
*/
fsleep(10);
- ret = dphy_pll_update(dsi);
+ ret = imx93_dsi_pll_update(dsi);
if (ret < 0) {
clk_disable_unprepare(dsi->clk_ref);
return ret;
@@ -430,14 +567,14 @@ static int dphy_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *o
return 0;
}
-static void dphy_pll_clear_reg(struct imx93_dsi *dsi)
+static void imx93_dsi_pll_clear_reg(struct imx93_dsi *dsi)
{
- dphy_pll_write(dsi, DSI_REG, 0);
- dphy_pll_write(dsi, DSI_WRITE_REG0, 0);
- dphy_pll_write(dsi, DSI_WRITE_REG1, 0);
+ imx93_dsi_pll_write(dsi, DSI_REG, 0);
+ imx93_dsi_pll_write(dsi, DSI_WRITE_REG0, 0);
+ imx93_dsi_pll_write(dsi, DSI_WRITE_REG1, 0);
}
-static int dphy_pll_init(struct imx93_dsi *dsi)
+static int imx93_dsi_pll_init(struct imx93_dsi *dsi)
{
int ret;
@@ -447,20 +584,20 @@ static int dphy_pll_init(struct imx93_dsi *dsi)
return ret;
}
- dphy_pll_clear_reg(dsi);
+ imx93_dsi_pll_clear_reg(dsi);
return 0;
}
-static void dphy_pll_uninit(struct imx93_dsi *dsi)
+static void imx93_dsi_pll_uninit(struct imx93_dsi *dsi)
{
- dphy_pll_clear_reg(dsi);
+ imx93_dsi_pll_clear_reg(dsi);
clk_disable_unprepare(dsi->clk_cfg);
}
-static void dphy_pll_power_off(struct imx93_dsi *dsi)
+static void imx93_pll_power_off(struct imx93_dsi *dsi)
{
- dphy_pll_clear_reg(dsi);
+ imx93_dsi_pll_clear_reg(dsi);
clk_disable_unprepare(dsi->clk_ref);
}
@@ -581,6 +718,10 @@ static bool imx93_dsi_mode_fixup(void *priv_data,
dev_dbg(dsi->dev, "adj clock %d for mode " DRM_MODE_FMT "\n",
adjusted_mode->clock, DRM_MODE_ARG(mode));
+ /* pixel link always generates active low HSYNC and VSYNC */
+ adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+ adjusted_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC;
+
return true;
}
@@ -592,6 +733,7 @@ static u32 *imx93_dsi_get_input_bus_fmts(void *priv_data,
u32 output_fmt,
unsigned int *num_input_fmts)
{
+ struct imx93_dsi *dsi = priv_data;
u32 *input_fmts, input_fmt;
*num_input_fmts = 0;
@@ -599,12 +741,15 @@ static u32 *imx93_dsi_get_input_bus_fmts(void *priv_data,
switch (output_fmt) {
case MEDIA_BUS_FMT_RGB888_1X24:
case MEDIA_BUS_FMT_RGB666_1X18:
- case MEDIA_BUS_FMT_FIXED:
input_fmt = MEDIA_BUS_FMT_RGB888_1X24;
break;
case MEDIA_BUS_FMT_RGB565_1X16:
input_fmt = output_fmt;
break;
+ case MEDIA_BUS_FMT_FIXED:
+ input_fmt = dsi->fixed_format;
+ break;
+
default:
return NULL;
}
@@ -647,16 +792,16 @@ static int imx93_dsi_phy_init(void *priv_data)
regmap_update_bits(dsi->regmap, DISPLAY_MUX, LCDIF_CROSS_LINE_PATTERN, fmt);
- ret = dphy_pll_init(dsi);
+ ret = imx93_dsi_pll_init(dsi);
if (ret < 0) {
dev_err(dsi->dev, "failed to init phy pll: %d\n", ret);
return ret;
}
- ret = dphy_pll_configure(dsi, &dsi->phy_cfg);
+ ret = imx93_dsi_pll_configure(dsi, &dsi->phy_cfg);
if (ret < 0) {
dev_err(dsi->dev, "failed to configure phy pll: %d\n", ret);
- dphy_pll_uninit(dsi);
+ imx93_dsi_pll_uninit(dsi);
return ret;
}
@@ -667,8 +812,342 @@ static void imx93_dsi_phy_power_off(void *priv_data)
{
struct imx93_dsi *dsi = priv_data;
- dphy_pll_power_off(dsi);
- dphy_pll_uninit(dsi);
+ imx93_pll_power_off(dsi);
+ imx93_dsi_pll_uninit(dsi);
+}
+
+static void
+imx95_dsi_phy_csr_write(struct imx93_dsi *dsi, unsigned int reg, u32 value)
+{
+ int ret;
+
+ ret = regmap_write(dsi->phy, reg, value);
+ if (ret < 0)
+ dev_err(dsi->dev, "failed to write 0x%08x to phy reg 0x%x: %d\n",
+ value, reg, ret);
+}
+
+static int imx95_dsi_select_input(struct imx93_dsi *dsi)
+{
+ struct device *dev = dsi->dev;
+ struct device_node *remote0, *remote1 = NULL;
+ struct device_node *remote_pi0, *remote_pi1 = NULL;
+ struct device_node *remote_ldb_ch0, *remote_ldb_ch1 = NULL;
+ u32 port;
+ int ret;
+
+ /* pixel link0 */
+ remote0 = of_graph_get_remote_node(dev->of_node, 0,
+ IMX95_DSI_ENDPOINT_PL0);
+ /* pixel interleaver channel0 */
+ remote_pi0 = of_graph_get_remote_node(remote0,
+ IMX95_DSI_ENDPOINT_PL0, 0);
+ /* ldb channel0 */
+ port = IMX95_DSI_ENDPOINT_PL0 + PIXEL_LINK_STREAMS;
+ remote_ldb_ch0 = of_graph_get_remote_node(remote0, port, 1);
+ if (remote_pi0 && !remote_ldb_ch0) {
+ dsi->use_pl0 = true;
+ } else {
+ /* pixel link1 */
+ remote1 = of_graph_get_remote_node(dev->of_node, 0,
+ IMX95_DSI_ENDPOINT_PL1);
+ /* pixel interleaver channel1 */
+ remote_pi1 = of_graph_get_remote_node(remote1,
+ IMX95_DSI_ENDPOINT_PL1, 0);
+ /* ldb channel1 */
+ port = IMX95_DSI_ENDPOINT_PL1 + PIXEL_LINK_STREAMS;
+ remote_ldb_ch1 = of_graph_get_remote_node(remote1, port, 1);
+ if (!remote_pi1 || remote_ldb_ch1) {
+ dev_err(dev, "No valid input endpoint found\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ dsi->use_pl0 = false;
+ }
+
+ dev_info(dev, "Using Pixel Link%d as input source\n",
+ dsi->use_pl0 ? 0 : 1);
+
+ return 0;
+
+out:
+ of_node_put(remote_ldb_ch1);
+ of_node_put(remote_pi1);
+ of_node_put(remote1);
+ of_node_put(remote_ldb_ch0);
+ of_node_put(remote_pi0);
+ of_node_put(remote0);
+
+ return ret;
+}
+
+static inline void imx95_dsi_write(struct imx93_dsi *dsi, u32 reg, u32 val)
+{
+ writel(val, dsi->base + reg);
+}
+
+static inline u32 imx95_dsi_read(struct imx93_dsi *dsi, u32 reg)
+{
+ return readl(dsi->base + reg);
+}
+
+static void imx95_dsi_phy_write_testcode(struct imx93_dsi *dsi, u16 test_code)
+{
+ /*
+ * Each control register address is composed by a 4-bit word(testcode
+ * MSBs) and an 8-bit word(testcode LSBs).
+ */
+
+ /* 1. For writing the 4-bit testcode MSBs: */
+ /* a. Ensure that TESTCLK and TESTEN are set to low. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLK);
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_UNTESTEN);
+ /* b. Set TESTEN to high. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN);
+ /* c. Set TESTCLK to high. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK);
+ /* d. Place 0x00 in TESTDIN. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN | PHY_TESTDIN(0));
+ /*
+ * e. Set TESTCLK to low(with the falling edge on TESTCLK, the TESTDIN
+ * signal content is latched internally).
+ */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLK);
+ /* f. Set TESTEN to low. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_UNTESTEN);
+ /* g. Place the MSB 8-bit word of testcode in TESTDIN. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_TESTDIN(test_code >> 8));
+ /* h. Set TESTCLK to high. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK);
+
+ /* 2. For writing the 8-bit testcode LSBs: */
+ /* a. Set TESTCLK to low. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLK);
+ /* b. Set TESTEN to high. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN);
+ /* c. Set TESTCLK to high. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK);
+ /* d. Place the LSB 8-bit word of testcode in TESTDIN. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL1,
+ PHY_TESTEN | PHY_TESTDIN(test_code & 0xff));
+ /*
+ * e. Set TESTCLK to low(with the falling edge on TESTCLK, the TESTDIN
+ * signal content is latched internally).
+ */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLK);
+ /* f. Set TESTEN to low. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL1,
+ PHY_UNTESTEN | PHY_TESTDIN(test_code & 0xff));
+}
+
+static void
+imx95_dsi_phy_tst_ctrl_write(struct imx93_dsi *dsi, u16 test_code, u8 test_data)
+{
+ imx95_dsi_phy_write_testcode(dsi, test_code);
+
+ /* For writing the data: */
+ /* a. Place the 8-bit word in TESTDIN. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_TESTDIN(test_data));
+ /* b. Set TESTCLK to high. */
+ imx95_dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK);
+}
+
+static u8 imx95_dsi_phy_tst_ctrl_read(struct imx93_dsi *dsi, u16 test_code)
+{
+ u32 val;
+
+ imx95_dsi_phy_write_testcode(dsi, test_code);
+
+ /* For reading the data: */
+ val = imx95_dsi_read(dsi, DSI_PHY_TST_CTRL1);
+ return FIELD_GET(PHY_TESTDOUT_MASK, val);
+}
+
+static void
+imx95_dsi_phy_tst_ctrl_update(struct imx93_dsi *dsi, u16 test_code, u8 mask, u8 val)
+{
+ u8 tmp;
+
+ tmp = imx95_dsi_phy_tst_ctrl_read(dsi, test_code);
+ tmp &= ~mask;
+ imx95_dsi_phy_tst_ctrl_write(dsi, test_code, tmp | val);
+}
+
+static int imx95_dsi_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *opts)
+{
+ struct dphy_pll_cfg cfg = { 0 };
+ u32 val;
+ int ret;
+
+ ret = dphy_pll_get_configure_from_opts(dsi, &opts->mipi_dphy, &cfg);
+ if (ret) {
+ dev_err(dsi->dev, "failed to get phy pll cfg %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(dsi->clk_ref);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to enable ref clock: %d\n", ret);
+ return ret;
+ }
+
+ val = PHY_CFGCLKFREQRANGE(dphy_pll_get_cfgclkrange(dsi)) |
+ PHY_HSFREQRANGE(dphy_pll_get_hsfreqrange(&opts->mipi_dphy));
+ imx95_dsi_phy_csr_write(dsi, PHY_FREQ_CONTROL, val);
+
+ /* set pll_mpll_prog_rw (bits1:0) to 2'b11 */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_PLL_13, 0x03);
+ /* set cb_sel_vref_lprx_rw (bits 1:0) to 2'b10 */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_CB_1, 0x06);
+ /* set cb_sel_vrefcd_lprx_rw (bits 6:5) to 2'b10 */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_CB_0, 0x53);
+ /*
+ * set txclk_term_lowcap_lp00_en_ovr_en and
+ * txclk_term_lowcap_lp00_en_ovr(bits 1:0) to 2'b10
+ */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_CLK_TERMLOWCAP, 0x02);
+ /* bit [5:4] of TX control register with address 0x272 to 2'b00 */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_TX_SLEW_7, 0x00);
+ /* sr_osc_freq_target */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_TX_SLEW_6, 0x07);
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_TX_SLEW_5, 0xd0);
+ /* enable slew rate calibration */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_TX_SLEW_7, 0x10);
+
+ ret = clk_prepare_enable(dsi->clk_cfg);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to enable cfg clock: %d\n", ret);
+ return ret;
+ }
+
+ /* pll m */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_PLL_28,
+ PLL_M_LOW(cfg.m));
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_PLL_29,
+ PLL_M_HIGH(cfg.m));
+ imx95_dsi_phy_tst_ctrl_update(dsi, DIG_RDWR_TX_PLL_30,
+ PLL_M_OVR_EN_RW, PLL_M_OVR_EN_RW);
+
+ /* pll n */
+ imx95_dsi_phy_tst_ctrl_update(dsi, DIG_RDWR_TX_PLL_27,
+ PLL_N_OVR_RW_MASK | PLL_N_OVR_EN_RW,
+ PLL_N_OVR_RW(cfg.n) | PLL_N_OVR_EN_RW);
+
+ /* vco ctrl */
+ val = dphy_pll_get_vco(&opts->mipi_dphy);
+ imx95_dsi_phy_tst_ctrl_update(dsi, DIG_RDWR_TX_PLL_30,
+ PLL_VCO_CNTRL_OVR_RW_MASK |
+ PLL_VCO_CNTRL_OVR_EN_RW,
+ PLL_VCO_CNTRL_OVR_RW(val) |
+ PLL_VCO_CNTRL_OVR_EN_RW);
+
+ /* cpbias ctrl */
+ imx95_dsi_phy_tst_ctrl_update(dsi, DIG_RDWR_TX_PLL_1,
+ PLL_CPBIAS_CNTRL_RW_MASK,
+ PLL_CPBIAS_CNTRL_RW(0x10));
+
+ /* int ctrl & gmp ctrl */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_PLL_5,
+ PLL_INT_CNTRL_RW(0x0) |
+ PLL_GMP_CNTRL_RW(0x1));
+
+ /* prop ctrl */
+ val = dphy_pll_get_prop(&opts->mipi_dphy);
+ imx95_dsi_phy_tst_ctrl_update(dsi, DIG_RDWR_TX_PLL_17,
+ PLL_PROP_CNTRL_RW_MASK,
+ PLL_PROP_CNTRL_RW(val));
+
+ /* pll lock configurations */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_PLL_22, 0x2); /* TH1 */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_PLL_23, 0x0); /* TH1 */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_PLL_24,
+ PLL_TH2_RW(0x60));
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_PLL_25,
+ PLL_TH3_RW(0x3));
+ imx95_dsi_phy_tst_ctrl_update(dsi, DIG_RDWR_TX_PLL_9,
+ PLL_LOCK_SEL_RW, PLL_LOCK_SEL_RW);
+
+ /* pll power on */
+ imx95_dsi_phy_tst_ctrl_update(dsi, DIG_RDWR_TX_PLL_17,
+ PLL_PWRON_OVR_RW | PLL_PWRON_OVR_EN_RW,
+ PLL_PWRON_OVR_RW | PLL_PWRON_OVR_EN_RW);
+
+ /* pll clkouten right/left */
+ imx95_dsi_phy_tst_ctrl_write(dsi, DIG_RDWR_TX_PLL_31,
+ PLL_CLKOUTEN_RIGHT_RW |
+ PLL_CLKOUTEN_LEFT_RW);
+
+ return 0;
+}
+
+static int imx95_dsi_phy_init(void *priv_data)
+{
+ struct imx93_dsi *dsi = priv_data;
+ u64 lane_mask;
+ int bpp, ret;
+
+ regmap_write(dsi->mst, DSI_PIXEL_LINK_CONTROL, dsi->use_pl0 ? 0 : PIXEL_LINK_SEL);
+
+ bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+ if (bpp < 0) {
+ dev_err(dsi->dev, "failed to get dsi format bpp\n");
+ return bpp;
+ }
+
+ imx95_dsi_write(dsi, DSI_DPI_CFG_POL, VSYNC_ACTIVE_LOW | HSYNC_ACTIVE_LOW);
+
+ regmap_write(dsi->mst, DSI_CLOCK_SETTING, 0);
+
+ switch (bpp) {
+ case 24:
+ regmap_write(dsi->str, DSI_HOST_CONFIGURATION, RGB_24BIT);
+ break;
+ case 18:
+ regmap_write(dsi->str, DSI_HOST_CONFIGURATION, RGB_18BIT);
+ break;
+ case 16:
+ regmap_write(dsi->str, DSI_HOST_CONFIGURATION, RGB_16BIT);
+ break;
+ default:
+ dev_err(dsi->dev, "invalid dsi format bpp %d\n", bpp);
+ return -EINVAL;
+ }
+
+ lane_mask = int_pow(2, dsi->lanes) - 1;
+ imx95_dsi_phy_csr_write(dsi, PHY_MODE_CONTROL,
+ PHY_ENABLE_EXT(lane_mask) | PLL_CLKSEL_GEN |
+ TX_RXZ_DSI_MODE);
+
+ ret = imx95_dsi_pll_configure(dsi, &dsi->phy_cfg);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to configure phy pll: %d\n", ret);
+ return ret;
+ }
+
+ imx95_dsi_phy_csr_write(dsi, PHY_TEST_MODE_CONTROL, TURNDISABLE_0);
+
+ regmap_write(dsi->mst, DSI_CLOCK_GATING_CONTROL,
+ DISPLAY_ASYNC_FIFO(dsi->use_pl0));
+
+ return 0;
+}
+
+static void imx95_dsi_phy_power_off(void *priv_data)
+{
+ struct imx93_dsi *dsi = priv_data;
+
+ /* set 1 to disable */
+ regmap_write(dsi->mst, DSI_CLOCK_GATING_CONTROL,
+ DPHY_PLL_CLKEXT | DPHY_PLL_CLKOUT | DPHY_PLL_CLKIN |
+ DISPLAY_ASYNC_FIFO(0) | DISPLAY_ASYNC_FIFO(1));
+
+ imx95_dsi_phy_csr_write(dsi, PHY_MODE_CONTROL, TX_RXZ_DSI_MODE);
+
+ clk_disable_unprepare(dsi->clk_cfg);
+ clk_disable_unprepare(dsi->clk_ref);
+
+ regmap_write(dsi->mst, DSI_PIXEL_LINK_CONTROL, 0);
}
static int
@@ -814,10 +1293,18 @@ static const struct dw_mipi_dsi_phy_ops imx93_dsi_phy_ops = {
.get_timing = imx93_dsi_phy_get_timing,
};
+static const struct dw_mipi_dsi_phy_ops imx95_dsi_phy_ops = {
+ .init = imx95_dsi_phy_init,
+ .power_off = imx95_dsi_phy_power_off,
+ .get_lane_mbps = imx93_dsi_get_lane_mbps,
+ .get_timing = imx93_dsi_phy_get_timing,
+};
+
static int imx93_dsi_host_attach(void *priv_data, struct mipi_dsi_device *device)
{
struct imx93_dsi *dsi = priv_data;
+ dsi->lanes = device->lanes;
dsi->format = device->format;
return 0;
@@ -827,17 +1314,12 @@ static const struct dw_mipi_dsi_host_ops imx93_dsi_host_ops = {
.attach = imx93_dsi_host_attach,
};
-static int imx93_dsi_probe(struct platform_device *pdev)
+static int imx93_dsi_parse_dt(struct imx93_dsi *dsi)
{
- struct device *dev = &pdev->dev;
+ struct device *dev = dsi->dev;
struct device_node *np = dev->of_node;
- struct imx93_dsi *dsi;
int ret;
- dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
- if (!dsi)
- return -ENOMEM;
-
dsi->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,media-blk-ctrl");
if (IS_ERR(dsi->regmap)) {
ret = PTR_ERR(dsi->regmap);
@@ -845,6 +1327,46 @@ static int imx93_dsi_probe(struct platform_device *pdev)
return ret;
}
+ return 0;
+}
+
+static int imx95_dsi_parse_dt(struct platform_device *pdev, struct imx93_dsi *dsi)
+{
+ struct device *dev = dsi->dev;
+ struct device_node *np = dev->of_node;
+
+ dsi->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(dsi->base))
+ return PTR_ERR(dsi->base);
+
+ dsi->mst = syscon_regmap_lookup_by_phandle(np, "fsl,disp-master-csr");
+ if (IS_ERR(dsi->mst))
+ return dev_err_probe(dev, PTR_ERR(dsi->mst),
+ "failed to get master CSR\n");
+
+ dsi->str = syscon_regmap_lookup_by_phandle(np, "fsl,disp-stream-csr");
+ if (IS_ERR(dsi->str))
+ return dev_err_probe(dev, PTR_ERR(dsi->str),
+ "failed to get stream CSR\n");
+
+ dsi->phy = syscon_regmap_lookup_by_phandle(np, "fsl,mipi-combo-phy-csr");
+ if (IS_ERR(dsi->phy))
+ return dev_err_probe(dev, PTR_ERR(dsi->phy),
+ "failed to get phy CSR\n");
+
+ return imx95_dsi_select_input(dsi);
+}
+
+static int imx93_dsi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct imx93_dsi *dsi;
+ int ret;
+
+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
+ if (!dsi)
+ return -ENOMEM;
+
dsi->clk_pixel = devm_clk_get(dev, "pix");
if (IS_ERR(dsi->clk_pixel))
return dev_err_probe(dev, PTR_ERR(dsi->clk_pixel),
@@ -870,11 +1392,26 @@ static int imx93_dsi_probe(struct platform_device *pdev)
dev_dbg(dev, "phy ref clock rate: %lu\n", dsi->ref_clk_rate);
dsi->dev = dev;
+
+ if (of_device_is_compatible(dev->of_node, "fsl,imx93-mipi-dsi"))
+ ret = imx93_dsi_parse_dt(dsi);
+ else
+ ret = imx95_dsi_parse_dt(pdev, dsi);
+ if (ret)
+ return ret;
+
+ dsi->pdata.base = dsi->base;
dsi->pdata.max_data_lanes = 4;
dsi->pdata.mode_valid = imx93_dsi_mode_valid;
dsi->pdata.mode_fixup = imx93_dsi_mode_fixup;
dsi->pdata.get_input_bus_fmts = imx93_dsi_get_input_bus_fmts;
- dsi->pdata.phy_ops = &imx93_dsi_phy_ops;
+ if (of_device_is_compatible(dev->of_node, "fsl,imx93-mipi-dsi")) {
+ dsi->pdata.phy_ops = &imx93_dsi_phy_ops;
+ dsi->fixed_format = MEDIA_BUS_FMT_RGB888_1X24;
+ } else {
+ dsi->pdata.phy_ops = &imx95_dsi_phy_ops;
+ dsi->fixed_format = MEDIA_BUS_FMT_RGB888_1X36_CPADLO;
+ }
dsi->pdata.host_ops = &imx93_dsi_host_ops;
dsi->pdata.priv_data = dsi;
platform_set_drvdata(pdev, dsi);
@@ -896,6 +1433,7 @@ static void imx93_dsi_remove(struct platform_device *pdev)
static const struct of_device_id imx93_dsi_dt_ids[] = {
{ .compatible = "fsl,imx93-mipi-dsi", },
+ { .compatible = "fsl,imx95-mipi-dsi", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx93_dsi_dt_ids);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* [PATCH 31/39] dt-bindings: clock: Split support for i.MX95 LVDS CSR
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (29 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 30/39] drm/bridge: imx93-mipi-dsi: Add i.MX95 PLL initialization Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:17 ` Frank Li
2025-10-11 16:51 ` [PATCH 32/39] dt-bindings: display: bridge: Document i.MX95 LVDS display bridge binding Marek Vasut
` (9 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Split i.MX95 LVDS CSR into separate binding document, as it is different
enough from the other CSR in the block controller binding document and
has subnodes too.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
.../bindings/clock/nxp,imx95-blk-ctl.yaml | 1 -
.../clock/nxp,imx95-lvds-blk-ctl.yaml | 80 +++++++++++++++++++
2 files changed, 80 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/clock/nxp,imx95-lvds-blk-ctl.yaml
diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
index 27403b4c52d62..0a28e24135243 100644
--- a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
+++ b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
@@ -18,7 +18,6 @@ properties:
- nxp,imx95-camera-csr
- nxp,imx95-display-csr
- nxp,imx95-hsio-blk-ctl
- - nxp,imx95-lvds-csr
- nxp,imx95-netcmix-blk-ctrl
- nxp,imx95-vpu-csr
- const: syscon
diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-lvds-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-lvds-blk-ctl.yaml
new file mode 100644
index 0000000000000..663f3ee1df4e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nxp,imx95-lvds-blk-ctl.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/nxp,imx95-lvds-blk-ctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX95 LVDS Block Control
+
+maintainers:
+ - Marek Vasut <marek.vasut@mailbox.org>
+ - Peng Fan <peng.fan@nxp.com>
+
+properties:
+ compatible:
+ items:
+ - const: nxp,imx95-lvds-csr
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+ description:
+ The clock consumer should specify the desired clock by having the clock
+ ID in its "clocks" phandle cell. See
+ include/dt-bindings/clock/nxp,imx95-clock.h
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+patternProperties:
+ "^lvds@[0-9a-f]+$":
+ type: object
+ additionalProperties: true
+
+ properties:
+ compatible:
+ const: fsl,imx95-lvds
+
+ "^phy@[0-9a-f]+$":
+ type: object
+ additionalProperties: true
+
+ properties:
+ compatible:
+ const: fsl,imx95-ldb
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+ - power-domains
+ - clocks
+ - "#address-cells"
+ - "#size-cells"
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ syscon@4c410000 {
+ compatible = "nxp,imx95-lvds-csr", "syscon";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x4b0c0000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&scmi_clk 76>;
+ power-domains = <&scmi_devpd 13>;
+ };
+...
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 31/39] dt-bindings: clock: Split support for i.MX95 LVDS CSR
2025-10-11 16:51 ` [PATCH 31/39] dt-bindings: clock: Split support for i.MX95 LVDS CSR Marek Vasut
@ 2025-10-13 19:17 ` Frank Li
2025-10-17 15:49 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:17 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:46PM +0200, Marek Vasut wrote:
> Split i.MX95 LVDS CSR into separate binding document, as it is different
> enough from the other CSR in the block controller binding document and
> has subnodes too.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../bindings/clock/nxp,imx95-blk-ctl.yaml | 1 -
> .../clock/nxp,imx95-lvds-blk-ctl.yaml | 80 +++++++++++++++++++
> 2 files changed, 80 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/devicetree/bindings/clock/nxp,imx95-lvds-blk-ctl.yaml
>
> diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> index 27403b4c52d62..0a28e24135243 100644
> --- a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> +++ b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> @@ -18,7 +18,6 @@ properties:
> - nxp,imx95-camera-csr
> - nxp,imx95-display-csr
> - nxp,imx95-hsio-blk-ctl
> - - nxp,imx95-lvds-csr
> - nxp,imx95-netcmix-blk-ctrl
> - nxp,imx95-vpu-csr
> - const: syscon
> diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-lvds-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-lvds-blk-ctl.yaml
> new file mode 100644
> index 0000000000000..663f3ee1df4e0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/nxp,imx95-lvds-blk-ctl.yaml
> @@ -0,0 +1,80 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/nxp,imx95-lvds-blk-ctl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP i.MX95 LVDS Block Control
> +
> +maintainers:
> + - Marek Vasut <marek.vasut@mailbox.org>
> + - Peng Fan <peng.fan@nxp.com>
> +
> +properties:
> + compatible:
> + items:
> + - const: nxp,imx95-lvds-csr
> + - const: syscon
> +
> + reg:
> + maxItems: 1
> +
> + power-domains:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + '#clock-cells':
> + const: 1
> + description:
> + The clock consumer should specify the desired clock by having the clock
> + ID in its "clocks" phandle cell. See
> + include/dt-bindings/clock/nxp,imx95-clock.h
> +
> + "#address-cells":
> + const: 1
> +
> + "#size-cells":
> + const: 1
> +
> +patternProperties:
> + "^lvds@[0-9a-f]+$":
> + type: object
> + additionalProperties: true
> +
> + properties:
> + compatible:
> + const: fsl,imx95-lvds
> +
> + "^phy@[0-9a-f]+$":
> + type: object
> + additionalProperties: true
Is it standard phy interface? need phy-cells
> +
> + properties:
> + compatible:
> + const: fsl,imx95-ldb
> +
> +required:
> + - compatible
> + - reg
> + - '#clock-cells'
> + - power-domains
> + - clocks
> + - "#address-cells"
> + - "#size-cells"
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + syscon@4c410000 {
> + compatible = "nxp,imx95-lvds-csr", "syscon";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0x4b0c0000 0x10000>;
> + #clock-cells = <1>;
> + clocks = <&scmi_clk 76>;
> + power-domains = <&scmi_devpd 13>;
Need full examples, included phy and lvds here.
Frank
> + };
> +...
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 31/39] dt-bindings: clock: Split support for i.MX95 LVDS CSR
2025-10-13 19:17 ` Frank Li
@ 2025-10-17 15:49 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:49 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 9:17 PM, Frank Li wrote:
Hello Frank,
[...]
>> + "^phy@[0-9a-f]+$":
>> + type: object
>> + additionalProperties: true
>
> Is it standard phy interface? need phy-cells
It is drivers/gpu/drm/bridge/fsl-ldb.c .
It is LVDS PHY, but modeled as a bridge driver.
The rest is fixed, thanks !
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 32/39] dt-bindings: display: bridge: Document i.MX95 LVDS display bridge binding
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (30 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 31/39] dt-bindings: clock: Split support for i.MX95 LVDS CSR Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:20 ` Frank Li
2025-10-11 16:51 ` [PATCH 33/39] drm: bridge: imx: Add i.MX95 LVDS Display Bridge (LDB) driver Marek Vasut
` (8 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Document i.MX95 LVDS display bridge (LDB) bindings.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
.../display/bridge/fsl,imx95-lvds.yaml | 140 ++++++++++++++++++
1 file changed, 140 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.yaml
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.yaml
new file mode 100644
index 0000000000000..8ada9c82a10d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.yaml
@@ -0,0 +1,140 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/fsl,imx95-lvds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX95 LVDS Display Bridge
+
+maintainers:
+ - Marek Vasut <marek.vasut@mailbox.org>
+
+description: |
+ The Freescale i.MX95 LVDS Display Bridge(LDB) has two channels.
+
+ The i.MX8qm/qxp LDB is controlled by Control and Status Registers(CSR) module.
+ The CSR module, as a system controller, contains the LDB's configuration
+ registers.
+
+properties:
+ compatible:
+ const: fsl,imx95-lvds
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 4
+
+ clock-names:
+ items:
+ - const: ldb_di0
+ - const: ldb_di1
+ - const: ldb_ch0
+ - const: ldb_ch1
+
+ power-domains:
+ maxItems: 1
+
+patternProperties:
+ "^channel@[0-1]$":
+ type: object
+ description: Represents a channel of LDB.
+
+ properties:
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ reg:
+ description: The channel index.
+ enum: [ 0, 1 ]
+
+ phys:
+ description: A phandle to the phy module representing the LVDS PHY.
+ maxItems: 1
+
+ phy-names:
+ const: lvds_phy
+
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Input port of the channel.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Output port of the channel.
+
+ required:
+ - "#address-cells"
+ - "#size-cells"
+ - reg
+ - phys
+ - phy-names
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - "#address-cells"
+ - "#size-cells"
+ - clocks
+ - clock-names
+ - power-domains
+ - channel@0
+ - channel@1
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/firmware/imx/rsrc.h>
+ ldb {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx95-ldb";
+ clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>,
+ <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
+ clock-names = "pixel", "bypass";
+ power-domains = <&pd IMX_SC_R_LVDS_0>;
+
+ channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ phys = <&mipi_lvds_0_phy>;
+ phy-names = "lvds_phy";
+
+ port@0 {
+ reg = <0>;
+
+ mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi: endpoint {
+ remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0>;
+ };
+ };
+ };
+
+ channel@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ phys = <&mipi_lvds_0_phy>;
+ phy-names = "lvds_phy";
+
+ port@0 {
+ reg = <0>;
+
+ mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi: endpoint {
+ remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1>;
+ };
+ };
+ };
+ };
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 32/39] dt-bindings: display: bridge: Document i.MX95 LVDS display bridge binding
2025-10-11 16:51 ` [PATCH 32/39] dt-bindings: display: bridge: Document i.MX95 LVDS display bridge binding Marek Vasut
@ 2025-10-13 19:20 ` Frank Li
2025-10-17 15:04 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:20 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:47PM +0200, Marek Vasut wrote:
> Document i.MX95 LVDS display bridge (LDB) bindings.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../display/bridge/fsl,imx95-lvds.yaml | 140 ++++++++++++++++++
> 1 file changed, 140 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.yaml
> new file mode 100644
> index 0000000000000..8ada9c82a10d0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.yaml
> @@ -0,0 +1,140 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/bridge/fsl,imx95-lvds.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX95 LVDS Display Bridge
> +
> +maintainers:
> + - Marek Vasut <marek.vasut@mailbox.org>
> +
> +description: |
use ">" instead | here.
> + The Freescale i.MX95 LVDS Display Bridge(LDB) has two channels.
> +
> + The i.MX8qm/qxp LDB is controlled by Control and Status Registers(CSR) module.
> + The CSR module, as a system controller, contains the LDB's configuration
> + registers.
> +
> +properties:
> + compatible:
> + const: fsl,imx95-lvds
> +
> + "#address-cells":
> + const: 1
> +
> + "#size-cells":
> + const: 0
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 4
> +
> + clock-names:
> + items:
> + - const: ldb_di0
> + - const: ldb_di1
> + - const: ldb_ch0
> + - const: ldb_ch1
> +
> + power-domains:
> + maxItems: 1
> +
> +patternProperties:
> + "^channel@[0-1]$":
> + type: object
> + description: Represents a channel of LDB.
> +
> + properties:
> + "#address-cells":
> + const: 1
> +
> + "#size-cells":
> + const: 0
> +
> + reg:
> + description: The channel index.
> + enum: [ 0, 1 ]
> +
> + phys:
> + description: A phandle to the phy module representing the LVDS PHY.
> + maxItems: 1
> +
> + phy-names:
> + const: lvds_phy
> +
> + port@0:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: Input port of the channel.
> +
> + port@1:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: Output port of the channel.
most likely port@<n> should be under ports.
> +
> + required:
> + - "#address-cells"
> + - "#size-cells"
> + - reg
> + - phys
> + - phy-names
> +
> + additionalProperties: false
> +
> +required:
> + - compatible
> + - "#address-cells"
> + - "#size-cells"
> + - clocks
> + - clock-names
> + - power-domains
> + - channel@0
> + - channel@1
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/firmware/imx/rsrc.h>
Add empty line here
> + ldb {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "fsl,imx95-ldb";
> + clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>,
> + <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
> + clock-names = "pixel", "bypass";
> + power-domains = <&pd IMX_SC_R_LVDS_0>;
> +
> + channel@0 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <0>;
> + phys = <&mipi_lvds_0_phy>;
> + phy-names = "lvds_phy";
> +
> + port@0 {
> + reg = <0>;
> +
> + mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi: endpoint {
needn't label here.
Frank
> + remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0>;
> + };
> + };
> + };
> +
> + channel@1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>;
> + phys = <&mipi_lvds_0_phy>;
> + phy-names = "lvds_phy";
> +
> + port@0 {
> + reg = <0>;
> +
> + mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi: endpoint {
> + remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1>;
> + };
> + };
> + };
> + };
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 32/39] dt-bindings: display: bridge: Document i.MX95 LVDS display bridge binding
2025-10-13 19:20 ` Frank Li
@ 2025-10-17 15:04 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:04 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 9:20 PM, Frank Li wrote:
Hello Frank,
[...]
>> +patternProperties:
>> + "^channel@[0-1]$":
>> + type: object
>> + description: Represents a channel of LDB.
...
>> + port@0:
>> + $ref: /schemas/graph.yaml#/properties/port
>> + description: Input port of the channel.
>> +
>> + port@1:
>> + $ref: /schemas/graph.yaml#/properties/port
>> + description: Output port of the channel.
>
> most likely port@<n> should be under ports.
The topology here is a bit different, the ports are directly under
channel, just like (usually) endpoints would be under port . I think
this is correct, even if I agree it does look odd.
The rest is fixed, thanks !
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 33/39] drm: bridge: imx: Add i.MX95 LVDS Display Bridge (LDB) driver
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (31 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 32/39] dt-bindings: display: bridge: Document i.MX95 LVDS display bridge binding Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-11 16:51 ` [PATCH 34/39] dt-bindings: display: bridge: ldb: Add an i.MX95 entry Marek Vasut
` (7 subsequent siblings)
40 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Sandor Yu, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
From: Sandor Yu <Sandor.yu@nxp.com>
Add i.MX95 LVDS Display Bridge (LDB) driver.
Signed-off-by: Sandor Yu <Sandor.yu@nxp.com>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/bridge/imx/Kconfig | 10 +
drivers/gpu/drm/bridge/imx/Makefile | 1 +
drivers/gpu/drm/bridge/imx/imx-ldb-helper.h | 2 +
drivers/gpu/drm/bridge/imx/imx95-ldb.c | 470 ++++++++++++++++++++
4 files changed, 483 insertions(+)
create mode 100644 drivers/gpu/drm/bridge/imx/imx95-ldb.c
diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig
index 8baa335deac49..350432f77801c 100644
--- a/drivers/gpu/drm/bridge/imx/Kconfig
+++ b/drivers/gpu/drm/bridge/imx/Kconfig
@@ -88,6 +88,16 @@ config DRM_IMX93_MIPI_DSI
Choose this to enable MIPI DSI controller found in Freescale i.MX93
processor.
+config DRM_IMX95_LDB
+ tristate "Freescale i.MX95 LVDS display bridge"
+ depends on OF
+ depends on COMMON_CLK
+ select DRM_IMX_LDB_HELPER
+ select DRM_KMS_HELPER
+ help
+ Choose this to enable the internal LVDS Display Bridge(LDB) found in
+ Freescale i.MX95 processor.
+
config DRM_IMX95_PIXEL_INTERLEAVER
tristate "NXP i.MX95 pixel interleaver"
depends on OF && MFD_SYSCON && COMMON_CLK
diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile
index b6b2e1bc8d4bd..1c78cfba16cad 100644
--- a/drivers/gpu/drm/bridge/imx/Makefile
+++ b/drivers/gpu/drm/bridge/imx/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o
obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o
obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o
obj-$(CONFIG_DRM_IMX93_MIPI_DSI) += imx93-mipi-dsi.o
+obj-$(CONFIG_DRM_IMX95_LDB) += imx95-ldb.o
obj-$(CONFIG_DRM_IMX95_PIXEL_INTERLEAVER) += imx95-pixel-interleaver.o
obj-$(CONFIG_DRM_IMX95_PIXEL_LINK) += imx95-pixel-link.o
diff --git a/drivers/gpu/drm/bridge/imx/imx-ldb-helper.h b/drivers/gpu/drm/bridge/imx/imx-ldb-helper.h
index de187e3269996..55fad97c65d2f 100644
--- a/drivers/gpu/drm/bridge/imx/imx-ldb-helper.h
+++ b/drivers/gpu/drm/bridge/imx/imx-ldb-helper.h
@@ -31,6 +31,8 @@
#define LDB_BIT_MAP_CH1_JEIDA BIT(8)
#define LDB_DI0_VS_POL_ACT_LOW BIT(9)
#define LDB_DI1_VS_POL_ACT_LOW BIT(10)
+#define LDB_DI0_HS_POL_ACT_LOW BIT(13)
+#define LDB_DI1_HS_POL_ACT_LOW BIT(14)
#define MAX_LDB_CHAN_NUM 2
diff --git a/drivers/gpu/drm/bridge/imx/imx95-ldb.c b/drivers/gpu/drm/bridge/imx/imx95-ldb.c
new file mode 100644
index 0000000000000..19e2d71b9c0c7
--- /dev/null
+++ b/drivers/gpu/drm/bridge/imx/imx95-ldb.c
@@ -0,0 +1,470 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright 2023 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/media-bus-format.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_of.h>
+#include <drm/drm_print.h>
+
+#include "imx-ldb-helper.h"
+
+#define LVDS_PHY_CLK_CTRL 0x00
+#define LVDS_PHY_DIV2 BIT(0)
+
+#define LDB_DI0_HS_POL_ACT_LOW BIT(13)
+#define LDB_DI1_HS_POL_ACT_LOW BIT(14)
+#define LDB_VSYNC_ADJ_EN BIT(19)
+
+#define DRIVER_NAME "imx95-ldb"
+
+struct imx95_ldb_channel {
+ struct ldb_channel base;
+};
+
+struct imx95_ldb {
+ struct ldb base;
+ struct device *dev;
+ struct imx95_ldb_channel *channel[MAX_LDB_CHAN_NUM];
+ struct clk *clk_ch[MAX_LDB_CHAN_NUM];
+ struct clk *clk_di[MAX_LDB_CHAN_NUM];
+ int active_chno;
+};
+
+static inline struct imx95_ldb_channel *
+base_to_imx95_ldb_channel(struct ldb_channel *base)
+{
+ return container_of(base, struct imx95_ldb_channel, base);
+}
+
+static inline struct imx95_ldb *base_to_imx95_ldb(struct ldb *base)
+{
+ return container_of(base, struct imx95_ldb, base);
+}
+
+static int imx95_ldb_bridge_atomic_check(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ return ldb_bridge_atomic_check_helper(bridge, bridge_state,
+ crtc_state, conn_state);
+}
+
+static void
+imx95_ldb_bridge_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adjusted_mode)
+{
+ struct ldb_channel *ldb_ch = bridge->driver_private;
+ struct ldb *ldb = ldb_ch->ldb;
+ struct imx95_ldb *imx95_ldb = base_to_imx95_ldb(ldb);
+ struct device *dev = imx95_ldb->dev;
+ unsigned long di_clk = adjusted_mode->clock * 1000;
+ bool is_split = ldb_channel_is_split_link(ldb_ch);
+ int ret;
+
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+ dev_err(dev, "failed to get runtime PM sync: %d\n", ret);
+
+ /* set lvds di clock rate */
+ clk_set_rate(imx95_ldb->clk_di[ldb_ch->chno], di_clk);
+
+ ldb->ldb_ctrl |= LDB_VSYNC_ADJ_EN;
+
+ if (ldb_ch->chno == 0 || is_split) {
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+ ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW;
+ else if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+ ldb->ldb_ctrl &= ~LDB_DI0_VS_POL_ACT_LOW;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+ ldb->ldb_ctrl |= LDB_DI0_HS_POL_ACT_LOW;
+ else if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+ ldb->ldb_ctrl &= ~LDB_DI0_HS_POL_ACT_LOW;
+ }
+ if (ldb_ch->chno == 1 || is_split) {
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+ ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW;
+ else if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+ ldb->ldb_ctrl &= ~LDB_DI1_VS_POL_ACT_LOW;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+ ldb->ldb_ctrl |= LDB_DI1_HS_POL_ACT_LOW;
+ else if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+ ldb->ldb_ctrl &= ~LDB_DI1_HS_POL_ACT_LOW;
+ }
+
+ ldb_bridge_mode_set_helper(bridge, mode, adjusted_mode);
+}
+
+static void
+imx95_ldb_bridge_atomic_enable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state)
+{
+ struct ldb_channel *ldb_ch = bridge->driver_private;
+ struct ldb *ldb = ldb_ch->ldb;
+ struct imx95_ldb *imx95_ldb = base_to_imx95_ldb(ldb);
+ bool is_split = ldb_channel_is_split_link(ldb_ch);
+
+ clk_prepare_enable(imx95_ldb->clk_ch[ldb_ch->chno]);
+ clk_prepare_enable(imx95_ldb->clk_di[ldb_ch->chno]);
+ if (is_split) {
+ clk_prepare_enable(imx95_ldb->clk_ch[ldb_ch->chno ^ 1]);
+ clk_prepare_enable(imx95_ldb->clk_di[ldb_ch->chno ^ 1]);
+ }
+
+ if (ldb_ch->chno == 0 || is_split) {
+ ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
+ ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0;
+ }
+ if (ldb_ch->chno == 1 || is_split) {
+ ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
+ ldb->ldb_ctrl |= is_split ?
+ LDB_CH1_MODE_EN_TO_DI0 : LDB_CH1_MODE_EN_TO_DI1;
+ }
+
+ if (is_split) {
+ /* PHY clock divider 2 */
+ regmap_update_bits(ldb->regmap, LVDS_PHY_CLK_CTRL,
+ LVDS_PHY_DIV2, LVDS_PHY_DIV2);
+ }
+
+ ldb_bridge_enable_helper(bridge);
+}
+
+static void
+imx95_ldb_bridge_atomic_disable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state)
+{
+ struct ldb_channel *ldb_ch = bridge->driver_private;
+ struct ldb *ldb = ldb_ch->ldb;
+ struct imx95_ldb *imx95_ldb = base_to_imx95_ldb(ldb);
+ struct device *dev = imx95_ldb->dev;
+ bool is_split = ldb_channel_is_split_link(ldb_ch);
+ int ret;
+
+ ldb_bridge_disable_helper(bridge);
+
+ if (is_split) {
+ /* clean PHY clock divider 2 */
+ regmap_update_bits(ldb->regmap, LVDS_PHY_CLK_CTRL, LVDS_PHY_DIV2, 0);
+ }
+
+ if (is_split) {
+ clk_disable_unprepare(imx95_ldb->clk_di[ldb_ch->chno ^ 1]);
+ clk_disable_unprepare(imx95_ldb->clk_ch[ldb_ch->chno ^ 1]);
+ }
+ clk_disable_unprepare(imx95_ldb->clk_di[ldb_ch->chno]);
+ clk_disable_unprepare(imx95_ldb->clk_ch[ldb_ch->chno]);
+
+ ret = pm_runtime_put(dev);
+ if (ret < 0)
+ dev_err(dev, "failed to put runtime PM: %d\n", ret);
+}
+
+static const u32 imx95_ldb_bus_output_fmts[] = {
+ MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
+ MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+ MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
+ MEDIA_BUS_FMT_FIXED,
+};
+
+static bool imx95_ldb_bus_output_fmt_supported(u32 fmt)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(imx95_ldb_bus_output_fmts); i++) {
+ if (imx95_ldb_bus_output_fmts[i] == fmt)
+ return true;
+ }
+
+ return false;
+}
+
+static u32 *
+imx95_ldb_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state,
+ u32 output_fmt,
+ unsigned int *num_input_fmts)
+{
+ struct drm_display_info *di;
+ const struct drm_format_info *finfo;
+ u32 *input_fmts;
+
+ if (!imx95_ldb_bus_output_fmt_supported(output_fmt))
+ return NULL;
+
+ *num_input_fmts = 1;
+
+ input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
+ if (!input_fmts)
+ return NULL;
+
+ switch (output_fmt) {
+ case MEDIA_BUS_FMT_FIXED:
+ di = &conn_state->connector->display_info;
+
+ /*
+ * Look at the first bus format to determine input format.
+ * Default to MEDIA_BUS_FMT_RGB888_1X36_CPADLO, if no match.
+ */
+ if (di->num_bus_formats) {
+ finfo = drm_format_info(di->bus_formats[0]);
+
+ input_fmts[0] = finfo->depth == 18 ?
+ MEDIA_BUS_FMT_RGB666_1X36_CPADLO :
+ MEDIA_BUS_FMT_RGB888_1X36_CPADLO;
+ } else {
+ input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X36_CPADLO;
+ }
+ break;
+ case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
+ input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X36_CPADLO;
+ break;
+ case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
+ case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
+ input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X36_CPADLO;
+ break;
+ default:
+ kfree(input_fmts);
+ input_fmts = NULL;
+ break;
+ }
+
+ return input_fmts;
+}
+
+static u32 *
+imx95_ldb_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state,
+ unsigned int *num_output_fmts)
+{
+ *num_output_fmts = ARRAY_SIZE(imx95_ldb_bus_output_fmts);
+ return kmemdup(imx95_ldb_bus_output_fmts,
+ sizeof(imx95_ldb_bus_output_fmts), GFP_KERNEL);
+}
+
+static enum drm_mode_status
+imx95_ldb_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
+ const struct drm_display_mode *mode)
+{
+ struct ldb_channel *ldb_ch = bridge->driver_private;
+ struct ldb *ldb = ldb_ch->ldb;
+ struct imx95_ldb *imx95_ldb = base_to_imx95_ldb(ldb);
+ bool is_single = ldb_channel_is_single_link(ldb_ch);
+ struct drm_bridge *next_bridge = bridge;
+ unsigned long pixel_clock_rate;
+ unsigned long rounded_rate;
+
+ if (mode->clock > 330000)
+ return MODE_CLOCK_HIGH;
+
+ if (mode->clock > 165000 && is_single)
+ return MODE_CLOCK_HIGH;
+
+ while (drm_bridge_get_next_bridge(next_bridge))
+ next_bridge = drm_bridge_get_next_bridge(next_bridge);
+
+ if ((next_bridge->ops & DRM_BRIDGE_OP_DETECT) &&
+ (next_bridge->ops & DRM_BRIDGE_OP_EDID)) {
+ if (imx95_ldb->clk_di[ldb_ch->chno]) {
+ pixel_clock_rate = mode->clock * 1000;
+ rounded_rate = clk_round_rate(imx95_ldb->clk_di[ldb_ch->chno],
+ pixel_clock_rate);
+ if (rounded_rate != pixel_clock_rate)
+ return MODE_CLOCK_RANGE;
+ }
+ }
+
+ return MODE_OK;
+}
+
+static const struct drm_bridge_funcs imx95_ldb_bridge_funcs = {
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .atomic_reset = drm_atomic_helper_bridge_reset,
+ .mode_valid = imx95_ldb_bridge_mode_valid,
+ .attach = ldb_bridge_attach_helper,
+ .atomic_check = imx95_ldb_bridge_atomic_check,
+ .mode_set = imx95_ldb_bridge_mode_set,
+ .atomic_enable = imx95_ldb_bridge_atomic_enable,
+ .atomic_disable = imx95_ldb_bridge_atomic_disable,
+ .atomic_get_input_bus_fmts =
+ imx95_ldb_bridge_atomic_get_input_bus_fmts,
+ .atomic_get_output_bus_fmts =
+ imx95_ldb_bridge_atomic_get_output_bus_fmts,
+};
+
+static int imx95_ldb_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct imx95_ldb *imx95_ldb;
+ struct imx95_ldb_channel *imx95_ldb_ch;
+ struct ldb *ldb;
+ struct ldb_channel *ldb_ch;
+ struct device_node *port1, *port2;
+ int pixel_order;
+ int ret, i;
+
+ imx95_ldb = devm_kzalloc(dev, sizeof(*imx95_ldb), GFP_KERNEL);
+ if (!imx95_ldb)
+ return -ENOMEM;
+
+ for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
+ char clk_name_ldb_ch[8], clk_name_ldb_di[8];
+
+ snprintf(clk_name_ldb_ch, sizeof(clk_name_ldb_ch), "ldb_ch%d", i);
+ snprintf(clk_name_ldb_di, sizeof(clk_name_ldb_di), "ldb_di%d", i);
+
+ imx95_ldb->clk_ch[i] = devm_clk_get(dev, clk_name_ldb_ch);
+ if (IS_ERR(imx95_ldb->clk_ch[i]))
+ return dev_err_probe(dev, PTR_ERR(imx95_ldb->clk_ch[i]),
+ "failed to get ldb ch%d clock\n", i);
+
+ imx95_ldb->clk_di[i] = devm_clk_get(dev, clk_name_ldb_di);
+ if (IS_ERR(imx95_ldb->clk_di[i]))
+ return dev_err_probe(dev, PTR_ERR(imx95_ldb->clk_di[i]),
+ "failed to get ldb di%d clock\n", i);
+ }
+
+ imx95_ldb->dev = dev;
+
+ ldb = &imx95_ldb->base;
+ ldb->dev = dev;
+ ldb->ctrl_reg = 0x4;
+ ldb->ldb_ctrl = 0;
+
+ for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
+ imx95_ldb->channel[i] =
+ devm_drm_bridge_alloc(dev, struct imx95_ldb_channel,
+ base.bridge, &imx95_ldb_bridge_funcs);
+ if (IS_ERR(imx95_ldb->channel[i]))
+ return PTR_ERR(imx95_ldb->channel[i]);
+ }
+
+ for (i = 0; i < MAX_LDB_CHAN_NUM; i++)
+ ldb->channel[i] = &imx95_ldb->channel[i]->base;
+
+ ret = ldb_init_helper(ldb);
+ if (ret)
+ return ret;
+
+ if (ldb->available_ch_cnt == 0) {
+ dev_dbg(dev, "no available channel\n");
+ return 0;
+ }
+
+ if (ldb->available_ch_cnt == 2) {
+ port1 = of_graph_get_port_by_id(ldb->channel[0]->np, 1);
+ port2 = of_graph_get_port_by_id(ldb->channel[1]->np, 1);
+ pixel_order =
+ drm_of_lvds_get_dual_link_pixel_order(port1, port2);
+ of_node_put(port1);
+ of_node_put(port2);
+
+ if (pixel_order == DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) {
+ dev_err(dev, "invalid dual link pixel order: %d\n", pixel_order);
+ return -EINVAL;
+ }
+
+ imx95_ldb->active_chno = 0;
+ imx95_ldb_ch = imx95_ldb->channel[0];
+ ldb_ch = &imx95_ldb_ch->base;
+ ldb_ch->link_type = pixel_order;
+ } else {
+ for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
+ imx95_ldb_ch = imx95_ldb->channel[i];
+ ldb_ch = &imx95_ldb_ch->base;
+
+ if (ldb_ch->is_available) {
+ imx95_ldb->active_chno = ldb_ch->chno;
+ break;
+ }
+ }
+ ldb_ch->link_type = LDB_CH_SINGLE_LINK;
+ }
+
+ ret = ldb_find_next_bridge_helper(ldb);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, imx95_ldb);
+ pm_runtime_enable(dev);
+
+ ldb_add_bridge_helper(ldb);
+
+ return ret;
+}
+
+static void imx95_ldb_remove(struct platform_device *pdev)
+{
+ struct imx95_ldb *imx95_ldb = platform_get_drvdata(pdev);
+ struct ldb *ldb = &imx95_ldb->base;
+
+ ldb_remove_bridge_helper(ldb);
+
+ pm_runtime_disable(&pdev->dev);
+}
+
+static int __maybe_unused imx95_ldb_runtime_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int __maybe_unused imx95_ldb_runtime_resume(struct device *dev)
+{
+ struct imx95_ldb *imx95_ldb = dev_get_drvdata(dev);
+ struct ldb *ldb = &imx95_ldb->base;
+
+ /* disable LDB by resetting the control register to POR default */
+ regmap_write(ldb->regmap, ldb->ctrl_reg, 0);
+
+ return 0;
+}
+
+static const struct dev_pm_ops imx95_ldb_pm_ops = {
+ SET_RUNTIME_PM_OPS(imx95_ldb_runtime_suspend,
+ imx95_ldb_runtime_resume, NULL)
+};
+
+static const struct of_device_id imx95_ldb_dt_ids[] = {
+ { .compatible = "fsl,imx95-lvds" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx95_ldb_dt_ids);
+
+static struct platform_driver imx95_ldb_driver = {
+ .probe = imx95_ldb_probe,
+ .remove = imx95_ldb_remove,
+ .driver = {
+ .pm = &imx95_ldb_pm_ops,
+ .name = DRIVER_NAME,
+ .of_match_table = imx95_ldb_dt_ids,
+ },
+};
+module_platform_driver(imx95_ldb_driver);
+
+MODULE_DESCRIPTION("i.MX95 LVDS Display Bridge(LDB) bridge driver");
+MODULE_AUTHOR("Sandor Yu <Sandor.yu@nxp.com>");
+MODULE_LICENSE("GPL");
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* [PATCH 34/39] dt-bindings: display: bridge: ldb: Add an i.MX95 entry
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (32 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 33/39] drm: bridge: imx: Add i.MX95 LVDS Display Bridge (LDB) driver Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 11:34 ` Rob Herring (Arm)
2025-10-11 16:51 ` [PATCH 35/39] drm/bridge: fsl-ldb: Parse register offsets from DT Marek Vasut
` (6 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
i.MX95 has twice a single LVDS port and share a similar LDB_CTRL register
layout with i.MX8MP and i.MX93. Unlike the other SoCs, i.MX95 does have a
mapping bridge in front of this LDB PHY.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml
index 07388bf2b90df..9564360d4bbb8 100644
--- a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml
@@ -20,6 +20,7 @@ properties:
- fsl,imx6sx-ldb
- fsl,imx8mp-ldb
- fsl,imx93-ldb
+ - fsl,imx95-ldb
clocks:
maxItems: 1
@@ -68,6 +69,7 @@ allOf:
enum:
- fsl,imx6sx-ldb
- fsl,imx93-ldb
+ - fsl,imx95-ldb
then:
properties:
ports:
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 34/39] dt-bindings: display: bridge: ldb: Add an i.MX95 entry
2025-10-11 16:51 ` [PATCH 34/39] dt-bindings: display: bridge: ldb: Add an i.MX95 entry Marek Vasut
@ 2025-10-13 11:34 ` Rob Herring (Arm)
0 siblings, 0 replies; 113+ messages in thread
From: Rob Herring (Arm) @ 2025-10-13 11:34 UTC (permalink / raw)
To: Marek Vasut
Cc: Laurent Pinchart, imx, Fabio Estevam, Abel Vesa,
Krzysztof Kozlowski, Pengutronix Kernel Team, Liu Ying,
linux-arm-kernel, dri-devel, Lucas Stach, Peng Fan, Shawn Guo,
Conor Dooley, devicetree, Thomas Zimmermann, linux-clk
On Sat, 11 Oct 2025 18:51:49 +0200, Marek Vasut wrote:
> i.MX95 has twice a single LVDS port and share a similar LDB_CTRL register
> layout with i.MX8MP and i.MX93. Unlike the other SoCs, i.MX95 does have a
> mapping bridge in front of this LDB PHY.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.example.dtb: ldb (fsl,imx95-ldb): '#address-cells', '#size-cells', 'channel@0', 'channel@1', 'power-domains' do not match any of the regexes: '^pinctrl-[0-9]+$'
from schema $id: http://devicetree.org/schemas/display/bridge/fsl,ldb.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.example.dtb: ldb (fsl,imx95-ldb): clock-names:0: 'ldb' was expected
from schema $id: http://devicetree.org/schemas/display/bridge/fsl,ldb.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.example.dtb: ldb (fsl,imx95-ldb): clock-names: ['pixel', 'bypass'] is too long
from schema $id: http://devicetree.org/schemas/display/bridge/fsl,ldb.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.example.dtb: ldb (fsl,imx95-ldb): clocks: [[4294967295, 266, 2], [4294967295, 266, 4]] is too long
from schema $id: http://devicetree.org/schemas/display/bridge/fsl,ldb.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.example.dtb: ldb (fsl,imx95-ldb): 'ports' is a required property
from schema $id: http://devicetree.org/schemas/display/bridge/fsl,ldb.yaml#
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20251011170213.128907-35-marek.vasut@mailbox.org
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 35/39] drm/bridge: fsl-ldb: Parse register offsets from DT
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (33 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 34/39] dt-bindings: display: bridge: ldb: Add an i.MX95 entry Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:23 ` Frank Li
2025-10-11 16:51 ` [PATCH 36/39] drm/bridge: fsl-ldb: Add i.MX95 support Marek Vasut
` (5 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
The DT binding for this bridge describe register offsets for the LDB,
parse the register offsets from DT instead of hard-coding them in the
driver. No functional change.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/bridge/fsl-ldb.c | 42 ++++++++++++++++++++------------
1 file changed, 26 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/bridge/fsl-ldb.c b/drivers/gpu/drm/bridge/fsl-ldb.c
index 5c3cf37200bce..c54caea0b63fc 100644
--- a/drivers/gpu/drm/bridge/fsl-ldb.c
+++ b/drivers/gpu/drm/bridge/fsl-ldb.c
@@ -61,24 +61,16 @@ enum fsl_ldb_devtype {
};
struct fsl_ldb_devdata {
- u32 ldb_ctrl;
- u32 lvds_ctrl;
bool lvds_en_bit;
bool single_ctrl_reg;
};
static const struct fsl_ldb_devdata fsl_ldb_devdata[] = {
[IMX6SX_LDB] = {
- .ldb_ctrl = 0x18,
.single_ctrl_reg = true,
},
- [IMX8MP_LDB] = {
- .ldb_ctrl = 0x5c,
- .lvds_ctrl = 0x128,
- },
+ [IMX8MP_LDB] = { },
[IMX93_LDB] = {
- .ldb_ctrl = 0x20,
- .lvds_ctrl = 0x24,
.lvds_en_bit = true,
},
};
@@ -90,6 +82,8 @@ struct fsl_ldb {
struct clk *clk;
struct regmap *regmap;
const struct fsl_ldb_devdata *devdata;
+ u32 ldb_ctrl;
+ u32 lvds_ctrl;
bool ch0_enabled;
bool ch1_enabled;
};
@@ -204,7 +198,7 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
reg |= (fsl_ldb->ch0_enabled ? LDB_CTRL_DI0_VSYNC_POLARITY : 0) |
(fsl_ldb->ch1_enabled ? LDB_CTRL_DI1_VSYNC_POLARITY : 0);
- regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, reg);
+ regmap_write(fsl_ldb->regmap, fsl_ldb->ldb_ctrl, reg);
if (fsl_ldb->devdata->single_ctrl_reg)
return;
@@ -212,7 +206,7 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
/* Program LVDS_CTRL */
reg = LVDS_CTRL_CC_ADJ(2) | LVDS_CTRL_PRE_EMPH_EN |
LVDS_CTRL_PRE_EMPH_ADJ(3) | LVDS_CTRL_VBG_EN;
- regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, reg);
+ regmap_write(fsl_ldb->regmap, fsl_ldb->lvds_ctrl, reg);
/* Wait for VBG to stabilize. */
usleep_range(15, 20);
@@ -220,7 +214,7 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
reg |= (fsl_ldb->ch0_enabled ? LVDS_CTRL_CH0_EN : 0) |
(fsl_ldb->ch1_enabled ? LVDS_CTRL_CH1_EN : 0);
- regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, reg);
+ regmap_write(fsl_ldb->regmap, fsl_ldb->lvds_ctrl, reg);
}
static void fsl_ldb_atomic_disable(struct drm_bridge *bridge,
@@ -231,12 +225,12 @@ static void fsl_ldb_atomic_disable(struct drm_bridge *bridge,
/* Stop channel(s). */
if (fsl_ldb->devdata->lvds_en_bit)
/* Set LVDS_CTRL_LVDS_EN bit to disable. */
- regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl,
+ regmap_write(fsl_ldb->regmap, fsl_ldb->lvds_ctrl,
LVDS_CTRL_LVDS_EN);
else
if (!fsl_ldb->devdata->single_ctrl_reg)
- regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0);
- regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, 0);
+ regmap_write(fsl_ldb->regmap, fsl_ldb->lvds_ctrl, 0);
+ regmap_write(fsl_ldb->regmap, fsl_ldb->ldb_ctrl, 0);
clk_disable_unprepare(fsl_ldb->clk);
}
@@ -296,7 +290,7 @@ static int fsl_ldb_probe(struct platform_device *pdev)
struct device_node *remote1, *remote2;
struct drm_panel *panel;
struct fsl_ldb *fsl_ldb;
- int dual_link;
+ int dual_link, idx, ret;
fsl_ldb = devm_drm_bridge_alloc(dev, struct fsl_ldb, bridge, &funcs);
if (IS_ERR(fsl_ldb))
@@ -309,6 +303,22 @@ static int fsl_ldb_probe(struct platform_device *pdev)
fsl_ldb->dev = &pdev->dev;
fsl_ldb->bridge.of_node = dev->of_node;
+ idx = of_property_match_string(dev->of_node, "reg-names", "ldb");
+ if (idx < 0)
+ return idx;
+
+ ret = of_property_read_u32_index(dev->of_node, "reg", 2 * idx, &fsl_ldb->ldb_ctrl);
+ if (ret)
+ return ret;
+
+ idx = of_property_match_string(dev->of_node, "reg-names", "lvds");
+ if (idx < 0)
+ return idx;
+
+ ret = of_property_read_u32_index(dev->of_node, "reg", 2 * idx, &fsl_ldb->lvds_ctrl);
+ if (ret)
+ return ret;
+
fsl_ldb->clk = devm_clk_get(dev, "ldb");
if (IS_ERR(fsl_ldb->clk))
return PTR_ERR(fsl_ldb->clk);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 35/39] drm/bridge: fsl-ldb: Parse register offsets from DT
2025-10-11 16:51 ` [PATCH 35/39] drm/bridge: fsl-ldb: Parse register offsets from DT Marek Vasut
@ 2025-10-13 19:23 ` Frank Li
2025-10-17 15:39 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:23 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:50PM +0200, Marek Vasut wrote:
> The DT binding for this bridge describe register offsets for the LDB,
> parse the register offsets from DT instead of hard-coding them in the
> driver. No functional change.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/bridge/fsl-ldb.c | 42 ++++++++++++++++++++------------
> 1 file changed, 26 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/fsl-ldb.c b/drivers/gpu/drm/bridge/fsl-ldb.c
> index 5c3cf37200bce..c54caea0b63fc 100644
> --- a/drivers/gpu/drm/bridge/fsl-ldb.c
> +++ b/drivers/gpu/drm/bridge/fsl-ldb.c
> @@ -61,24 +61,16 @@ enum fsl_ldb_devtype {
> };
>
> struct fsl_ldb_devdata {
> - u32 ldb_ctrl;
> - u32 lvds_ctrl;
> bool lvds_en_bit;
> bool single_ctrl_reg;
> };
>
> static const struct fsl_ldb_devdata fsl_ldb_devdata[] = {
> [IMX6SX_LDB] = {
> - .ldb_ctrl = 0x18,
> .single_ctrl_reg = true,
> },
> - [IMX8MP_LDB] = {
> - .ldb_ctrl = 0x5c,
> - .lvds_ctrl = 0x128,
> - },
> + [IMX8MP_LDB] = { },
> [IMX93_LDB] = {
> - .ldb_ctrl = 0x20,
> - .lvds_ctrl = 0x24,
> .lvds_en_bit = true,
> },
> };
> @@ -90,6 +82,8 @@ struct fsl_ldb {
> struct clk *clk;
> struct regmap *regmap;
> const struct fsl_ldb_devdata *devdata;
> + u32 ldb_ctrl;
> + u32 lvds_ctrl;
> bool ch0_enabled;
> bool ch1_enabled;
> };
> @@ -204,7 +198,7 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
> reg |= (fsl_ldb->ch0_enabled ? LDB_CTRL_DI0_VSYNC_POLARITY : 0) |
> (fsl_ldb->ch1_enabled ? LDB_CTRL_DI1_VSYNC_POLARITY : 0);
>
> - regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, reg);
> + regmap_write(fsl_ldb->regmap, fsl_ldb->ldb_ctrl, reg);
>
> if (fsl_ldb->devdata->single_ctrl_reg)
> return;
> @@ -212,7 +206,7 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
> /* Program LVDS_CTRL */
> reg = LVDS_CTRL_CC_ADJ(2) | LVDS_CTRL_PRE_EMPH_EN |
> LVDS_CTRL_PRE_EMPH_ADJ(3) | LVDS_CTRL_VBG_EN;
> - regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, reg);
> + regmap_write(fsl_ldb->regmap, fsl_ldb->lvds_ctrl, reg);
>
> /* Wait for VBG to stabilize. */
> usleep_range(15, 20);
> @@ -220,7 +214,7 @@ static void fsl_ldb_atomic_enable(struct drm_bridge *bridge,
> reg |= (fsl_ldb->ch0_enabled ? LVDS_CTRL_CH0_EN : 0) |
> (fsl_ldb->ch1_enabled ? LVDS_CTRL_CH1_EN : 0);
>
> - regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, reg);
> + regmap_write(fsl_ldb->regmap, fsl_ldb->lvds_ctrl, reg);
> }
>
> static void fsl_ldb_atomic_disable(struct drm_bridge *bridge,
> @@ -231,12 +225,12 @@ static void fsl_ldb_atomic_disable(struct drm_bridge *bridge,
> /* Stop channel(s). */
> if (fsl_ldb->devdata->lvds_en_bit)
> /* Set LVDS_CTRL_LVDS_EN bit to disable. */
> - regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl,
> + regmap_write(fsl_ldb->regmap, fsl_ldb->lvds_ctrl,
> LVDS_CTRL_LVDS_EN);
> else
> if (!fsl_ldb->devdata->single_ctrl_reg)
> - regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0);
> - regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, 0);
> + regmap_write(fsl_ldb->regmap, fsl_ldb->lvds_ctrl, 0);
> + regmap_write(fsl_ldb->regmap, fsl_ldb->ldb_ctrl, 0);
>
> clk_disable_unprepare(fsl_ldb->clk);
> }
> @@ -296,7 +290,7 @@ static int fsl_ldb_probe(struct platform_device *pdev)
> struct device_node *remote1, *remote2;
> struct drm_panel *panel;
> struct fsl_ldb *fsl_ldb;
> - int dual_link;
> + int dual_link, idx, ret;
>
> fsl_ldb = devm_drm_bridge_alloc(dev, struct fsl_ldb, bridge, &funcs);
> if (IS_ERR(fsl_ldb))
> @@ -309,6 +303,22 @@ static int fsl_ldb_probe(struct platform_device *pdev)
> fsl_ldb->dev = &pdev->dev;
> fsl_ldb->bridge.of_node = dev->of_node;
>
> + idx = of_property_match_string(dev->of_node, "reg-names", "ldb");
> + if (idx < 0)
> + return idx;
Does this broken compatiblity? If yes, need mention at commit message
Frank
> +
> + ret = of_property_read_u32_index(dev->of_node, "reg", 2 * idx, &fsl_ldb->ldb_ctrl);
> + if (ret)
> + return ret;
> +
> + idx = of_property_match_string(dev->of_node, "reg-names", "lvds");
> + if (idx < 0)
> + return idx;
> +
> + ret = of_property_read_u32_index(dev->of_node, "reg", 2 * idx, &fsl_ldb->lvds_ctrl);
> + if (ret)
> + return ret;
> +
> fsl_ldb->clk = devm_clk_get(dev, "ldb");
> if (IS_ERR(fsl_ldb->clk))
> return PTR_ERR(fsl_ldb->clk);
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 35/39] drm/bridge: fsl-ldb: Parse register offsets from DT
2025-10-13 19:23 ` Frank Li
@ 2025-10-17 15:39 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:39 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 9:23 PM, Frank Li wrote:
Hello Frank,
>> @@ -296,7 +290,7 @@ static int fsl_ldb_probe(struct platform_device *pdev)
>> struct device_node *remote1, *remote2;
>> struct drm_panel *panel;
>> struct fsl_ldb *fsl_ldb;
>> - int dual_link;
>> + int dual_link, idx, ret;
>>
>> fsl_ldb = devm_drm_bridge_alloc(dev, struct fsl_ldb, bridge, &funcs);
>> if (IS_ERR(fsl_ldb))
>> @@ -309,6 +303,22 @@ static int fsl_ldb_probe(struct platform_device *pdev)
>> fsl_ldb->dev = &pdev->dev;
>> fsl_ldb->bridge.of_node = dev->of_node;
>>
>> + idx = of_property_match_string(dev->of_node, "reg-names", "ldb");
>> + if (idx < 0)
>> + return idx;
>
> Does this broken compatiblity? If yes, need mention at commit message
Nope, it actually does not, because the binding document used for
validation was correct and required these entries. So we can now safely
parse them.
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 36/39] drm/bridge: fsl-ldb: Add i.MX95 support
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (34 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 35/39] drm/bridge: fsl-ldb: Parse register offsets from DT Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:24 ` Frank Li
2025-10-11 16:51 ` [PATCH 37/39] dt-bindings: interrupt-controller: fsl,irqsteer: " Marek Vasut
` (4 subsequent siblings)
40 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Add support for i.MX95 SoC variant of the LDB. This variant supports
single channel and all configuration is done via single register,
but there are two instances of this IP preceded by another bridge,
which handles the dual-lane configuration instead. This is also the
reason for special-case handling of input format, where the preceding
bridge needs the format details as well.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
drivers/gpu/drm/bridge/fsl-ldb.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/fsl-ldb.c b/drivers/gpu/drm/bridge/fsl-ldb.c
index c54caea0b63fc..1560438e4cb10 100644
--- a/drivers/gpu/drm/bridge/fsl-ldb.c
+++ b/drivers/gpu/drm/bridge/fsl-ldb.c
@@ -58,6 +58,7 @@ enum fsl_ldb_devtype {
IMX6SX_LDB,
IMX8MP_LDB,
IMX93_LDB,
+ IMX95_LDB,
};
struct fsl_ldb_devdata {
@@ -73,6 +74,9 @@ static const struct fsl_ldb_devdata fsl_ldb_devdata[] = {
[IMX93_LDB] = {
.lvds_en_bit = true,
},
+ [IMX95_LDB] = {
+ .lvds_en_bit = true,
+ },
};
struct fsl_ldb {
@@ -235,7 +239,7 @@ static void fsl_ldb_atomic_disable(struct drm_bridge *bridge,
clk_disable_unprepare(fsl_ldb->clk);
}
-#define MAX_INPUT_SEL_FORMATS 1
+#define MAX_INPUT_SEL_FORMATS 4
static u32 *
fsl_ldb_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
@@ -244,17 +248,26 @@ fsl_ldb_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
u32 output_fmt,
unsigned int *num_input_fmts)
{
+ struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
u32 *input_fmts;
*num_input_fmts = 0;
- input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
+ input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, MAX_INPUT_SEL_FORMATS * sizeof(*input_fmts),
GFP_KERNEL);
if (!input_fmts)
return NULL;
- input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
- *num_input_fmts = MAX_INPUT_SEL_FORMATS;
+ if (of_device_is_compatible(fsl_ldb->dev->of_node, "fsl,imx95-ldb")) {
+ input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
+ input_fmts[1] = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
+ input_fmts[2] = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
+ input_fmts[3] = MEDIA_BUS_FMT_FIXED;
+ *num_input_fmts = 4;
+ } else {
+ input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
+ *num_input_fmts = 1;
+ }
return input_fmts;
}
@@ -396,6 +409,8 @@ static const struct of_device_id fsl_ldb_match[] = {
.data = &fsl_ldb_devdata[IMX8MP_LDB], },
{ .compatible = "fsl,imx93-ldb",
.data = &fsl_ldb_devdata[IMX93_LDB], },
+ { .compatible = "fsl,imx95-ldb",
+ .data = &fsl_ldb_devdata[IMX95_LDB], },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, fsl_ldb_match);
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 36/39] drm/bridge: fsl-ldb: Add i.MX95 support
2025-10-11 16:51 ` [PATCH 36/39] drm/bridge: fsl-ldb: Add i.MX95 support Marek Vasut
@ 2025-10-13 19:24 ` Frank Li
0 siblings, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:24 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:51PM +0200, Marek Vasut wrote:
> Add support for i.MX95 SoC variant of the LDB. This variant supports
> single channel and all configuration is done via single register,
> but there are two instances of this IP preceded by another bridge,
> which handles the dual-lane configuration instead. This is also the
> reason for special-case handling of input format, where the preceding
> bridge needs the format details as well.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> drivers/gpu/drm/bridge/fsl-ldb.c | 23 +++++++++++++++++++----
> 1 file changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/fsl-ldb.c b/drivers/gpu/drm/bridge/fsl-ldb.c
> index c54caea0b63fc..1560438e4cb10 100644
> --- a/drivers/gpu/drm/bridge/fsl-ldb.c
> +++ b/drivers/gpu/drm/bridge/fsl-ldb.c
> @@ -58,6 +58,7 @@ enum fsl_ldb_devtype {
> IMX6SX_LDB,
> IMX8MP_LDB,
> IMX93_LDB,
> + IMX95_LDB,
> };
>
> struct fsl_ldb_devdata {
> @@ -73,6 +74,9 @@ static const struct fsl_ldb_devdata fsl_ldb_devdata[] = {
> [IMX93_LDB] = {
> .lvds_en_bit = true,
> },
> + [IMX95_LDB] = {
> + .lvds_en_bit = true,
> + },
> };
>
> struct fsl_ldb {
> @@ -235,7 +239,7 @@ static void fsl_ldb_atomic_disable(struct drm_bridge *bridge,
> clk_disable_unprepare(fsl_ldb->clk);
> }
>
> -#define MAX_INPUT_SEL_FORMATS 1
> +#define MAX_INPUT_SEL_FORMATS 4
> static u32 *
> fsl_ldb_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
> struct drm_bridge_state *bridge_state,
> @@ -244,17 +248,26 @@ fsl_ldb_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
> u32 output_fmt,
> unsigned int *num_input_fmts)
> {
> + struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
> u32 *input_fmts;
>
> *num_input_fmts = 0;
>
> - input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
> + input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, MAX_INPUT_SEL_FORMATS * sizeof(*input_fmts),
> GFP_KERNEL);
> if (!input_fmts)
> return NULL;
>
> - input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
> - *num_input_fmts = MAX_INPUT_SEL_FORMATS;
> + if (of_device_is_compatible(fsl_ldb->dev->of_node, "fsl,imx95-ldb")) {
You already use drv data, why need check fsl,imx95-ldb here. put below
data into drv data.
Frank
> + input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
> + input_fmts[1] = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
> + input_fmts[2] = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
> + input_fmts[3] = MEDIA_BUS_FMT_FIXED;
> + *num_input_fmts = 4;
> + } else {
> + input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
> + *num_input_fmts = 1;
> + }
>
> return input_fmts;
> }
> @@ -396,6 +409,8 @@ static const struct of_device_id fsl_ldb_match[] = {
> .data = &fsl_ldb_devdata[IMX8MP_LDB], },
> { .compatible = "fsl,imx93-ldb",
> .data = &fsl_ldb_devdata[IMX93_LDB], },
> + { .compatible = "fsl,imx95-ldb",
> + .data = &fsl_ldb_devdata[IMX95_LDB], },
> { /* sentinel */ },
> };
> MODULE_DEVICE_TABLE(of, fsl_ldb_match);
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 37/39] dt-bindings: interrupt-controller: fsl,irqsteer: Add i.MX95 support
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (35 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 36/39] drm/bridge: fsl-ldb: Add i.MX95 support Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:25 ` Frank Li
2025-10-15 13:31 ` Rob Herring (Arm)
2025-10-11 16:51 ` [PATCH 38/39] dt-bindings: clock: support i.MX95 Display Stream CSR module Marek Vasut
` (3 subsequent siblings)
40 siblings, 2 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Add compatible string "fsl,imx95-irqsteer" for the i.MX95 chip, which is
backward compatible with "fsl,imx-irqsteer".
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
.../devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml
index c49688be10581..5c768c1e159c1 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml
@@ -20,6 +20,7 @@ properties:
- fsl,imx8qm-irqsteer
- fsl,imx8qxp-irqsteer
- fsl,imx94-irqsteer
+ - fsl,imx95-irqsteer
- const: fsl,imx-irqsteer
reg:
@@ -87,6 +88,7 @@ allOf:
- fsl,imx8mp-irqsteer
- fsl,imx8qm-irqsteer
- fsl,imx8qxp-irqsteer
+ - fsl,imx95-irqsteer
then:
required:
- power-domains
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 37/39] dt-bindings: interrupt-controller: fsl,irqsteer: Add i.MX95 support
2025-10-11 16:51 ` [PATCH 37/39] dt-bindings: interrupt-controller: fsl,irqsteer: " Marek Vasut
@ 2025-10-13 19:25 ` Frank Li
2025-10-15 13:31 ` Rob Herring (Arm)
1 sibling, 0 replies; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:25 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:52PM +0200, Marek Vasut wrote:
> Add compatible string "fsl,imx95-irqsteer" for the i.MX95 chip, which is
> backward compatible with "fsl,imx-irqsteer".
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml
> index c49688be10581..5c768c1e159c1 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml
> +++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml
> @@ -20,6 +20,7 @@ properties:
> - fsl,imx8qm-irqsteer
> - fsl,imx8qxp-irqsteer
> - fsl,imx94-irqsteer
> + - fsl,imx95-irqsteer
> - const: fsl,imx-irqsteer
>
> reg:
> @@ -87,6 +88,7 @@ allOf:
> - fsl,imx8mp-irqsteer
> - fsl,imx8qm-irqsteer
> - fsl,imx8qxp-irqsteer
> + - fsl,imx95-irqsteer
> then:
> required:
> - power-domains
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 37/39] dt-bindings: interrupt-controller: fsl,irqsteer: Add i.MX95 support
2025-10-11 16:51 ` [PATCH 37/39] dt-bindings: interrupt-controller: fsl,irqsteer: " Marek Vasut
2025-10-13 19:25 ` Frank Li
@ 2025-10-15 13:31 ` Rob Herring (Arm)
1 sibling, 0 replies; 113+ messages in thread
From: Rob Herring (Arm) @ 2025-10-15 13:31 UTC (permalink / raw)
To: Marek Vasut
Cc: Abel Vesa, Thomas Zimmermann, linux-arm-kernel, linux-clk,
Laurent Pinchart, Peng Fan, Pengutronix Kernel Team, devicetree,
imx, Liu Ying, Fabio Estevam, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo, Lucas Stach, dri-devel
On Sat, 11 Oct 2025 18:51:52 +0200, Marek Vasut wrote:
> Add compatible string "fsl,imx95-irqsteer" for the i.MX95 chip, which is
> backward compatible with "fsl,imx-irqsteer".
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
Applied, thanks!
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 38/39] dt-bindings: clock: support i.MX95 Display Stream CSR module
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (36 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 37/39] dt-bindings: interrupt-controller: fsl,irqsteer: " Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-13 19:26 ` Frank Li
2025-10-15 13:33 ` Rob Herring
2025-10-11 16:51 ` [PATCH 39/39] arm64: dts: imx95: Describe display pipeline Marek Vasut
` (2 subsequent siblings)
40 siblings, 2 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
i.MX95 DISPLAY STREAM_CSR includes registers to control DSI PHY settings.
Add dt-schema for it.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
.../imx/nxp,imx95-display-stream-csr.yaml | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
diff --git a/Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml b/Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
new file mode 100644
index 0000000000000..61153120c9378
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/nxp,imx95-display-stream-csr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX95 Display Stream Block Control
+
+maintainers:
+ - Marek Vasut <marek.vasut@mailbox.org>
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - nxp,imx95-display-stream-csr
+ - nxp,imx95-master-stream-csr
+ - nxp,imx95-mipi-tx-phy-csr
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ syscon@4ad00000 {
+ compatible = "nxp,imx95-display-stream-csr", "syscon";
+ reg = <0x4ad00000 0x10000>;
+ clocks = <&scmi_clk 62>;
+ };
+...
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 38/39] dt-bindings: clock: support i.MX95 Display Stream CSR module
2025-10-11 16:51 ` [PATCH 38/39] dt-bindings: clock: support i.MX95 Display Stream CSR module Marek Vasut
@ 2025-10-13 19:26 ` Frank Li
2025-10-17 15:05 ` Marek Vasut
2025-10-15 13:33 ` Rob Herring
1 sibling, 1 reply; 113+ messages in thread
From: Frank Li @ 2025-10-13 19:26 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:53PM +0200, Marek Vasut wrote:
> i.MX95 DISPLAY STREAM_CSR includes registers to control DSI PHY settings.
> Add dt-schema for it.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../imx/nxp,imx95-display-stream-csr.yaml | 41 +++++++++++++++++++
> 1 file changed, 41 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml b/Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
> new file mode 100644
> index 0000000000000..61153120c9378
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
> @@ -0,0 +1,41 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/imx/nxp,imx95-display-stream-csr.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP i.MX95 Display Stream Block Control
> +
> +maintainers:
> + - Marek Vasut <marek.vasut@mailbox.org>
> +
> +properties:
> + compatible:
> + items:
> + - enum:
> + - nxp,imx95-display-stream-csr
> + - nxp,imx95-master-stream-csr
> + - nxp,imx95-mipi-tx-phy-csr
> + - const: syscon
why need syscon here? why not use standard phy interface.
Frank
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + syscon@4ad00000 {
> + compatible = "nxp,imx95-display-stream-csr", "syscon";
> + reg = <0x4ad00000 0x10000>;
> + clocks = <&scmi_clk 62>;
> + };
> +...
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 38/39] dt-bindings: clock: support i.MX95 Display Stream CSR module
2025-10-13 19:26 ` Frank Li
@ 2025-10-17 15:05 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:05 UTC (permalink / raw)
To: Frank Li
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
On 10/13/25 9:26 PM, Frank Li wrote:
Hello Frank,
>> +properties:
>> + compatible:
>> + items:
>> + - enum:
>> + - nxp,imx95-display-stream-csr
>> + - nxp,imx95-master-stream-csr
>> + - nxp,imx95-mipi-tx-phy-csr
>> + - const: syscon
>
> why need syscon here? why not use standard phy interface.
Those registers are not PHYs, they are aux control registers for this block.
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 38/39] dt-bindings: clock: support i.MX95 Display Stream CSR module
2025-10-11 16:51 ` [PATCH 38/39] dt-bindings: clock: support i.MX95 Display Stream CSR module Marek Vasut
2025-10-13 19:26 ` Frank Li
@ 2025-10-15 13:33 ` Rob Herring
2025-10-17 15:08 ` Marek Vasut
1 sibling, 1 reply; 113+ messages in thread
From: Rob Herring @ 2025-10-15 13:33 UTC (permalink / raw)
To: Marek Vasut
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Shawn Guo, Thomas Zimmermann,
devicetree, imx, linux-arm-kernel, linux-clk
On Sat, Oct 11, 2025 at 06:51:53PM +0200, Marek Vasut wrote:
> i.MX95 DISPLAY STREAM_CSR includes registers to control DSI PHY settings.
> Add dt-schema for it.
>
> Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
> ---
> .../imx/nxp,imx95-display-stream-csr.yaml | 41 +++++++++++++++++++
> 1 file changed, 41 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml b/Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
> new file mode 100644
> index 0000000000000..61153120c9378
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
> @@ -0,0 +1,41 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/imx/nxp,imx95-display-stream-csr.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP i.MX95 Display Stream Block Control
> +
> +maintainers:
> + - Marek Vasut <marek.vasut@mailbox.org>
> +
> +properties:
> + compatible:
> + items:
> + - enum:
> + - nxp,imx95-display-stream-csr
> + - nxp,imx95-master-stream-csr
> + - nxp,imx95-mipi-tx-phy-csr
'-csr' seems redundant.
> + - const: syscon
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 38/39] dt-bindings: clock: support i.MX95 Display Stream CSR module
2025-10-15 13:33 ` Rob Herring
@ 2025-10-17 15:08 ` Marek Vasut
0 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:08 UTC (permalink / raw)
To: Rob Herring
Cc: dri-devel, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Shawn Guo, Thomas Zimmermann,
devicetree, imx, linux-arm-kernel, linux-clk
On 10/15/25 3:33 PM, Rob Herring wrote:
Hello Rob,
>> +properties:
>> + compatible:
>> + items:
>> + - enum:
>> + - nxp,imx95-display-stream-csr
>> + - nxp,imx95-master-stream-csr
>> + - nxp,imx95-mipi-tx-phy-csr
>
> '-csr' seems redundant.
It follows the existing naming scheme on iMX95:
Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml:
- nxp,imx95-camera-csr
Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml:
- nxp,imx95-display-csr
Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml:
- nxp,imx95-lvds-csr
Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml:
- nxp,imx95-vpu-csr
Documentation/devicetree/bindings/clock/nxp,imx95-display-master-csr.yaml:
compatible = "nxp,imx95-display-master-csr", "syscon";
Shall I adjust that ?
^ permalink raw reply [flat|nested] 113+ messages in thread
* [PATCH 39/39] arm64: dts: imx95: Describe display pipeline
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (37 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 38/39] dt-bindings: clock: support i.MX95 Display Stream CSR module Marek Vasut
@ 2025-10-11 16:51 ` Marek Vasut
2025-10-14 8:51 ` [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Liu Ying
2025-10-14 9:13 ` Liu Ying
40 siblings, 0 replies; 113+ messages in thread
From: Marek Vasut @ 2025-10-11 16:51 UTC (permalink / raw)
To: dri-devel
Cc: Marek Vasut, Abel Vesa, Conor Dooley, Fabio Estevam,
Krzysztof Kozlowski, Laurent Pinchart, Liu Ying, Lucas Stach,
Peng Fan, Pengutronix Kernel Team, Rob Herring, Shawn Guo,
Thomas Zimmermann, devicetree, imx, linux-arm-kernel, linux-clk
Describe the entire i.MX95 display pipeline, which includes the DPU or DC
display controller, MIPI DSI serializer, LVDS serializer and the bridges
between those components.
Signed-off-by: Marek Vasut <marek.vasut@mailbox.org>
---
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Liu Ying <victor.liu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-clk@vger.kernel.org
---
arch/arm64/boot/dts/freescale/imx95.dtsi | 710 +++++++++++++++++++++++
1 file changed, 710 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index ad47b7f0d173a..e26942ab0b28b 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -19,6 +19,87 @@ / {
#address-cells = <2>;
#size-cells = <2>;
+ ldb_pll_pixel: ldb_pll_div7 {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&scmi_clk IMX95_CLK_LDBPLL>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ clock-output-names = "ldb_pll_div7";
+ };
+
+ display_pixel_link_0: pixel-link-0 {
+ compatible = "fsl,imx95-dc-pixel-link";
+ fsl,dc-stream-id = /bits/ 8 <0>;
+ fsl,syscon = <&dispmix_csr>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ display_pixel_link0_to_pixel_interleaver_disp0: endpoint {
+ remote-endpoint = <&pixel_interleaver_disp0_to_display_pixel_link0>;
+ };
+ };
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ display_pixel_link0_to_mipi_dsi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&mipi_dsi_to_display_pixel_link0>;
+ };
+
+ display_pixel_link0_to_lvds_ch0: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&lvds_ch0_to_display_pixel_link0>;
+ };
+ };
+ };
+ };
+
+ display_pixel_link_1: pixel-link-1 {
+ compatible = "fsl,imx95-dc-pixel-link";
+ fsl,dc-stream-id = /bits/ 8 <1>;
+ fsl,syscon = <&dispmix_csr>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ display_pixel_link1_to_pixel_interleaver_disp1: endpoint {
+ remote-endpoint = <&pixel_interleaver_disp1_to_display_pixel_link1>;
+ };
+ };
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ display_pixel_link1_to_mipi_dsi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&mipi_dsi_to_display_pixel_link1>;
+ };
+
+ display_pixel_link1_to_lvds_ch1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&lvds_ch1_to_display_pixel_link1>;
+ };
+ };
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -1772,6 +1853,635 @@ smmu: iommu@490d0000 {
};
};
+ mipi_dsi: dsi@4acf0000 {
+ compatible = "fsl,imx95-mipi-dsi";
+ reg = <0x0 0x4acf0000 0x0 0x10000>;
+ interrupt-parent = <&displaymix_irqsteer>;
+ interrupts = <48>;
+ clocks = <&scmi_clk IMX95_CLK_CAMAPB>,
+ <&scmi_clk IMX95_CLK_DISP1PIX>,
+ <&scmi_clk IMX95_CLK_MIPIPHYCFG>,
+ <&scmi_clk IMX95_CLK_MIPIPHYPLLREF>;
+ clock-names = "pclk", "pix", "phy_cfg", "phy_ref";
+ assigned-clocks = <&scmi_clk IMX95_CLK_MIPIPHYCFG>,
+ <&scmi_clk IMX95_CLK_MIPIPHYPLLBYPASS>,
+ <&scmi_clk IMX95_CLK_MIPIPHYPLLREF>;
+ assigned-clock-parents = <&scmi_clk IMX95_CLK_24M>,
+ <&scmi_clk IMX95_CLK_VIDEOPLL1>,
+ <&scmi_clk IMX95_CLK_24M>;
+ power-domains = <&scmi_devpd IMX95_PD_CAMERA>;
+ fsl,disp-master-csr = <&display_master_csr>;
+ fsl,disp-stream-csr = <&display_stream_csr>;
+ fsl,mipi-combo-phy-csr = <&mipi_tx_phy_csr>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ mipi_dsi_to_display_pixel_link0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&display_pixel_link0_to_mipi_dsi>;
+ };
+
+ mipi_dsi_to_display_pixel_link1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&display_pixel_link1_to_mipi_dsi>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ display_stream_csr: syscon@4ad00000 {
+ compatible = "nxp,imx95-display-stream-csr", "syscon";
+ reg = <0x0 0x4ad00000 0x0 0x10000>;
+ clocks = <&scmi_clk IMX95_CLK_CAMAPB>;
+ };
+
+ display_master_csr: syscon@4ad10000 {
+ compatible = "nxp,imx95-master-stream-csr", "syscon";
+ reg = <0x0 0x4ad10000 0x0 0x10000>;
+ clocks = <&scmi_clk IMX95_CLK_CAMAPB>;
+ };
+
+ mipi_tx_phy_csr: syscon@4ad20100 {
+ compatible = "nxp,imx95-mipi-tx-phy-csr", "syscon";
+ reg = <0x0 0x4ad20100 0x0 0x14>;
+ clocks = <&scmi_clk IMX95_CLK_CAMAPB>;
+ };
+
+ dispmix_csr: syscon@4b010000 {
+ compatible = "nxp,imx95-display-csr", "syscon";
+ reg = <0x0 0x4b010000 0x0 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&scmi_clk IMX95_CLK_DISPAPB>;
+ power-domains = <&scmi_devpd IMX95_PD_DISPLAY>;
+ };
+
+ displaymix_irqsteer: interrupt-controller@4b0b0000 {
+ compatible = "fsl,imx95-irqsteer", "fsl,imx-irqsteer";
+ reg = <0x0 0x4b0b0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>, /* reserved */
+ <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>, /* reserved */
+ <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&scmi_devpd IMX95_PD_DISPLAY>;
+ clocks = <&scmi_clk IMX95_CLK_DISPAPB>;
+ clock-names = "ipg";
+ fsl,channel = <0>;
+ fsl,num-irqs = <512>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ status = "disabled";
+ };
+
+ lvds_csr: syscon@4b0c0000 {
+ compatible = "nxp,imx95-lvds-csr", "syscon";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x0 0x4b0c0000 0x0 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&scmi_clk IMX95_CLK_DISPAPB>;
+ power-domains = <&scmi_devpd IMX95_PD_DISPLAY>;
+
+ lvds: lvds@4 {
+ compatible = "fsl,imx95-lvds";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4 0x4>;
+ clocks = <&lvds_csr IMX95_CLK_DISPMIX_PIX_DI0_GATE>,
+ <&lvds_csr IMX95_CLK_DISPMIX_PIX_DI1_GATE>,
+ <&lvds_csr IMX95_CLK_DISPMIX_LVDS_CH0_GATE>,
+ <&lvds_csr IMX95_CLK_DISPMIX_LVDS_CH1_GATE>;
+ clock-names = "ldb_di0", "ldb_di1", "ldb_ch0", "ldb_ch1";
+ status = "disabled";
+
+ lvds_ch0: channel@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ lvds_ch0_to_display_pixel_link0: endpoint {
+ remote-endpoint = <&display_pixel_link0_to_lvds_ch0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lvds_ch0_to_ldb0: endpoint {
+ remote-endpoint = <&ldb0_to_lvds_ch0>;
+ };
+ };
+ };
+
+ lvds_ch1: channel@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ lvds_ch1_to_display_pixel_link1: endpoint {
+ remote-endpoint = <&display_pixel_link1_to_lvds_ch1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ lvds_ch1_to_ldb1: endpoint {
+ remote-endpoint = <&ldb1_to_lvds_ch1>;
+ };
+ };
+ };
+ };
+
+ ldb0: phy@8 {
+ compatible = "fsl,imx95-ldb";
+ reg = <0x8 0x4>, <0x8 0x4>;
+ reg-names = "ldb", "lvds";
+ clocks = <&scmi_clk IMX95_CLK_DISPAPB>;
+ clock-names = "ldb";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ ldb0_to_lvds_ch0: endpoint {
+ remote-endpoint = <&lvds_ch0_to_ldb0>;
+ };
+ };
+
+ ldb0_port1: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ ldb1: phy@c {
+ compatible = "fsl,imx95-ldb";
+ reg = <0xc 0x4>, <0xc 0x4>;
+ reg-names = "ldb", "lvds";
+ clocks = <&scmi_clk IMX95_CLK_DISPAPB>;
+ clock-names = "ldb";
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ ldb1_to_lvds_ch1: endpoint {
+ remote-endpoint = <&lvds_ch1_to_ldb1>;
+ };
+ };
+
+ ldb1_port1: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+ };
+
+ pixel_interleaver_0: bridge@4b0d0000 {
+ compatible = "fsl,imx95-pixel-interleaver";
+ reg = <0x0 0x4b0d0000 0x0 0x50>;
+ clocks = <&scmi_clk IMX95_CLK_DISPAPB>;
+ fsl,syscon = <&dispmix_csr>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pixel_interleaver_disp0_to_dpu_disp0: endpoint {
+ remote-endpoint = <&dpu_disp0_to_pixel_interleaver_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pixel_interleaver_disp0_to_display_pixel_link0: endpoint {
+ remote-endpoint = <&display_pixel_link0_to_pixel_interleaver_disp0>;
+ };
+ };
+ };
+ };
+
+ pixel_interleaver_1: bridge@4b0e0000 {
+ compatible = "fsl,imx95-pixel-interleaver";
+ reg = <0x0 0x4b0e0000 0x0 0x50>;
+ clocks = <&scmi_clk IMX95_CLK_DISPAPB>;
+ fsl,syscon = <&dispmix_csr>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pixel_interleaver_disp1_to_dpu_disp1: endpoint {
+ remote-endpoint = <&dpu_disp1_to_pixel_interleaver_disp1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pixel_interleaver_disp1_to_display_pixel_link1: endpoint {
+ remote-endpoint = <&display_pixel_link1_to_pixel_interleaver_disp1>;
+ };
+ };
+ };
+ };
+
+ dpu: display-controller@4b400000 {
+ compatible = "fsl,imx95-dc";
+ reg = <0 0x4b400000 0 0x400000>;
+ clocks = <&scmi_clk IMX95_CLK_DISP1PIX>,
+ <&scmi_clk IMX95_CLK_DISPAPB>,
+ <&scmi_clk IMX95_CLK_DISPAXI>,
+ <&scmi_clk IMX95_CLK_DISPOCRAM>,
+ <&ldb_pll_pixel>,
+ <&scmi_clk IMX95_CLK_LDBPLL_VCO>;
+ clock-names = "pix", "apb", "axi", "ocram", "ldb", "ldb_vco";
+ fsl,syscon = <&dispmix_csr>;
+ power-domains = <&scmi_devpd IMX95_PD_DISPLAY>;
+ assigned-clocks = <&scmi_clk IMX95_CLK_DISPAXI>,
+ <&scmi_clk IMX95_CLK_DISPOCRAM>,
+ <&scmi_clk IMX95_CLK_DISPAPB>;
+ assigned-clock-parents = <&scmi_clk IMX95_CLK_SYSPLL1_PFD1>,
+ <&scmi_clk IMX95_CLK_SYSPLL1_PFD1>,
+ <&scmi_clk IMX95_CLK_SYSPLL1_PFD1_DIV2>;
+ assigned-clock-rates = <400000000>, <400000000>, <133333333>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ dc1_intc: interrupt-controller@4b781000 {
+ compatible = "fsl,imx95-dc-intc";
+ reg = <0 0x4b781000 0 0x60>;
+ clocks = <&scmi_clk IMX95_CLK_DISPAPB>,
+ <&scmi_clk IMX95_CLK_DISPAXI>;
+ clock-names = "apb", "axi";
+ power-domains = <&scmi_devpd IMX95_PD_DISPLAY>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&displaymix_irqsteer>;
+ interrupts = <448>, <449>, <450>, <64>,
+ <65>, <66>, <67>, <68>,
+ <69>, <192>, <193>, <194>,
+ <195>, <196>, <197>, <70>,
+ <71>, <72>, <73>, <74>,
+ <75>, <76>, <77>, <78>,
+ <79>, <80>, <81>, <82>,
+ <83>, <84>, <85>, <86>,
+ <87>, <88>, <89>, <90>,
+ <91>, <92>, <198>, <199>,
+ <200>, <201>, <202>, <203>,
+ <204>, <205>, <206>, <207>,
+ <208>, <209>, <210>, <211>,
+ <212>, <451>, <1>, <2>,
+ <3>, <4>, <93>, <94>,
+ <95>, <96>, <97>, <98>,
+ <99>, <100>, <101>, <102>,
+ <103>, <104>, <105>, <106>,
+ <213>, <214>, <215>, <216>,
+ <217>, <218>, <219>, <220>,
+ <221>, <222>, <223>, <224>,
+ <225>, <226>;
+ interrupt-names = "store9_shdload",
+ "store9_framecomplete",
+ "store9_seqcomplete",
+ "extdst0_shdload",
+ "extdst0_framecomplete",
+ "extdst0_seqcomplete",
+ "extdst4_shdload",
+ "extdst4_framecomplete",
+ "extdst4_seqcomplete",
+ "extdst1_shdload",
+ "extdst1_framecomplete",
+ "extdst1_seqcomplete",
+ "extdst5_shdload",
+ "extdst5_framecomplete",
+ "extdst5_seqcomplete",
+ "domainblend0_shdload",
+ "domainblend0_framecomplete",
+ "domainblend0_seqcomplete",
+ "disengcfg_shdload0",
+ "disengcfg_framecomplete0",
+ "disengcfg_seqcomplete0",
+ "framegen0_int0",
+ "framegen0_int1",
+ "framegen0_int2",
+ "framegen0_int3",
+ "sig0_shdload",
+ "sig0_valid",
+ "sig0_error",
+ "sig0_cluster_error",
+ "sig0_cluster_match",
+ "sig2_shdload",
+ "sig2_valid",
+ "sig2_error",
+ "sig2_cluster_error",
+ "sig2_cluster_match",
+ "idhash0_shdload",
+ "idhash0_valid",
+ "idhash0_window_error",
+ "domainblend1_shdload",
+ "domainblend1_framecomplete",
+ "domainblend1_seqcomplete",
+ "disengcfg_shdload1",
+ "disengcfg_framecomplete1",
+ "disengcfg_seqcomplete1",
+ "framegen1_int0",
+ "framegen1_int1",
+ "framegen1_int2",
+ "framegen1_int3",
+ "sig1_shdload",
+ "sig1_valid",
+ "sig1_error",
+ "sig1_cluster_error",
+ "sig1_cluster_match",
+ "cmdseq_error",
+ "comctrl_sw0",
+ "comctrl_sw1",
+ "comctrl_sw2",
+ "comctrl_sw3",
+ "framegen0_primsync_on",
+ "framegen0_primsync_off",
+ "framegen0_overflow0_on",
+ "framegen0_overflow0_off",
+ "framegen0_underrun0_on",
+ "framegen0_underrun0_off",
+ "framegen0_threshold0_rise",
+ "framegen0_threshold0_fail",
+ "framegen0_overflow1_on",
+ "framegen0_overflow1_off",
+ "framegen0_underrun1_on",
+ "framegen0_underrun1_off",
+ "framegen0_threshold1_rise",
+ "framegen0_threshold1_fail",
+ "framegen1_primsync_on",
+ "framegen1_primsync_off",
+ "framegen1_overflow0_on",
+ "framegen1_overflow0_off",
+ "framegen1_underrun0_on",
+ "framegen1_underrun0_off",
+ "framegen1_threshold0_rise",
+ "framegen1_threshold0_fail",
+ "framegen1_overflow1_on",
+ "framegen1_overflow1_off",
+ "framegen1_underrun1_on",
+ "framegen1_underrun1_off",
+ "framegen1_threshold1_rise",
+ "framegen1_threshold1_fail";
+ };
+
+ pixel-engine@4b4f0000 {
+ compatible = "fsl,imx95-dc-pixel-engine", "fsl,imx8qxp-dc-pixel-engine";
+ reg = <0 0x4b4f0000 0 0x1d0000>;
+ clocks = <&scmi_clk IMX95_CLK_DISPAPB>,
+ <&scmi_clk IMX95_CLK_DISPAXI>;
+ clock-names = "apb", "axi";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ constframe@4b4f0000 {
+ compatible = "fsl,imx95-dc-constframe";
+ reg = <0 0x4b4f1000 0 0xc>, <0 0x4b4f0000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+
+ extdst@4b510000 {
+ compatible = "fsl,imx95-dc-extdst";
+ reg = <0 0x4b511000 0 0x1c>, <0 0x4b510000 0 0x28>;
+ reg-names = "pec", "cfg";
+ interrupt-parent = <&dc1_intc>;
+ interrupts = <3>, <4>, <5>;
+ interrupt-names = "shdload", "framecomplete", "seqcomplete";
+ };
+
+ constframe@4b500000 {
+ compatible = "fsl,imx95-dc-constframe";
+ reg = <0 0x4b501000 0 0xc>, <0 0x4b500000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+
+ extdst@4b520000 {
+ compatible = "fsl,imx95-dc-extdst";
+ reg = <0 0x4b521000 0 0x1c>, <0 0x4b520000 0 0x28>;
+ reg-names = "pec", "cfg";
+ interrupt-parent = <&dc1_intc>;
+ interrupts = <9>, <10>, <11>;
+ interrupt-names = "shdload", "framecomplete", "seqcomplete";
+ };
+
+ constframe@4b530000 {
+ compatible = "fsl,imx95-dc-constframe";
+ reg = <0 0x4b531000 0 0xc>, <0 0x4b530000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+
+ extdst@4b550000 {
+ compatible = "fsl,imx95-dc-extdst";
+ reg = <0 0x4b551000 0 0x1c>, <0 0x4b550000 0 0x28>;
+ reg-names = "pec", "cfg";
+ interrupt-parent = <&dc1_intc>;
+ interrupts = <6>, <7>, <8>;
+ interrupt-names = "shdload", "framecomplete", "seqcomplete";
+ };
+
+ constframe@4b540000 {
+ compatible = "fsl,imx95-dc-constframe";
+ reg = <0 0x4b541000 0 0xc>, <0 0x4b540000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+
+ extdst@4b560000 {
+ compatible = "fsl,imx95-dc-extdst";
+ reg = <0 0x4b561000 0 0x1c>, <0 0x4b560000 0 0x28>;
+ reg-names = "pec", "cfg";
+ interrupt-parent = <&dc1_intc>;
+ interrupts = <12>, <13>, <14>;
+ interrupt-names = "shdload", "framecomplete", "seqcomplete";
+ };
+
+ fetchlayer@4b5d0000 {
+ compatible = "fsl,imx95-dc-fetchlayer";
+ reg = <0 0x4b5d1000 0 0xc>, <0 0x4b5d0000 0 0x404>;
+ reg-names = "pec", "cfg";
+ };
+
+ fetchlayer@4b5e0000 {
+ compatible = "fsl,imx95-dc-fetchlayer";
+ reg = <0 0x4b5e1000 0 0xc>, <0 0x4b5e0000 0 0x404>;
+ reg-names = "pec", "cfg";
+ };
+
+ layerblend@4b570000 {
+ compatible = "fsl,imx95-dc-layerblend";
+ reg = <0 0x4b571000 0 0x10>, <0 0x4b570000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+
+ layerblend@4b580000 {
+ compatible = "fsl,imx95-dc-layerblend";
+ reg = <0 0x4b581000 0 0x10>, <0 0x4b580000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+
+ layerblend@4b590000 {
+ compatible = "fsl,imx95-dc-layerblend";
+ reg = <0 0x4b591000 0 0x10>, <0 0x4b590000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+
+ layerblend@4b5a0000 {
+ compatible = "fsl,imx95-dc-layerblend";
+ reg = <0 0x4b5a1000 0 0x10>, <0 0x4b5a0000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+
+ layerblend@4b5b0000 {
+ compatible = "fsl,imx95-dc-layerblend";
+ reg = <0 0x4b5b1000 0 0x10>, <0 0x4b5b0000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+
+ layerblend@4b5c0000 {
+ compatible = "fsl,imx95-dc-layerblend";
+ reg = <0 0x4b5c1000 0 0x10>, <0 0x4b5c0000 0 0x20>;
+ reg-names = "pec", "cfg";
+ };
+ };
+
+ display-engine@4b600000 {
+ compatible = "fsl,imx95-dc-display-engine";
+ reg = <0 0x4b711000 0 0x14>, <0 0x4b710000 0 0x1c00>;
+ reg-names = "top", "cfg";
+ interrupt-parent = <&dc1_intc>;
+ interrupts = <18>, <19>, <20>;
+ interrupt-names = "shdload", "framecomplete", "seqcomplete";
+ power-domains = <&scmi_devpd IMX95_PD_DISPLAY>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ domainblend@4b6a0000 {
+ compatible = "fsl,imx95-dc-domainblend";
+ reg = <0 0x4b6a0000 0 0x20>;
+ };
+
+ framegen@4b6b0000 {
+ compatible = "fsl,imx95-dc-framegen";
+ reg = <0 0x4b6b0000 0 0x98>;
+
+ clocks = <&scmi_clk IMX95_CLK_DISP1PIX>,
+ <&scmi_clk IMX95_CLK_DISPAPB>,
+ <&scmi_clk IMX95_CLK_DISPAXI>,
+ <&scmi_clk IMX95_CLK_DISPOCRAM>,
+ <&ldb_pll_pixel>,
+ <&scmi_clk IMX95_CLK_LDBPLL_VCO>;
+ clock-names = "pix", "apb", "axi", "ocram", "ldb", "ldb_vco";
+
+ interrupt-parent = <&dc1_intc>;
+ interrupts = <21>, <22>, <23>, <24>, <58>, <59>;
+ interrupt-names = "int0", "int1", "int2", "int3",
+ "primsync_on", "primsync_off";
+ };
+
+ tcon {
+ compatible = "fsl,imx95-dc-tcon";
+
+ port {
+ dpu_disp0_to_pixel_interleaver_disp0: endpoint {
+ remote-endpoint = <&pixel_interleaver_disp0_to_dpu_disp0>;
+ };
+ };
+ };
+ };
+
+ display-engine@4b700000 {
+ compatible = "fsl,imx95-dc-display-engine";
+ reg = <0 0x4b771000 0 0x14>, <0 0x4b770000 0 0x1c00>;
+ reg-names = "top", "cfg";
+ interrupt-parent = <&dc1_intc>;
+ interrupts = <41>, <42>, <43>;
+ interrupt-names = "shdload", "framecomplete", "seqcomplete";
+ power-domains = <&scmi_devpd IMX95_PD_DISPLAY>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ domainblend@4b720000 {
+ compatible = "fsl,imx95-dc-domainblend";
+ reg = <0 0x4b720000 0 0x20>;
+ };
+
+ framegen@4b730000 {
+ compatible = "fsl,imx95-dc-framegen";
+ reg = <0 0x4b730000 0 0x98>;
+
+ clocks = <&scmi_clk IMX95_CLK_DISP1PIX>,
+ <&scmi_clk IMX95_CLK_DISPAPB>,
+ <&scmi_clk IMX95_CLK_DISPAXI>,
+ <&scmi_clk IMX95_CLK_DISPOCRAM>,
+ <&ldb_pll_pixel>,
+ <&scmi_clk IMX95_CLK_LDBPLL_VCO>;
+ clock-names = "pix", "apb", "axi", "ocram", "ldb", "ldb_vco";
+
+ interrupt-parent = <&dc1_intc>;
+ interrupts = <34>, <35>, <36>, <37>, <72>, <73>;
+ interrupt-names = "int0", "int1", "int2", "int3",
+ "primsync_on", "primsync_off";
+ };
+
+ tcon {
+ compatible = "fsl,imx95-dc-tcon";
+
+ port {
+ dpu_disp1_to_pixel_interleaver_disp1: endpoint {
+ remote-endpoint = <&pixel_interleaver_disp1_to_dpu_disp1>;
+ };
+ };
+ };
+ };
+ };
+
usb3: usb@4c010010 {
compatible = "fsl,imx95-dwc3", "fsl,imx8mp-dwc3";
reg = <0x0 0x4c010010 0x0 0x04>,
--
2.51.0
^ permalink raw reply related [flat|nested] 113+ messages in thread* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (38 preceding siblings ...)
2025-10-11 16:51 ` [PATCH 39/39] arm64: dts: imx95: Describe display pipeline Marek Vasut
@ 2025-10-14 8:51 ` Liu Ying
2025-10-14 21:55 ` Marek Vasut
2025-10-14 9:13 ` Liu Ying
40 siblings, 1 reply; 113+ messages in thread
From: Liu Ying @ 2025-10-14 8:51 UTC (permalink / raw)
To: Marek Vasut, dri-devel
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann, devicetree, imx,
linux-arm-kernel, linux-clk
Hi Marek,
On 10/11/2025, Marek Vasut wrote:
> This large series adds support for the i.MX95 display pipeline, including
> DPU, DSI and LVDS support. Most of the components extend existin drivers,
> DPU is added into DC driver, DSI into iMX93 DSI driver, LVDS into iMX8MP
> LDB. Pixel link and pixel interleaver drivers are reworked to work as two
> independent channels, since there seems to be no dependency between their
> two channels. The i.MX95 DTSI changes are also included.
>
> Since the DPU chapter is missing from the i.MX95 RM, this is based on the
> NXP downstream kernel fork code and there might be issues.
>
> Majority of this series are DPU patches on top of the DC driver, I tried
> to keep them separate and easy to review. Later part adds LVDS and DSI
> support, this can be split into separate series.
Like you said that this patch series is large, please split it.
Also, make sure proper maintainers are in TO or CC lists for each patch(b4
tool should do that automatically for you), e.g., patch 37 should be sent
to Thomas Gleixner <tglx@linutronix.de> according to MAINTAINERS.
>
> Both DSI-to-HDMI path using LT8912 bridge and LVDS single-lane with Logic
> Techno LT170410-2WHC panel were tested on Toradex i.MX95 Verdin EVK v1.2 .
>
> Liu Ying (2):
> drm/bridge: imx: Add NXP i.MX95 pixel interleaver support
> drm/bridge: imx: Add NXP i.MX95 pixel link support
>
> Marek Vasut (36):
> dt-bindings: display: imx: Document i.MX95 Display Controller
> DomainBlend
> drm/imx: Add i.MX95 Display Controller DomainBlend
> dt-bindings: display: imx: Document i.MX95 Display Controller
> processing units
> drm/imx: dc: Use bulk clock
> drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
> drm/imx: dc: Rename i.MX8QXP specific Link IDs
> drm/imx: dc: cf: Pass struct dc_subdev_info via OF match data
> drm/imx: dc: de: Pass struct dc_de_subdev_match_data via OF match data
> drm/imx: dc: ed: Rework dc_ed_pec_src_sel() to drop ARRAY_SIZE() use
> drm/imx: dc: ed: Pass struct dc_ed_subdev_match_data via OF match data
> drm/imx: dc: fg: Parametrize register access
> drm/imx: dc: ed: Pass struct dc_fg_subdev_match_data via OF match data
> drm/imx: dc: fu: Describe remaining register offsets
> drm/imx: dc: fu: Inline FRAC_OFFSET into FetchLayer and FetchWrap
> drm/imx: dc: fu: Pass struct dc_fu_subdev_match_data via OF match data
> drm/imx: dc: lb: Pass struct dc_lb_subdev_match_data via OF match data
> drm/imx: dc: tc: Pass struct dc_tc_subdev_match_data via OF match data
> drm/imx: dc: ic: Pass struct dc_ic_subdev_match_data via OF match data
> drm/imx: dc: ic: Use DT node as interrupt controller name
> drm/imx: dc: Configure display CSR clock feed select
> drm/imx: dc: crtc: Do not check disabled CRTCs
> drm/imx: dc: Keep FU unit running on i.MX95
> drm/imx: dc: Add OF match data for i.MX95
> drm/imx: Add more RGB swizzling options
> dt-bindings: display: bridge: Document NXP i.MX95 pixel interleaver
> support
> dt-bindings: display: bridge: Document NXP i.MX95 pixel link support
> dt-bindings: display: bridge: Document Freescale i.MX95 MIPI DSI
> drm/bridge: imx93-mipi-dsi: Add i.MX95 PLL initialization
> dt-bindings: clock: Split support for i.MX95 LVDS CSR
> dt-bindings: display: bridge: Document i.MX95 LVDS display bridge
> binding
> dt-bindings: display: bridge: ldb: Add an i.MX95 entry
> drm/bridge: fsl-ldb: Parse register offsets from DT
> drm/bridge: fsl-ldb: Add i.MX95 support
> dt-bindings: interrupt-controller: fsl,irqsteer: Add i.MX95 support
> dt-bindings: clock: support i.MX95 Display Stream CSR module
> arm64: dts: imx95: Describe display pipeline
>
> Sandor Yu (1):
> drm: bridge: imx: Add i.MX95 LVDS Display Bridge (LDB) driver
>
> .../bindings/clock/nxp,imx95-blk-ctl.yaml | 1 -
> .../clock/nxp,imx95-lvds-blk-ctl.yaml | 80 ++
> .../display/bridge/fsl,imx93-mipi-dsi.yaml | 48 +-
> .../display/bridge/fsl,imx95-lvds.yaml | 140 ++++
> .../bridge/fsl,imx95-pixel-interleaver.yaml | 85 +++
> .../display/bridge/fsl,imx95-pixel-link.yaml | 101 +++
> .../bindings/display/bridge/fsl,ldb.yaml | 2 +
> .../imx/fsl,imx8qxp-dc-constframe.yaml | 4 +-
> .../imx/fsl,imx8qxp-dc-display-engine.yaml | 45 +-
> .../display/imx/fsl,imx8qxp-dc-extdst.yaml | 4 +-
> .../display/imx/fsl,imx8qxp-dc-fetchunit.yaml | 1 +
> .../display/imx/fsl,imx8qxp-dc-framegen.yaml | 13 +-
> .../imx/fsl,imx8qxp-dc-layerblend.yaml | 4 +-
> .../imx/fsl,imx8qxp-dc-pixel-engine.yaml | 52 +-
> .../display/imx/fsl,imx8qxp-dc-tcon.yaml | 5 +-
> .../bindings/display/imx/fsl,imx8qxp-dc.yaml | 53 +-
> .../display/imx/fsl,imx95-dc-domainblend.yaml | 32 +
> .../imx/nxp,imx95-display-stream-csr.yaml | 41 +
> .../interrupt-controller/fsl,irqsteer.yaml | 2 +
> arch/arm64/boot/dts/freescale/imx95.dtsi | 710 ++++++++++++++++++
> drivers/gpu/drm/bridge/fsl-ldb.c | 65 +-
> drivers/gpu/drm/bridge/imx/Kconfig | 28 +
> drivers/gpu/drm/bridge/imx/Makefile | 3 +
> drivers/gpu/drm/bridge/imx/imx-ldb-helper.h | 2 +
> drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 612 ++++++++++++++-
> drivers/gpu/drm/bridge/imx/imx95-ldb.c | 470 ++++++++++++
> .../drm/bridge/imx/imx95-pixel-interleaver.c | 217 ++++++
> drivers/gpu/drm/bridge/imx/imx95-pixel-link.c | 184 +++++
> drivers/gpu/drm/imx/dc/Kconfig | 4 +-
> drivers/gpu/drm/imx/dc/Makefile | 2 +-
> drivers/gpu/drm/imx/dc/dc-cf.c | 41 +-
> drivers/gpu/drm/imx/dc/dc-crtc.c | 6 +
> drivers/gpu/drm/imx/dc/dc-db.c | 227 ++++++
> drivers/gpu/drm/imx/dc/dc-de.c | 83 +-
> drivers/gpu/drm/imx/dc/dc-de.h | 14 +
> drivers/gpu/drm/imx/dc/dc-drv.c | 45 +-
> drivers/gpu/drm/imx/dc/dc-drv.h | 11 +-
> drivers/gpu/drm/imx/dc/dc-ed.c | 67 +-
> drivers/gpu/drm/imx/dc/dc-fg.c | 157 ++--
> drivers/gpu/drm/imx/dc/dc-fl.c | 145 +++-
> drivers/gpu/drm/imx/dc/dc-fu.c | 46 +-
> drivers/gpu/drm/imx/dc/dc-fu.h | 7 +-
> drivers/gpu/drm/imx/dc/dc-fw.c | 54 +-
> drivers/gpu/drm/imx/dc/dc-ic.c | 192 +++--
> drivers/gpu/drm/imx/dc/dc-kms.h | 6 +
> drivers/gpu/drm/imx/dc/dc-lb.c | 109 ++-
> drivers/gpu/drm/imx/dc/dc-pe.c | 12 +-
> drivers/gpu/drm/imx/dc/dc-pe.h | 41 +-
> drivers/gpu/drm/imx/dc/dc-plane.c | 18 +-
> drivers/gpu/drm/imx/dc/dc-tc.c | 55 +-
> 50 files changed, 4000 insertions(+), 346 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/clock/nxp,imx95-lvds-blk-ctl.yaml
> create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx95-lvds.yaml
> create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-interleaver.yaml
> create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx95-pixel-link.yaml
> create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx95-dc-domainblend.yaml
> create mode 100644 Documentation/devicetree/bindings/display/imx/nxp,imx95-display-stream-csr.yaml
> create mode 100644 drivers/gpu/drm/bridge/imx/imx95-ldb.c
> create mode 100644 drivers/gpu/drm/bridge/imx/imx95-pixel-interleaver.c
> create mode 100644 drivers/gpu/drm/bridge/imx/imx95-pixel-link.c
> create mode 100644 drivers/gpu/drm/imx/dc/dc-db.c
>
> ---
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Liu Ying <victor.liu@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Peng Fan <peng.fan@nxp.com>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-clk@vger.kernel.org
>
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-14 8:51 ` [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Liu Ying
@ 2025-10-14 21:55 ` Marek Vasut
2025-10-15 10:00 ` Liu Ying
0 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-14 21:55 UTC (permalink / raw)
To: Liu Ying, dri-devel
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann, devicetree, imx,
linux-arm-kernel, linux-clk
On 10/14/25 10:51 AM, Liu Ying wrote:
> Hi Marek,
Hi,
> On 10/11/2025, Marek Vasut wrote:
>> This large series adds support for the i.MX95 display pipeline, including
>> DPU, DSI and LVDS support. Most of the components extend existin drivers,
>> DPU is added into DC driver, DSI into iMX93 DSI driver, LVDS into iMX8MP
>> LDB. Pixel link and pixel interleaver drivers are reworked to work as two
>> independent channels, since there seems to be no dependency between their
>> two channels. The i.MX95 DTSI changes are also included.
>>
>> Since the DPU chapter is missing from the i.MX95 RM, this is based on the
>> NXP downstream kernel fork code and there might be issues.
>>
>> Majority of this series are DPU patches on top of the DC driver, I tried
>> to keep them separate and easy to review. Later part adds LVDS and DSI
>> support, this can be split into separate series.
>
> Like you said that this patch series is large, please split it.
> Also, make sure proper maintainers are in TO or CC lists for each patch(b4
> tool should do that automatically for you), e.g., patch 37 should be sent
> to Thomas Gleixner <tglx@linutronix.de> according to MAINTAINERS.
I had to trim down the CC list for this series, it was enormous.
I wanted to put this whole thing on the list first, before I start
splitting it up.
For starters, I think I can send these separately:
- drm/imx: dc: Use bulk clock
- drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
- drm/imx: dc: Rename i.MX8QXP specific Link IDs
- drm/imx: Add more RGB swizzling options
- dt-bindings: interrupt-controller: fsl,irqsteer: Add i.MX95 support
Then in second round, probably all these clean ups:
- drm/imx: dc: *: Pass struct dc_*_subdev_match_data via OF match data
And then rest afterward.
What do you think ?
--
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-14 21:55 ` Marek Vasut
@ 2025-10-15 10:00 ` Liu Ying
2025-10-15 16:18 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Liu Ying @ 2025-10-15 10:00 UTC (permalink / raw)
To: Marek Vasut, dri-devel
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann, devicetree, imx,
linux-arm-kernel, linux-clk
On 10/14/2025, Marek Vasut wrote:
> On 10/14/25 10:51 AM, Liu Ying wrote:
>> Hi Marek,
>
> Hi,
>
>> On 10/11/2025, Marek Vasut wrote:
>>> This large series adds support for the i.MX95 display pipeline, including
>>> DPU, DSI and LVDS support. Most of the components extend existin drivers,
>>> DPU is added into DC driver, DSI into iMX93 DSI driver, LVDS into iMX8MP
>>> LDB. Pixel link and pixel interleaver drivers are reworked to work as two
>>> independent channels, since there seems to be no dependency between their
>>> two channels. The i.MX95 DTSI changes are also included.
>>>
>>> Since the DPU chapter is missing from the i.MX95 RM, this is based on the
>>> NXP downstream kernel fork code and there might be issues.
>>>
>>> Majority of this series are DPU patches on top of the DC driver, I tried
>>> to keep them separate and easy to review. Later part adds LVDS and DSI
>>> support, this can be split into separate series.
>>
>> Like you said that this patch series is large, please split it.
>> Also, make sure proper maintainers are in TO or CC lists for each patch(b4
>> tool should do that automatically for you), e.g., patch 37 should be sent
>> to Thomas Gleixner <tglx@linutronix.de> according to MAINTAINERS.
>
> I had to trim down the CC list for this series, it was enormous.
>
> I wanted to put this whole thing on the list first, before I start splitting it up.
>
> For starters, I think I can send these separately:
Before discussing how to split, a bigger question is that is it fine to
support both i.MX8qxp DC and i.MX95 DC in the same imx8_dc_drm module?
Separate modules look more reasonable to me, considering the fact that
there are quite a lot difference between the two DCs.
>
> - drm/imx: dc: Use bulk clock
I don't think this one is needed because reach relevant block has only one
clock.
> - drm/imx: dc: Rework dc_subdev_get_id() to drop ARRAY_SIZE() use
It doesn't seem that this one is needed either, if we use separate modules.
> - drm/imx: dc: Rename i.MX8QXP specific Link IDs
TBH, I'm not a big fan of adding LINK_ID_x_MXy to enum dc_link_id, since
the members may have the same value and it's kind of a mess considering
future SoCs.
> - drm/imx: Add more RGB swizzling options
This one seems ok.
> - dt-bindings: interrupt-controller: fsl,irqsteer: Add i.MX95 support
Ditto.
>
> Then in second round, probably all these clean ups:
>
> - drm/imx: dc: *: Pass struct dc_*_subdev_match_data via OF match data
Same, doesn't seem needed, if we use separate modules.
>
> And then rest afterward.
>
> What do you think ?
I kind of opt to separate modules. Maybe, to save some code, an additional
module can be introduced to wrap common part as helpers, plus some callback
magics, like fg->dc_fg_cfg_videomode().
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-15 10:00 ` Liu Ying
@ 2025-10-15 16:18 ` Marek Vasut
2025-10-20 2:15 ` Ying Liu
0 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-15 16:18 UTC (permalink / raw)
To: Liu Ying, dri-devel
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann, devicetree, imx,
linux-arm-kernel, linux-clk
On 10/15/25 12:00 PM, Liu Ying wrote:
Hi,
>> I wanted to put this whole thing on the list first, before I start splitting it up.
>>
>> For starters, I think I can send these separately:
>
> Before discussing how to split, a bigger question is that is it fine to
> support both i.MX8qxp DC and i.MX95 DC in the same imx8_dc_drm module?
> Separate modules look more reasonable to me, considering the fact that
> there are quite a lot difference between the two DCs.
(maybe I do not quite understand your suggestion with "separate module",
I assume this means entirely duplicate driver, is that correct? I
operate with that assumption in the text below.)
This series indicates that the functional units in the DC are basically
identical, with the majority of changes being register base addresses of
the whole DC and an odd bit or register offset here and there. Most of
the code can be reused, as can be seen in the first half of the series.
The addition of iMX95 into the iMX8QXP DC also does not seem to be
making the driver in any way more complicated.
What would be the benefit of having duplicate driver for IP that is
basically identical, for i.MX95 ?
[...]
>> - drm/imx: dc: Rename i.MX8QXP specific Link IDs
>
> TBH, I'm not a big fan of adding LINK_ID_x_MXy to enum dc_link_id, since
> the members may have the same value and it's kind of a mess considering
> future SoCs.
I am open to a better suggestion which does not involve duplicate driver.
>> - drm/imx: Add more RGB swizzling options
>
> This one seems ok.
I can send that one separately. Can you test that on MX8QXP ? I don't
have a board with that SoC, sorry.
[...]
> I kind of opt to separate modules. Maybe, to save some code, an additional
> module can be introduced to wrap common part as helpers, plus some callback
> magics, like fg->dc_fg_cfg_videomode().
Let me ask for clarification here -- by separate modules, do you mean
two totally separate drivers ?
^ permalink raw reply [flat|nested] 113+ messages in thread
* RE: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-15 16:18 ` Marek Vasut
@ 2025-10-20 2:15 ` Ying Liu
0 siblings, 0 replies; 113+ messages in thread
From: Ying Liu @ 2025-10-20 2:15 UTC (permalink / raw)
To: Marek Vasut, dri-devel@lists.freedesktop.org
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org
On 10/16/25, Marek Vasut <marek.vasut@mailbox.org> wrote:
> On 10/15/25 12:00 PM, Liu Ying wrote:
>
> Hi,
Hi,
>
> >> I wanted to put this whole thing on the list first, before I start splitting it
> up.
> >>
> >> For starters, I think I can send these separately:
> >
> > Before discussing how to split, a bigger question is that is it fine to
> > support both i.MX8qxp DC and i.MX95 DC in the same imx8_dc_drm
> module?
> > Separate modules look more reasonable to me, considering the fact that
> > there are quite a lot difference between the two DCs.
>
> (maybe I do not quite understand your suggestion with "separate module",
> I assume this means entirely duplicate driver, is that correct? I
> operate with that assumption in the text below.)
I'd expect separate modules: the existing imx8_dc_drm(which can be
modprobe'd) and something like imx95_dc_drm. I wouldn't call them
*entirely* duplicated drivers since I mentioned common part of the DCs
could be wrapped as helpers in an additional module(something like
imx_dc_drm_common).
>
> This series indicates that the functional units in the DC are basically
> identical, with the majority of changes being register base addresses of
> the whole DC and an odd bit or register offset here and there. Most of
> the code can be reused, as can be seen in the first half of the series.
The major differences between the i.MX95 and i.MX8qxp DCs are
different components in Display Engines(especially the additional
Domain Blend Unit in i.MX95 DC) plus i.MX8qxp DC's capability
to connect with the prefetch engines(DPRC & PRG). Both would
have significant impact on how we implement the drivers. We'll
certainly end up having different implementations for callbacks to
enable/disable CRTCs or update/disable planes.
The sort of minor difference is in Pixel Engine(including Blit Engine)
where FethUnit types and numbers are different plus different numbers
of Scaler Engine. I'd expect logics to allocate FetchUnits for planes can be
implemented in the imx_dc_drm_common module
>
> The addition of iMX95 into the iMX8QXP DC also does not seem to be
> making the driver in any way more complicated.
Disagree. The addition would introduce quite a few i.MX95 or i.MX8qxp
DC specific code branches due to the differences mentioned above.
I'd say i.MX95 DC support could be in drivers/gpu/drm/imx/dc, but it
needs to be in a separate module like again imx95_dc_drm.
This makes feel that the debate here becomes kind of similar to what
we did for single mxsfb module vs mxsfb + imx_lcdif separate modules...
>
> What would be the benefit of having duplicate driver for IP that is
> basically identical, for i.MX95 ?
Cleaner driver implementation and easier to maintain. I don’t want
to test both i.MX95 and i.MX8qxp platforms when only either
i.MX95 DC specific or i.MX8qxp DC specific code is changed.
But again, they won't be entirely duplicated drivers. Common
part could be shared between the drivers with software techniques,
like the imx_dc_drm_common module mentioned above.
>
> [...]
>
> >> - drm/imx: dc: Rename i.MX8QXP specific Link IDs
> >
> > TBH, I'm not a big fan of adding LINK_ID_x_MXy to enum dc_link_id, since
> > the members may have the same value and it's kind of a mess considering
> > future SoCs.
>
> I am open to a better suggestion which does not involve duplicate driver.
>
> >> - drm/imx: Add more RGB swizzling options
> >
> > This one seems ok.
>
> I can send that one separately. Can you test that on MX8QXP ? I don't
> have a board with that SoC, sorry.
I guess I can.
>
> [...]
>
> > I kind of opt to separate modules. Maybe, to save some code, an
> additional
> > module can be introduced to wrap common part as helpers, plus some
> callback
> > magics, like fg->dc_fg_cfg_videomode().
> Let me ask for clarification here -- by separate modules, do you mean
> two totally separate drivers ?
See above my reply. I'd expect separate modules(imx8_dc_drm and
something like imx95_dc_drm) + imx_dc_drm_common module.
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-11 16:51 [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Marek Vasut
` (39 preceding siblings ...)
2025-10-14 8:51 ` [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support Liu Ying
@ 2025-10-14 9:13 ` Liu Ying
2025-10-14 22:09 ` Marek Vasut
40 siblings, 1 reply; 113+ messages in thread
From: Liu Ying @ 2025-10-14 9:13 UTC (permalink / raw)
To: Marek Vasut, dri-devel
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann, devicetree, imx,
linux-arm-kernel, linux-clk
On 10/11/2025, Marek Vasut wrote:
> DPU is added into DC driver
This has conflicts with my in-flight patch series for adding i.MX8QXP DC
prefetch engine support(though i.MX95 SoC doesn't embed any display controller
prefetch engine). You probably want to take a look at it, just a heads up.
https://lore.kernel.org/all/20250929-imx8-dc-prefetch-v3-0-c01d0608add2@nxp.com/
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-14 9:13 ` Liu Ying
@ 2025-10-14 22:09 ` Marek Vasut
2025-10-15 10:09 ` Liu Ying
0 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-14 22:09 UTC (permalink / raw)
To: Liu Ying, dri-devel
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann, devicetree, imx,
linux-arm-kernel, linux-clk
On 10/14/25 11:13 AM, Liu Ying wrote:
> On 10/11/2025, Marek Vasut wrote:
>> DPU is added into DC driver
>
> This has conflicts with my in-flight patch series for adding i.MX8QXP DC
> prefetch engine support(though i.MX95 SoC doesn't embed any display controller
> prefetch engine). You probably want to take a look at it, just a heads up.
>
> https://lore.kernel.org/all/20250929-imx8-dc-prefetch-v3-0-c01d0608add2@nxp.com/
Thank you for sharing that.
Would it make sense to send 4 and 5 separately , so the fixes can land
faster?
Also, could you please try and avoid the SCU dependency on patch 7 , and
more in that direction , can the PRG be made a bit more optional, so the
iMX95 can still be supported by the DC driver ?
--
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-14 22:09 ` Marek Vasut
@ 2025-10-15 10:09 ` Liu Ying
2025-10-17 15:54 ` Marek Vasut
0 siblings, 1 reply; 113+ messages in thread
From: Liu Ying @ 2025-10-15 10:09 UTC (permalink / raw)
To: Marek Vasut, dri-devel
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann, devicetree, imx,
linux-arm-kernel, linux-clk
On 10/15/2025, Marek Vasut wrote:
> On 10/14/25 11:13 AM, Liu Ying wrote:
>> On 10/11/2025, Marek Vasut wrote:
>>> DPU is added into DC driver
>>
>> This has conflicts with my in-flight patch series for adding i.MX8QXP DC
>> prefetch engine support(though i.MX95 SoC doesn't embed any display controller
>> prefetch engine). You probably want to take a look at it, just a heads up.
>>
>> https://lore.kernel.org/all/20250929-imx8-dc-prefetch-v3-0-c01d0608add2@nxp.com/
>
> Thank you for sharing that.
>
> Would it make sense to send 4 and 5 separately , so the fixes can land faster?
Maybe not, since there is no user(DT node is not enabled) so far.
But I'd like to have more review/ack for that patch series(it's kind of
hard to get sufficient review...).
>
> Also, could you please try and avoid the SCU dependency on patch 7 ,
> and more in that direction , can the PRG be made a bit more optional, so the
Don't think there is any way to address them.
> iMX95 can still be supported by the DC driver ?
SCU dependency and PRG(even more other reasons) make me opt to separate
modules for i.MX95/8qxp DCs.
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-15 10:09 ` Liu Ying
@ 2025-10-17 15:54 ` Marek Vasut
2025-10-20 2:35 ` Liu Ying
0 siblings, 1 reply; 113+ messages in thread
From: Marek Vasut @ 2025-10-17 15:54 UTC (permalink / raw)
To: Liu Ying, dri-devel
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann, devicetree, imx,
linux-arm-kernel, linux-clk
On 10/15/25 12:09 PM, Liu Ying wrote:
Hello Liu,
>>> This has conflicts with my in-flight patch series for adding i.MX8QXP DC
>>> prefetch engine support(though i.MX95 SoC doesn't embed any display controller
>>> prefetch engine). You probably want to take a look at it, just a heads up.
>>>
>>> https://lore.kernel.org/all/20250929-imx8-dc-prefetch-v3-0-c01d0608add2@nxp.com/
>>
>> Thank you for sharing that.
>>
>> Would it make sense to send 4 and 5 separately , so the fixes can land faster?
>
> Maybe not, since there is no user(DT node is not enabled) so far.
> But I'd like to have more review/ack for that patch series(it's kind of
> hard to get sufficient review...).
I could test on the MX95 if we can somehow ... figure this out. Then I
can provide RB/TB easily. I don't have MX8qxp device.
>> Also, could you please try and avoid the SCU dependency on patch 7 ,
>> and more in that direction , can the PRG be made a bit more optional, so the
>
> Don't think there is any way to address them.
>
>> iMX95 can still be supported by the DC driver ?
>
> SCU dependency and PRG(even more other reasons) make me opt to separate
> modules for i.MX95/8qxp DCs.
SCU is only a register accessor, PRG is another block in the DC, I think
those can be isolated. It seems the whole DC is a composition of
multiple reusable blocks, so we can compose them for both MX8qxp and
MX95 the right way and reuse most of the code, right ?
^ permalink raw reply [flat|nested] 113+ messages in thread
* Re: [PATCH 00/39] Add i.MX95 DPU/DSI/LVDS support
2025-10-17 15:54 ` Marek Vasut
@ 2025-10-20 2:35 ` Liu Ying
0 siblings, 0 replies; 113+ messages in thread
From: Liu Ying @ 2025-10-20 2:35 UTC (permalink / raw)
To: Marek Vasut, dri-devel
Cc: Abel Vesa, Conor Dooley, Fabio Estevam, Krzysztof Kozlowski,
Laurent Pinchart, Lucas Stach, Peng Fan, Pengutronix Kernel Team,
Rob Herring, Shawn Guo, Thomas Zimmermann, devicetree, imx,
linux-arm-kernel, linux-clk
On 10/17/2025, Marek Vasut wrote:
> On 10/15/25 12:09 PM, Liu Ying wrote:
>
> Hello Liu,
Hello Marek,
>
>>>> This has conflicts with my in-flight patch series for adding i.MX8QXP DC
>>>> prefetch engine support(though i.MX95 SoC doesn't embed any display controller
>>>> prefetch engine). You probably want to take a look at it, just a heads up.
>>>>
>>>> https://lore.kernel.org/all/20250929-imx8-dc-prefetch-v3-0-c01d0608add2@nxp.com/
>>>
>>> Thank you for sharing that.
>>>
>>> Would it make sense to send 4 and 5 separately , so the fixes can land faster?
>>
>> Maybe not, since there is no user(DT node is not enabled) so far.
>> But I'd like to have more review/ack for that patch series(it's kind of
>> hard to get sufficient review...).
>
> I could test on the MX95 if we can somehow ... figure this out. Then I
> can provide RB/TB easily. I don't have MX8qxp device.
Thanks. Maybe RB is sufficient. TB is something nice to have.
>
>>> Also, could you please try and avoid the SCU dependency on patch 7 ,
>>> and more in that direction , can the PRG be made a bit more optional, so the
>>
>> Don't think there is any way to address them.
>>
>>> iMX95 can still be supported by the DC driver ?
>>
>> SCU dependency and PRG(even more other reasons) make me opt to separate
>> modules for i.MX95/8qxp DCs.
> SCU is only a register accessor,
Well, maybe it is. But IIUC the registers are directly accessed by Cortex-M
core, not Cortex-A core. See drivers/firmware/imx/Kconfig:
config IMX_SCU
bool "IMX SCU Protocol driver"
depends on IMX_MBOX
select SOC_BUS
help
The System Controller Firmware (SCFW) is a low-level system function
which runs on a dedicated Cortex-M core to provide power, clock, and
resource management. It exists on some i.MX8 processors. e.g. i.MX8QM
(QM, QP), and i.MX8QX (QXP, DX).
This driver manages the IPC interface between host CPU and the
SCU firmware running on M4.
> PRG is another block in the DC,
PRG and DPRC are in i.MX8qxp/qm DC subsystem but out of i.MX8qxp/qm DC.
> I think those can be isolated.
Not sure how to isolate SCU and PRG out of imx8_dc_drm.
> It seems the whole DC is a composition of
> multiple reusable blocks, so we can compose them for both MX8qxp and
> MX95 the right way and reuse most of the code, right ?
Some un-reusable blocks would impact how we implement the callbacks to
enable/disable CRTC and update/disable planes a lot. I'd expect separate
modules(imx8_dc_drm and something like imx95_dc_drm) + imx_dc_drm_common
module(which contains reusable code).
--
Regards,
Liu Ying
^ permalink raw reply [flat|nested] 113+ messages in thread