Subject: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

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 the aux transactions originating from
the panel probe.

Signed-off-by: Sankeerth Billakanti <[email protected]>
---

Changes in v6:
- Remove initialization
- Fix aux_bus node leak
- Split the patches

drivers/gpu/drm/msm/dp/dp_display.c | 54 +++++++++++++++++++++++++++++++++++--
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, 60 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 382b3aa..e082d02 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -10,6 +10,7 @@
#include <linux/component.h>
#include <linux/of_irq.h>
#include <linux/delay.h>
+#include <drm/dp/drm_dp_aux_bus.h>

#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) {
@@ -1524,6 +1523,53 @@ 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;
+ 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);
+ of_node_put(aux_bus);
+ }
+
+ /*
+ * 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 +1593,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)
+ return ret;
+
dp_display->bridge = dp_bridge_init(dp_display, dev, encoder);
if (IS_ERR(dp_display->bridge)) {
ret = PTR_ERR(dp_display->bridge);
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 7ce1aca..5254bd6 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -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) {
+ bridge->ops =
+ DRM_BRIDGE_OP_DETECT |
+ DRM_BRIDGE_OP_HPD |
+ DRM_BRIDGE_OP_MODES;
+ }

rc = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (rc) {
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index 1056b8d..6317dce 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -265,7 +265,7 @@ static int dp_parser_clock(struct dp_parser *parser)
return 0;
}

-static int dp_parser_find_next_bridge(struct dp_parser *parser)
+int dp_parser_find_next_bridge(struct dp_parser *parser)
{
struct device *dev = &parser->pdev->dev;
struct drm_bridge *bridge;
@@ -300,25 +300,6 @@ static int dp_parser_parse(struct dp_parser *parser, int connector_type)
if (rc)
return rc;

- /*
- * 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(parser);
- if (rc == -ENODEV) {
- if (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;
- }
-
/* Map the corresponding regulator information according to
* version. Currently, since we only have one supported platform,
* mapping the regulator directly.
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
index d371bae..091ff41 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -140,5 +140,6 @@ struct dp_parser {
* can be parsed using this module.
*/
struct dp_parser *dp_parser_get(struct platform_device *pdev);
+int dp_parser_find_next_bridge(struct dp_parser *parser);

#endif
--
2.7.4


2022-04-02 13:10:39

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Wed, Mar 30, 2022 at 9:03 AM Sankeerth Billakanti
<[email protected]> wrote:
>
> @@ -1547,6 +1593,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)
> + return ret;

It feels weird to me that this is in a function called "modeset_init",
though I certainly don't know the structure of the MSM display code
well enough to fully comment. My expectation would have been that
devm_of_dp_aux_populate_ep_devices() would have been called from your
probe routine and then you would have returned -EPROBE_DEFER from your
probe if you were unable to find the panel afterwards.

Huh, but I guess you _are_ getting called (indirectly) from
dpu_kms_hw_init() and I can't imagine AUX transfers working before
that function is called, so maybe I should just accept that it's
complicated and let those who understand this driver better confirm
that it's OK. ;-)


> @@ -140,5 +140,6 @@ struct dp_parser {
> * can be parsed using this module.
> */
> struct dp_parser *dp_parser_get(struct platform_device *pdev);
> +int dp_parser_find_next_bridge(struct dp_parser *parser);

Everything else in this file is described w/ kerneldoc. Shouldn't your
function also have a kerneldoc comment?

2022-04-04 07:41:42

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On 01/04/2022 02:22, Doug Anderson wrote:
> Hi,
>
> On Wed, Mar 30, 2022 at 9:03 AM Sankeerth Billakanti
> <[email protected]> wrote:
>>
>> @@ -1547,6 +1593,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)
>> + return ret;
>
> It feels weird to me that this is in a function called "modeset_init",
> though I certainly don't know the structure of the MSM display code
> well enough to fully comment.

It's called modeset_init() as it initializes KMS objects used by DP
driver. We have similar functions for dsi and hdmi

> My expectation would have been that
> devm_of_dp_aux_populate_ep_devices() would have been called from your
> probe routine and then you would have returned -EPROBE_DEFER from your
> probe if you were unable to find the panel afterwards.

I don't think it's possible to call it from probe() since
drm_dp_aux_register() is called only from dp_display_bind().
The PHY also isn't initialized at that moment, so we can not probe AUX
devices.

The overall semantics of the AUX bus is not clear to me.
Typically the bus is populated (and probed) when devices are accessible.
But for the display related buses this might not be the case.
For example for the DSI bus we clearly define that DSI transfer are not
possible before the corresponding bridge's (or panel's) enable call.

Maybe the same approach should be adopted for the AUX bus. This would
allow us to populate the AUX bus before hardware access is actually
possible, thus creating all the DRM bridges before the hardware is
actually up and running.

> Huh, but I guess you _are_ getting called (indirectly) from
> dpu_kms_hw_init() and I can't imagine AUX transfers working before
> that function is called, so maybe I should just accept that it's
> complicated and let those who understand this driver better confirm
> that it's OK. ;-)
>
>
>> @@ -140,5 +140,6 @@ struct dp_parser {
>> * can be parsed using this module.
>> */
>> struct dp_parser *dp_parser_get(struct platform_device *pdev);
>> +int dp_parser_find_next_bridge(struct dp_parser *parser);
>
> Everything else in this file is described w/ kerneldoc. Shouldn't your
> function also have a kerneldoc comment?

--
With best wishes
Dmitry

2022-04-04 21:39:23

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On Sat, 2 Apr 2022 at 20:06, Doug Anderson <[email protected]> wrote:
>
> Hi,
>
> On Sat, Apr 2, 2022 at 3:37 AM Dmitry Baryshkov
> <[email protected]> wrote:
> >
> > On 01/04/2022 02:22, Doug Anderson wrote:
> > > Hi,
> > >
> > > On Wed, Mar 30, 2022 at 9:03 AM Sankeerth Billakanti
> > > <[email protected]> wrote:
> > >>
> > >> @@ -1547,6 +1593,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)
> > >> + return ret;
> > >
> > > It feels weird to me that this is in a function called "modeset_init",
> > > though I certainly don't know the structure of the MSM display code
> > > well enough to fully comment.
> >
> > It's called modeset_init() as it initializes KMS objects used by DP
> > driver. We have similar functions for dsi and hdmi
>
> Sorry, I wasn't meaning to imply that modeset_init() was a bad name or
> anything. Mostly saying that I wasn't sure that modeset init was the
> proper time to populate the aux bus. ...but then again, perhaps it is
> given the current structure of this driver?
>
>
> > > My expectation would have been that
> > > devm_of_dp_aux_populate_ep_devices() would have been called from your
> > > probe routine and then you would have returned -EPROBE_DEFER from your
> > > probe if you were unable to find the panel afterwards.
> >
> > I don't think it's possible to call it from probe() since
> > drm_dp_aux_register() is called only from dp_display_bind().
> > The PHY also isn't initialized at that moment, so we can not probe AUX
> > devices.
> >
> > The overall semantics of the AUX bus is not clear to me.
> > Typically the bus is populated (and probed) when devices are accessible.
> > But for the display related buses this might not be the case.
>
> In general the AUX bus is modeled much like the i2c bus. You probe the
> sub-device when you're able to transfer. Then you can confirm that the
> device is actually there and init the device.
>
>
> > For example for the DSI bus we clearly define that DSI transfer are not
> > possible before the corresponding bridge's (or panel's) enable call.
> >
> > Maybe the same approach should be adopted for the AUX bus. This would
> > allow us to populate the AUX bus before hardware access is actually
> > possible, thus creating all the DRM bridges before the hardware is
> > actually up and running.
>
> So I guess what you're proposing is that you could probe the devices
> under the AUX bus and they could acquire resources (and possibly
> return EPROBE_DEFER) at a point in time _before_ it's actually
> possible to transfer. Then I guess you'd later do the transfer?

Exactly.

>
> I guess conceivably one could re-design the DRM subsystem like that,
> but I don't think it's trivial.

The problem is that the DRM subsystem is already designed like that.
All the bridge chains are static. They are created during the device
probe. And the modes are populated later (via the get_modes()
callback), after the HPD signal is delivered.
For the encoder/bridge chains it is explicitly stated that the display
pipe (clocks and timing signals) are not running before bridge's
enable() callback or after the disable() callback being called.

> Why? I believe that we need to know
> things about the panel at probe time. For instance, we need to be able
> to populate the panel's modes.

As I said, panel modes are not needed at the probe time. The fact that
most (if not all) of the panel drivers provide them in the platform
data (and thus modes are typically populated at the probe time) comes
from the fact that the panel is usually a known static piece of
hardware. With the generic edp-panel this is no longer the case. A
single device handles a (probed) variety of panels.

Compare it with the generic monitor:
We have a known bridge (display-connector.c), so the driver can build
the display chain. However a set of modes is not known till the actual
monitor is plugged into the device.

> To get this information we need the
> EDID which means we need to be able to do a transfer. If we're using
> an AUX backlight we also need to add info about the backlight at probe
> time and that also needs the transfer to work.

Yes, the backlight is the problem in the suggested design. I'm not
sure when panel->backlight has to be populated for things to work.
If we can set it after the probe but before calling into
mode_set/drm_bridge_chain_enable(), then it should be fine.

> So I guess the net result is maybe we should just keep it where it is.
> Long term I'd be interested in knowing if there's a reason why we
> can't structure the driver so that AUX transfers can happen with less
> intertwining with the rest of the code, but that can happen later. I
> would expect that you'd basically just need clocks and regulators on
> and maybe your PHY on. Ideally with some pm_runtime fun we should be
> able to do that independently with anything else the driver needs to
> do?

Not really. The driver is shared between the DP and eDP. And the DP
(well, combo DP+USB-C) part has quite logical expectations that e.g.
AUX channel is not up until all negotiations about the USB-C altmodes
are done and the HPD event is delivered. This is the source for my
suggestion regarding AUX bus rework/redesign. For non-eDP cases the
connected device becomes known much later than the dp_parser code runs
(and much later than all the bridges are to be instantiated).

Another option would be to keep common drm/msm/dp core code and split
the actual driver code into two distinct code paths: one supporting
DP, another one supporting eDP. I think, up to now we were trying hard
to stay away from such a split.

--
With best wishes
Dmitry

2022-04-04 23:53:56

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Sat, Apr 2, 2022 at 1:26 PM Dmitry Baryshkov
<[email protected]> wrote:
>
> On Sat, 2 Apr 2022 at 20:06, Doug Anderson <[email protected]> wrote:
> >
> > Hi,
> >
> > On Sat, Apr 2, 2022 at 3:37 AM Dmitry Baryshkov
> > <[email protected]> wrote:
> > >
> > > On 01/04/2022 02:22, Doug Anderson wrote:
> > > > Hi,
> > > >
> > > > On Wed, Mar 30, 2022 at 9:03 AM Sankeerth Billakanti
> > > > <[email protected]> wrote:
> > > >>
> > > >> @@ -1547,6 +1593,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)
> > > >> + return ret;
> > > >
> > > > It feels weird to me that this is in a function called "modeset_init",
> > > > though I certainly don't know the structure of the MSM display code
> > > > well enough to fully comment.
> > >
> > > It's called modeset_init() as it initializes KMS objects used by DP
> > > driver. We have similar functions for dsi and hdmi
> >
> > Sorry, I wasn't meaning to imply that modeset_init() was a bad name or
> > anything. Mostly saying that I wasn't sure that modeset init was the
> > proper time to populate the aux bus. ...but then again, perhaps it is
> > given the current structure of this driver?
> >
> >
> > > > My expectation would have been that
> > > > devm_of_dp_aux_populate_ep_devices() would have been called from your
> > > > probe routine and then you would have returned -EPROBE_DEFER from your
> > > > probe if you were unable to find the panel afterwards.
> > >
> > > I don't think it's possible to call it from probe() since
> > > drm_dp_aux_register() is called only from dp_display_bind().
> > > The PHY also isn't initialized at that moment, so we can not probe AUX
> > > devices.
> > >
> > > The overall semantics of the AUX bus is not clear to me.
> > > Typically the bus is populated (and probed) when devices are accessible.
> > > But for the display related buses this might not be the case.
> >
> > In general the AUX bus is modeled much like the i2c bus. You probe the
> > sub-device when you're able to transfer. Then you can confirm that the
> > device is actually there and init the device.
> >
> >
> > > For example for the DSI bus we clearly define that DSI transfer are not
> > > possible before the corresponding bridge's (or panel's) enable call.
> > >
> > > Maybe the same approach should be adopted for the AUX bus. This would
> > > allow us to populate the AUX bus before hardware access is actually
> > > possible, thus creating all the DRM bridges before the hardware is
> > > actually up and running.
> >
> > So I guess what you're proposing is that you could probe the devices
> > under the AUX bus and they could acquire resources (and possibly
> > return EPROBE_DEFER) at a point in time _before_ it's actually
> > possible to transfer. Then I guess you'd later do the transfer?
>
> Exactly.
>
> >
> > I guess conceivably one could re-design the DRM subsystem like that,
> > but I don't think it's trivial.
>
> The problem is that the DRM subsystem is already designed like that.
> All the bridge chains are static. They are created during the device
> probe. And the modes are populated later (via the get_modes()
> callback), after the HPD signal is delivered.
> For the encoder/bridge chains it is explicitly stated that the display
> pipe (clocks and timing signals) are not running before bridge's
> enable() callback or after the disable() callback being called.
>
> > Why? I believe that we need to know
> > things about the panel at probe time. For instance, we need to be able
> > to populate the panel's modes.
>
> As I said, panel modes are not needed at the probe time. The fact that
> most (if not all) of the panel drivers provide them in the platform
> data (and thus modes are typically populated at the probe time) comes
> from the fact that the panel is usually a known static piece of
> hardware. With the generic edp-panel this is no longer the case. A
> single device handles a (probed) variety of panels.

OK, so I misspoke when I said that the modes are populated during
probe time for edp-panel. They're not and I guess I managed to confuse
myself when I wrote my previous email. Instead they (and everything
else that comes from the EDID) isn't needed until the panel's
get_modes() is called, as you said. So, ignoring the backlight problem
talked about below, we could conceivably delay the reading of the EDID
until get_modes.

...but I think something still isn't quite right with your description
of how it works. Specifically:

1. I'm 99% certain that get_modes() is called _before_ enable, even
for the DP case. I have no idea how that works for you for DP if the
clocks / timing signals don't work until enable happens. Aside from my
previous observations of this, it also logically makes sense that
get_modes() needs to be called before enable(), doesn't it? When
enable() is called then don't you already know what mode userspace has
picked for you? How can userspace pick a mode to give to enable if you
can't query the modes until after enable?

2. As soon as you have told userspace that a display is present then,
I believe, it's legal for userspace to ask for the set of available
modes.

3. For DP and eDP HPD means something a little different. Essentially
there are two concepts: a) is a display physically connected and b) is
the display powered up and ready. For DP, the two are really tied
together. From the kernel's point of view you never "power down" a DP
display and you can't detect that it's physically connected until it's
ready. Said another way, on you tie "is a display there" to the HPD
line and the moment a display is there it's ready for you to do AUX
transfers. For eDP, in the lowest power state of a display it _won't_
assert its "HPD" signal. However, it's still physically present. For
eDP you simply have to _assume_ it's present without any actual proof
since you can't get proof until you power it up. Thus for eDP, you
report that the display is there as soon as we're asked. We can't
_talk_ to the display yet, though. So in get_modes() we need to be
able to power the display on enough to talk over the AUX channel to
it. As part of this, we wait for the signal named "HPD" which really
means "panel finished powering on" in this context.

NOTE: for aux transfer, we don't have the _display_ pipe and clocks
running. We only have enough stuff running to do the AUX transfer.
We're not clocking out pixels. We haven't fully powered on the
display. The AUX transfer is designed to be something that can be done
early _before_ you turn on the display.


OK, so basically that was a longwinded way of saying: yes, we could
avoid the AUX transfer in probe, but we can't wait all the way to
enable. We have to be able to transfer in get_modes(). If you think
that's helpful I think it'd be a pretty easy patch to write even if it
would look a tad bit awkward IMO. Let me know if you want me to post
it up.


