diff mbox

[RFC,v2,2/2] dt-bindings: mipi-dsi: Add dual-channel DSI related info

Message ID 20180118045355.8858-3-architt@codeaurora.org (mailing list archive)
State New, archived
Headers show

Commit Message

Archit Taneja Jan. 18, 2018, 4:53 a.m. UTC
Add binding info for peripherals that support dual-channel DSI. Add
corresponding optional bindings for DSI host controllers that may
be configured in this mode. Add an example of an I2C controlled
device operating in dual-channel DSI mode.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
v2:
- Specify that clock-master is a boolean property.
- Drop/add unit-address and #*-cells where applicable.

 .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80 ++++++++++++++++++++++
 1 file changed, 80 insertions(+)

Comments

Philippe CORNU Jan. 19, 2018, 10:41 a.m. UTC | #1
Hi Archit,

Many thanks for this documentation add-on.

I wonder if an extra example of "2 DSI hosts driving a dual-channel DSI 
peripheral controlled by the mipi bus" could be useful? well, I am not 
really convinced it is necessary and maybe this extra example could be 
added later when someone will meet the case... and I should have sent 
this comment on v1 (sorry for the delay).

Reviewed-by: Philippe Cornu <philippe.cornu@st.com>


Philippe :-)

On 01/18/2018 05:53 AM, Archit Taneja wrote:
> Add binding info for peripherals that support dual-channel DSI. Add

> corresponding optional bindings for DSI host controllers that may

> be configured in this mode. Add an example of an I2C controlled

> device operating in dual-channel DSI mode.

> 

> Signed-off-by: Archit Taneja <architt@codeaurora.org>

> ---

> v2:

> - Specify that clock-master is a boolean property.

> - Drop/add unit-address and #*-cells where applicable.

> 

>   .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80 ++++++++++++++++++++++

>   1 file changed, 80 insertions(+)

> 

> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt

> index 94fb72cb916f..7a3abbedb3fa 100644

> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt

> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt

> @@ -29,6 +29,13 @@ Required properties:

>   - #size-cells: Should be 0. There are cases where it makes sense to use a

>     different value here. See below.

>   

> +Optional properties:

> +- clock-master: boolean. Should be enabled if the host is being used in

> +  conjunction with another DSI host to drive the same peripheral. Hardware

> +  supporting such a configuration generally requires the data on both the busses

> +  to be driven by the same clock. Only the DSI host instance controlling this

> +  clock should contain this property.

> +

>   DSI peripheral

>   ==============

>   

> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI bus (mostly for the data

>   path). Connections between such peripherals and a DSI host can be represented

>   using the graph bindings [1], [2].

>   

> +Peripherals that support dual channel DSI

> +-----------------------------------------

> +

> +Peripherals with higher bandwidth requirements can be connected to 2 DSI

> +busses. Each DSI bus/channel drives some portion of the pixel data (generally

> +left/right half of each line of the display, or even/odd lines of the display).

> +The graph bindings should be used to represent the multiple DSI busses that are

> +connected to this peripheral. Each DSI host's output endpoint can be linked to

> +an input endpoint of the DSI peripheral.

> +

>   [1] Documentation/devicetree/bindings/graph.txt

>   [2] Documentation/devicetree/bindings/media/video-interfaces.txt

>   

> @@ -71,6 +88,8 @@ Examples

>     with different virtual channel configurations.

>   - (4) is an example of a peripheral on a I2C control bus connected with to

>     a DSI host using of-graph bindings.

> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI peripheral,

> +  which uses I2C as its primary control bus.

>   

>   1)

>   	dsi-host {

> @@ -153,3 +172,64 @@ Examples

>   			};

>   		};

>   	};

> +

> +5)

> +	i2c-host {

> +		dsi-bridge@35 {

> +			compatible = "...";

> +			reg = <0x35>;

> +

> +			ports {

> +				#address-cells = <1>;

> +				#size-cells = <0>;

> +

> +				port@0 {

> +					reg = <0>;

> +					dsi0_in: endpoint {

> +						remote-endpoint = <&dsi0_out>;

> +					};

> +				};

> +

> +				port@1 {

> +					reg = <1>;

> +					dsi1_in: endpoint {

> +						remote-endpoint = <&dsi1_out>;

> +					};

> +				};

> +			};

> +		};

> +	};

> +

> +	dsi0-host {

> +		...

> +

> +		/*

> +		 * this DSI instance drives the clock for both the host

> +		 * controllers

> +		 */

> +		clock-master;

> +

> +		ports {

> +			...

> +

> +			port {

> +				dsi0_out: endpoint {

> +					remote-endpoint = <&dsi0_in>;

> +				};

> +			};

> +		};

> +	};

> +

> +	dsi1-host {

> +		...

> +

> +		ports {

> +			...

> +

> +			port {

> +				dsi1_out: endpoint {

> +					remote-endpoint = <&dsi1_in>;

> +				};

> +			};

> +		};

> +	};

>
Sean Paul Jan. 29, 2018, 8:13 p.m. UTC | #2
On Thu, Jan 18, 2018 at 10:23:55AM +0530, Archit Taneja wrote:
> Add binding info for peripherals that support dual-channel DSI. Add
> corresponding optional bindings for DSI host controllers that may
> be configured in this mode. Add an example of an I2C controlled
> device operating in dual-channel DSI mode.
> 
> Signed-off-by: Archit Taneja <architt@codeaurora.org>

Reviewed-by: Sean Paul <seanpaul@chromium.org>

> ---
> v2:
> - Specify that clock-master is a boolean property.
> - Drop/add unit-address and #*-cells where applicable.
> 
>  .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80 ++++++++++++++++++++++
>  1 file changed, 80 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> index 94fb72cb916f..7a3abbedb3fa 100644
> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> @@ -29,6 +29,13 @@ Required properties:
>  - #size-cells: Should be 0. There are cases where it makes sense to use a
>    different value here. See below.
>  
> +Optional properties:
> +- clock-master: boolean. Should be enabled if the host is being used in
> +  conjunction with another DSI host to drive the same peripheral. Hardware
> +  supporting such a configuration generally requires the data on both the busses
> +  to be driven by the same clock. Only the DSI host instance controlling this
> +  clock should contain this property.
> +
>  DSI peripheral
>  ==============
>  
> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI bus (mostly for the data
>  path). Connections between such peripherals and a DSI host can be represented
>  using the graph bindings [1], [2].
>  
> +Peripherals that support dual channel DSI
> +-----------------------------------------
> +
> +Peripherals with higher bandwidth requirements can be connected to 2 DSI
> +busses. Each DSI bus/channel drives some portion of the pixel data (generally
> +left/right half of each line of the display, or even/odd lines of the display).
> +The graph bindings should be used to represent the multiple DSI busses that are
> +connected to this peripheral. Each DSI host's output endpoint can be linked to
> +an input endpoint of the DSI peripheral.
> +
>  [1] Documentation/devicetree/bindings/graph.txt
>  [2] Documentation/devicetree/bindings/media/video-interfaces.txt
>  
> @@ -71,6 +88,8 @@ Examples
>    with different virtual channel configurations.
>  - (4) is an example of a peripheral on a I2C control bus connected with to
>    a DSI host using of-graph bindings.
> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI peripheral,
> +  which uses I2C as its primary control bus.
>  
>  1)
>  	dsi-host {
> @@ -153,3 +172,64 @@ Examples
>  			};
>  		};
>  	};
> +
> +5)
> +	i2c-host {
> +		dsi-bridge@35 {
> +			compatible = "...";
> +			reg = <0x35>;
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				port@0 {
> +					reg = <0>;
> +					dsi0_in: endpoint {
> +						remote-endpoint = <&dsi0_out>;
> +					};
> +				};
> +
> +				port@1 {
> +					reg = <1>;
> +					dsi1_in: endpoint {
> +						remote-endpoint = <&dsi1_out>;
> +					};
> +				};
> +			};
> +		};
> +	};
> +
> +	dsi0-host {
> +		...
> +
> +		/*
> +		 * this DSI instance drives the clock for both the host
> +		 * controllers
> +		 */
> +		clock-master;
> +
> +		ports {
> +			...
> +
> +			port {
> +				dsi0_out: endpoint {
> +					remote-endpoint = <&dsi0_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	dsi1-host {
> +		...
> +
> +		ports {
> +			...
> +
> +			port {
> +				dsi1_out: endpoint {
> +					remote-endpoint = <&dsi1_in>;
> +				};
> +			};
> +		};
> +	};
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
>
Heiko Stübner June 4, 2018, 12:17 p.m. UTC | #3
Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
> Add binding info for peripherals that support dual-channel DSI. Add
> corresponding optional bindings for DSI host controllers that may
> be configured in this mode. Add an example of an I2C controlled
> device operating in dual-channel DSI mode.
> 
> Signed-off-by: Archit Taneja <architt@codeaurora.org>

Looks like a great solution for that problem, so
Reviewed-by: Heiko Stuebner <heiko@sntech.de>

As I'm looking into that for my rk3399-scarlet device right now and
couldn't find this patchset in the kernel yet, is it planned to
merge or refresh these binding changes or were problems encountered.

At least an Ack/Review from Rob seems to be missing.


Heiko

> ---
> v2:
> - Specify that clock-master is a boolean property.
> - Drop/add unit-address and #*-cells where applicable.
> 
>  .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80 ++++++++++++++++++++++
>  1 file changed, 80 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> index 94fb72cb916f..7a3abbedb3fa 100644
> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> @@ -29,6 +29,13 @@ Required properties:
>  - #size-cells: Should be 0. There are cases where it makes sense to use a
>    different value here. See below.
>  
> +Optional properties:
> +- clock-master: boolean. Should be enabled if the host is being used in
> +  conjunction with another DSI host to drive the same peripheral. Hardware
> +  supporting such a configuration generally requires the data on both the busses
> +  to be driven by the same clock. Only the DSI host instance controlling this
> +  clock should contain this property.
> +
>  DSI peripheral
>  ==============
>  
> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI bus (mostly for the data
>  path). Connections between such peripherals and a DSI host can be represented
>  using the graph bindings [1], [2].
>  
> +Peripherals that support dual channel DSI
> +-----------------------------------------
> +
> +Peripherals with higher bandwidth requirements can be connected to 2 DSI
> +busses. Each DSI bus/channel drives some portion of the pixel data (generally
> +left/right half of each line of the display, or even/odd lines of the display).
> +The graph bindings should be used to represent the multiple DSI busses that are
> +connected to this peripheral. Each DSI host's output endpoint can be linked to
> +an input endpoint of the DSI peripheral.
> +
>  [1] Documentation/devicetree/bindings/graph.txt
>  [2] Documentation/devicetree/bindings/media/video-interfaces.txt
>  
> @@ -71,6 +88,8 @@ Examples
>    with different virtual channel configurations.
>  - (4) is an example of a peripheral on a I2C control bus connected with to
>    a DSI host using of-graph bindings.
> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI peripheral,
> +  which uses I2C as its primary control bus.
>  
>  1)
>  	dsi-host {
> @@ -153,3 +172,64 @@ Examples
>  			};
>  		};
>  	};
> +
> +5)
> +	i2c-host {
> +		dsi-bridge@35 {
> +			compatible = "...";
> +			reg = <0x35>;
> +
> +			ports {
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				port@0 {
> +					reg = <0>;
> +					dsi0_in: endpoint {
> +						remote-endpoint = <&dsi0_out>;
> +					};
> +				};
> +
> +				port@1 {
> +					reg = <1>;
> +					dsi1_in: endpoint {
> +						remote-endpoint = <&dsi1_out>;
> +					};
> +				};
> +			};
> +		};
> +	};
> +
> +	dsi0-host {
> +		...
> +
> +		/*
> +		 * this DSI instance drives the clock for both the host
> +		 * controllers
> +		 */
> +		clock-master;
> +
> +		ports {
> +			...
> +
> +			port {
> +				dsi0_out: endpoint {
> +					remote-endpoint = <&dsi0_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	dsi1-host {
> +		...
> +
> +		ports {
> +			...
> +
> +			port {
> +				dsi1_out: endpoint {
> +					remote-endpoint = <&dsi1_in>;
> +				};
> +			};
> +		};
> +	};
>
Archit Taneja June 6, 2018, 5:59 a.m. UTC | #4
On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
>> Add binding info for peripherals that support dual-channel DSI. Add
>> corresponding optional bindings for DSI host controllers that may
>> be configured in this mode. Add an example of an I2C controlled
>> device operating in dual-channel DSI mode.
>>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> 
> Looks like a great solution for that problem, so
> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
> 
> As I'm looking into that for my rk3399-scarlet device right now and
> couldn't find this patchset in the kernel yet, is it planned to
> merge or refresh these binding changes or were problems encountered.
> 
> At least an Ack/Review from Rob seems to be missing.
> 

I forgot about these patches. Rob had reviewed the first one in
the set the second one still needed an Ack. I'll post a v3
that adds the Reviewed-bys and fixes a small typo.

Archit

> 
> Heiko
> 
>> ---
>> v2:
>> - Specify that clock-master is a boolean property.
>> - Drop/add unit-address and #*-cells where applicable.
>>
>>   .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80 ++++++++++++++++++++++
>>   1 file changed, 80 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>> index 94fb72cb916f..7a3abbedb3fa 100644
>> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>> @@ -29,6 +29,13 @@ Required properties:
>>   - #size-cells: Should be 0. There are cases where it makes sense to use a
>>     different value here. See below.
>>   
>> +Optional properties:
>> +- clock-master: boolean. Should be enabled if the host is being used in
>> +  conjunction with another DSI host to drive the same peripheral. Hardware
>> +  supporting such a configuration generally requires the data on both the busses
>> +  to be driven by the same clock. Only the DSI host instance controlling this
>> +  clock should contain this property.
>> +
>>   DSI peripheral
>>   ==============
>>   
>> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI bus (mostly for the data
>>   path). Connections between such peripherals and a DSI host can be represented
>>   using the graph bindings [1], [2].
>>   
>> +Peripherals that support dual channel DSI
>> +-----------------------------------------
>> +
>> +Peripherals with higher bandwidth requirements can be connected to 2 DSI
>> +busses. Each DSI bus/channel drives some portion of the pixel data (generally
>> +left/right half of each line of the display, or even/odd lines of the display).
>> +The graph bindings should be used to represent the multiple DSI busses that are
>> +connected to this peripheral. Each DSI host's output endpoint can be linked to
>> +an input endpoint of the DSI peripheral.
>> +
>>   [1] Documentation/devicetree/bindings/graph.txt
>>   [2] Documentation/devicetree/bindings/media/video-interfaces.txt
>>   
>> @@ -71,6 +88,8 @@ Examples
>>     with different virtual channel configurations.
>>   - (4) is an example of a peripheral on a I2C control bus connected with to
>>     a DSI host using of-graph bindings.
>> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI peripheral,
>> +  which uses I2C as its primary control bus.
>>   
>>   1)
>>   	dsi-host {
>> @@ -153,3 +172,64 @@ Examples
>>   			};
>>   		};
>>   	};
>> +
>> +5)
>> +	i2c-host {
>> +		dsi-bridge@35 {
>> +			compatible = "...";
>> +			reg = <0x35>;
>> +
>> +			ports {
>> +				#address-cells = <1>;
>> +				#size-cells = <0>;
>> +
>> +				port@0 {
>> +					reg = <0>;
>> +					dsi0_in: endpoint {
>> +						remote-endpoint = <&dsi0_out>;
>> +					};
>> +				};
>> +
>> +				port@1 {
>> +					reg = <1>;
>> +					dsi1_in: endpoint {
>> +						remote-endpoint = <&dsi1_out>;
>> +					};
>> +				};
>> +			};
>> +		};
>> +	};
>> +
>> +	dsi0-host {
>> +		...
>> +
>> +		/*
>> +		 * this DSI instance drives the clock for both the host
>> +		 * controllers
>> +		 */
>> +		clock-master;
>> +
>> +		ports {
>> +			...
>> +
>> +			port {
>> +				dsi0_out: endpoint {
>> +					remote-endpoint = <&dsi0_in>;
>> +				};
>> +			};
>> +		};
>> +	};
>> +
>> +	dsi1-host {
>> +		...
>> +
>> +		ports {
>> +			...
>> +
>> +			port {
>> +				dsi1_out: endpoint {
>> +					remote-endpoint = <&dsi1_in>;
>> +				};
>> +			};
>> +		};
>> +	};
>>
> 
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
Heiko Stübner June 6, 2018, 8:30 a.m. UTC | #5
Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
> > Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
> >> Add binding info for peripherals that support dual-channel DSI. Add
> >> corresponding optional bindings for DSI host controllers that may
> >> be configured in this mode. Add an example of an I2C controlled
> >> device operating in dual-channel DSI mode.
> >> 
> >> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> > 
> > Looks like a great solution for that problem, so
> > Reviewed-by: Heiko Stuebner <heiko@sntech.de>
> > 
> > As I'm looking into that for my rk3399-scarlet device right now and
> > couldn't find this patchset in the kernel yet, is it planned to
> > merge or refresh these binding changes or were problems encountered.
> > 
> > At least an Ack/Review from Rob seems to be missing.
> 
> I forgot about these patches. Rob had reviewed the first one in
> the set the second one still needed an Ack. I'll post a v3
> that adds the Reviewed-bys and fixes a small typo.

very nice ... because it looks like yesterday I managed to make the Rockchip 
dsi work in dual mode following this.

But one question came up, do you really want two input ports on the panel 
side? I.e. hardware-wise, I guess the panel will have one 8-lane or so input 
thatonly gets split up on the soc side onto 2 dsi controllers?

So right now I'm operating with a devicetree like

