2024-03-22 13:23:08

by Abel Vesa

[permalink] [raw]
Subject: [PATCH v3 0/2] drm/msm/dp: Rework the eDP/DP modes and add support for X1E80100

Since this new platform supports both DP and eDP, it's the perfect time
to drop the dual compatible (eDP and DP) and figure out a different way
to specify the mode. After some off-list discussion, one suggested way
was to add a 'is-edp' property to the controller node, but that approach
has been dropped due to bindings concerns. So now we lookup the panel
node in DT and based on it's presence we can safely say if it is eDP or not.

The PHY counterpart patchset is here:
https://lore.kernel.org/all/20240220-x1e80100-phy-edp-compatible-refactor-v5-0-e8658adf5461@linaro.org/

Signed-off-by: Abel Vesa <[email protected]>
---
Changes in v3:
- Dropped the bindings patch as this new solution doesn't involve
bindings update.
- Dropped R-b tags as this has been entirely reworked
- Reworked to lookup the panel node in DT and set the is_edp and
connector type based on panel node presence
- Link to v2: https://lore.kernel.org/r/20240222-x1e80100-display-refactor-connector-v2-0-bd4197dfceab@linaro.org

Changes in v2:
- Added Dmitry's R-b tag to both driver patches
- Dropped the if statement around assigning the is_edp in
dp_display_probe, and fixed said assignment by using the connector
type from match data instead.
- Moved the qcom,x1e80100-dp compatible where it belongs
- Re-worded the bindings commit message to follow Bjorn's suggestion
- Dropped the RFC tag as the approach doesn't seem to be questioned
anymore
- Link to v1: https://lore.kernel.org/r/20240221-x1e80100-display-refactor-connector-v1-0-86c0e1ebd5ec@linaro.org

---
Abel Vesa (2):
drm/msm/dp: Add support for determining the eDP/DP mode from DT
drm/msm/dp: Add support for the X1E80100

drivers/gpu/drm/msm/dp/dp_display.c | 52 ++++++++++++++++++++++++++++++++++---
1 file changed, 48 insertions(+), 4 deletions(-)
---
base-commit: e7528c088874326d3060a46f572252be43755a86
change-id: 20231219-x1e80100-display-refactor-connector-e1c66548cae3

Best regards,
--
Abel Vesa <[email protected]>



2024-03-22 13:23:33

by Abel Vesa

[permalink] [raw]
Subject: [PATCH v3 2/2] drm/msm/dp: Add support for the X1E80100

Add the X1E80100 DP descs and compatible. This platform will be using
a single compatible for both eDP and DP mode. The actual mode will
be set based on the presence of the panel node in DT.

Signed-off-by: Abel Vesa <[email protected]>
---
drivers/gpu/drm/msm/dp/dp_display.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index c9763f77c832..95f6cf949fe6 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -171,6 +171,14 @@ static const struct msm_dp_desc sm8650_dp_descs[] = {
{}
};