> Compare it with the generic monitor:
> We have a known bridge (display-connector.c), so the driver can build
> the display chain. However a set of modes is not known till the actual
> monitor is plugged into the device.
>
> > To get this information we need the
> > EDID which means we need to be able to do a transfer. If we're using
> > an AUX backlight we also need to add info about the backlight at probe
> > time and that also needs the transfer to work.
>
> Yes, the backlight is the problem in the suggested design. I'm not
> sure when panel->backlight has to be populated for things to work.
> If we can set it after the probe but before calling into
> mode_set/drm_bridge_chain_enable(), then it should be fine.

Actually we _probably_ can do this. Right now it only affects a small
subset of panels (those that use AUX backlight) and I can give it a
shot if this is the last blocker.

...this is even more awkward than the above, though, because the first
first call to get_modes() will actually _cause_ the backlight device
to show up. That's not super elegant but it might work OK?


> > So I guess the net result is maybe we should just keep it where it is.
> > Long term I'd be interested in knowing if there's a reason why we
> > can't structure the driver so that AUX transfers can happen with less
> > intertwining with the rest of the code, but that can happen later. I
> > would expect that you'd basically just need clocks and regulators on
> > and maybe your PHY on. Ideally with some pm_runtime fun we should be
> > able to do that independently with anything else the driver needs to
> > do?
>
> Not really. The driver is shared between the DP and eDP. And the DP
> (well, combo DP+USB-C) part has quite logical expectations that e.g.
> AUX channel is not up until all negotiations about the USB-C altmodes
> are done and the HPD event is delivered. This is the source for my
> suggestion regarding AUX bus rework/redesign. For non-eDP cases the
> connected device becomes known much later than the dp_parser code runs
> (and much later than all the bridges are to be instantiated).
>
> Another option would be to keep common drm/msm/dp core code and split
> the actual driver code into two distinct code paths: one supporting
> DP, another one supporting eDP. I think, up to now we were trying hard
> to stay away from such a split.

Even for eDP the AUX transfer shouldn't happen until after HPD is
asserted. That's why the AUX transfer function has to wait for HPD.
However, for eDP it's a requirement to register/create the AUX bus
before HPD is asserted. We went through lots of design discussions and
the end result of it all was that we pass the AUX bus to the panel at
the panel's probe time. This is something I don't think we want to
revisit.

Logically there are simply some things that will have to be different
for eDP and DP. It really stems from the case that in the lowest power
state of eDP that we truly can't tell if the panel is there and thus
we have to assume it's there. It also comes from the fact that, in
eDP, the panel driver is in charge of doing power sequencing across
several regulators / GPIOs including getting the timing right.


-Doug

2022-04-05 03:00:55

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Sat, Apr 2, 2022 at 3:37 AM Dmitry Baryshkov
<[email protected]> wrote:
>
> On 01/04/2022 02:22, Doug Anderson wrote:
> > Hi,
> >
> > On Wed, Mar 30, 2022 at 9:03 AM Sankeerth Billakanti
> > <[email protected]> wrote:
> >>
> >> @@ -1547,6 +1593,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)
> >> + return ret;
> >
> > It feels weird to me that this is in a function called "modeset_init",
> > though I certainly don't know the structure of the MSM display code
> > well enough to fully comment.
>
> It's called modeset_init() as it initializes KMS objects used by DP
> driver. We have similar functions for dsi and hdmi

Sorry, I wasn't meaning to imply that modeset_init() was a bad name or
anything. Mostly saying that I wasn't sure that modeset init was the
proper time to populate the aux bus. ...but then again, perhaps it is
given the current structure of this driver?


> > My expectation would have been that
> > devm_of_dp_aux_populate_ep_devices() would have been called from your
> > probe routine and then you would have returned -EPROBE_DEFER from your
> > probe if you were unable to find the panel afterwards.
>
> I don't think it's possible to call it from probe() since
> drm_dp_aux_register() is called only from dp_display_bind().
> The PHY also isn't initialized at that moment, so we can not probe AUX
> devices.
>
> The overall semantics of the AUX bus is not clear to me.
> Typically the bus is populated (and probed) when devices are accessible.
> But for the display related buses this might not be the case.

In general the AUX bus is modeled much like the i2c bus. You probe the
sub-device when you're able to transfer. Then you can confirm that the
device is actually there and init the device.


> For example for the DSI bus we clearly define that DSI transfer are not
> possible before the corresponding bridge's (or panel's) enable call.
>
> Maybe the same approach should be adopted for the AUX bus. This would
> allow us to populate the AUX bus before hardware access is actually
> possible, thus creating all the DRM bridges before the hardware is
> actually up and running.

So I guess what you're proposing is that you could probe the devices
under the AUX bus and they could acquire resources (and possibly
return EPROBE_DEFER) at a point in time _before_ it's actually
possible to transfer. Then I guess you'd later do the transfer?

I guess conceivably one could re-design the DRM subsystem like that,
but I don't think it's trivial. Why? I believe that we need to know
things about the panel at probe time. For instance, we need to be able
to populate the panel's modes. To get this information we need the
EDID which means we need to be able to do a transfer. If we're using
an AUX backlight we also need to add info about the backlight at probe
time and that also needs the transfer to work.


So I guess the net result is maybe we should just keep it where it is.
Long term I'd be interested in knowing if there's a reason why we
can't structure the driver so that AUX transfers can happen with less
intertwining with the rest of the code, but that can happen later. I
would expect that you'd basically just need clocks and regulators on
and maybe your PHY on. Ideally with some pm_runtime fun we should be
able to do that independently with anything else the driver needs to
do?

-Doug

2022-04-06 05:32:29

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On 05/04/2022 20:02, Doug Anderson wrote:
> Hi,
>
> On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
> <[email protected]> wrote:
>>> 3. For DP and eDP HPD means something a little different. Essentially
>>> there are two concepts: a) is a display physically connected and b) is
>>> the display powered up and ready. For DP, the two are really tied
>>> together. From the kernel's point of view you never "power down" a DP
>>> display and you can't detect that it's physically connected until it's
>>> ready. Said another way, on you tie "is a display there" to the HPD
>>> line and the moment a display is there it's ready for you to do AUX
>>> transfers. For eDP, in the lowest power state of a display it _won't_
>>> assert its "HPD" signal. However, it's still physically present. For
>>> eDP you simply have to _assume_ it's present without any actual proof
>>> since you can't get proof until you power it up. Thus for eDP, you
>>> report that the display is there as soon as we're asked. We can't
>>> _talk_ to the display yet, though. So in get_modes() we need to be
>>> able to power the display on enough to talk over the AUX channel to
>>> it. As part of this, we wait for the signal named "HPD" which really
>>> means "panel finished powering on" in this context.
>>>
>>> NOTE: for aux transfer, we don't have the _display_ pipe and clocks
>>> running. We only have enough stuff running to do the AUX transfer.
>>> We're not clocking out pixels. We haven't fully powered on the
>>> display. The AUX transfer is designed to be something that can be done
>>> early _before_ you turn on the display.
>>>
>>>
>>> OK, so basically that was a longwinded way of saying: yes, we could
>>> avoid the AUX transfer in probe, but we can't wait all the way to
>>> enable. We have to be able to transfer in get_modes(). If you think
>>> that's helpful I think it'd be a pretty easy patch to write even if it
>>> would look a tad bit awkward IMO. Let me know if you want me to post
>>> it up.
>>
>> I think it would be a good idea. At least it will allow us to judge,
>> which is the more correct way.
>
> I'm still happy to prototype this, but the more I think about it the
> more it feels like a workaround for the Qualcomm driver. The eDP panel
> driver is actually given a pointer to the AUX bus at probe time. It's
> really weird to say that we can't do a transfer on it yet... As you
> said, this is a little sideband bus. It should be able to be used
> without all the full blown infra of the rest of the driver.

Yes, I have that feeling too. However I also have a feeling that just
powering up the PHY before the bus probe is ... a hack. There are no
obvious stopgaps for the driver not to power it down later.

A cleaner design might be to split all hotplug event handling from the
dp_display, provide a lightweight state machine for the eDP and select
which state machine to use depending on the hardware connector type. The
dp_display_bind/unbind would probably also be duplicated and receive
correct code flows for calling dp_parser_get_next_bridge, etc.
Basically that means that depending on the device data we'd use either
dp_display_comp_ops or (new) edp_comp_ops.

WDYT?

>> And I also think it might help the ti,sn65dsi86 driver, as it won't
>> have to ensure that gpio is available during the AUX bus probe.
>
> The ti,sn65dsi86 GPIO issue has been solved for a while, though so not
> sure why we need to do something there? I'm also unclear how it would
> have helped. In this discussion, we've agreed that the panel driver
> would still acquire resources during its probe time and the only thing
> that would be delayed would be the first AUX transfer. The GPIO is a
> resource here and it's ideal to acquire it at probe time so we could
> EPROBE_DEFER if needed.

Ack. I agree here. The world at 5 a.m. looks differently :D

>
>
>> BTW, another random idea, before you start coding.
>>
>> We have the bridge's hpd_notify call. Currently it is called only by
>> the means of drm_bridge_connector's HPD mechanism, tied to the bridge
>> registering as DRM_BRIDGE_OP_HPD.
>> It looks to me like it might be a perfect fit for the first aux-bus
>> related reads.
>>
>> We'd need to trigger it manually once and tie it to the new
>> drm_panel_funcs callback, which in turn would probe the aux bus,
>> create backlight, etc.
>>
>> Regarding the Sankeerth's patch. I have been comparing it with the
>> hpd_event_thread()'s calls.
>> It looks to me like we should reuse dp_display_config_hpd()
>> /EV_HPD_INIT_SETUP and maybe others.
>>
>> What I'm trying to say is that if we split AUX probing and first AUX
>> transfers, it would be possible to reuse a significant part of MSM DP
>> HPD machine rather than hacking around it and replicating it manually.
>
> I'm not sure I completely understand, but I'm pretty wary here. It's
> my assertion that all of the current "HPD" infrastructure in DRM all
> relates to the physical presence of the panel. If you start
> implementing these functions for eDP I think you're going to confuse
> the heck out of everything. The kernel will think that this is a
> display that's sometimes not there. Whenever the display is powered
> off then HPD will be low and it will look like there's no display.
> Nothing will ever try to power it on because it looks like there's no
> display.
>
> I think your idea is to "trigger once" at bootup and then it all
> magically works, right? ...but what about after bootup? If you turn
> the display off for whatever reason (modeset or you simply close the
> lid of your laptop because you're using an external display) and then
> you want to use the eDP display again, how do you kickstart the
> process another time? You can't reboot, and when the display is off
> the HPD line is low.
>
> I can't say it enough times, HPD on eDP _does not mean hot plug
> detect_. The panel is always there. HPD is really a "panel ready /
> panel notify" signal for eDP. That's fully what its function is.

Too many things being called HPD. I meant to trigger drm's hpd handling,
which is not tied to the HPD pin for panel-edp. HPD pin is checked
during panel runtime resume. However... let's probably go a simpler way.

--
With best wishes
Dmitry

2022-04-06 11:08:03

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
<[email protected]> wrote:
> > 3. For DP and eDP HPD means something a little different. Essentially
> > there are two concepts: a) is a display physically connected and b) is
> > the display powered up and ready. For DP, the two are really tied
> > together. From the kernel's point of view you never "power down" a DP
> > display and you can't detect that it's physically connected until it's
> > ready. Said another way, on you tie "is a display there" to the HPD
> > line and the moment a display is there it's ready for you to do AUX
> > transfers. For eDP, in the lowest power state of a display it _won't_
> > assert its "HPD" signal. However, it's still physically present. For
> > eDP you simply have to _assume_ it's present without any actual proof
> > since you can't get proof until you power it up. Thus for eDP, you
> > report that the display is there as soon as we're asked. We can't
> > _talk_ to the display yet, though. So in get_modes() we need to be
> > able to power the display on enough to talk over the AUX channel to
> > it. As part of this, we wait for the signal named "HPD" which really
> > means "panel finished powering on" in this context.
> >
> > NOTE: for aux transfer, we don't have the _display_ pipe and clocks
> > running. We only have enough stuff running to do the AUX transfer.
> > We're not clocking out pixels. We haven't fully powered on the
> > display. The AUX transfer is designed to be something that can be done
> > early _before_ you turn on the display.
> >
> >
> > OK, so basically that was a longwinded way of saying: yes, we could
> > avoid the AUX transfer in probe, but we can't wait all the way to
> > enable. We have to be able to transfer in get_modes(). If you think
> > that's helpful I think it'd be a pretty easy patch to write even if it
> > would look a tad bit awkward IMO. Let me know if you want me to post
> > it up.
>
> I think it would be a good idea. At least it will allow us to judge,
> which is the more correct way.

I'm still happy to prototype this, but the more I think about it the
more it feels like a workaround for the Qualcomm driver. The eDP panel
driver is actually given a pointer to the AUX bus at probe time. It's
really weird to say that we can't do a transfer on it yet... As you
said, this is a little sideband bus. It should be able to be used
without all the full blown infra of the rest of the driver.


> And I also think it might help the ti,sn65dsi86 driver, as it won't
> have to ensure that gpio is available during the AUX bus probe.

The ti,sn65dsi86 GPIO issue has been solved for a while, though so not
sure why we need to do something there? I'm also unclear how it would
have helped. In this discussion, we've agreed that the panel driver
would still acquire resources during its probe time and the only thing
that would be delayed would be the first AUX transfer. The GPIO is a
resource here and it's ideal to acquire it at probe time so we could
EPROBE_DEFER if needed.


> BTW, another random idea, before you start coding.
>
> We have the bridge's hpd_notify call. Currently it is called only by
> the means of drm_bridge_connector's HPD mechanism, tied to the bridge
> registering as DRM_BRIDGE_OP_HPD.
> It looks to me like it might be a perfect fit for the first aux-bus
> related reads.
>
> We'd need to trigger it manually once and tie it to the new
> drm_panel_funcs callback, which in turn would probe the aux bus,
> create backlight, etc.
>
> Regarding the Sankeerth's patch. I have been comparing it with the
> hpd_event_thread()'s calls.
> It looks to me like we should reuse dp_display_config_hpd()
> /EV_HPD_INIT_SETUP and maybe others.
>
> What I'm trying to say is that if we split AUX probing and first AUX
> transfers, it would be possible to reuse a significant part of MSM DP
> HPD machine rather than hacking around it and replicating it manually.

I'm not sure I completely understand, but I'm pretty wary here. It's
my assertion that all of the current "HPD" infrastructure in DRM all
relates to the physical presence of the panel. If you start
implementing these functions for eDP I think you're going to confuse
the heck out of everything. The kernel will think that this is a
display that's sometimes not there. Whenever the display is powered
off then HPD will be low and it will look like there's no display.
Nothing will ever try to power it on because it looks like there's no
display.