&mipi_dsi {
        status = "okay";
        clock-master;

        ports {
                mipi_out: port@1 {
                        reg = <1>;

                        mipi_out_panel: endpoint {
                                remote-endpoint = <&mipi_in_panel>;
                        };
                };
        };

        mipi_panel: panel@0 {
		  compatible = "innolux,p097pfg";
                reg = <0>;
                backlight = <&backlight>;
                enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
                pinctrl-0 = <&display_rst_l>;

                port {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        mipi_in_panel: endpoint@0 {
                                reg = <0>;
                                remote-endpoint = <&mipi_out_panel>;
                        };

                        mipi1_in_panel: endpoint@1 {
                                reg = <1>;
                                remote-endpoint = <&mipi1_out_panel>;
                        };
                };
        };
};

&mipi_dsi1 {
        status = "okay";

        ports {
                mipi1_out: port@1 {
                        reg = <1>;

                        mipi1_out_panel: endpoint {
                                remote-endpoint = <&mipi1_in_panel>;
                        };
                };
        };
};


I guess it is a matter of preference on what reflects the hardware
best, so maybe that's Robs call?


Heiko

> >> ---
> >> v2:
> >> - Specify that clock-master is a boolean property.
> >> - Drop/add unit-address and #*-cells where applicable.
> >> 
> >>   .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80
> >>   ++++++++++++++++++++++ 1 file changed, 80 insertions(+)
> >> 
> >> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >> b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt index
> >> 94fb72cb916f..7a3abbedb3fa 100644
> >> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >> 
> >> @@ -29,6 +29,13 @@ Required properties:
> >>   - #size-cells: Should be 0. There are cases where it makes sense to use
> >>   a
> >>   
> >>     different value here. See below.
> >> 
> >> +Optional properties:
> >> +- clock-master: boolean. Should be enabled if the host is being used in
> >> +  conjunction with another DSI host to drive the same peripheral.
> >> Hardware
> >> +  supporting such a configuration generally requires the data on both
> >> the busses +  to be driven by the same clock. Only the DSI host instance
> >> controlling this +  clock should contain this property.
> >> +
> >> 
> >>   DSI peripheral
> >>   ==============
> >> 
> >> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI
> >> bus (mostly for the data>> 
> >>   path). Connections between such peripherals and a DSI host can be
> >>   represented using the graph bindings [1], [2].
> >> 
> >> +Peripherals that support dual channel DSI
> >> +-----------------------------------------
> >> +
> >> +Peripherals with higher bandwidth requirements can be connected to 2 DSI
> >> +busses. Each DSI bus/channel drives some portion of the pixel data
> >> (generally +left/right half of each line of the display, or even/odd
> >> lines of the display). +The graph bindings should be used to represent
> >> the multiple DSI busses that are +connected to this peripheral. Each DSI
> >> host's output endpoint can be linked to +an input endpoint of the DSI
> >> peripheral.
> >> +
> >> 
> >>   [1] Documentation/devicetree/bindings/graph.txt
> >>   [2] Documentation/devicetree/bindings/media/video-interfaces.txt
> >> 
> >> @@ -71,6 +88,8 @@ Examples
> >> 
> >>     with different virtual channel configurations.
> >>   
> >>   - (4) is an example of a peripheral on a I2C control bus connected with
> >>   to
> >>   
> >>     a DSI host using of-graph bindings.
> >> 
> >> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI
> >> peripheral,
> >> +  which uses I2C as its primary control bus.
> >> 
> >>   1)
> >>   
> >>   	dsi-host {
> >> 
> >> @@ -153,3 +172,64 @@ Examples
> >> 
> >>   			};
> >>   		
> >>   		};
> >>   	
> >>   	};
> >> 
> >> +
> >> +5)
> >> +	i2c-host {
> >> +		dsi-bridge@35 {
> >> +			compatible = "...";
> >> +			reg = <0x35>;
> >> +
> >> +			ports {
> >> +				#address-cells = <1>;
> >> +				#size-cells = <0>;
> >> +
> >> +				port@0 {
> >> +					reg = <0>;
> >> +					dsi0_in: endpoint {
> >> +						remote-endpoint = <&dsi0_out>;
> >> +					};
> >> +				};
> >> +
> >> +				port@1 {
> >> +					reg = <1>;
> >> +					dsi1_in: endpoint {
> >> +						remote-endpoint = <&dsi1_out>;
> >> +					};
> >> +				};
> >> +			};
> >> +		};
> >> +	};
> >> +
> >> +	dsi0-host {
> >> +		...
> >> +
> >> +		/*
> >> +		 * this DSI instance drives the clock for both the host
> >> +		 * controllers
> >> +		 */
> >> +		clock-master;
> >> +
> >> +		ports {
> >> +			...
> >> +
> >> +			port {
> >> +				dsi0_out: endpoint {
> >> +					remote-endpoint = <&dsi0_in>;
> >> +				};
> >> +			};
> >> +		};
> >> +	};
> >> +
> >> +	dsi1-host {
> >> +		...
> >> +
> >> +		ports {
> >> +			...
> >> +
> >> +			port {
> >> +				dsi1_out: endpoint {
> >> +					remote-endpoint = <&dsi1_in>;
> >> +				};
> >> +			};
> >> +		};
> >> +	};
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-arm-msm"
> > in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
Archit Taneja June 6, 2018, 10:21 a.m. UTC | #6
On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
> Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
>> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
>>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
>>>> Add binding info for peripherals that support dual-channel DSI. Add
>>>> corresponding optional bindings for DSI host controllers that may
>>>> be configured in this mode. Add an example of an I2C controlled
>>>> device operating in dual-channel DSI mode.
>>>>
>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>>>
>>> Looks like a great solution for that problem, so
>>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
>>>
>>> As I'm looking into that for my rk3399-scarlet device right now and
>>> couldn't find this patchset in the kernel yet, is it planned to
>>> merge or refresh these binding changes or were problems encountered.
>>>
>>> At least an Ack/Review from Rob seems to be missing.
>>
>> I forgot about these patches. Rob had reviewed the first one in
>> the set the second one still needed an Ack. I'll post a v3
>> that adds the Reviewed-bys and fixes a small typo.
> 
> very nice ... because it looks like yesterday I managed to make the Rockchip
> dsi work in dual mode following this.
> 
> But one question came up, do you really want two input ports on the panel
> side? I.e. hardware-wise, I guess the panel will have one 8-lane or so input
> thatonly gets split up on the soc side onto 2 dsi controllers?

I think all dual DSI panels actually have 2 DSI controllers/parsers
within them, one on each port. The MIPI DSI spec doesn't support 8
lanes. Also, the pixels coming out of the host are distributed among
the lanes differently than what would have been the case with a
'theoretical' 8 lane receiver.

Other than that, some dual DSI panels only accept DSI commands on the
'master' port, where as others expect the same command to be sent across
both the ports.

Therefore, I think it's better to represent dual DSI panels having 2
DSI input ports.

Your DT looks good to me.

Thanks,
Archit

> 
> So right now I'm operating with a devicetree like
> 
> &mipi_dsi {
>          status = "okay";
>          clock-master;
> 
>          ports {
>                  mipi_out: port@1 {
>                          reg = <1>;
> 
>                          mipi_out_panel: endpoint {
>                                  remote-endpoint = <&mipi_in_panel>;
>                          };
>                  };
>          };
> 
>          mipi_panel: panel@0 {
> 		  compatible = "innolux,p097pfg";
>                  reg = <0>;
>                  backlight = <&backlight>;
>                  enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
>                  pinctrl-names = "default";
>                  pinctrl-0 = <&display_rst_l>;
> 
>                  port {
>                          #address-cells = <1>;
>                          #size-cells = <0>;
> 
>                          mipi_in_panel: endpoint@0 {
>                                  reg = <0>;
>                                  remote-endpoint = <&mipi_out_panel>;
>                          };
> 
>                          mipi1_in_panel: endpoint@1 {
>                                  reg = <1>;
>                                  remote-endpoint = <&mipi1_out_panel>;
>                          };
>                  };
>          };
> };
> 
> &mipi_dsi1 {
>          status = "okay";
> 
>          ports {
>                  mipi1_out: port@1 {
>                          reg = <1>;
> 
>                          mipi1_out_panel: endpoint {
>                                  remote-endpoint = <&mipi1_in_panel>;
>                          };
>                  };
>          };
> };
> 
> 
> I guess it is a matter of preference on what reflects the hardware
> best, so maybe that's Robs call?
> 
> 
> Heiko
> 
>>>> ---
>>>> v2:
>>>> - Specify that clock-master is a boolean property.
>>>> - Drop/add unit-address and #*-cells where applicable.
>>>>
>>>>    .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80
>>>>    ++++++++++++++++++++++ 1 file changed, 80 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>>>> b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt index
>>>> 94fb72cb916f..7a3abbedb3fa 100644
>>>> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>>>> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>>>>
>>>> @@ -29,6 +29,13 @@ Required properties:
>>>>    - #size-cells: Should be 0. There are cases where it makes sense to use
>>>>    a
>>>>    
>>>>      different value here. See below.
>>>>
>>>> +Optional properties:
>>>> +- clock-master: boolean. Should be enabled if the host is being used in
>>>> +  conjunction with another DSI host to drive the same peripheral.
>>>> Hardware
>>>> +  supporting such a configuration generally requires the data on both
>>>> the busses +  to be driven by the same clock. Only the DSI host instance
>>>> controlling this +  clock should contain this property.
>>>> +
>>>>
>>>>    DSI peripheral
>>>>    ==============
>>>>
>>>> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI
>>>> bus (mostly for the data>>
>>>>    path). Connections between such peripherals and a DSI host can be
>>>>    represented using the graph bindings [1], [2].
>>>>
>>>> +Peripherals that support dual channel DSI
>>>> +-----------------------------------------
>>>> +
>>>> +Peripherals with higher bandwidth requirements can be connected to 2 DSI
>>>> +busses. Each DSI bus/channel drives some portion of the pixel data
>>>> (generally +left/right half of each line of the display, or even/odd
>>>> lines of the display). +The graph bindings should be used to represent
>>>> the multiple DSI busses that are +connected to this peripheral. Each DSI
>>>> host's output endpoint can be linked to +an input endpoint of the DSI
>>>> peripheral.
>>>> +
>>>>
>>>>    [1] Documentation/devicetree/bindings/graph.txt
>>>>    [2] Documentation/devicetree/bindings/media/video-interfaces.txt
>>>>
>>>> @@ -71,6 +88,8 @@ Examples
>>>>
>>>>      with different virtual channel configurations.
>>>>    
>>>>    - (4) is an example of a peripheral on a I2C control bus connected with
>>>>    to
>>>>    
>>>>      a DSI host using of-graph bindings.
>>>>
>>>> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI
>>>> peripheral,
>>>> +  which uses I2C as its primary control bus.
>>>>
>>>>    1)
>>>>    
>>>>    	dsi-host {
>>>>
>>>> @@ -153,3 +172,64 @@ Examples
>>>>
>>>>    			};
>>>>    		
>>>>    		};
>>>>    	
>>>>    	};
>>>>
>>>> +
>>>> +5)
>>>> +	i2c-host {
>>>> +		dsi-bridge@35 {
>>>> +			compatible = "...";
>>>> +			reg = <0x35>;
>>>> +
>>>> +			ports {
>>>> +				#address-cells = <1>;
>>>> +				#size-cells = <0>;
>>>> +
>>>> +				port@0 {
>>>> +					reg = <0>;
>>>> +					dsi0_in: endpoint {
>>>> +						remote-endpoint = <&dsi0_out>;
>>>> +					};
>>>> +				};
>>>> +
>>>> +				port@1 {
>>>> +					reg = <1>;
>>>> +					dsi1_in: endpoint {
>>>> +						remote-endpoint = <&dsi1_out>;
>>>> +					};
>>>> +				};
>>>> +			};
>>>> +		};
>>>> +	};
>>>> +
>>>> +	dsi0-host {
>>>> +		...
>>>> +
>>>> +		/*
>>>> +		 * this DSI instance drives the clock for both the host
>>>> +		 * controllers
>>>> +		 */
>>>> +		clock-master;
>>>> +
>>>> +		ports {
>>>> +			...
>>>> +
>>>> +			port {
>>>> +				dsi0_out: endpoint {
>>>> +					remote-endpoint = <&dsi0_in>;
>>>> +				};
>>>> +			};
>>>> +		};
>>>> +	};
>>>> +
>>>> +	dsi1-host {
>>>> +		...
>>>> +
>>>> +		ports {
>>>> +			...
>>>> +
>>>> +			port {
>>>> +				dsi1_out: endpoint {
>>>> +					remote-endpoint = <&dsi1_in>;
>>>> +				};
>>>> +			};
>>>> +		};
>>>> +	};
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm"
>>> in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> 
>
Heiko Stübner June 6, 2018, 10:46 a.m. UTC | #7
Hi Archit,

Am Mittwoch, 6. Juni 2018, 12:21:16 CEST schrieb Archit Taneja:
> On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
> > Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
> >> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
> >>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
> >>>> Add binding info for peripherals that support dual-channel DSI. Add
> >>>> corresponding optional bindings for DSI host controllers that may
> >>>> be configured in this mode. Add an example of an I2C controlled
> >>>> device operating in dual-channel DSI mode.
> >>>> 
> >>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> >>> 
> >>> Looks like a great solution for that problem, so
> >>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
> >>> 
> >>> As I'm looking into that for my rk3399-scarlet device right now and
> >>> couldn't find this patchset in the kernel yet, is it planned to
> >>> merge or refresh these binding changes or were problems encountered.
> >>> 
> >>> At least an Ack/Review from Rob seems to be missing.
> >> 
> >> I forgot about these patches. Rob had reviewed the first one in
> >> the set the second one still needed an Ack. I'll post a v3
> >> that adds the Reviewed-bys and fixes a small typo.
> > 
> > very nice ... because it looks like yesterday I managed to make the
> > Rockchip dsi work in dual mode following this.
> > 
> > But one question came up, do you really want two input ports on the panel
> > side? I.e. hardware-wise, I guess the panel will have one 8-lane or so
> > input thatonly gets split up on the soc side onto 2 dsi controllers?
> 
> I think all dual DSI panels actually have 2 DSI controllers/parsers
> within them, one on each port. The MIPI DSI spec doesn't support 8
> lanes. Also, the pixels coming out of the host are distributed among
> the lanes differently than what would have been the case with a
> 'theoretical' 8 lane receiver.
> 
> Other than that, some dual DSI panels only accept DSI commands on the
> 'master' port, where as others expect the same command to be sent across
> both the ports.
> 
> Therefore, I think it's better to represent dual DSI panels having 2
> DSI input ports.
> 
> Your DT looks good to me.

Hmm, that doesn't match up then ;-) ... as my dt uses 2 endpoints
in one port for the dsi-links.

The issue I see with using ports and not endpoints for dual-dsi links
is with distinguishing between input and output ports.

For a panel that's easy, as you every port will be an input port and if
you have 2, it's supposed dual-dsi. But for example I guess there might
exist some dual-dsi-to-something bridges, where you would end up
with say 3 (or even more) ports ... two dual-dsi inputs and 1 or more
outputs.


While the following argument might not be 100% valid from a dt-purity
standpoint implementing this might get hairy for _any_ operating system,
as you will need each panel/bridge to tell what the ports are used for.

I.e. in my endpoint based mapping, right now I have this nice and generic
WIP function to parse the of_graph and get the master+slave nodes:

https://github.com/mmind/linux-rockchip/blob/tmp/rk3399-gru-bob-scarlet/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c#L697
[0]

So I guess my proposal would be to have one port for inputs
and one port for outputs for dsi peripherals, with possibly
multiple endpoints in each.


Heiko


[0] github seems to have reliability problems, so for reference my
parsing function:

static int dw_mipi_dsi_is_dual(struct dw_mipi_dsi_rockchip *dsi,
			struct device_node **master, struct device_node **slave)
{
	struct device_node *local_ep, *remote_port, *ep;
	struct device_node *ctrls[2] = { NULL, NULL };
	int num = 0, ret = 0, idx;

	/* get local panel endpoint of the dsi controller */
	local_ep = of_graph_get_endpoint_by_regs(dsi->dev->of_node, 1, 0);
	if (!local_ep) {
		DRM_DEV_ERROR(dsi->dev, "couldn't find local panel endpoint\n");
		return -ENXIO;
	}

	/* get panel port */
	remote_port = of_graph_get_remote_port_parent(local_ep);
	of_node_put(local_ep);
	if (!remote_port) {
		DRM_DEV_ERROR(dsi->dev, "couldn't find panel port\n");
		return -ENXIO;
	}

	/* check other endpoints */
	for_each_endpoint_of_node(remote_port, ep) {
		struct device_node *np = of_graph_get_remote_port_parent(ep);

		if (!np)
			continue;

		idx = of_property_read_bool(np, "clock-master");

		/*
		 * Either master or slave already defined, drop refcnt
		 * but catch errors only after the full loop.
		 */
		if (ctrls[idx])
			of_node_put(np);
		else
			ctrls[idx] = np;

		num++;
	}
	of_node_put(remote_port);

	if (num > 2) {
		DRM_DEV_ERROR(dsi->dev, "too many dsi devices linked\n");
		ret = -EINVAL;
		goto cleanup;
	}

	/* nothing to do */
	if (num < 1) {
		ret = 0;
		goto cleanup;
	}

	if (!ctrls[1]) {
		DRM_DEV_ERROR(dsi->dev, "no master defined in dual-dsi\n");
		ret = -ENODEV;
		goto cleanup;
	}

	if (!ctrls[0]) {
		DRM_DEV_ERROR(dsi->dev, "no slave defined in dual-dsi\n");
		ret = -ENODEV;
		goto cleanup;
	}

	*master = ctrls[1];
	*slave = ctrls[0];

	return 1;

cleanup:
	for (idx = 0; idx < 2; idx++)
		if (ctrls[idx])
			of_node_put(ctrls[idx]);
	return ret;
}

