hints around rcar_lvds.c :)

From: Tommaso Merciai
Date: Tue Nov 26 2024 - 05:15:37 EST


Hi Laurent, All,

Sorry for bothering.
Looking for some feedback :)

I have a similar rcar_lvds.c IP's to handle but in my case:
I have lvds0 and lvds1 that are sharing some common regs (lvds_cmn).

----------------------
| ------------- |
| |lvds_cmn_regs| |
| ------------- |
| |
| ----------- |
| | lvds0_regs | |-----> ch0
| ------------ |
| |
| ----------- |
| | lvds1_regs | |-----> ch1
| ------------ |
----------------------


So I'm checking 2 drm dts/driver architecture:

1st architecture:
- Using a single lvds driver to handle both lvds0 and lvds1.

----------------------
| |
| |
| |
du_lvds0 ------>| |----> ch0_lvds
| lvds_bridge |
| |
| |
du_lvds1 ------>| |----> ch1_lvds
| |
----------------------


Issue:

Problem here is the 1 single link 2ch mode.
lvds0 and lvds1 can drive 2 display with 2 differents fb (fb0 and fb1).

Having a single drm_bridge to drive both channel give me the following issue:

In single link 2ch mode when for the first time the du encoder drm_attach()
the lvds bridge to the encoder(du) all goes fine and fb0 is created correctly.

Then again the du encoder is trying again to drm_attach() the lvds bridge
but this return -EBUSY obviously because is already attached.

Then I think this is not the way to follow because I need 2 drm_bridges
from the same drm drive, and I think this is not correct.
----------

2nd architecture:
- Follow rcar_lvds.c way using 2 nodes for lvds0 and lvds1:

------------
du_lvds0 -----> |lvds0_bridge|----> ch0_lvds
------------

------------
du_lvds1 -----> |lvds1_bridge|----> ch1_lvds
------------

Issue:
I thinks this is an optimal approach but in my case here
the problem is that lvds0 and lvds1 share a set of common registers
some common clocks and common reset:

My plan is to manipulate those common regs (lvds_cmn) using
compatible = "simple-mfd", "syscon"; as follow:

lvds_cmn: lvds-cmn {
compatible = "simple-mfd", "syscon";
reg = <common_regs>;

lvds0: lvds0-encoder {

ports {
#address-cells = <1>;
#size-cells = <0>;
clocks = <&common_clk>, <&dotclok0>, <&phyclock0>;
resets = <&common_rst>;

port@0 {
reg = <0>;
lvds0_in: endpoint {
remote-endpoint = <&du_out_lvds0>;
};
};

port@1 {
reg = <1>;
lvds_ch0: endpoint {
};
};
};
};

lvds1: lvds1-encoder {

ports {
#address-cells = <1>;
#size-cells = <0>;
clocks = <&common_clk>, <&dotclok1>, <&phyclock1>;
resets = <&common_rst>;

port@0 {
reg = <0>;
lvds1_in: endpoint {
remote-endpoint = <&du_out_lvds1>;
};
};

port@1 {
reg = <1>;
lvds_ch1: endpoint {
};
};
};
};
};
----------

I'm asking to find the best way to represent those IP's.
What do you think?
Any hints/tips would be nice.
Thanks in advance.

Thanks & Regards,
Tommaso