I think your idea is to "trigger once" at bootup and then it all
magically works, right? ...but what about after bootup? If you turn
the display off for whatever reason (modeset or you simply close the
lid of your laptop because you're using an external display) and then
you want to use the eDP display again, how do you kickstart the
process another time? You can't reboot, and when the display is off
the HPD line is low.

I can't say it enough times, HPD on eDP _does not mean hot plug
detect_. The panel is always there. HPD is really a "panel ready /
panel notify" signal for eDP. That's fully what its function is.

-Doug

2022-04-06 12:59:41

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On Mon, 4 Apr 2022 at 23:53, Doug Anderson <[email protected]> wrote:
>
> Hi,
>
> On Sat, Apr 2, 2022 at 1:26 PM Dmitry Baryshkov
> <[email protected]> wrote:
> >
> > On Sat, 2 Apr 2022 at 20:06, Doug Anderson <[email protected]> wrote:
> > >
> > > Hi,
> > >
> > > On Sat, Apr 2, 2022 at 3:37 AM Dmitry Baryshkov
> > > <[email protected]> wrote:
> > > >
> > > > On 01/04/2022 02:22, Doug Anderson wrote:
> > > > > Hi,
> > > > >
> > > > > On Wed, Mar 30, 2022 at 9:03 AM Sankeerth Billakanti
> > > > > <[email protected]> wrote:
> > > > >>
> > > > >> @@ -1547,6 +1593,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)
> > > > >> + return ret;
> > > > >
> > > > > It feels weird to me that this is in a function called "modeset_init",
> > > > > though I certainly don't know the structure of the MSM display code
> > > > > well enough to fully comment.
> > > >
> > > > It's called modeset_init() as it initializes KMS objects used by DP
> > > > driver. We have similar functions for dsi and hdmi
> > >
> > > Sorry, I wasn't meaning to imply that modeset_init() was a bad name or
> > > anything. Mostly saying that I wasn't sure that modeset init was the
> > > proper time to populate the aux bus. ...but then again, perhaps it is
> > > given the current structure of this driver?
> > >
> > >
> > > > > My expectation would have been that
> > > > > devm_of_dp_aux_populate_ep_devices() would have been called from your
> > > > > probe routine and then you would have returned -EPROBE_DEFER from your
> > > > > probe if you were unable to find the panel afterwards.
> > > >
> > > > I don't think it's possible to call it from probe() since
> > > > drm_dp_aux_register() is called only from dp_display_bind().
> > > > The PHY also isn't initialized at that moment, so we can not probe AUX
> > > > devices.
> > > >
> > > > The overall semantics of the AUX bus is not clear to me.
> > > > Typically the bus is populated (and probed) when devices are accessible.
> > > > But for the display related buses this might not be the case.
> > >
> > > In general the AUX bus is modeled much like the i2c bus. You probe the
> > > sub-device when you're able to transfer. Then you can confirm that the
> > > device is actually there and init the device.
> > >
> > >
> > > > For example for the DSI bus we clearly define that DSI transfer are not
> > > > possible before the corresponding bridge's (or panel's) enable call.
> > > >
> > > > Maybe the same approach should be adopted for the AUX bus. This would
> > > > allow us to populate the AUX bus before hardware access is actually
> > > > possible, thus creating all the DRM bridges before the hardware is
> > > > actually up and running.
> > >
> > > So I guess what you're proposing is that you could probe the devices
> > > under the AUX bus and they could acquire resources (and possibly
> > > return EPROBE_DEFER) at a point in time _before_ it's actually
> > > possible to transfer. Then I guess you'd later do the transfer?
> >
> > Exactly.
> >
> > >
> > > I guess conceivably one could re-design the DRM subsystem like that,
> > > but I don't think it's trivial.
> >
> > The problem is that the DRM subsystem is already designed like that.
> > All the bridge chains are static. They are created during the device
> > probe. And the modes are populated later (via the get_modes()
> > callback), after the HPD signal is delivered.
> > For the encoder/bridge chains it is explicitly stated that the display
> > pipe (clocks and timing signals) are not running before bridge's
> > enable() callback or after the disable() callback being called.
> >
> > > Why? I believe that we need to know
> > > things about the panel at probe time. For instance, we need to be able
> > > to populate the panel's modes.
> >
> > As I said, panel modes are not needed at the probe time. The fact that
> > most (if not all) of the panel drivers provide them in the platform
> > data (and thus modes are typically populated at the probe time) comes
> > from the fact that the panel is usually a known static piece of
> > hardware. With the generic edp-panel this is no longer the case. A
> > single device handles a (probed) variety of panels.
>
> OK, so I misspoke when I said that the modes are populated during
> probe time for edp-panel. They're not and I guess I managed to confuse
> myself when I wrote my previous email. Instead they (and everything
> else that comes from the EDID) isn't needed until the panel's
> get_modes() is called, as you said. So, ignoring the backlight problem
> talked about below, we could conceivably delay the reading of the EDID
> until get_modes.

Yes.

>
> ...but I think something still isn't quite right with your description
> of how it works. Specifically:
>
> 1. I'm 99% certain that get_modes() is called _before_ enable, even
> for the DP case. I have no idea how that works for you for DP if the
> clocks / timing signals don't work until enable happens. Aside from my
> previous observations of this, it also logically makes sense that
> get_modes() needs to be called before enable(), doesn't it?

Yes, you are correct here. I also wasn't clear enough about the
display clocks/aux clocks being enabled.
Of course, it's the display (video) mode clocks not being provided
before the enable() call. (well, before the moment between
prepare()/pre_enable() and enable()).

The side channel buses are a separate story.

> When
> enable() is called then don't you already know what mode userspace has
> picked for you? How can userspace pick a mode to give to enable if you
> can't query the modes until after enable?

Yes. You are correct here.

>
> 2. As soon as you have told userspace that a display is present then,
> I believe, it's legal for userspace to ask for the set of available
> modes.

Yes.

>
> 3. For DP and eDP HPD means something a little different. Essentially
> there are two concepts: a) is a display physically connected and b) is
> the display powered up and ready. For DP, the two are really tied
> together. From the kernel's point of view you never "power down" a DP
> display and you can't detect that it's physically connected until it's
> ready. Said another way, on you tie "is a display there" to the HPD
> line and the moment a display is there it's ready for you to do AUX
> transfers. For eDP, in the lowest power state of a display it _won't_
> assert its "HPD" signal. However, it's still physically present. For
> eDP you simply have to _assume_ it's present without any actual proof
> since you can't get proof until you power it up. Thus for eDP, you
> report that the display is there as soon as we're asked. We can't
> _talk_ to the display yet, though. So in get_modes() we need to be
> able to power the display on enough to talk over the AUX channel to
> it. As part of this, we wait for the signal named "HPD" which really
> means "panel finished powering on" in this context.
>
> NOTE: for aux transfer, we don't have the _display_ pipe and clocks
> running. We only have enough stuff running to do the AUX transfer.
> We're not clocking out pixels. We haven't fully powered on the
> display. The AUX transfer is designed to be something that can be done
> early _before_ you turn on the display.
>
>
> OK, so basically that was a longwinded way of saying: yes, we could
> avoid the AUX transfer in probe, but we can't wait all the way to
> enable. We have to be able to transfer in get_modes(). If you think
> that's helpful I think it'd be a pretty easy patch to write even if it
> would look a tad bit awkward IMO. Let me know if you want me to post
> it up.

I think it would be a good idea. At least it will allow us to judge,
which is the more correct way.
And I also think it might help the ti,sn65dsi86 driver, as it won't
have to ensure that gpio is available during the AUX bus probe.

BTW, another random idea, before you start coding.

We have the bridge's hpd_notify call. Currently it is called only by
the means of drm_bridge_connector's HPD mechanism, tied to the bridge
registering as DRM_BRIDGE_OP_HPD.
It looks to me like it might be a perfect fit for the first aux-bus
related reads.

We'd need to trigger it manually once and tie it to the new
drm_panel_funcs callback, which in turn would probe the aux bus,
create backlight, etc.

Regarding the Sankeerth's patch. I have been comparing it with the
hpd_event_thread()'s calls.
It looks to me like we should reuse dp_display_config_hpd()
/EV_HPD_INIT_SETUP and maybe others.

What I'm trying to say is that if we split AUX probing and first AUX
transfers, it would be possible to reuse a significant part of MSM DP
HPD machine rather than hacking around it and replicating it manually.

>
>
> > Compare it with the generic monitor:
> > We have a known bridge (display-connector.c), so the driver can build
> > the display chain. However a set of modes is not known till the actual
> > monitor is plugged into the device.
> >
> > > To get this information we need the
> > > EDID which means we need to be able to do a transfer. If we're using
> > > an AUX backlight we also need to add info about the backlight at probe
> > > time and that also needs the transfer to work.
> >
> > Yes, the backlight is the problem in the suggested design. I'm not
> > sure when panel->backlight has to be populated for things to work.
> > If we can set it after the probe but before calling into
> > mode_set/drm_bridge_chain_enable(), then it should be fine.
>
> Actually we _probably_ can do this. Right now it only affects a small
> subset of panels (those that use AUX backlight) and I can give it a
> shot if this is the last blocker.
>
> ...this is even more awkward than the above, though, because the first
> first call to get_modes() will actually _cause_ the backlight device
> to show up. That's not super elegant but it might work OK?

This is really an interesting question. See the hpd_notify suggestion above.


>
>
> > > So I guess the net result is maybe we should just keep it where it is.
> > > Long term I'd be interested in knowing if there's a reason why we
> > > can't structure the driver so that AUX transfers can happen with less
> > > intertwining with the rest of the code, but that can happen later. I
> > > would expect that you'd basically just need clocks and regulators on
> > > and maybe your PHY on. Ideally with some pm_runtime fun we should be
> > > able to do that independently with anything else the driver needs to
> > > do?
> >
> > Not really. The driver is shared between the DP and eDP. And the DP
> > (well, combo DP+USB-C) part has quite logical expectations that e.g.
> > AUX channel is not up until all negotiations about the USB-C altmodes
> > are done and the HPD event is delivered. This is the source for my
> > suggestion regarding AUX bus rework/redesign. For non-eDP cases the
> > connected device becomes known much later than the dp_parser code runs
> > (and much later than all the bridges are to be instantiated).
> >
> > Another option would be to keep common drm/msm/dp core code and split
> > the actual driver code into two distinct code paths: one supporting
> > DP, another one supporting eDP. I think, up to now we were trying hard
> > to stay away from such a split.
>
> Even for eDP the AUX transfer shouldn't happen until after HPD is
> asserted. That's why the AUX transfer function has to wait for HPD.
> However, for eDP it's a requirement to register/create the AUX bus
> before HPD is asserted. We went through lots of design discussions and
> the end result of it all was that we pass the AUX bus to the panel at
> the panel's probe time. This is something I don't think we want to
> revisit.
>
> Logically there are simply some things that will have to be different
> for eDP and DP. It really stems from the case that in the lowest power
> state of eDP that we truly can't tell if the panel is there and thus
> we have to assume it's there. It also comes from the fact that, in
> eDP, the panel driver is in charge of doing power sequencing across
> several regulators / GPIOs including getting the timing right.
>
>
> -Doug



--
With best wishes
Dmitry

2022-04-06 13:30:35

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Tue, Apr 5, 2022 at 10:36 AM Dmitry Baryshkov
<[email protected]> wrote:
>
> On 05/04/2022 20:02, Doug Anderson wrote:
> > Hi,
> >
> > On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
> > <[email protected]> wrote:
> >>> 3. For DP and eDP HPD means something a little different. Essentially
> >>> there are two concepts: a) is a display physically connected and b) is
> >>> the display powered up and ready. For DP, the two are really tied
> >>> together. From the kernel's point of view you never "power down" a DP
> >>> display and you can't detect that it's physically connected until it's
> >>> ready. Said another way, on you tie "is a display there" to the HPD
> >>> line and the moment a display is there it's ready for you to do AUX
> >>> transfers. For eDP, in the lowest power state of a display it _won't_
> >>> assert its "HPD" signal. However, it's still physically present. For
> >>> eDP you simply have to _assume_ it's present without any actual proof
> >>> since you can't get proof until you power it up. Thus for eDP, you
> >>> report that the display is there as soon as we're asked. We can't
> >>> _talk_ to the display yet, though. So in get_modes() we need to be
> >>> able to power the display on enough to talk over the AUX channel to
> >>> it. As part of this, we wait for the signal named "HPD" which really
> >>> means "panel finished powering on" in this context.
> >>>
> >>> NOTE: for aux transfer, we don't have the _display_ pipe and clocks
> >>> running. We only have enough stuff running to do the AUX transfer.
> >>> We're not clocking out pixels. We haven't fully powered on the
> >>> display. The AUX transfer is designed to be something that can be done
> >>> early _before_ you turn on the display.
> >>>
> >>>
> >>> OK, so basically that was a longwinded way of saying: yes, we could
> >>> avoid the AUX transfer in probe, but we can't wait all the way to
> >>> enable. We have to be able to transfer in get_modes(). If you think
> >>> that's helpful I think it'd be a pretty easy patch to write even if it
> >>> would look a tad bit awkward IMO. Let me know if you want me to post
> >>> it up.
> >>
> >> I think it would be a good idea. At least it will allow us to judge,
> >> which is the more correct way.
> >
> > I'm still happy to prototype this, but the more I think about it the
> > more it feels like a workaround for the Qualcomm driver. The eDP panel
> > driver is actually given a pointer to the AUX bus at probe time. It's
> > really weird to say that we can't do a transfer on it yet... As you
> > said, this is a little sideband bus. It should be able to be used
> > without all the full blown infra of the rest of the driver.
>
> Yes, I have that feeling too. However I also have a feeling that just
> powering up the PHY before the bus probe is ... a hack. There are no
> obvious stopgaps for the driver not to power it down later.

This is why I think we need to move to Runtime PM to manage this. Basically:

1. When an AUX transfer happens, you grab a PM runtime reference that
_that_ powers up the PHY.

2. At the end of the AUX transfer function, you do a "put_autosuspend".

Then it becomes not a hack, right?


> A cleaner design might be to split all hotplug event handling from the
> dp_display, provide a lightweight state machine for the eDP and select
> which state machine to use depending on the hardware connector type. The
> dp_display_bind/unbind would probably also be duplicated and receive
> correct code flows for calling dp_parser_get_next_bridge, etc.
> Basically that means that depending on the device data we'd use either
> dp_display_comp_ops or (new) edp_comp_ops.
>
> WDYT?

I don't think I know the structure of the MSM DP code to make a
definitive answer here. I think I'd have to see a patch. However I'd
agree in general terms that we need some different flows for the two.
;-) We definitely want to limit the differences but some of them will
be unavoidable...


-Doug

Subject: RE: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi Dmitry and Doug,

> Hi,
>
> On Tue, Apr 5, 2022 at 10:36 AM Dmitry Baryshkov
> <[email protected]> wrote:
> >
> > On 05/04/2022 20:02, Doug Anderson wrote:
> > > Hi,
> > >
> > > On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
> > > <[email protected]> wrote:
> > >>> 3. For DP and eDP HPD means something a little different.
> > >>> Essentially there are two concepts: a) is a display physically
> > >>> connected and b) is the display powered up and ready. For DP, the
> > >>> two are really tied together. From the kernel's point of view you
> > >>> never "power down" a DP display and you can't detect that it's
> > >>> physically connected until it's ready. Said another way, on you
> > >>> tie "is a display there" to the HPD line and the moment a display
> > >>> is there it's ready for you to do AUX transfers. For eDP, in the
> > >>> lowest power state of a display it _won't_ assert its "HPD"
> > >>> signal. However, it's still physically present. For eDP you simply
> > >>> have to _assume_ it's present without any actual proof since you
> > >>> can't get proof until you power it up. Thus for eDP, you report
> > >>> that the display is there as soon as we're asked. We can't _talk_
> > >>> to the display yet, though. So in get_modes() we need to be able
> > >>> to power the display on enough to talk over the AUX channel to it.
> > >>> As part of this, we wait for the signal named "HPD" which really means
> "panel finished powering on" in this context.
> > >>>
> > >>> NOTE: for aux transfer, we don't have the _display_ pipe and
> > >>> clocks running. We only have enough stuff running to do the AUX
> transfer.
> > >>> We're not clocking out pixels. We haven't fully powered on the
> > >>> display. The AUX transfer is designed to be something that can be
> > >>> done early _before_ you turn on the display.
> > >>>
> > >>>
> > >>> OK, so basically that was a longwinded way of saying: yes, we
> > >>> could avoid the AUX transfer in probe, but we can't wait all the
> > >>> way to enable. We have to be able to transfer in get_modes(). If
> > >>> you think that's helpful I think it'd be a pretty easy patch to
> > >>> write even if it would look a tad bit awkward IMO. Let me know if
> > >>> you want me to post it up.
> > >>
> > >> I think it would be a good idea. At least it will allow us to
> > >> judge, which is the more correct way.
> > >
> > > I'm still happy to prototype this, but the more I think about it the
> > > more it feels like a workaround for the Qualcomm driver. The eDP
> > > panel driver is actually given a pointer to the AUX bus at probe
> > > time. It's really weird to say that we can't do a transfer on it
> > > yet... As you said, this is a little sideband bus. It should be able
> > > to be used without all the full blown infra of the rest of the driver.
> >
> > Yes, I have that feeling too. However I also have a feeling that just
> > powering up the PHY before the bus probe is ... a hack. There are no
> > obvious stopgaps for the driver not to power it down later.
>
> This is why I think we need to move to Runtime PM to manage this. Basically:
>
> 1. When an AUX transfer happens, you grab a PM runtime reference that
> _that_ powers up the PHY.
>
> 2. At the end of the AUX transfer function, you do a "put_autosuspend".
>
> Then it becomes not a hack, right?
>
>