> > So right now I'm operating with a devicetree like
> > 
> > &mipi_dsi {
> > 
> >          status = "okay";
> >          clock-master;
> >          
> >          ports {
> >          
> >                  mipi_out: port@1 {
> >                  
> >                          reg = <1>;
> >                          
> >                          mipi_out_panel: endpoint {
> >                          
> >                                  remote-endpoint = <&mipi_in_panel>;
> >                          
> >                          };
> >                  
> >                  };
> >          
> >          };
> >          
> >          mipi_panel: panel@0 {
> > 		  
> > 		  compatible = "innolux,p097pfg";
> > 		  
> >                  reg = <0>;
> >                  backlight = <&backlight>;
> >                  enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
> >                  pinctrl-names = "default";
> >                  pinctrl-0 = <&display_rst_l>;
> >                  
> >                  port {
> >                  
> >                          #address-cells = <1>;
> >                          #size-cells = <0>;
> >                          
> >                          mipi_in_panel: endpoint@0 {
> >                          
> >                                  reg = <0>;
> >                                  remote-endpoint = <&mipi_out_panel>;
> >                          
> >                          };
> >                          
> >                          mipi1_in_panel: endpoint@1 {
> >                          
> >                                  reg = <1>;
> >                                  remote-endpoint = <&mipi1_out_panel>;
> >                          
> >                          };
> >                  
> >                  };
> >          
> >          };
> > 
> > };
> > 
> > &mipi_dsi1 {
> > 
> >          status = "okay";
> >          
> >          ports {
> >          
> >                  mipi1_out: port@1 {
> >                  
> >                          reg = <1>;
> >                          
> >                          mipi1_out_panel: endpoint {
> >                          
> >                                  remote-endpoint = <&mipi1_in_panel>;
> >                          
> >                          };
> >                  
> >                  };
> >          
> >          };
> > 
> > };
> > 
> > 
> > I guess it is a matter of preference on what reflects the hardware
> > best, so maybe that's Robs call?
> > 
> > 
> > Heiko
> > 
> >>>> ---
> >>>> v2:
> >>>> - Specify that clock-master is a boolean property.
> >>>> - Drop/add unit-address and #*-cells where applicable.
> >>>> 
> >>>>    .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80
> >>>>    ++++++++++++++++++++++ 1 file changed, 80 insertions(+)
> >>>> 
> >>>> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >>>> b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt index
> >>>> 94fb72cb916f..7a3abbedb3fa 100644
> >>>> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >>>> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >>>> 
> >>>> @@ -29,6 +29,13 @@ Required properties:
> >>>>    - #size-cells: Should be 0. There are cases where it makes sense to
> >>>>    use
> >>>>    a
> >>>>    
> >>>>      different value here. See below.
> >>>> 
> >>>> +Optional properties:
> >>>> +- clock-master: boolean. Should be enabled if the host is being used
> >>>> in
> >>>> +  conjunction with another DSI host to drive the same peripheral.
> >>>> Hardware
> >>>> +  supporting such a configuration generally requires the data on both
> >>>> the busses +  to be driven by the same clock. Only the DSI host
> >>>> instance
> >>>> controlling this +  clock should contain this property.
> >>>> +
> >>>> 
> >>>>    DSI peripheral
> >>>>    ==============
> >>>> 
> >>>> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI
> >>>> bus (mostly for the data>>
> >>>> 
> >>>>    path). Connections between such peripherals and a DSI host can be
> >>>>    represented using the graph bindings [1], [2].
> >>>> 
> >>>> +Peripherals that support dual channel DSI
> >>>> +-----------------------------------------
> >>>> +
> >>>> +Peripherals with higher bandwidth requirements can be connected to 2
> >>>> DSI
> >>>> +busses. Each DSI bus/channel drives some portion of the pixel data
> >>>> (generally +left/right half of each line of the display, or even/odd
> >>>> lines of the display). +The graph bindings should be used to represent
> >>>> the multiple DSI busses that are +connected to this peripheral. Each
> >>>> DSI
> >>>> host's output endpoint can be linked to +an input endpoint of the DSI
> >>>> peripheral.
> >>>> +
> >>>> 
> >>>>    [1] Documentation/devicetree/bindings/graph.txt
> >>>>    [2] Documentation/devicetree/bindings/media/video-interfaces.txt
> >>>> 
> >>>> @@ -71,6 +88,8 @@ Examples
> >>>> 
> >>>>      with different virtual channel configurations.
> >>>>    
> >>>>    - (4) is an example of a peripheral on a I2C control bus connected
> >>>>    with
> >>>>    to
> >>>>    
> >>>>      a DSI host using of-graph bindings.
> >>>> 
> >>>> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI
> >>>> peripheral,
> >>>> +  which uses I2C as its primary control bus.
> >>>> 
> >>>>    1)
> >>>>    
> >>>>    	dsi-host {
> >>>> 
> >>>> @@ -153,3 +172,64 @@ Examples
> >>>> 
> >>>>    			};
> >>>>    		
> >>>>    		};
> >>>>    	
> >>>>    	};
> >>>> 
> >>>> +
> >>>> +5)
> >>>> +	i2c-host {
> >>>> +		dsi-bridge@35 {
> >>>> +			compatible = "...";
> >>>> +			reg = <0x35>;
> >>>> +
> >>>> +			ports {
> >>>> +				#address-cells = <1>;
> >>>> +				#size-cells = <0>;
> >>>> +
> >>>> +				port@0 {
> >>>> +					reg = <0>;
> >>>> +					dsi0_in: endpoint {
> >>>> +						remote-endpoint = <&dsi0_out>;
> >>>> +					};
> >>>> +				};
> >>>> +
> >>>> +				port@1 {
> >>>> +					reg = <1>;
> >>>> +					dsi1_in: endpoint {
> >>>> +						remote-endpoint = <&dsi1_out>;
> >>>> +					};
> >>>> +				};
> >>>> +			};
> >>>> +		};
> >>>> +	};
> >>>> +
> >>>> +	dsi0-host {
> >>>> +		...
> >>>> +
> >>>> +		/*
> >>>> +		 * this DSI instance drives the clock for both the host
> >>>> +		 * controllers
> >>>> +		 */
> >>>> +		clock-master;
> >>>> +
> >>>> +		ports {
> >>>> +			...
> >>>> +
> >>>> +			port {
> >>>> +				dsi0_out: endpoint {
> >>>> +					remote-endpoint = <&dsi0_in>;
> >>>> +				};
> >>>> +			};
> >>>> +		};
> >>>> +	};
> >>>> +
> >>>> +	dsi1-host {
> >>>> +		...
> >>>> +
> >>>> +		ports {
> >>>> +			...
> >>>> +
> >>>> +			port {
> >>>> +				dsi1_out: endpoint {
> >>>> +					remote-endpoint = <&dsi1_in>;
> >>>> +				};
> >>>> +			};
> >>>> +		};
> >>>> +	};
> >>> 
> >>> --
> >>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm"
> >>> in
> >>> the body of a message to majordomo@vger.kernel.org
> >>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Archit Taneja June 6, 2018, 4:07 p.m. UTC | #8
On Wednesday 06 June 2018 04:16 PM, Heiko Stübner wrote:
> Hi Archit,
> 
> Am Mittwoch, 6. Juni 2018, 12:21:16 CEST schrieb Archit Taneja:
>> On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
>>> Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
>>>> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
>>>>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
>>>>>> Add binding info for peripherals that support dual-channel DSI. Add
>>>>>> corresponding optional bindings for DSI host controllers that may
>>>>>> be configured in this mode. Add an example of an I2C controlled
>>>>>> device operating in dual-channel DSI mode.
>>>>>>
>>>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>>>>>
>>>>> Looks like a great solution for that problem, so
>>>>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
>>>>>
>>>>> As I'm looking into that for my rk3399-scarlet device right now and
>>>>> couldn't find this patchset in the kernel yet, is it planned to
>>>>> merge or refresh these binding changes or were problems encountered.
>>>>>
>>>>> At least an Ack/Review from Rob seems to be missing.
>>>>
>>>> I forgot about these patches. Rob had reviewed the first one in
>>>> the set the second one still needed an Ack. I'll post a v3
>>>> that adds the Reviewed-bys and fixes a small typo.
>>>
>>> very nice ... because it looks like yesterday I managed to make the
>>> Rockchip dsi work in dual mode following this.
>>>
>>> But one question came up, do you really want two input ports on the panel
>>> side? I.e. hardware-wise, I guess the panel will have one 8-lane or so
>>> input thatonly gets split up on the soc side onto 2 dsi controllers?
>>
>> I think all dual DSI panels actually have 2 DSI controllers/parsers
>> within them, one on each port. The MIPI DSI spec doesn't support 8
>> lanes. Also, the pixels coming out of the host are distributed among
>> the lanes differently than what would have been the case with a
>> 'theoretical' 8 lane receiver.
>>
>> Other than that, some dual DSI panels only accept DSI commands on the
>> 'master' port, where as others expect the same command to be sent across
>> both the ports.
>>
>> Therefore, I think it's better to represent dual DSI panels having 2
>> DSI input ports.
>>
>> Your DT looks good to me.
> 
> Hmm, that doesn't match up then ;-) ... as my dt uses 2 endpoints
> in one port for the dsi-links.
> 

Sorry, I didn't notice you'd created two endpoints within a single port.

I don't think I'm particular about 2 ports vs 1 port with 2 endpoints.
They both seem okay to me as long as we follow it consistently. I'm
myself not 100% sure of how to figure where one should prefer endpoints
over ports. Maybe someone more familiar with the of graph bindings
could comment here.


> The issue I see with using ports and not endpoints for dual-dsi links
> is with distinguishing between input and output ports.
> 
> For a panel that's easy, as you every port will be an input port and if
> you have 2, it's supposed dual-dsi. But for example I guess there might
> exist some dual-dsi-to-something bridges, where you would end up
> with say 3 (or even more) ports ... two dual-dsi inputs and 1 or more
> outputs.

Okay, I get your point here. Although, even if the remote device had
exactly 2 ports. Is it safe to assume that port #0 is an input port and
port #1 is an output port? Is that the norm?

I've at least seen one device (toshiba,tc358767 bridge) that can 
actually take either DPI as input or DSI based on how you configure it.
There are 2 input ports here, port #0 for DSI and port #1 for DPI. Would
it have made sense here to have a single port and 2 endpoints here too?

> 
> 
> While the following argument might not be 100% valid from a dt-purity
> standpoint implementing this might get hairy for _any_ operating system,
> as you will need each panel/bridge to tell what the ports are used for.

Yeah.

> 
> I.e. in my endpoint based mapping, right now I have this nice and generic
> WIP function to parse the of_graph and get the master+slave nodes:
> 
> https://github.com/mmind/linux-rockchip/blob/tmp/rk3399-gru-bob-scarlet/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c#L697
> [0]

I'd tried out something locally before posting this patch, I don't have
the code for it, but I can describe the steps I took. This code expects
the panel/bridge to have 2 input ports.

1. DSI0 host driver looks up its output port, gets the remote endpoint,
and get this endpoint's parent (using
of_graph_get_remote_port_parent()). Keeps the parent device node in a
temp variable.

2. DSI1 host driver does the same thing.

3. DSI0 and DSI1 check whether their outputs are connected to the
same device. If so, they're in dual DSI mode. If not, they are
operating independently.

The positive of this approach is that we don't need to make any
assumptions about the panel/bridge's port numbers, which is great.
The negative is that our DSI controller instances now need to query
each other, which can be messy, but not too hard to implement.

I think the choice finally boils down to what makes more sense w.r.t
representing the HW correctly. We'd need Rob's comment on that.

Thanks,
Archit

