Re: [Freedreno] [PATCH v5 5/9] drm/msm/dp: Add eDP support via aux_bus

2022-03-25 Thread Doug Anderson
Hi,

On Fri, Mar 25, 2022 at 7:11 AM Sankeerth Billakanti (QUIC)
 wrote:
>
> > > @@ -114,10 +114,12 @@ struct drm_bridge *dp_bridge_init(struct
> > msm_dp *dp_display, struct drm_device *
> > > bridge->funcs = &dp_bridge_ops;
> > > bridge->type = dp_display->connector_type;
> > >
> > > -   bridge->ops =
> > > -   DRM_BRIDGE_OP_DETECT |
> > > -   DRM_BRIDGE_OP_HPD |
> > > -   DRM_BRIDGE_OP_MODES;
> > > +   if (bridge->type == DRM_MODE_CONNECTOR_DisplayPort) {
> >
> > Why can't eDP have bridge ops that are the same?
> >
>
> eDP needs to be reported as always connected. Whichever bridge is setting 
> these ops flags should provide the ops.
> The farthest bridge from the encoder with the ops flag set should implement 
> the ops.
> drm_bridge_connector_detect  reports always connected for eDP. So, we don't 
> need DRM_BRIDGE_OP_DETECT
> eDP panel bridge will add DRM_BRIDGE_OP_MODES in drm_panel_bridge_add_typed 
> and will call panel_edp_get_modes.
> As we are not supporting HPD for EDP, we are not setting the HPD ops flag.

Right. It's Expected that eDP and DP would have different ops. If we
define "detect" and "HPD" as whether the display is _physically_
connected, not the status of the poorly-named eDP "HPD" pin, then eDP
is _supposed_ to be considered always connected and thus would never
support DETECT / HPD.

...and right that the panel is expected to handle the modes.

This matches how things have been progressing in Laurent's patches
(taken over by Kieran) to add full DP support to sn65dsi86. For
instance:

https://lore.kernel.org/r/20220317131250.1481275-3-kieran.bingham+rene...@ideasonboard.com/
https://lore.kernel.org/r/20220317131250.1481275-4-kieran.bingham+rene...@ideasonboard.com/

-Doug


Re: [Freedreno] [PATCH v5 5/9] drm/msm/dp: Add eDP support via aux_bus

2022-03-25 Thread Sankeerth Billakanti (QUIC)


> -Original Message-
> From: Stephen Boyd 
> Sent: Friday, March 18, 2022 3:08 AM
> To: Sankeerth Billakanti (QUIC) ;
> devicet...@vger.kernel.org; dri-de...@lists.freedesktop.org;
> freedreno@lists.freedesktop.org; linux-arm-...@vger.kernel.org; linux-
> ker...@vger.kernel.org
> Cc: robdcl...@gmail.com; seanp...@chromium.org; quic_kalyant
> ; Abhinav Kumar (QUIC)
> ; diand...@chromium.org; Kuogee Hsieh
> (QUIC) ; agr...@kernel.org;
> bjorn.anders...@linaro.org; robh...@kernel.org; krzk...@kernel.org;
> s...@poorly.run; airl...@linux.ie; dan...@ffwll.ch;
> thierry.red...@gmail.com; s...@ravnborg.org;
> dmitry.barysh...@linaro.org; quic_vproddut 
> Subject: Re: [PATCH v5 5/9] drm/msm/dp: Add eDP support via aux_bus
> 
> Quoting Sankeerth Billakanti (2022-03-16 10:35:50)
> > This patch adds support for generic eDP sink through aux_bus.
> 
> Please unindent commit text paragraphs. This isn't a book.
> 

Okay. Will change it.

> > The eDP/DP controller driver should support aux transactions
> > originating from the panel-edp driver and hence should be initialized and
> ready.
> >
> > The panel bridge supporting the panel should be ready before
> > the bridge connector is initialized. The generic panel probe needs the
> > controller resources to be enabled to support aux tractions
> > originating
> 
> s/tractions/transactions/
>

Will correct it
 
> > from it. So, the host_init and phy_init are moved to execute before
> > the panel probe.
> >
> > The host_init has to return early if the core is already
> > initialized so that the regulator and clock votes for the controller
> > resources are balanced.
> >
> > EV_HPD_INIT_SETUP needs to execute immediately to enable the
> > interrupts for the aux transactions from panel-edp to get the modes
> > supported.
> 
> There are a lot of things going on in this patch. Can it be split up?
>

I can split them up.

> >
> > Signed-off-by: Sankeerth Billakanti 
> > ---
> >  drivers/gpu/drm/msm/dp/dp_display.c | 65
> +++--
> >  drivers/gpu/drm/msm/dp/dp_drm.c | 10 +++---
> >  drivers/gpu/drm/msm/dp/dp_parser.c  | 21 +---
> > drivers/gpu/drm/msm/dp/dp_parser.h  |  1 +
> >  4 files changed, 70 insertions(+), 27 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
> > b/drivers/gpu/drm/msm/dp/dp_display.c
> > index 382b3aa..688bbed 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > @@ -10,6 +10,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  #include "msm_drv.h"
> >  #include "msm_kms.h"
> > @@ -265,8 +266,6 @@ static int dp_display_bind(struct device *dev, struct
> device *master,
> > goto end;
> > }
> >
> > -   dp->dp_display.next_bridge = dp->parser->next_bridge;
> > -
> > dp->aux->drm_dev = drm;
> > rc = dp_aux_register(dp->aux);
> > if (rc) {
> > @@ -421,6 +420,11 @@ static void dp_display_host_init(struct
> dp_display_private *dp)
> > dp->dp_display.connector_type, dp->core_initialized,
> > dp->phy_initialized);
> >
> > +   if (dp->core_initialized) {
> > +   DRM_DEBUG_DP("DP core already initialized\n");
> > +   return;
> > +   }
> > +
> > dp_power_init(dp->power, false);
> > dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
> > dp_aux_init(dp->aux);
> > @@ -433,6 +437,11 @@ static void dp_display_host_deinit(struct
> dp_display_private *dp)
> > dp->dp_display.connector_type, dp->core_initialized,
> > dp->phy_initialized);
> >
> > +   if (!dp->core_initialized) {
> > +   DRM_DEBUG_DP("DP core not initialized\n");
> > +   return;
> > +   }
> > +
> > dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
> > dp_aux_deinit(dp->aux);
> > dp_power_deinit(dp->power);
> > @@ -1502,7 +1511,7 @@ void msm_dp_irq_postinstall(struct msm_dp
> > *dp_display)
> >
> > dp_hpd_event_setup(dp);
> >
> > -   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
> > +   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0);
> >  }
> >
> >  void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor
> > *minor) @@ -1524,6 +1533,52 @@ void msm_dp_debugfs_init(struct
> msm_dp *dp_display, struct drm_minor *minor)
> > }
> >  }
> >
> > +static int dp_display_get_next_bridge(struct msm_dp *dp) {
> > +   int rc = 0;
> 
> Drop initialization.
> 

Okay.

> > +   struct dp_display_private *dp_priv;
> > +   struct device_node *aux_bus;
> > +   struct device *dev;
> > +
> > +   dp_priv = container_of(dp, struct dp_display_private, dp_display);
> > +   dev = &dp_priv->pdev->dev;
> > +   aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
> > +
> > +   if (aux_bus) {
> > +   dp_display_host_init(dp_priv);
> > +   dp_catalog_ctrl_hpd_config(dp_priv->catalog);

Re: [Freedreno] [PATCH v5 5/9] drm/msm/dp: Add eDP support via aux_bus

2022-03-17 Thread Stephen Boyd
Quoting Sankeerth Billakanti (2022-03-16 10:35:50)
> This patch adds support for generic eDP sink through aux_bus.

Please unindent commit text paragraphs. This isn't a book.

> The eDP/DP controller driver should support aux transactions originating
> from the panel-edp driver and hence should be initialized and ready.
>
> The panel bridge supporting the panel should be ready before
> the bridge connector is initialized. The generic panel probe needs the
> controller resources to be enabled to support aux tractions originating

s/tractions/transactions/

> from it. So, the host_init and phy_init are moved to execute before the
> panel probe.
>
> The host_init has to return early if the core is already
> initialized so that the regulator and clock votes for the controller
> resources are balanced.
>
> EV_HPD_INIT_SETUP needs to execute immediately to enable the
> interrupts for the aux transactions from panel-edp to get the modes
> supported.

There are a lot of things going on in this patch. Can it be split up?

>
> Signed-off-by: Sankeerth Billakanti 
> ---
>  drivers/gpu/drm/msm/dp/dp_display.c | 65 
> +++--
>  drivers/gpu/drm/msm/dp/dp_drm.c | 10 +++---
>  drivers/gpu/drm/msm/dp/dp_parser.c  | 21 +---
>  drivers/gpu/drm/msm/dp/dp_parser.h  |  1 +
>  4 files changed, 70 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index 382b3aa..688bbed 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -10,6 +10,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #include "msm_drv.h"
>  #include "msm_kms.h"
> @@ -265,8 +266,6 @@ static int dp_display_bind(struct device *dev, struct 
> device *master,
> goto end;
> }
>
> -   dp->dp_display.next_bridge = dp->parser->next_bridge;
> -
> dp->aux->drm_dev = drm;
> rc = dp_aux_register(dp->aux);
> if (rc) {
> @@ -421,6 +420,11 @@ static void dp_display_host_init(struct 
> dp_display_private *dp)
> dp->dp_display.connector_type, dp->core_initialized,
> dp->phy_initialized);
>
> +   if (dp->core_initialized) {
> +   DRM_DEBUG_DP("DP core already initialized\n");
> +   return;
> +   }
> +
> dp_power_init(dp->power, false);
> dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
> dp_aux_init(dp->aux);
> @@ -433,6 +437,11 @@ static void dp_display_host_deinit(struct 
> dp_display_private *dp)
> dp->dp_display.connector_type, dp->core_initialized,
> dp->phy_initialized);
>
> +   if (!dp->core_initialized) {
> +   DRM_DEBUG_DP("DP core not initialized\n");
> +   return;
> +   }
> +
> dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
> dp_aux_deinit(dp->aux);
> dp_power_deinit(dp->power);
> @@ -1502,7 +1511,7 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
>
> dp_hpd_event_setup(dp);
>
> -   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
> +   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0);
>  }
>
>  void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
> @@ -1524,6 +1533,52 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, 
> struct drm_minor *minor)
> }
>  }
>
> +static int dp_display_get_next_bridge(struct msm_dp *dp)
> +{
> +   int rc = 0;

Drop initialization.

> +   struct dp_display_private *dp_priv;
> +   struct device_node *aux_bus;
> +   struct device *dev;
> +
> +   dp_priv = container_of(dp, struct dp_display_private, dp_display);
> +   dev = &dp_priv->pdev->dev;
> +   aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
> +
> +   if (aux_bus) {
> +   dp_display_host_init(dp_priv);
> +   dp_catalog_ctrl_hpd_config(dp_priv->catalog);
> +   enable_irq(dp_priv->irq);
> +   dp_display_host_phy_init(dp_priv);
> +
> +   devm_of_dp_aux_populate_ep_devices(dp_priv->aux);
> +
> +   disable_irq(dp_priv->irq);

Why do we disable irq?

> +   }

The aux_bus node leaked.

> +
> +   /*
> +* External bridges are mandatory for eDP interfaces: one has to
> +* provide at least an eDP panel (which gets wrapped into 
> panel-bridge).
> +*
> +* For DisplayPort interfaces external bridges are optional, so
> +* silently ignore an error if one is not present (-ENODEV).
> +*/
> +   rc = dp_parser_find_next_bridge(dp_priv->parser);
> +   if (rc == -ENODEV) {
> +   if (dp->connector_type == DRM_MODE_CONNECTOR_eDP) {
> +   DRM_ERROR("eDP: next bridge is not present\n");
> +   return rc;
> +   }
> +   } else if (rc) {
> +   if (rc != -EPROBE_DEFER)
> +   DRM_ERROR("

[Freedreno] [PATCH v5 5/9] drm/msm/dp: Add eDP support via aux_bus

2022-03-16 Thread Sankeerth Billakanti
This patch adds support for generic eDP sink through aux_bus.
The eDP/DP controller driver should support aux transactions originating
from the panel-edp driver and hence should be initialized and ready.

The panel bridge supporting the panel should be ready before
the bridge connector is initialized. The generic panel probe needs the
controller resources to be enabled to support aux tractions originating
from it. So, the host_init and phy_init are moved to execute before the
panel probe.

The host_init has to return early if the core is already
initialized so that the regulator and clock votes for the controller
resources are balanced.

EV_HPD_INIT_SETUP needs to execute immediately to enable the
interrupts for the aux transactions from panel-edp to get the modes
supported.

Signed-off-by: Sankeerth Billakanti 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 65 +++--
 drivers/gpu/drm/msm/dp/dp_drm.c | 10 +++---
 drivers/gpu/drm/msm/dp/dp_parser.c  | 21 +---
 drivers/gpu/drm/msm/dp/dp_parser.h  |  1 +
 4 files changed, 70 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 382b3aa..688bbed 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "msm_drv.h"
 #include "msm_kms.h"
@@ -265,8 +266,6 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
goto end;
}
 
-   dp->dp_display.next_bridge = dp->parser->next_bridge;
-
dp->aux->drm_dev = drm;
rc = dp_aux_register(dp->aux);
if (rc) {
@@ -421,6 +420,11 @@ static void dp_display_host_init(struct dp_display_private 
*dp)
dp->dp_display.connector_type, dp->core_initialized,
dp->phy_initialized);
 
+   if (dp->core_initialized) {
+   DRM_DEBUG_DP("DP core already initialized\n");
+   return;
+   }
+
dp_power_init(dp->power, false);
dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
dp_aux_init(dp->aux);
@@ -433,6 +437,11 @@ static void dp_display_host_deinit(struct 
dp_display_private *dp)
dp->dp_display.connector_type, dp->core_initialized,
dp->phy_initialized);
 
+   if (!dp->core_initialized) {
+   DRM_DEBUG_DP("DP core not initialized\n");
+   return;
+   }
+
dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
dp_aux_deinit(dp->aux);
dp_power_deinit(dp->power);
@@ -1502,7 +1511,7 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
 
dp_hpd_event_setup(dp);
 
-   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
+   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0);
 }
 
 void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