pm runtime ops needs to be implemented for both eDP and DP. This change
take good amount of planning and code changes as it affects DP also.

Because this patch series consist of basic eDP changes for SC7280 bootup,
shall we take this pm_runtime implementation in subsequent patch series?

> > A cleaner design might be to split all hotplug event handling from the
> > dp_display, provide a lightweight state machine for the eDP and select
> > which state machine to use depending on the hardware connector type.
> > The dp_display_bind/unbind would probably also be duplicated and
> > receive correct code flows for calling dp_parser_get_next_bridge, etc.
> > Basically that means that depending on the device data we'd use either
> > dp_display_comp_ops or (new) edp_comp_ops.
> >
> > WDYT?
>
> I don't think I know the structure of the MSM DP code to make a definitive
> answer here. I think I'd have to see a patch. However I'd agree in general
> terms that we need some different flows for the two.
> ;-) We definitely want to limit the differences but some of them will be
> unavoidable...
>
>
> -Doug

Thank you,
Sankeerth

2022-04-07 20:21:36

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Thu, Apr 7, 2022 at 7:19 AM Sankeerth Billakanti (QUIC)
<[email protected]> wrote:
>
> Hi Dmitry and Doug,
>
> > Hi,
> >
> > On Tue, Apr 5, 2022 at 10:36 AM Dmitry Baryshkov
> > <[email protected]> wrote:
> > >
> > > On 05/04/2022 20:02, Doug Anderson wrote:
> > > > Hi,
> > > >
> > > > On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
> > > > <[email protected]> wrote:
> > > >>> 3. For DP and eDP HPD means something a little different.
> > > >>> Essentially there are two concepts: a) is a display physically
> > > >>> connected and b) is the display powered up and ready. For DP, the
> > > >>> two are really tied together. From the kernel's point of view you
> > > >>> never "power down" a DP display and you can't detect that it's
> > > >>> physically connected until it's ready. Said another way, on you
> > > >>> tie "is a display there" to the HPD line and the moment a display
> > > >>> is there it's ready for you to do AUX transfers. For eDP, in the
> > > >>> lowest power state of a display it _won't_ assert its "HPD"
> > > >>> signal. However, it's still physically present. For eDP you simply
> > > >>> have to _assume_ it's present without any actual proof since you
> > > >>> can't get proof until you power it up. Thus for eDP, you report
> > > >>> that the display is there as soon as we're asked. We can't _talk_
> > > >>> to the display yet, though. So in get_modes() we need to be able
> > > >>> to power the display on enough to talk over the AUX channel to it.
> > > >>> As part of this, we wait for the signal named "HPD" which really means
> > "panel finished powering on" in this context.
> > > >>>
> > > >>> NOTE: for aux transfer, we don't have the _display_ pipe and
> > > >>> clocks running. We only have enough stuff running to do the AUX
> > transfer.
> > > >>> We're not clocking out pixels. We haven't fully powered on the
> > > >>> display. The AUX transfer is designed to be something that can be
> > > >>> done early _before_ you turn on the display.
> > > >>>
> > > >>>
> > > >>> OK, so basically that was a longwinded way of saying: yes, we
> > > >>> could avoid the AUX transfer in probe, but we can't wait all the
> > > >>> way to enable. We have to be able to transfer in get_modes(). If
> > > >>> you think that's helpful I think it'd be a pretty easy patch to
> > > >>> write even if it would look a tad bit awkward IMO. Let me know if
> > > >>> you want me to post it up.
> > > >>
> > > >> I think it would be a good idea. At least it will allow us to
> > > >> judge, which is the more correct way.
> > > >
> > > > I'm still happy to prototype this, but the more I think about it the
> > > > more it feels like a workaround for the Qualcomm driver. The eDP
> > > > panel driver is actually given a pointer to the AUX bus at probe
> > > > time. It's really weird to say that we can't do a transfer on it
> > > > yet... As you said, this is a little sideband bus. It should be able
> > > > to be used without all the full blown infra of the rest of the driver.
> > >
> > > Yes, I have that feeling too. However I also have a feeling that just
> > > powering up the PHY before the bus probe is ... a hack. There are no
> > > obvious stopgaps for the driver not to power it down later.
> >
> > This is why I think we need to move to Runtime PM to manage this. Basically:
> >
> > 1. When an AUX transfer happens, you grab a PM runtime reference that
> > _that_ powers up the PHY.
> >
> > 2. At the end of the AUX transfer function, you do a "put_autosuspend".
> >
> > Then it becomes not a hack, right?
> >
> >
>
> pm runtime ops needs to be implemented for both eDP and DP. This change
> take good amount of planning and code changes as it affects DP also.
>
> Because this patch series consist of basic eDP changes for SC7280 bootup,
> shall we take this pm_runtime implementation in subsequent patch series?

Dmitry is the real decision maker here, but in my opinion it would be
OK to get something landed first that worked OK and wasn't taking us
too far in the wrong direction and then we could get a follow up patch
to move to pm_runtime.

2022-04-07 21:28:22

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi Doug and Dmitry

Sorry, but I caught up on this email just now.

Some comments below.

Thanks

Abhinav
On 4/7/2022 10:07 AM, Doug Anderson wrote:
> Hi,
>
> On Thu, Apr 7, 2022 at 7:19 AM Sankeerth Billakanti (QUIC)
> <[email protected]> wrote:
>>
>> Hi Dmitry and Doug,
>>
>>> Hi,
>>>
>>> On Tue, Apr 5, 2022 at 10:36 AM Dmitry Baryshkov
>>> <[email protected]> wrote:
>>>>
>>>> On 05/04/2022 20:02, Doug Anderson wrote:
>>>>> Hi,
>>>>>
>>>>> On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
>>>>> <[email protected]> wrote:
>>>>>>> 3. For DP and eDP HPD means something a little different.
>>>>>>> Essentially there are two concepts: a) is a display physically
>>>>>>> connected and b) is the display powered up and ready. For DP, the
>>>>>>> two are really tied together. From the kernel's point of view you
>>>>>>> never "power down" a DP display and you can't detect that it's
>>>>>>> physically connected until it's ready. Said another way, on you
>>>>>>> tie "is a display there" to the HPD line and the moment a display
>>>>>>> is there it's ready for you to do AUX transfers. For eDP, in the
>>>>>>> lowest power state of a display it _won't_ assert its "HPD"
>>>>>>> signal. However, it's still physically present. For eDP you simply
>>>>>>> have to _assume_ it's present without any actual proof since you
>>>>>>> can't get proof until you power it up. Thus for eDP, you report
>>>>>>> that the display is there as soon as we're asked. We can't _talk_
>>>>>>> to the display yet, though. So in get_modes() we need to be able
>>>>>>> to power the display on enough to talk over the AUX channel to it.
>>>>>>> As part of this, we wait for the signal named "HPD" which really means
>>> "panel finished powering on" in this context.
>>>>>>>
>>>>>>> NOTE: for aux transfer, we don't have the _display_ pipe and
>>>>>>> clocks running. We only have enough stuff running to do the AUX
>>> transfer.
>>>>>>> We're not clocking out pixels. We haven't fully powered on the
>>>>>>> display. The AUX transfer is designed to be something that can be
>>>>>>> done early _before_ you turn on the display.
>>>>>>>
>>>>>>>
>>>>>>> OK, so basically that was a longwinded way of saying: yes, we
>>>>>>> could avoid the AUX transfer in probe, but we can't wait all the
>>>>>>> way to enable. We have to be able to transfer in get_modes(). If
>>>>>>> you think that's helpful I think it'd be a pretty easy patch to
>>>>>>> write even if it would look a tad bit awkward IMO. Let me know if
>>>>>>> you want me to post it up.
>>>>>>
>>>>>> I think it would be a good idea. At least it will allow us to
>>>>>> judge, which is the more correct way.
>>>>>
>>>>> I'm still happy to prototype this, but the more I think about it the
>>>>> more it feels like a workaround for the Qualcomm driver. The eDP
>>>>> panel driver is actually given a pointer to the AUX bus at probe
>>>>> time. It's really weird to say that we can't do a transfer on it
>>>>> yet... As you said, this is a little sideband bus. It should be able
>>>>> to be used without all the full blown infra of the rest of the driver.
>>>>
>>>> Yes, I have that feeling too. However I also have a feeling that just
>>>> powering up the PHY before the bus probe is ... a hack. There are no
>>>> obvious stopgaps for the driver not to power it down later.
>>>

Lets go back to why we need to power up the PHY before the bus probe.

We need to power up PHY before bus probe because panel-eDP tries to read
the EDID in probe() for the panel_id. Not get_modes().

So doug, I didnt follow your comment that panel-eDP only does EDID read
in get_modes()

panel_id = drm_edid_get_panel_id(panel->ddc);
if (!panel_id) {
dev_err(dev, "Couldn't identify panel via EDID\n");
ret = -EIO;
goto exit;
}

If we do not need this part, we really dont need to power up the PHY
before the probe(). The hack which dmitry was referring to.

So this is boiling down to why or how panel-eDP was originally designed.

>>> This is why I think we need to move to Runtime PM to manage this. Basically:
>>>
>>> 1. When an AUX transfer happens, you grab a PM runtime reference that
>>> _that_ powers up the PHY.

This will not be trivial and needs to be scoped out as sankeerth said
but if the above is the only concern, why do we need to do this? There
seems to be an explanation why we are doing this and its not a hack.

How would Dmitry's rework address this? We need some RFC to conclude on
that first.

>>>
>>> 2. At the end of the AUX transfer function, you do a "put_autosuspend".
>>>
>>> Then it becomes not a hack, right?
>>>
>>>
>>
>> pm runtime ops needs to be implemented for both eDP and DP. This change
>> take good amount of planning and code changes as it affects DP also.
>>
>> Because this patch series consist of basic eDP changes for SC7280 bootup,
>> shall we take this pm_runtime implementation in subsequent patch series?
>
> Dmitry is the real decision maker here, but in my opinion it would be
> OK to get something landed first that worked OK and wasn't taking us
> too far in the wrong direction and then we could get a follow up patch
> to move to pm_runtime.

I would say the discussion changed into a direction of implementing
pm-runtime because the current patch series does what it takes to adhere
to panel-eDP's design along with aux bus requirements of PHY needing to
be on.

So doug, to answer your questions here:

"So I guess the net result is maybe we should just keep it where it is.
Long term I'd be interested in knowing if there's a reason why we
can't structure the driver so that AUX transfers can happen with less
intertwining with the rest of the code, but that can happen later. I
would expect that you'd basically just need clocks and regulators on
and maybe your PHY on."

Yes PHY needs to be absolutely on and configured before aux transfers.

If we want to change that up to stop reading the panel_id in the panel
probe() and do it later, perhaps some of the changes done here are not
needed.

It only seems reasonable that we first prototype that in a separate
patch even a RFC perhaps and take this further as these set of changes
are needed for basic display functionality on sc7280 chromebooks.

Let us know what are the concerns with doing it in a follow up change.

Thanks

Abhinav

2022-04-07 21:38:46

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Thu, Apr 7, 2022 at 1:11 PM Abhinav Kumar <[email protected]> wrote:
>
> Hi Doug and Dmitry
>
> Sorry, but I caught up on this email just now.
>
> Some comments below.
>
> Thanks
>
> Abhinav
> On 4/7/2022 10:07 AM, Doug Anderson wrote:
> > Hi,
> >
> > On Thu, Apr 7, 2022 at 7:19 AM Sankeerth Billakanti (QUIC)
> > <[email protected]> wrote:
> >>
> >> Hi Dmitry and Doug,
> >>
> >>> Hi,
> >>>
> >>> On Tue, Apr 5, 2022 at 10:36 AM Dmitry Baryshkov
> >>> <[email protected]> wrote:
> >>>>
> >>>> On 05/04/2022 20:02, Doug Anderson wrote:
> >>>>> Hi,
> >>>>>
> >>>>> On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
> >>>>> <[email protected]> wrote:
> >>>>>>> 3. For DP and eDP HPD means something a little different.
> >>>>>>> Essentially there are two concepts: a) is a display physically
> >>>>>>> connected and b) is the display powered up and ready. For DP, the
> >>>>>>> two are really tied together. From the kernel's point of view you
> >>>>>>> never "power down" a DP display and you can't detect that it's
> >>>>>>> physically connected until it's ready. Said another way, on you
> >>>>>>> tie "is a display there" to the HPD line and the moment a display
> >>>>>>> is there it's ready for you to do AUX transfers. For eDP, in the
> >>>>>>> lowest power state of a display it _won't_ assert its "HPD"
> >>>>>>> signal. However, it's still physically present. For eDP you simply
> >>>>>>> have to _assume_ it's present without any actual proof since you
> >>>>>>> can't get proof until you power it up. Thus for eDP, you report
> >>>>>>> that the display is there as soon as we're asked. We can't _talk_
> >>>>>>> to the display yet, though. So in get_modes() we need to be able
> >>>>>>> to power the display on enough to talk over the AUX channel to it.
> >>>>>>> As part of this, we wait for the signal named "HPD" which really means
> >>> "panel finished powering on" in this context.
> >>>>>>>
> >>>>>>> NOTE: for aux transfer, we don't have the _display_ pipe and
> >>>>>>> clocks running. We only have enough stuff running to do the AUX
> >>> transfer.
> >>>>>>> We're not clocking out pixels. We haven't fully powered on the
> >>>>>>> display. The AUX transfer is designed to be something that can be
> >>>>>>> done early _before_ you turn on the display.
> >>>>>>>
> >>>>>>>
> >>>>>>> OK, so basically that was a longwinded way of saying: yes, we
> >>>>>>> could avoid the AUX transfer in probe, but we can't wait all the
> >>>>>>> way to enable. We have to be able to transfer in get_modes(). If
> >>>>>>> you think that's helpful I think it'd be a pretty easy patch to
> >>>>>>> write even if it would look a tad bit awkward IMO. Let me know if
> >>>>>>> you want me to post it up.
> >>>>>>
> >>>>>> I think it would be a good idea. At least it will allow us to
> >>>>>> judge, which is the more correct way.
> >>>>>
> >>>>> I'm still happy to prototype this, but the more I think about it the
> >>>>> more it feels like a workaround for the Qualcomm driver. The eDP
> >>>>> panel driver is actually given a pointer to the AUX bus at probe
> >>>>> time. It's really weird to say that we can't do a transfer on it
> >>>>> yet... As you said, this is a little sideband bus. It should be able
> >>>>> to be used without all the full blown infra of the rest of the driver.
> >>>>
> >>>> Yes, I have that feeling too. However I also have a feeling that just
> >>>> powering up the PHY before the bus probe is ... a hack. There are no
> >>>> obvious stopgaps for the driver not to power it down later.
> >>>
>
> Lets go back to why we need to power up the PHY before the bus probe.
>
> We need to power up PHY before bus probe because panel-eDP tries to read
> the EDID in probe() for the panel_id. Not get_modes().
>
> So doug, I didnt follow your comment that panel-eDP only does EDID read
> in get_modes()
>
> panel_id = drm_edid_get_panel_id(panel->ddc);
> if (!panel_id) {
> dev_err(dev, "Couldn't identify panel via EDID\n");
> ret = -EIO;
> goto exit;
> }
>
> If we do not need this part, we really dont need to power up the PHY
> before the probe(). The hack which dmitry was referring to.

Right. ...so we _could_ remove the above from the panel-edp probe and
defer it to get_modes() and it wouldn't be that hard. ...but:

1. It feels like a hack to work around the Qualcomm driver. The way
the AUX bus is designed is that a pointer to the AUX bus is passed to
the panel-edp probe. It seems kinda strange to say that the panel
isn't allowed to do transfers with the pointer that's passed in.

2. There's a second place where we might do an AUX transfer at probe
time which is when we're using the DP AUX backlight. There we call
drm_panel_dp_aux_backlight(). Conceivably this too could be deferred
until the get_modes(), but now it feels even more like a hack. We're
going to be registering the backlight in the first call to
get_modes()? That's, ummm, unexpected. We could look at perhaps
breaking the "DP AUX backlight" in two parts also, but that gets
involved. I think we're supposed to know the number of backlight
levels at device init time for backlight devices and we need an AUX
transfer to that.