> 
> So I guess my proposal would be to have one port for inputs
> and one port for outputs for dsi peripherals, with possibly
> multiple endpoints in each.
> 
> 
> Heiko
> 
> 
> [0] github seems to have reliability problems, so for reference my
> parsing function:
> 
> static int dw_mipi_dsi_is_dual(struct dw_mipi_dsi_rockchip *dsi,
> 			struct device_node **master, struct device_node **slave)
> {
> 	struct device_node *local_ep, *remote_port, *ep;
> 	struct device_node *ctrls[2] = { NULL, NULL };
> 	int num = 0, ret = 0, idx;
> 
> 	/* get local panel endpoint of the dsi controller */
> 	local_ep = of_graph_get_endpoint_by_regs(dsi->dev->of_node, 1, 0);
> 	if (!local_ep) {
> 		DRM_DEV_ERROR(dsi->dev, "couldn't find local panel endpoint\n");
> 		return -ENXIO;
> 	}
> 
> 	/* get panel port */
> 	remote_port = of_graph_get_remote_port_parent(local_ep);
> 	of_node_put(local_ep);
> 	if (!remote_port) {
> 		DRM_DEV_ERROR(dsi->dev, "couldn't find panel port\n");
> 		return -ENXIO;
> 	}
> 
> 	/* check other endpoints */
> 	for_each_endpoint_of_node(remote_port, ep) {
> 		struct device_node *np = of_graph_get_remote_port_parent(ep);
> 
> 		if (!np)
> 			continue;
> 
> 		idx = of_property_read_bool(np, "clock-master");
> 
> 		/*
> 		 * Either master or slave already defined, drop refcnt
> 		 * but catch errors only after the full loop.
> 		 */
> 		if (ctrls[idx])
> 			of_node_put(np);
> 		else
> 			ctrls[idx] = np;
> 
> 		num++;
> 	}
> 	of_node_put(remote_port);
> 
> 	if (num > 2) {
> 		DRM_DEV_ERROR(dsi->dev, "too many dsi devices linked\n");
> 		ret = -EINVAL;
> 		goto cleanup;
> 	}
> 
> 	/* nothing to do */
> 	if (num < 1) {
> 		ret = 0;
> 		goto cleanup;
> 	}
> 
> 	if (!ctrls[1]) {
> 		DRM_DEV_ERROR(dsi->dev, "no master defined in dual-dsi\n");
> 		ret = -ENODEV;
> 		goto cleanup;
> 	}
> 
> 	if (!ctrls[0]) {
> 		DRM_DEV_ERROR(dsi->dev, "no slave defined in dual-dsi\n");
> 		ret = -ENODEV;
> 		goto cleanup;
> 	}
> 
> 	*master = ctrls[1];
> 	*slave = ctrls[0];
> 
> 	return 1;
> 
> cleanup:
> 	for (idx = 0; idx < 2; idx++)
> 		if (ctrls[idx])
> 			of_node_put(ctrls[idx]);
> 	return ret;
> }
> 
>>> So right now I'm operating with a devicetree like
>>>
>>> &mipi_dsi {
>>>
>>>           status = "okay";
>>>           clock-master;
>>>           
>>>           ports {
>>>           
>>>                   mipi_out: port@1 {
>>>                   
>>>                           reg = <1>;
>>>                           
>>>                           mipi_out_panel: endpoint {
>>>                           
>>>                                   remote-endpoint = <&mipi_in_panel>;
>>>                           
>>>                           };
>>>                   
>>>                   };
>>>           
>>>           };
>>>           
>>>           mipi_panel: panel@0 {
>>> 		
>>> 		  compatible = "innolux,p097pfg";
>>> 		
>>>                   reg = <0>;
>>>                   backlight = <&backlight>;
>>>                   enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
>>>                   pinctrl-names = "default";
>>>                   pinctrl-0 = <&display_rst_l>;
>>>                   
>>>                   port {
>>>                   
>>>                           #address-cells = <1>;
>>>                           #size-cells = <0>;
>>>                           
>>>                           mipi_in_panel: endpoint@0 {
>>>                           
>>>                                   reg = <0>;
>>>                                   remote-endpoint = <&mipi_out_panel>;
>>>                           
>>>                           };
>>>                           
>>>                           mipi1_in_panel: endpoint@1 {
>>>                           
>>>                                   reg = <1>;
>>>                                   remote-endpoint = <&mipi1_out_panel>;
>>>                           
>>>                           };
>>>                   
>>>                   };
>>>           
>>>           };
>>>
>>> };
>>>
>>> &mipi_dsi1 {
>>>
>>>           status = "okay";
>>>           
>>>           ports {
>>>           
>>>                   mipi1_out: port@1 {
>>>                   
>>>                           reg = <1>;
>>>                           
>>>                           mipi1_out_panel: endpoint {
>>>                           
>>>                                   remote-endpoint = <&mipi1_in_panel>;
>>>                           
>>>                           };
>>>                   
>>>                   };
>>>           
>>>           };
>>>
>>> };
>>>
>>>
>>> I guess it is a matter of preference on what reflects the hardware
>>> best, so maybe that's Robs call?
>>>
>>>
>>> Heiko
>>>
>>>>>> ---
>>>>>> v2:
>>>>>> - Specify that clock-master is a boolean property.
>>>>>> - Drop/add unit-address and #*-cells where applicable.
>>>>>>
>>>>>>     .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80
>>>>>>     ++++++++++++++++++++++ 1 file changed, 80 insertions(+)
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>>>>>> b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt index
>>>>>> 94fb72cb916f..7a3abbedb3fa 100644
>>>>>> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>>>>>> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>>>>>>
>>>>>> @@ -29,6 +29,13 @@ Required properties:
>>>>>>     - #size-cells: Should be 0. There are cases where it makes sense to
>>>>>>     use
>>>>>>     a
>>>>>>     
>>>>>>       different value here. See below.
>>>>>>
>>>>>> +Optional properties:
>>>>>> +- clock-master: boolean. Should be enabled if the host is being used
>>>>>> in
>>>>>> +  conjunction with another DSI host to drive the same peripheral.
>>>>>> Hardware
>>>>>> +  supporting such a configuration generally requires the data on both
>>>>>> the busses +  to be driven by the same clock. Only the DSI host
>>>>>> instance
>>>>>> controlling this +  clock should contain this property.
>>>>>> +
>>>>>>
>>>>>>     DSI peripheral
>>>>>>     ==============
>>>>>>
>>>>>> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI
>>>>>> bus (mostly for the data>>
>>>>>>
>>>>>>     path). Connections between such peripherals and a DSI host can be
>>>>>>     represented using the graph bindings [1], [2].
>>>>>>
>>>>>> +Peripherals that support dual channel DSI
>>>>>> +-----------------------------------------
>>>>>> +
>>>>>> +Peripherals with higher bandwidth requirements can be connected to 2
>>>>>> DSI
>>>>>> +busses. Each DSI bus/channel drives some portion of the pixel data
>>>>>> (generally +left/right half of each line of the display, or even/odd
>>>>>> lines of the display). +The graph bindings should be used to represent
>>>>>> the multiple DSI busses that are +connected to this peripheral. Each
>>>>>> DSI
>>>>>> host's output endpoint can be linked to +an input endpoint of the DSI
>>>>>> peripheral.
>>>>>> +
>>>>>>
>>>>>>     [1] Documentation/devicetree/bindings/graph.txt
>>>>>>     [2] Documentation/devicetree/bindings/media/video-interfaces.txt
>>>>>>
>>>>>> @@ -71,6 +88,8 @@ Examples
>>>>>>
>>>>>>       with different virtual channel configurations.
>>>>>>     
>>>>>>     - (4) is an example of a peripheral on a I2C control bus connected
>>>>>>     with
>>>>>>     to
>>>>>>     
>>>>>>       a DSI host using of-graph bindings.
>>>>>>
>>>>>> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI
>>>>>> peripheral,
>>>>>> +  which uses I2C as its primary control bus.
>>>>>>
>>>>>>     1)
>>>>>>     
>>>>>>     	dsi-host {
>>>>>>
>>>>>> @@ -153,3 +172,64 @@ Examples
>>>>>>
>>>>>>     			};
>>>>>>     		
>>>>>>     		};
>>>>>>     	
>>>>>>     	};
>>>>>>
>>>>>> +
>>>>>> +5)
>>>>>> +	i2c-host {
>>>>>> +		dsi-bridge@35 {
>>>>>> +			compatible = "...";
>>>>>> +			reg = <0x35>;
>>>>>> +
>>>>>> +			ports {
>>>>>> +				#address-cells = <1>;
>>>>>> +				#size-cells = <0>;
>>>>>> +
>>>>>> +				port@0 {
>>>>>> +					reg = <0>;
>>>>>> +					dsi0_in: endpoint {
>>>>>> +						remote-endpoint = <&dsi0_out>;
>>>>>> +					};
>>>>>> +				};
>>>>>> +
>>>>>> +				port@1 {
>>>>>> +					reg = <1>;
>>>>>> +					dsi1_in: endpoint {
>>>>>> +						remote-endpoint = <&dsi1_out>;
>>>>>> +					};
>>>>>> +				};
>>>>>> +			};
>>>>>> +		};
>>>>>> +	};
>>>>>> +
>>>>>> +	dsi0-host {
>>>>>> +		...
>>>>>> +
>>>>>> +		/*
>>>>>> +		 * this DSI instance drives the clock for both the host
>>>>>> +		 * controllers
>>>>>> +		 */
>>>>>> +		clock-master;
>>>>>> +
>>>>>> +		ports {
>>>>>> +			...
>>>>>> +
>>>>>> +			port {
>>>>>> +				dsi0_out: endpoint {
>>>>>> +					remote-endpoint = <&dsi0_in>;
>>>>>> +				};
>>>>>> +			};
>>>>>> +		};
>>>>>> +	};
>>>>>> +
>>>>>> +	dsi1-host {
>>>>>> +		...
>>>>>> +
>>>>>> +		ports {
>>>>>> +			...
>>>>>> +
>>>>>> +			port {
>>>>>> +				dsi1_out: endpoint {
>>>>>> +					remote-endpoint = <&dsi1_in>;
>>>>>> +				};
>>>>>> +			};
>>>>>> +		};
>>>>>> +	};
>>>>>
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm"
>>>>> in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
Heiko Stübner June 6, 2018, 11:08 p.m. UTC | #9
Am Mittwoch, 6. Juni 2018, 18:07:46 CEST schrieb Archit Taneja:
> 
> On Wednesday 06 June 2018 04:16 PM, Heiko Stübner wrote:
> > Hi Archit,
> > 
> > Am Mittwoch, 6. Juni 2018, 12:21:16 CEST schrieb Archit Taneja:
> >> On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
> >>> Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
> >>>> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
> >>>>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
> >>>>>> Add binding info for peripherals that support dual-channel DSI. Add
> >>>>>> corresponding optional bindings for DSI host controllers that may
> >>>>>> be configured in this mode. Add an example of an I2C controlled
> >>>>>> device operating in dual-channel DSI mode.
> >>>>>>
> >>>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> >>>>>
> >>>>> Looks like a great solution for that problem, so
> >>>>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
> >>>>>
> >>>>> As I'm looking into that for my rk3399-scarlet device right now and
> >>>>> couldn't find this patchset in the kernel yet, is it planned to
> >>>>> merge or refresh these binding changes or were problems encountered.
> >>>>>
> >>>>> At least an Ack/Review from Rob seems to be missing.
> >>>>
> >>>> I forgot about these patches. Rob had reviewed the first one in
> >>>> the set the second one still needed an Ack. I'll post a v3
> >>>> that adds the Reviewed-bys and fixes a small typo.
> >>>
> >>> very nice ... because it looks like yesterday I managed to make the
> >>> Rockchip dsi work in dual mode following this.
> >>>
> >>> But one question came up, do you really want two input ports on the panel
> >>> side? I.e. hardware-wise, I guess the panel will have one 8-lane or so
> >>> input thatonly gets split up on the soc side onto 2 dsi controllers?
> >>
> >> I think all dual DSI panels actually have 2 DSI controllers/parsers
> >> within them, one on each port. The MIPI DSI spec doesn't support 8
> >> lanes. Also, the pixels coming out of the host are distributed among
> >> the lanes differently than what would have been the case with a
> >> 'theoretical' 8 lane receiver.
> >>
> >> Other than that, some dual DSI panels only accept DSI commands on the
> >> 'master' port, where as others expect the same command to be sent across
> >> both the ports.
> >>
> >> Therefore, I think it's better to represent dual DSI panels having 2
> >> DSI input ports.
> >>
> >> Your DT looks good to me.
> > 
> > Hmm, that doesn't match up then ;-) ... as my dt uses 2 endpoints
> > in one port for the dsi-links.
> > 
> 
> Sorry, I didn't notice you'd created two endpoints within a single port.
> 
> I don't think I'm particular about 2 ports vs 1 port with 2 endpoints.
> They both seem okay to me as long as we follow it consistently. I'm
> myself not 100% sure of how to figure where one should prefer endpoints
> over ports. Maybe someone more familiar with the of graph bindings
> could comment here.
> 
> 
> > The issue I see with using ports and not endpoints for dual-dsi links
> > is with distinguishing between input and output ports.
> > 
> > For a panel that's easy, as you every port will be an input port and if
> > you have 2, it's supposed dual-dsi. But for example I guess there might
> > exist some dual-dsi-to-something bridges, where you would end up
> > with say 3 (or even more) ports ... two dual-dsi inputs and 1 or more
> > outputs.
> 
> Okay, I get your point here. Although, even if the remote device had
> exactly 2 ports. Is it safe to assume that port #0 is an input port and
> port #1 is an output port? Is that the norm?

I don't think that anything like that is specified anywhere, so you cannot
assume anything about what a port contains.


> I've at least seen one device (toshiba,tc358767 bridge) that can 
> actually take either DPI as input or DSI based on how you configure it.
> There are 2 input ports here, port #0 for DSI and port #1 for DPI. Would
> it have made sense here to have a single port and 2 endpoints here too?

Nope, I guess having a port for DPI input, one port for DSI input makes
quite a lot of sense. And then you can have the input-specifics living in
the endpoints like dual links or so.


> > While the following argument might not be 100% valid from a dt-purity
> > standpoint implementing this might get hairy for _any_ operating system,
> > as you will need each panel/bridge to tell what the ports are used for.
> 
> Yeah.
> 
> > 
> > I.e. in my endpoint based mapping, right now I have this nice and generic
> > WIP function to parse the of_graph and get the master+slave nodes:
> > 
> > https://github.com/mmind/linux-rockchip/blob/tmp/rk3399-gru-bob-scarlet/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c#L697
> > [0]
> 
> I'd tried out something locally before posting this patch, I don't have
> the code for it, but I can describe the steps I took. This code expects
> the panel/bridge to have 2 input ports.

Which again would be very much panel-specific as you cannot assume
to much about the ports.


> 1. DSI0 host driver looks up its output port, gets the remote endpoint,
> and get this endpoint's parent (using
> of_graph_get_remote_port_parent()). Keeps the parent device node in a
> temp variable.
> 
> 2. DSI1 host driver does the same thing.
> 
> 3. DSI0 and DSI1 check whether their outputs are connected to the
> same device. If so, they're in dual DSI mode. If not, they are
> operating independently.
> 
> The positive of this approach is that we don't need to make any
> assumptions about the panel/bridge's port numbers, which is great.
> The negative is that our DSI controller instances now need to query
> each other, which can be messy, but not too hard to implement.
> 
> I think the choice finally boils down to what makes more sense w.r.t
> representing the HW correctly. We'd need Rob's comment on that.

Taking your DPI+DSI example from above actually shows quite nicely
how ports+endpoints could play together.

panel-or-bridge@0 {
	compatible = "something,something";
	reg = <0>;

	ports {
		/* DPI input */
		port@0 {
			endpoint {
				remote-endpoint = <&dpi_out>;
			};
		};

		/* DSI input */
		port@1 {
			/* from first dsi controller */
			endpoint@0 {
				remote-endpoint = <&dsi0_out>;
			};

			/* from second dsi controller */
			endpoint@1 {
				remote-endpoint = <&dsi1_out>;
			};
		};

		/* another input, or an output for a bridge */
		port@2 {
			endpoint {
				remote-endpoint = <&somewhere>;
			}
		};
	};
};

But yeah, hopefully we can entice Rob for comments :-) .

Heiko

> Thanks,
> Archit
> 
> > 
> > So I guess my proposal would be to have one port for inputs
> > and one port for outputs for dsi peripherals, with possibly
> > multiple endpoints in each.
> > 
> > 
> > Heiko
> > 
> > 
> > [0] github seems to have reliability problems, so for reference my
> > parsing function:
> > 
> > static int dw_mipi_dsi_is_dual(struct dw_mipi_dsi_rockchip *dsi,
> > 			struct device_node **master, struct device_node **slave)
> > {
> > 	struct device_node *local_ep, *remote_port, *ep;
> > 	struct device_node *ctrls[2] = { NULL, NULL };
> > 	int num = 0, ret = 0, idx;
> > 
> > 	/* get local panel endpoint of the dsi controller */
> > 	local_ep = of_graph_get_endpoint_by_regs(dsi->dev->of_node, 1, 0);
> > 	if (!local_ep) {
> > 		DRM_DEV_ERROR(dsi->dev, "couldn't find local panel endpoint\n");
> > 		return -ENXIO;
> > 	}
> > 
> > 	/* get panel port */
> > 	remote_port = of_graph_get_remote_port_parent(local_ep);
> > 	of_node_put(local_ep);
> > 	if (!remote_port) {
> > 		DRM_DEV_ERROR(dsi->dev, "couldn't find panel port\n");
> > 		return -ENXIO;
> > 	}
> > 
> > 	/* check other endpoints */
> > 	for_each_endpoint_of_node(remote_port, ep) {
> > 		struct device_node *np = of_graph_get_remote_port_parent(ep);
> > 
> > 		if (!np)
> > 			continue;
> > 
> > 		idx = of_property_read_bool(np, "clock-master");
> > 
> > 		/*
> > 		 * Either master or slave already defined, drop refcnt
> > 		 * but catch errors only after the full loop.
> > 		 */
> > 		if (ctrls[idx])
> > 			of_node_put(np);
> > 		else
> > 			ctrls[idx] = np;
> > 
> > 		num++;
> > 	}
> > 	of_node_put(remote_port);
> > 
> > 	if (num > 2) {
> > 		DRM_DEV_ERROR(dsi->dev, "too many dsi devices linked\n");
> > 		ret = -EINVAL;
> > 		goto cleanup;
> > 	}
> > 
> > 	/* nothing to do */
> > 	if (num < 1) {
> > 		ret = 0;
> > 		goto cleanup;
> > 	}
> > 
> > 	if (!ctrls[1]) {
> > 		DRM_DEV_ERROR(dsi->dev, "no master defined in dual-dsi\n");
> > 		ret = -ENODEV;
> > 		goto cleanup;
> > 	}
> > 
> > 	if (!ctrls[0]) {
> > 		DRM_DEV_ERROR(dsi->dev, "no slave defined in dual-dsi\n");
> > 		ret = -ENODEV;
> > 		goto cleanup;
> > 	}
> > 
> > 	*master = ctrls[1];
> > 	*slave = ctrls[0];
> > 
> > 	return 1;
> > 
> > cleanup:
> > 	for (idx = 0; idx < 2; idx++)
> > 		if (ctrls[idx])
> > 			of_node_put(ctrls[idx]);
> > 	return ret;
> > }
> > 
> >>> So right now I'm operating with a devicetree like
> >>>
> >>> &mipi_dsi {
> >>>
> >>>           status = "okay";
> >>>           clock-master;
> >>>           
> >>>           ports {
> >>>           
> >>>                   mipi_out: port@1 {
> >>>                   
> >>>                           reg = <1>;
> >>>                           
> >>>                           mipi_out_panel: endpoint {
> >>>                           
> >>>                                   remote-endpoint = <&mipi_in_panel>;
> >>>                           
> >>>                           };
> >>>                   
> >>>                   };
> >>>           
> >>>           };
> >>>           
> >>>           mipi_panel: panel@0 {
> >>> 		
> >>> 		  compatible = "innolux,p097pfg";
> >>> 		
> >>>                   reg = <0>;
> >>>                   backlight = <&backlight>;
> >>>                   enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
> >>>                   pinctrl-names = "default";
> >>>                   pinctrl-0 = <&display_rst_l>;
> >>>                   
> >>>                   port {
> >>>                   
> >>>                           #address-cells = <1>;
> >>>                           #size-cells = <0>;
> >>>                           
> >>>                           mipi_in_panel: endpoint@0 {
> >>>                           
> >>>                                   reg = <0>;
> >>>                                   remote-endpoint = <&mipi_out_panel>;
> >>>                           
> >>>                           };
> >>>                           
> >>>                           mipi1_in_panel: endpoint@1 {
> >>>                           
> >>>                                   reg = <1>;
> >>>                                   remote-endpoint = <&mipi1_out_panel>;
> >>>                           
> >>>                           };
> >>>                   
> >>>                   };
> >>>           
> >>>           };
> >>>
> >>> };
> >>>
> >>> &mipi_dsi1 {
> >>>
> >>>           status = "okay";
> >>>           
> >>>           ports {
> >>>           
> >>>                   mipi1_out: port@1 {
> >>>                   
> >>>                           reg = <1>;
> >>>                           
> >>>                           mipi1_out_panel: endpoint {
> >>>                           
> >>>                                   remote-endpoint = <&mipi1_in_panel>;
> >>>                           
> >>>                           };
> >>>                   
> >>>                   };
> >>>           
> >>>           };
> >>>
> >>> };
> >>>
> >>>
> >>> I guess it is a matter of preference on what reflects the hardware
> >>> best, so maybe that's Robs call?
> >>>
> >>>
> >>> Heiko
> >>>
> >>>>>> ---
> >>>>>> v2:
> >>>>>> - Specify that clock-master is a boolean property.
> >>>>>> - Drop/add unit-address and #*-cells where applicable.
> >>>>>>
> >>>>>>     .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80
> >>>>>>     ++++++++++++++++++++++ 1 file changed, 80 insertions(+)
> >>>>>>
> >>>>>> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >>>>>> b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt index
> >>>>>> 94fb72cb916f..7a3abbedb3fa 100644
> >>>>>> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >>>>>> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >>>>>>
> >>>>>> @@ -29,6 +29,13 @@ Required properties:
> >>>>>>     - #size-cells: Should be 0. There are cases where it makes sense to
> >>>>>>     use
> >>>>>>     a
> >>>>>>     
> >>>>>>       different value here. See below.
> >>>>>>
> >>>>>> +Optional properties:
> >>>>>> +- clock-master: boolean. Should be enabled if the host is being used
> >>>>>> in
> >>>>>> +  conjunction with another DSI host to drive the same peripheral.
> >>>>>> Hardware
> >>>>>> +  supporting such a configuration generally requires the data on both
> >>>>>> the busses +  to be driven by the same clock. Only the DSI host
> >>>>>> instance
> >>>>>> controlling this +  clock should contain this property.
> >>>>>> +
> >>>>>>
> >>>>>>     DSI peripheral
> >>>>>>     ==============
> >>>>>>
> >>>>>> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI
> >>>>>> bus (mostly for the data>>
> >>>>>>
> >>>>>>     path). Connections between such peripherals and a DSI host can be
> >>>>>>     represented using the graph bindings [1], [2].
> >>>>>>
> >>>>>> +Peripherals that support dual channel DSI
> >>>>>> +-----------------------------------------
> >>>>>> +
> >>>>>> +Peripherals with higher bandwidth requirements can be connected to 2
> >>>>>> DSI
> >>>>>> +busses. Each DSI bus/channel drives some portion of the pixel data
> >>>>>> (generally +left/right half of each line of the display, or even/odd
> >>>>>> lines of the display). +The graph bindings should be used to represent
> >>>>>> the multiple DSI busses that are +connected to this peripheral. Each
> >>>>>> DSI
> >>>>>> host's output endpoint can be linked to +an input endpoint of the DSI
> >>>>>> peripheral.
> >>>>>> +
> >>>>>>
> >>>>>>     [1] Documentation/devicetree/bindings/graph.txt
> >>>>>>     [2] Documentation/devicetree/bindings/media/video-interfaces.txt
> >>>>>>
> >>>>>> @@ -71,6 +88,8 @@ Examples
> >>>>>>
> >>>>>>       with different virtual channel configurations.
> >>>>>>     
> >>>>>>     - (4) is an example of a peripheral on a I2C control bus connected
> >>>>>>     with
> >>>>>>     to
> >>>>>>     
> >>>>>>       a DSI host using of-graph bindings.
> >>>>>>
> >>>>>> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI
> >>>>>> peripheral,
> >>>>>> +  which uses I2C as its primary control bus.
> >>>>>>
> >>>>>>     1)
> >>>>>>     
> >>>>>>     	dsi-host {
> >>>>>>
> >>>>>> @@ -153,3 +172,64 @@ Examples
> >>>>>>
> >>>>>>     			};
> >>>>>>     		
> >>>>>>     		};
> >>>>>>     	
> >>>>>>     	};
> >>>>>>
> >>>>>> +
> >>>>>> +5)
> >>>>>> +	i2c-host {
> >>>>>> +		dsi-bridge@35 {
> >>>>>> +			compatible = "...";
> >>>>>> +			reg = <0x35>;
> >>>>>> +
> >>>>>> +			ports {
> >>>>>> +				#address-cells = <1>;
> >>>>>> +				#size-cells = <0>;
> >>>>>> +
> >>>>>> +				port@0 {
> >>>>>> +					reg = <0>;
> >>>>>> +					dsi0_in: endpoint {
> >>>>>> +						remote-endpoint = <&dsi0_out>;
> >>>>>> +					};
> >>>>>> +				};
> >>>>>> +
> >>>>>> +				port@1 {
> >>>>>> +					reg = <1>;
> >>>>>> +					dsi1_in: endpoint {
> >>>>>> +						remote-endpoint = <&dsi1_out>;
> >>>>>> +					};
> >>>>>> +				};
> >>>>>> +			};
> >>>>>> +		};
> >>>>>> +	};
> >>>>>> +
> >>>>>> +	dsi0-host {
> >>>>>> +		...
> >>>>>> +
> >>>>>> +		/*
> >>>>>> +		 * this DSI instance drives the clock for both the host
> >>>>>> +		 * controllers
> >>>>>> +		 */
> >>>>>> +		clock-master;
> >>>>>> +
> >>>>>> +		ports {
> >>>>>> +			...
> >>>>>> +
> >>>>>> +			port {
> >>>>>> +				dsi0_out: endpoint {
> >>>>>> +					remote-endpoint = <&dsi0_in>;
> >>>>>> +				};
> >>>>>> +			};
> >>>>>> +		};
> >>>>>> +	};
> >>>>>> +
> >>>>>> +	dsi1-host {
> >>>>>> +		...
> >>>>>> +
> >>>>>> +		ports {
> >>>>>> +			...
> >>>>>> +
> >>>>>> +			port {
> >>>>>> +				dsi1_out: endpoint {
> >>>>>> +					remote-endpoint = <&dsi1_in>;
> >>>>>> +				};
> >>>>>> +			};
> >>>>>> +		};
> >>>>>> +	};
> >>>>>
> >>>>> --
> >>>>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm"
> >>>>> in
> >>>>> the body of a message to majordomo@vger.kernel.org
> >>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> > 
> > 
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> 
>
Andrzej Hajda June 7, 2018, 10:39 a.m. UTC | #10
On 07.06.2018 01:08, Heiko Stuebner wrote:
> Am Mittwoch, 6. Juni 2018, 18:07:46 CEST schrieb Archit Taneja:
>> On Wednesday 06 June 2018 04:16 PM, Heiko Stübner wrote:
>>> Hi Archit,
>>>
>>> Am Mittwoch, 6. Juni 2018, 12:21:16 CEST schrieb Archit Taneja:
>>>> On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
>>>>> Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
>>>>>> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
>>>>>>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
>>>>>>>> Add binding info for peripherals that support dual-channel DSI. Add
>>>>>>>> corresponding optional bindings for DSI host controllers that may
>>>>>>>> be configured in this mode. Add an example of an I2C controlled
>>>>>>>> device operating in dual-channel DSI mode.
>>>>>>>>
>>>>>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>>>>>>> Looks like a great solution for that problem, so
>>>>>>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
>>>>>>>
>>>>>>> As I'm looking into that for my rk3399-scarlet device right now and
>>>>>>> couldn't find this patchset in the kernel yet, is it planned to
>>>>>>> merge or refresh these binding changes or were problems encountered.
>>>>>>>
>>>>>>> At least an Ack/Review from Rob seems to be missing.
>>>>>> I forgot about these patches. Rob had reviewed the first one in
>>>>>> the set the second one still needed an Ack. I'll post a v3
>>>>>> that adds the Reviewed-bys and fixes a small typo.
>>>>> very nice ... because it looks like yesterday I managed to make the
>>>>> Rockchip dsi work in dual mode following this.
>>>>>
>>>>> But one question came up, do you really want two input ports on the panel
>>>>> side? I.e. hardware-wise, I guess the panel will have one 8-lane or so
>>>>> input thatonly gets split up on the soc side onto 2 dsi controllers?
>>>> I think all dual DSI panels actually have 2 DSI controllers/parsers
>>>> within them, one on each port. The MIPI DSI spec doesn't support 8
>>>> lanes. Also, the pixels coming out of the host are distributed among
>>>> the lanes differently than what would have been the case with a
>>>> 'theoretical' 8 lane receiver.
>>>>
>>>> Other than that, some dual DSI panels only accept DSI commands on the
>>>> 'master' port, where as others expect the same command to be sent across
>>>> both the ports.
>>>>
>>>> Therefore, I think it's better to represent dual DSI panels having 2
>>>> DSI input ports.
>>>>
>>>> Your DT looks good to me.
>>> Hmm, that doesn't match up then ;-) ... as my dt uses 2 endpoints
>>> in one port for the dsi-links.
>>>
>> Sorry, I didn't notice you'd created two endpoints within a single port.
>>
>> I don't think I'm particular about 2 ports vs 1 port with 2 endpoints.
>> They both seem okay to me as long as we follow it consistently. I'm
>> myself not 100% sure of how to figure where one should prefer endpoints
>> over ports. Maybe someone more familiar with the of graph bindings
>> could comment here.

