Re: [PATCH 2/2] drm/bridge: tc358767: Add DSI-to-(e)DP mode support

2022-05-12 Thread Robert Foss
On Fri, 29 Apr 2022 at 22:56, Marek Vasut  wrote:
>
> Implement DSI-to-e(DP) mode, which is a mix of currently supported
> DSI-to-DPI and DPI-to-(e)DP modes. The input side is configured as
> either DSI or DPI, the DP AUX channel is registered for both input
> side options, and the DSI host is attached for both DPI and (e)DP
> output side options.
>
> One notable detail is that the DSI-to-(e)DP mode requires the Pixel
> PLL to be always enabled, which is not needed for DPI-to-(e)DP mode
> which gets the matching clock direct from DPI Pixel Clock instead.
>
> Signed-off-by: Marek Vasut 
> Cc: Jonas Karlman 
> Cc: Laurent Pinchart 
> Cc: Lucas Stach 
> Cc: Marek Vasut 
> Cc: Maxime Ripard 
> Cc: Neil Armstrong 
> Cc: Robert Foss 
> Cc: Sam Ravnborg 
> ---
>  drivers/gpu/drm/bridge/tc358767.c | 40 +++
>  1 file changed, 30 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/tc358767.c 
> b/drivers/gpu/drm/bridge/tc358767.c
> index e72dd5cd9700..798da0e4d086 100644
> --- a/drivers/gpu/drm/bridge/tc358767.c
> +++ b/drivers/gpu/drm/bridge/tc358767.c
> @@ -309,6 +309,9 @@ struct tc_data {
> /* do we have IRQ */
> boolhave_irq;
>
> +   /* Input connector type, DSI and not DPI. */
> +   boolinput_connector_dsi;
> +
> /* HPD pin number (0 or 1) or -ENODEV */
> int hpd_pin;
>  };
> @@ -1353,8 +1356,18 @@ static int tc_edp_stream_enable(struct tc_data *tc)
>
> dev_dbg(tc->dev, "enable video stream\n");
>
> -   /* PXL PLL setup */
> -   if (tc_test_pattern) {
> +   /*
> +* Pixel PLL must be enabled for DSI input mode and test pattern.
> +*
> +* Per TC9595XBG datasheet Revision 0.1 2018-12-27 Figure 4.18
> +* "Clock Mode Selection and Clock Sources", either Pixel PLL
> +* or DPI_PCLK supplies StrmClk. DPI_PCLK is only available in
> +* case valid Pixel Clock are supplied to the chip DPI input.
> +* In case built-in test pattern is desired OR DSI input mode
> +* is used, DPI_PCLK is not available and thus Pixel PLL must
> +* be used instead.
> +*/
> +   if (tc->input_connector_dsi || tc_test_pattern) {
> ret = tc_pxl_pll_en(tc, clk_get_rate(tc->refclk),
> 1000 * tc->mode.clock);
> if (ret)
> @@ -1394,7 +1407,10 @@ static int tc_edp_stream_enable(struct tc_data *tc)
> return ret;
>
> /* Set input interface */
> -   return tc_dpi_rx_enable(tc);
> +   if (tc->input_connector_dsi)
> +   return tc_dsi_rx_enable(tc);
> +   else
> +   return tc_dpi_rx_enable(tc);
>  }
>
>  static int tc_edp_stream_disable(struct tc_data *tc)
> @@ -2004,14 +2020,18 @@ static int tc_probe_bridge_endpoint(struct tc_data 
> *tc)
> mode |= BIT(endpoint.port);
> }
>
> -   if (mode == mode_dpi_to_edp || mode == mode_dpi_to_dp)
> +   if (mode == mode_dpi_to_edp || mode == mode_dpi_to_dp) {
> +   tc->input_connector_dsi = false;
> return tc_probe_edp_bridge_endpoint(tc);
> -   else if (mode == mode_dsi_to_dpi)
> +   } else if (mode == mode_dsi_to_dpi) {
> +   tc->input_connector_dsi = true;
> return tc_probe_dpi_bridge_endpoint(tc);
> -   else if (mode == mode_dsi_to_edp || mode == mode_dsi_to_dp)
> -   dev_warn(dev, "The mode DSI-to-(e)DP is not supported!\n");
> -   else
> -   dev_warn(dev, "Invalid mode (0x%x) is not supported!\n", 
> mode);
> +   } else if (mode == mode_dsi_to_edp || mode == mode_dsi_to_dp) {
> +   tc->input_connector_dsi = true;
> +   return tc_probe_edp_bridge_endpoint(tc);
> +   }
> +
> +   dev_warn(dev, "Invalid mode (0x%x) is not supported!\n", mode);
>
> return -EINVAL;
>  }
> @@ -2149,7 +2169,7 @@ static int tc_probe(struct i2c_client *client, const 
> struct i2c_device_id *id)
>
> i2c_set_clientdata(client, tc);
>
> -   if (tc->bridge.type == DRM_MODE_CONNECTOR_DPI) { /* DPI output */
> +   if (tc->input_connector_dsi) {  /* DSI input */
> ret = tc_mipi_dsi_host_attach(tc);
> if (ret) {
> drm_bridge_remove(>bridge);

Reviewed-by: Robert Foss 


[PATCH 2/2] drm/bridge: tc358767: Add DSI-to-(e)DP mode support

2022-04-29 Thread Marek Vasut
Implement DSI-to-e(DP) mode, which is a mix of currently supported
DSI-to-DPI and DPI-to-(e)DP modes. The input side is configured as
either DSI or DPI, the DP AUX channel is registered for both input
side options, and the DSI host is attached for both DPI and (e)DP
output side options.

One notable detail is that the DSI-to-(e)DP mode requires the Pixel
PLL to be always enabled, which is not needed for DPI-to-(e)DP mode
which gets the matching clock direct from DPI Pixel Clock instead.

Signed-off-by: Marek Vasut 
Cc: Jonas Karlman 
Cc: Laurent Pinchart 
Cc: Lucas Stach 
Cc: Marek Vasut 
Cc: Maxime Ripard 
Cc: Neil Armstrong 
Cc: Robert Foss 
Cc: Sam Ravnborg 
---
 drivers/gpu/drm/bridge/tc358767.c | 40 +++
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358767.c 
b/drivers/gpu/drm/bridge/tc358767.c
index e72dd5cd9700..798da0e4d086 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -309,6 +309,9 @@ struct tc_data {
/* do we have IRQ */
boolhave_irq;
 
+   /* Input connector type, DSI and not DPI. */
+   boolinput_connector_dsi;
+
/* HPD pin number (0 or 1) or -ENODEV */
int hpd_pin;
 };
@@ -1353,8 +1356,18 @@ static int tc_edp_stream_enable(struct tc_data *tc)
 
dev_dbg(tc->dev, "enable video stream\n");
 
-   /* PXL PLL setup */
-   if (tc_test_pattern) {
+   /*
+* Pixel PLL must be enabled for DSI input mode and test pattern.
+*
+* Per TC9595XBG datasheet Revision 0.1 2018-12-27 Figure 4.18
+* "Clock Mode Selection and Clock Sources", either Pixel PLL
+* or DPI_PCLK supplies StrmClk. DPI_PCLK is only available in
+* case valid Pixel Clock are supplied to the chip DPI input.
+* In case built-in test pattern is desired OR DSI input mode
+* is used, DPI_PCLK is not available and thus Pixel PLL must
+* be used instead.
+*/
+   if (tc->input_connector_dsi || tc_test_pattern) {
ret = tc_pxl_pll_en(tc, clk_get_rate(tc->refclk),
1000 * tc->mode.clock);
if (ret)
@@ -1394,7 +1407,10 @@ static int tc_edp_stream_enable(struct tc_data *tc)
return ret;
 
/* Set input interface */
-   return tc_dpi_rx_enable(tc);
+   if (tc->input_connector_dsi)
+   return tc_dsi_rx_enable(tc);
+   else
+   return tc_dpi_rx_enable(tc);
 }
 
 static int tc_edp_stream_disable(struct tc_data *tc)
@@ -2004,14 +2020,18 @@ static int tc_probe_bridge_endpoint(struct tc_data *tc)
mode |= BIT(endpoint.port);
}
 
-   if (mode == mode_dpi_to_edp || mode == mode_dpi_to_dp)
+   if (mode == mode_dpi_to_edp || mode == mode_dpi_to_dp) {
+   tc->input_connector_dsi = false;
return tc_probe_edp_bridge_endpoint(tc);
-   else if (mode == mode_dsi_to_dpi)
+   } else if (mode == mode_dsi_to_dpi) {
+   tc->input_connector_dsi = true;
return tc_probe_dpi_bridge_endpoint(tc);
-   else if (mode == mode_dsi_to_edp || mode == mode_dsi_to_dp)
-   dev_warn(dev, "The mode DSI-to-(e)DP is not supported!\n");
-   else
-   dev_warn(dev, "Invalid mode (0x%x) is not supported!\n", mode);
+   } else if (mode == mode_dsi_to_edp || mode == mode_dsi_to_dp) {
+   tc->input_connector_dsi = true;
+   return tc_probe_edp_bridge_endpoint(tc);
+   }
+
+   dev_warn(dev, "Invalid mode (0x%x) is not supported!\n", mode);
 
return -EINVAL;
 }
@@ -2149,7 +2169,7 @@ static int tc_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
 
i2c_set_clientdata(client, tc);
 
-   if (tc->bridge.type == DRM_MODE_CONNECTOR_DPI) { /* DPI output */
+   if (tc->input_connector_dsi) {  /* DSI input */
ret = tc_mipi_dsi_host_attach(tc);
if (ret) {
drm_bridge_remove(>bridge);
-- 
2.35.1