So the answer is that we could probably make it work, but it seems
like an uglier solution than just making the Qualcomm driver able to
do AUX transfers when it should be able to.

> So this is boiling down to why or how panel-eDP was originally designed.
>
> >>> This is why I think we need to move to Runtime PM to manage this. Basically:
> >>>
> >>> 1. When an AUX transfer happens, you grab a PM runtime reference that
> >>> _that_ powers up the PHY.
>
> This will not be trivial and needs to be scoped out as sankeerth said
> but if the above is the only concern, why do we need to do this? There
> seems to be an explanation why we are doing this and its not a hack.
>
> How would Dmitry's rework address this? We need some RFC to conclude on
> that first.
>
> >>>
> >>> 2. At the end of the AUX transfer function, you do a "put_autosuspend".
> >>>
> >>> Then it becomes not a hack, right?
> >>>
> >>>
> >>
> >> pm runtime ops needs to be implemented for both eDP and DP. This change
> >> take good amount of planning and code changes as it affects DP also.
> >>
> >> Because this patch series consist of basic eDP changes for SC7280 bootup,
> >> shall we take this pm_runtime implementation in subsequent patch series?
> >
> > Dmitry is the real decision maker here, but in my opinion it would be
> > OK to get something landed first that worked OK and wasn't taking us
> > too far in the wrong direction and then we could get a follow up patch
> > to move to pm_runtime.
>
> I would say the discussion changed into a direction of implementing
> pm-runtime because the current patch series does what it takes to adhere
> to panel-eDP's design along with aux bus requirements of PHY needing to
> be on.
>
> So doug, to answer your questions here:
>
> "So I guess the net result is maybe we should just keep it where it is.
> Long term I'd be interested in knowing if there's a reason why we
> can't structure the driver so that AUX transfers can happen with less
> intertwining with the rest of the code, but that can happen later. I
> would expect that you'd basically just need clocks and regulators on
> and maybe your PHY on."
>
> Yes PHY needs to be absolutely on and configured before aux transfers.
>
> If we want to change that up to stop reading the panel_id in the panel
> probe() and do it later, perhaps some of the changes done here are not
> needed.
>
> It only seems reasonable that we first prototype that in a separate
> patch even a RFC perhaps and take this further as these set of changes
> are needed for basic display functionality on sc7280 chromebooks.
>
> Let us know what are the concerns with doing it in a follow up change.

As per above, I'm not objecting to it being a follow-up change, but I
do believe it's the right design and will lead to an overall cleaner
solution. I think I even mentioned in my reviews that the current
patch series seems to "scattershot" enable resources and that's how we
end up with patches like patch #5 in this series ("drm/msm/dp: prevent
multiple votes for dp resources"). IMO there should be be a 1-to-1
mapping between "turn on resources" and "turn off resources" and it
should be reference counted. So if your codepath turned on resources
then it's up to your codepath to turn resources off when done. If a
seconde code path might be running at the same time then it should
also turn on/off resources itself. ...and it should all be managed by
pm_runtime which is _exactly designed_ for this specific use case.

-Doug

2022-04-07 22:38:47

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi Doug

Thanks for the response, some comments below.

Abhinav
On 4/7/2022 1:47 PM, Doug Anderson wrote:
> Hi,
>
> On Thu, Apr 7, 2022 at 1:11 PM Abhinav Kumar <[email protected]> wrote:
>>
>> Hi Doug and Dmitry
>>
>> Sorry, but I caught up on this email just now.
>>
>> Some comments below.
>>
>> Thanks
>>
>> Abhinav
>> On 4/7/2022 10:07 AM, Doug Anderson wrote:
>>> Hi,
>>>
>>> On Thu, Apr 7, 2022 at 7:19 AM Sankeerth Billakanti (QUIC)
>>> <[email protected]> wrote:
>>>>
>>>> Hi Dmitry and Doug,
>>>>
>>>>> Hi,
>>>>>
>>>>> On Tue, Apr 5, 2022 at 10:36 AM Dmitry Baryshkov
>>>>> <[email protected]> wrote:
>>>>>>
>>>>>> On 05/04/2022 20:02, Doug Anderson wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
>>>>>>> <[email protected]> wrote:
>>>>>>>>> 3. For DP and eDP HPD means something a little different.
>>>>>>>>> Essentially there are two concepts: a) is a display physically
>>>>>>>>> connected and b) is the display powered up and ready. For DP, the
>>>>>>>>> two are really tied together. From the kernel's point of view you
>>>>>>>>> never "power down" a DP display and you can't detect that it's
>>>>>>>>> physically connected until it's ready. Said another way, on you
>>>>>>>>> tie "is a display there" to the HPD line and the moment a display
>>>>>>>>> is there it's ready for you to do AUX transfers. For eDP, in the
>>>>>>>>> lowest power state of a display it _won't_ assert its "HPD"
>>>>>>>>> signal. However, it's still physically present. For eDP you simply
>>>>>>>>> have to _assume_ it's present without any actual proof since you
>>>>>>>>> can't get proof until you power it up. Thus for eDP, you report
>>>>>>>>> that the display is there as soon as we're asked. We can't _talk_
>>>>>>>>> to the display yet, though. So in get_modes() we need to be able
>>>>>>>>> to power the display on enough to talk over the AUX channel to it.
>>>>>>>>> As part of this, we wait for the signal named "HPD" which really means
>>>>> "panel finished powering on" in this context.
>>>>>>>>>
>>>>>>>>> NOTE: for aux transfer, we don't have the _display_ pipe and
>>>>>>>>> clocks running. We only have enough stuff running to do the AUX
>>>>> transfer.
>>>>>>>>> We're not clocking out pixels. We haven't fully powered on the
>>>>>>>>> display. The AUX transfer is designed to be something that can be
>>>>>>>>> done early _before_ you turn on the display.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> OK, so basically that was a longwinded way of saying: yes, we
>>>>>>>>> could avoid the AUX transfer in probe, but we can't wait all the
>>>>>>>>> way to enable. We have to be able to transfer in get_modes(). If
>>>>>>>>> you think that's helpful I think it'd be a pretty easy patch to
>>>>>>>>> write even if it would look a tad bit awkward IMO. Let me know if
>>>>>>>>> you want me to post it up.
>>>>>>>>
>>>>>>>> I think it would be a good idea. At least it will allow us to
>>>>>>>> judge, which is the more correct way.
>>>>>>>
>>>>>>> I'm still happy to prototype this, but the more I think about it the
>>>>>>> more it feels like a workaround for the Qualcomm driver. The eDP
>>>>>>> panel driver is actually given a pointer to the AUX bus at probe
>>>>>>> time. It's really weird to say that we can't do a transfer on it
>>>>>>> yet... As you said, this is a little sideband bus. It should be able
>>>>>>> to be used without all the full blown infra of the rest of the driver.
>>>>>>
>>>>>> Yes, I have that feeling too. However I also have a feeling that just
>>>>>> powering up the PHY before the bus probe is ... a hack. There are no
>>>>>> obvious stopgaps for the driver not to power it down later.
>>>>>
>>
>> Lets go back to why we need to power up the PHY before the bus probe.
>>
>> We need to power up PHY before bus probe because panel-eDP tries to read
>> the EDID in probe() for the panel_id. Not get_modes().
>>
>> So doug, I didnt follow your comment that panel-eDP only does EDID read
>> in get_modes()
>>
>> panel_id = drm_edid_get_panel_id(panel->ddc);
>> if (!panel_id) {
>> dev_err(dev, "Couldn't identify panel via EDID\n");
>> ret = -EIO;
>> goto exit;
>> }
>>
>> If we do not need this part, we really dont need to power up the PHY
>> before the probe(). The hack which dmitry was referring to.
>
> Right. ...so we _could_ remove the above from the panel-edp probe and
> defer it to get_modes() and it wouldn't be that hard. ...but:
>
> 1. It feels like a hack to work around the Qualcomm driver. The way
> the AUX bus is designed is that a pointer to the AUX bus is passed to
> the panel-edp probe. It seems kinda strange to say that the panel
> isn't allowed to do transfers with the pointer that's passed in.
>

And thats why to satisfy the requirements of passing an initialized AUX,
sankeerth is delaying devm_of_dp_aux_populate_ep_devices() till PHY is
initialized which seems reasonable to satisfy the probe() time requirements.

Even if we move to pm_runtime(), yes I agree it will club all the
resources needed to control AUX in one place but you will still have to
initialize PHY before probe() under the hood of pm_runtime().

So how will it help this cause?

We just have to accept that initializing PHY is a requirement to use AUX
and before calling panel-eDP's probe(), we have to have an initialized AUX.

So we are not working around the driver but just satisfying the hardware
requirements to be able to satisfy panel-edp's and
drm_panel_dp_aux_backlight()'s aux bus requirements.

> 2. There's a second place where we might do an AUX transfer at probe
> time which is when we're using the DP AUX backlight. There we call
> drm_panel_dp_aux_backlight(). Conceivably this too could be deferred
> until the get_modes(), but now it feels even more like a hack. We're
> going to be registering the backlight in the first call to
> get_modes()? That's, ummm, unexpected. We could look at perhaps
> breaking the "DP AUX backlight" in two parts also, but that gets
> involved. I think we're supposed to know the number of backlight
> levels at device init time for backlight devices and we need an AUX
> transfer to that.
>


>
> So the answer is that we could probably make it work, but it seems
> like an uglier solution than just making the Qualcomm driver able to
> do AUX transfers when it should be able to.

Correct and by delaying the panel-edp's probe(), we are doing exactly that?

>
>> So this is boiling down to why or how panel-eDP was originally designed.
>>
>>>>> This is why I think we need to move to Runtime PM to manage this. Basically:
>>>>>
>>>>> 1. When an AUX transfer happens, you grab a PM runtime reference that
>>>>> _that_ powers up the PHY.
>>
>> This will not be trivial and needs to be scoped out as sankeerth said
>> but if the above is the only concern, why do we need to do this? There
>> seems to be an explanation why we are doing this and its not a hack.
>>
>> How would Dmitry's rework address this? We need some RFC to conclude on
>> that first.
>>
>>>>>
>>>>> 2. At the end of the AUX transfer function, you do a "put_autosuspend".
>>>>>
>>>>> Then it becomes not a hack, right?
>>>>>
>>>>>
>>>>
>>>> pm runtime ops needs to be implemented for both eDP and DP. This change
>>>> take good amount of planning and code changes as it affects DP also.
>>>>
>>>> Because this patch series consist of basic eDP changes for SC7280 bootup,
>>>> shall we take this pm_runtime implementation in subsequent patch series?
>>>
>>> Dmitry is the real decision maker here, but in my opinion it would be
>>> OK to get something landed first that worked OK and wasn't taking us
>>> too far in the wrong direction and then we could get a follow up patch
>>> to move to pm_runtime.
>>
>> I would say the discussion changed into a direction of implementing
>> pm-runtime because the current patch series does what it takes to adhere
>> to panel-eDP's design along with aux bus requirements of PHY needing to
>> be on.
>>
>> So doug, to answer your questions here:
>>
>> "So I guess the net result is maybe we should just keep it where it is.
>> Long term I'd be interested in knowing if there's a reason why we
>> can't structure the driver so that AUX transfers can happen with less
>> intertwining with the rest of the code, but that can happen later. I
>> would expect that you'd basically just need clocks and regulators on
>> and maybe your PHY on."
>>
>> Yes PHY needs to be absolutely on and configured before aux transfers.
>>
>> If we want to change that up to stop reading the panel_id in the panel
>> probe() and do it later, perhaps some of the changes done here are not
>> needed.
>>
>> It only seems reasonable that we first prototype that in a separate
>> patch even a RFC perhaps and take this further as these set of changes
>> are needed for basic display functionality on sc7280 chromebooks.
>>
>> Let us know what are the concerns with doing it in a follow up change.
>
> As per above, I'm not objecting to it being a follow-up change, but I
> do believe it's the right design and will lead to an overall cleaner
> solution. I think I even mentioned in my reviews that the current
> patch series seems to "scattershot" enable resources and that's how we
> end up with patches like patch #5 in this series ("drm/msm/dp: prevent
> multiple votes for dp resources"). IMO there should be be a 1-to-1
> mapping between "turn on resources" and "turn off resources" and it
> should be reference counted. So if your codepath turned on resources
> then it's up to your codepath to turn resources off when done. If a
> seconde code path might be running at the same time then it should
> also turn on/off resources itself. ...and it should all be managed by
> pm_runtime which is _exactly designed_ for this specific use case.
>
Agreed on this topic, moving to pm_runtime() will club all resources in
one place and make things cleaner that way.

Complexity of it obviously needs to be evaluated to check the effort Vs
rewards.

But it will still not address the original concern of this thread that
powering up the PHY before the probe() is a hack.

"Yes, I have that feeling too. However I also have a feeling that just
> powering up the PHY before the bus probe is ... a hack. There are no
> obvious stopgaps for the driver not to power it down later."

We would still end up doing that under the hood of pm_runtime.

And thats why its an improvement and not a necessity qualifying it for a
separate change.

> -Doug

2022-04-08 00:06:40

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On Thu, 7 Apr 2022 at 23:11, Abhinav Kumar <[email protected]> wrote:
>
> Hi Doug and Dmitry
>
> Sorry, but I caught up on this email just now.
>
> Some comments below.
>
> Thanks
>
> Abhinav
> On 4/7/2022 10:07 AM, Doug Anderson wrote:
> > Hi,
> >
> > On Thu, Apr 7, 2022 at 7:19 AM Sankeerth Billakanti (QUIC)
> > <[email protected]> wrote:
> >>
> >> Hi Dmitry and Doug,
> >>
> >>> Hi,
> >>>
> >>> On Tue, Apr 5, 2022 at 10:36 AM Dmitry Baryshkov
> >>> <[email protected]> wrote:
> >>>>
> >>>> On 05/04/2022 20:02, Doug Anderson wrote:
> >>>>> Hi,
> >>>>>
> >>>>> On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
> >>>>> <[email protected]> wrote:
> >>>>>>> 3. For DP and eDP HPD means something a little different.
> >>>>>>> Essentially there are two concepts: a) is a display physically
> >>>>>>> connected and b) is the display powered up and ready. For DP, the
> >>>>>>> two are really tied together. From the kernel's point of view you
> >>>>>>> never "power down" a DP display and you can't detect that it's
> >>>>>>> physically connected until it's ready. Said another way, on you
> >>>>>>> tie "is a display there" to the HPD line and the moment a display
> >>>>>>> is there it's ready for you to do AUX transfers. For eDP, in the
> >>>>>>> lowest power state of a display it _won't_ assert its "HPD"
> >>>>>>> signal. However, it's still physically present. For eDP you simply
> >>>>>>> have to _assume_ it's present without any actual proof since you
> >>>>>>> can't get proof until you power it up. Thus for eDP, you report
> >>>>>>> that the display is there as soon as we're asked. We can't _talk_
> >>>>>>> to the display yet, though. So in get_modes() we need to be able
> >>>>>>> to power the display on enough to talk over the AUX channel to it.
> >>>>>>> As part of this, we wait for the signal named "HPD" which really means
> >>> "panel finished powering on" in this context.
> >>>>>>>
> >>>>>>> NOTE: for aux transfer, we don't have the _display_ pipe and
> >>>>>>> clocks running. We only have enough stuff running to do the AUX
> >>> transfer.
> >>>>>>> We're not clocking out pixels. We haven't fully powered on the
> >>>>>>> display. The AUX transfer is designed to be something that can be
> >>>>>>> done early _before_ you turn on the display.
> >>>>>>>
> >>>>>>>
> >>>>>>> OK, so basically that was a longwinded way of saying: yes, we
> >>>>>>> could avoid the AUX transfer in probe, but we can't wait all the
> >>>>>>> way to enable. We have to be able to transfer in get_modes(). If
> >>>>>>> you think that's helpful I think it'd be a pretty easy patch to
> >>>>>>> write even if it would look a tad bit awkward IMO. Let me know if
> >>>>>>> you want me to post it up.
> >>>>>>
> >>>>>> I think it would be a good idea. At least it will allow us to
> >>>>>> judge, which is the more correct way.
> >>>>>
> >>>>> I'm still happy to prototype this, but the more I think about it the
> >>>>> more it feels like a workaround for the Qualcomm driver. The eDP
> >>>>> panel driver is actually given a pointer to the AUX bus at probe
> >>>>> time. It's really weird to say that we can't do a transfer on it
> >>>>> yet... As you said, this is a little sideband bus. It should be able
> >>>>> to be used without all the full blown infra of the rest of the driver.
> >>>>
> >>>> Yes, I have that feeling too. However I also have a feeling that just
> >>>> powering up the PHY before the bus probe is ... a hack. There are no
> >>>> obvious stopgaps for the driver not to power it down later.
> >>>
>
> Lets go back to why we need to power up the PHY before the bus probe.
>
> We need to power up PHY before bus probe because panel-eDP tries to read
> the EDID in probe() for the panel_id. Not get_modes().
>
> So doug, I didnt follow your comment that panel-eDP only does EDID read
> in get_modes()
>
> panel_id = drm_edid_get_panel_id(panel->ddc);
> if (!panel_id) {
> dev_err(dev, "Couldn't identify panel via EDID\n");
> ret = -EIO;
> goto exit;
> }
>
> If we do not need this part, we really dont need to power up the PHY
> before the probe(). The hack which dmitry was referring to.
>
> So this is boiling down to why or how panel-eDP was originally designed.