Port should describe physical port, endpoint are used to describe
multiple links to the same port. If the panel has two physical DSI
interfaces it should use two ports.


>>
>>
>>> The issue I see with using ports and not endpoints for dual-dsi links
>>> is with distinguishing between input and output ports.
>>>
>>> For a panel that's easy, as you every port will be an input port and if
>>> you have 2, it's supposed dual-dsi. But for example I guess there might
>>> exist some dual-dsi-to-something bridges, where you would end up
>>> with say 3 (or even more) ports ... two dual-dsi inputs and 1 or more
>>> outputs.
>> Okay, I get your point here. Although, even if the remote device had
>> exactly 2 ports. Is it safe to assume that port #0 is an input port and
>> port #1 is an output port? Is that the norm?
> I don't think that anything like that is specified anywhere, so you cannot
> assume anything about what a port contains.

Ports are defined per device-node and port number assignment should be
described in particular device bindings. So device driver knows well
which functions should be assigned to which port. But it is private
matter of the device/device driver. Different device bindings can assign
different number for input and output ports, but since ports are private
thing for devices it should not be a problem.

I do not see why do you have such issue, could you describe it more.

>
>
>> I've at least seen one device (toshiba,tc358767 bridge) that can 
>> actually take either DPI as input or DSI based on how you configure it.
>> There are 2 input ports here, port #0 for DSI and port #1 for DPI. Would
>> it have made sense here to have a single port and 2 endpoints here too?
> Nope, I guess having a port for DPI input, one port for DSI input makes
> quite a lot of sense. And then you can have the input-specifics living in
> the endpoints like dual links or so.
>
>
>>> While the following argument might not be 100% valid from a dt-purity
>>> standpoint implementing this might get hairy for _any_ operating system,
>>> as you will need each panel/bridge to tell what the ports are used for.
>> Yeah.

Each panel/bridge should know what his ports are used for, but to who
and why you want to communicate it?


>>
>>> I.e. in my endpoint based mapping, right now I have this nice and generic
>>> WIP function to parse the of_graph and get the master+slave nodes:
>>>
>>> https://github.com/mmind/linux-rockchip/blob/tmp/rk3399-gru-bob-scarlet/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c#L697
>>> [0]
>> I'd tried out something locally before posting this patch, I don't have
>> the code for it, but I can describe the steps I took. This code expects
>> the panel/bridge to have 2 input ports.
> Which again would be very much panel-specific as you cannot assume
> to much about the ports.
>
>
>> 1. DSI0 host driver looks up its output port, gets the remote endpoint,
>> and get this endpoint's parent (using
>> of_graph_get_remote_port_parent()). Keeps the parent device node in a
>> temp variable.
>>
>> 2. DSI1 host driver does the same thing.
>>
>> 3. DSI0 and DSI1 check whether their outputs are connected to the
>> same device. If so, they're in dual DSI mode. If not, they are
>> operating independently.
>>
>> The positive of this approach is that we don't need to make any
>> assumptions about the panel/bridge's port numbers, which is great.
>> The negative is that our DSI controller instances now need to query
>> each other, which can be messy, but not too hard to implement.

I think detection of dual dsi and whole configuration thing of dual-dsi
should be done using in-kernel frameworks (maybe new ones :) ).
Could you describe necessary configuration steps to be performed, what
info should be passed from who to who, etc. It would be easier to discuss.

Anyway I think there are rules which probably we should always (almost)
obey:
1. one port per interface, if it is control port it could be probably
omitted.
2. device drivers should only look into their private nodes, nodes
pointed by remote-endpoints should be used only/mainly for
identification of in-kernel objects exposed by in-kernel frameworks.

Regards
Andrzej

>>
>> I think the choice finally boils down to what makes more sense w.r.t
>> representing the HW correctly. We'd need Rob's comment on that.
> Taking your DPI+DSI example from above actually shows quite nicely
> how ports+endpoints could play together.
>
> panel-or-bridge@0 {
> 	compatible = "something,something";
> 	reg = <0>;
>
> 	ports {
> 		/* DPI input */
> 		port@0 {
> 			endpoint {
> 				remote-endpoint = <&dpi_out>;
> 			};
> 		};
>
> 		/* DSI input */
> 		port@1 {
> 			/* from first dsi controller */
> 			endpoint@0 {
> 				remote-endpoint = <&dsi0_out>;
> 			};
>
> 			/* from second dsi controller */
> 			endpoint@1 {
> 				remote-endpoint = <&dsi1_out>;
> 			};
> 		};
>
> 		/* another input, or an output for a bridge */
> 		port@2 {
> 			endpoint {
> 				remote-endpoint = <&somewhere>;
> 			}
> 		};
> 	};
> };
>
> But yeah, hopefully we can entice Rob for comments :-) .
>
> Heiko
>
>> Thanks,
>> Archit
>>
>>> So I guess my proposal would be to have one port for inputs
>>> and one port for outputs for dsi peripherals, with possibly
>>> multiple endpoints in each.
>>>
>>>
>>> Heiko
>>>
>>>
>>> [0] github seems to have reliability problems, so for reference my
>>> parsing function:
>>>
>>> static int dw_mipi_dsi_is_dual(struct dw_mipi_dsi_rockchip *dsi,
>>> 			struct device_node **master, struct device_node **slave)
>>> {
>>> 	struct device_node *local_ep, *remote_port, *ep;
>>> 	struct device_node *ctrls[2] = { NULL, NULL };
>>> 	int num = 0, ret = 0, idx;
>>>
>>> 	/* get local panel endpoint of the dsi controller */
>>> 	local_ep = of_graph_get_endpoint_by_regs(dsi->dev->of_node, 1, 0);
>>> 	if (!local_ep) {
>>> 		DRM_DEV_ERROR(dsi->dev, "couldn't find local panel endpoint\n");
>>> 		return -ENXIO;
>>> 	}
>>>
>>> 	/* get panel port */
>>> 	remote_port = of_graph_get_remote_port_parent(local_ep);
>>> 	of_node_put(local_ep);
>>> 	if (!remote_port) {
>>> 		DRM_DEV_ERROR(dsi->dev, "couldn't find panel port\n");
>>> 		return -ENXIO;
>>> 	}
>>>
>>> 	/* check other endpoints */
>>> 	for_each_endpoint_of_node(remote_port, ep) {
>>> 		struct device_node *np = of_graph_get_remote_port_parent(ep);
>>>
>>> 		if (!np)
>>> 			continue;
>>>
>>> 		idx = of_property_read_bool(np, "clock-master");
>>>
>>> 		/*
>>> 		 * Either master or slave already defined, drop refcnt
>>> 		 * but catch errors only after the full loop.
>>> 		 */
>>> 		if (ctrls[idx])
>>> 			of_node_put(np);
>>> 		else
>>> 			ctrls[idx] = np;
>>>
>>> 		num++;
>>> 	}
>>> 	of_node_put(remote_port);
>>>
>>> 	if (num > 2) {
>>> 		DRM_DEV_ERROR(dsi->dev, "too many dsi devices linked\n");
>>> 		ret = -EINVAL;
>>> 		goto cleanup;
>>> 	}
>>>
>>> 	/* nothing to do */
>>> 	if (num < 1) {
>>> 		ret = 0;
>>> 		goto cleanup;
>>> 	}
>>>
>>> 	if (!ctrls[1]) {
>>> 		DRM_DEV_ERROR(dsi->dev, "no master defined in dual-dsi\n");
>>> 		ret = -ENODEV;
>>> 		goto cleanup;
>>> 	}
>>>
>>> 	if (!ctrls[0]) {
>>> 		DRM_DEV_ERROR(dsi->dev, "no slave defined in dual-dsi\n");
>>> 		ret = -ENODEV;
>>> 		goto cleanup;
>>> 	}
>>>
>>> 	*master = ctrls[1];
>>> 	*slave = ctrls[0];
>>>
>>> 	return 1;
>>>
>>> cleanup:
>>> 	for (idx = 0; idx < 2; idx++)
>>> 		if (ctrls[idx])
>>> 			of_node_put(ctrls[idx]);
>>> 	return ret;
>>> }
>>>
>>>>> So right now I'm operating with a devicetree like
>>>>>
>>>>> &mipi_dsi {
>>>>>
>>>>>           status = "okay";
>>>>>           clock-master;
>>>>>           
>>>>>           ports {
>>>>>           
>>>>>                   mipi_out: port@1 {
>>>>>                   
>>>>>                           reg = <1>;
>>>>>                           
>>>>>                           mipi_out_panel: endpoint {
>>>>>                           
>>>>>                                   remote-endpoint = <&mipi_in_panel>;
>>>>>                           
>>>>>                           };
>>>>>                   
>>>>>                   };
>>>>>           
>>>>>           };
>>>>>           
>>>>>           mipi_panel: panel@0 {
>>>>> 		
>>>>> 		  compatible = "innolux,p097pfg";
>>>>> 		
>>>>>                   reg = <0>;
>>>>>                   backlight = <&backlight>;
>>>>>                   enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
>>>>>                   pinctrl-names = "default";
>>>>>                   pinctrl-0 = <&display_rst_l>;
>>>>>                   
>>>>>                   port {
>>>>>                   
>>>>>                           #address-cells = <1>;
>>>>>                           #size-cells = <0>;
>>>>>                           
>>>>>                           mipi_in_panel: endpoint@0 {
>>>>>                           
>>>>>                                   reg = <0>;
>>>>>                                   remote-endpoint = <&mipi_out_panel>;
>>>>>                           
>>>>>                           };
>>>>>                           
>>>>>                           mipi1_in_panel: endpoint@1 {
>>>>>                           
>>>>>                                   reg = <1>;
>>>>>                                   remote-endpoint = <&mipi1_out_panel>;
>>>>>                           
>>>>>                           };
>>>>>                   
>>>>>                   };
>>>>>           
>>>>>           };
>>>>>
>>>>> };
>>>>>
>>>>> &mipi_dsi1 {
>>>>>
>>>>>           status = "okay";
>>>>>           
>>>>>           ports {
>>>>>           
>>>>>                   mipi1_out: port@1 {
>>>>>                   
>>>>>                           reg = <1>;
>>>>>                           
>>>>>                           mipi1_out_panel: endpoint {
>>>>>                           
>>>>>                                   remote-endpoint = <&mipi1_in_panel>;
>>>>>                           
>>>>>                           };
>>>>>                   
>>>>>                   };
>>>>>           
>>>>>           };
>>>>>
>>>>> };
>>>>>
>>>>>
>>>>> I guess it is a matter of preference on what reflects the hardware
>>>>> best, so maybe that's Robs call?
>>>>>
>>>>>
>>>>> Heiko
>>>>>
>>>>>>>> ---
>>>>>>>> v2:
>>>>>>>> - Specify that clock-master is a boolean property.
>>>>>>>> - Drop/add unit-address and #*-cells where applicable.
>>>>>>>>
>>>>>>>>     .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80
>>>>>>>>     ++++++++++++++++++++++ 1 file changed, 80 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>>>>>>>> b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt index
>>>>>>>> 94fb72cb916f..7a3abbedb3fa 100644
>>>>>>>> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>>>>>>>> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
>>>>>>>>
>>>>>>>> @@ -29,6 +29,13 @@ Required properties:
>>>>>>>>     - #size-cells: Should be 0. There are cases where it makes sense to
>>>>>>>>     use
>>>>>>>>     a
>>>>>>>>     
>>>>>>>>       different value here. See below.
>>>>>>>>
>>>>>>>> +Optional properties:
>>>>>>>> +- clock-master: boolean. Should be enabled if the host is being used
>>>>>>>> in
>>>>>>>> +  conjunction with another DSI host to drive the same peripheral.
>>>>>>>> Hardware
>>>>>>>> +  supporting such a configuration generally requires the data on both
>>>>>>>> the busses +  to be driven by the same clock. Only the DSI host
>>>>>>>> instance
>>>>>>>> controlling this +  clock should contain this property.
>>>>>>>> +
>>>>>>>>
>>>>>>>>     DSI peripheral
>>>>>>>>     ==============
>>>>>>>>
>>>>>>>> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI
>>>>>>>> bus (mostly for the data>>
>>>>>>>>
>>>>>>>>     path). Connections between such peripherals and a DSI host can be
>>>>>>>>     represented using the graph bindings [1], [2].
>>>>>>>>
>>>>>>>> +Peripherals that support dual channel DSI
>>>>>>>> +-----------------------------------------
>>>>>>>> +
>>>>>>>> +Peripherals with higher bandwidth requirements can be connected to 2
>>>>>>>> DSI
>>>>>>>> +busses. Each DSI bus/channel drives some portion of the pixel data
>>>>>>>> (generally +left/right half of each line of the display, or even/odd
>>>>>>>> lines of the display). +The graph bindings should be used to represent
>>>>>>>> the multiple DSI busses that are +connected to this peripheral. Each
>>>>>>>> DSI
>>>>>>>> host's output endpoint can be linked to +an input endpoint of the DSI
>>>>>>>> peripheral.
>>>>>>>> +
>>>>>>>>
>>>>>>>>     [1] Documentation/devicetree/bindings/graph.txt
>>>>>>>>     [2] Documentation/devicetree/bindings/media/video-interfaces.txt
>>>>>>>>
>>>>>>>> @@ -71,6 +88,8 @@ Examples
>>>>>>>>
>>>>>>>>       with different virtual channel configurations.
>>>>>>>>     
>>>>>>>>     - (4) is an example of a peripheral on a I2C control bus connected
>>>>>>>>     with
>>>>>>>>     to
>>>>>>>>     
>>>>>>>>       a DSI host using of-graph bindings.
>>>>>>>>
>>>>>>>> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI
>>>>>>>> peripheral,
>>>>>>>> +  which uses I2C as its primary control bus.
>>>>>>>>
>>>>>>>>     1)
>>>>>>>>     
>>>>>>>>     	dsi-host {
>>>>>>>>
>>>>>>>> @@ -153,3 +172,64 @@ Examples
>>>>>>>>
>>>>>>>>     			};
>>>>>>>>     		
>>>>>>>>     		};
>>>>>>>>     	
>>>>>>>>     	};
>>>>>>>>
>>>>>>>> +
>>>>>>>> +5)
>>>>>>>> +	i2c-host {
>>>>>>>> +		dsi-bridge@35 {
>>>>>>>> +			compatible = "...";
>>>>>>>> +			reg = <0x35>;
>>>>>>>> +
>>>>>>>> +			ports {
>>>>>>>> +				#address-cells = <1>;
>>>>>>>> +				#size-cells = <0>;
>>>>>>>> +
>>>>>>>> +				port@0 {
>>>>>>>> +					reg = <0>;
>>>>>>>> +					dsi0_in: endpoint {
>>>>>>>> +						remote-endpoint = <&dsi0_out>;
>>>>>>>> +					};
>>>>>>>> +				};
>>>>>>>> +
>>>>>>>> +				port@1 {
>>>>>>>> +					reg = <1>;
>>>>>>>> +					dsi1_in: endpoint {
>>>>>>>> +						remote-endpoint = <&dsi1_out>;
>>>>>>>> +					};
>>>>>>>> +				};
>>>>>>>> +			};
>>>>>>>> +		};
>>>>>>>> +	};
>>>>>>>> +
>>>>>>>> +	dsi0-host {
>>>>>>>> +		...
>>>>>>>> +
>>>>>>>> +		/*
>>>>>>>> +		 * this DSI instance drives the clock for both the host
>>>>>>>> +		 * controllers
>>>>>>>> +		 */
>>>>>>>> +		clock-master;
>>>>>>>> +
>>>>>>>> +		ports {
>>>>>>>> +			...
>>>>>>>> +
>>>>>>>> +			port {
>>>>>>>> +				dsi0_out: endpoint {
>>>>>>>> +					remote-endpoint = <&dsi0_in>;
>>>>>>>> +				};
>>>>>>>> +			};
>>>>>>>> +		};
>>>>>>>> +	};
>>>>>>>> +
>>>>>>>> +	dsi1-host {
>>>>>>>> +		...
>>>>>>>> +
>>>>>>>> +		ports {
>>>>>>>> +			...
>>>>>>>> +
>>>>>>>> +			port {
>>>>>>>> +				dsi1_out: endpoint {
>>>>>>>> +					remote-endpoint = <&dsi1_in>;
>>>>>>>> +				};
>>>>>>>> +			};
>>>>>>>> +		};
>>>>>>>> +	};
>>>>>>> --
>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm"
>>>>>>> in
>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>>
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>
>
>
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
Heiko Stübner June 7, 2018, 1:25 p.m. UTC | #11
Hi Andrzej,