@@ -1524,6 +1533,52 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, 
struct drm_minor *minor)
}
 }
 
+static int dp_display_get_next_bridge(struct msm_dp *dp)
+{
+   int rc = 0;
+   struct dp_display_private *dp_priv;
+   struct device_node *aux_bus;
+   struct device *dev;
+
+   dp_priv = container_of(dp, struct dp_display_private, dp_display);
+   dev = &dp_priv->pdev->dev;
+   aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
+
+   if (aux_bus) {
+   dp_display_host_init(dp_priv);
+   dp_catalog_ctrl_hpd_config(dp_priv->catalog);
+   enable_irq(dp_priv->irq);
+   dp_display_host_phy_init(dp_priv);
+
+   devm_of_dp_aux_populate_ep_devices(dp_priv->aux);
+
+   disable_irq(dp_priv->irq);
+   }
+
+   /*
+* External bridges are mandatory for eDP interfaces: one has to
+* provide at least an eDP panel (which gets wrapped into panel-bridge).
+*
+* For DisplayPort interfaces external bridges are optional, so
+* silently ignore an error if one is not present (-ENODEV).
+*/
+   rc = dp_parser_find_next_bridge(dp_priv->parser);
+   if (rc == -ENODEV) {
+   if (dp->connector_type == DRM_MODE_CONNECTOR_eDP) {
+   DRM_ERROR("eDP: next bridge is not present\n");
+   return rc;
+   }
+   } else if (rc) {
+   if (rc != -EPROBE_DEFER)
+   DRM_ERROR("DP: error parsing next bridge: %d\n", rc);
+   return rc;
+   }
+
+   dp->next_bridge = dp_priv->parser->next_bridge;
+
+   return 0;
+}
+
 int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
struct drm_encoder *encoder)
 {
@@ -1547,6 +1602,10 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, 
struct drm_device *dev,
 
dp_display->encoder = encoder;
 
+   ret = dp_display_get_next_bridge(dp_display);
+   if (ret)
+   re