Well, it's not just panel-edp. It boils down to the DP-AUX bus design
vs DRM design. However in Doug's defense I should admit that I can not
come up with a significantly cleaner solution.

Just to emphasise (or to repeat): for all other display
panels/bridges, we either do not use a sidechannel bus or the
sidechannel bus (i2c, spi, platform) is managed outside of the DRM
framework. Thus it's possible to create the source in the drm's driver
probe path and then in the component's bind() path check (and return
an error) if the sink device wasn't yet probed successfully. The
source can then either communicate with the sink using the sidechannel
bus provided elsewhere or (e.g. in case of purely DSI panel), defer
communication till the moment the display path is fully available
(after encoder enablement).

For the DP/eDP the sidechannel (DP AUX) bus is closer to the display
path. It can not be used separately. For DP we can defer all
communication till the moment we know (through the DP/USB-C/etc
hotplug mechanism) that the sink is really available and running.

The eDP is being caught in between these two approaches:

For example sn65dsi86 and tegra have separate dpaux and separate
bridge/output devices. Thus dpaux'es probe() methos populates DP AUX
bus, then a separate device checks whether the panel/bridge has become
available in its own probe() method.

The ps8640 driver looks 'working by coincidence'. It calls
dp_aux_populate, then immediately after the function returns it checks
for the panel. If panel-edp is built as a module, the probe might fail
easily.
The anx7625 driver has the same kind of issue. The DP AUX bus is
populated from the probe() and after some additional work the panel is
being checked.
This design is fragile and from my quick glance it can break (or be
broken) too easy. It reminds me of our drm msm 'probe' loops
preventing the device to boot completely if the dsi bridge/panel could
not be probed in time.

If we talk about DP AUX bus EP drivers, both panel-edp and
panel-samsung-atna33xc20 (the only EP drivers present in Linux master)
expect that they can access DPCD from the probe method.

Now back to Qualcomm DP driver. We do not have a separate dpaux
entity. If leave aside the idea of adding a separate 'bus available'
callback, I see two possible solutions:

- Implement separate lightweight eDP driver sharing source with the DP
driver. Make it skip all the DP HPD craziness, init PHY and call
devm_of_dp_aux_ep_populate_ep_devices() from the probe method, check
in the bind method that the next bridge is available. However this can
potentially break ports which can be used either in the DP or in eDP
mode.

or

- Modify existing Qualcomm DP driver to return -EPROBE_DEFER from
dp_aux_transfer() if the AUX bus is not available. Make the driver
init PHY from probe() if it is running in the eDP mode. Populate DP
AUX bus from probe(). Check for the next bridge in dp_bind().

There might be potentially other possibilities, but I think you have
my main idea. Create the bus in probe(), check for the bridge in
bind().

or

- Create a bus at some point in bind. Forbid (and document that) AUX
access from EP probe(). Access it only from get_modes().


>
> >>> This is why I think we need to move to Runtime PM to manage this. Basically:
> >>>
> >>> 1. When an AUX transfer happens, you grab a PM runtime reference that
> >>> _that_ powers up the PHY.
>
> This will not be trivial and needs to be scoped out as sankeerth said
> but if the above is the only concern, why do we need to do this? There
> seems to be an explanation why we are doing this and its not a hack.
>
> How would Dmitry's rework address this? We need some RFC to conclude on
> that first.

Just to put things clear: I do not have plans to work on either of my
suggestions at least in the next few months. I do not have eDP hardware at hand.




>
> >>>
> >>> 2. At the end of the AUX transfer function, you do a "put_autosuspend".
> >>>
> >>> Then it becomes not a hack, right?
> >>>
> >>>
> >>
> >> pm runtime ops needs to be implemented for both eDP and DP. This change
> >> take good amount of planning and code changes as it affects DP also.
> >>
> >> Because this patch series consist of basic eDP changes for SC7280 bootup,
> >> shall we take this pm_runtime implementation in subsequent patch series?
> >
> > Dmitry is the real decision maker here, but in my opinion it would be
> > OK to get something landed first that worked OK and wasn't taking us
> > too far in the wrong direction and then we could get a follow up patch
> > to move to pm_runtime.
>
> I would say the discussion changed into a direction of implementing
> pm-runtime because the current patch series does what it takes to adhere
> to panel-eDP's design along with aux bus requirements of PHY needing to
> be on.
>
> So doug, to answer your questions here:
>
> "So I guess the net result is maybe we should just keep it where it is.
> Long term I'd be interested in knowing if there's a reason why we
> can't structure the driver so that AUX transfers can happen with less
> intertwining with the rest of the code, but that can happen later. I
> would expect that you'd basically just need clocks and regulators on
> and maybe your PHY on."
>
> Yes PHY needs to be absolutely on and configured before aux transfers.
>
> If we want to change that up to stop reading the panel_id in the panel
> probe() and do it later, perhaps some of the changes done here are not
> needed.
>
> It only seems reasonable that we first prototype that in a separate
> patch even a RFC perhaps and take this further as these set of changes
> are needed for basic display functionality on sc7280 chromebooks.
>
> Let us know what are the concerns with doing it in a follow up change.
>
> Thanks
>
> Abhinav



--
With best wishes
Dmitry

2022-04-08 00:12:16

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Thu, Apr 7, 2022 at 3:03 PM Abhinav Kumar <[email protected]> wrote:
>
> Hi Doug
>
> Thanks for the response, some comments below.
>
> Abhinav
> On 4/7/2022 1:47 PM, Doug Anderson wrote:
> > Hi,
> >
> > On Thu, Apr 7, 2022 at 1:11 PM Abhinav Kumar <[email protected]> wrote:
> >>
> >> Hi Doug and Dmitry
> >>
> >> Sorry, but I caught up on this email just now.
> >>
> >> Some comments below.
> >>
> >> Thanks
> >>
> >> Abhinav
> >> On 4/7/2022 10:07 AM, Doug Anderson wrote:
> >>> Hi,
> >>>
> >>> On Thu, Apr 7, 2022 at 7:19 AM Sankeerth Billakanti (QUIC)
> >>> <[email protected]> wrote:
> >>>>
> >>>> Hi Dmitry and Doug,
> >>>>
> >>>>> Hi,
> >>>>>
> >>>>> On Tue, Apr 5, 2022 at 10:36 AM Dmitry Baryshkov
> >>>>> <[email protected]> wrote:
> >>>>>>
> >>>>>> On 05/04/2022 20:02, Doug Anderson wrote:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
> >>>>>>> <[email protected]> wrote:
> >>>>>>>>> 3. For DP and eDP HPD means something a little different.
> >>>>>>>>> Essentially there are two concepts: a) is a display physically
> >>>>>>>>> connected and b) is the display powered up and ready. For DP, the
> >>>>>>>>> two are really tied together. From the kernel's point of view you
> >>>>>>>>> never "power down" a DP display and you can't detect that it's
> >>>>>>>>> physically connected until it's ready. Said another way, on you
> >>>>>>>>> tie "is a display there" to the HPD line and the moment a display
> >>>>>>>>> is there it's ready for you to do AUX transfers. For eDP, in the
> >>>>>>>>> lowest power state of a display it _won't_ assert its "HPD"
> >>>>>>>>> signal. However, it's still physically present. For eDP you simply
> >>>>>>>>> have to _assume_ it's present without any actual proof since you
> >>>>>>>>> can't get proof until you power it up. Thus for eDP, you report
> >>>>>>>>> that the display is there as soon as we're asked. We can't _talk_
> >>>>>>>>> to the display yet, though. So in get_modes() we need to be able
> >>>>>>>>> to power the display on enough to talk over the AUX channel to it.
> >>>>>>>>> As part of this, we wait for the signal named "HPD" which really means
> >>>>> "panel finished powering on" in this context.
> >>>>>>>>>
> >>>>>>>>> NOTE: for aux transfer, we don't have the _display_ pipe and
> >>>>>>>>> clocks running. We only have enough stuff running to do the AUX
> >>>>> transfer.
> >>>>>>>>> We're not clocking out pixels. We haven't fully powered on the
> >>>>>>>>> display. The AUX transfer is designed to be something that can be
> >>>>>>>>> done early _before_ you turn on the display.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> OK, so basically that was a longwinded way of saying: yes, we
> >>>>>>>>> could avoid the AUX transfer in probe, but we can't wait all the
> >>>>>>>>> way to enable. We have to be able to transfer in get_modes(). If
> >>>>>>>>> you think that's helpful I think it'd be a pretty easy patch to
> >>>>>>>>> write even if it would look a tad bit awkward IMO. Let me know if
> >>>>>>>>> you want me to post it up.
> >>>>>>>>
> >>>>>>>> I think it would be a good idea. At least it will allow us to
> >>>>>>>> judge, which is the more correct way.
> >>>>>>>
> >>>>>>> I'm still happy to prototype this, but the more I think about it the
> >>>>>>> more it feels like a workaround for the Qualcomm driver. The eDP
> >>>>>>> panel driver is actually given a pointer to the AUX bus at probe
> >>>>>>> time. It's really weird to say that we can't do a transfer on it
> >>>>>>> yet... As you said, this is a little sideband bus. It should be able
> >>>>>>> to be used without all the full blown infra of the rest of the driver.
> >>>>>>
> >>>>>> Yes, I have that feeling too. However I also have a feeling that just
> >>>>>> powering up the PHY before the bus probe is ... a hack. There are no
> >>>>>> obvious stopgaps for the driver not to power it down later.
> >>>>>
> >>
> >> Lets go back to why we need to power up the PHY before the bus probe.
> >>
> >> We need to power up PHY before bus probe because panel-eDP tries to read
> >> the EDID in probe() for the panel_id. Not get_modes().
> >>
> >> So doug, I didnt follow your comment that panel-eDP only does EDID read
> >> in get_modes()
> >>
> >> panel_id = drm_edid_get_panel_id(panel->ddc);
> >> if (!panel_id) {
> >> dev_err(dev, "Couldn't identify panel via EDID\n");
> >> ret = -EIO;
> >> goto exit;
> >> }
> >>
> >> If we do not need this part, we really dont need to power up the PHY
> >> before the probe(). The hack which dmitry was referring to.
> >
> > Right. ...so we _could_ remove the above from the panel-edp probe and
> > defer it to get_modes() and it wouldn't be that hard. ...but:
> >
> > 1. It feels like a hack to work around the Qualcomm driver. The way
> > the AUX bus is designed is that a pointer to the AUX bus is passed to
> > the panel-edp probe. It seems kinda strange to say that the panel
> > isn't allowed to do transfers with the pointer that's passed in.
> >
>
> And thats why to satisfy the requirements of passing an initialized AUX,
> sankeerth is delaying devm_of_dp_aux_populate_ep_devices() till PHY is
> initialized which seems reasonable to satisfy the probe() time requirements.
>
> Even if we move to pm_runtime(), yes I agree it will club all the
> resources needed to control AUX in one place but you will still have to
> initialize PHY before probe() under the hood of pm_runtime().
>
> So how will it help this cause?
>
> We just have to accept that initializing PHY is a requirement to use AUX
> and before calling panel-eDP's probe(), we have to have an initialized AUX.
>
> So we are not working around the driver but just satisfying the hardware
> requirements to be able to satisfy panel-edp's and
> drm_panel_dp_aux_backlight()'s aux bus requirements.

The way I'm arguing it should work is that:

1. A whole bunch of the DP init code should move to the DP driver's
probe function. This includes parsing the DT, acquiring clocks,
getting a handle to our PHY, and IO mapping registers. As far as I
know, there's no reason to wait on all the components being probed in
order to do this stuff.

2. Once we have done the above things, it should be possible to do AUX
transfers, correct? ...and then we can populate the AUX bus from the
probe function too.

3. Any other init (setting up pixel clocks) can continue to happen
where it is today.


> > 2. There's a second place where we might do an AUX transfer at probe
> > time which is when we're using the DP AUX backlight. There we call
> > drm_panel_dp_aux_backlight(). Conceivably this too could be deferred
> > until the get_modes(), but now it feels even more like a hack. We're
> > going to be registering the backlight in the first call to
> > get_modes()? That's, ummm, unexpected. We could look at perhaps
> > breaking the "DP AUX backlight" in two parts also, but that gets
> > involved. I think we're supposed to know the number of backlight
> > levels at device init time for backlight devices and we need an AUX
> > transfer to that.
> >
>
>
> >
> > So the answer is that we could probably make it work, but it seems
> > like an uglier solution than just making the Qualcomm driver able to
> > do AUX transfers when it should be able to.
>
> Correct and by delaying the panel-edp's probe(), we are doing exactly that?

Right. Where you put the probe now makes it work OK from an AUX
transfer point of view and it's probably OK for the short term, but
I'm not 100% convinced it would handle the -EPROBE_DEFER case, though
I haven't actually tested it.

Imagine this case:

1. 100% of your code is built-in to the kernel except for your PWM
driver, which is a module.

2. You start booting up. All the DRM components for MSM are finished
and eventually modeset_init() gets called.

3. We try to probe the panel. When the panel tries to acquire the PWM
backlight, it finds that the PWM driver hasn't been loaded yet. It
gets back -EPROBE_DEFER which prevents the panel driver from probing.

The question is: does modeset_init() handle that -EPROBE_DEFER
elegantly? Normally that's something that would only be returned by
probe functions. Maybe this is all handled, though? I definitely
haven't followed enough of the code and haven't tested it myself.

The above is probably not a giant deal, but I think long term it would
be better to be acquiring resources earlier.