Am Donnerstag, 7. Juni 2018, 12:39:03 CEST schrieb Andrzej Hajda:
> On 07.06.2018 01:08, Heiko Stuebner wrote:
> > Am Mittwoch, 6. Juni 2018, 18:07:46 CEST schrieb Archit Taneja:
> >> On Wednesday 06 June 2018 04:16 PM, Heiko Stübner wrote:
> >>> Hi Archit,
> >>> 
> >>> Am Mittwoch, 6. Juni 2018, 12:21:16 CEST schrieb Archit Taneja:
> >>>> On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
> >>>>> Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
> >>>>>> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
> >>>>>>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
> >>>>>>>> Add binding info for peripherals that support dual-channel DSI. Add
> >>>>>>>> corresponding optional bindings for DSI host controllers that may
> >>>>>>>> be configured in this mode. Add an example of an I2C controlled
> >>>>>>>> device operating in dual-channel DSI mode.
> >>>>>>>> 
> >>>>>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> >>>>>>> 
> >>>>>>> Looks like a great solution for that problem, so
> >>>>>>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
> >>>>>>> 
> >>>>>>> As I'm looking into that for my rk3399-scarlet device right now and
> >>>>>>> couldn't find this patchset in the kernel yet, is it planned to
> >>>>>>> merge or refresh these binding changes or were problems encountered.
> >>>>>>> 
> >>>>>>> At least an Ack/Review from Rob seems to be missing.
> >>>>>> 
> >>>>>> I forgot about these patches. Rob had reviewed the first one in
> >>>>>> the set the second one still needed an Ack. I'll post a v3
> >>>>>> that adds the Reviewed-bys and fixes a small typo.
> >>>>> 
> >>>>> very nice ... because it looks like yesterday I managed to make the
> >>>>> Rockchip dsi work in dual mode following this.
> >>>>> 
> >>>>> But one question came up, do you really want two input ports on the
> >>>>> panel
> >>>>> side? I.e. hardware-wise, I guess the panel will have one 8-lane or so
> >>>>> input thatonly gets split up on the soc side onto 2 dsi controllers?
> >>>> 
> >>>> I think all dual DSI panels actually have 2 DSI controllers/parsers
> >>>> within them, one on each port. The MIPI DSI spec doesn't support 8
> >>>> lanes. Also, the pixels coming out of the host are distributed among
> >>>> the lanes differently than what would have been the case with a
> >>>> 'theoretical' 8 lane receiver.
> >>>> 
> >>>> Other than that, some dual DSI panels only accept DSI commands on the
> >>>> 'master' port, where as others expect the same command to be sent
> >>>> across
> >>>> both the ports.
> >>>> 
> >>>> Therefore, I think it's better to represent dual DSI panels having 2
> >>>> DSI input ports.
> >>>> 
> >>>> Your DT looks good to me.
> >>> 
> >>> Hmm, that doesn't match up then ;-) ... as my dt uses 2 endpoints
> >>> in one port for the dsi-links.
> >> 
> >> Sorry, I didn't notice you'd created two endpoints within a single port.
> >> 
> >> I don't think I'm particular about 2 ports vs 1 port with 2 endpoints.
> >> They both seem okay to me as long as we follow it consistently. I'm
> >> myself not 100% sure of how to figure where one should prefer endpoints
> >> over ports. Maybe someone more familiar with the of graph bindings
> >> could comment here.
> 
> Port should describe physical port, endpoint are used to describe
> multiple links to the same port. If the panel has two physical DSI
> interfaces it should use two ports.

That again leaves a bit of space for interpretation ;-) .

A dual-dsi display is probably pretty useless with only one controller
connected to it, as its 4 lanes cannot satisfy the required 8 lanes
of the panel.

See [0] for current WIP panel addition.
[Was already on the lists but needs cleanup]



[0] https://github.com/mmind/linux-rockchip/commit/459bc1a1599377c2c5408724e82619a4602a953d#diff-5d6d6ddab4fd282102d23d2c02e835f8R381


> >>> The issue I see with using ports and not endpoints for dual-dsi links
> >>> is with distinguishing between input and output ports.
> >>> 
> >>> For a panel that's easy, as you every port will be an input port and if
> >>> you have 2, it's supposed dual-dsi. But for example I guess there might
> >>> exist some dual-dsi-to-something bridges, where you would end up
> >>> with say 3 (or even more) ports ... two dual-dsi inputs and 1 or more
> >>> outputs.
> >> 
> >> Okay, I get your point here. Although, even if the remote device had
> >> exactly 2 ports. Is it safe to assume that port #0 is an input port and
> >> port #1 is an output port? Is that the norm?
> > 
> > I don't think that anything like that is specified anywhere, so you cannot
> > assume anything about what a port contains.
> 
> Ports are defined per device-node and port number assignment should be
> described in particular device bindings. So device driver knows well
> which functions should be assigned to which port. But it is private
> matter of the device/device driver. Different device bindings can assign
> different number for input and output ports, but since ports are private
> thing for devices it should not be a problem.
> 
> I do not see why do you have such issue, could you describe it more.
> 
> >> I've at least seen one device (toshiba,tc358767 bridge) that can
> >> actually take either DPI as input or DSI based on how you configure it.
> >> There are 2 input ports here, port #0 for DSI and port #1 for DPI. Would
> >> it have made sense here to have a single port and 2 endpoints here too?
> > 
> > Nope, I guess having a port for DPI input, one port for DSI input makes
> > quite a lot of sense. And then you can have the input-specifics living in
> > the endpoints like dual links or so.
> > 
> >>> While the following argument might not be 100% valid from a dt-purity
> >>> standpoint implementing this might get hairy for _any_ operating system,
> >>> as you will need each panel/bridge to tell what the ports are used for.
> >> 
> >> Yeah.
> 
> Each panel/bridge should know what his ports are used for, but to who
> and why you want to communicate it?

I'll do that below :-)


> >>> I.e. in my endpoint based mapping, right now I have this nice and
> >>> generic
> >>> WIP function to parse the of_graph and get the master+slave nodes:
> >>> 
> >>> https://github.com/mmind/linux-rockchip/blob/tmp/rk3399-gru-bob-scarlet/
> >>> drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c#L697 [0]
> >> 
> >> I'd tried out something locally before posting this patch, I don't have
> >> the code for it, but I can describe the steps I took. This code expects
> >> the panel/bridge to have 2 input ports.
> > 
> > Which again would be very much panel-specific as you cannot assume
> > to much about the ports.
> > 
> >> 1. DSI0 host driver looks up its output port, gets the remote endpoint,
> >> and get this endpoint's parent (using
> >> of_graph_get_remote_port_parent()). Keeps the parent device node in a
> >> temp variable.
> >> 
> >> 2. DSI1 host driver does the same thing.
> >> 
> >> 3. DSI0 and DSI1 check whether their outputs are connected to the
> >> same device. If so, they're in dual DSI mode. If not, they are
> >> operating independently.
> >> 
> >> The positive of this approach is that we don't need to make any
> >> assumptions about the panel/bridge's port numbers, which is great.
> >> The negative is that our DSI controller instances now need to query
> >> each other, which can be messy, but not too hard to implement.
> 
> I think detection of dual dsi and whole configuration thing of dual-dsi
> should be done using in-kernel frameworks (maybe new ones :) ).
> Could you describe necessary configuration steps to be performed, what
> info should be passed from who to who, etc. It would be easier to discuss.

The base setup is the rk3399 soc, which has 2 completely separate
dw-mipi-dsi controllers.

Gru-Scarlet (a ChromeOS tablet device) uses a high-res dual-DSI display
(2500x1500 pixels or so) which is driven by both controllers together to
achieve the required number of lanes to it.

So you end up with one (specific) controller being the master and the
other being the slave, deferring to the master for most everything.
As the controllers are somehow build to work together in that case
via special soc-specific settings.

See [1] for current WIP code, I lifted out of the chromeos kernel and
modified to not have that special rockchip,dual-channel =<&...>; property.
That patch was on the lists already last year I think.

So each dw-mipi-dsi instance needs to at least know that it is in a
master-slave-relationship and right now also needs access to the other
driver instance. Doing the master->slave access should be fine in that
special case, as the IP is the same type.

Also the crtc<->dsi interaction is quite a bit of handling-different between
one crtc talking to 2 DSIs or 2 crtc talking to the 2 DSIs separately.


Heiko

[1] https://github.com/mmind/linux-rockchip/commits/tmp/rk3399-gru-bob-scarlet




> Anyway I think there are rules which probably we should always (almost)
> obey:
> 1. one port per interface, if it is control port it could be probably
> omitted.
> 2. device drivers should only look into their private nodes, nodes
> pointed by remote-endpoints should be used only/mainly for
> identification of in-kernel objects exposed by in-kernel frameworks.
Brian Norris June 7, 2018, 9:10 p.m. UTC | #12
Hi,

I only have a little bit to add, but Heiko did solicit my opinion.

On Thu, Jun 07, 2018 at 03:25:18PM +0200, Heiko Stuebner wrote:
> Am Donnerstag, 7. Juni 2018, 12:39:03 CEST schrieb Andrzej Hajda:
> > On 07.06.2018 01:08, Heiko Stuebner wrote:
> > > Am Mittwoch, 6. Juni 2018, 18:07:46 CEST schrieb Archit Taneja:
> > >> On Wednesday 06 June 2018 04:16 PM, Heiko Stübner wrote:
> > >>> Am Mittwoch, 6. Juni 2018, 12:21:16 CEST schrieb Archit Taneja:
> > >>>> On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
> > >>>>> Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
> > >>>>>> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
> > >>>>>>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
> > >>>>>>>> Add binding info for peripherals that support dual-channel DSI. Add
> > >>>>>>>> corresponding optional bindings for DSI host controllers that may
> > >>>>>>>> be configured in this mode. Add an example of an I2C controlled
> > >>>>>>>> device operating in dual-channel DSI mode.
> > >>>>>>>> 
> > >>>>>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> > >>>>>>> 
> > >>>>>>> Looks like a great solution for that problem, so
> > >>>>>>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
> > >>>>>>> 
> > >>>>>>> As I'm looking into that for my rk3399-scarlet device right now and
> > >>>>>>> couldn't find this patchset in the kernel yet, is it planned to
> > >>>>>>> merge or refresh these binding changes or were problems encountered.
> > >>>>>>> 
> > >>>>>>> At least an Ack/Review from Rob seems to be missing.
> > >>>>>> 
> > >>>>>> I forgot about these patches. Rob had reviewed the first one in
> > >>>>>> the set the second one still needed an Ack. I'll post a v3
> > >>>>>> that adds the Reviewed-bys and fixes a small typo.
> > >>>>> 
> > >>>>> very nice ... because it looks like yesterday I managed to make the
> > >>>>> Rockchip dsi work in dual mode following this.
> > >>>>> 
> > >>>>> But one question came up, do you really want two input ports on the
> > >>>>> panel
> > >>>>> side? I.e. hardware-wise, I guess the panel will have one 8-lane or so
> > >>>>> input thatonly gets split up on the soc side onto 2 dsi controllers?
> > >>>> 
> > >>>> I think all dual DSI panels actually have 2 DSI controllers/parsers
> > >>>> within them, one on each port. The MIPI DSI spec doesn't support 8
> > >>>> lanes. Also, the pixels coming out of the host are distributed among
> > >>>> the lanes differently than what would have been the case with a
> > >>>> 'theoretical' 8 lane receiver.
> > >>>> 
> > >>>> Other than that, some dual DSI panels only accept DSI commands on the
> > >>>> 'master' port, where as others expect the same command to be sent
> > >>>> across
> > >>>> both the ports.
> > >>>> 
> > >>>> Therefore, I think it's better to represent dual DSI panels having 2
> > >>>> DSI input ports.
> > >>>> 
> > >>>> Your DT looks good to me.
> > >>> 
> > >>> Hmm, that doesn't match up then ;-) ... as my dt uses 2 endpoints
> > >>> in one port for the dsi-links.
> > >> 
> > >> Sorry, I didn't notice you'd created two endpoints within a single port.
> > >> 
> > >> I don't think I'm particular about 2 ports vs 1 port with 2 endpoints.
> > >> They both seem okay to me as long as we follow it consistently. I'm
> > >> myself not 100% sure of how to figure where one should prefer endpoints
> > >> over ports. Maybe someone more familiar with the of graph bindings
> > >> could comment here.
> > 
> > Port should describe physical port, endpoint are used to describe
> > multiple links to the same port. If the panel has two physical DSI
> > interfaces it should use two ports.
> 
> That again leaves a bit of space for interpretation ;-) .

Does it really? DSI maxes out at 4 lanes, so more than 4 lanes is
clearly not a single standard port. Additionally, the code we're
currently using in Chrome OS actually sends the same commands to each
DSI separately (I'm not sure if it's actually required by the panels
were using), so again, they are to some extent logically independent.

> A dual-dsi display is probably pretty useless with only one controller
> connected to it, as its 4 lanes cannot satisfy the required 8 lanes
> of the panel.

Probably, although technically you can usually display on half the
screen, if you have only have 1 working DSI.