+static const struct msm_dp_desc x1e80100_dp_descs[] = {
+ { .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+ { .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+ { .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+ { .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
+ {}
+};
+
static const struct of_device_id dp_dt_match[] = {
{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
@@ -182,6 +190,7 @@ static const struct of_device_id dp_dt_match[] = {
{ .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs },
{ .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs },
{ .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs },
+ { .compatible = "qcom,x1e80100-dp", .data = &x1e80100_dp_descs },
{}
};


--
2.34.1


2024-03-22 13:25:31

by Abel Vesa

[permalink] [raw]
Subject: [PATCH v3 1/2] drm/msm/dp: Add support for determining the eDP/DP mode from DT

Instead of relying on different compatibles for eDP and DP, lookup
the panel node in devicetree to figure out the connector type and
then pass on that information to the PHY. External DP is not described
in DT, therefore, assume it's eDP if panel node is present.

Signed-off-by: Abel Vesa <[email protected]>
---
drivers/gpu/drm/msm/dp/dp_display.c | 43 +++++++++++++++++++++++++++++++++----
1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index c4cb82af5c2f..c9763f77c832 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -726,6 +726,14 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
if (IS_ERR(phy))
return PTR_ERR(phy);

+ rc = phy_set_mode_ext(phy, PHY_MODE_DP,
+ dp->dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);
+ if (rc) {
+ DRM_ERROR("failed to set phy submode, rc = %d\n", rc);
+ dp->catalog = NULL;
+ goto error;
+ }
+
dp->catalog = dp_catalog_get(dev);
if (IS_ERR(dp->catalog)) {
rc = PTR_ERR(dp->catalog);
@@ -734,9 +742,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
goto error;
}

- dp->aux = dp_aux_get(dev, dp->catalog,
- phy,
- dp->dp_display.is_edp);
+ dp->aux = dp_aux_get(dev, dp->catalog, phy, dp->dp_display.is_edp);
if (IS_ERR(dp->aux)) {
rc = PTR_ERR(dp->aux);
DRM_ERROR("failed to initialize aux, rc = %d\n", rc);
@@ -1241,6 +1247,35 @@ static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
return dp_display_probe_tail(aux->dev);
}

+static int dp_display_get_connector_type(struct platform_device *pdev,
+ const struct msm_dp_desc *desc)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *aux_bus;
+ struct device_node *panel;
+ int ret = DRM_MODE_CONNECTOR_DisplayPort;
+
+ /* legacy platforms specify connector type in match data */
+ if (desc->connector_type == DRM_MODE_CONNECTOR_eDP ||
+ desc->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+ return desc->connector_type;
+
+ aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
+ if (!aux_bus)
+ goto out;
+
+ panel = of_get_child_by_name(aux_bus, "panel");
+ if (!panel)
+ goto out;
+
+ ret = DRM_MODE_CONNECTOR_eDP;
+
+out:
+ of_node_put(panel);
+ of_node_put(aux_bus);
+ return ret;
+}
+
static int dp_display_probe(struct platform_device *pdev)
{
int rc = 0;
@@ -1263,7 +1298,7 @@ static int dp_display_probe(struct platform_device *pdev)
dp->dp_display.pdev = pdev;
dp->name = "drm_dp";
dp->id = desc->id;
- dp->dp_display.connector_type = desc->connector_type;
+ dp->dp_display.connector_type = dp_display_get_connector_type(pdev, desc);
dp->wide_bus_supported = desc->wide_bus_supported;
dp->dp_display.is_edp =
(dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);

--
2.34.1


2024-03-22 13:43:51

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] drm/msm/dp: Add support for determining the eDP/DP mode from DT

On Fri, 22 Mar 2024 at 15:22, Abel Vesa <[email protected]> wrote:
>
> Instead of relying on different compatibles for eDP and DP, lookup
> the panel node in devicetree to figure out the connector type and
> then pass on that information to the PHY. External DP is not described

Nit: External DP doesn't have a panel described in DT...

> in DT, therefore, assume it's eDP if panel node is present.
>
> Signed-off-by: Abel Vesa <[email protected]>
> ---
> drivers/gpu/drm/msm/dp/dp_display.c | 43 +++++++++++++++++++++++++++++++++----
> 1 file changed, 39 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index c4cb82af5c2f..c9763f77c832 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -726,6 +726,14 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> if (IS_ERR(phy))
> return PTR_ERR(phy);
>
> + rc = phy_set_mode_ext(phy, PHY_MODE_DP,
> + dp->dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);
> + if (rc) {
> + DRM_ERROR("failed to set phy submode, rc = %d\n", rc);
> + dp->catalog = NULL;
> + goto error;
> + }
> +
> dp->catalog = dp_catalog_get(dev);
> if (IS_ERR(dp->catalog)) {
> rc = PTR_ERR(dp->catalog);
> @@ -734,9 +742,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> goto error;
> }
>
> - dp->aux = dp_aux_get(dev, dp->catalog,
> - phy,
> - dp->dp_display.is_edp);
> + dp->aux = dp_aux_get(dev, dp->catalog, phy, dp->dp_display.is_edp);

Unrelated

> if (IS_ERR(dp->aux)) {
> rc = PTR_ERR(dp->aux);
> DRM_ERROR("failed to initialize aux, rc = %d\n", rc);
> @@ -1241,6 +1247,35 @@ static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
> return dp_display_probe_tail(aux->dev);
> }
>
> +static int dp_display_get_connector_type(struct platform_device *pdev,
> + const struct msm_dp_desc *desc)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *aux_bus;
> + struct device_node *panel;
> + int ret = DRM_MODE_CONNECTOR_DisplayPort;
> +
> + /* legacy platforms specify connector type in match data */
> + if (desc->connector_type == DRM_MODE_CONNECTOR_eDP ||
> + desc->connector_type == DRM_MODE_CONNECTOR_DisplayPort)

misaligned

> + return desc->connector_type;

Can we drop this part completely?

> +
> + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
> + if (!aux_bus)
> + goto out;
> +
> + panel = of_get_child_by_name(aux_bus, "panel");
> + if (!panel)
> + goto out;
> +
> + ret = DRM_MODE_CONNECTOR_eDP;
> +
> +out:
> + of_node_put(panel);
> + of_node_put(aux_bus);
> + return ret;
> +}
> +
> static int dp_display_probe(struct platform_device *pdev)
> {
> int rc = 0;
> @@ -1263,7 +1298,7 @@ static int dp_display_probe(struct platform_device *pdev)
> dp->dp_display.pdev = pdev;
> dp->name = "drm_dp";
> dp->id = desc->id;
> - dp->dp_display.connector_type = desc->connector_type;
> + dp->dp_display.connector_type = dp_display_get_connector_type(pdev, desc);
> dp->wide_bus_supported = desc->wide_bus_supported;
> dp->dp_display.is_edp =
> (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
>
> --
> 2.34.1
>


--
With best wishes
Dmitry

2024-03-22 13:44:02

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] drm/msm/dp: Add support for the X1E80100

On Fri, 22 Mar 2024 at 15:22, Abel Vesa <[email protected]> wrote:
>
> Add the X1E80100 DP descs and compatible. This platform will be using
> a single compatible for both eDP and DP mode. The actual mode will
> be set based on the presence of the panel node in DT.
>
> Signed-off-by: Abel Vesa <[email protected]>

Reviewed-by: Dmitry Baryshkov <[email protected]>

> ---
> drivers/gpu/drm/msm/dp/dp_display.c | 9 +++++++++
> 1 file changed, 9 insertions(+)

-
With best wishes
Dmitry

2024-03-22 13:45:42

by Abel Vesa

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] drm/msm/dp: Add support for determining the eDP/DP mode from DT

On 24-03-22 15:30:54, Dmitry Baryshkov wrote:
> On Fri, 22 Mar 2024 at 15:22, Abel Vesa <[email protected]> wrote:
> >
> > Instead of relying on different compatibles for eDP and DP, lookup
> > the panel node in devicetree to figure out the connector type and
> > then pass on that information to the PHY. External DP is not described
>
> Nit: External DP doesn't have a panel described in DT...
>

Will fix.

> > in DT, therefore, assume it's eDP if panel node is present.
> >
> > Signed-off-by: Abel Vesa <[email protected]>
> > ---
> > drivers/gpu/drm/msm/dp/dp_display.c | 43 +++++++++++++++++++++++++++++++++----
> > 1 file changed, 39 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> > index c4cb82af5c2f..c9763f77c832 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > @@ -726,6 +726,14 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> > if (IS_ERR(phy))
> > return PTR_ERR(phy);
> >
> > + rc = phy_set_mode_ext(phy, PHY_MODE_DP,
> > + dp->dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);
> > + if (rc) {
> > + DRM_ERROR("failed to set phy submode, rc = %d\n", rc);
> > + dp->catalog = NULL;
> > + goto error;
> > + }
> > +
> > dp->catalog = dp_catalog_get(dev);
> > if (IS_ERR(dp->catalog)) {
> > rc = PTR_ERR(dp->catalog);
> > @@ -734,9 +742,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> > goto error;
> > }
> >
> > - dp->aux = dp_aux_get(dev, dp->catalog,
> > - phy,
> > - dp->dp_display.is_edp);
> > + dp->aux = dp_aux_get(dev, dp->catalog, phy, dp->dp_display.is_edp);
>
> Unrelated
>

Yep, will drop the change.

> > if (IS_ERR(dp->aux)) {
> > rc = PTR_ERR(dp->aux);
> > DRM_ERROR("failed to initialize aux, rc = %d\n", rc);
> > @@ -1241,6 +1247,35 @@ static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
> > return dp_display_probe_tail(aux->dev);
> > }
> >
> > +static int dp_display_get_connector_type(struct platform_device *pdev,
> > + const struct msm_dp_desc *desc)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct device_node *aux_bus;
> > + struct device_node *panel;
> > + int ret = DRM_MODE_CONNECTOR_DisplayPort;
> > +
> > + /* legacy platforms specify connector type in match data */
> > + if (desc->connector_type == DRM_MODE_CONNECTOR_eDP ||
> > + desc->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
>
> misaligned
>

Sure, will fix.

> > + return desc->connector_type;
>
> Can we drop this part completely?
>

You mean the whole if clause? How should we handle the legacy approach
then?

> > +
> > + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
> > + if (!aux_bus)
> > + goto out;
> > +
> > + panel = of_get_child_by_name(aux_bus, "panel");
> > + if (!panel)
> > + goto out;
> > +
> > + ret = DRM_MODE_CONNECTOR_eDP;
> > +
> > +out:
> > + of_node_put(panel);
> > + of_node_put(aux_bus);
> > + return ret;
> > +}
> > +
> > static int dp_display_probe(struct platform_device *pdev)
> > {
> > int rc = 0;
> > @@ -1263,7 +1298,7 @@ static int dp_display_probe(struct platform_device *pdev)
> > dp->dp_display.pdev = pdev;
> > dp->name = "drm_dp";
> > dp->id = desc->id;
> > - dp->dp_display.connector_type = desc->connector_type;
> > + dp->dp_display.connector_type = dp_display_get_connector_type(pdev, desc);
> > dp->wide_bus_supported = desc->wide_bus_supported;
> > dp->dp_display.is_edp =
> > (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
> >
> > --
> > 2.34.1
> >
>
>
> --
> With best wishes
> Dmitry

2024-03-22 13:57:59

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] drm/msm/dp: Add support for determining the eDP/DP mode from DT

On Fri, 22 Mar 2024 at 15:36, Abel Vesa <[email protected]> wrote:
>
> On 24-03-22 15:30:54, Dmitry Baryshkov wrote:
> > On Fri, 22 Mar 2024 at 15:22, Abel Vesa <[email protected]> wrote:
> > >
> > > Instead of relying on different compatibles for eDP and DP, lookup
> > > the panel node in devicetree to figure out the connector type and
> > > then pass on that information to the PHY. External DP is not described
> >
> > Nit: External DP doesn't have a panel described in DT...
> >
>
> Will fix.
>
> > > in DT, therefore, assume it's eDP if panel node is present.
> > >
> > > Signed-off-by: Abel Vesa <[email protected]>
> > > ---
> > > drivers/gpu/drm/msm/dp/dp_display.c | 43 +++++++++++++++++++++++++++++++++----
> > > 1 file changed, 39 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> > > index c4cb82af5c2f..c9763f77c832 100644
> > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > @@ -726,6 +726,14 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> > > if (IS_ERR(phy))
> > > return PTR_ERR(phy);
> > >
> > > + rc = phy_set_mode_ext(phy, PHY_MODE_DP,
> > > + dp->dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);
> > > + if (rc) {
> > > + DRM_ERROR("failed to set phy submode, rc = %d\n", rc);
> > > + dp->catalog = NULL;
> > > + goto error;
> > > + }
> > > +
> > > dp->catalog = dp_catalog_get(dev);
> > > if (IS_ERR(dp->catalog)) {
> > > rc = PTR_ERR(dp->catalog);
> > > @@ -734,9 +742,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> > > goto error;
> > > }
> > >
> > > - dp->aux = dp_aux_get(dev, dp->catalog,
> > > - phy,
> > > - dp->dp_display.is_edp);
> > > + dp->aux = dp_aux_get(dev, dp->catalog, phy, dp->dp_display.is_edp);
> >
> > Unrelated
> >
>
> Yep, will drop the change.
>
> > > if (IS_ERR(dp->aux)) {
> > > rc = PTR_ERR(dp->aux);
> > > DRM_ERROR("failed to initialize aux, rc = %d\n", rc);
> > > @@ -1241,6 +1247,35 @@ static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
> > > return dp_display_probe_tail(aux->dev);
> > > }
> > >
> > > +static int dp_display_get_connector_type(struct platform_device *pdev,
> > > + const struct msm_dp_desc *desc)
> > > +{
> > > + struct device *dev = &pdev->dev;
> > > + struct device_node *aux_bus;
> > > + struct device_node *panel;
> > > + int ret = DRM_MODE_CONNECTOR_DisplayPort;
> > > +
> > > + /* legacy platforms specify connector type in match data */
> > > + if (desc->connector_type == DRM_MODE_CONNECTOR_eDP ||
> > > + desc->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
> >
> > misaligned
> >
>
> Sure, will fix.
>
> > > + return desc->connector_type;
> >
> > Can we drop this part completely?
> >
>
> You mean the whole if clause? How should we handle the legacy approach
> then?

Legacy platforms still have the aux-bus/panel. so they should be
handled by the check below.

>
> > > +
> > > + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
> > > + if (!aux_bus)
> > > + goto out;
> > > +
> > > + panel = of_get_child_by_name(aux_bus, "panel");
> > > + if (!panel)
> > > + goto out;
> > > +
> > > + ret = DRM_MODE_CONNECTOR_eDP;
> > > +
> > > +out:
> > > + of_node_put(panel);
> > > + of_node_put(aux_bus);
> > > + return ret;
> > > +}
> > > +
> > > static int dp_display_probe(struct platform_device *pdev)
> > > {
> > > int rc = 0;
> > > @@ -1263,7 +1298,7 @@ static int dp_display_probe(struct platform_device *pdev)
> > > dp->dp_display.pdev = pdev;
> > > dp->name = "drm_dp";
> > > dp->id = desc->id;
> > > - dp->dp_display.connector_type = desc->connector_type;
> > > + dp->dp_display.connector_type = dp_display_get_connector_type(pdev, desc);
> > > dp->wide_bus_supported = desc->wide_bus_supported;
> > > dp->dp_display.is_edp =
> > > (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
> > >
> > > --
> > > 2.34.1
> > >
> >
> >
> > --
> > With best wishes
> > Dmitry



--
With best wishes
Dmitry

2024-03-22 14:15:39

by Abel Vesa

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] drm/msm/dp: Add support for determining the eDP/DP mode from DT

On 24-03-22 15:38:03, Dmitry Baryshkov wrote:
> On Fri, 22 Mar 2024 at 15:36, Abel Vesa <[email protected]> wrote:
> >
> > On 24-03-22 15:30:54, Dmitry Baryshkov wrote:
> > > On Fri, 22 Mar 2024 at 15:22, Abel Vesa <[email protected]> wrote:
> > > >
> > > > Instead of relying on different compatibles for eDP and DP, lookup
> > > > the panel node in devicetree to figure out the connector type and
> > > > then pass on that information to the PHY. External DP is not described
> > >
> > > Nit: External DP doesn't have a panel described in DT...
> > >
> >
> > Will fix.
> >
> > > > in DT, therefore, assume it's eDP if panel node is present.
> > > >
> > > > Signed-off-by: Abel Vesa <[email protected]>
> > > > ---
> > > > drivers/gpu/drm/msm/dp/dp_display.c | 43 +++++++++++++++++++++++++++++++++----
> > > > 1 file changed, 39 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > index c4cb82af5c2f..c9763f77c832 100644
> > > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > @@ -726,6 +726,14 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> > > > if (IS_ERR(phy))
> > > > return PTR_ERR(phy);
> > > >
> > > > + rc = phy_set_mode_ext(phy, PHY_MODE_DP,
> > > > + dp->dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);
> > > > + if (rc) {
> > > > + DRM_ERROR("failed to set phy submode, rc = %d\n", rc);
> > > > + dp->catalog = NULL;
> > > > + goto error;
> > > > + }
> > > > +
> > > > dp->catalog = dp_catalog_get(dev);
> > > > if (IS_ERR(dp->catalog)) {
> > > > rc = PTR_ERR(dp->catalog);
> > > > @@ -734,9 +742,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> > > > goto error;
> > > > }
> > > >
> > > > - dp->aux = dp_aux_get(dev, dp->catalog,
> > > > - phy,
> > > > - dp->dp_display.is_edp);
> > > > + dp->aux = dp_aux_get(dev, dp->catalog, phy, dp->dp_display.is_edp);
> > >
> > > Unrelated
> > >
> >
> > Yep, will drop the change.
> >
> > > > if (IS_ERR(dp->aux)) {
> > > > rc = PTR_ERR(dp->aux);
> > > > DRM_ERROR("failed to initialize aux, rc = %d\n", rc);
> > > > @@ -1241,6 +1247,35 @@ static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
> > > > return dp_display_probe_tail(aux->dev);
> > > > }
> > > >
> > > > +static int dp_display_get_connector_type(struct platform_device *pdev,
> > > > + const struct msm_dp_desc *desc)
> > > > +{
> > > > + struct device *dev = &pdev->dev;
> > > > + struct device_node *aux_bus;
> > > > + struct device_node *panel;
> > > > + int ret = DRM_MODE_CONNECTOR_DisplayPort;
> > > > +
> > > > + /* legacy platforms specify connector type in match data */
> > > > + if (desc->connector_type == DRM_MODE_CONNECTOR_eDP ||
> > > > + desc->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
> > >
> > > misaligned
> > >
> >
> > Sure, will fix.
> >
> > > > + return desc->connector_type;
> > >
> > > Can we drop this part completely?
> > >
> >
> > You mean the whole if clause? How should we handle the legacy approach
> > then?
>
> Legacy platforms still have the aux-bus/panel. so they should be
> handled by the check below.
>

Oh, in that case we can drop the connector_type from every desc for all
platforms.

> >
> > > > +
> > > > + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
> > > > + if (!aux_bus)
> > > > + goto out;
> > > > +
> > > > + panel = of_get_child_by_name(aux_bus, "panel");
> > > > + if (!panel)
> > > > + goto out;
> > > > +
> > > > + ret = DRM_MODE_CONNECTOR_eDP;
> > > > +
> > > > +out:
> > > > + of_node_put(panel);
> > > > + of_node_put(aux_bus);
> > > > + return ret;
> > > > +}
> > > > +
> > > > static int dp_display_probe(struct platform_device *pdev)
> > > > {
> > > > int rc = 0;
> > > > @@ -1263,7 +1298,7 @@ static int dp_display_probe(struct platform_device *pdev)
> > > > dp->dp_display.pdev = pdev;
> > > > dp->name = "drm_dp";
> > > > dp->id = desc->id;
> > > > - dp->dp_display.connector_type = desc->connector_type;
> > > > + dp->dp_display.connector_type = dp_display_get_connector_type(pdev, desc);
> > > > dp->wide_bus_supported = desc->wide_bus_supported;
> > > > dp->dp_display.is_edp =
> > > > (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
> > > >
> > > > --
> > > > 2.34.1
> > > >
> > >
> > >
> > > --
> > > With best wishes
> > > Dmitry
>
>
>
> --
> With best wishes
> Dmitry

2024-03-22 14:25:27

by Johan Hovold

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] drm/msm/dp: Add support for determining the eDP/DP mode from DT

On Fri, Mar 22, 2024 at 04:15:23PM +0200, Abel Vesa wrote:
> On 24-03-22 15:38:03, Dmitry Baryshkov wrote:
> > On Fri, 22 Mar 2024 at 15:36, Abel Vesa <[email protected]> wrote:
> > > On 24-03-22 15:30:54, Dmitry Baryshkov wrote:
> > > > On Fri, 22 Mar 2024 at 15:22, Abel Vesa <[email protected]> wrote:

> > > > > +static int dp_display_get_connector_type(struct platform_device *pdev,
> > > > > + const struct msm_dp_desc *desc)
> > > > > +{
> > > > > + struct device *dev = &pdev->dev;
> > > > > + struct device_node *aux_bus;
> > > > > + struct device_node *panel;
> > > > > + int ret = DRM_MODE_CONNECTOR_DisplayPort;
> > > > > +
> > > > > + /* legacy platforms specify connector type in match data */
> > > > > + if (desc->connector_type == DRM_MODE_CONNECTOR_eDP ||
> > > > > + desc->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
> > > >
> > > > misaligned
> > > >
> > >
> > > Sure, will fix.
> > >
> > > > > + return desc->connector_type;
> > > >
> > > > Can we drop this part completely?
> > > >
> > >
> > > You mean the whole if clause? How should we handle the legacy approach
> > > then?
> >
> > Legacy platforms still have the aux-bus/panel. so they should be
> > handled by the check below.
> >
>
> Oh, in that case we can drop the connector_type from every desc for all
> platforms.

Guys, please trim your replies!

Johan

2024-03-22 14:30:35

by Bjorn Andersson

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] drm/msm/dp: Add support for determining the eDP/DP mode from DT

On Fri, Mar 22, 2024 at 03:22:22PM +0200, Abel Vesa wrote:
> Instead of relying on different compatibles for eDP and DP, lookup
> the panel node in devicetree to figure out the connector type and
> then pass on that information to the PHY. External DP is not described
> in DT, therefore, assume it's eDP if panel node is present.
>
> Signed-off-by: Abel Vesa <[email protected]>
> ---
> drivers/gpu/drm/msm/dp/dp_display.c | 43 +++++++++++++++++++++++++++++++++----
> 1 file changed, 39 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> index c4cb82af5c2f..c9763f77c832 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -726,6 +726,14 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> if (IS_ERR(phy))
> return PTR_ERR(phy);
>
> + rc = phy_set_mode_ext(phy, PHY_MODE_DP,
> + dp->dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);
> + if (rc) {
> + DRM_ERROR("failed to set phy submode, rc = %d\n", rc);
> + dp->catalog = NULL;
> + goto error;
> + }
> +
> dp->catalog = dp_catalog_get(dev);
> if (IS_ERR(dp->catalog)) {
> rc = PTR_ERR(dp->catalog);
> @@ -734,9 +742,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> goto error;
> }
>
> - dp->aux = dp_aux_get(dev, dp->catalog,
> - phy,
> - dp->dp_display.is_edp);
> + dp->aux = dp_aux_get(dev, dp->catalog, phy, dp->dp_display.is_edp);
> if (IS_ERR(dp->aux)) {
> rc = PTR_ERR(dp->aux);
> DRM_ERROR("failed to initialize aux, rc = %d\n", rc);
> @@ -1241,6 +1247,35 @@ static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
> return dp_display_probe_tail(aux->dev);
> }
>
> +static int dp_display_get_connector_type(struct platform_device *pdev,
> + const struct msm_dp_desc *desc)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *aux_bus;
> + struct device_node *panel;
> + int ret = DRM_MODE_CONNECTOR_DisplayPort;
> +
> + /* legacy platforms specify connector type in match data */
> + if (desc->connector_type == DRM_MODE_CONNECTOR_eDP ||
> + desc->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
> + return desc->connector_type;
> +
> + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
> + if (!aux_bus)
> + goto out;

My compiler warns that if we take this code path, then you will
of_node_put(<uninitialized panel>) below.

> +
> + panel = of_get_child_by_name(aux_bus, "panel");
> + if (!panel)
> + goto out;
> +
> + ret = DRM_MODE_CONNECTOR_eDP;

My brain read this function as:
check something
if (error)
bailout!

check something
if (error)
bailout!

ret should be edp

I then have to scan the code again to figure out what ret is otherwise,
and convince myself that the error path is never an error, but a totally
normal case.


If you instead rely on the fact that both of_get_child_by_name() and
of_node_put() can be passed NULL, you can write this as:

static int fn(..) {
aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
panel = of_get_child_by_name(aux_bus, "panel");

if (panel)
connector_type = DRM_MODE_CONNECTOR_eDP;
else
connector_type = DRM_MODE_CONNECTOR_DisplayPort;

of_node_put(panel);
of_node_put(aux_bus);

return connector_type;
}

Much easier to read, and you don't even have to zero-initialize panel to
avoid that compiler warning.

Regards,
Bjorn

> +
> +out:
> + of_node_put(panel);
> + of_node_put(aux_bus);
> + return ret;
> +}
> +
> static int dp_display_probe(struct platform_device *pdev)
> {
> int rc = 0;
> @@ -1263,7 +1298,7 @@ static int dp_display_probe(struct platform_device *pdev)
> dp->dp_display.pdev = pdev;
> dp->name = "drm_dp";
> dp->id = desc->id;
> - dp->dp_display.connector_type = desc->connector_type;
> + dp->dp_display.connector_type = dp_display_get_connector_type(pdev, desc);
> dp->wide_bus_supported = desc->wide_bus_supported;
> dp->dp_display.is_edp =
> (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
>
> --
> 2.34.1
>

2024-03-22 14:50:52

by Abel Vesa

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] drm/msm/dp: Add support for determining the eDP/DP mode from DT

On 24-03-22 09:30:21, Bjorn Andersson wrote:
> On Fri, Mar 22, 2024 at 03:22:22PM +0200, Abel Vesa wrote:
> > Instead of relying on different compatibles for eDP and DP, lookup
> > the panel node in devicetree to figure out the connector type and
> > then pass on that information to the PHY. External DP is not described
> > in DT, therefore, assume it's eDP if panel node is present.
> >
> > Signed-off-by: Abel Vesa <[email protected]>
> > ---
> > drivers/gpu/drm/msm/dp/dp_display.c | 43 +++++++++++++++++++++++++++++++++----
> > 1 file changed, 39 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
> > index c4cb82af5c2f..c9763f77c832 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > @@ -726,6 +726,14 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> > if (IS_ERR(phy))
> > return PTR_ERR(phy);
> >
> > + rc = phy_set_mode_ext(phy, PHY_MODE_DP,
> > + dp->dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);
> > + if (rc) {
> > + DRM_ERROR("failed to set phy submode, rc = %d\n", rc);
> > + dp->catalog = NULL;
> > + goto error;
> > + }
> > +
> > dp->catalog = dp_catalog_get(dev);
> > if (IS_ERR(dp->catalog)) {
> > rc = PTR_ERR(dp->catalog);
> > @@ -734,9 +742,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
> > goto error;
> > }
> >
> > - dp->aux = dp_aux_get(dev, dp->catalog,
> > - phy,
> > - dp->dp_display.is_edp);
> > + dp->aux = dp_aux_get(dev, dp->catalog, phy, dp->dp_display.is_edp);
> > if (IS_ERR(dp->aux)) {
> > rc = PTR_ERR(dp->aux);
> > DRM_ERROR("failed to initialize aux, rc = %d\n", rc);
> > @@ -1241,6 +1247,35 @@ static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
> > return dp_display_probe_tail(aux->dev);
> > }
> >
> > +static int dp_display_get_connector_type(struct platform_device *pdev,
> > + const struct msm_dp_desc *desc)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct device_node *aux_bus;
> > + struct device_node *panel;
> > + int ret = DRM_MODE_CONNECTOR_DisplayPort;
> > +
> > + /* legacy platforms specify connector type in match data */
> > + if (desc->connector_type == DRM_MODE_CONNECTOR_eDP ||
> > + desc->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
> > + return desc->connector_type;
> > +
> > + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
> > + if (!aux_bus)
> > + goto out;
>
> My compiler warns that if we take this code path, then you will
> of_node_put(<uninitialized panel>) below.
>
> > +
> > + panel = of_get_child_by_name(aux_bus, "panel");
> > + if (!panel)
> > + goto out;
> > +
> > + ret = DRM_MODE_CONNECTOR_eDP;
>
> My brain read this function as:
> check something
> if (error)
> bailout!
>
> check something
> if (error)
> bailout!
>
> ret should be edp
>
> I then have to scan the code again to figure out what ret is otherwise,
> and convince myself that the error path is never an error, but a totally
> normal case.
>
>
> If you instead rely on the fact that both of_get_child_by_name() and
> of_node_put() can be passed NULL, you can write this as:
>
> static int fn(..) {
> aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
> panel = of_get_child_by_name(aux_bus, "panel");
>
> if (panel)
> connector_type = DRM_MODE_CONNECTOR_eDP;
> else
> connector_type = DRM_MODE_CONNECTOR_DisplayPort;
>
> of_node_put(panel);
> of_node_put(aux_bus);
>
> return connector_type;
> }
>
> Much easier to read, and you don't even have to zero-initialize panel to
> avoid that compiler warning.
>

Fair enough, will do that instead.

> Regards,
> Bjorn
>
> > +
> > +out:
> > + of_node_put(panel);
> > + of_node_put(aux_bus);
> > + return ret;
> > +}
> > +
> > static int dp_display_probe(struct platform_device *pdev)
> > {
> > int rc = 0;
> > @@ -1263,7 +1298,7 @@ static int dp_display_probe(struct platform_device *pdev)
> > dp->dp_display.pdev = pdev;
> > dp->name = "drm_dp";
> > dp->id = desc->id;
> > - dp->dp_display.connector_type = desc->connector_type;
> > + dp->dp_display.connector_type = dp_display_get_connector_type(pdev, desc);
> > dp->wide_bus_supported = desc->wide_bus_supported;
> > dp->dp_display.is_edp =
> > (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
> >
> > --
> > 2.34.1
> >