2022-04-08 00:16:31

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On Fri, 8 Apr 2022 at 02:35, Doug Anderson <[email protected]> wrote:
>
> Hi,
>
> On Thu, Apr 7, 2022 at 3:03 PM Abhinav Kumar <[email protected]> wrote:
> >
> > Hi Doug
> >
> > Thanks for the response, some comments below.
> >
> > Abhinav
> > On 4/7/2022 1:47 PM, Doug Anderson wrote:
> > > Hi,
> > >
> > > On Thu, Apr 7, 2022 at 1:11 PM Abhinav Kumar <[email protected]> wrote:
> > >>
> > >> Hi Doug and Dmitry
> > >>
> > >> Sorry, but I caught up on this email just now.
> > >>
> > >> Some comments below.
> > >>
> > >> Thanks
> > >>
> > >> Abhinav
> > >> On 4/7/2022 10:07 AM, Doug Anderson wrote:
> > >>> Hi,
> > >>>
> > >>> On Thu, Apr 7, 2022 at 7:19 AM Sankeerth Billakanti (QUIC)
> > >>> <[email protected]> wrote:
> > >>>>
> > >>>> Hi Dmitry and Doug,
> > >>>>
> > >>>>> Hi,
> > >>>>>
> > >>>>> On Tue, Apr 5, 2022 at 10:36 AM Dmitry Baryshkov
> > >>>>> <[email protected]> wrote:
> > >>>>>>
> > >>>>>> On 05/04/2022 20:02, Doug Anderson wrote:
> > >>>>>>> Hi,
> > >>>>>>>
> > >>>>>>> On Tue, Apr 5, 2022 at 5:54 AM Dmitry Baryshkov
> > >>>>>>> <[email protected]> wrote:
> > >>>>>>>>> 3. For DP and eDP HPD means something a little different.
> > >>>>>>>>> Essentially there are two concepts: a) is a display physically
> > >>>>>>>>> connected and b) is the display powered up and ready. For DP, the
> > >>>>>>>>> two are really tied together. From the kernel's point of view you
> > >>>>>>>>> never "power down" a DP display and you can't detect that it's
> > >>>>>>>>> physically connected until it's ready. Said another way, on you
> > >>>>>>>>> tie "is a display there" to the HPD line and the moment a display
> > >>>>>>>>> is there it's ready for you to do AUX transfers. For eDP, in the
> > >>>>>>>>> lowest power state of a display it _won't_ assert its "HPD"
> > >>>>>>>>> signal. However, it's still physically present. For eDP you simply
> > >>>>>>>>> have to _assume_ it's present without any actual proof since you
> > >>>>>>>>> can't get proof until you power it up. Thus for eDP, you report
> > >>>>>>>>> that the display is there as soon as we're asked. We can't _talk_
> > >>>>>>>>> to the display yet, though. So in get_modes() we need to be able
> > >>>>>>>>> to power the display on enough to talk over the AUX channel to it.
> > >>>>>>>>> As part of this, we wait for the signal named "HPD" which really means
> > >>>>> "panel finished powering on" in this context.
> > >>>>>>>>>
> > >>>>>>>>> NOTE: for aux transfer, we don't have the _display_ pipe and
> > >>>>>>>>> clocks running. We only have enough stuff running to do the AUX
> > >>>>> transfer.
> > >>>>>>>>> We're not clocking out pixels. We haven't fully powered on the
> > >>>>>>>>> display. The AUX transfer is designed to be something that can be
> > >>>>>>>>> done early _before_ you turn on the display.
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>> OK, so basically that was a longwinded way of saying: yes, we
> > >>>>>>>>> could avoid the AUX transfer in probe, but we can't wait all the
> > >>>>>>>>> way to enable. We have to be able to transfer in get_modes(). If
> > >>>>>>>>> you think that's helpful I think it'd be a pretty easy patch to
> > >>>>>>>>> write even if it would look a tad bit awkward IMO. Let me know if
> > >>>>>>>>> you want me to post it up.
> > >>>>>>>>
> > >>>>>>>> I think it would be a good idea. At least it will allow us to
> > >>>>>>>> judge, which is the more correct way.
> > >>>>>>>
> > >>>>>>> I'm still happy to prototype this, but the more I think about it the
> > >>>>>>> more it feels like a workaround for the Qualcomm driver. The eDP
> > >>>>>>> panel driver is actually given a pointer to the AUX bus at probe
> > >>>>>>> time. It's really weird to say that we can't do a transfer on it
> > >>>>>>> yet... As you said, this is a little sideband bus. It should be able
> > >>>>>>> to be used without all the full blown infra of the rest of the driver.
> > >>>>>>
> > >>>>>> Yes, I have that feeling too. However I also have a feeling that just
> > >>>>>> powering up the PHY before the bus probe is ... a hack. There are no
> > >>>>>> obvious stopgaps for the driver not to power it down later.
> > >>>>>
> > >>
> > >> Lets go back to why we need to power up the PHY before the bus probe.
> > >>
> > >> We need to power up PHY before bus probe because panel-eDP tries to read
> > >> the EDID in probe() for the panel_id. Not get_modes().
> > >>
> > >> So doug, I didnt follow your comment that panel-eDP only does EDID read
> > >> in get_modes()
> > >>
> > >> panel_id = drm_edid_get_panel_id(panel->ddc);
> > >> if (!panel_id) {
> > >> dev_err(dev, "Couldn't identify panel via EDID\n");
> > >> ret = -EIO;
> > >> goto exit;
> > >> }
> > >>
> > >> If we do not need this part, we really dont need to power up the PHY
> > >> before the probe(). The hack which dmitry was referring to.
> > >
> > > Right. ...so we _could_ remove the above from the panel-edp probe and
> > > defer it to get_modes() and it wouldn't be that hard. ...but:
> > >
> > > 1. It feels like a hack to work around the Qualcomm driver. The way
> > > the AUX bus is designed is that a pointer to the AUX bus is passed to
> > > the panel-edp probe. It seems kinda strange to say that the panel
> > > isn't allowed to do transfers with the pointer that's passed in.
> > >
> >
> > And thats why to satisfy the requirements of passing an initialized AUX,
> > sankeerth is delaying devm_of_dp_aux_populate_ep_devices() till PHY is
> > initialized which seems reasonable to satisfy the probe() time requirements.
> >
> > Even if we move to pm_runtime(), yes I agree it will club all the
> > resources needed to control AUX in one place but you will still have to
> > initialize PHY before probe() under the hood of pm_runtime().
> >
> > So how will it help this cause?
> >
> > We just have to accept that initializing PHY is a requirement to use AUX
> > and before calling panel-eDP's probe(), we have to have an initialized AUX.
> >
> > So we are not working around the driver but just satisfying the hardware
> > requirements to be able to satisfy panel-edp's and
> > drm_panel_dp_aux_backlight()'s aux bus requirements.
>
> The way I'm arguing it should work is that:
>
> 1. A whole bunch of the DP init code should move to the DP driver's
> probe function. This includes parsing the DT, acquiring clocks,
> getting a handle to our PHY, and IO mapping registers. As far as I
> know, there's no reason to wait on all the components being probed in
> order to do this stuff.

Yes. And that's one of the reasons I tried to stay away from the DP
driver. Each time I open the source code, my hands itch to start
refactoring the code.

>
> 2. Once we have done the above things, it should be possible to do AUX
> transfers, correct? ...and then we can populate the AUX bus from the
> probe function too.

No. In the DP case the AUX bus is inaccessible until the dongle is
plugged (see all the HPD handling, phy_init()/phy_power_on() is hidden
somewhere in that path)

eDP needs to be a special case in the probe() function.

>
> 3. Any other init (setting up pixel clocks) can continue to happen
> where it is today.

Yes.

>
>
> > > 2. There's a second place where we might do an AUX transfer at probe
> > > time which is when we're using the DP AUX backlight. There we call
> > > drm_panel_dp_aux_backlight(). Conceivably this too could be deferred
> > > until the get_modes(), but now it feels even more like a hack. We're
> > > going to be registering the backlight in the first call to
> > > get_modes()? That's, ummm, unexpected. We could look at perhaps
> > > breaking the "DP AUX backlight" in two parts also, but that gets
> > > involved. I think we're supposed to know the number of backlight
> > > levels at device init time for backlight devices and we need an AUX
> > > transfer to that.
> > >
> >
> >
> > >
> > > So the answer is that we could probably make it work, but it seems
> > > like an uglier solution than just making the Qualcomm driver able to
> > > do AUX transfers when it should be able to.
> >
> > Correct and by delaying the panel-edp's probe(), we are doing exactly that?
>
> Right. Where you put the probe now makes it work OK from an AUX
> transfer point of view and it's probably OK for the short term, but
> I'm not 100% convinced it would handle the -EPROBE_DEFER case, though
> I haven't actually tested it.
>
> Imagine this case:
>
> 1. 100% of your code is built-in to the kernel except for your PWM
> driver, which is a module.
>
> 2. You start booting up. All the DRM components for MSM are finished
> and eventually modeset_init() gets called.
>
> 3. We try to probe the panel. When the panel tries to acquire the PWM
> backlight, it finds that the PWM driver hasn't been loaded yet. It
> gets back -EPROBE_DEFER which prevents the panel driver from probing.
>
> The question is: does modeset_init() handle that -EPROBE_DEFER
> elegantly? Normally that's something that would only be returned by
> probe functions. Maybe this is all handled, though? I definitely
> haven't followed enough of the code and haven't tested it myself.

It would be handled up to some point. The error would propagate to the
msm_drm_init() = msm_drm_bind(), failing the mdss probe() (and putting
it to the defer list).
However in the dp's error path the driver would destroy the EP device.
The kernel would notice this and retry devices from the defer list. We
have just sorted this out for the DSI (thank you Maxime, Rob and
Angelo for doing this).

>
> The above is probably not a giant deal, but I think long term it would
> be better to be acquiring resources earlier.


--
With best wishes
Dmitry

2022-04-08 00:50:07

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Thu, Apr 7, 2022 at 4:36 PM Dmitry Baryshkov
<[email protected]> wrote:
>
> The ps8640 driver looks 'working by coincidence'. It calls
> dp_aux_populate, then immediately after the function returns it checks
> for the panel. If panel-edp is built as a module, the probe might fail
> easily.
> The anx7625 driver has the same kind of issue. The DP AUX bus is
> populated from the probe() and after some additional work the panel is
> being checked.
> This design is fragile and from my quick glance it can break (or be
> broken) too easy. It reminds me of our drm msm 'probe' loops
> preventing the device to boot completely if the dsi bridge/panel could
> not be probed in time.

I did spend some time thinking about this, at least for ps8640. I
believe that as long as the panel's probe isn't asynchronous.
Basically if the panel isn't ready then ps8640 should return and we'll
retry later. I do remember the probe loops that we used to have with
msm and I don't _think_ this would trigger it.

That being said, if we need to separate out the AUX bus into a
sub-device like we did in sn65dsi86 we certainly could.

-Doug

2022-04-08 00:50:55

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Thu, Apr 7, 2022 at 4:46 PM Dmitry Baryshkov
<[email protected]> wrote:
>
> > The way I'm arguing it should work is that:
> >
> > 1. A whole bunch of the DP init code should move to the DP driver's
> > probe function. This includes parsing the DT, acquiring clocks,
> > getting a handle to our PHY, and IO mapping registers. As far as I
> > know, there's no reason to wait on all the components being probed in
> > order to do this stuff.
>
> Yes. And that's one of the reasons I tried to stay away from the DP
> driver. Each time I open the source code, my hands itch to start
> refactoring the code.
>
> >
> > 2. Once we have done the above things, it should be possible to do AUX
> > transfers, correct? ...and then we can populate the AUX bus from the
> > probe function too.
>
> No. In the DP case the AUX bus is inaccessible until the dongle is
> plugged (see all the HPD handling, phy_init()/phy_power_on() is hidden
> somewhere in that path)

I guess my thought was that in DP you could still create the AUX bus
at probe time. Then for DP you just return an instant "transfer
failed" from the AUX bus if HPD isn't asserted. For eDP (as discussed
elsewhere) when we try to do an AUX transfer then we delay until HPD
is there.

So we can still acquire resources (clocks, PHY, io maps, etc) at probe
time for DP and create the AUX bus, right? It will just return
"-ENODEV" if HPD isn't asserted and you're DP?

-Doug

2022-04-08 17:34:48

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On Fri, 8 Apr 2022 at 03:26, Doug Anderson <[email protected]> wrote:
>
> Hi,
>
> On Thu, Apr 7, 2022 at 4:46 PM Dmitry Baryshkov
> <[email protected]> wrote:
> >
> > > The way I'm arguing it should work is that:
> > >
> > > 1. A whole bunch of the DP init code should move to the DP driver's
> > > probe function. This includes parsing the DT, acquiring clocks,
> > > getting a handle to our PHY, and IO mapping registers. As far as I
> > > know, there's no reason to wait on all the components being probed in
> > > order to do this stuff.
> >
> > Yes. And that's one of the reasons I tried to stay away from the DP
> > driver. Each time I open the source code, my hands itch to start
> > refactoring the code.
> >
> > >
> > > 2. Once we have done the above things, it should be possible to do AUX
> > > transfers, correct? ...and then we can populate the AUX bus from the
> > > probe function too.
> >
> > No. In the DP case the AUX bus is inaccessible until the dongle is
> > plugged (see all the HPD handling, phy_init()/phy_power_on() is hidden
> > somewhere in that path)
>
> I guess my thought was that in DP you could still create the AUX bus
> at probe time. Then for DP you just return an instant "transfer
> failed" from the AUX bus if HPD isn't asserted. For eDP (as discussed
> elsewhere) when we try to do an AUX transfer then we delay until HPD
> is there.

I think panel-edp would already handle the delay, so we do not need to
have this logic in the DP driver.

> So we can still acquire resources (clocks, PHY, io maps, etc) at probe
> time for DP and create the AUX bus, right? It will just return
> "-ENODEV" if HPD isn't asserted and you're DP?

Yes, please. I still suppose that we'd need a separate case to
power_on eDP's PHY during the probe time. Maybe I'm mistaken here.

--
With best wishes
Dmitry

2022-04-08 18:53:04

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Fri, Apr 8, 2022 at 5:20 AM Dmitry Baryshkov
<[email protected]> wrote:
>
> > I guess my thought was that in DP you could still create the AUX bus
> > at probe time. Then for DP you just return an instant "transfer
> > failed" from the AUX bus if HPD isn't asserted. For eDP (as discussed
> > elsewhere) when we try to do an AUX transfer then we delay until HPD
> > is there.
>
> I think panel-edp would already handle the delay, so we do not need to
> have this logic in the DP driver.

There's a whole discussion about this between Stephen and me in patch
#5 ("drm/msm/dp: wait for hpd high before any sink interaction").
Basically:

* If panel HPD is hooked up to the dedicated HPD pin on the eDP
controller then the panel driver doesn't have a way to read it.

* We can't leverage the existing "HPD" query functions in DRM because
those indicate whether a panel is _physically_ connected. For eDP, it
always is.

For now the rule is that the AUX transfer function is in charge of
waiting for HPD for eDP if the dedicated HPD pin is used. If we want
to re-invent this we could, but that system works, isn't _too_ ugly,
and we're already making big enough changes in this series.


> > So we can still acquire resources (clocks, PHY, io maps, etc) at probe
> > time for DP and create the AUX bus, right? It will just return
> > "-ENODEV" if HPD isn't asserted and you're DP?
>
> Yes, please. I still suppose that we'd need a separate case to
> power_on eDP's PHY during the probe time. Maybe I'm mistaken here.

I think the ideal way is to do it like Kieran's proposal for sn65dsi86:

https://lore.kernel.org/r/[email protected]/

* When enabling HPD (physical hot plug detect) in the hpd_enable()
callback you do a pm_runtime_get(). You do the
pm_runtime_put_autosuspend() when disabling. This is only used for DP
since we only provide DRM_BRIDGE_OP_HPD for DP, not for eDP.

* We do a pm_runtime_get() / pm_runtime_put_autosuspend() in the AUX
transfer routine. While holding the pm_runtime reference we check HPD.
For DP we return immediately if HPD isn't asserted. For eDP, we delay.

* We do the pm_runtime_get() in pre_enable and the pm_runtime_put() in
post_disable. For DP this will add a 2nd refcount (since we probably
were holding the reference for HPD). For eDP this will cause us to
power on.

* If there's any other time we need to read HW registers, and we
aren't guaranteed to already have a pm_runtime reference (like during
probe), we can do a temporary pm_runtime_get() /
pm_runtime_put_autosuspend().

2022-04-08 21:14:39

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi,

On Fri, Apr 8, 2022 at 5:13 AM Dmitry Baryshkov
<[email protected]> wrote:
>
> On Fri, 8 Apr 2022 at 03:28, Doug Anderson <[email protected]> wrote:
> >
> > Hi,
> >
> > On Thu, Apr 7, 2022 at 4:36 PM Dmitry Baryshkov
> > <[email protected]> wrote:
> > >
> > > The ps8640 driver looks 'working by coincidence'. It calls
> > > dp_aux_populate, then immediately after the function returns it checks
> > > for the panel. If panel-edp is built as a module, the probe might fail
> > > easily.
> > > The anx7625 driver has the same kind of issue. The DP AUX bus is
> > > populated from the probe() and after some additional work the panel is
> > > being checked.
> > > This design is fragile and from my quick glance it can break (or be
> > > broken) too easy. It reminds me of our drm msm 'probe' loops
> > > preventing the device to boot completely if the dsi bridge/panel could
> > > not be probed in time.
> >
> > I did spend some time thinking about this, at least for ps8640. I
> > believe that as long as the panel's probe isn't asynchronous.
>
> By panel probe (as a probe of any device) is potentially asynchronous.
> As in your example, the PWM might not be present, the regulator probe
> might have been delayed, the panel-edp might be built as a module,
> which is not present for some reason.