> See [0] for current WIP panel addition.
> [Was already on the lists but needs cleanup]
> 
> 
> 
> [0] https://github.com/mmind/linux-rockchip/commit/459bc1a1599377c2c5408724e82619a4602a953d#diff-5d6d6ddab4fd282102d23d2c02e835f8R381
> 
> 
> > >>> The issue I see with using ports and not endpoints for dual-dsi links
> > >>> is with distinguishing between input and output ports.
> > >>> 
> > >>> For a panel that's easy, as you every port will be an input port and if
> > >>> you have 2, it's supposed dual-dsi. But for example I guess there might
> > >>> exist some dual-dsi-to-something bridges, where you would end up
> > >>> with say 3 (or even more) ports ... two dual-dsi inputs and 1 or more
> > >>> outputs.
> > >> 
> > >> Okay, I get your point here. Although, even if the remote device had
> > >> exactly 2 ports. Is it safe to assume that port #0 is an input port and
> > >> port #1 is an output port? Is that the norm?
> > > 
> > > I don't think that anything like that is specified anywhere, so you cannot
> > > assume anything about what a port contains.
> > 
> > Ports are defined per device-node and port number assignment should be
> > described in particular device bindings. So device driver knows well
> > which functions should be assigned to which port. But it is private
> > matter of the device/device driver. Different device bindings can assign
> > different number for input and output ports, but since ports are private
> > thing for devices it should not be a problem.

Agreed. And if Heiko needs a specific example close to home: all the
Rockchip display bindings do this similarly; for example
display/rockchip/analogix_dp-rockchip.txt describes exactly which port
numbers and enpoints mean what:

- ports: there are 2 port nodes with endpoint definitions as defined in
  Documentation/devicetree/bindings/media/video-interfaces.txt.
    Port 0: contained 2 endpoints, connecting to the output of vop.
    Port 1: contained 1 endpoint, connecting to the input of panel.

> > I do not see why do you have such issue, could you describe it more.
> > 
> > >> I've at least seen one device (toshiba,tc358767 bridge) that can
> > >> actually take either DPI as input or DSI based on how you configure it.
> > >> There are 2 input ports here, port #0 for DSI and port #1 for DPI. Would
> > >> it have made sense here to have a single port and 2 endpoints here too?
> > > 
> > > Nope, I guess having a port for DPI input, one port for DSI input makes
> > > quite a lot of sense. And then you can have the input-specifics living in
> > > the endpoints like dual links or so.
> > > 
> > >>> While the following argument might not be 100% valid from a dt-purity
> > >>> standpoint implementing this might get hairy for _any_ operating system,
> > >>> as you will need each panel/bridge to tell what the ports are used for.
> > >> 
> > >> Yeah.
> > 
> > Each panel/bridge should know what his ports are used for, but to who
> > and why you want to communicate it?
> 
> I'll do that below :-)
> 
> 
> > >>> I.e. in my endpoint based mapping, right now I have this nice and
> > >>> generic
> > >>> WIP function to parse the of_graph and get the master+slave nodes:
> > >>> 
> > >>> https://github.com/mmind/linux-rockchip/blob/tmp/rk3399-gru-bob-scarlet/
> > >>> drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c#L697 [0]
> > >> 
> > >> I'd tried out something locally before posting this patch, I don't have
> > >> the code for it, but I can describe the steps I took. This code expects
> > >> the panel/bridge to have 2 input ports.
> > > 
> > > Which again would be very much panel-specific as you cannot assume
> > > to much about the ports.
> > > 
> > >> 1. DSI0 host driver looks up its output port, gets the remote endpoint,
> > >> and get this endpoint's parent (using
> > >> of_graph_get_remote_port_parent()). Keeps the parent device node in a
> > >> temp variable.
> > >> 
> > >> 2. DSI1 host driver does the same thing.
> > >> 
> > >> 3. DSI0 and DSI1 check whether their outputs are connected to the
> > >> same device. If so, they're in dual DSI mode. If not, they are
> > >> operating independently.
> > >> 
> > >> The positive of this approach is that we don't need to make any
> > >> assumptions about the panel/bridge's port numbers, which is great.
> > >> The negative is that our DSI controller instances now need to query
> > >> each other, which can be messy, but not too hard to implement.
> > 
> > I think detection of dual dsi and whole configuration thing of dual-dsi
> > should be done using in-kernel frameworks (maybe new ones :) ).
> > Could you describe necessary configuration steps to be performed, what
> > info should be passed from who to who, etc. It would be easier to discuss.
> 
> The base setup is the rk3399 soc, which has 2 completely separate
> dw-mipi-dsi controllers.
> 
> Gru-Scarlet (a ChromeOS tablet device) uses a high-res dual-DSI display
> (2500x1500 pixels or so) which is driven by both controllers together to
> achieve the required number of lanes to it.
> 
> So you end up with one (specific) controller being the master and the
> other being the slave, deferring to the master for most everything.
> As the controllers are somehow build to work together in that case
> via special soc-specific settings.
> 
> See [1] for current WIP code, I lifted out of the chromeos kernel and
> modified to not have that special rockchip,dual-channel =<&...>; property.
> That patch was on the lists already last year I think.
> 
> So each dw-mipi-dsi instance needs to at least know that it is in a
> master-slave-relationship and right now also needs access to the other
> driver instance. Doing the master->slave access should be fine in that
> special case, as the IP is the same type.
> 
> Also the crtc<->dsi interaction is quite a bit of handling-different between
> one crtc talking to 2 DSIs or 2 crtc talking to the 2 DSIs separately.

That's probably the bigger key: to treat them as completely separate
ports means that you get separate CRTCs, IIUC (I'll admit, I'm still a
bit rusty on navigating some DRM concepts).

Brian
Heiko Stübner June 7, 2018, 10:50 p.m. UTC | #13
Am Donnerstag, 7. Juni 2018, 23:10:20 CEST schrieb Brian Norris:
> Hi,
> 
> I only have a little bit to add, but Heiko did solicit my opinion.

yep ... and I realized that I am/was way to attached to my (working)
endpoint-based thingy to really appreciate the other arguments ;-)

And your DSI-related writings below, did provide some new thought-
directions for me, so thanks for that.

> On Thu, Jun 07, 2018 at 03:25:18PM +0200, Heiko Stuebner wrote:
> > Am Donnerstag, 7. Juni 2018, 12:39:03 CEST schrieb Andrzej Hajda:
> > > On 07.06.2018 01:08, Heiko Stuebner wrote:
> > > > Am Mittwoch, 6. Juni 2018, 18:07:46 CEST schrieb Archit Taneja:
> > > >> On Wednesday 06 June 2018 04:16 PM, Heiko Stübner wrote:
> > > >>> Am Mittwoch, 6. Juni 2018, 12:21:16 CEST schrieb Archit Taneja:
> > > >>>> On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
> > > >>>>> Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
> > > >>>>>> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
> > > >>>>>>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
> > > >>>>>>>> Add binding info for peripherals that support dual-channel DSI. Add
> > > >>>>>>>> corresponding optional bindings for DSI host controllers that may
> > > >>>>>>>> be configured in this mode. Add an example of an I2C controlled
> > > >>>>>>>> device operating in dual-channel DSI mode.
> > > >>>>>>>> 
> > > >>>>>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> > > >>>>>>> 
> > > >>>>>>> Looks like a great solution for that problem, so
> > > >>>>>>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
> > > >>>>>>> 
> > > >>>>>>> As I'm looking into that for my rk3399-scarlet device right now and
> > > >>>>>>> couldn't find this patchset in the kernel yet, is it planned to
> > > >>>>>>> merge or refresh these binding changes or were problems encountered.
> > > >>>>>>> 
> > > >>>>>>> At least an Ack/Review from Rob seems to be missing.
> > > >>>>>> 
> > > >>>>>> I forgot about these patches. Rob had reviewed the first one in
> > > >>>>>> the set the second one still needed an Ack. I'll post a v3
> > > >>>>>> that adds the Reviewed-bys and fixes a small typo.
> > > >>>>> 
> > > >>>>> very nice ... because it looks like yesterday I managed to make the
> > > >>>>> Rockchip dsi work in dual mode following this.
> > > >>>>> 
> > > >>>>> But one question came up, do you really want two input ports on the
> > > >>>>> panel
> > > >>>>> side? I.e. hardware-wise, I guess the panel will have one 8-lane or so
> > > >>>>> input thatonly gets split up on the soc side onto 2 dsi controllers?
> > > >>>> 
> > > >>>> I think all dual DSI panels actually have 2 DSI controllers/parsers
> > > >>>> within them, one on each port. The MIPI DSI spec doesn't support 8
> > > >>>> lanes. Also, the pixels coming out of the host are distributed among
> > > >>>> the lanes differently than what would have been the case with a
> > > >>>> 'theoretical' 8 lane receiver.
> > > >>>> 
> > > >>>> Other than that, some dual DSI panels only accept DSI commands on the
> > > >>>> 'master' port, where as others expect the same command to be sent
> > > >>>> across
> > > >>>> both the ports.
> > > >>>> 
> > > >>>> Therefore, I think it's better to represent dual DSI panels having 2
> > > >>>> DSI input ports.
> > > >>>> 
> > > >>>> Your DT looks good to me.
> > > >>> 
> > > >>> Hmm, that doesn't match up then ;-) ... as my dt uses 2 endpoints
> > > >>> in one port for the dsi-links.
> > > >> 
> > > >> Sorry, I didn't notice you'd created two endpoints within a single port.
> > > >> 
> > > >> I don't think I'm particular about 2 ports vs 1 port with 2 endpoints.
> > > >> They both seem okay to me as long as we follow it consistently. I'm
> > > >> myself not 100% sure of how to figure where one should prefer endpoints
> > > >> over ports. Maybe someone more familiar with the of graph bindings
> > > >> could comment here.
> > > 
> > > Port should describe physical port, endpoint are used to describe
> > > multiple links to the same port. If the panel has two physical DSI
> > > interfaces it should use two ports.
> > 
> > That again leaves a bit of space for interpretation ;-) .
> 
> Does it really? DSI maxes out at 4 lanes, so more than 4 lanes is
> clearly not a single standard port. Additionally, the code we're
> currently using in Chrome OS actually sends the same commands to each
> DSI separately (I'm not sure if it's actually required by the panels
> were using), so again, they are to some extent logically independent.
>
> > A dual-dsi display is probably pretty useless with only one controller
> > connected to it, as its 4 lanes cannot satisfy the required 8 lanes
> > of the panel.
> 
> Probably, although technically you can usually display on half the
> screen, if you have only have 1 working DSI.
>
> > See [0] for current WIP panel addition.
> > [Was already on the lists but needs cleanup]
> > 
> > 
> > 
> > [0] https://github.com/mmind/linux-rockchip/commit/459bc1a1599377c2c5408724e82619a4602a953d#diff-5d6d6ddab4fd282102d23d2c02e835f8R381
> > 
> > 
> > > >>> The issue I see with using ports and not endpoints for dual-dsi links
> > > >>> is with distinguishing between input and output ports.
> > > >>> 
> > > >>> For a panel that's easy, as you every port will be an input port and if
> > > >>> you have 2, it's supposed dual-dsi. But for example I guess there might
> > > >>> exist some dual-dsi-to-something bridges, where you would end up
> > > >>> with say 3 (or even more) ports ... two dual-dsi inputs and 1 or more
> > > >>> outputs.
> > > >> 
> > > >> Okay, I get your point here. Although, even if the remote device had
> > > >> exactly 2 ports. Is it safe to assume that port #0 is an input port and
> > > >> port #1 is an output port? Is that the norm?
> > > > 
> > > > I don't think that anything like that is specified anywhere, so you cannot
> > > > assume anything about what a port contains.
> > > 
> > > Ports are defined per device-node and port number assignment should be
> > > described in particular device bindings. So device driver knows well
> > > which functions should be assigned to which port. But it is private
> > > matter of the device/device driver. Different device bindings can assign
> > > different number for input and output ports, but since ports are private
> > > thing for devices it should not be a problem.
> 
> Agreed. And if Heiko needs a specific example close to home: all the
> Rockchip display bindings do this similarly; for example
> display/rockchip/analogix_dp-rockchip.txt describes exactly which port
> numbers and enpoints mean what:
> 
> - ports: there are 2 port nodes with endpoint definitions as defined in
>   Documentation/devicetree/bindings/media/video-interfaces.txt.
>     Port 0: contained 2 endpoints, connecting to the output of vop.
>     Port 1: contained 1 endpoint, connecting to the input of panel.

Agreed here. My confusion stems from the issue that with the way
the code is right now, the dsi controller would need to know how
the ports of the panel are structured, to find its way to the 2nd
controller.

But then again, maybe the implementation just needs to change ;-) .


> > > I do not see why do you have such issue, could you describe it more.
> > > 
> > > >> I've at least seen one device (toshiba,tc358767 bridge) that can
> > > >> actually take either DPI as input or DSI based on how you configure it.
> > > >> There are 2 input ports here, port #0 for DSI and port #1 for DPI. Would
> > > >> it have made sense here to have a single port and 2 endpoints here too?
> > > > 
> > > > Nope, I guess having a port for DPI input, one port for DSI input makes
> > > > quite a lot of sense. And then you can have the input-specifics living in
> > > > the endpoints like dual links or so.
> > > > 
> > > >>> While the following argument might not be 100% valid from a dt-purity
> > > >>> standpoint implementing this might get hairy for _any_ operating system,
> > > >>> as you will need each panel/bridge to tell what the ports are used for.
> > > >> 
> > > >> Yeah.
> > > 
> > > Each panel/bridge should know what his ports are used for, but to who
> > > and why you want to communicate it?
> > 
> > I'll do that below :-)
> > 
> > 
> > > >>> I.e. in my endpoint based mapping, right now I have this nice and
> > > >>> generic
> > > >>> WIP function to parse the of_graph and get the master+slave nodes:
> > > >>> 
> > > >>> https://github.com/mmind/linux-rockchip/blob/tmp/rk3399-gru-bob-scarlet/
> > > >>> drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c#L697 [0]
> > > >> 
> > > >> I'd tried out something locally before posting this patch, I don't have
> > > >> the code for it, but I can describe the steps I took. This code expects
> > > >> the panel/bridge to have 2 input ports.
> > > > 
> > > > Which again would be very much panel-specific as you cannot assume
> > > > to much about the ports.
> > > > 
> > > >> 1. DSI0 host driver looks up its output port, gets the remote endpoint,
> > > >> and get this endpoint's parent (using
> > > >> of_graph_get_remote_port_parent()). Keeps the parent device node in a
> > > >> temp variable.
> > > >> 
> > > >> 2. DSI1 host driver does the same thing.
> > > >> 
> > > >> 3. DSI0 and DSI1 check whether their outputs are connected to the
> > > >> same device. If so, they're in dual DSI mode. If not, they are
> > > >> operating independently.
> > > >> 
> > > >> The positive of this approach is that we don't need to make any
> > > >> assumptions about the panel/bridge's port numbers, which is great.
> > > >> The negative is that our DSI controller instances now need to query
> > > >> each other, which can be messy, but not too hard to implement.
>
> > > I think detection of dual dsi and whole configuration thing of dual-dsi
> > > should be done using in-kernel frameworks (maybe new ones :) ).
> > > Could you describe necessary configuration steps to be performed, what
> > > info should be passed from who to who, etc. It would be easier to discuss.
> > 
> > The base setup is the rk3399 soc, which has 2 completely separate
> > dw-mipi-dsi controllers.
> > 
> > Gru-Scarlet (a ChromeOS tablet device) uses a high-res dual-DSI display
> > (2500x1500 pixels or so) which is driven by both controllers together to
> > achieve the required number of lanes to it.
> > 
> > So you end up with one (specific) controller being the master and the
> > other being the slave, deferring to the master for most everything.
> > As the controllers are somehow build to work together in that case
> > via special soc-specific settings.
> > 
> > See [1] for current WIP code, I lifted out of the chromeos kernel and
> > modified to not have that special rockchip,dual-channel =<&...>; property.
> > That patch was on the lists already last year I think.
> > 
> > So each dw-mipi-dsi instance needs to at least know that it is in a
> > master-slave-relationship and right now also needs access to the other
> > driver instance. Doing the master->slave access should be fine in that
> > special case, as the IP is the same type.
> > 
> > Also the crtc<->dsi interaction is quite a bit of handling-different between
> > one crtc talking to 2 DSIs or 2 crtc talking to the 2 DSIs separately.
> 
> That's probably the bigger key: to treat them as completely separate
> ports means that you get separate CRTCs, IIUC (I'll admit, I'm still a
> bit rusty on navigating some DRM concepts).

One thing I realized with your mention of DSI maxing out at 4 lanes is,
that this makes it easy to detect the existence of a dual-dsi situation ...
simply when the device reports 8 lanes.
(via of_find_mipi_dsi_device_by_node presumably)

As a dual-dsi situation requires a clock-master property in one,
both master and slave also would be able to determine their
master or slave status, thus the global dual-dsi config could be
done by the master (GRF stuff in the Rockchip case)


The only thing that makes my head explode now, is how to
make the slave actually react to settings sent to the master
in a sane way.

But that is a drm-specific implementation-detail, I guess ;-) .
And hopefully someone might have a great idea how this
could be done better than in my current implementation.


Heiko
Andrzej Hajda June 8, 2018, 8:47 a.m. UTC | #14
On 08.06.2018 00:50, Heiko Stuebner wrote:
> Am Donnerstag, 7. Juni 2018, 23:10:20 CEST schrieb Brian Norris:
>> Hi,
>>
>> I only have a little bit to add, but Heiko did solicit my opinion.
> yep ... and I realized that I am/was way to attached to my (working)
> endpoint-based thingy to really appreciate the other arguments ;-)
>
> And your DSI-related writings below, did provide some new thought-
> directions for me, so thanks for that.
>
>> On Thu, Jun 07, 2018 at 03:25:18PM +0200, Heiko Stuebner wrote:
>>> Am Donnerstag, 7. Juni 2018, 12:39:03 CEST schrieb Andrzej Hajda:
>>>> On 07.06.2018 01:08, Heiko Stuebner wrote:
>>>>> Am Mittwoch, 6. Juni 2018, 18:07:46 CEST schrieb Archit Taneja:
>>>>>> On Wednesday 06 June 2018 04:16 PM, Heiko Stübner wrote:
>>>>>>> Am Mittwoch, 6. Juni 2018, 12:21:16 CEST schrieb Archit Taneja:
>>>>>>>> On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
>>>>>>>>> Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
>>>>>>>>>> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
>>>>>>>>>>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
>>>>>>>>>>>> Add binding info for peripherals that support dual-channel DSI. Add
>>>>>>>>>>>> corresponding optional bindings for DSI host controllers that may
>>>>>>>>>>>> be configured in this mode. Add an example of an I2C controlled
>>>>>>>>>>>> device operating in dual-channel DSI mode.
>>>>>>>>>>>>
>>>>>>>>>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>>>>>>>>>>> Looks like a great solution for that problem, so
>>>>>>>>>>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
>>>>>>>>>>>
>>>>>>>>>>> As I'm looking into that for my rk3399-scarlet device right now and
>>>>>>>>>>> couldn't find this patchset in the kernel yet, is it planned to
>>>>>>>>>>> merge or refresh these binding changes or were problems encountered.
>>>>>>>>>>>
>>>>>>>>>>> At least an Ack/Review from Rob seems to be missing.
>>>>>>>>>> I forgot about these patches. Rob had reviewed the first one in
>>>>>>>>>> the set the second one still needed an Ack. I'll post a v3
>>>>>>>>>> that adds the Reviewed-bys and fixes a small typo.
>>>>>>>>> very nice ... because it looks like yesterday I managed to make the
>>>>>>>>> Rockchip dsi work in dual mode following this.
>>>>>>>>>
>>>>>>>>> But one question came up, do you really want two input ports on the
>>>>>>>>> panel
>>>>>>>>> side? I.e. hardware-wise, I guess the panel will have one 8-lane or so
>>>>>>>>> input thatonly gets split up on the soc side onto 2 dsi controllers?
>>>>>>>> I think all dual DSI panels actually have 2 DSI controllers/parsers
>>>>>>>> within them, one on each port. The MIPI DSI spec doesn't support 8
>>>>>>>> lanes. Also, the pixels coming out of the host are distributed among
>>>>>>>> the lanes differently than what would have been the case with a
>>>>>>>> 'theoretical' 8 lane receiver.
>>>>>>>>
>>>>>>>> Other than that, some dual DSI panels only accept DSI commands on the
>>>>>>>> 'master' port, where as others expect the same command to be sent
>>>>>>>> across
>>>>>>>> both the ports.
>>>>>>>>
>>>>>>>> Therefore, I think it's better to represent dual DSI panels having 2
>>>>>>>> DSI input ports.
>>>>>>>>
>>>>>>>> Your DT looks good to me.
>>>>>>> Hmm, that doesn't match up then ;-) ... as my dt uses 2 endpoints
>>>>>>> in one port for the dsi-links.
>>>>>> Sorry, I didn't notice you'd created two endpoints within a single port.
>>>>>>
>>>>>> I don't think I'm particular about 2 ports vs 1 port with 2 endpoints.
>>>>>> They both seem okay to me as long as we follow it consistently. I'm
>>>>>> myself not 100% sure of how to figure where one should prefer endpoints
>>>>>> over ports. Maybe someone more familiar with the of graph bindings
>>>>>> could comment here.
>>>> Port should describe physical port, endpoint are used to describe
>>>> multiple links to the same port. If the panel has two physical DSI
>>>> interfaces it should use two ports.
>>> That again leaves a bit of space for interpretation ;-) .
>> Does it really? DSI maxes out at 4 lanes, so more than 4 lanes is
>> clearly not a single standard port. Additionally, the code we're
>> currently using in Chrome OS actually sends the same commands to each
>> DSI separately (I'm not sure if it's actually required by the panels
>> were using), so again, they are to some extent logically independent.
>>
>>> A dual-dsi display is probably pretty useless with only one controller
>>> connected to it, as its 4 lanes cannot satisfy the required 8 lanes
>>> of the panel.
>> Probably, although technically you can usually display on half the
>> screen, if you have only have 1 working DSI.
>>
>>> See [0] for current WIP panel addition.
>>> [Was already on the lists but needs cleanup]
>>>
>>>
>>>
>>> [0] https://github.com/mmind/linux-rockchip/commit/459bc1a1599377c2c5408724e82619a4602a953d#diff-5d6d6ddab4fd282102d23d2c02e835f8R381
>>>
>>>
>>>>>>> The issue I see with using ports and not endpoints for dual-dsi links
>>>>>>> is with distinguishing between input and output ports.
>>>>>>>
>>>>>>> For a panel that's easy, as you every port will be an input port and if
>>>>>>> you have 2, it's supposed dual-dsi. But for example I guess there might
>>>>>>> exist some dual-dsi-to-something bridges, where you would end up
>>>>>>> with say 3 (or even more) ports ... two dual-dsi inputs and 1 or more
>>>>>>> outputs.
>>>>>> Okay, I get your point here. Although, even if the remote device had
>>>>>> exactly 2 ports. Is it safe to assume that port #0 is an input port and
>>>>>> port #1 is an output port? Is that the norm?
>>>>> I don't think that anything like that is specified anywhere, so you cannot
>>>>> assume anything about what a port contains.
>>>> Ports are defined per device-node and port number assignment should be
>>>> described in particular device bindings. So device driver knows well
>>>> which functions should be assigned to which port. But it is private
>>>> matter of the device/device driver. Different device bindings can assign
>>>> different number for input and output ports, but since ports are private
>>>> thing for devices it should not be a problem.
>> Agreed. And if Heiko needs a specific example close to home: all the
>> Rockchip display bindings do this similarly; for example
>> display/rockchip/analogix_dp-rockchip.txt describes exactly which port
>> numbers and enpoints mean what:
>>
>> - ports: there are 2 port nodes with endpoint definitions as defined in
>>   Documentation/devicetree/bindings/media/video-interfaces.txt.
>>     Port 0: contained 2 endpoints, connecting to the output of vop.
>>     Port 1: contained 1 endpoint, connecting to the input of panel.
> Agreed here. My confusion stems from the issue that with the way
> the code is right now, the dsi controller would need to know how
> the ports of the panel are structured, to find its way to the 2nd
> controller.
>
> But then again, maybe the implementation just needs to change ;-) .
>
>
>>>> I do not see why do you have such issue, could you describe it more.
>>>>
>>>>>> I've at least seen one device (toshiba,tc358767 bridge) that can
>>>>>> actually take either DPI as input or DSI based on how you configure it.
>>>>>> There are 2 input ports here, port #0 for DSI and port #1 for DPI. Would
>>>>>> it have made sense here to have a single port and 2 endpoints here too?
>>>>> Nope, I guess having a port for DPI input, one port for DSI input makes
>>>>> quite a lot of sense. And then you can have the input-specifics living in
>>>>> the endpoints like dual links or so.
>>>>>
>>>>>>> While the following argument might not be 100% valid from a dt-purity
>>>>>>> standpoint implementing this might get hairy for _any_ operating system,
>>>>>>> as you will need each panel/bridge to tell what the ports are used for.
>>>>>> Yeah.
>>>> Each panel/bridge should know what his ports are used for, but to who
>>>> and why you want to communicate it?
>>> I'll do that below :-)
>>>
>>>
>>>>>>> I.e. in my endpoint based mapping, right now I have this nice and
>>>>>>> generic
>>>>>>> WIP function to parse the of_graph and get the master+slave nodes:
>>>>>>>
>>>>>>> https://github.com/mmind/linux-rockchip/blob/tmp/rk3399-gru-bob-scarlet/
>>>>>>> drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c#L697 [0]
>>>>>> I'd tried out something locally before posting this patch, I don't have
>>>>>> the code for it, but I can describe the steps I took. This code expects
>>>>>> the panel/bridge to have 2 input ports.
>>>>> Which again would be very much panel-specific as you cannot assume
>>>>> to much about the ports.
>>>>>
>>>>>> 1. DSI0 host driver looks up its output port, gets the remote endpoint,
>>>>>> and get this endpoint's parent (using
>>>>>> of_graph_get_remote_port_parent()). Keeps the parent device node in a
>>>>>> temp variable.
>>>>>>
>>>>>> 2. DSI1 host driver does the same thing.
>>>>>>
>>>>>> 3. DSI0 and DSI1 check whether their outputs are connected to the
>>>>>> same device. If so, they're in dual DSI mode. If not, they are
>>>>>> operating independently.
>>>>>>
>>>>>> The positive of this approach is that we don't need to make any
>>>>>> assumptions about the panel/bridge's port numbers, which is great.
>>>>>> The negative is that our DSI controller instances now need to query
>>>>>> each other, which can be messy, but not too hard to implement.
>>>> I think detection of dual dsi and whole configuration thing of dual-dsi
>>>> should be done using in-kernel frameworks (maybe new ones :) ).
>>>> Could you describe necessary configuration steps to be performed, what
>>>> info should be passed from who to who, etc. It would be easier to discuss.
>>> The base setup is the rk3399 soc, which has 2 completely separate
>>> dw-mipi-dsi controllers.
>>>
>>> Gru-Scarlet (a ChromeOS tablet device) uses a high-res dual-DSI display
>>> (2500x1500 pixels or so) which is driven by both controllers together to
>>> achieve the required number of lanes to it.
>>>
>>> So you end up with one (specific) controller being the master and the
>>> other being the slave, deferring to the master for most everything.
>>> As the controllers are somehow build to work together in that case
>>> via special soc-specific settings.
>>>
>>> See [1] for current WIP code, I lifted out of the chromeos kernel and
>>> modified to not have that special rockchip,dual-channel =<&...>; property.
>>> That patch was on the lists already last year I think.
>>>
>>> So each dw-mipi-dsi instance needs to at least know that it is in a
>>> master-slave-relationship and right now also needs access to the other
>>> driver instance. Doing the master->slave access should be fine in that
>>> special case, as the IP is the same type.
>>>
>>> Also the crtc<->dsi interaction is quite a bit of handling-different between
>>> one crtc talking to 2 DSIs or 2 crtc talking to the 2 DSIs separately.
>> That's probably the bigger key: to treat them as completely separate
>> ports means that you get separate CRTCs, IIUC (I'll admit, I'm still a
>> bit rusty on navigating some DRM concepts).
> One thing I realized with your mention of DSI maxing out at 4 lanes is,
> that this makes it easy to detect the existence of a dual-dsi situation ...
> simply when the device reports 8 lanes.
> (via of_find_mipi_dsi_device_by_node presumably)

Hmm, device has two DSI interfaces, on each it has 4 lanes, so it report
4 lanes.
There is different problem with current implementation of panel lookup
code - drm_panel is identified by device_node of physical device, as a
result there can be only one panel per device.
I think proper identification should be by device_node of OF graph port,
or by pair: device_node of physical device and port number (practically
it is the same).
I think fixing it should not be a big deal.

>
> As a dual-dsi situation requires a clock-master property in one,
> both master and slave also would be able to determine their
> master or slave status, thus the global dual-dsi config could be
> done by the master (GRF stuff in the Rockchip case)
>
>
> The only thing that makes my head explode now, is how to
> make the slave actually react to settings sent to the master
> in a sane way.

Wouldn't be enough if the panel passes different bus info on DSI0 and DSI1?

Regards
Andrzej

>
> But that is a drm-specific implementation-detail, I guess ;-) .
> And hopefully someone might have a great idea how this
> could be done better than in my current implementation.
>
>
> Heiko
>
>
>
>
>
Heiko Stübner June 11, 2018, 1:47 p.m. UTC | #15
Hi Andrzej et all,

just so we don't discuss in a theoretic way much longer I've just
sent a RFC with my current state of work for the dw-mipi-dsi dual-dsi
support - aka the old "let code speak" ;-)

I've found a somewhat nice way to get from one dsi-controller node
to the node of the other dual-dsi part via separate ports as well.
So no more hackery with endpoints and I can just follow Archit's
dual-dsi binding text.


Am Freitag, 8. Juni 2018, 10:47:05 CEST schrieb Andrzej Hajda:
> On 08.06.2018 00:50, Heiko Stuebner wrote:
> > Am Donnerstag, 7. Juni 2018, 23:10:20 CEST schrieb Brian Norris:
> >> Hi,
> >>
> >> I only have a little bit to add, but Heiko did solicit my opinion.
> > yep ... and I realized that I am/was way to attached to my (working)
> > endpoint-based thingy to really appreciate the other arguments ;-)
> >
> > And your DSI-related writings below, did provide some new thought-
> > directions for me, so thanks for that.

[...]

> >> On Thu, Jun 07, 2018 at 03:25:18PM +0200, Heiko Stuebner wrote:
> >>> Am Donnerstag, 7. Juni 2018, 12:39:03 CEST schrieb Andrzej Hajda:
> >>>> On 07.06.2018 01:08, Heiko Stuebner wrote:
> >>> Also the crtc<->dsi interaction is quite a bit of handling-different between
> >>> one crtc talking to 2 DSIs or 2 crtc talking to the 2 DSIs separately.
> >> That's probably the bigger key: to treat them as completely separate
> >> ports means that you get separate CRTCs, IIUC (I'll admit, I'm still a
> >> bit rusty on navigating some DRM concepts).
> > One thing I realized with your mention of DSI maxing out at 4 lanes is,
> > that this makes it easy to detect the existence of a dual-dsi situation ...
> > simply when the device reports 8 lanes.
> > (via of_find_mipi_dsi_device_by_node presumably)
>
> Hmm, device has two DSI interfaces, on each it has 4 lanes, so it report
> 4 lanes.

Ok ... that is what Tegra seems to do as well. The panel reporting
4 lanes, and this gettings assigned to each of the two dsi controllers.
So I'll need to change that in my v2 as well.


> There is different problem with current implementation of panel lookup
> code - drm_panel is identified by device_node of physical device, as a
> result there can be only one panel per device.
> I think proper identification should be by device_node of OF graph port,
> or by pair: device_node of physical device and port number (practically
> it is the same).
> I think fixing it should not be a big deal.

Right now in my RFC it seems to work without needing changes to panel
types or identification, so I guess we can discuss changes you would like
to see over there.


Heiko

> > As a dual-dsi situation requires a clock-master property in one,
> > both master and slave also would be able to determine their
> > master or slave status, thus the global dual-dsi config could be
> > done by the master (GRF stuff in the Rockchip case)
> >
> >
> > The only thing that makes my head explode now, is how to
> > make the slave actually react to settings sent to the master
> > in a sane way.
> 
> Wouldn't be enough if the panel passes different bus info on DSI0 and DSI1?
> 
> Regards
> Andrzej
> 
> >
> > But that is a drm-specific implementation-detail, I guess ;-) .
> > And hopefully someone might have a great idea how this
> > could be done better than in my current implementation.
> >
> >
> > Heiko
> >
> >
> >
> >
> >
> 
> 
>
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
index 94fb72cb916f..7a3abbedb3fa 100644
--- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
+++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
@@ -29,6 +29,13 @@  Required properties:
 - #size-cells: Should be 0. There are cases where it makes sense to use a
   different value here. See below.
 
+Optional properties:
+- clock-master: boolean. Should be enabled if the host is being used in
+  conjunction with another DSI host to drive the same peripheral. Hardware
+  supporting such a configuration generally requires the data on both the busses
+  to be driven by the same clock. Only the DSI host instance controlling this
+  clock should contain this property.
+
 DSI peripheral
 ==============
 
@@ -62,6 +69,16 @@  primary control bus, but are also connected to a DSI bus (mostly for the data
 path). Connections between such peripherals and a DSI host can be represented
 using the graph bindings [1], [2].
 
+Peripherals that support dual channel DSI
+-----------------------------------------
+
+Peripherals with higher bandwidth requirements can be connected to 2 DSI
+busses. Each DSI bus/channel drives some portion of the pixel data (generally
+left/right half of each line of the display, or even/odd lines of the display).
+The graph bindings should be used to represent the multiple DSI busses that are
+connected to this peripheral. Each DSI host's output endpoint can be linked to
+an input endpoint of the DSI peripheral.
+
 [1] Documentation/devicetree/bindings/graph.txt
 [2] Documentation/devicetree/bindings/media/video-interfaces.txt
 
@@ -71,6 +88,8 @@  Examples
   with different virtual channel configurations.
 - (4) is an example of a peripheral on a I2C control bus connected with to
   a DSI host using of-graph bindings.
+- (5) is an example of 2 DSI hosts driving a dual-channel DSI peripheral,
+  which uses I2C as its primary control bus.
 
 1)
 	dsi-host {
@@ -153,3 +172,64 @@  Examples
 			};
 		};
 	};
+
+5)
+	i2c-host {
+		dsi-bridge@35 {
+			compatible = "...";
+			reg = <0x35>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dsi0_in: endpoint {
+						remote-endpoint = <&dsi0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					dsi1_in: endpoint {
+						remote-endpoint = <&dsi1_out>;
+					};
+				};
+			};
+		};
+	};
+
+	dsi0-host {
+		...
+
+		/*
+		 * this DSI instance drives the clock for both the host
+		 * controllers
+		 */
+		clock-master;
+
+		ports {
+			...
+
+			port {
+				dsi0_out: endpoint {
+					remote-endpoint = <&dsi0_in>;
+				};
+			};
+		};
+	};
+
+	dsi1-host {
+		...
+
+		ports {
+			...
+
+			port {
+				dsi1_out: endpoint {
+					remote-endpoint = <&dsi1_in>;
+				};
+			};
+		};
+	};