Well, in those cases it's not exactly asynchronous, or at least not in
the way I was thinking about. Either it will work now, or we should
try again later when more drivers have probed. The case I was worried
about was:

1. We call devm_of_dp_aux_populate_ep_devices()

2. devm_of_dp_aux_populate_ep_devices() kicks off a probe to the panel
in the background

3. devm_of_dp_aux_populate_ep_devices() returns to us without waiting
for the panel's probe to finish.

I think that's possible if the panel driver sets PROBE_PREFER_ASYNCHRONOUS.

I was less worried about the resources missing since I thought that
would be handled by the normal probe deferral case. IIRC the "infinite
loop" that we used to end up with MSM's probe was because something
about the way the MSM DRM driver worked would cause the deferral
mechanisms to retry instantly each time we deferred. I don't remember
exactly what triggered it, but I don't _think_ that's true for ps8640?


> > Basically if the panel isn't ready then ps8640 should return and we'll
> > retry later. I do remember the probe loops that we used to have with
> > msm and I don't _think_ this would trigger it.
>
> I don't have proof here. But as I wrote, this thing might break at some point.
>
> > That being said, if we need to separate out the AUX bus into a
> > sub-device like we did in sn65dsi86 we certainly could.
>
> Ideally we should separate the "bridge" subdevice, like it was done in
> sn65dsi86.
> So that the aux host probes, registers the EP device, then the bridge
> device can not be probed (and thus the drm_bridge is not created)
> until the next bridge becomes available.

You're definitely right, that's best. I was hesitant to force the
issue during review of the ps8640 because it adds a bunch of
complexity and didn't _seem_ to be needed. Maybe it makes sense to
just code it up, though...

-Doug

2022-04-09 07:39:27

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On Fri, 8 Apr 2022 at 03:28, Doug Anderson <[email protected]> wrote:
>
> Hi,
>
> On Thu, Apr 7, 2022 at 4:36 PM Dmitry Baryshkov
> <[email protected]> wrote:
> >
> > The ps8640 driver looks 'working by coincidence'. It calls
> > dp_aux_populate, then immediately after the function returns it checks
> > for the panel. If panel-edp is built as a module, the probe might fail
> > easily.
> > The anx7625 driver has the same kind of issue. The DP AUX bus is
> > populated from the probe() and after some additional work the panel is
> > being checked.
> > This design is fragile and from my quick glance it can break (or be
> > broken) too easy. It reminds me of our drm msm 'probe' loops
> > preventing the device to boot completely if the dsi bridge/panel could
> > not be probed in time.
>
> I did spend some time thinking about this, at least for ps8640. I
> believe that as long as the panel's probe isn't asynchronous.

By panel probe (as a probe of any device) is potentially asynchronous.
As in your example, the PWM might not be present, the regulator probe
might have been delayed, the panel-edp might be built as a module,
which is not present for some reason.

> Basically if the panel isn't ready then ps8640 should return and we'll
> retry later. I do remember the probe loops that we used to have with
> msm and I don't _think_ this would trigger it.

I don't have proof here. But as I wrote, this thing might break at some point.

> That being said, if we need to separate out the AUX bus into a
> sub-device like we did in sn65dsi86 we certainly could.

Ideally we should separate the "bridge" subdevice, like it was done in
sn65dsi86.
So that the aux host probes, registers the EP device, then the bridge
device can not be probed (and thus the drm_bridge is not created)
until the next bridge becomes available.

--
With best wishes
Dmitry

2022-04-11 13:32:40

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On Fri, 8 Apr 2022 at 16:56, Doug Anderson <[email protected]> wrote:
>
> Hi,
>
> On Fri, Apr 8, 2022 at 5:13 AM Dmitry Baryshkov
> <[email protected]> wrote:
> >
> > On Fri, 8 Apr 2022 at 03:28, Doug Anderson <[email protected]> wrote:
> > >
> > > Hi,
> > >
> > > On Thu, Apr 7, 2022 at 4:36 PM Dmitry Baryshkov
> > > <[email protected]> wrote:
> > > >
> > > > The ps8640 driver looks 'working by coincidence'. It calls
> > > > dp_aux_populate, then immediately after the function returns it checks
> > > > for the panel. If panel-edp is built as a module, the probe might fail
> > > > easily.
> > > > The anx7625 driver has the same kind of issue. The DP AUX bus is
> > > > populated from the probe() and after some additional work the panel is
> > > > being checked.
> > > > This design is fragile and from my quick glance it can break (or be
> > > > broken) too easy. It reminds me of our drm msm 'probe' loops
> > > > preventing the device to boot completely if the dsi bridge/panel could
> > > > not be probed in time.
> > >
> > > I did spend some time thinking about this, at least for ps8640. I
> > > believe that as long as the panel's probe isn't asynchronous.
> >
> > By panel probe (as a probe of any device) is potentially asynchronous.
> > As in your example, the PWM might not be present, the regulator probe
> > might have been delayed, the panel-edp might be built as a module,
> > which is not present for some reason.
>
> Well, in those cases it's not exactly asynchronous, or at least not in
> the way I was thinking about. Either it will work now, or we should
> try again later when more drivers have probed. The case I was worried
> about was:
>
> 1. We call devm_of_dp_aux_populate_ep_devices()
>
> 2. devm_of_dp_aux_populate_ep_devices() kicks off a probe to the panel
> in the background
>
> 3. devm_of_dp_aux_populate_ep_devices() returns to us without waiting
> for the panel's probe to finish.
>
> I think that's possible if the panel driver sets PROBE_PREFER_ASYNCHRONOUS.

That would be a separate story, yes. However the general case is still
valid: one can not guarantee that the panel device is available
immediately after aux bus population.
So ps8640 works at this moment and in the particular configuration.

>
> I was less worried about the resources missing since I thought that
> would be handled by the normal probe deferral case. IIRC the "infinite
> loop" that we used to end up with MSM's probe was because something
> about the way the MSM DRM driver worked would cause the deferral
> mechanisms to retry instantly each time we deferred. I don't remember
> exactly what triggered it, but I don't _think_ that's true for ps8640?

I'm not sure either. If you have a system with that bridge, it can be
easily tried by returning -EPROBE_DEFER from the panel driver's
probe().

For the msm driver it was the following sequence of events:
- mdss probes
- mdss creates subdevices including dsi host
- subdevices are probed
- mdss drivers tries to perform component binding
- dsi host determines that the next item is not available
- it returns -EPROBE_DEFER to the component bind
- mdss reverts registration of subdevices, returning probe defer.

However as there were devices added to the device list, the deferral
list was retried immediately. Thus we faced the probe loop.

I think this looks close to the ps8640, but I wouldn't bet on that.

> > > Basically if the panel isn't ready then ps8640 should return and we'll
> > > retry later. I do remember the probe loops that we used to have with
> > > msm and I don't _think_ this would trigger it.
> >
> > I don't have proof here. But as I wrote, this thing might break at some point.
> >
> > > That being said, if we need to separate out the AUX bus into a
> > > sub-device like we did in sn65dsi86 we certainly could.
> >
> > Ideally we should separate the "bridge" subdevice, like it was done in
> > sn65dsi86.
> > So that the aux host probes, registers the EP device, then the bridge
> > device can not be probed (and thus the drm_bridge is not created)
> > until the next bridge becomes available.
>
> You're definitely right, that's best. I was hesitant to force the
> issue during review of the ps8640 because it adds a bunch of
> complexity and didn't _seem_ to be needed. Maybe it makes sense to
> just code it up, though...

As I wrote, the test is easy. If the system boots fine, there is no
need to fix that immediately.
However I think in general we should stop depending on the panel being
available right after populating the aux bus.

--
With best wishes
Dmitry

2022-04-12 08:40:55

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

Hi Doug and Dmitry

On 4/8/2022 7:58 AM, Dmitry Baryshkov wrote:
> On Fri, 8 Apr 2022 at 16:43, Doug Anderson <[email protected]> wrote:
>>
>> Hi,
>>
>> On Fri, Apr 8, 2022 at 5:20 AM Dmitry Baryshkov
>> <[email protected]> wrote:
>>>
>>>> I guess my thought was that in DP you could still create the AUX bus
>>>> at probe time. Then for DP you just return an instant "transfer
>>>> failed" from the AUX bus if HPD isn't asserted. For eDP (as discussed
>>>> elsewhere) when we try to do an AUX transfer then we delay until HPD
>>>> is there.
>>>
>>> I think panel-edp would already handle the delay, so we do not need to
>>> have this logic in the DP driver.
>>
>> There's a whole discussion about this between Stephen and me in patch
>> #5 ("drm/msm/dp: wait for hpd high before any sink interaction").
>> Basically:
>>
>> * If panel HPD is hooked up to the dedicated HPD pin on the eDP
>> controller then the panel driver doesn't have a way to read it.
>
> I refreshed that dialog. I must admit, I have missed the fact that the
> HPD pin might not be visible as the GPIO pin.
>
>> * We can't leverage the existing "HPD" query functions in DRM because
>> those indicate whether a panel is _physically_ connected. For eDP, it
>> always is.
>
> Yes, I was thinking about (mis)using the
> drm_bridge_connector_hpd_notify() for generic HPD-related
> notifications (to tell eDP that it should check the current state). I
> have abandoned that idea.
>
>> For now the rule is that the AUX transfer function is in charge of
>> waiting for HPD for eDP if the dedicated HPD pin is used. If we want
>> to re-invent this we could, but that system works, isn't _too_ ugly,
>> and we're already making big enough changes in this series.
>
> The is_hpd_asserted() looks like a good callback for the aux bus.
> It will allow the panel driver to check if the panel is powered up (in
> the absence of the GPIO pin).
>
>>>> So we can still acquire resources (clocks, PHY, io maps, etc) at probe
>>>> time for DP and create the AUX bus, right? It will just return
>>>> "-ENODEV" if HPD isn't asserted and you're DP?
>>>
>>> Yes, please. I still suppose that we'd need a separate case to
>>> power_on eDP's PHY during the probe time. Maybe I'm mistaken here.
>>
>> I think the ideal way is to do it like Kieran's proposal for sn65dsi86:
>>
>> https://lore.kernel.org/r/[email protected]/
>>
>> * When enabling HPD (physical hot plug detect) in the hpd_enable()
>> callback you do a pm_runtime_get(). You do the
>> pm_runtime_put_autosuspend() when disabling. This is only used for DP
>> since we only provide DRM_BRIDGE_OP_HPD for DP, not for eDP.
>>
>> * We do a pm_runtime_get() / pm_runtime_put_autosuspend() in the AUX
>> transfer routine. While holding the pm_runtime reference we check HPD.
>> For DP we return immediately if HPD isn't asserted. For eDP, we delay.
>>
>> * We do the pm_runtime_get() in pre_enable and the pm_runtime_put() in
>> post_disable. For DP this will add a 2nd refcount (since we probably
>> were holding the reference for HPD). For eDP this will cause us to
>> power on.
>>
>> * If there's any other time we need to read HW registers, and we
>> aren't guaranteed to already have a pm_runtime reference (like during
>> probe), we can do a temporary pm_runtime_get() /
>> pm_runtime_put_autosuspend().
>
> This looks good. I'd be more than welcome to review such series.
>
> Note: I think this would require using
> drm_bridge_connector_enable_hpd() in the DP code.
> Hopefully at some point we would be able to move all
> drm_bridge_connector calls to the core msm layer.
> --
> With best wishes
> Dmitry


Thanks for the proposals.

In general I would break up this task as follows:

1) Re-factoring dp/edp parsing code to move it to probe ( its currently
done in bind ). So not sure what dependencies we will uncover there.
Nonetheless, lets assume for now it can be done.

2) Then bind all the power resources needed for AUX in pm_runtime_ops

3) Handle EPROBE_DEFER cases of the panel-eDP aux device

4) Probably the biggest from our point of view --- makes sure none of
this breaks DP/eDP

Since QC will be taking ownership of all of this, I would still suggest
land this series first so that basic display functionality on sc7280
chromebooks works, unblocks more developers and this program and we can
internally evaluate all of this and post the changes as-and-when ready
for review.

So, I suggest/request acking this current one after
fixing the other comments (unrelated to this re-factor) which have been
given so far ofcourse, as we all agree this is not breaking and seems
pretty reasonable short term.

Doug, you can track this re-factor with a different bug so that all this
discussion remains intact.

Thanks

Abhinav


2022-04-12 16:32:24

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/8] drm/msm/dp: Add eDP support via aux_bus

On Fri, 8 Apr 2022 at 16:43, Doug Anderson <[email protected]> wrote:
>
> Hi,
>
> On Fri, Apr 8, 2022 at 5:20 AM Dmitry Baryshkov
> <[email protected]> wrote:
> >
> > > I guess my thought was that in DP you could still create the AUX bus
> > > at probe time. Then for DP you just return an instant "transfer
> > > failed" from the AUX bus if HPD isn't asserted. For eDP (as discussed
> > > elsewhere) when we try to do an AUX transfer then we delay until HPD
> > > is there.
> >
> > I think panel-edp would already handle the delay, so we do not need to
> > have this logic in the DP driver.
>
> There's a whole discussion about this between Stephen and me in patch
> #5 ("drm/msm/dp: wait for hpd high before any sink interaction").
> Basically:
>
> * If panel HPD is hooked up to the dedicated HPD pin on the eDP
> controller then the panel driver doesn't have a way to read it.

I refreshed that dialog. I must admit, I have missed the fact that the
HPD pin might not be visible as the GPIO pin.

> * We can't leverage the existing "HPD" query functions in DRM because
> those indicate whether a panel is _physically_ connected. For eDP, it
> always is.

Yes, I was thinking about (mis)using the
drm_bridge_connector_hpd_notify() for generic HPD-related
notifications (to tell eDP that it should check the current state). I
have abandoned that idea.

> For now the rule is that the AUX transfer function is in charge of
> waiting for HPD for eDP if the dedicated HPD pin is used. If we want
> to re-invent this we could, but that system works, isn't _too_ ugly,
> and we're already making big enough changes in this series.

The is_hpd_asserted() looks like a good callback for the aux bus.
It will allow the panel driver to check if the panel is powered up (in
the absence of the GPIO pin).

> > > So we can still acquire resources (clocks, PHY, io maps, etc) at probe
> > > time for DP and create the AUX bus, right? It will just return
> > > "-ENODEV" if HPD isn't asserted and you're DP?
> >
> > Yes, please. I still suppose that we'd need a separate case to
> > power_on eDP's PHY during the probe time. Maybe I'm mistaken here.
>
> I think the ideal way is to do it like Kieran's proposal for sn65dsi86:
>
> https://lore.kernel.org/r/[email protected]/
>
> * When enabling HPD (physical hot plug detect) in the hpd_enable()
> callback you do a pm_runtime_get(). You do the
> pm_runtime_put_autosuspend() when disabling. This is only used for DP
> since we only provide DRM_BRIDGE_OP_HPD for DP, not for eDP.
>
> * We do a pm_runtime_get() / pm_runtime_put_autosuspend() in the AUX
> transfer routine. While holding the pm_runtime reference we check HPD.
> For DP we return immediately if HPD isn't asserted. For eDP, we delay.
>
> * We do the pm_runtime_get() in pre_enable and the pm_runtime_put() in
> post_disable. For DP this will add a 2nd refcount (since we probably
> were holding the reference for HPD). For eDP this will cause us to
> power on.
>
> * If there's any other time we need to read HW registers, and we
> aren't guaranteed to already have a pm_runtime reference (like during
> probe), we can do a temporary pm_runtime_get() /
> pm_runtime_put_autosuspend().

This looks good. I'd be more than welcome to review such series.

Note: I think this would require using
drm_bridge_connector_enable_hpd() in the DP code.
Hopefully at some point we would be able to move all
drm_bridge_connector calls to the core msm layer.
--
With best wishes
Dmitry